mirror of
https://github.com/moparisthebest/open-keychain
synced 2024-12-25 08:28:50 -05:00
All keybase proofs now in place
This commit is contained in:
parent
3c19e6cfc1
commit
36bac67dd5
@ -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) {
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
//yay
|
||||
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);
|
||||
|
@ -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>
|
||||
|
Loading…
Reference in New Issue
Block a user