okhttp3
This commit is contained in:
@@ -0,0 +1,55 @@
|
||||
package org.sufficientlysecure.keychain.util;
|
||||
|
||||
import okhttp3.CertificatePinner;
|
||||
import okhttp3.OkHttpClient;
|
||||
import org.sufficientlysecure.keychain.Constants;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.Proxy;
|
||||
import java.net.URL;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* Created by Michał Kępkowski on 11/03/16.
|
||||
*/
|
||||
public class OkHttpClientFactory {
|
||||
private static OkHttpClient client;
|
||||
|
||||
public static OkHttpClient getSimpleClient(){
|
||||
if(client == null){
|
||||
client = new OkHttpClient.Builder().build();
|
||||
}
|
||||
return client;
|
||||
}
|
||||
|
||||
public static OkHttpClient getPinnedSimpleClient(CertificatePinner pinner){
|
||||
return new OkHttpClient.Builder()
|
||||
.certificatePinner(pinner)
|
||||
.build();
|
||||
}
|
||||
|
||||
|
||||
public static OkHttpClient getPinnedClient(URL url, Proxy proxy) throws IOException, TlsHelper.TlsHelperException {
|
||||
|
||||
return new OkHttpClient.Builder()
|
||||
.followRedirects(false)
|
||||
.followSslRedirects(false)
|
||||
.proxy(proxy)
|
||||
.connectTimeout(30000, TimeUnit.MILLISECONDS)
|
||||
.readTimeout(45000, TimeUnit.MILLISECONDS)
|
||||
.sslSocketFactory(TlsHelper.getPinnedSslSocketFactory(url))
|
||||
.build();
|
||||
}
|
||||
|
||||
public static OkHttpClient getClient( Proxy proxy) throws IOException, TlsHelper.TlsHelperException {
|
||||
|
||||
return new OkHttpClient.Builder()
|
||||
.followRedirects(false)
|
||||
.followSslRedirects(false)
|
||||
.proxy(proxy)
|
||||
.connectTimeout(30000, TimeUnit.MILLISECONDS)
|
||||
.readTimeout(45000, TimeUnit.MILLISECONDS)
|
||||
.build();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -17,55 +17,36 @@
|
||||
|
||||
package org.sufficientlysecure.keychain.util;
|
||||
|
||||
import com.squareup.okhttp.OkHttpClient;
|
||||
import com.squareup.okhttp.OkUrlFactory;
|
||||
|
||||
import com.textuality.keybase.lib.KeybaseUrlConnectionClient;
|
||||
|
||||
import okhttp3.OkHttpClient;
|
||||
import org.sufficientlysecure.keychain.Constants;
|
||||
|
||||
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 OkUrlFactory generateUrlFactory() {
|
||||
OkHttpClient client = new OkHttpClient();
|
||||
return new OkUrlFactory(client);
|
||||
}
|
||||
|
||||
@Override
|
||||
public URLConnection openConnection(URL url, Proxy proxy, boolean isKeybase) throws IOException {
|
||||
OkUrlFactory factory = generateUrlFactory();
|
||||
if (proxy != null) {
|
||||
factory.client().setProxy(proxy);
|
||||
factory.client().setConnectTimeout(30000, TimeUnit.MILLISECONDS);
|
||||
factory.client().setReadTimeout(40000, TimeUnit.MILLISECONDS);
|
||||
} else {
|
||||
factory.client().setConnectTimeout(5000, TimeUnit.MILLISECONDS);
|
||||
factory.client().setReadTimeout(25000, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
factory.client().setFollowSslRedirects(false);
|
||||
|
||||
// forced the usage of api.keybase.io pinned certificate
|
||||
if (isKeybase) {
|
||||
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");
|
||||
public OkHttpClient getClient(URL url, Proxy proxy, boolean pin) throws IOException {
|
||||
try {
|
||||
if(pin) {
|
||||
return OkHttpClientFactory.getPinnedClient(url, proxy);
|
||||
}else{
|
||||
return OkHttpClientFactory.getClient( proxy);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
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);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -19,8 +19,8 @@ package org.sufficientlysecure.keychain.util;
|
||||
|
||||
import android.content.res.AssetManager;
|
||||
|
||||
import com.squareup.okhttp.OkHttpClient;
|
||||
|
||||
import okhttp3.OkHttpClient;
|
||||
import org.sufficientlysecure.keychain.Constants;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
@@ -39,6 +39,7 @@ import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.net.ssl.SSLContext;
|
||||
import javax.net.ssl.SSLSocketFactory;
|
||||
import javax.net.ssl.TrustManagerFactory;
|
||||
|
||||
public class TlsHelper {
|
||||
@@ -80,30 +81,30 @@ public class TlsHelper {
|
||||
* @throws TlsHelperException
|
||||
* @throws IOException
|
||||
*/
|
||||
public static boolean usePinnedCertificateIfAvailable(OkHttpClient client, URL url) throws TlsHelperException, IOException {
|
||||
public static SSLSocketFactory getPinnedSslSocketFactory(URL url) throws TlsHelperException, IOException {
|
||||
if (url.getProtocol().equals("https")) {
|
||||
// use certificate PIN from assets if we have one
|
||||
for (String host : sPinnedCertificates.keySet()) {
|
||||
if (url.getHost().endsWith(host)) {
|
||||
pinCertificate(sPinnedCertificates.get(host), client);
|
||||
return true;
|
||||
return pinCertificate(sPinnedCertificates.get(host));
|
||||
//return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Modifies the client to accept only requests with a given certificate. Applies to all URLs requested by the
|
||||
* client.
|
||||
* Therefore a client that is pinned this way should be used to only make requests to URLs with passed certificate.
|
||||
* Modifies the builder to accept only requests with a given certificate. Applies to all URLs requested by the
|
||||
* builder.
|
||||
* Therefore a builder that is pinned this way should be used to only make requests to URLs with passed certificate.
|
||||
*
|
||||
* @param certificate certificate to pin
|
||||
* @param client OkHttpClient to enforce pinning on
|
||||
* @param builder OkHttpBuilder to enforce pinning on
|
||||
* @throws TlsHelperException
|
||||
* @throws IOException
|
||||
*/
|
||||
private static void pinCertificate(byte[] certificate, OkHttpClient client)
|
||||
private static SSLSocketFactory pinCertificate(byte[] certificate)
|
||||
throws TlsHelperException, IOException {
|
||||
// We don't use OkHttp's CertificatePinner since it can not be used to pin self-signed
|
||||
// certificate if such certificate is not accepted by TrustManager.
|
||||
@@ -130,7 +131,8 @@ public class TlsHelper {
|
||||
SSLContext context = SSLContext.getInstance("TLS");
|
||||
context.init(null, tmf.getTrustManagers(), null);
|
||||
|
||||
client.setSslSocketFactory(context.getSocketFactory());
|
||||
return context.getSocketFactory();
|
||||
//builder.sslSocketFactory(context.getSocketFactory());
|
||||
} catch (CertificateException | KeyStoreException | KeyManagementException | NoSuchAlgorithmException e) {
|
||||
throw new TlsHelperException(e);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user