diff options
Diffstat (limited to 'nss/lib/cryptohi/seckey.c')
-rw-r--r-- | nss/lib/cryptohi/seckey.c | 77 |
1 files changed, 36 insertions, 41 deletions
diff --git a/nss/lib/cryptohi/seckey.c b/nss/lib/cryptohi/seckey.c index 1f053e5..9ea48b7 100644 --- a/nss/lib/cryptohi/seckey.c +++ b/nss/lib/cryptohi/seckey.c @@ -547,6 +547,23 @@ CERT_GetCertKeyType(const CERTSubjectPublicKeyInfo *spki) return seckey_GetKeyType(SECOID_GetAlgorithmTag(&spki->algorithm)); } +/* Ensure pubKey contains an OID */ +static SECStatus +seckey_HasCurveOID(const SECKEYPublicKey *pubKey) +{ + SECItem oid; + SECStatus rv; + PORTCheapArenaPool tmpArena; + + PORT_InitCheapArena(&tmpArena, DER_DEFAULT_CHUNKSIZE); + /* If we can decode it, an OID is available. */ + rv = SEC_QuickDERDecodeItem(&tmpArena.arena, &oid, + SEC_ASN1_GET(SEC_ObjectIDTemplate), + &pubKey->u.ec.DEREncodedParams); + PORT_DestroyCheapArena(&tmpArena); + return rv; +} + static SECKEYPublicKey * seckey_ExtractPublicKey(const CERTSubjectPublicKeyInfo *spki) { @@ -639,7 +656,8 @@ seckey_ExtractPublicKey(const CERTSubjectPublicKeyInfo *spki) if (rv != SECSuccess) { break; } - rv = seckey_SetPointEncoding(arena, pubk); + pubk->u.ec.encoding = ECPoint_Undefined; + rv = seckey_HasCurveOID(pubk); if (rv == SECSuccess) { return pubk; } @@ -1162,16 +1180,16 @@ SECKEY_CopyPublicKey(const SECKEYPublicKey *pubk) break; case ecKey: copyk->u.ec.size = pubk->u.ec.size; - rv = SECITEM_CopyItem(arena, ©k->u.ec.DEREncodedParams, - &pubk->u.ec.DEREncodedParams); + rv = seckey_HasCurveOID(pubk); if (rv != SECSuccess) { break; } - rv = seckey_SetPointEncoding(arena, copyk); + rv = SECITEM_CopyItem(arena, ©k->u.ec.DEREncodedParams, + &pubk->u.ec.DEREncodedParams); if (rv != SECSuccess) { break; } - PORT_Assert(copyk->u.ec.encoding == pubk->u.ec.encoding); + copyk->u.ec.encoding = ECPoint_Undefined; rv = SECITEM_CopyItem(arena, ©k->u.ec.publicValue, &pubk->u.ec.publicValue); break; @@ -1242,6 +1260,19 @@ SECKEY_ConvertToPublicKey(SECKEYPrivateKey *privk) break; return pubk; break; + case ecKey: + rv = PK11_ReadAttribute(privk->pkcs11Slot, privk->pkcs11ID, + CKA_EC_PARAMS, arena, &pubk->u.ec.DEREncodedParams); + if (rv != SECSuccess) { + break; + } + rv = PK11_ReadAttribute(privk->pkcs11Slot, privk->pkcs11ID, + CKA_EC_POINT, arena, &pubk->u.ec.publicValue); + if (rv != SECSuccess || pubk->u.ec.publicValue.len == 0) { + break; + } + pubk->u.ec.encoding = ECPoint_Undefined; + return pubk; default: break; } @@ -1943,39 +1974,3 @@ SECKEY_GetECCOid(const SECKEYECParams *params) return oidData->offset; } - -/* Set curve encoding in SECKEYECPublicKey in pubKey from OID. - * If the encoding is not set, determining the key size of EC public keys will - * fail. - */ -SECStatus -seckey_SetPointEncoding(PLArenaPool *arena, SECKEYPublicKey *pubKey) -{ - SECItem oid; - SECOidTag tag; - SECStatus rv; - - /* decode the OID tag */ - rv = SEC_QuickDERDecodeItem(arena, &oid, SEC_ASN1_GET(SEC_ObjectIDTemplate), - &pubKey->u.ec.DEREncodedParams); - if (rv != SECSuccess) { - return SECFailure; - } - - tag = SECOID_FindOIDTag(&oid); - switch (tag) { - case SEC_OID_CURVE25519: - pubKey->u.ec.encoding = ECPoint_XOnly; - break; - case SEC_OID_SECG_EC_SECP256R1: - /* fall through */ - case SEC_OID_SECG_EC_SECP384R1: - /* fall through */ - case SEC_OID_SECG_EC_SECP521R1: - /* fall through */ - default: - /* unknown curve, default to uncompressed */ - pubKey->u.ec.encoding = ECPoint_Uncompressed; - } - return SECSuccess; -} |