Added implementation of C_UnwrapKey all the way from PKCS#11 interface to the card driver level.
Not yet complete, but can be run with CKA_TOKEN=FALSE set in the target object. Currently unwrapping emulated with a decrypt operation in card-myeid.c. To be improved.
This commit is contained in:
parent
e2b1fb81e0
commit
5f51d5d315
|
@ -227,6 +227,9 @@ static int myeid_init(struct sc_card *card)
|
||||||
/* State that we have an RNG */
|
/* State that we have an RNG */
|
||||||
card->caps |= SC_CARD_CAP_RNG | SC_CARD_CAP_ISO7816_PIN_INFO;
|
card->caps |= SC_CARD_CAP_RNG | SC_CARD_CAP_ISO7816_PIN_INFO;
|
||||||
|
|
||||||
|
/* if (card->version.fw_major >= 41) */ /* TODO: check the version number that actually supports these ops */
|
||||||
|
card->caps |= SC_CARD_CAP_WRAP_KEY | SC_CARD_CAP_UNWRAP_KEY;
|
||||||
|
|
||||||
card->max_recv_size = 255;
|
card->max_recv_size = 255;
|
||||||
card->max_send_size = 255;
|
card->max_send_size = 255;
|
||||||
|
|
||||||
|
@ -632,6 +635,10 @@ static int myeid_set_security_env_rsa(sc_card_t *card, const sc_security_env_t *
|
||||||
apdu.p1 = 0x41;
|
apdu.p1 = 0x41;
|
||||||
apdu.p2 = 0xB6;
|
apdu.p2 = 0xB6;
|
||||||
break;
|
break;
|
||||||
|
case SC_SEC_OPERATION_UNWRAP:
|
||||||
|
apdu.p1 = 0x41; /* emulating unwrapping with DECIPHER operation */
|
||||||
|
apdu.p2 = 0xB8; /* TODO: set correct params when operation is implemented on card */
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
return SC_ERROR_INVALID_ARGUMENTS;
|
return SC_ERROR_INVALID_ARGUMENTS;
|
||||||
}
|
}
|
||||||
|
@ -1185,6 +1192,31 @@ static int myeid_decipher(struct sc_card *card, const u8 * crgram,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int myeid_wrap_key(struct sc_card *card, u8 *out, size_t outlen)
|
||||||
|
{
|
||||||
|
int r;
|
||||||
|
LOG_FUNC_CALLED(card->ctx);
|
||||||
|
|
||||||
|
LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int myeid_unwrap_key(struct sc_card *card, const u8 *crgram, size_t crgram_len)
|
||||||
|
{
|
||||||
|
int r;
|
||||||
|
u8 out[512];
|
||||||
|
size_t outlen = 512;
|
||||||
|
|
||||||
|
LOG_FUNC_CALLED(card->ctx);
|
||||||
|
|
||||||
|
/* Emulate unwrapping with decipher */
|
||||||
|
r = myeid_decipher(card, crgram, crgram_len, out, outlen);
|
||||||
|
|
||||||
|
LOG_FUNC_RETURN(card->ctx, r);
|
||||||
|
|
||||||
|
/*LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED); */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Write internal data, e.g. add default pin-records to pin */
|
/* Write internal data, e.g. add default pin-records to pin */
|
||||||
static int myeid_putdata(struct sc_card *card, struct sc_cardctl_myeid_data_obj* data_obj)
|
static int myeid_putdata(struct sc_card *card, struct sc_cardctl_myeid_data_obj* data_obj)
|
||||||
{
|
{
|
||||||
|
@ -1601,6 +1633,8 @@ static struct sc_card_driver * sc_get_driver(void)
|
||||||
myeid_ops.process_fci = myeid_process_fci;
|
myeid_ops.process_fci = myeid_process_fci;
|
||||||
myeid_ops.card_ctl = myeid_card_ctl;
|
myeid_ops.card_ctl = myeid_card_ctl;
|
||||||
myeid_ops.pin_cmd = myeid_pin_cmd;
|
myeid_ops.pin_cmd = myeid_pin_cmd;
|
||||||
|
myeid_ops.wrap = myeid_wrap_key;
|
||||||
|
myeid_ops.unwrap = myeid_unwrap_key;
|
||||||
return &myeid_drv;
|
return &myeid_drv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1273,7 +1273,9 @@ static struct sc_card_operations iso_ops = {
|
||||||
NULL, /* put_data */
|
NULL, /* put_data */
|
||||||
NULL, /* delete_record */
|
NULL, /* delete_record */
|
||||||
NULL, /* read_public_key */
|
NULL, /* read_public_key */
|
||||||
NULL /* card_reader_lock_obtained */
|
NULL, /* card_reader_lock_obtained */
|
||||||
|
NULL, /* wrap */
|
||||||
|
NULL /* unwrap */
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct sc_card_driver iso_driver = {
|
static struct sc_card_driver iso_driver = {
|
||||||
|
|
|
@ -237,6 +237,7 @@ sc_pkcs15_remove_unusedspace
|
||||||
sc_pkcs15_search_objects
|
sc_pkcs15_search_objects
|
||||||
sc_pkcs15_unbind
|
sc_pkcs15_unbind
|
||||||
sc_pkcs15_unblock_pin
|
sc_pkcs15_unblock_pin
|
||||||
|
sc_pkcs15_unwrap
|
||||||
sc_pkcs15_verify_pin
|
sc_pkcs15_verify_pin
|
||||||
sc_pkcs15_get_pin_info
|
sc_pkcs15_get_pin_info
|
||||||
sc_pkcs15_verify_pin_with_session_pin
|
sc_pkcs15_verify_pin_with_session_pin
|
||||||
|
|
|
@ -57,6 +57,8 @@ extern "C" {
|
||||||
#define SC_SEC_OPERATION_SIGN 0x0002
|
#define SC_SEC_OPERATION_SIGN 0x0002
|
||||||
#define SC_SEC_OPERATION_AUTHENTICATE 0x0003
|
#define SC_SEC_OPERATION_AUTHENTICATE 0x0003
|
||||||
#define SC_SEC_OPERATION_DERIVE 0x0004
|
#define SC_SEC_OPERATION_DERIVE 0x0004
|
||||||
|
#define SC_SEC_OPERATION_WRAP 0x0005
|
||||||
|
#define SC_SEC_OPERATION_UNWRAP 0x0006
|
||||||
|
|
||||||
/* sc_security_env flags */
|
/* sc_security_env flags */
|
||||||
#define SC_SEC_ENV_ALG_REF_PRESENT 0x0001
|
#define SC_SEC_ENV_ALG_REF_PRESENT 0x0001
|
||||||
|
@ -525,6 +527,17 @@ struct sc_reader_operations {
|
||||||
/* Card (or card driver) supports generating a session PIN */
|
/* Card (or card driver) supports generating a session PIN */
|
||||||
#define SC_CARD_CAP_SESSION_PIN 0x00000200
|
#define SC_CARD_CAP_SESSION_PIN 0x00000200
|
||||||
|
|
||||||
|
/* Card and driver supports handling on card session objects.
|
||||||
|
* If a driver has this capability, the driver handles storage and operations
|
||||||
|
* with objects that CKA_TOKEN set to FALSE. If a driver doesn't support this,
|
||||||
|
* OpenSC handles them as in memory objects.*/
|
||||||
|
#define SC_CARD_CAP_ONCARD_SESSION_OBJECTS 0x00000400
|
||||||
|
|
||||||
|
/* Card (or card driver) supports key wrapping operations */
|
||||||
|
#define SC_CARD_CAP_WRAP_KEY 0x00000800
|
||||||
|
/* Card (or card driver) supports key unwrapping operations */
|
||||||
|
#define SC_CARD_CAP_UNWRAP_KEY 0x00001000
|
||||||
|
|
||||||
typedef struct sc_card {
|
typedef struct sc_card {
|
||||||
struct sc_context *ctx;
|
struct sc_context *ctx;
|
||||||
struct sc_reader *reader;
|
struct sc_reader *reader;
|
||||||
|
@ -689,6 +702,10 @@ struct sc_card_operations {
|
||||||
unsigned char **, size_t *);
|
unsigned char **, size_t *);
|
||||||
|
|
||||||
int (*card_reader_lock_obtained)(struct sc_card *, int was_reset);
|
int (*card_reader_lock_obtained)(struct sc_card *, int was_reset);
|
||||||
|
|
||||||
|
int (*wrap)(struct sc_card *card, u8 *out, size_t outlen);
|
||||||
|
|
||||||
|
int (*unwrap)(struct sc_card *card, const u8 *crgram, size_t crgram_len);
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct sc_card_driver {
|
typedef struct sc_card_driver {
|
||||||
|
@ -1192,6 +1209,8 @@ int sc_decipher(struct sc_card *card, const u8 * crgram, size_t crgram_len,
|
||||||
u8 * out, size_t outlen);
|
u8 * out, size_t outlen);
|
||||||
int sc_compute_signature(struct sc_card *card, const u8 * data,
|
int sc_compute_signature(struct sc_card *card, const u8 * data,
|
||||||
size_t data_len, u8 * out, size_t outlen);
|
size_t data_len, u8 * out, size_t outlen);
|
||||||
|
int sc_unwrap(struct sc_card *card, const u8 * data,
|
||||||
|
size_t data_len, u8 * out, size_t outlen);
|
||||||
int sc_verify(struct sc_card *card, unsigned int type, int ref, const u8 *buf,
|
int sc_verify(struct sc_card *card, unsigned int type, int ref, const u8 *buf,
|
||||||
size_t buflen, int *tries_left);
|
size_t buflen, int *tries_left);
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -297,6 +297,53 @@ int sc_pkcs15_derive(struct sc_pkcs15_card *p15card,
|
||||||
LOG_FUNC_RETURN(ctx, r);
|
LOG_FUNC_RETURN(ctx, r);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Unwrap a key into a key object on card.
|
||||||
|
* in holds the wrapped key data
|
||||||
|
* the target file that target_key points to must be created before calling this function
|
||||||
|
* Use pkcs15init to peform the complete unwrapping operation and create the pkcs#15 object for the new key.
|
||||||
|
*/
|
||||||
|
int sc_pkcs15_unwrap(struct sc_pkcs15_card *p15card,
|
||||||
|
const struct sc_pkcs15_object *key,
|
||||||
|
struct sc_pkcs15_object *target_key,
|
||||||
|
unsigned long flags,
|
||||||
|
const u8 * in, size_t inlen)
|
||||||
|
{
|
||||||
|
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 *prkey = (const struct sc_pkcs15_prkey_info *) key->data;
|
||||||
|
unsigned long pad_flags = 0, sec_flags = 0;
|
||||||
|
u8 *out = 0;
|
||||||
|
size_t poutlen = 0;
|
||||||
|
|
||||||
|
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");
|
||||||
|
}
|
||||||
|
|
||||||
|
r = format_senv(p15card, key, &senv, &alg_info);
|
||||||
|
LOG_TEST_RET(ctx, r, "Could not initialize security environment");
|
||||||
|
senv.operation = SC_SEC_OPERATION_UNWRAP;
|
||||||
|
|
||||||
|
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);
|
||||||
|
LOG_TEST_RET(ctx, r, "use_key() failed");
|
||||||
|
|
||||||
|
LOG_FUNC_RETURN(ctx, r);
|
||||||
|
}
|
||||||
|
|
||||||
/* copied from pkcs15-cardos.c */
|
/* copied from pkcs15-cardos.c */
|
||||||
#define USAGE_ANY_SIGN (SC_PKCS15_PRKEY_USAGE_SIGN|\
|
#define USAGE_ANY_SIGN (SC_PKCS15_PRKEY_USAGE_SIGN|\
|
||||||
SC_PKCS15_PRKEY_USAGE_NONREPUDIATION)
|
SC_PKCS15_PRKEY_USAGE_NONREPUDIATION)
|
||||||
|
|
|
@ -452,6 +452,7 @@ typedef struct sc_pkcs15_skey_info sc_pkcs15_skey_info_t;
|
||||||
#define SC_PKCS15_TYPE_SKEY_DES 0x302
|
#define SC_PKCS15_TYPE_SKEY_DES 0x302
|
||||||
#define SC_PKCS15_TYPE_SKEY_2DES 0x303
|
#define SC_PKCS15_TYPE_SKEY_2DES 0x303
|
||||||
#define SC_PKCS15_TYPE_SKEY_3DES 0x304
|
#define SC_PKCS15_TYPE_SKEY_3DES 0x304
|
||||||
|
#define SC_PKCS15_TYPE_SKEY_AES 0x305
|
||||||
|
|
||||||
#define SC_PKCS15_TYPE_CERT 0x400
|
#define SC_PKCS15_TYPE_CERT 0x400
|
||||||
#define SC_PKCS15_TYPE_CERT_X509 0x401
|
#define SC_PKCS15_TYPE_CERT_X509 0x401
|
||||||
|
@ -660,6 +661,12 @@ int sc_pkcs15_derive(struct sc_pkcs15_card *p15card,
|
||||||
unsigned long flags,
|
unsigned long flags,
|
||||||
const u8 *in, size_t inlen, u8 *out, unsigned long *poutlen);
|
const u8 *in, size_t inlen, u8 *out, unsigned long *poutlen);
|
||||||
|
|
||||||
|
int sc_pkcs15_unwrap(struct sc_pkcs15_card *p15card,
|
||||||
|
const struct sc_pkcs15_object *key,
|
||||||
|
struct sc_pkcs15_object *target_key,
|
||||||
|
unsigned long flags,
|
||||||
|
const u8 * in, size_t inlen);
|
||||||
|
|
||||||
int sc_pkcs15_compute_signature(struct sc_pkcs15_card *p15card,
|
int sc_pkcs15_compute_signature(struct sc_pkcs15_card *p15card,
|
||||||
const struct sc_pkcs15_object *prkey_obj,
|
const struct sc_pkcs15_object *prkey_obj,
|
||||||
unsigned long alg_flags, const u8 *in,
|
unsigned long alg_flags, const u8 *in,
|
||||||
|
|
|
@ -63,6 +63,21 @@ int sc_compute_signature(sc_card_t *card,
|
||||||
SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, r);
|
SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, r);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int sc_unwrap(sc_card_t *card,
|
||||||
|
const u8 * crgram, size_t crgram_len, u8 * out, size_t outlen)
|
||||||
|
{
|
||||||
|
int r;
|
||||||
|
|
||||||
|
if (card == NULL || crgram == NULL) {
|
||||||
|
return SC_ERROR_INVALID_ARGUMENTS;
|
||||||
|
}
|
||||||
|
SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_NORMAL);
|
||||||
|
if (card->ops->unwrap == NULL)
|
||||||
|
SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_NOT_SUPPORTED);
|
||||||
|
r = card->ops->unwrap(card, crgram, crgram_len);
|
||||||
|
SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, r);
|
||||||
|
}
|
||||||
|
|
||||||
int sc_set_security_env(sc_card_t *card,
|
int sc_set_security_env(sc_card_t *card,
|
||||||
const sc_security_env_t *env,
|
const sc_security_env_t *env,
|
||||||
int se_num)
|
int se_num)
|
||||||
|
|
|
@ -2207,7 +2207,7 @@ pkcs15_create_secret_key(struct sc_pkcs11_slot *slot, struct sc_profile *profile
|
||||||
struct sc_pkcs15_skey_info *skey_info;
|
struct sc_pkcs15_skey_info *skey_info;
|
||||||
CK_KEY_TYPE key_type;
|
CK_KEY_TYPE key_type;
|
||||||
CK_BBOOL _token = FALSE;
|
CK_BBOOL _token = FALSE;
|
||||||
int rv;
|
int rv, rc;
|
||||||
char label[SC_PKCS15_MAX_LABEL_SIZE];
|
char label[SC_PKCS15_MAX_LABEL_SIZE];
|
||||||
|
|
||||||
memset(&args, 0, sizeof(args));
|
memset(&args, 0, sizeof(args));
|
||||||
|
@ -2228,6 +2228,9 @@ pkcs15_create_secret_key(struct sc_pkcs11_slot *slot, struct sc_profile *profile
|
||||||
switch (key_type) {
|
switch (key_type) {
|
||||||
/* Only support GENERIC_SECRET for now */
|
/* Only support GENERIC_SECRET for now */
|
||||||
case CKK_GENERIC_SECRET:
|
case CKK_GENERIC_SECRET:
|
||||||
|
case CKK_AES:
|
||||||
|
case CKK_DES3:
|
||||||
|
case CKK_DES:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return CKR_ATTRIBUTE_VALUE_INVALID;
|
return CKR_ATTRIBUTE_VALUE_INVALID;
|
||||||
|
@ -2283,7 +2286,7 @@ pkcs15_create_secret_key(struct sc_pkcs11_slot *slot, struct sc_profile *profile
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If creating a PKCS#11 session object, i.e. one that is only in memory */
|
/* If creating a PKCS#11 session object, i.e. one that is only in memory */
|
||||||
if (_token == FALSE) {
|
if (_token == FALSE && (fw_data->p15_card->card->caps & SC_CARD_CAP_ONCARD_SESSION_OBJECTS) == 0) {
|
||||||
|
|
||||||
/* TODO Have 3 choices as to how to create the object.
|
/* TODO Have 3 choices as to how to create the object.
|
||||||
* (1)create a sc_pkcs15init_store_secret_key routine like the others
|
* (1)create a sc_pkcs15init_store_secret_key routine like the others
|
||||||
|
@ -2319,18 +2322,11 @@ pkcs15_create_secret_key(struct sc_pkcs11_slot *slot, struct sc_profile *profile
|
||||||
args.key.data = NULL;
|
args.key.data = NULL;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
#if 1
|
|
||||||
rv = CKR_FUNCTION_NOT_SUPPORTED;
|
|
||||||
goto out;
|
|
||||||
#else
|
|
||||||
/* TODO add support for secret key on the card with something like this: */
|
|
||||||
|
|
||||||
rc = sc_pkcs15init_store_secret_key(fw_data->p15_card, profile, &args, &key_obj);
|
rc = sc_pkcs15init_store_secret_key(fw_data->p15_card, profile, &args, &key_obj);
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
rv = sc_to_cryptoki_error(rc, "C_CreateObject");
|
rv = sc_to_cryptoki_error(rc, "C_CreateObject");
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create a new pkcs11 object for it */
|
/* Create a new pkcs11 object for it */
|
||||||
|
@ -3480,6 +3476,7 @@ struct sc_pkcs11_object_ops pkcs15_cert_ops = {
|
||||||
NULL, /* derive */
|
NULL, /* derive */
|
||||||
NULL, /* can_do */
|
NULL, /* can_do */
|
||||||
NULL /* init_params */
|
NULL /* init_params */
|
||||||
|
NULL /* wrap_key */
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -3910,6 +3907,69 @@ pkcs15_prkey_sign(struct sc_pkcs11_session *session, void *obj,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static CK_RV
|
||||||
|
pkcs15_prkey_unwrap(struct sc_pkcs11_session *session, void *obj,
|
||||||
|
CK_MECHANISM_PTR pMechanism, CK_BYTE_PTR pWrappedKey,
|
||||||
|
CK_ULONG ulWrappedKeyLen,
|
||||||
|
void *targetKey)
|
||||||
|
/* CK_ATTRIBUTE_PTR pAttributes, CK_ULONG ulAttributesLen,
|
||||||
|
void ** pUnwrappedKey)*/
|
||||||
|
{
|
||||||
|
struct sc_pkcs11_card *p11card = session->slot->p11card;
|
||||||
|
struct pkcs15_fw_data *fw_data = NULL;
|
||||||
|
struct pkcs15_prkey_object *prkey = (struct pkcs15_prkey_object *) obj;
|
||||||
|
struct sc_pkcs11_object *targetKeyObj = (struct sc_pkcs11_object *) targetKey;
|
||||||
|
int rv, flags = 0;
|
||||||
|
|
||||||
|
sc_log(context, "Initiating unwrapping with private key.");
|
||||||
|
|
||||||
|
fw_data = (struct pkcs15_fw_data *) p11card->fws_data[session->slot->fw_data_idx];
|
||||||
|
if (!fw_data)
|
||||||
|
return sc_to_cryptoki_error(SC_ERROR_INTERNAL, "C_UnwrapKey");
|
||||||
|
|
||||||
|
sc_log(context, "unwrapping %p %p %p %p %lu %p", session, obj,
|
||||||
|
pMechanism, pWrappedKey, ulWrappedKeyLen, targetKeyObj);
|
||||||
|
|
||||||
|
if (pMechanism == NULL || pWrappedKey == NULL || ulWrappedKeyLen == 0 || targetKeyObj == NULL)
|
||||||
|
return CKR_ARGUMENTS_BAD;
|
||||||
|
|
||||||
|
/* See which of the alternative keys supports unwrap */
|
||||||
|
while (prkey && !(prkey->prv_info->usage & SC_PKCS15_PRKEY_USAGE_UNWRAP))
|
||||||
|
prkey = prkey->prv_next;
|
||||||
|
|
||||||
|
if (prkey == NULL)
|
||||||
|
return CKR_KEY_FUNCTION_NOT_PERMITTED;
|
||||||
|
|
||||||
|
/* Select the proper padding mechanism */
|
||||||
|
switch (pMechanism->mechanism) {
|
||||||
|
case CKM_RSA_PKCS:
|
||||||
|
flags |= SC_ALGORITHM_RSA_PAD_PKCS1;
|
||||||
|
break;
|
||||||
|
case CKM_RSA_X_509:
|
||||||
|
flags |= SC_ALGORITHM_RSA_RAW;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return CKR_MECHANISM_INVALID;
|
||||||
|
}
|
||||||
|
|
||||||
|
rv = sc_lock(p11card->card);
|
||||||
|
|
||||||
|
if (rv < 0)
|
||||||
|
return sc_to_cryptoki_error(rv, "C_UnwrapKey");
|
||||||
|
|
||||||
|
/* Call the card to do the unwrap operation */
|
||||||
|
rv = sc_pkcs15_unwrap(fw_data->p15_card, prkey->prv_p15obj, (struct sc_pkcs15_object *) targetKeyObj, 0,
|
||||||
|
pWrappedKey, ulWrappedKeyLen);
|
||||||
|
|
||||||
|
sc_unlock(p11card->card);
|
||||||
|
|
||||||
|
if (rv < 0)
|
||||||
|
return sc_to_cryptoki_error(rv, "C_UnwrapKey");
|
||||||
|
|
||||||
|
return CKR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static CK_RV
|
static CK_RV
|
||||||
pkcs15_prkey_decrypt(struct sc_pkcs11_session *session, void *obj,
|
pkcs15_prkey_decrypt(struct sc_pkcs11_session *session, void *obj,
|
||||||
CK_MECHANISM_PTR pMechanism,
|
CK_MECHANISM_PTR pMechanism,
|
||||||
|
@ -4183,11 +4243,12 @@ struct sc_pkcs11_object_ops pkcs15_prkey_ops = {
|
||||||
pkcs15_any_destroy,
|
pkcs15_any_destroy,
|
||||||
NULL, /* get_size */
|
NULL, /* get_size */
|
||||||
pkcs15_prkey_sign,
|
pkcs15_prkey_sign,
|
||||||
NULL, /* unwrap */
|
pkcs15_prkey_unwrap,
|
||||||
pkcs15_prkey_decrypt,
|
pkcs15_prkey_decrypt,
|
||||||
pkcs15_prkey_derive,
|
pkcs15_prkey_derive,
|
||||||
pkcs15_prkey_can_do,
|
pkcs15_prkey_can_do,
|
||||||
pkcs15_prkey_init_params,
|
pkcs15_prkey_init_params,
|
||||||
|
NULL /* wrap_key */
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -4426,6 +4487,7 @@ struct sc_pkcs11_object_ops pkcs15_pubkey_ops = {
|
||||||
NULL, /* derive */
|
NULL, /* derive */
|
||||||
NULL, /* can_do */
|
NULL, /* can_do */
|
||||||
NULL /* init_params */
|
NULL /* init_params */
|
||||||
|
NULL /* wrap_key */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -4605,6 +4667,7 @@ struct sc_pkcs11_object_ops pkcs15_dobj_ops = {
|
||||||
NULL, /* derive */
|
NULL, /* derive */
|
||||||
NULL, /* can_do */
|
NULL, /* can_do */
|
||||||
NULL /* init_params */
|
NULL /* init_params */
|
||||||
|
NULL /* wrap_key */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -4735,6 +4798,7 @@ struct sc_pkcs11_object_ops pkcs15_skey_ops = {
|
||||||
NULL, /* derive */
|
NULL, /* derive */
|
||||||
NULL, /* can_do */
|
NULL, /* can_do */
|
||||||
NULL /* init_params */
|
NULL /* init_params */
|
||||||
|
pkcs15_skey_wrap /* wrap_key */
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -5084,6 +5148,9 @@ register_mechanisms(struct sc_pkcs11_card *p11card)
|
||||||
/* That practise definitely conflicts with CKF_HW -- andre 2010-11-28 */
|
/* That practise definitely conflicts with CKF_HW -- andre 2010-11-28 */
|
||||||
mech_info.flags |= CKF_VERIFY;
|
mech_info.flags |= CKF_VERIFY;
|
||||||
#endif
|
#endif
|
||||||
|
if ((card->caps & SC_CARD_CAP_UNWRAP_KEY) == SC_CARD_CAP_UNWRAP_KEY)
|
||||||
|
mech_info.flags |= CKF_UNWRAP;
|
||||||
|
|
||||||
mech_info.ulMinKeySize = ~0;
|
mech_info.ulMinKeySize = ~0;
|
||||||
mech_info.ulMaxKeySize = 0;
|
mech_info.ulMaxKeySize = 0;
|
||||||
ec_min_key_size = ~0;
|
ec_min_key_size = ~0;
|
||||||
|
|
|
@ -830,6 +830,64 @@ sc_pkcs11_decr(struct sc_pkcs11_session *session,
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Unwrap a wrapped key into card. A new key object is created on card.
|
||||||
|
*/
|
||||||
|
CK_RV
|
||||||
|
sc_pkcs11_unwrap(struct sc_pkcs11_session *session,
|
||||||
|
CK_MECHANISM_PTR pMechanism,
|
||||||
|
struct sc_pkcs11_object *unwrappingKey,
|
||||||
|
CK_KEY_TYPE key_type, /* type of the unwrapping key */
|
||||||
|
CK_SESSION_HANDLE hSession,
|
||||||
|
CK_BYTE_PTR pWrappedKey, /* the wrapped key */
|
||||||
|
CK_ULONG ulWrappedKeyLen, /* bytes length of wrapped key */
|
||||||
|
struct sc_pkcs11_object *targetKey)
|
||||||
|
{
|
||||||
|
struct sc_pkcs11_card *p11card;
|
||||||
|
sc_pkcs11_operation_t *operation;
|
||||||
|
sc_pkcs11_mechanism_type_t *mt;
|
||||||
|
|
||||||
|
CK_RV rv;
|
||||||
|
|
||||||
|
if (!session || !session->slot
|
||||||
|
|| !(p11card = session->slot->p11card))
|
||||||
|
return CKR_ARGUMENTS_BAD;
|
||||||
|
|
||||||
|
/* See if we support this mechanism type */
|
||||||
|
mt = sc_pkcs11_find_mechanism(p11card, pMechanism->mechanism, CKF_UNWRAP);
|
||||||
|
if (mt == NULL)
|
||||||
|
return CKR_MECHANISM_INVALID;
|
||||||
|
|
||||||
|
/* See if compatible with key type */
|
||||||
|
/* TODO: what if there are several mechanisms with different key types? Should we loop through them? */
|
||||||
|
if (mt->key_type != key_type)
|
||||||
|
return CKR_KEY_TYPE_INCONSISTENT;
|
||||||
|
|
||||||
|
rv = session_start_operation(session, SC_PKCS11_OPERATION_UNWRAP, mt, &operation);
|
||||||
|
if (rv != CKR_OK)
|
||||||
|
return rv;
|
||||||
|
|
||||||
|
memcpy(&operation->mechanism, pMechanism, sizeof(CK_MECHANISM));
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* TODO: does it make sense to support unwrapping to a in memory key object?
|
||||||
|
* This implementation assumes that the key should be unwrapped into a
|
||||||
|
* key object on card, regardless whether CKA_TOKEN = FALSE
|
||||||
|
* CKA_TOKEN = FALSE is considered an on card session object.
|
||||||
|
*/
|
||||||
|
|
||||||
|
rv = operation->type->unwrap(operation, unwrappingKey,
|
||||||
|
pWrappedKey, ulWrappedKeyLen,
|
||||||
|
targetKey);
|
||||||
|
|
||||||
|
session_stop_operation(session, SC_PKCS11_OPERATION_UNWRAP);
|
||||||
|
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Derive one key from another, and return results in created object */
|
/* Derive one key from another, and return results in created object */
|
||||||
CK_RV
|
CK_RV
|
||||||
sc_pkcs11_deri(struct sc_pkcs11_session *session,
|
sc_pkcs11_deri(struct sc_pkcs11_session *session,
|
||||||
|
@ -990,6 +1048,29 @@ sc_pkcs11_derive(sc_pkcs11_operation_t *operation,
|
||||||
pData, pulDataLen);
|
pData, pulDataLen);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static CK_RV
|
||||||
|
sc_pkcs11_unwrap_operation(sc_pkcs11_operation_t *operation,
|
||||||
|
struct sc_pkcs11_object *unwrappingKey,
|
||||||
|
CK_BYTE_PTR pWrappedKey, CK_ULONG ulWrappedKeyLen,
|
||||||
|
struct sc_pkcs11_object *targetKey)
|
||||||
|
/* CK_ATTRIBUTE_PTR pAttributes, CK_ULONG ulAttresLen,
|
||||||
|
void** phUnwrappedKey)*/
|
||||||
|
{
|
||||||
|
return unwrappingKey->ops->unwrap_key(operation->session,
|
||||||
|
unwrappingKey,
|
||||||
|
&operation->mechanism,
|
||||||
|
pWrappedKey, ulWrappedKeyLen,
|
||||||
|
targetKey);
|
||||||
|
|
||||||
|
/*return unwrappingKey->ops->unwrap_key(operation->session,
|
||||||
|
unwrappingKey,
|
||||||
|
&operation->mechanism,
|
||||||
|
pmechParam, ulmechParamLen,
|
||||||
|
pAttributes, ulAttresLen,
|
||||||
|
phUnwrappedKey);*/
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Create new mechanism type for a mechanism supported by
|
* Create new mechanism type for a mechanism supported by
|
||||||
* the card
|
* the card
|
||||||
|
@ -1027,7 +1108,7 @@ sc_pkcs11_new_fw_mechanism(CK_MECHANISM_TYPE mech,
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
if (pInfo->flags & CKF_UNWRAP) {
|
if (pInfo->flags & CKF_UNWRAP) {
|
||||||
/* TODO */
|
mt->unwrap = sc_pkcs11_unwrap_operation;
|
||||||
}
|
}
|
||||||
if (pInfo->flags & CKF_DERIVE) {
|
if (pInfo->flags & CKF_DERIVE) {
|
||||||
mt->derive = sc_pkcs11_derive;
|
mt->derive = sc_pkcs11_derive;
|
||||||
|
|
|
@ -64,6 +64,8 @@ static sc_pkcs11_mechanism_type_t openssl_sha1_mech = {
|
||||||
NULL, NULL, NULL, /* verif_* */
|
NULL, NULL, NULL, /* verif_* */
|
||||||
NULL, NULL, /* decrypt_* */
|
NULL, NULL, /* decrypt_* */
|
||||||
NULL, /* derive */
|
NULL, /* derive */
|
||||||
|
NULL, /* wrap */
|
||||||
|
NULL, /* unwrap */
|
||||||
NULL, /* mech_data */
|
NULL, /* mech_data */
|
||||||
NULL, /* free_mech_data */
|
NULL, /* free_mech_data */
|
||||||
};
|
};
|
||||||
|
@ -98,6 +100,8 @@ static sc_pkcs11_mechanism_type_t openssl_sha256_mech = {
|
||||||
NULL, NULL, NULL, /* verif_* */
|
NULL, NULL, NULL, /* verif_* */
|
||||||
NULL, NULL, /* decrypt_* */
|
NULL, NULL, /* decrypt_* */
|
||||||
NULL, /* derive */
|
NULL, /* derive */
|
||||||
|
NULL, /* wrap */
|
||||||
|
NULL, /* unwrap */
|
||||||
NULL, /* mech_data */
|
NULL, /* mech_data */
|
||||||
NULL, /* free_mech_data */
|
NULL, /* free_mech_data */
|
||||||
};
|
};
|
||||||
|
@ -115,6 +119,8 @@ static sc_pkcs11_mechanism_type_t openssl_sha384_mech = {
|
||||||
NULL, NULL, NULL, /* verif_* */
|
NULL, NULL, NULL, /* verif_* */
|
||||||
NULL, NULL, /* decrypt_* */
|
NULL, NULL, /* decrypt_* */
|
||||||
NULL, /* derive */
|
NULL, /* derive */
|
||||||
|
NULL, /* wrap */
|
||||||
|
NULL, /* unwrap */
|
||||||
NULL, /* mech_data */
|
NULL, /* mech_data */
|
||||||
NULL, /* free_mech_data */
|
NULL, /* free_mech_data */
|
||||||
};
|
};
|
||||||
|
@ -132,6 +138,8 @@ static sc_pkcs11_mechanism_type_t openssl_sha512_mech = {
|
||||||
NULL, NULL, NULL, /* verif_* */
|
NULL, NULL, NULL, /* verif_* */
|
||||||
NULL, NULL, /* decrypt_* */
|
NULL, NULL, /* decrypt_* */
|
||||||
NULL, /* derive */
|
NULL, /* derive */
|
||||||
|
NULL, /* wrap */
|
||||||
|
NULL, /* unwrap */
|
||||||
NULL, /* mech_data */
|
NULL, /* mech_data */
|
||||||
NULL, /* free_mech_data */
|
NULL, /* free_mech_data */
|
||||||
};
|
};
|
||||||
|
@ -150,6 +158,8 @@ static sc_pkcs11_mechanism_type_t openssl_gostr3411_mech = {
|
||||||
NULL, NULL, NULL, /* verif_* */
|
NULL, NULL, NULL, /* verif_* */
|
||||||
NULL, NULL, /* decrypt_* */
|
NULL, NULL, /* decrypt_* */
|
||||||
NULL, /* derive */
|
NULL, /* derive */
|
||||||
|
NULL, /* wrap */
|
||||||
|
NULL, /* unwrap */
|
||||||
NULL, /* mech_data */
|
NULL, /* mech_data */
|
||||||
NULL, /* free_mech_data */
|
NULL, /* free_mech_data */
|
||||||
};
|
};
|
||||||
|
@ -168,6 +178,8 @@ static sc_pkcs11_mechanism_type_t openssl_md5_mech = {
|
||||||
NULL, NULL, NULL, /* verif_* */
|
NULL, NULL, NULL, /* verif_* */
|
||||||
NULL, NULL, /* decrypt_* */
|
NULL, NULL, /* decrypt_* */
|
||||||
NULL, /* derive */
|
NULL, /* derive */
|
||||||
|
NULL, /* wrap */
|
||||||
|
NULL, /* unwrap */
|
||||||
NULL, /* mech_data */
|
NULL, /* mech_data */
|
||||||
NULL, /* free_mech_data */
|
NULL, /* free_mech_data */
|
||||||
};
|
};
|
||||||
|
@ -185,6 +197,8 @@ static sc_pkcs11_mechanism_type_t openssl_ripemd160_mech = {
|
||||||
NULL, NULL, NULL, /* verif_* */
|
NULL, NULL, NULL, /* verif_* */
|
||||||
NULL, NULL, /* decrypt_* */
|
NULL, NULL, /* decrypt_* */
|
||||||
NULL, /* derive */
|
NULL, /* derive */
|
||||||
|
NULL, /* wrap */
|
||||||
|
NULL, /* unwrap */
|
||||||
NULL, /* mech_data */
|
NULL, /* mech_data */
|
||||||
NULL, /* free_mech_data */
|
NULL, /* free_mech_data */
|
||||||
};
|
};
|
||||||
|
|
|
@ -47,6 +47,8 @@ static sc_pkcs11_mechanism_type_t find_mechanism = {
|
||||||
NULL, /* decrypt_init */
|
NULL, /* decrypt_init */
|
||||||
NULL, /* decrypt */
|
NULL, /* decrypt */
|
||||||
NULL, /* derive */
|
NULL, /* derive */
|
||||||
|
NULL, /* wrap */
|
||||||
|
NULL, /* unwrap */
|
||||||
NULL, /* mech_data */
|
NULL, /* mech_data */
|
||||||
NULL, /* free_mech_data */
|
NULL, /* free_mech_data */
|
||||||
};
|
};
|
||||||
|
@ -1049,7 +1051,67 @@ CK_RV C_UnwrapKey(CK_SESSION_HANDLE hSession, /* the session's handle */
|
||||||
CK_ULONG ulAttributeCount, /* # of attributes in template */
|
CK_ULONG ulAttributeCount, /* # of attributes in template */
|
||||||
CK_OBJECT_HANDLE_PTR phKey)
|
CK_OBJECT_HANDLE_PTR phKey)
|
||||||
{ /* gets handle of recovered key */
|
{ /* gets handle of recovered key */
|
||||||
return CKR_FUNCTION_NOT_SUPPORTED;
|
CK_RV rv;
|
||||||
|
CK_BBOOL can_unwrap;
|
||||||
|
CK_KEY_TYPE key_type;
|
||||||
|
CK_ATTRIBUTE unwrap_attribute = { CKA_UNWRAP, &can_unwrap, sizeof(can_unwrap) };
|
||||||
|
CK_ATTRIBUTE key_type_attr = { CKA_KEY_TYPE, &key_type, sizeof(key_type) };
|
||||||
|
struct sc_pkcs11_session *session;
|
||||||
|
struct sc_pkcs11_object *object;
|
||||||
|
struct sc_pkcs11_object *key_object;
|
||||||
|
|
||||||
|
if (pMechanism == NULL_PTR)
|
||||||
|
return CKR_ARGUMENTS_BAD;
|
||||||
|
|
||||||
|
rv = sc_pkcs11_lock();
|
||||||
|
if (rv != CKR_OK)
|
||||||
|
return rv;
|
||||||
|
|
||||||
|
rv = get_object_from_session(hSession, hUnwrappingKey, &session, &object);
|
||||||
|
if (rv != CKR_OK) {
|
||||||
|
if (rv == CKR_OBJECT_HANDLE_INVALID)
|
||||||
|
rv = CKR_KEY_HANDLE_INVALID;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
if (object->ops->unwrap_key == NULL_PTR) {
|
||||||
|
rv = CKR_KEY_TYPE_INCONSISTENT;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
rv = object->ops->get_attribute(session, object, &unwrap_attribute);
|
||||||
|
if (rv != CKR_OK || !can_unwrap) {
|
||||||
|
rv = CKR_KEY_TYPE_INCONSISTENT;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
rv = object->ops->get_attribute(session, object, &key_type_attr);
|
||||||
|
if (rv != CKR_OK) {
|
||||||
|
rv = CKR_KEY_TYPE_INCONSISTENT;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create the target object in memory */
|
||||||
|
rv = sc_create_object_int(hSession, pTemplate, ulAttributeCount, phKey, 0);
|
||||||
|
|
||||||
|
if (rv != CKR_OK)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
rv = get_object_from_session(hSession, *phKey, &session, &key_object);
|
||||||
|
if (rv != CKR_OK) {
|
||||||
|
if (rv == CKR_OBJECT_HANDLE_INVALID)
|
||||||
|
rv = CKR_KEY_HANDLE_INVALID;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
rv = restore_login_state(session->slot);
|
||||||
|
if (rv == CKR_OK)
|
||||||
|
rv = sc_pkcs11_unwrap(session, pMechanism, object, key_type,
|
||||||
|
hSession, pWrappedKey, ulWrappedKeyLen, key_object);
|
||||||
|
/* TODO if (rv != CK_OK) need to destroy the object */
|
||||||
|
rv = reset_login_state(session->slot, rv);
|
||||||
|
|
||||||
|
out:
|
||||||
|
sc_pkcs11_unlock();
|
||||||
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
CK_RV C_DeriveKey(CK_SESSION_HANDLE hSession, /* the session's handle */
|
CK_RV C_DeriveKey(CK_SESSION_HANDLE hSession, /* the session's handle */
|
||||||
|
|
|
@ -104,8 +104,7 @@ struct sc_pkcs11_object_ops {
|
||||||
CK_RV (*unwrap_key)(struct sc_pkcs11_session *, void *,
|
CK_RV (*unwrap_key)(struct sc_pkcs11_session *, void *,
|
||||||
CK_MECHANISM_PTR,
|
CK_MECHANISM_PTR,
|
||||||
CK_BYTE_PTR pData, CK_ULONG ulDataLen,
|
CK_BYTE_PTR pData, CK_ULONG ulDataLen,
|
||||||
CK_ATTRIBUTE_PTR, CK_ULONG,
|
void *targetKey);
|
||||||
void **);
|
|
||||||
CK_RV (*decrypt)(struct sc_pkcs11_session *, void *,
|
CK_RV (*decrypt)(struct sc_pkcs11_session *, void *,
|
||||||
CK_MECHANISM_PTR,
|
CK_MECHANISM_PTR,
|
||||||
CK_BYTE_PTR pEncryptedData, CK_ULONG ulEncryptedDataLen,
|
CK_BYTE_PTR pEncryptedData, CK_ULONG ulEncryptedDataLen,
|
||||||
|
@ -122,6 +121,11 @@ struct sc_pkcs11_object_ops {
|
||||||
/* General validation of mechanism parameters (sign, encrypt, etc) */
|
/* General validation of mechanism parameters (sign, encrypt, etc) */
|
||||||
CK_RV (*init_params)(struct sc_pkcs11_session *, CK_MECHANISM_PTR);
|
CK_RV (*init_params)(struct sc_pkcs11_session *, CK_MECHANISM_PTR);
|
||||||
|
|
||||||
|
CK_RV (*wrap_key)(struct sc_pkcs11_session *, void *,
|
||||||
|
CK_MECHANISM_PTR,
|
||||||
|
void*,
|
||||||
|
CK_BYTE_PTR pData, CK_ULONG_PTR ulDataLen);
|
||||||
|
|
||||||
/* Others to be added when implemented */
|
/* Others to be added when implemented */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -237,6 +241,8 @@ enum {
|
||||||
SC_PKCS11_OPERATION_DIGEST,
|
SC_PKCS11_OPERATION_DIGEST,
|
||||||
SC_PKCS11_OPERATION_DECRYPT,
|
SC_PKCS11_OPERATION_DECRYPT,
|
||||||
SC_PKCS11_OPERATION_DERIVE,
|
SC_PKCS11_OPERATION_DERIVE,
|
||||||
|
SC_PKCS11_OPERATION_WRAP,
|
||||||
|
SC_PKCS11_OPERATION_UNWRAP,
|
||||||
SC_PKCS11_OPERATION_MAX
|
SC_PKCS11_OPERATION_MAX
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -280,6 +286,15 @@ struct sc_pkcs11_mechanism_type {
|
||||||
struct sc_pkcs11_object *,
|
struct sc_pkcs11_object *,
|
||||||
CK_BYTE_PTR, CK_ULONG,
|
CK_BYTE_PTR, CK_ULONG,
|
||||||
CK_BYTE_PTR, CK_ULONG_PTR);
|
CK_BYTE_PTR, CK_ULONG_PTR);
|
||||||
|
CK_RV (*wrap)(sc_pkcs11_operation_t *,
|
||||||
|
struct sc_pkcs11_object *,
|
||||||
|
struct sc_pkcs11_object *,
|
||||||
|
CK_BYTE_PTR, CK_ULONG_PTR);
|
||||||
|
CK_RV (*unwrap)(sc_pkcs11_operation_t *,
|
||||||
|
struct sc_pkcs11_object *,
|
||||||
|
CK_BYTE_PTR, CK_ULONG,
|
||||||
|
struct sc_pkcs11_object *);
|
||||||
|
|
||||||
/* mechanism specific data */
|
/* mechanism specific data */
|
||||||
const void * mech_data;
|
const void * mech_data;
|
||||||
/* free mechanism specific data */
|
/* free mechanism specific data */
|
||||||
|
@ -419,6 +434,7 @@ CK_RV sc_pkcs11_verif_final(struct sc_pkcs11_session *, CK_BYTE_PTR, CK_ULONG);
|
||||||
#endif
|
#endif
|
||||||
CK_RV sc_pkcs11_decr_init(struct sc_pkcs11_session *, CK_MECHANISM_PTR, struct sc_pkcs11_object *, CK_MECHANISM_TYPE);
|
CK_RV sc_pkcs11_decr_init(struct sc_pkcs11_session *, CK_MECHANISM_PTR, struct sc_pkcs11_object *, CK_MECHANISM_TYPE);
|
||||||
CK_RV sc_pkcs11_decr(struct sc_pkcs11_session *, CK_BYTE_PTR, CK_ULONG, CK_BYTE_PTR, CK_ULONG_PTR);
|
CK_RV sc_pkcs11_decr(struct sc_pkcs11_session *, CK_BYTE_PTR, CK_ULONG, CK_BYTE_PTR, CK_ULONG_PTR);
|
||||||
|
CK_RV sc_pkcs11_unwrap(struct sc_pkcs11_session *,CK_MECHANISM_PTR, struct sc_pkcs11_object *, CK_KEY_TYPE, CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG, struct sc_pkcs11_object *);
|
||||||
CK_RV sc_pkcs11_deri(struct sc_pkcs11_session *, CK_MECHANISM_PTR,
|
CK_RV sc_pkcs11_deri(struct sc_pkcs11_session *, CK_MECHANISM_PTR,
|
||||||
struct sc_pkcs11_object *, CK_KEY_TYPE,
|
struct sc_pkcs11_object *, CK_KEY_TYPE,
|
||||||
CK_SESSION_HANDLE, CK_OBJECT_HANDLE, struct sc_pkcs11_object *);
|
CK_SESSION_HANDLE, CK_OBJECT_HANDLE, struct sc_pkcs11_object *);
|
||||||
|
|
|
@ -418,6 +418,12 @@ extern int sc_pkcs15init_sanity_check(struct sc_pkcs15_card *, struct sc_profile
|
||||||
extern int sc_pkcs15init_finalize_profile(struct sc_card *card, struct sc_profile *profile,
|
extern int sc_pkcs15init_finalize_profile(struct sc_card *card, struct sc_profile *profile,
|
||||||
struct sc_aid *aid);
|
struct sc_aid *aid);
|
||||||
|
|
||||||
|
extern int sc_pkcs15init_unwrap_key(struct sc_pkcs15_card *p15card, struct sc_profile *profile,
|
||||||
|
struct sc_pkcs15_object *key, u8* wrapped_key, size_t wrapped_key_len,
|
||||||
|
struct sc_pkcs15init_skeyargs *keyargs, struct sc_pkcs15_object **res_obj);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
extern struct sc_pkcs15init_operations *sc_pkcs15init_get_gpk_ops(void);
|
extern struct sc_pkcs15init_operations *sc_pkcs15init_get_gpk_ops(void);
|
||||||
extern struct sc_pkcs15init_operations *sc_pkcs15init_get_miocos_ops(void);
|
extern struct sc_pkcs15init_operations *sc_pkcs15init_get_miocos_ops(void);
|
||||||
extern struct sc_pkcs15init_operations *sc_pkcs15init_get_cryptoflex_ops(void);
|
extern struct sc_pkcs15init_operations *sc_pkcs15init_get_cryptoflex_ops(void);
|
||||||
|
|
|
@ -175,6 +175,7 @@ static struct sc_pkcs15init_callbacks callbacks = {
|
||||||
NULL,
|
NULL,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
static void sc_pkcs15init_empty_callback(void *ptr)
|
static void sc_pkcs15init_empty_callback(void *ptr)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -1880,8 +1881,9 @@ sc_pkcs15init_store_secret_key(struct sc_pkcs15_card *p15card, struct sc_profile
|
||||||
if (check_key_compatibility(p15card, keyargs->algorithm, NULL, 0, keyargs->key.data_len * 8, 0)) {
|
if (check_key_compatibility(p15card, keyargs->algorithm, NULL, 0, keyargs->key.data_len * 8, 0)) {
|
||||||
/* Make sure the caller explicitly tells us to store
|
/* Make sure the caller explicitly tells us to store
|
||||||
* the key as extractable. */
|
* the key as extractable. */
|
||||||
if (!(keyargs->access_flags & SC_PKCS15_PRKEY_ACCESS_EXTRACTABLE))
|
/* Commented out. I don't understand why one couldn't store a key as non extractable. -HH */
|
||||||
LOG_TEST_RET(ctx, SC_ERROR_INCOMPATIBLE_KEY, "Card does not support this key.");
|
/* if (!(keyargs->access_flags & SC_PKCS15_PRKEY_ACCESS_EXTRACTABLE))
|
||||||
|
LOG_TEST_RET(ctx, SC_ERROR_INCOMPATIBLE_KEY, "Card does not support this key.");*/
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef ENABLE_OPENSSL
|
#ifdef ENABLE_OPENSSL
|
||||||
|
@ -1908,6 +1910,9 @@ sc_pkcs15init_store_secret_key(struct sc_pkcs15_card *p15card, struct sc_profile
|
||||||
r = profile->ops->create_key(profile, p15card, object);
|
r = profile->ops->create_key(profile, p15card, object);
|
||||||
LOG_TEST_RET(ctx, r, "Card specific 'create key' failed");
|
LOG_TEST_RET(ctx, r, "Card specific 'create key' failed");
|
||||||
|
|
||||||
|
/* If no key data, only an empty EF is created.
|
||||||
|
* It can be used to receive an unwrapped key later. */
|
||||||
|
if (keyargs->key.data_len > 0) {
|
||||||
if (profile->ops->store_key) {
|
if (profile->ops->store_key) {
|
||||||
struct sc_pkcs15_prkey key;
|
struct sc_pkcs15_prkey key;
|
||||||
memset(&key, 0, sizeof(key));
|
memset(&key, 0, sizeof(key));
|
||||||
|
@ -1915,6 +1920,7 @@ sc_pkcs15init_store_secret_key(struct sc_pkcs15_card *p15card, struct sc_profile
|
||||||
key.u.secret = keyargs->key;
|
key.u.secret = keyargs->key;
|
||||||
r = profile->ops->store_key(profile, p15card, object, &key);
|
r = profile->ops->store_key(profile, p15card, object, &key);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
LOG_TEST_RET(ctx, r, "Card specific 'store key' failed");
|
LOG_TEST_RET(ctx, r, "Card specific 'store key' failed");
|
||||||
|
|
||||||
sc_pkcs15_free_object_content(object);
|
sc_pkcs15_free_object_content(object);
|
||||||
|
|
Loading…
Reference in New Issue