8268199: Correct certificate requests
Reviewed-by: yan
Backport-of: afeccc7639d3d09041b58cf0f5672eb7310b2cbd
diff --git a/src/java.base/share/classes/sun/security/ssl/CertificateRequest.java b/src/java.base/share/classes/sun/security/ssl/CertificateRequest.java
index 79d92fc..8e8370b 100644
--- a/src/java.base/share/classes/sun/security/ssl/CertificateRequest.java
+++ b/src/java.base/share/classes/sun/security/ssl/CertificateRequest.java
@@ -31,6 +31,7 @@
import java.security.cert.X509Certificate;
import java.text.MessageFormat;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
@@ -44,6 +45,7 @@
import sun.security.ssl.CipherSuite.KeyExchange;
import sun.security.ssl.SSLHandshake.HandshakeMessage;
import sun.security.ssl.X509Authentication.X509Possession;
+import sun.security.ssl.X509Authentication.X509PossessionGenerator;
/**
* Pack of the CertificateRequest handshake message.
@@ -716,12 +718,11 @@
chc.handshakeSession.setPeerSupportedSignatureAlgorithms(sss);
chc.peerSupportedAuthorities = crm.getAuthorities();
- // For TLS 1.2, we no longer use the certificate_types field
- // from the CertificateRequest message to directly determine
- // the SSLPossession. Instead, the choosePossession method
- // will use the accepted signature schemes in the message to
- // determine the set of acceptable certificate types to select from.
- SSLPossession pos = choosePossession(chc);
+ // For TLS 1.2, we need to use a combination of the CR message's
+ // allowed key types and the signature algorithms in order to
+ // find a certificate chain that has the right key and all certs
+ // using one or more of the allowed cert signature schemes.
+ SSLPossession pos = choosePossession(chc, crm);
if (pos == null) {
return;
}
@@ -731,8 +732,8 @@
SSLHandshake.CERTIFICATE_VERIFY);
}
- private static SSLPossession choosePossession(HandshakeContext hc)
- throws IOException {
+ private static SSLPossession choosePossession(HandshakeContext hc,
+ T12CertificateRequestMessage crm) throws IOException {
if (hc.peerRequestedCertSignSchemes == null ||
hc.peerRequestedCertSignSchemes.isEmpty()) {
if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) {
@@ -742,6 +743,9 @@
return null;
}
+ // Put the CR key type into a more friendly format for searching
+ List<String> crKeyTypes = Arrays.asList(crm.getKeyTypes());
+
Collection<String> checkedKeyTypes = new HashSet<>();
for (SignatureScheme ss : hc.peerRequestedCertSignSchemes) {
if (checkedKeyTypes.contains(ss.keyAlgorithm)) {
@@ -768,7 +772,7 @@
continue;
}
- SSLAuthentication ka = X509Authentication.valueOf(ss);
+ X509Authentication ka = X509Authentication.valueOf(ss);
if (ka == null) {
if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) {
SSLLogger.warning(
@@ -776,6 +780,27 @@
}
checkedKeyTypes.add(ss.keyAlgorithm);
continue;
+ } else {
+ // Any auth object will have a possession generator and
+ // we need to make sure the key types for that generator
+ // share at least one common algorithm with the CR's
+ // allowed key types.
+ if (ka.possessionGenerator instanceof
+ X509PossessionGenerator) {
+ X509PossessionGenerator xpg =
+ (X509PossessionGenerator) ka.possessionGenerator;
+ if (Collections.disjoint(crKeyTypes,
+ Arrays.asList(xpg.keyTypes))) {
+ if (SSLLogger.isOn &&
+ SSLLogger.isOn("ssl,handshake")) {
+ SSLLogger.warning(
+ "Unsupported authentication scheme: " +
+ ss.name);
+ }
+ checkedKeyTypes.add(ss.keyAlgorithm);
+ continue;
+ }
+ }
}
SSLPossession pos = ka.createPossession(hc);
diff --git a/src/java.base/share/classes/sun/security/ssl/X509Authentication.java b/src/java.base/share/classes/sun/security/ssl/X509Authentication.java
index 5810a7e..32d3b05 100644
--- a/src/java.base/share/classes/sun/security/ssl/X509Authentication.java
+++ b/src/java.base/share/classes/sun/security/ssl/X509Authentication.java
@@ -191,9 +191,9 @@
}
}
- private static final
- class X509PossessionGenerator implements SSLPossessionGenerator {
- private final String[] keyTypes;
+ static final class X509PossessionGenerator
+ implements SSLPossessionGenerator {
+ final String[] keyTypes;
private X509PossessionGenerator(String[] keyTypes) {
this.keyTypes = keyTypes;