diff options
Diffstat (limited to 'crypto/openssl/test')
35 files changed, 671 insertions, 86 deletions
diff --git a/crypto/openssl/test/README-external.md b/crypto/openssl/test/README-external.md index d094c66f8254..7c01ef23a949 100644 --- a/crypto/openssl/test/README-external.md +++ b/crypto/openssl/test/README-external.md @@ -39,7 +39,7 @@ tests against the local OpenSSL build. You will need a git checkout of krb5 at the top level: - $ git clone https://github.com/krb5/krb5 + $ git submodule update --init krb5's master has to pass this same CI, but a known-good version is krb5-1.15.1-final if you want to be sure. diff --git a/crypto/openssl/test/asn1_decode_test.c b/crypto/openssl/test/asn1_decode_test.c index 7796968c2389..49af48c1605e 100644 --- a/crypto/openssl/test/asn1_decode_test.c +++ b/crypto/openssl/test/asn1_decode_test.c @@ -1,5 +1,5 @@ /* - * Copyright 2017-2024 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2017-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -41,7 +41,7 @@ ASN1_SEQUENCE(ASN1_LONG_DATA) = { ASN1_EMBED(ASN1_LONG_DATA, test_long, LONG), } static_ASN1_SEQUENCE_END(ASN1_LONG_DATA) - IMPLEMENT_STATIC_ASN1_ENCODE_FUNCTIONS(ASN1_LONG_DATA) +IMPLEMENT_STATIC_ASN1_ENCODE_FUNCTIONS(ASN1_LONG_DATA) IMPLEMENT_STATIC_ASN1_ALLOC_FUNCTIONS(ASN1_LONG_DATA) static int test_long(void) @@ -67,7 +67,7 @@ ASN1_SEQUENCE(ASN1_INT32_DATA) = { ASN1_EMBED(ASN1_INT32_DATA, test_int32, INT32), } static_ASN1_SEQUENCE_END(ASN1_INT32_DATA) - IMPLEMENT_STATIC_ASN1_ENCODE_FUNCTIONS(ASN1_INT32_DATA) +IMPLEMENT_STATIC_ASN1_ENCODE_FUNCTIONS(ASN1_INT32_DATA) IMPLEMENT_STATIC_ASN1_ALLOC_FUNCTIONS(ASN1_INT32_DATA) static int test_int32(void) @@ -92,7 +92,7 @@ ASN1_SEQUENCE(ASN1_UINT32_DATA) = { ASN1_EMBED(ASN1_UINT32_DATA, test_uint32, UINT32), } static_ASN1_SEQUENCE_END(ASN1_UINT32_DATA) - IMPLEMENT_STATIC_ASN1_ENCODE_FUNCTIONS(ASN1_UINT32_DATA) +IMPLEMENT_STATIC_ASN1_ENCODE_FUNCTIONS(ASN1_UINT32_DATA) IMPLEMENT_STATIC_ASN1_ALLOC_FUNCTIONS(ASN1_UINT32_DATA) static int test_uint32(void) @@ -117,7 +117,7 @@ ASN1_SEQUENCE(ASN1_INT64_DATA) = { ASN1_EMBED(ASN1_INT64_DATA, test_int64, INT64), } static_ASN1_SEQUENCE_END(ASN1_INT64_DATA) - IMPLEMENT_STATIC_ASN1_ENCODE_FUNCTIONS(ASN1_INT64_DATA) +IMPLEMENT_STATIC_ASN1_ENCODE_FUNCTIONS(ASN1_INT64_DATA) IMPLEMENT_STATIC_ASN1_ALLOC_FUNCTIONS(ASN1_INT64_DATA) static int test_int64(void) @@ -142,7 +142,7 @@ ASN1_SEQUENCE(ASN1_UINT64_DATA) = { ASN1_EMBED(ASN1_UINT64_DATA, test_uint64, UINT64), } static_ASN1_SEQUENCE_END(ASN1_UINT64_DATA) - IMPLEMENT_STATIC_ASN1_ENCODE_FUNCTIONS(ASN1_UINT64_DATA) +IMPLEMENT_STATIC_ASN1_ENCODE_FUNCTIONS(ASN1_UINT64_DATA) IMPLEMENT_STATIC_ASN1_ALLOC_FUNCTIONS(ASN1_UINT64_DATA) static int test_uint64(void) @@ -243,7 +243,7 @@ ASN1_SEQUENCE(INVALIDTEMPLATE) = { ASN1_IMP(INVALIDTEMPLATE, invalidDirString, DIRECTORYSTRING, 12) } static_ASN1_SEQUENCE_END(INVALIDTEMPLATE) - IMPLEMENT_STATIC_ASN1_ENCODE_FUNCTIONS(INVALIDTEMPLATE) +IMPLEMENT_STATIC_ASN1_ENCODE_FUNCTIONS(INVALIDTEMPLATE) IMPLEMENT_STATIC_ASN1_ALLOC_FUNCTIONS(INVALIDTEMPLATE) /* Empty sequence for invalid template test */ diff --git a/crypto/openssl/test/asn1_encode_test.c b/crypto/openssl/test/asn1_encode_test.c index 7d7cc0100bf1..03913d1d0e70 100644 --- a/crypto/openssl/test/asn1_encode_test.c +++ b/crypto/openssl/test/asn1_encode_test.c @@ -1,5 +1,5 @@ /* - * Copyright 2017-2024 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2017-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -198,7 +198,7 @@ ASN1_SEQUENCE(ASN1_LONG_DATA) = { ASN1_EXP_OPT(ASN1_LONG_DATA, test_zlong, ZLONG, 0) } static_ASN1_SEQUENCE_END(ASN1_LONG_DATA) - IMPLEMENT_STATIC_ASN1_ENCODE_FUNCTIONS(ASN1_LONG_DATA) +IMPLEMENT_STATIC_ASN1_ENCODE_FUNCTIONS(ASN1_LONG_DATA) IMPLEMENT_STATIC_ASN1_ALLOC_FUNCTIONS(ASN1_LONG_DATA) static ASN1_LONG_DATA long_expected_32bit[] = { @@ -292,7 +292,7 @@ ASN1_SEQUENCE(ASN1_INT32_DATA) = { ASN1_EXP_OPT_EMBED(ASN1_INT32_DATA, test_zint32, ZINT32, 0) } static_ASN1_SEQUENCE_END(ASN1_INT32_DATA) - IMPLEMENT_STATIC_ASN1_ENCODE_FUNCTIONS(ASN1_INT32_DATA) +IMPLEMENT_STATIC_ASN1_ENCODE_FUNCTIONS(ASN1_INT32_DATA) IMPLEMENT_STATIC_ASN1_ALLOC_FUNCTIONS(ASN1_INT32_DATA) static ASN1_INT32_DATA int32_expected[] = { @@ -340,7 +340,7 @@ ASN1_SEQUENCE(ASN1_UINT32_DATA) = { ASN1_EXP_OPT_EMBED(ASN1_UINT32_DATA, test_zuint32, ZUINT32, 0) } static_ASN1_SEQUENCE_END(ASN1_UINT32_DATA) - IMPLEMENT_STATIC_ASN1_ENCODE_FUNCTIONS(ASN1_UINT32_DATA) +IMPLEMENT_STATIC_ASN1_ENCODE_FUNCTIONS(ASN1_UINT32_DATA) IMPLEMENT_STATIC_ASN1_ALLOC_FUNCTIONS(ASN1_UINT32_DATA) static ASN1_UINT32_DATA uint32_expected[] = { @@ -388,7 +388,7 @@ ASN1_SEQUENCE(ASN1_INT64_DATA) = { ASN1_EXP_OPT_EMBED(ASN1_INT64_DATA, test_zint64, ZINT64, 0) } static_ASN1_SEQUENCE_END(ASN1_INT64_DATA) - IMPLEMENT_STATIC_ASN1_ENCODE_FUNCTIONS(ASN1_INT64_DATA) +IMPLEMENT_STATIC_ASN1_ENCODE_FUNCTIONS(ASN1_INT64_DATA) IMPLEMENT_STATIC_ASN1_ALLOC_FUNCTIONS(ASN1_INT64_DATA) static ASN1_INT64_DATA int64_expected[] = { @@ -437,7 +437,7 @@ ASN1_SEQUENCE(ASN1_UINT64_DATA) = { ASN1_EXP_OPT_EMBED(ASN1_UINT64_DATA, test_zuint64, ZUINT64, 0) } static_ASN1_SEQUENCE_END(ASN1_UINT64_DATA) - IMPLEMENT_STATIC_ASN1_ENCODE_FUNCTIONS(ASN1_UINT64_DATA) +IMPLEMENT_STATIC_ASN1_ENCODE_FUNCTIONS(ASN1_UINT64_DATA) IMPLEMENT_STATIC_ASN1_ALLOC_FUNCTIONS(ASN1_UINT64_DATA) static ASN1_UINT64_DATA uint64_expected[] = { @@ -873,7 +873,7 @@ ASN1_SEQUENCE(INVALIDTEMPLATE) = { ASN1_IMP(INVALIDTEMPLATE, invalidDirString, DIRECTORYSTRING, 12) } static_ASN1_SEQUENCE_END(INVALIDTEMPLATE) - IMPLEMENT_STATIC_ASN1_ENCODE_FUNCTIONS(INVALIDTEMPLATE) +IMPLEMENT_STATIC_ASN1_ENCODE_FUNCTIONS(INVALIDTEMPLATE) IMPLEMENT_STATIC_ASN1_ALLOC_FUNCTIONS(INVALIDTEMPLATE) static int test_invalid_template(void) diff --git a/crypto/openssl/test/asn1_internal_test.c b/crypto/openssl/test/asn1_internal_test.c index 4e58da2b755c..865877d78f8a 100644 --- a/crypto/openssl/test/asn1_internal_test.c +++ b/crypto/openssl/test/asn1_internal_test.c @@ -1,5 +1,5 @@ /* - * Copyright 1999-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1999-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -20,6 +20,7 @@ #include <openssl/asn1.h> #include <openssl/evp.h> +#include <openssl/pkcs12.h> #include <openssl/objects.h> #include "testutil.h" #include "internal/nelem.h" @@ -290,6 +291,22 @@ static int test_mbstring_ncopy(void) return 1; } +static int test_ossl_uni2utf8(void) +{ + const unsigned char in[] = { 0x21, 0x92 }; /* unicode right arrow */ + int inlen = 2; + char *out = NULL; + int ok = 0; + + /* reproducer for CVE-2025-69419 */ + out = OPENSSL_uni2utf8(in, inlen); + if (TEST_str_eq(out, "\xe2\x86\x92")) + ok = 1; + + OPENSSL_free(out); + return ok; +} + int setup_tests(void) { ADD_TEST(test_tbl_standard); @@ -300,5 +317,6 @@ int setup_tests(void) ADD_TEST(test_obj_create); ADD_TEST(test_obj_nid_undef); ADD_TEST(test_mbstring_ncopy); + ADD_TEST(test_ossl_uni2utf8); return 1; } diff --git a/crypto/openssl/test/bntest.c b/crypto/openssl/test/bntest.c index d8c71def932d..8eb5e7659a5b 100644 --- a/crypto/openssl/test/bntest.c +++ b/crypto/openssl/test/bntest.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2024 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -1664,6 +1664,52 @@ err: return st; } +static int file_modsqr(STANZA *s) +{ + BIGNUM *a = NULL, *m = NULL, *mod_sqr = NULL, *ret = NULL; + int st = 0; + + if (!TEST_ptr(a = getBN(s, "A")) + || !TEST_ptr(m = getBN(s, "M")) + || !TEST_ptr(mod_sqr = getBN(s, "ModSqr")) + || !TEST_ptr(ret = BN_new())) + goto err; + + if (!TEST_true(BN_mod_sqr(ret, a, m, ctx)) + || !equalBN("A^2 (mod M)", mod_sqr, ret)) + goto err; + + if (BN_is_odd(m)) { + /* Reduce |a| and test the Montgomery version. */ + BN_MONT_CTX *mont = BN_MONT_CTX_new(); + BIGNUM *a_tmp = BN_new(); + + if (mont == NULL || a_tmp == NULL + || !TEST_true(BN_MONT_CTX_set(mont, m, ctx)) + || !TEST_true(BN_nnmod(a_tmp, a, m, ctx)) + || !TEST_true(BN_to_montgomery(a_tmp, a_tmp, mont, ctx)) + || !TEST_true(BN_mod_mul_montgomery(ret, a_tmp, a_tmp, + mont, ctx)) + || !TEST_true(BN_from_montgomery(ret, ret, mont, ctx)) + || !equalBN("A^2 (mod M) (mont)", mod_sqr, ret)) + st = 0; + else + st = 1; + BN_MONT_CTX_free(mont); + BN_free(a_tmp); + if (st == 0) + goto err; + } + + st = 1; +err: + BN_free(a); + BN_free(m); + BN_free(mod_sqr); + BN_free(ret); + return st; +} + static int file_modexp(STANZA *s) { BIGNUM *a = NULL, *e = NULL, *m = NULL, *mod_exp = NULL, *ret = NULL; @@ -3274,6 +3320,7 @@ static int file_test_run(STANZA *s) { "Product", file_product }, { "Quotient", file_quotient }, { "ModMul", file_modmul }, + { "ModSqr", file_modsqr }, { "ModExp", file_modexp }, { "Exp", file_exp }, { "ModSqrt", file_modsqrt }, diff --git a/crypto/openssl/test/certs/cve-2026-28388-ca.pem b/crypto/openssl/test/certs/cve-2026-28388-ca.pem new file mode 100644 index 000000000000..9e36d11c4b4b --- /dev/null +++ b/crypto/openssl/test/certs/cve-2026-28388-ca.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDFTCCAf2gAwIBAgIUOl5NN/jfsuLU9JSGLZAfRzviF+owDQYJKoZIhvcNAQEL +BQAwEjEQMA4GA1UEAwwHVGVzdCBDQTAeFw0yNjAzMTcwODE5NDdaFw0yNzAzMTcw +ODE5NDdaMBIxEDAOBgNVBAMMB1Rlc3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IB +DwAwggEKAoIBAQD0m4KETjF0c25spNWUiNChWP0GalDL0gVDFbtAoMVF/lvlZEcp +hcg62ifHJRPntWyVAmH70DAI87cWzl/73QYGaOcMVcH5yEM31BoK83FvhsS3RTPO +FSrNCHaZrrWuga+QkBmMcR6qX7GF5eb6ASMBsLuuDqbkCRbTJ2ryhYeWF+VFemBF +pSHpcinSSLvswTVbZiCqmoy0WkK8eiyfLMZA17PgVLQpyPZ3rp5YG5vEZZoqFc/f +1bCHjwQ7fNdLCEMqPvE/I0mg2skRClb1L1Vieud/jmjL8nVd9I12j1eUOcSKtCkW +nj4BFa7TRz13sN3LZOFvV774ZaXRJ1GxoAlnAgMBAAGjYzBhMB0GA1UdDgQWBBSt +UxfaVbV9QMmfwMoImdgi4MZHzTAfBgNVHSMEGDAWgBStUxfaVbV9QMmfwMoImdgi +4MZHzTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0B +AQsFAAOCAQEA84w49n0pPJlqiD1/mn3pUZ66lBP0fFZiCuV/3YatBZcW+xcboW0Q +xImYztjZo0i+sQLZOalI4GoBqD77Dv4Qas0QoJZIp0wM8DjE3YcudCr4cpUhT1XC +ruHVHQA9bY5rW0GsfUBW6/3RbRpiK4SaFG3sUBbXPo0dC2EaLDjpLM7o2UljRrWu +d/vg6ieKuAicexLxqQLdM4SxjyvBpCwHg/dnMxawSj4Xhks1BHJ0hTLKJGDgfVHh +ex8+878u6Gf7fAOZa5idWUgTvdt5WHSW5x+Tm/P6LGG3HkM425ZU6BLTCHONoBud +cOlfWTTuIyweX5TRL5HY3SuO1cpMBpjiAA== +-----END CERTIFICATE----- diff --git a/crypto/openssl/test/certs/cve-2026-28388-crls.pem b/crypto/openssl/test/certs/cve-2026-28388-crls.pem new file mode 100644 index 000000000000..46cbd7876dcd --- /dev/null +++ b/crypto/openssl/test/certs/cve-2026-28388-crls.pem @@ -0,0 +1,22 @@ +-----BEGIN X509 CRL----- +MIIBizB1AgEBMA0GCSqGSIb3DQEBCwUAMBIxEDAOBgNVBAMMB1Rlc3QgQ0EXDTI2 +MDMxNzA4MTk0N1oXDTI2MDQxNjA4MTk0N1qgLzAtMB8GA1UdIwQYMBaAFK1TF9pV +tX1AyZ/AygiZ2CLgxkfNMAoGA1UdFAQDAgEBMA0GCSqGSIb3DQEBCwUAA4IBAQBl +3vVknchCNA/oW0ovtnrE+xQs8yAk3uElooQlw88moTcts2YAcKWl49lnNWZk/RbF +Zs8m+MUuNb2W861siuvY3EwnSKVaJB2tKPfCRBP4xt+Q0g/Tn5CWxzpzHjQfLT6l +pvWOwaO7aE6bthX7MQ9XBpnHSPxsbul+MhV5PER11BYZGVh5MH0XxfMI0jDHFh2M +klTamgaao3TkVOI3OQPgzUx/q0Lz/YoCIH0pYGGP6KTGUX2x7UfD1tcIOcUp6tvO +6hG3utMgJOpZJl9yMzhG+ZURjbz4MSbBM0FVIaWnBn2VzY1jHGky0nK83IZhiddf +OohWoSH8tqwrNFZkblAH +-----END X509 CRL----- +-----BEGIN X509 CRL----- +MIIBjjB4AgEBMA0GCSqGSIb3DQEBCwUAMBIxEDAOBgNVBAMMB1Rlc3QgQ0EXDTI2 +MDEwODEyMDAwMFoXDTI2MDIwODEyMDAwMFqgMjAwMB8GA1UdIwQYMBaAFK1TF9pV +tX1AyZ/AygiZ2CLgxkfNMA0GA1UdGwEB/wQDAgEBMA0GCSqGSIb3DQEBCwUAA4IB +AQCyYxa5iVUFxBpdXgBGSMqkuxJqQzVni8nXK0DiXHfgbTud+HD5Qp/6PX2EQuwK +SrT0yeNJBU1gxxMMsbdA0yVTPa7N2Ny39mjq/27yBXduiljo3Gs4NLEW9grJRnep +WOD1cQe3Fea5HlEfUoQJF1WVekF6CnOSqESaDvTAzqpZd7pxU8cuduiRJPin93ki +1nicQAU/G4Td190+JEAWD3/dJTg2LF6LKrmHiv2ZUTuNsVBfcbhFSoC6FpnjFUAI +kF8EgJpuBEfqV6erIuT1GD+5p1QGNqdcNl7LO9erJaUFnssJBJtj84iXd7RZARNs +njcibOSKC9YWgNmZUy0QV5D8 +-----END X509 CRL----- diff --git a/crypto/openssl/test/certs/cve-2026-28388-leaf.pem b/crypto/openssl/test/certs/cve-2026-28388-leaf.pem new file mode 100644 index 000000000000..02b22997cdd8 --- /dev/null +++ b/crypto/openssl/test/certs/cve-2026-28388-leaf.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDHTCCAgWgAwIBAgIBATANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdUZXN0 +IENBMB4XDTI2MDMxNzA4MTk0N1oXDTI3MDMxNzA4MTk0N1owFDESMBAGA1UEAwwJ +VGVzdCBMZWFmMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqx7jpC6+ +nRZ4ol6sShkpv04hGYtt7y+Ns4oIfdQTqo57DItFab8D8cH04zR8NND42MMnsPPn +Ovh9gv2l1mj9ZfwgXI5PvaKc6CoXvXb0ttekdDUS1iw9g04BxIXTDANxsdSXrCDd +Npyr1Pxdo3N2fiH6qN9/Lsh7yg0vJW/aJzdvhLcCTFcr89qmCsh17XfcTR0wZJXP +QdlRib9EK8aa6aKOYmm44SBbuXXyWojhheUaqVuzDj6A0L9opmh/DVXa9bdIN/FX +CKJB+d60Qxy5pKwpzDDxbCdG2vA1U2cPz8yAgelFG5AmXSHF7Id4G6GTCAY6PbTO +Jy2Z4I6NY+mj5wIDAQABo3wwejAdBgNVHQ4EFgQUlf2YZ93MvS4kZm7fshosgp+J +ImkwHwYDVR0jBBgwFoAUrVMX2lW1fUDJn8DKCJnYIuDGR80wCQYDVR0TBAIwADAt +BgNVHS4EJjAkMCKgIKAehhxodHRwOi8vZXhhbXBsZS5jb20vZGVsdGEucGVtMA0G +CSqGSIb3DQEBCwUAA4IBAQDoNAQGLS0Juf3i2fhuVQyWIFvNIMElLexeLnnd/y80 +13nsP68ZGT2D3DoHQSz3SL7sNjLBc2CiUVftdaRQ4dNCz8sBY5BRTS5XEGbbTAFZ +bQUReykuuTy83CGw/JYN6YT/OHcf4gEhUnWtRMCmIz3J/NMRVSRnpV2Ezjltm/Q+ +emFS/QclRhkP6Vu+lwM/nV6uAN8T7Ba68Hym2MN0clozrpoKeqFouB7D0i+iCZMw +zbac5as0hn7Fm+HGTbfTs2/fqUslvE6PmagepceP37pTSSVmYRmdpOD2cyCb30A+ +nJFGQg7PcacGSL1re65W35XzdU8Si8OYD+PxjDaRbPcP +-----END CERTIFICATE----- diff --git a/crypto/openssl/test/certs/ext-timeSpecification-periodic-no-second.pem b/crypto/openssl/test/certs/ext-timeSpecification-periodic-no-second.pem new file mode 100644 index 000000000000..9b23ddbb162c --- /dev/null +++ b/crypto/openssl/test/certs/ext-timeSpecification-periodic-no-second.pem @@ -0,0 +1,14 @@ +-----BEGIN CERTIFICATE----- +MIICLzCCAhmgAwIBAgIEDCI4TjANBgkqhkiG9w0BAQUFADARMQ8wDQYDVQQDDAZI +aSBtb20wIhgPMjAyMjEyMjExNDQ5NDJaGA8yMDIyMTIyMTE0NDk0MlowETEPMA0G +A1UEAwwGSGkgbW9tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtnjL +m1ts1hC4fNNt3UnQD9y73bDXgioTyWYSI3ca/KNfuTydjFTEYAmqnuGrBOUfgbmH +3PRQ0AmpqljgWTb3d3K8H4UFvDWQTPSS21IMjm8oqd19nE5GxWirGu0oDRzhWLHe +1RZ7ZrohCPg/1Ocsy47QZuK2laFB0rEmrRWBmEYbDl3/wxf5XfqIqpOynJB02thX +rTCcTM7Rz1FqCFt/ZVZB5hKY2S+CTdE9OIVKlr4WHMfuvUYeOj06GkwLFJHNv2tU ++tovI3mYRxUuY4UupkS3MC+Otey7XKm1P+INjWWoegm6iCAt3VuspVz+6pU2xgl3 +nrAVMQHB4fReQPH0pQIDAQABo4GMMIGJMIGGBgNVHSsEfzB9MXUwUaAlMSMwIaAM +MAqgAwIBBaEDAgEroREwD6ADAgEMoQMCASKiAwIBOKEIMQYCAQECAQKiCDEGAgED +AgEEowgxBgIBBQIBBqQKMQgCAgfmAgIH5zAgoQgxBgIBAwIBBKMIMQYCAQcCAQik +CjEIAgIH5wICB+gBAf8CAfswDQYJKoZIhvcNAQEFBQADAQA= +-----END CERTIFICATE----- diff --git a/crypto/openssl/test/certs/mkcert.sh b/crypto/openssl/test/certs/mkcert.sh index 1cb4a9000c69..1749ca698a23 100755 --- a/crypto/openssl/test/certs/mkcert.sh +++ b/crypto/openssl/test/certs/mkcert.sh @@ -1,6 +1,6 @@ #! /bin/bash # -# Copyright 2016-2023 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2016-2026 The OpenSSL Project Authors. All Rights Reserved. # Copyright (c) 2016 Viktor Dukhovni <openssl-users@dukhovni.org>. # All rights reserved. # @@ -257,7 +257,7 @@ genee() { local cakey=$1; shift local ca=$1; shift - exts=$(printf "%s\n%s\n%s\n%s\n%s\n[alts]\n%s\n" \ + exts=$(printf "%s\n%s\n%s\n%s\n%s\n%s\n[alts]\n%s\n" \ "subjectKeyIdentifier = hash" \ "authorityKeyIdentifier = keyid, issuer" \ "basicConstraints = CA:false" \ diff --git a/crypto/openssl/test/cmp_client_test.c b/crypto/openssl/test/cmp_client_test.c index b0681e85876c..c2072c1be25c 100644 --- a/crypto/openssl/test/cmp_client_test.c +++ b/crypto/openssl/test/cmp_client_test.c @@ -1,5 +1,5 @@ /* - * Copyright 2007-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2007-2026 The OpenSSL Project Authors. All Rights Reserved. * Copyright Nokia 2007-2019 * Copyright Siemens AG 2015-2019 * @@ -35,7 +35,7 @@ static EVP_PKEY *server_key = NULL; static X509 *server_cert = NULL; static EVP_PKEY *client_key = NULL; static X509 *client_cert = NULL; -static unsigned char ref[CMP_TEST_REFVALUE_LENGTH]; +static unsigned char ref[CMP_TEST_REFVALUE_LENGTH]; /* not actually used */ /* * For these unit tests, the client abandons message protection, and for @@ -51,6 +51,30 @@ static void tear_down(CMP_SES_TEST_FIXTURE *fixture) OPENSSL_free(fixture); } +static int set_simple_trust(OSSL_CMP_CTX *ctx, X509 *trusted) +{ + X509_STORE *ts = X509_STORE_new(); + X509_VERIFY_PARAM *vpm; + + /* + * not simply using OSSL_CMP_CTX_set1_srvCert() (to pin the server cert) + * in order to make sure that validated server cert gets cached, + * which is needed for the negative test case test_exec_KUR_bad_pkiConf_protection + */ + if (ts == NULL || !X509_STORE_add_cert(ts, trusted)) + goto err; + + vpm = X509_STORE_get0_param(ts); + if (!X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_NO_CHECK_TIME | X509_V_FLAG_PARTIAL_CHAIN) + || !OSSL_CMP_CTX_set0_trusted(ctx, ts)) + goto err; + + return 1; +err: + X509_STORE_free(ts); + return 0; +} + static CMP_SES_TEST_FIXTURE *set_up(const char *const test_case_name) { CMP_SES_TEST_FIXTURE *fixture; @@ -70,15 +94,15 @@ static CMP_SES_TEST_FIXTURE *set_up(const char *const test_case_name) goto err; if (!TEST_ptr(fixture->cmp_ctx = ctx = OSSL_CMP_CTX_new(libctx, NULL)) || !OSSL_CMP_CTX_set_log_cb(fixture->cmp_ctx, print_to_bio_out) - || !OSSL_CMP_CTX_set_transfer_cb(ctx, OSSL_CMP_CTX_server_perform) + /* using default verbosity: OSSL_CMP_LOG_INFO */ + || !OSSL_CMP_CTX_set_transfer_cb(ctx, ossl_cmp_mock_server_perform) || !OSSL_CMP_CTX_set_transfer_cb_arg(ctx, fixture->srv_ctx) || !OSSL_CMP_CTX_set_option(ctx, OSSL_CMP_OPT_UNPROTECTED_SEND, 1) - || !OSSL_CMP_CTX_set_option(ctx, OSSL_CMP_OPT_UNPROTECTED_ERRORS, 1) || !OSSL_CMP_CTX_set1_oldCert(ctx, client_cert) || !OSSL_CMP_CTX_set1_pkey(ctx, client_key) /* client_key is by default used also for newPkey */ - || !OSSL_CMP_CTX_set1_srvCert(ctx, server_cert) - || !OSSL_CMP_CTX_set1_referenceValue(ctx, ref, sizeof(ref))) + || !set_simple_trust(ctx, server_cert) + || !OSSL_CMP_CTX_set1_referenceValue(ctx, ref, sizeof(ref))) /* not actually needed */ goto err; fixture->req_type = -1; return fixture; @@ -128,9 +152,7 @@ static int execute_exec_certrequest_ses_test(CMP_SES_TEST_FIXTURE *fixture) int status = OSSL_CMP_CTX_get_status(ctx); OSSL_CMP_CTX_print_errors(ctx); - if (!TEST_int_eq(status, fixture->expected) - && !(fixture->expected == OSSL_CMP_PKISTATUS_waiting - && TEST_int_eq(status, OSSL_CMP_PKISTATUS_trans))) + if (!TEST_int_eq(status, fixture->expected)) return 0; if (fixture->expected != OSSL_CMP_PKISTATUS_accepted) return TEST_ptr_null(res); @@ -234,9 +256,9 @@ static int test_exec_IR_ses_poll_no_timeout(void) static int test_exec_IR_ses_poll_total_timeout(void) { - return !test_exec_REQ_ses_poll(OSSL_CMP_PKIBODY_IR, checkAfter + 1, + return test_exec_REQ_ses_poll(OSSL_CMP_PKIBODY_IR, checkAfter + 1, 3 /* pollCount */, checkAfter + 6, - OSSL_CMP_PKISTATUS_waiting); + OSSL_CMP_PKISTATUS_trans); } static int test_exec_CR_ses(int implicit_confirm, int granted, int reject) @@ -266,7 +288,9 @@ static int test_exec_CR_ses_implicit_confirm(void) && test_exec_CR_ses(1, 1 /* granted */, 0); } -static int test_exec_KUR_ses(int transfer_error, int pubkey, int raverified) +/* the KUR transactions include certConf/pkiConf */ +static int test_exec_KUR_ses(int transfer_error, int server_use_bad_protection, + int pubkey, int raverified) { SETUP_TEST_FIXTURE(CMP_SES_TEST_FIXTURE, set_up); fixture->req_type = OSSL_CMP_PKIBODY_KUR; @@ -274,6 +298,8 @@ static int test_exec_KUR_ses(int transfer_error, int pubkey, int raverified) if (transfer_error) OSSL_CMP_CTX_set_transfer_cb_arg(fixture->cmp_ctx, NULL); + (void)ossl_cmp_mock_srv_set_useBadProtection(fixture->srv_ctx, server_use_bad_protection); + if (pubkey) { EVP_PKEY *key = raverified /* wrong key */ ? server_key : client_key; @@ -286,7 +312,8 @@ static int test_exec_KUR_ses(int transfer_error, int pubkey, int raverified) if (pubkey || raverified) OSSL_CMP_CTX_set_option(fixture->cmp_ctx, OSSL_CMP_OPT_POPO_METHOD, OSSL_CRMF_POPO_RAVERIFIED); - fixture->expected = transfer_error ? OSSL_CMP_PKISTATUS_trans : raverified ? OSSL_CMP_PKISTATUS_rejection + fixture->expected = transfer_error ? OSSL_CMP_PKISTATUS_trans : raverified ? (pubkey ? OSSL_CMP_PKISTATUS_rejected_by_client : OSSL_CMP_PKISTATUS_rejection) + : server_use_bad_protection != -1 ? OSSL_CMP_PKISTATUS_checking_response : OSSL_CMP_PKISTATUS_accepted; EXECUTE_TEST(execute_exec_certrequest_ses_test, tear_down); return result; @@ -294,18 +321,23 @@ static int test_exec_KUR_ses(int transfer_error, int pubkey, int raverified) static int test_exec_KUR_ses_ok(void) { - return test_exec_KUR_ses(0, 0, 0); + return test_exec_KUR_ses(0, -1, 0, 0); } static int test_exec_KUR_ses_transfer_error(void) { - return test_exec_KUR_ses(1, 0, 0); + return test_exec_KUR_ses(1, -1, 0, 0); +} + +static int test_exec_KUR_bad_pkiConf_protection(void) +{ + return test_exec_KUR_ses(0, -1 /* disabled: OSSL_CMP_PKIBODY_PKICONF */, 0, 0); } static int test_exec_KUR_ses_wrong_popo(void) { #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION /* cf ossl_cmp_verify_popo() */ - return test_exec_KUR_ses(0, 0, 1); + return test_exec_KUR_ses(0, -1, 0, 1); #else return 1; #endif @@ -313,12 +345,12 @@ static int test_exec_KUR_ses_wrong_popo(void) static int test_exec_KUR_ses_pub(void) { - return test_exec_KUR_ses(0, 1, 0); + return test_exec_KUR_ses(0, -1, 1, 0); } static int test_exec_KUR_ses_wrong_pub(void) { - return test_exec_KUR_ses(0, 1, 1); + return test_exec_KUR_ses(0, -1, 1, 1); } static int test_certConf_cb(OSSL_CMP_CTX *ctx, X509 *cert, int fail_info, @@ -340,7 +372,7 @@ static int test_exec_P10CR_ses(int reject) SETUP_TEST_FIXTURE(CMP_SES_TEST_FIXTURE, set_up); fixture->req_type = OSSL_CMP_PKIBODY_P10CR; - fixture->expected = reject ? OSSL_CMP_PKISTATUS_rejection + fixture->expected = reject ? OSSL_CMP_PKISTATUS_rejected_by_client : OSSL_CMP_PKISTATUS_accepted; ctx = fixture->cmp_ctx; if (!TEST_ptr(csr = load_csr_der(pkcs10_f, libctx)) @@ -436,7 +468,7 @@ static int test_exec_GENM_ses_poll_total_timeout(void) { return test_exec_REQ_ses_poll(OSSL_CMP_PKIBODY_GENM, checkAfter + 1, 3 /* pollCount */, checkAfter + 2, - OSSL_CMP_PKISTATUS_waiting); + OSSL_CMP_PKISTATUS_trans); } static int test_exec_GENM_ses(int transfer_error, int total_timeout, int expect) @@ -546,7 +578,7 @@ int setup_tests(void) || !TEST_ptr(server_cert = load_cert_pem(server_cert_f, libctx)) || !TEST_ptr(client_key = load_pkey_pem(client_key_f, libctx)) || !TEST_ptr(client_cert = load_cert_pem(client_cert_f, libctx)) - || !TEST_int_eq(1, RAND_bytes_ex(libctx, ref, sizeof(ref), 0))) { + || !TEST_int_eq(1, RAND_bytes_ex(libctx, ref, sizeof(ref), 0))) { /* not actually used */ cleanup_tests(); return 0; } @@ -562,6 +594,7 @@ int setup_tests(void) ADD_TEST(test_exec_IR_ses_poll_total_timeout); ADD_TEST(test_exec_KUR_ses_ok); ADD_TEST(test_exec_KUR_ses_transfer_error); + ADD_TEST(test_exec_KUR_bad_pkiConf_protection); ADD_TEST(test_exec_KUR_ses_wrong_popo); ADD_TEST(test_exec_KUR_ses_pub); ADD_TEST(test_exec_KUR_ses_wrong_pub); diff --git a/crypto/openssl/test/evp_extra_test.c b/crypto/openssl/test/evp_extra_test.c index f55d17258d1f..eec9364f42ba 100644 --- a/crypto/openssl/test/evp_extra_test.c +++ b/crypto/openssl/test/evp_extra_test.c @@ -1,5 +1,5 @@ /* - * Copyright 2015-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2015-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -929,6 +929,32 @@ static EVP_PKEY *load_example_ec_key(void) #endif #ifndef OPENSSL_NO_DEPRECATED_3_0 + +static EVP_PKEY *make_bad_rsa_pubkey(void) +{ + RSA *rsa = NULL; + BIGNUM *n = NULL, *e = NULL; + EVP_PKEY *pkey = NULL; + + /* Deliberately invalid public key: n = 17, e = 17 */ + if (!TEST_ptr(pkey = EVP_PKEY_new()) + || !TEST_ptr(rsa = RSA_new()) + || !TEST_ptr(n = BN_new()) + || !TEST_ptr(e = BN_new()) + || !TEST_true(BN_set_word(n, 17)) + || !TEST_true(BN_set_word(e, 17)) + || !TEST_true(RSA_set0_key(rsa, n, e, NULL)) + || !EVP_PKEY_assign_RSA(pkey, rsa)) + goto err; + + return pkey; +err: + BN_free(n); + BN_free(e); + RSA_free(rsa); + return NULL; +} + #ifndef OPENSSL_NO_DH static EVP_PKEY *load_example_dh_key(void) { @@ -5898,6 +5924,46 @@ err: return testresult; } +static int test_rsasve_kem_with_invalid_pub_key(void) +{ + RSA *rsa = NULL; + EVP_PKEY *pkey = NULL; + EVP_PKEY_CTX *ctx = NULL; + unsigned char *ct = NULL; + unsigned char *secret = NULL; + size_t ctlen = 0, secretlen = 0; + int testresult = 0; + + if (nullprov != NULL) { + testresult = TEST_skip("Test does not support a non-default library context"); + goto err; + } + + if (!TEST_ptr(pkey = make_bad_rsa_pubkey())) + goto err; + + if (!TEST_ptr(ctx = EVP_PKEY_CTX_new_from_pkey(testctx, pkey, NULL)) + || !TEST_int_eq(EVP_PKEY_encapsulate_init(ctx, NULL), 1) + || !TEST_int_eq(EVP_PKEY_CTX_set_kem_op(ctx, "RSASVE"), 1) + || !TEST_int_eq(EVP_PKEY_encapsulate(ctx, NULL, &ctlen, NULL, &secretlen), 1) + || !TEST_ptr(ct = OPENSSL_malloc(ctlen)) + || !TEST_ptr(secret = OPENSSL_malloc(secretlen))) + goto err; + + if (!TEST_int_eq(EVP_PKEY_encapsulate(ctx, ct, &ctlen, secret, &secretlen), 0)) + goto err; + + testresult = 1; + +err: + OPENSSL_free(secret); + OPENSSL_free(ct); + EVP_PKEY_CTX_free(ctx); + RSA_free(rsa); + EVP_PKEY_free(pkey); + return testresult; +} + #ifndef OPENSSL_NO_DYNAMIC_ENGINE /* Test we can create a signature keys with an associated ENGINE */ static int test_signatures_with_engine(int tst) @@ -6481,6 +6547,45 @@ static int test_invalid_ctx_for_digest(void) return ret; } +static int test_evp_cipher_negative_length(void) +{ + EVP_CIPHER_CTX *ctx = NULL; + EVP_CIPHER *cipher = NULL; + unsigned char key[16] = { 0 }; + unsigned char iv[16] = { 0 }; + unsigned char buffer[32] = { 0 }; + int outl = 0; + int ret = 0; + + if (!TEST_ptr(ctx = EVP_CIPHER_CTX_new())) + goto end; + + if (!TEST_ptr(cipher = EVP_CIPHER_fetch(testctx, "AES-128-CBC", testpropq))) + goto end; + + /* Initialize encryption context */ + if (!TEST_int_eq(EVP_EncryptInit_ex2(ctx, cipher, key, iv, NULL), 1)) + goto end; + + /* Test EVP_EncryptUpdate with negative length - should fail */ + if (!TEST_int_eq(EVP_EncryptUpdate(ctx, buffer, &outl, (unsigned char *)"test", -1), 0)) + goto end; + + /* Reinitialize for decryption */ + if (!TEST_int_eq(EVP_DecryptInit_ex2(ctx, cipher, key, iv, NULL), 1)) + goto end; + + /* Test EVP_DecryptUpdate with negative length - should fail */ + if (!TEST_int_eq(EVP_DecryptUpdate(ctx, buffer, &outl, (unsigned char *)"test", -1), 0)) + goto end; + + ret = 1; +end: + EVP_CIPHER_free(cipher); + EVP_CIPHER_CTX_free(ctx); + return ret; +} + static int test_evp_cipher_pipeline(void) { OSSL_PROVIDER *fake_pipeline = NULL; @@ -6854,6 +6959,7 @@ int setup_tests(void) ADD_TEST(test_evp_md_cipher_meth); ADD_TEST(test_custom_md_meth); ADD_TEST(test_custom_ciph_meth); + ADD_TEST(test_rsasve_kem_with_invalid_pub_key); #ifndef OPENSSL_NO_DYNAMIC_ENGINE /* Tests only support the default libctx */ @@ -6883,6 +6989,8 @@ int setup_tests(void) ADD_TEST(test_invalid_ctx_for_digest); + ADD_TEST(test_evp_cipher_negative_length); + ADD_TEST(test_evp_cipher_pipeline); return 1; diff --git a/crypto/openssl/test/evp_test.c b/crypto/openssl/test/evp_test.c index 582328c877e0..e742b647e3b7 100644 --- a/crypto/openssl/test/evp_test.c +++ b/crypto/openssl/test/evp_test.c @@ -1,5 +1,5 @@ /* - * Copyright 2015-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2015-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -2607,7 +2607,7 @@ static int pkey_test_ctrl(EVP_TEST *t, EVP_PKEY_CTX *pctx, static int pkey_add_control(EVP_TEST *t, STACK_OF(OPENSSL_STRING) *controls, const char *value) { - char *p; + const char *p; if (controls == NULL) return 0; diff --git a/crypto/openssl/test/fake_rsaprov.c b/crypto/openssl/test/fake_rsaprov.c index 6252456e8df1..ec5d5df5b85b 100644 --- a/crypto/openssl/test/fake_rsaprov.c +++ b/crypto/openssl/test/fake_rsaprov.c @@ -1,5 +1,5 @@ /* - * Copyright 2021-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2021-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -776,8 +776,7 @@ ASN1_SEQUENCE(X509_PUBKEY_INTERNAL) = { ASN1_SIMPLE(X509_PUBKEY, public_key, ASN1_BIT_STRING) } static_ASN1_SEQUENCE_END_name(X509_PUBKEY, X509_PUBKEY_INTERNAL) - static X509_PUBKEY - * fake_rsa_d2i_X509_PUBKEY_INTERNAL(const unsigned char **pp, long len, OSSL_LIB_CTX *libctx) +static X509_PUBKEY *fake_rsa_d2i_X509_PUBKEY_INTERNAL(const unsigned char **pp, long len, OSSL_LIB_CTX *libctx) { X509_PUBKEY *xpub = OPENSSL_zalloc(sizeof(*xpub)); diff --git a/crypto/openssl/test/http_test.c b/crypto/openssl/test/http_test.c index 8b27e128cbf6..14942d511fcd 100644 --- a/crypto/openssl/test/http_test.c +++ b/crypto/openssl/test/http_test.c @@ -1,5 +1,5 @@ /* - * Copyright 2020-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2020-2026 The OpenSSL Project Authors. All Rights Reserved. * Copyright Siemens AG 2020 * * Licensed under the Apache License 2.0 (the "License"). You may not use @@ -331,6 +331,18 @@ static int test_http_url_path_query_ok(const char *url, const char *exp_path_qu) return res; } +static int test_http_url_host_ok(const char *url, const char *exp_host) +{ + char *host; + int res; + + res = TEST_true(OSSL_HTTP_parse_url(url, NULL, NULL, &host, NULL, NULL, + NULL, NULL, NULL)) + && TEST_str_eq(host, exp_host); + OPENSSL_free(host); + return res; +} + static int test_http_url_dns(void) { return test_http_url_ok("host:65535/path", 0, "host", "65535", "/path"); @@ -358,6 +370,13 @@ static int test_http_url_userinfo_query_fragment(void) return test_http_url_ok("user:pass@host/p?q#fr", 0, "host", "80", "/p"); } +static int test_http_url_at_sign_outside_authority(void) +{ + return test_http_url_host_ok("http://host/p@attacker.test", "host") + && test_http_url_host_ok("http://host/p?q=@attacker.test", "host") + && test_http_url_host_ok("http://host/p?q#fr@attacker.test", "host"); +} + static int test_http_url_ipv4(void) { return test_http_url_ok("https://1.2.3.4/p/q", 1, "1.2.3.4", "443", "/p/q"); @@ -576,6 +595,7 @@ int setup_tests(void) ADD_TEST(test_http_url_timestamp); ADD_TEST(test_http_url_path_query); ADD_TEST(test_http_url_userinfo_query_fragment); + ADD_TEST(test_http_url_at_sign_outside_authority); ADD_TEST(test_http_url_ipv4); ADD_TEST(test_http_url_ipv6); ADD_TEST(test_http_url_invalid_prefix); diff --git a/crypto/openssl/test/ossl_store_test.c b/crypto/openssl/test/ossl_store_test.c index f251313d1a69..50efd037a8ec 100644 --- a/crypto/openssl/test/ossl_store_test.c +++ b/crypto/openssl/test/ossl_store_test.c @@ -1,5 +1,5 @@ /* - * Copyright 2020-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2020-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -249,6 +249,12 @@ static int test_store_attach_unregistered_scheme(void) return ret; } +static int test_store_delete_null_uri(void) +{ + /* Passing NULL uri must return 0, not crash */ + return TEST_int_eq(OSSL_STORE_delete(NULL, NULL, NULL, NULL, NULL, NULL), 0); +} + const OPTIONS *test_get_options(void) { static const OPTIONS test_options[] = { @@ -303,6 +309,7 @@ int setup_tests(void) ADD_TEST(test_store_open_winstore); #endif ADD_TEST(test_store_search_by_key_fingerprint_fail); + ADD_TEST(test_store_delete_null_uri); ADD_ALL_TESTS(test_store_get_params, 3); if (sm2file != NULL) ADD_TEST(test_store_attach_unregistered_scheme); diff --git a/crypto/openssl/test/pkcs12_api_test.c b/crypto/openssl/test/pkcs12_api_test.c index b013818f0bf3..147d65bd665a 100644 --- a/crypto/openssl/test/pkcs12_api_test.c +++ b/crypto/openssl/test/pkcs12_api_test.c @@ -1,5 +1,5 @@ /* - * Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2022-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -253,6 +253,35 @@ const OPTIONS *test_get_options(void) return options; } +static int test_PKCS12_set_pbmac1_pbkdf2_invalid_saltlen(void) +{ + int ret = 0; + unsigned char salt[8] = { 0 }; + EVP_PKEY *key = NULL; + X509 *cert = NULL; + STACK_OF(X509) *ca = NULL; + PKCS12 *p12 = NULL; + + if (!TEST_ptr(p12 = PKCS12_load(in_file))) + return 0; + if (!TEST_true(PKCS12_parse(p12, in_pass, &key, &cert, &ca))) + goto err; + PKCS12_free(p12); + + if (!TEST_ptr(p12 = PKCS12_create_ex2("pass", NULL, key, cert, ca, + NID_undef, NID_undef, 0, -1, 0, + testctx, NULL, NULL, NULL))) + goto err; + ret = TEST_false(PKCS12_set_pbmac1_pbkdf2(p12, "pass", -1, + salt, -1, 0, NULL, NULL)); +err: + PKCS12_free(p12); + EVP_PKEY_free(key); + X509_free(cert); + OSSL_STACK_OF_X509_free(ca); + return ret; +} + int setup_tests(void) { OPTION_CHOICE o; @@ -292,6 +321,7 @@ int setup_tests(void) ADD_TEST(test_null_args); ADD_TEST(pkcs12_parse_test); ADD_ALL_TESTS(pkcs12_create_ex2_test, 3); + ADD_TEST(test_PKCS12_set_pbmac1_pbkdf2_invalid_saltlen); return 1; } diff --git a/crypto/openssl/test/quicapitest.c b/crypto/openssl/test/quicapitest.c index 6b9ee8e69ad8..c61dda6f7f7f 100644 --- a/crypto/openssl/test/quicapitest.c +++ b/crypto/openssl/test/quicapitest.c @@ -1,5 +1,5 @@ /* - * Copyright 2022-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2022-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -2869,8 +2869,8 @@ static int test_ssl_set_verify(void) serverssl = SSL_accept_connection(qlistener, 0); /* Call SSL_accept() and SSL_connect() until we are connected */ - if (!TEST_true(create_bare_ssl_connection(serverssl, clientssl, - SSL_ERROR_NONE, 0, 0))) + if (!TEST_ptr(serverssl) + || !TEST_true(create_bare_ssl_connection(serverssl, clientssl, SSL_ERROR_NONE, 0, 0))) goto err; testresult = 1; @@ -2923,8 +2923,8 @@ static int test_client_hello_retry(void) serverssl = SSL_accept_connection(qlistener, 0); /* Call SSL_accept() and SSL_connect() until we are connected */ - if (!TEST_true(create_bare_ssl_connection(serverssl, clientssl, - SSL_ERROR_NONE, 0, 0))) + if (!TEST_ptr(serverssl) + || !TEST_true(create_bare_ssl_connection(serverssl, clientssl, SSL_ERROR_NONE, 0, 0))) goto err; testresult = 1; diff --git a/crypto/openssl/test/recipes/10-test_bn_data/bnmod.txt b/crypto/openssl/test/recipes/10-test_bn_data/bnmod.txt index 85a17e0a05dc..a0a30df45e74 100644 --- a/crypto/openssl/test/recipes/10-test_bn_data/bnmod.txt +++ b/crypto/openssl/test/recipes/10-test_bn_data/bnmod.txt @@ -1,4 +1,4 @@ -# Copyright 2016-2022 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2016-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy @@ -2010,6 +2010,14 @@ A = ca6c51ba2f410d09bf71d60fe B = 8bdfa8fe5ef3b2ad02bc63c4d M = 84daecf412b8c50ad6dfdb546c3eb783dcc6f32003eda914bb +# These test vectors satisfy A ^ 2 = ModSqr (mod M) and 0 <= ModSqr < M. + +Title = ModSqr tests + +# Regression test for https://github.com/openssl/openssl/issues/15587 +ModSqr = 166794ed50cb31b6e6a319f7474416c266d5c3f3115ea2a7ed9638367d1f955f66a7179ee3ce5ee5e04e63c46781f1192beac3abb26ff238f5ed2f5505ae06003ff +A = 1407833bd4c893195cc32f56a507f15140be687a1994febe0bdbe793125f010a3c1c814737b10ab690498b7990ce4e625ad2f32cbf42626cb9649da38a5c9c76a99 +M = 1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff # These test vectors satisfy A ^ E = ModExp (mod M) and 0 <= ModExp < M. diff --git a/crypto/openssl/test/recipes/25-test_verify.t b/crypto/openssl/test/recipes/25-test_verify.t index 673c3d5f1772..ab8cdff23a21 100644 --- a/crypto/openssl/test/recipes/25-test_verify.t +++ b/crypto/openssl/test/recipes/25-test_verify.t @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2015-2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2015-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy @@ -30,7 +30,7 @@ sub verify { run(app([@args])); } -plan tests => 203; +plan tests => 204; # Canonical success ok(verify("ee-cert", "sslserver", ["root-cert"], ["ca-cert"]), @@ -594,6 +594,18 @@ ok(!verify("ee-cert-policies-bad", "", ["root-cert"], ["ca-pol-cert"], "-explicit_policy"), "Bad certificate policy"); +# CVE-2026-28388 +my $cve_28388_stderr = "cve-2026-28388.err"; +run(app(["openssl", "verify", + "-attime", "1739527200", + "-CAfile", srctop_file(@certspath, "cve-2026-28388-ca.pem"), + "-crl_check", "-use_deltas", + "-CRLfile", srctop_file(@certspath, "cve-2026-28388-crls.pem"), + srctop_file(@certspath, "cve-2026-28388-leaf.pem")], + stderr => $cve_28388_stderr)); +ok(grep(/CRL is not yet valid/, do { open my $fh, '<', $cve_28388_stderr; <$fh> }), + "CVE-2026-28388"); + # CAstore option my $rootcertname = "root-cert"; my $rootcert = srctop_file(@certspath, "${rootcertname}.pem"); diff --git a/crypto/openssl/test/recipes/25-test_x509.t b/crypto/openssl/test/recipes/25-test_x509.t index dfa0a428f5f0..e4e373fd5d0e 100644 --- a/crypto/openssl/test/recipes/25-test_x509.t +++ b/crypto/openssl/test/recipes/25-test_x509.t @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2015-2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2015-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy @@ -16,7 +16,7 @@ use OpenSSL::Test qw/:DEFAULT srctop_file/; setup("test_x509"); -plan tests => 138; +plan tests => 139; # Prevent MSys2 filename munging for arguments that look like file paths but # aren't @@ -413,6 +413,12 @@ cert_contains($time_spec_per_cert, "Years: 2023, 2024", 1, 'X.509 Time Specification (Periodic)'); +my $time_spec_per_no_second_cert = + srctop_file(@certs, "ext-timeSpecification-periodic-no-second.pem"); +cert_contains($time_spec_per_no_second_cert, + "05:43:00 - 12:34:56", + 1, 'X.509 Time Specification (Periodic, no second)'); + my $attr_map_cert = srctop_file(@certs, "ext-attributeMappings.pem"); cert_contains($attr_map_cert, "commonName == localityName", diff --git a/crypto/openssl/test/recipes/61-test_bio_readbuffer.t b/crypto/openssl/test/recipes/61-test_bio_readbuffer.t index e10ab746ae38..cd3db6a6ec54 100644 --- a/crypto/openssl/test/recipes/61-test_bio_readbuffer.t +++ b/crypto/openssl/test/recipes/61-test_bio_readbuffer.t @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2021 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2021-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy @@ -16,7 +16,7 @@ setup('test_bio_readbuffer'); my $pemfile = srctop_file("test", "certs", "leaf.pem"); my $derfile = 'readbuffer_leaf.der'; -plan tests => 3; +plan tests => 4; ok(run(app([ 'openssl', 'x509', '-inform', 'PEM', '-in', $pemfile, '-outform', 'DER', '-out', $derfile])), @@ -27,3 +27,7 @@ ok(run(test(["bio_readbuffer_test", $derfile])), ok(run(test(["bio_readbuffer_test", $pemfile])), "Running bio_readbuffer_test $pemfile"); + +ok(run(app([ 'openssl', 'x509', '-inform', 'DER', '-outform', 'PEM', + '-noout' ], stdin => $derfile)), + "Test stdin read buffer in openssl app"); diff --git a/crypto/openssl/test/recipes/80-test_cmp_http_data/test_commands.csv b/crypto/openssl/test/recipes/80-test_cmp_http_data/test_commands.csv index c6c54239b1d7..9e77baa4b127 100644 --- a/crypto/openssl/test/recipes/80-test_cmp_http_data/test_commands.csv +++ b/crypto/openssl/test/recipes/80-test_cmp_http_data/test_commands.csv @@ -147,6 +147,7 @@ expected,description, -section,val, -cmd,val,val2, -cacertsout,val,val2, -infoty 0,using popo 1 with -centralkeygen, -section,, -cmd,cr,, -centralkeygen, -popo,1, -newkeyout,_RESULT_DIR/newkeyout.pem 1, using popo -1 redundantly with -centralkeygen, -section,, -cmd,cr,, -centralkeygen, -popo,-1, -newkeyout,_RESULT_DIR/newkeyout2.pem 1, using popo -1 alternatively to -centralkeygen, -section,, -cmd,cr,, -popo,-1, -newkeyout,_RESULT_DIR/newkeyout3.pem, -newkeypass,pass:12345, -certout,_RESULT_DIR/test.cert3.pem -1, using centrally generated key (and cert) , -section,, -cmd,cr,,-cert,_RESULT_DIR/test.cert3.pem, -key,_RESULT_DIR/newkeyout3.pem, -keypass,pass:12345 +1, using centrally generated key (and cert) with existing chain, -section,, -cmd,cr,,-cert,_RESULT_DIR/test.cert3.pem, -key,_RESULT_DIR/newkeyout3.pem, -keypass,pass:12345, -extracerts, issuing.crt +1, using centrally generated key (and cert) without giving chain (requires sender cert caching), -section,, -cmd,cr,,-cert,_RESULT_DIR/test.cert3.pem, -key,_RESULT_DIR/newkeyout3.pem, -keypass,pass:12345, -extracerts, "" 0, using centrally generated key with wrong password, -section,, -cmd,cr,,-cert,_RESULT_DIR/test.cert3.pem, -key,_RESULT_DIR/newkeyout3.pem, -keypass,pass:wrong 0, using popo -1 (instead of -centralkeygen) without -newkeyout, -section,, -cmd,cr,, -popo,-1,,BLANK,,BLANK,,BLANK,,BLANK diff --git a/crypto/openssl/test/recipes/80-test_cms.t b/crypto/openssl/test/recipes/80-test_cms.t index 279a498475c8..d3adf2d1af77 100644 --- a/crypto/openssl/test/recipes/80-test_cms.t +++ b/crypto/openssl/test/recipes/80-test_cms.t @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2015-2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2015-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy @@ -53,7 +53,7 @@ my ($no_des, $no_dh, $no_dsa, $no_ec, $no_ec2m, $no_rc2, $no_zlib) $no_rc2 = 1 if disabled("legacy"); -plan tests => 31; +plan tests => 34; ok(run(test(["pkcs7_test"])), "test pkcs7"); @@ -1360,6 +1360,49 @@ with({ exit_checker => sub { return shift == 3; } }, "Check for failure when cipher does not have an assigned OID (issue#22225)"); }); +# Test cases for CVE-2026-28389 +my $smcont_malformed = srctop_file("test", "recipes", "80-test_cms_data", "dh-malformed.der"); +my $smdhcert = srctop_file("test", "recipes", "80-test_cms_data", "dh-cert.pem"); +my $smdhkey = srctop_file("test", "recipes", "80-test_cms_data", "dh-key.pem"); + +with({ exit_checker => sub { return shift == 4; } }, + sub { + SKIP: { + skip "DH is not supported in this build", 1 if $no_dh; + + ok(run(app(["openssl", "cms", @prov, "-decrypt", "-in", $smcont_malformed, + "-inform", "DER", "-recip", $smdhcert, "-inkey", $smdhkey])), + "Must not crash on malformed cms inputs with dh key"); + } + }); + +$smcont_malformed = srctop_file("test", "recipes", "80-test_cms_data", "ecdh-malformed.der"); +my $smecdhcert = srctop_file("test", "recipes", "80-test_cms_data", "ecdh-cert.pem"); +my $smecdhkey = srctop_file("test", "recipes", "80-test_cms_data", "ecdh-key.pem"); + +with({ exit_checker => sub { return shift == 4; } }, + sub { + SKIP: { + skip "EC is not supported in this build", 1 if $no_ec; + + ok(run(app(["openssl", "cms", @prov, "-decrypt", "-in", $smcont_malformed, + "-inform", "DER", "-recip", $smecdhcert, "-inkey", $smecdhkey])), + "Must not crash on malformed cms inputs with ecdh key"); + } + }); + +$smcont_malformed = srctop_file("test", "recipes", "80-test_cms_data", "rsa-malformed.der"); +my $smrsacert = catfile($smdir, "smrsa3.pem"); +my $smrsakey = catfile($smdir, "smrsa3-key.pem"); + +# Test case for CVE-2026-28390 +with({ exit_checker => sub { my $ret = shift; return $ret == 4 || $ret == 0; } }, + sub { + ok(run(app(["openssl", "cms", @prov, "-decrypt", "-in", $smcont_malformed, "-inform", + "DER", "-recip", $smrsacert, "-inkey", $smrsakey, "-out", "{output}.cms"])), + "Must not crash on malformed cms inputs with RSA key"); + }); + # Test encrypt to three recipients, and decrypt using key-only; # i.e. do not follow the recommended practice of providing the # recipient cert in the decrypt op. diff --git a/crypto/openssl/test/recipes/80-test_cms_data/dh-cert.pem b/crypto/openssl/test/recipes/80-test_cms_data/dh-cert.pem new file mode 100644 index 000000000000..f5fb90b9009b --- /dev/null +++ b/crypto/openssl/test/recipes/80-test_cms_data/dh-cert.pem @@ -0,0 +1,31 @@ +-----BEGIN CERTIFICATE----- +MIIFSjCCBDKgAwIBAgIUAV5WB+HkJTxtCmGX88OYfIRfEu8wDQYJKoZIhvcNAQEL +BQAwVjELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoM +GEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDEPMA0GA1UEAwwGcm9vdENBMB4XDTI2 +MDMzMTA4NDUwOVoXDTI2MDQwMTA4NDUwOVowDjEMMAoGA1UEAwwDcG9jMIIDJzCC +AhkGByqGSM4+AgEwggIMAoIBAQD//////////634VFiiu0qar9xWICc9PPHYucWD +zi02lanhNkEUZDP7zJOdziSbPvl9L+NjYwx12PaBsgKuxGF6098e1dX9ZWEkM/Uf +XwZu0IVjZVU97RrztVcTXn9XyTWYTwxw4OaLd+Kmidrz7+hyHfFYoTat5zUwrMpP +SDp5erwKsYKzJPth0QipS7LI4/u5atq3YNf0aB1PQqPeOU30rlbt52NyuxkLB6fI +7gptcJ4C/OHN9+LswDQEzSg0L2GRcv6c6YWD/45PEjLu8oGDw/47G0xvrXM7tfy8 +LsIgBcWO8YN9FoOyxvNKJsGy7/qIa0I4YShcl///////////AgECAoIBAH////// +////1vwqLFFdpU1X7isQE56eeOxc4sHnFptK1PCbIIoyGf3mSc7nEk2ffL6X8bGx +hjrse0DZAVdiML1p749q6v6ysJIZ+o+vgzdoQrGyqp72jXnaq4mvP6vkmswnhjhw +c0W78VNE7Xn39DkO+KxQm1bzmphWZSekHTy9XgVYwVmSfbDohFSl2WRx/dy1bVuw +a/o0DqehUe8cpvpXK3bzsbldjIWD0+R3BTa4TwF+cOb78XZgGgJmlBoXsMi5f050 +wsH/xyeJGXd5QMHh/x2NpjfWuZ3a/l4XYRAC4sd4wb6LQdljeaUTYNl3/UQ1oRww +lC5L//////////8DggEGAAKCAQEA8IGxSTAsrdMqlK3rFejocWZ0fmXhLzlhnARX +l3RL+jHyiFoCyCPRLmGBMaL9HqfcVp7E98IvFBxEjtDVc2tcbUJrbv922QaNYqQl +IwuUhdBHDpg0aSbDTV0Vvbny0hDuD7T7VTUO5D7XJammA2hlbpcfO8xuWFmRjdBJ +ctA+MaUbWL21ZzsF8A5rz58mVRHchrAez5ksNb8xaLd0lZqtbiBDntA52XnSp1bO +M2CPlKcb4qMMxVop2DGakChcxu7BUzob22HpRQl+k5K4Tq+kkToHKMR6obpl9Leu +lzJdR8cH9WqF6TE2YFYkpvzE7V7/Rp4uC6UqOGr62oS4thwLtqNTMFEwHwYDVR0j +BBgwFoAUhVaJNeKfABrhhgMLS692Emszbf0wDwYDVR0TAQH/BAUwAwEB/zAdBgNV +HQ4EFgQUIpXhOwY+ufefb4dBhx3niO/ntO0wDQYJKoZIhvcNAQELBQADggEBABWo +cJfSVwpnYmDHi9U0r0yickvRyFLiOK1vruoKfbkxfYk9J9OwLr4n4S5P5bGXXOSW +AAVXnvYKs6Xn07sg+1X1Sti/1wd/OLOvjaz1ebRqP5MiZRbKIlRHkv2maJEmcdyp +JGR4gHGnu/0I5Zp4DOi+xv1R3vGIkkcl/WIncrJflMJcCRMM4YdMV838kFU2esGm +eB8pTv7acyYsGeSTIk+AYEtS84w3ZQ2sOuGAep0hp9saV/LKiRzNUG0yX2LWP8EO +VMqGSXJqg1TYgAa7lcidtXfQgm+xdTeZzJRbl8Ti3d5YbgXW2vt4vhwkXtPGy5Y3 +NGpnrpeWX4rk4kQmx/I= +-----END CERTIFICATE----- diff --git a/crypto/openssl/test/recipes/80-test_cms_data/dh-key.pem b/crypto/openssl/test/recipes/80-test_cms_data/dh-key.pem new file mode 100644 index 000000000000..16010785214e --- /dev/null +++ b/crypto/openssl/test/recipes/80-test_cms_data/dh-key.pem @@ -0,0 +1,15 @@ +-----BEGIN PRIVATE KEY----- +MIICQAIBADCCAhkGByqGSM4+AgEwggIMAoIBAQD//////////634VFiiu0qar9xW +ICc9PPHYucWDzi02lanhNkEUZDP7zJOdziSbPvl9L+NjYwx12PaBsgKuxGF6098e +1dX9ZWEkM/UfXwZu0IVjZVU97RrztVcTXn9XyTWYTwxw4OaLd+Kmidrz7+hyHfFY +oTat5zUwrMpPSDp5erwKsYKzJPth0QipS7LI4/u5atq3YNf0aB1PQqPeOU30rlbt +52NyuxkLB6fI7gptcJ4C/OHN9+LswDQEzSg0L2GRcv6c6YWD/45PEjLu8oGDw/47 +G0xvrXM7tfy8LsIgBcWO8YN9FoOyxvNKJsGy7/qIa0I4YShcl///////////AgEC +AoIBAH//////////1vwqLFFdpU1X7isQE56eeOxc4sHnFptK1PCbIIoyGf3mSc7n +Ek2ffL6X8bGxhjrse0DZAVdiML1p749q6v6ysJIZ+o+vgzdoQrGyqp72jXnaq4mv +P6vkmswnhjhwc0W78VNE7Xn39DkO+KxQm1bzmphWZSekHTy9XgVYwVmSfbDohFSl +2WRx/dy1bVuwa/o0DqehUe8cpvpXK3bzsbldjIWD0+R3BTa4TwF+cOb78XZgGgJm +lBoXsMi5f050wsH/xyeJGXd5QMHh/x2NpjfWuZ3a/l4XYRAC4sd4wb6LQdljeaUT +YNl3/UQ1oRwwlC5L//////////8EHgIcJmHQRSrQ2wQnNyMZhx9Xdkf8hro/xi1r +xDHoWg== +-----END PRIVATE KEY----- diff --git a/crypto/openssl/test/recipes/80-test_cms_data/dh-malformed.der b/crypto/openssl/test/recipes/80-test_cms_data/dh-malformed.der Binary files differnew file mode 100644 index 000000000000..20a5ed84bde9 --- /dev/null +++ b/crypto/openssl/test/recipes/80-test_cms_data/dh-malformed.der diff --git a/crypto/openssl/test/recipes/80-test_cms_data/ecdh-cert.pem b/crypto/openssl/test/recipes/80-test_cms_data/ecdh-cert.pem new file mode 100644 index 000000000000..3a0ab6624ca2 --- /dev/null +++ b/crypto/openssl/test/recipes/80-test_cms_data/ecdh-cert.pem @@ -0,0 +1,10 @@ +-----BEGIN CERTIFICATE----- +MIIBcTCCARegAwIBAgIUFyBfipahA11TzFxBhYY2WfTejGswCgYIKoZIzj0EAwIw +DjEMMAoGA1UEAwwDcG9jMB4XDTI2MDMzMTA3MzQyOVoXDTI2MDQwMTA3MzQyOVow +DjEMMAoGA1UEAwwDcG9jMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE6iA2FR7s +OgRtpf8cRXDSLSSB5nSzQt2/hzueZTiQXUT1Knto2U5zRqUoioZ/FKsazdhQVQQC +EN0/WYGND+XwmaNTMFEwHwYDVR0jBBgwFoAU+AH0MqgJJ4WYRK+BmEDebmjREYcw +DwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU+AH0MqgJJ4WYRK+BmEDebmjREYcw +CgYIKoZIzj0EAwIDSAAwRQIhAPTS8MWoylN+jfLgRfr75WkJqNFlsrfxCDvMtWV+ +NT2yAiBaY72EVG36EP2gGFEhkBaXb0vLx0r7umDgejEwBWQ9mQ== +-----END CERTIFICATE----- diff --git a/crypto/openssl/test/recipes/80-test_cms_data/ecdh-key.pem b/crypto/openssl/test/recipes/80-test_cms_data/ecdh-key.pem new file mode 100644 index 000000000000..ef9488b3c516 --- /dev/null +++ b/crypto/openssl/test/recipes/80-test_cms_data/ecdh-key.pem @@ -0,0 +1,5 @@ +-----BEGIN PRIVATE KEY----- +MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgeDjy2W+FHVPt1Kg1 +unwzzD9yBC+NtbH/UaZ9PY4wZP6hRANCAATqIDYVHuw6BG2l/xxFcNItJIHmdLNC +3b+HO55lOJBdRPUqe2jZTnNGpSiKhn8UqxrN2FBVBAIQ3T9ZgY0P5fCZ +-----END PRIVATE KEY----- diff --git a/crypto/openssl/test/recipes/80-test_cms_data/ecdh-malformed.der b/crypto/openssl/test/recipes/80-test_cms_data/ecdh-malformed.der Binary files differnew file mode 100644 index 000000000000..14ddc1dea290 --- /dev/null +++ b/crypto/openssl/test/recipes/80-test_cms_data/ecdh-malformed.der diff --git a/crypto/openssl/test/recipes/80-test_cms_data/rsa-malformed.der b/crypto/openssl/test/recipes/80-test_cms_data/rsa-malformed.der Binary files differnew file mode 100644 index 000000000000..4182a465ce79 --- /dev/null +++ b/crypto/openssl/test/recipes/80-test_cms_data/rsa-malformed.der diff --git a/crypto/openssl/test/recipes/80-test_ocsp.t b/crypto/openssl/test/recipes/80-test_ocsp.t index 0539c79d5613..dfba630de42f 100644 --- a/crypto/openssl/test/recipes/80-test_ocsp.t +++ b/crypto/openssl/test/recipes/80-test_ocsp.t @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2015-2022 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2015-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy @@ -37,22 +37,24 @@ sub test_ocsp { } my $expected_exit = shift; my $nochecks = shift; + my $opt_untrusted = shift // "-verify_other"; my $outputfile = basename($inputfile, '.ors') . '.dat'; run(app(["openssl", "base64", "-d", "-in", catfile($ocspdir,$inputfile), "-out", $outputfile])); + my @certopt = ($opt_untrusted, catfile($ocspdir, $untrusted)); with({ exit_checker => sub { return shift == $expected_exit; } }, sub { ok(run(app(["openssl", "ocsp", "-respin", $outputfile, "-partial_chain", @check_time, "-CAfile", catfile($ocspdir, $CAfile), - "-verify_other", catfile($ocspdir, $untrusted), + @certopt, "-no-CApath", "-no-CAstore", $nochecks ? "-no_cert_checks" : ()])), $title); }); } -plan tests => 12; +plan tests => 13; subtest "=== VALID OCSP RESPONSES ===" => sub { plan tests => 7; @@ -230,6 +232,14 @@ subtest "=== OCSP API TESTS===" => sub { "running ocspapitest"); }; +subtest "=== UNTRUSTED ISSUER HINTS ===" => sub { + plan tests => 1; + + test_ocsp("NON-DELEGATED; invalid issuer via -issuer", + "ND1.ors", "ND1_Cross_Root.pem", + "ISIC_ND1_Issuer_ICA.pem", 1, 0, "-issuer"); +}; + subtest "=== OCSP handling of identical input and output files ===" => sub { plan tests => 5; diff --git a/crypto/openssl/test/sslapitest.c b/crypto/openssl/test/sslapitest.c index 993d9e601805..078b1dcf2e77 100644 --- a/crypto/openssl/test/sslapitest.c +++ b/crypto/openssl/test/sslapitest.c @@ -1,5 +1,5 @@ /* - * Copyright 2016-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2016-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -8343,6 +8343,13 @@ static struct { NULL, "AES128-SHA", "AES128-SHA" }, + { TLS1_2_VERSION, + "AES256-SHA", + NULL, + "AES128-SHA", + NULL, + "", + "" }, #endif /* * This test combines TLSv1.3 and TLSv1.2 ciphersuites so they must both be @@ -8367,6 +8374,13 @@ static struct { "TLS_AES_256_GCM_SHA384", "TLS_AES_256_GCM_SHA384", "TLS_AES_256_GCM_SHA384" }, + { TLS1_3_VERSION, + "AES128-SHA", + "TLS_AES_128_GCM_SHA256", + "AES256-SHA", + "TLS_AES_256_GCM_SHA384", + "", + "" }, #endif }; @@ -8377,6 +8391,9 @@ static int int_test_ssl_get_shared_ciphers(int tst, int clnt) int testresult = 0; char buf[1024]; OSSL_LIB_CTX *tmplibctx = OSSL_LIB_CTX_new(); + const char *expbuf = is_fips ? shared_ciphers_data[tst].fipsshared + : shared_ciphers_data[tst].shared; + int handshakeok = strcmp(expbuf, "") != 0; if (!TEST_ptr(tmplibctx)) goto end; @@ -8417,18 +8434,22 @@ static int int_test_ssl_get_shared_ciphers(int tst, int clnt) shared_ciphers_data[tst].srvrtls13ciphers)))) goto end; - if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl, - NULL, NULL)) - || !TEST_true(create_ssl_connection(serverssl, clientssl, - SSL_ERROR_NONE))) + if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl, NULL, + NULL))) goto end; + if (handshakeok) { + if (!TEST_true(create_ssl_connection(serverssl, clientssl, + SSL_ERROR_NONE))) + goto end; + } else { + if (!TEST_false(create_ssl_connection(serverssl, clientssl, + SSL_ERROR_NONE))) + goto end; + } + if (!TEST_ptr(SSL_get_shared_ciphers(serverssl, buf, sizeof(buf))) - || !TEST_int_eq(strcmp(buf, - is_fips - ? shared_ciphers_data[tst].fipsshared - : shared_ciphers_data[tst].shared), - 0)) { + || !TEST_int_eq(strcmp(buf, expbuf), 0)) { TEST_info("Shared ciphers are: %s\n", buf); goto end; } @@ -9714,6 +9735,7 @@ static int test_session_cache_overflow(int idx) SSL *serverssl = NULL, *clientssl = NULL; int testresult = 0; SSL_SESSION *sess = NULL; + int references; #ifdef OSSL_NO_USABLE_TLS1_3 /* If no TLSv1.3 available then do nothing in this case */ @@ -9787,6 +9809,15 @@ static int test_session_cache_overflow(int idx) get_sess_val = SSL_get_session(serverssl); if (!TEST_ptr(get_sess_val)) goto end; + /* + * Normally the session is also stored in the cache, thus we have more than + * one reference, but due to an out-of-memory error it can happen that this + * is the only reference, and in that case the SSL_free(serverssl) below + * would free the get_sess_val, causing a use-after-free error. + */ + if (!TEST_true(CRYPTO_GET_REF(&get_sess_val->references, &references)) + || !TEST_int_ge(references, 2)) + goto end; sess = SSL_get1_session(clientssl); if (!TEST_ptr(sess)) goto end; @@ -13507,6 +13538,52 @@ end: #endif /* !defined(OPENSSL_NO_EC) || !defined(OPENSSL_NO_DH) */ } +/* + * Test that if we attempt to send HTTP to a TLS server that we get the expected + * failure reason code. + */ +static int test_http_verbs(int idx) +{ + SSL_CTX *sctx = NULL; + SSL *serverssl = NULL; + int testresult = 0; + const char *verbs[] = { "GET", "POST", "HEAD" }; + const char *http_trailer = " / HTTP/1.0\r\n\r\n"; + BIO *b = BIO_new(BIO_s_mem()); + + if (!TEST_true((unsigned int)idx < OSSL_NELEM(verbs))) + goto end; + + if (!TEST_true(create_ssl_ctx_pair(libctx, TLS_server_method(), + NULL, 0, 0, &sctx, NULL, cert, privkey))) + goto end; + + serverssl = SSL_new(sctx); + if (!TEST_ptr(serverssl)) + goto end; + + if (!TEST_int_gt(BIO_write(b, verbs[idx], (int)strlen(verbs[idx])), 0)) + goto end; + if (!TEST_int_gt(BIO_write(b, http_trailer, (int)strlen(http_trailer)), 0)) + goto end; + SSL_set_bio(serverssl, b, b); + b = NULL; + + ERR_clear_error(); + if (!TEST_int_le(SSL_accept(serverssl), 0)) + goto end; + if (!TEST_int_eq(ERR_GET_REASON(ERR_get_error()), SSL_R_HTTP_REQUEST)) + goto end; + + testresult = 1; +end: + SSL_free(serverssl); + SSL_CTX_free(sctx); + BIO_free(b); + + return testresult; +} + OPT_TEST_DECLARE_USAGE("certfile privkeyfile srpvfile tmpfile provider config dhfile\n") int setup_tests(void) @@ -13840,6 +13917,7 @@ int setup_tests(void) ADD_TEST(test_ssl_trace); #endif ADD_ALL_TESTS(test_ssl_set_groups_unsupported_keyshare, 2); + ADD_ALL_TESTS(test_http_verbs, 3); return 1; err: diff --git a/crypto/openssl/test/tls-provider.c b/crypto/openssl/test/tls-provider.c index 37f6e32dfd63..354f75fbec31 100644 --- a/crypto/openssl/test/tls-provider.c +++ b/crypto/openssl/test/tls-provider.c @@ -1,5 +1,5 @@ /* - * Copyright 2019-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -2163,8 +2163,7 @@ ASN1_SEQUENCE(X509_PUBKEY_INTERNAL) = { ASN1_SIMPLE(X509_PUBKEY, public_key, ASN1_BIT_STRING) } static_ASN1_SEQUENCE_END_name(X509_PUBKEY, X509_PUBKEY_INTERNAL) - static X509_PUBKEY - * xorx_d2i_X509_PUBKEY_INTERNAL(const unsigned char **pp, long len, OSSL_LIB_CTX *libctx) +static X509_PUBKEY *xorx_d2i_X509_PUBKEY_INTERNAL(const unsigned char **pp, long len, OSSL_LIB_CTX *libctx) { X509_PUBKEY *xpub = OPENSSL_zalloc(sizeof(*xpub)); diff --git a/crypto/openssl/test/tls13groupselection_test.c b/crypto/openssl/test/tls13groupselection_test.c index 8340a9fd2b3b..a3335b0e0dae 100644 --- a/crypto/openssl/test/tls13groupselection_test.c +++ b/crypto/openssl/test/tls13groupselection_test.c @@ -1,5 +1,5 @@ /* - * Copyright 2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2025-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -40,6 +40,12 @@ typedef enum SERVER_RESPONSE { SH = 2 } SERVER_RESPONSE; +static const char *response_desc[] = { + "HRR", + "INIT", + "SH", +}; + static char *cert = NULL; static char *privkey = NULL; @@ -307,7 +313,23 @@ static const struct tls13groupselection_test_st tls13groupselection_tests[] = { { "*brainpoolP256r1:X25519", /* test 43 */ "X25519", SERVER_PREFERENCE, - NEGOTIATION_FAILURE, INIT } + NEGOTIATION_FAILURE, INIT }, + + /* DEFAULT retains tuple structure */ + { "*X25519:secp256r1", + "secp256r1:DEFAULT", /* test 44 */ + SERVER_PREFERENCE, + "secp256r1", HRR }, +#ifndef OPENSSL_NO_DH + { "*ffdhe2048:secp256r1", + "DEFAULT:ffdhe4096", /* test 45 */ + CLIENT_PREFERENCE, + "secp256r1", HRR }, + { "x25519:ffdhe2048:*ffdhe4096", + "DEFAULT:ffdhe4096", /* test 46 */ + SERVER_PREFERENCE, + "x25519", HRR }, +#endif }; static void server_response_check_cb(int write_p, int version, @@ -318,10 +340,12 @@ static void server_response_check_cb(int write_p, int version, enum SERVER_RESPONSE *server_response = (enum SERVER_RESPONSE *)arg; /* Prepare check for HRR */ const uint8_t *incoming_random = (uint8_t *)buf + 6; - const uint8_t magic_HRR_random[32] = { 0xCF, 0x21, 0xAD, 0x74, 0xE5, 0x9A, 0x61, 0x11, + const uint8_t magic_HRR_random[32] = { + 0xCF, 0x21, 0xAD, 0x74, 0xE5, 0x9A, 0x61, 0x11, 0xBE, 0x1D, 0x8C, 0x02, 0x1E, 0x65, 0xB8, 0x91, 0xC2, 0xA2, 0x11, 0x16, 0x7A, 0xBB, 0x8C, 0x5E, - 0x07, 0x9E, 0x09, 0xE2, 0xC8, 0xA8, 0x33, 0x9C }; + 0x07, 0x9E, 0x09, 0xE2, 0xC8, 0xA8, 0x33, 0x9C + }; /* Did a server hello arrive? */ if (write_p == 0 && /* Incoming data... */ @@ -450,13 +474,16 @@ static int test_groupnegotiation(const struct tls13groupselection_test_st *curre group_name_client = SSL_group_to_name(clientssl, negotiated_group_client); if (!TEST_int_eq(negotiated_group_client, negotiated_group_server)) goto end; - if (!TEST_int_eq((int)current_test_vector->expected_server_response, (int)server_response)) + if (!TEST_str_eq(response_desc[current_test_vector->expected_server_response], + response_desc[server_response])) goto end; if (TEST_str_eq(group_name_client, current_test_vector->expected_group)) ok = 1; } else { TEST_false_or_end(create_ssl_connection(serverssl, clientssl, SSL_ERROR_NONE)); - if (test_type == TEST_NEGOTIATION_FAILURE && !TEST_int_eq((int)current_test_vector->expected_server_response, (int)server_response)) + if (test_type == TEST_NEGOTIATION_FAILURE + && !TEST_str_eq(response_desc[current_test_vector->expected_server_response], + response_desc[server_response])) goto end; ok = 1; } |
