From b8bc3e183b43e9aeee8a8f23c8e48fffb6eedc35 Mon Sep 17 00:00:00 2001 From: Ingo Franzki Date: Fri, 4 Nov 2022 10:51:08 +0100 Subject: [PATCH 08/34] EP11: Supply CKA_PUBLIC_KEY_INFO when importing private keys When importing private keys, the SPKI of the corresponding public key is returned in parameters csum/cslen of the m_UnwrapKey() EP11 host library call. Supply this SPKI as CKA_PUBLIC_KEY_INFO to the object. For public key import, the common code already builds the SPKI from the clear public key attributes of the imported public key. Signed-off-by: Ingo Franzki --- usr/lib/common/obj_mgr.c | 5 ++ usr/lib/ep11_stdll/ep11_specific.c | 113 +++++++++++++++++++++++++------------ 2 files changed, 83 insertions(+), 35 deletions(-) diff --git a/usr/lib/common/obj_mgr.c b/usr/lib/common/obj_mgr.c index 8e61cbd4..347ec3f3 100644 --- a/usr/lib/common/obj_mgr.c +++ b/usr/lib/common/obj_mgr.c @@ -123,6 +123,11 @@ CK_RV object_mgr_add(STDLL_TokData_t *tokdata, switch(class) { case CKO_PUBLIC_KEY: case CKO_PRIVATE_KEY: + /* Skip if there is already a non-empty CKA_PUBLIC_KEY_INFO */ + if (template_attribute_get_non_empty(o->template, CKA_PUBLIC_KEY_INFO, + &spki_attr) == CKR_OK) + break; + rc = template_attribute_get_ulong(o->template, CKA_KEY_TYPE, &keytype); if (rc != CKR_OK) { TRACE_ERROR("Could not find CKA_KEY_TYPE for the key object.\n"); diff --git a/usr/lib/ep11_stdll/ep11_specific.c b/usr/lib/ep11_stdll/ep11_specific.c index 886692c4..3b14a557 100644 --- a/usr/lib/ep11_stdll/ep11_specific.c +++ b/usr/lib/ep11_stdll/ep11_specific.c @@ -2745,9 +2745,10 @@ static int get_curve_type_from_template(TEMPLATE *tmpl) * SPKIs for public imported RSA keys. * Similar to rawkey_2_blob, but keys must follow a standard BER encoding. */ -static CK_RV import_RSA_key(STDLL_TokData_t * tokdata, SESSION * sess, - OBJECT * rsa_key_obj, - CK_BYTE * blob, size_t * blob_size) +static CK_RV import_RSA_key(STDLL_TokData_t *tokdata, SESSION *sess, + OBJECT *rsa_key_obj, + CK_BYTE *blob, size_t *blob_size, + CK_BYTE *spki, size_t *spki_size) { ep11_private_data_t *ep11_data = tokdata->private_data; CK_RV rc; @@ -2759,8 +2760,6 @@ static CK_RV import_RSA_key(STDLL_TokData_t * tokdata, SESSION * sess, CK_ULONG attrs_len = 0; CK_ATTRIBUTE_PTR new_p_attrs = NULL; CK_ULONG new_attrs_len = 0; - CK_BYTE csum[MAX_BLOBSIZE]; - CK_ULONG cslen = sizeof(csum); CK_OBJECT_CLASS class; CK_BYTE *data = NULL; CK_ULONG data_len; @@ -2831,6 +2830,8 @@ static CK_RV import_RSA_key(STDLL_TokData_t * tokdata, SESSION * sess, goto import_RSA_key_end; } + *spki_size = 0; /* common code will extract SPKI from object */ + } else { /* imported private RSA key goes here */ @@ -2884,7 +2885,7 @@ static CK_RV import_RSA_key(STDLL_TokData_t * tokdata, SESSION * sess, ep11_data->raw2key_wrap_blob_l, NULL, ~0, ep11_pin_blob, ep11_pin_blob_len, &mech_w, new_p_attrs, new_attrs_len, blob, blob_size, - csum, &cslen, target_info->target); + spki, spki_size, target_info->target); RETRY_END(rc, tokdata, sess) if (rc != CKR_OK) { @@ -2921,9 +2922,10 @@ import_RSA_key_end: * SPKIs for public imported EC keys. * Similar to rawkey_2_blob, but keys must follow a standard BER encoding. */ -static CK_RV import_EC_key(STDLL_TokData_t * tokdata, SESSION * sess, - OBJECT * ec_key_obj, - CK_BYTE * blob, size_t * blob_size) +static CK_RV import_EC_key(STDLL_TokData_t *tokdata, SESSION *sess, + OBJECT *ec_key_obj, + CK_BYTE *blob, size_t *blob_size, + CK_BYTE *spki, size_t *spki_size) { ep11_private_data_t *ep11_data = tokdata->private_data; CK_RV rc; @@ -2935,8 +2937,6 @@ static CK_RV import_EC_key(STDLL_TokData_t * tokdata, SESSION * sess, CK_ULONG attrs_len = 0; CK_ATTRIBUTE_PTR new_p_attrs = NULL; CK_ULONG new_attrs_len = 0; - CK_BYTE csum[MAX_BLOBSIZE]; - CK_ULONG cslen = sizeof(csum); CK_OBJECT_CLASS class; CK_BYTE *data = NULL; CK_ULONG data_len; @@ -3059,6 +3059,8 @@ static CK_RV import_EC_key(STDLL_TokData_t * tokdata, SESSION * sess, goto import_EC_key_end; } + *spki_size = 0; /* common code will extract SPKI from object */ + } else { /* imported private EC key goes here */ @@ -3115,7 +3117,8 @@ static CK_RV import_EC_key(STDLL_TokData_t * tokdata, SESSION * sess, ep11_pin_blob, ep11_pin_blob_len, &mech_w, new_p_attrs, new_attrs_len, blob, - blob_size, csum, &cslen, target_info->target); + blob_size, spki, spki_size, + target_info->target); RETRY_END(rc, tokdata, sess) if (rc != CKR_OK) { @@ -3149,9 +3152,10 @@ import_EC_key_end: * SPKIs for public imported DSA keys. * Similar to rawkey_2_blob, but keys must follow a standard BER encoding. */ -static CK_RV import_DSA_key(STDLL_TokData_t * tokdata, SESSION * sess, - OBJECT * dsa_key_obj, - CK_BYTE * blob, size_t * blob_size) +static CK_RV import_DSA_key(STDLL_TokData_t *tokdata, SESSION *sess, + OBJECT *dsa_key_obj, + CK_BYTE *blob, size_t *blob_size, + CK_BYTE *spki, size_t *spki_size) { ep11_private_data_t *ep11_data = tokdata->private_data; CK_RV rc; @@ -3163,8 +3167,6 @@ static CK_RV import_DSA_key(STDLL_TokData_t * tokdata, SESSION * sess, CK_ULONG attrs_len = 0; CK_ATTRIBUTE_PTR new_p_attrs = NULL; CK_ULONG new_attrs_len = 0; - CK_BYTE csum[MAX_BLOBSIZE]; - CK_ULONG cslen = sizeof(csum); CK_OBJECT_CLASS class; CK_BYTE *data = NULL; CK_ULONG data_len; @@ -3251,6 +3253,8 @@ static CK_RV import_DSA_key(STDLL_TokData_t * tokdata, SESSION * sess, goto import_DSA_key_end; } + *spki_size = 0; /* common code will extract SPKI from object */ + } else { /* imported private DSA key goes here */ @@ -3307,7 +3311,8 @@ static CK_RV import_DSA_key(STDLL_TokData_t * tokdata, SESSION * sess, ep11_pin_blob, ep11_pin_blob_len, &mech_w, new_p_attrs, new_attrs_len, blob, - blob_size, csum, &cslen, target_info->target); + blob_size, spki, spki_size, + target_info->target); RETRY_END(rc, tokdata, sess) if (rc != CKR_OK) { @@ -3339,9 +3344,10 @@ import_DSA_key_end: * SPKIs for public imported DH keys. * Similar to rawkey_2_blob, but keys must follow a standard BER encoding. */ -static CK_RV import_DH_key(STDLL_TokData_t * tokdata, SESSION * sess, - OBJECT * dh_key_obj, - CK_BYTE * blob, size_t * blob_size) +static CK_RV import_DH_key(STDLL_TokData_t *tokdata, SESSION *sess, + OBJECT *dh_key_obj, + CK_BYTE *blob, size_t *blob_size, + CK_BYTE *spki, size_t *spki_size) { ep11_private_data_t *ep11_data = tokdata->private_data; CK_RV rc; @@ -3353,8 +3359,6 @@ static CK_RV import_DH_key(STDLL_TokData_t * tokdata, SESSION * sess, CK_ULONG attrs_len = 0; CK_ATTRIBUTE_PTR new_p_attrs = NULL; CK_ULONG new_attrs_len = 0; - CK_BYTE csum[MAX_BLOBSIZE]; - CK_ULONG cslen = sizeof(csum); CK_OBJECT_CLASS class; CK_BYTE *data = NULL; CK_ULONG data_len; @@ -3433,6 +3437,8 @@ static CK_RV import_DH_key(STDLL_TokData_t * tokdata, SESSION * sess, goto import_DH_key_end; } + *spki_size = 0; /* common code will extract SPKI from object */ + } else { CK_ATTRIBUTE *value; CK_ATTRIBUTE *value_bits; @@ -3500,7 +3506,8 @@ static CK_RV import_DH_key(STDLL_TokData_t * tokdata, SESSION * sess, ep11_pin_blob, ep11_pin_blob_len, &mech_w, new_p_attrs, new_attrs_len, blob, - blob_size, csum, &cslen, target_info->target); + blob_size, spki, spki_size, + target_info->target); RETRY_END(rc, tokdata, sess) if (rc != CKR_OK) { @@ -3547,9 +3554,10 @@ import_DH_key_end: * SPKIs for public imported IBM Dilithium keys. * Similar to rawkey_2_blob, but keys must follow a standard BER encoding. */ -static CK_RV import_IBM_Dilithium_key(STDLL_TokData_t * tokdata, SESSION * sess, - OBJECT * dilithium_key_obj, - CK_BYTE * blob, size_t * blob_size) +static CK_RV import_IBM_Dilithium_key(STDLL_TokData_t *tokdata, SESSION *sess, + OBJECT *dilithium_key_obj, + CK_BYTE *blob, size_t *blob_size, + CK_BYTE *spki, size_t *spki_size) { ep11_private_data_t *ep11_data = tokdata->private_data; CK_RV rc; @@ -3561,8 +3569,6 @@ static CK_RV import_IBM_Dilithium_key(STDLL_TokData_t * tokdata, SESSION * sess, CK_ULONG attrs_len = 0; CK_ATTRIBUTE_PTR new_p_attrs = NULL; CK_ULONG new_attrs_len = 0; - CK_BYTE csum[MAX_BLOBSIZE]; - CK_ULONG cslen = sizeof(csum); CK_OBJECT_CLASS class; CK_BYTE *data = NULL; CK_ULONG data_len; @@ -3652,6 +3658,8 @@ static CK_RV import_IBM_Dilithium_key(STDLL_TokData_t * tokdata, SESSION * sess, goto done; } + *spki_size = 0; /* common code will extract SPKI from object */ + } else { /* imported private IBM Dilithium key goes here */ @@ -3709,7 +3717,8 @@ static CK_RV import_IBM_Dilithium_key(STDLL_TokData_t * tokdata, SESSION * sess, ep11_pin_blob, ep11_pin_blob_len, &mech_w, new_p_attrs, new_attrs_len, blob, - blob_size, csum, &cslen, target_info->target); + blob_size, spki, spki_size, + target_info->target); RETRY_END(rc, tokdata, sess) if (rc != CKR_OK) { @@ -3747,9 +3756,13 @@ CK_RV token_specific_object_add(STDLL_TokData_t * tokdata, SESSION * sess, CK_ATTRIBUTE *attr = NULL; CK_BYTE blob[MAX_BLOBSIZE]; size_t blobsize = sizeof(blob); + CK_BYTE spki[MAX_BLOBSIZE]; + size_t spkisize = sizeof(spki); CK_RV rc; CK_ULONG class; CK_BBOOL attrbound; + CK_BYTE *temp; + CK_ULONG temp_len; /* get key type */ rc = template_attribute_get_ulong(obj->template, CKA_KEY_TYPE, &keytype); @@ -3783,7 +3796,8 @@ CK_RV token_specific_object_add(STDLL_TokData_t * tokdata, SESSION * sess, /* only these keys can be imported */ switch (keytype) { case CKK_RSA: - rc = import_RSA_key(tokdata, sess, obj, blob, &blobsize); + rc = import_RSA_key(tokdata, sess, obj, blob, &blobsize, + spki, &spkisize); if (rc != CKR_OK) { TRACE_ERROR("%s import RSA key rc=0x%lx blobsize=0x%zx\n", __func__, rc, blobsize); @@ -3793,7 +3807,8 @@ CK_RV token_specific_object_add(STDLL_TokData_t * tokdata, SESSION * sess, __func__, rc, blobsize); break; case CKK_EC: - rc = import_EC_key(tokdata, sess, obj, blob, &blobsize); + rc = import_EC_key(tokdata, sess, obj, blob, &blobsize, + spki, &spkisize); if (rc != CKR_OK) { TRACE_ERROR("%s import EC key rc=0x%lx blobsize=0x%zx\n", __func__, rc, blobsize); @@ -3803,7 +3818,8 @@ CK_RV token_specific_object_add(STDLL_TokData_t * tokdata, SESSION * sess, __func__, rc, blobsize); break; case CKK_DSA: - rc = import_DSA_key(tokdata, sess, obj, blob, &blobsize); + rc = import_DSA_key(tokdata, sess, obj, blob, &blobsize, + spki, &spkisize); if (rc != CKR_OK) { TRACE_ERROR("%s import DSA key rc=0x%lx blobsize=0x%zx\n", __func__, rc, blobsize); @@ -3813,7 +3829,8 @@ CK_RV token_specific_object_add(STDLL_TokData_t * tokdata, SESSION * sess, __func__, rc, blobsize); break; case CKK_DH: - rc = import_DH_key(tokdata, sess, obj, blob, &blobsize); + rc = import_DH_key(tokdata, sess, obj, blob, &blobsize, + spki, &spkisize); if (rc != CKR_OK) { TRACE_ERROR("%s import DH key rc=0x%lx blobsize=0x%zx\n", __func__, rc, blobsize); @@ -3823,7 +3840,8 @@ CK_RV token_specific_object_add(STDLL_TokData_t * tokdata, SESSION * sess, __func__, rc, blobsize); break; case CKK_IBM_PQC_DILITHIUM: - rc = import_IBM_Dilithium_key(tokdata, sess, obj, blob, &blobsize); + rc = import_IBM_Dilithium_key(tokdata, sess, obj, blob, &blobsize, + spki, &spkisize); if (rc != CKR_OK) { TRACE_ERROR("%s import IBM Dilithium key rc=0x%lx blobsize=0x%zx\n", __func__, rc, blobsize); @@ -3891,6 +3909,31 @@ CK_RV token_specific_object_add(STDLL_TokData_t * tokdata, SESSION * sess, return rc; } + if (spkisize > 0 && (class == CKO_PRIVATE_KEY || class == CKO_PUBLIC_KEY)) { + /* spki may be a MACed SPKI, get length of SPKI part only */ + rc = ber_decode_SEQUENCE(spki, &temp, &temp_len, &spkisize); + if (rc != CKR_OK) { + TRACE_ERROR("%s ber_decode_SEQUENCE failed rc=0x%lx\n", + __func__, rc); + return rc; + } + + rc = build_attribute(CKA_PUBLIC_KEY_INFO, spki, spkisize, &attr); + if (rc != CKR_OK) { + TRACE_ERROR("%s build_attribute failed with rc=0x%lx\n", __func__, + rc); + return rc; + } + + rc = template_update_attribute(obj->template, attr); + if (rc != CKR_OK) { + TRACE_ERROR("%s template_update_attribute failed with rc=0x%lx\n", + __func__, rc); + free(attr); + return rc; + } + } + rc = update_ep11_attrs_from_blob(tokdata, sess, obj->template); if (rc != CKR_OK) { TRACE_ERROR("%s update_ep11_attrs_from_blob failed with rc=0x%lx\n", -- 2.16.2.windows.1