aboutsummaryrefslogtreecommitdiffstats
path: root/OpenPGP-Keychain/src/main/java
diff options
context:
space:
mode:
authorAshley Hughes <spirit.returned@gmail.com>2014-03-07 15:16:13 +0000
committerAshley Hughes <spirit.returned@gmail.com>2014-03-07 15:16:13 +0000
commitfba0e2af1d04fe95f82a60ed2acbb69d5be920d2 (patch)
tree2ec7978ddac4a3c3a2b99e165ddfdffea3835989 /OpenPGP-Keychain/src/main/java
parent04fa0e9cc7fbfc117948d60a3ad8bfab0b0060ba (diff)
parent59067f9f8b0a12f875ba928b30f8f35fc284356c (diff)
downloadopen-keychain-fba0e2af1d04fe95f82a60ed2acbb69d5be920d2.tar.gz
open-keychain-fba0e2af1d04fe95f82a60ed2acbb69d5be920d2.tar.bz2
open-keychain-fba0e2af1d04fe95f82a60ed2acbb69d5be920d2.zip
keep up with master
Diffstat (limited to 'OpenPGP-Keychain/src/main/java')
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/Constants.java2
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/Id.java10
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java203
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerifyResult.java88
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpImportExport.java4
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java8
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java2
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java39
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentServiceHandler.java10
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/OpenPgpService.java413
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/RemoteService.java30
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/RemoteServiceActivity.java37
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptActivity.java84
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DrawerActivity.java23
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java50
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivity.java49
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java48
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysListFragment.java44
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListPublicFragment.java73
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListSecretFragment.java16
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/PreferencesActivity.java302
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectPublicKeyFragment.java38
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/AsyncTaskResultWrapper.java45
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListLoader.java16
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListServerLoader.java23
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/KeyListPublicAdapter.java2
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/BadImportKeyDialogFragment.java68
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/CreateKeyDialogFragment.java152
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteFileDialogFragment.java5
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteKeyDialogFragment.java21
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/PassphraseDialogFragment.java8
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/ProgressDialogFragment.java41
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/SetPassphraseDialogFragment.java10
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/ShareNfcDialogFragment.java1
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/ShareQrCodeDialogFragment.java18
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeyEditor.java47
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SectionView.java119
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/HkpKeyServer.java11
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/KeyServer.java12
39 files changed, 1402 insertions, 770 deletions
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/Constants.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/Constants.java
index c1809e4e1..4428c7133 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/Constants.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/Constants.java
@@ -51,7 +51,7 @@ public final class Constants {
public static final String DEFAULT_ASCII_ARMOUR = "defaultAsciiArmour";
public static final String DEFAULT_MESSAGE_COMPRESSION = "defaultMessageCompression";
public static final String DEFAULT_FILE_COMPRESSION = "defaultFileCompression";
- public static final String PASS_PHRASE_CACHE_TTL = "passPhraseCacheTtl";
+ public static final String PASS_PHRASE_CACHE_TTL = "passphraseCacheTtl";
public static final String LANGUAGE = "language";
public static final String FORCE_V3_SIGNATURES = "forceV3Signatures";
public static final String KEY_SERVERS = "keyServers";
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/Id.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/Id.java
index a1571e491..1d79edd43 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/Id.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/Id.java
@@ -30,7 +30,7 @@ public final class Id {
public static final class menu {
public static final class option {
- public static final int new_pass_phrase = 0x21070001;
+ public static final int new_passphrase = 0x21070001;
public static final int create = 0x21070002;
public static final int about = 0x21070003;
public static final int manage_public_keys = 0x21070004;
@@ -85,12 +85,12 @@ public final class Id {
}
public static final class dialog {
- public static final int pass_phrase = 0x21070001;
+ public static final int passphrase = 0x21070001;
public static final int encrypting = 0x21070002;
public static final int decrypting = 0x21070003;
- public static final int new_pass_phrase = 0x21070004;
- public static final int pass_phrases_do_not_match = 0x21070005;
- public static final int no_pass_phrase = 0x21070006;
+ public static final int new_passphrase = 0x21070004;
+ public static final int passphrases_do_not_match = 0x21070005;
+ public static final int no_passphrase = 0x21070006;
public static final int saving = 0x21070007;
public static final int delete_key = 0x21070008;
public static final int import_keys = 0x21070009;
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java
index fb97f3a5c..ccd6ff8df 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java
@@ -18,8 +18,8 @@
package org.sufficientlysecure.keychain.pgp;
import android.content.Context;
-import android.os.Bundle;
+import org.openintents.openpgp.OpenPgpSignatureResult;
import org.spongycastle.bcpg.ArmoredInputStream;
import org.spongycastle.bcpg.SignatureSubpacketTags;
import org.spongycastle.openpgp.PGPCompressedData;
@@ -36,6 +36,7 @@ import org.spongycastle.openpgp.PGPPublicKey;
import org.spongycastle.openpgp.PGPPublicKeyEncryptedData;
import org.spongycastle.openpgp.PGPPublicKeyRing;
import org.spongycastle.openpgp.PGPSecretKey;
+import org.spongycastle.openpgp.PGPSecretKeyRing;
import org.spongycastle.openpgp.PGPSignature;
import org.spongycastle.openpgp.PGPSignatureList;
import org.spongycastle.openpgp.PGPSignatureSubpacketVector;
@@ -53,7 +54,7 @@ import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
import org.sufficientlysecure.keychain.provider.ProviderHelper;
-import org.sufficientlysecure.keychain.service.KeychainIntentService;
+import org.sufficientlysecure.keychain.service.PassphraseCacheService;
import org.sufficientlysecure.keychain.util.InputData;
import org.sufficientlysecure.keychain.util.Log;
import org.sufficientlysecure.keychain.util.ProgressDialogUpdater;
@@ -75,9 +76,10 @@ public class PgpDecryptVerify {
private InputData data;
private OutputStream outStream;
- private ProgressDialogUpdater progress;
- boolean assumeSymmetric;
- String passphrase;
+ private ProgressDialogUpdater progressDialogUpdater;
+ private boolean assumeSymmetric;
+ private String passphrase;
+ private long enforcedKeyId;
private PgpDecryptVerify(Builder builder) {
// private Constructor can only be called from Builder
@@ -85,9 +87,10 @@ public class PgpDecryptVerify {
this.data = builder.data;
this.outStream = builder.outStream;
- this.progress = builder.progress;
+ this.progressDialogUpdater = builder.progressDialogUpdater;
this.assumeSymmetric = builder.assumeSymmetric;
this.passphrase = builder.passphrase;
+ this.enforcedKeyId = builder.enforcedKeyId;
}
public static class Builder {
@@ -97,9 +100,10 @@ public class PgpDecryptVerify {
private OutputStream outStream;
// optional
- private ProgressDialogUpdater progress = null;
+ private ProgressDialogUpdater progressDialogUpdater = null;
private boolean assumeSymmetric = false;
private String passphrase = "";
+ private long enforcedKeyId = 0;
public Builder(Context context, InputData data, OutputStream outStream) {
this.context = context;
@@ -107,8 +111,8 @@ public class PgpDecryptVerify {
this.outStream = outStream;
}
- public Builder progress(ProgressDialogUpdater progress) {
- this.progress = progress;
+ public Builder progressDialogUpdater(ProgressDialogUpdater progressDialogUpdater) {
+ this.progressDialogUpdater = progressDialogUpdater;
return this;
}
@@ -122,20 +126,32 @@ public class PgpDecryptVerify {
return this;
}
+ /**
+ * Allow this key id alone for decryption.
+ * This means only ciphertexts encrypted for this private key can be decrypted.
+ *
+ * @param enforcedKeyId
+ * @return
+ */
+ public Builder enforcedKeyId(long enforcedKeyId) {
+ this.enforcedKeyId = enforcedKeyId;
+ return this;
+ }
+
public PgpDecryptVerify build() {
return new PgpDecryptVerify(this);
}
}
public void updateProgress(int message, int current, int total) {
- if (progress != null) {
- progress.setProgress(message, current, total);
+ if (progressDialogUpdater != null) {
+ progressDialogUpdater.setProgress(message, current, total);
}
}
public void updateProgress(int current, int total) {
- if (progress != null) {
- progress.setProgress(current, total);
+ if (progressDialogUpdater != null) {
+ progressDialogUpdater.setProgress(current, total);
}
}
@@ -177,9 +193,8 @@ public class PgpDecryptVerify {
* @throws PGPException
* @throws SignatureException
*/
- public Bundle execute()
+ public PgpDecryptVerifyResult execute()
throws IOException, PgpGeneralException, PGPException, SignatureException {
-
// automatically works with ascii armor input and binary
InputStream in = PGPUtil.getDecoderStream(data.getInputStream());
if (in instanceof ArmoredInputStream) {
@@ -207,9 +222,9 @@ public class PgpDecryptVerify {
* @throws PGPException
* @throws SignatureException
*/
- private Bundle decryptVerify(InputStream in)
+ private PgpDecryptVerifyResult decryptVerify(InputStream in)
throws IOException, PgpGeneralException, PGPException, SignatureException {
- Bundle returnData = new Bundle();
+ PgpDecryptVerifyResult returnData = new PgpDecryptVerifyResult();
PGPObjectFactory pgpF = new PGPObjectFactory(in);
PGPEncryptedDataList enc;
@@ -277,9 +292,40 @@ public class PgpDecryptVerify {
PGPPublicKeyEncryptedData encData = (PGPPublicKeyEncryptedData) obj;
secretKey = ProviderHelper.getPGPSecretKeyByKeyId(context, encData.getKeyID());
if (secretKey != null) {
+ // secret key exists in database
+
+ // allow only a specific key for decryption?
+ if (enforcedKeyId != 0) {
+ // TODO: improve this code! get master key directly!
+ PGPSecretKeyRing secretKeyRing = ProviderHelper.getPGPSecretKeyRingByKeyId(context, encData.getKeyID());
+ long masterKeyId = PgpKeyHelper.getMasterKey(secretKeyRing).getKeyID();
+ Log.d(Constants.TAG, "encData.getKeyID():" + encData.getKeyID());
+ Log.d(Constants.TAG, "enforcedKeyId: " + enforcedKeyId);
+ Log.d(Constants.TAG, "masterKeyId: " + masterKeyId);
+
+ if (enforcedKeyId != masterKeyId) {
+ throw new PgpGeneralException(context.getString(R.string.error_no_secret_key_found));
+ }
+ }
+
pbe = encData;
+
+ // if no passphrase was explicitly set try to get it from the cache service
+ if (passphrase == null) {
+ // returns "" if key has no passphrase
+ passphrase = PassphraseCacheService.getCachedPassphrase(context, encData.getKeyID());
+
+ // if passphrase was not cached, return here indicating that a passphrase is missing!
+ if (passphrase == null) {
+ returnData.setKeyPassphraseNeeded(true);
+ return returnData;
+ }
+ }
+
break;
}
+
+
}
}
@@ -289,7 +335,7 @@ public class PgpDecryptVerify {
currentProgress += 5;
updateProgress(R.string.progress_extracting_key, currentProgress, 100);
- PGPPrivateKey privateKey = null;
+ PGPPrivateKey privateKey;
try {
PBESecretKeyDecryptor keyDecryptor = new JcePBESecretKeyDecryptorBuilder()
.setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(
@@ -317,6 +363,7 @@ public class PgpDecryptVerify {
PGPObjectFactory plainFact = new PGPObjectFactory(clear);
Object dataChunk = plainFact.nextObject();
PGPOnePassSignature signature = null;
+ OpenPgpSignatureResult signatureResult = null;
PGPPublicKey signatureKey = null;
int signatureIndex = -1;
@@ -334,7 +381,7 @@ public class PgpDecryptVerify {
if (dataChunk instanceof PGPOnePassSignatureList) {
updateProgress(R.string.progress_processing_signature, currentProgress, 100);
- returnData.putBoolean(KeychainIntentService.RESULT_SIGNATURE, true);
+ signatureResult = new OpenPgpSignatureResult();
PGPOnePassSignatureList sigList = (PGPOnePassSignatureList) dataChunk;
for (int i = 0; i < sigList.size(); ++i) {
signature = sigList.get(i);
@@ -354,12 +401,12 @@ public class PgpDecryptVerify {
if (signKeyRing != null) {
userId = PgpKeyHelper.getMainUserId(PgpKeyHelper.getMasterKey(signKeyRing));
}
- returnData.putString(KeychainIntentService.RESULT_SIGNATURE_USER_ID, userId);
+ signatureResult.setUserId(userId);
break;
}
}
- returnData.putLong(KeychainIntentService.RESULT_SIGNATURE_KEY_ID, signatureKeyId);
+ signatureResult.setKeyId(signatureKeyId);
if (signature != null) {
JcaPGPContentVerifierBuilderProvider contentVerifierBuilderProvider = new JcaPGPContentVerifierBuilderProvider()
@@ -367,7 +414,7 @@ public class PgpDecryptVerify {
signature.init(contentVerifierBuilderProvider, signatureKey);
} else {
- returnData.putBoolean(KeychainIntentService.RESULT_SIGNATURE_UNKNOWN, true);
+ signatureResult.setStatus(OpenPgpSignatureResult.SIGNATURE_UNKNOWN_PUB_KEY);
}
dataChunk = plainFact.nextObject();
@@ -405,8 +452,7 @@ public class PgpDecryptVerify {
try {
signature.update(buffer, 0, n);
} catch (SignatureException e) {
- returnData
- .putBoolean(KeychainIntentService.RESULT_SIGNATURE_SUCCESS, false);
+ signatureResult.setStatus(OpenPgpSignatureResult.SIGNATURE_ERROR);
signature = null;
}
}
@@ -430,17 +476,20 @@ public class PgpDecryptVerify {
PGPSignature messageSignature = signatureList.get(signatureIndex);
// these are not cleartext signatures!
- returnData.putBoolean(KeychainIntentService.RESULT_CLEARTEXT_SIGNATURE_ONLY, false);
+ // TODO: what about binary signatures?
+ signatureResult.setSignatureOnly(false);
//Now check binding signatures
- boolean keyBinding_isok = verifyKeyBinding(context, messageSignature, signatureKey);
- boolean sig_isok = signature.verify(messageSignature);
+ boolean validKeyBinding = verifyKeyBinding(context, messageSignature, signatureKey);
+ boolean validSignature = signature.verify(messageSignature);
- returnData.putBoolean(KeychainIntentService.RESULT_SIGNATURE_SUCCESS, keyBinding_isok & sig_isok);
+ // TODO: implement CERTIFIED!
+ if (validKeyBinding & validSignature) {
+ signatureResult.setStatus(OpenPgpSignatureResult.SIGNATURE_SUCCESS_UNCERTIFIED);
+ }
}
}
- // TODO: test if this integrity really check works!
if (encryptedData.isIntegrityProtected()) {
updateProgress(R.string.progress_verifying_integrity, 95, 100);
@@ -455,9 +504,12 @@ public class PgpDecryptVerify {
} else {
// no integrity check
Log.e(Constants.TAG, "Encrypted data was not integrity protected!");
+ // TODO: inform user?
}
updateProgress(R.string.progress_done, 100, 100);
+
+ returnData.setSignatureResult(signatureResult);
return returnData;
}
@@ -474,11 +526,12 @@ public class PgpDecryptVerify {
* @throws PGPException
* @throws SignatureException
*/
- private Bundle verifyCleartextSignature(ArmoredInputStream aIn)
+ private PgpDecryptVerifyResult verifyCleartextSignature(ArmoredInputStream aIn)
throws IOException, PgpGeneralException, PGPException, SignatureException {
- Bundle returnData = new Bundle();
+ PgpDecryptVerifyResult returnData = new PgpDecryptVerifyResult();
+ OpenPgpSignatureResult signatureResult = new OpenPgpSignatureResult();
// cleartext signatures are never encrypted ;)
- returnData.putBoolean(KeychainIntentService.RESULT_CLEARTEXT_SIGNATURE_ONLY, true);
+ signatureResult.setSignatureOnly(true);
ByteArrayOutputStream out = new ByteArrayOutputStream();
@@ -504,8 +557,6 @@ public class PgpDecryptVerify {
byte[] clearText = out.toByteArray();
outStream.write(clearText);
- returnData.putBoolean(KeychainIntentService.RESULT_SIGNATURE, true);
-
updateProgress(R.string.progress_processing_signature, 60, 100);
PGPObjectFactory pgpFact = new PGPObjectFactory(aIn);
@@ -533,15 +584,17 @@ public class PgpDecryptVerify {
if (signKeyRing != null) {
userId = PgpKeyHelper.getMainUserId(PgpKeyHelper.getMasterKey(signKeyRing));
}
- returnData.putString(KeychainIntentService.RESULT_SIGNATURE_USER_ID, userId);
+ signatureResult.setUserId(userId);
break;
}
}
- returnData.putLong(KeychainIntentService.RESULT_SIGNATURE_KEY_ID, signatureKeyId);
+ signatureResult.setKeyId(signatureKeyId);
if (signature == null) {
- returnData.putBoolean(KeychainIntentService.RESULT_SIGNATURE_UNKNOWN, true);
+ signatureResult.setStatus(OpenPgpSignatureResult.SIGNATURE_UNKNOWN_PUB_KEY);
+ returnData.setSignatureResult(signatureResult);
+
updateProgress(R.string.progress_done, 100, 100);
return returnData;
}
@@ -569,12 +622,17 @@ public class PgpDecryptVerify {
} while (lookAhead != -1);
}
- boolean sig_isok = signature.verify();
-
//Now check binding signatures
- boolean keyBinding_isok = verifyKeyBinding(context, signature, signatureKey);
+ boolean validKeyBinding = verifyKeyBinding(context, signature, signatureKey);
+ boolean validSignature = signature.verify();
+
+ if (validSignature & validKeyBinding) {
+ signatureResult.setStatus(OpenPgpSignatureResult.SIGNATURE_SUCCESS_UNCERTIFIED);
+ }
+
+ // TODO: what about SIGNATURE_SUCCESS_CERTIFIED and SIGNATURE_ERROR????
- returnData.putBoolean(KeychainIntentService.RESULT_SIGNATURE_SUCCESS, sig_isok & keyBinding_isok);
+ returnData.setSignatureResult(signatureResult);
updateProgress(R.string.progress_done, 100, 100);
return returnData;
@@ -582,34 +640,34 @@ public class PgpDecryptVerify {
private static boolean verifyKeyBinding(Context context, PGPSignature signature, PGPPublicKey signatureKey) {
long signatureKeyId = signature.getKeyID();
- boolean keyBinding_isok = false;
- String userId = null;
+ boolean validKeyBinding = false;
+
PGPPublicKeyRing signKeyRing = ProviderHelper.getPGPPublicKeyRingByKeyId(context,
signatureKeyId);
PGPPublicKey mKey = null;
if (signKeyRing != null) {
mKey = PgpKeyHelper.getMasterKey(signKeyRing);
}
+
if (signature.getKeyID() != mKey.getKeyID()) {
- keyBinding_isok = verifyKeyBinding(mKey, signatureKey);
+ validKeyBinding = verifyKeyBinding(mKey, signatureKey);
} else { //if the key used to make the signature was the master key, no need to check binding sigs
- keyBinding_isok = true;
+ validKeyBinding = true;
}
- return keyBinding_isok;
+ return validKeyBinding;
}
private static boolean verifyKeyBinding(PGPPublicKey masterPublicKey, PGPPublicKey signingPublicKey) {
- boolean subkeyBinding_isok = false;
- boolean tmp_subkeyBinding_isok = false;
- boolean primkeyBinding_isok = false;
- JcaPGPContentVerifierBuilderProvider contentVerifierBuilderProvider = new JcaPGPContentVerifierBuilderProvider()
- .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME);
+ boolean validSubkeyBinding = false;
+ boolean validTempSubkeyBinding = false;
+ boolean validPrimaryKeyBinding = false;
+
+ JcaPGPContentVerifierBuilderProvider contentVerifierBuilderProvider =
+ new JcaPGPContentVerifierBuilderProvider()
+ .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME);
Iterator<PGPSignature> itr = signingPublicKey.getSignatures();
- subkeyBinding_isok = false;
- tmp_subkeyBinding_isok = false;
- primkeyBinding_isok = false;
while (itr.hasNext()) { //what does gpg do if the subkey binding is wrong?
//gpg has an invalid subkey binding error on key import I think, but doesn't shout
//about keys without subkey signing. Can't get it to import a slightly broken one
@@ -619,32 +677,36 @@ public class PgpDecryptVerify {
//check and if ok, check primary key binding.
try {
sig.init(contentVerifierBuilderProvider, masterPublicKey);
- tmp_subkeyBinding_isok = sig.verifyCertification(masterPublicKey, signingPublicKey);
+ validTempSubkeyBinding = sig.verifyCertification(masterPublicKey, signingPublicKey);
} catch (PGPException e) {
continue;
} catch (SignatureException e) {
continue;
}
- if (tmp_subkeyBinding_isok)
- subkeyBinding_isok = true;
- if (tmp_subkeyBinding_isok) {
- primkeyBinding_isok = verifyPrimaryBinding(sig.getUnhashedSubPackets(), masterPublicKey, signingPublicKey);
- if (primkeyBinding_isok)
+ if (validTempSubkeyBinding)
+ validSubkeyBinding = true;
+ if (validTempSubkeyBinding) {
+ validPrimaryKeyBinding = verifyPrimaryKeyBinding(sig.getUnhashedSubPackets(),
+ masterPublicKey, signingPublicKey);
+ if (validPrimaryKeyBinding)
break;
- primkeyBinding_isok = verifyPrimaryBinding(sig.getHashedSubPackets(), masterPublicKey, signingPublicKey);
- if (primkeyBinding_isok)
+ validPrimaryKeyBinding = verifyPrimaryKeyBinding(sig.getHashedSubPackets(),
+ masterPublicKey, signingPublicKey);
+ if (validPrimaryKeyBinding)
break;
}
}
}
- return (subkeyBinding_isok & primkeyBinding_isok);
+ return (validSubkeyBinding & validPrimaryKeyBinding);
}
- private static boolean verifyPrimaryBinding(PGPSignatureSubpacketVector Pkts, PGPPublicKey masterPublicKey, PGPPublicKey signingPublicKey) {
- boolean primkeyBinding_isok = false;
- JcaPGPContentVerifierBuilderProvider contentVerifierBuilderProvider = new JcaPGPContentVerifierBuilderProvider()
- .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME);
+ private static boolean verifyPrimaryKeyBinding(PGPSignatureSubpacketVector Pkts,
+ PGPPublicKey masterPublicKey, PGPPublicKey signingPublicKey) {
+ boolean validPrimaryKeyBinding = false;
+ JcaPGPContentVerifierBuilderProvider contentVerifierBuilderProvider =
+ new JcaPGPContentVerifierBuilderProvider()
+ .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME);
PGPSignatureList eSigList;
if (Pkts.hasSubpacket(SignatureSubpacketTags.EMBEDDED_SIGNATURE)) {
@@ -660,8 +722,8 @@ public class PgpDecryptVerify {
if (emSig.getSignatureType() == PGPSignature.PRIMARYKEY_BINDING) {
try {
emSig.init(contentVerifierBuilderProvider, signingPublicKey);
- primkeyBinding_isok = emSig.verifyCertification(masterPublicKey, signingPublicKey);
- if (primkeyBinding_isok)
+ validPrimaryKeyBinding = emSig.verifyCertification(masterPublicKey, signingPublicKey);
+ if (validPrimaryKeyBinding)
break;
} catch (PGPException e) {
continue;
@@ -671,7 +733,8 @@ public class PgpDecryptVerify {
}
}
}
- return primkeyBinding_isok;
+
+ return validPrimaryKeyBinding;
}
/**
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerifyResult.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerifyResult.java
new file mode 100644
index 000000000..0477c4fdf
--- /dev/null
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerifyResult.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2014 Dominik Schürmann <dominik@dominikschuermann.de>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package org.sufficientlysecure.keychain.pgp;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import org.openintents.openpgp.OpenPgpSignatureResult;
+
+public class PgpDecryptVerifyResult implements Parcelable {
+ boolean symmetricPassphraseNeeded;
+ boolean keyPassphraseNeeded;
+ OpenPgpSignatureResult signatureResult;
+
+ public boolean isSymmetricPassphraseNeeded() {
+ return symmetricPassphraseNeeded;
+ }
+
+ public void setSymmetricPassphraseNeeded(boolean symmetricPassphraseNeeded) {
+ this.symmetricPassphraseNeeded = symmetricPassphraseNeeded;
+ }
+
+ public boolean isKeyPassphraseNeeded() {
+ return keyPassphraseNeeded;
+ }
+
+ public void setKeyPassphraseNeeded(boolean keyPassphraseNeeded) {
+ this.keyPassphraseNeeded = keyPassphraseNeeded;
+ }
+
+ public OpenPgpSignatureResult getSignatureResult() {
+ return signatureResult;
+ }
+
+ public void setSignatureResult(OpenPgpSignatureResult signatureResult) {
+ this.signatureResult = signatureResult;
+ }
+
+ public PgpDecryptVerifyResult() {
+
+ }
+
+ public PgpDecryptVerifyResult(PgpDecryptVerifyResult b) {
+ this.symmetricPassphraseNeeded = b.symmetricPassphraseNeeded;
+ this.keyPassphraseNeeded = b.keyPassphraseNeeded;
+ this.signatureResult = b.signatureResult;
+ }
+
+
+ public int describeContents() {
+ return 0;
+ }
+
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeByte((byte) (symmetricPassphraseNeeded ? 1 : 0));
+ dest.writeByte((byte) (keyPassphraseNeeded ? 1 : 0));
+ dest.writeParcelable(signatureResult, 0);
+ }
+
+ public static final Creator<PgpDecryptVerifyResult> CREATOR = new Creator<PgpDecryptVerifyResult>() {
+ public PgpDecryptVerifyResult createFromParcel(final Parcel source) {
+ PgpDecryptVerifyResult vr = new PgpDecryptVerifyResult();
+ vr.symmetricPassphraseNeeded = source.readByte() == 1;
+ vr.keyPassphraseNeeded = source.readByte() == 1;
+ vr.signatureResult = source.readParcelable(OpenPgpSignatureResult.class.getClassLoader());
+ return vr;
+ }
+
+ public PgpDecryptVerifyResult[] newArray(final int size) {
+ return new PgpDecryptVerifyResult[size];
+ }
+ };
+}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpImportExport.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpImportExport.java
index a7a574ee7..2495a212c 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpImportExport.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpImportExport.java
@@ -90,8 +90,8 @@ public class PgpImportExport {
aos.write(keyring.getEncoded());
aos.close();
- String armouredKey = bos.toString("UTF-8");
- server.add(armouredKey);
+ String armoredKey = bos.toString("UTF-8");
+ server.add(armoredKey);
return true;
} catch (IOException e) {
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java
index 0073107a0..f744fbcec 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java
@@ -105,7 +105,7 @@ public class PgpKeyOperation {
}
}
- public PGPSecretKey createKey(int algorithmChoice, int keySize, String passPhrase,
+ public PGPSecretKey createKey(int algorithmChoice, int keySize, String passphrase,
boolean isMasterKey) throws NoSuchAlgorithmException, PGPException, NoSuchProviderException,
PgpGeneralException, InvalidAlgorithmParameterException {
@@ -113,8 +113,8 @@ public class PgpKeyOperation {
throw new PgpGeneralException(mContext.getString(R.string.error_key_size_minimum512bit));
}
- if (passPhrase == null) {
- passPhrase = "";
+ if (passphrase == null) {
+ passphrase = "";
}
int algorithm;
@@ -168,7 +168,7 @@ public class PgpKeyOperation {
// Build key encrypter and decrypter based on passphrase
PBESecretKeyEncryptor keyEncryptor = new JcePBESecretKeyEncryptorBuilder(
PGPEncryptedData.CAST5, sha1Calc)
- .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(passPhrase.toCharArray());
+ .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(passphrase.toCharArray());
return new PGPSecretKey(keyPair.getPrivateKey(), keyPair.getPublicKey(),
sha1Calc, isMasterKey, keyEncryptor);
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java
index ba931c61a..fef3d391b 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java
@@ -626,7 +626,7 @@ public class ProviderHelper {
String armoredKey = bos.toString("UTF-8");
- Log.d(Constants.TAG, "armouredKey:" + armoredKey);
+ Log.d(Constants.TAG, "armoredKey:" + armoredKey);
output.add(armoredKey);
} catch (IOException e) {
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java
index 24bce8eeb..d796ccf31 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java
@@ -44,6 +44,7 @@ import org.sufficientlysecure.keychain.helper.OtherHelper;
import org.sufficientlysecure.keychain.helper.Preferences;
import org.sufficientlysecure.keychain.pgp.PgpConversionHelper;
import org.sufficientlysecure.keychain.pgp.PgpDecryptVerify;
+import org.sufficientlysecure.keychain.pgp.PgpDecryptVerifyResult;
import org.sufficientlysecure.keychain.pgp.PgpHelper;
import org.sufficientlysecure.keychain.pgp.PgpImportExport;
import org.sufficientlysecure.keychain.pgp.PgpKeyOperation;
@@ -176,13 +177,7 @@ public class KeychainIntentService extends IntentService implements ProgressDial
// decrypt/verify
public static final String RESULT_DECRYPTED_STRING = "decrypted_message";
public static final String RESULT_DECRYPTED_BYTES = "decrypted_data";
- public static final String RESULT_SIGNATURE = "signature";
- public static final String RESULT_SIGNATURE_KEY_ID = "signature_key_id";
- public static final String RESULT_SIGNATURE_USER_ID = "signature_user_id";
- public static final String RESULT_CLEARTEXT_SIGNATURE_ONLY = "signature_only";
-
- public static final String RESULT_SIGNATURE_SUCCESS = "signature_success";
- public static final String RESULT_SIGNATURE_UNKNOWN = "signature_unknown";
+ public static final String RESULT_DECRYPT_VERIFY_RESULT = "signature";
// import
public static final String RESULT_IMPORT_ADDED = "added";
@@ -198,8 +193,16 @@ public class KeychainIntentService extends IntentService implements ProgressDial
Messenger mMessenger;
+ private boolean mIsCanceled;
+
public KeychainIntentService() {
- super("ApgService");
+ super("KeychainIntentService");
+ }
+
+ @Override
+ public void onDestroy() {
+ super.onDestroy();
+ this.mIsCanceled = true;
}
/**
@@ -476,15 +479,17 @@ public class KeychainIntentService extends IntentService implements ProgressDial
// verifyText and decrypt returning additional resultData values for the
// verification of signatures
PgpDecryptVerify.Builder builder = new PgpDecryptVerify.Builder(this, inputData, outStream);
- builder.progress(this);
+ builder.progressDialogUpdater(this);
builder.assumeSymmetric(assumeSymmetricEncryption)
.passphrase(PassphraseCacheService.getCachedPassphrase(this, secretKeyId));
- resultData = builder.build().execute();
+ PgpDecryptVerifyResult decryptVerifyResult = builder.build().execute();
outStream.close();
+ resultData.putParcelable(RESULT_DECRYPT_VERIFY_RESULT, decryptVerifyResult);
+
/* Output */
switch (target) {
@@ -733,7 +738,7 @@ public class KeychainIntentService extends IntentService implements ProgressDial
*/
// need to have access to the bufferedInput, so we can reuse it for the possible
// PGPObject chunks after the first one, e.g. files with several consecutive ASCII
- // armour blocks
+ // armor blocks
BufferedInputStream bufferedInput = new BufferedInputStream(new ByteArrayInputStream(downloadedKey));
try {
@@ -805,6 +810,10 @@ public class KeychainIntentService extends IntentService implements ProgressDial
}
private void sendErrorToHandler(Exception e) {
+ // Service was canceled. Do not send error to handler.
+ if (this.mIsCanceled)
+ return;
+
Log.e(Constants.TAG, "ApgService Exception: ", e);
e.printStackTrace();
@@ -814,6 +823,10 @@ public class KeychainIntentService extends IntentService implements ProgressDial
}
private void sendMessageToHandler(Integer arg1, Integer arg2, Bundle data) {
+ // Service was canceled. Do not send message to handler.
+ if (this.mIsCanceled)
+ return;
+
Message msg = Message.obtain();
msg.arg1 = arg1;
if (arg2 != null) {
@@ -841,10 +854,10 @@ public class KeychainIntentService extends IntentService implements ProgressDial
}
/**
- * Set progress of ProgressDialog by sending message to handler on UI thread
+ * Set progressDialogUpdater of ProgressDialog by sending message to handler on UI thread
*/
public void setProgress(String message, int progress, int max) {
- Log.d(Constants.TAG, "Send message by setProgress with progress=" + progress + ", max="
+ Log.d(Constants.TAG, "Send message by setProgress with progressDialogUpdater=" + progress + ", max="
+ max);
Bundle data = new Bundle();
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentServiceHandler.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentServiceHandler.java
index dfea7eb04..6eba9cc83 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentServiceHandler.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentServiceHandler.java
@@ -21,6 +21,8 @@ import org.sufficientlysecure.keychain.ui.dialog.ProgressDialogFragment;
import org.sufficientlysecure.keychain.R;
import android.app.Activity;
+import android.content.DialogInterface;
+import android.content.DialogInterface.OnCancelListener;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
@@ -55,9 +57,15 @@ public class KeychainIntentServiceHandler extends Handler {
}
public KeychainIntentServiceHandler(Activity activity, int progressDialogMessageId, int progressDialogStyle) {
+ this(activity, progressDialogMessageId, progressDialogStyle, false, null);
+ }
+
+ public KeychainIntentServiceHandler(Activity activity, int progressDialogMessageId,
+ int progressDialogStyle, boolean cancelable,
+ OnCancelListener onCancelListener) {
this.mActivity = activity;
this.mProgressDialogFragment = ProgressDialogFragment.newInstance(progressDialogMessageId,
- progressDialogStyle);
+ progressDialogStyle, cancelable, onCancelListener);
}
public void showProgressDialog(FragmentActivity activity) {
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/OpenPgpService.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/OpenPgpService.java
index 34213bd3b..f697faa6e 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/OpenPgpService.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/OpenPgpService.java
@@ -21,21 +21,22 @@ import android.app.PendingIntent;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
-import android.os.Bundle;
import android.os.IBinder;
import android.os.ParcelFileDescriptor;
import org.openintents.openpgp.IOpenPgpService;
import org.openintents.openpgp.OpenPgpError;
import org.openintents.openpgp.OpenPgpSignatureResult;
-import org.openintents.openpgp.util.OpenPgpConstants;
+import org.openintents.openpgp.util.OpenPgpApi;
import org.spongycastle.util.Arrays;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.Id;
import org.sufficientlysecure.keychain.pgp.PgpDecryptVerify;
+import org.sufficientlysecure.keychain.pgp.PgpDecryptVerifyResult;
import org.sufficientlysecure.keychain.pgp.PgpSignEncrypt;
+import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
import org.sufficientlysecure.keychain.provider.KeychainContract;
-import org.sufficientlysecure.keychain.service.KeychainIntentService;
+import org.sufficientlysecure.keychain.provider.ProviderHelper;
import org.sufficientlysecure.keychain.service.PassphraseCacheService;
import org.sufficientlysecure.keychain.util.InputData;
import org.sufficientlysecure.keychain.util.Log;
@@ -48,7 +49,7 @@ public class OpenPgpService extends RemoteService {
private static final int PRIVATE_REQUEST_CODE_PASSPHRASE = 551;
private static final int PRIVATE_REQUEST_CODE_USER_IDS = 552;
-
+ private static final int PRIVATE_REQUEST_CODE_GET_KEYS = 553;
/**
* Search database for key ids based on emails.
@@ -56,7 +57,7 @@ public class OpenPgpService extends RemoteService {
* @param encryptionUserIds
* @return
*/
- private Bundle getKeyIdsFromEmails(Bundle params, String[] encryptionUserIds) {
+ private Intent getKeyIdsFromEmails(Intent data, String[] encryptionUserIds) {
// find key ids to given emails in database
ArrayList<Long> keyIds = new ArrayList<Long>();
@@ -91,21 +92,20 @@ public class OpenPgpService extends RemoteService {
// allow the user to verify pub key selection
if (missingUserIdsCheck || dublicateUserIdsCheck) {
- // build PendingIntent for passphrase input
+ // build PendingIntent
Intent intent = new Intent(getBaseContext(), RemoteServiceActivity.class);
intent.setAction(RemoteServiceActivity.ACTION_SELECT_PUB_KEYS);
intent.putExtra(RemoteServiceActivity.EXTRA_SELECTED_MASTER_KEY_IDS, keyIdsArray);
intent.putExtra(RemoteServiceActivity.EXTRA_MISSING_USER_IDS, missingUserIds);
intent.putExtra(RemoteServiceActivity.EXTRA_DUBLICATE_USER_IDS, dublicateUserIds);
- intent.putExtra(OpenPgpConstants.PI_RESULT_PARAMS, params);
+ intent.putExtra(RemoteServiceActivity.EXTRA_DATA, data);
PendingIntent pi = PendingIntent.getActivity(getBaseContext(), PRIVATE_REQUEST_CODE_USER_IDS, intent, 0);
// return PendingIntent to be executed by client
- Bundle result = new Bundle();
- result.putInt(OpenPgpConstants.RESULT_CODE, OpenPgpConstants.RESULT_CODE_USER_INTERACTION_REQUIRED);
- result.putParcelable(OpenPgpConstants.RESULT_INTENT, pi);
-
+ Intent result = new Intent();
+ result.putExtra(OpenPgpApi.RESULT_INTENT, pi);
+ result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_USER_INTERACTION_REQUIRED);
return result;
}
@@ -113,44 +113,43 @@ public class OpenPgpService extends RemoteService {
return null;
}
- Bundle result = new Bundle();
- result.putInt(OpenPgpConstants.RESULT_CODE, OpenPgpConstants.RESULT_CODE_SUCCESS);
- result.putLongArray(OpenPgpConstants.PARAMS_KEY_IDS, keyIdsArray);
+ Intent result = new Intent();
+ result.putExtra(OpenPgpApi.EXTRA_KEY_IDS, keyIdsArray);
+ result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_SUCCESS);
return result;
}
- private Bundle getPassphraseBundleIntent(Bundle params, long keyId) {
+ private Intent getPassphraseBundleIntent(Intent data, long keyId) {
// build PendingIntent for passphrase input
Intent intent = new Intent(getBaseContext(), RemoteServiceActivity.class);
intent.setAction(RemoteServiceActivity.ACTION_CACHE_PASSPHRASE);
intent.putExtra(RemoteServiceActivity.EXTRA_SECRET_KEY_ID, keyId);
// pass params through to activity that it can be returned again later to repeat pgp operation
- intent.putExtra(OpenPgpConstants.PI_RESULT_PARAMS, params);
+ intent.putExtra(RemoteServiceActivity.EXTRA_DATA, data);
PendingIntent pi = PendingIntent.getActivity(getBaseContext(), PRIVATE_REQUEST_CODE_PASSPHRASE, intent, 0);
// return PendingIntent to be executed by client
- Bundle result = new Bundle();
- result.putInt(OpenPgpConstants.RESULT_CODE, OpenPgpConstants.RESULT_CODE_USER_INTERACTION_REQUIRED);
- result.putParcelable(OpenPgpConstants.RESULT_INTENT, pi);
-
+ Intent result = new Intent();
+ result.putExtra(OpenPgpApi.RESULT_INTENT, pi);
+ result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_USER_INTERACTION_REQUIRED);
return result;
}
- private Bundle signImpl(Bundle params, ParcelFileDescriptor input, ParcelFileDescriptor output,
- AppSettings appSettings) {
+ private Intent signImpl(Intent data, ParcelFileDescriptor input,
+ ParcelFileDescriptor output, AppSettings appSettings) {
try {
- boolean asciiArmor = params.getBoolean(OpenPgpConstants.PARAMS_REQUEST_ASCII_ARMOR, true);
+ boolean asciiArmor = data.getBooleanExtra(OpenPgpApi.EXTRA_REQUEST_ASCII_ARMOR, true);
// get passphrase from cache, if key has "no" passphrase, this returns an empty String
String passphrase;
- if (params.containsKey(OpenPgpConstants.PARAMS_PASSPHRASE)) {
- passphrase = params.getString(OpenPgpConstants.PARAMS_PASSPHRASE);
+ if (data.hasExtra(OpenPgpApi.EXTRA_PASSPHRASE)) {
+ passphrase = data.getStringExtra(OpenPgpApi.EXTRA_PASSPHRASE);
} else {
passphrase = PassphraseCacheService.getCachedPassphrase(getContext(), appSettings.getKeyId());
}
if (passphrase == null) {
// get PendingIntent for passphrase input, add it to given params and return to client
- Bundle passphraseBundle = getPassphraseBundleIntent(params, appSettings.getKeyId());
+ Intent passphraseBundle = getPassphraseBundleIntent(data, appSettings.getKeyId());
return passphraseBundle;
}
@@ -174,44 +173,43 @@ public class OpenPgpService extends RemoteService {
os.close();
}
- Bundle result = new Bundle();
- result.putInt(OpenPgpConstants.RESULT_CODE, OpenPgpConstants.RESULT_CODE_SUCCESS);
+ Intent result = new Intent();
+ result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_SUCCESS);
return result;
} catch (Exception e) {
- Bundle result = new Bundle();
- result.putInt(OpenPgpConstants.RESULT_CODE, OpenPgpConstants.RESULT_CODE_ERROR);
- result.putParcelable(OpenPgpConstants.RESULT_ERRORS,
+ Intent result = new Intent();
+ result.putExtra(OpenPgpApi.RESULT_ERROR,
new OpenPgpError(OpenPgpError.GENERIC_ERROR, e.getMessage()));
+ result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_ERROR);
return result;
}
}
- private Bundle encryptAndSignImpl(Bundle params, ParcelFileDescriptor input,
- ParcelFileDescriptor output, AppSettings appSettings,
- boolean sign) {
+ private Intent encryptAndSignImpl(Intent data, ParcelFileDescriptor input,
+ ParcelFileDescriptor output, AppSettings appSettings, boolean sign) {
try {
- boolean asciiArmor = params.getBoolean(OpenPgpConstants.PARAMS_REQUEST_ASCII_ARMOR, true);
+ boolean asciiArmor = data.getBooleanExtra(OpenPgpApi.EXTRA_REQUEST_ASCII_ARMOR, true);
long[] keyIds;
- if (params.containsKey(OpenPgpConstants.PARAMS_KEY_IDS)) {
- keyIds = params.getLongArray(OpenPgpConstants.PARAMS_KEY_IDS);
- } else if (params.containsKey(OpenPgpConstants.PARAMS_USER_IDS)) {
+ if (data.hasExtra(OpenPgpApi.EXTRA_KEY_IDS)) {
+ keyIds = data.getLongArrayExtra(OpenPgpApi.EXTRA_KEY_IDS);
+ } else if (data.hasExtra(OpenPgpApi.EXTRA_USER_IDS)) {
// get key ids based on given user ids
- String[] userIds = params.getStringArray(OpenPgpConstants.PARAMS_USER_IDS);
+ String[] userIds = data.getStringArrayExtra(OpenPgpApi.EXTRA_USER_IDS);
// give params through to activity...
- Bundle result = getKeyIdsFromEmails(params, userIds);
+ Intent result = getKeyIdsFromEmails(data, userIds);
- if (result.getInt(OpenPgpConstants.RESULT_CODE, 0) == OpenPgpConstants.RESULT_CODE_SUCCESS) {
- keyIds = result.getLongArray(OpenPgpConstants.PARAMS_KEY_IDS);
+ if (result.getIntExtra(OpenPgpApi.RESULT_CODE, 0) == OpenPgpApi.RESULT_CODE_SUCCESS) {
+ keyIds = result.getLongArrayExtra(OpenPgpApi.EXTRA_KEY_IDS);
} else {
// if not success -> result contains a PendingIntent for user interaction
return result;
}
} else {
- Bundle result = new Bundle();
- result.putInt(OpenPgpConstants.RESULT_CODE, OpenPgpConstants.RESULT_CODE_ERROR);
- result.putParcelable(OpenPgpConstants.RESULT_ERRORS,
+ Intent result = new Intent();
+ result.putExtra(OpenPgpApi.RESULT_ERROR,
new OpenPgpError(OpenPgpError.GENERIC_ERROR, "Missing parameter user_ids or key_ids!"));
+ result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_ERROR);
return result;
}
@@ -235,15 +233,15 @@ public class OpenPgpService extends RemoteService {
if (sign) {
String passphrase;
- if (params.containsKey(OpenPgpConstants.PARAMS_PASSPHRASE)) {
- passphrase = params.getString(OpenPgpConstants.PARAMS_PASSPHRASE);
+ if (data.hasExtra(OpenPgpApi.EXTRA_PASSPHRASE)) {
+ passphrase = data.getStringExtra(OpenPgpApi.EXTRA_PASSPHRASE);
} else {
passphrase = PassphraseCacheService.getCachedPassphrase(getContext(),
appSettings.getKeyId());
}
if (passphrase == null) {
// get PendingIntent for passphrase input, add it to given params and return to client
- Bundle passphraseBundle = getPassphraseBundleIntent(params, appSettings.getKeyId());
+ Intent passphraseBundle = getPassphraseBundleIntent(data, appSettings.getKeyId());
return passphraseBundle;
}
@@ -263,193 +261,123 @@ public class OpenPgpService extends RemoteService {
os.close();
}
- Bundle result = new Bundle();
- result.putInt(OpenPgpConstants.RESULT_CODE, OpenPgpConstants.RESULT_CODE_SUCCESS);
+ Intent result = new Intent();
+ result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_SUCCESS);
return result;
} catch (Exception e) {
- Bundle result = new Bundle();
- result.putInt(OpenPgpConstants.RESULT_CODE, OpenPgpConstants.RESULT_CODE_ERROR);
- result.putParcelable(OpenPgpConstants.RESULT_ERRORS,
+ Intent result = new Intent();
+ result.putExtra(OpenPgpApi.RESULT_ERROR,
new OpenPgpError(OpenPgpError.GENERIC_ERROR, e.getMessage()));
+ result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_ERROR);
return result;
}
}
- private Bundle decryptAndVerifyImpl(Bundle params, ParcelFileDescriptor input,
+ private Intent decryptAndVerifyImpl(Intent data, ParcelFileDescriptor input,
ParcelFileDescriptor output, AppSettings appSettings) {
try {
// Get Input- and OutputStream from ParcelFileDescriptor
InputStream is = new ParcelFileDescriptor.AutoCloseInputStream(input);
OutputStream os = new ParcelFileDescriptor.AutoCloseOutputStream(output);
- OpenPgpSignatureResult sigResult = null;
- try {
-// PGPUtil.getDecoderStream(is)
- // TODOs API 2.0:
- // implement verify-only!
- // fix the mess: http://stackoverflow.com/questions/148130/how-do-i-peek-at-the-first-two-bytes-in-an-inputstream
- // should we allow to decrypt everything under every key id or only the one set?
- // TODO: instead of trying to get the passphrase before
- // pause stream when passphrase is missing and then resume
-
-
- // TODO: this is not really needed
- // checked if it is text with BEGIN and END tags
-// String message = new String(inputBytes);
-// Log.d(Constants.TAG, "in: " + message);
-// boolean signedOnly = false;
-// Matcher matcher = PgpHelper.PGP_MESSAGE.matcher(message);
-// if (matcher.matches()) {
-// Log.d(Constants.TAG, "PGP_MESSAGE matched");
-// message = matcher.group(1);
-// // replace non breakable spaces
-// message = message.replaceAll("\\xa0", " ");
-//
-// // overwrite inputBytes
-// inputBytes = message.getBytes();
-// } else {
-// matcher = PgpHelper.PGP_SIGNED_MESSAGE.matcher(message);
-// if (matcher.matches()) {
-// signedOnly = true;
-// Log.d(Constants.TAG, "PGP_SIGNED_MESSAGE matched");
-// message = matcher.group(1);
-// // replace non breakable spaces
-// message = message.replaceAll("\\xa0", " ");
-//
-// // overwrite inputBytes
-// inputBytes = message.getBytes();
-// } else {
-// Log.d(Constants.TAG, "Nothing matched! Binary?");
-// }
-// }
- // END TODO
-
-// Log.d(Constants.TAG, "in: " + new String(inputBytes));
-
- // TODO: This allows to decrypt messages with ALL secret keys, not only the one for the
- // app, Fix this?
-
-// String passphrase = null;
-// if (!signedOnly) {
-// // BEGIN Get key
-// // TODO: this input stream is consumed after PgpMain.getDecryptionKeyId()... do it
-// // better!
-// InputStream inputStream2 = new ByteArrayInputStream(inputBytes);
-//
-// // TODO: duplicates functions from DecryptActivity!
-// long secretKeyId;
-// try {
-// if (inputStream2.markSupported()) {
-// // should probably set this to the max size of two
-// // pgpF objects, if it even needs to be anything other
-// // than 0.
-// inputStream2.mark(200);
-// }
-// secretKeyId = PgpHelper.getDecryptionKeyId(this, inputStream2);
-// if (secretKeyId == Id.key.none) {
-// throw new PgpGeneralException(getString(R.string.error_no_secret_key_found));
-// }
-// } catch (NoAsymmetricEncryptionException e) {
-// if (inputStream2.markSupported()) {
-// inputStream2.reset();
-// }
-// secretKeyId = Id.key.symmetric;
-// if (!PgpDecryptVerify.hasSymmetricEncryption(this, inputStream2)) {
-// throw new PgpGeneralException(
-// getString(R.string.error_no_known_encryption_found));
-// }
-// // we do not support symmetric decryption from the API!
-// throw new Exception("Symmetric decryption is not supported!");
-// }
-//
-// Log.d(Constants.TAG, "secretKeyId " + secretKeyId);
-
- // NOTE: currently this only gets the passphrase for the key set for this client
- String passphrase;
- if (params.containsKey(OpenPgpConstants.PARAMS_PASSPHRASE)) {
- passphrase = params.getString(OpenPgpConstants.PARAMS_PASSPHRASE);
- } else {
- passphrase = PassphraseCacheService.getCachedPassphrase(getContext(), appSettings.getKeyId());
- }
- if (passphrase == null) {
- // get PendingIntent for passphrase input, add it to given params and return to client
- Bundle passphraseBundle = getPassphraseBundleIntent(params, appSettings.getKeyId());
- return passphraseBundle;
- }
-// }
+ Intent result = new Intent();
+ try {
- // build InputData and write into OutputStream
+ String passphrase = data.getStringExtra(OpenPgpApi.EXTRA_PASSPHRASE);
long inputLength = is.available();
InputData inputData = new InputData(is, inputLength);
-
- Bundle outputBundle;
PgpDecryptVerify.Builder builder = new PgpDecryptVerify.Builder(this, inputData, os);
-
-// if (signedOnly) {
-// outputBundle = builder.build().verifyText();
-// } else {
- builder.assumeSymmetric(false)
+ builder.assumeSymmetric(false) // no support for symmetric encryption
+ .enforcedKeyId(appSettings.getKeyId()) // allow only the private key for this app for decryption
.passphrase(passphrase);
- // Do we want to do this: instead of trying to get the passphrase before
- // pause stream when passphrase is missing and then resume???
-
- // TODO: this also decrypts with other secret keys without passphrase!!!
- outputBundle = builder.build().execute();
-// }
-
-// outputStream.close();
-
-// byte[] outputBytes = ((ByteArrayOutputStream) outputStream).toByteArray();
-
- // get signature informations from bundle
- boolean signature = outputBundle.getBoolean(KeychainIntentService.RESULT_SIGNATURE, false);
-
- if (signature) {
- long signatureKeyId = outputBundle
- .getLong(KeychainIntentService.RESULT_SIGNATURE_KEY_ID, 0);
- String signatureUserId = outputBundle
- .getString(KeychainIntentService.RESULT_SIGNATURE_USER_ID);
- boolean signatureSuccess = outputBundle
- .getBoolean(KeychainIntentService.RESULT_SIGNATURE_SUCCESS, false);
- boolean signatureUnknown = outputBundle
- .getBoolean(KeychainIntentService.RESULT_SIGNATURE_UNKNOWN, false);
- boolean signatureOnly = outputBundle
- .getBoolean(KeychainIntentService.RESULT_CLEARTEXT_SIGNATURE_ONLY, false);
-
- int signatureStatus = OpenPgpSignatureResult.SIGNATURE_ERROR;
- if (signatureSuccess) {
- signatureStatus = OpenPgpSignatureResult.SIGNATURE_SUCCESS_CERTIFIED;
- } else if (signatureUnknown) {
- signatureStatus = OpenPgpSignatureResult.SIGNATURE_UNKNOWN_PUB_KEY;
+ // TODO: currently does not support binary signed-only content
+ PgpDecryptVerifyResult decryptVerifyResult = builder.build().execute();
+
+ if (decryptVerifyResult.isKeyPassphraseNeeded()) {
+ // get PendingIntent for passphrase input, add it to given params and return to client
+ Intent passphraseBundle = getPassphraseBundleIntent(data, appSettings.getKeyId());
+ return passphraseBundle;
+ } else if (decryptVerifyResult.isSymmetricPassphraseNeeded()) {
+ throw new PgpGeneralException("Decryption of symmetric content not supported by API!");
+ }
+
+ OpenPgpSignatureResult signatureResult = decryptVerifyResult.getSignatureResult();
+ if (signatureResult != null) {
+ if (signatureResult.getStatus() == OpenPgpSignatureResult.SIGNATURE_UNKNOWN_PUB_KEY) {
+ // If signature is unknown we return an _additional_ PendingIntent
+ // to retrieve the missing key
+ // TODO!!!
+ Intent intent = new Intent(getBaseContext(), RemoteServiceActivity.class);
+ intent.setAction(RemoteServiceActivity.ACTION_ERROR_MESSAGE);
+ intent.putExtra(RemoteServiceActivity.EXTRA_ERROR_MESSAGE, "todo");
+ intent.putExtra(RemoteServiceActivity.EXTRA_DATA, data);
+
+ PendingIntent pi = PendingIntent.getActivity(getBaseContext(),
+ PRIVATE_REQUEST_CODE_GET_KEYS, intent, 0);
+
+ result.putExtra(OpenPgpApi.RESULT_INTENT, pi);
}
- sigResult = new OpenPgpSignatureResult(signatureStatus, signatureUserId,
- signatureOnly, signatureKeyId);
+ result.putExtra(OpenPgpApi.RESULT_SIGNATURE, signatureResult);
}
+
} finally {
is.close();
os.close();
}
- Bundle result = new Bundle();
- result.putInt(OpenPgpConstants.RESULT_CODE, OpenPgpConstants.RESULT_CODE_SUCCESS);
- result.putParcelable(OpenPgpConstants.RESULT_SIGNATURE, sigResult);
+ result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_SUCCESS);
return result;
} catch (Exception e) {
- Bundle result = new Bundle();
- result.putInt(OpenPgpConstants.RESULT_CODE, OpenPgpConstants.RESULT_CODE_ERROR);
- result.putParcelable(OpenPgpConstants.RESULT_ERRORS,
+ Intent result = new Intent();
+ result.putExtra(OpenPgpApi.RESULT_ERROR,
new OpenPgpError(OpenPgpError.GENERIC_ERROR, e.getMessage()));
+ result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_ERROR);
return result;
}
}
- private Bundle getKeyIdsImpl(Bundle params) {
+ private Intent getKeyImpl(Intent data) {
+ try {
+ long keyId = data.getLongExtra(OpenPgpApi.EXTRA_KEY_ID, 0);
+
+ if (ProviderHelper.getPGPPublicKeyByKeyId(this, keyId) == null) {
+ Intent result = new Intent();
+
+ // If keys are not in db we return an additional PendingIntent
+ // to retrieve the missing key
+ // TODO!!!
+ Intent intent = new Intent(getBaseContext(), RemoteServiceActivity.class);
+ intent.setAction(RemoteServiceActivity.ACTION_ERROR_MESSAGE);
+ intent.putExtra(RemoteServiceActivity.EXTRA_ERROR_MESSAGE, "todo");
+ intent.putExtra(RemoteServiceActivity.EXTRA_DATA, data);
+
+ PendingIntent pi = PendingIntent.getActivity(getBaseContext(),
+ PRIVATE_REQUEST_CODE_GET_KEYS, intent, 0);
+
+ result.putExtra(OpenPgpApi.RESULT_INTENT, pi);
+ result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_USER_INTERACTION_REQUIRED);
+ return result;
+ } else {
+ Intent result = new Intent();
+ result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_SUCCESS);
+ return result;
+ }
+ } catch (Exception e) {
+ Intent result = new Intent();
+ result.putExtra(OpenPgpApi.RESULT_ERROR,
+ new OpenPgpError(OpenPgpError.GENERIC_ERROR, e.getMessage()));
+ result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_ERROR);
+ return result;
+ }
+ }
+
+ private Intent getKeyIdsImpl(Intent data) {
// get key ids based on given user ids
- String[] userIds = params.getStringArray(OpenPgpConstants.PARAMS_USER_IDS);
- Bundle result = getKeyIdsFromEmails(params, userIds);
+ String[] userIds = data.getStringArrayExtra(OpenPgpApi.EXTRA_USER_IDS);
+ Intent result = getKeyIdsFromEmails(data, userIds);
return result;
}
@@ -459,30 +387,30 @@ public class OpenPgpService extends RemoteService {
* - has supported API version
* - is allowed to call the service (access has been granted)
*
- * @param params
+ * @param data
* @return null if everything is okay, or a Bundle with an error/PendingIntent
*/
- private Bundle checkRequirements(Bundle params) {
+ private Intent checkRequirements(Intent data) {
// params Bundle is required!
- if (params == null) {
- Bundle result = new Bundle();
+ if (data == null) {
+ Intent result = new Intent();
OpenPgpError error = new OpenPgpError(OpenPgpError.GENERIC_ERROR, "params Bundle required!");
- result.putParcelable(OpenPgpConstants.RESULT_ERRORS, error);
- result.putInt(OpenPgpConstants.RESULT_CODE, OpenPgpConstants.RESULT_CODE_ERROR);
+ result.putExtra(OpenPgpApi.RESULT_ERROR, error);
+ result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_ERROR);
return result;
}
// version code is required and needs to correspond to version code of service!
- if (params.getInt(OpenPgpConstants.PARAMS_API_VERSION) != OpenPgpConstants.API_VERSION) {
- Bundle result = new Bundle();
+ if (data.getIntExtra(OpenPgpApi.EXTRA_API_VERSION, -1) != OpenPgpApi.API_VERSION) {
+ Intent result = new Intent();
OpenPgpError error = new OpenPgpError(OpenPgpError.INCOMPATIBLE_API_VERSIONS, "Incompatible API versions!");
- result.putParcelable(OpenPgpConstants.RESULT_ERRORS, error);
- result.putInt(OpenPgpConstants.RESULT_CODE, OpenPgpConstants.RESULT_CODE_ERROR);
+ result.putExtra(OpenPgpApi.RESULT_ERROR, error);
+ result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_ERROR);
return result;
}
// check if caller is allowed to access openpgp keychain
- Bundle result = isAllowed(params);
+ Intent result = isAllowed(data);
if (result != null) {
return result;
}
@@ -494,61 +422,30 @@ public class OpenPgpService extends RemoteService {
private final IOpenPgpService.Stub mBinder = new IOpenPgpService.Stub() {
@Override
- public Bundle sign(Bundle params, final ParcelFileDescriptor input, final ParcelFileDescriptor output) {
- final AppSettings appSettings = getAppSettings();
-
- Bundle errorResult = checkRequirements(params);
+ public Intent execute(Intent data, ParcelFileDescriptor input, ParcelFileDescriptor output) {
+ Intent errorResult = checkRequirements(data);
if (errorResult != null) {
return errorResult;
}
- return signImpl(params, input, output, appSettings);
- }
-
- @Override
- public Bundle encrypt(Bundle params, ParcelFileDescriptor input, ParcelFileDescriptor output) {
final AppSettings appSettings = getAppSettings();
- Bundle errorResult = checkRequirements(params);
- if (errorResult != null) {
- return errorResult;
- }
-
- return encryptAndSignImpl(params, input, output, appSettings, false);
- }
-
- @Override
- public Bundle signAndEncrypt(Bundle params, ParcelFileDescriptor input, ParcelFileDescriptor output) {
- final AppSettings appSettings = getAppSettings();
-
- Bundle errorResult = checkRequirements(params);
- if (errorResult != null) {
- return errorResult;
- }
-
- return encryptAndSignImpl(params, input, output, appSettings, true);
- }
-
- @Override
- public Bundle decryptAndVerify(Bundle params, ParcelFileDescriptor input, ParcelFileDescriptor output) {
- final AppSettings appSettings = getAppSettings();
-
- Bundle errorResult = checkRequirements(params);
- if (errorResult != null) {
- return errorResult;
- }
-
- return decryptAndVerifyImpl(params, input, output, appSettings);
- }
-
- @Override
- public Bundle getKeyIds(Bundle params) {
- Bundle errorResult = checkRequirements(params);
- if (errorResult != null) {
- return errorResult;
+ String action = data.getAction();
+ if (OpenPgpApi.ACTION_SIGN.equals(action)) {
+ return signImpl(data, input, output, appSettings);
+ } else if (OpenPgpApi.ACTION_ENCRYPT.equals(action)) {
+ return encryptAndSignImpl(data, input, output, appSettings, false);
+ } else if (OpenPgpApi.ACTION_SIGN_AND_ENCRYPT.equals(action)) {
+ return encryptAndSignImpl(data, input, output, appSettings, true);
+ } else if (OpenPgpApi.ACTION_DECRYPT_VERIFY.equals(action)) {
+ return decryptAndVerifyImpl(data, input, output, appSettings);
+ } else if (OpenPgpApi.ACTION_GET_KEY.equals(action)) {
+ return getKeyImpl(data);
+ } else if (OpenPgpApi.ACTION_GET_KEY_IDS.equals(action)) {
+ return getKeyIdsImpl(data);
+ } else {
+ return null;
}
-
- return getKeyIdsImpl(params);
}
};
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/RemoteService.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/RemoteService.java
index cfd2b9ec3..cb556be39 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/RemoteService.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/RemoteService.java
@@ -21,7 +21,7 @@ import java.util.ArrayList;
import java.util.Arrays;
import org.openintents.openpgp.OpenPgpError;
-import org.openintents.openpgp.util.OpenPgpConstants;
+import org.openintents.openpgp.util.OpenPgpApi;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.provider.KeychainContract;
@@ -38,10 +38,6 @@ import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.Signature;
import android.net.Uri;
import android.os.Binder;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Message;
-import android.os.Messenger;
/**
* Abstract service class for remote APIs that handle app registration and user input.
@@ -57,7 +53,7 @@ public abstract class RemoteService extends Service {
return mContext;
}
- protected Bundle isAllowed(Bundle params) {
+ protected Intent isAllowed(Intent data) {
try {
if (isCallerAllowed(false)) {
@@ -74,9 +70,9 @@ public abstract class RemoteService extends Service {
} catch (NameNotFoundException e) {
Log.e(Constants.TAG, "Should not happen, returning!", e);
// return error
- Bundle result = new Bundle();
- result.putInt(OpenPgpConstants.RESULT_CODE, OpenPgpConstants.RESULT_CODE_ERROR);
- result.putParcelable(OpenPgpConstants.RESULT_ERRORS,
+ Intent result = new Intent();
+ result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_ERROR);
+ result.putExtra(OpenPgpApi.RESULT_ERROR,
new OpenPgpError(OpenPgpError.GENERIC_ERROR, e.getMessage()));
return result;
}
@@ -86,14 +82,14 @@ public abstract class RemoteService extends Service {
intent.setAction(RemoteServiceActivity.ACTION_REGISTER);
intent.putExtra(RemoteServiceActivity.EXTRA_PACKAGE_NAME, packageName);
intent.putExtra(RemoteServiceActivity.EXTRA_PACKAGE_SIGNATURE, packageSignature);
- intent.putExtra(OpenPgpConstants.PI_RESULT_PARAMS, params);
+ intent.putExtra(RemoteServiceActivity.EXTRA_DATA, data);
PendingIntent pi = PendingIntent.getActivity(getBaseContext(), PRIVATE_REQUEST_CODE_REGISTER, intent, 0);
// return PendingIntent to be executed by client
- Bundle result = new Bundle();
- result.putInt(OpenPgpConstants.RESULT_CODE, OpenPgpConstants.RESULT_CODE_USER_INTERACTION_REQUIRED);
- result.putParcelable(OpenPgpConstants.RESULT_INTENT, pi);
+ Intent result = new Intent();
+ result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_USER_INTERACTION_REQUIRED);
+ result.putExtra(OpenPgpApi.RESULT_INTENT, pi);
return result;
}
@@ -103,14 +99,14 @@ public abstract class RemoteService extends Service {
Intent intent = new Intent(getBaseContext(), RemoteServiceActivity.class);
intent.setAction(RemoteServiceActivity.ACTION_ERROR_MESSAGE);
intent.putExtra(RemoteServiceActivity.EXTRA_ERROR_MESSAGE, getString(R.string.api_error_wrong_signature));
- intent.putExtra(OpenPgpConstants.PI_RESULT_PARAMS, params);
+ intent.putExtra(RemoteServiceActivity.EXTRA_DATA, data);
PendingIntent pi = PendingIntent.getActivity(getBaseContext(), PRIVATE_REQUEST_CODE_ERROR, intent, 0);
// return PendingIntent to be executed by client
- Bundle result = new Bundle();
- result.putInt(OpenPgpConstants.RESULT_CODE, OpenPgpConstants.RESULT_CODE_USER_INTERACTION_REQUIRED);
- result.putParcelable(OpenPgpConstants.RESULT_INTENT, pi);
+ Intent result = new Intent();
+ result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_USER_INTERACTION_REQUIRED);
+ result.putExtra(OpenPgpApi.RESULT_INTENT, pi);
return result;
}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/RemoteServiceActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/RemoteServiceActivity.java
index af8e3ade8..11b3ee217 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/RemoteServiceActivity.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/RemoteServiceActivity.java
@@ -25,7 +25,7 @@ import android.os.Messenger;
import android.support.v7.app.ActionBarActivity;
import android.view.View;
-import org.openintents.openpgp.util.OpenPgpConstants;
+import org.openintents.openpgp.util.OpenPgpApi;
import org.sufficientlysecure.htmltextview.HtmlTextView;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.Id;
@@ -51,6 +51,8 @@ public class RemoteServiceActivity extends ActionBarActivity {
public static final String EXTRA_MESSENGER = "messenger";
+ public static final String EXTRA_DATA = "data";
+
// passphrase action
public static final String EXTRA_SECRET_KEY_ID = "secret_key_id";
// register action
@@ -100,12 +102,9 @@ public class RemoteServiceActivity extends ActionBarActivity {
ProviderHelper.insertApiApp(RemoteServiceActivity.this,
mSettingsFragment.getAppSettings());
- // give params through for new service call
- Bundle oldParams = extras.getBundle(OpenPgpConstants.PI_RESULT_PARAMS);
-
- Intent finishIntent = new Intent();
- finishIntent.putExtra(OpenPgpConstants.PI_RESULT_PARAMS, oldParams);
- RemoteServiceActivity.this.setResult(RESULT_OK, finishIntent);
+ // give data through for new service call
+ Intent resultData = extras.getParcelable(EXTRA_DATA);
+ RemoteServiceActivity.this.setResult(RESULT_OK, resultData);
RemoteServiceActivity.this.finish();
}
}
@@ -128,9 +127,9 @@ public class RemoteServiceActivity extends ActionBarActivity {
mSettingsFragment.setAppSettings(settings);
} else if (ACTION_CACHE_PASSPHRASE.equals(action)) {
long secretKeyId = extras.getLong(EXTRA_SECRET_KEY_ID);
- Bundle oldParams = extras.getBundle(OpenPgpConstants.PI_RESULT_PARAMS);
+ Intent resultData = extras.getParcelable(EXTRA_DATA);
- showPassphraseDialog(oldParams, secretKeyId);
+ showPassphraseDialog(resultData, secretKeyId);
} else if (ACTION_SELECT_PUB_KEYS.equals(action)) {
long[] selectedMasterKeyIds = intent.getLongArrayExtra(EXTRA_SELECTED_MASTER_KEY_IDS);
ArrayList<String> missingUserIds = intent
@@ -167,13 +166,11 @@ public class RemoteServiceActivity extends ActionBarActivity {
@Override
public void onClick(View v) {
// add key ids to params Bundle for new request
- Bundle params = extras.getBundle(OpenPgpConstants.PI_RESULT_PARAMS);
- params.putLongArray(OpenPgpConstants.PARAMS_KEY_IDS,
+ Intent resultData = extras.getParcelable(EXTRA_DATA);
+ resultData.putExtra(OpenPgpApi.EXTRA_KEY_IDS,
mSelectFragment.getSelectedMasterKeyIds());
- Intent finishIntent = new Intent();
- finishIntent.putExtra(OpenPgpConstants.PI_RESULT_PARAMS, params);
- RemoteServiceActivity.this.setResult(RESULT_OK, finishIntent);
+ RemoteServiceActivity.this.setResult(RESULT_OK, resultData);
RemoteServiceActivity.this.finish();
}
}, R.string.btn_do_not_save, new View.OnClickListener() {
@@ -222,7 +219,7 @@ public class RemoteServiceActivity extends ActionBarActivity {
@Override
public void onClick(View v) {
- RemoteServiceActivity.this.setResult(RESULT_OK);
+ RemoteServiceActivity.this.setResult(RESULT_CANCELED);
RemoteServiceActivity.this.finish();
}
});
@@ -244,16 +241,14 @@ public class RemoteServiceActivity extends ActionBarActivity {
* encryption. Based on mSecretKeyId it asks for a passphrase to open a private key or it asks
* for a symmetric passphrase
*/
- private void showPassphraseDialog(final Bundle params, long secretKeyId) {
+ private void showPassphraseDialog(final Intent data, long secretKeyId) {
// Message is received after passphrase is cached
Handler returnHandler = new Handler() {
@Override
public void handleMessage(Message message) {
if (message.what == PassphraseDialogFragment.MESSAGE_OKAY) {
// return given params again, for calling the service method again
- Intent finishIntent = new Intent();
- finishIntent.putExtra(OpenPgpConstants.PI_RESULT_PARAMS, params);
- RemoteServiceActivity.this.setResult(RESULT_OK, finishIntent);
+ RemoteServiceActivity.this.setResult(RESULT_OK, data);
} else {
RemoteServiceActivity.this.setResult(RESULT_CANCELED);
}
@@ -273,9 +268,7 @@ public class RemoteServiceActivity extends ActionBarActivity {
} catch (PgpGeneralException e) {
Log.d(Constants.TAG, "No passphrase for this secret key, do pgp operation directly!");
// return given params again, for calling the service method again
- Intent finishIntent = new Intent();
- finishIntent.putExtra(OpenPgpConstants.PI_RESULT_PARAMS, params);
- setResult(RESULT_OK, finishIntent);
+ setResult(RESULT_OK, data);
finish();
}
}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptActivity.java
index 652310cd2..42288ca37 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptActivity.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptActivity.java
@@ -25,6 +25,7 @@ import java.io.FileNotFoundException;
import java.io.InputStream;
import java.util.regex.Matcher;
+import org.openintents.openpgp.OpenPgpSignatureResult;
import org.spongycastle.openpgp.PGPPublicKeyRing;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.Id;
@@ -32,6 +33,7 @@ import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.compatibility.ClipboardReflection;
import org.sufficientlysecure.keychain.helper.ActionBarHelper;
import org.sufficientlysecure.keychain.helper.FileHelper;
+import org.sufficientlysecure.keychain.pgp.PgpDecryptVerifyResult;
import org.sufficientlysecure.keychain.pgp.PgpHelper;
import org.sufficientlysecure.keychain.pgp.PgpKeyHelper;
import org.sufficientlysecure.keychain.pgp.PgpDecryptVerify;
@@ -66,6 +68,7 @@ import android.widget.Toast;
import android.widget.ViewFlipper;
import com.beardedhen.androidbootstrap.BootstrapButton;
+import com.devspark.appmsg.AppMsg;
@SuppressLint("NewApi")
public class DecryptActivity extends DrawerActivity {
@@ -233,7 +236,7 @@ public class DecryptActivity extends DrawerActivity {
if (matcher.matches()) {
data = matcher.group(1);
mMessage.setText(data);
- Toast.makeText(this, R.string.using_clipboard_content, Toast.LENGTH_SHORT)
+ AppMsg.makeText(this, R.string.using_clipboard_content, AppMsg.STYLE_INFO)
.show();
}
}
@@ -420,17 +423,17 @@ public class DecryptActivity extends DrawerActivity {
}
if (mInputFilename.equals("")) {
- Toast.makeText(this, R.string.no_file_selected, Toast.LENGTH_SHORT).show();
+ AppMsg.makeText(this, R.string.no_file_selected, AppMsg.STYLE_ALERT).show();
return;
}
if (mInputFilename.startsWith("file")) {
File file = new File(mInputFilename);
if (!file.exists() || !file.isFile()) {
- Toast.makeText(
+ AppMsg.makeText(
this,
getString(R.string.error_message,
- getString(R.string.error_file_not_found)), Toast.LENGTH_SHORT)
+ getString(R.string.error_file_not_found)), AppMsg.STYLE_ALERT)
.show();
return;
}
@@ -510,14 +513,14 @@ public class DecryptActivity extends DrawerActivity {
inStream = getContentResolver().openInputStream(mContentUri);
} catch (FileNotFoundException e) {
Log.e(Constants.TAG, "File not found!", e);
- Toast.makeText(this, getString(R.string.error_file_not_found, e.getMessage()),
- Toast.LENGTH_SHORT).show();
+ AppMsg.makeText(this, getString(R.string.error_file_not_found, e.getMessage()),
+ AppMsg.STYLE_ALERT).show();
}
} else if (mDecryptTarget == Id.target.file) {
// check if storage is ready
if (!FileHelper.isStorageMounted(mInputFilename)) {
- Toast.makeText(this, getString(R.string.error_external_storage_not_ready),
- Toast.LENGTH_SHORT).show();
+ AppMsg.makeText(this, getString(R.string.error_external_storage_not_ready),
+ AppMsg.STYLE_ALERT).show();
return;
}
@@ -525,8 +528,8 @@ public class DecryptActivity extends DrawerActivity {
inStream = new BufferedInputStream(new FileInputStream(mInputFilename));
} catch (FileNotFoundException e) {
Log.e(Constants.TAG, "File not found!", e);
- Toast.makeText(this, getString(R.string.error_file_not_found, e.getMessage()),
- Toast.LENGTH_SHORT).show();
+ AppMsg.makeText(this, getString(R.string.error_file_not_found, e.getMessage()),
+ AppMsg.STYLE_ALERT).show();
}
} else {
inStream = new ByteArrayInputStream(mMessage.getText().toString().getBytes());
@@ -556,8 +559,8 @@ public class DecryptActivity extends DrawerActivity {
mAssumeSymmetricEncryption = true;
}
} catch (Exception e) {
- Toast.makeText(this, getString(R.string.error_message, e.getMessage()),
- Toast.LENGTH_SHORT).show();
+ AppMsg.makeText(this, getString(R.string.error_message, e.getMessage()),
+ AppMsg.STYLE_ALERT).show();
}
}
@@ -655,8 +658,8 @@ public class DecryptActivity extends DrawerActivity {
mSignatureKeyId = 0;
mSignatureLayout.setVisibility(View.GONE);
- Toast.makeText(DecryptActivity.this, R.string.decryption_successful,
- Toast.LENGTH_SHORT).show();
+ AppMsg.makeText(DecryptActivity.this, R.string.decryption_successful,
+ AppMsg.STYLE_INFO).show();
if (mReturnResult) {
Intent intent = new Intent();
intent.putExtras(returnData);
@@ -689,11 +692,15 @@ public class DecryptActivity extends DrawerActivity {
}
- if (returnData.getBoolean(KeychainIntentService.RESULT_SIGNATURE)) {
- String userId = returnData
- .getString(KeychainIntentService.RESULT_SIGNATURE_USER_ID);
- mSignatureKeyId = returnData
- .getLong(KeychainIntentService.RESULT_SIGNATURE_KEY_ID);
+ PgpDecryptVerifyResult decryptVerifyResult =
+ returnData.getParcelable(KeychainIntentService.RESULT_DECRYPT_VERIFY_RESULT);
+
+ OpenPgpSignatureResult signatureResult = decryptVerifyResult.getSignatureResult();
+
+ if (signatureResult != null) {
+
+ String userId = signatureResult.getUserId();
+ mSignatureKeyId = signatureResult.getKeyId();
mUserIdRest.setText("id: "
+ PgpKeyHelper.convertKeyIdToHex(mSignatureKeyId));
if (userId == null) {
@@ -706,19 +713,32 @@ public class DecryptActivity extends DrawerActivity {
}
mUserId.setText(userId);
- if (returnData.getBoolean(KeychainIntentService.RESULT_SIGNATURE_SUCCESS)) {
- mSignatureStatusImage.setImageResource(R.drawable.overlay_ok);
- mLookupKey.setVisibility(View.GONE);
- } else if (returnData
- .getBoolean(KeychainIntentService.RESULT_SIGNATURE_UNKNOWN)) {
- mSignatureStatusImage.setImageResource(R.drawable.overlay_error);
- mLookupKey.setVisibility(View.VISIBLE);
- Toast.makeText(DecryptActivity.this,
- R.string.unknown_signature,
- Toast.LENGTH_LONG).show();
- } else {
- mSignatureStatusImage.setImageResource(R.drawable.overlay_error);
- mLookupKey.setVisibility(View.GONE);
+ switch (signatureResult.getStatus()) {
+ case OpenPgpSignatureResult.SIGNATURE_SUCCESS_UNCERTIFIED: {
+ mSignatureStatusImage.setImageResource(R.drawable.overlay_ok);
+ mLookupKey.setVisibility(View.GONE);
+ break;
+ }
+
+ // TODO!
+// case OpenPgpSignatureResult.SIGNATURE_SUCCESS_CERTIFIED: {
+// break;
+// }
+
+ case OpenPgpSignatureResult.SIGNATURE_UNKNOWN_PUB_KEY: {
+ mSignatureStatusImage.setImageResource(R.drawable.overlay_error);
+ mLookupKey.setVisibility(View.VISIBLE);
+ AppMsg.makeText(DecryptActivity.this,
+ R.string.unknown_signature,
+ AppMsg.STYLE_ALERT).show();
+ break;
+ }
+
+ default: {
+ mSignatureStatusImage.setImageResource(R.drawable.overlay_error);
+ mLookupKey.setVisibility(View.GONE);
+ break;
+ }
}
mSignatureLayout.setVisibility(View.VISIBLE);
}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DrawerActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DrawerActivity.java
index 53a57c4cd..08ca262c3 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DrawerActivity.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DrawerActivity.java
@@ -19,6 +19,7 @@ package org.sufficientlysecure.keychain.ui;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.service.remote.RegisteredAppsListActivity;
+import org.sufficientlysecure.keychain.util.Log;
import android.app.Activity;
import android.content.Context;
@@ -52,6 +53,7 @@ public class DrawerActivity extends ActionBarActivity {
private static Class[] mItemsClass = new Class[] { KeyListPublicActivity.class,
EncryptActivity.class, DecryptActivity.class, ImportKeysActivity.class,
KeyListSecretActivity.class, RegisteredAppsListActivity.class };
+ private Class mSelectedItem;
private static final int MENU_ID_PREFERENCE = 222;
private static final int MENU_ID_HELP = 223;
@@ -94,6 +96,17 @@ public class DrawerActivity extends ActionBarActivity {
getSupportActionBar().setTitle(mTitle);
// creates call to onPrepareOptionsMenu()
supportInvalidateOptionsMenu();
+
+ // call intent activity if selected
+ if(mSelectedItem != null) {
+ finish();
+ overridePendingTransition(0, 0);
+
+ Intent intent = new Intent(DrawerActivity.this, mSelectedItem);
+ startActivity(intent);
+ // disable animation of activity start
+ overridePendingTransition(0, 0);
+ }
}
public void onDrawerOpened(View drawerView) {
@@ -182,14 +195,8 @@ public class DrawerActivity extends ActionBarActivity {
mDrawerList.setItemChecked(position, true);
// setTitle(mDrawerTitles[position]);
mDrawerLayout.closeDrawer(mDrawerList);
-
- finish();
- overridePendingTransition(0, 0);
-
- Intent intent = new Intent(this, mItemsClass[position]);
- startActivity(intent);
- // disable animation of activity start
- overridePendingTransition(0, 0);
+ // set selected class
+ mSelectedItem = mItemsClass[position];
}
/**
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java
index 6ce2a8f6b..716140655 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java
@@ -49,6 +49,7 @@ import org.sufficientlysecure.keychain.util.IterableIterator;
import org.sufficientlysecure.keychain.util.Log;
import android.app.AlertDialog;
+import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
@@ -97,7 +98,7 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener
private SectionView mUserIdsView;
private SectionView mKeysView;
- private String mCurrentPassPhrase = null;
+ private String mCurrentPassphrase = null;
private String mNewPassPhrase = null;
private String mSavedNewPassPhrase = null;
private boolean mIsPassPhraseSet;
@@ -105,7 +106,7 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener
private boolean mIsBrandNewKeyring = false;
private MenuItem mSaveButton;
- private BootstrapButton mChangePassPhrase;
+ private BootstrapButton mChangePassphrase;
private CheckBox mNoPassphrase;
@@ -174,7 +175,7 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener
private void handleActionCreateKey(Intent intent) {
Bundle extras = intent.getExtras();
- mCurrentPassPhrase = "";
+ mCurrentPassphrase = "";
mIsBrandNewKeyring = true;
if (extras != null) {
@@ -190,7 +191,7 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener
if (noPassphrase) {
// check "no passphrase" checkbox and remove button
mNoPassphrase.setChecked(true);
- mChangePassPhrase.setVisibility(View.GONE);
+ mChangePassphrase.setVisibility(View.GONE);
}
}
@@ -200,19 +201,31 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener
if (generateDefaultKeys) {
// Send all information needed to service generate keys in other thread
- Intent serviceIntent = new Intent(this, KeychainIntentService.class);
+ final Intent serviceIntent = new Intent(this, KeychainIntentService.class);
serviceIntent.setAction(KeychainIntentService.ACTION_GENERATE_DEFAULT_RSA_KEYS);
// fill values for this action
Bundle data = new Bundle();
data.putString(KeychainIntentService.GENERATE_KEY_SYMMETRIC_PASSPHRASE,
- mCurrentPassPhrase);
+ mCurrentPassphrase);
serviceIntent.putExtra(KeychainIntentService.EXTRA_DATA, data);
// Message is received after generating is done in ApgService
KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler(
- this, R.string.progress_generating, ProgressDialog.STYLE_SPINNER) {
+ this, R.string.progress_generating, ProgressDialog.STYLE_SPINNER, true,
+
+ new DialogInterface.OnCancelListener() {
+ @Override
+ public void onCancel(DialogInterface dialog) {
+ // Stop key generation on cancel
+ stopService(serviceIntent);
+ EditKeyActivity.this.setResult(Activity.RESULT_CANCELED);
+ EditKeyActivity.this.finish();
+ }
+ }) {
+
+ @Override
public void handleMessage(Message message) {
// handle messages by standard ApgHandler first
super.handleMessage(message);
@@ -286,7 +299,7 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener
@Override
public void handleMessage(Message message) {
if (message.what == PassphraseDialogFragment.MESSAGE_OKAY) {
- mCurrentPassPhrase = PassphraseCacheService.getCachedPassphrase(
+ mCurrentPassphrase = PassphraseCacheService.getCachedPassphrase(
EditKeyActivity.this, masterKeyId);
finallySaveClicked();
}
@@ -393,14 +406,14 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener
}
}
- mCurrentPassPhrase = "";
+ mCurrentPassphrase = "";
buildLayout(false);
mIsPassPhraseSet = PassphraseCacheService.hasPassphrase(this, masterKeyId);
if (!mIsPassPhraseSet) {
// check "no passphrase" checkbox and remove button
mNoPassphrase.setChecked(true);
- mChangePassPhrase.setVisibility(View.GONE);
+ mChangePassphrase.setVisibility(View.GONE);
}
}
@@ -431,7 +444,7 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener
// set title based on isPassphraseSet()
int title;
if (isPassphraseSet()) {
- title = R.string.title_change_pass_phrase;
+ title = R.string.title_change_passphrase;
} else {
title = R.string.title_set_passphrase;
}
@@ -451,7 +464,7 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener
setContentView(R.layout.edit_key_activity);
// find views
- mChangePassPhrase = (BootstrapButton) findViewById(R.id.edit_key_btn_change_pass_phrase);
+ mChangePassphrase = (BootstrapButton) findViewById(R.id.edit_key_btn_change_passphrase);
mNoPassphrase = (CheckBox) findViewById(R.id.edit_key_no_passphrase);
// Build layout based on given userIds and keys
@@ -473,7 +486,7 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener
updatePassPhraseButtonText();
- mChangePassPhrase.setOnClickListener(new OnClickListener() {
+ mChangePassphrase.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
showSetPassphraseDialog();
}
@@ -488,10 +501,10 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener
// remove passphrase
mSavedNewPassPhrase = mNewPassPhrase;
mNewPassPhrase = "";
- mChangePassPhrase.setVisibility(View.GONE);
+ mChangePassphrase.setVisibility(View.GONE);
} else {
mNewPassPhrase = mSavedNewPassPhrase;
- mChangePassPhrase.setVisibility(View.VISIBLE);
+ mChangePassphrase.setVisibility(View.VISIBLE);
}
somethingChanged();
}
@@ -545,7 +558,7 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener
if (passphrase == null) {
showPassphraseDialog(masterKeyId);
} else {
- mCurrentPassPhrase = passphrase;
+ mCurrentPassphrase = passphrase;
finallySaveClicked();
}
} catch (PgpGeneralException e) {
@@ -581,13 +594,14 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener
saveParams.keysExpiryDates = getKeysExpiryDates(mKeysView);
saveParams.keysUsages = getKeysUsages(mKeysView);
saveParams.newPassPhrase = mNewPassPhrase;
- saveParams.oldPassPhrase = mCurrentPassPhrase;
+ saveParams.oldPassPhrase = mCurrentPassphrase;
saveParams.newKeys = toPrimitiveArray(mKeysView.getNewKeysArray());
saveParams.keys = getKeys(mKeysView);
// fill values for this action
Bundle data = new Bundle();
+
data.putBoolean(KeychainIntentService.SAVE_KEYRING_CAN_SIGN, masterCanSign);
data.putParcelable(KeychainIntentService.SAVE_KEYRING_PARCEL, saveParams);
@@ -766,7 +780,7 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener
}
private void updatePassPhraseButtonText() {
- mChangePassPhrase.setText(isPassphraseSet() ? getString(R.string.btn_change_passphrase)
+ mChangePassphrase.setText(isPassphraseSet() ? getString(R.string.btn_change_passphrase)
: getString(R.string.btn_set_passphrase));
}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivity.java
index 85bfba224..faac9b157 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivity.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivity.java
@@ -63,6 +63,7 @@ import android.widget.Toast;
import android.widget.ViewFlipper;
import com.beardedhen.androidbootstrap.BootstrapButton;
+import com.devspark.appmsg.AppMsg;
public class EncryptActivity extends DrawerActivity {
@@ -100,8 +101,8 @@ public class EncryptActivity extends DrawerActivity {
private int mEncryptTarget;
- private EditText mPassPhrase = null;
- private EditText mPassPhraseAgain = null;
+ private EditText mPassphrase = null;
+ private EditText mPassphraseAgain = null;
private CheckBox mAsciiArmor = null;
private Spinner mFileCompression = null;
@@ -415,17 +416,17 @@ public class EncryptActivity extends DrawerActivity {
mOutputFilename = guessOutputFilename(mInputFilename);
if (mInputFilename.equals("")) {
- Toast.makeText(this, R.string.no_file_selected, Toast.LENGTH_SHORT).show();
+ AppMsg.makeText(this, R.string.no_file_selected, AppMsg.STYLE_ALERT).show();
return;
}
if (!mInputFilename.startsWith("content")) {
File file = new File(mInputFilename);
if (!file.exists() || !file.isFile()) {
- Toast.makeText(
+ AppMsg.makeText(
this,
getString(R.string.error_message,
- getString(R.string.error_file_not_found)), Toast.LENGTH_SHORT)
+ getString(R.string.error_file_not_found)), AppMsg.STYLE_ALERT)
.show();
return;
}
@@ -435,16 +436,16 @@ public class EncryptActivity extends DrawerActivity {
// symmetric encryption
if (mMode.getCurrentView().getId() == R.id.modeSymmetric) {
boolean gotPassPhrase = false;
- String passPhrase = mPassPhrase.getText().toString();
- String passPhraseAgain = mPassPhraseAgain.getText().toString();
- if (!passPhrase.equals(passPhraseAgain)) {
- Toast.makeText(this, R.string.passphrases_do_not_match, Toast.LENGTH_SHORT).show();
+ String passphrase = mPassphrase.getText().toString();
+ String passphraseAgain = mPassphraseAgain.getText().toString();
+ if (!passphrase.equals(passphraseAgain)) {
+ AppMsg.makeText(this, R.string.passphrases_do_not_match, AppMsg.STYLE_ALERT).show();
return;
}
- gotPassPhrase = (passPhrase.length() != 0);
+ gotPassPhrase = (passphrase.length() != 0);
if (!gotPassPhrase) {
- Toast.makeText(this, R.string.passphrase_must_not_be_empty, Toast.LENGTH_SHORT)
+ AppMsg.makeText(this, R.string.passphrase_must_not_be_empty, AppMsg.STYLE_ALERT)
.show();
return;
}
@@ -452,13 +453,13 @@ public class EncryptActivity extends DrawerActivity {
boolean encryptIt = (mEncryptionKeyIds != null && mEncryptionKeyIds.length > 0);
// for now require at least one form of encryption for files
if (!encryptIt && mEncryptTarget == Id.target.file) {
- Toast.makeText(this, R.string.select_encryption_key, Toast.LENGTH_SHORT).show();
+ AppMsg.makeText(this, R.string.select_encryption_key, AppMsg.STYLE_ALERT).show();
return;
}
if (!encryptIt && mSecretKeyId == 0) {
- Toast.makeText(this, R.string.select_encryption_or_signature_key,
- Toast.LENGTH_SHORT).show();
+ AppMsg.makeText(this, R.string.select_encryption_or_signature_key,
+ AppMsg.STYLE_ALERT).show();
return;
}
@@ -549,11 +550,11 @@ public class EncryptActivity extends DrawerActivity {
if (mMode.getCurrentView().getId() == R.id.modeSymmetric) {
Log.d(Constants.TAG, "Symmetric encryption enabled!");
- String passPhrase = mPassPhrase.getText().toString();
- if (passPhrase.length() == 0) {
- passPhrase = null;
+ String passphrase = mPassphrase.getText().toString();
+ if (passphrase.length() == 0) {
+ passphrase = null;
}
- data.putString(KeychainIntentService.GENERATE_KEY_SYMMETRIC_PASSPHRASE, passPhrase);
+ data.putString(KeychainIntentService.GENERATE_KEY_SYMMETRIC_PASSPHRASE, passphrase);
} else {
mSecretKeyIdToPass = mSecretKeyId;
encryptionKeyIds = mEncryptionKeyIds;
@@ -618,8 +619,8 @@ public class EncryptActivity extends DrawerActivity {
output = data.getString(KeychainIntentService.RESULT_ENCRYPTED_STRING);
Log.d(Constants.TAG, "output: " + output);
ClipboardReflection.copyToClipboard(EncryptActivity.this, output);
- Toast.makeText(EncryptActivity.this,
- R.string.encryption_to_clipboard_successful, Toast.LENGTH_SHORT)
+ AppMsg.makeText(EncryptActivity.this,
+ R.string.encryption_to_clipboard_successful, AppMsg.STYLE_INFO)
.show();
break;
@@ -640,8 +641,8 @@ public class EncryptActivity extends DrawerActivity {
break;
case Id.target.file:
- Toast.makeText(EncryptActivity.this, R.string.encryption_successful,
- Toast.LENGTH_SHORT).show();
+ AppMsg.makeText(EncryptActivity.this, R.string.encryption_successful,
+ AppMsg.STYLE_INFO).show();
if (mDeleteAfter.isChecked()) {
// Create and show dialog to delete original file
@@ -765,8 +766,8 @@ public class EncryptActivity extends DrawerActivity {
mMainUserId = (TextView) findViewById(R.id.mainUserId);
mMainUserIdRest = (TextView) findViewById(R.id.mainUserIdRest);
- mPassPhrase = (EditText) findViewById(R.id.passPhrase);
- mPassPhraseAgain = (EditText) findViewById(R.id.passPhraseAgain);
+ mPassphrase = (EditText) findViewById(R.id.passphrase);
+ mPassphraseAgain = (EditText) findViewById(R.id.passphraseAgain);
// measure the height of the source_file view and set the message view's min height to that,
// so it fills mSource fully... bit of a hack.
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java
index a5027ac1c..5ac421a44 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java
@@ -17,22 +17,9 @@
package org.sufficientlysecure.keychain.ui;
-import java.util.ArrayList;
-import java.util.Locale;
-
-import org.sufficientlysecure.keychain.Constants;
-import org.sufficientlysecure.keychain.R;
-import org.sufficientlysecure.keychain.pgp.PgpKeyHelper;
-import org.sufficientlysecure.keychain.service.KeychainIntentService;
-import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler;
-import org.sufficientlysecure.keychain.ui.adapter.ImportKeysListEntry;
-import org.sufficientlysecure.keychain.util.Log;
-
import android.annotation.SuppressLint;
-import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.Context;
-import android.content.DialogInterface;
import android.content.Intent;
import android.net.Uri;
import android.nfc.NdefMessage;
@@ -51,6 +38,18 @@ import android.widget.ArrayAdapter;
import com.beardedhen.androidbootstrap.BootstrapButton;
import com.devspark.appmsg.AppMsg;
+import org.sufficientlysecure.keychain.Constants;
+import org.sufficientlysecure.keychain.R;
+import org.sufficientlysecure.keychain.pgp.PgpKeyHelper;
+import org.sufficientlysecure.keychain.service.KeychainIntentService;
+import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler;
+import org.sufficientlysecure.keychain.ui.adapter.ImportKeysListEntry;
+import org.sufficientlysecure.keychain.ui.dialog.BadImportKeyDialogFragment;
+import org.sufficientlysecure.keychain.util.Log;
+
+import java.util.ArrayList;
+import java.util.Locale;
+
public class ImportKeysActivity extends DrawerActivity implements ActionBar.OnNavigationListener {
public static final String ACTION_IMPORT_KEY = Constants.INTENT_PREFIX + "IMPORT_KEY";
public static final String ACTION_IMPORT_KEY_FROM_QR_CODE = Constants.INTENT_PREFIX
@@ -236,10 +235,10 @@ public class ImportKeysActivity extends DrawerActivity implements ActionBar.OnNa
* inside your Activity."
* <p/>
* from http://stackoverflow.com/questions/10983396/fragment-oncreateview-and-onactivitycreated-called-twice/14295474#14295474
- *
+ * <p/>
* In our case, if we start ImportKeysActivity with parameters to directly search using a fingerprint,
* the fragment would be loaded twice resulting in the query being empty after the second load.
- *
+ * <p/>
* Our solution:
* To prevent that a fragment will be loaded again even if it was already loaded loadNavFragment
* checks against mCurrentNavPostition.
@@ -395,23 +394,8 @@ public class ImportKeysActivity extends DrawerActivity implements ActionBar.OnNa
AppMsg.makeText(ImportKeysActivity.this, toastMessage, AppMsg.STYLE_INFO)
.show();
if (bad > 0) {
- AlertDialog.Builder alert = new AlertDialog.Builder(
- ImportKeysActivity.this);
-
- alert.setIcon(android.R.drawable.ic_dialog_alert);
- alert.setTitle(R.string.warning);
-
- alert.setMessage(ImportKeysActivity.this.getResources()
- .getQuantityString(R.plurals.bad_keys_encountered, bad, bad));
-
- alert.setPositiveButton(android.R.string.ok,
- new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface dialog, int id) {
- dialog.cancel();
- }
- });
- alert.setCancelable(true);
- alert.create().show();
+ BadImportKeyDialogFragment badImportKeyDialogFragment = BadImportKeyDialogFragment.newInstance(bad);
+ badImportKeyDialogFragment.show(getSupportFragmentManager(), "badKeyDialog");
}
}
}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysListFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysListFragment.java
index b52de5bc9..1118f0264 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysListFragment.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysListFragment.java
@@ -27,11 +27,13 @@ import java.util.List;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.helper.Preferences;
+import org.sufficientlysecure.keychain.ui.adapter.AsyncTaskResultWrapper;
import org.sufficientlysecure.keychain.ui.adapter.ImportKeysAdapter;
import org.sufficientlysecure.keychain.ui.adapter.ImportKeysListEntry;
import org.sufficientlysecure.keychain.ui.adapter.ImportKeysListLoader;
import org.sufficientlysecure.keychain.ui.adapter.ImportKeysListServerLoader;
import org.sufficientlysecure.keychain.util.InputData;
+import org.sufficientlysecure.keychain.util.KeyServer;
import org.sufficientlysecure.keychain.util.Log;
import android.app.Activity;
@@ -42,10 +44,11 @@ import android.support.v4.app.LoaderManager;
import android.support.v4.content.Loader;
import android.view.View;
import android.widget.ListView;
-import android.widget.Toast;
+
+import com.devspark.appmsg.AppMsg;
public class ImportKeysListFragment extends ListFragment implements
- LoaderManager.LoaderCallbacks<List<ImportKeysListEntry>> {
+ LoaderManager.LoaderCallbacks<AsyncTaskResultWrapper<ArrayList<ImportKeysListEntry>>> {
private static final String ARG_DATA_URI = "uri";
private static final String ARG_BYTES = "bytes";
private static final String ARG_SERVER_QUERY = "query";
@@ -181,11 +184,10 @@ public class ImportKeysListFragment extends ListFragment implements
}
@Override
- public Loader<List<ImportKeysListEntry>> onCreateLoader(int id, Bundle args) {
+ public Loader<AsyncTaskResultWrapper<ArrayList<ImportKeysListEntry>>> onCreateLoader(int id, Bundle args) {
switch (id) {
case LOADER_ID_BYTES: {
InputData inputData = getInputData(mKeyBytes, mDataUri);
-
return new ImportKeysListLoader(mActivity, inputData);
}
case LOADER_ID_SERVER_QUERY: {
@@ -198,15 +200,15 @@ public class ImportKeysListFragment extends ListFragment implements
}
@Override
- public void onLoadFinished(Loader<List<ImportKeysListEntry>> loader,
- List<ImportKeysListEntry> data) {
+ public void onLoadFinished(Loader<AsyncTaskResultWrapper<ArrayList<ImportKeysListEntry>>> loader,
+ AsyncTaskResultWrapper<ArrayList<ImportKeysListEntry>> data) {
// Swap the new cursor in. (The framework will take care of closing the
// old cursor once we return.)
- Log.d(Constants.TAG, "data: " + data);
+ Log.d(Constants.TAG, "data: " + data.getResult());
// swap in the real data!
- mAdapter.setData(data);
+ mAdapter.setData(data.getResult());
mAdapter.notifyDataSetChanged();
setListAdapter(mAdapter);
@@ -222,11 +224,25 @@ public class ImportKeysListFragment extends ListFragment implements
break;
case LOADER_ID_SERVER_QUERY:
- Toast.makeText(
- getActivity(), getResources().getQuantityString(R.plurals.keys_found,
- mAdapter.getCount(), mAdapter.getCount()),
- Toast.LENGTH_SHORT
- ).show();
+
+ Exception error = data.getError();
+
+ if(error == null){
+ AppMsg.makeText(
+ getActivity(), getResources().getQuantityString(R.plurals.keys_found,
+ mAdapter.getCount(), mAdapter.getCount()),
+ AppMsg.STYLE_INFO
+ ).show();
+ } else if(error instanceof KeyServer.InsufficientQuery){
+ AppMsg.makeText(getActivity(), R.string.error_keyserver_insufficient_query,
+ AppMsg.STYLE_ALERT).show();
+ }else if(error instanceof KeyServer.QueryException){
+ AppMsg.makeText(getActivity(), R.string.error_keyserver_query,
+ AppMsg.STYLE_ALERT).show();
+ }else if(error instanceof KeyServer.TooManyResponses){
+ AppMsg.makeText(getActivity(), R.string.error_keyserver_too_many_responses,
+ AppMsg.STYLE_ALERT).show();
+ }
break;
default:
@@ -235,7 +251,7 @@ public class ImportKeysListFragment extends ListFragment implements
}
@Override
- public void onLoaderReset(Loader<List<ImportKeysListEntry>> loader) {
+ public void onLoaderReset(Loader<AsyncTaskResultWrapper<ArrayList<ImportKeysListEntry>>> loader) {
switch (loader.getId()) {
case LOADER_ID_BYTES:
// Clear the data in the adapter.
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListPublicFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListPublicFragment.java
index c28d57627..f2cb8a265 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListPublicFragment.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListPublicFragment.java
@@ -33,6 +33,7 @@ import se.emilsjolander.stickylistheaders.ApiLevelTooLowException;
import se.emilsjolander.stickylistheaders.StickyListHeadersListView;
import android.annotation.SuppressLint;
+import android.annotation.TargetApi;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
@@ -45,9 +46,13 @@ import android.support.v4.app.Fragment;
import android.support.v4.app.LoaderManager;
import android.support.v4.content.CursorLoader;
import android.support.v4.content.Loader;
+import android.support.v4.view.MenuItemCompat;
+import android.support.v7.widget.SearchView;
+import android.text.TextUtils;
import android.view.ActionMode;
import android.view.LayoutInflater;
import android.view.Menu;
+import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
@@ -63,23 +68,25 @@ import com.beardedhen.androidbootstrap.BootstrapButton;
* Public key list with sticky list headers. It does _not_ extend ListFragment because it uses
* StickyListHeaders library which does not extend upon ListView.
*/
-public class KeyListPublicFragment extends Fragment implements AdapterView.OnItemClickListener,
+public class KeyListPublicFragment extends Fragment implements SearchView.OnQueryTextListener, AdapterView.OnItemClickListener,
LoaderManager.LoaderCallbacks<Cursor> {
private KeyListPublicAdapter mAdapter;
private StickyListHeadersListView mStickyList;
-
+ private String mCurQuery;
+ private SearchView mSearchView;
// empty list layout
private BootstrapButton mButtonEmptyCreate;
private BootstrapButton mButtonEmptyImport;
+
/**
* Load custom layout with StickyListView from library
*/
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.key_list_public_fragment, container, false);
-
+ setHasOptionsMenu(true);
mButtonEmptyCreate = (BootstrapButton) view.findViewById(R.id.key_list_empty_button_create);
mButtonEmptyCreate.setOnClickListener(new OnClickListener() {
@@ -137,8 +144,6 @@ public class KeyListPublicFragment extends Fragment implements AdapterView.OnIte
mStickyList.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
mStickyList.getWrappedList().setMultiChoiceModeListener(new MultiChoiceModeListener() {
- private int count = 0;
-
@Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
android.view.MenuInflater inflater = getActivity().getMenuInflater();
@@ -172,13 +177,20 @@ public class KeyListPublicFragment extends Fragment implements AdapterView.OnIte
showDeleteKeyDialog(mode, ids);
break;
}
+ case R.id.menu_key_list_public_multi_select_all: {
+ //Select all
+ int localCount = mStickyList.getCount();
+ for(int k = 0; k < localCount; k++) {
+ mStickyList.setItemChecked(k, true);
+ }
+ break;
+ }
}
return true;
}
@Override
public void onDestroyActionMode(ActionMode mode) {
- count = 0;
mAdapter.clearSelection();
}
@@ -186,13 +198,11 @@ public class KeyListPublicFragment extends Fragment implements AdapterView.OnIte
public void onItemCheckedStateChanged(ActionMode mode, int position, long id,
boolean checked) {
if (checked) {
- count++;
mAdapter.setNewSelection(position, checked);
} else {
- count--;
mAdapter.removeSelection(position);
}
-
+ int count = mAdapter.getCurrentCheckedPosition().size();
String keysSelected = getResources().getQuantityString(
R.plurals.key_list_selected_keys, count, count);
mode.setTitle(keysSelected);
@@ -231,10 +241,15 @@ public class KeyListPublicFragment extends Fragment implements AdapterView.OnIte
// This is called when a new Loader needs to be created. This
// sample only has one Loader, so we don't care about the ID.
Uri baseUri = KeyRings.buildPublicKeyRingsUri();
-
+ String where = null;
+ String whereArgs[] = null;
+ if(mCurQuery != null){
+ where = KeychainContract.UserIds.USER_ID + " LIKE ?";
+ whereArgs = new String[]{mCurQuery+"%"};
+ }
// Now create and return a CursorLoader that will take care of
// creating a Cursor for the data being displayed.
- return new CursorLoader(getActivity(), baseUri, PROJECTION, null, null, SORT_ORDER);
+ return new CursorLoader(getActivity(), baseUri, PROJECTION, where, whereArgs, SORT_ORDER);
}
@Override
@@ -276,7 +291,8 @@ public class KeyListPublicFragment extends Fragment implements AdapterView.OnIte
viewIntent.setData(KeychainContract.KeyRings.buildPublicKeyRingsUri(Long.toString(id)));
startActivity(viewIntent);
}
-
+
+ @TargetApi(11)
public void encrypt(ActionMode mode, long[] keyRingRowIds) {
// get master key ids from row ids
long[] keyRingIds = new long[keyRingRowIds.length];
@@ -298,6 +314,7 @@ public class KeyListPublicFragment extends Fragment implements AdapterView.OnIte
*
* @param keyRingRowIds
*/
+ @TargetApi(11)
public void showDeleteKeyDialog(final ActionMode mode, long[] keyRingRowIds) {
// Message is received after key is deleted
Handler returnHandler = new Handler() {
@@ -332,4 +349,34 @@ public class KeyListPublicFragment extends Fragment implements AdapterView.OnIte
deleteKeyDialog.show(getActivity().getSupportFragmentManager(), "deleteKeyDialog");
}
-} \ No newline at end of file
+
+ @Override
+ public void onCreateOptionsMenu(final Menu menu, final MenuInflater inflater) {
+
+ // Get the searchview
+ MenuItem searchItem = menu.findItem(R.id.menu_key_list_public_search);
+ mSearchView = (SearchView) MenuItemCompat.getActionView(searchItem);
+
+ // Execute this when searching
+ mSearchView.setOnQueryTextListener(this);
+
+ super.onCreateOptionsMenu(menu, inflater);
+
+ }
+
+ @Override
+ public boolean onQueryTextSubmit(String s) {
+ return true;
+ }
+
+ @Override
+ public boolean onQueryTextChange(String s) {
+ // Called when the action bar search text has changed. Update
+ // the search filter, and restart the loader to do a new query
+ // with this filter.
+ String newQuery = !TextUtils.isEmpty(s) ? s : null;
+ mCurQuery = newQuery;
+ getLoaderManager().restartLoader(0, null, this);
+ return true;
+ }
+}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListSecretFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListSecretFragment.java
index f9d267f27..eaac6d8b1 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListSecretFragment.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListSecretFragment.java
@@ -29,6 +29,7 @@ import org.sufficientlysecure.keychain.ui.adapter.KeyListSecretAdapter;
import org.sufficientlysecure.keychain.ui.dialog.DeleteKeyDialogFragment;
import android.annotation.SuppressLint;
+import android.annotation.TargetApi;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
@@ -81,8 +82,6 @@ public class KeyListSecretFragment extends ListFragment implements
getListView().setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
getListView().setMultiChoiceModeListener(new MultiChoiceModeListener() {
- private int count = 0;
-
@Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
android.view.MenuInflater inflater = getActivity().getMenuInflater();
@@ -112,13 +111,20 @@ public class KeyListSecretFragment extends ListFragment implements
showDeleteKeyDialog(mode, ids);
break;
}
+ case R.id.menu_key_list_public_multi_select_all: {
+ //Select all
+ int localCount = getListView().getCount();
+ for(int k = 0; k < localCount; k++) {
+ getListView().setItemChecked(k, true);
+ }
+ break;
+ }
}
return true;
}
@Override
public void onDestroyActionMode(ActionMode mode) {
- count = 0;
mAdapter.clearSelection();
}
@@ -126,13 +132,12 @@ public class KeyListSecretFragment extends ListFragment implements
public void onItemCheckedStateChanged(ActionMode mode, int position, long id,
boolean checked) {
if (checked) {
- count++;
mAdapter.setNewSelection(position, checked);
} else {
- count--;
mAdapter.removeSelection(position);
}
+ int count = getListView().getCheckedItemCount();
String keysSelected = getResources().getQuantityString(
R.plurals.key_list_selected_keys, count, count);
mode.setTitle(keysSelected);
@@ -209,6 +214,7 @@ public class KeyListSecretFragment extends ListFragment implements
*
* @param keyRingRowIds
*/
+ @TargetApi(11)
public void showDeleteKeyDialog(final ActionMode mode, long[] keyRingRowIds) {
// Message is received after key is deleted
Handler returnHandler = new Handler() {
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/PreferencesActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/PreferencesActivity.java
index b38beebd1..af20b499b 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/PreferencesActivity.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/PreferencesActivity.java
@@ -24,24 +24,28 @@ import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.helper.Preferences;
import org.sufficientlysecure.keychain.ui.widget.IntegerListPreference;
+import android.annotation.SuppressLint;
+import android.content.Context;
import android.content.Intent;
+import android.os.Build;
import android.os.Bundle;
import android.preference.CheckBoxPreference;
import android.preference.Preference;
import android.preference.PreferenceActivity;
+import android.preference.PreferenceFragment;
import android.preference.PreferenceScreen;
import android.support.v7.app.ActionBarActivity;
+import java.util.List;
+
+@SuppressLint("NewApi")
public class PreferencesActivity extends PreferenceActivity {
- private IntegerListPreference mPassPhraseCacheTtl = null;
- private IntegerListPreference mEncryptionAlgorithm = null;
- private IntegerListPreference mHashAlgorithm = null;
- private IntegerListPreference mMessageCompression = null;
- private IntegerListPreference mFileCompression = null;
- private CheckBoxPreference mAsciiArmour = null;
- private CheckBoxPreference mForceV3Signatures = null;
+
+ public final static String ACTION_PREFS_GEN = "org.sufficientlysecure.keychain.ui.PREFS_GEN";
+ public final static String ACTION_PREFS_ADV = "org.sufficientlysecure.keychain.ui.PREFS_ADV";
+
private PreferenceScreen mKeyServerPreference = null;
- private Preferences mPreferences;
+ private static Preferences mPreferences;
@Override
protected void onCreate(Bundle savedInstanceState) {
@@ -53,22 +57,219 @@ public class PreferencesActivity extends PreferenceActivity {
// actionBar.setDisplayHomeAsUpEnabled(false);
// actionBar.setHomeButtonEnabled(false);
- addPreferencesFromResource(R.xml.preferences);
+ //addPreferencesFromResource(R.xml.preferences);
+ String action = getIntent().getAction();
+
+ if (action != null && action.equals(ACTION_PREFS_GEN)) {
+ addPreferencesFromResource(R.xml.gen_preferences);
+
+ initializePassPassPhraceCacheTtl(
+ (IntegerListPreference) findPreference(Constants.pref.PASS_PHRASE_CACHE_TTL));
+
+ mKeyServerPreference = (PreferenceScreen) findPreference(Constants.pref.KEY_SERVERS);
+ String servers[] = mPreferences.getKeyServers();
+ mKeyServerPreference.setSummary(getResources().getQuantityString(R.plurals.n_key_servers,
+ servers.length, servers.length));
+ mKeyServerPreference
+ .setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
+ public boolean onPreferenceClick(Preference preference) {
+ Intent intent = new Intent(PreferencesActivity.this,
+ PreferencesKeyServerActivity.class);
+ intent.putExtra(PreferencesKeyServerActivity.EXTRA_KEY_SERVERS,
+ mPreferences.getKeyServers());
+ startActivityForResult(intent, Id.request.key_server_preference);
+ return false;
+ }
+ });
+
+ } else if (action != null && action.equals(ACTION_PREFS_ADV)) {
+ addPreferencesFromResource(R.xml.adv_preferences);
+
+ initializeEncryptionAlgorithm(
+ (IntegerListPreference) findPreference(Constants.pref.DEFAULT_ENCRYPTION_ALGORITHM));
+
+ int[] valueIds = new int[] { Id.choice.compression.none, Id.choice.compression.zip,
+ Id.choice.compression.zlib, Id.choice.compression.bzip2, };
+ String[] entries = new String[] {
+ getString(R.string.choice_none) + " (" + getString(R.string.compression_fast) + ")",
+ "ZIP (" + getString(R.string.compression_fast) + ")",
+ "ZLIB (" + getString(R.string.compression_fast) + ")",
+ "BZIP2 (" + getString(R.string.compression_very_slow) + ")", };
+ String[] values = new String[valueIds.length];
+ for (int i = 0; i < values.length; ++i) {
+ values[i] = "" + valueIds[i];
+ }
+
+ initializeHashAlgorithm(
+ (IntegerListPreference) findPreference(Constants.pref.DEFAULT_HASH_ALGORITHM),
+ valueIds, entries, values);
+
+ initializeMessageCompression(
+ (IntegerListPreference) findPreference(Constants.pref.DEFAULT_MESSAGE_COMPRESSION),
+ valueIds, entries, values);
+
+ initializeFileCompression(
+ (IntegerListPreference) findPreference(Constants.pref.DEFAULT_FILE_COMPRESSION),
+ entries, values);
+
+ initializeAsciiArmour((CheckBoxPreference) findPreference(Constants.pref.DEFAULT_ASCII_ARMOUR));
+
+ initializeForceV3Signatures((CheckBoxPreference) findPreference(Constants.pref.FORCE_V3_SIGNATURES));
+
+ } else if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) {
+ // Load the legacy preferences headers
+ addPreferencesFromResource(R.xml.preference_headers_legacy);
+ }
+ }
+
+ @Override
+ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+ switch (requestCode) {
+ case Id.request.key_server_preference: {
+ if (resultCode == RESULT_CANCELED || data == null) {
+ return;
+ }
+ String servers[] = data
+ .getStringArrayExtra(PreferencesKeyServerActivity.EXTRA_KEY_SERVERS);
+ mPreferences.setKeyServers(servers);
+ mKeyServerPreference.setSummary(getResources().getQuantityString(
+ R.plurals.n_key_servers, servers.length, servers.length));
+ break;
+ }
+
+ default: {
+ super.onActivityResult(requestCode, resultCode, data);
+ break;
+ }
+ }
+ }
+
+ /* Called only on Honeycomb and later */
+ @Override
+ public void onBuildHeaders(List<Header> target) {
+ super.onBuildHeaders(target);
+ loadHeadersFromResource(R.xml.preference_headers, target);
+ }
+
+ /** This fragment shows the general preferences in android 3.0+ */
+ public static class GeneralPrefsFragment extends PreferenceFragment {
+
+ private PreferenceScreen mKeyServerPreference = null;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ // Load the preferences from an XML resource
+ addPreferencesFromResource(R.xml.gen_preferences);
+
+ initializePassPassPhraceCacheTtl(
+ (IntegerListPreference) findPreference(Constants.pref.PASS_PHRASE_CACHE_TTL));
+
+ mKeyServerPreference = (PreferenceScreen) findPreference(Constants.pref.KEY_SERVERS);
+ String servers[] = mPreferences.getKeyServers();
+ mKeyServerPreference.setSummary(getResources().getQuantityString(R.plurals.n_key_servers,
+ servers.length, servers.length));
+ mKeyServerPreference
+ .setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
+ public boolean onPreferenceClick(Preference preference) {
+ Intent intent = new Intent(getActivity(),
+ PreferencesKeyServerActivity.class);
+ intent.putExtra(PreferencesKeyServerActivity.EXTRA_KEY_SERVERS,
+ mPreferences.getKeyServers());
+ startActivityForResult(intent, Id.request.key_server_preference);
+ return false;
+ }
+ });
+ }
+
+ @Override
+ public void onActivityResult(int requestCode, int resultCode, Intent data) {
+ switch (requestCode) {
+ case Id.request.key_server_preference: {
+ if (resultCode == RESULT_CANCELED || data == null) {
+ return;
+ }
+ String servers[] = data
+ .getStringArrayExtra(PreferencesKeyServerActivity.EXTRA_KEY_SERVERS);
+ mPreferences.setKeyServers(servers);
+ mKeyServerPreference.setSummary(getResources().getQuantityString(
+ R.plurals.n_key_servers, servers.length, servers.length));
+ break;
+ }
+
+ default: {
+ super.onActivityResult(requestCode, resultCode, data);
+ break;
+ }
+ }
+ }
+ }
+
+ /** This fragment shows the advanced preferences in android 3.0+ */
+ public static class AdvancedPrefsFragment extends PreferenceFragment {
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ // Load the preferences from an XML resource
+ addPreferencesFromResource(R.xml.adv_preferences);
+
+ initializeEncryptionAlgorithm(
+ (IntegerListPreference) findPreference(Constants.pref.DEFAULT_ENCRYPTION_ALGORITHM));
+
+ int[] valueIds = new int[] { Id.choice.compression.none, Id.choice.compression.zip,
+ Id.choice.compression.zlib, Id.choice.compression.bzip2, };
+ String[] entries = new String[] {
+ getString(R.string.choice_none) + " (" + getString(R.string.compression_fast) + ")",
+ "ZIP (" + getString(R.string.compression_fast) + ")",
+ "ZLIB (" + getString(R.string.compression_fast) + ")",
+ "BZIP2 (" + getString(R.string.compression_very_slow) + ")", };
+ String[] values = new String[valueIds.length];
+ for (int i = 0; i < values.length; ++i) {
+ values[i] = "" + valueIds[i];
+ }
+
+ initializeHashAlgorithm(
+ (IntegerListPreference) findPreference(Constants.pref.DEFAULT_HASH_ALGORITHM),
+ valueIds, entries, values);
+
+ initializeMessageCompression(
+ (IntegerListPreference) findPreference(Constants.pref.DEFAULT_MESSAGE_COMPRESSION),
+ valueIds, entries, values);
+
+ initializeFileCompression(
+ (IntegerListPreference) findPreference(Constants.pref.DEFAULT_FILE_COMPRESSION),
+ entries, values);
- mPassPhraseCacheTtl = (IntegerListPreference) findPreference(Constants.pref.PASS_PHRASE_CACHE_TTL);
- mPassPhraseCacheTtl.setValue("" + mPreferences.getPassPhraseCacheTtl());
- mPassPhraseCacheTtl.setSummary(mPassPhraseCacheTtl.getEntry());
- mPassPhraseCacheTtl
+ initializeAsciiArmour((CheckBoxPreference) findPreference(Constants.pref.DEFAULT_ASCII_ARMOUR));
+
+ initializeForceV3Signatures((CheckBoxPreference) findPreference(Constants.pref.FORCE_V3_SIGNATURES));
+ }
+ }
+
+ protected boolean isValidFragment (String fragmentName) {
+ return AdvancedPrefsFragment.class.getName().equals(fragmentName)
+ || GeneralPrefsFragment.class.getName().equals(fragmentName)
+ || super.isValidFragment(fragmentName);
+ }
+
+ private static void initializePassPassPhraceCacheTtl(final IntegerListPreference mPassphraseCacheTtl) {
+ mPassphraseCacheTtl.setValue("" + mPreferences.getPassPhraseCacheTtl());
+ mPassphraseCacheTtl.setSummary(mPassphraseCacheTtl.getEntry());
+ mPassphraseCacheTtl
.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
public boolean onPreferenceChange(Preference preference, Object newValue) {
- mPassPhraseCacheTtl.setValue(newValue.toString());
- mPassPhraseCacheTtl.setSummary(mPassPhraseCacheTtl.getEntry());
+ mPassphraseCacheTtl.setValue(newValue.toString());
+ mPassphraseCacheTtl.setSummary(mPassphraseCacheTtl.getEntry());
mPreferences.setPassPhraseCacheTtl(Integer.parseInt(newValue.toString()));
return false;
}
});
+ }
- mEncryptionAlgorithm = (IntegerListPreference) findPreference(Constants.pref.DEFAULT_ENCRYPTION_ALGORITHM);
+ private static void initializeEncryptionAlgorithm(final IntegerListPreference mEncryptionAlgorithm) {
int valueIds[] = { PGPEncryptedData.AES_128, PGPEncryptedData.AES_192,
PGPEncryptedData.AES_256, PGPEncryptedData.BLOWFISH, PGPEncryptedData.TWOFISH,
PGPEncryptedData.CAST5, PGPEncryptedData.DES, PGPEncryptedData.TRIPLE_DES,
@@ -93,8 +294,10 @@ public class PreferencesActivity extends PreferenceActivity {
return false;
}
});
+ }
- mHashAlgorithm = (IntegerListPreference) findPreference(Constants.pref.DEFAULT_HASH_ALGORITHM);
+ private static void initializeHashAlgorithm
+ (final IntegerListPreference mHashAlgorithm, int[] valueIds, String[] entries, String[] values) {
valueIds = new int[] { HashAlgorithmTags.MD5, HashAlgorithmTags.RIPEMD160,
HashAlgorithmTags.SHA1, HashAlgorithmTags.SHA224, HashAlgorithmTags.SHA256,
HashAlgorithmTags.SHA384, HashAlgorithmTags.SHA512, };
@@ -116,19 +319,10 @@ public class PreferencesActivity extends PreferenceActivity {
return false;
}
});
+ }
- mMessageCompression = (IntegerListPreference) findPreference(Constants.pref.DEFAULT_MESSAGE_COMPRESSION);
- valueIds = new int[] { Id.choice.compression.none, Id.choice.compression.zip,
- Id.choice.compression.zlib, Id.choice.compression.bzip2, };
- entries = new String[] {
- getString(R.string.choice_none) + " (" + getString(R.string.compression_fast) + ")",
- "ZIP (" + getString(R.string.compression_fast) + ")",
- "ZLIB (" + getString(R.string.compression_fast) + ")",
- "BZIP2 (" + getString(R.string.compression_very_slow) + ")", };
- values = new String[valueIds.length];
- for (int i = 0; i < values.length; ++i) {
- values[i] = "" + valueIds[i];
- }
+ private static void initializeMessageCompression
+ (final IntegerListPreference mMessageCompression, int[] valueIds, String[] entries, String[] values) {
mMessageCompression.setEntries(entries);
mMessageCompression.setEntryValues(values);
mMessageCompression.setValue("" + mPreferences.getDefaultMessageCompression());
@@ -143,8 +337,10 @@ public class PreferencesActivity extends PreferenceActivity {
return false;
}
});
+ }
- mFileCompression = (IntegerListPreference) findPreference(Constants.pref.DEFAULT_FILE_COMPRESSION);
+ private static void initializeFileCompression
+ (final IntegerListPreference mFileCompression, String[] entries, String[] values) {
mFileCompression.setEntries(entries);
mFileCompression.setEntryValues(values);
mFileCompression.setValue("" + mPreferences.getDefaultFileCompression());
@@ -157,8 +353,9 @@ public class PreferencesActivity extends PreferenceActivity {
return false;
}
});
+ }
- mAsciiArmour = (CheckBoxPreference) findPreference(Constants.pref.DEFAULT_ASCII_ARMOUR);
+ private static void initializeAsciiArmour(final CheckBoxPreference mAsciiArmour) {
mAsciiArmour.setChecked(mPreferences.getDefaultAsciiArmour());
mAsciiArmour.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
public boolean onPreferenceChange(Preference preference, Object newValue) {
@@ -167,8 +364,9 @@ public class PreferencesActivity extends PreferenceActivity {
return false;
}
});
+ }
- mForceV3Signatures = (CheckBoxPreference) findPreference(Constants.pref.FORCE_V3_SIGNATURES);
+ private static void initializeForceV3Signatures(final CheckBoxPreference mForceV3Signatures) {
mForceV3Signatures.setChecked(mPreferences.getForceV3Signatures());
mForceV3Signatures
.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
@@ -178,43 +376,5 @@ public class PreferencesActivity extends PreferenceActivity {
return false;
}
});
-
- mKeyServerPreference = (PreferenceScreen) findPreference(Constants.pref.KEY_SERVERS);
- String servers[] = mPreferences.getKeyServers();
- mKeyServerPreference.setSummary(getResources().getQuantityString(R.plurals.n_key_servers,
- servers.length, servers.length));
- mKeyServerPreference
- .setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
- public boolean onPreferenceClick(Preference preference) {
- Intent intent = new Intent(PreferencesActivity.this,
- PreferencesKeyServerActivity.class);
- intent.putExtra(PreferencesKeyServerActivity.EXTRA_KEY_SERVERS,
- mPreferences.getKeyServers());
- startActivityForResult(intent, Id.request.key_server_preference);
- return false;
- }
- });
- }
-
- @Override
- protected void onActivityResult(int requestCode, int resultCode, Intent data) {
- switch (requestCode) {
- case Id.request.key_server_preference: {
- if (resultCode == RESULT_CANCELED || data == null) {
- return;
- }
- String servers[] = data
- .getStringArrayExtra(PreferencesKeyServerActivity.EXTRA_KEY_SERVERS);
- mPreferences.setKeyServers(servers);
- mKeyServerPreference.setSummary(getResources().getQuantityString(
- R.plurals.n_key_servers, servers.length, servers.length));
- break;
- }
-
- default: {
- super.onActivityResult(requestCode, resultCode, data);
- break;
- }
- }
}
-}
+} \ No newline at end of file
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectPublicKeyFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectPublicKeyFragment.java
index 59b46dd00..a43c84cf4 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectPublicKeyFragment.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectPublicKeyFragment.java
@@ -38,17 +38,22 @@ import android.os.Bundle;
import android.support.v4.app.LoaderManager;
import android.support.v4.content.CursorLoader;
import android.support.v4.content.Loader;
+import android.text.Editable;
+import android.text.TextUtils;
+import android.text.TextWatcher;
+import android.widget.EditText;
import android.widget.ListView;
-public class SelectPublicKeyFragment extends ListFragmentWorkaround implements
+public class SelectPublicKeyFragment extends ListFragmentWorkaround implements TextWatcher,
LoaderManager.LoaderCallbacks<Cursor> {
public static final String ARG_PRESELECTED_KEY_IDS = "preselected_key_ids";
private Activity mActivity;
private SelectKeyCursorAdapter mAdapter;
private ListView mListView;
-
+ private EditText mSearchView;
private long mSelectedMasterKeyIds[];
+ private String mCurQuery;
/**
* Creates new instance of this fragment
@@ -67,7 +72,8 @@ public class SelectPublicKeyFragment extends ListFragmentWorkaround implements
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
-
+ mSearchView = (EditText)getActivity().findViewById(R.id.select_public_key_search);
+ mSearchView.addTextChangedListener(this);
mSelectedMasterKeyIds = getArguments().getLongArray(ARG_PRESELECTED_KEY_IDS);
}
@@ -82,7 +88,6 @@ public class SelectPublicKeyFragment extends ListFragmentWorkaround implements
mListView = getListView();
mListView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
-
// Give some text to display if there is no data. In a real
// application this would come from a resource.
setEmptyText(getString(R.string.list_empty));
@@ -220,10 +225,16 @@ public class SelectPublicKeyFragment extends ListFragmentWorkaround implements
// sort by selected master keys
orderBy = inMasterKeyList + " DESC, " + orderBy;
}
+ String where = null;
+ String whereArgs[] = null;
+ if(mCurQuery != null){
+ where = UserIds.USER_ID + " LIKE ?";
+ whereArgs = new String[]{mCurQuery+"%"};
+ }
// Now create and return a CursorLoader that will take care of
// creating a Cursor for the data being displayed.
- return new CursorLoader(getActivity(), baseUri, projection, null, null, orderBy);
+ return new CursorLoader(getActivity(), baseUri, projection, where, whereArgs, orderBy);
}
@Override
@@ -250,4 +261,21 @@ public class SelectPublicKeyFragment extends ListFragmentWorkaround implements
// longer using it.
mAdapter.swapCursor(null);
}
+
+ @Override
+ public void beforeTextChanged(CharSequence charSequence, int i, int i2, int i3) {
+
+ }
+
+ @Override
+ public void onTextChanged(CharSequence charSequence, int i, int i2, int i3) {
+
+ }
+
+ @Override
+ public void afterTextChanged(Editable editable) {
+ String newQuery = !TextUtils.isEmpty(editable.toString()) ? editable.toString() : null;
+ mCurQuery = newQuery;
+ getLoaderManager().restartLoader(0, null, this);
+ }
}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/AsyncTaskResultWrapper.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/AsyncTaskResultWrapper.java
new file mode 100644
index 000000000..2ac19c1d9
--- /dev/null
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/AsyncTaskResultWrapper.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2014 Dominik Schürmann <dominik@dominikschuermann.de>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package org.sufficientlysecure.keychain.ui.adapter;
+
+/**
+ * The AsyncTaskResultWrapper is used to wrap a result from a AsyncTask (for example: Loader).
+ * You can pass the result and an exception in it if an error occurred.
+ * Concept found at:
+ * https://stackoverflow.com/questions/19593577/how-to-handle-errors-in-custom-asynctaskloader
+ * @param <T> - Typ of the result which is wrapped
+ */
+public class AsyncTaskResultWrapper <T>{
+
+ private final T result;
+ private final Exception error;
+
+ public AsyncTaskResultWrapper(T result, Exception error){
+ this.result = result;
+ this.error = error;
+ }
+
+ public T getResult() {
+ return result;
+ }
+
+ public Exception getError() {
+ return error;
+ }
+
+}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListLoader.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListLoader.java
index 00ad8c957..76649b27b 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListLoader.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListLoader.java
@@ -33,12 +33,13 @@ import org.sufficientlysecure.keychain.util.PositionAwareInputStream;
import android.content.Context;
import android.support.v4.content.AsyncTaskLoader;
-public class ImportKeysListLoader extends AsyncTaskLoader<List<ImportKeysListEntry>> {
+public class ImportKeysListLoader extends AsyncTaskLoader<AsyncTaskResultWrapper<ArrayList<ImportKeysListEntry>>> {
Context mContext;
InputData mInputData;
ArrayList<ImportKeysListEntry> data = new ArrayList<ImportKeysListEntry>();
+ AsyncTaskResultWrapper<ArrayList<ImportKeysListEntry>> entryListWrapper;
public ImportKeysListLoader(Context context, InputData inputData) {
super(context);
@@ -47,15 +48,18 @@ public class ImportKeysListLoader extends AsyncTaskLoader<List<ImportKeysListEnt
}
@Override
- public List<ImportKeysListEntry> loadInBackground() {
+ public AsyncTaskResultWrapper<ArrayList<ImportKeysListEntry>> loadInBackground() {
+
+ entryListWrapper = new AsyncTaskResultWrapper<ArrayList<ImportKeysListEntry>>(data, null);
+
if (mInputData == null) {
Log.e(Constants.TAG, "Input data is null!");
- return data;
+ return entryListWrapper;
}
generateListOfKeyrings(mInputData);
- return data;
+ return entryListWrapper;
}
@Override
@@ -77,7 +81,7 @@ public class ImportKeysListLoader extends AsyncTaskLoader<List<ImportKeysListEnt
}
@Override
- public void deliverResult(List<ImportKeysListEntry> data) {
+ public void deliverResult(AsyncTaskResultWrapper<ArrayList<ImportKeysListEntry>> data) {
super.deliverResult(data);
}
@@ -93,7 +97,7 @@ public class ImportKeysListLoader extends AsyncTaskLoader<List<ImportKeysListEnt
// need to have access to the bufferedInput, so we can reuse it for the possible
// PGPObject chunks after the first one, e.g. files with several consecutive ASCII
- // armour blocks
+ // armor blocks
BufferedInputStream bufferedInput = new BufferedInputStream(progressIn);
try {
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListServerLoader.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListServerLoader.java
index b3bc39127..3a3b6e58b 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListServerLoader.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListServerLoader.java
@@ -26,15 +26,15 @@ import org.sufficientlysecure.keychain.util.KeyServer;
import org.sufficientlysecure.keychain.util.Log;
import java.util.ArrayList;
-import java.util.List;
-public class ImportKeysListServerLoader extends AsyncTaskLoader<List<ImportKeysListEntry>> {
+public class ImportKeysListServerLoader extends AsyncTaskLoader<AsyncTaskResultWrapper<ArrayList<ImportKeysListEntry>>> {
Context mContext;
String mServerQuery;
String mKeyServer;
- ArrayList<ImportKeysListEntry> data = new ArrayList<ImportKeysListEntry>();
+ private ArrayList<ImportKeysListEntry> entryList = new ArrayList<ImportKeysListEntry>();
+ private AsyncTaskResultWrapper<ArrayList<ImportKeysListEntry>> entryListWrapper;
public ImportKeysListServerLoader(Context context, String serverQuery, String keyServer) {
super(context);
@@ -44,15 +44,18 @@ public class ImportKeysListServerLoader extends AsyncTaskLoader<List<ImportKeysL
}
@Override
- public List<ImportKeysListEntry> loadInBackground() {
+ public AsyncTaskResultWrapper<ArrayList<ImportKeysListEntry>> loadInBackground() {
+
+ entryListWrapper = new AsyncTaskResultWrapper<ArrayList<ImportKeysListEntry>>(entryList, null);
+
if (mServerQuery == null) {
Log.e(Constants.TAG, "mServerQuery is null!");
- return data;
+ return entryListWrapper;
}
queryServer(mServerQuery, mKeyServer);
- return data;
+ return entryListWrapper;
}
@Override
@@ -74,7 +77,7 @@ public class ImportKeysListServerLoader extends AsyncTaskLoader<List<ImportKeysL
}
@Override
- public void deliverResult(List<ImportKeysListEntry> data) {
+ public void deliverResult(AsyncTaskResultWrapper<ArrayList<ImportKeysListEntry>> data) {
super.deliverResult(data);
}
@@ -87,13 +90,17 @@ public class ImportKeysListServerLoader extends AsyncTaskLoader<List<ImportKeysL
ArrayList<ImportKeysListEntry> searchResult = server.search(query);
// add result to data
- data.addAll(searchResult);
+ entryList.addAll(searchResult);
+ entryListWrapper = new AsyncTaskResultWrapper<ArrayList<ImportKeysListEntry>>(entryList, null);
} catch (KeyServer.InsufficientQuery e) {
Log.e(Constants.TAG, "InsufficientQuery", e);
+ entryListWrapper = new AsyncTaskResultWrapper<ArrayList<ImportKeysListEntry>>(entryList, e);
} catch (KeyServer.QueryException e) {
Log.e(Constants.TAG, "QueryException", e);
+ entryListWrapper = new AsyncTaskResultWrapper<ArrayList<ImportKeysListEntry>>(entryList, e);
} catch (KeyServer.TooManyResponses e) {
Log.e(Constants.TAG, "TooManyResponses", e);
+ entryListWrapper = new AsyncTaskResultWrapper<ArrayList<ImportKeysListEntry>>(entryList, e);
}
}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/KeyListPublicAdapter.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/KeyListPublicAdapter.java
index 257136cbd..ac505adfb 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/KeyListPublicAdapter.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/KeyListPublicAdapter.java
@@ -223,7 +223,7 @@ public class KeyListPublicAdapter extends CursorAdapter implements StickyListHea
*/
// default color
v.setBackgroundColor(Color.TRANSPARENT);
- if (mSelection.get(position) != null) {
+ if (mSelection.get(position) != null && mSelection.get(position).booleanValue()) {
// this is a selected position, change color!
v.setBackgroundColor(parent.getResources().getColor(R.color.emphasis));
}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/BadImportKeyDialogFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/BadImportKeyDialogFragment.java
new file mode 100644
index 000000000..2b8cba857
--- /dev/null
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/BadImportKeyDialogFragment.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2012-2013 Dominik Schürmann <dominik@dominikschuermann.de>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package org.sufficientlysecure.keychain.ui.dialog;
+
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.content.DialogInterface;
+import android.os.Bundle;
+import android.support.v4.app.DialogFragment;
+import android.support.v4.app.FragmentActivity;
+
+import org.sufficientlysecure.keychain.R;
+
+public class BadImportKeyDialogFragment extends DialogFragment {
+ private static final String ARG_BAD_IMPORT = "bad_import";
+
+ /**
+ * Creates a new instance of this Bad Import Key DialogFragment
+ *
+ * @param bad
+ * @return
+ */
+ public static BadImportKeyDialogFragment newInstance(int bad) {
+ BadImportKeyDialogFragment frag = new BadImportKeyDialogFragment();
+ Bundle args = new Bundle();
+
+ args.putInt(ARG_BAD_IMPORT, bad);
+ frag.setArguments(args);
+
+ return frag;
+ }
+
+ @Override
+ public Dialog onCreateDialog(Bundle savedInstanceState) {
+ final FragmentActivity activity = getActivity();
+ final int badImport = getArguments().getInt(ARG_BAD_IMPORT);
+
+ AlertDialog.Builder alert = new AlertDialog.Builder(activity);
+ alert.setIcon(R.drawable.ic_dialog_alert_holo_light);
+ alert.setTitle(R.string.warning);
+ alert.setMessage(activity.getResources()
+ .getQuantityString(R.plurals.bad_keys_encountered, badImport, badImport));
+ alert.setPositiveButton(android.R.string.ok,
+ new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int id) {
+ dialog.cancel();
+ }
+ });
+ alert.setCancelable(true);
+
+ return alert.create();
+ }
+}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/CreateKeyDialogFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/CreateKeyDialogFragment.java
new file mode 100644
index 000000000..98b677511
--- /dev/null
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/CreateKeyDialogFragment.java
@@ -0,0 +1,152 @@
+/*
+ * Copyright (C) 2012-2013 Dominik Schürmann <dominik@dominikschuermann.de>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package org.sufficientlysecure.keychain.ui.dialog;
+
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.content.DialogInterface;
+import android.os.Bundle;
+import android.support.v4.app.DialogFragment;
+import android.support.v4.app.FragmentActivity;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.ArrayAdapter;
+import android.widget.Spinner;
+
+import org.sufficientlysecure.keychain.Id;
+import org.sufficientlysecure.keychain.R;
+import org.sufficientlysecure.keychain.util.Choice;
+
+import java.util.Vector;
+
+public class CreateKeyDialogFragment extends DialogFragment {
+
+ public interface OnAlgorithmSelectedListener {
+ public void onAlgorithmSelected(Choice algorithmChoice, int keySize);
+ }
+
+ private static final String ARG_EDITOR_CHILD_COUNT = "child_count";
+
+ private int mNewKeySize;
+ private Choice mNewKeyAlgorithmChoice;
+ private OnAlgorithmSelectedListener mAlgorithmSelectedListener;
+
+ public void setOnAlgorithmSelectedListener(OnAlgorithmSelectedListener listener) {
+ mAlgorithmSelectedListener = listener;
+ }
+
+ public static CreateKeyDialogFragment newInstance(int mEditorChildCount) {
+ CreateKeyDialogFragment frag = new CreateKeyDialogFragment();
+ Bundle args = new Bundle();
+
+ args.putInt(ARG_EDITOR_CHILD_COUNT, mEditorChildCount);
+
+ frag.setArguments(args);
+
+ return frag;
+ }
+
+ @Override
+ public Dialog onCreateDialog(Bundle savedInstanceState) {
+ final FragmentActivity context = getActivity();
+ final LayoutInflater mInflater;
+
+ final int childCount = getArguments().getInt(ARG_EDITOR_CHILD_COUNT);
+ mInflater = context.getLayoutInflater();
+
+ AlertDialog.Builder dialog = new AlertDialog.Builder(context);
+
+ View view = mInflater.inflate(R.layout.create_key_dialog, null);
+ dialog.setView(view);
+ dialog.setTitle(R.string.title_create_key);
+
+ boolean wouldBeMasterKey = (childCount == 0);
+
+ final Spinner algorithm = (Spinner) view.findViewById(R.id.create_key_algorithm);
+ Vector<Choice> choices = new Vector<Choice>();
+ choices.add(new Choice(Id.choice.algorithm.dsa, getResources().getString(
+ R.string.dsa)));
+ if (!wouldBeMasterKey) {
+ choices.add(new Choice(Id.choice.algorithm.elgamal, getResources().getString(
+ R.string.elgamal)));
+ }
+
+ choices.add(new Choice(Id.choice.algorithm.rsa, getResources().getString(
+ R.string.rsa)));
+
+ ArrayAdapter<Choice> adapter = new ArrayAdapter<Choice>(context,
+ android.R.layout.simple_spinner_item, choices);
+ adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
+ algorithm.setAdapter(adapter);
+ // make RSA the default
+ for (int i = 0; i < choices.size(); ++i) {
+ if (choices.get(i).getId() == Id.choice.algorithm.rsa) {
+ algorithm.setSelection(i);
+ break;
+ }
+ }
+
+ final Spinner keySize = (Spinner) view.findViewById(R.id.create_key_size);
+ ArrayAdapter<CharSequence> keySizeAdapter = ArrayAdapter.createFromResource(
+ context, R.array.key_size_spinner_values,
+ android.R.layout.simple_spinner_item);
+ keySizeAdapter
+ .setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
+ keySize.setAdapter(keySizeAdapter);
+ keySize.setSelection(3); // Default to 4096 for the key length
+ dialog.setPositiveButton(android.R.string.ok,
+ new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface di, int id) {
+ di.dismiss();
+ try {
+ int nKeyIndex = keySize.getSelectedItemPosition();
+ switch (nKeyIndex) {
+ case 0:
+ mNewKeySize = 512;
+ break;
+ case 1:
+ mNewKeySize = 1024;
+ break;
+ case 2:
+ mNewKeySize = 2048;
+ break;
+ case 3:
+ mNewKeySize = 4096;
+ break;
+ }
+ } catch (NumberFormatException e) {
+ mNewKeySize = 0;
+ }
+
+ mNewKeyAlgorithmChoice = (Choice) algorithm.getSelectedItem();
+ mAlgorithmSelectedListener.onAlgorithmSelected(mNewKeyAlgorithmChoice, mNewKeySize);
+ }
+ });
+
+ dialog.setCancelable(true);
+ dialog.setNegativeButton(android.R.string.cancel,
+ new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface di, int id) {
+ di.dismiss();
+ }
+ });
+
+ return dialog.create();
+ }
+
+} \ No newline at end of file
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteFileDialogFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteFileDialogFragment.java
index f7e41daf7..cd8bc79a9 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteFileDialogFragment.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteFileDialogFragment.java
@@ -61,7 +61,8 @@ public class DeleteFileDialogFragment extends DialogFragment {
AlertDialog.Builder alert = new AlertDialog.Builder(activity);
- alert.setIcon(android.R.drawable.ic_dialog_alert);
+
+ alert.setIcon(R.drawable.ic_dialog_alert_holo_light);
alert.setTitle(R.string.warning);
alert.setMessage(this.getString(R.string.file_delete_confirmation, deleteFile));
@@ -82,7 +83,7 @@ public class DeleteFileDialogFragment extends DialogFragment {
intent.putExtra(KeychainIntentService.EXTRA_DATA, data);
ProgressDialogFragment deletingDialog = ProgressDialogFragment.newInstance(
- R.string.progress_deleting_securely, ProgressDialog.STYLE_HORIZONTAL);
+ R.string.progress_deleting_securely, ProgressDialog.STYLE_HORIZONTAL, false, null);
// Message is received after deleting is done in ApgService
KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler(activity, deletingDialog) {
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteKeyDialogFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteKeyDialogFragment.java
index 3c44bff81..dc40bab2a 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteKeyDialogFragment.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteKeyDialogFragment.java
@@ -17,17 +17,6 @@
package org.sufficientlysecure.keychain.ui.dialog;
-import org.spongycastle.openpgp.PGPPublicKeyRing;
-import org.spongycastle.openpgp.PGPSecretKeyRing;
-import org.sufficientlysecure.keychain.Constants;
-import org.sufficientlysecure.keychain.Id;
-import org.sufficientlysecure.keychain.R;
-import org.sufficientlysecure.keychain.pgp.PgpKeyHelper;
-import org.sufficientlysecure.keychain.provider.KeychainContract;
-import org.sufficientlysecure.keychain.provider.KeychainDatabase;
-import org.sufficientlysecure.keychain.provider.ProviderHelper;
-import org.sufficientlysecure.keychain.util.Log;
-
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
@@ -40,6 +29,14 @@ import android.os.RemoteException;
import android.support.v4.app.DialogFragment;
import android.support.v4.app.FragmentActivity;
+import org.sufficientlysecure.keychain.Constants;
+import org.sufficientlysecure.keychain.Id;
+import org.sufficientlysecure.keychain.R;
+import org.sufficientlysecure.keychain.provider.KeychainContract;
+import org.sufficientlysecure.keychain.provider.KeychainDatabase;
+import org.sufficientlysecure.keychain.provider.ProviderHelper;
+import org.sufficientlysecure.keychain.util.Log;
+
import java.util.ArrayList;
public class DeleteKeyDialogFragment extends DialogFragment {
@@ -100,7 +97,7 @@ public class DeleteKeyDialogFragment extends DialogFragment {
builder.setMessage(R.string.key_deletion_confirmation_multi);
}
- builder.setIcon(android.R.drawable.ic_dialog_alert);
+ builder.setIcon(R.drawable.ic_dialog_alert_holo_light);
builder.setPositiveButton(R.string.btn_delete, new DialogInterface.OnClickListener() {
@Override
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/PassphraseDialogFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/PassphraseDialogFragment.java
index e88271240..c00232fd1 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/PassphraseDialogFragment.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/PassphraseDialogFragment.java
@@ -153,7 +153,7 @@ public class PassphraseDialogFragment extends DialogFragment implements OnEditor
dismiss();
long curKeyIndex = 1;
boolean keyOK = true;
- String passPhrase = mPassphraseEditText.getText().toString();
+ String passphrase = mPassphraseEditText.getText().toString();
long keyId;
PGPSecretKey clickSecretKey = secretKey;
@@ -163,7 +163,7 @@ public class PassphraseDialogFragment extends DialogFragment implements OnEditor
try {
PBESecretKeyDecryptor keyDecryptor = new JcePBESecretKeyDecryptorBuilder()
.setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(
- passPhrase.toCharArray());
+ passphrase.toCharArray());
PGPPrivateKey testKey = clickSecretKey
.extractPrivateKey(keyDecryptor);
if (testKey == null) {
@@ -206,10 +206,10 @@ 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);
+ PassphraseCacheService.addCachedPassphrase(activity, keyId, passphrase);
if (keyOK == false && clickSecretKey.getKeyID() != keyId) {
PassphraseCacheService.addCachedPassphrase(activity, clickSecretKey.getKeyID(),
- passPhrase);
+ passphrase);
}
sendMessageToHandler(MESSAGE_OKAY);
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/ProgressDialogFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/ProgressDialogFragment.java
index 9b5d233e8..6c62d14e0 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/ProgressDialogFragment.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/ProgressDialogFragment.java
@@ -21,28 +21,40 @@ import android.app.Activity;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.DialogInterface;
+import android.content.DialogInterface.OnCancelListener;
import android.content.DialogInterface.OnKeyListener;
import android.os.Bundle;
import android.support.v4.app.DialogFragment;
import android.view.KeyEvent;
+import org.sufficientlysecure.keychain.R;
+
public class ProgressDialogFragment extends DialogFragment {
private static final String ARG_MESSAGE_ID = "message_id";
private static final String ARG_STYLE = "style";
+ private static final String ARG_CANCELABLE = "cancelable";
+
+ private OnCancelListener mOnCancelListener;
/**
* Creates new instance of this fragment
*
- * @param id
+ * @param messageId
+ * @param style
+ * @param cancelable
* @return
*/
- public static ProgressDialogFragment newInstance(int messageId, int style) {
+ public static ProgressDialogFragment newInstance(int messageId, int style, boolean cancelable,
+ OnCancelListener onCancelListener) {
ProgressDialogFragment frag = new ProgressDialogFragment();
Bundle args = new Bundle();
args.putInt(ARG_MESSAGE_ID, messageId);
args.putInt(ARG_STYLE, style);
+ args.putBoolean(ARG_CANCELABLE, cancelable);
frag.setArguments(args);
+ frag.mOnCancelListener = onCancelListener;
+
return frag;
}
@@ -60,7 +72,6 @@ public class ProgressDialogFragment extends DialogFragment {
/**
* Updates progress of dialog
*
- * @param messageId
* @param progress
* @param max
*/
@@ -74,7 +85,7 @@ public class ProgressDialogFragment extends DialogFragment {
/**
* Updates progress of dialog
*
- * @param messageId
+ * @param message
* @param progress
* @param max
*/
@@ -86,12 +97,20 @@ public class ProgressDialogFragment extends DialogFragment {
dialog.setMax(max);
}
+ @Override
+ public void onCancel(DialogInterface dialog) {
+ super.onCancel(dialog);
+
+ if (this.mOnCancelListener != null)
+ this.mOnCancelListener.onCancel(dialog);
+ }
+
/**
* Creates dialog
*/
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
- Activity activity = getActivity();
+ final Activity activity = getActivity();
ProgressDialog dialog = new ProgressDialog(activity);
dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
@@ -100,10 +119,22 @@ public class ProgressDialogFragment extends DialogFragment {
int messageId = getArguments().getInt(ARG_MESSAGE_ID);
int style = getArguments().getInt(ARG_STYLE);
+ boolean cancelable = getArguments().getBoolean(ARG_CANCELABLE);
dialog.setMessage(getString(messageId));
dialog.setProgressStyle(style);
+ if (cancelable) {
+ dialog.setButton(DialogInterface.BUTTON_NEGATIVE,
+ activity.getString(R.string.progress_cancel),
+ new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ dialog.cancel();
+ }
+ });
+ }
+
// Disable the back button
OnKeyListener keyListener = new OnKeyListener() {
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/SetPassphraseDialogFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/SetPassphraseDialogFragment.java
index 50e72dfba..e406547b3 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/SetPassphraseDialogFragment.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/SetPassphraseDialogFragment.java
@@ -101,9 +101,9 @@ public class SetPassphraseDialogFragment extends DialogFragment implements OnEdi
public void onClick(DialogInterface dialog, int id) {
dismiss();
- String passPhrase1 = mPassphraseEditText.getText().toString();
- String passPhrase2 = mPassphraseAgainEditText.getText().toString();
- if (!passPhrase1.equals(passPhrase2)) {
+ String passphrase1 = mPassphraseEditText.getText().toString();
+ String passphrase2 = mPassphraseAgainEditText.getText().toString();
+ if (!passphrase1.equals(passphrase2)) {
Toast.makeText(
activity,
getString(R.string.error_message,
@@ -112,7 +112,7 @@ public class SetPassphraseDialogFragment extends DialogFragment implements OnEdi
return;
}
- if (passPhrase1.equals("")) {
+ if (passphrase1.equals("")) {
Toast.makeText(
activity,
getString(R.string.error_message,
@@ -123,7 +123,7 @@ public class SetPassphraseDialogFragment extends DialogFragment implements OnEdi
// return resulting data back to activity
Bundle data = new Bundle();
- data.putString(MESSAGE_NEW_PASSPHRASE, passPhrase1);
+ data.putString(MESSAGE_NEW_PASSPHRASE, passphrase1);
sendMessageToHandler(MESSAGE_OKAY, data);
}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/ShareNfcDialogFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/ShareNfcDialogFragment.java
index 03e09cdcb..b850638a6 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/ShareNfcDialogFragment.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/ShareNfcDialogFragment.java
@@ -53,7 +53,6 @@ public class ShareNfcDialogFragment extends DialogFragment {
AlertDialog.Builder alert = new AlertDialog.Builder(activity);
- alert.setIcon(android.R.drawable.ic_dialog_info);
alert.setTitle(R.string.share_nfc_dialog);
alert.setCancelable(true);
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/ShareQrCodeDialogFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/ShareQrCodeDialogFragment.java
index 9f3270250..f26cd35c0 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/ShareQrCodeDialogFragment.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/ShareQrCodeDialogFragment.java
@@ -17,28 +17,26 @@
package org.sufficientlysecure.keychain.ui.dialog;
-import java.util.ArrayList;
-
-import org.sufficientlysecure.keychain.Constants;
-import org.sufficientlysecure.keychain.R;
-import org.sufficientlysecure.keychain.pgp.PgpKeyHelper;
-import org.sufficientlysecure.keychain.provider.ProviderHelper;
-import org.sufficientlysecure.keychain.util.Log;
-import org.sufficientlysecure.keychain.util.QrCodeUtils;
-
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.app.DialogFragment;
-import android.view.ContextThemeWrapper;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
+import org.sufficientlysecure.keychain.Constants;
+import org.sufficientlysecure.keychain.R;
+import org.sufficientlysecure.keychain.pgp.PgpKeyHelper;
+import org.sufficientlysecure.keychain.provider.ProviderHelper;
+import org.sufficientlysecure.keychain.util.QrCodeUtils;
+
+import java.util.ArrayList;
+
public class ShareQrCodeDialogFragment extends DialogFragment {
private static final String ARG_KEY_URI = "uri";
private static final String ARG_FINGERPRINT_ONLY = "fingerprint_only";
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeyEditor.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeyEditor.java
index 68bfc573e..b1f97babf 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeyEditor.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeyEditor.java
@@ -35,6 +35,7 @@ import android.app.DatePickerDialog;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
+import android.text.format.DateUtils;
import android.util.AttributeSet;
import android.view.View;
import android.view.View.OnClickListener;
@@ -60,6 +61,7 @@ public class KeyEditor extends LinearLayout implements Editor, OnClickListener {
TextView mKeyId;
TextView mCreationDate;
BootstrapButton mExpiryDateButton;
+ GregorianCalendar mCreatedDate;
GregorianCalendar mExpiryDate;
GregorianCalendar mOriginalExpiryDate = null;
CheckBox mChkCertify;
@@ -142,8 +144,12 @@ public class KeyEditor extends LinearLayout implements Editor, OnClickListener {
if (date == null) {
date = new GregorianCalendar(TimeZone.getTimeZone("UTC"));
}
-
- DatePickerDialog dialog = new DatePickerDialog(getContext(),
+ /*
+ * Using custom DatePickerDialog which overrides the setTitle because
+ * the DatePickerDialog title is buggy (unix warparound bug).
+ * See: https://code.google.com/p/android/issues/detail?id=49066
+ */
+ DatePickerDialog dialog = new ExpiryDatePickerDialog(getContext(),
mExpiryDateSetListener, date.get(Calendar.YEAR), date.get(Calendar.MONTH),
date.get(Calendar.DAY_OF_MONTH));
mDatePickerResultCount = 0;
@@ -161,6 +167,21 @@ public class KeyEditor extends LinearLayout implements Editor, OnClickListener {
}
}
});
+
+ // setCalendarViewShown() is supported from API 11 onwards.
+ if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.HONEYCOMB)
+ // Hide calendarView in tablets because of the unix warparound bug.
+ dialog.getDatePicker().setCalendarViewShown(false);
+
+ if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.HONEYCOMB) {
+ if ( dialog != null && mCreatedDate != null ) {
+ dialog.getDatePicker().setMinDate(mCreatedDate.getTime().getTime()+ DateUtils.DAY_IN_MILLIS);
+ } else {
+ //When created date isn't available
+ dialog.getDatePicker().setMinDate(date.getTime().getTime()+ DateUtils.DAY_IN_MILLIS);
+ }
+ }
+
dialog.show();
}
});
@@ -237,7 +258,7 @@ public class KeyEditor extends LinearLayout implements Editor, OnClickListener {
GregorianCalendar cal = new GregorianCalendar(TimeZone.getTimeZone("UTC"));
cal.setTime(PgpKeyHelper.getCreationDate(key));
- mCreationDate.setText(DateFormat.getDateInstance().format(cal.getTime()));
+ setCreatedDate(cal);
cal = new GregorianCalendar(TimeZone.getTimeZone("UTC"));
Date expiryDate = PgpKeyHelper.getExpiryDate(key);
if (expiryDate == null) {
@@ -268,6 +289,15 @@ public class KeyEditor extends LinearLayout implements Editor, OnClickListener {
mEditorListener = listener;
}
+ private void setCreatedDate(GregorianCalendar date) {
+ mCreatedDate = date;
+ if (date == null) {
+ mCreationDate.setText(getContext().getString(R.string.none));
+ } else {
+ mCreationDate.setText(DateFormat.getDateInstance().format(date.getTime()));
+ }
+ }
+
private void setExpiryDate(GregorianCalendar date) {
mExpiryDate = date;
if (date == null) {
@@ -320,3 +350,14 @@ public class KeyEditor extends LinearLayout implements Editor, OnClickListener {
}
}
+
+class ExpiryDatePickerDialog extends DatePickerDialog {
+
+ public ExpiryDatePickerDialog(Context context, OnDateSetListener callBack, int year, int monthOfYear, int dayOfMonth) {
+ super(context, callBack, year, monthOfYear, dayOfMonth);
+ }
+ //Set permanent title.
+ public void setTitle(CharSequence title) {
+ super.setTitle(getContext().getString(R.string.expiry_date_dialog_title));
+ }
+}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SectionView.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SectionView.java
index 93c10a2b0..6ab422d69 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SectionView.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SectionView.java
@@ -46,13 +46,25 @@ import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
-import android.widget.ArrayAdapter;
import android.widget.LinearLayout;
-import android.widget.Spinner;
import android.widget.TextView;
import com.beardedhen.androidbootstrap.BootstrapButton;
+import org.spongycastle.openpgp.PGPSecretKey;
+import org.sufficientlysecure.keychain.Id;
+import org.sufficientlysecure.keychain.R;
+import org.sufficientlysecure.keychain.pgp.PgpConversionHelper;
+import org.sufficientlysecure.keychain.service.KeychainIntentService;
+import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler;
+import org.sufficientlysecure.keychain.service.PassphraseCacheService;
+import org.sufficientlysecure.keychain.ui.dialog.CreateKeyDialogFragment;
+import org.sufficientlysecure.keychain.ui.dialog.ProgressDialogFragment;
+import org.sufficientlysecure.keychain.ui.widget.Editor.EditorListener;
+import org.sufficientlysecure.keychain.util.Choice;
+
+
+
public class SectionView extends LinearLayout implements OnClickListener, EditorListener, Editor {
private LayoutInflater mInflater;
private BootstrapButton mPlusButton;
@@ -252,84 +264,16 @@ public class SectionView extends LinearLayout implements OnClickListener, Editor
}
case Id.type.key: {
- AlertDialog.Builder dialog = new AlertDialog.Builder(getContext());
-
- View view = mInflater.inflate(R.layout.create_key_dialog, null);
- dialog.setView(view);
- dialog.setTitle(R.string.title_create_key);
-
- boolean wouldBeMasterKey = (mEditors.getChildCount() == 0);
-
- final Spinner algorithm = (Spinner) view.findViewById(R.id.create_key_algorithm);
- Vector<Choice> choices = new Vector<Choice>();
- choices.add(new Choice(Id.choice.algorithm.dsa, getResources().getString(
- R.string.dsa)));
- if (!wouldBeMasterKey) {
- choices.add(new Choice(Id.choice.algorithm.elgamal, getResources().getString(
- R.string.elgamal)));
- }
-
- choices.add(new Choice(Id.choice.algorithm.rsa, getResources().getString(
- R.string.rsa)));
-
- ArrayAdapter<Choice> adapter = new ArrayAdapter<Choice>(getContext(),
- android.R.layout.simple_spinner_item, choices);
- adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
- algorithm.setAdapter(adapter);
- // make RSA the default
- for (int i = 0; i < choices.size(); ++i) {
- if (choices.get(i).getId() == Id.choice.algorithm.rsa) {
- algorithm.setSelection(i);
- break;
+ CreateKeyDialogFragment mCreateKeyDialogFragment = CreateKeyDialogFragment.newInstance(mEditors.getChildCount());
+ mCreateKeyDialogFragment.setOnAlgorithmSelectedListener(new CreateKeyDialogFragment.OnAlgorithmSelectedListener() {
+ @Override
+ public void onAlgorithmSelected(Choice algorithmChoice, int keySize) {
+ mNewKeyAlgorithmChoice = algorithmChoice;
+ mNewKeySize = keySize;
+ createKey();
}
- }
-
- final Spinner keySize = (Spinner) view.findViewById(R.id.create_key_size);
- ArrayAdapter<CharSequence> keySizeAdapter = ArrayAdapter.createFromResource(
- getContext(), R.array.key_size_spinner_values,
- android.R.layout.simple_spinner_item);
- keySizeAdapter
- .setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
- keySize.setAdapter(keySizeAdapter);
- keySize.setSelection(3); // Default to 4096 for the key length
- dialog.setPositiveButton(android.R.string.ok,
- new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface di, int id) {
- di.dismiss();
- try {
- int nKeyIndex = keySize.getSelectedItemPosition();
- switch (nKeyIndex) {
- case 0:
- mNewKeySize = 512;
- break;
- case 1:
- mNewKeySize = 1024;
- break;
- case 2:
- mNewKeySize = 2048;
- break;
- case 3:
- mNewKeySize = 4096;
- break;
- }
- } catch (NumberFormatException e) {
- mNewKeySize = 0;
- }
-
- mNewKeyAlgorithmChoice = (Choice) algorithm.getSelectedItem();
- createKey();
- }
- });
-
- dialog.setCancelable(true);
- dialog.setNegativeButton(android.R.string.cancel,
- new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface di, int id) {
- di.dismiss();
- }
- });
-
- dialog.create().show();
+ });
+ mCreateKeyDialogFragment.show(mActivity.getSupportFragmentManager(), "createKeyDialog");
break;
}
@@ -382,7 +326,7 @@ public class SectionView extends LinearLayout implements OnClickListener, Editor
private void createKey() {
// Send all information needed to service to edit key in other thread
- Intent intent = new Intent(mActivity, KeychainIntentService.class);
+ final Intent intent = new Intent(mActivity, KeychainIntentService.class);
intent.setAction(KeychainIntentService.ACTION_GENERATE_KEY);
@@ -390,18 +334,18 @@ public class SectionView extends LinearLayout implements OnClickListener, Editor
Bundle data = new Bundle();
Boolean isMasterKey;
- String passPhrase;
+ String passphrase;
if (mEditors.getChildCount() > 0) {
PGPSecretKey masterKey = ((KeyEditor) mEditors.getChildAt(0)).getValue();
- passPhrase = PassphraseCacheService
+ passphrase = PassphraseCacheService
.getCachedPassphrase(mActivity, masterKey.getKeyID());
isMasterKey = false;
} else {
- passPhrase = "";
+ passphrase = "";
isMasterKey = true;
}
data.putBoolean(KeychainIntentService.GENERATE_KEY_MASTER_KEY, isMasterKey);
- data.putString(KeychainIntentService.GENERATE_KEY_SYMMETRIC_PASSPHRASE, passPhrase);
+ data.putString(KeychainIntentService.GENERATE_KEY_SYMMETRIC_PASSPHRASE, passphrase);
data.putInt(KeychainIntentService.GENERATE_KEY_ALGORITHM, mNewKeyAlgorithmChoice.getId());
data.putInt(KeychainIntentService.GENERATE_KEY_KEY_SIZE, mNewKeySize);
@@ -409,7 +353,12 @@ public class SectionView extends LinearLayout implements OnClickListener, Editor
// show progress dialog
mGeneratingDialog = ProgressDialogFragment.newInstance(R.string.progress_generating,
- ProgressDialog.STYLE_SPINNER);
+ ProgressDialog.STYLE_SPINNER, true, new DialogInterface.OnCancelListener() {
+ @Override
+ public void onCancel(DialogInterface dialog) {
+ mActivity.stopService(intent);
+ }
+ });
// Message is received after generating is done in ApgService
KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler(mActivity,
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/HkpKeyServer.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/HkpKeyServer.java
index 61fe13ffb..921d22f21 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/HkpKeyServer.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/HkpKeyServer.java
@@ -1,6 +1,8 @@
/*
+ * Copyright (C) 2012-2014 Dominik Schürmann <dominik@dominikschuermann.de>
+ * Copyright (C) 2011 Thialfihar <thi@thialfihar.org>
* Copyright (C) 2011 Senecaso
- *
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
@@ -32,6 +34,7 @@ import java.util.List;
import java.util.TimeZone;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+import java.util.Locale;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
@@ -172,11 +175,11 @@ public class HkpKeyServer extends KeyServer {
if (e.getCode() == 404) {
return results;
} else {
- if (e.getData().toLowerCase().contains("no keys found")) {
+ if (e.getData().toLowerCase(Locale.US).contains("no keys found")) {
return results;
- } else if (e.getData().toLowerCase().contains("too many")) {
+ } else if (e.getData().toLowerCase(Locale.US).contains("too many")) {
throw new TooManyResponses();
- } else if (e.getData().toLowerCase().contains("insufficient")) {
+ } else if (e.getData().toLowerCase(Locale.US).contains("insufficient")) {
throw new InsufficientQuery();
}
}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/KeyServer.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/KeyServer.java
index 072affb1f..7049820e8 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/KeyServer.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/KeyServer.java
@@ -1,6 +1,8 @@
/*
+ * Copyright (C) 2012-2014 Dominik Schürmann <dominik@dominikschuermann.de>
+ * Copyright (C) 2011 Thialfihar <thi@thialfihar.org>
* Copyright (C) 2011 Senecaso
- *
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
@@ -16,14 +18,8 @@
package org.sufficientlysecure.keychain.util;
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.Date;
import java.util.List;
-import android.os.Parcel;
-import android.os.Parcelable;
-
import org.sufficientlysecure.keychain.ui.adapter.ImportKeysListEntry;
public abstract class KeyServer {
@@ -52,5 +48,5 @@ public abstract class KeyServer {
abstract String get(long keyId) throws QueryException;
- abstract void add(String armouredText) throws AddKeyException;
+ abstract void add(String armoredText) throws AddKeyException;
}