summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorDaiki Ueno <ueno@gnu.org>2022-12-08 11:53:20 +0900
committerDaiki Ueno <ueno@gnu.org>2022-12-21 15:09:09 +0900
commit0aaa4015d2a1b41681d8d60bcb4b0a7b805515da (patch)
tree47d48b85a8171fddeffa1d4d53f119f3fd2dc4eb /lib
parent9e2ccc12a56181c1cf6dea5bd898c703ecbc9652 (diff)
downloadgnutls-0aaa4015d2a1b41681d8d60bcb4b0a7b805515da.tar.gz
record: enable check on CCS content also in TLS 1.2
This generilizes the value check of Change Cipher Spec for all TLS protocol versions including TLS 1.2 or earlier. It also fixes the logic of the check so the value is decrypted before being examined, according to the RFC. Signed-off-by: Daiki Ueno <ueno@gnu.org>
Diffstat (limited to 'lib')
-rw-r--r--lib/record.c33
1 files changed, 25 insertions, 8 deletions
diff --git a/lib/record.c b/lib/record.c
index aad128e1f2..53adc83076 100644
--- a/lib/record.c
+++ b/lib/record.c
@@ -854,6 +854,16 @@ record_add_to_buffers(gnutls_session_t session,
goto unexpected_packet;
}
+ /* if the CCS has value other than 1 abort the connection,
+ * unless old DTLS is negotiated, where CCS includes a sequence
+ * number */
+ if (type == GNUTLS_CHANGE_CIPHER_SPEC &&
+ !(ver && ver->id == GNUTLS_DTLS0_9) &&
+ (bufel->msg.size != 1 || bufel->msg.data[0] != 1)) {
+ ret = gnutls_assert_val(GNUTLS_E_UNEXPECTED_PACKET);
+ goto unexpected_packet;
+ }
+
_gnutls_record_buffer_put(session, type, seq, bufel);
/* if we received application data as expected then we
@@ -919,6 +929,15 @@ record_add_to_buffers(gnutls_session_t session,
goto cleanup;
}
+ /* if the CCS has value other than 1 abort the
+ * connection, unless old DTLS is negotiated, where CCS
+ * includes a sequence number */
+ if (!(ver && ver->id == GNUTLS_DTLS0_9) &&
+ (bufel->msg.size != 1 || bufel->msg.data[0] != 1)) {
+ ret = gnutls_assert_val(GNUTLS_E_UNEXPECTED_PACKET);
+ goto unexpected_packet;
+ }
+
_gnutls_record_buffer_put(session, recv->type, seq,
bufel);
@@ -1351,15 +1370,13 @@ _gnutls_recv_in_buffers(gnutls_session_t session, content_type_t type,
if (bufel == NULL)
return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
- if (vers && vers->tls13_sem && record.type == GNUTLS_CHANGE_CIPHER_SPEC) {
- /* if the CCS has value other than 0x01, or arrives
- * after Finished, abort the connection */
- if (record.length != 1 ||
- *((uint8_t *) _mbuffer_get_udata_ptr(bufel) +
- record.header_size) != 0x01 ||
- !session->internals.handshake_in_progress)
+ /* ignore CCS if TLS 1.3 is negotiated */
+ if (record.type == GNUTLS_CHANGE_CIPHER_SPEC && vers && vers->tls13_sem) {
+ /* if the CCS has arrived after Finished, abort the
+ * connection */
+ if (!session->internals.handshake_in_progress) {
return gnutls_assert_val(GNUTLS_E_UNEXPECTED_PACKET);
-
+ }
_gnutls_read_log("discarding change cipher spec in TLS1.3\n");
/* we use the same mechanism to retry as when
* receiving multiple empty TLS packets */