src/java.base/share/classes/sun/security/ssl/X509KeyManagerImpl.java
branchJDK-8145252-TLS13-branch
changeset 56542 56aaa6cb3693
parent 47216 71c04702a3d5
child 56806 32a737f51e37
equal deleted inserted replaced
56541:92cbbfc996f3 56542:56aaa6cb3693
     1 /*
     1 /*
     2  * Copyright (c) 2004, 2017, Oracle and/or its affiliates. All rights reserved.
     2  * Copyright (c) 2004, 2018, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.  Oracle designates this
     7  * published by the Free Software Foundation.  Oracle designates this
    24  */
    24  */
    25 
    25 
    26 package sun.security.ssl;
    26 package sun.security.ssl;
    27 
    27 
    28 import java.lang.ref.*;
    28 import java.lang.ref.*;
       
    29 import java.net.Socket;
       
    30 import java.security.AlgorithmConstraints;
       
    31 import java.security.KeyStore;
       
    32 import java.security.KeyStore.Builder;
       
    33 import java.security.KeyStore.Entry;
       
    34 import java.security.KeyStore.PrivateKeyEntry;
       
    35 import java.security.Principal;
       
    36 import java.security.PrivateKey;
       
    37 import java.security.cert.CertPathValidatorException;
       
    38 import java.security.cert.Certificate;
       
    39 import java.security.cert.CertificateException;
       
    40 import java.security.cert.X509Certificate;
    29 import java.util.*;
    41 import java.util.*;
    30 import static java.util.Locale.ENGLISH;
    42 import static java.util.Locale.ENGLISH;
    31 import java.util.concurrent.atomic.AtomicLong;
    43 import java.util.concurrent.atomic.AtomicLong;
    32 import java.net.Socket;
       
    33 
       
    34 import java.security.*;
       
    35 import java.security.KeyStore.*;
       
    36 import java.security.cert.*;
       
    37 import java.security.cert.Certificate;
       
    38 
       
    39 import javax.net.ssl.*;
    44 import javax.net.ssl.*;
    40 
       
    41 import sun.security.provider.certpath.AlgorithmChecker;
    45 import sun.security.provider.certpath.AlgorithmChecker;
    42 import sun.security.validator.Validator;
    46 import sun.security.validator.Validator;
    43 
    47 
    44 /**
    48 /**
    45  * The new X509 key manager implementation. The main differences to the
    49  * The new X509 key manager implementation. The main differences to the
    59  * @author  Andreas Sterbenz
    63  * @author  Andreas Sterbenz
    60  */
    64  */
    61 final class X509KeyManagerImpl extends X509ExtendedKeyManager
    65 final class X509KeyManagerImpl extends X509ExtendedKeyManager
    62         implements X509KeyManager {
    66         implements X509KeyManager {
    63 
    67 
    64     private static final Debug debug = Debug.getInstance("ssl");
       
    65 
       
    66     private static final boolean useDebug =
       
    67                             (debug != null) && Debug.isOn("keymanager");
       
    68 
       
    69     // for unit testing only, set via privileged reflection
    68     // for unit testing only, set via privileged reflection
    70     private static Date verificationDate;
    69     private static Date verificationDate;
    71 
    70 
    72     // list of the builders
    71     // list of the builders
    73     private final List<Builder> builders;
    72     private final List<Builder> builders;
   187 
   186 
   188             SSLSocket sslSocket = (SSLSocket)socket;
   187             SSLSocket sslSocket = (SSLSocket)socket;
   189             SSLSession session = sslSocket.getHandshakeSession();
   188             SSLSession session = sslSocket.getHandshakeSession();
   190 
   189 
   191             if (session != null) {
   190             if (session != null) {
   192                 ProtocolVersion protocolVersion =
   191                 if (ProtocolVersion.useTLS12PlusSpec(session.getProtocol())) {
   193                     ProtocolVersion.valueOf(session.getProtocol());
       
   194                 if (protocolVersion.useTLS12PlusSpec()) {
       
   195                     String[] peerSupportedSignAlgs = null;
   192                     String[] peerSupportedSignAlgs = null;
   196 
   193 
   197                     if (session instanceof ExtendedSSLSession) {
   194                     if (session instanceof ExtendedSSLSession) {
   198                         ExtendedSSLSession extSession =
   195                         ExtendedSSLSession extSession =
   199                             (ExtendedSSLSession)session;
   196                             (ExtendedSSLSession)session;
   215     // Gets algorithm constraints of the engine.
   212     // Gets algorithm constraints of the engine.
   216     private AlgorithmConstraints getAlgorithmConstraints(SSLEngine engine) {
   213     private AlgorithmConstraints getAlgorithmConstraints(SSLEngine engine) {
   217         if (engine != null) {
   214         if (engine != null) {
   218             SSLSession session = engine.getHandshakeSession();
   215             SSLSession session = engine.getHandshakeSession();
   219             if (session != null) {
   216             if (session != null) {
   220                 ProtocolVersion protocolVersion =
   217                 if (ProtocolVersion.useTLS12PlusSpec(session.getProtocol())) {
   221                     ProtocolVersion.valueOf(session.getProtocol());
       
   222                 if (protocolVersion.useTLS12PlusSpec()) {
       
   223                     String[] peerSupportedSignAlgs = null;
   218                     String[] peerSupportedSignAlgs = null;
   224 
   219 
   225                     if (session instanceof ExtendedSSLSession) {
   220                     if (session instanceof ExtendedSSLSession) {
   226                         ExtendedSSLSession extSession =
   221                         ExtendedSSLSession extSession =
   227                             (ExtendedSSLSession)session;
   222                             (ExtendedSSLSession)session;
   386                     // the results will either be a single perfect match
   381                     // the results will either be a single perfect match
   387                     // or 1 or more imperfect matches
   382                     // or 1 or more imperfect matches
   388                     // if it's a perfect match, return immediately
   383                     // if it's a perfect match, return immediately
   389                     EntryStatus status = results.get(0);
   384                     EntryStatus status = results.get(0);
   390                     if (status.checkResult == CheckResult.OK) {
   385                     if (status.checkResult == CheckResult.OK) {
   391                         if (useDebug) {
   386                         if (SSLLogger.isOn && SSLLogger.isOn("keymanager")) {
   392                             debug.println("KeyMgr: choosing key: " + status);
   387                             SSLLogger.fine("KeyMgr: choosing key: " + status);
   393                         }
   388                         }
   394                         return makeAlias(status);
   389                         return makeAlias(status);
   395                     }
   390                     }
   396                     if (allResults == null) {
   391                     if (allResults == null) {
   397                         allResults = new ArrayList<EntryStatus>();
   392                         allResults = new ArrayList<EntryStatus>();
   401             } catch (Exception e) {
   396             } catch (Exception e) {
   402                 // ignore
   397                 // ignore
   403             }
   398             }
   404         }
   399         }
   405         if (allResults == null) {
   400         if (allResults == null) {
   406             if (useDebug) {
   401             if (SSLLogger.isOn && SSLLogger.isOn("keymanager")) {
   407                 debug.println("KeyMgr: no matching key found");
   402                 SSLLogger.fine("KeyMgr: no matching key found");
   408             }
   403             }
   409             return null;
   404             return null;
   410         }
   405         }
   411         Collections.sort(allResults);
   406         Collections.sort(allResults);
   412         if (useDebug) {
   407         if (SSLLogger.isOn && SSLLogger.isOn("keymanager")) {
   413             debug.println("KeyMgr: no good matching key found, "
   408             SSLLogger.fine(
   414                         + "returning best match out of:");
   409                     "KeyMgr: no good matching key found, "
   415             debug.println(allResults.toString());
   410                     + "returning best match out of", allResults);
   416         }
   411         }
   417         return makeAlias(allResults.get(0));
   412         return makeAlias(allResults.get(0));
   418     }
   413     }
   419 
   414 
   420     /*
   415     /*
   446             } catch (Exception e) {
   441             } catch (Exception e) {
   447                 // ignore
   442                 // ignore
   448             }
   443             }
   449         }
   444         }
   450         if (allResults == null || allResults.isEmpty()) {
   445         if (allResults == null || allResults.isEmpty()) {
   451             if (useDebug) {
   446             if (SSLLogger.isOn && SSLLogger.isOn("keymanager")) {
   452                 debug.println("KeyMgr: no matching alias found");
   447                 SSLLogger.fine("KeyMgr: no matching alias found");
   453             }
   448             }
   454             return null;
   449             return null;
   455         }
   450         }
   456         Collections.sort(allResults);
   451         Collections.sort(allResults);
   457         if (useDebug) {
   452         if (SSLLogger.isOn && SSLLogger.isOn("keymanager")) {
   458             debug.println("KeyMgr: getting aliases: " + allResults);
   453             SSLLogger.fine("KeyMgr: getting aliases", allResults);
   459         }
   454         }
   460         return toAliases(allResults);
   455         return toAliases(allResults);
   461     }
   456     }
   462 
   457 
   463     // turn candidate entries into unique aliases we can return to JSSE
   458     // turn candidate entries into unique aliases we can return to JSSE
   574                     switch (algorithm) {
   569                     switch (algorithm) {
   575                         case "RSA":
   570                         case "RSA":
   576                             // require either signature bit
   571                             // require either signature bit
   577                             // or if server also allow key encipherment bit
   572                             // or if server also allow key encipherment bit
   578                             if (kuSignature == false) {
   573                             if (kuSignature == false) {
   579                                 if ((this == CLIENT) || (getBit(ku, 2) == false)) {
   574                                 if (this == CLIENT || getBit(ku, 2) == false) {
   580                                     return CheckResult.EXTENSION_MISMATCH;
   575                                     return CheckResult.EXTENSION_MISMATCH;
   581                                 }
   576                                 }
   582                             }
   577                             }
   583                             break;
   578                             break;
   584                         case "DSA":
   579                         case "DSA":
   629                             try {
   624                             try {
   630                                 serverName =
   625                                 serverName =
   631                                     new SNIHostName(serverName.getEncoded());
   626                                     new SNIHostName(serverName.getEncoded());
   632                             } catch (IllegalArgumentException iae) {
   627                             } catch (IllegalArgumentException iae) {
   633                                 // unlikely to happen, just in case ...
   628                                 // unlikely to happen, just in case ...
   634                                 if (useDebug) {
   629                                 if (SSLLogger.isOn &&
   635                                     debug.println(
   630                                         SSLLogger.isOn("keymanager")) {
       
   631                                     SSLLogger.fine(
   636                                        "Illegal server name: " + serverName);
   632                                        "Illegal server name: " + serverName);
   637                                 }
   633                                 }
   638 
   634 
   639                                 return CheckResult.INSENSITIVE;
   635                                 return CheckResult.INSENSITIVE;
   640                             }
   636                             }
   644 
   640 
   645                         try {
   641                         try {
   646                             X509TrustManagerImpl.checkIdentity(hostname,
   642                             X509TrustManagerImpl.checkIdentity(hostname,
   647                                                         cert, idAlgorithm);
   643                                                         cert, idAlgorithm);
   648                         } catch (CertificateException e) {
   644                         } catch (CertificateException e) {
   649                             if (useDebug) {
   645                             if (SSLLogger.isOn &&
   650                                 debug.println(
   646                                     SSLLogger.isOn("keymanager")) {
   651                                    "Certificate identity does not match " +
   647                                 SSLLogger.fine(
   652                                    "Server Name Inidication (SNI): " +
   648                                     "Certificate identity does not match " +
   653                                    hostname);
   649                                     "Server Name Inidication (SNI): " +
       
   650                                     hostname);
   654                             }
   651                             }
   655                             return CheckResult.INSENSITIVE;
   652                             return CheckResult.INSENSITIVE;
   656                         }
   653                         }
   657 
   654 
   658                         break;
   655                         break;
   722         Date date = verificationDate;
   719         Date date = verificationDate;
   723         boolean preferred = false;
   720         boolean preferred = false;
   724         for (Enumeration<String> e = ks.aliases(); e.hasMoreElements(); ) {
   721         for (Enumeration<String> e = ks.aliases(); e.hasMoreElements(); ) {
   725             String alias = e.nextElement();
   722             String alias = e.nextElement();
   726             // check if it is a key entry (private key or secret key)
   723             // check if it is a key entry (private key or secret key)
   727             if (ks.isKeyEntry(alias) == false) {
   724             if (!ks.isKeyEntry(alias)) {
   728                 continue;
   725                 continue;
   729             }
   726             }
   730 
   727 
   731             Certificate[] chain = ks.getCertificateChain(alias);
   728             Certificate[] chain = ks.getCertificateChain(alias);
   732             if ((chain == null) || (chain.length == 0)) {
   729             if ((chain == null) || (chain.length == 0)) {
   755                     break;
   752                     break;
   756                 }
   753                 }
   757                 j++;
   754                 j++;
   758             }
   755             }
   759             if (keyIndex == -1) {
   756             if (keyIndex == -1) {
   760                 if (useDebug) {
   757                 if (SSLLogger.isOn && SSLLogger.isOn("keymanager")) {
   761                     debug.println("Ignoring alias " + alias
   758                     SSLLogger.fine("Ignore alias " + alias
   762                                 + ": key algorithm does not match");
   759                                 + ": key algorithm does not match");
   763                 }
   760                 }
   764                 continue;
   761                 continue;
   765             }
   762             }
   766             // check issuers
   763             // check issuers
   772                         found = true;
   769                         found = true;
   773                         break;
   770                         break;
   774                     }
   771                     }
   775                 }
   772                 }
   776                 if (found == false) {
   773                 if (found == false) {
   777                     if (useDebug) {
   774                     if (SSLLogger.isOn && SSLLogger.isOn("keymanager")) {
   778                         debug.println("Ignoring alias " + alias
   775                         SSLLogger.fine(
   779                                     + ": issuers do not match");
   776                                 "Ignore alias " + alias
       
   777                                 + ": issuers do not match");
   780                     }
   778                     }
   781                     continue;
   779                     continue;
   782                 }
   780                 }
   783             }
   781             }
   784 
   782 
   785             // check the algorithm constraints
   783             // check the algorithm constraints
   786             if (constraints != null &&
   784             if (constraints != null &&
   787                     !conformsToAlgorithmConstraints(constraints, chain,
   785                     !conformsToAlgorithmConstraints(constraints, chain,
   788                             checkType.getValidator())) {
   786                             checkType.getValidator())) {
   789 
   787 
   790                 if (useDebug) {
   788                 if (SSLLogger.isOn && SSLLogger.isOn("keymanager")) {
   791                     debug.println("Ignoring alias " + alias +
   789                     SSLLogger.fine("Ignore alias " + alias +
   792                             ": certificate list does not conform to " +
   790                             ": certificate list does not conform to " +
   793                             "algorithm constraints");
   791                             "algorithm constraints");
   794                 }
   792                 }
   795                 continue;
   793                 continue;
   796             }
   794             }
   823 
   821 
   824     private static boolean conformsToAlgorithmConstraints(
   822     private static boolean conformsToAlgorithmConstraints(
   825             AlgorithmConstraints constraints, Certificate[] chain,
   823             AlgorithmConstraints constraints, Certificate[] chain,
   826             String variant) {
   824             String variant) {
   827 
   825 
   828         AlgorithmChecker checker = new AlgorithmChecker(constraints, null, variant);
   826         AlgorithmChecker checker =
       
   827                 new AlgorithmChecker(constraints, null, variant);
   829         try {
   828         try {
   830             checker.init(false);
   829             checker.init(false);
   831         } catch (CertPathValidatorException cpve) {
   830         } catch (CertPathValidatorException cpve) {
   832             // unlikely to happen
   831             // unlikely to happen
   833             if (useDebug) {
   832             if (SSLLogger.isOn && SSLLogger.isOn("keymanager")) {
   834                 debug.println(
   833                 SSLLogger.fine(
   835                     "Cannot initialize algorithm constraints checker: " + cpve);
   834                     "Cannot initialize algorithm constraints checker", cpve);
   836             }
   835             }
   837 
   836 
   838             return false;
   837             return false;
   839         }
   838         }
   840 
   839 
   843             Certificate cert = chain[i];
   842             Certificate cert = chain[i];
   844             try {
   843             try {
   845                 // We don't care about the unresolved critical extensions.
   844                 // We don't care about the unresolved critical extensions.
   846                 checker.check(cert, Collections.<String>emptySet());
   845                 checker.check(cert, Collections.<String>emptySet());
   847             } catch (CertPathValidatorException cpve) {
   846             } catch (CertPathValidatorException cpve) {
   848                 if (useDebug) {
   847                 if (SSLLogger.isOn && SSLLogger.isOn("keymanager")) {
   849                     debug.println("Certificate (" + cert +
   848                     SSLLogger.fine("Certificate does not conform to " +
   850                         ") does not conform to algorithm constraints: " + cpve);
   849                             "algorithm constraints", cert, cpve);
   851                 }
   850                 }
   852 
   851 
   853                 return false;
   852                 return false;
   854             }
   853             }
   855         }
   854         }
   856 
   855 
   857         return true;
   856         return true;
   858     }
   857     }
   859 
       
   860 }
   858 }