mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-28 15:24:43 +02:00
8218863: Better endpoint checks
Reviewed-by: ahgross, jnimeh, mullan, rhalade
This commit is contained in:
parent
44b9ab02fe
commit
e06d193456
2 changed files with 62 additions and 66 deletions
|
@ -1480,8 +1480,9 @@ final class AbstractTrustManagerWrapper extends X509ExtendedTrustManager
|
||||||
checkAdditionalTrust(chain, authType, engine, false);
|
checkAdditionalTrust(chain, authType, engine, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkAdditionalTrust(X509Certificate[] chain, String authType,
|
private void checkAdditionalTrust(X509Certificate[] chain,
|
||||||
Socket socket, boolean isClient) throws CertificateException {
|
String authType, Socket socket,
|
||||||
|
boolean checkClientTrusted) throws CertificateException {
|
||||||
if (socket != null && socket.isConnected() &&
|
if (socket != null && socket.isConnected() &&
|
||||||
socket instanceof SSLSocket) {
|
socket instanceof SSLSocket) {
|
||||||
|
|
||||||
|
@ -1495,9 +1496,8 @@ final class AbstractTrustManagerWrapper extends X509ExtendedTrustManager
|
||||||
String identityAlg = sslSocket.getSSLParameters().
|
String identityAlg = sslSocket.getSSLParameters().
|
||||||
getEndpointIdentificationAlgorithm();
|
getEndpointIdentificationAlgorithm();
|
||||||
if (identityAlg != null && !identityAlg.isEmpty()) {
|
if (identityAlg != null && !identityAlg.isEmpty()) {
|
||||||
String hostname = session.getPeerHost();
|
X509TrustManagerImpl.checkIdentity(session, chain,
|
||||||
X509TrustManagerImpl.checkIdentity(
|
identityAlg, checkClientTrusted);
|
||||||
hostname, chain[0], identityAlg);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// try the best to check the algorithm constraints
|
// try the best to check the algorithm constraints
|
||||||
|
@ -1519,12 +1519,13 @@ final class AbstractTrustManagerWrapper extends X509ExtendedTrustManager
|
||||||
constraints = new SSLAlgorithmConstraints(sslSocket, true);
|
constraints = new SSLAlgorithmConstraints(sslSocket, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
checkAlgorithmConstraints(chain, constraints, isClient);
|
checkAlgorithmConstraints(chain, constraints, checkClientTrusted);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkAdditionalTrust(X509Certificate[] chain, String authType,
|
private void checkAdditionalTrust(X509Certificate[] chain,
|
||||||
SSLEngine engine, boolean isClient) throws CertificateException {
|
String authType, SSLEngine engine,
|
||||||
|
boolean checkClientTrusted) throws CertificateException {
|
||||||
if (engine != null) {
|
if (engine != null) {
|
||||||
SSLSession session = engine.getHandshakeSession();
|
SSLSession session = engine.getHandshakeSession();
|
||||||
if (session == null) {
|
if (session == null) {
|
||||||
|
@ -1535,9 +1536,8 @@ final class AbstractTrustManagerWrapper extends X509ExtendedTrustManager
|
||||||
String identityAlg = engine.getSSLParameters().
|
String identityAlg = engine.getSSLParameters().
|
||||||
getEndpointIdentificationAlgorithm();
|
getEndpointIdentificationAlgorithm();
|
||||||
if (identityAlg != null && !identityAlg.isEmpty()) {
|
if (identityAlg != null && !identityAlg.isEmpty()) {
|
||||||
String hostname = session.getPeerHost();
|
X509TrustManagerImpl.checkIdentity(session, chain,
|
||||||
X509TrustManagerImpl.checkIdentity(
|
identityAlg, checkClientTrusted);
|
||||||
hostname, chain[0], identityAlg);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// try the best to check the algorithm constraints
|
// try the best to check the algorithm constraints
|
||||||
|
@ -1559,13 +1559,13 @@ final class AbstractTrustManagerWrapper extends X509ExtendedTrustManager
|
||||||
constraints = new SSLAlgorithmConstraints(engine, true);
|
constraints = new SSLAlgorithmConstraints(engine, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
checkAlgorithmConstraints(chain, constraints, isClient);
|
checkAlgorithmConstraints(chain, constraints, checkClientTrusted);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkAlgorithmConstraints(X509Certificate[] chain,
|
private void checkAlgorithmConstraints(X509Certificate[] chain,
|
||||||
AlgorithmConstraints constraints,
|
AlgorithmConstraints constraints,
|
||||||
boolean isClient) throws CertificateException {
|
boolean checkClientTrusted) throws CertificateException {
|
||||||
try {
|
try {
|
||||||
// Does the certificate chain end with a trusted certificate?
|
// Does the certificate chain end with a trusted certificate?
|
||||||
int checkedLength = chain.length - 1;
|
int checkedLength = chain.length - 1;
|
||||||
|
@ -1584,7 +1584,7 @@ final class AbstractTrustManagerWrapper extends X509ExtendedTrustManager
|
||||||
if (checkedLength >= 0) {
|
if (checkedLength >= 0) {
|
||||||
AlgorithmChecker checker =
|
AlgorithmChecker checker =
|
||||||
new AlgorithmChecker(constraints, null,
|
new AlgorithmChecker(constraints, null,
|
||||||
(isClient ? Validator.VAR_TLS_CLIENT :
|
(checkClientTrusted ? Validator.VAR_TLS_CLIENT :
|
||||||
Validator.VAR_TLS_SERVER));
|
Validator.VAR_TLS_SERVER));
|
||||||
checker.init(false);
|
checker.init(false);
|
||||||
for (int i = checkedLength; i >= 0; i--) {
|
for (int i = checkedLength; i >= 0; i--) {
|
||||||
|
|
|
@ -145,7 +145,7 @@ final class X509TrustManagerImpl extends X509ExtendedTrustManager
|
||||||
}
|
}
|
||||||
|
|
||||||
private Validator checkTrustedInit(X509Certificate[] chain,
|
private Validator checkTrustedInit(X509Certificate[] chain,
|
||||||
String authType, boolean isClient) {
|
String authType, boolean checkClientTrusted) {
|
||||||
if (chain == null || chain.length == 0) {
|
if (chain == null || chain.length == 0) {
|
||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException(
|
||||||
"null or zero-length certificate chain");
|
"null or zero-length certificate chain");
|
||||||
|
@ -157,7 +157,7 @@ final class X509TrustManagerImpl extends X509ExtendedTrustManager
|
||||||
}
|
}
|
||||||
|
|
||||||
Validator v = null;
|
Validator v = null;
|
||||||
if (isClient) {
|
if (checkClientTrusted) {
|
||||||
v = clientValidator;
|
v = clientValidator;
|
||||||
if (v == null) {
|
if (v == null) {
|
||||||
validatorLock.lock();
|
validatorLock.lock();
|
||||||
|
@ -192,9 +192,10 @@ final class X509TrustManagerImpl extends X509ExtendedTrustManager
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkTrusted(X509Certificate[] chain, String authType,
|
private void checkTrusted(X509Certificate[] chain,
|
||||||
Socket socket, boolean isClient) throws CertificateException {
|
String authType, Socket socket,
|
||||||
Validator v = checkTrustedInit(chain, authType, isClient);
|
boolean checkClientTrusted) throws CertificateException {
|
||||||
|
Validator v = checkTrustedInit(chain, authType, checkClientTrusted);
|
||||||
|
|
||||||
X509Certificate[] trustedChain = null;
|
X509Certificate[] trustedChain = null;
|
||||||
if ((socket != null) && socket.isConnected() &&
|
if ((socket != null) && socket.isConnected() &&
|
||||||
|
@ -223,28 +224,23 @@ final class X509TrustManagerImpl extends X509ExtendedTrustManager
|
||||||
|
|
||||||
// Grab any stapled OCSP responses for use in validation
|
// Grab any stapled OCSP responses for use in validation
|
||||||
List<byte[]> responseList = Collections.emptyList();
|
List<byte[]> responseList = Collections.emptyList();
|
||||||
if (!isClient && isExtSession) {
|
if (!checkClientTrusted && isExtSession) {
|
||||||
responseList =
|
responseList =
|
||||||
((ExtendedSSLSession)session).getStatusResponses();
|
((ExtendedSSLSession)session).getStatusResponses();
|
||||||
}
|
}
|
||||||
trustedChain = v.validate(chain, null, responseList,
|
trustedChain = v.validate(chain, null, responseList,
|
||||||
constraints, isClient ? null : authType);
|
constraints, checkClientTrusted ? null : authType);
|
||||||
|
|
||||||
// check if EE certificate chains to a public root CA (as
|
|
||||||
// pre-installed in cacerts)
|
|
||||||
boolean chainsToPublicCA = AnchorCertificates.contains(
|
|
||||||
trustedChain[trustedChain.length-1]);
|
|
||||||
|
|
||||||
// check endpoint identity
|
// check endpoint identity
|
||||||
String identityAlg = sslSocket.getSSLParameters().
|
String identityAlg = sslSocket.getSSLParameters().
|
||||||
getEndpointIdentificationAlgorithm();
|
getEndpointIdentificationAlgorithm();
|
||||||
if (identityAlg != null && !identityAlg.isEmpty()) {
|
if (identityAlg != null && !identityAlg.isEmpty()) {
|
||||||
checkIdentity(session, trustedChain[0], identityAlg, isClient,
|
checkIdentity(session,
|
||||||
getRequestedServerNames(socket), chainsToPublicCA);
|
trustedChain, identityAlg, checkClientTrusted);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
trustedChain = v.validate(chain, null, Collections.emptyList(),
|
trustedChain = v.validate(chain, null, Collections.emptyList(),
|
||||||
null, isClient ? null : authType);
|
null, checkClientTrusted ? null : authType);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (SSLLogger.isOn && SSLLogger.isOn("ssl,trustmanager")) {
|
if (SSLLogger.isOn && SSLLogger.isOn("ssl,trustmanager")) {
|
||||||
|
@ -253,9 +249,10 @@ final class X509TrustManagerImpl extends X509ExtendedTrustManager
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkTrusted(X509Certificate[] chain, String authType,
|
private void checkTrusted(X509Certificate[] chain,
|
||||||
SSLEngine engine, boolean isClient) throws CertificateException {
|
String authType, SSLEngine engine,
|
||||||
Validator v = checkTrustedInit(chain, authType, isClient);
|
boolean checkClientTrusted) throws CertificateException {
|
||||||
|
Validator v = checkTrustedInit(chain, authType, checkClientTrusted);
|
||||||
|
|
||||||
X509Certificate[] trustedChain = null;
|
X509Certificate[] trustedChain = null;
|
||||||
if (engine != null) {
|
if (engine != null) {
|
||||||
|
@ -281,28 +278,23 @@ final class X509TrustManagerImpl extends X509ExtendedTrustManager
|
||||||
|
|
||||||
// Grab any stapled OCSP responses for use in validation
|
// Grab any stapled OCSP responses for use in validation
|
||||||
List<byte[]> responseList = Collections.emptyList();
|
List<byte[]> responseList = Collections.emptyList();
|
||||||
if (!isClient && isExtSession) {
|
if (!checkClientTrusted && isExtSession) {
|
||||||
responseList =
|
responseList =
|
||||||
((ExtendedSSLSession)session).getStatusResponses();
|
((ExtendedSSLSession)session).getStatusResponses();
|
||||||
}
|
}
|
||||||
trustedChain = v.validate(chain, null, responseList,
|
trustedChain = v.validate(chain, null, responseList,
|
||||||
constraints, isClient ? null : authType);
|
constraints, checkClientTrusted ? null : authType);
|
||||||
|
|
||||||
// check if EE certificate chains to a public root CA (as
|
|
||||||
// pre-installed in cacerts)
|
|
||||||
boolean chainsToPublicCA = AnchorCertificates.contains(
|
|
||||||
trustedChain[trustedChain.length-1]);
|
|
||||||
|
|
||||||
// check endpoint identity
|
// check endpoint identity
|
||||||
String identityAlg = engine.getSSLParameters().
|
String identityAlg = engine.getSSLParameters().
|
||||||
getEndpointIdentificationAlgorithm();
|
getEndpointIdentificationAlgorithm();
|
||||||
if (identityAlg != null && !identityAlg.isEmpty()) {
|
if (identityAlg != null && !identityAlg.isEmpty()) {
|
||||||
checkIdentity(session, trustedChain[0], identityAlg, isClient,
|
checkIdentity(session, trustedChain,
|
||||||
getRequestedServerNames(engine), chainsToPublicCA);
|
identityAlg, checkClientTrusted);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
trustedChain = v.validate(chain, null, Collections.emptyList(),
|
trustedChain = v.validate(chain, null, Collections.emptyList(),
|
||||||
null, isClient ? null : authType);
|
null, checkClientTrusted ? null : authType);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (SSLLogger.isOn && SSLLogger.isOn("ssl,trustmanager")) {
|
if (SSLLogger.isOn && SSLLogger.isOn("ssl,trustmanager")) {
|
||||||
|
@ -360,14 +352,8 @@ final class X509TrustManagerImpl extends X509ExtendedTrustManager
|
||||||
static List<SNIServerName> getRequestedServerNames(Socket socket) {
|
static List<SNIServerName> getRequestedServerNames(Socket socket) {
|
||||||
if (socket != null && socket.isConnected() &&
|
if (socket != null && socket.isConnected() &&
|
||||||
socket instanceof SSLSocket) {
|
socket instanceof SSLSocket) {
|
||||||
|
return getRequestedServerNames(
|
||||||
SSLSocket sslSocket = (SSLSocket)socket;
|
((SSLSocket)socket).getHandshakeSession());
|
||||||
SSLSession session = sslSocket.getHandshakeSession();
|
|
||||||
|
|
||||||
if (session != null && (session instanceof ExtendedSSLSession)) {
|
|
||||||
ExtendedSSLSession extSession = (ExtendedSSLSession)session;
|
|
||||||
return extSession.getRequestedServerNames();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return Collections.<SNIServerName>emptyList();
|
return Collections.<SNIServerName>emptyList();
|
||||||
|
@ -376,12 +362,16 @@ final class X509TrustManagerImpl extends X509ExtendedTrustManager
|
||||||
// Also used by X509KeyManagerImpl
|
// Also used by X509KeyManagerImpl
|
||||||
static List<SNIServerName> getRequestedServerNames(SSLEngine engine) {
|
static List<SNIServerName> getRequestedServerNames(SSLEngine engine) {
|
||||||
if (engine != null) {
|
if (engine != null) {
|
||||||
SSLSession session = engine.getHandshakeSession();
|
return getRequestedServerNames(engine.getHandshakeSession());
|
||||||
|
|
||||||
if (session != null && (session instanceof ExtendedSSLSession)) {
|
|
||||||
ExtendedSSLSession extSession = (ExtendedSSLSession)session;
|
|
||||||
return extSession.getRequestedServerNames();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return Collections.<SNIServerName>emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static List<SNIServerName> getRequestedServerNames(
|
||||||
|
SSLSession session) {
|
||||||
|
if (session != null && (session instanceof ExtendedSSLSession)) {
|
||||||
|
return ((ExtendedSSLSession)session).getRequestedServerNames();
|
||||||
}
|
}
|
||||||
|
|
||||||
return Collections.<SNIServerName>emptyList();
|
return Collections.<SNIServerName>emptyList();
|
||||||
|
@ -402,23 +392,28 @@ final class X509TrustManagerImpl extends X509ExtendedTrustManager
|
||||||
* the identity checking aginst the server_name extension if present, and
|
* the identity checking aginst the server_name extension if present, and
|
||||||
* may failove to peer host checking.
|
* may failove to peer host checking.
|
||||||
*/
|
*/
|
||||||
private static void checkIdentity(SSLSession session,
|
static void checkIdentity(SSLSession session,
|
||||||
X509Certificate cert,
|
X509Certificate[] trustedChain,
|
||||||
String algorithm,
|
String algorithm,
|
||||||
boolean isClient,
|
boolean checkClientTrusted) throws CertificateException {
|
||||||
List<SNIServerName> sniNames,
|
|
||||||
boolean chainsToPublicCA) throws CertificateException {
|
// check if EE certificate chains to a public root CA (as
|
||||||
|
// pre-installed in cacerts)
|
||||||
|
boolean chainsToPublicCA = AnchorCertificates.contains(
|
||||||
|
trustedChain[trustedChain.length - 1]);
|
||||||
|
|
||||||
boolean identifiable = false;
|
boolean identifiable = false;
|
||||||
String peerHost = session.getPeerHost();
|
String peerHost = session.getPeerHost();
|
||||||
if (isClient) {
|
if (!checkClientTrusted) {
|
||||||
String hostname = getHostNameInSNI(sniNames);
|
List<SNIServerName> sniNames = getRequestedServerNames(session);
|
||||||
if (hostname != null) {
|
String sniHostName = getHostNameInSNI(sniNames);
|
||||||
|
if (sniHostName != null) {
|
||||||
try {
|
try {
|
||||||
checkIdentity(hostname, cert, algorithm, chainsToPublicCA);
|
checkIdentity(sniHostName,
|
||||||
|
trustedChain[0], algorithm, chainsToPublicCA);
|
||||||
identifiable = true;
|
identifiable = true;
|
||||||
} catch (CertificateException ce) {
|
} catch (CertificateException ce) {
|
||||||
if (hostname.equalsIgnoreCase(peerHost)) {
|
if (sniHostName.equalsIgnoreCase(peerHost)) {
|
||||||
throw ce;
|
throw ce;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -428,7 +423,8 @@ final class X509TrustManagerImpl extends X509ExtendedTrustManager
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!identifiable) {
|
if (!identifiable) {
|
||||||
checkIdentity(peerHost, cert, algorithm, chainsToPublicCA);
|
checkIdentity(peerHost,
|
||||||
|
trustedChain[0], algorithm, chainsToPublicCA);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue