[PR3597] Advance to the next state variant when reusing messages.
[openssl.git] / ssl / t1_lib.c
index 0c0d6428dff3fefed1baf7e3d3aef804eb536a5f..e0f28d254ba2be11a0b5fae220ff70bee7c2cb31 100644 (file)
@@ -312,7 +312,7 @@ static const unsigned char suiteb_curves[] =
 
 int tls1_ec_curve_id2nid(int curve_id)
        {
-       /* ECC curves from RFC 4492 */
+       /* ECC curves from RFC 4492 and RFC 7027 */
        if ((curve_id < 1) || ((unsigned int)curve_id >
                                sizeof(nid_list)/sizeof(nid_list[0])))
                return 0;
@@ -321,7 +321,7 @@ int tls1_ec_curve_id2nid(int curve_id)
 
 int tls1_ec_nid2curve_id(int nid)
        {
-       /* ECC curves from RFC 4492 */
+       /* ECC curves from RFC 4492 and RFC 7027 */
        switch (nid)
                {
        case NID_sect163k1: /* sect163k1 (1) */
@@ -435,6 +435,10 @@ static int tls_curve_allowed(SSL *s, const unsigned char *curve, int op)
                                sizeof(nid_list)/sizeof(nid_list[0])))
                return 0;
        cinfo = &nid_list[curve[1]-1];
+#ifdef OPENSSL_NO_EC2M
+       if (cinfo->flags & TLS_CURVE_CHAR2)
+               return 0;
+#endif
        return ssl_security(s, op, cinfo->secbits, cinfo->nid, (void *)curve);
        }
 
@@ -1143,15 +1147,38 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf, unsigned c
                }
 #endif
 
-       /* don't add extensions for SSLv3 unless doing secure renegotiation */
-       if (s->client_version == SSL3_VERSION
-                                       && !s->s3->send_connection_binding)
-               return orig;
-
        ret+=2;
 
        if (ret>=limit) return NULL; /* this really never occurs, but ... */
 
+        /* Add RI if renegotiating */
+        if (s->renegotiate)
+          {
+          int el;
+
+          if(!ssl_add_clienthello_renegotiate_ext(s, 0, &el, 0))
+              {
+              SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
+              return NULL;
+              }
+
+          if((limit - ret - 4 - el) < 0) return NULL;
+
+          s2n(TLSEXT_TYPE_renegotiate,ret);
+          s2n(el,ret);
+
+          if(!ssl_add_clienthello_renegotiate_ext(s, ret, &el, el))
+              {
+              SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
+              return NULL;
+              }
+
+          ret += el;
+        }
+       /* Only add RI for SSLv3 */
+       if (s->client_version == SSL3_VERSION)
+               goto done;
+
        if (s->tlsext_hostname != NULL)
                { 
                /* Add TLS extension servername to the Client Hello message */
@@ -1184,31 +1211,6 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf, unsigned c
                ret+=size_str;
                }
 
-        /* Add RI if renegotiating */
-        if (s->renegotiate)
-          {
-          int el;
-          
-          if(!ssl_add_clienthello_renegotiate_ext(s, 0, &el, 0))
-              {
-              SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
-              return NULL;
-              }
-
-          if((limit - ret - 4 - el) < 0) return NULL;
-          
-          s2n(TLSEXT_TYPE_renegotiate,ret);
-          s2n(el,ret);
-
-          if(!ssl_add_clienthello_renegotiate_ext(s, ret, &el, el))
-              {
-              SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
-              return NULL;
-              }
-
-          ret += el;
-        }
-
 #ifndef OPENSSL_NO_SRP
        /* Add SRP username if there is one */
        if (s->srp_ctx.login != NULL)
@@ -1480,11 +1482,8 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf, unsigned c
        if (!custom_ext_add(s, 0, &ret, limit, al))
                return NULL;
 #ifdef TLSEXT_TYPE_encrypt_then_mac
-       if (s->version != SSL3_VERSION)
-               {
-               s2n(TLSEXT_TYPE_encrypt_then_mac,ret);
-               s2n(0,ret);
-               }
+       s2n(TLSEXT_TYPE_encrypt_then_mac,ret);
+       s2n(0,ret);
 #endif
 
        /* Add padding to workaround bugs in F5 terminators.
@@ -1517,6 +1516,8 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf, unsigned c
                        }
                }
 
+       done:
+
        if ((extdatalen = ret-orig-2)== 0) 
                return orig;
 
@@ -1538,21 +1539,10 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *buf, unsigned c
        int using_ecc = (alg_k & (SSL_kECDHE|SSL_kECDHr|SSL_kECDHe)) || (alg_a & SSL_aECDSA);
        using_ecc = using_ecc && (s->session->tlsext_ecpointformatlist != NULL);
 #endif
-       /* don't add extensions for SSLv3, unless doing secure renegotiation */
-       if (s->version == SSL3_VERSION && !s->s3->send_connection_binding)
-               return orig;
        
        ret+=2;
        if (ret>=limit) return NULL; /* this really never occurs, but ... */
 
-       if (!s->hit && s->servername_done == 1 && s->session->tlsext_hostname != NULL)
-               { 
-               if ((long)(limit - ret - 4) < 0) return NULL; 
-
-               s2n(TLSEXT_TYPE_server_name,ret);
-               s2n(0,ret);
-               }
-
        if(s->s3->send_connection_binding)
         {
           int el;
@@ -1577,6 +1567,18 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *buf, unsigned c
           ret += el;
         }
 
+       /* Only add RI for SSLv3 */
+       if (s->version == SSL3_VERSION)
+               goto done;
+
+       if (!s->hit && s->servername_done == 1 && s->session->tlsext_hostname != NULL)
+               {
+               if ((long)(limit - ret - 4) < 0) return NULL;
+
+               s2n(TLSEXT_TYPE_server_name,ret);
+               s2n(0,ret);
+               }
+
 #ifndef OPENSSL_NO_EC
        if (using_ecc)
                {
@@ -1717,12 +1719,11 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *buf, unsigned c
 #ifdef TLSEXT_TYPE_encrypt_then_mac
        if (s->s3->flags & TLS1_FLAGS_ENCRYPT_THEN_MAC)
                {
-               /* Don't use encrypt_then_mac if AEAD, RC4 or SSL 3.0:
+               /* Don't use encrypt_then_mac if AEAD or RC4
                 * might want to disable for other cases too.
                 */
                if (s->s3->tmp.new_cipher->algorithm_mac == SSL_AEAD
-                   || s->s3->tmp.new_cipher->algorithm_enc == SSL_RC4
-                   || s->version == SSL3_VERSION)
+                   || s->s3->tmp.new_cipher->algorithm_enc == SSL_RC4)
                        s->s3->flags &= ~TLS1_FLAGS_ENCRYPT_THEN_MAC;
                else
                        {
@@ -1747,6 +1748,8 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *buf, unsigned c
                ret += len;
                }
 
+       done:
+
        if ((extdatalen = ret-orig-2)== 0) 
                return orig;
 
@@ -1969,6 +1972,14 @@ static int ssl_scan_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char
                if (s->tlsext_debug_cb)
                        s->tlsext_debug_cb(s, 0, type, data, size,
                                                s->tlsext_debug_arg);
+               if (type == TLSEXT_TYPE_renegotiate)
+                       {
+                       if(!ssl_parse_clienthello_renegotiate_ext(s, data, size, al))
+                               return 0;
+                       renegotiate_seen = 1;
+                       }
+               else if (s->version == SSL3_VERSION)
+                       {}
 /* The servername extension is treated as follows:
 
    - Only the hostname type is supported with a maximum length of 255.
@@ -1992,7 +2003,7 @@ static int ssl_scan_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char
 
 */      
 
-               if (type == TLSEXT_TYPE_server_name)
+               else if (type == TLSEXT_TYPE_server_name)
                        {
                        unsigned char *sdata;
                        int servname_type;
@@ -2213,12 +2224,6 @@ static int ssl_scan_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char
                                return 0;
                                }
                        }
-               else if (type == TLSEXT_TYPE_renegotiate)
-                       {
-                       if(!ssl_parse_clienthello_renegotiate_ext(s, data, size, al))
-                               return 0;
-                       renegotiate_seen = 1;
-                       }
                else if (type == TLSEXT_TYPE_signature_algorithms)
                        {
                        int dsize;
@@ -2414,10 +2419,7 @@ static int ssl_scan_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char
                         }
 #ifdef TLSEXT_TYPE_encrypt_then_mac
                else if (type == TLSEXT_TYPE_encrypt_then_mac)
-                       {
-                       if (s->version != SSL3_VERSION)
-                               s->s3->flags |= TLS1_FLAGS_ENCRYPT_THEN_MAC;
-                       }
+                       s->s3->flags |= TLS1_FLAGS_ENCRYPT_THEN_MAC;
 #endif
                /* If this ClientHello extension was unhandled and this is 
                 * a nonresumed connection, check whether the extension is a 
@@ -2502,6 +2504,7 @@ static int ssl_scan_serverhello_tlsext(SSL *s, unsigned char **p, unsigned char
 #ifndef OPENSSL_NO_NEXTPROTONEG
        s->s3->next_proto_neg_seen = 0;
 #endif
+       s->tlsext_ticket_expected = 0;
 
        if (s->s3->alpn_selected)
                {
@@ -2540,7 +2543,16 @@ static int ssl_scan_serverhello_tlsext(SSL *s, unsigned char **p, unsigned char
                        s->tlsext_debug_cb(s, 1, type, data, size,
                                                s->tlsext_debug_arg);
 
-               if (type == TLSEXT_TYPE_server_name)
+
+               if (type == TLSEXT_TYPE_renegotiate)
+                       {
+                       if(!ssl_parse_serverhello_renegotiate_ext(s, data, size, al))
+                               return 0;
+                       renegotiate_seen = 1;
+                       }
+               else if (s->version == SSL3_VERSION)
+                       {}
+               else if (type == TLSEXT_TYPE_server_name)
                        {
                        if (s->tlsext_hostname == NULL || size > 0)
                                {
@@ -2722,13 +2734,6 @@ static int ssl_scan_serverhello_tlsext(SSL *s, unsigned char **p, unsigned char
                        memcpy(s->s3->alpn_selected, data + 3, len);
                        s->s3->alpn_selected_len = len;
                        }
-
-               else if (type == TLSEXT_TYPE_renegotiate)
-                       {
-                       if(!ssl_parse_serverhello_renegotiate_ext(s, data, size, al))
-                               return 0;
-                       renegotiate_seen = 1;
-                       }
 #ifndef OPENSSL_NO_HEARTBEATS
                else if (type == TLSEXT_TYPE_heartbeat)
                        {
@@ -2755,10 +2760,9 @@ static int ssl_scan_serverhello_tlsext(SSL *s, unsigned char **p, unsigned char
 #ifdef TLSEXT_TYPE_encrypt_then_mac
                else if (type == TLSEXT_TYPE_encrypt_then_mac)
                        {
-                       /* Ignore if inappropriate ciphersuite or SSL 3.0 */
+                       /* Ignore if inappropriate ciphersuite */
                        if (s->s3->tmp.new_cipher->algorithm_mac != SSL_AEAD
-                           && s->s3->tmp.new_cipher->algorithm_enc != SSL_RC4
-                           && s->version != SSL3_VERSION)
+                           && s->s3->tmp.new_cipher->algorithm_enc != SSL_RC4)
                                s->s3->flags |= TLS1_FLAGS_ENCRYPT_THEN_MAC;
                        }
 #endif
@@ -2963,11 +2967,54 @@ static int ssl_check_clienthello_tlsext_early(SSL *s)
                }
        }
 
+int tls1_set_server_sigalgs(SSL *s)
+       {
+       int al;
+       size_t i;
+       /* Clear any shared sigtnature algorithms */
+       if (s->cert->shared_sigalgs)
+               {
+               OPENSSL_free(s->cert->shared_sigalgs);
+               s->cert->shared_sigalgs = NULL;
+               }
+       /* Clear certificate digests and validity flags */
+       for (i = 0; i < SSL_PKEY_NUM; i++)
+               {
+               s->cert->pkeys[i].digest = NULL;
+               s->cert->pkeys[i].valid_flags = 0;
+               }
+
+       /* If sigalgs received process it. */
+       if (s->cert->peer_sigalgs)
+               {
+               if (!tls1_process_sigalgs(s))
+                       {
+                       SSLerr(SSL_F_TLS1_SET_SERVER_SIGALGS,
+                                       ERR_R_MALLOC_FAILURE);
+                       al = SSL_AD_INTERNAL_ERROR;
+                       goto err;
+                       }
+               /* Fatal error is no shared signature algorithms */
+               if (!s->cert->shared_sigalgs)
+                       {
+                       SSLerr(SSL_F_TLS1_SET_SERVER_SIGALGS,
+                                       SSL_R_NO_SHARED_SIGATURE_ALGORITHMS);
+                       al = SSL_AD_ILLEGAL_PARAMETER;
+                       goto err;
+                       }
+               }
+       else
+               ssl_cert_set_default_md(s->cert);
+       return 1;
+       err:
+       ssl3_send_alert(s, SSL3_AL_FATAL, al);
+       return 0;
+       }
+
 int ssl_check_clienthello_tlsext_late(SSL *s)
        {
        int ret = SSL_TLSEXT_ERR_OK;
        int al;
-       size_t i;
 
        /* If status request then ask callback what to do.
         * Note: this must be called after servername callbacks in case
@@ -3013,43 +3060,6 @@ int ssl_check_clienthello_tlsext_late(SSL *s)
        else
                s->tlsext_status_expected = 0;
 
-       /* Clear any shared sigtnature algorithms */
-       if (s->cert->shared_sigalgs)
-               {
-               OPENSSL_free(s->cert->shared_sigalgs);
-               s->cert->shared_sigalgs = NULL;
-               }
-       /* Clear certificate digests and validity flags */
-       for (i = 0; i < SSL_PKEY_NUM; i++)
-               {
-               s->cert->pkeys[i].digest = NULL;
-               s->cert->pkeys[i].valid_flags = 0;
-               }
-
-       /* If sigalgs received process it. */
-       if (s->cert->peer_sigalgs)
-               {
-               if (!tls1_process_sigalgs(s))
-                       {
-                       SSLerr(SSL_F_SSL_CHECK_CLIENTHELLO_TLSEXT_LATE,
-                                       ERR_R_MALLOC_FAILURE);
-                       ret = SSL_TLSEXT_ERR_ALERT_FATAL;
-                       al = SSL_AD_INTERNAL_ERROR;
-                       goto err;
-                       }
-               /* Fatal error is no shared signature algorithms */
-               if (!s->cert->shared_sigalgs)
-                       {
-                       SSLerr(SSL_F_SSL_CHECK_CLIENTHELLO_TLSEXT_LATE,
-                                       SSL_R_NO_SHARED_SIGATURE_ALGORITHMS);
-                       ret = SSL_TLSEXT_ERR_ALERT_FATAL;
-                       al = SSL_AD_ILLEGAL_PARAMETER;
-                       goto err;
-                       }
-               }
-       else
-               ssl_cert_set_default_md(s->cert);
-
  err:
        switch (ret)
                {
@@ -4284,13 +4294,10 @@ int tls1_check_chain(SSL *s, X509 *x, EVP_PKEY *pk, STACK_OF(X509) *chain,
                if (check_flags)
                        check_flags |= CERT_PKEY_SUITEB;
                ok = X509_chain_check_suiteb(NULL, x, chain, suiteb_flags);
-               if (ok != X509_V_OK)
-                       {
-                       if (check_flags)
-                               rv |= CERT_PKEY_SUITEB;
-                       else
-                               goto end;
-                       }
+               if (ok == X509_V_OK)
+                       rv |= CERT_PKEY_SUITEB;
+               else if (!check_flags)
+                       goto end;
                }
 
        /* Check all signature algorithms are consistent with