8129988: JSSE should create a single instance of the cacerts KeyStore
Reviewed-by: mullan
--- a/jdk/src/java.base/share/classes/sun/security/ssl/SSLContextImpl.java Fri Jan 06 01:09:03 2017 +0000
+++ b/jdk/src/java.base/share/classes/sun/security/ssl/SSLContextImpl.java Fri Jan 06 02:03:47 2017 +0000
@@ -935,12 +935,20 @@
}
private static TrustManager[] getTrustManagers() throws Exception {
- KeyStore ks =
- TrustManagerFactoryImpl.getCacertsKeyStore("defaultctx");
+ TrustManagerFactory tmf = TrustManagerFactory.getInstance(
+ TrustManagerFactory.getDefaultAlgorithm());
+ if ("SunJSSE".equals(tmf.getProvider().getName())) {
+ // The implementation will load the default KeyStore
+ // automatically. Cached trust materials may be used
+ // for performance improvement.
+ tmf.init((KeyStore)null);
+ } else {
+ // Use the explicitly specified KeyStore for third party's
+ // TrustManagerFactory implementation.
+ KeyStore ks = TrustStoreManager.getTrustedKeyStore();
+ tmf.init(ks);
+ }
- TrustManagerFactory tmf = TrustManagerFactory.getInstance(
- TrustManagerFactory.getDefaultAlgorithm());
- tmf.init(ks);
return tmf.getTrustManagers();
}
--- a/jdk/src/java.base/share/classes/sun/security/ssl/TrustManagerFactoryImpl.java Fri Jan 06 01:09:03 2017 +0000
+++ b/jdk/src/java.base/share/classes/sun/security/ssl/TrustManagerFactoryImpl.java Fri Jan 06 02:03:47 2017 +0000
@@ -32,6 +32,7 @@
import javax.net.ssl.*;
import sun.security.validator.Validator;
+import sun.security.validator.TrustStoreUtil;
abstract class TrustManagerFactoryImpl extends TrustManagerFactorySpi {
@@ -47,7 +48,7 @@
protected void engineInit(KeyStore ks) throws KeyStoreException {
if (ks == null) {
try {
- ks = getCacertsKeyStore("trustmanager");
+ trustManager = getInstance(TrustStoreManager.getTrustedCerts());
} catch (SecurityException se) {
// eat security exceptions but report other throwables
if (debug != null && Debug.isOn("trustmanager")) {
@@ -72,14 +73,17 @@
"SunX509: skip default keystore: " + e);
}
throw new KeyStoreException(
- "problem accessing trust store" + e);
+ "problem accessing trust store", e);
}
+ } else {
+ trustManager = getInstance(TrustStoreUtil.getTrustedCerts(ks));
}
- trustManager = getInstance(ks);
+
isInitialized = true;
}
- abstract X509TrustManager getInstance(KeyStore ks) throws KeyStoreException;
+ abstract X509TrustManager getInstance(
+ Collection<X509Certificate> trustedCerts);
abstract X509TrustManager getInstance(ManagerFactoryParameters spec)
throws InvalidAlgorithmParameterException;
@@ -126,126 +130,14 @@
});
}
- /**
- * Returns the keystore with the configured CA certificates.
- */
- static KeyStore getCacertsKeyStore(String dbgname) throws Exception
- {
- String storeFileName = null;
- File storeFile = null;
- FileInputStream fis = null;
- String defaultTrustStoreType;
- String defaultTrustStoreProvider;
- final HashMap<String,String> props = new HashMap<>();
- final String sep = File.separator;
- KeyStore ks = null;
-
- AccessController.doPrivileged(new PrivilegedExceptionAction<Void>() {
- @Override
- public Void run() throws Exception {
- props.put("trustStore", System.getProperty(
- "javax.net.ssl.trustStore"));
- props.put("javaHome", System.getProperty(
- "java.home"));
- props.put("trustStoreType", System.getProperty(
- "javax.net.ssl.trustStoreType",
- KeyStore.getDefaultType()));
- props.put("trustStoreProvider", System.getProperty(
- "javax.net.ssl.trustStoreProvider", ""));
- props.put("trustStorePasswd", System.getProperty(
- "javax.net.ssl.trustStorePassword", ""));
- return null;
- }
- });
-
- /*
- * Try:
- * javax.net.ssl.trustStore (if this variable exists, stop)
- * jssecacerts
- * cacerts
- *
- * If none exists, we use an empty keystore.
- */
-
- try {
- storeFileName = props.get("trustStore");
- if (!"NONE".equals(storeFileName)) {
- if (storeFileName != null) {
- storeFile = new File(storeFileName);
- fis = getFileInputStream(storeFile);
- } else {
- String javaHome = props.get("javaHome");
- storeFile = new File(javaHome + sep + "lib" + sep
- + "security" + sep +
- "jssecacerts");
- if ((fis = getFileInputStream(storeFile)) == null) {
- storeFile = new File(javaHome + sep + "lib" + sep
- + "security" + sep +
- "cacerts");
- fis = getFileInputStream(storeFile);
- }
- }
-
- if (fis != null) {
- storeFileName = storeFile.getPath();
- } else {
- storeFileName = "No File Available, using empty keystore.";
- }
- }
-
- defaultTrustStoreType = props.get("trustStoreType");
- defaultTrustStoreProvider = props.get("trustStoreProvider");
- if (debug != null && Debug.isOn(dbgname)) {
- System.out.println("trustStore is: " + storeFileName);
- System.out.println("trustStore type is : " +
- defaultTrustStoreType);
- System.out.println("trustStore provider is : " +
- defaultTrustStoreProvider);
- }
-
- /*
- * Try to initialize trust store.
- */
- if (defaultTrustStoreType.length() != 0) {
- if (debug != null && Debug.isOn(dbgname)) {
- System.out.println("init truststore");
- }
- if (defaultTrustStoreProvider.length() == 0) {
- ks = KeyStore.getInstance(defaultTrustStoreType);
- } else {
- ks = KeyStore.getInstance(defaultTrustStoreType,
- defaultTrustStoreProvider);
- }
- char[] passwd = null;
- String defaultTrustStorePassword =
- props.get("trustStorePasswd");
- if (defaultTrustStorePassword.length() != 0)
- passwd = defaultTrustStorePassword.toCharArray();
-
- // if trustStore is NONE, fis will be null
- ks.load(fis, passwd);
-
- // Zero out the temporary password storage
- if (passwd != null) {
- for (int i = 0; i < passwd.length; i++) {
- passwd[i] = (char)0;
- }
- }
- }
- } finally {
- if (fis != null) {
- fis.close();
- }
+ public static final class SimpleFactory extends TrustManagerFactoryImpl {
+ @Override
+ X509TrustManager getInstance(
+ Collection<X509Certificate> trustedCerts) {
+ return new X509TrustManagerImpl(
+ Validator.TYPE_SIMPLE, trustedCerts);
}
- return ks;
- }
-
- public static final class SimpleFactory extends TrustManagerFactoryImpl {
- @Override
- X509TrustManager getInstance(KeyStore ks) throws KeyStoreException {
- return new X509TrustManagerImpl(Validator.TYPE_SIMPLE, ks);
- }
@Override
X509TrustManager getInstance(ManagerFactoryParameters spec)
throws InvalidAlgorithmParameterException {
@@ -253,13 +145,15 @@
("SunX509 TrustManagerFactory does not use "
+ "ManagerFactoryParameters");
}
- }
+ }
public static final class PKIXFactory extends TrustManagerFactoryImpl {
@Override
- X509TrustManager getInstance(KeyStore ks) throws KeyStoreException {
- return new X509TrustManagerImpl(Validator.TYPE_PKIX, ks);
+ X509TrustManager getInstance(
+ Collection<X509Certificate> trustedCerts) {
+ return new X509TrustManagerImpl(Validator.TYPE_PKIX, trustedCerts);
}
+
@Override
X509TrustManager getInstance(ManagerFactoryParameters spec)
throws InvalidAlgorithmParameterException {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/classes/sun/security/ssl/TrustStoreManager.java Fri Jan 06 02:03:47 2017 +0000
@@ -0,0 +1,395 @@
+/*
+ * Copyright (c) 2016, 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.lang.ref.WeakReference;
+import java.io.*;
+import java.util.*;
+
+import java.security.*;
+import java.security.cert.*;
+import java.security.cert.Certificate;
+
+import sun.security.action.*;
+import sun.security.validator.TrustStoreUtil;
+
+/**
+ * Collection of static utility methods to manage the default trusted KeyStores
+ * effectively.
+ */
+final class TrustStoreManager {
+ private static final Debug debug = Debug.getInstance("ssl");
+
+ // A singleton service to manage the default trusted KeyStores effectively.
+ private static final TrustAnchorManager tam = new TrustAnchorManager();
+
+ // Restrict instantiation of this class.
+ private TrustStoreManager() {
+ // empty
+ }
+
+ /**
+ * Return an unmodifiable set of all trusted X509Certificates contained
+ * in the default trusted KeyStore.
+ */
+ public static Set<X509Certificate> getTrustedCerts() throws Exception {
+ return tam.getTrustedCerts(TrustStoreDescriptor.createInstance());
+ }
+
+ /**
+ * Return an instance of the default trusted KeyStore.
+ */
+ public static KeyStore getTrustedKeyStore() throws Exception {
+ return tam.getKeyStore(TrustStoreDescriptor.createInstance());
+ }
+
+ /**
+ * A descriptor of the default trusted KeyStore.
+ *
+ * The preference of the default trusted KeyStore is:
+ * javax.net.ssl.trustStore
+ * jssecacerts
+ * cacerts
+ */
+ private static final class TrustStoreDescriptor {
+ private static final String fileSep = File.separator;
+ private static final String defaultStorePath =
+ GetPropertyAction.privilegedGetProperty("java.home") +
+ fileSep + "lib" + fileSep + "security";
+ private static final String defaultStore =
+ defaultStorePath + fileSep + "cacerts";
+ private static final String jsseDefaultStore =
+ defaultStorePath + fileSep + "jssecacerts";
+
+ // the trust store name
+ private final String storeName;
+
+ // the trust store type, JKS/PKCS12
+ private final String storeType;
+
+ // the provider of the trust store
+ private final String storeProvider;
+
+ // the password used for the trust store
+ private final String storePassword;
+
+ // the File object of the trust store
+ private final File storeFile;
+
+ // the last modified time of the store
+ private final long lastModified;
+
+ private TrustStoreDescriptor(String storeName, String storeType,
+ String storeProvider, String storePassword,
+ File storeFile, long lastModified) {
+ this.storeName = storeName;
+ this.storeType = storeType;
+ this.storeProvider = storeProvider;
+ this.storePassword = storePassword;
+ this.storeFile = storeFile;
+ this.lastModified = lastModified;
+
+ if (debug != null && Debug.isOn("trustmanager")) {
+ System.out.println(
+ "trustStore is: " + storeName + "\n" +
+ "trustStore type is: " + storeType + "\n" +
+ "trustStore provider is: " + storeProvider + "\n" +
+ "the last modified time is: " + (new Date(lastModified)));
+ }
+ }
+
+ /**
+ * Create an instance of TrustStoreDescriptor for the default
+ * trusted KeyStore.
+ */
+ static TrustStoreDescriptor createInstance() {
+ return AccessController.doPrivileged(new PrivilegedAction<>() {
+
+ @Override
+ public TrustStoreDescriptor run() {
+ // Get the system properties for trust store.
+ String storePropName = System.getProperty(
+ "javax.net.ssl.trustStore", jsseDefaultStore);
+ String storePropType = System.getProperty(
+ "javax.net.ssl.trustStoreType",
+ KeyStore.getDefaultType());
+ String storePropProvider = System.getProperty(
+ "javax.net.ssl.trustStoreProvider", "");
+ String storePropPassword = System.getProperty(
+ "javax.net.ssl.trustStorePassword", "");
+
+ String temporaryName = "";
+ File temporaryFile = null;
+ long temporaryTime = 0L;
+ if (!"NONE".equals(storePropName)) {
+ String[] fileNames =
+ new String[] {storePropName, defaultStore};
+ for (String fileName : fileNames) {
+ File f = new File(fileName);
+ if (f.isFile() && f.canRead()) {
+ temporaryName = fileName;;
+ temporaryFile = f;
+ temporaryTime = f.lastModified();
+
+ break;
+ }
+
+ // Not break, the file is inaccessible.
+ if (debug != null &&
+ Debug.isOn("trustmanager")) {
+ System.out.println(
+ "Inaccessible trust store: " +
+ storePropName);
+ }
+ }
+ } else {
+ temporaryName = storePropName;
+ }
+
+ return new TrustStoreDescriptor(
+ temporaryName, storePropType, storePropProvider,
+ storePropPassword, temporaryFile, temporaryTime);
+ }
+ });
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == this) {
+ return true;
+ }
+
+ if (obj instanceof TrustStoreDescriptor) {
+ TrustStoreDescriptor that = (TrustStoreDescriptor)obj;
+ return ((this.lastModified == that.lastModified) &&
+ Objects.equals(this.storeName, that.storeName) &&
+ Objects.equals(this.storeType, that.storeType) &&
+ Objects.equals(this.storeProvider, that.storeProvider));
+ }
+
+ return false;
+ }
+
+
+ // Please be careful if computing security-sensitive attributes'
+ // hash code. For example the storePassword should not be computed.
+ @Override
+ public int hashCode() {
+ int result = 17;
+
+ if (storeName != null && !storeName.isEmpty()) {
+ result = 31 * result + storeName.hashCode();
+ }
+
+ if (storeType != null && !storeType.isEmpty()) {
+ result = 31 * result + storeType.hashCode();
+ }
+
+ if (storeProvider != null && !storeProvider.isEmpty()) {
+ result = 31 * result + storeProvider.hashCode();
+ }
+
+ if (storeFile != null) {
+ result = 31 * result + storeFile.hashCode();
+ }
+
+ if (lastModified != 0L) {
+ result = (int)(31 * result + lastModified);
+ }
+
+ return result;
+ }
+ }
+
+ /**
+ * The trust anchors manager used to expedite the performance.
+ *
+ * This class can be used to provide singleton services to access default
+ * trust KeyStore more effectively.
+ */
+ private static final class TrustAnchorManager {
+ // Last trust store descriptor.
+ private TrustStoreDescriptor descriptor;
+
+ // The key store used for the trust anchors.
+ //
+ // Use weak reference so that the heavy loaded KeyStore object can
+ // be atomically cleared, and reloaded if needed.
+ private WeakReference<KeyStore> ksRef;
+
+ // The trusted X.509 certificates in the key store.
+ //
+ // Use weak reference so that the heavy loaded certificates collection
+ // objects can be atomically cleared, and reloaded if needed.
+ private WeakReference<Set<X509Certificate>> csRef;
+
+ private TrustAnchorManager() {
+ this.descriptor = null;
+ this.ksRef = new WeakReference<>(null);
+ this.csRef = new WeakReference<>(null);
+ }
+
+ /**
+ * Get the default trusted KeyStore with the specified descriptor.
+ *
+ * @return null if the underlying KeyStore is not available.
+ */
+ synchronized KeyStore getKeyStore(
+ TrustStoreDescriptor descriptor) throws Exception {
+
+ TrustStoreDescriptor temporaryDesc = this.descriptor;
+ KeyStore ks = ksRef.get();
+ if ((ks != null) && descriptor.equals(temporaryDesc)) {
+ return ks;
+ }
+
+ // Reload a new key store.
+ if ((debug != null) && Debug.isOn("trustmanager")) {
+ System.out.println("Reload the trust store");
+ }
+
+ ks = loadKeyStore(descriptor);
+ this.descriptor = descriptor;
+ this.ksRef = new WeakReference<>(ks);
+
+ return ks;
+ }
+
+ /**
+ * Get trusted certificates in the default trusted KeyStore with
+ * the specified descriptor.
+ *
+ * @return empty collection if the underlying KeyStore is not available.
+ */
+ synchronized Set<X509Certificate> getTrustedCerts(
+ TrustStoreDescriptor descriptor) throws Exception {
+
+ KeyStore ks = null;
+ TrustStoreDescriptor temporaryDesc = this.descriptor;
+ Set<X509Certificate> certs = csRef.get();
+ if (certs != null) {
+ if (descriptor.equals(temporaryDesc)) {
+ return certs;
+ } else {
+ // Use the new descriptor.
+ this.descriptor = descriptor;
+ }
+ } else {
+ // Try to use the cached store at first.
+ if (descriptor.equals(temporaryDesc)) {
+ ks = ksRef.get();
+ } else {
+ // Use the new descriptor.
+ this.descriptor = descriptor;
+ }
+ }
+
+ // Reload the trust store if needed.
+ if (ks == null) {
+ if ((debug != null) && Debug.isOn("trustmanager")) {
+ System.out.println("Reload the trust store");
+ }
+ ks = loadKeyStore(descriptor);
+ }
+
+ // Reload trust certs from the key store.
+ if ((debug != null) && Debug.isOn("trustmanager")) {
+ System.out.println("Reload trust certs");
+ }
+
+ certs = loadTrustedCerts(ks);
+ if ((debug != null) && Debug.isOn("trustmanager")) {
+ System.out.println("Reloaded " + certs.size() + " trust certs");
+ }
+
+ // Note that as ks is a local variable, it is not
+ // necessary to add it to the ksRef weak reference.
+ this.csRef = new WeakReference<>(certs);
+
+ return certs;
+ }
+
+ /**
+ * Load the the KeyStore as described in the specified descriptor.
+ */
+ private static KeyStore loadKeyStore(
+ TrustStoreDescriptor descriptor) throws Exception {
+ if (!"NONE".equals(descriptor.storeName) &&
+ descriptor.storeFile == null) {
+
+ // No file available, no KeyStore available.
+ if (debug != null && Debug.isOn("trustmanager")) {
+ System.out.println("No available key store");
+ }
+
+ return null;
+ }
+
+ KeyStore ks;
+ if (descriptor.storeProvider.isEmpty()) {
+ ks = KeyStore.getInstance(descriptor.storeType);
+ } else {
+ ks = KeyStore.getInstance(
+ descriptor.storeType, descriptor.storeProvider);
+ }
+
+ char[] password = null;
+ if (!descriptor.storePassword.isEmpty()) {
+ password = descriptor.storePassword.toCharArray();
+ }
+
+ if (!"NONE".equals(descriptor.storeName)) {
+ try (FileInputStream fis = AccessController.doPrivileged(
+ new OpenFileInputStreamAction(descriptor.storeFile))) {
+ ks.load(fis, password);
+ } catch (FileNotFoundException fnfe) {
+ // No file available, no KeyStore available.
+ if (debug != null && Debug.isOn("trustmanager")) {
+ System.out.println(
+ "Not available key store: " + descriptor.storeName);
+ }
+
+ return null;
+ }
+ } else {
+ ks.load(null, password);
+ }
+
+ return ks;
+ }
+
+ /**
+ * Load trusted certificates from the specified KeyStore.
+ */
+ private static Set<X509Certificate> loadTrustedCerts(KeyStore ks) {
+ if (ks == null) {
+ return Collections.<X509Certificate>emptySet();
+ }
+
+ return TrustStoreUtil.getTrustedCerts(ks);
+ }
+ }
+}
--- a/jdk/src/java.base/share/classes/sun/security/ssl/X509TrustManagerImpl.java Fri Jan 06 01:09:03 2017 +0000
+++ b/jdk/src/java.base/share/classes/sun/security/ssl/X509TrustManagerImpl.java Fri Jan 06 02:03:47 2017 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, 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
@@ -68,16 +68,21 @@
private static final Debug debug = Debug.getInstance("ssl");
- X509TrustManagerImpl(String validatorType, KeyStore ks)
- throws KeyStoreException {
+ X509TrustManagerImpl(String validatorType,
+ Collection<X509Certificate> trustedCerts) {
+
this.validatorType = validatorType;
this.pkixParams = null;
- if (ks == null) {
+
+ if (trustedCerts == null) {
trustedCerts = Collections.<X509Certificate>emptySet();
- } else {
- trustedCerts = KeyStores.getTrustedCerts(ks);
}
- showTrustedCerts();
+
+ this.trustedCerts = trustedCerts;
+
+ if (debug != null && Debug.isOn("trustmanager")) {
+ showTrustedCerts();
+ }
}
X509TrustManagerImpl(String validatorType, PKIXBuilderParameters params) {
@@ -90,7 +95,10 @@
Validator v = getValidator(Validator.VAR_TLS_SERVER);
trustedCerts = v.getTrustedCertificates();
serverValidator = v;
- showTrustedCerts();
+
+ if (debug != null && Debug.isOn("trustmanager")) {
+ showTrustedCerts();
+ }
}
@Override
@@ -305,22 +313,20 @@
}
private void showTrustedCerts() {
- if (debug != null && Debug.isOn("trustmanager")) {
- for (X509Certificate cert : trustedCerts) {
- System.out.println("adding as trusted cert:");
- System.out.println(" Subject: "
- + cert.getSubjectX500Principal());
- System.out.println(" Issuer: "
- + cert.getIssuerX500Principal());
- System.out.println(" Algorithm: "
- + cert.getPublicKey().getAlgorithm()
- + "; Serial number: 0x"
- + cert.getSerialNumber().toString(16));
- System.out.println(" Valid from "
- + cert.getNotBefore() + " until "
- + cert.getNotAfter());
- System.out.println();
- }
+ for (X509Certificate cert : trustedCerts) {
+ System.out.println("adding as trusted cert:");
+ System.out.println(" Subject: "
+ + cert.getSubjectX500Principal());
+ System.out.println(" Issuer: "
+ + cert.getIssuerX500Principal());
+ System.out.println(" Algorithm: "
+ + cert.getPublicKey().getAlgorithm()
+ + "; Serial number: 0x"
+ + cert.getSerialNumber().toString(16));
+ System.out.println(" Valid from "
+ + cert.getNotBefore() + " until "
+ + cert.getNotAfter());
+ System.out.println();
}
}
--- a/jdk/src/java.base/share/classes/sun/security/validator/KeyStores.java Fri Jan 06 01:09:03 2017 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,120 +0,0 @@
-/*
- * Copyright (c) 2002, 2006, 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.validator;
-
-import java.io.*;
-import java.util.*;
-
-import java.security.*;
-import java.security.cert.*;
-import java.security.cert.Certificate;
-
-import sun.security.action.*;
-
-/**
- * Collection of static utility methods related to KeyStores.
- *
- * @author Andreas Sterbenz
- */
-public class KeyStores {
-
- private KeyStores() {
- // empty
- }
-
- // in the future, all accesses to the system cacerts keystore should
- // go through this class. but not right now.
-/*
- private static final String javaHome =
- (String)AccessController.doPrivileged(new GetPropertyAction("java.home"));
-
- private static final char SEP = File.separatorChar;
-
- private static KeyStore caCerts;
-
- private static KeyStore getKeyStore(String type, String name,
- char[] password) throws IOException {
- if (type == null) {
- type = "JKS";
- }
- try {
- KeyStore ks = KeyStore.getInstance(type);
- FileInputStream in = (FileInputStream)AccessController.doPrivileged
- (new OpenFileInputStreamAction(name));
- ks.load(in, password);
- return ks;
- } catch (GeneralSecurityException e) {
- // XXX
- throw new IOException();
- } catch (PrivilegedActionException e) {
- throw (IOException)e.getCause();
- }
- }
-
- /**
- * Return a KeyStore with the contents of the lib/security/cacerts file.
- * The file is only opened once per JVM invocation and the contents
- * cached subsequently.
- *
- public static synchronized KeyStore getCaCerts() throws IOException {
- if (caCerts != null) {
- return caCerts;
- }
- String name = javaHome + SEP + "lib" + SEP + "security" + SEP + "cacerts";
- caCerts = getKeyStore(null, name, null);
- return caCerts;
- }
-*/
-
- /**
- * Return a Set with all trusted X509Certificates contained in
- * this KeyStore.
- */
- public static Set<X509Certificate> getTrustedCerts(KeyStore ks) {
- Set<X509Certificate> set = new HashSet<X509Certificate>();
- try {
- for (Enumeration<String> e = ks.aliases(); e.hasMoreElements(); ) {
- String alias = e.nextElement();
- if (ks.isCertificateEntry(alias)) {
- Certificate cert = ks.getCertificate(alias);
- if (cert instanceof X509Certificate) {
- set.add((X509Certificate)cert);
- }
- } else if (ks.isKeyEntry(alias)) {
- Certificate[] certs = ks.getCertificateChain(alias);
- if ((certs != null) && (certs.length > 0) &&
- (certs[0] instanceof X509Certificate)) {
- set.add((X509Certificate)certs[0]);
- }
- }
- }
- } catch (KeyStoreException e) {
- // ignore
- }
- return set;
- }
-
-}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/classes/sun/security/validator/TrustStoreUtil.java Fri Jan 06 02:03:47 2017 +0000
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2002, 2016, 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.validator;
+
+import java.util.Set;
+import java.util.HashSet;
+import java.util.Collections;
+import java.util.Enumeration;
+
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.cert.X509Certificate;
+import java.security.cert.Certificate;
+
+/**
+ * Collection of static utility methods related to trust anchor KeyStores.
+ *
+ * @author Andreas Sterbenz
+ */
+public final class TrustStoreUtil {
+
+ private TrustStoreUtil() {
+ // empty
+ }
+
+ /**
+ * Return an unmodifiable Set with all trusted X509Certificates contained
+ * in the specified KeyStore.
+ */
+ public static Set<X509Certificate> getTrustedCerts(KeyStore ks) {
+ Set<X509Certificate> set = new HashSet<>();
+ try {
+ for (Enumeration<String> e = ks.aliases(); e.hasMoreElements(); ) {
+ String alias = e.nextElement();
+ if (ks.isCertificateEntry(alias)) {
+ Certificate cert = ks.getCertificate(alias);
+ if (cert instanceof X509Certificate) {
+ set.add((X509Certificate)cert);
+ }
+ } else if (ks.isKeyEntry(alias)) {
+ Certificate[] certs = ks.getCertificateChain(alias);
+ if ((certs != null) && (certs.length > 0) &&
+ (certs[0] instanceof X509Certificate)) {
+ set.add((X509Certificate)certs[0]);
+ }
+ }
+ }
+ } catch (KeyStoreException e) {
+ // ignore
+ //
+ // This should be rare, but better to log this in the future.
+ }
+
+ return Collections.unmodifiableSet(set);
+ }
+}
--- a/jdk/src/java.base/share/classes/sun/security/validator/Validator.java Fri Jan 06 01:09:03 2017 +0000
+++ b/jdk/src/java.base/share/classes/sun/security/validator/Validator.java Fri Jan 06 02:03:47 2017 +0000
@@ -166,7 +166,7 @@
*/
public static Validator getInstance(String type, String variant,
KeyStore ks) {
- return getInstance(type, variant, KeyStores.getTrustedCerts(ks));
+ return getInstance(type, variant, TrustStoreUtil.getTrustedCerts(ks));
}
/**
--- a/jdk/test/sun/security/ssl/SSLContextImpl/BadTSProvider.java Fri Jan 06 01:09:03 2017 +0000
+++ b/jdk/test/sun/security/ssl/SSLContextImpl/BadTSProvider.java Fri Jan 06 02:03:47 2017 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2016, 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
@@ -21,18 +21,21 @@
* questions.
*/
+//
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+//
+
/*
* @test
* @bug 4919147
* @summary Support for token-based KeyStores
* @run main/othervm BadTSProvider
- *
- * SunJSSE does not support dynamic system properties, no way to re-use
- * system properties in samevm/agentvm mode.
*/
import java.io.*;
import java.net.*;
+import java.security.*;
import javax.net.ssl.*;
public class BadTSProvider {
@@ -179,13 +182,19 @@
// XXX this test must be updated if the exception message changes
Throwable cause = se.getCause();
- if (cause instanceof java.security.NoSuchAlgorithmException == false) {
+ if (!(cause instanceof NoSuchAlgorithmException)) {
se.printStackTrace();
throw new Exception("Unexpected exception" + se);
}
cause = cause.getCause();
- if (cause instanceof java.security.NoSuchProviderException == false) {
+ if (!(cause instanceof KeyStoreException)) {
+ se.printStackTrace();
+ throw new Exception("Unexpected exception" + se);
+ }
+
+ cause = cause.getCause();
+ if (!(cause instanceof NoSuchProviderException)) {
se.printStackTrace();
throw new Exception("Unexpected exception" + se);
}
--- a/jdk/test/sun/security/validator/EndEntityExtensionCheck.java Fri Jan 06 01:09:03 2017 +0000
+++ b/jdk/test/sun/security/validator/EndEntityExtensionCheck.java Fri Jan 06 02:03:47 2017 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2016, 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
@@ -45,7 +45,7 @@
import java.util.Date;
import java.util.HashSet;
import java.util.Set;
-import sun.security.validator.KeyStores;
+import sun.security.validator.TrustStoreUtil;
import sun.security.validator.Validator;
@@ -113,7 +113,7 @@
Validator v = Validator.getInstance(Validator.TYPE_SIMPLE,
Validator.VAR_TLS_CLIENT,
- KeyStores.getTrustedCerts(ks));
+ TrustStoreUtil.getTrustedCerts(ks));
try {
v.validate(chain);
throw new Exception("Chain should not have validated " +