Remove all RFC5878 code.
[openssl.git] / ssl / s3_clnt.c
index 9755a0feb2ee58ac40b3b47f7a0f0b798dec317a..9a94de00d8492a292995a90b3f0c45b1fe85e087 100644 (file)
@@ -240,6 +240,13 @@ int ssl3_connect(SSL *s)
                                ret = -1;
                                goto end;
                                }
+
+                       if (!ssl_security(s, SSL_SECOP_VERSION, 0,
+                                                       s->version, NULL))
+                               {
+                               SSLerr(SSL_F_SSL3_CONNECT, SSL_R_VERSION_TOO_LOW);
+                               return -1;
+                               }
                                
                        /* s->version=SSL3_VERSION; */
                        s->type=SSL_ST_CONNECT;
@@ -311,26 +318,11 @@ int ssl3_connect(SSL *s)
                                }
                        s->init_num=0;
                        break;
-#ifndef OPENSSL_NO_TLSEXT
-               case SSL3_ST_CR_SUPPLEMENTAL_DATA_A:
-               case SSL3_ST_CR_SUPPLEMENTAL_DATA_B:
-                       ret = tls1_get_server_supplemental_data(s);
-                       if (ret <= 0) goto end;
-                       s->state=SSL3_ST_CR_CERT_A;
-                       s->init_num = 0;
-                       break;
-#endif
                case SSL3_ST_CR_CERT_A:
                case SSL3_ST_CR_CERT_B:
 #ifndef OPENSSL_NO_TLSEXT
                        ret=ssl3_check_finished(s);
                        if (ret <= 0) goto end;
-                       if (ret == 3)
-                               {
-                               s->state=SSL3_ST_CR_SUPPLEMENTAL_DATA_A;
-                               s->init_num=0;
-                               break;
-                               }
                        if (ret == 2)
                                {
                                s->hit = 1;
@@ -409,14 +401,10 @@ int ssl3_connect(SSL *s)
                                        }
                                }
 #endif
-#ifndef OPENSSL_NO_TLSEXT
-                       s->state=SSL3_ST_CW_SUPPLEMENTAL_DATA_A;
-#else
                        if (s->s3->tmp.cert_req)
                                s->state=SSL3_ST_CW_CERT_A;
                        else
                                s->state=SSL3_ST_CW_KEY_EXCH_A;
-#endif
                        s->init_num=0;
 
                        break;
@@ -523,19 +511,6 @@ int ssl3_connect(SSL *s)
                        break;
 #endif
 
-#ifndef OPENSSL_NO_TLSEXT
-               case SSL3_ST_CW_SUPPLEMENTAL_DATA_A:
-               case SSL3_ST_CW_SUPPLEMENTAL_DATA_B:
-                       ret = tls1_send_client_supplemental_data(s, &skip);
-                       if (ret <= 0) goto end;
-                       if (s->s3->tmp.cert_req)
-                               s->state=SSL3_ST_CW_CERT_A;
-                       else
-                               s->state=SSL3_ST_CW_KEY_EXCH_A;
-                       s->init_num=0;
-                       break;
-#endif
-
                case SSL3_ST_CW_FINISHED_A:
                case SSL3_ST_CW_FINISHED_B:
                        ret=ssl3_send_finished(s,
@@ -543,6 +518,7 @@ int ssl3_connect(SSL *s)
                                s->method->ssl3_enc->client_finished_label,
                                s->method->ssl3_enc->client_finished_label_len);
                        if (ret <= 0) goto end;
+                       s->s3->flags |= SSL3_FLAGS_CCS_OK;
                        s->state=SSL3_ST_CW_FLUSH;
 
                        /* clear flags */
@@ -592,6 +568,7 @@ int ssl3_connect(SSL *s)
                case SSL3_ST_CR_FINISHED_A:
                case SSL3_ST_CR_FINISHED_B:
 
+                       s->s3->flags |= SSL3_FLAGS_CCS_OK;
                        ret=ssl3_get_finished(s,SSL3_ST_CR_FINISHED_A,
                                SSL3_ST_CR_FINISHED_B);
                        if (ret <= 0) goto end;
@@ -871,8 +848,7 @@ int ssl3_client_hello(SSL *s)
                *(p++)=1;
 #else
 
-               if ((s->options & SSL_OP_NO_COMPRESSION)
-                                       || !s->ctx->comp_methods)
+               if (!ssl_allow_compression(s) || !s->ctx->comp_methods)
                        j=0;
                else
                        j=sk_SSL_COMP_num(s->ctx->comp_methods);
@@ -1030,6 +1006,7 @@ int ssl3_get_server_hello(SSL *s)
                        {
                        s->session->cipher = pref_cipher ?
                                pref_cipher : ssl_get_cipher_by_char(s, p+j);
+                       s->s3->flags |= SSL3_FLAGS_CCS_OK;
                        }
                }
 #endif /* OPENSSL_NO_TLSEXT */
@@ -1045,6 +1022,7 @@ int ssl3_get_server_hello(SSL *s)
                SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT);
                goto f_err;
                }
+           s->s3->flags |= SSL3_FLAGS_CCS_OK;
            s->hit=1;
            }
        else    /* a miss or crap from the other end */
@@ -1079,9 +1057,7 @@ int ssl3_get_server_hello(SSL *s)
        /* If it is a disabled cipher we didn't send it in client hello,
         * so return an error.
         */
-       if (c->algorithm_ssl & ct->mask_ssl ||
-               c->algorithm_mkey & ct->mask_k ||
-               c->algorithm_auth & ct->mask_a)
+       if (ssl_cipher_disabled(s, c, SSL_SECOP_CIPHER_CHECK))
                {
                al=SSL_AD_ILLEGAL_PARAMETER;
                SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_WRONG_CIPHER_RETURNED);
@@ -1150,7 +1126,7 @@ int ssl3_get_server_hello(SSL *s)
                }
        if (j == 0)
                comp=NULL;
-       else if (s->options & SSL_OP_NO_COMPRESSION)
+       else if (!ssl_allow_compression(s))
                {
                al=SSL_AD_ILLEGAL_PARAMETER;
                SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_COMPRESSION_DISABLED);
@@ -1292,6 +1268,12 @@ int ssl3_get_server_certificate(SSL *s)
                goto f_err; 
                }
        ERR_clear_error(); /* but we keep s->verify_result */
+       if (i > 1)
+               {
+               SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE, i);
+               al = SSL_AD_HANDSHAKE_FAILURE;
+               goto f_err;
+               }
 
        sc=ssl_sess_cert_new();
        if (sc == NULL) goto err;
@@ -1711,6 +1693,14 @@ int ssl3_get_key_exchange(SSL *s)
                p+=i;
                n-=param_len;
 
+               if (!ssl_security(s, SSL_SECOP_TMP_DH,
+                                               DH_security_bits(dh), 0, dh))
+                       {
+                       al=SSL_AD_HANDSHAKE_FAILURE;
+                       SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_DH_KEY_TOO_SMALL);
+                       goto f_err;
+                       }
+
 #ifndef OPENSSL_NO_RSA
                if (alg_a & SSL_aRSA)
                        pkey=X509_get_pubkey(s->session->sess_cert->peer_pkeys[SSL_PKEY_RSA_ENC].x509);
@@ -2694,6 +2684,13 @@ int ssl3_send_client_key_exchange(SSL *s)
                        int ecdh_clnt_cert = 0;
                        int field_size = 0;
 
+                       if (s->session->sess_cert == NULL) 
+                               {
+                               ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_UNEXPECTED_MESSAGE);
+                               SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,SSL_R_UNEXPECTED_MESSAGE);
+                               goto err;
+                               }
+
                        /* Did we send out the client's
                         * ECDH share for use in premaster
                         * computation as part of client certificate?
@@ -3382,8 +3379,13 @@ int ssl3_send_client_certificate(SSL *s)
        if (s->state == SSL3_ST_CW_CERT_C)
                {
                s->state=SSL3_ST_CW_CERT_D;
-               ssl3_output_cert_chain(s,
-                       (s->s3->tmp.cert_req == 2)?NULL:s->cert->key);
+               if (!ssl3_output_cert_chain(s,
+                       (s->s3->tmp.cert_req == 2)?NULL:s->cert->key))
+                       {
+                       SSLerr(SSL_F_SSL3_SEND_CLIENT_CERTIFICATE, ERR_R_INTERNAL_ERROR);
+                       ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_INTERNAL_ERROR);
+                       return 0;
+                       }
                }
        /* SSL3_ST_CW_CERT_D */
        return ssl_do_write(s);
@@ -3577,10 +3579,11 @@ int ssl3_check_finished(SSL *s)
        int ok;
        long n;
 
-       /* Read the message to see if it is supplemental data,
-        * regardless if there is a session ticket this function is
-        * called when we really expect a Certificate message, so
-        * permit appropriate message length */
+       /* If we have no ticket it cannot be a resumed session. */
+       if (!s->session->tlsext_tick)
+               return 1;
+       /* this function is called when we really expect a Certificate
+        * message, so permit appropriate message length */
        n=s->method->ssl_get_message(s,
                SSL3_ST_CR_CERT_A,
                SSL3_ST_CR_CERT_B,
@@ -3590,11 +3593,6 @@ int ssl3_check_finished(SSL *s)
        if (!ok) return((int)n);
        s->s3->tmp.reuse_message = 1;
 
-       if (s->s3->tmp.message_type == SSL3_MT_SUPPLEMENTAL_DATA)
-               return 3;
-       /* If we have no ticket it cannot be a resumed session. */
-       if (!s->session->tlsext_tick)
-               return 1;
        if ((s->s3->tmp.message_type == SSL3_MT_FINISHED)
                || (s->s3->tmp.message_type == SSL3_MT_NEWSESSION_TICKET))
                return 2;
@@ -3620,155 +3618,3 @@ int ssl_do_client_cert_cb(SSL *s, X509 **px509, EVP_PKEY **ppkey)
                i = s->ctx->client_cert_cb(s,px509,ppkey);
        return i;
        }
-
-#ifndef OPENSSL_NO_TLSEXT
-int tls1_send_client_supplemental_data(SSL *s, int *skip)
-       {
-       int al = 0;
-       if (s->ctx->cli_supp_data_records_count)
-               {
-               unsigned char *p = NULL;
-               unsigned char *size_loc = NULL;
-               cli_supp_data_record *record = NULL;
-               size_t length = 0;
-               size_t i = 0;
-
-               for (i = 0; i < s->ctx->cli_supp_data_records_count; i++)
-                       {
-                       const unsigned char *out = NULL;
-                       unsigned short outlen = 0;
-                       int cb_retval = 0;
-                       record = &s->ctx->cli_supp_data_records[i];
-
-                       /* NULL callback or -1 omits supp data entry*/
-                       if (!record->fn2)
-                               continue;
-                       cb_retval = record->fn2(s, record->supp_data_type,
-                                               &out, &outlen, &al,
-                                               record->arg);
-                       if (cb_retval == -1)
-                               continue; /* skip this supp data entry */
-                       if (cb_retval == 0)
-                               {
-                               SSLerr(SSL_F_TLS1_SEND_CLIENT_SUPPLEMENTAL_DATA,ERR_R_BUF_LIB);
-                               goto f_err;
-                               }
-                       if (outlen == 0 || TLSEXT_MAXLEN_supplemental_data < outlen + 4 + length)
-                               {
-                               SSLerr(SSL_F_TLS1_SEND_CLIENT_SUPPLEMENTAL_DATA,ERR_R_BUF_LIB);
-                               return 0;
-                               }
-                       /* if first entry, write handshake message type */
-                       if (length == 0)
-                               {
-                               if (!BUF_MEM_grow_clean(s->init_buf, 4))
-                                       {
-                                       SSLerr(SSL_F_TLS1_SEND_CLIENT_SUPPLEMENTAL_DATA,ERR_R_BUF_LIB);
-                                       return 0;
-                                       }
-                               p = (unsigned char *)s->init_buf->data;
-                               *(p++) = SSL3_MT_SUPPLEMENTAL_DATA;
-                               /* update message length when all
-                                * callbacks complete */
-                               size_loc = p;
-                               /* skip over handshake length field (3
-                                * bytes) and supp_data length field
-                                * (3 bytes) */
-                               p += 3 + 3;
-                               length += 1 +3 +3;
-                               }
-                       if (!BUF_MEM_grow(s->init_buf, outlen + 4))
-                               {
-                               SSLerr(SSL_F_TLS1_SEND_CLIENT_SUPPLEMENTAL_DATA,ERR_R_BUF_LIB);
-                               return 0;
-                               }
-                       s2n(record->supp_data_type, p);
-                       s2n(outlen, p);
-                       memcpy(p, out, outlen);
-                       length += (outlen + 4);
-                       p += outlen;
-                       }
-               if (length > 0)
-                       {
-                       /* write handshake length */
-                       l2n3(length - 4, size_loc);
-                       /* supp_data length */
-                       l2n3(length - 7, size_loc);
-                       s->state = SSL3_ST_CW_SUPPLEMENTAL_DATA_B;
-                       s->init_num = length;
-                       s->init_off = 0;
-                       return ssl3_do_write(s, SSL3_RT_HANDSHAKE);
-                       }
-               }
-
-       /* no supp data message sent */
-       *skip = 1;
-       s->init_num = 0;
-       s->init_off = 0;
-       return 1;
-
-       f_err:
-       ssl3_send_alert(s,SSL3_AL_FATAL,al);
-       return 0;
-       }
-
-int tls1_get_server_supplemental_data(SSL *s)
-       {
-       int al = 0;
-       int ok;
-       long n;
-       const unsigned char *p, *d;
-       unsigned short supp_data_entry_type = 0;
-       unsigned short supp_data_entry_len = 0;
-       unsigned long supp_data_len = 0;
-       size_t i;
-       int cb_retval = 0;
-
-       n=s->method->ssl_get_message(s,
-                                    SSL3_ST_CR_SUPPLEMENTAL_DATA_A,
-                                    SSL3_ST_CR_SUPPLEMENTAL_DATA_B,
-                                    SSL3_MT_SUPPLEMENTAL_DATA,
-                                    /* use default limit */
-                                    TLSEXT_MAXLEN_supplemental_data,
-                                    &ok);
-
-       if (!ok) return((int)n);
-
-       p = (unsigned char *)s->init_msg;
-       d = p;
-       /* The message cannot be empty */
-       if (n < 3)
-               {
-               al = SSL_AD_DECODE_ERROR;
-               SSLerr(SSL_F_TLS1_GET_SERVER_SUPPLEMENTAL_DATA,SSL_R_LENGTH_MISMATCH);
-               goto f_err;
-               }
-       n2l3(p, supp_data_len);
-       while (p < d+supp_data_len)
-               {
-               n2s(p, supp_data_entry_type);
-               n2s(p, supp_data_entry_len);
-               /* if there is a callback for this supp data type, send it */
-               for (i=0; i < s->ctx->cli_supp_data_records_count; i++)
-                       {
-                       if (s->ctx->cli_supp_data_records[i].supp_data_type == supp_data_entry_type &&
-                           s->ctx->cli_supp_data_records[i].fn1)
-                               {
-                               cb_retval = s->ctx->cli_supp_data_records[i].fn1(s, supp_data_entry_type, p,
-                                                                                supp_data_entry_len, &al,
-                                                                                s->ctx->cli_supp_data_records[i].arg);
-                               if (cb_retval == 0)
-                                       {
-                                       SSLerr(SSL_F_TLS1_GET_SERVER_SUPPLEMENTAL_DATA, ERR_R_SSL_LIB);
-                                       goto f_err;
-                                       }
-                               }
-                       }
-               p += supp_data_entry_len;
-               }
-       return 1;
-f_err:
-       ssl3_send_alert(s,SSL3_AL_FATAL,al);
-       return -1;
-       }
-#endif