org.bouncycastle.jcajce.provider.ProvEC Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of bc-fips Show documentation
Show all versions of bc-fips Show documentation
The FIPS 140-3 Bouncy Castle Crypto package is a Java implementation of cryptographic algorithms certified to FIPS 140-3 level 1. This jar contains JCE provider and low-level API for the BC-FJA version 2.0.0, FIPS Certificate #4743. Please see certificate for certified platform details.
package org.bouncycastle.jcajce.provider;
import java.io.IOException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.InvalidParameterException;
import java.security.Key;
import java.security.KeyPair;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.interfaces.ECPrivateKey;
import java.security.interfaces.ECPublicKey;
import java.security.spec.AlgorithmParameterSpec;
import java.security.spec.ECGenParameterSpec;
import java.security.spec.ECParameterSpec;
import java.security.spec.ECPrivateKeySpec;
import java.security.spec.ECPublicKeySpec;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.InvalidParameterSpecException;
import java.security.spec.KeySpec;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.asn1.DERNull;
import org.bouncycastle.asn1.nist.NISTObjectIdentifiers;
import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
import org.bouncycastle.asn1.sec.SECObjectIdentifiers;
import org.bouncycastle.asn1.teletrust.TeleTrusTObjectIdentifiers;
import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
import org.bouncycastle.asn1.x9.X962Parameters;
import org.bouncycastle.asn1.x9.X9ECParameters;
import org.bouncycastle.asn1.x9.X9ObjectIdentifiers;
import org.bouncycastle.crypto.AgreementFactory;
import org.bouncycastle.crypto.Algorithm;
import org.bouncycastle.crypto.AsymmetricKeyPairGenerator;
import org.bouncycastle.crypto.CryptoServicesRegistrar;
import org.bouncycastle.crypto.Parameters;
import org.bouncycastle.crypto.SignatureOperatorFactory;
import org.bouncycastle.crypto.asymmetric.AsymmetricECPrivateKey;
import org.bouncycastle.crypto.asymmetric.AsymmetricECPublicKey;
import org.bouncycastle.crypto.asymmetric.AsymmetricKeyPair;
import org.bouncycastle.crypto.asymmetric.ECDomainParameters;
import org.bouncycastle.crypto.asymmetric.ECDomainParametersID;
import org.bouncycastle.crypto.asymmetric.ECDomainParametersIndex;
import org.bouncycastle.crypto.asymmetric.ECImplicitDomainParameters;
import org.bouncycastle.crypto.asymmetric.NamedECDomainParameters;
import org.bouncycastle.crypto.fips.FipsAlgorithm;
import org.bouncycastle.crypto.fips.FipsEC;
import org.bouncycastle.crypto.fips.FipsKDF;
import org.bouncycastle.crypto.fips.FipsSHS;
import org.bouncycastle.crypto.general.EC;
import org.bouncycastle.crypto.general.SecureHash;
import org.bouncycastle.jcajce.spec.DHUParameterSpec;
import org.bouncycastle.jcajce.spec.ECDomainParameterSpec;
import org.bouncycastle.jcajce.spec.MQVParameterSpec;
import org.bouncycastle.jcajce.spec.UserKeyingMaterialSpec;
import org.bouncycastle.util.Integers;
import org.bouncycastle.util.Properties;
class ProvEC
extends AsymmetricAlgorithmProvider
{
private static final AgreementFactory fipsDHFactory;
private static final AgreementFactory fipsDHUFactory;
private static final AgreementFactory fipsMQVFactory;
private static final SignatureOperatorFactory fipsDsaFactory;
private static final Map generalEcAttributes = new HashMap();
private static final String PREFIX = ProvEC.class.getName() + ".";
private static SignatureOperatorFactory genDsaFactory;
static
{
generalEcAttributes.put("SupportedKeyClasses", "java.security.interfaces.ECPublicKey|java.security.interfaces.ECPrivateKey");
generalEcAttributes.put("SupportedKeyFormats", "PKCS#8|X.509");
if (Properties.isOverrideSet("org.bouncycastle.ec.disable"))
{
fipsDHFactory = null;
fipsDHUFactory = null;
fipsMQVFactory = null;
fipsDsaFactory = null;
}
else
{
fipsDHFactory = new FipsEC.DHAgreementFactory();
fipsDHUFactory = new FipsEC.DHUAgreementFactory();
fipsMQVFactory = Properties.isOverrideSet("org.bouncycastle.ec.disable_mqv") ? null : new FipsEC.MQVAgreementFactory();
fipsDsaFactory = new FipsEC.DSAOperatorFactory();
}
}
private static SignatureOperatorFactory getGeneralDSAFactory()
{
if (CryptoServicesRegistrar.isInApprovedOnlyMode())
{
return null;
}
if (genDsaFactory == null)
{
genDsaFactory = new EC.DSAOperatorFactory();
}
return genDsaFactory;
}
private static final PublicKeyConverter publicKeyConverter = new PublicKeyConverter()
{
public AsymmetricECPublicKey convertKey(Algorithm algorithm, PublicKey key)
throws InvalidKeyException
{
if (key instanceof ECPublicKey)
{
if (key instanceof ProvECPublicKey)
{
return ((ProvECPublicKey)key).getBaseKey();
}
return new ProvECPublicKey(algorithm, (ECPublicKey)key).getBaseKey();
}
else
{
// see if we can build a key from key.getEncoded()
try
{
return new AsymmetricECPublicKey(algorithm, SubjectPublicKeyInfo.getInstance(Utils.getKeyEncoding(key)));
}
catch (Exception e)
{
throw new InvalidKeyException("Cannot identify EC public key: " + e.getMessage(), e);
}
}
}
};
private static final PrivateKeyConverter privateKeyConverter = new PrivateKeyConverter()
{
public AsymmetricECPrivateKey convertKey(Algorithm algorithm, PrivateKey key)
throws InvalidKeyException
{
if (key instanceof ECPrivateKey)
{
if (key instanceof ProvECPrivateKey)
{
return ((ProvECPrivateKey)key).getBaseKey();
}
return new ProvECPrivateKey(algorithm, (ECPrivateKey)key).getBaseKey();
}
else
{
// see if we can build a key from key.getEncoded()
try
{
return new AsymmetricECPrivateKey(algorithm, PrivateKeyInfo.getInstance(Utils.getKeyEncoding(key)));
}
catch (Exception e)
{
throw new InvalidKeyException("Cannot identify EC private key: " + e.getMessage(), e);
}
}
}
};
public void configure(final BouncyCastleFipsProvider provider)
{
provider.addAlgorithmImplementation("AlgorithmParameters.EC", PREFIX + "AlgorithmParametersSpi$EC", new EngineCreator()
{
public Object createInstance(Object constructorParameter)
{
return new ECAlgParams();
}
});
final ParametersCreator dhParametersCreator = new ParametersCreator()
{
public Parameters createParameters(boolean forEncryption, AlgorithmParameterSpec spec, SecureRandom random)
throws InvalidAlgorithmParameterException
{
if (spec != null && !(spec instanceof UserKeyingMaterialSpec))
{
throw new InvalidAlgorithmParameterException("ECDH can only take a UserKeyingMaterialSpec");
}
return FipsEC.DH;
}
};
final ParametersCreator cdhParametersCreator = new ParametersCreator()
{
public Parameters createParameters(boolean forEncryption, AlgorithmParameterSpec spec, SecureRandom random)
throws InvalidAlgorithmParameterException
{
if (spec != null && !(spec instanceof UserKeyingMaterialSpec))
{
throw new InvalidAlgorithmParameterException("ECCDH can only take a UserKeyingMaterialSpec");
}
return FipsEC.CDH;
}
};
final ParametersCreator cdhuParametersCreator = new ParametersCreator()
{
public Parameters createParameters(boolean forEncryption, AlgorithmParameterSpec spec, SecureRandom random)
throws InvalidAlgorithmParameterException
{
try
{
if (!(spec instanceof DHUParameterSpec))
{
throw new InvalidAlgorithmParameterException("ECCDHU can only take an MQVParameterSpec");
}
DHUParameterSpec dhuSpec = (DHUParameterSpec)spec;
if (dhuSpec.getEphemeralPublicKey() != null)
{
return FipsEC.CDHU.using(publicKeyConverter.convertKey(FipsEC.CDHU.getAlgorithm(), dhuSpec.getEphemeralPublicKey()),
privateKeyConverter.convertKey(FipsEC.CDHU.getAlgorithm(), dhuSpec.getEphemeralPrivateKey()),
publicKeyConverter.convertKey(FipsEC.CDHU.getAlgorithm(), dhuSpec.getOtherPartyEphemeralKey()));
}
else
{
return FipsEC.CDHU.using(
privateKeyConverter.convertKey(FipsEC.CDHU.getAlgorithm(), dhuSpec.getEphemeralPrivateKey()),
publicKeyConverter.convertKey(FipsEC.CDHU.getAlgorithm(), dhuSpec.getOtherPartyEphemeralKey()));
}
}
catch (InvalidKeyException e)
{
throw new InvalidAlgorithmParameterException("Unable to convert keys in MQVParameterSpec: " + e.getMessage(), e);
}
}
};
provider.addAlgorithmImplementation("KeyFactory.EC", PREFIX + "KeyFactorySpi$EC", new EngineCreator()
{
public Object createInstance(Object constructorParameter)
{
return new ECKeyFactory(FipsEC.ALGORITHM);
}
});
provider.addAlgorithmImplementation("KeyFactory.ECDSA", PREFIX + "KeyFactorySpi$ECDSA", new EngineCreator()
{
public Object createInstance(Object constructorParameter)
{
return new ECKeyFactory(FipsEC.DSA);
}
});
provider.addAlgorithmImplementation("KeyFactory.ECDH", PREFIX + "KeyFactorySpi$ECDH", new EngineCreator()
{
public Object createInstance(Object constructorParameter)
{
return new ECKeyFactory(FipsEC.DH);
}
});
provider.addAlgorithmImplementation("KeyFactory.ECCDH", PREFIX + "KeyFactorySpi$ECCDH", new EngineCreator()
{
public Object createInstance(Object constructorParameter)
{
return new ECKeyFactory(FipsEC.CDH);
}
});
provider.addAlgorithmImplementation("KeyFactory.ECMQV", PREFIX + "KeyFactorySpi$ECMQV", new EngineCreator()
{
public Object createInstance(Object constructorParameter)
{
return new ECKeyFactory(FipsEC.MQV);
}
});
provider.addAlgorithmImplementation("KeyPairGenerator.EC", PREFIX + "KeyPairGeneratorSpi$EC", new EngineCreator()
{
public Object createInstance(Object constructorParameter)
{
return new ECKeyPairGenerator(provider, FipsEC.ALGORITHM);
}
});
provider.addAlgorithmImplementation("KeyPairGenerator.ECDSA", PREFIX + "KeyPairGeneratorSpi$ECDSA", new EngineCreator()
{
public Object createInstance(Object constructorParameter)
{
return new ECKeyPairGenerator(provider, FipsEC.DSA);
}
});
provider.addAlgorithmImplementation("KeyPairGenerator.ECDH", PREFIX + "KeyPairGeneratorSpi$ECDH", new EngineCreator()
{
public Object createInstance(Object constructorParameter)
{
return new ECKeyPairGenerator(provider, FipsEC.DH);
}
});
provider.addAlgorithmImplementation("KeyPairGenerator.ECCDH", PREFIX + "KeyPairGeneratorSpi$ECCDH", new EngineCreator()
{
public Object createInstance(Object constructorParameter)
{
return new ECKeyPairGenerator(provider, FipsEC.CDH);
}
});
provider.addAlgorithmImplementation("KeyPairGenerator.ECMQV", PREFIX + "KeyPairGeneratorSpi$ECMQV", new EngineCreator()
{
public Object createInstance(Object constructorParameter)
{
return new ECKeyPairGenerator(provider, FipsEC.MQV);
}
});
registerOid(provider, X9ObjectIdentifiers.id_ecPublicKey, "EC", new ECKeyFactory(FipsEC.DSA.getAlgorithm()));
addKeyAgreementAlgorithm(provider, "ECDH", PREFIX + "KeyAgreementSpi$DH", generalEcAttributes, new EngineCreator()
{
public Object createInstance(Object constructorParameter)
{
return new BaseAgreement(fipsDHFactory, publicKeyConverter, privateKeyConverter, dhParametersCreator);
}
});
addKeyAgreementAlgorithm(provider, "ECCDH", PREFIX + "KeyAgreementSpi$CDH", generalEcAttributes, new EngineCreator()
{
public Object createInstance(Object constructorParameter)
{
return new BaseAgreement(fipsDHFactory, publicKeyConverter, privateKeyConverter, cdhParametersCreator);
}
});
provider.addAlias("Alg.Alias.KeyAgreement.ECDHC", "ECCDH");
AsymmetricKeyInfoConverter converter = new ECKeyFactory(FipsEC.DH);
addDHAlgorithm(provider, "SHA1", FipsKDF.AgreementKDFPRF.SHA1, X9ObjectIdentifiers.dhSinglePass_stdDH_sha1kdf_scheme, converter, dhParametersCreator);
addDHAlgorithm(provider, "SHA224", FipsKDF.AgreementKDFPRF.SHA224, SECObjectIdentifiers.dhSinglePass_stdDH_sha224kdf_scheme, converter, dhParametersCreator);
addDHAlgorithm(provider, "SHA256", FipsKDF.AgreementKDFPRF.SHA256, SECObjectIdentifiers.dhSinglePass_stdDH_sha256kdf_scheme, converter, dhParametersCreator);
addDHAlgorithm(provider, "SHA384", FipsKDF.AgreementKDFPRF.SHA384, SECObjectIdentifiers.dhSinglePass_stdDH_sha384kdf_scheme, converter, dhParametersCreator);
addDHAlgorithm(provider, "SHA512", FipsKDF.AgreementKDFPRF.SHA512, SECObjectIdentifiers.dhSinglePass_stdDH_sha512kdf_scheme, converter, dhParametersCreator);
converter = new ECKeyFactory(FipsEC.CDH);
addCDHAlgorithm(provider, "SHA1", FipsKDF.AgreementKDFPRF.SHA1, X9ObjectIdentifiers.dhSinglePass_cofactorDH_sha1kdf_scheme, converter, cdhParametersCreator);
addCDHAlgorithm(provider, "SHA224", FipsKDF.AgreementKDFPRF.SHA224, SECObjectIdentifiers.dhSinglePass_cofactorDH_sha224kdf_scheme, converter, cdhParametersCreator);
addCDHAlgorithm(provider, "SHA256", FipsKDF.AgreementKDFPRF.SHA256, SECObjectIdentifiers.dhSinglePass_cofactorDH_sha256kdf_scheme, converter, cdhParametersCreator);
addCDHAlgorithm(provider, "SHA384", FipsKDF.AgreementKDFPRF.SHA384, SECObjectIdentifiers.dhSinglePass_cofactorDH_sha384kdf_scheme, converter, cdhParametersCreator);
addCDHAlgorithm(provider, "SHA512", FipsKDF.AgreementKDFPRF.SHA512, SECObjectIdentifiers.dhSinglePass_cofactorDH_sha512kdf_scheme, converter, cdhParametersCreator);
addCDHAlgorithm(provider, "SHA512(224)", FipsKDF.AgreementKDFPRF.SHA512_224, null, converter, cdhParametersCreator);
addCDHAlgorithm(provider, "SHA512(256)", FipsKDF.AgreementKDFPRF.SHA512_256, null, converter, cdhParametersCreator);
addConcatCDHAlgorithm(provider, "SHA1", FipsKDF.AgreementKDFPRF.SHA1, cdhParametersCreator);
addConcatCDHAlgorithm(provider, "SHA224", FipsKDF.AgreementKDFPRF.SHA224, cdhParametersCreator);
addConcatCDHAlgorithm(provider, "SHA256", FipsKDF.AgreementKDFPRF.SHA256, cdhParametersCreator);
addConcatCDHAlgorithm(provider, "SHA384", FipsKDF.AgreementKDFPRF.SHA384, cdhParametersCreator);
addConcatCDHAlgorithm(provider, "SHA512", FipsKDF.AgreementKDFPRF.SHA512, cdhParametersCreator);
addConcatCDHAlgorithm(provider, "SHA512(224)", FipsKDF.AgreementKDFPRF.SHA512_224, cdhParametersCreator);
addConcatCDHAlgorithm(provider, "SHA512(256)", FipsKDF.AgreementKDFPRF.SHA512_256, cdhParametersCreator);
addConcatCDHAlgorithm(provider, "SHA3-224", FipsKDF.AgreementKDFPRF.SHA3_224, cdhParametersCreator);
addConcatCDHAlgorithm(provider, "SHA3-256", FipsKDF.AgreementKDFPRF.SHA3_256, cdhParametersCreator);
addConcatCDHAlgorithm(provider, "SHA3-384", FipsKDF.AgreementKDFPRF.SHA3_384, cdhParametersCreator);
addConcatCDHAlgorithm(provider, "SHA3-512", FipsKDF.AgreementKDFPRF.SHA3_512, cdhParametersCreator);
addCDHUAlgorithm(provider, "SHA1", FipsKDF.AgreementKDFPRF.SHA1, cdhuParametersCreator);
addCDHUAlgorithm(provider, "SHA224", FipsKDF.AgreementKDFPRF.SHA224, cdhuParametersCreator);
addCDHUAlgorithm(provider, "SHA256", FipsKDF.AgreementKDFPRF.SHA256, cdhuParametersCreator);
addCDHUAlgorithm(provider, "SHA384", FipsKDF.AgreementKDFPRF.SHA384, cdhuParametersCreator);
addCDHUAlgorithm(provider, "SHA512", FipsKDF.AgreementKDFPRF.SHA512, cdhuParametersCreator);
addCDHUAlgorithm(provider, "SHA512(224)", FipsKDF.AgreementKDFPRF.SHA512_224, cdhuParametersCreator);
addCDHUAlgorithm(provider, "SHA512(256)", FipsKDF.AgreementKDFPRF.SHA512_256, cdhuParametersCreator);
addConcatCDHUAlgorithm(provider, "SHA1", FipsKDF.AgreementKDFPRF.SHA1, cdhuParametersCreator);
addConcatCDHUAlgorithm(provider, "SHA224", FipsKDF.AgreementKDFPRF.SHA224, cdhuParametersCreator);
addConcatCDHUAlgorithm(provider, "SHA256", FipsKDF.AgreementKDFPRF.SHA256, cdhuParametersCreator);
addConcatCDHUAlgorithm(provider, "SHA384", FipsKDF.AgreementKDFPRF.SHA384, cdhuParametersCreator);
addConcatCDHUAlgorithm(provider, "SHA512", FipsKDF.AgreementKDFPRF.SHA512, cdhuParametersCreator);
addConcatCDHUAlgorithm(provider, "SHA512(224)", FipsKDF.AgreementKDFPRF.SHA512_224, cdhuParametersCreator);
addConcatCDHUAlgorithm(provider, "SHA512(256)", FipsKDF.AgreementKDFPRF.SHA512_256, cdhuParametersCreator);
addConcatCDHUAlgorithm(provider, "SHA3-224", FipsKDF.AgreementKDFPRF.SHA3_224, cdhuParametersCreator);
addConcatCDHUAlgorithm(provider, "SHA3-256", FipsKDF.AgreementKDFPRF.SHA3_256, cdhuParametersCreator);
addConcatCDHUAlgorithm(provider, "SHA3-384", FipsKDF.AgreementKDFPRF.SHA3_384, cdhuParametersCreator);
addConcatCDHUAlgorithm(provider, "SHA3-512", FipsKDF.AgreementKDFPRF.SHA3_512, cdhuParametersCreator);
provider.addAlgorithmImplementation("Signature.NONEWITHECDSA", PREFIX + "SignatureSpi$ecDSAwithNONE", generalEcAttributes, new EngineCreator()
{
public Object createInstance(Object constructorParameter)
{
return new BaseSignature(provider, fipsDsaFactory, publicKeyConverter, privateKeyConverter, FipsEC.DSA.withDigestAlgorithm(null));
}
});
provider.addAlias("Signature", "NONEWITHECDSA", "RAWECDSA");
if (!CryptoServicesRegistrar.isInApprovedOnlyMode())
{
provider.addAlgorithmImplementation("Signature.SHA1WITHECDDSA", PREFIX + "SignatureSpi$ecDetDSA", generalEcAttributes, new GuardedEngineCreator(new EngineCreator()
{
public Object createInstance(Object constructorParameter)
{
return new BaseSignature(provider, getGeneralDSAFactory(), publicKeyConverter, privateKeyConverter, EC.DDSA.withDigestAlgorithm(FipsSHS.Algorithm.SHA1));
}
}));
provider.addAlgorithmImplementation("Signature.SHA224WITHECDDSA", PREFIX + "SignatureSpi$ecDetDSA224", generalEcAttributes, new GuardedEngineCreator(new EngineCreator()
{
public Object createInstance(Object constructorParameter)
{
return new BaseSignature(provider, getGeneralDSAFactory(), publicKeyConverter, privateKeyConverter, EC.DDSA.withDigestAlgorithm(FipsSHS.Algorithm.SHA224));
}
}));
provider.addAlgorithmImplementation("Signature.SHA256WITHECDDSA", PREFIX + "SignatureSpi$ecDetDSA256", generalEcAttributes, new GuardedEngineCreator(new EngineCreator()
{
public Object createInstance(Object constructorParameter)
{
return new BaseSignature(provider, getGeneralDSAFactory(), publicKeyConverter, privateKeyConverter, EC.DDSA.withDigestAlgorithm(FipsSHS.Algorithm.SHA256));
}
}));
provider.addAlgorithmImplementation("Signature.SHA384WITHECDDSA", PREFIX + "SignatureSpi$ecDetDSA384", generalEcAttributes, new GuardedEngineCreator(new EngineCreator()
{
public Object createInstance(Object constructorParameter)
{
return new BaseSignature(provider, getGeneralDSAFactory(), publicKeyConverter, privateKeyConverter, EC.DDSA.withDigestAlgorithm(FipsSHS.Algorithm.SHA384));
}
}));
provider.addAlgorithmImplementation("Signature.SHA512WITHECDDSA", PREFIX + "SignatureSpi$ecDetDSA512", generalEcAttributes, new GuardedEngineCreator(new EngineCreator()
{
public Object createInstance(Object constructorParameter)
{
return new BaseSignature(provider, getGeneralDSAFactory(), publicKeyConverter, privateKeyConverter, EC.DDSA.withDigestAlgorithm(FipsSHS.Algorithm.SHA512));
}
}));
provider.addAlgorithmImplementation("Signature.SHA512(224)WITHECDDSA", PREFIX + "SignatureSpi$ecDetDSA512_224", generalEcAttributes, new GuardedEngineCreator(new EngineCreator()
{
public Object createInstance(Object constructorParameter)
{
return new BaseSignature(provider, getGeneralDSAFactory(), publicKeyConverter, privateKeyConverter, EC.DDSA.withDigestAlgorithm(FipsSHS.Algorithm.SHA512_224));
}
}));
provider.addAlgorithmImplementation("Signature.SHA512(256)WITHECDDSA", PREFIX + "SignatureSpi$ecDetDSA512_256", generalEcAttributes, new GuardedEngineCreator(new EngineCreator()
{
public Object createInstance(Object constructorParameter)
{
return new BaseSignature(provider, getGeneralDSAFactory(), publicKeyConverter, privateKeyConverter, EC.DDSA.withDigestAlgorithm(FipsSHS.Algorithm.SHA512_256));
}
}));
provider.addAlgorithmImplementation("Signature.SHA3-224WITHECDDSA", PREFIX + "SignatureSpi$ecDetDSA3_224", generalEcAttributes, new GuardedEngineCreator(new EngineCreator()
{
public Object createInstance(Object constructorParameter)
{
return new BaseSignature(provider, getGeneralDSAFactory(), publicKeyConverter, privateKeyConverter, EC.DDSA.withDigestAlgorithm(FipsSHS.Algorithm.SHA3_224));
}
}));
provider.addAlgorithmImplementation("Signature.SHA3-256WITHECDDSA", PREFIX + "SignatureSpi$ecDetDSA3_256", generalEcAttributes, new GuardedEngineCreator(new EngineCreator()
{
public Object createInstance(Object constructorParameter)
{
return new BaseSignature(provider, getGeneralDSAFactory(), publicKeyConverter, privateKeyConverter, EC.DDSA.withDigestAlgorithm(FipsSHS.Algorithm.SHA3_256));
}
}));
provider.addAlgorithmImplementation("Signature.SHA3-384WITHECDDSA", PREFIX + "SignatureSpi$ecDetDSA3_384", generalEcAttributes, new GuardedEngineCreator(new EngineCreator()
{
public Object createInstance(Object constructorParameter)
{
return new BaseSignature(provider, getGeneralDSAFactory(), publicKeyConverter, privateKeyConverter, EC.DDSA.withDigestAlgorithm(FipsSHS.Algorithm.SHA3_384));
}
}));
provider.addAlgorithmImplementation("Signature.SHA3-512WITHECDDSA", PREFIX + "SignatureSpi$ecDetDSA3_512", generalEcAttributes, new GuardedEngineCreator(new EngineCreator()
{
public Object createInstance(Object constructorParameter)
{
return new BaseSignature(provider, getGeneralDSAFactory(), publicKeyConverter, privateKeyConverter, EC.DDSA.withDigestAlgorithm(FipsSHS.Algorithm.SHA3_512));
}
}));
provider.addAlias("Alg.Alias.Signature.ECDDSA", "SHA1WITHECDDSA");
provider.addAlias("Alg.Alias.Signature.DETECDSA", "SHA1WITHECDDSA");
provider.addAlias("Alg.Alias.Signature.SHA1WITHDETECDSA", "SHA1WITHECDDSA");
provider.addAlias("Alg.Alias.Signature.SHA224WITHDETECDSA", "SHA224WITHECDDSA");
provider.addAlias("Alg.Alias.Signature.SHA256WITHDETECDSA", "SHA256WITHECDDSA");
provider.addAlias("Alg.Alias.Signature.SHA384WITHDETECDSA", "SHA384WITHECDDSA");
provider.addAlias("Alg.Alias.Signature.SHA512WITHDETECDSA", "SHA512WITHECDDSA");
provider.addAlias("Alg.Alias.Signature.SHA512(224)WITHDETECDSA", "SHA512(224)WITHECDDSA");
provider.addAlias("Alg.Alias.Signature.SHA512(256)WITHDETECDSA", "SHA512(256)WITHECDDSA");
provider.addAlias("Alg.Alias.Signature.SHA3-224WITHDETECDSA", "SHA3-224WITHECDDSA");
provider.addAlias("Alg.Alias.Signature.SHA3-256WITHDETECDSA", "SHA3-256WITHECDDSA");
provider.addAlias("Alg.Alias.Signature.SHA3-384WITHDETECDSA", "SHA3-384WITHECDDSA");
provider.addAlias("Alg.Alias.Signature.SHA3-512WITHDETECDSA", "SHA3-512WITHECDDSA");
}
addSignatureAlgorithm(provider, "SHA1", "ECDSA", PREFIX + "SignatureSpi$ecDSA1", X9ObjectIdentifiers.ecdsa_with_SHA1, generalEcAttributes, new EngineCreator()
{
public Object createInstance(Object constructorParameter)
{
return new BaseSignature(provider, fipsDsaFactory, publicKeyConverter, privateKeyConverter, FipsEC.DSA.withDigestAlgorithm(FipsSHS.Algorithm.SHA1));
}
});
provider.addAlias("Signature", "SHA1WITHECDSA", "ECDSA");
provider.addAlias("Signature", "SHA1WITHECDSA", TeleTrusTObjectIdentifiers.ecSignWithSha1);
addSignatureAlgorithm(provider, "SHA224", "ECDSA", PREFIX + "SignatureSpi$ecDSA224", X9ObjectIdentifiers.ecdsa_with_SHA224, generalEcAttributes, new EngineCreator()
{
public Object createInstance(Object constructorParameter)
{
return new BaseSignature(provider, fipsDsaFactory, publicKeyConverter, privateKeyConverter, FipsEC.DSA.withDigestAlgorithm(FipsSHS.Algorithm.SHA224));
}
});
addSignatureAlgorithm(provider, "SHA256", "ECDSA", PREFIX + "SignatureSpi$ecDSA256", X9ObjectIdentifiers.ecdsa_with_SHA256, generalEcAttributes, new EngineCreator()
{
public Object createInstance(Object constructorParameter)
{
return new BaseSignature(provider, fipsDsaFactory, publicKeyConverter, privateKeyConverter, FipsEC.DSA.withDigestAlgorithm(FipsSHS.Algorithm.SHA256));
}
});
addSignatureAlgorithm(provider, "SHA384", "ECDSA", PREFIX + "SignatureSpi$ecDSA384", X9ObjectIdentifiers.ecdsa_with_SHA384, generalEcAttributes, new EngineCreator()
{
public Object createInstance(Object constructorParameter)
{
return new BaseSignature(provider, fipsDsaFactory, publicKeyConverter, privateKeyConverter, FipsEC.DSA.withDigestAlgorithm(FipsSHS.Algorithm.SHA384));
}
});
addSignatureAlgorithm(provider, "SHA512", "ECDSA", PREFIX + "SignatureSpi$ecDSA512", X9ObjectIdentifiers.ecdsa_with_SHA512, generalEcAttributes, new EngineCreator()
{
public Object createInstance(Object constructorParameter)
{
return new BaseSignature(provider, fipsDsaFactory, publicKeyConverter, privateKeyConverter, FipsEC.DSA.withDigestAlgorithm(FipsSHS.Algorithm.SHA512));
}
});
addSignatureAlgorithm(provider, "SHA512(224)", "ECDSA", PREFIX + "SignatureSpi$ecDSA512_224", null, generalEcAttributes, new EngineCreator()
{
public Object createInstance(Object constructorParameter)
{
return new BaseSignature(provider, fipsDsaFactory, publicKeyConverter, privateKeyConverter, FipsEC.DSA.withDigestAlgorithm(FipsSHS.Algorithm.SHA512_224));
}
});
addSignatureAlgorithm(provider, "SHA512(256)", "ECDSA", PREFIX + "SignatureSpi$ecDSA512_256", null, generalEcAttributes, new EngineCreator()
{
public Object createInstance(Object constructorParameter)
{
return new BaseSignature(provider, fipsDsaFactory, publicKeyConverter, privateKeyConverter, FipsEC.DSA.withDigestAlgorithm(FipsSHS.Algorithm.SHA512_256));
}
});
addSignatureAlgorithm(provider, "SHA3-224", "ECDSA", PREFIX + "SignatureSpi$ecDSA3_224", NISTObjectIdentifiers.id_ecdsa_with_sha3_224, generalEcAttributes, new EngineCreator()
{
public Object createInstance(Object constructorParameter)
{
return new BaseSignature(provider, fipsDsaFactory, publicKeyConverter, privateKeyConverter, FipsEC.DSA.withDigestAlgorithm(FipsSHS.Algorithm.SHA3_224));
}
});
addSignatureAlgorithm(provider, "SHA3-256", "ECDSA", PREFIX + "SignatureSpi$ecDSA3_256", NISTObjectIdentifiers.id_ecdsa_with_sha3_256, generalEcAttributes, new EngineCreator()
{
public Object createInstance(Object constructorParameter)
{
return new BaseSignature(provider, fipsDsaFactory, publicKeyConverter, privateKeyConverter, FipsEC.DSA.withDigestAlgorithm(FipsSHS.Algorithm.SHA3_256));
}
});
addSignatureAlgorithm(provider, "SHA3-384", "ECDSA", PREFIX + "SignatureSpi$ecDSA3_384", NISTObjectIdentifiers.id_ecdsa_with_sha3_384, generalEcAttributes, new EngineCreator()
{
public Object createInstance(Object constructorParameter)
{
return new BaseSignature(provider, fipsDsaFactory, publicKeyConverter, privateKeyConverter, FipsEC.DSA.withDigestAlgorithm(FipsSHS.Algorithm.SHA3_384));
}
});
addSignatureAlgorithm(provider, "SHA3-512", "ECDSA", PREFIX + "SignatureSpi$ecDSA3_512", NISTObjectIdentifiers.id_ecdsa_with_sha3_512, generalEcAttributes, new EngineCreator()
{
public Object createInstance(Object constructorParameter)
{
return new BaseSignature(provider, fipsDsaFactory, publicKeyConverter, privateKeyConverter, FipsEC.DSA.withDigestAlgorithm(FipsSHS.Algorithm.SHA3_512));
}
});
if (!CryptoServicesRegistrar.isInApprovedOnlyMode())
{
addSignatureAlgorithm(provider, "RIPEMD160", "ECDSA", PREFIX + "SignatureSpi$ecDSARipeMD160", TeleTrusTObjectIdentifiers.ecSignWithRipemd160, generalEcAttributes, new GuardedEngineCreator(new EngineCreator()
{
public Object createInstance(Object constructorParameter)
{
return new BaseSignature(provider, getGeneralDSAFactory(), publicKeyConverter, privateKeyConverter, EC.DSA.withDigestAlgorithm(SecureHash.Algorithm.RIPEMD160));
}
}));
}
if (!Properties.isOverrideSet("org.bouncycastle.ec.disable_mqv"))
{
converter = new ECKeyFactory(FipsEC.MQV.getAlgorithm());
final ParametersCreator mqvParametersCreator = new ParametersCreator()
{
public Parameters createParameters(boolean forEncryption, AlgorithmParameterSpec spec, SecureRandom random)
throws InvalidAlgorithmParameterException
{
try
{
if (!(spec instanceof MQVParameterSpec))
{
throw new InvalidAlgorithmParameterException("ECMQV can only take an MQVParameterSpec");
}
MQVParameterSpec mqvSpec = (MQVParameterSpec)spec;
if (mqvSpec.getEphemeralPublicKey() != null)
{
return FipsEC.MQV.using(publicKeyConverter.convertKey(FipsEC.MQV.getAlgorithm(), mqvSpec.getEphemeralPublicKey()),
privateKeyConverter.convertKey(FipsEC.MQV.getAlgorithm(), mqvSpec.getEphemeralPrivateKey()),
publicKeyConverter.convertKey(FipsEC.MQV.getAlgorithm(), mqvSpec.getOtherPartyEphemeralKey()));
}
else
{
return FipsEC.MQV.using(
privateKeyConverter.convertKey(FipsEC.MQV.getAlgorithm(), mqvSpec.getEphemeralPrivateKey()),
publicKeyConverter.convertKey(FipsEC.MQV.getAlgorithm(), mqvSpec.getOtherPartyEphemeralKey()));
}
}
catch (InvalidKeyException e)
{
throw new InvalidAlgorithmParameterException("Unable to convert keys in MQVParameterSpec: " + e.getMessage(), e);
}
}
};
addKeyAgreementAlgorithm(provider, "ECMQV", PREFIX + "KeyAgreementSpi$ECMQV", generalEcAttributes, new EngineCreator()
{
public Object createInstance(Object constructorParameter)
{
return new BaseAgreement(fipsMQVFactory, publicKeyConverter, privateKeyConverter, mqvParametersCreator);
}
});
addMQVAlgorithm(provider, "SHA1", FipsKDF.AgreementKDFPRF.SHA1, X9ObjectIdentifiers.mqvSinglePass_sha1kdf_scheme, converter, mqvParametersCreator);
addMQVAlgorithm(provider, "SHA224", FipsKDF.AgreementKDFPRF.SHA224, SECObjectIdentifiers.mqvSinglePass_sha224kdf_scheme, converter, mqvParametersCreator);
addMQVAlgorithm(provider, "SHA256", FipsKDF.AgreementKDFPRF.SHA256, SECObjectIdentifiers.mqvSinglePass_sha256kdf_scheme, converter, mqvParametersCreator);
addMQVAlgorithm(provider, "SHA384", FipsKDF.AgreementKDFPRF.SHA384, SECObjectIdentifiers.mqvSinglePass_sha384kdf_scheme, converter, mqvParametersCreator);
addMQVAlgorithm(provider, "SHA512", FipsKDF.AgreementKDFPRF.SHA512, SECObjectIdentifiers.mqvSinglePass_sha512kdf_scheme, converter, mqvParametersCreator);
addMQVAlgorithm(provider, "SHA512(224)", FipsKDF.AgreementKDFPRF.SHA512_224, null, converter, mqvParametersCreator);
addMQVAlgorithm(provider, "SHA512(256)", FipsKDF.AgreementKDFPRF.SHA512_256, null, converter, mqvParametersCreator);
addConcatMQVAlgorithm(provider, "SHA1", FipsKDF.AgreementKDFPRF.SHA1, mqvParametersCreator);
addConcatMQVAlgorithm(provider, "SHA224", FipsKDF.AgreementKDFPRF.SHA224, mqvParametersCreator);
addConcatMQVAlgorithm(provider, "SHA256", FipsKDF.AgreementKDFPRF.SHA256, mqvParametersCreator);
addConcatMQVAlgorithm(provider, "SHA384", FipsKDF.AgreementKDFPRF.SHA384, mqvParametersCreator);
addConcatMQVAlgorithm(provider, "SHA512", FipsKDF.AgreementKDFPRF.SHA512, mqvParametersCreator);
addConcatMQVAlgorithm(provider, "SHA512(224)", FipsKDF.AgreementKDFPRF.SHA512_224, mqvParametersCreator);
addConcatMQVAlgorithm(provider, "SHA512(256)", FipsKDF.AgreementKDFPRF.SHA512_256, mqvParametersCreator);
}
}
private void addDHAlgorithm(BouncyCastleFipsProvider provider, String digestName, final FipsKDF.AgreementKDFPRF prf, ASN1ObjectIdentifier algOid, AsymmetricKeyInfoConverter converter, final ParametersCreator dhParametersCreator)
{
String algorithm = "ECDHWITH" + digestName + "KDF";
addKeyAgreementAlgorithm(provider, algorithm, PREFIX + "KeyAgreementSpi$" + algorithm, generalEcAttributes, new EngineCreator()
{
public Object createInstance(Object constructorParameter)
{
return new BaseAgreement(fipsDHFactory, publicKeyConverter, privateKeyConverter, dhParametersCreator, FipsKDF.X963.withPRF(prf));
}
});
if (algOid != null)
{
provider.addAlias("KeyAgreement", algorithm, algOid);
registerOid(provider, algOid, "ECDH", converter);
provider.addAlias("AlgorithmParameters", "EC", algOid);
}
}
private void addCDHAlgorithm(BouncyCastleFipsProvider provider, String digestName, final FipsKDF.AgreementKDFPRF prf, ASN1ObjectIdentifier algOid, AsymmetricKeyInfoConverter converter, final ParametersCreator cdhParametersCreator)
{
String algorithm = "ECCDHWITH" + digestName + "KDF";
addKeyAgreementAlgorithm(provider, algorithm, PREFIX + "KeyAgreementSpi$" + algorithm, generalEcAttributes, new EngineCreator()
{
public Object createInstance(Object constructorParameter)
{
return new BaseAgreement(fipsDHFactory, publicKeyConverter, privateKeyConverter, cdhParametersCreator, FipsKDF.X963.withPRF(prf));
}
});
if (algOid != null)
{
provider.addAlias("KeyAgreement", algorithm, algOid);
registerOid(provider, algOid, "ECCDH", converter);
provider.addAlias("AlgorithmParameters", "EC", algOid);
}
}
private void addConcatCDHAlgorithm(BouncyCastleFipsProvider provider, String digestName, final FipsKDF.AgreementKDFPRF prf, final ParametersCreator cdhParametersCreator)
{
String algorithm = "ECCDHWITH" + digestName + "CKDF";
addKeyAgreementAlgorithm(provider, algorithm, PREFIX + "KeyAgreementSpi$" + algorithm, generalEcAttributes, new EngineCreator()
{
public Object createInstance(Object constructorParameter)
{
return new BaseAgreement(fipsDHFactory, publicKeyConverter, privateKeyConverter, cdhParametersCreator, FipsKDF.CONCATENATION.withPRF(prf));
}
});
}
private void addCDHUAlgorithm(BouncyCastleFipsProvider provider, String digestName, final FipsKDF.AgreementKDFPRF prf, final ParametersCreator cdhParametersCreator)
{
String algorithm = "ECCDHUWITH" + digestName + "KDF";
addKeyAgreementAlgorithm(provider, algorithm, PREFIX + "KeyAgreementSpi$" + algorithm, generalEcAttributes, new EngineCreator()
{
public Object createInstance(Object constructorParameter)
{
return new BaseAgreement(fipsDHUFactory, publicKeyConverter, privateKeyConverter, cdhParametersCreator, FipsKDF.X963.withPRF(prf));
}
});
}
private void addConcatCDHUAlgorithm(BouncyCastleFipsProvider provider, String digestName, final FipsKDF.AgreementKDFPRF prf, final ParametersCreator cdhParametersCreator)
{
String algorithm = "ECCDHUWITH" + digestName + "CKDF";
addKeyAgreementAlgorithm(provider, algorithm, PREFIX + "KeyAgreementSpi$" + algorithm, generalEcAttributes, new EngineCreator()
{
public Object createInstance(Object constructorParameter)
{
return new BaseAgreement(fipsDHUFactory, publicKeyConverter, privateKeyConverter, cdhParametersCreator, FipsKDF.CONCATENATION.withPRF(prf));
}
});
}
private void addMQVAlgorithm(BouncyCastleFipsProvider provider, String digestName, final FipsKDF.AgreementKDFPRF prf, ASN1ObjectIdentifier algOid, AsymmetricKeyInfoConverter converter, final ParametersCreator mqvParametersCreator)
{
String algorithm = "ECMQVWITH" + digestName + "KDF";
addKeyAgreementAlgorithm(provider, algorithm, PREFIX + "KeyAgreementSpi$" + algorithm, generalEcAttributes, new EngineCreator()
{
public Object createInstance(Object constructorParameter)
{
return new BaseAgreement(fipsMQVFactory, publicKeyConverter, privateKeyConverter, mqvParametersCreator, FipsKDF.X963.withPRF(prf));
}
});
if (algOid != null)
{
provider.addAlias("KeyAgreement", algorithm, algOid);
registerOid(provider, algOid, "EC", converter);
provider.addAlias("AlgorithmParameters", "EC", algOid);
}
}
private void addConcatMQVAlgorithm(BouncyCastleFipsProvider provider, String digestName, final FipsKDF.AgreementKDFPRF prf, final ParametersCreator mqvParametersCreator)
{
String algorithm = "ECMQVWITH" + digestName + "CKDF";
addKeyAgreementAlgorithm(provider, algorithm, PREFIX + "KeyAgreementSpi$" + algorithm, generalEcAttributes, new EngineCreator()
{
public Object createInstance(Object constructorParameter)
{
return new BaseAgreement(fipsMQVFactory, publicKeyConverter, privateKeyConverter, mqvParametersCreator, FipsKDF.CONCATENATION.withPRF(prf));
}
});
}
static class ECAlgParams
extends X509AlgorithmParameters
{
private ECDomainParameters domainParameters = ECDomainParametersIndex.lookupDomainParameters(SECObjectIdentifiers.secp521r1);
@Override
protected AlgorithmParameterSpec localEngineGetParameterSpec(Class paramSpec)
throws InvalidParameterSpecException
{
if (ECParameterSpec.class.isAssignableFrom(paramSpec) || paramSpec == AlgorithmParameterSpec.class)
{
return ECUtil.convertToSpec(domainParameters);
}
else if (ECGenParameterSpec.class.isAssignableFrom(paramSpec))
{
if (domainParameters instanceof NamedECDomainParameters)
{
return new ECGenParameterSpec(((NamedECDomainParameters)domainParameters).getID().getId());
}
else
{
ASN1ObjectIdentifier oid = ECDomainParametersIndex.lookupOID(domainParameters);
if (oid != null)
{
return new ECGenParameterSpec(oid.getId());
}
else
{
throw new InvalidParameterSpecException("Cannot identify curve in AlgorithmParameters by name");
}
}
}
throw new InvalidParameterSpecException("AlgorithmParameterSpec not recognized: " + paramSpec.getName());
}
@Override
protected void engineInit(AlgorithmParameterSpec algorithmParameterSpec)
throws InvalidParameterSpecException
{
if (algorithmParameterSpec instanceof ECGenParameterSpec)
{
final ECGenParameterSpec spec = (ECGenParameterSpec)algorithmParameterSpec;
domainParameters = getDomainParametersFromGenSpec(spec);
if (domainParameters == null)
{
throw new InvalidParameterSpecException("EC AlgorithmParameters cannot recognize curve " + spec.getName());
}
}
else if (algorithmParameterSpec instanceof ECDomainParameterSpec)
{
domainParameters = ((ECDomainParameterSpec)algorithmParameterSpec).getDomainParameters();
}
else if (algorithmParameterSpec instanceof ECParameterSpec)
{
domainParameters = ECUtil.convertFromSpec((ECParameterSpec)algorithmParameterSpec);
}
else
{
throw new InvalidParameterSpecException("AlgorithmParameterSpec class not recognized: " + algorithmParameterSpec.getClass().getName());
}
}
protected void localInit(byte[] encoding)
throws IOException
{
domainParameters = decodeCurveParameters(encoding);
}
protected byte[] localGetEncoded()
throws IOException
{
X962Parameters params;
if (domainParameters instanceof NamedECDomainParameters)
{
params = new X962Parameters(((NamedECDomainParameters)domainParameters).getID());
}
else if (domainParameters instanceof ECImplicitDomainParameters) // implicitly CA
{
params = new X962Parameters(DERNull.INSTANCE);
}
else
{
X9ECParameters ecP = new X9ECParameters(
domainParameters.getCurve(),
domainParameters.getG(),
domainParameters.getN(),
domainParameters.getH(),
domainParameters.getSeed());
params = new X962Parameters(ecP);
}
return params.getEncoded();
}
private static ECDomainParameters decodeCurveParameters(byte[] encoding)
throws IOException
{
X962Parameters params = X962Parameters.getInstance(encoding);
X9ECParameters x9;
if (params.isNamedCurve())
{
ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)params.getParameters();
return ECDomainParametersIndex.lookupDomainParameters(oid);
}
else if (!params.isImplicitlyCA())
{
x9 = X9ECParameters.getInstance(params.getParameters());
return new ECDomainParameters(x9.getCurve(), x9.getG(), x9.getN(), x9.getH(), x9.getSeed());
}
else
{
ECDomainParameters ecDomainParameters = CryptoServicesRegistrar.getProperty(CryptoServicesRegistrar.Property.EC_IMPLICITLY_CA);
if (ecDomainParameters == null)
{
throw new IOException("Encoding indicates implicitlyCA but CryptoServicesRegistrar.getProperty(CryptoServicesRegistrar.Property.EC_IMPLICITLY_CA) returns null");
}
return new ECImplicitDomainParameters(ecDomainParameters);
}
}
protected String engineToString()
{
return "EC AlgorithmParameters " + domainParameters;
}
}
static class ECKeyFactory
extends BaseKeyFactory
implements AsymmetricKeyInfoConverter
{
private final Algorithm algorithm;
ECKeyFactory(
Algorithm algorithm)
{
this.algorithm = algorithm;
}
ECKeyFactory(
Parameters parameters)
{
this.algorithm = parameters.getAlgorithm();
}
protected Key engineTranslateKey(
Key key)
throws InvalidKeyException
{
if (key instanceof PublicKey)
{
return new ProvECPublicKey(publicKeyConverter.convertKey(algorithm, (PublicKey)key));
}
else if (key instanceof PrivateKey)
{
return new ProvECPrivateKey(privateKeyConverter.convertKey(algorithm, (PrivateKey)key));
}
else if (key != null)
{
throw new InvalidKeyException("Key type unrecognized: " + key.getClass().getName());
}
throw new InvalidKeyException("Key is null");
}
protected KeySpec engineGetKeySpec(
Key key,
Class spec)
throws InvalidKeySpecException
{
if (spec == null)
{
throw new InvalidKeySpecException("null spec is invalid");
}
if (spec.isAssignableFrom(ECPublicKeySpec.class) && key instanceof ECPublicKey)
{
ECPublicKey k = (ECPublicKey)key;
if (k.getParams() != null)
{
return new ECPublicKeySpec(k.getW(), k.getParams());
}
}
else if (spec.isAssignableFrom(ECPrivateKeySpec.class) && key instanceof ECPrivateKey)
{
ECPrivateKey k = (ECPrivateKey)key;
if (k.getParams() != null)
{
return new ECPrivateKeySpec(k.getS(), k.getParams());
}
}
return super.engineGetKeySpec(key, spec);
}
protected PrivateKey engineGeneratePrivate(
KeySpec keySpec)
throws InvalidKeySpecException
{
if (keySpec instanceof ECPrivateKeySpec)
{
try
{
return new ProvECPrivateKey(algorithm, (ECPrivateKeySpec)keySpec);
}
catch (IllegalArgumentException e)
{
throw new InvalidKeySpecException(e.getMessage(), e);
}
}
return super.engineGeneratePrivate(keySpec);
}
protected PublicKey engineGeneratePublic(
KeySpec keySpec)
throws InvalidKeySpecException
{
if (keySpec instanceof ECPublicKeySpec)
{
try
{
return new ProvECPublicKey(algorithm, (ECPublicKeySpec)keySpec);
}
catch (IllegalArgumentException e)
{
throw new InvalidKeySpecException(e.getMessage(), e);
}
}
return super.engineGeneratePublic(keySpec);
}
public PrivateKey generatePrivate(PrivateKeyInfo keyInfo)
throws IOException
{
return new ProvECPrivateKey(new AsymmetricECPrivateKey(algorithm, keyInfo));
}
public PublicKey generatePublic(SubjectPublicKeyInfo keyInfo)
throws IOException
{
return new ProvECPublicKey(new AsymmetricECPublicKey(algorithm, keyInfo));
}
}
static class ECKeyPairGenerator
extends java.security.KeyPairGenerator
{
private final BouncyCastleFipsProvider fipsProvider;
private final Algorithm algorithmType;
private final Parameters parameters;
private AsymmetricKeyPairGenerator engine;
private int strength = 224;
private boolean initialised = false;
static private Hashtable ecParameters;
static
{
ecParameters = new Hashtable();
ecParameters.put(Integers.valueOf(192), new ECGenParameterSpec("prime192v1")); // a.k.a P-192
ecParameters.put(Integers.valueOf(239), new ECGenParameterSpec("prime239v1"));
ecParameters.put(Integers.valueOf(256), new ECGenParameterSpec("prime256v1")); // a.k.a P-256
ecParameters.put(Integers.valueOf(224), new ECGenParameterSpec("P-224"));
ecParameters.put(Integers.valueOf(384), new ECGenParameterSpec("P-384"));
ecParameters.put(Integers.valueOf(521), new ECGenParameterSpec("P-521"));
}
public ECKeyPairGenerator(BouncyCastleFipsProvider fipsProvider, Algorithm algorithmType)
{
this(fipsProvider, algorithmType, null);
}
public ECKeyPairGenerator(BouncyCastleFipsProvider fipsProvider, Parameters parameters)
{
this(fipsProvider, parameters.getAlgorithm(), parameters);
}
public ECKeyPairGenerator(BouncyCastleFipsProvider fipsProvider, Algorithm algorithmType, Parameters parameters)
{
super(algorithmType.getName());
this.fipsProvider = fipsProvider;
this.algorithmType = algorithmType;
this.parameters = parameters;
}
public void initialize(
int strength)
{
initialize(strength, fipsProvider.getDefaultSecureRandom());
}
public void initialize(
int strength,
SecureRandom random)
{
this.strength = strength;
ECGenParameterSpec ecParams = (ECGenParameterSpec)ecParameters.get(Integers.valueOf(strength));
if (ecParams != null)
{
try
{
initialize(ecParams, random);
}
catch (InvalidAlgorithmParameterException e)
{
throw new InvalidParameterException("key size not configurable.");
}
}
else
{
throw new InvalidParameterException("Key size " + strength + " bits not available");
}
}
public void initialize(
AlgorithmParameterSpec params)
throws InvalidAlgorithmParameterException
{
initialize(params, fipsProvider.getDefaultSecureRandom());
}
public void initialize(
AlgorithmParameterSpec params,
SecureRandom random)
throws InvalidAlgorithmParameterException
{
ECDomainParameters domainParameters;
if (params instanceof java.security.spec.ECParameterSpec)
{
domainParameters = ECUtil.convertFromSpec((java.security.spec.ECParameterSpec)params);
}
else if (params instanceof ECGenParameterSpec)
{
// See if it's actually an OID string (SunJSSE ServerHandshaker setupEphemeralECDHKeys bug)
domainParameters = getDomainParametersFromGenSpec((ECGenParameterSpec)params);
if (domainParameters == null)
{
throw new InvalidAlgorithmParameterException("unknown curve ID: " + ((ECGenParameterSpec)params).getName());
}
}
else if (params == null)
{
domainParameters = CryptoServicesRegistrar.getProperty(CryptoServicesRegistrar.Property.EC_IMPLICITLY_CA);
if (domainParameters == null)
{
throw new InvalidAlgorithmParameterException("null AlgorithmParameterSpec passed but no implicit CA set");
}
domainParameters = new ECImplicitDomainParameters(domainParameters);
}
else
{
throw new InvalidAlgorithmParameterException("AlgorithmParameterSpec not recognized: " + params.getClass().getName());
}
if (algorithmType instanceof FipsAlgorithm)
{
if (parameters != null)
{
if (parameters instanceof FipsEC.DSAParameters)
{
engine = new FipsEC.KeyPairGenerator(new FipsEC.KeyGenParameters((FipsEC.DSAParameters)parameters, domainParameters), random);
}
else if (parameters instanceof FipsEC.AgreementParameters)
{
engine = new FipsEC.KeyPairGenerator(new FipsEC.KeyGenParameters((FipsEC.AgreementParameters)parameters, domainParameters), random);
}
else
{
engine = new FipsEC.KeyPairGenerator(new FipsEC.KeyGenParameters((FipsEC.MQVAgreementParametersBuilder)parameters, domainParameters), random);
}
}
else
{
engine = new FipsEC.KeyPairGenerator(new FipsEC.KeyGenParameters(domainParameters), random);
}
}
else
{
if (parameters != null)
{
engine = new EC.KeyPairGenerator(new EC.KeyGenParameters((EC.DSAParameters)parameters, domainParameters), random);
}
else
{
engine = new EC.KeyPairGenerator(new EC.KeyGenParameters(domainParameters), random);
}
}
initialised = true;
}
public KeyPair generateKeyPair()
{
if (!initialised)
{
initialize(strength, fipsProvider.getDefaultSecureRandom());
}
AsymmetricKeyPair pair = engine.generateKeyPair();
AsymmetricECPublicKey pubKey = (AsymmetricECPublicKey)pair.getPublicKey();
AsymmetricECPrivateKey privKey = (AsymmetricECPrivateKey)pair.getPrivateKey();
return new KeyPair(new ProvECPublicKey(pubKey), new ProvECPrivateKey(privKey));
}
}
private static ECDomainParameters getDomainParametersFromGenSpec(ECGenParameterSpec genSpec)
{
String curveName = genSpec.getName();
ECDomainParameters domainParameters;
try
{
if (curveName.charAt(0) >= '0' && curveName.charAt(0) <= '2')
{
ASN1ObjectIdentifier oidID = new ASN1ObjectIdentifier(curveName);
domainParameters = ECDomainParametersIndex.lookupDomainParameters(oidID);
}
else
{
if (curveName.indexOf(' ') > 0)
{
curveName = curveName.substring(curveName.indexOf(' ') + 1);
domainParameters = getNamedECDomainParametersFromName(curveName);
}
else
{
domainParameters = getNamedECDomainParametersFromName(curveName);
}
}
}
catch (IllegalArgumentException ex)
{
domainParameters = getNamedECDomainParametersFromName(curveName);
}
return domainParameters;
}
private static NamedECDomainParameters getNamedECDomainParametersFromName(final String curveName)
{
return ECDomainParametersIndex.lookupDomainParameters(new ECDomainParametersID()
{
public String getCurveName()
{
return curveName;
}
});
}
}