diff options
author | Vincent Breitmoser <valodim@mugenguild.com> | 2016-02-01 15:21:33 +0100 |
---|---|---|
committer | Vincent Breitmoser <valodim@mugenguild.com> | 2016-02-05 16:10:47 +0100 |
commit | e3b8cea04d43d9aafec544f56aa46ccf691a575d (patch) | |
tree | 5963ecb99710fc2409298948bd83aa2cd50d8806 /OpenKeychain/src/main/java/org/spongycastle | |
parent | cbf6f15d91f53f460584d959fcd16440c9309be1 (diff) | |
download | open-keychain-e3b8cea04d43d9aafec544f56aa46ccf691a575d.tar.gz open-keychain-e3b8cea04d43d9aafec544f56aa46ccf691a575d.tar.bz2 open-keychain-e3b8cea04d43d9aafec544f56aa46ccf691a575d.zip |
performance: cache session keys per compatible S2K configuration
Diffstat (limited to 'OpenKeychain/src/main/java/org/spongycastle')
-rw-r--r-- | OpenKeychain/src/main/java/org/spongycastle/openpgp/operator/jcajce/SessionKeySecretKeyDecryptorBuilder.java | 107 |
1 files changed, 107 insertions, 0 deletions
diff --git a/OpenKeychain/src/main/java/org/spongycastle/openpgp/operator/jcajce/SessionKeySecretKeyDecryptorBuilder.java b/OpenKeychain/src/main/java/org/spongycastle/openpgp/operator/jcajce/SessionKeySecretKeyDecryptorBuilder.java new file mode 100644 index 000000000..49282230f --- /dev/null +++ b/OpenKeychain/src/main/java/org/spongycastle/openpgp/operator/jcajce/SessionKeySecretKeyDecryptorBuilder.java @@ -0,0 +1,107 @@ +package org.spongycastle.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.spongycastle.bcpg.S2K; +import org.spongycastle.jcajce.util.DefaultJcaJceHelper; +import org.spongycastle.jcajce.util.NamedJcaJceHelper; +import org.spongycastle.jcajce.util.ProviderJcaJceHelper; +import org.spongycastle.openpgp.PGPException; +import org.spongycastle.openpgp.operator.PBESecretKeyDecryptor; +import org.spongycastle.openpgp.operator.PGPDigestCalculatorProvider; + + +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); + } + } + }; + } +} |