diff --git a/jdk/src/share/classes/sun/security/ssl/TrustStoreManager.java b/jdk/src/share/classes/sun/security/ssl/TrustStoreManager.java index e7b4763db53..e8ec8467e6a 100644 --- a/jdk/src/share/classes/sun/security/ssl/TrustStoreManager.java +++ b/jdk/src/share/classes/sun/security/ssl/TrustStoreManager.java @@ -31,6 +31,7 @@ import java.security.*; import java.security.cert.*; import java.util.*; import sun.security.action.*; +import sun.security.tools.KeyStoreUtil; import sun.security.validator.TrustStoreUtil; /** @@ -68,7 +69,7 @@ final class TrustStoreManager { * The preference of the default trusted KeyStore is: * javax.net.ssl.trustStore * jssecacerts - * cacerts + * cacerts (system and local) */ private static final class TrustStoreDescriptor { private static final String fileSep = File.separator; @@ -76,7 +77,7 @@ final class TrustStoreManager { GetPropertyAction.privilegedGetProperty("java.home") + fileSep + "lib" + fileSep + "security"; private static final String defaultStore = - defaultStorePath + fileSep + "cacerts"; + KeyStoreUtil.getCacertsKeyStoreFile().getPath(); private static final String jsseDefaultStore = defaultStorePath + fileSep + "jssecacerts"; @@ -139,6 +140,10 @@ final class TrustStoreManager { String storePropPassword = System.getProperty( "javax.net.ssl.trustStorePassword", ""); + if (SSLLogger.isOn && SSLLogger.isOn("trustmanager")) { + SSLLogger.fine("Default store: " + defaultStore); + } + String temporaryName = ""; File temporaryFile = null; long temporaryTime = 0L; @@ -146,21 +151,22 @@ final class TrustStoreManager { 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 (SSLLogger.isOn && + if (fileName != null && !"".equals(fileName)) { + 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 (SSLLogger.isOn && SSLLogger.isOn("trustmanager")) { - SSLLogger.fine( - "Inaccessible trust store: " + - storePropName); + SSLLogger.fine( + "Inaccessible trust store: " + + fileName); + } } } } else { diff --git a/jdk/src/share/classes/sun/security/tools/KeyStoreUtil.java b/jdk/src/share/classes/sun/security/tools/KeyStoreUtil.java index fcc77786da1..f554f83a8b4 100644 --- a/jdk/src/share/classes/sun/security/tools/KeyStoreUtil.java +++ b/jdk/src/share/classes/sun/security/tools/KeyStoreUtil.java @@ -33,7 +33,10 @@ import java.io.InputStreamReader; import java.net.URL; +import java.security.AccessController; import java.security.KeyStore; +import java.security.PrivilegedAction; +import java.security.Security; import java.security.cert.X509Certificate; import java.text.Collator; @@ -54,6 +57,33 @@ public class KeyStoreUtil { private static final String JKS = "jks"; + private static final String PROP_NAME = "security.systemCACerts"; + + /** + * Returns the value of the security property propName, which can be overridden + * by a system property of the same name + * + * @param propName the name of the system or security property + * @return the value of the system or security property + */ + @SuppressWarnings("removal") + public static String privilegedGetOverridable(String propName) { + if (System.getSecurityManager() == null) { + return getOverridableProperty(propName); + } else { + return AccessController.doPrivileged((PrivilegedAction) () -> getOverridableProperty(propName)); + } + } + + private static String getOverridableProperty(String propName) { + String val = System.getProperty(propName); + if (val == null) { + return Security.getProperty(propName); + } else { + return val; + } + } + /** * Returns true if the certificate is self-signed, false otherwise. */ @@ -96,20 +126,38 @@ public class KeyStoreUtil { } } + /** + * Returns the path to the cacerts DB + */ + public static File getCacertsKeyStoreFile() + { + String sep = File.separator; + File file = null; + /* Check system cacerts DB first, preferring system property over security property */ + String systemDB = privilegedGetOverridable(PROP_NAME); + if (systemDB != null && !"".equals(systemDB)) { + file = new File(systemDB); + } + if (file == null || !file.exists()) { + file = new File(System.getProperty("java.home") + sep + + "lib" + sep + "security" + sep + + "cacerts"); + } + if (file.exists()) { + return file; + } + return null; + } + /** * Returns the keystore with the configured CA certificates. */ public static KeyStore getCacertsKeyStore() throws Exception { - String sep = File.separator; - File file = new File(System.getProperty("java.home") + sep - + "lib" + sep + "security" + sep - + "cacerts"); - if (!file.exists()) { - return null; - } KeyStore caks = null; + File file = getCacertsKeyStoreFile(); + if (file == null) { return null; } try (FileInputStream fis = new FileInputStream(file)) { caks = KeyStore.getInstance(JKS); caks.load(fis, null); diff --git a/jdk/src/share/lib/security/java.security-aix b/jdk/src/share/lib/security/java.security-aix index bfe0c593adb..093bc09bf95 100644 --- a/jdk/src/share/lib/security/java.security-aix +++ b/jdk/src/share/lib/security/java.security-aix @@ -294,6 +294,13 @@ security.overridePropertiesFile=true # security.useSystemPropertiesFile=false +# +# Specifies the system certificate store +# This property may be disabled using +# -Djava.security.disableSystemCACerts=true +# +security.systemCACerts=${java.home}/lib/security/cacerts + # # Determines the default key and trust manager factory algorithms for # the javax.net.ssl package. diff --git a/jdk/src/share/lib/security/java.security-linux b/jdk/src/share/lib/security/java.security-linux index 9d1c8fe8a8e..16c9281cc1f 100644 --- a/jdk/src/share/lib/security/java.security-linux +++ b/jdk/src/share/lib/security/java.security-linux @@ -307,6 +307,13 @@ security.overridePropertiesFile=true # security.useSystemPropertiesFile=false +# +# Specifies the system certificate store +# This property may be disabled using +# -Djava.security.disableSystemCACerts=true +# +security.systemCACerts=${java.home}/lib/security/cacerts + # # Determines the default key and trust manager factory algorithms for # the javax.net.ssl package. diff --git a/jdk/src/share/lib/security/java.security-macosx b/jdk/src/share/lib/security/java.security-macosx index 19047c61097..43e034cdeaf 100644 --- a/jdk/src/share/lib/security/java.security-macosx +++ b/jdk/src/share/lib/security/java.security-macosx @@ -297,6 +297,13 @@ security.overridePropertiesFile=true # security.useSystemPropertiesFile=false +# +# Specifies the system certificate store +# This property may be disabled using +# -Djava.security.disableSystemCACerts=true +# +security.systemCACerts=${java.home}/lib/security/cacerts + # # Determines the default key and trust manager factory algorithms for # the javax.net.ssl package. diff --git a/jdk/src/share/lib/security/java.security-solaris b/jdk/src/share/lib/security/java.security-solaris index 7eda556ae13..325937e97fb 100644 --- a/jdk/src/share/lib/security/java.security-solaris +++ b/jdk/src/share/lib/security/java.security-solaris @@ -295,6 +295,13 @@ security.overridePropertiesFile=true # security.useSystemPropertiesFile=false +# +# Specifies the system certificate store +# This property may be disabled using +# -Djava.security.disableSystemCACerts=true +# +security.systemCACerts=${java.home}/lib/security/cacerts + # # Determines the default key and trust manager factory algorithms for # the javax.net.ssl package. diff --git a/jdk/src/share/lib/security/java.security-windows b/jdk/src/share/lib/security/java.security-windows index dfa1a669aa9..92ef777e065 100644 --- a/jdk/src/share/lib/security/java.security-windows +++ b/jdk/src/share/lib/security/java.security-windows @@ -297,6 +297,13 @@ security.overridePropertiesFile=true # security.useSystemPropertiesFile=false +# +# Specifies the system certificate store +# This property may be disabled using +# -Djava.security.disableSystemCACerts=true +# +security.systemCACerts=${java.home}/lib/security/cacerts + # # Determines the default key and trust manager factory algorithms for # the javax.net.ssl package.