From ad2c8867e67e71f8b3d88db93911a7e37ed4bf69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Mon, 21 Sep 2015 12:49:02 +0200 Subject: Use more modular Keybase lib with OkHttp wrapper --- .../keychain/keyimport/KeybaseKeyserver.java | 11 +++- .../operations/KeybaseVerificationOperation.java | 35 ++++++---- .../keychain/ui/ViewKeyKeybaseFragment.java | 6 +- .../keychain/util/FilterCursorWrapper.java | 17 +++++ .../keychain/util/OkHttpKeybaseClient.java | 74 ++++++++++++++++++++++ 5 files changed, 125 insertions(+), 18 deletions(-) create mode 100644 OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/OkHttpKeybaseClient.java (limited to 'OpenKeychain/src/main/java/org') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/KeybaseKeyserver.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/KeybaseKeyserver.java index c2865410e..486d658f6 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/KeybaseKeyserver.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/KeybaseKeyserver.java @@ -19,12 +19,13 @@ package org.sufficientlysecure.keychain.keyimport; import com.textuality.keybase.lib.KeybaseException; import com.textuality.keybase.lib.Match; -import com.textuality.keybase.lib.Search; +import com.textuality.keybase.lib.KeybaseQuery; import com.textuality.keybase.lib.User; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils; import org.sufficientlysecure.keychain.util.Log; +import org.sufficientlysecure.keychain.util.OkHttpKeybaseClient; import java.net.Proxy; import java.util.ArrayList; @@ -49,7 +50,9 @@ public class KeybaseKeyserver extends Keyserver { mQuery = query; try { - Iterable matches = Search.search(query, proxy); + KeybaseQuery keybaseQuery = new KeybaseQuery(new OkHttpKeybaseClient()); + keybaseQuery.setProxy(proxy); + Iterable matches = keybaseQuery.search(query); for (Match match : matches) { results.add(makeEntry(match)); } @@ -101,7 +104,9 @@ public class KeybaseKeyserver extends Keyserver { @Override public String get(String id, Proxy proxy) throws QueryFailedException { try { - return User.keyForUsername(id, proxy); + KeybaseQuery keybaseQuery = new KeybaseQuery(new OkHttpKeybaseClient()); + keybaseQuery.setProxy(proxy); + return User.keyForUsername(keybaseQuery, id); } catch (KeybaseException e) { throw new QueryFailedException(e.getMessage()); } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/KeybaseVerificationOperation.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/KeybaseVerificationOperation.java index 8f1abde83..aaff0a07c 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/KeybaseVerificationOperation.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/KeybaseVerificationOperation.java @@ -20,39 +20,43 @@ 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.json.JSONObject; import org.spongycastle.openpgp.PGPUtil; import org.sufficientlysecure.keychain.R; 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.pgp.PgpDecryptVerifyOperation; import org.sufficientlysecure.keychain.pgp.PgpDecryptVerifyInputParcel; +import org.sufficientlysecure.keychain.pgp.PgpDecryptVerifyOperation; import org.sufficientlysecure.keychain.pgp.Progressable; import org.sufficientlysecure.keychain.provider.ProviderHelper; import org.sufficientlysecure.keychain.service.KeybaseVerificationParcel; import org.sufficientlysecure.keychain.service.input.CryptoInputParcel; import org.sufficientlysecure.keychain.service.input.RequiredInputParcel; +import org.sufficientlysecure.keychain.util.OkHttpKeybaseClient; import org.sufficientlysecure.keychain.util.Preferences; import org.sufficientlysecure.keychain.util.orbot.OrbotHelper; +import java.io.ByteArrayInputStream; +import java.io.InputStream; +import java.net.Proxy; +import java.util.ArrayList; +import java.util.List; + +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; + public class KeybaseVerificationOperation extends BaseOperation { public KeybaseVerificationOperation(Context context, ProviderHelper providerHelper, @@ -83,6 +87,9 @@ public class KeybaseVerificationOperation extends BaseOperation proofList = new ArrayList(); final Hashtable> proofs = new Hashtable>(); try { - User keybaseUser = User.findByFingerprint(fingerprint, mParcelableProxy.getProxy()); + 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(); appendIfOK(proofs, proofType, proof); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/FilterCursorWrapper.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/FilterCursorWrapper.java index ab73f59b8..d06f2ab65 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/FilterCursorWrapper.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/FilterCursorWrapper.java @@ -1,3 +1,20 @@ +/* + * Copyright (C) 2015 Dominik Schürmann + * + * 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 . + */ + package org.sufficientlysecure.keychain.util; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/OkHttpKeybaseClient.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/OkHttpKeybaseClient.java new file mode 100644 index 000000000..7c1d9f291 --- /dev/null +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/OkHttpKeybaseClient.java @@ -0,0 +1,74 @@ +package org.sufficientlysecure.keychain.util; + +import com.squareup.okhttp.OkHttpClient; +import com.squareup.okhttp.OkUrlFactory; +/* + * Copyright (C) 2015 Dominik Schürmann + * + * 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 . + */ + +import com.textuality.keybase.lib.KeybaseUrlConnectionClient; + +import java.io.IOException; +import java.net.Proxy; +import java.net.URL; +import java.net.URLConnection; +import java.util.concurrent.TimeUnit; + +/** + * Wrapper for Keybase Lib + */ +public class OkHttpKeybaseClient implements KeybaseUrlConnectionClient { + + private final OkUrlFactory factory; + private final OkUrlFactory proxyFactory; + + private static OkUrlFactory generateUrlFactory() { + OkHttpClient client = new OkHttpClient(); + client.setConnectTimeout(5000, TimeUnit.MILLISECONDS); + client.setReadTimeout(25000, TimeUnit.MILLISECONDS); + return new OkUrlFactory(client); + } + + private static OkUrlFactory generateProxyUrlFactory() { + OkHttpClient client = new OkHttpClient(); + client.setConnectTimeout(30000, TimeUnit.MILLISECONDS); + client.setReadTimeout(40000, TimeUnit.MILLISECONDS); + return new OkUrlFactory(client); + } + + public OkHttpKeybaseClient() { + factory = generateUrlFactory(); + proxyFactory = generateProxyUrlFactory(); + } + + @Override + public URLConnection openConnection(URL url) throws IOException { + return openConnection(url, null); + } + + @Override + public URLConnection openConnection(URL url, Proxy proxy) throws IOException { + URLConnection conn; + if (proxy != null) { + proxyFactory.client().setProxy(proxy); + conn = proxyFactory.open(url); + } else { + conn = factory.open(url); + } + return conn; + } + +} \ No newline at end of file -- cgit v1.2.3 From 9ee61dc0dfa5990126b7fb79c5373beb83a8b040 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Mon, 21 Sep 2015 14:05:44 +0200 Subject: Pin keybase certificate --- .../keychain/KeychainApplication.java | 6 +++ .../keychain/util/OkHttpKeybaseClient.java | 45 ++++++++++++---------- 2 files changed, 31 insertions(+), 20 deletions(-) (limited to 'OpenKeychain/src/main/java/org') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/KeychainApplication.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/KeychainApplication.java index 45d81749a..56dd9a4cb 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/KeychainApplication.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/KeychainApplication.java @@ -100,6 +100,12 @@ public class KeychainApplication extends Application { TlsHelper.addPinnedCertificate("hkps.pool.sks-keyservers.net", getAssets(), "hkps.pool.sks-keyservers.net.CA.cer"); TlsHelper.addPinnedCertificate("pgp.mit.edu", getAssets(), "pgp.mit.edu.cer"); + // NOTE: + // keybase.io.CA.cer only holds the CA issuing the actual keybase.io certificate, but this + // is better than no pinning! + // We are not using https://github.com/keybase/node-client/blob/master/src/ca.iced + // because it is only valid for api.keybase.io (https://github.com/keybase/keybase-issues/issues/964) + TlsHelper.addPinnedCertificate("keybase.io", getAssets(), "keybase.io.CA.cer"); TemporaryStorageProvider.cleanUp(this); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/OkHttpKeybaseClient.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/OkHttpKeybaseClient.java index 7c1d9f291..32a5406e0 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/OkHttpKeybaseClient.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/OkHttpKeybaseClient.java @@ -1,7 +1,3 @@ -package org.sufficientlysecure.keychain.util; - -import com.squareup.okhttp.OkHttpClient; -import com.squareup.okhttp.OkUrlFactory; /* * Copyright (C) 2015 Dominik Schürmann * @@ -19,8 +15,14 @@ import com.squareup.okhttp.OkUrlFactory; * along with this program. If not, see . */ +package org.sufficientlysecure.keychain.util; + +import com.squareup.okhttp.OkHttpClient; +import com.squareup.okhttp.OkUrlFactory; import com.textuality.keybase.lib.KeybaseUrlConnectionClient; +import org.sufficientlysecure.keychain.Constants; + import java.io.IOException; import java.net.Proxy; import java.net.URL; @@ -33,25 +35,14 @@ import java.util.concurrent.TimeUnit; public class OkHttpKeybaseClient implements KeybaseUrlConnectionClient { private final OkUrlFactory factory; - private final OkUrlFactory proxyFactory; private static OkUrlFactory generateUrlFactory() { OkHttpClient client = new OkHttpClient(); - client.setConnectTimeout(5000, TimeUnit.MILLISECONDS); - client.setReadTimeout(25000, TimeUnit.MILLISECONDS); - return new OkUrlFactory(client); - } - - private static OkUrlFactory generateProxyUrlFactory() { - OkHttpClient client = new OkHttpClient(); - client.setConnectTimeout(30000, TimeUnit.MILLISECONDS); - client.setReadTimeout(40000, TimeUnit.MILLISECONDS); return new OkUrlFactory(client); } public OkHttpKeybaseClient() { factory = generateUrlFactory(); - proxyFactory = generateProxyUrlFactory(); } @Override @@ -61,14 +52,28 @@ public class OkHttpKeybaseClient implements KeybaseUrlConnectionClient { @Override public URLConnection openConnection(URL url, Proxy proxy) throws IOException { - URLConnection conn; if (proxy != null) { - proxyFactory.client().setProxy(proxy); - conn = proxyFactory.open(url); + factory.client().setProxy(proxy); + factory.client().setConnectTimeout(30000, TimeUnit.MILLISECONDS); + factory.client().setReadTimeout(40000, TimeUnit.MILLISECONDS); } else { - conn = factory.open(url); + factory.client().setConnectTimeout(5000, TimeUnit.MILLISECONDS); + factory.client().setReadTimeout(25000, TimeUnit.MILLISECONDS); } - return conn; + + factory.client().setFollowSslRedirects(false); + + // forced the usage of keybase.io pinned certificate + try { + if (!TlsHelper.usePinnedCertificateIfAvailable(factory.client(), url)) { + throw new IOException("no pinned certificate found for URL!"); + } + } catch (TlsHelper.TlsHelperException e) { + Log.e(Constants.TAG, "TlsHelper failed", e); + throw new IOException("TlsHelper failed"); + } + + return factory.open(url); } } \ No newline at end of file -- cgit v1.2.3