pkcs11-tool: Allow to set CKA_ALLOWED_MECHANISMS when creating an objects

Also list them in the attributes listing
This commit is contained in:
Jakub Jelen 2019-03-08 17:52:31 +01:00 committed by Frank Morgner
parent 775d120517
commit fc4d600634
2 changed files with 83 additions and 2 deletions

View File

@ -453,6 +453,17 @@
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term>
<option>--allowed-mechanisms</option> <replaceable>mechanisms</replaceable>
</term>
<listitem><para>Sets the CKA_ALLOWED_MECHANISMS attribute
to a key objects when importing an object or generating
a keys. The argument accepts comma-separated list of
algorithmsm, that can be used with the given key.</para>
</listitem>
</varlistentry>
<varlistentry> <varlistentry>
<term> <term>
<option>--test-ec</option> <option>--test-ec</option>

View File

@ -155,7 +155,8 @@ enum {
OPT_SALT, OPT_SALT,
OPT_VERIFY, OPT_VERIFY,
OPT_SIGNATURE_FILE, OPT_SIGNATURE_FILE,
OPT_ALWAYS_AUTH OPT_ALWAYS_AUTH,
OPT_ALLOWED_MECHANISMS
}; };
static const struct option options[] = { static const struct option options[] = {
@ -213,6 +214,7 @@ static const struct option options[] = {
{ "signature-file", 1, NULL, OPT_SIGNATURE_FILE }, { "signature-file", 1, NULL, OPT_SIGNATURE_FILE },
{ "output-file", 1, NULL, 'o' }, { "output-file", 1, NULL, 'o' },
{ "signature-format", 1, NULL, 'f' }, { "signature-format", 1, NULL, 'f' },
{ "allowed-mechanisms", 1, NULL, OPT_ALLOWED_MECHANISMS },
{ "test", 0, NULL, 't' }, { "test", 0, NULL, 't' },
{ "test-hotplug", 0, NULL, OPT_TEST_HOTPLUG }, { "test-hotplug", 0, NULL, OPT_TEST_HOTPLUG },
@ -285,6 +287,7 @@ static const char *option_help[] = {
"Specify the file with signature for verification", "Specify the file with signature for verification",
"Specify the output file", "Specify the output file",
"Format for ECDSA signature <arg>: 'rs' (default), 'sequence', 'openssl'", "Format for ECDSA signature <arg>: 'rs' (default), 'sequence', 'openssl'",
"Specify the comma-separated list of allowed mechanisms when creating an object.",
"Test (best used with the --login or --pin option)", "Test (best used with the --login or --pin option)",
"Test hotplug capabilities (C_GetSlotList + C_WaitForSlotEvent)", "Test hotplug capabilities (C_GetSlotList + C_WaitForSlotEvent)",
@ -332,6 +335,9 @@ static char * opt_issuer = NULL;
static char * opt_subject = NULL; static char * opt_subject = NULL;
static char * opt_key_type = NULL; static char * opt_key_type = NULL;
static char * opt_sig_format = NULL; static char * opt_sig_format = NULL;
#define MAX_ALLOWED_MECHANISMS 20
static CK_MECHANISM_TYPE opt_allowed_mechanisms[MAX_ALLOWED_MECHANISMS];
static size_t opt_allowed_mechanisms_len = 0;
static int opt_is_private = 0; static int opt_is_private = 0;
static int opt_is_sensitive = 0; static int opt_is_sensitive = 0;
static int opt_test_hotplug = 0; static int opt_test_hotplug = 0;
@ -496,7 +502,7 @@ get##ATTR(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj, CK_ULONG_PTR pulCount) \
} \ } \
if (pulCount) \ if (pulCount) \
*pulCount = attr.ulValueLen / sizeof(TYPE); \ *pulCount = attr.ulValueLen / sizeof(TYPE); \
} else { \ } else if (rv != CKR_ATTRIBUTE_TYPE_INVALID) { \
p11_warn("C_GetAttributeValue(" #ATTR ")", rv); \ p11_warn("C_GetAttributeValue(" #ATTR ")", rv); \
} \ } \
return (TYPE *) attr.pValue; \ return (TYPE *) attr.pValue; \
@ -534,6 +540,7 @@ VARATTR_METHOD(VALUE, unsigned char); /* getVALUE */
VARATTR_METHOD(GOSTR3410_PARAMS, unsigned char); /* getGOSTR3410_PARAMS */ VARATTR_METHOD(GOSTR3410_PARAMS, unsigned char); /* getGOSTR3410_PARAMS */
VARATTR_METHOD(EC_POINT, unsigned char); /* getEC_POINT */ VARATTR_METHOD(EC_POINT, unsigned char); /* getEC_POINT */
VARATTR_METHOD(EC_PARAMS, unsigned char); /* getEC_PARAMS */ VARATTR_METHOD(EC_PARAMS, unsigned char); /* getEC_PARAMS */
VARATTR_METHOD(ALLOWED_MECHANISMS, CK_MECHANISM_TYPE); /* getALLOWED_MECHANISMS */
int main(int argc, char * argv[]) int main(int argc, char * argv[])
@ -571,6 +578,7 @@ int main(int argc, char * argv[])
int do_unlock_pin = 0; int do_unlock_pin = 0;
int action_count = 0; int action_count = 0;
int do_generate_random = 0; int do_generate_random = 0;
char *s = NULL;
CK_RV rv; CK_RV rv;
#ifdef _WIN32 #ifdef _WIN32
@ -896,6 +904,22 @@ int main(int argc, char * argv[])
case OPT_ALWAYS_AUTH: case OPT_ALWAYS_AUTH:
opt_always_auth = 1; opt_always_auth = 1;
break; break;
case OPT_ALLOWED_MECHANISMS:
/* Parse the mechanism list and fail early */
s = strtok(optarg, ",");
while (s != NULL) {
if (opt_allowed_mechanisms_len > MAX_ALLOWED_MECHANISMS) {
fprintf(stderr, "Too many mechanisms provided"
" (max %d). Skipping the rest.", MAX_ALLOWED_MECHANISMS);
break;
}
opt_allowed_mechanisms[opt_allowed_mechanisms_len] =
p11_name_to_mechanism(s);
opt_allowed_mechanisms_len++;
s = strtok(NULL, ",");
}
break;
default: default:
util_print_usage_and_die(app_name, options, option_help, NULL); util_print_usage_and_die(app_name, options, option_help, NULL);
} }
@ -2186,6 +2210,7 @@ static void hash_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session)
#define FILL_ATTR(attr, typ, val, len) {(attr).type=(typ); (attr).pValue=(val); (attr).ulValueLen=len;} #define FILL_ATTR(attr, typ, val, len) {(attr).type=(typ); (attr).pValue=(val); (attr).ulValueLen=len;}
/* Generate asymmetric key pair */
static int gen_keypair(CK_SLOT_ID slot, CK_SESSION_HANDLE session, static int gen_keypair(CK_SLOT_ID slot, CK_SESSION_HANDLE session,
CK_OBJECT_HANDLE *hPublicKey, CK_OBJECT_HANDLE *hPrivateKey, const char *type) CK_OBJECT_HANDLE *hPublicKey, CK_OBJECT_HANDLE *hPrivateKey, const char *type)
{ {
@ -2402,6 +2427,13 @@ static int gen_keypair(CK_SLOT_ID slot, CK_SESSION_HANDLE session,
n_privkey_attr++; n_privkey_attr++;
} }
if (opt_allowed_mechanisms_len > 0) {
FILL_ATTR(privateKeyTemplate[n_privkey_attr],
CKA_ALLOWED_MECHANISMS, opt_allowed_mechanisms,
sizeof(CK_MECHANISM_TYPE) * opt_allowed_mechanisms_len);
n_privkey_attr++;
}
rv = p11->C_GenerateKeyPair(session, &mechanism, rv = p11->C_GenerateKeyPair(session, &mechanism,
publicKeyTemplate, n_pubkey_attr, publicKeyTemplate, n_pubkey_attr,
privateKeyTemplate, n_privkey_attr, privateKeyTemplate, n_privkey_attr,
@ -2419,6 +2451,7 @@ static int gen_keypair(CK_SLOT_ID slot, CK_SESSION_HANDLE session,
return 1; return 1;
} }
/* generate symmetric key */
static int static int
gen_key(CK_SLOT_ID slot, CK_SESSION_HANDLE session, CK_OBJECT_HANDLE *hSecretKey, gen_key(CK_SLOT_ID slot, CK_SESSION_HANDLE session, CK_OBJECT_HANDLE *hSecretKey,
const char *type, char *label) const char *type, char *label)
@ -2538,6 +2571,13 @@ gen_key(CK_SLOT_ID slot, CK_SESSION_HANDLE session, CK_OBJECT_HANDLE *hSecretKey
n_attr++; n_attr++;
} }
if (opt_allowed_mechanisms_len > 0) {
FILL_ATTR(keyTemplate[n_attr],
CKA_ALLOWED_MECHANISMS, opt_allowed_mechanisms,
sizeof(CK_MECHANISM_TYPE) * opt_allowed_mechanisms_len);
n_attr++;
}
rv = p11->C_GenerateKey(session, &mechanism, keyTemplate, n_attr, hSecretKey); rv = p11->C_GenerateKey(session, &mechanism, keyTemplate, n_attr, hSecretKey);
if (rv != CKR_OK) if (rv != CKR_OK)
p11_fatal("C_GenerateKey", rv); p11_fatal("C_GenerateKey", rv);
@ -2996,6 +3036,13 @@ static int write_object(CK_SESSION_HANDLE session)
&_true, sizeof(_true)); &_true, sizeof(_true));
n_privkey_attr++; n_privkey_attr++;
} }
if (opt_allowed_mechanisms_len > 0) {
FILL_ATTR(privkey_templ[n_privkey_attr],
CKA_ALLOWED_MECHANISMS, opt_allowed_mechanisms,
sizeof(CK_MECHANISM_TYPE) * opt_allowed_mechanisms_len);
n_privkey_attr++;
}
#ifdef ENABLE_OPENSSL #ifdef ENABLE_OPENSSL
if (cert.subject_len != 0) { if (cert.subject_len != 0) {
@ -3533,6 +3580,13 @@ derive_ec_key(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE key, CK_MECHANISM_TYPE
FILL_ATTR(newkey_template[n_attrs], CKA_VALUE_LEN, &key_len, sizeof(key_len)); FILL_ATTR(newkey_template[n_attrs], CKA_VALUE_LEN, &key_len, sizeof(key_len));
n_attrs++; n_attrs++;
if (opt_allowed_mechanisms_len > 0) {
FILL_ATTR(newkey_template[n_attrs],
CKA_ALLOWED_MECHANISMS, opt_allowed_mechanisms,
sizeof(CK_MECHANISM_TYPE) * opt_allowed_mechanisms_len);
n_attrs++;
}
buf_size = EC_POINT_point2oct(ecgroup, ecpoint, POINT_CONVERSION_UNCOMPRESSED, NULL, 0, NULL); buf_size = EC_POINT_point2oct(ecgroup, ecpoint, POINT_CONVERSION_UNCOMPRESSED, NULL, 0, NULL);
buf = (unsigned char *)malloc(buf_size); buf = (unsigned char *)malloc(buf_size);
if (buf == NULL) if (buf == NULL)
@ -3631,6 +3685,7 @@ derive_key(CK_SLOT_ID slot, CK_SESSION_HANDLE session, CK_OBJECT_HANDLE key)
static void static void
show_key(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj) show_key(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj)
{ {
CK_MECHANISM_TYPE_PTR mechs = NULL;
CK_KEY_TYPE key_type = getKEY_TYPE(sess, obj); CK_KEY_TYPE key_type = getKEY_TYPE(sess, obj);
CK_ULONG size = 0; CK_ULONG size = 0;
unsigned char *id, *oid, *value; unsigned char *id, *oid, *value;
@ -3836,6 +3891,21 @@ show_key(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj)
if (!pub && getALWAYS_AUTHENTICATE(sess, obj)) if (!pub && getALWAYS_AUTHENTICATE(sess, obj))
printf(" Access: always authenticate\n"); printf(" Access: always authenticate\n");
if (!pub) {
mechs = getALLOWED_MECHANISMS(sess, obj, &size);
if (mechs && size) {
unsigned int n;
printf(" Allowed mechanisms: ");
for (n = 0; n < size; n++) {
printf("%s%s", (n != 0 ? "," : ""),
p11_mechanism_to_name(mechs[n]));
}
printf("\n");
}
}
suppress_warn = 0; suppress_warn = 0;
} }