aboutsummaryrefslogtreecommitdiffstats
path: root/OpenKeychain/src
diff options
context:
space:
mode:
authorTim Bray <timbray@gmail.com>2014-11-11 18:45:36 -0800
committerTim Bray <timbray@gmail.com>2014-11-11 18:45:36 -0800
commit36bac67dd5f19b72a58584f2fab104e6e26df66a (patch)
treec6d65d65dbcdf042b87172160c5ceeb58198e28b /OpenKeychain/src
parent3c19e6cfc12f6b24cf202aaaf9ad3e14223161d3 (diff)
downloadopen-keychain-36bac67dd5f19b72a58584f2fab104e6e26df66a.tar.gz
open-keychain-36bac67dd5f19b72a58584f2fab104e6e26df66a.tar.bz2
open-keychain-36bac67dd5f19b72a58584f2fab104e6e26df66a.zip
All keybase proofs now in place
Diffstat (limited to 'OpenKeychain/src')
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java38
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentServiceHandler.java5
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyTrustFragment.java90
-rw-r--r--OpenKeychain/src/main/res/values/strings.xml7
4 files changed, 96 insertions, 44 deletions
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java
index 42e0c7cc9..8a670df25 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java
@@ -84,6 +84,12 @@ import java.util.Iterator;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
+import de.measite.minidns.Client;
+import de.measite.minidns.Question;
+import de.measite.minidns.Record;
+import de.measite.minidns.record.Data;
+import de.measite.minidns.record.TXT;
+
/**
* This Service contains all important long lasting operations for APG. It receives Intents with
* data from the activities or other apps, queues these intents, executes them, and stops itself
@@ -124,6 +130,7 @@ public class KeychainIntentService extends IntentService implements Progressable
// encrypt, decrypt, import export
public static final String TARGET = "target";
public static final String SOURCE = "source";
+
// possible targets:
public static final int IO_BYTES = 1;
public static final int IO_URI = 2;
@@ -321,12 +328,27 @@ public class KeychainIntentService extends IntentService implements Progressable
return;
}
+ String domain = prover.dnsTxtCheckRequired();
+ if (domain != null) {
+ Record[] records = new Client().query(new Question(domain, Record.TYPE.TXT)).getAnswers();
+ List<List<byte[]>> extents = new ArrayList<List<byte[]>>();
+ for (Record r : records) {
+ Data d = r.getPayload();
+ if (d instanceof TXT) {
+ extents.add(((TXT) d).getExtents());
+ }
+ }
+ if (!prover.checkDnsTxt(extents)) {
+ sendProofError(prover.getLog(), null);
+ return;
+ }
+ }
+
byte[] messageBytes = prover.getPgpMessage().getBytes();
if (prover.rawMessageCheckRequired()) {
InputStream messageByteStream = PGPUtil.getDecoderStream(new ByteArrayInputStream(messageBytes));
- String problem = prover.checkRawMessageBytes(messageByteStream);
- if (problem != null) {
- sendProofError(prover.getLog(), problem);
+ if (!prover.checkRawMessageBytes(messageByteStream)) {
+ sendProofError(prover.getLog(), null);
return;
}
}
@@ -365,6 +387,11 @@ public class KeychainIntentService extends IntentService implements Progressable
Bundle resultData = new Bundle();
resultData.putString(KeychainIntentServiceHandler.DATA_MESSAGE, "OK");
+
+ // these help the handler construct a useful human-readable message
+ resultData.putString(KeychainIntentServiceHandler.KEYBASE_PROOF_URL, prover.getProofUrl());
+ resultData.putString(KeychainIntentServiceHandler.KEYBASE_PRESENCE_URL, prover.getPresenceUrl());
+ resultData.putString(KeychainIntentServiceHandler.KEYBASE_PRESENCE_LABEL, prover.getPresenceLabel());
sendMessageToHandler(KeychainIntentServiceHandler.MESSAGE_OKAY, resultData);
} catch (Exception e) {
sendErrorToHandler(e);
@@ -678,11 +705,12 @@ public class KeychainIntentService extends IntentService implements Progressable
private void sendProofError(List<String> log, String label) {
String msg = null;
+ label = (label == null) ? "" : label + ": ";
for (String m : log) {
- Log.e(Constants.TAG, label + ": " + m);
+ Log.e(Constants.TAG, label + m);
msg = m;
}
- sendProofError(label + ": " + msg);
+ sendProofError(label + msg);
}
private void sendProofError(String msg) {
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentServiceHandler.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentServiceHandler.java
index 180020d0b..fc65757f5 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentServiceHandler.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentServiceHandler.java
@@ -45,6 +45,11 @@ public class KeychainIntentServiceHandler extends Handler {
public static final String DATA_MESSAGE = "message";
public static final String DATA_MESSAGE_ID = "message_id";
+ // keybase proof specific
+ public static final String KEYBASE_PROOF_URL = "keybase_proof_url";
+ public static final String KEYBASE_PRESENCE_URL = "keybase_presence_url";
+ public static final String KEYBASE_PRESENCE_LABEL = "keybase_presence_label";
+
Activity mActivity;
ProgressDialogFragment mProgressDialogFragment;
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyTrustFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyTrustFragment.java
index 540dcc0b1..4965b2525 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyTrustFragment.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyTrustFragment.java
@@ -324,9 +324,6 @@ public class ViewKeyTrustFragment extends LoaderFragment implements
}
private void appendIfOK(Hashtable<Integer, ArrayList<Proof>> table, Integer proofType, Proof proof) throws KeybaseException {
- if (!proofIsOK(proof)) {
- return;
- }
ArrayList<Proof> list = table.get(proofType);
if (list == null) {
list = new ArrayList<Proof>();
@@ -335,23 +332,16 @@ public class ViewKeyTrustFragment extends LoaderFragment implements
list.add(proof);
}
- // We only accept http & https proofs. Maybe whitelist later?
- private boolean proofIsOK(Proof proof) throws KeybaseException {
- Uri uri = Uri.parse(proof.getServiceUrl());
- String scheme = uri.getScheme();
- return ("https".equalsIgnoreCase(scheme) || "http".equalsIgnoreCase(scheme));
- }
-
// which proofs do we have working verifiers for?
private boolean haveProofFor(int proofType) {
switch (proofType) {
case Proof.PROOF_TYPE_TWITTER: return true;
case Proof.PROOF_TYPE_GITHUB: return true;
- case Proof.PROOF_TYPE_DNS: return false;
+ case Proof.PROOF_TYPE_DNS: return true;
case Proof.PROOF_TYPE_WEB_SITE: return true;
case Proof.PROOF_TYPE_HACKERNEWS: return true;
- case Proof.PROOF_TYPE_COINBASE: return false;
- case Proof.PROOF_TYPE_REDDIT: return false;
+ case Proof.PROOF_TYPE_COINBASE: return true;
+ case Proof.PROOF_TYPE_REDDIT: return true;
default: return false;
}
}
@@ -381,47 +371,69 @@ public class ViewKeyTrustFragment extends LoaderFragment implements
SpannableStringBuilder ssb = new SpannableStringBuilder();
if ((msg != null) && msg.equals("OK")) {
+
//yay
- String serviceUrl, urlLabel, postUrl;
- try {
- serviceUrl = proof.getServiceUrl();
- if (serviceUrl.startsWith("https://")) {
- urlLabel = serviceUrl.substring("https://".length());
- } else if (serviceUrl.startsWith("http://")) {
- urlLabel = serviceUrl.substring("http://".length());
- } else {
- urlLabel = serviceUrl;
- }
- postUrl = proof.getHumanUrl();
-
- } catch (KeybaseException e) {
- throw new RuntimeException(e);
+ String proofUrl = returnData.getString(KeychainIntentServiceHandler.KEYBASE_PROOF_URL);
+ String presenceUrl = returnData.getString(KeychainIntentServiceHandler.KEYBASE_PRESENCE_URL);
+ String presenceLabel = returnData.getString(KeychainIntentServiceHandler.KEYBASE_PRESENCE_LABEL);
+
+ String proofLabel;
+ switch (proof.getType()) {
+ case Proof.PROOF_TYPE_TWITTER:
+ proofLabel = getString(R.string.keybase_twitter_proof);
+ break;
+ case Proof.PROOF_TYPE_DNS:
+ proofLabel = getString(R.string.keybase_dns_proof);
+ break;
+ case Proof.PROOF_TYPE_WEB_SITE:
+ proofLabel = getString(R.string.keybase_web_site_proof);
+ break;
+ case Proof.PROOF_TYPE_GITHUB:
+ proofLabel = getString(R.string.keybase_github_proof);
+ break;
+ case Proof.PROOF_TYPE_REDDIT:
+ proofLabel = getString(R.string.keybase_reddit_proof);
+ break;
+ default:
+ proofLabel = getString(R.string.keybase_a_post);
+ break;
}
+
ssb.append(getString(R.string.keybase_proof_succeeded));
StyleSpan bold = new StyleSpan(Typeface.BOLD);
ssb.setSpan(bold, 0, ssb.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
ssb.append("\n\n");
int length = ssb.length();
- String segment = getString(R.string.keybase_a_post);
- ssb.append(segment);
- URLSpan postLink = new URLSpan(postUrl);
- ssb.setSpan(postLink, length, length + segment.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
- ssb.append(" ").append(getString(R.string.keybase_fetched_from)).append(" ");
- URLSpan serviceLink = new URLSpan(serviceUrl);
+ ssb.append(proofLabel);
+ if (proofUrl != null) {
+ URLSpan postLink = new URLSpan(proofUrl);
+ ssb.setSpan(postLink, length, length + proofLabel.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
+ }
+ if (Proof.PROOF_TYPE_DNS == proof.getType()) {
+ ssb.append(" ").append(getString(R.string.keybase_for_the_domain)).append(" ");
+ } else {
+ ssb.append(" ").append(getString(R.string.keybase_fetched_from)).append(" ");
+ }
length = ssb.length();
- ssb.append(urlLabel);
- ssb.setSpan(serviceLink, length, length + urlLabel.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
+ URLSpan presenceLink = new URLSpan(presenceUrl);
+ ssb.append(presenceLabel);
+ ssb.setSpan(presenceLink, length, length + presenceLabel.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
+ if (Proof.PROOF_TYPE_REDDIT == proof.getType()) {
+ ssb.append(", ").
+ append(getString(R.string.keybase_reddit_attribution)).
+ append(" “").append(proof.getHandle()).append("”, ");
+ }
ssb.append(" ").append(getString(R.string.keybase_contained_signature));
-
} else {
+ // verification failed!
msg = returnData.getString(KeychainIntentServiceHandler.DATA_ERROR);
ssb.append(getString(R.string.keybase_proof_failure));
if (msg == null) {
msg = getString(R.string.keybase_unknown_proof_failure);
- StyleSpan bold = new StyleSpan(Typeface.BOLD);
- ssb.setSpan(bold, 0, ssb.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
- ssb.append("\n\n").append(msg);
}
+ StyleSpan bold = new StyleSpan(Typeface.BOLD);
+ ssb.setSpan(bold, 0, ssb.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
+ ssb.append("\n\n").append(msg);
}
mProofVerifyHeader.setVisibility(View.VISIBLE);
mProofVerifyDetail.setVisibility(View.VISIBLE);
diff --git a/OpenKeychain/src/main/res/values/strings.xml b/OpenKeychain/src/main/res/values/strings.xml
index f582bd746..9596cccc1 100644
--- a/OpenKeychain/src/main/res/values/strings.xml
+++ b/OpenKeychain/src/main/res/values/strings.xml
@@ -567,7 +567,14 @@
<string name="keybase_proof_succeeded">"This proof has been verified!"</string>
<string name="keybase_a_post">"A post"</string>
<string name="keybase_fetched_from">"fetched from"</string>
+ <string name="keybase_for_the_domain">"for the domain"</string>
<string name="keybase_contained_signature">"contains a message which could only have been created by the owner of this key."</string>
+ <string name="keybase_twitter_proof">"A tweet"</string>
+ <string name="keybase_dns_proof">"A DNS TXT record"</string>
+ <string name="keybase_web_site_proof">"A text file"</string>
+ <string name="keybase_github_proof">"A gist"</string>
+ <string name="keybase_reddit_proof">"A JSON file"</string>
+ <string name="keybase_reddit_attribution">"attributed by Reddit to"</string>
<!-- Edit key -->
<string name="edit_key_action_change_passphrase">"Change Passphrase"</string>