Implement server side of PSK extension construction

Reviewed-by: Rich Salz <rsalz@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/2259)
diff --git a/ssl/statem/extensions.c b/ssl/statem/extensions.c
index 95bfe75..c9e7d30 100644
--- a/ssl/statem/extensions.c
+++ b/ssl/statem/extensions.c
@@ -279,7 +279,7 @@
         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
     }
 };
diff --git a/ssl/statem/extensions_srvr.c b/ssl/statem/extensions_srvr.c
index 314cd5a..5a5d846 100644
--- a/ssl/statem/extensions_srvr.c
+++ b/ssl/statem/extensions_srvr.c
@@ -1006,12 +1006,14 @@
     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 @@
 
     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;
+}
diff --git a/ssl/statem/statem_locl.h b/ssl/statem/statem_locl.h
index 8079f30..cb6457f 100644
--- a/ssl/statem/statem_locl.h
+++ b/ssl/statem/statem_locl.h
@@ -247,6 +247,8 @@
 #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,