Improve RFC 8446 PSK key exchange mode compliance
authorBenjamin Kaduk <bkaduk@akamai.com>
Tue, 30 Mar 2021 06:03:49 +0000 (23:03 -0700)
committerBenjamin Kaduk <bkaduk@akamai.com>
Fri, 14 May 2021 18:40:21 +0000 (11:40 -0700)
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@openssl.org>
(cherry picked from commit efe0f315354b020213097885c79ce856a2f5ac68)

(Merged from https://github.com/openssl/openssl/pull/15255)

ssl/statem/extensions.c

index e1a3b1db67a102b6d93c2bf23dad68ef97641bbb..07803537bae9f5d1e96c957b66a7fc58004cdde5 100644 (file)
@@ -56,6 +56,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 {
@@ -389,7 +390,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
     }
 };
 
@@ -1718,3 +1719,19 @@ static int init_post_handshake_auth(SSL *s, 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_F_FINAL_PSK,
+                 SSL_R_MISSING_PSK_KEX_MODES_EXTENSION);
+        return 0;
+    }
+
+    return 1;
+}