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/sufficientlysecure/keychain/pgp/CanonicalizedSecretKey.java | |
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/sufficientlysecure/keychain/pgp/CanonicalizedSecretKey.java')
-rw-r--r-- | OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CanonicalizedSecretKey.java | 27 |
1 files changed, 23 insertions, 4 deletions
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CanonicalizedSecretKey.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CanonicalizedSecretKey.java index 7394c07c3..7f2a00617 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CanonicalizedSecretKey.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CanonicalizedSecretKey.java @@ -19,6 +19,7 @@ package org.sufficientlysecure.keychain.pgp; import org.spongycastle.bcpg.S2K; +import org.spongycastle.bcpg.SymmetricKeyAlgorithmTags; import org.spongycastle.openpgp.PGPException; import org.spongycastle.openpgp.PGPPrivateKey; import org.spongycastle.openpgp.PGPSecretKey; @@ -33,6 +34,7 @@ import org.spongycastle.openpgp.operator.jcajce.JcaPGPKeyConverter; import org.spongycastle.openpgp.operator.jcajce.JcePBESecretKeyDecryptorBuilder; import org.spongycastle.openpgp.operator.jcajce.JcePublicKeyDataDecryptorFactoryBuilder; import org.spongycastle.openpgp.operator.jcajce.NfcSyncPGPContentSignerBuilder; +import org.spongycastle.openpgp.operator.jcajce.SessionKeySecretKeyDecryptorBuilder; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException; import org.sufficientlysecure.keychain.pgp.exception.PgpKeyNotFoundException; @@ -145,13 +147,12 @@ public class CanonicalizedSecretKey extends CanonicalizedPublicKey { // Otherwise, it's just a regular ol' passphrase return SecretKeyType.PASSPHRASE; } - } /** * Returns true on right passphrase */ - public boolean unlock(Passphrase passphrase) throws PgpGeneralException { + public boolean unlock(final Passphrase passphrase) throws PgpGeneralException { // handle keys on OpenPGP cards like they were unlocked S2K s2k = mSecretKey.getS2K(); if (s2k != null @@ -163,8 +164,26 @@ public class CanonicalizedSecretKey extends CanonicalizedPublicKey { // try to extract keys using the passphrase try { - PBESecretKeyDecryptor keyDecryptor = new JcePBESecretKeyDecryptorBuilder().setProvider( - Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(passphrase.getCharArray()); + + int keyEncryptionAlgorithm = mSecretKey.getKeyEncryptionAlgorithm(); + if (keyEncryptionAlgorithm == SymmetricKeyAlgorithmTags.NULL) { + mPrivateKey = mSecretKey.extractPrivateKey(null); + mPrivateKeyState = PRIVATE_KEY_STATE_UNLOCKED; + return true; + } + + byte[] sessionKey; + sessionKey = passphrase.getCachedSessionKeyForAlgorithm(keyEncryptionAlgorithm, s2k); + if (sessionKey == null) { + PBESecretKeyDecryptor keyDecryptor = new JcePBESecretKeyDecryptorBuilder().setProvider( + Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(passphrase.getCharArray()); + // this operation is EXPENSIVE, so we cache its result in the passed Passphrase object! + sessionKey = keyDecryptor.makeKeyFromPassPhrase(keyEncryptionAlgorithm, s2k); + passphrase.addCachedSessionKey(keyEncryptionAlgorithm, s2k, sessionKey); + } + + PBESecretKeyDecryptor keyDecryptor = new SessionKeySecretKeyDecryptorBuilder() + .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(sessionKey); mPrivateKey = mSecretKey.extractPrivateKey(keyDecryptor); mPrivateKeyState = PRIVATE_KEY_STATE_UNLOCKED; } catch (PGPException e) { |