< prev index next >

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

Print this page


   1 /*
   2  * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   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
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package sun.security.ssl;
  27 
  28 import java.lang.ref.WeakReference;
  29 import java.io.*;
  30 import java.util.*;
  31 
  32 import java.security.*;
  33 import java.security.cert.*;
  34 import java.security.cert.Certificate;
  35 
  36 import sun.security.action.*;
  37 import sun.security.validator.TrustStoreUtil;
  38 
  39 /**
  40  * Collection of static utility methods to manage the default trusted KeyStores
  41  * effectively.
  42  */
  43 final class TrustStoreManager {
  44     private static final Debug debug = Debug.getInstance("ssl");
  45 
  46     // A singleton service to manage the default trusted KeyStores effectively.
  47     private static final TrustAnchorManager tam = new TrustAnchorManager();
  48 
  49     // Restrict instantiation of this class.
  50     private TrustStoreManager() {
  51         // empty
  52     }
  53 
  54     /**
  55      * Return an unmodifiable set of all trusted X509Certificates contained
  56      * in the default trusted KeyStore.
  57      */
  58     public static Set<X509Certificate> getTrustedCerts() throws Exception {
  59         return tam.getTrustedCerts(TrustStoreDescriptor.createInstance());
  60     }
  61 
  62     /**
  63      * Return an instance of the default trusted KeyStore.
  64      */


  95 
  96         // the password used for the trust store
  97         private final String storePassword;
  98 
  99         // the File object of the trust store
 100         private final File storeFile;
 101 
 102         // the last modified time of the store
 103         private final long lastModified;
 104 
 105         private TrustStoreDescriptor(String storeName, String storeType,
 106                 String storeProvider, String storePassword,
 107                 File storeFile, long lastModified) {
 108             this.storeName = storeName;
 109             this.storeType = storeType;
 110             this.storeProvider = storeProvider;
 111             this.storePassword = storePassword;
 112             this.storeFile = storeFile;
 113             this.lastModified = lastModified;
 114 
 115             if (debug != null && Debug.isOn("trustmanager")) {
 116                 System.out.println(
 117                     "trustStore is: " + storeName + "\n" +
 118                     "trustStore type is: " + storeType + "\n" +
 119                     "trustStore provider is: " + storeProvider + "\n" +
 120                     "the last modified time is: " + (new Date(lastModified)));
 121             }
 122         }
 123 
 124         /**
 125          * Create an instance of TrustStoreDescriptor for the default
 126          * trusted KeyStore.
 127          */

 128         static TrustStoreDescriptor createInstance() {
 129              return AccessController.doPrivileged(new PrivilegedAction<>() {

 130 
 131                 @Override
 132                 public TrustStoreDescriptor run() {
 133                     // Get the system properties for trust store.
 134                     String storePropName = System.getProperty(
 135                             "javax.net.ssl.trustStore", jsseDefaultStore);
 136                     String storePropType = System.getProperty(
 137                             "javax.net.ssl.trustStoreType",
 138                             KeyStore.getDefaultType());
 139                     String storePropProvider = System.getProperty(
 140                             "javax.net.ssl.trustStoreProvider", "");
 141                     String storePropPassword = System.getProperty(
 142                             "javax.net.ssl.trustStorePassword", "");
 143 
 144                     String temporaryName = "";
 145                     File temporaryFile = null;
 146                     long temporaryTime = 0L;
 147                     if (!"NONE".equals(storePropName)) {
 148                         String[] fileNames =
 149                                 new String[] {storePropName, defaultStore};
 150                         for (String fileName : fileNames) {
 151                             File f = new File(fileName);
 152                             if (f.isFile() && f.canRead()) {
 153                                 temporaryName = fileName;;
 154                                 temporaryFile = f;
 155                                 temporaryTime = f.lastModified();
 156 
 157                                 break;
 158                             }
 159 
 160                             // Not break, the file is inaccessible.
 161                             if (debug != null &&
 162                                     Debug.isOn("trustmanager")) {
 163                                 System.out.println(
 164                                     "Inaccessible trust store: " +
 165                                     storePropName);
 166                             }
 167                         }
 168                     } else {
 169                         temporaryName = storePropName;
 170                     }
 171 
 172                     return new TrustStoreDescriptor(
 173                             temporaryName, storePropType, storePropProvider,
 174                             storePropPassword, temporaryFile, temporaryTime);
 175                 }
 176             });
 177         }
 178 
 179         @Override
 180         public boolean equals(Object obj) {
 181             if (obj == this) {
 182                 return true;
 183             }


 250             this.descriptor = null;
 251             this.ksRef = new WeakReference<>(null);
 252             this.csRef = new WeakReference<>(null);
 253         }
 254 
 255         /**
 256          * Get the default trusted KeyStore with the specified descriptor.
 257          *
 258          * @return null if the underlying KeyStore is not available.
 259          */
 260         synchronized KeyStore getKeyStore(
 261                 TrustStoreDescriptor descriptor) throws Exception {
 262 
 263             TrustStoreDescriptor temporaryDesc = this.descriptor;
 264             KeyStore ks = ksRef.get();
 265             if ((ks != null) && descriptor.equals(temporaryDesc)) {
 266                 return ks;
 267             }
 268 
 269             // Reload a new key store.
 270             if ((debug != null) && Debug.isOn("trustmanager")) {
 271                 System.out.println("Reload the trust store");
 272             }
 273 
 274             ks = loadKeyStore(descriptor);
 275             this.descriptor = descriptor;
 276             this.ksRef = new WeakReference<>(ks);
 277 
 278             return ks;
 279         }
 280 
 281         /**
 282          * Get trusted certificates in the default trusted KeyStore with
 283          * the specified descriptor.
 284          *
 285          * @return empty collection if the underlying KeyStore is not available.
 286          */
 287         synchronized Set<X509Certificate> getTrustedCerts(
 288                 TrustStoreDescriptor descriptor) throws Exception {
 289 
 290             KeyStore ks = null;
 291             TrustStoreDescriptor temporaryDesc = this.descriptor;
 292             Set<X509Certificate> certs = csRef.get();
 293             if (certs != null) {
 294                 if (descriptor.equals(temporaryDesc)) {
 295                     return certs;
 296                 } else {
 297                     // Use the new descriptor.
 298                     this.descriptor = descriptor;
 299                 }
 300             } else {
 301                 // Try to use the cached store at first.
 302                 if (descriptor.equals(temporaryDesc)) {
 303                     ks = ksRef.get();
 304                 } else {
 305                     // Use the new descriptor.
 306                     this.descriptor = descriptor;
 307                 }
 308             }
 309 
 310             // Reload the trust store if needed.
 311             if (ks == null) {
 312                 if ((debug != null) && Debug.isOn("trustmanager")) {
 313                     System.out.println("Reload the trust store");
 314                 }
 315                 ks = loadKeyStore(descriptor);
 316             }
 317 
 318             // Reload trust certs from the key store.
 319             if ((debug != null) && Debug.isOn("trustmanager")) {
 320                 System.out.println("Reload trust certs");
 321             }
 322 
 323             certs = loadTrustedCerts(ks);
 324             if ((debug != null) && Debug.isOn("trustmanager")) {
 325                 System.out.println("Reloaded " + certs.size() + " trust certs");
 326             }
 327 
 328             // Note that as ks is a local variable, it is not
 329             // necessary to add it to the ksRef weak reference.
 330             this.csRef = new WeakReference<>(certs);
 331 
 332             return certs;
 333         }
 334 
 335         /**
 336          * Load the KeyStore as described in the specified descriptor.
 337          */
 338         private static KeyStore loadKeyStore(
 339                 TrustStoreDescriptor descriptor) throws Exception {
 340             if (!"NONE".equals(descriptor.storeName) &&
 341                     descriptor.storeFile == null) {
 342 
 343                 // No file available, no KeyStore available.
 344                 if (debug != null && Debug.isOn("trustmanager")) {
 345                     System.out.println("No available key store");
 346                 }
 347 
 348                 return null;
 349             }
 350 
 351             KeyStore ks;
 352             if (descriptor.storeProvider.isEmpty()) {
 353                 ks = KeyStore.getInstance(descriptor.storeType);
 354             } else {
 355                 ks = KeyStore.getInstance(
 356                         descriptor.storeType, descriptor.storeProvider);
 357             }
 358 
 359             char[] password = null;
 360             if (!descriptor.storePassword.isEmpty()) {
 361                 password = descriptor.storePassword.toCharArray();
 362             }
 363 
 364             if (!"NONE".equals(descriptor.storeName)) {
 365                 try (FileInputStream fis = AccessController.doPrivileged(
 366                         new OpenFileInputStreamAction(descriptor.storeFile))) {
 367                     ks.load(fis, password);
 368                 } catch (FileNotFoundException fnfe) {
 369                     // No file available, no KeyStore available.
 370                     if (debug != null && Debug.isOn("trustmanager")) {
 371                         System.out.println(
 372                             "Not available key store: " + descriptor.storeName);
 373                     }
 374 
 375                     return null;
 376                 }
 377             } else {
 378                 ks.load(null, password);
 379             }
 380 
 381             return ks;
 382         }
 383 
 384         /**
 385          * Load trusted certificates from the specified KeyStore.
 386          */
 387         private static Set<X509Certificate> loadTrustedCerts(KeyStore ks) {
 388             if (ks == null) {
 389                 return Collections.<X509Certificate>emptySet();
 390             }
 391 
   1 /*
   2  * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   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
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package sun.security.ssl;
  27 

  28 import java.io.*;
  29 import java.lang.ref.WeakReference;

  30 import java.security.*;
  31 import java.security.cert.*;
  32 import java.util.*;

  33 import sun.security.action.*;
  34 import sun.security.validator.TrustStoreUtil;
  35 
  36 /**
  37  * Collection of static utility methods to manage the default trusted KeyStores
  38  * effectively.
  39  */
  40 final class TrustStoreManager {

  41 
  42     // A singleton service to manage the default trusted KeyStores effectively.
  43     private static final TrustAnchorManager tam = new TrustAnchorManager();
  44 
  45     // Restrict instantiation of this class.
  46     private TrustStoreManager() {
  47         // empty
  48     }
  49 
  50     /**
  51      * Return an unmodifiable set of all trusted X509Certificates contained
  52      * in the default trusted KeyStore.
  53      */
  54     public static Set<X509Certificate> getTrustedCerts() throws Exception {
  55         return tam.getTrustedCerts(TrustStoreDescriptor.createInstance());
  56     }
  57 
  58     /**
  59      * Return an instance of the default trusted KeyStore.
  60      */


  91 
  92         // the password used for the trust store
  93         private final String storePassword;
  94 
  95         // the File object of the trust store
  96         private final File storeFile;
  97 
  98         // the last modified time of the store
  99         private final long lastModified;
 100 
 101         private TrustStoreDescriptor(String storeName, String storeType,
 102                 String storeProvider, String storePassword,
 103                 File storeFile, long lastModified) {
 104             this.storeName = storeName;
 105             this.storeType = storeType;
 106             this.storeProvider = storeProvider;
 107             this.storePassword = storePassword;
 108             this.storeFile = storeFile;
 109             this.lastModified = lastModified;
 110 
 111             if (SSLLogger.isOn && SSLLogger.isOn("trustmanager")) {
 112                 SSLLogger.fine(
 113                     "trustStore is: " + storeName + "\n" +
 114                     "trustStore type is: " + storeType + "\n" +
 115                     "trustStore provider is: " + storeProvider + "\n" +
 116                     "the last modified time is: " + (new Date(lastModified)));
 117             }
 118         }
 119 
 120         /**
 121          * Create an instance of TrustStoreDescriptor for the default
 122          * trusted KeyStore.
 123          */
 124         @SuppressWarnings("Convert2Lambda")
 125         static TrustStoreDescriptor createInstance() {
 126              return AccessController.doPrivileged(
 127                     new PrivilegedAction<TrustStoreDescriptor>() {
 128 
 129                 @Override
 130                 public TrustStoreDescriptor run() {
 131                     // Get the system properties for trust store.
 132                     String storePropName = System.getProperty(
 133                             "javax.net.ssl.trustStore", jsseDefaultStore);
 134                     String storePropType = System.getProperty(
 135                             "javax.net.ssl.trustStoreType",
 136                             KeyStore.getDefaultType());
 137                     String storePropProvider = System.getProperty(
 138                             "javax.net.ssl.trustStoreProvider", "");
 139                     String storePropPassword = System.getProperty(
 140                             "javax.net.ssl.trustStorePassword", "");
 141 
 142                     String temporaryName = "";
 143                     File temporaryFile = null;
 144                     long temporaryTime = 0L;
 145                     if (!"NONE".equals(storePropName)) {
 146                         String[] fileNames =
 147                                 new String[] {storePropName, defaultStore};
 148                         for (String fileName : fileNames) {
 149                             File f = new File(fileName);
 150                             if (f.isFile() && f.canRead()) {
 151                                 temporaryName = fileName;;
 152                                 temporaryFile = f;
 153                                 temporaryTime = f.lastModified();
 154 
 155                                 break;
 156                             }
 157 
 158                             // Not break, the file is inaccessible.
 159                             if (SSLLogger.isOn &&
 160                                     SSLLogger.isOn("trustmanager")) {
 161                                 SSLLogger.fine(
 162                                         "Inaccessible trust store: " +
 163                                         storePropName);
 164                             }
 165                         }
 166                     } else {
 167                         temporaryName = storePropName;
 168                     }
 169 
 170                     return new TrustStoreDescriptor(
 171                             temporaryName, storePropType, storePropProvider,
 172                             storePropPassword, temporaryFile, temporaryTime);
 173                 }
 174             });
 175         }
 176 
 177         @Override
 178         public boolean equals(Object obj) {
 179             if (obj == this) {
 180                 return true;
 181             }


 248             this.descriptor = null;
 249             this.ksRef = new WeakReference<>(null);
 250             this.csRef = new WeakReference<>(null);
 251         }
 252 
 253         /**
 254          * Get the default trusted KeyStore with the specified descriptor.
 255          *
 256          * @return null if the underlying KeyStore is not available.
 257          */
 258         synchronized KeyStore getKeyStore(
 259                 TrustStoreDescriptor descriptor) throws Exception {
 260 
 261             TrustStoreDescriptor temporaryDesc = this.descriptor;
 262             KeyStore ks = ksRef.get();
 263             if ((ks != null) && descriptor.equals(temporaryDesc)) {
 264                 return ks;
 265             }
 266 
 267             // Reload a new key store.
 268             if (SSLLogger.isOn && SSLLogger.isOn("trustmanager")) {
 269                 SSLLogger.fine("Reload the trust store");
 270             }
 271 
 272             ks = loadKeyStore(descriptor);
 273             this.descriptor = descriptor;
 274             this.ksRef = new WeakReference<>(ks);
 275 
 276             return ks;
 277         }
 278 
 279         /**
 280          * Get trusted certificates in the default trusted KeyStore with
 281          * the specified descriptor.
 282          *
 283          * @return empty collection if the underlying KeyStore is not available.
 284          */
 285         synchronized Set<X509Certificate> getTrustedCerts(
 286                 TrustStoreDescriptor descriptor) throws Exception {
 287 
 288             KeyStore ks = null;
 289             TrustStoreDescriptor temporaryDesc = this.descriptor;
 290             Set<X509Certificate> certs = csRef.get();
 291             if (certs != null) {
 292                 if (descriptor.equals(temporaryDesc)) {
 293                     return certs;
 294                 } else {
 295                     // Use the new descriptor.
 296                     this.descriptor = descriptor;
 297                 }
 298             } else {
 299                 // Try to use the cached store at first.
 300                 if (descriptor.equals(temporaryDesc)) {
 301                     ks = ksRef.get();
 302                 } else {
 303                     // Use the new descriptor.
 304                     this.descriptor = descriptor;
 305                 }
 306             }
 307 
 308             // Reload the trust store if needed.
 309             if (ks == null) {
 310                 if (SSLLogger.isOn && SSLLogger.isOn("trustmanager")) {
 311                     SSLLogger.fine("Reload the trust store");
 312                 }
 313                 ks = loadKeyStore(descriptor);
 314             }
 315 
 316             // Reload trust certs from the key store.
 317             if (SSLLogger.isOn && SSLLogger.isOn("trustmanager")) {
 318                 SSLLogger.fine("Reload trust certs");
 319             }
 320 
 321             certs = loadTrustedCerts(ks);
 322             if (SSLLogger.isOn && SSLLogger.isOn("trustmanager")) {
 323                 SSLLogger.fine("Reloaded " + certs.size() + " trust certs");
 324             }
 325 
 326             // Note that as ks is a local variable, it is not
 327             // necessary to add it to the ksRef weak reference.
 328             this.csRef = new WeakReference<>(certs);
 329 
 330             return certs;
 331         }
 332 
 333         /**
 334          * Load the the KeyStore as described in the specified descriptor.
 335          */
 336         private static KeyStore loadKeyStore(
 337                 TrustStoreDescriptor descriptor) throws Exception {
 338             if (!"NONE".equals(descriptor.storeName) &&
 339                     descriptor.storeFile == null) {
 340 
 341                 // No file available, no KeyStore available.
 342                 if (SSLLogger.isOn && SSLLogger.isOn("trustmanager")) {
 343                     SSLLogger.fine("No available key store");
 344                 }
 345 
 346                 return null;
 347             }
 348 
 349             KeyStore ks;
 350             if (descriptor.storeProvider.isEmpty()) {
 351                 ks = KeyStore.getInstance(descriptor.storeType);
 352             } else {
 353                 ks = KeyStore.getInstance(
 354                         descriptor.storeType, descriptor.storeProvider);
 355             }
 356 
 357             char[] password = null;
 358             if (!descriptor.storePassword.isEmpty()) {
 359                 password = descriptor.storePassword.toCharArray();
 360             }
 361 
 362             if (!"NONE".equals(descriptor.storeName)) {
 363                 try (FileInputStream fis = AccessController.doPrivileged(
 364                         new OpenFileInputStreamAction(descriptor.storeFile))) {
 365                     ks.load(fis, password);
 366                 } catch (FileNotFoundException fnfe) {
 367                     // No file available, no KeyStore available.
 368                     if (SSLLogger.isOn && SSLLogger.isOn("trustmanager")) {
 369                         SSLLogger.fine(
 370                             "Not available key store: " + descriptor.storeName);
 371                     }
 372 
 373                     return null;
 374                 }
 375             } else {
 376                 ks.load(null, password);
 377             }
 378 
 379             return ks;
 380         }
 381 
 382         /**
 383          * Load trusted certificates from the specified KeyStore.
 384          */
 385         private static Set<X509Certificate> loadTrustedCerts(KeyStore ks) {
 386             if (ks == null) {
 387                 return Collections.<X509Certificate>emptySet();
 388             }
 389 
< prev index next >