diff options
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.java | 153 |
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; + } +} |