Add support for magic cipher suite value (MCSV). Make secure renegotiation
[openssl.git] / ssl / s3_both.c
index 361ecf1f9f83eadcdf9286e040a725189b39a925..16d92610e95f1283a63f3bb959496ab4b662291a 100644 (file)
@@ -166,6 +166,23 @@ int ssl3_send_finished(SSL *s, int a, int b, const char *sender, int slen)
                p+=i;
                l=i;
 
+                /* Copy the finished so we can use it for
+                   renegotiation checks */
+                if(s->type == SSL_ST_CONNECT)
+                        {
+                         OPENSSL_assert(i <= EVP_MAX_MD_SIZE);
+                         memcpy(s->s3->previous_client_finished, 
+                             s->s3->tmp.finish_md, i);
+                         s->s3->previous_client_finished_len=i;
+                        }
+                else
+                        {
+                        OPENSSL_assert(i <= EVP_MAX_MD_SIZE);
+                        memcpy(s->s3->previous_server_finished, 
+                            s->s3->tmp.finish_md, i);
+                        s->s3->previous_server_finished_len=i;
+                        }
+
 #ifdef OPENSSL_SYS_WIN16
                /* MSVC 1.5 does not clear the top bytes of the word unless
                 * I do this.
@@ -230,6 +247,23 @@ int ssl3_get_finished(SSL *s, int a, int b)
                goto f_err;
                }
 
+        /* Copy the finished so we can use it for
+           renegotiation checks */
+        if(s->type == SSL_ST_ACCEPT)
+                {
+                OPENSSL_assert(i <= EVP_MAX_MD_SIZE);
+                memcpy(s->s3->previous_client_finished, 
+                    s->s3->tmp.peer_finish_md, i);
+                s->s3->previous_client_finished_len=i;
+                }
+        else
+                {
+                OPENSSL_assert(i <= EVP_MAX_MD_SIZE);
+                memcpy(s->s3->previous_server_finished, 
+                    s->s3->tmp.peer_finish_md, i);
+                s->s3->previous_server_finished_len=i;
+                }
+
        return(1);
 f_err:
        ssl3_send_alert(s,SSL3_AL_FATAL,al);
@@ -262,15 +296,31 @@ int ssl3_send_change_cipher_spec(SSL *s, int a, int b)
        return(ssl3_do_write(s,SSL3_RT_CHANGE_CIPHER_SPEC));
        }
 
+static int ssl3_add_cert_to_buf(BUF_MEM *buf, unsigned long *l, X509 *x)
+       {
+       int n;
+       unsigned char *p;
+
+       n=i2d_X509(x,NULL);
+       if (!BUF_MEM_grow_clean(buf,(int)(n+(*l)+3)))
+               {
+               SSLerr(SSL_F_SSL3_ADD_CERT_TO_BUF,ERR_R_BUF_LIB);
+               return(-1);
+               }
+       p=(unsigned char *)&(buf->data[*l]);
+       l2n3(n,p);
+       i2d_X509(x,&p);
+       *l+=n+3;
+
+       return(0);
+       }
+
 unsigned long ssl3_output_cert_chain(SSL *s, X509 *x)
        {
        unsigned char *p;
-       int n,i;
+       int i;
        unsigned long l=7;
        BUF_MEM *buf;
-       X509_STORE_CTX xs_ctx;
-       X509_OBJECT obj;
-
        int no_chain;
 
        if ((s->mode & SSL_MODE_NO_AUTO_CHAIN) || s->ctx->extra_certs)
@@ -287,58 +337,40 @@ unsigned long ssl3_output_cert_chain(SSL *s, X509 *x)
                }
        if (x != NULL)
                {
-               if(!no_chain && !X509_STORE_CTX_init(&xs_ctx,s->ctx->cert_store,NULL,NULL))
+               if (no_chain)
                        {
-                       SSLerr(SSL_F_SSL3_OUTPUT_CERT_CHAIN,ERR_R_X509_LIB);
-                       return(0);
+                       if (ssl3_add_cert_to_buf(buf, &l, x))
+                               return(0);
                        }
-
-               for (;;)
+               else
                        {
-                       n=i2d_X509(x,NULL);
-                       if (!BUF_MEM_grow_clean(buf,(int)(n+l+3)))
+                       X509_STORE_CTX xs_ctx;
+
+                       if (!X509_STORE_CTX_init(&xs_ctx,s->ctx->cert_store,x,NULL))
                                {
-                               SSLerr(SSL_F_SSL3_OUTPUT_CERT_CHAIN,ERR_R_BUF_LIB);
+                               SSLerr(SSL_F_SSL3_OUTPUT_CERT_CHAIN,ERR_R_X509_LIB);
                                return(0);
                                }
-                       p=(unsigned char *)&(buf->data[l]);
-                       l2n3(n,p);
-                       i2d_X509(x,&p);
-                       l+=n+3;
-
-                       if (no_chain)
-                               break;
-
-                       if (X509_NAME_cmp(X509_get_subject_name(x),
-                               X509_get_issuer_name(x)) == 0) break;
-
-                       i=X509_STORE_get_by_subject(&xs_ctx,X509_LU_X509,
-                               X509_get_issuer_name(x),&obj);
-                       if (i <= 0) break;
-                       x=obj.data.x509;
-                       /* Count is one too high since the X509_STORE_get uped the
-                        * ref count */
-                       X509_free(x);
-                       }
-               if (!no_chain)
+                       X509_verify_cert(&xs_ctx);
+                       for (i=0; i < sk_X509_num(xs_ctx.chain); i++)
+                               {
+                               x = sk_X509_value(xs_ctx.chain, i);
+
+                               if (ssl3_add_cert_to_buf(buf, &l, x))
+                                       {
+                                       X509_STORE_CTX_cleanup(&xs_ctx);
+                                       return 0;
+                                       }
+                               }
                        X509_STORE_CTX_cleanup(&xs_ctx);
+                       }
                }
-
        /* Thawte special :-) */
-       if (s->ctx->extra_certs != NULL)
        for (i=0; i<sk_X509_num(s->ctx->extra_certs); i++)
                {
                x=sk_X509_value(s->ctx->extra_certs,i);
-               n=i2d_X509(x,NULL);
-               if (!BUF_MEM_grow_clean(buf,(int)(n+l+3)))
-                       {
-                       SSLerr(SSL_F_SSL3_OUTPUT_CERT_CHAIN,ERR_R_BUF_LIB);
+               if (ssl3_add_cert_to_buf(buf, &l, x))
                        return(0);
-                       }
-               p=(unsigned char *)&(buf->data[l]);
-               l2n3(n,p);
-               i2d_X509(x,&p);
-               l+=n+3;
                }
 
        l-=7;
@@ -668,7 +700,12 @@ freelist_insert(SSL_CTX *ctx, int for_read, size_t sz, void *mem)
 int ssl3_setup_read_buffer(SSL *s)
        {
        unsigned char *p;
-       size_t len,align=0;
+       size_t len,align=0,headerlen;
+       
+       if (SSL_version(s) == DTLS1_VERSION || SSL_version(s) == DTLS1_BAD_VER)
+               headerlen = DTLS1_RT_HEADER_LENGTH;
+       else
+               headerlen = SSL3_RT_HEADER_LENGTH;
 
 #if defined(SSL3_ALIGN_PAYLOAD) && SSL3_ALIGN_PAYLOAD!=0
        align = (-SSL3_RT_HEADER_LENGTH)&(SSL3_ALIGN_PAYLOAD-1);
@@ -678,7 +715,7 @@ int ssl3_setup_read_buffer(SSL *s)
                {
                len = SSL3_RT_MAX_PLAIN_LENGTH
                        + SSL3_RT_MAX_ENCRYPTED_OVERHEAD
-                       + SSL3_RT_HEADER_LENGTH + align;
+                       + headerlen + align;
                if (s->options & SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER)
                        {
                        s->s3->init_extra = 1;
@@ -705,7 +742,12 @@ err:
 int ssl3_setup_write_buffer(SSL *s)
        {
        unsigned char *p;
-       size_t len,align=0;
+       size_t len,align=0,headerlen;
+
+       if (SSL_version(s) == DTLS1_VERSION || SSL_version(s) == DTLS1_BAD_VER)
+               headerlen = DTLS1_RT_HEADER_LENGTH + 1;
+       else
+               headerlen = SSL3_RT_HEADER_LENGTH;
 
 #if defined(SSL3_ALIGN_PAYLOAD) && SSL3_ALIGN_PAYLOAD!=0
        align = (-SSL3_RT_HEADER_LENGTH)&(SSL3_ALIGN_PAYLOAD-1);
@@ -715,13 +757,13 @@ int ssl3_setup_write_buffer(SSL *s)
                {
                len = s->max_send_fragment
                        + SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD
-                       + SSL3_RT_HEADER_LENGTH + align;
+                       + headerlen + align;
 #ifndef OPENSSL_NO_COMP
                if (!(s->options & SSL_OP_NO_COMPRESSION))
                        len += SSL3_RT_MAX_COMPRESSED_OVERHEAD;
 #endif
                if (!(s->options & SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS))
-                       len += SSL3_RT_HEADER_LENGTH + align
+                       len += headerlen + align
                                + SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD;
 
                if ((p=freelist_extract(s->ctx, 0, len)) == NULL)