Add key_share info to the ServerHello
authorMatt Caswell <matt@openssl.org>
Tue, 1 Nov 2016 13:24:02 +0000 (13:24 +0000)
committerMatt Caswell <matt@openssl.org>
Wed, 16 Nov 2016 10:09:46 +0000 (10:09 +0000)
Reviewed-by: Rich Salz <rsalz@openssl.org>
ssl/ssl_locl.h
ssl/t1_lib.c

index 105a487c7e05793522520d8a4795cb11a2a1d251..ec0d0b48248d5355eeebf714f72ba3e2e55fe96a 100644 (file)
@@ -1299,6 +1299,8 @@ typedef struct ssl3_state_st {
 
     /* For clients: peer temporary key */
 # if !defined(OPENSSL_NO_EC) || !defined(OPENSSL_NO_DH)
+    /* The group_id for the DH/ECDH key */
+    unsigned int group_id;
     EVP_PKEY *peer_tmp;
 # endif
 
index 37e6841d7e7c05b935cb092633bbb83fefb648d9..11c8399a2830cae0a796079b7268d90fefad3f55 100644 (file)
@@ -1648,6 +1648,47 @@ int ssl_add_serverhello_tlsext(SSL *s, WPACKET *pkt, int *al)
         }
     }
 #endif
+
+    if (s->version == TLS1_3_VERSION) {
+        unsigned char *encodedPoint;
+        size_t encoded_pt_len = 0;
+        EVP_PKEY *ckey = NULL, *skey = NULL;
+
+        ckey = s->s3->peer_tmp;
+        if (ckey == NULL) {
+            SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
+            return 0;
+        }
+
+        if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_key_share)
+                || !WPACKET_start_sub_packet_u16(pkt)
+                || !WPACKET_put_bytes_u16(pkt, s->s3->group_id)) {
+            SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
+            return 0;
+        }
+
+        skey = ssl_generate_pkey(ckey);
+
+        /* Generate encoding of server key */
+        encoded_pt_len = EVP_PKEY_get1_tls_encodedpoint(skey, &encodedPoint);
+        if (encoded_pt_len == 0) {
+            SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_EC_LIB);
+            EVP_PKEY_free(skey);
+            return 0;
+        }
+
+        if (!WPACKET_sub_memcpy_u16(pkt, encodedPoint, encoded_pt_len)
+                || !WPACKET_close(pkt)) {
+            SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
+            EVP_PKEY_free(skey);
+            OPENSSL_free(encodedPoint);
+            return 0;
+        }
+
+        s->s3->tmp.pkey = skey;
+        OPENSSL_free(encodedPoint);
+    }
+
     if (!custom_ext_add(s, 1, pkt, al)) {
         SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
         return 0;
@@ -2293,6 +2334,7 @@ static int ssl_scan_clienthello_tlsext(SSL *s, CLIENTHELLO_MSG *hello, int *al)
                     EVP_PKEY_CTX_free(pctx);
                     pctx = NULL;
                 }
+                s->s3->group_id = group_id;
 
                 if (!EVP_PKEY_set1_tls_encodedpoint(s->s3->peer_tmp,
                         PACKET_data(&encoded_pt),