Preparations for support of onion keyservers. Refactoring of Keyserver and proxy related classes

This commit is contained in:
Dominik Schürmann
2016-10-27 16:19:43 +02:00
parent bf382ec59d
commit 911fa020c2
37 changed files with 576 additions and 479 deletions

View File

@@ -39,9 +39,9 @@ import android.support.annotation.NonNull;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.keyimport.FacebookKeyserver;
import org.sufficientlysecure.keychain.keyimport.HkpKeyserver;
import org.sufficientlysecure.keychain.keyimport.KeybaseKeyserver;
import org.sufficientlysecure.keychain.keyimport.Keyserver;
import org.sufficientlysecure.keychain.keyimport.ParcelableHkpKeyserver;
import org.sufficientlysecure.keychain.keyimport.ParcelableKeyRing;
import org.sufficientlysecure.keychain.operations.results.ConsolidateResult;
import org.sufficientlysecure.keychain.operations.results.ImportKeyResult;
@@ -60,6 +60,7 @@ import org.sufficientlysecure.keychain.service.input.RequiredInputParcel;
import org.sufficientlysecure.keychain.util.Log;
import org.sufficientlysecure.keychain.util.ParcelableFileCache;
import org.sufficientlysecure.keychain.util.ParcelableFileCache.IteratorWithSize;
import org.sufficientlysecure.keychain.util.ParcelableProxy;
import org.sufficientlysecure.keychain.util.Preferences;
import org.sufficientlysecure.keychain.util.ProgressScaler;
import org.sufficientlysecure.keychain.util.orbot.OrbotHelper;
@@ -83,7 +84,7 @@ import org.sufficientlysecure.keychain.util.orbot.OrbotHelper;
*/
public class ImportOperation extends BaseOperation<ImportKeyringParcel> {
public static final int MAX_THREADS = 10;
private static final int MAX_THREADS = 10;
public ImportOperation(Context context, ProviderHelper providerHelper, Progressable
progressable) {
@@ -97,20 +98,20 @@ public class ImportOperation extends BaseOperation<ImportKeyringParcel> {
// Overloaded functions for using progressable supplied in constructor during import
public ImportKeyResult serialKeyRingImport(Iterator<ParcelableKeyRing> entries, int num,
String keyServerUri, Proxy proxy) {
return serialKeyRingImport(entries, num, keyServerUri, mProgressable, proxy);
ParcelableHkpKeyserver hkpKeyserver, ParcelableProxy proxy) {
return serialKeyRingImport(entries, num, hkpKeyserver, mProgressable, proxy);
}
@NonNull
private ImportKeyResult serialKeyRingImport(ParcelableFileCache<ParcelableKeyRing> cache,
String keyServerUri, Proxy proxy) {
ParcelableHkpKeyserver hkpKeyserver, ParcelableProxy proxy) {
// get entries from cached file
try {
IteratorWithSize<ParcelableKeyRing> it = cache.readCache();
int numEntries = it.getSize();
return serialKeyRingImport(it, numEntries, keyServerUri, mProgressable, proxy);
return serialKeyRingImport(it, numEntries, hkpKeyserver, mProgressable, proxy);
} catch (IOException e) {
// Special treatment here, we need a lot
@@ -129,14 +130,14 @@ public class ImportOperation extends BaseOperation<ImportKeyringParcel> {
*
* @param entries keys to import
* @param num number of keys to import
* @param keyServerUri contains uri of keyserver to import from, if it is an import from cloud
* @param hkpKeyserver contains uri of keyserver to import from, if it is an import from cloud
* @param progressable Allows multi-threaded import to supply a progressable that ignores the
* progress of a single key being imported
*/
@NonNull
private ImportKeyResult serialKeyRingImport(Iterator<ParcelableKeyRing> entries, int num,
String keyServerUri, Progressable progressable,
@NonNull Proxy proxy) {
ParcelableHkpKeyserver hkpKeyserver, Progressable progressable,
@NonNull ParcelableProxy proxy) {
if (progressable != null) {
progressable.setProgress(R.string.progress_importing, 0, 100);
}
@@ -158,7 +159,7 @@ public class ImportOperation extends BaseOperation<ImportKeyringParcel> {
KeybaseKeyserver keybaseServer = null;
FacebookKeyserver facebookServer = null;
HkpKeyserver keyServer = null;
ParcelableHkpKeyserver keyServer = null;
// iterate over all entries
while (entries.hasNext()) {
@@ -187,12 +188,12 @@ public class ImportOperation extends BaseOperation<ImportKeyringParcel> {
// If we have a keyServerUri and a fingerprint or at least a keyId,
// download from HKP
if (keyServerUri != null
if (hkpKeyserver != null
&& (entry.mKeyIdHex != null || entry.mExpectedFingerprint != null)) {
// Make sure we have the keyserver instance cached
if (keyServer == null) {
log.add(LogType.MSG_IMPORT_KEYSERVER, 1, keyServerUri);
keyServer = new HkpKeyserver(keyServerUri, proxy);
log.add(LogType.MSG_IMPORT_KEYSERVER, 1, hkpKeyserver);
keyServer = hkpKeyserver;
}
try {
@@ -201,10 +202,10 @@ public class ImportOperation extends BaseOperation<ImportKeyringParcel> {
if (entry.mExpectedFingerprint != null) {
log.add(LogType.MSG_IMPORT_FETCH_KEYSERVER, 2, "0x" +
entry.mExpectedFingerprint.substring(24));
data = keyServer.get("0x" + entry.mExpectedFingerprint).getBytes();
data = keyServer.get("0x" + entry.mExpectedFingerprint, proxy).getBytes();
} else {
log.add(LogType.MSG_IMPORT_FETCH_KEYSERVER, 2, entry.mKeyIdHex);
data = keyServer.get(entry.mKeyIdHex).getBytes();
data = keyServer.get(entry.mKeyIdHex, proxy).getBytes();
}
key = UncachedKeyRing.decodeFromData(data);
if (key != null) {
@@ -222,12 +223,12 @@ public class ImportOperation extends BaseOperation<ImportKeyringParcel> {
if (entry.mKeybaseName != null) {
// Make sure we have this cached
if (keybaseServer == null) {
keybaseServer = new KeybaseKeyserver(proxy);
keybaseServer = new KeybaseKeyserver();
}
try {
log.add(LogType.MSG_IMPORT_FETCH_KEYBASE, 2, entry.mKeybaseName);
byte[] data = keybaseServer.get(entry.mKeybaseName).getBytes();
byte[] data = keybaseServer.get(entry.mKeybaseName, proxy).getBytes();
UncachedKeyRing keybaseKey = UncachedKeyRing.decodeFromData(data);
if (keybaseKey != null) {
@@ -260,12 +261,12 @@ public class ImportOperation extends BaseOperation<ImportKeyringParcel> {
if (entry.mFbUsername != null) {
// Make sure we have this cached
if (facebookServer == null) {
facebookServer = new FacebookKeyserver(proxy);
facebookServer = new FacebookKeyserver();
}
try {
log.add(LogType.MSG_IMPORT_FETCH_FACEBOOK, 2, entry.mFbUsername);
byte[] data = facebookServer.get(entry.mFbUsername).getBytes();
byte[] data = facebookServer.get(entry.mFbUsername, proxy).getBytes();
UncachedKeyRing facebookKey = UncachedKeyRing.decodeFromData(data);
if (facebookKey != null) {
@@ -425,7 +426,7 @@ public class ImportOperation extends BaseOperation<ImportKeyringParcel> {
@Override
public ImportKeyResult execute(ImportKeyringParcel importInput, CryptoInputParcel cryptoInput) {
ArrayList<ParcelableKeyRing> keyList = importInput.mKeyList;
String keyServer = importInput.mKeyserver;
ParcelableHkpKeyserver keyServer = importInput.mKeyserver;
ImportKeyResult result;
@@ -435,7 +436,7 @@ public class ImportOperation extends BaseOperation<ImportKeyringParcel> {
result = serialKeyRingImport(cache, null, null);
} else {
Proxy proxy;
ParcelableProxy proxy;
if (cryptoInput.getParcelableProxy() == null) {
// explicit proxy not set
if(!OrbotHelper.isOrbotInRequiredState(mContext)) {
@@ -443,9 +444,9 @@ public class ImportOperation extends BaseOperation<ImportKeyringParcel> {
return new ImportKeyResult(null,
RequiredInputParcel.createOrbotRequiredOperation(), cryptoInput);
}
proxy = Preferences.getPreferences(mContext).getProxyPrefs().getProxy();
proxy = Preferences.getPreferences(mContext).getParcelableProxy();
} else {
proxy = cryptoInput.getParcelableProxy().getProxy();
proxy = cryptoInput.getParcelableProxy();
}
result = multiThreadedKeyImport(keyList.iterator(), keyList.size(), keyServer, proxy);
@@ -457,8 +458,8 @@ public class ImportOperation extends BaseOperation<ImportKeyringParcel> {
@NonNull
private ImportKeyResult multiThreadedKeyImport(@NonNull Iterator<ParcelableKeyRing> keyListIterator,
int totKeys, final String keyServer,
final Proxy proxy) {
int totKeys, final ParcelableHkpKeyserver hkpKeyserver,
final ParcelableProxy proxy) {
Log.d(Constants.TAG, "Multi-threaded key import starting");
KeyImportAccumulator accumulator = new KeyImportAccumulator(totKeys, mProgressable);
@@ -487,7 +488,7 @@ public class ImportOperation extends BaseOperation<ImportKeyringParcel> {
ArrayList<ParcelableKeyRing> list = new ArrayList<>();
list.add(pkRing);
return serialKeyRingImport(list.iterator(), 1, keyServer, ignoreProgressable, proxy);
return serialKeyRingImport(list.iterator(), 1, hkpKeyserver, ignoreProgressable, proxy);
}
};

View File

@@ -75,8 +75,7 @@ public class KeybaseVerificationOperation extends BaseOperation<KeybaseVerificat
return new KeybaseVerificationResult(null,
RequiredInputParcel.createOrbotRequiredOperation(), cryptoInput);
}
proxy = Preferences.getPreferences(mContext).getProxyPrefs()
.parcelableProxy.getProxy();
proxy = Preferences.getPreferences(mContext).getParcelableProxy().getProxy();
} else {
proxy = cryptoInput.getParcelableProxy().getProxy();
}

View File

@@ -20,11 +20,6 @@
package org.sufficientlysecure.keychain.operations;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.Proxy;
import java.util.concurrent.atomic.AtomicBoolean;
import android.content.Context;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
@@ -32,8 +27,8 @@ import android.support.annotation.Nullable;
import org.bouncycastle.bcpg.ArmoredOutputStream;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.keyimport.HkpKeyserver;
import org.sufficientlysecure.keychain.keyimport.Keyserver.AddKeyException;
import org.sufficientlysecure.keychain.keyimport.ParcelableHkpKeyserver;
import org.sufficientlysecure.keychain.operations.results.OperationResult.LogType;
import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog;
import org.sufficientlysecure.keychain.operations.results.UploadResult;
@@ -50,9 +45,13 @@ import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
import org.sufficientlysecure.keychain.util.Log;
import org.sufficientlysecure.keychain.util.ParcelableProxy;
import org.sufficientlysecure.keychain.util.Preferences;
import org.sufficientlysecure.keychain.util.Preferences.ProxyPrefs;
import org.sufficientlysecure.keychain.util.orbot.OrbotHelper;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.Proxy;
import java.util.concurrent.atomic.AtomicBoolean;
/**
* An operation class which implements the upload of a single key to a key server.
@@ -60,7 +59,7 @@ import org.sufficientlysecure.keychain.util.orbot.OrbotHelper;
public class UploadOperation extends BaseOperation<UploadKeyringParcel> {
public UploadOperation(Context context, ProviderHelper providerHelper,
Progressable progressable, AtomicBoolean cancelled) {
Progressable progressable, AtomicBoolean cancelled) {
super(context, providerHelper, progressable, cancelled);
}
@@ -71,41 +70,32 @@ public class UploadOperation extends BaseOperation<UploadKeyringParcel> {
log.add(LogType.MSG_UPLOAD, 0);
updateProgress(R.string.progress_uploading, 0, 1);
Proxy proxy;
{
boolean proxyIsTor = false;
// Proxy priorities:
// 1. explicit proxy
// 2. orbot proxy state
// 3. proxy from preferences
ParcelableProxy parcelableProxy = cryptoInput.getParcelableProxy();
if (parcelableProxy != null) {
proxy = parcelableProxy.getProxy();
} else {
if ( ! OrbotHelper.isOrbotInRequiredState(mContext)) {
return new UploadResult(log, RequiredInputParcel.createOrbotRequiredOperation(), cryptoInput);
}
ProxyPrefs proxyPrefs = Preferences.getPreferences(mContext).getProxyPrefs();
if (proxyPrefs.torEnabled) {
proxyIsTor = true;
}
proxy = proxyPrefs.getProxy();
}
if (proxyIsTor) {
log.add(LogType.MSG_UPLOAD_PROXY_TOR, 1);
} else if (proxy == Proxy.NO_PROXY) {
log.add(LogType.MSG_UPLOAD_PROXY_DIRECT, 1);
} else {
log.add(LogType.MSG_UPLOAD_PROXY, 1, proxy.toString());
// Proxy priorities:
// 1. explicit proxy
// 2. orbot proxy state
// 3. proxy from preferences
ParcelableProxy parcelableProxy = cryptoInput.getParcelableProxy();
if (parcelableProxy == null) {
if (!OrbotHelper.isOrbotInRequiredState(mContext)) {
return new UploadResult(log, RequiredInputParcel.createOrbotRequiredOperation(), cryptoInput);
}
parcelableProxy = Preferences.getPreferences(mContext).getParcelableProxy();
}
HkpKeyserver hkpKeyserver;
boolean proxyIsTor = parcelableProxy.isTorEnabled();
if (proxyIsTor) {
log.add(LogType.MSG_UPLOAD_PROXY_TOR, 1);
} else if (parcelableProxy.getProxy() == Proxy.NO_PROXY) {
log.add(LogType.MSG_UPLOAD_PROXY_DIRECT, 1);
} else {
log.add(LogType.MSG_UPLOAD_PROXY, 1, parcelableProxy.getProxy().toString());
}
ParcelableHkpKeyserver hkpKeyserver;
{
hkpKeyserver = new HkpKeyserver(uploadInput.mKeyserver, proxy);
hkpKeyserver = uploadInput.mKeyserver;
log.add(LogType.MSG_UPLOAD_SERVER, 1, hkpKeyserver.toString());
}
@@ -114,7 +104,7 @@ public class UploadOperation extends BaseOperation<UploadKeyringParcel> {
return new UploadResult(UploadResult.RESULT_ERROR, log);
}
return uploadKeyRingToServer(log, hkpKeyserver, keyring);
return uploadKeyRingToServer(log, hkpKeyserver, keyring, parcelableProxy);
}
@Nullable
@@ -136,7 +126,7 @@ public class UploadOperation extends BaseOperation<UploadKeyringParcel> {
CanonicalizedKeyRing canonicalizedRing =
UncachedKeyRing.decodeFromData(uploadInput.mUncachedKeyringBytes)
.canonicalize(new OperationLog(), 0, true);
if ( ! CanonicalizedPublicKeyRing.class.isInstance(canonicalizedRing)) {
if (!CanonicalizedPublicKeyRing.class.isInstance(canonicalizedRing)) {
throw new IllegalArgumentException("keyring bytes must contain public key ring!");
}
log.add(LogType.MSG_UPLOAD_KEY, 0, KeyFormattingUtils.convertKeyIdToHex(canonicalizedRing.getMasterKeyId()));
@@ -155,7 +145,8 @@ public class UploadOperation extends BaseOperation<UploadKeyringParcel> {
@NonNull
private UploadResult uploadKeyRingToServer(
OperationLog log, HkpKeyserver server, CanonicalizedPublicKeyRing keyring) {
OperationLog log, ParcelableHkpKeyserver server, CanonicalizedPublicKeyRing keyring,
ParcelableProxy proxy) {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ArmoredOutputStream aos = null;
@@ -166,7 +157,7 @@ public class UploadOperation extends BaseOperation<UploadKeyringParcel> {
aos.close();
String armoredKey = bos.toString("UTF-8");
server.add(armoredKey);
server.add(armoredKey, proxy);
updateProgress(R.string.progress_uploading, 1, 1);