diff options
Diffstat (limited to 'pkix/src/main/java/org/spongycastle/openssl/jcajce/JceOpenSSLPKCS8DecryptorProviderBuilder.java')
-rw-r--r-- | pkix/src/main/java/org/spongycastle/openssl/jcajce/JceOpenSSLPKCS8DecryptorProviderBuilder.java | 141 |
1 files changed, 141 insertions, 0 deletions
diff --git a/pkix/src/main/java/org/spongycastle/openssl/jcajce/JceOpenSSLPKCS8DecryptorProviderBuilder.java b/pkix/src/main/java/org/spongycastle/openssl/jcajce/JceOpenSSLPKCS8DecryptorProviderBuilder.java new file mode 100644 index 00000000..5050f4b2 --- /dev/null +++ b/pkix/src/main/java/org/spongycastle/openssl/jcajce/JceOpenSSLPKCS8DecryptorProviderBuilder.java @@ -0,0 +1,141 @@ +package org.spongycastle.openssl.jcajce; + +import java.io.IOException; +import java.io.InputStream; +import java.security.AlgorithmParameters; +import java.security.GeneralSecurityException; +import java.security.Provider; + +import javax.crypto.Cipher; +import javax.crypto.CipherInputStream; +import javax.crypto.SecretKey; +import javax.crypto.SecretKeyFactory; +import javax.crypto.spec.PBEKeySpec; +import javax.crypto.spec.PBEParameterSpec; + +import org.spongycastle.asn1.pkcs.EncryptionScheme; +import org.spongycastle.asn1.pkcs.KeyDerivationFunc; +import org.spongycastle.asn1.pkcs.PBEParameter; +import org.spongycastle.asn1.pkcs.PBES2Parameters; +import org.spongycastle.asn1.pkcs.PBKDF2Params; +import org.spongycastle.asn1.pkcs.PKCS12PBEParams; +import org.spongycastle.asn1.x509.AlgorithmIdentifier; +import org.spongycastle.jcajce.util.DefaultJcaJceHelper; +import org.spongycastle.jcajce.util.JcaJceHelper; +import org.spongycastle.jcajce.util.NamedJcaJceHelper; +import org.spongycastle.jcajce.util.ProviderJcaJceHelper; +import org.spongycastle.openssl.PEMException; +import org.spongycastle.operator.InputDecryptor; +import org.spongycastle.operator.InputDecryptorProvider; +import org.spongycastle.operator.OperatorCreationException; + +public class JceOpenSSLPKCS8DecryptorProviderBuilder +{ + private JcaJceHelper helper = new DefaultJcaJceHelper(); + + public JceOpenSSLPKCS8DecryptorProviderBuilder() + { + helper = new DefaultJcaJceHelper(); + } + + public JceOpenSSLPKCS8DecryptorProviderBuilder setProvider(String providerName) + { + helper = new NamedJcaJceHelper(providerName); + + return this; + } + + public JceOpenSSLPKCS8DecryptorProviderBuilder setProvider(Provider provider) + { + helper = new ProviderJcaJceHelper(provider); + + return this; + } + + public InputDecryptorProvider build(final char[] password) + throws OperatorCreationException + { + return new InputDecryptorProvider() + { + public InputDecryptor get(final AlgorithmIdentifier algorithm) + throws OperatorCreationException + { + final Cipher cipher; + + try + { + if (PEMUtilities.isPKCS5Scheme2(algorithm.getAlgorithm())) + { + PBES2Parameters params = PBES2Parameters.getInstance(algorithm.getParameters()); + KeyDerivationFunc func = params.getKeyDerivationFunc(); + EncryptionScheme scheme = params.getEncryptionScheme(); + PBKDF2Params defParams = (PBKDF2Params)func.getParameters(); + + int iterationCount = defParams.getIterationCount().intValue(); + byte[] salt = defParams.getSalt(); + + String oid = scheme.getAlgorithm().getId(); + + SecretKey key = PEMUtilities.generateSecretKeyForPKCS5Scheme2(oid, password, salt, iterationCount); + + cipher = helper.createCipher(oid); + AlgorithmParameters algParams = helper.createAlgorithmParameters(oid); + + algParams.init(scheme.getParameters().toASN1Primitive().getEncoded()); + + cipher.init(Cipher.DECRYPT_MODE, key, algParams); + } + else if (PEMUtilities.isPKCS12(algorithm.getAlgorithm())) + { + PKCS12PBEParams params = PKCS12PBEParams.getInstance(algorithm.getParameters()); + PBEKeySpec pbeSpec = new PBEKeySpec(password); + + SecretKeyFactory secKeyFact = helper.createSecretKeyFactory(algorithm.getAlgorithm().getId()); + PBEParameterSpec defParams = new PBEParameterSpec(params.getIV(), params.getIterations().intValue()); + + cipher = helper.createCipher(algorithm.getAlgorithm().getId()); + + cipher.init(Cipher.DECRYPT_MODE, secKeyFact.generateSecret(pbeSpec), defParams); + } + else if (PEMUtilities.isPKCS5Scheme1(algorithm.getAlgorithm())) + { + PBEParameter params = PBEParameter.getInstance(algorithm.getParameters()); + PBEKeySpec pbeSpec = new PBEKeySpec(password); + + SecretKeyFactory secKeyFact = helper.createSecretKeyFactory(algorithm.getAlgorithm().getId()); + PBEParameterSpec defParams = new PBEParameterSpec(params.getSalt(), params.getIterationCount().intValue()); + + cipher = helper.createCipher(algorithm.getAlgorithm().getId()); + + cipher.init(Cipher.DECRYPT_MODE, secKeyFact.generateSecret(pbeSpec), defParams); + } + else + { + throw new PEMException("Unknown algorithm: " + algorithm.getAlgorithm()); + } + + return new InputDecryptor() + { + public AlgorithmIdentifier getAlgorithmIdentifier() + { + return algorithm; + } + + public InputStream getInputStream(InputStream encIn) + { + return new CipherInputStream(encIn, cipher); + } + }; + } + catch (IOException e) + { + throw new OperatorCreationException(algorithm.getAlgorithm() + " not available: " + e.getMessage(), e); + } + catch (GeneralSecurityException e) + { + throw new OperatorCreationException(algorithm.getAlgorithm() + " not available: " + e.getMessage(), e); + } + }; + }; + } +} |