| 
									
										
										
										
											1998-12-21 18:52:47 +08:00
										 |  |  | /* ssl/s23_clnt.c */ | 
					
						
							| 
									
										
										
										
											1998-12-21 18:56:39 +08:00
										 |  |  | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
 | 
					
						
							| 
									
										
										
										
											1998-12-21 18:52:47 +08:00
										 |  |  |  * All rights reserved. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This package is an SSL implementation written | 
					
						
							|  |  |  |  * by Eric Young (eay@cryptsoft.com). | 
					
						
							|  |  |  |  * The implementation was written so as to conform with Netscapes SSL. | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											1998-12-21 18:52:47 +08:00
										 |  |  |  * This library is free for commercial and non-commercial use as long as | 
					
						
							|  |  |  |  * the following conditions are aheared to.  The following conditions | 
					
						
							|  |  |  |  * apply to all code found in this distribution, be it the RC4, RSA, | 
					
						
							|  |  |  |  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation | 
					
						
							|  |  |  |  * included with this distribution is covered by the same copyright terms | 
					
						
							|  |  |  |  * except that the holder is Tim Hudson (tjh@cryptsoft.com). | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											1998-12-21 18:52:47 +08:00
										 |  |  |  * Copyright remains Eric Young's, and as such any Copyright notices in | 
					
						
							|  |  |  |  * the code are not to be removed. | 
					
						
							|  |  |  |  * If this package is used in a product, Eric Young should be given attribution | 
					
						
							|  |  |  |  * as the author of the parts of the library used. | 
					
						
							|  |  |  |  * This can be in the form of a textual message at program startup or | 
					
						
							|  |  |  |  * in documentation (online or textual) provided with the package. | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											1998-12-21 18:52:47 +08:00
										 |  |  |  * Redistribution and use in source and binary forms, with or without | 
					
						
							|  |  |  |  * modification, are permitted provided that the following conditions | 
					
						
							|  |  |  |  * are met: | 
					
						
							|  |  |  |  * 1. Redistributions of source code must retain the copyright | 
					
						
							|  |  |  |  *    notice, this list of conditions and the following disclaimer. | 
					
						
							|  |  |  |  * 2. Redistributions in binary form must reproduce the above copyright | 
					
						
							|  |  |  |  *    notice, this list of conditions and the following disclaimer in the | 
					
						
							|  |  |  |  *    documentation and/or other materials provided with the distribution. | 
					
						
							|  |  |  |  * 3. All advertising materials mentioning features or use of this software | 
					
						
							|  |  |  |  *    must display the following acknowledgement: | 
					
						
							|  |  |  |  *    "This product includes cryptographic software written by | 
					
						
							|  |  |  |  *     Eric Young (eay@cryptsoft.com)" | 
					
						
							|  |  |  |  *    The word 'cryptographic' can be left out if the rouines from the library | 
					
						
							|  |  |  |  *    being used are not cryptographic related :-). | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  |  * 4. If you include any Windows specific code (or a derivative thereof) from | 
					
						
							| 
									
										
										
										
											1998-12-21 18:52:47 +08:00
										 |  |  |  *    the apps directory (application code) you must include an acknowledgement: | 
					
						
							|  |  |  |  *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											1998-12-21 18:52:47 +08:00
										 |  |  |  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND | 
					
						
							|  |  |  |  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | 
					
						
							|  |  |  |  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | 
					
						
							|  |  |  |  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | 
					
						
							|  |  |  |  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | 
					
						
							|  |  |  |  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | 
					
						
							|  |  |  |  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | 
					
						
							|  |  |  |  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | 
					
						
							|  |  |  |  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | 
					
						
							|  |  |  |  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 
					
						
							|  |  |  |  * SUCH DAMAGE. | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											1998-12-21 18:52:47 +08:00
										 |  |  |  * The licence and distribution terms for any publically available version or | 
					
						
							|  |  |  |  * derivative of this code cannot be changed.  i.e. this code cannot simply be | 
					
						
							|  |  |  |  * copied and put under another distribution licence | 
					
						
							|  |  |  |  * [including the GNU Public Licence.] | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2006-01-03 11:27:19 +08:00
										 |  |  | /* ====================================================================
 | 
					
						
							|  |  |  |  * Copyright (c) 1998-2006 The OpenSSL Project.  All rights reserved. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Redistribution and use in source and binary forms, with or without | 
					
						
							|  |  |  |  * modification, are permitted provided that the following conditions | 
					
						
							|  |  |  |  * are met: | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * 1. Redistributions of source code must retain the above copyright | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  |  *    notice, this list of conditions and the following disclaimer. | 
					
						
							| 
									
										
										
										
											2006-01-03 11:27:19 +08:00
										 |  |  |  * | 
					
						
							|  |  |  |  * 2. Redistributions in binary form must reproduce the above copyright | 
					
						
							|  |  |  |  *    notice, this list of conditions and the following disclaimer in | 
					
						
							|  |  |  |  *    the documentation and/or other materials provided with the | 
					
						
							|  |  |  |  *    distribution. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * 3. All advertising materials mentioning features or use of this | 
					
						
							|  |  |  |  *    software must display the following acknowledgment: | 
					
						
							|  |  |  |  *    "This product includes software developed by the OpenSSL Project | 
					
						
							|  |  |  |  *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
 | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to | 
					
						
							|  |  |  |  *    endorse or promote products derived from this software without | 
					
						
							|  |  |  |  *    prior written permission. For written permission, please contact | 
					
						
							|  |  |  |  *    openssl-core@openssl.org. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * 5. Products derived from this software may not be called "OpenSSL" | 
					
						
							|  |  |  |  *    nor may "OpenSSL" appear in their names without prior written | 
					
						
							|  |  |  |  *    permission of the OpenSSL Project. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * 6. Redistributions of any form whatsoever must retain the following | 
					
						
							|  |  |  |  *    acknowledgment: | 
					
						
							|  |  |  |  *    "This product includes software developed by the OpenSSL Project | 
					
						
							|  |  |  |  *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
 | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY | 
					
						
							|  |  |  |  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | 
					
						
							|  |  |  |  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | 
					
						
							|  |  |  |  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR | 
					
						
							|  |  |  |  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | 
					
						
							|  |  |  |  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | 
					
						
							|  |  |  |  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | 
					
						
							|  |  |  |  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | 
					
						
							|  |  |  |  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | 
					
						
							|  |  |  |  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | 
					
						
							|  |  |  |  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | 
					
						
							|  |  |  |  * OF THE POSSIBILITY OF SUCH DAMAGE. | 
					
						
							|  |  |  |  * ==================================================================== | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This product includes cryptographic software written by Eric Young | 
					
						
							|  |  |  |  * (eay@cryptsoft.com).  This product includes software written by Tim | 
					
						
							|  |  |  |  * Hudson (tjh@cryptsoft.com). | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											1998-12-21 18:52:47 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include <stdio.h>
 | 
					
						
							| 
									
										
										
										
											2002-07-10 15:01:54 +08:00
										 |  |  | #include "ssl_locl.h"
 | 
					
						
							| 
									
										
										
										
											1999-04-24 06:13:45 +08:00
										 |  |  | #include <openssl/buffer.h>
 | 
					
						
							|  |  |  | #include <openssl/rand.h>
 | 
					
						
							|  |  |  | #include <openssl/objects.h>
 | 
					
						
							|  |  |  | #include <openssl/evp.h>
 | 
					
						
							| 
									
										
										
										
											1998-12-21 18:52:47 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-08-15 05:48:33 +08:00
										 |  |  | static const SSL_METHOD *ssl23_get_client_method(int ver); | 
					
						
							| 
									
										
										
										
											1998-12-21 18:52:47 +08:00
										 |  |  | static int ssl23_client_hello(SSL *s); | 
					
						
							|  |  |  | static int ssl23_get_server_hello(SSL *s); | 
					
						
							| 
									
										
										
										
											2005-08-15 05:48:33 +08:00
										 |  |  | static const SSL_METHOD *ssl23_get_client_method(int ver) | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2014-10-15 15:25:50 +08:00
										 |  |  | #ifndef OPENSSL_NO_SSL3
 | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  |     if (ver == SSL3_VERSION) | 
					
						
							|  |  |  |         return (SSLv3_client_method()); | 
					
						
							| 
									
										
										
										
											2014-10-15 15:25:50 +08:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  |     if (ver == TLS1_VERSION) | 
					
						
							|  |  |  |         return (TLSv1_client_method()); | 
					
						
							|  |  |  |     else if (ver == TLS1_1_VERSION) | 
					
						
							|  |  |  |         return (TLSv1_1_client_method()); | 
					
						
							|  |  |  |     else if (ver == TLS1_2_VERSION) | 
					
						
							|  |  |  |         return (TLSv1_2_client_method()); | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |         return (NULL); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											1998-12-21 18:52:47 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-08-06 07:56:11 +08:00
										 |  |  | IMPLEMENT_ssl23_meth_func(SSLv23_client_method, | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  |                           ssl_undefined_function, | 
					
						
							|  |  |  |                           ssl23_connect, ssl23_get_client_method) | 
					
						
							| 
									
										
										
										
											1998-12-21 18:52:47 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1999-04-20 05:31:43 +08:00
										 |  |  | int ssl23_connect(SSL *s) | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  | { | 
					
						
							|  |  |  |     BUF_MEM *buf = NULL; | 
					
						
							|  |  |  |     unsigned long Time = (unsigned long)time(NULL); | 
					
						
							|  |  |  |     void (*cb) (const SSL *ssl, int type, int val) = NULL; | 
					
						
							|  |  |  |     int ret = -1; | 
					
						
							|  |  |  |     int new_state, state; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     RAND_add(&Time, sizeof(Time), 0); | 
					
						
							|  |  |  |     ERR_clear_error(); | 
					
						
							|  |  |  |     clear_sys_error(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (s->info_callback != NULL) | 
					
						
							|  |  |  |         cb = s->info_callback; | 
					
						
							|  |  |  |     else if (s->ctx->info_callback != NULL) | 
					
						
							|  |  |  |         cb = s->ctx->info_callback; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     s->in_handshake++; | 
					
						
							| 
									
										
										
										
											2015-03-06 22:37:17 +08:00
										 |  |  |     if (!SSL_in_init(s) || SSL_in_before(s)) { | 
					
						
							|  |  |  |         if(!SSL_clear(s)) | 
					
						
							|  |  |  |             return -1; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     for (;;) { | 
					
						
							|  |  |  |         state = s->state; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         switch (s->state) { | 
					
						
							|  |  |  |         case SSL_ST_BEFORE: | 
					
						
							|  |  |  |         case SSL_ST_CONNECT: | 
					
						
							|  |  |  |         case SSL_ST_BEFORE | SSL_ST_CONNECT: | 
					
						
							|  |  |  |         case SSL_ST_OK | SSL_ST_CONNECT: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if (s->session != NULL) { | 
					
						
							|  |  |  |                 SSLerr(SSL_F_SSL23_CONNECT, | 
					
						
							|  |  |  |                        SSL_R_SSL23_DOING_SESSION_ID_REUSE); | 
					
						
							|  |  |  |                 ret = -1; | 
					
						
							|  |  |  |                 goto end; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             s->server = 0; | 
					
						
							|  |  |  |             if (cb != NULL) | 
					
						
							|  |  |  |                 cb(s, SSL_CB_HANDSHAKE_START, 1); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             /* s->version=TLS1_VERSION; */ | 
					
						
							|  |  |  |             s->type = SSL_ST_CONNECT; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if (s->init_buf == NULL) { | 
					
						
							|  |  |  |                 if ((buf = BUF_MEM_new()) == NULL) { | 
					
						
							|  |  |  |                     ret = -1; | 
					
						
							|  |  |  |                     goto end; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 if (!BUF_MEM_grow(buf, SSL3_RT_MAX_PLAIN_LENGTH)) { | 
					
						
							|  |  |  |                     ret = -1; | 
					
						
							|  |  |  |                     goto end; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 s->init_buf = buf; | 
					
						
							|  |  |  |                 buf = NULL; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if (!ssl3_setup_buffers(s)) { | 
					
						
							|  |  |  |                 ret = -1; | 
					
						
							|  |  |  |                 goto end; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             ssl3_init_finished_mac(s); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             s->state = SSL23_ST_CW_CLNT_HELLO_A; | 
					
						
							|  |  |  |             s->ctx->stats.sess_connect++; | 
					
						
							|  |  |  |             s->init_num = 0; | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         case SSL23_ST_CW_CLNT_HELLO_A: | 
					
						
							|  |  |  |         case SSL23_ST_CW_CLNT_HELLO_B: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             s->shutdown = 0; | 
					
						
							|  |  |  |             ret = ssl23_client_hello(s); | 
					
						
							|  |  |  |             if (ret <= 0) | 
					
						
							|  |  |  |                 goto end; | 
					
						
							|  |  |  |             s->state = SSL23_ST_CR_SRVR_HELLO_A; | 
					
						
							|  |  |  |             s->init_num = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         case SSL23_ST_CR_SRVR_HELLO_A: | 
					
						
							|  |  |  |         case SSL23_ST_CR_SRVR_HELLO_B: | 
					
						
							|  |  |  |             ret = ssl23_get_server_hello(s); | 
					
						
							|  |  |  |             if (ret >= 0) | 
					
						
							|  |  |  |                 cb = NULL; | 
					
						
							|  |  |  |             goto end; | 
					
						
							|  |  |  |             /* break; */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         default: | 
					
						
							|  |  |  |             SSLerr(SSL_F_SSL23_CONNECT, SSL_R_UNKNOWN_STATE); | 
					
						
							|  |  |  |             ret = -1; | 
					
						
							|  |  |  |             goto end; | 
					
						
							|  |  |  |             /* break; */ | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (s->debug) { | 
					
						
							|  |  |  |             (void)BIO_flush(s->wbio); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if ((cb != NULL) && (s->state != state)) { | 
					
						
							|  |  |  |             new_state = s->state; | 
					
						
							|  |  |  |             s->state = state; | 
					
						
							|  |  |  |             cb(s, SSL_CB_CONNECT_LOOP, 1); | 
					
						
							|  |  |  |             s->state = new_state; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |  end: | 
					
						
							|  |  |  |     s->in_handshake--; | 
					
						
							|  |  |  |     if (buf != NULL) | 
					
						
							|  |  |  |         BUF_MEM_free(buf); | 
					
						
							|  |  |  |     if (cb != NULL) | 
					
						
							|  |  |  |         cb(s, SSL_CB_CONNECT_EXIT, ret); | 
					
						
							|  |  |  |     return (ret); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * Fill a ClientRandom or ServerRandom field of length len. Returns <= 0 on | 
					
						
							|  |  |  |  * failure, 1 on success. | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2013-10-21 06:03:24 +08:00
										 |  |  | int ssl_fill_hello_random(SSL *s, int server, unsigned char *result, int len) | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  | { | 
					
						
							|  |  |  |     int send_time = 0; | 
					
						
							| 
									
										
										
										
											2015-02-26 19:57:37 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  |     if (len < 4) | 
					
						
							|  |  |  |         return 0; | 
					
						
							|  |  |  |     if (server) | 
					
						
							|  |  |  |         send_time = (s->mode & SSL_MODE_SEND_SERVERHELLO_TIME) != 0; | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |         send_time = (s->mode & SSL_MODE_SEND_CLIENTHELLO_TIME) != 0; | 
					
						
							|  |  |  |     if (send_time) { | 
					
						
							|  |  |  |         unsigned long Time = (unsigned long)time(NULL); | 
					
						
							|  |  |  |         unsigned char *p = result; | 
					
						
							|  |  |  |         l2n(Time, p); | 
					
						
							| 
									
										
										
										
											2015-02-26 19:57:37 +08:00
										 |  |  |         return RAND_bytes(p, len - 4); | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  |     } else | 
					
						
							| 
									
										
										
										
											2015-02-26 19:57:37 +08:00
										 |  |  |         return RAND_bytes(result, len); | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2013-10-21 06:03:24 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1999-04-20 05:31:43 +08:00
										 |  |  | static int ssl23_client_hello(SSL *s) | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  | { | 
					
						
							|  |  |  |     unsigned char *buf; | 
					
						
							|  |  |  |     unsigned char *p, *d; | 
					
						
							|  |  |  |     int i; | 
					
						
							|  |  |  |     unsigned long l; | 
					
						
							|  |  |  |     int version = 0, version_major, version_minor; | 
					
						
							|  |  |  |     int al = 0; | 
					
						
							| 
									
										
										
										
											2009-08-05 23:29:58 +08:00
										 |  |  | #ifndef OPENSSL_NO_COMP
 | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  |     int j; | 
					
						
							|  |  |  |     SSL_COMP *comp; | 
					
						
							| 
									
										
										
										
											2009-08-05 23:29:58 +08:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  |     int ret; | 
					
						
							|  |  |  |     unsigned long mask, options = s->options; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /*
 | 
					
						
							|  |  |  |      * SSL_OP_NO_X disables all protocols above X *if* there are | 
					
						
							|  |  |  |      * some protocols below X enabled. This is required in order | 
					
						
							|  |  |  |      * to maintain "version capability" vector contiguous. So | 
					
						
							|  |  |  |      * that if application wants to disable TLS1.0 in favour of | 
					
						
							|  |  |  |      * TLS1>=1, it would be insufficient to pass SSL_NO_TLSv1, the | 
					
						
							|  |  |  |      * answer is SSL_OP_NO_TLSv1|SSL_OP_NO_SSLv3|SSL_OP_NO_SSLv2. | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     mask = SSL_OP_NO_TLSv1_1 | SSL_OP_NO_TLSv1 | 
					
						
							| 
									
										
										
										
											2012-04-26 06:06:32 +08:00
										 |  |  | #if !defined(OPENSSL_NO_SSL3)
 | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  |         | SSL_OP_NO_SSLv3 | 
					
						
							| 
									
										
										
										
											2012-04-26 06:06:32 +08:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  |         ; | 
					
						
							| 
									
										
										
										
											2012-04-26 06:06:32 +08:00
										 |  |  | #if !defined(OPENSSL_NO_TLS1_2_CLIENT)
 | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  |     version = TLS1_2_VERSION; | 
					
						
							| 
									
										
										
										
											2012-04-26 06:06:32 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  |     if ((options & SSL_OP_NO_TLSv1_2) && (options & mask) != mask) | 
					
						
							|  |  |  |         version = TLS1_1_VERSION; | 
					
						
							| 
									
										
										
										
											2012-04-26 06:06:32 +08:00
										 |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  |     version = TLS1_1_VERSION; | 
					
						
							| 
									
										
										
										
											2012-04-26 06:06:32 +08:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  |     mask &= ~SSL_OP_NO_TLSv1_1; | 
					
						
							|  |  |  |     if ((options & SSL_OP_NO_TLSv1_1) && (options & mask) != mask) | 
					
						
							|  |  |  |         version = TLS1_VERSION; | 
					
						
							|  |  |  |     mask &= ~SSL_OP_NO_TLSv1; | 
					
						
							| 
									
										
										
										
											2012-04-26 06:06:32 +08:00
										 |  |  | #if !defined(OPENSSL_NO_SSL3)
 | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  |     if ((options & SSL_OP_NO_TLSv1) && (options & mask) != mask) | 
					
						
							|  |  |  |         version = SSL3_VERSION; | 
					
						
							|  |  |  |     mask &= ~SSL_OP_NO_SSLv3; | 
					
						
							| 
									
										
										
										
											2012-04-26 06:06:32 +08:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2007-09-21 14:54:24 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  |     buf = (unsigned char *)s->init_buf->data; | 
					
						
							|  |  |  |     if (s->state == SSL23_ST_CW_CLNT_HELLO_A) { | 
					
						
							|  |  |  |         p = s->s3->client_random; | 
					
						
							|  |  |  |         if (ssl_fill_hello_random(s, 0, p, SSL3_RANDOM_SIZE) <= 0) | 
					
						
							|  |  |  |             return -1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (version == TLS1_2_VERSION) { | 
					
						
							|  |  |  |             version_major = TLS1_2_VERSION_MAJOR; | 
					
						
							|  |  |  |             version_minor = TLS1_2_VERSION_MINOR; | 
					
						
							|  |  |  |         } else if (tls1_suiteb(s)) { | 
					
						
							|  |  |  |             SSLerr(SSL_F_SSL23_CLIENT_HELLO, | 
					
						
							|  |  |  |                    SSL_R_ONLY_TLS_1_2_ALLOWED_IN_SUITEB_MODE); | 
					
						
							|  |  |  |             return -1; | 
					
						
							|  |  |  |         } else if (version == TLS1_1_VERSION) { | 
					
						
							|  |  |  |             version_major = TLS1_1_VERSION_MAJOR; | 
					
						
							|  |  |  |             version_minor = TLS1_1_VERSION_MINOR; | 
					
						
							|  |  |  |         } else if (version == TLS1_VERSION) { | 
					
						
							|  |  |  |             version_major = TLS1_VERSION_MAJOR; | 
					
						
							|  |  |  |             version_minor = TLS1_VERSION_MINOR; | 
					
						
							|  |  |  |         } else if (FIPS_mode()) { | 
					
						
							|  |  |  |             SSLerr(SSL_F_SSL23_CLIENT_HELLO, | 
					
						
							|  |  |  |                    SSL_R_ONLY_TLS_ALLOWED_IN_FIPS_MODE); | 
					
						
							|  |  |  |             return -1; | 
					
						
							|  |  |  |         } else if (version == SSL3_VERSION) { | 
					
						
							|  |  |  |             version_major = SSL3_VERSION_MAJOR; | 
					
						
							|  |  |  |             version_minor = SSL3_VERSION_MINOR; | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |             SSLerr(SSL_F_SSL23_CLIENT_HELLO, SSL_R_NO_PROTOCOLS_AVAILABLE); | 
					
						
							|  |  |  |             return (-1); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         s->client_version = version; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         /* create Client Hello in SSL 3.0/TLS 1.0 format */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         /*
 | 
					
						
							|  |  |  |          * do the record header (5 bytes) and handshake message header (4 | 
					
						
							|  |  |  |          * bytes) last | 
					
						
							|  |  |  |          */ | 
					
						
							|  |  |  |         d = p = &(buf[9]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         *(p++) = version_major; | 
					
						
							|  |  |  |         *(p++) = version_minor; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         /* Random stuff */ | 
					
						
							|  |  |  |         memcpy(p, s->s3->client_random, SSL3_RANDOM_SIZE); | 
					
						
							|  |  |  |         p += SSL3_RANDOM_SIZE; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         /* Session ID (zero since there is no reuse) */ | 
					
						
							|  |  |  |         *(p++) = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         /* Ciphers supported (using SSL 3.0/TLS 1.0 format) */ | 
					
						
							|  |  |  |         i = ssl_cipher_list_to_bytes(s, SSL_get_ciphers(s), &(p[2]), | 
					
						
							|  |  |  |                                      ssl3_put_cipher_by_char); | 
					
						
							|  |  |  |         if (i == 0) { | 
					
						
							|  |  |  |             SSLerr(SSL_F_SSL23_CLIENT_HELLO, SSL_R_NO_CIPHERS_AVAILABLE); | 
					
						
							|  |  |  |             return -1; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2012-04-17 23:12:09 +08:00
										 |  |  | #ifdef OPENSSL_MAX_TLS1_2_CIPHER_LENGTH
 | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  |         /*
 | 
					
						
							|  |  |  |          * Some servers hang if client hello > 256 bytes as hack workaround | 
					
						
							|  |  |  |          * chop number of supported ciphers to keep it well below this if we | 
					
						
							|  |  |  |          * use TLS v1.2 | 
					
						
							|  |  |  |          */ | 
					
						
							|  |  |  |         if (TLS1_get_version(s) >= TLS1_2_VERSION | 
					
						
							|  |  |  |             && i > OPENSSL_MAX_TLS1_2_CIPHER_LENGTH) | 
					
						
							|  |  |  |             i = OPENSSL_MAX_TLS1_2_CIPHER_LENGTH & ~1; | 
					
						
							| 
									
										
										
										
											2012-04-17 23:12:09 +08:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  |         s2n(i, p); | 
					
						
							|  |  |  |         p += i; | 
					
						
							| 
									
										
										
										
											2005-05-12 02:25:49 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  |         /* COMPRESSION */ | 
					
						
							| 
									
										
										
										
											2006-01-03 07:14:37 +08:00
										 |  |  | #ifdef OPENSSL_NO_COMP
 | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  |         *(p++) = 1; | 
					
						
							| 
									
										
										
										
											2006-01-03 07:14:37 +08:00
										 |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  |         if (!ssl_allow_compression(s) || !s->ctx->comp_methods) | 
					
						
							|  |  |  |             j = 0; | 
					
						
							|  |  |  |         else | 
					
						
							|  |  |  |             j = sk_SSL_COMP_num(s->ctx->comp_methods); | 
					
						
							|  |  |  |         *(p++) = 1 + j; | 
					
						
							|  |  |  |         for (i = 0; i < j; i++) { | 
					
						
							|  |  |  |             comp = sk_SSL_COMP_value(s->ctx->comp_methods, i); | 
					
						
							|  |  |  |             *(p++) = comp->id; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2006-01-03 07:14:37 +08:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  |         *(p++) = 0;             /* Add the NULL method */ | 
					
						
							| 
									
										
										
										
											2006-01-03 11:27:19 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-01-03 07:14:37 +08:00
										 |  |  | #ifndef OPENSSL_NO_TLSEXT
 | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  |         /* TLS extensions */ | 
					
						
							|  |  |  |         if (ssl_prepare_clienthello_tlsext(s) <= 0) { | 
					
						
							|  |  |  |             SSLerr(SSL_F_SSL23_CLIENT_HELLO, SSL_R_CLIENTHELLO_TLSEXT); | 
					
						
							|  |  |  |             return -1; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         if ((p = | 
					
						
							|  |  |  |              ssl_add_clienthello_tlsext(s, p, buf + SSL3_RT_MAX_PLAIN_LENGTH, | 
					
						
							|  |  |  |                                         &al)) == NULL) { | 
					
						
							|  |  |  |             ssl3_send_alert(s, SSL3_AL_FATAL, al); | 
					
						
							|  |  |  |             SSLerr(SSL_F_SSL23_CLIENT_HELLO, ERR_R_INTERNAL_ERROR); | 
					
						
							|  |  |  |             return -1; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2006-01-03 07:14:37 +08:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |         l = p - d; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         /* fill in 4-byte handshake header */ | 
					
						
							|  |  |  |         d = &(buf[5]); | 
					
						
							|  |  |  |         *(d++) = SSL3_MT_CLIENT_HELLO; | 
					
						
							|  |  |  |         l2n3(l, d); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         l += 4; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (l > SSL3_RT_MAX_PLAIN_LENGTH) { | 
					
						
							|  |  |  |             SSLerr(SSL_F_SSL23_CLIENT_HELLO, ERR_R_INTERNAL_ERROR); | 
					
						
							|  |  |  |             return -1; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         /* fill in 5-byte record header */ | 
					
						
							|  |  |  |         d = buf; | 
					
						
							|  |  |  |         *(d++) = SSL3_RT_HANDSHAKE; | 
					
						
							|  |  |  |         *(d++) = version_major; | 
					
						
							|  |  |  |         /*
 | 
					
						
							|  |  |  |          * Some servers hang if we use long client hellos and a record number | 
					
						
							|  |  |  |          * > TLS 1.0. | 
					
						
							|  |  |  |          */ | 
					
						
							|  |  |  |         if (TLS1_get_client_version(s) > TLS1_VERSION) | 
					
						
							|  |  |  |             *(d++) = 1; | 
					
						
							|  |  |  |         else | 
					
						
							|  |  |  |             *(d++) = version_minor; | 
					
						
							|  |  |  |         s2n((int)l, d); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         /* number of bytes to write */ | 
					
						
							|  |  |  |         s->init_num = p - buf; | 
					
						
							|  |  |  |         s->init_off = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         ssl3_finish_mac(s, &(buf[5]), s->init_num - 5); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         s->state = SSL23_ST_CW_CLNT_HELLO_B; | 
					
						
							|  |  |  |         s->init_off = 0; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* SSL3_ST_CW_CLNT_HELLO_B */ | 
					
						
							|  |  |  |     ret = ssl23_write_bytes(s); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if ((ret >= 2) && s->msg_callback) { | 
					
						
							|  |  |  |         /* Client Hello has been sent; tell msg_callback */ | 
					
						
							|  |  |  |         s->msg_callback(1, version, SSL3_RT_HEADER, s->init_buf->data, 5, s, | 
					
						
							|  |  |  |                         s->msg_callback_arg); | 
					
						
							|  |  |  |         s->msg_callback(1, version, SSL3_RT_HANDSHAKE, s->init_buf->data + 5, | 
					
						
							|  |  |  |                         ret - 5, s, s->msg_callback_arg); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return ret; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											1998-12-21 18:52:47 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1999-04-20 05:31:43 +08:00
										 |  |  | static int ssl23_get_server_hello(SSL *s) | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2015-01-30 22:57:54 +08:00
										 |  |  |     unsigned char buf[8]; | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  |     unsigned char *p; | 
					
						
							|  |  |  |     int i; | 
					
						
							|  |  |  |     int n; | 
					
						
							| 
									
										
										
										
											1998-12-21 18:52:47 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  |     n = ssl23_read_bytes(s, 7); | 
					
						
							| 
									
										
										
										
											1998-12-21 18:52:47 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  |     if (n != 7) | 
					
						
							|  |  |  |         return (n); | 
					
						
							| 
									
										
										
										
											2015-02-03 04:55:15 +08:00
										 |  |  |     p = RECORD_LAYER_get_packet(&s->rlayer); | 
					
						
							| 
									
										
										
										
											1998-12-21 18:52:47 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  |     memcpy(buf, p, n); | 
					
						
							| 
									
										
										
										
											1998-12-21 18:52:47 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  |     if (p[1] == SSL3_VERSION_MAJOR && | 
					
						
							|  |  |  |         p[2] <= TLS1_2_VERSION_MINOR && | 
					
						
							|  |  |  |         ((p[0] == SSL3_RT_HANDSHAKE && p[5] == SSL3_MT_SERVER_HELLO) || | 
					
						
							|  |  |  |          (p[0] == SSL3_RT_ALERT && p[3] == 0 && p[4] == 2))) { | 
					
						
							|  |  |  |         /* we have sslv3 or tls1 (server hello or alert) */ | 
					
						
							| 
									
										
										
										
											1998-12-21 18:52:47 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-15 15:25:50 +08:00
										 |  |  | #ifndef OPENSSL_NO_SSL3
 | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  |         if ((p[2] == SSL3_VERSION_MINOR) && !(s->options & SSL_OP_NO_SSLv3)) { | 
					
						
							|  |  |  |             if (FIPS_mode()) { | 
					
						
							|  |  |  |                 SSLerr(SSL_F_SSL23_GET_SERVER_HELLO, | 
					
						
							|  |  |  |                        SSL_R_ONLY_TLS_ALLOWED_IN_FIPS_MODE); | 
					
						
							|  |  |  |                 goto err; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             s->version = SSL3_VERSION; | 
					
						
							|  |  |  |             s->method = SSLv3_client_method(); | 
					
						
							|  |  |  |         } else | 
					
						
							| 
									
										
										
										
											2014-10-15 15:25:50 +08:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  |         if ((p[2] == TLS1_VERSION_MINOR) && !(s->options & SSL_OP_NO_TLSv1)) { | 
					
						
							|  |  |  |             s->version = TLS1_VERSION; | 
					
						
							|  |  |  |             s->method = TLSv1_client_method(); | 
					
						
							|  |  |  |         } else if ((p[2] == TLS1_1_VERSION_MINOR) && | 
					
						
							|  |  |  |                    !(s->options & SSL_OP_NO_TLSv1_1)) { | 
					
						
							|  |  |  |             s->version = TLS1_1_VERSION; | 
					
						
							|  |  |  |             s->method = TLSv1_1_client_method(); | 
					
						
							|  |  |  |         } else if ((p[2] == TLS1_2_VERSION_MINOR) && | 
					
						
							|  |  |  |                    !(s->options & SSL_OP_NO_TLSv1_2)) { | 
					
						
							|  |  |  |             s->version = TLS1_2_VERSION; | 
					
						
							|  |  |  |             s->method = TLSv1_2_client_method(); | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |             SSLerr(SSL_F_SSL23_GET_SERVER_HELLO, SSL_R_UNSUPPORTED_PROTOCOL); | 
					
						
							|  |  |  |             goto err; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         /* ensure that TLS_MAX_VERSION is up-to-date */ | 
					
						
							|  |  |  |         OPENSSL_assert(s->version <= TLS_MAX_VERSION); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (!ssl_security(s, SSL_SECOP_VERSION, 0, s->version, NULL)) { | 
					
						
							|  |  |  |             SSLerr(SSL_F_SSL23_GET_SERVER_HELLO, SSL_R_VERSION_TOO_LOW); | 
					
						
							|  |  |  |             goto err; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (p[0] == SSL3_RT_ALERT && p[5] != SSL3_AL_WARNING) { | 
					
						
							|  |  |  |             /* fatal alert */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             void (*cb) (const SSL *ssl, int type, int val) = NULL; | 
					
						
							|  |  |  |             int j; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if (s->info_callback != NULL) | 
					
						
							|  |  |  |                 cb = s->info_callback; | 
					
						
							|  |  |  |             else if (s->ctx->info_callback != NULL) | 
					
						
							|  |  |  |                 cb = s->ctx->info_callback; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             i = p[5]; | 
					
						
							|  |  |  |             if (cb != NULL) { | 
					
						
							|  |  |  |                 j = (i << 8) | p[6]; | 
					
						
							|  |  |  |                 cb(s, SSL_CB_READ_ALERT, j); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if (s->msg_callback) { | 
					
						
							|  |  |  |                 s->msg_callback(0, s->version, SSL3_RT_HEADER, p, 5, s, | 
					
						
							|  |  |  |                                 s->msg_callback_arg); | 
					
						
							|  |  |  |                 s->msg_callback(0, s->version, SSL3_RT_ALERT, p + 5, 2, s, | 
					
						
							|  |  |  |                                 s->msg_callback_arg); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             s->rwstate = SSL_NOTHING; | 
					
						
							|  |  |  |             SSLerr(SSL_F_SSL23_GET_SERVER_HELLO, SSL_AD_REASON_OFFSET + p[6]); | 
					
						
							|  |  |  |             goto err; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (!ssl_init_wbio_buffer(s, 1)) | 
					
						
							|  |  |  |             goto err; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         /* we are in this state */ | 
					
						
							|  |  |  |         s->state = SSL3_ST_CR_SRVR_HELLO_A; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         /*
 | 
					
						
							|  |  |  |          * put the 7 bytes we have read into the input buffer for SSLv3 | 
					
						
							|  |  |  |          */ | 
					
						
							| 
									
										
										
										
											2015-02-02 21:43:38 +08:00
										 |  |  |         if(!RECORD_LAYER_set_data(&s->rlayer, buf, n)) | 
					
						
							|  |  |  |             goto err; | 
					
						
							| 
									
										
										
										
											2015-01-22 11:40:55 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |         s->handshake_func = s->method->ssl_connect; | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |         SSLerr(SSL_F_SSL23_GET_SERVER_HELLO, SSL_R_UNKNOWN_PROTOCOL); | 
					
						
							|  |  |  |         goto err; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     s->init_num = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /*
 | 
					
						
							|  |  |  |      * Since, if we are sending a ssl23 client hello, we are not reusing a | 
					
						
							|  |  |  |      * session-id | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     if (!ssl_get_new_session(s, 0)) | 
					
						
							|  |  |  |         goto err; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return (SSL_connect(s)); | 
					
						
							|  |  |  |  err: | 
					
						
							|  |  |  |     return (-1); | 
					
						
							|  |  |  | } |