do a TON of UI work

This commit is contained in:
Vincent Breitmoser
2015-03-05 01:58:36 +01:00
parent 8222315dbd
commit 1f324be243
27 changed files with 674 additions and 248 deletions

View File

@@ -114,6 +114,15 @@ public class WrappedUserAttribute implements Serializable {
}
public byte[][] getSubpackets() {
UserAttributeSubpacket[] subpackets = mVector.toSubpacketArray();
byte[][] ret = new byte[subpackets.length][];
for (int i = 0; i < subpackets.length; i++) {
ret[i] = subpackets[i].getData();
}
return ret;
}
private void readObjectNoData() throws ObjectStreamException {
}

View File

@@ -19,27 +19,10 @@ import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public abstract class LinkedCookieResource {
protected final URI mSubUri;
protected final Set<String> mFlags;
protected final HashMap<String,String> mParams;
static Pattern magicPattern =
Pattern.compile("\\[Verifying my PGP key: openpgp4fpr:([a-zA-Z0-9]+)#([a-zA-Z0-9]+)\\]");
public abstract class LinkedCookieResource extends LinkedResource {
protected LinkedCookieResource(Set<String> flags, HashMap<String, String> params, URI uri) {
mFlags = flags;
mParams = params;
mSubUri = uri;
}
public Set<String> getFlags () {
return new HashSet<String>(mFlags);
}
public HashMap<String,String> getParams () {
return new HashMap<String,String>(mParams);
super(flags, params, uri);
}
public URI toUri () {
@@ -82,10 +65,10 @@ public abstract class LinkedCookieResource {
return mSubUri;
}
public static String generate (Context context, byte[] fingerprint, String nonce) {
public static String generate (Context context, byte[] fingerprint, int nonce) {
return "[Verifying my PGP key: openpgp4fpr:"
+ KeyFormattingUtils.convertFingerprintToHex(fingerprint) + "#" + nonce + "]";
+ KeyFormattingUtils.convertFingerprintToHex(fingerprint) + "#" + Integer.toHexString(nonce) + "]";
}
@@ -129,7 +112,17 @@ public abstract class LinkedCookieResource {
}
String candidateFp = match.group(1).toLowerCase();
int nonceCandidate = Integer.parseInt(match.group(2).toLowerCase(), 16);
try {
int nonceCandidate = Integer.parseInt(match.group(2).toLowerCase(), 16);
if (nonce != nonceCandidate) {
log.add(LogType.MSG_LV_NONCE_ERROR, indent);
return new LinkedVerifyResult(LinkedVerifyResult.RESULT_ERROR, log);
}
} catch (NumberFormatException e) {
log.add(LogType.MSG_LV_NONCE_ERROR, indent);
return new LinkedVerifyResult(LinkedVerifyResult.RESULT_ERROR, log);
}
String fp = KeyFormattingUtils.convertFingerprintToHex(fingerprint);
@@ -139,72 +132,9 @@ public abstract class LinkedCookieResource {
}
log.add(LogType.MSG_LV_FP_OK, indent);
if (nonce != nonceCandidate) {
log.add(LogType.MSG_LV_NONCE_ERROR, indent);
return new LinkedVerifyResult(LinkedVerifyResult.RESULT_ERROR, log);
}
log.add(LogType.MSG_LV_NONCE_OK, indent);
return new LinkedVerifyResult(LinkedVerifyResult.RESULT_OK, log);
}
protected static LinkedCookieResource fromRawLinkedId (RawLinkedIdentity id) {
return fromUri(id.mNonce, id.mUri);
}
protected static LinkedCookieResource fromUri (int nonce, URI uri) {
if ("pgpid".equals(uri.getScheme())) {
Log.e(Constants.TAG, "unknown uri scheme in (suspected) linked id packet");
return null;
}
if (!uri.isOpaque()) {
Log.e(Constants.TAG, "non-opaque uri in (suspected) linked id packet");
return null;
}
String specific = uri.getSchemeSpecificPart();
if (!specific.contains("@")) {
Log.e(Constants.TAG, "unknown uri scheme in linked id packet");
return null;
}
String[] pieces = specific.split("@", 2);
URI subUri = URI.create(pieces[1]);
Set<String> flags = new HashSet<String>();
HashMap<String,String> params = new HashMap<String,String>();
{
String[] rawParams = pieces[0].split(";");
for (String param : rawParams) {
String[] p = param.split("=", 2);
if (p.length == 1) {
flags.add(param);
} else {
params.put(p[0], p[1]);
}
}
}
return findResourceType(nonce, flags, params, subUri);
}
protected static LinkedCookieResource findResourceType (int nonce, Set<String> flags,
HashMap<String,String> params,
URI subUri) {
LinkedCookieResource res;
res = GenericHttpsResource.create(flags, params, subUri);
if (res != null) {
return res;
}
return new UnknownResource(flags, params, subUri);
}
}

View File

@@ -0,0 +1,75 @@
package org.sufficientlysecure.keychain.pgp.linked;
import org.spongycastle.bcpg.UserAttributeSubpacket;
import org.spongycastle.util.Strings;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.pgp.WrappedUserAttribute;
import org.sufficientlysecure.keychain.util.Log;
import java.io.IOException;
import java.net.URI;
import java.nio.ByteBuffer;
import java.util.Arrays;
public class LinkedIdentity extends RawLinkedIdentity {
public final LinkedResource mResource;
protected LinkedIdentity(int nonce, URI uri, LinkedResource resource) {
super(nonce, uri);
if (resource == null) {
throw new AssertionError("resource must not be null in a LinkedIdentity!");
}
mResource = resource;
}
public static RawLinkedIdentity fromAttributeData(byte[] data) throws IOException {
WrappedUserAttribute att = WrappedUserAttribute.fromData(data);
byte[][] subpackets = att.getSubpackets();
if (subpackets.length >= 1) {
return fromSubpacketData(subpackets[0]);
}
throw new IOException("no subpacket data");
}
/** This method parses a linked id from a UserAttributeSubpacket, or returns null if the
* subpacket can not be parsed as a valid linked id.
*/
static RawLinkedIdentity fromAttributeSubpacket(UserAttributeSubpacket subpacket) {
if (subpacket.getType() != 100) {
return null;
}
byte[] data = subpacket.getData();
return fromSubpacketData(data);
}
static RawLinkedIdentity fromSubpacketData(byte[] data) {
try {
int nonce = ByteBuffer.wrap(data).getInt();
String uriStr = Strings.fromUTF8ByteArray(Arrays.copyOfRange(data, 4, data.length));
URI uri = URI.create(uriStr);
LinkedResource res = LinkedResource.fromUri(uri);
if (res == null) {
return new RawLinkedIdentity(nonce, uri);
}
return new LinkedIdentity(nonce, uri, res);
} catch (IllegalArgumentException e) {
Log.e(Constants.TAG, "error parsing uri in (suspected) linked id packet");
return null;
}
}
public static RawLinkedIdentity fromResource (LinkedCookieResource res, int nonce) {
return new RawLinkedIdentity(nonce, res.toUri());
}
}

View File

@@ -0,0 +1,101 @@
package org.sufficientlysecure.keychain.pgp.linked;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.pgp.linked.resources.DnsResource;
import org.sufficientlysecure.keychain.pgp.linked.resources.GenericHttpsResource;
import org.sufficientlysecure.keychain.pgp.linked.resources.UnknownResource;
import org.sufficientlysecure.keychain.util.Log;
import java.net.URI;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Set;
import java.util.regex.Pattern;
public abstract class LinkedResource {
protected final URI mSubUri;
protected final Set<String> mFlags;
protected final HashMap<String,String> mParams;
static Pattern magicPattern =
Pattern.compile("\\[Verifying my PGP key: openpgp4fpr:([a-zA-Z0-9]+)#([a-zA-Z0-9]+)\\]");
protected LinkedResource(Set<String> flags, HashMap<String, String> params, URI uri) {
mFlags = flags;
mParams = params;
mSubUri = uri;
}
public abstract URI toUri();
public Set<String> getFlags () {
return new HashSet<>(mFlags);
}
public HashMap<String,String> getParams () {
return new HashMap<>(mParams);
}
protected static LinkedCookieResource fromUri (URI uri) {
if ("pgpid+cookie".equals(uri.getScheme())) {
Log.e(Constants.TAG, "unknown uri scheme in (suspected) linked id packet");
return null;
}
if (!uri.isOpaque()) {
Log.e(Constants.TAG, "non-opaque uri in (suspected) linked id packet");
return null;
}
String specific = uri.getSchemeSpecificPart();
if (!specific.contains("@")) {
Log.e(Constants.TAG, "unknown uri scheme in linked id packet");
return null;
}
String[] pieces = specific.split("@", 2);
URI subUri = URI.create(pieces[1]);
Set<String> flags = new HashSet<String>();
HashMap<String,String> params = new HashMap<String,String>();
{
String[] rawParams = pieces[0].split(";");
for (String param : rawParams) {
String[] p = param.split("=", 2);
if ("".equals(p[0])) {
continue;
}
if (p.length == 1) {
flags.add(param);
} else {
params.put(p[0], p[1]);
}
}
}
return findResourceType(flags, params, subUri);
}
protected static LinkedCookieResource findResourceType (Set<String> flags,
HashMap<String,String> params,
URI subUri) {
LinkedCookieResource res;
res = GenericHttpsResource.create(flags, params, subUri);
if (res != null) {
return res;
}
res = DnsResource.create(flags, params, subUri);
if (res != null) {
return res;
}
return null;
}
}

View File

@@ -1,18 +1,10 @@
package org.sufficientlysecure.keychain.pgp.linked;
import org.spongycastle.bcpg.UserAttributeSubpacket;
import org.spongycastle.util.Strings;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.pgp.WrappedUserAttribute;
import org.sufficientlysecure.keychain.util.Log;
import java.net.URI;
import java.nio.ByteBuffer;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map.Entry;
import java.util.Set;
/** The RawLinkedIdentity contains raw parsed data from a Linked Identity subpacket. */
public class RawLinkedIdentity {
@@ -36,50 +28,18 @@ public class RawLinkedIdentity {
return buf.array();
}
/** This method parses a linked id from a UserAttributeSubpacket, or returns null if the
* subpacket can not be parsed as a valid linked id.
*/
static RawLinkedIdentity fromAttributeSubpacket(UserAttributeSubpacket subpacket) {
if (subpacket.getType() != 100) {
return null;
}
byte[] data = subpacket.getData();
return fromSubpacketData(data);
}
public static RawLinkedIdentity fromSubpacketData(byte[] data) {
try {
int nonce = ByteBuffer.wrap(data).getInt();
String uri = Strings.fromUTF8ByteArray(Arrays.copyOfRange(data, 4, data.length));
return new RawLinkedIdentity(nonce, URI.create(uri));
} catch (IllegalArgumentException e) {
Log.e(Constants.TAG, "error parsing uri in (suspected) linked id packet");
return null;
}
}
public static RawLinkedIdentity fromResource (LinkedCookieResource res, int nonce) {
return new RawLinkedIdentity(nonce, res.toUri());
}
public WrappedUserAttribute toUserAttribute () {
return WrappedUserAttribute.fromSubpacket(WrappedUserAttribute.UAT_LINKED_ID, getEncoded());
}
public static String generateNonce() {
public static int generateNonce() {
// TODO make this actually random
// byte[] data = new byte[4];
// new SecureRandom().nextBytes(data);
// return Hex.toHexString(data);
// debug for now
return "01234567";
return 1234567;
}
}

View File

@@ -39,10 +39,11 @@ public class DnsResource extends LinkedCookieResource {
mType = type;
}
public static String generateText (Context context, byte[] fingerprint, String nonce) {
public static String generateText (Context context, byte[] fingerprint, int nonce) {
return "pgpid+cookie="
+ KeyFormattingUtils.convertFingerprintToHex(fingerprint) + ";" + nonce + "";
+ KeyFormattingUtils.convertFingerprintToHex(fingerprint) + ";"
+ Integer.toHexString(nonce) + "";
}
@@ -81,6 +82,10 @@ public class DnsResource extends LinkedCookieResource {
return new DnsResource(flags, params, uri, fqdn, clazz, type);
}
public String getFqdn() {
return mFqdn;
}
@Override
protected String fetchResource (OperationLog log, int indent) {

View File

@@ -28,7 +28,7 @@ public class GenericHttpsResource extends LinkedCookieResource {
super(flags, params, uri);
}
public static String generateText (Context context, byte[] fingerprint, String nonce) {
public static String generateText (Context context, byte[] fingerprint, int nonce) {
String cookie = LinkedCookieResource.generate(context, fingerprint, nonce);
return String.format(context.getResources().getString(R.string.linked_id_generic_text),

View File

@@ -35,7 +35,7 @@ public class TwitterResource extends LinkedCookieResource {
super(flags, params, uri);
}
public static String generateText (Context context, byte[] fingerprint, String nonce) {
public static String generateText (Context context, byte[] fingerprint, int nonce) {
// nothing special here for now, might change this later
return LinkedCookieResource.generate(context, fingerprint, nonce);
}