pkcs11: Added support to encode ECDSA public keys.

This commit is contained in:
Tobias Brunner
2011-11-02 20:27:55 +01:00
parent 36d1627f6e
commit 9e3b1e1495
@@ -285,6 +285,91 @@ METHOD(public_key_t, encrypt, bool,
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
*/
@@ -325,6 +410,8 @@ METHOD(public_key_t, get_encoding, bool,
{
case KEY_RSA:
return encode_rsa(this, type, NULL, encoding);
case KEY_ECDSA:
return encode_ecdsa(this, type, encoding);
default:
return FALSE;
}
@@ -341,6 +428,8 @@ METHOD(public_key_t, get_fingerprint, bool,
{
case KEY_RSA:
return encode_rsa(this, type, this, fp);
case KEY_ECDSA:
return fingerprint_ecdsa(this, type, fp);
default:
return FALSE;
}