From cd8af25ba71d95ebb2ab2a3ab4b19dc28cad63fc Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Sun, 4 May 2014 16:59:20 +0200 Subject: wrapped-key-ring: more work on passphrase caching and certification --- .../keychain/pgp/PgpKeyHelper.java | 17 ------ .../keychain/service/PassphraseCacheService.java | 66 +++++++++++----------- .../keychain/ui/CertifyKeyActivity.java | 63 ++++++--------------- .../ui/dialog/PassphraseDialogFragment.java | 8 ++- 4 files changed, 56 insertions(+), 98 deletions(-) (limited to 'OpenKeychain/src/main/java/org/sufficientlysecure/keychain') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyHelper.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyHelper.java index e888d594e..77697b026 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyHelper.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyHelper.java @@ -81,23 +81,6 @@ public class PgpKeyHelper { return getExpiryDate(key.getPublicKey()); } - @SuppressWarnings("unchecked") - @Deprecated - public static PGPSecretKey getKeyNum(PGPSecretKeyRing keyRing, long num) { - long cnt = 0; - if (keyRing == null) { - return null; - } - for (PGPSecretKey key : new IterableIterator(keyRing.getSecretKeys())) { - if (cnt == num) { - return key; - } - cnt++; - } - - return null; - } - public static int getKeyUsage(PGPSecretKey key) { return getKeyUsage(key.getPublicKey()); } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/PassphraseCacheService.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/PassphraseCacheService.java index 88e974288..2889b89c6 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/PassphraseCacheService.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/PassphraseCacheService.java @@ -42,6 +42,7 @@ import org.spongycastle.openpgp.operator.PBESecretKeyDecryptor; import org.spongycastle.openpgp.operator.jcajce.JcePBESecretKeyDecryptorBuilder; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.helper.Preferences; +import org.sufficientlysecure.keychain.pgp.CachedSecretKeyRing; import org.sufficientlysecure.keychain.provider.KeychainContract; import org.sufficientlysecure.keychain.provider.ProviderHelper; import org.sufficientlysecure.keychain.util.Log; @@ -163,38 +164,46 @@ public class PassphraseCacheService extends Service { * @return */ private String getCachedPassphraseImpl(long keyId) { - Log.d(TAG, "getCachedPassphraseImpl() get masterKeyId for " + keyId); - - // try to get master key id which is used as an identifier for cached passphrases - long masterKeyId = keyId; - if (masterKeyId != Constants.key.symmetric) { - try { - masterKeyId = new ProviderHelper(this).getMasterKeyId( - KeychainContract.KeyRings.buildUnifiedKeyRingsFindBySubkeyUri(Long.toString(keyId))); - } catch (ProviderHelper.NotFoundException e) { + // passphrase for symmetric encryption? + if (keyId == Constants.key.symmetric) { + Log.d(TAG, "getCachedPassphraseImpl() for symmetric encryption"); + String cachedPassphrase = mPassphraseCache.get(Constants.key.symmetric); + if (cachedPassphrase == null) { return null; } + addCachedPassphrase(this, Constants.key.symmetric, cachedPassphrase); + return cachedPassphrase; } - Log.d(TAG, "getCachedPassphraseImpl() for masterKeyId " + masterKeyId); - // get cached passphrase - String cachedPassphrase = mPassphraseCache.get(masterKeyId); - if (cachedPassphrase == null) { - // if key has no passphrase -> cache and return empty passphrase - if (!hasPassphrase(this, masterKeyId)) { + // try to get master key id which is used as an identifier for cached passphrases + try { + Log.d(TAG, "getCachedPassphraseImpl() for masterKeyId " + keyId); + CachedSecretKeyRing key = new ProviderHelper(this).getCachedSecretKeyRing( + KeychainContract.KeyRings.buildUnifiedKeyRingsFindBySubkeyUri(Long.toString(keyId))); + // no passphrase needed? just add empty string and return it, then + if (!key.hasPassphrase()) { Log.d(Constants.TAG, "Key has no passphrase! Caches and returns empty passphrase!"); - addCachedPassphrase(this, masterKeyId, ""); + addCachedPassphrase(this, keyId, ""); return ""; - } else { + } + + // get cached passphrase + String cachedPassphrase = mPassphraseCache.get(keyId); + if (cachedPassphrase == null) { + // this is an error return null; } - } - // set it again to reset the cache life cycle - Log.d(TAG, "Cache passphrase again when getting it!"); - addCachedPassphrase(this, masterKeyId, cachedPassphrase); - return cachedPassphrase; + // set it again to reset the cache life cycle + Log.d(TAG, "Cache passphrase again when getting it!"); + addCachedPassphrase(this, keyId, cachedPassphrase); + return cachedPassphrase; + + } catch (ProviderHelper.NotFoundException e) { + Log.e(TAG, "Passphrase for unknown key was requested!"); + return null; + } } @Deprecated @@ -230,16 +239,9 @@ public class PassphraseCacheService extends Service { * @return true if it has a passphrase */ @Deprecated - public static boolean hasPassphrase(Context context, long secretKeyId) { - // check if the key has no passphrase - try { - PGPSecretKeyRing secRing = new ProviderHelper(context).getPGPSecretKeyRing(secretKeyId); - return hasPassphrase(secRing); - } catch (ProviderHelper.NotFoundException e) { - Log.e(Constants.TAG, "key not found!", e); - } - - return true; + public static boolean hasPassphrase(Context context, long secretKeyId) + throws ProviderHelper.NotFoundException { + return new ProviderHelper(context).getCachedSecretKeyRing(secretKeyId).hasPassphrase(); } /** diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java index fbcbbb0c3..30e8d9537 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java @@ -226,53 +226,22 @@ public class CertifyKeyActivity extends ActionBarActivity implements * handles the UI bits of the signing process on the UI thread */ private void initiateSigning() { - try { - PGPPublicKeyRing pubring = new ProviderHelper(this).getPGPPublicKeyRing(mPubKeyId); - - // if we have already signed this key, dont bother doing it again - boolean alreadySigned = false; - - /* todo: reconsider this at a later point when certs are in the db - @SuppressWarnings("unchecked") - Iterator itr = pubring.getPublicKey(mPubKeyId).getSignatures(); - while (itr.hasNext()) { - PGPSignature sig = itr.next(); - if (sig.getKeyID() == mMasterKeyId) { - alreadySigned = true; - break; - } - } - */ - - if (!alreadySigned) { - /* - * get the user's passphrase for this key (if required) - */ - String passphrase = PassphraseCacheService.getCachedPassphrase(this, mMasterKeyId); - if (passphrase == null) { - PassphraseDialogFragment.show(this, mMasterKeyId, - new Handler() { - @Override - public void handleMessage(Message message) { - if (message.what == PassphraseDialogFragment.MESSAGE_OKAY) { - startSigning(); - } - } - }); - // bail out; need to wait until the user has entered the passphrase before trying again - return; - } else { - startSigning(); - } - } else { - AppMsg.makeText(this, R.string.key_has_already_been_certified, AppMsg.STYLE_ALERT) - .show(); - - setResult(RESULT_CANCELED); - finish(); - } - } catch (ProviderHelper.NotFoundException e) { - Log.e(Constants.TAG, "key not found!", e); + // get the user's passphrase for this key (if required) + String passphrase = PassphraseCacheService.getCachedPassphrase(this, mMasterKeyId); + if (passphrase == null) { + PassphraseDialogFragment.show(this, mMasterKeyId, + new Handler() { + @Override + public void handleMessage(Message message) { + if (message.what == PassphraseDialogFragment.MESSAGE_OKAY) { + startSigning(); + } + } + }); + // bail out; need to wait until the user has entered the passphrase before trying again + return; + } else { + startSigning(); } } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/PassphraseDialogFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/PassphraseDialogFragment.java index 256d9d4b7..9b5581cc7 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/PassphraseDialogFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/PassphraseDialogFragment.java @@ -101,8 +101,12 @@ public class PassphraseDialogFragment extends DialogFragment implements OnEditor long secretKeyId) throws PgpGeneralException { // check if secret key has a passphrase if (!(secretKeyId == Constants.key.symmetric || secretKeyId == Constants.key.none)) { - if (!PassphraseCacheService.hasPassphrase(context, secretKeyId)) { - throw new PgpGeneralException("No passphrase! No passphrase dialog needed!"); + try { + if (new ProviderHelper(context).getCachedSecretKeyRing(secretKeyId).hasPassphrase()) { + throw new PgpGeneralException("No passphrase! No passphrase dialog needed!"); + } + } catch(ProviderHelper.NotFoundException e) { + throw new PgpGeneralException("Error: Key not found!", e); } } -- cgit v1.2.3