Skip to content

Commit 97c5666

Browse files
committed
Refuse to send a DTLS handshake message whose message_seq would wrap the uint16, relates to github #1468.
1 parent 5643cc6 commit 97c5666

4 files changed

Lines changed: 60 additions & 0 deletions

File tree

‎tls/src/main/java/org/bouncycastle/tls/DTLSReliableHandshake.java‎

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,15 @@ void sendMessage(short msg_type, byte[] body)
183183
{
184184
TlsUtils.checkUint24(body.length);
185185

186+
/*
187+
* draft-ietf-tls-rfc9147bis: message_seq is a uint16 and "MUST NOT wrap"; writeUint16 would
188+
* silently truncate and reuse the sequence number of an earlier message.
189+
*/
190+
if (next_send_seq > 0xFFFF)
191+
{
192+
throw new TlsFatalAlert(AlertDescription.internal_error);
193+
}
194+
186195
if (null != resendTimeout)
187196
{
188197
checkInboundFlight();
@@ -781,6 +790,12 @@ void acknowledgeForTest(Vector recordNumbers)
781790
flightTracker.acknowledge(recordNumbers);
782791
}
783792

793+
/** For the reliable-handshake tests: position the send counter, e.g. at the uint16 limit. */
794+
void setNextSendSeqForTest(int nextSendSeq)
795+
{
796+
next_send_seq = nextSendSeq;
797+
}
798+
784799
/** For the reliable-handshake tests: drive the retransmission path directly. */
785800
void resendOutboundFlightForTest() throws IOException
786801
{

‎tls/src/test/java/org/bouncycastle/tls/AllTests.java‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ public static Test suite()
3030
suite.addTestSuite(DTLS13UnifiedHeaderTest.class);
3131
suite.addTestSuite(DTLSAckTest.class);
3232
suite.addTestSuite(DTLSAckTransportTest.class);
33+
suite.addTestSuite(DTLSMessageSeqTest.class);
3334
suite.addTestSuite(DTLSReassemblerTest.class);
3435
suite.addTestSuite(DTLSRecordLayer13Test.class);
3536
suite.addTestSuite(DTLSRecordLayerAggregationTest.class);

‎tls/src/test/java/org/bouncycastle/tls/DTLS13HandshakeTestSupport.java‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -316,6 +316,11 @@ void receiveUntilTimeout() throws IOException
316316
}
317317

318318
/** Send a small message, which opens a new outbound flight (and so a new inbound flight). */
319+
void setNextSendSeq(int nextSendSeq)
320+
{
321+
handshake.setNextSendSeqForTest(nextSendSeq);
322+
}
323+
319324
void sendMessage() throws IOException
320325
{
321326
handshake.sendMessage(HandshakeType.certificate, new byte[8]);
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package org.bouncycastle.tls;
2+
3+
import java.io.IOException;
4+
5+
import junit.framework.TestCase;
6+
7+
/**
8+
* draft-ietf-tls-rfc9147bis: message_seq is a uint16 that MUST NOT wrap. The send side has to refuse the
9+
* 65537th message rather than let writeUint16 truncate it onto the sequence number of an earlier one.
10+
*/
11+
public class DTLSMessageSeqTest
12+
extends TestCase
13+
{
14+
public void testLastMessageSeqIsStillSent() throws IOException
15+
{
16+
DTLS13HandshakeTestSupport support = new DTLS13HandshakeTestSupport();
17+
support.begin(500);
18+
19+
support.setNextSendSeq(0xFFFF);
20+
support.sendMessage();
21+
}
22+
23+
public void testMessageSeqWrapIsRefused() throws IOException
24+
{
25+
DTLS13HandshakeTestSupport support = new DTLS13HandshakeTestSupport();
26+
support.begin(500);
27+
28+
support.setNextSendSeq(0x10000);
29+
try
30+
{
31+
support.sendMessage();
32+
fail("message_seq 65536 must not be sent");
33+
}
34+
catch (TlsFatalAlert e)
35+
{
36+
assertEquals(AlertDescription.internal_error, e.getAlertDescription());
37+
}
38+
}
39+
}

0 commit comments

Comments
 (0)