Send the supported_groups extension in EE where applicable
[openssl.git] / ssl / statem / statem_lib.c
index 849310ea75ffad4846a80d04d46f6db348de888e..33206c6ea96c9e7f2bf8e5e4fe56b5d91e3f9d32 100644 (file)
@@ -78,6 +78,39 @@ int tls_setup_handshake(SSL *s)
         return 0;
 
     if (s->server) {
+        STACK_OF(SSL_CIPHER) *ciphers = SSL_get_ciphers(s);
+        int i, ver_min, ver_max, ok = 0;
+
+        /*
+         * Sanity check that the maximum version we accept has ciphers
+         * enabled. For clients we do this check during construction of the
+         * ClientHello.
+         */
+        if (ssl_get_min_max_version(s, &ver_min, &ver_max) != 0) {
+            SSLerr(SSL_F_TLS_SETUP_HANDSHAKE, ERR_R_INTERNAL_ERROR);
+            ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
+            return 0;
+        }
+        for (i = 0; i < sk_SSL_CIPHER_num(ciphers); i++) {
+            const SSL_CIPHER *c = sk_SSL_CIPHER_value(ciphers, i);
+
+            if (SSL_IS_DTLS(s)) {
+                if (DTLS_VERSION_GE(ver_max, c->min_dtls) &&
+                        DTLS_VERSION_LE(ver_max, c->max_dtls))
+                    ok = 1;
+            } else if (ver_max >= c->min_tls && ver_max <= c->max_tls) {
+                ok = 1;
+            }
+            if (ok)
+                break;
+        }
+        if (!ok) {
+            SSLerr(SSL_F_TLS_SETUP_HANDSHAKE, SSL_R_NO_CIPHERS_AVAILABLE);
+            ERR_add_error_data(1, "No ciphers enabled for max supported "
+                                  "SSL/TLS version");
+            ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
+            return 0;
+        }
         if (SSL_IS_FIRST_HANDSHAKE(s)) {
             s->ctx->stats.sess_accept++;
         } else if (!s->s3->send_connection_binding &&
@@ -281,7 +314,7 @@ MSG_PROCESS_RETURN tls_process_cert_verify(SSL *s, PACKET *pkt)
     unsigned char *gost_data = NULL;
 #endif
     int al = SSL_AD_INTERNAL_ERROR, ret = MSG_PROCESS_ERROR;
-    int type = 0, j, pktype;
+    int type = 0, j;
     unsigned int len;
     X509 *peer;
     const EVP_MD *md = NULL;
@@ -303,7 +336,6 @@ MSG_PROCESS_RETURN tls_process_cert_verify(SSL *s, PACKET *pkt)
         goto f_err;
     }
 
-    pktype = EVP_PKEY_id(pkey);
     type = X509_certificate_type(peer, pkey);
 
     if (!(type & EVP_PKT_SIGN)) {
@@ -384,6 +416,7 @@ MSG_PROCESS_RETURN tls_process_cert_verify(SSL *s, PACKET *pkt)
     }
 #ifndef OPENSSL_NO_GOST
     {
+        int pktype = EVP_PKEY_id(pkey);
         if (pktype == NID_id_GostR3410_2001
             || pktype == NID_id_GostR3410_2012_256
             || pktype == NID_id_GostR3410_2012_512) {
@@ -418,10 +451,7 @@ MSG_PROCESS_RETURN tls_process_cert_verify(SSL *s, PACKET *pkt)
         goto f_err;
     }
 
-    if (SSL_IS_TLS13(s))
-        ret = MSG_PROCESS_CONTINUE_READING;
-    else
-        ret = MSG_PROCESS_CONTINUE_PROCESSING;
+    ret = MSG_PROCESS_CONTINUE_READING;
     if (0) {
  f_err:
         ssl3_send_alert(s, SSL3_AL_FATAL, al);
@@ -801,7 +831,7 @@ static int ssl_add_cert_to_wpacket(SSL *s, WPACKET *pkt, X509 *x, int chain,
     }
 
     if (SSL_IS_TLS13(s)
-            && !tls_construct_extensions(s, pkt, EXT_TLS1_3_CERTIFICATE, x,
+            && !tls_construct_extensions(s, pkt, SSL_EXT_TLS1_3_CERTIFICATE, x,
                                          chain, al))
         return 0;
 
@@ -1295,6 +1325,7 @@ typedef struct {
 # error Code needs update for TLS_method() support beyond TLS1_3_VERSION.
 #endif
 
+/* Must be in order high to low */
 static const version_info tls_version_table[] = {
 #ifndef OPENSSL_NO_TLS1_3
     {TLS1_3_VERSION, tlsv1_3_client_method, tlsv1_3_server_method},
@@ -1328,6 +1359,7 @@ static const version_info tls_version_table[] = {
 # error Code needs update for DTLS_method() support beyond DTLS1_2_VERSION.
 #endif
 
+/* Must be in order high to low */
 static const version_info dtls_version_table[] = {
 #ifndef OPENSSL_NO_DTLS1_2
     {DTLS1_2_VERSION, dtlsv1_2_client_method, dtlsv1_2_server_method},
@@ -1510,6 +1542,20 @@ int ssl_set_version_bound(int method_version, int version, int *bound)
     return 1;
 }
 
+static void check_for_downgrade(SSL *s, int vers, DOWNGRADE *dgrd)
+{
+    if (vers == TLS1_2_VERSION
+            && ssl_version_supported(s, TLS1_3_VERSION)) {
+        *dgrd = DOWNGRADE_TO_1_2;
+    } else if (!SSL_IS_DTLS(s) && vers < TLS1_2_VERSION
+            && (ssl_version_supported(s, TLS1_2_VERSION)
+                || ssl_version_supported(s, TLS1_3_VERSION))) {
+        *dgrd = DOWNGRADE_TO_1_1;
+    } else {
+        *dgrd = DOWNGRADE_NONE;
+    }
+}
+
 /*
  * ssl_choose_server_version - Choose server (D)TLS version.  Called when the
  * client HELLO is received to select the final server protocol version and
@@ -1519,7 +1565,7 @@ int ssl_set_version_bound(int method_version, int version, int *bound)
  *
  * Returns 0 on success or an SSL error reason number on failure.
  */
-int ssl_choose_server_version(SSL *s, CLIENTHELLO_MSG *hello)
+int ssl_choose_server_version(SSL *s, CLIENTHELLO_MSG *hello, DOWNGRADE *dgrd)
 {
     /*-
      * With version-flexible methods we have an initial state with:
@@ -1544,6 +1590,7 @@ int ssl_choose_server_version(SSL *s, CLIENTHELLO_MSG *hello)
         if (!SSL_IS_TLS13(s)) {
             if (version_cmp(s, client_version, s->version) < 0)
                 return SSL_R_WRONG_SSL_VERSION;
+            *dgrd = DOWNGRADE_NONE;
             /*
              * If this SSL handle is not from a version flexible method we don't
              * (and never did) check min/max FIPS or Suite B constraints.  Hope
@@ -1586,7 +1633,7 @@ int ssl_choose_server_version(SSL *s, CLIENTHELLO_MSG *hello)
                 candidate_vers = TLS1_3_VERSION;
             /*
              * TODO(TLS1.3): There is some discussion on the TLS list about
-             * wheter to ignore versions <TLS1.2 in supported_versions. At the
+             * whether to ignore versions <TLS1.2 in supported_versions. At the
              * moment we honour them if present. To be reviewed later
              */
             if (version_cmp(s, candidate_vers, best_vers) <= 0)
@@ -1620,6 +1667,7 @@ int ssl_choose_server_version(SSL *s, CLIENTHELLO_MSG *hello)
                     return SSL_R_UNSUPPORTED_PROTOCOL;
                 return 0;
             }
+            check_for_downgrade(s, best_vers, dgrd);
             s->version = best_vers;
             s->method = best_method;
             return 0;
@@ -1646,6 +1694,7 @@ int ssl_choose_server_version(SSL *s, CLIENTHELLO_MSG *hello)
             continue;
         method = vent->smeth();
         if (ssl_method_error(s, method) == 0) {
+            check_for_downgrade(s, vent->version, dgrd);
             s->version = vent->version;
             s->method = method;
             return 0;
@@ -1662,22 +1711,32 @@ int ssl_choose_server_version(SSL *s, CLIENTHELLO_MSG *hello)
  *
  * @s: client SSL handle.
  * @version: The proposed version from the server's HELLO.
+ * @checkdgrd: Whether to check the downgrade sentinels in the server_random
+ * @al: Where to store any alert value that may be generated
  *
  * Returns 0 on success or an SSL error reason number on failure.
  */
-int ssl_choose_client_version(SSL *s, int version)
+int ssl_choose_client_version(SSL *s, int version, int checkdgrd, int *al)
 {
     const version_info *vent;
     const version_info *table;
+    int highver = 0;
 
     /* TODO(TLS1.3): Remove this before release */
     if (version == TLS1_3_VERSION_DRAFT)
         version = TLS1_3_VERSION;
 
+    if (s->hello_retry_request && version != TLS1_3_VERSION) {
+        *al = SSL_AD_PROTOCOL_VERSION;
+        return SSL_R_WRONG_SSL_VERSION;
+    }
+
     switch (s->method->version) {
     default:
-        if (version != s->version)
+        if (version != s->version) {
+            *al = SSL_AD_PROTOCOL_VERSION;
             return SSL_R_WRONG_SSL_VERSION;
+        }
         /*
          * If this SSL handle is not from a version flexible method we don't
          * (and never did) check min/max, FIPS or Suite B constraints.  Hope
@@ -1698,27 +1757,64 @@ int ssl_choose_client_version(SSL *s, int version)
         const SSL_METHOD *method;
         int err;
 
-        if (version != vent->version)
-            continue;
         if (vent->cmeth == NULL)
-            break;
-        if (s->hello_retry_request && version != TLS1_3_VERSION)
-            return SSL_R_WRONG_SSL_VERSION;
+            continue;
+
+        if (highver != 0 && version != vent->version)
+            continue;
 
         method = vent->cmeth();
         err = ssl_method_error(s, method);
-        if (err != 0)
-            return err;
+        if (err != 0) {
+            if (version == vent->version) {
+                *al = SSL_AD_PROTOCOL_VERSION;
+                return err;
+            }
+
+            continue;
+        }
+        if (highver == 0)
+            highver = vent->version;
+
+        if (version != vent->version)
+            continue;
+
+#ifndef OPENSSL_NO_TLS13DOWNGRADE
+        /* Check for downgrades */
+        if (checkdgrd) {
+            if (version == TLS1_2_VERSION && highver > version) {
+                if (memcmp(tls12downgrade,
+                           s->s3->server_random + SSL3_RANDOM_SIZE
+                                                - sizeof(tls12downgrade),
+                           sizeof(tls12downgrade)) == 0) {
+                    *al = SSL_AD_ILLEGAL_PARAMETER;
+                    return SSL_R_INAPPROPRIATE_FALLBACK;
+                }
+            } else if (!SSL_IS_DTLS(s)
+                       && version < TLS1_2_VERSION
+                       && highver > version) {
+                if (memcmp(tls11downgrade,
+                           s->s3->server_random + SSL3_RANDOM_SIZE
+                                                - sizeof(tls11downgrade),
+                           sizeof(tls11downgrade)) == 0) {
+                    *al = SSL_AD_ILLEGAL_PARAMETER;
+                    return SSL_R_INAPPROPRIATE_FALLBACK;
+                }
+            }
+        }
+#endif
+
         s->method = method;
         s->version = version;
         return 0;
     }
 
+    *al = SSL_AD_PROTOCOL_VERSION;
     return SSL_R_UNSUPPORTED_PROTOCOL;
 }
 
 /*
- * ssl_get_client_min_max_version - get minimum and maximum client version
+ * ssl_get_min_max_version - get minimum and maximum protocol version
  * @s: The SSL connection
  * @min_version: The minimum supported version
  * @max_version: The maximum supported version
@@ -1736,8 +1832,7 @@ int ssl_choose_client_version(SSL *s, int version)
  * Returns 0 on success or an SSL error reason number on failure.  On failure
  * min_version and max_version will also be set to 0.
  */
-int ssl_get_client_min_max_version(const SSL *s, int *min_version,
-                                   int *max_version)
+int ssl_get_min_max_version(const SSL *s, int *min_version, int *max_version)
 {
     int version;
     int hole;
@@ -1831,7 +1926,7 @@ int ssl_set_client_hello_version(SSL *s)
 {
     int ver_min, ver_max, ret;
 
-    ret = ssl_get_client_min_max_version(s, &ver_min, &ver_max);
+    ret = ssl_get_min_max_version(s, &ver_min, &ver_max);
 
     if (ret != 0)
         return ret;
@@ -1862,17 +1957,14 @@ int check_in_list(SSL *s, unsigned int group_id, const unsigned char *groups,
         return 0;
 
     for (i = 0; i < num_groups; i++, groups += 2) {
-        unsigned int share_id = (groups[0] << 8) | (groups[1]);
-
-        if (group_id == share_id
+        if (group_id == GET_GROUP_ID(groups, 0)
                 && (!checkallow
                     || tls_curve_allowed(s, groups, SSL_SECOP_CURVE_CHECK))) {
-            break;
+            return 1;
         }
     }
 
-    /* If i == num_groups then not in the list */
-    return i < num_groups;
+    return 0;
 }
 #endif
 
@@ -1958,8 +2050,8 @@ int parse_ca_names(SSL *s, PACKET *pkt, int *al)
         xn = NULL;
     }
 
-    sk_X509_NAME_pop_free(s->s3->tmp.ca_names, X509_NAME_free);
-    s->s3->tmp.ca_names = ca_sk;
+    sk_X509_NAME_pop_free(s->s3->tmp.peer_ca_names, X509_NAME_free);
+    s->s3->tmp.peer_ca_names = ca_sk;
 
     return 1;
 
@@ -1973,7 +2065,7 @@ int parse_ca_names(SSL *s, PACKET *pkt, int *al)
 
 int construct_ca_names(SSL *s, WPACKET *pkt)
 {
-    STACK_OF(X509_NAME) *ca_sk = SSL_get_client_CA_list(s);
+    const STACK_OF(X509_NAME) *ca_sk = SSL_get0_CA_list(s);
 
     /* Start sub-packet for client CA list */
     if (!WPACKET_start_sub_packet_u16(pkt))