summaryrefslogtreecommitdiffstats
path: root/ssl/statem/statem_srvr.c
diff options
context:
space:
mode:
authorMatt Caswell <matt@openssl.org>2018-08-07 12:40:08 +0100
committerMatt Caswell <matt@openssl.org>2018-08-08 10:16:58 +0100
commitde9e884b2f43c59834c2b1c3cfde35fa2c797f2b (patch)
tree6e696fc5f4b219da631d844d68cd9a392e966099 /ssl/statem/statem_srvr.c
parent7426cd343d99d3d82e3fb06c8df18e5cc6bcec75 (diff)
Tolerate encrypted or plaintext alerts
At certain points in the handshake we could receive either a plaintext or an encrypted alert from the client. We should tolerate both where appropriate. Reviewed-by: Rich Salz <rsalz@openssl.org> (Merged from https://github.com/openssl/openssl/pull/6887)
Diffstat (limited to 'ssl/statem/statem_srvr.c')
-rw-r--r--ssl/statem/statem_srvr.c20
1 files changed, 14 insertions, 6 deletions
diff --git a/ssl/statem/statem_srvr.c b/ssl/statem/statem_srvr.c
index eb9070ecc4..db5aafe3be 100644
--- a/ssl/statem/statem_srvr.c
+++ b/ssl/statem/statem_srvr.c
@@ -848,12 +848,7 @@ WORK_STATE ossl_statem_server_post_work(SSL *s, WORK_STATE wst)
return WORK_MORE_A;
break;
}
- /*
- * TODO(TLS1.3): This actually causes a problem. We don't yet know
- * whether the next record we are going to receive is an unencrypted
- * alert, or an encrypted handshake message. We're going to need
- * something clever in the record layer for this.
- */
+
if (SSL_IS_TLS13(s)) {
if (!s->method->ssl3_enc->setup_key_block(s)
|| !s->method->ssl3_enc->change_cipher_state(s,
@@ -868,6 +863,12 @@ WORK_STATE ossl_statem_server_post_work(SSL *s, WORK_STATE wst)
/* SSLfatal() already called */
return WORK_ERROR;
}
+ /*
+ * We don't yet know whether the next record we are going to receive
+ * is an unencrypted alert, an encrypted alert, or an encrypted
+ * handshake message. We temporarily tolerate unencrypted alerts.
+ */
+ s->statem.enc_read_state = ENC_READ_STATE_ALLOW_PLAIN_ALERTS;
break;
}
@@ -3523,6 +3524,13 @@ MSG_PROCESS_RETURN tls_process_client_certificate(SSL *s, PACKET *pkt)
size_t chainidx;
SSL_SESSION *new_sess = NULL;
+ /*
+ * To get this far we must have read encrypted data from the client. We no
+ * longer tolerate unencrypted alerts. This value is ignored if less than
+ * TLSv1.3
+ */
+ s->statem.enc_read_state = ENC_READ_STATE_VALID;
+
if ((sk = sk_X509_new_null()) == NULL) {
SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PROCESS_CLIENT_CERTIFICATE,
ERR_R_MALLOC_FAILURE);