opencryptoki/SOURCES/0008-EP11-Supply-CKA_PUBLIC_KEY_INFO-when-importing-priva.patch
2023-05-17 02:26:01 +00:00

348 lines
15 KiB
Diff

From b8bc3e183b43e9aeee8a8f23c8e48fffb6eedc35 Mon Sep 17 00:00:00 2001
From: Ingo Franzki <ifranzki@linux.ibm.com>
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 <ifranzki@linux.ibm.com>
---
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