Server side version negotiation rewrite
authorMatt Caswell <matt@openssl.org>
Fri, 27 Mar 2015 23:01:51 +0000 (23:01 +0000)
committerMatt Caswell <matt@openssl.org>
Sat, 16 May 2015 08:19:56 +0000 (09:19 +0100)
This commit changes the way that we do server side protocol version
negotiation. Previously we had a whole set of code that had an "up front"
state machine dedicated to the negotiating the protocol version. This adds
significant complexity to the state machine. Historically the justification
for doing this was the support of SSLv2 which works quite differently to
SSLv3+. However, we have now removed support for SSLv2 so there is little
reason to maintain this complexity.

The one slight difficulty is that, although we no longer support SSLv2, we
do still support an SSLv3+ ClientHello in an SSLv2 backward compatible
ClientHello format. This is generally only used by legacy clients. This
commit adds support within the SSLv3 code for these legacy format
ClientHellos.

Server side version negotiation now works in much the same was as DTLS,
i.e. we introduce the concept of TLS_ANY_VERSION. If s->version is set to
that then when a ClientHello is received it will work out the most
appropriate version to respond with. Also, SSLv23_method and
SSLv23_server_method have been replaced with TLS_method and
TLS_server_method respectively. The old SSLv23* names still exist as
macros pointing at the new name, although they are deprecated.

Subsequent commits will look at client side version negotiation, as well of
removal of the old s23* code.

Reviewed-by: Kurt Roeckx <kurt@openssl.org>
26 files changed:
apps/ciphers.c
apps/s_server.c
crypto/threads/mttest.c
demos/bio/saccept.c
demos/bio/server-arg.c
demos/bio/server-conf.c
demos/easy_tls/easy-tls.c
demos/ssl/serv.cpp
demos/state_machine/state_machine.c
include/openssl/ssl.h
include/openssl/tls1.h
ssl/record/rec_layer_s3.c
ssl/record/record.h
ssl/record/record_locl.h
ssl/record/ssl3_record.c
ssl/s23_meth.c
ssl/s23_srvr.c
ssl/s3_both.c
ssl/s3_lib.c
ssl/s3_srvr.c
ssl/ssl_lib.c
ssl/ssl_locl.h
ssl/t1_meth.c
ssl/t1_srvr.c
test/ssltest.c
util/ssleay.num

index 232fd602fd250b5a2e2bde586531397c0c696527..47132fdfc51e68ae41defdd2ac5058113e8ae526 100644 (file)
@@ -94,7 +94,7 @@ int ciphers_main(int argc, char **argv)
     SSL_CTX *ctx = NULL;
     SSL *ssl = NULL;
     STACK_OF(SSL_CIPHER) *sk = NULL;
     SSL_CTX *ctx = NULL;
     SSL *ssl = NULL;
     STACK_OF(SSL_CIPHER) *sk = NULL;
-    const SSL_METHOD *meth = SSLv23_server_method();
+    const SSL_METHOD *meth = TLS_server_method();
     int ret = 1, i, verbose = 0, Verbose = 0, use_supported = 0;
 #ifndef OPENSSL_NO_SSL_TRACE
     int stdname = 0;
     int ret = 1, i, verbose = 0, Verbose = 0, use_supported = 0;
 #ifndef OPENSSL_NO_SSL_TRACE
     int stdname = 0;
index 2ef902a5315164251c906e0c88f27c531eb258cb..61d13f3e0a5705cb6b3d8afcd76934688b1bbd90 100644 (file)
@@ -987,7 +987,7 @@ int s_server_main(int argc, char *argv[])
     ENGINE *e = NULL;
     EVP_PKEY *s_key = NULL, *s_dkey = NULL;
     SSL_CONF_CTX *cctx = NULL;
     ENGINE *e = NULL;
     EVP_PKEY *s_key = NULL, *s_dkey = NULL;
     SSL_CONF_CTX *cctx = NULL;
-    const SSL_METHOD *meth = SSLv23_server_method();
+    const SSL_METHOD *meth = TLS_server_method();
     SSL_EXCERT *exc = NULL;
     STACK_OF(OPENSSL_STRING) *ssl_args = NULL;
     STACK_OF(X509) *s_chain = NULL, *s_dchain = NULL;
     SSL_EXCERT *exc = NULL;
     STACK_OF(OPENSSL_STRING) *ssl_args = NULL;
     STACK_OF(X509) *s_chain = NULL, *s_dchain = NULL;
index f6f8df289cd338b1b93508bef20d62d5088747d7..3218c32924a9cfdb3ca09d67152873e33827e15d 100644 (file)
@@ -194,7 +194,7 @@ int main(int argc, char *argv[])
     SSL_CTX *c_ctx = NULL;
     char *scert = TEST_SERVER_CERT;
     char *ccert = TEST_CLIENT_CERT;
     SSL_CTX *c_ctx = NULL;
     char *scert = TEST_SERVER_CERT;
     char *ccert = TEST_CLIENT_CERT;
-    SSL_METHOD *ssl_method = SSLv23_method();
+    SSL_METHOD *ssl_method = TLS_method();
 
     RAND_seed(rnd_seed, sizeof rnd_seed);
 
 
     RAND_seed(rnd_seed, sizeof rnd_seed);
 
index 505d98b68f8dd3d081c00d168969c731b7890364..0d173aa039a700cef5882704cc5373ca49b775e6 100644 (file)
@@ -45,7 +45,7 @@ int main(int argc, char *argv[])
     /* Add ciphers and message digests */
     OpenSSL_add_ssl_algorithms();
 
     /* Add ciphers and message digests */
     OpenSSL_add_ssl_algorithms();
 
-    ctx = SSL_CTX_new(SSLv23_server_method());
+    ctx = SSL_CTX_new(TLS_server_method());
     if (!SSL_CTX_use_certificate_file(ctx, CERT_FILE, SSL_FILETYPE_PEM))
         goto err;
     if (!SSL_CTX_use_PrivateKey_file(ctx, CERT_FILE, SSL_FILETYPE_PEM))
     if (!SSL_CTX_use_certificate_file(ctx, CERT_FILE, SSL_FILETYPE_PEM))
         goto err;
     if (!SSL_CTX_use_PrivateKey_file(ctx, CERT_FILE, SSL_FILETYPE_PEM))
index b188f6a4edebfa3f0e4de6deb4e6381c917c5574..242ca6c0afcb310bf897213e45ef68cadb3a5cd3 100644 (file)
@@ -29,7 +29,7 @@ int main(int argc, char *argv[])
     /* Add ciphers and message digests */
     OpenSSL_add_ssl_algorithms();
 
     /* Add ciphers and message digests */
     OpenSSL_add_ssl_algorithms();
 
-    ctx = SSL_CTX_new(SSLv23_server_method());
+    ctx = SSL_CTX_new(TLS_server_method());
 
     cctx = SSL_CONF_CTX_new();
     SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_SERVER);
 
     cctx = SSL_CONF_CTX_new();
     SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_SERVER);
index cc9fe8a828751e204fb3f3a0c0ee8bc7f8b3f3c6..bf3dd067e52c277fba61e6af34a47caeb7ac3f5f 100644 (file)
@@ -49,7 +49,7 @@ int main(int argc, char *argv[])
         goto err;
     }
 
         goto err;
     }
 
-    ctx = SSL_CTX_new(SSLv23_server_method());
+    ctx = SSL_CTX_new(TLS_server_method());
     cctx = SSL_CONF_CTX_new();
     SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_SERVER);
     SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_CERTIFICATE);
     cctx = SSL_CONF_CTX_new();
     SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_SERVER);
     SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_CERTIFICATE);
index 9346720daeb1f551af1de25257f431f50475f3db..2befb657a0bc2e3c5f859b0fed97581380d193f6 100644 (file)
@@ -668,7 +668,7 @@ SSL_CTX *tls_create_ctx(struct tls_create_ctx_args a, void *apparg)
 
     ret =
         SSL_CTX_new((a.client_p ? SSLv23_client_method :
 
     ret =
         SSL_CTX_new((a.client_p ? SSLv23_client_method :
-                     SSLv23_server_method) ());
+                     TLS_server_method) ());
 
     if (ret == NULL)
         goto err;
 
     if (ret == NULL)
         goto err;
index 6d4cefd5d02424ba159522c22d42fe6b3a05dc5d..9cb77f8275fbf9932ee3e9524a3ef1fb6ccd33c4 100644 (file)
@@ -55,7 +55,7 @@ void main ()
 
   SSL_load_error_strings();
   SSLeay_add_ssl_algorithms();
 
   SSL_load_error_strings();
   SSLeay_add_ssl_algorithms();
-  meth = SSLv23_server_method();
+  meth = TLS_server_method();
   ctx = SSL_CTX_new (meth);
   if (!ctx) {
     ERR_print_errors_fp(stderr);
   ctx = SSL_CTX_new (meth);
   if (!ctx) {
     ERR_print_errors_fp(stderr);
index 1dd8c2be22c7c7ab0d507e297ceaaeb24e01dcc2..98802a12eca30aacbf917fca288ab6dda6040858 100644 (file)
@@ -119,7 +119,7 @@ SSLStateMachine *SSLStateMachine_new(const char *szCertificateFile,
 
     die_unless(pMachine);
 
 
     die_unless(pMachine);
 
-    pMachine->pCtx = SSL_CTX_new(SSLv23_server_method());
+    pMachine->pCtx = SSL_CTX_new(TLS_server_method());
     die_unless(pMachine->pCtx);
 
     n = SSL_CTX_use_certificate_file(pMachine->pCtx, szCertificateFile,
     die_unless(pMachine->pCtx);
 
     n = SSL_CTX_use_certificate_file(pMachine->pCtx, szCertificateFile,
index 27e44cc20fe7c42dc6ad9e08d223d18573d1fcf4..f169fcd2a9c5be8a3706a37c135c90dcde7b9cb7 100644 (file)
@@ -1562,13 +1562,18 @@ __owur const SSL_METHOD *SSLv3_server_method(void); /* SSLv3 */
 __owur const SSL_METHOD *SSLv3_client_method(void); /* SSLv3 */
 # endif
 
 __owur const SSL_METHOD *SSLv3_client_method(void); /* SSLv3 */
 # endif
 
-__owur const SSL_METHOD *SSLv23_method(void); /* Negotiate highest available SSL/TLS
-                                        * version */
-__owur const SSL_METHOD *SSLv23_server_method(void); /* Negotiate highest available
-                                               * SSL/TLS version */
+#ifdef OPENSSL_USE_DEPRECATED
+#define SSLv23_method           TLS_method
+#define SSLv23_server_method    TLS_server_method
+#endif
+/* This next one will be deprecated in a subsequent commit */
 __owur const SSL_METHOD *SSLv23_client_method(void); /* Negotiate highest available
                                                * SSL/TLS version */
 
 __owur const SSL_METHOD *SSLv23_client_method(void); /* Negotiate highest available
                                                * SSL/TLS version */
 
+/* Negotiate highest available SSL/TLS version */
+__owur const SSL_METHOD *TLS_method(void);
+__owur const SSL_METHOD *TLS_server_method(void);
+
 __owur const SSL_METHOD *TLSv1_method(void); /* TLSv1.0 */
 __owur const SSL_METHOD *TLSv1_server_method(void); /* TLSv1.0 */
 __owur const SSL_METHOD *TLSv1_client_method(void); /* TLSv1.0 */
 __owur const SSL_METHOD *TLSv1_method(void); /* TLSv1.0 */
 __owur const SSL_METHOD *TLSv1_server_method(void); /* TLSv1.0 */
 __owur const SSL_METHOD *TLSv1_client_method(void); /* TLSv1.0 */
index e1beaf3bbd0a67a87acaca9a276d75e41f195678..d10739690e72e7083deea170cd922fedbb6ba5b8 100644 (file)
@@ -167,6 +167,9 @@ extern "C" {
 # define TLS1_2_VERSION                  0x0303
 # define TLS_MAX_VERSION                 TLS1_2_VERSION
 
 # define TLS1_2_VERSION                  0x0303
 # define TLS_MAX_VERSION                 TLS1_2_VERSION
 
+/* Special value for method supporting multiple versions */
+# define TLS_ANY_VERSION                 0x10000
+
 # define TLS1_VERSION_MAJOR              0x03
 # define TLS1_VERSION_MINOR              0x01
 
 # define TLS1_VERSION_MAJOR              0x03
 # define TLS1_VERSION_MINOR              0x01
 
index eccb5176ba88f798c13e49bc58076187beb6498e..97f6e900c563af79e544486b8f82c7989729edbe 100644 (file)
@@ -1109,6 +1109,21 @@ int ssl3_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek)
      * then it was unexpected (Hello Request or Client Hello).
      */
 
      * then it was unexpected (Hello Request or Client Hello).
      */
 
+    /*
+     * Lets just double check that we've not got an SSLv2 record
+     */
+    if (rr->rec_version == SSL2_VERSION) {
+        /*
+         * Should never happen. ssl3_get_record() should only give us an SSLv2
+         * record back if this is the first packet and we are looking for an
+         * initial ClientHello. Therefore |type| should always be equal to
+         * |rr->type|. If not then something has gone horribly wrong
+         */
+        al = SSL_AD_INTERNAL_ERROR;
+        SSLerr(SSL_F_SSL3_READ_BYTES, ERR_R_INTERNAL_ERROR);
+        goto f_err;
+    }
+
     /*
      * In case of record types for which we have 'fragment' storage, fill
      * that so that we can process the data at a fixed place.
     /*
      * In case of record types for which we have 'fragment' storage, fill
      * that so that we can process the data at a fixed place.
@@ -1464,4 +1479,12 @@ void ssl3_record_sequence_update(unsigned char *seq)
     }
 }
 
     }
 }
 
+int RECORD_LAYER_is_sslv2_record(RECORD_LAYER *rl)
+{
+    return SSL3_RECORD_is_sslv2_record(&rl->rrec);
+}
 
 
+int RECORD_LAYER_get_rrec_length(RECORD_LAYER *rl)
+{
+    return SSL3_RECORD_get_length(&rl->rrec);
+}
index 6bccb71d837583c25027779468d5f23cc3d8cff5..a778998196d443f37bd76cc3824b22e29ad51eec 100644 (file)
@@ -132,6 +132,10 @@ typedef struct ssl3_buffer_st {
 #define SEQ_NUM_SIZE                            8
 
 typedef struct ssl3_record_st {
 #define SEQ_NUM_SIZE                            8
 
 typedef struct ssl3_record_st {
+    /* Record layer version */
+    /* r */
+    int rec_version;
+
     /* type of record */
     /* r */
     int type;
     /* type of record */
     /* r */
     int type;
@@ -298,6 +302,8 @@ typedef struct record_layer_st {
  *                                                                           *
  *****************************************************************************/
 
  *                                                                           *
  *****************************************************************************/
 
+#define MIN_SSL2_RECORD_LEN     9
+
 #define RECORD_LAYER_set_read_ahead(rl, ra)     ((rl)->read_ahead = (ra))
 #define RECORD_LAYER_get_read_ahead(rl)         ((rl)->read_ahead)
 #define RECORD_LAYER_get_packet(rl)             ((rl)->packet)
 #define RECORD_LAYER_set_read_ahead(rl, ra)     ((rl)->read_ahead = (ra))
 #define RECORD_LAYER_get_read_ahead(rl)         ((rl)->read_ahead)
 #define RECORD_LAYER_get_packet(rl)             ((rl)->packet)
@@ -319,6 +325,8 @@ void RECORD_LAYER_dup(RECORD_LAYER *dst, RECORD_LAYER *src);
 void RECORD_LAYER_reset_read_sequence(RECORD_LAYER *rl);
 void RECORD_LAYER_reset_write_sequence(RECORD_LAYER *rl);
 int RECORD_LAYER_setup_comp_buffer(RECORD_LAYER *rl);
 void RECORD_LAYER_reset_read_sequence(RECORD_LAYER *rl);
 void RECORD_LAYER_reset_write_sequence(RECORD_LAYER *rl);
 int RECORD_LAYER_setup_comp_buffer(RECORD_LAYER *rl);
+int RECORD_LAYER_is_sslv2_record(RECORD_LAYER *rl);
+int RECORD_LAYER_get_rrec_length(RECORD_LAYER *rl);
 __owur int ssl3_pending(const SSL *s);
 __owur int ssl23_read_bytes(SSL *s, int n);
 __owur int ssl23_write_bytes(SSL *s);
 __owur int ssl3_pending(const SSL *s);
 __owur int ssl23_read_bytes(SSL *s, int n);
 __owur int ssl23_write_bytes(SSL *s);
index 72f8e55f3b01cdc4e3eab8ea21aed23717cc2e6d..b2222d7c22dddfac70deee6a346ed628b8b7f4f9 100644 (file)
@@ -186,6 +186,8 @@ int ssl3_release_write_buffer(SSL *s);
 #define SSL3_RECORD_set_off(r, o)               ((r)->off = (o))
 #define SSL3_RECORD_add_off(r, o)               ((r)->off += (o))
 #define SSL3_RECORD_get_epoch(r)                ((r)->epoch)
 #define SSL3_RECORD_set_off(r, o)               ((r)->off = (o))
 #define SSL3_RECORD_add_off(r, o)               ((r)->off += (o))
 #define SSL3_RECORD_get_epoch(r)                ((r)->epoch)
+#define SSL3_RECORD_is_sslv2_record(r) \
+            ((r)->rec_version == SSL2_VERSION)
 
 void SSL3_RECORD_clear(SSL3_RECORD *r);
 void SSL3_RECORD_release(SSL3_RECORD *r);
 
 void SSL3_RECORD_clear(SSL3_RECORD *r);
 void SSL3_RECORD_release(SSL3_RECORD *r);
index 032812772f04b17403a556798d20c7786d0c32bc..190abd26e857c95a27b860dbfbe49b0a3f23ae3e 100644 (file)
@@ -166,6 +166,7 @@ void SSL3_RECORD_set_seq_num(SSL3_RECORD *r, const unsigned char *seq_num)
  */
 #define MAX_EMPTY_RECORDS 32
 
  */
 #define MAX_EMPTY_RECORDS 32
 
+#define SSL2_RT_HEADER_LENGTH   2
 /*-
  * Call this to get a new input record.
  * It will return <= 0 if more data is needed, normally due to an error
 /*-
  * Call this to get a new input record.
  * It will return <= 0 if more data is needed, normally due to an error
@@ -216,71 +217,121 @@ int ssl3_get_record(SSL *s)
         RECORD_LAYER_set_rstate(&s->rlayer, SSL_ST_READ_BODY);
 
         p = RECORD_LAYER_get_packet(&s->rlayer);
         RECORD_LAYER_set_rstate(&s->rlayer, SSL_ST_READ_BODY);
 
         p = RECORD_LAYER_get_packet(&s->rlayer);
-        if (s->msg_callback)
-            s->msg_callback(0, 0, SSL3_RT_HEADER, p, 5, s,
-                            s->msg_callback_arg);
 
 
-        /* Pull apart the header into the SSL3_RECORD */
-        rr->type = *(p++);
-        ssl_major = *(p++);
-        ssl_minor = *(p++);
-        version = (ssl_major << 8) | ssl_minor;
-        n2s(p, rr->length);
+        /*
+         * Check whether this is a regular record or an SSLv2 style record. The
+         * latter is only used in an initial ClientHello for old clients.
+         */
+        if (s->first_packet && s->server && !s->read_hash && !s->enc_read_ctx
+                && (p[0] & 0x80) && (p[2] == SSL2_MT_CLIENT_HELLO)) {
+            /* SSLv2 style record */
+            if (s->msg_callback)
+                s->msg_callback(0, SSL2_VERSION, 0,  p + 2,
+                                RECORD_LAYER_get_packet_length(&s->rlayer) - 2,
+                                s, s->msg_callback_arg);
+
+            rr->type = SSL3_RT_HANDSHAKE;
+            rr->rec_version = SSL2_VERSION;
+
+            rr->length = ((p[0] & 0x7f) << 8) | p[1];
+
+            if (rr->length > SSL3_BUFFER_get_len(&s->rlayer.rbuf)
+                                    - SSL2_RT_HEADER_LENGTH) {
+                al = SSL_AD_RECORD_OVERFLOW;
+                SSLerr(SSL_F_SSL3_GET_RECORD, SSL_R_PACKET_LENGTH_TOO_LONG);
+                goto f_err;
+            }
 
 
-        /* Lets check version */
-        if (!s->first_packet) {
-            if (version != s->version) {
-                SSLerr(SSL_F_SSL3_GET_RECORD, SSL_R_WRONG_VERSION_NUMBER);
-                if ((s->version & 0xFF00) == (version & 0xFF00)
-                    && !s->enc_write_ctx && !s->write_hash)
-                    /*
-                     * Send back error using their minor version number :-)
-                     */
-                    s->version = (unsigned short)version;
-                al = SSL_AD_PROTOCOL_VERSION;
+            if (rr->length < MIN_SSL2_RECORD_LEN) {
+                al = SSL_AD_HANDSHAKE_FAILURE;
+                SSLerr(SSL_F_SSL3_GET_RECORD, SSL_R_LENGTH_TOO_SHORT);
                 goto f_err;
             }
                 goto f_err;
             }
-        }
+        } else {
+            /* SSLv3+ style record */
+            if (s->msg_callback)
+                s->msg_callback(0, 0, SSL3_RT_HEADER, p, 5, s,
+                                s->msg_callback_arg);
+
+            /* Pull apart the header into the SSL3_RECORD */
+            rr->type = *(p++);
+            ssl_major = *(p++);
+            ssl_minor = *(p++);
+            version = (ssl_major << 8) | ssl_minor;
+            rr->rec_version = version;
+            n2s(p, rr->length);
+
+            /* Lets check version */
+            if (!s->first_packet) {
+                if (version != s->version) {
+                    SSLerr(SSL_F_SSL3_GET_RECORD, SSL_R_WRONG_VERSION_NUMBER);
+                    if ((s->version & 0xFF00) == (version & 0xFF00)
+                        && !s->enc_write_ctx && !s->write_hash)
+                        /*
+                         * Send back error using their minor version number :-)
+                         */
+                        s->version = (unsigned short)version;
+                    al = SSL_AD_PROTOCOL_VERSION;
+                    goto f_err;
+                }
+            }
 
 
-        if ((version >> 8) != SSL3_VERSION_MAJOR) {
-            SSLerr(SSL_F_SSL3_GET_RECORD, SSL_R_WRONG_VERSION_NUMBER);
-            goto err;
-        }
+            if ((version >> 8) != SSL3_VERSION_MAJOR) {
+                SSLerr(SSL_F_SSL3_GET_RECORD, SSL_R_WRONG_VERSION_NUMBER);
+                goto err;
+            }
 
 
-        if (rr->length >
-                SSL3_BUFFER_get_len(&s->rlayer.rbuf)
-                - SSL3_RT_HEADER_LENGTH) {
-            al = SSL_AD_RECORD_OVERFLOW;
-            SSLerr(SSL_F_SSL3_GET_RECORD, SSL_R_PACKET_LENGTH_TOO_LONG);
-            goto f_err;
+            if (rr->length >
+                    SSL3_BUFFER_get_len(&s->rlayer.rbuf)
+                    - SSL3_RT_HEADER_LENGTH) {
+                al = SSL_AD_RECORD_OVERFLOW;
+                SSLerr(SSL_F_SSL3_GET_RECORD, SSL_R_PACKET_LENGTH_TOO_LONG);
+                goto f_err;
+            }
         }
 
         /* now s->rlayer.rstate == SSL_ST_READ_BODY */
     }
 
         }
 
         /* now s->rlayer.rstate == SSL_ST_READ_BODY */
     }
 
-    /* s->rlayer.rstate == SSL_ST_READ_BODY, get and decode the data */
-
-    if (rr->length >
-        RECORD_LAYER_get_packet_length(&s->rlayer) - SSL3_RT_HEADER_LENGTH) {
-        /* now s->packet_length == SSL3_RT_HEADER_LENGTH */
+    /*
+     * s->rlayer.rstate == SSL_ST_READ_BODY, get and decode the data.
+     * Calculate how much more data we need to read for the rest of the record
+     */
+    if (rr->rec_version == SSL2_VERSION) {
+        i = rr->length + SSL2_RT_HEADER_LENGTH - SSL3_RT_HEADER_LENGTH;
+    } else {
         i = rr->length;
         i = rr->length;
+    }
+    if (i > 0) {
+        /* now s->packet_length == SSL3_RT_HEADER_LENGTH */
+
         n = ssl3_read_n(s, i, i, 1);
         if (n <= 0)
             return (n);         /* error or non-blocking io */
         /*
         n = ssl3_read_n(s, i, i, 1);
         if (n <= 0)
             return (n);         /* error or non-blocking io */
         /*
-         * now n == rr->length, and s->packet_length == SSL3_RT_HEADER_LENGTH
-         * + rr->length
+         * now n == rr->length, and
+         * s->packet_length == SSL3_RT_HEADER_LENGTH + rr->length
+         * or
+         * s->packet_length == SSL2_RT_HEADER_LENGTH + rr->length
+         * (if SSLv2 packet)
          */
          */
+    } else {
+        n = 0;
     }
 
     /* set state for later operations */
     RECORD_LAYER_set_rstate(&s->rlayer, SSL_ST_READ_HEADER);
 
     /*
     }
 
     /* set state for later operations */
     RECORD_LAYER_set_rstate(&s->rlayer, SSL_ST_READ_HEADER);
 
     /*
-     * At this point, s->packet_length == SSL3_RT_HEADER_LNGTH + rr->length,
+     * At this point, s->packet_length == SSL3_RT_HEADER_LENGTH + rr->length,
+     * or s->packet_length == SSL2_RT_HEADER_LENGTH + rr->length
      * and we have that many bytes in s->packet
      */
      * and we have that many bytes in s->packet
      */
-    rr->input = &(RECORD_LAYER_get_packet(&s->rlayer)[SSL3_RT_HEADER_LENGTH]);
+    if(rr->rec_version == SSL2_VERSION) {
+        rr->input = &(RECORD_LAYER_get_packet(&s->rlayer)[SSL2_RT_HEADER_LENGTH]);
+    } else {
+        rr->input = &(RECORD_LAYER_get_packet(&s->rlayer)[SSL3_RT_HEADER_LENGTH]);
+    }
 
     /*
      * ok, we can now read from 's->packet' data into 'rr' rr->input points
 
     /*
      * ok, we can now read from 's->packet' data into 'rr' rr->input points
index 757c5a9dc9288cef83c42b385d10f893d5a54aab..6080fba1501a4fdcf55998fdfa30a97d49ff0bb2 100644 (file)
@@ -60,6 +60,7 @@
 #include <openssl/objects.h>
 #include "ssl_locl.h"
 
 #include <openssl/objects.h>
 #include "ssl_locl.h"
 
+/*
 static const SSL_METHOD *ssl23_get_method(int ver);
 static const SSL_METHOD *ssl23_get_method(int ver)
 {
 static const SSL_METHOD *ssl23_get_method(int ver);
 static const SSL_METHOD *ssl23_get_method(int ver)
 {
@@ -76,7 +77,5 @@ static const SSL_METHOD *ssl23_get_method(int ver)
         return (TLSv1_2_method());
     else
         return (NULL);
         return (TLSv1_2_method());
     else
         return (NULL);
-}
+}*/
 
 
-IMPLEMENT_ssl23_meth_func(SSLv23_method,
-                          ssl23_accept, ssl23_connect, ssl23_get_method)
index 50d634e265c4ace670026675c6bfe0fd7f29cd68..58b89a6c93ea1c783315c3f1fbd4ad0be82dd35d 100644 (file)
@@ -134,9 +134,6 @@ static const SSL_METHOD *ssl23_get_server_method(int ver)
         return (NULL);
 }
 
         return (NULL);
 }
 
-IMPLEMENT_ssl23_meth_func(SSLv23_server_method,
-                          ssl23_accept,
-                          ssl_undefined_function, ssl23_get_server_method)
 
 int ssl23_accept(SSL *s)
 {
 
 int ssl23_accept(SSL *s)
 {
index bf5e8c7c2da42c27478ab80f79ea166a3c9b2dc8..193270b3157e1793bf56e980211b59982012f538 100644 (file)
@@ -356,7 +356,7 @@ long ssl3_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok)
         }
         *ok = 1;
         s->state = stn;
         }
         *ok = 1;
         s->state = stn;
-        s->init_msg = s->init_buf->data + 4;
+        s->init_msg = s->init_buf->data + SSL3_HM_HEADER_LENGTH;
         s->init_num = (int)s->s3->tmp.message_size;
         return s->init_num;
     }
         s->init_num = (int)s->s3->tmp.message_size;
         return s->init_num;
     }
@@ -367,10 +367,9 @@ long ssl3_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok)
         int skip_message;
 
         do {
         int skip_message;
 
         do {
-            while (s->init_num < 4) {
+            while (s->init_num < SSL3_HM_HEADER_LENGTH) {
                 i = s->method->ssl_read_bytes(s, SSL3_RT_HANDSHAKE,
                 i = s->method->ssl_read_bytes(s, SSL3_RT_HANDSHAKE,
-                                              &p[s->init_num],
-                                              4 - s->init_num, 0);
+                    &p[s->init_num], SSL3_HM_HEADER_LENGTH - s->init_num, 0);
                 if (i <= 0) {
                     s->rwstate = SSL_READING;
                     *ok = 0;
                 if (i <= 0) {
                     s->rwstate = SSL_READING;
                     *ok = 0;
@@ -409,26 +408,49 @@ long ssl3_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok)
 
         s->s3->tmp.message_type = *(p++);
 
 
         s->s3->tmp.message_type = *(p++);
 
-        n2l3(p, l);
-        if (l > (unsigned long)max) {
-            al = SSL_AD_ILLEGAL_PARAMETER;
-            SSLerr(SSL_F_SSL3_GET_MESSAGE, SSL_R_EXCESSIVE_MESSAGE_SIZE);
-            goto f_err;
-        }
-        if (l > (INT_MAX - 4)) { /* BUF_MEM_grow takes an 'int' parameter */
-            al = SSL_AD_ILLEGAL_PARAMETER;
-            SSLerr(SSL_F_SSL3_GET_MESSAGE, SSL_R_EXCESSIVE_MESSAGE_SIZE);
-            goto f_err;
-        }
-        if (l && !BUF_MEM_grow_clean(s->init_buf, (int)l + 4)) {
-            SSLerr(SSL_F_SSL3_GET_MESSAGE, ERR_R_BUF_LIB);
-            goto err;
-        }
-        s->s3->tmp.message_size = l;
-        s->state = stn;
+        if(RECORD_LAYER_is_sslv2_record(&s->rlayer)) {
+            /*
+             * Only happens with SSLv3+ in an SSLv2 backward compatible
+             * ClientHello
+             */
+             /*
+              * Total message size is the remaining record bytes to read
+              * plus the SSL3_HM_HEADER_LENGTH bytes that we already read
+              */
+            l = RECORD_LAYER_get_rrec_length(&s->rlayer)
+                + SSL3_HM_HEADER_LENGTH;
+            if (l && !BUF_MEM_grow_clean(s->init_buf, (int)l)) {
+                SSLerr(SSL_F_SSL3_GET_MESSAGE, ERR_R_BUF_LIB);
+                goto err;
+            }
+            s->s3->tmp.message_size = l;
+            s->state = stn;
 
 
-        s->init_msg = s->init_buf->data + 4;
-        s->init_num = 0;
+            s->init_msg = s->init_buf->data;
+            s->init_num = SSL3_HM_HEADER_LENGTH;
+        } else {
+            n2l3(p, l);
+            if (l > (unsigned long)max) {
+                al = SSL_AD_ILLEGAL_PARAMETER;
+                SSLerr(SSL_F_SSL3_GET_MESSAGE, SSL_R_EXCESSIVE_MESSAGE_SIZE);
+                goto f_err;
+            }
+            /* BUF_MEM_grow takes an 'int' parameter */
+            if (l > (INT_MAX - SSL3_HM_HEADER_LENGTH)) {
+                al = SSL_AD_ILLEGAL_PARAMETER;
+                SSLerr(SSL_F_SSL3_GET_MESSAGE, SSL_R_EXCESSIVE_MESSAGE_SIZE);
+                goto f_err;
+            }
+            if (l && !BUF_MEM_grow_clean(s->init_buf, (int)l + 4)) {
+                SSLerr(SSL_F_SSL3_GET_MESSAGE, ERR_R_BUF_LIB);
+                goto err;
+            }
+            s->s3->tmp.message_size = l;
+            s->state = stn;
+
+            s->init_msg = s->init_buf->data + SSL3_HM_HEADER_LENGTH;
+            s->init_num = 0;
+        }
     }
 
     /* next state (stn) */
     }
 
     /* next state (stn) */
@@ -456,10 +478,26 @@ long ssl3_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok)
 #endif
 
     /* Feed this message into MAC computation. */
 #endif
 
     /* Feed this message into MAC computation. */
-    ssl3_finish_mac(s, (unsigned char *)s->init_buf->data, s->init_num + 4);
-    if (s->msg_callback)
-        s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, s->init_buf->data,
-                        (size_t)s->init_num + 4, s, s->msg_callback_arg);
+    if(RECORD_LAYER_is_sslv2_record(&s->rlayer)) {
+        ssl3_finish_mac(s, (unsigned char *)s->init_buf->data, s->init_num);
+        /*
+         * In previous versions we would have rewritten the SSLv2 record into
+         * something that looked like a SSLv3+ record and passed that to the
+         * callback. As we're not doing the rewriting anymore it's not clear
+         * what we should do here.
+         */
+        if (s->msg_callback)
+            s->msg_callback(0, SSL2_VERSION, 0,  s->init_buf->data,
+                            (size_t)s->init_num, s, s->msg_callback_arg);
+    } else {
+        ssl3_finish_mac(s, (unsigned char *)s->init_buf->data,
+            s->init_num + SSL3_HM_HEADER_LENGTH);
+        if (s->msg_callback)
+            s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, s->init_buf->data,
+                            (size_t)s->init_num + SSL3_HM_HEADER_LENGTH, s,
+                            s->msg_callback_arg);
+    }
+
     *ok = 1;
     return s->init_num;
  f_err:
     *ok = 1;
     return s->init_num;
  f_err:
index e7f1898e8130e126fb1e6340a43bc2758d3f703b..d3265f676eedda849b29e081ccfa0e13bd383cc2 100644 (file)
@@ -3386,9 +3386,9 @@ long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg)
          * Apparently we're using a version-flexible SSL_METHOD (not at its
          * highest protocol version).
          */
          * Apparently we're using a version-flexible SSL_METHOD (not at its
          * highest protocol version).
          */
-        if (s->ctx->method->version == SSLv23_method()->version) {
+        if (s->ctx->method->version == TLS_method()->version) {
 #if TLS_MAX_VERSION != TLS1_2_VERSION
 #if TLS_MAX_VERSION != TLS1_2_VERSION
-# error Code needs update for SSLv23_method() support beyond TLS1_2_VERSION.
+# error Code needs update for TLS_method() support beyond TLS1_2_VERSION.
 #endif
             if (!(s->options & SSL_OP_NO_TLSv1_2))
                 return s->version == TLS1_2_VERSION;
 #endif
             if (!(s->options & SSL_OP_NO_TLSv1_2))
                 return s->version == TLS1_2_VERSION;
index 4ee45eb57f6071992bd84859ddfd2450ce27316e..14daf8fe4ec2fc0340e7fc98eb95964c319f844e 100644 (file)
@@ -256,7 +256,7 @@ int ssl3_accept(SSL *s)
             if (cb != NULL)
                 cb(s, SSL_CB_HANDSHAKE_START, 1);
 
             if (cb != NULL)
                 cb(s, SSL_CB_HANDSHAKE_START, 1);
 
-            if ((s->version >> 8) != 3) {
+            if ((s->version >> 8 != 3) && s->version != TLS_ANY_VERSION) {
                 SSLerr(SSL_F_SSL3_ACCEPT, ERR_R_INTERNAL_ERROR);
                 s->state = SSL_ST_ERR;
                 return -1;
                 SSLerr(SSL_F_SSL3_ACCEPT, ERR_R_INTERNAL_ERROR);
                 s->state = SSL_ST_ERR;
                 return -1;
@@ -905,6 +905,7 @@ int ssl3_get_client_hello(SSL *s)
     SSL_COMP *comp = NULL;
 #endif
     STACK_OF(SSL_CIPHER) *ciphers = NULL;
     SSL_COMP *comp = NULL;
 #endif
     STACK_OF(SSL_CIPHER) *ciphers = NULL;
+    int protverr = 1;
 
     if (s->state == SSL3_ST_SR_CLNT_HELLO_C && !s->first_packet)
         goto retry_cert;
 
     if (s->state == SSL3_ST_SR_CLNT_HELLO_C && !s->first_packet)
         goto retry_cert;
@@ -930,29 +931,130 @@ int ssl3_get_client_hello(SSL *s)
     s->first_packet = 0;
     d = p = (unsigned char *)s->init_msg;
 
     s->first_packet = 0;
     d = p = (unsigned char *)s->init_msg;
 
-    /*
-     * 2 bytes for client version, SSL3_RANDOM_SIZE bytes for random, 1 byte
-     * for session id length
-     */
-    if (n < 2 + SSL3_RANDOM_SIZE + 1) {
-        al = SSL_AD_DECODE_ERROR;
-        SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_TOO_SHORT);
-        goto f_err;
+    /* First lets get s->client_version set correctly */
+    if (!s->read_hash && !s->enc_read_ctx
+            && RECORD_LAYER_is_sslv2_record(&s->rlayer)) {
+        if (n < MIN_SSL2_RECORD_LEN) {
+            SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_RECORD_LENGTH_MISMATCH);
+            al = SSL_AD_DECODE_ERROR;
+            goto f_err;
+        }
+        /*-
+         * An SSLv3/TLSv1 backwards-compatible CLIENT-HELLO in an SSLv2
+         * header is sent directly on the wire, not wrapped as a TLS
+         * record. Our record layer just processes the message length and passes
+         * the rest right through. Its format is:
+         * Byte  Content
+         * 0-1   msg_length - decoded by the record layer
+         * 2     msg_type - s->init_msg points here
+         * 3-4   version
+         * 5-6   cipher_spec_length
+         * 7-8   session_id_length
+         * 9-10  challenge_length
+         * ...   ...
+         */
+
+        if (p[0] != SSL2_MT_CLIENT_HELLO) {
+            /*
+             * Should never happen. We should have tested this in the record
+             * layer in order to have determined that this is a SSLv2 record
+             * in the first place
+             */
+            al = SSL_AD_HANDSHAKE_FAILURE;
+            SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, ERR_R_INTERNAL_ERROR);
+            goto f_err;
+        }
+
+        if ((p[1] == 0x00) && (p[2] == 0x02)) {
+            /* This is real SSLv2. We don't support it. */
+            SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_UNKNOWN_PROTOCOL);
+            goto err;
+        } else if (p[1] == SSL3_VERSION_MAJOR) {
+            /* SSLv3/TLS */
+            s->client_version = (((int)p[1]) << 8) | (int)p[2];
+        } else {
+            /* No idea what protocol this is */
+            SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_UNKNOWN_PROTOCOL);
+            goto err;
+        }
+    } else {
+        /*
+         * 2 bytes for client version, SSL3_RANDOM_SIZE bytes for random, 1 byte
+         * for session id length
+         */
+        if (n < 2 + SSL3_RANDOM_SIZE + 1) {
+            al = SSL_AD_DECODE_ERROR;
+            SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_TOO_SHORT);
+            goto f_err;
+        }
+
+        /*
+         * use version from inside client hello, not from record header (may
+         * differ: see RFC 2246, Appendix E, second paragraph)
+         */
+        s->client_version = (((int)p[0]) << 8) | (int)p[1];
     }
 
     }
 
-    /*
-     * use version from inside client hello, not from record header (may
-     * differ: see RFC 2246, Appendix E, second paragraph)
-     */
-    s->client_version = (((int)p[0]) << 8) | (int)p[1];
-    p += 2;
-
-    if (SSL_IS_DTLS(s) ? (s->client_version > s->version &&
-                          s->method->version != DTLS_ANY_VERSION)
-        : (s->client_version < s->version)) {
-        SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_WRONG_VERSION_NUMBER);
-        if ((s->client_version >> 8) == SSL3_VERSION_MAJOR &&
-            !s->enc_write_ctx && !s->write_hash) {
+    /* Do SSL/TLS version negotiation if applicable */
+    if (!SSL_IS_DTLS(s)) {
+        if (s->version != TLS_ANY_VERSION) {
+            if (s->client_version >= s->version
+                && (((s->client_version >> 8) & 0xff) == SSL3_VERSION_MAJOR)) {
+                protverr = 0;
+            }
+        } else {
+            /*
+             * We already know that this is an SSL3_VERSION_MAJOR protocol,
+             * so we're just testing the minor versions here
+             */
+            switch(s->client_version) {
+            default:
+            case TLS1_2_VERSION:
+                if(!(s->options & SSL_OP_NO_TLSv1_2)) {
+                    s->version = TLS1_2_VERSION;
+                    s->method = TLSv1_2_server_method();
+                    protverr = 0;
+                    break;
+                }
+                /* Deliberately fall through */
+            case TLS1_1_VERSION:
+                if(!(s->options & SSL_OP_NO_TLSv1_1)) {
+                    s->version = TLS1_1_VERSION;
+                    s->method = TLSv1_1_server_method();
+                    protverr = 0;
+                    break;
+                }
+                /* Deliberately fall through */
+            case TLS1_VERSION:
+                if(!(s->options & SSL_OP_NO_TLSv1)) {
+                    s->version = TLS1_VERSION;
+                    s->method = TLSv1_server_method();
+                    protverr = 0;
+                    break;
+                }
+                /* Deliberately fall through */
+            case SSL3_VERSION:
+                if(!(s->options & SSL_OP_NO_SSLv3)) {
+                    s->version = SSL3_VERSION;
+                    s->method = SSLv3_server_method();
+                    protverr = 0;
+                    break;
+                }
+            }
+        }
+    } else if (((s->client_version >> 8) & 0xff) == DTLS1_VERSION_MAJOR &&
+                (s->client_version <= s->version
+                || s->method->version == DTLS_ANY_VERSION)) {
+        /*
+         * For DTLS we just check versions are potentially compatible. Version
+         * negotiation comes later.
+         */
+        protverr = 0;
+    }
+
+    if (protverr) {
+        SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_UNKNOWN_PROTOCOL);
+        if ((!s->enc_write_ctx && !s->write_hash)) {
             /*
              * similar to ssl3_get_record, send alert using remote version
              * number
             /*
              * similar to ssl3_get_record, send alert using remote version
              * number
@@ -963,263 +1065,322 @@ int ssl3_get_client_hello(SSL *s)
         goto f_err;
     }
 
         goto f_err;
     }
 
-    /*
-     * If we require cookies and this ClientHello doesn't contain one, just
-     * return since we do not want to allocate any memory yet. So check
-     * cookie length...
-     */
-    if (SSL_get_options(s) & SSL_OP_COOKIE_EXCHANGE) {
-        unsigned int session_length, cookie_length;
+    if (RECORD_LAYER_is_sslv2_record(&s->rlayer)) {
+        /*
+         * Handle an SSLv2 backwards compatible ClientHello
+         * Note, this is only for SSLv3+ using the backward compatible format.
+         * Real SSLv2 is not supported, and is rejected above.
+         */
+        unsigned int csl, sil, cl;
 
 
-        session_length = *(p + SSL3_RANDOM_SIZE);
+        p += 3;
+        n2s(p, csl);
+        n2s(p, sil);
+        n2s(p, cl);
 
 
-        if (p + SSL3_RANDOM_SIZE + session_length + 1 >= d + n) {
+        if (csl + sil + cl + MIN_SSL2_RECORD_LEN != (unsigned int) n) {
+            SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_RECORD_LENGTH_MISMATCH);
             al = SSL_AD_DECODE_ERROR;
             al = SSL_AD_DECODE_ERROR;
-            SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_TOO_SHORT);
             goto f_err;
         }
             goto f_err;
         }
-        cookie_length = *(p + SSL3_RANDOM_SIZE + session_length + 1);
-
-        if (cookie_length == 0)
-            return 1;
-    }
 
 
-    /* load the client random */
-    memcpy(s->s3->client_random, p, SSL3_RANDOM_SIZE);
-    p += SSL3_RANDOM_SIZE;
+        if (csl == 0) {
+            /* we need at least one cipher */
+            al = SSL_AD_ILLEGAL_PARAMETER;
+            SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_NO_CIPHERS_SPECIFIED);
+            goto f_err;
+        }
 
 
-    /* get the session-id */
-    j = *(p++);
+        if (ssl_bytes_to_cipher_list(s, p, csl, &(ciphers), 1) == NULL) {
+            goto err;
+        }
 
 
-    if (p + j > d + n) {
-        al = SSL_AD_DECODE_ERROR;
-        SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_TOO_SHORT);
-        goto f_err;
-    }
+        /*
+         * Ignore any session id. We don't allow resumption in a backwards
+         * compatible ClientHello
+         */
+        s->hit = 0;
 
 
-    s->hit = 0;
-    /*
-     * Versions before 0.9.7 always allow clients to resume sessions in
-     * renegotiation. 0.9.7 and later allow this by default, but optionally
-     * ignore resumption requests with flag
-     * SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION (it's a new flag rather
-     * than a change to default behavior so that applications relying on this
-     * for security won't even compile against older library versions).
-     * 1.0.1 and later also have a function SSL_renegotiate_abbreviated() to
-     * request renegotiation but not a new session (s->new_session remains
-     * unset): for servers, this essentially just means that the
-     * SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION setting will be ignored.
-     */
-    if ((s->new_session
-         && (s->options & SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION))) {
         if (!ssl_get_new_session(s, 1))
             goto err;
         if (!ssl_get_new_session(s, 1))
             goto err;
+
+        /* Load the client random */
+        i = (cl > SSL3_RANDOM_SIZE) ? SSL3_RANDOM_SIZE : cl;
+        memset(s->s3->client_random, 0, SSL3_RANDOM_SIZE);
+        memcpy(s->s3->client_random, &(p[csl + sil]), i);
+
+        /* Set p to end of packet to ensure we don't look for extensions */
+        p = d + n;
+
+        /* No compression, so set i to 0 */
+        i = 0;
     } else {
     } else {
-        i = ssl_get_prev_session(s, p, j, d + n);
+        /* If we get here we've got SSLv3+ in an SSLv3+ record */
+
+        p += 2;
+
         /*
         /*
-         * Only resume if the session's version matches the negotiated
-         * version.
-         * RFC 5246 does not provide much useful advice on resumption
-         * with a different protocol version. It doesn't forbid it but
-         * the sanity of such behaviour would be questionable.
-         * In practice, clients do not accept a version mismatch and
-         * will abort the handshake with an error.
+         * If we require cookies and this ClientHello doesn't contain one, just
+         * return since we do not want to allocate any memory yet. So check
+         * cookie length...
          */
          */
-        if (i == 1 && s->version == s->session->ssl_version) { /* previous
-                                                                * session */
-            s->hit = 1;
-        } else if (i == -1)
-            goto err;
-        else {                  /* i == 0 */
+        if (SSL_get_options(s) & SSL_OP_COOKIE_EXCHANGE) {
+            unsigned int session_length, cookie_length;
 
 
-            if (!ssl_get_new_session(s, 1))
-                goto err;
-        }
-    }
+            session_length = *(p + SSL3_RANDOM_SIZE);
 
 
-    p += j;
+            if (p + SSL3_RANDOM_SIZE + session_length + 1 >= d + n) {
+                al = SSL_AD_DECODE_ERROR;
+                SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_TOO_SHORT);
+                goto f_err;
+            }
+            cookie_length = *(p + SSL3_RANDOM_SIZE + session_length + 1);
 
 
-    if (SSL_IS_DTLS(s)) {
-        /* cookie stuff */
-        if (p + 1 > d + n) {
-            al = SSL_AD_DECODE_ERROR;
-            SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_TOO_SHORT);
-            goto f_err;
+            if (cookie_length == 0)
+                return 1;
         }
         }
-        cookie_len = *(p++);
 
 
-        if (p + cookie_len > d + n) {
+        /* load the client random */
+        memcpy(s->s3->client_random, p, SSL3_RANDOM_SIZE);
+        p += SSL3_RANDOM_SIZE;
+
+        /* get the session-id */
+        j = *(p++);
+
+        if (p + j > d + n) {
             al = SSL_AD_DECODE_ERROR;
             SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_TOO_SHORT);
             goto f_err;
         }
 
             al = SSL_AD_DECODE_ERROR;
             SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_TOO_SHORT);
             goto f_err;
         }
 
+        s->hit = 0;
         /*
         /*
-         * The ClientHello may contain a cookie even if the
-         * HelloVerify message has not been sent--make sure that it
-         * does not cause an overflow.
+         * Versions before 0.9.7 always allow clients to resume sessions in
+         * renegotiation. 0.9.7 and later allow this by default, but optionally
+         * ignore resumption requests with flag
+         * SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION (it's a new flag rather
+         * than a change to default behavior so that applications relying on
+         * this for security won't even compile against older library versions).
+         * 1.0.1 and later also have a function SSL_renegotiate_abbreviated() to
+         * request renegotiation but not a new session (s->new_session remains
+         * unset): for servers, this essentially just means that the
+         * SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION setting will be
+         * ignored.
          */
          */
-        if (cookie_len > sizeof(s->d1->rcvd_cookie)) {
-            /* too much data */
-            al = SSL_AD_DECODE_ERROR;
-            SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_COOKIE_MISMATCH);
-            goto f_err;
+        if ((s->new_session
+             && (s->options & SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION))) {
+            if (!ssl_get_new_session(s, 1))
+                goto err;
+        } else {
+            i = ssl_get_prev_session(s, p, j, d + n);
+            /*
+             * Only resume if the session's version matches the negotiated
+             * version.
+             * RFC 5246 does not provide much useful advice on resumption
+             * with a different protocol version. It doesn't forbid it but
+             * the sanity of such behaviour would be questionable.
+             * In practice, clients do not accept a version mismatch and
+             * will abort the handshake with an error.
+             */
+            if (i == 1 && s->version == s->session->ssl_version) {
+                /* previous session */
+                s->hit = 1;
+            } else if (i == -1)
+                goto err;
+            else {
+                /* i == 0 */
+                if (!ssl_get_new_session(s, 1))
+                    goto err;
+            }
         }
 
         }
 
-        /* verify the cookie if appropriate option is set. */
-        if ((SSL_get_options(s) & SSL_OP_COOKIE_EXCHANGE) && cookie_len > 0) {
-            memcpy(s->d1->rcvd_cookie, p, cookie_len);
+        p += j;
 
 
-            if (s->ctx->app_verify_cookie_cb != NULL) {
-                if (s->ctx->app_verify_cookie_cb(s, s->d1->rcvd_cookie,
-                                                 cookie_len) == 0) {
-                    al = SSL_AD_HANDSHAKE_FAILURE;
-                    SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,
-                           SSL_R_COOKIE_MISMATCH);
-                    goto f_err;
-                }
-                /* else cookie verification succeeded */
-            }
-            /* default verification */
-            else if (memcmp(s->d1->rcvd_cookie, s->d1->cookie,
-                            s->d1->cookie_len) != 0) {
-                al = SSL_AD_HANDSHAKE_FAILURE;
-                SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_COOKIE_MISMATCH);
+        if (SSL_IS_DTLS(s)) {
+            /* cookie stuff */
+            if (p + 1 > d + n) {
+                al = SSL_AD_DECODE_ERROR;
+                SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_TOO_SHORT);
                 goto f_err;
             }
                 goto f_err;
             }
-            /* Set to -2 so if successful we return 2 */
-            ret = -2;
-        }
+            cookie_len = *(p++);
 
 
-        p += cookie_len;
-        if (s->method->version == DTLS_ANY_VERSION) {
-            /* Select version to use */
-            if (s->client_version <= DTLS1_2_VERSION &&
-                !(s->options & SSL_OP_NO_DTLSv1_2)) {
-                s->version = DTLS1_2_VERSION;
-                s->method = DTLSv1_2_server_method();
-            } else if (tls1_suiteb(s)) {
-                SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,
-                       SSL_R_ONLY_DTLS_1_2_ALLOWED_IN_SUITEB_MODE);
-                s->version = s->client_version;
-                al = SSL_AD_PROTOCOL_VERSION;
+            if (p + cookie_len > d + n) {
+                al = SSL_AD_DECODE_ERROR;
+                SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_TOO_SHORT);
                 goto f_err;
                 goto f_err;
-            } else if (s->client_version <= DTLS1_VERSION &&
-                       !(s->options & SSL_OP_NO_DTLSv1)) {
-                s->version = DTLS1_VERSION;
-                s->method = DTLSv1_server_method();
-            } else {
-                SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,
-                       SSL_R_WRONG_VERSION_NUMBER);
-                s->version = s->client_version;
-                al = SSL_AD_PROTOCOL_VERSION;
+            }
+
+            /*
+             * The ClientHello may contain a cookie even if the
+             * HelloVerify message has not been sent--make sure that it
+             * does not cause an overflow.
+             */
+            if (cookie_len > sizeof(s->d1->rcvd_cookie)) {
+                /* too much data */
+                al = SSL_AD_DECODE_ERROR;
+                SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_COOKIE_MISMATCH);
                 goto f_err;
             }
                 goto f_err;
             }
-            s->session->ssl_version = s->version;
+
+            /* verify the cookie if appropriate option is set. */
+            if ((SSL_get_options(s) & SSL_OP_COOKIE_EXCHANGE)
+                    && cookie_len > 0) {
+                memcpy(s->d1->rcvd_cookie, p, cookie_len);
+
+                if (s->ctx->app_verify_cookie_cb != NULL) {
+                    if (s->ctx->app_verify_cookie_cb(s, s->d1->rcvd_cookie,
+                                                     cookie_len) == 0) {
+                        al = SSL_AD_HANDSHAKE_FAILURE;
+                        SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,
+                               SSL_R_COOKIE_MISMATCH);
+                        goto f_err;
+                    }
+                    /* else cookie verification succeeded */
+                }
+                /* default verification */
+                else if (memcmp(s->d1->rcvd_cookie, s->d1->cookie,
+                                s->d1->cookie_len) != 0) {
+                    al = SSL_AD_HANDSHAKE_FAILURE;
+                    SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_COOKIE_MISMATCH);
+                    goto f_err;
+                }
+                /* Set to -2 so if successful we return 2 */
+                ret = -2;
+            }
+
+            p += cookie_len;
+            if (s->method->version == DTLS_ANY_VERSION) {
+                /* Select version to use */
+                if (s->client_version <= DTLS1_2_VERSION &&
+                    !(s->options & SSL_OP_NO_DTLSv1_2)) {
+                    s->version = DTLS1_2_VERSION;
+                    s->method = DTLSv1_2_server_method();
+                } else if (tls1_suiteb(s)) {
+                    SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,
+                           SSL_R_ONLY_DTLS_1_2_ALLOWED_IN_SUITEB_MODE);
+                    s->version = s->client_version;
+                    al = SSL_AD_PROTOCOL_VERSION;
+                    goto f_err;
+                } else if (s->client_version <= DTLS1_VERSION &&
+                           !(s->options & SSL_OP_NO_DTLSv1)) {
+                    s->version = DTLS1_VERSION;
+                    s->method = DTLSv1_server_method();
+                } else {
+                    SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,
+                           SSL_R_WRONG_VERSION_NUMBER);
+                    s->version = s->client_version;
+                    al = SSL_AD_PROTOCOL_VERSION;
+                    goto f_err;
+                }
+                s->session->ssl_version = s->version;
+            }
         }
         }
-    }
 
 
-    if (p + 2 > d + n) {
-        al = SSL_AD_DECODE_ERROR;
-        SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_TOO_SHORT);
-        goto f_err;
-    }
-    n2s(p, i);
+        if (p + 2 > d + n) {
+            al = SSL_AD_DECODE_ERROR;
+            SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_TOO_SHORT);
+            goto f_err;
+        }
+        n2s(p, i);
 
 
-    if (i == 0) {
-        al = SSL_AD_ILLEGAL_PARAMETER;
-        SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_NO_CIPHERS_SPECIFIED);
-        goto f_err;
-    }
+        if (i == 0) {
+            al = SSL_AD_ILLEGAL_PARAMETER;
+            SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_NO_CIPHERS_SPECIFIED);
+            goto f_err;
+        }
 
 
-    /* i bytes of cipher data + 1 byte for compression length later */
-    if ((p + i + 1) > (d + n)) {
-        /* not enough data */
-        al = SSL_AD_DECODE_ERROR;
-        SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_MISMATCH);
-        goto f_err;
-    }
-    if (ssl_bytes_to_cipher_list(s, p, i, &(ciphers)) == NULL) {
-        goto err;
-    }
-    p += i;
+        /* i bytes of cipher data + 1 byte for compression length later */
+        if ((p + i + 1) > (d + n)) {
+            /* not enough data */
+            al = SSL_AD_DECODE_ERROR;
+            SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_MISMATCH);
+            goto f_err;
+        }
+        if (ssl_bytes_to_cipher_list(s, p, i, &(ciphers), 0) == NULL) {
+            goto err;
+        }
+        p += i;
 
 
-    /* If it is a hit, check that the cipher is in the list */
-    if (s->hit) {
-        j = 0;
-        id = s->session->cipher->id;
+        /* If it is a hit, check that the cipher is in the list */
+        if (s->hit) {
+            j = 0;
+            id = s->session->cipher->id;
 
 #ifdef CIPHER_DEBUG
 
 #ifdef CIPHER_DEBUG
-        fprintf(stderr, "client sent %d ciphers\n",
-                sk_SSL_CIPHER_num(ciphers));
+            fprintf(stderr, "client sent %d ciphers\n",
+                    sk_SSL_CIPHER_num(ciphers));
 #endif
 #endif
-        for (i = 0; i < sk_SSL_CIPHER_num(ciphers); i++) {
-            c = sk_SSL_CIPHER_value(ciphers, i);
+            for (i = 0; i < sk_SSL_CIPHER_num(ciphers); i++) {
+                c = sk_SSL_CIPHER_value(ciphers, i);
 #ifdef CIPHER_DEBUG
 #ifdef CIPHER_DEBUG
-            fprintf(stderr, "client [%2d of %2d]:%s\n",
-                    i, sk_SSL_CIPHER_num(ciphers), SSL_CIPHER_get_name(c));
+                fprintf(stderr, "client [%2d of %2d]:%s\n",
+                        i, sk_SSL_CIPHER_num(ciphers), SSL_CIPHER_get_name(c));
 #endif
 #endif
-            if (c->id == id) {
-                j = 1;
-                break;
+                if (c->id == id) {
+                    j = 1;
+                    break;
+                }
             }
             }
-        }
-        /*
-         * Disabled because it can be used in a ciphersuite downgrade attack:
-         * CVE-2010-4180.
-         */
-#if 0
-        if (j == 0 && (s->options & SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG)
-            && (sk_SSL_CIPHER_num(ciphers) == 1)) {
             /*
             /*
-             * Special case as client bug workaround: the previously used
-             * cipher may not be in the current list, the client instead
-             * might be trying to continue using a cipher that before wasn't
-             * chosen due to server preferences.  We'll have to reject the
-             * connection if the cipher is not enabled, though.
+             * Disabled because it can be used in a ciphersuite downgrade
+             * attack:
+             * CVE-2010-4180.
              */
              */
-            c = sk_SSL_CIPHER_value(ciphers, 0);
-            if (sk_SSL_CIPHER_find(SSL_get_ciphers(s), c) >= 0) {
-                s->session->cipher = c;
-                j = 1;
+#if 0
+            if (j == 0 && (s->options & SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG)
+                && (sk_SSL_CIPHER_num(ciphers) == 1)) {
+                /*
+                 * Special case as client bug workaround: the previously used
+                 * cipher may not be in the current list, the client instead
+                 * might be trying to continue using a cipher that before wasn't
+                 * chosen due to server preferences.  We'll have to reject the
+                 * connection if the cipher is not enabled, though.
+                 */
+                c = sk_SSL_CIPHER_value(ciphers, 0);
+                if (sk_SSL_CIPHER_find(SSL_get_ciphers(s), c) >= 0) {
+                    s->session->cipher = c;
+                    j = 1;
+                }
             }
             }
-        }
 #endif
 #endif
-        if (j == 0) {
-            /*
-             * we need to have the cipher in the cipher list if we are asked
-             * to reuse it
-             */
-            al = SSL_AD_ILLEGAL_PARAMETER;
-            SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,
-                   SSL_R_REQUIRED_CIPHER_MISSING);
-            goto f_err;
+            if (j == 0) {
+                /*
+                 * we need to have the cipher in the cipher list if we are asked
+                 * to reuse it
+                 */
+                al = SSL_AD_ILLEGAL_PARAMETER;
+                SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,
+                       SSL_R_REQUIRED_CIPHER_MISSING);
+                goto f_err;
+            }
         }
         }
-    }
 
 
-    /* compression */
-    i = *(p++);
-    if ((p + i) > (d + n)) {
-        /* not enough data */
-        al = SSL_AD_DECODE_ERROR;
-        SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_MISMATCH);
-        goto f_err;
-    }
+        /* compression */
+        i = *(p++);
+        if ((p + i) > (d + n)) {
+            /* not enough data */
+            al = SSL_AD_DECODE_ERROR;
+            SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_MISMATCH);
+            goto f_err;
+        }
 #ifndef OPENSSL_NO_COMP
 #ifndef OPENSSL_NO_COMP
-    q = p;
+        q = p;
 #endif
 #endif
-    for (j = 0; j < i; j++) {
-        if (p[j] == 0)
-            break;
-    }
+        for (j = 0; j < i; j++) {
+            if (p[j] == 0)
+                break;
+        }
 
 
-    p += i;
-    if (j >= i) {
-        /* no compress */
-        al = SSL_AD_DECODE_ERROR;
-        SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_NO_COMPRESSION_SPECIFIED);
-        goto f_err;
+        p += i;
+        if (j >= i) {
+            /* no compress */
+            al = SSL_AD_DECODE_ERROR;
+            SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_NO_COMPRESSION_SPECIFIED);
+            goto f_err;
+        }
     }
     }
+
 #ifndef OPENSSL_NO_TLSEXT
     /* TLS extensions */
     if (s->version >= SSL3_VERSION) {
 #ifndef OPENSSL_NO_TLSEXT
     /* TLS extensions */
     if (s->version >= SSL3_VERSION) {
index 38280186fab3e77b8fd5235ae19130deb44c0923..0969368c46262044997d078ebb02c450ee2318b1 100644 (file)
@@ -1456,9 +1456,12 @@ int ssl_cipher_list_to_bytes(SSL *s, STACK_OF(SSL_CIPHER) *sk,
     return (p - q);
 }
 
     return (p - q);
 }
 
+#define SSLV2_CIPHER_LEN    3
+
 STACK_OF(SSL_CIPHER) *ssl_bytes_to_cipher_list(SSL *s, unsigned char *p,
                                                int num,
 STACK_OF(SSL_CIPHER) *ssl_bytes_to_cipher_list(SSL *s, unsigned char *p,
                                                int num,
-                                               STACK_OF(SSL_CIPHER) **skp)
+                                               STACK_OF(SSL_CIPHER) **skp,
+                                               int sslv2format)
 {
     const SSL_CIPHER *c;
     STACK_OF(SSL_CIPHER) *sk;
 {
     const SSL_CIPHER *c;
     STACK_OF(SSL_CIPHER) *sk;
@@ -1467,7 +1470,11 @@ STACK_OF(SSL_CIPHER) *ssl_bytes_to_cipher_list(SSL *s, unsigned char *p,
     if (s->s3)
         s->s3->send_connection_binding = 0;
 
     if (s->s3)
         s->s3->send_connection_binding = 0;
 
-    n = ssl_put_cipher_by_char(s, NULL, NULL);
+    if(sslv2format) {
+        n = SSLV2_CIPHER_LEN;
+    } else {
+        n = ssl_put_cipher_by_char(s, NULL, NULL);
+    }
     if (n == 0 || (num % n) != 0) {
         SSLerr(SSL_F_SSL_BYTES_TO_CIPHER_LIST,
                SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST);
     if (n == 0 || (num % n) != 0) {
         SSLerr(SSL_F_SSL_BYTES_TO_CIPHER_LIST,
                SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST);
@@ -1533,7 +1540,20 @@ STACK_OF(SSL_CIPHER) *ssl_bytes_to_cipher_list(SSL *s, unsigned char *p,
             continue;
         }
 
             continue;
         }
 
-        c = ssl_get_cipher_by_char(s, p);
+        if(sslv2format) {
+            /*
+             * We only support SSLv2 format ciphers in SSLv3+ using a
+             * SSLv2 backward compatible ClientHello. In this case the first
+             * byte is always 0 for SSLv3 compatible ciphers. Anything else
+             * is an SSLv2 cipher and we ignore it
+             */
+            if(p[0] == 0)
+                c = ssl_get_cipher_by_char(s, &p[1]);
+            else
+                c = NULL;
+        } else {
+            c = ssl_get_cipher_by_char(s, p);
+        }
         p += n;
         if (c != NULL) {
             if (!sk_SSL_CIPHER_push(sk, c)) {
         p += n;
         if (c != NULL) {
             if (!sk_SSL_CIPHER_push(sk, c)) {
index f9c4e127f4f2e7cf725bee1e08d05291e436c76a..641fe20b52a244ffff27b5a75946546869a123b7 100644 (file)
@@ -1921,7 +1921,8 @@ __owur int ssl_cipher_ptr_id_cmp(const SSL_CIPHER *const *ap,
                           const SSL_CIPHER *const *bp);
 __owur STACK_OF(SSL_CIPHER) *ssl_bytes_to_cipher_list(SSL *s, unsigned char *p,
                                                int num,
                           const SSL_CIPHER *const *bp);
 __owur STACK_OF(SSL_CIPHER) *ssl_bytes_to_cipher_list(SSL *s, unsigned char *p,
                                                int num,
-                                               STACK_OF(SSL_CIPHER) **skp);
+                                               STACK_OF(SSL_CIPHER) **skp,
+                                               int sslv2format);
 __owur int ssl_cipher_list_to_bytes(SSL *s, STACK_OF(SSL_CIPHER) *sk,
                              unsigned char *p,
                              int (*put_cb) (const SSL_CIPHER *,
 __owur int ssl_cipher_list_to_bytes(SSL *s, STACK_OF(SSL_CIPHER) *sk,
                              unsigned char *p,
                              int (*put_cb) (const SSL_CIPHER *,
index 335d57b530f734fe81906735b6477473eda8db24..0726274ba3558e054fef8cb5ffd83ca2354f929e 100644 (file)
@@ -62,6 +62,8 @@
 
 static const SSL_METHOD *tls1_get_method(int ver)
 {
 
 static const SSL_METHOD *tls1_get_method(int ver)
 {
+    if (ver == TLS_ANY_VERSION)
+        return TLS_method();
     if (ver == TLS1_2_VERSION)
         return TLSv1_2_method();
     if (ver == TLS1_1_VERSION)
     if (ver == TLS1_2_VERSION)
         return TLSv1_2_method();
     if (ver == TLS1_1_VERSION)
@@ -71,14 +73,18 @@ static const SSL_METHOD *tls1_get_method(int ver)
     return NULL;
 }
 
     return NULL;
 }
 
+IMPLEMENT_tls_meth_func(TLS_ANY_VERSION, TLS_method,
+                        ssl3_accept,
+                        ssl3_connect, tls1_get_method, TLSv1_2_enc_data)
+
 IMPLEMENT_tls_meth_func(TLS1_2_VERSION, TLSv1_2_method,
                         ssl3_accept,
                         ssl3_connect, tls1_get_method, TLSv1_2_enc_data)
 
 IMPLEMENT_tls_meth_func(TLS1_2_VERSION, TLSv1_2_method,
                         ssl3_accept,
                         ssl3_connect, tls1_get_method, TLSv1_2_enc_data)
 
-    IMPLEMENT_tls_meth_func(TLS1_1_VERSION, TLSv1_1_method,
+IMPLEMENT_tls_meth_func(TLS1_1_VERSION, TLSv1_1_method,
                         ssl3_accept,
                         ssl3_connect, tls1_get_method, TLSv1_1_enc_data)
 
                         ssl3_accept,
                         ssl3_connect, tls1_get_method, TLSv1_1_enc_data)
 
-    IMPLEMENT_tls_meth_func(TLS1_VERSION, TLSv1_method,
+IMPLEMENT_tls_meth_func(TLS1_VERSION, TLSv1_method,
                         ssl3_accept,
                         ssl3_connect, tls1_get_method, TLSv1_enc_data)
                         ssl3_accept,
                         ssl3_connect, tls1_get_method, TLSv1_enc_data)
index 8c6b3dff2f559d2d0fa14e589e49ca4c3aa2bf4a..451f384ecc51f07231d4566f64baeb5211c4e6c1 100644 (file)
@@ -67,6 +67,8 @@
 static const SSL_METHOD *tls1_get_server_method(int ver);
 static const SSL_METHOD *tls1_get_server_method(int ver)
 {
 static const SSL_METHOD *tls1_get_server_method(int ver);
 static const SSL_METHOD *tls1_get_server_method(int ver)
 {
+    if (ver == TLS_ANY_VERSION)
+        return TLS_server_method();
     if (ver == TLS1_2_VERSION)
         return TLSv1_2_server_method();
     if (ver == TLS1_1_VERSION)
     if (ver == TLS1_2_VERSION)
         return TLSv1_2_server_method();
     if (ver == TLS1_1_VERSION)
@@ -76,17 +78,22 @@ static const SSL_METHOD *tls1_get_server_method(int ver)
     return NULL;
 }
 
     return NULL;
 }
 
+IMPLEMENT_tls_meth_func(TLS_ANY_VERSION, TLS_server_method,
+                        ssl3_accept,
+                        ssl_undefined_function,
+                        tls1_get_server_method, TLSv1_2_enc_data)
+
 IMPLEMENT_tls_meth_func(TLS1_2_VERSION, TLSv1_2_server_method,
                         ssl3_accept,
                         ssl_undefined_function,
                         tls1_get_server_method, TLSv1_2_enc_data)
 
 IMPLEMENT_tls_meth_func(TLS1_2_VERSION, TLSv1_2_server_method,
                         ssl3_accept,
                         ssl_undefined_function,
                         tls1_get_server_method, TLSv1_2_enc_data)
 
-    IMPLEMENT_tls_meth_func(TLS1_1_VERSION, TLSv1_1_server_method,
+IMPLEMENT_tls_meth_func(TLS1_1_VERSION, TLSv1_1_server_method,
                         ssl3_accept,
                         ssl_undefined_function,
                         tls1_get_server_method, TLSv1_1_enc_data)
 
                         ssl3_accept,
                         ssl_undefined_function,
                         tls1_get_server_method, TLSv1_1_enc_data)
 
-    IMPLEMENT_tls_meth_func(TLS1_VERSION, TLSv1_server_method,
+IMPLEMENT_tls_meth_func(TLS1_VERSION, TLSv1_server_method,
                         ssl3_accept,
                         ssl_undefined_function,
                         tls1_get_server_method, TLSv1_enc_data)
                         ssl3_accept,
                         ssl_undefined_function,
                         tls1_get_server_method, TLSv1_enc_data)
index 1fa2aa2c720f4b62503e465a6ffa875666ce3403..95ba1a0bf761260497baeec89ecf313fdecc2002 100644 (file)
@@ -1417,7 +1417,7 @@ int main(int argc, char *argv[])
     if (tls1)
         meth = TLSv1_method();
     else
     if (tls1)
         meth = TLSv1_method();
     else
-        meth = SSLv23_method();
+        meth = TLS_method();
 
     c_ctx = SSL_CTX_new(meth);
     s_ctx = SSL_CTX_new(meth);
 
     c_ctx = SSL_CTX_new(meth);
     s_ctx = SSL_CTX_new(meth);
index 7fb0714c9e3405be2163848324b2395051ec93db..d0b41915b375713a18ab402ea942c65a34a2d8d3 100755 (executable)
@@ -96,8 +96,8 @@ SSL_use_certificate_file                107   EXIST::FUNCTION:STDIO
 SSL_write                               108    EXIST::FUNCTION:
 SSLeay_add_ssl_algorithms               109    NOEXIST::FUNCTION:
 SSLv23_client_method                    110    EXIST::FUNCTION:RSA
 SSL_write                               108    EXIST::FUNCTION:
 SSLeay_add_ssl_algorithms               109    NOEXIST::FUNCTION:
 SSLv23_client_method                    110    EXIST::FUNCTION:RSA
-SSLv23_method                           111    EXIST::FUNCTION:RSA
-SSLv23_server_method                    112    EXIST::FUNCTION:RSA
+SSLv23_method                           111    NOEXIST::FUNCTION:
+SSLv23_server_method                    112    NOEXIST::FUNCTION:
 SSLv2_client_method                     113    NOEXIST::FUNCTION:
 SSLv2_method                            114    NOEXIST::FUNCTION:
 SSLv2_server_method                     115    NOEXIST::FUNCTION:
 SSLv2_client_method                     113    NOEXIST::FUNCTION:
 SSLv2_method                            114    NOEXIST::FUNCTION:
 SSLv2_server_method                     115    NOEXIST::FUNCTION:
@@ -396,3 +396,5 @@ SSL_set_rbio                            430 EXIST::FUNCTION:
 SSL_CIPHER_get_digest_nid               431    EXIST::FUNCTION:
 SSL_CIPHER_get_cipher_nid               432    EXIST::FUNCTION:
 SSL_use_certificate_chain_file          433    EXIST::FUNCTION:STDIO
 SSL_CIPHER_get_digest_nid               431    EXIST::FUNCTION:
 SSL_CIPHER_get_cipher_nid               432    EXIST::FUNCTION:
 SSL_use_certificate_chain_file          433    EXIST::FUNCTION:STDIO
+TLS_server_method                       434    EXIST::FUNCTION:
+TLS_method                              435    EXIST::FUNCTION: