JSSE: refactor KeyManager and TrustManager loading of KeyStore in engineInit(), add support for wolfJCE WKS KeyStore type
parent
1e65f4c215
commit
b80a989b4e
|
@ -40,13 +40,109 @@ import javax.net.ssl.ManagerFactoryParameters;
|
||||||
* WolfSSL KeyManagerFactory implementation
|
* WolfSSL KeyManagerFactory implementation
|
||||||
*/
|
*/
|
||||||
public class WolfSSLKeyManager extends KeyManagerFactorySpi {
|
public class WolfSSLKeyManager extends KeyManagerFactorySpi {
|
||||||
private char[] pswd;
|
private char[] pswd = null;
|
||||||
private KeyStore store;
|
private KeyStore store = null;
|
||||||
private boolean initialized = false;
|
private boolean initialized = false;
|
||||||
|
|
||||||
/** Default WolfSSLKeyManager constructor */
|
/** Default WolfSSLKeyManager constructor */
|
||||||
public WolfSSLKeyManager() { }
|
public WolfSSLKeyManager() { }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Try to load KeyStore from System properties if set.
|
||||||
|
*
|
||||||
|
* If a KeyStore file has been specified in the javax.net.ssl.keyStore
|
||||||
|
* System property, then we try to load it in the following ways:
|
||||||
|
*
|
||||||
|
* 1. Using type specified in javax.net.ssl.keyStoreType. If not given:
|
||||||
|
* 2. Using wolfJCE WKS type, if available
|
||||||
|
* 3. Using BKS type if on Android
|
||||||
|
* 4. Using JKS type if above all fail
|
||||||
|
*
|
||||||
|
* @return new KeyStore object that has been created and loaded using
|
||||||
|
* details specified in System properties.
|
||||||
|
*
|
||||||
|
* @throws KeyStoreException if javax.net.ssl.keyStore property is
|
||||||
|
* set but KeyStore fails to load
|
||||||
|
*/
|
||||||
|
private KeyStore LoadKeyStoreFromSystemProperties()
|
||||||
|
throws KeyStoreException {
|
||||||
|
|
||||||
|
KeyStore sysStore = null;
|
||||||
|
InputStream stream = null;
|
||||||
|
String pass = System.getProperty("javax.net.ssl.keyStorePassword");
|
||||||
|
String file = System.getProperty("javax.net.ssl.keyStore");
|
||||||
|
String type = System.getProperty("javax.net.ssl.keyStoreType");
|
||||||
|
boolean wksAvailable = false;
|
||||||
|
|
||||||
|
if (file != null) {
|
||||||
|
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
||||||
|
"Loading certs from: " + file);
|
||||||
|
|
||||||
|
/* Check if wolfJCE WKS KeyStore is registered and available */
|
||||||
|
wksAvailable = WolfSSLUtil.WKSAvailable();
|
||||||
|
|
||||||
|
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
||||||
|
"wolfJCE WKS KeyStore type available: " + wksAvailable);
|
||||||
|
|
||||||
|
/* Set KeyStore password if javax.net.ssl.keyStorePassword set */
|
||||||
|
if (pass != null) {
|
||||||
|
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
||||||
|
"javax.net.ssl.keyStorePassword system property " +
|
||||||
|
"set, using password");
|
||||||
|
this.pswd = pass.toCharArray();
|
||||||
|
} else {
|
||||||
|
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
||||||
|
"javax.net.ssl.keyStorePassword system property " +
|
||||||
|
"not set");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Keystore type given in property, try loading using it */
|
||||||
|
if (type != null && !type.trim().isEmpty()) {
|
||||||
|
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
||||||
|
"javax.net.ssl.keyStoreType set: " + type);
|
||||||
|
sysStore = WolfSSLUtil.LoadKeyStoreFileByType(
|
||||||
|
file, this.pswd, type);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* Try with wolfJCE WKS type first, in case wolfCrypt
|
||||||
|
* FIPS is being used */
|
||||||
|
if (wksAvailable) {
|
||||||
|
sysStore = WolfSSLUtil.LoadKeyStoreFileByType(
|
||||||
|
file, this.pswd, "WKS");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Try with BKS, if we're running on Android */
|
||||||
|
if ((sysStore == null) && WolfSSLUtil.isAndroid()) {
|
||||||
|
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
||||||
|
"Detected Android VM, trying BKS KeyStore type");
|
||||||
|
sysStore = WolfSSLUtil.LoadKeyStoreFileByType(
|
||||||
|
file, this.pswd, "BKS");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Try falling back to JKS */
|
||||||
|
if (sysStore == null) {
|
||||||
|
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
||||||
|
"javax.net.ssl.keyStoreType system property not set, " +
|
||||||
|
"trying type: JKS");
|
||||||
|
sysStore = WolfSSLUtil.LoadKeyStoreFileByType(
|
||||||
|
file, this.pswd, "JKS");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sysStore == null) {
|
||||||
|
throw new KeyStoreException(
|
||||||
|
"Failed to load KeyStore from System properties, " +
|
||||||
|
"please double check settings");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
||||||
|
"Loaded certs from KeyStore via System properties");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return sysStore;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void engineInit(KeyStore store, char[] password)
|
protected void engineInit(KeyStore store, char[] password)
|
||||||
throws KeyStoreException, NoSuchAlgorithmException,
|
throws KeyStoreException, NoSuchAlgorithmException,
|
||||||
|
@ -58,84 +154,21 @@ public class WolfSSLKeyManager extends KeyManagerFactorySpi {
|
||||||
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
||||||
"entering engineInit(KeyStore store, char[] password)");
|
"entering engineInit(KeyStore store, char[] password)");
|
||||||
|
|
||||||
/* If no KeyStore passed in, try to load from system property values */
|
/* If no KeyStore passed in, try to load from system property values
|
||||||
|
* if they have been set */
|
||||||
if (store == null) {
|
if (store == null) {
|
||||||
String pass = System.getProperty("javax.net.ssl.keyStorePassword");
|
|
||||||
String file = System.getProperty("javax.net.ssl.keyStore");
|
|
||||||
String type = System.getProperty("javax.net.ssl.keyStoreType");
|
|
||||||
String vmVendor = System.getProperty("java.vm.vendor");
|
|
||||||
InputStream stream = null;
|
|
||||||
|
|
||||||
try {
|
|
||||||
if (file != null) {
|
|
||||||
if (pass != null) {
|
|
||||||
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
|
||||||
"javax.net.ssl.keyStorePassword system property " +
|
|
||||||
"set, using password");
|
|
||||||
this.pswd = pass.toCharArray();
|
|
||||||
} else {
|
|
||||||
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
|
||||||
"javax.net.ssl.keyStorePassword system property " +
|
|
||||||
"not set");
|
|
||||||
}
|
|
||||||
|
|
||||||
/* We default to use a JKS KeyStore type if not set at the
|
|
||||||
* system level, except on Android we use BKS */
|
|
||||||
try {
|
|
||||||
if (type != null && !type.trim().isEmpty()) {
|
|
||||||
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
|
||||||
"javax.net.ssl.keyStoreType system property " +
|
|
||||||
"set: " + type);
|
|
||||||
certs = KeyStore.getInstance(type);
|
|
||||||
} else {
|
|
||||||
if (vmVendor != null &&
|
|
||||||
vmVendor.equals("The Android Project")) {
|
|
||||||
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
|
||||||
"Detected Android VM, " +
|
|
||||||
"using BKS KeyStore type");
|
|
||||||
certs = KeyStore.getInstance("BKS");
|
|
||||||
} else {
|
|
||||||
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
|
||||||
"javax.net.ssl.keyStoreType system property " +
|
|
||||||
"not set, using type: JKS");
|
|
||||||
certs = KeyStore.getInstance("JKS");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (KeyStoreException kse) {
|
|
||||||
WolfSSLDebug.log(getClass(), WolfSSLDebug.ERROR,
|
|
||||||
"Unsupported KeyStore type: " + type);
|
|
||||||
throw kse;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
/* initialize KeyStore, loading certs below will
|
|
||||||
* overwrite if needed, otherwise Android needs
|
|
||||||
* this to be initialized here */
|
|
||||||
certs.load(null, null);
|
|
||||||
|
|
||||||
} catch (Exception e) {
|
|
||||||
WolfSSLDebug.log(getClass(), WolfSSLDebug.ERROR,
|
|
||||||
"Error initializing KeyStore with load(null, null)");
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
|
|
||||||
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
||||||
"Loading certs from " + file);
|
"input KeyStore null, trying to load KeyStore from " +
|
||||||
stream = new FileInputStream(file);
|
"system properties");
|
||||||
certs.load(stream, this.pswd);
|
|
||||||
stream.close();
|
certs = LoadKeyStoreFromSystemProperties();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
||||||
|
"input KeyStore provided, using inside KeyManager");
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (FileNotFoundException ex) {
|
|
||||||
throw new KeyStoreException(ex);
|
|
||||||
} catch (IOException ex) {
|
|
||||||
throw new KeyStoreException(ex);
|
|
||||||
} catch (NoSuchAlgorithmException ex) {
|
|
||||||
throw new KeyStoreException(ex);
|
|
||||||
} catch (CertificateException ex) {
|
|
||||||
throw new KeyStoreException(ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.store = certs;
|
this.store = certs;
|
||||||
this.initialized = true;
|
this.initialized = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,10 +27,11 @@ import java.io.FileNotFoundException;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
import java.security.InvalidAlgorithmParameterException;
|
import java.security.Security;
|
||||||
import java.security.KeyStore;
|
import java.security.KeyStore;
|
||||||
import java.security.KeyStoreException;
|
import java.security.KeyStoreException;
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
import java.security.InvalidAlgorithmParameterException;
|
||||||
import java.security.cert.CertificateException;
|
import java.security.cert.CertificateException;
|
||||||
import java.security.cert.Certificate;
|
import java.security.cert.Certificate;
|
||||||
import java.security.cert.CertificateFactory;
|
import java.security.cert.CertificateFactory;
|
||||||
|
@ -54,225 +55,407 @@ public class WolfSSLTrustManager extends TrustManagerFactorySpi {
|
||||||
/** Default WolfSSLTrustManager constructor */
|
/** Default WolfSSLTrustManager constructor */
|
||||||
public WolfSSLTrustManager() { }
|
public WolfSSLTrustManager() { }
|
||||||
|
|
||||||
/* Initialize TrustManager. Attempts to load CA certifciates as trusted
|
/**
|
||||||
* roots into wolfSSL from user-provided KeyStore. If KeyStore is null,
|
* Try to load KeyStore from System properties if set.
|
||||||
* we attempt to load default system CA certificates in the following
|
*
|
||||||
* priority order:
|
* If a KeyStore file has been specified in the javax.net.ssl.keyStore
|
||||||
* 1. javax.net.ssl.trustStore location, if set. Using password
|
* System property, then we try to load it in the following ways:
|
||||||
* in javax.net.ssl.trustStorePassword.
|
*
|
||||||
* 2. $JAVA_HOME/lib/security/jssecacerts (JDK 9+)
|
* 1. Using type specified in javax.net.ssl.keyStoreType. If not given:
|
||||||
* 3. $JAVA_HOME/jre/lib/security/jssecacerts (JDK <= 8)
|
* 2. Using wolfJCE WKS type, if available
|
||||||
* 4. $JAVA_HOME/lib/security/cacerts (JDK 9+)
|
* 3. Using BKS type if on Android
|
||||||
* 5. $JAVA_HOME/jre/lib/security/cacerts (JDK <= 8)
|
* 4. Using JKS type if above all fail
|
||||||
* 6. /etc/ssl/certs/java/cacerts
|
*
|
||||||
* 7. Android: AndroidCAStore system KeyStore
|
* @param wksAvailable Boolean indicating if wolfJCE WKS KeyStore type
|
||||||
* 8. Android: $ANDROID_ROOT/etc/security/cacerts
|
* is available, true if so, false if not
|
||||||
|
* @param tsPass javax.net.ssl.trustStorePassword system property
|
||||||
|
* value, or null
|
||||||
|
* @param tsFile javax.net.ssl.trustStore system property value, or null
|
||||||
|
* @param tsType javax.net.ssl.trustStoreType system property value,
|
||||||
|
* or null
|
||||||
|
*
|
||||||
|
* @return new KeyStore object that has been created and loaded using
|
||||||
|
* details specified in System properties.
|
||||||
|
*
|
||||||
|
* @throws KeyStoreException if javax.net.ssl.keyStore property is
|
||||||
|
* set but KeyStore fails to load
|
||||||
*/
|
*/
|
||||||
@Override
|
private KeyStore LoadKeyStoreFromSystemProperties(boolean wksAvailable,
|
||||||
protected void engineInit(KeyStore in) throws KeyStoreException {
|
String tsPass, String tsFile, String tsType)
|
||||||
KeyStore certs = in;
|
throws KeyStoreException {
|
||||||
|
|
||||||
|
char[] passArr = null;
|
||||||
|
KeyStore sysStore = null;
|
||||||
|
|
||||||
|
if (tsFile != null) {
|
||||||
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
||||||
"entered engineInit()");
|
"Loading certs from: " + tsFile);
|
||||||
|
|
||||||
if (in == null) {
|
/* Set KeyStore password if javax.net.ssl.keyStorePassword set */
|
||||||
String pass = System.getProperty("javax.net.ssl.trustStorePassword");
|
if (tsPass != null) {
|
||||||
String file = System.getProperty("javax.net.ssl.trustStore");
|
|
||||||
String type = System.getProperty("javax.net.ssl.trustStoreType");
|
|
||||||
String vmVendor = System.getProperty("java.vm.vendor");
|
|
||||||
String javaHome = System.getenv("JAVA_HOME");
|
|
||||||
String androidRoot = System.getenv("ANDROID_ROOT");
|
|
||||||
char[] passAr = null;
|
|
||||||
InputStream stream = null;
|
|
||||||
boolean systemCertsFound = false;
|
|
||||||
int aliasCnt = 0;
|
|
||||||
|
|
||||||
try {
|
|
||||||
if (pass != null) {
|
|
||||||
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
||||||
"javax.net.ssl.trustStorePassword system property " +
|
"javax.net.ssl.trustStorePassword system property " +
|
||||||
"set, using password");
|
"set, using password");
|
||||||
passAr = pass.toCharArray();
|
passArr = tsPass.toCharArray();
|
||||||
} else {
|
} else {
|
||||||
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
||||||
"javax.net.ssl.trustStorePassword system property " +
|
"javax.net.ssl.trustStorePassword system property " +
|
||||||
"not set");
|
"not set");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* default to JKS KeyStore type if not set at system level */
|
/* System keystore type set, try loading using it first */
|
||||||
/* We default to use a JKS KeyStore type if not set at the
|
if (tsType != null && !tsType.trim().isEmpty()) {
|
||||||
* system level, except on Android we use BKS */
|
|
||||||
try {
|
|
||||||
if (type != null && !type.trim().isEmpty()) {
|
|
||||||
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
||||||
"javax.net.ssl.trustStoreType system property " +
|
"javax.net.ssl.trustStoreType set: " + tsType);
|
||||||
"set: " + type);
|
sysStore = WolfSSLUtil.LoadKeyStoreFileByType(
|
||||||
certs = KeyStore.getInstance(type);
|
tsFile, passArr, tsType);
|
||||||
} else {
|
}
|
||||||
if (vmVendor != null &&
|
else {
|
||||||
vmVendor.equals("The Android Project")) {
|
/* Try with wolfJCE WKS type first, in case wolfCrypt
|
||||||
|
* FIPS is being used */
|
||||||
|
if (wksAvailable) {
|
||||||
|
sysStore = WolfSSLUtil.LoadKeyStoreFileByType(
|
||||||
|
tsFile, passArr, "WKS");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Try with BKS, if we're running on Android */
|
||||||
|
if (sysStore == null && WolfSSLUtil.isAndroid()) {
|
||||||
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
||||||
"Detected Android VM, using BKS KeyStore type");
|
"Detected Android VM, trying BKS KeyStore type");
|
||||||
certs = KeyStore.getInstance("BKS");
|
sysStore = WolfSSLUtil.LoadKeyStoreFileByType(
|
||||||
} else {
|
tsFile, passArr, "BKS");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Try falling back to JKS */
|
||||||
|
if (sysStore == null) {
|
||||||
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
||||||
"javax.net.ssl.trustStoreType system property " +
|
"javax.net.ssl.trustStoreType system property not set, " +
|
||||||
"not set, using type: JKS");
|
"trying type: JKS");
|
||||||
certs = KeyStore.getInstance("JKS");
|
sysStore = WolfSSLUtil.LoadKeyStoreFileByType(
|
||||||
|
tsFile, passArr, "JKS");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (KeyStoreException kse) {
|
|
||||||
WolfSSLDebug.log(getClass(), WolfSSLDebug.ERROR,
|
|
||||||
"Unsupported KeyStore type: " + type);
|
|
||||||
throw kse;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
if (sysStore == null) {
|
||||||
/* initialize KeyStore, loading certs below will
|
throw new KeyStoreException(
|
||||||
* overwrite if needed, otherwise Android needs
|
"Failed to load KeyStore from System properties, " +
|
||||||
* this to be initialized here */
|
"please double check settings");
|
||||||
certs.load(null, null);
|
|
||||||
|
|
||||||
} catch (Exception e) {
|
|
||||||
WolfSSLDebug.log(getClass(), WolfSSLDebug.ERROR,
|
|
||||||
"Error initializing KeyStore with load(null, null)");
|
|
||||||
throw new KeyStoreException(e);
|
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
if (file == null) {
|
|
||||||
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
||||||
"javax.net.ssl.trustStore system property not set, " +
|
"Loaded certs from KeyStore via System properties");
|
||||||
"trying to load system certs");
|
}
|
||||||
|
|
||||||
/* try to load trusted system certs if possible */
|
|
||||||
if (javaHome != null) {
|
|
||||||
if (!javaHome.endsWith("/") &&
|
|
||||||
!javaHome.endsWith("\\")) {
|
|
||||||
/* add trailing slash if not there already */
|
|
||||||
javaHome = javaHome.concat("/");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Java 9+ have cacerts under:
|
return sysStore;
|
||||||
* $JAVA_HOME/lib/security/cacerts
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Try to load system CA certs from jssecacerts or cacerts KeyStore.
|
||||||
|
*
|
||||||
|
* Java 9+ has cacerts and/or jssecacerts under:
|
||||||
|
* $JAVA_HOME/lib/security/[jssecacerts | cacerts]
|
||||||
* Java 8 and earlier use:
|
* Java 8 and earlier use:
|
||||||
* $JAVA_HOME/jre/lib/security/cacerts
|
* $JAVA_HOME/jre/lib/security/[jssecacerts | cacerts ]
|
||||||
|
*
|
||||||
|
* If wolfJCE WKS KeyStore type is available (ie: wolfJCE has been
|
||||||
|
* registered on this system), we first try to load jssecacerts.wks
|
||||||
|
* or cacerts.wks as WKS type KeyStore before falling back to trying to
|
||||||
|
* load KeyStore type specified in java.security by 'keystore.type'
|
||||||
|
* Security property. This is "JKS" type by default on my platforms.
|
||||||
|
*
|
||||||
|
* @param jh String value of $JAVA_HOME with trailing slash
|
||||||
|
* @param wksAvailable Boolean if wolfJCE WKS KeyStore typs is available
|
||||||
|
* @param tsPass javax.net.ssl.trustStorePassword, or null if not set
|
||||||
|
* @param certBundleName Name of system certificate bundle, either
|
||||||
|
* "jssecacerts" or "cacerts"
|
||||||
|
*
|
||||||
|
* @return KeyStore object loaded with CA certs from jssecacerts, or
|
||||||
|
* null if not able to find KeyStore or load certs
|
||||||
*/
|
*/
|
||||||
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
private KeyStore LoadJavaSystemCerts(String jh, boolean wksAvailable,
|
||||||
"$JAVA_HOME = " + javaHome);
|
String tsPass, String certBundleName) {
|
||||||
|
|
||||||
/* trying: "lib/security/jssecacerts" */
|
char[] passArr = null;
|
||||||
File f = new File(javaHome.concat(
|
KeyStore sysStore = null;
|
||||||
"lib/security/jssecacerts"));
|
File f = null;
|
||||||
|
FileInputStream stream = null;
|
||||||
|
|
||||||
|
/* Get default KeyStore type, set in java.security and normally JKS */
|
||||||
|
String storeType = Security.getProperty("keystore.type");
|
||||||
|
if (storeType != null) {
|
||||||
|
storeType = storeType.toUpperCase();
|
||||||
|
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
||||||
|
"keystore.type Security property set: " + storeType);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wksAvailable) {
|
||||||
|
/* First try wolfJCE WKS converted version for Java 9+ */
|
||||||
|
f = new File(jh.concat("lib/security/")
|
||||||
|
.concat(certBundleName).concat(".wks"));
|
||||||
|
|
||||||
|
/* Second try wolfJCE WKS converted version for Java <= 8 */
|
||||||
if (!f.exists()) {
|
if (!f.exists()) {
|
||||||
f = new File(javaHome.concat(
|
f = new File(jh.concat("jre/lib/security/")
|
||||||
"jre/lib/security/jssecacerts"));
|
.concat(certBundleName).concat(".wks"));
|
||||||
}
|
|
||||||
if (f.exists()) {
|
|
||||||
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
|
||||||
"Loading certs from " + f.getAbsolutePath());
|
|
||||||
stream = new FileInputStream(f);
|
|
||||||
certs.load(stream, passAr);
|
|
||||||
stream.close();
|
|
||||||
systemCertsFound = true;
|
|
||||||
} else {
|
|
||||||
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
|
||||||
"$JAVA_HOME/(jre/)lib/security/jssecacerts: " +
|
|
||||||
"not found");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* trying: "lib/security/cacerts" */
|
if (f.exists()) {
|
||||||
f = new File(javaHome.concat("lib/security/cacerts"));
|
storeType = "WKS";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Third try normal Java 9+ location */
|
||||||
|
if ((f == null) || !f.exists()) {
|
||||||
|
f = new File(jh.concat("lib/security/").concat(certBundleName));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Fourth try normal Java <= 8 location */
|
||||||
if (!f.exists()) {
|
if (!f.exists()) {
|
||||||
f = new File(javaHome.concat(
|
f = new File(jh.concat("jre/lib/security/").concat(certBundleName));
|
||||||
"jre/lib/security/cacerts"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (f.exists()) {
|
||||||
|
|
||||||
|
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
||||||
|
"Loading certs from " + f.getAbsolutePath());
|
||||||
|
|
||||||
|
try {
|
||||||
|
sysStore = KeyStore.getInstance(storeType);
|
||||||
|
} catch (KeyStoreException e) {
|
||||||
|
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
||||||
|
"Not able to get KeyStore of type: " + storeType);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
sysStore.load(null, null);
|
||||||
|
} catch (IOException | NoSuchAlgorithmException |
|
||||||
|
CertificateException e) {
|
||||||
|
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
||||||
|
"Not able to load empty KeyStore(" + storeType + ")");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tsPass != null) {
|
||||||
|
passArr = tsPass.toCharArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
stream = new FileInputStream(f);
|
||||||
|
} catch (FileNotFoundException e) {
|
||||||
|
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
||||||
|
"Not able to open KeyStore file for reading: " +
|
||||||
|
f.getAbsolutePath());
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
sysStore.load(stream, passArr);
|
||||||
|
|
||||||
|
} catch (IOException | NoSuchAlgorithmException |
|
||||||
|
CertificateException e) {
|
||||||
|
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
||||||
|
"Not able to load KeyStore with file stream: " +
|
||||||
|
f.getAbsolutePath());
|
||||||
|
|
||||||
|
} finally {
|
||||||
|
try {
|
||||||
|
if (stream != null) {
|
||||||
|
stream.close();
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
||||||
|
"$JAVA_HOME/(jre/)lib/security/" +
|
||||||
|
certBundleName + ": not found");
|
||||||
|
}
|
||||||
|
|
||||||
|
return sysStore;
|
||||||
|
}
|
||||||
|
|
||||||
|
private KeyStore LoadSystemJsseCaCerts(String jh, boolean wksAvailable,
|
||||||
|
String tsPass) {
|
||||||
|
|
||||||
|
return LoadJavaSystemCerts(jh, wksAvailable, tsPass, "jssecacerts");
|
||||||
|
}
|
||||||
|
|
||||||
|
private KeyStore LoadSystemCaCerts(String jh, boolean wksAvailable,
|
||||||
|
String tsPass) {
|
||||||
|
|
||||||
|
return LoadJavaSystemCerts(jh, wksAvailable, tsPass, "cacerts");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Try to load system CA certs from common KeyStore locations.
|
||||||
|
*
|
||||||
|
* Currently includes:
|
||||||
|
* 1. /etc/ssl/certs/java/cacerts
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private KeyStore LoadCommonSystemCerts(boolean wksAvailable,
|
||||||
|
String tsPass) {
|
||||||
|
|
||||||
|
char[] passArr = null;
|
||||||
|
File f = null;
|
||||||
|
FileInputStream stream = null;
|
||||||
|
KeyStore sysStore = null;
|
||||||
|
|
||||||
|
f = new File("/etc/ssl/certs/java/cacerts");
|
||||||
|
|
||||||
if (f.exists()) {
|
if (f.exists()) {
|
||||||
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
||||||
"Loading certs from " + f.getAbsolutePath());
|
"Loading certs from " + f.getAbsolutePath());
|
||||||
stream = new FileInputStream(f);
|
|
||||||
certs.load(stream, passAr);
|
if (tsPass != null) {
|
||||||
stream.close();
|
passArr = tsPass.toCharArray();
|
||||||
systemCertsFound = true;
|
|
||||||
} else {
|
|
||||||
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
|
||||||
"$JAVA_HOME/(jre/)lib/security/cacerts: " +
|
|
||||||
"not found");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
|
||||||
"$JAVA_HOME not set, unable to load system certs");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (systemCertsFound == false) {
|
try {
|
||||||
/* try loading from common system paths */
|
|
||||||
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
|
||||||
"Trying to load system certs from common " +
|
|
||||||
"system paths");
|
|
||||||
|
|
||||||
/* trying: "/etc/ssl/certs/java/cacerts" */
|
|
||||||
File f = new File("/etc/ssl/certs/java/cacerts");
|
|
||||||
if (f.exists()) {
|
|
||||||
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
|
||||||
"Loading certs from " + f.getAbsolutePath());
|
|
||||||
stream = new FileInputStream(f);
|
stream = new FileInputStream(f);
|
||||||
certs.load(stream, passAr);
|
} catch (FileNotFoundException e) {
|
||||||
|
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
||||||
|
"Not able to open KeyStore file for reading: " +
|
||||||
|
f.getAbsolutePath());
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
sysStore.load(stream, passArr);
|
||||||
|
|
||||||
|
} catch (IOException | NoSuchAlgorithmException |
|
||||||
|
CertificateException e) {
|
||||||
|
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
||||||
|
"Not able to load KeyStore with file stream: " +
|
||||||
|
f.getAbsolutePath());
|
||||||
|
|
||||||
|
} finally {
|
||||||
|
try {
|
||||||
|
if (stream != null) {
|
||||||
stream.close();
|
stream.close();
|
||||||
systemCertsFound = true;
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
||||||
"/etc/ssl/certs/java/cacerts: not found");
|
"/etc/ssl/certs/java/cacerts: not found");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return sysStore;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Try to load Android system CA certs from AndroidCAStore KeyStore.
|
||||||
|
*
|
||||||
|
* The AndroidCAStore KeyStore is pre-loaded with Android system CA
|
||||||
|
* certs. We try to load this first before going on to load root certs
|
||||||
|
* manually, since it's already pre-imported and set up.
|
||||||
|
*
|
||||||
|
* @return KeyStore object referencing AndroidCAStore, or null if not
|
||||||
|
* found or not able to be loaded
|
||||||
|
*/
|
||||||
|
private KeyStore LoadAndroidCAStore() {
|
||||||
|
|
||||||
|
KeyStore sysStore = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
sysStore = KeyStore.getInstance("AndroidCAStore");
|
||||||
|
|
||||||
|
} catch (KeyStoreException e) {
|
||||||
|
/* Error finding AndroidCAStore */
|
||||||
|
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
||||||
|
"AndroidCAStore KeyStore not found, not loading");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
sysStore.load(null, null);
|
||||||
|
|
||||||
|
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
||||||
|
"Using AndroidCAStore KeyStore for default system certs");
|
||||||
|
|
||||||
|
} catch (IOException | NoSuchAlgorithmException |
|
||||||
|
CertificateException e) {
|
||||||
|
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
||||||
|
"Not able to load AndroidCAStore with null args");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return sysStore;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Try to load Android system root certificates manually by reading
|
||||||
|
* all PEM certificates in [android_root]/etc/security/cacerts directory.
|
||||||
|
*
|
||||||
|
* @return KeyStore object containing Android system CA certificates, or
|
||||||
|
* null if none found or error loading any certs
|
||||||
|
*/
|
||||||
|
private KeyStore LoadAndroidSystemCertsManually() {
|
||||||
|
|
||||||
|
int aliasCnt = 0;
|
||||||
|
byte[] derArray = null;
|
||||||
|
KeyStore sysStore = null;
|
||||||
|
CertificateFactory cfactory = null;
|
||||||
|
ByteArrayInputStream bis = null;
|
||||||
|
Certificate tmpCert = null;
|
||||||
|
String androidRoot = System.getenv("ANDROID_ROOT");
|
||||||
|
|
||||||
if (androidRoot != null) {
|
if (androidRoot != null) {
|
||||||
|
|
||||||
/* first try to use AndroidCAStore KeyStore, this is
|
/* Android default KeyStore type is BKS */
|
||||||
* pre-loaded with Android system CA certs */
|
|
||||||
try {
|
try {
|
||||||
certs = KeyStore.getInstance("AndroidCAStore");
|
sysStore = KeyStore.getInstance("BKS");
|
||||||
certs.load(null, null);
|
|
||||||
systemCertsFound = true;
|
|
||||||
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
|
||||||
"Using AndroidCAStore KeyStore for default " +
|
|
||||||
"system certs");
|
|
||||||
} catch (KeyStoreException e) {
|
} catch (KeyStoreException e) {
|
||||||
/* error finding AndroidCAStore */
|
/* Unable to get or load empty BKS KeyStore type */
|
||||||
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
||||||
"AndroidCAStore KeyStore not found, trying " +
|
"Unable to get or load BKS KeyStore instance");
|
||||||
"to manually load system certs");
|
return null;
|
||||||
systemCertsFound = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Otherwise, try to manually load system certs */
|
try {
|
||||||
if (systemCertsFound == false) {
|
sysStore.load(null, null);
|
||||||
|
|
||||||
|
} catch (IOException | NoSuchAlgorithmException |
|
||||||
|
CertificateException e) {
|
||||||
|
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
||||||
|
"Not able to load BKS KeyStore with null args");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Add trailing slash if not there already */
|
||||||
if (!androidRoot.endsWith("/") &&
|
if (!androidRoot.endsWith("/") &&
|
||||||
!androidRoot.endsWith("\\")) {
|
!androidRoot.endsWith("\\")) {
|
||||||
/* add trailing slash if not there already */
|
|
||||||
androidRoot = androidRoot.concat("/");
|
androidRoot = androidRoot.concat("/");
|
||||||
}
|
}
|
||||||
|
|
||||||
String caStoreDir = androidRoot.concat(
|
String caStoreDir = androidRoot.concat("etc/security/cacerts");
|
||||||
"etc/security/cacerts");
|
|
||||||
File cadir = new File(caStoreDir);
|
File cadir = new File(caStoreDir);
|
||||||
String[] cafiles = null;
|
String[] cafiles = null;
|
||||||
try {
|
try {
|
||||||
cafiles = cadir.list();
|
cafiles = cadir.list();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
/* denied access reading cacerts directory */
|
/* Denied access reading cacerts directory */
|
||||||
WolfSSLDebug.log(getClass(), WolfSSLDebug.ERROR,
|
WolfSSLDebug.log(getClass(), WolfSSLDebug.ERROR,
|
||||||
"Permission error when trying to read " +
|
"Permission error when trying to read system " +
|
||||||
"system CA certificates");
|
"CA certificates");
|
||||||
throw new KeyStoreException(e);
|
return null;
|
||||||
}
|
}
|
||||||
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
||||||
"Found " + cafiles.length + " CA files to load " +
|
"Found " + cafiles.length + " CA files to load into KeyStore");
|
||||||
"into KeyStore");
|
|
||||||
|
|
||||||
/* get factory for cert creation */
|
/* Get factory for cert creation */
|
||||||
CertificateFactory cfactory =
|
try {
|
||||||
CertificateFactory.getInstance("X.509");
|
cfactory = CertificateFactory.getInstance("X.509");
|
||||||
|
} catch (CertificateException e) {
|
||||||
|
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
||||||
|
"Not able to get X.509 CertificateFactory instance");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
/* loop over all PEM certs */
|
/* Loop over all PEM certs */
|
||||||
for (String cafile : cafiles) {
|
for (String cafile : cafiles) {
|
||||||
|
|
||||||
WolfSSLCertificate certPem = null;
|
WolfSSLCertificate certPem = null;
|
||||||
|
@ -292,66 +475,162 @@ public class WolfSSLTrustManager extends TrustManagerFactorySpi {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
byte[] derArray = certPem.getDer();
|
try {
|
||||||
|
derArray = certPem.getDer();
|
||||||
|
} catch (WolfSSLJNIException e) {
|
||||||
|
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
||||||
|
"Error getting DER from PEM cert, skipping: " +
|
||||||
|
fullCertPath);
|
||||||
|
} finally {
|
||||||
certPem.free();
|
certPem.free();
|
||||||
ByteArrayInputStream bis =
|
}
|
||||||
new ByteArrayInputStream(derArray);
|
|
||||||
Certificate tmpCert = null;
|
bis = new ByteArrayInputStream(derArray);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
tmpCert = cfactory.generateCertificate(bis);
|
tmpCert = cfactory.generateCertificate(bis);
|
||||||
bis.close();
|
|
||||||
} catch (CertificateException ce) {
|
} catch (CertificateException ce) {
|
||||||
WolfSSLDebug.log(getClass(), WolfSSLDebug.ERROR,
|
WolfSSLDebug.log(getClass(), WolfSSLDebug.ERROR,
|
||||||
"Error generating certificate from " +
|
"Error generating certificate from " +
|
||||||
"ByteArrayInputStream");
|
"ByteArrayInputStream, skipped loading cert: " +
|
||||||
|
fullCertPath);
|
||||||
|
continue;
|
||||||
|
|
||||||
|
} finally {
|
||||||
|
try {
|
||||||
|
if (bis != null) {
|
||||||
bis.close();
|
bis.close();
|
||||||
throw new KeyStoreException(ce);
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String aliasString = "alias" + aliasCnt;
|
String aliasString = "alias" + aliasCnt;
|
||||||
try {
|
try {
|
||||||
certs.setCertificateEntry(aliasString, tmpCert);
|
sysStore.setCertificateEntry(aliasString, tmpCert);
|
||||||
} catch (KeyStoreException kse) {
|
} catch (KeyStoreException kse) {
|
||||||
WolfSSLDebug.log(getClass(), WolfSSLDebug.ERROR,
|
WolfSSLDebug.log(getClass(), WolfSSLDebug.ERROR,
|
||||||
"Error setting certificate entry in " +
|
"Error setting certificate entry in " +
|
||||||
"KeyStore, skipping loading cert");
|
"KeyStore, skipping loading cert: " +
|
||||||
|
fullCertPath);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* increment alias counter for unique aliases */
|
/* increment alias counter for unique aliases */
|
||||||
aliasCnt++;
|
aliasCnt++;
|
||||||
}
|
}
|
||||||
systemCertsFound = true;
|
|
||||||
|
|
||||||
} /* end Android manual load */
|
if (aliasCnt == 0) {
|
||||||
|
/* No certs loaded, don't return empty KeyStore */
|
||||||
|
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
||||||
|
"No root certificates loaded from etc/security/cacerts");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (systemCertsFound == false) {
|
return sysStore;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize TrustManager, loading root/CA certs.
|
||||||
|
*
|
||||||
|
* Attempts to load CA certifciates as trusted roots into wolfSSL from
|
||||||
|
* user-provided KeyStore. If KeyStore is null, we attempt to load default
|
||||||
|
* system CA certificates. Certs are loaded in the following priority order:
|
||||||
|
*
|
||||||
|
* 1. User-provided KeyStore passed in
|
||||||
|
* 2. javax.net.ssl.trustStore location, if set. Using password
|
||||||
|
* in javax.net.ssl.trustStorePassword.
|
||||||
|
* 3. Java installation 'jssecacerts' bundle:
|
||||||
|
* a. $JAVA_HOME/lib/security/jssecacerts (JDK 9+)
|
||||||
|
* b. $JAVA_HOME/jre/lib/security/jssecacerts (JDK less than 9)
|
||||||
|
* 4. Java installation 'cacerts' bundle:
|
||||||
|
* a. $JAVA_HOME/lib/security/cacerts (JDK 9+)
|
||||||
|
* b. $JAVA_HOME/jre/lib/security/cacerts (JDK less than 9)
|
||||||
|
* 5. Common system CA certs locations:
|
||||||
|
* a. /etc/ssl/certs/java/cacerts
|
||||||
|
* 6. Android: AndroidCAStore system KeyStore
|
||||||
|
* 7. Android: $ANDROID_ROOT/etc/security/cacerts
|
||||||
|
*
|
||||||
|
* If none of the locations above work for finding/loading CA certs,
|
||||||
|
* none are loaded into this TrustManager.
|
||||||
|
*
|
||||||
|
* @param in KeyStore from which to load trusted root/CA certificates, may
|
||||||
|
* be null
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected void engineInit(KeyStore in) throws KeyStoreException {
|
||||||
|
|
||||||
|
KeyStore certs = in;
|
||||||
|
String javaHome = null;
|
||||||
|
boolean wksAvailable = false;
|
||||||
|
String pass = System.getProperty("javax.net.ssl.trustStorePassword");
|
||||||
|
String file = System.getProperty("javax.net.ssl.trustStore");
|
||||||
|
String type = System.getProperty("javax.net.ssl.trustStoreType");
|
||||||
|
|
||||||
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
||||||
"No trusted system certs found, none " +
|
"entered engineInit(KeyStore in)");
|
||||||
"loaded by default");
|
|
||||||
|
/* [1] Just use KeyStore passed in by user if available */
|
||||||
|
if (in == null) {
|
||||||
|
|
||||||
|
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
||||||
|
"input KeyStore null, trying to load system CA certs");
|
||||||
|
|
||||||
|
/* Check if wolfJCE WKS KeyStore is registered and available */
|
||||||
|
wksAvailable = WolfSSLUtil.WKSAvailable();
|
||||||
|
|
||||||
|
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
||||||
|
"wolfJCE WKS KeyStore type available: " + wksAvailable);
|
||||||
|
|
||||||
|
/* [2] Try to load from system property details */
|
||||||
|
certs = LoadKeyStoreFromSystemProperties(
|
||||||
|
wksAvailable, pass, file, type);
|
||||||
|
|
||||||
|
/* Get JAVA_HOME for trying to load system certs next */
|
||||||
|
if (certs == null) {
|
||||||
|
javaHome = WolfSSLUtil.GetJavaHome();
|
||||||
|
if (javaHome == null) {
|
||||||
|
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
||||||
|
"$JAVA_HOME not set, unable to load system CA certs");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
||||||
|
"$JAVA_HOME = " + javaHome);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* [3] Try to load system jssecacerts */
|
||||||
|
if ((certs == null) && (javaHome != null)) {
|
||||||
|
certs = LoadSystemJsseCaCerts(javaHome, wksAvailable, pass);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* [4] Try to load system cacerts */
|
||||||
|
if ((certs == null) && (javaHome != null)) {
|
||||||
|
certs = LoadSystemCaCerts(javaHome, wksAvailable, pass);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* [5] Try to load common CA cert locations */
|
||||||
|
if (certs == null) {
|
||||||
|
certs = LoadCommonSystemCerts(wksAvailable, pass);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* [6] Try to load system certs if on Android */
|
||||||
|
if ((certs == null) && WolfSSLUtil.isAndroid()) {
|
||||||
|
certs = LoadAndroidCAStore();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* [7] Try to load Android system root certs manually */
|
||||||
|
if ((certs == null) && WolfSSLUtil.isAndroid()) {
|
||||||
|
certs = LoadAndroidSystemCertsManually();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
||||||
"Loading certs from " + file);
|
"input KeyStore provided, using for trusted certs");
|
||||||
stream = new FileInputStream(file);
|
|
||||||
certs.load(stream, passAr);
|
|
||||||
stream.close();
|
|
||||||
}
|
|
||||||
} catch (FileNotFoundException ex) {
|
|
||||||
throw new KeyStoreException(ex);
|
|
||||||
} catch (IOException ex) {
|
|
||||||
throw new KeyStoreException(ex);
|
|
||||||
} catch (NoSuchAlgorithmException ex) {
|
|
||||||
throw new KeyStoreException(ex);
|
|
||||||
} catch (CertificateException ex) {
|
|
||||||
throw new KeyStoreException(ex);
|
|
||||||
} catch (WolfSSLJNIException ex) {
|
|
||||||
throw new KeyStoreException(ex);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.store = certs;
|
this.store = certs;
|
||||||
this.initialized = true;
|
this.initialized = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,13 @@ import java.util.Arrays;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
import java.security.Security;
|
import java.security.Security;
|
||||||
|
import java.security.KeyStore;
|
||||||
|
import java.security.KeyStoreException;
|
||||||
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
import java.security.cert.CertificateException;
|
||||||
|
|
||||||
import com.wolfssl.WolfSSLException;
|
import com.wolfssl.WolfSSLException;
|
||||||
|
|
||||||
|
@ -274,5 +280,106 @@ public class WolfSSLUtil {
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get path that JAVA_HOME is set, append trailing slash if needed.
|
||||||
|
*
|
||||||
|
* @return String that JAVA_HOME is set to, otherwise null if not set
|
||||||
|
*/
|
||||||
|
protected static String GetJavaHome() {
|
||||||
|
|
||||||
|
String javaHome = System.getenv("JAVA_HOME");
|
||||||
|
|
||||||
|
if (javaHome != null) {
|
||||||
|
if (!javaHome.endsWith("/") &&
|
||||||
|
!javaHome.endsWith("\\")) {
|
||||||
|
/* add trailing slash if not there already */
|
||||||
|
javaHome = javaHome.concat("/");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return javaHome;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Detect if we are running on Android or not.
|
||||||
|
*
|
||||||
|
* @return true if we are running on an Android VM, otherwise false
|
||||||
|
*/
|
||||||
|
protected static boolean isAndroid() {
|
||||||
|
|
||||||
|
String vmVendor = System.getProperty("java.vm.vendor");
|
||||||
|
|
||||||
|
if ((vmVendor != null) &&
|
||||||
|
vmVendor.equals("The Android Project")) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if wolfJCE WKS KeyStore is available for use.
|
||||||
|
*
|
||||||
|
* @return true if WKS KeyStore type available, otherwise false
|
||||||
|
*/
|
||||||
|
protected static boolean WKSAvailable() {
|
||||||
|
|
||||||
|
boolean wksAvailable = false;
|
||||||
|
|
||||||
|
try {
|
||||||
|
KeyStore.getInstance("WKS");
|
||||||
|
wksAvailable = true;
|
||||||
|
} catch (KeyStoreException e) {
|
||||||
|
/* wolfJCE WKS not available, may be that wolfJCE is not being
|
||||||
|
* used or hasn't bee installed in system */
|
||||||
|
}
|
||||||
|
|
||||||
|
return wksAvailable;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Try to get KeyStore instance of type specified and load from
|
||||||
|
* given file using provided password.
|
||||||
|
*
|
||||||
|
* @param file KeyStore file to load into new KeyStore object
|
||||||
|
* @param pass KeyStore password used to verify KeyStore integrity
|
||||||
|
* @param type KeyStore type of file to load
|
||||||
|
*
|
||||||
|
* @return new KeyStore object loaded with KeyStore file, or null
|
||||||
|
* if unable to load KeyStore
|
||||||
|
*/
|
||||||
|
protected static KeyStore LoadKeyStoreFileByType(String file, char[] pass,
|
||||||
|
String type) {
|
||||||
|
|
||||||
|
KeyStore ks = null;
|
||||||
|
FileInputStream stream = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
ks = KeyStore.getInstance(type);
|
||||||
|
|
||||||
|
try {
|
||||||
|
/* Initialize KeyStore, loading certs below will overwrite if
|
||||||
|
* needed, but Android needs this to be initialized here */
|
||||||
|
ks.load(null, null);
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
WolfSSLDebug.log(WolfSSLUtil.class, WolfSSLDebug.ERROR,
|
||||||
|
"Error initializing KeyStore with load(null, null)");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
stream = new FileInputStream(file);
|
||||||
|
ks.load(stream, pass);
|
||||||
|
stream.close();
|
||||||
|
|
||||||
|
} catch (KeyStoreException | IOException | NoSuchAlgorithmException |
|
||||||
|
CertificateException e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ks;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue