mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-28 15:24:43 +02:00
8206925: Support the certificate_authorities extension
Reviewed-by: mullan
This commit is contained in:
parent
6f5e8a2aa3
commit
17a298962c
8 changed files with 1087 additions and 96 deletions
|
@ -0,0 +1,408 @@
|
|||
/*
|
||||
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package sun.security.ssl;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.*;
|
||||
import javax.net.ssl.SSLProtocolException;
|
||||
import javax.security.auth.x500.X500Principal;
|
||||
import sun.security.ssl.SSLExtension.ExtensionConsumer;
|
||||
import sun.security.ssl.SSLExtension.SSLExtensionSpec;
|
||||
import sun.security.ssl.SSLHandshake.HandshakeMessage;
|
||||
|
||||
/**
|
||||
* Pack of the "certificate_authorities" extensions.
|
||||
*/
|
||||
final class CertificateAuthoritiesExtension {
|
||||
static final HandshakeProducer chNetworkProducer =
|
||||
new CHCertificateAuthoritiesProducer();
|
||||
static final ExtensionConsumer chOnLoadConsumer =
|
||||
new CHCertificateAuthoritiesConsumer();
|
||||
|
||||
static final HandshakeProducer crNetworkProducer =
|
||||
new CRCertificateAuthoritiesProducer();
|
||||
static final ExtensionConsumer crOnLoadConsumer =
|
||||
new CRCertificateAuthoritiesConsumer();
|
||||
|
||||
static final SSLStringizer ssStringizer =
|
||||
new CertificateAuthoritiesStringizer();
|
||||
|
||||
/**
|
||||
* The "certificate_authorities" extension.
|
||||
*/
|
||||
static final class CertificateAuthoritiesSpec implements SSLExtensionSpec {
|
||||
final List<byte[]> authorities; // certificate authorities
|
||||
|
||||
private CertificateAuthoritiesSpec(List<byte[]> authorities) {
|
||||
this.authorities = authorities;
|
||||
}
|
||||
|
||||
private CertificateAuthoritiesSpec(HandshakeContext hc,
|
||||
ByteBuffer m) throws IOException {
|
||||
if (m.remaining() < 3) { // 2: the length of the list
|
||||
// 1: at least one byte authorities
|
||||
throw hc.conContext.fatal(Alert.DECODE_ERROR,
|
||||
new SSLProtocolException(
|
||||
"Invalid certificate_authorities extension: " +
|
||||
"insufficient data"));
|
||||
}
|
||||
|
||||
int listLen = Record.getInt16(m);
|
||||
if (listLen == 0) {
|
||||
throw hc.conContext.fatal(Alert.DECODE_ERROR,
|
||||
"Invalid certificate_authorities extension: " +
|
||||
"no certificate authorities");
|
||||
}
|
||||
|
||||
if (listLen > m.remaining()) {
|
||||
throw hc.conContext.fatal(Alert.DECODE_ERROR,
|
||||
"Invalid certificate_authorities extension: " +
|
||||
"insufficient data");
|
||||
}
|
||||
|
||||
this.authorities = new LinkedList<>();
|
||||
while (listLen > 0) {
|
||||
// opaque DistinguishedName<1..2^16-1>;
|
||||
byte[] encoded = Record.getBytes16(m);
|
||||
listLen -= (2 + encoded.length);
|
||||
authorities.add(encoded);
|
||||
}
|
||||
}
|
||||
|
||||
private static List<byte[]> getEncodedAuthorities(
|
||||
X509Certificate[] trustedCerts) {
|
||||
List<byte[]> authorities = new ArrayList<>(trustedCerts.length);
|
||||
int sizeAccount = 0;
|
||||
for (X509Certificate cert : trustedCerts) {
|
||||
X500Principal x500Principal = cert.getSubjectX500Principal();
|
||||
byte[] encodedPrincipal = x500Principal.getEncoded();
|
||||
sizeAccount += encodedPrincipal.length;
|
||||
if (sizeAccount > 0xFFFF) { // the size limit of this extension
|
||||
// If there too many trusts CAs such that they exceed the
|
||||
// size limit of the extension, enabling this extension
|
||||
// does not really make sense as there is no way to
|
||||
// indicate the peer certificate selection accurately.
|
||||
// In such cases, the extension is just ignored, rather
|
||||
// than fatal close, for better compatibility and
|
||||
// interoperability.
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
if (encodedPrincipal.length != 0) {
|
||||
authorities.add(encodedPrincipal);
|
||||
}
|
||||
}
|
||||
|
||||
return authorities;
|
||||
}
|
||||
|
||||
X500Principal[] getAuthorities() {
|
||||
X500Principal[] principals = new X500Principal[authorities.size()];
|
||||
int i = 0;
|
||||
for (byte[] encoded : authorities) {
|
||||
principals[i++] = new X500Principal(encoded);
|
||||
}
|
||||
|
||||
return principals;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
MessageFormat messageFormat = new MessageFormat(
|
||||
"\"certificate authorities\": '['\n{0}']'", Locale.ENGLISH);
|
||||
StringBuilder builder = new StringBuilder(512);
|
||||
for (byte[] encoded : authorities) {
|
||||
X500Principal principal = new X500Principal(encoded);
|
||||
builder.append(principal.toString());
|
||||
builder.append("\n");
|
||||
}
|
||||
Object[] messageFields = {
|
||||
Utilities.indent(builder.toString())
|
||||
};
|
||||
|
||||
return messageFormat.format(messageFields);
|
||||
}
|
||||
}
|
||||
|
||||
private static final
|
||||
class CertificateAuthoritiesStringizer implements SSLStringizer {
|
||||
@Override
|
||||
public String toString(HandshakeContext hc, ByteBuffer buffer) {
|
||||
try {
|
||||
return (new CertificateAuthoritiesSpec(hc, buffer))
|
||||
.toString();
|
||||
} catch (IOException ioe) {
|
||||
// For debug logging only, so please swallow exceptions.
|
||||
return ioe.getMessage();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Network data producer of a "certificate_authorities" extension in
|
||||
* the ClientHello handshake message.
|
||||
*/
|
||||
private static final
|
||||
class CHCertificateAuthoritiesProducer implements HandshakeProducer {
|
||||
|
||||
// Prevent instantiation of this class.
|
||||
private CHCertificateAuthoritiesProducer() {
|
||||
// blank
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] produce(ConnectionContext context,
|
||||
HandshakeMessage message) throws IOException {
|
||||
// The producing happens in client side only.
|
||||
ClientHandshakeContext chc = (ClientHandshakeContext)context;
|
||||
|
||||
// Is it a supported and enabled extension?
|
||||
if (!chc.sslConfig.isAvailable(
|
||||
SSLExtension.CH_CERTIFICATE_AUTHORITIES)) {
|
||||
if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) {
|
||||
SSLLogger.fine(
|
||||
"Ignore unavailable " +
|
||||
"certificate_authorities extension");
|
||||
}
|
||||
|
||||
return null; // ignore the extension
|
||||
}
|
||||
|
||||
// Produce the extension.
|
||||
X509Certificate[] caCerts =
|
||||
chc.sslContext.getX509TrustManager().getAcceptedIssuers();
|
||||
if (caCerts.length == 0) {
|
||||
if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) {
|
||||
SSLLogger.fine(
|
||||
"No available certificate authorities");
|
||||
}
|
||||
|
||||
return null; // ignore the extension
|
||||
}
|
||||
|
||||
List<byte[]> encodedCAs =
|
||||
CertificateAuthoritiesSpec.getEncodedAuthorities(caCerts);
|
||||
if (encodedCAs.isEmpty()) {
|
||||
if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) {
|
||||
SSLLogger.warning(
|
||||
"The number of CAs exceeds the maximum size" +
|
||||
"of the certificate_authorities extension");
|
||||
}
|
||||
|
||||
return null; // ignore the extension
|
||||
}
|
||||
|
||||
CertificateAuthoritiesSpec spec =
|
||||
new CertificateAuthoritiesSpec(encodedCAs);
|
||||
|
||||
int vectorLen = 0;
|
||||
for (byte[] encoded : spec.authorities) {
|
||||
vectorLen += encoded.length + 2;
|
||||
}
|
||||
|
||||
byte[] extData = new byte[vectorLen + 2];
|
||||
ByteBuffer m = ByteBuffer.wrap(extData);
|
||||
Record.putInt16(m, vectorLen);
|
||||
for (byte[] encoded : spec.authorities) {
|
||||
Record.putBytes16(m, encoded);
|
||||
}
|
||||
|
||||
// Update the context.
|
||||
chc.handshakeExtensions.put(
|
||||
SSLExtension.CH_CERTIFICATE_AUTHORITIES, spec);
|
||||
|
||||
return extData;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Network data consumer of a "certificate_authorities" extension in
|
||||
* the ClientHello handshake message.
|
||||
*/
|
||||
private static final
|
||||
class CHCertificateAuthoritiesConsumer implements ExtensionConsumer {
|
||||
|
||||
// Prevent instantiation of this class.
|
||||
private CHCertificateAuthoritiesConsumer() {
|
||||
// blank
|
||||
}
|
||||
|
||||
@Override
|
||||
public void consume(ConnectionContext context,
|
||||
HandshakeMessage message, ByteBuffer buffer) throws IOException {
|
||||
|
||||
// The consuming happens in server side only.
|
||||
ServerHandshakeContext shc = (ServerHandshakeContext)context;
|
||||
|
||||
// Is it a supported and enabled extension?
|
||||
if (!shc.sslConfig.isAvailable(
|
||||
SSLExtension.CH_CERTIFICATE_AUTHORITIES)) {
|
||||
if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) {
|
||||
SSLLogger.fine(
|
||||
"Ignore unavailable " +
|
||||
"certificate_authorities extension");
|
||||
}
|
||||
|
||||
return; // ignore the extension
|
||||
}
|
||||
|
||||
// Parse the extension.
|
||||
CertificateAuthoritiesSpec spec =
|
||||
new CertificateAuthoritiesSpec(shc, buffer);
|
||||
|
||||
// Update the context.
|
||||
shc.peerSupportedAuthorities = spec.getAuthorities();
|
||||
shc.handshakeExtensions.put(
|
||||
SSLExtension.CH_CERTIFICATE_AUTHORITIES, spec);
|
||||
|
||||
// No impact on session resumption.
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Network data producer of a "certificate_authorities" extension in
|
||||
* the CertificateRequest handshake message.
|
||||
*/
|
||||
private static final
|
||||
class CRCertificateAuthoritiesProducer implements HandshakeProducer {
|
||||
|
||||
// Prevent instantiation of this class.
|
||||
private CRCertificateAuthoritiesProducer() {
|
||||
// blank
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] produce(ConnectionContext context,
|
||||
HandshakeMessage message) throws IOException {
|
||||
// The producing happens in server side only.
|
||||
ServerHandshakeContext shc = (ServerHandshakeContext)context;
|
||||
|
||||
// Is it a supported and enabled extension?
|
||||
if (!shc.sslConfig.isAvailable(
|
||||
SSLExtension.CR_CERTIFICATE_AUTHORITIES)) {
|
||||
if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) {
|
||||
SSLLogger.fine(
|
||||
"Ignore unavailable " +
|
||||
"certificate_authorities extension");
|
||||
}
|
||||
|
||||
return null; // ignore the extension
|
||||
}
|
||||
|
||||
// Produce the extension.
|
||||
X509Certificate[] caCerts =
|
||||
shc.sslContext.getX509TrustManager().getAcceptedIssuers();
|
||||
if (caCerts.length == 0) {
|
||||
if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) {
|
||||
SSLLogger.fine(
|
||||
"No available certificate authorities");
|
||||
}
|
||||
|
||||
return null; // ignore the extension
|
||||
}
|
||||
|
||||
List<byte[]> encodedCAs =
|
||||
CertificateAuthoritiesSpec.getEncodedAuthorities(caCerts);
|
||||
if (encodedCAs.isEmpty()) {
|
||||
if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) {
|
||||
SSLLogger.warning(
|
||||
"Too many certificate authorities to use " +
|
||||
"the certificate_authorities extension");
|
||||
}
|
||||
|
||||
return null; // ignore the extension
|
||||
}
|
||||
|
||||
CertificateAuthoritiesSpec spec =
|
||||
new CertificateAuthoritiesSpec(encodedCAs);
|
||||
|
||||
int vectorLen = 0;
|
||||
for (byte[] encoded : spec.authorities) {
|
||||
vectorLen += encoded.length + 2;
|
||||
}
|
||||
|
||||
byte[] extData = new byte[vectorLen + 2];
|
||||
ByteBuffer m = ByteBuffer.wrap(extData);
|
||||
Record.putInt16(m, vectorLen);
|
||||
for (byte[] encoded : spec.authorities) {
|
||||
Record.putBytes16(m, encoded);
|
||||
}
|
||||
|
||||
// Update the context.
|
||||
shc.handshakeExtensions.put(
|
||||
SSLExtension.CR_CERTIFICATE_AUTHORITIES, spec);
|
||||
|
||||
return extData;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Network data consumer of a "certificate_authorities" extension in
|
||||
* the CertificateRequest handshake message.
|
||||
*/
|
||||
private static final
|
||||
class CRCertificateAuthoritiesConsumer implements ExtensionConsumer {
|
||||
|
||||
// Prevent instantiation of this class.
|
||||
private CRCertificateAuthoritiesConsumer() {
|
||||
// blank
|
||||
}
|
||||
|
||||
@Override
|
||||
public void consume(ConnectionContext context,
|
||||
HandshakeMessage message, ByteBuffer buffer) throws IOException {
|
||||
|
||||
// The consuming happens in client side only.
|
||||
ClientHandshakeContext chc = (ClientHandshakeContext)context;
|
||||
|
||||
// Is it a supported and enabled extension?
|
||||
if (!chc.sslConfig.isAvailable(
|
||||
SSLExtension.CR_CERTIFICATE_AUTHORITIES)) {
|
||||
if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) {
|
||||
SSLLogger.fine(
|
||||
"Ignore unavailable " +
|
||||
"certificate_authorities extension");
|
||||
}
|
||||
|
||||
return; // ignore the extension
|
||||
}
|
||||
|
||||
// Parse the extension.
|
||||
CertificateAuthoritiesSpec spec =
|
||||
new CertificateAuthoritiesSpec(chc, buffer);
|
||||
|
||||
// Update the context.
|
||||
chc.peerSupportedAuthorities = spec.getAuthorities();
|
||||
chc.handshakeExtensions.put(
|
||||
SSLExtension.CR_CERTIFICATE_AUTHORITIES, spec);
|
||||
|
||||
// No impact on session resumption.
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -200,14 +200,13 @@ final class CertificateRequest {
|
|||
}
|
||||
|
||||
X500Principal[] getAuthorities() {
|
||||
List<X500Principal> principals =
|
||||
new ArrayList<>(authorities.size());
|
||||
X500Principal[] principals = new X500Principal[authorities.size()];
|
||||
int i = 0;
|
||||
for (byte[] encoded : authorities) {
|
||||
X500Principal principal = new X500Principal(encoded);
|
||||
principals.add(principal);
|
||||
principals[i++] = new X500Principal(encoded);
|
||||
}
|
||||
|
||||
return principals.toArray(new X500Principal[0]);
|
||||
return principals;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -504,14 +503,13 @@ final class CertificateRequest {
|
|||
}
|
||||
|
||||
X500Principal[] getAuthorities() {
|
||||
List<X500Principal> principals =
|
||||
new ArrayList<>(authorities.size());
|
||||
X500Principal[] principals = new X500Principal[authorities.size()];
|
||||
int i = 0;
|
||||
for (byte[] encoded : authorities) {
|
||||
X500Principal principal = new X500Principal(encoded);
|
||||
principals.add(principal);
|
||||
principals[i++] = new X500Principal(encoded);
|
||||
}
|
||||
|
||||
return principals.toArray(new X500Principal[0]);
|
||||
return principals;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -407,7 +407,27 @@ enum SSLExtension implements SSLStringizer {
|
|||
null,
|
||||
PskKeyExchangeModesExtension.chOnTradeAbsence,
|
||||
PskKeyExchangeModesExtension.pkemStringizer),
|
||||
CERTIFICATE_AUTHORITIES (0x002F, "certificate_authorities"),
|
||||
|
||||
CH_CERTIFICATE_AUTHORITIES (0x002F, "certificate_authorities",
|
||||
SSLHandshake.CLIENT_HELLO,
|
||||
ProtocolVersion.PROTOCOLS_OF_13,
|
||||
CertificateAuthoritiesExtension.chNetworkProducer,
|
||||
CertificateAuthoritiesExtension.chOnLoadConsumer,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
CertificateAuthoritiesExtension.ssStringizer),
|
||||
|
||||
CR_CERTIFICATE_AUTHORITIES (0x002F, "certificate_authorities",
|
||||
SSLHandshake.CERTIFICATE_REQUEST,
|
||||
ProtocolVersion.PROTOCOLS_OF_13,
|
||||
CertificateAuthoritiesExtension.crNetworkProducer,
|
||||
CertificateAuthoritiesExtension.crOnLoadConsumer,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
CertificateAuthoritiesExtension.ssStringizer),
|
||||
|
||||
OID_FILTERS (0x0030, "oid_filters"),
|
||||
POST_HANDSHAKE_AUTH (0x0030, "post_handshake_auth"),
|
||||
|
||||
|
@ -725,6 +745,50 @@ enum SSLExtension implements SSLStringizer {
|
|||
extensions.remove(CH_MAX_FRAGMENT_LENGTH);
|
||||
}
|
||||
|
||||
// To switch on certificate_authorities extension in ClientHello.
|
||||
//
|
||||
// Note: Please be careful to enable this extension in ClientHello.
|
||||
//
|
||||
// In practice, if the server certificate cannot be validated by
|
||||
// the underlying programs, the user may manually check the
|
||||
// certificate in order to access the service. The certificate
|
||||
// could be accepted manually, and the handshake continues. For
|
||||
// example, the browsers provide the manual option to accept
|
||||
// untrusted server certificate. If this extension is enabled in
|
||||
// the ClientHello handshake message, and the server's certificate
|
||||
// does not chain back to any of the CAs in the extension, then the
|
||||
// server will terminate the handshake and close the connection.
|
||||
// There is no chance for the client to perform the manual check.
|
||||
// Therefore, enabling this extension in ClientHello may lead to
|
||||
// unexpected compatibility issues for such cases.
|
||||
//
|
||||
// According to TLS 1.3 specification [RFC 8446] the maximum size
|
||||
// of the certificate_authorities extension is 2^16 bytes. The
|
||||
// maximum TLS record size is 2^14 bytes. If the handshake
|
||||
// message is bigger than maximum TLS record size, it should be
|
||||
// splitted into several records. In fact, some server
|
||||
// implementations do not allow ClientHello messages bigger than
|
||||
// the maximum TLS record size and will immediately abort the
|
||||
// connection with a fatal alert. Therefore, if the client trusts
|
||||
// too many certificate authorities, there may be unexpected
|
||||
// interoperability issues.
|
||||
//
|
||||
// Furthermore, if the client trusts more CAs such that it exceeds
|
||||
// the size limit of the extension, enabling this extension in
|
||||
// client side does not really make sense any longer as there is
|
||||
// no way to indicate the server certificate selection accurately.
|
||||
//
|
||||
// In general, a server does not use multiple certificates issued
|
||||
// from different CAs. It is not expected to use this extension a
|
||||
// lot in practice. When there is a need to use this extension
|
||||
// in ClientHello handshake message, please take care of the
|
||||
// potential compatibility and interoperability issues above.
|
||||
enableExtension = Utilities.getBooleanProperty(
|
||||
"jdk.tls.client.enableCAExtension", false);
|
||||
if (!enableExtension) {
|
||||
extensions.remove(CH_CERTIFICATE_AUTHORITIES);
|
||||
}
|
||||
|
||||
defaults = Collections.unmodifiableCollection(extensions);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -230,12 +230,14 @@ enum X509Authentication implements SSLAuthentication {
|
|||
if (chc.conContext.transport instanceof SSLSocketImpl) {
|
||||
clientAlias = km.chooseClientAlias(
|
||||
new String[] { keyType },
|
||||
chc.peerSupportedAuthorities,
|
||||
chc.peerSupportedAuthorities == null ? null :
|
||||
chc.peerSupportedAuthorities.clone(),
|
||||
(SSLSocket)chc.conContext.transport);
|
||||
} else if (chc.conContext.transport instanceof SSLEngineImpl) {
|
||||
clientAlias = km.chooseEngineClientAlias(
|
||||
new String[] { keyType },
|
||||
chc.peerSupportedAuthorities,
|
||||
chc.peerSupportedAuthorities == null ? null :
|
||||
chc.peerSupportedAuthorities.clone(),
|
||||
(SSLEngine)chc.conContext.transport);
|
||||
}
|
||||
|
||||
|
@ -284,10 +286,14 @@ enum X509Authentication implements SSLAuthentication {
|
|||
String serverAlias = null;
|
||||
if (shc.conContext.transport instanceof SSLSocketImpl) {
|
||||
serverAlias = km.chooseServerAlias(keyType,
|
||||
null, (SSLSocket)shc.conContext.transport);
|
||||
shc.peerSupportedAuthorities == null ? null :
|
||||
shc.peerSupportedAuthorities.clone(),
|
||||
(SSLSocket)shc.conContext.transport);
|
||||
} else if (shc.conContext.transport instanceof SSLEngineImpl) {
|
||||
serverAlias = km.chooseEngineServerAlias(keyType,
|
||||
null, (SSLEngine)shc.conContext.transport);
|
||||
shc.peerSupportedAuthorities == null ? null :
|
||||
shc.peerSupportedAuthorities.clone(),
|
||||
(SSLEngine)shc.conContext.transport);
|
||||
}
|
||||
|
||||
if (serverAlias == null) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue