aboutsummaryrefslogtreecommitdiffstats
path: root/OpenKeychain/src/main/java
diff options
context:
space:
mode:
Diffstat (limited to 'OpenKeychain/src/main/java')
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/Constants.java17
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/ImportExportOperation.java8
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/OperationResult.java78
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CanonicalizedSecretKey.java36
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CanonicalizedSecretKeyRing.java4
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpConstants.java106
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java30
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpHelper.java20
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java95
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncryptInput.java4
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncryptOperation.java18
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java2
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java3
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java16
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyActivity.java18
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyFinalFragment.java3
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyInputFragment.java3
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFragment.java25
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivityInterface.java1
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptFilesActivity.java39
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptTextActivity.java27
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/HelpActivity.java19
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java20
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/LogDisplayFragment.java198
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/PassphraseDialogActivity.java58
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectPublicKeyFragment.java9
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/SettingsActivity.java149
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java61
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvActivity.java9
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvShareFragment.java4
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvUserIdsFragment.java4
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyFragment.java4
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyTrustFragment.java7
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysAdapter.java5
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/SelectKeyCursorAdapter.java5
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/SubkeysAdapter.java4
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/UserIdsAdapter.java9
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/AddSubkeyDialogFragment.java12
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/CustomAlertDialogBuilder.java17
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteFileDialogFragment.java5
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteKeyDialogFragment.java17
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/EditSubkeyExpiryDialogFragment.java78
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/SetPassphraseDialogFragment.java1
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/util/KeyFormattingUtils.java80
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/CertifyKeySpinner.java7
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/EncryptKeyCompletionView.java2
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SignKeySpinner.java7
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/ContactHelper.java231
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/Preferences.java97
49 files changed, 919 insertions, 753 deletions
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/Constants.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/Constants.java
index 67fa30a44..30d855a74 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/Constants.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/Constants.java
@@ -19,6 +19,8 @@ package org.sufficientlysecure.keychain;
import android.os.Environment;
+import org.spongycastle.bcpg.HashAlgorithmTags;
+import org.spongycastle.bcpg.SymmetricKeyAlgorithmTags;
import org.spongycastle.jce.provider.BouncyCastleProvider;
import java.io.File;
@@ -26,6 +28,8 @@ import java.io.File;
public final class Constants {
public static final boolean DEBUG = BuildConfig.DEBUG;
+ public static final boolean DEBUG_LOG_DB_QUERIES = false;
+ public static final boolean DEBUG_SYNC_REMOVE_CONTACTS = false;
public static final String TAG = "Keychain";
@@ -33,6 +37,7 @@ public final class Constants {
public static final String ACCOUNT_NAME = "OpenKeychain";
public static final String ACCOUNT_TYPE = PACKAGE_NAME + ".account";
+ public static final String CUSTOM_CONTACT_DATA_MIME_TYPE = "vnd.android.cursor.item/vnd.org.sufficientlysecure.keychain.key";
// as defined in http://tools.ietf.org/html/rfc3156, section 7
public static final String NFC_MIME = "application/pgp-keys";
@@ -49,8 +54,6 @@ public final class Constants {
public static final String INTENT_PREFIX = PACKAGE_NAME + ".action.";
public static final String EXTRA_PREFIX = PACKAGE_NAME + ".";
- public static final String CUSTOM_CONTACT_DATA_MIME_TYPE = "vnd.android.cursor.item/vnd.org.sufficientlysecure.keychain.key";
-
public static final int TEMPFILE_TTL = 24 * 60 * 60 * 1000; // 1 day
public static final String SAFESLINGER_SERVER = "safeslinger-openpgp.appspot.com";
@@ -61,24 +64,17 @@ public final class Constants {
}
public static final class Pref {
- public static final String DEFAULT_ENCRYPTION_ALGORITHM = "defaultEncryptionAlgorithm";
- public static final String DEFAULT_HASH_ALGORITHM = "defaultHashAlgorithm";
- public static final String DEFAULT_ASCII_ARMOR = "defaultAsciiArmor";
- public static final String DEFAULT_MESSAGE_COMPRESSION = "defaultMessageCompression";
- public static final String DEFAULT_FILE_COMPRESSION = "defaultFileCompression";
public static final String PASSPHRASE_CACHE_TTL = "passphraseCacheTtl";
public static final String PASSPHRASE_CACHE_SUBS = "passphraseCacheSubs";
public static final String LANGUAGE = "language";
public static final String KEY_SERVERS = "keyServers";
public static final String PREF_DEFAULT_VERSION = "keyServersDefaultVersion";
- public static final String WRITE_VERSION_HEADER = "writeVersionHeader";
public static final String FIRST_TIME = "firstTime";
- public static final String SHOW_ADVANCED_TABS = "showAdvancedTabs";
public static final String CACHED_CONSOLIDATE = "cachedConsolidate";
public static final String SEARCH_KEYSERVER = "search_keyserver_pref";
public static final String SEARCH_KEYBASE = "search_keybase_pref";
public static final String USE_DEFAULT_YUBIKEY_PIN = "useDefaultYubikeyPin";
- public static final String USE_NUMKEYPAD_FOR_YUBIKEY_PIN="useNumKeypadForYubikeyPin";
+ public static final String USE_NUMKEYPAD_FOR_YUBIKEY_PIN = "useNumKeypadForYubikeyPin";
}
public static final class Defaults {
@@ -90,4 +86,5 @@ public final class Constants {
public static final int none = 0;
public static final int symmetric = -1;
}
+
}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/ImportExportOperation.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/ImportExportOperation.java
index 8f10377cd..20dba95e9 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/ImportExportOperation.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/ImportExportOperation.java
@@ -505,10 +505,6 @@ public class ImportExportOperation extends BaseOperation {
// Create an output stream
try {
arOutStream = new ArmoredOutputStream(outStream);
- String version = PgpHelper.getVersionForHeader(mContext);
- if (version != null) {
- arOutStream.setHeader("Version", version);
- }
log.add(LogType.MSG_EXPORT_PUBLIC, 1, KeyFormattingUtils.beautifyKeyId(keyId));
@@ -533,10 +529,6 @@ public class ImportExportOperation extends BaseOperation {
if (exportSecret && cursor.getInt(3) > 0) {
try {
arOutStream = new ArmoredOutputStream(outStream);
- String version = PgpHelper.getVersionForHeader(mContext);
- if (version != null) {
- arOutStream.setHeader("Version", version);
- }
// export secret key part
log.add(LogType.MSG_EXPORT_SECRET, 2, KeyFormattingUtils.beautifyKeyId(keyId));
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/OperationResult.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/OperationResult.java
index f79900aab..a96cec8cf 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/OperationResult.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/OperationResult.java
@@ -38,6 +38,8 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
+import java.util.UUID;
+import java.util.concurrent.ConcurrentHashMap;
/** Represent the result of an operation.
*
@@ -51,6 +53,56 @@ import java.util.List;
public abstract class OperationResult implements Parcelable {
public static final String EXTRA_RESULT = "operation_result";
+ public static final UUID NULL_UUID = new UUID(0,0);
+
+ /**
+ * A HashMap of UUID:OperationLog which contains logs that we don't need
+ * to care about. This is used such that when we become parceled, we are
+ * well below the 1Mbit boundary that is specified.
+ */
+ private static ConcurrentHashMap<UUID, OperationLog> dehydratedLogs;
+ static {
+ // Static initializer for ConcurrentHashMap
+ dehydratedLogs = new ConcurrentHashMap<UUID,OperationLog>();
+ }
+
+ /**
+ * Dehydrate a log (such that it is available after deparcelization)
+ *
+ * Returns the NULL uuid (0) if you hand it null.
+ * @param log An OperationLog to dehydrate
+ * @return a UUID, the ticket for your dehydrated log
+ *
+ */
+ private static UUID dehydrateLog(OperationLog log) {
+ if(log == null) {
+ return NULL_UUID;
+ }
+ else {
+ UUID ticket = UUID.randomUUID();
+ dehydratedLogs.put(ticket, log);
+ return ticket;
+ }
+ }
+
+ /***
+ * Rehydrate a log after going through parcelization, invalidating its place in the
+ * dehydration pool.
+ * This is used such that when parcelized, the parcel is no larger than 1mbit.
+ * @param ticket A UUID ticket that identifies the log in question.
+ * @return An OperationLog.
+ */
+ private static OperationLog rehydrateLog(UUID ticket) {
+ // UUID.equals isn't well documented; we use compareTo instead.
+ if( NULL_UUID.compareTo(ticket) == 0 ) {
+ return null;
+ }
+ else {
+ OperationLog log = dehydratedLogs.get(ticket);
+ dehydratedLogs.remove(ticket);
+ return log;
+ }
+ }
/** Holds the overall result, the number specifying varying degrees of success:
* - The first bit is 0 on overall success, 1 on overall failure
@@ -65,7 +117,7 @@ public abstract class OperationResult implements Parcelable {
public static final int RESULT_WARNINGS = 4;
/// A list of log entries tied to the operation result.
- final OperationLog mLog;
+ protected OperationLog mLog;
public OperationResult(int result, OperationLog log) {
mResult = result;
@@ -74,8 +126,11 @@ public abstract class OperationResult implements Parcelable {
public OperationResult(Parcel source) {
mResult = source.readInt();
- mLog = new OperationLog();
- mLog.addAll(source.createTypedArrayList(LogEntryParcel.CREATOR));
+ long mostSig = source.readLong();
+ long leastSig = source.readLong();
+ UUID mTicket = new UUID(mostSig, leastSig);
+ // fetch the dehydrated log out of storage (this removes it from the dehydration pool)
+ mLog = rehydrateLog(mTicket);
}
public int getResult() {
@@ -571,6 +626,7 @@ public abstract class OperationResult implements Parcelable {
MSG_DC_ERROR_NO_DATA (LogLevel.ERROR, R.string.msg_dc_error_no_data),
MSG_DC_ERROR_NO_KEY (LogLevel.ERROR, R.string.msg_dc_error_no_key),
MSG_DC_ERROR_PGP_EXCEPTION (LogLevel.ERROR, R.string.msg_dc_error_pgp_exception),
+ MSG_DC_ERROR_UNSUPPORTED_HASH_ALGO (LogLevel.ERROR, R.string.msg_dc_error_unsupported_hash_algo),
MSG_DC_INTEGRITY_CHECK_OK (LogLevel.INFO, R.string.msg_dc_integrity_check_ok),
MSG_DC_OK_META_ONLY (LogLevel.OK, R.string.msg_dc_ok_meta_only),
MSG_DC_OK (LogLevel.OK, R.string.msg_dc_ok),
@@ -585,6 +641,7 @@ public abstract class OperationResult implements Parcelable {
MSG_DC_TRAIL_SYM (LogLevel.DEBUG, R.string.msg_dc_trail_sym),
MSG_DC_TRAIL_UNKNOWN (LogLevel.DEBUG, R.string.msg_dc_trail_unknown),
MSG_DC_UNLOCKING (LogLevel.INFO, R.string.msg_dc_unlocking),
+ MSG_DC_OLD_SYMMETRIC_ENCRYPTION_ALGO (LogLevel.WARN, R.string.msg_dc_old_symmetric_encryption_algo),
// verify signed literal data
MSG_VL (LogLevel.INFO, R.string.msg_vl),
@@ -707,6 +764,13 @@ public abstract class OperationResult implements Parcelable {
MSG_DEL_CONSOLIDATE (LogLevel.DEBUG, R.string.msg_del_consolidate),
MSG_DEL_OK (LogLevel.OK, R.plurals.msg_del_ok),
MSG_DEL_FAIL (LogLevel.WARN, R.plurals.msg_del_fail),
+
+ //export log
+ MSG_EXPORT_LOG(LogLevel.START,R.string.msg_export_log_start),
+ MSG_EXPORT_LOG_EXPORT_ERROR_NO_FILE(LogLevel.ERROR,R.string.msg_export_log_error_no_file),
+ MSG_EXPORT_LOG_EXPORT_ERROR_FOPEN(LogLevel.ERROR,R.string.msg_export_log_error_fopen),
+ MSG_EXPORT_LOG_EXPORT_ERROR_WRITING(LogLevel.ERROR,R.string.msg_export_log_error_writing),
+ MSG_EXPORT_LOG_EXPORT_SUCCESS (LogLevel.OK, R.string.msg_export_log_success),
;
public final int mMsgId;
@@ -739,9 +803,11 @@ public abstract class OperationResult implements Parcelable {
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(mResult);
- if (mLog != null) {
- dest.writeTypedList(mLog.toList());
- }
+ // Get a ticket for our log.
+ UUID mTicket = dehydrateLog(mLog);
+ // And write out the UUID most and least significant bits.
+ dest.writeLong(mTicket.getMostSignificantBits());
+ dest.writeLong(mTicket.getLeastSignificantBits());
}
public static class OperationLog implements Iterable<LogEntryParcel> {
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CanonicalizedSecretKey.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CanonicalizedSecretKey.java
index 40f2f48ad..fe5db8c6d 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CanonicalizedSecretKey.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CanonicalizedSecretKey.java
@@ -20,6 +20,7 @@ package org.sufficientlysecure.keychain.pgp;
import org.spongycastle.bcpg.HashAlgorithmTags;
import org.spongycastle.bcpg.S2K;
+import org.spongycastle.bcpg.SymmetricKeyAlgorithmTags;
import org.spongycastle.openpgp.PGPException;
import org.spongycastle.openpgp.PGPPrivateKey;
import org.spongycastle.openpgp.PGPPublicKey;
@@ -44,6 +45,7 @@ import org.sufficientlysecure.keychain.pgp.exception.PgpKeyNotFoundException;
import org.sufficientlysecure.keychain.util.IterableIterator;
import org.sufficientlysecure.keychain.util.Log;
+import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedList;
@@ -137,7 +139,7 @@ public class CanonicalizedSecretKey extends CanonicalizedPublicKey {
// It means the passphrase is empty
return SecretKeyType.PASSPHRASE_EMPTY;
} catch (PGPException e) {
- HashMap<String,String> notation = getRing().getLocalNotationData();
+ HashMap<String, String> notation = getRing().getLocalNotationData();
if (notation.containsKey("unlock.pin@sufficientlysecure.org")
&& "1".equals(notation.get("unlock.pin@sufficientlysecure.org"))) {
return SecretKeyType.PIN;
@@ -176,33 +178,13 @@ public class CanonicalizedSecretKey extends CanonicalizedPublicKey {
}
/**
- * Returns a list of all supported hash algorithms. This list is currently hardcoded to return
- * a limited set of algorithms supported by Yubikeys.
- *
- * @return
+ * Returns a list of all supported hash algorithms.
*/
- public LinkedList<Integer> getSupportedHashAlgorithms() {
- LinkedList<Integer> supported = new LinkedList<>();
-
- if (mPrivateKeyState == PRIVATE_KEY_STATE_DIVERT_TO_CARD) {
- // No support for MD5
- supported.add(HashAlgorithmTags.RIPEMD160);
- supported.add(HashAlgorithmTags.SHA1);
- supported.add(HashAlgorithmTags.SHA224);
- supported.add(HashAlgorithmTags.SHA256);
- supported.add(HashAlgorithmTags.SHA384);
- supported.add(HashAlgorithmTags.SHA512); // preferred is latest
- } else {
- supported.add(HashAlgorithmTags.MD5);
- supported.add(HashAlgorithmTags.RIPEMD160);
- supported.add(HashAlgorithmTags.SHA1);
- supported.add(HashAlgorithmTags.SHA224);
- supported.add(HashAlgorithmTags.SHA256);
- supported.add(HashAlgorithmTags.SHA384);
- supported.add(HashAlgorithmTags.SHA512); // preferred is latest
- }
+ public ArrayList<Integer> getSupportedHashAlgorithms() {
+ // TODO: intersection between preferred hash algos of this key and PgpConstants.PREFERRED_HASH_ALGORITHMS
+ // choose best algo
- return supported;
+ return PgpConstants.sPreferredHashAlgorithms;
}
private PGPContentSignerBuilder getContentSignerBuilder(int hashAlgo, byte[] nfcSignedHash,
@@ -358,7 +340,7 @@ public class CanonicalizedSecretKey extends CanonicalizedPublicKey {
}
// HACK, for TESTING ONLY!!
- PGPPrivateKey getPrivateKey () {
+ PGPPrivateKey getPrivateKey() {
return mPrivateKey;
}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CanonicalizedSecretKeyRing.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CanonicalizedSecretKeyRing.java
index b5f6a5b09..97b5fa6fe 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CanonicalizedSecretKeyRing.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CanonicalizedSecretKeyRing.java
@@ -19,11 +19,11 @@
package org.sufficientlysecure.keychain.pgp;
import org.spongycastle.openpgp.PGPKeyRing;
-import org.spongycastle.openpgp.PGPObjectFactory;
import org.spongycastle.openpgp.PGPPublicKey;
import org.spongycastle.openpgp.PGPSecretKey;
import org.spongycastle.openpgp.PGPSecretKeyRing;
import org.spongycastle.openpgp.PGPSignature;
+import org.spongycastle.openpgp.jcajce.JcaPGPObjectFactory;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
import org.sufficientlysecure.keychain.util.IterableIterator;
@@ -45,7 +45,7 @@ public class CanonicalizedSecretKeyRing extends CanonicalizedKeyRing {
public CanonicalizedSecretKeyRing(byte[] blob, boolean isRevoked, int verified)
{
super(verified);
- PGPObjectFactory factory = new PGPObjectFactory(blob);
+ JcaPGPObjectFactory factory = new JcaPGPObjectFactory(blob);
PGPKeyRing keyRing = null;
try {
if ((keyRing = (PGPKeyRing) factory.nextObject()) == null) {
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpConstants.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpConstants.java
new file mode 100644
index 000000000..90991ba15
--- /dev/null
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpConstants.java
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2015 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 org.spongycastle.bcpg.CompressionAlgorithmTags;
+import org.spongycastle.bcpg.HashAlgorithmTags;
+import org.spongycastle.bcpg.SymmetricKeyAlgorithmTags;
+
+import java.util.ArrayList;
+
+public class PgpConstants {
+
+ public static ArrayList<Integer> sPreferredSymmetricAlgorithms = new ArrayList<>();
+ public static ArrayList<Integer> sPreferredHashAlgorithms = new ArrayList<>();
+ public static ArrayList<Integer> sPreferredCompressionAlgorithms = new ArrayList<>();
+
+ // TODO: use hashmaps for contains in O(1) and intersections!
+
+ /*
+ * Most preferred is first
+ * These arrays are written as preferred algorithms into the keys on creation.
+ * Other implementations may choose to honor this selection.
+ *
+ * These lists also define the only algorithms which are used in OpenKeychain.
+ * We do not support algorithms such as MD5
+ */
+ static {
+ sPreferredSymmetricAlgorithms.add(SymmetricKeyAlgorithmTags.AES_256);
+ sPreferredSymmetricAlgorithms.add(SymmetricKeyAlgorithmTags.AES_192);
+ sPreferredSymmetricAlgorithms.add(SymmetricKeyAlgorithmTags.AES_128);
+ sPreferredSymmetricAlgorithms.add(SymmetricKeyAlgorithmTags.TWOFISH);
+
+ // NOTE: some implementations do not support SHA512, thus we choose SHA256 as default (Mailvelope?)
+ sPreferredHashAlgorithms.add(HashAlgorithmTags.SHA256);
+ sPreferredHashAlgorithms.add(HashAlgorithmTags.SHA512);
+ sPreferredHashAlgorithms.add(HashAlgorithmTags.SHA384);
+ sPreferredHashAlgorithms.add(HashAlgorithmTags.SHA224);
+ sPreferredHashAlgorithms.add(HashAlgorithmTags.SHA1);
+ sPreferredHashAlgorithms.add(HashAlgorithmTags.RIPEMD160);
+
+ sPreferredCompressionAlgorithms.add(CompressionAlgorithmTags.ZLIB);
+ sPreferredCompressionAlgorithms.add(CompressionAlgorithmTags.BZIP2);
+ sPreferredCompressionAlgorithms.add(CompressionAlgorithmTags.ZIP);
+ }
+
+ /*
+ * Note: s2kcount is a number between 0 and 0xff that controls the
+ * number of times to iterate the password hash before use. More
+ * iterations are useful against offline attacks, as it takes more
+ * time to check each password. The actual number of iterations is
+ * rather complex, and also depends on the hash function in use.
+ * Refer to Section 3.7.1.3 in rfc4880.txt. Bigger numbers give
+ * you more iterations. As a rough rule of thumb, when using
+ * SHA256 as the hashing function, 0x10 gives you about 64
+ * iterations, 0x20 about 128, 0x30 about 256 and so on till 0xf0,
+ * or about 1 million iterations. The maximum you can go to is
+ * 0xff, or about 2 million iterations.
+ * from http://kbsriram.com/2013/01/generating-rsa-keys-with-bouncycastle.html
+ *
+ * Bouncy Castle default: 0x60
+ * kbsriram proposes: 0xc0
+ * OpenKeychain: 0x90
+ */
+ public static final int SECRET_KEY_ENCRYPTOR_S2K_COUNT = 0x90;
+ public static final int SECRET_KEY_ENCRYPTOR_HASH_ALGO = HashAlgorithmTags.SHA256;
+ public static final int SECRET_KEY_ENCRYPTOR_SYMMETRIC_ALGO = SymmetricKeyAlgorithmTags.AES_256;
+ public static final int SECRET_KEY_SIGNATURE_HASH_ALGO = HashAlgorithmTags.SHA256;
+ // NOTE: only SHA1 is supported for key checksum calculations in OpenPGP,
+ // see http://tools.ietf.org/html/rfc488 0#section-5.5.3
+ public static final int SECRET_KEY_SIGNATURE_CHECKSUM_HASH_ALGO = HashAlgorithmTags.SHA1;
+
+ public static interface OpenKeychainSymmetricKeyAlgorithmTags extends SymmetricKeyAlgorithmTags {
+ public static final int USE_PREFERRED = -1;
+ }
+
+ public static interface OpenKeychainHashAlgorithmTags extends HashAlgorithmTags {
+ public static final int USE_PREFERRED = -1;
+ }
+
+ public static interface OpenKeychainCompressionAlgorithmTags extends CompressionAlgorithmTags {
+ public static final int USE_PREFERRED = -1;
+ }
+
+ public static int[] getAsArray(ArrayList<Integer> list) {
+ int[] array = new int[list.size()];
+ for (int i = 0; i < list.size(); i++) {
+ array[i] = list.get(i);
+ }
+ return array;
+ }
+}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java
index 2ba0b6231..14bc56538 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java
@@ -563,6 +563,7 @@ public class PgpDecryptVerify extends BaseOperation {
log.add(LogType.MSG_DC_PREP_STREAMS, indent);
// we made sure above one of these two would be true
+ int symmetricEncryptionAlgo;
if (symmetricPacketFound) {
currentProgress += 2;
updateProgress(R.string.progress_preparing_streams, currentProgress, 100);
@@ -576,6 +577,7 @@ public class PgpDecryptVerify extends BaseOperation {
clear = encryptedDataSymmetric.getDataStream(decryptorFactory);
encryptedData = encryptedDataSymmetric;
+ symmetricEncryptionAlgo = encryptedDataSymmetric.getSymmetricAlgorithm(decryptorFactory);
} else if (asymmetricPacketFound) {
currentProgress += 2;
updateProgress(R.string.progress_extracting_key, currentProgress, 100);
@@ -598,6 +600,8 @@ public class PgpDecryptVerify extends BaseOperation {
PublicKeyDataDecryptorFactory decryptorFactory
= secretEncryptionKey.getDecryptorFactory(mDecryptedSessionKey);
clear = encryptedDataAsymmetric.getDataStream(decryptorFactory);
+
+ symmetricEncryptionAlgo = encryptedDataAsymmetric.getSymmetricAlgorithm(decryptorFactory);
} catch (NfcSyncPublicKeyDataDecryptorFactoryBuilder.NfcInteractionNeeded e) {
log.add(LogType.MSG_DC_PENDING_NFC, indent + 1);
DecryptVerifyResult result =
@@ -614,6 +618,11 @@ public class PgpDecryptVerify extends BaseOperation {
return new DecryptVerifyResult(DecryptVerifyResult.RESULT_ERROR, log);
}
+ // Warn about old encryption algorithms!
+ if (!PgpConstants.sPreferredSymmetricAlgorithms.contains(symmetricEncryptionAlgo)) {
+ log.add(LogType.MSG_DC_OLD_SYMMETRIC_ENCRYPTION_ALGO, indent + 1);
+ }
+
JcaPGPObjectFactory plainFact = new JcaPGPObjectFactory(clear);
Object dataChunk = plainFact.nextObject();
OpenPgpSignatureResultBuilder signatureResultBuilder = new OpenPgpSignatureResultBuilder();
@@ -811,6 +820,13 @@ public class PgpDecryptVerify extends BaseOperation {
} else {
log.add(LogType.MSG_DC_CLEAR_SIGNATURE_BAD, indent + 1);
}
+
+ // Don't allow verification of old hash algorithms!
+ if (!PgpConstants.sPreferredHashAlgorithms.contains(signature.getHashAlgorithm())) {
+ validSignature = false;
+ log.add(LogType.MSG_DC_ERROR_UNSUPPORTED_HASH_ALGO, indent + 1);
+ }
+
signatureResultBuilder.setValidSignature(validSignature);
}
@@ -936,6 +952,13 @@ public class PgpDecryptVerify extends BaseOperation {
} else {
log.add(LogType.MSG_DC_CLEAR_SIGNATURE_BAD, indent + 1);
}
+
+ // Don't allow verification of old hash algorithms!
+ if (!PgpConstants.sPreferredHashAlgorithms.contains(signature.getHashAlgorithm())) {
+ validSignature = false;
+ log.add(LogType.MSG_DC_ERROR_UNSUPPORTED_HASH_ALGO, indent + 1);
+ }
+
signatureResultBuilder.setValidSignature(validSignature);
} catch (SignatureException e) {
@@ -1024,6 +1047,13 @@ public class PgpDecryptVerify extends BaseOperation {
} else {
log.add(LogType.MSG_DC_CLEAR_SIGNATURE_BAD, indent + 1);
}
+
+ // Don't allow verification of old hash algorithms!
+ if (!PgpConstants.sPreferredHashAlgorithms.contains(signature.getHashAlgorithm())) {
+ validSignature = false;
+ log.add(LogType.MSG_DC_ERROR_UNSUPPORTED_HASH_ALGO, indent + 1);
+ }
+
signatureResultBuilder.setValidSignature(validSignature);
}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpHelper.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpHelper.java
index 12de2f637..d8b86a18c 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpHelper.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpHelper.java
@@ -47,26 +47,6 @@ public class PgpHelper {
".*?(-----BEGIN PGP PUBLIC KEY BLOCK-----.*?-----END PGP PUBLIC KEY BLOCK-----).*",
Pattern.DOTALL);
- public static String getVersion(Context context) {
- String version;
- try {
- PackageInfo pi = context.getPackageManager().getPackageInfo(Constants.PACKAGE_NAME, 0);
- version = pi.versionName;
- return version;
- } catch (NameNotFoundException e) {
- Log.e(Constants.TAG, "Version could not be retrieved!", e);
- return "0.0";
- }
- }
-
- public static String getVersionForHeader(Context context) {
- if(Preferences.getPreferences(context).getWriteVersionHeader()){
- return "OpenKeychain v" + getVersion(context);
- } else {
- return null;
- }
- }
-
/**
* Deletes file securely by overwriting it with random data before deleting it.
* <p/>
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java
index 1a251eb79..8fb5392e3 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java
@@ -18,9 +18,7 @@
package org.sufficientlysecure.keychain.pgp;
-import org.spongycastle.bcpg.CompressionAlgorithmTags;
import org.spongycastle.bcpg.HashAlgorithmTags;
-import org.spongycastle.bcpg.SymmetricKeyAlgorithmTags;
import org.spongycastle.bcpg.sig.Features;
import org.spongycastle.bcpg.sig.KeyFlags;
import org.spongycastle.jce.spec.ElGamalParameterSpec;
@@ -90,48 +88,6 @@ public class PgpKeyOperation {
private Stack<Progressable> mProgress;
private AtomicBoolean mCancelled;
- // most preferred is first
- private static final int[] PREFERRED_SYMMETRIC_ALGORITHMS = new int[]{
- SymmetricKeyAlgorithmTags.AES_256,
- SymmetricKeyAlgorithmTags.AES_192,
- SymmetricKeyAlgorithmTags.AES_128,
- SymmetricKeyAlgorithmTags.CAST5
- };
- private static final int[] PREFERRED_HASH_ALGORITHMS = new int[]{
- HashAlgorithmTags.SHA512,
- HashAlgorithmTags.SHA384,
- HashAlgorithmTags.SHA224,
- HashAlgorithmTags.SHA256,
- HashAlgorithmTags.RIPEMD160
- };
- private static final int[] PREFERRED_COMPRESSION_ALGORITHMS = new int[]{
- CompressionAlgorithmTags.ZLIB,
- CompressionAlgorithmTags.BZIP2,
- CompressionAlgorithmTags.ZIP
- };
-
- /*
- * Note: s2kcount is a number between 0 and 0xff that controls the
- * number of times to iterate the password hash before use. More
- * iterations are useful against offline attacks, as it takes more
- * time to check each password. The actual number of iterations is
- * rather complex, and also depends on the hash function in use.
- * Refer to Section 3.7.1.3 in rfc4880.txt. Bigger numbers give
- * you more iterations. As a rough rule of thumb, when using
- * SHA256 as the hashing function, 0x10 gives you about 64
- * iterations, 0x20 about 128, 0x30 about 256 and so on till 0xf0,
- * or about 1 million iterations. The maximum you can go to is
- * 0xff, or about 2 million iterations.
- * from http://kbsriram.com/2013/01/generating-rsa-keys-with-bouncycastle.html
- *
- * Bouncy Castle default: 0x60
- * kbsriram proposes 0xc0
- * we use 0x90, a good trade-off between usability and security against offline attacks
- */
- private static final int SECRET_KEY_ENCRYPTOR_S2K_COUNT = 0x90;
- private static final int SECRET_KEY_ENCRYPTOR_HASH_ALGO = HashAlgorithmTags.SHA256;
- private static final int SECRET_KEY_ENCRYPTOR_SYMMETRIC_ALGO = SymmetricKeyAlgorithmTags.AES_256;
-
public PgpKeyOperation(Progressable progress) {
super();
if (progress != null) {
@@ -345,14 +301,14 @@ public class PgpKeyOperation {
// Build key encrypter and decrypter based on passphrase
PGPDigestCalculator encryptorHashCalc = new JcaPGPDigestCalculatorProviderBuilder()
- .build().get(SECRET_KEY_ENCRYPTOR_HASH_ALGO);
+ .build().get(PgpConstants.SECRET_KEY_ENCRYPTOR_HASH_ALGO);
PBESecretKeyEncryptor keyEncryptor = new JcePBESecretKeyEncryptorBuilder(
- SECRET_KEY_ENCRYPTOR_SYMMETRIC_ALGO, encryptorHashCalc, SECRET_KEY_ENCRYPTOR_S2K_COUNT)
+ PgpConstants.SECRET_KEY_ENCRYPTOR_SYMMETRIC_ALGO,
+ encryptorHashCalc, PgpConstants.SECRET_KEY_ENCRYPTOR_S2K_COUNT)
.setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build("".toCharArray());
- // NOTE: only SHA1 is supported for key checksum calculations.
PGPDigestCalculator sha1Calc = new JcaPGPDigestCalculatorProviderBuilder()
- .build().get(HashAlgorithmTags.SHA1);
+ .build().get(PgpConstants.SECRET_KEY_SIGNATURE_CHECKSUM_HASH_ALGO);
PGPSecretKey masterSecretKey = new PGPSecretKey(keyPair.getPrivateKey(), keyPair.getPublicKey(),
sha1Calc, true, keyEncryptor);
@@ -879,14 +835,14 @@ public class PgpKeyOperation {
PGPSecretKey sKey; {
// Build key encrypter and decrypter based on passphrase
PGPDigestCalculator encryptorHashCalc = new JcaPGPDigestCalculatorProviderBuilder()
- .build().get(SECRET_KEY_ENCRYPTOR_HASH_ALGO);
+ .build().get(PgpConstants.SECRET_KEY_ENCRYPTOR_HASH_ALGO);
PBESecretKeyEncryptor keyEncryptor = new JcePBESecretKeyEncryptorBuilder(
- SECRET_KEY_ENCRYPTOR_SYMMETRIC_ALGO, encryptorHashCalc, SECRET_KEY_ENCRYPTOR_S2K_COUNT)
+ PgpConstants.SECRET_KEY_ENCRYPTOR_SYMMETRIC_ALGO, encryptorHashCalc,
+ PgpConstants.SECRET_KEY_ENCRYPTOR_S2K_COUNT)
.setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(passphrase.toCharArray());
- // NOTE: only SHA1 is supported for key checksum calculations.
PGPDigestCalculator sha1Calc = new JcaPGPDigestCalculatorProviderBuilder()
- .build().get(HashAlgorithmTags.SHA1);
+ .build().get(PgpConstants.SECRET_KEY_SIGNATURE_CHECKSUM_HASH_ALGO);
sKey = new PGPSecretKey(keyPair.getPrivateKey(), pKey, sha1Calc, false, keyEncryptor);
}
@@ -1025,7 +981,8 @@ public class PgpKeyOperation {
// add packet with EMPTY notation data (updates old one, but will be stripped later)
PGPContentSignerBuilder signerBuilder = new JcaPGPContentSignerBuilder(
- masterPrivateKey.getPublicKeyPacket().getAlgorithm(), HashAlgorithmTags.SHA512)
+ masterPrivateKey.getPublicKeyPacket().getAlgorithm(),
+ PgpConstants.SECRET_KEY_SIGNATURE_HASH_ALGO)
.setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME);
PGPSignatureGenerator sGen = new PGPSignatureGenerator(signerBuilder);
{ // set subpackets
@@ -1051,7 +1008,8 @@ public class PgpKeyOperation {
// add packet with "pin" notation data
PGPContentSignerBuilder signerBuilder = new JcaPGPContentSignerBuilder(
- masterPrivateKey.getPublicKeyPacket().getAlgorithm(), HashAlgorithmTags.SHA512)
+ masterPrivateKey.getPublicKeyPacket().getAlgorithm(),
+ PgpConstants.SECRET_KEY_SIGNATURE_HASH_ALGO)
.setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME);
PGPSignatureGenerator sGen = new PGPSignatureGenerator(signerBuilder);
{ // set subpackets
@@ -1098,12 +1056,13 @@ public class PgpKeyOperation {
OperationLog log, int indent) throws PGPException {
PGPDigestCalculator encryptorHashCalc = new JcaPGPDigestCalculatorProviderBuilder().build()
- .get(SECRET_KEY_ENCRYPTOR_HASH_ALGO);
+ .get(PgpConstants.SECRET_KEY_ENCRYPTOR_HASH_ALGO);
PBESecretKeyDecryptor keyDecryptor = new JcePBESecretKeyDecryptorBuilder().setProvider(
Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(passphrase.toCharArray());
// Build key encryptor based on new passphrase
PBESecretKeyEncryptor keyEncryptorNew = new JcePBESecretKeyEncryptorBuilder(
- SECRET_KEY_ENCRYPTOR_SYMMETRIC_ALGO, encryptorHashCalc, SECRET_KEY_ENCRYPTOR_S2K_COUNT)
+ PgpConstants.SECRET_KEY_ENCRYPTOR_SYMMETRIC_ALGO, encryptorHashCalc,
+ PgpConstants.SECRET_KEY_ENCRYPTOR_S2K_COUNT)
.setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(
newPassphrase.toCharArray());
@@ -1236,7 +1195,8 @@ public class PgpKeyOperation {
int flags, long expiry)
throws IOException, PGPException, SignatureException {
PGPContentSignerBuilder signerBuilder = new JcaPGPContentSignerBuilder(
- masterPrivateKey.getPublicKeyPacket().getAlgorithm(), HashAlgorithmTags.SHA512)
+ masterPrivateKey.getPublicKeyPacket().getAlgorithm(),
+ PgpConstants.SECRET_KEY_SIGNATURE_HASH_ALGO)
.setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME);
PGPSignatureGenerator sGen = new PGPSignatureGenerator(signerBuilder);
@@ -1253,9 +1213,12 @@ public class PgpKeyOperation {
* error than be ignored.
*/
/* non-critical subpackets: */
- hashedPacketsGen.setPreferredSymmetricAlgorithms(false, PREFERRED_SYMMETRIC_ALGORITHMS);
- hashedPacketsGen.setPreferredHashAlgorithms(false, PREFERRED_HASH_ALGORITHMS);
- hashedPacketsGen.setPreferredCompressionAlgorithms(false, PREFERRED_COMPRESSION_ALGORITHMS);
+ hashedPacketsGen.setPreferredSymmetricAlgorithms(false,
+ PgpConstants.getAsArray(PgpConstants.sPreferredSymmetricAlgorithms));
+ hashedPacketsGen.setPreferredHashAlgorithms(false,
+ PgpConstants.getAsArray(PgpConstants.sPreferredHashAlgorithms));
+ hashedPacketsGen.setPreferredCompressionAlgorithms(false,
+ PgpConstants.getAsArray(PgpConstants.sPreferredCompressionAlgorithms));
hashedPacketsGen.setPrimaryUserID(false, primary);
/* critical subpackets: we consider those important for a modern pgp implementation */
@@ -1279,7 +1242,8 @@ public class PgpKeyOperation {
PGPUserAttributeSubpacketVector vector)
throws IOException, PGPException, SignatureException {
PGPContentSignerBuilder signerBuilder = new JcaPGPContentSignerBuilder(
- masterPrivateKey.getPublicKeyPacket().getAlgorithm(), HashAlgorithmTags.SHA512)
+ masterPrivateKey.getPublicKeyPacket().getAlgorithm(),
+ PgpConstants.SECRET_KEY_SIGNATURE_HASH_ALGO)
.setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME);
PGPSignatureGenerator sGen = new PGPSignatureGenerator(signerBuilder);
@@ -1298,7 +1262,8 @@ public class PgpKeyOperation {
PGPPrivateKey masterPrivateKey, PGPPublicKey pKey, String userId)
throws IOException, PGPException, SignatureException {
PGPContentSignerBuilder signerBuilder = new JcaPGPContentSignerBuilder(
- masterPrivateKey.getPublicKeyPacket().getAlgorithm(), HashAlgorithmTags.SHA512)
+ masterPrivateKey.getPublicKeyPacket().getAlgorithm(),
+ PgpConstants.SECRET_KEY_SIGNATURE_HASH_ALGO)
.setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME);
PGPSignatureGenerator sGen = new PGPSignatureGenerator(signerBuilder);
PGPSignatureSubpacketGenerator subHashedPacketsGen = new PGPSignatureSubpacketGenerator();
@@ -1312,7 +1277,7 @@ public class PgpKeyOperation {
PGPPublicKey masterPublicKey, PGPPrivateKey masterPrivateKey, PGPPublicKey pKey)
throws IOException, PGPException, SignatureException {
PGPContentSignerBuilder signerBuilder = new JcaPGPContentSignerBuilder(
- masterPublicKey.getAlgorithm(), HashAlgorithmTags.SHA512)
+ masterPublicKey.getAlgorithm(), PgpConstants.SECRET_KEY_SIGNATURE_HASH_ALGO)
.setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME);
PGPSignatureGenerator sGen = new PGPSignatureGenerator(signerBuilder);
PGPSignatureSubpacketGenerator subHashedPacketsGen = new PGPSignatureSubpacketGenerator();
@@ -1356,7 +1321,7 @@ public class PgpKeyOperation {
PGPSignatureSubpacketGenerator subHashedPacketsGen = new PGPSignatureSubpacketGenerator();
subHashedPacketsGen.setSignatureCreationTime(false, creationTime);
PGPContentSignerBuilder signerBuilder = new JcaPGPContentSignerBuilder(
- pKey.getAlgorithm(), HashAlgorithmTags.SHA512)
+ pKey.getAlgorithm(), PgpConstants.SECRET_KEY_SIGNATURE_HASH_ALGO)
.setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME);
PGPSignatureGenerator sGen = new PGPSignatureGenerator(signerBuilder);
sGen.init(PGPSignature.PRIMARYKEY_BINDING, subPrivateKey);
@@ -1377,7 +1342,7 @@ public class PgpKeyOperation {
}
PGPContentSignerBuilder signerBuilder = new JcaPGPContentSignerBuilder(
- masterPublicKey.getAlgorithm(), HashAlgorithmTags.SHA512)
+ masterPublicKey.getAlgorithm(), PgpConstants.SECRET_KEY_SIGNATURE_HASH_ALGO)
.setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME);
PGPSignatureGenerator sGen = new PGPSignatureGenerator(signerBuilder);
sGen.init(PGPSignature.SUBKEY_BINDING, masterPrivateKey);
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncryptInput.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncryptInput.java
index 9318be006..1ed0a4720 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncryptInput.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncryptInput.java
@@ -12,10 +12,10 @@ public class PgpSignEncryptInput {
protected int mCompressionId = CompressionAlgorithmTags.UNCOMPRESSED;
protected long[] mEncryptionMasterKeyIds = null;
protected String mSymmetricPassphrase = null;
- protected int mSymmetricEncryptionAlgorithm = 0;
+ protected int mSymmetricEncryptionAlgorithm = PgpConstants.OpenKeychainSymmetricKeyAlgorithmTags.USE_PREFERRED;
protected long mSignatureMasterKeyId = Constants.key.none;
protected Long mSignatureSubKeyId = null;
- protected int mSignatureHashAlgorithm = 0;
+ protected int mSignatureHashAlgorithm = PgpConstants.OpenKeychainHashAlgorithmTags.USE_PREFERRED;
protected String mSignaturePassphrase = null;
protected long mAdditionalEncryptId = Constants.key.none;
protected byte[] mNfcSignedHash = null;
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncryptOperation.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncryptOperation.java
index 2fa01d241..81cc2c847 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncryptOperation.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncryptOperation.java
@@ -25,7 +25,6 @@ import org.spongycastle.bcpg.ArmoredOutputStream;
import org.spongycastle.bcpg.BCPGOutputStream;
import org.spongycastle.bcpg.CompressionAlgorithmTags;
import org.spongycastle.openpgp.PGPCompressedDataGenerator;
-import org.spongycastle.openpgp.PGPEncryptedData;
import org.spongycastle.openpgp.PGPEncryptedDataGenerator;
import org.spongycastle.openpgp.PGPException;
import org.spongycastle.openpgp.PGPLiteralData;
@@ -58,6 +57,7 @@ import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.security.SignatureException;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.LinkedList;
@@ -206,12 +206,12 @@ public class PgpSignEncryptOperation extends BaseOperation {
return new PgpSignEncryptResult(PgpSignEncryptResult.RESULT_ERROR, log);
}
- // check if hash algo is supported
+ // Use preferred hash algo
int requestedAlgorithm = input.getSignatureHashAlgorithm();
- LinkedList<Integer> supported = signingKey.getSupportedHashAlgorithms();
- if (requestedAlgorithm == 0) {
+ ArrayList<Integer> supported = signingKey.getSupportedHashAlgorithms();
+ if (requestedAlgorithm == PgpConstants.OpenKeychainHashAlgorithmTags.USE_PREFERRED) {
// get most preferred
- input.setSignatureHashAlgorithm(supported.getLast());
+ input.setSignatureHashAlgorithm(supported.get(0));
} else if (!supported.contains(requestedAlgorithm)) {
log.add(LogType.MSG_PSE_ERROR_HASH_ALGO, indent);
return new PgpSignEncryptResult(PgpSignEncryptResult.RESULT_ERROR, log);
@@ -222,9 +222,13 @@ public class PgpSignEncryptOperation extends BaseOperation {
/* Initialize PGPEncryptedDataGenerator for later usage */
PGPEncryptedDataGenerator cPk = null;
if (enableEncryption) {
+
+ // Use preferred encryption algo
int algo = input.getSymmetricEncryptionAlgorithm();
- if (algo == 0) {
- algo = PGPEncryptedData.AES_128;
+ if (algo == PgpConstants.OpenKeychainSymmetricKeyAlgorithmTags.USE_PREFERRED) {
+ // get most preferred
+ // TODO: get from recipients
+ algo = PgpConstants.sPreferredSymmetricAlgorithms.get(0);
}
// has Integrity packet enabled!
JcePGPDataEncryptorBuilder encryptorBuilder =
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java
index 2601c1f69..4ccfc3cd9 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java
@@ -650,7 +650,7 @@ public class KeychainProvider extends ContentProvider {
cursor.setNotificationUri(getContext().getContentResolver(), uri);
}
- if (Constants.DEBUG) {
+ if (Constants.DEBUG && Constants.DEBUG_LOG_DB_QUERIES) {
Log.d(Constants.TAG,
"Query: "
+ qb.buildQuery(projection, selection, selectionArgs, null, null,
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java
index d947ae053..6366e8536 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java
@@ -1372,8 +1372,7 @@ public class ProviderHelper {
UncachedKeyRing keyRing = UncachedKeyRing.decodeFromData(data);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
- String version = PgpHelper.getVersionForHeader(mContext);
- keyRing.encodeArmored(bos, version);
+ keyRing.encodeArmored(bos, null);
String armoredKey = bos.toString("UTF-8");
Log.d(Constants.TAG, "armoredKey:" + armoredKey);
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java
index 1a65b1bee..03fa41984 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java
@@ -30,13 +30,16 @@ import org.openintents.openpgp.OpenPgpError;
import org.openintents.openpgp.OpenPgpMetadata;
import org.openintents.openpgp.OpenPgpSignatureResult;
import org.openintents.openpgp.util.OpenPgpApi;
+import org.spongycastle.bcpg.CompressionAlgorithmTags;
import org.spongycastle.util.encoders.Hex;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.operations.results.DecryptVerifyResult;
import org.sufficientlysecure.keychain.operations.results.OperationResult.LogEntryParcel;
import org.sufficientlysecure.keychain.operations.results.PgpSignEncryptResult;
+import org.sufficientlysecure.keychain.pgp.PgpConstants;
import org.sufficientlysecure.keychain.pgp.PgpDecryptVerify;
import org.sufficientlysecure.keychain.pgp.PgpHelper;
+import org.sufficientlysecure.keychain.pgp.PgpKeyOperation;
import org.sufficientlysecure.keychain.pgp.PgpSignEncryptInput;
import org.sufficientlysecure.keychain.pgp.PgpSignEncryptOperation;
import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
@@ -52,6 +55,7 @@ import org.sufficientlysecure.keychain.ui.PassphraseDialogActivity;
import org.sufficientlysecure.keychain.ui.ViewKeyActivity;
import org.sufficientlysecure.keychain.util.InputData;
import org.sufficientlysecure.keychain.util.Log;
+import org.sufficientlysecure.keychain.util.Preferences;
import java.io.IOException;
import java.io.InputStream;
@@ -258,8 +262,8 @@ public class OpenPgpService extends RemoteService {
.setEnableAsciiArmorOutput(asciiArmor)
.setCleartextSignature(cleartextSign)
.setDetachedSignature(!cleartextSign)
- .setVersionHeader(PgpHelper.getVersionForHeader(this))
- .setSignatureHashAlgorithm(accSettings.getHashAlgorithm())
+ .setVersionHeader(null)
+ .setSignatureHashAlgorithm(PgpConstants.OpenKeychainHashAlgorithmTags.USE_PREFERRED)
.setSignatureMasterKeyId(accSettings.getKeyId())
.setNfcState(nfcSignedHash, nfcCreationDate);
@@ -356,9 +360,9 @@ public class OpenPgpService extends RemoteService {
PgpSignEncryptInput pseInput = new PgpSignEncryptInput();
pseInput.setEnableAsciiArmorOutput(asciiArmor)
- .setVersionHeader(PgpHelper.getVersionForHeader(this))
- .setCompressionId(accSettings.getCompression())
- .setSymmetricEncryptionAlgorithm(accSettings.getEncryptionAlgorithm())
+ .setVersionHeader(null)
+ .setCompressionId(CompressionAlgorithmTags.UNCOMPRESSED)
+ .setSymmetricEncryptionAlgorithm(PgpConstants.OpenKeychainSymmetricKeyAlgorithmTags.USE_PREFERRED)
.setEncryptionMasterKeyIds(keyIds)
.setFailOnMissingEncryptionKeyIds(true)
.setAdditionalEncryptId(accSettings.getKeyId()); // add acc key for encryption
@@ -374,7 +378,7 @@ public class OpenPgpService extends RemoteService {
}
// sign and encrypt
- pseInput.setSignatureHashAlgorithm(accSettings.getHashAlgorithm())
+ pseInput.setSignatureHashAlgorithm(PgpConstants.OpenKeychainHashAlgorithmTags.USE_PREFERRED)
.setSignatureMasterKeyId(accSettings.getKeyId())
.setNfcState(nfcSignedHash, nfcCreationDate);
}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyActivity.java
index 62c38d136..60cc404b6 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyActivity.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyActivity.java
@@ -28,9 +28,11 @@ public class CreateKeyActivity extends BaseActivity {
public static final String EXTRA_NAME = "name";
public static final String EXTRA_EMAIL = "email";
- public static final int FRAG_ACTION_START = 0;
- public static final int FRAG_ACTION_TO_RIGHT = 1;
- public static final int FRAG_ACTION_TO_LEFT = 2;
+ public static enum FragAction {
+ START,
+ TO_RIGHT,
+ TO_LEFT
+ }
@Override
public void onCreate(Bundle savedInstanceState) {
@@ -42,7 +44,7 @@ public class CreateKeyActivity extends BaseActivity {
getIntent().getStringExtra(EXTRA_NAME),
getIntent().getStringExtra(EXTRA_EMAIL)
);
- loadFragment(null, frag, FRAG_ACTION_START);
+ loadFragment(null, frag, FragAction.START);
}
@Override
@@ -50,7 +52,7 @@ public class CreateKeyActivity extends BaseActivity {
setContentView(R.layout.create_key_activity);
}
- public void loadFragment(Bundle savedInstanceState, Fragment fragment, int action) {
+ public void loadFragment(Bundle savedInstanceState, Fragment fragment, FragAction action) {
// However, if we're being restored from a previous state,
// then we don't need to do anything and should return or else
// we could end up with overlapping fragments.
@@ -63,15 +65,15 @@ public class CreateKeyActivity extends BaseActivity {
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
switch (action) {
- case FRAG_ACTION_START:
+ case START:
transaction.setCustomAnimations(0, 0);
transaction.replace(R.id.create_key_fragment_container, fragment)
.commitAllowingStateLoss();
break;
- case FRAG_ACTION_TO_LEFT:
+ case TO_LEFT:
getSupportFragmentManager().popBackStackImmediate();
break;
- case FRAG_ACTION_TO_RIGHT:
+ case TO_RIGHT:
transaction.setCustomAnimations(R.anim.frag_slide_in_from_right, R.anim.frag_slide_out_to_left,
R.anim.frag_slide_in_from_left, R.anim.frag_slide_out_to_right);
transaction.addToBackStack(null);
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyFinalFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyFinalFragment.java
index 6e0115342..920488e3e 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyFinalFragment.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyFinalFragment.java
@@ -43,6 +43,7 @@ import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler;
import org.sufficientlysecure.keychain.service.SaveKeyringParcel;
import org.sufficientlysecure.keychain.service.SaveKeyringParcel.Algorithm;
import org.sufficientlysecure.keychain.service.SaveKeyringParcel.ChangeUnlockParcel;
+import org.sufficientlysecure.keychain.ui.CreateKeyActivity.FragAction;
import org.sufficientlysecure.keychain.util.Log;
import org.sufficientlysecure.keychain.util.Preferences;
@@ -117,7 +118,7 @@ public class CreateKeyFinalFragment extends Fragment {
mBackButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
- mCreateKeyActivity.loadFragment(null, null, CreateKeyActivity.FRAG_ACTION_TO_LEFT);
+ mCreateKeyActivity.loadFragment(null, null, FragAction.TO_LEFT);
}
});
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyInputFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyInputFragment.java
index 091418304..115614808 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyInputFragment.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyInputFragment.java
@@ -32,6 +32,7 @@ import android.widget.AutoCompleteTextView;
import android.widget.EditText;
import org.sufficientlysecure.keychain.R;
+import org.sufficientlysecure.keychain.ui.CreateKeyActivity.FragAction;
import org.sufficientlysecure.keychain.ui.widget.passwordstrengthindicator.PasswordStrengthView;
import org.sufficientlysecure.keychain.util.ContactHelper;
@@ -187,7 +188,7 @@ public class CreateKeyInputFragment extends Fragment {
);
hideKeyboard();
- mCreateKeyActivity.loadFragment(null, frag, CreateKeyActivity.FRAG_ACTION_TO_RIGHT);
+ mCreateKeyActivity.loadFragment(null, frag, FragAction.TO_RIGHT);
}
}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFragment.java
index 8723c7255..60103f344 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFragment.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFragment.java
@@ -31,6 +31,7 @@ import org.sufficientlysecure.keychain.operations.results.DecryptVerifyResult;
import org.sufficientlysecure.keychain.pgp.KeyRing;
import org.sufficientlysecure.keychain.provider.KeychainContract;
import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
+import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils.State;
public abstract class DecryptFragment extends Fragment {
private static final int RESULT_CODE_LOOKUP_KEY = 0x00007006;
@@ -141,16 +142,16 @@ public abstract class DecryptFragment extends Fragment {
if (signatureResult.isSignatureOnly()) {
mEncryptionText.setText(R.string.decrypt_result_not_encrypted);
- KeyFormattingUtils.setStatusImage(getActivity(), mEncryptionIcon, mEncryptionText, KeyFormattingUtils.STATE_NOT_ENCRYPTED);
+ KeyFormattingUtils.setStatusImage(getActivity(), mEncryptionIcon, mEncryptionText, State.NOT_ENCRYPTED);
} else {
mEncryptionText.setText(R.string.decrypt_result_encrypted);
- KeyFormattingUtils.setStatusImage(getActivity(), mEncryptionIcon, mEncryptionText, KeyFormattingUtils.STATE_ENCRYPTED);
+ KeyFormattingUtils.setStatusImage(getActivity(), mEncryptionIcon, mEncryptionText, State.ENCRYPTED);
}
switch (signatureResult.getStatus()) {
case OpenPgpSignatureResult.SIGNATURE_SUCCESS_CERTIFIED: {
mSignatureText.setText(R.string.decrypt_result_signature_certified);
- KeyFormattingUtils.setStatusImage(getActivity(), mSignatureIcon, mSignatureText, KeyFormattingUtils.STATE_VERIFIED);
+ KeyFormattingUtils.setStatusImage(getActivity(), mSignatureIcon, mSignatureText, State.VERIFIED);
setSignatureLayoutVisibility(View.VISIBLE);
setShowAction(mSignatureKeyId);
@@ -161,7 +162,7 @@ public abstract class DecryptFragment extends Fragment {
case OpenPgpSignatureResult.SIGNATURE_SUCCESS_UNCERTIFIED: {
mSignatureText.setText(R.string.decrypt_result_signature_uncertified);
- KeyFormattingUtils.setStatusImage(getActivity(), mSignatureIcon, mSignatureText, KeyFormattingUtils.STATE_UNVERIFIED);
+ KeyFormattingUtils.setStatusImage(getActivity(), mSignatureIcon, mSignatureText, State.UNVERIFIED);
setSignatureLayoutVisibility(View.VISIBLE);
setShowAction(mSignatureKeyId);
@@ -172,11 +173,11 @@ public abstract class DecryptFragment extends Fragment {
case OpenPgpSignatureResult.SIGNATURE_KEY_MISSING: {
mSignatureText.setText(R.string.decrypt_result_signature_missing_key);
- KeyFormattingUtils.setStatusImage(getActivity(), mSignatureIcon, mSignatureText, KeyFormattingUtils.STATE_UNKNOWN_KEY);
+ KeyFormattingUtils.setStatusImage(getActivity(), mSignatureIcon, mSignatureText, State.UNKNOWN_KEY);
setSignatureLayoutVisibility(View.VISIBLE);
mSignatureAction.setText(R.string.decrypt_result_action_Lookup);
- mSignatureAction.setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.ic_action_download, 0);
+ mSignatureAction.setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.ic_file_download_grey_24dp, 0);
mSignatureLayout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
@@ -190,7 +191,7 @@ public abstract class DecryptFragment extends Fragment {
case OpenPgpSignatureResult.SIGNATURE_KEY_EXPIRED: {
mSignatureText.setText(R.string.decrypt_result_signature_expired_key);
- KeyFormattingUtils.setStatusImage(getActivity(), mSignatureIcon, mSignatureText, KeyFormattingUtils.STATE_EXPIRED);
+ KeyFormattingUtils.setStatusImage(getActivity(), mSignatureIcon, mSignatureText, State.EXPIRED);
setSignatureLayoutVisibility(View.VISIBLE);
setShowAction(mSignatureKeyId);
@@ -201,7 +202,7 @@ public abstract class DecryptFragment extends Fragment {
case OpenPgpSignatureResult.SIGNATURE_KEY_REVOKED: {
mSignatureText.setText(R.string.decrypt_result_signature_revoked_key);
- KeyFormattingUtils.setStatusImage(getActivity(), mSignatureIcon, mSignatureText, KeyFormattingUtils.STATE_REVOKED);
+ KeyFormattingUtils.setStatusImage(getActivity(), mSignatureIcon, mSignatureText, State.REVOKED);
setSignatureLayoutVisibility(View.VISIBLE);
setShowAction(mSignatureKeyId);
@@ -212,7 +213,7 @@ public abstract class DecryptFragment extends Fragment {
case OpenPgpSignatureResult.SIGNATURE_ERROR: {
mSignatureText.setText(R.string.decrypt_result_invalid_signature);
- KeyFormattingUtils.setStatusImage(getActivity(), mSignatureIcon, mSignatureText, KeyFormattingUtils.STATE_INVALID);
+ KeyFormattingUtils.setStatusImage(getActivity(), mSignatureIcon, mSignatureText, State.INVALID);
setSignatureLayoutVisibility(View.GONE);
@@ -224,9 +225,9 @@ public abstract class DecryptFragment extends Fragment {
setSignatureLayoutVisibility(View.GONE);
mSignatureText.setText(R.string.decrypt_result_no_signature);
- KeyFormattingUtils.setStatusImage(getActivity(), mSignatureIcon, mSignatureText, KeyFormattingUtils.STATE_NOT_SIGNED);
+ KeyFormattingUtils.setStatusImage(getActivity(), mSignatureIcon, mSignatureText, State.NOT_SIGNED);
mEncryptionText.setText(R.string.decrypt_result_encrypted);
- KeyFormattingUtils.setStatusImage(getActivity(), mEncryptionIcon, mEncryptionText, KeyFormattingUtils.STATE_ENCRYPTED);
+ KeyFormattingUtils.setStatusImage(getActivity(), mEncryptionIcon, mEncryptionText, State.ENCRYPTED);
valid = true;
}
@@ -242,7 +243,7 @@ public abstract class DecryptFragment extends Fragment {
private void setShowAction(final long signatureKeyId) {
mSignatureAction.setText(R.string.decrypt_result_action_show);
- mSignatureAction.setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.ic_action_accounts, 0);
+ mSignatureAction.setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.ic_vpn_key_grey_24dp, 0);
mSignatureLayout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivityInterface.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivityInterface.java
index 54fe369a7..baf445293 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivityInterface.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivityInterface.java
@@ -28,6 +28,7 @@ public interface EncryptActivityInterface {
}
public boolean isUseArmor();
+ public boolean isUseCompression();
public long getSignatureKey();
public long[] getEncryptionKeys();
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptFilesActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptFilesActivity.java
index 1286617d3..11b596c24 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptFilesActivity.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptFilesActivity.java
@@ -25,11 +25,13 @@ import android.support.v4.app.Fragment;
import android.view.Menu;
import android.view.MenuItem;
+import org.spongycastle.bcpg.CompressionAlgorithmTags;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.api.OpenKeychainIntents;
import org.sufficientlysecure.keychain.operations.results.SignEncryptResult;
import org.sufficientlysecure.keychain.pgp.KeyRing;
+import org.sufficientlysecure.keychain.pgp.PgpConstants;
import org.sufficientlysecure.keychain.pgp.SignEncryptParcel;
import org.sufficientlysecure.keychain.ui.dialog.DeleteFileDialogFragment;
import org.sufficientlysecure.keychain.ui.util.Notify;
@@ -66,6 +68,7 @@ public class EncryptFilesActivity extends EncryptActivity implements EncryptActi
private long mSigningKeyId = Constants.key.none;
private String mPassphrase = "";
private boolean mUseArmor;
+ private boolean mUseCompression;
private boolean mDeleteAfterEncrypt = false;
private boolean mShareAfterEncrypt = false;
private ArrayList<Uri> mInputUris;
@@ -82,6 +85,11 @@ public class EncryptFilesActivity extends EncryptActivity implements EncryptActi
}
@Override
+ public boolean isUseCompression() {
+ return mUseCompression;
+ }
+
+ @Override
public long getSignatureKey() {
return mSigningKeyId;
}
@@ -196,10 +204,13 @@ public class EncryptFilesActivity extends EncryptActivity implements EncryptActi
data.addInputUris(mInputUris);
data.addOutputUris(mOutputUris);
- data.setCompressionId(Preferences.getPreferences(this).getDefaultMessageCompression());
-
- // Always use armor for messages
- data.setEnableAsciiArmorOutput(mUseArmor);
+ if (mUseCompression) {
+ data.setCompressionId(PgpConstants.sPreferredCompressionAlgorithms.get(0));
+ } else {
+ data.setCompressionId(CompressionAlgorithmTags.UNCOMPRESSED);
+ }
+ data.setSymmetricEncryptionAlgorithm(PgpConstants.OpenKeychainSymmetricKeyAlgorithmTags.USE_PREFERRED);
+ data.setSignatureHashAlgorithm(PgpConstants.OpenKeychainSymmetricKeyAlgorithmTags.USE_PREFERRED);
if (isModeSymmetric()) {
Log.d(Constants.TAG, "Symmetric encryption enabled!");
@@ -315,8 +326,6 @@ public class EncryptFilesActivity extends EncryptActivity implements EncryptActi
// Handle intent actions
handleActions(getIntent());
updateModeFragment();
-
- mUseArmor = Preferences.getPreferences(this).getDefaultAsciiArmor();
}
@Override
@@ -327,7 +336,6 @@ public class EncryptFilesActivity extends EncryptActivity implements EncryptActi
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.encrypt_file_activity, menu);
- menu.findItem(R.id.check_use_armor).setChecked(mUseArmor);
return super.onCreateOptionsMenu(menu);
}
@@ -348,21 +356,30 @@ public class EncryptFilesActivity extends EncryptActivity implements EncryptActi
item.setChecked(!item.isChecked());
}
switch (item.getItemId()) {
- case R.id.check_use_symmetric:
+ case R.id.check_use_symmetric: {
mCurrentMode = item.isChecked() ? MODE_SYMMETRIC : MODE_ASYMMETRIC;
updateModeFragment();
notifyUpdate();
break;
- case R.id.check_use_armor:
+ }
+ case R.id.check_use_armor: {
mUseArmor = item.isChecked();
notifyUpdate();
break;
- case R.id.check_delete_after_encrypt:
+ }
+ case R.id.check_delete_after_encrypt: {
mDeleteAfterEncrypt = item.isChecked();
notifyUpdate();
break;
- default:
+ }
+ case R.id.check_enable_compression: {
+ mUseCompression = item.isChecked();
+ notifyUpdate();
+ break;
+ }
+ default: {
return super.onOptionsItemSelected(item);
+ }
}
return true;
}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptTextActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptTextActivity.java
index 2dd861d07..08ff5b962 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptTextActivity.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptTextActivity.java
@@ -25,12 +25,14 @@ import android.support.v4.app.Fragment;
import android.view.Menu;
import android.view.MenuItem;
+import org.spongycastle.bcpg.CompressionAlgorithmTags;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.api.OpenKeychainIntents;
import org.sufficientlysecure.keychain.compatibility.ClipboardReflection;
import org.sufficientlysecure.keychain.operations.results.SignEncryptResult;
import org.sufficientlysecure.keychain.pgp.KeyRing;
+import org.sufficientlysecure.keychain.pgp.PgpConstants;
import org.sufficientlysecure.keychain.pgp.SignEncryptParcel;
import org.sufficientlysecure.keychain.ui.util.Notify;
import org.sufficientlysecure.keychain.util.Log;
@@ -70,6 +72,7 @@ public class EncryptTextActivity extends EncryptActivity implements EncryptActiv
private ArrayList<Uri> mInputUris;
private ArrayList<Uri> mOutputUris;
private String mMessage = "";
+ private boolean mUseCompression;
public boolean isModeSymmetric() {
return MODE_SYMMETRIC == mCurrentMode;
@@ -81,6 +84,11 @@ public class EncryptTextActivity extends EncryptActivity implements EncryptActiv
}
@Override
+ public boolean isUseCompression() {
+ return mUseCompression;
+ }
+
+ @Override
public long getSignatureKey() {
return mSigningKeyId;
}
@@ -189,7 +197,13 @@ public class EncryptTextActivity extends EncryptActivity implements EncryptActiv
data.setBytes(mMessage.getBytes());
data.setCleartextSignature(true);
- data.setCompressionId(Preferences.getPreferences(this).getDefaultMessageCompression());
+ if (mUseCompression) {
+ data.setCompressionId(PgpConstants.sPreferredCompressionAlgorithms.get(0));
+ } else {
+ data.setCompressionId(CompressionAlgorithmTags.UNCOMPRESSED);
+ }
+ data.setSymmetricEncryptionAlgorithm(PgpConstants.OpenKeychainSymmetricKeyAlgorithmTags.USE_PREFERRED);
+ data.setSignatureHashAlgorithm(PgpConstants.OpenKeychainSymmetricKeyAlgorithmTags.USE_PREFERRED);
// Always use armor for messages
data.setEnableAsciiArmorOutput(true);
@@ -328,13 +342,20 @@ public class EncryptTextActivity extends EncryptActivity implements EncryptActiv
item.setChecked(!item.isChecked());
}
switch (item.getItemId()) {
- case R.id.check_use_symmetric:
+ case R.id.check_use_symmetric: {
mCurrentMode = item.isChecked() ? MODE_SYMMETRIC : MODE_ASYMMETRIC;
updateModeFragment();
notifyUpdate();
break;
- default:
+ }
+ case R.id.check_enable_compression: {
+ mUseCompression = item.isChecked();
+ notifyUpdate();
+ break;
+ }
+ default: {
return super.onOptionsItemSelected(item);
+ }
}
return true;
}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/HelpActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/HelpActivity.java
index 2eb35351e..cd6cdf4d6 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/HelpActivity.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/HelpActivity.java
@@ -32,10 +32,9 @@ public class HelpActivity extends BaseActivity {
public static final int TAB_START = 0;
public static final int TAB_FAQ = 1;
- public static final int TAB_WOT = 2;
- public static final int TAB_NFC = 3;
- public static final int TAB_CHANGELOG = 4;
- public static final int TAB_ABOUT = 5;
+ public static final int TAB_TRUST = 2;
+ public static final int TAB_CHANGELOG = 3;
+ public static final int TAB_ABOUT = 4;
ViewPager mViewPager;
private PagerTabStripAdapter mTabsAdapter;
@@ -69,21 +68,11 @@ public class HelpActivity extends BaseActivity {
mTabsAdapter.addTab(HelpHtmlFragment.class, startBundle,
getString(R.string.help_tab_start));
- Bundle faqBundle = new Bundle();
- faqBundle.putInt(HelpHtmlFragment.ARG_HTML_FILE, R.raw.help_faq);
- mTabsAdapter.addTab(HelpHtmlFragment.class, faqBundle,
- getString(R.string.help_tab_faq));
-
Bundle wotBundle = new Bundle();
- wotBundle.putInt(HelpHtmlFragment.ARG_HTML_FILE, R.raw.help_wot);
+ wotBundle.putInt(HelpHtmlFragment.ARG_HTML_FILE, R.raw.help_certification);
mTabsAdapter.addTab(HelpHtmlFragment.class, wotBundle,
getString(R.string.help_tab_wot));
- Bundle nfcBundle = new Bundle();
- nfcBundle.putInt(HelpHtmlFragment.ARG_HTML_FILE, R.raw.help_nfc_beam);
- mTabsAdapter.addTab(HelpHtmlFragment.class, nfcBundle,
- getString(R.string.help_tab_nfc_beam));
-
Bundle changelogBundle = new Bundle();
changelogBundle.putInt(HelpHtmlFragment.ARG_HTML_FILE, R.raw.help_changelog);
mTabsAdapter.addTab(HelpHtmlFragment.class, changelogBundle,
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java
index b56da463a..43d893fa6 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java
@@ -70,6 +70,7 @@ import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler;
import org.sufficientlysecure.keychain.ui.dialog.DeleteKeyDialogFragment;
import org.sufficientlysecure.keychain.ui.util.Highlighter;
import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
+import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils.State;
import org.sufficientlysecure.keychain.ui.util.Notify;
import org.sufficientlysecure.keychain.util.ExportHelper;
import org.sufficientlysecure.keychain.util.FabContainer;
@@ -77,7 +78,6 @@ import org.sufficientlysecure.keychain.util.Log;
import org.sufficientlysecure.keychain.util.Preferences;
import java.io.IOException;
-import java.util.Date;
import java.util.HashMap;
import se.emilsjolander.stickylistheaders.StickyListHeadersAdapter;
@@ -268,7 +268,7 @@ public class KeyListFragment extends LoaderFragment
KeyRings.MASTER_KEY_ID,
KeyRings.USER_ID,
KeyRings.IS_REVOKED,
- KeyRings.EXPIRY,
+ KeyRings.IS_EXPIRED,
KeyRings.VERIFIED,
KeyRings.HAS_ANY_SECRET
};
@@ -276,7 +276,7 @@ public class KeyListFragment extends LoaderFragment
static final int INDEX_MASTER_KEY_ID = 1;
static final int INDEX_USER_ID = 2;
static final int INDEX_IS_REVOKED = 3;
- static final int INDEX_EXPIRY = 4;
+ static final int INDEX_IS_EXPIRED = 4;
static final int INDEX_VERIFIED = 5;
static final int INDEX_HAS_ANY_SECRET = 6;
@@ -678,9 +678,6 @@ public class KeyListFragment extends LoaderFragment
/**
* Bind cursor data to the item list view
- * <p/>
- * NOTE: CursorAdapter already implements the ViewHolder pattern in its getView() method.
- * Thus no ViewHolder is required here.
*/
@Override
public void bindView(View view, Context context, Cursor cursor) {
@@ -708,21 +705,20 @@ public class KeyListFragment extends LoaderFragment
long masterKeyId = cursor.getLong(INDEX_MASTER_KEY_ID);
boolean isSecret = cursor.getInt(INDEX_HAS_ANY_SECRET) != 0;
boolean isRevoked = cursor.getInt(INDEX_IS_REVOKED) > 0;
- boolean isExpired = !cursor.isNull(INDEX_EXPIRY)
- && new Date(cursor.getLong(INDEX_EXPIRY) * 1000).before(new Date());
+ boolean isExpired = cursor.getInt(INDEX_IS_EXPIRED) != 0;
boolean isVerified = cursor.getInt(INDEX_VERIFIED) > 0;
h.mMasterKeyId = masterKeyId;
// Note: order is important!
if (isRevoked) {
- KeyFormattingUtils.setStatusImage(getActivity(), h.mStatus, null, KeyFormattingUtils.STATE_REVOKED, R.color.bg_gray);
+ KeyFormattingUtils.setStatusImage(getActivity(), h.mStatus, null, State.REVOKED, R.color.bg_gray);
h.mStatus.setVisibility(View.VISIBLE);
h.mSlinger.setVisibility(View.GONE);
h.mMainUserId.setTextColor(context.getResources().getColor(R.color.bg_gray));
h.mMainUserIdRest.setTextColor(context.getResources().getColor(R.color.bg_gray));
} else if (isExpired) {
- KeyFormattingUtils.setStatusImage(getActivity(), h.mStatus, null, KeyFormattingUtils.STATE_EXPIRED, R.color.bg_gray);
+ KeyFormattingUtils.setStatusImage(getActivity(), h.mStatus, null, State.EXPIRED, R.color.bg_gray);
h.mStatus.setVisibility(View.VISIBLE);
h.mSlinger.setVisibility(View.GONE);
h.mMainUserId.setTextColor(context.getResources().getColor(R.color.bg_gray));
@@ -735,10 +731,10 @@ public class KeyListFragment extends LoaderFragment
} else {
// this is a public key - show if it's verified
if (isVerified) {
- KeyFormattingUtils.setStatusImage(getActivity(), h.mStatus, KeyFormattingUtils.STATE_VERIFIED);
+ KeyFormattingUtils.setStatusImage(getActivity(), h.mStatus, State.VERIFIED);
h.mStatus.setVisibility(View.VISIBLE);
} else {
- KeyFormattingUtils.setStatusImage(getActivity(), h.mStatus, KeyFormattingUtils.STATE_UNVERIFIED);
+ KeyFormattingUtils.setStatusImage(getActivity(), h.mStatus, State.UNVERIFIED);
h.mStatus.setVisibility(View.VISIBLE);
}
h.mSlinger.setVisibility(View.GONE);
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/LogDisplayFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/LogDisplayFragment.java
index b655a7e55..138f2f4e7 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/LogDisplayFragment.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/LogDisplayFragment.java
@@ -22,9 +22,13 @@ import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.os.Bundle;
+import android.os.Parcel;
import android.support.v4.app.ListFragment;
import android.util.TypedValue;
import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
@@ -33,11 +37,19 @@ import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;
+import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.operations.results.OperationResult;
import org.sufficientlysecure.keychain.operations.results.OperationResult.LogEntryParcel;
import org.sufficientlysecure.keychain.operations.results.OperationResult.LogLevel;
import org.sufficientlysecure.keychain.operations.results.OperationResult.SubLogEntryParcel;
+import org.sufficientlysecure.keychain.util.FileHelper;
+import org.sufficientlysecure.keychain.util.Log;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.PrintWriter;
+import java.util.Iterator;
public class LogDisplayFragment extends ListFragment implements OnItemClickListener {
@@ -46,6 +58,12 @@ public class LogDisplayFragment extends ListFragment implements OnItemClickListe
OperationResult mResult;
public static final String EXTRA_RESULT = "log";
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ setHasOptionsMenu(true);
+ }
@Override
public void onActivityCreated(Bundle savedInstanceState) {
@@ -70,6 +88,183 @@ public class LogDisplayFragment extends ListFragment implements OnItemClickListe
getListView().setFastScrollEnabled(true);
getListView().setDividerHeight(0);
+
+ }
+
+ @Override
+ public void onCreateOptionsMenu(final Menu menu, final MenuInflater inflater) {
+ inflater.inflate(R.menu.log_display, menu);
+
+ super.onCreateOptionsMenu(menu, inflater);
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch (item.getItemId()) {
+ case R.id.menu_log_display_export_log:
+ exportLog();
+ break;
+ }
+
+ return super.onOptionsItemSelected(item);
+ }
+
+ private void exportLog() {
+
+ showExportLogDialog(new File(Constants.Path.APP_DIR, "export.log"));
+ }
+
+ private void writeToLogFile(final OperationResult.OperationLog operationLog, final File f) {
+ OperationResult.OperationLog currLog = new OperationResult.OperationLog();
+ currLog.add(OperationResult.LogType.MSG_EXPORT_LOG, 0);
+
+ boolean error = false;
+
+ PrintWriter pw = null;
+ try {
+ pw = new PrintWriter(f);
+ pw.print(getPrintableOperationLog(operationLog, ""));
+ if (pw.checkError()) {//IOException
+ Log.e(Constants.TAG, "Log Export I/O Exception " + f.getAbsolutePath());
+ currLog.add(OperationResult.LogType.MSG_EXPORT_LOG_EXPORT_ERROR_WRITING, 1);
+ error = true;
+ }
+ } catch (FileNotFoundException e) {
+ Log.e(Constants.TAG, "File not found for exporting log " + f.getAbsolutePath());
+ currLog.add(OperationResult.LogType.MSG_EXPORT_LOG_EXPORT_ERROR_FOPEN, 1);
+ error = true;
+ }
+ if (pw != null) {
+ pw.close();
+ if (!error && pw.checkError()) {//check if it is only pw.close() which generated error
+ currLog.add(OperationResult.LogType.MSG_EXPORT_LOG_EXPORT_ERROR_WRITING, 1);
+ error = true;
+ }
+ }
+
+ if (!error) currLog.add(OperationResult.LogType.MSG_EXPORT_LOG_EXPORT_SUCCESS, 1);
+
+ int opResultCode = error ? OperationResult.RESULT_ERROR : OperationResult.RESULT_OK;
+ OperationResult opResult = new LogExportResult(opResultCode, currLog);
+ opResult.createNotify(getActivity()).show();
+ }
+
+ /**
+ * returns an indented String of an entire OperationLog
+ *
+ * @param opLog log to be converted to indented, printable format
+ * @param basePadding padding to add at the start of all log entries, made for use with SubLogs
+ * @return printable, indented version of passed operationLog
+ */
+ private String getPrintableOperationLog(OperationResult.OperationLog opLog, String basePadding) {
+ String log = "";
+ for (Iterator<LogEntryParcel> logIterator = opLog.iterator(); logIterator.hasNext(); ) {
+ log += getPrintableLogEntry(logIterator.next(), basePadding) + "\n";
+ }
+ log = log.substring(0, log.length() - 1);//gets rid of extra new line
+ return log;
+ }
+
+ /**
+ * returns an indented String of a LogEntryParcel including any sub-logs it may contain
+ *
+ * @param entryParcel log entryParcel whose String representation is to be obtained
+ * @return indented version of passed log entryParcel in a readable format
+ */
+ private String getPrintableLogEntry(OperationResult.LogEntryParcel entryParcel,
+ String basePadding) {
+
+ final String indent = " ";//4 spaces = 1 Indent level
+
+ String padding = basePadding;
+ for (int i = 0; i < entryParcel.mIndent; i++) {
+ padding += indent;
+ }
+ String logText = padding;
+
+ switch (entryParcel.mType.mLevel) {
+ case DEBUG:
+ logText += "[DEBUG]";
+ break;
+ case INFO:
+ logText += "[INFO]";
+ break;
+ case WARN:
+ logText += "[WARN]";
+ break;
+ case ERROR:
+ logText += "[ERROR]";
+ break;
+ case START:
+ logText += "[START]";
+ break;
+ case OK:
+ logText += "[OK]";
+ break;
+ case CANCELLED:
+ logText += "[CANCELLED]";
+ break;
+ }
+
+ // special case: first parameter may be a quantity
+ if (entryParcel.mParameters != null && entryParcel.mParameters.length > 0
+ && entryParcel.mParameters[0] instanceof Integer) {
+ logText += getResources().getQuantityString(entryParcel.mType.getMsgId(),
+ (Integer) entryParcel.mParameters[0],
+ entryParcel.mParameters);
+ } else {
+ logText += getResources().getString(entryParcel.mType.getMsgId(),
+ entryParcel.mParameters);
+ }
+
+ if (entryParcel instanceof SubLogEntryParcel) {
+ OperationResult subResult = ((SubLogEntryParcel) entryParcel).getSubResult();
+ LogEntryParcel subEntry = subResult.getLog().getLast();
+ if (subEntry != null) {
+ //the first line of log of subResult is same as entryParcel, so replace logText
+ logText = getPrintableOperationLog(subResult.getLog(), padding);
+ }
+ }
+
+ return logText;
+ }
+
+ private void showExportLogDialog(final File exportFile) {
+
+ String title = this.getString(R.string.title_export_log);
+
+ String message = this.getString(R.string.specify_file_to_export_log_to);
+
+ FileHelper.saveFile(new FileHelper.FileDialogCallback() {
+ @Override
+ public void onFileSelected(File file, boolean checked) {
+ writeToLogFile(mResult.getLog(), file);
+ }
+ }, this.getActivity().getSupportFragmentManager(), title, message, exportFile, null);
+ }
+
+ private static class LogExportResult extends OperationResult {
+
+ public static Creator<LogExportResult> CREATOR = new Creator<LogExportResult>() {
+ public LogExportResult createFromParcel(final Parcel source) {
+ return new LogExportResult(source);
+ }
+
+ public LogExportResult[] newArray(final int size) {
+ return new LogExportResult[size];
+ }
+ };
+
+ public LogExportResult(int result, OperationLog log) {
+ super(result, log);
+ }
+
+ /**
+ * trivial but necessary to implement the Parcelable protocol.
+ */
+ public LogExportResult(Parcel source) {
+ super(source);
+ }
}
@Override
@@ -109,7 +304,7 @@ public class LogDisplayFragment extends ListFragment implements OnItemClickListe
mSecondImg = secondImg;
}
}
-
+ // Check if convertView.setPadding is redundant
@Override
public View getView(int position, View convertView, ViewGroup parent) {
LogEntryParcel entry = getItem(position);
@@ -132,7 +327,6 @@ public class LogDisplayFragment extends ListFragment implements OnItemClickListe
if (entry instanceof SubLogEntryParcel) {
ih.mSub.setVisibility(View.VISIBLE);
convertView.setClickable(false);
-
convertView.setPadding((entry.mIndent) * dipFactor, 0, 0, 0);
OperationResult result = ((SubLogEntryParcel) entry).getSubResult();
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/PassphraseDialogActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/PassphraseDialogActivity.java
index d5ca08936..bb669f6b8 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/PassphraseDialogActivity.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/PassphraseDialogActivity.java
@@ -46,6 +46,7 @@ import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.compatibility.DialogFragmentWorkaround;
import org.sufficientlysecure.keychain.pgp.CanonicalizedSecretKey;
import org.sufficientlysecure.keychain.pgp.CanonicalizedSecretKeyRing;
+import org.sufficientlysecure.keychain.pgp.KeyRing;
import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
import org.sufficientlysecure.keychain.pgp.exception.PgpKeyNotFoundException;
import org.sufficientlysecure.keychain.provider.CachedPublicKeyRing;
@@ -149,6 +150,7 @@ public class PassphraseDialogActivity extends FragmentActivity {
public static class PassphraseDialogFragment extends DialogFragment implements TextView.OnEditorActionListener {
private EditText mPassphraseEditText;
+ private TextView mPassphraseText;
private View mInput, mProgress;
private CanonicalizedSecretKeyRing mSecretRing = null;
@@ -167,7 +169,7 @@ public class PassphraseDialogActivity extends FragmentActivity {
// if the dialog is displayed from the application class, design is missing
// hack to get holo design (which is not automatically applied due to activity's Theme.NoDisplay
ContextThemeWrapper theme = new ContextThemeWrapper(activity,
- R.style.Theme_AppCompat_Light);
+ R.style.Theme_AppCompat_Light_Dialog);
mSubKeyId = getArguments().getLong(EXTRA_SUBKEY_ID);
mServiceIntent = getArguments().getParcelable(EXTRA_DATA);
@@ -176,13 +178,30 @@ public class PassphraseDialogActivity extends FragmentActivity {
alert.setTitle(R.string.title_unlock);
+ LayoutInflater inflater = LayoutInflater.from(theme);
+ View view = inflater.inflate(R.layout.passphrase_dialog, null);
+ alert.setView(view);
+
+ mPassphraseText = (TextView) view.findViewById(R.id.passphrase_text);
+ mPassphraseEditText = (EditText) view.findViewById(R.id.passphrase_passphrase);
+ mInput = view.findViewById(R.id.input);
+ mProgress = view.findViewById(R.id.progress);
+
+ alert.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
+
+ @Override
+ public void onClick(DialogInterface dialog, int id) {
+ dialog.cancel();
+ }
+ });
+
String userId;
CanonicalizedSecretKey.SecretKeyType keyType = CanonicalizedSecretKey.SecretKeyType.PASSPHRASE;
+ String message;
if (mSubKeyId == Constants.key.symmetric || mSubKeyId == Constants.key.none) {
- alert.setMessage(R.string.passphrase_for_symmetric_encryption);
+ message = getString(R.string.passphrase_for_symmetric_encryption);
} else {
- String message;
try {
ProviderHelper helper = new ProviderHelper(activity);
mSecretRing = helper.getCanonicalizedSecretKeyRing(
@@ -191,7 +210,13 @@ public class PassphraseDialogActivity extends FragmentActivity {
// above can't be statically verified to have been set in all cases because
// the catch clause doesn't return.
try {
- userId = mSecretRing.getPrimaryUserIdWithFallback();
+ String mainUserId = mSecretRing.getPrimaryUserIdWithFallback();
+ String[] mainUserIdSplit = KeyRing.splitUserId(mainUserId);
+ if (mainUserIdSplit[0] != null) {
+ userId = mainUserIdSplit[0];
+ } else {
+ userId = getString(R.string.user_id_no_name);
+ }
} catch (PgpKeyNotFoundException e) {
userId = null;
}
@@ -228,33 +253,16 @@ public class PassphraseDialogActivity extends FragmentActivity {
alert.setCancelable(false);
return alert.create();
}
-
- alert.setMessage(message);
}
- LayoutInflater inflater = LayoutInflater.from(theme);
- View view = inflater.inflate(R.layout.passphrase_dialog, null);
- alert.setView(view);
-
- mPassphraseEditText = (EditText) view.findViewById(R.id.passphrase_passphrase);
- mInput = view.findViewById(R.id.input);
- mProgress = view.findViewById(R.id.progress);
-
- alert.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
-
- @Override
- public void onClick(DialogInterface dialog, int id) {
- dialog.cancel();
- }
- });
-
+ mPassphraseText.setText(message);
if (keyType == CanonicalizedSecretKey.SecretKeyType.PATTERN) {
// start pattern dialog and show progress circle here...
// Intent patternActivity = new Intent(getActivity(), LockPatternActivity.class);
// patternActivity.putExtra(LockPatternActivity.EXTRA_PATTERN, "123");
// startActivityForResult(patternActivity, REQUEST_CODE_ENTER_PATTERN);
- mInput.setVisibility(View.GONE);
+ mInput.setVisibility(View.INVISIBLE);
mProgress.setVisibility(View.VISIBLE);
} else {
// Hack to open keyboard.
@@ -322,7 +330,7 @@ public class PassphraseDialogActivity extends FragmentActivity {
return;
}
- mInput.setVisibility(View.GONE);
+ mInput.setVisibility(View.INVISIBLE);
mProgress.setVisibility(View.VISIBLE);
positive.setEnabled(false);
@@ -364,7 +372,7 @@ public class PassphraseDialogActivity extends FragmentActivity {
mPassphraseEditText.setText("");
mPassphraseEditText.setError(getString(R.string.wrong_passphrase));
mInput.setVisibility(View.VISIBLE);
- mProgress.setVisibility(View.GONE);
+ mProgress.setVisibility(View.INVISIBLE);
positive.setEnabled(true);
return;
}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectPublicKeyFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectPublicKeyFragment.java
index afec3bf06..65d7eca37 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectPublicKeyFragment.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectPublicKeyFragment.java
@@ -46,6 +46,7 @@ import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
import org.sufficientlysecure.keychain.provider.KeychainDatabase.Tables;
import org.sufficientlysecure.keychain.ui.adapter.SelectKeyCursorAdapter;
import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
+import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils.State;
import java.util.Vector;
@@ -136,7 +137,7 @@ public class SelectPublicKeyFragment extends ListFragmentWorkaround implements T
mSearchView.setId(SEARCH_ID);
mSearchView.setHint(R.string.menu_search);
mSearchView.setCompoundDrawablesWithIntrinsicBounds(
- getResources().getDrawable(R.drawable.ic_action_search), null, null, null);
+ getResources().getDrawable(R.drawable.ic_search_grey_24dp), null, null, null);
linearLayout.addView(mSearchView, new FrameLayout.LayoutParams(
ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
@@ -376,15 +377,15 @@ public class SelectPublicKeyFragment extends ListFragmentWorkaround implements T
// Check if key is viable for our purposes
if (cursor.getInt(mIndexHasEncrypt) == 0) {
h.statusIcon.setVisibility(View.VISIBLE);
- KeyFormattingUtils.setStatusImage(mContext, h.statusIcon, KeyFormattingUtils.STATE_UNAVAILABLE);
+ KeyFormattingUtils.setStatusImage(mContext, h.statusIcon, State.UNAVAILABLE);
enabled = false;
} else if (cursor.getInt(mIndexIsVerified) != 0) {
h.statusIcon.setVisibility(View.VISIBLE);
- KeyFormattingUtils.setStatusImage(mContext, h.statusIcon, KeyFormattingUtils.STATE_VERIFIED);
+ KeyFormattingUtils.setStatusImage(mContext, h.statusIcon, State.VERIFIED);
enabled = true;
} else {
h.statusIcon.setVisibility(View.VISIBLE);
- KeyFormattingUtils.setStatusImage(mContext, h.statusIcon, KeyFormattingUtils.STATE_UNVERIFIED);
+ KeyFormattingUtils.setStatusImage(mContext, h.statusIcon, State.UNVERIFIED);
enabled = true;
}
}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/SettingsActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/SettingsActivity.java
index 53986a392..210960b65 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/SettingsActivity.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/SettingsActivity.java
@@ -33,8 +33,6 @@ import android.view.ViewGroup;
import android.widget.LinearLayout;
import org.spongycastle.bcpg.CompressionAlgorithmTags;
-import org.spongycastle.bcpg.HashAlgorithmTags;
-import org.spongycastle.openpgp.PGPEncryptedData;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.ui.widget.IntegerListPreference;
@@ -93,12 +91,6 @@ public class SettingsActivity extends PreferenceActivity {
initializePassphraseCacheTtl(
(IntegerListPreference) findPreference(Constants.Pref.PASSPHRASE_CACHE_TTL));
- initializeEncryptionAlgorithm(
- (IntegerListPreference) findPreference(Constants.Pref.DEFAULT_ENCRYPTION_ALGORITHM));
-
- initializeHashAlgorithm(
- (IntegerListPreference) findPreference(Constants.Pref.DEFAULT_HASH_ALGORITHM));
-
int[] valueIds = new int[]{
CompressionAlgorithmTags.UNCOMPRESSED,
CompressionAlgorithmTags.ZIP,
@@ -115,20 +107,6 @@ public class SettingsActivity extends PreferenceActivity {
values[i] = "" + valueIds[i];
}
- initializeMessageCompression(
- (IntegerListPreference) findPreference(Constants.Pref.DEFAULT_MESSAGE_COMPRESSION),
- entries, values);
-
- initializeFileCompression(
- (IntegerListPreference) findPreference(Constants.Pref.DEFAULT_FILE_COMPRESSION),
- entries, values);
-
- initializeAsciiArmor(
- (CheckBoxPreference) findPreference(Constants.Pref.DEFAULT_ASCII_ARMOR));
-
- initializeWriteVersionHeader(
- (CheckBoxPreference) findPreference(Constants.Pref.WRITE_VERSION_HEADER));
-
initializeUseDefaultYubikeyPin(
(CheckBoxPreference) findPreference(Constants.Pref.USE_DEFAULT_YUBIKEY_PIN));
@@ -265,12 +243,6 @@ public class SettingsActivity extends PreferenceActivity {
initializePassphraseCacheTtl(
(IntegerListPreference) findPreference(Constants.Pref.PASSPHRASE_CACHE_TTL));
- initializeEncryptionAlgorithm(
- (IntegerListPreference) findPreference(Constants.Pref.DEFAULT_ENCRYPTION_ALGORITHM));
-
- initializeHashAlgorithm(
- (IntegerListPreference) findPreference(Constants.Pref.DEFAULT_HASH_ALGORITHM));
-
int[] valueIds = new int[]{
CompressionAlgorithmTags.UNCOMPRESSED,
CompressionAlgorithmTags.ZIP,
@@ -290,20 +262,6 @@ public class SettingsActivity extends PreferenceActivity {
values[i] = "" + valueIds[i];
}
- initializeMessageCompression(
- (IntegerListPreference) findPreference(Constants.Pref.DEFAULT_MESSAGE_COMPRESSION),
- entries, values);
-
- initializeFileCompression(
- (IntegerListPreference) findPreference(Constants.Pref.DEFAULT_FILE_COMPRESSION),
- entries, values);
-
- initializeAsciiArmor(
- (CheckBoxPreference) findPreference(Constants.Pref.DEFAULT_ASCII_ARMOR));
-
- initializeWriteVersionHeader(
- (CheckBoxPreference) findPreference(Constants.Pref.WRITE_VERSION_HEADER));
-
initializeUseDefaultYubikeyPin(
(CheckBoxPreference) findPreference(Constants.Pref.USE_DEFAULT_YUBIKEY_PIN));
@@ -344,113 +302,6 @@ public class SettingsActivity extends PreferenceActivity {
});
}
- 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,
- PGPEncryptedData.IDEA,};
- String entries[] = {"AES-128", "AES-192", "AES-256", "Blowfish", "Twofish", "CAST5",
- "DES", "Triple DES", "IDEA",};
- String values[] = new String[valueIds.length];
- for (int i = 0; i < values.length; ++i) {
- values[i] = "" + valueIds[i];
- }
- mEncryptionAlgorithm.setEntries(entries);
- mEncryptionAlgorithm.setEntryValues(values);
- mEncryptionAlgorithm.setValue("" + sPreferences.getDefaultEncryptionAlgorithm());
- mEncryptionAlgorithm.setSummary(mEncryptionAlgorithm.getEntry());
- mEncryptionAlgorithm
- .setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
- public boolean onPreferenceChange(Preference preference, Object newValue) {
- mEncryptionAlgorithm.setValue(newValue.toString());
- mEncryptionAlgorithm.setSummary(mEncryptionAlgorithm.getEntry());
- sPreferences.setDefaultEncryptionAlgorithm(Integer.parseInt(newValue
- .toString()));
- return false;
- }
- });
- }
-
- private static void initializeHashAlgorithm(final IntegerListPreference mHashAlgorithm) {
- int[] valueIds = new int[]{HashAlgorithmTags.RIPEMD160,
- HashAlgorithmTags.SHA1, HashAlgorithmTags.SHA224, HashAlgorithmTags.SHA256,
- HashAlgorithmTags.SHA384, HashAlgorithmTags.SHA512,};
- String[] entries = new String[]{"RIPEMD-160", "SHA-1", "SHA-224", "SHA-256", "SHA-384",
- "SHA-512",};
- String[] values = new String[valueIds.length];
- for (int i = 0; i < values.length; ++i) {
- values[i] = "" + valueIds[i];
- }
- mHashAlgorithm.setEntries(entries);
- mHashAlgorithm.setEntryValues(values);
- mHashAlgorithm.setValue("" + sPreferences.getDefaultHashAlgorithm());
- mHashAlgorithm.setSummary(mHashAlgorithm.getEntry());
- mHashAlgorithm.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
- public boolean onPreferenceChange(Preference preference, Object newValue) {
- mHashAlgorithm.setValue(newValue.toString());
- mHashAlgorithm.setSummary(mHashAlgorithm.getEntry());
- sPreferences.setDefaultHashAlgorithm(Integer.parseInt(newValue.toString()));
- return false;
- }
- });
- }
-
- private static void initializeMessageCompression(final IntegerListPreference mMessageCompression,
- String[] entries, String[] values) {
- mMessageCompression.setEntries(entries);
- mMessageCompression.setEntryValues(values);
- mMessageCompression.setValue("" + sPreferences.getDefaultMessageCompression());
- mMessageCompression.setSummary(mMessageCompression.getEntry());
- mMessageCompression
- .setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
- public boolean onPreferenceChange(Preference preference, Object newValue) {
- mMessageCompression.setValue(newValue.toString());
- mMessageCompression.setSummary(mMessageCompression.getEntry());
- sPreferences.setDefaultMessageCompression(Integer.parseInt(newValue
- .toString()));
- return false;
- }
- });
- }
-
- private static void initializeFileCompression
- (final IntegerListPreference mFileCompression, String[] entries, String[] values) {
- mFileCompression.setEntries(entries);
- mFileCompression.setEntryValues(values);
- mFileCompression.setValue("" + sPreferences.getDefaultFileCompression());
- mFileCompression.setSummary(mFileCompression.getEntry());
- mFileCompression.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
- public boolean onPreferenceChange(Preference preference, Object newValue) {
- mFileCompression.setValue(newValue.toString());
- mFileCompression.setSummary(mFileCompression.getEntry());
- sPreferences.setDefaultFileCompression(Integer.parseInt(newValue.toString()));
- return false;
- }
- });
- }
-
- private static void initializeAsciiArmor(final CheckBoxPreference mAsciiArmor) {
- mAsciiArmor.setChecked(sPreferences.getDefaultAsciiArmor());
- mAsciiArmor.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
- public boolean onPreferenceChange(Preference preference, Object newValue) {
- mAsciiArmor.setChecked((Boolean) newValue);
- sPreferences.setDefaultAsciiArmor((Boolean) newValue);
- return false;
- }
- });
- }
-
- private static void initializeWriteVersionHeader(final CheckBoxPreference mWriteVersionHeader) {
- mWriteVersionHeader.setChecked(sPreferences.getWriteVersionHeader());
- mWriteVersionHeader.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
- public boolean onPreferenceChange(Preference preference, Object newValue) {
- mWriteVersionHeader.setChecked((Boolean) newValue);
- sPreferences.setWriteVersionHeader((Boolean) newValue);
- return false;
- }
- });
- }
-
private static void initializeSearchKeyserver(final CheckBoxPreference mSearchKeyserver) {
Preferences.CloudSearchPrefs prefs = sPreferences.getCloudSearchPrefs();
mSearchKeyserver.setChecked(prefs.searchKeyserver);
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java
index 0be6c26f6..1b4fc503c 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java
@@ -74,16 +74,15 @@ import org.sufficientlysecure.keychain.service.KeychainIntentService;
import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler;
import org.sufficientlysecure.keychain.ui.util.FormattingUtils;
import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
+import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils.State;
import org.sufficientlysecure.keychain.ui.util.Notify;
import org.sufficientlysecure.keychain.ui.util.QrCodeUtils;
-import org.sufficientlysecure.keychain.ui.widget.AspectRatioImageView;
import org.sufficientlysecure.keychain.util.ContactHelper;
import org.sufficientlysecure.keychain.util.ExportHelper;
import org.sufficientlysecure.keychain.util.Log;
import org.sufficientlysecure.keychain.util.Preferences;
import java.util.ArrayList;
-import java.util.Date;
import java.util.HashMap;
public class ViewKeyActivity extends BaseActivity implements
@@ -105,7 +104,7 @@ public class ViewKeyActivity extends BaseActivity implements
private ImageButton mActionEncryptText;
private ImageButton mActionNfc;
private FloatingActionButton mFab;
- private AspectRatioImageView mPhoto;
+ private ImageView mPhoto;
private ImageView mQrCode;
private CardView mQrCodeLayout;
@@ -121,6 +120,9 @@ public class ViewKeyActivity extends BaseActivity implements
private boolean mIsSecret = false;
private boolean mHasEncrypt = false;
private boolean mIsVerified = false;
+ private boolean mIsRevoked = false;
+ private boolean mIsExpired = false;
+
private MenuItem mRefreshItem;
private boolean mIsRefreshing;
private Animation mRotate, mRotateSpin;
@@ -147,7 +149,7 @@ public class ViewKeyActivity extends BaseActivity implements
mActionEncryptText = (ImageButton) findViewById(R.id.view_key_action_encrypt_text);
mActionNfc = (ImageButton) findViewById(R.id.view_key_action_nfc);
mFab = (FloatingActionButton) findViewById(R.id.fab);
- mPhoto = (AspectRatioImageView) findViewById(R.id.view_key_photo);
+ mPhoto = (ImageView) findViewById(R.id.view_key_photo);
mQrCode = (ImageView) findViewById(R.id.view_key_qr_code);
mQrCodeLayout = (CardView) findViewById(R.id.view_key_qr_code_layout);
@@ -173,7 +175,7 @@ public class ViewKeyActivity extends BaseActivity implements
}
});
- mRotate = AnimationUtils.loadAnimation(this, R.anim.rotate);
+ mRotate = AnimationUtils.loadAnimation(this, R.anim.rotate);
mRotate.setRepeatCount(Animation.INFINITE);
mRotate.setAnimationListener(new Animation.AnimationListener() {
@Override
@@ -347,7 +349,7 @@ public class ViewKeyActivity extends BaseActivity implements
MenuItem editKey = menu.findItem(R.id.menu_key_view_edit);
editKey.setVisible(mIsSecret);
MenuItem certifyFingerprint = menu.findItem(R.id.menu_key_view_certify_fingerprint);
- certifyFingerprint.setVisible(!mIsSecret && !mIsVerified);
+ certifyFingerprint.setVisible(!mIsSecret && !mIsVerified && !mIsExpired && !mIsRevoked);
return true;
}
@@ -398,12 +400,12 @@ public class ViewKeyActivity extends BaseActivity implements
private void certifyImmediate() {
Intent intent = new Intent(this, CertifyKeyActivity.class);
- intent.putExtra(CertifyKeyActivity.EXTRA_KEY_IDS, new long[]{ mMasterKeyId });
+ intent.putExtra(CertifyKeyActivity.EXTRA_KEY_IDS, new long[]{mMasterKeyId});
startCertifyIntent(intent);
}
- private void startCertifyIntent (Intent intent) {
+ private void startCertifyIntent(Intent intent) {
// Message is received after signing is done in KeychainIntentService
KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler(this) {
public void handleMessage(Message message) {
@@ -750,7 +752,7 @@ public class ViewKeyActivity extends BaseActivity implements
KeychainContract.KeyRings.MASTER_KEY_ID,
KeychainContract.KeyRings.USER_ID,
KeychainContract.KeyRings.IS_REVOKED,
- KeychainContract.KeyRings.EXPIRY,
+ KeychainContract.KeyRings.IS_EXPIRED,
KeychainContract.KeyRings.VERIFIED,
KeychainContract.KeyRings.HAS_ANY_SECRET,
KeychainContract.KeyRings.FINGERPRINT,
@@ -760,7 +762,7 @@ public class ViewKeyActivity extends BaseActivity implements
static final int INDEX_MASTER_KEY_ID = 1;
static final int INDEX_USER_ID = 2;
static final int INDEX_IS_REVOKED = 3;
- static final int INDEX_EXPIRY = 4;
+ static final int INDEX_IS_EXPIRED = 4;
static final int INDEX_VERIFIED = 5;
static final int INDEX_HAS_ANY_SECRET = 6;
static final int INDEX_FINGERPRINT = 7;
@@ -809,9 +811,8 @@ public class ViewKeyActivity extends BaseActivity implements
mIsSecret = data.getInt(INDEX_HAS_ANY_SECRET) != 0;
mHasEncrypt = data.getInt(INDEX_HAS_ENCRYPT) != 0;
- boolean isRevoked = data.getInt(INDEX_IS_REVOKED) > 0;
- boolean isExpired = !data.isNull(INDEX_EXPIRY)
- && new Date(data.getLong(INDEX_EXPIRY) * 1000).before(new Date());
+ mIsRevoked = data.getInt(INDEX_IS_REVOKED) > 0;
+ mIsExpired = data.getInt(INDEX_IS_EXPIRED) != 0;
mIsVerified = data.getInt(INDEX_VERIFIED) > 0;
// if the refresh animation isn't playing
@@ -821,10 +822,10 @@ public class ViewKeyActivity extends BaseActivity implements
// this is done at the end of the animation otherwise
}
- AsyncTask<String, Void, Bitmap> photoTask =
- new AsyncTask<String, Void, Bitmap>() {
- protected Bitmap doInBackground(String... fingerprint) {
- return ContactHelper.photoFromFingerprint(getContentResolver(), fingerprint[0]);
+ AsyncTask<Long, Void, Bitmap> photoTask =
+ new AsyncTask<Long, Void, Bitmap>() {
+ protected Bitmap doInBackground(Long... mMasterKeyId) {
+ return ContactHelper.loadPhotoByMasterKeyId(getContentResolver(), mMasterKeyId[0], true);
}
protected void onPostExecute(Bitmap photo) {
@@ -835,11 +836,11 @@ public class ViewKeyActivity extends BaseActivity implements
// Note: order is important
int color;
- if (isRevoked) {
+ if (mIsRevoked) {
mStatusText.setText(R.string.view_key_revoked);
mStatusImage.setVisibility(View.VISIBLE);
KeyFormattingUtils.setStatusImage(this, mStatusImage, mStatusText,
- KeyFormattingUtils.STATE_REVOKED, R.color.icons, true);
+ State.REVOKED, R.color.icons, true);
color = getResources().getColor(R.color.android_red_light);
mActionEncryptFile.setVisibility(View.GONE);
@@ -847,7 +848,7 @@ public class ViewKeyActivity extends BaseActivity implements
mActionNfc.setVisibility(View.GONE);
mFab.setVisibility(View.GONE);
mQrCodeLayout.setVisibility(View.GONE);
- } else if (isExpired) {
+ } else if (mIsExpired) {
if (mIsSecret) {
mStatusText.setText(R.string.view_key_expired_secret);
} else {
@@ -855,7 +856,7 @@ public class ViewKeyActivity extends BaseActivity implements
}
mStatusImage.setVisibility(View.VISIBLE);
KeyFormattingUtils.setStatusImage(this, mStatusImage, mStatusText,
- KeyFormattingUtils.STATE_EXPIRED, R.color.icons, true);
+ State.EXPIRED, R.color.icons, true);
color = getResources().getColor(R.color.android_red_light);
mActionEncryptFile.setVisibility(View.GONE);
@@ -868,10 +869,10 @@ public class ViewKeyActivity extends BaseActivity implements
mStatusImage.setVisibility(View.GONE);
color = getResources().getColor(R.color.primary);
// reload qr code only if the fingerprint changed
- if ( !mFingerprint.equals(oldFingerprint)) {
+ if (!mFingerprint.equals(oldFingerprint)) {
loadQrCode(mFingerprint);
}
- photoTask.execute(mFingerprint);
+ photoTask.execute(mMasterKeyId);
mQrCodeLayout.setVisibility(View.VISIBLE);
// and place leftOf qr code
@@ -915,16 +916,16 @@ public class ViewKeyActivity extends BaseActivity implements
mStatusText.setText(R.string.view_key_verified);
mStatusImage.setVisibility(View.VISIBLE);
KeyFormattingUtils.setStatusImage(this, mStatusImage, mStatusText,
- KeyFormattingUtils.STATE_VERIFIED, R.color.icons, true);
+ State.VERIFIED, R.color.icons, true);
color = getResources().getColor(R.color.primary);
- photoTask.execute(mFingerprint);
+ photoTask.execute(mMasterKeyId);
mFab.setVisibility(View.GONE);
} else {
mStatusText.setText(R.string.view_key_unverified);
mStatusImage.setVisibility(View.VISIBLE);
KeyFormattingUtils.setStatusImage(this, mStatusImage, mStatusText,
- KeyFormattingUtils.STATE_UNVERIFIED, R.color.icons, true);
+ State.UNVERIFIED, R.color.icons, true);
color = getResources().getColor(R.color.android_orange_light);
mFab.setVisibility(View.VISIBLE);
@@ -932,27 +933,21 @@ public class ViewKeyActivity extends BaseActivity implements
}
if (mPreviousColor == 0 || mPreviousColor == color) {
- mToolbar.setBackgroundColor(color);
mStatusBar.setBackgroundColor(color);
mBigToolbar.setBackgroundColor(color);
mPreviousColor = color;
} else {
ObjectAnimator colorFade1 =
- ObjectAnimator.ofObject(mToolbar, "backgroundColor",
- new ArgbEvaluator(), mPreviousColor, color);
- ObjectAnimator colorFade2 =
ObjectAnimator.ofObject(mStatusBar, "backgroundColor",
new ArgbEvaluator(), mPreviousColor, color);
- ObjectAnimator colorFade3 =
+ ObjectAnimator colorFade2 =
ObjectAnimator.ofObject(mBigToolbar, "backgroundColor",
new ArgbEvaluator(), mPreviousColor, color);
colorFade1.setDuration(1200);
colorFade2.setDuration(1200);
- colorFade3.setDuration(1200);
colorFade1.start();
colorFade2.start();
- colorFade3.start();
mPreviousColor = color;
}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvActivity.java
index 9d79b377c..9390e8a69 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvActivity.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvActivity.java
@@ -43,8 +43,6 @@ import org.sufficientlysecure.keychain.util.ContactHelper;
import org.sufficientlysecure.keychain.util.ExportHelper;
import org.sufficientlysecure.keychain.util.Log;
-import java.util.Date;
-
public class ViewKeyAdvActivity extends BaseActivity implements
LoaderManager.LoaderCallbacks<Cursor> {
@@ -159,7 +157,7 @@ public class ViewKeyAdvActivity extends BaseActivity implements
KeychainContract.KeyRings.MASTER_KEY_ID,
KeychainContract.KeyRings.USER_ID,
KeychainContract.KeyRings.IS_REVOKED,
- KeychainContract.KeyRings.EXPIRY,
+ KeychainContract.KeyRings.IS_EXPIRED,
KeychainContract.KeyRings.VERIFIED,
KeychainContract.KeyRings.HAS_ANY_SECRET
};
@@ -167,7 +165,7 @@ public class ViewKeyAdvActivity extends BaseActivity implements
static final int INDEX_MASTER_KEY_ID = 1;
static final int INDEX_USER_ID = 2;
static final int INDEX_IS_REVOKED = 3;
- static final int INDEX_EXPIRY = 4;
+ static final int INDEX_IS_EXPIRED = 4;
static final int INDEX_VERIFIED = 5;
static final int INDEX_HAS_ANY_SECRET = 6;
@@ -212,8 +210,7 @@ public class ViewKeyAdvActivity extends BaseActivity implements
boolean isSecret = data.getInt(INDEX_HAS_ANY_SECRET) != 0;
boolean isRevoked = data.getInt(INDEX_IS_REVOKED) > 0;
- boolean isExpired = !data.isNull(INDEX_EXPIRY)
- && new Date(data.getLong(INDEX_EXPIRY) * 1000).before(new Date());
+ boolean isExpired = data.getInt(INDEX_IS_EXPIRED) != 0;
boolean isVerified = data.getInt(INDEX_VERIFIED) > 0;
// Note: order is important
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvShareFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvShareFragment.java
index 8d0a2dd1d..95a6faea9 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvShareFragment.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvShareFragment.java
@@ -260,7 +260,7 @@ public class ViewKeyAdvShareFragment extends LoaderFragment implements
static final String[] UNIFIED_PROJECTION = new String[]{
KeyRings._ID, KeyRings.MASTER_KEY_ID, KeyRings.HAS_ANY_SECRET,
KeyRings.USER_ID, KeyRings.FINGERPRINT,
- KeyRings.ALGORITHM, KeyRings.KEY_SIZE, KeyRings.CREATION, KeyRings.EXPIRY,
+ KeyRings.ALGORITHM, KeyRings.KEY_SIZE, KeyRings.CREATION, KeyRings.IS_EXPIRED,
};
static final int INDEX_UNIFIED_MASTER_KEY_ID = 1;
@@ -270,7 +270,7 @@ public class ViewKeyAdvShareFragment extends LoaderFragment implements
static final int INDEX_UNIFIED_ALGORITHM = 5;
static final int INDEX_UNIFIED_KEY_SIZE = 6;
static final int INDEX_UNIFIED_CREATION = 7;
- static final int INDEX_UNIFIED_EXPIRY = 8;
+ static final int INDEX_UNIFIED_ID_EXPIRED = 8;
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
setContentShown(false);
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvUserIdsFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvUserIdsFragment.java
index c4e6639a8..7bfebaf62 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvUserIdsFragment.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvUserIdsFragment.java
@@ -114,12 +114,12 @@ public class ViewKeyAdvUserIdsFragment extends LoaderFragment implements
static final String[] UNIFIED_PROJECTION = new String[]{
KeyRings._ID, KeyRings.MASTER_KEY_ID,
- KeyRings.HAS_ANY_SECRET, KeyRings.IS_REVOKED, KeyRings.EXPIRY, KeyRings.HAS_ENCRYPT
+ KeyRings.HAS_ANY_SECRET, KeyRings.IS_REVOKED, KeyRings.IS_EXPIRED, KeyRings.HAS_ENCRYPT
};
static final int INDEX_UNIFIED_MASTER_KEY_ID = 1;
static final int INDEX_UNIFIED_HAS_ANY_SECRET = 2;
static final int INDEX_UNIFIED_IS_REVOKED = 3;
- static final int INDEX_UNIFIED_EXPIRY = 4;
+ static final int INDEX_UNIFIED_IS_EXPIRED = 4;
static final int INDEX_UNIFIED_HAS_ENCRYPT = 5;
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyFragment.java
index 32630b459..628970b27 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyFragment.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyFragment.java
@@ -121,7 +121,7 @@ public class ViewKeyFragment extends LoaderFragment implements
KeychainContract.KeyRings.MASTER_KEY_ID,
KeychainContract.KeyRings.USER_ID,
KeychainContract.KeyRings.IS_REVOKED,
- KeychainContract.KeyRings.EXPIRY,
+ KeychainContract.KeyRings.IS_EXPIRED,
KeychainContract.KeyRings.VERIFIED,
KeychainContract.KeyRings.HAS_ANY_SECRET,
KeychainContract.KeyRings.FINGERPRINT,
@@ -131,7 +131,7 @@ public class ViewKeyFragment extends LoaderFragment implements
static final int INDEX_MASTER_KEY_ID = 1;
static final int INDEX_USER_ID = 2;
static final int INDEX_IS_REVOKED = 3;
- static final int INDEX_EXPIRY = 4;
+ static final int INDEX_IS_EXPIRED = 4;
static final int INDEX_VERIFIED = 5;
static final int INDEX_HAS_ANY_SECRET = 6;
static final int INDEX_FINGERPRINT = 7;
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyTrustFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyTrustFragment.java
index 25edc7a02..d22f01a48 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyTrustFragment.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyTrustFragment.java
@@ -115,12 +115,12 @@ public class ViewKeyTrustFragment extends LoaderFragment implements
}
static final String[] TRUST_PROJECTION = new String[]{
- KeyRings._ID, KeyRings.FINGERPRINT, KeyRings.IS_REVOKED, KeyRings.EXPIRY,
+ KeyRings._ID, KeyRings.FINGERPRINT, KeyRings.IS_REVOKED, KeyRings.IS_EXPIRED,
KeyRings.HAS_ANY_SECRET, KeyRings.VERIFIED
};
static final int INDEX_TRUST_FINGERPRINT = 1;
static final int INDEX_TRUST_IS_REVOKED = 2;
- static final int INDEX_TRUST_EXPIRY = 3;
+ static final int INDEX_TRUST_IS_EXPIRED = 3;
static final int INDEX_UNIFIED_HAS_ANY_SECRET = 4;
static final int INDEX_VERIFIED = 5;
@@ -169,8 +169,7 @@ public class ViewKeyTrustFragment extends LoaderFragment implements
nothingSpecial = false;
} else {
- Date expiryDate = new Date(data.getLong(INDEX_TRUST_EXPIRY) * 1000);
- if (!data.isNull(INDEX_TRUST_EXPIRY) && expiryDate.before(new Date())) {
+ if (data.getInt(INDEX_TRUST_IS_EXPIRED) != 0) {
// if expired, don’t trust it!
message.append(getString(R.string.key_trust_expired)).
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysAdapter.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysAdapter.java
index 6ba9e26ad..429feb075 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysAdapter.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysAdapter.java
@@ -37,6 +37,7 @@ import org.sufficientlysecure.keychain.pgp.KeyRing;
import org.sufficientlysecure.keychain.ui.util.FormattingUtils;
import org.sufficientlysecure.keychain.ui.util.Highlighter;
import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
+import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils.State;
import java.util.ArrayList;
import java.util.HashMap;
@@ -175,9 +176,9 @@ public class ImportKeysAdapter extends ArrayAdapter<ImportKeysListEntry> {
}
if (entry.isRevoked()) {
- KeyFormattingUtils.setStatusImage(getContext(), holder.status, null, KeyFormattingUtils.STATE_REVOKED, R.color.bg_gray);
+ KeyFormattingUtils.setStatusImage(getContext(), holder.status, null, State.REVOKED, R.color.bg_gray);
} else if (entry.isExpired()) {
- KeyFormattingUtils.setStatusImage(getContext(), holder.status, null, KeyFormattingUtils.STATE_EXPIRED, R.color.bg_gray);
+ KeyFormattingUtils.setStatusImage(getContext(), holder.status, null, State.EXPIRED, R.color.bg_gray);
}
if (entry.isRevoked() || entry.isExpired()) {
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/SelectKeyCursorAdapter.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/SelectKeyCursorAdapter.java
index a836b35df..226fda20b 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/SelectKeyCursorAdapter.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/SelectKeyCursorAdapter.java
@@ -33,6 +33,7 @@ import org.sufficientlysecure.keychain.pgp.KeyRing;
import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
import org.sufficientlysecure.keychain.ui.util.Highlighter;
import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
+import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils.State;
/**
@@ -133,11 +134,11 @@ abstract public class SelectKeyCursorAdapter extends CursorAdapter {
boolean enabled;
if (cursor.getInt(mIndexIsRevoked) != 0) {
h.statusIcon.setVisibility(View.VISIBLE);
- KeyFormattingUtils.setStatusImage(mContext, h.statusIcon, null, KeyFormattingUtils.STATE_REVOKED, R.color.bg_gray);
+ KeyFormattingUtils.setStatusImage(mContext, h.statusIcon, null, State.REVOKED, R.color.bg_gray);
enabled = false;
} else if (cursor.getInt(mIndexIsExpiry) != 0) {
h.statusIcon.setVisibility(View.VISIBLE);
- KeyFormattingUtils.setStatusImage(mContext, h.statusIcon, null, KeyFormattingUtils.STATE_EXPIRED, R.color.bg_gray);
+ KeyFormattingUtils.setStatusImage(mContext, h.statusIcon, null, State.EXPIRED, R.color.bg_gray);
enabled = false;
} else {
h.statusIcon.setVisibility(View.GONE);
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/SubkeysAdapter.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/SubkeysAdapter.java
index ff5fbb49a..096dea51f 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/SubkeysAdapter.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/SubkeysAdapter.java
@@ -272,12 +272,12 @@ public class SubkeysAdapter extends CursorAdapter {
PorterDuff.Mode.SRC_IN);
if (isRevoked) {
- vStatus.setImageResource(R.drawable.status_signature_revoked_cutout_24px);
+ vStatus.setImageResource(R.drawable.status_signature_revoked_cutout_24dp);
vStatus.setColorFilter(
mContext.getResources().getColor(R.color.bg_gray),
PorterDuff.Mode.SRC_IN);
} else if (isExpired) {
- vStatus.setImageResource(R.drawable.status_signature_expired_cutout_24px);
+ vStatus.setImageResource(R.drawable.status_signature_expired_cutout_24dp);
vStatus.setColorFilter(
mContext.getResources().getColor(R.color.bg_gray),
PorterDuff.Mode.SRC_IN);
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/UserIdsAdapter.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/UserIdsAdapter.java
index 6a4f61f4b..3486f1516 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/UserIdsAdapter.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/UserIdsAdapter.java
@@ -36,6 +36,7 @@ import org.sufficientlysecure.keychain.provider.KeychainContract.Certs;
import org.sufficientlysecure.keychain.provider.KeychainContract.UserPackets;
import org.sufficientlysecure.keychain.service.SaveKeyringParcel;
import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
+import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils.State;
public class UserIdsAdapter extends UserAttributesAdapter {
protected LayoutInflater mInflater;
@@ -127,7 +128,7 @@ public class UserIdsAdapter extends UserAttributesAdapter {
if (isRevoked) {
// set revocation icon (can this even be primary?)
- KeyFormattingUtils.setStatusImage(mContext, vVerified, null, KeyFormattingUtils.STATE_REVOKED, R.color.bg_gray);
+ KeyFormattingUtils.setStatusImage(mContext, vVerified, null, State.REVOKED, R.color.bg_gray);
// disable revoked user ids
vName.setEnabled(false);
@@ -149,13 +150,13 @@ public class UserIdsAdapter extends UserAttributesAdapter {
int isVerified = cursor.getInt(INDEX_VERIFIED);
switch (isVerified) {
case Certs.VERIFIED_SECRET:
- KeyFormattingUtils.setStatusImage(mContext, vVerified, null, KeyFormattingUtils.STATE_VERIFIED, KeyFormattingUtils.DEFAULT_COLOR);
+ KeyFormattingUtils.setStatusImage(mContext, vVerified, null, State.VERIFIED, KeyFormattingUtils.DEFAULT_COLOR);
break;
case Certs.VERIFIED_SELF:
- KeyFormattingUtils.setStatusImage(mContext, vVerified, null, KeyFormattingUtils.STATE_UNVERIFIED, KeyFormattingUtils.DEFAULT_COLOR);
+ KeyFormattingUtils.setStatusImage(mContext, vVerified, null, State.UNVERIFIED, KeyFormattingUtils.DEFAULT_COLOR);
break;
default:
- KeyFormattingUtils.setStatusImage(mContext, vVerified, null, KeyFormattingUtils.STATE_INVALID, KeyFormattingUtils.DEFAULT_COLOR);
+ KeyFormattingUtils.setStatusImage(mContext, vVerified, null, State.INVALID, KeyFormattingUtils.DEFAULT_COLOR);
break;
}
}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/AddSubkeyDialogFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/AddSubkeyDialogFragment.java
index d5376cbdc..0b1d39fc1 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/AddSubkeyDialogFragment.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/AddSubkeyDialogFragment.java
@@ -137,12 +137,10 @@ public class AddSubkeyDialogFragment extends DialogFragment {
}
});
- if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.HONEYCOMB) {
- // date picker works based on default time zone
- Calendar minDateCal = Calendar.getInstance(TimeZone.getDefault());
- minDateCal.add(Calendar.DAY_OF_YEAR, 1); // at least one day after creation (today)
- mExpiryDatePicker.setMinDate(minDateCal.getTime().getTime());
- }
+ // date picker works based on default time zone
+ Calendar minDateCal = Calendar.getInstance(TimeZone.getDefault());
+ minDateCal.add(Calendar.DAY_OF_YEAR, 1); // at least one day after creation (today)
+ mExpiryDatePicker.setMinDate(minDateCal.getTime().getTime());
{
ArrayList<Choice<Algorithm>> choices = new ArrayList<>();
@@ -283,7 +281,7 @@ public class AddSubkeyDialogFragment extends DialogFragment {
// For EC keys, add a curve
if (algorithm == Algorithm.ECDH || algorithm == Algorithm.ECDSA) {
curve = ((Choice<Curve>) mCurveSpinner.getSelectedItem()).getId();
- // Otherwise, get a keysize
+ // Otherwise, get a keysize
} else {
keySize = getProperKeyLength(algorithm, getSelectedKeyLength());
}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/CustomAlertDialogBuilder.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/CustomAlertDialogBuilder.java
index d405b1dda..794af5b15 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/CustomAlertDialogBuilder.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/CustomAlertDialogBuilder.java
@@ -1,3 +1,20 @@
+/*
+ * 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.dialog;
import android.app.AlertDialog;
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteFileDialogFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteFileDialogFragment.java
index 879e3f6da..07462b4ff 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteFileDialogFragment.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteFileDialogFragment.java
@@ -62,12 +62,9 @@ public class DeleteFileDialogFragment extends DialogFragment {
CustomAlertDialogBuilder alert = new CustomAlertDialogBuilder(activity);
-
- alert.setIcon(R.drawable.ic_dialog_alert_holo_light);
- alert.setTitle(R.string.warning);
alert.setMessage(this.getString(R.string.file_delete_confirmation, deleteFilename));
- alert.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
+ alert.setPositiveButton(R.string.btn_delete, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int id) {
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteKeyDialogFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteKeyDialogFragment.java
index 802f0c11b..32789d53b 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteKeyDialogFragment.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteKeyDialogFragment.java
@@ -83,8 +83,6 @@ public class DeleteKeyDialogFragment extends DialogFragment {
mMainMessage = (TextView) mInflateView.findViewById(R.id.mainMessage);
- builder.setTitle(R.string.warning);
-
final boolean hasSecret;
// If only a single key has been selected
@@ -110,12 +108,14 @@ public class DeleteKeyDialogFragment extends DialogFragment {
}
hasSecret = ((Long) data.get(KeyRings.HAS_ANY_SECRET)) == 1;
- // Set message depending on which key it is.
- mMainMessage.setText(getString(
- hasSecret ? R.string.secret_key_deletion_confirmation
- : R.string.public_key_deletetion_confirmation,
- name
- ));
+ if (hasSecret) {
+ // show title only for secret key deletions,
+ // see http://www.google.com/design/spec/components/dialogs.html#dialogs-behavior
+ builder.setTitle(getString(R.string.title_delete_secret_key, name));
+ mMainMessage.setText(getString(R.string.secret_key_deletion_confirmation, name));
+ } else {
+ mMainMessage.setText(getString(R.string.public_key_deletetion_confirmation, name));
+ }
} catch (ProviderHelper.NotFoundException e) {
dismiss();
return null;
@@ -125,7 +125,6 @@ public class DeleteKeyDialogFragment extends DialogFragment {
hasSecret = false;
}
- builder.setIcon(R.drawable.ic_dialog_alert_holo_light);
builder.setPositiveButton(R.string.btn_delete, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/EditSubkeyExpiryDialogFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/EditSubkeyExpiryDialogFragment.java
index fc618c9eb..37e05a61d 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/EditSubkeyExpiryDialogFragment.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/EditSubkeyExpiryDialogFragment.java
@@ -25,11 +25,14 @@ import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;
import android.support.v4.app.DialogFragment;
+import android.text.format.DateFormat;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.DatePicker;
+import android.widget.LinearLayout;
+import android.widget.TextView;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R;
@@ -97,61 +100,64 @@ public class EditSubkeyExpiryDialogFragment extends DialogFragment {
final CheckBox noExpiry = (CheckBox) view.findViewById(R.id.edit_subkey_expiry_no_expiry);
final DatePicker datePicker = (DatePicker) view.findViewById(R.id.edit_subkey_expiry_date_picker);
+ final TextView currentExpiry = (TextView) view.findViewById(R.id.edit_subkey_expiry_current_expiry);
+ final LinearLayout expiryLayout = (LinearLayout) view.findViewById(R.id.edit_subkey_expiry_layout);
noExpiry.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (isChecked) {
- datePicker.setVisibility(View.GONE);
+ expiryLayout.setVisibility(View.GONE);
} else {
- datePicker.setVisibility(View.VISIBLE);
+ expiryLayout.setVisibility(View.VISIBLE);
}
}
});
- // init date picker with default selected date
if (expiry == 0L) {
noExpiry.setChecked(true);
- datePicker.setVisibility(View.GONE);
-
- Calendar todayCal = Calendar.getInstance(TimeZone.getDefault());
- if (creationCal.after(todayCal)) {
- // Note: This is just for the rare cases where creation is _after_ today
-
- // set it to creation date +1 day (don't set it to creationCal, it would break crash
- // datePicker.setMinDate() execution with IllegalArgumentException
- Calendar creationCalPlusOne = (Calendar) creationCal.clone();
- creationCalPlusOne.add(Calendar.DAY_OF_YEAR, 1);
- datePicker.init(
- creationCalPlusOne.get(Calendar.YEAR),
- creationCalPlusOne.get(Calendar.MONTH),
- creationCalPlusOne.get(Calendar.DAY_OF_MONTH),
- null
- );
-
- } else {
- // normally, just init with today
- datePicker.init(
- todayCal.get(Calendar.YEAR),
- todayCal.get(Calendar.MONTH),
- todayCal.get(Calendar.DAY_OF_MONTH),
- null
- );
- }
+ expiryLayout.setVisibility(View.GONE);
+
+ currentExpiry.setText(R.string.btn_no_date);
} else {
noExpiry.setChecked(false);
- datePicker.setVisibility(View.VISIBLE);
+ expiryLayout.setVisibility(View.VISIBLE);
+
+ // convert from UTC to time zone of device
+ Calendar expiryCalTimeZone = (Calendar) expiryCal.clone();
+ expiryCalTimeZone.setTimeZone(TimeZone.getDefault());
+ currentExpiry.setText(DateFormat.getDateFormat(
+ getActivity()).format(expiryCalTimeZone.getTime()));
+ }
+
+ // date picker works based on default time zone
+ Calendar todayCal = Calendar.getInstance(TimeZone.getDefault());
+ if (creationCal.after(todayCal)) {
+ // NOTE: This is just for the rare cases where creation is _after_ today
+ // Min Date: Creation date + 1 day
- // set date picker to current expiry
+ Calendar creationCalPlusOne = (Calendar) creationCal.clone();
+ creationCalPlusOne.add(Calendar.DAY_OF_YEAR, 1);
+ datePicker.setMinDate(creationCalPlusOne.getTime().getTime());
datePicker.init(
- expiryCal.get(Calendar.YEAR),
- expiryCal.get(Calendar.MONTH),
- expiryCal.get(Calendar.DAY_OF_MONTH),
+ creationCalPlusOne.get(Calendar.YEAR),
+ creationCalPlusOne.get(Calendar.MONTH),
+ creationCalPlusOne.get(Calendar.DAY_OF_MONTH),
null
);
- }
+ } else {
+ // Min Date: today + 1 day
- datePicker.setMinDate(creationCal.getTime().getTime());
+ // at least one day after creation (today)
+ todayCal.add(Calendar.DAY_OF_YEAR, 1);
+ datePicker.setMinDate(todayCal.getTime().getTime());
+ datePicker.init(
+ todayCal.get(Calendar.YEAR),
+ todayCal.get(Calendar.MONTH),
+ todayCal.get(Calendar.DAY_OF_MONTH),
+ null
+ );
+ }
alert.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
@Override
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/SetPassphraseDialogFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/SetPassphraseDialogFragment.java
index a05719072..a3ffe250b 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/SetPassphraseDialogFragment.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/SetPassphraseDialogFragment.java
@@ -92,7 +92,6 @@ public class SetPassphraseDialogFragment extends DialogFragment implements OnEdi
CustomAlertDialogBuilder alert = new CustomAlertDialogBuilder(activity);
alert.setTitle(title);
- alert.setMessage(R.string.enter_passphrase_twice);
LayoutInflater inflater = activity.getLayoutInflater();
View view = inflater.inflate(R.layout.passphrase_repeat_dialog, null);
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/util/KeyFormattingUtils.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/util/KeyFormattingUtils.java
index 38ed88b9c..c5403e054 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/util/KeyFormattingUtils.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/util/KeyFormattingUtils.java
@@ -379,27 +379,29 @@ public class KeyFormattingUtils {
public static final int DEFAULT_COLOR = -1;
- public static final int STATE_REVOKED = 1;
- public static final int STATE_EXPIRED = 2;
- public static final int STATE_VERIFIED = 3;
- public static final int STATE_UNAVAILABLE = 4;
- public static final int STATE_ENCRYPTED = 5;
- public static final int STATE_NOT_ENCRYPTED = 6;
- public static final int STATE_UNVERIFIED = 7;
- public static final int STATE_UNKNOWN_KEY = 8;
- public static final int STATE_INVALID = 9;
- public static final int STATE_NOT_SIGNED = 10;
-
- public static void setStatusImage(Context context, ImageView statusIcon, int state) {
+ public static enum State {
+ REVOKED,
+ EXPIRED,
+ VERIFIED,
+ UNAVAILABLE,
+ ENCRYPTED,
+ NOT_ENCRYPTED,
+ UNVERIFIED,
+ UNKNOWN_KEY,
+ INVALID,
+ NOT_SIGNED
+ }
+
+ public static void setStatusImage(Context context, ImageView statusIcon, State state) {
setStatusImage(context, statusIcon, null, state);
}
- public static void setStatusImage(Context context, ImageView statusIcon, TextView statusText, int state) {
+ public static void setStatusImage(Context context, ImageView statusIcon, TextView statusText, State state) {
setStatusImage(context, statusIcon, statusText, state, KeyFormattingUtils.DEFAULT_COLOR, false);
}
public static void setStatusImage(Context context, ImageView statusIcon, TextView statusText,
- int state, int color) {
+ State state, int color) {
setStatusImage(context, statusIcon, statusText, state, color, false);
}
@@ -407,16 +409,16 @@ public class KeyFormattingUtils {
* Sets status image based on constant
*/
public static void setStatusImage(Context context, ImageView statusIcon, TextView statusText,
- int state, int color, boolean big) {
+ State state, int color, boolean big) {
switch (state) {
/** GREEN: everything is good **/
- case STATE_VERIFIED: {
+ case VERIFIED: {
if (big) {
statusIcon.setImageDrawable(
- context.getResources().getDrawable(R.drawable.status_signature_verified_cutout_96px));
+ context.getResources().getDrawable(R.drawable.status_signature_verified_cutout_96dp));
} else {
statusIcon.setImageDrawable(
- context.getResources().getDrawable(R.drawable.status_signature_verified_cutout_24px));
+ context.getResources().getDrawable(R.drawable.status_signature_verified_cutout_24dp));
}
if (color == KeyFormattingUtils.DEFAULT_COLOR) {
color = R.color.android_green_light;
@@ -428,9 +430,9 @@ public class KeyFormattingUtils {
}
break;
}
- case STATE_ENCRYPTED: {
+ case ENCRYPTED: {
statusIcon.setImageDrawable(
- context.getResources().getDrawable(R.drawable.status_lock_closed_24px));
+ context.getResources().getDrawable(R.drawable.status_lock_closed_24dp));
if (color == KeyFormattingUtils.DEFAULT_COLOR) {
color = R.color.android_green_light;
}
@@ -442,13 +444,13 @@ public class KeyFormattingUtils {
break;
}
/** ORANGE: mostly bad... **/
- case STATE_UNVERIFIED: {
+ case UNVERIFIED: {
if (big) {
statusIcon.setImageDrawable(
- context.getResources().getDrawable(R.drawable.status_signature_unverified_cutout_96px));
+ context.getResources().getDrawable(R.drawable.status_signature_unverified_cutout_96dp));
} else {
statusIcon.setImageDrawable(
- context.getResources().getDrawable(R.drawable.status_signature_unverified_cutout_24px));
+ context.getResources().getDrawable(R.drawable.status_signature_unverified_cutout_24dp));
}
if (color == KeyFormattingUtils.DEFAULT_COLOR) {
color = R.color.android_orange_light;
@@ -460,9 +462,9 @@ public class KeyFormattingUtils {
}
break;
}
- case STATE_UNKNOWN_KEY: {
+ case UNKNOWN_KEY: {
statusIcon.setImageDrawable(
- context.getResources().getDrawable(R.drawable.status_signature_unknown_cutout_24px));
+ context.getResources().getDrawable(R.drawable.status_signature_unknown_cutout_24dp));
if (color == KeyFormattingUtils.DEFAULT_COLOR) {
color = R.color.android_orange_light;
}
@@ -474,13 +476,13 @@ public class KeyFormattingUtils {
break;
}
/** RED: really bad... **/
- case STATE_REVOKED: {
+ case REVOKED: {
if (big) {
statusIcon.setImageDrawable(
- context.getResources().getDrawable(R.drawable.status_signature_revoked_cutout_96px));
+ context.getResources().getDrawable(R.drawable.status_signature_revoked_cutout_96dp));
} else {
statusIcon.setImageDrawable(
- context.getResources().getDrawable(R.drawable.status_signature_revoked_cutout_24px));
+ context.getResources().getDrawable(R.drawable.status_signature_revoked_cutout_24dp));
}
if (color == KeyFormattingUtils.DEFAULT_COLOR) {
color = R.color.android_red_light;
@@ -492,13 +494,13 @@ public class KeyFormattingUtils {
}
break;
}
- case STATE_EXPIRED: {
+ case EXPIRED: {
if (big) {
statusIcon.setImageDrawable(
- context.getResources().getDrawable(R.drawable.status_signature_expired_cutout_96px));
+ context.getResources().getDrawable(R.drawable.status_signature_expired_cutout_96dp));
} else {
statusIcon.setImageDrawable(
- context.getResources().getDrawable(R.drawable.status_signature_expired_cutout_24px));
+ context.getResources().getDrawable(R.drawable.status_signature_expired_cutout_24dp));
}
if (color == KeyFormattingUtils.DEFAULT_COLOR) {
color = R.color.android_red_light;
@@ -510,9 +512,9 @@ public class KeyFormattingUtils {
}
break;
}
- case STATE_NOT_ENCRYPTED: {
+ case NOT_ENCRYPTED: {
statusIcon.setImageDrawable(
- context.getResources().getDrawable(R.drawable.status_lock_open_24px));
+ context.getResources().getDrawable(R.drawable.status_lock_open_24dp));
if (color == KeyFormattingUtils.DEFAULT_COLOR) {
color = R.color.android_red_light;
}
@@ -523,9 +525,9 @@ public class KeyFormattingUtils {
}
break;
}
- case STATE_NOT_SIGNED: {
+ case NOT_SIGNED: {
statusIcon.setImageDrawable(
- context.getResources().getDrawable(R.drawable.status_signature_unknown_cutout_24px));
+ context.getResources().getDrawable(R.drawable.status_signature_unknown_cutout_24dp));
if (color == KeyFormattingUtils.DEFAULT_COLOR) {
color = R.color.android_red_light;
}
@@ -536,9 +538,9 @@ public class KeyFormattingUtils {
}
break;
}
- case STATE_INVALID: {
+ case INVALID: {
statusIcon.setImageDrawable(
- context.getResources().getDrawable(R.drawable.status_signature_invalid_cutout_24px));
+ context.getResources().getDrawable(R.drawable.status_signature_invalid_cutout_24dp));
if (color == KeyFormattingUtils.DEFAULT_COLOR) {
color = R.color.android_red_light;
}
@@ -550,9 +552,9 @@ public class KeyFormattingUtils {
break;
}
/** special **/
- case STATE_UNAVAILABLE: {
+ case UNAVAILABLE: {
statusIcon.setImageDrawable(
- context.getResources().getDrawable(R.drawable.status_signature_invalid_cutout_24px));
+ context.getResources().getDrawable(R.drawable.status_signature_invalid_cutout_24dp));
if (color == KeyFormattingUtils.DEFAULT_COLOR) {
color = R.color.bg_gray;
}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/CertifyKeySpinner.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/CertifyKeySpinner.java
index 6d0e6556f..fc912fccb 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/CertifyKeySpinner.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/CertifyKeySpinner.java
@@ -31,6 +31,7 @@ import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.provider.KeychainContract;
import org.sufficientlysecure.keychain.provider.KeychainDatabase;
import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
+import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils.State;
public class CertifyKeySpinner extends KeySpinner {
private long mHiddenMasterKeyId = Constants.key.none;
@@ -103,16 +104,16 @@ public class CertifyKeySpinner extends KeySpinner {
@Override
boolean setStatus(Context context, Cursor cursor, ImageView statusView) {
if (cursor.getInt(mIndexIsRevoked) != 0) {
- KeyFormattingUtils.setStatusImage(getContext(), statusView, null, KeyFormattingUtils.STATE_REVOKED, R.color.bg_gray);
+ KeyFormattingUtils.setStatusImage(getContext(), statusView, null, State.REVOKED, R.color.bg_gray);
return false;
}
if (cursor.getInt(mIndexIsExpired) != 0) {
- KeyFormattingUtils.setStatusImage(getContext(), statusView, null, KeyFormattingUtils.STATE_EXPIRED, R.color.bg_gray);
+ KeyFormattingUtils.setStatusImage(getContext(), statusView, null, State.EXPIRED, R.color.bg_gray);
return false;
}
// don't invalidate the "None" entry, which is also null!
if (cursor.getPosition() != 0 && cursor.isNull(mIndexHasCertify)) {
- KeyFormattingUtils.setStatusImage(getContext(), statusView, null, KeyFormattingUtils.STATE_UNAVAILABLE, R.color.bg_gray);
+ KeyFormattingUtils.setStatusImage(getContext(), statusView, null, State.UNAVAILABLE, R.color.bg_gray);
return false;
}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/EncryptKeyCompletionView.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/EncryptKeyCompletionView.java
index f05f5f96b..d20e2bc99 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/EncryptKeyCompletionView.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/EncryptKeyCompletionView.java
@@ -90,7 +90,7 @@ public class EncryptKeyCompletionView extends TokenCompleteTextView {
}
private void setImageByKey(ImageView view, EncryptionKey key) {
- Bitmap photo = ContactHelper.photoFromFingerprint(getContext().getContentResolver(), key.getFingerprint());
+ Bitmap photo = ContactHelper.getCachedPhotoByMasterKeyId(getContext().getContentResolver(), key.getKeyId());
if (photo != null) {
view.setImageBitmap(photo);
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SignKeySpinner.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SignKeySpinner.java
index fe91e306e..10327a6a4 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SignKeySpinner.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SignKeySpinner.java
@@ -29,6 +29,7 @@ import android.widget.ImageView;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.provider.KeychainContract;
import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
+import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils.State;
public class SignKeySpinner extends KeySpinner {
public SignKeySpinner(Context context) {
@@ -84,15 +85,15 @@ public class SignKeySpinner extends KeySpinner {
@Override
boolean setStatus(Context context, Cursor cursor, ImageView statusView) {
if (cursor.getInt(mIndexIsRevoked) != 0) {
- KeyFormattingUtils.setStatusImage(getContext(), statusView, null, KeyFormattingUtils.STATE_REVOKED, R.color.bg_gray);
+ KeyFormattingUtils.setStatusImage(getContext(), statusView, null, State.REVOKED, R.color.bg_gray);
return false;
}
if (cursor.getInt(mIndexIsExpired) != 0) {
- KeyFormattingUtils.setStatusImage(getContext(), statusView, null, KeyFormattingUtils.STATE_EXPIRED, R.color.bg_gray);
+ KeyFormattingUtils.setStatusImage(getContext(), statusView, null, State.EXPIRED, R.color.bg_gray);
return false;
}
if (cursor.getInt(mIndexHasSign) == 0) {
- KeyFormattingUtils.setStatusImage(getContext(), statusView, null, KeyFormattingUtils.STATE_UNAVAILABLE, R.color.bg_gray);
+ KeyFormattingUtils.setStatusImage(getContext(), statusView, null, State.UNAVAILABLE, R.color.bg_gray);
return false;
}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/ContactHelper.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/ContactHelper.java
index 28480cee5..c66dc04d0 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/ContactHelper.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/ContactHelper.java
@@ -20,18 +20,15 @@ package org.sufficientlysecure.keychain.util;
import android.accounts.Account;
import android.accounts.AccountManager;
import android.annotation.TargetApi;
-import android.content.ContentProviderClient;
import android.content.ContentProviderOperation;
import android.content.ContentResolver;
import android.content.ContentUris;
-import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Build;
-import android.os.RemoteException;
import android.provider.ContactsContract;
import android.util.Patterns;
@@ -44,7 +41,6 @@ import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
import java.io.InputStream;
import java.util.ArrayList;
-import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
@@ -53,40 +49,7 @@ import java.util.Set;
public class ContactHelper {
- public static final String[] KEYS_TO_CONTACT_PROJECTION = new String[]{
- KeychainContract.KeyRings.USER_ID,
- KeychainContract.KeyRings.FINGERPRINT,
- KeychainContract.KeyRings.KEY_ID,
- KeychainContract.KeyRings.MASTER_KEY_ID,
- KeychainContract.KeyRings.EXPIRY,
- KeychainContract.KeyRings.IS_REVOKED};
-
- public static final int INDEX_USER_ID = 0;
- public static final int INDEX_FINGERPRINT = 1;
- public static final int INDEX_KEY_ID = 2;
- public static final int INDEX_MASTER_KEY_ID = 3;
- public static final int INDEX_EXPIRY = 4;
- public static final int INDEX_IS_REVOKED = 5;
-
- public static final String[] USER_IDS_PROJECTION = new String[]{
- UserPackets.USER_ID
- };
-
- public static final int INDEX_USER_IDS_USER_ID = 0;
-
- public static final String NON_REVOKED_SELECTION = UserPackets.IS_REVOKED + "=0";
-
- public static final String[] ID_PROJECTION = new String[]{ContactsContract.RawContacts._ID};
- public static final String[] SOURCE_ID_PROJECTION = new String[]{ContactsContract.RawContacts.SOURCE_ID};
-
- public static final String ACCOUNT_TYPE_AND_SOURCE_ID_SELECTION =
- ContactsContract.RawContacts.ACCOUNT_TYPE + "=? AND " + ContactsContract.RawContacts.SOURCE_ID + "=?";
- public static final String ACCOUNT_TYPE_SELECTION = ContactsContract.RawContacts.ACCOUNT_TYPE + "=?";
- public static final String RAW_CONTACT_AND_MIMETYPE_SELECTION =
- ContactsContract.Data.RAW_CONTACT_ID + "=? AND " + ContactsContract.Data.MIMETYPE + "=?";
- public static final String ID_SELECTION = ContactsContract.RawContacts._ID + "=?";
-
- private static final Map<String, Bitmap> photoCache = new HashMap<>();
+ private static final Map<Long, Bitmap> photoCache = new HashMap<>();
public static List<String> getPossibleUserEmails(Context context) {
Set<String> accountMails = getAccountEmails(context);
@@ -282,27 +245,30 @@ public class ContactHelper {
return null;
}
- public static Bitmap photoFromFingerprint(ContentResolver contentResolver, String fingerprint) {
- if (fingerprint == null) {
+ public static Bitmap getCachedPhotoByMasterKeyId(ContentResolver contentResolver, long masterKeyId) {
+ if (masterKeyId == -1) {
return null;
}
- if (!photoCache.containsKey(fingerprint)) {
- photoCache.put(fingerprint, loadPhotoFromFingerprint(contentResolver, fingerprint));
+ if (!photoCache.containsKey(masterKeyId)) {
+ photoCache.put(masterKeyId, loadPhotoByMasterKeyId(contentResolver, masterKeyId, false));
}
- return photoCache.get(fingerprint);
+ return photoCache.get(masterKeyId);
}
- private static Bitmap loadPhotoFromFingerprint(ContentResolver contentResolver, String fingerprint) {
- if (fingerprint == null) return null;
+ public static Bitmap loadPhotoByMasterKeyId(ContentResolver contentResolver, long masterKeyId,
+ boolean highRes) {
+ if (masterKeyId == -1) {
+ return null;
+ }
try {
- int rawContactId = findRawContactId(contentResolver, fingerprint);
+ long rawContactId = findRawContactId(contentResolver, masterKeyId);
if (rawContactId == -1) {
return null;
}
Uri rawContactUri = ContentUris.withAppendedId(ContactsContract.RawContacts.CONTENT_URI, rawContactId);
Uri contactUri = ContactsContract.RawContacts.getContactLookupUri(contentResolver, rawContactUri);
InputStream photoInputStream =
- ContactsContract.Contacts.openContactPhotoInputStream(contentResolver, contactUri);
+ ContactsContract.Contacts.openContactPhotoInputStream(contentResolver, contactUri, highRes);
if (photoInputStream == null) {
return null;
}
@@ -312,12 +278,27 @@ public class ContactHelper {
}
}
+ public static final String[] KEYS_TO_CONTACT_PROJECTION = new String[]{
+ KeychainContract.KeyRings.MASTER_KEY_ID,
+ KeychainContract.KeyRings.USER_ID,
+ KeychainContract.KeyRings.IS_EXPIRED,
+ KeychainContract.KeyRings.IS_REVOKED};
+
+ public static final int INDEX_MASTER_KEY_ID = 0;
+ public static final int INDEX_USER_ID = 1;
+ public static final int INDEX_IS_EXPIRED = 2;
+ public static final int INDEX_IS_REVOKED = 3;
+
/**
- * Write the current Keychain to the contact db
+ * Write/Update the current OpenKeychain keys to the contact db
*/
public static void writeKeysToContacts(Context context) {
ContentResolver resolver = context.getContentResolver();
- Set<String> deletedKeys = getRawContactFingerprints(resolver);
+ Set<Long> deletedKeys = getRawContactMasterKeyIds(resolver);
+
+ if (Constants.DEBUG_SYNC_REMOVE_CONTACTS) {
+ debugDeleteRawContacts(resolver);
+ }
// ContentProviderClient client = resolver.acquireContentProviderClient(ContactsContract.AUTHORITY_URI);
// ContentValues values = new ContentValues();
@@ -336,42 +317,41 @@ public class ContactHelper {
null, null, null);
if (cursor != null) {
while (cursor.moveToNext()) {
- String[] primaryUserId = KeyRing.splitUserId(cursor.getString(INDEX_USER_ID));
- String fingerprint = KeyFormattingUtils.convertFingerprintToHex(cursor.getBlob(INDEX_FINGERPRINT));
- deletedKeys.remove(fingerprint);
-
- Log.d(Constants.TAG, "fingerprint: " + fingerprint);
-
- String keyIdShort = KeyFormattingUtils.convertKeyIdToHexShort(cursor.getLong(INDEX_KEY_ID));
long masterKeyId = cursor.getLong(INDEX_MASTER_KEY_ID);
- boolean isExpired = !cursor.isNull(INDEX_EXPIRY)
- && new Date(cursor.getLong(INDEX_EXPIRY) * 1000).before(new Date());
+ String[] userIdSplit = KeyRing.splitUserId(cursor.getString(INDEX_USER_ID));
+ String keyIdShort = KeyFormattingUtils.convertKeyIdToHexShort(cursor.getLong(INDEX_MASTER_KEY_ID));
+ boolean isExpired = cursor.getInt(INDEX_IS_EXPIRED) != 0;
boolean isRevoked = cursor.getInt(INDEX_IS_REVOKED) > 0;
- int rawContactId = findRawContactId(resolver, fingerprint);
- ArrayList<ContentProviderOperation> ops = new ArrayList<>();
- Log.d(Constants.TAG, "raw contact id: " + rawContactId);
+ Log.d(Constants.TAG, "masterKeyId: " + masterKeyId);
+
+ deletedKeys.remove(masterKeyId);
+
+ // get raw contact to this master key id
+ long rawContactId = findRawContactId(resolver, masterKeyId);
+ Log.d(Constants.TAG, "rawContactId: " + rawContactId);
+
+ ArrayList<ContentProviderOperation> ops = new ArrayList<>();
// Do not store expired or revoked keys in contact db - and remove them if they already exist
if (isExpired || isRevoked) {
Log.d(Constants.TAG, "Expired or revoked: Deleting " + rawContactId);
if (rawContactId != -1) {
- resolver.delete(ContactsContract.RawContacts.CONTENT_URI, ID_SELECTION,
- new String[]{Integer.toString(rawContactId)});
+ deleteRawContactById(resolver, rawContactId);
}
- } else if (primaryUserId[0] != null) {
+ } else if (userIdSplit[0] != null) {
// Create a new rawcontact with corresponding key if it does not exist yet
if (rawContactId == -1) {
- Log.d(Constants.TAG, "Insert new raw contact with fingerprint " + fingerprint);
+ Log.d(Constants.TAG, "Insert new raw contact with masterKeyId " + masterKeyId);
- insertContact(ops, context, fingerprint);
+ insertContact(ops, context, masterKeyId);
writeContactKey(ops, context, rawContactId, masterKeyId, keyIdShort);
}
// We always update the display name (which is derived from primary user id)
// and email addresses from user id
- writeContactDisplayName(ops, rawContactId, primaryUserId[0]);
+ writeContactDisplayName(ops, rawContactId, userIdSplit[0]);
writeContactEmail(ops, resolver, rawContactId, masterKeyId);
try {
resolver.applyBatch(ContactsContract.AUTHORITY, ops);
@@ -383,42 +363,84 @@ public class ContactHelper {
cursor.close();
}
- // Delete fingerprints that are no longer present in OK
- for (String fingerprint : deletedKeys) {
- resolver.delete(ContactsContract.RawContacts.CONTENT_URI, ACCOUNT_TYPE_AND_SOURCE_ID_SELECTION,
- new String[]{Constants.ACCOUNT_TYPE, fingerprint});
+ // Delete master key ids that are no longer present in OK
+ for (Long masterKeyId : deletedKeys) {
+ Log.d(Constants.TAG, "Delete raw contact with masterKeyId " + masterKeyId);
+ deleteRawContactByMasterKeyId(resolver, masterKeyId);
}
}
/**
- * @return a set of all key fingerprints currently present in the contact db
+ * Delete all raw contacts associated to OpenKeychain.
+ * <p/>
+ * TODO: Does this work?
+ */
+ private static int debugDeleteRawContacts(ContentResolver resolver) {
+ Log.d(Constants.TAG, "Deleting all raw contacts associated to OK...");
+ return resolver.delete(ContactsContract.RawContacts.CONTENT_URI,
+ ContactsContract.RawContacts.ACCOUNT_TYPE + "=?",
+ new String[]{
+ Constants.ACCOUNT_TYPE
+ });
+ }
+
+ private static int deleteRawContactById(ContentResolver resolver, long rawContactId) {
+ return resolver.delete(ContactsContract.RawContacts.CONTENT_URI,
+ ContactsContract.RawContacts.ACCOUNT_TYPE + "=? AND " + ContactsContract.RawContacts._ID + "=?",
+ new String[]{
+ Constants.ACCOUNT_TYPE, Long.toString(rawContactId)
+ });
+ }
+
+ private static int deleteRawContactByMasterKeyId(ContentResolver resolver, long masterKeyId) {
+ return resolver.delete(ContactsContract.RawContacts.CONTENT_URI,
+ ContactsContract.RawContacts.ACCOUNT_TYPE + "=? AND " + ContactsContract.RawContacts.SOURCE_ID + "=?",
+ new String[]{
+ Constants.ACCOUNT_TYPE, Long.toString(masterKeyId)
+ });
+ }
+
+ /**
+ * @return a set of all key master key ids currently present in the contact db
*/
- private static Set<String> getRawContactFingerprints(ContentResolver resolver) {
- HashSet<String> result = new HashSet<>();
- Cursor fingerprints = resolver.query(ContactsContract.RawContacts.CONTENT_URI, SOURCE_ID_PROJECTION,
- ACCOUNT_TYPE_SELECTION, new String[]{Constants.ACCOUNT_TYPE}, null);
- if (fingerprints != null) {
- while (fingerprints.moveToNext()) {
- result.add(fingerprints.getString(0));
+ private static Set<Long> getRawContactMasterKeyIds(ContentResolver resolver) {
+ HashSet<Long> result = new HashSet<>();
+ Cursor masterKeyIds = resolver.query(ContactsContract.RawContacts.CONTENT_URI,
+ new String[]{
+ ContactsContract.RawContacts.SOURCE_ID
+ },
+ ContactsContract.RawContacts.ACCOUNT_TYPE + "=?",
+ new String[]{
+ Constants.ACCOUNT_TYPE
+ }, null);
+ if (masterKeyIds != null) {
+ while (masterKeyIds.moveToNext()) {
+ result.add(masterKeyIds.getLong(0));
}
- fingerprints.close();
+ masterKeyIds.close();
}
return result;
}
/**
- * This will search the contact db for a raw contact with a given fingerprint
+ * This will search the contact db for a raw contact with a given master key id
*
* @return raw contact id or -1 if not found
*/
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
- private static int findRawContactId(ContentResolver resolver, String fingerprint) {
- int rawContactId = -1;
- Cursor raw = resolver.query(ContactsContract.RawContacts.CONTENT_URI, ID_PROJECTION,
- ACCOUNT_TYPE_AND_SOURCE_ID_SELECTION, new String[]{Constants.ACCOUNT_TYPE, fingerprint}, null, null);
+ private static long findRawContactId(ContentResolver resolver, long masterKeyId) {
+ long rawContactId = -1;
+ Cursor raw = resolver.query(ContactsContract.RawContacts.CONTENT_URI,
+ new String[]{
+ ContactsContract.RawContacts._ID
+ },
+ ContactsContract.RawContacts.ACCOUNT_TYPE + "=? AND " + ContactsContract.RawContacts.SOURCE_ID + "=?",
+ new String[]{
+ Constants.ACCOUNT_TYPE, Long.toString(masterKeyId)
+ }, null, null);
if (raw != null) {
if (raw.moveToNext()) {
- rawContactId = raw.getInt(0);
+ rawContactId = raw.getLong(0);
}
raw.close();
}
@@ -426,13 +448,13 @@ public class ContactHelper {
}
/**
- * Creates a empty raw contact with a given fingerprint
+ * Creates a empty raw contact with a given masterKeyId
*/
- private static void insertContact(ArrayList<ContentProviderOperation> ops, Context context, String fingerprint) {
+ private static void insertContact(ArrayList<ContentProviderOperation> ops, Context context, long masterKeyId) {
ops.add(ContentProviderOperation.newInsert(ContactsContract.RawContacts.CONTENT_URI)
.withValue(ContactsContract.RawContacts.ACCOUNT_NAME, Constants.ACCOUNT_NAME)
.withValue(ContactsContract.RawContacts.ACCOUNT_TYPE, Constants.ACCOUNT_TYPE)
- .withValue(ContactsContract.RawContacts.SOURCE_ID, fingerprint)
+ .withValue(ContactsContract.RawContacts.SOURCE_ID, Long.toString(masterKeyId))
.build());
}
@@ -441,7 +463,7 @@ public class ContactHelper {
* <p/>
* This creates the link to OK in contact details
*/
- private static void writeContactKey(ArrayList<ContentProviderOperation> ops, Context context, int rawContactId,
+ private static void writeContactKey(ArrayList<ContentProviderOperation> ops, Context context, long rawContactId,
long masterKeyId, String keyIdShort) {
ops.add(referenceRawContact(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI), rawContactId)
.withValue(ContactsContract.Data.MIMETYPE, Constants.CUSTOM_CONTACT_DATA_MIME_TYPE)
@@ -454,16 +476,22 @@ public class ContactHelper {
* Write all known email addresses of a key (derived from user ids) to a given raw contact
*/
private static void writeContactEmail(ArrayList<ContentProviderOperation> ops, ContentResolver resolver,
- int rawContactId, long masterKeyId) {
- ops.add(selectByRawContactAndItemType(ContentProviderOperation.newDelete(ContactsContract.Data.CONTENT_URI),
+ long rawContactId, long masterKeyId) {
+ ops.add(selectByRawContactAndItemType(
+ ContentProviderOperation.newDelete(ContactsContract.Data.CONTENT_URI),
rawContactId, ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE).build());
Cursor ids = resolver.query(UserPackets.buildUserIdsUri(masterKeyId),
- USER_IDS_PROJECTION, NON_REVOKED_SELECTION, null, null);
+ new String[]{
+ UserPackets.USER_ID
+ },
+ UserPackets.IS_REVOKED + "=0",
+ null, null);
if (ids != null) {
while (ids.moveToNext()) {
String[] userId = KeyRing.splitUserId(ids.getString(0));
if (userId[1] != null) {
- ops.add(referenceRawContact(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI),
+ ops.add(referenceRawContact(
+ ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI),
rawContactId)
.withValue(ContactsContract.Data.MIMETYPE,
ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE)
@@ -475,7 +503,7 @@ public class ContactHelper {
}
}
- private static void writeContactDisplayName(ArrayList<ContentProviderOperation> ops, int rawContactId,
+ private static void writeContactDisplayName(ArrayList<ContentProviderOperation> ops, long rawContactId,
String displayName) {
if (displayName != null) {
ops.add(insertOrUpdateForRawContact(ContactsContract.Data.CONTENT_URI, rawContactId,
@@ -486,13 +514,13 @@ public class ContactHelper {
}
private static ContentProviderOperation.Builder referenceRawContact(ContentProviderOperation.Builder builder,
- int rawContactId) {
+ long rawContactId) {
return rawContactId == -1 ?
builder.withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0) :
builder.withValue(ContactsContract.Data.RAW_CONTACT_ID, rawContactId);
}
- private static ContentProviderOperation.Builder insertOrUpdateForRawContact(Uri uri, int rawContactId,
+ private static ContentProviderOperation.Builder insertOrUpdateForRawContact(Uri uri, long rawContactId,
String itemType) {
if (rawContactId == -1) {
return referenceRawContact(ContentProviderOperation.newInsert(uri), rawContactId).withValue(
@@ -503,8 +531,11 @@ public class ContactHelper {
}
private static ContentProviderOperation.Builder selectByRawContactAndItemType(
- ContentProviderOperation.Builder builder, int rawContactId, String itemType) {
- return builder.withSelection(RAW_CONTACT_AND_MIMETYPE_SELECTION,
- new String[]{Integer.toString(rawContactId), itemType});
+ ContentProviderOperation.Builder builder, long rawContactId, String itemType) {
+ return builder.withSelection(
+ ContactsContract.Data.RAW_CONTACT_ID + "=? AND " + ContactsContract.Data.MIMETYPE + "=?",
+ new String[]{
+ Long.toString(rawContactId), itemType
+ });
}
}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/Preferences.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/Preferences.java
index a36af5c87..44c1e6b6c 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/Preferences.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/Preferences.java
@@ -20,11 +20,7 @@ package org.sufficientlysecure.keychain.util;
import android.content.Context;
import android.content.SharedPreferences;
-import android.os.Build;
-import org.spongycastle.bcpg.CompressionAlgorithmTags;
-import org.spongycastle.bcpg.HashAlgorithmTags;
-import org.spongycastle.openpgp.PGPEncryptedData;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.Constants.Pref;
@@ -59,12 +55,8 @@ public class Preferences {
}
public void updateSharedPreferences(Context context) {
- // multi-process preferences
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
- mSharedPreferences = context.getSharedPreferences("APG.main", Context.MODE_MULTI_PROCESS);
- } else {
- mSharedPreferences = context.getSharedPreferences("APG.main", Context.MODE_PRIVATE);
- }
+ // multi-process safe preferences
+ mSharedPreferences = context.getSharedPreferences("APG.main", Context.MODE_MULTI_PROCESS);
}
public String getLanguage() {
@@ -103,60 +95,6 @@ public class Preferences {
editor.commit();
}
- public int getDefaultEncryptionAlgorithm() {
- return mSharedPreferences.getInt(Constants.Pref.DEFAULT_ENCRYPTION_ALGORITHM,
- PGPEncryptedData.AES_256);
- }
-
- public void setDefaultEncryptionAlgorithm(int value) {
- SharedPreferences.Editor editor = mSharedPreferences.edit();
- editor.putInt(Constants.Pref.DEFAULT_ENCRYPTION_ALGORITHM, value);
- editor.commit();
- }
-
- public int getDefaultHashAlgorithm() {
- return mSharedPreferences.getInt(Constants.Pref.DEFAULT_HASH_ALGORITHM,
- HashAlgorithmTags.SHA256);
- }
-
- public void setDefaultHashAlgorithm(int value) {
- SharedPreferences.Editor editor = mSharedPreferences.edit();
- editor.putInt(Constants.Pref.DEFAULT_HASH_ALGORITHM, value);
- editor.commit();
- }
-
- public int getDefaultMessageCompression() {
- return mSharedPreferences.getInt(Constants.Pref.DEFAULT_MESSAGE_COMPRESSION,
- CompressionAlgorithmTags.ZLIB);
- }
-
- public void setDefaultMessageCompression(int value) {
- SharedPreferences.Editor editor = mSharedPreferences.edit();
- editor.putInt(Constants.Pref.DEFAULT_MESSAGE_COMPRESSION, value);
- editor.commit();
- }
-
- public int getDefaultFileCompression() {
- return mSharedPreferences.getInt(Constants.Pref.DEFAULT_FILE_COMPRESSION,
- CompressionAlgorithmTags.UNCOMPRESSED);
- }
-
- public void setDefaultFileCompression(int value) {
- SharedPreferences.Editor editor = mSharedPreferences.edit();
- editor.putInt(Constants.Pref.DEFAULT_FILE_COMPRESSION, value);
- editor.commit();
- }
-
- public boolean getDefaultAsciiArmor() {
- return mSharedPreferences.getBoolean(Constants.Pref.DEFAULT_ASCII_ARMOR, false);
- }
-
- public void setDefaultAsciiArmor(boolean value) {
- SharedPreferences.Editor editor = mSharedPreferences.edit();
- editor.putBoolean(Constants.Pref.DEFAULT_ASCII_ARMOR, value);
- editor.commit();
- }
-
public boolean getCachedConsolidate() {
return mSharedPreferences.getBoolean(Pref.CACHED_CONSOLIDATE, false);
}
@@ -210,6 +148,7 @@ public class Preferences {
}
return servers.toArray(chunks);
}
+
public String getPreferredKeyserver() {
return getKeyServers()[0];
}
@@ -231,21 +170,12 @@ public class Preferences {
editor.commit();
}
- public void setWriteVersionHeader(boolean conceal) {
- SharedPreferences.Editor editor = mSharedPreferences.edit();
- editor.putBoolean(Constants.Pref.WRITE_VERSION_HEADER, conceal);
- editor.commit();
- }
-
- public boolean getWriteVersionHeader() {
- return mSharedPreferences.getBoolean(Constants.Pref.WRITE_VERSION_HEADER, false);
- }
-
public void setSearchKeyserver(boolean searchKeyserver) {
SharedPreferences.Editor editor = mSharedPreferences.edit();
editor.putBoolean(Pref.SEARCH_KEYSERVER, searchKeyserver);
editor.commit();
}
+
public void setSearchKeybase(boolean searchKeybase) {
SharedPreferences.Editor editor = mSharedPreferences.edit();
editor.putBoolean(Pref.SEARCH_KEYBASE, searchKeybase);
@@ -253,7 +183,7 @@ public class Preferences {
}
public CloudSearchPrefs getCloudSearchPrefs() {
- return new CloudSearchPrefs(mSharedPreferences.getBoolean(Pref.SEARCH_KEYSERVER, true),
+ return new CloudSearchPrefs(mSharedPreferences.getBoolean(Pref.SEARCH_KEYSERVER, true),
mSharedPreferences.getBoolean(Pref.SEARCH_KEYBASE, true),
getPreferredKeyserver());
}
@@ -301,26 +231,9 @@ public class Preferences {
}
setKeyServers(servers.toArray(new String[servers.size()]));
-
- // migrate old uncompressed constant to new one
- if (mSharedPreferences.getInt(Constants.Pref.DEFAULT_FILE_COMPRESSION, 0)
- == 0x21070001) {
- setDefaultFileCompression(CompressionAlgorithmTags.UNCOMPRESSED);
- }
-
- // migrate away from MD5
- if (mSharedPreferences.getInt(Constants.Pref.DEFAULT_HASH_ALGORITHM, 0)
- == HashAlgorithmTags.MD5) {
- setDefaultHashAlgorithm(HashAlgorithmTags.SHA256);
- }
}
// fall through
case 4: {
- // for compatibility: change from SHA512 to SHA256
- if (mSharedPreferences.getInt(Constants.Pref.DEFAULT_HASH_ALGORITHM, 0)
- == HashAlgorithmTags.SHA512) {
- setDefaultHashAlgorithm(HashAlgorithmTags.SHA256);
- }
}
}