--- a/src/java.base/share/classes/sun/security/ssl/DHKeyExchange.java Fri May 25 14:24:17 2018 -0700
+++ b/src/java.base/share/classes/sun/security/ssl/DHKeyExchange.java Sat May 26 15:15:27 2018 -0700
@@ -221,7 +221,7 @@
if (pSize > 0 && encoded.length < pSize) {
byte[] buffer = new byte[pSize];
System.arraycopy(encoded, 0,
- buffer, pSize - encoded.length, encoded.length);
+ buffer, pSize - encoded.length, encoded.length);
encoded = buffer;
}
--- a/src/java.base/share/classes/sun/security/ssl/RandomCookie.java Fri May 25 14:24:17 2018 -0700
+++ b/src/java.base/share/classes/sun/security/ssl/RandomCookie.java Sat May 26 15:15:27 2018 -0700
@@ -58,7 +58,7 @@
private static final byte[] t11Protection = new byte[] {
(byte)0x44, (byte)0x4F, (byte)0x57, (byte)0x4E,
- (byte)0x47, (byte)0x52, (byte)0x44, (byte)0x01
+ (byte)0x47, (byte)0x52, (byte)0x44, (byte)0x00
};
static final RandomCookie hrrRandom = new RandomCookie(hrrRandomBytes);
@@ -67,6 +67,36 @@
generator.nextBytes(randomBytes);
}
+ // Used for server random generation with version downgrade protection.
+ RandomCookie(HandshakeContext context) {
+ SecureRandom generator = context.sslContext.getSecureRandom();
+ generator.nextBytes(randomBytes);
+
+ // TLS 1.3 has a downgrade protection mechanism embedded in the
+ // server's random value. TLS 1.3 servers which negotiate TLS 1.2
+ // or below in response to a ClientHello MUST set the last eight
+ // bytes of their Random value specially.
+ byte[] protection = null;
+ if (context.maximumActiveProtocol.useTLS13PlusSpec()) {
+ if (!context.negotiatedProtocol.useTLS13PlusSpec()) {
+ if (context.negotiatedProtocol.useTLS12PlusSpec()) {
+ protection = t12Protection;
+ } else {
+ protection = t11Protection;
+ }
+ }
+ } else if (context.maximumActiveProtocol.useTLS12PlusSpec()) {
+ if (!context.negotiatedProtocol.useTLS12PlusSpec()) {
+ protection = t11Protection;
+ }
+ }
+
+ if (protection != null) {
+ System.arraycopy(protection, 0, randomBytes,
+ randomBytes.length - protection.length, protection.length);
+ }
+ }
+
RandomCookie(ByteBuffer m) throws IOException {
m.get(randomBytes);
}
@@ -84,11 +114,26 @@
return Arrays.equals(hrrRandomBytes, randomBytes);
}
- boolean isT12Downgrade() {
- return Arrays.equals(hrrRandomBytes, 24, 31, t12Protection, 0, 7);
+ // Used for client random validation of version downgrade protection.
+ boolean isVersionDowngrade(HandshakeContext context) {
+ if (context.maximumActiveProtocol.useTLS13PlusSpec()) {
+ if (!context.negotiatedProtocol.useTLS13PlusSpec()) {
+ return isT12Downgrade() || isT11Downgrade();
+ }
+ } else if (context.maximumActiveProtocol.useTLS12PlusSpec()) {
+ if (!context.negotiatedProtocol.useTLS12PlusSpec()) {
+ return isT11Downgrade();
+ }
+ }
+
+ return false;
}
- boolean isT11Downgrade() {
- return Arrays.equals(hrrRandomBytes, 24, 31, t11Protection, 0, 7);
+ private boolean isT12Downgrade() {
+ return Arrays.equals(randomBytes, 24, 31, t12Protection, 0, 7);
+ }
+
+ private boolean isT11Downgrade() {
+ return Arrays.equals(randomBytes, 24, 31, t11Protection, 0, 7);
}
}
--- a/src/java.base/share/classes/sun/security/ssl/ServerHello.java Fri May 25 14:24:17 2018 -0700
+++ b/src/java.base/share/classes/sun/security/ssl/ServerHello.java Sat May 26 15:15:27 2018 -0700
@@ -344,12 +344,11 @@
}
// Generate the ServerHello handshake message.
- // TODO: not yet consider downgrade protection.
ServerHelloMessage shm = new ServerHelloMessage(shc,
shc.negotiatedProtocol,
shc.handshakeSession.getSessionId(),
shc.negotiatedCipherSuite,
- new RandomCookie(shc.sslContext.getSecureRandom()),
+ new RandomCookie(shc),
clientHello);
shc.serverHelloRandom = shm.serverRandom;
@@ -557,12 +556,12 @@
shc.handshakeProducers.put(SSLHandshake.FINISHED.id,
SSLHandshake.FINISHED);
- // TODO: not yet consider downgrade protection.
+ // Generate the ServerHello handshake message.
ServerHelloMessage shm = new ServerHelloMessage(shc,
ProtocolVersion.TLS12, // use legacy version
clientHello.sessionId, // echo back
shc.negotiatedCipherSuite,
- new RandomCookie(shc.sslContext.getSecureRandom()),
+ new RandomCookie(shc),
clientHello);
shc.serverHelloRandom = shm.serverRandom;
@@ -959,6 +958,11 @@
"Negotiated protocol version: " + serverVersion.name);
}
+ if (serverHello.serverRandom.isVersionDowngrade(chc)) {
+ chc.conContext.fatal(Alert.ILLEGAL_PARAMETER,
+ "A potential protocol versoin downgrade attack");
+ }
+
// Consume the handshake message for the specific protocol version.
if (serverVersion.isDTLS) {
if (serverVersion.useTLS13PlusSpec()) {