From e72e47d92ec957d42c04bf8b1e0dd8e8b641cd7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Thu, 14 Aug 2014 15:24:37 +0200 Subject: Remove support for v3 sig generation --- .../org/sufficientlysecure/keychain/Constants.java | 1 - .../keychain/helper/Preferences.java | 10 --- .../keychain/pgp/PgpSignEncrypt.java | 90 +++------------------- .../keychain/remote/OpenPgpService.java | 2 - .../keychain/service/KeychainIntentService.java | 1 - .../keychain/ui/PreferencesActivity.java | 18 ----- OpenKeychain/src/main/res/values/strings.xml | 1 - OpenKeychain/src/main/res/xml/adv_preferences.xml | 12 +-- 8 files changed, 13 insertions(+), 122 deletions(-) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/Constants.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/Constants.java index f240b5cc2..755d74ac2 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/Constants.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/Constants.java @@ -64,7 +64,6 @@ public final class Constants { public static final String DEFAULT_FILE_COMPRESSION = "defaultFileCompression"; public static final String PASSPHRASE_CACHE_TTL = "passphraseCacheTtl"; public static final String LANGUAGE = "language"; - public static final String FORCE_V3_SIGNATURES = "forceV3Signatures"; public static final String KEY_SERVERS = "keyServers"; public static final String KEY_SERVERS_DEFAULT_VERSION = "keyServersDefaultVersion"; public static final String WRITE_VERSION_HEADER = "writeVersionHeader"; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/helper/Preferences.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/helper/Preferences.java index a0bac80aa..72e88d793 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/helper/Preferences.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/helper/Preferences.java @@ -130,16 +130,6 @@ public class Preferences { editor.commit(); } - public boolean getForceV3Signatures() { - return mSharedPreferences.getBoolean(Constants.Pref.FORCE_V3_SIGNATURES, false); - } - - public void setForceV3Signatures(boolean value) { - SharedPreferences.Editor editor = mSharedPreferences.edit(); - editor.putBoolean(Constants.Pref.FORCE_V3_SIGNATURES, value); - editor.commit(); - } - public boolean isFirstTime() { return mSharedPreferences.getBoolean(Constants.Pref.FIRST_TIME, true); } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncrypt.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncrypt.java index b0e546662..263b0c5bb 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncrypt.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncrypt.java @@ -27,7 +27,6 @@ import org.spongycastle.openpgp.PGPException; import org.spongycastle.openpgp.PGPLiteralData; import org.spongycastle.openpgp.PGPLiteralDataGenerator; import org.spongycastle.openpgp.PGPSignatureGenerator; -import org.spongycastle.openpgp.PGPV3SignatureGenerator; import org.spongycastle.openpgp.operator.jcajce.JcePBEKeyEncryptionMethodGenerator; import org.spongycastle.openpgp.operator.jcajce.JcePGPDataEncryptorBuilder; import org.sufficientlysecure.keychain.Constants; @@ -68,7 +67,6 @@ public class PgpSignEncrypt { private int mSymmetricEncryptionAlgorithm; private long mSignatureMasterKeyId; private int mSignatureHashAlgorithm; - private boolean mSignatureForceV3; private String mSignaturePassphrase; private boolean mEncryptToSigner; private boolean mCleartextInput; @@ -99,7 +97,6 @@ public class PgpSignEncrypt { this.mSymmetricEncryptionAlgorithm = builder.mSymmetricEncryptionAlgorithm; this.mSignatureMasterKeyId = builder.mSignatureMasterKeyId; this.mSignatureHashAlgorithm = builder.mSignatureHashAlgorithm; - this.mSignatureForceV3 = builder.mSignatureForceV3; this.mSignaturePassphrase = builder.mSignaturePassphrase; this.mEncryptToSigner = builder.mEncryptToSigner; this.mCleartextInput = builder.mCleartextInput; @@ -122,7 +119,6 @@ public class PgpSignEncrypt { private int mSymmetricEncryptionAlgorithm = 0; private long mSignatureMasterKeyId = Constants.key.none; private int mSignatureHashAlgorithm = 0; - private boolean mSignatureForceV3 = false; private String mSignaturePassphrase = null; private boolean mEncryptToSigner = false; private boolean mCleartextInput = false; @@ -179,11 +175,6 @@ public class PgpSignEncrypt { return this; } - public Builder setSignatureForceV3(boolean signatureForceV3) { - mSignatureForceV3 = signatureForceV3; - return this; - } - public Builder setSignaturePassphrase(String signaturePassphrase) { mSignaturePassphrase = signaturePassphrase; return this; @@ -349,19 +340,13 @@ public class PgpSignEncrypt { /* Initialize signature generator object for later usage */ PGPSignatureGenerator signatureGenerator = null; - PGPV3SignatureGenerator signatureV3Generator = null; if (enableSignature) { updateProgress(R.string.progress_preparing_signature, 4, 100); try { boolean cleartext = mCleartextInput && mEnableAsciiArmorOutput && !enableEncryption; - if (mSignatureForceV3) { - signatureV3Generator = signingKey.getV3SignatureGenerator( - mSignatureHashAlgorithm, cleartext); - } else { - signatureGenerator = signingKey.getSignatureGenerator( - mSignatureHashAlgorithm, cleartext); - } + signatureGenerator = signingKey.getSignatureGenerator( + mSignatureHashAlgorithm, cleartext); } catch (PgpGeneralException e) { // TODO throw correct type of exception (which shouldn't be PGPException) throw new KeyExtractionException(); @@ -388,11 +373,7 @@ public class PgpSignEncrypt { } if (enableSignature) { - if (mSignatureForceV3) { - signatureV3Generator.generateOnePassVersion(false).encode(bcpgOut); - } else { - signatureGenerator.generateOnePassVersion(false).encode(bcpgOut); - } + signatureGenerator.generateOnePassVersion(false).encode(bcpgOut); } PGPLiteralDataGenerator literalGen = new PGPLiteralDataGenerator(); @@ -408,11 +389,7 @@ public class PgpSignEncrypt { // update signature buffer if signature is requested if (enableSignature) { - if (mSignatureForceV3) { - signatureV3Generator.update(buffer, 0, length); - } else { - signatureGenerator.update(buffer, 0, length); - } + signatureGenerator.update(buffer, 0, length); } alreadyWritten += length; @@ -435,11 +412,7 @@ public class PgpSignEncrypt { final BufferedReader reader = new BufferedReader(new InputStreamReader(in)); // update signature buffer with first line - if (mSignatureForceV3) { - processLineV3(reader.readLine(), armorOut, signatureV3Generator); - } else { - processLine(reader.readLine(), armorOut, signatureGenerator); - } + processLine(reader.readLine(), armorOut, signatureGenerator); // TODO: progress: fake annealing? while (true) { @@ -454,13 +427,8 @@ public class PgpSignEncrypt { armorOut.write(NEW_LINE); // update signature buffer with input line - if (mSignatureForceV3) { - signatureV3Generator.update(NEW_LINE); - processLineV3(line, armorOut, signatureV3Generator); - } else { - signatureGenerator.update(NEW_LINE); - processLine(line, armorOut, signatureGenerator); - } + signatureGenerator.update(NEW_LINE); + processLine(line, armorOut, signatureGenerator); } armorOut.endClearText(); @@ -480,11 +448,7 @@ public class PgpSignEncrypt { bcpgOut = new BCPGOutputStream(out); } - if (mSignatureForceV3) { - signatureV3Generator.generateOnePassVersion(false).encode(bcpgOut); - } else { - signatureGenerator.generateOnePassVersion(false).encode(bcpgOut); - } + signatureGenerator.generateOnePassVersion(false).encode(bcpgOut); PGPLiteralDataGenerator literalGen = new PGPLiteralDataGenerator(); pOut = literalGen.open(bcpgOut, PGPLiteralData.BINARY, mOriginalFilename, new Date(), @@ -496,11 +460,7 @@ public class PgpSignEncrypt { while ((length = in.read(buffer)) > 0) { pOut.write(buffer, 0, length); - if (mSignatureForceV3) { - signatureV3Generator.update(buffer, 0, length); - } else { - signatureGenerator.update(buffer, 0, length); - } + signatureGenerator.update(buffer, 0, length); alreadyWritten += length; if (mData.getSize() > 0) { @@ -517,11 +477,7 @@ public class PgpSignEncrypt { if (enableSignature) { updateProgress(R.string.progress_generating_signature, 95, 100); - if (mSignatureForceV3) { - signatureV3Generator.generate().encode(pOut); - } else { - signatureGenerator.generate().encode(pOut); - } + signatureGenerator.generate().encode(pOut); } // closing outputs @@ -570,30 +526,4 @@ public class PgpSignEncrypt { pSignatureGenerator.update(data); } - private static void processLineV3(final String pLine, final ArmoredOutputStream pArmoredOutput, - final PGPV3SignatureGenerator pSignatureGenerator) - throws IOException, SignatureException { - - if (pLine == null) { - return; - } - - final char[] chars = pLine.toCharArray(); - int len = chars.length; - - while (len > 0) { - if (!Character.isWhitespace(chars[len - 1])) { - break; - } - len--; - } - - final byte[] data = pLine.substring(0, len).getBytes("UTF-8"); - - if (pArmoredOutput != null) { - pArmoredOutput.write(data); - } - pSignatureGenerator.update(data); - } - } 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 492ade7c3..3541dad98 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java @@ -191,7 +191,6 @@ public class OpenPgpService extends RemoteService { builder.setEnableAsciiArmorOutput(asciiArmor) .setVersionHeader(PgpHelper.getVersionForHeader(this)) .setSignatureHashAlgorithm(accSettings.getHashAlgorithm()) - .setSignatureForceV3(false) .setSignatureMasterKeyId(accSettings.getKeyId()) .setSignaturePassphrase(passphrase); @@ -299,7 +298,6 @@ public class OpenPgpService extends RemoteService { // sign and encrypt builder.setSignatureHashAlgorithm(accSettings.getHashAlgorithm()) - .setSignatureForceV3(false) .setSignatureMasterKeyId(accSettings.getKeyId()) .setSignaturePassphrase(passphrase); } else { diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java index d1d848066..d6c470e11 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java @@ -257,7 +257,6 @@ public class KeychainIntentService extends IntentService .setCompressionId(compressionId) .setSymmetricEncryptionAlgorithm( Preferences.getPreferences(this).getDefaultEncryptionAlgorithm()) - .setSignatureForceV3(Preferences.getPreferences(this).getForceV3Signatures()) .setEncryptionMasterKeyIds(encryptionKeyIds) .setSymmetricPassphrase(symmetricPassphrase) .setSignatureMasterKeyId(signatureKeyId) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/PreferencesActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/PreferencesActivity.java index 5bef6cc9f..de3236d35 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/PreferencesActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/PreferencesActivity.java @@ -119,9 +119,6 @@ public class PreferencesActivity extends PreferenceActivity { initializeAsciiArmor( (CheckBoxPreference) findPreference(Constants.Pref.DEFAULT_ASCII_ARMOR)); - initializeForceV3Signatures( - (CheckBoxPreference) findPreference(Constants.Pref.FORCE_V3_SIGNATURES)); - initializeWriteVersionHeader( (CheckBoxPreference) findPreference(Constants.Pref.WRITE_VERSION_HEADER)); @@ -266,9 +263,6 @@ public class PreferencesActivity extends PreferenceActivity { initializeAsciiArmor( (CheckBoxPreference) findPreference(Constants.Pref.DEFAULT_ASCII_ARMOR)); - initializeForceV3Signatures( - (CheckBoxPreference) findPreference(Constants.Pref.FORCE_V3_SIGNATURES)); - initializeWriteVersionHeader( (CheckBoxPreference) findPreference(Constants.Pref.WRITE_VERSION_HEADER)); } @@ -392,18 +386,6 @@ public class PreferencesActivity extends PreferenceActivity { }); } - private static void initializeForceV3Signatures(final CheckBoxPreference mForceV3Signatures) { - mForceV3Signatures.setChecked(sPreferences.getForceV3Signatures()); - mForceV3Signatures - .setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { - public boolean onPreferenceChange(Preference preference, Object newValue) { - mForceV3Signatures.setChecked((Boolean) newValue); - sPreferences.setForceV3Signatures((Boolean) newValue); - return false; - } - }); - } - private static void initializeWriteVersionHeader(final CheckBoxPreference mWriteVersionHeader) { mWriteVersionHeader.setChecked(sPreferences.getWriteVersionHeader()); mWriteVersionHeader.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { diff --git a/OpenKeychain/src/main/res/values/strings.xml b/OpenKeychain/src/main/res/values/strings.xml index 8ccb92854..09a434d5d 100644 --- a/OpenKeychain/src/main/res/values/strings.xml +++ b/OpenKeychain/src/main/res/values/strings.xml @@ -103,7 +103,6 @@ Passphrase Cache Message Compression File Compression - Force old OpenPGPv3 Signatures Keyservers Key ID Creation diff --git a/OpenKeychain/src/main/res/xml/adv_preferences.xml b/OpenKeychain/src/main/res/xml/adv_preferences.xml index 588a6e62d..49f241ffe 100644 --- a/OpenKeychain/src/main/res/xml/adv_preferences.xml +++ b/OpenKeychain/src/main/res/xml/adv_preferences.xml @@ -16,7 +16,7 @@ --> - + - - + + - - - -- cgit v1.2.3 From 225e2482935fbe93147303654f09536b605eac96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Thu, 14 Aug 2014 15:30:08 +0200 Subject: Remove MD5 support --- .../java/org/sufficientlysecure/keychain/helper/Preferences.java | 5 +++++ .../java/org/sufficientlysecure/keychain/ui/PreferencesActivity.java | 4 ++-- .../java/org/sufficientlysecure/keychain/util/AlgorithmNames.java | 1 - 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/helper/Preferences.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/helper/Preferences.java index 72e88d793..80b047530 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/helper/Preferences.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/helper/Preferences.java @@ -193,6 +193,11 @@ public class Preferences { 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.SHA512); + } } public void setWriteVersionHeader(boolean conceal) { diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/PreferencesActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/PreferencesActivity.java index de3236d35..64c1e16be 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/PreferencesActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/PreferencesActivity.java @@ -317,10 +317,10 @@ public class PreferencesActivity extends PreferenceActivity { private static void initializeHashAlgorithm (final IntegerListPreference mHashAlgorithm, int[] valueIds, String[] entries, String[] values) { - valueIds = new int[]{HashAlgorithmTags.MD5, HashAlgorithmTags.RIPEMD160, + valueIds = new int[]{HashAlgorithmTags.RIPEMD160, HashAlgorithmTags.SHA1, HashAlgorithmTags.SHA224, HashAlgorithmTags.SHA256, HashAlgorithmTags.SHA384, HashAlgorithmTags.SHA512,}; - entries = new String[]{"MD5", "RIPEMD-160", "SHA-1", "SHA-224", "SHA-256", "SHA-384", + entries = new String[]{"RIPEMD-160", "SHA-1", "SHA-224", "SHA-256", "SHA-384", "SHA-512",}; values = new String[valueIds.length]; for (int i = 0; i < values.length; ++i) { diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/AlgorithmNames.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/AlgorithmNames.java index 9acc7a73b..99db634ac 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/AlgorithmNames.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/AlgorithmNames.java @@ -50,7 +50,6 @@ public class AlgorithmNames { mEncryptionNames.put(PGPEncryptedData.TRIPLE_DES, "Triple DES"); mEncryptionNames.put(PGPEncryptedData.IDEA, "IDEA"); - mHashNames.put(HashAlgorithmTags.MD5, "MD5"); mHashNames.put(HashAlgorithmTags.RIPEMD160, "RIPEMD-160"); mHashNames.put(HashAlgorithmTags.SHA1, "SHA-1"); mHashNames.put(HashAlgorithmTags.SHA224, "SHA-224"); -- cgit v1.2.3 From 0a1de8deeaa543f3a0658c3927fd632d115e34fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Thu, 14 Aug 2014 15:42:02 +0200 Subject: Do not import v3 keys, they are insecure! --- .../org/sufficientlysecure/keychain/pgp/UncachedKeyRing.java | 4 ++++ .../sufficientlysecure/keychain/provider/ProviderHelper.java | 10 ++++++++++ .../keychain/service/OperationResultParcel.java | 1 + OpenKeychain/src/main/res/values/strings.xml | 3 ++- 4 files changed, 17 insertions(+), 1 deletion(-) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedKeyRing.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedKeyRing.java index 73a51942d..18f27cbff 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedKeyRing.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedKeyRing.java @@ -118,6 +118,10 @@ public class UncachedKeyRing { return mRing.getPublicKey().getFingerprint(); } + public int getVersion() { + return mRing.getPublicKey().getVersion(); + } + public static UncachedKeyRing decodeFromData(byte[] data) throws PgpGeneralException, IOException { 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 a13bb9c98..f8b2e549f 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java @@ -642,6 +642,11 @@ public class ProviderHelper { log(LogLevel.START, LogType.MSG_IP, PgpKeyHelper.convertKeyIdToHex(masterKeyId)); mIndent += 1; + if (publicRing.getVersion() <= 3) { + log(LogLevel.ERROR, LogType.MSG_IP_V3_KEY); + return new SaveKeyringResult(SaveKeyringResult.RESULT_ERROR, mLog); + } + if (publicRing.isSecret()) { log(LogLevel.ERROR, LogType.MSG_IP_BAD_TYPE_SECRET); return new SaveKeyringResult(SaveKeyringResult.RESULT_ERROR, mLog); @@ -734,6 +739,11 @@ public class ProviderHelper { log(LogLevel.START, LogType.MSG_IS, PgpKeyHelper.convertKeyIdToHex(masterKeyId)); mIndent += 1; + if (secretRing.getVersion() <= 3) { + log(LogLevel.ERROR, LogType.MSG_IP_V3_KEY); + return new SaveKeyringResult(SaveKeyringResult.RESULT_ERROR, mLog); + } + if ( ! secretRing.isSecret()) { log(LogLevel.ERROR, LogType.MSG_IS_BAD_TYPE_PUBLIC); return new SaveKeyringResult(SaveKeyringResult.RESULT_ERROR, mLog); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/OperationResultParcel.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/OperationResultParcel.java index d7d98fd68..93c3fc42b 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/OperationResultParcel.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/OperationResultParcel.java @@ -231,6 +231,7 @@ public class OperationResultParcel implements Parcelable { MSG_IP(R.string.msg_ip), MSG_IP_APPLY_BATCH (R.string.msg_ip_apply_batch), MSG_IP_BAD_TYPE_SECRET (R.string.msg_ip_bad_type_secret), + MSG_IP_V3_KEY (R.string.msg_ip_v3_key), MSG_IP_DELETE_OLD_FAIL (R.string.msg_ip_delete_old_fail), MSG_IP_DELETE_OLD_OK (R.string.msg_ip_delete_old_ok), MSG_IP_ENCODE_FAIL (R.string.msg_ip_encode_fail), diff --git a/OpenKeychain/src/main/res/values/strings.xml b/OpenKeychain/src/main/res/values/strings.xml index 09a434d5d..75175212c 100644 --- a/OpenKeychain/src/main/res/values/strings.xml +++ b/OpenKeychain/src/main/res/values/strings.xml @@ -433,7 +433,7 @@ Verified This identity has been verified. Not verified - This identity has not been verified yet. You can not be sure if the identity really corresponds to a specific person. + This identity has not been verified yet. You cannot be sure if the identity really corresponds to a specific person. Invalid Something is wrong with this identity! @@ -497,6 +497,7 @@ Applying insert batch operation. Tried to import secret keyring as public. This is a bug, please file a report! + This key is an OpenPGP version 3 key and thus insecure. It has not been imported. No old key deleted (creating a new one?) Deleted old key from database Operation failed due to encoding error -- cgit v1.2.3 From 62f7bf62150b460ee2dfa14f2c45f6df40d55cc9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Thu, 14 Aug 2014 15:58:26 +0200 Subject: move v3 key import prevention into canonicalization method --- .../org/sufficientlysecure/keychain/pgp/UncachedKeyRing.java | 7 +++++++ .../sufficientlysecure/keychain/provider/ProviderHelper.java | 10 ---------- .../keychain/service/OperationResultParcel.java | 2 +- OpenKeychain/src/main/res/values/strings.xml | 2 +- 4 files changed, 9 insertions(+), 12 deletions(-) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedKeyRing.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedKeyRing.java index 18f27cbff..5c8a85de9 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedKeyRing.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedKeyRing.java @@ -36,6 +36,7 @@ import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException; import org.sufficientlysecure.keychain.service.OperationResultParcel.LogLevel; import org.sufficientlysecure.keychain.service.OperationResultParcel.LogType; import org.sufficientlysecure.keychain.service.OperationResultParcel.OperationLog; +import org.sufficientlysecure.keychain.service.OperationResults; import org.sufficientlysecure.keychain.util.IterableIterator; import org.sufficientlysecure.keychain.util.Log; @@ -245,6 +246,12 @@ public class UncachedKeyRing { indent, PgpKeyHelper.convertKeyIdToHex(getMasterKeyId())); indent += 1; + // do not accept v3 keys + if (getVersion() <= 3) { + log.add(LogLevel.ERROR, LogType.MSG_KC_V3_KEY, indent); + return null; + } + final Date now = new Date(); int redundantCerts = 0, badCerts = 0; 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 f8b2e549f..a13bb9c98 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java @@ -642,11 +642,6 @@ public class ProviderHelper { log(LogLevel.START, LogType.MSG_IP, PgpKeyHelper.convertKeyIdToHex(masterKeyId)); mIndent += 1; - if (publicRing.getVersion() <= 3) { - log(LogLevel.ERROR, LogType.MSG_IP_V3_KEY); - return new SaveKeyringResult(SaveKeyringResult.RESULT_ERROR, mLog); - } - if (publicRing.isSecret()) { log(LogLevel.ERROR, LogType.MSG_IP_BAD_TYPE_SECRET); return new SaveKeyringResult(SaveKeyringResult.RESULT_ERROR, mLog); @@ -739,11 +734,6 @@ public class ProviderHelper { log(LogLevel.START, LogType.MSG_IS, PgpKeyHelper.convertKeyIdToHex(masterKeyId)); mIndent += 1; - if (secretRing.getVersion() <= 3) { - log(LogLevel.ERROR, LogType.MSG_IP_V3_KEY); - return new SaveKeyringResult(SaveKeyringResult.RESULT_ERROR, mLog); - } - if ( ! secretRing.isSecret()) { log(LogLevel.ERROR, LogType.MSG_IS_BAD_TYPE_PUBLIC); return new SaveKeyringResult(SaveKeyringResult.RESULT_ERROR, mLog); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/OperationResultParcel.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/OperationResultParcel.java index 93c3fc42b..25dac2139 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/OperationResultParcel.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/OperationResultParcel.java @@ -231,7 +231,6 @@ public class OperationResultParcel implements Parcelable { MSG_IP(R.string.msg_ip), MSG_IP_APPLY_BATCH (R.string.msg_ip_apply_batch), MSG_IP_BAD_TYPE_SECRET (R.string.msg_ip_bad_type_secret), - MSG_IP_V3_KEY (R.string.msg_ip_v3_key), MSG_IP_DELETE_OLD_FAIL (R.string.msg_ip_delete_old_fail), MSG_IP_DELETE_OLD_OK (R.string.msg_ip_delete_old_ok), MSG_IP_ENCODE_FAIL (R.string.msg_ip_encode_fail), @@ -290,6 +289,7 @@ public class OperationResultParcel implements Parcelable { MSG_IS_SUCCESS (R.string.msg_is_success), // keyring canonicalization + MSG_KC_V3_KEY (R.string.msg_kc_v3_key), MSG_KC_PUBLIC (R.string.msg_kc_public), MSG_KC_SECRET (R.string.msg_kc_secret), MSG_KC_FATAL_NO_UID (R.string.msg_kc_fatal_no_uid), diff --git a/OpenKeychain/src/main/res/values/strings.xml b/OpenKeychain/src/main/res/values/strings.xml index 75175212c..d491723fd 100644 --- a/OpenKeychain/src/main/res/values/strings.xml +++ b/OpenKeychain/src/main/res/values/strings.xml @@ -497,7 +497,7 @@ Applying insert batch operation. Tried to import secret keyring as public. This is a bug, please file a report! - This key is an OpenPGP version 3 key and thus insecure. It has not been imported. + This key is an OpenPGP version 3 key and thus insecure. It has not been imported. No old key deleted (creating a new one?) Deleted old key from database Operation failed due to encoding error -- cgit v1.2.3 From ef2449917e53e312ebc2eb4bea7e3149ba9db137 Mon Sep 17 00:00:00 2001 From: mar-v-in Date: Thu, 14 Aug 2014 12:22:02 +0200 Subject: factor KeySpinner out --- .../keychain/ui/EncryptAsymmetricFragment.java | 142 +---------------- .../ui/widget/EncryptKeyCompletionView.java | 4 +- .../keychain/ui/widget/KeySpinner.java | 171 +++++++++++++++++++++ .../keychain/ui/widget/SignKeySpinner.java | 48 ++++++ .../res/layout/encrypt_asymmetric_fragment.xml | 2 +- .../main/res/layout/encrypt_asymmetric_signkey.xml | 31 ---- .../src/main/res/layout/keyspinner_key.xml | 31 ++++ 7 files changed, 261 insertions(+), 168 deletions(-) create mode 100644 OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeySpinner.java create mode 100644 OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SignKeySpinner.java delete mode 100644 OpenKeychain/src/main/res/layout/encrypt_asymmetric_signkey.xml create mode 100644 OpenKeychain/src/main/res/layout/keyspinner_key.xml diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptAsymmetricFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptAsymmetricFragment.java index a402b6f68..41566cffc 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptAsymmetricFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptAsymmetricFragment.java @@ -47,6 +47,7 @@ import org.sufficientlysecure.keychain.provider.CachedPublicKeyRing; import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings; import org.sufficientlysecure.keychain.provider.ProviderHelper; import org.sufficientlysecure.keychain.ui.widget.EncryptKeyCompletionView; +import org.sufficientlysecure.keychain.ui.widget.KeySpinner; import org.sufficientlysecure.keychain.util.Log; import java.util.ArrayList; @@ -54,22 +55,20 @@ import java.util.Iterator; import java.util.List; public class EncryptAsymmetricFragment extends Fragment implements EncryptActivityInterface.UpdateListener { - public static final String ARG_SIGNATURE_KEY_ID = "signature_key_id"; - public static final String ARG_ENCRYPTION_KEY_IDS = "encryption_key_ids"; - ProviderHelper mProviderHelper; // view - private Spinner mSign; + private KeySpinner mSign; private EncryptKeyCompletionView mEncryptKeyView; - private SelectSignKeyCursorAdapter mSignAdapter = new SelectSignKeyCursorAdapter(); // model private EncryptActivityInterface mEncryptInterface; @Override public void onNotifyUpdate() { - + if (mSign != null) { + mSign.setSelectedKeyId(mEncryptInterface.getSignatureKey()); + } } @Override @@ -101,8 +100,7 @@ public class EncryptAsymmetricFragment extends Fragment implements EncryptActivi public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.encrypt_asymmetric_fragment, container, false); - mSign = (Spinner) view.findViewById(R.id.sign); - mSign.setAdapter(mSignAdapter); + mSign = (KeySpinner) view.findViewById(R.id.sign); mSign.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { @Override public void onItemSelected(AdapterView parent, View view, int position, long id) { @@ -128,42 +126,6 @@ public class EncryptAsymmetricFragment extends Fragment implements EncryptActivi // preselect keys given preselectKeys(); - getLoaderManager().initLoader(1, null, new LoaderManager.LoaderCallbacks() { - @Override - public Loader onCreateLoader(int id, Bundle args) { - // This is called when a new Loader needs to be created. This - // sample only has one Loader, so we don't care about the ID. - Uri baseUri = KeyRings.buildUnifiedKeyRingsUri(); - - // These are the rows that we will retrieve. - String[] projection = new String[]{ - KeyRings._ID, - KeyRings.MASTER_KEY_ID, - KeyRings.KEY_ID, - KeyRings.USER_ID, - KeyRings.IS_EXPIRED, - KeyRings.HAS_SIGN, - KeyRings.HAS_ANY_SECRET - }; - - String where = KeyRings.HAS_ANY_SECRET + " = 1 AND " + KeyRings.HAS_SIGN + " NOT NULL AND " - + KeyRings.IS_REVOKED + " = 0 AND " + KeyRings.IS_EXPIRED + " = 0"; - - // Now create and return a CursorLoader that will take care of - // creating a Cursor for the data being displayed. - return new CursorLoader(getActivity(), baseUri, projection, where, null, null); - } - - @Override - public void onLoadFinished(Loader loader, Cursor data) { - mSignAdapter.swapCursor(data); - } - - @Override - public void onLoaderReset(Loader loader) { - mSignAdapter.swapCursor(null); - } - }); mEncryptKeyView.setTokenListener(new TokenCompleteTextView.TokenListener() { @Override public void onTokenAdded(Object token) { @@ -194,6 +156,7 @@ public class EncryptAsymmetricFragment extends Fragment implements EncryptActivi KeyRings.buildUnifiedKeyRingUri(signatureKey)); if(keyring.hasAnySecret()) { setSignatureKeyId(keyring.getMasterKeyId()); + mSign.setSelectedKeyId(mEncryptInterface.getSignatureKey()); } } catch (PgpGeneralException e) { Log.e(Constants.TAG, "key not found!", e); @@ -233,95 +196,4 @@ public class EncryptAsymmetricFragment extends Fragment implements EncryptActivi setEncryptionKeyIds(keyIdsArr); setEncryptionUserIds(userIds.toArray(new String[userIds.size()])); } - - private class SelectSignKeyCursorAdapter extends BaseAdapter implements SpinnerAdapter { - private CursorAdapter inner; - private int mIndexUserId; - private int mIndexKeyId; - private int mIndexMasterKeyId; - - public SelectSignKeyCursorAdapter() { - inner = new CursorAdapter(null, null, 0) { - @Override - public View newView(Context context, Cursor cursor, ViewGroup parent) { - return getActivity().getLayoutInflater().inflate(R.layout.encrypt_asymmetric_signkey, null); - } - - @Override - public void bindView(View view, Context context, Cursor cursor) { - String[] userId = KeyRing.splitUserId(cursor.getString(mIndexUserId)); - ((TextView) view.findViewById(android.R.id.title)).setText(userId[2] == null ? userId[0] : (userId[0] + " (" + userId[2] + ")")); - ((TextView) view.findViewById(android.R.id.text1)).setText(userId[1]); - ((TextView) view.findViewById(android.R.id.text2)).setText(PgpKeyHelper.convertKeyIdToHex(cursor.getLong(mIndexKeyId))); - } - - @Override - public long getItemId(int position) { - mCursor.moveToPosition(position); - return mCursor.getLong(mIndexMasterKeyId); - } - }; - } - - public Cursor swapCursor(Cursor newCursor) { - if (newCursor == null) return inner.swapCursor(null); - - mIndexKeyId = newCursor.getColumnIndex(KeyRings.KEY_ID); - mIndexUserId = newCursor.getColumnIndex(KeyRings.USER_ID); - mIndexMasterKeyId = newCursor.getColumnIndex(KeyRings.MASTER_KEY_ID); - if (newCursor.moveToFirst()) { - do { - if (newCursor.getLong(mIndexMasterKeyId) == mEncryptInterface.getSignatureKey()) { - mSign.setSelection(newCursor.getPosition() + 1); - } - } while (newCursor.moveToNext()); - } - return inner.swapCursor(newCursor); - } - - @Override - public int getCount() { - return inner.getCount() + 1; - } - - @Override - public Object getItem(int position) { - if (position == 0) return null; - return inner.getItem(position - 1); - } - - @Override - public long getItemId(int position) { - if (position == 0) return Constants.key.none; - return inner.getItemId(position - 1); - } - - @Override - public View getView(int position, View convertView, ViewGroup parent) { - View v = getDropDownView(position, convertView, parent); - v.findViewById(android.R.id.text1).setVisibility(View.GONE); - return v; - } - - @Override - public View getDropDownView(int position, View convertView, ViewGroup parent) { - View v; - if (position == 0) { - if (convertView == null) { - v = inner.newView(null, null, parent); - } else { - v = convertView; - } - ((TextView) v.findViewById(android.R.id.title)).setText("None"); - v.findViewById(android.R.id.text1).setVisibility(View.GONE); - v.findViewById(android.R.id.text2).setVisibility(View.GONE); - } else { - v = inner.getView(position - 1, convertView, parent); - v.findViewById(android.R.id.text1).setVisibility(View.VISIBLE); - v.findViewById(android.R.id.text2).setVisibility(View.VISIBLE); - } - return v; - } - } - } 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 20b9570bb..ceb3f665f 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 @@ -111,7 +111,7 @@ public class EncryptKeyCompletionView extends TokenCompleteTextView { protected void onAttachedToWindow() { super.onAttachedToWindow(); if (getContext() instanceof FragmentActivity) { - ((FragmentActivity) getContext()).getSupportLoaderManager().initLoader(0, null, new LoaderManager.LoaderCallbacks() { + ((FragmentActivity) getContext()).getSupportLoaderManager().initLoader(hashCode(), null, new LoaderManager.LoaderCallbacks() { @Override public Loader onCreateLoader(int id, Bundle args) { // These are the rows that we will retrieve. @@ -143,6 +143,8 @@ public class EncryptKeyCompletionView extends TokenCompleteTextView { swapCursor(null); } }); + } else { + Log.e(Constants.TAG, "EncryptKeyCompletionView must be attached to a FragmentActivity, this is " + getContext().getClass()); } } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeySpinner.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeySpinner.java new file mode 100644 index 000000000..b8d83311a --- /dev/null +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeySpinner.java @@ -0,0 +1,171 @@ +package org.sufficientlysecure.keychain.ui.widget; + +import android.content.Context; +import android.database.Cursor; +import android.os.Bundle; +import android.support.v4.app.FragmentActivity; +import android.support.v4.app.LoaderManager; +import android.support.v4.content.Loader; +import android.support.v4.widget.CursorAdapter; +import android.util.AttributeSet; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.Spinner; +import android.widget.SpinnerAdapter; +import android.widget.TextView; + +import org.sufficientlysecure.keychain.Constants; +import org.sufficientlysecure.keychain.R; +import org.sufficientlysecure.keychain.pgp.KeyRing; +import org.sufficientlysecure.keychain.pgp.PgpKeyHelper; +import org.sufficientlysecure.keychain.provider.KeychainContract; +import org.sufficientlysecure.keychain.util.Log; + +public abstract class KeySpinner extends Spinner { + private long mSelectedKeyId; + private SelectKeyAdapter mAdapter = new SelectKeyAdapter(); + + public KeySpinner(Context context) { + super(context); + } + + public KeySpinner(Context context, AttributeSet attrs) { + super(context, attrs); + } + + public KeySpinner(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + } + + public abstract Loader onCreateLoader(); + + @Override + protected void onAttachedToWindow() { + super.onAttachedToWindow(); + setAdapter(mAdapter); + if (getContext() instanceof FragmentActivity) { + ((FragmentActivity) getContext()).getSupportLoaderManager().initLoader(hashCode(), null, new LoaderManager.LoaderCallbacks() { + @Override + public Loader onCreateLoader(int id, Bundle args) { + return KeySpinner.this.onCreateLoader(); + } + + @Override + public void onLoadFinished(Loader loader, Cursor data) { + mAdapter.swapCursor(data); + } + + @Override + public void onLoaderReset(Loader loader) { + mAdapter.swapCursor(null); + } + }); + } else { + Log.e(Constants.TAG, "KeySpinner must be attached to FragmentActivity, this is " + getContext().getClass()); + } + } + + public long getSelectedKeyId() { + return mSelectedKeyId; + } + + public void setSelectedKeyId(long selectedKeyId) { + this.mSelectedKeyId = selectedKeyId; + } + + private class SelectKeyAdapter extends BaseAdapter implements SpinnerAdapter { + private CursorAdapter inner; + private int mIndexUserId; + private int mIndexKeyId; + private int mIndexMasterKeyId; + + public SelectKeyAdapter() { + inner = new CursorAdapter(null, null, 0) { + @Override + public View newView(Context context, Cursor cursor, ViewGroup parent) { + return View.inflate(getContext(), R.layout.keyspinner_key, null); + } + + @Override + public void bindView(View view, Context context, Cursor cursor) { + String[] userId = KeyRing.splitUserId(cursor.getString(mIndexUserId)); + ((TextView) view.findViewById(android.R.id.title)).setText(userId[2] == null ? userId[0] : (userId[0] + " (" + userId[2] + ")")); + ((TextView) view.findViewById(android.R.id.text1)).setText(userId[1]); + ((TextView) view.findViewById(android.R.id.text2)).setText(PgpKeyHelper.convertKeyIdToHex(cursor.getLong(mIndexKeyId))); + } + + @Override + public long getItemId(int position) { + mCursor.moveToPosition(position); + return mCursor.getLong(mIndexMasterKeyId); + } + }; + } + + public Cursor swapCursor(Cursor newCursor) { + if (newCursor == null) return inner.swapCursor(null); + + mIndexKeyId = newCursor.getColumnIndex(KeychainContract.KeyRings.KEY_ID); + mIndexUserId = newCursor.getColumnIndex(KeychainContract.KeyRings.USER_ID); + mIndexMasterKeyId = newCursor.getColumnIndex(KeychainContract.KeyRings.MASTER_KEY_ID); + if (newCursor.moveToFirst()) { + do { + if (newCursor.getLong(mIndexMasterKeyId) == mSelectedKeyId) { + setSelection(newCursor.getPosition() + 1); + } + } while (newCursor.moveToNext()); + } + return inner.swapCursor(newCursor); + } + + @Override + public int getCount() { + return inner.getCount() + 1; + } + + @Override + public Object getItem(int position) { + if (position == 0) return null; + return inner.getItem(position - 1); + } + + @Override + public long getItemId(int position) { + if (position == 0) return Constants.key.none; + return inner.getItemId(position - 1); + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + try { + View v = getDropDownView(position, convertView, parent); + v.findViewById(android.R.id.text1).setVisibility(View.GONE); + return v; + } catch (NullPointerException e) { + // This is for the preview... + return View.inflate(getContext(), android.R.layout.simple_list_item_1, null); + } + } + + @Override + public View getDropDownView(int position, View convertView, ViewGroup parent) { + View v; + if (position == 0) { + if (convertView == null) { + v = inner.newView(null, null, parent); + } else { + v = convertView; + } + ((TextView) v.findViewById(android.R.id.title)).setText("None"); + v.findViewById(android.R.id.text1).setVisibility(View.GONE); + v.findViewById(android.R.id.text2).setVisibility(View.GONE); + } else { + v = inner.getView(position - 1, convertView, parent); + v.findViewById(android.R.id.text1).setVisibility(View.VISIBLE); + v.findViewById(android.R.id.text2).setVisibility(View.VISIBLE); + } + return v; + } + } +} 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 new file mode 100644 index 000000000..cbec7f920 --- /dev/null +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SignKeySpinner.java @@ -0,0 +1,48 @@ +package org.sufficientlysecure.keychain.ui.widget; + +import android.content.Context; +import android.database.Cursor; +import android.net.Uri; +import android.support.v4.content.CursorLoader; +import android.support.v4.content.Loader; +import android.util.AttributeSet; +import org.sufficientlysecure.keychain.provider.KeychainContract; + +public class SignKeySpinner extends KeySpinner { + public SignKeySpinner(Context context) { + super(context); + } + + public SignKeySpinner(Context context, AttributeSet attrs) { + super(context, attrs); + } + + public SignKeySpinner(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + } + + @Override + public Loader onCreateLoader() { + // This is called when a new Loader needs to be created. This + // sample only has one Loader, so we don't care about the ID. + Uri baseUri = KeychainContract.KeyRings.buildUnifiedKeyRingsUri(); + + // These are the rows that we will retrieve. + String[] projection = new String[]{ + KeychainContract.KeyRings._ID, + KeychainContract.KeyRings.MASTER_KEY_ID, + KeychainContract.KeyRings.KEY_ID, + KeychainContract.KeyRings.USER_ID, + KeychainContract.KeyRings.IS_EXPIRED, + KeychainContract.KeyRings.HAS_SIGN, + KeychainContract.KeyRings.HAS_ANY_SECRET + }; + + String where = KeychainContract.KeyRings.HAS_ANY_SECRET + " = 1 AND " + KeychainContract.KeyRings.HAS_SIGN + " NOT NULL AND " + + KeychainContract.KeyRings.IS_REVOKED + " = 0 AND " + KeychainContract.KeyRings.IS_EXPIRED + " = 0"; + + // Now create and return a CursorLoader that will take care of + // creating a Cursor for the data being displayed. + return new CursorLoader(getContext(), baseUri, projection, where, null, null); + } +} diff --git a/OpenKeychain/src/main/res/layout/encrypt_asymmetric_fragment.xml b/OpenKeychain/src/main/res/layout/encrypt_asymmetric_fragment.xml index 4d82477bc..2189a1f34 100644 --- a/OpenKeychain/src/main/res/layout/encrypt_asymmetric_fragment.xml +++ b/OpenKeychain/src/main/res/layout/encrypt_asymmetric_fragment.xml @@ -24,7 +24,7 @@ android:textAppearance="?android:attr/textAppearanceMedium" android:text="@string/label_asymmetric_from" /> - - - - - - - \ No newline at end of file diff --git a/OpenKeychain/src/main/res/layout/keyspinner_key.xml b/OpenKeychain/src/main/res/layout/keyspinner_key.xml new file mode 100644 index 000000000..703f9133b --- /dev/null +++ b/OpenKeychain/src/main/res/layout/keyspinner_key.xml @@ -0,0 +1,31 @@ + + + + + + + \ No newline at end of file -- cgit v1.2.3 From 9fab740aadb76883105b61451c047fc1d4b27f1f Mon Sep 17 00:00:00 2001 From: mar-v-in Date: Thu, 14 Aug 2014 12:22:44 +0200 Subject: add HAS_CERTIFY (not sure why it's missing) --- .../keychain/provider/KeychainContract.java | 1 + .../keychain/provider/KeychainProvider.java | 11 +++++++++++ 2 files changed, 12 insertions(+) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainContract.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainContract.java index dd59f8603..c239ea7f7 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainContract.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainContract.java @@ -111,6 +111,7 @@ public class KeychainContract { public static final String HAS_ANY_SECRET = "has_any_secret"; public static final String HAS_ENCRYPT = "has_encrypt"; public static final String HAS_SIGN = "has_sign"; + public static final String HAS_CERTIFY = "has_certify"; public static final String PUBKEY_DATA = "pubkey_data"; public static final String PRIVKEY_DATA = "privkey_data"; 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 c914cb5b7..ed12fb94a 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java @@ -271,6 +271,8 @@ public class KeychainProvider extends ContentProvider { "kE." + Keys.KEY_ID + " AS " + KeyRings.HAS_ENCRYPT); projectionMap.put(KeyRings.HAS_SIGN, "kS." + Keys.KEY_ID + " AS " + KeyRings.HAS_SIGN); + projectionMap.put(KeyRings.HAS_CERTIFY, + "kC." + Keys.KEY_ID + " AS " + KeyRings.HAS_SIGN); projectionMap.put(KeyRings.IS_EXPIRED, "(" + Tables.KEYS + "." + Keys.EXPIRY + " IS NOT NULL AND " + Tables.KEYS + "." + Keys.EXPIRY + " < " + new Date().getTime() / 1000 + ") AS " + KeyRings.IS_EXPIRED); @@ -324,6 +326,15 @@ public class KeychainProvider extends ContentProvider { + " AND ( kS." + Keys.EXPIRY + " IS NULL OR kS." + Keys.EXPIRY + " >= " + new Date().getTime() / 1000 + " )" + ")" : "") + + (plist.contains(KeyRings.HAS_CERTIFY) ? + " LEFT JOIN " + Tables.KEYS + " AS kC ON (" + +"kC." + Keys.MASTER_KEY_ID + + " = " + Tables.KEYS + "." + Keys.MASTER_KEY_ID + + " AND kC." + Keys.IS_REVOKED + " = 0" + + " AND kC." + Keys.CAN_CERTIFY + " = 1" + + " AND ( kC." + Keys.EXPIRY + " IS NULL OR kC." + Keys.EXPIRY + + " >= " + new Date().getTime() / 1000 + " )" + + ")" : "") ); qb.appendWhere(Tables.KEYS + "." + Keys.RANK + " = 0"); // in case there are multiple verifying certificates -- cgit v1.2.3 From 07d6a26778b69c5340f5bbf11dcab970c63783d4 Mon Sep 17 00:00:00 2001 From: mar-v-in Date: Thu, 14 Aug 2014 15:23:12 +0200 Subject: add OnKeyChangedListener to KeySpinner --- .../keychain/ui/EncryptAsymmetricFragment.java | 11 ++---- .../keychain/ui/widget/KeySpinner.java | 41 ++++++++++++++++++++-- 2 files changed, 41 insertions(+), 11 deletions(-) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptAsymmetricFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptAsymmetricFragment.java index 41566cffc..748cbca14 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptAsymmetricFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptAsymmetricFragment.java @@ -101,15 +101,10 @@ public class EncryptAsymmetricFragment extends Fragment implements EncryptActivi View view = inflater.inflate(R.layout.encrypt_asymmetric_fragment, container, false); mSign = (KeySpinner) view.findViewById(R.id.sign); - mSign.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { + mSign.setOnKeyChangedListener(new KeySpinner.OnKeyChangedListener() { @Override - public void onItemSelected(AdapterView parent, View view, int position, long id) { - setSignatureKeyId(parent.getAdapter().getItemId(position)); - } - - @Override - public void onNothingSelected(AdapterView parent) { - setSignatureKeyId(Constants.key.none); + public void onKeyChanged(long masterKeyId) { + setSignatureKeyId(masterKeyId); } }); mEncryptKeyView = (EncryptKeyCompletionView) view.findViewById(R.id.recipient_list); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeySpinner.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeySpinner.java index b8d83311a..fe3c61197 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeySpinner.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeySpinner.java @@ -10,6 +10,7 @@ import android.support.v4.widget.CursorAdapter; import android.util.AttributeSet; import android.view.View; import android.view.ViewGroup; +import android.widget.AdapterView; import android.widget.BaseAdapter; import android.widget.Spinner; import android.widget.SpinnerAdapter; @@ -23,27 +24,62 @@ import org.sufficientlysecure.keychain.provider.KeychainContract; import org.sufficientlysecure.keychain.util.Log; public abstract class KeySpinner extends Spinner { + public interface OnKeyChangedListener { + public void onKeyChanged(long masterKeyId); + } + private long mSelectedKeyId; private SelectKeyAdapter mAdapter = new SelectKeyAdapter(); + private OnKeyChangedListener mListener; public KeySpinner(Context context) { super(context); + initView(); } public KeySpinner(Context context, AttributeSet attrs) { super(context, attrs); + initView(); } public KeySpinner(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); + initView(); + } + + private void initView() { + setAdapter(mAdapter); + super.setOnItemSelectedListener(new OnItemSelectedListener() { + @Override + public void onItemSelected(AdapterView parent, View view, int position, long id) { + if (mListener != null) { + mListener.onKeyChanged(id); + } + } + + @Override + public void onNothingSelected(AdapterView parent) { + if (mListener != null) { + mListener.onKeyChanged(Constants.key.none); + } + } + }); } public abstract Loader onCreateLoader(); + @Override + public void setOnItemSelectedListener(OnItemSelectedListener listener) { + throw new UnsupportedOperationException(); + } + + public void setOnKeyChangedListener(OnKeyChangedListener listener) { + mListener = listener; + } + @Override protected void onAttachedToWindow() { super.onAttachedToWindow(); - setAdapter(mAdapter); if (getContext() instanceof FragmentActivity) { ((FragmentActivity) getContext()).getSupportLoaderManager().initLoader(hashCode(), null, new LoaderManager.LoaderCallbacks() { @Override @@ -97,8 +133,7 @@ public abstract class KeySpinner extends Spinner { @Override public long getItemId(int position) { - mCursor.moveToPosition(position); - return mCursor.getLong(mIndexMasterKeyId); + return ((Cursor) getItem(position)).getLong(mIndexMasterKeyId); } }; } -- cgit v1.2.3 From 00286744f232bec569b46411db7be62e40c534d0 Mon Sep 17 00:00:00 2001 From: mar-v-in Date: Thu, 14 Aug 2014 15:44:54 +0200 Subject: small bug in has_certify --- .../java/org/sufficientlysecure/keychain/provider/KeychainProvider.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 ed12fb94a..2c552a060 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java @@ -272,7 +272,7 @@ public class KeychainProvider extends ContentProvider { projectionMap.put(KeyRings.HAS_SIGN, "kS." + Keys.KEY_ID + " AS " + KeyRings.HAS_SIGN); projectionMap.put(KeyRings.HAS_CERTIFY, - "kC." + Keys.KEY_ID + " AS " + KeyRings.HAS_SIGN); + "kC." + Keys.KEY_ID + " AS " + KeyRings.HAS_CERTIFY); projectionMap.put(KeyRings.IS_EXPIRED, "(" + Tables.KEYS + "." + Keys.EXPIRY + " IS NOT NULL AND " + Tables.KEYS + "." + Keys.EXPIRY + " < " + new Date().getTime() / 1000 + ") AS " + KeyRings.IS_EXPIRED); -- cgit v1.2.3 From a6118877ff1b096925c908583985889d30087e24 Mon Sep 17 00:00:00 2001 From: mar-v-in Date: Thu, 14 Aug 2014 16:00:07 +0200 Subject: Add and use CertifyKeySpinner --- .../keychain/ui/CertifyKeyActivity.java | 32 +++++++-------- .../keychain/ui/widget/CertifyKeySpinner.java | 48 ++++++++++++++++++++++ .../src/main/res/layout/certify_key_activity.xml | 12 ++---- 3 files changed, 66 insertions(+), 26 deletions(-) create mode 100644 OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/CertifyKeySpinner.java diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java index c1986825c..d1e8a80dc 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java @@ -34,6 +34,7 @@ import android.support.v7.app.ActionBarActivity; import android.view.MenuItem; import android.view.View; import android.view.View.OnClickListener; +import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.CheckBox; import android.widget.CompoundButton; @@ -56,6 +57,8 @@ import org.sufficientlysecure.keychain.service.OperationResultParcel; import org.sufficientlysecure.keychain.service.PassphraseCacheService; import org.sufficientlysecure.keychain.ui.adapter.UserIdsAdapter; import org.sufficientlysecure.keychain.ui.dialog.PassphraseDialogFragment; +import org.sufficientlysecure.keychain.ui.widget.CertifyKeySpinner; +import org.sufficientlysecure.keychain.ui.widget.KeySpinner; import org.sufficientlysecure.keychain.util.Log; import org.sufficientlysecure.keychain.util.Notify; @@ -64,18 +67,17 @@ import java.util.ArrayList; /** * Signs the specified public key with the specified secret master key */ -public class CertifyKeyActivity extends ActionBarActivity implements - SelectSecretKeyLayoutFragment.SelectSecretKeyCallback, LoaderManager.LoaderCallbacks { +public class CertifyKeyActivity extends ActionBarActivity implements LoaderManager.LoaderCallbacks { private View mCertifyButton; private ImageView mActionCertifyImage; private CheckBox mUploadKeyCheckbox; private Spinner mSelectKeyserverSpinner; - private SelectSecretKeyLayoutFragment mSelectKeyFragment; + private CertifyKeySpinner mCertifyKeySpinner; private Uri mDataUri; - private long mPubKeyId = 0; - private long mMasterKeyId = 0; + private long mPubKeyId = Constants.key.none; + private long mMasterKeyId = Constants.key.none; private ListView mUserIds; private UserIdsAdapter mUserIdsAdapter; @@ -89,8 +91,7 @@ public class CertifyKeyActivity extends ActionBarActivity implements setContentView(R.layout.certify_key_activity); - mSelectKeyFragment = (SelectSecretKeyLayoutFragment) getSupportFragmentManager() - .findFragmentById(R.id.sign_key_select_key_fragment); + mCertifyKeySpinner = (CertifyKeySpinner) findViewById(R.id.certify_key_spinner); mSelectKeyserverSpinner = (Spinner) findViewById(R.id.upload_key_keyserver); mUploadKeyCheckbox = (CheckBox) findViewById(R.id.sign_key_upload_checkbox); mCertifyButton = findViewById(R.id.certify_key_certify_button); @@ -101,8 +102,12 @@ public class CertifyKeyActivity extends ActionBarActivity implements mActionCertifyImage.setColorFilter(getResources().getColor(R.color.tertiary_text_light), PorterDuff.Mode.SRC_IN); - mSelectKeyFragment.setCallback(this); - mSelectKeyFragment.setFilterCertify(true); + mCertifyKeySpinner.setOnKeyChangedListener(new KeySpinner.OnKeyChangedListener() { + @Override + public void onKeyChanged(long masterKeyId) { + mMasterKeyId = masterKeyId; + } + }); ArrayAdapter adapter = new ArrayAdapter(this, android.R.layout.simple_spinner_item, Preferences.getPreferences(this) @@ -135,7 +140,6 @@ public class CertifyKeyActivity extends ActionBarActivity implements public void onClick(View v) { if (mPubKeyId != 0) { if (mMasterKeyId == 0) { - mSelectKeyFragment.setError(getString(R.string.select_key_to_certify)); Notify.showNotify(CertifyKeyActivity.this, getString(R.string.select_key_to_certify), Notify.Style.ERROR); } else { @@ -367,14 +371,6 @@ public class CertifyKeyActivity extends ActionBarActivity implements startService(intent); } - /** - * callback from select key fragment - */ - @Override - public void onKeySelected(long secretKeyId) { - mMasterKeyId = secretKeyId; - } - @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { 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 new file mode 100644 index 000000000..b686d108b --- /dev/null +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/CertifyKeySpinner.java @@ -0,0 +1,48 @@ +package org.sufficientlysecure.keychain.ui.widget; + +import android.content.Context; +import android.database.Cursor; +import android.net.Uri; +import android.support.v4.content.CursorLoader; +import android.support.v4.content.Loader; +import android.util.AttributeSet; +import org.sufficientlysecure.keychain.provider.KeychainContract; + +public class CertifyKeySpinner extends KeySpinner { + public CertifyKeySpinner(Context context) { + super(context); + } + + public CertifyKeySpinner(Context context, AttributeSet attrs) { + super(context, attrs); + } + + public CertifyKeySpinner(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + } + + @Override + public Loader onCreateLoader() { + // This is called when a new Loader needs to be created. This + // sample only has one Loader, so we don't care about the ID. + Uri baseUri = KeychainContract.KeyRings.buildUnifiedKeyRingsUri(); + + // These are the rows that we will retrieve. + String[] projection = new String[]{ + KeychainContract.KeyRings._ID, + KeychainContract.KeyRings.MASTER_KEY_ID, + KeychainContract.KeyRings.KEY_ID, + KeychainContract.KeyRings.USER_ID, + KeychainContract.KeyRings.IS_EXPIRED, + KeychainContract.KeyRings.HAS_CERTIFY, + KeychainContract.KeyRings.HAS_ANY_SECRET + }; + + String where = KeychainContract.KeyRings.HAS_ANY_SECRET + " = 1 AND " + KeychainContract.KeyRings.HAS_CERTIFY + " NOT NULL AND " + + KeychainContract.KeyRings.IS_REVOKED + " = 0 AND " + KeychainContract.KeyRings.IS_EXPIRED + " = 0"; + + // Now create and return a CursorLoader that will take care of + // creating a Cursor for the data being displayed. + return new CursorLoader(getContext(), baseUri, projection, where, null, null); + } +} diff --git a/OpenKeychain/src/main/res/layout/certify_key_activity.xml b/OpenKeychain/src/main/res/layout/certify_key_activity.xml index 34d4dbd57..bce194438 100644 --- a/OpenKeychain/src/main/res/layout/certify_key_activity.xml +++ b/OpenKeychain/src/main/res/layout/certify_key_activity.xml @@ -26,14 +26,10 @@ android:layout_marginTop="14dp" android:text="@string/section_certification_key" /> - + Date: Thu, 14 Aug 2014 16:12:42 +0200 Subject: Automcomplete names and emails in keyserver tab --- .../keychain/helper/ContactHelper.java | 18 ++++++++++++++++++ .../keychain/ui/ImportKeysServerFragment.java | 18 ++++++++++++++++-- .../main/res/layout/import_keys_server_fragment.xml | 2 +- 3 files changed, 35 insertions(+), 3 deletions(-) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/helper/ContactHelper.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/helper/ContactHelper.java index 8697e49f7..96e1b25af 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/helper/ContactHelper.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/helper/ContactHelper.java @@ -234,6 +234,24 @@ public class ContactHelper { return new ArrayList(mails); } + public static List getContactNames(Context context) { + ContentResolver resolver = context.getContentResolver(); + Cursor cursor = resolver.query(ContactsContract.Contacts.CONTENT_URI, + new String[]{ContactsContract.Contacts.DISPLAY_NAME}, + null, null, null); + if (cursor == null) return null; + + Set names = new HashSet(); + while (cursor.moveToNext()) { + String name = cursor.getString(0); + if (name != null) { + names.add(name); + } + } + cursor.close(); + return new ArrayList(names); + } + public static Uri dataUriFromContactUri(Context context, Uri contactUri) { Cursor contactMasterKey = context.getContentResolver().query(contactUri, new String[]{ContactsContract.Data.DATA2}, null, null, null, null); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysServerFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysServerFragment.java index d339bc132..88caebc32 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysServerFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysServerFragment.java @@ -29,15 +29,19 @@ import android.view.ViewGroup; import android.view.inputmethod.EditorInfo; import android.view.inputmethod.InputMethodManager; import android.widget.ArrayAdapter; +import android.widget.AutoCompleteTextView; import android.widget.EditText; import android.widget.Spinner; import android.widget.TextView; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; +import org.sufficientlysecure.keychain.helper.ContactHelper; import org.sufficientlysecure.keychain.helper.Preferences; import org.sufficientlysecure.keychain.util.Log; +import java.util.List; + public class ImportKeysServerFragment extends Fragment { public static final String ARG_QUERY = "query"; public static final String ARG_KEYSERVER = "keyserver"; @@ -46,7 +50,7 @@ public class ImportKeysServerFragment extends Fragment { private ImportKeysActivity mImportActivity; private View mSearchButton; - private EditText mQueryEditText; + private AutoCompleteTextView mQueryEditText; private View mConfigButton; private View mConfigLayout; private Spinner mServerSpinner; @@ -75,7 +79,7 @@ public class ImportKeysServerFragment extends Fragment { View view = inflater.inflate(R.layout.import_keys_server_fragment, container, false); mSearchButton = view.findViewById(R.id.import_server_search); - mQueryEditText = (EditText) view.findViewById(R.id.import_server_query); + mQueryEditText = (AutoCompleteTextView) view.findViewById(R.id.import_server_query); mConfigButton = view.findViewById(R.id.import_server_config_button); mConfigLayout = view.findViewById(R.id.import_server_config); mServerSpinner = (Spinner) view.findViewById(R.id.import_server_spinner); @@ -93,6 +97,16 @@ public class ImportKeysServerFragment extends Fragment { mSearchButton.setEnabled(false); } + List namesAndEmails = ContactHelper.getContactNames(getActivity()); + namesAndEmails.addAll(ContactHelper.getContactMails(getActivity())); + mQueryEditText.setThreshold(3); + mQueryEditText.setAdapter( + new ArrayAdapter + (getActivity(), android.R.layout.simple_spinner_dropdown_item, + namesAndEmails + ) + ); + mSearchButton.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { diff --git a/OpenKeychain/src/main/res/layout/import_keys_server_fragment.xml b/OpenKeychain/src/main/res/layout/import_keys_server_fragment.xml index 47c354c53..fde90b81f 100644 --- a/OpenKeychain/src/main/res/layout/import_keys_server_fragment.xml +++ b/OpenKeychain/src/main/res/layout/import_keys_server_fragment.xml @@ -10,7 +10,7 @@ android:layout_height="?android:attr/listPreferredItemHeight" android:orientation="horizontal"> - Date: Thu, 14 Aug 2014 16:14:16 +0200 Subject: Fix KeySpinner on cursor change --- .../java/org/sufficientlysecure/keychain/ui/widget/KeySpinner.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeySpinner.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeySpinner.java index fe3c61197..380361fc0 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeySpinner.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeySpinner.java @@ -133,7 +133,12 @@ public abstract class KeySpinner extends Spinner { @Override public long getItemId(int position) { - return ((Cursor) getItem(position)).getLong(mIndexMasterKeyId); + try { + return ((Cursor) getItem(position)).getLong(mIndexMasterKeyId); + } catch (Exception e) { + // This can happen on concurrent modification :( + return Constants.key.none; + } } }; } -- cgit v1.2.3 From 05da0f4328580fe9b2a164a61e39fb49fb1adef1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Thu, 14 Aug 2014 16:20:24 +0200 Subject: change keybase hint following pull request #755 --- OpenKeychain/src/main/res/layout/import_keys_keybase_fragment.xml | 2 +- OpenKeychain/src/main/res/layout/import_keys_server_fragment.xml | 2 +- OpenKeychain/src/main/res/values-cs/strings.xml | 2 +- OpenKeychain/src/main/res/values-de/strings.xml | 4 ++-- OpenKeychain/src/main/res/values-es/strings.xml | 4 ++-- OpenKeychain/src/main/res/values-fr/strings.xml | 4 ++-- OpenKeychain/src/main/res/values-it/strings.xml | 4 ++-- OpenKeychain/src/main/res/values-ja/strings.xml | 4 ++-- OpenKeychain/src/main/res/values-ru/strings.xml | 2 +- OpenKeychain/src/main/res/values-sl/strings.xml | 4 ++-- OpenKeychain/src/main/res/values-uk/strings.xml | 2 +- OpenKeychain/src/main/res/values/strings.xml | 4 ++-- 12 files changed, 19 insertions(+), 19 deletions(-) diff --git a/OpenKeychain/src/main/res/layout/import_keys_keybase_fragment.xml b/OpenKeychain/src/main/res/layout/import_keys_keybase_fragment.xml index 062289688..c70236e07 100644 --- a/OpenKeychain/src/main/res/layout/import_keys_keybase_fragment.xml +++ b/OpenKeychain/src/main/res/layout/import_keys_keybase_fragment.xml @@ -11,7 +11,7 @@ android:layout_height="wrap_content" android:layout_weight="1" android:gravity="top|left" - android:hint="@string/hint_keybase_search" + android:hint="@string/hint_keybase_search_hint" android:imeOptions="actionSearch" android:inputType="textNoSuggestions" android:singleLine="true" diff --git a/OpenKeychain/src/main/res/layout/import_keys_server_fragment.xml b/OpenKeychain/src/main/res/layout/import_keys_server_fragment.xml index fde90b81f..62e7d740c 100644 --- a/OpenKeychain/src/main/res/layout/import_keys_server_fragment.xml +++ b/OpenKeychain/src/main/res/layout/import_keys_server_fragment.xml @@ -16,7 +16,7 @@ android:layout_height="wrap_content" android:layout_weight="1" android:gravity="top|left" - android:hint="@string/hint_public_keys" + android:hint="@string/hint_keyserver_search_hint" android:imeOptions="actionSearch" android:inputType="textNoSuggestions" android:singleLine="true" diff --git a/OpenKeychain/src/main/res/values-cs/strings.xml b/OpenKeychain/src/main/res/values-cs/strings.xml index 19e94b4b8..dd4d41650 100644 --- a/OpenKeychain/src/main/res/values-cs/strings.xml +++ b/OpenKeychain/src/main/res/values-cs/strings.xml @@ -184,7 +184,7 @@ verifikuji integritu... mažu \'%s\' bezpečně... - Jméno/Email/ID klíče + Jméno/Email/ID klíče 512 768 diff --git a/OpenKeychain/src/main/res/values-de/strings.xml b/OpenKeychain/src/main/res/values-de/strings.xml index a843a154a..74282fd29 100644 --- a/OpenKeychain/src/main/res/values-de/strings.xml +++ b/OpenKeychain/src/main/res/values-de/strings.xml @@ -270,8 +270,8 @@ Integrität wird überprüft… \'%s\' wird sicher gelöscht… - Name/Email/Schlüssel ID... - Name/Keybase.io Benutzername... + Name/Email/Schlüssel ID... + Name/Keybase.io Benutzername... 512 768 diff --git a/OpenKeychain/src/main/res/values-es/strings.xml b/OpenKeychain/src/main/res/values-es/strings.xml index 80c2060d1..8b8af788d 100644 --- a/OpenKeychain/src/main/res/values-es/strings.xml +++ b/OpenKeychain/src/main/res/values-es/strings.xml @@ -276,8 +276,8 @@ verificando la integridad... borrando \'%s\' de forma segura… - Identidad de Nombre/Correo/Clave... - Nombre de usuario de Nombre/Keybase.io... + Identidad de Nombre/Correo/Clave... + Nombre de usuario de Nombre/Keybase.io... 512 768 diff --git a/OpenKeychain/src/main/res/values-fr/strings.xml b/OpenKeychain/src/main/res/values-fr/strings.xml index e30ebb883..35e4c5766 100644 --- a/OpenKeychain/src/main/res/values-fr/strings.xml +++ b/OpenKeychain/src/main/res/values-fr/strings.xml @@ -276,8 +276,8 @@ vérification de l\'intégrité... suppression sûre de « %s »... - Nom/courriel/ ID clef... - Nom/nom d\'utilisateur keybase.io... + Nom/courriel/ ID clef... + Nom/nom d\'utilisateur keybase.io... 512 768 diff --git a/OpenKeychain/src/main/res/values-it/strings.xml b/OpenKeychain/src/main/res/values-it/strings.xml index 89e09783b..2a5131bcf 100644 --- a/OpenKeychain/src/main/res/values-it/strings.xml +++ b/OpenKeychain/src/main/res/values-it/strings.xml @@ -236,8 +236,8 @@ verifica integrita\'... eliminazione sicura di \'%s\'... - Nome/Email/ID Chiave... - Nome/Keybase.io nome utente... + Nome/Email/ID Chiave... + Nome/Keybase.io nome utente... 512 768 diff --git a/OpenKeychain/src/main/res/values-ja/strings.xml b/OpenKeychain/src/main/res/values-ja/strings.xml index dbb52d208..f0cb9d47b 100644 --- a/OpenKeychain/src/main/res/values-ja/strings.xml +++ b/OpenKeychain/src/main/res/values-ja/strings.xml @@ -271,8 +271,8 @@ 完全性の検証中... \'%s\' を完全に削除中… - 名前/メール/鍵ID... - 名前/Keybase.io名... + 名前/メール/鍵ID... + 名前/Keybase.io名... 512 768 diff --git a/OpenKeychain/src/main/res/values-ru/strings.xml b/OpenKeychain/src/main/res/values-ru/strings.xml index fd2c0312d..4f32bea3a 100644 --- a/OpenKeychain/src/main/res/values-ru/strings.xml +++ b/OpenKeychain/src/main/res/values-ru/strings.xml @@ -238,7 +238,7 @@ проверка целостности... безопасное удаление \'%s\'... - Имя/Email/ID ключа… + Имя/Email/ID ключа… 512 768 diff --git a/OpenKeychain/src/main/res/values-sl/strings.xml b/OpenKeychain/src/main/res/values-sl/strings.xml index 0a7b4713e..0de5e97ea 100644 --- a/OpenKeychain/src/main/res/values-sl/strings.xml +++ b/OpenKeychain/src/main/res/values-sl/strings.xml @@ -243,8 +243,8 @@ preverjam neokrnjenost... varno brišem \'%s\'… - Ime/e-pošta/ID ključa - Ime/Keybase.io uporabniško ime... + Ime/e-pošta/ID ključa + Ime/Keybase.io uporabniško ime... 512 768 diff --git a/OpenKeychain/src/main/res/values-uk/strings.xml b/OpenKeychain/src/main/res/values-uk/strings.xml index 42ac94c32..7a4c79ddb 100644 --- a/OpenKeychain/src/main/res/values-uk/strings.xml +++ b/OpenKeychain/src/main/res/values-uk/strings.xml @@ -238,7 +238,7 @@ перевірка цілісності… вилучення безпечно \'%s\'… - Назва/Ел. пошта/ІД ключа… + Назва/Ел. пошта/ІД ключа… 512 768 diff --git a/OpenKeychain/src/main/res/values/strings.xml b/OpenKeychain/src/main/res/values/strings.xml index d491723fd..20a149956 100644 --- a/OpenKeychain/src/main/res/values/strings.xml +++ b/OpenKeychain/src/main/res/values/strings.xml @@ -303,8 +303,8 @@ deleting \'%s\' securely… - Name/Email/Key ID… - Name/Keybase.io username… + Name/Email/Key ID… + Name/Email/Proof/Key… 512 -- cgit v1.2.3 From d2b9e95c8089520411792028717ebd4b0d105764 Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Thu, 14 Aug 2014 15:59:03 +0200 Subject: tests: cleaner code in PgpKeyOperationTest --- .../keychain/pgp/PgpKeyOperationTest.java | 123 ++++++++++++--------- 1 file changed, 73 insertions(+), 50 deletions(-) diff --git a/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperationTest.java b/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperationTest.java index 8e7d395fd..93aaf05c5 100644 --- a/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperationTest.java +++ b/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperationTest.java @@ -18,8 +18,8 @@ import org.spongycastle.bcpg.UserIDPacket; import org.spongycastle.bcpg.sig.KeyFlags; import org.spongycastle.openpgp.PGPSignature; import org.spongycastle.bcpg.PublicKeyAlgorithmTags; -import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.service.OperationResultParcel.OperationLog; +import org.sufficientlysecure.keychain.service.OperationResults.EditKeyResult; import org.sufficientlysecure.keychain.service.SaveKeyringParcel; import org.sufficientlysecure.keychain.service.SaveKeyringParcel.SubkeyAdd; import org.sufficientlysecure.keychain.service.SaveKeyringParcel.SubkeyChange; @@ -78,9 +78,11 @@ public class PgpKeyOperationTest { parcel.mNewPassphrase = passphrase; PgpKeyOperation op = new PgpKeyOperation(null); - staticRing = op.createSecretKeyRing(parcel).getRing(); + EditKeyResult result = op.createSecretKeyRing(parcel); + Assert.assertTrue("initial test key creation must succeed", result.success()); + Assert.assertNotNull("initial test key creation must succeed", result.getRing()); - Assert.assertNotNull("initial test key creation must succeed", staticRing); + staticRing = result.getRing(); // we sleep here for a second, to make sure all new certificates have different timestamps Thread.sleep(1000); @@ -111,9 +113,7 @@ public class PgpKeyOperationTest { parcel.mAddUserIds.add("shy"); parcel.mNewPassphrase = passphrase; - UncachedKeyRing ring = op.createSecretKeyRing(parcel).getRing(); - - Assert.assertNull("creating ring with < 512 bytes keysize should fail", ring); + assertFailure("creating ring with < 512 bytes keysize should fail", parcel); } { @@ -123,9 +123,7 @@ public class PgpKeyOperationTest { parcel.mAddUserIds.add("shy"); parcel.mNewPassphrase = passphrase; - UncachedKeyRing ring = op.createSecretKeyRing(parcel).getRing(); - - Assert.assertNull("creating ring with ElGamal master key should fail", ring); + assertFailure("creating ring with ElGamal master key should fail", parcel); } { @@ -135,8 +133,7 @@ public class PgpKeyOperationTest { parcel.mAddUserIds.add("shy"); parcel.mNewPassphrase = passphrase; - UncachedKeyRing ring = op.createSecretKeyRing(parcel).getRing(); - Assert.assertNull("creating ring with bad algorithm choice should fail", ring); + assertFailure("creating ring with bad algorithm choice should fail", parcel); } { @@ -146,8 +143,7 @@ public class PgpKeyOperationTest { parcel.mAddUserIds.add("shy"); parcel.mNewPassphrase = passphrase; - UncachedKeyRing ring = op.createSecretKeyRing(parcel).getRing(); - Assert.assertNull("creating ring with non-certifying master key should fail", ring); + assertFailure("creating ring with non-certifying master key should fail", parcel); } { @@ -156,8 +152,7 @@ public class PgpKeyOperationTest { PublicKeyAlgorithmTags.RSA_GENERAL, 1024, KeyFlags.CERTIFY_OTHER, null)); parcel.mNewPassphrase = passphrase; - UncachedKeyRing ring = op.createSecretKeyRing(parcel).getRing(); - Assert.assertNull("creating ring without user ids should fail", ring); + assertFailure("creating ring without user ids should fail", parcel); } { @@ -165,8 +160,7 @@ public class PgpKeyOperationTest { parcel.mAddUserIds.add("shy"); parcel.mNewPassphrase = passphrase; - UncachedKeyRing ring = op.createSecretKeyRing(parcel).getRing(); - Assert.assertNull("creating ring without subkeys should fail", ring); + assertFailure("creating ring without subkeys should fail", parcel); } } @@ -179,7 +173,7 @@ public class PgpKeyOperationTest { parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( PublicKeyAlgorithmTags.RSA_GENERAL, 1024, KeyFlags.CERTIFY_OTHER | KeyFlags.SIGN_DATA, null)); parcel.mAddUserIds.add("luna"); - ring = op.createSecretKeyRing(parcel).getRing(); + ring = assertCreateSuccess("creating ring with master key flags must succeed", parcel); Assert.assertEquals("the keyring should contain only the master key", 1, KeyringTestingHelper.itToList(ring.getPublicKeys()).size()); @@ -240,9 +234,9 @@ public class PgpKeyOperationTest { parcel.mFingerprint = ring.getFingerprint(); CanonicalizedSecretKeyRing secretRing = new CanonicalizedSecretKeyRing(ring.getEncoded(), false, 0); - UncachedKeyRing modified = op.modifySecretKeyRing(secretRing, parcel, passphrase).getRing(); - Assert.assertNull("keyring modification with bad master key id should fail", modified); + assertModifyFailure("keyring modification with bad master key id should fail", + secretRing, parcel); } { @@ -252,9 +246,9 @@ public class PgpKeyOperationTest { parcel.mFingerprint = ring.getFingerprint(); CanonicalizedSecretKeyRing secretRing = new CanonicalizedSecretKeyRing(ring.getEncoded(), false, 0); - UncachedKeyRing modified = op.modifySecretKeyRing(secretRing, parcel, passphrase).getRing(); - Assert.assertNull("keyring modification with null master key id should fail", modified); + assertModifyFailure("keyring modification with null master key id should fail", + secretRing, parcel); } { @@ -265,9 +259,9 @@ public class PgpKeyOperationTest { parcel.mFingerprint[5] += 1; CanonicalizedSecretKeyRing secretRing = new CanonicalizedSecretKeyRing(ring.getEncoded(), false, 0); - UncachedKeyRing modified = op.modifySecretKeyRing(secretRing, parcel, passphrase).getRing(); - Assert.assertNull("keyring modification with bad fingerprint should fail", modified); + assertModifyFailure("keyring modification with bad fingerprint should fail", + secretRing, parcel); } { @@ -276,9 +270,9 @@ public class PgpKeyOperationTest { parcel.mFingerprint = null; CanonicalizedSecretKeyRing secretRing = new CanonicalizedSecretKeyRing(ring.getEncoded(), false, 0); - UncachedKeyRing modified = op.modifySecretKeyRing(secretRing, parcel, passphrase).getRing(); - Assert.assertNull("keyring modification with null fingerprint should fail", modified); + assertModifyFailure("keyring modification with null fingerprint should fail", + secretRing, parcel); } { @@ -287,9 +281,9 @@ public class PgpKeyOperationTest { badphrase = "a"; } CanonicalizedSecretKeyRing secretRing = new CanonicalizedSecretKeyRing(ring.getEncoded(), false, 0); - UncachedKeyRing modified = op.modifySecretKeyRing(secretRing, parcel, badphrase).getRing(); - Assert.assertNull("keyring modification with bad passphrase should fail", modified); + assertModifyFailure("keyring modification with bad passphrase should fail", + secretRing, parcel, badphrase); } } @@ -344,9 +338,8 @@ public class PgpKeyOperationTest { PublicKeyAlgorithmTags.RSA_GENERAL, new Random().nextInt(512), KeyFlags.SIGN_DATA, null)); CanonicalizedSecretKeyRing secretRing = new CanonicalizedSecretKeyRing(ring.getEncoded(), false, 0); - modified = op.modifySecretKeyRing(secretRing, parcel, passphrase).getRing(); + assertModifyFailure("creating a subkey with keysize < 512 should fail", secretRing, parcel); - Assert.assertNull("creating a subkey with keysize < 512 should fail", modified); } { // a past expiry should fail @@ -355,9 +348,7 @@ public class PgpKeyOperationTest { new Date().getTime()/1000-10)); CanonicalizedSecretKeyRing secretRing = new CanonicalizedSecretKeyRing(ring.getEncoded(), false, 0); - modified = op.modifySecretKeyRing(secretRing, parcel, passphrase).getRing(); - - Assert.assertNull("creating subkey with past expiry date should fail", modified); + assertModifyFailure("creating subkey with past expiry date should fail", secretRing, parcel); } } @@ -423,9 +414,7 @@ public class PgpKeyOperationTest { parcel.mChangeSubKeys.add(new SubkeyChange(keyId, null, new Date().getTime()/1000-10)); CanonicalizedSecretKeyRing secretRing = new CanonicalizedSecretKeyRing(ring.getEncoded(), false, 0); - modified = op.modifySecretKeyRing(secretRing, parcel, passphrase).getRing(); - - Assert.assertNull("setting subkey expiry to a past date should fail", modified); + assertModifyFailure("setting subkey expiry to a past date should fail", secretRing, parcel); } { // modifying nonexistent keyring should fail @@ -433,9 +422,7 @@ public class PgpKeyOperationTest { parcel.mChangeSubKeys.add(new SubkeyChange(123, null, null)); CanonicalizedSecretKeyRing secretRing = new CanonicalizedSecretKeyRing(ring.getEncoded(), false, 0); - modified = op.modifySecretKeyRing(secretRing, parcel, passphrase).getRing(); - - Assert.assertNull("modifying non-existent subkey should fail", modified); + assertModifyFailure("modifying non-existent subkey should fail", secretRing, parcel); } } @@ -556,9 +543,7 @@ public class PgpKeyOperationTest { parcel.mChangePrimaryUserId = uid; CanonicalizedSecretKeyRing secretRing = new CanonicalizedSecretKeyRing(modified.getEncoded(), false, 0); - UncachedKeyRing otherModified = op.modifySecretKeyRing(secretRing, parcel, passphrase).getRing(); - - Assert.assertNull("setting primary user id to a revoked user id should fail", otherModified); + assertModifyFailure("setting primary user id to a revoked user id should fail", secretRing, parcel); } @@ -604,8 +589,7 @@ public class PgpKeyOperationTest { { parcel.mAddUserIds.add(""); CanonicalizedSecretKeyRing secretRing = new CanonicalizedSecretKeyRing(ring.getEncoded(), false, 0); - UncachedKeyRing modified = op.modifySecretKeyRing(secretRing, parcel, passphrase).getRing(); - Assert.assertNull("adding an empty user id should fail", modified); + assertModifyFailure("adding an empty user id should fail", secretRing, parcel); } parcel.reset(); @@ -674,9 +658,8 @@ public class PgpKeyOperationTest { } CanonicalizedSecretKeyRing secretRing = new CanonicalizedSecretKeyRing(ring.getEncoded(), false, 0); - modified = op.modifySecretKeyRing(secretRing, parcel, passphrase).getRing(); - - Assert.assertNull("changing primary user id to a non-existent one should fail", modified); + assertModifyFailure("changing primary user id to a non-existent one should fail", + secretRing, parcel); } // check for revoked primary user id already done in revoke test @@ -705,8 +688,10 @@ public class PgpKeyOperationTest { CanonicalizedSecretKeyRing secretRing = new CanonicalizedSecretKeyRing(ring.getEncoded(), false, 0); PgpKeyOperation op = new PgpKeyOperation(null); - UncachedKeyRing rawModified = op.modifySecretKeyRing(secretRing, parcel, passphrase).getRing(); - Assert.assertNotNull("key modification failed", rawModified); + EditKeyResult result = op.modifySecretKeyRing(secretRing, parcel, passphrase); + Assert.assertTrue("key modification must succeed", result.success()); + UncachedKeyRing rawModified = result.getRing(); + Assert.assertNotNull("key modification must not return null", rawModified); if (!canonicalize) { Assert.assertTrue("keyring must differ from original", KeyringTestingHelper.diffKeyrings( @@ -753,10 +738,48 @@ public class PgpKeyOperationTest { */ @Test public void testConcat() throws Exception { - byte[] actual = TestDataUtil.concatAll(new byte[]{1}, new byte[]{2,-2}, new byte[]{5},new byte[]{3}); + byte[] actual = TestDataUtil.concatAll(new byte[]{1}, new byte[]{2, -2}, new byte[]{5}, new byte[]{3}); byte[] expected = new byte[]{1,2,-2,5,3}; Assert.assertEquals(java.util.Arrays.toString(expected), java.util.Arrays.toString(actual)); } + private void assertFailure(String reason, SaveKeyringParcel parcel) { + + EditKeyResult result = op.createSecretKeyRing(parcel); + + Assert.assertFalse(reason, result.success()); + Assert.assertNull(reason, result.getRing()); + + } + + private void assertModifyFailure(String reason, CanonicalizedSecretKeyRing secretRing, + SaveKeyringParcel parcel, String passphrase) { + + EditKeyResult result = op.modifySecretKeyRing(secretRing, parcel, passphrase); + + Assert.assertFalse(reason, result.success()); + Assert.assertNull(reason, result.getRing()); + + } + + private void assertModifyFailure(String reason, CanonicalizedSecretKeyRing secretRing, SaveKeyringParcel parcel) { + + EditKeyResult result = op.modifySecretKeyRing(secretRing, parcel, passphrase); + + Assert.assertFalse(reason, result.success()); + Assert.assertNull(reason, result.getRing()); + + } + + private UncachedKeyRing assertCreateSuccess(String reason, SaveKeyringParcel parcel) { + + EditKeyResult result = op.createSecretKeyRing(parcel); + + Assert.assertTrue(reason, result.success()); + Assert.assertNotNull(reason, result.getRing()); + + return result.getRing(); + + } } -- cgit v1.2.3 From a19784ed7e930055a6a1d0a537f2f4f1d3ea1f21 Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Thu, 14 Aug 2014 16:27:50 +0200 Subject: merge: check fingerprints on merge operation! (this needs a testcase!) --- .../java/org/sufficientlysecure/keychain/pgp/UncachedKeyRing.java | 4 +++- OpenKeychain/src/main/res/values/strings.xml | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedKeyRing.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedKeyRing.java index 5c8a85de9..20e78d7fa 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedKeyRing.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedKeyRing.java @@ -45,6 +45,7 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import java.util.Arrays; import java.util.Comparator; import java.util.Date; import java.util.Iterator; @@ -692,7 +693,8 @@ public class UncachedKeyRing { long masterKeyId = other.getMasterKeyId(); - if (getMasterKeyId() != masterKeyId) { + if (getMasterKeyId() != masterKeyId + || Arrays.equals(getFingerprint(), other.getFingerprint())) { log.add(LogLevel.ERROR, LogType.MSG_MG_HETEROGENEOUS, indent); return null; } diff --git a/OpenKeychain/src/main/res/values/strings.xml b/OpenKeychain/src/main/res/values/strings.xml index 20a149956..0da651b03 100644 --- a/OpenKeychain/src/main/res/values/strings.xml +++ b/OpenKeychain/src/main/res/values/strings.xml @@ -616,7 +616,7 @@ Merging into public keyring %s Merging into secret keyring %s Fatal error encoding signature - Tried to consolidate heterogeneous keyrings + Tried to merge keyrings with differing fingerprints! Adding new subkey %s Found %s new certificates in keyring No new certificates -- cgit v1.2.3 From 2c408f679c691a29814ef7d53de7130e3aa22dfc Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Thu, 14 Aug 2014 16:34:57 +0200 Subject: dem logix --- .../main/java/org/sufficientlysecure/keychain/pgp/UncachedKeyRing.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedKeyRing.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedKeyRing.java index 20e78d7fa..83c244d52 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedKeyRing.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedKeyRing.java @@ -694,7 +694,7 @@ public class UncachedKeyRing { long masterKeyId = other.getMasterKeyId(); if (getMasterKeyId() != masterKeyId - || Arrays.equals(getFingerprint(), other.getFingerprint())) { + || !Arrays.equals(getFingerprint(), other.getFingerprint())) { log.add(LogLevel.ERROR, LogType.MSG_MG_HETEROGENEOUS, indent); return null; } -- cgit v1.2.3 From 110f8c4d5287e2603041c6ccc099ba18327d5043 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Thu, 14 Aug 2014 17:00:36 +0200 Subject: Update sticky list headers --- extern/StickyListHeaders | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extern/StickyListHeaders b/extern/StickyListHeaders index 706c0e447..67e757703 160000 --- a/extern/StickyListHeaders +++ b/extern/StickyListHeaders @@ -1 +1 @@ -Subproject commit 706c0e447229226b6edc82ab10630d39fd0f6c38 +Subproject commit 67e7577033e488701e7d03767d13656735015e4b -- cgit v1.2.3 From 9c0388939076c0d15de01941a41ab8428df5c668 Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Thu, 14 Aug 2014 17:10:08 +0200 Subject: tests: add ProviderHelperSaveTest, with long key id collision test --- .../keychain/provider/ProviderHelperSaveTest.java | 55 ++++++++++++++++++++++ .../9E669861368BCA0BE42DAF7DDDA252EBB8EBE1AF.asc | 29 ++++++++++++ .../A55120427374F3F7AA5F1166DDA252EBB8EBE1AF.asc | 29 ++++++++++++ .../src/test/resources/cooperpair/readme | 3 ++ .../keychain/provider/KeychainDatabase.java | 5 ++ 5 files changed, 121 insertions(+) create mode 100644 OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/provider/ProviderHelperSaveTest.java create mode 100644 OpenKeychain-Test/src/test/resources/cooperpair/9E669861368BCA0BE42DAF7DDDA252EBB8EBE1AF.asc create mode 100644 OpenKeychain-Test/src/test/resources/cooperpair/A55120427374F3F7AA5F1166DDA252EBB8EBE1AF.asc create mode 100644 OpenKeychain-Test/src/test/resources/cooperpair/readme diff --git a/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/provider/ProviderHelperSaveTest.java b/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/provider/ProviderHelperSaveTest.java new file mode 100644 index 000000000..7a5afcc3a --- /dev/null +++ b/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/provider/ProviderHelperSaveTest.java @@ -0,0 +1,55 @@ +package org.sufficientlysecure.keychain.provider; + +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.Robolectric; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.shadows.ShadowLog; +import org.sufficientlysecure.keychain.pgp.UncachedKeyRing; +import org.sufficientlysecure.keychain.service.OperationResults.SaveKeyringResult; + +import java.io.IOException; +import java.util.Iterator; + +@RunWith(RobolectricTestRunner.class) +@org.robolectric.annotation.Config(emulateSdk = 18) // Robolectric doesn't yet support 19 +public class ProviderHelperSaveTest { + + @BeforeClass + public static void setUpOnce() throws Exception { + ShadowLog.stream = System.out; + } + + @Test + public void testLongKeyIdCollision() throws Exception { + + UncachedKeyRing first = + readRingFromResource("/cooperpair/9E669861368BCA0BE42DAF7DDDA252EBB8EBE1AF.asc"); + UncachedKeyRing second = + readRingFromResource("/cooperpair/A55120427374F3F7AA5F1166DDA252EBB8EBE1AF.asc"); + + SaveKeyringResult result; + + // insert both keys, second should fail + result = new ProviderHelper(Robolectric.application).savePublicKeyRing(first); + Assert.assertTrue("first keyring import should succeed", result.success()); + result = new ProviderHelper(Robolectric.application).savePublicKeyRing(second); + Assert.assertFalse("second keyring import should fail", result.success()); + + new KeychainDatabase(Robolectric.application).clearDatabase(); + + // and the other way around + result = new ProviderHelper(Robolectric.application).savePublicKeyRing(second); + Assert.assertTrue("first keyring import should succeed", result.success()); + result = new ProviderHelper(Robolectric.application).savePublicKeyRing(first); + Assert.assertFalse("second keyring import should fail", result.success()); + + } + + UncachedKeyRing readRingFromResource(String name) throws Exception { + return UncachedKeyRing.fromStream(ProviderHelperSaveTest.class.getResourceAsStream(name)).next(); + } + +} \ No newline at end of file diff --git a/OpenKeychain-Test/src/test/resources/cooperpair/9E669861368BCA0BE42DAF7DDDA252EBB8EBE1AF.asc b/OpenKeychain-Test/src/test/resources/cooperpair/9E669861368BCA0BE42DAF7DDDA252EBB8EBE1AF.asc new file mode 100644 index 000000000..4f51252da --- /dev/null +++ b/OpenKeychain-Test/src/test/resources/cooperpair/9E669861368BCA0BE42DAF7DDDA252EBB8EBE1AF.asc @@ -0,0 +1,29 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- +Version: GnuPG v1 + +mQINBFJtd/UBEACpw/psXoGNM8RHczviD7FnGdjMQPEJQ+nuWQ2AEGYouulg5hFv +0ChuSQVLiqQht2k5K2liyW1MeXoJ8tr9nSn/Zi9nttc0Wo6K7pvrDD40r2HNg305 +qLCzItr5st3x8cq2cIXvN4LOm2rqpBLZ/sqMmNiW2Y7/aAQqV1xtR35joHqamWHD +UPOmzBMs07YSUjXgC1EMx8kWQSV6cuARj93kxWj8R6eoYHHfrWCEGR313wov6QST +zIfVU7FqQqOmdLW3LaPHxcrI/TjsnkUN99qdlpjJH/YW925LDPJHAkliqPP5AvhU +F9KbY2F8mcIZBCDd8TH+xXynuN3BbIU4kCwVbdx/tcpO1npuJcKB1Go/udyow/Ei +Z3nHzJsCVkezvopek77wnwPaP0nAb7f4iIY3gJCoGirOx6N075TgF6MBe00q9oFE +y4rvnUnU9/QzOOes95eUMhM+9eK1cuLFEV5t47DfxRdq+fQip3FJ2l6v19sZvQ0G +j06pjYqg0of273rG8oXcDrFjb1Zqhj8x1mLl6u7d/ide5wTm9HylBWcYKQjIJJAi +WIScxEPIOINDJKgsKTuKtoyNvISJ3xUeS1yzxiIb3YGLIyPgFFx0vFyqJfbkXq70 +m1n2xnJlkTidfzbZvc6EA7vRGSDYK6FqqhlGhc7UypUEVW8FM/jZNAOS6QARAUGt +tCg5RTY2OTg2MTM2OEJDQTBCRTQyREFGN0REREEyNTJFQkI4RUJFMUFGiQI3BBMB +CgAhBQJSg/uTAhsDBQsJCAcDBRUKCQgLBRYCAwEAAh4BAheAAAoJEN2iUuu46+Gv ++Z0P+wQhkLwm+WGcEsS98Lei9O7hit/k4g/VkLUUQV7BOR3n8uRZIFkdOtpvrFU3 +aKf246uCy6GM48Oh+1U2cv5InX/WEuKaFo5uF6t79wyt18BUn1weDcU+DQdOSG4f +fSnNa55wkN0l0svW4fGIthjmDTz6HZFntYD+9A20wZAqpPIs+vyG9Jp+e9E9Y/W/ +EFQbNlxHHb9+BMT2+DtNP+HSl3MPFlQPKOLZxyLAU5uzT0Sa0LxhrQy5FgkW6Jog +sbAJVM9z0pZw+grzGPciM66ZW1rxeICvbYsdWLytRjqxpY8GS8XudyseUGd+dZim +ptarsrE5yfSMg2gW5Z1PTc0tEMXJLUwtpyzQjpFpbb7dPuo2TUp09LgZKX63WCbS +Nb1RTaGfkeYudOTo2rh4Jfg+Tb/JRpO6clo0rxAq8nPH2WmG+9TB8Zbb7YRzGWuV +/e5SeVNR+zY8tXZKnmUIH1HIprc+BtT6Bupdvd0CT14Mg9MmsFvUXofwHLa4gahr +8/iG9y3uHSA6Rhz++yOpyOmNvO1LDxsYNaRCIXQJbqgNwF5YNYlMPsEeY/CG7FOb +Afv7rHiYtRRQfz2P4OF900DJO7QL9gdNXJ1+Hajy/5Lvvl7qwqMG4GvVQEsgFc5O +jjFCUhE2i20j2kEMxvA5RLBH/fOoGARn87tiKSfb+pqLNZQb +=fDJ8 +-----END PGP PUBLIC KEY BLOCK----- \ No newline at end of file diff --git a/OpenKeychain-Test/src/test/resources/cooperpair/A55120427374F3F7AA5F1166DDA252EBB8EBE1AF.asc b/OpenKeychain-Test/src/test/resources/cooperpair/A55120427374F3F7AA5F1166DDA252EBB8EBE1AF.asc new file mode 100644 index 000000000..549bc51a2 --- /dev/null +++ b/OpenKeychain-Test/src/test/resources/cooperpair/A55120427374F3F7AA5F1166DDA252EBB8EBE1AF.asc @@ -0,0 +1,29 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- +Version: GnuPG v1 + +mQINBFKD+38BEADSv5l4xOx9hCRJVcybq6yK5hTpGSFf3xo1bkhoMvyC62ehb4jD +MDLwwNRyzCBEWQJLbq/LLizPFN2qXFJpXJcsuqsHNYRtDqDBEjtriRQwSqHnqTXt +c0K46FYHldCJQ4/tBXxPI+WwtXjcNRWaV7n2BvR/Jk+B5e4Zz3LPnN0C4w5vORHs +hN1jil8A3Hs/F+OmlQYrU8ZtNwTpSo2EXxe2fVgSDCsKRyNsPZj++OyujPzW+yaN +lJ9I/q6s9gvX9o9o7nwZbqBETipWsdRK6RfBdTKpnyLNordbWwWTk6GxN8T5Ppit +P6a3UlQ71VuflcswCTmEQ1pEfZrlRFKa9psBOW+cZLNxT9h0jGFMh6/B3w48Sag+ +cFcPBFWParC+cAXBIURDxT9G6bzNLogg7YKoaPsyiXnLDH2VJUCXs27D2wPJL24Q +S7npvsg63MPPssWgG5cauLznmNR4y5pQi6oH/C10v0zrUJy6FPJzQhYRhWOvhtz6 +j88RGMrFNNCdB2VACtn699D+ixu3nRlXHIKCT+xLSfgslVYifmJOCNljBLGHOQ1e +FJxQuNVpmmxjvk/8kqK+pHLB9Qn6M1ZYzip7OyUL3OAWabCabgEw2bQmUhiBWD3u +buv0WAVOJEAFvBCAeYNQzrQMY+Rc3RnvynG4pI6Tbo8wC6/IJcDOw516JwARASB3 +tChBNTUxMjA0MjczNzRGM0Y3QUE1RjExNjZEREEyNTJFQkI4RUJFMUFGiQI3BBMB +CgAhBQJSg/uTAhsDBQsJCAcDBRUKCQgLBRYCAwEAAh4BAheAAAoJEN2iUuu46+Gv +9L0P/3tFu0LOZ/dAPjUNfKJCZqcIuVnD5xShMTsUbVx+QoXMy7rt4iRLD7ofGi/I +vTAZehxk3sk/Slx5nbews+3NItyw6mcaP9HlmwKNr6k7BC2kJHcCxH4DNzhmIx1H +3T/CggtHX42JBYKlGf22y+M8jAbvsPOUfTznx96mYNrOY6s1dJyn0kRleqJ8+tGj +/5+0y90iZnGCa0FtacQkKUPkXwVodeZVxk8z5OEipShYKc+8dl+5WsvOzHqLC/KY +xCGRb4JaqEMwouLNg8dTNAXXUvFGqJNDX4+andggogmI1hdD9xExfSU9cAGegg2t +vvveC4S+CCHd+zt88iK5ze6F61RxwYhhNbkuFGjdgNGCpHtG/BQhKnYJuKEbq3oi +mgNyxJERlfgaWXveiMG0AmACXN+jCkTtqZjQnsg2N2QDL3tjY7usmuiwRL1aVOFG +Kw5/Cc+2nDeANS3Xi1403Ni269b1c6kNSoLe4zd0WsbO3Kouds8F8EQfeheXQe97 +ZxuvBOMsR9wHC3f0sl/vfxCGdUC+khmKk5taKnUeUFJmVmh5ghlVy8FySHGB0QHO +zd8GUl59rFpQJNpNFQW2YKDhrcjxIr2AeJrdoDI6NsQ02+Qtep/bbq53hqtAD4jF +t3S8vBbTXtRk6g2qn4ojF4SOIc8SAiZcURgVFuSJX8ngFbO4 +=OEw/ +-----END PGP PUBLIC KEY BLOCK----- \ No newline at end of file diff --git a/OpenKeychain-Test/src/test/resources/cooperpair/readme b/OpenKeychain-Test/src/test/resources/cooperpair/readme new file mode 100644 index 000000000..fecb372d9 --- /dev/null +++ b/OpenKeychain-Test/src/test/resources/cooperpair/readme @@ -0,0 +1,3 @@ +"Cooperpair" testcase under public domain license, by @coruus: + +https://github.com/coruus/cooperpair/tree/master/pgpv4 diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainDatabase.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainDatabase.java index 3a859f505..a90c88c3e 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainDatabase.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainDatabase.java @@ -349,4 +349,9 @@ public class KeychainDatabase extends SQLiteOpenHelper { copy(in, out); } + // for test cases ONLY!! + public void clearDatabase() { + getWritableDatabase().execSQL("delete from " + Tables.KEY_RINGS_PUBLIC); + } + } -- cgit v1.2.3 From 9af301ec7750e33f687de3e3cdbfceae5551451c Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Thu, 14 Aug 2014 17:12:17 +0200 Subject: handle modify and save errors in KeychainIntentResult --- .../keychain/provider/ProviderHelper.java | 4 +++ .../keychain/service/KeychainIntentService.java | 30 ++++++++++++++++------ .../keychain/ui/EditKeyFragment.java | 15 +++++------ 3 files changed, 33 insertions(+), 16 deletions(-) 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 a13bb9c98..960c508f8 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java @@ -86,6 +86,10 @@ public class ProviderHelper { this(context, new OperationLog(), 0); } + public ProviderHelper(Context context, OperationLog log) { + this(context, log, 0); + } + public ProviderHelper(Context context, OperationLog log, int indent) { mContext = context; mContentResolver = context.getContentResolver(); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java index d6c470e11..0fdc62633 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java @@ -54,6 +54,7 @@ import org.sufficientlysecure.keychain.provider.KeychainDatabase; import org.sufficientlysecure.keychain.provider.ProviderHelper; import org.sufficientlysecure.keychain.service.OperationResults.EditKeyResult; import org.sufficientlysecure.keychain.service.OperationResults.ImportKeyResult; +import org.sufficientlysecure.keychain.service.OperationResults.SaveKeyringResult; import org.sufficientlysecure.keychain.util.FileImportCache; import org.sufficientlysecure.keychain.util.InputData; import org.sufficientlysecure.keychain.util.Log; @@ -391,23 +392,36 @@ public class KeychainIntentService extends IntentService } /* Operation */ - ProviderHelper providerHelper = new ProviderHelper(this); PgpKeyOperation keyOperations = new PgpKeyOperation(new ProgressScaler(this, 10, 60, 100)); - EditKeyResult result; + EditKeyResult modifyResult; if (saveParcel.mMasterKeyId != null) { String passphrase = data.getString(SAVE_KEYRING_PASSPHRASE); CanonicalizedSecretKeyRing secRing = - providerHelper.getCanonicalizedSecretKeyRing(saveParcel.mMasterKeyId); + new ProviderHelper(this).getCanonicalizedSecretKeyRing(saveParcel.mMasterKeyId); - result = keyOperations.modifySecretKeyRing(secRing, saveParcel, passphrase); + modifyResult = keyOperations.modifySecretKeyRing(secRing, saveParcel, passphrase); } else { - result = keyOperations.createSecretKeyRing(saveParcel); + modifyResult = keyOperations.createSecretKeyRing(saveParcel); + } + + // If the edit operation didn't succeed, exit here + if ( ! modifyResult.success()) { + sendMessageToHandler(KeychainIntentServiceHandler.MESSAGE_OKAY, modifyResult); + return; } - UncachedKeyRing ring = result.getRing(); + UncachedKeyRing ring = modifyResult.getRing(); - providerHelper.saveSecretKeyRing(ring, new ProgressScaler(this, 60, 95, 100)); + // Save the keyring. The ProviderHelper is initialized with the previous log + SaveKeyringResult saveResult = new ProviderHelper(this, modifyResult.getLog()) + .saveSecretKeyRing(ring, new ProgressScaler(this, 60, 95, 100)); + + // If the edit operation didn't succeed, exit here + if ( ! saveResult.success()) { + sendMessageToHandler(KeychainIntentServiceHandler.MESSAGE_OKAY, saveResult); + return; + } // cache new passphrase if (saveParcel.mNewPassphrase != null) { @@ -418,7 +432,7 @@ public class KeychainIntentService extends IntentService setProgress(R.string.progress_done, 100, 100); /* Output */ - sendMessageToHandler(KeychainIntentServiceHandler.MESSAGE_OKAY, result); + sendMessageToHandler(KeychainIntentServiceHandler.MESSAGE_OKAY, saveResult); } catch (Exception e) { sendErrorToHandler(e); } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyFragment.java index 03074bb6a..b18d1626a 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyFragment.java @@ -48,8 +48,7 @@ import org.sufficientlysecure.keychain.provider.KeychainContract; import org.sufficientlysecure.keychain.provider.ProviderHelper; import org.sufficientlysecure.keychain.service.KeychainIntentService; import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler; -import org.sufficientlysecure.keychain.service.OperationResults; -import org.sufficientlysecure.keychain.service.OperationResults.EditKeyResult; +import org.sufficientlysecure.keychain.service.OperationResultParcel; import org.sufficientlysecure.keychain.service.PassphraseCacheService; import org.sufficientlysecure.keychain.service.SaveKeyringParcel; import org.sufficientlysecure.keychain.ui.adapter.SubkeysAdapter; @@ -408,9 +407,9 @@ public class EditKeyFragment extends LoaderFragment implements public void handleMessage(Message message) { switch (message.what) { case EditSubkeyExpiryDialogFragment.MESSAGE_NEW_EXPIRY_DATE: - Long expiry = (Long) message.getData(). - getSerializable(EditSubkeyExpiryDialogFragment.MESSAGE_DATA_EXPIRY_DATE); - mSaveKeyringParcel.getOrCreateSubkeyChange(keyId).mExpiry = expiry; + mSaveKeyringParcel.getOrCreateSubkeyChange(keyId).mExpiry = + (Long) message.getData().getSerializable( + EditSubkeyExpiryDialogFragment.MESSAGE_DATA_EXPIRY_DATE); break; } getLoaderManager().getLoader(LOADER_ID_SUBKEYS).forceLoad(); @@ -520,8 +519,8 @@ public class EditKeyFragment extends LoaderFragment implements if (returnData == null) { return; } - final OperationResults.EditKeyResult result = - returnData.getParcelable(EditKeyResult.EXTRA_RESULT); + final OperationResultParcel result = + returnData.getParcelable(OperationResultParcel.EXTRA_RESULT); if (result == null) { return; } @@ -534,7 +533,7 @@ public class EditKeyFragment extends LoaderFragment implements // if good -> finish, return result to showkey and display there! Intent intent = new Intent(); - intent.putExtra(EditKeyResult.EXTRA_RESULT, result); + intent.putExtra(OperationResultParcel.EXTRA_RESULT, result); getActivity().setResult(EditKeyActivity.RESULT_OK, intent); getActivity().finish(); -- cgit v1.2.3 From e1958009bd022021971c1fd2f81557fb4fe99e4e Mon Sep 17 00:00:00 2001 From: mar-v-in Date: Thu, 14 Aug 2014 18:10:22 +0200 Subject: Do not allow self certifying --- .../keychain/ui/CertifyKeyActivity.java | 2 +- .../keychain/ui/widget/CertifyKeySpinner.java | 16 ++++++++++++++-- .../keychain/ui/widget/KeySpinner.java | 6 +++++- 3 files changed, 20 insertions(+), 4 deletions(-) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java index d1e8a80dc..7c6e94d5e 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java @@ -34,7 +34,6 @@ import android.support.v7.app.ActionBarActivity; import android.view.MenuItem; import android.view.View; import android.view.View.OnClickListener; -import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.CheckBox; import android.widget.CompoundButton; @@ -203,6 +202,7 @@ public class CertifyKeyActivity extends ActionBarActivity implements LoaderManag if (data.moveToFirst()) { // TODO: put findViewById in onCreate! mPubKeyId = data.getLong(INDEX_MASTER_KEY_ID); + mCertifyKeySpinner.setHiddenMasterKeyId(mPubKeyId); String keyIdStr = PgpKeyHelper.convertKeyIdToHex(mPubKeyId); ((TextView) findViewById(R.id.key_id)).setText(keyIdStr); 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 b686d108b..030a76136 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 @@ -6,9 +6,13 @@ import android.net.Uri; import android.support.v4.content.CursorLoader; import android.support.v4.content.Loader; import android.util.AttributeSet; +import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.provider.KeychainContract; +import org.sufficientlysecure.keychain.provider.KeychainDatabase; public class CertifyKeySpinner extends KeySpinner { + private long mHiddenMasterKeyId = Constants.key.none; + public CertifyKeySpinner(Context context) { super(context); } @@ -21,6 +25,11 @@ public class CertifyKeySpinner extends KeySpinner { super(context, attrs, defStyle); } + public void setHiddenMasterKeyId(long hiddenMasterKeyId) { + this.mHiddenMasterKeyId = hiddenMasterKeyId; + reload(); + } + @Override public Loader onCreateLoader() { // This is called when a new Loader needs to be created. This @@ -38,8 +47,11 @@ public class CertifyKeySpinner extends KeySpinner { KeychainContract.KeyRings.HAS_ANY_SECRET }; - String where = KeychainContract.KeyRings.HAS_ANY_SECRET + " = 1 AND " + KeychainContract.KeyRings.HAS_CERTIFY + " NOT NULL AND " - + KeychainContract.KeyRings.IS_REVOKED + " = 0 AND " + KeychainContract.KeyRings.IS_EXPIRED + " = 0"; + String where = KeychainContract.KeyRings.HAS_ANY_SECRET + " = 1 AND " + + KeychainContract.KeyRings.HAS_CERTIFY + " NOT NULL AND " + + KeychainContract.KeyRings.IS_REVOKED + " = 0 AND " + + KeychainContract.KeyRings.IS_EXPIRED + " = 0 AND " + KeychainDatabase.Tables.KEYS + "." + + KeychainContract.KeyRings.MASTER_KEY_ID + " != " + mHiddenMasterKeyId; // Now create and return a CursorLoader that will take care of // creating a Cursor for the data being displayed. diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeySpinner.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeySpinner.java index 380361fc0..b12029239 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeySpinner.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeySpinner.java @@ -80,8 +80,12 @@ public abstract class KeySpinner extends Spinner { @Override protected void onAttachedToWindow() { super.onAttachedToWindow(); + reload(); + } + + public void reload() { if (getContext() instanceof FragmentActivity) { - ((FragmentActivity) getContext()).getSupportLoaderManager().initLoader(hashCode(), null, new LoaderManager.LoaderCallbacks() { + ((FragmentActivity) getContext()).getSupportLoaderManager().restartLoader(hashCode(), null, new LoaderManager.LoaderCallbacks() { @Override public Loader onCreateLoader(int id, Bundle args) { return KeySpinner.this.onCreateLoader(); -- cgit v1.2.3 From 65e76f6e4465324af59a305c87c745fbedcaac46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Thu, 14 Aug 2014 18:51:35 +0200 Subject: hacky fix to prevent key list from scrolling to top when opening nav drawer --- .../keychain/ui/KeyListFragment.java | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) 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 3c97b1128..e7b7d2efc 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java @@ -330,12 +330,12 @@ public class KeyListFragment extends LoaderFragment * Show dialog to delete key * * @param masterKeyIds - * @param hasSecret must contain whether the list of masterKeyIds contains a secret key or not + * @param hasSecret must contain whether the list of masterKeyIds contains a secret key or not */ @TargetApi(Build.VERSION_CODES.HONEYCOMB) public void showDeleteKeyDialog(final ActionMode mode, long[] masterKeyIds, boolean hasSecret) { // Can only work on singular secret keys - if(hasSecret && masterKeyIds.length > 1) { + if (hasSecret && masterKeyIds.length > 1) { Notify.showNotify(getActivity(), R.string.secret_cannot_multiple, Notify.Style.ERROR); return; @@ -365,6 +365,7 @@ public class KeyListFragment extends LoaderFragment public void onCreateOptionsMenu(final Menu menu, final MenuInflater inflater) { // Get the searchview MenuItem searchItem = menu.findItem(R.id.menu_key_list_search); + mSearchView = (SearchView) MenuItemCompat.getActionView(searchItem); // Execute this when searching @@ -383,7 +384,6 @@ public class KeyListFragment extends LoaderFragment @Override public boolean onMenuItemActionCollapse(MenuItem item) { mQuery = null; - mSearchView.setQuery("", true); getLoaderManager().restartLoader(0, null, KeyListFragment.this); return true; } @@ -399,11 +399,18 @@ public class KeyListFragment extends LoaderFragment @Override public boolean onQueryTextChange(String s) { + Log.d(Constants.TAG, "onQueryTextChange s:" + s); // Called when the action bar search text has changed. Update // the search filter, and restart the loader to do a new query // with this filter. - mQuery = !TextUtils.isEmpty(s) ? s : null; - getLoaderManager().restartLoader(0, null, this); + // If the nav drawer is opened, onQueryTextChange("") is executed. + // This hack prevents restarting the loader. + // TODO: better way to fix this? + String tmp = (mQuery == null) ? "" : mQuery; + if (!s.equals(tmp)) { + mQuery = s; + getLoaderManager().restartLoader(0, null, this); + } return true; } @@ -479,7 +486,7 @@ public class KeyListFragment extends LoaderFragment boolean isRevoked = cursor.getInt(INDEX_IS_REVOKED) > 0; boolean isExpired = !cursor.isNull(INDEX_EXPIRY) - && new Date(cursor.getLong(INDEX_EXPIRY)*1000).before(new Date()); + && new Date(cursor.getLong(INDEX_EXPIRY) * 1000).before(new Date()); boolean isVerified = cursor.getInt(INDEX_VERIFIED) > 0; // Note: order is important! @@ -521,6 +528,7 @@ public class KeyListFragment extends LoaderFragment return mCursor.getInt(INDEX_HAS_ANY_SECRET) != 0; } + public long getMasterKeyId(int id) { if (!mCursor.moveToPosition(id)) { throw new IllegalStateException("couldn't move cursor to position " + id); @@ -625,7 +633,7 @@ public class KeyListFragment extends LoaderFragment public boolean isAnySecretSelected() { for (int pos : mSelection.keySet()) { - if(mAdapter.isSecretAvailable(pos)) + if (mAdapter.isSecretAvailable(pos)) return true; } return false; -- cgit v1.2.3 From 6e7b99940964e162d9b1134bc1607b8084bc2dcc Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Thu, 14 Aug 2014 18:56:08 +0200 Subject: fix subkey certification canonicalization (why did the test not catch this?!) --- .../main/java/org/sufficientlysecure/keychain/pgp/UncachedKeyRing.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedKeyRing.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedKeyRing.java index 83c244d52..0a59ba9f8 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedKeyRing.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedKeyRing.java @@ -593,7 +593,7 @@ public class UncachedKeyRing { } // if we already have a cert, and this one is not newer: skip it - if (selfCert != null && selfCert.getCreationTime().before(cert.getCreationTime())) { + if (selfCert != null && cert.getCreationTime().before(selfCert.getCreationTime())) { log.add(LogLevel.DEBUG, LogType.MSG_KC_SUB_DUP, indent); redundantCerts += 1; continue; -- cgit v1.2.3 From 48935557e89051fb905f20690522632f39b1406a Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Thu, 14 Aug 2014 19:12:29 +0200 Subject: support changing expiry of subkeys to none --- .../keychain/pgp/PgpKeyOperationTest.java | 18 ++++++++++++++++++ .../keychain/pgp/PgpKeyOperation.java | 3 ++- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperationTest.java b/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperationTest.java index 93aaf05c5..2f32677f2 100644 --- a/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperationTest.java +++ b/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperationTest.java @@ -409,6 +409,24 @@ public class PgpKeyOperationTest { expiry, modified.getPublicKey(keyId).getExpiryTime().getTime()/1000); } + { // expiry of 0 should be "no expiry" + parcel.reset(); + parcel.mChangeSubKeys.add(new SubkeyChange(keyId, null, 0L)); + modified = applyModificationWithChecks(parcel, modified, onlyA, onlyB); + + Assert.assertEquals("old packet must be signature", + PacketTags.SIGNATURE, onlyA.get(0).tag); + + Packet p = new BCPGInputStream(new ByteArrayInputStream(onlyB.get(0).buf)).readPacket(); + Assert.assertTrue("first new packet must be signature", p instanceof SignaturePacket); + Assert.assertEquals("signature type must be subkey binding certificate", + PGPSignature.SUBKEY_BINDING, ((SignaturePacket) p).getSignatureType()); + Assert.assertEquals("signature must have been created by master key", + ring.getMasterKeyId(), ((SignaturePacket) p).getKeyID()); + + Assert.assertNull("key must not expire anymore", modified.getPublicKey(keyId).getExpiryTime()); + } + { // a past expiry should fail parcel.reset(); parcel.mChangeSubKeys.add(new SubkeyChange(keyId, null, new Date().getTime()/1000-10)); 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 bb692555e..fe84b3802 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java @@ -543,7 +543,8 @@ public class PgpKeyOperation { PGPPublicKey pKey = sKey.getPublicKey(); // expiry must not be in the past - if (change.mExpiry != null && new Date(change.mExpiry*1000).before(new Date())) { + if (change.mExpiry != null && change.mExpiry != 0 && + new Date(change.mExpiry*1000).before(new Date())) { log.add(LogLevel.ERROR, LogType.MSG_MF_SUBKEY_PAST_EXPIRY, indent + 1, PgpKeyHelper.convertKeyIdToHex(change.mKeyId)); return new EditKeyResult(EditKeyResult.RESULT_ERROR, log, null); -- cgit v1.2.3 From 621978a7f501197d7f662c657f4bd6813391bab0 Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Thu, 14 Aug 2014 19:13:18 +0200 Subject: explicitly add BouncyCastleProvider (fixes travis?) --- .../java/org/sufficientlysecure/keychain/pgp/PgpKeyOperationTest.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperationTest.java b/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperationTest.java index 2f32677f2..f37f11d87 100644 --- a/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperationTest.java +++ b/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperationTest.java @@ -16,6 +16,7 @@ import org.spongycastle.bcpg.SecretSubkeyPacket; import org.spongycastle.bcpg.SignaturePacket; import org.spongycastle.bcpg.UserIDPacket; import org.spongycastle.bcpg.sig.KeyFlags; +import org.spongycastle.jce.provider.BouncyCastleProvider; import org.spongycastle.openpgp.PGPSignature; import org.spongycastle.bcpg.PublicKeyAlgorithmTags; import org.sufficientlysecure.keychain.service.OperationResultParcel.OperationLog; @@ -31,6 +32,7 @@ import org.sufficientlysecure.keychain.util.ProgressScaler; import java.io.ByteArrayInputStream; import java.io.IOException; +import java.security.Security; import java.util.ArrayList; import java.util.Date; import java.util.Iterator; @@ -51,6 +53,8 @@ public class PgpKeyOperationTest { ArrayList onlyB = new ArrayList(); @BeforeClass public static void setUpOnce() throws Exception { + Security.insertProviderAt(new BouncyCastleProvider(), 1); + ShadowLog.stream = System.out; { -- cgit v1.2.3 From 0f60bcbc3d2438a8822e9bc1c6d80f8d0b743e3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Thu, 14 Aug 2014 19:25:39 +0200 Subject: Pass through of master key id in SaveKeyringResult --- .../keychain/provider/ProviderHelper.java | 38 +++++++++++----------- .../keychain/service/OperationResults.java | 37 ++++++++++++++++++--- .../keychain/ui/CreateKeyFinalFragment.java | 4 +-- 3 files changed, 54 insertions(+), 25 deletions(-) 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 960c508f8..ac6ea015a 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java @@ -648,7 +648,7 @@ public class ProviderHelper { if (publicRing.isSecret()) { log(LogLevel.ERROR, LogType.MSG_IP_BAD_TYPE_SECRET); - return new SaveKeyringResult(SaveKeyringResult.RESULT_ERROR, mLog); + return new SaveKeyringResult(SaveKeyringResult.RESULT_ERROR, mLog, null); } CanonicalizedPublicKeyRing canPublicRing; @@ -662,20 +662,20 @@ public class ProviderHelper { // If this is null, there is an error in the log so we can just return if (publicRing == null) { - return new SaveKeyringResult(SaveKeyringResult.RESULT_ERROR, mLog); + return new SaveKeyringResult(SaveKeyringResult.RESULT_ERROR, mLog, null); } // Canonicalize this keyring, to assert a number of assumptions made about it. canPublicRing = (CanonicalizedPublicKeyRing) publicRing.canonicalize(mLog, mIndent); if (canPublicRing == null) { - return new SaveKeyringResult(SaveKeyringResult.RESULT_ERROR, mLog); + return new SaveKeyringResult(SaveKeyringResult.RESULT_ERROR, mLog, null); } // Early breakout if nothing changed if (Arrays.hashCode(publicRing.getEncoded()) == Arrays.hashCode(oldPublicRing.getEncoded())) { log(LogLevel.OK, LogType.MSG_IP_SUCCESS_IDENTICAL); - return new SaveKeyringResult(SaveKeyringResult.UPDATED, mLog); + return new SaveKeyringResult(SaveKeyringResult.UPDATED, mLog, null); } } catch (NotFoundException e) { // Not an issue, just means we are dealing with a new keyring. @@ -683,7 +683,7 @@ public class ProviderHelper { // Canonicalize this keyring, to assert a number of assumptions made about it. canPublicRing = (CanonicalizedPublicKeyRing) publicRing.canonicalize(mLog, mIndent); if (canPublicRing == null) { - return new SaveKeyringResult(SaveKeyringResult.RESULT_ERROR, mLog); + return new SaveKeyringResult(SaveKeyringResult.RESULT_ERROR, mLog, null); } } @@ -696,12 +696,12 @@ public class ProviderHelper { // Merge data from new public ring into secret one secretRing = secretRing.merge(publicRing, mLog, mIndent); if (secretRing == null) { - return new SaveKeyringResult(SaveKeyringResult.RESULT_ERROR, mLog); + return new SaveKeyringResult(SaveKeyringResult.RESULT_ERROR, mLog, null); } // This has always been a secret key ring, this is a safe cast canSecretRing = (CanonicalizedSecretKeyRing) secretRing.canonicalize(mLog, mIndent); if (canSecretRing == null) { - return new SaveKeyringResult(SaveKeyringResult.RESULT_ERROR, mLog); + return new SaveKeyringResult(SaveKeyringResult.RESULT_ERROR, mLog, null); } } catch (NotFoundException e) { @@ -720,11 +720,11 @@ public class ProviderHelper { } } - return new SaveKeyringResult(result, mLog); + return new SaveKeyringResult(result, mLog, canSecretRing); } catch (IOException e) { log(LogLevel.ERROR, LogType.MSG_IP_FAIL_IO_EXC); - return new SaveKeyringResult(SaveKeyringResult.RESULT_ERROR, mLog); + return new SaveKeyringResult(SaveKeyringResult.RESULT_ERROR, mLog, null); } finally { mIndent -= 1; } @@ -740,7 +740,7 @@ public class ProviderHelper { if ( ! secretRing.isSecret()) { log(LogLevel.ERROR, LogType.MSG_IS_BAD_TYPE_PUBLIC); - return new SaveKeyringResult(SaveKeyringResult.RESULT_ERROR, mLog); + return new SaveKeyringResult(SaveKeyringResult.RESULT_ERROR, mLog, null); } CanonicalizedSecretKeyRing canSecretRing; @@ -754,14 +754,14 @@ public class ProviderHelper { // If this is null, there is an error in the log so we can just return if (secretRing == null) { - return new SaveKeyringResult(SaveKeyringResult.RESULT_ERROR, mLog); + return new SaveKeyringResult(SaveKeyringResult.RESULT_ERROR, mLog, null); } // Canonicalize this keyring, to assert a number of assumptions made about it. // This is a safe cast, because we made sure this is a secret ring above canSecretRing = (CanonicalizedSecretKeyRing) secretRing.canonicalize(mLog, mIndent); if (canSecretRing == null) { - return new SaveKeyringResult(SaveKeyringResult.RESULT_ERROR, mLog); + return new SaveKeyringResult(SaveKeyringResult.RESULT_ERROR, mLog, null); } // Early breakout if nothing changed @@ -769,7 +769,7 @@ public class ProviderHelper { == Arrays.hashCode(oldSecretRing.getEncoded())) { log(LogLevel.OK, LogType.MSG_IS_SUCCESS_IDENTICAL, PgpKeyHelper.convertKeyIdToHex(masterKeyId) ); - return new SaveKeyringResult(SaveKeyringResult.UPDATED, mLog); + return new SaveKeyringResult(SaveKeyringResult.UPDATED, mLog, null); } } catch (NotFoundException e) { // Not an issue, just means we are dealing with a new keyring @@ -778,7 +778,7 @@ public class ProviderHelper { // This is a safe cast, because we made sure this is a secret ring above canSecretRing = (CanonicalizedSecretKeyRing) secretRing.canonicalize(mLog, mIndent); if (canSecretRing == null) { - return new SaveKeyringResult(SaveKeyringResult.RESULT_ERROR, mLog); + return new SaveKeyringResult(SaveKeyringResult.RESULT_ERROR, mLog, null); } } @@ -791,7 +791,7 @@ public class ProviderHelper { // Merge data from new secret ring into public one publicRing = oldPublicRing.merge(secretRing, mLog, mIndent); if (publicRing == null) { - return new SaveKeyringResult(SaveKeyringResult.RESULT_ERROR, mLog); + return new SaveKeyringResult(SaveKeyringResult.RESULT_ERROR, mLog, null); } } catch (NotFoundException e) { @@ -801,24 +801,24 @@ public class ProviderHelper { CanonicalizedPublicKeyRing canPublicRing = (CanonicalizedPublicKeyRing) publicRing.canonicalize(mLog, mIndent); if (canPublicRing == null) { - return new SaveKeyringResult(SaveKeyringResult.RESULT_ERROR, mLog); + return new SaveKeyringResult(SaveKeyringResult.RESULT_ERROR, mLog, null); } int result; result = saveCanonicalizedPublicKeyRing(canPublicRing, progress, true); if ((result & SaveKeyringResult.RESULT_ERROR) == SaveKeyringResult.RESULT_ERROR) { - return new SaveKeyringResult(SaveKeyringResult.RESULT_ERROR, mLog); + return new SaveKeyringResult(SaveKeyringResult.RESULT_ERROR, mLog, null); } progress.setProgress(LogType.MSG_IP_REINSERT_SECRET.getMsgId(), 90, 100); result = saveCanonicalizedSecretKeyRing(canSecretRing); - return new SaveKeyringResult(result, mLog); + return new SaveKeyringResult(result, mLog, canSecretRing); } catch (IOException e) { log(LogLevel.ERROR, LogType.MSG_IS_FAIL_IO_EXC); - return new SaveKeyringResult(SaveKeyringResult.RESULT_ERROR, mLog); + return new SaveKeyringResult(SaveKeyringResult.RESULT_ERROR, mLog, null); } finally { mIndent -= 1; } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/OperationResults.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/OperationResults.java index 543b83edb..d58392d77 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/OperationResults.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/OperationResults.java @@ -29,6 +29,8 @@ import com.github.johnpersano.supertoasts.util.OnClickWrapper; import com.github.johnpersano.supertoasts.util.Style; import org.sufficientlysecure.keychain.R; +import org.sufficientlysecure.keychain.pgp.CanonicalizedKeyRing; +import org.sufficientlysecure.keychain.pgp.KeyRing; import org.sufficientlysecure.keychain.pgp.UncachedKeyRing; import org.sufficientlysecure.keychain.ui.LogDisplayActivity; import org.sufficientlysecure.keychain.ui.LogDisplayFragment; @@ -49,18 +51,21 @@ public abstract class OperationResults { public static final int RESULT_WITH_WARNINGS = 16; // No keys to import... - public static final int RESULT_FAIL_NOTHING = 32 +1; + public static final int RESULT_FAIL_NOTHING = 32 + 1; public boolean isOkBoth() { return (mResult & (RESULT_OK_NEWKEYS | RESULT_OK_UPDATED)) == (RESULT_OK_NEWKEYS | RESULT_OK_UPDATED); } + public boolean isOkNew() { return (mResult & RESULT_OK_NEWKEYS) == RESULT_OK_NEWKEYS; } + public boolean isOkUpdated() { return (mResult & RESULT_OK_UPDATED) == RESULT_OK_UPDATED; } + public boolean isFailNothing() { return (mResult & RESULT_FAIL_NOTHING) == RESULT_FAIL_NOTHING; } @@ -124,7 +129,7 @@ public abstract class OperationResults { if (this.isOkBoth()) { str = activity.getResources().getQuantityString( R.plurals.import_keys_added_and_updated_1, mNewKeys, mNewKeys); - str += " "+ activity.getResources().getQuantityString( + str += " " + activity.getResources().getQuantityString( R.plurals.import_keys_added_and_updated_2, mUpdatedKeys, mUpdatedKeys, withWarnings); } else if (isOkUpdated()) { str = activity.getResources().getQuantityString( @@ -188,7 +193,7 @@ public abstract class OperationResults { public final Long mRingMasterKeyId; public EditKeyResult(int result, OperationLog log, - UncachedKeyRing ring) { + UncachedKeyRing ring) { super(result, log); mRing = ring; mRingMasterKeyId = ring != null ? ring.getMasterKeyId() : null; @@ -224,8 +229,12 @@ public abstract class OperationResults { public static class SaveKeyringResult extends OperationResultParcel { - public SaveKeyringResult(int result, OperationLog log) { + public final Long mRingMasterKeyId; + + public SaveKeyringResult(int result, OperationLog log, + CanonicalizedKeyRing ring) { super(result, log); + mRingMasterKeyId = ring != null ? ring.getMasterKeyId() : null; } // Some old key was updated @@ -240,6 +249,26 @@ public abstract class OperationResults { return (mResult & UPDATED) == UPDATED; } + public SaveKeyringResult(Parcel source) { + super(source); + mRingMasterKeyId = source.readLong(); + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + super.writeToParcel(dest, flags); + dest.writeLong(mRingMasterKeyId); + } + + public static Creator CREATOR = new Creator() { + public SaveKeyringResult createFromParcel(final Parcel source) { + return new SaveKeyringResult(source); + } + + public SaveKeyringResult[] newArray(final int size) { + return new SaveKeyringResult[size]; + } + }; } } 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 773be816a..3fc9e7f31 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyFinalFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyFinalFragment.java @@ -140,7 +140,7 @@ public class CreateKeyFinalFragment extends Fragment { if (returnData == null) { return; } - final OperationResults.EditKeyResult result = + final OperationResults.SaveKeyringResult result = returnData.getParcelable(OperationResultParcel.EXTRA_RESULT); if (result == null) { return; @@ -191,7 +191,7 @@ public class CreateKeyFinalFragment extends Fragment { getActivity().startService(intent); } - private void uploadKey(final OperationResults.EditKeyResult editKeyResult) { + private void uploadKey(final OperationResults.SaveKeyringResult editKeyResult) { // Send all information needed to service to upload key in other thread final Intent intent = new Intent(getActivity(), KeychainIntentService.class); -- cgit v1.2.3 From bc76941bc1e47bc3919f58e29436f8d2a77f3258 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Thu, 14 Aug 2014 19:30:59 +0200 Subject: Fix sticky list headers lib, fix travis --- extern/StickyListHeaders | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extern/StickyListHeaders b/extern/StickyListHeaders index 67e757703..911f8ddfd 160000 --- a/extern/StickyListHeaders +++ b/extern/StickyListHeaders @@ -1 +1 @@ -Subproject commit 67e7577033e488701e7d03767d13656735015e4b +Subproject commit 911f8ddfd007ce65aededae7e7b79e5a8d903a43 -- cgit v1.2.3 From 09d37a5fa6b431bd7be91aca9a7bbae5af928453 Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Thu, 14 Aug 2014 22:12:07 +0200 Subject: fix keys with no expiry in ui code --- .../sufficientlysecure/keychain/service/OperationResults.java | 9 +++++++-- .../sufficientlysecure/keychain/ui/adapter/SubkeysAdapter.java | 2 +- .../keychain/ui/dialog/EditSubkeyExpiryDialogFragment.java | 2 +- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/OperationResults.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/OperationResults.java index d58392d77..1c83873be 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/OperationResults.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/OperationResults.java @@ -205,13 +205,18 @@ public abstract class OperationResults { public EditKeyResult(Parcel source) { super(source); - mRingMasterKeyId = source.readLong(); + mRingMasterKeyId = source.readInt() != 0 ? source.readLong() : null; } @Override public void writeToParcel(Parcel dest, int flags) { super.writeToParcel(dest, flags); - dest.writeLong(mRingMasterKeyId); + if (mRingMasterKeyId == null) { + dest.writeInt(0); + } else { + dest.writeInt(1); + dest.writeLong(mRingMasterKeyId); + } } public static Creator CREATOR = new Creator() { 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 d457e75bd..6df84a056 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 @@ -183,7 +183,7 @@ public class SubkeysAdapter extends CursorAdapter { SaveKeyringParcel.SubkeyChange subkeyChange = mSaveKeyringParcel.getSubkeyChange(keyId); if (subkeyChange != null) { - if (subkeyChange.mExpiry == null) { + if (subkeyChange.mExpiry == null || subkeyChange.mExpiry == 0L) { expiryDate = null; } else { expiryDate = new Date(subkeyChange.mExpiry * 1000); 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 aa63f9944..276ad15fc 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 @@ -141,7 +141,7 @@ public class EditSubkeyExpiryDialogFragment extends DialogFragment { dismiss(); Bundle data = new Bundle(); - data.putSerializable(MESSAGE_DATA_EXPIRY_DATE, null); + data.putSerializable(MESSAGE_DATA_EXPIRY_DATE, 0L); sendMessageToHandler(MESSAGE_NEW_EXPIRY_DATE, data); } }); -- cgit v1.2.3 From cf450d24fbcbbd9bc56959e387bd52141004bde1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Fri, 15 Aug 2014 10:19:46 +0200 Subject: Remove subkeys.pgp.net keyserver, often down and no hkps --- .../org/sufficientlysecure/keychain/Constants.java | 2 +- .../keychain/helper/Preferences.java | 27 ++++++++++++++++------ 2 files changed, 21 insertions(+), 8 deletions(-) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/Constants.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/Constants.java index 755d74ac2..7cfc11bc6 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/Constants.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/Constants.java @@ -72,7 +72,7 @@ public final class Constants { public static final class Defaults { public static final String KEY_SERVERS = "hkps://hkps.pool.sks-keyservers.net, subkeys.pgp.net, hkps://pgp.mit.edu"; - public static final int KEY_SERVERS_VERSION = 2; + public static final int KEY_SERVERS_VERSION = 3; } public static final class DrawerItems { diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/helper/Preferences.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/helper/Preferences.java index 80b047530..14ae46840 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/helper/Preferences.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/helper/Preferences.java @@ -26,6 +26,10 @@ import org.spongycastle.bcpg.HashAlgorithmTags; import org.spongycastle.openpgp.PGPEncryptedData; import org.sufficientlysecure.keychain.Constants; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Iterator; +import java.util.ListIterator; import java.util.Vector; /** @@ -175,15 +179,24 @@ public class Preferences { // migrate keyserver to hkps if (mSharedPreferences.getInt(Constants.Pref.KEY_SERVERS_DEFAULT_VERSION, 0) != Constants.Defaults.KEY_SERVERS_VERSION) { - String[] servers = getKeyServers(); - for (int i = 0; i < servers.length; i++) { - if (servers[i].equals("pool.sks-keyservers.net")) { - servers[i] = "hkps://hkps.pool.sks-keyservers.net"; - } else if (servers[i].equals("pgp.mit.edu")) { - servers[i] = "hkps://pgp.mit.edu"; + String[] serversArray = getKeyServers(); + ArrayList servers = new ArrayList(Arrays.asList(serversArray)); + ListIterator it = servers.listIterator(); + while (it.hasNext()) { + String server = it.next(); + if (server.equals("pool.sks-keyservers.net")) { + // use HKPS! + it.set("hkps://hkps.pool.sks-keyservers.net"); + } else if (server.equals("pgp.mit.edu")) { + // use HKPS! + it.set("hkps://pgp.mit.edu"); + } else if (server.equals("subkeys.pgp.net")) { + // remove, because often down and no HKPS! + it.remove(); } + } - setKeyServers(servers); + setKeyServers(servers.toArray(new String[servers.size()])); mSharedPreferences.edit() .putInt(Constants.Pref.KEY_SERVERS_DEFAULT_VERSION, Constants.Defaults.KEY_SERVERS_VERSION) .commit(); -- cgit v1.2.3 From b1fa5d992268642adf8e860812027aa0a24f3617 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Fri, 15 Aug 2014 11:00:45 +0200 Subject: Remove subkeys.pgp.net keyserver from defaults --- .../src/main/java/org/sufficientlysecure/keychain/Constants.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/Constants.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/Constants.java index 7cfc11bc6..bce093427 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/Constants.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/Constants.java @@ -71,7 +71,7 @@ public final class Constants { } public static final class Defaults { - public static final String KEY_SERVERS = "hkps://hkps.pool.sks-keyservers.net, subkeys.pgp.net, hkps://pgp.mit.edu"; + public static final String KEY_SERVERS = "hkps://hkps.pool.sks-keyservers.net, hkps://pgp.mit.edu"; public static final int KEY_SERVERS_VERSION = 3; } -- cgit v1.2.3 From b1dc6639300c7ecafea2ac8f26d624e0275aa780 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Fri, 15 Aug 2014 11:07:21 +0200 Subject: Remove old_apg --- .../sufficientlysecure/keychain/provider/KeychainDatabase.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainDatabase.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainDatabase.java index a90c88c3e..1536c21fc 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainDatabase.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainDatabase.java @@ -227,7 +227,8 @@ public class KeychainDatabase extends SQLiteOpenHelper { if (db.equals("apg.db")) { hasApgDb = true; } else if (db.equals("apg_old.db")) { - Log.d(Constants.TAG, "Found apg_old.db"); + Log.d(Constants.TAG, "Found apg_old.db, delete it!"); + context.getDatabasePath("apg_old.db").delete(); } } } @@ -310,9 +311,8 @@ public class KeychainDatabase extends SQLiteOpenHelper { } } - // Move to a different file (but don't delete, just to be safe) - Log.d(Constants.TAG, "All done - moving apg.db to apg_old.db"); - context.getDatabasePath("apg.db").renameTo(context.getDatabasePath("apg_old.db")); + // delete old database + context.getDatabasePath("apg.db").delete(); } private static void copy(File in, File out) throws IOException { -- cgit v1.2.3 From 8d60d9f1031c7a2ad4d1484291497c1dff197e12 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Sat, 16 Aug 2014 03:59:58 +0200 Subject: Fix encrypt only --- .../keychain/pgp/PgpSignEncrypt.java | 20 ++++++------- .../keychain/remote/OpenPgpService.java | 11 ++----- .../keychain/service/KeychainIntentService.java | 34 ++++++++++++---------- .../keychain/service/PassphraseCacheService.java | 6 ++-- 4 files changed, 34 insertions(+), 37 deletions(-) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncrypt.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncrypt.java index 263b0c5bb..1784ae063 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncrypt.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncrypt.java @@ -68,7 +68,7 @@ public class PgpSignEncrypt { private long mSignatureMasterKeyId; private int mSignatureHashAlgorithm; private String mSignaturePassphrase; - private boolean mEncryptToSigner; + private long mAdditionalEncryptId; private boolean mCleartextInput; private String mOriginalFilename; @@ -98,7 +98,7 @@ public class PgpSignEncrypt { this.mSignatureMasterKeyId = builder.mSignatureMasterKeyId; this.mSignatureHashAlgorithm = builder.mSignatureHashAlgorithm; this.mSignaturePassphrase = builder.mSignaturePassphrase; - this.mEncryptToSigner = builder.mEncryptToSigner; + this.mAdditionalEncryptId = builder.mAdditionalEncryptId; this.mCleartextInput = builder.mCleartextInput; this.mOriginalFilename = builder.mOriginalFilename; } @@ -120,7 +120,7 @@ public class PgpSignEncrypt { private long mSignatureMasterKeyId = Constants.key.none; private int mSignatureHashAlgorithm = 0; private String mSignaturePassphrase = null; - private boolean mEncryptToSigner = false; + private long mAdditionalEncryptId = Constants.key.none; private boolean mCleartextInput = false; private String mOriginalFilename = ""; @@ -166,7 +166,7 @@ public class PgpSignEncrypt { } public Builder setSignatureMasterKeyId(long signatureMasterKeyId) { - this.mSignatureMasterKeyId = signatureMasterKeyId; + mSignatureMasterKeyId = signatureMasterKeyId; return this; } @@ -183,11 +183,11 @@ public class PgpSignEncrypt { /** * Also encrypt with the signing keyring * - * @param encryptToSigner + * @param additionalEncryptId * @return */ - public Builder setEncryptToSigner(boolean encryptToSigner) { - mEncryptToSigner = encryptToSigner; + public Builder setAdditionalEncryptId(long additionalEncryptId) { + mAdditionalEncryptId = additionalEncryptId; return this; } @@ -256,10 +256,10 @@ public class PgpSignEncrypt { + "\nenableCompression:" + enableCompression + "\nenableAsciiArmorOutput:" + mEnableAsciiArmorOutput); - // add signature key id to encryption ids (self-encrypt) - if (enableEncryption && enableSignature && mEncryptToSigner) { + // add additional key id to encryption ids (mostly to do self-encryption) + if (enableEncryption && mAdditionalEncryptId != Constants.key.none) { mEncryptionMasterKeyIds = Arrays.copyOf(mEncryptionMasterKeyIds, mEncryptionMasterKeyIds.length + 1); - mEncryptionMasterKeyIds[mEncryptionMasterKeyIds.length - 1] = mSignatureMasterKeyId; + mEncryptionMasterKeyIds[mEncryptionMasterKeyIds.length - 1] = mAdditionalEncryptId; } ArmoredOutputStream armorOut = null; 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 3541dad98..93cc08081 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java @@ -29,7 +29,6 @@ import org.openintents.openpgp.OpenPgpMetadata; import org.openintents.openpgp.OpenPgpError; import org.openintents.openpgp.OpenPgpSignatureResult; import org.openintents.openpgp.util.OpenPgpApi; -import org.spongycastle.util.Arrays; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.pgp.PgpDecryptVerify; @@ -261,10 +260,6 @@ public class OpenPgpService extends RemoteService { return result; } - // add own key for encryption - keyIds = Arrays.copyOf(keyIds, keyIds.length + 1); - keyIds[keyIds.length - 1] = accSettings.getKeyId(); - // build InputData and write into OutputStream // Get Input- and OutputStream from ParcelFileDescriptor InputStream is = new ParcelFileDescriptor.AutoCloseInputStream(input); @@ -281,7 +276,8 @@ public class OpenPgpService extends RemoteService { .setCompressionId(accSettings.getCompression()) .setSymmetricEncryptionAlgorithm(accSettings.getEncryptionAlgorithm()) .setEncryptionMasterKeyIds(keyIds) - .setOriginalFilename(originalFilename); + .setOriginalFilename(originalFilename) + .setAdditionalEncryptId(accSettings.getKeyId()); // add acc key for encryption if (sign) { String passphrase; @@ -300,9 +296,6 @@ public class OpenPgpService extends RemoteService { builder.setSignatureHashAlgorithm(accSettings.getHashAlgorithm()) .setSignatureMasterKeyId(accSettings.getKeyId()) .setSignaturePassphrase(passphrase); - } else { - // encrypt only - builder.setSignatureMasterKeyId(Constants.key.none); } try { diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java index 0fdc62633..83ade9b9b 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java @@ -247,27 +247,31 @@ public class KeychainIntentService extends IntentService String originalFilename = getOriginalFilename(data); /* Operation */ - PgpSignEncrypt.Builder builder = - new PgpSignEncrypt.Builder( - new ProviderHelper(this), - inputData, outStream); - builder.setProgressable(this); - - builder.setEnableAsciiArmorOutput(useAsciiArmor) + PgpSignEncrypt.Builder builder = new PgpSignEncrypt.Builder( + new ProviderHelper(this), + inputData, outStream + ); + builder.setProgressable(this) + .setEnableAsciiArmorOutput(useAsciiArmor) .setVersionHeader(PgpHelper.getVersionForHeader(this)) .setCompressionId(compressionId) .setSymmetricEncryptionAlgorithm( Preferences.getPreferences(this).getDefaultEncryptionAlgorithm()) .setEncryptionMasterKeyIds(encryptionKeyIds) .setSymmetricPassphrase(symmetricPassphrase) - .setSignatureMasterKeyId(signatureKeyId) - .setEncryptToSigner(true) - .setSignatureHashAlgorithm( - Preferences.getPreferences(this).getDefaultHashAlgorithm()) - .setSignaturePassphrase( - PassphraseCacheService.getCachedPassphrase(this, signatureKeyId)) .setOriginalFilename(originalFilename); + try { + builder.setSignatureMasterKeyId(signatureKeyId) + .setSignaturePassphrase( + PassphraseCacheService.getCachedPassphrase(this, signatureKeyId)) + .setSignatureHashAlgorithm( + Preferences.getPreferences(this).getDefaultHashAlgorithm()) + .setAdditionalEncryptId(signatureKeyId); + } catch (PassphraseCacheService.KeyNotFoundException e) { + // encrypt-only + } + // this assumes that the bytes are cleartext (valid for current implementation!) if (source == IO_BYTES) { builder.setCleartextInput(true); @@ -406,7 +410,7 @@ public class KeychainIntentService extends IntentService } // If the edit operation didn't succeed, exit here - if ( ! modifyResult.success()) { + if (!modifyResult.success()) { sendMessageToHandler(KeychainIntentServiceHandler.MESSAGE_OKAY, modifyResult); return; } @@ -418,7 +422,7 @@ public class KeychainIntentService extends IntentService .saveSecretKeyRing(ring, new ProgressScaler(this, 60, 95, 100)); // If the edit operation didn't succeed, exit here - if ( ! saveResult.success()) { + if (!saveResult.success()) { sendMessageToHandler(KeychainIntentServiceHandler.MESSAGE_OKAY, saveResult); return; } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/PassphraseCacheService.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/PassphraseCacheService.java index ae1b026a5..3707fdebf 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/PassphraseCacheService.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/PassphraseCacheService.java @@ -77,7 +77,7 @@ public class PassphraseCacheService extends Service { private static final int NOTIFICATION_ID = 1; private static final int MSG_PASSPHRASE_CACHE_GET_OKAY = 1; - private static final int MSG_PASSPHRASE_CACHE_GET_KEY_NO_FOUND = 2; + private static final int MSG_PASSPHRASE_CACHE_GET_KEY_NOT_FOUND = 2; private BroadcastReceiver mIntentReceiver; @@ -169,7 +169,7 @@ public class PassphraseCacheService extends Service { switch (returnMessage.what) { case MSG_PASSPHRASE_CACHE_GET_OKAY: return returnMessage.getData().getString(EXTRA_PASSPHRASE); - case MSG_PASSPHRASE_CACHE_GET_KEY_NO_FOUND: + case MSG_PASSPHRASE_CACHE_GET_KEY_NOT_FOUND: throw new KeyNotFoundException(); default: throw new KeyNotFoundException("should not happen!"); @@ -313,7 +313,7 @@ public class PassphraseCacheService extends Service { msg.setData(bundle); } catch (ProviderHelper.NotFoundException e) { Log.e(Constants.TAG, "PassphraseCacheService: Passphrase for unknown key was requested!"); - msg.what = MSG_PASSPHRASE_CACHE_GET_KEY_NO_FOUND; + msg.what = MSG_PASSPHRASE_CACHE_GET_KEY_NOT_FOUND; } try { -- cgit v1.2.3 From 443170b876751739df7249f0c497fdec6f6f892f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Sat, 16 Aug 2014 04:11:39 +0200 Subject: do not pre-select revoked or expired keys --- .../keychain/remote/OpenPgpService.java | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) 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 93cc08081..93c71f5d0 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java @@ -36,6 +36,7 @@ import org.sufficientlysecure.keychain.pgp.PgpDecryptVerifyResult; import org.sufficientlysecure.keychain.pgp.PgpHelper; import org.sufficientlysecure.keychain.pgp.PgpSignEncrypt; import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException; +import org.sufficientlysecure.keychain.provider.KeychainContract; import org.sufficientlysecure.keychain.provider.KeychainContract.ApiAccounts; import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings; import org.sufficientlysecure.keychain.provider.ProviderHelper; @@ -53,11 +54,16 @@ import java.util.Set; public class OpenPgpService extends RemoteService { - static final String[] KEYRING_PROJECTION = - new String[]{ - KeyRings._ID, - KeyRings.MASTER_KEY_ID, - }; + static final String[] EMAIL_SEARCH_PROJECTION = new String[]{ + KeyRings._ID, + KeyRings.MASTER_KEY_ID, + KeyRings.IS_EXPIRED, + KeyRings.IS_REVOKED, + }; + + // do not pre-select revoked or expired keys + static final String EMAIL_SEARCH_WHERE = KeychainContract.KeyRings.IS_REVOKED + " = 0 AND " + + KeychainContract.KeyRings.IS_EXPIRED + " = 0"; /** * Search database for key ids based on emails. @@ -76,7 +82,7 @@ public class OpenPgpService extends RemoteService { for (String email : encryptionUserIds) { Uri uri = KeyRings.buildUnifiedKeyRingsFindByEmailUri(email); - Cursor cursor = getContentResolver().query(uri, KEYRING_PROJECTION, null, null, null); + Cursor cursor = getContentResolver().query(uri, EMAIL_SEARCH_PROJECTION, EMAIL_SEARCH_WHERE, null, null); try { if (cursor != null && cursor.moveToFirst()) { long id = cursor.getLong(cursor.getColumnIndex(KeyRings.MASTER_KEY_ID)); -- cgit v1.2.3 From bbe986743c9e6c2a22df95e0fbde0de2340bf467 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Sat, 16 Aug 2014 05:28:51 +0200 Subject: API: Allow ACTION_SIGN_AND_ENCRYPT with no key ids or user ids extras, fix pre-selection of key ids (no revoked or expired ones, also select duplicates), refactor text using spannables --- .../keychain/remote/OpenPgpService.java | 100 +++++++++++---------- .../keychain/remote/ui/RemoteServiceActivity.java | 56 ++++++++---- .../main/res/layout/api_remote_select_pub_keys.xml | 10 +-- OpenKeychain/src/main/res/values/strings.xml | 5 +- 4 files changed, 96 insertions(+), 75 deletions(-) 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 93c71f5d0..e2d809d9e 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java @@ -72,52 +72,61 @@ public class OpenPgpService extends RemoteService { * @return */ private Intent getKeyIdsFromEmails(Intent data, String[] encryptionUserIds) { - // find key ids to given emails in database - ArrayList keyIds = new ArrayList(); - + boolean noUserIdsCheck = (encryptionUserIds == null || encryptionUserIds.length == 0); boolean missingUserIdsCheck = false; boolean duplicateUserIdsCheck = false; + + ArrayList keyIds = new ArrayList(); ArrayList missingUserIds = new ArrayList(); ArrayList duplicateUserIds = new ArrayList(); - - for (String email : encryptionUserIds) { - Uri uri = KeyRings.buildUnifiedKeyRingsFindByEmailUri(email); - Cursor cursor = getContentResolver().query(uri, EMAIL_SEARCH_PROJECTION, EMAIL_SEARCH_WHERE, null, null); - try { - if (cursor != null && cursor.moveToFirst()) { - long id = cursor.getLong(cursor.getColumnIndex(KeyRings.MASTER_KEY_ID)); - keyIds.add(id); - } else { - missingUserIdsCheck = true; - missingUserIds.add(email); - Log.d(Constants.TAG, "user id missing"); - } - if (cursor != null && cursor.moveToNext()) { - duplicateUserIdsCheck = true; - duplicateUserIds.add(email); - Log.d(Constants.TAG, "more than one user id with the same email"); - } - } finally { - if (cursor != null) { - cursor.close(); + if (!noUserIdsCheck) { + for (String email : encryptionUserIds) { + // try to find the key for this specific email + Uri uri = KeyRings.buildUnifiedKeyRingsFindByEmailUri(email); + Cursor cursor = getContentResolver().query(uri, EMAIL_SEARCH_PROJECTION, EMAIL_SEARCH_WHERE, null, null); + try { + // result should be one entry containing the key id + if (cursor != null && cursor.moveToFirst()) { + long id = cursor.getLong(cursor.getColumnIndex(KeyRings.MASTER_KEY_ID)); + keyIds.add(id); + } else { + missingUserIdsCheck = true; + missingUserIds.add(email); + Log.d(Constants.TAG, "user id missing"); + } + // another entry for this email -> too keys with the same email inside user id + if (cursor != null && cursor.moveToNext()) { + duplicateUserIdsCheck = true; + duplicateUserIds.add(email); + + // also pre-select + long id = cursor.getLong(cursor.getColumnIndex(KeyRings.MASTER_KEY_ID)); + keyIds.add(id); + Log.d(Constants.TAG, "more than one user id with the same email"); + } + } finally { + if (cursor != null) { + cursor.close(); + } } } } - // convert to long[] + // convert ArrayList to long[] long[] keyIdsArray = new long[keyIds.size()]; for (int i = 0; i < keyIdsArray.length; i++) { keyIdsArray[i] = keyIds.get(i); } - // allow the user to verify pub key selection - if (missingUserIdsCheck || duplicateUserIdsCheck) { - // build PendingIntent + if (noUserIdsCheck || missingUserIdsCheck || duplicateUserIdsCheck) { + // allow the user to verify pub key selection + Intent intent = new Intent(getBaseContext(), RemoteServiceActivity.class); intent.setAction(RemoteServiceActivity.ACTION_SELECT_PUB_KEYS); intent.putExtra(RemoteServiceActivity.EXTRA_SELECTED_MASTER_KEY_IDS, keyIdsArray); + intent.putExtra(RemoteServiceActivity.EXTRA_NO_USER_IDS_CHECK, noUserIdsCheck); intent.putExtra(RemoteServiceActivity.EXTRA_MISSING_USER_IDS, missingUserIds); - intent.putExtra(RemoteServiceActivity.EXTRA_DUBLICATE_USER_IDS, duplicateUserIds); + intent.putExtra(RemoteServiceActivity.EXTRA_DUPLICATE_USER_IDS, duplicateUserIds); intent.putExtra(RemoteServiceActivity.EXTRA_DATA, data); PendingIntent pi = PendingIntent.getActivity(getBaseContext(), 0, @@ -129,16 +138,18 @@ public class OpenPgpService extends RemoteService { result.putExtra(OpenPgpApi.RESULT_INTENT, pi); result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_USER_INTERACTION_REQUIRED); return result; - } + } else { + // everything was easy, we have exactly one key for every email - if (keyIdsArray.length == 0) { - return null; - } + if (keyIdsArray.length == 0) { + Log.e(Constants.TAG, "keyIdsArray.length == 0, should never happen!"); + } - Intent result = new Intent(); - result.putExtra(OpenPgpApi.RESULT_KEY_IDS, keyIdsArray); - result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_SUCCESS); - return result; + Intent result = new Intent(); + result.putExtra(OpenPgpApi.RESULT_KEY_IDS, keyIdsArray); + result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_SUCCESS); + return result; + } } private Intent getPassphraseBundleIntent(Intent data, long keyId) { @@ -241,10 +252,9 @@ public class OpenPgpService extends RemoteService { originalFilename = ""; } - long[] keyIds; - if (data.hasExtra(OpenPgpApi.EXTRA_KEY_IDS)) { - keyIds = data.getLongArrayExtra(OpenPgpApi.EXTRA_KEY_IDS); - } else if (data.hasExtra(OpenPgpApi.EXTRA_USER_IDS)) { + // first try to get key ids from non-ambiguous key id extra + long[] keyIds = data.getLongArrayExtra(OpenPgpApi.EXTRA_KEY_IDS); + if (keyIds == null) { // get key ids based on given user ids String[] userIds = data.getStringArrayExtra(OpenPgpApi.EXTRA_USER_IDS); // give params through to activity... @@ -256,14 +266,6 @@ public class OpenPgpService extends RemoteService { // if not success -> result contains a PendingIntent for user interaction return result; } - } else { - Intent result = new Intent(); - result.putExtra(OpenPgpApi.RESULT_ERROR, - new OpenPgpError(OpenPgpError.GENERIC_ERROR, - "Missing parameter user_ids or key_ids!") - ); - result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_ERROR); - return result; } // build InputData and write into OutputStream diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/RemoteServiceActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/RemoteServiceActivity.java index 48c76d561..4b27e115b 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/RemoteServiceActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/RemoteServiceActivity.java @@ -18,11 +18,20 @@ package org.sufficientlysecure.keychain.remote.ui; import android.content.Intent; +import android.graphics.Color; +import android.graphics.Typeface; import android.net.Uri; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.support.v7.app.ActionBarActivity; +import android.text.Spannable; +import android.text.SpannableString; +import android.text.SpannableStringBuilder; +import android.text.SpannedString; +import android.text.TextUtils; +import android.text.style.BulletSpan; +import android.text.style.StyleSpan; import android.view.View; import android.widget.TextView; @@ -39,7 +48,6 @@ import org.sufficientlysecure.keychain.ui.SelectPublicKeyFragment; import org.sufficientlysecure.keychain.ui.dialog.PassphraseDialogFragment; import org.sufficientlysecure.keychain.util.Log; -import java.security.Provider; import java.util.ArrayList; public class RemoteServiceActivity extends ActionBarActivity { @@ -68,7 +76,8 @@ public class RemoteServiceActivity extends ActionBarActivity { // select pub keys action public static final String EXTRA_SELECTED_MASTER_KEY_IDS = "master_key_ids"; public static final String EXTRA_MISSING_USER_IDS = "missing_user_ids"; - public static final String EXTRA_DUBLICATE_USER_IDS = "dublicate_user_ids"; + public static final String EXTRA_DUPLICATE_USER_IDS = "dublicate_user_ids"; + public static final String EXTRA_NO_USER_IDS_CHECK = "no_user_ids"; // error message public static final String EXTRA_ERROR_MESSAGE = "error_message"; @@ -229,32 +238,41 @@ public class RemoteServiceActivity extends ActionBarActivity { } else if (ACTION_SELECT_PUB_KEYS.equals(action)) { long[] selectedMasterKeyIds = intent.getLongArrayExtra(EXTRA_SELECTED_MASTER_KEY_IDS); + boolean noUserIdsCheck = intent.getBooleanExtra(EXTRA_NO_USER_IDS_CHECK, true); ArrayList missingUserIds = intent .getStringArrayListExtra(EXTRA_MISSING_USER_IDS); ArrayList dublicateUserIds = intent - .getStringArrayListExtra(EXTRA_DUBLICATE_USER_IDS); + .getStringArrayListExtra(EXTRA_DUPLICATE_USER_IDS); + + SpannableStringBuilder ssb = new SpannableStringBuilder(); + final SpannableString textIntro = new SpannableString( + noUserIdsCheck ? getString(R.string.api_select_pub_keys_text_no_user_ids) + : getString(R.string.api_select_pub_keys_text) + ); + textIntro.setSpan(new StyleSpan(Typeface.BOLD), 0, textIntro.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); + ssb.append(textIntro); - // TODO: do this with spannable instead of HTML to prevent parsing failures with weird user ids - String text = "" + getString(R.string.api_select_pub_keys_text) + ""; - text += "

"; if (missingUserIds != null && missingUserIds.size() > 0) { - text += getString(R.string.api_select_pub_keys_missing_text); - text += "
"; - text += "
    "; + ssb.append("\n\n"); + ssb.append(getString(R.string.api_select_pub_keys_missing_text)); + ssb.append("\n"); for (String userId : missingUserIds) { - text += "
  • " + userId + "
  • "; + SpannableString ss = new SpannableString(userId + "\n"); + ss.setSpan(new BulletSpan(15, Color.BLACK), 0, ss.length(), + Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); + ssb.append(ss); } - text += "
"; - text += "
"; } if (dublicateUserIds != null && dublicateUserIds.size() > 0) { - text += getString(R.string.api_select_pub_keys_dublicates_text); - text += "
"; - text += "
    "; + ssb.append("\n\n"); + ssb.append(getString(R.string.api_select_pub_keys_dublicates_text)); + ssb.append("\n"); for (String userId : dublicateUserIds) { - text += "
  • " + userId + "
  • "; + SpannableString ss = new SpannableString(userId + "\n"); + ss.setSpan(new BulletSpan(15, Color.BLACK), 0, ss.length(), + Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); + ssb.append(ss); } - text += "
"; } // Inflate a "Done"/"Cancel" custom action bar view @@ -284,8 +302,8 @@ public class RemoteServiceActivity extends ActionBarActivity { setContentView(R.layout.api_remote_select_pub_keys); // set text on view - HtmlTextView textView = (HtmlTextView) findViewById(R.id.api_select_pub_keys_text); - textView.setHtmlFromString(text, true); + TextView textView = (TextView) findViewById(R.id.api_select_pub_keys_text); + textView.setText(ssb, TextView.BufferType.SPANNABLE); /* Load select pub keys fragment */ // Check that the activity is using the layout version with diff --git a/OpenKeychain/src/main/res/layout/api_remote_select_pub_keys.xml b/OpenKeychain/src/main/res/layout/api_remote_select_pub_keys.xml index a10592607..bf4d0a70d 100644 --- a/OpenKeychain/src/main/res/layout/api_remote_select_pub_keys.xml +++ b/OpenKeychain/src/main/res/layout/api_remote_select_pub_keys.xml @@ -4,13 +4,13 @@ android:layout_height="fill_parent" android:orientation="vertical" > - Allow access
Disallow access Please select a key! - No public keys were found for these identities: - More than one public key exist for these identities: + No keys were found for these identities: + More than one key exist for these identities: Please review the list of recipients! + Please select the recipients! Signature check failed! Have you installed this app from a different source? If you are sure that this is not an attack, revoke this app\'s registration in OpenKeychain and then register the app again. -- cgit v1.2.3 From 0708b573fc7a058d08840b8ce256cb103a0eeafa Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Sat, 16 Aug 2014 03:48:13 +0200 Subject: test: even nicer code --- .../keychain/pgp/PgpKeyOperationTest.java | 45 ++++++++-------------- 1 file changed, 16 insertions(+), 29 deletions(-) diff --git a/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperationTest.java b/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperationTest.java index f37f11d87..91c95a873 100644 --- a/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperationTest.java +++ b/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperationTest.java @@ -237,10 +237,8 @@ public class PgpKeyOperationTest { parcel.mMasterKeyId = ring.getMasterKeyId() -1; parcel.mFingerprint = ring.getFingerprint(); - CanonicalizedSecretKeyRing secretRing = new CanonicalizedSecretKeyRing(ring.getEncoded(), false, 0); - assertModifyFailure("keyring modification with bad master key id should fail", - secretRing, parcel); + ring, parcel); } { @@ -249,10 +247,8 @@ public class PgpKeyOperationTest { parcel.mMasterKeyId = null; parcel.mFingerprint = ring.getFingerprint(); - CanonicalizedSecretKeyRing secretRing = new CanonicalizedSecretKeyRing(ring.getEncoded(), false, 0); - assertModifyFailure("keyring modification with null master key id should fail", - secretRing, parcel); + ring, parcel); } { @@ -262,10 +258,8 @@ public class PgpKeyOperationTest { // some byte, off by one parcel.mFingerprint[5] += 1; - CanonicalizedSecretKeyRing secretRing = new CanonicalizedSecretKeyRing(ring.getEncoded(), false, 0); - assertModifyFailure("keyring modification with bad fingerprint should fail", - secretRing, parcel); + ring, parcel); } { @@ -273,10 +267,8 @@ public class PgpKeyOperationTest { parcel.mMasterKeyId = ring.getMasterKeyId(); parcel.mFingerprint = null; - CanonicalizedSecretKeyRing secretRing = new CanonicalizedSecretKeyRing(ring.getEncoded(), false, 0); - assertModifyFailure("keyring modification with null fingerprint should fail", - secretRing, parcel); + ring, parcel); } { @@ -284,10 +276,9 @@ public class PgpKeyOperationTest { if (badphrase.equals(passphrase)) { badphrase = "a"; } - CanonicalizedSecretKeyRing secretRing = new CanonicalizedSecretKeyRing(ring.getEncoded(), false, 0); assertModifyFailure("keyring modification with bad passphrase should fail", - secretRing, parcel, badphrase); + ring, parcel, badphrase); } } @@ -340,9 +331,7 @@ public class PgpKeyOperationTest { parcel.reset(); parcel.mAddSubKeys.add(new SubkeyAdd( PublicKeyAlgorithmTags.RSA_GENERAL, new Random().nextInt(512), KeyFlags.SIGN_DATA, null)); - - CanonicalizedSecretKeyRing secretRing = new CanonicalizedSecretKeyRing(ring.getEncoded(), false, 0); - assertModifyFailure("creating a subkey with keysize < 512 should fail", secretRing, parcel); + assertModifyFailure("creating a subkey with keysize < 512 should fail", ring, parcel); } @@ -350,9 +339,7 @@ public class PgpKeyOperationTest { parcel.reset(); parcel.mAddSubKeys.add(new SubkeyAdd(PublicKeyAlgorithmTags.RSA_GENERAL, 1024, KeyFlags.SIGN_DATA, new Date().getTime()/1000-10)); - - CanonicalizedSecretKeyRing secretRing = new CanonicalizedSecretKeyRing(ring.getEncoded(), false, 0); - assertModifyFailure("creating subkey with past expiry date should fail", secretRing, parcel); + assertModifyFailure("creating subkey with past expiry date should fail", ring, parcel); } } @@ -564,8 +551,7 @@ public class PgpKeyOperationTest { parcel.reset(); parcel.mChangePrimaryUserId = uid; - CanonicalizedSecretKeyRing secretRing = new CanonicalizedSecretKeyRing(modified.getEncoded(), false, 0); - assertModifyFailure("setting primary user id to a revoked user id should fail", secretRing, parcel); + assertModifyFailure("setting primary user id to a revoked user id should fail", modified, parcel); } @@ -610,8 +596,7 @@ public class PgpKeyOperationTest { { parcel.mAddUserIds.add(""); - CanonicalizedSecretKeyRing secretRing = new CanonicalizedSecretKeyRing(ring.getEncoded(), false, 0); - assertModifyFailure("adding an empty user id should fail", secretRing, parcel); + assertModifyFailure("adding an empty user id should fail", ring, parcel); } parcel.reset(); @@ -679,9 +664,8 @@ public class PgpKeyOperationTest { parcel.mChangePrimaryUserId += "A"; } - CanonicalizedSecretKeyRing secretRing = new CanonicalizedSecretKeyRing(ring.getEncoded(), false, 0); assertModifyFailure("changing primary user id to a non-existent one should fail", - secretRing, parcel); + ring, parcel); } // check for revoked primary user id already done in revoke test @@ -774,9 +758,10 @@ public class PgpKeyOperationTest { } - private void assertModifyFailure(String reason, CanonicalizedSecretKeyRing secretRing, - SaveKeyringParcel parcel, String passphrase) { + private void assertModifyFailure(String reason, UncachedKeyRing ring, + SaveKeyringParcel parcel, String passphrase) throws Exception { + CanonicalizedSecretKeyRing secretRing = new CanonicalizedSecretKeyRing(ring.getEncoded(), false, 0); EditKeyResult result = op.modifySecretKeyRing(secretRing, parcel, passphrase); Assert.assertFalse(reason, result.success()); @@ -784,8 +769,10 @@ public class PgpKeyOperationTest { } - private void assertModifyFailure(String reason, CanonicalizedSecretKeyRing secretRing, SaveKeyringParcel parcel) { + private void assertModifyFailure(String reason, UncachedKeyRing ring, SaveKeyringParcel parcel) + throws Exception { + CanonicalizedSecretKeyRing secretRing = new CanonicalizedSecretKeyRing(ring.getEncoded(), false, 0); EditKeyResult result = op.modifySecretKeyRing(secretRing, parcel, passphrase); Assert.assertFalse(reason, result.success()); -- cgit v1.2.3 From c54fe21f44f118c59874fe97b662b3faea6ebc48 Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Sat, 16 Aug 2014 05:13:09 +0200 Subject: modifySecretKey: err out on revocation of nonexistent user id --- .../sufficientlysecure/keychain/pgp/PgpKeyOperationTest.java | 7 +++++++ .../org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java | 12 ++++++++++++ .../keychain/service/OperationResultParcel.java | 1 + OpenKeychain/src/main/res/values/strings.xml | 1 + 4 files changed, 21 insertions(+) diff --git a/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperationTest.java b/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperationTest.java index 91c95a873..9d4aa7dba 100644 --- a/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperationTest.java +++ b/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperationTest.java @@ -589,6 +589,13 @@ public class PgpKeyOperationTest { ring.getMasterKeyId(), ((SignaturePacket) p).getKeyID()); } + { // revocation of non-existent user id should fail + parcel.reset(); + parcel.mRevokeUserIds.add("nonexistent"); + + assertModifyFailure("revocation of nonexistent user id should fail", modified, parcel); + } + } @Test 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 fe84b3802..06d8dff69 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java @@ -403,6 +403,18 @@ public class PgpKeyOperation { progress(R.string.progress_modify_revokeuid, (i-1) * (100 / saveParcel.mRevokeUserIds.size())); String userId = saveParcel.mRevokeUserIds.get(i); log.add(LogLevel.INFO, LogType.MSG_MF_UID_REVOKE, indent, userId); + // Make sure the user id exists (yes these are 10 LoC in Java!) + boolean exists = false; + for (String uid : new IterableIterator(modifiedPublicKey.getUserIDs())) { + if (userId.equals(uid)) { + exists = true; + break; + } + } + if (!exists) { + log.add(LogLevel.ERROR, LogType.MSG_MF_ERROR_NOEXIST_REVOKE, indent); + return new EditKeyResult(EditKeyResult.RESULT_ERROR, log, null); + } // a duplicate revocation will be removed during canonicalization, so no need to // take care of that here. diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/OperationResultParcel.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/OperationResultParcel.java index 25dac2139..4c93e2a91 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/OperationResultParcel.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/OperationResultParcel.java @@ -359,6 +359,7 @@ public class OperationResultParcel implements Parcelable { MSG_MF_ERROR_KEYID (R.string.msg_mf_error_keyid), MSG_MF_ERROR_INTEGRITY (R.string.msg_mf_error_integrity), MSG_MF_ERROR_NOEXIST_PRIMARY (R.string.msg_mf_error_noexist_primary), + MSG_MF_ERROR_NOEXIST_REVOKE (R.string.msg_mf_error_noexist_revoke), MSG_MF_ERROR_REVOKED_PRIMARY (R.string.msg_mf_error_revoked_primary), MSG_MF_ERROR_PGP (R.string.msg_mf_error_pgp), MSG_MF_ERROR_SIG (R.string.msg_mf_error_sig), diff --git a/OpenKeychain/src/main/res/values/strings.xml b/OpenKeychain/src/main/res/values/strings.xml index 6f77be78f..5eb594163 100644 --- a/OpenKeychain/src/main/res/values/strings.xml +++ b/OpenKeychain/src/main/res/values/strings.xml @@ -639,6 +639,7 @@ No key ID. This is an internal error, please file a bug report! Internal error, integrity check failed! Bad primary user id specified! + Bad user id for revocation specified! Revoked user ids cannot be primary! PGP internal exception! Signature exception! -- cgit v1.2.3 From 1fa77d57d2bb0e82291364a046ddce0e17fa393f Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Sat, 16 Aug 2014 05:15:12 +0200 Subject: modifySecretKey: err out on "use previous" expiry date for (sub)key creation --- .../keychain/pgp/PgpKeyOperationTest.java | 20 ++++++++++---------- .../keychain/pgp/PgpKeyOperation.java | 8 +++++++- .../keychain/service/OperationResultParcel.java | 2 ++ OpenKeychain/src/main/res/values/strings.xml | 2 ++ 4 files changed, 21 insertions(+), 11 deletions(-) diff --git a/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperationTest.java b/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperationTest.java index 9d4aa7dba..08c29bc2c 100644 --- a/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperationTest.java +++ b/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperationTest.java @@ -71,11 +71,11 @@ public class PgpKeyOperationTest { SaveKeyringParcel parcel = new SaveKeyringParcel(); parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( - PublicKeyAlgorithmTags.RSA_GENERAL, 1024, KeyFlags.CERTIFY_OTHER, null)); + PublicKeyAlgorithmTags.RSA_GENERAL, 1024, KeyFlags.CERTIFY_OTHER, 0L)); parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( - PublicKeyAlgorithmTags.RSA_GENERAL, 1024, KeyFlags.SIGN_DATA, null)); + PublicKeyAlgorithmTags.RSA_GENERAL, 1024, KeyFlags.SIGN_DATA, 0L)); parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( - PublicKeyAlgorithmTags.RSA_GENERAL, 1024, KeyFlags.ENCRYPT_COMMS, null)); + PublicKeyAlgorithmTags.RSA_GENERAL, 1024, KeyFlags.ENCRYPT_COMMS, 0L)); parcel.mAddUserIds.add("twi"); parcel.mAddUserIds.add("pink"); @@ -113,7 +113,7 @@ public class PgpKeyOperationTest { { parcel.reset(); parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( - PublicKeyAlgorithmTags.RSA_GENERAL, new Random().nextInt(256)+255, KeyFlags.CERTIFY_OTHER, null)); + PublicKeyAlgorithmTags.RSA_GENERAL, new Random().nextInt(256)+255, KeyFlags.CERTIFY_OTHER, 0L)); parcel.mAddUserIds.add("shy"); parcel.mNewPassphrase = passphrase; @@ -123,7 +123,7 @@ public class PgpKeyOperationTest { { parcel.reset(); parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( - PublicKeyAlgorithmTags.ELGAMAL_ENCRYPT, 1024, KeyFlags.CERTIFY_OTHER, null)); + PublicKeyAlgorithmTags.ELGAMAL_ENCRYPT, 1024, KeyFlags.CERTIFY_OTHER, 0L)); parcel.mAddUserIds.add("shy"); parcel.mNewPassphrase = passphrase; @@ -133,7 +133,7 @@ public class PgpKeyOperationTest { { parcel.reset(); parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( - 12345, 1024, KeyFlags.CERTIFY_OTHER, null)); + 12345, 1024, KeyFlags.CERTIFY_OTHER, 0L)); parcel.mAddUserIds.add("shy"); parcel.mNewPassphrase = passphrase; @@ -143,7 +143,7 @@ public class PgpKeyOperationTest { { parcel.reset(); parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( - PublicKeyAlgorithmTags.RSA_GENERAL, 1024, KeyFlags.SIGN_DATA, null)); + PublicKeyAlgorithmTags.RSA_GENERAL, 1024, KeyFlags.SIGN_DATA, 0L)); parcel.mAddUserIds.add("shy"); parcel.mNewPassphrase = passphrase; @@ -153,7 +153,7 @@ public class PgpKeyOperationTest { { parcel.reset(); parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( - PublicKeyAlgorithmTags.RSA_GENERAL, 1024, KeyFlags.CERTIFY_OTHER, null)); + PublicKeyAlgorithmTags.RSA_GENERAL, 1024, KeyFlags.CERTIFY_OTHER, 0L)); parcel.mNewPassphrase = passphrase; assertFailure("creating ring without user ids should fail", parcel); @@ -175,7 +175,7 @@ public class PgpKeyOperationTest { public void testMasterFlags() throws Exception { SaveKeyringParcel parcel = new SaveKeyringParcel(); parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( - PublicKeyAlgorithmTags.RSA_GENERAL, 1024, KeyFlags.CERTIFY_OTHER | KeyFlags.SIGN_DATA, null)); + PublicKeyAlgorithmTags.RSA_GENERAL, 1024, KeyFlags.CERTIFY_OTHER | KeyFlags.SIGN_DATA, 0L)); parcel.mAddUserIds.add("luna"); ring = assertCreateSuccess("creating ring with master key flags must succeed", parcel); @@ -330,7 +330,7 @@ public class PgpKeyOperationTest { { // bad keysize should fail parcel.reset(); parcel.mAddSubKeys.add(new SubkeyAdd( - PublicKeyAlgorithmTags.RSA_GENERAL, new Random().nextInt(512), KeyFlags.SIGN_DATA, null)); + PublicKeyAlgorithmTags.RSA_GENERAL, new Random().nextInt(512), KeyFlags.SIGN_DATA, 0L)); assertModifyFailure("creating a subkey with keysize < 512 should fail", ring, parcel); } 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 06d8dff69..d7658efef 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java @@ -218,6 +218,11 @@ public class PgpKeyOperation { return new EditKeyResult(EditKeyResult.RESULT_ERROR, log, null); } + if (add.mExpiry == null) { + log.add(LogLevel.ERROR, LogType.MSG_CR_ERROR_NULL_EXPIRY, indent); + return new EditKeyResult(EditKeyResult.RESULT_ERROR, log, null); + } + if (add.mAlgorithm == PublicKeyAlgorithmTags.ELGAMAL_ENCRYPT) { log.add(LogLevel.ERROR, LogType.MSG_CR_ERROR_MASTER_ELGAMAL, indent); return new EditKeyResult(EditKeyResult.RESULT_ERROR, log, null); @@ -638,7 +643,8 @@ public class PgpKeyOperation { ); PGPKeyPair keyPair = createKey(add.mAlgorithm, add.mKeysize, log, indent); subProgressPop(); - if(keyPair == null) { + if (keyPair == null) { + log.add(LogLevel.ERROR, LogType.MSG_MF_ERROR_PGP, indent +1); return new EditKeyResult(EditKeyResult.RESULT_ERROR, log, null); } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/OperationResultParcel.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/OperationResultParcel.java index 4c93e2a91..01c7611ff 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/OperationResultParcel.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/OperationResultParcel.java @@ -347,6 +347,7 @@ public class OperationResultParcel implements Parcelable { MSG_CR_ERROR_NO_MASTER (R.string.msg_cr_error_no_master), MSG_CR_ERROR_NO_USER_ID (R.string.msg_cr_error_no_user_id), MSG_CR_ERROR_NO_CERTIFY (R.string.msg_cr_error_no_certify), + MSG_CR_ERROR_NULL_EXPIRY(R.string.msg_cr_error_null_expiry), MSG_CR_ERROR_KEYSIZE_512 (R.string.msg_cr_error_keysize_512), MSG_CR_ERROR_UNKNOWN_ALGO (R.string.msg_cr_error_unknown_algo), MSG_CR_ERROR_INTERNAL_PGP (R.string.msg_cr_error_internal_pgp), @@ -360,6 +361,7 @@ public class OperationResultParcel implements Parcelable { MSG_MF_ERROR_INTEGRITY (R.string.msg_mf_error_integrity), MSG_MF_ERROR_NOEXIST_PRIMARY (R.string.msg_mf_error_noexist_primary), MSG_MF_ERROR_NOEXIST_REVOKE (R.string.msg_mf_error_noexist_revoke), + MSG_MF_ERROR_NULL_EXPIRY (R.string.msg_mf_error_null_expiry), MSG_MF_ERROR_REVOKED_PRIMARY (R.string.msg_mf_error_revoked_primary), MSG_MF_ERROR_PGP (R.string.msg_mf_error_pgp), MSG_MF_ERROR_SIG (R.string.msg_mf_error_sig), diff --git a/OpenKeychain/src/main/res/values/strings.xml b/OpenKeychain/src/main/res/values/strings.xml index 5eb594163..f603663e8 100644 --- a/OpenKeychain/src/main/res/values/strings.xml +++ b/OpenKeychain/src/main/res/values/strings.xml @@ -627,6 +627,7 @@ No master key options specified! Keyrings must be created with at least one user id! Master key must have certify flag! + Expiry time cannot be "same as before" on key creation. This is a programming error, please file a bug report! Key size must be greater or equal 512! Internal PGP error! Bad algorithm choice! @@ -641,6 +642,7 @@ Bad primary user id specified! Bad user id for revocation specified! Revoked user ids cannot be primary! + Expiry time cannot be "same as before" on subkey creation. This is a programming error, please file a bug report! PGP internal exception! Signature exception! Changing passphrase -- cgit v1.2.3 From a943bebfdf063700c01170ea264e342283e5d6b3 Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Sat, 16 Aug 2014 06:24:40 +0200 Subject: support for master key modifications, among other stuff --- .../keychain/pgp/PgpKeyOperationTest.java | 122 +++++- .../pgp/UncachedKeyringCanonicalizeTest.java | 8 +- .../keychain/pgp/UncachedKeyringMergeTest.java | 8 +- .../keychain/pgp/UncachedKeyringTest.java | 6 +- .../keychain/pgp/PgpKeyOperation.java | 479 +++++++++++++-------- .../keychain/service/OperationResultParcel.java | 13 +- OpenKeychain/src/main/res/values-es/strings.xml | 2 +- OpenKeychain/src/main/res/values-fr/strings.xml | 2 +- OpenKeychain/src/main/res/values-it/strings.xml | 2 +- OpenKeychain/src/main/res/values-ja/strings.xml | 2 +- OpenKeychain/src/main/res/values-ru/strings.xml | 2 +- OpenKeychain/src/main/res/values/strings.xml | 4 +- 12 files changed, 446 insertions(+), 204 deletions(-) diff --git a/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperationTest.java b/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperationTest.java index 08c29bc2c..c46e3ee15 100644 --- a/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperationTest.java +++ b/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperationTest.java @@ -376,6 +376,20 @@ public class PgpKeyOperationTest { ring.getPublicKey(keyId).getKeyUsage(), modified.getPublicKey(keyId).getKeyUsage()); } + { // change expiry + expiry += 60*60*24; + + parcel.mChangeSubKeys.add(new SubkeyChange(keyId, null, expiry)); + modified = applyModificationWithChecks(parcel, modified, onlyA, onlyB); + + Assert.assertNotNull("modified key must have an expiry date", + modified.getPublicKey(keyId).getExpiryTime()); + Assert.assertEquals("modified key must have expected expiry date", + expiry, modified.getPublicKey(keyId).getExpiryTime().getTime()/1000); + Assert.assertEquals("modified key must have same flags as before", + ring.getPublicKey(keyId).getKeyUsage(), modified.getPublicKey(keyId).getKeyUsage()); + } + { int flags = KeyFlags.SIGN_DATA | KeyFlags.ENCRYPT_COMMS; parcel.reset(); @@ -422,16 +436,114 @@ public class PgpKeyOperationTest { parcel.reset(); parcel.mChangeSubKeys.add(new SubkeyChange(keyId, null, new Date().getTime()/1000-10)); - CanonicalizedSecretKeyRing secretRing = new CanonicalizedSecretKeyRing(ring.getEncoded(), false, 0); - assertModifyFailure("setting subkey expiry to a past date should fail", secretRing, parcel); + assertModifyFailure("setting subkey expiry to a past date should fail", ring, parcel); } - { // modifying nonexistent keyring should fail + { // modifying nonexistent subkey should fail parcel.reset(); parcel.mChangeSubKeys.add(new SubkeyChange(123, null, null)); - CanonicalizedSecretKeyRing secretRing = new CanonicalizedSecretKeyRing(ring.getEncoded(), false, 0); - assertModifyFailure("modifying non-existent subkey should fail", secretRing, parcel); + assertModifyFailure("modifying non-existent subkey should fail", ring, parcel); + } + + } + + @Test + public void testMasterModify() throws Exception { + + long expiry = new Date().getTime()/1000 + 1024; + long keyId = ring.getMasterKeyId(); + + UncachedKeyRing modified = ring; + + // to make this check less trivial, we add a user id, change the primary one and revoke one + parcel.mAddUserIds.add("aloe"); + parcel.mChangePrimaryUserId = "aloe"; + parcel.mRevokeUserIds.add("pink"); + modified = applyModificationWithChecks(parcel, modified, onlyA, onlyB); + + { + parcel.mChangeSubKeys.add(new SubkeyChange(keyId, null, expiry)); + modified = applyModificationWithChecks(parcel, modified, onlyA, onlyB); + + // this implies that only the two non-revoked signatures were changed! + Assert.assertEquals("two extra packets in original", 2, onlyA.size()); + Assert.assertEquals("two extra packets in modified", 2, onlyB.size()); + + Assert.assertEquals("first original packet must be a signature", + PacketTags.SIGNATURE, onlyA.get(0).tag); + Assert.assertEquals("second original packet must be a signature", + PacketTags.SIGNATURE, onlyA.get(1).tag); + Assert.assertEquals("first new packet must be signature", + PacketTags.SIGNATURE, onlyB.get(0).tag); + Assert.assertEquals("first new packet must be signature", + PacketTags.SIGNATURE, onlyB.get(1).tag); + + Assert.assertNotNull("modified key must have an expiry date", + modified.getPublicKey().getExpiryTime()); + Assert.assertEquals("modified key must have expected expiry date", + expiry, modified.getPublicKey().getExpiryTime().getTime() / 1000); + Assert.assertEquals("modified key must have same flags as before", + ring.getPublicKey().getKeyUsage(), modified.getPublicKey().getKeyUsage()); + } + + { // change expiry + expiry += 60*60*24; + + parcel.mChangeSubKeys.add(new SubkeyChange(keyId, null, expiry)); + modified = applyModificationWithChecks(parcel, modified, onlyA, onlyB); + + Assert.assertNotNull("modified key must have an expiry date", + modified.getPublicKey(keyId).getExpiryTime()); + Assert.assertEquals("modified key must have expected expiry date", + expiry, modified.getPublicKey(keyId).getExpiryTime().getTime()/1000); + Assert.assertEquals("modified key must have same flags as before", + ring.getPublicKey(keyId).getKeyUsage(), modified.getPublicKey(keyId).getKeyUsage()); + } + + { + int flags = KeyFlags.CERTIFY_OTHER | KeyFlags.SIGN_DATA; + parcel.reset(); + parcel.mChangeSubKeys.add(new SubkeyChange(keyId, flags, null)); + modified = applyModificationWithChecks(parcel, modified, onlyA, onlyB); + + Assert.assertEquals("modified key must have expected flags", + flags, modified.getPublicKey(keyId).getKeyUsage()); + Assert.assertNotNull("key must retain its expiry", + modified.getPublicKey(keyId).getExpiryTime()); + Assert.assertEquals("key expiry must be unchanged", + expiry, modified.getPublicKey(keyId).getExpiryTime().getTime()/1000); + } + + { // expiry of 0 should be "no expiry" + parcel.reset(); + parcel.mChangeSubKeys.add(new SubkeyChange(keyId, null, 0L)); + modified = applyModificationWithChecks(parcel, modified, onlyA, onlyB); + + Assert.assertNull("key must not expire anymore", modified.getPublicKey(keyId).getExpiryTime()); + } + + { // if we revoke everything, nothing is left to properly sign... + parcel.reset(); + parcel.mRevokeUserIds.add("twi"); + parcel.mRevokeUserIds.add("pink"); + parcel.mChangeSubKeys.add(new SubkeyChange(keyId, KeyFlags.CERTIFY_OTHER, null)); + + assertModifyFailure("master key modification with all user ids revoked should fail", ring, parcel); + } + + { // any flag not including CERTIFY_OTHER should fail + parcel.reset(); + parcel.mChangeSubKeys.add(new SubkeyChange(keyId, KeyFlags.SIGN_DATA, null)); + + assertModifyFailure("setting master key flags without certify should fail", ring, parcel); + } + + { // a past expiry should fail + parcel.reset(); + parcel.mChangeSubKeys.add(new SubkeyChange(keyId, null, new Date().getTime()/1000-10)); + + assertModifyFailure("setting subkey expiry to a past date should fail", ring, parcel); } } diff --git a/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/UncachedKeyringCanonicalizeTest.java b/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/UncachedKeyringCanonicalizeTest.java index 535e9d01a..588dac17b 100644 --- a/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/UncachedKeyringCanonicalizeTest.java +++ b/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/UncachedKeyringCanonicalizeTest.java @@ -64,11 +64,11 @@ public class UncachedKeyringCanonicalizeTest { SaveKeyringParcel parcel = new SaveKeyringParcel(); parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( - PublicKeyAlgorithmTags.RSA_GENERAL, 1024, KeyFlags.CERTIFY_OTHER, null)); + PublicKeyAlgorithmTags.RSA_GENERAL, 1024, KeyFlags.CERTIFY_OTHER, 0L)); parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( - PublicKeyAlgorithmTags.RSA_GENERAL, 1024, KeyFlags.SIGN_DATA, null)); + PublicKeyAlgorithmTags.RSA_GENERAL, 1024, KeyFlags.SIGN_DATA, 0L)); parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( - PublicKeyAlgorithmTags.RSA_GENERAL, 1024, KeyFlags.ENCRYPT_COMMS, null)); + PublicKeyAlgorithmTags.RSA_GENERAL, 1024, KeyFlags.ENCRYPT_COMMS, 0L)); parcel.mAddUserIds.add("twi"); parcel.mAddUserIds.add("pink"); @@ -277,7 +277,7 @@ public class UncachedKeyringCanonicalizeTest { SaveKeyringParcel parcel = new SaveKeyringParcel(); parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( - PublicKeyAlgorithmTags.RSA_GENERAL, 1024, KeyFlags.CERTIFY_OTHER, null)); + PublicKeyAlgorithmTags.RSA_GENERAL, 1024, KeyFlags.CERTIFY_OTHER, 0L)); parcel.mAddUserIds.add("trix"); PgpKeyOperation op = new PgpKeyOperation(null); diff --git a/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/UncachedKeyringMergeTest.java b/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/UncachedKeyringMergeTest.java index 6e9381c06..603b1e6d1 100644 --- a/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/UncachedKeyringMergeTest.java +++ b/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/UncachedKeyringMergeTest.java @@ -64,9 +64,9 @@ public class UncachedKeyringMergeTest { { SaveKeyringParcel parcel = new SaveKeyringParcel(); parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( - PublicKeyAlgorithmTags.RSA_GENERAL, 1024, KeyFlags.CERTIFY_OTHER, null)); + PublicKeyAlgorithmTags.RSA_GENERAL, 1024, KeyFlags.CERTIFY_OTHER, 0L)); parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( - PublicKeyAlgorithmTags.RSA_GENERAL, 1024, KeyFlags.SIGN_DATA, null)); + PublicKeyAlgorithmTags.RSA_GENERAL, 1024, KeyFlags.SIGN_DATA, 0L)); parcel.mAddUserIds.add("twi"); parcel.mAddUserIds.add("pink"); @@ -83,7 +83,7 @@ public class UncachedKeyringMergeTest { { SaveKeyringParcel parcel = new SaveKeyringParcel(); parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( - PublicKeyAlgorithmTags.RSA_GENERAL, 1024, KeyFlags.CERTIFY_OTHER, null)); + PublicKeyAlgorithmTags.RSA_GENERAL, 1024, KeyFlags.CERTIFY_OTHER, 0L)); parcel.mAddUserIds.add("shy"); // passphrase is tested in PgpKeyOperationTest, just use empty here @@ -189,7 +189,7 @@ public class UncachedKeyringMergeTest { parcel.reset(); parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( - PublicKeyAlgorithmTags.RSA_GENERAL, 1024, KeyFlags.SIGN_DATA, null)); + PublicKeyAlgorithmTags.RSA_GENERAL, 1024, KeyFlags.SIGN_DATA, 0L)); modifiedA = op.modifySecretKeyRing(secretRing, parcel, "").getRing(); modifiedB = op.modifySecretKeyRing(secretRing, parcel, "").getRing(); diff --git a/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/UncachedKeyringTest.java b/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/UncachedKeyringTest.java index cbd1bc502..581e315a0 100644 --- a/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/UncachedKeyringTest.java +++ b/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/UncachedKeyringTest.java @@ -37,11 +37,11 @@ public class UncachedKeyringTest { SaveKeyringParcel parcel = new SaveKeyringParcel(); parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( - PublicKeyAlgorithmTags.RSA_GENERAL, 1024, KeyFlags.CERTIFY_OTHER, null)); + PublicKeyAlgorithmTags.RSA_GENERAL, 1024, KeyFlags.CERTIFY_OTHER, 0L)); parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( - PublicKeyAlgorithmTags.RSA_GENERAL, 1024, KeyFlags.SIGN_DATA, null)); + PublicKeyAlgorithmTags.RSA_GENERAL, 1024, KeyFlags.SIGN_DATA, 0L)); parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( - PublicKeyAlgorithmTags.RSA_GENERAL, 1024, KeyFlags.ENCRYPT_COMMS, null)); + PublicKeyAlgorithmTags.RSA_GENERAL, 1024, KeyFlags.ENCRYPT_COMMS, 0L)); parcel.mAddUserIds.add("twi"); parcel.mAddUserIds.add("pink"); 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 d7658efef..710bd42c6 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java @@ -253,7 +253,7 @@ public class PgpKeyOperation { masterSecretKey.getEncoded(), new JcaKeyFingerprintCalculator()); subProgressPush(50, 100); - return internal(sKR, masterSecretKey, add.mFlags, saveParcel, "", log); + return internal(sKR, masterSecretKey, add.mFlags, add.mExpiry, saveParcel, "", log); } catch (PGPException e) { log.add(LogLevel.ERROR, LogType.MSG_CR_ERROR_INTERNAL_PGP, indent); @@ -319,14 +319,17 @@ public class PgpKeyOperation { // read masterKeyFlags, and use the same as before. // since this is the master key, this contains at least CERTIFY_OTHER - int masterKeyFlags = readKeyFlags(masterSecretKey.getPublicKey()) | KeyFlags.CERTIFY_OTHER; + PGPPublicKey masterPublicKey = masterSecretKey.getPublicKey(); + int masterKeyFlags = readKeyFlags(masterPublicKey) | KeyFlags.CERTIFY_OTHER; + long masterKeyExpiry = masterPublicKey.getValidSeconds() == 0L ? 0L : + masterPublicKey.getCreationTime().getTime() / 1000 + masterPublicKey.getValidSeconds(); - return internal(sKR, masterSecretKey, masterKeyFlags, saveParcel, passphrase, log); + return internal(sKR, masterSecretKey, masterKeyFlags, masterKeyExpiry, saveParcel, passphrase, log); } private EditKeyResult internal(PGPSecretKeyRing sKR, PGPSecretKey masterSecretKey, - int masterKeyFlags, + int masterKeyFlags, long masterKeyExpiry, SaveKeyringParcel saveParcel, String passphrase, OperationLog log) { @@ -351,189 +354,196 @@ public class PgpKeyOperation { } } - // work on master secret key try { - PGPPublicKey modifiedPublicKey = masterPublicKey; + { // work on master secret key - // 2a. Add certificates for new user ids - subProgressPush(15, 25); - for (int i = 0; i < saveParcel.mAddUserIds.size(); i++) { + PGPPublicKey modifiedPublicKey = masterPublicKey; - progress(R.string.progress_modify_adduid, (i-1) * (100 / saveParcel.mAddUserIds.size())); - String userId = saveParcel.mAddUserIds.get(i); - log.add(LogLevel.INFO, LogType.MSG_MF_UID_ADD, indent, userId); + // 2a. Add certificates for new user ids + subProgressPush(15, 25); + for (int i = 0; i < saveParcel.mAddUserIds.size(); i++) { - if (userId.equals("")) { - log.add(LogLevel.ERROR, LogType.MSG_MF_UID_ERROR_EMPTY, indent+1); - return new EditKeyResult(EditKeyResult.RESULT_ERROR, log, null); - } + progress(R.string.progress_modify_adduid, (i - 1) * (100 / saveParcel.mAddUserIds.size())); + String userId = saveParcel.mAddUserIds.get(i); + log.add(LogLevel.INFO, LogType.MSG_MF_UID_ADD, indent, userId); - // this operation supersedes all previous binding and revocation certificates, - // so remove those to retain assertions from canonicalization for later operations - @SuppressWarnings("unchecked") - Iterator it = modifiedPublicKey.getSignaturesForID(userId); - if (it != null) { - for (PGPSignature cert : new IterableIterator(it)) { - if (cert.getKeyID() != masterPublicKey.getKeyID()) { - // foreign certificate?! error error error - log.add(LogLevel.ERROR, LogType.MSG_MF_ERROR_INTEGRITY, indent); - return new EditKeyResult(EditKeyResult.RESULT_ERROR, log, null); - } - if (cert.getSignatureType() == PGPSignature.CERTIFICATION_REVOCATION - || cert.getSignatureType() == PGPSignature.NO_CERTIFICATION - || cert.getSignatureType() == PGPSignature.CASUAL_CERTIFICATION - || cert.getSignatureType() == PGPSignature.POSITIVE_CERTIFICATION - || cert.getSignatureType() == PGPSignature.DEFAULT_CERTIFICATION) { - modifiedPublicKey = PGPPublicKey.removeCertification( - modifiedPublicKey, userId, cert); + if (userId.equals("")) { + log.add(LogLevel.ERROR, LogType.MSG_MF_UID_ERROR_EMPTY, indent + 1); + return new EditKeyResult(EditKeyResult.RESULT_ERROR, log, null); + } + + // this operation supersedes all previous binding and revocation certificates, + // so remove those to retain assertions from canonicalization for later operations + @SuppressWarnings("unchecked") + Iterator it = modifiedPublicKey.getSignaturesForID(userId); + if (it != null) { + for (PGPSignature cert : new IterableIterator(it)) { + if (cert.getKeyID() != masterPublicKey.getKeyID()) { + // foreign certificate?! error error error + log.add(LogLevel.ERROR, LogType.MSG_MF_ERROR_INTEGRITY, indent); + return new EditKeyResult(EditKeyResult.RESULT_ERROR, log, null); + } + if (cert.getSignatureType() == PGPSignature.CERTIFICATION_REVOCATION + || cert.getSignatureType() == PGPSignature.NO_CERTIFICATION + || cert.getSignatureType() == PGPSignature.CASUAL_CERTIFICATION + || cert.getSignatureType() == PGPSignature.POSITIVE_CERTIFICATION + || cert.getSignatureType() == PGPSignature.DEFAULT_CERTIFICATION) { + modifiedPublicKey = PGPPublicKey.removeCertification( + modifiedPublicKey, userId, cert); + } } } - } - // if it's supposed to be primary, we can do that here as well - boolean isPrimary = saveParcel.mChangePrimaryUserId != null - && userId.equals(saveParcel.mChangePrimaryUserId); - // generate and add new certificate - PGPSignature cert = generateUserIdSignature(masterPrivateKey, - masterPublicKey, userId, isPrimary, masterKeyFlags); - modifiedPublicKey = PGPPublicKey.addCertification(modifiedPublicKey, userId, cert); - } - subProgressPop(); + // if it's supposed to be primary, we can do that here as well + boolean isPrimary = saveParcel.mChangePrimaryUserId != null + && userId.equals(saveParcel.mChangePrimaryUserId); + // generate and add new certificate + PGPSignature cert = generateUserIdSignature(masterPrivateKey, + masterPublicKey, userId, isPrimary, masterKeyFlags, masterKeyExpiry); + modifiedPublicKey = PGPPublicKey.addCertification(modifiedPublicKey, userId, cert); + } + subProgressPop(); - // 2b. Add revocations for revoked user ids - subProgressPush(25, 40); - for (int i = 0; i < saveParcel.mRevokeUserIds.size(); i++) { - - progress(R.string.progress_modify_revokeuid, (i-1) * (100 / saveParcel.mRevokeUserIds.size())); - String userId = saveParcel.mRevokeUserIds.get(i); - log.add(LogLevel.INFO, LogType.MSG_MF_UID_REVOKE, indent, userId); - // Make sure the user id exists (yes these are 10 LoC in Java!) - boolean exists = false; - for (String uid : new IterableIterator(modifiedPublicKey.getUserIDs())) { - if (userId.equals(uid)) { - exists = true; - break; + // 2b. Add revocations for revoked user ids + subProgressPush(25, 40); + for (int i = 0; i < saveParcel.mRevokeUserIds.size(); i++) { + + progress(R.string.progress_modify_revokeuid, (i - 1) * (100 / saveParcel.mRevokeUserIds.size())); + String userId = saveParcel.mRevokeUserIds.get(i); + log.add(LogLevel.INFO, LogType.MSG_MF_UID_REVOKE, indent, userId); + + // Make sure the user id exists (yes these are 10 LoC in Java!) + boolean exists = false; + //noinspection unchecked + for (String uid : new IterableIterator(modifiedPublicKey.getUserIDs())) { + if (userId.equals(uid)) { + exists = true; + break; + } + } + if (!exists) { + log.add(LogLevel.ERROR, LogType.MSG_MF_ERROR_NOEXIST_REVOKE, indent); + return new EditKeyResult(EditKeyResult.RESULT_ERROR, log, null); } - } - if (!exists) { - log.add(LogLevel.ERROR, LogType.MSG_MF_ERROR_NOEXIST_REVOKE, indent); - return new EditKeyResult(EditKeyResult.RESULT_ERROR, log, null); - } - // a duplicate revocation will be removed during canonicalization, so no need to - // take care of that here. - PGPSignature cert = generateRevocationSignature(masterPrivateKey, - masterPublicKey, userId); - modifiedPublicKey = PGPPublicKey.addCertification(modifiedPublicKey, userId, cert); - } - subProgressPop(); + // a duplicate revocation will be removed during canonicalization, so no need to + // take care of that here. + PGPSignature cert = generateRevocationSignature(masterPrivateKey, + masterPublicKey, userId); + modifiedPublicKey = PGPPublicKey.addCertification(modifiedPublicKey, userId, cert); + } + subProgressPop(); - // 3. If primary user id changed, generate new certificates for both old and new - if (saveParcel.mChangePrimaryUserId != null) { - progress(R.string.progress_modify_primaryuid, 40); + // 3. If primary user id changed, generate new certificates for both old and new + if (saveParcel.mChangePrimaryUserId != null) { + progress(R.string.progress_modify_primaryuid, 40); - // keep track if we actually changed one - boolean ok = false; - log.add(LogLevel.INFO, LogType.MSG_MF_UID_PRIMARY, indent); - indent += 1; + // keep track if we actually changed one + boolean ok = false; + log.add(LogLevel.INFO, LogType.MSG_MF_UID_PRIMARY, indent); + indent += 1; - // we work on the modifiedPublicKey here, to respect new or newly revoked uids - // noinspection unchecked - for (String userId : new IterableIterator(modifiedPublicKey.getUserIDs())) { - boolean isRevoked = false; - PGPSignature currentCert = null; + // we work on the modifiedPublicKey here, to respect new or newly revoked uids // noinspection unchecked - for (PGPSignature cert : new IterableIterator( - modifiedPublicKey.getSignaturesForID(userId))) { - if (cert.getKeyID() != masterPublicKey.getKeyID()) { - // foreign certificate?! error error error + for (String userId : new IterableIterator(modifiedPublicKey.getUserIDs())) { + boolean isRevoked = false; + PGPSignature currentCert = null; + // noinspection unchecked + for (PGPSignature cert : new IterableIterator( + modifiedPublicKey.getSignaturesForID(userId))) { + if (cert.getKeyID() != masterPublicKey.getKeyID()) { + // foreign certificate?! error error error + log.add(LogLevel.ERROR, LogType.MSG_MF_ERROR_INTEGRITY, indent); + return new EditKeyResult(EditKeyResult.RESULT_ERROR, log, null); + } + // we know from canonicalization that if there is any revocation here, it + // is valid and not superseded by a newer certification. + if (cert.getSignatureType() == PGPSignature.CERTIFICATION_REVOCATION) { + isRevoked = true; + continue; + } + // we know from canonicalization that there is only one binding + // certification here, so we can just work with the first one. + if (cert.getSignatureType() == PGPSignature.NO_CERTIFICATION || + cert.getSignatureType() == PGPSignature.CASUAL_CERTIFICATION || + cert.getSignatureType() == PGPSignature.POSITIVE_CERTIFICATION || + cert.getSignatureType() == PGPSignature.DEFAULT_CERTIFICATION) { + currentCert = cert; + } + } + + if (currentCert == null) { + // no certificate found?! error error error log.add(LogLevel.ERROR, LogType.MSG_MF_ERROR_INTEGRITY, indent); return new EditKeyResult(EditKeyResult.RESULT_ERROR, log, null); } - // we know from canonicalization that if there is any revocation here, it - // is valid and not superseded by a newer certification. - if (cert.getSignatureType() == PGPSignature.CERTIFICATION_REVOCATION) { - isRevoked = true; + + // we definitely should not update certifications of revoked keys, so just leave it. + if (isRevoked) { + // revoked user ids cannot be primary! + if (userId.equals(saveParcel.mChangePrimaryUserId)) { + log.add(LogLevel.ERROR, LogType.MSG_MF_ERROR_REVOKED_PRIMARY, indent); + return new EditKeyResult(EditKeyResult.RESULT_ERROR, log, null); + } continue; } - // we know from canonicalization that there is only one binding - // certification here, so we can just work with the first one. - if (cert.getSignatureType() == PGPSignature.NO_CERTIFICATION || - cert.getSignatureType() == PGPSignature.CASUAL_CERTIFICATION || - cert.getSignatureType() == PGPSignature.POSITIVE_CERTIFICATION || - cert.getSignatureType() == PGPSignature.DEFAULT_CERTIFICATION) { - currentCert = cert; - } - } - if (currentCert == null) { - // no certificate found?! error error error - log.add(LogLevel.ERROR, LogType.MSG_MF_ERROR_INTEGRITY, indent); - return new EditKeyResult(EditKeyResult.RESULT_ERROR, log, null); - } - - // we definitely should not update certifications of revoked keys, so just leave it. - if (isRevoked) { - // revoked user ids cannot be primary! - if (userId.equals(saveParcel.mChangePrimaryUserId)) { - log.add(LogLevel.ERROR, LogType.MSG_MF_ERROR_REVOKED_PRIMARY, indent); - return new EditKeyResult(EditKeyResult.RESULT_ERROR, log, null); + // if this is~ the/a primary user id + if (currentCert.getHashedSubPackets() != null + && currentCert.getHashedSubPackets().isPrimaryUserID()) { + // if it's the one we want, just leave it as is + if (userId.equals(saveParcel.mChangePrimaryUserId)) { + ok = true; + continue; + } + // otherwise, generate new non-primary certification + log.add(LogLevel.DEBUG, LogType.MSG_MF_PRIMARY_REPLACE_OLD, indent); + modifiedPublicKey = PGPPublicKey.removeCertification( + modifiedPublicKey, userId, currentCert); + PGPSignature newCert = generateUserIdSignature( + masterPrivateKey, masterPublicKey, userId, false, + masterKeyFlags, masterKeyExpiry); + modifiedPublicKey = PGPPublicKey.addCertification( + modifiedPublicKey, userId, newCert); + continue; } - continue; - } - // if this is~ the/a primary user id - if (currentCert.getHashedSubPackets() != null - && currentCert.getHashedSubPackets().isPrimaryUserID()) { - // if it's the one we want, just leave it as is + // if we are here, this is not currently a primary user id + + // if it should be if (userId.equals(saveParcel.mChangePrimaryUserId)) { + // add shiny new primary user id certificate + log.add(LogLevel.DEBUG, LogType.MSG_MF_PRIMARY_NEW, indent); + modifiedPublicKey = PGPPublicKey.removeCertification( + modifiedPublicKey, userId, currentCert); + PGPSignature newCert = generateUserIdSignature( + masterPrivateKey, masterPublicKey, userId, true, + masterKeyFlags, masterKeyExpiry); + modifiedPublicKey = PGPPublicKey.addCertification( + modifiedPublicKey, userId, newCert); ok = true; - continue; } - // otherwise, generate new non-primary certification - log.add(LogLevel.DEBUG, LogType.MSG_MF_PRIMARY_REPLACE_OLD, indent); - modifiedPublicKey = PGPPublicKey.removeCertification( - modifiedPublicKey, userId, currentCert); - PGPSignature newCert = generateUserIdSignature( - masterPrivateKey, masterPublicKey, userId, false, masterKeyFlags); - modifiedPublicKey = PGPPublicKey.addCertification( - modifiedPublicKey, userId, newCert); - continue; - } - // if we are here, this is not currently a primary user id - - // if it should be - if (userId.equals(saveParcel.mChangePrimaryUserId)) { - // add shiny new primary user id certificate - log.add(LogLevel.DEBUG, LogType.MSG_MF_PRIMARY_NEW, indent); - modifiedPublicKey = PGPPublicKey.removeCertification( - modifiedPublicKey, userId, currentCert); - PGPSignature newCert = generateUserIdSignature( - masterPrivateKey, masterPublicKey, userId, true, masterKeyFlags); - modifiedPublicKey = PGPPublicKey.addCertification( - modifiedPublicKey, userId, newCert); - ok = true; + // user id is not primary and is not supposed to be - nothing to do here. + } - // user id is not primary and is not supposed to be - nothing to do here. + indent -= 1; + if (!ok) { + log.add(LogLevel.ERROR, LogType.MSG_MF_ERROR_NOEXIST_PRIMARY, indent); + return new EditKeyResult(EditKeyResult.RESULT_ERROR, log, null); + } } - indent -= 1; - - if (!ok) { - log.add(LogLevel.ERROR, LogType.MSG_MF_ERROR_NOEXIST_PRIMARY, indent); - return new EditKeyResult(EditKeyResult.RESULT_ERROR, log, null); + // Update the secret key ring + if (modifiedPublicKey != masterPublicKey) { + masterSecretKey = PGPSecretKey.replacePublicKey(masterSecretKey, modifiedPublicKey); + masterPublicKey = modifiedPublicKey; + sKR = PGPSecretKeyRing.insertSecretKey(sKR, masterSecretKey); } - } - // Update the secret key ring - if (modifiedPublicKey != masterPublicKey) { - masterSecretKey = PGPSecretKey.replacePublicKey(masterSecretKey, modifiedPublicKey); - masterPublicKey = modifiedPublicKey; - sKR = PGPSecretKeyRing.insertSecretKey(sKR, masterSecretKey); } // 4a. For each subkey change, generate new subkey binding certificate @@ -545,28 +555,47 @@ public class PgpKeyOperation { log.add(LogLevel.INFO, LogType.MSG_MF_SUBKEY_CHANGE, indent, PgpKeyHelper.convertKeyIdToHex(change.mKeyId)); - // TODO allow changes in master key? this implies generating new user id certs... - if (change.mKeyId == masterPublicKey.getKeyID()) { - Log.e(Constants.TAG, "changing the master key not supported"); - return new EditKeyResult(EditKeyResult.RESULT_ERROR, log, null); - } - PGPSecretKey sKey = sKR.getSecretKey(change.mKeyId); if (sKey == null) { log.add(LogLevel.ERROR, LogType.MSG_MF_SUBKEY_MISSING, indent + 1, PgpKeyHelper.convertKeyIdToHex(change.mKeyId)); return new EditKeyResult(EditKeyResult.RESULT_ERROR, log, null); } - PGPPublicKey pKey = sKey.getPublicKey(); // expiry must not be in the past if (change.mExpiry != null && change.mExpiry != 0 && new Date(change.mExpiry*1000).before(new Date())) { - log.add(LogLevel.ERROR, LogType.MSG_MF_SUBKEY_PAST_EXPIRY, + log.add(LogLevel.ERROR, LogType.MSG_MF_ERROR_PAST_EXPIRY, indent + 1, PgpKeyHelper.convertKeyIdToHex(change.mKeyId)); return new EditKeyResult(EditKeyResult.RESULT_ERROR, log, null); } + // if this is the master key, update uid certificates instead + if (change.mKeyId == masterPublicKey.getKeyID()) { + int flags = change.mFlags == null ? masterKeyFlags : change.mFlags; + long expiry = change.mExpiry == null ? masterKeyExpiry : change.mExpiry; + + if ((flags & KeyFlags.CERTIFY_OTHER) != KeyFlags.CERTIFY_OTHER) { + log.add(LogLevel.ERROR, LogType.MSG_MF_ERROR_NO_CERTIFY, indent + 1); + return new EditKeyResult(EditKeyResult.RESULT_ERROR, log, null); + } + + PGPPublicKey pKey = + updateMasterCertificates(masterPrivateKey, masterPublicKey, + flags, expiry, indent, log); + if (pKey == null) { + // error log entry has already been added by updateMasterCertificates itself + return new EditKeyResult(EditKeyResult.RESULT_ERROR, log, null); + } + masterSecretKey = PGPSecretKey.replacePublicKey(masterSecretKey, pKey); + masterPublicKey = pKey; + sKR = PGPSecretKeyRing.insertSecretKey(sKR, masterSecretKey); + continue; + } + + // otherwise, continue working on the public key + PGPPublicKey pKey = sKey.getPublicKey(); + // keep old flags, or replace with new ones int flags = change.mFlags == null ? readKeyFlags(pKey) : change.mFlags; long expiry; @@ -583,7 +612,7 @@ public class PgpKeyOperation { //noinspection unchecked for (PGPSignature sig : new IterableIterator(pKey.getSignatures())) { // special case: if there is a revocation, don't use expiry from before - if (change.mExpiry == null + if ( (change.mExpiry == null || change.mExpiry == 0L) && sig.getSignatureType() == PGPSignature.SUBKEY_REVOCATION) { expiry = 0; } @@ -631,8 +660,13 @@ public class PgpKeyOperation { SaveKeyringParcel.SubkeyAdd add = saveParcel.mAddSubKeys.get(i); log.add(LogLevel.INFO, LogType.MSG_MF_SUBKEY_NEW, indent); - if (add.mExpiry != null && new Date(add.mExpiry*1000).before(new Date())) { - log.add(LogLevel.ERROR, LogType.MSG_MF_SUBKEY_PAST_EXPIRY, indent +1); + if (add.mExpiry == null) { + log.add(LogLevel.ERROR, LogType.MSG_MF_ERROR_NULL_EXPIRY, indent +1); + return new EditKeyResult(EditKeyResult.RESULT_ERROR, log, null); + } + + if (add.mExpiry > 0L && new Date(add.mExpiry*1000).before(new Date())) { + log.add(LogLevel.ERROR, LogType.MSG_MF_ERROR_PAST_EXPIRY, indent +1); return new EditKeyResult(EditKeyResult.RESULT_ERROR, log, null); } @@ -652,7 +686,7 @@ public class PgpKeyOperation { PGPPublicKey pKey = keyPair.getPublicKey(); PGPSignature cert = generateSubkeyBindingSignature( masterPublicKey, masterPrivateKey, keyPair.getPrivateKey(), pKey, - add.mFlags, add.mExpiry == null ? 0 : add.mExpiry); + add.mFlags, add.mExpiry); pKey = PGPPublicKey.addSubkeyBindingCertification(pKey, cert); PGPSecretKey sKey; { @@ -713,21 +747,104 @@ public class PgpKeyOperation { } + /** Update all (non-revoked) uid signatures with new flags and expiry time. */ + private static PGPPublicKey updateMasterCertificates( + PGPPrivateKey masterPrivateKey, PGPPublicKey masterPublicKey, + int flags, long expiry, int indent, OperationLog log) + throws PGPException, IOException, SignatureException { + + // keep track if we actually changed one + boolean ok = false; + log.add(LogLevel.DEBUG, LogType.MSG_MF_MASTER, indent); + indent += 1; + + PGPPublicKey modifiedPublicKey = masterPublicKey; + + // we work on the modifiedPublicKey here, to respect new or newly revoked uids + // noinspection unchecked + for (String userId : new IterableIterator(modifiedPublicKey.getUserIDs())) { + boolean isRevoked = false; + PGPSignature currentCert = null; + // noinspection unchecked + for (PGPSignature cert : new IterableIterator( + modifiedPublicKey.getSignaturesForID(userId))) { + if (cert.getKeyID() != masterPublicKey.getKeyID()) { + // foreign certificate?! error error error + log.add(LogLevel.ERROR, LogType.MSG_MF_ERROR_INTEGRITY, indent); + return null; + } + // we know from canonicalization that if there is any revocation here, it + // is valid and not superseded by a newer certification. + if (cert.getSignatureType() == PGPSignature.CERTIFICATION_REVOCATION) { + isRevoked = true; + continue; + } + // we know from canonicalization that there is only one binding + // certification here, so we can just work with the first one. + if (cert.getSignatureType() == PGPSignature.NO_CERTIFICATION || + cert.getSignatureType() == PGPSignature.CASUAL_CERTIFICATION || + cert.getSignatureType() == PGPSignature.POSITIVE_CERTIFICATION || + cert.getSignatureType() == PGPSignature.DEFAULT_CERTIFICATION) { + currentCert = cert; + } + } + + if (currentCert == null) { + // no certificate found?! error error error + log.add(LogLevel.ERROR, LogType.MSG_MF_ERROR_INTEGRITY, indent); + return null; + } + + // we definitely should not update certifications of revoked keys, so just leave it. + if (isRevoked) { + continue; + } + + // add shiny new user id certificate + modifiedPublicKey = PGPPublicKey.removeCertification( + modifiedPublicKey, userId, currentCert); + PGPSignature newCert = generateUserIdSignature( + masterPrivateKey, masterPublicKey, userId, true, flags, expiry); + modifiedPublicKey = PGPPublicKey.addCertification( + modifiedPublicKey, userId, newCert); + ok = true; + + } + + if (!ok) { + // might happen, theoretically, if there is a key with no uid.. + log.add(LogLevel.ERROR, LogType.MSG_MF_ERROR_INTEGRITY, indent); + return null; + } + + return modifiedPublicKey; + + } + private static PGPSignature generateUserIdSignature( - PGPPrivateKey masterPrivateKey, PGPPublicKey pKey, String userId, boolean primary, int flags) + PGPPrivateKey masterPrivateKey, PGPPublicKey pKey, String userId, boolean primary, + int flags, long expiry) throws IOException, PGPException, SignatureException { PGPContentSignerBuilder signerBuilder = new JcaPGPContentSignerBuilder( pKey.getAlgorithm(), PGPUtil.SHA1) .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME); PGPSignatureGenerator sGen = new PGPSignatureGenerator(signerBuilder); - PGPSignatureSubpacketGenerator subHashedPacketsGen = new PGPSignatureSubpacketGenerator(); - subHashedPacketsGen.setSignatureCreationTime(false, new Date()); - subHashedPacketsGen.setPreferredSymmetricAlgorithms(true, PREFERRED_SYMMETRIC_ALGORITHMS); - subHashedPacketsGen.setPreferredHashAlgorithms(true, PREFERRED_HASH_ALGORITHMS); - subHashedPacketsGen.setPreferredCompressionAlgorithms(true, PREFERRED_COMPRESSION_ALGORITHMS); - subHashedPacketsGen.setPrimaryUserID(false, primary); - subHashedPacketsGen.setKeyFlags(false, flags); - sGen.setHashedSubpackets(subHashedPacketsGen.generate()); + + PGPSignatureSubpacketGenerator hashedPacketsGen = new PGPSignatureSubpacketGenerator(); + { + hashedPacketsGen.setSignatureCreationTime(false, new Date()); + hashedPacketsGen.setPreferredSymmetricAlgorithms(true, PREFERRED_SYMMETRIC_ALGORITHMS); + hashedPacketsGen.setPreferredHashAlgorithms(true, PREFERRED_HASH_ALGORITHMS); + hashedPacketsGen.setPreferredCompressionAlgorithms(true, PREFERRED_COMPRESSION_ALGORITHMS); + hashedPacketsGen.setPrimaryUserID(false, primary); + hashedPacketsGen.setKeyFlags(false, flags); + if (expiry > 0) { + hashedPacketsGen.setKeyExpirationTime( + false, expiry - pKey.getCreationTime().getTime() / 1000); + } + } + + sGen.setHashedSubpackets(hashedPacketsGen.generate()); sGen.init(PGPSignature.POSITIVE_CERTIFICATION, masterPrivateKey); return sGen.generateCertification(userId, pKey); } @@ -784,14 +901,15 @@ public class PgpKeyOperation { throws IOException, PGPException, SignatureException { // date for signing - Date todayDate = new Date(); + Date creationTime = new Date(); + PGPSignatureSubpacketGenerator unhashedPacketsGen = new PGPSignatureSubpacketGenerator(); // If this key can sign, we need a primary key binding signature if ((flags & KeyFlags.SIGN_DATA) > 0) { // cross-certify signing keys PGPSignatureSubpacketGenerator subHashedPacketsGen = new PGPSignatureSubpacketGenerator(); - subHashedPacketsGen.setSignatureCreationTime(false, todayDate); + subHashedPacketsGen.setSignatureCreationTime(false, creationTime); PGPContentSignerBuilder signerBuilder = new JcaPGPContentSignerBuilder( pKey.getAlgorithm(), PGPUtil.SHA1) .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME); @@ -805,13 +923,12 @@ public class PgpKeyOperation { PGPSignatureSubpacketGenerator hashedPacketsGen; { hashedPacketsGen = new PGPSignatureSubpacketGenerator(); - hashedPacketsGen.setSignatureCreationTime(false, todayDate); + hashedPacketsGen.setSignatureCreationTime(false, creationTime); hashedPacketsGen.setKeyFlags(false, flags); - } - - if (expiry > 0) { - long creationTime = pKey.getCreationTime().getTime() / 1000; - hashedPacketsGen.setKeyExpirationTime(false, expiry - creationTime); + if (expiry > 0) { + hashedPacketsGen.setKeyExpirationTime(false, + expiry - pKey.getCreationTime().getTime() / 1000); + } } PGPContentSignerBuilder signerBuilder = new JcaPGPContentSignerBuilder( diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/OperationResultParcel.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/OperationResultParcel.java index 01c7611ff..138283b81 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/OperationResultParcel.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/OperationResultParcel.java @@ -359,12 +359,15 @@ public class OperationResultParcel implements Parcelable { MSG_MF_ERROR_FINGERPRINT (R.string.msg_mf_error_fingerprint), MSG_MF_ERROR_KEYID (R.string.msg_mf_error_keyid), MSG_MF_ERROR_INTEGRITY (R.string.msg_mf_error_integrity), + MSG_MF_ERROR_NO_CERTIFY (R.string.msg_cr_error_no_certify), MSG_MF_ERROR_NOEXIST_PRIMARY (R.string.msg_mf_error_noexist_primary), MSG_MF_ERROR_NOEXIST_REVOKE (R.string.msg_mf_error_noexist_revoke), MSG_MF_ERROR_NULL_EXPIRY (R.string.msg_mf_error_null_expiry), + MSG_MF_ERROR_PAST_EXPIRY(R.string.msg_mf_error_past_expiry), MSG_MF_ERROR_REVOKED_PRIMARY (R.string.msg_mf_error_revoked_primary), MSG_MF_ERROR_PGP (R.string.msg_mf_error_pgp), MSG_MF_ERROR_SIG (R.string.msg_mf_error_sig), + MSG_MF_MASTER (R.string.msg_mf_master), MSG_MF_PASSPHRASE (R.string.msg_mf_passphrase), MSG_MF_PRIMARY_REPLACE_OLD (R.string.msg_mf_primary_replace_old), MSG_MF_PRIMARY_NEW (R.string.msg_mf_primary_new), @@ -372,7 +375,6 @@ public class OperationResultParcel implements Parcelable { MSG_MF_SUBKEY_MISSING (R.string.msg_mf_subkey_missing), MSG_MF_SUBKEY_NEW_ID (R.string.msg_mf_subkey_new_id), MSG_MF_SUBKEY_NEW (R.string.msg_mf_subkey_new), - MSG_MF_SUBKEY_PAST_EXPIRY (R.string.msg_mf_subkey_past_expiry), MSG_MF_SUBKEY_REVOKE (R.string.msg_mf_subkey_revoke), MSG_MF_SUCCESS (R.string.msg_mf_success), MSG_MF_UID_ADD (R.string.msg_mf_uid_add), @@ -436,6 +438,15 @@ public class OperationResultParcel implements Parcelable { mParcels.add(new OperationResultParcel.LogEntryParcel(level, type, indent, (Object[]) null)); } + public boolean containsType(LogType type) { + for(LogEntryParcel entry : new IterableIterator(mParcels.iterator())) { + if (entry.mType == type) { + return true; + } + } + return false; + } + public boolean containsWarnings() { for(LogEntryParcel entry : new IterableIterator(mParcels.iterator())) { if (entry.mLevel == LogLevel.WARN || entry.mLevel == LogLevel.ERROR) { diff --git a/OpenKeychain/src/main/res/values-es/strings.xml b/OpenKeychain/src/main/res/values-es/strings.xml index 8b8af788d..0bd3a48c5 100644 --- a/OpenKeychain/src/main/res/values-es/strings.xml +++ b/OpenKeychain/src/main/res/values-es/strings.xml @@ -588,7 +588,7 @@ ¡Intentó operar sobre una subclave ausente %s! Generando nueva subclave %2$s de %1$s bits Nueva identidad de subclave: %s - ¡La fecha de expiración no puede ser del pasado! + ¡La fecha de expiración no puede ser del pasado! Revocando subclave %s Juego de claves modificado con éxito Añadiendo identidad de usuario %s diff --git a/OpenKeychain/src/main/res/values-fr/strings.xml b/OpenKeychain/src/main/res/values-fr/strings.xml index 35e4c5766..3f570d144 100644 --- a/OpenKeychain/src/main/res/values-fr/strings.xml +++ b/OpenKeychain/src/main/res/values-fr/strings.xml @@ -588,7 +588,7 @@ Une action a été tentée sur la sous-clef manquante %s ! Génération d\'une nouvelle sous-clef %2$s de %1$s bit ID de la nouvelle sous-clef : %s - La date d\'expiration ne peut pas être dans le passé ! + La date d\'expiration ne peut pas être dans le passé ! Révocation de la sous-clef %s Trousseau modifié avec succès Ajout de l\'ID d\'utilisateur %s diff --git a/OpenKeychain/src/main/res/values-it/strings.xml b/OpenKeychain/src/main/res/values-it/strings.xml index 2a5131bcf..590532d4d 100644 --- a/OpenKeychain/src/main/res/values-it/strings.xml +++ b/OpenKeychain/src/main/res/values-it/strings.xml @@ -528,7 +528,7 @@ Tentativo di operare su sottochiave mancante %s! Generazione nuovi %1$s bit %2$s sottochiave Nuovo ID sottochiave: %s - La data di scadenza non può essere passata! + La data di scadenza non può essere passata! Revoca sottochiave %s Portachiavi modificato con successo Aggiunta id utente %s diff --git a/OpenKeychain/src/main/res/values-ja/strings.xml b/OpenKeychain/src/main/res/values-ja/strings.xml index f0cb9d47b..6794deba9 100644 --- a/OpenKeychain/src/main/res/values-ja/strings.xml +++ b/OpenKeychain/src/main/res/values-ja/strings.xml @@ -574,7 +574,7 @@ 遺失した副鍵 %s の操作をしようとした! 新しい %1$s ビットの %2$s 副鍵の生成中 新しい副鍵 ID: %s - 期限切れ日を過去にはできません! + 期限切れ日を過去にはできません! 副鍵 %s を破棄中 鍵輪の変更に成功 ユーザID %s を追加中 diff --git a/OpenKeychain/src/main/res/values-ru/strings.xml b/OpenKeychain/src/main/res/values-ru/strings.xml index 4f32bea3a..2ac766466 100644 --- a/OpenKeychain/src/main/res/values-ru/strings.xml +++ b/OpenKeychain/src/main/res/values-ru/strings.xml @@ -384,7 +384,7 @@ Внутренняя ошибка PGP! Ошибка подписи! Изменение пароля - Срок годности не может быть в прошлом! + Срок годности не может быть в прошлом! Связка успешно изменена Добавление id %s Изменение основного uid на %s diff --git a/OpenKeychain/src/main/res/values/strings.xml b/OpenKeychain/src/main/res/values/strings.xml index f603663e8..8aa10943d 100644 --- a/OpenKeychain/src/main/res/values/strings.xml +++ b/OpenKeychain/src/main/res/values/strings.xml @@ -639,12 +639,14 @@ Actual key fingerprint does not match the expected one! No key ID. This is an internal error, please file a bug report! Internal error, integrity check failed! + No master certificate found to modify! Bad primary user id specified! Bad user id for revocation specified! Revoked user ids cannot be primary! Expiry time cannot be "same as before" on subkey creation. This is a programming error, please file a bug report! PGP internal exception! Signature exception! + Modifying master certifications Changing passphrase Replacing certificate of previous primary user id Generating new certificate for new primary user id @@ -652,7 +654,7 @@ Tried to operate on missing subkey %s! Generating new %1$s bit %2$s subkey New subkey ID: %s - Expiry date cannot be in the past! + Expiry date cannot be in the past! Revoking subkey %s Keyring successfully modified Adding user id %s -- cgit v1.2.3 From de0d95432e40b9ed436c3509364ba49d2e487723 Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Sat, 16 Aug 2014 06:40:03 +0200 Subject: typed expected failures and a couple minor things --- .../keychain/pgp/PgpKeyOperationTest.java | 53 ++++++++++++++-------- .../keychain/pgp/PgpKeyOperation.java | 6 +-- .../keychain/service/OperationResultParcel.java | 5 +- OpenKeychain/src/main/res/values-cs/strings.xml | 1 - OpenKeychain/src/main/res/values-de/strings.xml | 1 - OpenKeychain/src/main/res/values-es/strings.xml | 3 +- OpenKeychain/src/main/res/values-fr/strings.xml | 3 +- OpenKeychain/src/main/res/values-it/strings.xml | 3 +- OpenKeychain/src/main/res/values-ja/strings.xml | 3 +- OpenKeychain/src/main/res/values-nl/strings.xml | 1 - OpenKeychain/src/main/res/values-pl/strings.xml | 1 - OpenKeychain/src/main/res/values-ru/strings.xml | 1 - OpenKeychain/src/main/res/values-sl/strings.xml | 1 - OpenKeychain/src/main/res/values-uk/strings.xml | 1 - OpenKeychain/src/main/res/values/strings.xml | 4 +- 15 files changed, 47 insertions(+), 40 deletions(-) diff --git a/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperationTest.java b/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperationTest.java index c46e3ee15..88cf260fb 100644 --- a/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperationTest.java +++ b/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperationTest.java @@ -19,6 +19,7 @@ import org.spongycastle.bcpg.sig.KeyFlags; import org.spongycastle.jce.provider.BouncyCastleProvider; import org.spongycastle.openpgp.PGPSignature; import org.spongycastle.bcpg.PublicKeyAlgorithmTags; +import org.sufficientlysecure.keychain.service.OperationResultParcel.LogType; import org.sufficientlysecure.keychain.service.OperationResultParcel.OperationLog; import org.sufficientlysecure.keychain.service.OperationResults.EditKeyResult; import org.sufficientlysecure.keychain.service.SaveKeyringParcel; @@ -238,7 +239,7 @@ public class PgpKeyOperationTest { parcel.mFingerprint = ring.getFingerprint(); assertModifyFailure("keyring modification with bad master key id should fail", - ring, parcel); + ring, parcel, LogType.MSG_MF_ERROR_KEYID); } { @@ -248,7 +249,7 @@ public class PgpKeyOperationTest { parcel.mFingerprint = ring.getFingerprint(); assertModifyFailure("keyring modification with null master key id should fail", - ring, parcel); + ring, parcel, LogType.MSG_MF_ERROR_KEYID); } { @@ -259,7 +260,7 @@ public class PgpKeyOperationTest { parcel.mFingerprint[5] += 1; assertModifyFailure("keyring modification with bad fingerprint should fail", - ring, parcel); + ring, parcel, LogType.MSG_MF_ERROR_FINGERPRINT); } { @@ -268,7 +269,7 @@ public class PgpKeyOperationTest { parcel.mFingerprint = null; assertModifyFailure("keyring modification with null fingerprint should fail", - ring, parcel); + ring, parcel, LogType.MSG_MF_ERROR_FINGERPRINT); } { @@ -278,7 +279,7 @@ public class PgpKeyOperationTest { } assertModifyFailure("keyring modification with bad passphrase should fail", - ring, parcel, badphrase); + ring, parcel, badphrase, LogType.MSG_MF_UNLOCK_ERROR); } } @@ -331,7 +332,8 @@ public class PgpKeyOperationTest { parcel.reset(); parcel.mAddSubKeys.add(new SubkeyAdd( PublicKeyAlgorithmTags.RSA_GENERAL, new Random().nextInt(512), KeyFlags.SIGN_DATA, 0L)); - assertModifyFailure("creating a subkey with keysize < 512 should fail", ring, parcel); + assertModifyFailure("creating a subkey with keysize < 512 should fail", ring, parcel, + LogType.MSG_CR_ERROR_KEYSIZE_512); } @@ -339,7 +341,8 @@ public class PgpKeyOperationTest { parcel.reset(); parcel.mAddSubKeys.add(new SubkeyAdd(PublicKeyAlgorithmTags.RSA_GENERAL, 1024, KeyFlags.SIGN_DATA, new Date().getTime()/1000-10)); - assertModifyFailure("creating subkey with past expiry date should fail", ring, parcel); + assertModifyFailure("creating subkey with past expiry date should fail", ring, parcel, + LogType.MSG_MF_ERROR_PAST_EXPIRY); } } @@ -436,14 +439,16 @@ public class PgpKeyOperationTest { parcel.reset(); parcel.mChangeSubKeys.add(new SubkeyChange(keyId, null, new Date().getTime()/1000-10)); - assertModifyFailure("setting subkey expiry to a past date should fail", ring, parcel); + assertModifyFailure("setting subkey expiry to a past date should fail", ring, parcel, + LogType.MSG_MF_ERROR_PAST_EXPIRY); } { // modifying nonexistent subkey should fail parcel.reset(); parcel.mChangeSubKeys.add(new SubkeyChange(123, null, null)); - assertModifyFailure("modifying non-existent subkey should fail", ring, parcel); + assertModifyFailure("modifying non-existent subkey should fail", ring, parcel, + LogType.MSG_MF_ERROR_SUBKEY_MISSING); } } @@ -529,21 +534,24 @@ public class PgpKeyOperationTest { parcel.mRevokeUserIds.add("pink"); parcel.mChangeSubKeys.add(new SubkeyChange(keyId, KeyFlags.CERTIFY_OTHER, null)); - assertModifyFailure("master key modification with all user ids revoked should fail", ring, parcel); + assertModifyFailure("master key modification with all user ids revoked should fail", ring, parcel, + LogType.MSG_MF_ERROR_MASTER_NONE); } { // any flag not including CERTIFY_OTHER should fail parcel.reset(); parcel.mChangeSubKeys.add(new SubkeyChange(keyId, KeyFlags.SIGN_DATA, null)); - assertModifyFailure("setting master key flags without certify should fail", ring, parcel); + assertModifyFailure("setting master key flags without certify should fail", ring, parcel, + LogType.MSG_MF_ERROR_NO_CERTIFY); } { // a past expiry should fail parcel.reset(); parcel.mChangeSubKeys.add(new SubkeyChange(keyId, null, new Date().getTime()/1000-10)); - assertModifyFailure("setting subkey expiry to a past date should fail", ring, parcel); + assertModifyFailure("setting subkey expiry to a past date should fail", ring, parcel, + LogType.MSG_MF_ERROR_PAST_EXPIRY); } } @@ -663,7 +671,8 @@ public class PgpKeyOperationTest { parcel.reset(); parcel.mChangePrimaryUserId = uid; - assertModifyFailure("setting primary user id to a revoked user id should fail", modified, parcel); + assertModifyFailure("setting primary user id to a revoked user id should fail", modified, parcel, + LogType.MSG_MF_ERROR_REVOKED_PRIMARY); } @@ -705,7 +714,8 @@ public class PgpKeyOperationTest { parcel.reset(); parcel.mRevokeUserIds.add("nonexistent"); - assertModifyFailure("revocation of nonexistent user id should fail", modified, parcel); + assertModifyFailure("revocation of nonexistent user id should fail", modified, parcel, + LogType.MSG_MF_ERROR_NOEXIST_REVOKE); } } @@ -715,7 +725,8 @@ public class PgpKeyOperationTest { { parcel.mAddUserIds.add(""); - assertModifyFailure("adding an empty user id should fail", ring, parcel); + assertModifyFailure("adding an empty user id should fail", ring, parcel, + LogType.MSG_MF_UID_ERROR_EMPTY); } parcel.reset(); @@ -784,7 +795,7 @@ public class PgpKeyOperationTest { } assertModifyFailure("changing primary user id to a non-existent one should fail", - ring, parcel); + ring, parcel, LogType.MSG_MF_ERROR_NOEXIST_PRIMARY); } // check for revoked primary user id already done in revoke test @@ -878,17 +889,21 @@ public class PgpKeyOperationTest { } private void assertModifyFailure(String reason, UncachedKeyRing ring, - SaveKeyringParcel parcel, String passphrase) throws Exception { + SaveKeyringParcel parcel, String passphrase, LogType expected) + throws Exception { CanonicalizedSecretKeyRing secretRing = new CanonicalizedSecretKeyRing(ring.getEncoded(), false, 0); EditKeyResult result = op.modifySecretKeyRing(secretRing, parcel, passphrase); Assert.assertFalse(reason, result.success()); Assert.assertNull(reason, result.getRing()); + Assert.assertTrue(reason + "(with correct error)", + result.getLog().containsType(expected)); } - private void assertModifyFailure(String reason, UncachedKeyRing ring, SaveKeyringParcel parcel) + private void assertModifyFailure(String reason, UncachedKeyRing ring, SaveKeyringParcel parcel, + LogType expected) throws Exception { CanonicalizedSecretKeyRing secretRing = new CanonicalizedSecretKeyRing(ring.getEncoded(), false, 0); @@ -896,6 +911,8 @@ public class PgpKeyOperationTest { Assert.assertFalse(reason, result.success()); Assert.assertNull(reason, result.getRing()); + Assert.assertTrue(reason + "(with correct error)", + result.getLog().containsType(expected)); } 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 710bd42c6..3fcabf636 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java @@ -557,7 +557,7 @@ public class PgpKeyOperation { PGPSecretKey sKey = sKR.getSecretKey(change.mKeyId); if (sKey == null) { - log.add(LogLevel.ERROR, LogType.MSG_MF_SUBKEY_MISSING, + log.add(LogLevel.ERROR, LogType.MSG_MF_ERROR_SUBKEY_MISSING, indent + 1, PgpKeyHelper.convertKeyIdToHex(change.mKeyId)); return new EditKeyResult(EditKeyResult.RESULT_ERROR, log, null); } @@ -638,7 +638,7 @@ public class PgpKeyOperation { PGPSecretKey sKey = sKR.getSecretKey(revocation); if (sKey == null) { - log.add(LogLevel.ERROR, LogType.MSG_MF_SUBKEY_MISSING, + log.add(LogLevel.ERROR, LogType.MSG_MF_ERROR_SUBKEY_MISSING, indent+1, PgpKeyHelper.convertKeyIdToHex(revocation)); return new EditKeyResult(EditKeyResult.RESULT_ERROR, log, null); } @@ -813,7 +813,7 @@ public class PgpKeyOperation { if (!ok) { // might happen, theoretically, if there is a key with no uid.. - log.add(LogLevel.ERROR, LogType.MSG_MF_ERROR_INTEGRITY, indent); + log.add(LogLevel.ERROR, LogType.MSG_MF_ERROR_MASTER_NONE, indent); return null; } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/OperationResultParcel.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/OperationResultParcel.java index 138283b81..8e7dcd4aa 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/OperationResultParcel.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/OperationResultParcel.java @@ -359,20 +359,21 @@ public class OperationResultParcel implements Parcelable { MSG_MF_ERROR_FINGERPRINT (R.string.msg_mf_error_fingerprint), MSG_MF_ERROR_KEYID (R.string.msg_mf_error_keyid), MSG_MF_ERROR_INTEGRITY (R.string.msg_mf_error_integrity), + MSG_MF_ERROR_MASTER_NONE(R.string.msg_mf_error_master_none), MSG_MF_ERROR_NO_CERTIFY (R.string.msg_cr_error_no_certify), MSG_MF_ERROR_NOEXIST_PRIMARY (R.string.msg_mf_error_noexist_primary), MSG_MF_ERROR_NOEXIST_REVOKE (R.string.msg_mf_error_noexist_revoke), MSG_MF_ERROR_NULL_EXPIRY (R.string.msg_mf_error_null_expiry), MSG_MF_ERROR_PAST_EXPIRY(R.string.msg_mf_error_past_expiry), - MSG_MF_ERROR_REVOKED_PRIMARY (R.string.msg_mf_error_revoked_primary), MSG_MF_ERROR_PGP (R.string.msg_mf_error_pgp), + MSG_MF_ERROR_REVOKED_PRIMARY (R.string.msg_mf_error_revoked_primary), MSG_MF_ERROR_SIG (R.string.msg_mf_error_sig), + MSG_MF_ERROR_SUBKEY_MISSING(R.string.msg_mf_error_subkey_missing), MSG_MF_MASTER (R.string.msg_mf_master), MSG_MF_PASSPHRASE (R.string.msg_mf_passphrase), MSG_MF_PRIMARY_REPLACE_OLD (R.string.msg_mf_primary_replace_old), MSG_MF_PRIMARY_NEW (R.string.msg_mf_primary_new), MSG_MF_SUBKEY_CHANGE (R.string.msg_mf_subkey_change), - MSG_MF_SUBKEY_MISSING (R.string.msg_mf_subkey_missing), MSG_MF_SUBKEY_NEW_ID (R.string.msg_mf_subkey_new_id), MSG_MF_SUBKEY_NEW (R.string.msg_mf_subkey_new), MSG_MF_SUBKEY_REVOKE (R.string.msg_mf_subkey_revoke), diff --git a/OpenKeychain/src/main/res/values-cs/strings.xml b/OpenKeychain/src/main/res/values-cs/strings.xml index dd4d41650..c9e7875d8 100644 --- a/OpenKeychain/src/main/res/values-cs/strings.xml +++ b/OpenKeychain/src/main/res/values-cs/strings.xml @@ -62,7 +62,6 @@ Cache hesel Komprimovat zprávu Komprimovat soubor - Vynutit staré OpenPGPv3 podpisy ID klíče Vytvořeno Expirace diff --git a/OpenKeychain/src/main/res/values-de/strings.xml b/OpenKeychain/src/main/res/values-de/strings.xml index 74282fd29..18e6cf585 100644 --- a/OpenKeychain/src/main/res/values-de/strings.xml +++ b/OpenKeychain/src/main/res/values-de/strings.xml @@ -94,7 +94,6 @@ Passwort-Cache Nachrichten-Komprimierung Datei-Komprimierung - Erzwinge alte OpenPGPv3-Signaturen Schlüsselserver Schlüssel-ID Erstellungsdatum diff --git a/OpenKeychain/src/main/res/values-es/strings.xml b/OpenKeychain/src/main/res/values-es/strings.xml index 0bd3a48c5..1770ec896 100644 --- a/OpenKeychain/src/main/res/values-es/strings.xml +++ b/OpenKeychain/src/main/res/values-es/strings.xml @@ -97,7 +97,6 @@ Caché de frase de contraseña Compresión de mensaje Compresión de archivo - Forzar firmas OpenPGPv3 antiguas Servidores de claves ID de clave Creación @@ -585,7 +584,7 @@ Reemplazando certificado de la anterior identidad de usuario primaria Generando nuevo certificado para nueva identidad de usuario primaria Modificando subclave %s - ¡Intentó operar sobre una subclave ausente %s! + ¡Intentó operar sobre una subclave ausente %s! Generando nueva subclave %2$s de %1$s bits Nueva identidad de subclave: %s ¡La fecha de expiración no puede ser del pasado! diff --git a/OpenKeychain/src/main/res/values-fr/strings.xml b/OpenKeychain/src/main/res/values-fr/strings.xml index 3f570d144..3b356fd18 100644 --- a/OpenKeychain/src/main/res/values-fr/strings.xml +++ b/OpenKeychain/src/main/res/values-fr/strings.xml @@ -97,7 +97,6 @@ Cache de la phrase de passe Compression des messages Compression des fichiers - Forcer les anciennes signatures OpenPGP v3 Serveurs de clefs ID de le clef Création @@ -585,7 +584,7 @@ Remplacement du certificat de l\'ID d\'utilisateur principal précédent Génération d\'un nouveau certificat pour le nouvel ID d\'utilisateur principal Modification de la sous-clef %s - Une action a été tentée sur la sous-clef manquante %s ! + Une action a été tentée sur la sous-clef manquante %s ! Génération d\'une nouvelle sous-clef %2$s de %1$s bit ID de la nouvelle sous-clef : %s La date d\'expiration ne peut pas être dans le passé ! diff --git a/OpenKeychain/src/main/res/values-it/strings.xml b/OpenKeychain/src/main/res/values-it/strings.xml index 590532d4d..33bb4ce9d 100644 --- a/OpenKeychain/src/main/res/values-it/strings.xml +++ b/OpenKeychain/src/main/res/values-it/strings.xml @@ -77,7 +77,6 @@ Cache Frase di Accesso Compressione Messaggio Compressione File - Forza vecchie Firme OpenPGPv3 Server Chiavi ID Chiave Creazione @@ -525,7 +524,7 @@ Sostituzione certificato del ID utente primario precedente Generazione di un nuovo certificato per il nuovo ID utente primario Modifica sottochiave %s - Tentativo di operare su sottochiave mancante %s! + Tentativo di operare su sottochiave mancante %s! Generazione nuovi %1$s bit %2$s sottochiave Nuovo ID sottochiave: %s La data di scadenza non può essere passata! diff --git a/OpenKeychain/src/main/res/values-ja/strings.xml b/OpenKeychain/src/main/res/values-ja/strings.xml index 6794deba9..deb7715e1 100644 --- a/OpenKeychain/src/main/res/values-ja/strings.xml +++ b/OpenKeychain/src/main/res/values-ja/strings.xml @@ -97,7 +97,6 @@ パスフレーズキャッシュ メッセージの圧縮 ファイルの圧縮 - 強制的に古いOpenPGPV3形式の署名にする 鍵サーバ 鍵ID 生成 @@ -571,7 +570,7 @@ 以前の主ユーザIDで証明を入れ替え中 新しい主ユーザIDで新しい証明を生成中 副鍵 %s を変更中 - 遺失した副鍵 %s の操作をしようとした! + 遺失した副鍵 %s の操作をしようとした! 新しい %1$s ビットの %2$s 副鍵の生成中 新しい副鍵 ID: %s 期限切れ日を過去にはできません! diff --git a/OpenKeychain/src/main/res/values-nl/strings.xml b/OpenKeychain/src/main/res/values-nl/strings.xml index f225e204a..a49a51671 100644 --- a/OpenKeychain/src/main/res/values-nl/strings.xml +++ b/OpenKeychain/src/main/res/values-nl/strings.xml @@ -71,7 +71,6 @@ Wachtwoordcache Berichtcompressie Bestandscompressie - Forceer oude OpenPGPv3 Handtekeningen Sleutelservers Sleutel-id Aanmaak diff --git a/OpenKeychain/src/main/res/values-pl/strings.xml b/OpenKeychain/src/main/res/values-pl/strings.xml index a4a66e30c..7b12653c6 100644 --- a/OpenKeychain/src/main/res/values-pl/strings.xml +++ b/OpenKeychain/src/main/res/values-pl/strings.xml @@ -59,7 +59,6 @@ Bufor haseł Kompresja wiadomości Kompresja plików - Wymuś stare podpisy OpenPGPv3 Serwery kluczy Identyfikator klucza Utworzenia diff --git a/OpenKeychain/src/main/res/values-ru/strings.xml b/OpenKeychain/src/main/res/values-ru/strings.xml index 2ac766466..1b2aa7dc6 100644 --- a/OpenKeychain/src/main/res/values-ru/strings.xml +++ b/OpenKeychain/src/main/res/values-ru/strings.xml @@ -74,7 +74,6 @@ Помнить пароль Сжатие сообщения Сжатие файла - Использовать OpenPGPv3 подписи (устар.) Серверы ключей ID ключа Создан diff --git a/OpenKeychain/src/main/res/values-sl/strings.xml b/OpenKeychain/src/main/res/values-sl/strings.xml index 0de5e97ea..e98e207b5 100644 --- a/OpenKeychain/src/main/res/values-sl/strings.xml +++ b/OpenKeychain/src/main/res/values-sl/strings.xml @@ -74,7 +74,6 @@ Hranjenje gesla v spominu Stiskanje sporočil Stiskanje datotek - Vsili stare podpise OpenPGPv3 Strežniki ID ključa Ustvarjanje diff --git a/OpenKeychain/src/main/res/values-uk/strings.xml b/OpenKeychain/src/main/res/values-uk/strings.xml index 7a4c79ddb..401b8ae83 100644 --- a/OpenKeychain/src/main/res/values-uk/strings.xml +++ b/OpenKeychain/src/main/res/values-uk/strings.xml @@ -74,7 +74,6 @@ Кеш парольної фрази Стиснення повідомлення Стиснення файлу - Примусово старі підписи OpenPGPv3 Сервери ключів ІД ключа Створення diff --git a/OpenKeychain/src/main/res/values/strings.xml b/OpenKeychain/src/main/res/values/strings.xml index 8aa10943d..f6c208ca0 100644 --- a/OpenKeychain/src/main/res/values/strings.xml +++ b/OpenKeychain/src/main/res/values/strings.xml @@ -639,7 +639,7 @@ Actual key fingerprint does not match the expected one! No key ID. This is an internal error, please file a bug report! Internal error, integrity check failed! - No master certificate found to modify! + No master certificate found to operate on! (All revoked?) Bad primary user id specified! Bad user id for revocation specified! Revoked user ids cannot be primary! @@ -651,7 +651,7 @@ Replacing certificate of previous primary user id Generating new certificate for new primary user id Modifying subkey %s - Tried to operate on missing subkey %s! + Tried to operate on missing subkey %s! Generating new %1$s bit %2$s subkey New subkey ID: %s Expiry date cannot be in the past! -- cgit v1.2.3 From 6e84c728011cebe44c3b2ef6c6cacee64098c16a Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Sat, 16 Aug 2014 06:49:46 +0200 Subject: tests: more expected error types --- .../keychain/pgp/PgpKeyOperationTest.java | 42 ++++++++++++++++++---- .../keychain/pgp/PgpKeyOperation.java | 3 +- 2 files changed, 37 insertions(+), 8 deletions(-) diff --git a/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperationTest.java b/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperationTest.java index 88cf260fb..10a42b80f 100644 --- a/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperationTest.java +++ b/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperationTest.java @@ -118,7 +118,8 @@ public class PgpKeyOperationTest { parcel.mAddUserIds.add("shy"); parcel.mNewPassphrase = passphrase; - assertFailure("creating ring with < 512 bytes keysize should fail", parcel); + assertFailure("creating ring with < 512 bytes keysize should fail", parcel, + LogType.MSG_CR_ERROR_KEYSIZE_512); } { @@ -128,7 +129,19 @@ public class PgpKeyOperationTest { parcel.mAddUserIds.add("shy"); parcel.mNewPassphrase = passphrase; - assertFailure("creating ring with ElGamal master key should fail", parcel); + assertFailure("creating ring with ElGamal master key should fail", parcel, + LogType.MSG_CR_ERROR_MASTER_ELGAMAL); + } + + { + parcel.reset(); + parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( + PublicKeyAlgorithmTags.RSA_GENERAL, 1024, KeyFlags.CERTIFY_OTHER, null)); + parcel.mAddUserIds.add("lotus"); + parcel.mNewPassphrase = passphrase; + + assertFailure("creating master key with null expiry should fail", parcel, + LogType.MSG_CR_ERROR_NULL_EXPIRY); } { @@ -138,7 +151,8 @@ public class PgpKeyOperationTest { parcel.mAddUserIds.add("shy"); parcel.mNewPassphrase = passphrase; - assertFailure("creating ring with bad algorithm choice should fail", parcel); + assertFailure("creating ring with bad algorithm choice should fail", parcel, + LogType.MSG_CR_ERROR_UNKNOWN_ALGO); } { @@ -148,7 +162,8 @@ public class PgpKeyOperationTest { parcel.mAddUserIds.add("shy"); parcel.mNewPassphrase = passphrase; - assertFailure("creating ring with non-certifying master key should fail", parcel); + assertFailure("creating ring with non-certifying master key should fail", parcel, + LogType.MSG_CR_ERROR_NO_CERTIFY); } { @@ -157,7 +172,8 @@ public class PgpKeyOperationTest { PublicKeyAlgorithmTags.RSA_GENERAL, 1024, KeyFlags.CERTIFY_OTHER, 0L)); parcel.mNewPassphrase = passphrase; - assertFailure("creating ring without user ids should fail", parcel); + assertFailure("creating ring without user ids should fail", parcel, + LogType.MSG_CR_ERROR_NO_USER_ID); } { @@ -165,7 +181,8 @@ public class PgpKeyOperationTest { parcel.mAddUserIds.add("shy"); parcel.mNewPassphrase = passphrase; - assertFailure("creating ring without subkeys should fail", parcel); + assertFailure("creating ring with no master key should fail", parcel, + LogType.MSG_CR_ERROR_NO_MASTER); } } @@ -337,6 +354,15 @@ public class PgpKeyOperationTest { } + { + parcel.reset(); + parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( + PublicKeyAlgorithmTags.RSA_GENERAL, 1024, KeyFlags.SIGN_DATA, null)); + + assertModifyFailure("creating master key with null expiry should fail", ring, parcel, + LogType.MSG_MF_ERROR_NULL_EXPIRY); + } + { // a past expiry should fail parcel.reset(); parcel.mAddSubKeys.add(new SubkeyAdd(PublicKeyAlgorithmTags.RSA_GENERAL, 1024, KeyFlags.SIGN_DATA, @@ -879,12 +905,14 @@ public class PgpKeyOperationTest { Assert.assertEquals(java.util.Arrays.toString(expected), java.util.Arrays.toString(actual)); } - private void assertFailure(String reason, SaveKeyringParcel parcel) { + private void assertFailure(String reason, SaveKeyringParcel parcel, LogType expected) { EditKeyResult result = op.createSecretKeyRing(parcel); Assert.assertFalse(reason, result.success()); Assert.assertNull(reason, result.getRing()); + Assert.assertTrue(reason + "(with correct error)", + result.getLog().containsType(expected)); } 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 3fcabf636..26ad69eb7 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java @@ -728,8 +728,8 @@ public class PgpKeyOperation { sKR = PGPSecretKeyRing.copyWithNewPassword(sKR, keyDecryptor, keyEncryptorNew); } - // This one must only be thrown by } catch (IOException e) { + Log.e(Constants.TAG, "encountered IOException while modifying key", e); log.add(LogLevel.ERROR, LogType.MSG_MF_ERROR_ENCODE, indent+1); return new EditKeyResult(EditKeyResult.RESULT_ERROR, log, null); } catch (PGPException e) { @@ -737,6 +737,7 @@ public class PgpKeyOperation { log.add(LogLevel.ERROR, LogType.MSG_MF_ERROR_PGP, indent+1); return new EditKeyResult(EditKeyResult.RESULT_ERROR, log, null); } catch (SignatureException e) { + Log.e(Constants.TAG, "encountered SignatureException while modifying key", e); log.add(LogLevel.ERROR, LogType.MSG_MF_ERROR_SIG, indent+1); return new EditKeyResult(EditKeyResult.RESULT_ERROR, log, null); } -- cgit v1.2.3 From 7c7ba217148d0560744fd417c4e76726df3ffec7 Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Sat, 16 Aug 2014 07:06:07 +0200 Subject: tests: add test for master key revocation --- .../keychain/pgp/PgpKeyOperationTest.java | 25 ++++++++++++++++++++++ .../keychain/pgp/UncachedKeyRing.java | 3 +-- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperationTest.java b/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperationTest.java index 10a42b80f..deec1cf3a 100644 --- a/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperationTest.java +++ b/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperationTest.java @@ -582,6 +582,31 @@ public class PgpKeyOperationTest { } + @Test + public void testMasterRevoke() throws Exception { + + parcel.reset(); + parcel.mRevokeSubKeys.add(ring.getMasterKeyId()); + + UncachedKeyRing modified = applyModificationWithChecks(parcel, ring, onlyA, onlyB); + + Assert.assertEquals("no extra packets in original", 0, onlyA.size()); + Assert.assertEquals("exactly one extra packet in modified", 1, onlyB.size()); + + Packet p; + + p = new BCPGInputStream(new ByteArrayInputStream(onlyB.get(0).buf)).readPacket(); + Assert.assertTrue("first new packet must be secret subkey", p instanceof SignaturePacket); + Assert.assertEquals("signature type must be subkey binding certificate", + PGPSignature.KEY_REVOCATION, ((SignaturePacket) p).getSignatureType()); + Assert.assertEquals("signature must have been created by master key", + ring.getMasterKeyId(), ((SignaturePacket) p).getKeyID()); + + Assert.assertTrue("subkey must actually be revoked", + modified.getPublicKey().isRevoked()); + + } + @Test public void testSubkeyRevoke() throws Exception { diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedKeyRing.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedKeyRing.java index 0a59ba9f8..ababd39e0 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedKeyRing.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedKeyRing.java @@ -271,13 +271,12 @@ public class UncachedKeyRing { for (PGPSignature zert : new IterableIterator(masterKey.getKeySignatures())) { int type = zert.getSignatureType(); - // Disregard certifications on user ids, we will deal with those later + // These should most definitely not be here... if (type == PGPSignature.NO_CERTIFICATION || type == PGPSignature.DEFAULT_CERTIFICATION || type == PGPSignature.CASUAL_CERTIFICATION || type == PGPSignature.POSITIVE_CERTIFICATION || type == PGPSignature.CERTIFICATION_REVOCATION) { - // These should not be here... log.add(LogLevel.WARN, LogType.MSG_KC_REVOKE_BAD_TYPE_UID, indent); modified = PGPPublicKey.removeCertification(modified, zert); badCerts += 1; -- cgit v1.2.3 From 2497722b48561ac1031f7ed9c0cb0526f694b1b3 Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Sat, 16 Aug 2014 07:12:37 +0200 Subject: fix travis tests (more), minor comment edits --- .../org/sufficientlysecure/keychain/pgp/PgpKeyOperationTest.java | 4 ++-- .../keychain/pgp/UncachedKeyringCanonicalizeTest.java | 3 +++ .../sufficientlysecure/keychain/pgp/UncachedKeyringMergeTest.java | 3 +++ .../java/org/sufficientlysecure/keychain/pgp/UncachedKeyRing.java | 7 +++---- 4 files changed, 11 insertions(+), 6 deletions(-) diff --git a/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperationTest.java b/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperationTest.java index deec1cf3a..fef325a1a 100644 --- a/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperationTest.java +++ b/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperationTest.java @@ -53,9 +53,9 @@ public class PgpKeyOperationTest { ArrayList onlyA = new ArrayList(); ArrayList onlyB = new ArrayList(); - @BeforeClass public static void setUpOnce() throws Exception { + @BeforeClass + public static void setUpOnce() throws Exception { Security.insertProviderAt(new BouncyCastleProvider(), 1); - ShadowLog.stream = System.out; { diff --git a/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/UncachedKeyringCanonicalizeTest.java b/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/UncachedKeyringCanonicalizeTest.java index 588dac17b..6e3a9814e 100644 --- a/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/UncachedKeyringCanonicalizeTest.java +++ b/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/UncachedKeyringCanonicalizeTest.java @@ -13,6 +13,7 @@ import org.spongycastle.bcpg.PacketTags; import org.spongycastle.bcpg.UserIDPacket; import org.spongycastle.bcpg.sig.KeyFlags; import org.spongycastle.bcpg.PublicKeyAlgorithmTags; +import org.spongycastle.jce.provider.BouncyCastleProvider; import org.spongycastle.openpgp.PGPPrivateKey; import org.spongycastle.openpgp.PGPPublicKey; import org.spongycastle.openpgp.PGPSecretKey; @@ -34,6 +35,7 @@ import org.sufficientlysecure.keychain.support.KeyringTestingHelper; import org.sufficientlysecure.keychain.support.KeyringTestingHelper.RawPacket; import java.io.ByteArrayInputStream; +import java.security.Security; import java.util.ArrayList; import java.util.Date; import java.util.Iterator; @@ -60,6 +62,7 @@ public class UncachedKeyringCanonicalizeTest { @BeforeClass public static void setUpOnce() throws Exception { + Security.insertProviderAt(new BouncyCastleProvider(), 1); ShadowLog.stream = System.out; SaveKeyringParcel parcel = new SaveKeyringParcel(); diff --git a/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/UncachedKeyringMergeTest.java b/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/UncachedKeyringMergeTest.java index 603b1e6d1..428206c97 100644 --- a/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/UncachedKeyringMergeTest.java +++ b/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/UncachedKeyringMergeTest.java @@ -10,6 +10,7 @@ import org.robolectric.shadows.ShadowLog; import org.spongycastle.bcpg.PacketTags; import org.spongycastle.bcpg.sig.KeyFlags; import org.spongycastle.bcpg.PublicKeyAlgorithmTags; +import org.spongycastle.jce.provider.BouncyCastleProvider; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.service.OperationResultParcel; import org.sufficientlysecure.keychain.service.OperationResults.EditKeyResult; @@ -18,6 +19,7 @@ import org.sufficientlysecure.keychain.support.KeyringTestingHelper; import org.sufficientlysecure.keychain.support.KeyringTestingHelper.RawPacket; import org.sufficientlysecure.keychain.util.ProgressScaler; +import java.security.Security; import java.util.ArrayList; import java.util.Iterator; @@ -59,6 +61,7 @@ public class UncachedKeyringMergeTest { @BeforeClass public static void setUpOnce() throws Exception { + Security.insertProviderAt(new BouncyCastleProvider(), 1); ShadowLog.stream = System.out; { diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedKeyRing.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedKeyRing.java index ababd39e0..90abf05f5 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedKeyRing.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedKeyRing.java @@ -217,8 +217,7 @@ public class UncachedKeyRing { aos.close(); } - /** "Canonicalizes" a public key, removing inconsistencies in the process. This variant can be - * applied to public keyrings only. + /** "Canonicalizes" a public key, removing inconsistencies in the process. * * More specifically: * - Remove all non-verifying self-certificates @@ -235,9 +234,9 @@ public class UncachedKeyRing { * - If the key is a secret key, remove all certificates by foreign keys * - If no valid user id remains, log an error and return null * - * This operation writes an OperationLog which can be used as part of a OperationResultParcel. + * This operation writes an OperationLog which can be used as part of an OperationResultParcel. * - * @return A canonicalized key, or null on fatal error + * @return A canonicalized key, or null on fatal error (log will include a message in this case) * */ @SuppressWarnings("ConstantConditions") -- cgit v1.2.3 From 188eeb79c9f2eb536d73efee09a3698750c87dab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Sat, 16 Aug 2014 12:13:30 +0200 Subject: Fix and simplify in OperationResultParcel --- .../keychain/service/OperationResults.java | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/OperationResults.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/OperationResults.java index 1c83873be..1fc496082 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/OperationResults.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/OperationResults.java @@ -28,6 +28,7 @@ import com.github.johnpersano.supertoasts.SuperToast; import com.github.johnpersano.supertoasts.util.OnClickWrapper; import com.github.johnpersano.supertoasts.util.Style; +import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.pgp.CanonicalizedKeyRing; import org.sufficientlysecure.keychain.pgp.KeyRing; @@ -190,13 +191,13 @@ public abstract class OperationResults { public static class EditKeyResult extends OperationResultParcel { private transient UncachedKeyRing mRing; - public final Long mRingMasterKeyId; + public final long mRingMasterKeyId; public EditKeyResult(int result, OperationLog log, UncachedKeyRing ring) { super(result, log); mRing = ring; - mRingMasterKeyId = ring != null ? ring.getMasterKeyId() : null; + mRingMasterKeyId = ring != null ? ring.getMasterKeyId() : Constants.key.none; } public UncachedKeyRing getRing() { @@ -205,18 +206,13 @@ public abstract class OperationResults { public EditKeyResult(Parcel source) { super(source); - mRingMasterKeyId = source.readInt() != 0 ? source.readLong() : null; + mRingMasterKeyId = source.readLong(); } @Override public void writeToParcel(Parcel dest, int flags) { super.writeToParcel(dest, flags); - if (mRingMasterKeyId == null) { - dest.writeInt(0); - } else { - dest.writeInt(1); - dest.writeLong(mRingMasterKeyId); - } + dest.writeLong(mRingMasterKeyId); } public static Creator CREATOR = new Creator() { @@ -234,12 +230,12 @@ public abstract class OperationResults { public static class SaveKeyringResult extends OperationResultParcel { - public final Long mRingMasterKeyId; + public final long mRingMasterKeyId; public SaveKeyringResult(int result, OperationLog log, CanonicalizedKeyRing ring) { super(result, log); - mRingMasterKeyId = ring != null ? ring.getMasterKeyId() : null; + mRingMasterKeyId = ring != null ? ring.getMasterKeyId() : Constants.key.none; } // Some old key was updated -- cgit v1.2.3 From 474fc50b80ae57e3434c2d748895eda28d2ef548 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Sat, 16 Aug 2014 12:24:46 +0200 Subject: Always return a SaveKeyringResult from saving --- .../sufficientlysecure/keychain/service/KeychainIntentService.java | 7 ++++++- .../org/sufficientlysecure/keychain/ui/CreateKeyFinalFragment.java | 4 +--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java index 83ade9b9b..036251cd6 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java @@ -411,7 +411,12 @@ public class KeychainIntentService extends IntentService // If the edit operation didn't succeed, exit here if (!modifyResult.success()) { - sendMessageToHandler(KeychainIntentServiceHandler.MESSAGE_OKAY, modifyResult); + // always return SaveKeyringResult, so create one out of the EditKeyResult + SaveKeyringResult saveResult = new SaveKeyringResult( + SaveKeyringResult.RESULT_ERROR, + modifyResult.getLog(), + null); + sendMessageToHandler(KeychainIntentServiceHandler.MESSAGE_OKAY, saveResult); return; } 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 3fc9e7f31..461d25928 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyFinalFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyFinalFragment.java @@ -125,10 +125,9 @@ public class CreateKeyFinalFragment extends Fragment { Intent intent = new Intent(getActivity(), KeychainIntentService.class); intent.setAction(KeychainIntentService.ACTION_SAVE_KEYRING); - // Message is received after importing is done in KeychainIntentService KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler( getActivity(), - getString(R.string.progress_importing), + getString(R.string.progress_building_key), ProgressDialog.STYLE_HORIZONTAL) { public void handleMessage(Message message) { // handle messages by standard KeychainIntentServiceHandler first @@ -211,7 +210,6 @@ public class CreateKeyFinalFragment extends Fragment { intent.putExtra(KeychainIntentService.EXTRA_DATA, data); - // Message is received after uploading is done in KeychainIntentService KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler(getActivity(), getString(R.string.progress_uploading), ProgressDialog.STYLE_HORIZONTAL) { public void handleMessage(Message message) { -- cgit v1.2.3 From 4d698c896a69148fbae4cccf7528ed9974449482 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Sat, 16 Aug 2014 12:28:49 +0200 Subject: Fix expiry when adding subkeys --- .../org/sufficientlysecure/keychain/ui/CreateKeyFinalFragment.java | 6 +++--- .../java/org/sufficientlysecure/keychain/ui/EditKeyFragment.java | 1 - .../keychain/ui/dialog/AddSubkeyDialogFragment.java | 4 ++-- 3 files changed, 5 insertions(+), 6 deletions(-) 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 461d25928..22c0f7767 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyFinalFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyFinalFragment.java @@ -168,9 +168,9 @@ public class CreateKeyFinalFragment extends Fragment { Bundle data = new Bundle(); SaveKeyringParcel parcel = new SaveKeyringParcel(); - parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd(PublicKeyAlgorithmTags.RSA_GENERAL, 4096, KeyFlags.CERTIFY_OTHER, null)); - parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd(PublicKeyAlgorithmTags.RSA_GENERAL, 4096, KeyFlags.SIGN_DATA, null)); - parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd(PublicKeyAlgorithmTags.RSA_GENERAL, 4096, KeyFlags.ENCRYPT_COMMS | KeyFlags.ENCRYPT_STORAGE, null)); + parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd(PublicKeyAlgorithmTags.RSA_GENERAL, 4096, KeyFlags.CERTIFY_OTHER, 0L)); + parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd(PublicKeyAlgorithmTags.RSA_GENERAL, 4096, KeyFlags.SIGN_DATA, 0L)); + parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd(PublicKeyAlgorithmTags.RSA_GENERAL, 4096, KeyFlags.ENCRYPT_COMMS | KeyFlags.ENCRYPT_STORAGE, 0L)); String userId = KeyRing.createUserId(mName, mEmail, null); parcel.mAddUserIds.add(userId); parcel.mChangePrimaryUserId = userId; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyFragment.java index b18d1626a..409953ad5 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyFragment.java @@ -503,7 +503,6 @@ public class EditKeyFragment extends LoaderFragment implements private void save(String passphrase) { Log.d(Constants.TAG, "mSaveKeyringParcel:\n" + mSaveKeyringParcel.toString()); - // Message is received after importing is done in KeychainIntentService KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler( getActivity(), getString(R.string.progress_saving), 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 cb31978e9..2b8768596 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 @@ -183,9 +183,9 @@ public class AddSubkeyDialogFragment extends DialogFragment { flags |= KeyFlags.AUTHENTICATION; } - Long expiry; + long expiry; if (mNoExpiryCheckBox.isChecked()) { - expiry = null; + expiry = 0L; } else { Calendar selectedCal = Calendar.getInstance(TimeZone.getTimeZone("UTC")); //noinspection ResourceType -- cgit v1.2.3 From c1f9c5e4b5378f6c98f96e85ae82137c93f5009f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Sat, 16 Aug 2014 13:30:13 +0200 Subject: Fix ElGamal key creation, SUBKEY_BINDING cert must use algo of master key --- .../main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 26ad69eb7..ccd83c334 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java @@ -933,7 +933,7 @@ public class PgpKeyOperation { } PGPContentSignerBuilder signerBuilder = new JcaPGPContentSignerBuilder( - pKey.getAlgorithm(), PGPUtil.SHA1) + masterPrivateKey.getPublicKeyPacket().getAlgorithm(), PGPUtil.SHA1) .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME); PGPSignatureGenerator sGen = new PGPSignatureGenerator(signerBuilder); sGen.init(PGPSignature.SUBKEY_BINDING, masterPrivateKey); -- cgit v1.2.3 From ccf58a92fa915f948709fffde17f834bb1a88cdd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Sat, 16 Aug 2014 13:42:55 +0200 Subject: Fix flags UI in add subkey dialog --- .../keychain/ui/adapter/SubkeysAddedAdapter.java | 2 +- .../ui/dialog/AddSubkeyDialogFragment.java | 47 ++++++++++++++++++++-- 2 files changed, 44 insertions(+), 5 deletions(-) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/SubkeysAddedAdapter.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/SubkeysAddedAdapter.java index be2e17c63..7e0027ddc 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/SubkeysAddedAdapter.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/SubkeysAddedAdapter.java @@ -106,7 +106,7 @@ public class SubkeysAddedAdapter extends ArrayAdapter choices = new ArrayList(); choices.add(new Choice(PublicKeyAlgorithmTags.DSA, getResources().getString( R.string.dsa))); - if (!willBeMasterKey) { + if (!mWillBeMasterKey) { choices.add(new Choice(PublicKeyAlgorithmTags.ELGAMAL_ENCRYPT, getResources().getString( R.string.elgamal))); } @@ -246,7 +248,7 @@ public class AddSubkeyDialogFragment extends DialogFragment { mAlgorithmSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { @Override public void onItemSelected(AdapterView parent, View view, int position, long id) { - setKeyLengthSpinnerValuesForAlgorithm(((Choice) parent.getSelectedItem()).getId()); + updateUiForAlgorithm(((Choice) parent.getSelectedItem()).getId()); setCustomKeyVisibility(); setOkButtonAvailability(alertDialog); @@ -348,7 +350,7 @@ public class AddSubkeyDialogFragment extends DialogFragment { } } - private void setKeyLengthSpinnerValuesForAlgorithm(int algorithmId) { + private void updateUiForAlgorithm(int algorithmId) { final ArrayAdapter keySizeAdapter = (ArrayAdapter) mKeySizeSpinner.getAdapter(); final Object selectedItem = mKeySizeSpinner.getSelectedItem(); keySizeAdapter.clear(); @@ -356,14 +358,51 @@ public class AddSubkeyDialogFragment extends DialogFragment { case PublicKeyAlgorithmTags.RSA_GENERAL: replaceArrayAdapterContent(keySizeAdapter, R.array.rsa_key_size_spinner_values); mCustomKeyInfoTextView.setText(getResources().getString(R.string.key_size_custom_info_rsa)); + // allowed flags: + mFlagSign.setEnabled(true); + mFlagEncrypt.setEnabled(true); + mFlagAuthenticate.setEnabled(true); + + if (mWillBeMasterKey) { + mFlagCertify.setEnabled(true); + + mFlagCertify.setChecked(true); + mFlagSign.setChecked(false); + mFlagEncrypt.setChecked(false); + } else { + mFlagCertify.setEnabled(false); + + mFlagCertify.setChecked(false); + mFlagSign.setChecked(true); + mFlagEncrypt.setChecked(true); + } + mFlagAuthenticate.setChecked(false); break; case PublicKeyAlgorithmTags.ELGAMAL_ENCRYPT: replaceArrayAdapterContent(keySizeAdapter, R.array.elgamal_key_size_spinner_values); mCustomKeyInfoTextView.setText(""); // ElGamal does not support custom key length + // allowed flags: + mFlagCertify.setChecked(false); + mFlagCertify.setEnabled(false); + mFlagSign.setChecked(false); + mFlagSign.setEnabled(false); + mFlagEncrypt.setChecked(true); + mFlagEncrypt.setEnabled(true); + mFlagAuthenticate.setChecked(false); + mFlagAuthenticate.setEnabled(false); break; case PublicKeyAlgorithmTags.DSA: replaceArrayAdapterContent(keySizeAdapter, R.array.dsa_key_size_spinner_values); mCustomKeyInfoTextView.setText(getResources().getString(R.string.key_size_custom_info_dsa)); + // allowed flags: + mFlagCertify.setChecked(false); + mFlagCertify.setEnabled(false); + mFlagSign.setChecked(true); + mFlagSign.setEnabled(true); + mFlagEncrypt.setChecked(false); + mFlagEncrypt.setEnabled(false); + mFlagAuthenticate.setChecked(false); + mFlagAuthenticate.setEnabled(false); break; } keySizeAdapter.notifyDataSetChanged(); -- cgit v1.2.3 From f2069020029f138ae02a7a9f2697f5737f568268 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Sat, 16 Aug 2014 16:17:46 +0200 Subject: Fixing date picker issues --- .../ui/dialog/AddSubkeyDialogFragment.java | 5 +- .../ui/dialog/EditSubkeyExpiryDialogFragment.java | 64 +++++++++++++++------- 2 files changed, 47 insertions(+), 22 deletions(-) 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 c35afd4fe..56c004f97 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 @@ -189,10 +189,13 @@ public class AddSubkeyDialogFragment extends DialogFragment { if (mNoExpiryCheckBox.isChecked()) { expiry = 0L; } else { - Calendar selectedCal = Calendar.getInstance(TimeZone.getTimeZone("UTC")); + Calendar selectedCal = Calendar.getInstance(TimeZone.getDefault()); //noinspection ResourceType selectedCal.set(mExpiryDatePicker.getYear(), mExpiryDatePicker.getMonth(), mExpiryDatePicker.getDayOfMonth()); + // date picker uses default time zone, we need to convert to UTC + selectedCal.setTimeZone(TimeZone.getTimeZone("UTC")); + expiry = selectedCal.getTime().getTime() / 1000; } 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 276ad15fc..fde8a3477 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 @@ -48,7 +48,6 @@ public class EditSubkeyExpiryDialogFragment extends DialogFragment { public static final String MESSAGE_DATA_EXPIRY_DATE = "expiry_date"; private Messenger mMessenger; - private Calendar mExpiryCal; private DatePicker mDatePicker; @@ -75,15 +74,17 @@ public class EditSubkeyExpiryDialogFragment extends DialogFragment { public Dialog onCreateDialog(Bundle savedInstanceState) { final Activity activity = getActivity(); mMessenger = getArguments().getParcelable(ARG_MESSENGER); - Date creationDate = new Date(getArguments().getLong(ARG_CREATION_DATE) * 1000); - Date expiryDate = new Date(getArguments().getLong(ARG_EXPIRY_DATE) * 1000); + long creationDate = getArguments().getLong(ARG_CREATION_DATE); + long expiryDate = getArguments().getLong(ARG_EXPIRY_DATE); Calendar creationCal = Calendar.getInstance(TimeZone.getTimeZone("UTC")); - creationCal.setTime(creationDate); - mExpiryCal = Calendar.getInstance(TimeZone.getTimeZone("UTC")); - mExpiryCal.setTime(expiryDate); + creationCal.setTime(new Date(creationDate * 1000)); + final Calendar expiryCal = Calendar.getInstance(TimeZone.getTimeZone("UTC")); + expiryCal.setTime(new Date(expiryDate * 1000)); - Log.d(Constants.TAG, "onCreateDialog"); + // date picker works with default time zone, we need to convert from UTC to default timezone + creationCal.setTimeZone(TimeZone.getDefault()); + expiryCal.setTimeZone(TimeZone.getDefault()); // Explicitly not using DatePickerDialog here! // DatePickerDialog is difficult to customize and has many problems (see old git versions) @@ -97,15 +98,40 @@ public class EditSubkeyExpiryDialogFragment extends DialogFragment { mDatePicker = (DatePicker) view.findViewById(R.id.edit_subkey_expiry_date_picker); + // set default date + if (expiryDate == 0L) { + // if key has no expiry, set it to creation date +1 day + + Calendar creationCalPlusOne = (Calendar) creationCal.clone(); + creationCalPlusOne.add(Calendar.DAY_OF_MONTH, 1); + mDatePicker.init( + creationCalPlusOne.get(Calendar.YEAR), + creationCalPlusOne.get(Calendar.MONTH), + creationCalPlusOne.get(Calendar.DAY_OF_MONTH), + null + ); + } else { + // set date picker to current expiry date +1 day + + Calendar expiryCalPlusOne = (Calendar) expiryCal.clone(); + expiryCalPlusOne.add(Calendar.DAY_OF_MONTH, 1); + mDatePicker.init( + expiryCalPlusOne.get(Calendar.YEAR), + expiryCalPlusOne.get(Calendar.MONTH), + expiryCalPlusOne.get(Calendar.DAY_OF_MONTH), + null + ); + } + if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.HONEYCOMB) { // will crash with IllegalArgumentException if we set a min date - // that is not before expiry - if (creationCal.before(mExpiryCal)) { + // that is before creation date + if (expiryDate == 0L || creationCal.before(expiryCal)) { mDatePicker.setMinDate(creationCal.getTime().getTime() + DateUtils.DAY_IN_MILLIS); } else { - // when creation date isn't available - mDatePicker.setMinDate(mExpiryCal.getTime().getTime() + // set min to expiry date + mDatePicker.setMinDate(expiryCal.getTime().getTime() + DateUtils.DAY_IN_MILLIS); } } @@ -115,19 +141,15 @@ public class EditSubkeyExpiryDialogFragment extends DialogFragment { public void onClick(DialogInterface dialog, int id) { dismiss(); - Calendar selectedCal = Calendar.getInstance(TimeZone.getTimeZone("UTC")); + Calendar selectedCal = Calendar.getInstance(TimeZone.getDefault()); //noinspection ResourceType selectedCal.set(mDatePicker.getYear(), mDatePicker.getMonth(), mDatePicker.getDayOfMonth()); + // date picker uses default time zone, we need to convert to UTC + selectedCal.setTimeZone(TimeZone.getTimeZone("UTC")); - if (mExpiryCal != null) { - long numDays = (selectedCal.getTimeInMillis() / 86400000) - - (mExpiryCal.getTimeInMillis() / 86400000); - if (numDays > 0) { - Bundle data = new Bundle(); - data.putSerializable(MESSAGE_DATA_EXPIRY_DATE, selectedCal.getTime().getTime() / 1000); - sendMessageToHandler(MESSAGE_NEW_EXPIRY_DATE, data); - } - } else { + long numDays = (selectedCal.getTimeInMillis() / 86400000) + - (expiryCal.getTimeInMillis() / 86400000); + if (numDays > 0) { Bundle data = new Bundle(); data.putSerializable(MESSAGE_DATA_EXPIRY_DATE, selectedCal.getTime().getTime() / 1000); sendMessageToHandler(MESSAGE_NEW_EXPIRY_DATE, data); -- cgit v1.2.3 From 62b7d2d7d80f7ecfa17d6a8484fecae21f42a92d Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Sat, 16 Aug 2014 19:30:32 +0200 Subject: fix small log format string mistake for adding subkeys closes #768 --- .../main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) 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 ccd83c334..5da8c5f6a 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java @@ -658,7 +658,8 @@ public class PgpKeyOperation { progress(R.string.progress_modify_subkeyadd, (i-1) * (100 / saveParcel.mAddSubKeys.size())); SaveKeyringParcel.SubkeyAdd add = saveParcel.mAddSubKeys.get(i); - log.add(LogLevel.INFO, LogType.MSG_MF_SUBKEY_NEW, indent); + log.add(LogLevel.INFO, LogType.MSG_MF_SUBKEY_NEW, indent, add.mKeysize, + PgpKeyHelper.getAlgorithmInfo(add.mAlgorithm) ); if (add.mExpiry == null) { log.add(LogLevel.ERROR, LogType.MSG_MF_ERROR_NULL_EXPIRY, indent +1); -- cgit v1.2.3 From e38f6a2a46c5b246f2f6a60d497f85f95c10908a Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Sat, 16 Aug 2014 19:45:14 +0200 Subject: use correct algorithm for signatures (actually fix heterogeneous subkeys) --- .../org/sufficientlysecure/keychain/pgp/PgpKeyOperationTest.java | 4 ++-- .../java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperationTest.java b/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperationTest.java index fef325a1a..00bbafed1 100644 --- a/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperationTest.java +++ b/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperationTest.java @@ -74,9 +74,9 @@ public class PgpKeyOperationTest { parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( PublicKeyAlgorithmTags.RSA_GENERAL, 1024, KeyFlags.CERTIFY_OTHER, 0L)); parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( - PublicKeyAlgorithmTags.RSA_GENERAL, 1024, KeyFlags.SIGN_DATA, 0L)); + PublicKeyAlgorithmTags.DSA, 1024, KeyFlags.SIGN_DATA, 0L)); parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( - PublicKeyAlgorithmTags.RSA_GENERAL, 1024, KeyFlags.ENCRYPT_COMMS, 0L)); + PublicKeyAlgorithmTags.ELGAMAL_ENCRYPT, 1024, KeyFlags.ENCRYPT_COMMS, 0L)); parcel.mAddUserIds.add("twi"); parcel.mAddUserIds.add("pink"); 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 5da8c5f6a..222c47215 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java @@ -828,7 +828,7 @@ public class PgpKeyOperation { int flags, long expiry) throws IOException, PGPException, SignatureException { PGPContentSignerBuilder signerBuilder = new JcaPGPContentSignerBuilder( - pKey.getAlgorithm(), PGPUtil.SHA1) + masterPrivateKey.getPublicKeyPacket().getAlgorithm(), PGPUtil.SHA1) .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME); PGPSignatureGenerator sGen = new PGPSignatureGenerator(signerBuilder); @@ -855,7 +855,7 @@ public class PgpKeyOperation { PGPPrivateKey masterPrivateKey, PGPPublicKey pKey, String userId) throws IOException, PGPException, SignatureException { PGPContentSignerBuilder signerBuilder = new JcaPGPContentSignerBuilder( - pKey.getAlgorithm(), PGPUtil.SHA1) + masterPrivateKey.getPublicKeyPacket().getAlgorithm(), PGPUtil.SHA1) .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME); PGPSignatureGenerator sGen = new PGPSignatureGenerator(signerBuilder); PGPSignatureSubpacketGenerator subHashedPacketsGen = new PGPSignatureSubpacketGenerator(); @@ -869,7 +869,7 @@ public class PgpKeyOperation { PGPPublicKey masterPublicKey, PGPPrivateKey masterPrivateKey, PGPPublicKey pKey) throws IOException, PGPException, SignatureException { PGPContentSignerBuilder signerBuilder = new JcaPGPContentSignerBuilder( - pKey.getAlgorithm(), PGPUtil.SHA1) + masterPublicKey.getAlgorithm(), PGPUtil.SHA1) .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME); PGPSignatureGenerator sGen = new PGPSignatureGenerator(signerBuilder); PGPSignatureSubpacketGenerator subHashedPacketsGen = new PGPSignatureSubpacketGenerator(); @@ -934,7 +934,7 @@ public class PgpKeyOperation { } PGPContentSignerBuilder signerBuilder = new JcaPGPContentSignerBuilder( - masterPrivateKey.getPublicKeyPacket().getAlgorithm(), PGPUtil.SHA1) + masterPublicKey.getAlgorithm(), PGPUtil.SHA1) .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME); PGPSignatureGenerator sGen = new PGPSignatureGenerator(signerBuilder); sGen.init(PGPSignature.SUBKEY_BINDING, masterPrivateKey); -- cgit v1.2.3 From c00343d516f1afc2d4e062d30eba07689fc3092a Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Sat, 16 Aug 2014 21:04:43 +0200 Subject: modify*Key: improve handling of passphrase modification (add tests, too) --- .../keychain/pgp/PgpKeyOperationTest.java | 100 ++++++++++++++++++--- .../keychain/pgp/PgpKeyOperation.java | 50 ++++++++++- .../keychain/service/OperationResultParcel.java | 4 + OpenKeychain/src/main/res/values/strings.xml | 6 +- 4 files changed, 143 insertions(+), 17 deletions(-) diff --git a/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperationTest.java b/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperationTest.java index 00bbafed1..964512617 100644 --- a/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperationTest.java +++ b/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperationTest.java @@ -45,7 +45,7 @@ import java.util.Random; public class PgpKeyOperationTest { static UncachedKeyRing staticRing; - static String passphrase; + final static String passphrase = genPassphrase(); UncachedKeyRing ring; PgpKeyOperation op; @@ -58,18 +58,6 @@ public class PgpKeyOperationTest { Security.insertProviderAt(new BouncyCastleProvider(), 1); ShadowLog.stream = System.out; - { - String chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ123456789!@#$%^&*()-_="; - Random r = new Random(); - StringBuilder passbuilder = new StringBuilder(); - // 20% chance for an empty passphrase - for(int i = 0, j = r.nextInt(10) > 2 ? r.nextInt(20) : 0; i < j; i++) { - passbuilder.append(chars.charAt(r.nextInt(chars.length()))); - } - passphrase = passbuilder.toString(); - System.out.println("Passphrase is '" + passphrase + "'"); - } - SaveKeyringParcel parcel = new SaveKeyringParcel(); parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( PublicKeyAlgorithmTags.RSA_GENERAL, 1024, KeyFlags.CERTIFY_OTHER, 0L)); @@ -853,12 +841,79 @@ public class PgpKeyOperationTest { } + @Test + public void testPassphraseChange() throws Exception { + + // change passphrase to empty + parcel.mNewPassphrase = ""; + UncachedKeyRing modified = applyModificationWithChecks(parcel, ring, onlyA, onlyB); + + Assert.assertEquals("exactly three packets should have been modified (the secret keys)", + 3, onlyB.size()); + + // remember secret key packet with no passphrase for later + RawPacket sKeyNoPassphrase = onlyB.get(1); + Assert.assertEquals("extracted packet should be a secret subkey", + PacketTags.SECRET_SUBKEY, sKeyNoPassphrase.tag); + + // modify keyring, change to non-empty passphrase + String otherPassphrase = genPassphrase(true); + parcel.mNewPassphrase = otherPassphrase; + modified = applyModificationWithChecks(parcel, modified, onlyA, onlyB, ""); + + RawPacket sKeyWithPassphrase = onlyB.get(1); + Assert.assertEquals("extracted packet should be a secret subkey", + PacketTags.SECRET_SUBKEY, sKeyNoPassphrase.tag); + + String otherPassphrase2 = genPassphrase(true); + parcel.mNewPassphrase = otherPassphrase2; + { + // if we replace a secret key with one without passphrase + modified = KeyringTestingHelper.removePacket(modified, sKeyNoPassphrase.position); + modified = KeyringTestingHelper.injectPacket(modified, sKeyNoPassphrase.buf, sKeyNoPassphrase.position); + + // we should still be able to modify it (and change its passphrase) without errors + PgpKeyOperation op = new PgpKeyOperation(null); + CanonicalizedSecretKeyRing secretRing = new CanonicalizedSecretKeyRing(modified.getEncoded(), false, 0); + EditKeyResult result = op.modifySecretKeyRing(secretRing, parcel, otherPassphrase); + Assert.assertTrue("key modification must succeed", result.success()); + Assert.assertFalse("log must not contain a warning", + result.getLog().containsWarnings()); + Assert.assertTrue("log must contain an empty passphrase retry notice", + result.getLog().containsType(LogType.MSG_MF_PASSPHRASE_EMPTY_RETRY)); + modified = result.getRing(); + } + + { + // if we add one subkey with a different passphrase, that should produce a warning but also work + modified = KeyringTestingHelper.removePacket(modified, sKeyWithPassphrase.position); + modified = KeyringTestingHelper.injectPacket(modified, sKeyWithPassphrase.buf, sKeyWithPassphrase.position); + + PgpKeyOperation op = new PgpKeyOperation(null); + CanonicalizedSecretKeyRing secretRing = new CanonicalizedSecretKeyRing(modified.getEncoded(), false, 0); + EditKeyResult result = op.modifySecretKeyRing(secretRing, parcel, otherPassphrase2); + Assert.assertTrue("key modification must succeed", result.success()); + Assert.assertTrue("log must contain a warning", + result.getLog().containsWarnings()); + Assert.assertTrue("log must contain a failed passphrase change warning", + result.getLog().containsType(LogType.MSG_MF_PASSPHRASE_FAIL)); + } + + } private static UncachedKeyRing applyModificationWithChecks(SaveKeyringParcel parcel, UncachedKeyRing ring, ArrayList onlyA, ArrayList onlyB) { - return applyModificationWithChecks(parcel, ring, onlyA, onlyB, true, true); + return applyModificationWithChecks(parcel, ring, onlyA, onlyB, passphrase, true, true); + } + + private static UncachedKeyRing applyModificationWithChecks(SaveKeyringParcel parcel, + UncachedKeyRing ring, + ArrayList onlyA, + ArrayList onlyB, + String passphrase) { + return applyModificationWithChecks(parcel, ring, onlyA, onlyB, passphrase, true, true); } // applies a parcel modification while running some integrity checks @@ -866,6 +921,7 @@ public class PgpKeyOperationTest { UncachedKeyRing ring, ArrayList onlyA, ArrayList onlyB, + String passphrase, boolean canonicalize, boolean constantCanonicalize) { @@ -980,4 +1036,20 @@ public class PgpKeyOperationTest { } + private static String genPassphrase() { + return genPassphrase(false); + } + + private static String genPassphrase(boolean noEmpty) { + String chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ123456789!@#$%^&*()-_="; + Random r = new Random(); + StringBuilder passbuilder = new StringBuilder(); + // 20% chance for an empty passphrase + for(int i = 0, j = noEmpty || r.nextInt(10) > 2 ? r.nextInt(20)+1 : 0; i < j; i++) { + passbuilder.append(chars.charAt(r.nextInt(chars.length()))); + } + System.out.println("Generated passphrase: '" + passbuilder.toString() + "'"); + return passbuilder.toString(); + } + } 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 222c47215..cdd2eacc0 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java @@ -698,7 +698,7 @@ public class PgpKeyOperation { // Build key encrypter and decrypter based on passphrase PBESecretKeyEncryptor keyEncryptor = new JcePBESecretKeyEncryptorBuilder( PGPEncryptedData.CAST5, sha1Calc) - .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build("".toCharArray()); + .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(passphrase.toCharArray()); sKey = new PGPSecretKey(keyPair.getPrivateKey(), pKey, sha1Calc, false, keyEncryptor); @@ -716,6 +716,8 @@ public class PgpKeyOperation { if (saveParcel.mNewPassphrase != null) { progress(R.string.progress_modify_passphrase, 90); log.add(LogLevel.INFO, LogType.MSG_MF_PASSPHRASE, indent); + indent += 1; + PGPDigestCalculator sha1Calc = new JcaPGPDigestCalculatorProviderBuilder().build() .get(HashAlgorithmTags.SHA1); PBESecretKeyDecryptor keyDecryptor = new JcePBESecretKeyDecryptorBuilder().setProvider( @@ -726,7 +728,51 @@ public class PgpKeyOperation { .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build( saveParcel.mNewPassphrase.toCharArray()); - sKR = PGPSecretKeyRing.copyWithNewPassword(sKR, keyDecryptor, keyEncryptorNew); + // noinspection unchecked + for (PGPSecretKey sKey : new IterableIterator(sKR.getSecretKeys())) { + log.add(LogLevel.DEBUG, LogType.MSG_MF_PASSPHRASE_KEY, indent, + PgpKeyHelper.convertKeyIdToHex(sKey.getKeyID())); + + boolean ok = false; + + try { + // try to set new passphrase + sKey = PGPSecretKey.copyWithNewPassword(sKey, keyDecryptor, keyEncryptorNew); + ok = true; + } catch (PGPException e) { + + // if this is the master key, error! + if (sKey.getKeyID() == masterPublicKey.getKeyID()) { + log.add(LogLevel.ERROR, LogType.MSG_MF_ERROR_PASSPHRASE_MASTER, indent+1); + return new EditKeyResult(EditKeyResult.RESULT_ERROR, log, null); + } + + // being in here means decrypt failed, likely due to a bad passphrase try + // again with an empty passphrase, maybe we can salvage this + try { + log.add(LogLevel.DEBUG, LogType.MSG_MF_PASSPHRASE_EMPTY_RETRY, indent+1); + PBESecretKeyDecryptor emptyDecryptor = + new JcePBESecretKeyDecryptorBuilder().setProvider( + Constants.BOUNCY_CASTLE_PROVIDER_NAME).build("".toCharArray()); + sKey = PGPSecretKey.copyWithNewPassword(sKey, emptyDecryptor, keyEncryptorNew); + ok = true; + } catch (PGPException e2) { + // non-fatal but not ok, handled below + } + } + + if (!ok) { + // for a subkey, it's merely a warning + log.add(LogLevel.WARN, LogType.MSG_MF_PASSPHRASE_FAIL, indent+1, + PgpKeyHelper.convertKeyIdToHex(sKey.getKeyID())); + continue; + } + + sKR = PGPSecretKeyRing.insertSecretKey(sKR, sKey); + + } + + indent -= 1; } } catch (IOException e) { diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/OperationResultParcel.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/OperationResultParcel.java index 8e7dcd4aa..26fe63550 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/OperationResultParcel.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/OperationResultParcel.java @@ -364,6 +364,7 @@ public class OperationResultParcel implements Parcelable { MSG_MF_ERROR_NOEXIST_PRIMARY (R.string.msg_mf_error_noexist_primary), MSG_MF_ERROR_NOEXIST_REVOKE (R.string.msg_mf_error_noexist_revoke), MSG_MF_ERROR_NULL_EXPIRY (R.string.msg_mf_error_null_expiry), + MSG_MF_ERROR_PASSPHRASE_MASTER(R.string.msg_mf_error_passphrase_master), MSG_MF_ERROR_PAST_EXPIRY(R.string.msg_mf_error_past_expiry), MSG_MF_ERROR_PGP (R.string.msg_mf_error_pgp), MSG_MF_ERROR_REVOKED_PRIMARY (R.string.msg_mf_error_revoked_primary), @@ -371,6 +372,9 @@ public class OperationResultParcel implements Parcelable { MSG_MF_ERROR_SUBKEY_MISSING(R.string.msg_mf_error_subkey_missing), MSG_MF_MASTER (R.string.msg_mf_master), MSG_MF_PASSPHRASE (R.string.msg_mf_passphrase), + MSG_MF_PASSPHRASE_KEY (R.string.msg_mf_passphrase_key), + MSG_MF_PASSPHRASE_EMPTY_RETRY (R.string.msg_mf_passphrase_empty_retry), + MSG_MF_PASSPHRASE_FAIL (R.string.msg_mf_passphrase_fail), MSG_MF_PRIMARY_REPLACE_OLD (R.string.msg_mf_primary_replace_old), MSG_MF_PRIMARY_NEW (R.string.msg_mf_primary_new), MSG_MF_SUBKEY_CHANGE (R.string.msg_mf_subkey_change), diff --git a/OpenKeychain/src/main/res/values/strings.xml b/OpenKeychain/src/main/res/values/strings.xml index f6c208ca0..5259336ec 100644 --- a/OpenKeychain/src/main/res/values/strings.xml +++ b/OpenKeychain/src/main/res/values/strings.xml @@ -644,10 +644,14 @@ Bad user id for revocation specified! Revoked user ids cannot be primary! Expiry time cannot be "same as before" on subkey creation. This is a programming error, please file a bug report! + Fatal error decrypting master key! This is likely a programming error, please file a bug report! PGP internal exception! Signature exception! Modifying master certifications - Changing passphrase + Changing passphrase for keyring… + Changing passphrase for subkey %s + Setting new passphrase failed, trying again with empty old passphrase + Passphrase for subkey could not be changed! (Does it have a different one from the other keys?) Replacing certificate of previous primary user id Generating new certificate for new primary user id Modifying subkey %s -- cgit v1.2.3 From aa625d4fbf8cf97de5a81675d55e4ac004ef5f11 Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Sun, 17 Aug 2014 00:49:14 +0200 Subject: parametrize FileImportCache for filename --- .../sufficientlysecure/keychain/util/FileImportCacheTest.java | 2 +- .../keychain/service/KeychainIntentService.java | 2 +- .../sufficientlysecure/keychain/ui/ImportKeysActivity.java | 3 ++- .../org/sufficientlysecure/keychain/util/FileImportCache.java | 11 ++++++----- 4 files changed, 10 insertions(+), 8 deletions(-) diff --git a/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/util/FileImportCacheTest.java b/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/util/FileImportCacheTest.java index b5708b46f..11bc05c9e 100644 --- a/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/util/FileImportCacheTest.java +++ b/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/util/FileImportCacheTest.java @@ -25,7 +25,7 @@ public class FileImportCacheTest { @Test public void testInputOutput() throws Exception { - FileImportCache cache = new FileImportCache(Robolectric.application); + FileImportCache cache = new FileImportCache(Robolectric.application, "test.pcl"); ArrayList list = new ArrayList(); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java index 036251cd6..0505a6339 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java @@ -477,7 +477,7 @@ public class KeychainIntentService extends IntentService } else { // get entries from cached file FileImportCache cache = - new FileImportCache(this); + new FileImportCache(this, "key_import.pcl"); entries = cache.readCacheIntoList(); } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java index 255290de3..7df180296 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java @@ -503,7 +503,8 @@ public class ImportKeysActivity extends ActionBarActivity { // to prevent Java Binder problems on heavy imports // read FileImportCache for more info. try { - FileImportCache cache = new FileImportCache(this); + FileImportCache cache = + new FileImportCache(this, "key_import.pcl"); cache.writeCache(selectedEntries); intent.putExtra(KeychainIntentService.EXTRA_DATA, data); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/FileImportCache.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/FileImportCache.java index 5a4bf5311..35833adc6 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/FileImportCache.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/FileImportCache.java @@ -46,10 +46,11 @@ public class FileImportCache { private Context mContext; - private static final String FILENAME = "key_import.pcl"; + private final String mFilename; - public FileImportCache(Context context) { - this.mContext = context; + public FileImportCache(Context context, String filename) { + mContext = context; + mFilename = filename; } public void writeCache(ArrayList selectedEntries) throws IOException { @@ -64,7 +65,7 @@ public class FileImportCache { throw new IOException("cache dir is null!"); } - File tempFile = new File(mContext.getCacheDir(), FILENAME); + File tempFile = new File(mContext.getCacheDir(), mFilename); DataOutputStream oos = new DataOutputStream(new FileOutputStream(tempFile)); @@ -98,7 +99,7 @@ public class FileImportCache { throw new IOException("cache dir is null!"); } - final File tempFile = new File(cacheDir, FILENAME); + final File tempFile = new File(cacheDir, mFilename); final DataInputStream ois = new DataInputStream(new FileInputStream(tempFile)); return new Iterator() { -- cgit v1.2.3 From 14290c3ce9a1cfcf2b45c47198ba44737bd5d996 Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Sun, 17 Aug 2014 03:29:03 +0200 Subject: consolidate: working implementation, lacking ui --- .../keychain/pgp/PgpImportExport.java | 21 ++- .../keychain/provider/KeychainDatabase.java | 2 +- .../keychain/provider/ProviderHelper.java | 181 ++++++++++++++++++++- .../keychain/service/KeychainIntentService.java | 15 ++ .../keychain/service/OperationResultParcel.java | 9 + .../keychain/service/OperationResults.java | 8 + .../keychain/ui/KeyListActivity.java | 60 +++++++ OpenKeychain/src/main/res/menu/key_list.xml | 6 + OpenKeychain/src/main/res/values/strings.xml | 15 ++ 9 files changed, 302 insertions(+), 15 deletions(-) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpImportExport.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpImportExport.java index f14eacda2..fd37112a5 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpImportExport.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpImportExport.java @@ -36,6 +36,7 @@ import org.sufficientlysecure.keychain.service.KeychainIntentService; import org.sufficientlysecure.keychain.service.OperationResultParcel.OperationLog; import org.sufficientlysecure.keychain.service.OperationResults.ImportKeyResult; import org.sufficientlysecure.keychain.service.OperationResults.SaveKeyringResult; +import org.sufficientlysecure.keychain.util.IterableIterator; import org.sufficientlysecure.keychain.util.Log; import org.sufficientlysecure.keychain.util.ProgressScaler; @@ -43,6 +44,7 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; import java.util.ArrayList; +import java.util.Iterator; import java.util.List; public class PgpImportExport { @@ -60,10 +62,14 @@ public class PgpImportExport { private ProviderHelper mProviderHelper; public PgpImportExport(Context context, Progressable progressable) { + this(context, new ProviderHelper(context), progressable); + } + + public PgpImportExport(Context context, ProviderHelper providerHelper, Progressable progressable) { super(); this.mContext = context; this.mProgressable = progressable; - this.mProviderHelper = new ProviderHelper(context); + this.mProviderHelper = providerHelper; } public PgpImportExport(Context context, @@ -124,11 +130,14 @@ public class PgpImportExport { /** Imports keys from given data. If keyIds is given only those are imported */ public ImportKeyResult importKeyRings(List entries) { + return importKeyRings(entries.iterator(), entries.size()); + } + public ImportKeyResult importKeyRings(Iterator entries, int num) { updateProgress(R.string.progress_importing, 0, 100); // If there aren't even any keys, do nothing here. - if (entries == null || entries.size() == 0) { + if (entries == null || !entries.hasNext()) { return new ImportKeyResult( ImportKeyResult.RESULT_FAIL_NOTHING, mProviderHelper.getLog(), 0, 0, 0); } @@ -136,8 +145,8 @@ public class PgpImportExport { int newKeys = 0, oldKeys = 0, badKeys = 0; int position = 0; - int progSteps = 100 / entries.size(); - for (ParcelableKeyRing entry : entries) { + double progSteps = 100.0 / num; + for (ParcelableKeyRing entry : new IterableIterator(entries)) { try { UncachedKeyRing key = UncachedKeyRing.decodeFromData(entry.getBytes()); @@ -157,10 +166,10 @@ public class PgpImportExport { SaveKeyringResult result; if (key.isSecret()) { result = mProviderHelper.saveSecretKeyRing(key, - new ProgressScaler(mProgressable, position, (position+1)*progSteps, 100)); + new ProgressScaler(mProgressable, (int)(position*progSteps), (int)((position+1)*progSteps), 100)); } else { result = mProviderHelper.savePublicKeyRing(key, - new ProgressScaler(mProgressable, position, (position+1)*progSteps, 100)); + new ProgressScaler(mProgressable, (int)(position*progSteps), (int)((position+1)*progSteps), 100)); } if (!result.success()) { badKeys += 1; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainDatabase.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainDatabase.java index 1536c21fc..560eb9ef8 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainDatabase.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainDatabase.java @@ -349,7 +349,7 @@ public class KeychainDatabase extends SQLiteOpenHelper { copy(in, out); } - // for test cases ONLY!! + // DANGEROUS public void clearDatabase() { getWritableDatabase().execSQL("delete from " + Tables.KEY_RINGS_PUBLIC); } 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 ac6ea015a..3594ded51 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java @@ -28,12 +28,14 @@ import android.os.RemoteException; import android.support.v4.util.LongSparseArray; import org.sufficientlysecure.keychain.Constants; +import org.sufficientlysecure.keychain.keyimport.ParcelableKeyRing; import org.sufficientlysecure.keychain.pgp.CanonicalizedPublicKey; import org.sufficientlysecure.keychain.pgp.CanonicalizedPublicKeyRing; import org.sufficientlysecure.keychain.pgp.CanonicalizedSecretKeyRing; import org.sufficientlysecure.keychain.pgp.KeyRing; import org.sufficientlysecure.keychain.pgp.NullProgressable; import org.sufficientlysecure.keychain.pgp.PgpHelper; +import org.sufficientlysecure.keychain.pgp.PgpImportExport; import org.sufficientlysecure.keychain.pgp.PgpKeyHelper; import org.sufficientlysecure.keychain.pgp.Progressable; import org.sufficientlysecure.keychain.pgp.UncachedKeyRing; @@ -51,9 +53,12 @@ import org.sufficientlysecure.keychain.remote.AppSettings; import org.sufficientlysecure.keychain.service.OperationResultParcel.LogLevel; import org.sufficientlysecure.keychain.service.OperationResultParcel.LogType; import org.sufficientlysecure.keychain.service.OperationResultParcel.OperationLog; +import org.sufficientlysecure.keychain.service.OperationResults.ConsolidateResult; import org.sufficientlysecure.keychain.service.OperationResults.SaveKeyringResult; +import org.sufficientlysecure.keychain.util.FileImportCache; import org.sufficientlysecure.keychain.util.IterableIterator; import org.sufficientlysecure.keychain.util.Log; +import org.sufficientlysecure.keychain.util.ProgressScaler; import java.io.ByteArrayOutputStream; import java.io.IOException; @@ -63,6 +68,7 @@ import java.util.Collections; import java.util.Date; import java.util.HashMap; import java.util.HashSet; +import java.util.Iterator; import java.util.List; import java.util.Set; @@ -97,14 +103,6 @@ public class ProviderHelper { mIndent = indent; } - public void resetLog() { - if(mLog != null) { - // Start a new log (leaving the old one intact) - mLog = new OperationLog(); - mIndent = 0; - } - } - public OperationLog getLog() { return mLog; } @@ -825,6 +823,173 @@ public class ProviderHelper { } + public ConsolidateResult consolidateDatabase(Progressable progress) { + + // 1a. fetch all secret keyrings into a cache file + int numSecrets, numPublics; + + log(LogLevel.START, LogType.MSG_CON, mIndent); + mIndent += 1; + + try { + + log(LogLevel.DEBUG, LogType.MSG_CON_SAVE_SECRET, mIndent); + mIndent += 1; + + final Cursor cursor = mContentResolver.query(KeyRings.buildUnifiedKeyRingsUri(), new String[] { + KeyRings.PRIVKEY_DATA, KeyRings.FINGERPRINT, KeyRings.HAS_ANY_SECRET + }, KeyRings.HAS_ANY_SECRET + " = 1", null, null); + + if (cursor == null || !cursor.moveToFirst()) { + return new ConsolidateResult(ConsolidateResult.RESULT_ERROR, mLog); + } + + numSecrets = cursor.getCount(); + + FileImportCache cache = + new FileImportCache(mContext, "consolidate_secret.pcl"); + cache.writeCache(new Iterator() { + ParcelableKeyRing ring; + + @Override + public boolean hasNext() { + if (ring != null) { + return true; + } + if (cursor.isAfterLast()) { + return false; + } + ring = new ParcelableKeyRing(cursor.getBlob(0), + PgpKeyHelper.convertFingerprintToHex(cursor.getBlob(1))); + cursor.moveToNext(); + return true; + } + + @Override + public ParcelableKeyRing next() { + try { + return ring; + } finally { + ring = null; + } + } + + @Override + public void remove() { + throw new UnsupportedOperationException(); + } + + }); + + } catch (IOException e) { + Log.e(Constants.TAG, "error saving secret"); + return new ConsolidateResult(ConsolidateResult.RESULT_ERROR, mLog); + } finally { + mIndent -= 1; + } + + // 1b. fetch all public keyrings into a cache file + try { + + log(LogLevel.DEBUG, LogType.MSG_CON_SAVE_PUBLIC, mIndent); + mIndent += 1; + + final Cursor cursor = mContentResolver.query(KeyRings.buildUnifiedKeyRingsUri(), new String[] { + KeyRings.PUBKEY_DATA, KeyRings.FINGERPRINT + }, null, null, null); + + if (cursor == null || !cursor.moveToFirst()) { + return new ConsolidateResult(ConsolidateResult.RESULT_ERROR, mLog); + } + + numPublics = cursor.getCount(); + + FileImportCache cache = + new FileImportCache(mContext, "consolidate_public.pcl"); + cache.writeCache(new Iterator() { + ParcelableKeyRing ring; + + @Override + public boolean hasNext() { + if (ring != null) { + return true; + } + if (cursor.isAfterLast()) { + return false; + } + ring = new ParcelableKeyRing(cursor.getBlob(0), + PgpKeyHelper.convertFingerprintToHex(cursor.getBlob(1))); + cursor.moveToNext(); + return true; + } + + @Override + public ParcelableKeyRing next() { + try { + return ring; + } finally { + ring = null; + } + } + + @Override + public void remove() { + throw new UnsupportedOperationException(); + } + + }); + + } catch (IOException e) { + Log.e(Constants.TAG, "error saving public"); + return new ConsolidateResult(ConsolidateResult.RESULT_ERROR, mLog); + } finally { + mIndent -= 1; + } + + // 2. wipe database (IT'S DANGEROUS) + log(LogLevel.DEBUG, LogType.MSG_CON_DB_CLEAR, mIndent); + new KeychainDatabase(mContext).clearDatabase(); + + // 3. Re-Import secret keyrings from cache + try { + log(LogLevel.DEBUG, LogType.MSG_CON_REIMPORT_SECRET, mIndent, numSecrets); + mIndent += 1; + + FileImportCache cache = + new FileImportCache(mContext, "consolidate_secret.pcl"); + new PgpImportExport(mContext, this, new ProgressScaler(progress, 10, 25, 100)) + .importKeyRings(cache.readCache(), numSecrets); + } catch (IOException e) { + Log.e(Constants.TAG, "error importing secret"); + return new ConsolidateResult(ConsolidateResult.RESULT_ERROR, mLog); + } finally { + mIndent -= 1; + } + + // 3. Re-Import public keyrings from cache + try { + log(LogLevel.DEBUG, LogType.MSG_CON_REIMPORT_PUBLIC, mIndent, numPublics); + mIndent += 1; + + FileImportCache cache = + new FileImportCache(mContext, "consolidate_public.pcl"); + new PgpImportExport(mContext, this, new ProgressScaler(progress, 25, 99, 100)) + .importKeyRings(cache.readCache(), numPublics); + } catch (IOException e) { + Log.e(Constants.TAG, "error importing public"); + return new ConsolidateResult(ConsolidateResult.RESULT_ERROR, mLog); + } finally { + mIndent -= 1; + } + + progress.setProgress(100, 100); + log(LogLevel.OK, LogType.MSG_CON_SUCCESS, mIndent); + mIndent -= 1; + + return new ConsolidateResult(ConsolidateResult.RESULT_OK, mLog); + + } + /** * Build ContentProviderOperation to add PGPPublicKey to database corresponding to a keyRing */ diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java index 0505a6339..9f5650df6 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java @@ -52,6 +52,7 @@ import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralMsgIdException; import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings; import org.sufficientlysecure.keychain.provider.KeychainDatabase; import org.sufficientlysecure.keychain.provider.ProviderHelper; +import org.sufficientlysecure.keychain.service.OperationResults.ConsolidateResult; import org.sufficientlysecure.keychain.service.OperationResults.EditKeyResult; import org.sufficientlysecure.keychain.service.OperationResults.ImportKeyResult; import org.sufficientlysecure.keychain.service.OperationResults.SaveKeyringResult; @@ -103,6 +104,8 @@ public class KeychainIntentService extends IntentService public static final String ACTION_CERTIFY_KEYRING = Constants.INTENT_PREFIX + "SIGN_KEYRING"; + public static final String ACTION_CONSOLIDATE = Constants.INTENT_PREFIX + "CONSOLIDATE"; + /* keys for data bundle */ // encrypt, decrypt, import export @@ -142,6 +145,7 @@ public class KeychainIntentService extends IntentService // import key public static final String IMPORT_KEY_LIST = "import_key_list"; + public static final String IMPORT_KEY_FILE = "import_key_file"; // export key public static final String EXPORT_OUTPUT_STREAM = "export_output_stream"; @@ -179,6 +183,8 @@ public class KeychainIntentService extends IntentService public static final String RESULT_IMPORT = "result"; + public static final String RESULT_CONSOLIDATE = "consolidate_result"; + Messenger mMessenger; private boolean mIsCanceled; @@ -662,7 +668,16 @@ public class KeychainIntentService extends IntentService } catch (Exception e) { sendErrorToHandler(e); } + + } else if (ACTION_CONSOLIDATE.equals(action)) { + ConsolidateResult result = new ProviderHelper(this).consolidateDatabase(this); + + Bundle resultData = new Bundle(); + resultData.putParcelable(RESULT_CONSOLIDATE, result); + + sendMessageToHandler(KeychainIntentServiceHandler.MESSAGE_OKAY, resultData); } + } private void sendErrorToHandler(Exception e) { diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/OperationResultParcel.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/OperationResultParcel.java index 26fe63550..c601ec57e 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/OperationResultParcel.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/OperationResultParcel.java @@ -388,6 +388,15 @@ public class OperationResultParcel implements Parcelable { MSG_MF_UID_ERROR_EMPTY (R.string.msg_mf_uid_error_empty), MSG_MF_UNLOCK_ERROR (R.string.msg_mf_unlock_error), MSG_MF_UNLOCK (R.string.msg_mf_unlock), + + // consolidate + MSG_CON (R.string.msg_con), + MSG_CON_SAVE_SECRET (R.string.msg_con_save_secret), + MSG_CON_SAVE_PUBLIC (R.string.msg_con_save_public), + MSG_CON_DB_CLEAR (R.string.msg_con_db_clear), + MSG_CON_REIMPORT_SECRET (R.plurals.msg_con_reimport_secret), + MSG_CON_REIMPORT_PUBLIC (R.plurals.msg_con_reimport_public), + MSG_CON_SUCCESS (R.string.msg_con_success), ; private final int mMsgId; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/OperationResults.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/OperationResults.java index 1fc496082..878f6ca47 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/OperationResults.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/OperationResults.java @@ -272,4 +272,12 @@ public abstract class OperationResults { }; } + public static class ConsolidateResult extends OperationResultParcel { + + public ConsolidateResult(int result, OperationLog log) { + super(result, log); + } + + } + } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListActivity.java index 7a6e78a7d..9d9462648 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListActivity.java @@ -17,8 +17,11 @@ package org.sufficientlysecure.keychain.ui; +import android.app.ProgressDialog; import android.content.Intent; import android.os.Bundle; +import android.os.Message; +import android.os.Messenger; import android.view.Menu; import android.view.MenuItem; @@ -28,6 +31,9 @@ import org.sufficientlysecure.keychain.helper.ExportHelper; import org.sufficientlysecure.keychain.helper.Preferences; import org.sufficientlysecure.keychain.provider.KeychainContract; import org.sufficientlysecure.keychain.provider.KeychainDatabase; +import org.sufficientlysecure.keychain.service.KeychainIntentService; +import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler; +import org.sufficientlysecure.keychain.service.OperationResults.ConsolidateResult; import org.sufficientlysecure.keychain.util.Log; import org.sufficientlysecure.keychain.util.Notify; @@ -63,6 +69,7 @@ public class KeyListActivity extends DrawerActivity { getMenuInflater().inflate(R.menu.key_list, menu); if (Constants.DEBUG) { + menu.findItem(R.id.menu_key_list_debug_cons).setVisible(true); menu.findItem(R.id.menu_key_list_debug_read).setVisible(true); menu.findItem(R.id.menu_key_list_debug_write).setVisible(true); menu.findItem(R.id.menu_key_list_debug_first_time).setVisible(true); @@ -92,6 +99,10 @@ public class KeyListActivity extends DrawerActivity { mExportHelper.showExportKeysDialog(null, Constants.Path.APP_DIR_FILE, true); return true; + case R.id.menu_key_list_debug_cons: + consolidate(); + return true; + case R.id.menu_key_list_debug_read: try { KeychainDatabase.debugBackup(this, true); @@ -136,4 +147,53 @@ public class KeyListActivity extends DrawerActivity { startActivity(intent); } + private void consolidate() { + // Message is received after importing is done in KeychainIntentService + KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler( + this, + getString(R.string.progress_importing), + ProgressDialog.STYLE_HORIZONTAL) { + public void handleMessage(Message message) { + // handle messages by standard KeychainIntentServiceHandler first + super.handleMessage(message); + + if (message.arg1 == KeychainIntentServiceHandler.MESSAGE_OKAY) { + // get returned data bundle + Bundle returnData = message.getData(); + if (returnData == null) { + return; + } + final ConsolidateResult result = + returnData.getParcelable(KeychainIntentService.RESULT_CONSOLIDATE); + if (result == null) { + return; + } + + result.createNotify(KeyListActivity.this).show(); + } + } + }; + + // Send all information needed to service to import key in other thread + Intent intent = new Intent(this, KeychainIntentService.class); + + intent.setAction(KeychainIntentService.ACTION_CONSOLIDATE); + + // fill values for this action + Bundle data = new Bundle(); + + intent.putExtra(KeychainIntentService.EXTRA_DATA, data); + + // Create a new Messenger for the communication back + Messenger messenger = new Messenger(saveHandler); + intent.putExtra(KeychainIntentService.EXTRA_MESSENGER, messenger); + + // show progress dialog + saveHandler.showProgressDialog(this); + + // start service with intent + startService(intent); + + } + } diff --git a/OpenKeychain/src/main/res/menu/key_list.xml b/OpenKeychain/src/main/res/menu/key_list.xml index 056dd5986..6e571243d 100644 --- a/OpenKeychain/src/main/res/menu/key_list.xml +++ b/OpenKeychain/src/main/res/menu/key_list.xml @@ -31,6 +31,12 @@ app:showAsAction="never" android:title="@string/menu_import_existing_key" /> + + Error unlocking keyring! Unlocking keyring + + Consolidating database + Saving secret keyrings + Saving public keyrings + Clearing database + + Reimporting one secret key + Reimporting %d secret keys + + + Reimporting one public key + Reimporting %d public keys + + Successfully consolidated database + Click to clear cached passphrases OpenKeychain has cached %d passphrases -- cgit v1.2.3 From 3cc57a092a7ba59390b2d892db028cc1990cdbd1 Mon Sep 17 00:00:00 2001 From: mar-v-in Date: Sun, 17 Aug 2014 11:07:34 +0200 Subject: Remove NoSwipeWrapContentViewPager --- .../keychain/ui/EncryptActivity.java | 41 +++++++------- .../ui/widget/NoSwipeWrapContentViewPager.java | 62 ---------------------- .../src/main/res/layout/encrypt_content.xml | 8 ++- 3 files changed, 23 insertions(+), 88 deletions(-) delete mode 100644 OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/NoSwipeWrapContentViewPager.java diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivity.java index 7e08f6b7c..59a433af3 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivity.java @@ -73,16 +73,13 @@ public class EncryptActivity extends DrawerActivity implements EncryptActivityIn public static final String EXTRA_ENCRYPTION_KEY_IDS = "encryption_key_ids"; // view - ViewPager mViewPagerMode; - //PagerTabStrip mPagerTabStripMode; - PagerTabStripAdapter mTabsAdapterMode; - ViewPager mViewPagerContent; - PagerTabStrip mPagerTabStripContent; - PagerTabStripAdapter mTabsAdapterContent; + private int mCurrentMode = PAGER_MODE_ASYMMETRIC; + private ViewPager mViewPagerContent; + private PagerTabStrip mPagerTabStripContent; + private PagerTabStripAdapter mTabsAdapterContent; // tabs - int mSwitchToMode = PAGER_MODE_ASYMMETRIC; - int mSwitchToContent = PAGER_CONTENT_MESSAGE; + private int mSwitchToContent = PAGER_CONTENT_MESSAGE; private static final int PAGER_MODE_ASYMMETRIC = 0; private static final int PAGER_MODE_SYMMETRIC = 1; @@ -102,7 +99,7 @@ public class EncryptActivity extends DrawerActivity implements EncryptActivityIn private String mMessage = ""; public boolean isModeSymmetric() { - return PAGER_MODE_SYMMETRIC == mViewPagerMode.getCurrentItem(); + return PAGER_MODE_SYMMETRIC == mCurrentMode; } public boolean isContentMessage() { @@ -474,13 +471,9 @@ public class EncryptActivity extends DrawerActivity implements EncryptActivityIn } private void initView() { - mViewPagerMode = (ViewPager) findViewById(R.id.encrypt_pager_mode); - //mPagerTabStripMode = (PagerTabStrip) findViewById(R.id.encrypt_pager_tab_strip_mode); mViewPagerContent = (ViewPager) findViewById(R.id.encrypt_pager_content); mPagerTabStripContent = (PagerTabStrip) findViewById(R.id.encrypt_pager_tab_strip_content); - mTabsAdapterMode = new PagerTabStripAdapter(this); - mViewPagerMode.setAdapter(mTabsAdapterMode); mTabsAdapterContent = new PagerTabStripAdapter(this); mViewPagerContent.setAdapter(mTabsAdapterContent); } @@ -502,10 +495,7 @@ public class EncryptActivity extends DrawerActivity implements EncryptActivityIn // Handle intent actions handleActions(getIntent()); - - mTabsAdapterMode.addTab(EncryptAsymmetricFragment.class, null, getString(R.string.label_asymmetric)); - mTabsAdapterMode.addTab(EncryptSymmetricFragment.class, null, getString(R.string.label_symmetric)); - mViewPagerMode.setCurrentItem(mSwitchToMode); + updateModeFragment(); mTabsAdapterContent.addTab(EncryptMessageFragment.class, null, getString(R.string.label_message)); mTabsAdapterContent.addTab(EncryptFileFragment.class, null, getString(R.string.label_files)); @@ -521,6 +511,16 @@ public class EncryptActivity extends DrawerActivity implements EncryptActivityIn return super.onCreateOptionsMenu(menu); } + private void updateModeFragment() { + getSupportFragmentManager().beginTransaction() + .replace(R.id.encrypt_pager_mode, + mCurrentMode == PAGER_MODE_SYMMETRIC + ? new EncryptSymmetricFragment() + : new EncryptAsymmetricFragment()) + .commitAllowingStateLoss(); + getSupportFragmentManager().executePendingTransactions(); + } + @Override public boolean onOptionsItemSelected(MenuItem item) { if (item.isCheckable()) { @@ -528,9 +528,8 @@ public class EncryptActivity extends DrawerActivity implements EncryptActivityIn } switch (item.getItemId()) { case R.id.check_use_symmetric: - mSwitchToMode = item.isChecked() ? PAGER_MODE_SYMMETRIC : PAGER_MODE_ASYMMETRIC; - - mViewPagerMode.setCurrentItem(mSwitchToMode); + mCurrentMode = item.isChecked() ? PAGER_MODE_SYMMETRIC : PAGER_MODE_ASYMMETRIC; + updateModeFragment(); notifyUpdate(); break; case R.id.check_use_armor: @@ -604,7 +603,7 @@ public class EncryptActivity extends DrawerActivity implements EncryptActivityIn mEncryptionKeyIds = extras.getLongArray(EXTRA_ENCRYPTION_KEY_IDS); // preselect keys given by intent - mSwitchToMode = PAGER_MODE_ASYMMETRIC; + mCurrentMode = PAGER_MODE_ASYMMETRIC; /** * Main Actions diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/NoSwipeWrapContentViewPager.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/NoSwipeWrapContentViewPager.java deleted file mode 100644 index a48d2a026..000000000 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/NoSwipeWrapContentViewPager.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (C) 2014 Dominik Schürmann - * - * 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 . - */ - -package org.sufficientlysecure.keychain.ui.widget; - -import android.content.Context; -import android.util.AttributeSet; -import android.view.MotionEvent; -import android.view.View; - -public class NoSwipeWrapContentViewPager extends android.support.v4.view.ViewPager { - public NoSwipeWrapContentViewPager(Context context) { - super(context); - } - - public NoSwipeWrapContentViewPager(Context context, AttributeSet attrs) { - super(context, attrs); - } - - @Override - protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - - int height; - View child = getChildAt(getCurrentItem()); - if (child != null) { - child.measure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED)); - height = child.getMeasuredHeight(); - } else { - height = 0; - } - - heightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY); - - super.onMeasure(widthMeasureSpec, heightMeasureSpec); - } - - @Override - public boolean onInterceptTouchEvent(MotionEvent arg0) { - // Never allow swiping to switch between pages - return false; - } - - @Override - public boolean onTouchEvent(MotionEvent event) { - // Never allow swiping to switch between pages - return false; - } -} diff --git a/OpenKeychain/src/main/res/layout/encrypt_content.xml b/OpenKeychain/src/main/res/layout/encrypt_content.xml index e5edc6657..d029e7b83 100644 --- a/OpenKeychain/src/main/res/layout/encrypt_content.xml +++ b/OpenKeychain/src/main/res/layout/encrypt_content.xml @@ -9,13 +9,11 @@ - - - + android:layout_height="wrap_content" + android:orientation="vertical" /> Date: Sun, 17 Aug 2014 11:31:41 +0200 Subject: Work-around rendering bug when switching back to asymmetric with multiple recipients selected --- .../keychain/ui/EncryptAsymmetricFragment.java | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptAsymmetricFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptAsymmetricFragment.java index 748cbca14..a508472d6 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptAsymmetricFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptAsymmetricFragment.java @@ -18,30 +18,16 @@ package org.sufficientlysecure.keychain.ui; import android.app.Activity; -import android.content.Context; -import android.database.Cursor; -import android.net.Uri; import android.os.Bundle; import android.support.v4.app.Fragment; -import android.support.v4.app.LoaderManager; -import android.support.v4.content.CursorLoader; -import android.support.v4.content.Loader; -import android.support.v4.widget.CursorAdapter; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; -import android.widget.AdapterView; -import android.widget.BaseAdapter; -import android.widget.Spinner; -import android.widget.SpinnerAdapter; -import android.widget.TextView; import com.tokenautocomplete.TokenCompleteTextView; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; -import org.sufficientlysecure.keychain.pgp.KeyRing; -import org.sufficientlysecure.keychain.pgp.PgpKeyHelper; import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException; import org.sufficientlysecure.keychain.provider.CachedPublicKeyRing; import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings; @@ -169,6 +155,8 @@ public class EncryptAsymmetricFragment extends Fragment implements EncryptActivi Log.e(Constants.TAG, "key not found!", e); } } + // This is to work-around a rendering bug in TokenCompleteTextView + mEncryptKeyView.requestFocus(); updateEncryptionKeys(); } } -- cgit v1.2.3 From 3e7ce0008fde176634980a31f61052052698ff93 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Mon, 18 Aug 2014 11:02:41 +0200 Subject: Fixes for expiry UI --- .../keychain/ui/EditKeyFragment.java | 4 +- .../keychain/ui/adapter/SubkeysAdapter.java | 8 +- .../keychain/ui/adapter/SubkeysAddedAdapter.java | 8 +- .../ui/dialog/AddSubkeyDialogFragment.java | 5 +- .../ui/dialog/EditSubkeyExpiryDialogFragment.java | 145 ++++++++++++--------- .../main/res/layout/edit_subkey_expiry_dialog.xml | 10 ++ 6 files changed, 111 insertions(+), 69 deletions(-) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyFragment.java index 409953ad5..f2d6d4c13 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyFragment.java @@ -406,10 +406,10 @@ public class EditKeyFragment extends LoaderFragment implements @Override public void handleMessage(Message message) { switch (message.what) { - case EditSubkeyExpiryDialogFragment.MESSAGE_NEW_EXPIRY_DATE: + case EditSubkeyExpiryDialogFragment.MESSAGE_NEW_EXPIRY: mSaveKeyringParcel.getOrCreateSubkeyChange(keyId).mExpiry = (Long) message.getData().getSerializable( - EditSubkeyExpiryDialogFragment.MESSAGE_DATA_EXPIRY_DATE); + EditSubkeyExpiryDialogFragment.MESSAGE_DATA_EXPIRY); break; } getLoaderManager().getLoader(LOADER_ID_SUBKEYS).forceLoad(); 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 6df84a056..9958b33a1 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 @@ -35,7 +35,9 @@ import org.sufficientlysecure.keychain.pgp.PgpKeyHelper; import org.sufficientlysecure.keychain.provider.KeychainContract.Keys; import org.sufficientlysecure.keychain.service.SaveKeyringParcel; +import java.util.Calendar; import java.util.Date; +import java.util.TimeZone; public class SubkeysAdapter extends CursorAdapter { private LayoutInflater mInflater; @@ -198,9 +200,13 @@ public class SubkeysAdapter extends CursorAdapter { boolean isExpired; if (expiryDate != null) { isExpired = expiryDate.before(new Date()); + Calendar expiryCal = Calendar.getInstance(TimeZone.getTimeZone("UTC")); + expiryCal.setTime(expiryDate); + // convert from UTC to time zone of device + expiryCal.setTimeZone(TimeZone.getDefault()); vKeyExpiry.setText(context.getString(R.string.label_expiry) + ": " - + DateFormat.getDateFormat(context).format(expiryDate)); + + DateFormat.getDateFormat(context).format(expiryCal.getTime())); } else { isExpired = false; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/SubkeysAddedAdapter.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/SubkeysAddedAdapter.java index 7e0027ddc..a1dfeb10c 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/SubkeysAddedAdapter.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/SubkeysAddedAdapter.java @@ -33,8 +33,10 @@ import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.pgp.PgpKeyHelper; import org.sufficientlysecure.keychain.service.SaveKeyringParcel; +import java.util.Calendar; import java.util.Date; import java.util.List; +import java.util.TimeZone; public class SubkeysAddedAdapter extends ArrayAdapter { private LayoutInflater mInflater; @@ -108,9 +110,13 @@ public class SubkeysAddedAdapter extends ArrayAdapter= android.os.Build.VERSION_CODES.HONEYCOMB) { - mExpiryDatePicker.setMinDate(new Date().getTime() + DateUtils.DAY_IN_MILLIS); + // 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 choices = new ArrayList(); 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 fde8a3477..f46e253c0 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,9 +25,10 @@ import android.os.Message; import android.os.Messenger; import android.os.RemoteException; import android.support.v4.app.DialogFragment; -import android.text.format.DateUtils; import android.view.LayoutInflater; import android.view.View; +import android.widget.CheckBox; +import android.widget.CompoundButton; import android.widget.DatePicker; import org.sufficientlysecure.keychain.Constants; @@ -40,17 +41,15 @@ import java.util.TimeZone; public class EditSubkeyExpiryDialogFragment extends DialogFragment { private static final String ARG_MESSENGER = "messenger"; - private static final String ARG_CREATION_DATE = "creation_date"; - private static final String ARG_EXPIRY_DATE = "expiry_date"; + private static final String ARG_CREATION = "creation"; + private static final String ARG_EXPIRY = "expiry"; - public static final int MESSAGE_NEW_EXPIRY_DATE = 1; + public static final int MESSAGE_NEW_EXPIRY = 1; public static final int MESSAGE_CANCEL = 2; - public static final String MESSAGE_DATA_EXPIRY_DATE = "expiry_date"; + public static final String MESSAGE_DATA_EXPIRY = "expiry"; private Messenger mMessenger; - private DatePicker mDatePicker; - /** * Creates new instance of this dialog fragment */ @@ -59,8 +58,8 @@ public class EditSubkeyExpiryDialogFragment extends DialogFragment { EditSubkeyExpiryDialogFragment frag = new EditSubkeyExpiryDialogFragment(); Bundle args = new Bundle(); args.putParcelable(ARG_MESSENGER, messenger); - args.putSerializable(ARG_CREATION_DATE, creationDate); - args.putSerializable(ARG_EXPIRY_DATE, expiryDate); + args.putSerializable(ARG_CREATION, creationDate); + args.putSerializable(ARG_EXPIRY, expiryDate); frag.setArguments(args); @@ -74,13 +73,13 @@ public class EditSubkeyExpiryDialogFragment extends DialogFragment { public Dialog onCreateDialog(Bundle savedInstanceState) { final Activity activity = getActivity(); mMessenger = getArguments().getParcelable(ARG_MESSENGER); - long creationDate = getArguments().getLong(ARG_CREATION_DATE); - long expiryDate = getArguments().getLong(ARG_EXPIRY_DATE); + long creation = getArguments().getLong(ARG_CREATION); + long expiry = getArguments().getLong(ARG_EXPIRY); Calendar creationCal = Calendar.getInstance(TimeZone.getTimeZone("UTC")); - creationCal.setTime(new Date(creationDate * 1000)); + creationCal.setTime(new Date(creation * 1000)); final Calendar expiryCal = Calendar.getInstance(TimeZone.getTimeZone("UTC")); - expiryCal.setTime(new Date(expiryDate * 1000)); + expiryCal.setTime(new Date(expiry * 1000)); // date picker works with default time zone, we need to convert from UTC to default timezone creationCal.setTimeZone(TimeZone.getDefault()); @@ -96,44 +95,64 @@ public class EditSubkeyExpiryDialogFragment extends DialogFragment { View view = inflater.inflate(R.layout.edit_subkey_expiry_dialog, null); alert.setView(view); - mDatePicker = (DatePicker) view.findViewById(R.id.edit_subkey_expiry_date_picker); + 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); - // set default date - if (expiryDate == 0L) { - // if key has no expiry, set it to creation date +1 day + noExpiry.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { + if (isChecked) { + datePicker.setVisibility(View.GONE); + } else { + datePicker.setVisibility(View.VISIBLE); + } + } + }); - Calendar creationCalPlusOne = (Calendar) creationCal.clone(); - creationCalPlusOne.add(Calendar.DAY_OF_MONTH, 1); - mDatePicker.init( - creationCalPlusOne.get(Calendar.YEAR), - creationCalPlusOne.get(Calendar.MONTH), - creationCalPlusOne.get(Calendar.DAY_OF_MONTH), - null - ); + // 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 + ); + } } else { - // set date picker to current expiry date +1 day - - Calendar expiryCalPlusOne = (Calendar) expiryCal.clone(); - expiryCalPlusOne.add(Calendar.DAY_OF_MONTH, 1); - mDatePicker.init( - expiryCalPlusOne.get(Calendar.YEAR), - expiryCalPlusOne.get(Calendar.MONTH), - expiryCalPlusOne.get(Calendar.DAY_OF_MONTH), + noExpiry.setChecked(false); + datePicker.setVisibility(View.VISIBLE); + + // set date picker to current expiry + datePicker.init( + expiryCal.get(Calendar.YEAR), + expiryCal.get(Calendar.MONTH), + expiryCal.get(Calendar.DAY_OF_MONTH), null ); } if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.HONEYCOMB) { - // will crash with IllegalArgumentException if we set a min date - // that is before creation date - if (expiryDate == 0L || creationCal.before(expiryCal)) { - mDatePicker.setMinDate(creationCal.getTime().getTime() - + DateUtils.DAY_IN_MILLIS); - } else { - // set min to expiry date - mDatePicker.setMinDate(expiryCal.getTime().getTime() - + DateUtils.DAY_IN_MILLIS); - } + datePicker.setMinDate(creationCal.getTime().getTime()); } alert.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { @@ -141,30 +160,28 @@ public class EditSubkeyExpiryDialogFragment extends DialogFragment { public void onClick(DialogInterface dialog, int id) { dismiss(); - Calendar selectedCal = Calendar.getInstance(TimeZone.getDefault()); - //noinspection ResourceType - selectedCal.set(mDatePicker.getYear(), mDatePicker.getMonth(), mDatePicker.getDayOfMonth()); - // date picker uses default time zone, we need to convert to UTC - selectedCal.setTimeZone(TimeZone.getTimeZone("UTC")); - - long numDays = (selectedCal.getTimeInMillis() / 86400000) - - (expiryCal.getTimeInMillis() / 86400000); - if (numDays > 0) { - Bundle data = new Bundle(); - data.putSerializable(MESSAGE_DATA_EXPIRY_DATE, selectedCal.getTime().getTime() / 1000); - sendMessageToHandler(MESSAGE_NEW_EXPIRY_DATE, data); + long expiry; + if (noExpiry.isChecked()) { + expiry = 0L; + } else { + Calendar selectedCal = Calendar.getInstance(TimeZone.getDefault()); + //noinspection ResourceType + selectedCal.set(datePicker.getYear(), datePicker.getMonth(), datePicker.getDayOfMonth()); + // date picker uses default time zone, we need to convert to UTC + selectedCal.setTimeZone(TimeZone.getTimeZone("UTC")); + + long numDays = (selectedCal.getTimeInMillis() / 86400000) + - (expiryCal.getTimeInMillis() / 86400000); + if (numDays <= 0) { + Log.e(Constants.TAG, "Should not happen! Expiry num of days <= 0!"); + throw new RuntimeException(); + } + expiry = selectedCal.getTime().getTime() / 1000; } - } - }); - - alert.setNeutralButton(R.string.btn_no_date, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int id) { - dismiss(); Bundle data = new Bundle(); - data.putSerializable(MESSAGE_DATA_EXPIRY_DATE, 0L); - sendMessageToHandler(MESSAGE_NEW_EXPIRY_DATE, data); + data.putSerializable(MESSAGE_DATA_EXPIRY, expiry); + sendMessageToHandler(MESSAGE_NEW_EXPIRY, data); } }); diff --git a/OpenKeychain/src/main/res/layout/edit_subkey_expiry_dialog.xml b/OpenKeychain/src/main/res/layout/edit_subkey_expiry_dialog.xml index 062f07863..8a713115e 100644 --- a/OpenKeychain/src/main/res/layout/edit_subkey_expiry_dialog.xml +++ b/OpenKeychain/src/main/res/layout/edit_subkey_expiry_dialog.xml @@ -4,6 +4,16 @@ android:layout_width="match_parent" android:layout_height="match_parent"> + + Date: Mon, 18 Aug 2014 11:13:52 +0200 Subject: Add subkey: at least one flag should be selected! --- .../ui/dialog/AddSubkeyDialogFragment.java | 127 ++++++++++++--------- OpenKeychain/src/main/res/values/strings.xml | 1 + 2 files changed, 75 insertions(+), 53 deletions(-) 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 d5c80d18a..450e6a5f5 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 @@ -33,6 +33,7 @@ import android.view.View; import android.view.inputmethod.InputMethodManager; import android.widget.AdapterView; import android.widget.ArrayAdapter; +import android.widget.Button; import android.widget.CheckBox; import android.widget.CompoundButton; import android.widget.DatePicker; @@ -40,6 +41,7 @@ import android.widget.EditText; import android.widget.Spinner; import android.widget.TableRow; import android.widget.TextView; +import android.widget.Toast; import org.spongycastle.bcpg.PublicKeyAlgorithmTags; import org.spongycastle.bcpg.sig.KeyFlags; @@ -167,60 +169,11 @@ public class AddSubkeyDialogFragment extends DialogFragment { mKeySizeSpinner.setSelection(1); // Default to 4096 for the key length - dialog.setPositiveButton(android.R.string.ok, - new DialogInterface.OnClickListener() { - public void onClick(DialogInterface di, int id) { - di.dismiss(); - Choice newKeyAlgorithmChoice = (Choice) mAlgorithmSpinner.getSelectedItem(); - int newKeySize = getProperKeyLength(newKeyAlgorithmChoice.getId(), getSelectedKeyLength()); - - int flags = 0; - if (mFlagCertify.isChecked()) { - flags |= KeyFlags.CERTIFY_OTHER; - } - if (mFlagSign.isChecked()) { - flags |= KeyFlags.SIGN_DATA; - } - if (mFlagEncrypt.isChecked()) { - flags |= KeyFlags.ENCRYPT_COMMS | KeyFlags.ENCRYPT_STORAGE; - } - if (mFlagAuthenticate.isChecked()) { - flags |= KeyFlags.AUTHENTICATION; - } - - long expiry; - if (mNoExpiryCheckBox.isChecked()) { - expiry = 0L; - } else { - Calendar selectedCal = Calendar.getInstance(TimeZone.getDefault()); - //noinspection ResourceType - selectedCal.set(mExpiryDatePicker.getYear(), - mExpiryDatePicker.getMonth(), mExpiryDatePicker.getDayOfMonth()); - // date picker uses default time zone, we need to convert to UTC - selectedCal.setTimeZone(TimeZone.getTimeZone("UTC")); - - expiry = selectedCal.getTime().getTime() / 1000; - } - - SaveKeyringParcel.SubkeyAdd newSubkey = new SaveKeyringParcel.SubkeyAdd( - newKeyAlgorithmChoice.getId(), - newKeySize, - flags, - expiry - ); - mAlgorithmSelectedListener.onAlgorithmSelected(newSubkey); - } - } - ); - dialog.setCancelable(true); - dialog.setNegativeButton(android.R.string.cancel, - new DialogInterface.OnClickListener() { - public void onClick(DialogInterface di, int id) { - di.dismiss(); - } - } - ); + + // onClickListener are set in onStart() to override default dismiss behaviour + dialog.setPositiveButton(android.R.string.ok, null); + dialog.setNegativeButton(android.R.string.cancel, null); final AlertDialog alertDialog = dialog.show(); @@ -268,6 +221,74 @@ public class AddSubkeyDialogFragment extends DialogFragment { return alertDialog; } + @Override + public void onStart() { + super.onStart(); //super.onStart() is where dialog.show() is actually called on the underlying dialog, so we have to do it after this point + AlertDialog d = (AlertDialog) getDialog(); + if (d != null) { + Button positiveButton = d.getButton(Dialog.BUTTON_POSITIVE); + Button negativeButton = d.getButton(Dialog.BUTTON_NEGATIVE); + positiveButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + if (!mFlagCertify.isChecked() && !mFlagSign.isChecked() + && !mFlagEncrypt.isChecked() && !mFlagAuthenticate.isChecked()) { + Toast.makeText(getActivity(), R.string.edit_key_select_flag, Toast.LENGTH_LONG).show(); + return; + } + + // dismiss only if at least one flag is selected + dismiss(); + + Choice newKeyAlgorithmChoice = (Choice) mAlgorithmSpinner.getSelectedItem(); + int newKeySize = getProperKeyLength(newKeyAlgorithmChoice.getId(), getSelectedKeyLength()); + + int flags = 0; + if (mFlagCertify.isChecked()) { + flags |= KeyFlags.CERTIFY_OTHER; + } + if (mFlagSign.isChecked()) { + flags |= KeyFlags.SIGN_DATA; + } + if (mFlagEncrypt.isChecked()) { + flags |= KeyFlags.ENCRYPT_COMMS | KeyFlags.ENCRYPT_STORAGE; + } + if (mFlagAuthenticate.isChecked()) { + flags |= KeyFlags.AUTHENTICATION; + } + + long expiry; + if (mNoExpiryCheckBox.isChecked()) { + expiry = 0L; + } else { + Calendar selectedCal = Calendar.getInstance(TimeZone.getDefault()); + //noinspection ResourceType + selectedCal.set(mExpiryDatePicker.getYear(), + mExpiryDatePicker.getMonth(), mExpiryDatePicker.getDayOfMonth()); + // date picker uses default time zone, we need to convert to UTC + selectedCal.setTimeZone(TimeZone.getTimeZone("UTC")); + + expiry = selectedCal.getTime().getTime() / 1000; + } + + SaveKeyringParcel.SubkeyAdd newSubkey = new SaveKeyringParcel.SubkeyAdd( + newKeyAlgorithmChoice.getId(), + newKeySize, + flags, + expiry + ); + mAlgorithmSelectedListener.onAlgorithmSelected(newSubkey); + } + }); + negativeButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + dismiss(); + } + }); + } + } + private int getSelectedKeyLength() { final String selectedItemString = (String) mKeySizeSpinner.getSelectedItem(); final String customLengthString = getResources().getString(R.string.key_size_custom); diff --git a/OpenKeychain/src/main/res/values/strings.xml b/OpenKeychain/src/main/res/values/strings.xml index 51053754e..7a4f41969 100644 --- a/OpenKeychain/src/main/res/values/strings.xml +++ b/OpenKeychain/src/main/res/values/strings.xml @@ -457,6 +457,7 @@ Revoke Subkey new + Please select at least one flag! Upload key to keyserver -- cgit v1.2.3 From 638c29792d38dc48581c22ef4f89ef5780dad0dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Tue, 19 Aug 2014 09:52:15 +0200 Subject: Header for certs view --- .../src/main/res/layout/view_key_activity.xml | 10 ++--- .../main/res/layout/view_key_certs_fragment.xml | 51 ++++++++++++++-------- OpenKeychain/src/main/res/values/strings.xml | 1 + 3 files changed, 39 insertions(+), 23 deletions(-) diff --git a/OpenKeychain/src/main/res/layout/view_key_activity.xml b/OpenKeychain/src/main/res/layout/view_key_activity.xml index b15a73c0e..451eb30ee 100644 --- a/OpenKeychain/src/main/res/layout/view_key_activity.xml +++ b/OpenKeychain/src/main/res/layout/view_key_activity.xml @@ -4,7 +4,7 @@ android:layout_height="match_parent" android:orientation="vertical"> - + + android:layout_height="wrap_content" /> + android:layout_marginLeft="8dp" /> diff --git a/OpenKeychain/src/main/res/layout/view_key_certs_fragment.xml b/OpenKeychain/src/main/res/layout/view_key_certs_fragment.xml index 00b3f85c5..0b63abbb1 100644 --- a/OpenKeychain/src/main/res/layout/view_key_certs_fragment.xml +++ b/OpenKeychain/src/main/res/layout/view_key_certs_fragment.xml @@ -1,24 +1,39 @@ - - - + android:layout_height="match_parent" + android:orientation="vertical"> + android:text="@string/certs_text" /> + + + + + + + + + + - diff --git a/OpenKeychain/src/main/res/values/strings.xml b/OpenKeychain/src/main/res/values/strings.xml index 7a4f41969..8d57f6f2e 100644 --- a/OpenKeychain/src/main/res/values/strings.xml +++ b/OpenKeychain/src/main/res/values/strings.xml @@ -698,6 +698,7 @@ Identity <unknown> No certificates for this key + Only certificates created with your keys and self-certificates are displayed here. Identities to certify Revocation Reason Verification Status -- cgit v1.2.3 From c1a265bfd17c6cb2fdc83403bcda6bb875c70e7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Tue, 19 Aug 2014 10:01:31 +0200 Subject: certs header design --- .../src/main/res/layout/view_key_certs_fragment.xml | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/OpenKeychain/src/main/res/layout/view_key_certs_fragment.xml b/OpenKeychain/src/main/res/layout/view_key_certs_fragment.xml index 0b63abbb1..1cf826b30 100644 --- a/OpenKeychain/src/main/res/layout/view_key_certs_fragment.xml +++ b/OpenKeychain/src/main/res/layout/view_key_certs_fragment.xml @@ -4,11 +4,19 @@ android:orientation="vertical"> + android:textAppearance="?android:attr/textAppearanceSmall" + android:text="@string/certs_text" + android:gravity="center_horizontal" /> + + Date: Tue, 19 Aug 2014 10:01:39 +0200 Subject: Add license headers --- .../keychain/pgp/PgpKeyOperationTest.java | 17 +++++++++++++++++ .../keychain/pgp/UncachedKeyringCanonicalizeTest.java | 17 +++++++++++++++++ .../keychain/pgp/UncachedKeyringMergeTest.java | 17 +++++++++++++++++ .../keychain/pgp/UncachedKeyringTest.java | 17 +++++++++++++++++ .../keychain/provider/ProviderHelperSaveTest.java | 17 +++++++++++++++++ .../keychain/support/KeyringTestingHelper.java | 1 + .../keychain/util/FileImportCacheTest.java | 17 +++++++++++++++++ .../keychain/ui/widget/CertifyKeySpinner.java | 17 +++++++++++++++++ .../keychain/ui/widget/KeySpinner.java | 17 +++++++++++++++++ .../keychain/ui/widget/SignKeySpinner.java | 17 +++++++++++++++++ 10 files changed, 154 insertions(+) diff --git a/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperationTest.java b/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperationTest.java index 964512617..3c54c3528 100644 --- a/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperationTest.java +++ b/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperationTest.java @@ -1,3 +1,20 @@ +/* + * Copyright (C) 2014 Dominik Schürmann + * + * 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 . + */ + package org.sufficientlysecure.keychain.pgp; import junit.framework.AssertionFailedError; diff --git a/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/UncachedKeyringCanonicalizeTest.java b/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/UncachedKeyringCanonicalizeTest.java index 6e3a9814e..1e4fb564a 100644 --- a/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/UncachedKeyringCanonicalizeTest.java +++ b/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/UncachedKeyringCanonicalizeTest.java @@ -1,3 +1,20 @@ +/* + * Copyright (C) 2014 Dominik Schürmann + * + * 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 . + */ + package org.sufficientlysecure.keychain.pgp; import org.junit.BeforeClass; diff --git a/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/UncachedKeyringMergeTest.java b/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/UncachedKeyringMergeTest.java index 428206c97..6324b65d8 100644 --- a/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/UncachedKeyringMergeTest.java +++ b/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/UncachedKeyringMergeTest.java @@ -1,3 +1,20 @@ +/* + * Copyright (C) 2014 Dominik Schürmann + * + * 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 . + */ + package org.sufficientlysecure.keychain.pgp; import org.junit.Assert; diff --git a/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/UncachedKeyringTest.java b/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/UncachedKeyringTest.java index 581e315a0..e25f0b081 100644 --- a/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/UncachedKeyringTest.java +++ b/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/UncachedKeyringTest.java @@ -1,3 +1,20 @@ +/* + * Copyright (C) 2014 Dominik Schürmann + * + * 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 . + */ + package org.sufficientlysecure.keychain.pgp; import org.junit.Assert; diff --git a/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/provider/ProviderHelperSaveTest.java b/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/provider/ProviderHelperSaveTest.java index 7a5afcc3a..065c1ffba 100644 --- a/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/provider/ProviderHelperSaveTest.java +++ b/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/provider/ProviderHelperSaveTest.java @@ -1,3 +1,20 @@ +/* + * Copyright (C) 2014 Dominik Schürmann + * + * 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 . + */ + package org.sufficientlysecure.keychain.provider; import org.junit.Assert; diff --git a/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/support/KeyringTestingHelper.java b/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/support/KeyringTestingHelper.java index 015e134ea..3bf046773 100644 --- a/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/support/KeyringTestingHelper.java +++ b/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/support/KeyringTestingHelper.java @@ -14,6 +14,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ + package org.sufficientlysecure.keychain.support; import android.content.Context; diff --git a/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/util/FileImportCacheTest.java b/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/util/FileImportCacheTest.java index 11bc05c9e..23649e6f8 100644 --- a/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/util/FileImportCacheTest.java +++ b/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/util/FileImportCacheTest.java @@ -1,3 +1,20 @@ +/* + * Copyright (C) 2014 Dominik Schürmann + * + * 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 . + */ + package org.sufficientlysecure.keychain.util; import android.os.Bundle; 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 030a76136..e3c9804bb 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 @@ -1,3 +1,20 @@ +/* + * Copyright (C) 2014 Dominik Schürmann + * + * 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 . + */ + package org.sufficientlysecure.keychain.ui.widget; import android.content.Context; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeySpinner.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeySpinner.java index b12029239..3a31fc9f4 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeySpinner.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeySpinner.java @@ -1,3 +1,20 @@ +/* + * Copyright (C) 2014 Dominik Schürmann + * + * 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 . + */ + package org.sufficientlysecure.keychain.ui.widget; import android.content.Context; 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 cbec7f920..a1ed2c065 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 @@ -1,3 +1,20 @@ +/* + * Copyright (C) 2014 Dominik Schürmann + * + * 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 . + */ + package org.sufficientlysecure.keychain.ui.widget; import android.content.Context; -- cgit v1.2.3 From a2b38245567ec314cbe1d428d8ad2082d1148134 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Tue, 19 Aug 2014 10:30:44 +0200 Subject: New preferred hash and symmetric algos, removed SHA-1, 3DES, new ordering --- .../keychain/pgp/PgpKeyOperation.java | 24 +++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) 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 cdd2eacc0..c6c064a25 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java @@ -84,15 +84,25 @@ import java.util.Stack; public class PgpKeyOperation { private Stack mProgress; + // most preferred is first private static final int[] PREFERRED_SYMMETRIC_ALGORITHMS = new int[]{ - SymmetricKeyAlgorithmTags.AES_256, SymmetricKeyAlgorithmTags.AES_192, - SymmetricKeyAlgorithmTags.AES_128, SymmetricKeyAlgorithmTags.CAST5, - SymmetricKeyAlgorithmTags.TRIPLE_DES}; - private static final int[] PREFERRED_HASH_ALGORITHMS = new int[]{HashAlgorithmTags.SHA1, - HashAlgorithmTags.SHA256, HashAlgorithmTags.RIPEMD160}; + 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}; + CompressionAlgorithmTags.ZLIB, + CompressionAlgorithmTags.BZIP2, + CompressionAlgorithmTags.ZIP + }; public PgpKeyOperation(Progressable progress) { super(); -- cgit v1.2.3 From 2c8bcffff3d04a84e7fb51efac6b099a477a98f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Tue, 19 Aug 2014 10:37:27 +0200 Subject: add feature to key sig subpacket to indicate that we want MDC --- .../main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java | 3 +++ 1 file changed, 3 insertions(+) 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 c6c064a25..7dedcb242 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java @@ -22,6 +22,7 @@ import org.spongycastle.bcpg.CompressionAlgorithmTags; import org.spongycastle.bcpg.HashAlgorithmTags; import org.spongycastle.bcpg.PublicKeyAlgorithmTags; import org.spongycastle.bcpg.SymmetricKeyAlgorithmTags; +import org.spongycastle.bcpg.sig.Features; import org.spongycastle.bcpg.sig.KeyFlags; import org.spongycastle.jce.spec.ElGamalParameterSpec; import org.spongycastle.openpgp.PGPEncryptedData; @@ -894,6 +895,8 @@ public class PgpKeyOperation { hashedPacketsGen.setPreferredSymmetricAlgorithms(true, PREFERRED_SYMMETRIC_ALGORITHMS); hashedPacketsGen.setPreferredHashAlgorithms(true, PREFERRED_HASH_ALGORITHMS); hashedPacketsGen.setPreferredCompressionAlgorithms(true, PREFERRED_COMPRESSION_ALGORITHMS); + // Request senders add additional checksums to the message (useful when verifying unsigned messages.) + hashedPacketsGen.setFeature(true, Features.FEATURE_MODIFICATION_DETECTION); hashedPacketsGen.setPrimaryUserID(false, primary); hashedPacketsGen.setKeyFlags(false, flags); if (expiry > 0) { -- cgit v1.2.3 From b1bde6ead93f61d471c7fcd183c50da81d7ee848 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Tue, 19 Aug 2014 10:42:35 +0200 Subject: Mark packets critical --- .../keychain/pgp/PgpKeyOperation.java | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) 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 7dedcb242..c1c261126 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java @@ -891,17 +891,17 @@ public class PgpKeyOperation { PGPSignatureSubpacketGenerator hashedPacketsGen = new PGPSignatureSubpacketGenerator(); { - hashedPacketsGen.setSignatureCreationTime(false, new Date()); + hashedPacketsGen.setSignatureCreationTime(true, new Date()); hashedPacketsGen.setPreferredSymmetricAlgorithms(true, PREFERRED_SYMMETRIC_ALGORITHMS); hashedPacketsGen.setPreferredHashAlgorithms(true, PREFERRED_HASH_ALGORITHMS); hashedPacketsGen.setPreferredCompressionAlgorithms(true, PREFERRED_COMPRESSION_ALGORITHMS); - // Request senders add additional checksums to the message (useful when verifying unsigned messages.) + // Request that senders add the MDC to the message (useful when verifying unsigned messages.) hashedPacketsGen.setFeature(true, Features.FEATURE_MODIFICATION_DETECTION); - hashedPacketsGen.setPrimaryUserID(false, primary); - hashedPacketsGen.setKeyFlags(false, flags); + hashedPacketsGen.setPrimaryUserID(true, primary); + hashedPacketsGen.setKeyFlags(true, flags); if (expiry > 0) { hashedPacketsGen.setKeyExpirationTime( - false, expiry - pKey.getCreationTime().getTime() / 1000); + true, expiry - pKey.getCreationTime().getTime() / 1000); } } @@ -918,7 +918,7 @@ public class PgpKeyOperation { .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME); PGPSignatureGenerator sGen = new PGPSignatureGenerator(signerBuilder); PGPSignatureSubpacketGenerator subHashedPacketsGen = new PGPSignatureSubpacketGenerator(); - subHashedPacketsGen.setSignatureCreationTime(false, new Date()); + subHashedPacketsGen.setSignatureCreationTime(true, new Date()); sGen.setHashedSubpackets(subHashedPacketsGen.generate()); sGen.init(PGPSignature.CERTIFICATION_REVOCATION, masterPrivateKey); return sGen.generateCertification(userId, pKey); @@ -932,7 +932,7 @@ public class PgpKeyOperation { .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME); PGPSignatureGenerator sGen = new PGPSignatureGenerator(signerBuilder); PGPSignatureSubpacketGenerator subHashedPacketsGen = new PGPSignatureSubpacketGenerator(); - subHashedPacketsGen.setSignatureCreationTime(false, new Date()); + subHashedPacketsGen.setSignatureCreationTime(true, new Date()); sGen.setHashedSubpackets(subHashedPacketsGen.generate()); // Generate key revocation or subkey revocation, depending on master/subkey-ness if (masterPublicKey.getKeyID() == pKey.getKeyID()) { @@ -978,16 +978,16 @@ public class PgpKeyOperation { sGen.init(PGPSignature.PRIMARYKEY_BINDING, subPrivateKey); sGen.setHashedSubpackets(subHashedPacketsGen.generate()); PGPSignature certification = sGen.generateCertification(masterPublicKey, pKey); - unhashedPacketsGen.setEmbeddedSignature(false, certification); + unhashedPacketsGen.setEmbeddedSignature(true, certification); } PGPSignatureSubpacketGenerator hashedPacketsGen; { hashedPacketsGen = new PGPSignatureSubpacketGenerator(); - hashedPacketsGen.setSignatureCreationTime(false, creationTime); - hashedPacketsGen.setKeyFlags(false, flags); + hashedPacketsGen.setSignatureCreationTime(true, creationTime); + hashedPacketsGen.setKeyFlags(true, flags); if (expiry > 0) { - hashedPacketsGen.setKeyExpirationTime(false, + hashedPacketsGen.setKeyExpirationTime(true, expiry - pKey.getCreationTime().getTime() / 1000); } } -- cgit v1.2.3 From d131693bb89f2bddd194993be45aeb13402196a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Tue, 19 Aug 2014 10:58:38 +0200 Subject: Use SHA512 instead of SHA1 and AES256 instead of CAST5 where possible --- .../keychain/pgp/PgpKeyOperation.java | 42 +++++++++++----------- 1 file changed, 22 insertions(+), 20 deletions(-) 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 c1c261126..b143085d5 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java @@ -35,7 +35,6 @@ import org.spongycastle.openpgp.PGPSecretKeyRing; import org.spongycastle.openpgp.PGPSignature; import org.spongycastle.openpgp.PGPSignatureGenerator; import org.spongycastle.openpgp.PGPSignatureSubpacketGenerator; -import org.spongycastle.openpgp.PGPUtil; import org.spongycastle.openpgp.operator.PBESecretKeyDecryptor; import org.spongycastle.openpgp.operator.PBESecretKeyEncryptor; import org.spongycastle.openpgp.operator.PGPContentSignerBuilder; @@ -250,13 +249,16 @@ public class PgpKeyOperation { progress(R.string.progress_building_master_key, 40); - // define hashing and signing algos - PGPDigestCalculator sha1Calc = new JcaPGPDigestCalculatorProviderBuilder() - .build().get(HashAlgorithmTags.SHA1); // Build key encrypter and decrypter based on passphrase + PGPDigestCalculator sha512Calc = new JcaPGPDigestCalculatorProviderBuilder() + .build().get(HashAlgorithmTags.SHA512); PBESecretKeyEncryptor keyEncryptor = new JcePBESecretKeyEncryptorBuilder( - PGPEncryptedData.CAST5, sha1Calc) + PGPEncryptedData.AES_256, sha512Calc) .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); PGPSecretKey masterSecretKey = new PGPSecretKey(keyPair.getPrivateKey(), keyPair.getPublicKey(), sha1Calc, true, keyEncryptor); @@ -702,17 +704,17 @@ public class PgpKeyOperation { pKey = PGPPublicKey.addSubkeyBindingCertification(pKey, cert); PGPSecretKey sKey; { - // define hashing and signing algos - PGPDigestCalculator sha1Calc = new JcaPGPDigestCalculatorProviderBuilder() - .build().get(HashAlgorithmTags.SHA1); - // Build key encrypter and decrypter based on passphrase + PGPDigestCalculator sha512Calc = new JcaPGPDigestCalculatorProviderBuilder() + .build().get(HashAlgorithmTags.SHA512); PBESecretKeyEncryptor keyEncryptor = new JcePBESecretKeyEncryptorBuilder( - PGPEncryptedData.CAST5, sha1Calc) + PGPEncryptedData.AES_256, sha512Calc) .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(passphrase.toCharArray()); - sKey = new PGPSecretKey(keyPair.getPrivateKey(), pKey, - sha1Calc, false, keyEncryptor); + // NOTE: only SHA1 is supported for key checksum calculations. + PGPDigestCalculator sha1Calc = new JcaPGPDigestCalculatorProviderBuilder() + .build().get(HashAlgorithmTags.SHA1); + sKey = new PGPSecretKey(keyPair.getPrivateKey(), pKey, sha1Calc, false, keyEncryptor); } log.add(LogLevel.DEBUG, LogType.MSG_MF_SUBKEY_NEW_ID, @@ -729,13 +731,13 @@ public class PgpKeyOperation { log.add(LogLevel.INFO, LogType.MSG_MF_PASSPHRASE, indent); indent += 1; - PGPDigestCalculator sha1Calc = new JcaPGPDigestCalculatorProviderBuilder().build() - .get(HashAlgorithmTags.SHA1); + PGPDigestCalculator sha512Calc = new JcaPGPDigestCalculatorProviderBuilder().build() + .get(HashAlgorithmTags.SHA512); PBESecretKeyDecryptor keyDecryptor = new JcePBESecretKeyDecryptorBuilder().setProvider( Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(passphrase.toCharArray()); // Build key encryptor based on new passphrase PBESecretKeyEncryptor keyEncryptorNew = new JcePBESecretKeyEncryptorBuilder( - PGPEncryptedData.CAST5, sha1Calc) + PGPEncryptedData.AES_256, sha512Calc) .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build( saveParcel.mNewPassphrase.toCharArray()); @@ -885,7 +887,7 @@ public class PgpKeyOperation { int flags, long expiry) throws IOException, PGPException, SignatureException { PGPContentSignerBuilder signerBuilder = new JcaPGPContentSignerBuilder( - masterPrivateKey.getPublicKeyPacket().getAlgorithm(), PGPUtil.SHA1) + masterPrivateKey.getPublicKeyPacket().getAlgorithm(), HashAlgorithmTags.SHA512) .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME); PGPSignatureGenerator sGen = new PGPSignatureGenerator(signerBuilder); @@ -914,7 +916,7 @@ public class PgpKeyOperation { PGPPrivateKey masterPrivateKey, PGPPublicKey pKey, String userId) throws IOException, PGPException, SignatureException { PGPContentSignerBuilder signerBuilder = new JcaPGPContentSignerBuilder( - masterPrivateKey.getPublicKeyPacket().getAlgorithm(), PGPUtil.SHA1) + masterPrivateKey.getPublicKeyPacket().getAlgorithm(), HashAlgorithmTags.SHA512) .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME); PGPSignatureGenerator sGen = new PGPSignatureGenerator(signerBuilder); PGPSignatureSubpacketGenerator subHashedPacketsGen = new PGPSignatureSubpacketGenerator(); @@ -928,7 +930,7 @@ public class PgpKeyOperation { PGPPublicKey masterPublicKey, PGPPrivateKey masterPrivateKey, PGPPublicKey pKey) throws IOException, PGPException, SignatureException { PGPContentSignerBuilder signerBuilder = new JcaPGPContentSignerBuilder( - masterPublicKey.getAlgorithm(), PGPUtil.SHA1) + masterPublicKey.getAlgorithm(), HashAlgorithmTags.SHA512) .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME); PGPSignatureGenerator sGen = new PGPSignatureGenerator(signerBuilder); PGPSignatureSubpacketGenerator subHashedPacketsGen = new PGPSignatureSubpacketGenerator(); @@ -972,7 +974,7 @@ public class PgpKeyOperation { PGPSignatureSubpacketGenerator subHashedPacketsGen = new PGPSignatureSubpacketGenerator(); subHashedPacketsGen.setSignatureCreationTime(false, creationTime); PGPContentSignerBuilder signerBuilder = new JcaPGPContentSignerBuilder( - pKey.getAlgorithm(), PGPUtil.SHA1) + pKey.getAlgorithm(), HashAlgorithmTags.SHA512) .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME); PGPSignatureGenerator sGen = new PGPSignatureGenerator(signerBuilder); sGen.init(PGPSignature.PRIMARYKEY_BINDING, subPrivateKey); @@ -993,7 +995,7 @@ public class PgpKeyOperation { } PGPContentSignerBuilder signerBuilder = new JcaPGPContentSignerBuilder( - masterPublicKey.getAlgorithm(), PGPUtil.SHA1) + masterPublicKey.getAlgorithm(), HashAlgorithmTags.SHA512) .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME); PGPSignatureGenerator sGen = new PGPSignatureGenerator(signerBuilder); sGen.init(PGPSignature.SUBKEY_BINDING, masterPrivateKey); -- cgit v1.2.3 From 4a280f6ba36f35d21e87642d74d3e9dfdf6f09d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Tue, 19 Aug 2014 11:11:58 +0200 Subject: Use higher s2k count --- .../keychain/pgp/PgpKeyOperation.java | 39 ++++++++++++++++------ 1 file changed, 29 insertions(+), 10 deletions(-) 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 b143085d5..c69eeaf04 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java @@ -25,7 +25,6 @@ import org.spongycastle.bcpg.SymmetricKeyAlgorithmTags; import org.spongycastle.bcpg.sig.Features; import org.spongycastle.bcpg.sig.KeyFlags; import org.spongycastle.jce.spec.ElGamalParameterSpec; -import org.spongycastle.openpgp.PGPEncryptedData; import org.spongycastle.openpgp.PGPException; import org.spongycastle.openpgp.PGPKeyPair; import org.spongycastle.openpgp.PGPPrivateKey; @@ -104,6 +103,26 @@ public class PgpKeyOperation { 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. I'll use 0xc0 as a + * default -- about 130,000 iterations. + * + * http://kbsriram.com/2013/01/generating-rsa-keys-with-bouncycastle.html + */ + private static final int SECRET_KEY_ENCRYPTOR_HASH_ALGO = HashAlgorithmTags.SHA512; + private static final int SECRET_KEY_ENCRYPTOR_SYMMETRIC_ALGO = SymmetricKeyAlgorithmTags.AES_256; + private static final int SECRET_KEY_ENCRYPTOR_S2K_COUNT = 0xc0; + public PgpKeyOperation(Progressable progress) { super(); if (progress != null) { @@ -250,10 +269,10 @@ public class PgpKeyOperation { progress(R.string.progress_building_master_key, 40); // Build key encrypter and decrypter based on passphrase - PGPDigestCalculator sha512Calc = new JcaPGPDigestCalculatorProviderBuilder() - .build().get(HashAlgorithmTags.SHA512); + PGPDigestCalculator encryptorHashCalc = new JcaPGPDigestCalculatorProviderBuilder() + .build().get(SECRET_KEY_ENCRYPTOR_HASH_ALGO); PBESecretKeyEncryptor keyEncryptor = new JcePBESecretKeyEncryptorBuilder( - PGPEncryptedData.AES_256, sha512Calc) + SECRET_KEY_ENCRYPTOR_SYMMETRIC_ALGO, encryptorHashCalc, SECRET_KEY_ENCRYPTOR_S2K_COUNT) .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build("".toCharArray()); // NOTE: only SHA1 is supported for key checksum calculations. @@ -705,10 +724,10 @@ public class PgpKeyOperation { PGPSecretKey sKey; { // Build key encrypter and decrypter based on passphrase - PGPDigestCalculator sha512Calc = new JcaPGPDigestCalculatorProviderBuilder() - .build().get(HashAlgorithmTags.SHA512); + PGPDigestCalculator encryptorHashCalc = new JcaPGPDigestCalculatorProviderBuilder() + .build().get(SECRET_KEY_ENCRYPTOR_HASH_ALGO); PBESecretKeyEncryptor keyEncryptor = new JcePBESecretKeyEncryptorBuilder( - PGPEncryptedData.AES_256, sha512Calc) + SECRET_KEY_ENCRYPTOR_SYMMETRIC_ALGO, encryptorHashCalc, SECRET_KEY_ENCRYPTOR_S2K_COUNT) .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(passphrase.toCharArray()); // NOTE: only SHA1 is supported for key checksum calculations. @@ -731,13 +750,13 @@ public class PgpKeyOperation { log.add(LogLevel.INFO, LogType.MSG_MF_PASSPHRASE, indent); indent += 1; - PGPDigestCalculator sha512Calc = new JcaPGPDigestCalculatorProviderBuilder().build() - .get(HashAlgorithmTags.SHA512); + PGPDigestCalculator encryptorHashCalc = new JcaPGPDigestCalculatorProviderBuilder().build() + .get(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( - PGPEncryptedData.AES_256, sha512Calc) + SECRET_KEY_ENCRYPTOR_SYMMETRIC_ALGO, encryptorHashCalc, SECRET_KEY_ENCRYPTOR_S2K_COUNT) .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build( saveParcel.mNewPassphrase.toCharArray()); -- cgit v1.2.3 From c1d05d0ee92e9c9bc2a12a64aa4b73e832fbde0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Tue, 19 Aug 2014 14:16:30 +0200 Subject: Change criticallity of subpackets after discussion --- .../org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) 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 c69eeaf04..85e772d52 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java @@ -913,12 +913,12 @@ public class PgpKeyOperation { PGPSignatureSubpacketGenerator hashedPacketsGen = new PGPSignatureSubpacketGenerator(); { hashedPacketsGen.setSignatureCreationTime(true, new Date()); - hashedPacketsGen.setPreferredSymmetricAlgorithms(true, PREFERRED_SYMMETRIC_ALGORITHMS); - hashedPacketsGen.setPreferredHashAlgorithms(true, PREFERRED_HASH_ALGORITHMS); - hashedPacketsGen.setPreferredCompressionAlgorithms(true, PREFERRED_COMPRESSION_ALGORITHMS); - // Request that senders add the MDC to the message (useful when verifying unsigned messages.) + hashedPacketsGen.setPreferredSymmetricAlgorithms(false, PREFERRED_SYMMETRIC_ALGORITHMS); + hashedPacketsGen.setPreferredHashAlgorithms(false, PREFERRED_HASH_ALGORITHMS); + hashedPacketsGen.setPreferredCompressionAlgorithms(false, PREFERRED_COMPRESSION_ALGORITHMS); + // Request that senders add the MDC to the message (authenticate unsigned messages) hashedPacketsGen.setFeature(true, Features.FEATURE_MODIFICATION_DETECTION); - hashedPacketsGen.setPrimaryUserID(true, primary); + hashedPacketsGen.setPrimaryUserID(false, primary); hashedPacketsGen.setKeyFlags(true, flags); if (expiry > 0) { hashedPacketsGen.setKeyExpirationTime( -- cgit v1.2.3 From 6a3150d8788664a5e1d501488159ff5e080cb9b4 Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Tue, 19 Aug 2014 14:42:40 +0200 Subject: fix primary user id in master key flag modification --- .../java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) 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 c69eeaf04..88c6437d3 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java @@ -881,10 +881,12 @@ public class PgpKeyOperation { } // add shiny new user id certificate + boolean isPrimary = currentCert.getHashedSubPackets() != null && + currentCert.getHashedSubPackets().isPrimaryUserID(); modifiedPublicKey = PGPPublicKey.removeCertification( modifiedPublicKey, userId, currentCert); PGPSignature newCert = generateUserIdSignature( - masterPrivateKey, masterPublicKey, userId, true, flags, expiry); + masterPrivateKey, masterPublicKey, userId, isPrimary, flags, expiry); modifiedPublicKey = PGPPublicKey.addCertification( modifiedPublicKey, userId, newCert); ok = true; -- cgit v1.2.3 From 9474749be15b49c89b6e2de820f62b2e0029f393 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Tue, 19 Aug 2014 14:51:28 +0200 Subject: Decrease iteration count, delayed for 2.9 --- .../main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 913bfafed..6228b36ac 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java @@ -121,7 +121,7 @@ public class PgpKeyOperation { */ private static final int SECRET_KEY_ENCRYPTOR_HASH_ALGO = HashAlgorithmTags.SHA512; private static final int SECRET_KEY_ENCRYPTOR_SYMMETRIC_ALGO = SymmetricKeyAlgorithmTags.AES_256; - private static final int SECRET_KEY_ENCRYPTOR_S2K_COUNT = 0xc0; + private static final int SECRET_KEY_ENCRYPTOR_S2K_COUNT = 0x60; public PgpKeyOperation(Progressable progress) { super(); -- cgit v1.2.3 From 68cce5c0c85aea44257f294369a0abe316dd2347 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Tue, 19 Aug 2014 14:53:25 +0200 Subject: Bouncy Castle link --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 4b8f23063..a9b03b2c3 100644 --- a/README.md +++ b/README.md @@ -107,6 +107,7 @@ see * Tests in https://github.com/bcgit/bc-java/tree/master/pg/src/test/java/org/bouncycastle/openpgp/test * Examples in https://github.com/bcgit/bc-java/tree/master/pg/src/main/java/org/bouncycastle/openpgp/examples * Mailinglist Archive at http://bouncy-castle.1462172.n4.nabble.com/Bouncy-Castle-Dev-f1462173.html +* Commit changelog of pg subpackage: https://github.com/bcgit/bc-java/commits/master/pg ## Notes -- cgit v1.2.3 From 8d668d170c41959897aa78e2f0acc9fac7168d36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Tue, 19 Aug 2014 15:23:37 +0200 Subject: Notes about criticality --- .../keychain/pgp/PgpKeyOperation.java | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) 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 6228b36ac..b4e21cc0e 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java @@ -914,13 +914,26 @@ public class PgpKeyOperation { PGPSignatureSubpacketGenerator hashedPacketsGen = new PGPSignatureSubpacketGenerator(); { - hashedPacketsGen.setSignatureCreationTime(true, new Date()); + /* + * From RFC about critical subpackets: + * If a subpacket is encountered that is + * marked critical but is unknown to the evaluating software, the + * evaluator SHOULD consider the signature to be in error. + * An evaluator may "recognize" a subpacket, but not implement it. The + * purpose of the critical bit is to allow the signer to tell an + * evaluator that it would prefer a new, unknown feature to generate an + * 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.setPrimaryUserID(false, primary); + + /* critical subpackets: */ + hashedPacketsGen.setSignatureCreationTime(true, new Date()); // Request that senders add the MDC to the message (authenticate unsigned messages) hashedPacketsGen.setFeature(true, Features.FEATURE_MODIFICATION_DETECTION); - hashedPacketsGen.setPrimaryUserID(false, primary); hashedPacketsGen.setKeyFlags(true, flags); if (expiry > 0) { hashedPacketsGen.setKeyExpirationTime( -- cgit v1.2.3 From c725239a69544213229e2d1d0b69b4dca0bcc5d9 Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Tue, 19 Aug 2014 15:45:42 +0200 Subject: consolidate: split into two steps, can pick up at second step if anything fails --- .../org/sufficientlysecure/keychain/Constants.java | 3 + .../keychain/helper/Preferences.java | 31 +++++++++++ .../keychain/provider/ProviderHelper.java | 65 +++++++++++++++++----- .../keychain/service/KeychainIntentService.java | 13 +---- .../keychain/service/OperationResultParcel.java | 1 + .../keychain/util/FileImportCache.java | 22 +++++++- OpenKeychain/src/main/res/values/strings.xml | 3 + 7 files changed, 112 insertions(+), 26 deletions(-) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/Constants.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/Constants.java index bce093427..78b66464b 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/Constants.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/Constants.java @@ -68,6 +68,9 @@ public final class Constants { public static final String KEY_SERVERS_DEFAULT_VERSION = "keyServersDefaultVersion"; public static final String WRITE_VERSION_HEADER = "writeVersionHeader"; public static final String FIRST_TIME = "firstTime"; + public static final String CACHED_CONSOLIDATE = "cachedConsolidate"; + public static final String CACHED_CONSOLIDATE_SECRETS = "cachedConsolidateSecrets"; + public static final String CACHED_CONSOLIDATE_PUBLICS = "cachedConsolidatePublics"; } public static final class Defaults { diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/helper/Preferences.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/helper/Preferences.java index 14ae46840..9a10148f2 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/helper/Preferences.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/helper/Preferences.java @@ -25,6 +25,7 @@ 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; import java.util.ArrayList; import java.util.Arrays; @@ -134,6 +135,36 @@ public class Preferences { editor.commit(); } + public boolean getCachedConsolidate() { + return mSharedPreferences.getBoolean(Pref.CACHED_CONSOLIDATE, false); + } + + public void setCachedConsolidate(boolean value) { + SharedPreferences.Editor editor = mSharedPreferences.edit(); + editor.putBoolean(Pref.CACHED_CONSOLIDATE, value); + editor.commit(); + } + + public int getCachedConsolidateNumPublics() { + return mSharedPreferences.getInt(Pref.CACHED_CONSOLIDATE_PUBLICS, 100); + } + + public void setCachedConsolidateNumPublics(int value) { + SharedPreferences.Editor editor = mSharedPreferences.edit(); + editor.putInt(Pref.CACHED_CONSOLIDATE_PUBLICS, value); + editor.commit(); + } + + public int getCachedConsolidateNumSecrets() { + return mSharedPreferences.getInt(Pref.CACHED_CONSOLIDATE_SECRETS, 100); + } + + public void setCachedConsolidateNumSecrets(int value) { + SharedPreferences.Editor editor = mSharedPreferences.edit(); + editor.putInt(Pref.CACHED_CONSOLIDATE_SECRETS, value); + editor.commit(); + } + public boolean isFirstTime() { return mSharedPreferences.getBoolean(Constants.Pref.FIRST_TIME, true); } 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 3594ded51..5f55eedd5 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java @@ -28,6 +28,8 @@ import android.os.RemoteException; import android.support.v4.util.LongSparseArray; import org.sufficientlysecure.keychain.Constants; +import org.sufficientlysecure.keychain.R; +import org.sufficientlysecure.keychain.helper.Preferences; import org.sufficientlysecure.keychain.keyimport.ParcelableKeyRing; import org.sufficientlysecure.keychain.pgp.CanonicalizedPublicKey; import org.sufficientlysecure.keychain.pgp.CanonicalizedPublicKeyRing; @@ -58,6 +60,7 @@ import org.sufficientlysecure.keychain.service.OperationResults.SaveKeyringResul import org.sufficientlysecure.keychain.util.FileImportCache; import org.sufficientlysecure.keychain.util.IterableIterator; import org.sufficientlysecure.keychain.util.Log; +import org.sufficientlysecure.keychain.util.ProgressFixedScaler; import org.sufficientlysecure.keychain.util.ProgressScaler; import java.io.ByteArrayOutputStream; @@ -823,11 +826,9 @@ public class ProviderHelper { } - public ConsolidateResult consolidateDatabase(Progressable progress) { + public ConsolidateResult consolidateDatabaseStep1(Progressable progress) { // 1a. fetch all secret keyrings into a cache file - int numSecrets, numPublics; - log(LogLevel.START, LogType.MSG_CON, mIndent); mIndent += 1; @@ -836,7 +837,7 @@ public class ProviderHelper { log(LogLevel.DEBUG, LogType.MSG_CON_SAVE_SECRET, mIndent); mIndent += 1; - final Cursor cursor = mContentResolver.query(KeyRings.buildUnifiedKeyRingsUri(), new String[] { + final Cursor cursor = mContentResolver.query(KeyRings.buildUnifiedKeyRingsUri(), new String[]{ KeyRings.PRIVKEY_DATA, KeyRings.FINGERPRINT, KeyRings.HAS_ANY_SECRET }, KeyRings.HAS_ANY_SECRET + " = 1", null, null); @@ -844,7 +845,7 @@ public class ProviderHelper { return new ConsolidateResult(ConsolidateResult.RESULT_ERROR, mLog); } - numSecrets = cursor.getCount(); + Preferences.getPreferences(mContext).setCachedConsolidateNumSecrets(cursor.getCount()); FileImportCache cache = new FileImportCache(mContext, "consolidate_secret.pcl"); @@ -894,7 +895,7 @@ public class ProviderHelper { log(LogLevel.DEBUG, LogType.MSG_CON_SAVE_PUBLIC, mIndent); mIndent += 1; - final Cursor cursor = mContentResolver.query(KeyRings.buildUnifiedKeyRingsUri(), new String[] { + final Cursor cursor = mContentResolver.query(KeyRings.buildUnifiedKeyRingsUri(), new String[]{ KeyRings.PUBKEY_DATA, KeyRings.FINGERPRINT }, null, null, null); @@ -902,7 +903,7 @@ public class ProviderHelper { return new ConsolidateResult(ConsolidateResult.RESULT_ERROR, mLog); } - numPublics = cursor.getCount(); + Preferences.getPreferences(mContext).setCachedConsolidateNumSecrets(cursor.getCount()); FileImportCache cache = new FileImportCache(mContext, "consolidate_public.pcl"); @@ -946,19 +947,39 @@ public class ProviderHelper { mIndent -= 1; } + Preferences.getPreferences(mContext).setCachedConsolidate(true); + + return consolidateDatabaseStep2(progress); + } + + public ConsolidateResult consolidateDatabaseStep2(Progressable progress) { + + Preferences prefs = Preferences.getPreferences(mContext); + if ( ! prefs.getCachedConsolidate()) { + log(LogLevel.ERROR, LogType.MSG_CON_ERROR_BAD_STATE); + return new ConsolidateResult(ConsolidateResult.RESULT_ERROR, mLog); + } + + // Set flag that we have a cached consolidation here + int numSecrets = prefs.getCachedConsolidateNumSecrets(); + int numPublics = prefs.getCachedConsolidateNumPublics(); + // 2. wipe database (IT'S DANGEROUS) log(LogLevel.DEBUG, LogType.MSG_CON_DB_CLEAR, mIndent); new KeychainDatabase(mContext).clearDatabase(); + FileImportCache cacheSecret = + new FileImportCache(mContext, "consolidate_secret.pcl"); + FileImportCache cachePublic = + new FileImportCache(mContext, "consolidate_public.pcl"); + // 3. Re-Import secret keyrings from cache try { log(LogLevel.DEBUG, LogType.MSG_CON_REIMPORT_SECRET, mIndent, numSecrets); mIndent += 1; - FileImportCache cache = - new FileImportCache(mContext, "consolidate_secret.pcl"); - new PgpImportExport(mContext, this, new ProgressScaler(progress, 10, 25, 100)) - .importKeyRings(cache.readCache(), numSecrets); + new PgpImportExport(mContext, this, new ProgressFixedScaler(progress, 10, 25, 100, R.string.progress_con_reimport)) + .importKeyRings(cacheSecret.readCache(false), numSecrets); } catch (IOException e) { Log.e(Constants.TAG, "error importing secret"); return new ConsolidateResult(ConsolidateResult.RESULT_ERROR, mLog); @@ -966,15 +987,13 @@ public class ProviderHelper { mIndent -= 1; } - // 3. Re-Import public keyrings from cache + // 4. Re-Import public keyrings from cache try { log(LogLevel.DEBUG, LogType.MSG_CON_REIMPORT_PUBLIC, mIndent, numPublics); mIndent += 1; - FileImportCache cache = - new FileImportCache(mContext, "consolidate_public.pcl"); new PgpImportExport(mContext, this, new ProgressScaler(progress, 25, 99, 100)) - .importKeyRings(cache.readCache(), numPublics); + .importKeyRings(cachePublic.readCache(false), numPublics); } catch (IOException e) { Log.e(Constants.TAG, "error importing public"); return new ConsolidateResult(ConsolidateResult.RESULT_ERROR, mLog); @@ -982,6 +1001,22 @@ public class ProviderHelper { mIndent -= 1; } + Preferences.getPreferences(mContext).setCachedConsolidate(false); + + // 5. Delete caches + try { + cacheSecret.delete(); + } catch (IOException e) { + // doesn't really matter + Log.e(Constants.TAG, "IOException during delete of secret cache", e); + } + try { + cachePublic.delete(); + } catch (IOException e) { + // doesn't really matter + Log.e(Constants.TAG, "IOException during deletion of public cache", e); + } + progress.setProgress(100, 100); log(LogLevel.OK, LogType.MSG_CON_SUCCESS, mIndent); mIndent -= 1; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java index 9f5650df6..2c1bc8463 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java @@ -490,10 +490,7 @@ public class KeychainIntentService extends IntentService PgpImportExport pgpImportExport = new PgpImportExport(this, this); ImportKeyResult result = pgpImportExport.importKeyRings(entries); - Bundle resultData = new Bundle(); - resultData.putParcelable(RESULT_IMPORT, result); - - sendMessageToHandler(KeychainIntentServiceHandler.MESSAGE_OKAY, resultData); + sendMessageToHandler(KeychainIntentServiceHandler.MESSAGE_OKAY, result); } catch (Exception e) { sendErrorToHandler(e); } @@ -670,12 +667,8 @@ public class KeychainIntentService extends IntentService } } else if (ACTION_CONSOLIDATE.equals(action)) { - ConsolidateResult result = new ProviderHelper(this).consolidateDatabase(this); - - Bundle resultData = new Bundle(); - resultData.putParcelable(RESULT_CONSOLIDATE, result); - - sendMessageToHandler(KeychainIntentServiceHandler.MESSAGE_OKAY, resultData); + ConsolidateResult result = new ProviderHelper(this).consolidateDatabaseStep1(this); + sendMessageToHandler(KeychainIntentServiceHandler.MESSAGE_OKAY, result); } } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/OperationResultParcel.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/OperationResultParcel.java index c601ec57e..3f478cfed 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/OperationResultParcel.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/OperationResultParcel.java @@ -391,6 +391,7 @@ public class OperationResultParcel implements Parcelable { // consolidate MSG_CON (R.string.msg_con), + MSG_CON_ERROR_BAD_STATE (R.string.msg_con_error_bad_state), MSG_CON_SAVE_SECRET (R.string.msg_con_save_secret), MSG_CON_SAVE_PUBLIC (R.string.msg_con_save_public), MSG_CON_DB_CLEAR (R.string.msg_con_db_clear), diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/FileImportCache.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/FileImportCache.java index 35833adc6..09275fc95 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/FileImportCache.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/FileImportCache.java @@ -92,6 +92,10 @@ public class FileImportCache { } public Iterator readCache() throws IOException { + return readCache(true); + } + + public Iterator readCache(final boolean deleteAfterRead) throws IOException { File cacheDir = mContext.getCacheDir(); if (cacheDir == null) { @@ -166,7 +170,10 @@ public class FileImportCache { if (!closed) { try { ois.close(); - tempFile.delete(); + if (deleteAfterRead) { + //noinspection ResultOfMethodCallIgnored + tempFile.delete(); + } } catch (IOException e) { // nvm } @@ -177,4 +184,17 @@ public class FileImportCache { }; } + + public boolean delete() throws IOException { + + File cacheDir = mContext.getCacheDir(); + if (cacheDir == null) { + // https://groups.google.com/forum/#!topic/android-developers/-694j87eXVU + throw new IOException("cache dir is null!"); + } + + final File tempFile = new File(cacheDir, mFilename); + return tempFile.delete(); + } + } diff --git a/OpenKeychain/src/main/res/values/strings.xml b/OpenKeychain/src/main/res/values/strings.xml index 8d57f6f2e..e506bf488 100644 --- a/OpenKeychain/src/main/res/values/strings.xml +++ b/OpenKeychain/src/main/res/values/strings.xml @@ -302,6 +302,8 @@ verifying integrity… deleting \'%s\' securely… + reimporting database… + Name/Email/Key ID… Name/Email/Proof/Key… @@ -671,6 +673,7 @@ Consolidating database + Consolidation started while no database was cached! This is probably a programming error, please file a bug report. Saving secret keyrings Saving public keyrings Clearing database -- cgit v1.2.3 From a2ae318a1adb355efd593b8fd8041d75c25866b3 Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Tue, 19 Aug 2014 15:55:40 +0200 Subject: add OpenDialogActivity (stub) --- .../keychain/ui/OpenDialogActivity.java | 117 +++++++++++++++++++++ 1 file changed, 117 insertions(+) create mode 100644 OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/OpenDialogActivity.java diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/OpenDialogActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/OpenDialogActivity.java new file mode 100644 index 000000000..cdb09bbd0 --- /dev/null +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/OpenDialogActivity.java @@ -0,0 +1,117 @@ +/* + * Copyright (C) 2014 Dominik Schürmann + * + * 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 . + */ + +package org.sufficientlysecure.keychain.ui; + +import android.app.Dialog; +import android.app.DialogFragment; +import android.app.ProgressDialog; +import android.content.DialogInterface; +import android.os.Bundle; +import android.os.Message; +import android.os.Messenger; +import android.os.RemoteException; +import android.support.v4.app.FragmentActivity; +import android.util.Log; +import android.view.ContextThemeWrapper; + +import org.sufficientlysecure.keychain.Constants; + +/** + * We can not directly create a dialog on the context provided inside the content provider. + * This activity encapsulates a DialogFragment to emulate a dialog. + */ +public class OpenDialogActivity extends FragmentActivity { + + public static final String EXTRA_MESSENGER = "messenger"; + public static final String EXTRA_FILENAME = "filename"; + + public static final int MSG_CANCEL = 1; + public static final int MSG_DECRYPT_OPEN = 2; + public static final int MSG_GET_ENCRYPTED = 3; + + MyDialogFragment mDialogFragment; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + // this activity itself has no content view (see manifest) + + mDialogFragment = new MyDialogFragment(); + // give all extras through to the fragment + mDialogFragment.setArguments(getIntent().getExtras()); + + mDialogFragment.show(getFragmentManager(), "dialog"); + } + + public static class MyDialogFragment extends DialogFragment { + + private Messenger mMessenger; + + /** + * Creates dialog + */ + @Override + public Dialog onCreateDialog(Bundle savedInstanceState) { + mMessenger = getArguments().getParcelable(EXTRA_MESSENGER); + String filename = getArguments().getString(EXTRA_FILENAME); + + // hack to get holo design (which is not automatically applied due to activity's Theme.NoDisplay + ContextThemeWrapper context = new ContextThemeWrapper(getActivity(), + android.R.style.Theme_DeviceDefault_Light_Dialog); + ProgressDialog.Builder progress = new ProgressDialog.Builder(context); + return progress.show(); + } + + @Override + public void onCancel(DialogInterface dialog) { + super.onCancel(dialog); + + dismiss(); + sendMessageToHandler(MSG_CANCEL); + } + + @Override + public void onDismiss(DialogInterface dialog) { + super.onDismiss(dialog); + Log.d(Constants.TAG, "onDismiss"); + + getActivity().finish(); + } + + /** + * Send message back to handler which is initialized in a activity + * + * @param what Message integer you want to send + */ + private void sendMessageToHandler(Integer what) { + Message msg = Message.obtain(); + msg.what = what; + + try { + mMessenger.send(msg); + } catch (RemoteException e) { + Log.w(Constants.TAG, "Exception sending message, Is handler present?", e); + } catch (NullPointerException e) { + Log.w(Constants.TAG, "Messenger is null!", e); + } + } + + } + +} -- cgit v1.2.3 From 0422d48b61011ff75ef6d85a6e45b90aebb5e58b Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Tue, 19 Aug 2014 15:55:53 +0200 Subject: add ProgressFixedScaler (forgot in a previous commit) --- .../keychain/util/ProgressFixedScaler.java | 29 ++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/ProgressFixedScaler.java diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/ProgressFixedScaler.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/ProgressFixedScaler.java new file mode 100644 index 000000000..4bb4ca5de --- /dev/null +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/ProgressFixedScaler.java @@ -0,0 +1,29 @@ +package org.sufficientlysecure.keychain.util; + +import org.sufficientlysecure.keychain.pgp.Progressable; + +/** This is a simple variant of ProgressScaler which shows a fixed progress message, ignoring + * the provided ones. + */ +public class ProgressFixedScaler extends ProgressScaler { + + final int mResId; + + public ProgressFixedScaler(Progressable wrapped, int from, int to, int max, int resId) { + super(wrapped, from, to, max); + mResId = resId; + } + + public void setProgress(int resourceId, int progress, int max) { + if (mWrapped != null) { + mWrapped.setProgress(mResId, mFrom + progress * (mTo - mFrom) / max, mMax); + } + } + + public void setProgress(String message, int progress, int max) { + if (mWrapped != null) { + mWrapped.setProgress(mResId, mFrom + progress * (mTo - mFrom) / max, mMax); + } + } + +} -- cgit v1.2.3 From 9fb1050fed5cdaa238219b29958cba1c484dff7e Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Tue, 19 Aug 2014 15:56:53 +0200 Subject: stub for consolidate recovery in KeychainApplication --- .../org/sufficientlysecure/keychain/KeychainApplication.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/KeychainApplication.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/KeychainApplication.java index 9b9880533..233226cc5 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/KeychainApplication.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/KeychainApplication.java @@ -84,11 +84,18 @@ public class KeychainApplication extends Application { setupAccountAsNeeded(this); // Update keyserver list as needed - Preferences.getPreferences(this).updatePreferences(); + Preferences prefs = Preferences.getPreferences(this); + + prefs.updatePreferences(); TlsHelper.addStaticCA("pool.sks-keyservers.net", getAssets(), "sks-keyservers.netCA.cer"); TemporaryStorageProvider.cleanUp(this); + + if (prefs.getCachedConsolidate()) { + // do something which calls ProviderHelper.consolidateDatabaseStep2 with a progressable + } + } public static void setupAccountAsNeeded(Context context) { -- cgit v1.2.3 From 5f8bbab5694bfe1e1c45205b075481d696f34738 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Tue, 19 Aug 2014 16:31:51 +0200 Subject: Scroll fixes for certify activity --- .../sufficientlysecure/keychain/pgp/PgpKeyOperation.java | 2 +- .../keychain/ui/CertifyKeyActivity.java | 15 +++++++++++++++ OpenKeychain/src/main/res/layout/certify_key_activity.xml | 12 +++++------- 3 files changed, 21 insertions(+), 8 deletions(-) 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 b4e21cc0e..e357db412 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java @@ -930,7 +930,7 @@ public class PgpKeyOperation { hashedPacketsGen.setPreferredCompressionAlgorithms(false, PREFERRED_COMPRESSION_ALGORITHMS); hashedPacketsGen.setPrimaryUserID(false, primary); - /* critical subpackets: */ + /* critical subpackets: we consider those important for a modern pgp implementation */ hashedPacketsGen.setSignatureCreationTime(true, new Date()); // Request that senders add the MDC to the message (authenticate unsigned messages) hashedPacketsGen.setFeature(true, Features.FEATURE_MODIFICATION_DETECTION); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java index 7c6e94d5e..e81ebb9c4 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java @@ -40,6 +40,7 @@ import android.widget.CompoundButton; import android.widget.CompoundButton.OnCheckedChangeListener; import android.widget.ImageView; import android.widget.ListView; +import android.widget.ScrollView; import android.widget.Spinner; import android.widget.TextView; @@ -71,6 +72,7 @@ public class CertifyKeyActivity extends ActionBarActivity implements LoaderManag private ImageView mActionCertifyImage; private CheckBox mUploadKeyCheckbox; private Spinner mSelectKeyserverSpinner; + private ScrollView mScrollView; private CertifyKeySpinner mCertifyKeySpinner; @@ -96,6 +98,7 @@ public class CertifyKeyActivity extends ActionBarActivity implements LoaderManag mCertifyButton = findViewById(R.id.certify_key_certify_button); mActionCertifyImage = (ImageView) findViewById(R.id.certify_key_action_certify_image); mUserIds = (ListView) findViewById(R.id.view_key_user_ids); + mScrollView = (ScrollView) findViewById(R.id.certify_scroll_view); // make certify image gray, like action icons mActionCertifyImage.setColorFilter(getResources().getColor(R.color.tertiary_text_light), @@ -141,6 +144,7 @@ public class CertifyKeyActivity extends ActionBarActivity implements LoaderManag if (mMasterKeyId == 0) { Notify.showNotify(CertifyKeyActivity.this, getString(R.string.select_key_to_certify), Notify.Style.ERROR); + scrollUp(); } else { initiateCertifying(); } @@ -165,6 +169,14 @@ public class CertifyKeyActivity extends ActionBarActivity implements LoaderManag getSupportLoaderManager().initLoader(LOADER_ID_USER_IDS, null, this); } + private void scrollUp() { + mScrollView.post(new Runnable() { + public void run() { + mScrollView.fullScroll(ScrollView.FOCUS_UP); + } + }); + } + static final String USER_IDS_SELECTION = UserIds.IS_REVOKED + " = 0"; static final String[] KEYRING_PROJECTION = @@ -217,6 +229,9 @@ public class CertifyKeyActivity extends ActionBarActivity implements LoaderManag break; case LOADER_ID_USER_IDS: mUserIdsAdapter.swapCursor(data); + // when some user ids are pre-checked, the focus is requested and the scroll view goes + // down. This fixes it. + scrollUp(); break; } } diff --git a/OpenKeychain/src/main/res/layout/certify_key_activity.xml b/OpenKeychain/src/main/res/layout/certify_key_activity.xml index bce194438..9796a6ddc 100644 --- a/OpenKeychain/src/main/res/layout/certify_key_activity.xml +++ b/OpenKeychain/src/main/res/layout/certify_key_activity.xml @@ -1,6 +1,5 @@ @@ -8,6 +7,7 @@ @@ -27,9 +27,9 @@ android:text="@string/section_certification_key" /> + android:id="@+id/certify_key_spinner" + android:layout_width="match_parent" + android:layout_height="wrap_content" /> + android:layout_height="wrap_content" /> - -- cgit v1.2.3 From 4f8ddad9d37f77d5a119623ccaf042f41b65ebbc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Tue, 19 Aug 2014 16:40:57 +0200 Subject: ConsolidateDialogActivity --- OpenKeychain/src/main/AndroidManifest.xml | 4 + .../keychain/ui/ConsolidateDialogActivity.java | 102 ++++++++++++++++++ .../keychain/ui/OpenDialogActivity.java | 117 --------------------- 3 files changed, 106 insertions(+), 117 deletions(-) create mode 100644 OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ConsolidateDialogActivity.java delete mode 100644 OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/OpenDialogActivity.java diff --git a/OpenKeychain/src/main/AndroidManifest.xml b/OpenKeychain/src/main/AndroidManifest.xml index c10629c6d..142690abb 100644 --- a/OpenKeychain/src/main/AndroidManifest.xml +++ b/OpenKeychain/src/main/AndroidManifest.xml @@ -556,6 +556,10 @@ android:name="android.support.PARENT_ACTIVITY" android:value=".ui.KeyListActivity" /> + diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ConsolidateDialogActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ConsolidateDialogActivity.java new file mode 100644 index 000000000..e4a80ff48 --- /dev/null +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ConsolidateDialogActivity.java @@ -0,0 +1,102 @@ +/* + * Copyright (C) 2014 Dominik Schürmann + * + * 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 . + */ + +package org.sufficientlysecure.keychain.ui; + +import android.app.Dialog; +import android.app.ProgressDialog; +import android.content.DialogInterface; +import android.os.Bundle; +import android.support.v4.app.DialogFragment; +import android.support.v4.app.FragmentActivity; +import android.util.Log; +import android.view.ContextThemeWrapper; +import android.view.KeyEvent; + +import org.sufficientlysecure.keychain.Constants; +import org.sufficientlysecure.keychain.R; + +/** + * We can not directly create a dialog on the application context. + * This activity encapsulates a DialogFragment to emulate a dialog. + */ +public class ConsolidateDialogActivity extends FragmentActivity { + + MyDialogFragment mDialogFragment; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + // this activity itself has no content view (see manifest) + + mDialogFragment = new MyDialogFragment(); + // give all extras through to the fragment + mDialogFragment.setArguments(getIntent().getExtras()); + + mDialogFragment.show(getSupportFragmentManager(), "dialog"); + } + + public static class MyDialogFragment extends DialogFragment { + + /** + * Creates dialog + */ + @Override + public Dialog onCreateDialog(Bundle savedInstanceState) { + // hack to get holo design (which is not automatically applied due to activity's Theme.NoDisplay + ContextThemeWrapper context = new ContextThemeWrapper(getActivity(), + R.style.Theme_AppCompat_Light); + ProgressDialog dialog = new ProgressDialog(context); + dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); + dialog.setCancelable(false); + dialog.setCanceledOnTouchOutside(false); + + // Disable the back button + DialogInterface.OnKeyListener keyListener = new DialogInterface.OnKeyListener() { + @Override + public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) { + if (keyCode == KeyEvent.KEYCODE_BACK) { + return true; + } + return false; + } + + }; + dialog.setOnKeyListener(keyListener); + + return dialog; + } + + @Override + public void onCancel(DialogInterface dialog) { + super.onCancel(dialog); + + dismiss(); + } + + @Override + public void onDismiss(DialogInterface dialog) { + super.onDismiss(dialog); + Log.d(Constants.TAG, "onDismiss"); + + getActivity().finish(); + } + + } + +} diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/OpenDialogActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/OpenDialogActivity.java deleted file mode 100644 index cdb09bbd0..000000000 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/OpenDialogActivity.java +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright (C) 2014 Dominik Schürmann - * - * 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 . - */ - -package org.sufficientlysecure.keychain.ui; - -import android.app.Dialog; -import android.app.DialogFragment; -import android.app.ProgressDialog; -import android.content.DialogInterface; -import android.os.Bundle; -import android.os.Message; -import android.os.Messenger; -import android.os.RemoteException; -import android.support.v4.app.FragmentActivity; -import android.util.Log; -import android.view.ContextThemeWrapper; - -import org.sufficientlysecure.keychain.Constants; - -/** - * We can not directly create a dialog on the context provided inside the content provider. - * This activity encapsulates a DialogFragment to emulate a dialog. - */ -public class OpenDialogActivity extends FragmentActivity { - - public static final String EXTRA_MESSENGER = "messenger"; - public static final String EXTRA_FILENAME = "filename"; - - public static final int MSG_CANCEL = 1; - public static final int MSG_DECRYPT_OPEN = 2; - public static final int MSG_GET_ENCRYPTED = 3; - - MyDialogFragment mDialogFragment; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - // this activity itself has no content view (see manifest) - - mDialogFragment = new MyDialogFragment(); - // give all extras through to the fragment - mDialogFragment.setArguments(getIntent().getExtras()); - - mDialogFragment.show(getFragmentManager(), "dialog"); - } - - public static class MyDialogFragment extends DialogFragment { - - private Messenger mMessenger; - - /** - * Creates dialog - */ - @Override - public Dialog onCreateDialog(Bundle savedInstanceState) { - mMessenger = getArguments().getParcelable(EXTRA_MESSENGER); - String filename = getArguments().getString(EXTRA_FILENAME); - - // hack to get holo design (which is not automatically applied due to activity's Theme.NoDisplay - ContextThemeWrapper context = new ContextThemeWrapper(getActivity(), - android.R.style.Theme_DeviceDefault_Light_Dialog); - ProgressDialog.Builder progress = new ProgressDialog.Builder(context); - return progress.show(); - } - - @Override - public void onCancel(DialogInterface dialog) { - super.onCancel(dialog); - - dismiss(); - sendMessageToHandler(MSG_CANCEL); - } - - @Override - public void onDismiss(DialogInterface dialog) { - super.onDismiss(dialog); - Log.d(Constants.TAG, "onDismiss"); - - getActivity().finish(); - } - - /** - * Send message back to handler which is initialized in a activity - * - * @param what Message integer you want to send - */ - private void sendMessageToHandler(Integer what) { - Message msg = Message.obtain(); - msg.what = what; - - try { - mMessenger.send(msg); - } catch (RemoteException e) { - Log.w(Constants.TAG, "Exception sending message, Is handler present?", e); - } catch (NullPointerException e) { - Log.w(Constants.TAG, "Messenger is null!", e); - } - } - - } - -} -- cgit v1.2.3 From c42f6a04eddf29eb655e56d574dee46374488614 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Tue, 19 Aug 2014 16:49:48 +0200 Subject: Start consolidate activity --- .../org/sufficientlysecure/keychain/KeychainApplication.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/KeychainApplication.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/KeychainApplication.java index 233226cc5..bb691a9d2 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/KeychainApplication.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/KeychainApplication.java @@ -21,6 +21,7 @@ import android.accounts.Account; import android.accounts.AccountManager; import android.app.Application; import android.content.Context; +import android.content.Intent; import android.graphics.PorterDuff; import android.graphics.drawable.Drawable; import android.os.Environment; @@ -29,6 +30,7 @@ import org.spongycastle.jce.provider.BouncyCastleProvider; import org.sufficientlysecure.keychain.helper.Preferences; import org.sufficientlysecure.keychain.helper.TlsHelper; import org.sufficientlysecure.keychain.provider.TemporaryStorageProvider; +import org.sufficientlysecure.keychain.ui.ConsolidateDialogActivity; import org.sufficientlysecure.keychain.util.Log; import org.sufficientlysecure.keychain.util.PRNGFixes; @@ -92,12 +94,17 @@ public class KeychainApplication extends Application { TemporaryStorageProvider.cleanUp(this); + // restart consolidate process if it has been interruped before if (prefs.getCachedConsolidate()) { // do something which calls ProviderHelper.consolidateDatabaseStep2 with a progressable + Intent consolidateIntent = new Intent(this, ConsolidateDialogActivity.class); + consolidateIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + startActivity(consolidateIntent); } - } + + public static void setupAccountAsNeeded(Context context) { AccountManager manager = AccountManager.get(context); Account[] accounts = manager.getAccountsByType(Constants.PACKAGE_NAME); -- cgit v1.2.3 From 9930ab7f6ff9400d6e3aa36ce06c663ce09be633 Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Tue, 19 Aug 2014 16:53:44 +0200 Subject: consolidate: a lot more log output, better recovery --- .../keychain/helper/Preferences.java | 4 +- .../keychain/provider/ProviderHelper.java | 86 ++++++++++++++++------ .../keychain/service/OperationResultParcel.java | 25 +++++-- OpenKeychain/src/main/res/values/strings.xml | 28 +++++-- 4 files changed, 108 insertions(+), 35 deletions(-) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/helper/Preferences.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/helper/Preferences.java index 9a10148f2..5190a550e 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/helper/Preferences.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/helper/Preferences.java @@ -146,7 +146,7 @@ public class Preferences { } public int getCachedConsolidateNumPublics() { - return mSharedPreferences.getInt(Pref.CACHED_CONSOLIDATE_PUBLICS, 100); + return mSharedPreferences.getInt(Pref.CACHED_CONSOLIDATE_PUBLICS, -1); } public void setCachedConsolidateNumPublics(int value) { @@ -156,7 +156,7 @@ public class Preferences { } public int getCachedConsolidateNumSecrets() { - return mSharedPreferences.getInt(Pref.CACHED_CONSOLIDATE_SECRETS, 100); + return mSharedPreferences.getInt(Pref.CACHED_CONSOLIDATE_SECRETS, -1); } public void setCachedConsolidateNumSecrets(int value) { 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 5f55eedd5..4f8b50a94 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java @@ -829,12 +829,12 @@ public class ProviderHelper { public ConsolidateResult consolidateDatabaseStep1(Progressable progress) { // 1a. fetch all secret keyrings into a cache file - log(LogLevel.START, LogType.MSG_CON, mIndent); + log(LogLevel.START, LogType.MSG_CON); mIndent += 1; try { - log(LogLevel.DEBUG, LogType.MSG_CON_SAVE_SECRET, mIndent); + log(LogLevel.DEBUG, LogType.MSG_CON_SAVE_SECRET); mIndent += 1; final Cursor cursor = mContentResolver.query(KeyRings.buildUnifiedKeyRingsUri(), new String[]{ @@ -842,6 +842,7 @@ public class ProviderHelper { }, KeyRings.HAS_ANY_SECRET + " = 1", null, null); if (cursor == null || !cursor.moveToFirst()) { + log(LogLevel.ERROR, LogType.MSG_CON_ERROR_DB); return new ConsolidateResult(ConsolidateResult.RESULT_ERROR, mLog); } @@ -883,7 +884,8 @@ public class ProviderHelper { }); } catch (IOException e) { - Log.e(Constants.TAG, "error saving secret"); + Log.e(Constants.TAG, "error saving secret", e); + log(LogLevel.ERROR, LogType.MSG_CON_ERROR_IO_SECRET); return new ConsolidateResult(ConsolidateResult.RESULT_ERROR, mLog); } finally { mIndent -= 1; @@ -892,7 +894,7 @@ public class ProviderHelper { // 1b. fetch all public keyrings into a cache file try { - log(LogLevel.DEBUG, LogType.MSG_CON_SAVE_PUBLIC, mIndent); + log(LogLevel.DEBUG, LogType.MSG_CON_SAVE_PUBLIC); mIndent += 1; final Cursor cursor = mContentResolver.query(KeyRings.buildUnifiedKeyRingsUri(), new String[]{ @@ -900,10 +902,11 @@ public class ProviderHelper { }, null, null, null); if (cursor == null || !cursor.moveToFirst()) { + log(LogLevel.ERROR, LogType.MSG_CON_ERROR_DB); return new ConsolidateResult(ConsolidateResult.RESULT_ERROR, mLog); } - Preferences.getPreferences(mContext).setCachedConsolidateNumSecrets(cursor.getCount()); + Preferences.getPreferences(mContext).setCachedConsolidateNumPublics(cursor.getCount()); FileImportCache cache = new FileImportCache(mContext, "consolidate_public.pcl"); @@ -941,31 +944,48 @@ public class ProviderHelper { }); } catch (IOException e) { - Log.e(Constants.TAG, "error saving public"); + Log.e(Constants.TAG, "error saving public", e); + log(LogLevel.ERROR, LogType.MSG_CON_ERROR_IO_PUBLIC); return new ConsolidateResult(ConsolidateResult.RESULT_ERROR, mLog); } finally { mIndent -= 1; } + log(LogLevel.INFO, LogType.MSG_CON_CRITICAL_IN); Preferences.getPreferences(mContext).setCachedConsolidate(true); - return consolidateDatabaseStep2(progress); + return consolidateDatabaseStep2(progress, false); } public ConsolidateResult consolidateDatabaseStep2(Progressable progress) { + return consolidateDatabaseStep2(progress, true); + } + + private ConsolidateResult consolidateDatabaseStep2(Progressable progress, boolean recovery) { + Preferences prefs = Preferences.getPreferences(mContext); - if ( ! prefs.getCachedConsolidate()) { - log(LogLevel.ERROR, LogType.MSG_CON_ERROR_BAD_STATE); - return new ConsolidateResult(ConsolidateResult.RESULT_ERROR, mLog); - } // Set flag that we have a cached consolidation here int numSecrets = prefs.getCachedConsolidateNumSecrets(); int numPublics = prefs.getCachedConsolidateNumPublics(); + if (recovery) { + if (numSecrets >= 0 && numPublics >= 0) { + log(LogLevel.START, LogType.MSG_CON_RECOVER, numSecrets, Integer.toString(numPublics)); + } else { + log(LogLevel.START, LogType.MSG_CON_RECOVER_UNKNOWN); + } + mIndent += 1; + } + + if ( ! prefs.getCachedConsolidate()) { + log(LogLevel.ERROR, LogType.MSG_CON_ERROR_BAD_STATE); + return new ConsolidateResult(ConsolidateResult.RESULT_ERROR, mLog); + } + // 2. wipe database (IT'S DANGEROUS) - log(LogLevel.DEBUG, LogType.MSG_CON_DB_CLEAR, mIndent); + log(LogLevel.DEBUG, LogType.MSG_CON_DB_CLEAR); new KeychainDatabase(mContext).clearDatabase(); FileImportCache cacheSecret = @@ -974,51 +994,71 @@ public class ProviderHelper { new FileImportCache(mContext, "consolidate_public.pcl"); // 3. Re-Import secret keyrings from cache - try { - log(LogLevel.DEBUG, LogType.MSG_CON_REIMPORT_SECRET, mIndent, numSecrets); + if (numSecrets > 0) try { + log(LogLevel.DEBUG, LogType.MSG_CON_REIMPORT_SECRET, numSecrets); mIndent += 1; - new PgpImportExport(mContext, this, new ProgressFixedScaler(progress, 10, 25, 100, R.string.progress_con_reimport)) + new PgpImportExport(mContext, this, + new ProgressFixedScaler(progress, 10, 25, 100, R.string.progress_con_reimport)) .importKeyRings(cacheSecret.readCache(false), numSecrets); } catch (IOException e) { - Log.e(Constants.TAG, "error importing secret"); + Log.e(Constants.TAG, "error importing secret", e); + log(LogLevel.ERROR, LogType.MSG_CON_ERROR_SECRET); return new ConsolidateResult(ConsolidateResult.RESULT_ERROR, mLog); } finally { mIndent -= 1; + } else { + log(LogLevel.DEBUG, LogType.MSG_CON_REIMPORT_SECRET_SKIP); } // 4. Re-Import public keyrings from cache - try { - log(LogLevel.DEBUG, LogType.MSG_CON_REIMPORT_PUBLIC, mIndent, numPublics); + if (numPublics > 0) try { + log(LogLevel.DEBUG, LogType.MSG_CON_REIMPORT_PUBLIC, numPublics); mIndent += 1; - new PgpImportExport(mContext, this, new ProgressScaler(progress, 25, 99, 100)) + new PgpImportExport(mContext, this, + new ProgressFixedScaler(progress, 25, 99, 100, R.string.progress_con_reimport)) .importKeyRings(cachePublic.readCache(false), numPublics); } catch (IOException e) { - Log.e(Constants.TAG, "error importing public"); + Log.e(Constants.TAG, "error importing public", e); + log(LogLevel.ERROR, LogType.MSG_CON_ERROR_PUBLIC); return new ConsolidateResult(ConsolidateResult.RESULT_ERROR, mLog); } finally { mIndent -= 1; + } else { + log(LogLevel.DEBUG, LogType.MSG_CON_REIMPORT_PUBLIC_SKIP); } + log(LogLevel.INFO, LogType.MSG_CON_CRITICAL_OUT); Preferences.getPreferences(mContext).setCachedConsolidate(false); // 5. Delete caches try { + log(LogLevel.DEBUG, LogType.MSG_CON_DELETE_SECRET); + mIndent += 1; cacheSecret.delete(); } catch (IOException e) { - // doesn't really matter + // doesn't /really/ matter Log.e(Constants.TAG, "IOException during delete of secret cache", e); + log(LogLevel.WARN, LogType.MSG_CON_WARN_DELETE_SECRET); + } finally { + mIndent -= 1; } + try { + log(LogLevel.DEBUG, LogType.MSG_CON_DELETE_PUBLIC); + mIndent += 1; cachePublic.delete(); } catch (IOException e) { - // doesn't really matter + // doesn't /really/ matter Log.e(Constants.TAG, "IOException during deletion of public cache", e); + log(LogLevel.WARN, LogType.MSG_CON_WARN_DELETE_PUBLIC); + } finally { + mIndent -= 1; } progress.setProgress(100, 100); - log(LogLevel.OK, LogType.MSG_CON_SUCCESS, mIndent); + log(LogLevel.OK, LogType.MSG_CON_SUCCESS); mIndent -= 1; return new ConsolidateResult(ConsolidateResult.RESULT_OK, mLog); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/OperationResultParcel.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/OperationResultParcel.java index 3f478cfed..cf9f69033 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/OperationResultParcel.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/OperationResultParcel.java @@ -390,14 +390,29 @@ public class OperationResultParcel implements Parcelable { MSG_MF_UNLOCK (R.string.msg_mf_unlock), // consolidate - MSG_CON (R.string.msg_con), + MSG_CON_CRITICAL_IN (R.string.msg_con_critical_in), + MSG_CON_CRITICAL_OUT (R.string.msg_con_critical_out), + MSG_CON_DB_CLEAR (R.string.msg_con_db_clear), + MSG_CON_DELETE_PUBLIC (R.string.msg_con_delete_public), + MSG_CON_DELETE_SECRET (R.string.msg_con_delete_secret), MSG_CON_ERROR_BAD_STATE (R.string.msg_con_error_bad_state), - MSG_CON_SAVE_SECRET (R.string.msg_con_save_secret), + MSG_CON_ERROR_DB (R.string.msg_con_error_db), + MSG_CON_ERROR_IO_PUBLIC (R.string.msg_con_error_io_public), + MSG_CON_ERROR_IO_SECRET (R.string.msg_con_error_io_secret), + MSG_CON_ERROR_PUBLIC (R.string.msg_con_error_public), + MSG_CON_ERROR_SECRET (R.string.msg_con_error_secret), + MSG_CON_RECOVER (R.plurals.msg_con_recover), + MSG_CON_RECOVER_UNKNOWN (R.string.msg_con_recover_unknown), + MSG_CON_REIMPORT_PUBLIC (R.string.msg_con_reimport_public), + MSG_CON_REIMPORT_PUBLIC_SKIP (R.string.msg_con_reimport_public_skip), + MSG_CON_REIMPORT_SECRET (R.string.msg_con_reimport_secret), + MSG_CON_REIMPORT_SECRET_SKIP (R.string.msg_con_reimport_secret_skip), + MSG_CON (R.string.msg_con), MSG_CON_SAVE_PUBLIC (R.string.msg_con_save_public), - MSG_CON_DB_CLEAR (R.string.msg_con_db_clear), - MSG_CON_REIMPORT_SECRET (R.plurals.msg_con_reimport_secret), - MSG_CON_REIMPORT_PUBLIC (R.plurals.msg_con_reimport_public), + MSG_CON_SAVE_SECRET (R.string.msg_con_save_secret), MSG_CON_SUCCESS (R.string.msg_con_success), + MSG_CON_WARN_DELETE_PUBLIC (R.string.msg_con_warn_delete_public), + MSG_CON_WARN_DELETE_SECRET (R.string.msg_con_warn_delete_secret), ; private final int mMsgId; diff --git a/OpenKeychain/src/main/res/values/strings.xml b/OpenKeychain/src/main/res/values/strings.xml index e506bf488..c00449f8e 100644 --- a/OpenKeychain/src/main/res/values/strings.xml +++ b/OpenKeychain/src/main/res/values/strings.xml @@ -677,15 +677,33 @@ Saving secret keyrings Saving public keyrings Clearing database - - Reimporting one secret key - Reimporting %d secret keys + Successfully consolidated database + Entering critical phase + Leaving critical phase + Deleting public keyring cache file + Deleting secret keyring cache file + Error opening database! + IO error writing public keys to cache! + IO error writing secret keys to cache! + Error reimporting public keys! + Error reimporting secret keys! + + Recovering consolidation with one secret and %s public keys + Recovering consolidation with %d secret and %s public keys + Recovering from unknown state Reimporting one public key - Reimporting %d public keys + Reimporting %d public keys - Successfully consolidated database + No public keys to reimport, skipping… + + Reimporting one secret key + Reimporting %d secret keys + + No secret keys to reimport, skipping… + Exception deleting public cache file + Exception deleting public cache file Click to clear cached passphrases -- cgit v1.2.3 From 16ab7610061726110f917533348f4c37a0690321 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Tue, 19 Aug 2014 18:12:19 +0200 Subject: Fix strings --- .../org/sufficientlysecure/keychain/provider/ProviderHelper.java | 2 +- .../keychain/service/OperationResultParcel.java | 4 ++-- OpenKeychain/src/main/res/values/strings.xml | 8 ++++---- 3 files changed, 7 insertions(+), 7 deletions(-) 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 4f8b50a94..2867967ff 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java @@ -972,7 +972,7 @@ public class ProviderHelper { if (recovery) { if (numSecrets >= 0 && numPublics >= 0) { - log(LogLevel.START, LogType.MSG_CON_RECOVER, numSecrets, Integer.toString(numPublics)); + log(LogLevel.START, LogType.MSG_CON_RECOVER, numSecrets, numPublics); } else { log(LogLevel.START, LogType.MSG_CON_RECOVER_UNKNOWN); } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/OperationResultParcel.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/OperationResultParcel.java index cf9f69033..91939739a 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/OperationResultParcel.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/OperationResultParcel.java @@ -403,9 +403,9 @@ public class OperationResultParcel implements Parcelable { MSG_CON_ERROR_SECRET (R.string.msg_con_error_secret), MSG_CON_RECOVER (R.plurals.msg_con_recover), MSG_CON_RECOVER_UNKNOWN (R.string.msg_con_recover_unknown), - MSG_CON_REIMPORT_PUBLIC (R.string.msg_con_reimport_public), + MSG_CON_REIMPORT_PUBLIC (R.plurals.msg_con_reimport_public), MSG_CON_REIMPORT_PUBLIC_SKIP (R.string.msg_con_reimport_public_skip), - MSG_CON_REIMPORT_SECRET (R.string.msg_con_reimport_secret), + MSG_CON_REIMPORT_SECRET (R.plurals.msg_con_reimport_secret), MSG_CON_REIMPORT_SECRET_SKIP (R.string.msg_con_reimport_secret_skip), MSG_CON (R.string.msg_con), MSG_CON_SAVE_PUBLIC (R.string.msg_con_save_public), diff --git a/OpenKeychain/src/main/res/values/strings.xml b/OpenKeychain/src/main/res/values/strings.xml index c00449f8e..1bd412d4d 100644 --- a/OpenKeychain/src/main/res/values/strings.xml +++ b/OpenKeychain/src/main/res/values/strings.xml @@ -688,18 +688,18 @@ Error reimporting public keys! Error reimporting secret keys! - Recovering consolidation with one secret and %s public keys - Recovering consolidation with %d secret and %s public keys + Recovering consolidation with %1$d secret and %2$d public keys + Recovering consolidation with %1$d secret and %2$d public keys Recovering from unknown state Reimporting one public key - Reimporting %d public keys + Reimporting %d public keys No public keys to reimport, skipping… Reimporting one secret key - Reimporting %d secret keys + Reimporting %d secret keys No secret keys to reimport, skipping… Exception deleting public cache file -- cgit v1.2.3 From 1a6734f29c0a07c58f356e3861530adfe63f684a Mon Sep 17 00:00:00 2001 From: mar-v-in Date: Tue, 19 Aug 2014 18:54:48 +0200 Subject: Fix mime types, #781 --- OpenKeychain/src/main/AndroidManifest.xml | 6 ++++-- .../java/org/sufficientlysecure/keychain/ui/EncryptActivity.java | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/OpenKeychain/src/main/AndroidManifest.xml b/OpenKeychain/src/main/AndroidManifest.xml index 142690abb..a1ad7139d 100644 --- a/OpenKeychain/src/main/AndroidManifest.xml +++ b/OpenKeychain/src/main/AndroidManifest.xml @@ -176,7 +176,7 @@ android:label="@string/title_decrypt" android:windowSoftInputMode="stateHidden"> - + @@ -184,7 +184,9 @@ - + + + diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivity.java index 59a433af3..d33e5116c 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivity.java @@ -382,7 +382,7 @@ public class EncryptActivity extends DrawerActivity implements EncryptActivityIn sendIntent = new Intent(Intent.ACTION_SEND_MULTIPLE); sendIntent.putExtra(Intent.EXTRA_STREAM, mOutputUris); } - sendIntent.setType("application/pgp-encrypted"); + sendIntent.setType("application/octet-stream"); } if (!isModeSymmetric() && mEncryptionUserIds != null) { Set users = new HashSet(); -- cgit v1.2.3 From d26c6b1a08448c6fa884b8b7591d625006d1ac3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Wed, 20 Aug 2014 09:20:30 +0200 Subject: Update keybase lib --- extern/KeybaseLib | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extern/KeybaseLib b/extern/KeybaseLib index e214906a5..2e8f38f6e 160000 --- a/extern/KeybaseLib +++ b/extern/KeybaseLib @@ -1 +1 @@ -Subproject commit e214906a52233bb6f230bc6759ac7be803d24bf5 +Subproject commit 2e8f38f6e38fe77b828826d3c6e8cb89a8a9aee5 -- cgit v1.2.3 From d6d68622cee488d06f680334f3c4f53d4d410bca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Wed, 20 Aug 2014 11:03:56 +0200 Subject: Travis is now stable --- README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/README.md b/README.md index a9b03b2c3..7338f1071 100644 --- a/README.md +++ b/README.md @@ -5,8 +5,6 @@ For a more detailed description and installation instructions go to http://www.o ### Travis CI Build Status -Currently, some tests could fail even when everything is okay! - [![Build Status](https://travis-ci.org/open-keychain/open-keychain.png?branch=master)](https://travis-ci.org/open-keychain/open-keychain) ## How to help the project? -- cgit v1.2.3 From 70426041dfb828c7117b05fd25ae6d077fdd501e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Wed, 20 Aug 2014 11:09:41 +0200 Subject: Pull from transifex --- .../src/main/res/raw-cs/help_nfc_beam.html | 10 +- OpenKeychain/src/main/res/raw-cs/help_start.html | 22 +-- OpenKeychain/src/main/res/raw-cs/help_wot.html | 2 +- .../src/main/res/raw-cs/nfc_beam_share.html | 8 +- OpenKeychain/src/main/res/raw-de/help_start.html | 6 +- .../src/main/res/raw-es/help_changelog.html | 140 ++++++------- .../src/main/res/raw-fr/help_changelog.html | 6 +- .../src/main/res/raw-it/help_changelog.html | 170 ++++++++-------- .../src/main/res/raw-ja/help_changelog.html | 4 +- OpenKeychain/src/main/res/raw-pt/help_about.html | 54 +++++ .../src/main/res/raw-pt/help_changelog.html | 170 ++++++++++++++++ .../src/main/res/raw-pt/help_nfc_beam.html | 12 ++ OpenKeychain/src/main/res/raw-pt/help_start.html | 22 +++ OpenKeychain/src/main/res/raw-pt/help_wot.html | 17 ++ .../src/main/res/raw-pt/nfc_beam_share.html | 11 ++ OpenKeychain/src/main/res/raw-uk/help_about.html | 20 +- .../src/main/res/raw-uk/help_changelog.html | 170 ++++++++-------- OpenKeychain/src/main/res/values-cs/strings.xml | 124 +++++++++++- OpenKeychain/src/main/res/values-de/strings.xml | 42 +++- OpenKeychain/src/main/res/values-es/strings.xml | 55 +++++- OpenKeychain/src/main/res/values-et/strings.xml | 1 + OpenKeychain/src/main/res/values-fr/strings.xml | 65 ++++-- OpenKeychain/src/main/res/values-it/strings.xml | 84 +++++++- OpenKeychain/src/main/res/values-ja/strings.xml | 47 ++++- OpenKeychain/src/main/res/values-nl/strings.xml | 3 +- OpenKeychain/src/main/res/values-pl/strings.xml | 1 + OpenKeychain/src/main/res/values-pt/strings.xml | 44 +++++ OpenKeychain/src/main/res/values-ru/strings.xml | 6 +- OpenKeychain/src/main/res/values-sl/strings.xml | 5 +- OpenKeychain/src/main/res/values-tr/strings.xml | 1 + OpenKeychain/src/main/res/values-uk/strings.xml | 218 ++++++++++++++++++++- OpenKeychain/src/main/res/values-zh/strings.xml | 1 + 32 files changed, 1203 insertions(+), 338 deletions(-) create mode 100644 OpenKeychain/src/main/res/raw-pt/help_about.html create mode 100644 OpenKeychain/src/main/res/raw-pt/help_changelog.html create mode 100644 OpenKeychain/src/main/res/raw-pt/help_nfc_beam.html create mode 100644 OpenKeychain/src/main/res/raw-pt/help_start.html create mode 100644 OpenKeychain/src/main/res/raw-pt/help_wot.html create mode 100644 OpenKeychain/src/main/res/raw-pt/nfc_beam_share.html create mode 100644 OpenKeychain/src/main/res/values-pt/strings.xml diff --git a/OpenKeychain/src/main/res/raw-cs/help_nfc_beam.html b/OpenKeychain/src/main/res/raw-cs/help_nfc_beam.html index 88492731c..d691df871 100644 --- a/OpenKeychain/src/main/res/raw-cs/help_nfc_beam.html +++ b/OpenKeychain/src/main/res/raw-cs/help_nfc_beam.html @@ -1,12 +1,12 @@ -

How to receive keys

+

Jak přijmout klíče

    -
  1. Go to your partners contacts and open the contact you want to share.
  2. -
  3. Hold the two devices back to back (they have to be almost touching) and you’ll feel a vibration.
  4. -
  5. After it vibrates you’ll see the content on your partners device turn into a card-like object with Star Trek warp speed-looking animation in the background.
  6. -
  7. Tap the card and the content will then load on the your device.
  8. +
  9. Navigujte na kontakt vašeho partnera a otevřete ten který chcete sdílet.
  10. +
  11. Podržte dvě zařízení zády k sobě (musí se téměř dotýkat) a ucítíte vibraci.
  12. +
  13. Po tom co ucítíte vibraci, uvidíte že se obsah na displeji zařízení vašeho partnera změní na objekt typu karta s animací na pozadí připomínající rychlost warpu ze Star Treku.
  14. +
  15. Tapněte na kartu a obsach se nahraje do zařízení.
diff --git a/OpenKeychain/src/main/res/raw-cs/help_start.html b/OpenKeychain/src/main/res/raw-cs/help_start.html index 51a76c01e..eaffc2389 100644 --- a/OpenKeychain/src/main/res/raw-cs/help_start.html +++ b/OpenKeychain/src/main/res/raw-cs/help_start.html @@ -1,22 +1,22 @@ -

Getting started

-

First you need a personal secret key. Create one via the option menus in "Keys" or import existing secret keys. Afterwards, you can download your friends' keys or exchange them via QR Codes or NFC.

+

Začínáme

+

Nejprve potřebujete osobní tajný klíč. Vytvořte si ho pomocí volby v menu v sekci "Klíče" nebo importujte existující tajné klíče. Následně můžete stáhnout klíče vašich známých nebo si je vyměnit pomocí QR kódu případně NFC.

-

It is recommended that you install OI File Manager for enhanced file selection and Barcode Scanner to scan generated QR Codes. Clicking on the links will open Google Play Store or F-Droid for installation.

+

Doporučujeme instalaci OI File Manager pro zlepšení práce se soubory a Barcode Scanner pro skenování generovaných QR kódů. Kliknutí na odkazy otevře Google Play Store nebo F-Droid odkud můžete začít installovat.

-

Applications

-

Several applications support OpenKeychain to encrypt/sign your private communication:

K-9 Mail: OpenKeychain support available in current alpha build!

Conversations
: Jabber/XMPP client

PGPAuth
: App to send a PGP-signed request to a server to open or close something, e.g. a door

+

Aplikace

+

Několik aplikací umožňuje šifrovat/podepsat privátní komunikaci pomocí OpenKeychain:

K-9 Mail: podpora OpenKeychain v aktualní verzi alpha build!

Konverzace
: Jabber/XMPP client

PGPAuth
: Appka sloužící k odesílání požadavků podepsaných PGP na servery pro otevření nebo zavření něčeho, třeba dveří

-

I found a bug in OpenKeychain!

-

Please report the bug using the issue tracker of OpenKeychain.

+

Našel jsem bug v OpenChain!

+

Reportujte chyby pomocí issue trackeru OpenKeychain.

-

Contribute

-

If you want to help us developing OpenKeychain by contributing code follow our small guide on Github.

+

Přispět

+

Pokud chcete pomoci vyvýjet OpenKeychain tak, že přispějete svými kodérskými schopnostmi přečtěte si naší malou příručku na Githubu.

-

Translations

-

Help translating OpenKeychain! Everybody can participate at OpenKeychain on Transifex.

+

Překlady

+

Pomozte s překladem OpenKeychain! Každý může participovat na OpenKeychain na Transifexu

diff --git a/OpenKeychain/src/main/res/raw-cs/help_wot.html b/OpenKeychain/src/main/res/raw-cs/help_wot.html index 29790139b..30288f2bb 100644 --- a/OpenKeychain/src/main/res/raw-cs/help_wot.html +++ b/OpenKeychain/src/main/res/raw-cs/help_wot.html @@ -1,7 +1,7 @@ -

Web of Trust

+

Síť důvěry

The Web of Trust describes the part of PGP which deals with creation and bookkeeping of certifications. It provides mechanisms to help the user keep track of who a public key belongs to, and share this information with others; To ensure the privacy of encrypted communication, it is essential to know that the public key you encrypt to belongs to the person you think it does.

Support in OpenKeychain

diff --git a/OpenKeychain/src/main/res/raw-cs/nfc_beam_share.html b/OpenKeychain/src/main/res/raw-cs/nfc_beam_share.html index 083e055c7..09128be62 100644 --- a/OpenKeychain/src/main/res/raw-cs/nfc_beam_share.html +++ b/OpenKeychain/src/main/res/raw-cs/nfc_beam_share.html @@ -2,10 +2,10 @@
    -
  1. Make sure that NFC is turned on in Settings > More > NFC and make sure that Android Beam is also on in the same section.
  2. -
  3. Hold the two devices back to back (they have to be almost touching) and you'll feel a vibration.
  4. -
  5. After it vibrates you'll see the content on your device turn into a card-like object with Star Trek warp speed-looking animation in the background.
  6. -
  7. Tap the card and the content will then load on the other person’s device.
  8. +
  9. Ujistěte se, že NFC je zapnuto v Nastavení > Další > NFC a ujistěte se, že Android Beam ve stejné sekci je také zapnutý.
  10. +
  11. Podržte dvě zařízení zády k sobě (musí se téměř dotýkat) a ucítíte vibraci.
  12. +
  13. Po tom co ucítíte vibraci, uvidíte že se obsah na displeji zařízení vašeho partnera změní na objekt typu karta s animací na pozadí připomínající rychlost warpu ze Star Treku.
  14. +
  15. Tapněte na kartu a obsach se nahraje do zařízení.
diff --git a/OpenKeychain/src/main/res/raw-de/help_start.html b/OpenKeychain/src/main/res/raw-de/help_start.html index dfff2bc03..0764c9ebb 100644 --- a/OpenKeychain/src/main/res/raw-de/help_start.html +++ b/OpenKeychain/src/main/res/raw-de/help_start.html @@ -1,7 +1,7 @@ -

Los gehts

+

Los geht's

Zuerst benötigen Sie einen privaten Schlüssel. Erstellen Sie einen Schlüssel über den Eintrag "Schlüssel" im Menu oder importieren Sie bestehende private Schlüssel. Anschließend können Sie die Schlüssel ihrer Freunde runterladen oder Sie über QR-Codes oder NFC austauschen.

Es wird empfohlen, dass Sie den OI File Manager für ein verbessertes Dateihandling installieren, sowie den Barcode Scanner installieren um erstellte QR-Codes zu scannen. Die Links führen entweder zu Google Play oder zu F-Droid zur Installation.

@@ -13,10 +13,10 @@

Bitte berichten Sie Bugs mithilfe des Issue Trackers der OpenKeychain.

Unterstützen

-

Wenn Sie uns bei der Entwickelung von OpenKeychain durch das Beisteuern von Code helfen wollt, schaut euch unsere kurze Anleitung auf Github an.

+

Wenn Sie uns bei der Entwickelung von OpenKeychain durch das Beisteuern von Code helfen wollen, schauen Sie unsere kurze Anleitung auf Github an.

Übersetzungen

-

Hilf mit OpenKeychain zu übersetzten! Jeder kann auf OpenKeychain auf Transifex mitmachen.

+

Hilf mit, OpenKeychain zu übersetzten! Jeder kann auf OpenKeychain auf Transifex mitmachen.

diff --git a/OpenKeychain/src/main/res/raw-es/help_changelog.html b/OpenKeychain/src/main/res/raw-es/help_changelog.html index a6b2d269d..0530f3999 100644 --- a/OpenKeychain/src/main/res/raw-es/help_changelog.html +++ b/OpenKeychain/src/main/res/raw-es/help_changelog.html @@ -7,7 +7,7 @@
  • Edición de clave: Tremendo nuevo diseño, revocación de clave
  • Importación de clave: Impresionante nuevo diseño, conexiones seguras al servidor de claves vía hkps, el servidor de claves resuelve mediante registros DNS SRV
  • Nueva pantalla de primer inicio
  • -
  • Nueva pantalla de creación de clave: Autocompletado del nombre y correo electrónico basado en sus cuentas Android personales
  • +
  • Nueva pantalla de creación: autocompletado de nombre y correo electrónico basado en sus cuentas de Android personales
  • Cifrado de fichero: Pasmante nuevo diseño, soporte para cifrar múltiples ficheros.
  • Nuevos iconos para mostrar el estado de la clave (por Brennan Novak)
  • Importante reparacion de fallo: Ahora es posible la importación de grandes colecciones de claves desde un fichero
  • @@ -33,13 +33,13 @@
  • Soporte para claves secretas parciales de GnuPG (gracias a Vincent Breitmoser)
  • Nuevo diseño para verificación de firma
  • Tamaño de clave personalizado (gracias a Greg Witczak)
  • -
  • Fix share-functionality from other apps
  • +
  • Repara la funcionalidad de compartido desde otras aplicaciones
  • 2.5

      -
    • Fix decryption of symmetric pgp messages/files
    • -
    • Refactored edit key screen (thanks to Ash Hughes)
    • -
    • New modern design for encrypt/decrypt screens
    • +
    • Repara el descifrado de mensajes/ficheros pgp simétricos
    • +
    • Pantalla de edición de clave refactorizada (gracias a Ash Hughes)
    • +
    • Nuevo diseño moderno para pantallas de cifrado/descifrado
    • OpenPGP API versión 3 (múltiples cuentas API, reparaciones internas, comprobación de claves)

    2.4

    @@ -47,45 +47,45 @@ Además de varios parches pequeños, un notable número de correcciones fueron hechas por las siguientes personas (en orden alfabético): Daniel Hammann, Daniel Haß, Greg Witczak, Miroojin Bakshi, Nikhil Peter Raj, Paul Sarbinowski, Sreeram Boyapati, Vincent Breitmoser.

      -
    • New unified key list
    • -
    • Colorized key fingerprint
    • -
    • Support for keyserver ports
    • -
    • Deactivate possibility to generate weak keys
    • -
    • Much more internal work on the API
    • -
    • Certify user ids
    • -
    • Keyserver query based on machine-readable output
    • -
    • Lock navigation drawer on tablets
    • -
    • Suggestions for emails on creation of keys
    • -
    • Search in public key lists
    • -
    • And much more improvements and fixes…
    • +
    • Nueva lista unificada de claves
    • +
    • Huella de validación de clave coloreada
    • +
    • Soporte para puertos de servidores de claves
    • +
    • Desactiva la posibilidad de generar claves débiles.
    • +
    • Mucho más trabajo interno en la API
    • +
    • Certifica las identidades de usuario
    • +
    • Petición al servidor de claves basada en salida legible-por-máquina
    • +
    • Cerrar panel lateral de navegación en tabletas
    • +
    • Sugerencias para correos electrónicos al crear claves
    • +
    • Buscar en listas de claves públicas
    • +
    • Añadir muchas más mejoras y reparaciones...

    2.3.1

      -
    • Hotfix for crash when upgrading from old versions
    • +
    • Reparación para fallo al actualizar desde versiones antiguas.

    2.3

      -
    • Remove unnecessary export of public keys when exporting secret key (thanks to Ash Hughes)
    • -
    • Fix setting expiry dates on keys (thanks to Ash Hughes)
    • -
    • More internal fixes when editing keys (thanks to Ash Hughes)
    • -
    • Querying keyservers directly from the import screen
    • -
    • Fix layout and dialog style on Android 2.2-3.0
    • -
    • Fix crash on keys with empty user ids
    • -
    • Fix crash and empty lists when coming back from signing screen
    • +
    • Elimina la exportación innecesaria de claves públicas al exportar claves secretas (privadas) (gracias a Ash Hughes)
    • +
    • Repara el establecimiento de fechas de expiración de claves (gracias a Ash Hughes)
    • +
    • Más reparaciones internas al editar claves (gracias a Ash Hughes)
    • +
    • Realización de peticiones a los servidores de claves desde la pantalla de importación
    • +
    • Repara la disposición y el estilo del cuadro de diálogo en Android 2.2-3.0
    • +
    • Repara fallos en claves con identidades de usuario vacías
    • +
    • Repara fallos y listas vacías al volver desde la pantalla de firmado
    • Bouncy Castle (librería criptográfica) actualizada de 1.47 a 1.50 y compilada desde la fuente
    • -
    • Fix upload of key from signing screen
    • +
    • Repara la subida de clave desde la pantalla de firmado

    2.2

      -
    • New design with navigation drawer
    • -
    • New public key list design
    • -
    • New public key view
    • -
    • Bug fixes for importing of keys
    • -
    • Key cross-certification (thanks to Ash Hughes)
    • -
    • Handle UTF-8 passwords properly (thanks to Ash Hughes)
    • -
    • First version with new languages (thanks to the contributors on Transifex)
    • -
    • Sharing of keys via QR Codes fixed and improved
    • -
    • Package signature verification for API
    • +
    • Nuevo diseño con panel lateral de navegación
    • +
    • Nuevo diseño de lista de claves públicas
    • +
    • Nueva vista de clave pública
    • +
    • Reparación de fallos para la importación de claves
    • +
    • Certificación-cruzada de clave (gracias a Ash Hughes)
    • +
    • Tratamiento adecuado de contraseñas UTF-8 (gracias a Ash Hughes)
    • +
    • Primera versión nuevos idiomas (gracias a los contribuidores en Transifex)
    • +
    • Compartición de claves mediante códigos QR reparada y mejorada
    • +
    • Verificación de firma de paquetes para la API

    2.1.1

      @@ -93,65 +93,65 @@ Daniel Hammann, Daniel Haß, Greg Witczak, Miroojin Bakshi, Nikhil Peter Raj, Pa

    2.1

      -
    • Lots of bug fixes
    • -
    • New API for developers
    • +
    • Muchas reparaciones de fallos
    • +
    • Nueva API para desarrolladores
    • corrección del bug PRNG por Google

    2.0

      -
    • Complete redesign
    • -
    • Share public keys via qr codes, nfc beam
    • -
    • Sign keys
    • -
    • Upload keys to server
    • -
    • Fixes import issues
    • -
    • New AIDL API
    • +
    • Rediseño completo
    • +
    • Compartido de claves públicas mediante códigos qr, nfc beam
    • +
    • Firmar claves
    • +
    • Subir claves al servidor
    • +
    • Repara problemas de importación
    • +
    • Nueva API AIDL

    1.0.8

      -
    • Basic keyserver support
    • +
    • Soporte básico de servidor de claves
    • App2sd
    • -
    • More choices for pass phrase cache: 1, 2, 4, 8, hours
    • -
    • Translations: Norwegian (thanks, Sander Danielsen), Chinese (thanks, Zhang Fredrick)
    • -
    • Bugfixes
    • -
    • Optimizations
    • +
    • Más opciones para caché de frase contraseña: 1, 2, 4, 8 horas
    • +
    • Traducciones: noruego (gracias, Sander Danielsen), chino (gracias, Zhang Fredrick)
    • +
    • Reparaciones de fallos
    • +
    • Optimizaciones

    1.0.7

      -
    • Fixed problem with signature verification of texts with trailing newline
    • -
    • More options for pass phrase cache time to live (20, 40, 60 mins)
    • +
    • Reparado un problema con la verificación de firma de textos con una nueva línea al principio
    • +
    • Más opciones para el periodo de vida en caché de la frase contraseña (20, 40, 60 mins)

    1.0.6

      -
    • Account adding crash on Froyo fixed
    • -
    • Secure file deletion
    • -
    • Option to delete key file after import
    • -
    • Stream encryption/decryption (gallery, etc.)
    • -
    • New options (language, force v3 signatures)
    • -
    • Interface changes
    • -
    • Bugfixes
    • +
    • Reparado el fallo de la adición de cuenta en Froyo
    • +
    • Borrado seguro de fichero
    • +
    • Opción para borrar fichero de clave después de importar
    • +
    • Cifrado/descifrado del stream (galería, etc.)
    • +
    • Nuevas opciones (idioma, forzar firmas v3)
    • +
    • Cambios en la interfaz
    • +
    • Reparaciones de fallos

    1.0.5

    • traducciones a alemán e italiano
    • -
    • Much smaller package, due to reduced BC sources
    • -
    • New preferences GUI
    • -
    • Layout adjustment for localization
    • -
    • Signature bugfix
    • +
    • Paquete mucho más pequeño, debido a fuentes de codec de bitrate (BC) reducido
    • +
    • Nueva interfaz gráfica (GUI) de prefencias
    • +
    • Ajuste de la disposición para localización
    • +
    • Reparación de firma

    1.0.4

      -
    • Fixed another crash caused by some SDK bug with query builder
    • +
    • Reparado otro fallo causado por algún fallo del kit de desarrollo de software (SDK) con el constructor de peticiones

    1.0.3

      -
    • Fixed crashes during encryption/signing and possibly key export
    • +
    • Reparados fallos durante el cifrado/firmado y posiblemente el exportado de clave

    1.0.2

      -
    • Filterable key lists
    • -
    • Smarter pre-selection of encryption keys
    • -
    • New Intent handling for VIEW and SEND, allows files to be encrypted/decrypted out of file managers
    • -
    • Fixes and additional features (key preselection) for K-9 Mail, new beta build available
    • +
    • Listas de claves filtrables
    • +
    • Pre-selección de claves de cifrado más inteligente
    • +
    • Nuevo objeto Intent que maneja VIEW y SEND (ver y enviar), permite que los ficheros sean cifrados/descifrados fuera de los administradores de ficheros.
    • +
    • Reparaciones y características adicionales (preselección de clave) para K-9 Mail, nueva versión beta disponible

    1.0.1

      @@ -160,11 +160,11 @@ Daniel Hammann, Daniel Haß, Greg Witczak, Miroojin Bakshi, Nikhil Peter Raj, Pa

      1.0.0

      • integración con K-9 Mail, APG compatible con la compilación beta de K-9 Mail
      • -
      • Support of more file managers (including ASTRO)
      • +
      • Soporte de más administradores de ficheros (incluyendo ASTRO)
      • traducción al esloveno
      • -
      • New database, much faster, less memory usage
      • -
      • Defined Intents and content provider for other apps
      • -
      • Bugfixes
      • +
      • Nueva base de datos, mucho más rápida, menos uso de memoria
      • +
      • Definidos objetos Intent y proveedores de contenido para otras aplicaciones
      • +
      • Reparaciones de fallos
      diff --git a/OpenKeychain/src/main/res/raw-fr/help_changelog.html b/OpenKeychain/src/main/res/raw-fr/help_changelog.html index 43618398d..309d7ce76 100644 --- a/OpenKeychain/src/main/res/raw-fr/help_changelog.html +++ b/OpenKeychain/src/main/res/raw-fr/help_changelog.html @@ -38,7 +38,7 @@

      2.5

      • Correctif - déchiffrement de messages/fichiers pgp symétriques
      • -
      • Nouvel mouture de l'écran de modification des clefs (merci à Ash Hughes)
      • +
      • Écran de modification des clefs remanié (merci à Ash Hughes)
      • Nouvelle conception moderne pour les écrans de chiffrement/déchiffrement
      • API OpenPGP version 3 (comptes multiples d'api, correctifs internes, recherche de clefs)
      @@ -110,7 +110,7 @@ Daniel Hammann, Daniel Haß, Greg Witczak, Miroojin Bakshi, Nikhil Peter Raj, Pa
      • Prise en charge de base du serveur de clefs
      • App2sd
      • -
      • Plus de choix pour le cache des phrases de passe : 1, 2, 4, 8 heures
      • +
      • Plus de choix pour le cache de la phrase de passe : 1, 2, 4, 8 heures
      • Traductions : norvégien (merci Sander Danielsen), chinois (merci Zhang Fredrick)
      • Correctifs de bogues
      • Optimisations
      • @@ -118,7 +118,7 @@ Daniel Hammann, Daniel Haß, Greg Witczak, Miroojin Bakshi, Nikhil Peter Raj, Pa

        1.0.7

        • Problème corrigé avec la vérification de la signature des textes se terminant par un retour à la ligne
        • -
        • Plus de choix pour la durée de vie de la phrase de passe : (20, 40, 60 min)
        • +
        • Plus de choix pour la durée de vie de la phrase de passe (20, 40, 60 min)

        1.0.6

          diff --git a/OpenKeychain/src/main/res/raw-it/help_changelog.html b/OpenKeychain/src/main/res/raw-it/help_changelog.html index 6b39c43c0..9134bc4a2 100644 --- a/OpenKeychain/src/main/res/raw-it/help_changelog.html +++ b/OpenKeychain/src/main/res/raw-it/help_changelog.html @@ -3,17 +3,17 @@

          2.8

            -
          • So many bugs have been fixed in this release that we focus on the main new features
          • -
          • Key edit: awesome new design, key revocation
          • -
          • Key import: awesome new design, secure keyserver connections via hkps, keyserver resolving via DNS SRV records
          • -
          • New first time screen
          • -
          • New create key screen: autocompletion of name and email based on your personal Android accounts
          • -
          • File encryption: awesome new design, support for encrypting multiple files
          • -
          • New icons to show status of key (by Brennan Novak)
          • -
          • Important bug fix: Importing of large key collections from a file is now possible
          • -
          • Notification showing cached passphrases
          • -
          -

          This release wouldn't be possible without the work of Vincent Breitmoser (GSoC 2014), mar-v-in (GSoC 2014), Daniel Albert, Art O Cathain, Daniel Haß, Tim Bray, Thialfihar

          +
        • Così tanti bug sono stati corretti in questa versione che ci concentriamo sulle principali novità
        • +
        • Modifica chiave: nuovo eccezionale design, revoca chiave
        • +
        • Importa chiave: nuovo eccezionale design, connessioni sicure via keyserver HKPS, risoluzione keyserver tramite record SRV DNS
        • +
        • Nuova schermata di introduzione
        • +
        • Nuova schermata di creazione chiave: autocompletamento di nomi e email basato sui tuoi account personali di Android
        • +
        • Codifica File: nuovo eccezionale design, supporto per codifica di più documenti
        • +
        • Nuove icone per mostrare lo stato delle chiavi (di Brennan Novak)
        • +
        • Correzione bug importante: Importazione di grandi collezioni di chiavi da un file ora è possibile
        • +
        • Notifiche mostrando la frase di accesso nella cache
        • +
        +

        Questo rilascio non sarebbe stato possibile senza il lavoro di Vincent Breitmoser (GSoC 2014), mar-v-in (GSoC 2014), Daniel Albert, Art O Cathain, Daniel Haß, Tim Bray, Thialfihar

        2.7

          @@ -25,21 +25,21 @@

        2.6.1

          -
        • Some fixes for regression bugs
        • +
        • alcune correzioni per i bug di regressione

        2.6

          -
        • Key certifications (thanks to Vincent Breitmoser)
        • -
        • Support for GnuPG partial secret keys (thanks to Vincent Breitmoser)
        • -
        • New design for signature verification
        • -
        • Custom key length (thanks to Greg Witczak)
        • -
        • Fix share-functionality from other apps
        • +
        • Certificazioni chiave (grazie a Vincent Breitmoser)
        • +
        • supporto per chiavi segrete parziali GnuPG (grazie a Vincent Breitmoser)
        • +
        • nuovo design per la verifica della firma
        • +
        • lunghezza chiave personalizzata (grazie a Greg Witczak)
        • +
        • fix funzionalità di condivisione da altre app

        2.5

          -
        • Fix decryption of symmetric pgp messages/files
        • -
        • Refactored edit key screen (thanks to Ash Hughes)
        • -
        • New modern design for encrypt/decrypt screens
        • +
        • Corretta la decodifica di messaggi PGP / file simmetrici
        • +
        • Refactoring della schermata di modifica chiave (grazie a Ash Hughes)
        • +
        • Nuovo design moderno per le schermate di codifica / decodifica
        • OpenPGP API versione 3 (api account multipli, correzioni interne, ricerca chiavi)

        2.4

        @@ -47,45 +47,45 @@ Oltre a numerose piccole correzioni, un notevole numero di patch sono state fatte dalle seguenti persone (in ordine alfabetico): Daniel Hammann, Daniel Haß, Greg Witczak, Miroojin Bakshi, Nikhil Peter Raj, Paolo Sarbinowski, Sreeram Boyapati, Vincent Breitmoser.

          -
        • New unified key list
        • -
        • Colorized key fingerprint
        • -
        • Support for keyserver ports
        • -
        • Deactivate possibility to generate weak keys
        • -
        • Much more internal work on the API
        • -
        • Certify user ids
        • -
        • Keyserver query based on machine-readable output
        • -
        • Lock navigation drawer on tablets
        • -
        • Suggestions for emails on creation of keys
        • -
        • Search in public key lists
        • -
        • And much more improvements and fixes…
        • +
        • Nuova lista chiave unificata
        • +
        • Impronta chiave colorata
        • +
        • Supporto per le porte keyserver
        • +
        • disattivata la possibilità di generare chiavi deboli
        • +
        • Molto più lavoro interno sulle API
        • +
        • Certificazione ID utente
        • +
        • Interrogazione keyserver basate su output leggibile a livello macchina
        • +
        • Blocco del menu di navigazione sui tablet
        • +
        • Suggerimenti per e-mail sulla creazione di chiavi
        • +
        • Ricerca nelle liste di chiavi pubbliche
        • +
        • E molti altri miglioramenti e correzioni ...

        2.3.1

          -
        • Hotfix for crash when upgrading from old versions
        • +
        • Correzione del crash quando si aggiorna da versioni precedenti

        2.3

          -
        • Remove unnecessary export of public keys when exporting secret key (thanks to Ash Hughes)
        • -
        • Fix setting expiry dates on keys (thanks to Ash Hughes)
        • -
        • More internal fixes when editing keys (thanks to Ash Hughes)
        • -
        • Querying keyservers directly from the import screen
        • -
        • Fix layout and dialog style on Android 2.2-3.0
        • -
        • Fix crash on keys with empty user ids
        • -
        • Fix crash and empty lists when coming back from signing screen
        • +
        • Rimossa esportazione non necessaria delle chiavi pubbliche quando si esportano le chiavi private (grazie a Ash Hughes)
        • +
        • Corretto impostazione data di scadenza delle chiavi (grazie a Ash Hughes)
        • +
        • Molte altre correzioni interne quando si modificano le chiavi (grazie a Ash Hughes)
        • +
        • Interrogazione server delle chiavi direttamente dalla schermata di importazione
        • +
        • Corretta impaginazione e stile di dialogo su Android 2.2-3.0
        • +
        • Corretto crash su chiavi con id utente vuoto
        • +
        • Corretto crash e liste vuote quando si torna dalla schermata di firma
        • Bouncy Castle (libreria crittografica) aggiornata da 1.47 a 1.50 e compilata da sorgente
        • -
        • Fix upload of key from signing screen
        • +
        • Corretto caricamento delle chiavi dalla schermata di firma

        2.2

          -
        • New design with navigation drawer
        • -
        • New public key list design
        • -
        • New public key view
        • -
        • Bug fixes for importing of keys
        • -
        • Key cross-certification (thanks to Ash Hughes)
        • -
        • Handle UTF-8 passwords properly (thanks to Ash Hughes)
        • -
        • First version with new languages (thanks to the contributors on Transifex)
        • -
        • Sharing of keys via QR Codes fixed and improved
        • -
        • Package signature verification for API
        • +
        • Nuovo design con barra di navigazione
        • +
        • Nuovo design per la lista chiavi pubbliche
        • +
        • Nuova visuale chiavi pubbliche
        • +
        • Correzione bug per importazione chiavi
        • +
        • Chiave certificazione incrociata (grazie a Ash Hughes)
        • +
        • Password UTF-8 gestite correttamente (grazie a Ash Hughes)
        • +
        • Prima versione con nuove lingue (grazie ai contributori su Transifex)
        • +
        • Condivisione di chiavi via Codici QR corretta e migliorata
        • +
        • Verifica firma pacchetto per API

        2.1.1

          @@ -93,65 +93,65 @@ Daniel Hammann, Daniel Haß, Greg Witczak, Miroojin Bakshi, Nikhil Peter Raj, Pa

        2.1

          -
        • Lots of bug fixes
        • -
        • New API for developers
        • +
        • Molte correzioni di bug
        • +
        • Nuove API per sviluppatori
        • PRNG bug fix by Google

        2.0

          -
        • Complete redesign
        • -
        • Share public keys via qr codes, nfc beam
        • -
        • Sign keys
        • -
        • Upload keys to server
        • -
        • Fixes import issues
        • -
        • New AIDL API
        • +
        • Completo restyle
        • +
        • Condivisione chiavi pubbliche via codici qr, nfc beam
        • +
        • Firma chiavi
        • +
        • Caricamento chiavi sul server
        • +
        • Corrette caratteristiche di importazione
        • +
        • Nuova API AIDL

        1.0.8

          -
        • Basic keyserver support
        • +
        • Supporto base per server delle chiavi
        • App2sd
        • -
        • More choices for pass phrase cache: 1, 2, 4, 8, hours
        • -
        • Translations: Norwegian (thanks, Sander Danielsen), Chinese (thanks, Zhang Fredrick)
        • -
        • Bugfixes
        • -
        • Optimizations
        • +
        • Aggiunte opzioni per la cache della frase di accesso: 1, 2, 4, 8 ore
        • +
        • Traduzioni: Norvegese (grazie, Sander Danielsen), Cinese (grazie, Zhang Fredrick)
        • +
        • Correzione bug
        • +
        • Ottimizzazioni

        1.0.7

          -
        • Fixed problem with signature verification of texts with trailing newline
        • -
        • More options for pass phrase cache time to live (20, 40, 60 mins)
        • +
        • Corretto problema con la verifica firma di testi con capo finale
        • +
        • Maggiori opzioni per il tempo di mantenimento della cache della frase di accesso (20, 40, 60 minuti)

        1.0.6

          -
        • Account adding crash on Froyo fixed
        • -
        • Secure file deletion
        • -
        • Option to delete key file after import
        • -
        • Stream encryption/decryption (gallery, etc.)
        • -
        • New options (language, force v3 signatures)
        • -
        • Interface changes
        • -
        • Bugfixes
        • +
        • Crash della aggiunta degli account risolto su Froyo
        • +
        • Cancellazione sicura dei file
        • +
        • Opzione per cancellare file delle chiavi dopo l'importazione
        • +
        • Flusso codifica/decodifica (galleria, ecc.)
        • +
        • Nuove opzioni (lingua, forza firme v3)
        • +
        • Cambiamenti interfaccia
        • +
        • Correzione bug

        1.0.5

        • Traduzione Italiana e Tedesca
        • -
        • Much smaller package, due to reduced BC sources
        • -
        • New preferences GUI
        • -
        • Layout adjustment for localization
        • -
        • Signature bugfix
        • +
        • Dimensioni pacchetto ridotte, a causa della riduzione dei sorgenti BC
        • +
        • Nuove preferenze GUI
        • +
        • Regolazione layout per la localizzazione
        • +
        • Correzione bug firma

        1.0.4

          -
        • Fixed another crash caused by some SDK bug with query builder
        • +
        • Corretto altro crash causato da alcuni bug SDK con query builder

        1.0.3

          -
        • Fixed crashes during encryption/signing and possibly key export
        • +
        • Corretto crash durante codifica/firma e possibilita' di esportare chiave

        1.0.2

          -
        • Filterable key lists
        • -
        • Smarter pre-selection of encryption keys
        • -
        • New Intent handling for VIEW and SEND, allows files to be encrypted/decrypted out of file managers
        • -
        • Fixes and additional features (key preselection) for K-9 Mail, new beta build available
        • +
        • Liste chiavi filtrabili
        • +
        • Preselezione di chiavi di codifica intelligente
        • +
        • Nuovo gestore intent per VIEW e SEND, permette la codifica/decodifica file all'infuori di file manager
        • +
        • Caratteristiche corrette e aggiunte (preselezione chiavi) per K-9 Mail. nuova build beta disponibile

        1.0.1

          @@ -160,11 +160,11 @@ Daniel Hammann, Daniel Haß, Greg Witczak, Miroojin Bakshi, Nikhil Peter Raj, Pa

          1.0.0

          • integrazione K-9 Mail, APG supporto beta build di K-9 Mail
          • -
          • Support of more file managers (including ASTRO)
          • +
          • Supporto per altri file manager (incluso ASTRO)
          • traduzione Slovena
          • -
          • New database, much faster, less memory usage
          • -
          • Defined Intents and content provider for other apps
          • -
          • Bugfixes
          • +
          • Nuovo database, piu' veloce, utilizzo memoria ridotto
          • +
          • Definiti Intent e ContentProvider per le altre app
          • +
          • Correzione bug
          diff --git a/OpenKeychain/src/main/res/raw-ja/help_changelog.html b/OpenKeychain/src/main/res/raw-ja/help_changelog.html index 21f0fa230..207c9d895 100644 --- a/OpenKeychain/src/main/res/raw-ja/help_changelog.html +++ b/OpenKeychain/src/main/res/raw-ja/help_changelog.html @@ -110,7 +110,7 @@ Daniel Hammann, Daniel Haß, Greg Witczak, Miroojin Bakshi, Nikhil Peter Raj, Pa
          • 鍵サーバの基本サポート
          • App2SD
          • -
          • パスフレーズのキャッシュ時間について1,2,4,8時間の選択肢追加
          • +
          • パスフレーズのキャッシュ時間についての選択肢追加: 1,2,4,8時間
          • 翻訳: ノルウェー語 (ありがとう、Sander Danielsen)、中国語 (ありがとう、Zhang Fredrick) 追加
          • バグ修正
          • 最適化
          • @@ -118,7 +118,7 @@ Daniel Hammann, Daniel Haß, Greg Witczak, Miroojin Bakshi, Nikhil Peter Raj, Pa

            1.0.7

            • 改行を含まないテキストの署名検証問題の修正
            • -
            • パスフレーズのキャッシュ時間 (20,40,60分) のオプション追加
            • +
            • パスフレーズのキャッシュ生存時間 (20,40,60分) のオプション追加

            1.0.6

              diff --git a/OpenKeychain/src/main/res/raw-pt/help_about.html b/OpenKeychain/src/main/res/raw-pt/help_about.html new file mode 100644 index 000000000..f536fecbd --- /dev/null +++ b/OpenKeychain/src/main/res/raw-pt/help_about.html @@ -0,0 +1,54 @@ + + + +

              http://www.openkeychain.org

              +

              OpenKeychain is an OpenPGP implementation for Android.

              +

              License: GPLv3+

              + +

              Developers

              +
                +
              • Dominik Schürmann (Maintainer)
              • +
              • Art O Cathain
              • +
              • Ash Hughes
              • +
              • Brian C. Barnes
              • +
              • Bahtiar 'kalkin' Gadimov
              • +
              • Daniel Albert
              • +
              • Daniel Hammann
              • +
              • Daniel Haß
              • +
              • Greg Witczak
              • +
              • 'mar-v-in'
              • +
              • Markus Doits
              • +
              • Miroojin Bakshi
              • +
              • Nikhil Peter Raj
              • +
              • Paul Sarbinowski
              • +
              • 'Senecaso'
              • +
              • Sreeram Boyapati
              • +
              • Thialfihar (APG 1.x)
              • +
              • Tim Bray
              • +
              • Vincent Breitmoser
              • +
              +

              Libraries

              + + + diff --git a/OpenKeychain/src/main/res/raw-pt/help_changelog.html b/OpenKeychain/src/main/res/raw-pt/help_changelog.html new file mode 100644 index 000000000..687fd99b9 --- /dev/null +++ b/OpenKeychain/src/main/res/raw-pt/help_changelog.html @@ -0,0 +1,170 @@ + + + +

              2.8

              +
                +
              • So many bugs have been fixed in this release that we focus on the main new features
              • +
              • Key edit: awesome new design, key revocation
              • +
              • Key import: awesome new design, secure keyserver connections via hkps, keyserver resolving via DNS SRV records
              • +
              • New first time screen
              • +
              • New key creation screen: autocompletion of name and email based on your personal Android accounts
              • +
              • File encryption: awesome new design, support for encrypting multiple files
              • +
              • New icons to show status of key (by Brennan Novak)
              • +
              • Important bug fix: Importing of large key collections from a file is now possible
              • +
              • Notification showing cached passphrases
              • +
              +

              This release wouldn't be possible without the work of Vincent Breitmoser (GSoC 2014), mar-v-in (GSoC 2014), Daniel Albert, Art O Cathain, Daniel Haß, Tim Bray, Thialfihar

              + +

              2.7

              +
                +
              • Purple! (Dominik, Vincent)
              • +
              • New key view design (Dominik, Vincent)
              • +
              • New flat Android buttons (Dominik, Vincent)
              • +
              • API fixes (Dominik)
              • +
              • Keybase.io import (Tim Bray)
              • +
              +

              2.6.1

              +
                +
              • Some fixes for regression bugs
              • +
              +

              2.6

              +
                +
              • Key certifications (thanks to Vincent Breitmoser)
              • +
              • Support for GnuPG partial secret keys (thanks to Vincent Breitmoser)
              • +
              • New design for signature verification
              • +
              • Custom key length (thanks to Greg Witczak)
              • +
              • Fix share-functionality from other apps
              • +
              +

              2.5

              +
                +
              • Fix decryption of symmetric pgp messages/files
              • +
              • Refactored key edit screen (thanks to Ash Hughes)
              • +
              • New modern design for encrypt/decrypt screens
              • +
              • OpenPGP API version 3 (multiple api accounts, internal fixes, key lookup)
              • +
              +

              2.4

              +

              Thanks to all applicants of Google Summer of Code 2014 who made this release feature rich and bug free! +Besides several small patches, a notable number of patches are made by the following people (in alphabetical order): +Daniel Hammann, Daniel Haß, Greg Witczak, Miroojin Bakshi, Nikhil Peter Raj, Paul Sarbinowski, Sreeram Boyapati, Vincent Breitmoser.

              +
                +
              • New unified key list
              • +
              • Colorized key fingerprint
              • +
              • Support for keyserver ports
              • +
              • Deactivate possibility to generate weak keys
              • +
              • Much more internal work on the API
              • +
              • Certify user ids
              • +
              • Keyserver query based on machine-readable output
              • +
              • Lock navigation drawer on tablets
              • +
              • Suggestions for emails on creation of keys
              • +
              • Search in public key lists
              • +
              • And much more improvements and fixes…
              • +
              +

              2.3.1

              +
                +
              • Hotfix for crash when upgrading from old versions
              • +
              +

              2.3

              +
                +
              • Remove unnecessary export of public keys when exporting secret key (thanks to Ash Hughes)
              • +
              • Fix setting expiry dates on keys (thanks to Ash Hughes)
              • +
              • More internal fixes when editing keys (thanks to Ash Hughes)
              • +
              • Querying keyservers directly from the import screen
              • +
              • Fix layout and dialog style on Android 2.2-3.0
              • +
              • Fix crash on keys with empty user ids
              • +
              • Fix crash and empty lists when coming back from signing screen
              • +
              • Bouncy Castle (cryptography library) updated from 1.47 to 1.50 and build from source
              • +
              • Fix upload of key from signing screen
              • +
              +

              2.2

              +
                +
              • New design with navigation drawer
              • +
              • New public key list design
              • +
              • New public key view
              • +
              • Bug fixes for importing of keys
              • +
              • Key cross-certification (thanks to Ash Hughes)
              • +
              • Handle UTF-8 passwords properly (thanks to Ash Hughes)
              • +
              • First version with new languages (thanks to the contributors on Transifex)
              • +
              • Sharing of keys via QR Codes fixed and improved
              • +
              • Package signature verification for API
              • +
              +

              2.1.1

              +
                +
              • API Updates, preparation for K-9 Mail integration
              • +
              +

              2.1

              +
                +
              • Lots of bug fixes
              • +
              • New API for developers
              • +
              • PRNG bug fix by Google
              • +
              +

              2.0

              +
                +
              • Complete redesign
              • +
              • Share public keys via qr codes, nfc beam
              • +
              • Sign keys
              • +
              • Upload keys to server
              • +
              • Fixes import issues
              • +
              • New AIDL API
              • +
              +

              1.0.8

              +
                +
              • Basic keyserver support
              • +
              • App2sd
              • +
              • More choices for passphrase cache: 1, 2, 4, 8, hours
              • +
              • Translations: Norwegian (thanks, Sander Danielsen), Chinese (thanks, Zhang Fredrick)
              • +
              • Bugfixes
              • +
              • Optimizations
              • +
              +

              1.0.7

              +
                +
              • Fixed problem with signature verification of texts with trailing newline
              • +
              • More options for passphrase cache time to live (20, 40, 60 mins)
              • +
              +

              1.0.6

              +
                +
              • Account adding crash on Froyo fixed
              • +
              • Secure file deletion
              • +
              • Option to delete key file after import
              • +
              • Stream encryption/decryption (gallery, etc.)
              • +
              • New options (language, force v3 signatures)
              • +
              • Interface changes
              • +
              • Bugfixes
              • +
              +

              1.0.5

              +
                +
              • German and Italian translation
              • +
              • Much smaller package, due to reduced BC sources
              • +
              • New preferences GUI
              • +
              • Layout adjustment for localization
              • +
              • Signature bugfix
              • +
              +

              1.0.4

              +
                +
              • Fixed another crash caused by some SDK bug with query builder
              • +
              +

              1.0.3

              +
                +
              • Fixed crashes during encryption/signing and possibly key export
              • +
              +

              1.0.2

              +
                +
              • Filterable key lists
              • +
              • Smarter pre-selection of encryption keys
              • +
              • New Intent handling for VIEW and SEND, allows files to be encrypted/decrypted out of file managers
              • +
              • Fixes and additional features (key preselection) for K-9 Mail, new beta build available
              • +
              +

              1.0.1

              +
                +
              • GMail account listing was broken in 1.0.0, fixed again
              • +
              +

              1.0.0

              +
                +
              • K-9 Mail integration, APG supporting beta build of K-9 Mail
              • +
              • Support of more file managers (including ASTRO)
              • +
              • Slovenian translation
              • +
              • New database, much faster, less memory usage
              • +
              • Defined Intents and content provider for other apps
              • +
              • Bugfixes
              • +
              + + diff --git a/OpenKeychain/src/main/res/raw-pt/help_nfc_beam.html b/OpenKeychain/src/main/res/raw-pt/help_nfc_beam.html new file mode 100644 index 000000000..88492731c --- /dev/null +++ b/OpenKeychain/src/main/res/raw-pt/help_nfc_beam.html @@ -0,0 +1,12 @@ + + + +

              How to receive keys

              +
                +
              1. Go to your partners contacts and open the contact you want to share.
              2. +
              3. Hold the two devices back to back (they have to be almost touching) and you’ll feel a vibration.
              4. +
              5. After it vibrates you’ll see the content on your partners device turn into a card-like object with Star Trek warp speed-looking animation in the background.
              6. +
              7. Tap the card and the content will then load on the your device.
              8. +
              + + diff --git a/OpenKeychain/src/main/res/raw-pt/help_start.html b/OpenKeychain/src/main/res/raw-pt/help_start.html new file mode 100644 index 000000000..51a76c01e --- /dev/null +++ b/OpenKeychain/src/main/res/raw-pt/help_start.html @@ -0,0 +1,22 @@ + + + +

              Getting started

              +

              First you need a personal secret key. Create one via the option menus in "Keys" or import existing secret keys. Afterwards, you can download your friends' keys or exchange them via QR Codes or NFC.

              + +

              It is recommended that you install OI File Manager for enhanced file selection and Barcode Scanner to scan generated QR Codes. Clicking on the links will open Google Play Store or F-Droid for installation.

              + +

              Applications

              +

              Several applications support OpenKeychain to encrypt/sign your private communication:

              K-9 Mail: OpenKeychain support available in current alpha build!

              Conversations
              : Jabber/XMPP client

              PGPAuth
              : App to send a PGP-signed request to a server to open or close something, e.g. a door

              + +

              I found a bug in OpenKeychain!

              +

              Please report the bug using the issue tracker of OpenKeychain.

              + +

              Contribute

              +

              If you want to help us developing OpenKeychain by contributing code follow our small guide on Github.

              + +

              Translations

              +

              Help translating OpenKeychain! Everybody can participate at OpenKeychain on Transifex.

              + + + diff --git a/OpenKeychain/src/main/res/raw-pt/help_wot.html b/OpenKeychain/src/main/res/raw-pt/help_wot.html new file mode 100644 index 000000000..29790139b --- /dev/null +++ b/OpenKeychain/src/main/res/raw-pt/help_wot.html @@ -0,0 +1,17 @@ + + + +

              Web of Trust

              +

              The Web of Trust describes the part of PGP which deals with creation and bookkeeping of certifications. It provides mechanisms to help the user keep track of who a public key belongs to, and share this information with others; To ensure the privacy of encrypted communication, it is essential to know that the public key you encrypt to belongs to the person you think it does.

              + +

              Support in OpenKeychain

              +

              There is only basic support for Web of Trust in OpenKeychain. This is a heavy work in progress and subject to changes in upcoming releases.

              + +

              Trust Model

              +

              Trust evaluation is based on the simple assumption that all keys which have secret keys available are trusted. Public keys which contain at least one user id certified by a trusted key will be marked with a green dot in the key listings. It is not (yet) possible to specify trust levels for certificates of other known public keys.

              + +

              Certifying keys

              +

              Support for key certification is available, and user ids can be certified individually. It is not yet possible to specify the level of trust or create local and other special types of certificates.

              + + + diff --git a/OpenKeychain/src/main/res/raw-pt/nfc_beam_share.html b/OpenKeychain/src/main/res/raw-pt/nfc_beam_share.html new file mode 100644 index 000000000..083e055c7 --- /dev/null +++ b/OpenKeychain/src/main/res/raw-pt/nfc_beam_share.html @@ -0,0 +1,11 @@ + + + +
                +
              1. Make sure that NFC is turned on in Settings > More > NFC and make sure that Android Beam is also on in the same section.
              2. +
              3. Hold the two devices back to back (they have to be almost touching) and you'll feel a vibration.
              4. +
              5. After it vibrates you'll see the content on your device turn into a card-like object with Star Trek warp speed-looking animation in the background.
              6. +
              7. Tap the card and the content will then load on the other person’s device.
              8. +
              + + diff --git a/OpenKeychain/src/main/res/raw-uk/help_about.html b/OpenKeychain/src/main/res/raw-uk/help_about.html index 92fd7db13..106e7cabc 100644 --- a/OpenKeychain/src/main/res/raw-uk/help_about.html +++ b/OpenKeychain/src/main/res/raw-uk/help_about.html @@ -5,14 +5,14 @@

              OpenKeychain імплементація OpenPGP для Андроїду.

              Ліцензія: GPLv3+

              -

              Developers

              +

              Розробники

                -
              • Dominik Schürmann (Maintainer)
              • -
              • Art O Cathain
              • -
              • Ash Hughes
              • +
              • Домінік Шурман (супроводжувач)
              • +
              • Арт О'Катен
              • +
              • Еш Гуджес
              • Браян С. Барнс
              • -
              • Bahtiar 'kalkin' Gadimov
              • -
              • Daniel Albert
              • +
              • Бахтіяр 'kalkin' Ґадімов
              • +
              • Даніель Альберт
              • Даніель Гаман
              • Даніель Габ
              • Ґреґ Вітчак
              • @@ -34,13 +34,13 @@
              • Бібліотека підтримки Android в.7 'appcompat' (Ліцензія Apache в.2)
              • -KeybaseLib (Apache License v2)
              • +KeybaseLib (ліцензія Apache в2)
              • -SuperToasts (Apache License v2)
              • +SuperToasts (ліцензія Apache в2)
              • -TokenAutoComplete (Apache License v2)
              • +TokenAutoComplete (ліцензія Apache в2)
              • -MiniDNS (Apache License v2)
              • +MiniDNS (ліцензія Apache в2)
              • StickyListHeaders (ліцензія Apache в. 2)
              • diff --git a/OpenKeychain/src/main/res/raw-uk/help_changelog.html b/OpenKeychain/src/main/res/raw-uk/help_changelog.html index 7ecb25c2b..f28210fd0 100644 --- a/OpenKeychain/src/main/res/raw-uk/help_changelog.html +++ b/OpenKeychain/src/main/res/raw-uk/help_changelog.html @@ -3,17 +3,17 @@

                2.8

                  -
                • So many bugs have been fixed in this release that we focus on the main new features
                • -
                • Key edit: awesome new design, key revocation
                • -
                • Key import: awesome new design, secure keyserver connections via hkps, keyserver resolving via DNS SRV records
                • -
                • New first time screen
                • -
                • New create key screen: autocompletion of name and email based on your personal Android accounts
                • -
                • File encryption: awesome new design, support for encrypting multiple files
                • -
                • New icons to show status of key (by Brennan Novak)
                • -
                • Important bug fix: Importing of large key collections from a file is now possible
                • -
                • Notification showing cached passphrases
                • -
                -

                This release wouldn't be possible without the work of Vincent Breitmoser (GSoC 2014), mar-v-in (GSoC 2014), Daniel Albert, Art O Cathain, Daniel Haß, Tim Bray, Thialfihar

                +
              • У цій версії виправлено надто багато вад, тому ви зосередилися на основних нових функціях
              • +
              • Редагування ключа: новий вражаючий дизайн, відкликання ключа
              • +
              • Імпорт ключа: новий вражаючий дизайн, безпечні з'єднання із сервером ключів через hkps, вирішення сервера ключів через записи DNS SRV
              • +
              • Новий екран першого запуску
              • +
              • Новий екран створення ключа: автозавершення імені та ел. пошти на основі вашого особистого профілю на Андроїді
              • +
              • Шифрування файлу: новий вражаючий дизайн, підтримка шифрування кількох файлів
              • +
              • Нові піктограми для показу стану ключа (від Бренана Новака)
              • +
              • Виправлення важливої вади: зараз став можливим імпорт великих збірок ключів із файлу
              • +
              • Сповіщення для показу кешованих парольних фраз
              • +
              +

              Ця версія була б неможливою без роботи Вінсента Брейтмозера (GSoC 2014), mar-v-in (GSoC 2014), Даніеля Альберта, Арт О'Катен, Даніеля Хасс, Тіма Брея, Thialfihar

              2.7

                @@ -25,21 +25,21 @@

              2.6.1

                -
              • Some fixes for regression bugs
              • +
              • Деякі виправлення для накопичених вад

              2.6

                -
              • Key certifications (thanks to Vincent Breitmoser)
              • -
              • Support for GnuPG partial secret keys (thanks to Vincent Breitmoser)
              • -
              • New design for signature verification
              • -
              • Custom key length (thanks to Greg Witczak)
              • -
              • Fix share-functionality from other apps
              • +
              • Сертифікації ключів (завдяки Вінсенту Бреймозеру)
              • +
              • Підтримка часткових секретних ключів для GnuPG (завдяки Вінсенту Брейтмозеру)
              • +
              • Новий дизайн для перевірки підпису
              • +
              • Власна довжина ключа (завдяки Ґреґу Вітчаку)
              • +
              • Виправлено функцію поширення з інших програм

              2.5

                -
              • Fix decryption of symmetric pgp messages/files
              • -
              • Refactored edit key screen (thanks to Ash Hughes)
              • -
              • New modern design for encrypt/decrypt screens
              • +
              • Виправлено опис симетричних повідомлень/файлів pgp
              • +
              • Перероблено екран редагування ключа (завдяки Ash Hughes)
              • +
              • Новий сучасний дизайн для екранів шифрування/розшифрування
              • OpenPGP API версія 3 (підтримка кількох профілів, внутрішні зміни, пошук ключа)

              2.4

              @@ -47,45 +47,45 @@ Крім окремих незначних латок, значне число латок зробили наступні люди (у алфавітному порядку): Даніель Гаман, Даніель Габ, Ґреґ Вітчак, Міроджін Бакші, Ніхіл Петер Радж, Пауль Сарбіновський, Срірам Бояпаті, Вінсент Брейтмосер.

                -
              • New unified key list
              • -
              • Colorized key fingerprint
              • -
              • Support for keyserver ports
              • -
              • Deactivate possibility to generate weak keys
              • -
              • Much more internal work on the API
              • -
              • Certify user ids
              • -
              • Keyserver query based on machine-readable output
              • -
              • Lock navigation drawer on tablets
              • -
              • Suggestions for emails on creation of keys
              • -
              • Search in public key lists
              • -
              • And much more improvements and fixes…
              • +
              • Новий єдиний перелік ключів
              • +
              • Кольоровий відбиток ключа
              • +
              • Підтримка для портів сервера ключів
              • +
              • Деактивувати можливість генерувати слабкі ключі
              • +
              • Набагато більше внутрішньої роботи на API
              • +
              • Сертифікувано ідентифікатори користувача
              • +
              • Запит сервера ключів на основі машиночитабельного виводу
              • +
              • Блокування панелі навігації на планшетах
              • +
              • Пропозиції для листів при створенні ключів
              • +
              • Пошук у списках відкритих ключів
              • +
              • І багато інших покращень та виправлень…

              2.3.1

                -
              • Hotfix for crash when upgrading from old versions
              • +
              • Свіже виправлення збою при оновленні із старих версій

              2.3

                -
              • Remove unnecessary export of public keys when exporting secret key (thanks to Ash Hughes)
              • -
              • Fix setting expiry dates on keys (thanks to Ash Hughes)
              • -
              • More internal fixes when editing keys (thanks to Ash Hughes)
              • -
              • Querying keyservers directly from the import screen
              • -
              • Fix layout and dialog style on Android 2.2-3.0
              • -
              • Fix crash on keys with empty user ids
              • -
              • Fix crash and empty lists when coming back from signing screen
              • +
              • Видалений непотрібний експорт публічного ключа при експорті секретного ключа (завдяки Ash Hughes)
              • +
              • Виправлено налаштування дат дії ключів (завдяки Ash Hughes)
              • +
              • Більше внутрішніх виправлень при редагуванні ключів (завдяки Ash Hughes)
              • +
              • Сервери запитаного ключа безпосередньо з екрану імпорту
              • +
              • Виправлено стиль розмітки і діалогу у Андроїд 2.2-3.0
              • +
              • Виправлено збої, коли ключ мав порожній ідентифікатор користувача
              • +
              • Виправлено збої та порожні списки при поверненні з екрану реєстрації
              • Bouncy Castle (криптографічна бібліотека) оновлена з версії 1.47 до 1.50 та зібрана з коду
              • -
              • Fix upload of key from signing screen
              • +
              • Виправлено завантаження ключа з вікна реєстрації

              2.2

                -
              • New design with navigation drawer
              • -
              • New public key list design
              • -
              • New public key view
              • -
              • Bug fixes for importing of keys
              • -
              • Key cross-certification (thanks to Ash Hughes)
              • -
              • Handle UTF-8 passwords properly (thanks to Ash Hughes)
              • -
              • First version with new languages (thanks to the contributors on Transifex)
              • -
              • Sharing of keys via QR Codes fixed and improved
              • -
              • Package signature verification for API
              • +
              • Новий дизайн з бічною панеллю
              • +
              • Новий дизайн списку ключів
              • +
              • Новий вид перегляду ключа
              • +
              • Виправлення помилок імпорту ключів
              • +
              • Крос-сертифікація ключів (завдяки Ash Hughes)
              • +
              • Правильна обробка паролів в UTF-8 (завдяки Ash Hughes)
              • +
              • Перша версія з новими мовами (завдяки перекладачам на Transifex)
              • +
              • Виправлення і поліпшення передачі ключів через QR коди
              • +
              • Перевірка підписів пакетів для API

              2.1.1

                @@ -93,65 +93,65 @@

              2.1

                -
              • Lots of bug fixes
              • -
              • New API for developers
              • +
              • Безліч виправлень помилок
              • +
              • Новий API для розробників
              • Виправлення вади генератора випадкових чисел від Google

              2.0

                -
              • Complete redesign
              • -
              • Share public keys via qr codes, nfc beam
              • -
              • Sign keys
              • -
              • Upload keys to server
              • -
              • Fixes import issues
              • -
              • New AIDL API
              • +
              • Переробка дизайну
              • +
              • Передача ключів через QR-коди і NFC
              • +
              • Підписати ключ
              • +
              • Завантаження на сервер ключів
              • +
              • Виправлення проблем імпорту
              • +
              • Новий AIDL API

              1.0.8

                -
              • Basic keyserver support
              • +
              • Підтримка сервера основних ключів
              • App2sd
              • -
              • More choices for pass phrase cache: 1, 2, 4, 8, hours
              • -
              • Translations: Norwegian (thanks, Sander Danielsen), Chinese (thanks, Zhang Fredrick)
              • -
              • Bugfixes
              • -
              • Optimizations
              • +
              • Більше варіантів збереження кешу пароля: 1, 2, 4, 8 годин
              • +
              • Переклади: норвезькою (завдяки Сандер Даніельсен), китайською (завдяки Чжан Фредріку)
              • +
              • Виправлення вад
              • +
              • Оптимізації

              1.0.7

                -
              • Fixed problem with signature verification of texts with trailing newline
              • -
              • More options for pass phrase cache time to live (20, 40, 60 mins)
              • +
              • Виправлення помилки при перевірці підпису тексту з переведенням рядка
              • +
              • Більше варіантів збереження кешу пароля (20, 40, 60 хвилин)

              1.0.6

                -
              • Account adding crash on Froyo fixed
              • -
              • Secure file deletion
              • -
              • Option to delete key file after import
              • -
              • Stream encryption/decryption (gallery, etc.)
              • -
              • New options (language, force v3 signatures)
              • -
              • Interface changes
              • -
              • Bugfixes
              • +
              • Виправлення помилки створення запису на Froyo
              • +
              • Вилучення безпечного файлу
              • +
              • Вилучення файлу ключа після імпорту
              • +
              • Передача шифрування (галерея і т. д.)
              • +
              • Нові можливості (мова, примусові v3 підписи)
              • +
              • Зміни інтерфейсу
              • +
              • Виправлення вад

              1.0.5

              • Німецький та італійський переклад
              • -
              • Much smaller package, due to reduced BC sources
              • -
              • New preferences GUI
              • -
              • Layout adjustment for localization
              • -
              • Signature bugfix
              • +
              • Істотно менший пакунок програми завдяки зменшенню джерел
              • +
              • Нові налаштунки інтерфейсу
              • +
              • Зміна розмітки для локалізації
              • +
              • Виправлення помилки підпису

              1.0.4

                -
              • Fixed another crash caused by some SDK bug with query builder
              • +
              • Виправлення ще однієї помилки, що виникає в SDK

              1.0.3

                -
              • Fixed crashes during encryption/signing and possibly key export
              • +
              • Виправлення помилок при шифруванні/підписанні та експорті ключів

              1.0.2

                -
              • Filterable key lists
              • -
              • Smarter pre-selection of encryption keys
              • -
              • New Intent handling for VIEW and SEND, allows files to be encrypted/decrypted out of file managers
              • -
              • Fixes and additional features (key preselection) for K-9 Mail, new beta build available
              • +
              • Фільтр списку ключів
              • +
              • Поліпшення вибору ключів шифрування
              • +
              • Додана можливість шифрувати файли прямо з файлового менеджера
              • +
              • Виправлення помилок і нові можливості (попередній вибір ключа) для інтеграції з K-9 Mail, нова бета-збірка доступна

              1.0.1

                @@ -160,11 +160,11 @@

                1.0.0

                • інтеграція з K-9 Mail, APG підтримує бета-збірку K-9 Mail
                • -
                • Support of more file managers (including ASTRO)
                • +
                • Підтримка сторонніх файлових менеджерів (в т.ч. ASTRO)
                • Словенський переклад
                • -
                • New database, much faster, less memory usage
                • -
                • Defined Intents and content provider for other apps
                • -
                • Bugfixes
                • +
                • Нова база даних, швидша робота, менше використання пам'яті
                • +
                • Додано обробники для взаємодії з іншими програмами
                • +
                • Виправлення вад
                diff --git a/OpenKeychain/src/main/res/values-cs/strings.xml b/OpenKeychain/src/main/res/values-cs/strings.xml index c9e7875d8..5f62b9036 100644 --- a/OpenKeychain/src/main/res/values-cs/strings.xml +++ b/OpenKeychain/src/main/res/values-cs/strings.xml @@ -1,14 +1,21 @@ + Vybrat klíče + Vybrat svůj klíč Zašifrovat Rozšifrovat Heslo + Přidat podklíč Editovat klíč Možnosti Appky Nastavení keyservrů Změnit heslo + Sdílet otisk s... + Sdílet klíč s... + Sdílet soubor s... + Sdílet zprávu s... Zašifrovat do souboru Rozšifrovat do souboru Importovat klíče @@ -19,6 +26,8 @@ Certifikovat identity Detaily klíče Nápověda + Log + Vytvořit klíč Identity Podklíče @@ -26,42 +35,68 @@ Výchozí hodnoty Pokročilé Akce + Celý klíč Klíč použitý pro certifikaci Uploadovat klíč Keyserver + Otisk + Klíče k ověření + Dešifrovat, ověřit a uložit soubor + Dešifrovat a ověřit zpávu Zaširovat a uložit soubor + Zašifrovat a sdílet soubor Uložit Zrušit Smazat + Žádná expirace OK Nahrát na keyserver Další Zpět Vyhledat klíč + Zašifrovat a sdílet zprávu + Zobrazit klíč certifikátu + Vytvořit klíč + Přidat soubor(y) Nastavení Nápověda Exportovat do souboru Smazat klíč + Vytvořit moje klíče + Importovat existující klíč Hledat Beam settings Zrušit Zašifrovat do... Vybrat vše Přidat klíče + Exportovat všechny klíče + Zobrazit pokročilé info Zpráva Soubor + Soubor(y) + Soubor: Bez hesla Heslo + Opakovat heslo Algoritmus + Soubor ASCII armor + Soubory: ASCII armor + Od: + Komu: + Soubory: smazat po zašifrování Smazat po rozšifrování Šifrovací algoritmus Hashovací algoritmus + Veřejným klíčem + Heslem Cache hesel Komprimovat zprávu Komprimovat soubor + Keyservery ID klíče Vytvořeno Expirace @@ -79,6 +114,8 @@ <žádný klíč> slouží k šifrovní slouží k podpisu + může ověřit + nemůže ověřit po epiraci revokovat Tajný klíč: @@ -118,6 +155,8 @@ Určitě smazat\n%s? Úspěšně smazáno. Nejprve vyberte soubor. + Úspěšně podepsáno a/nebo zašifrováno. + Úspěšně podepsání a/nebo zašifrováno do schránky. Heslo zadejte dvakrát. Vyberte alespoň jeden šifrovací klíč. Vyberte alespoň jeden šifrovací nebo podpisový klíč. @@ -127,14 +166,19 @@ Opravdu si přejete smazat všechny vybrané veřejné klíče?\nToto nebude možné vzít zpět! Opravdu chcete smazat TAJNÝ klíč \'%s\'?\nToto je nevratná operace! Opravdu chcete smazat veřejný klíč \'%s\'?\nToto nebude možné vrátit zpět! + Zárověň exportovat tajný klíč Úspěšně exportován 1 klíč. Úspěšně exportován %d klíč. Žádný kláč pro export. Žádný: pouze podklíče podporují ElGamal. Nemohu najít klíč %08X. Úspěšně nahráno na keyserver. + Úspěšně ověřené identity Seznam je prázný! + Úspěšně odeslaný klíč pomocí NFC Beam! Klíč byl zkopírován do schránky! + Fingerprint byl zkopírován do schránky! + Prosím vyberte klíč pro ověření! Klíč je příliš velký aby byl sdílen pomocí této metody! + Špatný podpis! + Neznámý veřejný klíč + Validní podpis (neověřen) + Validní podpis (ověřen) + Úspěšně rozšifrováno + Úspěšně rozšifrováno ale neznámý veřejný klíč + Úspěšně rozšifrováno a validní podpis (neověřen) + Úspěšně rozšifrováno a validní podpis (ověřen) Hotovo. Zrušit ukládám... importuji... exportuji... + uloaduji... vytvářím klíč... vytvářím hlavní klíč... + generuji nový RSA klíč... + generuji nový DSA klíč... + generuji nový ElGamal klíč... + modifikuji klíčenku... + odemykám klíčenku... + přidávám uživatelské IDčka... + revokuji uživatelská IDčka... + měním primární uživatelské ID... + modifikuji podklíče... + revokuji podklíče... + přidávám podklíče... + mněním heslo... extrahuji podpisový klíč... extrahuji klíč... připravuji streamy... @@ -177,13 +247,13 @@ zpracovávám podpis... verifikuji podpis... podepisuji... + ověřuji... načítám data... hledám klíč... rozbaluji data... verifikuji integritu... mažu \'%s\' bezpečně... - Jméno/Email/ID klíče 512 768 @@ -195,6 +265,7 @@ 8192 Vlastní velikost klíče Napište vlastní délku klíče (v bitech): + Délka RSA klíče musí být větší než 1024 a alespoň 16384. Zároveň musí být dělitelná 8mi. Délka DSA klíče musí být alespoň 512 a nejvýše 1024. Zároveň musí být dělitelná 64. rychle @@ -208,10 +279,19 @@ O aplikaci Verze: + Keyserver + Soubor/schránka + QR kód/NFC + Keybase.io Importovat vybrané klíče QR kód nerozpoznán! Zkuste to znovu prosím! Fingerprint je příliš krátký (< 16 znaků) + Skenovat QR kód... + Zobrazit log + Nic k importu + Chyba importu klíčů! + , s varováními Dešifrovat soubor pomocí OpenKeychain Importovat kíč pomocí OpenKeychain @@ -229,17 +309,17 @@ Uložit Zrušit Zneplatnit přístup + Spustit aplikaci Smazat účet Jméno balíčku SHA-256 z podpisu balíčku Účty Žádné účty nejsou specifikovány pro tuto appku. + Appka žádá o vytvoření nového účtu. Prosím vyberte nějaký existující klíč nebo vytvořte nový.\nAppky jsou omezeny na použití klíčů, které zde vyberete! Zobrazená appka chce zašifrovat/rozšifrovat zprávy a podepsat je vačím jménem.\nPovolit přístup?\n\nVAROVÁNÍ: Pokud nevíte proč se tato obrazovka objevila, zamítněte přístup! Také můžete zneplatnit přístup jindy v obrazovce \'Appky\'. Povolit přístup Zamítnout přístup Prosím vyberte klíč! - Nebyl nalezen žádný veřejný klíč pro tyto identity: - Existuje více jak jeden veřejný klíč pro tyto identity: Zkontrolujte prosím seznam příjemců! Selhala kontrola podpisu! Instalovali jste tuto appku z jiného zdroje? Pokud jste si jistí, že toto není útok, zneplatněte registraci této appky v OpenKeychain a poté ji znovu zaregistrujte. @@ -250,16 +330,51 @@ Můžete začít pomocí nebo vytvářím váš vlastní klíč + Importuji existující klíč. Editovat klíč Šifruji pomocí těchto klíčů. Certifikovat identity + Aktualizuji z keyserveru + Sdílet pomocí... + Sdílet přes NFC tak, že podržíte zařízení zády k sobě + Aktualizovat na keyserver Hlavní info + Sdílet + Podklíče Certifikáty + Změnit heslo + Přidat identitu + Přidat podklíč + Vyberte akci! + + Změnit na hlavní identitu + Zneplatnit identitu + + + Zrušit zneplatnění + + Tato identity byla zneplatněna. Toto není možné vzít zpět. + Vyberte akci! + + Změnit expiraci + Zneplatnit podklíč + + nový + Aktualizovat klíč na keyserver + Toto pole je vyžadováno + Heslo nesouhlasí + Zadali jste následující identitu: + Vytvoření identity může chvíli tvrvat. Mezitím si dejte šálek kávy.\n(3 podklíče, RSA, 4096 bit) + Zadejte své celé jméno, emailovou adresu a zvolte heslo. + Celé jméno, např. Jan Novák + Tento klíč byl zneplatněn! + Tento klíč vyexpiroval! + Klíče Podepisuji a šifruji Dešifruji a kontroluji Appky @@ -267,6 +382,8 @@ Zavří navigační panel Moje Klíče + Zpráva zadaná sem bude podepsána za použití klíče vybraného v poli \'Od\' a zašifrovaná pro všecny příjemce vybrané v \'Pro\'. + Vložte zašifrovaný text pro jeho rozšifrování a/nebo ověření... výchozí žádný @@ -283,6 +400,7 @@ + Identita diff --git a/OpenKeychain/src/main/res/values-de/strings.xml b/OpenKeychain/src/main/res/values-de/strings.xml index 18e6cf585..fb43b9d04 100644 --- a/OpenKeychain/src/main/res/values-de/strings.xml +++ b/OpenKeychain/src/main/res/values-de/strings.xml @@ -6,6 +6,7 @@ Verschlüsseln Entschlüsseln Passwort + Unterschlüssel hinzufügen Schlüssel bearbeiten Einstellungen Apps @@ -26,6 +27,7 @@ Schlüsseldetails Hilfe Log + Schlüssel erzeugen Identitäten Unterschlüssel @@ -47,6 +49,7 @@ Speichern Abbrechen Löschen + verfällt nie Okay Auf Schlüsselserver hochladen Weiter @@ -80,9 +83,10 @@ Passwort Passwort wiederholen Algorithmus + ASCII Armor Datei Datei: ASCII Armor Lass andere wissen dass du OpenKeychain nutzt - Fügt \'OpenKeychain v2.7\' zu OpenPGP Signaturen, Daten und exportierten Schlüsseln hinzu + Fügt \'OpenKeychain v2.7\' zu OpenPGP Signaturen, DAten und exportierten Schlüsseln hinzu Von: An: Dateien: Nach Verschlüsselung löschen @@ -245,8 +249,10 @@ verändere Schlüsselbund... entsperre Schlüsselbund... füge User ID hinzu... + Wiederrufe Benutzerkennungen... ändere Haupt User ID... verändere Unterschlüssel... + Widerrufe Unterschlüssel... füge Unterschlüssel hinzu... ändere Passwort... @@ -263,14 +269,13 @@ Signatur wird verarbeitet… Signatur wird verifiziert… wird signiert… + beglaubige... Daten werden gelesen… Schlüssel wird gesucht… Daten werden entpackt… Integrität wird überprüft… \'%s\' wird sicher gelöscht… - Name/Email/Schlüssel ID... - Name/Keybase.io Benutzername... 512 768 @@ -282,6 +287,7 @@ 8192 Benutzerdefinierte Schlüssellänge Benutzerdefinierte Schlüssellänge (in Bit): + Die RSA-Schlüssellänge muss grösser als 1024 und höchstens 16384 sein. Sie muss auch ein Mehrfaches von 8 sein. Die DSA-Schlüssellänge muss mindestens 512 und höchstens 1024 sein. Auch muss sie ein Mehrfaches von 64 sein. schnell @@ -343,12 +349,11 @@ SHA-256 der Paketsignatur Konten Keine Konten mit dieser Anwendung verknüpft. + Die Anwendung verlangt die Erstellung eines neuen Accounts. Bitte wähle einen deiner existierenden Schlüssel aus oder erstelle einen Neuen.\nAnwendugen sind auf die Nutzung der Schlüssel beschränkt die du hier auswählst! Folgende Anwendung möchte Nachrichten ver-/entschlüsseln und in Ihrem Namen signieren\nZugriff erlauben?\n\nVORSICHT: Sollten Sie nicht wissen warum dieses Fenster erscheint, sollten Sie den Zugriff nicht gewähren! Sie können Zugriffe später über das Menü \'Anwendungen\' widerrufen. Zugriff erlauben Zugriff verbieten Bitte einen Schlüssel auswählen! - Für diese Identität wurden keine öffentlichen Schlüssel gefunden: - Für diese Identität existieren mehrere öffentliche Schlüssel: Bitte die Liste der Empfänger überprüfen! Signaturüberprüfung fehlgeschlagen! Haben Sie diese Anwendung aus einer anderen Quelle installiert? Wenn Sie eine Attacke ausschliessen können, sollten Sie die Registrierung der App in OpenKeychain widerrufen und die Anwendung erneut registrieren. @@ -363,21 +368,33 @@ Du kannst anfangen OpenKeychain zu benutzen indem du oder deinen eigenen Schlüssel erstellst + Importiere einen existierenden Schlüssel. Schlüssel bearbeiten Mit diesem Schlüssel verschlüsseln Identitäten beglaubigen + Von Schlüsselserver aktualisieren Teilen über... Teilen über NFC (Geräte Rückseite an Rückseite halten) + Auf Schlüsselserver hochladen Informationen Teilen Unterschlüssel Beglaubigungen + Wiederrufen + Ungültig + Passwort ändern Identität hinzufügen Unterschlüssel hinzufügen + neu + Schlüssel auf Schlüsselserver hochladen + Passwörter stimmen nicht überein + Vollständiger Name, z.B. Max Mustermann + Dieser Schlüssel wurde widerrufen! + Dieser Schlüssel ist nicht mehr gültig! Schlüssel Signieren und Verschlüsseln @@ -395,25 +412,38 @@ einfach überprüft positiv widerrufen + OK fehlgeschlagen! Fehler! Schlüssel nicht verfügbar Alte Schlüssel aus der Datenbank löschen Die Anwendung ist wegen Kodierungsfehler fehlgeschlagen - Die Anwendung is wegen Eingabe/Ausgabe-Fehler fehlgeschlagen + Die Anwendung ist wegen eines Eingabe/Ausgabe-Fehlers fehlgeschlagen Die Anwendung ist wegen internen Fehler fehlgeschlagen + Importiere öffentlichen Schlüsselbund %s% Schlüsselbund-daten werden kodiert Datenbank-Transaktionen werden vorbereitet + Hauptschlüssel %s wird verarbeitet Unterschlüssel %s wird bearbeitet + Benutzerkennung wurde widerrufen + Datenbankfehler! Geheime Unterschlüssel werden bearbeitet + Schlüsselbund enthält keine neuen Daten, es gibt nichts zu tun. + Geheimer Schlüsselbund erfolgreich importiert + Verarbeite Unterschlüssel %s + Ändere primäre Benutzerkenung auf %s + Widerrufe Benutzerkennung %s + Benutzerkennung darf nicht leer sein! + + Interner Fehler! Beglaubiger Zertifikatdetails Identität diff --git a/OpenKeychain/src/main/res/values-es/strings.xml b/OpenKeychain/src/main/res/values-es/strings.xml index 1770ec896..7948b7f1b 100644 --- a/OpenKeychain/src/main/res/values-es/strings.xml +++ b/OpenKeychain/src/main/res/values-es/strings.xml @@ -27,6 +27,7 @@ Detalles de la clave Ayuda Registro (log) + Crear clave Identidades Subclaves @@ -84,8 +85,8 @@ Algoritmo Armadura ASCII del fichero Ficheros: Armadura ASCII - Permitir a otros saber que está usando OpenKeychain - Escribe \'OpenKeychain v2.7\' en las firmas OpenPGP, el texto cifrado, y las claves exportadas + Permitir conocer a otros que usted está usando OpenKeychain + Escribe \'OpenKeychain v2.7\' en las firmas OpenPGP, texto cifrado, y claves exportadas Desde: Hacia: Ficheros: Borrar después del cifrado @@ -275,8 +276,8 @@ verificando la integridad... borrando \'%s\' de forma segura… - Identidad de Nombre/Correo/Clave... - Nombre de usuario de Nombre/Keybase.io... + Nombre/Correo electrónico/Identidad de clave... + Nombre/Correo electrónico/Prueba/Clave... 512 768 @@ -355,13 +356,15 @@ Cuentas No hay cuentas adjuntas a esta aplicación La aplicación solicita la creación de una nueva cuenta. Por favor, seleccione una de sus claves existentes o cree una nueva.\n¡Las aplicaciones están restringidas al uso de las claves que usted seleccione aquí! + La clave guardada para esta cuenta ha sido borrada. ¡Por favor seleccione una diferente!\n¡Las aplicaciones están restringidas al uso de las claves que seleccione aquí! La aplicación mostrada quiere cifrar, descrifrar y firmar mensajes en su nombre.\n¿Permitir acceso?\n\nADVERTENCIA: Si no sabe por qué apareció esta pantalla, ¡no permita el acceso! Puede revocar el acceso más tarde usando la pantalla de \'Aplicaciones\'. Permitir el acceso Denegar el acceso ¡Por favor, selecciona una clave! - No se encontraron claves públicas para estas identidades: - Existe más de una clave pública para estas identidades: + No se encontraron claves para estas identidades: + Existe más de una clave para estas identidades: ¡Por favor, revisa la lista de destinatarios! + ¡Por favor seleccione los receptores! ¡La comprobación de la firma ha fallado! ¿Has instalado esta app desde una fuente distinta? Si estás seguro de que esto no es un ataque, revoca el registro de esta app en OpenKeychain y regístrala de nuevo. Compartir con código QR @@ -388,6 +391,14 @@ Compartir Subclaves Certificados + Revocada + Esta identidad ha sido revocada por el propietario de la clave. En adelante no es válida. + Verificada + Esta identidad ha sido verificada + No verificada + Esta identidad no se ha verificado aún. No puede estar seguro de si la identidad realmente corresponde a una persona en concreto. + No válido + ¡Algo está mal con esta identidad! Cambiar frase contraseña Añadir identidad @@ -407,6 +418,7 @@ Revocar subclave nueva + ¡Por favor, seleccione al menos un indicador! Subir clave al servidor de claves Este campo es obligatorio @@ -442,6 +454,7 @@ Aplicando operación de inserción por lote. Se intentó importar un juego de claves (keyring) secreto como público. Esto es un fallo, por favor ¡consigne un informe! + Esta clave es una clave OpenPGP versión 3 y por tanto insegura. No ha sido importada. No se borró ninguna clave antigua (¿crear una nueva?) Clave antigua borrada de la base de datos La operación falló debido a un error de codificación @@ -557,7 +570,7 @@ Incorporándolas en el juego de claves públicas %s Incorporándolas en el juego de claves secretas (privadas) %s Error fatal codificando la firma - Se intentaron consolidar juegos de claves heterogéneos + ¡Se intentaron fusionar juegos de claves con diferentes huellas de validación de claves! Añadiendo nueva subclave %s Se encontraron %s nuevos certificados en el juego de claves No hay nuevos certificados @@ -566,6 +579,7 @@ ¡No se especificaron opciones de clave! ¡Los juegos de claves tienen que estar creados con al menos una identidad de usuario! ¡La clave maestra debe tener el indicador de certificado! + El periodo hasta la expiración no puede ser \"el mismo que antes\" al crear la clave. Esto es un error de programación, por favor ¡rellene un informe de fallo! ¡El tamaño de la clave debe ser mayor o igual de 512! ¡Error PGP interno! ¡Seleccionado algoritmo defectuoso! @@ -576,15 +590,23 @@ ¡La actual huella de validación de clave no coincide con la esperada! No hay identidad de clave. Esto es un error interno, por favor ¡consigne un informe de error! Error interno, ¡fallo en la comprobación de integridad! + ¡No se encontró certificado maestro sobre el que operar! (¿Todos revocados?) ¡Especificada identidad de usuario primaria defectuosa! + ¡Se especificó una mala identidad de usuario para revocación! ¡Las identidades de usuario revocadas no pueden ser primarias! + El periodo hasta la expiración no puede ser \"el mismo que antes\" al crear subclave. Esto es un error de programación, por favor ¡rellene un informe de fallo! + ¡Error fatal descrifrando la clave maestra! Probablemente esto se daba a un error de programación, por favor ¡rellene un informe de fallo! ¡Excepción interna de PGP! ¡Excepción con la firma! - Cambiando frase contraseña + Modificando certificaciones maestras + Cambiando frase contraseña para el juego de claves (keyring)... + Cambiando frase contraseña para la subclave %s + Fallo al establecer nueva frase contraseña, intentándolo de nuevo con una antigua frase contraseña vacía + ¡La frase contraseña para la subclave no pudo cambiarse! (¿Tiene la subclave una diferente de la de las otras claves?) Reemplazando certificado de la anterior identidad de usuario primaria Generando nuevo certificado para nueva identidad de usuario primaria Modificando subclave %s - ¡Intentó operar sobre una subclave ausente %s! + ¡Se intentó operar sobre una subclave desaparecida %s! Generando nueva subclave %2$s de %1$s bits Nueva identidad de subclave: %s ¡La fecha de expiración no puede ser del pasado! @@ -596,6 +618,20 @@ ¡La identidad de usuario no debe estar vacía! ¡Error desbloqueando juego de claves! Desbloqueando juego de claves + + Consolidando base de datos + Guardando juegos de claves secretas (privadas) + Guardando juegos de claves públicas + Limpiando base de datos + + Reimportando una clave secreta (privada) + Reimportando %d claves secretas (privadas) + + + Reimportando una clave pública + Reimportando %d claves públicas + + Base de datos consolidada con éxito Haga clic para limpiar las frases contraseña almacenadas en caché OpenKeychain ha almacenado en caché %d frases contraseña @@ -609,6 +645,7 @@ Identidad <desconocido> No hay certificados para esta clave + Sólo los certificados creados con sus claves y auto-certificados son mostrados aquí. Identidades a certificar Razón de la revocación Estado de la verificación diff --git a/OpenKeychain/src/main/res/values-et/strings.xml b/OpenKeychain/src/main/res/values-et/strings.xml index fdd7f026a..6ea0d1236 100644 --- a/OpenKeychain/src/main/res/values-et/strings.xml +++ b/OpenKeychain/src/main/res/values-et/strings.xml @@ -97,6 +97,7 @@ + diff --git a/OpenKeychain/src/main/res/values-fr/strings.xml b/OpenKeychain/src/main/res/values-fr/strings.xml index 3b356fd18..74fa562ff 100644 --- a/OpenKeychain/src/main/res/values-fr/strings.xml +++ b/OpenKeychain/src/main/res/values-fr/strings.xml @@ -27,6 +27,7 @@ Détails sur la clef Aide Journal + Créer une clef identités Sous-clefs @@ -84,8 +85,8 @@ Algorithme Fichier ASCII Armor Fichier : ASCII Armor - Informez les autres de votre utilisation d\'OpenKeychain - Ajoute « OpenKeychain v2.7 » aux signatures OpenPGP, aux cryptogrammes, et aux clefs exportées + Faire savoir aux autres que vous utilisez OpenKeychain + Ajoute « OpenKeychain v2.7 » aux signatures OpenPGP, aux cryptogrammes et aux clefs exportées De : À : Fichier : supprimer après chiffrement @@ -98,7 +99,7 @@ Compression des messages Compression des fichiers Serveurs de clefs - ID de le clef + ID de clef Création Expiration Utilisation @@ -247,8 +248,8 @@ génération d\'une nouvelle clef ElGamal... modification du trousseau... déverrouillage du trousseau... - ajout des IDs d\'utilisateur... - révocation des IDs d\'utilisateur... + ajout des ID d\'utilisateur... + révocation des ID d\'utilisateur... changement de l\'ID d\'utilisateur principale... modification des sous-clefs... révocation des sous-clefs... @@ -275,8 +276,8 @@ vérification de l\'intégrité... suppression sûre de « %s »... - Nom/courriel/ ID clef... - Nom/nom d\'utilisateur keybase.io... + Nom/courriel/ID de clef... + Nom/courriel/preuve/clef... 512 768 @@ -355,13 +356,15 @@ Comptes Aucun compte n\'est attaché à cette appli. L\'appli demande la création d\'un nouveau compte. Veuillez choisir une de vos clefs existantes ou en créer une nouvelle.\nLes applis ne peuvent utiliser que les clefs que vous choisissez ici ! + La clef enregistrée pour ce compte a été supprimée. Veuillez en choisir une autre !\nLes applis sont restreintes à l\'utilisation de clefs choisies ici. L\'application affichée veut chiffrer/déchiffrer des messages et les signer en votre nom.\nPermettre l\'accès ?\n\nAVERTISSEMENT : si vous ne savez pas pourquoi cet écran est apparu, refusez l\'accès ! Vous pourrez révoquer l\'accès plus tard en utilisant l\'écran « Applis ». Permettre l\'accès Enlever l\'accès Veuillez choisir une clef ! - Aucune clef publique n\'a été trouvée pour ces identités : - Plus d\'une clef publique existe pour ces identités : + Aucune clef n\'a été trouvée pour ces identités : + Plus d\'une clef existe pour ces identités : Veuillez revoir la liste des destinataires ! + Veuillez choisir les destinataires ! La vérification de la signature a échoué ! Avez-vous installé cette appli à partir d\'une source différente ? Si vous êtes sûr que ce n\'est pas une attaque, révoquez l\'enregistrement de cette appli dans OpenKeychain et enregistrez-la à nouveau. Partager par un code QR @@ -388,6 +391,14 @@ Partager Sous-clefs Certificats + Révoquée + Cette identité a été révoquée par le propriétaire de la clef. Elle n\'est plus valide. + Vérifiée + Cette identité a été vérifiée. + Non vérifiée + Cette identité n\'a pas encore été vérifiée. Vous ne pouvez pas être certain si l\'identité corresponds vraiment à une personne spécifique. + Invalide + Quelque chose ne va pas avec cette identité ! Changer la phrase de passe Ajouter une identité @@ -407,6 +418,7 @@ Révoquer la sous-clef nouvelle + Veuillez sélectionner au moins un drapeau ! Téléverser la clef vers le serveur de clefs Ce champ est exigé @@ -442,6 +454,7 @@ Application de l\'opération d\'insertion par lot. Tentative d\'importer le trousseau secret comme public. Ceci est un bogue, veuillez remplir un rapport ! + Cette clef est une clef d\'OpenPGP version 3 et n\'est, par conséquent, pas sécuritaire. Elle n\'a pas été importée. Aucune ancienne clef de supprimée (création d\'une nouvelle ?) L\'ancienne clef a été supprimée de la base de données Échec de l\'opération causé par une erreur d\'encodage @@ -557,7 +570,7 @@ Fusion vers le trousseau public %s Fusion vers le trousseau secret %s Erreur fatale lors de l\'encodage de la signature - Il a été tenté de consolider les trousseaux hétérogènes + Il a été tenté de fusionner des trousseaux avec des empreintes différentes ! Ajout de la nouvelle sous-clef %s %s nouveaux certificats trouvés dans le trousseau Aucun nouveau certificat @@ -566,6 +579,7 @@ Aucune option de clef maîtresse n\'a été spécifiée ! Les trousseaux doivent être créés avec au moins un ID d\'utilisateur ! La clef maîtresse doit avoir le drapeau « certifié » ! + L\'expiration ne peut pas être « pareille qu\'avant » lors de la création de clefs. Ceci est une erreur de programmation, veuillez remplir un rapport de bogue ! La taille de la clef doit être supérieure ou égale à 512 ! Erreur interne PGP ! Mauvais choix d’algorithme ! @@ -576,17 +590,25 @@ L\'empreinte de clef effective ne correspond pas à celle attendue ! Aucune ID de clef. Ceci est une erreur interne, veuillez remplir un rapport de bogue ! Erreur interne, le contrôle d\'intégrité a échoué ! - Mauvais ID principal spécifié ! - Les IDs d\'utilisateurs révoqués ne peuvent pas être principaux ! + Aucun certificat maître sur lequel se basé n\'a été trouvé ! (Tous révoqués ?) + Mauvais ID d\'utilisateur principal spécifié ! + Mauvais ID d\'utilisateur spécifié pour la révocation ! + Les ID d\'utilisateurs révoqués ne peuvent pas être principaux ! + L\'expiration ne peut pas être « pareille qu\'avant » lors de la création de sous-clefs. Ceci est une erreur de programmation, veuillez remplir un rapport de bogue ! + Erreur fatale lors du déchiffrement de la clef maîtresse ! Ceci est probablement une erreur de programmation, veuillez remplir un rapport de bogue ! Exception interne PGP ! Exception de signature ! - Changement de la phrase de passe + Modification des certifications maîtresses + Changement de la phrase de passe pour le trousseau... + Changement de la phrase de passe pour la sous-clef %s + Échec lors de la définition de la nouvelle phrase de passe, nouvel essai avec une ancienne phrase de passe vide + La phrase de passe de la sous-clef n\'a pas pu être changée ! (Est-elle différente des autres clefs ?) Remplacement du certificat de l\'ID d\'utilisateur principal précédent Génération d\'un nouveau certificat pour le nouvel ID d\'utilisateur principal Modification de la sous-clef %s Une action a été tentée sur la sous-clef manquante %s ! Génération d\'une nouvelle sous-clef %2$s de %1$s bit - ID de la nouvelle sous-clef : %s + Nouvelle ID de sous-clef : %s La date d\'expiration ne peut pas être dans le passé ! Révocation de la sous-clef %s Trousseau modifié avec succès @@ -596,6 +618,20 @@ L\'ID d\'utilisateur ne peut pas être vide ! Erreur lors du déverrouillage du trousseau ! Déverrouillage du trousseau + + Consolidation de la base de données + Enregistrement des trousseaux secrets + Enregistrement des trousseaux publiques + Nettoyage de la base de données + + Réimportation d\'une clef secrète + Réimportation de %d clefs secrètes + + + Réimportation d\'une clef publique + Réimportation de %d clefs publiques + + Base de données consolidée avec succès Cliquer ici pour effacer les phrases de passe mises en cache OpenKeychain a mis en cache %d phrases de passe @@ -609,6 +645,7 @@ identité <inconnu> Aucun certificat pour cette clef + Seuls les certificats créés avec vos clefs et les auto-certificats sont affichés ici. Identités à certifier Raison de la révocation État de vérification diff --git a/OpenKeychain/src/main/res/values-it/strings.xml b/OpenKeychain/src/main/res/values-it/strings.xml index 33bb4ce9d..7a5289313 100644 --- a/OpenKeychain/src/main/res/values-it/strings.xml +++ b/OpenKeychain/src/main/res/values-it/strings.xml @@ -1,9 +1,12 @@ + Seleziona chiavi + Seleziona la Tua Chiave Codifica Decodifica Frase di accesso + Aggiungi Sottochiave Modifica Chiave Preferenze Apps @@ -12,6 +15,7 @@ Condivi impronta con... Condividi chiave con... Condividi file con... + Condividi messaggio con... Codifica File Decodifica File Importa Chiavi @@ -23,6 +27,7 @@ Dettagli Chiave Aiuto Registro + Crea Chiave Identità Sottochiavi @@ -40,20 +45,27 @@ Decodifica, verifica e salva su file Decodifica e verifica messaggio Codifica e salva file + Codifica e condividi file Salva Annulla Elimina + Nessuna Scadenza OK Carica sul Server delle Chiavi Prossimo Precedente Chiave di ricerca + Codifica e condividi messaggio Mostra chiave di certificazione + Crea chiave + Aggiungi file(s) Impostazioni Aiuto Esporta su un file Cancella chiave + Crea mia chiave + Importa chiavi esistenti Cerca Impostazioni Beam Annulla @@ -65,15 +77,24 @@ Messaggio File + File(s) + File: Nessuna Frase di Accesso Frase di Accesso Ripeti Frase di Accesso Algortimo + Documenti con Armatura ASCII + Documenti: Armatura ASCII Fai sapere agli altri che utilizzi OpenKeychain Scrive \'OpenKeychain v2.7\' nelle firme OpenPGP, testi cifrati e chiavi esportate + Da: + A: + Documenti: Cancella Dopo Codifica Cancella Dopo Decodifica Algoritmo di Codifica Algoritmo di Hash + Con Chiave Pubblica + Con Frase di Accesso Cache Frase di Accesso Compressione Messaggio Compressione File @@ -155,6 +176,7 @@ Vuoi veramente eliminare tutte le chiavi pubbliche selezionate?\nNon potrai annullare! Vuoi veramente eliminare la chiave PRIVATA \'%s\'?\nNon potrai annullare! Vuoi veramente eliminare la chiave pubblica \'%s\'?\nNon potrai annullare! + Esporta anche chiave segreta 1 chiave esportata correttamente. %d chiavi esportate correttamente. Nessuna chiave esportata. @@ -193,6 +215,11 @@ Devi avere Android 4.1 per usare Android NFC Beam! NFC non disponibile nel tuo dispositivo! Nessuna chiave trovata! + Query di ricerca troppo. Per favore ridefinisci la tua ricerca! + C\'è stato un errore durante la ricerca delle chiavi. + La query di ricerca della chiave ha generato troppi risultati. Per favore ridefinisci la tua ricerca! + In entrambi i casi sono state trovate troppe o nessuna chiave. Si prega di migliorare la vostra ricerca! + Nessuna chiave valida trovata nei File/Appunti! Si è verificato un errore generico, si prega di creare una nuova segnalazione di errore per OpenKeychain. parte del file caricato e\' un oggetto OpenPGP valido, ma non una chave OpenPGP @@ -213,8 +240,21 @@ salvataggio... importazione... esportazione... + caricamento... fabbricazione chiave... fabbricazione portachiavi principale... + generazione di una nuova chiave RSA... + generazione di una nuova chiave DSA... + generazione di una nuova chiave ElGamal... + modifica portachiavi... + Sblocco portachiavi... + Aggiunta ID utente... + Revoca ID utente... + Cambio ID utente primario... + Modifica sottochiave... + Revoca sottochiave... + Aggiunta sottochiave... + Cambio frase di accesso... esportazione chiave... esportazione chiavi... @@ -229,6 +269,7 @@ elaborazione firma... verifica firma... firma... + certificazione... lettura dati... ricerca chiave... decompressione dati... @@ -236,7 +277,7 @@ eliminazione sicura di \'%s\'... Nome/Email/ID Chiave... - Nome/Keybase.io nome utente... + Nome/Email/Certificato/Chiave... 512 768 @@ -248,6 +289,7 @@ 8192 Lunghezza chiave peronalizzata Digita lunghezza chiave personalizzata (in bit): + La lunghezza della chiave RSA deve essere maggiore di 1024 e al massimo 16384. Inoltre, deve essere multipla di 8. La lunghezza della chiave DSA deve essere almeno 512 e al massimo 1024. Inoltre, deve essere multipla di 64. veloce @@ -274,6 +316,10 @@ Chiave importata correttamente. %1$d chiavi importate correttamente. + + e chiave%2$s aggiornata. + e aggiornate %1$d chiavi%2$s. + Chiave%2$s importata correttamente. %1$d chiavi%2$s importate correttamente. @@ -309,12 +355,12 @@ SHA-256 della Firma del Pacchetto Account Nessun account collegato a questa applicazione + L\'applicazione richiede la creazione di un nuovo account. Si prega di selezionare una chiave esistente o crearne una nuova.\nLe applicazioni sono limitate all\'utilizzo delle chiavi selezionate qui! + La chiave salvata per questo account è stata cancellata. Perfavore selezionane una diversa!\nLe applicazioni sono limitate all\'utilizzo delle chiavi qui selezionate! Le app visualizzate hanno richiesto l\'accesso a OpenKeychain.\nPermetti accesso?\n\nATTENZIONE: Se non sai perche\' questo schermata e\' apparsa, nega l\'accesso! Puoi revocare l\'accesso dopo, usando la schermata \'App Registrate\'. Permetti accesso Nega accesso Per favore selezionare una chiave! - Nessuna chiave pubblica trovata per queste identità: - Esistono piu\' di una chiave pubblica per queste identità: Per favore ricontrolla la lista destinatari! Controllo della firma fallito! Hai installato questa app da una fonte diversa? Se sei sicuro che non sia un attacco, revoca la registrazione di questa app in OpenKeychain e dopo registra di nuovo l\'app. @@ -329,16 +375,27 @@ Puoi iniziare da o creazione della tua chiave + importazione di chiave esistente. Modifica chiave Codifica con questa chiave Certifica identità + Aggiorna dal server delle chiavi Condividi con... Condividi con NFC tenendo i dispositivi a stretto contatto + Carica nel server delle chiavi Info Principale Condividi Sottochiavi Certificati + Revocato + Questa identità è stata revocata dal suo proprietario. Non è più valida. + Verificato + Questa identità è stata verificata. + Non verificato + Questa identità non è stata ancora verificata. Non puoi esser sicuro che l\'identità corrisponda veramente ad una specifica persona. + Non valido + C\'è qualcosa che non va con questa identità! Cambia Frase Di Accesso Aggiungi Identità @@ -348,14 +405,24 @@ Cambia in Identita\' Primaria Revoca identita\' + + Ripristina revoca + + Questa identità è stata revocata. Ciò non può essere annullato. Seleziona un azione! Cambia Scadenza Revoca Sottochiave + nuovo Carica chiave nel server delle chiavi Questo campo è necessario + Le frasi di accesso non coincidono. + Hai inserito la seguente identità: + La creazione di una chiave richiede un po\' di tempo, prendi un caffè nel frattempo...\n(3 sottochiavi, RSA, 4096 bit) + Inserisci Nome Completo, Email e scegli una Frase di Accesso. + Nome completo, es: Mario Rossi Questa chiave è stata revocata! Questa chiave è scaduta @@ -368,6 +435,7 @@ Chiudi drawer di navigazione Le Mie Chiavi + Il messaggio inserito in questo campo verrà firmato con la chiave selezionata in \'Da\' e crittografato per tutti i destinatari selezionati in \'A\'. Inserisci il testo cifrato qui per la decodifica e/o verifica... predefiniti @@ -382,6 +450,7 @@ Applicazione inserimento operazioni in batch. Ho cercato di importare portachiavi privato come pubblico. Questo è un bug, per cortesia inviateci un rapporto! + Questa chiave è una chiave OpenPGP versione 3 e quindi non sicura. Non è stata importata. Nessuna vecchia chiave cancellata (stai creando una nuova?) Cancellate vecchie chiavi dal database Operazione fallita a causa di un errore di codifica @@ -497,7 +566,7 @@ Fusione nel portachiavi pubblico %s Fusione nel portachiavi privato %s Errore fatale nella codifica della firma - Tentativo di consolidare portachiavi eterogenei + Tentativo di unire portachiavi con impronte digitali diverse! Aggiunta nuova sottochiave %s Trovati %s nuovi certificati nel portachiavi Nessun nuovo certificato @@ -520,14 +589,11 @@ ID utente revocato non può essere primario! Eccezione interna di PGP! Eccezione di firma! - Cambio frase di accesso Sostituzione certificato del ID utente primario precedente Generazione di un nuovo certificato per il nuovo ID utente primario Modifica sottochiave %s - Tentativo di operare su sottochiave mancante %s! Generazione nuovi %1$s bit %2$s sottochiave Nuovo ID sottochiave: %s - La data di scadenza non può essere passata! Revoca sottochiave %s Portachiavi modificato con successo Aggiunta id utente %s @@ -536,6 +602,7 @@ ID Utente non può essere vuoto! Errore di apertura portachiavi! Apertura portachiavi + Clicca per rimuovere la frase di accesso nella cache OpenKeychain ha memorizzato nella cache %d frasi di accesso @@ -556,6 +623,7 @@ Chiave non trovata! Errore di elaborazione chiave! ripulito + Le vostre chiavi possono essere eliminate solo singolarmente! Visualizza Dettagli Certificati sconosciuto non può firmare @@ -564,5 +632,7 @@ Mostra chiave (%s) Riappropriati della tua riservatezza con OpenKeychain! + Crea mia chiave + Importa Chiave esistente Salta Installazione diff --git a/OpenKeychain/src/main/res/values-ja/strings.xml b/OpenKeychain/src/main/res/values-ja/strings.xml index deb7715e1..6a02916ad 100644 --- a/OpenKeychain/src/main/res/values-ja/strings.xml +++ b/OpenKeychain/src/main/res/values-ja/strings.xml @@ -27,6 +27,7 @@ 鍵の概要 ヘルプ ログ + 鍵の生成 ユーザID 副鍵 @@ -271,7 +272,7 @@ \'%s\' を完全に削除中… 名前/メール/鍵ID... - 名前/Keybase.io名... + 名前/メール/証明/鍵... 512 768 @@ -346,13 +347,15 @@ アカウント このアプリに接続されてるアカウントはありません。 このアプリは新しいアカウントの生成を要求しています。すでにある鍵1つを選択するか、新たに生成してください。\nここであなたが選択する鍵の使い道についてアプリケーションには制約があります! + このアカウントの削除された鍵を保存しました。異るものを選択してください!\nここであなたが選択する鍵の使い道についてはアプリには制約があります! 表示されているアプリはメッセージの暗号/復号化とあなたの名前での署名付けを要求しています。\nアクセスを許可しますか?\n\n注意: もしなぜスクリーンに表れたかわからないなら、アクセスを許可しないでください! あなたは後で\'アプリ\'スクリーンを使い、アクセスを破棄するこもできます。 許可されたアクセス 許可されないアクセス 鍵を選択してください! - このユーザIDについて公開鍵が見付かりません: - このユーザIDについて1つ以上の公開鍵が存在します: + このユーザIDについて鍵が見付かりません: + このユーザIDについて1つ以上の鍵が存在します: 受信者リストを確認してください! + 受信者を選択してください! 署名チェックが失敗! 違うところからこのアプリをインストールしましたか? もし攻撃されてでなくそうであるなら、OpenKeychainにあるこのアプリの登録を破棄し、再度アプリを登録してください。 QRコードで共有 @@ -378,6 +381,14 @@ 共有 副鍵 証明 + 破棄 + このIDは鍵の所有者により破棄されています。もう適正ではありません。 + 検証 + このIDは検証されています。 + 未検証 + このIDはまだ検証されていません。IDが本当に特定の人に対応している場合を、あなたは確認することができません。 + 不適正 + このIDではなにかしら問題があります! パスフレーズの変更 ユーザIDの追加 @@ -397,6 +408,7 @@ 副鍵を破棄 新規 + 最低1つフラグを選択してください! 鍵サーバへアップロード このフィールドは必須です @@ -432,6 +444,7 @@ 連続挿入処理を適用する。 秘密鍵の鍵輪を公開鍵としてインポートを試行しました。これはバグで、ファイルをレポートしてください! + この鍵はOpenPGP v3形式の鍵で安全ではありません。そのためインポートできません。 削除された古い鍵はありません (新しく作りますか?) データベースから古い鍵を削除しました エンコードエラーにより操作が失敗しました @@ -543,7 +556,7 @@ 公開鍵の鍵輪 %s にマージ中 秘密鍵の鍵輪 %s にマージ中 署名のエンコードでの致命的なエラー - 種類の異なる鍵輪を統合しようとした + 指紋が異なる鍵輪をマージしようとしています! 新しい副鍵 %s を追加中 鍵輪に新しい検証を %s 発見 新しい証明がない @@ -552,6 +565,7 @@ 主鍵オプション特有ではありません! 鍵輪は最低でも1つのユーザIDの生成が必要です! 主鍵は検証フラグが必須です! + 鍵の生成時に期限を\"過去\"とすることはできません。これはプログラムエラーで、バグレポートとしてファイルを送ってください! 鍵サイズは512かそれ以上が必須です! PGP内部エラー! 悪いアルゴリズムを選択しています! @@ -562,15 +576,23 @@ 現実の鍵指紋が想定の1つと合致しませんでした! 鍵IDがない。 これは内部エラーで、バグレポートの提出をお願いします! 内部エラー、完全性チェックが失敗! + マスター認証が操作で見付かりませんでした(すべて破棄しましたか?) 問題のある主ユーザIDが指定された! + 破棄において問題のあるユーザIDが指定された! 主ユーザIDの破棄はできません! + 副鍵の生成時に期限を\"過去\"とすることはできません。これはプログラムエラーで、バグレポートとしてファイルを送ってください! + 主鍵の復号で致命的な失敗! これはプログラミングのエラーの場合がありますので、バグレポートの提出をお願いします! PGP内部例外! 署名例外! - パスフレーズの変更中 + マスター認証を変更 + 鍵輪のパスフレーズの変更中... + 副鍵 %s のパスフレーズの変更中 + 新しいパスフレーズの設定に失敗しました、空の古いパスフレーズで再度試してください + 副鍵のパスフレーズは変更されていません! (他の鍵とは異なるになっていませんか?) 以前の主ユーザIDで証明を入れ替え中 新しい主ユーザIDで新しい証明を生成中 副鍵 %s を変更中 - 遺失した副鍵 %s の操作をしようとした! + 見付からない副鍵 %s の操作をしようとした! 新しい %1$s ビットの %2$s 副鍵の生成中 新しい副鍵 ID: %s 期限切れ日を過去にはできません! @@ -582,6 +604,18 @@ ユーザIDは空にすることはできません! 鍵輪のロック解除エラー! 鍵輪のロック解除中 + + データベースの統合中 + 秘密鍵の鍵輪を保存中 + 公開鍵の鍵輪を保存中 + データベースの消去中 + + %d の秘密鍵を再インポート中 + + + %d の公開鍵を再インポート中 + + データベースの統合が成功しました クリックしてパスフレーズのキャッシュをクリア OpenKeychainは %d のパスフレーズをキャッシュしています @@ -595,6 +629,7 @@ ユーザID <不明> この鍵に証明がない + あなたの鍵でだけ生成された証明と自己証明がここに表示されます ユーザIDを検証 破棄の理由 検証ステータス diff --git a/OpenKeychain/src/main/res/values-nl/strings.xml b/OpenKeychain/src/main/res/values-nl/strings.xml index a49a51671..7f93d0d51 100644 --- a/OpenKeychain/src/main/res/values-nl/strings.xml +++ b/OpenKeychain/src/main/res/values-nl/strings.xml @@ -280,8 +280,6 @@ Toegang toestaan Toegang weigeren Selecteert u a.u.b. een sleutel - Geen publieke sleutels zijn gevonden voor deze identiteiten: - Meer dan een publieke sleutel bestaat voor deze identiteiten: Bekijkt u a.u.b. de ontvangers Handtekening check mislukt! Hebt u deze app van een andere bron geïnstalleerd? Als u zeker weet dat dit geen aanval is, haal dan de registratie van deze app in OpenKeychain weg en registreer de app opnieuw. @@ -333,6 +331,7 @@ + Certificeer diff --git a/OpenKeychain/src/main/res/values-pl/strings.xml b/OpenKeychain/src/main/res/values-pl/strings.xml index 7b12653c6..f96753662 100644 --- a/OpenKeychain/src/main/res/values-pl/strings.xml +++ b/OpenKeychain/src/main/res/values-pl/strings.xml @@ -310,6 +310,7 @@ + Szczegóły certyfikatu diff --git a/OpenKeychain/src/main/res/values-pt/strings.xml b/OpenKeychain/src/main/res/values-pt/strings.xml new file mode 100644 index 000000000..9a8c94e31 --- /dev/null +++ b/OpenKeychain/src/main/res/values-pt/strings.xml @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/OpenKeychain/src/main/res/values-ru/strings.xml b/OpenKeychain/src/main/res/values-ru/strings.xml index 1b2aa7dc6..dba0aed12 100644 --- a/OpenKeychain/src/main/res/values-ru/strings.xml +++ b/OpenKeychain/src/main/res/values-ru/strings.xml @@ -237,7 +237,6 @@ проверка целостности... безопасное удаление \'%s\'... - Имя/Email/ID ключа… 512 768 @@ -303,8 +302,6 @@ Разрешить доступ Запретить доступ Пожалуйста, выберите ключ! - Для этих идентификаторов не найдены публичные ключи: - Для этих идентификаторов найдено более одного публичного ключа: Пожалуйста, проверьте получателей! Проверка подписи пакета не удалась! Если вы установили программу из другого источника, отзовите для неё доступ к этой программе или обновите право доступа. @@ -382,14 +379,13 @@ Аннулированные идентификаторы не могут быть основными! Внутренняя ошибка PGP! Ошибка подписи! - Изменение пароля - Срок годности не может быть в прошлом! Связка успешно изменена Добавление id %s Изменение основного uid на %s Аннулирование id %s Ошибка разблокирования связки! Разблокирование связки + Кем подписан diff --git a/OpenKeychain/src/main/res/values-sl/strings.xml b/OpenKeychain/src/main/res/values-sl/strings.xml index e98e207b5..a24c1ddf1 100644 --- a/OpenKeychain/src/main/res/values-sl/strings.xml +++ b/OpenKeychain/src/main/res/values-sl/strings.xml @@ -242,8 +242,6 @@ preverjam neokrnjenost... varno brišem \'%s\'… - Ime/e-pošta/ID ključa - Ime/Keybase.io uporabniško ime... 512 768 @@ -302,8 +300,6 @@ Dovoli dostop Zavrni dostop Izberite ključ! - Za te identitete ni bil najden noben javni ključ: - Za te identitete obstaja več ključev: Preverite seznam prejemnikov! Preverjanje podpisa ni uspelo! Ste namestili to aplikacijo iz drugega vira? Če ste prepričani, da to ni napad, prekličite registracijo te aplikacije v OpenKeychain in jo izvedite znova. @@ -405,6 +401,7 @@ + Overovitelj diff --git a/OpenKeychain/src/main/res/values-tr/strings.xml b/OpenKeychain/src/main/res/values-tr/strings.xml index f8c26f140..f8ef23467 100644 --- a/OpenKeychain/src/main/res/values-tr/strings.xml +++ b/OpenKeychain/src/main/res/values-tr/strings.xml @@ -162,6 +162,7 @@ + imzalanamadı diff --git a/OpenKeychain/src/main/res/values-uk/strings.xml b/OpenKeychain/src/main/res/values-uk/strings.xml index 401b8ae83..15bb9ad3e 100644 --- a/OpenKeychain/src/main/res/values-uk/strings.xml +++ b/OpenKeychain/src/main/res/values-uk/strings.xml @@ -1,9 +1,12 @@ + Вибрати ключі + Виберіть ваш ключ Зашифрувати Розшифрувати Парольна фраза + Додати підключ Редагувати ключ Налаштування Програми @@ -12,6 +15,7 @@ Поділитися відбитком із… Поділитися ключем з… Поширити файл з… + Поширити повідомлення із… Зашифрувати до файлу Розшифрувати до файлу Імпортувати ключі @@ -23,6 +27,7 @@ Подробиці про ключ Довідка Журнал + Створити ключ Сутності Підключі @@ -40,20 +45,27 @@ Розшифрувати, перевірити та зберегти файл Розшифрувати і перевірити повідомлення Шифрувати і зберегти файл + Зашифрувати та поширити файл Зберегти Скасувати Вилучити + Необмежено Гаразд Завантажити на сервер ключів Далі Назад Шукати ключ + Зашифрувати і поширити повідомлення Переглянути ключ сертифікації + Створити ключ + Додати файл(и) Параметри Довідка Експорт до файлу Вилучити ключ + Створити мій ключ + Імпортувати наявний ключ Пошук Налаштування променя Скасувати @@ -65,12 +77,24 @@ Повідомлення Файл + Файл(и) + Файл: Без парольної фрази Парольна фраза + Повторити пароль Алгоритм + Файл ASCII Armor + Файли: ASCII Armor + Нехай інші дізнаються, що ви користуєтеся OpenKeychain + Напишіть \'OpenKeychain v2.7\' для підписів, зашифрованого тексту та експортованих ключів OpenPGP + Від: + Кому: + Файли: вилучити після шифрування Вилучити після розшифрування Алгоритм шифрування Хеш алгоритм + З публічним ключем + З паролем Кеш парольної фрази Стиснення повідомлення Стиснення файлу @@ -154,6 +178,7 @@ Ви справді хочете вилучити усі вибрані відкриті ключі?\nВи не зможете це відмінити! Ви справді хочете вилучити секретний ключ \'%s\'?\nВи не зможете це відмінити! Ви справді хочете вилучити відкритий ключ \'%s\'?\nВи не зможете це відмінити! + Також експортувати секретні ключі Успішно експортовано 1 ключ. Успішно експортовано %d ключів. Жодного ключа не експортовано. @@ -193,6 +218,11 @@ Вам потрібний Android 4.1 для використання функції Androids NFC промінь! NFC недоступний на вашому пристрої! Ключ не знайдено! + Надто короткий пошуковий запит. Поліпшіть його! + Трапилася помилка при пошуці за ключами. + Запит пошуку ключа видав надто багато варіантів. Уточніть пошуковий запит! + Нема жодного ключа або знайдено надто багато! Поліпшіть свій запит! + Жодного дійсного ключа не знайдено у File/Clipboard! Трапилася загальна помилка, будь ласка, створіть новий звіт про помилку для OpenKeychain. частина завантаженого файлу є вірним об\'єктом OpenPGP, але не ключем OpenPGP @@ -214,8 +244,21 @@ збереження… імпортується… експортується… + відвантаження… будується ключ… побудова основного кільця… + генерується новий ключ RSA… + генерується новий ключ DSA… + генерується новий ключ ElGamal… + змінюється в\'язка ключів… + розблоковується в\'язка… + розблоковуються ID користувачів… + відхилення ІД користувачів… + змінюється ІД первинного користувача… + змінюються підключі… + відхилення підключів… + додаються підключі… + змінюється пароль… експортується ключ… експортуються ключі… @@ -231,6 +274,7 @@ обробляється підпис… перевірка підпису… підписання… + сертифікується… читання даних… пошук ключа… розпакування даних… @@ -238,6 +282,7 @@ вилучення безпечно \'%s\'… Назва/Ел. пошта/ІД ключа… + Назва/Ел.пошта/Доказ/Ключ… 512 768 @@ -249,6 +294,7 @@ 8192 Особливий розмір ключа Введіть інший розмір ключа (у бітах): + Довжина ключа RSA має бути більша за 1024 та менша за 16384. Також він має мати кратність 8. Довжина ключа DSA має бути більша за 512 та менша за 1024. Також він має мати кратність 64. швидке @@ -276,11 +322,22 @@ Успішно імпортовано %1$d ключі. Успішно імпортовано %1$d ключів. + + та оновлено ключ%2$s. + та оновлено %1$d ключі%2$s. + та оновлено %1$d ключів%2$s. + Успішно імпортований ключ%2$s. Успішно імпортовано %1$d ключі%2$s. Успішно імпортовано %1$d ключів%2$s. + + Успішно оновлено ключ%2$s. + Успішно оновлено %1$d ключі%2$s. + Успішно оновлено %1$d ключів%2$s. + + Переглянути журнал Нема що імпортувати. Помилка імпорту ключів! , із застереженнями @@ -290,6 +347,7 @@ Зашифрувати з OpenKeychain Розшифрувати з OpenKeychain + Незареєстровані програми!\n\nСписок підтримуваних сторонніх програм можна знайти у Довідці! Показати додаткову інформацію Приховати додаткову інформацію Показати додаткові налаштування @@ -305,12 +363,17 @@ Назва пакунку SHA-256 підписку пакунку Облікові записи + Немає облікового запису приєднаного до цієї програми. + Ця програма вимагає створення нового профілю. Будь ласка, виберіть наявний приватний ключ або створіть інший.\nПрограми обмежені використання ключів, які ви тут оберете! + Збережений для цього профілю ключ вже вилучений. Будь ласка, виберіть інший!\nПрограми обмежені використання ключів, які ви тут оберете! + Показана програма запитує доступ до OpenPGP Keychain.\nДозволити доступ?\n\nУВАГА: якщо ви не знаєте, чому цей екран появився, не дозволяйте доступ! Ви можете відкликати доступ пізніше, використовуючи екран \'Зареєстровані програми\'. Дозволити доступ Не дозволити доступ Будь ласка, виберіть ключ! - Немає публічних ключів для цих сутностей: - Наявно більше одного публічного ключа для цих сутностей: + Не знайдено жодного ключа для цих сутностей: + Наявно більше одного ключа для цих сутностей: Будь ласка, перевірте список одержувачів! + Будь ласка, виберіть одержувачів! Перевірка підпису пакету не вдалася! Може ви встановили програму з іншого джерела? Якщо ви впевнені, що це не атака, то відкличте реєстрацію програми у OpenKeychain та знову зареєструйте її. Відправити як штрих-код @@ -325,19 +388,57 @@ Ви можете розпочати за чи створюється ваш власний ключ + імпортується наявний ключ. Редагувати ключ Шифрувати з цим ключем Сертифікувати сутності + Оновити із сервера ключів Поділитися із… Поширити через NFC, тримаючи пристрої пліч-о-пліч + Відвантажити на сервер ключів Основна інформація Поділитися Підключі Сертифікати + Відхилено + Ця сутність вже відкликана власником ключа. Вона більше не дійсна. + Перевірено + Не перевірено + Не перевірено + Ця сутність ще не перевірена. Ви не можете переконатися, чи сутність справді відповідає вказаній особі. + Недійсна + Щось неправильне у цій сутності! + Змінити пароль + Додати сутність + Додати підключ + Виберіть дію! + + Змінити на первинну сутність + Відкликати сутність + + + Обернути відкликання + + Ця сутність вже відкликана. Це не можна скасувати. + Виберіть дію! + + Змінити термін дії + Відкликати підключ + + новий + Відвантажити ключ на сервер ключів + Це поле - обов\'язкове + Паролі фрази не збігаються + Ви ввели наступну сутність: + Створення ключа може зайняти деякий час, випийте чашечку кави за цей час ...\n(3 підключі, RSA, 4096 біт) + Введіть ваше повне ім\'я, електронну адреса та оберіть парольну фразу. + Повне ім\'я, наприклад Степан Бандера + Цей ключ вже відкликано! + Термін дії цього ключа вже минув! Ключі Підписати і зашифрувати @@ -347,6 +448,7 @@ Закрити панель навігації Мої ключі + Введене тут повідомлення буде підписане, використовуючи ключ, вибраний у Звідки та зашифрований для всіх одержувачів, вказаних у Кому. Уведіть зашифрований текст тут для його розшифрування та/або перевірки… типово @@ -354,48 +456,153 @@ випадковий додатний відкликано + Гаразд Невдача! Помилка! Недоступний ключ Застосовується пакетна операція вставки. + Спробували імпортувати секретну в\'язку як публічну. Це вада. Будь ласка, відправте звіт! + Цей ключ зроблений OpenPGP версії 3, а тому небезпечний. Його не можна імпортувати. Нема вилученого старого ключа (створюється новий?) Вилучений старий ключ з бази даних Операція не вдалася через помилку кодування Операція не вдалася через помилку вводу/виводу + Операція не вдалася через помилку бази даних Операція не вдалася через внутрішню помилку + Імпортується публічна в\'язка %s Шифруються дані із в\'язки Аналізуються ключі Підготовка операцій з базою даних Обробляється основний ключа %s + В\'язка закінчилася %s + В\'язка закінчується %s + Прапори основного ключа: certify, encrypt, sign + Прапори основного ключа: certify, encrypt + Прапори основного ключа: certify, sign + Прапори основного ключа: encrypt, sign + Прапори основного ключа: certify + Прапори основного ключа: encrypt + Прапори основного ключа: sign + Прапори основного ключа: немає Опрацьовується підключ %s + Підключ закінчився %s + Підключ закінчуєтья %s + Прапори підключів: certify, encrypt, sign + Прапори підключів: certify, encrypt + Прапори підключів: certify, sign + Прапори підключів: encrypt, sign + Прапори підключів: certify + Прапори підключів: encrypt + Прапори підключів: sign + Прапори підключів: жодний Успішно імпортована публічна в\'язка + В\'язка не містить нових даних. Нема що робити. Повторне вставлення секретного ключа Виявлено поганий сертифікат! Помилка опрацювання сертифікату! + ІД користувача сертифіковано %1$s + + Ігнорується один сертифікат виданий невідомим відкритим ключем + Ігнорується %s сертифікати, виданих невідомими відкритими ключами + Ігнорується %s сертифікатів, виданих невідомими відкритими ключами + + Класифікуються ІД користувача (нема доступних надійних ключів) + + Класифікуються ІД користувача (за допомогою одного надійного ключа) + Класифікуються ІД користувача (за допомогою %s надійних ключів) + Класифікуються ІД користувача (за допомогою %s надійних ключів) + + Перевпорядкування ІД користувачів Обробляється ІД користувача %s + ІД користувача відхилене + Спробували імпортувати публічну в\'язку як секретну. Це вада. Будь ласка, відправте звіт! + Спробували імпортувати в\'язку без канонізації. Це вада. Будь ласка, відправте звіт! Імпортується секретний ключ %s Помилка бази даних! Опрацьовуються секретні підключі Помилка шифрування в’язки + Генерується публічна в\'язка із секретної Підключ %s недоступний у публічному ключі Позначено %s як доступно + В\'язка не містить нових даних. Нема що робити. Успішно імпортована секретна в\'язка + Канонізація публічної в\'язки %s + Канонізація секретної в\'язки %s + Невдала канонізація в\'язки: в\'язка не має дійсних ІД користувача Обробляється основний ключ… Опрацьовується підключ %s + Тип сертифікату невідомого ключа: %s + Не знайдено дійсного сертифікату для %s, вилучення із кільця + Успішна канонізація в\'язки, без змін + + Успішна канонізація в\'язки, вилучено один хибний сертифікат + Успішна канонізація в\'язки, вилучено %d хибні сертифікати + Успішна канонізація в\'язки, вилучено %d хибних сертифікатів + + Успішна канонізація в\'язки, вилучено %1$s хибних та %2$s надлишкових сертифікатів + + Успішна канонізація в\'язки, вилучено один надлишковий сертифікат + Успішна канонізація в\'язки, вилучено %d надлишкові сертифікати + Успішна канонізація в\'язки, вилучено %d надлишкових сертифікатів + + Вилучення недійсного ІД користувача %s + Злиття у публічну в\'язку %s + Злиття у секретну в\'язку %s + Фатальна помилка шифрування підпису + Спробували злити в\'язки із різними відбитками! Додається новий підключ %s + Знайдено %s нових сертифікатів у в\'язці + Немає нових сертифікатів + Генерується новий основний ключ + Не вказано параметрів основного ключа! + В\'язка мусить бути створеною хоча б одним ІД користувача! + Основний ключ повинен мати прапорець certify! + Розмір ключа має бути більшим або рівним 512! + Внутрішня помилка PGP! + Поганий вибір алгоритму! + Основний ключ не може бути ключем ElGamal! + Змінюється в\'язка %s + Виняток шифрування! + Дійсний відбиток ключа не зібгається з очікуваним! + Немає ІД ключа. Це внутрішня помилка! Будь ласка, надішліть звіт про ваду! Внутрішня помилка - збій перевірки цілісності! + Не знайдено основного сертифікату для операцій! (Усе відкликано?) + Вказаний поганий ІД первинного користувача! + Вказаний поганий ІД первинного користувача! ІД відхилених користувачів не може бути первинним! Внутрішній виняток PGP! - Змінюється парольна фраза + Виняток підпису! + Змінюються основі сертифікації + Замінюється сертифікат ІД попереднього первинного користувача + Генерується новий сертифікат для ІД нового первинного користувача + Змінюється підключ %s + Спробували працювати із втраченим підключем %s! + Генерується новий %1$s біт %2$s підключа + Новий ід підключа: %s + Дата завершення дії не може бути у минулому! + Відкликається підключ %s + Успішно модифіковано в\'язку + Додається ід користувача %s + Змінюється первинне uid на %s + Відхилення ІД користувача %s + ІД користувача не повинно бути порожнім! + Помилка розблокування в\'язки! Розблоковується в\'язка + + Клацніть для очищення кешованих парольних фраз + OpenKeychain має %d кешованих парольних фраз + Кешовані парольні фрази: + Очистити кеш + Пароль + Внутрішня помилка! Ким підписаний Дані сертифікату Сутність @@ -408,6 +615,7 @@ Ключ не знайдено! Помилка опрацювання ключа! голий + Ваші власні ключі можна вилучити лише окремо! Переглянути дані сертифікату невідомий не можна підписати @@ -415,4 +623,8 @@ Вручну не створюються профілі OpenKeychain.\nЗа подробицями дивіться Довідку. Показати ключ (%s) + Заберіть вашу приватність із OpenKeychain! + Створити мій ключ + Імпортувати наявний ключ + Пропустити установку diff --git a/OpenKeychain/src/main/res/values-zh/strings.xml b/OpenKeychain/src/main/res/values-zh/strings.xml index 8e5d42bb7..9d0848c07 100644 --- a/OpenKeychain/src/main/res/values-zh/strings.xml +++ b/OpenKeychain/src/main/res/values-zh/strings.xml @@ -144,6 +144,7 @@ + -- cgit v1.2.3 From c3b12bb3c271a62c99e9417558576c202e6fed59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Wed, 20 Aug 2014 18:30:22 +0200 Subject: Pull from transifex --- OpenKeychain/src/main/res/raw-cs/help_about.html | 8 ++-- .../src/main/res/raw-cs/help_changelog.html | 8 ++-- OpenKeychain/src/main/res/raw-de/help_about.html | 2 +- .../src/main/res/raw-de/help_changelog.html | 44 +++++++++++----------- .../src/main/res/raw-et/help_changelog.html | 8 ++-- OpenKeychain/src/main/res/raw-it/help_about.html | 12 +++--- .../src/main/res/raw-nl/help_changelog.html | 8 ++-- .../src/main/res/raw-pl/help_changelog.html | 8 ++-- .../src/main/res/raw-ru/help_changelog.html | 8 ++-- .../src/main/res/raw-sl/help_changelog.html | 8 ++-- .../src/main/res/raw-tr/help_changelog.html | 8 ++-- .../src/main/res/raw-zh/help_changelog.html | 8 ++-- OpenKeychain/src/main/res/values-es/strings.xml | 28 ++++++++++++-- OpenKeychain/src/main/res/values-fr/strings.xml | 28 ++++++++++++-- OpenKeychain/src/main/res/values-ja/strings.xml | 25 ++++++++++-- 15 files changed, 135 insertions(+), 76 deletions(-) diff --git a/OpenKeychain/src/main/res/raw-cs/help_about.html b/OpenKeychain/src/main/res/raw-cs/help_about.html index f536fecbd..6394ce319 100644 --- a/OpenKeychain/src/main/res/raw-cs/help_about.html +++ b/OpenKeychain/src/main/res/raw-cs/help_about.html @@ -3,11 +3,11 @@

                http://www.openkeychain.org

                OpenKeychain is an OpenPGP implementation for Android.

                -

                License: GPLv3+

                +

                Licence: GPLv3+

                -

                Developers

                +

                Vývojáři

                  -
                • Dominik Schürmann (Maintainer)
                • +
                • Dominik Schürmann (Hlavní vývojář)
                • Art O Cathain
                • Ash Hughes
                • Brian C. Barnes
                • @@ -27,7 +27,7 @@
                • Tim Bray
                • Vincent Breitmoser
                -

                Libraries

                +

                Knihovny

                • Android Support Library v4 (Apache License v2)
                • diff --git a/OpenKeychain/src/main/res/raw-cs/help_changelog.html b/OpenKeychain/src/main/res/raw-cs/help_changelog.html index e27ac7475..687fd99b9 100644 --- a/OpenKeychain/src/main/res/raw-cs/help_changelog.html +++ b/OpenKeychain/src/main/res/raw-cs/help_changelog.html @@ -7,7 +7,7 @@
                • Key edit: awesome new design, key revocation
                • Key import: awesome new design, secure keyserver connections via hkps, keyserver resolving via DNS SRV records
                • New first time screen
                • -
                • New create key screen: autocompletion of name and email based on your personal Android accounts
                • +
                • New key creation screen: autocompletion of name and email based on your personal Android accounts
                • File encryption: awesome new design, support for encrypting multiple files
                • New icons to show status of key (by Brennan Novak)
                • Important bug fix: Importing of large key collections from a file is now possible
                • @@ -38,7 +38,7 @@

                  2.5

                  • Fix decryption of symmetric pgp messages/files
                  • -
                  • Refactored edit key screen (thanks to Ash Hughes)
                  • +
                  • Refactored key edit screen (thanks to Ash Hughes)
                  • New modern design for encrypt/decrypt screens
                  • OpenPGP API version 3 (multiple api accounts, internal fixes, key lookup)
                  @@ -110,7 +110,7 @@ Daniel Hammann, Daniel Haß, Greg Witczak, Miroojin Bakshi, Nikhil Peter Raj, Pa
                  • Basic keyserver support
                  • App2sd
                  • -
                  • More choices for pass phrase cache: 1, 2, 4, 8, hours
                  • +
                  • More choices for passphrase cache: 1, 2, 4, 8, hours
                  • Translations: Norwegian (thanks, Sander Danielsen), Chinese (thanks, Zhang Fredrick)
                  • Bugfixes
                  • Optimizations
                  • @@ -118,7 +118,7 @@ Daniel Hammann, Daniel Haß, Greg Witczak, Miroojin Bakshi, Nikhil Peter Raj, Pa

                    1.0.7

                    • Fixed problem with signature verification of texts with trailing newline
                    • -
                    • More options for pass phrase cache time to live (20, 40, 60 mins)
                    • +
                    • More options for passphrase cache time to live (20, 40, 60 mins)

                    1.0.6

                      diff --git a/OpenKeychain/src/main/res/raw-de/help_about.html b/OpenKeychain/src/main/res/raw-de/help_about.html index f5622d54a..934caa832 100644 --- a/OpenKeychain/src/main/res/raw-de/help_about.html +++ b/OpenKeychain/src/main/res/raw-de/help_about.html @@ -5,7 +5,7 @@

                      OpenKeychain ist eine OpenPGP-Implementierung für Android.

                      Lizenz: GPLv3+

                      -

                      Developers

                      +

                      Engwickler

                      • Dominik Schürmann (Maintainer)
                      • Art O Cathain
                      • diff --git a/OpenKeychain/src/main/res/raw-de/help_changelog.html b/OpenKeychain/src/main/res/raw-de/help_changelog.html index 674d9c93f..a706b92d4 100644 --- a/OpenKeychain/src/main/res/raw-de/help_changelog.html +++ b/OpenKeychain/src/main/res/raw-de/help_changelog.html @@ -3,17 +3,17 @@

                        2.8

                          -
                        • So many bugs have been fixed in this release that we focus on the main new features
                        • -
                        • Key edit: awesome new design, key revocation
                        • -
                        • Key import: awesome new design, secure keyserver connections via hkps, keyserver resolving via DNS SRV records
                        • -
                        • New first time screen
                        • -
                        • New create key screen: autocompletion of name and email based on your personal Android accounts
                        • -
                        • File encryption: awesome new design, support for encrypting multiple files
                        • -
                        • New icons to show status of key (by Brennan Novak)
                        • -
                        • Important bug fix: Importing of large key collections from a file is now possible
                        • -
                        • Notification showing cached passphrases
                        • -
                        -

                        This release wouldn't be possible without the work of Vincent Breitmoser (GSoC 2014), mar-v-in (GSoC 2014), Daniel Albert, Art O Cathain, Daniel Haß, Tim Bray, Thialfihar

                        +
                      • Es wurden in diesem Release so viele Bugs ausgebessert, sodass wir uns besser auf die neuen Funktionen konzentrieren
                      • +
                      • Schlüsselbearbeitung: tolles neues Design und Schlüsselrückruf
                      • +
                      • Schlüsselimport: tolles neues Design, gesicherte Verbindungen zum Schlüsselserver über HKPS, Schlüsselserver [?] über DNS SRV Einträge
                      • +
                      • Neuer Bildschirm bei der ersten Öffnung
                      • +
                      • New key creation screen: autocompletion of name and email based on your personal Android accounts
                      • +
                      • Dateiverschlüsselung: tolles neues Design, Unterstützung für mehrere Dateien
                      • +
                      • Neue Icons zum Anzeigen des Schlüsselstatus' (von Brennan Novak)
                      • +
                      • Wichtige Ausbesserung eines Bugs: Importieren größerer Schlüsselsammlungen aus einer Datei ist nun möglich
                      • +
                      • Benachrichtigung, die die Passphrasen im Cache anzeigt
                      • +
                      +

                      Dieser Release wäre ohne die Arbeit von Vincent Breitmoser (GSoC 2014), mar-v-in (GSoC 2014), Daniel Albert, Art O Cathain, Daniel Haß, Tim Bray und Thialfihar nicht möglich

                      2.7

                        @@ -21,7 +21,7 @@
                      • Neues Schlüsselansicht Design (Dominik, Vincent)
                      • Neue flache Android Buttons (Dominik, Vincent)
                      • API Fehler behoben (Dominik)
                      • -
                      • keybase.io importiert (Tim Bray)
                      • +
                      • Import aus keybase.io (Tim Bray)

                      2.6.1

                        @@ -29,17 +29,17 @@

                      2.6

                        -
                      • Key certifications (thanks to Vincent Breitmoser)
                      • -
                      • Support for GnuPG partial secret keys (thanks to Vincent Breitmoser)
                      • -
                      • New design for signature verification
                      • -
                      • Custom key length (thanks to Greg Witczak)
                      • -
                      • Fix share-functionality from other apps
                      • +
                      • Schlüsselzertifizierungen (danke an Vincent Breitmoser)
                      • +
                      • Unterstützung für GnuPG-Teilschlüssel (danke an Vincent Breitmoser)
                      • +
                      • Neues Design für Signaturverifikation
                      • +
                      • Benutzerdefinierte Schlüssellänge (Dank an Greg Witczak)
                      • +
                      • Fehler behoben bei der Teilen-Funktion von anderen Apps

                      2.5

                        -
                      • Fix decryption of symmetric pgp messages/files
                      • -
                      • Refactored edit key screen (thanks to Ash Hughes)
                      • -
                      • New modern design for encrypt/decrypt screens
                      • +
                      • Fehler bei der Entschlüsselung symmetrischer PGP Nachrichten/Dateien behoben
                      • +
                      • Refactored key edit screen (thanks to Ash Hughes)
                      • +
                      • Neues modernes Design für Verschlüsselungs-/Entschlüsselungs-Bildschirme
                      • OpenPGP API Version 3 (mehrfache api accounts, interne fehlerbehebungen, schlüssel suche)

                      2.4

                      @@ -110,7 +110,7 @@ Daniel Hammann, Daniel Haß, Greg Witczak, Miroojin Bakshi, Nikhil Peter Raj, Pa
                      • Basic keyserver support
                      • App2sd
                      • -
                      • More choices for pass phrase cache: 1, 2, 4, 8, hours
                      • +
                      • More choices for passphrase cache: 1, 2, 4, 8, hours
                      • Translations: Norwegian (thanks, Sander Danielsen), Chinese (thanks, Zhang Fredrick)
                      • Bugfixes
                      • Optimizations
                      • @@ -118,7 +118,7 @@ Daniel Hammann, Daniel Haß, Greg Witczak, Miroojin Bakshi, Nikhil Peter Raj, Pa

                        1.0.7

                        • Fixed problem with signature verification of texts with trailing newline
                        • -
                        • More options for pass phrase cache time to live (20, 40, 60 mins)
                        • +
                        • More options for passphrase cache time to live (20, 40, 60 mins)

                        1.0.6

                          diff --git a/OpenKeychain/src/main/res/raw-et/help_changelog.html b/OpenKeychain/src/main/res/raw-et/help_changelog.html index e27ac7475..687fd99b9 100644 --- a/OpenKeychain/src/main/res/raw-et/help_changelog.html +++ b/OpenKeychain/src/main/res/raw-et/help_changelog.html @@ -7,7 +7,7 @@
                        • Key edit: awesome new design, key revocation
                        • Key import: awesome new design, secure keyserver connections via hkps, keyserver resolving via DNS SRV records
                        • New first time screen
                        • -
                        • New create key screen: autocompletion of name and email based on your personal Android accounts
                        • +
                        • New key creation screen: autocompletion of name and email based on your personal Android accounts
                        • File encryption: awesome new design, support for encrypting multiple files
                        • New icons to show status of key (by Brennan Novak)
                        • Important bug fix: Importing of large key collections from a file is now possible
                        • @@ -38,7 +38,7 @@

                          2.5

                          • Fix decryption of symmetric pgp messages/files
                          • -
                          • Refactored edit key screen (thanks to Ash Hughes)
                          • +
                          • Refactored key edit screen (thanks to Ash Hughes)
                          • New modern design for encrypt/decrypt screens
                          • OpenPGP API version 3 (multiple api accounts, internal fixes, key lookup)
                          @@ -110,7 +110,7 @@ Daniel Hammann, Daniel Haß, Greg Witczak, Miroojin Bakshi, Nikhil Peter Raj, Pa
                          • Basic keyserver support
                          • App2sd
                          • -
                          • More choices for pass phrase cache: 1, 2, 4, 8, hours
                          • +
                          • More choices for passphrase cache: 1, 2, 4, 8, hours
                          • Translations: Norwegian (thanks, Sander Danielsen), Chinese (thanks, Zhang Fredrick)
                          • Bugfixes
                          • Optimizations
                          • @@ -118,7 +118,7 @@ Daniel Hammann, Daniel Haß, Greg Witczak, Miroojin Bakshi, Nikhil Peter Raj, Pa

                            1.0.7

                            • Fixed problem with signature verification of texts with trailing newline
                            • -
                            • More options for pass phrase cache time to live (20, 40, 60 mins)
                            • +
                            • More options for passphrase cache time to live (20, 40, 60 mins)

                            1.0.6

                              diff --git a/OpenKeychain/src/main/res/raw-it/help_about.html b/OpenKeychain/src/main/res/raw-it/help_about.html index e26c8e246..7b586cbd3 100644 --- a/OpenKeychain/src/main/res/raw-it/help_about.html +++ b/OpenKeychain/src/main/res/raw-it/help_about.html @@ -5,9 +5,9 @@

                              OpenKeychain un implementazione OpenPGP per Android.

                              Licenza: GPLv3+

                              -

                              Developers

                              +

                              Sviluppatori

                                -
                              • Dominik Schürmann (Maintainer)
                              • +
                              • Dominik Schürmann (Manutentore)
                              • Art O Cathain
                              • Ash Hughes
                              • Brian C. Barnes
                              • @@ -34,13 +34,13 @@
                              • Android Support Library v7 'appcompat' (Licenza Apache v2)
                              • -KeybaseLib (Apache License v2)
                              • +KeybaseLib (Licenza Apache v2)
                              • -SuperToasts (Apache License v2)
                              • +SuperToasts (Licenza Apache v2)
                              • -TokenAutoComplete (Apache License v2)
                              • +TokenAutoComplete (Licenza Apache v2)
                              • -MiniDNS (Apache License v2)
                              • +MiniDNS (Licenza Apache v2)
                              • StickyListHeaders (Licenza Apache v2)
                              • diff --git a/OpenKeychain/src/main/res/raw-nl/help_changelog.html b/OpenKeychain/src/main/res/raw-nl/help_changelog.html index 3bc039642..0b6fabc24 100644 --- a/OpenKeychain/src/main/res/raw-nl/help_changelog.html +++ b/OpenKeychain/src/main/res/raw-nl/help_changelog.html @@ -7,7 +7,7 @@
                              • Key edit: awesome new design, key revocation
                              • Key import: awesome new design, secure keyserver connections via hkps, keyserver resolving via DNS SRV records
                              • New first time screen
                              • -
                              • New create key screen: autocompletion of name and email based on your personal Android accounts
                              • +
                              • New key creation screen: autocompletion of name and email based on your personal Android accounts
                              • File encryption: awesome new design, support for encrypting multiple files
                              • New icons to show status of key (by Brennan Novak)
                              • Important bug fix: Importing of large key collections from a file is now possible
                              • @@ -38,7 +38,7 @@

                                2.5

                                • Fix decryption of symmetric pgp messages/files
                                • -
                                • Refactored edit key screen (thanks to Ash Hughes)
                                • +
                                • Refactored key edit screen (thanks to Ash Hughes)
                                • New modern design for encrypt/decrypt screens
                                • OpenPGP API versie 3 (meerdere api accounts, interne fixes, sleutel lookup)
                                @@ -110,7 +110,7 @@ Daniel Hammann, Daniel Haß, Greg Witczak, Miroojin Bakshi, Nikhil Peter Raj, Pa
                                • Basic keyserver support
                                • App2sd
                                • -
                                • More choices for pass phrase cache: 1, 2, 4, 8, hours
                                • +
                                • More choices for passphrase cache: 1, 2, 4, 8, hours
                                • Translations: Norwegian (thanks, Sander Danielsen), Chinese (thanks, Zhang Fredrick)
                                • Bugfixes
                                • Optimizations
                                • @@ -118,7 +118,7 @@ Daniel Hammann, Daniel Haß, Greg Witczak, Miroojin Bakshi, Nikhil Peter Raj, Pa

                                  1.0.7

                                  • Fixed problem with signature verification of texts with trailing newline
                                  • -
                                  • More options for pass phrase cache time to live (20, 40, 60 mins)
                                  • +
                                  • More options for passphrase cache time to live (20, 40, 60 mins)

                                  1.0.6

                                    diff --git a/OpenKeychain/src/main/res/raw-pl/help_changelog.html b/OpenKeychain/src/main/res/raw-pl/help_changelog.html index eded2c8c4..eb2dc26c1 100644 --- a/OpenKeychain/src/main/res/raw-pl/help_changelog.html +++ b/OpenKeychain/src/main/res/raw-pl/help_changelog.html @@ -7,7 +7,7 @@
                                  • Key edit: awesome new design, key revocation
                                  • Key import: awesome new design, secure keyserver connections via hkps, keyserver resolving via DNS SRV records
                                  • New first time screen
                                  • -
                                  • New create key screen: autocompletion of name and email based on your personal Android accounts
                                  • +
                                  • New key creation screen: autocompletion of name and email based on your personal Android accounts
                                  • File encryption: awesome new design, support for encrypting multiple files
                                  • New icons to show status of key (by Brennan Novak)
                                  • Important bug fix: Importing of large key collections from a file is now possible
                                  • @@ -38,7 +38,7 @@

                                    2.5

                                    • Fix decryption of symmetric pgp messages/files
                                    • -
                                    • Refactored edit key screen (thanks to Ash Hughes)
                                    • +
                                    • Refactored key edit screen (thanks to Ash Hughes)
                                    • New modern design for encrypt/decrypt screens
                                    • OpenPGP API wersja 3 (wiele kont API, wewnętrzne poprawki, wyszukiwanie kluczy)
                                    @@ -110,7 +110,7 @@ Daniel Hammann, Daniel Haß, Greg Witczak, Miroojin Bakshi, Nikhil Peter Raj, Pa
                                    • Basic keyserver support
                                    • App2sd
                                    • -
                                    • More choices for pass phrase cache: 1, 2, 4, 8, hours
                                    • +
                                    • More choices for passphrase cache: 1, 2, 4, 8, hours
                                    • Translations: Norwegian (thanks, Sander Danielsen), Chinese (thanks, Zhang Fredrick)
                                    • Bugfixes
                                    • Optimizations
                                    • @@ -118,7 +118,7 @@ Daniel Hammann, Daniel Haß, Greg Witczak, Miroojin Bakshi, Nikhil Peter Raj, Pa

                                      1.0.7

                                      • Fixed problem with signature verification of texts with trailing newline
                                      • -
                                      • More options for pass phrase cache time to live (20, 40, 60 mins)
                                      • +
                                      • More options for passphrase cache time to live (20, 40, 60 mins)

                                      1.0.6

                                        diff --git a/OpenKeychain/src/main/res/raw-ru/help_changelog.html b/OpenKeychain/src/main/res/raw-ru/help_changelog.html index f74a54762..6d9c92e9b 100644 --- a/OpenKeychain/src/main/res/raw-ru/help_changelog.html +++ b/OpenKeychain/src/main/res/raw-ru/help_changelog.html @@ -7,7 +7,7 @@
                                      • Key edit: awesome new design, key revocation
                                      • Key import: awesome new design, secure keyserver connections via hkps, keyserver resolving via DNS SRV records
                                      • New first time screen
                                      • -
                                      • New create key screen: autocompletion of name and email based on your personal Android accounts
                                      • +
                                      • New key creation screen: autocompletion of name and email based on your personal Android accounts
                                      • File encryption: awesome new design, support for encrypting multiple files
                                      • New icons to show status of key (by Brennan Novak)
                                      • Important bug fix: Importing of large key collections from a file is now possible
                                      • @@ -38,7 +38,7 @@

                                        2.5

                                        • Fix decryption of symmetric pgp messages/files
                                        • -
                                        • Refactored edit key screen (thanks to Ash Hughes)
                                        • +
                                        • Refactored key edit screen (thanks to Ash Hughes)
                                        • New modern design for encrypt/decrypt screens
                                        • OpenPGP API версии 3 (множественные аккаунты, внутренние исправления, поиск ключей)
                                        @@ -110,7 +110,7 @@ Daniel Hammann, Daniel Haß, Greg Witczak, Miroojin Bakshi, Nikhil Peter Raj, Pa
                                        • Basic keyserver support
                                        • App2sd
                                        • -
                                        • More choices for pass phrase cache: 1, 2, 4, 8, hours
                                        • +
                                        • More choices for passphrase cache: 1, 2, 4, 8, hours
                                        • Translations: Norwegian (thanks, Sander Danielsen), Chinese (thanks, Zhang Fredrick)
                                        • Bugfixes
                                        • Optimizations
                                        • @@ -118,7 +118,7 @@ Daniel Hammann, Daniel Haß, Greg Witczak, Miroojin Bakshi, Nikhil Peter Raj, Pa

                                          1.0.7

                                          • Fixed problem with signature verification of texts with trailing newline
                                          • -
                                          • More options for pass phrase cache time to live (20, 40, 60 mins)
                                          • +
                                          • More options for passphrase cache time to live (20, 40, 60 mins)

                                          1.0.6

                                            diff --git a/OpenKeychain/src/main/res/raw-sl/help_changelog.html b/OpenKeychain/src/main/res/raw-sl/help_changelog.html index e5ff10005..635d02780 100644 --- a/OpenKeychain/src/main/res/raw-sl/help_changelog.html +++ b/OpenKeychain/src/main/res/raw-sl/help_changelog.html @@ -7,7 +7,7 @@
                                          • Key edit: awesome new design, key revocation
                                          • Key import: awesome new design, secure keyserver connections via hkps, keyserver resolving via DNS SRV records
                                          • New first time screen
                                          • -
                                          • New create key screen: autocompletion of name and email based on your personal Android accounts
                                          • +
                                          • New key creation screen: autocompletion of name and email based on your personal Android accounts
                                          • File encryption: awesome new design, support for encrypting multiple files
                                          • New icons to show status of key (by Brennan Novak)
                                          • Important bug fix: Importing of large key collections from a file is now possible
                                          • @@ -38,7 +38,7 @@

                                            2.5

                                            • Fix decryption of symmetric pgp messages/files
                                            • -
                                            • Refactored edit key screen (thanks to Ash Hughes)
                                            • +
                                            • Refactored key edit screen (thanks to Ash Hughes)
                                            • New modern design for encrypt/decrypt screens
                                            • API OpenPGP, verzija 3 (podpora za več API računov, interni popravki, iskanje ključev)
                                            @@ -110,7 +110,7 @@ Daniel Hammann, Daniel Haß, Greg Witczak, Miroojin Bakshi, Nikhil Peter Raj, Pa
                                            • Basic keyserver support
                                            • App2sd
                                            • -
                                            • More choices for pass phrase cache: 1, 2, 4, 8, hours
                                            • +
                                            • More choices for passphrase cache: 1, 2, 4, 8, hours
                                            • Translations: Norwegian (thanks, Sander Danielsen), Chinese (thanks, Zhang Fredrick)
                                            • Bugfixes
                                            • Optimizations
                                            • @@ -118,7 +118,7 @@ Daniel Hammann, Daniel Haß, Greg Witczak, Miroojin Bakshi, Nikhil Peter Raj, Pa

                                              1.0.7

                                              • Fixed problem with signature verification of texts with trailing newline
                                              • -
                                              • More options for pass phrase cache time to live (20, 40, 60 mins)
                                              • +
                                              • More options for passphrase cache time to live (20, 40, 60 mins)

                                              1.0.6

                                                diff --git a/OpenKeychain/src/main/res/raw-tr/help_changelog.html b/OpenKeychain/src/main/res/raw-tr/help_changelog.html index e27ac7475..687fd99b9 100644 --- a/OpenKeychain/src/main/res/raw-tr/help_changelog.html +++ b/OpenKeychain/src/main/res/raw-tr/help_changelog.html @@ -7,7 +7,7 @@
                                              • Key edit: awesome new design, key revocation
                                              • Key import: awesome new design, secure keyserver connections via hkps, keyserver resolving via DNS SRV records
                                              • New first time screen
                                              • -
                                              • New create key screen: autocompletion of name and email based on your personal Android accounts
                                              • +
                                              • New key creation screen: autocompletion of name and email based on your personal Android accounts
                                              • File encryption: awesome new design, support for encrypting multiple files
                                              • New icons to show status of key (by Brennan Novak)
                                              • Important bug fix: Importing of large key collections from a file is now possible
                                              • @@ -38,7 +38,7 @@

                                                2.5

                                                • Fix decryption of symmetric pgp messages/files
                                                • -
                                                • Refactored edit key screen (thanks to Ash Hughes)
                                                • +
                                                • Refactored key edit screen (thanks to Ash Hughes)
                                                • New modern design for encrypt/decrypt screens
                                                • OpenPGP API version 3 (multiple api accounts, internal fixes, key lookup)
                                                @@ -110,7 +110,7 @@ Daniel Hammann, Daniel Haß, Greg Witczak, Miroojin Bakshi, Nikhil Peter Raj, Pa
                                                • Basic keyserver support
                                                • App2sd
                                                • -
                                                • More choices for pass phrase cache: 1, 2, 4, 8, hours
                                                • +
                                                • More choices for passphrase cache: 1, 2, 4, 8, hours
                                                • Translations: Norwegian (thanks, Sander Danielsen), Chinese (thanks, Zhang Fredrick)
                                                • Bugfixes
                                                • Optimizations
                                                • @@ -118,7 +118,7 @@ Daniel Hammann, Daniel Haß, Greg Witczak, Miroojin Bakshi, Nikhil Peter Raj, Pa

                                                  1.0.7

                                                  • Fixed problem with signature verification of texts with trailing newline
                                                  • -
                                                  • More options for pass phrase cache time to live (20, 40, 60 mins)
                                                  • +
                                                  • More options for passphrase cache time to live (20, 40, 60 mins)

                                                  1.0.6

                                                    diff --git a/OpenKeychain/src/main/res/raw-zh/help_changelog.html b/OpenKeychain/src/main/res/raw-zh/help_changelog.html index e27ac7475..687fd99b9 100644 --- a/OpenKeychain/src/main/res/raw-zh/help_changelog.html +++ b/OpenKeychain/src/main/res/raw-zh/help_changelog.html @@ -7,7 +7,7 @@
                                                  • Key edit: awesome new design, key revocation
                                                  • Key import: awesome new design, secure keyserver connections via hkps, keyserver resolving via DNS SRV records
                                                  • New first time screen
                                                  • -
                                                  • New create key screen: autocompletion of name and email based on your personal Android accounts
                                                  • +
                                                  • New key creation screen: autocompletion of name and email based on your personal Android accounts
                                                  • File encryption: awesome new design, support for encrypting multiple files
                                                  • New icons to show status of key (by Brennan Novak)
                                                  • Important bug fix: Importing of large key collections from a file is now possible
                                                  • @@ -38,7 +38,7 @@

                                                    2.5

                                                    • Fix decryption of symmetric pgp messages/files
                                                    • -
                                                    • Refactored edit key screen (thanks to Ash Hughes)
                                                    • +
                                                    • Refactored key edit screen (thanks to Ash Hughes)
                                                    • New modern design for encrypt/decrypt screens
                                                    • OpenPGP API version 3 (multiple api accounts, internal fixes, key lookup)
                                                    @@ -110,7 +110,7 @@ Daniel Hammann, Daniel Haß, Greg Witczak, Miroojin Bakshi, Nikhil Peter Raj, Pa
                                                    • Basic keyserver support
                                                    • App2sd
                                                    • -
                                                    • More choices for pass phrase cache: 1, 2, 4, 8, hours
                                                    • +
                                                    • More choices for passphrase cache: 1, 2, 4, 8, hours
                                                    • Translations: Norwegian (thanks, Sander Danielsen), Chinese (thanks, Zhang Fredrick)
                                                    • Bugfixes
                                                    • Optimizations
                                                    • @@ -118,7 +118,7 @@ Daniel Hammann, Daniel Haß, Greg Witczak, Miroojin Bakshi, Nikhil Peter Raj, Pa

                                                      1.0.7

                                                      • Fixed problem with signature verification of texts with trailing newline
                                                      • -
                                                      • More options for pass phrase cache time to live (20, 40, 60 mins)
                                                      • +
                                                      • More options for passphrase cache time to live (20, 40, 60 mins)

                                                      1.0.6

                                                        diff --git a/OpenKeychain/src/main/res/values-es/strings.xml b/OpenKeychain/src/main/res/values-es/strings.xml index 7948b7f1b..115da1278 100644 --- a/OpenKeychain/src/main/res/values-es/strings.xml +++ b/OpenKeychain/src/main/res/values-es/strings.xml @@ -275,6 +275,7 @@ descomprimiendo los datos... verificando la integridad... borrando \'%s\' de forma segura… + reimportando base de datos... Nombre/Correo electrónico/Identidad de clave... Nombre/Correo electrónico/Prueba/Clave... @@ -620,18 +621,37 @@ Desbloqueando juego de claves Consolidando base de datos + ¡La consolidación se inició cuando no había una base de datos cacheada! Probablemente esto es un error de programación, por favor consigne un informe de fallos. Guardando juegos de claves secretas (privadas) Guardando juegos de claves públicas Limpiando base de datos - - Reimportando una clave secreta (privada) - Reimportando %d claves secretas (privadas) + Base de datos consolidada con éxito + Entrando en fase crítica + Abandonando fase crítica + Borrando fichero de caché de juego de claves públicas + Borrando fichero de caché de juego de claves secretas (privadas) + ¡Error al abrir la base de datos! + ¡Error de E/S al escribir claves públicas en caché! + ¡Error de E/S al escribir claves secretas (privadas) en caché! + ¡Error al reimportar claves públicas! + ¡Error reimportando claves secretas (privadas)! + + Recuperando consolidación con %1$d clave secreta (privada) y %2$d pública + Recuperando consolidación con %1$d claves secretas (privadas) y %2$d públicas + Recuperando desde un estado desconocido Reimportando una clave pública Reimportando %d claves públicas - Base de datos consolidada con éxito + No hay claves públicas a reimportar, omitiendo... + + Reimportando una clave secreta (privada) + Reimportando %d claves secretas (privadas) + + No hay claves públicas a reimportar, omitiendo... + Excepción borrando fichero de caché público + Excepción borrando fichero de caché público Haga clic para limpiar las frases contraseña almacenadas en caché OpenKeychain ha almacenado en caché %d frases contraseña diff --git a/OpenKeychain/src/main/res/values-fr/strings.xml b/OpenKeychain/src/main/res/values-fr/strings.xml index 74fa562ff..41b7c24ae 100644 --- a/OpenKeychain/src/main/res/values-fr/strings.xml +++ b/OpenKeychain/src/main/res/values-fr/strings.xml @@ -275,6 +275,7 @@ décompression des données... vérification de l\'intégrité... suppression sûre de « %s »... + réimportation de la base de données... Nom/courriel/ID de clef... Nom/courriel/preuve/clef... @@ -620,18 +621,37 @@ Déverrouillage du trousseau Consolidation de la base de données + La consolidation a commencé alors qu\'aucune base de données n\'était en cache ! Ceci est probablement une erreur de programmation, veuillez remplir un rapport de bogue ! Enregistrement des trousseaux secrets Enregistrement des trousseaux publiques Nettoyage de la base de données - - Réimportation d\'une clef secrète - Réimportation de %d clefs secrètes + Base de données consolidée avec succès + Début de la phase critique + Fin de la phase critique + Suppression du fichier de cache du trousseau public + Suppression du fichier de cache du trousseau secret + Erreur lors de l\'ouverture de la base de données ! + Erreur E/S lors de l\'écriture des clefs publiques vers le cache ! + Erreur E/S lors de l\'écriture des clefs secrètes vers le cache ! + Erreur lors de la réimportation des clefs publiques ! + Erreur lors de la réimportation des clefs secrètes ! + + Consolidation de récupération avec %1$d clef secrète et %2$d publique + Consolidation de récupération avec %1$d clefs secrètes et %2$d publiques + Récupération à partir d\'un état inconnu Réimportation d\'une clef publique Réimportation de %d clefs publiques - Base de données consolidée avec succès + Aucune clef publique à réimporter, étape ignorée... + + Réimportation d\'une clef secrète + Réimportation de %d clefs secrètes + + Aucune clef secrète à réimporter, étape ignorée... + Une exception a eu lieu lors de la suppression du fichier de cache publique + Une exception a eu lieu lors de la suppression du fichier de cache publique Cliquer ici pour effacer les phrases de passe mises en cache OpenKeychain a mis en cache %d phrases de passe diff --git a/OpenKeychain/src/main/res/values-ja/strings.xml b/OpenKeychain/src/main/res/values-ja/strings.xml index 6a02916ad..bf2f83e66 100644 --- a/OpenKeychain/src/main/res/values-ja/strings.xml +++ b/OpenKeychain/src/main/res/values-ja/strings.xml @@ -270,6 +270,7 @@ データの展開中... 完全性の検証中... \'%s\' を完全に削除中… + データベースの再インポート中... 名前/メール/鍵ID... 名前/メール/証明/鍵... @@ -606,16 +607,34 @@ 鍵輪のロック解除中 データベースの統合中 + データベースでキャッシュせずに統合を開始します! これはおそらくプログラミングのエラーなので、バグレポートの提出をお願いします! 秘密鍵の鍵輪を保存中 公開鍵の鍵輪を保存中 データベースの消去中 - - %d の秘密鍵を再インポート中 + データベースの統合が成功しました + クリティカルなフェーズに入りました + クリティカルなフェーズを抜けました + 公開鍵輪のキャッシュファイルを削除中 + 秘密鍵輪のキャッシュファイルを削除中 + データベースオープン中のエラー! + キャッシュに公開鍵を書く際にI/Oエラー! + キャッシュに秘密鍵を書く際にI/Oエラー! + 公開鍵の再インポートのエラー! + 秘密鍵の再インポートのエラー! + + %1$d の秘密鍵と %2$d の公開鍵の統合のリカバリー中 + 不明な状態からリカバリー中 %d の公開鍵を再インポート中 - データベースの統合が成功しました + 再インポートで公開鍵がありません、スキップします... + + %d の秘密鍵を再インポート中 + + 再インポートで秘密鍵がありません、スキップします... + 公開鍵キャッシュファイルの削除例外 + 公開鍵キャッシュファイルの削除例外 クリックしてパスフレーズのキャッシュをクリア OpenKeychainは %d のパスフレーズをキャッシュしています -- cgit v1.2.3 From 9aaaac068efa21c4f9fdc8ae9c79abdee685b0fc Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Wed, 20 Aug 2014 19:31:51 +0200 Subject: consolidate: use KeychainProvider for deletion operation --- .../java/org/sufficientlysecure/keychain/KeychainApplication.java | 2 -- .../org/sufficientlysecure/keychain/provider/KeychainDatabase.java | 2 +- .../org/sufficientlysecure/keychain/provider/KeychainProvider.java | 5 +++++ .../org/sufficientlysecure/keychain/provider/ProviderHelper.java | 3 +-- 4 files changed, 7 insertions(+), 5 deletions(-) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/KeychainApplication.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/KeychainApplication.java index bb691a9d2..964a15d58 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/KeychainApplication.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/KeychainApplication.java @@ -103,8 +103,6 @@ public class KeychainApplication extends Application { } } - - public static void setupAccountAsNeeded(Context context) { AccountManager manager = AccountManager.get(context); Account[] accounts = manager.getAccountsByType(Constants.PACKAGE_NAME); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainDatabase.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainDatabase.java index 560eb9ef8..041c4d904 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainDatabase.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainDatabase.java @@ -349,7 +349,7 @@ public class KeychainDatabase extends SQLiteOpenHelper { copy(in, out); } - // DANGEROUS + // DANGEROUS, use in test code ONLY! public void clearDatabase() { getWritableDatabase().execSQL("delete from " + Tables.KEY_RINGS_PUBLIC); } 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 2c552a060..c5bf12143 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java @@ -685,6 +685,11 @@ public class KeychainProvider extends ContentProvider { final int match = mUriMatcher.match(uri); switch (match) { + // dangerous + case KEY_RINGS_UNIFIED: { + count = db.delete(Tables.KEY_RINGS_PUBLIC, null, null); + break; + } case KEY_RING_PUBLIC: { @SuppressWarnings("ConstantConditions") // ensured by uriMatcher above String selection = KeyRings.MASTER_KEY_ID + " = " + uri.getPathSegments().get(1); 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 2867967ff..daa920f74 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java @@ -963,7 +963,6 @@ public class ProviderHelper { private ConsolidateResult consolidateDatabaseStep2(Progressable progress, boolean recovery) { - Preferences prefs = Preferences.getPreferences(mContext); // Set flag that we have a cached consolidation here @@ -986,7 +985,7 @@ public class ProviderHelper { // 2. wipe database (IT'S DANGEROUS) log(LogLevel.DEBUG, LogType.MSG_CON_DB_CLEAR); - new KeychainDatabase(mContext).clearDatabase(); + mContentResolver.delete(KeyRings.buildUnifiedKeyRingsUri(), null, null); FileImportCache cacheSecret = new FileImportCache(mContext, "consolidate_secret.pcl"); -- cgit v1.2.3 From fe1f5489ff8e819c8711f9bde3a19573bc621110 Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Wed, 20 Aug 2014 19:34:36 +0200 Subject: consolidate: implement (mostly) recovery mode --- .../keychain/provider/ProviderHelper.java | 5 ++ .../keychain/service/KeychainIntentService.java | 13 ++- .../keychain/ui/ConsolidateDialogActivity.java | 93 ++++++++++++---------- .../keychain/ui/KeyListActivity.java | 3 +- OpenKeychain/src/main/res/values/strings.xml | 2 +- 5 files changed, 67 insertions(+), 49 deletions(-) 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 daa920f74..125f33ded 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java @@ -987,6 +987,11 @@ public class ProviderHelper { log(LogLevel.DEBUG, LogType.MSG_CON_DB_CLEAR); mContentResolver.delete(KeyRings.buildUnifiedKeyRingsUri(), null, null); + // debug: break if this isn't recovery + if (!recovery) { + return new ConsolidateResult(ConsolidateResult.RESULT_ERROR, mLog); + } + FileImportCache cacheSecret = new FileImportCache(mContext, "consolidate_secret.pcl"); FileImportCache cachePublic = diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java index 2c1bc8463..ae881769d 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java @@ -167,6 +167,10 @@ public class KeychainIntentService extends IntentService public static final String CERTIFY_KEY_PUB_KEY_ID = "sign_key_pub_key_id"; public static final String CERTIFY_KEY_UIDS = "sign_key_uids"; + // consolidate + public static final String CONSOLIDATE_RECOVERY = "consolidate_recovery"; + + /* * possible data keys as result send over messenger */ @@ -183,8 +187,6 @@ public class KeychainIntentService extends IntentService public static final String RESULT_IMPORT = "result"; - public static final String RESULT_CONSOLIDATE = "consolidate_result"; - Messenger mMessenger; private boolean mIsCanceled; @@ -667,7 +669,12 @@ public class KeychainIntentService extends IntentService } } else if (ACTION_CONSOLIDATE.equals(action)) { - ConsolidateResult result = new ProviderHelper(this).consolidateDatabaseStep1(this); + ConsolidateResult result; + if (data.containsKey(CONSOLIDATE_RECOVERY) && data.getBoolean(CONSOLIDATE_RECOVERY)) { + result = new ProviderHelper(this).consolidateDatabaseStep2(this); + } else { + result = new ProviderHelper(this).consolidateDatabaseStep1(this); + } sendMessageToHandler(KeychainIntentServiceHandler.MESSAGE_OKAY, result); } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ConsolidateDialogActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ConsolidateDialogActivity.java index e4a80ff48..b21b1375e 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ConsolidateDialogActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ConsolidateDialogActivity.java @@ -20,7 +20,10 @@ package org.sufficientlysecure.keychain.ui; import android.app.Dialog; import android.app.ProgressDialog; import android.content.DialogInterface; +import android.content.Intent; import android.os.Bundle; +import android.os.Message; +import android.os.Messenger; import android.support.v4.app.DialogFragment; import android.support.v4.app.FragmentActivity; import android.util.Log; @@ -29,6 +32,9 @@ import android.view.KeyEvent; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; +import org.sufficientlysecure.keychain.service.KeychainIntentService; +import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler; +import org.sufficientlysecure.keychain.service.OperationResults.ConsolidateResult; /** * We can not directly create a dialog on the application context. @@ -36,66 +42,65 @@ import org.sufficientlysecure.keychain.R; */ public class ConsolidateDialogActivity extends FragmentActivity { - MyDialogFragment mDialogFragment; - @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // this activity itself has no content view (see manifest) - mDialogFragment = new MyDialogFragment(); - // give all extras through to the fragment - mDialogFragment.setArguments(getIntent().getExtras()); + consolidateRecovery(); - mDialogFragment.show(getSupportFragmentManager(), "dialog"); } - public static class MyDialogFragment extends DialogFragment { - - /** - * Creates dialog - */ - @Override - public Dialog onCreateDialog(Bundle savedInstanceState) { - // hack to get holo design (which is not automatically applied due to activity's Theme.NoDisplay - ContextThemeWrapper context = new ContextThemeWrapper(getActivity(), - R.style.Theme_AppCompat_Light); - ProgressDialog dialog = new ProgressDialog(context); - dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); - dialog.setCancelable(false); - dialog.setCanceledOnTouchOutside(false); - - // Disable the back button - DialogInterface.OnKeyListener keyListener = new DialogInterface.OnKeyListener() { - @Override - public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) { - if (keyCode == KeyEvent.KEYCODE_BACK) { - return true; + private void consolidateRecovery() { + // Message is received after importing is done in KeychainIntentService + KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler( + this, + getString(R.string.progress_importing), + ProgressDialog.STYLE_HORIZONTAL) { + public void handleMessage(Message message) { + // handle messages by standard KeychainIntentServiceHandler first + super.handleMessage(message); + + if (message.arg1 == KeychainIntentServiceHandler.MESSAGE_OKAY) { + /* don't care about the results (for now?) + + // get returned data bundle + Bundle returnData = message.getData(); + if (returnData == null) { + return; } - return false; - } + final ConsolidateResult result = + returnData.getParcelable(KeychainIntentService.RESULT_CONSOLIDATE); + if (result == null) { + return; + } + result.createNotify(ConsolidateDialogActivity.this).show(); + */ - }; - dialog.setOnKeyListener(keyListener); + ConsolidateDialogActivity.this.finish(); + } + } + }; - return dialog; - } + // Send all information needed to service to import key in other thread + Intent intent = new Intent(this, KeychainIntentService.class); + intent.setAction(KeychainIntentService.ACTION_CONSOLIDATE); - @Override - public void onCancel(DialogInterface dialog) { - super.onCancel(dialog); + // fill values for this action + Bundle data = new Bundle(); + data.putBoolean(KeychainIntentService.CONSOLIDATE_RECOVERY, true); + intent.putExtra(KeychainIntentService.EXTRA_DATA, data); - dismiss(); - } + // Create a new Messenger for the communication back + Messenger messenger = new Messenger(saveHandler); + intent.putExtra(KeychainIntentService.EXTRA_MESSENGER, messenger); - @Override - public void onDismiss(DialogInterface dialog) { - super.onDismiss(dialog); - Log.d(Constants.TAG, "onDismiss"); + // show progress dialog + saveHandler.showProgressDialog(this); - getActivity().finish(); - } + // start service with intent + startService(intent); } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListActivity.java index 9d9462648..0bc98d545 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListActivity.java @@ -33,6 +33,7 @@ import org.sufficientlysecure.keychain.provider.KeychainContract; import org.sufficientlysecure.keychain.provider.KeychainDatabase; import org.sufficientlysecure.keychain.service.KeychainIntentService; import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler; +import org.sufficientlysecure.keychain.service.OperationResultParcel; import org.sufficientlysecure.keychain.service.OperationResults.ConsolidateResult; import org.sufficientlysecure.keychain.util.Log; import org.sufficientlysecure.keychain.util.Notify; @@ -164,7 +165,7 @@ public class KeyListActivity extends DrawerActivity { return; } final ConsolidateResult result = - returnData.getParcelable(KeychainIntentService.RESULT_CONSOLIDATE); + returnData.getParcelable(OperationResultParcel.EXTRA_RESULT); if (result == null) { return; } diff --git a/OpenKeychain/src/main/res/values/strings.xml b/OpenKeychain/src/main/res/values/strings.xml index 1bd412d4d..64c743ead 100644 --- a/OpenKeychain/src/main/res/values/strings.xml +++ b/OpenKeychain/src/main/res/values/strings.xml @@ -703,7 +703,7 @@ No secret keys to reimport, skipping… Exception deleting public cache file - Exception deleting public cache file + Exception deleting secret cache file Click to clear cached passphrases -- cgit v1.2.3 From f46f2b6895ac0c9c5c000e93457cb66049269ed0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Wed, 20 Aug 2014 19:46:44 +0200 Subject: Fixes and temporary fixes for returning results --- .../keychain/remote/OpenPgpService.java | 4 ++-- .../keychain/service/KeychainIntentService.java | 2 -- .../keychain/service/OperationResultParcel.java | 4 +++- .../keychain/ui/CertifyKeyActivity.java | 24 ++++++++++++++-------- .../keychain/ui/ImportKeysActivity.java | 12 ++++++----- .../keychain/ui/LogDisplayFragment.java | 1 + OpenKeychain/src/main/res/values-de/strings.xml | 2 +- 7 files changed, 30 insertions(+), 19 deletions(-) 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 e2d809d9e..6e9f2fad6 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java @@ -415,7 +415,7 @@ public class OpenPgpService extends RemoteService { // If signature is unknown we return an _additional_ PendingIntent // to retrieve the missing key Intent intent = new Intent(getBaseContext(), ImportKeysActivity.class); - intent.setAction(ImportKeysActivity.ACTION_IMPORT_KEY_FROM_KEYSERVER_AND_RETURN); + intent.setAction(ImportKeysActivity.ACTION_IMPORT_KEY_FROM_KEYSERVER_AND_RETURN_TO_SERVICE); intent.putExtra(ImportKeysActivity.EXTRA_KEY_ID, signatureResult.getKeyId()); intent.putExtra(ImportKeysActivity.EXTRA_PENDING_INTENT_DATA, data); @@ -481,7 +481,7 @@ public class OpenPgpService extends RemoteService { // If keys are not in db we return an additional PendingIntent // to retrieve the missing key Intent intent = new Intent(getBaseContext(), ImportKeysActivity.class); - intent.setAction(ImportKeysActivity.ACTION_IMPORT_KEY_FROM_KEYSERVER_AND_RETURN); + intent.setAction(ImportKeysActivity.ACTION_IMPORT_KEY_FROM_KEYSERVER_AND_RETURN_TO_SERVICE); intent.putExtra(ImportKeysActivity.EXTRA_KEY_ID, masterKeyId); intent.putExtra(ImportKeysActivity.EXTRA_PENDING_INTENT_DATA, data); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java index 2c1bc8463..99eab7f1d 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java @@ -181,8 +181,6 @@ public class KeychainIntentService extends IntentService // export public static final String RESULT_EXPORT = "exported"; - public static final String RESULT_IMPORT = "result"; - public static final String RESULT_CONSOLIDATE = "consolidate_result"; Messenger mMessenger; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/OperationResultParcel.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/OperationResultParcel.java index 91939739a..1ca06e6b6 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/OperationResultParcel.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/OperationResultParcel.java @@ -442,7 +442,9 @@ public class OperationResultParcel implements Parcelable { @Override public void writeToParcel(Parcel dest, int flags) { dest.writeInt(mResult); - dest.writeTypedList(mLog.toList()); + if (mLog != null) { + dest.writeTypedList(mLog.toList()); + } } public static final Creator CREATOR = new Creator() { diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java index e81ebb9c4..323c6a00d 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java @@ -54,6 +54,7 @@ import org.sufficientlysecure.keychain.provider.KeychainContract.UserIds; import org.sufficientlysecure.keychain.service.KeychainIntentService; import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler; import org.sufficientlysecure.keychain.service.OperationResultParcel; +import org.sufficientlysecure.keychain.service.OperationResults; import org.sufficientlysecure.keychain.service.PassphraseCacheService; import org.sufficientlysecure.keychain.ui.adapter.UserIdsAdapter; import org.sufficientlysecure.keychain.ui.dialog.PassphraseDialogFragment; @@ -311,8 +312,14 @@ public class CertifyKeyActivity extends ActionBarActivity implements LoaderManag if (message.arg1 == KeychainIntentServiceHandler.MESSAGE_OKAY) { - Notify.showNotify(CertifyKeyActivity.this, R.string.key_certify_success, - Notify.Style.INFO); +// Notify.showNotify(CertifyKeyActivity.this, R.string.key_certify_success, +// Notify.Style.INFO); + + OperationResultParcel result = new OperationResultParcel(OperationResultParcel.RESULT_OK, null); + Intent intent = new Intent(); + intent.putExtra(OperationResults.ImportKeyResult.EXTRA_RESULT, result); + CertifyKeyActivity.this.setResult(RESULT_OK, intent); + CertifyKeyActivity.this.finish(); // check if we need to send the key to the server or not if (mUploadKeyCheckbox.isChecked()) { @@ -364,13 +371,14 @@ public class CertifyKeyActivity extends ActionBarActivity implements LoaderManag super.handleMessage(message); if (message.arg1 == KeychainIntentServiceHandler.MESSAGE_OKAY) { - Intent intent = new Intent(); - intent.putExtra(OperationResultParcel.EXTRA_RESULT, message.getData()); - Notify.showNotify(CertifyKeyActivity.this, R.string.key_send_success, - Notify.Style.INFO); + //Notify.showNotify(CertifyKeyActivity.this, R.string.key_send_success, + //Notify.Style.INFO); - setResult(RESULT_OK); - finish(); + OperationResultParcel result = new OperationResultParcel(OperationResultParcel.RESULT_OK, null); + Intent intent = new Intent(); + intent.putExtra(OperationResults.ImportKeyResult.EXTRA_RESULT, result); + CertifyKeyActivity.this.setResult(RESULT_OK, intent); + CertifyKeyActivity.this.finish(); } } }; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java index 7df180296..0ec9b445b 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java @@ -45,6 +45,7 @@ import org.sufficientlysecure.keychain.keyimport.ParcelableKeyRing; import org.sufficientlysecure.keychain.pgp.PgpKeyHelper; import org.sufficientlysecure.keychain.service.KeychainIntentService; import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler; +import org.sufficientlysecure.keychain.service.OperationResultParcel; import org.sufficientlysecure.keychain.service.OperationResults.ImportKeyResult; import org.sufficientlysecure.keychain.ui.adapter.PagerTabStripAdapter; import org.sufficientlysecure.keychain.ui.widget.SlidingTabLayout; @@ -64,7 +65,7 @@ public class ImportKeysActivity extends ActionBarActivity { + "IMPORT_KEY_FROM_KEYSERVER"; public static final String ACTION_IMPORT_KEY_FROM_KEYSERVER_AND_RETURN_RESULT = Constants.INTENT_PREFIX + "IMPORT_KEY_FROM_KEY_SERVER_AND_RETURN_RESULT"; - public static final String ACTION_IMPORT_KEY_FROM_KEYSERVER_AND_RETURN = Constants.INTENT_PREFIX + public static final String ACTION_IMPORT_KEY_FROM_KEYSERVER_AND_RETURN_TO_SERVICE = Constants.INTENT_PREFIX + "IMPORT_KEY_FROM_KEY_SERVER_AND_RETURN"; public static final String ACTION_IMPORT_KEY_FROM_FILE_AND_RETURN = Constants.INTENT_PREFIX + "IMPORT_KEY_FROM_FILE_AND_RETURN"; @@ -87,7 +88,7 @@ public class ImportKeysActivity extends ActionBarActivity { public static final String EXTRA_KEY_ID = "key_id"; public static final String EXTRA_FINGERPRINT = "fingerprint"; - // only used by ACTION_IMPORT_KEY_FROM_KEYSERVER_AND_RETURN when used from OpenPgpService + // only used by ACTION_IMPORT_KEY_FROM_KEYSERVER_AND_RETURN_TO_SERVICE when used from OpenPgpService public static final String EXTRA_PENDING_INTENT_DATA = "data"; private Intent mPendingIntentData; @@ -170,7 +171,7 @@ public class ImportKeysActivity extends ActionBarActivity { startListFragment(savedInstanceState, importData, null, null); } } else if (ACTION_IMPORT_KEY_FROM_KEYSERVER.equals(action) - || ACTION_IMPORT_KEY_FROM_KEYSERVER_AND_RETURN.equals(action) + || ACTION_IMPORT_KEY_FROM_KEYSERVER_AND_RETURN_TO_SERVICE.equals(action) || ACTION_IMPORT_KEY_FROM_KEYSERVER_AND_RETURN_RESULT.equals(action)) { // only used for OpenPgpService @@ -456,8 +457,9 @@ public class ImportKeysActivity extends ActionBarActivity { return; } final ImportKeyResult result = - returnData.getParcelable(KeychainIntentService.RESULT_IMPORT); + returnData.getParcelable(OperationResultParcel.EXTRA_RESULT); if (result == null) { + Log.e(Constants.TAG, "result == null"); return; } @@ -468,7 +470,7 @@ public class ImportKeysActivity extends ActionBarActivity { ImportKeysActivity.this.finish(); return; } - if (ACTION_IMPORT_KEY_FROM_KEYSERVER_AND_RETURN.equals(getIntent().getAction())) { + if (ACTION_IMPORT_KEY_FROM_KEYSERVER_AND_RETURN_TO_SERVICE.equals(getIntent().getAction())) { ImportKeysActivity.this.setResult(RESULT_OK, mPendingIntentData); ImportKeysActivity.this.finish(); return; 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 0e948bf7f..7b0f3ecff 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/LogDisplayFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/LogDisplayFragment.java @@ -179,6 +179,7 @@ public class LogDisplayFragment extends ListFragment implements OnTouchListener (Integer) entry.mParameters[0], entry.mParameters)); } else { + Log.d(Constants.TAG, "entry.mType.getMsgId() "+entry.mType.name()); ih.mText.setText(getResources().getString(entry.mType.getMsgId(), entry.mParameters)); } diff --git a/OpenKeychain/src/main/res/values-de/strings.xml b/OpenKeychain/src/main/res/values-de/strings.xml index fb43b9d04..d746f6fb3 100644 --- a/OpenKeychain/src/main/res/values-de/strings.xml +++ b/OpenKeychain/src/main/res/values-de/strings.xml @@ -421,7 +421,7 @@ Die Anwendung ist wegen Kodierungsfehler fehlgeschlagen Die Anwendung ist wegen eines Eingabe/Ausgabe-Fehlers fehlgeschlagen Die Anwendung ist wegen internen Fehler fehlgeschlagen - Importiere öffentlichen Schlüsselbund %s% + Importiere öffentlichen Schlüsselbund %s Schlüsselbund-daten werden kodiert Datenbank-Transaktionen werden vorbereitet Hauptschlüssel %s wird verarbeitet -- cgit v1.2.3 From 475293a116b5c3f7937bc5075921a2a0cb9c9a29 Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Wed, 20 Aug 2014 19:59:45 +0200 Subject: consolidate: prevent concurrent calls of step 2 --- .../keychain/KeychainApplication.java | 13 +- .../keychain/provider/ProviderHelper.java | 189 +++++++++++---------- .../keychain/service/OperationResultParcel.java | 1 + OpenKeychain/src/main/res/values/strings.xml | 3 +- 4 files changed, 115 insertions(+), 91 deletions(-) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/KeychainApplication.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/KeychainApplication.java index 964a15d58..ead29e229 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/KeychainApplication.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/KeychainApplication.java @@ -86,21 +86,26 @@ public class KeychainApplication extends Application { setupAccountAsNeeded(this); // Update keyserver list as needed - Preferences prefs = Preferences.getPreferences(this); - - prefs.updatePreferences(); + Preferences.getPreferences(this).updatePreferences(); TlsHelper.addStaticCA("pool.sks-keyservers.net", getAssets(), "sks-keyservers.netCA.cer"); TemporaryStorageProvider.cleanUp(this); + checkConsolidateRecovery(); + + } + + public void checkConsolidateRecovery() { + // restart consolidate process if it has been interruped before - if (prefs.getCachedConsolidate()) { + if (Preferences.getPreferences(this).getCachedConsolidate()) { // do something which calls ProviderHelper.consolidateDatabaseStep2 with a progressable Intent consolidateIntent = new Intent(this, ConsolidateDialogActivity.class); consolidateIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(consolidateIntent); } + } public static void setupAccountAsNeeded(Context context) { 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 125f33ded..0d6e83749 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java @@ -961,111 +961,128 @@ public class ProviderHelper { return consolidateDatabaseStep2(progress, true); } + private static boolean mConsolidateCritical = false; + private ConsolidateResult consolidateDatabaseStep2(Progressable progress, boolean recovery) { - Preferences prefs = Preferences.getPreferences(mContext); + synchronized (ProviderHelper.class) { + if (mConsolidateCritical) { + log(LogLevel.ERROR, LogType.MSG_CON_ERROR_CONCURRENT); + return new ConsolidateResult(ConsolidateResult.RESULT_ERROR, mLog); + } + mConsolidateCritical = true; + } - // Set flag that we have a cached consolidation here - int numSecrets = prefs.getCachedConsolidateNumSecrets(); - int numPublics = prefs.getCachedConsolidateNumPublics(); + try { + Preferences prefs = Preferences.getPreferences(mContext); - if (recovery) { - if (numSecrets >= 0 && numPublics >= 0) { - log(LogLevel.START, LogType.MSG_CON_RECOVER, numSecrets, numPublics); - } else { - log(LogLevel.START, LogType.MSG_CON_RECOVER_UNKNOWN); + // Set flag that we have a cached consolidation here + int numSecrets = prefs.getCachedConsolidateNumSecrets(); + int numPublics = prefs.getCachedConsolidateNumPublics(); + + if (recovery) { + if (numSecrets >= 0 && numPublics >= 0) { + log(LogLevel.START, LogType.MSG_CON_RECOVER, numSecrets, numPublics); + } else { + log(LogLevel.START, LogType.MSG_CON_RECOVER_UNKNOWN); + } + mIndent += 1; } - mIndent += 1; - } - if ( ! prefs.getCachedConsolidate()) { - log(LogLevel.ERROR, LogType.MSG_CON_ERROR_BAD_STATE); - return new ConsolidateResult(ConsolidateResult.RESULT_ERROR, mLog); - } + if (!prefs.getCachedConsolidate()) { + log(LogLevel.ERROR, LogType.MSG_CON_ERROR_BAD_STATE); + return new ConsolidateResult(ConsolidateResult.RESULT_ERROR, mLog); + } - // 2. wipe database (IT'S DANGEROUS) - log(LogLevel.DEBUG, LogType.MSG_CON_DB_CLEAR); - mContentResolver.delete(KeyRings.buildUnifiedKeyRingsUri(), null, null); + // 2. wipe database (IT'S DANGEROUS) + log(LogLevel.DEBUG, LogType.MSG_CON_DB_CLEAR); + mContentResolver.delete(KeyRings.buildUnifiedKeyRingsUri(), null, null); - // debug: break if this isn't recovery - if (!recovery) { - return new ConsolidateResult(ConsolidateResult.RESULT_ERROR, mLog); - } + // debug: break if this isn't recovery + if (!recovery) { + return new ConsolidateResult(ConsolidateResult.RESULT_ERROR, mLog); + } - FileImportCache cacheSecret = - new FileImportCache(mContext, "consolidate_secret.pcl"); - FileImportCache cachePublic = - new FileImportCache(mContext, "consolidate_public.pcl"); + FileImportCache cacheSecret = + new FileImportCache(mContext, "consolidate_secret.pcl"); + FileImportCache cachePublic = + new FileImportCache(mContext, "consolidate_public.pcl"); - // 3. Re-Import secret keyrings from cache - if (numSecrets > 0) try { - log(LogLevel.DEBUG, LogType.MSG_CON_REIMPORT_SECRET, numSecrets); - mIndent += 1; + // 3. Re-Import secret keyrings from cache + if (numSecrets > 0) try { + log(LogLevel.DEBUG, LogType.MSG_CON_REIMPORT_SECRET, numSecrets); + mIndent += 1; - new PgpImportExport(mContext, this, - new ProgressFixedScaler(progress, 10, 25, 100, R.string.progress_con_reimport)) - .importKeyRings(cacheSecret.readCache(false), numSecrets); - } catch (IOException e) { - Log.e(Constants.TAG, "error importing secret", e); - log(LogLevel.ERROR, LogType.MSG_CON_ERROR_SECRET); - return new ConsolidateResult(ConsolidateResult.RESULT_ERROR, mLog); - } finally { - mIndent -= 1; - } else { - log(LogLevel.DEBUG, LogType.MSG_CON_REIMPORT_SECRET_SKIP); - } + new PgpImportExport(mContext, this, + new ProgressFixedScaler(progress, 10, 25, 100, R.string.progress_con_reimport)) + .importKeyRings(cacheSecret.readCache(false), numSecrets); + } catch (IOException e) { + Log.e(Constants.TAG, "error importing secret", e); + log(LogLevel.ERROR, LogType.MSG_CON_ERROR_SECRET); + return new ConsolidateResult(ConsolidateResult.RESULT_ERROR, mLog); + } finally { + mIndent -= 1; + } + else { + log(LogLevel.DEBUG, LogType.MSG_CON_REIMPORT_SECRET_SKIP); + } - // 4. Re-Import public keyrings from cache - if (numPublics > 0) try { - log(LogLevel.DEBUG, LogType.MSG_CON_REIMPORT_PUBLIC, numPublics); - mIndent += 1; + // 4. Re-Import public keyrings from cache + if (numPublics > 0) try { + log(LogLevel.DEBUG, LogType.MSG_CON_REIMPORT_PUBLIC, numPublics); + mIndent += 1; - new PgpImportExport(mContext, this, - new ProgressFixedScaler(progress, 25, 99, 100, R.string.progress_con_reimport)) - .importKeyRings(cachePublic.readCache(false), numPublics); - } catch (IOException e) { - Log.e(Constants.TAG, "error importing public", e); - log(LogLevel.ERROR, LogType.MSG_CON_ERROR_PUBLIC); - return new ConsolidateResult(ConsolidateResult.RESULT_ERROR, mLog); - } finally { - mIndent -= 1; - } else { - log(LogLevel.DEBUG, LogType.MSG_CON_REIMPORT_PUBLIC_SKIP); - } + new PgpImportExport(mContext, this, + new ProgressFixedScaler(progress, 25, 99, 100, R.string.progress_con_reimport)) + .importKeyRings(cachePublic.readCache(false), numPublics); + } catch (IOException e) { + Log.e(Constants.TAG, "error importing public", e); + log(LogLevel.ERROR, LogType.MSG_CON_ERROR_PUBLIC); + return new ConsolidateResult(ConsolidateResult.RESULT_ERROR, mLog); + } finally { + mIndent -= 1; + } + else { + log(LogLevel.DEBUG, LogType.MSG_CON_REIMPORT_PUBLIC_SKIP); + } - log(LogLevel.INFO, LogType.MSG_CON_CRITICAL_OUT); - Preferences.getPreferences(mContext).setCachedConsolidate(false); + log(LogLevel.INFO, LogType.MSG_CON_CRITICAL_OUT); + Preferences.getPreferences(mContext).setCachedConsolidate(false); - // 5. Delete caches - try { - log(LogLevel.DEBUG, LogType.MSG_CON_DELETE_SECRET); - mIndent += 1; - cacheSecret.delete(); - } catch (IOException e) { - // doesn't /really/ matter - Log.e(Constants.TAG, "IOException during delete of secret cache", e); - log(LogLevel.WARN, LogType.MSG_CON_WARN_DELETE_SECRET); - } finally { - mIndent -= 1; - } + // 5. Delete caches + try { + log(LogLevel.DEBUG, LogType.MSG_CON_DELETE_SECRET); + mIndent += 1; + cacheSecret.delete(); + } catch (IOException e) { + // doesn't /really/ matter + Log.e(Constants.TAG, "IOException during delete of secret cache", e); + log(LogLevel.WARN, LogType.MSG_CON_WARN_DELETE_SECRET); + } finally { + mIndent -= 1; + } - try { - log(LogLevel.DEBUG, LogType.MSG_CON_DELETE_PUBLIC); - mIndent += 1; - cachePublic.delete(); - } catch (IOException e) { - // doesn't /really/ matter - Log.e(Constants.TAG, "IOException during deletion of public cache", e); - log(LogLevel.WARN, LogType.MSG_CON_WARN_DELETE_PUBLIC); - } finally { + try { + log(LogLevel.DEBUG, LogType.MSG_CON_DELETE_PUBLIC); + mIndent += 1; + cachePublic.delete(); + } catch (IOException e) { + // doesn't /really/ matter + Log.e(Constants.TAG, "IOException during deletion of public cache", e); + log(LogLevel.WARN, LogType.MSG_CON_WARN_DELETE_PUBLIC); + } finally { + mIndent -= 1; + } + + progress.setProgress(100, 100); + log(LogLevel.OK, LogType.MSG_CON_SUCCESS); mIndent -= 1; - } - progress.setProgress(100, 100); - log(LogLevel.OK, LogType.MSG_CON_SUCCESS); - mIndent -= 1; + return new ConsolidateResult(ConsolidateResult.RESULT_OK, mLog); - return new ConsolidateResult(ConsolidateResult.RESULT_OK, mLog); + } finally { + mConsolidateCritical = false; + } } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/OperationResultParcel.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/OperationResultParcel.java index 91939739a..7fe712534 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/OperationResultParcel.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/OperationResultParcel.java @@ -396,6 +396,7 @@ public class OperationResultParcel implements Parcelable { MSG_CON_DELETE_PUBLIC (R.string.msg_con_delete_public), MSG_CON_DELETE_SECRET (R.string.msg_con_delete_secret), MSG_CON_ERROR_BAD_STATE (R.string.msg_con_error_bad_state), + MSG_CON_ERROR_CONCURRENT(R.string.msg_con_error_concurrent), MSG_CON_ERROR_DB (R.string.msg_con_error_db), MSG_CON_ERROR_IO_PUBLIC (R.string.msg_con_error_io_public), MSG_CON_ERROR_IO_SECRET (R.string.msg_con_error_io_secret), diff --git a/OpenKeychain/src/main/res/values/strings.xml b/OpenKeychain/src/main/res/values/strings.xml index 64c743ead..3175d679b 100644 --- a/OpenKeychain/src/main/res/values/strings.xml +++ b/OpenKeychain/src/main/res/values/strings.xml @@ -673,7 +673,8 @@ Consolidating database - Consolidation started while no database was cached! This is probably a programming error, please file a bug report. + Consolidation was started while no database was cached! This is probably a programming error, please file a bug report. + Consolidation aborted, already running on other thread! Saving secret keyrings Saving public keyrings Clearing database -- cgit v1.2.3 From 47bcc6149e72d4bc354e5065feefcedca6c7db26 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Wed, 20 Aug 2014 20:08:51 +0200 Subject: return some more results --- .../keychain/ui/CertifyKeyActivity.java | 4 +- .../keychain/ui/CreateKeyFinalFragment.java | 45 +++++++++------------- .../keychain/ui/FirstTimeActivity.java | 12 +++--- .../keychain/ui/KeyListActivity.java | 13 ++++++- .../keychain/ui/LogDisplayFragment.java | 1 - .../keychain/ui/ViewKeyActivity.java | 1 + 6 files changed, 41 insertions(+), 35 deletions(-) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java index 323c6a00d..728e6e1e1 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java @@ -317,7 +317,7 @@ public class CertifyKeyActivity extends ActionBarActivity implements LoaderManag OperationResultParcel result = new OperationResultParcel(OperationResultParcel.RESULT_OK, null); Intent intent = new Intent(); - intent.putExtra(OperationResults.ImportKeyResult.EXTRA_RESULT, result); + intent.putExtra(OperationResultParcel.EXTRA_RESULT, result); CertifyKeyActivity.this.setResult(RESULT_OK, intent); CertifyKeyActivity.this.finish(); @@ -376,7 +376,7 @@ public class CertifyKeyActivity extends ActionBarActivity implements LoaderManag OperationResultParcel result = new OperationResultParcel(OperationResultParcel.RESULT_OK, null); Intent intent = new Intent(); - intent.putExtra(OperationResults.ImportKeyResult.EXTRA_RESULT, result); + intent.putExtra(OperationResultParcel.EXTRA_RESULT, result); CertifyKeyActivity.this.setResult(RESULT_OK, intent); CertifyKeyActivity.this.finish(); } 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 22c0f7767..076f52a10 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyFinalFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyFinalFragment.java @@ -33,6 +33,7 @@ import android.widget.TextView; import org.spongycastle.bcpg.PublicKeyAlgorithmTags; import org.spongycastle.bcpg.sig.KeyFlags; +import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.helper.Preferences; import org.sufficientlysecure.keychain.pgp.KeyRing; @@ -42,6 +43,7 @@ import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler; import org.sufficientlysecure.keychain.service.OperationResultParcel; import org.sufficientlysecure.keychain.service.OperationResults; import org.sufficientlysecure.keychain.service.SaveKeyringParcel; +import org.sufficientlysecure.keychain.util.Log; import org.sufficientlysecure.keychain.util.Notify; public class CreateKeyFinalFragment extends Fragment { @@ -142,23 +144,18 @@ public class CreateKeyFinalFragment extends Fragment { final OperationResults.SaveKeyringResult result = returnData.getParcelable(OperationResultParcel.EXTRA_RESULT); if (result == null) { + Log.e(Constants.TAG, "result == null"); return; } - if (result.getResult() == OperationResultParcel.RESULT_OK) { - if (mUploadCheckbox.isChecked()) { - // result will be displayed after upload - uploadKey(result); - } else { - // TODO: return result - result.createNotify(getActivity()); - - getActivity().setResult(Activity.RESULT_OK); - getActivity().finish(); - } + if (mUploadCheckbox.isChecked()) { + // result will be displayed after upload + uploadKey(result); } else { - // display result on error without finishing activity - result.createNotify(getActivity()); + Intent data = new Intent(); + data.putExtra(OperationResultParcel.EXTRA_RESULT, result); + getActivity().setResult(Activity.RESULT_OK, data); + getActivity().finish(); } } } @@ -217,20 +214,16 @@ public class CreateKeyFinalFragment extends Fragment { super.handleMessage(message); if (message.arg1 == KeychainIntentServiceHandler.MESSAGE_OKAY) { - // TODO: not supported by upload? -// if (result.getResult() == OperationResultParcel.RESULT_OK) { - // TODO: return result - editKeyResult.createNotify(getActivity()); - - Notify.showNotify(getActivity(), R.string.key_send_success, - Notify.Style.INFO); - - getActivity().setResult(Activity.RESULT_OK); + // TODO: upload operation needs a result! + // TODO: then combine these results + //if (result.getResult() == OperationResultParcel.RESULT_OK) { + //Notify.showNotify(getActivity(), R.string.key_send_success, + //Notify.Style.INFO); + + Intent data = new Intent(); + data.putExtra(OperationResultParcel.EXTRA_RESULT, editKeyResult); + getActivity().setResult(Activity.RESULT_OK, data); getActivity().finish(); -// } else { -// // display result on error without finishing activity -// editKeyResult.createNotify(getActivity()); -// } } } }; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/FirstTimeActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/FirstTimeActivity.java index 5f3f170a1..9811500a2 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/FirstTimeActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/FirstTimeActivity.java @@ -51,7 +51,7 @@ public class FirstTimeActivity extends ActionBarActivity { mSkipSetup.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - finishSetup(); + finishSetup(null); } }); @@ -80,18 +80,20 @@ public class FirstTimeActivity extends ActionBarActivity { if (requestCode == REQUEST_CODE_CREATE_OR_IMPORT_KEY) { if (resultCode == RESULT_OK) { - finishSetup(); + finishSetup(data); } } else { Log.e(Constants.TAG, "No valid request code!"); } } - private void finishSetup() { + private void finishSetup(Intent srcData) { Preferences prefs = Preferences.getPreferences(this); prefs.setFirstTime(false); - Intent intent = new Intent(FirstTimeActivity.this, KeyListActivity.class); - startActivity(intent); + Intent intent = new Intent(this, KeyListActivity.class); + // give intent through to display notify + intent.putExtras(srcData); + startActivityForResult(intent, 0); finish(); } } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListActivity.java index 0bc98d545..7663b7366 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListActivity.java @@ -145,7 +145,7 @@ public class KeyListActivity extends DrawerActivity { private void createKey() { Intent intent = new Intent(this, CreateKeyActivity.class); - startActivity(intent); + startActivityForResult(intent, 0); } private void consolidate() { @@ -197,4 +197,15 @@ public class KeyListActivity extends DrawerActivity { } + @Override + protected void onActivityResult(int requestCode, int resultCode, Intent data) { + // if a result has been returned, display a notify + if (data != null && data.hasExtra(OperationResultParcel.EXTRA_RESULT)) { + OperationResultParcel result = data.getParcelableExtra(OperationResultParcel.EXTRA_RESULT); + result.createNotify(this).show(); + } else { + super.onActivityResult(requestCode, resultCode, data); + } + } + } 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 7b0f3ecff..0e948bf7f 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/LogDisplayFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/LogDisplayFragment.java @@ -179,7 +179,6 @@ public class LogDisplayFragment extends ListFragment implements OnTouchListener (Integer) entry.mParameters[0], entry.mParameters)); } else { - Log.d(Constants.TAG, "entry.mType.getMsgId() "+entry.mType.name()); ih.mText.setText(getResources().getString(entry.mType.getMsgId(), entry.mParameters)); } 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 28f7b8bf5..c9db79740 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java @@ -313,6 +313,7 @@ public class ViewKeyActivity extends ActionBarActivity implements @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { + // if a result has been returned, display a notify if (data != null && data.hasExtra(OperationResultParcel.EXTRA_RESULT)) { OperationResultParcel result = data.getParcelableExtra(OperationResultParcel.EXTRA_RESULT); result.createNotify(this).show(); -- cgit v1.2.3 From 50c33ef3223c77ca8c36285ef379fd80ab2e77e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Wed, 20 Aug 2014 20:13:25 +0200 Subject: progress dialog design fix --- .../sufficientlysecure/keychain/ui/ConsolidateDialogActivity.java | 8 -------- .../keychain/ui/dialog/ProgressDialogFragment.java | 8 +++++++- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ConsolidateDialogActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ConsolidateDialogActivity.java index b21b1375e..edc05e28d 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ConsolidateDialogActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ConsolidateDialogActivity.java @@ -17,24 +17,16 @@ package org.sufficientlysecure.keychain.ui; -import android.app.Dialog; import android.app.ProgressDialog; -import android.content.DialogInterface; import android.content.Intent; import android.os.Bundle; import android.os.Message; import android.os.Messenger; -import android.support.v4.app.DialogFragment; import android.support.v4.app.FragmentActivity; -import android.util.Log; -import android.view.ContextThemeWrapper; -import android.view.KeyEvent; -import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.service.KeychainIntentService; import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler; -import org.sufficientlysecure.keychain.service.OperationResults.ConsolidateResult; /** * We can not directly create a dialog on the application context. diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/ProgressDialogFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/ProgressDialogFragment.java index 093a04aff..0324dd3b9 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/ProgressDialogFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/ProgressDialogFragment.java @@ -25,6 +25,7 @@ import android.content.DialogInterface.OnCancelListener; import android.content.DialogInterface.OnKeyListener; import android.os.Bundle; import android.support.v4.app.DialogFragment; +import android.view.ContextThemeWrapper; import android.view.KeyEvent; import org.sufficientlysecure.keychain.R; @@ -113,7 +114,12 @@ public class ProgressDialogFragment extends DialogFragment { public Dialog onCreateDialog(Bundle savedInstanceState) { final Activity activity = getActivity(); - ProgressDialog dialog = new ProgressDialog(activity); + // if the progress 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 context = new ContextThemeWrapper(activity, + R.style.Theme_AppCompat_Light); + + ProgressDialog dialog = new ProgressDialog(context); dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); dialog.setCancelable(false); dialog.setCanceledOnTouchOutside(false); -- cgit v1.2.3 From c2965290497e12d65d0a8412c8f29d7134a05c95 Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Wed, 20 Aug 2014 20:15:43 +0200 Subject: modifyKey: small logging changes --- .../java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java | 2 +- OpenKeychain/src/main/res/values/strings.xml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) 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 e357db412..f3af51397 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java @@ -690,7 +690,7 @@ public class PgpKeyOperation { progress(R.string.progress_modify_subkeyadd, (i-1) * (100 / saveParcel.mAddSubKeys.size())); SaveKeyringParcel.SubkeyAdd add = saveParcel.mAddSubKeys.get(i); - log.add(LogLevel.INFO, LogType.MSG_MF_SUBKEY_NEW, indent, add.mKeysize, + log.add(LogLevel.INFO, LogType.MSG_MF_SUBKEY_NEW, indent, Integer.toString(add.mKeysize), PgpKeyHelper.getAlgorithmInfo(add.mAlgorithm) ); if (add.mExpiry == null) { diff --git a/OpenKeychain/src/main/res/values/strings.xml b/OpenKeychain/src/main/res/values/strings.xml index 3175d679b..71f4504d7 100644 --- a/OpenKeychain/src/main/res/values/strings.xml +++ b/OpenKeychain/src/main/res/values/strings.xml @@ -652,14 +652,14 @@ Signature exception! Modifying master certifications Changing passphrase for keyring… - Changing passphrase for subkey %s + Re-encrypting subkey %s with new passphrase Setting new passphrase failed, trying again with empty old passphrase Passphrase for subkey could not be changed! (Does it have a different one from the other keys?) Replacing certificate of previous primary user id Generating new certificate for new primary user id Modifying subkey %s Tried to operate on missing subkey %s! - Generating new %1$s bit %2$s subkey + Adding new subkey of type %2$s (%1$s bit) New subkey ID: %s Expiry date cannot be in the past! Revoking subkey %s -- cgit v1.2.3 From 735040e19302a99587c5dfd058de7fd0f1db6ef5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Wed, 20 Aug 2014 20:24:19 +0200 Subject: return some more results --- .../keychain/remote/ui/AccountSettingsActivity.java | 12 ++++++++++++ .../sufficientlysecure/keychain/ui/ImportKeysActivity.java | 8 ++------ 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AccountSettingsActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AccountSettingsActivity.java index 666252353..67ad0822d 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AccountSettingsActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AccountSettingsActivity.java @@ -30,6 +30,7 @@ import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.helper.ActionBarHelper; import org.sufficientlysecure.keychain.provider.ProviderHelper; import org.sufficientlysecure.keychain.remote.AccountSettings; +import org.sufficientlysecure.keychain.service.OperationResultParcel; import org.sufficientlysecure.keychain.util.Log; public class AccountSettingsActivity extends ActionBarActivity { @@ -106,4 +107,15 @@ public class AccountSettingsActivity extends ActionBarActivity { finish(); } + @Override + protected void onActivityResult(int requestCode, int resultCode, Intent data) { + // if a result has been returned, display a notify + if (data != null && data.hasExtra(OperationResultParcel.EXTRA_RESULT)) { + OperationResultParcel result = data.getParcelableExtra(OperationResultParcel.EXTRA_RESULT); + result.createNotify(this).show(); + } else { + super.onActivityResult(requestCode, resultCode, data); + } + } + } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java index 0ec9b445b..18f805360 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java @@ -463,7 +463,8 @@ public class ImportKeysActivity extends ActionBarActivity { return; } - if (ACTION_IMPORT_KEY_FROM_KEYSERVER_AND_RETURN_RESULT.equals(getIntent().getAction())) { + if (ACTION_IMPORT_KEY_FROM_KEYSERVER_AND_RETURN_RESULT.equals(getIntent().getAction()) + || ACTION_IMPORT_KEY_FROM_FILE_AND_RETURN.equals(getIntent().getAction())) { Intent intent = new Intent(); intent.putExtra(ImportKeyResult.EXTRA_RESULT, result); ImportKeysActivity.this.setResult(RESULT_OK, intent); @@ -475,11 +476,6 @@ public class ImportKeysActivity extends ActionBarActivity { ImportKeysActivity.this.finish(); return; } - if (ACTION_IMPORT_KEY_FROM_FILE_AND_RETURN.equals(getIntent().getAction())) { - ImportKeysActivity.this.setResult(RESULT_OK); - ImportKeysActivity.this.finish(); - return; - } result.createNotify(ImportKeysActivity.this).show(); } -- cgit v1.2.3 From 937c91eefaa55ef5bc065b54a4ec9b04c8f3a522 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Wed, 20 Aug 2014 20:44:49 +0200 Subject: Fix nullpointer in first time activity --- .../java/org/sufficientlysecure/keychain/ui/FirstTimeActivity.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/FirstTimeActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/FirstTimeActivity.java index 9811500a2..7b608a0a2 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/FirstTimeActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/FirstTimeActivity.java @@ -92,7 +92,9 @@ public class FirstTimeActivity extends ActionBarActivity { prefs.setFirstTime(false); Intent intent = new Intent(this, KeyListActivity.class); // give intent through to display notify - intent.putExtras(srcData); + if (srcData != null) { + intent.putExtras(srcData); + } startActivityForResult(intent, 0); finish(); } -- cgit v1.2.3 From 45706e653466743dcfd5ac5bb150f5a7907d59f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Wed, 20 Aug 2014 21:09:46 +0200 Subject: Notify duration, cleanup --- .../sufficientlysecure/keychain/service/OperationResultParcel.java | 7 ++----- .../java/org/sufficientlysecure/keychain/ui/KeyListFragment.java | 6 ++---- 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/OperationResultParcel.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/OperationResultParcel.java index a7092d7c7..3f48a2200 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/OperationResultParcel.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/OperationResultParcel.java @@ -155,10 +155,8 @@ public class OperationResultParcel implements Parcelable { if ((resultType & OperationResultParcel.RESULT_ERROR) == 0) { if (getLog().containsWarnings()) { - duration = 0; color = Style.ORANGE; } else { - duration = SuperToast.Duration.LONG; color = Style.GREEN; } @@ -167,7 +165,6 @@ public class OperationResultParcel implements Parcelable { } else { - duration = 0; color = Style.RED; str = "operation failed"; @@ -180,8 +177,8 @@ public class OperationResultParcel implements Parcelable { button ? SuperToast.Type.BUTTON : SuperToast.Type.STANDARD, Style.getStyle(color, SuperToast.Animations.POPUP)); toast.setText(str); - toast.setDuration(duration); - toast.setIndeterminate(duration == 0); + toast.setDuration(SuperToast.Duration.EXTRA_LONG); + toast.setIndeterminate(false); toast.setSwipeToDismiss(true); // If we have a log and it's non-empty, show a View Log button if (button) { 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 e7b7d2efc..d1109631a 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java @@ -85,8 +85,6 @@ public class KeyListFragment extends LoaderFragment private Button mButtonEmptyCreate; private Button mButtonEmptyImport; - public static final int REQUEST_CODE_CREATE_OR_IMPORT_KEY = 0x00007012; - /** * Load custom layout with StickyListView from library */ @@ -105,7 +103,7 @@ public class KeyListFragment extends LoaderFragment @Override public void onClick(View v) { Intent intent = new Intent(getActivity(), CreateKeyActivity.class); - startActivityForResult(intent, REQUEST_CODE_CREATE_OR_IMPORT_KEY); + startActivityForResult(intent, 0); } }); mButtonEmptyImport = (Button) view.findViewById(R.id.key_list_empty_button_import); @@ -115,7 +113,7 @@ public class KeyListFragment extends LoaderFragment public void onClick(View v) { Intent intent = new Intent(getActivity(), ImportKeysActivity.class); intent.setAction(ImportKeysActivity.ACTION_IMPORT_KEY_FROM_FILE_AND_RETURN); - startActivityForResult(intent, REQUEST_CODE_CREATE_OR_IMPORT_KEY); + startActivityForResult(intent, 0); } }); -- cgit v1.2.3 From 6ed0f667cd1d556a923bc7d624f296abe17f795a Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Wed, 20 Aug 2014 21:29:11 +0200 Subject: consolidate: remove debug "breakpoint" --- .../org/sufficientlysecure/keychain/provider/ProviderHelper.java | 5 ----- 1 file changed, 5 deletions(-) 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 0d6e83749..47f4682c7 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java @@ -998,11 +998,6 @@ public class ProviderHelper { log(LogLevel.DEBUG, LogType.MSG_CON_DB_CLEAR); mContentResolver.delete(KeyRings.buildUnifiedKeyRingsUri(), null, null); - // debug: break if this isn't recovery - if (!recovery) { - return new ConsolidateResult(ConsolidateResult.RESULT_ERROR, mLog); - } - FileImportCache cacheSecret = new FileImportCache(mContext, "consolidate_secret.pcl"); FileImportCache cachePublic = -- cgit v1.2.3 From e33e5b0003614d27365c8b2f713ba2293b0c13d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Wed, 20 Aug 2014 21:44:51 +0200 Subject: Work on upload key --- .../keychain/keyimport/HkpKeyserver.java | 38 ++++++++++++++-------- 1 file changed, 24 insertions(+), 14 deletions(-) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/HkpKeyserver.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/HkpKeyserver.java index f617be62a..e63fdeb6d 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/HkpKeyserver.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/HkpKeyserver.java @@ -24,8 +24,10 @@ import org.sufficientlysecure.keychain.pgp.PgpHelper; import org.sufficientlysecure.keychain.pgp.PgpKeyHelper; import org.sufficientlysecure.keychain.util.Log; -import java.io.DataOutputStream; +import java.io.BufferedWriter; import java.io.IOException; +import java.io.OutputStream; +import java.io.OutputStreamWriter; import java.io.UnsupportedEncodingException; import java.net.HttpURLConnection; import java.net.URL; @@ -352,24 +354,32 @@ public class HkpKeyserver extends Keyserver { @Override public void add(String armoredKey) throws AddKeyException { try { - String query = getUrlPrefix() + mHost + ":" + mPort + "/pks/add"; + String request = "/pks/add"; String params; try { - params = "keytext=" + URLEncoder.encode(armoredKey, "utf8"); + params = "keytext=" + URLEncoder.encode(armoredKey, "UTF-8"); } catch (UnsupportedEncodingException e) { throw new AddKeyException(); } - Log.d(Constants.TAG, "hkp keyserver add: " + query); - - HttpURLConnection connection = openConnection(new URL(query)); - connection.setRequestMethod("POST"); - connection.addRequestProperty("Content-Type", "application/x-www-form-urlencoded"); - connection.setRequestProperty("Content-Length", Integer.toString(params.getBytes().length)); - connection.setDoOutput(true); - DataOutputStream wr = new DataOutputStream(connection.getOutputStream()); - wr.writeBytes(params); - wr.flush(); - wr.close(); + URL url = new URL(getUrlPrefix() + mHost + ":" + mPort + request); + + Log.d(Constants.TAG, "hkp keyserver add: " + url.toString()); + + HttpURLConnection conn = openConnection(url); + conn.setRequestMethod("POST"); + conn.addRequestProperty("Content-Type", "application/x-www-form-urlencoded"); + conn.setRequestProperty("Content-Length", Integer.toString(params.getBytes().length)); + conn.setDoInput(true); + conn.setDoOutput(true); + + OutputStream os = conn.getOutputStream(); + BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(os, "UTF-8")); + writer.write(params); + writer.flush(); + writer.close(); + os.close(); + + conn.connect(); } catch (IOException e) { throw new AddKeyException(); } -- cgit v1.2.3 From fa25265e7967b29c6ab9a2ecec97b0d076261f98 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Wed, 20 Aug 2014 21:51:01 +0200 Subject: Fix key sharing --- .../java/org/sufficientlysecure/keychain/provider/ProviderHelper.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) 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 0d6e83749..8fd4bc7cf 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java @@ -1128,9 +1128,7 @@ public class ProviderHelper { ByteArrayOutputStream bos = new ByteArrayOutputStream(); String version = PgpHelper.getVersionForHeader(mContext); - if (version != null) { - keyRing.encodeArmored(bos, version); - } + keyRing.encodeArmored(bos, version); String armoredKey = bos.toString("UTF-8"); Log.d(Constants.TAG, "armoredKey:" + armoredKey); -- cgit v1.2.3 From 9122d43d0ab681cfafa67a0b8f81e07776f86083 Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Wed, 20 Aug 2014 21:51:19 +0200 Subject: close actionmode in keylist on loading events (avoid inconsistent state) --- .../org/sufficientlysecure/keychain/ui/KeyListFragment.java | 10 ++++++++++ 1 file changed, 10 insertions(+) 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 e7b7d2efc..d50ff4331 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java @@ -79,6 +79,9 @@ public class KeyListFragment extends LoaderFragment private KeyListAdapter mAdapter; private StickyListHeadersListView mStickyList; + // saves the mode object for multiselect, needed for reset at some point + private ActionMode mActionMode = null; + private String mQuery; private SearchView mSearchView; // empty list layout @@ -148,6 +151,7 @@ public class KeyListFragment extends LoaderFragment public boolean onCreateActionMode(ActionMode mode, Menu menu) { android.view.MenuInflater inflater = getActivity().getMenuInflater(); inflater.inflate(R.menu.key_list_multi, menu); + mActionMode = mode; return true; } @@ -193,6 +197,7 @@ public class KeyListFragment extends LoaderFragment @Override public void onDestroyActionMode(ActionMode mode) { + mActionMode = null; mAdapter.clearSelection(); } @@ -288,6 +293,11 @@ public class KeyListFragment extends LoaderFragment // this view is made visible if no data is available mStickyList.setEmptyView(getActivity().findViewById(R.id.key_list_empty)); + // end action mode, if any + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB && mActionMode != null) { + mActionMode.finish(); + } + // The list should now be shown. if (isResumed()) { setContentShown(true); -- cgit v1.2.3 From 6c428fa6b58fcaa8f681baa9ec5b98625c9cef91 Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Wed, 20 Aug 2014 21:51:57 +0200 Subject: make number of secret keys imported part of ImportResult parcel --- .../org/sufficientlysecure/keychain/pgp/PgpImportExport.java | 9 ++++++--- .../sufficientlysecure/keychain/service/OperationResults.java | 7 +++++-- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpImportExport.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpImportExport.java index fd37112a5..94ff4a1ba 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpImportExport.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpImportExport.java @@ -139,10 +139,10 @@ public class PgpImportExport { // If there aren't even any keys, do nothing here. if (entries == null || !entries.hasNext()) { return new ImportKeyResult( - ImportKeyResult.RESULT_FAIL_NOTHING, mProviderHelper.getLog(), 0, 0, 0); + ImportKeyResult.RESULT_FAIL_NOTHING, mProviderHelper.getLog(), 0, 0, 0, 0); } - int newKeys = 0, oldKeys = 0, badKeys = 0; + int newKeys = 0, oldKeys = 0, badKeys = 0, secret = 0; int position = 0; double progSteps = 100.0 / num; @@ -177,6 +177,9 @@ public class PgpImportExport { oldKeys += 1; } else { newKeys += 1; + if (key.isSecret()) { + secret += 1; + } } } catch (IOException e) { @@ -213,7 +216,7 @@ public class PgpImportExport { } } - return new ImportKeyResult(resultType, log, newKeys, oldKeys, badKeys); + return new ImportKeyResult(resultType, log, newKeys, oldKeys, badKeys, secret); } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/OperationResults.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/OperationResults.java index 878f6ca47..c59a7d172 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/OperationResults.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/OperationResults.java @@ -40,7 +40,7 @@ public abstract class OperationResults { public static class ImportKeyResult extends OperationResultParcel { - public final int mNewKeys, mUpdatedKeys, mBadKeys; + public final int mNewKeys, mUpdatedKeys, mBadKeys, mSecret; // At least one new key public static final int RESULT_OK_NEWKEYS = 2; @@ -76,14 +76,16 @@ public abstract class OperationResults { mNewKeys = source.readInt(); mUpdatedKeys = source.readInt(); mBadKeys = source.readInt(); + mSecret = source.readInt(); } public ImportKeyResult(int result, OperationLog log, - int newKeys, int updatedKeys, int badKeys) { + int newKeys, int updatedKeys, int badKeys, int secret) { super(result, log); mNewKeys = newKeys; mUpdatedKeys = updatedKeys; mBadKeys = badKeys; + mSecret = secret; } @Override @@ -92,6 +94,7 @@ public abstract class OperationResults { dest.writeInt(mNewKeys); dest.writeInt(mUpdatedKeys); dest.writeInt(mBadKeys); + dest.writeInt(mSecret); } public static Creator CREATOR = new Creator() { -- cgit v1.2.3 From dd1b27b28f7c84cc10a4dd632b2175d9171f6c72 Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Wed, 20 Aug 2014 21:52:54 +0200 Subject: consolidate: small ui things --- .../java/org/sufficientlysecure/keychain/provider/ProviderHelper.java | 4 ++++ OpenKeychain/src/main/res/values/strings.xml | 3 ++- 2 files changed, 6 insertions(+), 1 deletion(-) 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 47f4682c7..717d3c5ba 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java @@ -832,6 +832,8 @@ public class ProviderHelper { log(LogLevel.START, LogType.MSG_CON); mIndent += 1; + progress.setProgress(R.string.progress_con_saving, 0, 100); + try { log(LogLevel.DEBUG, LogType.MSG_CON_SAVE_SECRET); @@ -891,6 +893,8 @@ public class ProviderHelper { mIndent -= 1; } + progress.setProgress(R.string.progress_con_saving, 3, 100); + // 1b. fetch all public keyrings into a cache file try { diff --git a/OpenKeychain/src/main/res/values/strings.xml b/OpenKeychain/src/main/res/values/strings.xml index 71f4504d7..c4697cac3 100644 --- a/OpenKeychain/src/main/res/values/strings.xml +++ b/OpenKeychain/src/main/res/values/strings.xml @@ -302,7 +302,8 @@ verifying integrity… deleting \'%s\' securely… - reimporting database… + consolidate: saving to cache… + consolidate: reimporting… Name/Email/Key ID… -- cgit v1.2.3 From 0f8958afb91c1b28a3509c91d0a7b7b56b9b6343 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Wed, 20 Aug 2014 22:17:16 +0200 Subject: Upload key working --- .../java/org/sufficientlysecure/keychain/keyimport/HkpKeyserver.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/HkpKeyserver.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/HkpKeyserver.java index e63fdeb6d..2fe32dc6b 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/HkpKeyserver.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/HkpKeyserver.java @@ -380,6 +380,9 @@ public class HkpKeyserver extends Keyserver { os.close(); conn.connect(); + + Log.d(Constants.TAG, "response code: " + conn.getResponseCode()); + Log.d(Constants.TAG, "answer: " + readAll(conn.getInputStream(), conn.getContentEncoding())); } catch (IOException e) { throw new AddKeyException(); } -- cgit v1.2.3 From 37caddca7021039f9828d1c08164499748fb5ca5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Wed, 20 Aug 2014 22:51:00 +0200 Subject: Upload key working --- .../sufficientlysecure/keychain/keyimport/HkpKeyserver.java | 2 ++ .../keychain/pgp/CanonicalizedPublicKeyRing.java | 4 ---- .../org/sufficientlysecure/keychain/pgp/PgpImportExport.java | 10 +++------- .../keychain/service/KeychainIntentService.java | 5 +++-- 4 files changed, 8 insertions(+), 13 deletions(-) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/HkpKeyserver.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/HkpKeyserver.java index 2fe32dc6b..69ac2551f 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/HkpKeyserver.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/HkpKeyserver.java @@ -364,6 +364,7 @@ public class HkpKeyserver extends Keyserver { URL url = new URL(getUrlPrefix() + mHost + ":" + mPort + request); Log.d(Constants.TAG, "hkp keyserver add: " + url.toString()); + Log.d(Constants.TAG, "params: " + params); HttpURLConnection conn = openConnection(url); conn.setRequestMethod("POST"); @@ -384,6 +385,7 @@ public class HkpKeyserver extends Keyserver { Log.d(Constants.TAG, "response code: " + conn.getResponseCode()); Log.d(Constants.TAG, "answer: " + readAll(conn.getInputStream(), conn.getContentEncoding())); } catch (IOException e) { + Log.e(Constants.TAG, "IOException", e); throw new AddKeyException(); } } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CanonicalizedPublicKeyRing.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CanonicalizedPublicKeyRing.java index 972e45c2e..7b5d5d4be 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CanonicalizedPublicKeyRing.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CanonicalizedPublicKeyRing.java @@ -60,10 +60,6 @@ public class CanonicalizedPublicKeyRing extends CanonicalizedKeyRing { return mRing; } - public void encode(ArmoredOutputStream stream) throws IOException { - getRing().encode(stream); - } - /** Getter that returns the subkey that should be used for signing. */ CanonicalizedPublicKey getEncryptionSubKey() throws PgpGeneralException { PGPPublicKey key = getRing().getPublicKey(getEncryptId()); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpImportExport.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpImportExport.java index fd37112a5..067af3f7c 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpImportExport.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpImportExport.java @@ -99,7 +99,7 @@ public class PgpImportExport { } } - public boolean uploadKeyRingToServer(HkpKeyserver server, CanonicalizedPublicKeyRing keyring) { + public void uploadKeyRingToServer(HkpKeyserver server, CanonicalizedPublicKeyRing keyring) throws AddKeyException { ByteArrayOutputStream bos = new ByteArrayOutputStream(); ArmoredOutputStream aos = null; try { @@ -109,13 +109,9 @@ public class PgpImportExport { String armoredKey = bos.toString("UTF-8"); server.add(armoredKey); - - return true; } catch (IOException e) { - return false; - } catch (AddKeyException e) { - // TODO: tell the user? - return false; + Log.e(Constants.TAG, "IOException", e); + throw new AddKeyException(); } finally { try { if (aos != null) { diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java index d568df91a..e82c43d82 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java @@ -575,8 +575,9 @@ public class KeychainIntentService extends IntentService CanonicalizedPublicKeyRing keyring = providerHelper.getCanonicalizedPublicKeyRing(dataUri); PgpImportExport pgpImportExport = new PgpImportExport(this, null); - boolean uploaded = pgpImportExport.uploadKeyRingToServer(server, keyring); - if (!uploaded) { + try { + pgpImportExport.uploadKeyRingToServer(server, keyring); + } catch (Keyserver.AddKeyException e) { throw new PgpGeneralException("Unable to export key to selected server"); } -- cgit v1.2.3 From e8bc9083f2699fc5c998ac17b3ea7c1325771aa1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Wed, 20 Aug 2014 23:01:27 +0200 Subject: improve certs_text --- OpenKeychain/src/main/res/values/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenKeychain/src/main/res/values/strings.xml b/OpenKeychain/src/main/res/values/strings.xml index 71f4504d7..556df3923 100644 --- a/OpenKeychain/src/main/res/values/strings.xml +++ b/OpenKeychain/src/main/res/values/strings.xml @@ -720,7 +720,7 @@ Identity <unknown> No certificates for this key - Only certificates created with your keys and self-certificates are displayed here. + Only self-certificates and certificates created with your keys are displayed here. Identities to certify Revocation Reason Verification Status -- cgit v1.2.3 From dcf268bcb2cbe433fdef8af4fd516a6482ac268a Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Wed, 20 Aug 2014 23:08:52 +0200 Subject: move key deletion into KeychainIntentHandler --- .../keychain/service/KeychainIntentService.java | 50 ++++++++++++- .../keychain/ui/ViewKeyActivity.java | 8 +- .../ui/dialog/DeleteKeyDialogFragment.java | 85 ++++++++++++---------- OpenKeychain/src/main/res/values/strings.xml | 1 + 4 files changed, 104 insertions(+), 40 deletions(-) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java index d568df91a..4330a1c01 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java @@ -49,6 +49,7 @@ import org.sufficientlysecure.keychain.pgp.Progressable; import org.sufficientlysecure.keychain.pgp.UncachedKeyRing; import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException; import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralMsgIdException; +import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRingData; import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings; import org.sufficientlysecure.keychain.provider.KeychainDatabase; import org.sufficientlysecure.keychain.provider.ProviderHelper; @@ -104,6 +105,8 @@ public class KeychainIntentService extends IntentService public static final String ACTION_CERTIFY_KEYRING = Constants.INTENT_PREFIX + "SIGN_KEYRING"; + public static final String ACTION_DELETE = Constants.INTENT_PREFIX + "DELETE"; + public static final String ACTION_CONSOLIDATE = Constants.INTENT_PREFIX + "CONSOLIDATE"; /* keys for data bundle */ @@ -143,6 +146,10 @@ public class KeychainIntentService extends IntentService // delete file securely public static final String DELETE_FILE = "deleteFile"; + // delete keyring(s) + public static final String DELETE_KEY_LIST = "delete_list"; + public static final String DELETE_IS_SECRET = "delete_is_secret"; + // import key public static final String IMPORT_KEY_LIST = "import_key_list"; public static final String IMPORT_KEY_FILE = "import_key_file"; @@ -487,9 +494,14 @@ public class KeychainIntentService extends IntentService entries = cache.readCacheIntoList(); } - PgpImportExport pgpImportExport = new PgpImportExport(this, this); + ProviderHelper providerHelper = new ProviderHelper(this); + PgpImportExport pgpImportExport = new PgpImportExport(this, providerHelper, this); ImportKeyResult result = pgpImportExport.importKeyRings(entries); + if (result.mSecret > 0) { + providerHelper.consolidateDatabaseStep1(this); + } + sendMessageToHandler(KeychainIntentServiceHandler.MESSAGE_OKAY, result); } catch (Exception e) { sendErrorToHandler(e); @@ -666,6 +678,42 @@ public class KeychainIntentService extends IntentService sendErrorToHandler(e); } + } else if (ACTION_DELETE.equals(action)) { + + try { + + long[] masterKeyIds = data.getLongArray(DELETE_KEY_LIST); + boolean isSecret = data.getBoolean(DELETE_IS_SECRET); + + if (masterKeyIds.length == 0) { + throw new PgpGeneralException("List of keys to delete is empty"); + } + + if (isSecret && masterKeyIds.length > 1) { + throw new PgpGeneralException("Secret keys can only be deleted individually!"); + } + + boolean success = false; + for (long masterKeyId : masterKeyIds) { + int count = getContentResolver().delete( + KeyRingData.buildPublicKeyRingUri(masterKeyId), null, null + ); + success |= count > 0; + } + + if (isSecret && success) { + ConsolidateResult result = + new ProviderHelper(this).consolidateDatabaseStep1(this); + } + + if (success) { + sendMessageToHandler(KeychainIntentServiceHandler.MESSAGE_OKAY); + } + + } catch (Exception e) { + sendErrorToHandler(e); + } + } else if (ACTION_CONSOLIDATE.equals(action)) { ConsolidateResult result; if (data.containsKey(CONSOLIDATE_RECOVERY) && data.getBoolean(CONSOLIDATE_RECOVERY)) { 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 c9db79740..2c0881ea4 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java @@ -54,6 +54,8 @@ import org.sufficientlysecure.keychain.pgp.KeyRing; import org.sufficientlysecure.keychain.pgp.PgpKeyHelper; import org.sufficientlysecure.keychain.provider.KeychainContract; import org.sufficientlysecure.keychain.provider.ProviderHelper; +import org.sufficientlysecure.keychain.service.KeychainIntentService; +import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler; import org.sufficientlysecure.keychain.service.OperationResultParcel; import org.sufficientlysecure.keychain.ui.adapter.PagerTabStripAdapter; import org.sufficientlysecure.keychain.ui.widget.SlidingTabLayout; @@ -303,8 +305,10 @@ public class ViewKeyActivity extends ActionBarActivity implements Handler returnHandler = new Handler() { @Override public void handleMessage(Message message) { - setResult(RESULT_CANCELED); - finish(); + if (message.arg1 == KeychainIntentServiceHandler.MESSAGE_OKAY) { + setResult(RESULT_CANCELED); + finish(); + } } }; 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 4927a4d24..d0c9cea5b 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 @@ -18,7 +18,9 @@ package org.sufficientlysecure.keychain.ui.dialog; import android.app.Dialog; +import android.app.ProgressDialog; import android.content.DialogInterface; +import android.content.Intent; import android.os.Bundle; import android.os.Message; import android.os.Messenger; @@ -31,9 +33,10 @@ import android.widget.TextView; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; -import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRingData; import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings; import org.sufficientlysecure.keychain.provider.ProviderHelper; +import org.sufficientlysecure.keychain.service.KeychainIntentService; +import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler; import org.sufficientlysecure.keychain.util.Log; import java.util.HashMap; @@ -48,8 +51,6 @@ public class DeleteKeyDialogFragment extends DialogFragment { private TextView mMainMessage; private View mInflateView; - private Messenger mMessenger; - /** * Creates new instance of this delete file dialog fragment */ @@ -68,7 +69,7 @@ public class DeleteKeyDialogFragment extends DialogFragment { @Override public Dialog onCreateDialog(Bundle savedInstanceState) { final FragmentActivity activity = getActivity(); - mMessenger = getArguments().getParcelable(ARG_MESSENGER); + final Messenger messenger = getArguments().getParcelable(ARG_MESSENGER); final long[] masterKeyIds = getArguments().getLongArray(ARG_DELETE_MASTER_KEY_IDS); @@ -83,6 +84,8 @@ public class DeleteKeyDialogFragment extends DialogFragment { builder.setTitle(R.string.warning); + final boolean hasSecret; + // If only a single key has been selected if (masterKeyIds.length == 1) { long masterKeyId = masterKeyIds[0]; @@ -98,7 +101,7 @@ public class DeleteKeyDialogFragment extends DialogFragment { } ); String userId = (String) data.get(KeyRings.USER_ID); - boolean hasSecret = ((Long) data.get(KeyRings.HAS_ANY_SECRET)) == 1; + hasSecret = ((Long) data.get(KeyRings.HAS_ANY_SECRET)) == 1; // Set message depending on which key it is. mMainMessage.setText(getString( @@ -107,12 +110,12 @@ public class DeleteKeyDialogFragment extends DialogFragment { userId )); } catch (ProviderHelper.NotFoundException e) { - sendMessageToHandler(MESSAGE_ERROR, null); dismiss(); return null; } } else { mMainMessage.setText(R.string.key_deletion_confirmation_multi); + hasSecret = false; } builder.setIcon(R.drawable.ic_dialog_alert_holo_light); @@ -120,18 +123,45 @@ public class DeleteKeyDialogFragment extends DialogFragment { @Override public void onClick(DialogInterface dialog, int which) { - boolean success = false; - for (long masterKeyId : masterKeyIds) { - int count = activity.getContentResolver().delete( - KeyRingData.buildPublicKeyRingUri(masterKeyId), null, null - ); - success = count > 0; - } - if (success) { - sendMessageToHandler(MESSAGE_OKAY, null); - } else { - sendMessageToHandler(MESSAGE_ERROR, null); - } + // Send all information needed to service to import key in other thread + Intent intent = new Intent(getActivity(), KeychainIntentService.class); + + intent.setAction(KeychainIntentService.ACTION_DELETE); + + // Message is received after importing is done in KeychainIntentService + KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler( + getActivity(), + getString(R.string.progress_deleting), + ProgressDialog.STYLE_HORIZONTAL) { + public void handleMessage(Message message) { + // handle messages by standard KeychainIntentServiceHandler first + super.handleMessage(message); + try { + Message msg = Message.obtain(); + msg.copyFrom(message); + messenger.send(msg); + } catch (RemoteException e) { + Log.e(Constants.TAG, "messenger error", e); + } + } + }; + + // fill values for this action + Bundle data = new Bundle(); + data.putLongArray(KeychainIntentService.DELETE_KEY_LIST, masterKeyIds); + data.putBoolean(KeychainIntentService.DELETE_IS_SECRET, hasSecret); + intent.putExtra(KeychainIntentService.EXTRA_DATA, data); + + // Create a new Messenger for the communication back + Messenger messenger = new Messenger(saveHandler); + intent.putExtra(KeychainIntentService.EXTRA_MESSENGER, messenger); + + // show progress dialog + saveHandler.showProgressDialog(getActivity()); + + // start service with intent + getActivity().startService(intent); + dismiss(); } }); @@ -146,23 +176,4 @@ public class DeleteKeyDialogFragment extends DialogFragment { return builder.show(); } - /** - * Send message back to handler which is initialized in a activity - * - * @param what Message integer you want to send - */ - private void sendMessageToHandler(Integer what, Bundle data) { - Message msg = Message.obtain(); - msg.what = what; - if (data != null) { - msg.setData(data); - } - try { - mMessenger.send(msg); - } catch (RemoteException e) { - Log.w(Constants.TAG, "Exception sending message, Is handler present?", e); - } catch (NullPointerException e) { - Log.w(Constants.TAG, "Messenger is null!", e); - } - } } diff --git a/OpenKeychain/src/main/res/values/strings.xml b/OpenKeychain/src/main/res/values/strings.xml index c4697cac3..fede86b1c 100644 --- a/OpenKeychain/src/main/res/values/strings.xml +++ b/OpenKeychain/src/main/res/values/strings.xml @@ -301,6 +301,7 @@ decompressing data… verifying integrity… deleting \'%s\' securely… + deleting keys… consolidate: saving to cache… consolidate: reimporting… -- cgit v1.2.3 From 9c9fc5330a402fb873708b998dac5f1ebf54b71c Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Wed, 20 Aug 2014 23:09:20 +0200 Subject: small change to make android studio recognize a honeycomb-only block --- .../java/org/sufficientlysecure/keychain/ui/KeyListFragment.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) 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 6a4039e98..96a332d3e 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java @@ -292,8 +292,10 @@ public class KeyListFragment extends LoaderFragment mStickyList.setEmptyView(getActivity().findViewById(R.id.key_list_empty)); // end action mode, if any - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB && mActionMode != null) { - mActionMode.finish(); + if (mActionMode != null) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { + mActionMode.finish(); + } } // The list should now be shown. -- cgit v1.2.3 From 0b07c5258fe4062dfe540ea3ef51471075379fad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Wed, 20 Aug 2014 23:13:37 +0200 Subject: Disable key import in sync adapter --- .../service/ContactSyncAdapterService.java | 77 +++++++++++----------- 1 file changed, 39 insertions(+), 38 deletions(-) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/ContactSyncAdapterService.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/ContactSyncAdapterService.java index 43ed2dad0..e70e74d91 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/ContactSyncAdapterService.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/ContactSyncAdapterService.java @@ -42,7 +42,7 @@ public class ContactSyncAdapterService extends Service { private class ContactSyncAdapter extends AbstractThreadedSyncAdapter { - private final AtomicBoolean importDone = new AtomicBoolean(false); +// private final AtomicBoolean importDone = new AtomicBoolean(false); public ContactSyncAdapter() { super(ContactSyncAdapterService.this, true); @@ -51,43 +51,44 @@ public class ContactSyncAdapterService extends Service { @Override public void onPerformSync(Account account, Bundle extras, String authority, ContentProviderClient provider, final SyncResult syncResult) { - importDone.set(false); - KeychainApplication.setupAccountAsNeeded(ContactSyncAdapterService.this); - EmailKeyHelper.importContacts(getContext(), new Messenger(new Handler(Looper.getMainLooper(), - new Handler.Callback() { - @Override - public boolean handleMessage(Message msg) { - Bundle data = msg.getData(); - switch (msg.arg1) { - case KeychainIntentServiceHandler.MESSAGE_OKAY: - Log.d(Constants.TAG, "Syncing... Done."); - synchronized (importDone) { - importDone.set(true); - importDone.notifyAll(); - } - return true; - case KeychainIntentServiceHandler.MESSAGE_UPDATE_PROGRESS: - if (data.containsKey(KeychainIntentServiceHandler.DATA_PROGRESS) && - data.containsKey(KeychainIntentServiceHandler.DATA_PROGRESS_MAX)) { - Log.d(Constants.TAG, "Syncing... Progress: " + - data.getInt(KeychainIntentServiceHandler.DATA_PROGRESS) + "/" + - data.getInt(KeychainIntentServiceHandler.DATA_PROGRESS_MAX)); - return false; - } - default: - Log.d(Constants.TAG, "Syncing... " + msg.toString()); - return false; - } - } - }))); - synchronized (importDone) { - try { - if (!importDone.get()) importDone.wait(); - } catch (InterruptedException e) { - Log.w(Constants.TAG, e); - return; - } - } + // TODO: Import is currently disabled for 2.8, until we implement proper origin management +// importDone.set(false); +// KeychainApplication.setupAccountAsNeeded(ContactSyncAdapterService.this); +// EmailKeyHelper.importContacts(getContext(), new Messenger(new Handler(Looper.getMainLooper(), +// new Handler.Callback() { +// @Override +// public boolean handleMessage(Message msg) { +// Bundle data = msg.getData(); +// switch (msg.arg1) { +// case KeychainIntentServiceHandler.MESSAGE_OKAY: +// Log.d(Constants.TAG, "Syncing... Done."); +// synchronized (importDone) { +// importDone.set(true); +// importDone.notifyAll(); +// } +// return true; +// case KeychainIntentServiceHandler.MESSAGE_UPDATE_PROGRESS: +// if (data.containsKey(KeychainIntentServiceHandler.DATA_PROGRESS) && +// data.containsKey(KeychainIntentServiceHandler.DATA_PROGRESS_MAX)) { +// Log.d(Constants.TAG, "Syncing... Progress: " + +// data.getInt(KeychainIntentServiceHandler.DATA_PROGRESS) + "/" + +// data.getInt(KeychainIntentServiceHandler.DATA_PROGRESS_MAX)); +// return false; +// } +// default: +// Log.d(Constants.TAG, "Syncing... " + msg.toString()); +// return false; +// } +// } +// }))); +// synchronized (importDone) { +// try { +// if (!importDone.get()) importDone.wait(); +// } catch (InterruptedException e) { +// Log.w(Constants.TAG, e); +// return; +// } +// } ContactHelper.writeKeysToContacts(ContactSyncAdapterService.this); } } -- cgit v1.2.3 From 418e922c78c365cd1c428f334de6814cbbc17b47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Wed, 20 Aug 2014 23:26:01 +0200 Subject: Enable sync adapter, changelog --- CHANGELOG | 1 + .../java/org/sufficientlysecure/keychain/KeychainApplication.java | 8 ++++++-- .../keychain/service/ContactSyncAdapterService.java | 1 + OpenKeychain/src/main/res/raw/help_changelog.html | 1 + 4 files changed, 9 insertions(+), 2 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 8804a9c63..196fc9937 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -8,6 +8,7 @@ * New icons to show status of key (by Brennan Novak) * Important bug fix: Importing of large key collections from a file is now possible * Notification showing cached passphrases +* Keys are connected to Android's contacts This release wouldn't be possible without the work of Vincent Breitmoser (GSoC 2014), mar-v-in (GSoC 2014), Daniel Albert, Art O Cathain, Daniel Haß, Tim Bray, Thialfihar diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/KeychainApplication.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/KeychainApplication.java index ead29e229..ca9af8a9d 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/KeychainApplication.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/KeychainApplication.java @@ -20,11 +20,13 @@ package org.sufficientlysecure.keychain; import android.accounts.Account; import android.accounts.AccountManager; import android.app.Application; +import android.content.ContentResolver; import android.content.Context; import android.content.Intent; import android.graphics.PorterDuff; import android.graphics.drawable.Drawable; import android.os.Environment; +import android.provider.ContactsContract; import org.spongycastle.jce.provider.BouncyCastleProvider; import org.sufficientlysecure.keychain.helper.Preferences; @@ -112,8 +114,10 @@ public class KeychainApplication extends Application { AccountManager manager = AccountManager.get(context); Account[] accounts = manager.getAccountsByType(Constants.PACKAGE_NAME); if (accounts == null || accounts.length == 0) { - Account dummy = new Account(context.getString(R.string.app_name), Constants.PACKAGE_NAME); - manager.addAccountExplicitly(dummy, null, null); + Account account = new Account(context.getString(R.string.app_name), Constants.PACKAGE_NAME); + manager.addAccountExplicitly(account, null, null); + ContentResolver.setIsSyncable(account, ContactsContract.AUTHORITY, 1); + ContentResolver.setSyncAutomatically(account, ContactsContract.AUTHORITY, true); } } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/ContactSyncAdapterService.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/ContactSyncAdapterService.java index e70e74d91..78d132df7 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/ContactSyncAdapterService.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/ContactSyncAdapterService.java @@ -51,6 +51,7 @@ public class ContactSyncAdapterService extends Service { @Override public void onPerformSync(Account account, Bundle extras, String authority, ContentProviderClient provider, final SyncResult syncResult) { + Log.d(Constants.TAG, "Performing a sync!"); // TODO: Import is currently disabled for 2.8, until we implement proper origin management // importDone.set(false); // KeychainApplication.setupAccountAsNeeded(ContactSyncAdapterService.this); diff --git a/OpenKeychain/src/main/res/raw/help_changelog.html b/OpenKeychain/src/main/res/raw/help_changelog.html index 5f1798896..c8992ddab 100644 --- a/OpenKeychain/src/main/res/raw/help_changelog.html +++ b/OpenKeychain/src/main/res/raw/help_changelog.html @@ -16,6 +16,7 @@ And don't add newlines before or after p tags because of transifex -->
                                                      • New icons to show status of key (by Brennan Novak)
                                                      • Important bug fix: Importing of large key collections from a file is now possible
                                                      • Notification showing cached passphrases
                                                      • +
                                                      • Keys are connected to Android's contacts

                                                      This release wouldn't be possible without the work of Vincent Breitmoser (GSoC 2014), mar-v-in (GSoC 2014), Daniel Albert, Art O Cathain, Daniel Haß, Tim Bray, Thialfihar

                                                      -- cgit v1.2.3 From 6e3af6605a1cd722c76fc4daa91ae2ae5207bbca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Wed, 20 Aug 2014 23:55:01 +0200 Subject: Sync in KeychainIntentService on delete, import, save --- .../keychain/service/ContactSyncAdapterService.java | 13 +++++++++++++ .../keychain/service/KeychainIntentService.java | 8 ++++++++ 2 files changed, 21 insertions(+) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/ContactSyncAdapterService.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/ContactSyncAdapterService.java index 78d132df7..506a30b46 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/ContactSyncAdapterService.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/ContactSyncAdapterService.java @@ -21,6 +21,8 @@ import android.accounts.Account; import android.app.Service; import android.content.AbstractThreadedSyncAdapter; import android.content.ContentProviderClient; +import android.content.ContentResolver; +import android.content.Context; import android.content.Intent; import android.content.SyncResult; import android.os.Bundle; @@ -29,9 +31,11 @@ import android.os.IBinder; import android.os.Looper; import android.os.Message; import android.os.Messenger; +import android.provider.ContactsContract; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.KeychainApplication; +import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.helper.ContactHelper; import org.sufficientlysecure.keychain.helper.EmailKeyHelper; import org.sufficientlysecure.keychain.util.Log; @@ -94,6 +98,15 @@ public class ContactSyncAdapterService extends Service { } } + public static void requestSync(Context context) { + Bundle extras = new Bundle(); + extras.putBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, true); + ContentResolver.requestSync( + new Account(context.getString(R.string.app_name), Constants.PACKAGE_NAME), + ContactsContract.AUTHORITY, + extras); + } + @Override public IBinder onBind(Intent intent) { return new ContactSyncAdapter().getSyncAdapterBinder(); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java index ad2932f92..764acd552 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java @@ -453,6 +453,9 @@ public class KeychainIntentService extends IntentService setProgress(R.string.progress_done, 100, 100); + // make sure new data is synced into contacts + ContactSyncAdapterService.requestSync(this); + /* Output */ sendMessageToHandler(KeychainIntentServiceHandler.MESSAGE_OKAY, saveResult); } catch (Exception e) { @@ -501,6 +504,8 @@ public class KeychainIntentService extends IntentService if (result.mSecret > 0) { providerHelper.consolidateDatabaseStep1(this); } + // make sure new data is synced into contacts + ContactSyncAdapterService.requestSync(this); sendMessageToHandler(KeychainIntentServiceHandler.MESSAGE_OKAY, result); } catch (Exception e) { @@ -708,6 +713,9 @@ public class KeychainIntentService extends IntentService } if (success) { + // make sure new data is synced into contacts + ContactSyncAdapterService.requestSync(this); + sendMessageToHandler(KeychainIntentServiceHandler.MESSAGE_OKAY); } -- cgit v1.2.3 From 3ace5052e7b7b63c2de745b5626d9d08773174b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Wed, 20 Aug 2014 23:56:17 +0200 Subject: Comment extra in requestSync --- .../sufficientlysecure/keychain/service/ContactSyncAdapterService.java | 1 + 1 file changed, 1 insertion(+) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/ContactSyncAdapterService.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/ContactSyncAdapterService.java index 506a30b46..909c3031c 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/ContactSyncAdapterService.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/ContactSyncAdapterService.java @@ -100,6 +100,7 @@ public class ContactSyncAdapterService extends Service { public static void requestSync(Context context) { Bundle extras = new Bundle(); + // no need to wait for internet connection! extras.putBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, true); ContentResolver.requestSync( new Account(context.getString(R.string.app_name), Constants.PACKAGE_NAME), -- cgit v1.2.3 From 63ca81d8717bad8df9a9c159126612eb62867647 Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Thu, 21 Aug 2014 00:02:27 +0200 Subject: Copyright (C) 2014 Vincent Breitmoser --- .../java/org/sufficientlysecure/keychain/pgp/PgpKeyOperationTest.java | 1 + .../keychain/pgp/UncachedKeyringCanonicalizeTest.java | 1 + .../org/sufficientlysecure/keychain/pgp/UncachedKeyringMergeTest.java | 1 + .../java/org/sufficientlysecure/keychain/pgp/UncachedKeyringTest.java | 1 + .../sufficientlysecure/keychain/provider/ProviderHelperSaveTest.java | 1 + .../org/sufficientlysecure/keychain/support/KeyringTestingHelper.java | 3 ++- .../java/org/sufficientlysecure/keychain/util/FileImportCacheTest.java | 1 + .../org/sufficientlysecure/keychain/keyimport/ParcelableKeyRing.java | 1 + .../java/org/sufficientlysecure/keychain/pgp/CanonicalizedKeyRing.java | 1 + .../org/sufficientlysecure/keychain/pgp/CanonicalizedPublicKey.java | 1 + .../sufficientlysecure/keychain/pgp/CanonicalizedPublicKeyRing.java | 1 + .../org/sufficientlysecure/keychain/pgp/CanonicalizedSecretKey.java | 1 + .../sufficientlysecure/keychain/pgp/CanonicalizedSecretKeyRing.java | 1 + .../src/main/java/org/sufficientlysecure/keychain/pgp/KeyRing.java | 1 + .../main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java | 2 +- .../main/java/org/sufficientlysecure/keychain/pgp/UncachedKeyRing.java | 1 + .../java/org/sufficientlysecure/keychain/pgp/UncachedPublicKey.java | 1 + .../java/org/sufficientlysecure/keychain/pgp/UncachedSecretKey.java | 1 + .../java/org/sufficientlysecure/keychain/pgp/WrappedSignature.java | 1 + .../keychain/pgp/exception/PgpGeneralMsgIdException.java | 2 +- .../org/sufficientlysecure/keychain/provider/CachedPublicKeyRing.java | 1 + .../org/sufficientlysecure/keychain/provider/KeychainContract.java | 1 + .../org/sufficientlysecure/keychain/provider/KeychainDatabase.java | 1 + .../org/sufficientlysecure/keychain/provider/KeychainProvider.java | 1 + .../java/org/sufficientlysecure/keychain/provider/ProviderHelper.java | 1 + .../sufficientlysecure/keychain/provider/TemporaryStorageProvider.java | 1 + .../org/sufficientlysecure/keychain/service/KeychainIntentService.java | 1 + .../org/sufficientlysecure/keychain/service/OperationResultParcel.java | 1 + .../java/org/sufficientlysecure/keychain/service/OperationResults.java | 1 + .../org/sufficientlysecure/keychain/service/SaveKeyringParcel.java | 1 + .../java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java | 1 + .../main/java/org/sufficientlysecure/keychain/ui/KeyListActivity.java | 1 + .../main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java | 1 + .../java/org/sufficientlysecure/keychain/ui/LogDisplayActivity.java | 1 + .../java/org/sufficientlysecure/keychain/ui/LogDisplayFragment.java | 1 + .../main/java/org/sufficientlysecure/keychain/ui/ViewCertActivity.java | 1 + .../java/org/sufficientlysecure/keychain/ui/ViewKeyCertsFragment.java | 1 + .../java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java | 1 + 38 files changed, 39 insertions(+), 3 deletions(-) diff --git a/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperationTest.java b/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperationTest.java index 3c54c3528..ee312aedf 100644 --- a/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperationTest.java +++ b/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperationTest.java @@ -1,5 +1,6 @@ /* * Copyright (C) 2014 Dominik Schürmann + * Copyright (C) 2014 Vincent Breitmoser * * 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 diff --git a/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/UncachedKeyringCanonicalizeTest.java b/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/UncachedKeyringCanonicalizeTest.java index 1e4fb564a..670022a10 100644 --- a/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/UncachedKeyringCanonicalizeTest.java +++ b/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/UncachedKeyringCanonicalizeTest.java @@ -1,5 +1,6 @@ /* * Copyright (C) 2014 Dominik Schürmann + * Copyright (C) 2014 Vincent Breitmoser * * 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 diff --git a/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/UncachedKeyringMergeTest.java b/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/UncachedKeyringMergeTest.java index 6324b65d8..a04fe1f11 100644 --- a/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/UncachedKeyringMergeTest.java +++ b/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/UncachedKeyringMergeTest.java @@ -1,5 +1,6 @@ /* * Copyright (C) 2014 Dominik Schürmann + * Copyright (C) 2014 Vincent Breitmoser * * 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 diff --git a/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/UncachedKeyringTest.java b/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/UncachedKeyringTest.java index e25f0b081..8aac5d430 100644 --- a/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/UncachedKeyringTest.java +++ b/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/UncachedKeyringTest.java @@ -1,5 +1,6 @@ /* * Copyright (C) 2014 Dominik Schürmann + * Copyright (C) 2014 Vincent Breitmoser * * 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 diff --git a/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/provider/ProviderHelperSaveTest.java b/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/provider/ProviderHelperSaveTest.java index 065c1ffba..b5d950f59 100644 --- a/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/provider/ProviderHelperSaveTest.java +++ b/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/provider/ProviderHelperSaveTest.java @@ -1,5 +1,6 @@ /* * Copyright (C) 2014 Dominik Schürmann + * Copyright (C) 2014 Vincent Breitmoser * * 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 diff --git a/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/support/KeyringTestingHelper.java b/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/support/KeyringTestingHelper.java index 3bf046773..c0ba3c9bb 100644 --- a/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/support/KeyringTestingHelper.java +++ b/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/support/KeyringTestingHelper.java @@ -1,5 +1,6 @@ /* - * Copyright (C) Art O Cathain, Vincent Breitmoser + * Copyright (C) Art O Cathain + * Copyright (C) 2014 Vincent Breitmoser * * 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 diff --git a/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/util/FileImportCacheTest.java b/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/util/FileImportCacheTest.java index 23649e6f8..c5b53e95b 100644 --- a/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/util/FileImportCacheTest.java +++ b/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/util/FileImportCacheTest.java @@ -1,5 +1,6 @@ /* * Copyright (C) 2014 Dominik Schürmann + * Copyright (C) 2014 Vincent Breitmoser * * 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 diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/ParcelableKeyRing.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/ParcelableKeyRing.java index 8609a7082..55e6be9b9 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/ParcelableKeyRing.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/ParcelableKeyRing.java @@ -1,5 +1,6 @@ /* * Copyright (C) 2014 Dominik Schürmann + * Copyright (C) 2014 Vincent Breitmoser * * 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 diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CanonicalizedKeyRing.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CanonicalizedKeyRing.java index 1da66872d..8076a14f3 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CanonicalizedKeyRing.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CanonicalizedKeyRing.java @@ -1,5 +1,6 @@ /* * Copyright (C) 2014 Dominik Schürmann + * Copyright (C) 2014 Vincent Breitmoser * * 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 diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CanonicalizedPublicKey.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CanonicalizedPublicKey.java index ce6498df1..7a63a7a42 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CanonicalizedPublicKey.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CanonicalizedPublicKey.java @@ -1,5 +1,6 @@ /* * Copyright (C) 2014 Dominik Schürmann + * Copyright (C) 2014 Vincent Breitmoser * * 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 diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CanonicalizedPublicKeyRing.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CanonicalizedPublicKeyRing.java index 7b5d5d4be..2c27c5c37 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CanonicalizedPublicKeyRing.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CanonicalizedPublicKeyRing.java @@ -1,5 +1,6 @@ /* * Copyright (C) 2014 Dominik Schürmann + * Copyright (C) 2014 Vincent Breitmoser * * 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 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 af058b618..34eb9fb0b 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CanonicalizedSecretKey.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CanonicalizedSecretKey.java @@ -1,5 +1,6 @@ /* * Copyright (C) 2014 Dominik Schürmann + * Copyright (C) 2014 Vincent Breitmoser * * 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 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 80889f70d..bc7f001dc 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CanonicalizedSecretKeyRing.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CanonicalizedSecretKeyRing.java @@ -1,5 +1,6 @@ /* * Copyright (C) 2014 Dominik Schürmann + * Copyright (C) 2014 Vincent Breitmoser * * 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 diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/KeyRing.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/KeyRing.java index 35020b815..3ef4b336e 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/KeyRing.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/KeyRing.java @@ -1,5 +1,6 @@ /* * Copyright (C) 2014 Dominik Schürmann + * Copyright (C) 2014 Vincent Breitmoser * * 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 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 f3af51397..175045470 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2012-2014 Dominik Schürmann - * Copyright (C) 2010-2014 Thialfihar + * Copyright (C) 2014 Vincent Breitmoser * * 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 diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedKeyRing.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedKeyRing.java index 90abf05f5..caacb948e 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedKeyRing.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedKeyRing.java @@ -1,5 +1,6 @@ /* * Copyright (C) 2014 Dominik Schürmann + * Copyright (C) 2014 Vincent Breitmoser * * 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 diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedPublicKey.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedPublicKey.java index 341ca6d04..dda52d786 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedPublicKey.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedPublicKey.java @@ -1,5 +1,6 @@ /* * Copyright (C) 2014 Dominik Schürmann + * Copyright (C) 2014 Vincent Breitmoser * * 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 diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedSecretKey.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedSecretKey.java index 8dc28c2b3..4dfd93289 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedSecretKey.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedSecretKey.java @@ -1,5 +1,6 @@ /* * Copyright (C) 2014 Dominik Schürmann + * Copyright (C) 2014 Vincent Breitmoser * * 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 diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/WrappedSignature.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/WrappedSignature.java index ebd110dc5..03dbe4860 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/WrappedSignature.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/WrappedSignature.java @@ -1,5 +1,6 @@ /* * Copyright (C) 2014 Dominik Schürmann + * Copyright (C) 2014 Vincent Breitmoser * * 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 diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/exception/PgpGeneralMsgIdException.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/exception/PgpGeneralMsgIdException.java index 3700b4c34..aa0d86bb3 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/exception/PgpGeneralMsgIdException.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/exception/PgpGeneralMsgIdException.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2012-2014 Dominik Schürmann - * Copyright (C) 2010-2014 Thialfihar + * Copyright (C) 2014 Vincent Breitmoser * * 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 diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/CachedPublicKeyRing.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/CachedPublicKeyRing.java index e076fd9cc..21f0dddf6 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/CachedPublicKeyRing.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/CachedPublicKeyRing.java @@ -1,5 +1,6 @@ /* * Copyright (C) 2014 Dominik Schürmann + * Copyright (C) 2014 Vincent Breitmoser * * 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 diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainContract.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainContract.java index c239ea7f7..24d86dc4a 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainContract.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainContract.java @@ -1,5 +1,6 @@ /* * Copyright (C) 2012-2014 Dominik Schürmann + * Copyright (C) 2014 Vincent Breitmoser * * 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 diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainDatabase.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainDatabase.java index 041c4d904..36e94208d 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainDatabase.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainDatabase.java @@ -1,5 +1,6 @@ /* * Copyright (C) 2012-2014 Dominik Schürmann + * Copyright (C) 2014 Vincent Breitmoser * * 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 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 c5bf12143..b2a47cccd 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java @@ -1,6 +1,7 @@ /* * Copyright (C) 2012-2014 Dominik Schürmann * Copyright (C) 2010-2014 Thialfihar + * Copyright (C) 2014 Vincent Breitmoser * * 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 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 6447a180c..16ff2286b 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java @@ -1,5 +1,6 @@ /* * Copyright (C) 2012-2014 Dominik Schürmann + * Copyright (C) 2014 Vincent Breitmoser * * 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 diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/TemporaryStorageProvider.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/TemporaryStorageProvider.java index 87c0cc0a6..a65d222da 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/TemporaryStorageProvider.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/TemporaryStorageProvider.java @@ -1,5 +1,6 @@ /* * Copyright (C) 2014 Dominik Schürmann + * Copyright (C) 2014 Vincent Breitmoser * * 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 diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java index ad2932f92..b7596ea4b 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java @@ -1,5 +1,6 @@ /* * Copyright (C) 2012-2014 Dominik Schürmann + * Copyright (C) 2014 Vincent Breitmoser * * 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 diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/OperationResultParcel.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/OperationResultParcel.java index 3f48a2200..886f77068 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/OperationResultParcel.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/OperationResultParcel.java @@ -1,5 +1,6 @@ /* * Copyright (C) 2014 Dominik Schürmann + * Copyright (C) 2014 Vincent Breitmoser * * 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 diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/OperationResults.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/OperationResults.java index c59a7d172..f3d0b9e9b 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/OperationResults.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/OperationResults.java @@ -1,5 +1,6 @@ /* * Copyright (C) 2014 Dominik Schürmann + * Copyright (C) 2014 Vincent Breitmoser * * 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 diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/SaveKeyringParcel.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/SaveKeyringParcel.java index 490a8e738..6e06c4fa9 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/SaveKeyringParcel.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/SaveKeyringParcel.java @@ -1,5 +1,6 @@ /* * Copyright (C) 2014 Dominik Schürmann + * Copyright (C) 2014 Vincent Breitmoser * * 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 diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java index 728e6e1e1..8b99d474d 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java @@ -1,5 +1,6 @@ /* * Copyright (C) 2014 Dominik Schürmann + * Copyright (C) 2014 Vincent Breitmoser * Copyright (C) 2011 Senecaso * * Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListActivity.java index 7663b7366..e2ad241e2 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListActivity.java @@ -1,5 +1,6 @@ /* * Copyright (C) 2012-2014 Dominik Schürmann + * Copyright (C) 2014 Vincent Breitmoser * * 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 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 96a332d3e..b4676f9b7 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java @@ -1,5 +1,6 @@ /* * Copyright (C) 2013-2014 Dominik Schürmann + * Copyright (C) 2014 Vincent Breitmoser * * 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 diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/LogDisplayActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/LogDisplayActivity.java index b8386b144..248b8976a 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/LogDisplayActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/LogDisplayActivity.java @@ -1,5 +1,6 @@ /* * Copyright (C) 2014 Dominik Schürmann + * Copyright (C) 2014 Vincent Breitmoser * * 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 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 0e948bf7f..e524c3870 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/LogDisplayFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/LogDisplayFragment.java @@ -1,5 +1,6 @@ /* * Copyright (C) 2014 Dominik Schürmann + * Copyright (C) 2014 Vincent Breitmoser * * 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 diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewCertActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewCertActivity.java index 341e11d1d..48e9da87f 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewCertActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewCertActivity.java @@ -1,5 +1,6 @@ /* * Copyright (C) 2013-2014 Dominik Schürmann + * Copyright (C) 2014 Vincent Breitmoser * * 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 diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyCertsFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyCertsFragment.java index 5a55b0dad..786537b25 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyCertsFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyCertsFragment.java @@ -1,5 +1,6 @@ /* * Copyright (C) 2014 Dominik Schürmann + * Copyright (C) 2014 Vincent Breitmoser * * 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 diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java index 08243f06b..c37cb014e 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java @@ -1,5 +1,6 @@ /* * Copyright (C) 2014 Dominik Schürmann + * Copyright (C) 2014 Vincent Breitmoser * * 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 -- cgit v1.2.3 From d1ef355f559c31d14e19bf6cf55efb91c8c65444 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Thu, 21 Aug 2014 00:29:49 +0200 Subject: Fix result handling in account settings --- .../remote/ui/AccountSettingsFragment.java | 23 ++++++++++------------ .../keychain/ui/CreateKeyFinalFragment.java | 6 +++--- 2 files changed, 13 insertions(+), 16 deletions(-) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AccountSettingsFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AccountSettingsFragment.java index 8468f5eca..2cab23e51 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AccountSettingsFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AccountSettingsFragment.java @@ -36,6 +36,8 @@ import org.sufficientlysecure.keychain.pgp.KeyRing; import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException; import org.sufficientlysecure.keychain.provider.ProviderHelper; import org.sufficientlysecure.keychain.remote.AccountSettings; +import org.sufficientlysecure.keychain.service.OperationResultParcel; +import org.sufficientlysecure.keychain.service.OperationResults; import org.sufficientlysecure.keychain.ui.CreateKeyActivity; import org.sufficientlysecure.keychain.ui.SelectSecretKeyLayoutFragment; import org.sufficientlysecure.keychain.ui.adapter.KeyValueSpinnerAdapter; @@ -177,24 +179,19 @@ public class AccountSettingsFragment extends Fragment implements switch (requestCode) { case REQUEST_CODE_CREATE_KEY: { if (resultCode == Activity.RESULT_OK) { - // select newly created key - try { - long masterKeyId = new ProviderHelper(getActivity()) - .getCachedPublicKeyRing(data.getData()) - .extractOrGetMasterKeyId(); - mSelectKeyFragment.selectKey(masterKeyId); - } catch (PgpGeneralException e) { - Log.e(Constants.TAG, "key not found!", e); + if (data != null && data.hasExtra(OperationResultParcel.EXTRA_RESULT)) { + OperationResults.SaveKeyringResult result = data.getParcelableExtra(OperationResultParcel.EXTRA_RESULT); + mSelectKeyFragment.selectKey(result.mRingMasterKeyId); + } else { + Log.e(Constants.TAG, "missing result!"); } } break; } - - default: - super.onActivityResult(requestCode, resultCode, data); - - break; } + + // execute activity's onActivityResult to show log notify + super.onActivityResult(requestCode, resultCode, data); } /** 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 076f52a10..d804b9b70 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyFinalFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyFinalFragment.java @@ -187,7 +187,7 @@ public class CreateKeyFinalFragment extends Fragment { getActivity().startService(intent); } - private void uploadKey(final OperationResults.SaveKeyringResult editKeyResult) { + private void uploadKey(final OperationResults.SaveKeyringResult saveKeyResult) { // Send all information needed to service to upload key in other thread final Intent intent = new Intent(getActivity(), KeychainIntentService.class); @@ -195,7 +195,7 @@ public class CreateKeyFinalFragment extends Fragment { // set data uri as path to keyring Uri blobUri = KeychainContract.KeyRings.buildUnifiedKeyRingUri( - editKeyResult.mRingMasterKeyId); + saveKeyResult.mRingMasterKeyId); intent.setData(blobUri); // fill values for this action @@ -221,7 +221,7 @@ public class CreateKeyFinalFragment extends Fragment { //Notify.Style.INFO); Intent data = new Intent(); - data.putExtra(OperationResultParcel.EXTRA_RESULT, editKeyResult); + data.putExtra(OperationResultParcel.EXTRA_RESULT, saveKeyResult); getActivity().setResult(Activity.RESULT_OK, data); getActivity().finish(); } -- cgit v1.2.3 From 4c6783215fc9007542feaaaeaa32e72800584c30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Thu, 21 Aug 2014 00:33:52 +0200 Subject: cleanup --- .../sufficientlysecure/keychain/pgp/PgpHelper.java | 71 ---------------------- 1 file changed, 71 deletions(-) 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 1cf027721..db360f810 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpHelper.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpHelper.java @@ -29,7 +29,6 @@ import org.sufficientlysecure.keychain.util.Log; import java.io.File; import java.io.IOException; -import java.io.InputStream; import java.io.RandomAccessFile; import java.security.SecureRandom; import java.util.regex.Pattern; @@ -68,76 +67,6 @@ public class PgpHelper { } } -// public static final class content { -// public static final int unknown = 0; -// public static final int encrypted_data = 1; -// public static final int keys = 2; -// } -// -// public static int getStreamContent(Context context, InputStream inStream) throws IOException { -// -// InputStream in = PGPUtil.getDecoderStream(inStream); -// PGPObjectFactory pgpF = new PGPObjectFactory(in); -// Object object = pgpF.nextObject(); -// while (object != null) { -// if (object instanceof PGPPublicKeyRing || object instanceof PGPSecretKeyRing) { -// return Id.content.keys; -// } else if (object instanceof PGPEncryptedDataList) { -// return Id.content.encrypted_data; -// } -// object = pgpF.nextObject(); -// } -// -// return Id.content.unknown; -// } - - /** - * Generate a random filename - * - * @param length - * @return - */ - public static String generateRandomFilename(int length) { - SecureRandom random = new SecureRandom(); - - byte bytes[] = new byte[length]; - random.nextBytes(bytes); - String result = ""; - for (int i = 0; i < length; ++i) { - int v = (bytes[i] + 256) % 64; - if (v < 10) { - result += (char) ('0' + v); - } else if (v < 36) { - result += (char) ('A' + v - 10); - } else if (v < 62) { - result += (char) ('a' + v - 36); - } else if (v == 62) { - result += '_'; - } else if (v == 63) { - result += '.'; - } - } - return result; - } - - /** - * Go once through stream to get length of stream. The length is later used to display progress - * when encrypting/decrypting - * - * @param in - * @return - * @throws IOException - */ - public static long getLengthOfStream(InputStream in) throws IOException { - long size = 0; - long n = 0; - byte dummy[] = new byte[0x10000]; - while ((n = in.read(dummy)) > 0) { - size += n; - } - return size; - } - /** * Deletes file securely by overwriting it with random data before deleting it. *

                                                      -- cgit v1.2.3 From 41052d6f8f9a1acb9ebbd850c241e6f1d62a9a2b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Thu, 21 Aug 2014 00:36:15 +0200 Subject: Pull from transifex --- OpenKeychain/src/main/res/values-de/strings.xml | 44 ++++++++++++------------- OpenKeychain/src/main/res/values-es/strings.xml | 6 ---- OpenKeychain/src/main/res/values-fr/strings.xml | 6 ---- OpenKeychain/src/main/res/values-it/strings.xml | 1 - OpenKeychain/src/main/res/values-ja/strings.xml | 6 ---- OpenKeychain/src/main/res/values-uk/strings.xml | 1 - 6 files changed, 22 insertions(+), 42 deletions(-) diff --git a/OpenKeychain/src/main/res/values-de/strings.xml b/OpenKeychain/src/main/res/values-de/strings.xml index d746f6fb3..3b8fe1e36 100644 --- a/OpenKeychain/src/main/res/values-de/strings.xml +++ b/OpenKeychain/src/main/res/values-de/strings.xml @@ -237,24 +237,24 @@ Fertig. Abbrechen - wird gespeichert… - wird importiert… - wird exportiert… - hochladen... + Wird gespeichert… + Wird importiert… + Wird exportiert… + Wird hochgeladen... Schlüssel wird erstellt… Hauptschlüssel wird erstellt… - erzeuge neuen RSA Schlüssel... - erzeuge neuen DSA Schlüssel... - erzeuge neuen ElGamal Schlüssel... - verändere Schlüsselbund... - entsperre Schlüsselbund... - füge User ID hinzu... - Wiederrufe Benutzerkennungen... - ändere Haupt User ID... - verändere Unterschlüssel... - Widerrufe Unterschlüssel... - füge Unterschlüssel hinzu... - ändere Passwort... + Erzeuge neuen RSA-Schlüssel... + Erzeuge neuen DSA-Schlüssel... + Erzeuge neuen ElGamal-Schlüssel... + Schlüsselbund wird verändert... + Schlüsselbund wird entsperrt... + User-ID wird hinzugefügt... + User-IDs werden widerrufen... + Primäre User-ID wird geändert... + Unterschlüssel werden verändert... + Unterschlüssel wird widerrufen... + Unterschlüssel wird hinzugefügt... + Passwort wird geändert... Schlüssel wird exportiert… Schlüssel werden exportiert… @@ -268,8 +268,8 @@ Signatur wird erstellt… Signatur wird verarbeitet… Signatur wird verifiziert… - wird signiert… - beglaubige... + Wird signiert… + Wird beglaubige... Daten werden gelesen… Schlüssel wird gesucht… Daten werden entpackt… @@ -303,12 +303,12 @@ Schlüsselserver Datei/Zwischenablage - QR Kode/NFC + QR-Code/NFC Keybase.io Ausgewählte Schlüssel importieren Falsch formatierter QR-Code! Bitte erneut versuchen! Der Fingerabdruck ist zu kurz (< 16 Zeichen) - QR Kode Einlesen... + QR-Code Einlesen... 1 Schlüssel erfolgreich importiert @@ -349,8 +349,8 @@ SHA-256 der Paketsignatur Konten Keine Konten mit dieser Anwendung verknüpft. - Die Anwendung verlangt die Erstellung eines neuen Accounts. Bitte wähle einen deiner existierenden Schlüssel aus oder erstelle einen Neuen.\nAnwendugen sind auf die Nutzung der Schlüssel beschränkt die du hier auswählst! - Folgende Anwendung möchte Nachrichten ver-/entschlüsseln und in Ihrem Namen signieren\nZugriff erlauben?\n\nVORSICHT: Sollten Sie nicht wissen warum dieses Fenster erscheint, sollten Sie den Zugriff nicht gewähren! Sie können Zugriffe später über das Menü \'Anwendungen\' widerrufen. + Die App verlangt die Erstellung eines neuen Accounts. Bitte wähle einen deiner existierenden Schlüssel aus oder erstelle einen neuen.\nApps können nur hier ausgewählte Schlüssel nutzen. + Folgende Anwendung möchte Nachrichten ver-/entschlüsseln und in Ihrem Namen signieren.\nZugriff erlauben?\n\nVORSICHT: Sollten Sie nicht wissen warum dieses Fenster erscheint, sollten Sie den Zugriff verbieten! Sie können Zugriffe später über das Menü \'Apps\' widerrufen. Zugriff erlauben Zugriff verbieten Bitte einen Schlüssel auswählen! diff --git a/OpenKeychain/src/main/res/values-es/strings.xml b/OpenKeychain/src/main/res/values-es/strings.xml index 115da1278..cc1a29c34 100644 --- a/OpenKeychain/src/main/res/values-es/strings.xml +++ b/OpenKeychain/src/main/res/values-es/strings.xml @@ -275,7 +275,6 @@ descomprimiendo los datos... verificando la integridad... borrando \'%s\' de forma segura… - reimportando base de datos... Nombre/Correo electrónico/Identidad de clave... Nombre/Correo electrónico/Prueba/Clave... @@ -601,14 +600,12 @@ ¡Excepción con la firma! Modificando certificaciones maestras Cambiando frase contraseña para el juego de claves (keyring)... - Cambiando frase contraseña para la subclave %s Fallo al establecer nueva frase contraseña, intentándolo de nuevo con una antigua frase contraseña vacía ¡La frase contraseña para la subclave no pudo cambiarse! (¿Tiene la subclave una diferente de la de las otras claves?) Reemplazando certificado de la anterior identidad de usuario primaria Generando nuevo certificado para nueva identidad de usuario primaria Modificando subclave %s ¡Se intentó operar sobre una subclave desaparecida %s! - Generando nueva subclave %2$s de %1$s bits Nueva identidad de subclave: %s ¡La fecha de expiración no puede ser del pasado! Revocando subclave %s @@ -621,7 +618,6 @@ Desbloqueando juego de claves Consolidando base de datos - ¡La consolidación se inició cuando no había una base de datos cacheada! Probablemente esto es un error de programación, por favor consigne un informe de fallos. Guardando juegos de claves secretas (privadas) Guardando juegos de claves públicas Limpiando base de datos @@ -651,7 +647,6 @@ No hay claves públicas a reimportar, omitiendo... Excepción borrando fichero de caché público - Excepción borrando fichero de caché público Haga clic para limpiar las frases contraseña almacenadas en caché OpenKeychain ha almacenado en caché %d frases contraseña @@ -665,7 +660,6 @@ Identidad <desconocido> No hay certificados para esta clave - Sólo los certificados creados con sus claves y auto-certificados son mostrados aquí. Identidades a certificar Razón de la revocación Estado de la verificación diff --git a/OpenKeychain/src/main/res/values-fr/strings.xml b/OpenKeychain/src/main/res/values-fr/strings.xml index 41b7c24ae..e25f4cd05 100644 --- a/OpenKeychain/src/main/res/values-fr/strings.xml +++ b/OpenKeychain/src/main/res/values-fr/strings.xml @@ -275,7 +275,6 @@ décompression des données... vérification de l\'intégrité... suppression sûre de « %s »... - réimportation de la base de données... Nom/courriel/ID de clef... Nom/courriel/preuve/clef... @@ -601,14 +600,12 @@ Exception de signature ! Modification des certifications maîtresses Changement de la phrase de passe pour le trousseau... - Changement de la phrase de passe pour la sous-clef %s Échec lors de la définition de la nouvelle phrase de passe, nouvel essai avec une ancienne phrase de passe vide La phrase de passe de la sous-clef n\'a pas pu être changée ! (Est-elle différente des autres clefs ?) Remplacement du certificat de l\'ID d\'utilisateur principal précédent Génération d\'un nouveau certificat pour le nouvel ID d\'utilisateur principal Modification de la sous-clef %s Une action a été tentée sur la sous-clef manquante %s ! - Génération d\'une nouvelle sous-clef %2$s de %1$s bit Nouvelle ID de sous-clef : %s La date d\'expiration ne peut pas être dans le passé ! Révocation de la sous-clef %s @@ -621,7 +618,6 @@ Déverrouillage du trousseau Consolidation de la base de données - La consolidation a commencé alors qu\'aucune base de données n\'était en cache ! Ceci est probablement une erreur de programmation, veuillez remplir un rapport de bogue ! Enregistrement des trousseaux secrets Enregistrement des trousseaux publiques Nettoyage de la base de données @@ -651,7 +647,6 @@ Aucune clef secrète à réimporter, étape ignorée... Une exception a eu lieu lors de la suppression du fichier de cache publique - Une exception a eu lieu lors de la suppression du fichier de cache publique Cliquer ici pour effacer les phrases de passe mises en cache OpenKeychain a mis en cache %d phrases de passe @@ -665,7 +660,6 @@ identité <inconnu> Aucun certificat pour cette clef - Seuls les certificats créés avec vos clefs et les auto-certificats sont affichés ici. Identités à certifier Raison de la révocation État de vérification diff --git a/OpenKeychain/src/main/res/values-it/strings.xml b/OpenKeychain/src/main/res/values-it/strings.xml index 7a5289313..4cb029508 100644 --- a/OpenKeychain/src/main/res/values-it/strings.xml +++ b/OpenKeychain/src/main/res/values-it/strings.xml @@ -592,7 +592,6 @@ Sostituzione certificato del ID utente primario precedente Generazione di un nuovo certificato per il nuovo ID utente primario Modifica sottochiave %s - Generazione nuovi %1$s bit %2$s sottochiave Nuovo ID sottochiave: %s Revoca sottochiave %s Portachiavi modificato con successo diff --git a/OpenKeychain/src/main/res/values-ja/strings.xml b/OpenKeychain/src/main/res/values-ja/strings.xml index bf2f83e66..724abeab4 100644 --- a/OpenKeychain/src/main/res/values-ja/strings.xml +++ b/OpenKeychain/src/main/res/values-ja/strings.xml @@ -270,7 +270,6 @@ データの展開中... 完全性の検証中... \'%s\' を完全に削除中… - データベースの再インポート中... 名前/メール/鍵ID... 名前/メール/証明/鍵... @@ -587,14 +586,12 @@ 署名例外! マスター認証を変更 鍵輪のパスフレーズの変更中... - 副鍵 %s のパスフレーズの変更中 新しいパスフレーズの設定に失敗しました、空の古いパスフレーズで再度試してください 副鍵のパスフレーズは変更されていません! (他の鍵とは異なるになっていませんか?) 以前の主ユーザIDで証明を入れ替え中 新しい主ユーザIDで新しい証明を生成中 副鍵 %s を変更中 見付からない副鍵 %s の操作をしようとした! - 新しい %1$s ビットの %2$s 副鍵の生成中 新しい副鍵 ID: %s 期限切れ日を過去にはできません! 副鍵 %s を破棄中 @@ -607,7 +604,6 @@ 鍵輪のロック解除中 データベースの統合中 - データベースでキャッシュせずに統合を開始します! これはおそらくプログラミングのエラーなので、バグレポートの提出をお願いします! 秘密鍵の鍵輪を保存中 公開鍵の鍵輪を保存中 データベースの消去中 @@ -634,7 +630,6 @@ 再インポートで秘密鍵がありません、スキップします... 公開鍵キャッシュファイルの削除例外 - 公開鍵キャッシュファイルの削除例外 クリックしてパスフレーズのキャッシュをクリア OpenKeychainは %d のパスフレーズをキャッシュしています @@ -648,7 +643,6 @@ ユーザID <不明> この鍵に証明がない - あなたの鍵でだけ生成された証明と自己証明がここに表示されます ユーザIDを検証 破棄の理由 検証ステータス diff --git a/OpenKeychain/src/main/res/values-uk/strings.xml b/OpenKeychain/src/main/res/values-uk/strings.xml index 15bb9ad3e..77458e93f 100644 --- a/OpenKeychain/src/main/res/values-uk/strings.xml +++ b/OpenKeychain/src/main/res/values-uk/strings.xml @@ -583,7 +583,6 @@ Генерується новий сертифікат для ІД нового первинного користувача Змінюється підключ %s Спробували працювати із втраченим підключем %s! - Генерується новий %1$s біт %2$s підключа Новий ід підключа: %s Дата завершення дії не може бути у минулому! Відкликається підключ %s -- cgit v1.2.3 From e1d60c698cf5f825663a0a336dfb8eee1b26614b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Thu, 21 Aug 2014 00:46:30 +0200 Subject: v2.8 beta1 --- OpenKeychain/src/main/AndroidManifest.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/OpenKeychain/src/main/AndroidManifest.xml b/OpenKeychain/src/main/AndroidManifest.xml index a1ad7139d..b11d3fd69 100644 --- a/OpenKeychain/src/main/AndroidManifest.xml +++ b/OpenKeychain/src/main/AndroidManifest.xml @@ -3,8 +3,8 @@ xmlns:tools="http://schemas.android.com/tools" package="org.sufficientlysecure.keychain" android:installLocation="auto" - android:versionCode="27000" - android:versionName="2.7"> + android:versionCode="27001" + android:versionName="2.8 beta1"> - - + \ No newline at end of file diff --git a/OpenKeychain/src/main/res/xml/gen_preferences.xml b/OpenKeychain/src/main/res/xml/gen_preferences.xml index 10be61b6a..fd3c6c31a 100644 --- a/OpenKeychain/src/main/res/xml/gen_preferences.xml +++ b/OpenKeychain/src/main/res/xml/gen_preferences.xml @@ -1,22 +1,5 @@ - - - + - - 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 . ---> -

                                                      - - 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 . ---> - diff --git a/OpenKeychain/src/main/res/xml/sync_adapter_desc.xml b/OpenKeychain/src/main/res/xml/sync_adapter_desc.xml index d8fe60e91..bbfd41842 100644 --- a/OpenKeychain/src/main/res/xml/sync_adapter_desc.xml +++ b/OpenKeychain/src/main/res/xml/sync_adapter_desc.xml @@ -1,6 +1,6 @@ \ No newline at end of file + android:contentAuthority="com.android.contacts" + android:accountType="org.sufficientlysecure.keychain" + android:supportsUploading="false" + android:userVisible="true" /> \ No newline at end of file -- cgit v1.2.3 From 2930f83b2a49735a840f2adad4a4c3cb83ac07e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Thu, 21 Aug 2014 11:19:44 +0200 Subject: Change account type --- .../src/main/java/org/sufficientlysecure/keychain/Constants.java | 3 +++ .../java/org/sufficientlysecure/keychain/KeychainApplication.java | 4 ++-- .../keychain/service/ContactSyncAdapterService.java | 4 ++-- .../sufficientlysecure/keychain/service/KeychainIntentService.java | 6 +++--- OpenKeychain/src/main/res/xml/account_desc.xml | 2 +- OpenKeychain/src/main/res/xml/sync_adapter_desc.xml | 2 +- 6 files changed, 12 insertions(+), 9 deletions(-) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/Constants.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/Constants.java index 78b66464b..9f84da815 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/Constants.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/Constants.java @@ -35,6 +35,9 @@ public final class Constants { public static final String PACKAGE_NAME = "org.sufficientlysecure.keychain"; + public static final String ACCOUNT_NAME = "OpenKeychain"; + public static final String ACCOUNT_TYPE = PACKAGE_NAME + ".account"; + // as defined in http://tools.ietf.org/html/rfc3156, section 7 public static final String NFC_MIME = "application/pgp-keys"; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/KeychainApplication.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/KeychainApplication.java index ca9af8a9d..964342c60 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/KeychainApplication.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/KeychainApplication.java @@ -112,9 +112,9 @@ public class KeychainApplication extends Application { public static void setupAccountAsNeeded(Context context) { AccountManager manager = AccountManager.get(context); - Account[] accounts = manager.getAccountsByType(Constants.PACKAGE_NAME); + Account[] accounts = manager.getAccountsByType(Constants.ACCOUNT_TYPE); if (accounts == null || accounts.length == 0) { - Account account = new Account(context.getString(R.string.app_name), Constants.PACKAGE_NAME); + Account account = new Account(Constants.ACCOUNT_NAME, Constants.ACCOUNT_TYPE); manager.addAccountExplicitly(account, null, null); ContentResolver.setIsSyncable(account, ContactsContract.AUTHORITY, 1); ContentResolver.setSyncAutomatically(account, ContactsContract.AUTHORITY, true); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/ContactSyncAdapterService.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/ContactSyncAdapterService.java index 909c3031c..fbe914b78 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/ContactSyncAdapterService.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/ContactSyncAdapterService.java @@ -98,12 +98,12 @@ public class ContactSyncAdapterService extends Service { } } - public static void requestSync(Context context) { + public static void requestSync() { Bundle extras = new Bundle(); // no need to wait for internet connection! extras.putBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, true); ContentResolver.requestSync( - new Account(context.getString(R.string.app_name), Constants.PACKAGE_NAME), + new Account(Constants.ACCOUNT_NAME, Constants.ACCOUNT_TYPE), ContactsContract.AUTHORITY, extras); } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java index 246804383..021e6bc07 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java @@ -455,7 +455,7 @@ public class KeychainIntentService extends IntentService setProgress(R.string.progress_done, 100, 100); // make sure new data is synced into contacts - ContactSyncAdapterService.requestSync(this); + ContactSyncAdapterService.requestSync(); /* Output */ sendMessageToHandler(KeychainIntentServiceHandler.MESSAGE_OKAY, saveResult); @@ -506,7 +506,7 @@ public class KeychainIntentService extends IntentService providerHelper.consolidateDatabaseStep1(this); } // make sure new data is synced into contacts - ContactSyncAdapterService.requestSync(this); + ContactSyncAdapterService.requestSync(); sendMessageToHandler(KeychainIntentServiceHandler.MESSAGE_OKAY, result); } catch (Exception e) { @@ -715,7 +715,7 @@ public class KeychainIntentService extends IntentService if (success) { // make sure new data is synced into contacts - ContactSyncAdapterService.requestSync(this); + ContactSyncAdapterService.requestSync(); sendMessageToHandler(KeychainIntentServiceHandler.MESSAGE_OKAY); } diff --git a/OpenKeychain/src/main/res/xml/account_desc.xml b/OpenKeychain/src/main/res/xml/account_desc.xml index 41ce8fe48..d29395202 100644 --- a/OpenKeychain/src/main/res/xml/account_desc.xml +++ b/OpenKeychain/src/main/res/xml/account_desc.xml @@ -1,5 +1,5 @@ diff --git a/OpenKeychain/src/main/res/xml/sync_adapter_desc.xml b/OpenKeychain/src/main/res/xml/sync_adapter_desc.xml index bbfd41842..d05dc6918 100644 --- a/OpenKeychain/src/main/res/xml/sync_adapter_desc.xml +++ b/OpenKeychain/src/main/res/xml/sync_adapter_desc.xml @@ -1,6 +1,6 @@ \ No newline at end of file -- cgit v1.2.3 From f0ff8d22226f4f3b65b5b5ec9d6de47b181cefda Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Thu, 21 Aug 2014 11:25:41 +0200 Subject: Add sync properties --- OpenKeychain/src/main/AndroidManifest.xml | 5 ++++- OpenKeychain/src/main/res/xml/sync_adapter_desc.xml | 4 +++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/OpenKeychain/src/main/AndroidManifest.xml b/OpenKeychain/src/main/AndroidManifest.xml index b11d3fd69..9e903e372 100644 --- a/OpenKeychain/src/main/AndroidManifest.xml +++ b/OpenKeychain/src/main/AndroidManifest.xml @@ -634,7 +634,10 @@ android:resource="@xml/account_desc" /> - + diff --git a/OpenKeychain/src/main/res/xml/sync_adapter_desc.xml b/OpenKeychain/src/main/res/xml/sync_adapter_desc.xml index d05dc6918..6871e1a5d 100644 --- a/OpenKeychain/src/main/res/xml/sync_adapter_desc.xml +++ b/OpenKeychain/src/main/res/xml/sync_adapter_desc.xml @@ -3,4 +3,6 @@ android:contentAuthority="com.android.contacts" android:accountType="org.sufficientlysecure.keychain.account" android:supportsUploading="false" - android:userVisible="true" /> \ No newline at end of file + android:userVisible="true" + android:allowParallelSyncs="false" + android:isAlwaysSyncable="true" /> \ No newline at end of file -- cgit v1.2.3 From 0c1e65bc8bbfed59d299e2f0ca7a6a30eef22664 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Thu, 21 Aug 2014 11:33:42 +0200 Subject: No need for setSyncAutomatically, this is only for network tickles --- .../java/org/sufficientlysecure/keychain/KeychainApplication.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/KeychainApplication.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/KeychainApplication.java index 964342c60..aee6a5d70 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/KeychainApplication.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/KeychainApplication.java @@ -115,9 +115,11 @@ public class KeychainApplication extends Application { Account[] accounts = manager.getAccountsByType(Constants.ACCOUNT_TYPE); if (accounts == null || accounts.length == 0) { Account account = new Account(Constants.ACCOUNT_NAME, Constants.ACCOUNT_TYPE); - manager.addAccountExplicitly(account, null, null); - ContentResolver.setIsSyncable(account, ContactsContract.AUTHORITY, 1); - ContentResolver.setSyncAutomatically(account, ContactsContract.AUTHORITY, true); + if (manager.addAccountExplicitly(account, null, null)) { + ContentResolver.setIsSyncable(account, ContactsContract.AUTHORITY, 1); + } else { + Log.e(Constants.TAG, "Adding account failed!"); + } } } -- cgit v1.2.3 From 3c46c3c2dfd4ec6ec8b91eb43246c7d579f9b95d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Thu, 21 Aug 2014 11:36:47 +0200 Subject: Add account only on jelly bean and above --- .../keychain/KeychainApplication.java | 20 ++++++++++++-------- .../keychain/helper/ContactHelper.java | 3 +++ 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/KeychainApplication.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/KeychainApplication.java index aee6a5d70..37af95e28 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/KeychainApplication.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/KeychainApplication.java @@ -25,6 +25,7 @@ import android.content.Context; import android.content.Intent; import android.graphics.PorterDuff; import android.graphics.drawable.Drawable; +import android.os.Build; import android.os.Environment; import android.provider.ContactsContract; @@ -111,14 +112,17 @@ public class KeychainApplication extends Application { } public static void setupAccountAsNeeded(Context context) { - AccountManager manager = AccountManager.get(context); - Account[] accounts = manager.getAccountsByType(Constants.ACCOUNT_TYPE); - if (accounts == null || accounts.length == 0) { - Account account = new Account(Constants.ACCOUNT_NAME, Constants.ACCOUNT_TYPE); - if (manager.addAccountExplicitly(account, null, null)) { - ContentResolver.setIsSyncable(account, ContactsContract.AUTHORITY, 1); - } else { - Log.e(Constants.TAG, "Adding account failed!"); + // only enabled for Jelly Bean because we need some newer methods in our sync adapter + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { + AccountManager manager = AccountManager.get(context); + Account[] accounts = manager.getAccountsByType(Constants.ACCOUNT_TYPE); + if (accounts == null || accounts.length == 0) { + Account account = new Account(Constants.ACCOUNT_NAME, Constants.ACCOUNT_TYPE); + if (manager.addAccountExplicitly(account, null, null)) { + ContentResolver.setIsSyncable(account, ContactsContract.AUTHORITY, 1); + } else { + Log.e(Constants.TAG, "Adding account failed!"); + } } } } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/helper/ContactHelper.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/helper/ContactHelper.java index 96e1b25af..b7c4dcb80 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/helper/ContactHelper.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/helper/ContactHelper.java @@ -19,6 +19,7 @@ package org.sufficientlysecure.keychain.helper; import android.accounts.Account; import android.accounts.AccountManager; +import android.annotation.TargetApi; import android.content.ContentProviderOperation; import android.content.ContentResolver; import android.content.ContentUris; @@ -252,6 +253,7 @@ public class ContactHelper { return new ArrayList(names); } + @TargetApi(Build.VERSION_CODES.JELLY_BEAN) public static Uri dataUriFromContactUri(Context context, Uri contactUri) { Cursor contactMasterKey = context.getContentResolver().query(contactUri, new String[]{ContactsContract.Data.DATA2}, null, null, null, null); @@ -367,6 +369,7 @@ public class ContactHelper { * * @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, -- cgit v1.2.3 From 562e379c56a96bc54df7b5ee4c5843771a14461a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Thu, 21 Aug 2014 11:40:48 +0200 Subject: Fix nullpointer when revoking keys --- .../main/java/org/sufficientlysecure/keychain/ui/EditKeyFragment.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyFragment.java index f2d6d4c13..28692f638 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyFragment.java @@ -339,7 +339,8 @@ public class EditKeyFragment extends LoaderFragment implements } else { mSaveKeyringParcel.mRevokeUserIds.add(userId); // not possible to revoke and change to primary user id - if (mSaveKeyringParcel.mChangePrimaryUserId.equals(userId)) { + if (mSaveKeyringParcel.mChangePrimaryUserId != null + && mSaveKeyringParcel.mChangePrimaryUserId.equals(userId)) { mSaveKeyringParcel.mChangePrimaryUserId = null; } } -- cgit v1.2.3 From acff54d7d75f2868cc42f3b73ba75056eb1949eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Thu, 21 Aug 2014 11:44:55 +0200 Subject: 2.8 beta2 --- OpenKeychain/src/main/AndroidManifest.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/OpenKeychain/src/main/AndroidManifest.xml b/OpenKeychain/src/main/AndroidManifest.xml index 9e903e372..e4e671b97 100644 --- a/OpenKeychain/src/main/AndroidManifest.xml +++ b/OpenKeychain/src/main/AndroidManifest.xml @@ -3,8 +3,8 @@ xmlns:tools="http://schemas.android.com/tools" package="org.sufficientlysecure.keychain" android:installLocation="auto" - android:versionCode="27001" - android:versionName="2.8 beta1"> + android:versionCode="27002" + android:versionName="2.8 beta2"> Nachricht Datei @@ -83,7 +83,7 @@ Passwort Passwort wiederholen Algorithmus - ASCII Armor Datei + Datei: ASCII Armor Datei: ASCII Armor Lass andere wissen dass du OpenKeychain nutzt Fügt \'OpenKeychain v2.7\' zu OpenPGP Signaturen, DAten und exportierten Schlüsseln hinzu @@ -116,8 +116,8 @@ <kein Schlüssel> kann verschlüsseln kann signieren - kann bestätigen - kann nicht bestätigen + kann beglaubigen + kann nicht beglaubigen abgelaufen widerrufen @@ -170,9 +170,9 @@ Das Passwort bitte zweimal eingeben. Mindestens einen Schlüssel zum Verschlüsseln auswählen. Mindestens einen Schlüssel zum Verschlüsseln oder einen zum Signieren auswählen. - Bitte angeben, in welche Datei verschlüsselt werden soll.\nWARNUNG: Datei wird überschrieben, wenn sie bereits existiert. - Bitte angeben, in welche Datei entschlüsselt werden soll.\nWARNUNG: Datei wird überschrieben, wenn sie bereits existiert. - Bitte angeben, in welche Datei exportiert werden soll.\nWARNUNG: Datei wird überschrieben, wenn sie bereits existiert. + Bitte angeben in welche Datei verschlüsselt werden soll.\nWARNUNG: Datei wird überschrieben, wenn sie bereits existiert. + Bitte angeben,in welche Datei entschlüsselt werden soll.\nWARNUNG: Datei wird überschrieben, wenn sie bereits existiert. + Bitte angeben in welche Datei exportiert werden soll.\nWARNUNG: Datei wird überschrieben, wenn sie bereits existiert. Möchtest du wirklich alle ausgewählten öffentlichen Schlüssel löschen?\nDies kann nicht rückgängig gemacht werden! Soll der PRIVATE Schlüssel \'%s\' wirklich gelöscht werden?\nDies kann nicht rückgängig gemacht werden! Soll der öffentliche Schlüssel \'%s\' wirklich gelöscht werden?\nDies kann nicht rückgängig gemacht werden! diff --git a/OpenKeychain/src/main/res/values-es/strings.xml b/OpenKeychain/src/main/res/values-es/strings.xml index cc1a29c34..9266950d2 100644 --- a/OpenKeychain/src/main/res/values-es/strings.xml +++ b/OpenKeychain/src/main/res/values-es/strings.xml @@ -275,6 +275,9 @@ descomprimiendo los datos... verificando la integridad... borrando \'%s\' de forma segura… + borrando claves... + consolidación: guardando en caché... + consolidación: reimportando Nombre/Correo electrónico/Identidad de clave... Nombre/Correo electrónico/Prueba/Clave... @@ -600,12 +603,14 @@ ¡Excepción con la firma! Modificando certificaciones maestras Cambiando frase contraseña para el juego de claves (keyring)... + Re-cifrando subclave %s con nueva frase contraseña Fallo al establecer nueva frase contraseña, intentándolo de nuevo con una antigua frase contraseña vacía ¡La frase contraseña para la subclave no pudo cambiarse! (¿Tiene la subclave una diferente de la de las otras claves?) Reemplazando certificado de la anterior identidad de usuario primaria Generando nuevo certificado para nueva identidad de usuario primaria Modificando subclave %s ¡Se intentó operar sobre una subclave desaparecida %s! + Añadiendo nueva subclave de tipo %2$s (%1$s bits) Nueva identidad de subclave: %s ¡La fecha de expiración no puede ser del pasado! Revocando subclave %s @@ -615,9 +620,11 @@ Revocando identidad de usuario %s ¡La identidad de usuario no debe estar vacía! ¡Error desbloqueando juego de claves! - Desbloqueando juego de claves + Desbloqueando juego de claves (keyring) Consolidando base de datos + ¡La consolidación se inició cuando ninguna base de datos estaba cacheada! Probablemente esto es un error de programación, por favor consigne un informe de fallo. + ¡Consolidación abortada, ejecutándose ya en otro hilo! Guardando juegos de claves secretas (privadas) Guardando juegos de claves públicas Limpiando base de datos @@ -646,7 +653,8 @@ Reimportando %d claves secretas (privadas) No hay claves públicas a reimportar, omitiendo... - Excepción borrando fichero de caché público + Excepción borrando fichero de caché de claves públicas + Excepción al borrar fichero de caché de claves secretas (privadas) Haga clic para limpiar las frases contraseña almacenadas en caché OpenKeychain ha almacenado en caché %d frases contraseña @@ -660,6 +668,7 @@ Identidad <desconocido> No hay certificados para esta clave + Sólo los auto-certificados y los certificados creados con las claves de usted se muestran aquí. Identidades a certificar Razón de la revocación Estado de la verificación diff --git a/OpenKeychain/src/main/res/values-fr/strings.xml b/OpenKeychain/src/main/res/values-fr/strings.xml index e25f4cd05..4ac578ba8 100644 --- a/OpenKeychain/src/main/res/values-fr/strings.xml +++ b/OpenKeychain/src/main/res/values-fr/strings.xml @@ -275,6 +275,9 @@ décompression des données... vérification de l\'intégrité... suppression sûre de « %s »... + suppression des clefs... + consolider : enregistrement dans le cache... + consolider : réimportation... Nom/courriel/ID de clef... Nom/courriel/preuve/clef... @@ -600,12 +603,14 @@ Exception de signature ! Modification des certifications maîtresses Changement de la phrase de passe pour le trousseau... + Rechiffrement de la sous-clef %s avec la nouvelle phrase de passe Échec lors de la définition de la nouvelle phrase de passe, nouvel essai avec une ancienne phrase de passe vide La phrase de passe de la sous-clef n\'a pas pu être changée ! (Est-elle différente des autres clefs ?) Remplacement du certificat de l\'ID d\'utilisateur principal précédent Génération d\'un nouveau certificat pour le nouvel ID d\'utilisateur principal Modification de la sous-clef %s Une action a été tentée sur la sous-clef manquante %s ! + Ajout de la nouvelle sous-clef de type %2$s (%1$s bit) Nouvelle ID de sous-clef : %s La date d\'expiration ne peut pas être dans le passé ! Révocation de la sous-clef %s @@ -618,6 +623,8 @@ Déverrouillage du trousseau Consolidation de la base de données + La consolidation a été commencée alors qu\'aucune base de données n\'était en cache ! Ceci est probablement une erreur de programmation, veuillez remplir un rapport de bogue ! + La consolidation a été abandonnée, elle est déjà en cours sur un autre exétron ! Enregistrement des trousseaux secrets Enregistrement des trousseaux publiques Nettoyage de la base de données @@ -646,7 +653,8 @@ Réimportation de %d clefs secrètes Aucune clef secrète à réimporter, étape ignorée... - Une exception a eu lieu lors de la suppression du fichier de cache publique + Une exception a eu lieu lors de la suppression du fichier de cache public + Une exception a eu lieu lors de la suppression du fichier de cache secret Cliquer ici pour effacer les phrases de passe mises en cache OpenKeychain a mis en cache %d phrases de passe @@ -660,6 +668,7 @@ identité <inconnu> Aucun certificat pour cette clef + Seuls les auto-certificats et les certificats créés avec vos clefs sont affichés ici. Identités à certifier Raison de la révocation État de vérification diff --git a/OpenKeychain/src/main/res/values-it/strings.xml b/OpenKeychain/src/main/res/values-it/strings.xml index 4cb029508..9a21a642b 100644 --- a/OpenKeychain/src/main/res/values-it/strings.xml +++ b/OpenKeychain/src/main/res/values-it/strings.xml @@ -275,6 +275,9 @@ decompressione dati... verifica integrita\'... eliminazione sicura di \'%s\'... + cancellazione chiavi... + consolidazione: salvataggio della cache... + consolidazione: reimportazione... Nome/Email/ID Chiave... Nome/Email/Certificato/Chiave... @@ -361,7 +364,10 @@ Permetti accesso Nega accesso Per favore selezionare una chiave! + Nessuna chiave trovata per queste identità: + Esistono piu\' di una chiave per queste identità: Per favore ricontrolla la lista destinatari! + Per favore seleziona i destinatari! Controllo della firma fallito! Hai installato questa app da una fonte diversa? Se sei sicuro che non sia un attacco, revoca la registrazione di questa app in OpenKeychain e dopo registra di nuovo l\'app. Condividi tramite Codice QR @@ -415,6 +421,7 @@ Revoca Sottochiave nuovo + Per favore seleziona almeno una spunta! Carica chiave nel server delle chiavi Questo campo è necessario @@ -575,6 +582,7 @@ Nessuna opzione della chiave principale specificata! I portachiavi devono essere creati con almeno un ID utente! La chiave principale deve avere la caratteristica di certificazione! + La data di scadenza non può essere \"come prima\" sulla creazione di chiavi. Questo è un errore di programmazione, si prega di inviare una segnalazione di bug! La grandezza della chiave deve essere di 512bit o maggiore Errore PGP interno! Pessima opzione di algortimo! @@ -585,14 +593,26 @@ Impronta chiave attuale non corrispondente! Nessun ID chiave. Questo è un errore di programmazione, per favore invia una segnalazione! Errore interno, controllo di integrità fallito! + Nessun certificato principale trovato su cui operare! (Tutti revocati?) ID utente primario specificato non valido! + ID utente specificato non valido per la revoca! ID utente revocato non può essere primario! + La data di scadenza non può essere \"come prima\" sulla creazione di sottochiavi. Questo è un errore di programmazione, si prega di inviare una segnalazione di bug! + Errore irreversibile nella decodifica della chiave principale! Questo è probabilmente un errore di programmazione, si prega di inviare una segnalazione di bug! Eccezione interna di PGP! Eccezione di firma! + Modifica delle certificazioni principali + Cambio frase di accesso del portachiavi... + Ri-codifica sottochiave %s con nuova frase di accesso + Impostazione nuova frase di accesso fallita, provo di nuovo con frase precedente di accesso vuota + La frase di accesso per la sottochiave non può essere modificata! (Ne ha una diversa dalle altre chiavi?) Sostituzione certificato del ID utente primario precedente Generazione di un nuovo certificato per il nuovo ID utente primario Modifica sottochiave %s + Tentativo di operare su sottochiave %s mancante! + Aggiunta nuova sottochiave di tipo %2$s (%1$s bit) Nuovo ID sottochiave: %s + La data di scadenza non può essere nel passato! Revoca sottochiave %s Portachiavi modificato con successo Aggiunta id utente %s @@ -602,6 +622,39 @@ Errore di apertura portachiavi! Apertura portachiavi + Consolidazione database + Il consolidamento è stato avviato mentre nessun database è stato memorizzato nella cache! Questo è probabilmente un errore di programmazione, si prega di aprire un bug report. + Consolidamento interrotto, già in esecuzione su un altro processo! + Salvataggio portachiavi privati + Salvataggio portachiavi pubblico + Pulizia database + Consolidamento database con successo + Ingresso fase critica + Uscita fase critica + Eliminazione del file di cache del portachiavi pubblico + Eliminazione del file di cache del portachiavi privato + Errore nell\'apertura del database + Errore di IO durante la scrittura delle chiavi pubbliche nella cache! + Errore di IO durante la scrittura delle chiavi private nella cache! + Errore nella re-importazione delle chiavi pubbliche! + Errore nella re-importazione delle chiavi private! + + Recupero consolidamento con %1$d chiavi segrete e %2$d chiavi pubbliche + Recupero consolidamento con %1$d chiavi segrete e %2$d chiavi pubbliche + + Recupero da situazione ignota + + Reimportazione di una chiave pubblica + Reimportazione di %d chiavi pubbliche + + Nessuna chiave pubblica da reimportare, proseguo... + + Reimportazione di una chiave privata + Reimportazione di %d chiavi private + + Nessuna chiave privata da reimportare, proseguo... + Eccezione durante la eliminazione del file di cache pubblico + Eccezione durante la eliminazione del file di cache privato Clicca per rimuovere la frase di accesso nella cache OpenKeychain ha memorizzato nella cache %d frasi di accesso @@ -615,6 +668,7 @@ Identit <sconosciuto> Nessun certificato per questa chiave + Solo le autocertificazioni e i certificati creati con le tue chiavi vengono visualizzati qui. Identità da certificare Ragione della Revoca Stato Verifica -- cgit v1.2.3 From 08bdb0c5b983b6d0096187873275598a1ae4c9c3 Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Sat, 23 Aug 2014 11:57:19 +0200 Subject: update to tidy spongy-master --- extern/spongycastle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extern/spongycastle b/extern/spongycastle index d65458612..526d23382 160000 --- a/extern/spongycastle +++ b/extern/spongycastle @@ -1 +1 @@ -Subproject commit d65458612838f7de0b222c0b7168db97018cac32 +Subproject commit 526d23382e53ce46a17a5efd9c23d884125e32ce -- cgit v1.2.3 From 9f9c31868de851b685f2fa06746a2fc2b59c0142 Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Sat, 23 Aug 2014 12:13:28 +0200 Subject: tests: fix non-deterministic testMasterModify --- .../java/org/sufficientlysecure/keychain/pgp/PgpKeyOperationTest.java | 1 + 1 file changed, 1 insertion(+) diff --git a/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperationTest.java b/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperationTest.java index ee312aedf..f6d993d6b 100644 --- a/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperationTest.java +++ b/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperationTest.java @@ -500,6 +500,7 @@ public class PgpKeyOperationTest { modified = applyModificationWithChecks(parcel, modified, onlyA, onlyB); { + parcel.reset(); parcel.mChangeSubKeys.add(new SubkeyChange(keyId, null, expiry)); modified = applyModificationWithChecks(parcel, modified, onlyA, onlyB); -- cgit v1.2.3 From 71657d993c7efe5e700e488d2b3e5235196cd412 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Sat, 23 Aug 2014 15:27:25 +0200 Subject: API: Fix re-seletion of keys on default account --- .../keychain/remote/OpenPgpService.java | 20 +++++++++++++------- .../keychain/remote/RemoteService.java | 5 +++-- 2 files changed, 16 insertions(+), 9 deletions(-) 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 6e9f2fad6..5340222d3 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java @@ -23,6 +23,7 @@ import android.database.Cursor; import android.net.Uri; import android.os.IBinder; import android.os.ParcelFileDescriptor; +import android.text.TextUtils; import org.openintents.openpgp.IOpenPgpService; import org.openintents.openpgp.OpenPgpMetadata; @@ -185,7 +186,7 @@ public class OpenPgpService extends RemoteService { } catch (PassphraseCacheService.KeyNotFoundException e) { // secret key that is set for this account is deleted? // show account config again! - return getCreateAccountIntent(data, data.getStringExtra(OpenPgpApi.EXTRA_ACCOUNT_NAME)); + return getCreateAccountIntent(data, getAccountName(data)); } } if (passphrase == null) { @@ -564,6 +565,16 @@ public class OpenPgpService extends RemoteService { return null; } + private String getAccountName(Intent data) { + String accName = data.getStringExtra(OpenPgpApi.EXTRA_ACCOUNT_NAME); + // if no account name is given use name "default" + if (TextUtils.isEmpty(accName)) { + accName = "default"; + } + Log.d(Constants.TAG, "accName: " + accName); + return accName; + } + // TODO: multi-threading private final IOpenPgpService.Stub mBinder = new IOpenPgpService.Stub() { @@ -574,12 +585,7 @@ public class OpenPgpService extends RemoteService { return errorResult; } - String accName; - if (data.getStringExtra(OpenPgpApi.EXTRA_ACCOUNT_NAME) != null) { - accName = data.getStringExtra(OpenPgpApi.EXTRA_ACCOUNT_NAME); - } else { - accName = "default"; - } + String accName = getAccountName(data); final AccountSettings accSettings = getAccSettings(accName); if (accSettings == null) { return getCreateAccountIntent(data, accName); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/RemoteService.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/RemoteService.java index f70324e2c..e71b52ccd 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/RemoteService.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/RemoteService.java @@ -27,6 +27,7 @@ import android.content.pm.PackageManager.NameNotFoundException; import android.content.pm.Signature; import android.net.Uri; import android.os.Binder; +import android.text.TextUtils; import org.openintents.openpgp.OpenPgpError; import org.openintents.openpgp.util.OpenPgpApi; @@ -160,7 +161,7 @@ public abstract class RemoteService extends Service { */ protected AccountSettings getAccSettings(String accountName) { String currentPkg = getCurrentCallingPackage(); - Log.d(Constants.TAG, "accountName: " + accountName); + Log.d(Constants.TAG, "getAccSettings accountName: "+ accountName); Uri uri = KeychainContract.ApiAccounts.buildByPackageAndAccountUri(currentPkg, accountName); @@ -171,7 +172,7 @@ public abstract class RemoteService extends Service { protected Intent getCreateAccountIntent(Intent data, String accountName) { String packageName = getCurrentCallingPackage(); - Log.d(Constants.TAG, "accountName: " + accountName); + Log.d(Constants.TAG, "getCreateAccountIntent accountName: " + accountName); Intent intent = new Intent(getBaseContext(), RemoteServiceActivity.class); intent.setAction(RemoteServiceActivity.ACTION_CREATE_ACCOUNT); -- cgit v1.2.3 From 783dae8804fee1f1594cc910d3570fcf6178015c Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Sun, 24 Aug 2014 05:12:09 +0200 Subject: add ecc support --- .../keychain/pgp/PgpKeyOperationTest.java | 43 ++--- .../pgp/UncachedKeyringCanonicalizeTest.java | 9 +- .../keychain/pgp/UncachedKeyringMergeTest.java | 9 +- .../keychain/pgp/UncachedKeyringTest.java | 7 +- .../keychain/keyimport/HkpKeyserver.java | 2 +- .../keychain/keyimport/ImportKeysListEntry.java | 23 ++- .../keychain/keyimport/KeybaseKeyserver.java | 2 +- .../keychain/pgp/PgpKeyHelper.java | 131 ++++++++++++-- .../keychain/pgp/PgpKeyOperation.java | 106 +++++++++--- .../keychain/pgp/UncachedKeyRing.java | 6 +- .../keychain/pgp/UncachedPublicKey.java | 23 ++- .../keychain/provider/KeychainContract.java | 1 + .../keychain/provider/KeychainDatabase.java | 24 ++- .../keychain/provider/KeychainProvider.java | 2 + .../keychain/provider/ProviderHelper.java | 2 +- .../keychain/service/OperationResultParcel.java | 7 +- .../keychain/service/SaveKeyringParcel.java | 29 +++- .../keychain/ui/CreateKeyFinalFragment.java | 10 +- .../keychain/ui/ViewCertActivity.java | 2 +- .../keychain/ui/adapter/ImportKeysAdapter.java | 4 +- .../keychain/ui/adapter/SubkeysAdapter.java | 21 ++- .../keychain/ui/adapter/SubkeysAddedAdapter.java | 7 +- .../ui/dialog/AddSubkeyDialogFragment.java | 188 ++++++++++++++------- .../sufficientlysecure/keychain/util/Choice.java | 13 +- .../src/main/res/layout/add_subkey_dialog.xml | 20 ++- OpenKeychain/src/main/res/values/strings.xml | 24 ++- 26 files changed, 524 insertions(+), 191 deletions(-) diff --git a/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperationTest.java b/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperationTest.java index ee312aedf..262c83404 100644 --- a/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperationTest.java +++ b/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperationTest.java @@ -36,11 +36,11 @@ import org.spongycastle.bcpg.UserIDPacket; import org.spongycastle.bcpg.sig.KeyFlags; import org.spongycastle.jce.provider.BouncyCastleProvider; import org.spongycastle.openpgp.PGPSignature; -import org.spongycastle.bcpg.PublicKeyAlgorithmTags; import org.sufficientlysecure.keychain.service.OperationResultParcel.LogType; import org.sufficientlysecure.keychain.service.OperationResultParcel.OperationLog; import org.sufficientlysecure.keychain.service.OperationResults.EditKeyResult; import org.sufficientlysecure.keychain.service.SaveKeyringParcel; +import org.sufficientlysecure.keychain.service.SaveKeyringParcel.Algorithm; import org.sufficientlysecure.keychain.service.SaveKeyringParcel.SubkeyAdd; import org.sufficientlysecure.keychain.service.SaveKeyringParcel.SubkeyChange; import org.sufficientlysecure.keychain.support.KeyringBuilder; @@ -78,11 +78,11 @@ public class PgpKeyOperationTest { SaveKeyringParcel parcel = new SaveKeyringParcel(); parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( - PublicKeyAlgorithmTags.RSA_GENERAL, 1024, KeyFlags.CERTIFY_OTHER, 0L)); + Algorithm.RSA, 1024, null, KeyFlags.CERTIFY_OTHER, 0L)); parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( - PublicKeyAlgorithmTags.DSA, 1024, KeyFlags.SIGN_DATA, 0L)); + Algorithm.DSA, 1024, null, KeyFlags.SIGN_DATA, 0L)); parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( - PublicKeyAlgorithmTags.ELGAMAL_ENCRYPT, 1024, KeyFlags.ENCRYPT_COMMS, 0L)); + Algorithm.ELGAMAL, 1024, null, KeyFlags.ENCRYPT_COMMS, 0L)); parcel.mAddUserIds.add("twi"); parcel.mAddUserIds.add("pink"); @@ -120,7 +120,7 @@ public class PgpKeyOperationTest { { parcel.reset(); parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( - PublicKeyAlgorithmTags.RSA_GENERAL, new Random().nextInt(256)+255, KeyFlags.CERTIFY_OTHER, 0L)); + Algorithm.RSA, new Random().nextInt(256)+255, null, KeyFlags.CERTIFY_OTHER, 0L)); parcel.mAddUserIds.add("shy"); parcel.mNewPassphrase = passphrase; @@ -131,18 +131,18 @@ public class PgpKeyOperationTest { { parcel.reset(); parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( - PublicKeyAlgorithmTags.ELGAMAL_ENCRYPT, 1024, KeyFlags.CERTIFY_OTHER, 0L)); + Algorithm.ELGAMAL, 1024, null, KeyFlags.CERTIFY_OTHER, 0L)); parcel.mAddUserIds.add("shy"); parcel.mNewPassphrase = passphrase; assertFailure("creating ring with ElGamal master key should fail", parcel, - LogType.MSG_CR_ERROR_MASTER_ELGAMAL); + LogType.MSG_CR_ERROR_FLAGS_ELGAMAL); } { parcel.reset(); parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( - PublicKeyAlgorithmTags.RSA_GENERAL, 1024, KeyFlags.CERTIFY_OTHER, null)); + Algorithm.RSA, 1024, null, KeyFlags.CERTIFY_OTHER, null)); parcel.mAddUserIds.add("lotus"); parcel.mNewPassphrase = passphrase; @@ -153,18 +153,7 @@ public class PgpKeyOperationTest { { parcel.reset(); parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( - 12345, 1024, KeyFlags.CERTIFY_OTHER, 0L)); - parcel.mAddUserIds.add("shy"); - parcel.mNewPassphrase = passphrase; - - assertFailure("creating ring with bad algorithm choice should fail", parcel, - LogType.MSG_CR_ERROR_UNKNOWN_ALGO); - } - - { - parcel.reset(); - parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( - PublicKeyAlgorithmTags.RSA_GENERAL, 1024, KeyFlags.SIGN_DATA, 0L)); + Algorithm.RSA, 1024, null, KeyFlags.SIGN_DATA, 0L)); parcel.mAddUserIds.add("shy"); parcel.mNewPassphrase = passphrase; @@ -175,7 +164,7 @@ public class PgpKeyOperationTest { { parcel.reset(); parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( - PublicKeyAlgorithmTags.RSA_GENERAL, 1024, KeyFlags.CERTIFY_OTHER, 0L)); + Algorithm.RSA, 1024, null, KeyFlags.CERTIFY_OTHER, 0L)); parcel.mNewPassphrase = passphrase; assertFailure("creating ring without user ids should fail", parcel, @@ -199,7 +188,7 @@ public class PgpKeyOperationTest { public void testMasterFlags() throws Exception { SaveKeyringParcel parcel = new SaveKeyringParcel(); parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( - PublicKeyAlgorithmTags.RSA_GENERAL, 1024, KeyFlags.CERTIFY_OTHER | KeyFlags.SIGN_DATA, 0L)); + Algorithm.RSA, 1024, null, KeyFlags.CERTIFY_OTHER | KeyFlags.SIGN_DATA, 0L)); parcel.mAddUserIds.add("luna"); ring = assertCreateSuccess("creating ring with master key flags must succeed", parcel); @@ -313,7 +302,7 @@ public class PgpKeyOperationTest { long expiry = new Date().getTime() / 1000 + 159; int flags = KeyFlags.SIGN_DATA; int bits = 1024 + new Random().nextInt(8); - parcel.mAddSubKeys.add(new SubkeyAdd(PublicKeyAlgorithmTags.RSA_GENERAL, bits, flags, expiry)); + parcel.mAddSubKeys.add(new SubkeyAdd(Algorithm.RSA, bits, null, flags, expiry)); UncachedKeyRing modified = applyModificationWithChecks(parcel, ring, onlyA, onlyB); @@ -349,12 +338,12 @@ public class PgpKeyOperationTest { Assert.assertEquals("added key must have expected flags", flags, newKey.getKeyUsage()); Assert.assertEquals("added key must have expected bitsize", - bits, newKey.getBitStrength()); + bits, (int) newKey.getBitStrength()); { // bad keysize should fail parcel.reset(); parcel.mAddSubKeys.add(new SubkeyAdd( - PublicKeyAlgorithmTags.RSA_GENERAL, new Random().nextInt(512), KeyFlags.SIGN_DATA, 0L)); + Algorithm.RSA, new Random().nextInt(512), null, KeyFlags.SIGN_DATA, 0L)); assertModifyFailure("creating a subkey with keysize < 512 should fail", ring, parcel, LogType.MSG_CR_ERROR_KEYSIZE_512); @@ -363,7 +352,7 @@ public class PgpKeyOperationTest { { parcel.reset(); parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( - PublicKeyAlgorithmTags.RSA_GENERAL, 1024, KeyFlags.SIGN_DATA, null)); + Algorithm.RSA, 1024, null, KeyFlags.SIGN_DATA, null)); assertModifyFailure("creating master key with null expiry should fail", ring, parcel, LogType.MSG_MF_ERROR_NULL_EXPIRY); @@ -371,7 +360,7 @@ public class PgpKeyOperationTest { { // a past expiry should fail parcel.reset(); - parcel.mAddSubKeys.add(new SubkeyAdd(PublicKeyAlgorithmTags.RSA_GENERAL, 1024, KeyFlags.SIGN_DATA, + parcel.mAddSubKeys.add(new SubkeyAdd(Algorithm.RSA, 1024, null, KeyFlags.SIGN_DATA, new Date().getTime()/1000-10)); assertModifyFailure("creating subkey with past expiry date should fail", ring, parcel, LogType.MSG_MF_ERROR_PAST_EXPIRY); diff --git a/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/UncachedKeyringCanonicalizeTest.java b/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/UncachedKeyringCanonicalizeTest.java index 670022a10..5792e8326 100644 --- a/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/UncachedKeyringCanonicalizeTest.java +++ b/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/UncachedKeyringCanonicalizeTest.java @@ -49,6 +49,7 @@ import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.service.OperationResultParcel; import org.sufficientlysecure.keychain.service.OperationResults.EditKeyResult; import org.sufficientlysecure.keychain.service.SaveKeyringParcel; +import org.sufficientlysecure.keychain.service.SaveKeyringParcel.Algorithm; import org.sufficientlysecure.keychain.support.KeyringTestingHelper; import org.sufficientlysecure.keychain.support.KeyringTestingHelper.RawPacket; @@ -85,11 +86,11 @@ public class UncachedKeyringCanonicalizeTest { SaveKeyringParcel parcel = new SaveKeyringParcel(); parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( - PublicKeyAlgorithmTags.RSA_GENERAL, 1024, KeyFlags.CERTIFY_OTHER, 0L)); + Algorithm.RSA, 1024, null, KeyFlags.CERTIFY_OTHER, 0L)); parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( - PublicKeyAlgorithmTags.RSA_GENERAL, 1024, KeyFlags.SIGN_DATA, 0L)); + Algorithm.RSA, 1024, null, KeyFlags.SIGN_DATA, 0L)); parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( - PublicKeyAlgorithmTags.RSA_GENERAL, 1024, KeyFlags.ENCRYPT_COMMS, 0L)); + Algorithm.RSA, 1024, null, KeyFlags.ENCRYPT_COMMS, 0L)); parcel.mAddUserIds.add("twi"); parcel.mAddUserIds.add("pink"); @@ -298,7 +299,7 @@ public class UncachedKeyringCanonicalizeTest { SaveKeyringParcel parcel = new SaveKeyringParcel(); parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( - PublicKeyAlgorithmTags.RSA_GENERAL, 1024, KeyFlags.CERTIFY_OTHER, 0L)); + Algorithm.RSA, 1024, null, KeyFlags.CERTIFY_OTHER, 0L)); parcel.mAddUserIds.add("trix"); PgpKeyOperation op = new PgpKeyOperation(null); diff --git a/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/UncachedKeyringMergeTest.java b/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/UncachedKeyringMergeTest.java index a04fe1f11..64152a040 100644 --- a/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/UncachedKeyringMergeTest.java +++ b/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/UncachedKeyringMergeTest.java @@ -33,6 +33,7 @@ import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.service.OperationResultParcel; import org.sufficientlysecure.keychain.service.OperationResults.EditKeyResult; import org.sufficientlysecure.keychain.service.SaveKeyringParcel; +import org.sufficientlysecure.keychain.service.SaveKeyringParcel.Algorithm; import org.sufficientlysecure.keychain.support.KeyringTestingHelper; import org.sufficientlysecure.keychain.support.KeyringTestingHelper.RawPacket; import org.sufficientlysecure.keychain.util.ProgressScaler; @@ -85,9 +86,9 @@ public class UncachedKeyringMergeTest { { SaveKeyringParcel parcel = new SaveKeyringParcel(); parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( - PublicKeyAlgorithmTags.RSA_GENERAL, 1024, KeyFlags.CERTIFY_OTHER, 0L)); + Algorithm.RSA, 1024, null, KeyFlags.CERTIFY_OTHER, 0L)); parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( - PublicKeyAlgorithmTags.RSA_GENERAL, 1024, KeyFlags.SIGN_DATA, 0L)); + Algorithm.RSA, 1024, null, KeyFlags.SIGN_DATA, 0L)); parcel.mAddUserIds.add("twi"); parcel.mAddUserIds.add("pink"); @@ -104,7 +105,7 @@ public class UncachedKeyringMergeTest { { SaveKeyringParcel parcel = new SaveKeyringParcel(); parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( - PublicKeyAlgorithmTags.RSA_GENERAL, 1024, KeyFlags.CERTIFY_OTHER, 0L)); + Algorithm.RSA, 1024, null, KeyFlags.CERTIFY_OTHER, 0L)); parcel.mAddUserIds.add("shy"); // passphrase is tested in PgpKeyOperationTest, just use empty here @@ -210,7 +211,7 @@ public class UncachedKeyringMergeTest { parcel.reset(); parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( - PublicKeyAlgorithmTags.RSA_GENERAL, 1024, KeyFlags.SIGN_DATA, 0L)); + Algorithm.RSA, 1024, null, KeyFlags.SIGN_DATA, 0L)); modifiedA = op.modifySecretKeyRing(secretRing, parcel, "").getRing(); modifiedB = op.modifySecretKeyRing(secretRing, parcel, "").getRing(); diff --git a/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/UncachedKeyringTest.java b/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/UncachedKeyringTest.java index 8aac5d430..636dae90c 100644 --- a/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/UncachedKeyringTest.java +++ b/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/UncachedKeyringTest.java @@ -31,6 +31,7 @@ import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException; import org.sufficientlysecure.keychain.service.OperationResults.EditKeyResult; import org.sufficientlysecure.keychain.service.SaveKeyringParcel; +import org.sufficientlysecure.keychain.service.SaveKeyringParcel.Algorithm; import org.sufficientlysecure.keychain.support.KeyringTestingHelper.RawPacket; import java.io.ByteArrayInputStream; @@ -55,11 +56,11 @@ public class UncachedKeyringTest { SaveKeyringParcel parcel = new SaveKeyringParcel(); parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( - PublicKeyAlgorithmTags.RSA_GENERAL, 1024, KeyFlags.CERTIFY_OTHER, 0L)); + Algorithm.RSA, 1024, null, KeyFlags.CERTIFY_OTHER, 0L)); parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( - PublicKeyAlgorithmTags.RSA_GENERAL, 1024, KeyFlags.SIGN_DATA, 0L)); + Algorithm.RSA, 1024, null, KeyFlags.SIGN_DATA, 0L)); parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( - PublicKeyAlgorithmTags.RSA_GENERAL, 1024, KeyFlags.ENCRYPT_COMMS, 0L)); + Algorithm.RSA, 1024, null, KeyFlags.ENCRYPT_COMMS, 0L)); parcel.mAddUserIds.add("twi"); parcel.mAddUserIds.add("pink"); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/HkpKeyserver.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/HkpKeyserver.java index 69ac2551f..e30401180 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/HkpKeyserver.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/HkpKeyserver.java @@ -283,7 +283,7 @@ public class HkpKeyserver extends Keyserver { entry.setBitStrength(Integer.parseInt(matcher.group(3))); final int algorithmId = Integer.decode(matcher.group(2)); - entry.setAlgorithm(PgpKeyHelper.getAlgorithmInfo(algorithmId)); + entry.setAlgorithm(PgpKeyHelper.getAlgorithmInfo(algorithmId, null, null)); // group 1 contains the full fingerprint (v4) or the long key id if available // see http://bit.ly/1d4bxbk and http://bit.ly/1gD1wwr diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/ImportKeysListEntry.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/ImportKeysListEntry.java index 30e93f957..da70f1505 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/ImportKeysListEntry.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/ImportKeysListEntry.java @@ -39,7 +39,8 @@ public class ImportKeysListEntry implements Serializable, Parcelable { private boolean mExpired; private Date mDate; // TODO: not displayed private String mFingerprintHex; - private int mBitStrength; + private Integer mBitStrength; + private String mCurveOid; private String mAlgorithm; private boolean mSecretKey; private String mPrimaryUserId; @@ -162,10 +163,14 @@ public class ImportKeysListEntry implements Serializable, Parcelable { this.mFingerprintHex = fingerprintHex; } - public int getBitStrength() { + public Integer getBitStrength() { return mBitStrength; } + public String getCurveOid() { + return mCurveOid; + } + public void setBitStrength(int bitStrength) { this.mBitStrength = bitStrength; } @@ -258,13 +263,15 @@ public class ImportKeysListEntry implements Serializable, Parcelable { mPrimaryUserId = mUserIds.get(0); } - this.mKeyId = key.getKeyId(); - this.mKeyIdHex = PgpKeyHelper.convertKeyIdToHex(mKeyId); + mKeyId = key.getKeyId(); + mKeyIdHex = PgpKeyHelper.convertKeyIdToHex(mKeyId); - this.mRevoked = key.isRevoked(); - this.mFingerprintHex = PgpKeyHelper.convertFingerprintToHex(key.getFingerprint()); - this.mBitStrength = key.getBitStrength(); + mRevoked = key.isRevoked(); + mFingerprintHex = PgpKeyHelper.convertFingerprintToHex(key.getFingerprint()); + mBitStrength = key.getBitStrength(); + mCurveOid = key.getCurveOid(); final int algorithm = key.getAlgorithm(); - this.mAlgorithm = PgpKeyHelper.getAlgorithmInfo(context, algorithm); + mAlgorithm = PgpKeyHelper.getAlgorithmInfo(context, algorithm, mBitStrength, mCurveOid); } + } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/KeybaseKeyserver.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/KeybaseKeyserver.java index 0ca6f07fd..cbd06da90 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/KeybaseKeyserver.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/KeybaseKeyserver.java @@ -75,7 +75,7 @@ public class KeybaseKeyserver extends Keyserver { entry.setExtraData(username); final int algorithmId = match.getAlgorithmId(); - entry.setAlgorithm(PgpKeyHelper.getAlgorithmInfo(algorithmId)); + entry.setAlgorithm(PgpKeyHelper.getAlgorithmInfo(algorithmId, null, null)); final int bitStrength = match.getBitStrength(); entry.setBitStrength(bitStrength); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyHelper.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyHelper.java index 0c640538f..22956c8af 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyHelper.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyHelper.java @@ -24,10 +24,16 @@ import android.text.Spannable; import android.text.SpannableStringBuilder; import android.text.style.ForegroundColorSpan; +import org.spongycastle.asn1.ASN1ObjectIdentifier; +import org.spongycastle.asn1.nist.NISTNamedCurves; +import org.spongycastle.asn1.teletrust.TeleTrusTNamedCurves; +import org.spongycastle.bcpg.ECPublicBCPGKey; import org.spongycastle.bcpg.PublicKeyAlgorithmTags; import org.spongycastle.util.encoders.Hex; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; +import org.sufficientlysecure.keychain.service.SaveKeyringParcel.Algorithm; +import org.sufficientlysecure.keychain.service.SaveKeyringParcel.Curve; import org.sufficientlysecure.keychain.util.Log; import java.security.DigestException; @@ -37,18 +43,14 @@ import java.util.Locale; public class PgpKeyHelper { - public static String getAlgorithmInfo(int algorithm) { - return getAlgorithmInfo(null, algorithm, 0); - } - - public static String getAlgorithmInfo(Context context, int algorithm) { - return getAlgorithmInfo(context, algorithm, 0); + public static String getAlgorithmInfo(int algorithm, Integer keySize, String oid) { + return getAlgorithmInfo(null, algorithm, keySize, oid); } /** * Based on OpenPGP Message Format */ - public static String getAlgorithmInfo(Context context, int algorithm, int keySize) { + public static String getAlgorithmInfo(Context context, int algorithm, Integer keySize, String oid) { String algorithmStr; switch (algorithm) { @@ -69,10 +71,19 @@ public class PgpKeyHelper { break; } - case PublicKeyAlgorithmTags.ECDSA: + case PublicKeyAlgorithmTags.ECDSA: { + if (oid == null) { + return "ECDSA"; + } + String oidName = PgpKeyHelper.getCurveInfo(context, oid); + return "ECDSA (" + oidName + ")"; + } case PublicKeyAlgorithmTags.ECDH: { - algorithmStr = "ECC"; - break; + if (oid == null) { + return "ECDH"; + } + String oidName = PgpKeyHelper.getCurveInfo(context, oid); + return "ECDH (" + oidName + ")"; } default: { @@ -90,6 +101,106 @@ public class PgpKeyHelper { return algorithmStr; } + public static String getAlgorithmInfo(Algorithm algorithm, Integer keySize, Curve curve) { + return getAlgorithmInfo(null, algorithm, keySize, curve); + } + + /** + * Based on OpenPGP Message Format + */ + public static String getAlgorithmInfo(Context context, Algorithm algorithm, Integer keySize, Curve curve) { + String algorithmStr; + + switch (algorithm) { + case RSA: { + algorithmStr = "RSA"; + break; + } + case DSA: { + algorithmStr = "DSA"; + break; + } + + case ELGAMAL: { + algorithmStr = "ElGamal"; + break; + } + + case ECDSA: { + algorithmStr = "ECDSA"; + if (curve != null) { + algorithmStr += " (" + getCurveInfo(context, curve) + ")"; + } + return algorithmStr; + } + case ECDH: { + algorithmStr = "ECDH"; + if (curve != null) { + algorithmStr += " (" + getCurveInfo(context, curve) + ")"; + } + return algorithmStr; + } + + default: { + if (context != null) { + algorithmStr = context.getResources().getString(R.string.unknown_algorithm); + } else { + algorithmStr = "unknown"; + } + break; + } + } + if (keySize != null && keySize > 0) + return algorithmStr + ", " + keySize + " bit"; + else + return algorithmStr; + } + + // Return name of a curve. These are names, no need for translation + public static String getCurveInfo(Context context, Curve curve) { + switch(curve) { + case NIST_P256: + return "NIST P-256"; + case NIST_P384: + return "NIST P-384"; + case NIST_P521: + return "NIST P-521"; + + /* see SaveKeyringParcel + case BRAINPOOL_P256: + return "Brainpool P-256"; + case BRAINPOOL_P384: + return "Brainpool P-384"; + case BRAINPOOL_P512: + return "Brainpool P-512"; + */ + } + if (context != null) { + return context.getResources().getString(R.string.unknown_algorithm); + } else { + return "unknown"; + } + } + + public static String getCurveInfo(Context context, String oidStr) { + ASN1ObjectIdentifier oid = new ASN1ObjectIdentifier(oidStr); + + String name; + name = NISTNamedCurves.getName(oid); + if (name != null) { + return name; + } + name = TeleTrusTNamedCurves.getName(oid); + if (name != null) { + return name; + } + if (context != null) { + return context.getResources().getString(R.string.unknown_algorithm); + } else { + return "unknown"; + } + } + /** * Converts fingerprint to hex (optional: with whitespaces after 4 characters) *

                                                      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 175045470..967a7caa9 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java @@ -20,12 +20,12 @@ package org.sufficientlysecure.keychain.pgp; import org.spongycastle.bcpg.CompressionAlgorithmTags; import org.spongycastle.bcpg.HashAlgorithmTags; -import org.spongycastle.bcpg.PublicKeyAlgorithmTags; import org.spongycastle.bcpg.SymmetricKeyAlgorithmTags; import org.spongycastle.bcpg.sig.Features; import org.spongycastle.bcpg.sig.KeyFlags; import org.spongycastle.jce.spec.ElGamalParameterSpec; import org.spongycastle.openpgp.PGPException; +import org.spongycastle.openpgp.PGPKeyFlags; import org.spongycastle.openpgp.PGPKeyPair; import org.spongycastle.openpgp.PGPPrivateKey; import org.spongycastle.openpgp.PGPPublicKey; @@ -52,6 +52,8 @@ import org.sufficientlysecure.keychain.service.OperationResultParcel.LogType; import org.sufficientlysecure.keychain.service.OperationResultParcel.OperationLog; import org.sufficientlysecure.keychain.service.OperationResults.EditKeyResult; import org.sufficientlysecure.keychain.service.SaveKeyringParcel; +import org.sufficientlysecure.keychain.service.SaveKeyringParcel.Algorithm; +import org.sufficientlysecure.keychain.service.SaveKeyringParcel.Curve; import org.sufficientlysecure.keychain.service.SaveKeyringParcel.SubkeyAdd; import org.sufficientlysecure.keychain.util.IterableIterator; import org.sufficientlysecure.keychain.util.Log; @@ -66,6 +68,7 @@ import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.SecureRandom; import java.security.SignatureException; +import java.security.spec.ECGenParameterSpec; import java.util.Arrays; import java.util.Date; import java.util.Iterator; @@ -155,31 +158,65 @@ public class PgpKeyOperation { mProgress.peek().setProgress(message, current, 100); } + private ECGenParameterSpec getEccParameterSpec(Curve curve) { + switch (curve) { + case NIST_P256: return new ECGenParameterSpec("P-256"); + case NIST_P384: return new ECGenParameterSpec("P-384"); + case NIST_P521: return new ECGenParameterSpec("P-521"); + + // @see SaveKeyringParcel + // case BRAINPOOL_P256: return new ECGenParameterSpec("brainpoolp256r1"); + // case BRAINPOOL_P384: return new ECGenParameterSpec("brainpoolp384r1"); + // case BRAINPOOL_P512: return new ECGenParameterSpec("brainpoolp512r1"); + } + throw new RuntimeException("Invalid choice! (can't happen)"); + } + /** Creates new secret key. */ - private PGPKeyPair createKey(int algorithmChoice, int keySize, OperationLog log, int indent) { + private PGPKeyPair createKey(SubkeyAdd add, OperationLog log, int indent) { try { - if (keySize < 512) { - log.add(LogLevel.ERROR, LogType.MSG_CR_ERROR_KEYSIZE_512, indent); - return null; + // Some safety checks + if (add.mAlgorithm == Algorithm.ECDH || add.mAlgorithm == Algorithm.ECDSA) { + if (add.mCurve == null) { + log.add(LogLevel.ERROR, LogType.MSG_CR_ERROR_NO_CURVE, indent); + return null; + } + } else { + if (add.mKeySize == null) { + log.add(LogLevel.ERROR, LogType.MSG_CR_ERROR_NO_KEYSIZE, indent); + return null; + } + if (add.mKeySize < 512) { + log.add(LogLevel.ERROR, LogType.MSG_CR_ERROR_KEYSIZE_512, indent); + return null; + } } int algorithm; KeyPairGenerator keyGen; - switch (algorithmChoice) { - case PublicKeyAlgorithmTags.DSA: { + switch (add.mAlgorithm) { + case DSA: { + if ((add.mFlags & (PGPKeyFlags.CAN_ENCRYPT_COMMS | PGPKeyFlags.CAN_ENCRYPT_STORAGE)) > 0) { + log.add(LogLevel.ERROR, LogType.MSG_CR_ERROR_FLAGS_DSA, indent); + return null; + } progress(R.string.progress_generating_dsa, 30); keyGen = KeyPairGenerator.getInstance("DSA", Constants.BOUNCY_CASTLE_PROVIDER_NAME); - keyGen.initialize(keySize, new SecureRandom()); + keyGen.initialize(add.mKeySize, new SecureRandom()); algorithm = PGPPublicKey.DSA; break; } - case PublicKeyAlgorithmTags.ELGAMAL_ENCRYPT: { + case ELGAMAL: { + if ((add.mFlags & (PGPKeyFlags.CAN_SIGN | PGPKeyFlags.CAN_CERTIFY)) > 0) { + log.add(LogLevel.ERROR, LogType.MSG_CR_ERROR_FLAGS_ELGAMAL, indent); + return null; + } progress(R.string.progress_generating_elgamal, 30); keyGen = KeyPairGenerator.getInstance("ElGamal", Constants.BOUNCY_CASTLE_PROVIDER_NAME); - BigInteger p = Primes.getBestPrime(keySize); + BigInteger p = Primes.getBestPrime(add.mKeySize); BigInteger g = new BigInteger("2"); ElGamalParameterSpec elParams = new ElGamalParameterSpec(p, g); @@ -189,15 +226,44 @@ public class PgpKeyOperation { break; } - case PublicKeyAlgorithmTags.RSA_GENERAL: { + case RSA: { progress(R.string.progress_generating_rsa, 30); keyGen = KeyPairGenerator.getInstance("RSA", Constants.BOUNCY_CASTLE_PROVIDER_NAME); - keyGen.initialize(keySize, new SecureRandom()); + keyGen.initialize(add.mKeySize, new SecureRandom()); algorithm = PGPPublicKey.RSA_GENERAL; break; } + case ECDSA: { + if ((add.mFlags & (PGPKeyFlags.CAN_ENCRYPT_COMMS | PGPKeyFlags.CAN_ENCRYPT_STORAGE)) > 0) { + log.add(LogLevel.ERROR, LogType.MSG_CR_ERROR_FLAGS_ECDSA, indent); + return null; + } + progress(R.string.progress_generating_ecdsa, 30); + ECGenParameterSpec ecParamSpec = getEccParameterSpec(add.mCurve); + keyGen = KeyPairGenerator.getInstance("ECDSA", Constants.BOUNCY_CASTLE_PROVIDER_NAME); + keyGen.initialize(ecParamSpec, new SecureRandom()); + + algorithm = PGPPublicKey.ECDSA; + break; + } + + case ECDH: { + // make sure there are no sign or certify flags set + if ((add.mFlags & (PGPKeyFlags.CAN_SIGN | PGPKeyFlags.CAN_CERTIFY)) > 0) { + log.add(LogLevel.ERROR, LogType.MSG_CR_ERROR_FLAGS_ECDH, indent); + return null; + } + progress(R.string.progress_generating_ecdh, 30); + ECGenParameterSpec ecParamSpec = getEccParameterSpec(add.mCurve); + keyGen = KeyPairGenerator.getInstance("ECDH", Constants.BOUNCY_CASTLE_PROVIDER_NAME); + keyGen.initialize(ecParamSpec, new SecureRandom()); + + algorithm = PGPPublicKey.ECDH; + break; + } + default: { log.add(LogLevel.ERROR, LogType.MSG_CR_ERROR_UNKNOWN_ALGO, indent); return null; @@ -210,7 +276,8 @@ public class PgpKeyOperation { } catch(NoSuchProviderException e) { throw new RuntimeException(e); } catch(NoSuchAlgorithmException e) { - throw new RuntimeException(e); + log.add(LogLevel.ERROR, LogType.MSG_CR_ERROR_UNKNOWN_ALGO, indent); + return null; } catch(InvalidAlgorithmParameterException e) { throw new RuntimeException(e); } catch(PGPException e) { @@ -252,13 +319,8 @@ public class PgpKeyOperation { return new EditKeyResult(EditKeyResult.RESULT_ERROR, log, null); } - if (add.mAlgorithm == PublicKeyAlgorithmTags.ELGAMAL_ENCRYPT) { - log.add(LogLevel.ERROR, LogType.MSG_CR_ERROR_MASTER_ELGAMAL, indent); - return new EditKeyResult(EditKeyResult.RESULT_ERROR, log, null); - } - subProgressPush(10, 30); - PGPKeyPair keyPair = createKey(add.mAlgorithm, add.mKeysize, log, indent); + PGPKeyPair keyPair = createKey(add, log, indent); subProgressPop(); // return null if this failed (an error will already have been logged by createKey) @@ -690,8 +752,8 @@ public class PgpKeyOperation { progress(R.string.progress_modify_subkeyadd, (i-1) * (100 / saveParcel.mAddSubKeys.size())); SaveKeyringParcel.SubkeyAdd add = saveParcel.mAddSubKeys.get(i); - log.add(LogLevel.INFO, LogType.MSG_MF_SUBKEY_NEW, indent, Integer.toString(add.mKeysize), - PgpKeyHelper.getAlgorithmInfo(add.mAlgorithm) ); + log.add(LogLevel.INFO, LogType.MSG_MF_SUBKEY_NEW, indent, + PgpKeyHelper.getAlgorithmInfo(add.mAlgorithm, add.mKeySize, add.mCurve) ); if (add.mExpiry == null) { log.add(LogLevel.ERROR, LogType.MSG_MF_ERROR_NULL_EXPIRY, indent +1); @@ -708,7 +770,7 @@ public class PgpKeyOperation { (i-1) * (100 / saveParcel.mAddSubKeys.size()), i * (100 / saveParcel.mAddSubKeys.size()) ); - PGPKeyPair keyPair = createKey(add.mAlgorithm, add.mKeysize, log, indent); + PGPKeyPair keyPair = createKey(add, log, indent); subProgressPop(); if (keyPair == null) { log.add(LogLevel.ERROR, LogType.MSG_MF_ERROR_PGP, indent +1); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedKeyRing.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedKeyRing.java index caacb948e..9effe4e67 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedKeyRing.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedKeyRing.java @@ -37,7 +37,6 @@ import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException; import org.sufficientlysecure.keychain.service.OperationResultParcel.LogLevel; import org.sufficientlysecure.keychain.service.OperationResultParcel.LogType; import org.sufficientlysecure.keychain.service.OperationResultParcel.OperationLog; -import org.sufficientlysecure.keychain.service.OperationResults; import org.sufficientlysecure.keychain.util.IterableIterator; import org.sufficientlysecure.keychain.util.Log; @@ -58,7 +57,8 @@ import java.util.TreeSet; * This class and its relatives UncachedPublicKey and UncachedSecretKey are * used to move around pgp key rings in non crypto related (UI, mostly) code. * It should be used for simple inspection only until it saved in the database, - * all actual crypto operations should work with WrappedKeyRings exclusively. + * all actual crypto operations should work with CanonicalizedKeyRings + * exclusively. * * This class is also special in that it can hold either the PGPPublicKeyRing * or PGPSecretKeyRing derivate of the PGPKeyRing class, since these are @@ -591,7 +591,7 @@ public class UncachedKeyRing { } - // if we already have a cert, and this one is not newer: skip it + // if we already have a cert, and this one is older: skip it if (selfCert != null && cert.getCreationTime().before(selfCert.getCreationTime())) { log.add(LogLevel.DEBUG, LogType.MSG_KC_SUB_DUP, indent); redundantCerts += 1; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedPublicKey.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedPublicKey.java index dda52d786..c7a8bb1d0 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedPublicKey.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedPublicKey.java @@ -18,6 +18,10 @@ package org.sufficientlysecure.keychain.pgp; +import org.spongycastle.asn1.ASN1ObjectIdentifier; +import org.spongycastle.asn1.nist.NISTNamedCurves; +import org.spongycastle.asn1.teletrust.TeleTrusTNamedCurves; +import org.spongycastle.bcpg.ECPublicBCPGKey; import org.spongycastle.bcpg.sig.KeyFlags; import org.spongycastle.openpgp.PGPPublicKey; import org.spongycastle.openpgp.PGPSignature; @@ -94,10 +98,23 @@ public class UncachedPublicKey { return mPublicKey.getAlgorithm(); } - public int getBitStrength() { + public Integer getBitStrength() { + if (isEC()) { + return null; + } return mPublicKey.getBitStrength(); } + public String getCurveOid() { + if ( ! isEC()) { + return null; + } + if ( ! (mPublicKey.getPublicKeyPacket().getKey() instanceof ECPublicBCPGKey)) { + return null; + } + return ((ECPublicBCPGKey) mPublicKey.getPublicKeyPacket().getKey()).getCurveOID().getId(); + } + /** Returns the primary user id, as indicated by the public key's self certificates. * * This is an expensive operation, since potentially a lot of certificates (and revocations) @@ -186,6 +203,10 @@ public class UncachedPublicKey { return getAlgorithm() == PGPPublicKey.DSA; } + public boolean isEC() { + return getAlgorithm() == PGPPublicKey.ECDH || getAlgorithm() == PGPPublicKey.ECDSA; + } + @SuppressWarnings("unchecked") // TODO make this safe public int getKeyUsage() { diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainContract.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainContract.java index 24d86dc4a..4f6e878b4 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainContract.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainContract.java @@ -39,6 +39,7 @@ public class KeychainContract { String FINGERPRINT = "fingerprint"; String KEY_SIZE = "key_size"; + String KEY_CURVE_OID = "key_curve_oid"; String CAN_SIGN = "can_sign"; String CAN_ENCRYPT = "can_encrypt"; String CAN_CERTIFY = "can_certify"; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainDatabase.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainDatabase.java index 36e94208d..0bb43d47f 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainDatabase.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainDatabase.java @@ -52,7 +52,7 @@ import java.io.IOException; */ public class KeychainDatabase extends SQLiteOpenHelper { private static final String DATABASE_NAME = "openkeychain.db"; - private static final int DATABASE_VERSION = 2; + private static final int DATABASE_VERSION = 3; static Boolean apgHack = false; public interface Tables { @@ -86,6 +86,7 @@ public class KeychainDatabase extends SQLiteOpenHelper { + KeysColumns.KEY_ID + " INTEGER, " + KeysColumns.KEY_SIZE + " INTEGER, " + + KeysColumns.KEY_CURVE_OID + " TEXT, " + KeysColumns.ALGORITHM + " INTEGER, " + KeysColumns.FINGERPRINT + " BLOB, " @@ -202,13 +203,20 @@ public class KeychainDatabase extends SQLiteOpenHelper { @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { - if (oldVersion == 1) { - // add has_secret for all who are upgrading from a beta version - try { - db.execSQL("ALTER TABLE keys ADD COLUMN has_secret BOOLEAN"); - } catch (Exception e) { - // never mind, the column probably already existed - } + // add has_secret for all who are upgrading from a beta version + switch (oldVersion) { + case 1: + try { + db.execSQL("ALTER TABLE keys ADD COLUMN has_secret BOOLEAN"); + } catch(Exception e){ + // never mind, the column probably already existed + } + case 2: + try { + db.execSQL("ALTER TABLE keys ADD COLUMN " + KeysColumns.KEY_CURVE_OID + " TEXT"); + } catch(Exception e){ + // never mind, the column probably already existed + } } } 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 b2a47cccd..f6df4a3eb 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java @@ -246,6 +246,7 @@ public class KeychainProvider extends ContentProvider { projectionMap.put(KeyRings.MASTER_KEY_ID, Tables.KEYS + "." + Keys.MASTER_KEY_ID); projectionMap.put(KeyRings.KEY_ID, Tables.KEYS + "." + Keys.KEY_ID); projectionMap.put(KeyRings.KEY_SIZE, Tables.KEYS + "." + Keys.KEY_SIZE); + projectionMap.put(KeyRings.KEY_CURVE_OID, Tables.KEYS + "." + Keys.KEY_CURVE_OID); projectionMap.put(KeyRings.IS_REVOKED, Tables.KEYS + "." + Keys.IS_REVOKED); projectionMap.put(KeyRings.CAN_CERTIFY, Tables.KEYS + "." + Keys.CAN_CERTIFY); projectionMap.put(KeyRings.CAN_ENCRYPT, Tables.KEYS + "." + Keys.CAN_ENCRYPT); @@ -412,6 +413,7 @@ public class KeychainProvider extends ContentProvider { projectionMap.put(Keys.RANK, Tables.KEYS + "." + Keys.RANK); projectionMap.put(Keys.KEY_ID, Keys.KEY_ID); projectionMap.put(Keys.KEY_SIZE, Keys.KEY_SIZE); + projectionMap.put(Keys.KEY_CURVE_OID, Keys.KEY_CURVE_OID); projectionMap.put(Keys.IS_REVOKED, Keys.IS_REVOKED); projectionMap.put(Keys.CAN_CERTIFY, Keys.CAN_CERTIFY); projectionMap.put(Keys.CAN_ENCRYPT, Keys.CAN_ENCRYPT); 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 16ff2286b..bb095c340 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java @@ -62,7 +62,6 @@ import org.sufficientlysecure.keychain.util.FileImportCache; import org.sufficientlysecure.keychain.util.IterableIterator; import org.sufficientlysecure.keychain.util.Log; import org.sufficientlysecure.keychain.util.ProgressFixedScaler; -import org.sufficientlysecure.keychain.util.ProgressScaler; import java.io.ByteArrayOutputStream; import java.io.IOException; @@ -328,6 +327,7 @@ public class ProviderHelper { values.put(Keys.KEY_ID, key.getKeyId()); values.put(Keys.KEY_SIZE, key.getBitStrength()); + values.put(Keys.KEY_CURVE_OID, key.getCurveOid()); values.put(Keys.ALGORITHM, key.getAlgorithm()); values.put(Keys.FINGERPRINT, key.getFingerprint()); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/OperationResultParcel.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/OperationResultParcel.java index 886f77068..b69ecef34 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/OperationResultParcel.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/OperationResultParcel.java @@ -347,9 +347,14 @@ public class OperationResultParcel implements Parcelable { MSG_CR_ERROR_NO_CERTIFY (R.string.msg_cr_error_no_certify), MSG_CR_ERROR_NULL_EXPIRY(R.string.msg_cr_error_null_expiry), MSG_CR_ERROR_KEYSIZE_512 (R.string.msg_cr_error_keysize_512), + MSG_CR_ERROR_NO_KEYSIZE (R.string.msg_cr_error_no_keysize), + MSG_CR_ERROR_NO_CURVE (R.string.msg_cr_error_no_curve), MSG_CR_ERROR_UNKNOWN_ALGO (R.string.msg_cr_error_unknown_algo), MSG_CR_ERROR_INTERNAL_PGP (R.string.msg_cr_error_internal_pgp), - MSG_CR_ERROR_MASTER_ELGAMAL (R.string.msg_cr_error_master_elgamal), + MSG_CR_ERROR_FLAGS_DSA (R.string.msg_cr_error_flags_dsa), + MSG_CR_ERROR_FLAGS_ELGAMAL (R.string.msg_cr_error_flags_elgamal), + MSG_CR_ERROR_FLAGS_ECDSA (R.string.msg_cr_error_flags_ecdsa), + MSG_CR_ERROR_FLAGS_ECDH (R.string.msg_cr_error_flags_ecdh), // secret key modify MSG_MF (R.string.msg_mr), diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/SaveKeyringParcel.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/SaveKeyringParcel.java index 6e06c4fa9..996ce6a5a 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/SaveKeyringParcel.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/SaveKeyringParcel.java @@ -80,14 +80,16 @@ public class SaveKeyringParcel implements Parcelable { // performance gain for using Parcelable here would probably be negligible, // use Serializable instead. public static class SubkeyAdd implements Serializable { - public int mAlgorithm; - public int mKeysize; + public Algorithm mAlgorithm; + public Integer mKeySize; + public Curve mCurve; public int mFlags; public Long mExpiry; - public SubkeyAdd(int algorithm, int keysize, int flags, Long expiry) { + public SubkeyAdd(Algorithm algorithm, Integer keySize, Curve curve, int flags, Long expiry) { mAlgorithm = algorithm; - mKeysize = keysize; + mKeySize = keySize; + mCurve = curve; mFlags = flags; mExpiry = expiry; } @@ -95,7 +97,8 @@ public class SaveKeyringParcel implements Parcelable { @Override public String toString() { String out = "mAlgorithm: " + mAlgorithm + ", "; - out += "mKeysize: " + mKeysize + ", "; + out += "mKeySize: " + mKeySize + ", "; + out += "mCurve: " + mCurve + ", "; out += "mFlags: " + mFlags; out += "mExpiry: " + mExpiry; @@ -214,4 +217,20 @@ public class SaveKeyringParcel implements Parcelable { return out; } + + // All supported algorithms + public enum Algorithm { + RSA, DSA, ELGAMAL, ECDSA, ECDH + } + + // All curves defined in the standard + // http://www.bouncycastle.org/wiki/pages/viewpage.action?pageId=362269 + public enum Curve { + NIST_P256, NIST_P384, NIST_P521, + + // these are supported by gpg, but they are not in rfc6637 and not supported by BouncyCastle yet + // (adding support would be trivial though -> JcaPGPKeyConverter.java:190) + // BRAINPOOL_P256, BRAINPOOL_P384, BRAINPOOL_P512 + } + } 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 d804b9b70..69f4af04b 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.OperationResultParcel; import org.sufficientlysecure.keychain.service.OperationResults; import org.sufficientlysecure.keychain.service.SaveKeyringParcel; +import org.sufficientlysecure.keychain.service.SaveKeyringParcel.Algorithm; import org.sufficientlysecure.keychain.util.Log; import org.sufficientlysecure.keychain.util.Notify; @@ -165,9 +166,12 @@ public class CreateKeyFinalFragment extends Fragment { Bundle data = new Bundle(); SaveKeyringParcel parcel = new SaveKeyringParcel(); - parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd(PublicKeyAlgorithmTags.RSA_GENERAL, 4096, KeyFlags.CERTIFY_OTHER, 0L)); - parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd(PublicKeyAlgorithmTags.RSA_GENERAL, 4096, KeyFlags.SIGN_DATA, 0L)); - parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd(PublicKeyAlgorithmTags.RSA_GENERAL, 4096, KeyFlags.ENCRYPT_COMMS | KeyFlags.ENCRYPT_STORAGE, 0L)); + parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( + Algorithm.RSA, 4096, null, KeyFlags.CERTIFY_OTHER, 0L)); + parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( + Algorithm.RSA, 4096, null, KeyFlags.SIGN_DATA, 0L)); + parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( + Algorithm.RSA, 4096, null, KeyFlags.ENCRYPT_COMMS | KeyFlags.ENCRYPT_STORAGE, 0L)); String userId = KeyRing.createUserId(mName, mEmail, null); parcel.mAddUserIds.add(userId); parcel.mChangePrimaryUserId = userId; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewCertActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewCertActivity.java index 48e9da87f..92f38a44c 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewCertActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewCertActivity.java @@ -167,7 +167,7 @@ public class ViewCertActivity extends ActionBarActivity mStatus.setTextColor(getResources().getColor(R.color.black)); } - String algorithmStr = PgpKeyHelper.getAlgorithmInfo(this, sig.getKeyAlgorithm(), 0); + String algorithmStr = PgpKeyHelper.getAlgorithmInfo(this, sig.getKeyAlgorithm(), null, null); mAlgorithm.setText(algorithmStr); mRowReason.setVisibility(View.GONE); 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 1f809cc51..1fed58721 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 @@ -155,8 +155,8 @@ public class ImportKeysAdapter extends ArrayAdapter { // don't show full fingerprint on key import holder.fingerprint.setVisibility(View.GONE); - if (entry.getBitStrength() != 0 && entry.getAlgorithm() != null) { - holder.algorithm.setText("" + entry.getBitStrength() + "/" + entry.getAlgorithm()); + if (entry.getAlgorithm() != null) { + holder.algorithm.setText(entry.getAlgorithm()); holder.algorithm.setVisibility(View.VISIBLE); } else { holder.algorithm.setVisibility(View.INVISIBLE); 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 9958b33a1..489cbcefb 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 @@ -52,6 +52,7 @@ public class SubkeysAdapter extends CursorAdapter { Keys.RANK, Keys.ALGORITHM, Keys.KEY_SIZE, + Keys.KEY_CURVE_OID, Keys.HAS_SECRET, Keys.CAN_CERTIFY, Keys.CAN_ENCRYPT, @@ -66,14 +67,15 @@ public class SubkeysAdapter extends CursorAdapter { private static final int INDEX_RANK = 2; private static final int INDEX_ALGORITHM = 3; private static final int INDEX_KEY_SIZE = 4; - private static final int INDEX_HAS_SECRET = 5; - private static final int INDEX_CAN_CERTIFY = 6; - private static final int INDEX_CAN_ENCRYPT = 7; - private static final int INDEX_CAN_SIGN = 8; - private static final int INDEX_IS_REVOKED = 9; - private static final int INDEX_CREATION = 10; - private static final int INDEX_EXPIRY = 11; - private static final int INDEX_FINGERPRINT = 12; + private static final int INDEX_KEY_CURVE_OID = 5; + private static final int INDEX_HAS_SECRET = 6; + private static final int INDEX_CAN_CERTIFY = 7; + private static final int INDEX_CAN_ENCRYPT = 8; + private static final int INDEX_CAN_SIGN = 9; + private static final int INDEX_IS_REVOKED = 10; + private static final int INDEX_CREATION = 11; + private static final int INDEX_EXPIRY = 12; + private static final int INDEX_FINGERPRINT = 13; public SubkeysAdapter(Context context, Cursor c, int flags, SaveKeyringParcel saveKeyringParcel) { @@ -141,7 +143,8 @@ public class SubkeysAdapter extends CursorAdapter { String algorithmStr = PgpKeyHelper.getAlgorithmInfo( context, cursor.getInt(INDEX_ALGORITHM), - cursor.getInt(INDEX_KEY_SIZE) + cursor.getInt(INDEX_KEY_SIZE), + cursor.getString(INDEX_KEY_CURVE_OID) ); vKeyId.setText(keyIdStr); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/SubkeysAddedAdapter.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/SubkeysAddedAdapter.java index a1dfeb10c..d50318fb4 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/SubkeysAddedAdapter.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/SubkeysAddedAdapter.java @@ -42,14 +42,10 @@ public class SubkeysAddedAdapter extends ArrayAdapter mData; - public SubkeysAddedAdapter(Activity activity, List data) { super(activity, -1, data); mActivity = activity; mInflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE); - mData = data; } static class ViewHolder { @@ -103,7 +99,8 @@ public class SubkeysAddedAdapter extends ArrayAdapter choices = new ArrayList(); - choices.add(new Choice(PublicKeyAlgorithmTags.DSA, getResources().getString( - R.string.dsa))); - if (!mWillBeMasterKey) { - choices.add(new Choice(PublicKeyAlgorithmTags.ELGAMAL_ENCRYPT, getResources().getString( - R.string.elgamal))); - } - choices.add(new Choice(PublicKeyAlgorithmTags.RSA_GENERAL, getResources().getString( - R.string.rsa))); - choices.add(new Choice(PublicKeyAlgorithmTags.ECDH, getResources().getString( - R.string.ecdh))); - choices.add(new Choice(PublicKeyAlgorithmTags.ECDSA, getResources().getString( - R.string.ecdsa))); - ArrayAdapter adapter = new ArrayAdapter(context, - android.R.layout.simple_spinner_item, choices); - adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); - mAlgorithmSpinner.setAdapter(adapter); - // make RSA the default - for (int i = 0; i < choices.size(); ++i) { - if (choices.get(i).getId() == PublicKeyAlgorithmTags.RSA_GENERAL) { - mAlgorithmSpinner.setSelection(i); - break; + { + ArrayList> choices = new ArrayList>(); + choices.add(new Choice(Algorithm.DSA, getResources().getString( + R.string.dsa))); + if (!mWillBeMasterKey) { + choices.add(new Choice(Algorithm.ELGAMAL, getResources().getString( + R.string.elgamal))); + } + choices.add(new Choice(Algorithm.RSA, getResources().getString( + R.string.rsa))); + choices.add(new Choice(Algorithm.ECDSA, getResources().getString( + R.string.ecdsa))); + choices.add(new Choice(Algorithm.ECDH, getResources().getString( + R.string.ecdh))); + ArrayAdapter> adapter = new ArrayAdapter>(context, + android.R.layout.simple_spinner_item, choices); + adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); + mAlgorithmSpinner.setAdapter(adapter); + // make RSA the default + for (int i = 0; i < choices.size(); ++i) { + if (choices.get(i).getId() == Algorithm.RSA) { + mAlgorithmSpinner.setSelection(i); + break; + } } } @@ -172,6 +178,36 @@ public class AddSubkeyDialogFragment extends DialogFragment { mKeySizeSpinner.setAdapter(keySizeAdapter); mKeySizeSpinner.setSelection(1); // Default to 4096 for the key length + { + ArrayList> choices = new ArrayList>(); + + choices.add(new Choice(Curve.NIST_P256, getResources().getString( + R.string.key_curve_nist_p256))); + choices.add(new Choice(Curve.NIST_P384, getResources().getString( + R.string.key_curve_nist_p384))); + choices.add(new Choice(Curve.NIST_P521, getResources().getString( + R.string.key_curve_nist_p521))); + + /* @see SaveKeyringParcel + choices.add(new Choice(Curve.BRAINPOOL_P256, getResources().getString( + R.string.key_curve_bp_p256))); + choices.add(new Choice(Curve.BRAINPOOL_P384, getResources().getString( + R.string.key_curve_bp_p384))); + choices.add(new Choice(Curve.BRAINPOOL_P512, getResources().getString( + R.string.key_curve_bp_p512))); + */ + + ArrayAdapter> adapter = new ArrayAdapter>(context, + android.R.layout.simple_spinner_item, choices); + mCurveSpinner.setAdapter(adapter); + // make NIST P-256 the default + for (int i = 0; i < choices.size(); ++i) { + if (choices.get(i).getId() == Curve.NIST_P256) { + mCurveSpinner.setSelection(i); + break; + } + } + } dialog.setCancelable(true); @@ -211,7 +247,7 @@ public class AddSubkeyDialogFragment extends DialogFragment { mAlgorithmSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { @Override public void onItemSelected(AdapterView parent, View view, int position, long id) { - updateUiForAlgorithm(((Choice) parent.getSelectedItem()).getId()); + updateUiForAlgorithm(((Choice) parent.getSelectedItem()).getId()); setCustomKeyVisibility(); setOkButtonAvailability(alertDialog); @@ -241,11 +277,16 @@ public class AddSubkeyDialogFragment extends DialogFragment { return; } - // dismiss only if at least one flag is selected - dismiss(); - - Choice newKeyAlgorithmChoice = (Choice) mAlgorithmSpinner.getSelectedItem(); - int newKeySize = getProperKeyLength(newKeyAlgorithmChoice.getId(), getSelectedKeyLength()); + Algorithm algorithm = ((Choice) mAlgorithmSpinner.getSelectedItem()).getId(); + Curve curve = null; + Integer keySize = null; + // For EC keys, add a curve + if (algorithm == Algorithm.ECDH || algorithm == Algorithm.ECDSA) { + curve = ((Choice) mCurveSpinner.getSelectedItem()).getId(); + // Otherwise, get a keysize + } else { + keySize = getProperKeyLength(algorithm, getSelectedKeyLength()); + } int flags = 0; if (mFlagCertify.isChecked()) { @@ -276,12 +317,12 @@ public class AddSubkeyDialogFragment extends DialogFragment { } SaveKeyringParcel.SubkeyAdd newSubkey = new SaveKeyringParcel.SubkeyAdd( - newKeyAlgorithmChoice.getId(), - newKeySize, - flags, - expiry + algorithm, keySize, curve, flags, expiry ); mAlgorithmSelectedListener.onAlgorithmSelected(newSubkey); + + // finally, dismiss the dialogue + dismiss(); } }); negativeButton.setOnClickListener(new View.OnClickListener() { @@ -323,16 +364,16 @@ public class AddSubkeyDialogFragment extends DialogFragment { * @return correct key length, according to SpongyCastle specification. Returns -1, if key length is * inappropriate. */ - private int getProperKeyLength(int algorithmId, int currentKeyLength) { + private int getProperKeyLength(Algorithm algorithm, int currentKeyLength) { final int[] elGamalSupportedLengths = {1536, 2048, 3072, 4096, 8192}; int properKeyLength = -1; - switch (algorithmId) { - case PublicKeyAlgorithmTags.RSA_GENERAL: + switch (algorithm) { + case RSA: if (currentKeyLength > 1024 && currentKeyLength <= 16384) { properKeyLength = currentKeyLength + ((8 - (currentKeyLength % 8)) % 8); } break; - case PublicKeyAlgorithmTags.ELGAMAL_ENCRYPT: + case ELGAMAL: int[] elGammalKeyDiff = new int[elGamalSupportedLengths.length]; for (int i = 0; i < elGamalSupportedLengths.length; i++) { elGammalKeyDiff[i] = Math.abs(elGamalSupportedLengths[i] - currentKeyLength); @@ -347,7 +388,7 @@ public class AddSubkeyDialogFragment extends DialogFragment { } properKeyLength = elGamalSupportedLengths[minimalIndex]; break; - case PublicKeyAlgorithmTags.DSA: + case DSA: if (currentKeyLength >= 512 && currentKeyLength <= 1024) { properKeyLength = currentKeyLength + ((64 - (currentKeyLength % 64)) % 64); } @@ -357,10 +398,10 @@ public class AddSubkeyDialogFragment extends DialogFragment { } private void setOkButtonAvailability(AlertDialog alertDialog) { - final Choice selectedAlgorithm = (Choice) mAlgorithmSpinner.getSelectedItem(); - final int selectedKeySize = getSelectedKeyLength(); //Integer.parseInt((String) mKeySizeSpinner.getSelectedItem()); - final int properKeyLength = getProperKeyLength(selectedAlgorithm.getId(), selectedKeySize); - alertDialog.getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(properKeyLength > 0); + Algorithm algorithm = ((Choice) mAlgorithmSpinner.getSelectedItem()).getId(); + boolean enabled = algorithm == Algorithm.ECDSA || algorithm == Algorithm.ECDH + || getProperKeyLength(algorithm, getSelectedKeyLength()) > 0; + alertDialog.getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(enabled); } private void setCustomKeyVisibility() { @@ -376,18 +417,20 @@ public class AddSubkeyDialogFragment extends DialogFragment { // hide keyboard after setting visibility to gone if (visibility == View.GONE) { InputMethodManager imm = (InputMethodManager) - getActivity().getSystemService(getActivity().INPUT_METHOD_SERVICE); + getActivity().getSystemService(FragmentActivity.INPUT_METHOD_SERVICE); imm.hideSoftInputFromWindow(mCustomKeyEditText.getWindowToken(), 0); } } - private void updateUiForAlgorithm(int algorithmId) { + private void updateUiForAlgorithm(Algorithm algorithm) { final ArrayAdapter keySizeAdapter = (ArrayAdapter) mKeySizeSpinner.getAdapter(); - final Object selectedItem = mKeySizeSpinner.getSelectedItem(); keySizeAdapter.clear(); - switch (algorithmId) { - case PublicKeyAlgorithmTags.RSA_GENERAL: + switch (algorithm) { + case RSA: replaceArrayAdapterContent(keySizeAdapter, R.array.rsa_key_size_spinner_values); + mKeySizeSpinner.setSelection(1); + mKeySizeRow.setVisibility(View.VISIBLE); + mCurveRow.setVisibility(View.GONE); mCustomKeyInfoTextView.setText(getResources().getString(R.string.key_size_custom_info_rsa)); // allowed flags: mFlagSign.setEnabled(true); @@ -409,8 +452,11 @@ public class AddSubkeyDialogFragment extends DialogFragment { } mFlagAuthenticate.setChecked(false); break; - case PublicKeyAlgorithmTags.ELGAMAL_ENCRYPT: + case ELGAMAL: replaceArrayAdapterContent(keySizeAdapter, R.array.elgamal_key_size_spinner_values); + mKeySizeSpinner.setSelection(3); + mKeySizeRow.setVisibility(View.VISIBLE); + mCurveRow.setVisibility(View.GONE); mCustomKeyInfoTextView.setText(""); // ElGamal does not support custom key length // allowed flags: mFlagCertify.setChecked(false); @@ -422,8 +468,11 @@ public class AddSubkeyDialogFragment extends DialogFragment { mFlagAuthenticate.setChecked(false); mFlagAuthenticate.setEnabled(false); break; - case PublicKeyAlgorithmTags.DSA: + case DSA: replaceArrayAdapterContent(keySizeAdapter, R.array.dsa_key_size_spinner_values); + mKeySizeSpinner.setSelection(2); + mKeySizeRow.setVisibility(View.VISIBLE); + mCurveRow.setVisibility(View.GONE); mCustomKeyInfoTextView.setText(getResources().getString(R.string.key_size_custom_info_dsa)); // allowed flags: mFlagCertify.setChecked(false); @@ -435,16 +484,37 @@ public class AddSubkeyDialogFragment extends DialogFragment { mFlagAuthenticate.setChecked(false); mFlagAuthenticate.setEnabled(false); break; + case ECDSA: + mKeySizeRow.setVisibility(View.GONE); + mCurveRow.setVisibility(View.VISIBLE); + mCustomKeyInfoTextView.setText(""); + // allowed flags: + mFlagCertify.setEnabled(mWillBeMasterKey); + mFlagCertify.setChecked(mWillBeMasterKey); + mFlagSign.setEnabled(true); + mFlagSign.setChecked(!mWillBeMasterKey); + mFlagEncrypt.setEnabled(false); + mFlagEncrypt.setChecked(false); + mFlagAuthenticate.setEnabled(true); + mFlagAuthenticate.setChecked(false); + break; + case ECDH: + mKeySizeRow.setVisibility(View.GONE); + mCurveRow.setVisibility(View.VISIBLE); + mCustomKeyInfoTextView.setText(""); + // allowed flags: + mFlagCertify.setChecked(false); + mFlagCertify.setEnabled(false); + mFlagSign.setChecked(false); + mFlagSign.setEnabled(false); + mFlagEncrypt.setChecked(true); + mFlagEncrypt.setEnabled(true); + mFlagAuthenticate.setChecked(false); + mFlagAuthenticate.setEnabled(false); + break; } keySizeAdapter.notifyDataSetChanged(); - // when switching algorithm, try to select same key length as before - for (int i = 0; i < keySizeAdapter.getCount(); i++) { - if (selectedItem.equals(keySizeAdapter.getItem(i))) { - mKeySizeSpinner.setSelection(i); - break; - } - } } @TargetApi(Build.VERSION_CODES.HONEYCOMB) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/Choice.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/Choice.java index 70c7d80fe..48f10d4b9 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/Choice.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/Choice.java @@ -17,21 +17,16 @@ package org.sufficientlysecure.keychain.util; -public class Choice { +public class Choice { private String mName; - private int mId; + private E mId; - public Choice() { - mId = -1; - mName = ""; - } - - public Choice(int id, String name) { + public Choice(E id, String name) { mId = id; mName = name; } - public int getId() { + public E getId() { return mId; } diff --git a/OpenKeychain/src/main/res/layout/add_subkey_dialog.xml b/OpenKeychain/src/main/res/layout/add_subkey_dialog.xml index e1ccfee1f..7af73be09 100644 --- a/OpenKeychain/src/main/res/layout/add_subkey_dialog.xml +++ b/OpenKeychain/src/main/res/layout/add_subkey_dialog.xml @@ -34,7 +34,7 @@ android:padding="4dp" /> - + + + + + + + + Expiry Usage Key Size + Elliptic Curve Primary identity Name Comment @@ -270,6 +271,8 @@ generating new RSA key… generating new DSA key… generating new ElGamal key… + generating new ECDSA key… + generating new ECDH key… modifying keyring… @@ -326,6 +329,16 @@ RSA key length must be greater than 1024 and at most 16384. Also it must be multiplicity of 8. DSA key length must be at least 512 and at most 1024. Also it must be multiplicity of 64. + + NIST P-256 + NIST P-384 + NIST P-521 + + fast very slow @@ -636,9 +649,14 @@ Master key must have certify flag! Expiry time cannot be "same as before" on key creation. This is a programming error, please file a bug report! Key size must be greater or equal 512! + No key size specified! This is a programming error, please file a bug report! + No elliptic curve specified! This is a programming error, please file a bug report! Internal PGP error! - Bad algorithm choice! - Master key must not be of type ElGamal! + Unknown algorithm selected! This is a programming error, please file a bug report! + Bad key flags selected, DSA cannot be used for encryption! + Bad key flags selected, ElGamal cannot be used for signing! + Bad key flags selected, ECDSA cannot be used for encryption! + Bad key flags selected, ECDH cannot be used for signing! Modifying keyring %s @@ -663,7 +681,7 @@ Generating new certificate for new primary user id Modifying subkey %s Tried to operate on missing subkey %s! - Adding new subkey of type %2$s (%1$s bit) + Adding new subkey of type %s New subkey ID: %s Expiry date cannot be in the past! Revoking subkey %s -- cgit v1.2.3 From 5ddbbb76bee45d801b184748d6535a736dffde57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Tue, 26 Aug 2014 08:50:44 +0200 Subject: Function graphic --- Resources/graphics/function.png | Bin 0 -> 97519 bytes Resources/graphics/function.svg | 4042 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 4042 insertions(+) create mode 100644 Resources/graphics/function.png create mode 100644 Resources/graphics/function.svg diff --git a/Resources/graphics/function.png b/Resources/graphics/function.png new file mode 100644 index 000000000..9b8983c48 Binary files /dev/null and b/Resources/graphics/function.png differ diff --git a/Resources/graphics/function.svg b/Resources/graphics/function.svg new file mode 100644 index 000000000..97bc936ba --- /dev/null +++ b/Resources/graphics/function.svg @@ -0,0 +1,4042 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + Dominik Schürmann + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Manage Keys.Encrypt your Files and Communications.Compatible with the OpenPGP Standard. + + + -- cgit v1.2.3 From 86a05033aedc965c1842db45094c744094a906af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Wed, 27 Aug 2014 13:54:33 +0200 Subject: Cleanup FoldableLinearLayout --- .../keychain/ui/widget/FoldableLinearLayout.java | 10 ++++------ .../src/main/res/layout/api_account_settings_fragment.xml | 4 +--- OpenKeychain/src/main/res/layout/api_app_settings_fragment.xml | 6 ++---- OpenKeychain/src/main/res/layout/foldable_linearlayout.xml | 5 ++--- OpenKeychain/src/main/res/values/attr.xml | 2 -- 5 files changed, 9 insertions(+), 18 deletions(-) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/FoldableLinearLayout.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/FoldableLinearLayout.java index 31e01a7fb..b456b61ab 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/FoldableLinearLayout.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/FoldableLinearLayout.java @@ -24,7 +24,7 @@ import android.view.LayoutInflater; import android.view.View; import android.view.animation.AlphaAnimation; import android.view.animation.Animation; -import android.widget.ImageButton; +import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.TextView; @@ -38,9 +38,7 @@ import org.sufficientlysecure.keychain.R; android:layout_width="wrap_content" android:layout_height="wrap_content" custom:foldedLabel="@string/TEXT_TO_DISPLAY_WHEN_FOLDED" - custom:unFoldedLabel="@string/TEXT_TO_DISPLAY_WHEN_UNFOLDED" - custom:foldedIcon="ICON_NAME_FROM_FontAwesomeText_TO_USE_WHEN_FOLDED" - custom:unFoldedIcon="ICON_NAME_FROM_FontAwesomeText_TO_USE_WHEN_UNFOLDED"> + custom:unFoldedLabel="@string/TEXT_TO_DISPLAY_WHEN_UNFOLDED"> @@ -49,7 +47,7 @@ import org.sufficientlysecure.keychain.R; */ public class FoldableLinearLayout extends LinearLayout { - private ImageButton mFoldableIcon; + private ImageView mFoldableIcon; private boolean mFolded; private boolean mHasMigrated = false; private Integer mShortAnimationDuration = null; @@ -139,7 +137,7 @@ public class FoldableLinearLayout extends LinearLayout { } private void initialiseInnerViews() { - mFoldableIcon = (ImageButton) mFoldableLayout.findViewById(R.id.foldableIcon); + mFoldableIcon = (ImageView) mFoldableLayout.findViewById(R.id.foldableIcon); mFoldableIcon.setImageResource(R.drawable.ic_action_expand); mFoldableTextView = (TextView) mFoldableLayout.findViewById(R.id.foldableText); mFoldableTextView.setText(mFoldedLabel); diff --git a/OpenKeychain/src/main/res/layout/api_account_settings_fragment.xml b/OpenKeychain/src/main/res/layout/api_account_settings_fragment.xml index aaeae78e0..d8e1d9ad8 100644 --- a/OpenKeychain/src/main/res/layout/api_account_settings_fragment.xml +++ b/OpenKeychain/src/main/res/layout/api_account_settings_fragment.xml @@ -59,9 +59,7 @@ android:layout_width="match_parent" android:layout_height="match_parent" custom:foldedLabel="@string/api_settings_show_advanced" - custom:unFoldedLabel="@string/api_settings_hide_advanced" - custom:foldedIcon="fa-chevron-right" - custom:unFoldedIcon="fa-chevron-down"> + custom:unFoldedLabel="@string/api_settings_hide_advanced"> + custom:unFoldedLabel="@string/api_settings_hide_info"> diff --git a/OpenKeychain/src/main/res/layout/foldable_linearlayout.xml b/OpenKeychain/src/main/res/layout/foldable_linearlayout.xml index 3d2fb688b..13cf7c225 100644 --- a/OpenKeychain/src/main/res/layout/foldable_linearlayout.xml +++ b/OpenKeychain/src/main/res/layout/foldable_linearlayout.xml @@ -11,14 +11,13 @@ android:orientation="horizontal" android:clickable="true"> - + android:src="@drawable/ic_action_expand"/> - - \ No newline at end of file -- cgit v1.2.3 From 12a5b2174f79d93e8531fa4e0b3fc0def3796ca9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Wed, 27 Aug 2014 14:12:59 +0200 Subject: Abort import of pubkeys where secret keys exist but new pubkey has more subkeys, fix #696 --- .../keychain/pgp/UncachedKeyRing.java | 41 +++++++++++++++++----- .../keychain/service/OperationResultParcel.java | 1 + OpenKeychain/src/main/res/values/strings.xml | 1 + 3 files changed, 34 insertions(+), 9 deletions(-) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedKeyRing.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedKeyRing.java index caacb948e..424420e72 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedKeyRing.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedKeyRing.java @@ -485,6 +485,10 @@ public class UncachedKeyRing { // Replace modified key in the keyring ring = replacePublicKey(ring, modified); + if (ring == null) { + log.add(LogLevel.ERROR, LogType.MSG_MG_NO_SECRET_KEYRING, indent); + return null; + } indent -= 1; } @@ -652,6 +656,10 @@ public class UncachedKeyRing { } // replace pubkey in keyring ring = replacePublicKey(ring, modified); + if (ring == null) { + log.add(LogLevel.ERROR, LogType.MSG_MG_NO_SECRET_KEYRING, indent); + return null; + } indent -= 1; } @@ -741,6 +749,10 @@ public class UncachedKeyRing { } else { // otherwise, just insert the public key result = replacePublicKey(result, key); + if (result == null) { + log.add(LogLevel.ERROR, LogType.MSG_MG_NO_SECRET_KEYRING, indent); + return null; + } } continue; } @@ -769,6 +781,10 @@ public class UncachedKeyRing { if (!key.isMasterKey()) { if (modified != resultKey) { result = replacePublicKey(result, modified); + if (result == null) { + log.add(LogLevel.ERROR, LogType.MSG_MG_NO_SECRET_KEYRING, indent); + return null; + } } continue; } @@ -793,6 +809,10 @@ public class UncachedKeyRing { // If anything changed, save the updated (sub)key if (modified != resultKey) { result = replacePublicKey(result, modified); + if (result == null) { + log.add(LogLevel.ERROR, LogType.MSG_MG_NO_SECRET_KEYRING, indent); + return null; + } } } @@ -838,16 +858,19 @@ public class UncachedKeyRing { */ private static PGPKeyRing replacePublicKey(PGPKeyRing ring, PGPPublicKey key) { if (ring instanceof PGPPublicKeyRing) { - return PGPPublicKeyRing.insertPublicKey((PGPPublicKeyRing) ring, key); - } - PGPSecretKeyRing secRing = (PGPSecretKeyRing) ring; - PGPSecretKey sKey = secRing.getSecretKey(key.getKeyID()); - // TODO generate secret key with S2K dummy, if none exists! for now, just die. - if (sKey == null) { - throw new RuntimeException("dummy secret key generation not yet implemented"); + PGPPublicKeyRing pubRing = (PGPPublicKeyRing) ring; + return PGPPublicKeyRing.insertPublicKey(pubRing, key); + } else { + PGPSecretKeyRing secRing = (PGPSecretKeyRing) ring; + PGPSecretKey sKey = secRing.getSecretKey(key.getKeyID()); + // TODO generate secret key with S2K dummy, if none exists! + if (sKey == null) { + Log.e(Constants.TAG, "dummy secret key generation not yet implemented"); + return null; + } + sKey = PGPSecretKey.replacePublicKey(sKey, key); + return PGPSecretKeyRing.insertSecretKey(secRing, sKey); } - sKey = PGPSecretKey.replacePublicKey(sKey, key); - return PGPSecretKeyRing.insertSecretKey(secRing, sKey); } /** This method removes a subkey in a keyring. diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/OperationResultParcel.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/OperationResultParcel.java index 886f77068..ddc456e34 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/OperationResultParcel.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/OperationResultParcel.java @@ -339,6 +339,7 @@ public class OperationResultParcel implements Parcelable { MSG_MG_NEW_SUBKEY (R.string.msg_mg_new_subkey), MSG_MG_FOUND_NEW (R.string.msg_mg_found_new), MSG_MG_UNCHANGED (R.string.msg_mg_unchanged), + MSG_MG_NO_SECRET_KEYRING (R.string.msg_mg_no_secret_keyring), // secret key create MSG_CR (R.string.msg_cr), diff --git a/OpenKeychain/src/main/res/values/strings.xml b/OpenKeychain/src/main/res/values/strings.xml index 2eb9f2b97..d8c73bd9e 100644 --- a/OpenKeychain/src/main/res/values/strings.xml +++ b/OpenKeychain/src/main/res/values/strings.xml @@ -626,6 +626,7 @@ Adding new subkey %s Found %s new certificates in keyring No new certificates + No secret keyring to add subkey to Generating new master key -- cgit v1.2.3 From cb2eb8aca2e7aab6243fd3e1a3313c941e3f1998 Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Wed, 27 Aug 2014 15:42:09 +0200 Subject: small language fixes for previous commit --- .../sufficientlysecure/keychain/pgp/UncachedKeyRing.java | 15 +++++++-------- .../keychain/service/OperationResultParcel.java | 6 +++--- OpenKeychain/src/main/res/values-es/strings.xml | 4 ++-- OpenKeychain/src/main/res/values-fr/strings.xml | 4 ++-- OpenKeychain/src/main/res/values-it/strings.xml | 4 ++-- OpenKeychain/src/main/res/values-ja/strings.xml | 4 ++-- OpenKeychain/src/main/res/values-uk/strings.xml | 4 ++-- OpenKeychain/src/main/res/values/strings.xml | 8 +++++--- 8 files changed, 25 insertions(+), 24 deletions(-) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedKeyRing.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedKeyRing.java index 424420e72..65a2fe4a0 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedKeyRing.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedKeyRing.java @@ -37,7 +37,6 @@ import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException; import org.sufficientlysecure.keychain.service.OperationResultParcel.LogLevel; import org.sufficientlysecure.keychain.service.OperationResultParcel.LogType; import org.sufficientlysecure.keychain.service.OperationResultParcel.OperationLog; -import org.sufficientlysecure.keychain.service.OperationResults; import org.sufficientlysecure.keychain.util.IterableIterator; import org.sufficientlysecure.keychain.util.Log; @@ -486,7 +485,7 @@ public class UncachedKeyRing { // Replace modified key in the keyring ring = replacePublicKey(ring, modified); if (ring == null) { - log.add(LogLevel.ERROR, LogType.MSG_MG_NO_SECRET_KEYRING, indent); + log.add(LogLevel.ERROR, LogType.MSG_MG_ERROR_SECRET_DUMMY, indent); return null; } indent -= 1; @@ -657,7 +656,7 @@ public class UncachedKeyRing { // replace pubkey in keyring ring = replacePublicKey(ring, modified); if (ring == null) { - log.add(LogLevel.ERROR, LogType.MSG_MG_NO_SECRET_KEYRING, indent); + log.add(LogLevel.ERROR, LogType.MSG_MG_ERROR_SECRET_DUMMY, indent); return null; } indent -= 1; @@ -702,7 +701,7 @@ public class UncachedKeyRing { if (getMasterKeyId() != masterKeyId || !Arrays.equals(getFingerprint(), other.getFingerprint())) { - log.add(LogLevel.ERROR, LogType.MSG_MG_HETEROGENEOUS, indent); + log.add(LogLevel.ERROR, LogType.MSG_MG_ERROR_HETEROGENEOUS, indent); return null; } @@ -750,7 +749,7 @@ public class UncachedKeyRing { // otherwise, just insert the public key result = replacePublicKey(result, key); if (result == null) { - log.add(LogLevel.ERROR, LogType.MSG_MG_NO_SECRET_KEYRING, indent); + log.add(LogLevel.ERROR, LogType.MSG_MG_ERROR_SECRET_DUMMY, indent); return null; } } @@ -782,7 +781,7 @@ public class UncachedKeyRing { if (modified != resultKey) { result = replacePublicKey(result, modified); if (result == null) { - log.add(LogLevel.ERROR, LogType.MSG_MG_NO_SECRET_KEYRING, indent); + log.add(LogLevel.ERROR, LogType.MSG_MG_ERROR_SECRET_DUMMY, indent); return null; } } @@ -810,7 +809,7 @@ public class UncachedKeyRing { if (modified != resultKey) { result = replacePublicKey(result, modified); if (result == null) { - log.add(LogLevel.ERROR, LogType.MSG_MG_NO_SECRET_KEYRING, indent); + log.add(LogLevel.ERROR, LogType.MSG_MG_ERROR_SECRET_DUMMY, indent); return null; } } @@ -827,7 +826,7 @@ public class UncachedKeyRing { return new UncachedKeyRing(result); } catch (IOException e) { - log.add(LogLevel.ERROR, LogType.MSG_MG_FATAL_ENCODE, indent); + log.add(LogLevel.ERROR, LogType.MSG_MG_ERROR_ENCODE, indent); return null; } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/OperationResultParcel.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/OperationResultParcel.java index ddc456e34..72cac4856 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/OperationResultParcel.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/OperationResultParcel.java @@ -332,14 +332,14 @@ public class OperationResultParcel implements Parcelable { // keyring consolidation + MSG_MG_ERROR_SECRET_DUMMY(R.string.msg_mg_error_secret_dummy), + MSG_MG_ERROR_ENCODE(R.string.msg_mg_error_encode), + MSG_MG_ERROR_HETEROGENEOUS(R.string.msg_mg_error_heterogeneous), MSG_MG_PUBLIC (R.string.msg_mg_public), MSG_MG_SECRET (R.string.msg_mg_secret), - MSG_MG_FATAL_ENCODE (R.string.msg_mg_fatal_encode), - MSG_MG_HETEROGENEOUS (R.string.msg_mg_heterogeneous), MSG_MG_NEW_SUBKEY (R.string.msg_mg_new_subkey), MSG_MG_FOUND_NEW (R.string.msg_mg_found_new), MSG_MG_UNCHANGED (R.string.msg_mg_unchanged), - MSG_MG_NO_SECRET_KEYRING (R.string.msg_mg_no_secret_keyring), // secret key create MSG_CR (R.string.msg_cr), diff --git a/OpenKeychain/src/main/res/values-es/strings.xml b/OpenKeychain/src/main/res/values-es/strings.xml index 9266950d2..8883d1b70 100644 --- a/OpenKeychain/src/main/res/values-es/strings.xml +++ b/OpenKeychain/src/main/res/values-es/strings.xml @@ -572,8 +572,8 @@ Incorporándolas en el juego de claves públicas %s Incorporándolas en el juego de claves secretas (privadas) %s - Error fatal codificando la firma - ¡Se intentaron fusionar juegos de claves con diferentes huellas de validación de claves! + Error fatal codificando la firma + ¡Se intentaron fusionar juegos de claves con diferentes huellas de validación de claves! Añadiendo nueva subclave %s Se encontraron %s nuevos certificados en el juego de claves No hay nuevos certificados diff --git a/OpenKeychain/src/main/res/values-fr/strings.xml b/OpenKeychain/src/main/res/values-fr/strings.xml index 4ac578ba8..db7c51867 100644 --- a/OpenKeychain/src/main/res/values-fr/strings.xml +++ b/OpenKeychain/src/main/res/values-fr/strings.xml @@ -572,8 +572,8 @@ Fusion vers le trousseau public %s Fusion vers le trousseau secret %s - Erreur fatale lors de l\'encodage de la signature - Il a été tenté de fusionner des trousseaux avec des empreintes différentes ! + Erreur fatale lors de l\'encodage de la signature + Il a été tenté de fusionner des trousseaux avec des empreintes différentes ! Ajout de la nouvelle sous-clef %s %s nouveaux certificats trouvés dans le trousseau Aucun nouveau certificat diff --git a/OpenKeychain/src/main/res/values-it/strings.xml b/OpenKeychain/src/main/res/values-it/strings.xml index 9a21a642b..9e956111f 100644 --- a/OpenKeychain/src/main/res/values-it/strings.xml +++ b/OpenKeychain/src/main/res/values-it/strings.xml @@ -572,8 +572,8 @@ Fusione nel portachiavi pubblico %s Fusione nel portachiavi privato %s - Errore fatale nella codifica della firma - Tentativo di unire portachiavi con impronte digitali diverse! + Errore fatale nella codifica della firma + Tentativo di unire portachiavi con impronte digitali diverse! Aggiunta nuova sottochiave %s Trovati %s nuovi certificati nel portachiavi Nessun nuovo certificato diff --git a/OpenKeychain/src/main/res/values-ja/strings.xml b/OpenKeychain/src/main/res/values-ja/strings.xml index 724abeab4..e2cc70f9a 100644 --- a/OpenKeychain/src/main/res/values-ja/strings.xml +++ b/OpenKeychain/src/main/res/values-ja/strings.xml @@ -555,8 +555,8 @@ 公開鍵の鍵輪 %s にマージ中 秘密鍵の鍵輪 %s にマージ中 - 署名のエンコードでの致命的なエラー - 指紋が異なる鍵輪をマージしようとしています! + 署名のエンコードでの致命的なエラー + 指紋が異なる鍵輪をマージしようとしています! 新しい副鍵 %s を追加中 鍵輪に新しい検証を %s 発見 新しい証明がない diff --git a/OpenKeychain/src/main/res/values-uk/strings.xml b/OpenKeychain/src/main/res/values-uk/strings.xml index 77458e93f..f1533f4f2 100644 --- a/OpenKeychain/src/main/res/values-uk/strings.xml +++ b/OpenKeychain/src/main/res/values-uk/strings.xml @@ -552,8 +552,8 @@ Злиття у публічну в\'язку %s Злиття у секретну в\'язку %s - Фатальна помилка шифрування підпису - Спробували злити в\'язки із різними відбитками! + Фатальна помилка шифрування підпису + Спробували злити в\'язки із різними відбитками! Додається новий підключ %s Знайдено %s нових сертифікатів у в\'язці Немає нових сертифікатів diff --git a/OpenKeychain/src/main/res/values/strings.xml b/OpenKeychain/src/main/res/values/strings.xml index d8c73bd9e..6e487adfa 100644 --- a/OpenKeychain/src/main/res/values/strings.xml +++ b/OpenKeychain/src/main/res/values/strings.xml @@ -500,6 +500,8 @@ error! key unavailable + + Applying insert batch operation. Tried to import secret keyring as public. This is a bug, please file a report! @@ -619,14 +621,14 @@ Removing invalid user id %s + New public subkey found, but secret subkey dummy generation is not supported! + Tried to merge keyrings with differing fingerprints! + Fatal error encoding signature! Merging into public keyring %s Merging into secret keyring %s - Fatal error encoding signature - Tried to merge keyrings with differing fingerprints! Adding new subkey %s Found %s new certificates in keyring No new certificates - No secret keyring to add subkey to Generating new master key -- cgit v1.2.3 From d795f8d4e240877861ab993608fb7f5aed0a2042 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Wed, 27 Aug 2014 19:28:33 +0200 Subject: Strip out duplicate user ids --- .../sufficientlysecure/keychain/pgp/UncachedKeyRing.java | 16 +++++++++++++--- .../keychain/service/OperationResultParcel.java | 1 + OpenKeychain/src/main/res/values-es/strings.xml | 2 +- OpenKeychain/src/main/res/values-fr/strings.xml | 2 +- OpenKeychain/src/main/res/values-it/strings.xml | 2 +- OpenKeychain/src/main/res/values-ja/strings.xml | 2 +- OpenKeychain/src/main/res/values/strings.xml | 3 ++- 7 files changed, 20 insertions(+), 8 deletions(-) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedKeyRing.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedKeyRing.java index 424420e72..9fa737be4 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedKeyRing.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedKeyRing.java @@ -37,7 +37,6 @@ import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException; import org.sufficientlysecure.keychain.service.OperationResultParcel.LogLevel; import org.sufficientlysecure.keychain.service.OperationResultParcel.LogType; import org.sufficientlysecure.keychain.service.OperationResultParcel.OperationLog; -import org.sufficientlysecure.keychain.service.OperationResults; import org.sufficientlysecure.keychain.util.IterableIterator; import org.sufficientlysecure.keychain.util.Log; @@ -46,6 +45,7 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import java.util.ArrayList; import java.util.Arrays; import java.util.Comparator; import java.util.Date; @@ -339,7 +339,17 @@ public class UncachedKeyRing { } } + ArrayList processedUserIds = new ArrayList(); for (String userId : new IterableIterator(masterKey.getUserIDs())) { + // check for duplicate user ids + if (processedUserIds.contains(userId)) { + log.add(LogLevel.WARN, LogType.MSG_KC_UID_DUP, + indent, userId); + // strip out the first found user id with this name + modified = PGPPublicKey.removeCertification(modified, userId); + } + processedUserIds.add(userId); + PGPSignature selfCert = null; revocation = null; @@ -416,13 +426,13 @@ public class UncachedKeyRing { if (selfCert == null) { selfCert = zert; } else if (selfCert.getCreationTime().before(cert.getCreationTime())) { - log.add(LogLevel.DEBUG, LogType.MSG_KC_UID_DUP, + log.add(LogLevel.DEBUG, LogType.MSG_KC_UID_CERT_DUP, indent, userId); modified = PGPPublicKey.removeCertification(modified, userId, selfCert); redundantCerts += 1; selfCert = zert; } else { - log.add(LogLevel.DEBUG, LogType.MSG_KC_UID_DUP, + log.add(LogLevel.DEBUG, LogType.MSG_KC_UID_CERT_DUP, indent, userId); modified = PGPPublicKey.removeCertification(modified, userId, zert); redundantCerts += 1; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/OperationResultParcel.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/OperationResultParcel.java index ddc456e34..a08ee3091 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/OperationResultParcel.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/OperationResultParcel.java @@ -323,6 +323,7 @@ public class OperationResultParcel implements Parcelable { MSG_KC_UID_BAD_TIME (R.string.msg_kc_uid_bad_time), MSG_KC_UID_BAD_TYPE (R.string.msg_kc_uid_bad_type), MSG_KC_UID_BAD (R.string.msg_kc_uid_bad), + MSG_KC_UID_CERT_DUP (R.string.msg_kc_uid_cert_dup), MSG_KC_UID_DUP (R.string.msg_kc_uid_dup), MSG_KC_UID_FOREIGN (R.string.msg_kc_uid_foreign), MSG_KC_UID_NO_CERT (R.string.msg_kc_uid_no_cert), diff --git a/OpenKeychain/src/main/res/values-es/strings.xml b/OpenKeychain/src/main/res/values-es/strings.xml index 9266950d2..e2b2d2e73 100644 --- a/OpenKeychain/src/main/res/values-es/strings.xml +++ b/OpenKeychain/src/main/res/values-es/strings.xml @@ -563,7 +563,7 @@ Eliminando identidad de usuario con marca de tiempo futura Eliminando certificado de identidad de usuario, de tipo desconocido (%s) Eliminando auto-certificado defectuoso para la identidad de usuario \"%s\" - Eliminando auto-certificado desactualizado para el identificador de usuario \"%s\" + Eliminando auto-certificado desactualizado para el identificador de usuario \"%s\" Eliminando certificado ajeno de identidad de usuario por %s Eliminando certificado redundate de revocación para la identidad de usuario \"%s\" Eliminando certificado desactualizado de revocación para la identidad de usuario \"%s\" diff --git a/OpenKeychain/src/main/res/values-fr/strings.xml b/OpenKeychain/src/main/res/values-fr/strings.xml index 4ac578ba8..de1506665 100644 --- a/OpenKeychain/src/main/res/values-fr/strings.xml +++ b/OpenKeychain/src/main/res/values-fr/strings.xml @@ -563,7 +563,7 @@ Suppression de l\'ID d\'utilisateur ayant une estampille temporelle dans le futur Suppression du certificat d\'ID d\'utilisateur de type inconnu (%s) Suppression du mauvais auto-certificat pour l\'ID d\'utilisateur « %s » - Suppression de l\'auto-certificat périmé pour l\'ID d\'utilisateur « %s » + Suppression de l\'auto-certificat périmé pour l\'ID d\'utilisateur « %s » Suppression du certificat étranger d\'ID d\'utilisateur par %s Suppression du certificat de révocation redondant pour l\'ID d\'utilisateur « %s » Suppression du certificat de révocation périmé pour l\'ID d\'utilisateur « %s » diff --git a/OpenKeychain/src/main/res/values-it/strings.xml b/OpenKeychain/src/main/res/values-it/strings.xml index 9a21a642b..b5cbfd2f5 100644 --- a/OpenKeychain/src/main/res/values-it/strings.xml +++ b/OpenKeychain/src/main/res/values-it/strings.xml @@ -563,7 +563,7 @@ Rimozione ID utente con marca temporale futura Rimozione certificato ID utente di tipo sconosciuto (%s) Rimozione autocertificazione corrotta per ID utente \"%s\" - Rimozione autocertificazione scaduta per ID utente \"%s\" + Rimozione autocertificazione scaduta per ID utente \"%s\" Rimozione certificato ID utente estraneo di %s Rimozione certificato di revoca ridondante per ID utente \"%s\" Rimozione certificato di revoca scaduto per ID utente \"%s\" diff --git a/OpenKeychain/src/main/res/values-ja/strings.xml b/OpenKeychain/src/main/res/values-ja/strings.xml index 724abeab4..6dfe65312 100644 --- a/OpenKeychain/src/main/res/values-ja/strings.xml +++ b/OpenKeychain/src/main/res/values-ja/strings.xml @@ -546,7 +546,7 @@ 未来にタイムスタンプがあるユーザIDを破棄中 不明な型 (%s) でのユーザID検証を破棄中 ユーザID \"%s\" による問題のある自己検証を破棄中 - 期限の切れたユーザID \"%s\" による自己検証を破棄中 + 期限の切れたユーザID \"%s\" による自己検証を破棄中 %s によって検証されている外部ユーザIDを破棄中 ユーザID \"%s\" による重複した破棄証明を破棄中 ユーザID \"%s\" による期限切れ破棄証明を破棄中 diff --git a/OpenKeychain/src/main/res/values/strings.xml b/OpenKeychain/src/main/res/values/strings.xml index d8c73bd9e..418004721 100644 --- a/OpenKeychain/src/main/res/values/strings.xml +++ b/OpenKeychain/src/main/res/values/strings.xml @@ -611,12 +611,13 @@ Removing user id with future timestamp Removing user id certificate of unknown type (%s) Removing bad self certificate for user id "%s" - Removing outdated self certificate for user id "%s" + Removing outdated self certificate for user id "%s" Removing foreign user id certificate by %s Removing redundant revocation certificate for user id "%s" Removing outdated revocation certificate for user id "%s" No valid self-certificate found for user id %s, removing from ring Removing invalid user id %s + Removing duplicate user id "%s". The secret key contained two of them. This may result in missing certifications! Merging into public keyring %s -- cgit v1.2.3 From 6d9a18941b00b1118fb41cd42044f2440581e78e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Wed, 27 Aug 2014 19:29:17 +0200 Subject: v2.8 --- OpenKeychain/src/main/AndroidManifest.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/OpenKeychain/src/main/AndroidManifest.xml b/OpenKeychain/src/main/AndroidManifest.xml index a27bf4a54..e14fb44ba 100644 --- a/OpenKeychain/src/main/AndroidManifest.xml +++ b/OpenKeychain/src/main/AndroidManifest.xml @@ -3,8 +3,8 @@ xmlns:tools="http://schemas.android.com/tools" package="org.sufficientlysecure.keychain" android:installLocation="auto" - android:versionCode="27004" - android:versionName="2.8 beta4"> + android:versionCode="28000" + android:versionName="2.8">