diff options
author | Vincent <valodim@mugenguild.com> | 2016-02-10 18:39:55 +0100 |
---|---|---|
committer | Vincent <valodim@mugenguild.com> | 2016-02-10 18:39:55 +0100 |
commit | 2eac4ebb950c9f36fbb8852b4266529065ff6731 (patch) | |
tree | da193d233e2f753e2c31d9c446f4c2cb5ad23248 /OpenKeychain/src/main/java/org/bouncycastle/openpgp/operator/jcajce/SessionKeySecretKeyDecryptorBuilder.java | |
parent | a94713103b6c72136fbf4886bf561616b2a01e4e (diff) | |
parent | da6dfb57a0aa816919cd23752e1707ba6a2e8cae (diff) | |
download | open-keychain-2eac4ebb950c9f36fbb8852b4266529065ff6731.tar.gz open-keychain-2eac4ebb950c9f36fbb8852b4266529065ff6731.tar.bz2 open-keychain-2eac4ebb950c9f36fbb8852b4266529065ff6731.zip |
Merge pull request #1708 from open-keychain/performance
performance improvements
Diffstat (limited to 'OpenKeychain/src/main/java/org/bouncycastle/openpgp/operator/jcajce/SessionKeySecretKeyDecryptorBuilder.java')
-rw-r--r-- | OpenKeychain/src/main/java/org/bouncycastle/openpgp/operator/jcajce/SessionKeySecretKeyDecryptorBuilder.java | 116 |
1 files changed, 116 insertions, 0 deletions
diff --git a/OpenKeychain/src/main/java/org/bouncycastle/openpgp/operator/jcajce/SessionKeySecretKeyDecryptorBuilder.java b/OpenKeychain/src/main/java/org/bouncycastle/openpgp/operator/jcajce/SessionKeySecretKeyDecryptorBuilder.java new file mode 100644 index 000000000..6f1b6f5ef --- /dev/null +++ b/OpenKeychain/src/main/java/org/bouncycastle/openpgp/operator/jcajce/SessionKeySecretKeyDecryptorBuilder.java @@ -0,0 +1,116 @@ +/** + * Copyright (c) 2016 Vincent Breitmoser + * + * Licensed under the Bouncy Castle License (MIT license). See LICENSE file for details. + */ + +package org.bouncycastle.openpgp.operator.jcajce; + + +import java.security.InvalidAlgorithmParameterException; +import java.security.InvalidKeyException; +import java.security.Provider; + +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.spec.IvParameterSpec; +import org.bouncycastle.bcpg.S2K; +import org.bouncycastle.jcajce.util.DefaultJcaJceHelper; +import org.bouncycastle.jcajce.util.NamedJcaJceHelper; +import org.bouncycastle.jcajce.util.ProviderJcaJceHelper; +import org.bouncycastle.openpgp.PGPException; +import org.bouncycastle.openpgp.operator.PBESecretKeyDecryptor; +import org.bouncycastle.openpgp.operator.PGPDigestCalculatorProvider; + + +/** This is a builder for a special PBESecretKeyDecryptor which is parametrized by a + * fixed session key, which is used in place of the one obtained from a passphrase. + */ +public class SessionKeySecretKeyDecryptorBuilder +{ + private OperatorHelper helper = new OperatorHelper(new DefaultJcaJceHelper()); + private PGPDigestCalculatorProvider calculatorProvider; + + private JcaPGPDigestCalculatorProviderBuilder calculatorProviderBuilder; + + public SessionKeySecretKeyDecryptorBuilder() + { + this.calculatorProviderBuilder = new JcaPGPDigestCalculatorProviderBuilder(); + } + + public SessionKeySecretKeyDecryptorBuilder(PGPDigestCalculatorProvider calculatorProvider) + { + this.calculatorProvider = calculatorProvider; + } + + public SessionKeySecretKeyDecryptorBuilder setProvider(Provider provider) + { + this.helper = new OperatorHelper(new ProviderJcaJceHelper(provider)); + + if (calculatorProviderBuilder != null) + { + calculatorProviderBuilder.setProvider(provider); + } + + return this; + } + + public SessionKeySecretKeyDecryptorBuilder setProvider(String providerName) + { + this.helper = new OperatorHelper(new NamedJcaJceHelper(providerName)); + + if (calculatorProviderBuilder != null) + { + calculatorProviderBuilder.setProvider(providerName); + } + + return this; + } + + public PBESecretKeyDecryptor build(final byte[] sessionKey) + throws PGPException + { + if (calculatorProvider == null) + { + calculatorProvider = calculatorProviderBuilder.build(); + } + + return new PBESecretKeyDecryptor(null, calculatorProvider) + { + @Override + public byte[] makeKeyFromPassPhrase(int keyAlgorithm, S2K s2k) throws PGPException { + return sessionKey; + } + + public byte[] recoverKeyData(int encAlgorithm, byte[] key, byte[] iv, byte[] keyData, int keyOff, int keyLen) + throws PGPException + { + try + { + Cipher c = helper.createCipher(PGPUtil.getSymmetricCipherName(encAlgorithm) + "/CFB/NoPadding"); + + c.init(Cipher.DECRYPT_MODE, PGPUtil.makeSymmetricKey(encAlgorithm, key), new IvParameterSpec(iv)); + + return c.doFinal(keyData, keyOff, keyLen); + } + catch (IllegalBlockSizeException e) + { + throw new PGPException("illegal block size: " + e.getMessage(), e); + } + catch (BadPaddingException e) + { + throw new PGPException("bad padding: " + e.getMessage(), e); + } + catch (InvalidAlgorithmParameterException e) + { + throw new PGPException("invalid parameter: " + e.getMessage(), e); + } + catch (InvalidKeyException e) + { + throw new PGPException("invalid key: " + e.getMessage(), e); + } + } + }; + } +} |