Add new attribute CKA_SPKI for CKO_PUBLIC_KEY

CKA_SPKI is a vendor defined attribute to be used internally
as input to to OpenSSL d2i_PUBKEY

 On branch verify-pubkey-as-spki-2
 Changes to be committed:
	modified:   framework-pkcs15.c
	modified:   mechanism.c
	modified:   openssl.c
	modified:   pkcs11-opensc.h
This commit is contained in:
Doug Engert 2017-04-08 06:18:55 -05:00 committed by Frank Morgner
parent d48f438581
commit 4049283675
4 changed files with 24 additions and 30 deletions

View File

@ -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);
}

View File

@ -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;

View File

@ -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;

View File

@ -9,4 +9,6 @@
*/
#define CKA_OPENSC_NON_REPUDIATION (CKA_VENDOR_DEFINED | 1UL)
#define CKA_SPKI (CKA_VENDOR_DEFINED | 2UL)
#endif