From 7524881a01efe96d7467e439098ad440d9afb11b Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Tue, 30 Dec 2014 12:02:37 +0100 Subject: fix unit tests for ChangeUnlockParcel --- .../keychain/pgp/PgpEncryptDecryptTest.java | 5 +++-- .../keychain/pgp/PgpKeyOperationTest.java | 21 +++++++++++---------- .../pgp/UncachedKeyringCanonicalizeTest.java | 3 ++- .../keychain/pgp/UncachedKeyringMergeTest.java | 5 +++-- .../keychain/pgp/UncachedKeyringTest.java | 3 ++- 5 files changed, 21 insertions(+), 16 deletions(-) (limited to 'OpenKeychain-Test/src') 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..6fa907520 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 @@ -43,6 +43,7 @@ import org.sufficientlysecure.keychain.operations.results.OperationResult.Operat 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.service.SaveKeyringParcel.SubkeyAdd; import org.sufficientlysecure.keychain.service.SaveKeyringParcel.SubkeyChange; import org.sufficientlysecure.keychain.support.KeyringBuilder; @@ -91,7 +92,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); @@ -127,7 +128,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 +139,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 +150,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 +161,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 +171,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 +180,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,7 +911,7 @@ public class PgpKeyOperationTest { public void testPassphraseChange() throws Exception { // change passphrase to empty - parcel.mNewUnlock = ""; + parcel.mNewUnlock = new ChangeUnlockParcel(""); UncachedKeyRing modified = applyModificationWithChecks(parcel, ring, onlyA, onlyB); Assert.assertEquals("exactly three packets should have been modified (the secret keys)", @@ -923,7 +924,7 @@ public class PgpKeyOperationTest { // modify keyring, change to non-empty passphrase String otherPassphrase = TestingUtils.genPassphrase(true); - parcel.mNewUnlock = 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 +949,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); 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); -- cgit v1.2.3 From 22ea1defa80d7cb185e75bed20ec9ed28377df8c Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Tue, 30 Dec 2014 13:07:36 +0100 Subject: add test case for PIN unlock --- .../keychain/pgp/PgpKeyOperationTest.java | 30 ++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) (limited to 'OpenKeychain-Test/src') 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 6fa907520..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,6 +41,7 @@ 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; @@ -100,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); @@ -912,7 +914,9 @@ public class PgpKeyOperationTest { // change passphrase to empty parcel.mNewUnlock = new ChangeUnlockParcel(""); - UncachedKeyRing modified = applyModificationWithChecks(parcel, ring, onlyA, onlyB); + // 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()); @@ -925,7 +929,7 @@ public class PgpKeyOperationTest { // modify keyring, change to non-empty passphrase String otherPassphrase = TestingUtils.genPassphrase(true); parcel.mNewUnlock = new ChangeUnlockParcel(otherPassphrase); - modified = applyModificationWithChecks(parcel, modified, onlyA, onlyB, ""); + modified = applyModificationWithChecks(parcel, modified, onlyA, onlyB, "", true, false); Assert.assertEquals("exactly three packets should have been modified (the secret keys)", 3, onlyB.size()); @@ -982,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 onlyA, -- cgit v1.2.3 From bf537c4a81371e95cff613d4f9847bf2365e6ec8 Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Thu, 1 Jan 2015 18:24:09 +0100 Subject: fix unit tests (canonicalize after create) --- .../keychain/pgp/UncachedKeyringCanonicalizeTest.java | 2 ++ .../org/sufficientlysecure/keychain/pgp/UncachedKeyringMergeTest.java | 3 +++ 2 files changed, 5 insertions(+) (limited to 'OpenKeychain-Test/src') 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 7d8a10ee0..b3a149eec 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 @@ -113,6 +113,8 @@ public class UncachedKeyringCanonicalizeTest { staticRing = result.getRing(); Assert.assertNotNull("initial test key creation must succeed", staticRing); + staticRing = staticRing.canonicalize(new OperationLog(), 0).getUncachedKeyRing(); + // just for later reference totalPackets = 9; 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 799640d6c..7e2cbee0c 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 @@ -34,6 +34,7 @@ import org.spongycastle.jce.provider.BouncyCastleProvider; import org.spongycastle.util.Strings; import org.sufficientlysecure.keychain.operations.results.OperationResult; import org.sufficientlysecure.keychain.operations.results.EditKeyResult; +import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog; import org.sufficientlysecure.keychain.service.SaveKeyringParcel; import org.sufficientlysecure.keychain.service.SaveKeyringParcel.Algorithm; import org.sufficientlysecure.keychain.service.SaveKeyringParcel.ChangeUnlockParcel; @@ -104,6 +105,7 @@ public class UncachedKeyringMergeTest { EditKeyResult result = op.createSecretKeyRing(parcel); staticRingA = result.getRing(); + staticRingA = staticRingA.canonicalize(new OperationLog(), 0).getUncachedKeyRing(); } { @@ -119,6 +121,7 @@ public class UncachedKeyringMergeTest { OperationResult.OperationLog log = new OperationResult.OperationLog(); EditKeyResult result = op.createSecretKeyRing(parcel); staticRingB = result.getRing(); + staticRingB = staticRingB.canonicalize(new OperationLog(), 0).getUncachedKeyRing(); } Assert.assertNotNull("initial test key creation must succeed", staticRingA); -- cgit v1.2.3 From 5e9d8ca8c6af6a3c274208799cd4b2a22de2d843 Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Thu, 1 Jan 2015 20:21:32 +0100 Subject: tests: add multi key encryption/decryption test, new way for fake passphrase cache --- .../keychain/pgp/PgpEncryptDecryptTest.java | 166 +++++++++++++++------ 1 file changed, 123 insertions(+), 43 deletions(-) (limited to 'OpenKeychain-Test/src') 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 8c1a358b0..6a396697c 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 @@ -119,7 +119,7 @@ public class PgpEncryptDecryptTest { InputData data = new InputData(in, in.available()); Builder b = new PgpSignEncrypt.Builder(Robolectric.application, new ProviderHelper(Robolectric.application), - null, // new DummyPassphraseCache(mPassphrase, 0L) + null, data, out); b.setSymmetricPassphrase(mPassphrase); @@ -216,11 +216,8 @@ public class PgpEncryptDecryptTest { ByteArrayInputStream in = new ByteArrayInputStream(ciphertext); InputData data = new InputData(in, in.available()); - PgpDecryptVerify.Builder b = new PgpDecryptVerify.Builder( - Robolectric.application, - new ProviderHelper(Robolectric.application), - null, // new DummyPassphraseCache(null, null), - data, out); + + PgpDecryptVerify.Builder b = builderWithFakePassphraseCache(data, out, null, null, null); b.setPassphrase(mKeyPhrase1); DecryptVerifyResult result = b.build().execute(); Assert.assertTrue("decryption with provided passphrase must succeed", result.success()); @@ -231,74 +228,157 @@ public class PgpEncryptDecryptTest { // TODO how to test passphrase cache? - /*{ // decryption with passphrase cached should succeed + { // decryption with passphrase cached should succeed ByteArrayOutputStream out = new ByteArrayOutputStream(); ByteArrayInputStream in = new ByteArrayInputStream(ciphertext); InputData data = new InputData(in, in.available()); - PassphraseCacheService.addCachedPassphrase( - Robolectric.application, mStaticRing1.getMasterKeyId(), - mStaticRing1.getMasterKeyId(), mKeyPhrase1, "dummy"); + PgpDecryptVerify.Builder b = builderWithFakePassphraseCache(data, out, + mKeyPhrase1, mStaticRing1.getMasterKeyId(), null); - PgpDecryptVerify.Builder b = new PgpDecryptVerify.Builder( - Robolectric.application, - new ProviderHelper(Robolectric.application), - null, // new DummyPassphraseCache(mKeyPhrase1, null), - data, out); DecryptVerifyResult result = b.build().execute(); Assert.assertTrue("decryption with cached passphrase must succeed", result.success()); Assert.assertArrayEquals("decrypted ciphertext with cached passphrase should equal plaintext", out.toByteArray(), plaintext.getBytes()); Assert.assertNull("signature should be empty", result.getSignatureResult()); - }*/ + } - /*{ // decryption with no passphrase provided should return status pending + { // decryption with no passphrase provided should return status pending ByteArrayOutputStream out = new ByteArrayOutputStream(); ByteArrayInputStream in = new ByteArrayInputStream(ciphertext); InputData data = new InputData(in, in.available()); - PgpDecryptVerify.Builder b = new PgpDecryptVerify.Builder( - Robolectric.application, - new ProviderHelper(Robolectric.application), - null, // new DummyPassphraseCache(null, null), - data, out); + PgpDecryptVerify.Builder b = builderWithFakePassphraseCache(data, out, + null, mStaticRing1.getMasterKeyId(), null); DecryptVerifyResult result = b.build().execute(); Assert.assertFalse("decryption with no passphrase must return pending", result.success()); Assert.assertTrue("decryption with no passphrase should return pending", result.isPending()); Assert.assertEquals("decryption with no passphrase should return pending passphrase", DecryptVerifyResult.RESULT_PENDING_ASYM_PASSPHRASE, result.getResult()); - }*/ + } } - static class DummyPassphraseCache implements PassphraseCacheInterface { + @Test + public void testMultiAsymmetricEncryptDecrypt() { + + String plaintext = "dies ist ein plaintext ☭" + TestingUtils.genPassphrase(true); + byte[] ciphertext; + + { // encrypt data with a given passphrase + ByteArrayOutputStream out = new ByteArrayOutputStream(); + ByteArrayInputStream in = new ByteArrayInputStream(plaintext.getBytes()); - String mPassphrase; - Long mExpectedId; - public DummyPassphraseCache(String passphrase, Long expectedId) { - mPassphrase = passphrase; - mExpectedId = expectedId; + InputData data = new InputData(in, in.available()); + Builder b = new PgpSignEncrypt.Builder( + Robolectric.application, + new ProviderHelper(Robolectric.application), + null, // new DummyPassphraseCache(mPassphrase, 0L), + data, out); + + b.setEncryptionMasterKeyIds(new long[] { + mStaticRing1.getMasterKeyId(), + mStaticRing2.getMasterKeyId() + }); + b.setSymmetricEncryptionAlgorithm(PGPEncryptedData.AES_128); + SignEncryptResult result = b.build().execute(); + Assert.assertTrue("encryption must succeed", result.success()); + + ciphertext = out.toByteArray(); } - @Override - public String getCachedPassphrase(long masterKeyId, long subKeyId) throws NoSecretKeyException { - if (mExpectedId != null){ - Assert.assertEquals("requested passphrase must be for expected id", - (long) mExpectedId, subKeyId); - } - return mPassphrase; + { // decryption with passphrase cached should succeed for the first key + + ByteArrayOutputStream out = new ByteArrayOutputStream(); + ByteArrayInputStream in = new ByteArrayInputStream(ciphertext); + InputData data = new InputData(in, in.available()); + + PgpDecryptVerify.Builder b = builderWithFakePassphraseCache(data, out, + mKeyPhrase1, mStaticRing1.getMasterKeyId(), null); + + DecryptVerifyResult result = b.build().execute(); + Assert.assertTrue("decryption with cached passphrase must succeed for the first key", result.success()); + Assert.assertArrayEquals("decrypted ciphertext with cached passphrase should equal plaintext", + out.toByteArray(), plaintext.getBytes()); + Assert.assertNull("signature should be empty", result.getSignatureResult()); } - @Override - public String getCachedPassphrase(long subKeyId) throws NoSecretKeyException { - if (mExpectedId != null){ - Assert.assertEquals("requested passphrase must be for expected id", - (long) mExpectedId, subKeyId); - } - return mPassphrase; + { // decryption with passphrase cached should succeed for the first key + + ByteArrayOutputStream out = new ByteArrayOutputStream(); + ByteArrayInputStream in = new ByteArrayInputStream(ciphertext); + InputData data = new InputData(in, in.available()); + + // allow only the second to decrypt + HashSet allowed = new HashSet(); + allowed.add(mStaticRing2.getMasterKeyId()); + + // provide passphrase for the second, and check that the first is never asked for! + PgpDecryptVerify.Builder b = builderWithFakePassphraseCache(data, out, + mKeyPhrase2, mStaticRing2.getMasterKeyId(), null); + b.setAllowedKeyIds(allowed); + + DecryptVerifyResult result = b.build().execute(); + Assert.assertTrue("decryption with cached passphrase must succeed for the first key", result.success()); + Assert.assertArrayEquals("decrypted ciphertext with cached passphrase should equal plaintext", + out.toByteArray(), plaintext.getBytes()); + Assert.assertNull("signature should be empty", result.getSignatureResult()); } + + { // decryption with passphrase cached should succeed for the other key if first is gone + + // delete first key from database + new ProviderHelper(Robolectric.application).getContentResolver().delete( + KeyRingData.buildPublicKeyRingUri(mStaticRing1.getMasterKeyId()), null, null + ); + + ByteArrayOutputStream out = new ByteArrayOutputStream(); + ByteArrayInputStream in = new ByteArrayInputStream(ciphertext); + InputData data = new InputData(in, in.available()); + + PgpDecryptVerify.Builder b = builderWithFakePassphraseCache(data, out, + mKeyPhrase2, mStaticRing2.getMasterKeyId(), null); + + DecryptVerifyResult result = b.build().execute(); + Assert.assertTrue("decryption with cached passphrase must succeed", result.success()); + Assert.assertArrayEquals("decrypted ciphertext with cached passphrase should equal plaintext", + out.toByteArray(), plaintext.getBytes()); + Assert.assertNull("signature should be empty", result.getSignatureResult()); + } + + } + + private PgpDecryptVerify.Builder builderWithFakePassphraseCache ( + InputData data, OutputStream out, + final String passphrase, final Long checkMasterKeyId, final Long checkSubKeyId) { + + return new PgpDecryptVerify.Builder(Robolectric.application, + new ProviderHelper(Robolectric.application), + null, + data, out) { + public PgpDecryptVerify build() { + return new PgpDecryptVerify(this) { + @Override + public String getCachedPassphrase(long masterKeyId, long subKeyId) + throws NoSecretKeyException { + if (checkMasterKeyId != null) { + Assert.assertEquals("requested passphrase should be for expected master key id", + (long) checkMasterKeyId, masterKeyId); + } + if (checkSubKeyId != null) { + Assert.assertEquals("requested passphrase should be for expected sub key id", + (long) checkSubKeyId, subKeyId); + } + if (passphrase == null) { + return null; + } + return passphrase; + } + }; + } + }; } } -- cgit v1.2.3 From 9f7b2472cfdfbd48072dbcc122656945fc319650 Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Thu, 1 Jan 2015 20:21:52 +0100 Subject: tests: be less verbose about inserting keyrings for encrypt/decrypt --- .../keychain/pgp/PgpEncryptDecryptTest.java | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) (limited to 'OpenKeychain-Test/src') 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 6a396697c..8d0c4ab80 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 @@ -28,6 +28,7 @@ import org.spongycastle.bcpg.sig.KeyFlags; import org.spongycastle.jce.provider.BouncyCastleProvider; import org.spongycastle.openpgp.PGPEncryptedData; import org.sufficientlysecure.keychain.pgp.PgpSignEncrypt.Builder; +import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRingData; import org.sufficientlysecure.keychain.provider.ProviderHelper; import org.sufficientlysecure.keychain.service.SaveKeyringParcel; import org.sufficientlysecure.keychain.service.SaveKeyringParcel.Algorithm; @@ -41,7 +42,10 @@ import org.sufficientlysecure.keychain.util.TestingUtils; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; +import java.io.OutputStream; +import java.io.PrintStream; import java.security.Security; +import java.util.HashSet; @RunWith(RobolectricTestRunner.class) @org.robolectric.annotation.Config(emulateSdk = 18) // Robolectric doesn't yet support 19 @@ -53,10 +57,13 @@ public class PgpEncryptDecryptTest { static String mKeyPhrase1 = TestingUtils.genPassphrase(true); static String mKeyPhrase2 = TestingUtils.genPassphrase(true); + static PrintStream oldShadowStream; + @BeforeClass public static void setUpOnce() throws Exception { Security.insertProviderAt(new BouncyCastleProvider(), 1); - ShadowLog.stream = System.out; + oldShadowStream = ShadowLog.stream; + // ShadowLog.stream = System.out; PgpKeyOperation op = new PgpKeyOperation(null); @@ -102,8 +109,14 @@ public class PgpEncryptDecryptTest { public void setUp() { ProviderHelper providerHelper = new ProviderHelper(Robolectric.application); + // don't log verbosely here, we're not here to test imports + ShadowLog.stream = oldShadowStream; + providerHelper.saveSecretKeyRing(mStaticRing1, new ProgressScaler()); - providerHelper.saveSecretKeyRing(mStaticRing1, new ProgressScaler()); + providerHelper.saveSecretKeyRing(mStaticRing2, new ProgressScaler()); + + // ok NOW log verbosely! + ShadowLog.stream = System.out; } @Test -- cgit v1.2.3 From 1c1ae769ef78a9bd3c95f97b95215616ee9b15db Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Thu, 1 Jan 2015 21:13:07 +0100 Subject: small improvements regarding pin tests and logging --- .../keychain/pgp/PgpKeyOperationTest.java | 28 ++++++++++++++++++---- 1 file changed, 23 insertions(+), 5 deletions(-) (limited to 'OpenKeychain-Test/src') 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 6b53a93ce..103e2dc88 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 @@ -916,7 +916,7 @@ public class PgpKeyOperationTest { parcel.mNewUnlock = new ChangeUnlockParcel(""); // note that canonicalization here necessarily strips the empty notation packet UncachedKeyRing modified = applyModificationWithChecks(parcel, ring, onlyA, onlyB, - passphrase, true, false); + passphrase); Assert.assertEquals("exactly three packets should have been modified (the secret keys)", 3, onlyB.size()); @@ -929,7 +929,7 @@ public class PgpKeyOperationTest { // modify keyring, change to non-empty passphrase String otherPassphrase = TestingUtils.genPassphrase(true); parcel.mNewUnlock = new ChangeUnlockParcel(otherPassphrase); - modified = applyModificationWithChecks(parcel, modified, onlyA, onlyB, "", true, false); + modified = applyModificationWithChecks(parcel, modified, onlyA, onlyB, ""); Assert.assertEquals("exactly three packets should have been modified (the secret keys)", 3, onlyB.size()); @@ -989,11 +989,15 @@ public class PgpKeyOperationTest { @Test public void testUnlockPin() throws Exception { + String pin = "5235125"; + // change passphrase to a pin type - parcel.mNewUnlock = new ChangeUnlockParcel(null, "52351"); + parcel.mNewUnlock = new ChangeUnlockParcel(null, pin); UncachedKeyRing modified = applyModificationWithChecks(parcel, ring, onlyA, onlyB); - Assert.assertEquals("exactly four packets should have been modified (the secret keys + notation packet)", + 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); @@ -1001,11 +1005,25 @@ public class PgpKeyOperationTest { PacketTags.SIGNATURE, dkSig.tag); // check that notation data contains pin - CanonicalizedSecretKeyRing secretRing = new CanonicalizedSecretKeyRing(modified.getEncoded(), false, 0); + 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()); + } + } private static UncachedKeyRing applyModificationWithChecks(SaveKeyringParcel parcel, -- cgit v1.2.3 From 57e3266fa5dfeab605ba327c7daaccfd57b87d12 Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Fri, 2 Jan 2015 00:15:08 +0100 Subject: tests: add test for key export --- .../keychain/operations/ExportTest.java | 211 +++++++++++++++++++++ 1 file changed, 211 insertions(+) create mode 100644 OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/operations/ExportTest.java (limited to 'OpenKeychain-Test/src') diff --git a/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/operations/ExportTest.java b/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/operations/ExportTest.java new file mode 100644 index 000000000..110fec2d3 --- /dev/null +++ b/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/operations/ExportTest.java @@ -0,0 +1,211 @@ +/* + * 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 + * 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.operations; + +import org.junit.Assert; +import org.junit.Before; +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.spongycastle.bcpg.sig.KeyFlags; +import org.spongycastle.jce.provider.BouncyCastleProvider; +import org.sufficientlysecure.keychain.operations.results.EditKeyResult; +import org.sufficientlysecure.keychain.operations.results.ExportResult; +import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog; +import org.sufficientlysecure.keychain.pgp.CanonicalizedPublicKeyRing; +import org.sufficientlysecure.keychain.pgp.PgpKeyOperation; +import org.sufficientlysecure.keychain.pgp.UncachedKeyRing; +import org.sufficientlysecure.keychain.pgp.WrappedSignature; +import org.sufficientlysecure.keychain.provider.ProviderHelper; +import org.sufficientlysecure.keychain.service.SaveKeyringParcel; +import org.sufficientlysecure.keychain.service.SaveKeyringParcel.Algorithm; +import org.sufficientlysecure.keychain.service.SaveKeyringParcel.ChangeUnlockParcel; +import org.sufficientlysecure.keychain.util.ProgressScaler; +import org.sufficientlysecure.keychain.util.TestingUtils; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; +import java.security.Security; +import java.util.Iterator; + +@RunWith(RobolectricTestRunner.class) +@org.robolectric.annotation.Config(emulateSdk = 18) // Robolectric doesn't yet support 19 +public class ExportTest { + + static String mPassphrase = TestingUtils.genPassphrase(true); + + static UncachedKeyRing mStaticRing1, mStaticRing2; + static String mKeyPhrase1 = TestingUtils.genPassphrase(true); + static String mKeyPhrase2 = TestingUtils.genPassphrase(true); + + static PrintStream oldShadowStream; + + @BeforeClass + public static void setUpOnce() throws Exception { + Security.insertProviderAt(new BouncyCastleProvider(), 1); + oldShadowStream = ShadowLog.stream; + // ShadowLog.stream = System.out; + + PgpKeyOperation op = new PgpKeyOperation(null); + + { + SaveKeyringParcel parcel = new SaveKeyringParcel(); + parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( + Algorithm.RSA, 1024, null, KeyFlags.CERTIFY_OTHER, 0L)); + parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( + Algorithm.DSA, 1024, null, KeyFlags.SIGN_DATA, 0L)); + parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( + Algorithm.ELGAMAL, 1024, null, KeyFlags.ENCRYPT_COMMS, 0L)); + parcel.mAddUserIds.add("snips"); + parcel.mNewUnlock = new ChangeUnlockParcel(mKeyPhrase1); + + 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()); + + mStaticRing1 = result.getRing(); + } + + { + SaveKeyringParcel parcel = new SaveKeyringParcel(); + parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( + Algorithm.RSA, 1024, null, KeyFlags.CERTIFY_OTHER, 0L)); + parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( + Algorithm.DSA, 1024, null, KeyFlags.SIGN_DATA, 0L)); + parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( + Algorithm.ELGAMAL, 1024, null, KeyFlags.ENCRYPT_COMMS, 0L)); + parcel.mAddUserIds.add("snails"); + parcel.mNewUnlock = new ChangeUnlockParcel(null, "1234"); + + 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()); + + mStaticRing2 = result.getRing(); + } + + } + + @Before + public void setUp() { + ProviderHelper providerHelper = new ProviderHelper(Robolectric.application); + + // don't log verbosely here, we're not here to test imports + ShadowLog.stream = oldShadowStream; + + providerHelper.saveSecretKeyRing(mStaticRing1, new ProgressScaler()); + providerHelper.saveSecretKeyRing(mStaticRing2, new ProgressScaler()); + + // ok NOW log verbosely! + ShadowLog.stream = System.out; + } + + @Test + public void testExportAllPublic() throws Exception { + ImportExportOperation op = new ImportExportOperation(Robolectric.application, + new ProviderHelper(Robolectric.application), null); + + ByteArrayOutputStream out = new ByteArrayOutputStream(); + ExportResult result = op.exportKeyRings(new OperationLog(), null, false, out); + + Assert.assertTrue("export must be a success", result.success()); + + long masterKeyId1, masterKeyId2; + if (mStaticRing1.getMasterKeyId() < mStaticRing2.getMasterKeyId()) { + masterKeyId1 = mStaticRing1.getMasterKeyId(); + masterKeyId2 = mStaticRing2.getMasterKeyId(); + } else { + masterKeyId2 = mStaticRing1.getMasterKeyId(); + masterKeyId1 = mStaticRing2.getMasterKeyId(); + } + + Iterator unc = + UncachedKeyRing.fromStream(new ByteArrayInputStream(out.toByteArray())); + + { + Assert.assertTrue("export must have two keys (1/2)", unc.hasNext()); + UncachedKeyRing ring = unc.next(); + Assert.assertEquals("first exported key has correct masterkeyid", + masterKeyId1, ring.getMasterKeyId()); + Assert.assertFalse("first exported key must not be secret", ring.isSecret()); + checkForLocal(ring); + } + + { + Assert.assertTrue("export must have two keys (2/2)", unc.hasNext()); + UncachedKeyRing ring = unc.next(); + Assert.assertEquals("second exported key has correct masterkeyid", + masterKeyId2, ring.getMasterKeyId()); + Assert.assertFalse("second exported key must not be secret", ring.isSecret()); + checkForLocal(ring); + } + + out = new ByteArrayOutputStream(); + result = op.exportKeyRings(new OperationLog(), null, true, out); + + Assert.assertTrue("export must be a success", result.success()); + + unc = UncachedKeyRing.fromStream(new ByteArrayInputStream(out.toByteArray())); + + { + Assert.assertTrue("export must have four keys (1/4)", unc.hasNext()); + UncachedKeyRing ring = unc.next(); + Assert.assertEquals("1/4 exported key has correct masterkeyid", + masterKeyId1, ring.getMasterKeyId()); + Assert.assertFalse("1/4 exported key must not be public", ring.isSecret()); + checkForLocal(ring); + + Assert.assertTrue("export must have four keys (2/4)", unc.hasNext()); + ring = unc.next(); + Assert.assertEquals("2/4 exported key has correct masterkeyid", + masterKeyId1, ring.getMasterKeyId()); + Assert.assertTrue("2/4 exported key must be public", ring.isSecret()); + checkForLocal(ring); + } + + { + Assert.assertTrue("export must have four keys (3/4)", unc.hasNext()); + UncachedKeyRing ring = unc.next(); + Assert.assertEquals("3/4 exported key has correct masterkeyid", + masterKeyId2, ring.getMasterKeyId()); + Assert.assertFalse("3/4 exported key must not be public", ring.isSecret()); + checkForLocal(ring); + + Assert.assertTrue("export must have four keys (4/4)", unc.hasNext()); + ring = unc.next(); + Assert.assertEquals("4/4 exported key has correct masterkeyid", + masterKeyId2, ring.getMasterKeyId()); + Assert.assertTrue("4/4 exported key must be public", ring.isSecret()); + checkForLocal(ring); + } + + } + + private void checkForLocal(UncachedKeyRing ring) { + Iterator sigs = ring.getPublicKey().getSignatures(); + while (sigs.hasNext()) { + Assert.assertFalse("there must be no local signatures in an exported keyring", + sigs.next().isLocal()); + } + } + +} -- cgit v1.2.3 From 704fc2dd45f20c7edc68b2930e2a73179d5fbdae Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Fri, 2 Jan 2015 01:11:43 +0100 Subject: tests: for export, check that a token local cert actually exists before export --- .../keychain/operations/ExportTest.java | 32 +++++++++++++++------- 1 file changed, 22 insertions(+), 10 deletions(-) (limited to 'OpenKeychain-Test/src') diff --git a/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/operations/ExportTest.java b/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/operations/ExportTest.java index 110fec2d3..8ac23b1ee 100644 --- a/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/operations/ExportTest.java +++ b/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/operations/ExportTest.java @@ -120,10 +120,13 @@ public class ExportTest { } @Test - public void testExportAllPublic() throws Exception { + public void testExportAll() throws Exception { ImportExportOperation op = new ImportExportOperation(Robolectric.application, new ProviderHelper(Robolectric.application), null); + // make sure there is a local cert (so the later checks that there are none are meaningful) + Assert.assertTrue("second keyring has local certification", checkForLocal(mStaticRing2)); + ByteArrayOutputStream out = new ByteArrayOutputStream(); ExportResult result = op.exportKeyRings(new OperationLog(), null, false, out); @@ -147,7 +150,8 @@ public class ExportTest { Assert.assertEquals("first exported key has correct masterkeyid", masterKeyId1, ring.getMasterKeyId()); Assert.assertFalse("first exported key must not be secret", ring.isSecret()); - checkForLocal(ring); + Assert.assertFalse("there must be no local signatures in an exported keyring", + checkForLocal(ring)); } { @@ -156,7 +160,8 @@ public class ExportTest { Assert.assertEquals("second exported key has correct masterkeyid", masterKeyId2, ring.getMasterKeyId()); Assert.assertFalse("second exported key must not be secret", ring.isSecret()); - checkForLocal(ring); + Assert.assertFalse("there must be no local signatures in an exported keyring", + checkForLocal(ring)); } out = new ByteArrayOutputStream(); @@ -172,14 +177,16 @@ public class ExportTest { Assert.assertEquals("1/4 exported key has correct masterkeyid", masterKeyId1, ring.getMasterKeyId()); Assert.assertFalse("1/4 exported key must not be public", ring.isSecret()); - checkForLocal(ring); + Assert.assertFalse("there must be no local signatures in an exported keyring", + checkForLocal(ring)); Assert.assertTrue("export must have four keys (2/4)", unc.hasNext()); ring = unc.next(); Assert.assertEquals("2/4 exported key has correct masterkeyid", masterKeyId1, ring.getMasterKeyId()); Assert.assertTrue("2/4 exported key must be public", ring.isSecret()); - checkForLocal(ring); + Assert.assertFalse("there must be no local signatures in an exported keyring", + checkForLocal(ring)); } { @@ -188,24 +195,29 @@ public class ExportTest { Assert.assertEquals("3/4 exported key has correct masterkeyid", masterKeyId2, ring.getMasterKeyId()); Assert.assertFalse("3/4 exported key must not be public", ring.isSecret()); - checkForLocal(ring); + Assert.assertFalse("there must be no local signatures in an exported keyring", + checkForLocal(ring)); Assert.assertTrue("export must have four keys (4/4)", unc.hasNext()); ring = unc.next(); Assert.assertEquals("4/4 exported key has correct masterkeyid", masterKeyId2, ring.getMasterKeyId()); Assert.assertTrue("4/4 exported key must be public", ring.isSecret()); - checkForLocal(ring); + Assert.assertFalse("there must be no local signatures in an exported keyring", + checkForLocal(ring)); } } - private void checkForLocal(UncachedKeyRing ring) { + /** This function checks whether or not there are any local signatures in a keyring. */ + private boolean checkForLocal(UncachedKeyRing ring) { Iterator sigs = ring.getPublicKey().getSignatures(); while (sigs.hasNext()) { - Assert.assertFalse("there must be no local signatures in an exported keyring", - sigs.next().isLocal()); + if (sigs.next().isLocal()) { + return true; + } } + return false; } } -- cgit v1.2.3 From b52fb903803c2dfca578c140dfdc776927c6fc4b Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Fri, 2 Jan 2015 01:57:49 +0100 Subject: fix and test for bad certificate version numbers (#1012) closes #1012 --- .../keychain/pgp/UncachedKeyringTest.java | 17 +++++++++++++++++ .../test/resources/test-keys/broken_cert_version.asc | 17 +++++++++++++++++ 2 files changed, 34 insertions(+) create mode 100644 OpenKeychain-Test/src/test/resources/test-keys/broken_cert_version.asc (limited to 'OpenKeychain-Test/src') 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 34c637abf..89fefb767 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 @@ -34,6 +34,7 @@ import org.sufficientlysecure.keychain.service.SaveKeyringParcel.ChangeUnlockPar import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; +import java.io.IOException; import java.util.Iterator; @RunWith(RobolectricTestRunner.class) @@ -129,4 +130,20 @@ public class UncachedKeyringTest { pubRing.extractPublicKeyRing(); } + @Test(expected = IOException.class) + public void testBrokenVersionCert() throws Throwable { + // this is a test for one of the patches we use on top of stock bouncycastle, which + // returns an IOException rather than a RuntimeException in case of a bad certificate + // version byte + readRingFromResource("/test-keys/broken_cert_version.asc"); + } + + UncachedKeyRing readRingFromResource(String name) throws Throwable { + try { + return UncachedKeyRing.fromStream(UncachedKeyringTest.class.getResourceAsStream(name)).next(); + } catch (RuntimeException e) { + throw e.getCause(); + } + } + } diff --git a/OpenKeychain-Test/src/test/resources/test-keys/broken_cert_version.asc b/OpenKeychain-Test/src/test/resources/test-keys/broken_cert_version.asc new file mode 100644 index 000000000..e2d2abd8e --- /dev/null +++ b/OpenKeychain-Test/src/test/resources/test-keys/broken_cert_version.asc @@ -0,0 +1,17 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- + +mQENBFSl5DIBCADqsGJJ8RhV4Uw6a3Q48QyTMrUtvZquOTlLVaqOdEFZNL5/OBal +prft9LNkcOkIVA89Hdn715WwkmG2OJiJoQ/ZAKwal1CPGm4Q8kZIM7k57ISJL6J5 +300e7UIznc74XbG7eFNxNcjCM9wG12vW2rFwc+ogJtkBSf0IXukPwtUkRK+H5ufO +lpqS5NNZfiGbNQCrb+YsGZNRk4QTGR6WGyaIRHlcG8G00VPGNSauTqe/11MO9MoF +BvPgFeur3nefWunCQ+uDmzIEs8r94gaHu3LWbctd5w5x/o/PDfTSSiO+U8zzXrKC +4ZpEl5bk7t7jH1hYMLWyO6nn0vWTOMO1EYLBABEBAAG0GGJyb2tlbiBzaWduYXR1 +cmUgdmVyc2lvbokBOMATAQIAIgUCVKXkMgIbAwYLCQgHAwIGFQgCCQoLBBYCAwEC +HgECF4AACgkQDe00lH/2SnprLggAh64TsdHDfIhTNc1DeJLCuvuHsitAcUdEEnue +yJjodxboKNSplIwnmb5CpM3P8f736dNaW77Yd6aO4IeAy6cBlxT1tSRkJMsp+cBt +kBa3lRr+GnWZlLZs3coL2g0t5RbuyYKyQxm2qvgFJGi/7Qfty5nJOW5U1ElT3VT8 +jISNdQdDAIaBsCE+TuyW3VsP3PqnJ7x14K7VhkFuCyvYB9paLcJBnan93R0Ja0Ip +Cv1pbrNxXp0UELf0RYc2X5C1m6otZ9LKf3PmzxlEkApkb1TZUEBak2Za5p99koZT ++pg/XpZPyawi+gZeYkBAohxRGmzG/a4L+YacAZHbchfN0eG7lg== +=mxTR +-----END PGP PUBLIC KEY BLOCK----- -- cgit v1.2.3 From 56f2a3137bbe56fee328bfbece625cf4a2f9e51d Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Fri, 2 Jan 2015 02:05:12 +0100 Subject: get rid of RuntimeException control flow in UncachedKeyRing.fromStream --- .../org/sufficientlysecure/keychain/operations/ExportTest.java | 3 ++- .../org/sufficientlysecure/keychain/pgp/UncachedKeyringTest.java | 9 +++------ 2 files changed, 5 insertions(+), 7 deletions(-) (limited to 'OpenKeychain-Test/src') diff --git a/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/operations/ExportTest.java b/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/operations/ExportTest.java index 8ac23b1ee..4470ef411 100644 --- a/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/operations/ExportTest.java +++ b/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/operations/ExportTest.java @@ -33,6 +33,7 @@ import org.sufficientlysecure.keychain.operations.results.OperationResult.Operat import org.sufficientlysecure.keychain.pgp.CanonicalizedPublicKeyRing; import org.sufficientlysecure.keychain.pgp.PgpKeyOperation; import org.sufficientlysecure.keychain.pgp.UncachedKeyRing; +import org.sufficientlysecure.keychain.pgp.UncachedKeyRing.IteratorWithIOThrow; import org.sufficientlysecure.keychain.pgp.WrappedSignature; import org.sufficientlysecure.keychain.provider.ProviderHelper; import org.sufficientlysecure.keychain.service.SaveKeyringParcel; @@ -141,7 +142,7 @@ public class ExportTest { masterKeyId1 = mStaticRing2.getMasterKeyId(); } - Iterator unc = + IteratorWithIOThrow unc = UncachedKeyRing.fromStream(new ByteArrayInputStream(out.toByteArray())); { 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 89fefb767..e5c00221b 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 @@ -27,6 +27,7 @@ import org.robolectric.RobolectricTestRunner; import org.robolectric.shadows.ShadowLog; import org.spongycastle.bcpg.sig.KeyFlags; import org.sufficientlysecure.keychain.operations.results.EditKeyResult; +import org.sufficientlysecure.keychain.pgp.UncachedKeyRing.IteratorWithIOThrow; import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException; import org.sufficientlysecure.keychain.service.SaveKeyringParcel; import org.sufficientlysecure.keychain.service.SaveKeyringParcel.Algorithm; @@ -110,7 +111,7 @@ public class UncachedKeyringTest { ring.encodeArmored(out, "OpenKeychain"); pubRing.encodeArmored(out, "OpenKeychain"); - Iterator it = + IteratorWithIOThrow it = UncachedKeyRing.fromStream(new ByteArrayInputStream(out.toByteArray())); Assert.assertTrue("there should be two rings in the stream", it.hasNext()); Assert.assertArrayEquals("first ring should be the first we put in", @@ -139,11 +140,7 @@ public class UncachedKeyringTest { } UncachedKeyRing readRingFromResource(String name) throws Throwable { - try { - return UncachedKeyRing.fromStream(UncachedKeyringTest.class.getResourceAsStream(name)).next(); - } catch (RuntimeException e) { - throw e.getCause(); - } + return UncachedKeyRing.fromStream(UncachedKeyringTest.class.getResourceAsStream(name)).next(); } } -- cgit v1.2.3 From 9cf800bcd8870961acc1719fc56f5e8dab21d0a3 Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Fri, 2 Jan 2015 02:50:14 +0100 Subject: tests: add multiple keys with signature test case --- .../keychain/pgp/PgpEncryptDecryptTest.java | 75 ++++++++++++++++++++++ 1 file changed, 75 insertions(+) (limited to 'OpenKeychain-Test/src') 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 8d0c4ab80..d03375a61 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 @@ -22,6 +22,7 @@ import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; import org.junit.runner.RunWith; +import org.openintents.openpgp.OpenPgpSignatureResult; import org.robolectric.*; import org.robolectric.shadows.ShadowLog; import org.spongycastle.bcpg.sig.KeyFlags; @@ -36,6 +37,7 @@ 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.support.KeyringTestingHelper; import org.sufficientlysecure.keychain.util.InputData; import org.sufficientlysecure.keychain.util.ProgressScaler; import org.sufficientlysecure.keychain.util.TestingUtils; @@ -363,6 +365,79 @@ public class PgpEncryptDecryptTest { } + @Test + public void testMultiAsymmetricSignEncryptDecryptVerify() { + + String plaintext = "dies ist ein plaintext ☭" + TestingUtils.genPassphrase(true); + byte[] ciphertext; + + { // encrypt data with a given passphrase + ByteArrayOutputStream out = new ByteArrayOutputStream(); + ByteArrayInputStream in = new ByteArrayInputStream(plaintext.getBytes()); + + InputData data = new InputData(in, in.available()); + Builder b = new PgpSignEncrypt.Builder( + Robolectric.application, + new ProviderHelper(Robolectric.application), + null, // new DummyPassphraseCache(mPassphrase, 0L), + data, out); + + b.setEncryptionMasterKeyIds(new long[] { + mStaticRing1.getMasterKeyId(), + mStaticRing2.getMasterKeyId() + }); + b.setSignatureMasterKeyId(mStaticRing1.getMasterKeyId()); + b.setSignatureSubKeyId(KeyringTestingHelper.getSubkeyId(mStaticRing1, 1)); + b.setSignaturePassphrase(mKeyPhrase1); + b.setSymmetricEncryptionAlgorithm(PGPEncryptedData.AES_128); + SignEncryptResult result = b.build().execute(); + Assert.assertTrue("encryption must succeed", result.success()); + + ciphertext = out.toByteArray(); + } + + { // decryption with passphrase cached should succeed for the first key + + ByteArrayOutputStream out = new ByteArrayOutputStream(); + ByteArrayInputStream in = new ByteArrayInputStream(ciphertext); + InputData data = new InputData(in, in.available()); + + PgpDecryptVerify.Builder b = builderWithFakePassphraseCache(data, out, + mKeyPhrase1, mStaticRing1.getMasterKeyId(), null); + + DecryptVerifyResult result = b.build().execute(); + Assert.assertTrue("decryption with cached passphrase must succeed for the first key", result.success()); + Assert.assertArrayEquals("decrypted ciphertext with cached passphrase should equal plaintext", + out.toByteArray(), plaintext.getBytes()); + Assert.assertEquals("signature should be verified and certified", + OpenPgpSignatureResult.SIGNATURE_SUCCESS_CERTIFIED, result.getSignatureResult().getStatus()); + } + + { // decryption with passphrase cached should succeed for the other key if first is gone + + // delete first key from database + new ProviderHelper(Robolectric.application).getContentResolver().delete( + KeyRingData.buildPublicKeyRingUri(mStaticRing1.getMasterKeyId()), null, null + ); + + ByteArrayOutputStream out = new ByteArrayOutputStream(); + ByteArrayInputStream in = new ByteArrayInputStream(ciphertext); + InputData data = new InputData(in, in.available()); + + PgpDecryptVerify.Builder b = builderWithFakePassphraseCache(data, out, + mKeyPhrase2, mStaticRing2.getMasterKeyId(), null); + + DecryptVerifyResult result = b.build().execute(); + Assert.assertTrue("decryption with cached passphrase must succeed", result.success()); + Assert.assertArrayEquals("decrypted ciphertext with cached passphrase should equal plaintext", + out.toByteArray(), plaintext.getBytes()); + Assert.assertEquals("signature key should be missing", + OpenPgpSignatureResult.SIGNATURE_KEY_MISSING, + result.getSignatureResult().getStatus()); + } + + } + private PgpDecryptVerify.Builder builderWithFakePassphraseCache ( InputData data, OutputStream out, final String passphrase, final Long checkMasterKeyId, final Long checkSubKeyId) { -- cgit v1.2.3 From 320f7d35efb059b99b31506426554e9a8f138d8f Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Sat, 3 Jan 2015 13:55:06 +0100 Subject: encapsulate high level edit key into new operation class --- .../keychain/operations/ExportTest.java | 7 +++---- .../keychain/pgp/PgpEncryptDecryptTest.java | 6 +++--- .../keychain/pgp/PgpKeyOperationTest.java | 18 +++++++++--------- .../keychain/pgp/UncachedKeyringCanonicalizeTest.java | 4 ++-- .../keychain/pgp/UncachedKeyringMergeTest.java | 6 +++--- .../keychain/pgp/UncachedKeyringTest.java | 4 ++-- 6 files changed, 22 insertions(+), 23 deletions(-) (limited to 'OpenKeychain-Test/src') diff --git a/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/operations/ExportTest.java b/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/operations/ExportTest.java index 4470ef411..b6fdbfc6c 100644 --- a/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/operations/ExportTest.java +++ b/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/operations/ExportTest.java @@ -27,10 +27,9 @@ import org.robolectric.RobolectricTestRunner; import org.robolectric.shadows.ShadowLog; import org.spongycastle.bcpg.sig.KeyFlags; import org.spongycastle.jce.provider.BouncyCastleProvider; -import org.sufficientlysecure.keychain.operations.results.EditKeyResult; +import org.sufficientlysecure.keychain.operations.results.PgpEditKeyResult; import org.sufficientlysecure.keychain.operations.results.ExportResult; import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog; -import org.sufficientlysecure.keychain.pgp.CanonicalizedPublicKeyRing; import org.sufficientlysecure.keychain.pgp.PgpKeyOperation; import org.sufficientlysecure.keychain.pgp.UncachedKeyRing; import org.sufficientlysecure.keychain.pgp.UncachedKeyRing.IteratorWithIOThrow; @@ -79,7 +78,7 @@ public class ExportTest { parcel.mAddUserIds.add("snips"); parcel.mNewUnlock = new ChangeUnlockParcel(mKeyPhrase1); - 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()); @@ -97,7 +96,7 @@ public class ExportTest { parcel.mAddUserIds.add("snails"); parcel.mNewUnlock = new ChangeUnlockParcel(null, "1234"); - 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()); 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 d03375a61..008edcda4 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 @@ -28,13 +28,13 @@ import org.robolectric.shadows.ShadowLog; import org.spongycastle.bcpg.sig.KeyFlags; import org.spongycastle.jce.provider.BouncyCastleProvider; import org.spongycastle.openpgp.PGPEncryptedData; +import org.sufficientlysecure.keychain.operations.results.PgpEditKeyResult; import org.sufficientlysecure.keychain.pgp.PgpSignEncrypt.Builder; import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRingData; import org.sufficientlysecure.keychain.provider.ProviderHelper; import org.sufficientlysecure.keychain.service.SaveKeyringParcel; 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.support.KeyringTestingHelper; @@ -80,7 +80,7 @@ public class PgpEncryptDecryptTest { parcel.mAddUserIds.add("bloom"); parcel.mNewUnlock = new ChangeUnlockParcel(mKeyPhrase1); - 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()); @@ -98,7 +98,7 @@ public class PgpEncryptDecryptTest { parcel.mAddUserIds.add("belle"); parcel.mNewUnlock = new ChangeUnlockParcel(mKeyPhrase2); - 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()); 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 103e2dc88..52115a76d 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 @@ -40,7 +40,7 @@ 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; @@ -96,7 +96,7 @@ public class PgpKeyOperationTest { 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()); @@ -962,7 +962,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()); @@ -978,7 +978,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)); @@ -1056,7 +1056,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); @@ -1113,7 +1113,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()); @@ -1127,7 +1127,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()); @@ -1141,7 +1141,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()); @@ -1152,7 +1152,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()); 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 b3a149eec..721d1a51d 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 @@ -53,7 +53,7 @@ import org.spongycastle.openpgp.operator.jcajce.JcePBESecretKeyEncryptorBuilder; import org.spongycastle.util.Strings; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.operations.results.OperationResult; -import org.sufficientlysecure.keychain.operations.results.EditKeyResult; +import org.sufficientlysecure.keychain.operations.results.PgpEditKeyResult; import org.sufficientlysecure.keychain.service.SaveKeyringParcel; import org.sufficientlysecure.keychain.service.SaveKeyringParcel.Algorithm; import org.sufficientlysecure.keychain.operations.results.OperationResult.LogType; @@ -108,7 +108,7 @@ public class UncachedKeyringCanonicalizeTest { parcel.mNewUnlock = new ChangeUnlockParcel(""); 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()); staticRing = result.getRing(); Assert.assertNotNull("initial test key creation must succeed", staticRing); 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 7e2cbee0c..7f6f480d4 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,7 +33,7 @@ import org.spongycastle.bcpg.sig.KeyFlags; import org.spongycastle.jce.provider.BouncyCastleProvider; import org.spongycastle.util.Strings; import org.sufficientlysecure.keychain.operations.results.OperationResult; -import org.sufficientlysecure.keychain.operations.results.EditKeyResult; +import org.sufficientlysecure.keychain.operations.results.PgpEditKeyResult; import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog; import org.sufficientlysecure.keychain.service.SaveKeyringParcel; import org.sufficientlysecure.keychain.service.SaveKeyringParcel.Algorithm; @@ -103,7 +103,7 @@ public class UncachedKeyringMergeTest { OperationResult.OperationLog log = new OperationResult.OperationLog(); - EditKeyResult result = op.createSecretKeyRing(parcel); + PgpEditKeyResult result = op.createSecretKeyRing(parcel); staticRingA = result.getRing(); staticRingA = staticRingA.canonicalize(new OperationLog(), 0).getUncachedKeyRing(); } @@ -119,7 +119,7 @@ public class UncachedKeyringMergeTest { PgpKeyOperation op = new PgpKeyOperation(null); OperationResult.OperationLog log = new OperationResult.OperationLog(); - EditKeyResult result = op.createSecretKeyRing(parcel); + PgpEditKeyResult result = op.createSecretKeyRing(parcel); staticRingB = result.getRing(); staticRingB = staticRingB.canonicalize(new OperationLog(), 0).getUncachedKeyRing(); } 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 e5c00221b..a3c58a5c8 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 @@ -26,7 +26,7 @@ import org.junit.runner.RunWith; import org.robolectric.RobolectricTestRunner; import org.robolectric.shadows.ShadowLog; import org.spongycastle.bcpg.sig.KeyFlags; -import org.sufficientlysecure.keychain.operations.results.EditKeyResult; +import org.sufficientlysecure.keychain.operations.results.PgpEditKeyResult; import org.sufficientlysecure.keychain.pgp.UncachedKeyRing.IteratorWithIOThrow; import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException; import org.sufficientlysecure.keychain.service.SaveKeyringParcel; @@ -63,7 +63,7 @@ public class UncachedKeyringTest { parcel.mNewUnlock = new ChangeUnlockParcel(""); PgpKeyOperation op = new PgpKeyOperation(null); - EditKeyResult result = op.createSecretKeyRing(parcel); + PgpEditKeyResult result = op.createSecretKeyRing(parcel); staticRing = result.getRing(); staticPubRing = staticRing.extractPublicKeyRing(); -- cgit v1.2.3 From 0c3f9ae0a67cb98b2ac3ac59985aec03e6a15861 Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Sat, 3 Jan 2015 23:02:11 +0100 Subject: tests: add a couple of CertifyOperation test cases --- .../keychain/operations/CertifyOperationTest.java | 238 +++++++++++++++++++++ 1 file changed, 238 insertions(+) create mode 100644 OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/operations/CertifyOperationTest.java (limited to 'OpenKeychain-Test/src') diff --git a/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/operations/CertifyOperationTest.java b/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/operations/CertifyOperationTest.java new file mode 100644 index 000000000..c05f4a029 --- /dev/null +++ b/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/operations/CertifyOperationTest.java @@ -0,0 +1,238 @@ +/* + * 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 + * 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.operations; + +import org.junit.Assert; +import org.junit.Before; +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.spongycastle.bcpg.sig.KeyFlags; +import org.spongycastle.jce.provider.BouncyCastleProvider; +import org.sufficientlysecure.keychain.operations.results.CertifyResult; +import org.sufficientlysecure.keychain.operations.results.OperationResult.LogType; +import org.sufficientlysecure.keychain.operations.results.PgpEditKeyResult; +import org.sufficientlysecure.keychain.operations.results.ExportResult; +import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog; +import org.sufficientlysecure.keychain.pgp.CanonicalizedPublicKeyRing; +import org.sufficientlysecure.keychain.pgp.PgpDecryptVerify; +import org.sufficientlysecure.keychain.pgp.PgpKeyOperation; +import org.sufficientlysecure.keychain.pgp.UncachedKeyRing; +import org.sufficientlysecure.keychain.pgp.UncachedKeyRing.IteratorWithIOThrow; +import org.sufficientlysecure.keychain.pgp.WrappedSignature; +import org.sufficientlysecure.keychain.provider.KeychainContract.Certs; +import org.sufficientlysecure.keychain.provider.ProviderHelper; +import org.sufficientlysecure.keychain.service.CertifyActionsParcel; +import org.sufficientlysecure.keychain.service.CertifyActionsParcel.CertifyAction; +import org.sufficientlysecure.keychain.service.SaveKeyringParcel; +import org.sufficientlysecure.keychain.service.SaveKeyringParcel.Algorithm; +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; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.OutputStream; +import java.io.PrintStream; +import java.security.Security; +import java.util.Iterator; + +@RunWith(RobolectricTestRunner.class) +@org.robolectric.annotation.Config(emulateSdk = 18) // Robolectric doesn't yet support 19 +public class CertifyOperationTest { + + static String mPassphrase = TestingUtils.genPassphrase(true); + + static UncachedKeyRing mStaticRing1, mStaticRing2; + static String mKeyPhrase1 = TestingUtils.genPassphrase(true); + static String mKeyPhrase2 = TestingUtils.genPassphrase(true); + + static PrintStream oldShadowStream; + + @BeforeClass + public static void setUpOnce() throws Exception { + Security.insertProviderAt(new BouncyCastleProvider(), 1); + oldShadowStream = ShadowLog.stream; + // ShadowLog.stream = System.out; + + PgpKeyOperation op = new PgpKeyOperation(null); + + { + SaveKeyringParcel parcel = new SaveKeyringParcel(); + parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( + Algorithm.RSA, 1024, null, KeyFlags.CERTIFY_OTHER, 0L)); + parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( + Algorithm.DSA, 1024, null, KeyFlags.SIGN_DATA, 0L)); + parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( + Algorithm.ELGAMAL, 1024, null, KeyFlags.ENCRYPT_COMMS, 0L)); + parcel.mAddUserIds.add("derp"); + parcel.mNewUnlock = new ChangeUnlockParcel(mKeyPhrase1); + + 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()); + + mStaticRing1 = result.getRing(); + } + + { + SaveKeyringParcel parcel = new SaveKeyringParcel(); + parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( + Algorithm.RSA, 1024, null, KeyFlags.CERTIFY_OTHER, 0L)); + parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( + Algorithm.DSA, 1024, null, KeyFlags.SIGN_DATA, 0L)); + parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( + Algorithm.ELGAMAL, 1024, null, KeyFlags.ENCRYPT_COMMS, 0L)); + parcel.mAddUserIds.add("ditz"); + parcel.mNewUnlock = new ChangeUnlockParcel(null, "1234"); + + 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()); + + mStaticRing2 = result.getRing(); + } + + } + + @Before + public void setUp() throws Exception { + ProviderHelper providerHelper = new ProviderHelper(Robolectric.application); + + // don't log verbosely here, we're not here to test imports + ShadowLog.stream = oldShadowStream; + + providerHelper.saveSecretKeyRing(mStaticRing1, new ProgressScaler()); + providerHelper.savePublicKeyRing(mStaticRing2.extractPublicKeyRing(), new ProgressScaler()); + + // ok NOW log verbosely! + ShadowLog.stream = System.out; + } + + @Test + public void testSelfCertifyFlag() throws Exception { + + CanonicalizedPublicKeyRing ring = new ProviderHelper(Robolectric.application) + .getCanonicalizedPublicKeyRing(mStaticRing1.getMasterKeyId()); + Assert.assertEquals("secret key must be marked self-certified in database", + // TODO this should be more correctly be VERIFIED_SELF at some point! + Certs.VERIFIED_SECRET, ring.getVerified()); + + } + + @Test + public void testCertify() throws Exception { + CertifyOperation op = operationWithFakePassphraseCache( + mStaticRing1.getMasterKeyId(), mStaticRing1.getMasterKeyId(), mKeyPhrase1); + + { + CanonicalizedPublicKeyRing ring = new ProviderHelper(Robolectric.application) + .getCanonicalizedPublicKeyRing(mStaticRing2.getMasterKeyId()); + Assert.assertEquals("public key must not be marked verified prior to certification", + Certs.UNVERIFIED, ring.getVerified()); + } + + CertifyActionsParcel actions = new CertifyActionsParcel(mStaticRing1.getMasterKeyId()); + actions.add(new CertifyAction(mStaticRing2.getMasterKeyId())); + CertifyResult result = op.certify(actions, null); + + Assert.assertTrue("certification must succeed", result.success()); + + { + CanonicalizedPublicKeyRing ring = new ProviderHelper(Robolectric.application) + .getCanonicalizedPublicKeyRing(mStaticRing2.getMasterKeyId()); + Assert.assertEquals("new key must be verified now", + Certs.VERIFIED_SECRET, ring.getVerified()); + } + + } + + @Test + public void testCertifySelf() throws Exception { + CertifyOperation op = operationWithFakePassphraseCache( + mStaticRing1.getMasterKeyId(), mStaticRing1.getMasterKeyId(), mKeyPhrase1); + + CertifyActionsParcel actions = new CertifyActionsParcel(mStaticRing1.getMasterKeyId()); + actions.add(new CertifyAction(mStaticRing1.getMasterKeyId())); + + CertifyResult result = op.certify(actions, null); + + Assert.assertFalse("certification with itself must fail!", result.success()); + Assert.assertTrue("error msg must be about self certification", + result.getLog().containsType(LogType.MSG_CRT_ERROR_SELF)); + } + + @Test + public void testCertifyNonexistent() throws Exception { + + CertifyOperation op = operationWithFakePassphraseCache(null, null, mKeyPhrase1); + + { + CertifyActionsParcel actions = new CertifyActionsParcel(mStaticRing1.getMasterKeyId()); + actions.add(new CertifyAction(1234L)); + + CertifyResult result = op.certify(actions, null); + + Assert.assertFalse("certification of nonexistent key must fail", result.success()); + Assert.assertTrue("must contain error msg about not found", + result.getLog().containsType(LogType.MSG_CRT_WARN_NOT_FOUND)); + } + + { + CertifyActionsParcel actions = new CertifyActionsParcel(1234L); + actions.add(new CertifyAction(mStaticRing1.getMasterKeyId())); + + CertifyResult result = op.certify(actions, null); + + Assert.assertFalse("certification of nonexistent key must fail", result.success()); + Assert.assertTrue("must contain error msg about not found", + result.getLog().containsType(LogType.MSG_CRT_ERROR_MASTER_NOT_FOUND)); + } + + } + + private CertifyOperation operationWithFakePassphraseCache( + final Long checkMasterKeyId, final Long checkSubKeyId, final String passphrase) { + + return new CertifyOperation(Robolectric.application, + new ProviderHelper(Robolectric.application), + null, null) { + @Override + public String getCachedPassphrase(long masterKeyId, long subKeyId) + throws NoSecretKeyException { + if (checkMasterKeyId != null) { + Assert.assertEquals("requested passphrase should be for expected master key id", + (long) checkMasterKeyId, masterKeyId); + } + if (checkSubKeyId != null) { + Assert.assertEquals("requested passphrase should be for expected sub key id", + (long) checkSubKeyId, subKeyId); + } + if (passphrase == null) { + return null; + } + return passphrase; + } + }; + } + +} -- cgit v1.2.3