Resolved a merge conflict. Included both changes manually.
This commit is contained in:
parent
c217b254fc
commit
a9ee85452e
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue