org.spongycastle.pqc.jcajce.provider.BouncyCastlePQCProvider Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of prov Show documentation
Show all versions of prov Show documentation
Spongy Castle is a package-rename (org.bouncycastle.* to org.spongycastle.*) of Bouncy Castle
intended for the Android platform. Android unfortunately ships with a stripped-down version of
Bouncy Castle, which prevents easy upgrades - Spongy Castle overcomes this and provides a full,
up-to-date version of the Bouncy Castle cryptographic libs.
The newest version!
package org.spongycastle.pqc.jcajce.provider;
import java.io.IOException;
import java.security.AccessController;
import java.security.PrivateKey;
import java.security.PrivilegedAction;
import java.security.Provider;
import java.security.PublicKey;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import org.spongycastle.asn1.ASN1ObjectIdentifier;
import org.spongycastle.asn1.pkcs.PrivateKeyInfo;
import org.spongycastle.asn1.x509.SubjectPublicKeyInfo;
import org.spongycastle.jcajce.provider.config.ConfigurableProvider;
import org.spongycastle.jcajce.provider.config.ProviderConfiguration;
import org.spongycastle.jcajce.provider.util.AlgorithmProvider;
import org.spongycastle.jcajce.provider.util.AsymmetricKeyInfoConverter;
public class BouncyCastlePQCProvider
extends Provider
implements ConfigurableProvider
{
private static String info = "BouncyCastle Post-Quantum Security Provider v1.58";
public static String PROVIDER_NAME = "BCPQC";
public static final ProviderConfiguration CONFIGURATION = null;
private static final Map keyInfoConverters = new HashMap();
/*
* Configurable symmetric ciphers
*/
private static final String ALGORITHM_PACKAGE = "org.spongycastle.pqc.jcajce.provider.";
private static final String[] ALGORITHMS =
{
"Rainbow", "McEliece", "SPHINCS", "NH", "XMSS"
};
/**
* Construct a new provider. This should only be required when
* using runtime registration of the provider using the
* Security.addProvider()
mechanism.
*/
public BouncyCastlePQCProvider()
{
super(PROVIDER_NAME, 1.58, info);
AccessController.doPrivileged(new PrivilegedAction()
{
public Object run()
{
setup();
return null;
}
});
}
private void setup()
{
loadAlgorithms(ALGORITHM_PACKAGE, ALGORITHMS);
}
private void loadAlgorithms(String packageName, String[] names)
{
for (int i = 0; i != names.length; i++)
{
Class clazz = loadClass(BouncyCastlePQCProvider.class, packageName + names[i] + "$Mappings");
if (clazz != null)
{
try
{
((AlgorithmProvider)clazz.newInstance()).configure(this);
}
catch (Exception e)
{ // this should never ever happen!!
throw new InternalError("cannot create instance of "
+ packageName + names[i] + "$Mappings : " + e);
}
}
}
}
public void setParameter(String parameterName, Object parameter)
{
synchronized (CONFIGURATION)
{
//((BouncyCastleProviderConfiguration)CONFIGURATION).setParameter(parameterName, parameter);
}
}
public boolean hasAlgorithm(String type, String name)
{
return containsKey(type + "." + name) || containsKey("Alg.Alias." + type + "." + name);
}
public void addAlgorithm(String key, String value)
{
if (containsKey(key))
{
throw new IllegalStateException("duplicate provider key (" + key + ") found");
}
put(key, value);
}
public void addAlgorithm(String type, ASN1ObjectIdentifier oid, String className)
{
if (!containsKey(type + "." + className))
{
throw new IllegalStateException("primary key (" + type + "." + className + ") not found");
}
addAlgorithm(type + "." + oid, className);
addAlgorithm(type + ".OID." + oid, className);
}
public void addKeyInfoConverter(ASN1ObjectIdentifier oid, AsymmetricKeyInfoConverter keyInfoConverter)
{
synchronized (keyInfoConverters)
{
keyInfoConverters.put(oid, keyInfoConverter);
}
}
public void addAttributes(String key, Map attributeMap)
{
for (Iterator it = attributeMap.keySet().iterator(); it.hasNext();)
{
String attributeName = (String)it.next();
String attributeKey = key + " " + attributeName;
if (containsKey(attributeKey))
{
throw new IllegalStateException("duplicate provider attribute key (" + attributeKey + ") found");
}
put(attributeKey, attributeMap.get(attributeName));
}
}
private static AsymmetricKeyInfoConverter getAsymmetricKeyInfoConverter(ASN1ObjectIdentifier algorithm)
{
synchronized (keyInfoConverters)
{
return (AsymmetricKeyInfoConverter)keyInfoConverters.get(algorithm);
}
}
public static PublicKey getPublicKey(SubjectPublicKeyInfo publicKeyInfo)
throws IOException
{
AsymmetricKeyInfoConverter converter = getAsymmetricKeyInfoConverter(publicKeyInfo.getAlgorithm().getAlgorithm());
if (converter == null)
{
return null;
}
return converter.generatePublic(publicKeyInfo);
}
public static PrivateKey getPrivateKey(PrivateKeyInfo privateKeyInfo)
throws IOException
{
AsymmetricKeyInfoConverter converter = getAsymmetricKeyInfoConverter(privateKeyInfo.getPrivateKeyAlgorithm().getAlgorithm());
if (converter == null)
{
return null;
}
return converter.generatePrivate(privateKeyInfo);
}
static Class loadClass(Class sourceClass, final String className)
{
try
{
ClassLoader loader = sourceClass.getClassLoader();
if (loader != null)
{
return loader.loadClass(className);
}
else
{
return (Class)AccessController.doPrivileged(new PrivilegedAction()
{
public Object run()
{
try
{
return Class.forName(className);
}
catch (Exception e)
{
// ignore - maybe log?
}
return null;
}
});
}
}
catch (ClassNotFoundException e)
{
// ignore - maybe log?
}
return null;
}
}