pkcs15init: generalize key compatibility checking helpers
This commit is contained in:
parent
0576ccce0c
commit
048e703ab7
|
@ -109,14 +109,15 @@ static int do_select_parent(struct sc_profile *, struct sc_pkcs15_card *,
|
||||||
struct sc_file *, struct sc_file **);
|
struct sc_file *, struct sc_file **);
|
||||||
static int sc_pkcs15init_create_pin(struct sc_pkcs15_card *, struct sc_profile *,
|
static int sc_pkcs15init_create_pin(struct sc_pkcs15_card *, struct sc_profile *,
|
||||||
struct sc_pkcs15_object *, struct sc_pkcs15init_pinargs *);
|
struct sc_pkcs15_object *, struct sc_pkcs15init_pinargs *);
|
||||||
static int check_keygen_params_consistency(struct sc_card *card, struct sc_pkcs15init_keygen_args *args,
|
static int check_keygen_params_consistency(struct sc_card *card,
|
||||||
unsigned int bits, unsigned int *out_bits);
|
unsigned int alg, struct sc_pkcs15init_prkeyargs *prkey,
|
||||||
static int check_key_compatibility(struct sc_pkcs15_card *,
|
unsigned int *keybits);
|
||||||
|
static int check_key_compatibility(struct sc_pkcs15_card *, unsigned int,
|
||||||
struct sc_pkcs15_prkey *, unsigned int,
|
struct sc_pkcs15_prkey *, unsigned int,
|
||||||
unsigned int, unsigned int);
|
unsigned int, unsigned int);
|
||||||
static int prkey_fixup(struct sc_pkcs15_card *, struct sc_pkcs15_prkey *);
|
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_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_id(struct sc_pkcs15_card *, int, struct sc_pkcs15_id *);
|
||||||
static int select_object_path(struct sc_pkcs15_card *, struct sc_profile *,
|
static int select_object_path(struct sc_pkcs15_card *, struct sc_profile *,
|
||||||
struct sc_pkcs15_object *, struct sc_path *);
|
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.
|
/* Create the prkey object now.
|
||||||
* If we find out below that we're better off reusing an
|
* If we find out below that we're better off reusing an
|
||||||
* existing object, we'll ditch this one */
|
* 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;
|
r = key_type;
|
||||||
LOG_TEST_GOTO_ERR(ctx, r, "Unsupported 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);
|
LOG_FUNC_CALLED(ctx);
|
||||||
/* check supported key size */
|
/* 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");
|
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))
|
keybits, SC_ALGORITHM_ONBOARD_KEY_GEN))
|
||||||
LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "Cannot generate key with the given parameters");
|
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");
|
LOG_TEST_RET(ctx, keybits, "Invalid private key size");
|
||||||
|
|
||||||
/* Now check whether the card is able to handle this key */
|
/* 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
|
/* 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))
|
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.
|
* Check consistency of the key parameters.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
check_keygen_params_consistency(struct sc_card *card, struct sc_pkcs15init_keygen_args *params,
|
check_keygen_params_consistency(struct sc_card *card,
|
||||||
unsigned int keybits, unsigned int *out_keybits)
|
unsigned int alg, struct sc_pkcs15init_prkeyargs *prkey,
|
||||||
|
unsigned int *keybits)
|
||||||
{
|
{
|
||||||
struct sc_context *ctx = card->ctx;
|
struct sc_context *ctx = card->ctx;
|
||||||
unsigned int alg = params->prkey_args.key.algorithm;
|
|
||||||
int i, rv;
|
int i, rv;
|
||||||
|
|
||||||
if (alg == SC_ALGORITHM_EC) {
|
if (alg == SC_ALGORITHM_EC && prkey) {
|
||||||
struct sc_ec_parameters *ecparams = ¶ms->prkey_args.key.u.ec.params;
|
struct sc_ec_parameters *ecparams = &prkey->key.u.ec.params;
|
||||||
|
|
||||||
rv = sc_pkcs15_fix_ec_parameters(ctx, ecparams);
|
rv = sc_pkcs15_fix_ec_parameters(ctx, ecparams);
|
||||||
LOG_TEST_RET(ctx, rv, "Cannot fix EC parameters");
|
LOG_TEST_RET(ctx, rv, "Cannot fix EC parameters");
|
||||||
|
|
||||||
sc_log(ctx, "EC parameters: %s", sc_dump_hex(ecparams->der.value, ecparams->der.len));
|
sc_log(ctx, "EC parameters: %s", sc_dump_hex(ecparams->der.value, ecparams->der.len));
|
||||||
if (!keybits)
|
if (!*keybits)
|
||||||
keybits = ecparams->field_length;
|
*keybits = ecparams->field_length;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (out_keybits)
|
|
||||||
*out_keybits = keybits;
|
|
||||||
|
|
||||||
for (i = 0; i < card->algorithm_count; i++) {
|
for (i = 0; i < card->algorithm_count; i++) {
|
||||||
struct sc_algorithm_info *info = &card->algorithms[i];
|
struct sc_algorithm_info *info = &card->algorithms[i];
|
||||||
|
|
||||||
if (info->algorithm != alg)
|
if (info->algorithm != alg)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (info->key_length != keybits)
|
if (info->key_length != *keybits)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
LOG_FUNC_RETURN(ctx, SC_SUCCESS);
|
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.
|
* Check whether the card has native crypto support for this key.
|
||||||
*/
|
*/
|
||||||
static int
|
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)
|
unsigned int key_length, unsigned int flags)
|
||||||
{
|
{
|
||||||
struct sc_context *ctx = p15card->card->ctx;
|
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;
|
count = p15card->card->algorithm_count;
|
||||||
for (info = p15card->card->algorithms; count--; info++) {
|
for (info = p15card->card->algorithms; count--; info++) {
|
||||||
/* don't check flags if none was specified */
|
/* 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;
|
continue;
|
||||||
if (flags != 0 && ((info->flags & flags) != flags))
|
if (flags != 0 && ((info->flags & flags) != flags))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (key->algorithm == SC_ALGORITHM_RSA) {
|
if (alg == SC_ALGORITHM_RSA && prkey) {
|
||||||
if (info->u._rsa.exponent != 0 && key->u.rsa.exponent.len != 0) {
|
if (info->u._rsa.exponent != 0 && prkey->u.rsa.exponent.len != 0) {
|
||||||
struct sc_pkcs15_bignum *e = &key->u.rsa.exponent;
|
struct sc_pkcs15_bignum *e = &prkey->u.rsa.exponent;
|
||||||
unsigned long exponent = 0;
|
unsigned long exponent = 0;
|
||||||
unsigned int n;
|
unsigned int n;
|
||||||
|
|
||||||
|
@ -2158,12 +2160,12 @@ check_key_compatibility(struct sc_pkcs15_card *p15card, struct sc_pkcs15_prkey *
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (key->algorithm == SC_ALGORITHM_EC) {
|
else if (alg == SC_ALGORITHM_EC) {
|
||||||
if (!sc_valid_oid(&key->u.ec.params.id))
|
if (!sc_valid_oid(&prkey->u.ec.params.id))
|
||||||
if (sc_pkcs15_fix_ec_parameters(ctx, &key->u.ec.params))
|
if (sc_pkcs15_fix_ec_parameters(ctx, &prkey->u.ec.params))
|
||||||
LOG_FUNC_RETURN(ctx, SC_ERROR_OBJECT_NOT_VALID);
|
LOG_FUNC_RETURN(ctx, SC_ERROR_OBJECT_NOT_VALID);
|
||||||
if (sc_valid_oid(&info->u._ec.params.id))
|
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;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2320,11 +2322,11 @@ prkey_bits(struct sc_pkcs15_card *p15card, struct sc_pkcs15_prkey *key)
|
||||||
|
|
||||||
|
|
||||||
static int
|
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;
|
struct sc_context *ctx = p15card->card->ctx;
|
||||||
|
|
||||||
switch (key->algorithm) {
|
switch (algorithm) {
|
||||||
case SC_ALGORITHM_RSA:
|
case SC_ALGORITHM_RSA:
|
||||||
return SC_PKCS15_TYPE_PRKEY_RSA;
|
return SC_PKCS15_TYPE_PRKEY_RSA;
|
||||||
case SC_ALGORITHM_DSA:
|
case SC_ALGORITHM_DSA:
|
||||||
|
|
Loading…
Reference in New Issue