From e3b8cea04d43d9aafec544f56aa46ccf691a575d Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Mon, 1 Feb 2016 15:21:33 +0100 Subject: performance: cache session keys per compatible S2K configuration --- .../keychain/util/Passphrase.java | 45 +++++++++++++++++++++- 1 file changed, 43 insertions(+), 2 deletions(-) (limited to 'OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/Passphrase.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/Passphrase.java index fe42c7a2c..bb54f8024 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/Passphrase.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/Passphrase.java @@ -22,9 +22,14 @@ import android.os.Parcelable; import android.text.Editable; import android.widget.EditText; +import org.spongycastle.bcpg.S2K; import org.sufficientlysecure.keychain.Constants; +import org.sufficientlysecure.keychain.pgp.ComparableS2K; import java.util.Arrays; +import java.util.HashMap; +import java.util.Map.Entry; + /** * Passwords should not be stored as Strings in memory. @@ -38,6 +43,7 @@ import java.util.Arrays; */ public class Passphrase implements Parcelable { private char[] mPassphrase; + HashMap mCachedSessionKeys; /** * According to http://stackoverflow.com/a/15844273 EditText is not using String internally @@ -87,8 +93,18 @@ public class Passphrase implements Parcelable { return mPassphrase.length; } - public char charAt(int index) { - return mPassphrase[index]; + public byte[] getCachedSessionKeyForAlgorithm(int keyEncryptionAlgorithm, S2K s2k) { + if (mCachedSessionKeys == null) { + return null; + } + return mCachedSessionKeys.get(new ComparableS2K(keyEncryptionAlgorithm, s2k)); + } + + public void addCachedSessionKey(int keyEncryptionAlgorithm, S2K s2k, byte[] sessionKey) { + if (mCachedSessionKeys == null) { + mCachedSessionKeys = new HashMap<>(); + } + mCachedSessionKeys.put(new ComparableS2K(keyEncryptionAlgorithm, s2k), sessionKey); } /** @@ -98,6 +114,12 @@ public class Passphrase implements Parcelable { if (mPassphrase != null) { Arrays.fill(mPassphrase, ' '); } + if (mCachedSessionKeys == null) { + return; + } + for (byte[] cachedSessionKey : mCachedSessionKeys.values()) { + Arrays.fill(cachedSessionKey, (byte) 0); + } } @Override @@ -144,10 +166,29 @@ public class Passphrase implements Parcelable { private Passphrase(Parcel source) { mPassphrase = source.createCharArray(); + int size = source.readInt(); + if (size == 0) { + return; + } + mCachedSessionKeys = new HashMap<>(size); + for (int i = 0; i < size; i++) { + ComparableS2K cachedS2K = source.readParcelable(getClass().getClassLoader()); + byte[] cachedSessionKey = source.createByteArray(); + mCachedSessionKeys.put(cachedS2K, cachedSessionKey); + } } public void writeToParcel(Parcel dest, int flags) { dest.writeCharArray(mPassphrase); + if (mCachedSessionKeys == null || mCachedSessionKeys.isEmpty()) { + dest.writeInt(0); + return; + } + dest.writeInt(mCachedSessionKeys.size()); + for (Entry entry : mCachedSessionKeys.entrySet()) { + dest.writeParcelable(entry.getKey(), 0); + dest.writeByteArray(entry.getValue()); + } } public static final Creator CREATOR = new Creator() { -- cgit v1.2.3