Clear error queue entries from bad DLTS records
authorBenjamin Kaduk <bkaduk@akamai.com>
Mon, 26 Oct 2020 19:30:16 +0000 (12:30 -0700)
committerBenjamin Kaduk <bkaduk@akamai.com>
Mon, 2 Nov 2020 19:28:24 +0000 (11:28 -0800)
DTLS by design ignores records/packets with bad MAC or failed AEAD tag
validation.  However, recent changes to have provided cipher
implementations caused tls1_enc() to leave an entry on the error queue
for invalid GCM tags, e.g.:

800BEAEF487F0000:error::Provider routines:gcm_stream_update:cipher operation failed:providers/implementations/ciphers/ciphercommon_gcm.c:306

The BoringSSL tests check for entries on the error queue with
SSL_get_error() and so we were seeing spurious test failures
due to the additional item on the error queue.  To avoid leaving
such spurious entries on the error queue, set a mark before calling
the ssl3_enc 'enc' method, and pop to that mark before ignoring
invalid packets.

Reviewed-by: Tomas Mraz <tmraz@fedoraproject.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/13251)

ssl/record/ssl3_record.c

index 046d6f2054e5a0e429e6ef7238a5448ad53048bd..52a8986aca183b334b50db391623c8ba6b0e7731 100644 (file)
@@ -1615,6 +1615,12 @@ int dtls1_process_record(SSL *s, DTLS1_BITMAP *bitmap)
         mac_size = 0;
     }
 
+    /*
+     * Set a mark around the packet decryption attempt.  This is DTLS, so
+     * bad packets are just ignored, and we don't want to leave stray
+     * errors in the queue from processing bogus junk that we ignored.
+     */
+    ERR_set_mark();
     enc_err = s->method->ssl3_enc->enc(s, rr, 1, 0, &macbuf, mac_size);
 
     /*-
@@ -1624,6 +1630,7 @@ int dtls1_process_record(SSL *s, DTLS1_BITMAP *bitmap)
      *    1: Success or MTE decryption failed (MAC will be randomised)
      */
     if (enc_err == 0) {
+        ERR_pop_to_mark();
         if (ossl_statem_in_error(s)) {
             /* SSLfatal() got called */
             goto end;
@@ -1633,6 +1640,7 @@ int dtls1_process_record(SSL *s, DTLS1_BITMAP *bitmap)
         RECORD_LAYER_reset_packet_length(&s->rlayer);
         goto end;
     }
+    ERR_clear_last_mark();
     OSSL_TRACE_BEGIN(TLS) {
         BIO_printf(trc_out, "dec %zd\n", rr->length);
         BIO_dump_indent(trc_out, rr->data, rr->length, 4);