Skip to content

Commit

Permalink
Map certs with ITUT X509 to our RSA implementation (#1754) and update…
Browse files Browse the repository at this point in the history
… version to v2.0.16 (#1893)

This is a cherry pick of
4916fe8
to the fips-2022-11-02 branch. The changes are outside the fipsmodule
and were modified from the original commit to match the return values of
`parse_key_type()` in `evp_asn1.c` without changing the fipsmodule
files.

Release version is updated to v2.0.16.
  • Loading branch information
nebeid authored Oct 7, 2024
2 parents ec94d74 + c2811c5 commit 72d3b02
Show file tree
Hide file tree
Showing 8 changed files with 81 additions and 37 deletions.
11 changes: 10 additions & 1 deletion crypto/evp_extra/evp_asn1.c
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@
#include <openssl/ec_key.h>
#include <openssl/err.h>
#include <openssl/rsa.h>
#include <openssl/obj.h>

#include "../fipsmodule/evp/internal.h"
#include "../bytestring/internal.h"
Expand All @@ -75,7 +76,8 @@ static int parse_key_type(CBS *cbs, int *out_type) {
return 0;
}

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 &&
Expand All @@ -85,6 +87,13 @@ static int parse_key_type(CBS *cbs, int *out_type) {
}
}

// 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) {
*out_type = rsa_asn1_meth.pkey_id;
return 1;
}

return 0;
}

Expand Down
9 changes: 6 additions & 3 deletions crypto/evp_extra/evp_tests.txt
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,13 @@ PublicKey = RSA-2048-SPKI-Negative
Input = 30820121300d06092a864886f70d01010105000382010e003082010902820100cd0081ea7b2ae1ea06d59f7c73d9ffb94a09615c2e4ba7c636cef08dd3533ec3185525b015c769b99a77d6725bf9c3532a9b6e5f6627d5fb85160768d3dda9cbd35974511717dc3d309d2fc47ee41f97e32adb7f9dd864a1c4767a666ecd71bc1aacf5e7517f4b38594fea9b05e42d5ada9912008013e45316a4d9bb8ed086b88d28758bacaf922d46a868b485d239c9baeb0e2b64592710f42b2d1ea0a4b4802c0becab328f8a68b0073bdb546feea9809d2849912b390c1532bc7e29c7658f8175fae46f34332ff87bcab3e40649b98577869da0ea718353f0722754886913648760d122be676e0fc483dd20ffc31bda96a31966c9aa2e75ad03de47e1c44f0203010001
Error = NEGATIVE_NUMBER

# 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
Expand Down
17 changes: 7 additions & 10 deletions crypto/evp_extra/p_rsa_asn1.c
Original file line number Diff line number Diff line change
Expand Up @@ -85,16 +85,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) {
Expand Down
4 changes: 2 additions & 2 deletions crypto/fipsmodule/service_indicator/service_indicator_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4051,7 +4051,7 @@ TEST(ServiceIndicatorTest, DRBG) {
// Since this is running in FIPS mode it should end in FIPS
// Update this when the AWS-LC version number is modified
TEST(ServiceIndicatorTest, AWSLCVersionString) {
ASSERT_STREQ(awslc_version_string(), "AWS-LC FIPS 2.0.15");
ASSERT_STREQ(awslc_version_string(), "AWS-LC FIPS 2.0.16");
}

#else
Expand Down Expand Up @@ -4094,6 +4094,6 @@ TEST(ServiceIndicatorTest, BasicTest) {
// Since this is not running in FIPS mode it shouldn't end in FIPS
// Update this when the AWS-LC version number is modified
TEST(ServiceIndicatorTest, AWSLCVersionString) {
ASSERT_STREQ(awslc_version_string(), "AWS-LC 2.0.15");
ASSERT_STREQ(awslc_version_string(), "AWS-LC 2.0.16");
}
#endif // AWSLC_FIPS
4 changes: 4 additions & 0 deletions crypto/obj/obj_xref.c
Original file line number Diff line number Diff line change
Expand Up @@ -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},
Expand Down
31 changes: 31 additions & 0 deletions crypto/x509/x509_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4818,6 +4818,37 @@ TEST(X509Test, NamePrint) {
}
}

// kRareRSAPEM is a certificate with the rare |nid_rsa|.
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<X509> cert(CertFromPEM(kRareRSAPEM));
ASSERT_TRUE(cert);

EXPECT_TRUE(X509_get_X509_PUBKEY(cert.get()));
bssl::UniquePtr<EVP_PKEY> evp_pkey(X509_get_pubkey(cert.get()));
EXPECT_TRUE(evp_pkey);

bssl::UniquePtr<RSA> rsa(EVP_PKEY_get1_RSA(evp_pkey.get()));
EXPECT_TRUE(rsa);
}

// kLargeSerialPEM is a certificate with a large serial number.
static const char kLargeSerialPEM[] = R"(
-----BEGIN CERTIFICATE-----
Expand Down
40 changes: 20 additions & 20 deletions generated-src/crypto_test_data.cc

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion include/openssl/base.h
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ extern "C" {
// ServiceIndicatorTest.AWSLCVersionString
// Note: there are two versions of this test. Only one test is compiled
// depending on FIPS mode.
#define AWSLC_VERSION_NUMBER_STRING "2.0.15"
#define AWSLC_VERSION_NUMBER_STRING "2.0.16"

#if defined(BORINGSSL_SHARED_LIBRARY)

Expand Down

0 comments on commit 72d3b02

Please sign in to comment.