diff --git a/openssl-3.changes b/openssl-3.changes index c751635..3d1fa16 100644 --- a/openssl-3.changes +++ b/openssl-3.changes @@ -1,3 +1,10 @@ +------------------------------------------------------------------- +Thu Aug 22 15:18:03 UTC 2024 - Alexander Bergmann + +- Security fix: [bsc#1229465, CVE-2024-6119] + * possible denial of service in X.509 name checks + * openssl-CVE-2024-6119.patch + ------------------------------------------------------------------- Mon Jul 22 16:42:52 UTC 2024 - Pedro Monreal diff --git a/openssl-3.spec b/openssl-3.spec index e75e639..3ba1d9e 100644 --- a/openssl-3.spec +++ b/openssl-3.spec @@ -165,6 +165,8 @@ Patch68: openssl-FIPS-enforce-security-checks-during-initialization.patch Patch69: openssl-3-FIPS-PCT_rsa_keygen.patch # PATCH-FIX-FEDORA bsc#1221365 FIPS: Deny SHA-1 signature verification in FIPS provider Patch70: openssl-3-FIPS-Deny-SHA-1-sigver-in-FIPS-provider.patch +# PATCH-FIX-UPSTREAM bsc#1229465 CVE-2024-6119: possible denial of service in X.509 name checks +Patch71: openssl-CVE-2024-6119.patch BuildRequires: pkgconfig %if 0%{?sle_version} >= 150400 || 0%{?suse_version} >= 1550 BuildRequires: ulp-macros diff --git a/openssl-CVE-2024-6119.patch b/openssl-CVE-2024-6119.patch new file mode 100644 index 0000000..f7aadcf --- /dev/null +++ b/openssl-CVE-2024-6119.patch @@ -0,0 +1,255 @@ +commit 97ebe37033e8884f4cca5544a74376633c665e11 +Author: Viktor Dukhovni +Date: Wed Jun 19 21:04:11 2024 +1000 + + Avoid type errors in EAI-related name check logic. + + The incorrectly typed data is read only, used in a compare operation, so + neither remote code execution, nor memory content disclosure were possible. + However, applications performing certificate name checks were vulnerable to + denial of service. + + The GENERAL_TYPE data type is a union, and we must take care to access the + correct member, based on `gen->type`, not all the member fields have the same + structure, and a segfault is possible if the wrong member field is read. + + The code in question was lightly refactored with the intent to make it more + obviously correct. + + CVE-2024-6119 + + (cherry picked from commit 1486960d6cdb052e4fc0109a56a0597b4e902ba1) + +diff --git a/crypto/x509/v3_utl.c b/crypto/x509/v3_utl.c +index 1a18174995..a09414c972 100644 +--- a/crypto/x509/v3_utl.c ++++ b/crypto/x509/v3_utl.c +@@ -916,36 +916,64 @@ static int do_x509_check(X509 *x, const char *chk, size_t chklen, + ASN1_STRING *cstr; + + gen = sk_GENERAL_NAME_value(gens, i); +- if ((gen->type == GEN_OTHERNAME) && (check_type == GEN_EMAIL)) { +- if (OBJ_obj2nid(gen->d.otherName->type_id) == +- NID_id_on_SmtpUTF8Mailbox) { +- san_present = 1; +- +- /* +- * If it is not a UTF8String then that is unexpected and we +- * treat it as no match +- */ +- if (gen->d.otherName->value->type == V_ASN1_UTF8STRING) { +- cstr = gen->d.otherName->value->value.utf8string; +- +- /* Positive on success, negative on error! */ +- if ((rv = do_check_string(cstr, 0, equal, flags, +- chk, chklen, peername)) != 0) +- break; +- } +- } else ++ switch (gen->type) { ++ default: ++ continue; ++ case GEN_OTHERNAME: ++ switch (OBJ_obj2nid(gen->d.otherName->type_id)) { ++ default: + continue; +- } else { +- if ((gen->type != check_type) && (gen->type != GEN_OTHERNAME)) ++ case NID_id_on_SmtpUTF8Mailbox: ++ /*- ++ * https://datatracker.ietf.org/doc/html/rfc8398#section-3 ++ * ++ * Due to name constraint compatibility reasons described ++ * in Section 6, SmtpUTF8Mailbox subjectAltName MUST NOT ++ * be used unless the local-part of the email address ++ * contains non-ASCII characters. When the local-part is ++ * ASCII, rfc822Name subjectAltName MUST be used instead ++ * of SmtpUTF8Mailbox. This is compatible with legacy ++ * software that supports only rfc822Name (and not ++ * SmtpUTF8Mailbox). [...] ++ * ++ * SmtpUTF8Mailbox is encoded as UTF8String. ++ * ++ * If it is not a UTF8String then that is unexpected, and ++ * we ignore the invalid SAN (neither set san_present nor ++ * consider it a candidate for equality). This does mean ++ * that the subject CN may be considered, as would be the ++ * case when the malformed SmtpUtf8Mailbox SAN is instead ++ * simply absent. ++ * ++ * When CN-ID matching is not desirable, applications can ++ * choose to turn it off, doing so is at this time a best ++ * practice. ++ */ ++ if (check_type != GEN_EMAIL ++ || gen->d.otherName->value->type != V_ASN1_UTF8STRING) ++ continue; ++ alt_type = 0; ++ cstr = gen->d.otherName->value->value.utf8string; ++ break; ++ } ++ break; ++ case GEN_EMAIL: ++ if (check_type != GEN_EMAIL) + continue; +- } +- san_present = 1; +- if (check_type == GEN_EMAIL) + cstr = gen->d.rfc822Name; +- else if (check_type == GEN_DNS) ++ break; ++ case GEN_DNS: ++ if (check_type != GEN_DNS) ++ continue; + cstr = gen->d.dNSName; +- else ++ break; ++ case GEN_IPADD: ++ if (check_type != GEN_IPADD) ++ continue; + cstr = gen->d.iPAddress; ++ break; ++ } ++ san_present = 1; + /* Positive on success, negative on error! */ + if ((rv = do_check_string(cstr, alt_type, equal, flags, + chk, chklen, peername)) != 0) +diff --git a/test/recipes/25-test_eai_data.t b/test/recipes/25-test_eai_data.t +index 522982ddfb..e18735d89a 100644 +--- a/test/recipes/25-test_eai_data.t ++++ b/test/recipes/25-test_eai_data.t +@@ -21,16 +21,18 @@ setup("test_eai_data"); + #./util/wrap.pl apps/openssl verify -nameopt utf8 -no_check_time -CAfile test/recipes/25-test_eai_data/utf8_chain.pem test/recipes/25-test_eai_data/ascii_leaf.pem + #./util/wrap.pl apps/openssl verify -nameopt utf8 -no_check_time -CAfile test/recipes/25-test_eai_data/ascii_chain.pem test/recipes/25-test_eai_data/utf8_leaf.pem + +-plan tests => 12; ++plan tests => 16; + + require_ok(srctop_file('test','recipes','tconversion.pl')); + my $folder = "test/recipes/25-test_eai_data"; + + my $ascii_pem = srctop_file($folder, "ascii_leaf.pem"); + my $utf8_pem = srctop_file($folder, "utf8_leaf.pem"); ++my $kdc_pem = srctop_file($folder, "kdc-cert.pem"); + + my $ascii_chain_pem = srctop_file($folder, "ascii_chain.pem"); + my $utf8_chain_pem = srctop_file($folder, "utf8_chain.pem"); ++my $kdc_chain_pem = srctop_file($folder, "kdc-root-cert.pem"); + + my $out; + my $outcnt = 0; +@@ -56,10 +58,18 @@ SKIP: { + + ok(run(app(["openssl", "verify", "-nameopt", "utf8", "-no_check_time", "-CAfile", $ascii_chain_pem, $ascii_pem]))); + ok(run(app(["openssl", "verify", "-nameopt", "utf8", "-no_check_time", "-CAfile", $utf8_chain_pem, $utf8_pem]))); ++ok(run(app(["openssl", "verify", "-nameopt", "utf8", "-no_check_time", "-CAfile", $kdc_chain_pem, $kdc_pem]))); + + ok(!run(app(["openssl", "verify", "-nameopt", "utf8", "-no_check_time", "-CAfile", $ascii_chain_pem, $utf8_pem]))); + ok(!run(app(["openssl", "verify", "-nameopt", "utf8", "-no_check_time", "-CAfile", $utf8_chain_pem, $ascii_pem]))); + ++# Check an otherName does not get misparsed as an DNS name, (should trigger ASAN errors if violated). ++ok(run(app(["openssl", "verify", "-nameopt", "utf8", "-no_check_time", "-verify_hostname", 'mx1.example.com', "-CAfile", $kdc_chain_pem, $kdc_pem]))); ++# Check an otherName does not get misparsed as an email address, (should trigger ASAN errors if violated). ++ok(run(app(["openssl", "verify", "-nameopt", "utf8", "-no_check_time", "-verify_email", 'joe@example.com', "-CAfile", $kdc_chain_pem, $kdc_pem]))); ++# We expect SmtpUTF8Mailbox to be a UTF8 String, not an IA5String. ++ok(!run(app(["openssl", "verify", "-nameopt", "utf8", "-no_check_time", "-verify_email", 'moe@example.com', "-CAfile", $kdc_chain_pem, $kdc_pem]))); ++ + #Check that we get the expected failure return code + with({ exit_checker => sub { return shift == 2; } }, + sub { +diff --git a/test/recipes/25-test_eai_data/kdc-cert.pem b/test/recipes/25-test_eai_data/kdc-cert.pem +new file mode 100644 +index 0000000000..e8a2c6f55d +--- /dev/null ++++ b/test/recipes/25-test_eai_data/kdc-cert.pem +@@ -0,0 +1,21 @@ ++-----BEGIN CERTIFICATE----- ++MIIDbDCCAlSgAwIBAgIBAjANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDDARSb290 ++MCAXDTI0MDYyMDA2MTQxNVoYDzIxMjQwNjIwMDYxNDE1WjAXMRUwEwYDVQQDDAxU ++RVNULkVYQU1QTEUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6wfP+ ++6go79dkpo/dGLMlPZ7Gw/Q6gUYrCWZWUEgEeRVHCrqOlgUEyA+PcWas/XDPUxXry ++BQlJHLvlqamAQn8gs4QPBARFYWKNiTVGyaRkgNA1N5gqyZdrP9UE+ZJmdqxRAAe8 ++vvpGZWSgevPhLUiSCFYDiD0Rtji2Hm3rGUrReQFBQDEw2pNGwz9zIaxUs08kQZcx ++Yzyiplz5Oau+R/6sAgUwDlrD9xOlUxx/tA/MSDIfkK8qioU11uUZtO5VjkNQy/bT ++7zQMmXxWgm2MIgOs1u4YN7YGOtgqHE9v9iPHHfgrkbQDtVDGQsa8AQEhkUDSCtW9 ++3VFAKx6dGNXYzFwfAgMBAAGjgcgwgcUwHQYDVR0OBBYEFFR5tZycW19DmtbL4Zqj ++te1c2vZLMAkGA1UdIwQCMAAwCQYDVR0TBAIwADCBjQYDVR0RBIGFMIGCoD8GBisG ++AQUCAqA1MDOgDhsMVEVTVC5FWEFNUExFoSEwH6ADAgEBoRgwFhsGa3JidGd0GwxU ++RVNULkVYQU1QTEWgHQYIKwYBBQUHCAmgERYPbW9lQGV4YW1wbGUuY29tgQ9qb2VA ++ZXhhbXBsZS5jb22CD214MS5leGFtcGxlLmNvbTANBgkqhkiG9w0BAQsFAAOCAQEA ++T0xzVtVpRtaOzIhgzw7XQUdzWD5UEGSJJ1cBCOmKUWwDLTAouCYLFB4TbEE7MMUb ++iuMy60bjmVtvfJIXorGUgSadRe5RWJ5DamJWvPA0Q9x7blnEcXqEF+9Td+ypevgU ++UYHFmg83OYwxOsFXZ5cRuXMk3WCsDHQIBi6D1L6oDDZ2pfArs5mqm3thQKVlqyl1 ++El3XRYEdqAz/5eCOFNfwxF0ALxjxVr/Z50StUZU8I7Zfev6+kHhyrR7dqzYJImv9 ++0fTCOBEMjIETDsrA70OxAMu4V16nrWZdJdvzblS2qrt97Omkj+2kiPAJFB76RpwI ++oDQ9fKfUOAmUFth2/R/eGA== ++-----END CERTIFICATE----- +diff --git a/test/recipes/25-test_eai_data/kdc-root-cert.pem b/test/recipes/25-test_eai_data/kdc-root-cert.pem +new file mode 100644 +index 0000000000..a74c96bf31 +--- /dev/null ++++ b/test/recipes/25-test_eai_data/kdc-root-cert.pem +@@ -0,0 +1,16 @@ ++-----BEGIN CERTIFICATE----- ++MIICnDCCAYQCCQCBswYcrlZSHjANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDDARS ++b290MCAXDTI0MDYyMDA2MTQxNVoYDzIxMjQwNjIwMDYxNDE1WjAPMQ0wCwYDVQQD ++DARSb290MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqRj8S4kBbIUj ++61kZfi6nE35Q38U140+qt4uAiwAhKumfVHlBM0zQ98WFt5zMHIBQwIb3yjc2zj+0 ++qzUnQfwm1r/RfcMmBPEti9Ge+aEMSsds2gMXziOFM8wd2aAFPy7UVE0XpEWofsRK ++MGi61MKVdPSbGIxBwY9VW38/7D/wf1HtJe7y0xpuecR7GB2XAs+qST59NjuF+7wS ++dLM8Hb3TATgeYbXXWsRJgwz+SPzExg5WmLnU+7y4brZ32dHtdSmkRVSgSlaIf7Xj ++3Tc6Zi7I+W/JYk7hy1zUexVdWCak4PHcoWrXe0gNNN/t8VfLfMExt5z/HIylXnU7 ++pGUyqZlTGQIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQAHpLF1UCRy7b6Hk0rLokxI ++lgwiH9BU9mktigAGASvkbllpt+YbUbWnuYAvpHBGiP1qZtfX2r96UrSJaGO9BEzT ++Gp9ThnSjoj4Srul0+s/NArU22irFLmDzbalgevAmm9gMGkdqkiIm/mXbwrPj0ncl ++KGicevXryVpvaP62eZ8cc3C4p97frMmXxRX8sTdQpD/gRI7prdEILRSKveqT+AEW ++7rFGM5AOevb4U8ddop8A3D/kX0wcCAIBF6jCNk3uEJ57jVcagL04kPnVfdRiedTS ++vfq1DRNcD29d1H/9u0fHdSn1/+8Ep3X+afQ3C6//5NvOEaXcIGO4QSwkprQydfv8 ++-----END CERTIFICATE----- +diff --git a/test/recipes/25-test_eai_data/kdc.sh b/test/recipes/25-test_eai_data/kdc.sh +new file mode 100755 +index 0000000000..7a8dbc719f +--- /dev/null ++++ b/test/recipes/25-test_eai_data/kdc.sh +@@ -0,0 +1,41 @@ ++#! /usr/bin/env bash ++ ++# Create a root CA, signing a leaf cert with a KDC principal otherName SAN, and ++# also a non-UTF8 smtpUtf8Mailbox SAN followed by an rfc822Name SAN and a DNS ++# name SAN. In the vulnerable EAI code, the KDC principal `otherName` should ++# trigger ASAN errors in DNS name checks, while the non-UTF8 `smtpUtf8Mailbox` ++# should likewise lead to ASAN issues with email name checks. ++ ++rm -f root-key.pem root-cert.pem ++openssl req -nodes -new -newkey rsa:2048 -keyout kdc-root-key.pem \ ++ -x509 -subj /CN=Root -days 36524 -out kdc-root-cert.pem ++ ++exts=$( ++ printf "%s\n%s\n%s\n%s = " \ ++ "subjectKeyIdentifier = hash" \ ++ "authorityKeyIdentifier = keyid" \ ++ "basicConstraints = CA:false" \ ++ "subjectAltName" ++ printf "%s, " "otherName:1.3.6.1.5.2.2;SEQUENCE:kdc_princ_name" ++ printf "%s, " "otherName:1.3.6.1.5.5.7.8.9;IA5:moe@example.com" ++ printf "%s, " "email:joe@example.com" ++ printf "%s\n" "DNS:mx1.example.com" ++ printf "[kdc_princ_name]\n" ++ printf "realm = EXP:0, GeneralString:TEST.EXAMPLE\n" ++ printf "principal_name = EXP:1, SEQUENCE:kdc_principal_seq\n" ++ printf "[kdc_principal_seq]\n" ++ printf "name_type = EXP:0, INTEGER:1\n" ++ printf "name_string = EXP:1, SEQUENCE:kdc_principal_components\n" ++ printf "[kdc_principal_components]\n" ++ printf "princ1 = GeneralString:krbtgt\n" ++ printf "princ2 = GeneralString:TEST.EXAMPLE\n" ++ ) ++ ++printf "%s\n" "$exts" ++ ++openssl req -nodes -new -newkey rsa:2048 -keyout kdc-key.pem \ ++ -subj "/CN=TEST.EXAMPLE" | ++ openssl x509 -req -out kdc-cert.pem \ ++ -CA "kdc-root-cert.pem" -CAkey "kdc-root-key.pem" \ ++ -set_serial 2 -days 36524 \ ++ -extfile <(printf "%s\n" "$exts")