summaryrefslogtreecommitdiff
path: root/bcpkix/src/main/java/org/bouncycastle/pkcs/bc/PKCS12PBEUtils.java
diff options
context:
space:
mode:
Diffstat (limited to 'bcpkix/src/main/java/org/bouncycastle/pkcs/bc/PKCS12PBEUtils.java')
-rw-r--r--bcpkix/src/main/java/org/bouncycastle/pkcs/bc/PKCS12PBEUtils.java153
1 files changed, 153 insertions, 0 deletions
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;
+ }
+}