Remove all RFC5878 code.
[openssl.git] / ssl / s3_srvr.c
index 54266fb6dac6c490131855c080029693a02c642f..00fa6793e94406fb1801eebc0e23237dcc45b5fb 100644 (file)
@@ -272,6 +272,14 @@ int ssl3_accept(SSL *s)
                                SSLerr(SSL_F_SSL3_ACCEPT, ERR_R_INTERNAL_ERROR);
                                return -1;
                                }
+
+                       if (!ssl_security(s, SSL_SECOP_VERSION, 0,
+                                                       s->version, NULL))
+                               {
+                               SSLerr(SSL_F_SSL3_ACCEPT, SSL_R_VERSION_TOO_LOW);
+                               return -1;
+                               }
+
                        s->type=SSL_ST_ACCEPT;
 
                        if (s->init_buf == NULL)
@@ -401,24 +409,9 @@ int ssl3_accept(SSL *s)
                                        s->state=SSL3_ST_SW_CHANGE_A;
 #endif
                        else
-#ifndef OPENSSL_NO_TLSEXT
-                               s->state = SSL3_ST_SW_SUPPLEMENTAL_DATA_A;
-#else
-                       s->state = SSL3_ST_SW_CERT_A;
-#endif
-                       s->init_num = 0;
-                       break;
-
-#ifndef OPENSSL_NO_TLSEXT
-               case SSL3_ST_SW_SUPPLEMENTAL_DATA_A:
-               case SSL3_ST_SW_SUPPLEMENTAL_DATA_B:
-                       ret = tls1_send_server_supplemental_data(s, &skip);
-                       if (ret <= 0) goto end;
-
-                       s->state = SSL3_ST_SW_CERT_A;
+                                       s->state = SSL3_ST_SW_CERT_A;
                        s->init_num = 0;
                        break;
-#endif
 
                case SSL3_ST_SW_CERT_A:
                case SSL3_ST_SW_CERT_B:
@@ -588,16 +581,7 @@ int ssl3_accept(SSL *s)
 
                        s->state=s->s3->tmp.next_state;
                        break;
-#ifndef OPENSSL_NO_TLSEXT
-               case SSL3_ST_SR_SUPPLEMENTAL_DATA_A:
-               case SSL3_ST_SR_SUPPLEMENTAL_DATA_B:
-                       ret=tls1_get_client_supplemental_data(s);
-                       if (ret <= 0) goto end;
-                       s->s3->tmp.next_state=SSL3_ST_SR_CERT_A;
-                       s->state=SSL3_ST_SW_FLUSH;
-                       s->init_num=0;
-                       break;
-#endif
+
                case SSL3_ST_SR_CERT_A:
                case SSL3_ST_SR_CERT_B:
                        /* Check for second client hello (MS SGC) */
@@ -606,10 +590,6 @@ int ssl3_accept(SSL *s)
                                goto end;
                        if (ret == 2)
                                s->state = SSL3_ST_SR_CLNT_HELLO_C;
-#ifndef OPENSSL_NO_TLSEXT
-                       else if (ret == 3)
-                               s->state = SSL3_ST_SR_SUPPLEMENTAL_DATA_A;
-#endif
                        else {
                                if (s->s3->tmp.cert_request)
                                        {
@@ -700,6 +680,7 @@ int ssl3_accept(SSL *s)
                case SSL3_ST_SR_CERT_VRFY_A:
                case SSL3_ST_SR_CERT_VRFY_B:
 
+                       s->s3->flags |= SSL3_FLAGS_CCS_OK;
                        /* we should decide if we expected this one */
                        ret=ssl3_get_cert_verify(s);
                        if (ret <= 0) goto end;
@@ -727,6 +708,7 @@ int ssl3_accept(SSL *s)
 
                case SSL3_ST_SR_FINISHED_A:
                case SSL3_ST_SR_FINISHED_B:
+                       s->s3->flags |= SSL3_FLAGS_CCS_OK;
                        ret=ssl3_get_finished(s,SSL3_ST_SR_FINISHED_A,
                                SSL3_ST_SR_FINISHED_B);
                        if (ret <= 0) goto end;
@@ -797,7 +779,10 @@ int ssl3_accept(SSL *s)
                                s->s3->tmp.next_state=SSL3_ST_SR_FINISHED_A;
 #else
                                if (s->s3->next_proto_neg_seen)
+                                       {
+                                       s->s3->flags |= SSL3_FLAGS_CCS_OK;
                                        s->s3->tmp.next_state=SSL3_ST_SR_NEXT_PROTO_A;
+                                       }
                                else
                                        s->s3->tmp.next_state=SSL3_ST_SR_FINISHED_A;
 #endif
@@ -900,10 +885,6 @@ int ssl3_check_client_hello(SSL *s)
                &ok);
        if (!ok) return((int)n);
        s->s3->tmp.reuse_message = 1;
-#ifndef OPENSSL_NO_TLSEXT
-       if (s->s3->tmp.message_type == SSL3_MT_SUPPLEMENTAL_DATA)
-               return 3;
-#endif
        if (s->s3->tmp.message_type == SSL3_MT_CLIENT_HELLO)
                {
                /* We only allow the client to restart the handshake once per
@@ -949,7 +930,7 @@ int ssl3_get_client_hello(SSL *s)
 #endif
        STACK_OF(SSL_CIPHER) *ciphers=NULL;
 
-       if (s->state == SSL3_ST_SR_CLNT_HELLO_C)
+       if (s->state == SSL3_ST_SR_CLNT_HELLO_C && !s->first_packet)
                goto retry_cert;
 
        /* We do this so that we will respond with our native type.
@@ -1305,7 +1286,7 @@ int ssl3_get_client_hello(SSL *s)
                int m, comp_id = s->session->compress_meth;
                /* Perform sanity checks on resumed compression algorithm */
                /* Can't disable compression */
-               if (s->options & SSL_OP_NO_COMPRESSION)
+               if (!ssl_allow_compression(s))
                        {
                        SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_INCONSISTENT_COMPRESSION);
                        goto f_err;
@@ -1340,7 +1321,7 @@ int ssl3_get_client_hello(SSL *s)
                }
        else if (s->hit)
                comp = NULL;
-       else if (!(s->options & SSL_OP_NO_COMPRESSION) && s->ctx->comp_methods)
+       else if (ssl_allow_compression(s) && s->ctx->comp_methods)
                { /* See if we have a match */
                int m,nn,o,v,done=0;
 
@@ -1476,7 +1457,7 @@ int ssl3_get_client_hello(SSL *s)
         * ssl version is set   - sslv3
         * s->session           - The ssl session has been setup.
         * s->hit               - session reuse flag
-        * s->tmp.new_cipher    - the new cipher to use.
+        * s->s3->tmp.new_cipher- the new cipher to use.
         */
 
        /* Handles TLS extensions that we couldn't check earlier */
@@ -1504,7 +1485,8 @@ int ssl3_send_server_hello(SSL *s)
        {
        unsigned char *buf;
        unsigned char *p,*d;
-        int i,sl,al;
+       int i,sl;
+       int al = 0;
        unsigned long l;
 
        if (s->state == SSL3_ST_SW_SRVR_HELLO_A)
@@ -1574,9 +1556,9 @@ int ssl3_send_server_hello(SSL *s)
                        SSLerr(SSL_F_SSL3_SEND_SERVER_HELLO,SSL_R_SERVERHELLO_TLSEXT);
                        return -1;
                        }
-                if ((p = ssl_add_serverhello_tlsext(s, p, buf+SSL3_RT_MAX_PLAIN_LENGTH, &al)) == NULL)
+               if ((p = ssl_add_serverhello_tlsext(s, p, buf+SSL3_RT_MAX_PLAIN_LENGTH, &al)) == NULL)
                        {
-                        ssl3_send_alert(s, SSL3_AL_FATAL, al);
+                       ssl3_send_alert(s, SSL3_AL_FATAL, al);
                        SSLerr(SSL_F_SSL3_SEND_SERVER_HELLO,ERR_R_INTERNAL_ERROR);
                        return -1;
                        }
@@ -1678,7 +1660,18 @@ int ssl3_send_server_key_exchange(SSL *s)
 #ifndef OPENSSL_NO_DH
                        if (type & SSL_kDHE)
                        {
-                       dhp=cert->dh_tmp;
+                       if (s->cert->dh_tmp_auto)
+                               {
+                               dhp = ssl_get_auto_dh(s);
+                               if (dhp == NULL)
+                                       {
+                                       al=SSL_AD_INTERNAL_ERROR;
+                                       SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,ERR_R_INTERNAL_ERROR);
+                                       goto f_err;
+                                       }
+                               }
+                       else
+                               dhp=cert->dh_tmp;
                        if ((dhp == NULL) && (s->cert->dh_tmp_cb != NULL))
                                dhp=s->cert->dh_tmp_cb(s,
                                      SSL_C_IS_EXPORT(s->s3->tmp.new_cipher),
@@ -1689,14 +1682,22 @@ int ssl3_send_server_key_exchange(SSL *s)
                                SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,SSL_R_MISSING_TMP_DH_KEY);
                                goto f_err;
                                }
-
+                       if (!ssl_security(s, SSL_SECOP_TMP_DH,
+                                               DH_security_bits(dhp), 0, dhp))
+                               {
+                               al=SSL_AD_HANDSHAKE_FAILURE;
+                               SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,SSL_R_DH_KEY_TOO_SMALL);
+                               goto f_err;
+                               }
                        if (s->s3->tmp.dh != NULL)
                                {
                                SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR);
                                goto err;
                                }
 
-                       if ((dh=DHparams_dup(dhp)) == NULL)
+                       if (s->cert->dh_tmp_auto)
+                               dh = dhp;
+                       else if ((dh=DHparams_dup(dhp)) == NULL)
                                {
                                SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,ERR_R_DH_LIB);
                                goto err;
@@ -2101,9 +2102,13 @@ int ssl3_send_certificate_request(SSL *s)
                if (SSL_USE_SIGALGS(s))
                        {
                        const unsigned char *psigs;
+                       unsigned char *etmp = p;
                        nl = tls12_get_psigalgs(s, &psigs);
-                       s2n(nl, p);
-                       memcpy(p, psigs, nl);
+                       /* Skip over length for now */
+                       p += 2;
+                       nl = tls12_copy_sigalgs(s, p, psigs, nl);
+                       /* Now fill in length */
+                       s2n(nl, etmp);
                        p += nl;
                        n += nl + 2;
                        }
@@ -2152,6 +2157,11 @@ int ssl3_send_certificate_request(SSL *s)
 #ifdef NETSCAPE_HANG_BUG
                if (!SSL_IS_DTLS(s))
                        {
+                       if (!BUF_MEM_grow_clean(buf, s->init_num + 4))
+                               {
+                               SSLerr(SSL_F_SSL3_SEND_CERTIFICATE_REQUEST,ERR_R_BUF_LIB);
+                               goto err;
+                               }
                        p=(unsigned char *)s->init_buf->data + s->init_num;
                        /* do the header */
                        *(p++)=SSL3_MT_SERVER_DONE;
@@ -2947,6 +2957,8 @@ int ssl3_get_client_key_exchange(SSL *s)
                        unsigned char premaster_secret[32], *start;
                        size_t outlen=32, inlen;
                        unsigned long alg_a;
+                       int Ttag, Tclass;
+                       long Tlen;
 
                        /* Get our certificate private key*/
                        alg_a = s->s3->tmp.new_cipher->algorithm_auth;
@@ -2968,26 +2980,15 @@ int ssl3_get_client_key_exchange(SSL *s)
                                        ERR_clear_error();
                                }
                        /* Decrypt session key */
-                       if ((*p!=( V_ASN1_SEQUENCE| V_ASN1_CONSTRUCTED))) 
-                               {
-                               SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_DECRYPTION_FAILED);
-                               goto gerr;
-                               }
-                       if (p[1] == 0x81)
-                               {
-                               start = p+3;
-                               inlen = p[2];
-                               }
-                       else if (p[1] < 0x80)
-                               {
-                               start = p+2;
-                               inlen = p[1];
-                               }
-                       else
+                       if (ASN1_get_object((const unsigned char **)&p, &Tlen, &Ttag, &Tclass, n) != V_ASN1_CONSTRUCTED || 
+                               Ttag != V_ASN1_SEQUENCE ||
+                               Tclass != V_ASN1_UNIVERSAL) 
                                {
                                SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_DECRYPTION_FAILED);
                                goto gerr;
                                }
+                       start = p;
+                       inlen = Tlen;
                        if (EVP_PKEY_decrypt(pkey_ctx,premaster_secret,&outlen,start,inlen) <=0) 
 
                                {
@@ -3399,6 +3400,7 @@ int ssl3_get_client_certificate(SSL *s)
                }
        else
                {
+               EVP_PKEY *pkey;
                i=ssl_verify_cert_chain(s,sk);
                if (i <= 0)
                        {
@@ -3406,6 +3408,21 @@ int ssl3_get_client_certificate(SSL *s)
                        SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE,SSL_R_CERTIFICATE_VERIFY_FAILED);
                        goto f_err;
                        }
+               if (i > 1)
+                       {
+                       SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE, i);
+                       al = SSL_AD_HANDSHAKE_FAILURE;
+                       goto f_err;
+                       }
+               pkey = X509_get_pubkey(sk_X509_value(sk, 0));
+               if (pkey == NULL)
+                       {
+                       al=SSL3_AD_HANDSHAKE_FAILURE;
+                       SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE,
+                                               SSL_R_UNKNOWN_CERTIFICATE_TYPE);
+                       goto f_err;
+                       }
+               EVP_PKEY_free(pkey);
                }
 
        if (s->session->peer != NULL) /* This should not be needed */
@@ -3462,7 +3479,11 @@ int ssl3_send_server_certificate(SSL *s)
                                }
                        }
 
-               ssl3_output_cert_chain(s,cpk);
+               if (!ssl3_output_cert_chain(s,cpk))
+                       {
+                       SSLerr(SSL_F_SSL3_SEND_SERVER_CERTIFICATE,ERR_R_INTERNAL_ERROR);
+                       return(0);
+                       }
                s->state=SSL3_ST_SW_CERT_B;
                }
 
@@ -3702,157 +3723,4 @@ int ssl3_get_next_proto(SSL *s)
        }
 # endif
 
-int tls1_send_server_supplemental_data(SSL *s, int *skip)
-       {
-        int al = 0;
-       if (s->ctx->srv_supp_data_records_count)
-               {
-               unsigned char *p = NULL;
-               unsigned char *size_loc = NULL;
-               srv_supp_data_record *record = NULL;
-               size_t length = 0;
-               size_t i = 0;
-
-               for (i = 0; i < s->ctx->srv_supp_data_records_count; i++)
-                       {
-                       const unsigned char *out = NULL;
-                       unsigned short outlen = 0;
-                       int cb_retval = 0;
-                       record = &s->ctx->srv_supp_data_records[i];
-
-                       /* NULL callback or -1 omits supp data entry */
-                       if (!record->fn1)
-                               continue;
-                       cb_retval = record->fn1(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_SERVER_SUPPLEMENTAL_DATA,ERR_R_BUF_LIB);
-                                goto f_err;
-                               }
-                       if (outlen == 0 || TLSEXT_MAXLEN_supplemental_data < outlen + 4 + length)
-                               {
-                               SSLerr(SSL_F_TLS1_SEND_SERVER_SUPPLEMENTAL_DATA,ERR_R_BUF_LIB);
-                               return 0;
-                               }
-                       /* write supp data entry...
-                        * if first entry, write handshake message type
-                        * jump back to write length at end */
-                       if (length == 0)
-                               {
-                               /* 1 byte message type + 3 bytes for
-                                * message length */
-                               if (!BUF_MEM_grow_clean(s->init_buf, 4))
-                                       {
-                                       SSLerr(SSL_F_TLS1_SEND_SERVER_SUPPLEMENTAL_DATA,ERR_R_BUF_LIB);
-                                       return 0;
-                                       }
-                               p = (unsigned char *)s->init_buf->data;
-                               *(p++) = SSL3_MT_SUPPLEMENTAL_DATA;
-                               /* hold on to length field to update later */
-                               size_loc = p;
-                               /* skip over handshake length field (3
-                                * bytes) and supp_data length field
-                                * (3 bytes) */
-                               p += 3 + 3;
-                               length += 1 +3 +3;
-                               }
-                       /* 2 byte supp data type + 2 byte length + outlen */
-                       if (!BUF_MEM_grow(s->init_buf, outlen + 4))
-                               {
-                               SSLerr(SSL_F_TLS1_SEND_SERVER_SUPPLEMENTAL_DATA,ERR_R_BUF_LIB);
-                               return 0;
-                               }
-                       s2n(record->supp_data_type, p);
-                       s2n(outlen, p);
-                       memcpy(p, out, outlen);
-                       /* update length to supp data type (2 bytes) +
-                        * supp data length (2 bytes) + supp data */
-                       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_SW_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_client_supplemental_data(SSL *s)
-       {
-       int al = 0;
-       int cb_retval = 0;
-       int ok;
-       long n;
-       const unsigned char *p, *d;
-       unsigned short supp_data_entry_type = 0;
-       unsigned long supp_data_entry_len = 0;
-       unsigned long supp_data_len = 0;
-       size_t i = 0;
-
-       n=s->method->ssl_get_message(s,
-       SSL3_ST_SR_SUPPLEMENTAL_DATA_A,
-       SSL3_ST_SR_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_CLIENT_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->srv_supp_data_records_count; i++)
-                       {
-                       if (s->ctx->srv_supp_data_records[i].supp_data_type == supp_data_entry_type && s->ctx->srv_supp_data_records[i].fn2)
-                               {
-                               cb_retval = s->ctx->srv_supp_data_records[i].fn2(s, supp_data_entry_type, p, supp_data_entry_len, &al, s->ctx->srv_supp_data_records[i].arg);
-                               if (cb_retval == 0)
-                                       {
-                                       SSLerr(SSL_F_TLS1_GET_CLIENT_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