Implemented handling of CKA_ALWAYS_AUTHENTICATE attribute when importing and generating keys, mapping it to pkcs#15 userConsent field. Added command line options to pkcs11-tool and pkcs15-init tool to use the feature.
This commit is contained in:
parent
b01ca2dcc9
commit
ee8c80af4f
|
@ -2153,6 +2153,9 @@ pkcs15_create_private_key(struct sc_pkcs11_slot *slot, struct sc_profile *profil
|
|||
case CKA_OPENSC_NON_REPUDIATION:
|
||||
args.usage |= pkcs15_check_bool_cka(attr, SC_PKCS15_PRKEY_USAGE_NONREPUDIATION);
|
||||
break;
|
||||
case CKA_ALWAYS_AUTHENTICATE:
|
||||
args.user_consent = (int) (pkcs15_check_bool_cka(attr, 1));
|
||||
break;
|
||||
default:
|
||||
/* ignore unknown attrs, or flag error? */
|
||||
continue;
|
||||
|
@ -2318,7 +2321,10 @@ pkcs15_create_secret_key(struct sc_pkcs11_slot *slot, struct sc_profile *profile
|
|||
break;
|
||||
case CKA_EXTRACTABLE:
|
||||
if (pkcs15_check_bool_cka(attr, 1))
|
||||
args.access_flags |= SC_PKCS15_PRKEY_ACCESS_EXTRACTABLE;
|
||||
args.access_flags |= SC_PKCS15_PRKEY_ACCESS_EXTRACTABLE;
|
||||
break;
|
||||
case CKA_ALWAYS_AUTHENTICATE:
|
||||
args.user_consent = (int) (pkcs15_check_bool_cka(attr, 1));
|
||||
break;
|
||||
default:
|
||||
/* ignore unknown attrs, or flag error? */
|
||||
|
@ -2931,6 +2937,7 @@ pkcs15_gen_keypair(struct sc_pkcs11_slot *slot, CK_MECHANISM_PTR pMechanism,
|
|||
char priv_label[SC_PKCS15_MAX_LABEL_SIZE];
|
||||
int rc;
|
||||
CK_RV rv = CKR_OK;
|
||||
CK_BBOOL always_auth = CK_FALSE;
|
||||
|
||||
sc_log(context, "Keypair generation, mech = 0x%0lx",
|
||||
pMechanism->mechanism);
|
||||
|
@ -3046,6 +3053,12 @@ pkcs15_gen_keypair(struct sc_pkcs11_slot *slot, CK_MECHANISM_PTR pMechanism,
|
|||
goto kpgen_done;
|
||||
pub_args.x509_usage = keygen_args.prkey_args.x509_usage;
|
||||
|
||||
len = sizeof(always_auth);
|
||||
rv = attr_find(pPrivTpl, ulPrivCnt, CKA_ALWAYS_AUTHENTICATE, &always_auth, &len);
|
||||
if (rv == CKR_OK && always_auth == CK_TRUE) {
|
||||
keygen_args.prkey_args.user_consent = 1;
|
||||
}
|
||||
|
||||
/* 3.a Try on-card key pair generation */
|
||||
|
||||
sc_pkcs15init_set_p15card(profile, fw_data->p15_card);
|
||||
|
@ -4832,6 +4845,10 @@ pkcs15_skey_get_attribute(struct sc_pkcs11_session *session,
|
|||
&& (skey->base.p15_object->flags & SC_PKCS15_PRKEY_ACCESS_NEVEREXTRACTABLE) == 0
|
||||
&& (skey->base.p15_object->flags & SC_PKCS15_PRKEY_ACCESS_ALWAYSSENSITIVE) == 0) ? CK_TRUE : CK_FALSE;
|
||||
break;
|
||||
case CKA_ALWAYS_AUTHENTICATE:
|
||||
check_attribute_buffer(attr, sizeof(CK_BBOOL));
|
||||
*(CK_BBOOL*)attr->pValue = skey->base.p15_object->user_consent;
|
||||
break;
|
||||
case CKA_VALUE_LEN:
|
||||
check_attribute_buffer(attr, sizeof(CK_ULONG));
|
||||
*(CK_ULONG*)attr->pValue = skey->info->data.len;
|
||||
|
|
|
@ -228,6 +228,7 @@ struct sc_pkcs15init_prkeyargs {
|
|||
unsigned long x509_usage;
|
||||
unsigned int flags;
|
||||
unsigned int access_flags;
|
||||
int user_consent;
|
||||
|
||||
union {
|
||||
struct sc_pkcs15init_keyarg_gost_params gost;
|
||||
|
@ -269,13 +270,14 @@ struct sc_pkcs15init_skeyargs {
|
|||
struct sc_pkcs15_id id;
|
||||
struct sc_pkcs15_id auth_id;
|
||||
const char * label;
|
||||
unsigned long usage;
|
||||
unsigned long usage;
|
||||
unsigned int flags;
|
||||
unsigned int access_flags;
|
||||
unsigned long algorithm; /* User requested algorithm */
|
||||
unsigned long value_len; /* User requested length */
|
||||
int session_object; /* If nonzero. this is a session object, which will
|
||||
be cleared from card when the session is closed.*/
|
||||
int user_consent;
|
||||
struct sc_pkcs15_skey key;
|
||||
};
|
||||
|
||||
|
|
|
@ -1211,6 +1211,7 @@ sc_pkcs15init_init_prkdf(struct sc_pkcs15_card *p15card, struct sc_profile *prof
|
|||
key_info->key_reference = 0;
|
||||
key_info->modulus_length = keybits;
|
||||
key_info->access_flags = keyargs->access_flags;
|
||||
object->user_consent = keyargs->user_consent;
|
||||
/* Path is selected below */
|
||||
|
||||
if (keyargs->access_flags & SC_PKCS15_PRKEY_ACCESS_EXTRACTABLE) {
|
||||
|
@ -1352,6 +1353,8 @@ sc_pkcs15init_init_skdf(struct sc_pkcs15_card *p15card, struct sc_profile *profi
|
|||
if (keyargs->session_object > 0)
|
||||
object->session_object = 1;
|
||||
|
||||
object->user_consent = keyargs->user_consent;
|
||||
|
||||
/* Select a Key ID if the user didn't specify one,
|
||||
* otherwise make sure it's compatible with our intended use */
|
||||
r = select_id(p15card, SC_PKCS15_TYPE_SKEY, &keyargs->id);
|
||||
|
|
|
@ -152,6 +152,7 @@ enum {
|
|||
OPT_SALT,
|
||||
OPT_VERIFY,
|
||||
OPT_SIGNATURE_FILE,
|
||||
OPT_ALWAYS_AUTH
|
||||
};
|
||||
|
||||
static const struct option options[] = {
|
||||
|
@ -221,6 +222,7 @@ static const struct option options[] = {
|
|||
{ "test-fork", 0, NULL, OPT_TEST_FORK },
|
||||
#endif
|
||||
{ "generate-random", 1, NULL, OPT_GENERATE_RANDOM },
|
||||
{ "always-auth", 0, NULL, OPT_ALWAYS_AUTH },
|
||||
|
||||
{ NULL, 0, NULL, 0 }
|
||||
};
|
||||
|
@ -292,6 +294,7 @@ static const char *option_help[] = {
|
|||
"Test forking and calling C_Initialize() in the child",
|
||||
#endif
|
||||
"Generate given amount of random data",
|
||||
"Set the CKA_ALWAYS_AUTHENTICATE attribute to a key object (require PIN verification for each use)",
|
||||
};
|
||||
|
||||
static const char * app_name = "pkcs11-tool"; /* for utils.c */
|
||||
|
@ -340,6 +343,7 @@ static CK_MECHANISM_TYPE opt_hash_alg = 0;
|
|||
static unsigned long opt_mgf = 0;
|
||||
static long opt_salt_len = 0;
|
||||
static int opt_salt_len_given = 0; /* 0 - not given, 1 - given with input parameters */
|
||||
static int opt_always_auth = 0;
|
||||
|
||||
static void *module = NULL;
|
||||
static CK_FUNCTION_LIST_PTR p11 = NULL;
|
||||
|
@ -886,7 +890,9 @@ int main(int argc, char * argv[])
|
|||
do_generate_random = 1;
|
||||
action_count++;
|
||||
break;
|
||||
|
||||
case OPT_ALWAYS_AUTH:
|
||||
opt_always_auth = 1;
|
||||
break;
|
||||
default:
|
||||
util_print_usage_and_die(app_name, options, option_help, NULL);
|
||||
}
|
||||
|
@ -2380,6 +2386,12 @@ static int gen_keypair(CK_SLOT_ID slot, CK_SESSION_HANDLE session,
|
|||
n_pubkey_attr++;
|
||||
}
|
||||
|
||||
if (opt_always_auth != 0) {
|
||||
FILL_ATTR(privateKeyTemplate[n_privkey_attr], CKA_ALWAYS_AUTHENTICATE,
|
||||
&_true, sizeof(_true));
|
||||
n_privkey_attr++;
|
||||
}
|
||||
|
||||
rv = p11->C_GenerateKeyPair(session, &mechanism,
|
||||
publicKeyTemplate, n_pubkey_attr,
|
||||
privateKeyTemplate, n_privkey_attr,
|
||||
|
@ -2499,6 +2511,12 @@ gen_key(CK_SLOT_ID slot, CK_SESSION_HANDLE session, CK_OBJECT_HANDLE *hSecretKey
|
|||
FILL_ATTR(keyTemplate[n_attr], CKA_VALUE_LEN, &key_length, sizeof(key_length));
|
||||
n_attr++;
|
||||
|
||||
if (opt_always_auth != 0) {
|
||||
FILL_ATTR(keyTemplate[n_attr], CKA_ALWAYS_AUTHENTICATE,
|
||||
&_true, sizeof(_true));
|
||||
n_attr++;
|
||||
}
|
||||
|
||||
mechanism.mechanism = opt_mechanism;
|
||||
}
|
||||
|
||||
|
@ -2969,6 +2987,11 @@ static int write_object(CK_SESSION_HANDLE session)
|
|||
FILL_ATTR(privkey_templ[n_privkey_attr], CKA_DERIVE, &_true, sizeof(_true));
|
||||
n_privkey_attr++;
|
||||
}
|
||||
if (opt_always_auth != 0) {
|
||||
FILL_ATTR(privkey_templ[n_privkey_attr], CKA_ALWAYS_AUTHENTICATE,
|
||||
&_true, sizeof(_true));
|
||||
n_privkey_attr++;
|
||||
}
|
||||
|
||||
#ifdef ENABLE_OPENSSL
|
||||
if (cert.subject_len != 0) {
|
||||
|
|
|
@ -147,6 +147,7 @@ enum {
|
|||
OPT_UPDATE_EXISTING,
|
||||
OPT_MD_CONTAINER_GUID,
|
||||
OPT_VERSION,
|
||||
OPT_USER_CONSENT,
|
||||
|
||||
OPT_PIN1 = 0x10000, /* don't touch these values */
|
||||
OPT_PUK1 = 0x10001,
|
||||
|
@ -218,6 +219,7 @@ const struct option options[] = {
|
|||
{ "wait", no_argument, NULL, 'w' },
|
||||
{ "help", no_argument, NULL, 'h' },
|
||||
{ "verbose", no_argument, NULL, 'v' },
|
||||
{ "user-consent", required_argument, NULL, OPT_USER_CONSENT},
|
||||
|
||||
/* Hidden options for testing */
|
||||
{ "assert-pristine", no_argument, NULL, OPT_ASSERT_PRISTINE },
|
||||
|
@ -283,6 +285,7 @@ static const char * option_help[] = {
|
|||
"Wait for card insertion",
|
||||
"Display this message",
|
||||
"Verbose operation. Use several times to enable debug output.",
|
||||
"Set userConsent. Default = 0",
|
||||
|
||||
NULL,
|
||||
NULL,
|
||||
|
@ -394,6 +397,7 @@ static unsigned int opt_secret_count;
|
|||
static int opt_ignore_ca_certs = 0;
|
||||
static int opt_update_existing = 0;
|
||||
static int verbose = 0;
|
||||
static int opt_user_consent = 0;
|
||||
|
||||
static struct sc_pkcs15init_callbacks callbacks = {
|
||||
get_pin_callback, /* get_pin() */
|
||||
|
@ -1814,6 +1818,7 @@ static int init_prkeyargs(struct sc_pkcs15init_prkeyargs *args)
|
|||
args->guid = (unsigned char *)opt_md_container_guid;
|
||||
args->guid_len = strlen(opt_md_container_guid);
|
||||
}
|
||||
args->user_consent = opt_user_consent;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1842,6 +1847,7 @@ static int init_skeyargs(struct sc_pkcs15init_skeyargs *args)
|
|||
if ((opt_x509_usage & SC_PKCS15INIT_X509_KEY_ENCIPHERMENT) == SC_PKCS15INIT_X509_KEY_ENCIPHERMENT) {
|
||||
args->usage |= SC_PKCS15_PRKEY_USAGE_WRAP | SC_PKCS15_PRKEY_USAGE_UNWRAP;
|
||||
}
|
||||
args->user_consent = opt_user_consent;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -2848,6 +2854,10 @@ handle_option(const struct option *opt)
|
|||
case OPT_VERSION:
|
||||
this_action = ACTION_PRINT_VERSION;
|
||||
break;
|
||||
case OPT_USER_CONSENT:
|
||||
if (optarg != NULL)
|
||||
opt_user_consent = atoi(optarg);
|
||||
break;
|
||||
default:
|
||||
util_print_usage_and_die(app_name, options, option_help, NULL);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue