diff options
Diffstat (limited to 'OpenPGP-Keychain/src')
3 files changed, 95 insertions, 35 deletions
diff --git a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/helper/PgpHelper.java b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/helper/PgpHelper.java index f59bd58de..b77fc71d1 100644 --- a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/helper/PgpHelper.java +++ b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/helper/PgpHelper.java @@ -24,12 +24,16 @@ import java.util.Locale; import java.util.Vector; import org.spongycastle.bcpg.sig.KeyFlags; +import org.spongycastle.openpgp.PGPPrivateKey; import org.spongycastle.openpgp.PGPPublicKey; import org.spongycastle.openpgp.PGPPublicKeyRing; import org.spongycastle.openpgp.PGPSecretKey; import org.spongycastle.openpgp.PGPSecretKeyRing; import org.spongycastle.openpgp.PGPSignature; import org.spongycastle.openpgp.PGPSignatureSubpacketVector; +import org.spongycastle.openpgp.operator.PBESecretKeyDecryptor; +import org.spongycastle.openpgp.operator.jcajce.JcePBESecretKeyDecryptorBuilder; +import org.spongycastle.openpgp.PGPException; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.provider.ProviderHelper; import org.sufficientlysecure.keychain.util.IterableIterator; @@ -77,6 +81,22 @@ public class PgpHelper { } @SuppressWarnings("unchecked") + public static PGPSecretKey getKeyNum(PGPSecretKeyRing keyRing, long num) { + long cnt = 0; + if (keyRing == null) { + return null; + } + for (PGPSecretKey key : new IterableIterator<PGPSecretKey>(keyRing.getSecretKeys())) { + if (cnt == num) { + return key; + } + cnt++; + } + + return null; + } + + @SuppressWarnings("unchecked") public static Vector<PGPPublicKey> getEncryptKeys(PGPPublicKeyRing keyRing) { Vector<PGPPublicKey> encryptKeys = new Vector<PGPPublicKey>(); @@ -144,7 +164,17 @@ public class PgpHelper { for (int i = 0; i < signingKeys.size(); ++i) { PGPSecretKey key = signingKeys.get(i); if (key.isMasterKey()) { - masterKey = key; + try { + PBESecretKeyDecryptor keyDecryptor = new JcePBESecretKeyDecryptorBuilder() + .setProvider(PgpMain.BOUNCY_CASTLE_PROVIDER_NAME).build(new char[] {}); + PGPPrivateKey testKey = key.extractPrivateKey( + keyDecryptor); + if (testKey != null) { + masterKey = key; + } + } catch (PGPException e) { + // all good if this fails, we likely didn't use the right password + } } else { usableKeys.add(key); } diff --git a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/helper/PgpMain.java b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/helper/PgpMain.java index 26842e4dc..26739f564 100644 --- a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/helper/PgpMain.java +++ b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/helper/PgpMain.java @@ -84,6 +84,7 @@ import org.sufficientlysecure.keychain.util.PositionAwareInputStream; import org.sufficientlysecure.keychain.util.Primes; import org.sufficientlysecure.keychain.util.ProgressDialogUpdater; import org.sufficientlysecure.keychain.util.KeyServer.AddKeyException; +import org.sufficientlysecure.keychain.util.IterableIterator; import org.sufficientlysecure.keychain.R; import android.content.Context; @@ -483,25 +484,28 @@ public class PgpMain { * @param keyring * @return */ + @SuppressWarnings("unchecked") public static int storeKeyRingInCache(Context context, PGPKeyRing keyring) { int status = Integer.MIN_VALUE; // out of bounds value (Id.return_value.*) try { if (keyring instanceof PGPSecretKeyRing) { PGPSecretKeyRing secretKeyRing = (PGPSecretKeyRing) keyring; boolean save = true; - try { - PBESecretKeyDecryptor keyDecryptor = new JcePBESecretKeyDecryptorBuilder() - .setProvider(BOUNCY_CASTLE_PROVIDER_NAME).build(new char[] {}); - PGPPrivateKey testKey = secretKeyRing.getSecretKey().extractPrivateKey( - keyDecryptor); - if (testKey == null) { - // this is bad, something is very wrong... likely a --export-secret-subkeys - // export - save = false; - status = Id.return_value.bad; + + for (PGPSecretKey testSecretKey : new IterableIterator<PGPSecretKey>(secretKeyRing.getSecretKeys())) { + try { + PBESecretKeyDecryptor keyDecryptor = new JcePBESecretKeyDecryptorBuilder() + .setProvider(BOUNCY_CASTLE_PROVIDER_NAME).build(new char[] {}); + PGPPrivateKey testKey = testSecretKey.extractPrivateKey( + keyDecryptor); + if (testKey == null && !testSecretKey.isMasterKey()) { + // this is bad, something is very wrong... + save = false; + status = Id.return_value.bad; + } + } catch (PGPException e) { + // all good if this fails, we likely didn't use the right password } - } catch (PGPException e) { - // all good if this fails, we likely didn't use the right password } if (save) { diff --git a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/dialog/PassphraseDialogFragment.java b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/dialog/PassphraseDialogFragment.java index 504de9d69..6f81b9319 100644 --- a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/dialog/PassphraseDialogFragment.java +++ b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/dialog/PassphraseDialogFragment.java @@ -19,6 +19,7 @@ package org.sufficientlysecure.keychain.ui.dialog; import org.spongycastle.openpgp.PGPException; import org.spongycastle.openpgp.PGPPrivateKey; import org.spongycastle.openpgp.PGPSecretKey; +import org.spongycastle.openpgp.PGPSecretKeyRing; import org.spongycastle.openpgp.operator.PBESecretKeyDecryptor; import org.spongycastle.openpgp.operator.jcajce.JcePBESecretKeyDecryptorBuilder; import org.sufficientlysecure.keychain.Constants; @@ -63,6 +64,7 @@ public class PassphraseDialogFragment extends DialogFragment implements OnEditor private Messenger mMessenger; private EditText mPassphraseEditText; + private boolean canKB; /** * Creates new instance of this dialog fragment @@ -137,8 +139,7 @@ public class PassphraseDialogFragment extends DialogFragment implements OnEditor @Override public Dialog onCreateDialog(Bundle savedInstanceState) { final Activity activity = getActivity(); - - long secretKeyId = getArguments().getLong(ARG_SECRET_KEY_ID); + final long secretKeyId = getArguments().getLong(ARG_SECRET_KEY_ID); mMessenger = getArguments().getParcelable(ARG_MESSENGER); AlertDialog.Builder alert = new AlertDialog.Builder(activity); @@ -152,8 +153,7 @@ public class PassphraseDialogFragment extends DialogFragment implements OnEditor alert.setMessage(R.string.passPhraseForSymmetricEncryption); } else { // TODO: by master key id??? - secretKey = PgpHelper.getMasterKey(ProviderHelper.getPGPSecretKeyRingByMasterKeyId( - activity, secretKeyId)); + secretKey = PgpHelper.getMasterKey(ProviderHelper.getPGPSecretKeyRingByKeyId(activity, secretKeyId)); // secretKey = PGPHelper.getMasterKey(PGPMain.getSecretKeyRing(secretKeyId)); if (secretKey == null) { @@ -165,6 +165,7 @@ public class PassphraseDialogFragment extends DialogFragment implements OnEditor } }); alert.setCancelable(false); + canKB = false; return alert.create(); } String userId = PgpHelper.getMainUserIdSafe(activity, secretKey); @@ -184,24 +185,43 @@ public class PassphraseDialogFragment extends DialogFragment implements OnEditor @Override public void onClick(DialogInterface dialog, int id) { dismiss(); - + long curKeyIndex = 0; + boolean keyOK = true; String passPhrase = mPassphraseEditText.getText().toString(); long keyId; - if (secretKey != null) { - try { - PBESecretKeyDecryptor keyDecryptor = new JcePBESecretKeyDecryptorBuilder() - .setProvider(PgpMain.BOUNCY_CASTLE_PROVIDER_NAME).build( - passPhrase.toCharArray()); - PGPPrivateKey testKey = secretKey.extractPrivateKey(keyDecryptor); - if (testKey == null) { + PGPSecretKey clickSecretKey = secretKey; + + if (clickSecretKey != null) { + while (keyOK == true) { + if (clickSecretKey != null) { //check again for loop + try { + PBESecretKeyDecryptor keyDecryptor = new JcePBESecretKeyDecryptorBuilder() + .setProvider(PgpMain.BOUNCY_CASTLE_PROVIDER_NAME).build( + passPhrase.toCharArray()); + PGPPrivateKey testKey = clickSecretKey.extractPrivateKey(keyDecryptor); + if (testKey == null) { + if (!clickSecretKey.isMasterKey()) { + Toast.makeText(activity, R.string.error_couldNotExtractPrivateKey, + Toast.LENGTH_SHORT).show(); + return; + } else { + clickSecretKey = PgpHelper.getKeyNum(ProviderHelper.getPGPSecretKeyRingByKeyId(activity, secretKeyId), curKeyIndex); + curKeyIndex++; //does post-increment work like C? + continue; + } + } else { + keyOK = false; + } + } catch (PGPException e) { + Toast.makeText(activity, R.string.wrongPassPhrase, Toast.LENGTH_SHORT) + .show(); + return; + } + } else { Toast.makeText(activity, R.string.error_couldNotExtractPrivateKey, Toast.LENGTH_SHORT).show(); - return; + return; //ran out of keys to try } - } catch (PGPException e) { - Toast.makeText(activity, R.string.wrongPassPhrase, Toast.LENGTH_SHORT) - .show(); - return; } keyId = secretKey.getKeyID(); } else { @@ -211,6 +231,9 @@ public class PassphraseDialogFragment extends DialogFragment implements OnEditor // cache the new passphrase Log.d(Constants.TAG, "Everything okay! Caching entered passphrase"); PassphraseCacheService.addCachedPassphrase(activity, keyId, passPhrase); + if (keyOK == false) { + PassphraseCacheService.addCachedPassphrase(activity, clickSecretKey.getKeyID(), passPhrase); + } sendMessageToHandler(MESSAGE_OKAY); } @@ -224,18 +247,20 @@ public class PassphraseDialogFragment extends DialogFragment implements OnEditor } }); + canKB = true; return alert.create(); } @Override public void onActivityCreated(Bundle arg0) { super.onActivityCreated(arg0); - + if (canKB) { // request focus and open soft keyboard - mPassphraseEditText.requestFocus(); - getDialog().getWindow().setSoftInputMode(LayoutParams.SOFT_INPUT_STATE_VISIBLE); + mPassphraseEditText.requestFocus(); + getDialog().getWindow().setSoftInputMode(LayoutParams.SOFT_INPUT_STATE_VISIBLE); - mPassphraseEditText.setOnEditorActionListener(this); + mPassphraseEditText.setOnEditorActionListener(this); + } } /** @@ -272,4 +297,5 @@ public class PassphraseDialogFragment extends DialogFragment implements OnEditor } } -}
\ No newline at end of file +} + |