diff options
Diffstat (limited to 'OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp')
10 files changed, 722 insertions, 0 deletions
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedPublicKey.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedPublicKey.java index 9276cba10..0173a1d83 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedPublicKey.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedPublicKey.java @@ -361,4 +361,5 @@ public class UncachedPublicKey { return calendar.getTime(); } + } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/WrappedUserAttribute.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/WrappedUserAttribute.java index 8e23d36d9..49e4d9793 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/WrappedUserAttribute.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/WrappedUserAttribute.java @@ -1,4 +1,8 @@ /* +<<<<<<< HEAD + * Copyright (C) 2014 Dominik Schürmann <dominik@dominikschuermann.de> +======= +>>>>>>> development * Copyright (C) 2014 Vincent Breitmoser <v.breitmoser@mugenguild.com> * * This program is free software: you can redistribute it and/or modify @@ -37,6 +41,7 @@ public class WrappedUserAttribute implements Serializable { public static final int UAT_NONE = 0; public static final int UAT_IMAGE = UserAttributeSubpacketTags.IMAGE_ATTRIBUTE; + public static final int UAT_LINKED_ID = 100; private PGPUserAttributeSubpacketVector mVector; @@ -109,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 { } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/linked/LinkedCookieResource.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/linked/LinkedCookieResource.java new file mode 100644 index 000000000..b21f482b7 --- /dev/null +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/linked/LinkedCookieResource.java @@ -0,0 +1,138 @@ +package org.sufficientlysecure.keychain.pgp.linked; + +import android.content.Context; + +import org.sufficientlysecure.keychain.Constants; +import org.sufficientlysecure.keychain.operations.results.LinkedVerifyResult; +import org.sufficientlysecure.keychain.operations.results.OperationResult.LogType; +import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog; +import org.sufficientlysecure.keychain.pgp.linked.resources.GenericHttpsResource; +import org.sufficientlysecure.keychain.pgp.linked.resources.UnknownResource; +import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils; +import org.sufficientlysecure.keychain.util.Log; + +import java.net.URI; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map.Entry; +import java.util.Set; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public abstract class LinkedCookieResource extends LinkedResource { + + protected LinkedCookieResource(Set<String> flags, HashMap<String, String> params, URI uri) { + super(flags, params, uri); + } + + public URI toUri () { + + StringBuilder b = new StringBuilder(); + b.append("pgpid+cookie:"); + + // 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; + for (Entry<String, String> stringStringEntry : mParams.entrySet()) { + if (!first) { + b.append(";"); + } + first = false; + b.append(stringStringEntry.getKey()).append("=").append(stringStringEntry.getValue()); + } + } + + b.append("@"); + b.append(mSubUri); + + return URI.create(b.toString()); + + } + + public URI getSubUri () { + return mSubUri; + } + + public static String generate (Context context, byte[] fingerprint, int nonce) { + return String.format("\"[Verifying my PGP key: openpgp4fpr:%s#%08x]\"", + KeyFormattingUtils.convertFingerprintToHex(fingerprint), nonce); + } + + public static String generatePreview () { + return "[Verifying my PGP key: openpgp4fpr:0x…]"; + } + + public LinkedVerifyResult verify(byte[] fingerprint, int nonce) { + + OperationLog log = new OperationLog(); + log.add(LogType.MSG_LV, 0); + + // Try to fetch resource. Logs for itself + String res = fetchResource(log, 1); + if (res == null) { + // if this is null, an error was recorded in fetchResource above + return new LinkedVerifyResult(LinkedVerifyResult.RESULT_ERROR, log); + } + + Log.d(Constants.TAG, "Resource data: '" + res + "'"); + + return verifyString(log, 1, res, nonce, fingerprint); + + } + + protected abstract String fetchResource (OperationLog log, int indent); + + protected Matcher matchResource (OperationLog log, int indent, String res) { + return magicPattern.matcher(res); + } + + protected LinkedVerifyResult verifyString (OperationLog log, int indent, + String res, + int nonce, byte[] fingerprint) { + + log.add(LogType.MSG_LV_MATCH, indent); + Matcher match = matchResource(log, indent+1, res); + if (!match.find()) { + log.add(LogType.MSG_LV_MATCH_ERROR, 2); + return new LinkedVerifyResult(LinkedVerifyResult.RESULT_ERROR, log); + } + + String candidateFp = match.group(1).toLowerCase(); + 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); + + if (!fp.equals(candidateFp)) { + log.add(LogType.MSG_LV_FP_ERROR, indent); + return new LinkedVerifyResult(LinkedVerifyResult.RESULT_ERROR, log); + } + log.add(LogType.MSG_LV_FP_OK, indent); + + log.add(LogType.MSG_LV_NONCE_OK, indent); + return new LinkedVerifyResult(LinkedVerifyResult.RESULT_OK, log); + + } + +} diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/linked/LinkedIdentity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/linked/LinkedIdentity.java new file mode 100644 index 000000000..f06a23681 --- /dev/null +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/linked/LinkedIdentity.java @@ -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()); + } + +} diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/linked/LinkedResource.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/linked/LinkedResource.java new file mode 100644 index 000000000..59ffbfc45 --- /dev/null +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/linked/LinkedResource.java @@ -0,0 +1,98 @@ +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>(); + if (!pieces[0].isEmpty()) { + 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(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; + + } + +} diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/linked/RawLinkedIdentity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/linked/RawLinkedIdentity.java new file mode 100644 index 000000000..bfde3c3b9 --- /dev/null +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/linked/RawLinkedIdentity.java @@ -0,0 +1,45 @@ +package org.sufficientlysecure.keychain.pgp.linked; + +import org.spongycastle.util.Strings; +import org.sufficientlysecure.keychain.pgp.WrappedUserAttribute; + +import java.net.URI; +import java.nio.ByteBuffer; + +/** The RawLinkedIdentity contains raw parsed data from a Linked Identity subpacket. */ +public class RawLinkedIdentity { + + public final int mNonce; + public final URI mUri; + + protected RawLinkedIdentity(int nonce, URI uri) { + mNonce = nonce; + mUri = uri; + } + + public byte[] getEncoded() { + byte[] uriData = Strings.toUTF8ByteArray(mUri.toASCIIString()); + + ByteBuffer buf = ByteBuffer.allocate(4 + uriData.length); + + buf.putInt(mNonce); + buf.put(uriData); + + return buf.array(); + } + + public WrappedUserAttribute toUserAttribute () { + return WrappedUserAttribute.fromSubpacket(WrappedUserAttribute.UAT_LINKED_ID, getEncoded()); + } + + 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 1234567; + } + +} diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/linked/resources/DnsResource.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/linked/resources/DnsResource.java new file mode 100644 index 000000000..d5b8a0345 --- /dev/null +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/linked/resources/DnsResource.java @@ -0,0 +1,103 @@ +package org.sufficientlysecure.keychain.pgp.linked.resources; + +import android.content.Context; + +import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog; +import org.sufficientlysecure.keychain.pgp.linked.LinkedCookieResource; +import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils; + +import java.net.URI; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Set; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import de.measite.minidns.Client; +import de.measite.minidns.DNSMessage; +import de.measite.minidns.Question; +import de.measite.minidns.Record; +import de.measite.minidns.Record.CLASS; +import de.measite.minidns.Record.TYPE; +import de.measite.minidns.record.TXT; + +public class DnsResource extends LinkedCookieResource { + + final static Pattern magicPattern = + Pattern.compile("pgpid\\+cookie=([a-zA-Z0-9]+)(?:#|;)([a-zA-Z0-9]+)"); + + String mFqdn; + CLASS mClass; + TYPE mType; + + DnsResource(Set<String> flags, HashMap<String, String> params, URI uri, + String fqdn, CLASS clazz, TYPE type) { + super(flags, params, uri); + + mFqdn = fqdn; + mClass = clazz; + mType = type; + } + + public static String generateText (Context context, byte[] fingerprint, int nonce) { + + return String.format("pgpid+cookie=%s;%08x", + KeyFormattingUtils.convertFingerprintToHex(fingerprint), nonce); + + } + + public static DnsResource createNew (String domain) { + HashSet<String> flags = new HashSet<String>(); + HashMap<String,String> params = new HashMap<String,String>(); + URI uri = URI.create("dns:" + domain); + return create(flags, params, uri); + } + + public static DnsResource create(Set<String> flags, HashMap<String,String> params, URI uri) { + if ( ! ("dns".equals(uri.getScheme()) + && (flags == null || flags.isEmpty()) + && (params == null || params.isEmpty()))) { + return null; + } + + // + String spec = uri.getSchemeSpecificPart(); + // If there are // at the beginning, this includes an authority - we don't support those! + if (spec.startsWith("//")) { + return null; + } + + String[] pieces = spec.split("\\?", 2); + // In either case, part before a ? is the fqdn + String fqdn = pieces[0]; + // There may be a query part + if (pieces.length > 1) { + // TODO parse CLASS and TYPE query paramters + } + + CLASS clazz = CLASS.IN; + TYPE type = TYPE.TXT; + + return new DnsResource(flags, params, uri, fqdn, clazz, type); + } + + public String getFqdn() { + return mFqdn; + } + + @Override + protected String fetchResource (OperationLog log, int indent) { + + Client c = new Client(); + DNSMessage msg = c.query(new Question(mFqdn, mType, mClass)); + Record aw = msg.getAnswers()[0]; + TXT txt = (TXT) aw.getPayload(); + return txt.getText().toLowerCase(); + + } + + @Override + protected Matcher matchResource(OperationLog log, int indent, String res) { + return magicPattern.matcher(res); + } +} diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/linked/resources/GenericHttpsResource.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/linked/resources/GenericHttpsResource.java new file mode 100644 index 000000000..ba94bae75 --- /dev/null +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/linked/resources/GenericHttpsResource.java @@ -0,0 +1,103 @@ +package org.sufficientlysecure.keychain.pgp.linked.resources; + +import android.content.Context; + +import com.textuality.keybase.lib.Search; + +import org.sufficientlysecure.keychain.Constants; +import org.sufficientlysecure.keychain.R; +import org.sufficientlysecure.keychain.operations.results.OperationResult.LogType; +import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog; +import org.sufficientlysecure.keychain.pgp.linked.LinkedCookieResource; +import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils; +import org.sufficientlysecure.keychain.util.Log; + +import java.io.IOException; +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 LinkedCookieResource { + + GenericHttpsResource(Set<String> flags, HashMap<String,String> params, URI uri) { + super(flags, params, uri); + } + + 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), + cookie, "0x" + KeyFormattingUtils.convertFingerprintToHex(fingerprint).substring(24)); + } + + @Override + protected String fetchResource (OperationLog log, int indent) { + + log.add(LogType.MSG_LV_FETCH, indent, mSubUri.toString()); + indent += 1; + + try { + + HttpsURLConnection conn = null; + URL url = mSubUri.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)); + log.add(LogType.MSG_LV_FETCH_REDIR, indent, url.toString()); + } else { + break; + } + } + + if (status >= 200 && status < 300) { + log.add(LogType.MSG_LV_FETCH_OK, indent, Integer.toString(status)); + return Search.snarf(conn.getInputStream()); + } else { + // log verbose output to logcat + Log.e(Constants.TAG, Search.snarf(conn.getErrorStream())); + log.add(LogType.MSG_LV_FETCH_ERROR, indent, Integer.toString(status)); + return null; + } + + } catch (MalformedURLException e) { + log.add(LogType.MSG_LV_FETCH_ERROR_URL, indent); + return null; + } catch (IOException e) { + log.add(LogType.MSG_LV_FETCH_ERROR_IO, indent); + return null; + } + + } + + 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/linked/resources/TwitterResource.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/linked/resources/TwitterResource.java new file mode 100644 index 000000000..f6ec4f97a --- /dev/null +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/linked/resources/TwitterResource.java @@ -0,0 +1,124 @@ +package org.sufficientlysecure.keychain.pgp.linked.resources; + +import android.content.Context; +import android.util.Base64; + +import com.textuality.keybase.lib.JWalk; + +import org.apache.http.HttpEntity; +import org.apache.http.HttpResponse; +import org.apache.http.client.ClientProtocolException; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.client.methods.HttpRequestBase; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.DefaultHttpClient; +import org.apache.http.params.BasicHttpParams; +import org.json.JSONException; +import org.json.JSONObject; +import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog; +import org.sufficientlysecure.keychain.pgp.linked.LinkedCookieResource; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.UnsupportedEncodingException; +import java.net.URI; +import java.net.URLEncoder; +import java.util.HashMap; +import java.util.Set; + +public class TwitterResource extends LinkedCookieResource { + + TwitterResource(Set<String> flags, HashMap<String,String> params, URI uri) { + super(flags, params, uri); + } + + 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); + } + + private String getTwitterStream(String screenName) { + String results = null; + + // Step 1: Encode consumer key and secret + try { + // URL encode the consumer key and secret + String urlApiKey = URLEncoder.encode("6IhPnWbYxASAoAzH2QaUtHD0J", "UTF-8"); + String urlApiSecret = URLEncoder.encode("L0GnuiOnapWbSBbQtLIqtpeS5BTtvh06dmoMoKQfHQS8UwHuWm", "UTF-8"); + + // Concatenate the encoded consumer key, a colon character, and the + // encoded consumer secret + String combined = urlApiKey + ":" + urlApiSecret; + + // Base64 encode the string + String base64Encoded = Base64.encodeToString(combined.getBytes(), Base64.NO_WRAP); + + // Step 2: Obtain a bearer token + HttpPost httpPost = new HttpPost("https://api.twitter.com/oauth2/token"); + httpPost.setHeader("Authorization", "Basic " + base64Encoded); + httpPost.setHeader("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8"); + httpPost.setEntity(new StringEntity("grant_type=client_credentials")); + JSONObject rawAuthorization = new JSONObject(getResponseBody(httpPost)); + String auth = JWalk.getString(rawAuthorization, "access_token"); + + // Applications should verify that the value associated with the + // token_type key of the returned object is bearer + if (auth != null && JWalk.getString(rawAuthorization, "token_type").equals("bearer")) { + + // Step 3: Authenticate API requests with bearer token + HttpGet httpGet = + new HttpGet("https://api.twitter.com/1.1/statuses/user_timeline.json?screen_name=" + screenName); + + // construct a normal HTTPS request and include an Authorization + // header with the value of Bearer <> + httpGet.setHeader("Authorization", "Bearer " + auth); + httpGet.setHeader("Content-Type", "application/json"); + // update the results with the body of the response + results = getResponseBody(httpGet); + } + } catch (UnsupportedEncodingException ex) { + } catch (JSONException ex) { + } catch (IllegalStateException ex1) { + } + return results; + } + + private static String getResponseBody(HttpRequestBase request) { + StringBuilder sb = new StringBuilder(); + try { + + DefaultHttpClient httpClient = new DefaultHttpClient(new BasicHttpParams()); + HttpResponse response = httpClient.execute(request); + int statusCode = response.getStatusLine().getStatusCode(); + String reason = response.getStatusLine().getReasonPhrase(); + + if (statusCode == 200) { + + HttpEntity entity = response.getEntity(); + InputStream inputStream = entity.getContent(); + + BufferedReader bReader = new BufferedReader( + new InputStreamReader(inputStream, "UTF-8"), 8); + String line = null; + while ((line = bReader.readLine()) != null) { + sb.append(line); + } + } else { + sb.append(reason); + } + } catch (UnsupportedEncodingException ex) { + } catch (ClientProtocolException ex1) { + } catch (IOException ex2) { + } + return sb.toString(); + } + + @Override + protected String fetchResource(OperationLog log, int indent) { + return getTwitterStream("Valodim"); + } + +} diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/linked/resources/UnknownResource.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/linked/resources/UnknownResource.java new file mode 100644 index 000000000..f29ab5b39 --- /dev/null +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/linked/resources/UnknownResource.java @@ -0,0 +1,21 @@ +package org.sufficientlysecure.keychain.pgp.linked.resources; + +import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog; +import org.sufficientlysecure.keychain.pgp.linked.LinkedCookieResource; + +import java.net.URI; +import java.util.HashMap; +import java.util.Set; + +public class UnknownResource extends LinkedCookieResource { + + public UnknownResource(Set<String> flags, HashMap<String,String> params, URI uri) { + super(flags, params, uri); + } + + @Override + protected String fetchResource(OperationLog log, int indent) { + return null; + } + +} |