diff options
Diffstat (limited to 'bcpkix/src/main/java/org/bouncycastle/pkcs/bc')
7 files changed, 460 insertions, 0 deletions
diff --git a/bcpkix/src/main/java/org/bouncycastle/pkcs/bc/BcPKCS10CertificationRequest.java b/bcpkix/src/main/java/org/bouncycastle/pkcs/bc/BcPKCS10CertificationRequest.java new file mode 100644 index 00000000..99c337c9 --- /dev/null +++ b/bcpkix/src/main/java/org/bouncycastle/pkcs/bc/BcPKCS10CertificationRequest.java @@ -0,0 +1,42 @@ +package org.bouncycastle.pkcs.bc; + +import java.io.IOException; + +import org.bouncycastle.asn1.pkcs.CertificationRequest; +import org.bouncycastle.crypto.params.AsymmetricKeyParameter; +import org.bouncycastle.crypto.util.PublicKeyFactory; +import org.bouncycastle.pkcs.PKCS10CertificationRequest; +import org.bouncycastle.pkcs.PKCSException; + +public class BcPKCS10CertificationRequest + extends PKCS10CertificationRequest +{ + public BcPKCS10CertificationRequest(CertificationRequest certificationRequest) + { + super(certificationRequest); + } + + public BcPKCS10CertificationRequest(byte[] encoding) + throws IOException + { + super(encoding); + } + + public BcPKCS10CertificationRequest(PKCS10CertificationRequest requestHolder) + { + super(requestHolder.toASN1Structure()); + } + + public AsymmetricKeyParameter getPublicKey() + throws PKCSException + { + try + { + return PublicKeyFactory.createKey(this.getSubjectPublicKeyInfo()); + } + catch (IOException e) + { + throw new PKCSException("error extracting key encoding: " + e.getMessage(), e); + } + } +} diff --git a/bcpkix/src/main/java/org/bouncycastle/pkcs/bc/BcPKCS10CertificationRequestBuilder.java b/bcpkix/src/main/java/org/bouncycastle/pkcs/bc/BcPKCS10CertificationRequestBuilder.java new file mode 100644 index 00000000..04b0fc60 --- /dev/null +++ b/bcpkix/src/main/java/org/bouncycastle/pkcs/bc/BcPKCS10CertificationRequestBuilder.java @@ -0,0 +1,28 @@ +package org.bouncycastle.pkcs.bc; + +import java.io.IOException; + +import org.bouncycastle.asn1.x500.X500Name; +import org.bouncycastle.crypto.params.AsymmetricKeyParameter; +import org.bouncycastle.crypto.util.SubjectPublicKeyInfoFactory; +import org.bouncycastle.pkcs.PKCS10CertificationRequestBuilder; + +/** + * Extension of the PKCS#10 builder to support AsymmetricKey objects. + */ +public class BcPKCS10CertificationRequestBuilder + extends PKCS10CertificationRequestBuilder +{ + /** + * Create a PKCS#10 builder for the passed in subject and JCA public key. + * + * @param subject an X500Name containing the subject associated with the request we are building. + * @param publicKey a JCA public key that is to be associated with the request we are building. + * @throws IOException if there is a problem encoding the public key. + */ + public BcPKCS10CertificationRequestBuilder(X500Name subject, AsymmetricKeyParameter publicKey) + throws IOException + { + super(subject, SubjectPublicKeyInfoFactory.createSubjectPublicKeyInfo(publicKey)); + } +} diff --git a/bcpkix/src/main/java/org/bouncycastle/pkcs/bc/BcPKCS12MacCalculatorBuilder.java b/bcpkix/src/main/java/org/bouncycastle/pkcs/bc/BcPKCS12MacCalculatorBuilder.java new file mode 100644 index 00000000..d8c38b59 --- /dev/null +++ b/bcpkix/src/main/java/org/bouncycastle/pkcs/bc/BcPKCS12MacCalculatorBuilder.java @@ -0,0 +1,54 @@ +package org.bouncycastle.pkcs.bc; + +import java.security.SecureRandom; + +import org.bouncycastle.asn1.DERNull; +import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; +import org.bouncycastle.asn1.pkcs.PKCS12PBEParams; +import org.bouncycastle.asn1.x509.AlgorithmIdentifier; +import org.bouncycastle.crypto.ExtendedDigest; +import org.bouncycastle.crypto.digests.SHA1Digest; +import org.bouncycastle.operator.MacCalculator; +import org.bouncycastle.pkcs.PKCS12MacCalculatorBuilder; + +public class BcPKCS12MacCalculatorBuilder + implements PKCS12MacCalculatorBuilder +{ + private ExtendedDigest digest; + private AlgorithmIdentifier algorithmIdentifier; + + private SecureRandom random; + private int saltLength; + private int iterationCount = 1024; + + public BcPKCS12MacCalculatorBuilder() + { + this(new SHA1Digest(), new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1, DERNull.INSTANCE)); + } + + public BcPKCS12MacCalculatorBuilder(ExtendedDigest digest, AlgorithmIdentifier algorithmIdentifier) + { + this.digest = digest; + this.algorithmIdentifier = algorithmIdentifier; + this.saltLength = digest.getDigestSize(); + } + + public AlgorithmIdentifier getDigestAlgorithmIdentifier() + { + return algorithmIdentifier; + } + + public MacCalculator build(final char[] password) + { + if (random == null) + { + random = new SecureRandom(); + } + + byte[] salt = new byte[saltLength]; + + random.nextBytes(salt); + + return PKCS12PBEUtils.createMacCalculator(algorithmIdentifier.getAlgorithm(), digest, new PKCS12PBEParams(salt, iterationCount), password); + } +} diff --git a/bcpkix/src/main/java/org/bouncycastle/pkcs/bc/BcPKCS12MacCalculatorBuilderProvider.java b/bcpkix/src/main/java/org/bouncycastle/pkcs/bc/BcPKCS12MacCalculatorBuilderProvider.java new file mode 100644 index 00000000..d6f92306 --- /dev/null +++ b/bcpkix/src/main/java/org/bouncycastle/pkcs/bc/BcPKCS12MacCalculatorBuilderProvider.java @@ -0,0 +1,40 @@ +package org.bouncycastle.pkcs.bc; + +import org.bouncycastle.asn1.DERNull; +import org.bouncycastle.asn1.pkcs.PKCS12PBEParams; +import org.bouncycastle.asn1.x509.AlgorithmIdentifier; +import org.bouncycastle.operator.MacCalculator; +import org.bouncycastle.operator.OperatorCreationException; +import org.bouncycastle.operator.bc.BcDigestProvider; +import org.bouncycastle.pkcs.PKCS12MacCalculatorBuilder; +import org.bouncycastle.pkcs.PKCS12MacCalculatorBuilderProvider; + +public class BcPKCS12MacCalculatorBuilderProvider + implements PKCS12MacCalculatorBuilderProvider +{ + private BcDigestProvider digestProvider; + + public BcPKCS12MacCalculatorBuilderProvider(BcDigestProvider digestProvider) + { + this.digestProvider = digestProvider; + } + + public PKCS12MacCalculatorBuilder get(final AlgorithmIdentifier algorithmIdentifier) + { + return new PKCS12MacCalculatorBuilder() + { + public MacCalculator build(final char[] password) + throws OperatorCreationException + { + PKCS12PBEParams pbeParams = PKCS12PBEParams.getInstance(algorithmIdentifier.getParameters()); + + return PKCS12PBEUtils.createMacCalculator(algorithmIdentifier.getAlgorithm(), digestProvider.get(algorithmIdentifier), pbeParams, password); + } + + public AlgorithmIdentifier getDigestAlgorithmIdentifier() + { + return new AlgorithmIdentifier(algorithmIdentifier.getAlgorithm(), DERNull.INSTANCE); + } + }; + } +} diff --git a/bcpkix/src/main/java/org/bouncycastle/pkcs/bc/BcPKCS12PBEInputDecryptorProviderBuilder.java b/bcpkix/src/main/java/org/bouncycastle/pkcs/bc/BcPKCS12PBEInputDecryptorProviderBuilder.java new file mode 100644 index 00000000..e578fd53 --- /dev/null +++ b/bcpkix/src/main/java/org/bouncycastle/pkcs/bc/BcPKCS12PBEInputDecryptorProviderBuilder.java @@ -0,0 +1,66 @@ +package org.bouncycastle.pkcs.bc; + +import java.io.InputStream; + +import org.bouncycastle.asn1.pkcs.PKCS12PBEParams; +import org.bouncycastle.asn1.x509.AlgorithmIdentifier; +import org.bouncycastle.crypto.CipherParameters; +import org.bouncycastle.crypto.ExtendedDigest; +import org.bouncycastle.crypto.digests.SHA1Digest; +import org.bouncycastle.crypto.generators.PKCS12ParametersGenerator; +import org.bouncycastle.crypto.io.CipherInputStream; +import org.bouncycastle.crypto.paddings.PaddedBufferedBlockCipher; +import org.bouncycastle.operator.GenericKey; +import org.bouncycastle.operator.InputDecryptor; +import org.bouncycastle.operator.InputDecryptorProvider; + +public class BcPKCS12PBEInputDecryptorProviderBuilder +{ + private ExtendedDigest digest; + + public BcPKCS12PBEInputDecryptorProviderBuilder() + { + this(new SHA1Digest()); + } + + public BcPKCS12PBEInputDecryptorProviderBuilder(ExtendedDigest digest) + { + this.digest = digest; + } + + public InputDecryptorProvider build(final char[] password) + { + return new InputDecryptorProvider() + { + public InputDecryptor get(final AlgorithmIdentifier algorithmIdentifier) + { + final PaddedBufferedBlockCipher engine = PKCS12PBEUtils.getEngine(algorithmIdentifier.getAlgorithm()); + + PKCS12PBEParams pbeParams = PKCS12PBEParams.getInstance(algorithmIdentifier.getParameters()); + + CipherParameters params = PKCS12PBEUtils.createCipherParameters(algorithmIdentifier.getAlgorithm(), digest, engine.getBlockSize(), pbeParams, password); + + engine.init(false, params); + + return new InputDecryptor() + { + public AlgorithmIdentifier getAlgorithmIdentifier() + { + return algorithmIdentifier; + } + + public InputStream getInputStream(InputStream input) + { + return new CipherInputStream(input, engine); + } + + public GenericKey getKey() + { + return new GenericKey(PKCS12ParametersGenerator.PKCS12PasswordToBytes(password)); + } + }; + } + }; + + } +} diff --git a/bcpkix/src/main/java/org/bouncycastle/pkcs/bc/BcPKCS12PBEOutputEncryptorBuilder.java b/bcpkix/src/main/java/org/bouncycastle/pkcs/bc/BcPKCS12PBEOutputEncryptorBuilder.java new file mode 100644 index 00000000..414c604f --- /dev/null +++ b/bcpkix/src/main/java/org/bouncycastle/pkcs/bc/BcPKCS12PBEOutputEncryptorBuilder.java @@ -0,0 +1,77 @@ +package org.bouncycastle.pkcs.bc; + +import java.io.OutputStream; +import java.security.SecureRandom; + +import org.bouncycastle.asn1.ASN1ObjectIdentifier; +import org.bouncycastle.asn1.pkcs.PKCS12PBEParams; +import org.bouncycastle.asn1.x509.AlgorithmIdentifier; +import org.bouncycastle.crypto.BlockCipher; +import org.bouncycastle.crypto.BufferedBlockCipher; +import org.bouncycastle.crypto.CipherParameters; +import org.bouncycastle.crypto.ExtendedDigest; +import org.bouncycastle.crypto.digests.SHA1Digest; +import org.bouncycastle.crypto.generators.PKCS12ParametersGenerator; +import org.bouncycastle.crypto.io.CipherOutputStream; +import org.bouncycastle.crypto.paddings.PKCS7Padding; +import org.bouncycastle.crypto.paddings.PaddedBufferedBlockCipher; +import org.bouncycastle.operator.GenericKey; +import org.bouncycastle.operator.OutputEncryptor; + +public class BcPKCS12PBEOutputEncryptorBuilder +{ + private ExtendedDigest digest; + + private BufferedBlockCipher engine; + private ASN1ObjectIdentifier algorithm; + private SecureRandom random; + + public BcPKCS12PBEOutputEncryptorBuilder(ASN1ObjectIdentifier algorithm, BlockCipher engine) + { + this(algorithm, engine, new SHA1Digest()); + } + + public BcPKCS12PBEOutputEncryptorBuilder(ASN1ObjectIdentifier algorithm, BlockCipher engine, ExtendedDigest pbeDigest) + { + this.algorithm = algorithm; + this.engine = new PaddedBufferedBlockCipher(engine, new PKCS7Padding()); + this.digest = pbeDigest; + } + + public OutputEncryptor build(final char[] password) + { + if (random == null) + { + random = new SecureRandom(); + } + + final byte[] salt = new byte[20]; + final int iterationCount = 1024; + + random.nextBytes(salt); + + final PKCS12PBEParams pbeParams = new PKCS12PBEParams(salt, iterationCount); + + CipherParameters params = PKCS12PBEUtils.createCipherParameters(algorithm, digest, engine.getBlockSize(), pbeParams, password); + + engine.init(true, params); + + return new OutputEncryptor() + { + public AlgorithmIdentifier getAlgorithmIdentifier() + { + return new AlgorithmIdentifier(algorithm, pbeParams); + } + + public OutputStream getOutputStream(OutputStream out) + { + return new CipherOutputStream(out, engine); + } + + public GenericKey getKey() + { + return new GenericKey(new AlgorithmIdentifier(algorithm, pbeParams), PKCS12ParametersGenerator.PKCS12PasswordToBytes(password)); + } + }; + } +} diff --git a/bcpkix/src/main/java/org/bouncycastle/pkcs/bc/PKCS12PBEUtils.java b/bcpkix/src/main/java/org/bouncycastle/pkcs/bc/PKCS12PBEUtils.java new file mode 100644 index 00000000..2edce234 --- /dev/null +++ b/bcpkix/src/main/java/org/bouncycastle/pkcs/bc/PKCS12PBEUtils.java @@ -0,0 +1,153 @@ +package org.bouncycastle.pkcs.bc; + +import java.io.OutputStream; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import org.bouncycastle.asn1.ASN1ObjectIdentifier; +import org.bouncycastle.asn1.pkcs.PKCS12PBEParams; +import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; +import org.bouncycastle.asn1.x509.AlgorithmIdentifier; +import org.bouncycastle.crypto.BlockCipher; +import org.bouncycastle.crypto.CipherParameters; +import org.bouncycastle.crypto.ExtendedDigest; +import org.bouncycastle.crypto.engines.DESedeEngine; +import org.bouncycastle.crypto.engines.RC2Engine; +import org.bouncycastle.crypto.generators.PKCS12ParametersGenerator; +import org.bouncycastle.crypto.io.MacOutputStream; +import org.bouncycastle.crypto.macs.HMac; +import org.bouncycastle.crypto.modes.CBCBlockCipher; +import org.bouncycastle.crypto.paddings.PKCS7Padding; +import org.bouncycastle.crypto.paddings.PaddedBufferedBlockCipher; +import org.bouncycastle.crypto.params.DESedeParameters; +import org.bouncycastle.crypto.params.KeyParameter; +import org.bouncycastle.crypto.params.ParametersWithIV; +import org.bouncycastle.operator.GenericKey; +import org.bouncycastle.operator.MacCalculator; +import org.bouncycastle.util.Integers; + +class PKCS12PBEUtils +{ + private static Map keySizes = new HashMap(); + private static Set noIvAlgs = new HashSet(); + private static Set desAlgs = new HashSet(); + + static + { + keySizes.put(PKCSObjectIdentifiers.pbeWithSHAAnd128BitRC4, Integers.valueOf(128)); + keySizes.put(PKCSObjectIdentifiers.pbeWithSHAAnd40BitRC4, Integers.valueOf(40)); + keySizes.put(PKCSObjectIdentifiers.pbeWithSHAAnd3_KeyTripleDES_CBC, Integers.valueOf(192)); + keySizes.put(PKCSObjectIdentifiers.pbeWithSHAAnd2_KeyTripleDES_CBC, Integers.valueOf(128)); + keySizes.put(PKCSObjectIdentifiers.pbeWithSHAAnd128BitRC2_CBC, Integers.valueOf(128)); + keySizes.put(PKCSObjectIdentifiers.pbeWithSHAAnd40BitRC2_CBC, Integers.valueOf(40)); + + noIvAlgs.add(PKCSObjectIdentifiers.pbeWithSHAAnd128BitRC4); + noIvAlgs.add(PKCSObjectIdentifiers.pbeWithSHAAnd40BitRC4); + + desAlgs.add(PKCSObjectIdentifiers.pbeWithSHAAnd3_KeyTripleDES_CBC); + desAlgs.add(PKCSObjectIdentifiers.pbeWithSHAAnd3_KeyTripleDES_CBC); + } + + static int getKeySize(ASN1ObjectIdentifier algorithm) + { + return ((Integer)keySizes.get(algorithm)).intValue(); + } + + static boolean hasNoIv(ASN1ObjectIdentifier algorithm) + { + return noIvAlgs.contains(algorithm); + } + + static boolean isDesAlg(ASN1ObjectIdentifier algorithm) + { + return desAlgs.contains(algorithm); + } + + static PaddedBufferedBlockCipher getEngine(ASN1ObjectIdentifier algorithm) + { + BlockCipher engine; + + if (algorithm.equals(PKCSObjectIdentifiers.pbeWithSHAAnd3_KeyTripleDES_CBC) + || algorithm.equals(PKCSObjectIdentifiers.pbeWithSHAAnd2_KeyTripleDES_CBC)) + { + engine = new DESedeEngine(); + } + else if (algorithm.equals(PKCSObjectIdentifiers.pbeWithSHAAnd128BitRC2_CBC) + || algorithm.equals(PKCSObjectIdentifiers.pbeWithSHAAnd40BitRC2_CBC)) + { + engine = new RC2Engine(); + } + else + { + throw new IllegalStateException("unknown algorithm"); + } + + return new PaddedBufferedBlockCipher(new CBCBlockCipher(engine), new PKCS7Padding()); + } + + static MacCalculator createMacCalculator(final ASN1ObjectIdentifier digestAlgorithm, ExtendedDigest digest, final PKCS12PBEParams pbeParams, final char[] password) + { + PKCS12ParametersGenerator pGen = new PKCS12ParametersGenerator(digest); + + pGen.init(PKCS12ParametersGenerator.PKCS12PasswordToBytes(password), pbeParams.getIV(), pbeParams.getIterations().intValue()); + + final KeyParameter keyParam = (KeyParameter)pGen.generateDerivedMacParameters(digest.getDigestSize() * 8); + + final HMac hMac = new HMac(digest); + + hMac.init(keyParam); + + return new MacCalculator() + { + public AlgorithmIdentifier getAlgorithmIdentifier() + { + return new AlgorithmIdentifier(digestAlgorithm, pbeParams); + } + + public OutputStream getOutputStream() + { + return new MacOutputStream(hMac); + } + + public byte[] getMac() + { + byte[] res = new byte[hMac.getMacSize()]; + + hMac.doFinal(res, 0); + + return res; + } + + public GenericKey getKey() + { + return new GenericKey(getAlgorithmIdentifier(), PKCS12ParametersGenerator.PKCS12PasswordToBytes(password)); + } + }; + } + + static CipherParameters createCipherParameters(ASN1ObjectIdentifier algorithm, ExtendedDigest digest, int blockSize, PKCS12PBEParams pbeParams, char[] password) + { + PKCS12ParametersGenerator pGen = new PKCS12ParametersGenerator(digest); + + pGen.init(PKCS12ParametersGenerator.PKCS12PasswordToBytes(password), pbeParams.getIV(), pbeParams.getIterations().intValue()); + + CipherParameters params; + + if (PKCS12PBEUtils.hasNoIv(algorithm)) + { + params = pGen.generateDerivedParameters(PKCS12PBEUtils.getKeySize(algorithm)); + } + else + { + params = pGen.generateDerivedParameters(PKCS12PBEUtils.getKeySize(algorithm), blockSize * 8); + + if (PKCS12PBEUtils.isDesAlg(algorithm)) + { + DESedeParameters.setOddParity(((KeyParameter)((ParametersWithIV)params).getParameters()).getKey()); + } + } + return params; + } +} |