diff --git a/src/libopensc/asn1.c b/src/libopensc/asn1.c index bed2c04c..189075ba 100644 --- a/src/libopensc/asn1.c +++ b/src/libopensc/asn1.c @@ -1804,7 +1804,7 @@ sc_encode_oid (struct sc_context *ctx, struct sc_object_id *id, unsigned char **out, size_t *size) { static const struct sc_asn1_entry c_asn1_object_id[2] = { - { "oid", SC_ASN1_OBJECT, SC_ASN1_TAG_OBJECT, SC_ASN1_ALLOC, NULL, NULL }, + { "oid", SC_ASN1_OBJECT, SC_ASN1_TAG_OBJECT, SC_ASN1_ALLOC, NULL, NULL }, { NULL, 0, 0, 0, NULL, NULL } }; struct sc_asn1_entry asn1_object_id[2]; diff --git a/src/libopensc/card-myeid.c b/src/libopensc/card-myeid.c index 4b253f16..d906e0ef 100644 --- a/src/libopensc/card-myeid.c +++ b/src/libopensc/card-myeid.c @@ -119,9 +119,9 @@ static int myeid_init(struct sc_card *card) flags |= SC_ALGORITHM_ECDSA_RAW; ext_flags = SC_ALGORITHM_EXT_EC_NAMEDCURVE | SC_ALGORITHM_EXT_EC_UNCOMPRESES; - _sc_card_add_ec_alg(card, 192, flags, ext_flags); - _sc_card_add_ec_alg(card, 224, flags, ext_flags); - _sc_card_add_ec_alg(card, 256, flags, ext_flags); + _sc_card_add_ec_alg(card, 192, flags, ext_flags, NULL); + _sc_card_add_ec_alg(card, 224, flags, ext_flags, NULL); + _sc_card_add_ec_alg(card, 256, flags, ext_flags, NULL); #endif /* State that we have an RNG */ diff --git a/src/libopensc/card-piv.c b/src/libopensc/card-piv.c index 62ac7df1..e397c599 100644 --- a/src/libopensc/card-piv.c +++ b/src/libopensc/card-piv.c @@ -2882,8 +2882,8 @@ static int piv_init(sc_card_t *card) flags = SC_ALGORITHM_ECDSA_RAW; ext_flags = SC_ALGORITHM_EXT_EC_NAMEDCURVE | SC_ALGORITHM_EXT_EC_UNCOMPRESES; - _sc_card_add_ec_alg(card, 256, flags, ext_flags); - _sc_card_add_ec_alg(card, 384, flags, ext_flags); + _sc_card_add_ec_alg(card, 256, flags, ext_flags, NULL); + _sc_card_add_ec_alg(card, 384, flags, ext_flags, NULL); card->caps |= SC_CARD_CAP_RNG; diff --git a/src/libopensc/card-sc-hsm.c b/src/libopensc/card-sc-hsm.c index cb30ddcd..98f7b9e5 100644 --- a/src/libopensc/card-sc-hsm.c +++ b/src/libopensc/card-sc-hsm.c @@ -1053,10 +1053,10 @@ static int sc_hsm_init(struct sc_card *card) SC_ALGORITHM_EXT_EC_NAMEDCURVE| SC_ALGORITHM_EXT_EC_UNCOMPRESES| SC_ALGORITHM_ONBOARD_KEY_GEN; - _sc_card_add_ec_alg(card, 192, flags, ext_flags); - _sc_card_add_ec_alg(card, 224, flags, ext_flags); - _sc_card_add_ec_alg(card, 256, flags, ext_flags); - _sc_card_add_ec_alg(card, 320, flags, ext_flags); + _sc_card_add_ec_alg(card, 192, flags, ext_flags, NULL); + _sc_card_add_ec_alg(card, 224, flags, ext_flags, NULL); + _sc_card_add_ec_alg(card, 256, flags, ext_flags, NULL); + _sc_card_add_ec_alg(card, 320, flags, ext_flags, NULL); card->caps |= SC_CARD_CAP_RNG|SC_CARD_CAP_APDU_EXT; diff --git a/src/libopensc/card.c b/src/libopensc/card.c index d40dc821..b0ae035f 100644 --- a/src/libopensc/card.c +++ b/src/libopensc/card.c @@ -95,15 +95,34 @@ static void sc_card_free(sc_card_t *card) { sc_free_apps(card); sc_free_ef_atr(card); + if (card->ef_dir != NULL) sc_file_free(card->ef_dir); + free(card->ops); - if (card->algorithms != NULL) + + if (card->algorithms != NULL) { + int i; + for (i=0; ialgorithm_count; i++) { + struct sc_algorithm_info *info = (card->algorithms + i); + if (info->algorithm == SC_ALGORITHM_EC) { + struct sc_ec_parameters ep = info->u._ec.params; + + free(ep.named_curve); + free(ep.der.value); + } + } + card->algorithms = NULL; + card->algorithm_count = 0; free(card->algorithms); + } + if (card->cache.current_ef) sc_file_free(card->cache.current_ef); + if (card->cache.current_df) sc_file_free(card->cache.current_df); + if (card->mutex != NULL) { int r = sc_mutex_destroy(card->ctx, card->mutex); if (r != SC_SUCCESS) @@ -806,21 +825,27 @@ int _sc_card_add_algorithm(sc_card_t *card, const sc_algorithm_info_t *info) } int _sc_card_add_ec_alg(sc_card_t *card, unsigned int key_length, - unsigned long flags, unsigned long ext_flags) + unsigned long flags, unsigned long ext_flags, + struct sc_object_id *curve_oid) { sc_algorithm_info_t info; memset(&info, 0, sizeof(info)); + sc_init_oid(&info.u._ec.params.id); + info.algorithm = SC_ALGORITHM_EC; info.key_length = key_length; info.flags = flags; + info.u._ec.ext_flags = ext_flags; + if (curve_oid) + info.u._ec.params.id = *curve_oid; return _sc_card_add_algorithm(card, &info); } static sc_algorithm_info_t * sc_card_find_alg(sc_card_t *card, - unsigned int algorithm, unsigned int key_length) + unsigned int algorithm, unsigned int key_length, void *param) { int i; @@ -831,15 +856,20 @@ static sc_algorithm_info_t * sc_card_find_alg(sc_card_t *card, continue; if (info->key_length != key_length) continue; + if (param) { + if (info->algorithm == SC_ALGORITHM_EC) + if(sc_compare_oid((struct sc_object_id *)param, &info->u._ec.params.id)) + continue; + } return info; } return NULL; } sc_algorithm_info_t * sc_card_find_ec_alg(sc_card_t *card, - unsigned int key_length) + unsigned int key_length, struct sc_object_id *curve_name) { - return sc_card_find_alg(card, SC_ALGORITHM_EC, key_length); + return sc_card_find_alg(card, SC_ALGORITHM_EC, key_length, curve_name); } int _sc_card_add_rsa_alg(sc_card_t *card, unsigned int key_length, @@ -859,13 +889,13 @@ int _sc_card_add_rsa_alg(sc_card_t *card, unsigned int key_length, sc_algorithm_info_t * sc_card_find_rsa_alg(sc_card_t *card, unsigned int key_length) { - return sc_card_find_alg(card, SC_ALGORITHM_RSA, key_length); + return sc_card_find_alg(card, SC_ALGORITHM_RSA, key_length, NULL); } sc_algorithm_info_t * sc_card_find_gostr3410_alg(sc_card_t *card, unsigned int key_length) { - return sc_card_find_alg(card, SC_ALGORITHM_GOSTR3410, key_length); + return sc_card_find_alg(card, SC_ALGORITHM_GOSTR3410, key_length, NULL); } static int match_atr_table(sc_context_t *ctx, struct sc_atr_table *table, struct sc_atr *atr) diff --git a/src/libopensc/internal.h b/src/libopensc/internal.h index 4edad3d8..2658428b 100644 --- a/src/libopensc/internal.h +++ b/src/libopensc/internal.h @@ -121,7 +121,8 @@ int _sc_card_add_algorithm(struct sc_card *card, const struct sc_algorithm_info int _sc_card_add_rsa_alg(struct sc_card *card, unsigned int key_length, unsigned long flags, unsigned long exponent); int _sc_card_add_ec_alg(struct sc_card *card, unsigned int key_length, - unsigned long flags, unsigned long ext_flags); + unsigned long flags, unsigned long ext_flags, + struct sc_object_id *curve_oid); /********************************************************************/ /* pkcs1 padding/encoding functions */ diff --git a/src/libopensc/opensc.h b/src/libopensc/opensc.h index 5df97687..42d8bf10 100644 --- a/src/libopensc/opensc.h +++ b/src/libopensc/opensc.h @@ -191,10 +191,23 @@ struct sc_pbes2_params { struct sc_algorithm_id key_encr_alg; }; -struct sc_ec_params { +/* + * The ecParameters can be presented as + * - name of curve; + * - OID of named curve; + * - implicit parameters. + * + * type - type(choice) of 'EC domain parameters' as it present in CKA_EC_PARAMS (PKCS#11). + Recommended value '1' -- namedCurve. + * field_length - EC key size in bits. + */ +struct sc_ec_parameters { + char *named_curve; + struct sc_object_id id; + struct sc_lv_data der; + int type; - u8 * der; - size_t der_len; + size_t field_length; }; typedef struct sc_algorithm_info { @@ -208,6 +221,7 @@ typedef struct sc_algorithm_info { } _rsa; struct sc_ec_info { unsigned ext_flags; + struct sc_ec_parameters params; } _ec; } u; } sc_algorithm_info_t; @@ -1282,7 +1296,7 @@ void sc_print_cache(struct sc_card *card); struct sc_algorithm_info * sc_card_find_rsa_alg(struct sc_card *card, unsigned int key_length); struct sc_algorithm_info * sc_card_find_ec_alg(struct sc_card *card, - unsigned int field_length); + unsigned int field_length, struct sc_object_id *curve_oid); struct sc_algorithm_info * sc_card_find_gostr3410_alg(struct sc_card *card, unsigned int key_length); diff --git a/src/libopensc/pkcs15-algo.c b/src/libopensc/pkcs15-algo.c index 0bc69028..f66692de 100644 --- a/src/libopensc/pkcs15-algo.c +++ b/src/libopensc/pkcs15-algo.c @@ -249,8 +249,8 @@ asn1_free_pbes2_params(void *ptr) free(params); } -static const struct sc_asn1_entry c_asn1_ec_params[] = { - { "ecParameters", SC_ASN1_STRUCT, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, 0, NULL, NULL }, +static const struct sc_asn1_entry c_asn1_ec_params[] = { + { "ecParameters", SC_ASN1_STRUCT, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, 0, NULL, NULL }, { "namedCurve", SC_ASN1_OBJECT, SC_ASN1_TAG_OBJECT, 0, NULL, NULL}, { "implicityCA", SC_ASN1_NULL, SC_ASN1_TAG_NULL, 0, NULL, NULL }, { NULL, 0, 0, 0, NULL, NULL } @@ -263,49 +263,43 @@ asn1_decode_ec_params(sc_context_t *ctx, void **paramp, int r; struct sc_object_id curve; struct sc_asn1_entry asn1_ec_params[4]; - struct sc_ec_params * ecp; + struct sc_ec_parameters *ecp; sc_debug(ctx, SC_LOG_DEBUG_ASN1, "DEE - asn1_decode_ec_params %p:%d %d", buf, buflen, depth); memset(&curve, 0, sizeof(curve)); - ecp = malloc(sizeof(struct sc_ec_params)); - if (ecp == NULL) - return SC_ERROR_OUT_OF_MEMORY; - memset(ecp,0,sizeof(struct sc_ec_params)); - - /* We only want to copy the parms if they are a namedCurve - * or ecParameters nullParam aka implicityCA is not to be + /* We only want to copy the parms if they are a namedCurve + * or ecParameters nullParam aka implicityCA is not to be * used with PKCS#11 2.20 */ sc_copy_asn1_entry(c_asn1_ec_params, asn1_ec_params); sc_format_asn1_entry(asn1_ec_params + 1, &curve, 0, 0); /* Some signature algorithms will not have any data */ - if (buflen == 0 || buf == NULL) { - free(ecp); + if (buflen == 0 || buf == NULL) return 0; - } + + ecp = calloc(sizeof(struct sc_ec_parameters), 1); + if (ecp == NULL) + return SC_ERROR_OUT_OF_MEMORY; r = sc_asn1_decode_choice(ctx, asn1_ec_params, buf, buflen, NULL, NULL); - /* r = index into asn1_ec_params */ - sc_debug(ctx, SC_LOG_DEBUG_ASN1, "DEE - asn1_decode_ec_params r=%d", r); - if (r < 0) { - free(ecp); + /* r = index in asn1_ec_params */ + sc_debug(ctx, SC_LOG_DEBUG_ASN1, "asn1_decode_ec_params r=%d", r); + if (r < 0) return r; - } + if (r <= 1) { - ecp->der = malloc(buflen); - - if (ecp->der == NULL) + ecp->der.value = malloc(buflen); + if (ecp->der.value == NULL) return SC_ERROR_OUT_OF_MEMORY; - - ecp->der_len = buflen; - - sc_debug(ctx, SC_LOG_DEBUG_ASN1, "DEE - asn1_decode_ec_params paramp=%p %p:%d %d", - ecp, ecp->der, ecp->der_len, ecp->type); - memcpy(ecp->der, buf, buflen); /* copy der parameters */ - } else + ecp->der.len = buflen; + memcpy(ecp->der.value, buf, buflen); + } + else { r = 0; + } + ecp->type = r; /* but 0 = ecparams if any, 1=named curve */ *paramp = ecp; return 0; @@ -313,23 +307,25 @@ asn1_decode_ec_params(sc_context_t *ctx, void **paramp, static int asn1_encode_ec_params(sc_context_t *ctx, void *params, -u8 **buf, size_t *buflen, int depth) +u8 **buf, size_t *buflen, int depth) { - struct sc_ec_params * ecp = (struct sc_ec_params *) params; + struct sc_ec_parameters *ecp = (struct sc_ec_parameters *) params; /* Only handle named curves. They may be absent too */ - sc_debug(ctx, SC_LOG_DEBUG_ASN1, "DEE - asn1_encode_ec_params"); + sc_debug(ctx, SC_LOG_DEBUG_ASN1, "asn1_encode_ec_params() called"); *buf = NULL; *buflen = 0; - if (ecp && ecp->type == 1 && ecp->der) { /* named curve */ - *buf = malloc(ecp->der_len); + if (ecp && ecp->type == 1 && ecp->der.value) { /* named curve */ + *buf = malloc(ecp->der.len); if (*buf == NULL) return SC_ERROR_OUT_OF_MEMORY; - memcpy(*buf, ecp->der, ecp->der_len); - *buflen = ecp->der_len; - } else - sc_debug(ctx, SC_LOG_DEBUG_ASN1, "DEE - Not named curve"); + memcpy(*buf, ecp->der.value, ecp->der.len); + *buflen = ecp->der.len; + } + else { + sc_debug(ctx, SC_LOG_DEBUG_ASN1, "Not named curve"); + } return 0; } @@ -337,10 +333,13 @@ u8 **buf, size_t *buflen, int depth) static void asn1_free_ec_params(void *params) { - struct sc_ec_params * ecp = (struct sc_ec_params *) params; + struct sc_ec_parameters *ecp = (struct sc_ec_parameters *) params; + if (ecp) { - if (ecp->der) - free(ecp->der); + if (ecp->der.value) + free(ecp->der.value); + if (ecp->named_curve) + free(ecp->named_curve); free(ecp); } } diff --git a/src/libopensc/pkcs15-pubkey.c b/src/libopensc/pkcs15-pubkey.c index 8b96d8e3..16f01ade 100644 --- a/src/libopensc/pkcs15-pubkey.c +++ b/src/libopensc/pkcs15-pubkey.c @@ -812,20 +812,20 @@ sc_pkcs15_encode_pubkey_as_spki(sc_context_t *ctx, struct sc_pkcs15_pubkey *pubk pkey.len = 0; /* flag as do not delete */ if (pubkey->u.ec.params.named_curve || pubkey->u.ec.params.der.value) { - struct sc_ec_params *ec_params = NULL; + struct sc_ec_parameters *ec_params = NULL; r = sc_pkcs15_fix_ec_parameters(ctx, &pubkey->u.ec.params); LOG_TEST_RET(ctx, r, "failed to fix EC parameters"); - ec_params = calloc(1, sizeof(struct sc_ec_params)); + ec_params = calloc(1, sizeof(struct sc_ec_parameters)); if (!ec_params) LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY); ec_params->type = 1; - ec_params->der = calloc(pubkey->u.ec.params.der.len, 1); - if (!ec_params->der) + ec_params->der.value = calloc(pubkey->u.ec.params.der.len, 1); + if (!ec_params->der.value) LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY); - memcpy(ec_params->der, pubkey->u.ec.params.der.value, pubkey->u.ec.params.der.len); - ec_params->der_len = pubkey->u.ec.params.der.len; + memcpy(ec_params->der.value, pubkey->u.ec.params.der.value, pubkey->u.ec.params.der.len); + ec_params->der.len = pubkey->u.ec.params.der.len; pubkey->alg_id->params = ec_params; } break; @@ -1295,14 +1295,14 @@ sc_pkcs15_pubkey_from_spki_fields(struct sc_context *ctx, struct sc_pkcs15_pubke if (pk_alg.algorithm == SC_ALGORITHM_EC) { /* EC public key is not encapsulated into BIT STRING -- it's a BIT STRING */ if (pubkey->alg_id->params) { - struct sc_ec_params *ecp = (struct sc_ec_params *)pubkey->alg_id->params; + struct sc_ec_parameters *ecp = (struct sc_ec_parameters *)pubkey->alg_id->params; - pubkey->u.ec.params.der.value = malloc(ecp->der_len); + pubkey->u.ec.params.der.value = malloc(ecp->der.len); if (pubkey->u.ec.params.der.value == NULL) LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY); - memcpy(pubkey->u.ec.params.der.value, ecp->der, ecp->der_len); - pubkey->u.ec.params.der.len = ecp->der_len; + memcpy(pubkey->u.ec.params.der.value, ecp->der.value, ecp->der.len); + pubkey->u.ec.params.der.len = ecp->der.len; r = sc_pkcs15_fix_ec_parameters(ctx, &pubkey->u.ec.params); LOG_TEST_RET(ctx, r, "failed to fix EC parameters"); } @@ -1399,7 +1399,7 @@ static struct ec_curve_info { int -sc_pkcs15_fix_ec_parameters(struct sc_context *ctx, struct sc_pkcs15_ec_parameters *ecparams) +sc_pkcs15_fix_ec_parameters(struct sc_context *ctx, struct sc_ec_parameters *ecparams) { int rv, ii; diff --git a/src/libopensc/pkcs15-sc-hsm.c b/src/libopensc/pkcs15-sc-hsm.c index 03801cdb..77d329bb 100644 --- a/src/libopensc/pkcs15-sc-hsm.c +++ b/src/libopensc/pkcs15-sc-hsm.c @@ -374,7 +374,7 @@ static int sc_pkcs15emu_sc_hsm_get_rsa_public_key(struct sc_context *ctx, sc_cvc static int sc_pkcs15emu_sc_hsm_get_ec_public_key(struct sc_context *ctx, sc_cvc_t *cvc, struct sc_pkcs15_pubkey *pubkey) { - struct sc_ec_params *ecp; + struct sc_ec_parameters *ecp; const struct sc_lv_data *oid; int r; @@ -384,18 +384,18 @@ static int sc_pkcs15emu_sc_hsm_get_ec_public_key(struct sc_context *ctx, sc_cvc_ if (r != SC_SUCCESS) return r; - ecp = calloc(1, sizeof(struct sc_ec_params)); + ecp = calloc(1, sizeof(struct sc_ec_parameters)); if (!ecp) return SC_ERROR_OUT_OF_MEMORY; - ecp->der_len = oid->len + 2; - ecp->der = calloc(ecp->der_len, 1); - if (!ecp->der) + ecp->der.len = oid->len + 2; + ecp->der.value = calloc(ecp->der.len, 1); + if (!ecp->der.value) return SC_ERROR_OUT_OF_MEMORY; - ecp->der[0] = 0x06; - ecp->der[1] = (u8)oid->len; - memcpy(ecp->der + 2, oid->value, oid->len); + *(ecp->der.value + 0) = 0x06; + *(ecp->der.value + 1) = (u8)oid->len; + memcpy(ecp->der.value + 2, oid->value, oid->len); ecp->type = 1; // Named curve pubkey->alg_id = (struct sc_algorithm_id *)calloc(1, sizeof(struct sc_algorithm_id)); @@ -411,11 +411,11 @@ static int sc_pkcs15emu_sc_hsm_get_ec_public_key(struct sc_context *ctx, sc_cvc_ memcpy(pubkey->u.ec.ecpointQ.value, cvc->publicPoint, cvc->publicPointlen); pubkey->u.ec.ecpointQ.len = cvc->publicPointlen; - pubkey->u.ec.params.der.value = malloc(ecp->der_len); + pubkey->u.ec.params.der.value = malloc(ecp->der.len); if (!pubkey->u.ec.params.der.value) return SC_ERROR_OUT_OF_MEMORY; - memcpy(pubkey->u.ec.params.der.value, ecp->der, ecp->der_len); - pubkey->u.ec.params.der.len = ecp->der_len; + memcpy(pubkey->u.ec.params.der.value, ecp->der.value, ecp->der.len); + pubkey->u.ec.params.der.len = ecp->der.len; sc_pkcs15_fix_ec_parameters(ctx, &pubkey->u.ec.params); diff --git a/src/libopensc/pkcs15-sec.c b/src/libopensc/pkcs15-sec.c index e6ebafe0..3b8764ff 100644 --- a/src/libopensc/pkcs15-sec.c +++ b/src/libopensc/pkcs15-sec.c @@ -212,7 +212,7 @@ int sc_pkcs15_derive(struct sc_pkcs15_card *p15card, switch (obj->type) { case SC_PKCS15_TYPE_PRKEY_EC: - alg_info = sc_card_find_ec_alg(p15card->card, prkey->field_length); + alg_info = sc_card_find_ec_alg(p15card->card, prkey->field_length, NULL); if (alg_info == NULL) { sc_log(ctx, "Card does not support EC with field_size %d", prkey->field_length); LOG_FUNC_RETURN(ctx, SC_ERROR_NOT_SUPPORTED); @@ -352,7 +352,7 @@ int sc_pkcs15_compute_signature(struct sc_pkcs15_card *p15card, case SC_PKCS15_TYPE_PRKEY_EC: modlen = ((prkey->field_length +7) / 8) * 2; /* 2*nLen */ - alg_info = sc_card_find_ec_alg(p15card->card, prkey->field_length); + alg_info = sc_card_find_ec_alg(p15card->card, prkey->field_length, NULL); if (alg_info == NULL) { sc_log(ctx, "Card does not support EC with field_size %d", prkey->field_length); LOG_FUNC_RETURN(ctx, SC_ERROR_NOT_SUPPORTED); diff --git a/src/libopensc/pkcs15.h b/src/libopensc/pkcs15.h index 629902ce..b6958dd0 100644 --- a/src/libopensc/pkcs15.h +++ b/src/libopensc/pkcs15.h @@ -200,19 +200,6 @@ struct sc_pkcs15_prkey_dsa { sc_pkcs15_bignum_t priv; }; -/* - * The ecParameters can be presented as - * - named curve; - * - OID of named curve; - * - implicit parameters. - */ -struct sc_pkcs15_ec_parameters { - char *named_curve; - struct sc_object_id id; - struct sc_pkcs15_der der; - size_t field_length; /* in bits */ -}; - struct sc_pkcs15_gost_parameters { struct sc_object_id key; struct sc_object_id hash; @@ -220,12 +207,12 @@ struct sc_pkcs15_gost_parameters { }; struct sc_pkcs15_pubkey_ec { - struct sc_pkcs15_ec_parameters params; + struct sc_ec_parameters params; struct sc_pkcs15_u8 ecpointQ; /* This is NOT DER, just value and length */ }; struct sc_pkcs15_prkey_ec { - struct sc_pkcs15_ec_parameters params; + struct sc_ec_parameters params; sc_pkcs15_bignum_t privateD; /* note this is bignum */ struct sc_pkcs15_u8 ecpointQ; /* This is NOT DER, just value and length */ }; @@ -964,7 +951,7 @@ struct sc_supported_algo_info *sc_pkcs15_get_supported_algo(struct sc_pkcs15_car int sc_pkcs15_add_supported_algo_ref(struct sc_pkcs15_object *, struct sc_supported_algo_info *); -int sc_pkcs15_fix_ec_parameters(struct sc_context *, struct sc_pkcs15_ec_parameters *); +int sc_pkcs15_fix_ec_parameters(struct sc_context *, struct sc_ec_parameters *); /* Convert the OpenSSL key data type into the OpenSC key */ int sc_pkcs15_convert_bignum(sc_pkcs15_bignum_t *dst, const void *bignum); diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index 9111e510..d3001658 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -2763,7 +2763,7 @@ pkcs15_gen_keypair(struct sc_pkcs11_slot *slot, CK_MECHANISM_PTR pMechanism, /* TODO: check allowed values of keybits */ } else if (keytype == CKK_EC) { - struct sc_pkcs15_der *der = &keygen_args.prkey_args.key.u.ec.params.der; + struct sc_lv_data *der = &keygen_args.prkey_args.key.u.ec.params.der; der->len = sizeof(struct sc_object_id); rv = attr_find_ptr(pPubTpl, ulPubCnt, CKA_EC_PARAMS, (void **)&der->value, &der->len); @@ -4379,7 +4379,7 @@ get_public_exponent(struct sc_pkcs15_pubkey *key, CK_ATTRIBUTE_PTR attr) static CK_RV get_ec_pubkey_params(struct sc_pkcs15_pubkey *key, CK_ATTRIBUTE_PTR attr) { - struct sc_ec_params * ecp; + struct sc_ec_parameters *ecp; if (key == NULL) return CKR_ATTRIBUTE_TYPE_INVALID; @@ -4396,10 +4396,10 @@ get_ec_pubkey_params(struct sc_pkcs15_pubkey *key, CK_ATTRIBUTE_PTR attr) return CKR_OK; } - ecp = (struct sc_ec_params *) key->alg_id->params; - if (ecp && ecp->der && ecp->der_len) { - check_attribute_buffer(attr, ecp->der_len); - memcpy(attr->pValue, ecp->der, ecp->der_len); + ecp = (struct sc_ec_parameters *) key->alg_id->params; + if (ecp && ecp->der.value && ecp->der.len) { + check_attribute_buffer(attr, ecp->der.len); + memcpy(attr->pValue, ecp->der.value, ecp->der.len); return CKR_OK; } } diff --git a/src/pkcs15init/pkcs15-lib.c b/src/pkcs15init/pkcs15-lib.c index e5d30a81..cc655f6a 100644 --- a/src/pkcs15init/pkcs15-lib.c +++ b/src/pkcs15init/pkcs15-lib.c @@ -1214,7 +1214,7 @@ sc_pkcs15init_init_prkdf(struct sc_pkcs15_card *p15card, struct sc_profile *prof keyinfo_gostparams->gost28147 = keyargs->params.gost.gost28147; } else if (key->algorithm == SC_ALGORITHM_EC) { - struct sc_pkcs15_ec_parameters *ecparams = &keyargs->key.u.ec.params; + struct sc_ec_parameters *ecparams = &keyargs->key.u.ec.params; key_info->params.data = &keyargs->key.u.ec.params; key_info->params.free_params = sc_pkcs15init_empty_callback; key_info->field_length = ecparams->field_length; @@ -1975,7 +1975,7 @@ check_keygen_params_consistency(struct sc_card *card, struct sc_pkcs15init_keyge int i, rv; if (alg == SC_ALGORITHM_EC) { - struct sc_pkcs15_ec_parameters *ecparams = ¶ms->prkey_args.key.u.ec.params; + struct sc_ec_parameters *ecparams = ¶ms->prkey_args.key.u.ec.params; rv = sc_pkcs15_fix_ec_parameters(ctx, ecparams); LOG_TEST_RET(ctx, rv, "Cannot fix EC parameters"); @@ -2011,9 +2011,11 @@ static int check_key_compatibility(struct sc_pkcs15_card *p15card, struct sc_pkcs15_prkey *key, unsigned int x509_usage, unsigned int key_length, unsigned int flags) { + struct sc_context *ctx = p15card->card->ctx; struct sc_algorithm_info *info; unsigned int count; + LOG_FUNC_CALLED(ctx); count = p15card->card->algorithm_count; for (info = p15card->card->algorithms; count--; info++) { /* don't check flags if none was specified */ @@ -2039,12 +2041,18 @@ check_key_compatibility(struct sc_pkcs15_card *p15card, struct sc_pkcs15_prkey * } } else if (key->algorithm == SC_ALGORITHM_EC) { + if (!sc_valid_oid(&key->u.ec.params.id)) + if (sc_pkcs15_fix_ec_parameters(ctx, &key->u.ec.params)) + LOG_FUNC_RETURN(ctx, SC_ERROR_OBJECT_NOT_VALID); + if (sc_valid_oid(&info->u._ec.params.id)) + if (!sc_compare_oid(&info->u._ec.params.id, &key->u.ec.params.id)) + continue; } - return SC_SUCCESS; + LOG_FUNC_RETURN(ctx, SC_SUCCESS); } - return SC_ERROR_OBJECT_NOT_VALID; + LOG_FUNC_RETURN(ctx, SC_ERROR_OBJECT_NOT_VALID); } diff --git a/src/pkcs15init/pkcs15-sc-hsm.c b/src/pkcs15init/pkcs15-sc-hsm.c index 0f2fd8af..ddf84af9 100644 --- a/src/pkcs15init/pkcs15-sc-hsm.c +++ b/src/pkcs15init/pkcs15-sc-hsm.c @@ -173,7 +173,7 @@ static int sc_hsm_encode_gakp_rsa(struct sc_pkcs15_card *p15card, sc_cvc_t *cvc, static int sc_hsm_encode_gakp_ec(struct sc_pkcs15_card *p15card, sc_cvc_t *cvc, struct sc_pkcs15_prkey_info *key_info) { struct sc_object_id ecdsaWithSHA256 = { { 0,4,0,127,0,7,2,2,2,2,3,-1 } }; - struct sc_pkcs15_ec_parameters *ecparams = (struct sc_pkcs15_ec_parameters *)key_info->params.data; + struct sc_ec_parameters *ecparams = (struct sc_ec_parameters *)key_info->params.data; struct ec_curve *curve = NULL; u8 *curveoid; int curveoidlen,r;