Merge pull request #272 from cconlon/WolfSSLKeyX509_CachedEntries
JSSE: cache KeyStore entries in X509ExtendedKeyManagermaster
commit
1dc7d5a741
13
README.md
13
README.md
|
@ -469,6 +469,7 @@ and used by wolfSSL JNI/JSSE.
|
|||
| wolfjsse.enabledSignatureAlgorithms | | String | Restricts enabled signature algorithms |
|
||||
| wolfjsse.keystore.type.required | | String | Restricts KeyStore type |
|
||||
| wolfjsse.clientSessionCache.disabled | | "true" | Disables client session cache |
|
||||
| wolfjsse.X509KeyManager.disableCache | "false" | "true" | Disables X509KeyManager KeyStore entry caching |
|
||||
|
||||
**wolfssl.readWriteByteBufferPool.disabled (String)** - Can be used to disable
|
||||
the static per-thread ByteBuffer pool used in com.wolfssl.WolfSSLSession
|
||||
|
@ -554,6 +555,18 @@ cache. The Java client cache is enabled by default.
|
|||
wolfjsse.clientSessionCache.disabled=true
|
||||
```
|
||||
|
||||
**wolfjsse.X509KeyManager.disableCache (String)** - Can be used to disable
|
||||
KeyStore entry caching in the WolfSSLKeyX509 (X509ExtendedKeyManager) implementation.
|
||||
When set to "true", the X509KeyManager will revert to the original behavior of
|
||||
calling KeyStore methods directly for each operation instead of using cached
|
||||
entries. This can be useful for debugging, compatibility testing, or when
|
||||
KeyStore contents may change dynamically. Caching is enabled by default for
|
||||
performance. This should be set to the String "true" to disable caching:
|
||||
|
||||
```
|
||||
wolfjsse.X509KeyManager.disableCache=true
|
||||
```
|
||||
|
||||
If there are other Security properties you would like to use with wolfJSSE,
|
||||
please contact support@wolfssl.com.
|
||||
|
||||
|
|
|
@ -1081,7 +1081,6 @@ public class WolfSSLImplementSSLSession extends ExtendedSSLSession {
|
|||
throws UnsupportedOperationException {
|
||||
|
||||
byte[] sniRequestArr = null;
|
||||
List<SNIServerName> sniNames = new ArrayList<>(1);
|
||||
|
||||
if (this.ssl == null) {
|
||||
return Collections.emptyList();
|
||||
|
@ -1103,6 +1102,7 @@ public class WolfSSLImplementSSLSession extends ExtendedSSLSession {
|
|||
}
|
||||
|
||||
if (sniRequestArr != null) {
|
||||
List<SNIServerName> sniNames = new ArrayList<>(1);
|
||||
SNIHostName sniName = new SNIHostName(sniRequestArr);
|
||||
sniNames.add(sniName);
|
||||
|
||||
|
|
|
@ -222,8 +222,14 @@ public class WolfSSLKeyManager extends KeyManagerFactorySpi {
|
|||
"initialized before use, please call init()");
|
||||
}
|
||||
|
||||
KeyManager[] km = {new WolfSSLKeyX509(this.store, this.pswd)};
|
||||
return km;
|
||||
try {
|
||||
KeyManager[] km = { new WolfSSLKeyX509(this.store, this.pswd) };
|
||||
return km;
|
||||
|
||||
} catch (KeyStoreException e) {
|
||||
throw new IllegalStateException(
|
||||
"Failed to create WolfSSLKeyX509: " + e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -26,10 +26,16 @@ import java.security.KeyStore;
|
|||
import java.security.KeyStoreException;
|
||||
import java.security.Principal;
|
||||
import java.security.PrivateKey;
|
||||
import java.security.Security;
|
||||
import java.security.cert.Certificate;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Enumeration;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.Arrays;
|
||||
import javax.net.ssl.SSLEngine;
|
||||
import javax.net.ssl.X509ExtendedKeyManager;
|
||||
import com.wolfssl.WolfSSLDebug;
|
||||
|
@ -43,71 +49,257 @@ import com.wolfssl.WolfSSLDebug;
|
|||
*/
|
||||
public class WolfSSLKeyX509 extends X509ExtendedKeyManager {
|
||||
|
||||
private KeyStore store;
|
||||
private char[] password;
|
||||
/* Security property to control caching behavior. When set to "true",
|
||||
* disables KeyStore entry caching and reverts to calling KeyStore
|
||||
* methods directly for each operation. */
|
||||
private static final String DISABLE_CACHE_PROPERTY =
|
||||
"wolfjsse.X509KeyManager.disableCache";
|
||||
|
||||
/* Reference to original KeyStore for non-cached operations */
|
||||
private final KeyStore keyStore;
|
||||
private final char[] keyStorePassword;
|
||||
|
||||
/* Cache behavior determined once at construction time */
|
||||
private final boolean cacheDisabled;
|
||||
|
||||
/* Cache for KeyStore entries to avoid concurrent access issues. Prior
|
||||
* to the addition of these caches, WolfSSLKeyX509 called down directly
|
||||
* to the underlying KeyStore for each operation. Since the KeyStore
|
||||
* operations are synchronized, concurrent threads accessing this
|
||||
* KeyManager can queue up in that scenario and hurt performance.
|
||||
* These caches are only used if caching has not been disabled via
|
||||
* Security property. */
|
||||
private final Map<String, X509Certificate> certificateCache;
|
||||
private final Map<String, X509Certificate[]> certificateChainCache;
|
||||
private final Map<String, PrivateKey> privateKeyCache;
|
||||
private final Set<String> aliasSet;
|
||||
|
||||
/**
|
||||
* Create new WolfSSLKeyX509 object
|
||||
*
|
||||
* @param in input KeyStore to use with this object
|
||||
* @param store input KeyStore to cache entries from
|
||||
* @param password input KeyStore password
|
||||
* @throws KeyStoreException if unable to populate cache from KeyStore
|
||||
*/
|
||||
public WolfSSLKeyX509(KeyStore in, char[] password) {
|
||||
this.store = in;
|
||||
this.password = password;
|
||||
public WolfSSLKeyX509(KeyStore store, char[] password)
|
||||
throws KeyStoreException {
|
||||
|
||||
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
||||
() -> "creating new WolfSSLKeyX509 object");
|
||||
|
||||
/* Check Security property once at construction time */
|
||||
this.cacheDisabled = "true".equalsIgnoreCase(
|
||||
Security.getProperty(DISABLE_CACHE_PROPERTY));
|
||||
|
||||
if (this.cacheDisabled) {
|
||||
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
||||
() -> "KeyStore caching disabled via " +
|
||||
DISABLE_CACHE_PROPERTY +
|
||||
" Security property, using direct KeyStore access");
|
||||
|
||||
this.keyStore = store;
|
||||
this.keyStorePassword =
|
||||
(password != null) ? password.clone() : null;
|
||||
|
||||
this.certificateCache = null;
|
||||
this.certificateChainCache = null;
|
||||
this.privateKeyCache = null;
|
||||
this.aliasSet = null;
|
||||
|
||||
} else {
|
||||
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
||||
() -> "KeyStore caching enabled, populating caches");
|
||||
|
||||
this.keyStore = null;
|
||||
this.keyStorePassword = null;
|
||||
|
||||
/* Initialize cache data structures */
|
||||
this.certificateCache = new HashMap<String, X509Certificate>();
|
||||
this.certificateChainCache =
|
||||
new HashMap<String, X509Certificate[]>();
|
||||
this.privateKeyCache = new HashMap<String, PrivateKey>();
|
||||
this.aliasSet = new LinkedHashSet<String>();
|
||||
|
||||
/* Populate caches from KeyStore */
|
||||
populateCache(store, password);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return array of aliases from current KeyStore that matches provided
|
||||
* type and issuers array.
|
||||
* Populate internal caches with all entries from KeyStore
|
||||
*
|
||||
* @param store KeyStore to read entries from
|
||||
* @param password KeyStore password to access private keys
|
||||
* @throws KeyStoreException if unable to read from KeyStore
|
||||
*/
|
||||
private void populateCache(KeyStore store, char[] password)
|
||||
throws KeyStoreException {
|
||||
|
||||
if (store == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Enumeration<String> aliases = store.aliases();
|
||||
|
||||
while (aliases.hasMoreElements()) {
|
||||
String alias = aliases.nextElement();
|
||||
aliasSet.add(alias);
|
||||
|
||||
try {
|
||||
/* Cache individual certificate */
|
||||
Certificate cert = store.getCertificate(alias);
|
||||
if (cert instanceof X509Certificate) {
|
||||
certificateCache.put(alias, (X509Certificate)cert);
|
||||
}
|
||||
|
||||
/* Cache certificate chain */
|
||||
Certificate[] certChain = store.getCertificateChain(alias);
|
||||
if (certChain != null) {
|
||||
int x509Cnt = 0;
|
||||
|
||||
/* Count X509Certificate entries */
|
||||
for (int i = 0; i < certChain.length; i++) {
|
||||
if (certChain[i] instanceof X509Certificate) {
|
||||
x509Cnt++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Store X509Certificate chain */
|
||||
if (x509Cnt > 0) {
|
||||
int idx = 0;
|
||||
X509Certificate[] x509Chain =
|
||||
new X509Certificate[x509Cnt];
|
||||
|
||||
for (int i = 0; i < certChain.length; i++) {
|
||||
if (certChain[i] instanceof X509Certificate) {
|
||||
x509Chain[idx++] = (X509Certificate)certChain[i];
|
||||
}
|
||||
}
|
||||
certificateChainCache.put(alias, x509Chain);
|
||||
}
|
||||
}
|
||||
|
||||
/* Cache private key */
|
||||
PrivateKey key = (PrivateKey)store.getKey(alias, password);
|
||||
if (key != null) {
|
||||
privateKeyCache.put(alias, key);
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
WolfSSLDebug.log(getClass(), WolfSSLDebug.ERROR,
|
||||
() -> "Error caching entry for alias: " + alias + ", " + e);
|
||||
/* Continue processing other aliases */
|
||||
}
|
||||
}
|
||||
|
||||
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
||||
() -> "Cached " + aliasSet.size() + " aliases from KeyStore");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return array of aliases from KeyStore that matches provided
|
||||
* type and issuers array (non-cached version).
|
||||
*
|
||||
* Returns:
|
||||
* null - if current KeyStore is null, error getting aliases from store,
|
||||
* or no alias mathes found in current KeyStore.
|
||||
* null - if no alias matches found in KeyStore.
|
||||
* String[] - aliases, if found that match type and/or issuers
|
||||
*/
|
||||
private String[] getAliases(String type, Principal[] issuers) {
|
||||
Enumeration<String> aliases = null;
|
||||
private String[] getAliasesFromKeyStore(String type, Principal[] issuers)
|
||||
throws KeyStoreException {
|
||||
|
||||
int i;
|
||||
ArrayList<String> ret = new ArrayList<String>();
|
||||
|
||||
if (store == null) {
|
||||
if (keyStore == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
aliases = this.store.aliases();
|
||||
} catch (KeyStoreException ex) {
|
||||
WolfSSLDebug.log(getClass(), WolfSSLDebug.ERROR,
|
||||
() -> "Error getting aliases from current KeyStore");
|
||||
return null;
|
||||
}
|
||||
Enumeration<String> aliases = keyStore.aliases();
|
||||
|
||||
/* loop through each alias in KeyStore */
|
||||
/* loop through each KeyStore alias */
|
||||
while (aliases.hasMoreElements()) {
|
||||
String current = aliases.nextElement();
|
||||
X509Certificate cert = null;
|
||||
try {
|
||||
cert = (X509Certificate)this.store.getCertificate(current);
|
||||
} catch (KeyStoreException ex) {
|
||||
WolfSSLDebug.log(getClass(), WolfSSLDebug.ERROR,
|
||||
() -> "Error getting certificate from KeyStore " +
|
||||
"for alias: " + current + ", continuing to next alias");
|
||||
Certificate cert = keyStore.getCertificate(current);
|
||||
|
||||
if (!(cert instanceof X509Certificate)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
X509Certificate x509cert = (X509Certificate)cert;
|
||||
|
||||
if (type != null &&
|
||||
!x509cert.getPublicKey().getAlgorithm().equals(type)) {
|
||||
/* different public key type, skip */
|
||||
continue;
|
||||
}
|
||||
|
||||
/* if issuers is null then it does not matter which issuer */
|
||||
if (issuers == null) {
|
||||
ret.add(current);
|
||||
}
|
||||
else {
|
||||
/* search through issuers for matching issuer name */
|
||||
for (i = 0; i < issuers.length; i++) {
|
||||
String certIssuer = x509cert.getIssuerDN().getName();
|
||||
String issuerName = issuers[i].getName();
|
||||
|
||||
/* normalize spaces after commas, needed on some JDKs */
|
||||
certIssuer = certIssuer.replaceAll(", ", ",");
|
||||
issuerName = issuerName.replaceAll(", ", ",");
|
||||
|
||||
if (certIssuer.equals(issuerName)) {
|
||||
/* matched issuer, add alias and continue on */
|
||||
ret.add(current);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ret.size() == 0) {
|
||||
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
||||
() -> "No aliases found in KeyStore that match type " +
|
||||
"and/or issuer");
|
||||
return null;
|
||||
}
|
||||
|
||||
return ret.toArray(new String[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return array of aliases that matches provided type and issuers array.
|
||||
* Uses either cached entries or direct KeyStore access based on Security
|
||||
* property configuration.
|
||||
*
|
||||
* Returns:
|
||||
* null - if no alias matches found.
|
||||
* String[] - aliases, if found that match type and/or issuers
|
||||
*/
|
||||
private String[] getAliases(String type, Principal[] issuers) {
|
||||
|
||||
/* Check if caching is disabled, use direct KeyStore access */
|
||||
if (this.cacheDisabled) {
|
||||
try {
|
||||
return getAliasesFromKeyStore(type, issuers);
|
||||
} catch (KeyStoreException e) {
|
||||
WolfSSLDebug.log(getClass(), WolfSSLDebug.ERROR,
|
||||
() -> "Error accessing KeyStore directly: " +
|
||||
e.getMessage());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/* Use cached entries */
|
||||
int i;
|
||||
ArrayList<String> ret = new ArrayList<String>();
|
||||
|
||||
/* loop through each cached alias */
|
||||
for (String current : aliasSet) {
|
||||
X509Certificate cert = certificateCache.get(current);
|
||||
|
||||
if (type != null && cert != null &&
|
||||
!cert.getPublicKey().getAlgorithm().equals(type)) {
|
||||
|
||||
/* free native memory early if X509Certificate is WolfSSLX509 */
|
||||
if (cert instanceof WolfSSLX509) {
|
||||
((WolfSSLX509)cert).free();
|
||||
}
|
||||
cert = null;
|
||||
|
||||
/* different public key type, skip */
|
||||
continue;
|
||||
}
|
||||
|
@ -135,11 +327,11 @@ public class WolfSSLKeyX509 extends X509ExtendedKeyManager {
|
|||
}
|
||||
}
|
||||
}
|
||||
} /* end while */
|
||||
}
|
||||
|
||||
if (ret.size() == 0) {
|
||||
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
||||
() -> "No aliases found in KeyStore that match type " +
|
||||
() -> "No aliases found in cache that match type " +
|
||||
"and/or issuer");
|
||||
return null;
|
||||
}
|
||||
|
@ -244,59 +436,140 @@ public class WolfSSLKeyX509 extends X509ExtendedKeyManager {
|
|||
@Override
|
||||
public X509Certificate[] getCertificateChain(String alias) {
|
||||
|
||||
X509Certificate[] ret = null;
|
||||
|
||||
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
||||
() -> "entered getCertificateChain(), alias: " + alias);
|
||||
|
||||
if (store == null || alias == null) {
|
||||
if (alias == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
Certificate[] certs = this.store.getCertificateChain(alias);
|
||||
if (certs != null) {
|
||||
int x509Cnt = 0;
|
||||
/* Check if caching is disabled, use direct KeyStore access */
|
||||
if (this.cacheDisabled) {
|
||||
try {
|
||||
if (keyStore == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/* count up X509Certificate type in certs[] */
|
||||
for (int i = 0; i < certs.length; i++) {
|
||||
if (certs[i] instanceof X509Certificate) {
|
||||
Certificate[] certChain = keyStore.getCertificateChain(alias);
|
||||
if (certChain == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/* Convert to X509Certificate array */
|
||||
int x509Cnt = 0;
|
||||
for (int i = 0; i < certChain.length; i++) {
|
||||
if (certChain[i] instanceof X509Certificate) {
|
||||
x509Cnt++;
|
||||
}
|
||||
}
|
||||
|
||||
/* store into X509Certificate array */
|
||||
ret = new X509Certificate[x509Cnt];
|
||||
for (int i = 0; i < certs.length; i++) {
|
||||
if (certs[i] instanceof X509Certificate) {
|
||||
ret[i] = (X509Certificate)certs[i];
|
||||
if (x509Cnt == 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
X509Certificate[] x509Chain = new X509Certificate[x509Cnt];
|
||||
int idx = 0;
|
||||
for (int i = 0; i < certChain.length; i++) {
|
||||
if (certChain[i] instanceof X509Certificate) {
|
||||
x509Chain[idx++] = (X509Certificate)certChain[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} catch (KeyStoreException ex) {
|
||||
return null;
|
||||
return x509Chain;
|
||||
|
||||
} catch (KeyStoreException e) {
|
||||
WolfSSLDebug.log(getClass(), WolfSSLDebug.ERROR,
|
||||
() -> "Error accessing certificate chain from KeyStore: " +
|
||||
e.getMessage());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
/* Return cached certificate chain */
|
||||
return certificateChainCache.get(alias);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PrivateKey getPrivateKey(String alias) {
|
||||
|
||||
PrivateKey key = null;
|
||||
|
||||
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
||||
() -> "entered getPrivateKey(), alias: " + alias);
|
||||
|
||||
try {
|
||||
key = (PrivateKey)store.getKey(alias, password);
|
||||
} catch (Exception e) {
|
||||
/* @TODO unable to get key */
|
||||
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
||||
() -> "failed to load private key: " + e);
|
||||
if (alias == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/* Check if caching is disabled, use direct KeyStore access */
|
||||
if (this.cacheDisabled) {
|
||||
try {
|
||||
if (keyStore == null || keyStorePassword == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (PrivateKey)keyStore.getKey(alias, keyStorePassword);
|
||||
|
||||
} catch (Exception e) {
|
||||
WolfSSLDebug.log(getClass(), WolfSSLDebug.ERROR,
|
||||
() -> "Error accessing private key from KeyStore: " +
|
||||
e.getMessage());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/* Return cached private key */
|
||||
return privateKeyCache.get(alias);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear sensitive data when object is garbage collected
|
||||
*/
|
||||
@Override
|
||||
protected void finalize() throws Throwable {
|
||||
try {
|
||||
/* Clear KeyStore password if present */
|
||||
if (keyStorePassword != null) {
|
||||
Arrays.fill(keyStorePassword, (char)0);
|
||||
}
|
||||
|
||||
/* Clear cached private keys */
|
||||
if (privateKeyCache != null) {
|
||||
privateKeyCache.clear();
|
||||
}
|
||||
|
||||
/* Free WolfSSLX509 certificates if present */
|
||||
if (certificateCache != null) {
|
||||
for (X509Certificate cert : certificateCache.values()) {
|
||||
if (cert instanceof WolfSSLX509) {
|
||||
((WolfSSLX509)cert).free();
|
||||
}
|
||||
}
|
||||
certificateCache.clear();
|
||||
}
|
||||
|
||||
/* Free WolfSSLX509 certificate chains if present */
|
||||
if (certificateChainCache != null) {
|
||||
for (X509Certificate[] chain : certificateChainCache.values()) {
|
||||
if (chain != null) {
|
||||
for (X509Certificate cert : chain) {
|
||||
if (cert instanceof WolfSSLX509) {
|
||||
((WolfSSLX509)cert).free();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
certificateChainCache.clear();
|
||||
}
|
||||
|
||||
if (aliasSet != null) {
|
||||
aliasSet.clear();
|
||||
}
|
||||
|
||||
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
||||
() -> "WolfSSLKeyX509 finalized, sensitive data cleared");
|
||||
|
||||
} finally {
|
||||
super.finalize();
|
||||
}
|
||||
return key;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@ import static org.junit.Assert.assertNotNull;
|
|||
import static org.junit.Assert.fail;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.security.KeyStore;
|
||||
import java.security.Principal;
|
||||
import java.security.Provider;
|
||||
import java.security.Security;
|
||||
|
@ -459,6 +460,657 @@ public class WolfSSLKeyX509Test {
|
|||
pass("\t... passed");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConstructorWithInvalidKeyStore()
|
||||
throws NoSuchAlgorithmException, KeyStoreException,
|
||||
KeyManagementException, CertificateException, IOException,
|
||||
NoSuchProviderException, UnrecoverableKeyException {
|
||||
|
||||
System.out.print("\tTesting with invalid KeyStore");
|
||||
|
||||
/* Test with null KeyStore - should not throw exception */
|
||||
try {
|
||||
com.wolfssl.provider.jsse.WolfSSLKeyX509 km =
|
||||
new com.wolfssl.provider.jsse.WolfSSLKeyX509(null, null);
|
||||
/* Should succeed with empty cache */
|
||||
} catch (Exception e) {
|
||||
error("\t... failed");
|
||||
fail("Constructor should handle null KeyStore gracefully: " + e);
|
||||
}
|
||||
|
||||
pass("\t... passed");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCacheConsistencyWithKeyStore()
|
||||
throws NoSuchAlgorithmException, KeyStoreException,
|
||||
KeyManagementException, CertificateException, IOException,
|
||||
NoSuchProviderException, UnrecoverableKeyException {
|
||||
|
||||
KeyManager[] list;
|
||||
X509KeyManager km;
|
||||
String[] aliases;
|
||||
|
||||
System.out.print("\tTesting cache consistency");
|
||||
|
||||
/* Create KeyManager with cached WolfSSLKeyX509 */
|
||||
list = tf.createKeyManager("SunX509", tf.allJKS, provider);
|
||||
km = (X509KeyManager) list[0];
|
||||
|
||||
/* Test that cached aliases match what we expect */
|
||||
aliases = km.getClientAliases("RSA", null);
|
||||
if (aliases == null || aliases.length == 0) {
|
||||
error("\t... failed");
|
||||
fail("No RSA client aliases found in cache");
|
||||
}
|
||||
|
||||
/* Test certificate chain consistency */
|
||||
for (String alias : aliases) {
|
||||
if (alias != null) {
|
||||
X509Certificate[] chain = km.getCertificateChain(alias);
|
||||
if (chain == null) {
|
||||
error("\t... failed");
|
||||
fail("Certificate chain missing from cache for alias: " + alias);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Test private key consistency */
|
||||
for (String alias : aliases) {
|
||||
if (alias != null) {
|
||||
/* Private key may be null for some aliases, that's expected */
|
||||
km.getPrivateKey(alias);
|
||||
}
|
||||
}
|
||||
|
||||
pass("\t... passed");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEmptyKeyStoreCache()
|
||||
throws NoSuchAlgorithmException, KeyStoreException,
|
||||
KeyManagementException, CertificateException, IOException,
|
||||
NoSuchProviderException, UnrecoverableKeyException {
|
||||
|
||||
System.out.print("\tTesting empty KeyStore cache");
|
||||
|
||||
try {
|
||||
/* Create empty KeyStore */
|
||||
KeyStore emptyStore = KeyStore.getInstance("JKS");
|
||||
emptyStore.load(null, null);
|
||||
|
||||
/* Create WolfSSLKeyX509 with empty KeyStore */
|
||||
com.wolfssl.provider.jsse.WolfSSLKeyX509 km =
|
||||
new com.wolfssl.provider.jsse.WolfSSLKeyX509(emptyStore, null);
|
||||
|
||||
/* Test methods with empty cache */
|
||||
String[] aliases = km.getClientAliases("RSA", null);
|
||||
if (aliases != null) {
|
||||
error("\t... failed");
|
||||
fail("Expected null aliases from empty KeyStore");
|
||||
}
|
||||
|
||||
aliases = km.getServerAliases("RSA", null);
|
||||
if (aliases != null) {
|
||||
error("\t... failed");
|
||||
fail("Expected null server aliases from empty KeyStore");
|
||||
}
|
||||
|
||||
String alias = km.chooseClientAlias(new String[] {"RSA"}, null, null);
|
||||
if (alias != null) {
|
||||
error("\t... failed");
|
||||
fail("Expected null client alias from empty KeyStore");
|
||||
}
|
||||
|
||||
alias = km.chooseServerAlias("RSA", null, null);
|
||||
if (alias != null) {
|
||||
error("\t... failed");
|
||||
fail("Expected null server alias from empty KeyStore");
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
error("\t... failed");
|
||||
fail("Empty KeyStore test failed: " + e);
|
||||
}
|
||||
|
||||
pass("\t... passed");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNullKeyStoreCache()
|
||||
throws NoSuchAlgorithmException, KeyStoreException,
|
||||
KeyManagementException, CertificateException, IOException,
|
||||
NoSuchProviderException, UnrecoverableKeyException {
|
||||
|
||||
System.out.print("\tTesting null KeyStore cache");
|
||||
|
||||
try {
|
||||
/* Create WolfSSLKeyX509 with null KeyStore */
|
||||
com.wolfssl.provider.jsse.WolfSSLKeyX509 km =
|
||||
new com.wolfssl.provider.jsse.WolfSSLKeyX509(null, null);
|
||||
|
||||
/* Test methods with null KeyStore */
|
||||
String[] aliases = km.getClientAliases("RSA", null);
|
||||
if (aliases != null) {
|
||||
error("\t... failed");
|
||||
fail("Expected null aliases from null KeyStore");
|
||||
}
|
||||
|
||||
aliases = km.getServerAliases("RSA", null);
|
||||
if (aliases != null) {
|
||||
error("\t... failed");
|
||||
fail("Expected null server aliases from null KeyStore");
|
||||
}
|
||||
|
||||
String alias = km.chooseClientAlias(new String[] {"RSA"}, null, null);
|
||||
if (alias != null) {
|
||||
error("\t... failed");
|
||||
fail("Expected null client alias from null KeyStore");
|
||||
}
|
||||
|
||||
alias = km.chooseServerAlias("RSA", null, null);
|
||||
if (alias != null) {
|
||||
error("\t... failed");
|
||||
fail("Expected null server alias from null KeyStore");
|
||||
}
|
||||
|
||||
X509Certificate[] chain = km.getCertificateChain("nonexistent");
|
||||
if (chain != null) {
|
||||
error("\t... failed");
|
||||
fail("Expected null certificate chain from null KeyStore");
|
||||
}
|
||||
|
||||
java.security.PrivateKey key = km.getPrivateKey("nonexistent");
|
||||
if (key != null) {
|
||||
error("\t... failed");
|
||||
fail("Expected null private key from null KeyStore");
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
error("\t... failed");
|
||||
fail("Null KeyStore test failed: " + e);
|
||||
}
|
||||
|
||||
pass("\t... passed");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCertificateChainCaching()
|
||||
throws NoSuchAlgorithmException, KeyStoreException,
|
||||
KeyManagementException, CertificateException, IOException,
|
||||
NoSuchProviderException, UnrecoverableKeyException {
|
||||
|
||||
KeyManager[] list;
|
||||
X509KeyManager km;
|
||||
X509Certificate[] chain1, chain2;
|
||||
|
||||
System.out.print("\tTesting cert chain caching");
|
||||
|
||||
list = tf.createKeyManager("SunX509", tf.allJKS, provider);
|
||||
km = (X509KeyManager) list[0];
|
||||
|
||||
/* Get certificate chain twice to test caching */
|
||||
chain1 = km.getCertificateChain("client");
|
||||
chain2 = km.getCertificateChain("client");
|
||||
|
||||
if (chain1 == null) {
|
||||
error("\t... failed");
|
||||
fail("Certificate chain should not be null for 'client' alias");
|
||||
}
|
||||
|
||||
if (chain2 == null) {
|
||||
error("\t... failed");
|
||||
fail("Second certificate chain retrieval should not be null");
|
||||
}
|
||||
|
||||
/* Test that both retrievals return the same cached object */
|
||||
if (chain1 != chain2) {
|
||||
error("\t... failed");
|
||||
fail("Certificate chain caching failed - different objects returned");
|
||||
}
|
||||
|
||||
/* Test with non-existent alias */
|
||||
X509Certificate[] nullChain = km.getCertificateChain("nonexistent");
|
||||
if (nullChain != null) {
|
||||
error("\t... failed");
|
||||
fail("Expected null certificate chain for non-existent alias");
|
||||
}
|
||||
|
||||
/* Test with null alias */
|
||||
nullChain = km.getCertificateChain(null);
|
||||
if (nullChain != null) {
|
||||
error("\t... failed");
|
||||
fail("Expected null certificate chain for null alias");
|
||||
}
|
||||
|
||||
pass("\t... passed");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPrivateKeyCaching()
|
||||
throws NoSuchAlgorithmException, KeyStoreException,
|
||||
KeyManagementException, CertificateException, IOException,
|
||||
NoSuchProviderException, UnrecoverableKeyException {
|
||||
|
||||
KeyManager[] list;
|
||||
X509KeyManager km;
|
||||
java.security.PrivateKey key1, key2;
|
||||
|
||||
System.out.print("\tTesting private key caching");
|
||||
|
||||
list = tf.createKeyManager("SunX509", tf.allJKS, provider);
|
||||
km = (X509KeyManager) list[0];
|
||||
|
||||
/* Get private key twice to test caching */
|
||||
key1 = km.getPrivateKey("client");
|
||||
key2 = km.getPrivateKey("client");
|
||||
|
||||
if (key1 == null) {
|
||||
error("\t... failed");
|
||||
fail("Private key should not be null for 'client' alias");
|
||||
}
|
||||
|
||||
if (key2 == null) {
|
||||
error("\t... failed");
|
||||
fail("Second private key retrieval should not be null");
|
||||
}
|
||||
|
||||
/* Test that both retrievals return the same cached object */
|
||||
if (key1 != key2) {
|
||||
error("\t... failed");
|
||||
fail("Private key caching failed - different objects returned");
|
||||
}
|
||||
|
||||
/* Test with non-existent alias */
|
||||
java.security.PrivateKey nullKey = km.getPrivateKey("nonexistent");
|
||||
if (nullKey != null) {
|
||||
error("\t... failed");
|
||||
fail("Expected null private key for non-existent alias");
|
||||
}
|
||||
|
||||
/* Test with null alias */
|
||||
nullKey = km.getPrivateKey(null);
|
||||
if (nullKey != null) {
|
||||
error("\t... failed");
|
||||
fail("Expected null private key for null alias");
|
||||
}
|
||||
|
||||
pass("\t... passed");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCacheDisabledSecurityProperty()
|
||||
throws NoSuchAlgorithmException, KeyStoreException,
|
||||
KeyManagementException, CertificateException, IOException,
|
||||
NoSuchProviderException, UnrecoverableKeyException {
|
||||
|
||||
System.out.print("\tTesting cache disabled");
|
||||
|
||||
/* Save original property value */
|
||||
String originalValue =
|
||||
Security.getProperty("wolfjsse.X509KeyManager.disableCache");
|
||||
|
||||
try {
|
||||
/* Test with caching disabled */
|
||||
Security.setProperty(
|
||||
"wolfjsse.X509KeyManager.disableCache", "true");
|
||||
|
||||
/* Create KeyManager with caching disabled */
|
||||
KeyStore ks = KeyStore.getInstance("JKS");
|
||||
java.io.FileInputStream fis =
|
||||
new java.io.FileInputStream(tf.allJKS);
|
||||
ks.load(fis, "wolfSSL test".toCharArray());
|
||||
fis.close();
|
||||
|
||||
com.wolfssl.provider.jsse.WolfSSLKeyX509 km =
|
||||
new com.wolfssl.provider.jsse.WolfSSLKeyX509(
|
||||
ks, "wolfSSL test".toCharArray());
|
||||
|
||||
/* Test that operations work with caching disabled */
|
||||
String[] aliases = km.getClientAliases("RSA", null);
|
||||
if (aliases == null || aliases.length == 0) {
|
||||
error("\t\t... failed");
|
||||
fail("No RSA client aliases found with caching disabled");
|
||||
}
|
||||
|
||||
/* Test certificate chain retrieval */
|
||||
X509Certificate[] chain = km.getCertificateChain("client");
|
||||
if (chain == null) {
|
||||
error("\t\t... failed");
|
||||
fail("Certificate chain should not be null with " +
|
||||
"caching disabled");
|
||||
}
|
||||
|
||||
/* Test private key retrieval */
|
||||
java.security.PrivateKey key = km.getPrivateKey("client");
|
||||
if (key == null) {
|
||||
error("\t\t... failed");
|
||||
fail("Private key should not be null with caching disabled");
|
||||
}
|
||||
|
||||
/* Test alias selection */
|
||||
String selectedAlias =
|
||||
km.chooseClientAlias(new String[] {"RSA"}, null, null);
|
||||
if (selectedAlias == null) {
|
||||
error("\t\t... failed");
|
||||
fail("Should be able to choose client alias with " +
|
||||
"caching disabled");
|
||||
}
|
||||
|
||||
} finally {
|
||||
/* Restore original property value */
|
||||
if (originalValue != null) {
|
||||
Security.setProperty(
|
||||
"wolfjsse.X509KeyManager.disableCache", originalValue);
|
||||
} else {
|
||||
/* Remove property if it wasn't set originally */
|
||||
Security.setProperty(
|
||||
"wolfjsse.X509KeyManager.disableCache", "");
|
||||
}
|
||||
}
|
||||
|
||||
pass("\t\t... passed");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCacheEnabledSecurityProperty()
|
||||
throws NoSuchAlgorithmException, KeyStoreException,
|
||||
KeyManagementException, CertificateException, IOException,
|
||||
NoSuchProviderException, UnrecoverableKeyException {
|
||||
|
||||
System.out.print("\tTesting cache enabled");
|
||||
|
||||
/* Save original property value */
|
||||
String originalValue =
|
||||
Security.getProperty("wolfjsse.X509KeyManager.disableCache");
|
||||
|
||||
try {
|
||||
/* Test with caching explicitly enabled */
|
||||
Security.setProperty(
|
||||
"wolfjsse.X509KeyManager.disableCache", "false");
|
||||
|
||||
/* Create KeyManager with caching enabled */
|
||||
KeyStore ks = KeyStore.getInstance("JKS");
|
||||
java.io.FileInputStream fis =
|
||||
new java.io.FileInputStream(tf.allJKS);
|
||||
ks.load(fis, "wolfSSL test".toCharArray());
|
||||
fis.close();
|
||||
|
||||
com.wolfssl.provider.jsse.WolfSSLKeyX509 km =
|
||||
new com.wolfssl.provider.jsse.WolfSSLKeyX509(
|
||||
ks, "wolfSSL test".toCharArray());
|
||||
|
||||
/* Test that operations work with caching enabled */
|
||||
String[] aliases = km.getClientAliases("RSA", null);
|
||||
if (aliases == null || aliases.length == 0) {
|
||||
error("\t\t... failed");
|
||||
fail("No RSA client aliases found with caching enabled");
|
||||
}
|
||||
|
||||
/* Test certificate chain retrieval and caching */
|
||||
X509Certificate[] chain1 = km.getCertificateChain("client");
|
||||
X509Certificate[] chain2 = km.getCertificateChain("client");
|
||||
if (chain1 == null || chain2 == null) {
|
||||
error("\t\t... failed");
|
||||
fail("Certificate chains should not be null " +
|
||||
"with caching enabled");
|
||||
}
|
||||
|
||||
/* With caching enabled, should return same cached object */
|
||||
if (chain1 != chain2) {
|
||||
error("\t\t... failed");
|
||||
fail("Certificate chain caching failed - different " +
|
||||
"objects returned");
|
||||
}
|
||||
|
||||
/* Test private key retrieval and caching */
|
||||
java.security.PrivateKey key1 = km.getPrivateKey("client");
|
||||
java.security.PrivateKey key2 = km.getPrivateKey("client");
|
||||
if (key1 == null || key2 == null) {
|
||||
error("\t\t... failed");
|
||||
fail("Private keys should not be null with caching enabled");
|
||||
}
|
||||
|
||||
/* With caching enabled, should return same cached object */
|
||||
if (key1 != key2) {
|
||||
error("\t\t... failed");
|
||||
fail("Private key caching failed - different objects returned");
|
||||
}
|
||||
|
||||
} finally {
|
||||
/* Restore original property value */
|
||||
if (originalValue != null) {
|
||||
Security.setProperty(
|
||||
"wolfjsse.X509KeyManager.disableCache", originalValue);
|
||||
} else {
|
||||
/* Remove property if it wasn't set originally */
|
||||
Security.setProperty(
|
||||
"wolfjsse.X509KeyManager.disableCache", "");
|
||||
}
|
||||
}
|
||||
|
||||
pass("\t\t... passed");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDefaultCachingBehavior()
|
||||
throws NoSuchAlgorithmException, KeyStoreException,
|
||||
KeyManagementException, CertificateException, IOException,
|
||||
NoSuchProviderException, UnrecoverableKeyException {
|
||||
|
||||
System.out.print("\tTesting default cache behavior");
|
||||
|
||||
/* Save original property value */
|
||||
String originalValue = Security.getProperty(
|
||||
"wolfjsse.X509KeyManager.disableCache");
|
||||
|
||||
try {
|
||||
/* Clear property to test default behavior */
|
||||
Security.setProperty("wolfjsse.X509KeyManager.disableCache", "");
|
||||
|
||||
/* Create KeyManager with default behavior
|
||||
* (should be caching enabled) */
|
||||
KeyStore ks = KeyStore.getInstance("JKS");
|
||||
java.io.FileInputStream fis =
|
||||
new java.io.FileInputStream(tf.allJKS);
|
||||
ks.load(fis, "wolfSSL test".toCharArray());
|
||||
fis.close();
|
||||
|
||||
com.wolfssl.provider.jsse.WolfSSLKeyX509 km =
|
||||
new com.wolfssl.provider.jsse.WolfSSLKeyX509(
|
||||
ks, "wolfSSL test".toCharArray());
|
||||
|
||||
/* Test that operations work with default behavior */
|
||||
String[] aliases = km.getClientAliases("RSA", null);
|
||||
if (aliases == null || aliases.length == 0) {
|
||||
error("\t... failed");
|
||||
fail("No RSA client aliases found with default behavior");
|
||||
}
|
||||
|
||||
/* Test that caching works by default (same objects returned) */
|
||||
X509Certificate[] chain1 = km.getCertificateChain("client");
|
||||
X509Certificate[] chain2 = km.getCertificateChain("client");
|
||||
if (chain1 == null || chain2 == null) {
|
||||
error("\t... failed");
|
||||
fail("Certificate chains should not be null " +
|
||||
"with default behavior");
|
||||
}
|
||||
|
||||
/* Default behavior should be caching enabled */
|
||||
if (chain1 != chain2) {
|
||||
error("\t... failed");
|
||||
fail("Default behavior should enable caching - " +
|
||||
"different objects returned");
|
||||
}
|
||||
|
||||
} finally {
|
||||
/* Restore original property value */
|
||||
if (originalValue != null) {
|
||||
Security.setProperty(
|
||||
"wolfjsse.X509KeyManager.disableCache", originalValue);
|
||||
} else {
|
||||
/* Remove property if it wasn't set originally */
|
||||
Security.setProperty(
|
||||
"wolfjsse.X509KeyManager.disableCache", "");
|
||||
}
|
||||
}
|
||||
|
||||
pass("\t... passed");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCaseInsensitiveSecurityProperty()
|
||||
throws NoSuchAlgorithmException, KeyStoreException,
|
||||
KeyManagementException, CertificateException, IOException,
|
||||
NoSuchProviderException, UnrecoverableKeyException {
|
||||
|
||||
System.out.print("\tCase insensitive cache disable");
|
||||
|
||||
/* Save original property value */
|
||||
String originalValue = Security.getProperty(
|
||||
"wolfjsse.X509KeyManager.disableCache");
|
||||
|
||||
try {
|
||||
/* Test different case variations of "true" */
|
||||
String[] trueVariations = {"true", "TRUE", "True", "tRuE"};
|
||||
|
||||
for (String trueValue : trueVariations) {
|
||||
Security.setProperty(
|
||||
"wolfjsse.X509KeyManager.disableCache", trueValue);
|
||||
|
||||
KeyStore ks = KeyStore.getInstance("JKS");
|
||||
java.io.FileInputStream fis =
|
||||
new java.io.FileInputStream(tf.allJKS);
|
||||
ks.load(fis, "wolfSSL test".toCharArray());
|
||||
fis.close();
|
||||
|
||||
com.wolfssl.provider.jsse.WolfSSLKeyX509 km =
|
||||
new com.wolfssl.provider.jsse.WolfSSLKeyX509(
|
||||
ks, "wolfSSL test".toCharArray());
|
||||
|
||||
/* Should work with any case variation of "true" */
|
||||
String[] aliases = km.getClientAliases("RSA", null);
|
||||
if (aliases == null || aliases.length == 0) {
|
||||
error("\t... failed");
|
||||
fail("No RSA client aliases found with '" +
|
||||
trueValue + "'");
|
||||
}
|
||||
}
|
||||
|
||||
/* Test values that should NOT disable caching */
|
||||
String[] falseVariations = {"false", "FALSE", "False", "0",
|
||||
"no", "disabled", "random"};
|
||||
|
||||
for (String falseValue : falseVariations) {
|
||||
Security.setProperty(
|
||||
"wolfjsse.X509KeyManager.disableCache", falseValue);
|
||||
|
||||
KeyStore ks = KeyStore.getInstance("JKS");
|
||||
java.io.FileInputStream fis =
|
||||
new java.io.FileInputStream(tf.allJKS);
|
||||
ks.load(fis, "wolfSSL test".toCharArray());
|
||||
fis.close();
|
||||
|
||||
com.wolfssl.provider.jsse.WolfSSLKeyX509 km =
|
||||
new com.wolfssl.provider.jsse.WolfSSLKeyX509(
|
||||
ks, "wolfSSL test".toCharArray());
|
||||
|
||||
/* Should have caching enabled (same objects returned) */
|
||||
X509Certificate[] chain1 = km.getCertificateChain("client");
|
||||
X509Certificate[] chain2 = km.getCertificateChain("client");
|
||||
if (chain1 == null || chain2 == null) {
|
||||
error("\t... failed");
|
||||
fail("Certificate chains should not be null with '" +
|
||||
falseValue + "'");
|
||||
}
|
||||
|
||||
if (chain1 != chain2) {
|
||||
error("\t... failed");
|
||||
fail("Caching should be enabled with '" +
|
||||
falseValue + "' - different objects returned");
|
||||
}
|
||||
}
|
||||
|
||||
} finally {
|
||||
/* Restore original property value */
|
||||
if (originalValue != null) {
|
||||
Security.setProperty(
|
||||
"wolfjsse.X509KeyManager.disableCache", originalValue);
|
||||
} else {
|
||||
/* Remove property if it wasn't set originally */
|
||||
Security.setProperty(
|
||||
"wolfjsse.X509KeyManager.disableCache", "");
|
||||
}
|
||||
}
|
||||
|
||||
pass("\t... passed");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNullKeyStoreWithCachingDisabled()
|
||||
throws NoSuchAlgorithmException, KeyStoreException,
|
||||
KeyManagementException, CertificateException, IOException,
|
||||
NoSuchProviderException, UnrecoverableKeyException {
|
||||
|
||||
System.out.print("\tnull KeyStore with no caching");
|
||||
|
||||
/* Save original property value */
|
||||
String originalValue = Security.getProperty(
|
||||
"wolfjsse.X509KeyManager.disableCache");
|
||||
|
||||
try {
|
||||
/* Test with caching disabled and null KeyStore */
|
||||
Security.setProperty(
|
||||
"wolfjsse.X509KeyManager.disableCache", "true");
|
||||
|
||||
com.wolfssl.provider.jsse.WolfSSLKeyX509 km =
|
||||
new com.wolfssl.provider.jsse.WolfSSLKeyX509(null, null);
|
||||
|
||||
/* Test that all operations return null gracefully */
|
||||
String[] aliases = km.getClientAliases("RSA", null);
|
||||
if (aliases != null) {
|
||||
error("\t... failed");
|
||||
fail("Expected null aliases with null KeyStore and " +
|
||||
"caching disabled");
|
||||
}
|
||||
|
||||
X509Certificate[] chain = km.getCertificateChain("client");
|
||||
if (chain != null) {
|
||||
error("\t... failed");
|
||||
fail("Expected null certificate chain with null " +
|
||||
"KeyStore and caching disabled");
|
||||
}
|
||||
|
||||
java.security.PrivateKey key = km.getPrivateKey("client");
|
||||
if (key != null) {
|
||||
error("\t... failed");
|
||||
fail("Expected null private key with null KeyStore " +
|
||||
"and caching disabled");
|
||||
}
|
||||
|
||||
String alias = km.chooseClientAlias(new String[] {"RSA"},
|
||||
null, null);
|
||||
if (alias != null) {
|
||||
error("\t... failed");
|
||||
fail("Expected null alias with null KeyStore and " +
|
||||
"caching disabled");
|
||||
}
|
||||
|
||||
} finally {
|
||||
/* Restore original property value */
|
||||
if (originalValue != null) {
|
||||
Security.setProperty(
|
||||
"wolfjsse.X509KeyManager.disableCache", originalValue);
|
||||
} else {
|
||||
/* Remove property if it wasn't set originally */
|
||||
Security.setProperty(
|
||||
"wolfjsse.X509KeyManager.disableCache", "");
|
||||
}
|
||||
}
|
||||
|
||||
pass("\t... passed");
|
||||
}
|
||||
|
||||
private void pass(String msg) {
|
||||
WolfSSLTestFactory.pass(msg);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue