Document a change I'd already made, and at the same time, correct the
[openssl.git] / ssl / s23_srvr.c
index fe8bd33ce742f9a269ab5919409da03b248b6e53..c5404ca0bcd4c015f0273f38e22ef07bffb92585 100644 (file)
  */
 
 #include <stdio.h>
+#include "ssl_locl.h"
 #include <openssl/buffer.h>
 #include <openssl/rand.h>
 #include <openssl/objects.h>
 #include <openssl/evp.h>
-#include "ssl_locl.h"
 
 static SSL_METHOD *ssl23_get_server_method(int ver);
 int ssl23_get_client_hello(SSL *s);
@@ -139,11 +139,18 @@ SSL_METHOD *SSLv23_server_method(void)
 
        if (init)
                {
-               memcpy((char *)&SSLv23_server_data,
-                       (char *)sslv23_base_method(),sizeof(SSL_METHOD));
-               SSLv23_server_data.ssl_accept=ssl23_accept;
-               SSLv23_server_data.get_ssl_method=ssl23_get_server_method;
-               init=0;
+               CRYPTO_w_lock(CRYPTO_LOCK_SSL_METHOD);
+
+               if (init)
+                       {
+                       memcpy((char *)&SSLv23_server_data,
+                               (char *)sslv23_base_method(),sizeof(SSL_METHOD));
+                       SSLv23_server_data.ssl_accept=ssl23_accept;
+                       SSLv23_server_data.get_ssl_method=ssl23_get_server_method;
+                       init=0;
+                       }
+
+               CRYPTO_w_unlock(CRYPTO_LOCK_SSL_METHOD);
                }
        return(&SSLv23_server_data);
        }
@@ -152,7 +159,7 @@ int ssl23_accept(SSL *s)
        {
        BUF_MEM *buf;
        unsigned long Time=time(NULL);
-       void (*cb)()=NULL;
+       void (*cb)(const SSL *ssl,int type,int val)=NULL;
        int ret= -1;
        int new_state,state;
 
@@ -232,9 +239,9 @@ int ssl23_accept(SSL *s)
                        }
                }
 end:
+       s->in_handshake--;
        if (cb != NULL)
                cb(s,SSL_CB_ACCEPT_EXIT,ret);
-       s->in_handshake--;
        return(ret);
        }
 
@@ -339,17 +346,22 @@ int ssl23_get_client_hello(SSL *s)
                        /* We must look at client_version inside the Client Hello message
                         * 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.
-                        */
+                        * Client Hello message, this would be difficult, and we'd have
+                        * to read more records to find out.
+                        * No known SSL 3.0 client fragments ClientHello like this,
+                        * so we simply assume TLS 1.0 to avoid protocol version downgrade
+                        * attacks. */
                        if (p[3] == 0 && p[4] < 6)
                                {
+#if 0
                                SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO,SSL_R_RECORD_TOO_SMALL);
                                goto err;
+#else
+                               v[1] = TLS1_VERSION_MINOR;
+#endif
                                }
-                       v[1]=p[10]; /* minor version according to client_version */
+                       else
+                               v[1]=p[10]; /* minor version according to client_version */
                        if (v[1] >= TLS1_VERSION_MINOR)
                                {
                                if (!(s->options & SSL_OP_NO_TLSv1))
@@ -415,7 +427,9 @@ int ssl23_get_client_hello(SSL *s)
                j=ssl23_read_bytes(s,n+2);
                if (j <= 0) return(j);
 
-               ssl3_finish_mac(s,&(s->packet[2]),s->packet_length-2);
+               ssl3_finish_mac(s, s->packet+2, s->packet_length-2);
+               if (s->msg_callback)
+                       s->msg_callback(0, SSL2_VERSION, 0, s->packet+2, s->packet_length-2, s, s->msg_callback_arg); /* CLIENT-HELLO */
 
                p=s->packet;
                p+=5;
@@ -466,7 +480,7 @@ int ssl23_get_client_hello(SSL *s)
                *(d++)=1;
                *(d++)=0;
                
-               i=(d-(unsigned char *)s->init_buf->data);
+               i = (d-(unsigned char *)s->init_buf->data) - 4;
                l2n3((long)i, d_len);
 
                /* get the data reused from the init_buf */
@@ -498,7 +512,7 @@ int ssl23_get_client_hello(SSL *s)
 
                if (s->s3 != NULL) ssl3_free(s);
 
-               if (!BUF_MEM_grow(s->init_buf,
+               if (!BUF_MEM_grow_clean(s->init_buf,
                        SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER))
                        {
                        goto err;