mirror of
https://github.com/moparisthebest/open-keychain
synced 2025-02-07 10:30:14 -05:00
test: start with UncachedKeyRing.canonicalize tests
This commit is contained in:
parent
19dc49153d
commit
299570f1b9
@ -21,6 +21,7 @@ import android.content.Context;
|
||||
import org.spongycastle.util.Arrays;
|
||||
import org.sufficientlysecure.keychain.pgp.NullProgressable;
|
||||
import org.sufficientlysecure.keychain.pgp.UncachedKeyRing;
|
||||
import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
|
||||
import org.sufficientlysecure.keychain.provider.ProviderHelper;
|
||||
import org.sufficientlysecure.keychain.service.OperationResults;
|
||||
|
||||
@ -68,6 +69,11 @@ public class KeyringTestingHelper {
|
||||
return saveSuccess;
|
||||
}
|
||||
|
||||
public static UncachedKeyRing removePacket(UncachedKeyRing ring, int position)
|
||||
throws IOException, PgpGeneralException {
|
||||
return UncachedKeyRing.decodeFromData(removePacket(ring.getEncoded(), position));
|
||||
}
|
||||
|
||||
public static byte[] removePacket(byte[] ring, int position) throws IOException {
|
||||
Iterator<RawPacket> it = parseKeyring(ring);
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream(ring.length);
|
||||
@ -76,6 +82,7 @@ public class KeyringTestingHelper {
|
||||
while(it.hasNext()) {
|
||||
// at the right position, skip the packet
|
||||
if(i++ == position) {
|
||||
it.next();
|
||||
continue;
|
||||
}
|
||||
// write the old one
|
||||
@ -89,6 +96,11 @@ public class KeyringTestingHelper {
|
||||
return out.toByteArray();
|
||||
}
|
||||
|
||||
public static UncachedKeyRing injectPacket(UncachedKeyRing ring, byte[] inject, int position)
|
||||
throws IOException, PgpGeneralException {
|
||||
return UncachedKeyRing.decodeFromData(injectPacket(ring.getEncoded(), inject, position));
|
||||
}
|
||||
|
||||
public static byte[] injectPacket(byte[] ring, byte[] inject, int position) throws IOException {
|
||||
|
||||
Iterator<RawPacket> it = parseKeyring(ring);
|
||||
|
@ -31,6 +31,7 @@ import java.util.Iterator;
|
||||
public class UncachedKeyringTest {
|
||||
|
||||
static UncachedKeyRing staticRing;
|
||||
static int totalPackets;
|
||||
UncachedKeyRing ring;
|
||||
ArrayList<RawPacket> onlyA = new ArrayList<RawPacket>();
|
||||
ArrayList<RawPacket> onlyB = new ArrayList<RawPacket>();
|
||||
@ -59,6 +60,9 @@ public class UncachedKeyringTest {
|
||||
|
||||
Assert.assertNotNull("initial test key creation must succeed", staticRing);
|
||||
|
||||
// just for later reference
|
||||
totalPackets = 9;
|
||||
|
||||
// we sleep here for a second, to make sure all new certificates have different timestamps
|
||||
Thread.sleep(1000);
|
||||
}
|
||||
@ -76,24 +80,24 @@ public class UncachedKeyringTest {
|
||||
Assert.assertEquals("packet #1 should be secret key",
|
||||
PacketTags.SECRET_KEY, it.next().tag);
|
||||
|
||||
Assert.assertEquals("packet #2 should be secret key",
|
||||
Assert.assertEquals("packet #2 should be user id",
|
||||
PacketTags.USER_ID, it.next().tag);
|
||||
Assert.assertEquals("packet #3 should be secret key",
|
||||
Assert.assertEquals("packet #3 should be signature",
|
||||
PacketTags.SIGNATURE, it.next().tag);
|
||||
|
||||
Assert.assertEquals("packet #4 should be secret key",
|
||||
Assert.assertEquals("packet #4 should be user id",
|
||||
PacketTags.USER_ID, it.next().tag);
|
||||
Assert.assertEquals("packet #5 should be secret key",
|
||||
Assert.assertEquals("packet #5 should be signature",
|
||||
PacketTags.SIGNATURE, it.next().tag);
|
||||
|
||||
Assert.assertEquals("packet #6 should be secret key",
|
||||
Assert.assertEquals("packet #6 should be secret subkey",
|
||||
PacketTags.SECRET_SUBKEY, it.next().tag);
|
||||
Assert.assertEquals("packet #7 should be secret key",
|
||||
Assert.assertEquals("packet #7 should be signature",
|
||||
PacketTags.SIGNATURE, it.next().tag);
|
||||
|
||||
Assert.assertEquals("packet #8 should be secret key",
|
||||
Assert.assertEquals("packet #8 should be secret subkey",
|
||||
PacketTags.SECRET_SUBKEY, it.next().tag);
|
||||
Assert.assertEquals("packet #9 should be secret key",
|
||||
Assert.assertEquals("packet #9 should be signature",
|
||||
PacketTags.SIGNATURE, it.next().tag);
|
||||
|
||||
Assert.assertFalse("exactly 9 packets total", it.hasNext());
|
||||
@ -103,4 +107,107 @@ public class UncachedKeyringTest {
|
||||
|
||||
}
|
||||
|
||||
@Test public void testBrokenSignature() throws Exception {
|
||||
|
||||
byte[] brokenSig;
|
||||
{
|
||||
UncachedPublicKey masterKey = ring.getPublicKey();
|
||||
WrappedSignature sig = masterKey.getSignaturesForId("twi").next();
|
||||
brokenSig = sig.getEncoded();
|
||||
// break the signature
|
||||
brokenSig[brokenSig.length - 5] += 1;
|
||||
}
|
||||
|
||||
byte[] reng = ring.getEncoded();
|
||||
for(int i = 0; i < totalPackets; i++) {
|
||||
|
||||
byte[] brokenBytes = KeyringTestingHelper.injectPacket(reng, brokenSig, i);
|
||||
Assert.assertEquals("broken ring must be original + injected size",
|
||||
reng.length + brokenSig.length, brokenBytes.length);
|
||||
|
||||
try {
|
||||
UncachedKeyRing brokenRing = UncachedKeyRing.decodeFromData(brokenBytes);
|
||||
|
||||
brokenRing = brokenRing.canonicalize(log, 0);
|
||||
if (brokenRing == null) {
|
||||
System.out.println("ok, canonicalization failed.");
|
||||
continue;
|
||||
}
|
||||
|
||||
Assert.assertArrayEquals("injected bad signature must be gone after canonicalization",
|
||||
ring.getEncoded(), brokenRing.getEncoded());
|
||||
|
||||
} catch (Exception e) {
|
||||
System.out.println("ok, rejected with: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Test public void testUidSignature() throws Exception {
|
||||
|
||||
UncachedPublicKey masterKey = ring.getPublicKey();
|
||||
final WrappedSignature sig = masterKey.getSignaturesForId("twi").next();
|
||||
|
||||
byte[] raw = sig.getEncoded();
|
||||
// destroy the signature
|
||||
raw[raw.length - 5] += 1;
|
||||
final WrappedSignature brokenSig = WrappedSignature.fromBytes(raw);
|
||||
|
||||
{ // bad certificates get stripped
|
||||
UncachedKeyRing modified = KeyringTestingHelper.injectPacket(ring, brokenSig.getEncoded(), 3);
|
||||
modified = modified.canonicalize(log, 0);
|
||||
|
||||
Assert.assertTrue("canonicalized keyring with invalid extra sig must be same as original one",
|
||||
!KeyringTestingHelper.diffKeyrings(
|
||||
ring.getEncoded(), modified.getEncoded(), onlyA, onlyB));
|
||||
}
|
||||
|
||||
// remove user id certificate for one user
|
||||
final UncachedKeyRing base = KeyringTestingHelper.removePacket(ring, 2);
|
||||
|
||||
{ // user id without certificate should be removed
|
||||
UncachedKeyRing modified = base.canonicalize(log, 0);
|
||||
Assert.assertTrue("canonicalized keyring must differ", KeyringTestingHelper.diffKeyrings(
|
||||
ring.getEncoded(), modified.getEncoded(), onlyA, onlyB));
|
||||
|
||||
Assert.assertEquals("two packets should be stripped after canonicalization", 2, onlyA.size());
|
||||
Assert.assertEquals("no new packets after canonicalization", 0, onlyB.size());
|
||||
|
||||
Packet p;
|
||||
p = new BCPGInputStream(new ByteArrayInputStream(onlyA.get(0).buf)).readPacket();
|
||||
Assert.assertTrue("first stripped packet must be user id", p instanceof UserIDPacket);
|
||||
Assert.assertEquals("missing user id must be the expected one",
|
||||
"twi", ((UserIDPacket) p).getID());
|
||||
|
||||
p = new BCPGInputStream(new ByteArrayInputStream(onlyA.get(1).buf)).readPacket();
|
||||
Assert.assertArrayEquals("second stripped packet must be signature we removed",
|
||||
sig.getEncoded(), onlyA.get(1).buf);
|
||||
|
||||
}
|
||||
|
||||
{ // add error to signature
|
||||
|
||||
UncachedKeyRing modified = KeyringTestingHelper.injectPacket(base, brokenSig.getEncoded(), 3);
|
||||
modified = modified.canonicalize(log, 0);
|
||||
|
||||
Assert.assertTrue("canonicalized keyring must differ", KeyringTestingHelper.diffKeyrings(
|
||||
ring.getEncoded(), modified.getEncoded(), onlyA, onlyB));
|
||||
|
||||
Assert.assertEquals("two packets should be missing after canonicalization", 2, onlyA.size());
|
||||
Assert.assertEquals("no new packets after canonicalization", 0, onlyB.size());
|
||||
|
||||
Packet p;
|
||||
p = new BCPGInputStream(new ByteArrayInputStream(onlyA.get(0).buf)).readPacket();
|
||||
Assert.assertTrue("first stripped packet must be user id", p instanceof UserIDPacket);
|
||||
Assert.assertEquals("missing user id must be the expected one",
|
||||
"twi", ((UserIDPacket) p).getID());
|
||||
|
||||
p = new BCPGInputStream(new ByteArrayInputStream(onlyA.get(1).buf)).readPacket();
|
||||
Assert.assertArrayEquals("second stripped packet must be signature we removed",
|
||||
sig.getEncoded(), onlyA.get(1).buf);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user