org.bouncycastle.jsse.provider.BouncyCastleJsseProvider Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of bctls-jdk15on Show documentation
Show all versions of bctls-jdk15on Show documentation
The Bouncy Castle Java APIs for TLS and DTLS, including a provider for the JSSE.
package org.bouncycastle.jsse.provider;
import java.security.GeneralSecurityException;
import java.security.NoSuchAlgorithmException;
import java.security.Provider;
import java.security.Security;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.bouncycastle.tls.crypto.impl.jcajce.JcaTlsCryptoProvider;
import org.bouncycastle.util.Strings;
@SuppressWarnings("serial")
public class BouncyCastleJsseProvider
extends Provider
{
public static final String PROVIDER_NAME = "BCJSSE";
private static final double PROVIDER_VERSION = 1.0;
private static final String PROVIDER_INFO = "Bouncy Castle JSSE Provider Version 1.0.0";
private Map serviceMap = new HashMap();
private Map creatorMap = new HashMap();
private final boolean isInFipsMode;
public BouncyCastleJsseProvider()
{
super(PROVIDER_NAME, PROVIDER_VERSION, PROVIDER_INFO);
this.isInFipsMode = configure(false, new JcaTlsCryptoProvider());
}
public BouncyCastleJsseProvider(Provider provider)
{
this(false, provider);
}
public BouncyCastleJsseProvider(boolean fipsMode, Provider provider)
{
super(PROVIDER_NAME, PROVIDER_VERSION, PROVIDER_INFO);
this.isInFipsMode = configure(fipsMode, new JcaTlsCryptoProvider().setProvider(provider));
}
public BouncyCastleJsseProvider(String config)
{
super(PROVIDER_NAME, PROVIDER_VERSION, PROVIDER_INFO);
config = config.trim();
boolean fipsMode = false;
String cryptoName = config;
int colonPos = config.indexOf(':');
if (colonPos >= 0)
{
String first = config.substring(0, colonPos).trim();
String second = config.substring(colonPos + 1).trim();
fipsMode = first.equalsIgnoreCase("fips");
cryptoName = second;
}
JcaTlsCryptoProvider cryptoProvider;
try
{
cryptoProvider = createCryptoProvider(cryptoName);
}
catch (GeneralSecurityException e)
{
throw new IllegalArgumentException("unable to set up TlsCrypto: " + e.getMessage(), e);
}
this.isInFipsMode = configure(fipsMode, cryptoProvider);
}
public BouncyCastleJsseProvider(boolean fipsMode, JcaTlsCryptoProvider tlsCryptoProvider)
{
super(PROVIDER_NAME, PROVIDER_VERSION, PROVIDER_INFO);
this.isInFipsMode = configure(fipsMode, tlsCryptoProvider);
}
private JcaTlsCryptoProvider createCryptoProvider(String cryptoName)
throws GeneralSecurityException
{
if (cryptoName.equalsIgnoreCase("default"))
{
return new JcaTlsCryptoProvider();
}
Provider provider = Security.getProvider(cryptoName);
if (provider != null)
{
return new JcaTlsCryptoProvider().setProvider(provider);
}
try
{
Class> cryptoProviderClass = Class.forName(cryptoName);
// the TlsCryptoProvider/Provider class named requires a no-args constructor
Object cryptoProviderInstance = cryptoProviderClass.newInstance();
if (cryptoProviderInstance instanceof JcaTlsCryptoProvider)
{
return (JcaTlsCryptoProvider)cryptoProviderInstance;
}
if (cryptoProviderInstance instanceof Provider)
{
return new JcaTlsCryptoProvider().setProvider((Provider)cryptoProviderInstance);
}
throw new IllegalArgumentException("unrecognized class: " + cryptoName);
}
catch (ClassNotFoundException e)
{
throw new IllegalArgumentException("unable to find Provider/TlsCrypto class: " + cryptoName);
}
catch (InstantiationException e)
{
throw new IllegalArgumentException("unable to create Provider/TlsCrypto class '" + cryptoName + "': " + e.getMessage(), e);
}
catch (IllegalAccessException e)
{
throw new IllegalArgumentException("unable to create Provider/TlsCrypto class '" + cryptoName + "': " + e.getMessage(), e);
}
}
private boolean configure(final boolean fipsMode, final JcaTlsCryptoProvider baseCryptoProvider)
{
// TODO[jsse]: should X.509 be an alias.
addAlgorithmImplementation("KeyManagerFactory.X.509", "org.bouncycastle.jsse.provider.KeyManagerFactory", new EngineCreator()
{
public Object createInstance(Object constructorParameter)
{
return new ProvKeyManagerFactorySpi();
}
});
addAlias("Alg.Alias.KeyManagerFactory.X509", "X.509");
addAlias("Alg.Alias.KeyManagerFactory.PKIX", "X.509");
addAlgorithmImplementation("TrustManagerFactory.PKIX", "org.bouncycastle.jsse.provider.TrustManagerFactory", new EngineCreator()
{
public Object createInstance(Object constructorParameter)
{
return new ProvTrustManagerFactorySpi(baseCryptoProvider.getPkixProvider());
}
});
addAlias("Alg.Alias.TrustManagerFactory.X.509", "PKIX");
addAlias("Alg.Alias.TrustManagerFactory.X509", "PKIX");
addAlgorithmImplementation("SSLContext.TLS", "org.bouncycastle.jsse.provider.SSLContext.TLS",
new EngineCreator()
{
public Object createInstance(Object constructorParameter)
{
return new ProvSSLContextSpi(fipsMode, baseCryptoProvider, new String[]{ "TLSv1.2" });
}
});
addAlgorithmImplementation("SSLContext.TLSV1", "org.bouncycastle.jsse.provider.SSLContext.TLSv1",
new EngineCreator()
{
public Object createInstance(Object constructorParameter)
{
return new ProvSSLContextSpi(fipsMode, baseCryptoProvider, new String[]{ "TLSv1", "TLSv1.1", "TLSv1.2" });
}
});
addAlgorithmImplementation("SSLContext.TLSV1.1", "org.bouncycastle.jsse.provider.SSLContext.TLSv1_1",
new EngineCreator()
{
public Object createInstance(Object constructorParameter)
{
return new ProvSSLContextSpi(fipsMode, baseCryptoProvider, new String[]{ "TLSv1.1", "TLSv1.2" });
}
});
addAlgorithmImplementation("SSLContext.TLSV1.2", "org.bouncycastle.jsse.provider.SSLContext.TLSv1_2",
new EngineCreator()
{
public Object createInstance(Object constructorParameter)
{
return new ProvSSLContextSpi(fipsMode, baseCryptoProvider, new String[]{ "TLSv1.2" });
}
});
addAlgorithmImplementation("SSLContext.DEFAULT", "org.bouncycastle.jsse.provider.SSLContext.Default",
new EngineCreator()
{
public Object createInstance(Object constructorParameter)
{
try
{
ProvSSLContextSpi defaultSSLContextSpi = new ProvSSLContextSpi(fipsMode, baseCryptoProvider, new String[]{ "TLSv1.2" });
defaultSSLContextSpi.engineInit(null, null, null);
return defaultSSLContextSpi;
}
catch (GeneralSecurityException e)
{
// TODO[jsse] Log this exception
return null;
}
}
});
return fipsMode;
}
void addAttribute(String key, String attributeName, String attributeValue)
{
String attributeKey = key + " " + attributeName;
if (containsKey(attributeKey))
{
throw new IllegalStateException("duplicate provider attribute key (" + attributeKey + ") found");
}
put(attributeKey, attributeValue);
}
void addAlgorithmImplementation(String key, String className, EngineCreator creator)
{
if (containsKey(key))
{
throw new IllegalStateException("duplicate provider key (" + key + ") found");
}
addAttribute(key, "ImplementedIn", "Software");
put(key, className);
creatorMap.put(className, creator);
}
void addAlias(String key, String value)
{
if (containsKey(key))
{
throw new IllegalStateException("duplicate provider key (" + key + ") found");
}
put(key, value);
}
public synchronized final Provider.Service getService(String type, String algorithm)
{
String upperCaseAlgName = Strings.toUpperCase(algorithm);
BcJsseService service = serviceMap.get(type + "." + upperCaseAlgName);
if (service == null)
{
String aliasString = "Alg.Alias." + type + ".";
String realName = (String)this.get(aliasString + upperCaseAlgName);
if (realName == null)
{
realName = upperCaseAlgName;
}
String className = (String)this.get(type + "." + realName);
if (className == null)
{
return null;
}
String attributeKeyStart = type + "." + upperCaseAlgName + " ";
List aliases = new ArrayList();
Map attributes = new HashMap();
for (Object key : this.keySet())
{
String sKey = (String)key;
if (sKey.startsWith(aliasString))
{
if (this.get(key).equals(algorithm))
{
aliases.add(sKey.substring(aliasString.length()));
}
}
if (sKey.startsWith(attributeKeyStart))
{
attributes.put(sKey.substring(attributeKeyStart.length()), (String)this.get(sKey));
}
}
service = new BcJsseService(this, type, upperCaseAlgName, className, aliases, getAttributeMap(attributes), creatorMap.get(className));
serviceMap.put(type + "." + upperCaseAlgName, service);
}
return service;
}
public synchronized final Set getServices()
{
Set serviceSet = super.getServices();
Set bcServiceSet = new HashSet();
for (Provider.Service service: serviceSet)
{
bcServiceSet.add(getService(service.getType(), service.getAlgorithm()));
}
return bcServiceSet;
}
private static final Map
© 2015 - 2024 Weber Informatics LLC | Privacy Policy