|
1 /* ssl/s23_clnt.c */ |
|
2 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) |
|
3 * All rights reserved. |
|
4 * |
|
5 * This package is an SSL implementation written |
|
6 * by Eric Young (eay@cryptsoft.com). |
|
7 * The implementation was written so as to conform with Netscapes SSL. |
|
8 * |
|
9 * This library is free for commercial and non-commercial use as long as |
|
10 * the following conditions are aheared to. The following conditions |
|
11 * apply to all code found in this distribution, be it the RC4, RSA, |
|
12 * lhash, DES, etc., code; not just the SSL code. The SSL documentation |
|
13 * included with this distribution is covered by the same copyright terms |
|
14 * except that the holder is Tim Hudson (tjh@cryptsoft.com). |
|
15 * |
|
16 * Copyright remains Eric Young's, and as such any Copyright notices in |
|
17 * the code are not to be removed. |
|
18 * If this package is used in a product, Eric Young should be given attribution |
|
19 * as the author of the parts of the library used. |
|
20 * This can be in the form of a textual message at program startup or |
|
21 * in documentation (online or textual) provided with the package. |
|
22 * |
|
23 * Redistribution and use in source and binary forms, with or without |
|
24 * modification, are permitted provided that the following conditions |
|
25 * are met: |
|
26 * 1. Redistributions of source code must retain the copyright |
|
27 * notice, this list of conditions and the following disclaimer. |
|
28 * 2. Redistributions in binary form must reproduce the above copyright |
|
29 * notice, this list of conditions and the following disclaimer in the |
|
30 * documentation and/or other materials provided with the distribution. |
|
31 * 3. All advertising materials mentioning features or use of this software |
|
32 * must display the following acknowledgement: |
|
33 * "This product includes cryptographic software written by |
|
34 * Eric Young (eay@cryptsoft.com)" |
|
35 * The word 'cryptographic' can be left out if the rouines from the library |
|
36 * being used are not cryptographic related :-). |
|
37 * 4. If you include any Windows specific code (or a derivative thereof) from |
|
38 * the apps directory (application code) you must include an acknowledgement: |
|
39 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" |
|
40 * |
|
41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND |
|
42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
|
43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
|
44 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE |
|
45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
|
46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
|
47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
|
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
|
49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
|
50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
|
51 * SUCH DAMAGE. |
|
52 * |
|
53 * The licence and distribution terms for any publically available version or |
|
54 * derivative of this code cannot be changed. i.e. this code cannot simply be |
|
55 * copied and put under another distribution licence |
|
56 * [including the GNU Public Licence.] |
|
57 */ |
|
58 /* |
|
59 © Portions copyright (c) 2006 Nokia Corporation. All rights reserved. |
|
60 */ |
|
61 |
|
62 #include <stdio.h> |
|
63 #include "ssl_locl.h" |
|
64 #include <openssl/buffer.h> |
|
65 #include <openssl/rand.h> |
|
66 #include <openssl/objects.h> |
|
67 #include <openssl/evp.h> |
|
68 |
|
69 #if (defined(SYMBIAN) && (defined(__WINSCW__) || defined(__WINS__))) |
|
70 #include "libssl_wsd.h" |
|
71 #endif |
|
72 |
|
73 #ifdef EMULATOR |
|
74 |
|
75 GET_STATIC_VAR_FROM_TLS(SSLv23_client_method_data,s23_clnt,SSL_METHOD) |
|
76 |
|
77 #define SSLv23_client_method_data (*GET_WSD_VAR_NAME(SSLv23_client_method_data,s23_clnt,s)()) |
|
78 |
|
79 #endif |
|
80 static SSL_METHOD *ssl23_get_client_method(int ver); |
|
81 static int ssl23_client_hello(SSL *s); |
|
82 static int ssl23_get_server_hello(SSL *s); |
|
83 static SSL_METHOD *ssl23_get_client_method(int ver) |
|
84 { |
|
85 #ifndef OPENSSL_NO_SSL2 |
|
86 if (ver == SSL2_VERSION) |
|
87 return(SSLv2_client_method()); |
|
88 #endif |
|
89 if (ver == SSL3_VERSION) |
|
90 return(SSLv3_client_method()); |
|
91 else if (ver == TLS1_VERSION) |
|
92 return(TLSv1_client_method()); |
|
93 else |
|
94 return(NULL); |
|
95 } |
|
96 |
|
97 EXPORT_C IMPLEMENT_ssl23_meth_func(SSLv23_client_method, |
|
98 ssl_undefined_function, |
|
99 ssl23_connect, |
|
100 ssl23_get_client_method) |
|
101 |
|
102 int ssl23_connect(SSL *s) |
|
103 { |
|
104 BUF_MEM *buf=NULL; |
|
105 unsigned long Time=(unsigned long)time(NULL); |
|
106 void (*cb)(const SSL *ssl,int type,int val)=NULL; |
|
107 int ret= -1; |
|
108 int new_state,state; |
|
109 |
|
110 RAND_add(&Time,sizeof(Time),0); |
|
111 ERR_clear_error(); |
|
112 clear_sys_error(); |
|
113 |
|
114 if (s->info_callback != NULL) |
|
115 cb=s->info_callback; |
|
116 else if (s->ctx->info_callback != NULL) |
|
117 cb=s->ctx->info_callback; |
|
118 |
|
119 s->in_handshake++; |
|
120 if (!SSL_in_init(s) || SSL_in_before(s)) SSL_clear(s); |
|
121 |
|
122 for (;;) |
|
123 { |
|
124 state=s->state; |
|
125 |
|
126 switch(s->state) |
|
127 { |
|
128 case SSL_ST_BEFORE: |
|
129 case SSL_ST_CONNECT: |
|
130 case SSL_ST_BEFORE|SSL_ST_CONNECT: |
|
131 case SSL_ST_OK|SSL_ST_CONNECT: |
|
132 |
|
133 if (s->session != NULL) |
|
134 { |
|
135 SSLerr(SSL_F_SSL23_CONNECT,SSL_R_SSL23_DOING_SESSION_ID_REUSE); |
|
136 ret= -1; |
|
137 goto end; |
|
138 } |
|
139 s->server=0; |
|
140 if (cb != NULL) cb(s,SSL_CB_HANDSHAKE_START,1); |
|
141 |
|
142 /* s->version=TLS1_VERSION; */ |
|
143 s->type=SSL_ST_CONNECT; |
|
144 |
|
145 if (s->init_buf == NULL) |
|
146 { |
|
147 if ((buf=BUF_MEM_new()) == NULL) |
|
148 { |
|
149 ret= -1; |
|
150 goto end; |
|
151 } |
|
152 if (!BUF_MEM_grow(buf,SSL3_RT_MAX_PLAIN_LENGTH)) |
|
153 { |
|
154 ret= -1; |
|
155 goto end; |
|
156 } |
|
157 s->init_buf=buf; |
|
158 buf=NULL; |
|
159 } |
|
160 |
|
161 if (!ssl3_setup_buffers(s)) { ret= -1; goto end; } |
|
162 |
|
163 ssl3_init_finished_mac(s); |
|
164 |
|
165 s->state=SSL23_ST_CW_CLNT_HELLO_A; |
|
166 s->ctx->stats.sess_connect++; |
|
167 s->init_num=0; |
|
168 break; |
|
169 |
|
170 case SSL23_ST_CW_CLNT_HELLO_A: |
|
171 case SSL23_ST_CW_CLNT_HELLO_B: |
|
172 |
|
173 s->shutdown=0; |
|
174 ret=ssl23_client_hello(s); |
|
175 if (ret <= 0) goto end; |
|
176 s->state=SSL23_ST_CR_SRVR_HELLO_A; |
|
177 s->init_num=0; |
|
178 |
|
179 break; |
|
180 |
|
181 case SSL23_ST_CR_SRVR_HELLO_A: |
|
182 case SSL23_ST_CR_SRVR_HELLO_B: |
|
183 ret=ssl23_get_server_hello(s); |
|
184 if (ret >= 0) cb=NULL; |
|
185 goto end; |
|
186 /* break; */ |
|
187 |
|
188 default: |
|
189 SSLerr(SSL_F_SSL23_CONNECT,SSL_R_UNKNOWN_STATE); |
|
190 ret= -1; |
|
191 goto end; |
|
192 /* break; */ |
|
193 } |
|
194 |
|
195 if (s->debug) { (void)BIO_flush(s->wbio); } |
|
196 |
|
197 if ((cb != NULL) && (s->state != state)) |
|
198 { |
|
199 new_state=s->state; |
|
200 s->state=state; |
|
201 cb(s,SSL_CB_CONNECT_LOOP,1); |
|
202 s->state=new_state; |
|
203 } |
|
204 } |
|
205 end: |
|
206 s->in_handshake--; |
|
207 if (buf != NULL) |
|
208 BUF_MEM_free(buf); |
|
209 if (cb != NULL) |
|
210 cb(s,SSL_CB_CONNECT_EXIT,ret); |
|
211 return(ret); |
|
212 } |
|
213 |
|
214 |
|
215 static int ssl23_client_hello(SSL *s) |
|
216 { |
|
217 unsigned char *buf; |
|
218 unsigned char *p,*d; |
|
219 int i,j,ch_len; |
|
220 unsigned long Time,l; |
|
221 int ssl2_compat; |
|
222 int version = 0, version_major, version_minor; |
|
223 SSL_COMP *comp; |
|
224 int ret; |
|
225 |
|
226 ssl2_compat = (s->options & SSL_OP_NO_SSLv2) ? 0 : 1; |
|
227 |
|
228 if (!(s->options & SSL_OP_NO_TLSv1)) |
|
229 { |
|
230 version = TLS1_VERSION; |
|
231 } |
|
232 else if (!(s->options & SSL_OP_NO_SSLv3)) |
|
233 { |
|
234 version = SSL3_VERSION; |
|
235 } |
|
236 else if (!(s->options & SSL_OP_NO_SSLv2)) |
|
237 { |
|
238 version = SSL2_VERSION; |
|
239 } |
|
240 |
|
241 buf=(unsigned char *)s->init_buf->data; |
|
242 if (s->state == SSL23_ST_CW_CLNT_HELLO_A) |
|
243 { |
|
244 #if 0 |
|
245 /* don't reuse session-id's */ |
|
246 if (!ssl_get_new_session(s,0)) |
|
247 { |
|
248 return(-1); |
|
249 } |
|
250 #endif |
|
251 |
|
252 p=s->s3->client_random; |
|
253 Time=(unsigned long)time(NULL); /* Time */ |
|
254 l2n(Time,p); |
|
255 if (RAND_pseudo_bytes(p,SSL3_RANDOM_SIZE-4) <= 0) |
|
256 return -1; |
|
257 |
|
258 if (version == TLS1_VERSION) |
|
259 { |
|
260 version_major = TLS1_VERSION_MAJOR; |
|
261 version_minor = TLS1_VERSION_MINOR; |
|
262 } |
|
263 else if (version == SSL3_VERSION) |
|
264 { |
|
265 version_major = SSL3_VERSION_MAJOR; |
|
266 version_minor = SSL3_VERSION_MINOR; |
|
267 } |
|
268 else if (version == SSL2_VERSION) |
|
269 { |
|
270 version_major = SSL2_VERSION_MAJOR; |
|
271 version_minor = SSL2_VERSION_MINOR; |
|
272 } |
|
273 else |
|
274 { |
|
275 SSLerr(SSL_F_SSL23_CLIENT_HELLO,SSL_R_NO_PROTOCOLS_AVAILABLE); |
|
276 return(-1); |
|
277 } |
|
278 |
|
279 s->client_version = version; |
|
280 |
|
281 if (ssl2_compat) |
|
282 { |
|
283 /* create SSL 2.0 compatible Client Hello */ |
|
284 |
|
285 /* two byte record header will be written last */ |
|
286 d = &(buf[2]); |
|
287 p = d + 9; /* leave space for message type, version, individual length fields */ |
|
288 |
|
289 *(d++) = SSL2_MT_CLIENT_HELLO; |
|
290 *(d++) = version_major; |
|
291 *(d++) = version_minor; |
|
292 |
|
293 /* Ciphers supported */ |
|
294 i=ssl_cipher_list_to_bytes(s,SSL_get_ciphers(s),p,0); |
|
295 if (i == 0) |
|
296 { |
|
297 /* no ciphers */ |
|
298 SSLerr(SSL_F_SSL23_CLIENT_HELLO,SSL_R_NO_CIPHERS_AVAILABLE); |
|
299 return -1; |
|
300 } |
|
301 s2n(i,d); |
|
302 p+=i; |
|
303 |
|
304 /* put in the session-id length (zero since there is no reuse) */ |
|
305 #if 0 |
|
306 s->session->session_id_length=0; |
|
307 #endif |
|
308 s2n(0,d); |
|
309 |
|
310 if (s->options & SSL_OP_NETSCAPE_CHALLENGE_BUG) |
|
311 ch_len=SSL2_CHALLENGE_LENGTH; |
|
312 else |
|
313 ch_len=SSL2_MAX_CHALLENGE_LENGTH; |
|
314 |
|
315 /* write out sslv2 challenge */ |
|
316 if (SSL3_RANDOM_SIZE < ch_len) |
|
317 i=SSL3_RANDOM_SIZE; |
|
318 else |
|
319 i=ch_len; |
|
320 s2n(i,d); |
|
321 memset(&(s->s3->client_random[0]),0,SSL3_RANDOM_SIZE); |
|
322 if (RAND_pseudo_bytes(&(s->s3->client_random[SSL3_RANDOM_SIZE-i]),i) <= 0) |
|
323 return -1; |
|
324 |
|
325 memcpy(p,&(s->s3->client_random[SSL3_RANDOM_SIZE-i]),i); |
|
326 p+=i; |
|
327 |
|
328 i= p- &(buf[2]); |
|
329 buf[0]=((i>>8)&0xff)|0x80; |
|
330 buf[1]=(i&0xff); |
|
331 |
|
332 /* number of bytes to write */ |
|
333 s->init_num=i+2; |
|
334 s->init_off=0; |
|
335 |
|
336 ssl3_finish_mac(s,&(buf[2]),i); |
|
337 } |
|
338 else |
|
339 { |
|
340 /* create Client Hello in SSL 3.0/TLS 1.0 format */ |
|
341 |
|
342 /* do the record header (5 bytes) and handshake message header (4 bytes) last */ |
|
343 d = p = &(buf[9]); |
|
344 |
|
345 *(p++) = version_major; |
|
346 *(p++) = version_minor; |
|
347 |
|
348 /* Random stuff */ |
|
349 memcpy(p, s->s3->client_random, SSL3_RANDOM_SIZE); |
|
350 p += SSL3_RANDOM_SIZE; |
|
351 |
|
352 /* Session ID (zero since there is no reuse) */ |
|
353 *(p++) = 0; |
|
354 |
|
355 /* Ciphers supported (using SSL 3.0/TLS 1.0 format) */ |
|
356 i=ssl_cipher_list_to_bytes(s,SSL_get_ciphers(s),&(p[2]),ssl3_put_cipher_by_char); |
|
357 if (i == 0) |
|
358 { |
|
359 SSLerr(SSL_F_SSL23_CLIENT_HELLO,SSL_R_NO_CIPHERS_AVAILABLE); |
|
360 return -1; |
|
361 } |
|
362 s2n(i,p); |
|
363 p+=i; |
|
364 |
|
365 /* COMPRESSION */ |
|
366 if (s->ctx->comp_methods == NULL) |
|
367 j=0; |
|
368 else |
|
369 j=sk_SSL_COMP_num(s->ctx->comp_methods); |
|
370 *(p++)=1+j; |
|
371 for (i=0; i<j; i++) |
|
372 { |
|
373 comp=sk_SSL_COMP_value(s->ctx->comp_methods,i); |
|
374 *(p++)=comp->id; |
|
375 } |
|
376 *(p++)=0; /* Add the NULL method */ |
|
377 |
|
378 l = p-d; |
|
379 *p = 42; |
|
380 |
|
381 /* fill in 4-byte handshake header */ |
|
382 d=&(buf[5]); |
|
383 *(d++)=SSL3_MT_CLIENT_HELLO; |
|
384 l2n3(l,d); |
|
385 |
|
386 l += 4; |
|
387 |
|
388 if (l > SSL3_RT_MAX_PLAIN_LENGTH) |
|
389 { |
|
390 SSLerr(SSL_F_SSL23_CLIENT_HELLO,ERR_R_INTERNAL_ERROR); |
|
391 return -1; |
|
392 } |
|
393 |
|
394 /* fill in 5-byte record header */ |
|
395 d=buf; |
|
396 *(d++) = SSL3_RT_HANDSHAKE; |
|
397 *(d++) = version_major; |
|
398 *(d++) = version_minor; /* arguably we should send the *lowest* suported version here |
|
399 * (indicating, e.g., TLS 1.0 in "SSL 3.0 format") */ |
|
400 s2n((int)l,d); |
|
401 |
|
402 /* number of bytes to write */ |
|
403 s->init_num=p-buf; |
|
404 s->init_off=0; |
|
405 |
|
406 ssl3_finish_mac(s,&(buf[5]), s->init_num - 5); |
|
407 } |
|
408 |
|
409 s->state=SSL23_ST_CW_CLNT_HELLO_B; |
|
410 s->init_off=0; |
|
411 } |
|
412 |
|
413 /* SSL3_ST_CW_CLNT_HELLO_B */ |
|
414 ret = ssl23_write_bytes(s); |
|
415 |
|
416 if ((ret >= 2) && s->msg_callback) |
|
417 { |
|
418 /* Client Hello has been sent; tell msg_callback */ |
|
419 |
|
420 if (ssl2_compat) |
|
421 s->msg_callback(1, SSL2_VERSION, 0, s->init_buf->data+2, ret-2, s, s->msg_callback_arg); |
|
422 else |
|
423 s->msg_callback(1, version, SSL3_RT_HANDSHAKE, s->init_buf->data+5, ret-5, s, s->msg_callback_arg); |
|
424 } |
|
425 |
|
426 return ret; |
|
427 } |
|
428 |
|
429 static int ssl23_get_server_hello(SSL *s) |
|
430 { |
|
431 char buf[8]; |
|
432 unsigned char *p; |
|
433 int i; |
|
434 int n; |
|
435 |
|
436 n=ssl23_read_bytes(s,7); |
|
437 |
|
438 if (n != 7) return(n); |
|
439 p=s->packet; |
|
440 |
|
441 memcpy(buf,p,n); |
|
442 |
|
443 if ((p[0] & 0x80) && (p[2] == SSL2_MT_SERVER_HELLO) && |
|
444 (p[5] == 0x00) && (p[6] == 0x02)) |
|
445 { |
|
446 #ifdef OPENSSL_NO_SSL2 |
|
447 SSLerr(SSL_F_SSL23_GET_SERVER_HELLO,SSL_R_UNSUPPORTED_PROTOCOL); |
|
448 goto err; |
|
449 #else |
|
450 /* we are talking sslv2 */ |
|
451 /* we need to clean up the SSLv3 setup and put in the |
|
452 * sslv2 stuff. */ |
|
453 int ch_len; |
|
454 |
|
455 if (s->options & SSL_OP_NO_SSLv2) |
|
456 { |
|
457 SSLerr(SSL_F_SSL23_GET_SERVER_HELLO,SSL_R_UNSUPPORTED_PROTOCOL); |
|
458 goto err; |
|
459 } |
|
460 if (s->s2 == NULL) |
|
461 { |
|
462 if (!ssl2_new(s)) |
|
463 goto err; |
|
464 } |
|
465 else |
|
466 ssl2_clear(s); |
|
467 |
|
468 if (s->options & SSL_OP_NETSCAPE_CHALLENGE_BUG) |
|
469 ch_len=SSL2_CHALLENGE_LENGTH; |
|
470 else |
|
471 ch_len=SSL2_MAX_CHALLENGE_LENGTH; |
|
472 |
|
473 /* write out sslv2 challenge */ |
|
474 i=(SSL3_RANDOM_SIZE < ch_len) |
|
475 ?SSL3_RANDOM_SIZE:ch_len; |
|
476 s->s2->challenge_length=i; |
|
477 memcpy(s->s2->challenge, |
|
478 &(s->s3->client_random[SSL3_RANDOM_SIZE-i]),i); |
|
479 |
|
480 if (s->s3 != NULL) ssl3_free(s); |
|
481 |
|
482 if (!BUF_MEM_grow_clean(s->init_buf, |
|
483 SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER)) |
|
484 { |
|
485 SSLerr(SSL_F_SSL23_GET_SERVER_HELLO,ERR_R_BUF_LIB); |
|
486 goto err; |
|
487 } |
|
488 |
|
489 s->state=SSL2_ST_GET_SERVER_HELLO_A; |
|
490 if (!(s->client_version == SSL2_VERSION)) |
|
491 /* use special padding (SSL 3.0 draft/RFC 2246, App. E.2) */ |
|
492 s->s2->ssl2_rollback=1; |
|
493 |
|
494 /* setup the 5 bytes we have read so we get them from |
|
495 * the sslv2 buffer */ |
|
496 s->rstate=SSL_ST_READ_HEADER; |
|
497 s->packet_length=n; |
|
498 s->packet= &(s->s2->rbuf[0]); |
|
499 memcpy(s->packet,buf,n); |
|
500 s->s2->rbuf_left=n; |
|
501 s->s2->rbuf_offs=0; |
|
502 |
|
503 /* we have already written one */ |
|
504 s->s2->write_sequence=1; |
|
505 |
|
506 s->method=SSLv2_client_method(); |
|
507 s->handshake_func=s->method->ssl_connect; |
|
508 #endif |
|
509 } |
|
510 else if ((p[0] == SSL3_RT_HANDSHAKE) && |
|
511 (p[1] == SSL3_VERSION_MAJOR) && |
|
512 ((p[2] == SSL3_VERSION_MINOR) || |
|
513 (p[2] == TLS1_VERSION_MINOR)) && |
|
514 (p[5] == SSL3_MT_SERVER_HELLO)) |
|
515 { |
|
516 /* we have sslv3 or tls1 */ |
|
517 |
|
518 if (!ssl_init_wbio_buffer(s,1)) goto err; |
|
519 |
|
520 /* we are in this state */ |
|
521 s->state=SSL3_ST_CR_SRVR_HELLO_A; |
|
522 |
|
523 /* put the 5 bytes we have read into the input buffer |
|
524 * for SSLv3 */ |
|
525 s->rstate=SSL_ST_READ_HEADER; |
|
526 s->packet_length=n; |
|
527 s->packet= &(s->s3->rbuf.buf[0]); |
|
528 memcpy(s->packet,buf,n); |
|
529 s->s3->rbuf.left=n; |
|
530 s->s3->rbuf.offset=0; |
|
531 |
|
532 if ((p[2] == SSL3_VERSION_MINOR) && |
|
533 !(s->options & SSL_OP_NO_SSLv3)) |
|
534 { |
|
535 s->version=SSL3_VERSION; |
|
536 s->method=SSLv3_client_method(); |
|
537 } |
|
538 else if ((p[2] == TLS1_VERSION_MINOR) && |
|
539 !(s->options & SSL_OP_NO_TLSv1)) |
|
540 { |
|
541 s->version=TLS1_VERSION; |
|
542 s->method=TLSv1_client_method(); |
|
543 } |
|
544 else |
|
545 { |
|
546 SSLerr(SSL_F_SSL23_GET_SERVER_HELLO,SSL_R_UNSUPPORTED_PROTOCOL); |
|
547 goto err; |
|
548 } |
|
549 |
|
550 s->handshake_func=s->method->ssl_connect; |
|
551 } |
|
552 else if ((p[0] == SSL3_RT_ALERT) && |
|
553 (p[1] == SSL3_VERSION_MAJOR) && |
|
554 ((p[2] == SSL3_VERSION_MINOR) || |
|
555 (p[2] == TLS1_VERSION_MINOR)) && |
|
556 (p[3] == 0) && |
|
557 (p[4] == 2)) |
|
558 { |
|
559 void (*cb)(const SSL *ssl,int type,int val)=NULL; |
|
560 int j; |
|
561 |
|
562 /* An alert */ |
|
563 if (s->info_callback != NULL) |
|
564 cb=s->info_callback; |
|
565 else if (s->ctx->info_callback != NULL) |
|
566 cb=s->ctx->info_callback; |
|
567 |
|
568 i=p[5]; |
|
569 if (cb != NULL) |
|
570 { |
|
571 j=(i<<8)|p[6]; |
|
572 cb(s,SSL_CB_READ_ALERT,j); |
|
573 } |
|
574 |
|
575 s->rwstate=SSL_NOTHING; |
|
576 SSLerr(SSL_F_SSL23_GET_SERVER_HELLO,SSL_AD_REASON_OFFSET+p[6]); |
|
577 goto err; |
|
578 } |
|
579 else |
|
580 { |
|
581 SSLerr(SSL_F_SSL23_GET_SERVER_HELLO,SSL_R_UNKNOWN_PROTOCOL); |
|
582 goto err; |
|
583 } |
|
584 s->init_num=0; |
|
585 |
|
586 /* Since, if we are sending a ssl23 client hello, we are not |
|
587 * reusing a session-id */ |
|
588 if (!ssl_get_new_session(s,0)) |
|
589 goto err; |
|
590 |
|
591 return(SSL_connect(s)); |
|
592 err: |
|
593 return(-1); |
|
594 } |
|
595 |