aboutsummaryrefslogtreecommitdiffstats
path: root/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperationTest.java
diff options
context:
space:
mode:
Diffstat (limited to 'OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperationTest.java')
-rw-r--r--OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperationTest.java259
1 files changed, 216 insertions, 43 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 abe39b894..dd2feb825 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
@@ -34,15 +34,19 @@ import org.spongycastle.bcpg.S2K;
import org.spongycastle.bcpg.SecretKeyPacket;
import org.spongycastle.bcpg.SecretSubkeyPacket;
import org.spongycastle.bcpg.SignaturePacket;
+import org.spongycastle.bcpg.UserAttributePacket;
+import org.spongycastle.bcpg.UserAttributeSubpacket;
import org.spongycastle.bcpg.UserIDPacket;
import org.spongycastle.bcpg.sig.KeyFlags;
import org.spongycastle.jce.provider.BouncyCastleProvider;
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.operations.results.PgpEditKeyResult;
+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,14 +95,15 @@ public class PgpKeyOperationTest {
parcel.mAddUserIds.add("twi");
parcel.mAddUserIds.add("pink");
- parcel.mNewPassphrase = passphrase;
+ parcel.mNewUnlock = new ChangeUnlockParcel(passphrase);
PgpKeyOperation op = new PgpKeyOperation(null);
- EditKeyResult result = op.createSecretKeyRing(parcel);
+ PgpEditKeyResult result = op.createSecretKeyRing(parcel);
Assert.assertTrue("initial test key creation must succeed", result.success());
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 +132,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.mNewPassphrase = passphrase;
+ parcel.mNewUnlock = new ChangeUnlockParcel(passphrase);
assertFailure("creating ring with < 512 bytes keysize should fail", parcel,
LogType.MSG_CR_ERROR_KEYSIZE_512);
@@ -138,7 +143,7 @@ public class PgpKeyOperationTest {
parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd(
Algorithm.ELGAMAL, 1024, null, KeyFlags.CERTIFY_OTHER, 0L));
parcel.mAddUserIds.add("shy");
- parcel.mNewPassphrase = passphrase;
+ parcel.mNewUnlock = new ChangeUnlockParcel(passphrase);
assertFailure("creating ring with ElGamal master key should fail", parcel,
LogType.MSG_CR_ERROR_FLAGS_ELGAMAL);
@@ -149,7 +154,7 @@ public class PgpKeyOperationTest {
parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd(
Algorithm.RSA, 1024, null, KeyFlags.CERTIFY_OTHER, null));
parcel.mAddUserIds.add("lotus");
- parcel.mNewPassphrase = passphrase;
+ parcel.mNewUnlock = new ChangeUnlockParcel(passphrase);
assertFailure("creating master key with null expiry should fail", parcel,
LogType.MSG_CR_ERROR_NULL_EXPIRY);
@@ -160,7 +165,7 @@ public class PgpKeyOperationTest {
parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd(
Algorithm.RSA, 1024, null, KeyFlags.SIGN_DATA, 0L));
parcel.mAddUserIds.add("shy");
- parcel.mNewPassphrase = 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 +175,7 @@ public class PgpKeyOperationTest {
parcel.reset();
parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd(
Algorithm.RSA, 1024, null, KeyFlags.CERTIFY_OTHER, 0L));
- parcel.mNewPassphrase = passphrase;
+ parcel.mNewUnlock = new ChangeUnlockParcel(passphrase);
assertFailure("creating ring without user ids should fail", parcel,
LogType.MSG_CR_ERROR_NO_USER_ID);
@@ -179,7 +184,7 @@ public class PgpKeyOperationTest {
{
parcel.reset();
parcel.mAddUserIds.add("shy");
- parcel.mNewPassphrase = passphrase;
+ parcel.mNewUnlock = new ChangeUnlockParcel(passphrase);
assertFailure("creating ring with no master key should fail", parcel,
LogType.MSG_CR_ERROR_NO_MASTER);
@@ -226,7 +231,7 @@ public class PgpKeyOperationTest {
ring.getPublicKey().getCreationTime().after(new Date(new Date().getTime()-1000*120)));
Assert.assertNull("key ring should not expire",
- ring.getPublicKey().getExpiryTime());
+ ring.getPublicKey().getUnsafeExpiryTimeForTesting());
Assert.assertEquals("first (master) key can certify",
KeyFlags.CERTIFY_OTHER, (long) subkeys.get(0).getKeyUsage());
@@ -337,9 +342,9 @@ public class PgpKeyOperationTest {
Assert.assertNotNull("new key is not null", newKey);
Assert.assertNotNull("added key must have an expiry date",
- newKey.getExpiryTime());
+ newKey.getUnsafeExpiryTimeForTesting());
Assert.assertEquals("added key must have expected expiry date",
- expiry, newKey.getExpiryTime().getTime()/1000);
+ expiry, newKey.getUnsafeExpiryTimeForTesting().getTime()/1000);
Assert.assertEquals("added key must have expected flags",
flags, (long) newKey.getKeyUsage());
Assert.assertEquals("added key must have expected bitsize",
@@ -398,9 +403,9 @@ public class PgpKeyOperationTest {
ring.getMasterKeyId(), ((SignaturePacket) p).getKeyID());
Assert.assertNotNull("modified key must have an expiry date",
- modified.getPublicKey(keyId).getExpiryTime());
+ modified.getPublicKey(keyId).getUnsafeExpiryTimeForTesting());
Assert.assertEquals("modified key must have expected expiry date",
- expiry, modified.getPublicKey(keyId).getExpiryTime().getTime()/1000);
+ expiry, modified.getPublicKey(keyId).getUnsafeExpiryTimeForTesting().getTime()/1000);
Assert.assertEquals("modified key must have same flags as before",
ring.getPublicKey(keyId).getKeyUsage(), modified.getPublicKey(keyId).getKeyUsage());
}
@@ -412,9 +417,9 @@ public class PgpKeyOperationTest {
modified = applyModificationWithChecks(parcel, modified, onlyA, onlyB);
Assert.assertNotNull("modified key must have an expiry date",
- modified.getPublicKey(keyId).getExpiryTime());
+ modified.getPublicKey(keyId).getUnsafeExpiryTimeForTesting());
Assert.assertEquals("modified key must have expected expiry date",
- expiry, modified.getPublicKey(keyId).getExpiryTime().getTime()/1000);
+ expiry, modified.getPublicKey(keyId).getUnsafeExpiryTimeForTesting().getTime()/1000);
Assert.assertEquals("modified key must have same flags as before",
ring.getPublicKey(keyId).getKeyUsage(), modified.getPublicKey(keyId).getKeyUsage());
}
@@ -438,9 +443,9 @@ public class PgpKeyOperationTest {
Assert.assertEquals("modified key must have expected flags",
flags, (long) modified.getPublicKey(keyId).getKeyUsage());
Assert.assertNotNull("key must retain its expiry",
- modified.getPublicKey(keyId).getExpiryTime());
+ modified.getPublicKey(keyId).getUnsafeExpiryTimeForTesting());
Assert.assertEquals("key expiry must be unchanged",
- expiry, modified.getPublicKey(keyId).getExpiryTime().getTime()/1000);
+ expiry, modified.getPublicKey(keyId).getUnsafeExpiryTimeForTesting().getTime()/1000);
}
{ // expiry of 0 should be "no expiry"
@@ -458,7 +463,7 @@ public class PgpKeyOperationTest {
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());
+ Assert.assertNull("key must not expire anymore", modified.getPublicKey(keyId).getUnsafeExpiryTimeForTesting());
}
{ // a past expiry should fail
@@ -512,9 +517,9 @@ public class PgpKeyOperationTest {
PacketTags.SIGNATURE, onlyB.get(1).tag);
Assert.assertNotNull("modified key must have an expiry date",
- modified.getPublicKey().getExpiryTime());
+ modified.getPublicKey().getUnsafeExpiryTimeForTesting());
Assert.assertEquals("modified key must have expected expiry date",
- expiry, modified.getPublicKey().getExpiryTime().getTime() / 1000);
+ expiry, modified.getPublicKey().getUnsafeExpiryTimeForTesting().getTime() / 1000);
Assert.assertEquals("modified key must have same flags as before",
ring.getPublicKey().getKeyUsage(), modified.getPublicKey().getKeyUsage());
}
@@ -526,9 +531,9 @@ public class PgpKeyOperationTest {
modified = applyModificationWithChecks(parcel, modified, onlyA, onlyB);
Assert.assertNotNull("modified key must have an expiry date",
- modified.getPublicKey(keyId).getExpiryTime());
+ modified.getPublicKey(keyId).getUnsafeExpiryTimeForTesting());
Assert.assertEquals("modified key must have expected expiry date",
- expiry, modified.getPublicKey(keyId).getExpiryTime().getTime()/1000);
+ expiry, modified.getPublicKey(keyId).getUnsafeExpiryTimeForTesting().getTime() / 1000);
Assert.assertEquals("modified key must have same flags as before",
ring.getPublicKey(keyId).getKeyUsage(), modified.getPublicKey(keyId).getKeyUsage());
}
@@ -542,17 +547,29 @@ public class PgpKeyOperationTest {
Assert.assertEquals("modified key must have expected flags",
flags, (long) modified.getPublicKey(keyId).getKeyUsage());
Assert.assertNotNull("key must retain its expiry",
- modified.getPublicKey(keyId).getExpiryTime());
+ modified.getPublicKey(keyId).getUnsafeExpiryTimeForTesting());
Assert.assertEquals("key expiry must be unchanged",
- expiry, modified.getPublicKey(keyId).getExpiryTime().getTime()/1000);
+ expiry, modified.getPublicKey(keyId).getUnsafeExpiryTimeForTesting().getTime()/1000);
}
{ // expiry of 0 should be "no expiry"
+
+ // even if there is a non-expiring user id while all others are revoked, it doesn't count!
+ // for this purpose we revoke one while they still have expiry times
+ parcel.reset();
+ parcel.mRevokeUserIds.add("aloe");
+ modified = applyModificationWithChecks(parcel, modified, onlyA, onlyB);
+
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());
+ // for this check, it is relevant that we DON'T use the unsafe one!
+ Assert.assertNull("key must not expire anymore",
+ modified.canonicalize(new OperationLog(), 0).getPublicKey().getExpiryTime());
+ // make sure the unsafe one behaves incorrectly as expected
+ Assert.assertNotNull("unsafe expiry must yield wrong result from revoked user id",
+ modified.getPublicKey(keyId).getUnsafeExpiryTimeForTesting());
}
{ // if we revoke everything, nothing is left to properly sign...
@@ -604,7 +621,7 @@ public class PgpKeyOperationTest {
ring.getMasterKeyId(), ((SignaturePacket) p).getKeyID());
Assert.assertTrue("subkey must actually be revoked",
- modified.getPublicKey().isRevoked());
+ modified.getPublicKey().isMaybeRevoked());
}
@@ -648,13 +665,14 @@ public class PgpKeyOperationTest {
ring.getMasterKeyId(), ((SignaturePacket) p).getKeyID());
Assert.assertTrue("subkey must actually be revoked",
- modified.getPublicKey(keyId).isRevoked());
+ modified.getPublicKey(keyId).isMaybeRevoked());
}
{ // re-add second subkey
parcel.reset();
- parcel.mChangeSubKeys.add(new SubkeyChange(keyId, null, null));
+ // re-certify the revoked subkey
+ parcel.mChangeSubKeys.add(new SubkeyChange(keyId, true));
modified = applyModificationWithChecks(parcel, modified, onlyA, onlyB);
@@ -685,7 +703,7 @@ public class PgpKeyOperationTest {
ring.getMasterKeyId(), ((SignaturePacket) p).getKeyID());
Assert.assertFalse("subkey must no longer be revoked",
- modified.getPublicKey(keyId).isRevoked());
+ modified.getPublicKey(keyId).isMaybeRevoked());
Assert.assertEquals("subkey must have the same usage flags as before",
flags, (long) modified.getPublicKey(keyId).getKeyUsage());
@@ -696,7 +714,7 @@ public class PgpKeyOperationTest {
public void testSubkeyStrip() throws Exception {
long keyId = KeyringTestingHelper.getSubkeyId(ring, 1);
- parcel.mStripSubKeys.add(keyId);
+ parcel.mChangeSubKeys.add(new SubkeyChange(keyId, true, null));
applyModificationWithChecks(parcel, ring, onlyA, onlyB);
Assert.assertEquals("one extra packet in original", 1, onlyA.size());
@@ -722,7 +740,7 @@ public class PgpKeyOperationTest {
public void testMasterStrip() throws Exception {
long keyId = ring.getMasterKeyId();
- parcel.mStripSubKeys.add(keyId);
+ parcel.mChangeSubKeys.add(new SubkeyChange(keyId, true, null));
applyModificationWithChecks(parcel, ring, onlyA, onlyB);
Assert.assertEquals("one extra packet in original", 1, onlyA.size());
@@ -741,6 +759,44 @@ public class PgpKeyOperationTest {
Assert.assertEquals("new packet secret key data should have length zero",
0, ((SecretKeyPacket) p).getSecretKeyData().length);
Assert.assertNull("new packet should have no iv data", ((SecretKeyPacket) p).getIV());
+ }
+
+ @Test
+ public void testRestrictedStrip() throws Exception {
+
+ long keyId = KeyringTestingHelper.getSubkeyId(ring, 1);
+ UncachedKeyRing modified;
+
+ { // we should be able to change the stripped/divert status of subkeys without passphrase
+ parcel.reset();
+ parcel.mChangeSubKeys.add(new SubkeyChange(keyId, true, null));
+ modified = applyModificationWithChecks(parcel, ring, onlyA, onlyB, null);
+ Assert.assertEquals("one extra packet in modified", 1, onlyB.size());
+ Packet p = new BCPGInputStream(new ByteArrayInputStream(onlyB.get(0).buf)).readPacket();
+ Assert.assertEquals("new packet should have GNU_DUMMY S2K type",
+ S2K.GNU_DUMMY_S2K, ((SecretKeyPacket) p).getS2K().getType());
+ Assert.assertEquals("new packet should have GNU_DUMMY protection mode stripped",
+ S2K.GNU_PROTECTION_MODE_NO_PRIVATE_KEY, ((SecretKeyPacket) p).getS2K().getProtectionMode());
+ }
+
+ { // and again, changing to divert-to-card
+ parcel.reset();
+ byte[] serial = new byte[] {
+ 0x6a, 0x6f, 0x6c, 0x6f, 0x73, 0x77, 0x61, 0x67,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ };
+ parcel.mChangeSubKeys.add(new SubkeyChange(keyId, false, serial));
+ modified = applyModificationWithChecks(parcel, ring, onlyA, onlyB, null);
+ Assert.assertEquals("one extra packet in modified", 1, onlyB.size());
+ Packet p = new BCPGInputStream(new ByteArrayInputStream(onlyB.get(0).buf)).readPacket();
+ Assert.assertEquals("new packet should have GNU_DUMMY S2K type",
+ S2K.GNU_DUMMY_S2K, ((SecretKeyPacket) p).getS2K().getType());
+ Assert.assertEquals("new packet should have GNU_DUMMY protection mode divert-to-card",
+ S2K.GNU_PROTECTION_MODE_DIVERT_TO_CARD, ((SecretKeyPacket) p).getS2K().getProtectionMode());
+ Assert.assertArrayEquals("new packet should have correct serial number as iv",
+ serial, ((SecretKeyPacket) p).getIV());
+
+ }
}
@@ -862,6 +918,70 @@ public class PgpKeyOperationTest {
}
@Test
+ public void testUserAttributeAdd() throws Exception {
+
+ {
+ parcel.mAddUserAttribute.add(WrappedUserAttribute.fromData(new byte[0]));
+ assertModifyFailure("adding an empty user attribute should fail", ring, parcel,
+ LogType.MSG_MF_UAT_ERROR_EMPTY);
+ }
+
+ parcel.reset();
+
+ Random r = new Random();
+ int type = r.nextInt(110)+1;
+ byte[] data = new byte[r.nextInt(2000)];
+ new Random().nextBytes(data);
+
+ WrappedUserAttribute uat = WrappedUserAttribute.fromSubpacket(type, data);
+ parcel.mAddUserAttribute.add(uat);
+
+ UncachedKeyRing modified = applyModificationWithChecks(parcel, ring, onlyA, onlyB);
+
+ Assert.assertEquals("no extra packets in original", 0, onlyA.size());
+ Assert.assertEquals("exactly two extra packets in modified", 2, onlyB.size());
+
+ Assert.assertTrue("keyring must contain added user attribute",
+ modified.getPublicKey().getUnorderedUserAttributes().contains(uat));
+
+ Packet p;
+
+ p = new BCPGInputStream(new ByteArrayInputStream(onlyB.get(0).buf)).readPacket();
+ Assert.assertTrue("first new packet must be user attribute", p instanceof UserAttributePacket);
+ {
+ UserAttributeSubpacket[] subpackets = ((UserAttributePacket) p).getSubpackets();
+ Assert.assertEquals("user attribute packet must contain one subpacket",
+ 1, subpackets.length);
+ Assert.assertEquals("user attribute subpacket type must be as specified above",
+ type, subpackets[0].getType());
+ Assert.assertArrayEquals("user attribute subpacket data must be as specified above",
+ data, subpackets[0].getData());
+ }
+
+ p = new BCPGInputStream(new ByteArrayInputStream(onlyB.get(1).buf)).readPacket();
+ Assert.assertTrue("second new packet must be signature", p instanceof SignaturePacket);
+ Assert.assertEquals("signature type must be positive certification",
+ PGPSignature.POSITIVE_CERTIFICATION, ((SignaturePacket) p).getSignatureType());
+
+ // make sure packets can be distinguished by timestamp
+ Thread.sleep(1000);
+
+ // applying the same modification AGAIN should not add more certifications but drop those
+ // as duplicates
+ modified = applyModificationWithChecks(parcel, modified, onlyA, onlyB, passphrase, true, false);
+
+ Assert.assertEquals("duplicate modification: one extra packet in original", 1, onlyA.size());
+ Assert.assertEquals("duplicate modification: one extra packet in modified", 1, onlyB.size());
+
+ p = new BCPGInputStream(new ByteArrayInputStream(onlyA.get(0).buf)).readPacket();
+ Assert.assertTrue("lost packet must be signature", p instanceof SignaturePacket);
+ p = new BCPGInputStream(new ByteArrayInputStream(onlyB.get(0).buf)).readPacket();
+ Assert.assertTrue("new packet must be signature", p instanceof SignaturePacket);
+
+ }
+
+
+ @Test
public void testUserIdPrimary() throws Exception {
UncachedKeyRing modified = ring;
@@ -910,8 +1030,10 @@ public class PgpKeyOperationTest {
public void testPassphraseChange() throws Exception {
// change passphrase to empty
- parcel.mNewPassphrase = "";
- 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);
Assert.assertEquals("exactly three packets should have been modified (the secret keys)",
3, onlyB.size());
@@ -923,7 +1045,7 @@ public class PgpKeyOperationTest {
// modify keyring, change to non-empty passphrase
String otherPassphrase = TestingUtils.genPassphrase(true);
- parcel.mNewPassphrase = otherPassphrase;
+ parcel.mNewUnlock = new ChangeUnlockParcel(otherPassphrase);
modified = applyModificationWithChecks(parcel, modified, onlyA, onlyB, "");
Assert.assertEquals("exactly three packets should have been modified (the secret keys)",
@@ -948,7 +1070,7 @@ public class PgpKeyOperationTest {
PacketTags.SECRET_SUBKEY, sKeyNoPassphrase.tag);
String otherPassphrase2 = TestingUtils.genPassphrase(true);
- parcel.mNewPassphrase = otherPassphrase2;
+ parcel.mNewUnlock = new ChangeUnlockParcel(otherPassphrase2);
{
// if we replace a secret key with one without passphrase
modified = KeyringTestingHelper.removePacket(modified, sKeyNoPassphrase.position);
@@ -957,7 +1079,7 @@ public class PgpKeyOperationTest {
// 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);
+ PgpEditKeyResult 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());
@@ -973,7 +1095,7 @@ public class PgpKeyOperationTest {
PgpKeyOperation op = new PgpKeyOperation(null);
CanonicalizedSecretKeyRing secretRing = new CanonicalizedSecretKeyRing(modified.getEncoded(), false, 0);
- EditKeyResult result = op.modifySecretKeyRing(secretRing, parcel, otherPassphrase2);
+ PgpEditKeyResult result = op.modifySecretKeyRing(secretRing, parcel, otherPassphrase2);
Assert.assertTrue("key modification must succeed", result.success());
Assert.assertTrue("log must contain a failed passphrase change warning",
result.getLog().containsType(LogType.MSG_MF_PASSPHRASE_FAIL));
@@ -981,6 +1103,57 @@ public class PgpKeyOperationTest {
}
+ @Test
+ public void testUnlockPin() throws Exception {
+
+ String pin = "5235125";
+
+ // change passphrase to a pin type
+ parcel.mNewUnlock = new ChangeUnlockParcel(null, pin);
+ UncachedKeyRing modified = applyModificationWithChecks(parcel, ring, onlyA, onlyB);
+
+ Assert.assertEquals("exactly three packets should have been added (the secret keys + notation packet)",
+ 3, onlyA.size());
+ Assert.assertEquals("exactly four packets should have been added (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());
+
+ // need to sleep for a sec, so the timestamp changes for notation data
+ Thread.sleep(1000);
+
+ {
+ parcel.mNewUnlock = new ChangeUnlockParcel("phrayse", null);
+ applyModificationWithChecks(parcel, modified, onlyA, onlyB, pin, true, false);
+
+ Assert.assertEquals("exactly four packets should have been removed (the secret keys + notation packet)",
+ 4, onlyA.size());
+ Assert.assertEquals("exactly three packets should have been added (no more notation packet)",
+ 3, onlyB.size());
+ }
+
+ }
+
+ @Test
+ public void testRestricted () throws Exception {
+
+ CanonicalizedSecretKeyRing secretRing = new CanonicalizedSecretKeyRing(ring.getEncoded(), false, 0);
+
+ parcel.mAddUserIds.add("discord");
+ PgpKeyOperation op = new PgpKeyOperation(null);
+ PgpEditKeyResult result = op.modifySecretKeyRing(secretRing, parcel, null);
+ Assert.assertFalse("non-restricted operations should fail without passphrase", result.success());
+ }
+
private static UncachedKeyRing applyModificationWithChecks(SaveKeyringParcel parcel,
UncachedKeyRing ring,
ArrayList<RawPacket> onlyA,
@@ -1011,7 +1184,7 @@ public class PgpKeyOperationTest {
CanonicalizedSecretKeyRing secretRing = new CanonicalizedSecretKeyRing(ring.getEncoded(), false, 0);
PgpKeyOperation op = new PgpKeyOperation(null);
- EditKeyResult result = op.modifySecretKeyRing(secretRing, parcel, passphrase);
+ PgpEditKeyResult 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);
@@ -1068,7 +1241,7 @@ public class PgpKeyOperationTest {
private void assertFailure(String reason, SaveKeyringParcel parcel, LogType expected) {
- EditKeyResult result = op.createSecretKeyRing(parcel);
+ PgpEditKeyResult result = op.createSecretKeyRing(parcel);
Assert.assertFalse(reason, result.success());
Assert.assertNull(reason, result.getRing());
@@ -1082,7 +1255,7 @@ public class PgpKeyOperationTest {
throws Exception {
CanonicalizedSecretKeyRing secretRing = new CanonicalizedSecretKeyRing(ring.getEncoded(), false, 0);
- EditKeyResult result = op.modifySecretKeyRing(secretRing, parcel, passphrase);
+ PgpEditKeyResult result = op.modifySecretKeyRing(secretRing, parcel, passphrase);
Assert.assertFalse(reason, result.success());
Assert.assertNull(reason, result.getRing());
@@ -1096,7 +1269,7 @@ public class PgpKeyOperationTest {
throws Exception {
CanonicalizedSecretKeyRing secretRing = new CanonicalizedSecretKeyRing(ring.getEncoded(), false, 0);
- EditKeyResult result = op.modifySecretKeyRing(secretRing, parcel, passphrase);
+ PgpEditKeyResult result = op.modifySecretKeyRing(secretRing, parcel, passphrase);
Assert.assertFalse(reason, result.success());
Assert.assertNull(reason, result.getRing());
@@ -1107,7 +1280,7 @@ public class PgpKeyOperationTest {
private UncachedKeyRing assertCreateSuccess(String reason, SaveKeyringParcel parcel) {
- EditKeyResult result = op.createSecretKeyRing(parcel);
+ PgpEditKeyResult result = op.createSecretKeyRing(parcel);
Assert.assertTrue(reason, result.success());
Assert.assertNotNull(reason, result.getRing());