Send a missing_extension alert if key_share/supported groups not present
[openssl.git] / ssl / statem / extensions_srvr.c
index 22d2c4af2d52d037c797212c98e8f5ca834546d4..f85477c8f4488ebb6e0cdc8314090fec2e39cad2 100644 (file)
@@ -512,7 +512,7 @@ int tls_parse_ctos_key_share(SSL *s, PACKET *pkt, unsigned int context, X509 *x,
     }
 
     if (!PACKET_as_length_prefixed_2(pkt, &key_share_list)) {
-        *al = SSL_AD_HANDSHAKE_FAILURE;
+        *al = SSL_AD_DECODE_ERROR;
         SSLerr(SSL_F_TLS_PARSE_CTOS_KEY_SHARE, SSL_R_LENGTH_MISMATCH);
         return 0;
     }
@@ -524,22 +524,29 @@ int tls_parse_ctos_key_share(SSL *s, PACKET *pkt, unsigned int context, X509 *x,
         return 0;
     }
 
-    /*
-     * Get the clients list of supported curves.
-     * TODO(TLS1.3): We should validate that we actually received
-     * supported_groups!
-     */
+    /* Get the clients list of supported curves. */
     if (!tls1_get_curvelist(s, 1, &clntcurves, &clnt_num_curves)) {
         *al = SSL_AD_INTERNAL_ERROR;
         SSLerr(SSL_F_TLS_PARSE_CTOS_KEY_SHARE, ERR_R_INTERNAL_ERROR);
         return 0;
     }
+    if (clnt_num_curves == 0) {
+        /*
+         * This can only happen if the supported_groups extension was not sent,
+         * because we verify that the length is non-zero when we process that
+         * extension.
+         */
+        *al = SSL_AD_MISSING_EXTENSION;
+        SSLerr(SSL_F_TLS_PARSE_CTOS_KEY_SHARE,
+               SSL_R_MISSING_SUPPORTED_GROUPS_EXTENSION);
+        return 0;
+    }
 
     while (PACKET_remaining(&key_share_list) > 0) {
         if (!PACKET_get_net_2(&key_share_list, &group_id)
                 || !PACKET_get_length_prefixed_2(&key_share_list, &encoded_pt)
                 || PACKET_remaining(&encoded_pt) == 0) {
-            *al = SSL_AD_HANDSHAKE_FAILURE;
+            *al = SSL_AD_DECODE_ERROR;
             SSLerr(SSL_F_TLS_PARSE_CTOS_KEY_SHARE,
                    SSL_R_LENGTH_MISMATCH);
             return 0;
@@ -554,7 +561,7 @@ int tls_parse_ctos_key_share(SSL *s, PACKET *pkt, unsigned int context, X509 *x,
 
         /* Check if this share is in supported_groups sent from client */
         if (!check_in_list(s, group_id, clntcurves, clnt_num_curves, 0)) {
-            *al = SSL_AD_HANDSHAKE_FAILURE;
+            *al = SSL_AD_ILLEGAL_PARAMETER;
             SSLerr(SSL_F_TLS_PARSE_CTOS_KEY_SHARE, SSL_R_BAD_KEY_SHARE);
             return 0;
         }
@@ -868,6 +875,7 @@ int tls_construct_stoc_ec_pt_formats(SSL *s, WPACKET *pkt, unsigned int context,
 }
 #endif
 
+#ifndef OPENSSL_NO_EC
 int tls_construct_stoc_supported_groups(SSL *s, WPACKET *pkt,
                                         unsigned int context, X509 *x,
                                         size_t chainidx, int *al)
@@ -923,6 +931,7 @@ int tls_construct_stoc_supported_groups(SSL *s, WPACKET *pkt,
 
     return 1;
 }
+#endif
 
 int tls_construct_stoc_session_ticket(SSL *s, WPACKET *pkt,
                                       unsigned int context, X509 *x,