[openssl] master update
kaduk at mit.edu
kaduk at mit.edu
Wed May 12 16:37:43 UTC 2021
The branch master has been updated
via 80c25611abd7067815943187f36f5e1879201678 (commit)
via e776858bce32d473bd7a69c616ad7f6c2f979dfc (commit)
via f84ab284e91991a80191cf0e6d22ddc452043661 (commit)
via efe0f315354b020213097885c79ce856a2f5ac68 (commit)
from 8f965908a53b4f0c5a735739e8a273a3a33a976e (commit)
- Log -----------------------------------------------------------------
commit 80c25611abd7067815943187f36f5e1879201678
Author: Benjamin Kaduk <bkaduk at akamai.com>
Date: Mon Mar 29 23:05:22 2021 -0700
Update expected results for tls13kexmodes tests
One of the scenarios constructed in these tests was erroneously
producing successful handshakes until the previous commits, but should
have been failing. Update our expected behavior to match the
specification requirements, and adjust the commentary slightly for
a test case relevant for the other preceding commit.
Reviewed-by: Tomas Mraz <tomas at openssl.org>
(Merged from https://github.com/openssl/openssl/pull/14749)
commit e776858bce32d473bd7a69c616ad7f6c2f979dfc
Author: Benjamin Kaduk <bkaduk at akamai.com>
Date: Mon Mar 29 21:27:49 2021 -0700
Don't send key_share for PSK-only key exchange
TLS 1.3 allows for the "psk_ke" and "psk_dhe_ke" key-exchange modes.
Only the latter mode introduces a new ephemeral (Diffie-Hellman)
key exchange, with the PSK being the only key material used in the
former case.
It's a compliance requirement of RFC 8446 that the server MUST NOT
send a KeyShareEntry when using the "psk_ke" mode, but prior to
this commit we would send a key-share based solely on whether the
client sent one. This bug goes unnoticed in our internal test suite
since openssl communicating with openssl can never negotiate the
PSK-only key-exchange mode. However, we should still be compliant
with the spec, so check whether the DHE mode was offered and don't
send a key-share if it wasn't.
Reviewed-by: Tomas Mraz <tomas at openssl.org>
(Merged from https://github.com/openssl/openssl/pull/14749)
commit f84ab284e91991a80191cf0e6d22ddc452043661
Author: Benjamin Kaduk <bkaduk at akamai.com>
Date: Mon Mar 29 23:08:10 2021 -0700
make update
Reviewed-by: Tomas Mraz <tomas at openssl.org>
(Merged from https://github.com/openssl/openssl/pull/14749)
commit efe0f315354b020213097885c79ce856a2f5ac68
Author: Benjamin Kaduk <bkaduk at akamai.com>
Date: Mon Mar 29 23:03:49 2021 -0700
Improve RFC 8446 PSK key exchange mode compliance
It's a MUST-level requirement that if the client sends a pre_shared_key
extension not accompanied by a psk_key_exchange_modes extension, the
server must abort the handshake. Prior to this commit the server
would continue on.
Reviewed-by: Tomas Mraz <tomas at openssl.org>
(Merged from https://github.com/openssl/openssl/pull/14749)
-----------------------------------------------------------------------
Summary of changes:
crypto/err/openssl.txt | 1 +
include/openssl/sslerr.h | 1 +
ssl/ssl_err.c | 2 ++
ssl/statem/extensions.c | 19 ++++++++++++++++++-
ssl/statem/extensions_srvr.c | 7 +++++++
test/recipes/70-test_tls13kexmodes.t | 12 +++++-------
6 files changed, 34 insertions(+), 8 deletions(-)
diff --git a/crypto/err/openssl.txt b/crypto/err/openssl.txt
index 1391c00a17..9ad6757857 100644
--- a/crypto/err/openssl.txt
+++ b/crypto/err/openssl.txt
@@ -1361,6 +1361,7 @@ SSL_R_MISSING_DSA_SIGNING_CERT:165:missing dsa signing cert
SSL_R_MISSING_ECDSA_SIGNING_CERT:381:missing ecdsa signing cert
SSL_R_MISSING_FATAL:256:missing fatal
SSL_R_MISSING_PARAMETERS:290:missing parameters
+SSL_R_MISSING_PSK_KEX_MODES_EXTENSION:310:missing psk kex modes extension
SSL_R_MISSING_RSA_CERTIFICATE:168:missing rsa certificate
SSL_R_MISSING_RSA_ENCRYPTING_CERT:169:missing rsa encrypting cert
SSL_R_MISSING_RSA_SIGNING_CERT:170:missing rsa signing cert
diff --git a/include/openssl/sslerr.h b/include/openssl/sslerr.h
index 87aa4f0d00..a4746d70b5 100644
--- a/include/openssl/sslerr.h
+++ b/include/openssl/sslerr.h
@@ -159,6 +159,7 @@
# define SSL_R_MISSING_ECDSA_SIGNING_CERT 381
# define SSL_R_MISSING_FATAL 256
# define SSL_R_MISSING_PARAMETERS 290
+# define SSL_R_MISSING_PSK_KEX_MODES_EXTENSION 310
# define SSL_R_MISSING_RSA_CERTIFICATE 168
# define SSL_R_MISSING_RSA_ENCRYPTING_CERT 169
# define SSL_R_MISSING_RSA_SIGNING_CERT 170
diff --git a/ssl/ssl_err.c b/ssl/ssl_err.c
index c15a24f65f..595e9f5ed0 100644
--- a/ssl/ssl_err.c
+++ b/ssl/ssl_err.c
@@ -237,6 +237,8 @@ static const ERR_STRING_DATA SSL_str_reasons[] = {
"missing ecdsa signing cert"},
{ERR_PACK(ERR_LIB_SSL, 0, SSL_R_MISSING_FATAL), "missing fatal"},
{ERR_PACK(ERR_LIB_SSL, 0, SSL_R_MISSING_PARAMETERS), "missing parameters"},
+ {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_MISSING_PSK_KEX_MODES_EXTENSION),
+ "missing psk kex modes extension"},
{ERR_PACK(ERR_LIB_SSL, 0, SSL_R_MISSING_RSA_CERTIFICATE),
"missing rsa certificate"},
{ERR_PACK(ERR_LIB_SSL, 0, SSL_R_MISSING_RSA_ENCRYPTING_CERT),
diff --git a/ssl/statem/extensions.c b/ssl/statem/extensions.c
index 2f624c0e64..ee047dc638 100644
--- a/ssl/statem/extensions.c
+++ b/ssl/statem/extensions.c
@@ -57,6 +57,7 @@ static int final_sig_algs(SSL *s, unsigned int context, int sent);
static int final_early_data(SSL *s, unsigned int context, int sent);
static int final_maxfragmentlen(SSL *s, unsigned int context, int sent);
static int init_post_handshake_auth(SSL *s, unsigned int context);
+static int final_psk(SSL *s, unsigned int context, int sent);
/* Structure to define a built-in extension */
typedef struct extensions_definition_st {
@@ -381,7 +382,7 @@ static const EXTENSION_DEFINITION ext_defs[] = {
SSL_EXT_CLIENT_HELLO | SSL_EXT_TLS1_3_SERVER_HELLO
| SSL_EXT_TLS_IMPLEMENTATION_ONLY | SSL_EXT_TLS1_3_ONLY,
NULL, tls_parse_ctos_psk, tls_parse_stoc_psk, tls_construct_stoc_psk,
- tls_construct_ctos_psk, NULL
+ tls_construct_ctos_psk, final_psk
}
};
@@ -1676,3 +1677,19 @@ static int init_post_handshake_auth(SSL *s, ossl_unused unsigned int context)
return 1;
}
+
+/*
+ * If clients offer "pre_shared_key" without a "psk_key_exchange_modes"
+ * extension, servers MUST abort the handshake.
+ */
+static int final_psk(SSL *s, unsigned int context, int sent)
+{
+ if (s->server && sent && s->clienthello != NULL
+ && !s->clienthello->pre_proc_exts[TLSEXT_IDX_psk_kex_modes].present) {
+ SSLfatal(s, TLS13_AD_MISSING_EXTENSION,
+ SSL_R_MISSING_PSK_KEX_MODES_EXTENSION);
+ return 0;
+ }
+
+ return 1;
+}
diff --git a/ssl/statem/extensions_srvr.c b/ssl/statem/extensions_srvr.c
index 8462a67c1a..b2d7ff8f39 100644
--- a/ssl/statem/extensions_srvr.c
+++ b/ssl/statem/extensions_srvr.c
@@ -1614,6 +1614,13 @@ EXT_RETURN tls_construct_stoc_key_share(SSL *s, WPACKET *pkt,
}
return EXT_RETURN_NOT_SENT;
}
+ if (s->hit && (s->ext.psk_kex_mode & TLSEXT_KEX_MODE_FLAG_KE_DHE) == 0) {
+ /*
+ * PSK ('hit') and explicitly not doing DHE (if the client sent the
+ * DHE option we always take it); don't send key share.
+ */
+ return EXT_RETURN_NOT_SENT;
+ }
if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_key_share)
|| !WPACKET_start_sub_packet_u16(pkt)
diff --git a/test/recipes/70-test_tls13kexmodes.t b/test/recipes/70-test_tls13kexmodes.t
index 44f29055a2..6385885057 100644
--- a/test/recipes/70-test_tls13kexmodes.t
+++ b/test/recipes/70-test_tls13kexmodes.t
@@ -197,17 +197,14 @@ $proxy->start() or plan skip_all => "Unable to start up Proxy for tests";
plan tests => 11;
ok(TLSProxy::Message->success(), "Initial connection");
-#Test 2: Attempt a resume with no kex modes extension. Should not resume
+#Test 2: Attempt a resume with no kex modes extension. Should fail (server
+# MUST abort handshake with pre_shared key and no psk_kex_modes)
$proxy->clear();
$proxy->clientflags("-sess_in ".$session);
my $testtype = DELETE_EXTENSION;
$proxy->filter(\&modify_kex_modes_filter);
$proxy->start();
-checkhandshake($proxy, checkhandshake::DEFAULT_HANDSHAKE,
- checkhandshake::DEFAULT_EXTENSIONS
- | checkhandshake::KEY_SHARE_SRV_EXTENSION
- | checkhandshake::PSK_CLI_EXTENSION,
- "Resume with no kex modes");
+ok(TLSProxy::Message->fail(), "Resume with no kex modes");
#Test 3: Attempt a resume with empty kex modes extension. Should fail (empty
# extension is invalid)
@@ -245,6 +242,7 @@ checkhandshake($proxy, checkhandshake::RESUME_HANDSHAKE,
"Resume with non-dhe kex mode");
#Test 6: Attempt a resume with only unrecognised kex modes. Should not resume
+# but rather fall back to full handshake
$proxy->clear();
$proxy->clientflags("-sess_in ".$session);
$testtype = UNKNOWN_KEX_MODES;
@@ -254,7 +252,7 @@ checkhandshake($proxy, checkhandshake::DEFAULT_HANDSHAKE,
| checkhandshake::PSK_KEX_MODES_EXTENSION
| checkhandshake::KEY_SHARE_SRV_EXTENSION
| checkhandshake::PSK_CLI_EXTENSION,
- "Resume with empty kex modes");
+ "Resume with unrecognized kex mode");
#Test 7: Attempt a resume with both non-dhe and dhe kex mode. Should resume with
# a key_share
More information about the openssl-commits
mailing list