Change ssl3_get_message and the functions using it so that complete
[openssl.git] / ssl / s23_srvr.c
index 930769be0d1971637f92894eaf6b9f71eed39639..342d145c233cfe93fbcaa6bf116edd69c9daa0c5 100644 (file)
@@ -67,7 +67,7 @@ static SSL_METHOD *ssl23_get_server_method(int ver);
 int ssl23_get_client_hello(SSL *s);
 static SSL_METHOD *ssl23_get_server_method(int ver)
        {
-#ifndef NO_SSL2
+#ifndef OPENSSL_NO_SSL2
        if (ver == SSL2_VERSION)
                return(SSLv2_server_method());
 #endif
@@ -202,13 +202,13 @@ int ssl23_get_client_hello(SSL *s)
                             *  9/10  client_version  /
                             */
        char *buf= &(buf_space[0]);
-       unsigned char *p,*d,*dd;
+       unsigned char *p,*d,*d_len,*dd;
        unsigned int i;
        unsigned int csl,sil,cl;
        int n=0,j;
        int type=0;
        int v[2];
-#ifndef NO_RSA
+#ifndef OPENSSL_NO_RSA
        int use_sslv2_strong=0;
 #endif
 
@@ -270,72 +270,6 @@ int ssl23_get_client_hello(SSL *s)
                                else if (!(s->options & SSL_OP_NO_SSLv2))
                                        type=1;
 
-                               if (s->options & SSL_OP_NON_EXPORT_FIRST)
-                                       /* Not only utterly confusing, but broken
-                                        * ('fractured programming'?) -- the details
-                                        * of this block nearly make it work
-                                        * as intended in this environment, but on one
-                                        * of the fine points (w.r.t. restarts) it fails.
-                                        * The obvious fix would be even more devastating
-                                        * to program structure; if you want the functionality,
-                                        * throw this away and implement it in a way
-                                        * that makes sense */
-                                       {
-#if 0
-                                       STACK_OF(SSL_CIPHER) *sk;
-                                       SSL_CIPHER *c;
-                                       int ne2,ne3;
-
-                                       j=((p[0]&0x7f)<<8)|p[1];
-                                       if (j > (1024*4))
-                                               {
-                                               SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO,SSL_R_RECORD_TOO_LARGE);
-                                               goto err;
-                                               }
-
-                                       n=ssl23_read_bytes(s,j+2);
-                                       if (n <= 0) return(n);
-                                       p=s->packet;
-
-                                       if ((buf=OPENSSL_malloc(n)) == NULL)
-                                               {
-                                               SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO,ERR_R_MALLOC_FAILURE);
-                                               goto err;
-                                               }
-                                       memcpy(buf,p,n);
-
-                                       p+=5;
-                                       n2s(p,csl);
-                                       p+=4;
-
-                                       sk=ssl_bytes_to_cipher_list(
-                                               s,p,csl,NULL);
-                                       if (sk != NULL)
-                                               {
-                                               ne2=ne3=0;
-                                               for (j=0; j<sk_SSL_CIPHER_num(sk); j++)
-                                                       {
-                                                       c=sk_SSL_CIPHER_value(sk,j);
-                                                       if (!SSL_C_IS_EXPORT(c))
-                                                               {
-                                                               if ((c->id>>24L) == 2L)
-                                                                       ne2=1;
-                                                               else
-                                                                       ne3=1;
-                                                               }
-                                                       }
-                                               if (ne2 && !ne3)
-                                                       {
-                                                       type=1;
-                                                       use_sslv2_strong=1;
-                                                       goto next_bit;
-                                                       }
-                                               }
-#else
-                                       SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO,SSL_R_UNSUPPORTED_OPTION);
-                                       goto err;
-#endif
-                                       }
                                }
                        }
                else if ((p[0] == SSL3_RT_HANDSHAKE) &&
@@ -348,16 +282,21 @@ int ssl23_get_client_hello(SSL *s)
                         * SSLv3 or tls1 header
                         */
                        
-                       v[0]=p[1]; /* major version */
+                       v[0]=p[1]; /* major version (= SSL3_VERSION_MAJOR) */
                        /* We must look at client_version inside the Client Hello message
-                        * to get the correct minor version: */
-                       v[1]=p[10];
-                       /* However if we have only a pathologically small fragment of the
-                        * Client Hello message, we simply use the version from the
-                        * record header -- this is incorrect but unlikely to fail in
-                        * practice */
+                        * to get the correct minor version.
+                        * However if we have only a pathologically small fragment of the
+                        * Client Hello message, this would be difficult, we'd have
+                        * to read at least one additional record to find out.
+                        * This doesn't usually happen in real life, so we just complain
+                        * for now.
+                        */
                        if (p[3] == 0 && p[4] < 6)
-                               v[1]=p[2];
+                               {
+                               SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO,SSL_R_RECORD_TOO_SMALL);
+                               goto err;
+                               }
+                       v[1]=p[10]; /* minor version according to client_version */
                        if (v[1] >= TLS1_VERSION_MINOR)
                                {
                                if (!(s->options & SSL_OP_NO_TLSv1))
@@ -426,6 +365,14 @@ int ssl23_get_client_hello(SSL *s)
                        goto err;
                        }
 
+               /* record header: version ... */
+               *(d++) = SSL3_VERSION_MAJOR; /* == v[0] */
+               *(d++) = v[1];
+               /* ... and length (actual value will be written later) */
+               d_len = d++;
+               d++;
+
+               /* client_version */
                *(d++) = SSL3_VERSION_MAJOR; /* == v[0] */
                *(d++) = v[1];
 
@@ -457,6 +404,7 @@ int ssl23_get_client_hello(SSL *s)
                *(d++)=0;
                
                i=(d-(unsigned char *)s->init_buf->data);
+               s2n(i, d_len);
 
                /* get the data reused from the init_buf */
                s->s3->tmp.reuse_message=1;
@@ -469,7 +417,7 @@ int ssl23_get_client_hello(SSL *s)
 
        if (type == 1)
                {
-#ifdef NO_SSL2
+#ifdef OPENSSL_NO_SSL2
                SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO,SSL_R_UNSUPPORTED_PROTOCOL);
                goto err;
 #else
@@ -495,9 +443,12 @@ int ssl23_get_client_hello(SSL *s)
 
                s->state=SSL2_ST_GET_CLIENT_HELLO_A;
                if ((s->options & SSL_OP_MSIE_SSLV2_RSA_PADDING) ||
-                       use_sslv2_strong)
+                       use_sslv2_strong ||
+                       (s->options & SSL_OP_NO_TLSv1 && s->options & SSL_OP_NO_SSLv3))
                        s->s2->ssl2_rollback=0;
                else
+                       /* reject SSL 2.0 session if client supports SSL 3.0 or TLS 1.0
+                        * (SSL 3.0 draft/RFC 2246, App. E.2) */
                        s->s2->ssl2_rollback=1;
 
                /* setup the n bytes we have read so we get them from