DTLS drops the connection with a BAD_RECORD alert whenever validation of the MAC or decryption failed. This is ok with the specification as an optional behavior but is also an easy target for a potential attack to drop the connection. An attacker only has to send random data to cause the decryption to fail and the connection is closed. So DTLS should rather silently discard those messages and continue the connection.
--- ssl/d1_pkt.c 6 Apr 2010 12:44:55 -0000 1.27.2.20 +++ ssl/d1_pkt.c 8 Apr 2010 10:44:09 -0000 @@ -414,7 +425,7 @@ goto err; /* otherwise enc_err == -1 */ - goto decryption_failed_or_bad_record_mac; + goto err; } #ifdef TLS_DEBUG @@ -444,7 +455,7 @@ SSLerr(SSL_F_DTLS1_PROCESS_RECORD,SSL_R_PRE_MAC_LENGTH_TOO_LONG); goto f_err; #else - goto decryption_failed_or_bad_record_mac; + goto err; #endif } /* check the MAC for rr->input (it's in mac_size bytes at the tail) */ @@ -455,14 +466,14 @@ SSLerr(SSL_F_DTLS1_PROCESS_RECORD,SSL_R_LENGTH_TOO_SHORT); goto f_err; #else - goto decryption_failed_or_bad_record_mac; + goto err; #endif } rr->length-=mac_size; i=s->method->ssl3_enc->mac(s,md,0); if (i < 0 || memcmp(md,&(rr->data[rr->length]),mac_size) != 0) { - goto decryption_failed_or_bad_record_mac; + goto err; } } @@ -504,14 +515,6 @@ dtls1_record_bitmap_update(s, &(s->d1->bitmap));/* Mark receipt of record. */ return(1); -decryption_failed_or_bad_record_mac: - /* Separate 'decryption_failed' alert was introduced with TLS 1.0, - * SSL 3.0 only has 'bad_record_mac'. But unless a decryption - * failure is directly visible from the ciphertext anyway, - * we should not reveal which kind of error occured -- this - * might become visible to an attacker (e.g. via logfile) */ - al=SSL_AD_BAD_RECORD_MAC; - SSLerr(SSL_F_DTLS1_PROCESS_RECORD,SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC); f_err: ssl3_send_alert(s,SSL3_AL_FATAL,al); err: @@ -544,8 +547,7 @@ /* The epoch may have changed. If so, process all the * pending records. This is a non-blocking operation. */ - if ( ! dtls1_process_buffered_records(s)) - return 0; + dtls1_process_buffered_records(s); /* if we're renegotiating, then there may be buffered records */ if (dtls1_get_processed_record(s)) @@ -680,8 +690,12 @@ goto again; } - if ( ! dtls1_process_record(s)) - return(0); + if (!dtls1_process_record(s)) + { + rr->length = 0; + s->packet_length = 0; /* dump this record */ + goto again; /* get another record */ + } dtls1_clear_timeouts(s); /* done waiting */ return(1);
dtls-badmsg-alert-bug-0.9.8.patch
Description: Binary data
dtls-badmsg-alert-bug-1.0.0.patch
Description: Binary data