Navigation Menu

Skip to content

Commit

Permalink
Add protocol version DTLS 1.2.
Browse files Browse the repository at this point in the history
Reuse that version instance.

Signed-off-by: Achim Kraus <achim.kraus@bosch.io>
  • Loading branch information
Achim Kraus committed Jul 28, 2020
1 parent 48bf746 commit 4cc7eb5
Show file tree
Hide file tree
Showing 19 changed files with 94 additions and 42 deletions.
Expand Up @@ -2076,7 +2076,7 @@ private void sendHelloVerify(ClientHello clientHello, Record record, byte[] expe
if (expectedCookie == null) {
expectedCookie = cookieGenerator.generateCookie(clientHello);
}
HelloVerifyRequest msg = new HelloVerifyRequest(new ProtocolVersion(), expectedCookie, record.getPeerAddress());
HelloVerifyRequest msg = new HelloVerifyRequest(ProtocolVersion.VERSION_DTLS_1_2, expectedCookie, record.getPeerAddress());
// because we do not have a handshaker in place yet that
// manages message_seq numbers, we need to set it explicitly
// use message_seq from CLIENT_HELLO in order to allow for
Expand Down
Expand Up @@ -94,7 +94,7 @@ public class ClientHandshaker extends Handshaker {

// Members ////////////////////////////////////////////////////////

private ProtocolVersion maxProtocolVersion = new ProtocolVersion();
private ProtocolVersion maxProtocolVersion = ProtocolVersion.VERSION_DTLS_1_2;

/**
* Indicates probing for this handshake.
Expand Down
Expand Up @@ -69,7 +69,7 @@ public final class ClientHello extends HandshakeMessage {
* The version of the DTLS protocol by which the client wishes to
* communicate during this session.
*/
private ProtocolVersion clientVersion = new ProtocolVersion();
private ProtocolVersion clientVersion;

/** A client-generated random structure. */
private Random random;
Expand Down Expand Up @@ -307,7 +307,7 @@ public static ClientHello fromReader(DatagramReader reader, InetSocketAddress pe

int major = reader.read(VERSION_BITS);
int minor = reader.read(VERSION_BITS);
result.clientVersion = new ProtocolVersion(major, minor);
result.clientVersion = ProtocolVersion.valueOf(major, minor);

result.random = new Random(reader.readBytes(RANDOM_BYTES));

Expand Down
Expand Up @@ -1176,7 +1176,7 @@ else if (sessionIdentifier.isEmpty()) {
return null;
}
return new SessionTicket(
new ProtocolVersion(),
ProtocolVersion.VERSION_DTLS_1_2,
writeState.getCipherSuite(),
writeState.getCompressionMethod(),
masterSecret,
Expand Down
Expand Up @@ -76,7 +76,7 @@ public static HandshakeMessage fromReader(DatagramReader reader, InetSocketAddre

int major = reader.read(VERSION_BITS);
int minor = reader.read(VERSION_BITS);
ProtocolVersion version = new ProtocolVersion(major, minor);
ProtocolVersion version = ProtocolVersion.valueOf(major, minor);

int cookieLength = reader.read(COOKIE_LENGTH_BITS);
byte[] cookie = reader.readBytes(cookieLength);
Expand Down
Expand Up @@ -20,38 +20,65 @@
/**
* Represents the DTLS protocol version.
*
* Note that the major and minor version numbers are represented
* as the 1's complement of the corresponding DTLS version numbers,
* e.g. DTLS version 1.2 is represented as bytes {254, 253}.
* Note that the major and minor version numbers are represented as the 1's
* complement of the corresponding DTLS version numbers, e.g. DTLS version 1.2
* is represented as bytes {254, 253}.
*
* See <a href="http://tools.ietf.org/html/rfc6347#section-4.1">
* Datagram Transport Layer Security Version 1.2 (RFC 6347), Section 4.1</a>
* for details.
* See <a href="http://tools.ietf.org/html/rfc6347#section-4.1"> Datagram
* Transport Layer Security Version 1.2 (RFC 6347), Section 4.1</a> for details.
*/
public class ProtocolVersion implements Comparable<ProtocolVersion> {

/**
* Major version for DTLS 1.2.
*
* @since 2.4
*/
public static final int MAJOR_1_2 = 254;

/**
* Minor version for DTLS 1.2.
*
* @since 2.4
*/
public static final int MINOR_1_2 = 253;

/**
* Protocol version DTLS 1.2
*
* @since 2.4
*/
public static final ProtocolVersion VERSION_DTLS_1_2 = new ProtocolVersion(MAJOR_1_2, MINOR_1_2);

/** The minor. */
private int minor;
private final int minor;

/** The major. */
private int major;
private final int major;

/**
* Creates an instance representing DTLS version 1.2.
*
* The version is represented as {254, 253} (1's complement of {1, 2}).
*
* @deprecated use {@link #VERSION_DTLS_1_2} or {@link #valueOf(int, int)}
* instead.
*/
@Deprecated
public ProtocolVersion() {
this.major = 254;
this.minor = 253;
this.major = MAJOR_1_2;
this.minor = MINOR_1_2;
}

/**
* Instantiates a new protocol version.
*
* @param major the major
* @param minor the minor
* @deprecated intended to became private. Use {@link #valueOf(int, int)}
* instead.
*/
@Deprecated
public ProtocolVersion(int major, int minor) {
this.minor = minor;
this.major = major;
Expand All @@ -69,21 +96,27 @@ public int getMajor() {
* Compares this protocol version to another one.
*
* Note that the comparison is done based on the <em>semantic</em> version,
* i.e. DTLS protocol version 1.0 (represented as major 254, minor 255) is considered
* <em>lower</em> than 1.2 (represented as major 254, minor 253) whereas the
* byte values representing version 1.0 are actually larger.
* i.e. DTLS protocol version 1.0 (represented as major 254, minor 255) is
* considered <em>lower</em> than 1.2 (represented as major 254, minor 253)
* whereas the byte values representing version 1.0 are actually larger.
*
* @param o the protocol version to compare to
* @return <em>0</em> if this version is exactly the same as the other version,
* <em>-1</em> if this version is lower than the other version or
* <em>1</em> if this version is higher than the other version
* @return <em>0</em> if this version is exactly the same as the other
* version, <em>-1</em> if this version is lower than the other
* version or <em>1</em> if this version is higher than the other
* version
*/
@Override
public int compareTo(ProtocolVersion o) {

if (this == o) {
return 0;
}

/*
* Example, version 1.0 (254,255) is smaller than version 1.2 (254,253)
*/

if (major == o.getMajor()) {
if (minor < o.getMinor()) {
return 1;
Expand Down Expand Up @@ -121,4 +154,24 @@ public boolean equals(Object obj) {
return major == other.major && minor == other.minor;
}
}

@Override
public String toString() {
return Integer.toString(255 - major) + "." + Integer.toString(255 - minor);
}

/**
* Get protocol version value of the provided versions.
*
* @param major major version
* @param minor minor version
* @return protocol version
*/
public static ProtocolVersion valueOf(int major, int minor) {
if (major == MAJOR_1_2 && minor == MINOR_1_2) {
return VERSION_DTLS_1_2;
} else {
return new ProtocolVersion(major, minor);
}
}
}
Expand Up @@ -204,7 +204,7 @@ public class Record {
*/
public Record(ContentType type, int epoch, long sequenceNumber, DTLSMessage fragment, DTLSSession session,
boolean cid, int pad) throws GeneralSecurityException {
this(new ProtocolVersion(), epoch, sequenceNumber, 0, session != null ? session.getPeer() : null, false);
this(ProtocolVersion.VERSION_DTLS_1_2, epoch, sequenceNumber, 0, session != null ? session.getPeer() : null, false);
if (fragment == null) {
throw new NullPointerException("Fragment must not be null");
} else if (session == null) {
Expand Down Expand Up @@ -241,7 +241,7 @@ public Record(ContentType type, int epoch, long sequenceNumber, DTLSMessage frag
* is {@code null}.
*/
public Record(ContentType type, long sequenceNumber, DTLSMessage fragment, InetSocketAddress peerAddress) {
this(new ProtocolVersion(), 0, sequenceNumber, 0, peerAddress, false);
this(ProtocolVersion.VERSION_DTLS_1_2, 0, sequenceNumber, 0, peerAddress, false);
if (fragment == null) {
throw new NullPointerException("Fragment must not be null");
} else if (peerAddress == null) {
Expand Down Expand Up @@ -371,7 +371,7 @@ public static List<Record> fromReader(DatagramReader reader, InetSocketAddress p
int type = reader.read(CONTENT_TYPE_BITS);
int major = reader.read(VERSION_BITS);
int minor = reader.read(VERSION_BITS);
ProtocolVersion version = new ProtocolVersion(major, minor);
ProtocolVersion version = ProtocolVersion.valueOf(major, minor);

int epoch = reader.read(EPOCH_BITS);
long sequenceNumber = reader.readLong(SEQUENCE_NUMBER_BITS);
Expand Down
Expand Up @@ -254,7 +254,7 @@ private void receivedServerFinished(Finished message) throws HandshakeException
@Override
public void startHandshake() throws HandshakeException {
handshakeStarted();
ClientHello message = new ClientHello(new ProtocolVersion(), session, supportedSignatureAlgorithms,
ClientHello message = new ClientHello(ProtocolVersion.VERSION_DTLS_1_2, session, supportedSignatureAlgorithms,
supportedClientCertificateTypes, supportedServerCertificateTypes, supportedGroups);

clientRandom = message.getRandom();
Expand Down
Expand Up @@ -702,9 +702,8 @@ public void startHandshake() throws HandshakeException {
* if the client's version is smaller than DTLS 1.2
*/
private ProtocolVersion negotiateProtocolVersion(ProtocolVersion clientVersion) throws HandshakeException {
ProtocolVersion version = new ProtocolVersion();
if (clientVersion.compareTo(version) >= 0) {
return new ProtocolVersion();
if (clientVersion.compareTo(ProtocolVersion.VERSION_DTLS_1_2) >= 0) {
return ProtocolVersion.VERSION_DTLS_1_2;
} else {
AlertMessage alert = new AlertMessage(AlertLevel.FATAL, AlertDescription.PROTOCOL_VERSION, session.getPeer());
throw new HandshakeException("The server only supports DTLS v1.2", alert);
Expand Down
Expand Up @@ -180,7 +180,7 @@ public static HandshakeMessage fromReader(DatagramReader reader, InetSocketAddre

int major = reader.read(VERSION_BITS);
int minor = reader.read(VERSION_BITS);
ProtocolVersion version = new ProtocolVersion(major, minor);
ProtocolVersion version = ProtocolVersion.valueOf(major, minor);

Random random = new Random(reader.readBytes(RANDOM_BYTES));

Expand Down
Expand Up @@ -180,7 +180,7 @@ public static SessionTicket decode(final DatagramReader source) {
// protocol_version
int major = source.read(8);
int minor = source.read(8);
ProtocolVersion ver = new ProtocolVersion(major, minor);
ProtocolVersion ver = ProtocolVersion.valueOf(major, minor);

// cipher_suite
CipherSuite cipherSuite = CipherSuite.getTypeByCode(source.read(CipherSuite.CIPHER_SUITE_BITS));
Expand Down
Expand Up @@ -1017,7 +1017,7 @@ private ClientHello createClientHello(CipherSuite... cipherSuites) {
if (cipherSuites != null && cipherSuites.length > 0) {
list = Arrays.asList(cipherSuites);
}
ClientHello hello = new ClientHello(new ProtocolVersion(), list, clientConfig.getSupportedSignatureAlgorithms(),
ClientHello hello = new ClientHello(ProtocolVersion.VERSION_DTLS_1_2, list, clientConfig.getSupportedSignatureAlgorithms(),
clientConfig.getIdentityCertificateTypes(), clientConfig.getTrustCertificateTypes(),
clientConfig.getSupportedGroups(), clientEndpoint);
hello.addCompressionMethod(CompressionMethod.NULL);
Expand Down
Expand Up @@ -106,7 +106,7 @@ Collections.<CertificateType> emptyList(),
}

private void givenAClientHelloWithEmptyExtensions() {
clientHello = new ClientHello(new ProtocolVersion(), Collections.<CipherSuite> emptyList(),
clientHello = new ClientHello(ProtocolVersion.VERSION_DTLS_1_2, Collections.<CipherSuite> emptyList(),
SignatureAndHashAlgorithm.DEFAULT, null, null,
Collections.<SupportedGroup> emptyList(), peerAddress);
}
Expand All @@ -125,7 +125,7 @@ public static ClientHello createClientHello(InetSocketAddress address, List<Ciph
List<CertificateType> supportedClientCertTypes, List<CertificateType> supportedServerCertTypes,
List<SupportedGroup> supportedGroups) {

return new ClientHello(new ProtocolVersion(), supportedCipherSuites, supportedSignatureAndHashAlgorithms,
return new ClientHello(ProtocolVersion.VERSION_DTLS_1_2, supportedCipherSuites, supportedSignatureAndHashAlgorithms,
supportedClientCertTypes, supportedServerCertTypes, supportedGroups, address);
}

Expand Down
Expand Up @@ -47,7 +47,7 @@ public static Record getRecordForMessage(int epoch, int seqNo, DTLSMessage msg,

public static final byte[] newDTLSRecord(int typeCode, int epoch, long sequenceNo, byte[] fragment) {

ProtocolVersion protocolVer = new ProtocolVersion();
ProtocolVersion protocolVer = ProtocolVersion.VERSION_DTLS_1_2;
// the record header contains a type code, version, epoch, sequenceNo, length
DatagramWriter writer = new DatagramWriter();
writer.write(typeCode, 8);
Expand Down
Expand Up @@ -429,7 +429,7 @@ private void assertThatCertificateValidationFailsForEmptyTrustAnchor() {
}

private static Record createClientHelloRecord(DTLSSession session, int epoch, long sequenceNo, int messageSeqNo) throws GeneralSecurityException {
ClientHello clientHello = new ClientHello(new ProtocolVersion(), session, Collections.<SignatureAndHashAlgorithm> emptyList(), null, null, SupportedGroup.getPreferredGroups());
ClientHello clientHello = new ClientHello(ProtocolVersion.VERSION_DTLS_1_2, session, Collections.<SignatureAndHashAlgorithm> emptyList(), null, null, SupportedGroup.getPreferredGroups());
clientHello.setMessageSeq(messageSeqNo);
return getRecordForMessage(epoch, sequenceNo, clientHello);
}
Expand Down
Expand Up @@ -63,7 +63,7 @@ public class RecordTest {
@Before
public void setUp() throws Exception {

protocolVer = new ProtocolVersion();
protocolVer = ProtocolVersion.VERSION_DTLS_1_2;
key = new SecretKeySpec(aesKey, "AES");
payloadData = new byte[payloadLength];
for ( int i = 0; i < payloadLength; i++) {
Expand Down
Expand Up @@ -70,12 +70,12 @@ private void givenAServerHelloWith(CertificateType serverType, CertificateType c
if (clientType != null) {
ext.addExtension(new ClientCertificateTypeExtension(clientType));
}
serverHello = new ServerHello(new ProtocolVersion(), new Random(), new SessionId(),
serverHello = new ServerHello(ProtocolVersion.VERSION_DTLS_1_2, new Random(), new SessionId(),
CipherSuite.TLS_PSK_WITH_AES_128_CCM_8, CompressionMethod.NULL, ext, peerAddress);
}

private void givenAServerHelloWithEmptyExtensions() {
serverHello = new ServerHello(new ProtocolVersion(), new Random(), new SessionId(),
serverHello = new ServerHello(ProtocolVersion.VERSION_DTLS_1_2, new Random(), new SessionId(),
CipherSuite.TLS_PSK_WITH_AES_128_CCM_8, CompressionMethod.NULL, new HelloExtensions(), peerAddress);
}
}
Expand Up @@ -96,7 +96,7 @@ public CCMBlockCipherTest(int payloadLength, int aLength, int nonceLength) {
public void setUp() throws Exception {
// salt: 32bit client write init vector (can be any four bytes)
byte[] client_iv = new byte[]{0x55, 0x23, 0x2F, (byte) 0xA3};
ProtocolVersion protocolVer = new ProtocolVersion();
ProtocolVersion protocolVer = ProtocolVersion.VERSION_DTLS_1_2;
payloadData = new byte[payloadLength];
random = new Random(payloadLength);
random.nextBytes(payloadData);
Expand Down
Expand Up @@ -98,7 +98,7 @@ public CbcBlockCipherTest(int payloadLength, int aLength) {
@Before
public void setUp() throws Exception {
// salt: 32bit client write init vector (can be any four bytes)
ProtocolVersion protocolVer = new ProtocolVersion();
ProtocolVersion protocolVer = ProtocolVersion.VERSION_DTLS_1_2;
payloadData = Bytes.createBytes(random, payloadLength);

// 64bit sequence number, consisting of 16bit epoch (0) + 48bit sequence number (5)
Expand Down

0 comments on commit 4cc7eb5

Please sign in to comment.