aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--crypto/err/openssl.txt2
-rw-r--r--include/openssl/sslerr.h1
-rw-r--r--ssl/record/rec_layer_s3.c15
-rw-r--r--ssl/ssl_err.c2
-rw-r--r--test/sslapitest.c19
5 files changed, 29 insertions, 10 deletions
diff --git a/crypto/err/openssl.txt b/crypto/err/openssl.txt
index e65a80670d..ee68388b50 100644
--- a/crypto/err/openssl.txt
+++ b/crypto/err/openssl.txt
@@ -2544,6 +2544,8 @@ SM2_R_INVALID_ENCODING:104:invalid encoding
SM2_R_INVALID_FIELD:105:invalid field
SM2_R_NO_PARAMETERS_SET:109:no parameters set
SM2_R_USER_ID_TOO_LARGE:106:user id too large
+SSL_R_APPLICATION_DATA_AFTER_CLOSE_NOTIFY:291:\
+ application data after close notify
SSL_R_APP_DATA_IN_HANDSHAKE:100:app data in handshake
SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT:272:\
attempt to reuse session in different context
diff --git a/include/openssl/sslerr.h b/include/openssl/sslerr.h
index b2c6c1ee37..9eba6d8fd5 100644
--- a/include/openssl/sslerr.h
+++ b/include/openssl/sslerr.h
@@ -449,6 +449,7 @@ int ERR_load_SSL_strings(void);
/*
* SSL reason codes.
*/
+# define SSL_R_APPLICATION_DATA_AFTER_CLOSE_NOTIFY 291
# define SSL_R_APP_DATA_IN_HANDSHAKE 100
# define SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT 272
# define SSL_R_AT_LEAST_TLS_1_0_NEEDED_IN_FIPS_MODE 143
diff --git a/ssl/record/rec_layer_s3.c b/ssl/record/rec_layer_s3.c
index e12a2178a4..1628ac8f9a 100644
--- a/ssl/record/rec_layer_s3.c
+++ b/ssl/record/rec_layer_s3.c
@@ -1573,11 +1573,18 @@ int ssl3_read_bytes(SSL *s, int type, int *recvd_type, unsigned char *buf,
rbio = SSL_get_rbio(s);
BIO_clear_retry_flags(rbio);
BIO_set_retry_read(rbio);
- return -1;
+ } else {
+ /*
+ * The peer is continuing to send application data, but we have
+ * already sent close_notify. If this was expected we should have
+ * been called via SSL_read() and this would have been handled
+ * above.
+ * No alert sent because we already sent close_notify
+ */
+ SSLfatal(s, SSL_AD_NO_ALERT, SSL_F_SSL3_READ_BYTES,
+ SSL_R_APPLICATION_DATA_AFTER_CLOSE_NOTIFY);
}
-
- s->rwstate = SSL_NOTHING;
- return 0;
+ return -1;
}
/*
diff --git a/ssl/ssl_err.c b/ssl/ssl_err.c
index 03c5bf255e..9ce643ae8e 100644
--- a/ssl/ssl_err.c
+++ b/ssl/ssl_err.c
@@ -726,6 +726,8 @@ static const ERR_STRING_DATA SSL_str_functs[] = {
};
static const ERR_STRING_DATA SSL_str_reasons[] = {
+ {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_APPLICATION_DATA_AFTER_CLOSE_NOTIFY),
+ "application data after close notify"},
{ERR_PACK(ERR_LIB_SSL, 0, SSL_R_APP_DATA_IN_HANDSHAKE),
"app data in handshake"},
{ERR_PACK(ERR_LIB_SSL, 0, SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT),
diff --git a/test/sslapitest.c b/test/sslapitest.c
index ec449560f4..baf0881cd0 100644
--- a/test/sslapitest.c
+++ b/test/sslapitest.c
@@ -5069,18 +5069,25 @@ static int test_shutdown(int tst)
|| !TEST_int_eq(SSL_shutdown(clientssl), 1)
|| !TEST_int_eq(SSL_shutdown(serverssl), 1))
goto end;
- } else {
+ } else if (tst == 4) {
/*
* In this test the client has sent close_notify and it has been
* received by the server which has responded with a close_notify. The
- * client needs to read the close_notify sent by the server. When
- * tst == 5, there is application data to be read first but this is
- * discarded with a -1 return value.
+ * client needs to read the close_notify sent by the server.
*/
- if (tst == 5 && !TEST_int_eq(SSL_shutdown(clientssl), -1))
- goto end;
if (!TEST_int_eq(SSL_shutdown(clientssl), 1))
goto end;
+ } else {
+ /*
+ * tst == 5
+ *
+ * The client has sent close_notify and is expecting a close_notify
+ * back, but instead there is application data first. The shutdown
+ * should fail with a fatal error.
+ */
+ if (!TEST_int_eq(SSL_shutdown(clientssl), -1)
+ || !TEST_int_eq(SSL_get_error(clientssl, -1), SSL_ERROR_SSL))
+ goto end;
}
testresult = 1;