From ef93cf994dbde20556c77614e8ec7f3b586d48d9 Mon Sep 17 00:00:00 2001 From: Tomas Mraz Date: Fri, 5 Jun 2020 17:39:16 +0200 Subject: [PATCH] SHA1 is allowed in @SECLEVEL=2 only if allowed by TLS SigAlgs configuration Also some small TLS protocol fixes/changes: Disallow dropping Extended Master Secret extension on renegotiation Return alert from s_server if ALPN protocol does not match --- openssl-1.1.1-alpn-cb.patch | 27 ++++++ openssl-1.1.1-reneg-no-extms.patch | 44 ++++++++++ openssl-1.1.1-seclevel.patch | 133 ++++++++++++++++++++++++----- openssl.spec | 13 ++- 4 files changed, 197 insertions(+), 20 deletions(-) create mode 100644 openssl-1.1.1-alpn-cb.patch create mode 100644 openssl-1.1.1-reneg-no-extms.patch diff --git a/openssl-1.1.1-alpn-cb.patch b/openssl-1.1.1-alpn-cb.patch new file mode 100644 index 0000000..465f7b8 --- /dev/null +++ b/openssl-1.1.1-alpn-cb.patch @@ -0,0 +1,27 @@ +commit 9e885a707d604e9528b5491b78fb9c00f41193fc +Author: Tomas Mraz +Date: Thu Mar 26 15:59:00 2020 +0100 + + s_server: Properly indicate ALPN protocol mismatch + + Return SSL_TLSEXT_ERR_ALERT_FATAL from alpn_select_cb so that + an alert is sent to the client on ALPN protocol mismatch. + + Fixes: #2708 + + Reviewed-by: Matt Caswell + (Merged from https://github.com/openssl/openssl/pull/11415) + +diff --git a/apps/s_server.c b/apps/s_server.c +index bcc83e562c..591c6c19c5 100644 +--- a/apps/s_server.c ++++ b/apps/s_server.c +@@ -707,7 +707,7 @@ static int alpn_cb(SSL *s, const unsigned char **out, unsigned char *outlen, + if (SSL_select_next_proto + ((unsigned char **)out, outlen, alpn_ctx->data, alpn_ctx->len, in, + inlen) != OPENSSL_NPN_NEGOTIATED) { +- return SSL_TLSEXT_ERR_NOACK; ++ return SSL_TLSEXT_ERR_ALERT_FATAL; + } + + if (!s_quiet) { diff --git a/openssl-1.1.1-reneg-no-extms.patch b/openssl-1.1.1-reneg-no-extms.patch new file mode 100644 index 0000000..76adef7 --- /dev/null +++ b/openssl-1.1.1-reneg-no-extms.patch @@ -0,0 +1,44 @@ +diff -up openssl-1.1.1g/include/openssl/ssl3.h.reneg-no-extms openssl-1.1.1g/include/openssl/ssl3.h +--- openssl-1.1.1g/include/openssl/ssl3.h.reneg-no-extms 2020-04-21 14:22:39.000000000 +0200 ++++ openssl-1.1.1g/include/openssl/ssl3.h 2020-06-05 15:20:22.090682776 +0200 +@@ -292,6 +292,9 @@ extern "C" { + + # define TLS1_FLAGS_STATELESS 0x0800 + ++/* Set if extended master secret extension required on renegotiation */ ++# define TLS1_FLAGS_REQUIRED_EXTMS 0x1000 ++ + # define SSL3_MT_HELLO_REQUEST 0 + # define SSL3_MT_CLIENT_HELLO 1 + # define SSL3_MT_SERVER_HELLO 2 +diff -up openssl-1.1.1g/ssl/statem/extensions.c.reneg-no-extms openssl-1.1.1g/ssl/statem/extensions.c +--- openssl-1.1.1g/ssl/statem/extensions.c.reneg-no-extms 2020-04-21 14:22:39.000000000 +0200 ++++ openssl-1.1.1g/ssl/statem/extensions.c 2020-06-05 15:22:19.677653437 +0200 +@@ -1168,14 +1168,26 @@ static int init_etm(SSL *s, unsigned int + + static int init_ems(SSL *s, unsigned int context) + { +- if (!s->server) ++ if (s->s3->flags & TLS1_FLAGS_RECEIVED_EXTMS) { + s->s3->flags &= ~TLS1_FLAGS_RECEIVED_EXTMS; ++ s->s3->flags |= TLS1_FLAGS_REQUIRED_EXTMS; ++ } + + return 1; + } + + static int final_ems(SSL *s, unsigned int context, int sent) + { ++ /* ++ * Check extended master secret extension is not dropped on ++ * renegotiation. ++ */ ++ if (!(s->s3->flags & TLS1_FLAGS_RECEIVED_EXTMS) ++ && (s->s3->flags & TLS1_FLAGS_REQUIRED_EXTMS)) { ++ SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_F_FINAL_EMS, ++ SSL_R_INCONSISTENT_EXTMS); ++ return 0; ++ } + if (!s->server && s->hit) { + /* + * Check extended master secret extension is consistent with diff --git a/openssl-1.1.1-seclevel.patch b/openssl-1.1.1-seclevel.patch index fe6c6bb..c6751a5 100644 --- a/openssl-1.1.1-seclevel.patch +++ b/openssl-1.1.1-seclevel.patch @@ -1,7 +1,7 @@ -diff -up openssl-1.1.1/crypto/x509/x509_vfy.c.seclevel openssl-1.1.1/crypto/x509/x509_vfy.c ---- openssl-1.1.1/crypto/x509/x509_vfy.c.seclevel 2018-09-11 14:48:22.000000000 +0200 -+++ openssl-1.1.1/crypto/x509/x509_vfy.c 2018-10-01 09:52:23.535298908 +0200 -@@ -3220,6 +3220,7 @@ static int build_chain(X509_STORE_CTX *c +diff -up openssl-1.1.1g/crypto/x509/x509_vfy.c.seclevel openssl-1.1.1g/crypto/x509/x509_vfy.c +--- openssl-1.1.1g/crypto/x509/x509_vfy.c.seclevel 2020-04-21 14:22:39.000000000 +0200 ++++ openssl-1.1.1g/crypto/x509/x509_vfy.c 2020-06-05 17:16:54.835536823 +0200 +@@ -3225,6 +3225,7 @@ static int build_chain(X509_STORE_CTX *c } static const int minbits_table[] = { 80, 112, 128, 192, 256 }; @@ -9,20 +9,23 @@ diff -up openssl-1.1.1/crypto/x509/x509_vfy.c.seclevel openssl-1.1.1/crypto/x509 static const int NUM_AUTH_LEVELS = OSSL_NELEM(minbits_table); /* -@@ -3264,6 +3265,8 @@ static int check_sig_level(X509_STORE_CT +@@ -3276,6 +3277,11 @@ static int check_sig_level(X509_STORE_CT if (!X509_get_signature_info(cert, NULL, NULL, &secbits, NULL)) return 0; - - return secbits >= minbits_table[level - 1]; -+ /* Allow SHA1 in SECLEVEL 2 in non-FIPS mode */ -+ if (FIPS_mode()) ++ /* ++ * Allow SHA1 in SECLEVEL 2 in non-FIPS mode or when the magic ++ * disable SHA1 flag is not set. ++ */ ++ if ((ctx->param->flags & 0x40000000) || FIPS_mode()) + return secbits >= minbits_table[level - 1]; + return secbits >= minbits_digest_table[level - 1]; } -diff -up openssl-1.1.1/doc/man3/SSL_CTX_set_security_level.pod.seclevel openssl-1.1.1/doc/man3/SSL_CTX_set_security_level.pod ---- openssl-1.1.1/doc/man3/SSL_CTX_set_security_level.pod.seclevel 2018-09-11 14:48:22.000000000 +0200 -+++ openssl-1.1.1/doc/man3/SSL_CTX_set_security_level.pod 2018-10-01 09:52:23.535298908 +0200 +diff -up openssl-1.1.1g/doc/man3/SSL_CTX_set_security_level.pod.seclevel openssl-1.1.1g/doc/man3/SSL_CTX_set_security_level.pod +--- openssl-1.1.1g/doc/man3/SSL_CTX_set_security_level.pod.seclevel 2020-04-21 14:22:39.000000000 +0200 ++++ openssl-1.1.1g/doc/man3/SSL_CTX_set_security_level.pod 2020-06-04 15:48:01.608178833 +0200 @@ -81,8 +81,10 @@ using MD5 for the MAC is also prohibited =item B @@ -36,23 +39,115 @@ diff -up openssl-1.1.1/doc/man3/SSL_CTX_set_security_level.pod.seclevel openssl- In addition to the level 1 exclusions any cipher suite using RC4 is also prohibited. SSL version 3 is also not allowed. Compression is disabled. -diff -up openssl-1.1.1/ssl/ssl_cert.c.seclevel openssl-1.1.1/ssl/ssl_cert.c ---- openssl-1.1.1/ssl/ssl_cert.c.seclevel 2018-09-11 14:48:23.000000000 +0200 -+++ openssl-1.1.1/ssl/ssl_cert.c 2018-10-12 15:29:12.673799305 +0200 -@@ -983,6 +983,9 @@ static int ssl_security_default_callback +diff -up openssl-1.1.1g/ssl/ssl_cert.c.seclevel openssl-1.1.1g/ssl/ssl_cert.c +--- openssl-1.1.1g/ssl/ssl_cert.c.seclevel 2020-04-21 14:22:39.000000000 +0200 ++++ openssl-1.1.1g/ssl/ssl_cert.c 2020-06-05 17:10:11.842198401 +0200 +@@ -27,6 +27,7 @@ + static int ssl_security_default_callback(const SSL *s, const SSL_CTX *ctx, + int op, int bits, int nid, void *other, + void *ex); ++static unsigned long sha1_disable(const SSL *s, const SSL_CTX *ctx); + + static CRYPTO_ONCE ssl_x509_store_ctx_once = CRYPTO_ONCE_STATIC_INIT; + static volatile int ssl_x509_store_ctx_idx = -1; +@@ -396,7 +397,7 @@ int ssl_verify_cert_chain(SSL *s, STACK_ + X509_VERIFY_PARAM_set_auth_level(param, SSL_get_security_level(s)); + + /* Set suite B flags if needed */ +- X509_STORE_CTX_set_flags(ctx, tls1_suiteb(s)); ++ X509_STORE_CTX_set_flags(ctx, tls1_suiteb(s) | sha1_disable(s, NULL)); + if (!X509_STORE_CTX_set_ex_data + (ctx, SSL_get_ex_data_X509_STORE_CTX_idx(), s)) { + goto end; +@@ -953,12 +954,33 @@ static int ssl_security_default_callback return 0; break; default: + /* allow SHA1 in SECLEVEL 2 in non FIPS mode */ -+ if (nid == NID_sha1 && minbits == 112 && !FIPS_mode()) ++ if (nid == NID_sha1 && minbits == 112 && !sha1_disable(s, ctx)) + break; if (bits < minbits) return 0; } -diff -up openssl-1.1.1/test/recipes/25-test_verify.t.seclevel openssl-1.1.1/test/recipes/25-test_verify.t ---- openssl-1.1.1/test/recipes/25-test_verify.t.seclevel 2018-09-11 14:48:24.000000000 +0200 -+++ openssl-1.1.1/test/recipes/25-test_verify.t 2018-10-01 09:52:23.535298908 +0200 -@@ -342,8 +342,8 @@ ok(verify("ee-pss-sha1-cert", "sslserver + return 1; + } + ++static unsigned long sha1_disable(const SSL *s, const SSL_CTX *ctx) ++{ ++ unsigned long ret = 0x40000000; /* a magical internal value used by X509_VERIFY_PARAM */ ++ const CERT *c; ++ ++ if (FIPS_mode()) ++ return ret; ++ ++ if (ctx != NULL) { ++ c = ctx->cert; ++ } else { ++ c = s->cert; ++ } ++ if (tls1_cert_sigalgs_have_sha1(c)) ++ return 0; ++ return ret; ++} ++ + int ssl_security(const SSL *s, int op, int bits, int nid, void *other) + { + return s->cert->sec_cb(s, NULL, op, bits, nid, other, s->cert->sec_ex); +diff -up openssl-1.1.1g/ssl/ssl_local.h.seclevel openssl-1.1.1g/ssl/ssl_local.h +--- openssl-1.1.1g/ssl/ssl_local.h.seclevel 2020-06-04 15:48:01.602178783 +0200 ++++ openssl-1.1.1g/ssl/ssl_local.h 2020-06-05 17:02:22.666313410 +0200 +@@ -2576,6 +2576,7 @@ __owur int tls1_save_sigalgs(SSL *s, PAC + __owur int tls1_process_sigalgs(SSL *s); + __owur int tls1_set_peer_legacy_sigalg(SSL *s, const EVP_PKEY *pkey); + __owur int tls1_lookup_md(const SIGALG_LOOKUP *lu, const EVP_MD **pmd); ++int tls1_cert_sigalgs_have_sha1(const CERT *c); + __owur size_t tls12_get_psigalgs(SSL *s, int sent, const uint16_t **psigs); + # ifndef OPENSSL_NO_EC + __owur int tls_check_sigalg_curve(const SSL *s, int curve); +diff -up openssl-1.1.1g/ssl/t1_lib.c.seclevel openssl-1.1.1g/ssl/t1_lib.c +--- openssl-1.1.1g/ssl/t1_lib.c.seclevel 2020-06-04 15:48:01.654179221 +0200 ++++ openssl-1.1.1g/ssl/t1_lib.c 2020-06-05 17:02:40.268459157 +0200 +@@ -2145,6 +2145,36 @@ int tls1_set_sigalgs(CERT *c, const int + return 0; + } + ++static int tls1_sigalgs_have_sha1(const uint16_t *sigalgs, size_t sigalgslen) ++{ ++ size_t i; ++ ++ for (i = 0; i < sigalgslen; i++, sigalgs++) { ++ const SIGALG_LOOKUP *lu = tls1_lookup_sigalg(*sigalgs); ++ ++ if (lu == NULL) ++ continue; ++ if (lu->hash == NID_sha1) ++ return 1; ++ } ++ return 0; ++} ++ ++ ++int tls1_cert_sigalgs_have_sha1(const CERT *c) ++{ ++ if (c->client_sigalgs != NULL) { ++ if (tls1_sigalgs_have_sha1(c->client_sigalgs, c->client_sigalgslen)) ++ return 1; ++ } ++ if (c->conf_sigalgs != NULL) { ++ if (tls1_sigalgs_have_sha1(c->conf_sigalgs, c->conf_sigalgslen)) ++ return 1; ++ return 0; ++ } ++ return 1; ++} ++ + static int tls1_check_sig_alg(SSL *s, X509 *x, int default_nid) + { + int sig_nid, use_pc_sigalgs = 0; +diff -up openssl-1.1.1g/test/recipes/25-test_verify.t.seclevel openssl-1.1.1g/test/recipes/25-test_verify.t +--- openssl-1.1.1g/test/recipes/25-test_verify.t.seclevel 2020-04-21 14:22:39.000000000 +0200 ++++ openssl-1.1.1g/test/recipes/25-test_verify.t 2020-06-04 15:48:01.608178833 +0200 +@@ -346,8 +346,8 @@ ok(verify("ee-pss-sha1-cert", "sslserver ok(verify("ee-pss-sha256-cert", "sslserver", ["root-cert"], ["ca-cert"], ), "CA with PSS signature using SHA256"); diff --git a/openssl.spec b/openssl.spec index 3984ecf..d4111ad 100644 --- a/openssl.spec +++ b/openssl.spec @@ -22,7 +22,7 @@ Summary: Utilities from the general purpose cryptography library with TLS implementation Name: openssl Version: 1.1.1g -Release: 8%{?dist} +Release: 9%{?dist} Epoch: 1 # We have to remove certain patented algorithms from the openssl source # tarball with the hobble-openssl script which is included below. @@ -69,6 +69,8 @@ Patch62: openssl-1.1.1-fips-curves.patch Patch65: openssl-1.1.1-fips-drbg-selftest.patch Patch66: openssl-1.1.1-fips-dh.patch Patch67: openssl-1.1.1-kdf-selftest.patch +Patch68: openssl-1.1.1-reneg-no-extms.patch +Patch69: openssl-1.1.1-alpn-cb.patch # Backported fixes including security fixes Patch52: openssl-1.1.1-s390x-update.patch Patch53: openssl-1.1.1-fips-crng-test.patch @@ -183,6 +185,8 @@ cp %{SOURCE13} test/ %patch65 -p1 -b .drbg-selftest %patch66 -p1 -b .fips-dh %patch67 -p1 -b .kdf-selftest +%patch68 -p1 -b .reneg-no-extms +%patch69 -p1 -b .alpn-cb %build @@ -469,6 +473,13 @@ export LD_LIBRARY_PATH %ldconfig_scriptlets libs %changelog +* Fri Jun 5 2020 Tomáš Mráz 1.1.1g-9 +- Disallow dropping Extended Master Secret extension + on renegotiation +- Return alert from s_server if ALPN protocol does not match +- SHA1 is allowed in @SECLEVEL=2 only if allowed by + TLS SigAlgs configuration + * Wed Jun 3 2020 Tomáš Mráz 1.1.1g-8 - Add FIPS selftest for PBKDF2 and KBKDF