pkcs11: Added support to encode ECDSA public keys.
This commit is contained in:
@@ -285,6 +285,91 @@ METHOD(public_key_t, encrypt, bool,
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Encode ECDSA key using a given encoding type
|
||||||
|
*/
|
||||||
|
static bool encode_ecdsa(private_pkcs11_public_key_t *this,
|
||||||
|
cred_encoding_type_t type, chunk_t *encoding)
|
||||||
|
{
|
||||||
|
enumerator_t *enumerator;
|
||||||
|
bool success = FALSE;
|
||||||
|
CK_ATTRIBUTE attr[] = {
|
||||||
|
{CKA_EC_PARAMS, NULL, 0},
|
||||||
|
{CKA_EC_POINT, NULL, 0},
|
||||||
|
};
|
||||||
|
|
||||||
|
if (type != PUBKEY_SPKI_ASN1_DER && type != PUBKEY_PEM)
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
enumerator = this->lib->create_object_attr_enumerator(this->lib,
|
||||||
|
this->session, this->object, attr, countof(attr));
|
||||||
|
if (enumerator && enumerator->enumerate(enumerator, NULL) &&
|
||||||
|
attr[0].ulValueLen > 0 && attr[1].ulValueLen > 0)
|
||||||
|
{
|
||||||
|
chunk_t ecparams, ecpoint;
|
||||||
|
ecparams = chunk_create(attr[0].pValue, attr[0].ulValueLen);
|
||||||
|
ecpoint = chunk_create(attr[1].pValue, attr[1].ulValueLen);
|
||||||
|
/* encode as subjectPublicKeyInfo */
|
||||||
|
*encoding = asn1_wrap(ASN1_SEQUENCE, "mm",
|
||||||
|
asn1_wrap(ASN1_SEQUENCE, "mc",
|
||||||
|
asn1_build_known_oid(OID_EC_PUBLICKEY), ecparams),
|
||||||
|
asn1_bitstring("c", ecpoint));
|
||||||
|
success = TRUE;
|
||||||
|
if (type == PUBKEY_PEM)
|
||||||
|
{
|
||||||
|
chunk_t asn1 = *encoding;
|
||||||
|
success = lib->encoding->encode(lib->encoding, PUBKEY_PEM,
|
||||||
|
NULL, encoding, CRED_PART_ECDSA_PUB_ASN1_DER,
|
||||||
|
asn1, CRED_PART_END);
|
||||||
|
chunk_clear(&asn1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DESTROY_IF(enumerator);
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute fingerprint of an ECDSA key
|
||||||
|
*/
|
||||||
|
static bool fingerprint_ecdsa(private_pkcs11_public_key_t *this,
|
||||||
|
cred_encoding_type_t type, chunk_t *fp)
|
||||||
|
{
|
||||||
|
hasher_t *hasher;
|
||||||
|
chunk_t asn1;
|
||||||
|
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case KEYID_PUBKEY_SHA1:
|
||||||
|
if (!this->lib->get_ck_attribute(this->lib, this->session,
|
||||||
|
this->object, CKA_EC_POINT, &asn1))
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case KEYID_PUBKEY_INFO_SHA1:
|
||||||
|
if (!encode_ecdsa(this, PUBKEY_SPKI_ASN1_DER, &asn1))
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
|
||||||
|
if (!hasher)
|
||||||
|
{
|
||||||
|
chunk_clear(&asn1);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
hasher->allocate_hash(hasher, asn1, fp);
|
||||||
|
hasher->destroy(hasher);
|
||||||
|
chunk_clear(&asn1);
|
||||||
|
lib->encoding->cache(lib->encoding, type, this, *fp);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Encode RSA key using a given encoding type
|
* Encode RSA key using a given encoding type
|
||||||
*/
|
*/
|
||||||
@@ -325,6 +410,8 @@ METHOD(public_key_t, get_encoding, bool,
|
|||||||
{
|
{
|
||||||
case KEY_RSA:
|
case KEY_RSA:
|
||||||
return encode_rsa(this, type, NULL, encoding);
|
return encode_rsa(this, type, NULL, encoding);
|
||||||
|
case KEY_ECDSA:
|
||||||
|
return encode_ecdsa(this, type, encoding);
|
||||||
default:
|
default:
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
@@ -341,6 +428,8 @@ METHOD(public_key_t, get_fingerprint, bool,
|
|||||||
{
|
{
|
||||||
case KEY_RSA:
|
case KEY_RSA:
|
||||||
return encode_rsa(this, type, this, fp);
|
return encode_rsa(this, type, this, fp);
|
||||||
|
case KEY_ECDSA:
|
||||||
|
return fingerprint_ecdsa(this, type, fp);
|
||||||
default:
|
default:
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user