1 |
/* ssl/s23_srvr.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 |
* Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved. |
60 |
* |
61 |
* Redistribution and use in source and binary forms, with or without |
62 |
* modification, are permitted provided that the following conditions |
63 |
* are met: |
64 |
* |
65 |
* 1. Redistributions of source code must retain the above copyright |
66 |
* notice, this list of conditions and the following disclaimer. |
67 |
* |
68 |
* 2. Redistributions in binary form must reproduce the above copyright |
69 |
* notice, this list of conditions and the following disclaimer in |
70 |
* the documentation and/or other materials provided with the |
71 |
* distribution. |
72 |
* |
73 |
* 3. All advertising materials mentioning features or use of this |
74 |
* software must display the following acknowledgment: |
75 |
* "This product includes software developed by the OpenSSL Project |
76 |
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)" |
77 |
* |
78 |
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to |
79 |
* endorse or promote products derived from this software without |
80 |
* prior written permission. For written permission, please contact |
81 |
* openssl-core@openssl.org. |
82 |
* |
83 |
* 5. Products derived from this software may not be called "OpenSSL" |
84 |
* nor may "OpenSSL" appear in their names without prior written |
85 |
* permission of the OpenSSL Project. |
86 |
* |
87 |
* 6. Redistributions of any form whatsoever must retain the following |
88 |
* acknowledgment: |
89 |
* "This product includes software developed by the OpenSSL Project |
90 |
* for use in the OpenSSL Toolkit (http://www.openssl.org/)" |
91 |
* |
92 |
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY |
93 |
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
94 |
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
95 |
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR |
96 |
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
97 |
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
98 |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
99 |
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
100 |
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, |
101 |
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
102 |
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED |
103 |
* OF THE POSSIBILITY OF SUCH DAMAGE. |
104 |
* ==================================================================== |
105 |
* |
106 |
* This product includes cryptographic software written by Eric Young |
107 |
* (eay@cryptsoft.com). This product includes software written by Tim |
108 |
* Hudson (tjh@cryptsoft.com). |
109 |
* |
110 |
*/ |
111 |
|
112 |
#include <stdio.h> |
113 |
#include "ssl_locl.h" |
114 |
#include <openssl/buffer.h> |
115 |
#include <openssl/rand.h> |
116 |
#include <openssl/objects.h> |
117 |
#include <openssl/evp.h> |
118 |
|
119 |
static SSL_METHOD *ssl23_get_server_method(int ver); |
120 |
int ssl23_get_client_hello(SSL *s); |
121 |
static SSL_METHOD *ssl23_get_server_method(int ver) |
122 |
{ |
123 |
#ifndef OPENSSL_NO_SSL2 |
124 |
if (ver == SSL2_VERSION) |
125 |
return(SSLv2_server_method()); |
126 |
#endif |
127 |
#ifndef OPENSSL_NO_SSL3 |
128 |
if (ver == SSL3_VERSION) |
129 |
return(SSLv3_server_method()); |
130 |
#endif |
131 |
if (ver == TLS1_VERSION) |
132 |
return(TLSv1_server_method()); |
133 |
else |
134 |
return(NULL); |
135 |
} |
136 |
|
137 |
IMPLEMENT_ssl23_meth_func(SSLv23_server_method, |
138 |
ssl23_accept, |
139 |
ssl_undefined_function, |
140 |
ssl23_get_server_method) |
141 |
|
142 |
int ssl23_accept(SSL *s) |
143 |
{ |
144 |
BUF_MEM *buf; |
145 |
unsigned long Time=(unsigned long)time(NULL); |
146 |
void (*cb)(const SSL *ssl,int type,int val)=NULL; |
147 |
int ret= -1; |
148 |
int new_state,state; |
149 |
|
150 |
RAND_add(&Time,sizeof(Time),0); |
151 |
ERR_clear_error(); |
152 |
clear_sys_error(); |
153 |
|
154 |
if (s->info_callback != NULL) |
155 |
cb=s->info_callback; |
156 |
else if (s->ctx->info_callback != NULL) |
157 |
cb=s->ctx->info_callback; |
158 |
|
159 |
s->in_handshake++; |
160 |
if (!SSL_in_init(s) || SSL_in_before(s)) SSL_clear(s); |
161 |
|
162 |
for (;;) |
163 |
{ |
164 |
state=s->state; |
165 |
|
166 |
switch(s->state) |
167 |
{ |
168 |
case SSL_ST_BEFORE: |
169 |
case SSL_ST_ACCEPT: |
170 |
case SSL_ST_BEFORE|SSL_ST_ACCEPT: |
171 |
case SSL_ST_OK|SSL_ST_ACCEPT: |
172 |
|
173 |
s->server=1; |
174 |
if (cb != NULL) cb(s,SSL_CB_HANDSHAKE_START,1); |
175 |
|
176 |
/* s->version=SSL3_VERSION; */ |
177 |
s->type=SSL_ST_ACCEPT; |
178 |
|
179 |
if (s->init_buf == NULL) |
180 |
{ |
181 |
if ((buf=BUF_MEM_new()) == NULL) |
182 |
{ |
183 |
ret= -1; |
184 |
goto end; |
185 |
} |
186 |
if (!BUF_MEM_grow(buf,SSL3_RT_MAX_PLAIN_LENGTH)) |
187 |
{ |
188 |
ret= -1; |
189 |
goto end; |
190 |
} |
191 |
s->init_buf=buf; |
192 |
} |
193 |
|
194 |
ssl3_init_finished_mac(s); |
195 |
|
196 |
s->state=SSL23_ST_SR_CLNT_HELLO_A; |
197 |
s->ctx->stats.sess_accept++; |
198 |
s->init_num=0; |
199 |
break; |
200 |
|
201 |
case SSL23_ST_SR_CLNT_HELLO_A: |
202 |
case SSL23_ST_SR_CLNT_HELLO_B: |
203 |
|
204 |
s->shutdown=0; |
205 |
ret=ssl23_get_client_hello(s); |
206 |
if (ret >= 0) cb=NULL; |
207 |
goto end; |
208 |
/* break; */ |
209 |
|
210 |
default: |
211 |
SSLerr(SSL_F_SSL23_ACCEPT,SSL_R_UNKNOWN_STATE); |
212 |
ret= -1; |
213 |
goto end; |
214 |
/* break; */ |
215 |
} |
216 |
|
217 |
if ((cb != NULL) && (s->state != state)) |
218 |
{ |
219 |
new_state=s->state; |
220 |
s->state=state; |
221 |
cb(s,SSL_CB_ACCEPT_LOOP,1); |
222 |
s->state=new_state; |
223 |
} |
224 |
} |
225 |
end: |
226 |
s->in_handshake--; |
227 |
if (cb != NULL) |
228 |
cb(s,SSL_CB_ACCEPT_EXIT,ret); |
229 |
return(ret); |
230 |
} |
231 |
|
232 |
|
233 |
int ssl23_get_client_hello(SSL *s) |
234 |
{ |
235 |
char buf_space[11]; /* Request this many bytes in initial read. |
236 |
* We can detect SSL 3.0/TLS 1.0 Client Hellos |
237 |
* ('type == 3') correctly only when the following |
238 |
* is in a single record, which is not guaranteed by |
239 |
* the protocol specification: |
240 |
* Byte Content |
241 |
* 0 type \ |
242 |
* 1/2 version > record header |
243 |
* 3/4 length / |
244 |
* 5 msg_type \ |
245 |
* 6-8 length > Client Hello message |
246 |
* 9/10 client_version / |
247 |
*/ |
248 |
char *buf= &(buf_space[0]); |
249 |
unsigned char *p,*d,*d_len,*dd; |
250 |
unsigned int i; |
251 |
unsigned int csl,sil,cl; |
252 |
int n=0,j; |
253 |
int type=0; |
254 |
int v[2]; |
255 |
|
256 |
if (s->state == SSL23_ST_SR_CLNT_HELLO_A) |
257 |
{ |
258 |
/* read the initial header */ |
259 |
v[0]=v[1]=0; |
260 |
|
261 |
if (!ssl3_setup_buffers(s)) goto err; |
262 |
|
263 |
n=ssl23_read_bytes(s, sizeof buf_space); |
264 |
if (n != sizeof buf_space) return(n); /* n == -1 || n == 0 */ |
265 |
|
266 |
p=s->packet; |
267 |
|
268 |
memcpy(buf,p,n); |
269 |
|
270 |
if ((p[0] & 0x80) && (p[2] == SSL2_MT_CLIENT_HELLO)) |
271 |
{ |
272 |
/* |
273 |
* SSLv2 header |
274 |
*/ |
275 |
if ((p[3] == 0x00) && (p[4] == 0x02)) |
276 |
{ |
277 |
v[0]=p[3]; v[1]=p[4]; |
278 |
/* SSLv2 */ |
279 |
if (!(s->options & SSL_OP_NO_SSLv2)) |
280 |
type=1; |
281 |
} |
282 |
else if (p[3] == SSL3_VERSION_MAJOR) |
283 |
{ |
284 |
v[0]=p[3]; v[1]=p[4]; |
285 |
/* SSLv3/TLSv1 */ |
286 |
if (p[4] >= TLS1_VERSION_MINOR) |
287 |
{ |
288 |
if (!(s->options & SSL_OP_NO_TLSv1)) |
289 |
{ |
290 |
s->version=TLS1_VERSION; |
291 |
/* type=2; */ /* done later to survive restarts */ |
292 |
s->state=SSL23_ST_SR_CLNT_HELLO_B; |
293 |
} |
294 |
else if (!(s->options & SSL_OP_NO_SSLv3)) |
295 |
{ |
296 |
s->version=SSL3_VERSION; |
297 |
/* type=2; */ |
298 |
s->state=SSL23_ST_SR_CLNT_HELLO_B; |
299 |
} |
300 |
else if (!(s->options & SSL_OP_NO_SSLv2)) |
301 |
{ |
302 |
type=1; |
303 |
} |
304 |
} |
305 |
else if (!(s->options & SSL_OP_NO_SSLv3)) |
306 |
{ |
307 |
s->version=SSL3_VERSION; |
308 |
/* type=2; */ |
309 |
s->state=SSL23_ST_SR_CLNT_HELLO_B; |
310 |
} |
311 |
else if (!(s->options & SSL_OP_NO_SSLv2)) |
312 |
type=1; |
313 |
|
314 |
} |
315 |
} |
316 |
else if ((p[0] == SSL3_RT_HANDSHAKE) && |
317 |
(p[1] == SSL3_VERSION_MAJOR) && |
318 |
(p[5] == SSL3_MT_CLIENT_HELLO) && |
319 |
((p[3] == 0 && p[4] < 5 /* silly record length? */) |
320 |
|| (p[9] >= p[1]))) |
321 |
{ |
322 |
/* |
323 |
* SSLv3 or tls1 header |
324 |
*/ |
325 |
|
326 |
v[0]=p[1]; /* major version (= SSL3_VERSION_MAJOR) */ |
327 |
/* We must look at client_version inside the Client Hello message |
328 |
* to get the correct minor version. |
329 |
* However if we have only a pathologically small fragment of the |
330 |
* Client Hello message, this would be difficult, and we'd have |
331 |
* to read more records to find out. |
332 |
* No known SSL 3.0 client fragments ClientHello like this, |
333 |
* so we simply reject such connections to avoid |
334 |
* protocol version downgrade attacks. */ |
335 |
if (p[3] == 0 && p[4] < 6) |
336 |
{ |
337 |
SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO,SSL_R_RECORD_TOO_SMALL); |
338 |
goto err; |
339 |
} |
340 |
/* if major version number > 3 set minor to a value |
341 |
* which will use the highest version 3 we support. |
342 |
* If TLS 2.0 ever appears we will need to revise |
343 |
* this.... |
344 |
*/ |
345 |
if (p[9] > SSL3_VERSION_MAJOR) |
346 |
v[1]=0xff; |
347 |
else |
348 |
v[1]=p[10]; /* minor version according to client_version */ |
349 |
if (v[1] >= TLS1_VERSION_MINOR) |
350 |
{ |
351 |
if (!(s->options & SSL_OP_NO_TLSv1)) |
352 |
{ |
353 |
s->version=TLS1_VERSION; |
354 |
type=3; |
355 |
} |
356 |
else if (!(s->options & SSL_OP_NO_SSLv3)) |
357 |
{ |
358 |
s->version=SSL3_VERSION; |
359 |
type=3; |
360 |
} |
361 |
} |
362 |
else |
363 |
{ |
364 |
/* client requests SSL 3.0 */ |
365 |
if (!(s->options & SSL_OP_NO_SSLv3)) |
366 |
{ |
367 |
s->version=SSL3_VERSION; |
368 |
type=3; |
369 |
} |
370 |
else if (!(s->options & SSL_OP_NO_TLSv1)) |
371 |
{ |
372 |
/* we won't be able to use TLS of course, |
373 |
* but this will send an appropriate alert */ |
374 |
s->version=TLS1_VERSION; |
375 |
type=3; |
376 |
} |
377 |
} |
378 |
} |
379 |
else if ((strncmp("GET ", (char *)p,4) == 0) || |
380 |
(strncmp("POST ",(char *)p,5) == 0) || |
381 |
(strncmp("HEAD ",(char *)p,5) == 0) || |
382 |
(strncmp("PUT ", (char *)p,4) == 0)) |
383 |
{ |
384 |
SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO,SSL_R_HTTP_REQUEST); |
385 |
goto err; |
386 |
} |
387 |
else if (strncmp("CONNECT",(char *)p,7) == 0) |
388 |
{ |
389 |
SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO,SSL_R_HTTPS_PROXY_REQUEST); |
390 |
goto err; |
391 |
} |
392 |
} |
393 |
|
394 |
#ifdef OPENSSL_FIPS |
395 |
if (FIPS_mode() && (s->version < TLS1_VERSION)) |
396 |
{ |
397 |
SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO, |
398 |
SSL_R_ONLY_TLS_ALLOWED_IN_FIPS_MODE); |
399 |
goto err; |
400 |
} |
401 |
#endif |
402 |
|
403 |
/* ensure that TLS_MAX_VERSION is up-to-date */ |
404 |
OPENSSL_assert(s->version <= TLS_MAX_VERSION); |
405 |
|
406 |
if (s->state == SSL23_ST_SR_CLNT_HELLO_B) |
407 |
{ |
408 |
/* we have SSLv3/TLSv1 in an SSLv2 header |
409 |
* (other cases skip this state) */ |
410 |
|
411 |
type=2; |
412 |
p=s->packet; |
413 |
v[0] = p[3]; /* == SSL3_VERSION_MAJOR */ |
414 |
v[1] = p[4]; |
415 |
|
416 |
/* An SSLv3/TLSv1 backwards-compatible CLIENT-HELLO in an SSLv2 |
417 |
* header is sent directly on the wire, not wrapped as a TLS |
418 |
* record. It's format is: |
419 |
* Byte Content |
420 |
* 0-1 msg_length |
421 |
* 2 msg_type |
422 |
* 3-4 version |
423 |
* 5-6 cipher_spec_length |
424 |
* 7-8 session_id_length |
425 |
* 9-10 challenge_length |
426 |
* ... ... |
427 |
*/ |
428 |
n=((p[0]&0x7f)<<8)|p[1]; |
429 |
if (n > (1024*4)) |
430 |
{ |
431 |
SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO,SSL_R_RECORD_TOO_LARGE); |
432 |
goto err; |
433 |
} |
434 |
if (n < 9) |
435 |
{ |
436 |
SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO,SSL_R_RECORD_LENGTH_MISMATCH); |
437 |
goto err; |
438 |
} |
439 |
|
440 |
j=ssl23_read_bytes(s,n+2); |
441 |
/* We previously read 11 bytes, so if j > 0, we must have |
442 |
* j == n+2 == s->packet_length. We have at least 11 valid |
443 |
* packet bytes. */ |
444 |
if (j <= 0) return(j); |
445 |
|
446 |
ssl3_finish_mac(s, s->packet+2, s->packet_length-2); |
447 |
if (s->msg_callback) |
448 |
s->msg_callback(0, SSL2_VERSION, 0, s->packet+2, s->packet_length-2, s, s->msg_callback_arg); /* CLIENT-HELLO */ |
449 |
|
450 |
p=s->packet; |
451 |
p+=5; |
452 |
n2s(p,csl); |
453 |
n2s(p,sil); |
454 |
n2s(p,cl); |
455 |
d=(unsigned char *)s->init_buf->data; |
456 |
if ((csl+sil+cl+11) != s->packet_length) |
457 |
{ |
458 |
SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO,SSL_R_RECORD_LENGTH_MISMATCH); |
459 |
goto err; |
460 |
} |
461 |
|
462 |
/* record header: msg_type ... */ |
463 |
*(d++) = SSL3_MT_CLIENT_HELLO; |
464 |
/* ... and length (actual value will be written later) */ |
465 |
d_len = d; |
466 |
d += 3; |
467 |
|
468 |
/* client_version */ |
469 |
*(d++) = SSL3_VERSION_MAJOR; /* == v[0] */ |
470 |
*(d++) = v[1]; |
471 |
|
472 |
/* lets populate the random area */ |
473 |
/* get the challenge_length */ |
474 |
i=(cl > SSL3_RANDOM_SIZE)?SSL3_RANDOM_SIZE:cl; |
475 |
memset(d,0,SSL3_RANDOM_SIZE); |
476 |
memcpy(&(d[SSL3_RANDOM_SIZE-i]),&(p[csl+sil]),i); |
477 |
d+=SSL3_RANDOM_SIZE; |
478 |
|
479 |
/* no session-id reuse */ |
480 |
*(d++)=0; |
481 |
|
482 |
/* ciphers */ |
483 |
j=0; |
484 |
dd=d; |
485 |
d+=2; |
486 |
for (i=0; i<csl; i+=3) |
487 |
{ |
488 |
if (p[i] != 0) continue; |
489 |
*(d++)=p[i+1]; |
490 |
*(d++)=p[i+2]; |
491 |
j+=2; |
492 |
} |
493 |
s2n(j,dd); |
494 |
|
495 |
/* COMPRESSION */ |
496 |
*(d++)=1; |
497 |
*(d++)=0; |
498 |
|
499 |
i = (d-(unsigned char *)s->init_buf->data) - 4; |
500 |
l2n3((long)i, d_len); |
501 |
|
502 |
/* get the data reused from the init_buf */ |
503 |
s->s3->tmp.reuse_message=1; |
504 |
s->s3->tmp.message_type=SSL3_MT_CLIENT_HELLO; |
505 |
s->s3->tmp.message_size=i; |
506 |
} |
507 |
|
508 |
/* imaginary new state (for program structure): */ |
509 |
/* s->state = SSL23_SR_CLNT_HELLO_C */ |
510 |
|
511 |
if (type == 1) |
512 |
{ |
513 |
#ifdef OPENSSL_NO_SSL2 |
514 |
SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO,SSL_R_UNSUPPORTED_PROTOCOL); |
515 |
goto err; |
516 |
#else |
517 |
/* we are talking sslv2 */ |
518 |
/* we need to clean up the SSLv3/TLSv1 setup and put in the |
519 |
* sslv2 stuff. */ |
520 |
|
521 |
if (s->s2 == NULL) |
522 |
{ |
523 |
if (!ssl2_new(s)) |
524 |
goto err; |
525 |
} |
526 |
else |
527 |
ssl2_clear(s); |
528 |
|
529 |
if (s->s3 != NULL) ssl3_free(s); |
530 |
|
531 |
if (!BUF_MEM_grow_clean(s->init_buf, |
532 |
SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER)) |
533 |
{ |
534 |
goto err; |
535 |
} |
536 |
|
537 |
s->state=SSL2_ST_GET_CLIENT_HELLO_A; |
538 |
if (s->options & SSL_OP_NO_TLSv1 && s->options & SSL_OP_NO_SSLv3) |
539 |
s->s2->ssl2_rollback=0; |
540 |
else |
541 |
/* reject SSL 2.0 session if client supports SSL 3.0 or TLS 1.0 |
542 |
* (SSL 3.0 draft/RFC 2246, App. E.2) */ |
543 |
s->s2->ssl2_rollback=1; |
544 |
|
545 |
/* setup the n bytes we have read so we get them from |
546 |
* the sslv2 buffer */ |
547 |
s->rstate=SSL_ST_READ_HEADER; |
548 |
s->packet_length=n; |
549 |
s->packet= &(s->s2->rbuf[0]); |
550 |
memcpy(s->packet,buf,n); |
551 |
s->s2->rbuf_left=n; |
552 |
s->s2->rbuf_offs=0; |
553 |
|
554 |
s->method=SSLv2_server_method(); |
555 |
s->handshake_func=s->method->ssl_accept; |
556 |
#endif |
557 |
} |
558 |
|
559 |
if ((type == 2) || (type == 3)) |
560 |
{ |
561 |
/* we have SSLv3/TLSv1 (type 2: SSL2 style, type 3: SSL3/TLS style) */ |
562 |
SSL_METHOD *new_method; |
563 |
new_method = ssl23_get_server_method(s->version); |
564 |
if (new_method == NULL) |
565 |
{ |
566 |
SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO,SSL_R_UNSUPPORTED_PROTOCOL); |
567 |
goto err; |
568 |
} |
569 |
s->method = new_method; |
570 |
|
571 |
if (!ssl_init_wbio_buffer(s,1)) goto err; |
572 |
|
573 |
/* we are in this state */ |
574 |
s->state=SSL3_ST_SR_CLNT_HELLO_A; |
575 |
|
576 |
if (type == 3) |
577 |
{ |
578 |
/* put the 'n' bytes we have read into the input buffer |
579 |
* for SSLv3 */ |
580 |
s->rstate=SSL_ST_READ_HEADER; |
581 |
s->packet_length=n; |
582 |
s->packet= &(s->s3->rbuf.buf[0]); |
583 |
memcpy(s->packet,buf,n); |
584 |
s->s3->rbuf.left=n; |
585 |
s->s3->rbuf.offset=0; |
586 |
} |
587 |
else |
588 |
{ |
589 |
s->packet_length=0; |
590 |
s->s3->rbuf.left=0; |
591 |
s->s3->rbuf.offset=0; |
592 |
} |
593 |
#if 0 /* ssl3_get_client_hello does this */ |
594 |
s->client_version=(v[0]<<8)|v[1]; |
595 |
#endif |
596 |
s->handshake_func=s->method->ssl_accept; |
597 |
} |
598 |
|
599 |
if ((type < 1) || (type > 3)) |
600 |
{ |
601 |
/* bad, very bad */ |
602 |
SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO,SSL_R_UNKNOWN_PROTOCOL); |
603 |
goto err; |
604 |
} |
605 |
s->init_num=0; |
606 |
|
607 |
if (buf != buf_space) OPENSSL_free(buf); |
608 |
return(SSL_accept(s)); |
609 |
err: |
610 |
if (buf != buf_space) OPENSSL_free(buf); |
611 |
return(-1); |
612 |
} |