From c694d73cab1edf91cb94d53cc8352ca93f0eb6ce Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Mon, 23 Mar 2015 01:44:14 +0100 Subject: further improve yubikey error handling --- .../keychain/service/PassphraseCacheService.java | 40 ++++++++++++++++++---- 1 file changed, 34 insertions(+), 6 deletions(-) (limited to 'OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/PassphraseCacheService.java') 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 ee481ad31..5e8ad96cd 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/PassphraseCacheService.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/PassphraseCacheService.java @@ -124,7 +124,7 @@ public class PassphraseCacheService extends Service { public static void addCachedPassphrase(Context context, long masterKeyId, long subKeyId, Passphrase passphrase, String primaryUserId) { - Log.d(Constants.TAG, "PassphraseCacheService.cacheNewPassphrase() for " + masterKeyId); + Log.d(Constants.TAG, "PassphraseCacheService.addCachedPassphrase() for " + masterKeyId); Intent intent = new Intent(context, PassphraseCacheService.class); intent.setAction(ACTION_PASSPHRASE_CACHE_ADD); @@ -138,6 +138,19 @@ public class PassphraseCacheService extends Service { context.startService(intent); } + public static void clearCachedPassphrase(Context context, long masterKeyId, long subKeyId) { + Log.d(Constants.TAG, "PassphraseCacheService.clearCachedPassphrase() for " + masterKeyId); + + Intent intent = new Intent(context, PassphraseCacheService.class); + intent.setAction(ACTION_PASSPHRASE_CACHE_CLEAR); + + intent.putExtra(EXTRA_KEY_ID, masterKeyId); + intent.putExtra(EXTRA_SUBKEY_ID, subKeyId); + + context.startService(intent); + } + + /** * Gets a cached passphrase from memory by sending an intent to the service. This method is * designed to wait until the service returns the passphrase. @@ -395,12 +408,27 @@ public class PassphraseCacheService extends Service { } else if (ACTION_PASSPHRASE_CACHE_CLEAR.equals(intent.getAction())) { AlarmManager am = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE); - // Stop all ttl alarms - for (int i = 0; i < mPassphraseCache.size(); i++) { - am.cancel(buildIntent(this, mPassphraseCache.keyAt(i))); - } + if (intent.hasExtra(EXTRA_SUBKEY_ID) && intent.hasExtra(EXTRA_KEY_ID)) { - mPassphraseCache.clear(); + long keyId; + if (Preferences.getPreferences(mContext).getPassphraseCacheSubs()) { + keyId = intent.getLongExtra(EXTRA_KEY_ID, 0L); + } else { + keyId = intent.getLongExtra(EXTRA_SUBKEY_ID, 0L); + } + // Stop specific ttl alarm and + am.cancel(buildIntent(this, keyId)); + mPassphraseCache.delete(keyId); + + } else { + + // Stop all ttl alarms + for (int i = 0; i < mPassphraseCache.size(); i++) { + am.cancel(buildIntent(this, mPassphraseCache.keyAt(i))); + } + mPassphraseCache.clear(); + + } updateService(); } else { -- cgit v1.2.3 From c3d6637e6acf595e0f13ce8a3cb7accd6173e5d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Sun, 12 Apr 2015 19:55:10 +0200 Subject: Simplify PassphraseCacheService --- .../keychain/service/PassphraseCacheService.java | 28 ++++++++++------------ 1 file changed, 12 insertions(+), 16 deletions(-) (limited to 'OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/PassphraseCacheService.java') 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 8e37a8867..2bea05de8 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/PassphraseCacheService.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/PassphraseCacheService.java @@ -355,25 +355,21 @@ public class PassphraseCacheService extends Service { + masterKeyId + ", subKeyId: " + subKeyId + ", ttl: " + ttl + ", usrId: " + primaryUserID ); - // if we don't cache by specific subkey id, or the requested subkey is the master key, - // just add master key id to the cache + long referenceKeyId; if (subKeyId == masterKeyId || !Preferences.getPreferences(mContext).getPassphraseCacheSubs()) { - mPassphraseCache.put(masterKeyId, new CachedPassphrase(passphrase, primaryUserID)); - if (ttl > 0) { - // register new alarm with keyId for this passphrase - long triggerTime = new Date().getTime() + (ttl * 1000); - AlarmManager am = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE); - am.set(AlarmManager.RTC_WAKEUP, triggerTime, buildIntent(this, masterKeyId)); - } + // if we don't cache by specific subkey id, or the requested subkey is the master key, + // just add master key id to the cache + referenceKeyId = masterKeyId; } else { // otherwise, add this specific subkey to the cache - mPassphraseCache.put(subKeyId, new CachedPassphrase(passphrase, primaryUserID)); - if (ttl > 0) { - // register new alarm with keyId for this passphrase - long triggerTime = new Date().getTime() + (ttl * 1000); - AlarmManager am = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE); - am.set(AlarmManager.RTC_WAKEUP, triggerTime, buildIntent(this, subKeyId)); - } + referenceKeyId = subKeyId; + } + mPassphraseCache.put(referenceKeyId, new CachedPassphrase(passphrase, primaryUserID)); + if (ttl > 0) { + // register new alarm with keyId for this passphrase + long triggerTime = new Date().getTime() + (ttl * 1000); + AlarmManager am = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE); + am.set(AlarmManager.RTC_WAKEUP, triggerTime, buildIntent(this, referenceKeyId)); } updateService(); -- cgit v1.2.3 From 4a553087416097cfe08269c0417313fa691b3042 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Sun, 12 Apr 2015 20:12:10 +0200 Subject: More simplifications to PassphraseCacheService --- .../keychain/service/PassphraseCacheService.java | 48 ++++++++++------------ 1 file changed, 21 insertions(+), 27 deletions(-) (limited to 'OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/PassphraseCacheService.java') 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 2bea05de8..ba3216c23 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/PassphraseCacheService.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/PassphraseCacheService.java @@ -52,27 +52,26 @@ import java.util.Date; * This service runs in its own process, but is available to all other processes as the main * passphrase cache. Use the static methods addCachedPassphrase and getCachedPassphrase for * convenience. - * + *

* The passphrase cache service always works with both a master key id and a subkey id. The master * key id is always used to retrieve relevant info from the database, while the subkey id is used * to determine the type behavior (regular passphrase, empty passphrase, stripped key, * divert-to-card) for the specific key requested. - * + *

* Caching behavior for subkeys depends on the cacheSubs preference: - * - * - If cacheSubs is NOT set, passphrases will be cached and retrieved by master key id. The - * checks for special subkeys will still be done, but otherwise it is assumed that all subkeys - * from the same master key will use the same passphrase. This can lead to bad passphrase - * errors if two subkeys are encrypted differently. This is the default behavior. - * - * - If cacheSubs IS set, passphrases will be cached per subkey id. This means that if a keyring - * has two subkeys for different purposes, passphrases will be cached independently and the - * user will be asked for a passphrase once per subkey even if it is the same one. This mode - * of operation is more precise, since we can assume that all passphrases returned from cache - * will be correct without fail. Since keyrings with differently encrypted subkeys are a very - * rare occurrence, and caching by keyring is what the user expects in the vast majority of - * cases, this is not the default behavior. - * + *

+ * - If cacheSubs is NOT set, passphrases will be cached and retrieved by master key id. The + * checks for special subkeys will still be done, but otherwise it is assumed that all subkeys + * from the same master key will use the same passphrase. This can lead to bad passphrase + * errors if two subkeys are encrypted differently. This is the default behavior. + *

+ * - If cacheSubs IS set, passphrases will be cached per subkey id. This means that if a keyring + * has two subkeys for different purposes, passphrases will be cached independently and the + * user will be asked for a passphrase once per subkey even if it is the same one. This mode + * of operation is more precise, since we can assume that all passphrases returned from cache + * will be correct without fail. Since keyrings with differently encrypted subkeys are a very + * rare occurrence, and caching by keyring is what the user expects in the vast majority of + * cases, this is not the default behavior. */ public class PassphraseCacheService extends Service { @@ -153,7 +152,7 @@ public class PassphraseCacheService extends Service { /** * Gets a cached passphrase from memory by sending an intent to the service. This method is * designed to wait until the service returns the passphrase. - + * * @return passphrase or null (if no passphrase is cached for this keyId) */ public static Passphrase getCachedPassphrase(Context context, long masterKeyId, long subKeyId) throws KeyNotFoundException { @@ -231,7 +230,7 @@ public class PassphraseCacheService extends Service { } // on "none" key, just do nothing - if(masterKeyId == Constants.key.none) { + if (masterKeyId == Constants.key.none) { return null; } @@ -355,15 +354,10 @@ public class PassphraseCacheService extends Service { + masterKeyId + ", subKeyId: " + subKeyId + ", ttl: " + ttl + ", usrId: " + primaryUserID ); - long referenceKeyId; - if (subKeyId == masterKeyId || !Preferences.getPreferences(mContext).getPassphraseCacheSubs()) { - // if we don't cache by specific subkey id, or the requested subkey is the master key, - // just add master key id to the cache - referenceKeyId = masterKeyId; - } else { - // otherwise, add this specific subkey to the cache - referenceKeyId = subKeyId; - } + // if we don't cache by specific subkey id, or the requested subkey is the master key, + // just add master key id to the cache, otherwise, add this specific subkey to the cache + long referenceKeyId = + Preferences.getPreferences(mContext).getPassphraseCacheSubs() ? subKeyId : masterKeyId; mPassphraseCache.put(referenceKeyId, new CachedPassphrase(passphrase, primaryUserID)); if (ttl > 0) { // register new alarm with keyId for this passphrase -- cgit v1.2.3 From 9fc001c9b98e54f37eb8254a215f9d4c1e1c95ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Sun, 12 Apr 2015 21:23:59 +0200 Subject: Clearer var naming --- .../keychain/service/PassphraseCacheService.java | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/PassphraseCacheService.java') 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 ba3216c23..2e09db900 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/PassphraseCacheService.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/PassphraseCacheService.java @@ -322,11 +322,11 @@ public class PassphraseCacheService extends Service { /** * Build pending intent that is executed by alarm manager to time out a specific passphrase */ - private static PendingIntent buildIntent(Context context, long keyId) { + private static PendingIntent buildIntent(Context context, long referenceKeyId) { Intent intent = new Intent(BROADCAST_ACTION_PASSPHRASE_CACHE_SERVICE); - intent.putExtra(EXTRA_KEY_ID, keyId); + intent.putExtra(EXTRA_KEY_ID, referenceKeyId); // request code should be unique for each PendingIntent, thus keyId is used - return PendingIntent.getBroadcast(context, (int) keyId, intent, + return PendingIntent.getBroadcast(context, (int) referenceKeyId, intent, PendingIntent.FLAG_CANCEL_CURRENT); } @@ -400,15 +400,15 @@ public class PassphraseCacheService extends Service { if (intent.hasExtra(EXTRA_SUBKEY_ID) && intent.hasExtra(EXTRA_KEY_ID)) { - long keyId; + long referenceKeyId; if (Preferences.getPreferences(mContext).getPassphraseCacheSubs()) { - keyId = intent.getLongExtra(EXTRA_KEY_ID, 0L); + referenceKeyId = intent.getLongExtra(EXTRA_KEY_ID, 0L); } else { - keyId = intent.getLongExtra(EXTRA_SUBKEY_ID, 0L); + referenceKeyId = intent.getLongExtra(EXTRA_SUBKEY_ID, 0L); } // Stop specific ttl alarm and - am.cancel(buildIntent(this, keyId)); - mPassphraseCache.delete(keyId); + am.cancel(buildIntent(this, referenceKeyId)); + mPassphraseCache.delete(referenceKeyId); } else { -- cgit v1.2.3 From 256d644d03f989132e9db01e15f75aaee2f76157 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Mon, 13 Apr 2015 23:29:35 +0200 Subject: IMplement CryptoInputParcelCacheService --- .../keychain/service/PassphraseCacheService.java | 29 +++++++++++++++------- 1 file changed, 20 insertions(+), 9 deletions(-) (limited to 'OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/PassphraseCacheService.java') 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 2e09db900..778d0d525 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/PassphraseCacheService.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/PassphraseCacheService.java @@ -337,11 +337,17 @@ public class PassphraseCacheService extends Service { public int onStartCommand(Intent intent, int flags, int startId) { Log.d(Constants.TAG, "PassphraseCacheService.onStartCommand()"); + if (intent == null || intent.getAction() == null) { + updateService(); + return START_STICKY; + } + // register broadcastreceiver registerReceiver(); - if (intent != null && intent.getAction() != null) { - if (ACTION_PASSPHRASE_CACHE_ADD.equals(intent.getAction())) { + String action = intent.getAction(); + switch (action) { + case ACTION_PASSPHRASE_CACHE_ADD: { long ttl = intent.getLongExtra(EXTRA_TTL, DEFAULT_TTL); long masterKeyId = intent.getLongExtra(EXTRA_KEY_ID, -1); long subKeyId = intent.getLongExtra(EXTRA_SUBKEY_ID, -1); @@ -365,9 +371,9 @@ public class PassphraseCacheService extends Service { AlarmManager am = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE); am.set(AlarmManager.RTC_WAKEUP, triggerTime, buildIntent(this, referenceKeyId)); } - - updateService(); - } else if (ACTION_PASSPHRASE_CACHE_GET.equals(intent.getAction())) { + break; + } + case ACTION_PASSPHRASE_CACHE_GET: { long masterKeyId = intent.getLongExtra(EXTRA_KEY_ID, Constants.key.symmetric); long subKeyId = intent.getLongExtra(EXTRA_SUBKEY_ID, Constants.key.symmetric); Messenger messenger = intent.getParcelableExtra(EXTRA_MESSENGER); @@ -395,7 +401,9 @@ public class PassphraseCacheService extends Service { } catch (RemoteException e) { Log.e(Constants.TAG, "PassphraseCacheService: Sending message failed", e); } - } else if (ACTION_PASSPHRASE_CACHE_CLEAR.equals(intent.getAction())) { + break; + } + case ACTION_PASSPHRASE_CACHE_CLEAR: { AlarmManager am = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE); if (intent.hasExtra(EXTRA_SUBKEY_ID) && intent.hasExtra(EXTRA_KEY_ID)) { @@ -419,13 +427,16 @@ public class PassphraseCacheService extends Service { mPassphraseCache.clear(); } - - updateService(); - } else { + break; + } + default: { Log.e(Constants.TAG, "PassphraseCacheService: Intent or Intent Action not supported!"); + break; } } + updateService(); + return START_STICKY; } -- cgit v1.2.3 From 71024460cbb397957ab079a3568b0bb9462c0c84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Mon, 13 Apr 2015 23:53:46 +0200 Subject: Reformat comment in PassphraseCacheService --- .../keychain/service/PassphraseCacheService.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/PassphraseCacheService.java') 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 778d0d525..03c250035 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/PassphraseCacheService.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/PassphraseCacheService.java @@ -52,19 +52,19 @@ import java.util.Date; * This service runs in its own process, but is available to all other processes as the main * passphrase cache. Use the static methods addCachedPassphrase and getCachedPassphrase for * convenience. - *

+ * * The passphrase cache service always works with both a master key id and a subkey id. The master * key id is always used to retrieve relevant info from the database, while the subkey id is used * to determine the type behavior (regular passphrase, empty passphrase, stripped key, * divert-to-card) for the specific key requested. - *

+ * * Caching behavior for subkeys depends on the cacheSubs preference: - *

+ * * - If cacheSubs is NOT set, passphrases will be cached and retrieved by master key id. The * checks for special subkeys will still be done, but otherwise it is assumed that all subkeys * from the same master key will use the same passphrase. This can lead to bad passphrase * errors if two subkeys are encrypted differently. This is the default behavior. - *

+ * * - If cacheSubs IS set, passphrases will be cached per subkey id. This means that if a keyring * has two subkeys for different purposes, passphrases will be cached independently and the * user will be asked for a passphrase once per subkey even if it is the same one. This mode @@ -72,6 +72,7 @@ import java.util.Date; * will be correct without fail. Since keyrings with differently encrypted subkeys are a very * rare occurrence, and caching by keyring is what the user expects in the vast majority of * cases, this is not the default behavior. + * */ public class PassphraseCacheService extends Service { -- cgit v1.2.3 From 3668c8897d88989780da800ecd648c7b33a0e8f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Wed, 15 Apr 2015 10:02:41 +0200 Subject: Fix YubiKey naming, cleanup --- .../keychain/service/PassphraseCacheService.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/PassphraseCacheService.java') 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 03c250035..78137170d 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/PassphraseCacheService.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/PassphraseCacheService.java @@ -245,11 +245,11 @@ public class PassphraseCacheService extends Service { switch (keyType) { case DIVERT_TO_CARD: - if (Preferences.getPreferences(this).useDefaultYubikeyPin()) { - Log.d(Constants.TAG, "PassphraseCacheService: Using default Yubikey PIN: 123456"); - return new Passphrase("123456"); // default Yubikey PIN, see http://www.yubico.com/2012/12/yubikey-neo-openpgp/ + if (Preferences.getPreferences(this).useDefaultYubiKeyPin()) { + Log.d(Constants.TAG, "PassphraseCacheService: Using default YubiKey PIN: 123456"); + return new Passphrase("123456"); // default YubiKey PIN, see http://www.yubico.com/2012/12/yubikey-neo-openpgp/ } else { - Log.d(Constants.TAG, "PassphraseCacheService: NOT using default Yubikey PIN"); + Log.d(Constants.TAG, "PassphraseCacheService: NOT using default YubiKey PIN"); break; } case PASSPHRASE_EMPTY: -- cgit v1.2.3