summaryrefslogtreecommitdiffstats
path: root/ssl/statem/statem_dtls.c
diff options
context:
space:
mode:
authorMatt Caswell <matt@openssl.org>2018-01-16 11:48:01 +0100
committerMatt Caswell <matt@openssl.org>2018-03-21 11:27:29 +0100
commit2e92af5ea5987354fd7fe582a07440ff7aca01f4 (patch)
treee1092f003f05bf416f17f3c82152eaaab6837048 /ssl/statem/statem_dtls.c
parentFix stack-use-after-scope (diff)
downloadopenssl-2e92af5ea5987354fd7fe582a07440ff7aca01f4.tar.xz
openssl-2e92af5ea5987354fd7fe582a07440ff7aca01f4.zip
Check for alerts while waiting for a dry event
At a couple of points in a DTLS/SCTP handshake we need to wait for a dry event before continuing. However if an alert has been sent by the peer then we will never receive that dry event and an infinite loop results. This commit changes things so that we attempt to read a message if we are waiting for a dry event but haven't got one yet. This should never succeed, but any alerts will be processed. Fixes #4763 Reviewed-by: Rich Salz <rsalz@openssl.org> (Merged from https://github.com/openssl/openssl/pull/5084)
Diffstat (limited to 'ssl/statem/statem_dtls.c')
-rw-r--r--ssl/statem/statem_dtls.c20
1 files changed, 19 insertions, 1 deletions
diff --git a/ssl/statem/statem_dtls.c b/ssl/statem/statem_dtls.c
index 9bda18b8ca..b5e62a2a7e 100644
--- a/ssl/statem/statem_dtls.c
+++ b/ssl/statem/statem_dtls.c
@@ -922,9 +922,14 @@ int dtls_construct_change_cipher_spec(SSL *s, WPACKET *pkt)
}
#ifndef OPENSSL_NO_SCTP
+/*
+ * Wait for a dry event. Should only be called at a point in the handshake
+ * where we are not expecting any data from the peer except an alert.
+ */
WORK_STATE dtls_wait_for_dry(SSL *s)
{
- int ret;
+ int ret, errtype;
+ size_t len;
/* read app data until dry event */
ret = BIO_dgram_sctp_wait_for_dry(SSL_get_wbio(s));
@@ -935,6 +940,19 @@ WORK_STATE dtls_wait_for_dry(SSL *s)
}
if (ret == 0) {
+ /*
+ * We're not expecting any more messages from the peer at this point -
+ * but we could get an alert. If an alert is waiting then we will never
+ * return successfully. Therefore we attempt to read a message. This
+ * should never succeed but will process any waiting alerts.
+ */
+ if (dtls_get_reassembled_message(s, &errtype, &len)) {
+ /* The call succeeded! This should never happen */
+ SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, SSL_F_DTLS_WAIT_FOR_DRY,
+ SSL_R_UNEXPECTED_MESSAGE);
+ return WORK_ERROR;
+ }
+
s->s3->in_read_app_data = 2;
s->rwstate = SSL_READING;
BIO_clear_retry_flags(SSL_get_rbio(s));