aboutsummaryrefslogtreecommitdiffstats
path: root/OpenPGP-Keychain/src/org
diff options
context:
space:
mode:
authorAsh Hughes <ashes-iontach@hotmail.com>2013-03-14 03:23:50 +0000
committerAsh Hughes <ashes-iontach@hotmail.com>2013-03-14 03:23:50 +0000
commit115d34ba0e22dca586e7205614c48f3fbf4cad7d (patch)
treec22756fb51c5e50639668836c053076f3a09eb61 /OpenPGP-Keychain/src/org
parent99122fa8d94af9f158bab247ceb3167fef69b367 (diff)
downloadopen-keychain-115d34ba0e22dca586e7205614c48f3fbf4cad7d.tar.gz
open-keychain-115d34ba0e22dca586e7205614c48f3fbf4cad7d.tar.bz2
open-keychain-115d34ba0e22dca586e7205614c48f3fbf4cad7d.zip
private keys without master keys and some fixes for things which broke along the way
Diffstat (limited to 'OpenPGP-Keychain/src/org')
-rw-r--r--OpenPGP-Keychain/src/org/sufficientlysecure/keychain/helper/PgpHelper.java32
-rw-r--r--OpenPGP-Keychain/src/org/sufficientlysecure/keychain/helper/PgpMain.java28
-rw-r--r--OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/dialog/PassphraseDialogFragment.java70
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
+}
+