This patch addresses this issue.
--- ssl/d1_pkt.c 4 Oct 2009 16:52:35 -0000 1.27.2.18
+++ ssl/d1_pkt.c 4 Apr 2010 09:10:09 -0000
@@ -667,14 +667,14 @@
if (rr->length == 0) goto again;
/* If this record is from the next epoch (either HM or ALERT),
- * buffer it since it cannot be processed at this time. Records
- * from the next epoch are marked as received even though they
- * are not processed, so as to prevent any potential resource
- * DoS attack */
+ * and a handshake is currently in progress, buffer it since it
+ * cannot be processed at this time. */
if (is_next_epoch)
{
- dtls1_record_bitmap_update(s, bitmap);
- dtls1_buffer_record(s, &(s->d1->unprocessed_rcds), rr->seq_num);
+ if (SSL_in_init(s) || s->in_handshake)
+ {
+ dtls1_buffer_record(s, &(s->d1->unprocessed_rcds),
rr->seq_num);
+ }
rr->length = 0;
s->packet_length = 0;
goto again;
Regards,
Robin
On Apr 3, 2010, at 2:19 PM, Daniel Mentz via RT wrote:
> d1_pkt.c:dtls1_get_record() processes DTLS records which it gets from
> the wire. At the same time, this function performs replay protection: It
> memorizes the (explicit) sequence numbers of the records and drops
> records that have already been processed.
>
> The sequence numbers of the processed records are saved in a sliding
> bitmap window. The corresponding bit in the window is set to 1, if a
> specific sequence number is processed. The key point is that the MAC of
> the record is usually verified *before* the bitmap of sequence numbers
> is updated. This requires the receiving end to be in possession of the
> symmetric key used for integrity control.
>
> With every renegotiation, the keys are renewed and a new epoch begins.
>
> Due to reordering on the network, it may happen that a record from a
> future epoch arrives during renegotiation. Because the keying material
> is not yet available, the integrity of these records can not be verified.
>
> The aspect I'm complaining about is that OpenSSL updates the record
> bitmap *without* prior verification of the integrity of the record *iff*
> the record is from a future epoch.
>
> Here's the code:
>
> /* If this record is from the next epoch (either HM or ALERT),
> * buffer it since it cannot be processed at this time. Records
> * from the next epoch are marked as received even though they
> * are not processed, so as to prevent any potential resource
> * DoS attack */
> if (is_next_epoch)
> {
> dtls1_record_bitmap_update(s, bitmap);
> dtls1_buffer_record(s, &(s->d1->unprocessed_rcds), rr->seq_num);
> rr->length = 0;
> s->packet_length = 0;
> goto again;
> }
>
> In my opinion, there's no potential for resource DoS attacks because
> dtls1_buffer_record() limits the number of buffered records to 100.
>
> However, as the code stands today, there is a potential for a DoS
> attack. An attacker might guess the source and destination UDP port as
> well as the number of the next epoch. They then send a faked DTLS record
> with a high sequence number, say n. As a result, OpenSSL moves forward
> the bitmap window and will drop any future record carrying a sequence
> number that is smaller than (n-64) i.e. which lies outside the window.
>
> I suggest to improve on that situation by doing the following:
>
> - Do *not* update the record bitmap if the record belongs to the next
> epoch. As a result, two records carrying the same sequence number may be
> buffered at the same time. However, one of these records might be
> invalid or faked.
>
> - Buffer records from the next epoch only if a re-handshake is currently
> in progress.
>
> Does that make sense?
> Please let me know your opinions.
>
> -Daniel
>
> ______________________________________________________________________
> OpenSSL Project http://www.openssl.org
> Development Mailing List [email protected]
> Automated List Manager [email protected]
dtls-replay-bug-1.0.0.patch
Description: Binary data
dtls-replay-bug-0.9.8.patch
Description: Binary data
