summaryrefslogtreecommitdiff
path: root/src/lib/libssl/ssl_pkt.c
diff options
context:
space:
mode:
authorjsing <>2022-02-21 18:22:20 +0000
committerjsing <>2022-02-21 18:22:20 +0000
commita59b14b2d3f8047fe5b687d37304433773603a3f (patch)
treeb58aa2f628b6d8b36920b544c96c0647c2281969 /src/lib/libssl/ssl_pkt.c
parent194ce8d94cd74f12663cf8ca258294804ca1aabf (diff)
downloadopenbsd-a59b14b2d3f8047fe5b687d37304433773603a3f.tar.gz
openbsd-a59b14b2d3f8047fe5b687d37304433773603a3f.tar.bz2
openbsd-a59b14b2d3f8047fe5b687d37304433773603a3f.zip
Factor out alert handing code in the legacy stack.libressl-v3.5.0
Pull out the code that processes incoming alerts - a chunk of the complexity is due to the fact that in TLSv1.2 and earlier, alerts can be fragmented across multiple records or multiple alerts can be delivered in a single record. In DTLS there is no way that we can reassemble fragmented alerts (although the RFC is silent on this), however we could have multiple alerts in the same record. This change means that we will handle this situation more appropriately and if we encounter a fragmented alert we will now treat this as a decode error (instead of silently ignoring it). ok beck@ tb@
Diffstat (limited to 'src/lib/libssl/ssl_pkt.c')
-rw-r--r--src/lib/libssl/ssl_pkt.c122
1 files changed, 71 insertions, 51 deletions
diff --git a/src/lib/libssl/ssl_pkt.c b/src/lib/libssl/ssl_pkt.c
index 3374713644..e3b2034eb4 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.53 2022/02/05 14:54:10 jsing Exp $ */ 1/* $OpenBSD: ssl_pkt.c,v 1.54 2022/02/21 18:22:20 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 *
@@ -685,6 +685,73 @@ ssl3_write_pending(SSL *s, int type, const unsigned char *buf, unsigned int len)
685 } 685 }
686} 686}
687 687
688int
689ssl3_read_alert(SSL *s)
690{
691 SSL3_RECORD_INTERNAL *rr = &s->s3->rrec;
692 uint8_t alert_level, alert_descr;
693
694 /*
695 * TLSv1.2 permits an alert to be fragmented across multiple records or
696 * for multiple alerts to be be coalesced into a single alert record.
697 * In the case of DTLS, there is no way to reassemble an alert
698 * fragmented across multiple records, hence a full alert must be
699 * available in the record.
700 */
701 while (rr->length > 0 &&
702 s->s3->alert_fragment_len < sizeof(s->s3->alert_fragment)) {
703 s->s3->alert_fragment[s->s3->alert_fragment_len++] =
704 rr->data[rr->off++];
705 rr->length--;
706 }
707 if (s->s3->alert_fragment_len < sizeof(s->s3->alert_fragment)) {
708 if (SSL_is_dtls(s)) {
709 SSLerror(s, SSL_R_BAD_LENGTH);
710 ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
711 return -1;
712 }
713 return 1;
714 }
715
716 ssl_msg_callback(s, 0, SSL3_RT_ALERT, s->s3->alert_fragment, 2);
717
718 alert_level = s->s3->alert_fragment[0];
719 alert_descr = s->s3->alert_fragment[1];
720 s->s3->alert_fragment_len = 0;
721
722 ssl_info_callback(s, SSL_CB_READ_ALERT,
723 (alert_level << 8) | alert_descr);
724
725 if (alert_level == SSL3_AL_WARNING) {
726 s->s3->warn_alert = alert_descr;
727 if (alert_descr == SSL_AD_CLOSE_NOTIFY) {
728 s->internal->shutdown |= SSL_RECEIVED_SHUTDOWN;
729 return 0;
730 }
731 /* We requested renegotiation and the peer rejected it. */
732 if (alert_descr == SSL_AD_NO_RENEGOTIATION) {
733 SSLerror(s, SSL_R_NO_RENEGOTIATION);
734 ssl3_send_alert(s, SSL3_AL_FATAL,
735 SSL_AD_HANDSHAKE_FAILURE);
736 return -1;
737 }
738 } else if (alert_level == SSL3_AL_FATAL) {
739 s->internal->rwstate = SSL_NOTHING;
740 s->s3->fatal_alert = alert_descr;
741 SSLerror(s, SSL_AD_REASON_OFFSET + alert_descr);
742 ERR_asprintf_error_data("SSL alert number %d", alert_descr);
743 s->internal->shutdown |= SSL_RECEIVED_SHUTDOWN;
744 SSL_CTX_remove_session(s->ctx, s->session);
745 return 0;
746 } else {
747 SSLerror(s, SSL_R_UNKNOWN_ALERT_TYPE);
748 ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
749 return -1;
750 }
751
752 return 1;
753}
754
688/* Return up to 'len' payload bytes received in 'type' records. 755/* Return up to 'len' payload bytes received in 'type' records.
689 * 'type' is one of the following: 756 * 'type' is one of the following:
690 * 757 *
@@ -875,10 +942,6 @@ ssl3_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek)
875 dest_maxlen = sizeof s->s3->handshake_fragment; 942 dest_maxlen = sizeof s->s3->handshake_fragment;
876 dest = s->s3->handshake_fragment; 943 dest = s->s3->handshake_fragment;
877 dest_len = &s->s3->handshake_fragment_len; 944 dest_len = &s->s3->handshake_fragment_len;
878 } else if (rr->type == SSL3_RT_ALERT) {
879 dest_maxlen = sizeof s->s3->alert_fragment;
880 dest = s->s3->alert_fragment;
881 dest_len = &s->s3->alert_fragment_len;
882 } 945 }
883 if (dest_maxlen > 0) { 946 if (dest_maxlen > 0) {
884 /* available space in 'dest' */ 947 /* available space in 'dest' */
@@ -966,53 +1029,10 @@ ssl3_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek)
966 ssl3_send_alert(s, SSL3_AL_WARNING, SSL_AD_NO_RENEGOTIATION); 1029 ssl3_send_alert(s, SSL3_AL_WARNING, SSL_AD_NO_RENEGOTIATION);
967 goto start; 1030 goto start;
968 } 1031 }
969 if (s->s3->alert_fragment_len >= 2) {
970 int alert_level = s->s3->alert_fragment[0];
971 int alert_descr = s->s3->alert_fragment[1];
972
973 s->s3->alert_fragment_len = 0;
974
975 ssl_msg_callback(s, 0, SSL3_RT_ALERT,
976 s->s3->alert_fragment, 2);
977
978 ssl_info_callback(s, SSL_CB_READ_ALERT,
979 (alert_level << 8) | alert_descr);
980
981 if (alert_level == SSL3_AL_WARNING) {
982 s->s3->warn_alert = alert_descr;
983 if (alert_descr == SSL_AD_CLOSE_NOTIFY) {
984 s->internal->shutdown |= SSL_RECEIVED_SHUTDOWN;
985 return (0);
986 }
987 /* This is a warning but we receive it if we requested
988 * renegotiation and the peer denied it. Terminate with
989 * a fatal alert because if application tried to
990 * renegotiatie it presumably had a good reason and
991 * expects it to succeed.
992 *
993 * In future we might have a renegotiation where we
994 * don't care if the peer refused it where we carry on.
995 */
996 else if (alert_descr == SSL_AD_NO_RENEGOTIATION) {
997 al = SSL_AD_HANDSHAKE_FAILURE;
998 SSLerror(s, SSL_R_NO_RENEGOTIATION);
999 goto fatal_err;
1000 }
1001 } else if (alert_level == SSL3_AL_FATAL) {
1002 s->internal->rwstate = SSL_NOTHING;
1003 s->s3->fatal_alert = alert_descr;
1004 SSLerror(s, SSL_AD_REASON_OFFSET + alert_descr);
1005 ERR_asprintf_error_data("SSL alert number %d",
1006 alert_descr);
1007 s->internal->shutdown |= SSL_RECEIVED_SHUTDOWN;
1008 SSL_CTX_remove_session(s->ctx, s->session);
1009 return (0);
1010 } else {
1011 al = SSL_AD_ILLEGAL_PARAMETER;
1012 SSLerror(s, SSL_R_UNKNOWN_ALERT_TYPE);
1013 goto fatal_err;
1014 }
1015 1032
1033 if (rr->type == SSL3_RT_ALERT) {
1034 if ((ret = ssl3_read_alert(s)) <= 0)
1035 return ret;
1016 goto start; 1036 goto start;
1017 } 1037 }
1018 1038