diff options
Diffstat (limited to '')
| -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 | |||
