| 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; |
| } |
| } |