diff options
Diffstat (limited to 'src/lib/libssl/s23_srvr.c')
-rw-r--r-- | src/lib/libssl/s23_srvr.c | 135 |
1 files changed, 100 insertions, 35 deletions
diff --git a/src/lib/libssl/s23_srvr.c b/src/lib/libssl/s23_srvr.c index e4122f2d78..6a3bbb10b9 100644 --- a/src/lib/libssl/s23_srvr.c +++ b/src/lib/libssl/s23_srvr.c | |||
@@ -67,8 +67,10 @@ static SSL_METHOD *ssl23_get_server_method(int ver); | |||
67 | int ssl23_get_client_hello(SSL *s); | 67 | int ssl23_get_client_hello(SSL *s); |
68 | static SSL_METHOD *ssl23_get_server_method(int ver) | 68 | static SSL_METHOD *ssl23_get_server_method(int ver) |
69 | { | 69 | { |
70 | #ifndef NO_SSL2 | ||
70 | if (ver == SSL2_VERSION) | 71 | if (ver == SSL2_VERSION) |
71 | return(SSLv2_server_method()); | 72 | return(SSLv2_server_method()); |
73 | #endif | ||
72 | if (ver == SSL3_VERSION) | 74 | if (ver == SSL3_VERSION) |
73 | return(SSLv3_server_method()); | 75 | return(SSLv3_server_method()); |
74 | else if (ver == TLS1_VERSION) | 76 | else if (ver == TLS1_VERSION) |
@@ -101,7 +103,7 @@ int ssl23_accept(SSL *s) | |||
101 | int ret= -1; | 103 | int ret= -1; |
102 | int new_state,state; | 104 | int new_state,state; |
103 | 105 | ||
104 | RAND_seed(&Time,sizeof(Time)); | 106 | RAND_add(&Time,sizeof(Time),0); |
105 | ERR_clear_error(); | 107 | ERR_clear_error(); |
106 | clear_sys_error(); | 108 | clear_sys_error(); |
107 | 109 | ||
@@ -186,23 +188,39 @@ end: | |||
186 | 188 | ||
187 | int ssl23_get_client_hello(SSL *s) | 189 | int ssl23_get_client_hello(SSL *s) |
188 | { | 190 | { |
189 | char buf_space[8]; | 191 | char buf_space[11]; /* Request this many bytes in initial read. |
192 | * We can detect SSL 3.0/TLS 1.0 Client Hellos | ||
193 | * ('type == 3') correctly only when the following | ||
194 | * is in a single record, which is not guaranteed by | ||
195 | * the protocol specification: | ||
196 | * Byte Content | ||
197 | * 0 type \ | ||
198 | * 1/2 version > record header | ||
199 | * 3/4 length / | ||
200 | * 5 msg_type \ | ||
201 | * 6-8 length > Client Hello message | ||
202 | * 9/10 client_version / | ||
203 | */ | ||
190 | char *buf= &(buf_space[0]); | 204 | char *buf= &(buf_space[0]); |
191 | unsigned char *p,*d,*dd; | 205 | unsigned char *p,*d,*dd; |
192 | unsigned int i; | 206 | unsigned int i; |
193 | unsigned int csl,sil,cl; | 207 | unsigned int csl,sil,cl; |
194 | int n=0,j,tls1=0; | 208 | int n=0,j; |
195 | int type=0,use_sslv2_strong=0; | 209 | int type=0; |
196 | int v[2]; | 210 | int v[2]; |
211 | #ifndef NO_RSA | ||
212 | int use_sslv2_strong=0; | ||
213 | #endif | ||
197 | 214 | ||
198 | /* read the initial header */ | ||
199 | v[0]=v[1]=0; | ||
200 | if (s->state == SSL23_ST_SR_CLNT_HELLO_A) | 215 | if (s->state == SSL23_ST_SR_CLNT_HELLO_A) |
201 | { | 216 | { |
217 | /* read the initial header */ | ||
218 | v[0]=v[1]=0; | ||
219 | |||
202 | if (!ssl3_setup_buffers(s)) goto err; | 220 | if (!ssl3_setup_buffers(s)) goto err; |
203 | 221 | ||
204 | n=ssl23_read_bytes(s,7); | 222 | n=ssl23_read_bytes(s, sizeof buf_space); |
205 | if (n != 7) return(n); /* n == -1 || n == 0 */ | 223 | if (n != sizeof buf_space) return(n); /* n == -1 || n == 0 */ |
206 | 224 | ||
207 | p=s->packet; | 225 | p=s->packet; |
208 | 226 | ||
@@ -210,7 +228,9 @@ int ssl23_get_client_hello(SSL *s) | |||
210 | 228 | ||
211 | if ((p[0] & 0x80) && (p[2] == SSL2_MT_CLIENT_HELLO)) | 229 | if ((p[0] & 0x80) && (p[2] == SSL2_MT_CLIENT_HELLO)) |
212 | { | 230 | { |
213 | /* SSLv2 header */ | 231 | /* |
232 | * SSLv2 header | ||
233 | */ | ||
214 | if ((p[3] == 0x00) && (p[4] == 0x02)) | 234 | if ((p[3] == 0x00) && (p[4] == 0x02)) |
215 | { | 235 | { |
216 | v[0]=p[3]; v[1]=p[4]; | 236 | v[0]=p[3]; v[1]=p[4]; |
@@ -226,11 +246,14 @@ int ssl23_get_client_hello(SSL *s) | |||
226 | { | 246 | { |
227 | if (!(s->options & SSL_OP_NO_TLSv1)) | 247 | if (!(s->options & SSL_OP_NO_TLSv1)) |
228 | { | 248 | { |
229 | tls1=1; | 249 | s->version=TLS1_VERSION; |
250 | /* type=2; */ /* done later to survive restarts */ | ||
230 | s->state=SSL23_ST_SR_CLNT_HELLO_B; | 251 | s->state=SSL23_ST_SR_CLNT_HELLO_B; |
231 | } | 252 | } |
232 | else if (!(s->options & SSL_OP_NO_SSLv3)) | 253 | else if (!(s->options & SSL_OP_NO_SSLv3)) |
233 | { | 254 | { |
255 | s->version=SSL3_VERSION; | ||
256 | /* type=2; */ | ||
234 | s->state=SSL23_ST_SR_CLNT_HELLO_B; | 257 | s->state=SSL23_ST_SR_CLNT_HELLO_B; |
235 | } | 258 | } |
236 | else if (!(s->options & SSL_OP_NO_SSLv2)) | 259 | else if (!(s->options & SSL_OP_NO_SSLv2)) |
@@ -239,12 +262,26 @@ int ssl23_get_client_hello(SSL *s) | |||
239 | } | 262 | } |
240 | } | 263 | } |
241 | else if (!(s->options & SSL_OP_NO_SSLv3)) | 264 | else if (!(s->options & SSL_OP_NO_SSLv3)) |
265 | { | ||
266 | s->version=SSL3_VERSION; | ||
267 | /* type=2; */ | ||
242 | s->state=SSL23_ST_SR_CLNT_HELLO_B; | 268 | s->state=SSL23_ST_SR_CLNT_HELLO_B; |
269 | } | ||
243 | else if (!(s->options & SSL_OP_NO_SSLv2)) | 270 | else if (!(s->options & SSL_OP_NO_SSLv2)) |
244 | type=1; | 271 | type=1; |
245 | 272 | ||
246 | if (s->options & SSL_OP_NON_EXPORT_FIRST) | 273 | if (s->options & SSL_OP_NON_EXPORT_FIRST) |
274 | /* Not only utterly confusing, but broken | ||
275 | * ('fractured programming'?) -- the details | ||
276 | * of this block nearly make it work | ||
277 | * as intended in this environment, but on one | ||
278 | * of the fine points (w.r.t. restarts) it fails. | ||
279 | * The obvious fix would be even more devastating | ||
280 | * to program structure; if you want the functionality, | ||
281 | * throw this away and implement it in a way | ||
282 | * that makes sense */ | ||
247 | { | 283 | { |
284 | #if 0 | ||
248 | STACK_OF(SSL_CIPHER) *sk; | 285 | STACK_OF(SSL_CIPHER) *sk; |
249 | SSL_CIPHER *c; | 286 | SSL_CIPHER *c; |
250 | int ne2,ne3; | 287 | int ne2,ne3; |
@@ -294,27 +331,51 @@ int ssl23_get_client_hello(SSL *s) | |||
294 | goto next_bit; | 331 | goto next_bit; |
295 | } | 332 | } |
296 | } | 333 | } |
334 | #else | ||
335 | SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO,SSL_R_UNSUPPORTED_OPTION); | ||
336 | goto err; | ||
337 | #endif | ||
297 | } | 338 | } |
298 | } | 339 | } |
299 | } | 340 | } |
300 | else if ((p[0] == SSL3_RT_HANDSHAKE) && | 341 | else if ((p[0] == SSL3_RT_HANDSHAKE) && |
301 | (p[1] == SSL3_VERSION_MAJOR) && | 342 | (p[1] == SSL3_VERSION_MAJOR) && |
302 | (p[5] == SSL3_MT_CLIENT_HELLO)) | 343 | (p[5] == SSL3_MT_CLIENT_HELLO) && |
344 | ((p[3] == 0 && p[4] < 5 /* silly record length? */) | ||
345 | || (p[9] == p[1]))) | ||
303 | { | 346 | { |
304 | v[0]=p[1]; v[1]=p[2]; | 347 | /* |
305 | /* true SSLv3 or tls1 */ | 348 | * SSLv3 or tls1 header |
306 | if (p[2] >= TLS1_VERSION_MINOR) | 349 | */ |
350 | |||
351 | v[0]=p[1]; /* major version */ | ||
352 | /* We must look at client_version inside the Client Hello message | ||
353 | * to get the correct minor version: */ | ||
354 | v[1]=p[10]; | ||
355 | /* However if we have only a pathologically small fragment of the | ||
356 | * Client Hello message, we simply use the version from the | ||
357 | * record header -- this is incorrect but unlikely to fail in | ||
358 | * practice */ | ||
359 | if (p[3] == 0 && p[4] < 6) | ||
360 | v[1]=p[2]; | ||
361 | if (v[1] >= TLS1_VERSION_MINOR) | ||
307 | { | 362 | { |
308 | if (!(s->options & SSL_OP_NO_TLSv1)) | 363 | if (!(s->options & SSL_OP_NO_TLSv1)) |
309 | { | 364 | { |
365 | s->version=TLS1_VERSION; | ||
310 | type=3; | 366 | type=3; |
311 | tls1=1; | ||
312 | } | 367 | } |
313 | else if (!(s->options & SSL_OP_NO_SSLv3)) | 368 | else if (!(s->options & SSL_OP_NO_SSLv3)) |
369 | { | ||
370 | s->version=SSL3_VERSION; | ||
314 | type=3; | 371 | type=3; |
372 | } | ||
315 | } | 373 | } |
316 | else if (!(s->options & SSL_OP_NO_SSLv3)) | 374 | else if (!(s->options & SSL_OP_NO_SSLv3)) |
375 | { | ||
376 | s->version=SSL3_VERSION; | ||
317 | type=3; | 377 | type=3; |
378 | } | ||
318 | } | 379 | } |
319 | else if ((strncmp("GET ", (char *)p,4) == 0) || | 380 | else if ((strncmp("GET ", (char *)p,4) == 0) || |
320 | (strncmp("POST ",(char *)p,5) == 0) || | 381 | (strncmp("POST ",(char *)p,5) == 0) || |
@@ -331,12 +392,16 @@ int ssl23_get_client_hello(SSL *s) | |||
331 | } | 392 | } |
332 | } | 393 | } |
333 | 394 | ||
334 | next_bit: | ||
335 | if (s->state == SSL23_ST_SR_CLNT_HELLO_B) | 395 | if (s->state == SSL23_ST_SR_CLNT_HELLO_B) |
336 | { | 396 | { |
337 | /* we have a SSLv3/TLSv1 in a SSLv2 header */ | 397 | /* we have SSLv3/TLSv1 in an SSLv2 header |
398 | * (other cases skip this state) */ | ||
399 | |||
338 | type=2; | 400 | type=2; |
339 | p=s->packet; | 401 | p=s->packet; |
402 | v[0] = p[3]; /* == SSL3_VERSION_MAJOR */ | ||
403 | v[1] = p[4]; | ||
404 | |||
340 | n=((p[0]&0x7f)<<8)|p[1]; | 405 | n=((p[0]&0x7f)<<8)|p[1]; |
341 | if (n > (1024*4)) | 406 | if (n > (1024*4)) |
342 | { | 407 | { |
@@ -361,14 +426,11 @@ next_bit: | |||
361 | goto err; | 426 | goto err; |
362 | } | 427 | } |
363 | 428 | ||
364 | *(d++)=SSL3_VERSION_MAJOR; | 429 | *(d++) = SSL3_VERSION_MAJOR; /* == v[0] */ |
365 | if (tls1) | 430 | *(d++) = v[1]; |
366 | *(d++)=TLS1_VERSION_MINOR; | ||
367 | else | ||
368 | *(d++)=SSL3_VERSION_MINOR; | ||
369 | 431 | ||
370 | /* lets populate the random area */ | 432 | /* lets populate the random area */ |
371 | /* get the chalenge_length */ | 433 | /* get the challenge_length */ |
372 | i=(cl > SSL3_RANDOM_SIZE)?SSL3_RANDOM_SIZE:cl; | 434 | i=(cl > SSL3_RANDOM_SIZE)?SSL3_RANDOM_SIZE:cl; |
373 | memset(d,0,SSL3_RANDOM_SIZE); | 435 | memset(d,0,SSL3_RANDOM_SIZE); |
374 | memcpy(&(d[SSL3_RANDOM_SIZE-i]),&(p[csl+sil]),i); | 436 | memcpy(&(d[SSL3_RANDOM_SIZE-i]),&(p[csl+sil]),i); |
@@ -402,8 +464,15 @@ next_bit: | |||
402 | s->s3->tmp.message_size=i; | 464 | s->s3->tmp.message_size=i; |
403 | } | 465 | } |
404 | 466 | ||
467 | /* imaginary new state (for program structure): */ | ||
468 | /* s->state = SSL23_SR_CLNT_HELLO_C */ | ||
469 | |||
405 | if (type == 1) | 470 | if (type == 1) |
406 | { | 471 | { |
472 | #ifdef NO_SSL2 | ||
473 | SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO,SSL_R_UNSUPPORTED_PROTOCOL); | ||
474 | goto err; | ||
475 | #else | ||
407 | /* we are talking sslv2 */ | 476 | /* we are talking sslv2 */ |
408 | /* we need to clean up the SSLv3/TLSv1 setup and put in the | 477 | /* we need to clean up the SSLv3/TLSv1 setup and put in the |
409 | * sslv2 stuff. */ | 478 | * sslv2 stuff. */ |
@@ -431,7 +500,7 @@ next_bit: | |||
431 | else | 500 | else |
432 | s->s2->ssl2_rollback=1; | 501 | s->s2->ssl2_rollback=1; |
433 | 502 | ||
434 | /* setup the 5 bytes we have read so we get them from | 503 | /* setup the n bytes we have read so we get them from |
435 | * the sslv2 buffer */ | 504 | * the sslv2 buffer */ |
436 | s->rstate=SSL_ST_READ_HEADER; | 505 | s->rstate=SSL_ST_READ_HEADER; |
437 | s->packet_length=n; | 506 | s->packet_length=n; |
@@ -442,11 +511,12 @@ next_bit: | |||
442 | 511 | ||
443 | s->method=SSLv2_server_method(); | 512 | s->method=SSLv2_server_method(); |
444 | s->handshake_func=s->method->ssl_accept; | 513 | s->handshake_func=s->method->ssl_accept; |
514 | #endif | ||
445 | } | 515 | } |
446 | 516 | ||
447 | if ((type == 2) || (type == 3)) | 517 | if ((type == 2) || (type == 3)) |
448 | { | 518 | { |
449 | /* we have SSLv3/TLSv1 */ | 519 | /* we have SSLv3/TLSv1 (type 2: SSL2 style, type 3: SSL3/TLS style) */ |
450 | 520 | ||
451 | if (!ssl_init_wbio_buffer(s,1)) goto err; | 521 | if (!ssl_init_wbio_buffer(s,1)) goto err; |
452 | 522 | ||
@@ -471,17 +541,13 @@ next_bit: | |||
471 | s->s3->rbuf.offset=0; | 541 | s->s3->rbuf.offset=0; |
472 | } | 542 | } |
473 | 543 | ||
474 | if (tls1) | 544 | if (s->version == TLS1_VERSION) |
475 | { | 545 | s->method = TLSv1_server_method(); |
476 | s->version=TLS1_VERSION; | ||
477 | s->method=TLSv1_server_method(); | ||
478 | } | ||
479 | else | 546 | else |
480 | { | 547 | s->method = SSLv3_server_method(); |
481 | s->version=SSL3_VERSION; | 548 | #if 0 /* ssl3_get_client_hello does this */ |
482 | s->method=SSLv3_server_method(); | ||
483 | } | ||
484 | s->client_version=(v[0]<<8)|v[1]; | 549 | s->client_version=(v[0]<<8)|v[1]; |
550 | #endif | ||
485 | s->handshake_func=s->method->ssl_accept; | 551 | s->handshake_func=s->method->ssl_accept; |
486 | } | 552 | } |
487 | 553 | ||
@@ -500,4 +566,3 @@ err: | |||
500 | if (buf != buf_space) Free(buf); | 566 | if (buf != buf_space) Free(buf); |
501 | return(-1); | 567 | return(-1); |
502 | } | 568 | } |
503 | |||