package net.rafaeltoledo.security.http;
import android.util.Log;
import java.security.GeneralSecurityException;
import java.security.KeyStore;
import java.util.Collections;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager;
import okhttp3.CertificatePinner;
import okhttp3.ConnectionSpec;
import okhttp3.OkHttpClient;
import okhttp3.TlsVersion;
public class HttpClientProvider {
private static final String TAG = HttpClientProvider.class.getSimpleName();
private static final OkHttpClient CLIENT = init();
private static OkHttpClient init() {
ConnectionSpec.Builder spec = new ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS)
.tlsVersions(TlsVersion.TLS_1_2);
OkHttpClient.Builder client = new OkHttpClient.Builder()
.connectionSpecs(Collections.singletonList(spec.build()));
// This setup is necessary because API 16-18 support TLS 1.2,
// but use 1.0 as default.
setupTls(client);
setupPinning(client);
return client.build();
}
private static void setupPinning(OkHttpClient.Builder client) {
client.certificatePinner(new CertificatePinner.Builder()
.add("github.com", "sha256/pL1+qb9HTMRZJmuC/bB/ZI9d302BYrrqiVuRyW+DGrU=")
.add("github.com", "sha256/RRM1dGqnDFsCJXBTHky16vi1obOlCgFFn/yOhI/y+ho=")
.add("github.com", "sha256/WoiWRyIOVNa9ihaBciRSC7XHjliYS9VwUGOIud4PB18=")
.build());
}
private static void setupTls(OkHttpClient.Builder builder) {
try {
TrustManagerFactory factory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
factory.init((KeyStore) null);
for (TrustManager trustManager : factory.getTrustManagers()) {
if (trustManager instanceof X509TrustManager) {
builder.sslSocketFactory(new Tls12SslSocketFactory(), (X509TrustManager) trustManager);
break;
}
}
} catch (GeneralSecurityException e) {
Log.e(TAG, "Failed to initialize SSL Socket Factory", e);
}
}
public static OkHttpClient getClient() {
return CLIENT;
}
}