Skip to content

Commit

Permalink
Implement special parameter to define Key Usage
Browse files Browse the repository at this point in the history
This allows an application finer control on what usage will be allowed
for the key.

Fixes #285

Signed-off-by: Simo Sorce <simo@redhat.com>
  • Loading branch information
simo5 committed Sep 6, 2023
1 parent cd2b377 commit dd47127
Show file tree
Hide file tree
Showing 2 changed files with 152 additions and 27 deletions.
178 changes: 151 additions & 27 deletions src/keymgmt.c
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ struct key_generator {
CK_KEY_TYPE type;

P11PROV_URI *uri;
char *key_usage;

CK_MECHANISM mechanism;

Expand Down Expand Up @@ -220,6 +221,14 @@ static int p11prov_common_gen_set_params(void *genctx,
}
}

p = OSSL_PARAM_locate_const(params, P11PROV_PARAM_KEY_USAGE);
if (p) {
ret = OSSL_PARAM_get_utf8_string(p, &ctx->key_usage, 0);
if (ret != RET_OSSL_OK) {
return ret;
}
}

switch (ctx->type) {
case CKK_RSA:
p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_BITS);
Expand Down Expand Up @@ -334,6 +343,118 @@ static CK_RV common_gen_callback(void *cbarg)
return CKR_OK;
}

/* Common attributes that may currently be added to the template
* CKA_ID
* CKA_LABEL
*/
#define COMMON_TMPL_SIZE 2

const CK_BBOOL val_true = CK_TRUE;
const CK_BBOOL val_false = CK_FALSE;
#define DISCARD_CONST(x) (void *)(x)

static void common_key_usage_set_attrs(CK_ATTRIBUTE *template, int tsize,
bool enc, bool sig, bool der, bool wrap)
{
for (int i = 0; i < tsize; i++) {
switch (template[i].type) {
case CKA_ENCRYPT:
case CKA_DECRYPT:
if (enc) {
template[i].pValue = DISCARD_CONST(&val_true);
} else {
template[i].pValue = DISCARD_CONST(&val_false);
}
break;
case CKA_VERIFY:
case CKA_VERIFY_RECOVER:
case CKA_SIGN:
case CKA_SIGN_RECOVER:
if (sig) {
template[i].pValue = DISCARD_CONST(&val_true);
} else {
template[i].pValue = DISCARD_CONST(&val_false);
}
break;
case CKA_DERIVE:
if (der) {
template[i].pValue = DISCARD_CONST(&val_true);
} else {
template[i].pValue = DISCARD_CONST(&val_false);
}
break;
case CKA_WRAP:
case CKA_UNWRAP:
if (wrap) {
template[i].pValue = DISCARD_CONST(&val_true);
} else {
template[i].pValue = DISCARD_CONST(&val_false);
}
break;
default:
break;
}
}
}

/*
* Takes a KEy Usage string, which must be a space separated list of tokens.
* The tokens are the Key usage flag names as defined in ISO/IEC 9594-8 (X.509)
* Only the following tokens are recognized:
* - dataEncipherment
* - digitalSignature
* - keyAgreement
* - keyEncipherment
* uses: Table 25 from pkcs#11 3.1 spec for mappings for public keys
* and an analogous mapping for private keys
*/
static CK_RV common_key_usage_to_tmpl(struct key_generator *ctx,
CK_ATTRIBUTE *pubtmpl,
CK_ATTRIBUTE *privtmpl, int pubtsize,
int privtsize)
{
const char *str = NULL;
size_t len = 0;
bool enc = false;
bool sig = false;
bool der = false;
bool wrap = false;

if (!ctx->key_usage) {
/* leave defaults as set by templates */
return CKR_OK;
}

str = ctx->key_usage;
len = strlen(ctx->key_usage);
while (str) {
size_t toklen = len;
const char *p = strchr(str, ' ');
if (p) {
toklen = p - str;
p += 1;
}
if (strncmp(str, "dataEncipherment", toklen) == 0) {
enc = true;
} else if (strncmp(str, "digitalSignature", toklen) == 0) {
sig = true;
} else if (strncmp(str, "keyAgreement", toklen) == 0) {
der = true;
} else if (strncmp(str, "keyEncipherment", toklen) == 0) {
wrap = true;
} else {
return CKR_ARGUMENTS_BAD;
}
str = p;
len -= toklen;
}

common_key_usage_set_attrs(pubtmpl, pubtsize, enc, sig, der, wrap);
common_key_usage_set_attrs(privtmpl, privtsize, enc, sig, der, wrap);

return CKR_OK;
}

static void *p11prov_common_gen(struct key_generator *ctx,
CK_ATTRIBUTE *pubkey_template,
CK_ATTRIBUTE *privkey_template, int pubtsize,
Expand All @@ -351,6 +472,13 @@ static void *p11prov_common_gen(struct key_generator *ctx,
CK_ATTRIBUTE label = { 0 };
CK_RV ret;

ret = common_key_usage_to_tmpl(ctx, pubkey_template, privkey_template,
pubtsize, privtsize);
if (ret != CKR_OK) {
P11PROV_raise(ctx->provctx, ret, "Failed to map Key Usage");
return NULL;
}

if (ctx->uri) {
cka_id = p11prov_uri_get_id(ctx->uri);
label = p11prov_uri_get_label(ctx->uri);
Expand Down Expand Up @@ -483,29 +611,27 @@ static void *p11prov_rsa_gen_init(void *provctx, int selection,
static void *p11prov_rsa_gen(void *genctx, OSSL_CALLBACK *cb_fn, void *cb_arg)
{
struct key_generator *ctx = (struct key_generator *)genctx;
CK_BBOOL val_true = CK_TRUE;
/* CK_BBOOL val_false = CK_FALSE; */

/* always leave space for CKA_ID and CKA_LABEL */
#define RSA_PUBKEY_TMPL_SIZE 6
CK_ATTRIBUTE pubkey_template[RSA_PUBKEY_TMPL_SIZE + 2] = {
{ CKA_ENCRYPT, &val_true, sizeof(val_true) },
{ CKA_VERIFY, &val_true, sizeof(val_true) },
{ CKA_WRAP, &val_true, sizeof(val_true) },
{ CKA_TOKEN, &val_true, sizeof(CK_BBOOL) },
CK_ATTRIBUTE pubkey_template[RSA_PUBKEY_TMPL_SIZE + COMMON_TMPL_SIZE] = {
{ CKA_ENCRYPT, DISCARD_CONST(&val_true), sizeof(CK_BBOOL) },
{ CKA_VERIFY, DISCARD_CONST(&val_true), sizeof(CK_BBOOL) },
{ CKA_WRAP, DISCARD_CONST(&val_true), sizeof(CK_BBOOL) },
{ CKA_TOKEN, DISCARD_CONST(&val_true), sizeof(CK_BBOOL) },
{ CKA_MODULUS_BITS, &ctx->data.rsa.modulus_bits,
sizeof(ctx->data.rsa.modulus_bits) },
{ CKA_PUBLIC_EXPONENT, &ctx->data.rsa.exponent,
ctx->data.rsa.exponent_size },
};
#define RSA_PRIVKEY_TMPL_SIZE 6
CK_ATTRIBUTE privkey_template[RSA_PRIVKEY_TMPL_SIZE + 2] = {
{ CKA_TOKEN, &val_true, sizeof(CK_BBOOL) },
{ CKA_PRIVATE, &val_true, sizeof(CK_BBOOL) },
{ CKA_SENSITIVE, &val_true, sizeof(CK_BBOOL) },
{ CKA_DECRYPT, &val_true, sizeof(CK_BBOOL) },
{ CKA_SIGN, &val_true, sizeof(CK_BBOOL) },
{ CKA_UNWRAP, &val_true, sizeof(CK_BBOOL) },
CK_ATTRIBUTE privkey_template[RSA_PRIVKEY_TMPL_SIZE + COMMON_TMPL_SIZE] = {
{ CKA_TOKEN, DISCARD_CONST(&val_true), sizeof(CK_BBOOL) },
{ CKA_PRIVATE, DISCARD_CONST(&val_true), sizeof(CK_BBOOL) },
{ CKA_SENSITIVE, DISCARD_CONST(&val_true), sizeof(CK_BBOOL) },
{ CKA_DECRYPT, DISCARD_CONST(&val_true), sizeof(CK_BBOOL) },
{ CKA_SIGN, DISCARD_CONST(&val_true), sizeof(CK_BBOOL) },
{ CKA_UNWRAP, DISCARD_CONST(&val_true), sizeof(CK_BBOOL) },
/* TODO?
* CKA_SUBJECT
* CKA_COPYABLE = true ?
Expand Down Expand Up @@ -1019,26 +1145,24 @@ static void *p11prov_ec_gen_init(void *provctx, int selection,
static void *p11prov_ec_gen(void *genctx, OSSL_CALLBACK *cb_fn, void *cb_arg)
{
struct key_generator *ctx = (struct key_generator *)genctx;
CK_BBOOL val_true = CK_TRUE;
/* CK_BBOOL val_false = CK_FALSE; */

/* always leave space for CKA_ID and CKA_LABEL */
#define EC_PUBKEY_TMPL_SIZE 5
CK_ATTRIBUTE pubkey_template[EC_PUBKEY_TMPL_SIZE + 2] = {
{ CKA_TOKEN, &val_true, sizeof(CK_BBOOL) },
{ CKA_DERIVE, &val_true, sizeof(val_true) },
{ CKA_VERIFY, &val_true, sizeof(val_true) },
{ CKA_WRAP, &val_true, sizeof(val_true) },
CK_ATTRIBUTE pubkey_template[EC_PUBKEY_TMPL_SIZE + COMMON_TMPL_SIZE] = {
{ CKA_TOKEN, DISCARD_CONST(&val_true), sizeof(CK_BBOOL) },
{ CKA_DERIVE, DISCARD_CONST(&val_true), sizeof(CK_BBOOL) },
{ CKA_VERIFY, DISCARD_CONST(&val_true), sizeof(CK_BBOOL) },
{ CKA_WRAP, DISCARD_CONST(&val_true), sizeof(CK_BBOOL) },
{ CKA_EC_PARAMS, (CK_BYTE *)ctx->data.ec.ec_params,
ctx->data.ec.ec_params_size },
};
#define EC_PRIVKEY_TMPL_SIZE 6
CK_ATTRIBUTE privkey_template[EC_PRIVKEY_TMPL_SIZE + 2] = {
{ CKA_TOKEN, &val_true, sizeof(CK_BBOOL) },
{ CKA_PRIVATE, &val_true, sizeof(CK_BBOOL) },
{ CKA_SENSITIVE, &val_true, sizeof(CK_BBOOL) },
{ CKA_SIGN, &val_true, sizeof(CK_BBOOL) },
{ CKA_UNWRAP, &val_true, sizeof(CK_BBOOL) },
CK_ATTRIBUTE privkey_template[EC_PRIVKEY_TMPL_SIZE + COMMON_TMPL_SIZE] = {
{ CKA_TOKEN, DISCARD_CONST(&val_true), sizeof(CK_BBOOL) },
{ CKA_PRIVATE, DISCARD_CONST(&val_true), sizeof(CK_BBOOL) },
{ CKA_SENSITIVE, DISCARD_CONST(&val_true), sizeof(CK_BBOOL) },
{ CKA_SIGN, DISCARD_CONST(&val_true), sizeof(CK_BBOOL) },
{ CKA_UNWRAP, DISCARD_CONST(&val_true), sizeof(CK_BBOOL) },
/* TODO?
* CKA_SUBJECT
* CKA_COPYABLE = true ?
Expand Down
1 change: 1 addition & 0 deletions src/provider.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
#define P11PROV_DESCS_RAND "PKCS11 Random Generator"

#define P11PROV_PARAM_URI "pkcs11_uri"
#define P11PROV_PARAM_KEY_USAGE "pkcs11_key_usage"
#define P11PROV_PARAM_SLOT_ID "pkcs11_slot_id"

typedef struct p11prov_ctx P11PROV_CTX;
Expand Down

0 comments on commit dd47127

Please sign in to comment.