aboutsummaryrefslogtreecommitdiffstats
path: root/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/PassphraseDialogFragment.java
diff options
context:
space:
mode:
Diffstat (limited to 'OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/PassphraseDialogFragment.java')
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/PassphraseDialogFragment.java134
1 files changed, 61 insertions, 73 deletions
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 12fd77141..5f47ee13c 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
@@ -41,17 +41,12 @@ import android.widget.TextView;
import android.widget.TextView.OnEditorActionListener;
import android.widget.Toast;
-import org.spongycastle.openpgp.PGPException;
-import org.spongycastle.openpgp.PGPPrivateKey;
-import org.spongycastle.openpgp.PGPSecretKey;
-import org.spongycastle.openpgp.operator.PBESecretKeyDecryptor;
-import org.spongycastle.openpgp.operator.jcajce.JcePBESecretKeyDecryptorBuilder;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.compatibility.DialogFragmentWorkaround;
-import org.sufficientlysecure.keychain.pgp.PgpKeyHelper;
+import org.sufficientlysecure.keychain.pgp.WrappedSecretKey;
+import org.sufficientlysecure.keychain.pgp.WrappedSecretKeyRing;
import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
-import org.sufficientlysecure.keychain.provider.KeychainContract;
import org.sufficientlysecure.keychain.provider.ProviderHelper;
import org.sufficientlysecure.keychain.service.PassphraseCacheService;
import org.sufficientlysecure.keychain.util.Log;
@@ -106,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).getWrappedSecretKeyRing(secretKeyId).hasPassphrase()) {
+ throw new PgpGeneralException("No passphrase! No passphrase dialog needed!");
+ }
+ } catch(ProviderHelper.NotFoundException e) {
+ throw new PgpGeneralException("Error: Key not found!", e);
}
}
@@ -139,18 +138,24 @@ public class PassphraseDialogFragment extends DialogFragment implements OnEditor
alert.setTitle(R.string.title_authentication);
- final PGPSecretKey secretKey;
- final String userId;
+ final WrappedSecretKeyRing secretRing;
+ String userId;
if (secretKeyId == Constants.key.symmetric || secretKeyId == Constants.key.none) {
- secretKey = null;
alert.setMessage(R.string.passphrase_for_symmetric_encryption);
+ secretRing = null;
} else {
try {
ProviderHelper helper = new ProviderHelper(activity);
- secretKey = helper.getPGPSecretKeyRing(secretKeyId).getSecretKey();
- userId = (String) helper.getUnifiedData(secretKeyId,
- KeychainContract.KeyRings.USER_ID, ProviderHelper.FIELD_TYPE_STRING);
+ secretRing = helper.getWrappedSecretKeyRing(secretKeyId);
+ // 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.
+ try {
+ userId = secretRing.getPrimaryUserId();
+ } catch (PgpGeneralException e) {
+ userId = null;
+ }
} catch (ProviderHelper.NotFoundException e) {
alert.setTitle(R.string.title_key_not_found);
alert.setMessage(getString(R.string.key_not_found, secretKeyId));
@@ -179,76 +184,59 @@ public class PassphraseDialogFragment extends DialogFragment implements OnEditor
@Override
public void onClick(DialogInterface dialog, int id) {
dismiss();
- long curKeyIndex = 1;
- boolean keyOK = true;
+
String passphrase = mPassphraseEditText.getText().toString();
- long keyId;
- PGPSecretKey clickSecretKey = secretKey;
-
- if (clickSecretKey != null) {
- while (keyOK) {
- if (clickSecretKey != null) { // check again for loop
- try {
- PBESecretKeyDecryptor keyDecryptor = new JcePBESecretKeyDecryptorBuilder()
- .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(
- passphrase.toCharArray());
- PGPPrivateKey testKey = clickSecretKey
- .extractPrivateKey(keyDecryptor);
- if (testKey == null) {
- if (!clickSecretKey.isMasterKey()) {
- Toast.makeText(activity,
- R.string.error_could_not_extract_private_key,
- Toast.LENGTH_SHORT).show();
-
- sendMessageToHandler(MESSAGE_CANCEL);
- return;
- } else {
- try {
- clickSecretKey = PgpKeyHelper.getKeyNum(new ProviderHelper(activity)
- .getPGPSecretKeyRingWithKeyId(secretKeyId),
- curKeyIndex
- );
- } catch (ProviderHelper.NotFoundException e) {
- Log.e(Constants.TAG, "key not found!", e);
- }
- curKeyIndex++; // does post-increment work like C?
- continue;
- }
- } else {
- keyOK = false;
- }
- } catch (PGPException e) {
- Toast.makeText(activity, R.string.wrong_passphrase,
- Toast.LENGTH_SHORT).show();
-
- sendMessageToHandler(MESSAGE_CANCEL);
- return;
- }
- } else {
- Toast.makeText(activity, R.string.error_could_not_extract_private_key,
- Toast.LENGTH_SHORT).show();
-
- sendMessageToHandler(MESSAGE_CANCEL);
- return; // ran out of keys to try
+
+ // Early breakout if we are dealing with a symmetric key
+ if (secretRing == null) {
+ PassphraseCacheService.addCachedPassphrase(activity, Constants.key.symmetric, passphrase);
+ // also return passphrase back to activity
+ Bundle data = new Bundle();
+ data.putString(MESSAGE_DATA_PASSPHRASE, passphrase);
+ sendMessageToHandler(MESSAGE_OKAY, data);
+ return;
+ }
+
+ WrappedSecretKey unlockedSecretKey = null;
+
+ for(WrappedSecretKey clickSecretKey : secretRing.iterator()) {
+ try {
+ boolean unlocked = clickSecretKey.unlock(passphrase);
+ if (unlocked) {
+ unlockedSecretKey = clickSecretKey;
+ break;
}
+ } catch (PgpGeneralException e) {
+ Toast.makeText(activity, R.string.error_could_not_extract_private_key,
+ Toast.LENGTH_SHORT).show();
+
+ sendMessageToHandler(MESSAGE_CANCEL);
+ return; // ran out of keys to try
}
- keyId = secretKey.getKeyID();
- } else {
- keyId = Constants.key.symmetric;
}
+ // Means we got an exception every time
+ if (unlockedSecretKey == null) {
+ Toast.makeText(activity, R.string.wrong_passphrase,
+ Toast.LENGTH_SHORT).show();
+
+ sendMessageToHandler(MESSAGE_CANCEL);
+ return;
+ }
+
+ long masterKeyId = secretRing.getMasterKeyId();
+
// cache the new passphrase
Log.d(Constants.TAG, "Everything okay! Caching entered passphrase");
- PassphraseCacheService.addCachedPassphrase(activity, keyId, passphrase);
- if (!keyOK && clickSecretKey.getKeyID() != keyId) {
- PassphraseCacheService.addCachedPassphrase(activity, clickSecretKey.getKeyID(),
- passphrase);
+ PassphraseCacheService.addCachedPassphrase(activity, masterKeyId, passphrase);
+ if (unlockedSecretKey.getKeyId() != masterKeyId) {
+ PassphraseCacheService.addCachedPassphrase(
+ activity, unlockedSecretKey.getKeyId(), passphrase);
}
// also return passphrase back to activity
Bundle data = new Bundle();
data.putString(MESSAGE_DATA_PASSPHRASE, passphrase);
-
sendMessageToHandler(MESSAGE_OKAY, data);
}
});