diff options
Diffstat (limited to 'src/lib')
-rw-r--r-- | src/lib/libssl/d1_pkt.c | 162 | ||||
-rw-r--r-- | src/lib/libssl/dtls_locl.h | 9 |
2 files changed, 48 insertions, 123 deletions
diff --git a/src/lib/libssl/d1_pkt.c b/src/lib/libssl/d1_pkt.c index 0b66bf7cc8..22f0167c75 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.108 2021/08/31 13:14:43 jsing Exp $ */ | 1 | /* $OpenBSD: d1_pkt.c,v 1.109 2021/08/31 13:34:55 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. |
@@ -178,8 +178,6 @@ satsub64be(const unsigned char *v1, const unsigned char *v2) | |||
178 | return brw + (ret & 0xFF); | 178 | return brw + (ret & 0xFF); |
179 | } | 179 | } |
180 | 180 | ||
181 | static int have_handshake_fragment(SSL *s, int type, unsigned char *buf, | ||
182 | int len, int peek); | ||
183 | static int dtls1_record_replay_check(SSL *s, DTLS1_BITMAP *bitmap, | 181 | static int dtls1_record_replay_check(SSL *s, DTLS1_BITMAP *bitmap, |
184 | const unsigned char *seq); | 182 | const unsigned char *seq); |
185 | static void dtls1_record_bitmap_update(SSL *s, DTLS1_BITMAP *bitmap, | 183 | static void dtls1_record_bitmap_update(SSL *s, DTLS1_BITMAP *bitmap, |
@@ -530,15 +528,7 @@ dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek) | |||
530 | return -1; | 528 | return -1; |
531 | } | 529 | } |
532 | 530 | ||
533 | /* check whether there's a handshake message (client hello?) waiting */ | 531 | if (!s->internal->in_handshake && SSL_in_init(s)) { |
534 | if ((ret = have_handshake_fragment(s, type, buf, len, peek))) | ||
535 | return ret; | ||
536 | |||
537 | /* Now D1I(s)->handshake_fragment_len == 0 if type == SSL3_RT_HANDSHAKE. */ | ||
538 | |||
539 | if (!s->internal->in_handshake && SSL_in_init(s)) | ||
540 | { | ||
541 | /* type == SSL3_RT_APPLICATION_DATA */ | ||
542 | i = s->internal->handshake_func(s); | 532 | i = s->internal->handshake_func(s); |
543 | if (i < 0) | 533 | if (i < 0) |
544 | return (i); | 534 | return (i); |
@@ -645,89 +635,62 @@ dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek) | |||
645 | return (n); | 635 | return (n); |
646 | } | 636 | } |
647 | 637 | ||
648 | 638 | /* | |
649 | /* If we get here, then type != rr->type; if we have a handshake | 639 | * If we get here, then type != rr->type; if we have a handshake |
650 | * message, then it was unexpected (Hello Request or Client Hello). */ | 640 | * message, then it was unexpected (Hello Request or Client Hello). |
651 | |||
652 | /* In case of record types for which we have 'fragment' storage, | ||
653 | * fill that so that we can process the data at a fixed place. | ||
654 | */ | 641 | */ |
642 | |||
655 | { | 643 | { |
656 | unsigned int k, dest_maxlen = 0; | 644 | unsigned int record_min_len = 0; |
657 | unsigned char *dest = NULL; | ||
658 | unsigned int *dest_len = NULL; | ||
659 | 645 | ||
660 | if (rr->type == SSL3_RT_HANDSHAKE) { | 646 | if (rr->type == SSL3_RT_HANDSHAKE) { |
661 | dest_maxlen = sizeof D1I(s)->handshake_fragment; | 647 | record_min_len = DTLS1_HM_HEADER_LENGTH; |
662 | dest = D1I(s)->handshake_fragment; | ||
663 | dest_len = &D1I(s)->handshake_fragment_len; | ||
664 | } else if (rr->type == SSL3_RT_ALERT) { | 648 | } else if (rr->type == SSL3_RT_ALERT) { |
665 | dest_maxlen = sizeof(D1I(s)->alert_fragment); | 649 | record_min_len = DTLS1_AL_HEADER_LENGTH; |
666 | dest = D1I(s)->alert_fragment; | 650 | } else if (rr->type == SSL3_RT_CHANGE_CIPHER_SPEC) { |
667 | dest_len = &D1I(s)->alert_fragment_len; | 651 | record_min_len = DTLS1_CCS_HEADER_LENGTH; |
668 | } | 652 | } else if (rr->type == SSL3_RT_APPLICATION_DATA) { |
669 | /* else it's a CCS message, or application data or wrong */ | 653 | /* |
670 | else if (rr->type != SSL3_RT_CHANGE_CIPHER_SPEC) { | 654 | * Application data while renegotiating is allowed. |
671 | /* Application data while renegotiating | 655 | * Try reading again. |
672 | * is allowed. Try again reading. | ||
673 | */ | 656 | */ |
674 | if (rr->type == SSL3_RT_APPLICATION_DATA) { | 657 | BIO *bio; |
675 | BIO *bio; | ||
676 | S3I(s)->in_read_app_data = 2; | ||
677 | bio = SSL_get_rbio(s); | ||
678 | s->internal->rwstate = SSL_READING; | ||
679 | BIO_clear_retry_flags(bio); | ||
680 | BIO_set_retry_read(bio); | ||
681 | return (-1); | ||
682 | } | ||
683 | 658 | ||
659 | S3I(s)->in_read_app_data = 2; | ||
660 | bio = SSL_get_rbio(s); | ||
661 | s->internal->rwstate = SSL_READING; | ||
662 | BIO_clear_retry_flags(bio); | ||
663 | BIO_set_retry_read(bio); | ||
664 | return (-1); | ||
665 | } else { | ||
684 | /* Not certain if this is the right error handling */ | 666 | /* Not certain if this is the right error handling */ |
685 | al = SSL_AD_UNEXPECTED_MESSAGE; | 667 | al = SSL_AD_UNEXPECTED_MESSAGE; |
686 | SSLerror(s, SSL_R_UNEXPECTED_RECORD); | 668 | SSLerror(s, SSL_R_UNEXPECTED_RECORD); |
687 | goto fatal_err; | 669 | goto fatal_err; |
688 | } | 670 | } |
689 | 671 | ||
690 | if (dest_maxlen > 0) { | 672 | if (record_min_len > 0 && rr->length < record_min_len) { |
691 | /* XDTLS: In a pathalogical case, the Client Hello | 673 | s->internal->rstate = SSL_ST_READ_HEADER; |
692 | * may be fragmented--don't always expect dest_maxlen bytes */ | 674 | rr->length = 0; |
693 | if (rr->length < dest_maxlen) { | 675 | goto start; |
694 | s->internal->rstate = SSL_ST_READ_HEADER; | ||
695 | rr->length = 0; | ||
696 | goto start; | ||
697 | } | ||
698 | |||
699 | /* now move 'n' bytes: */ | ||
700 | for ( k = 0; k < dest_maxlen; k++) { | ||
701 | dest[k] = rr->data[rr->off++]; | ||
702 | rr->length--; | ||
703 | } | ||
704 | *dest_len = dest_maxlen; | ||
705 | } | 676 | } |
706 | } | 677 | } |
707 | 678 | ||
708 | /* D1I(s)->handshake_fragment_len == 12 iff rr->type == SSL3_RT_HANDSHAKE; | ||
709 | * D1I(s)->alert_fragment_len == 7 iff rr->type == SSL3_RT_ALERT. | ||
710 | * (Possibly rr is 'empty' now, i.e. rr->length may be 0.) */ | ||
711 | |||
712 | /* If we are a client, check for an incoming 'Hello Request': */ | 679 | /* If we are a client, check for an incoming 'Hello Request': */ |
713 | if ((!s->server) && | 680 | if (!s->server && rr->type == SSL3_RT_HANDSHAKE && |
714 | (D1I(s)->handshake_fragment_len >= DTLS1_HM_HEADER_LENGTH) && | 681 | rr->length >= DTLS1_HM_HEADER_LENGTH && rr->off == 0 && |
715 | (D1I(s)->handshake_fragment[0] == SSL3_MT_HELLO_REQUEST) && | 682 | rr->data[0] == SSL3_MT_HELLO_REQUEST && |
716 | (s->session != NULL) && (s->session->cipher != NULL)) { | 683 | s->session != NULL && s->session->cipher != NULL) { |
717 | D1I(s)->handshake_fragment_len = 0; | 684 | if (rr->data[1] != 0 || rr->data[2] != 0 || rr->data[3] != 0) { |
718 | |||
719 | if ((D1I(s)->handshake_fragment[1] != 0) || | ||
720 | (D1I(s)->handshake_fragment[2] != 0) || | ||
721 | (D1I(s)->handshake_fragment[3] != 0)) { | ||
722 | al = SSL_AD_DECODE_ERROR; | 685 | al = SSL_AD_DECODE_ERROR; |
723 | SSLerror(s, SSL_R_BAD_HELLO_REQUEST); | 686 | SSLerror(s, SSL_R_BAD_HELLO_REQUEST); |
724 | goto fatal_err; | 687 | goto fatal_err; |
725 | } | 688 | } |
689 | rr->length = 0; | ||
726 | 690 | ||
727 | /* no need to check sequence number on HELLO REQUEST messages */ | 691 | /* no need to check sequence number on HELLO REQUEST messages */ |
728 | 692 | ||
729 | ssl_msg_callback(s, 0, SSL3_RT_HANDSHAKE, | 693 | ssl_msg_callback(s, 0, SSL3_RT_HANDSHAKE, rr->data, 4); |
730 | D1I(s)->handshake_fragment, 4); | ||
731 | 694 | ||
732 | if (SSL_is_init_finished(s) && | 695 | if (SSL_is_init_finished(s) && |
733 | !(s->s3->flags & SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS) && | 696 | !(s->s3->flags & SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS) && |
@@ -763,16 +726,16 @@ dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek) | |||
763 | } | 726 | } |
764 | /* we either finished a handshake or ignored the request, | 727 | /* we either finished a handshake or ignored the request, |
765 | * now try again to obtain the (application) data we were asked for */ | 728 | * now try again to obtain the (application) data we were asked for */ |
729 | rr->length = 0; | ||
766 | goto start; | 730 | goto start; |
767 | } | 731 | } |
768 | 732 | ||
769 | if (D1I(s)->alert_fragment_len >= DTLS1_AL_HEADER_LENGTH) { | 733 | if (rr->type == SSL3_RT_ALERT && rr->length >= DTLS1_AL_HEADER_LENGTH && |
770 | int alert_level = D1I(s)->alert_fragment[0]; | 734 | rr->off == 0) { |
771 | int alert_descr = D1I(s)->alert_fragment[1]; | 735 | int alert_level = rr->data[0]; |
772 | 736 | int alert_descr = rr->data[1]; | |
773 | D1I(s)->alert_fragment_len = 0; | ||
774 | 737 | ||
775 | ssl_msg_callback(s, 0, SSL3_RT_ALERT, D1I(s)->alert_fragment, 2); | 738 | ssl_msg_callback(s, 0, SSL3_RT_ALERT, rr->data, 2); |
776 | 739 | ||
777 | ssl_info_callback(s, SSL_CB_READ_ALERT, | 740 | ssl_info_callback(s, SSL_CB_READ_ALERT, |
778 | (alert_level << 8) | alert_descr); | 741 | (alert_level << 8) | alert_descr); |
@@ -798,11 +761,11 @@ dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek) | |||
798 | goto fatal_err; | 761 | goto fatal_err; |
799 | } | 762 | } |
800 | 763 | ||
764 | rr->length = 0; | ||
801 | goto start; | 765 | goto start; |
802 | } | 766 | } |
803 | 767 | ||
804 | if (s->internal->shutdown & SSL_SENT_SHUTDOWN) /* but we have not received a shutdown */ | 768 | if (s->internal->shutdown & SSL_SENT_SHUTDOWN) { |
805 | { | ||
806 | s->internal->rwstate = SSL_NOTHING; | 769 | s->internal->rwstate = SSL_NOTHING; |
807 | rr->length = 0; | 770 | rr->length = 0; |
808 | return (0); | 771 | return (0); |
@@ -819,14 +782,13 @@ dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek) | |||
819 | goto fatal_err; | 782 | goto fatal_err; |
820 | } | 783 | } |
821 | 784 | ||
822 | rr->length = 0; | ||
823 | |||
824 | ssl_msg_callback(s, 0, SSL3_RT_CHANGE_CIPHER_SPEC, rr->data, 1); | 785 | ssl_msg_callback(s, 0, SSL3_RT_CHANGE_CIPHER_SPEC, rr->data, 1); |
825 | 786 | ||
826 | /* We can't process a CCS now, because previous handshake | 787 | /* We can't process a CCS now, because previous handshake |
827 | * messages are still missing, so just drop it. | 788 | * messages are still missing, so just drop it. |
828 | */ | 789 | */ |
829 | if (!D1I(s)->change_cipher_spec_ok) { | 790 | if (!D1I(s)->change_cipher_spec_ok) { |
791 | rr->length = 0; | ||
830 | goto start; | 792 | goto start; |
831 | } | 793 | } |
832 | 794 | ||
@@ -836,11 +798,13 @@ dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek) | |||
836 | if (!ssl3_do_change_cipher_spec(s)) | 798 | if (!ssl3_do_change_cipher_spec(s)) |
837 | goto err; | 799 | goto err; |
838 | 800 | ||
801 | rr->length = 0; | ||
839 | goto start; | 802 | goto start; |
840 | } | 803 | } |
841 | 804 | ||
842 | /* Unexpected handshake message (Client Hello, or protocol violation) */ | 805 | /* Unexpected handshake message (Client Hello, or protocol violation) */ |
843 | if ((D1I(s)->handshake_fragment_len >= DTLS1_HM_HEADER_LENGTH) && | 806 | if (rr->type == SSL3_RT_HANDSHAKE && |
807 | rr->length >= DTLS1_HM_HEADER_LENGTH && rr->off == 0 && | ||
844 | !s->internal->in_handshake) { | 808 | !s->internal->in_handshake) { |
845 | struct hm_header_st msg_hdr; | 809 | struct hm_header_st msg_hdr; |
846 | 810 | ||
@@ -893,6 +857,7 @@ dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek) | |||
893 | return (-1); | 857 | return (-1); |
894 | } | 858 | } |
895 | } | 859 | } |
860 | rr->length = 0; | ||
896 | goto start; | 861 | goto start; |
897 | } | 862 | } |
898 | 863 | ||
@@ -967,39 +932,6 @@ dtls1_write_app_data_bytes(SSL *s, int type, const void *buf_, int len) | |||
967 | return i; | 932 | return i; |
968 | } | 933 | } |
969 | 934 | ||
970 | |||
971 | /* this only happens when a client hello is received and a handshake | ||
972 | * is started. */ | ||
973 | static int | ||
974 | have_handshake_fragment(SSL *s, int type, unsigned char *buf, | ||
975 | int len, int peek) | ||
976 | { | ||
977 | |||
978 | if ((type == SSL3_RT_HANDSHAKE) && (D1I(s)->handshake_fragment_len > 0)) | ||
979 | /* (partially) satisfy request from storage */ | ||
980 | { | ||
981 | unsigned char *src = D1I(s)->handshake_fragment; | ||
982 | unsigned char *dst = buf; | ||
983 | unsigned int k, n; | ||
984 | |||
985 | /* peek == 0 */ | ||
986 | n = 0; | ||
987 | while ((len > 0) && (D1I(s)->handshake_fragment_len > 0)) { | ||
988 | *dst++ = *src++; | ||
989 | len--; | ||
990 | D1I(s)->handshake_fragment_len--; | ||
991 | n++; | ||
992 | } | ||
993 | /* move any remaining fragment bytes: */ | ||
994 | for (k = 0; k < D1I(s)->handshake_fragment_len; k++) | ||
995 | D1I(s)->handshake_fragment[k] = *src++; | ||
996 | return n; | ||
997 | } | ||
998 | |||
999 | return 0; | ||
1000 | } | ||
1001 | |||
1002 | |||
1003 | /* Call this to write data in records of type 'type' | 935 | /* Call this to write data in records of type 'type' |
1004 | * It will return <= 0 if not all data has been sent or non-blocking IO. | 936 | * It will return <= 0 if not all data has been sent or non-blocking IO. |
1005 | */ | 937 | */ |
diff --git a/src/lib/libssl/dtls_locl.h b/src/lib/libssl/dtls_locl.h index 83fb9e0e10..502b42dcdd 100644 --- a/src/lib/libssl/dtls_locl.h +++ b/src/lib/libssl/dtls_locl.h | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: dtls_locl.h,v 1.5 2021/08/30 19:12:25 jsing Exp $ */ | 1 | /* $OpenBSD: dtls_locl.h,v 1.6 2021/08/31 13:34:55 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. |
@@ -167,13 +167,6 @@ typedef struct dtls1_state_internal_st { | |||
167 | 167 | ||
168 | struct dtls1_timeout_st timeout; | 168 | struct dtls1_timeout_st timeout; |
169 | 169 | ||
170 | /* storage for Alert/Handshake protocol data received but not | ||
171 | * yet processed by ssl3_read_bytes: */ | ||
172 | unsigned char alert_fragment[DTLS1_AL_HEADER_LENGTH]; | ||
173 | unsigned int alert_fragment_len; | ||
174 | unsigned char handshake_fragment[DTLS1_HM_HEADER_LENGTH]; | ||
175 | unsigned int handshake_fragment_len; | ||
176 | |||
177 | unsigned int retransmitting; | 170 | unsigned int retransmitting; |
178 | unsigned int change_cipher_spec_ok; | 171 | unsigned int change_cipher_spec_ok; |
179 | } DTLS1_STATE_INTERNAL; | 172 | } DTLS1_STATE_INTERNAL; |