org.bouncycastle.jsse.provider.ProvKeyManagerFactorySpi Maven / Gradle / Ivy
package org.bouncycastle.jsse.provider;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.security.InvalidAlgorithmParameterException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.UnrecoverableKeyException;
import java.util.List;
import java.util.logging.Logger;
import javax.net.ssl.KeyManager;
import javax.net.ssl.KeyManagerFactorySpi;
import javax.net.ssl.KeyStoreBuilderParameters;
import javax.net.ssl.ManagerFactoryParameters;
import org.bouncycastle.jcajce.util.JcaJceHelper;
import org.bouncycastle.jsse.BCX509ExtendedKeyManager;
import org.bouncycastle.tls.TlsUtils;
class ProvKeyManagerFactorySpi
extends KeyManagerFactorySpi
{
private static final Logger LOG = Logger.getLogger(ProvKeyManagerFactorySpi.class.getName());
static KeyStoreConfig getDefaultKeyStore() throws Exception
{
String defaultType = KeyStore.getDefaultType();
String ksPath = null;
char[] ksPassword = null;
String ksPathProp = PropertyUtils.getStringSystemProperty("javax.net.ssl.keyStore");
if ("NONE".equals(ksPathProp))
{
// Do not try to load any file
}
else if (null != ksPathProp)
{
if (new File(ksPathProp).exists())
{
ksPath = ksPathProp;
}
}
KeyStore ks = createKeyStore(defaultType);
String ksPasswordProp = PropertyUtils.getSensitiveStringSystemProperty("javax.net.ssl.keyStorePassword");
if (null != ksPasswordProp)
{
ksPassword = ksPasswordProp.toCharArray();
}
InputStream ksInput = null;
try
{
if (null == ksPath)
{
LOG.config("Initializing default key store as empty");
}
else
{
LOG.config("Initializing default key store from path: " + ksPath);
ksInput = new BufferedInputStream(new FileInputStream(ksPath));
}
try
{
ks.load(ksInput, ksPassword);
}
catch (NullPointerException e)
{
// work around for NPE in FIPS KeyStore
ks = KeyStore.getInstance("BCFKS");
ks.load(null, null);
}
}
finally
{
if (null != ksInput)
{
ksInput.close();
}
}
return new KeyStoreConfig(ks, ksPassword);
}
protected final boolean isInFipsMode;
protected final JcaJceHelper helper;
protected BCX509ExtendedKeyManager x509KeyManager;
ProvKeyManagerFactorySpi(boolean isInFipsMode, JcaJceHelper helper)
{
this.isInFipsMode = isInFipsMode;
this.helper = helper;
}
@Override
protected KeyManager[] engineGetKeyManagers()
{
if (null == x509KeyManager)
{
throw new IllegalStateException("KeyManagerFactory not initialized");
}
return new KeyManager[]{ x509KeyManager };
}
@Override
protected void engineInit(KeyStore ks, char[] ksPassword)
throws KeyStoreException, NoSuchAlgorithmException, UnrecoverableKeyException
{
// NOTE: When key store is null, we do not try to load defaults
this.x509KeyManager = new ProvX509KeyManagerSimple(isInFipsMode, helper, ks, ksPassword);
}
@Override
protected void engineInit(ManagerFactoryParameters managerFactoryParameters)
throws InvalidAlgorithmParameterException
{
if (managerFactoryParameters instanceof KeyStoreBuilderParameters)
{
List builders = ((KeyStoreBuilderParameters)managerFactoryParameters).getParameters();
this.x509KeyManager = new ProvX509KeyManager(isInFipsMode, helper, builders);
}
else
{
throw new InvalidAlgorithmParameterException("Parameters must be instance of KeyStoreBuilderParameters");
}
}
private static KeyStore createKeyStore(String defaultType)
throws NoSuchProviderException, KeyStoreException
{
String ksType = getKeyStoreType(defaultType);
String ksProv = PropertyUtils.getStringSystemProperty("javax.net.ssl.keyStoreProvider");
return TlsUtils.isNullOrEmpty(ksProv)
? KeyStore.getInstance(ksType)
: KeyStore.getInstance(ksType, ksProv);
}
private static String getKeyStoreType(String defaultType)
{
String ksType = PropertyUtils.getStringSystemProperty("javax.net.ssl.keyStoreType");
return (null == ksType) ? defaultType : ksType;
}
}