mirror of
https://github.com/moparisthebest/open-keychain
synced 2024-12-25 00:18:51 -05:00
Add experimental support for yubikey PINs, remove caching of empty passphrases
This commit is contained in:
parent
fa9bbdd60c
commit
6e3973e26a
@ -213,15 +213,13 @@ public class PassphraseCacheService extends Service {
|
|||||||
SecretKeyType keyType = keyRing.getSecretKeyType(subKeyId);
|
SecretKeyType keyType = keyRing.getSecretKeyType(subKeyId);
|
||||||
|
|
||||||
switch (keyType) {
|
switch (keyType) {
|
||||||
// TODO: HACK for yubikeys
|
|
||||||
case DIVERT_TO_CARD:
|
case DIVERT_TO_CARD:
|
||||||
return "123456";
|
if (Preferences.getPreferences(this).useDefaultYubikeyPin()) {
|
||||||
case PASSPHRASE_EMPTY:
|
return "123456"; // default Yubikey PIN, see http://www.yubico.com/2012/12/yubikey-neo-openpgp/
|
||||||
try {
|
} else {
|
||||||
addCachedPassphrase(this, subKeyId, "", keyRing.getPrimaryUserIdWithFallback());
|
break;
|
||||||
} catch (PgpGeneralException e) {
|
|
||||||
Log.d(Constants.TAG, "PgpGeneralException occured");
|
|
||||||
}
|
}
|
||||||
|
case PASSPHRASE_EMPTY:
|
||||||
return "";
|
return "";
|
||||||
case UNAVAILABLE:
|
case UNAVAILABLE:
|
||||||
throw new NotFoundException("secret key for this subkey is not available");
|
throw new NotFoundException("secret key for this subkey is not available");
|
||||||
|
@ -47,6 +47,7 @@ import org.sufficientlysecure.keychain.compatibility.DialogFragmentWorkaround;
|
|||||||
import org.sufficientlysecure.keychain.pgp.CanonicalizedSecretKey;
|
import org.sufficientlysecure.keychain.pgp.CanonicalizedSecretKey;
|
||||||
import org.sufficientlysecure.keychain.pgp.CanonicalizedSecretKeyRing;
|
import org.sufficientlysecure.keychain.pgp.CanonicalizedSecretKeyRing;
|
||||||
import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
|
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.KeychainContract.KeyRings;
|
||||||
import org.sufficientlysecure.keychain.provider.ProviderHelper;
|
import org.sufficientlysecure.keychain.provider.ProviderHelper;
|
||||||
import org.sufficientlysecure.keychain.service.PassphraseCacheService;
|
import org.sufficientlysecure.keychain.service.PassphraseCacheService;
|
||||||
@ -116,7 +117,7 @@ public class PassphraseDialogFragment extends DialogFragment implements OnEditor
|
|||||||
@Override
|
@Override
|
||||||
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
||||||
final Activity activity = getActivity();
|
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);
|
mMessenger = getArguments().getParcelable(ARG_MESSENGER);
|
||||||
|
|
||||||
CustomAlertDialogBuilder alert = new CustomAlertDialogBuilder(activity);
|
CustomAlertDialogBuilder alert = new CustomAlertDialogBuilder(activity);
|
||||||
@ -126,14 +127,15 @@ public class PassphraseDialogFragment extends DialogFragment implements OnEditor
|
|||||||
final CanonicalizedSecretKeyRing secretRing;
|
final CanonicalizedSecretKeyRing secretRing;
|
||||||
String userId;
|
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);
|
alert.setMessage(R.string.passphrase_for_symmetric_encryption);
|
||||||
secretRing = null;
|
secretRing = null;
|
||||||
} else {
|
} else {
|
||||||
|
String message;
|
||||||
try {
|
try {
|
||||||
ProviderHelper helper = new ProviderHelper(activity);
|
ProviderHelper helper = new ProviderHelper(activity);
|
||||||
secretRing = helper.getCanonicalizedSecretKeyRing(
|
secretRing = helper.getCanonicalizedSecretKeyRing(
|
||||||
KeyRings.buildUnifiedKeyRingsFindBySubkeyUri(secretKeyId));
|
KeyRings.buildUnifiedKeyRingsFindBySubkeyUri(subKeyId));
|
||||||
// yes the inner try/catch block is necessary, otherwise the final variable
|
// 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
|
// above can't be statically verified to have been set in all cases because
|
||||||
// the catch clause doesn't return.
|
// the catch clause doesn't return.
|
||||||
@ -142,9 +144,28 @@ public class PassphraseDialogFragment extends DialogFragment implements OnEditor
|
|||||||
} catch (PgpGeneralException e) {
|
} catch (PgpGeneralException e) {
|
||||||
userId = null;
|
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) {
|
} catch (ProviderHelper.NotFoundException e) {
|
||||||
alert.setTitle(R.string.title_key_not_found);
|
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() {
|
alert.setPositiveButton(android.R.string.ok, new OnClickListener() {
|
||||||
public void onClick(DialogInterface dialog, int which) {
|
public void onClick(DialogInterface dialog, int which) {
|
||||||
dismiss();
|
dismiss();
|
||||||
@ -154,8 +175,7 @@ public class PassphraseDialogFragment extends DialogFragment implements OnEditor
|
|||||||
return alert.create();
|
return alert.create();
|
||||||
}
|
}
|
||||||
|
|
||||||
Log.d(Constants.TAG, "User id: '" + userId + "'");
|
alert.setMessage(message);
|
||||||
alert.setMessage(getString(R.string.passphrase_for, userId));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LayoutInflater inflater = activity.getLayoutInflater();
|
LayoutInflater inflater = activity.getLayoutInflater();
|
||||||
@ -186,7 +206,7 @@ public class PassphraseDialogFragment extends DialogFragment implements OnEditor
|
|||||||
try {
|
try {
|
||||||
// make sure this unlocks
|
// make sure this unlocks
|
||||||
// TODO this is a very costly operation, we should not be doing this here!
|
// 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) {
|
} catch (PgpGeneralException e) {
|
||||||
Toast.makeText(activity, R.string.error_could_not_extract_private_key,
|
Toast.makeText(activity, R.string.error_could_not_extract_private_key,
|
||||||
Toast.LENGTH_SHORT).show();
|
Toast.LENGTH_SHORT).show();
|
||||||
@ -199,7 +219,7 @@ public class PassphraseDialogFragment extends DialogFragment implements OnEditor
|
|||||||
Log.d(Constants.TAG, "Everything okay! Caching entered passphrase");
|
Log.d(Constants.TAG, "Everything okay! Caching entered passphrase");
|
||||||
|
|
||||||
try {
|
try {
|
||||||
PassphraseCacheService.addCachedPassphrase(activity, secretKeyId, passphrase,
|
PassphraseCacheService.addCachedPassphrase(activity, subKeyId, passphrase,
|
||||||
secretRing.getPrimaryUserIdWithFallback());
|
secretRing.getPrimaryUserIdWithFallback());
|
||||||
} catch (PgpGeneralException e) {
|
} catch (PgpGeneralException e) {
|
||||||
Log.e(Constants.TAG, "adding of a passphrase failed", e);
|
Log.e(Constants.TAG, "adding of a passphrase failed", e);
|
||||||
|
@ -180,6 +180,7 @@
|
|||||||
<string name="passphrase_must_not_be_empty">Please enter a passphrase.</string>
|
<string name="passphrase_must_not_be_empty">Please enter a passphrase.</string>
|
||||||
<string name="passphrase_for_symmetric_encryption">Symmetric encryption.</string>
|
<string name="passphrase_for_symmetric_encryption">Symmetric encryption.</string>
|
||||||
<string name="passphrase_for">Enter passphrase for \'%s\'</string>
|
<string name="passphrase_for">Enter passphrase for \'%s\'</string>
|
||||||
|
<string name="yubikey_pin">Enter PIN to access Yubikey for \'%s\'</string>
|
||||||
<string name="file_delete_confirmation">"Are you sure you want to delete\n%s?"</string>
|
<string name="file_delete_confirmation">"Are you sure you want to delete\n%s?"</string>
|
||||||
<string name="file_delete_successful">Successfully deleted.</string>
|
<string name="file_delete_successful">Successfully deleted.</string>
|
||||||
<string name="no_file_selected">Select a file first.</string>
|
<string name="no_file_selected">Select a file first.</string>
|
||||||
|
Loading…
Reference in New Issue
Block a user