diff options
Diffstat (limited to 'src/lib/libssl/d1_pkt.c')
-rw-r--r-- | src/lib/libssl/d1_pkt.c | 176 |
1 files changed, 83 insertions, 93 deletions
diff --git a/src/lib/libssl/d1_pkt.c b/src/lib/libssl/d1_pkt.c index f17608608e..456f871a43 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.122 2022/03/26 15:00:51 jsing Exp $ */ | 1 | /* $OpenBSD: d1_pkt.c,v 1.123 2022/03/26 15:05:53 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. |
@@ -685,29 +685,37 @@ dtls1_read_handshake_unexpected(SSL *s) | |||
685 | int | 685 | int |
686 | dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek) | 686 | dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek) |
687 | { | 687 | { |
688 | int al, i, ret; | 688 | SSL3_RECORD_INTERNAL *rr; |
689 | int rrcount = 0; | 689 | int rrcount = 0; |
690 | unsigned int n; | 690 | unsigned int n; |
691 | SSL3_RECORD_INTERNAL *rr; | 691 | int ret; |
692 | 692 | ||
693 | if (s->s3->rbuf.buf == NULL) /* Not initialized yet */ | 693 | if (s->s3->rbuf.buf == NULL) { |
694 | if (!ssl3_setup_buffers(s)) | 694 | if (!ssl3_setup_buffers(s)) |
695 | return (-1); | 695 | return -1; |
696 | } | ||
696 | 697 | ||
697 | if ((type && | 698 | if (len < 0) { |
698 | type != SSL3_RT_APPLICATION_DATA && type != SSL3_RT_HANDSHAKE) || | ||
699 | (peek && (type != SSL3_RT_APPLICATION_DATA))) { | ||
700 | SSLerror(s, ERR_R_INTERNAL_ERROR); | 699 | SSLerror(s, ERR_R_INTERNAL_ERROR); |
701 | return -1; | 700 | return -1; |
702 | } | 701 | } |
703 | 702 | ||
704 | if (!s->internal->in_handshake && SSL_in_init(s)) { | 703 | if (type != 0 && type != SSL3_RT_APPLICATION_DATA && |
705 | i = s->internal->handshake_func(s); | 704 | type != SSL3_RT_HANDSHAKE) { |
706 | if (i < 0) | 705 | SSLerror(s, ERR_R_INTERNAL_ERROR); |
707 | return (i); | 706 | return -1; |
708 | if (i == 0) { | 707 | } |
708 | if (peek && type != SSL3_RT_APPLICATION_DATA) { | ||
709 | SSLerror(s, ERR_R_INTERNAL_ERROR); | ||
710 | return -1; | ||
711 | } | ||
712 | |||
713 | if (SSL_in_init(s) && !s->internal->in_handshake) { | ||
714 | if ((ret = s->internal->handshake_func(s)) < 0) | ||
715 | return ret; | ||
716 | if (ret == 0) { | ||
709 | SSLerror(s, SSL_R_SSL_HANDSHAKE_FAILURE); | 717 | SSLerror(s, SSL_R_SSL_HANDSHAKE_FAILURE); |
710 | return (-1); | 718 | return -1; |
711 | } | 719 | } |
712 | } | 720 | } |
713 | 721 | ||
@@ -727,33 +735,24 @@ dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek) | |||
727 | 735 | ||
728 | s->internal->rwstate = SSL_NOTHING; | 736 | s->internal->rwstate = SSL_NOTHING; |
729 | 737 | ||
730 | /* s->s3->rrec.type - is the type of record | 738 | rr = &s->s3->rrec; |
731 | * s->s3->rrec.data, - data | ||
732 | * s->s3->rrec.off, - offset into 'data' for next read | ||
733 | * s->s3->rrec.length, - number of bytes. */ | ||
734 | rr = &(s->s3->rrec); | ||
735 | 739 | ||
736 | /* We are not handshaking and have no data yet, | 740 | /* |
737 | * so process data buffered during the last handshake | 741 | * We are not handshaking and have no data yet, so process data buffered |
738 | * in advance, if any. | 742 | * during the last handshake in advance, if any. |
739 | */ | 743 | */ |
740 | if (s->s3->hs.state == SSL_ST_OK && rr->length == 0) | 744 | if (s->s3->hs.state == SSL_ST_OK && rr->length == 0) |
741 | dtls1_retrieve_buffered_record(s, &(s->d1->buffered_app_data)); | 745 | dtls1_retrieve_buffered_record(s, &s->d1->buffered_app_data); |
742 | 746 | ||
743 | /* Check for timeout */ | ||
744 | if (dtls1_handle_timeout(s) > 0) | 747 | if (dtls1_handle_timeout(s) > 0) |
745 | goto start; | 748 | goto start; |
746 | 749 | ||
747 | /* get new packet if necessary */ | 750 | if (rr->length == 0 || s->internal->rstate == SSL_ST_READ_BODY) { |
748 | if ((rr->length == 0) || (s->internal->rstate == SSL_ST_READ_BODY)) { | 751 | if ((ret = dtls1_get_record(s)) <= 0) { |
749 | ret = dtls1_get_record(s); | 752 | /* Anything other than a timeout is an error. */ |
750 | if (ret <= 0) { | 753 | if ((ret = dtls1_read_failed(s, ret)) <= 0) |
751 | ret = dtls1_read_failed(s, ret); | 754 | return ret; |
752 | /* anything other than a timeout is an error */ | 755 | goto start; |
753 | if (ret <= 0) | ||
754 | return (ret); | ||
755 | else | ||
756 | goto start; | ||
757 | } | 756 | } |
758 | } | 757 | } |
759 | 758 | ||
@@ -762,17 +761,16 @@ dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek) | |||
762 | goto start; | 761 | goto start; |
763 | } | 762 | } |
764 | 763 | ||
765 | /* we now have a packet which can be read and processed */ | 764 | /* We now have a packet which can be read and processed. */ |
766 | 765 | ||
767 | if (s->s3->change_cipher_spec /* set when we receive ChangeCipherSpec, | 766 | if (s->s3->change_cipher_spec && rr->type != SSL3_RT_HANDSHAKE) { |
768 | * reset by ssl3_get_finished */ | 767 | /* |
769 | && (rr->type != SSL3_RT_HANDSHAKE)) { | 768 | * We now have application data between CCS and Finished. |
770 | /* We now have application data between CCS and Finished. | ||
771 | * Most likely the packets were reordered on their way, so | 769 | * Most likely the packets were reordered on their way, so |
772 | * buffer the application data for later processing rather | 770 | * buffer the application data for later processing rather |
773 | * than dropping the connection. | 771 | * than dropping the connection. |
774 | */ | 772 | */ |
775 | if (dtls1_buffer_record(s, &(s->d1->buffered_app_data), | 773 | if (dtls1_buffer_record(s, &s->d1->buffered_app_data, |
776 | rr->seq_num) < 0) { | 774 | rr->seq_num) < 0) { |
777 | SSLerror(s, ERR_R_INTERNAL_ERROR); | 775 | SSLerror(s, ERR_R_INTERNAL_ERROR); |
778 | return (-1); | 776 | return (-1); |
@@ -781,35 +779,41 @@ dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek) | |||
781 | goto start; | 779 | goto start; |
782 | } | 780 | } |
783 | 781 | ||
784 | /* If the other end has shut down, throw anything we read away | 782 | /* |
785 | * (even in 'peek' mode) */ | 783 | * If the other end has shut down, throw anything we read away (even in |
784 | * 'peek' mode). | ||
785 | */ | ||
786 | if (s->internal->shutdown & SSL_RECEIVED_SHUTDOWN) { | 786 | if (s->internal->shutdown & SSL_RECEIVED_SHUTDOWN) { |
787 | rr->length = 0; | ||
788 | s->internal->rwstate = SSL_NOTHING; | 787 | s->internal->rwstate = SSL_NOTHING; |
789 | return (0); | 788 | rr->length = 0; |
789 | return 0; | ||
790 | } | 790 | } |
791 | 791 | ||
792 | /* SSL3_RT_APPLICATION_DATA or SSL3_RT_HANDSHAKE */ | 792 | /* SSL3_RT_APPLICATION_DATA or SSL3_RT_HANDSHAKE */ |
793 | if (type == rr->type) { | 793 | if (type == rr->type) { |
794 | /* make sure that we are not getting application data when we | 794 | /* |
795 | * are doing a handshake for the first time */ | 795 | * Make sure that we are not getting application data when we |
796 | * are doing a handshake for the first time. | ||
797 | */ | ||
796 | if (SSL_in_init(s) && type == SSL3_RT_APPLICATION_DATA && | 798 | if (SSL_in_init(s) && type == SSL3_RT_APPLICATION_DATA && |
797 | !tls12_record_layer_read_protected(s->internal->rl)) { | 799 | !tls12_record_layer_read_protected(s->internal->rl)) { |
798 | al = SSL_AD_UNEXPECTED_MESSAGE; | ||
799 | SSLerror(s, SSL_R_APP_DATA_IN_HANDSHAKE); | 800 | SSLerror(s, SSL_R_APP_DATA_IN_HANDSHAKE); |
800 | goto fatal_err; | 801 | ssl3_send_alert(s, SSL3_AL_FATAL, |
802 | SSL_AD_UNEXPECTED_MESSAGE); | ||
803 | return -1; | ||
801 | } | 804 | } |
802 | 805 | ||
803 | if (len <= 0) | 806 | if (len <= 0) |
804 | return (len); | 807 | return len; |
805 | 808 | ||
806 | if ((unsigned int)len > rr->length) | 809 | if ((unsigned int)len > rr->length) |
807 | n = rr->length; | 810 | n = rr->length; |
808 | else | 811 | else |
809 | n = (unsigned int)len; | 812 | n = (unsigned int)len; |
810 | 813 | ||
811 | memcpy(buf, &(rr->data[rr->off]), n); | 814 | memcpy(buf, &rr->data[rr->off], n); |
812 | if (!peek) { | 815 | if (!peek) { |
816 | memset(&rr->data[rr->off], 0, n); | ||
813 | rr->length -= n; | 817 | rr->length -= n; |
814 | rr->off += n; | 818 | rr->off += n; |
815 | if (rr->length == 0) { | 819 | if (rr->length == 0) { |
@@ -818,7 +822,7 @@ dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek) | |||
818 | } | 822 | } |
819 | } | 823 | } |
820 | 824 | ||
821 | return (n); | 825 | return n; |
822 | } | 826 | } |
823 | 827 | ||
824 | /* | 828 | /* |
@@ -838,42 +842,16 @@ dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek) | |||
838 | return (0); | 842 | return (0); |
839 | } | 843 | } |
840 | 844 | ||
841 | if (rr->type == SSL3_RT_CHANGE_CIPHER_SPEC) { | 845 | if (rr->type == SSL3_RT_APPLICATION_DATA) { |
842 | if ((ret = ssl3_read_change_cipher_spec(s)) <= 0) | 846 | /* |
843 | return ret; | 847 | * At this point, we were expecting handshake data, but have |
844 | goto start; | 848 | * application data. If the library was running inside |
845 | } | 849 | * ssl3_read() (i.e. in_read_app_data is set) and it makes |
846 | 850 | * sense to read application data at this point (session | |
847 | if (rr->type == SSL3_RT_HANDSHAKE) { | 851 | * renegotiation not yet started), we will indulge it. |
848 | if ((ret = dtls1_read_handshake_unexpected(s)) <= 0) | ||
849 | return ret; | ||
850 | goto start; | ||
851 | } | ||
852 | |||
853 | switch (rr->type) { | ||
854 | default: | ||
855 | al = SSL_AD_UNEXPECTED_MESSAGE; | ||
856 | SSLerror(s, SSL_R_UNEXPECTED_RECORD); | ||
857 | goto fatal_err; | ||
858 | case SSL3_RT_CHANGE_CIPHER_SPEC: | ||
859 | case SSL3_RT_ALERT: | ||
860 | case SSL3_RT_HANDSHAKE: | ||
861 | /* we already handled all of these, with the possible exception | ||
862 | * of SSL3_RT_HANDSHAKE when s->internal->in_handshake is set, but that | ||
863 | * should not happen when type != rr->type */ | ||
864 | al = SSL_AD_UNEXPECTED_MESSAGE; | ||
865 | SSLerror(s, ERR_R_INTERNAL_ERROR); | ||
866 | goto fatal_err; | ||
867 | case SSL3_RT_APPLICATION_DATA: | ||
868 | /* At this point, we were expecting handshake data, | ||
869 | * but have application data. If the library was | ||
870 | * running inside ssl3_read() (i.e. in_read_app_data | ||
871 | * is set) and it makes sense to read application data | ||
872 | * at this point (session renegotiation not yet started), | ||
873 | * we will indulge it. | ||
874 | */ | 852 | */ |
875 | if (s->s3->in_read_app_data && | 853 | if (s->s3->in_read_app_data != 0 && |
876 | (s->s3->total_renegotiations != 0) && | 854 | s->s3->total_renegotiations != 0 && |
877 | (((s->s3->hs.state & SSL_ST_CONNECT) && | 855 | (((s->s3->hs.state & SSL_ST_CONNECT) && |
878 | (s->s3->hs.state >= SSL3_ST_CW_CLNT_HELLO_A) && | 856 | (s->s3->hs.state >= SSL3_ST_CW_CLNT_HELLO_A) && |
879 | (s->s3->hs.state <= SSL3_ST_CR_SRVR_HELLO_A)) || ( | 857 | (s->s3->hs.state <= SSL3_ST_CR_SRVR_HELLO_A)) || ( |
@@ -881,19 +859,31 @@ dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek) | |||
881 | (s->s3->hs.state <= SSL3_ST_SW_HELLO_REQ_A) && | 859 | (s->s3->hs.state <= SSL3_ST_SW_HELLO_REQ_A) && |
882 | (s->s3->hs.state >= SSL3_ST_SR_CLNT_HELLO_A)))) { | 860 | (s->s3->hs.state >= SSL3_ST_SR_CLNT_HELLO_A)))) { |
883 | s->s3->in_read_app_data = 2; | 861 | s->s3->in_read_app_data = 2; |
884 | return (-1); | 862 | return -1; |
885 | } else { | 863 | } else { |
886 | al = SSL_AD_UNEXPECTED_MESSAGE; | ||
887 | SSLerror(s, SSL_R_UNEXPECTED_RECORD); | 864 | SSLerror(s, SSL_R_UNEXPECTED_RECORD); |
888 | goto fatal_err; | 865 | ssl3_send_alert(s, SSL3_AL_FATAL, |
866 | SSL_AD_UNEXPECTED_MESSAGE); | ||
867 | return -1; | ||
889 | } | 868 | } |
890 | } | 869 | } |
891 | /* not reached */ | ||
892 | 870 | ||
893 | fatal_err: | 871 | if (rr->type == SSL3_RT_CHANGE_CIPHER_SPEC) { |
894 | ssl3_send_alert(s, SSL3_AL_FATAL, al); | 872 | if ((ret = ssl3_read_change_cipher_spec(s)) <= 0) |
873 | return ret; | ||
874 | goto start; | ||
875 | } | ||
895 | 876 | ||
896 | return (-1); | 877 | if (rr->type == SSL3_RT_HANDSHAKE) { |
878 | if ((ret = dtls1_read_handshake_unexpected(s)) <= 0) | ||
879 | return ret; | ||
880 | goto start; | ||
881 | } | ||
882 | |||
883 | /* Unknown record type. */ | ||
884 | SSLerror(s, SSL_R_UNEXPECTED_RECORD); | ||
885 | ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE); | ||
886 | return -1; | ||
897 | } | 887 | } |
898 | 888 | ||
899 | int | 889 | int |