diff --git a/crypto/evp_extra/evp_asn1.c b/crypto/evp_extra/evp_asn1.c index 9765d3916d..e394494cb0 100644 --- a/crypto/evp_extra/evp_asn1.c +++ b/crypto/evp_extra/evp_asn1.c @@ -75,7 +75,8 @@ static const EVP_PKEY_ASN1_METHOD *parse_key_type(CBS *cbs) { return NULL; } - const EVP_PKEY_ASN1_METHOD *const *asn1_methods = AWSLC_non_fips_pkey_evp_asn1_methods(); + const EVP_PKEY_ASN1_METHOD *const *asn1_methods = + AWSLC_non_fips_pkey_evp_asn1_methods(); for (size_t i = 0; i < ASN1_EVP_PKEY_METHODS; i++) { const EVP_PKEY_ASN1_METHOD *method = asn1_methods[i]; if (CBS_len(&oid) == method->oid_len && @@ -84,6 +85,12 @@ static const EVP_PKEY_ASN1_METHOD *parse_key_type(CBS *cbs) { } } + // Special logic to handle the rarer |NID_rsa|. + // https://www.itu.int/ITU-T/formal-language/itu-t/x/x509/2008/AlgorithmObjectIdentifiers.html + if (OBJ_cbs2nid(&oid) == NID_rsa) { + return &rsa_asn1_meth; + } + return NULL; } diff --git a/crypto/evp_extra/evp_tests.txt b/crypto/evp_extra/evp_tests.txt index d0c06038a1..31026be280 100644 --- a/crypto/evp_extra/evp_tests.txt +++ b/crypto/evp_extra/evp_tests.txt @@ -33,10 +33,13 @@ PublicKey = RSA-2048-Even-Modulus Input = 30820122300d06092a864886f70d01010105000382010f003082010a0282010100cd0081ea7b2ae1ea06d59f7c73d9ffb94a09615c2e4ba7c636cef08dd3533ec3185525b015c769b99a77d6725bf9c3532a9b6e5f6627d5fb85160768d3dda9cbd35974511717dc3d309d2fc47ee41f97e32adb7f9dd864a1c4767a666ecd71bc1aacf5e7517f4b38594fea9b05e42d5ada9912008013e45316a4d9bb8ed086b88d28758bacaf922d46a868b485d239c9baeb0e2b64592710f42b2d1ea0a4b4802c0becab328f8a68b0073bdb546feea9809d2849912b390c1532bc7e29c7658f8175fae46f34332ff87bcab3e40649b98577869da0ea718353f0722754886913648760d122be676e0fc483dd20ffc31bda96a31966c9aa2e75ad03de47e1c44e0203010001 Error = BAD_RSA_PARAMETERS -# The same key but with missing parameters rather than a NULL. -PublicKey = RSA-2048-SPKI-Invalid +# The same key but with missing parameters rather than a NULL. This parses correctly in OpenSSL, so we let this parse +# to gain compatibility. +PublicKey = RSA-2048-SPKI-MISSING-NULL +Type = RSA Input = 30820120300b06092a864886f70d0101010382010f003082010a0282010100cd0081ea7b2ae1ea06d59f7c73d9ffb94a09615c2e4ba7c636cef08dd3533ec3185525b015c769b99a77d6725bf9c3532a9b6e5f6627d5fb85160768d3dda9cbd35974511717dc3d309d2fc47ee41f97e32adb7f9dd864a1c4767a666ecd71bc1aacf5e7517f4b38594fea9b05e42d5ada9912008013e45316a4d9bb8ed086b88d28758bacaf922d46a868b485d239c9baeb0e2b64592710f42b2d1ea0a4b4802c0becab328f8a68b0073bdb546feea9809d2849912b390c1532bc7e29c7658f8175fae46f34332ff87bcab3e40649b98577869da0ea718353f0722754886913648760d122be676e0fc483dd20ffc31bda96a31966c9aa2e75ad03de47e1c44f0203010001 -Error = DECODE_ERROR +# The key re-encodes with the missing NULL parameter in place. +Output = 30820122300d06092a864886f70d01010105000382010f003082010a0282010100cd0081ea7b2ae1ea06d59f7c73d9ffb94a09615c2e4ba7c636cef08dd3533ec3185525b015c769b99a77d6725bf9c3532a9b6e5f6627d5fb85160768d3dda9cbd35974511717dc3d309d2fc47ee41f97e32adb7f9dd864a1c4767a666ecd71bc1aacf5e7517f4b38594fea9b05e42d5ada9912008013e45316a4d9bb8ed086b88d28758bacaf922d46a868b485d239c9baeb0e2b64592710f42b2d1ea0a4b4802c0becab328f8a68b0073bdb546feea9809d2849912b390c1532bc7e29c7658f8175fae46f34332ff87bcab3e40649b98577869da0ea718353f0722754886913648760d122be676e0fc483dd20ffc31bda96a31966c9aa2e75ad03de47e1c44f0203010001 # The same key but with an incorrectly-encoded length prefix. PublicKey = RSA-2048-SPKI-Invalid2 diff --git a/crypto/evp_extra/p_rsa_asn1.c b/crypto/evp_extra/p_rsa_asn1.c index 04235950cc..05f5881112 100644 --- a/crypto/evp_extra/p_rsa_asn1.c +++ b/crypto/evp_extra/p_rsa_asn1.c @@ -86,16 +86,13 @@ static int rsa_pub_encode(CBB *out, const EVP_PKEY *key) { } static int rsa_pub_decode(EVP_PKEY *out, CBS *params, CBS *key) { - // See RFC 3279, section 2.3.1. - - // The parameters must be NULL. - CBS null; - if (!CBS_get_asn1(params, &null, CBS_ASN1_NULL) || - CBS_len(&null) != 0 || - CBS_len(params) != 0) { - OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); - return 0; - } + // The IETF specification defines that the parameters must be + // NULL. See RFC 3279, section 2.3.1. + // There is also an ITU-T X.509 specification that is rarely seen, + // which defines a KeySize parameter. See ITU-T X.509 2008-11 + // AlgorithmObjectIdentifiers. + // + // OpenSSL ignores both parameters when parsing, however. RSA *rsa = RSA_parse_public_key(key); if (rsa == NULL || CBS_len(key) != 0) { diff --git a/crypto/obj/obj_xref.c b/crypto/obj/obj_xref.c index e6646e8d7b..3b59258593 100644 --- a/crypto/obj/obj_xref.c +++ b/crypto/obj/obj_xref.c @@ -74,6 +74,10 @@ static const nid_triple kTriples[] = { {NID_sha256WithRSAEncryption, NID_sha256, NID_rsaEncryption}, {NID_sha384WithRSAEncryption, NID_sha384, NID_rsaEncryption}, {NID_sha512WithRSAEncryption, NID_sha512, NID_rsaEncryption}, + // RSA ITU-T X.509. These are rare and we map them to the more + // common |NID_rsaEncryption| instead for simplicity. + {NID_md5WithRSA, NID_md5, NID_rsaEncryption}, + {NID_sha1WithRSA, NID_sha1, NID_rsaEncryption}, // DSA. {NID_dsaWithSHA1, NID_sha1, NID_dsa}, {NID_dsaWithSHA1_2, NID_sha1, NID_dsa_2}, diff --git a/crypto/x509/x509_test.cc b/crypto/x509/x509_test.cc index e811828fd5..cee8e27203 100644 --- a/crypto/x509/x509_test.cc +++ b/crypto/x509/x509_test.cc @@ -5876,6 +5876,35 @@ TEST(X509Test, NamePrint) { } } + +// kLargeSerialPEM is a certificate with a large serial number. +static const char kRareRSAPEM[] = R"( +-----BEGIN CERTIFICATE----- +MIICVTCCAb6gAwIBAgIJAPuwTC6rEJsMMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV +BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX +aWRnaXRzIFB0eSBMdGQwHhcNMTQwNDIzMjA1MDQwWhcNMTcwNDIyMjA1MDQwWjBF +MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50 +ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIGcMAoGBFUIAQECAgQAA4GNADCBiQKBgQDY +K8imMuRi/03z0K1Zi0WnvfFHvwlYeyK9Na6XJYaUoIDAtB92kWdGMdAQhLciHnAj +kXLI6W15OoV3gA/ElRZ1xUpxTMhjP6PyY5wqT5r6y8FxbiiFKKAnHmUcrgfVW28t +Q+0rkLGMryRtrukXOgXBv7gcrmU7G1jC2a7WqmeI8QIDAQABo1AwTjAdBgNVHQ4E +FgQUi3XVrMsIvg4fZbf6Vr5sp3Xaha8wHwYDVR0jBBgwFoAUi3XVrMsIvg4fZbf6 +Vr5sp3Xaha8wDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOBgQAIZuUICtYv +w3cbpCGX6HNCtyI0guOfbytcdwzRkQaCsYNSDrTxrSSWxHwqg3Dl/RlvS+T3Yaua +Xkioadstwt7GDP6MwpIpdbjchh0XZd3kjdJWqXSvihUDpRePNjNS2LmJW8GWfB3c +F6UVyNK+wcApRY+goREIhyYupAHUexR7FQ== +-----END CERTIFICATE----- +)"; + +TEST(X509Test, ITUT_X509_nid_rsa) { + bssl::UniquePtr cert(CertFromPEM(kRareRSAPEM)); + ASSERT_TRUE(cert); + + EXPECT_TRUE(X509_get_X509_PUBKEY(cert.get())); + bssl::UniquePtr evp_pkey(X509_get_pubkey(cert.get())); + EXPECT_TRUE(evp_pkey); +} + // kLargeSerialPEM is a certificate with a large serial number. static const char kLargeSerialPEM[] = R"( -----BEGIN CERTIFICATE-----