summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjsing <>2022-03-18 18:00:54 +0000
committerjsing <>2022-03-18 18:00:54 +0000
commit6107421d301da846b3038da564727953439669fc (patch)
tree28afd5b4887a8630bd3a752b6d12cb6a8a447b6c
parente43f72664814b516c70029cf02fd7327521d8b80 (diff)
downloadopenbsd-6107421d301da846b3038da564727953439669fc.tar.gz
openbsd-6107421d301da846b3038da564727953439669fc.tar.bz2
openbsd-6107421d301da846b3038da564727953439669fc.zip
Rewrite legacy DTLS unexpected handshake message handling.
Rewrite the code that handles unexpected handshake messages in the legacy DTLS stack. Parse the DTLS message header up front, then process it based on the message type. Overall the code should be more strict and we should reject various invalid messages that would have previously been accepted. ok inoguchi@ tb@
-rw-r--r--src/lib/libssl/d1_pkt.c222
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
486dtls1_read_handshake_unexpected(SSL *s) 486dtls1_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