diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/lib/libssl/d1_pkt.c | 222 |
1 files changed, 139 insertions, 83 deletions
diff --git a/src/lib/libssl/d1_pkt.c b/src/lib/libssl/d1_pkt.c index f6f07052a1..9072315e72 100644 --- a/src/lib/libssl/d1_pkt.c +++ b/src/lib/libssl/d1_pkt.c | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* $OpenBSD: d1_pkt.c,v 1.120 2022/03/14 16:49:35 jsing Exp $ */ | 1 | /* $OpenBSD: d1_pkt.c,v 1.121 2022/03/18 18:00:54 jsing Exp $ */ |
| 2 | /* | 2 | /* |
| 3 | * DTLS implementation written by Nagendra Modadugu | 3 | * DTLS implementation written by Nagendra Modadugu |
| 4 | * (nagendra@cs.stanford.edu) for the OpenSSL project 2005. | 4 | * (nagendra@cs.stanford.edu) for the OpenSSL project 2005. |
| @@ -486,116 +486,172 @@ static int | |||
| 486 | dtls1_read_handshake_unexpected(SSL *s) | 486 | dtls1_read_handshake_unexpected(SSL *s) |
| 487 | { | 487 | { |
| 488 | SSL3_RECORD_INTERNAL *rr = &s->s3->rrec; | 488 | SSL3_RECORD_INTERNAL *rr = &s->s3->rrec; |
| 489 | int i; | 489 | struct hm_header_st hs_msg_hdr; |
| 490 | CBS cbs; | ||
| 491 | int ret; | ||
| 490 | 492 | ||
| 491 | if (s->internal->in_handshake) { | 493 | if (s->internal->in_handshake) { |
| 492 | SSLerror(s, ERR_R_INTERNAL_ERROR); | 494 | SSLerror(s, ERR_R_INTERNAL_ERROR); |
| 493 | return -1; | 495 | return -1; |
| 494 | } | 496 | } |
| 495 | 497 | ||
| 496 | /* If we are a client, check for an incoming 'Hello Request': */ | 498 | if (rr->off != 0) { |
| 497 | if (!s->server && rr->type == SSL3_RT_HANDSHAKE && | 499 | SSLerror(s, ERR_R_INTERNAL_ERROR); |
| 498 | rr->length >= DTLS1_HM_HEADER_LENGTH && rr->off == 0 && | 500 | return -1; |
| 499 | rr->data[0] == SSL3_MT_HELLO_REQUEST && | 501 | } |
| 500 | s->session != NULL && s->session->cipher != NULL) { | 502 | |
| 501 | struct hm_header_st msg_hdr; | 503 | /* Parse handshake message header. */ |
| 502 | CBS cbs; | 504 | CBS_init(&cbs, rr->data, rr->length); |
| 503 | 505 | if (!dtls1_get_message_header(&cbs, &hs_msg_hdr)) | |
| 504 | CBS_init(&cbs, rr->data, rr->length); | 506 | return -1; /* XXX - probably should drop/continue. */ |
| 505 | if (!dtls1_get_message_header(&cbs, &msg_hdr)) | 507 | |
| 506 | return -1; /* XXX - probably should drop/continue. */ | 508 | /* This may just be a stale retransmit. */ |
| 507 | if (msg_hdr.msg_len != 0) { | 509 | if (rr->epoch != tls12_record_layer_read_epoch(s->internal->rl)) { |
| 510 | rr->length = 0; | ||
| 511 | return 1; | ||
| 512 | } | ||
| 513 | |||
| 514 | if (hs_msg_hdr.type == SSL3_MT_HELLO_REQUEST) { | ||
| 515 | /* | ||
| 516 | * Incoming HelloRequest messages should only be received by a | ||
| 517 | * client. A server may send these at any time - a client should | ||
| 518 | * ignore the message if received in the middle of a handshake. | ||
| 519 | * See RFC 5246 sections 7.4 and 7.4.1.1. | ||
| 520 | */ | ||
| 521 | if (s->server) { | ||
| 522 | SSLerror(s, SSL_R_UNEXPECTED_MESSAGE); | ||
| 523 | ssl3_send_alert(s, SSL3_AL_FATAL, | ||
| 524 | SSL_AD_UNEXPECTED_MESSAGE); | ||
| 525 | return -1; | ||
| 526 | } | ||
| 527 | |||
| 528 | /* XXX - should also check frag offset/length. */ | ||
| 529 | if (hs_msg_hdr.msg_len != 0) { | ||
| 508 | SSLerror(s, SSL_R_BAD_HELLO_REQUEST); | 530 | SSLerror(s, SSL_R_BAD_HELLO_REQUEST); |
| 509 | ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); | 531 | ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); |
| 510 | return -1; | 532 | return -1; |
| 511 | } | 533 | } |
| 512 | rr->length = 0; | ||
| 513 | 534 | ||
| 514 | /* no need to check sequence number on HELLO REQUEST messages */ | 535 | ssl_msg_callback(s, 0, SSL3_RT_HANDSHAKE, rr->data, |
| 515 | 536 | DTLS1_HM_HEADER_LENGTH); | |
| 516 | ssl_msg_callback(s, 0, SSL3_RT_HANDSHAKE, rr->data, 4); | 537 | |
| 517 | |||
| 518 | if (SSL_is_init_finished(s) && | ||
| 519 | !(s->s3->flags & SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS) && | ||
| 520 | !s->s3->renegotiate) { | ||
| 521 | s->d1->handshake_read_seq++; | ||
| 522 | s->internal->new_session = 1; | ||
| 523 | ssl3_renegotiate(s); | ||
| 524 | if (ssl3_renegotiate_check(s)) { | ||
| 525 | i = s->internal->handshake_func(s); | ||
| 526 | if (i < 0) | ||
| 527 | return (i); | ||
| 528 | if (i == 0) { | ||
| 529 | SSLerror(s, SSL_R_SSL_HANDSHAKE_FAILURE); | ||
| 530 | return (-1); | ||
| 531 | } | ||
| 532 | |||
| 533 | if (!(s->internal->mode & SSL_MODE_AUTO_RETRY)) { | ||
| 534 | if (s->s3->rbuf.left == 0) { | ||
| 535 | ssl_force_want_read(s); | ||
| 536 | return (-1); | ||
| 537 | } | ||
| 538 | } | ||
| 539 | } | ||
| 540 | } | ||
| 541 | /* we either finished a handshake or ignored the request, | ||
| 542 | * now try again to obtain the (application) data we were asked for */ | ||
| 543 | rr->length = 0; | 538 | rr->length = 0; |
| 544 | return 1; | ||
| 545 | } | ||
| 546 | 539 | ||
| 547 | /* Unexpected handshake message (Client Hello, or protocol violation) */ | 540 | /* |
| 548 | if (rr->type == SSL3_RT_HANDSHAKE && | 541 | * It should be impossible to hit this, but keep the safety |
| 549 | rr->length >= DTLS1_HM_HEADER_LENGTH && rr->off == 0 && | 542 | * harness for now... |
| 550 | !s->internal->in_handshake) { | 543 | */ |
| 551 | struct hm_header_st msg_hdr; | 544 | if (s->session == NULL || s->session->cipher == NULL) |
| 552 | CBS cbs; | ||
| 553 | |||
| 554 | /* this may just be a stale retransmit */ | ||
| 555 | CBS_init(&cbs, rr->data, rr->length); | ||
| 556 | if (!dtls1_get_message_header(&cbs, &msg_hdr)) | ||
| 557 | return -1; /* XXX - this should probably drop/continue. */ | ||
| 558 | if (rr->epoch != tls12_record_layer_read_epoch(s->internal->rl)) { | ||
| 559 | rr->length = 0; | ||
| 560 | return 1; | 545 | return 1; |
| 561 | } | ||
| 562 | 546 | ||
| 563 | /* If we are server, we may have a repeated FINISHED of the | 547 | /* |
| 564 | * client here, then retransmit our CCS and FINISHED. | 548 | * Ignore this message if we're currently handshaking, |
| 549 | * renegotiation is already pending or renegotiation is disabled | ||
| 550 | * via flags. | ||
| 565 | */ | 551 | */ |
| 566 | if (msg_hdr.type == SSL3_MT_FINISHED) { | 552 | if (!SSL_is_init_finished(s) || s->s3->renegotiate || |
| 567 | if (dtls1_check_timeout_num(s) < 0) | 553 | (s->s3->flags & SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS) != 0) |
| 568 | return -1; | 554 | return 1; |
| 569 | 555 | ||
| 570 | dtls1_retransmit_buffered_messages(s); | 556 | s->d1->handshake_read_seq++; |
| 571 | rr->length = 0; | 557 | |
| 558 | /* XXX - why is this set here but not in ssl3? */ | ||
| 559 | s->internal->new_session = 1; | ||
| 560 | |||
| 561 | if (!ssl3_renegotiate(s)) | ||
| 562 | return 1; | ||
| 563 | if (!ssl3_renegotiate_check(s)) | ||
| 572 | return 1; | 564 | return 1; |
| 565 | |||
| 566 | } else if (hs_msg_hdr.type == SSL3_MT_CLIENT_HELLO) { | ||
| 567 | /* | ||
| 568 | * Incoming ClientHello messages should only be received by a | ||
| 569 | * server. A client may send these in response to server | ||
| 570 | * initiated renegotiation (HelloRequest) or in order to | ||
| 571 | * initiate renegotiation by the client. See RFC 5246 section | ||
| 572 | * 7.4.1.2. | ||
| 573 | */ | ||
| 574 | if (!s->server) { | ||
| 575 | SSLerror(s, SSL_R_UNEXPECTED_MESSAGE); | ||
| 576 | ssl3_send_alert(s, SSL3_AL_FATAL, | ||
| 577 | SSL_AD_UNEXPECTED_MESSAGE); | ||
| 578 | return -1; | ||
| 579 | } | ||
| 580 | |||
| 581 | /* | ||
| 582 | * A client should not be sending a ClientHello unless we're not | ||
| 583 | * currently handshaking. | ||
| 584 | */ | ||
| 585 | if (!SSL_is_init_finished(s)) { | ||
| 586 | SSLerror(s, SSL_R_UNEXPECTED_MESSAGE); | ||
| 587 | ssl3_send_alert(s, SSL3_AL_FATAL, | ||
| 588 | SSL_AD_UNEXPECTED_MESSAGE); | ||
| 589 | return -1; | ||
| 573 | } | 590 | } |
| 574 | 591 | ||
| 575 | if (((s->s3->hs.state&SSL_ST_MASK) == SSL_ST_OK) && | 592 | if ((s->internal->options & SSL_OP_NO_CLIENT_RENEGOTIATION) != 0) { |
| 576 | !(s->s3->flags & SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS)) { | 593 | ssl3_send_alert(s, SSL3_AL_FATAL, |
| 577 | s->s3->hs.state = s->server ? SSL_ST_ACCEPT : SSL_ST_CONNECT; | 594 | SSL_AD_NO_RENEGOTIATION); |
| 578 | s->internal->renegotiate = 1; | 595 | return -1; |
| 579 | s->internal->new_session = 1; | ||
| 580 | } | 596 | } |
| 581 | i = s->internal->handshake_func(s); | 597 | |
| 582 | if (i < 0) | 598 | if (s->session == NULL || s->session->cipher == NULL) { |
| 583 | return (i); | 599 | SSLerror(s, ERR_R_INTERNAL_ERROR); |
| 584 | if (i == 0) { | 600 | return -1; |
| 585 | SSLerror(s, SSL_R_SSL_HANDSHAKE_FAILURE); | ||
| 586 | return (-1); | ||
| 587 | } | 601 | } |
| 588 | 602 | ||
| 589 | if (!(s->internal->mode & SSL_MODE_AUTO_RETRY)) { | 603 | /* Client requested renegotiation but it is not permitted. */ |
| 590 | if (s->s3->rbuf.left == 0) { | 604 | if (!s->s3->send_connection_binding || |
| 591 | ssl_force_want_read(s); | 605 | (s->s3->flags & SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS) != 0) { |
| 592 | return (-1); | 606 | ssl3_send_alert(s, SSL3_AL_WARNING, |
| 593 | } | 607 | SSL_AD_NO_RENEGOTIATION); |
| 608 | return 1; | ||
| 594 | } | 609 | } |
| 610 | |||
| 611 | s->s3->hs.state = SSL_ST_ACCEPT; | ||
| 612 | s->internal->renegotiate = 1; | ||
| 613 | s->internal->new_session = 1; | ||
| 614 | |||
| 615 | } else if (hs_msg_hdr.type == SSL3_MT_FINISHED && s->server) { | ||
| 616 | /* | ||
| 617 | * If we are server, we may have a repeated FINISHED of the | ||
| 618 | * client here, then retransmit our CCS and FINISHED. | ||
| 619 | */ | ||
| 620 | if (dtls1_check_timeout_num(s) < 0) | ||
| 621 | return -1; | ||
| 622 | |||
| 623 | /* XXX - should this be calling ssl_msg_callback()? */ | ||
| 624 | |||
| 625 | dtls1_retransmit_buffered_messages(s); | ||
| 626 | |||
| 595 | rr->length = 0; | 627 | rr->length = 0; |
| 628 | |||
| 596 | return 1; | 629 | return 1; |
| 630 | |||
| 631 | } else { | ||
| 632 | SSLerror(s, SSL_R_UNEXPECTED_MESSAGE); | ||
| 633 | ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE); | ||
| 634 | return -1; | ||
| 597 | } | 635 | } |
| 598 | 636 | ||
| 637 | if ((ret = s->internal->handshake_func(s)) < 0) | ||
| 638 | return ret; | ||
| 639 | if (ret == 0) { | ||
| 640 | SSLerror(s, SSL_R_SSL_HANDSHAKE_FAILURE); | ||
| 641 | return -1; | ||
| 642 | } | ||
| 643 | |||
| 644 | if (!(s->internal->mode & SSL_MODE_AUTO_RETRY)) { | ||
| 645 | if (s->s3->rbuf.left == 0) { | ||
| 646 | ssl_force_want_read(s); | ||
| 647 | return -1; | ||
| 648 | } | ||
| 649 | } | ||
| 650 | |||
| 651 | /* | ||
| 652 | * We either finished a handshake or ignored the request, now try again | ||
| 653 | * to obtain the (application) data we were asked for. | ||
| 654 | */ | ||
| 599 | return 1; | 655 | return 1; |
| 600 | } | 656 | } |
| 601 | 657 | ||
