diff options
Diffstat (limited to '')
-rw-r--r-- | src/lib/libssl/ssl_pkt.c | 102 |
1 files changed, 67 insertions, 35 deletions
diff --git a/src/lib/libssl/ssl_pkt.c b/src/lib/libssl/ssl_pkt.c index e3b2034eb4..33bb4b659f 100644 --- a/src/lib/libssl/ssl_pkt.c +++ b/src/lib/libssl/ssl_pkt.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ssl_pkt.c,v 1.54 2022/02/21 18:22:20 jsing Exp $ */ | 1 | /* $OpenBSD: ssl_pkt.c,v 1.55 2022/03/12 12:53:03 jsing Exp $ */ |
2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) |
3 | * All rights reserved. | 3 | * All rights reserved. |
4 | * | 4 | * |
@@ -752,6 +752,68 @@ ssl3_read_alert(SSL *s) | |||
752 | return 1; | 752 | return 1; |
753 | } | 753 | } |
754 | 754 | ||
755 | int | ||
756 | ssl3_read_change_cipher_spec(SSL *s) | ||
757 | { | ||
758 | SSL3_RECORD_INTERNAL *rr = &s->s3->rrec; | ||
759 | |||
760 | /* | ||
761 | * 'Change Cipher Spec' is just a single byte, so we know exactly what | ||
762 | * the record payload has to look like. | ||
763 | */ | ||
764 | if (rr->length != 1 || rr->off != 0) { | ||
765 | SSLerror(s, SSL_R_BAD_CHANGE_CIPHER_SPEC); | ||
766 | ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); | ||
767 | return -1; | ||
768 | } | ||
769 | if (rr->data[0] != SSL3_MT_CCS) { | ||
770 | SSLerror(s, SSL_R_BAD_CHANGE_CIPHER_SPEC); | ||
771 | ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER); | ||
772 | return -1; | ||
773 | } | ||
774 | |||
775 | /* XDTLS: check that epoch is consistent */ | ||
776 | |||
777 | ssl_msg_callback(s, 0, SSL3_RT_CHANGE_CIPHER_SPEC, rr->data, 1); | ||
778 | |||
779 | /* Check that we have a cipher to change to. */ | ||
780 | if (s->s3->hs.cipher == NULL) { | ||
781 | SSLerror(s, SSL_R_CCS_RECEIVED_EARLY); | ||
782 | ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE); | ||
783 | return -1; | ||
784 | } | ||
785 | |||
786 | /* Check that we should be receiving a Change Cipher Spec. */ | ||
787 | if (SSL_is_dtls(s)) { | ||
788 | if (!s->d1->change_cipher_spec_ok) { | ||
789 | /* | ||
790 | * We can't process a CCS now, because previous | ||
791 | * handshake messages are still missing, so just | ||
792 | * drop it. | ||
793 | */ | ||
794 | rr->length = 0; | ||
795 | return 1; | ||
796 | } | ||
797 | s->d1->change_cipher_spec_ok = 0; | ||
798 | } else { | ||
799 | if ((s->s3->flags & SSL3_FLAGS_CCS_OK) == 0) { | ||
800 | SSLerror(s, SSL_R_CCS_RECEIVED_EARLY); | ||
801 | ssl3_send_alert(s, SSL3_AL_FATAL, | ||
802 | SSL_AD_UNEXPECTED_MESSAGE); | ||
803 | return -1; | ||
804 | } | ||
805 | s->s3->flags &= ~SSL3_FLAGS_CCS_OK; | ||
806 | } | ||
807 | |||
808 | rr->length = 0; | ||
809 | |||
810 | s->s3->change_cipher_spec = 1; | ||
811 | if (!ssl3_do_change_cipher_spec(s)) | ||
812 | return -1; | ||
813 | |||
814 | return 1; | ||
815 | } | ||
816 | |||
755 | /* Return up to 'len' payload bytes received in 'type' records. | 817 | /* Return up to 'len' payload bytes received in 'type' records. |
756 | * 'type' is one of the following: | 818 | * 'type' is one of the following: |
757 | * | 819 | * |
@@ -1044,39 +1106,9 @@ ssl3_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek) | |||
1044 | } | 1106 | } |
1045 | 1107 | ||
1046 | if (rr->type == SSL3_RT_CHANGE_CIPHER_SPEC) { | 1108 | if (rr->type == SSL3_RT_CHANGE_CIPHER_SPEC) { |
1047 | /* 'Change Cipher Spec' is just a single byte, so we know | 1109 | if ((ret = ssl3_read_change_cipher_spec(s)) <= 0) |
1048 | * exactly what the record payload has to look like */ | 1110 | return ret; |
1049 | if ((rr->length != 1) || (rr->off != 0) || | 1111 | goto start; |
1050 | (rr->data[0] != SSL3_MT_CCS)) { | ||
1051 | al = SSL_AD_ILLEGAL_PARAMETER; | ||
1052 | SSLerror(s, SSL_R_BAD_CHANGE_CIPHER_SPEC); | ||
1053 | goto fatal_err; | ||
1054 | } | ||
1055 | |||
1056 | /* Check we have a cipher to change to */ | ||
1057 | if (s->s3->hs.cipher == NULL) { | ||
1058 | al = SSL_AD_UNEXPECTED_MESSAGE; | ||
1059 | SSLerror(s, SSL_R_CCS_RECEIVED_EARLY); | ||
1060 | goto fatal_err; | ||
1061 | } | ||
1062 | |||
1063 | /* Check that we should be receiving a Change Cipher Spec. */ | ||
1064 | if (!(s->s3->flags & SSL3_FLAGS_CCS_OK)) { | ||
1065 | al = SSL_AD_UNEXPECTED_MESSAGE; | ||
1066 | SSLerror(s, SSL_R_CCS_RECEIVED_EARLY); | ||
1067 | goto fatal_err; | ||
1068 | } | ||
1069 | s->s3->flags &= ~SSL3_FLAGS_CCS_OK; | ||
1070 | |||
1071 | rr->length = 0; | ||
1072 | |||
1073 | ssl_msg_callback(s, 0, SSL3_RT_CHANGE_CIPHER_SPEC, rr->data, 1); | ||
1074 | |||
1075 | s->s3->change_cipher_spec = 1; | ||
1076 | if (!ssl3_do_change_cipher_spec(s)) | ||
1077 | goto err; | ||
1078 | else | ||
1079 | goto start; | ||
1080 | } | 1112 | } |
1081 | 1113 | ||
1082 | /* Unexpected handshake message (Client Hello, or protocol violation) */ | 1114 | /* Unexpected handshake message (Client Hello, or protocol violation) */ |
@@ -1155,7 +1187,7 @@ ssl3_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek) | |||
1155 | 1187 | ||
1156 | fatal_err: | 1188 | fatal_err: |
1157 | ssl3_send_alert(s, SSL3_AL_FATAL, al); | 1189 | ssl3_send_alert(s, SSL3_AL_FATAL, al); |
1158 | err: | 1190 | |
1159 | return (-1); | 1191 | return (-1); |
1160 | } | 1192 | } |
1161 | 1193 | ||