Use the new SPKI API in d2i_RSA_PUBKEY and friends These functions only need to pull in the algorithms they support. The new API is slightly less friendly in this context because it expects the caller to have found the end first, but it's easy enough to to write a small wrapper. Bug: 42290364 Change-Id: Ibdc44f399182cd5722700917aec6c151221f4674 Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/81747 Reviewed-by: Adam Langley <agl@google.com> Auto-Submit: David Benjamin <davidben@google.com> Commit-Queue: Adam Langley <agl@google.com>
diff --git a/crypto/evp/evp_asn1.cc b/crypto/evp/evp_asn1.cc index 1f5216f..a135b0a 100644 --- a/crypto/evp/evp_asn1.cc +++ b/crypto/evp/evp_asn1.cc
@@ -390,13 +390,28 @@ return CBB_finish_i2d(&cbb, outp); } +static bssl::UniquePtr<EVP_PKEY> parse_spki( + CBS *cbs, bssl::Span<const EVP_PKEY_ALG *const> algs) { + CBS spki; + if (!CBS_get_asn1_element(cbs, &spki, CBS_ASN1_SEQUENCE)) { + OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); + return nullptr; + } + return bssl::UniquePtr<EVP_PKEY>(EVP_PKEY_from_subject_public_key_info( + CBS_data(&spki), CBS_len(&spki), algs.data(), algs.size())); +} + +static bssl::UniquePtr<EVP_PKEY> parse_spki(CBS *cbs, const EVP_PKEY_ALG *alg) { + return parse_spki(cbs, bssl::Span(&alg, 1)); +} + RSA *d2i_RSA_PUBKEY(RSA **out, const uint8_t **inp, long len) { if (len < 0) { return nullptr; } CBS cbs; CBS_init(&cbs, *inp, (size_t)len); - bssl::UniquePtr<EVP_PKEY> pkey(EVP_parse_public_key(&cbs)); + bssl::UniquePtr<EVP_PKEY> pkey = parse_spki(&cbs, EVP_pkey_rsa()); if (pkey == nullptr) { return nullptr; } @@ -432,7 +447,7 @@ } CBS cbs; CBS_init(&cbs, *inp, (size_t)len); - bssl::UniquePtr<EVP_PKEY> pkey(EVP_parse_public_key(&cbs)); + bssl::UniquePtr<EVP_PKEY> pkey = parse_spki(&cbs, EVP_pkey_dsa()); if (pkey == nullptr) { return nullptr; } @@ -468,7 +483,9 @@ } CBS cbs; CBS_init(&cbs, *inp, (size_t)len); - bssl::UniquePtr<EVP_PKEY> pkey(EVP_parse_public_key(&cbs)); + const EVP_PKEY_ALG *const algs[] = {EVP_pkey_ec_p224(), EVP_pkey_ec_p256(), + EVP_pkey_ec_p384(), EVP_pkey_ec_p521()}; + bssl::UniquePtr<EVP_PKEY> pkey = parse_spki(&cbs, algs); if (pkey == nullptr) { return nullptr; }