8245417: Improve certificate chain handling

Co-authored-by: Hai-may Chao <hai-may.chao@oracle.com>
Reviewed-by: mullan, jnimeh
This commit is contained in:
Jamil Nimeh 2020-07-20 10:35:34 -07:00 committed by Henry Jen
parent 24f7f84594
commit d6cef99050
6 changed files with 66 additions and 10 deletions

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -137,6 +137,15 @@ final class CertificateMessage {
byte[] encodedCert = Record.getBytes24(m); byte[] encodedCert = Record.getBytes24(m);
listLen -= (3 + encodedCert.length); listLen -= (3 + encodedCert.length);
encodedCerts.add(encodedCert); encodedCerts.add(encodedCert);
if (encodedCerts.size() > SSLConfiguration.maxCertificateChainLength) {
throw new SSLProtocolException(
"The certificate chain length ("
+ encodedCerts.size()
+ ") exceeds the maximum allowed length ("
+ SSLConfiguration.maxCertificateChainLength
+ ")");
}
} }
this.encodedCertChain = encodedCerts; this.encodedCertChain = encodedCerts;
} else { } else {
@ -859,6 +868,14 @@ final class CertificateMessage {
SSLExtensions extensions = SSLExtensions extensions =
new SSLExtensions(this, m, enabledExtensions); new SSLExtensions(this, m, enabledExtensions);
certList.add(new CertificateEntry(encodedCert, extensions)); certList.add(new CertificateEntry(encodedCert, extensions));
if (certList.size() > SSLConfiguration.maxCertificateChainLength) {
throw new SSLProtocolException(
"The certificate chain length ("
+ certList.size()
+ ") exceeds the maximum allowed length ("
+ SSLConfiguration.maxCertificateChainLength
+ ")");
}
} }
this.certEntries = Collections.unmodifiableList(certList); this.certEntries = Collections.unmodifiableList(certList);

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -37,6 +37,7 @@ import java.util.Set;
import java.util.TreeSet; import java.util.TreeSet;
import javax.crypto.BadPaddingException; import javax.crypto.BadPaddingException;
import javax.net.ssl.SSLException; import javax.net.ssl.SSLException;
import javax.net.ssl.SSLProtocolException;
import sun.security.ssl.SSLCipher.SSLReadCipher; import sun.security.ssl.SSLCipher.SSLReadCipher;
/** /**
@ -91,7 +92,7 @@ final class DTLSInputRecord extends InputRecord implements DTLSRecord {
} }
@Override @Override
Plaintext acquirePlaintext() { Plaintext acquirePlaintext() throws SSLProtocolException {
if (reassembler != null) { if (reassembler != null) {
return reassembler.acquirePlaintext(); return reassembler.acquirePlaintext();
} }
@ -114,7 +115,7 @@ final class DTLSInputRecord extends InputRecord implements DTLSRecord {
} }
} }
Plaintext[] decode(ByteBuffer packet) { Plaintext[] decode(ByteBuffer packet) throws SSLProtocolException {
if (isClosed) { if (isClosed) {
return null; return null;
} }
@ -346,7 +347,7 @@ final class DTLSInputRecord extends InputRecord implements DTLSRecord {
private static HandshakeFragment parseHandshakeMessage( private static HandshakeFragment parseHandshakeMessage(
byte contentType, byte majorVersion, byte minorVersion, byte contentType, byte majorVersion, byte minorVersion,
byte[] recordEnS, int recordEpoch, long recordSeq, byte[] recordEnS, int recordEpoch, long recordSeq,
ByteBuffer plaintextFragment) { ByteBuffer plaintextFragment) throws SSLProtocolException {
int remaining = plaintextFragment.remaining(); int remaining = plaintextFragment.remaining();
if (remaining < handshakeHeaderSize) { if (remaining < handshakeHeaderSize) {
@ -376,6 +377,16 @@ final class DTLSInputRecord extends InputRecord implements DTLSRecord {
((plaintextFragment.get() & 0xFF) << 16) | ((plaintextFragment.get() & 0xFF) << 16) |
((plaintextFragment.get() & 0xFF) << 8) | ((plaintextFragment.get() & 0xFF) << 8) |
(plaintextFragment.get() & 0xFF); // pos: 1-3 (plaintextFragment.get() & 0xFF); // pos: 1-3
if (messageLength > SSLConfiguration.maxHandshakeMessageSize) {
throw new SSLProtocolException(
"The size of the handshake message ("
+ messageLength
+ ") exceeds the maximum allowed size ("
+ SSLConfiguration.maxHandshakeMessageSize
+ ")");
}
int messageSeq = int messageSeq =
((plaintextFragment.get() & 0xFF) << 8) | ((plaintextFragment.get() & 0xFF) << 8) |
(plaintextFragment.get() & 0xFF); // pos: 4/5 (plaintextFragment.get() & 0xFF); // pos: 4/5
@ -968,7 +979,7 @@ final class DTLSInputRecord extends InputRecord implements DTLSRecord {
(needToCheckFlight && !flightIsReady())); (needToCheckFlight && !flightIsReady()));
} }
Plaintext acquirePlaintext() { Plaintext acquirePlaintext() throws SSLProtocolException {
if (bufferedFragments.isEmpty()) { if (bufferedFragments.isEmpty()) {
if (SSLLogger.isOn && SSLLogger.isOn("verbose")) { if (SSLLogger.isOn && SSLLogger.isOn("verbose")) {
SSLLogger.fine("No received handshake messages"); SSLLogger.fine("No received handshake messages");
@ -1080,7 +1091,7 @@ final class DTLSInputRecord extends InputRecord implements DTLSRecord {
needToCheckFlight = false; needToCheckFlight = false;
} }
private Plaintext acquireCachedMessage() { private Plaintext acquireCachedMessage() throws SSLProtocolException {
RecordFragment rFrag = bufferedFragments.first(); RecordFragment rFrag = bufferedFragments.first();
if (readEpoch != rFrag.recordEpoch) { if (readEpoch != rFrag.recordEpoch) {
if (readEpoch > rFrag.recordEpoch) { if (readEpoch > rFrag.recordEpoch) {

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -43,6 +43,7 @@ import javax.net.ssl.SNIServerName;
import javax.net.ssl.SSLEngine; import javax.net.ssl.SSLEngine;
import javax.net.ssl.SSLParameters; import javax.net.ssl.SSLParameters;
import javax.net.ssl.SSLSocket; import javax.net.ssl.SSLSocket;
import sun.security.action.GetIntegerAction;
import sun.security.action.GetPropertyAction; import sun.security.action.GetPropertyAction;
import sun.security.ssl.SSLExtension.ClientExtensions; import sun.security.ssl.SSLExtension.ClientExtensions;
import sun.security.ssl.SSLExtension.ServerExtensions; import sun.security.ssl.SSLExtension.ServerExtensions;
@ -104,6 +105,14 @@ final class SSLConfiguration implements Cloneable {
static final boolean acknowledgeCloseNotify = Utilities.getBooleanProperty( static final boolean acknowledgeCloseNotify = Utilities.getBooleanProperty(
"jdk.tls.acknowledgeCloseNotify", false); "jdk.tls.acknowledgeCloseNotify", false);
// Set the max size limit for Handshake Message to 2^15
static final int maxHandshakeMessageSize = GetIntegerAction.privilegedGetProperty(
"jdk.tls.maxHandshakeMessageSize", 32768);
// Set the max certificate chain length to 10
static final int maxCertificateChainLength = GetIntegerAction.privilegedGetProperty(
"jdk.tls.maxCertificateChainLength", 10);
// Is the extended_master_secret extension supported? // Is the extended_master_secret extension supported?
static { static {
boolean supportExtendedMasterSecret = Utilities.getBooleanProperty( boolean supportExtendedMasterSecret = Utilities.getBooleanProperty(

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1996, 2019, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1996, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -297,6 +297,15 @@ final class SSLEngineInputRecord extends InputRecord implements SSLRecord {
} }
int handshakeBodyLen = Record.getInt24(handshakeFrag); int handshakeBodyLen = Record.getInt24(handshakeFrag);
if (handshakeBodyLen > SSLConfiguration.maxHandshakeMessageSize) {
throw new SSLProtocolException(
"The size of the handshake message ("
+ handshakeBodyLen
+ ") exceeds the maximum allowed size ("
+ SSLConfiguration.maxHandshakeMessageSize
+ ")");
}
handshakeFrag.reset(); handshakeFrag.reset();
int handshakeMessageLen = int handshakeMessageLen =
handshakeHeaderSize + handshakeBodyLen; handshakeHeaderSize + handshakeBodyLen;

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1996, 2019, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1996, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2020, Azul Systems, Inc. All rights reserved. * Copyright (c) 2020, Azul Systems, Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
@ -310,6 +310,15 @@ final class SSLSocketInputRecord extends InputRecord implements SSLRecord {
} }
int handshakeBodyLen = Record.getInt24(handshakeFrag); int handshakeBodyLen = Record.getInt24(handshakeFrag);
if (handshakeBodyLen > SSLConfiguration.maxHandshakeMessageSize) {
throw new SSLProtocolException(
"The size of the handshake message ("
+ handshakeBodyLen
+ ") exceeds the maximum allowed size ("
+ SSLConfiguration.maxHandshakeMessageSize
+ ")");
}
handshakeFrag.reset(); handshakeFrag.reset();
int handshakeMessageLen = int handshakeMessageLen =
handshakeHeaderSize + handshakeBodyLen; handshakeHeaderSize + handshakeBodyLen;

View file

@ -87,6 +87,7 @@ import java.util.concurrent.atomic.AtomicLong;
* @run main/othervm -Dtest.requiresHost=true * @run main/othervm -Dtest.requiresHost=true
* -Djdk.httpclient.HttpClient.log=headers * -Djdk.httpclient.HttpClient.log=headers
* -Djdk.internal.httpclient.debug=true * -Djdk.internal.httpclient.debug=true
* -Djdk.tls.maxHandshakeMessageSize=131072
* LargeHandshakeTest * LargeHandshakeTest
* *
*/ */