ditch keybase

This commit is contained in:
Vincent Breitmoser 2019-11-15 11:47:46 +01:00
parent 5e0a17b966
commit d3e48db520
35 changed files with 41 additions and 1344 deletions

4
.gitmodules vendored
View file

@ -2,10 +2,6 @@
path = extern/openpgp-api-lib
url = https://github.com/open-keychain/openpgp-api.git
ignore = dirty
[submodule "extern/KeybaseLib"]
path = extern/KeybaseLib
url = https://github.com/open-keychain/KeybaseLib.git
ignore = dirty
[submodule "extern/minidns"]
path = extern/minidns
url = https://github.com/open-keychain/minidns.git

View file

@ -61,7 +61,6 @@ dependencies {
implementation project(':extern:bouncycastle:pg')
implementation project(':extern:bouncycastle:prov')
implementation project(':extern:minidns')
implementation project(':KeybaseLib')
implementation project(':extern:MaterialChipsInput')
implementation "android.arch.work:work-runtime:1.0.0-alpha02"

View file

@ -1,38 +0,0 @@
-----BEGIN CERTIFICATE-----
MIIGmzCCBIOgAwIBAgIJAPzhpcIBaOeNMA0GCSqGSIb3DQEBBQUAMIGPMQswCQYD
VQQGEwJVUzELMAkGA1UECBMCTlkxETAPBgNVBAcTCE5ldyBZb3JrMRQwEgYDVQQK
EwtLZXliYXNlIExMQzEXMBUGA1UECxMOQ2VydCBBdXRob3JpdHkxEzARBgNVBAMT
CmtleWJhc2UuaW8xHDAaBgkqhkiG9w0BCQEWDWNhQGtleWJhc2UuaW8wHhcNMTQw
MTAyMTY0MjMzWhcNMjMxMjMxMTY0MjMzWjCBjzELMAkGA1UEBhMCVVMxCzAJBgNV
BAgTAk5ZMREwDwYDVQQHEwhOZXcgWW9yazEUMBIGA1UEChMLS2V5YmFzZSBMTEMx
FzAVBgNVBAsTDkNlcnQgQXV0aG9yaXR5MRMwEQYDVQQDEwprZXliYXNlLmlvMRww
GgYJKoZIhvcNAQkBFg1jYUBrZXliYXNlLmlvMIICIjANBgkqhkiG9w0BAQEFAAOC
Ag8AMIICCgKCAgEA3sLA6ZG8uOvmlFvFLVIOURmcQrZyMFKbVu9/TeDiemls3w3/
JzVTduD+7KiUi9R7QcCW/V1ZpReTfunm7rfACiJ1fpIkjSQrgsvKDLghIzxIS5FM
I8utet5p6QtuJhaAwmmXn8xX05FvqWNbrcXRdpL4goFdigPsFK2xhTUiWatLMste
oShI7+zmrgkx75LeLMD0bL2uOf87JjOzbY8x2sUIZLGwPoATyG8WS38ey6KkJxRj
AhG3p+OTYEjYSrsAtQA6ImbeDpfSHKOB8HF3nVp//Eb4HEiEsWwBRbQXvAWh3DYL
GukFW0wiO0HVCoWY+bHL/Mqa0NdRGOlLsbL4Z4pLrhqKgSDU8umX9YuNRRaB0P5n
TkzyU6axHqzq990Gep/I62bjsBdYYp+DjSPK43mXRrfWJl2NTcl8xKAyfsOW+9hQ
9vwK0tpSicNxfYuUZs0BhfjSZ/Tc6Z1ERdgUYRiXTtohl+SRA2IgZMloHCllVMNj
EjXhguvHgLAOrcuyhVBupiUQGUHQvkMsr1Uz8VPNDFOJedwucRU2AaR881bknnSb
ds9+zNLsvUFV+BK7Qdnt/WkFpYL78rGwY47msi9Ooddx6fPyeg3qkJGM6cwn/boy
w9lQeleYDq8kyJdixIAxtAskNzRPJ4nDu2izTfByQoM8epwAWboc/gNFObMCAwEA
AaOB9zCB9DAdBgNVHQ4EFgQURqpATOw1gVVrzlqqFKbkfaKXvwowgcQGA1UdIwSB
vDCBuYAURqpATOw1gVVrzlqqFKbkfaKXvwqhgZWkgZIwgY8xCzAJBgNVBAYTAlVT
MQswCQYDVQQIEwJOWTERMA8GA1UEBxMITmV3IFlvcmsxFDASBgNVBAoTC0tleWJh
c2UgTExDMRcwFQYDVQQLEw5DZXJ0IEF1dGhvcml0eTETMBEGA1UEAxMKa2V5YmFz
ZS5pbzEcMBoGCSqGSIb3DQEJARYNY2FAa2V5YmFzZS5pb4IJAPzhpcIBaOeNMAwG
A1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggIBAA3Z5FIhulYghMuHdcHYTYWc
7xT5WD4hXQ0WALZs4p5Y+b2Af54o6v1wUE1Au97FORq5CsFXX/kGl/JzzTimeucn
YJwGuXMpilrlHCBAL5/lSQjA7qbYIolQ3SB9ON+LYuF1jKB9k8SqNp7qzucxT3tO
b8ZMDEPNsseC7NE2uwNtcW3yrTh6WZnSqg/jwswiWjHYDdG7U8FjMYlRol3wPux2
PizGbSgiR+ztI2OthxtxNWMrT9XKxNQTpcxOXnLuhiSwqH8PoY17ecP8VPpaa0K6
zym0zSkbroqydazaxcXRk3eSlc02Ktk7HzRzuqQQXhRMkxVnHbFHgGsz03L533pm
mlIEgBMggZkHwNvs1LR7f3v2McdKulDH7Mv8yyfguuQ5Jxxt7RJhUuqSudbEhoaM
6jAJwBkMFxsV2YnyFEd3eZ/qBYPf7TYHhyzmHW6WkSypGqSnXd4gYpJ8o7LxSf4F
inLjxRD+H9Xn1UVXWLM0gaBB7zZcXd2zjMpRsWgezf5IR5vyakJsc7fxzgor3Qeq
Ri6LvdEkhhFVl5rHMQBwNOPngySrq8cs/ikTLTfQVTYXXA4Ba1YyiMOlfaR1LhKw
If1AkUV0tfCTNRZ01EotKSK77+o+k214n+BAu+7mO+9B5Kb7lMFQcuWCHXKYB2Md
cT7Yh09F0QpFUd0ymEfv
-----END CERTIFICATE-----

View file

@ -132,7 +132,6 @@ public final class Constants {
public static final String FIRST_TIME_APP = "firstTimeApp";
public static final String CACHED_CONSOLIDATE = "cachedConsolidate";
public static final String SEARCH_KEYSERVER = "search_keyserver_pref";
public static final String SEARCH_KEYBASE = "search_keybase_pref";
public static final String SEARCH_WEB_KEY_DIRECTORY = "search_wkd_pref";
public static final String USE_NUMKEYPAD_FOR_SECURITY_TOKEN_PIN = "useNumKeypadForYubikeyPin";
public static final String ENCRYPT_FILENAMES = "encryptFilenames";
@ -154,7 +153,6 @@ public final class Constants {
public static final String ENABLE_WIFI_SYNC_ONLY = "enableWifiSyncOnly";
public static final String SYNC_WORK_UUID = "syncWorkUuid";
// other settings
public static final String EXPERIMENTAL_ENABLE_KEYBASE = "experimentalEnableKeybase";
public static final String EXPERIMENTAL_USB_ALLOW_UNTESTED = "experimentalUsbAllowUntested";
public static final String EXPERIMENTAL_SMARTPGP_VERIFY_AUTHORITY = "smartpgp_authorities_pref";
public static final String EXPERIMENTAL_SMARTPGP_AUTHORITIES = "smartpgp_authorities";
@ -178,9 +176,9 @@ public final class Constants {
// we generally only track booleans. never snoop around in the user's string settings!!
public static final List<String> ANALYTICS_PREFS = Arrays.asList(USE_NORMAL_PROXY, USE_TOR_PROXY,
SYNC_CONTACTS, SYNC_KEYSERVER, ENABLE_WIFI_SYNC_ONLY, EXPERIMENTAL_ENABLE_KEYBASE,
SYNC_CONTACTS, SYNC_KEYSERVER, ENABLE_WIFI_SYNC_ONLY,
EXPERIMENTAL_USB_ALLOW_UNTESTED,
PASSPHRASE_CACHE_SUBS, SEARCH_KEYSERVER, SEARCH_KEYBASE, SEARCH_WEB_KEY_DIRECTORY,
PASSPHRASE_CACHE_SUBS, SEARCH_KEYSERVER, SEARCH_WEB_KEY_DIRECTORY,
TEXT_USE_COMPRESSION, TEXT_SELF_ENCRYPT, FILE_USE_COMPRESSION, FILE_SELF_ENCRYPT, USE_ARMOR,
USE_NUMKEYPAD_FOR_SECURITY_TOKEN_PIN, ENCRYPT_FILENAMES);
}

View file

@ -102,7 +102,6 @@ public class KeychainApplication extends Application {
TlsCertificatePinning.addPinnedCertificate("keys.openpgp.org", getAssets(), "LetsEncryptCA.cer");
TlsCertificatePinning.addPinnedCertificate("hkps.pool.sks-keyservers.net", getAssets(), "hkps.pool.sks-keyservers.net.CA.cer");
TlsCertificatePinning.addPinnedCertificate("pgp.mit.edu", getAssets(), "pgp.mit.edu.cer");
TlsCertificatePinning.addPinnedCertificate("api.keybase.io", getAssets(), "api.keybase.io.CA.cer");
TlsCertificatePinning.addPinnedCertificate("keyserver.ubuntu.com", getAssets(), "LetsEncryptCA.cer");
KeyserverSyncManager.updateKeyserverSyncScheduleAsync(this, false);

View file

@ -45,9 +45,6 @@ public class CloudSearch {
if (cloudPrefs.isKeyserverEnabled()) {
servers.add(HkpKeyserverClient.fromHkpKeyserverAddress(cloudPrefs.getKeyserver()));
}
if (cloudPrefs.isKeybaseEnabled()) {
servers.add(KeybaseKeyserverClient.getInstance());
}
if (cloudPrefs.isFacebookEnabled()) {
servers.add(FacebookKeyserverClient.getInstance());
}

View file

@ -77,14 +77,8 @@ public class ImportKeysList extends ArrayList<ImportKeysListEntry> {
if (incoming.getKeyserver() != null) {
existing.setKeyserver(incoming.getKeyserver());
// Mail addresses returned by HKP servers are preferred over keybase.io IDs
existing.setPrimaryUserId(incoming.getPrimaryUserId());
modified = true;
} else if (incoming.getKeybaseName() != null) {
// to work properly, Keybase-sourced/Facebook-sourced entries need to pass along the
// identifying name/id
existing.setKeybaseName(incoming.getKeybaseName());
modified = true;
} else if (incoming.getFbUsername() != null) {
existing.setFbUsername(incoming.getFbUsername());

View file

@ -17,6 +17,18 @@
package org.sufficientlysecure.keychain.keyimport;
import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import android.content.Context;
import android.os.Parcel;
import android.os.Parcelable;
@ -27,18 +39,6 @@ import org.sufficientlysecure.keychain.pgp.UncachedKeyRing;
import org.sufficientlysecure.keychain.pgp.UncachedPublicKey;
import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
public class ImportKeysListEntry implements Serializable, Parcelable {
private static final long serialVersionUID = -7797972103284992662L;
@ -64,7 +64,6 @@ public class ImportKeysListEntry implements Serializable, Parcelable {
private UserId mPrimaryUserId;
private HkpKeyserverAddress mKeyserver;
private String mKeybaseName;
private String mFbUsername;
private String mQuery;
@ -197,14 +196,6 @@ public class ImportKeysListEntry implements Serializable, Parcelable {
mKeyserver = keyserver;
}
public String getKeybaseName() {
return mKeybaseName;
}
public void setKeybaseName(String keybaseName) {
mKeybaseName = keybaseName;
}
public String getFbUsername() {
return mFbUsername;
}
@ -257,20 +248,11 @@ public class ImportKeysListEntry implements Serializable, Parcelable {
return modified;
}
public ArrayList<String> getKeybaseUserIds() {
ArrayList<String> keybaseUserIds = new ArrayList<>();
for (String s : mUserIds) {
if (s.contains(":"))
keybaseUserIds.add(s);
}
return keybaseUserIds;
}
/**
* Constructor for later querying from keyserver
*/
public ImportKeysListEntry() {
// keys from keyserver are always public keys; from keybase too
// keys from keyserver are always public keys
mSecretKey = false;
mUserIds = new ArrayList<>();
@ -339,20 +321,8 @@ public class ImportKeysListEntry implements Serializable, Parcelable {
private void sortMergedUserIds() {
mSortedUserIds = new ArrayList<>(mMergedUserIds.entrySet());
Collections.sort(mSortedUserIds, new Comparator<Map.Entry<String, HashSet<String>>>() {
@Override
public int compare(Map.Entry<String, HashSet<String>> entry1,
Map.Entry<String, HashSet<String>> entry2) {
// sort keybase UserIds after non-Keybase
boolean e1IsKeybase = entry1.getKey().contains(":");
boolean e2IsKeybase = entry2.getKey().contains(":");
if (e1IsKeybase != e2IsKeybase) {
return (e1IsKeybase) ? 1 : -1;
}
return entry1.getKey().compareTo(entry2.getKey());
}
});
Collections.sort(mSortedUserIds,
(entry1, entry2) -> entry1.getKey().compareTo(entry2.getKey()));
}
@Override
@ -377,7 +347,6 @@ public class ImportKeysListEntry implements Serializable, Parcelable {
dest.writeString(mAlgorithm);
dest.writeByte((byte) (mSecretKey ? 1 : 0));
dest.writeParcelable(mKeyserver, flags);
dest.writeString(mKeybaseName);
dest.writeString(mFbUsername);
}
@ -400,7 +369,6 @@ public class ImportKeysListEntry implements Serializable, Parcelable {
vr.mAlgorithm = source.readString();
vr.mSecretKey = source.readByte() == 1;
vr.mKeyserver = source.readParcelable(HkpKeyserverAddress.class.getClassLoader());
vr.mKeybaseName = source.readString();
vr.mFbUsername = source.readString();
return vr;

View file

@ -1,121 +0,0 @@
/*
* Copyright (C) 2017 Schürmann & Breitmoser GbR
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.sufficientlysecure.keychain.keyimport;
import com.textuality.keybase.lib.KeybaseException;
import com.textuality.keybase.lib.KeybaseQuery;
import com.textuality.keybase.lib.Match;
import com.textuality.keybase.lib.User;
import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
import org.sufficientlysecure.keychain.network.OkHttpKeybaseClient;
import org.sufficientlysecure.keychain.util.ParcelableProxy;
import timber.log.Timber;
import java.util.ArrayList;
import java.util.List;
public class KeybaseKeyserverClient implements KeyserverClient {
public static KeybaseKeyserverClient getInstance() {
return new KeybaseKeyserverClient();
}
private KeybaseKeyserverClient() { }
@Override
public ArrayList<ImportKeysListEntry> search(String query, ParcelableProxy proxy) throws QueryFailedException,
QueryNeedsRepairException {
ArrayList<ImportKeysListEntry> results = new ArrayList<>();
if (query.startsWith("0x")) {
// cut off "0x" if a user is searching for a key id
query = query.substring(2);
}
if (query.isEmpty()) {
throw new QueryTooShortException();
}
try {
KeybaseQuery keybaseQuery = new KeybaseQuery(new OkHttpKeybaseClient());
keybaseQuery.setProxy(proxy.getProxy());
Iterable<Match> matches = keybaseQuery.search(query);
for (Match match : matches) {
results.add(makeEntry(match, query));
}
} catch (KeybaseException e) {
Timber.e(e, "keybase result parsing error");
throw new QueryFailedException("Unexpected structure in keybase search result: " + e.getMessage());
}
return results;
}
private ImportKeysListEntry makeEntry(Match match, String query) throws KeybaseException {
final ImportKeysListEntry entry = new ImportKeysListEntry();
entry.setQuery(query);
entry.setRevoked(false); // keybase doesnt say anything about revoked keys
String username = match.getUsername();
String fullName = match.getFullName();
String fingerprint = match.getFingerprint();
entry.setFingerprint(KeyFormattingUtils.convertFingerprintHexFingerprint(fingerprint));
entry.setKeyIdHex("0x" + match.getKeyID());
// so we can query for the keybase id directly, and to identify the location from which the
// key is to be retrieved
entry.setKeybaseName(username);
final int bitStrength = match.getBitStrength();
entry.setBitStrength(bitStrength);
final int algorithmId = match.getAlgorithmId();
entry.setAlgorithm(KeyFormattingUtils.getAlgorithmInfo(algorithmId, bitStrength, null));
ArrayList<String> userIds = new ArrayList<>();
String name = "<keybase.io/" + username + ">";
if (fullName != null) {
name = fullName + " " + name;
}
userIds.add(name);
List<String> proofLabels = match.getProofLabels();
for (String proofLabel : proofLabels) {
userIds.add(proofLabel);
}
entry.setUserIds(userIds);
entry.setPrimaryUserId(name);
return entry;
}
@Override
public String get(String id, ParcelableProxy proxy) throws QueryFailedException {
try {
KeybaseQuery keybaseQuery = new KeybaseQuery(new OkHttpKeybaseClient());
keybaseQuery.setProxy(proxy.getProxy());
return User.keyForUsername(keybaseQuery, id);
} catch (KeybaseException e) {
throw new QueryFailedException(e.getMessage());
}
}
@Override
public void add(String armoredKey, ParcelableProxy proxy) throws AddKeyException {
throw new AddKeyException();
}
}

View file

@ -26,7 +26,7 @@ import com.google.auto.value.AutoValue;
/**
* This class is a parcelable representation of either a keyring as raw data,
* or a (unique) reference to one as a fingerprint, keyid, or keybase name.
* or a (unique) reference to one as a fingerprint, or keyid.
*/
@AutoValue
public abstract class ParcelableKeyRing implements Parcelable {
@ -41,16 +41,14 @@ public abstract class ParcelableKeyRing implements Parcelable {
@Nullable
public abstract String getKeyIdHex();
@Nullable
public abstract String getKeybaseName();
@Nullable
public abstract String getFbUsername();
public static ParcelableKeyRing createFromEncodedBytes(byte[] bytes) {
return new AutoValue_ParcelableKeyRing(bytes, null, null, null, null);
return new AutoValue_ParcelableKeyRing(bytes, null, null, null);
}
public static ParcelableKeyRing createFromReference(
byte[] expectedFingerprint, String keyIdHex, String keybaseName, String fbUsername) {
return new AutoValue_ParcelableKeyRing(null, expectedFingerprint, keyIdHex, keybaseName, fbUsername);
byte[] expectedFingerprint, String keyIdHex, String fbUsername) {
return new AutoValue_ParcelableKeyRing(null, expectedFingerprint, keyIdHex, fbUsername);
}
}

View file

@ -51,8 +51,7 @@ public class ImportKeysListCloudLoader
*
* @param loaderState state containing the string to search on servers for (if it is a
* fingerprint, will enforce fingerprint check) and the keyserver to
* search on (whether to search on the keyserver, and whether to search
* keybase.io)
* search on (whether to search on the keyserver)
* @param parcelableProxy explicit proxy to use. If null, will retrieve from preferences
*/
public ImportKeysListCloudLoader(Context context, CloudLoaderState loaderState,
@ -84,7 +83,7 @@ public class ImportKeysListCloudLoader
for (ImportKeysListEntry e : mEntryList) {
if (e.getParcelableKeyRing() == null) {
e.setParcelableKeyRing(ParcelableKeyRing.createFromReference(e.getFingerprint(), e.getKeyIdHex(),
e.getKeybaseName(), e.getFbUsername()));
e.getFbUsername()));
}
}

View file

@ -1,55 +0,0 @@
/*
* Copyright (C) 2017 Schürmann & Breitmoser GbR
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.sufficientlysecure.keychain.network;
import java.io.IOException;
import java.net.Proxy;
import java.net.URL;
import com.textuality.keybase.lib.KeybaseUrlConnectionClient;
import okhttp3.OkHttpClient;
import okhttp3.Request;
/**
* Wrapper for Keybase Lib
*/
public class OkHttpKeybaseClient implements KeybaseUrlConnectionClient {
@Override
public Response getUrlResponse(URL url, Proxy proxy, boolean isKeybase) throws IOException {
OkHttpClient client;
if (proxy != null) {
client = OkHttpClientFactory.getClientPinnedIfAvailable(url, proxy);
} else {
client = OkHttpClientFactory.getSimpleClient();
}
Request request = new Request.Builder()
.url(url).build();
okhttp3.Response okResponse = client.newCall(request).execute();
return new Response(okResponse.body().byteStream(), okResponse.code(), okResponse.message(), okResponse.headers().toMultimap());
}
@Override
public String getKeybaseBaseUrl() {
return "https://api.keybase.io/";
}
}

View file

@ -41,7 +41,6 @@ import org.sufficientlysecure.keychain.daos.KeyWritableRepository;
import org.sufficientlysecure.keychain.keyimport.FacebookKeyserverClient;
import org.sufficientlysecure.keychain.keyimport.HkpKeyserverAddress;
import org.sufficientlysecure.keychain.keyimport.HkpKeyserverClient;
import org.sufficientlysecure.keychain.keyimport.KeybaseKeyserverClient;
import org.sufficientlysecure.keychain.keyimport.KeyserverClient;
import org.sufficientlysecure.keychain.keyimport.KeyserverClient.QueryNotFoundException;
import org.sufficientlysecure.keychain.keyimport.ParcelableKeyRing;
@ -76,8 +75,7 @@ import timber.log.Timber;
* all steps for this import.
* For the import operation, the only valid source is an Iterator of
* ParcelableKeyRing, each of which must contain either a single
* keyring encoded as bytes, or a unique reference to a keyring
* on keyservers and/or keybase.io.
* keyring encoded as bytes, or a unique reference to a keyring on keyservers.
* It is important to note that public keys should generally be imported before
* secret keys, because some implementations (notably Symantec PGP Desktop) do
* not include self certificates for user ids in the secret keyring. The import
@ -93,7 +91,6 @@ public class ImportOperation extends BaseReadWriteOperation<ImportKeyringParcel>
private final KeyMetadataDao keyMetadataDao;
private FacebookKeyserverClient facebookServer;
private KeybaseKeyserverClient keybaseServer;
public ImportOperation(Context context, KeyWritableRepository databaseInteractor, Progressable progressable) {
super(context, databaseInteractor, progressable);
@ -355,14 +352,6 @@ public class ImportOperation extends BaseReadWriteOperation<ImportKeyringParcel>
}
}
boolean hasKeybaseName = entry.getKeybaseName() != null;
if (hasKeybaseName) {
UncachedKeyRing keybaseKey = fetchKeyFromKeybase(proxy, log, entry);
if (keybaseKey != null) {
key = mergeKeysOrUseEither(log, 3, key, keybaseKey);
}
}
boolean hasFacebookName = entry.getFbUsername() != null;
if (hasFacebookName) {
UncachedKeyRing facebookKey = fetchKeyFromFacebook(proxy, log, entry);
@ -414,32 +403,6 @@ public class ImportOperation extends BaseReadWriteOperation<ImportKeyringParcel>
}
}
private UncachedKeyRing fetchKeyFromKeybase(@NonNull ParcelableProxy proxy, OperationLog log, ParcelableKeyRing entry)
throws PgpGeneralException, IOException {
if (keybaseServer == null) {
keybaseServer = KeybaseKeyserverClient.getInstance();
}
try {
log.add(LogType.MSG_IMPORT_FETCH_KEYBASE, 2, entry.getKeybaseName());
byte[] data = keybaseServer.get(entry.getKeybaseName(), proxy).getBytes();
UncachedKeyRing keybaseKey = UncachedKeyRing.decodeFromData(data);
if (keybaseKey != null) {
log.add(LogType.MSG_IMPORT_FETCH_KEYSERVER_OK, 3);
} else {
log.add(LogType.MSG_IMPORT_FETCH_ERROR_DECODE, 3);
}
return keybaseKey;
} catch (KeyserverClient.QueryFailedException e) {
// download failed, too bad. just proceed
Timber.e(e, "query failed");
log.add(LogType.MSG_IMPORT_FETCH_ERROR_KEYSERVER, 3, e.getMessage());
return null;
}
}
private UncachedKeyRing fetchKeyFromFacebook(@NonNull ParcelableProxy proxy, OperationLog log, ParcelableKeyRing entry)
throws PgpGeneralException, IOException {
if (facebookServer == null) {

View file

@ -72,7 +72,7 @@ public class KeySyncOperation extends BaseReadWriteOperation<KeySyncParcel> {
ArrayList<ParcelableKeyRing> result = new ArrayList<>(staleKeyFingerprints.size());
for (byte[] fingerprint : staleKeyFingerprints) {
Timber.d("Keyserver sync: Updating %s", KeyFormattingUtils.beautifyKeyId(fingerprint));
result.add(ParcelableKeyRing.createFromReference(fingerprint, null, null, null));
result.add(ParcelableKeyRing.createFromReference(fingerprint, null, null));
}
return result;
}

View file

@ -1,188 +0,0 @@
/*
* Copyright (C) 2017 Schürmann & Breitmoser GbR
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.sufficientlysecure.keychain.operations;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.net.Proxy;
import java.util.ArrayList;
import java.util.List;
import android.content.Context;
import android.support.annotation.NonNull;
import com.textuality.keybase.lib.KeybaseQuery;
import com.textuality.keybase.lib.Proof;
import com.textuality.keybase.lib.prover.Prover;
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.Data;
import de.measite.minidns.record.TXT;
import org.bouncycastle.openpgp.PGPUtil;
import org.json.JSONObject;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.network.OkHttpKeybaseClient;
import org.sufficientlysecure.keychain.network.orbot.OrbotHelper;
import org.sufficientlysecure.keychain.operations.results.DecryptVerifyResult;
import org.sufficientlysecure.keychain.operations.results.KeybaseVerificationResult;
import org.sufficientlysecure.keychain.operations.results.OperationResult;
import org.sufficientlysecure.keychain.operations.results.OperationResult.LogType;
import org.sufficientlysecure.keychain.pgp.PgpDecryptVerifyInputParcel;
import org.sufficientlysecure.keychain.pgp.PgpDecryptVerifyOperation;
import org.sufficientlysecure.keychain.pgp.Progressable;
import org.sufficientlysecure.keychain.daos.KeyWritableRepository;
import org.sufficientlysecure.keychain.service.KeybaseVerificationParcel;
import org.sufficientlysecure.keychain.service.input.CryptoInputParcel;
import org.sufficientlysecure.keychain.service.input.RequiredInputParcel;
import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
import org.sufficientlysecure.keychain.util.Preferences;
public class KeybaseVerificationOperation extends BaseOperation<KeybaseVerificationParcel> {
public KeybaseVerificationOperation(Context context, KeyWritableRepository databaseInteractor,
Progressable progressable) {
super(context, databaseInteractor, progressable);
}
@NonNull
@Override
public KeybaseVerificationResult execute(KeybaseVerificationParcel keybaseInput,
CryptoInputParcel cryptoInput) {
Proxy proxy;
if (cryptoInput.getParcelableProxy() == null) {
// explicit proxy not set
if (!OrbotHelper.isOrbotInRequiredState(mContext)) {
return new KeybaseVerificationResult(null,
RequiredInputParcel.createOrbotRequiredOperation(), cryptoInput);
}
proxy = Preferences.getPreferences(mContext).getParcelableProxy().getProxy();
} else {
proxy = cryptoInput.getParcelableProxy().getProxy();
}
String requiredFingerprint = keybaseInput.mRequiredFingerprint;
OperationResult.OperationLog log = new OperationResult.OperationLog();
log.add(OperationResult.LogType.MSG_KEYBASE_VERIFICATION, 0, requiredFingerprint);
try {
KeybaseQuery keybaseQuery = new KeybaseQuery(new OkHttpKeybaseClient());
keybaseQuery.setProxy(proxy);
String keybaseProof = keybaseInput.mKeybaseProof;
Proof proof = new Proof(new JSONObject(keybaseProof));
mProgressable.setProgress(R.string.keybase_message_fetching_data, 0, 100);
Prover prover = Prover.findProverFor(proof);
if (prover == null) {
log.add(OperationResult.LogType.MSG_KEYBASE_ERROR_NO_PROVER, 1,
proof.getPrettyName());
return new KeybaseVerificationResult(OperationResult.RESULT_ERROR, log);
}
if (!prover.fetchProofData(keybaseQuery)) {
log.add(OperationResult.LogType.MSG_KEYBASE_ERROR_FETCH_PROOF, 1);
return new KeybaseVerificationResult(OperationResult.RESULT_ERROR, log);
}
if (!prover.checkFingerprint(requiredFingerprint)) {
log.add(OperationResult.LogType.MSG_KEYBASE_ERROR_FINGERPRINT_MISMATCH, 1);
return new KeybaseVerificationResult(OperationResult.RESULT_ERROR, log);
}
String domain = prover.dnsTxtCheckRequired();
if (domain != null) {
DNSMessage dnsQuery = new Client().query(new Question(domain, Record.TYPE.TXT));
if (dnsQuery == null) {
log.add(OperationResult.LogType.MSG_KEYBASE_ERROR_DNS_FAIL, 1);
log.add(OperationResult.LogType.MSG_KEYBASE_ERROR_SPECIFIC, 2,
getFlattenedProverLog(prover));
return new KeybaseVerificationResult(OperationResult.RESULT_ERROR, log);
}
Record[] records = dnsQuery.getAnswers();
List<List<byte[]>> extents = new ArrayList<>();
for (Record r : records) {
Data d = r.getPayload();
if (d instanceof TXT) {
extents.add(((TXT) d).getExtents());
}
}
if (!prover.checkDnsTxt(extents)) {
log.add(OperationResult.LogType.MSG_KEYBASE_ERROR_SPECIFIC, 1,
getFlattenedProverLog(prover));
return new KeybaseVerificationResult(OperationResult.RESULT_ERROR, log);
}
}
byte[] messageBytes = prover.getPgpMessage().getBytes();
if (prover.rawMessageCheckRequired()) {
InputStream messageByteStream = PGPUtil.getDecoderStream(new
ByteArrayInputStream
(messageBytes));
if (!prover.checkRawMessageBytes(messageByteStream)) {
log.add(OperationResult.LogType.MSG_KEYBASE_ERROR_SPECIFIC, 1,
getFlattenedProverLog(prover));
return new KeybaseVerificationResult(OperationResult.RESULT_ERROR, log);
}
}
PgpDecryptVerifyOperation op = new PgpDecryptVerifyOperation(mContext, mKeyRepository, mProgressable);
PgpDecryptVerifyInputParcel input = PgpDecryptVerifyInputParcel.builder()
.setInputBytes(messageBytes)
.build();
DecryptVerifyResult decryptVerifyResult = op.execute(input, CryptoInputParcel.createCryptoInputParcel());
if (!decryptVerifyResult.success()) {
log.add(decryptVerifyResult, 1);
return new KeybaseVerificationResult(OperationResult.RESULT_ERROR, log);
}
long verifyingKeyId = decryptVerifyResult.getSignatureResult().getKeyId();
byte[] verifyingFingerprint = mKeyRepository.getFingerprintByKeyId(verifyingKeyId);
if (!requiredFingerprint.equals(KeyFormattingUtils.convertFingerprintToHex(verifyingFingerprint))) {
log.add(LogType.MSG_KEYBASE_ERROR_FINGERPRINT_MISMATCH, 1);
return new KeybaseVerificationResult(OperationResult.RESULT_ERROR, log);
}
if (!prover.validate(new String(decryptVerifyResult.getOutputBytes()))) {
log.add(OperationResult.LogType.MSG_KEYBASE_ERROR_PAYLOAD_MISMATCH, 1);
return new KeybaseVerificationResult(OperationResult.RESULT_ERROR, log);
}
return new KeybaseVerificationResult(OperationResult.RESULT_OK, log, prover);
} catch (Exception e) {
// just adds the passed parameter, in this case e.getMessage()
log.add(OperationResult.LogType.MSG_KEYBASE_ERROR_SPECIFIC, 1, e.getMessage());
return new KeybaseVerificationResult(OperationResult.RESULT_ERROR, log);
}
}
private String getFlattenedProverLog(Prover prover) {
String log = "";
for (String line : prover.getLog()) {
log += line + "\n";
}
return log;
}
}

View file

@ -1,87 +0,0 @@
/*
* Copyright (C) 2017 Schürmann & Breitmoser GbR
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.sufficientlysecure.keychain.operations.results;
import android.os.Parcel;
import android.os.Parcelable;
import com.textuality.keybase.lib.KeybaseException;
import com.textuality.keybase.lib.prover.Prover;
import org.sufficientlysecure.keychain.service.input.CryptoInputParcel;
import org.sufficientlysecure.keychain.service.input.RequiredInputParcel;
public class KeybaseVerificationResult extends InputPendingResult {
public final String mProofUrl;
public final String mPresenceUrl;
public final String mPresenceLabel;
public KeybaseVerificationResult(int result, OperationLog log) {
super(result, log);
mProofUrl = null;
mPresenceLabel = null;
mPresenceUrl = null;
}
public KeybaseVerificationResult(int result, OperationLog log, Prover prover)
throws KeybaseException {
super(result, log);
mProofUrl = prover.getProofUrl();
mPresenceUrl = prover.getPresenceUrl();
mPresenceLabel = prover.getPresenceLabel();
}
public KeybaseVerificationResult(OperationLog log, RequiredInputParcel requiredInputParcel,
CryptoInputParcel cryptoInputParcel) {
super(log, requiredInputParcel, cryptoInputParcel);
mProofUrl = null;
mPresenceUrl = null;
mPresenceLabel = null;
}
protected KeybaseVerificationResult(Parcel in) {
super(in);
mProofUrl = in.readString();
mPresenceUrl = in.readString();
mPresenceLabel = in.readString();
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
super.writeToParcel(dest, flags);
dest.writeString(mProofUrl);
dest.writeString(mPresenceUrl);
dest.writeString(mPresenceLabel);
}
public static final Parcelable.Creator<KeybaseVerificationResult> CREATOR = new Parcelable.Creator<KeybaseVerificationResult>() {
@Override
public KeybaseVerificationResult createFromParcel(Parcel in) {
return new KeybaseVerificationResult(in);
}
@Override
public KeybaseVerificationResult[] newArray(int size) {
return new KeybaseVerificationResult[size];
}
};
}

View file

@ -756,7 +756,6 @@ public abstract class OperationResult implements Parcelable {
MSG_IMPORT_FETCH_ERROR_NOT_FOUND (LogLevel.ERROR, R.string.msg_import_fetch_error_not_found),
MSG_IMPORT_FETCH_ERROR_KEYSERVER(LogLevel.ERROR, R.string.msg_import_fetch_error_keyserver),
MSG_IMPORT_FETCH_ERROR_KEYSERVER_SECRET (LogLevel.ERROR, R.string.msg_import_fetch_error_keyserver_secret),
MSG_IMPORT_FETCH_KEYBASE (LogLevel.INFO, R.string.msg_import_fetch_keybase),
MSG_IMPORT_FETCH_FACEBOOK (LogLevel.INFO, R.string.msg_import_fetch_facebook),
MSG_IMPORT_FETCH_KEYSERVER (LogLevel.INFO, R.string.msg_import_fetch_keyserver),
MSG_IMPORT_FETCH_KEYSERVER_OK (LogLevel.DEBUG, R.string.msg_import_fetch_keyserver_ok),
@ -820,18 +819,6 @@ public abstract class OperationResult implements Parcelable {
MSG_REVOKE_ERROR_KEY_FAIL (LogLevel.ERROR, R.string.msg_revoke_key_fail),
MSG_REVOKE_OK (LogLevel.OK, R.string.msg_revoke_ok),
// keybase verification
MSG_KEYBASE_VERIFICATION(LogLevel.START, R.string.msg_keybase_verification),
MSG_KEYBASE_ERROR_NO_PROVER(LogLevel.ERROR, R.string.msg_keybase_error_no_prover),
MSG_KEYBASE_ERROR_FETCH_PROOF(LogLevel.ERROR, R.string.msg_keybase_error_fetching_evidence),
MSG_KEYBASE_ERROR_FINGERPRINT_MISMATCH(LogLevel.ERROR,
R.string.msg_keybase_error_key_mismatch),
MSG_KEYBASE_ERROR_DNS_FAIL(LogLevel.ERROR, R.string.msg_keybase_error_dns_fail),
MSG_KEYBASE_ERROR_SPECIFIC(LogLevel.ERROR, R.string.msg_keybase_error_specific),
MSG_KEYBASE_ERROR_PAYLOAD_MISMATCH(LogLevel.ERROR,
R.string.msg_keybase_error_msg_payload_mismatch),
// InputData Operation
MSG_DATA (LogLevel.START, R.string.msg_data),
MSG_DATA_OPENPGP (LogLevel.DEBUG, R.string.msg_data_openpgp),

View file

@ -1,60 +0,0 @@
/*
* Copyright (C) 2017 Schürmann & Breitmoser GbR
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.sufficientlysecure.keychain.service;
import android.os.Parcel;
import android.os.Parcelable;
public class KeybaseVerificationParcel implements Parcelable {
public String mKeybaseProof;
public String mRequiredFingerprint;
public KeybaseVerificationParcel(String keybaseProof, String requiredFingerprint) {
mKeybaseProof = keybaseProof;
mRequiredFingerprint = requiredFingerprint;
}
protected KeybaseVerificationParcel(Parcel in) {
mKeybaseProof = in.readString();
mRequiredFingerprint = in.readString();
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(mKeybaseProof);
dest.writeString(mRequiredFingerprint);
}
public static final Parcelable.Creator<KeybaseVerificationParcel> CREATOR = new Parcelable.Creator<KeybaseVerificationParcel>() {
@Override
public KeybaseVerificationParcel createFromParcel(Parcel in) {
return new KeybaseVerificationParcel(in);
}
@Override
public KeybaseVerificationParcel[] newArray(int size) {
return new KeybaseVerificationParcel[size];
}
};
}

View file

@ -41,7 +41,6 @@ import org.sufficientlysecure.keychain.operations.ImportOperation;
import org.sufficientlysecure.keychain.operations.InputDataOperation;
import org.sufficientlysecure.keychain.operations.KeySyncOperation;
import org.sufficientlysecure.keychain.operations.KeySyncParcel;
import org.sufficientlysecure.keychain.operations.KeybaseVerificationOperation;
import org.sufficientlysecure.keychain.operations.PromoteKeyOperation;
import org.sufficientlysecure.keychain.operations.RevokeOperation;
import org.sufficientlysecure.keychain.operations.SignEncryptOperation;
@ -114,8 +113,6 @@ public class KeychainServiceTask {
} else if (inputParcel instanceof UploadKeyringParcel) {
op = new UploadOperation(context, keyRepository, asyncProgressable,
operationCancelledBoolean);
} else if (inputParcel instanceof KeybaseVerificationParcel) {
op = new KeybaseVerificationOperation(context, keyRepository, asyncProgressable);
} else if (inputParcel instanceof InputDataParcel) {
op = new InputDataOperation(context, keyRepository, asyncProgressable);
} else if (inputParcel instanceof BenchmarkInputParcel) {

View file

@ -138,7 +138,7 @@ public abstract class DecryptFragment extends Fragment {
{
ParcelableKeyRing keyEntry = ParcelableKeyRing.createFromReference(null,
KeyFormattingUtils.convertKeyIdToHex(unknownKeyId), null, null);
KeyFormattingUtils.convertKeyIdToHex(unknownKeyId), null);
ArrayList<ParcelableKeyRing> selectedEntries = new ArrayList<>();
selectedEntries.add(keyEntry);

View file

@ -769,7 +769,7 @@ public class DecryptListFragment
{
ParcelableKeyRing keyEntry = ParcelableKeyRing.createFromReference(null,
KeyFormattingUtils.convertKeyIdToHex(unknownKeyId), null, null);
KeyFormattingUtils.convertKeyIdToHex(unknownKeyId), null);
ArrayList<ParcelableKeyRing> selectedEntries = new ArrayList<>();
selectedEntries.add(keyEntry);

View file

@ -223,7 +223,7 @@ public class ImportKeysProxyActivity extends FragmentActivity
}
public void importKeysFromFingerprint(byte[] fingerprint) {
ParcelableKeyRing keyEntry = ParcelableKeyRing.createFromReference(fingerprint, null, null, null);
ParcelableKeyRing keyEntry = ParcelableKeyRing.createFromReference(fingerprint, null, null);
ArrayList<ParcelableKeyRing> selectedEntries = new ArrayList<>();
selectedEntries.add(keyEntry);

View file

@ -1,465 +0,0 @@
/*
* Copyright (C) 2017 Schürmann & Breitmoser GbR
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.sufficientlysecure.keychain.ui;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;
import android.arch.lifecycle.ViewModelProviders;
import android.content.Intent;
import android.graphics.Typeface;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.Fragment;
import android.text.SpannableStringBuilder;
import android.text.Spanned;
import android.text.method.LinkMovementMethod;
import android.text.style.ClickableSpan;
import android.text.style.StyleSpan;
import android.text.style.URLSpan;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TableLayout;
import android.widget.TableRow;
import android.widget.TextView;
import com.textuality.keybase.lib.KeybaseException;
import com.textuality.keybase.lib.KeybaseQuery;
import com.textuality.keybase.lib.Proof;
import com.textuality.keybase.lib.User;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.model.SubKey.UnifiedKeyInfo;
import org.sufficientlysecure.keychain.network.OkHttpKeybaseClient;
import org.sufficientlysecure.keychain.network.orbot.OrbotHelper;
import org.sufficientlysecure.keychain.operations.results.KeybaseVerificationResult;
import org.sufficientlysecure.keychain.service.KeybaseVerificationParcel;
import org.sufficientlysecure.keychain.ui.base.CryptoOperationHelper;
import org.sufficientlysecure.keychain.ui.keyview.UnifiedKeyInfoViewModel;
import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
import org.sufficientlysecure.keychain.util.ParcelableProxy;
import org.sufficientlysecure.keychain.util.Preferences;
public class ViewKeyKeybaseFragment extends Fragment implements
CryptoOperationHelper.Callback<KeybaseVerificationParcel, KeybaseVerificationResult> {
private TextView mReportHeader;
private TableLayout mProofListing;
private LayoutInflater mInflater;
private View mProofVerifyHeader;
private TextView mProofVerifyDetail;
private Proof mProof;
// for CryptoOperationHelper,Callback
private String mKeybaseProof;
private String mKeybaseFingerprint;
private CryptoOperationHelper<KeybaseVerificationParcel, KeybaseVerificationResult> mKeybaseOpHelper;
/**
* Creates new instance of this fragment
*/
public static ViewKeyKeybaseFragment newInstance() {
return new ViewKeyKeybaseFragment();
}
@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup viewGroup, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.view_key_adv_keybase_fragment, viewGroup, false);
mInflater = inflater;
mReportHeader = view.findViewById(R.id.view_key_trust_cloud_narrative);
mProofListing = view.findViewById(R.id.view_key_proof_list);
mProofVerifyHeader = view.findViewById(R.id.view_key_proof_verify_header);
mProofVerifyDetail = view.findViewById(R.id.view_key_proof_verify_detail);
mReportHeader.setVisibility(View.GONE);
mProofListing.setVisibility(View.GONE);
mProofVerifyHeader.setVisibility(View.GONE);
mProofVerifyDetail.setVisibility(View.GONE);
return view;
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
UnifiedKeyInfoViewModel viewKeyViewModel = ViewModelProviders.of(requireActivity()).get(UnifiedKeyInfoViewModel.class);
viewKeyViewModel.getUnifiedKeyInfoLiveData(requireContext()).observe(this, this::onLoadUnifiedKeyInfo);
}
private void onLoadUnifiedKeyInfo(UnifiedKeyInfo unifiedKeyInfo) {
if (unifiedKeyInfo == null) {
return;
}
String fingerprint = KeyFormattingUtils.convertFingerprintToHex(unifiedKeyInfo.fingerprint());
startSearch(fingerprint);
}
private void startSearch(final String fingerprint) {
final ParcelableProxy parcelableProxy =
Preferences.getPreferences(getActivity()).getParcelableProxy();
OrbotHelper.DialogActions dialogActions = new OrbotHelper.DialogActions() {
@Override
public void onOrbotStarted() {
new DescribeKey(parcelableProxy).execute(fingerprint);
}
@Override
public void onNeutralButton() {
new DescribeKey(ParcelableProxy.getForNoProxy())
.execute(fingerprint);
}
@Override
public void onCancel() {
}
};
if (OrbotHelper.putOrbotInRequiredState(dialogActions, getActivity())) {
new DescribeKey(parcelableProxy).execute(fingerprint);
}
}
class ResultPage {
String mHeader;
final List<CharSequence> mProofs;
ResultPage(String header, List<CharSequence> proofs) {
mHeader = header;
mProofs = proofs;
}
}
/**
* look for evidence from keybase in the background, make tabular version of result
*/
private class DescribeKey extends AsyncTask<String, Void, ResultPage> {
ParcelableProxy mParcelableProxy;
DescribeKey(ParcelableProxy parcelableProxy) {
mParcelableProxy = parcelableProxy;
}
@Override
protected ResultPage doInBackground(String... args) {
String fingerprint = args[0];
final ArrayList<CharSequence> proofList = new ArrayList<>();
final Hashtable<Integer, ArrayList<Proof>> proofs = new Hashtable<>();
try {
KeybaseQuery keybaseQuery = new KeybaseQuery(new OkHttpKeybaseClient());
keybaseQuery.setProxy(mParcelableProxy.getProxy());
User keybaseUser = User.findByFingerprint(keybaseQuery, fingerprint);
for (Proof proof : keybaseUser.getProofs()) {
Integer proofType = proof.getType();