package org.bouncycastle.pkcs.jcajce; import java.io.OutputStream; import java.security.Provider; import javax.crypto.Mac; import javax.crypto.SecretKey; import javax.crypto.SecretKeyFactory; import javax.crypto.spec.PBEKeySpec; import javax.crypto.spec.PBEParameterSpec; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.pkcs.PKCS12PBEParams; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.crypto.generators.PKCS12ParametersGenerator; import org.bouncycastle.jcajce.DefaultJcaJceHelper; import org.bouncycastle.jcajce.JcaJceHelper; import org.bouncycastle.jcajce.NamedJcaJceHelper; import org.bouncycastle.jcajce.ProviderJcaJceHelper; import org.bouncycastle.jcajce.io.MacOutputStream; import org.bouncycastle.operator.GenericKey; import org.bouncycastle.operator.MacCalculator; import org.bouncycastle.operator.OperatorCreationException; import org.bouncycastle.pkcs.PKCS12MacCalculatorBuilder; import org.bouncycastle.pkcs.PKCS12MacCalculatorBuilderProvider; public class JcePKCS12MacCalculatorBuilderProvider implements PKCS12MacCalculatorBuilderProvider { private JcaJceHelper helper = new DefaultJcaJceHelper(); public JcePKCS12MacCalculatorBuilderProvider() { } public JcePKCS12MacCalculatorBuilderProvider setProvider(Provider provider) { this.helper = new ProviderJcaJceHelper(provider); return this; } public JcePKCS12MacCalculatorBuilderProvider setProvider(String providerName) { this.helper = new NamedJcaJceHelper(providerName); return this; } public PKCS12MacCalculatorBuilder get(final AlgorithmIdentifier algorithmIdentifier) { return new PKCS12MacCalculatorBuilder() { public MacCalculator build(final char[] password) throws OperatorCreationException { final PKCS12PBEParams pbeParams = PKCS12PBEParams.getInstance(algorithmIdentifier.getParameters()); try { final ASN1ObjectIdentifier algorithm = algorithmIdentifier.getAlgorithm(); final Mac mac = helper.createMac(algorithm.getId()); SecretKeyFactory keyFact = helper.createSecretKeyFactory(algorithm.getId()); PBEParameterSpec defParams = new PBEParameterSpec(pbeParams.getIV(), pbeParams.getIterations().intValue()); PBEKeySpec pbeSpec = new PBEKeySpec(password); SecretKey key = keyFact.generateSecret(pbeSpec); mac.init(key, defParams); return new MacCalculator() { public AlgorithmIdentifier getAlgorithmIdentifier() { return new AlgorithmIdentifier(algorithm, pbeParams); } public OutputStream getOutputStream() { return new MacOutputStream(mac); } public byte[] getMac() { return mac.doFinal(); } public GenericKey getKey() { return new GenericKey(getAlgorithmIdentifier(), PKCS12ParametersGenerator.PKCS12PasswordToBytes(password)); } }; } catch (Exception e) { throw new OperatorCreationException("unable to create MAC calculator: " + e.getMessage(), e); } } public AlgorithmIdentifier getDigestAlgorithmIdentifier() { return new AlgorithmIdentifier(algorithmIdentifier.getAlgorithm(), DERNull.INSTANCE); } }; } }