aboutsummaryrefslogtreecommitdiffstats
path: root/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp
diff options
context:
space:
mode:
authorVincent Breitmoser <valodim@mugenguild.com>2015-01-12 13:17:18 +0100
committerVincent Breitmoser <valodim@mugenguild.com>2015-01-12 13:17:18 +0100
commit5faeb5f5f060e049000e804deca5445d281f8611 (patch)
tree9c6d9446ce980c4a69125b3957e18e35fc5673f1 /OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp
parent6570483fab4b7bfa2b09cc3e94a3901a002326cc (diff)
downloadopen-keychain-5faeb5f5f060e049000e804deca5445d281f8611.tar.gz
open-keychain-5faeb5f5f060e049000e804deca5445d281f8611.tar.bz2
open-keychain-5faeb5f5f060e049000e804deca5445d281f8611.zip
intermediate state, nothing really working yet
Diffstat (limited to 'OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp')
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/affirmation/Affirmation.java157
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/affirmation/AffirmationResource.java43
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/affirmation/resources/DnsResouce.java4
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/affirmation/resources/GenericHttpsResource.java130
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/affirmation/resources/TwitterResource.java4
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/affirmation/resources/UnknownResource.java20
6 files changed, 358 insertions, 0 deletions
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/affirmation/Affirmation.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/affirmation/Affirmation.java
new file mode 100644
index 000000000..f12ebd481
--- /dev/null
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/affirmation/Affirmation.java
@@ -0,0 +1,157 @@
+package org.sufficientlysecure.keychain.pgp.affirmation;
+
+import org.spongycastle.bcpg.UserAttributeSubpacket;
+import org.spongycastle.util.Strings;
+import org.sufficientlysecure.keychain.Constants;
+import org.sufficientlysecure.keychain.util.Log;
+
+import java.net.URI;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map.Entry;
+import java.util.Set;
+
+public class Affirmation {
+
+ protected byte[] mData;
+ public final long mNonce;
+ public final URI mSubUri;
+ final Set<String> mFlags;
+ final HashMap<String,String> mParams;
+
+ protected Affirmation(byte[] data, long nonce, Set<String> flags,
+ HashMap<String,String> params, URI subUri) {
+ mData = data;
+ mNonce = nonce;
+ mFlags = flags;
+ mParams = params;
+ mSubUri = subUri;
+ }
+
+ Affirmation(long nonce, Set<String> flags,
+ HashMap<String,String> params, URI subUri) {
+ this(null, nonce, flags, params, subUri);
+ }
+
+ public byte[] encode() {
+ if (mData != null) {
+ return mData;
+ }
+
+ StringBuilder b = new StringBuilder();
+ b.append("pgpid:");
+
+ // add flags
+ if (mFlags != null) {
+ boolean first = true;
+ for (String flag : mFlags) {
+ if (!first) {
+ b.append(";");
+ }
+ first = false;
+ b.append(flag);
+ }
+ }
+
+ // add parameters
+ if (mParams != null) {
+ boolean first = true;
+ Iterator<Entry<String, String>> it = mParams.entrySet().iterator();
+ while (it.hasNext()) {
+ if (!first) {
+ b.append(";");
+ }
+ first = false;
+ Entry<String, String> entry = it.next();
+ b.append(entry.getKey()).append("=").append(entry.getValue());
+ }
+ }
+
+ b.append("@");
+ b.append(mSubUri);
+
+ byte[] data = Strings.toUTF8ByteArray(b.toString());
+
+ byte[] result = new byte[data.length+4];
+ result[0] = (byte) (mNonce >> 24 & 255);
+ result[1] = (byte) (mNonce >> 16 & 255);
+ result[2] = (byte) (mNonce >> 8 & 255);
+ result[3] = (byte) (mNonce & 255);
+
+ System.arraycopy(data, 0, result, 4, result.length);
+
+ return result;
+ }
+
+ /** This method parses an affirmation from a UserAttributeSubpacket, or returns null if the
+ * subpacket can not be parsed as a valid affirmation.
+ */
+ public static Affirmation parseAffirmation(UserAttributeSubpacket subpacket) {
+ if (subpacket.getType() != 100) {
+ return null;
+ }
+
+ byte[] data = subpacket.getData();
+
+ long nonce = (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3];
+
+ try {
+ return parseUri(nonce, Strings.fromUTF8ByteArray(Arrays.copyOfRange(data, 4, data.length)));
+
+ } catch (IllegalArgumentException e) {
+ Log.e(Constants.TAG, "error parsing uri in (suspected) affirmation packet");
+ return null;
+ }
+ }
+
+ public static Affirmation generateForUri(String uri) {
+ return parseUri(generateNonce(), uri);
+ }
+
+ protected static Affirmation parseUri (long nonce, String uriString) {
+ URI uri = URI.create(uriString);
+
+ if ("pgpid".equals(uri.getScheme())) {
+ Log.e(Constants.TAG, "unknown uri scheme in (suspected) affirmation packet");
+ return null;
+ }
+
+ if (!uri.isOpaque()) {
+ Log.e(Constants.TAG, "non-opaque uri in (suspected) affirmation packet");
+ return null;
+ }
+
+ String specific = uri.getSchemeSpecificPart();
+ if (!specific.contains("@")) {
+ Log.e(Constants.TAG, "unknown uri scheme in affirmation 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 new Affirmation(null, nonce, flags, params, subUri);
+
+ }
+
+ public static long generateNonce() {
+ return 1234567890L; // new SecureRandom().nextLong();
+ }
+
+}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/affirmation/AffirmationResource.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/affirmation/AffirmationResource.java
new file mode 100644
index 000000000..e356ccb8e
--- /dev/null
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/affirmation/AffirmationResource.java
@@ -0,0 +1,43 @@
+package org.sufficientlysecure.keychain.pgp.affirmation;
+
+import org.sufficientlysecure.keychain.pgp.affirmation.resources.GenericHttpsResource;
+import org.sufficientlysecure.keychain.pgp.affirmation.resources.UnknownResource;
+
+import java.net.URI;
+import java.security.SecureRandom;
+import java.util.HashMap;
+import java.util.Set;
+
+public abstract class AffirmationResource {
+
+ protected final URI mUri;
+ protected final Set<String> mFlags;
+ protected final HashMap<String,String> mParams;
+
+ protected AffirmationResource(Set<String> flags, HashMap<String,String> params, URI uri) {
+ mFlags = flags;
+ mParams = params;
+ mUri = uri;
+ }
+
+ public abstract boolean verify();
+
+ public static AffirmationResource findResourceType
+ (Set<String> flags, HashMap<String,String> params, URI uri) {
+
+ AffirmationResource res;
+
+ res = GenericHttpsResource.create(flags, params, uri);
+ if (res != null) {
+ return res;
+ }
+
+ return new UnknownResource(flags, params, uri);
+
+ }
+
+ public static long generateNonce() {
+ return 1234567890L; // new SecureRandom().nextLong();
+ }
+
+}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/affirmation/resources/DnsResouce.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/affirmation/resources/DnsResouce.java
new file mode 100644
index 000000000..3e39a695d
--- /dev/null
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/affirmation/resources/DnsResouce.java
@@ -0,0 +1,4 @@
+package org.sufficientlysecure.keychain.pgp.affirmation.resources;
+
+public class DnsResouce {
+}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/affirmation/resources/GenericHttpsResource.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/affirmation/resources/GenericHttpsResource.java
new file mode 100644
index 000000000..42615d105
--- /dev/null
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/affirmation/resources/GenericHttpsResource.java
@@ -0,0 +1,130 @@
+package org.sufficientlysecure.keychain.pgp.affirmation.resources;
+
+import android.content.Context;
+
+import com.textuality.keybase.lib.Search;
+
+import org.sufficientlysecure.keychain.Constants;
+import org.sufficientlysecure.keychain.operations.results.DecryptVerifyResult;
+import org.sufficientlysecure.keychain.pgp.PgpDecryptVerify;
+import org.sufficientlysecure.keychain.pgp.Progressable;
+import org.sufficientlysecure.keychain.pgp.affirmation.AffirmationResource;
+import org.sufficientlysecure.keychain.provider.ProviderHelper;
+import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
+import org.sufficientlysecure.keychain.util.InputData;
+import org.sufficientlysecure.keychain.util.Log;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.net.MalformedURLException;
+import java.net.URI;
+import java.net.URL;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.net.ssl.HttpsURLConnection;
+
+public class GenericHttpsResource extends AffirmationResource {
+
+ GenericHttpsResource(Set<String> flags, HashMap<String,String> params, URI uri) {
+ super(flags, params, uri);
+ }
+
+ @Override
+ public boolean verify() {
+ return false;
+ }
+
+ public static String generate (byte[] fingerprint, String uri) {
+ long nonce = generateNonce();
+
+ StringBuilder b = new StringBuilder();
+ b.append("---\r\n");
+
+ b.append("fingerprint=");
+ b.append(KeyFormattingUtils.convertFingerprintToHex(fingerprint));
+ b.append('\r').append('\n');
+
+ b.append("nonce=");
+ b.append(nonce);
+ b.append('\r').append('\n');
+
+ if (uri != null) {
+ b.append("uri=");
+ b.append(uri);
+ b.append('\r').append('\n');
+ }
+ b.append("---\r\n");
+
+ return b.toString();
+ }
+
+ public DecryptVerifyResult verify
+ (Context context, ProviderHelper providerHelper, Progressable progress)
+ throws IOException {
+
+ byte[] data = fetchResource(mUri).getBytes();
+ InputData input = new InputData(new ByteArrayInputStream(data), data.length);
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ PgpDecryptVerify.Builder b =
+ new PgpDecryptVerify.Builder(context, providerHelper, progress, input, out);
+ PgpDecryptVerify op = b.build();
+
+ Log.d(Constants.TAG, new String(out.toByteArray()));
+
+ return op.execute();
+ }
+
+ protected static String fetchResource (URI uri) throws IOException {
+
+ try {
+ HttpsURLConnection conn = null;
+ URL url = uri.toURL();
+ int status = 0;
+ int redirects = 0;
+ while (redirects < 5) {
+ conn = (HttpsURLConnection) url.openConnection();
+ conn.addRequestProperty("User-Agent", "OpenKeychain");
+ conn.setConnectTimeout(5000);
+ conn.setReadTimeout(25000);
+ conn.connect();
+ status = conn.getResponseCode();
+ if (status == 301) {
+ redirects++;
+ url = new URL(conn.getHeaderFields().get("Location").get(0));
+ } else {
+ break;
+ }
+ }
+ if (status >= 200 && status < 300) {
+ return Search.snarf(conn.getInputStream());
+ } else {
+ throw new IOException("Fetch failed, status " + status + ": " + Search.snarf(conn.getErrorStream()));
+ }
+
+ } catch (MalformedURLException e) {
+ throw new IOException(e);
+ }
+
+ }
+
+ public static GenericHttpsResource createNew (URI uri) {
+ HashSet<String> flags = new HashSet<String>();
+ flags.add("generic");
+ HashMap<String,String> params = new HashMap<String,String>();
+ return create(flags, params, uri);
+ }
+
+ public static GenericHttpsResource create(Set<String> flags, HashMap<String,String> params, URI uri) {
+ if ( ! ("https".equals(uri.getScheme())
+ && flags != null && flags.size() == 1 && flags.contains("generic")
+ && (params == null || params.isEmpty()))) {
+ return null;
+ }
+ return new GenericHttpsResource(flags, params, uri);
+ }
+
+}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/affirmation/resources/TwitterResource.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/affirmation/resources/TwitterResource.java
new file mode 100644
index 000000000..4fc3590f8
--- /dev/null
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/affirmation/resources/TwitterResource.java
@@ -0,0 +1,4 @@
+package org.sufficientlysecure.keychain.pgp.affirmation.resources;
+
+public class TwitterResource {
+}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/affirmation/resources/UnknownResource.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/affirmation/resources/UnknownResource.java
new file mode 100644
index 000000000..e2d050eb4
--- /dev/null
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/affirmation/resources/UnknownResource.java
@@ -0,0 +1,20 @@
+package org.sufficientlysecure.keychain.pgp.affirmation.resources;
+
+import org.sufficientlysecure.keychain.pgp.affirmation.AffirmationResource;
+
+import java.net.URI;
+import java.util.HashMap;
+import java.util.Set;
+
+public class UnknownResource extends AffirmationResource {
+
+ public UnknownResource(Set<String> flags, HashMap<String,String> params, URI uri) {
+ super(flags, params, uri);
+ }
+
+ @Override
+ public boolean verify() {
+ return false;
+ }
+
+}