aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/PgpEncryptDecryptTest.java5
-rw-r--r--OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperationTest.java51
-rw-r--r--OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/UncachedKeyringCanonicalizeTest.java3
-rw-r--r--OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/UncachedKeyringMergeTest.java5
-rw-r--r--OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/UncachedKeyringTest.java3
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/OperationResult.java5
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CanonicalizedSecretKey.java6
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CanonicalizedSecretKeyRing.java14
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java51
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedKeyRing.java57
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/WrappedSignature.java18
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java5
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/SaveKeyringParcel.java3
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/PassphraseDialogActivity.java3
-rw-r--r--OpenKeychain/src/main/res/values-de/strings.xml2
-rw-r--r--OpenKeychain/src/main/res/values-es/strings.xml2
-rw-r--r--OpenKeychain/src/main/res/values-fr/strings.xml2
-rw-r--r--OpenKeychain/src/main/res/values-it/strings.xml2
-rw-r--r--OpenKeychain/src/main/res/values-ja/strings.xml2
-rw-r--r--OpenKeychain/src/main/res/values-sl/strings.xml2
-rw-r--r--OpenKeychain/src/main/res/values-sr/strings.xml2
-rw-r--r--OpenKeychain/src/main/res/values-sv/strings.xml2
-rw-r--r--OpenKeychain/src/main/res/values/strings.xml5
-rw-r--r--build.gradle2
24 files changed, 209 insertions, 43 deletions
diff --git a/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/PgpEncryptDecryptTest.java b/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/PgpEncryptDecryptTest.java
index ebe31c9f0..8c1a358b0 100644
--- a/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/PgpEncryptDecryptTest.java
+++ b/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/PgpEncryptDecryptTest.java
@@ -34,6 +34,7 @@ import org.sufficientlysecure.keychain.service.SaveKeyringParcel.Algorithm;
import org.sufficientlysecure.keychain.operations.results.DecryptVerifyResult;
import org.sufficientlysecure.keychain.operations.results.EditKeyResult;
import org.sufficientlysecure.keychain.operations.results.SignEncryptResult;
+import org.sufficientlysecure.keychain.service.SaveKeyringParcel.ChangeUnlockParcel;
import org.sufficientlysecure.keychain.util.InputData;
import org.sufficientlysecure.keychain.util.ProgressScaler;
import org.sufficientlysecure.keychain.util.TestingUtils;
@@ -68,7 +69,7 @@ public class PgpEncryptDecryptTest {
parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd(
Algorithm.ELGAMAL, 1024, null, KeyFlags.ENCRYPT_COMMS, 0L));
parcel.mAddUserIds.add("bloom");
- parcel.mNewUnlock = mKeyPhrase1;
+ parcel.mNewUnlock = new ChangeUnlockParcel(mKeyPhrase1);
EditKeyResult result = op.createSecretKeyRing(parcel);
Assert.assertTrue("initial test key creation must succeed", result.success());
@@ -86,7 +87,7 @@ public class PgpEncryptDecryptTest {
parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd(
Algorithm.ELGAMAL, 1024, null, KeyFlags.ENCRYPT_COMMS, 0L));
parcel.mAddUserIds.add("belle");
- parcel.mNewUnlock = mKeyPhrase2;
+ parcel.mNewUnlock = new ChangeUnlockParcel(mKeyPhrase2);
EditKeyResult result = op.createSecretKeyRing(parcel);
Assert.assertTrue("initial test key creation must succeed", result.success());
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 79778c6d0..6b53a93ce 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
@@ -41,8 +41,10 @@ import org.spongycastle.openpgp.PGPSignature;
import org.sufficientlysecure.keychain.operations.results.OperationResult.LogType;
import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog;
import org.sufficientlysecure.keychain.operations.results.EditKeyResult;
+import org.sufficientlysecure.keychain.pgp.CanonicalizedSecretKey.SecretKeyType;
import org.sufficientlysecure.keychain.service.SaveKeyringParcel;
import org.sufficientlysecure.keychain.service.SaveKeyringParcel.Algorithm;
+import org.sufficientlysecure.keychain.service.SaveKeyringParcel.ChangeUnlockParcel;
import org.sufficientlysecure.keychain.service.SaveKeyringParcel.SubkeyAdd;
import org.sufficientlysecure.keychain.service.SaveKeyringParcel.SubkeyChange;
import org.sufficientlysecure.keychain.support.KeyringBuilder;
@@ -91,7 +93,7 @@ public class PgpKeyOperationTest {
parcel.mAddUserIds.add("twi");
parcel.mAddUserIds.add("pink");
- parcel.mNewUnlock = passphrase;
+ parcel.mNewUnlock = new ChangeUnlockParcel(passphrase);
PgpKeyOperation op = new PgpKeyOperation(null);
EditKeyResult result = op.createSecretKeyRing(parcel);
@@ -99,6 +101,7 @@ public class PgpKeyOperationTest {
Assert.assertNotNull("initial test key creation must succeed", result.getRing());
staticRing = result.getRing();
+ staticRing = staticRing.canonicalize(new OperationLog(), 0).getUncachedKeyRing();
// we sleep here for a second, to make sure all new certificates have different timestamps
Thread.sleep(1000);
@@ -127,7 +130,7 @@ public class PgpKeyOperationTest {
parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd(
Algorithm.RSA, new Random().nextInt(256)+255, null, KeyFlags.CERTIFY_OTHER, 0L));
parcel.mAddUserIds.add("shy");
- parcel.mNewUnlock = passphrase;
+ parcel.mNewUnlock = new ChangeUnlockParcel(passphrase);
assertFailure("creating ring with < 512 bytes keysize should fail", parcel,
LogType.MSG_CR_ERROR_KEYSIZE_512);
@@ -138,7 +141,7 @@ public class PgpKeyOperationTest {
parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd(
Algorithm.ELGAMAL, 1024, null, KeyFlags.CERTIFY_OTHER, 0L));
parcel.mAddUserIds.add("shy");
- parcel.mNewUnlock = passphrase;
+ parcel.mNewUnlock = new ChangeUnlockParcel(passphrase);
assertFailure("creating ring with ElGamal master key should fail", parcel,
LogType.MSG_CR_ERROR_FLAGS_ELGAMAL);
@@ -149,7 +152,7 @@ public class PgpKeyOperationTest {
parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd(
Algorithm.RSA, 1024, null, KeyFlags.CERTIFY_OTHER, null));
parcel.mAddUserIds.add("lotus");
- parcel.mNewUnlock = passphrase;
+ parcel.mNewUnlock = new ChangeUnlockParcel(passphrase);
assertFailure("creating master key with null expiry should fail", parcel,
LogType.MSG_CR_ERROR_NULL_EXPIRY);
@@ -160,7 +163,7 @@ public class PgpKeyOperationTest {
parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd(
Algorithm.RSA, 1024, null, KeyFlags.SIGN_DATA, 0L));
parcel.mAddUserIds.add("shy");
- parcel.mNewUnlock = passphrase;
+ parcel.mNewUnlock = new ChangeUnlockParcel(passphrase);
assertFailure("creating ring with non-certifying master key should fail", parcel,
LogType.MSG_CR_ERROR_NO_CERTIFY);
@@ -170,7 +173,7 @@ public class PgpKeyOperationTest {
parcel.reset();
parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd(
Algorithm.RSA, 1024, null, KeyFlags.CERTIFY_OTHER, 0L));
- parcel.mNewUnlock = passphrase;
+ parcel.mNewUnlock = new ChangeUnlockParcel(passphrase);
assertFailure("creating ring without user ids should fail", parcel,
LogType.MSG_CR_ERROR_NO_USER_ID);
@@ -179,7 +182,7 @@ public class PgpKeyOperationTest {
{
parcel.reset();
parcel.mAddUserIds.add("shy");
- parcel.mNewUnlock = passphrase;
+ parcel.mNewUnlock = new ChangeUnlockParcel(passphrase);
assertFailure("creating ring with no master key should fail", parcel,
LogType.MSG_CR_ERROR_NO_MASTER);
@@ -910,8 +913,10 @@ public class PgpKeyOperationTest {
public void testPassphraseChange() throws Exception {
// change passphrase to empty
- parcel.mNewUnlock = "";
- UncachedKeyRing modified = applyModificationWithChecks(parcel, ring, onlyA, onlyB);
+ parcel.mNewUnlock = new ChangeUnlockParcel("");
+ // note that canonicalization here necessarily strips the empty notation packet
+ UncachedKeyRing modified = applyModificationWithChecks(parcel, ring, onlyA, onlyB,
+ passphrase, true, false);
Assert.assertEquals("exactly three packets should have been modified (the secret keys)",
3, onlyB.size());
@@ -923,8 +928,8 @@ public class PgpKeyOperationTest {
// modify keyring, change to non-empty passphrase
String otherPassphrase = TestingUtils.genPassphrase(true);
- parcel.mNewUnlock = otherPassphrase;
- modified = applyModificationWithChecks(parcel, modified, onlyA, onlyB, "");
+ parcel.mNewUnlock = new ChangeUnlockParcel(otherPassphrase);
+ modified = applyModificationWithChecks(parcel, modified, onlyA, onlyB, "", true, false);
Assert.assertEquals("exactly three packets should have been modified (the secret keys)",
3, onlyB.size());
@@ -948,7 +953,7 @@ public class PgpKeyOperationTest {
PacketTags.SECRET_SUBKEY, sKeyNoPassphrase.tag);
String otherPassphrase2 = TestingUtils.genPassphrase(true);
- parcel.mNewUnlock = otherPassphrase2;
+ parcel.mNewUnlock = new ChangeUnlockParcel(otherPassphrase2);
{
// if we replace a secret key with one without passphrase
modified = KeyringTestingHelper.removePacket(modified, sKeyNoPassphrase.position);
@@ -981,6 +986,28 @@ public class PgpKeyOperationTest {
}
+ @Test
+ public void testUnlockPin() throws Exception {
+
+ // change passphrase to a pin type
+ parcel.mNewUnlock = new ChangeUnlockParcel(null, "52351");
+ UncachedKeyRing modified = applyModificationWithChecks(parcel, ring, onlyA, onlyB);
+
+ Assert.assertEquals("exactly four packets should have been modified (the secret keys + notation packet)",
+ 4, onlyB.size());
+
+ RawPacket dkSig = onlyB.get(1);
+ Assert.assertEquals("second modified packet should be notation data",
+ PacketTags.SIGNATURE, dkSig.tag);
+
+ // check that notation data contains pin
+ CanonicalizedSecretKeyRing secretRing = new CanonicalizedSecretKeyRing(modified.getEncoded(), false, 0);
+ Assert.assertEquals("secret key type should be 'pin' after this",
+ SecretKeyType.PIN,
+ secretRing.getSecretKey().getSecretKeyType());
+
+ }
+
private static UncachedKeyRing applyModificationWithChecks(SaveKeyringParcel parcel,
UncachedKeyRing ring,
ArrayList<RawPacket> onlyA,
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 cbdbd0e72..7d8a10ee0 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
@@ -58,6 +58,7 @@ import org.sufficientlysecure.keychain.service.SaveKeyringParcel;
import org.sufficientlysecure.keychain.service.SaveKeyringParcel.Algorithm;
import org.sufficientlysecure.keychain.operations.results.OperationResult.LogType;
import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog;
+import org.sufficientlysecure.keychain.service.SaveKeyringParcel.ChangeUnlockParcel;
import org.sufficientlysecure.keychain.support.KeyringTestingHelper;
import org.sufficientlysecure.keychain.support.KeyringTestingHelper.RawPacket;
@@ -104,7 +105,7 @@ public class UncachedKeyringCanonicalizeTest {
parcel.mAddUserIds.add("twi");
parcel.mAddUserIds.add("pink");
// passphrase is tested in PgpKeyOperationTest, just use empty here
- parcel.mNewUnlock = "";
+ parcel.mNewUnlock = new ChangeUnlockParcel("");
PgpKeyOperation op = new PgpKeyOperation(null);
EditKeyResult result = op.createSecretKeyRing(parcel);
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 006c77fbc..799640d6c 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
@@ -36,6 +36,7 @@ import org.sufficientlysecure.keychain.operations.results.OperationResult;
import org.sufficientlysecure.keychain.operations.results.EditKeyResult;
import org.sufficientlysecure.keychain.service.SaveKeyringParcel;
import org.sufficientlysecure.keychain.service.SaveKeyringParcel.Algorithm;
+import org.sufficientlysecure.keychain.service.SaveKeyringParcel.ChangeUnlockParcel;
import org.sufficientlysecure.keychain.support.KeyringTestingHelper;
import org.sufficientlysecure.keychain.support.KeyringTestingHelper.RawPacket;
import org.sufficientlysecure.keychain.util.ProgressScaler;
@@ -96,7 +97,7 @@ public class UncachedKeyringMergeTest {
parcel.mAddUserIds.add("twi");
parcel.mAddUserIds.add("pink");
// passphrase is tested in PgpKeyOperationTest, just use empty here
- parcel.mNewUnlock = "";
+ parcel.mNewUnlock = new ChangeUnlockParcel("");
PgpKeyOperation op = new PgpKeyOperation(null);
OperationResult.OperationLog log = new OperationResult.OperationLog();
@@ -112,7 +113,7 @@ public class UncachedKeyringMergeTest {
parcel.mAddUserIds.add("shy");
// passphrase is tested in PgpKeyOperationTest, just use empty here
- parcel.mNewUnlock = "";
+ parcel.mNewUnlock = new ChangeUnlockParcel("");
PgpKeyOperation op = new PgpKeyOperation(null);
OperationResult.OperationLog log = new OperationResult.OperationLog();
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 d8d825783..34c637abf 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
@@ -30,6 +30,7 @@ import org.sufficientlysecure.keychain.operations.results.EditKeyResult;
import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
import org.sufficientlysecure.keychain.service.SaveKeyringParcel;
import org.sufficientlysecure.keychain.service.SaveKeyringParcel.Algorithm;
+import org.sufficientlysecure.keychain.service.SaveKeyringParcel.ChangeUnlockParcel;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
@@ -57,7 +58,7 @@ public class UncachedKeyringTest {
parcel.mAddUserIds.add("twi");
parcel.mAddUserIds.add("pink");
// passphrase is tested in PgpKeyOperationTest, just use empty here
- parcel.mNewUnlock = "";
+ parcel.mNewUnlock = new ChangeUnlockParcel("");
PgpKeyOperation op = new PgpKeyOperation(null);
EditKeyResult result = op.createSecretKeyRing(parcel);
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/OperationResult.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/OperationResult.java
index dc45fabc3..606dd49d5 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/OperationResult.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/OperationResult.java
@@ -359,6 +359,7 @@ public abstract class OperationResult implements Parcelable {
MSG_IS_SUBKEY_STRIPPED (LogLevel.DEBUG, R.string.msg_is_subkey_stripped),
MSG_IS_SUBKEY_DIVERT (LogLevel.DEBUG, R.string.msg_is_subkey_divert),
MSG_IS_SUBKEY_EMPTY (LogLevel.DEBUG, R.string.msg_is_subkey_empty),
+ MSG_IS_SUBKEY_PIN (LogLevel.DEBUG, R.string.msg_is_subkey_pin),
MSG_IS_SUCCESS_IDENTICAL (LogLevel.OK, R.string.msg_is_success_identical),
MSG_IS_SUCCESS (LogLevel.OK, R.string.msg_is_success),
@@ -370,13 +371,15 @@ public abstract class OperationResult implements Parcelable {
MSG_KC_ERROR_MASTER_ALGO (LogLevel.ERROR, R.string.msg_kc_error_master_algo),
MSG_KC_ERROR_DUP_KEY (LogLevel.ERROR, R.string.msg_kc_error_dup_key),
MSG_KC_MASTER (LogLevel.DEBUG, R.string.msg_kc_master),
+ MSG_KC_BAD_TYPE(LogLevel.WARN, R.string.msg_kc_bad_type),
MSG_KC_REVOKE_BAD_ERR (LogLevel.WARN, R.string.msg_kc_revoke_bad_err),
MSG_KC_REVOKE_BAD_LOCAL (LogLevel.WARN, R.string.msg_kc_revoke_bad_local),
MSG_KC_REVOKE_BAD_TIME (LogLevel.WARN, R.string.msg_kc_revoke_bad_time),
- MSG_KC_REVOKE_BAD_TYPE (LogLevel.WARN, R.string.msg_kc_revoke_bad_type),
MSG_KC_REVOKE_BAD_TYPE_UID (LogLevel.WARN, R.string.msg_kc_revoke_bad_type_uid),
MSG_KC_REVOKE_BAD (LogLevel.WARN, R.string.msg_kc_revoke_bad),
MSG_KC_REVOKE_DUP (LogLevel.DEBUG, R.string.msg_kc_revoke_dup),
+ MSG_KC_NOTATION_DUP (LogLevel.DEBUG, R.string.msg_kc_notation_dup),
+ MSG_KC_NOTATION_EMPTY (LogLevel.DEBUG, R.string.msg_kc_notation_empty),
MSG_KC_SUB (LogLevel.DEBUG, R.string.msg_kc_sub),
MSG_KC_SUB_BAD(LogLevel.WARN, R.string.msg_kc_sub_bad),
MSG_KC_SUB_BAD_ERR(LogLevel.WARN, R.string.msg_kc_sub_bad_err),
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 a965d4819..42e59b3bc 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CanonicalizedSecretKey.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CanonicalizedSecretKey.java
@@ -49,6 +49,7 @@ import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.SignatureException;
import java.util.Date;
+import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
@@ -140,6 +141,11 @@ public class CanonicalizedSecretKey extends CanonicalizedPublicKey {
// It means the passphrase is empty
return SecretKeyType.PASSPHRASE_EMPTY;
} catch (PGPException e) {
+ HashMap<String,String> notation = getRing().getLocalNotationData();
+ if (notation.containsKey("unlock.pin@sufficientlysecure.org")
+ && "1".equals(notation.get("unlock.pin@sufficientlysecure.org"))) {
+ return SecretKeyType.PIN;
+ }
// Otherwise, it's just a regular ol' passphrase
return SecretKeyType.PASSPHRASE;
}
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 e20155cc6..eb589c3f9 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CanonicalizedSecretKeyRing.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CanonicalizedSecretKeyRing.java
@@ -26,6 +26,7 @@ import org.spongycastle.openpgp.PGPPrivateKey;
import org.spongycastle.openpgp.PGPPublicKey;
import org.spongycastle.openpgp.PGPSecretKey;
import org.spongycastle.openpgp.PGPSecretKeyRing;
+import org.spongycastle.openpgp.PGPSignature;
import org.spongycastle.openpgp.operator.PBESecretKeyDecryptor;
import org.spongycastle.openpgp.operator.jcajce.JcePBESecretKeyDecryptorBuilder;
import org.sufficientlysecure.keychain.Constants;
@@ -36,6 +37,7 @@ import org.sufficientlysecure.keychain.util.IterableIterator;
import org.sufficientlysecure.keychain.util.Log;
import java.io.IOException;
+import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
@@ -130,4 +132,16 @@ public class CanonicalizedSecretKeyRing extends CanonicalizedKeyRing {
});
}
+ public HashMap<String,String> getLocalNotationData() {
+ HashMap<String,String> result = new HashMap<String,String>();
+ Iterator<PGPSignature> it = getRing().getPublicKey().getKeySignatures();
+ while (it.hasNext()) {
+ WrappedSignature sig = new WrappedSignature(it.next());
+ if (sig.isLocal()) {
+ result.putAll(sig.getNotation());
+ }
+ }
+ return result;
+ }
+
}
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 c125165a8..c8ce349f8 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java
@@ -34,6 +34,7 @@ import org.spongycastle.openpgp.PGPSecretKeyRing;
import org.spongycastle.openpgp.PGPSignature;
import org.spongycastle.openpgp.PGPSignatureGenerator;
import org.spongycastle.openpgp.PGPSignatureSubpacketGenerator;
+import org.spongycastle.openpgp.PGPSignatureSubpacketVector;
import org.spongycastle.openpgp.operator.PBESecretKeyDecryptor;
import org.spongycastle.openpgp.operator.PBESecretKeyEncryptor;
import org.spongycastle.openpgp.operator.PGPContentSignerBuilder;
@@ -877,7 +878,8 @@ public class PgpKeyOperation {
log.add(LogType.MSG_MF_PASSPHRASE, indent);
indent += 1;
- sKR = applyNewUnlock(sKR, masterPublicKey, passphrase, saveParcel.mNewUnlock, log, indent);
+ sKR = applyNewUnlock(sKR, masterPublicKey, masterPrivateKey,
+ passphrase, saveParcel.mNewUnlock, log, indent);
if (sKR == null) {
// The error has been logged above, just return a bad state
return new EditKeyResult(EditKeyResult.RESULT_ERROR, log, null);
@@ -909,19 +911,62 @@ public class PgpKeyOperation {
private static PGPSecretKeyRing applyNewUnlock(
PGPSecretKeyRing sKR,
PGPPublicKey masterPublicKey,
+ PGPPrivateKey masterPrivateKey,
String passphrase,
ChangeUnlockParcel newUnlock,
OperationLog log, int indent) throws PGPException {
if (newUnlock.mNewPassphrase != null) {
- return applyNewPassphrase(sKR, masterPublicKey, passphrase, newUnlock.mNewPassphrase, log, indent);
+ sKR = applyNewPassphrase(sKR, masterPublicKey, passphrase, newUnlock.mNewPassphrase, log, indent);
+
+ // add packet with EMPTY notation data (updates old one, but will be stripped later)
+ PGPContentSignerBuilder signerBuilder = new JcaPGPContentSignerBuilder(
+ masterPrivateKey.getPublicKeyPacket().getAlgorithm(), HashAlgorithmTags.SHA512)
+ .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME);
+ PGPSignatureGenerator sGen = new PGPSignatureGenerator(signerBuilder);
+ { // set subpackets
+ PGPSignatureSubpacketGenerator hashedPacketsGen = new PGPSignatureSubpacketGenerator();
+ hashedPacketsGen.setExportable(false, false);
+ sGen.setHashedSubpackets(hashedPacketsGen.generate());
+ }
+ sGen.init(PGPSignature.DIRECT_KEY, masterPrivateKey);
+ PGPSignature emptySig = sGen.generateCertification(masterPublicKey);
+
+ masterPublicKey = PGPPublicKey.addCertification(masterPublicKey, emptySig);
+ sKR = PGPSecretKeyRing.insertSecretKey(sKR,
+ PGPSecretKey.replacePublicKey(sKR.getSecretKey(), masterPublicKey));
+
+ return sKR;
+ }
+
+ if (newUnlock.mNewPin != null) {
+ sKR = applyNewPassphrase(sKR, masterPublicKey, passphrase, newUnlock.mNewPin, log, indent);
+
+ // add packet with EMPTY notation data (updates old one, but will be stripped later)
+ PGPContentSignerBuilder signerBuilder = new JcaPGPContentSignerBuilder(
+ masterPrivateKey.getPublicKeyPacket().getAlgorithm(), HashAlgorithmTags.SHA512)
+ .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME);
+ PGPSignatureGenerator sGen = new PGPSignatureGenerator(signerBuilder);
+ { // set subpackets
+ PGPSignatureSubpacketGenerator hashedPacketsGen = new PGPSignatureSubpacketGenerator();
+ hashedPacketsGen.setExportable(false, false);
+ hashedPacketsGen.setNotationData(false, true, "unlock.pin@sufficientlysecure.org", "1");
+ sGen.setHashedSubpackets(hashedPacketsGen.generate());
+ }
+ sGen.init(PGPSignature.DIRECT_KEY, masterPrivateKey);
+ PGPSignature emptySig = sGen.generateCertification(masterPublicKey);
+
+ masterPublicKey = PGPPublicKey.addCertification(masterPublicKey, emptySig);
+ sKR = PGPSecretKeyRing.insertSecretKey(sKR,
+ PGPSecretKey.replacePublicKey(sKR.getSecretKey(), masterPublicKey));
+
+ return sKR;
}
throw new UnsupportedOperationException("PIN passphrases not yet implemented!");
}
-
private static PGPSecretKeyRing applyNewPassphrase(
PGPSecretKeyRing sKR,
PGPPublicKey masterPublicKey,
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 b343c779a..5e5a28e83 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedKeyRing.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedKeyRing.java
@@ -41,7 +41,6 @@ import org.sufficientlysecure.keychain.util.IterableIterator;
import org.sufficientlysecure.keychain.util.Log;
import org.sufficientlysecure.keychain.util.Utf8Util;
-import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
@@ -302,6 +301,7 @@ public class UncachedKeyRing {
PGPPublicKey modified = masterKey;
PGPSignature revocation = null;
+ PGPSignature notation = null;
for (PGPSignature zert : new IterableIterator<PGPSignature>(masterKey.getKeySignatures())) {
int type = zert.getSignatureType();
@@ -318,9 +318,9 @@ public class UncachedKeyRing {
}
WrappedSignature cert = new WrappedSignature(zert);
- if (type != PGPSignature.KEY_REVOCATION) {
+ if (type != PGPSignature.KEY_REVOCATION && type != PGPSignature.DIRECT_KEY) {
// Unknown type, just remove
- log.add(LogType.MSG_KC_REVOKE_BAD_TYPE, indent, "0x" + Integer.toString(type, 16));
+ log.add(LogType.MSG_KC_BAD_TYPE, indent, "0x" + Integer.toString(type, 16));
modified = PGPPublicKey.removeCertification(modified, zert);
badCerts += 1;
continue;
@@ -334,14 +334,6 @@ public class UncachedKeyRing {
continue;
}
- if (cert.isLocal()) {
- // Remove revocation certs with "local" flag
- log.add(LogType.MSG_KC_REVOKE_BAD_LOCAL, indent);
- modified = PGPPublicKey.removeCertification(modified, zert);
- badCerts += 1;
- continue;
- }
-
try {
cert.init(masterKey);
if (!cert.verifySignature(masterKey)) {
@@ -357,6 +349,39 @@ public class UncachedKeyRing {
continue;
}
+ // special case: direct key signatures!
+ if (cert.getSignatureType() == PGPSignature.DIRECT_KEY) {
+ // must be local, otherwise strip!
+ if (!cert.isLocal()) {
+ log.add(LogType.MSG_KC_BAD_TYPE, indent);
+ modified = PGPPublicKey.removeCertification(modified, zert);
+ badCerts += 1;
+ continue;
+ }
+
+ // first notation? fine then.
+ if (notation == null) {
+ notation = zert;
+ // more notations? at least one is superfluous, then.
+ } else if (notation.getCreationTime().before(zert.getCreationTime())) {
+ log.add(LogType.MSG_KC_NOTATION_DUP, indent);
+ modified = PGPPublicKey.removeCertification(modified, notation);
+ redundantCerts += 1;
+ notation = zert;
+ } else {
+ log.add(LogType.MSG_KC_NOTATION_DUP, indent);
+ modified = PGPPublicKey.removeCertification(modified, zert);
+ redundantCerts += 1;
+ }
+ continue;
+ } else if (cert.isLocal()) {
+ // Remove revocation certs with "local" flag
+ log.add(LogType.MSG_KC_REVOKE_BAD_LOCAL, indent);
+ modified = PGPPublicKey.removeCertification(modified, zert);
+ badCerts += 1;
+ continue;
+ }
+
// first revocation? fine then.
if (revocation == null) {
revocation = zert;
@@ -373,6 +398,16 @@ public class UncachedKeyRing {
}
}
+ // If we have a notation packet, check if there is even any data in it?
+ if (notation != null) {
+ // If there isn't, might as well strip it
+ if (new WrappedSignature(notation).getNotation().isEmpty()) {
+ log.add(LogType.MSG_KC_NOTATION_EMPTY, indent);
+ modified = PGPPublicKey.removeCertification(modified, notation);
+ redundantCerts += 1;
+ }
+ }
+
ArrayList<String> processedUserIds = new ArrayList<String>();
for (byte[] rawUserId : new IterableIterator<byte[]>(masterKey.getRawUserIDs())) {
String userId = Utf8Util.fromUTF8ByteArrayReplaceBadEncoding(rawUserId);
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 93afb987a..c395ca52d 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/WrappedSignature.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/WrappedSignature.java
@@ -21,6 +21,7 @@ package org.sufficientlysecure.keychain.pgp;
import org.spongycastle.bcpg.SignatureSubpacket;
import org.spongycastle.bcpg.SignatureSubpacketTags;
import org.spongycastle.bcpg.sig.Exportable;
+import org.spongycastle.bcpg.sig.NotationData;
import org.spongycastle.bcpg.sig.Revocable;
import org.spongycastle.bcpg.sig.RevocationReason;
import org.spongycastle.openpgp.PGPException;
@@ -37,6 +38,7 @@ import java.io.IOException;
import java.security.SignatureException;
import java.util.ArrayList;
import java.util.Date;
+import java.util.HashMap;
/** OpenKeychain wrapper around PGPSignature objects.
*
@@ -239,4 +241,20 @@ public class WrappedSignature {
SignatureSubpacket p = mSig.getHashedSubPackets().getSubpacket(SignatureSubpacketTags.EXPORTABLE);
return ! ((Exportable) p).isExportable();
}
+
+ public HashMap<String,String> getNotation() {
+ HashMap<String,String> result = new HashMap<String,String>();
+
+ // If there is any notation data
+ if (mSig.getHashedSubPackets() != null
+ && mSig.getHashedSubPackets().hasSubpacket(SignatureSubpacketTags.NOTATION_DATA)) {
+ // Iterate over notation data
+ for (NotationData data : mSig.getHashedSubPackets().getNotationDataOccurrences()) {
+ result.put(data.getNotationName(), data.getNotationValue());
+ }
+ }
+
+ return result;
+ }
+
}
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 05dc99c5e..6daa26cd3 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java
@@ -682,6 +682,11 @@ public class ProviderHelper {
KeyFormattingUtils.convertKeyIdToHex(id)
);
break;
+ case PIN:
+ log(LogType.MSG_IS_SUBKEY_PIN,
+ KeyFormattingUtils.convertKeyIdToHex(id)
+ );
+ break;
case GNU_DUMMY:
log(LogType.MSG_IS_SUBKEY_STRIPPED,
KeyFormattingUtils.convertKeyIdToHex(id)
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 f5d4e5bd4..810190fee 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/SaveKeyringParcel.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/SaveKeyringParcel.java
@@ -254,6 +254,9 @@ public class SaveKeyringParcel implements Parcelable {
// A new pin to use. Must only contain [0-9]+
public final String mNewPin;
+ public ChangeUnlockParcel(String newPassphrase) {
+ this(newPassphrase, null);
+ }
public ChangeUnlockParcel(String newPassphrase, String newPin) {
if (newPassphrase == null && newPin == null) {
throw new RuntimeException("Cannot set both passphrase and pin. THIS IS A BUG!");
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/PassphraseDialogActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/PassphraseDialogActivity.java
index 4c65aa314..cd564551a 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/PassphraseDialogActivity.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/PassphraseDialogActivity.java
@@ -208,6 +208,9 @@ public class PassphraseDialogActivity extends FragmentActivity {
case PASSPHRASE:
message = getString(R.string.passphrase_for, userId);
break;
+ case PIN:
+ message = getString(R.string.pin_for, userId);
+ break;
case DIVERT_TO_CARD:
message = getString(R.string.yubikey_pin_for, userId);
break;
diff --git a/OpenKeychain/src/main/res/values-de/strings.xml b/OpenKeychain/src/main/res/values-de/strings.xml
index 12738bc60..fa74b287b 100644
--- a/OpenKeychain/src/main/res/values-de/strings.xml
+++ b/OpenKeychain/src/main/res/values-de/strings.xml
@@ -607,7 +607,7 @@
<string name="msg_kc_revoke_bad_err">Entferne fehlerhaftes Schlüsselbund Widerrufszertifikat</string>
<string name="msg_kc_revoke_bad_local">Entferne Schlüsselbund Widerrufszertifikat mit \"Lokal\" Attribut</string>
<string name="msg_kc_revoke_bad_time">Entferne Schlüsselbund Widerrufszertifikat mit zukünftigem Zeitstempel</string>
- <string name="msg_kc_revoke_bad_type">Entferne Hauptschlüsselbeglaubigung unbekannter Art (%s)</string>
+ <string name="msg_kc_bad_type">Entferne Hauptschlüsselbeglaubigung unbekannter Art (%s)</string>
<string name="msg_kc_revoke_bad">Entferne fehlerhaftes Schlüsselbund Widerrufszertifikat</string>
<string name="msg_kc_revoke_dup">Entferne redundantes Schlüsselbund Widerrufszertifikat</string>
<string name="msg_kc_sub">Verarbeite Unterschlüssel %s</string>
diff --git a/OpenKeychain/src/main/res/values-es/strings.xml b/OpenKeychain/src/main/res/values-es/strings.xml
index f89ca0bf7..afae20592 100644
--- a/OpenKeychain/src/main/res/values-es/strings.xml
+++ b/OpenKeychain/src/main/res/values-es/strings.xml
@@ -652,7 +652,7 @@
<string name="msg_kc_revoke_bad_err">Eliminando certificado defectuoso de revocación de juego de claves</string>
<string name="msg_kc_revoke_bad_local">Eliminando certificado de revocación de juego de claves, con distintivo \"local\"</string>
<string name="msg_kc_revoke_bad_time">Eliminando certificado de revocación de juego de claves, con marca de tiempo futura</string>
- <string name="msg_kc_revoke_bad_type">Eliminando certificado de clave maestra, de tipo desconocido (%s)</string>
+ <string name="msg_kc_bad_type">Eliminando certificado de clave maestra, de tipo desconocido (%s)</string>
<string name="msg_kc_revoke_bad_type_uid">Eliminando certificado de identificación de usuario en posición incorrecta</string>
<string name="msg_kc_revoke_bad">Eliminando certificado defectuoso de revocación de juego de claves</string>
<string name="msg_kc_revoke_dup">Eliminando certificado redundante de revocación de juego de claves </string>
diff --git a/OpenKeychain/src/main/res/values-fr/strings.xml b/OpenKeychain/src/main/res/values-fr/strings.xml
index 69764f514..60b7a3bcf 100644
--- a/OpenKeychain/src/main/res/values-fr/strings.xml
+++ b/OpenKeychain/src/main/res/values-fr/strings.xml
@@ -652,7 +652,7 @@
<string name="msg_kc_revoke_bad_err">Suppression du mauvais certificat de révocation du trousseau</string>
<string name="msg_kc_revoke_bad_local">Suppression du certificat de révocation du trousseau ayant le drapeau « local »</string>
<string name="msg_kc_revoke_bad_time">Suppression du certificat de révocation du trousseau ayant une estampille temporelle dans le futur</string>
- <string name="msg_kc_revoke_bad_type">Suppression du certificat de clef maîtresse de type inconnu (%s)</string>
+ <string name="msg_kc_bad_type">Suppression du certificat de clef maîtresse de type inconnu (%s)</string>
<string name="msg_kc_revoke_bad_type_uid">Suppression du certificat de l\'ID d\'utilisateur en mauvaise position</string>
<string name="msg_kc_revoke_bad">Suppression du mauvais certificat de révocation du trousseau</string>
<string name="msg_kc_revoke_dup"> Suppression du certificat redondant de révocation du trousseau</string>
diff --git a/OpenKeychain/src/main/res/values-it/strings.xml b/OpenKeychain/src/main/res/values-it/strings.xml
index 8d7c9e8f8..6a33e25f1 100644
--- a/OpenKeychain/src/main/res/values-it/strings.xml
+++ b/OpenKeychain/src/main/res/values-it/strings.xml
@@ -602,7 +602,7 @@ Permetti accesso?\n\nATTENZIONE: Se non sai perche\' questo schermata e\' appars
<string name="msg_kc_revoke_bad_err">Rimozione di certificato di revoca del portachiavi corrotto</string>
<string name="msg_kc_revoke_bad_local">Rimozione certificato di revoca del portachiavi con caratteristica \"locale\"</string>
<string name="msg_kc_revoke_bad_time">Rimozione certificato di revoca del portachiavi con marca temporale futura</string>
- <string name="msg_kc_revoke_bad_type">Rimozione certificato della chiave principale di tipo sconosciuto (%s)</string>
+ <string name="msg_kc_bad_type">Rimozione certificato della chiave principale di tipo sconosciuto (%s)</string>
<string name="msg_kc_revoke_bad">Rimozione certificato di revoca del portachiavi corrotto</string>
<string name="msg_kc_revoke_dup">Rimozione certificato di revoca del portachiavi ridondante</string>
<string name="msg_kc_sub">Elaborazione sottochiave %s</string>
diff --git a/OpenKeychain/src/main/res/values-ja/strings.xml b/OpenKeychain/src/main/res/values-ja/strings.xml
index e53f0bfb1..5ed93c931 100644
--- a/OpenKeychain/src/main/res/values-ja/strings.xml
+++ b/OpenKeychain/src/main/res/values-ja/strings.xml
@@ -618,7 +618,7 @@
<string name="msg_kc_revoke_bad_err">問題のある鍵輪の破棄証明を破棄中</string>
<string name="msg_kc_revoke_bad_local">鍵輪のローカルフラグ付き破棄証明を破棄中</string>
<string name="msg_kc_revoke_bad_time">鍵輪の未来にタイムスタンプがある破棄証明を破棄中</string>
- <string name="msg_kc_revoke_bad_type">問題のある主鍵の不明な型 (%s) の証明を破棄中</string>
+ <string name="msg_kc_bad_type">問題のある主鍵の不明な型 (%s) の証明を破棄中</string>
<string name="msg_kc_revoke_bad_type_uid">不正な位置のユーザID検証を破棄中</string>
<string name="msg_kc_revoke_bad">問題のある鍵輪の破棄証明を破棄中</string>
<string name="msg_kc_revoke_dup">重複している鍵輪の破棄証明を破棄中</string>
diff --git a/OpenKeychain/src/main/res/values-sl/strings.xml b/OpenKeychain/src/main/res/values-sl/strings.xml
index 0799e951f..1841ee46b 100644
--- a/OpenKeychain/src/main/res/values-sl/strings.xml
+++ b/OpenKeychain/src/main/res/values-sl/strings.xml
@@ -450,7 +450,7 @@
<string name="msg_kc_revoke_bad_err">Umikam slab certifikat za preklic zbirk ključev</string>
<string name="msg_kc_revoke_bad_local">Umikam certifikat za preklic zbirk ključev z oznako \"lokalno\"</string>
<string name="msg_kc_revoke_bad_time">Umikam certifikat za preklic zbirk ključev s časovno znamko v prihodnosti</string>
- <string name="msg_kc_revoke_bad_type">Umikam certifikat glavnega ključa neznanega tipa (%s)</string>
+ <string name="msg_kc_bad_type">Umikam certifikat glavnega ključa neznanega tipa (%s)</string>
<string name="msg_kc_revoke_bad">Umikam slab certifikat za preklic zbirk ključev</string>
<string name="msg_kc_revoke_dup">Umikam odvečen certifikat za preklic zbirk ključev</string>
<string name="msg_kc_sub">Obdelujem podključ %s</string>
diff --git a/OpenKeychain/src/main/res/values-sr/strings.xml b/OpenKeychain/src/main/res/values-sr/strings.xml
index c38b681c4..5ba833972 100644
--- a/OpenKeychain/src/main/res/values-sr/strings.xml
+++ b/OpenKeychain/src/main/res/values-sr/strings.xml
@@ -672,7 +672,7 @@
<string name="msg_kc_revoke_bad_err">Уклањам лош сертификат опозива привеска</string>
<string name="msg_kc_revoke_bad_local">Уклањам сертификат опозива привеска са заставицом „локални“</string>
<string name="msg_kc_revoke_bad_time">Уклањам сертификат опозива привеска са временском ознаком у будућности</string>
- <string name="msg_kc_revoke_bad_type">Уклањам сертификат главног кључа непознатог типа (%s)</string>
+ <string name="msg_kc_bad_type">Уклањам сертификат главног кључа непознатог типа (%s)</string>
<string name="msg_kc_revoke_bad_type_uid">Уклањам сертификат корисничког ИД-а са погрешног места</string>
<string name="msg_kc_revoke_bad">Уклањам лош сертификат опозива привеска</string>
<string name="msg_kc_revoke_dup">Уклањам сувишни сертификат опозива привеска</string>
diff --git a/OpenKeychain/src/main/res/values-sv/strings.xml b/OpenKeychain/src/main/res/values-sv/strings.xml
index c1a7178e0..fda0ace11 100644
--- a/OpenKeychain/src/main/res/values-sv/strings.xml
+++ b/OpenKeychain/src/main/res/values-sv/strings.xml
@@ -573,7 +573,7 @@
<string name="msg_kc_master">Bearbetar huvudnyckel</string>
<string name="msg_kc_revoke_bad_err">Tar bort dåligt återkallelsecertifikat för nyckelring</string>
<string name="msg_kc_revoke_bad_time">Tar bort återkallelsecertifikat för nyckelring med framtida tidstämpel</string>
- <string name="msg_kc_revoke_bad_type">Tar bort huvudnyckelcertifikat av okänd typ (%s)</string>
+ <string name="msg_kc_bad_type">Tar bort huvudnyckelcertifikat av okänd typ (%s)</string>
<string name="msg_kc_revoke_bad">Tar bort dåligt återkallelsecertifikat för nyckelring</string>
<string name="msg_kc_revoke_dup">Tar bort överflödigt återkallelsecertifikat för nyckelring</string>
<string name="msg_kc_sub">Bearbetar undernyckel %s</string>
diff --git a/OpenKeychain/src/main/res/values/strings.xml b/OpenKeychain/src/main/res/values/strings.xml
index c142e9fee..05ea2a99a 100644
--- a/OpenKeychain/src/main/res/values/strings.xml
+++ b/OpenKeychain/src/main/res/values/strings.xml
@@ -697,6 +697,7 @@
<string name="msg_is_subkey_nonexistent">"Subkey %s unavailable in secret key"</string>
<string name="msg_is_subkey_ok">"Marked secret subkey %s as available"</string>
<string name="msg_is_subkey_empty">"Marked secret subkey %s as available, with empty passphrase"</string>
+ <string name="msg_is_subkey_pin">"Marked secret subkey %s as available, with pin passphrase"</string>
<string name="msg_is_subkey_stripped">"Marked secret subkey %s as stripped"</string>
<string name="msg_is_subkey_divert">"Marked secret subkey %s as 'divert to smartcard/NFC'"</string>
<string name="msg_is_success_identical">"Keyring contains no new data, nothing to do"</string>
@@ -710,13 +711,15 @@
<string name="msg_kc_error_master_algo">"The master key uses an unknown (%s) algorithm!"</string>
<string name="msg_kc_error_dup_key">"Subkey %s occurs twice in keyring. Keyring is malformed, not importing!"</string>
<string name="msg_kc_master">"Processing master key"</string>
+ <string name="msg_kc_bad_type">"Removing master key certificate of unknown type (%s)"</string>
<string name="msg_kc_revoke_bad_err">"Removing bad keyring revocation certificate"</string>
<string name="msg_kc_revoke_bad_local">"Removing keyring revocation certificate with "local" flag"</string>
<string name="msg_kc_revoke_bad_time">"Removing keyring revocation certificate with future timestamp"</string>
- <string name="msg_kc_revoke_bad_type">"Removing master key certificate of unknown type (%s)"</string>
<string name="msg_kc_revoke_bad_type_uid">"Removing user ID certificate in bad position"</string>
<string name="msg_kc_revoke_bad">"Removing bad keyring revocation certificate"</string>
<string name="msg_kc_revoke_dup">"Removing redundant keyring revocation certificate"</string>
+ <string name="msg_kc_notation_dup">"Removing redundant notation certificate"</string>
+ <string name="msg_kc_notation_empty">"Removing empty notation certificate"</string>
<string name="msg_kc_sub">"Processing subkey %s"</string>
<string name="msg_kc_sub_bad">"Removing invalid subkey binding certificate"</string>
<string name="msg_kc_sub_bad_err">"Removing bad subkey binding certificate"</string>
diff --git a/build.gradle b/build.gradle
index f6fff5d3c..8c3b355d4 100644
--- a/build.gradle
+++ b/build.gradle
@@ -21,7 +21,7 @@ task wrapper(type: Wrapper) {
subprojects {
tasks.withType(Test) {
- maxParallelForks = 5
+ maxParallelForks = 1
}
}