From 6e3973e26a74acad2e3ab562ea83687ad0c39e2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Fri, 5 Sep 2014 20:04:07 +0200 Subject: Add experimental support for yubikey PINs, remove caching of empty passphrases --- .../keychain/service/PassphraseCacheService.java | 12 +++----- .../ui/dialog/PassphraseDialogFragment.java | 36 +++++++++++++++++----- OpenKeychain/src/main/res/values/strings.xml | 1 + 3 files changed, 34 insertions(+), 15 deletions(-) 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 fe5c88f62..1218760da 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/PassphraseCacheService.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/PassphraseCacheService.java @@ -213,15 +213,13 @@ public class PassphraseCacheService extends Service { SecretKeyType keyType = keyRing.getSecretKeyType(subKeyId); switch (keyType) { - // TODO: HACK for yubikeys case DIVERT_TO_CARD: - return "123456"; - case PASSPHRASE_EMPTY: - try { - addCachedPassphrase(this, subKeyId, "", keyRing.getPrimaryUserIdWithFallback()); - } catch (PgpGeneralException e) { - Log.d(Constants.TAG, "PgpGeneralException occured"); + if (Preferences.getPreferences(this).useDefaultYubikeyPin()) { + return "123456"; // default Yubikey PIN, see http://www.yubico.com/2012/12/yubikey-neo-openpgp/ + } else { + break; } + case PASSPHRASE_EMPTY: return ""; case UNAVAILABLE: throw new NotFoundException("secret key for this subkey is not available"); 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 f19309b51..47d689193 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 @@ -47,6 +47,7 @@ import org.sufficientlysecure.keychain.compatibility.DialogFragmentWorkaround; import org.sufficientlysecure.keychain.pgp.CanonicalizedSecretKey; import org.sufficientlysecure.keychain.pgp.CanonicalizedSecretKeyRing; import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException; +import org.sufficientlysecure.keychain.provider.CachedPublicKeyRing; import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings; import org.sufficientlysecure.keychain.provider.ProviderHelper; import org.sufficientlysecure.keychain.service.PassphraseCacheService; @@ -116,7 +117,7 @@ public class PassphraseDialogFragment extends DialogFragment implements OnEditor @Override public Dialog onCreateDialog(Bundle savedInstanceState) { final Activity activity = getActivity(); - final long secretKeyId = getArguments().getLong(ARG_SECRET_KEY_ID); + final long subKeyId = getArguments().getLong(ARG_SECRET_KEY_ID); mMessenger = getArguments().getParcelable(ARG_MESSENGER); CustomAlertDialogBuilder alert = new CustomAlertDialogBuilder(activity); @@ -126,14 +127,15 @@ public class PassphraseDialogFragment extends DialogFragment implements OnEditor final CanonicalizedSecretKeyRing secretRing; String userId; - if (secretKeyId == Constants.key.symmetric || secretKeyId == Constants.key.none) { + if (subKeyId == Constants.key.symmetric || subKeyId == Constants.key.none) { alert.setMessage(R.string.passphrase_for_symmetric_encryption); secretRing = null; } else { + String message; try { ProviderHelper helper = new ProviderHelper(activity); secretRing = helper.getCanonicalizedSecretKeyRing( - KeyRings.buildUnifiedKeyRingsFindBySubkeyUri(secretKeyId)); + KeyRings.buildUnifiedKeyRingsFindBySubkeyUri(subKeyId)); // yes the inner try/catch block is necessary, otherwise the final variable // above can't be statically verified to have been set in all cases because // the catch clause doesn't return. @@ -142,9 +144,28 @@ public class PassphraseDialogFragment extends DialogFragment implements OnEditor } catch (PgpGeneralException e) { userId = null; } + + /* Get key type for message */ + // find a master key id for our key + long masterKeyId = new ProviderHelper(getActivity()).getMasterKeyId(subKeyId); + CachedPublicKeyRing keyRing = new ProviderHelper(getActivity()).getCachedPublicKeyRing(masterKeyId); + // get the type of key (from the database) + CanonicalizedSecretKey.SecretKeyType keyType = keyRing.getSecretKeyType(subKeyId); + switch (keyType) { + case PASSPHRASE: + message = getString(R.string.passphrase_for, userId); + break; + case DIVERT_TO_CARD: + message = getString(R.string.yubikey_pin); + break; + default: + message = "This should not happen!"; + break; + } + } catch (ProviderHelper.NotFoundException e) { alert.setTitle(R.string.title_key_not_found); - alert.setMessage(getString(R.string.key_not_found, secretKeyId)); + alert.setMessage(getString(R.string.key_not_found, subKeyId)); alert.setPositiveButton(android.R.string.ok, new OnClickListener() { public void onClick(DialogInterface dialog, int which) { dismiss(); @@ -154,8 +175,7 @@ public class PassphraseDialogFragment extends DialogFragment implements OnEditor return alert.create(); } - Log.d(Constants.TAG, "User id: '" + userId + "'"); - alert.setMessage(getString(R.string.passphrase_for, userId)); + alert.setMessage(message); } LayoutInflater inflater = activity.getLayoutInflater(); @@ -186,7 +206,7 @@ public class PassphraseDialogFragment extends DialogFragment implements OnEditor try { // make sure this unlocks // TODO this is a very costly operation, we should not be doing this here! - secretRing.getSecretKey(secretKeyId).unlock(passphrase); + secretRing.getSecretKey(subKeyId).unlock(passphrase); } catch (PgpGeneralException e) { Toast.makeText(activity, R.string.error_could_not_extract_private_key, Toast.LENGTH_SHORT).show(); @@ -199,7 +219,7 @@ public class PassphraseDialogFragment extends DialogFragment implements OnEditor Log.d(Constants.TAG, "Everything okay! Caching entered passphrase"); try { - PassphraseCacheService.addCachedPassphrase(activity, secretKeyId, passphrase, + PassphraseCacheService.addCachedPassphrase(activity, subKeyId, passphrase, secretRing.getPrimaryUserIdWithFallback()); } catch (PgpGeneralException e) { Log.e(Constants.TAG, "adding of a passphrase failed", e); diff --git a/OpenKeychain/src/main/res/values/strings.xml b/OpenKeychain/src/main/res/values/strings.xml index b666a198c..afab18686 100644 --- a/OpenKeychain/src/main/res/values/strings.xml +++ b/OpenKeychain/src/main/res/values/strings.xml @@ -180,6 +180,7 @@ Please enter a passphrase. Symmetric encryption. Enter passphrase for \'%s\' + Enter PIN to access Yubikey for \'%s\' "Are you sure you want to delete\n%s?" Successfully deleted. Select a file first. -- cgit v1.2.3