Resolved a merge conflict. Included both changes manually.

This commit is contained in:
Hannu Honkanen 2018-06-11 23:13:23 -07:00
parent c217b254fc
commit a9ee85452e
1 changed files with 167 additions and 29 deletions

View File

@ -32,17 +32,39 @@
#include "internal.h"
#include "pkcs15.h"
#include "pkcs11/pkcs11.h"
static sc_path_t get_file_path(const struct sc_pkcs15_object* obj)
{
sc_path_t path;
const struct sc_pkcs15_prkey_info *prkey = (const struct sc_pkcs15_prkey_info *) obj->data;
const struct sc_pkcs15_skey_info *skey = (const struct sc_pkcs15_skey_info *) obj->data;
memset (&path, 0, sizeof(path));
if ((obj->type & SC_PKCS15_TYPE_CLASS_MASK) == SC_PKCS15_TYPE_PRKEY) {
path = prkey->path;
}
else if ((obj->type & SC_PKCS15_TYPE_CLASS_MASK) == SC_PKCS15_TYPE_SKEY) {
path = skey->path;
}
return path;
}
static int select_key_file(struct sc_pkcs15_card *p15card,
const struct sc_pkcs15_prkey_info *prkey,
const struct sc_pkcs15_object *key,
sc_security_env_t *senv)
{
sc_context_t *ctx = p15card->card->ctx;
sc_path_t orig_path;
sc_path_t path, file_id;
int r;
LOG_FUNC_CALLED(ctx);
orig_path = get_file_path(key);
memset(&path, 0, sizeof(sc_path_t));
memset(&file_id, 0, sizeof(sc_path_t));
@ -50,21 +72,21 @@ static int select_key_file(struct sc_pkcs15_card *p15card,
* Check validity of the following assumption. */
/* For pkcs15-emulated cards, the file_app may be NULL,
* in that case we always assume an absolute path */
if (!prkey->path.len && prkey->path.aid.len) {
if (!orig_path.len && orig_path.aid.len) {
/* Private key is a SDO allocated in application DF */
path = prkey->path;
path = orig_path;
}
else if (prkey->path.len == 2 && p15card->file_app != NULL) {
else if (orig_path.len == 2 && p15card->file_app != NULL) {
/* Path is relative to app. DF */
path = p15card->file_app->path;
file_id = prkey->path;
file_id = orig_path;
sc_append_path(&path, &file_id);
senv->file_ref = file_id;
senv->flags |= SC_SEC_ENV_FILE_REF_PRESENT;
}
else if (prkey->path.len > 2) {
path = prkey->path;
memcpy(file_id.value, prkey->path.value + prkey->path.len - 2, 2);
else if (orig_path.len > 2) {
path = orig_path;
memcpy(file_id.value, orig_path.value + orig_path.len - 2, 2);
file_id.len = 2;
file_id.type = SC_PATH_TYPE_FILE_ID;
senv->file_ref = file_id;
@ -90,14 +112,14 @@ static int use_key(struct sc_pkcs15_card *p15card,
{
int r = SC_SUCCESS;
int revalidated_cached_pin = 0;
const struct sc_pkcs15_prkey_info *prkey = (const struct sc_pkcs15_prkey_info *) obj->data;
sc_path_t path = get_file_path(obj);
r = sc_lock(p15card->card);
LOG_TEST_RET(p15card->card->ctx, r, "sc_lock() failed");
do {
if (prkey->path.len != 0 || prkey->path.aid.len != 0) {
r = select_key_file(p15card, prkey, senv);
if (path.len != 0 || path.aid.len != 0) {
r = select_key_file(p15card, obj, senv);
if (r < 0) {
sc_log(p15card->card->ctx,
"Unable to select private key file");
@ -131,6 +153,7 @@ static int format_senv(struct sc_pkcs15_card *p15card,
{
sc_context_t *ctx = p15card->card->ctx;
const struct sc_pkcs15_prkey_info *prkey = (const struct sc_pkcs15_prkey_info *) obj->data;
const struct sc_pkcs15_skey_info *skey = (const struct sc_pkcs15_skey_info *) obj->data;
memset(senv_out, 0, sizeof(*senv_out));
@ -138,8 +161,8 @@ static int format_senv(struct sc_pkcs15_card *p15card,
* it can get value of card specific 'AlgorithmInfo::algRef'. */
memcpy(senv_out->supported_algos, &p15card->tokeninfo->supported_algos, sizeof(senv_out->supported_algos));
if ((obj->type & SC_PKCS15_TYPE_CLASS_MASK) != SC_PKCS15_TYPE_PRKEY)
LOG_TEST_RET(ctx, SC_ERROR_NOT_ALLOWED, "This is not a private key");
if (!((obj->type & SC_PKCS15_TYPE_CLASS_MASK) == SC_PKCS15_TYPE_PRKEY || (obj->type & SC_PKCS15_TYPE_CLASS_MASK) == SC_PKCS15_TYPE_SKEY))
LOG_TEST_RET(ctx, SC_ERROR_NOT_ALLOWED, "This is not a private or secret key");
/* If the key is not native, we can't operate with it. */
if (!prkey->native)
@ -181,6 +204,19 @@ static int format_senv(struct sc_pkcs15_card *p15card,
senv_out->flags |= SC_SEC_ENV_ALG_REF_PRESENT;
senv_out->algorithm_ref = prkey->field_length;
break;
case SC_PKCS15_TYPE_SKEY_GENERIC:
if (obj->type == SC_PKCS15_TYPE_SKEY_GENERIC && skey->key_type != CKK_AES)
LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "Key type not supported");
*alg_info_out = sc_card_find_alg(p15card->card, SC_ALGORITHM_AES,
skey->value_len, NULL);
if (*alg_info_out == NULL) {
sc_log(ctx,
"Card does not support AES with key length %"SC_FORMAT_LEN_SIZE_T"u",
skey->value_len);
LOG_FUNC_RETURN(ctx, SC_ERROR_NOT_SUPPORTED);
}
senv_out->algorithm = SC_ALGORITHM_AES;
break;
/* add other crypto types here */
default:
LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "Key type not supported");
@ -196,7 +232,7 @@ static int format_senv(struct sc_pkcs15_card *p15card,
return SC_SUCCESS;
}
int sc_pkcs15_decipher(struct sc_pkcs15_card *p15card,
const struct sc_pkcs15_object *obj,
unsigned long flags,
@ -210,7 +246,7 @@ int sc_pkcs15_decipher(struct sc_pkcs15_card *p15card,
unsigned long pad_flags = 0, sec_flags = 0;
LOG_FUNC_CALLED(ctx);
if (!(prkey->usage & (SC_PKCS15_PRKEY_USAGE_DECRYPT|SC_PKCS15_PRKEY_USAGE_UNWRAP)))
LOG_TEST_RET(ctx, SC_ERROR_NOT_ALLOWED, "This key cannot be used for decryption");
@ -297,7 +333,6 @@ int sc_pkcs15_derive(struct sc_pkcs15_card *p15card,
LOG_FUNC_RETURN(ctx, r);
}
/*
* Unwrap a key into a key object on card.
* in holds the wrapped key data
@ -314,7 +349,8 @@ int sc_pkcs15_unwrap(struct sc_pkcs15_card *p15card,
int r;
sc_algorithm_info_t *alg_info = NULL;
sc_security_env_t senv;
const struct sc_pkcs15_prkey_info *prkey = (const struct sc_pkcs15_prkey_info *) key->data;
const struct sc_pkcs15_prkey_info *src_prkey = (const struct sc_pkcs15_prkey_info *) key->data;
const struct sc_pkcs15_skey_info *src_skey = (const struct sc_pkcs15_skey_info *) key->data;
const struct sc_pkcs15_skey_info *tkey = (const struct sc_pkcs15_skey_info *) target_key->data;
unsigned long pad_flags = 0, sec_flags = 0;
u8 *out = 0;
@ -323,13 +359,16 @@ int sc_pkcs15_unwrap(struct sc_pkcs15_card *p15card,
LOG_FUNC_CALLED(ctx);
if (!(prkey->usage & (SC_PKCS15_PRKEY_USAGE_UNWRAP)))
LOG_TEST_RET(ctx, SC_ERROR_NOT_ALLOWED, "This key cannot be used for unwrapping");
if (!(key->type == SC_PKCS15_TYPE_PRKEY_RSA ||
(key->type & SC_PKCS15_TYPE_CLASS_MASK) == SC_PKCS15_TYPE_SKEY)) {
LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED,"Key type not supported");
if (key->type == SC_PKCS15_TYPE_PRKEY_RSA) {
if (!(src_prkey->usage & (SC_PKCS15_PRKEY_USAGE_UNWRAP)))
LOG_TEST_RET(ctx, SC_ERROR_NOT_ALLOWED, "This key cannot be used for unwrapping");
}
else if ((key->type & SC_PKCS15_TYPE_CLASS_MASK) == SC_PKCS15_TYPE_SKEY) {
if (!(src_skey->usage & (SC_PKCS15_PRKEY_USAGE_UNWRAP)))
LOG_TEST_RET(ctx, SC_ERROR_NOT_ALLOWED, "This key cannot be used for unwrapping");
}
else
LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "Key type not supported");
r = format_senv(p15card, key, &senv, &alg_info);
LOG_TEST_RET(ctx, r, "Could not initialize security environment");
@ -362,19 +401,118 @@ int sc_pkcs15_unwrap(struct sc_pkcs15_card *p15card,
LOG_TEST_RET(ctx, SC_ERROR_INVALID_ARGUMENTS, "invalid unwrapping target key path");
}
r = sc_get_encoding_flags(ctx, flags, alg_info->flags, &pad_flags, &sec_flags);
LOG_TEST_RET(ctx, r, "cannot encode security operation flags");
senv.algorithm_flags = sec_flags;
r = use_key(p15card, key, &senv, sc_unwrap, in, inlen, out,
poutlen);
poutlen);
LOG_TEST_RET(ctx, r, "use_key() failed");
LOG_FUNC_RETURN(ctx, r);
}
/*
* Wrap a key and return a cryptogram
* <key> is the wrapping key
* <target_key> is the key to be wrapped
* wrapped data is returned in <cryptogram>
*/
int sc_pkcs15_wrap(struct sc_pkcs15_card *p15card,
const struct sc_pkcs15_object *key,
struct sc_pkcs15_object *target_key,
unsigned long flags,
u8 * cryptogram, size_t* crgram_len) {
sc_context_t *ctx = p15card->card->ctx;
int r;
sc_algorithm_info_t *alg_info = NULL;
sc_security_env_t senv;
const struct sc_pkcs15_prkey_info *src_prkey = (const struct sc_pkcs15_prkey_info *) key->data;
const struct sc_pkcs15_skey_info *src_skey = (const struct sc_pkcs15_skey_info *) key->data;
const struct sc_pkcs15_prkey_info *target_prkey = (const struct sc_pkcs15_prkey_info *) target_key->data;
const struct sc_pkcs15_skey_info *target_skey = (const struct sc_pkcs15_skey_info *) target_key->data;
unsigned long pad_flags = 0, sec_flags = 0;
sc_path_t tkey_path;
u8 *in = 0;
u8 *out = 0;
size_t *poutlen = 0, inlen = 0;
sc_path_t path, target_file_id;
LOG_FUNC_CALLED(ctx);
switch (key->type) {
case SC_PKCS15_TYPE_PRKEY_RSA:
if (!(src_prkey->usage & (SC_PKCS15_PRKEY_USAGE_WRAP)))
LOG_TEST_RET(ctx, SC_ERROR_NOT_ALLOWED, "This key cannot be used for wrapping");
break;
case SC_PKCS15_TYPE_SKEY_DES:
case SC_PKCS15_TYPE_SKEY_3DES:
case SC_PKCS15_TYPE_SKEY_GENERIC:
if (!(src_skey->usage & (SC_PKCS15_PRKEY_USAGE_WRAP)))
LOG_TEST_RET(ctx, SC_ERROR_NOT_ALLOWED, "This key cannot be used for wrapping");
break;
default:
LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "Wrapping key type not supported");
}
if (!(target_key->type == SC_PKCS15_TYPE_PRKEY_RSA ||
(key->type & SC_PKCS15_TYPE_CLASS_MASK) == SC_PKCS15_TYPE_SKEY)) {
LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "Target key type not supported");
}
r = format_senv(p15card, key, &senv, &alg_info);
LOG_TEST_RET(ctx, r, "Could not initialize security environment");
senv.operation = SC_SEC_OPERATION_WRAP;
memset(&path, 0, sizeof (sc_path_t));
memset(&target_file_id, 0, sizeof (sc_path_t));
switch (target_key->type) {
case SC_PKCS15_TYPE_PRKEY_RSA:
tkey_path = target_prkey->path;
break;
default: /* we already know it is a secret key */
tkey_path = target_skey->path;
break;
}
if (!path.len && path.aid.len) {
/* Target key is a SDO allocated in application DF */
path = tkey_path;
} else if (tkey_path.len == 2 && p15card->file_app != NULL) {
/* Path is relative to app. DF */
path = p15card->file_app->path;
target_file_id = tkey_path;
sc_append_path(&path, &target_file_id);
senv.target_file_ref = target_file_id;
senv.flags |= SC_SEC_ENV_TARGET_FILE_REF_PRESENT;
} else if (tkey_path.len > 2) {
path = tkey_path;
memcpy(target_file_id.value, tkey_path.value + tkey_path.len - 2, 2);
target_file_id.len = 2;
target_file_id.type = SC_PATH_TYPE_FILE_ID;
senv.target_file_ref = target_file_id;
senv.flags |= SC_SEC_ENV_TARGET_FILE_REF_PRESENT;
}
else {
LOG_TEST_RET(ctx, SC_ERROR_INVALID_ARGUMENTS, "invalid unwrapping target key path");
}
r = sc_get_encoding_flags(ctx, flags, alg_info->flags, &pad_flags, &sec_flags);
LOG_TEST_RET(ctx, r, "cannot encode security operation flags");
senv.algorithm_flags = sec_flags;
out = cryptogram;
poutlen = crgram_len;
r = use_key(p15card, key, &senv, sc_wrap, in, inlen, out,
*poutlen);
/* TODO: handle SC_ERROR_BUFFER_TOO_SMALL, return size in *poutlen */
LOG_TEST_RET(ctx, r, "use_key() failed");
LOG_FUNC_RETURN(ctx, r);
}
/* copied from pkcs15-cardos.c */
#define USAGE_ANY_SIGN (SC_PKCS15_PRKEY_USAGE_SIGN|\
SC_PKCS15_PRKEY_USAGE_NONREPUDIATION)
@ -428,7 +566,7 @@ int sc_pkcs15_compute_signature(struct sc_pkcs15_card *p15card,
/* revert data to sign when signing with the GOST key.
* TODO: can it be confirmed by the GOST standard?
* TODO: tested with RuTokenECP, has to be validated for RuToken. */
if (obj->type == SC_PKCS15_TYPE_PRKEY_GOSTR3410) {
if (obj->type == SC_PKCS15_TYPE_PRKEY_GOSTR3410) {
r = sc_mem_reverse(buf, inlen);
LOG_TEST_RET(ctx, r, "Reverse memory error");
}
@ -449,7 +587,7 @@ int sc_pkcs15_compute_signature(struct sc_pkcs15_card *p15card,
(prkey->usage & USAGE_ANY_DECIPHER)) ) {
size_t tmplen = sizeof(buf);
if (flags & SC_ALGORITHM_RSA_RAW) {
r = sc_pkcs15_decipher(p15card, obj,flags, in, inlen, out, outlen);
r = sc_pkcs15_decipher(p15card, obj, flags, in, inlen, out, outlen);
LOG_FUNC_RETURN(ctx, r);
}
if (modlen > tmplen)
@ -465,7 +603,7 @@ int sc_pkcs15_compute_signature(struct sc_pkcs15_card *p15card,
LOG_TEST_RET(ctx, r, "Unable to add padding");
r = sc_pkcs15_decipher(p15card, obj,flags, buf, modlen, out, outlen);
r = sc_pkcs15_decipher(p15card, obj, flags, buf, modlen, out, outlen);
LOG_FUNC_RETURN(ctx, r);
}