diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index dba579a3..e6ab3574 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -3880,6 +3880,7 @@ pkcs15_pubkey_get_attribute(struct sc_pkcs11_session *session, void *object, CK_ case CKA_MODULUS: case CKA_MODULUS_BITS: case CKA_VALUE: + case CKA_SPKI: case CKA_PUBLIC_EXPONENT: case CKA_EC_PARAMS: case CKA_EC_POINT: @@ -3982,9 +3983,17 @@ pkcs15_pubkey_get_attribute(struct sc_pkcs11_session *session, void *object, CK_ return get_modulus_bits(pubkey->pub_data, attr); case CKA_PUBLIC_EXPONENT: return get_public_exponent(pubkey->pub_data, attr); + /* + * PKCS#11 does not define a CKA_VALUE for a CKO_PUBLIC_KEY. + * OpenSC does, but it is not consistent it what it returns + * Internally to do verify, with OpenSSL, we need a SPKI that + * can be converted into a EVP_KEY with d2i_PUBKEY + * CKA_SPKI is defined internally as a CKA_VENDOR_DFINED attribute. + */ case CKA_VALUE: + case CKA_SPKI: - if (pubkey->pub_info && pubkey->pub_info->direct.raw.value && pubkey->pub_info->direct.raw.len) { + if (attr->type != CKA_SPKI && pubkey->pub_info && pubkey->pub_info->direct.raw.value && pubkey->pub_info->direct.raw.len) { check_attribute_buffer(attr, pubkey->pub_info->direct.raw.len); memcpy(attr->pValue, pubkey->pub_info->direct.raw.value, pubkey->pub_info->direct.raw.len); } diff --git a/src/pkcs11/mechanism.c b/src/pkcs11/mechanism.c index 0ac4366a..8b1d18f4 100644 --- a/src/pkcs11/mechanism.c +++ b/src/pkcs11/mechanism.c @@ -686,7 +686,7 @@ sc_pkcs11_verify_final(sc_pkcs11_operation_t *operation, { struct signature_data *data; struct sc_pkcs11_object *key; - unsigned char *pubkey_value; + unsigned char *pubkey_value = NULL; CK_KEY_TYPE key_type; CK_BYTE params[9 /* GOST_PARAMS_OID_SIZE */] = { 0 }; CK_ATTRIBUTE attr = {CKA_VALUE, NULL, 0}; @@ -700,6 +700,14 @@ sc_pkcs11_verify_final(sc_pkcs11_operation_t *operation, return CKR_ARGUMENTS_BAD; key = data->key; + rv = key->ops->get_attribute(operation->session, key, &attr_key_type); + if (rv != CKR_OK) + return rv; + + if (key_type != CKK_GOSTR3410) + attr.type = CKA_SPKI; + + rv = key->ops->get_attribute(operation->session, key, &attr); if (rv != CKR_OK) return rv; @@ -713,8 +721,7 @@ sc_pkcs11_verify_final(sc_pkcs11_operation_t *operation, if (rv != CKR_OK) goto done; - rv = key->ops->get_attribute(operation->session, key, &attr_key_type); - if (rv == CKR_OK && key_type == CKK_GOSTR3410) { + if (key_type == CKK_GOSTR3410) { rv = key->ops->get_attribute(operation->session, key, &attr_key_params); if (rv != CKR_OK) goto done; diff --git a/src/pkcs11/openssl.c b/src/pkcs11/openssl.c index 77ce28d7..50b9b0a6 100644 --- a/src/pkcs11/openssl.c +++ b/src/pkcs11/openssl.c @@ -406,8 +406,7 @@ CK_RV sc_pkcs11_verify_data(const unsigned char *pubkey, int pubkey_len, int res; CK_RV rv = CKR_GENERAL_ERROR; EVP_PKEY *pkey = NULL; - const unsigned char *pubkey_tmp; - int is_spki = 0; + const unsigned char *pubkey_tmp = NULL; if (mech == CKM_GOSTR3410) { @@ -428,31 +427,8 @@ CK_RV sc_pkcs11_verify_data(const unsigned char *pubkey, int pubkey_len, * We can use d2i_PUBKEY which works for SPKI and any key type. */ pubkey_tmp = pubkey; /* pass in so pubkey pointer is not modified */ - /* SPKI ASN.1 starts with SEQUENCE, SEQUENCE, OBJECT IDENTIFIER */ - if (*pubkey_tmp++ == 0x30) { - if (*pubkey_tmp & 0x80) - pubkey_tmp += *pubkey_tmp & 0x7F; - pubkey_tmp++; - if (*pubkey_tmp++ == 0x30) { - if (*pubkey_tmp & 0x80) - pubkey_tmp += *pubkey_tmp & 0x7F; - - pubkey_tmp += 1; - if (*pubkey_tmp == 0x06) - is_spki = 1; - } - } - - pubkey_tmp = pubkey; /* pass in so pubkey pointer is not modified */ - - if (is_spki) { - pkey = d2i_PUBKEY(NULL, &pubkey_tmp, pubkey_len); - }else { - /* Assume it is RSA */ - /* TODO support others but GOST is done above, and EC always uses SPKI */ - pkey = d2i_PublicKey(EVP_PKEY_RSA, NULL, &pubkey_tmp, pubkey_len); - } + pkey = d2i_PUBKEY(NULL, &pubkey_tmp, pubkey_len); if (pkey == NULL) return CKR_GENERAL_ERROR; diff --git a/src/pkcs11/pkcs11-opensc.h b/src/pkcs11/pkcs11-opensc.h index d5272190..33beb6a3 100644 --- a/src/pkcs11/pkcs11-opensc.h +++ b/src/pkcs11/pkcs11-opensc.h @@ -9,4 +9,6 @@ */ #define CKA_OPENSC_NON_REPUDIATION (CKA_VENDOR_DEFINED | 1UL) +#define CKA_SPKI (CKA_VENDOR_DEFINED | 2UL) + #endif