< prev index next >

src/java.base/share/classes/sun/security/ssl/X509KeyManagerImpl.java

Print this page

        

@@ -52,11 +52,11 @@
  *  . it is explicitly designed to accommodate KeyStores that change over
  *    the lifetime of the process.
  *  . it makes an effort to choose the key that matches best, i.e. one that
  *    is not expired and has the appropriate certificate extensions.
  *
- * Note that this code is not explicitly performance optimzied yet.
+ * Note that this code is not explicitly performance optimized yet.
  *
  * @author  Andreas Sterbenz
  */
 final class X509KeyManagerImpl extends X509ExtendedKeyManager
         implements X509KeyManager {

@@ -133,10 +133,11 @@
     @Override
     public String chooseServerAlias(String keyType,
             Principal[] issuers, Socket socket) {
         return chooseAlias(getKeyTypes(keyType), issuers, CheckType.SERVER,
             getAlgorithmConstraints(socket),
+            getCertificateAuthorities(socket),
             X509TrustManagerImpl.getRequestedServerNames(socket),
             "HTTPS");    // The SNI HostName is a fully qualified domain name.
                          // The certificate selection scheme for SNI HostName
                          // is similar to HTTPS endpoint identification scheme
                          // implemented in this provider.

@@ -151,10 +152,11 @@
     @Override
     public String chooseEngineServerAlias(String keyType,
             Principal[] issuers, SSLEngine engine) {
         return chooseAlias(getKeyTypes(keyType), issuers, CheckType.SERVER,
             getAlgorithmConstraints(engine),
+            getCertificateAuthorities(engine),
             X509TrustManagerImpl.getRequestedServerNames(engine),
             "HTTPS");    // The SNI HostName is a fully qualified domain name.
                          // The certificate selection scheme for SNI HostName
                          // is similar to HTTPS endpoint identification scheme
                          // implemented in this provider.

@@ -236,10 +238,44 @@
         }
 
         return new SSLAlgorithmConstraints(engine, true);
     }
 
+    private CertificateAuthority[] getCertificateAuthorities(Socket socket) {
+        if(socket != null && socket.isConnected() && socket instanceof SSLSocket){
+            final SSLSocket sslSocket = (SSLSocket)socket;
+            final SSLParameters sslParameters = sslSocket.getSSLParameters();
+            if (sslParameters.getUseCertificateAuthorities()) {
+                return getCertificateAuthorities(sslSocket.getHandshakeSession());
+            }
+        }
+        return null;
+    }
+
+    private CertificateAuthority[] getCertificateAuthorities(SSLEngine engine) {
+        if (engine != null) {
+            final SSLParameters sslParameters = engine.getSSLParameters();
+            if (sslParameters.getUseCertificateAuthorities()) {
+                return getCertificateAuthorities(engine.getHandshakeSession());
+            }
+        }
+        return null;
+    }
+
+    private CertificateAuthority[] getCertificateAuthorities(SSLSession session) {
+        if (session != null) {
+            final ProtocolVersion protocolVersion =
+                ProtocolVersion.valueOf(session.getProtocol());
+            if (protocolVersion.useTLS12PlusSpec()) {
+                if (session instanceof ExtendedSSLSession) {
+                    return ((ExtendedSSLSession)session).getCertificateAuthorities();
+                }
+            }
+        }
+        return null;
+    }
+
     // we construct the alias we return to JSSE as seen in the code below
     // a unique id is included to allow us to reliably cache entries
     // between the calls to getCertificateChain() and getPrivateKey()
     // even if tokens are inserted or removed
     private String makeAlias(EntryStatus entry) {

@@ -362,15 +398,16 @@
      */
     private String chooseAlias(List<KeyType> keyTypeList, Principal[] issuers,
             CheckType checkType, AlgorithmConstraints constraints) {
 
         return chooseAlias(keyTypeList, issuers,
-                                    checkType, constraints, null, null);
+                                    checkType, constraints, null, null, null);
     }
 
     private String chooseAlias(List<KeyType> keyTypeList, Principal[] issuers,
             CheckType checkType, AlgorithmConstraints constraints,
+            CertificateAuthority[] certificateAuthorities,
             List<SNIServerName> requestedServerNames, String idAlgorithm) {
 
         if (keyTypeList == null || keyTypeList.isEmpty()) {
             return null;
         }

@@ -379,11 +416,12 @@
         List<EntryStatus> allResults = null;
         for (int i = 0, n = builders.size(); i < n; i++) {
             try {
                 List<EntryStatus> results = getAliases(i, keyTypeList,
                             issuerSet, false, checkType, constraints,
-                            requestedServerNames, idAlgorithm);
+                            certificateAuthorities, requestedServerNames, 
+                            idAlgorithm);
                 if (results != null) {
                     // the results will either be a single perfect match
                     // or 1 or more imperfect matches
                     // if it's a perfect match, return immediately
                     EntryStatus status = results.get(0);

@@ -434,11 +472,11 @@
         List<EntryStatus> allResults = null;
         for (int i = 0, n = builders.size(); i < n; i++) {
             try {
                 List<EntryStatus> results = getAliases(i, keyTypeList,
                                     issuerSet, true, checkType, constraints,
-                                    null, null);
+                                    null, null, null);
                 if (results != null) {
                     if (allResults == null) {
                         allResults = new ArrayList<EntryStatus>();
                     }
                     allResults.addAll(results);

@@ -711,10 +749,11 @@
      */
     private List<EntryStatus> getAliases(int builderIndex,
             List<KeyType> keyTypes, Set<Principal> issuerSet,
             boolean findAll, CheckType checkType,
             AlgorithmConstraints constraints,
+            CertificateAuthority[] certificateAuthorities,
             List<SNIServerName> requestedServerNames,
             String idAlgorithm) throws Exception {
 
         Builder builder = builders.get(builderIndex);
         KeyStore ks = builder.getKeyStore();

@@ -780,10 +819,37 @@
                     }
                     continue;
                 }
             }
 
+            // check that certificate chain has an indicated certificate authority
+            // (if indications are available)
+            if (certificateAuthorities != null) {
+                boolean foundCertificateAuthority = false;
+                // Iterate the certificate chain starting from root certificate
+                look_for_ca:
+                for (int i = chain.length; i > 0;) {
+                    i--;
+                    final X509Certificate cert = (X509Certificate) chain[i];
+                                                 // Can safely cast because of
+                                                 // previous check for X509Certificate
+                    for (CertificateAuthority certificateAuthority : certificateAuthorities) {
+                        try {
+                            if (certificateAuthority.implies(cert)) {
+                                foundCertificateAuthority = true;
+                                break look_for_ca;
+                            }
+                        } catch (Exception e1) {
+                            // Certificate matching is a best-effort. Continue looking for matches.
+                        }
+                    }
+                }
+                if (foundCertificateAuthority == false) {
+                    continue;
+                }
+            }
+
             // check the algorithm constraints
             if (constraints != null &&
                     !conformsToAlgorithmConstraints(constraints, chain,
                             checkType.getValidator())) {
 
< prev index next >