Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Map certs with ITUT X509 to our RSA implementation (#1754) #1893

Merged
merged 2 commits into from
Oct 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
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
Loading