add diffKeyrings method

This commit is contained in:
Vincent Breitmoser 2014-07-07 18:30:08 +02:00 committed by Art O Cathain
parent 4fbffd7bb4
commit 83e5a3d341

View File

@ -2,12 +2,18 @@ package org.sufficientlysecure.keychain.testsupport;
import android.content.Context; import android.content.Context;
import org.spongycastle.util.Arrays;
import org.sufficientlysecure.keychain.pgp.NullProgressable; import org.sufficientlysecure.keychain.pgp.NullProgressable;
import org.sufficientlysecure.keychain.pgp.UncachedKeyRing; import org.sufficientlysecure.keychain.pgp.UncachedKeyRing;
import org.sufficientlysecure.keychain.provider.ProviderHelper; import org.sufficientlysecure.keychain.provider.ProviderHelper;
import org.sufficientlysecure.keychain.service.OperationResults; import org.sufficientlysecure.keychain.service.OperationResults;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Collection; import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
/** /**
* Helper for tests of the Keyring import in ProviderHelper. * Helper for tests of the Keyring import in ProviderHelper.
@ -44,6 +50,132 @@ public class KeyringTestingHelper {
return saveSuccess; return saveSuccess;
} }
public static class Packet {
int tag;
int length;
byte[] buf;
public boolean equals(Object other) {
return other instanceof Packet && Arrays.areEqual(this.buf, ((Packet) other).buf);
}
public int hashCode() {
System.out.println("tag: " + tag + ", code: " + Arrays.hashCode(buf));
return Arrays.hashCode(buf);
}
}
public static boolean diffKeyrings(byte[] ringA, byte[] ringB, Set<Packet> onlyA, Set<Packet> onlyB)
throws IOException {
InputStream streamA = new ByteArrayInputStream(ringA);
InputStream streamB = new ByteArrayInputStream(ringB);
HashSet<Packet> a = new HashSet<Packet>(), b = new HashSet<Packet>();
Packet p;
while(true) {
p = readPacket(streamA);
if (p == null) {
break;
}
a.add(p);
}
while(true) {
p = readPacket(streamB);
if (p == null) {
break;
}
b.add(p);
}
onlyA.addAll(a);
onlyA.removeAll(b);
onlyB.addAll(b);
onlyB.removeAll(a);
return onlyA.isEmpty() && onlyB.isEmpty();
}
private static Packet readPacket(InputStream in) throws IOException {
// save here. this is tag + length, max 6 bytes
in.mark(6);
int hdr = in.read();
int headerLength = 1;
if (hdr < 0) {
return null;
}
if ((hdr & 0x80) == 0) {
throw new IOException("invalid header encountered");
}
boolean newPacket = (hdr & 0x40) != 0;
int tag = 0;
int bodyLen = 0;
if (newPacket) {
tag = hdr & 0x3f;
int l = in.read();
headerLength += 1;
if (l < 192) {
bodyLen = l;
} else if (l <= 223) {
int b = in.read();
headerLength += 1;
bodyLen = ((l - 192) << 8) + (b) + 192;
} else if (l == 255) {
bodyLen = (in.read() << 24) | (in.read() << 16) | (in.read() << 8) | in.read();
headerLength += 4;
} else {
// bodyLen = 1 << (l & 0x1f);
throw new IOException("no support for partial bodies in test classes");
}
} else {
int lengthType = hdr & 0x3;
tag = (hdr & 0x3f) >> 2;
switch (lengthType) {
case 0:
bodyLen = in.read();
headerLength += 1;
break;
case 1:
bodyLen = (in.read() << 8) | in.read();
headerLength += 2;
break;
case 2:
bodyLen = (in.read() << 24) | (in.read() << 16) | (in.read() << 8) | in.read();
headerLength += 4;
break;
case 3:
// bodyLen = 1 << (l & 0x1f);
throw new IOException("no support for partial bodies in test classes");
default:
throw new IOException("unknown length type encountered");
}
}
in.reset();
// read the entire packet INCLUDING the header here
byte[] buf = new byte[headerLength+bodyLen];
if (in.read(buf) != headerLength+bodyLen) {
throw new IOException("read length mismatch!");
}
Packet p = new Packet();
p.tag = tag;
p.length = bodyLen;
p.buf = buf;
return p;
}
private void retrieveKeyAndExpectNotFound(ProviderHelper providerHelper, long masterKeyId) { private void retrieveKeyAndExpectNotFound(ProviderHelper providerHelper, long masterKeyId) {
try { try {
@ -53,4 +185,5 @@ public class KeyringTestingHelper {
// good // good
} }
} }
} }