summaryrefslogtreecommitdiff
path: root/bcpkix/src/main/java/org/bouncycastle/pkcs/bc
diff options
context:
space:
mode:
Diffstat (limited to 'bcpkix/src/main/java/org/bouncycastle/pkcs/bc')
-rw-r--r--bcpkix/src/main/java/org/bouncycastle/pkcs/bc/BcPKCS10CertificationRequest.java42
-rw-r--r--bcpkix/src/main/java/org/bouncycastle/pkcs/bc/BcPKCS10CertificationRequestBuilder.java28
-rw-r--r--bcpkix/src/main/java/org/bouncycastle/pkcs/bc/BcPKCS12MacCalculatorBuilder.java54
-rw-r--r--bcpkix/src/main/java/org/bouncycastle/pkcs/bc/BcPKCS12MacCalculatorBuilderProvider.java40
-rw-r--r--bcpkix/src/main/java/org/bouncycastle/pkcs/bc/BcPKCS12PBEInputDecryptorProviderBuilder.java66
-rw-r--r--bcpkix/src/main/java/org/bouncycastle/pkcs/bc/BcPKCS12PBEOutputEncryptorBuilder.java77
-rw-r--r--bcpkix/src/main/java/org/bouncycastle/pkcs/bc/PKCS12PBEUtils.java153
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;
+ }
+}