From 048e703ab719e2dc2004da935f59661ae5bfdc05 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20Ter=C3=A4s?= Date: Wed, 12 Apr 2017 13:39:52 +0300 Subject: [PATCH] pkcs15init: generalize key compatibility checking helpers --- src/pkcs15init/pkcs15-lib.c | 62 +++++++++++++++++++------------------ 1 file changed, 32 insertions(+), 30 deletions(-) diff --git a/src/pkcs15init/pkcs15-lib.c b/src/pkcs15init/pkcs15-lib.c index e001e727..9e28278c 100644 --- a/src/pkcs15init/pkcs15-lib.c +++ b/src/pkcs15init/pkcs15-lib.c @@ -109,14 +109,15 @@ static int do_select_parent(struct sc_profile *, struct sc_pkcs15_card *, struct sc_file *, struct sc_file **); static int sc_pkcs15init_create_pin(struct sc_pkcs15_card *, struct sc_profile *, struct sc_pkcs15_object *, struct sc_pkcs15init_pinargs *); -static int check_keygen_params_consistency(struct sc_card *card, struct sc_pkcs15init_keygen_args *args, - unsigned int bits, unsigned int *out_bits); -static int check_key_compatibility(struct sc_pkcs15_card *, +static int check_keygen_params_consistency(struct sc_card *card, + unsigned int alg, struct sc_pkcs15init_prkeyargs *prkey, + unsigned int *keybits); +static int check_key_compatibility(struct sc_pkcs15_card *, unsigned int, struct sc_pkcs15_prkey *, unsigned int, unsigned int, unsigned int); static int prkey_fixup(struct sc_pkcs15_card *, struct sc_pkcs15_prkey *); static int prkey_bits(struct sc_pkcs15_card *, struct sc_pkcs15_prkey *); -static int prkey_pkcs15_algo(struct sc_pkcs15_card *, struct sc_pkcs15_prkey *); +static int key_pkcs15_algo(struct sc_pkcs15_card *, unsigned int); static int select_id(struct sc_pkcs15_card *, int, struct sc_pkcs15_id *); static int select_object_path(struct sc_pkcs15_card *, struct sc_profile *, struct sc_pkcs15_object *, struct sc_path *); @@ -1188,7 +1189,7 @@ sc_pkcs15init_init_prkdf(struct sc_pkcs15_card *p15card, struct sc_profile *prof /* Create the prkey object now. * If we find out below that we're better off reusing an * existing object, we'll ditch this one */ - key_type = prkey_pkcs15_algo(p15card, key); + key_type = key_pkcs15_algo(p15card, key->algorithm); r = key_type; LOG_TEST_GOTO_ERR(ctx, r, "Unsupported key type"); @@ -1348,10 +1349,13 @@ sc_pkcs15init_generate_key(struct sc_pkcs15_card *p15card, struct sc_profile *pr LOG_FUNC_CALLED(ctx); /* check supported key size */ - r = check_keygen_params_consistency(p15card->card, keygen_args, keybits, &keybits); + r = check_keygen_params_consistency(p15card->card, + keygen_args->prkey_args.key.algorithm, &keygen_args->prkey_args, + &keybits); LOG_TEST_RET(ctx, r, "Invalid key size"); - if (check_key_compatibility(p15card, &keygen_args->prkey_args.key, keygen_args->prkey_args.x509_usage, + if (check_key_compatibility(p15card, keygen_args->prkey_args.key.algorithm, + &keygen_args->prkey_args.key, keygen_args->prkey_args.x509_usage, keybits, SC_ALGORITHM_ONBOARD_KEY_GEN)) LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "Cannot generate key with the given parameters"); @@ -1483,7 +1487,7 @@ sc_pkcs15init_store_private_key(struct sc_pkcs15_card *p15card, struct sc_profil LOG_TEST_RET(ctx, keybits, "Invalid private key size"); /* Now check whether the card is able to handle this key */ - if (check_key_compatibility(p15card, &key, keyargs->x509_usage, keybits, 0)) { + if (check_key_compatibility(p15card, key.algorithm, &key, keyargs->x509_usage, keybits, 0)) { /* Make sure the caller explicitly tells us to store * the key as extractable. */ if (!(keyargs->access_flags & SC_PKCS15_PRKEY_ACCESS_EXTRACTABLE)) @@ -2085,34 +2089,31 @@ sc_pkcs15init_keybits(struct sc_pkcs15_bignum *bn) * Check consistency of the key parameters. */ static int -check_keygen_params_consistency(struct sc_card *card, struct sc_pkcs15init_keygen_args *params, - unsigned int keybits, unsigned int *out_keybits) +check_keygen_params_consistency(struct sc_card *card, + unsigned int alg, struct sc_pkcs15init_prkeyargs *prkey, + unsigned int *keybits) { struct sc_context *ctx = card->ctx; - unsigned int alg = params->prkey_args.key.algorithm; int i, rv; - if (alg == SC_ALGORITHM_EC) { - struct sc_ec_parameters *ecparams = ¶ms->prkey_args.key.u.ec.params; + if (alg == SC_ALGORITHM_EC && prkey) { + struct sc_ec_parameters *ecparams = &prkey->key.u.ec.params; rv = sc_pkcs15_fix_ec_parameters(ctx, ecparams); LOG_TEST_RET(ctx, rv, "Cannot fix EC parameters"); sc_log(ctx, "EC parameters: %s", sc_dump_hex(ecparams->der.value, ecparams->der.len)); - if (!keybits) - keybits = ecparams->field_length; + if (!*keybits) + *keybits = ecparams->field_length; } - if (out_keybits) - *out_keybits = keybits; - for (i = 0; i < card->algorithm_count; i++) { struct sc_algorithm_info *info = &card->algorithms[i]; if (info->algorithm != alg) continue; - if (info->key_length != keybits) + if (info->key_length != *keybits) continue; LOG_FUNC_RETURN(ctx, SC_SUCCESS); @@ -2126,7 +2127,8 @@ check_keygen_params_consistency(struct sc_card *card, struct sc_pkcs15init_keyge * Check whether the card has native crypto support for this key. */ static int -check_key_compatibility(struct sc_pkcs15_card *p15card, struct sc_pkcs15_prkey *key, unsigned int x509_usage, +check_key_compatibility(struct sc_pkcs15_card *p15card, unsigned int alg, + struct sc_pkcs15_prkey *prkey, unsigned int x509_usage, unsigned int key_length, unsigned int flags) { struct sc_context *ctx = p15card->card->ctx; @@ -2137,14 +2139,14 @@ check_key_compatibility(struct sc_pkcs15_card *p15card, struct sc_pkcs15_prkey * count = p15card->card->algorithm_count; for (info = p15card->card->algorithms; count--; info++) { /* don't check flags if none was specified */ - if (info->algorithm != key->algorithm || info->key_length != key_length) + if (info->algorithm != alg || info->key_length != key_length) continue; if (flags != 0 && ((info->flags & flags) != flags)) continue; - if (key->algorithm == SC_ALGORITHM_RSA) { - if (info->u._rsa.exponent != 0 && key->u.rsa.exponent.len != 0) { - struct sc_pkcs15_bignum *e = &key->u.rsa.exponent; + if (alg == SC_ALGORITHM_RSA && prkey) { + if (info->u._rsa.exponent != 0 && prkey->u.rsa.exponent.len != 0) { + struct sc_pkcs15_bignum *e = &prkey->u.rsa.exponent; unsigned long exponent = 0; unsigned int n; @@ -2158,12 +2160,12 @@ check_key_compatibility(struct sc_pkcs15_card *p15card, struct sc_pkcs15_prkey * continue; } } - 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)) + else if (alg == SC_ALGORITHM_EC) { + if (!sc_valid_oid(&prkey->u.ec.params.id)) + if (sc_pkcs15_fix_ec_parameters(ctx, &prkey->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)) + if (!sc_compare_oid(&info->u._ec.params.id, &prkey->u.ec.params.id)) continue; } @@ -2320,11 +2322,11 @@ prkey_bits(struct sc_pkcs15_card *p15card, struct sc_pkcs15_prkey *key) static int -prkey_pkcs15_algo(struct sc_pkcs15_card *p15card, struct sc_pkcs15_prkey *key) +key_pkcs15_algo(struct sc_pkcs15_card *p15card, unsigned int algorithm) { struct sc_context *ctx = p15card->card->ctx; - switch (key->algorithm) { + switch (algorithm) { case SC_ALGORITHM_RSA: return SC_PKCS15_TYPE_PRKEY_RSA; case SC_ALGORITHM_DSA: