Implement server side of PSK extension construction
authorMatt Caswell <matt@openssl.org>
Wed, 18 Jan 2017 17:22:18 +0000 (17:22 +0000)
committerMatt Caswell <matt@openssl.org>
Mon, 30 Jan 2017 10:18:21 +0000 (10:18 +0000)
Reviewed-by: Rich Salz <rsalz@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/2259)

include/openssl/ssl.h
ssl/s3_lib.c
ssl/ssl_err.c
ssl/statem/extensions.c
ssl/statem/extensions_srvr.c
ssl/statem/statem_locl.h

index af8878c..e8f351d 100644 (file)
@@ -2315,6 +2315,7 @@ int ERR_load_SSL_strings(void);
 # define SSL_F_TLS_CONSTRUCT_STOC_KEY_EXCHANGE            377
 # define SSL_F_TLS_CONSTRUCT_STOC_KEY_SHARE               456
 # define SSL_F_TLS_CONSTRUCT_STOC_NEXT_PROTO_NEG          457
+# define SSL_F_TLS_CONSTRUCT_STOC_PSK                     504
 # define SSL_F_TLS_CONSTRUCT_STOC_RENEGOTIATE             458
 # define SSL_F_TLS_CONSTRUCT_STOC_SERVER_NAME             459
 # define SSL_F_TLS_CONSTRUCT_STOC_SESSION_TICKET          460
index 6c74bd1..35684f4 100644 (file)
@@ -4113,6 +4113,9 @@ int ssl_derive(SSL *s, EVP_PKEY *privkey, EVP_PKEY *pubkey, int gensecret)
                 rv = tls13_generate_secret(s, ssl_handshake_md(s), NULL, NULL,
                                            0,
                                            (unsigned char *)&s->early_secret);
+            else
+                rv = 1;
+
             rv = rv && tls13_generate_handshake_secret(s, pms, pmslen);
         } else {
             /* Generate master secret and discard premaster */
index 4047d0e..589cfa2 100644 (file)
@@ -355,6 +355,7 @@ static ERR_STRING_DATA SSL_str_functs[] = {
      "tls_construct_stoc_key_share"},
     {ERR_FUNC(SSL_F_TLS_CONSTRUCT_STOC_NEXT_PROTO_NEG),
      "tls_construct_stoc_next_proto_neg"},
+    {ERR_FUNC(SSL_F_TLS_CONSTRUCT_STOC_PSK), "tls_construct_stoc_psk"},
     {ERR_FUNC(SSL_F_TLS_CONSTRUCT_STOC_RENEGOTIATE),
      "tls_construct_stoc_renegotiate"},
     {ERR_FUNC(SSL_F_TLS_CONSTRUCT_STOC_SERVER_NAME),
index 95bfe75..c9e7d30 100644 (file)
@@ -279,7 +279,7 @@ static const EXTENSION_DEFINITION ext_defs[] = {
         TLSEXT_TYPE_psk,
         EXT_CLIENT_HELLO | EXT_TLS1_3_SERVER_HELLO | EXT_TLS_IMPLEMENTATION_ONLY
         | EXT_TLS1_3_ONLY,
-        NULL, tls_parse_ctos_psk, tls_parse_stoc_psk, NULL,
+        NULL, tls_parse_ctos_psk, tls_parse_stoc_psk, tls_construct_stoc_psk,
         tls_construct_ctos_psk, NULL
     }
 };
index 314cd5a..5a5d846 100644 (file)
@@ -1006,12 +1006,14 @@ int tls_construct_stoc_key_share(SSL *s, WPACKET *pkt, X509 *x, size_t chainidx,
     size_t encoded_pt_len = 0;
     EVP_PKEY *ckey = s->s3->peer_tmp, *skey = NULL;
 
-    if (s->hit)
-        return 1;
-
     if (ckey == NULL) {
-        SSLerr(SSL_F_TLS_CONSTRUCT_STOC_KEY_SHARE, ERR_R_INTERNAL_ERROR);
-        return 0;
+        /* No key_share received from client, must be resuming. */
+        if (!s->hit || !tls13_generate_handshake_secret(s, NULL, 0)) {
+            *al = SSL_AD_INTERNAL_ERROR;
+            SSLerr(SSL_F_TLS_CONSTRUCT_STOC_KEY_SHARE, ERR_R_INTERNAL_ERROR);
+            return 0;
+        }
+        return 1;
     }
 
     if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_key_share)
@@ -1079,3 +1081,20 @@ int tls_construct_stoc_cryptopro_bug(SSL *s, WPACKET *pkt, X509 *x,
 
     return 1;
 }
+
+int tls_construct_stoc_psk(SSL *s, WPACKET *pkt, X509 *x, size_t chainidx,
+                           int *al)
+{
+    if (!s->hit)
+        return 1;
+
+    if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_psk)
+            || !WPACKET_start_sub_packet_u16(pkt)
+            || !WPACKET_put_bytes_u16(pkt, s->session->ext.tick_identity)
+            || !WPACKET_close(pkt)) {
+        SSLerr(SSL_F_TLS_CONSTRUCT_STOC_PSK, ERR_R_INTERNAL_ERROR);
+        return 0;
+    }
+
+    return 1;
+}
index 8079f30..cb6457f 100644 (file)
@@ -247,6 +247,8 @@ int tls_construct_stoc_key_share(SSL *s, WPACKET *pkt, X509 *x, size_t chainidx,
 #define TLSEXT_TYPE_cryptopro_bug      0xfde8
 int tls_construct_stoc_cryptopro_bug(SSL *s, WPACKET *pkt, X509 *x,
                                      size_t chainidx, int *al);
+int tls_construct_stoc_psk(SSL *s, WPACKET *pkt, X509 *x, size_t chainidx,
+                           int *al);
 
 /* Client Extension processing */
 int tls_construct_ctos_renegotiate(SSL *s, WPACKET *pkt, X509 *x,