diff --git a/src/libopensc/errors.c b/src/libopensc/errors.c index 0bd322c8..be01c422 100644 --- a/src/libopensc/errors.c +++ b/src/libopensc/errors.c @@ -104,7 +104,7 @@ const char *sc_strerror(int error) "Inconsistent or incomplete PKCS#15 profile", "Key length/algorithm not supported by card", "No default (transport) key available", - "UNUSED", + "Non unique object ID", "Unable to load key and certificate(s) from file", "UNUSED", "File template not found", diff --git a/src/libopensc/errors.h b/src/libopensc/errors.h index 9a124219..b3b54033 100644 --- a/src/libopensc/errors.h +++ b/src/libopensc/errors.h @@ -99,7 +99,7 @@ extern "C" { #define SC_ERROR_INCONSISTENT_PROFILE -1502 #define SC_ERROR_INCOMPATIBLE_KEY -1503 #define SC_ERROR_NO_DEFAULT_KEY -1504 -/* Unused: -1505 */ +#define SC_ERROR_NON_UNIQUE_ID -1505 #define SC_ERROR_CANNOT_LOAD_KEY -1506 /* Unused: -1007 */ #define SC_ERROR_TEMPLATE_NOT_FOUND -1508 diff --git a/src/pkcs15init/pkcs15-lib.c b/src/pkcs15init/pkcs15-lib.c index e7b69de1..7ca14e77 100644 --- a/src/pkcs15init/pkcs15-lib.c +++ b/src/pkcs15init/pkcs15-lib.c @@ -1195,7 +1195,16 @@ sc_pkcs15init_generate_key(struct sc_pkcs15_card *p15card, if (profile->ops->generate_key == NULL) LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "Key generation not supported"); - caller_supplied_id = keygen_args->prkey_args.id.len != 0; + if (keygen_args->prkey_args.id.len) { + caller_supplied_id = 1; + + /* Make sure that private key's ID is the unique inside the PKCS#15 application */ + r = sc_pkcs15_find_prkey_by_id(p15card, &keygen_args->prkey_args.id, NULL); + if (!r) + LOG_TEST_RET(ctx, SC_ERROR_NON_UNIQUE_ID, "Non unique ID of the private key object"); + else if (r != SC_ERROR_OBJECT_NOT_FOUND) + LOG_TEST_RET(ctx, r, "Find private key error"); + } /* Set up the PrKDF object */ r = sc_pkcs15init_init_prkdf(p15card, profile, &keygen_args->prkey_args, @@ -1284,15 +1293,13 @@ sc_pkcs15init_store_private_key(struct sc_pkcs15_card *p15card, 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, 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)) LOG_TEST_RET(ctx, SC_ERROR_INCOMPATIBLE_KEY, "Card does not support this key."); - if (!keyargs->passphrase - && !(keyargs->flags & SC_PKCS15INIT_NO_PASSPHRASE)) + if (!keyargs->passphrase && !(keyargs->flags & SC_PKCS15INIT_NO_PASSPHRASE)) LOG_TEST_RET(ctx, SC_ERROR_PASSPHRASE_REQUIRED, "No key encryption passphrase given."); } @@ -1300,6 +1307,13 @@ sc_pkcs15init_store_private_key(struct sc_pkcs15_card *p15card, r = select_intrinsic_id(p15card, profile, SC_PKCS15_TYPE_PRKEY, &keyargs->id, &keyargs->key); LOG_TEST_RET(ctx, r, "Get intrinsic ID error"); + /* Make sure that private key's ID is the unique inside the PKCS#15 application */ + r = sc_pkcs15_find_prkey_by_id(p15card, &keyargs->id, NULL); + if (!r) + LOG_TEST_RET(ctx, SC_ERROR_NON_UNIQUE_ID, "Non unique ID of the private key object"); + else if (r != SC_ERROR_OBJECT_NOT_FOUND) + LOG_TEST_RET(ctx, r, "Find private key error"); + /* Set up the PrKDF object */ r = sc_pkcs15init_init_prkdf(p15card, profile, keyargs, &key, keybits, &object); LOG_TEST_RET(ctx, r, "Failed to initialize private key object");