I am trying to learn how to use Retrofit and OkHttp with HTTPS. From what I read, I either have to have a certificate in my folder raw
, or get it with this command echo -n | openssl s_client -connect api.****.com:443 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > gtux.cert
. Where can I run the above command? In my case, I already have a file .cer
in the folder raw
(it was given to me). According to this gist, my code is as follows:
public class SelfSignInClient {
private Context context;
public SelfSignInClient(Context context) {
this.context = context;
}
public OkHttpClient getOkHttpClient() {
HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
logging.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient.Builder okHttpClient = new OkHttpClient.Builder();
Certificate certificate = getCertificate();
KeyStore keyStore = createKeyStoreTrustedCAs(certificate);
TrustManagerFactory managerFactory = createTrustManagerCAs(keyStore);
SSLContext sslContext = createSSLSocketFactory(managerFactory);
okHttpClient.sslSocketFactory(sslContext.getSocketFactory());
okHttpClient.hostnameVerifier(new HostnameVerifier() {
@Override
public boolean verify(String hostname, SSLSession session) {
return hostname.equals("https://dev.api.***.com:443");
}
});
okHttpClient.addInterceptor(logging);
return okHttpClient.build();
}
private SSLContext createSSLSocketFactory(TrustManagerFactory managerFactory) {
final String PROTOCOL = "TLS";
SSLContext sslContext = null;
try {
sslContext = SSLContext.getInstance(PROTOCOL);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
try {
assert sslContext != null;
sslContext.init(null, managerFactory.getTrustManagers(), null);
} catch (KeyManagementException e) {
e.printStackTrace();
}
return sslContext;
}
private TrustManagerFactory createTrustManagerCAs(KeyStore keyStore) {
String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
TrustManagerFactory managerFactory = null;
try {
managerFactory = TrustManagerFactory.getInstance(tmfAlgorithm);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
try {
assert managerFactory != null;
managerFactory.init(keyStore);
} catch (KeyStoreException e) {
e.printStackTrace();
}
return managerFactory;
}
private KeyStore createKeyStoreTrustedCAs(Certificate certificate) {
final String ALIAS_CA = "ca";
String keyStoreType = KeyStore.getDefaultType();
KeyStore keyStore = null;
try {
keyStore = KeyStore.getInstance(keyStoreType);
} catch (KeyStoreException e) {
e.printStackTrace();
}
try {
assert keyStore != null;
keyStore.load(null, null);
} catch (IOException | NoSuchAlgorithmException | CertificateException e) {
e.printStackTrace();
}
try {
keyStore.setCertificateEntry(ALIAS_CA, certificate);
} catch (KeyStoreException e) {
e.printStackTrace();
}
return keyStore;
}
private Certificate getCertificate() {
Certificate certificate = null;
CertificateFactory certificateFactory = loadCertificateAuthorityFromResources();
InputStream inputStream = getCAFromResources();
try {
certificate = certificateFactory.generateCertificate(inputStream);
} catch (CertificateException e) {
e.printStackTrace();
}
return certificate;
}
private CertificateFactory loadCertificateAuthorityFromResources() {
final String CERT_TYPE = "X.509";
InputStream certificateAuthority = getCAFromResources();
CertificateFactory certificateFactory = null;
try {
certificateFactory = CertificateFactory.getInstance(CERT_TYPE);
} catch (CertificateException e) {
e.printStackTrace();
}
try {
assert certificateFactory != null;
certificateFactory.generateCertificate(certificateAuthority);
} catch (CertificateException e) {
e.printStackTrace();
} finally {
try {
certificateAuthority.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return certificateFactory;
}
private InputStream getCAFromResources() {
return context.getResources().openRawResource(R.raw.certificate);
}
}
And then my REST client:
private static final String BASE_URL = "***";
ApiService mApiService;
public RestClient() {
SelfSignInClient selfSignInClient = new SelfSignInClient(App.getContext());
OkHttpClient okClient;
okClient = selfSignInClient.getOkHttpClient();
GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.registerTypeAdapter(Peem.class, new PeemDeserializer());
gsonBuilder.registerTypeAdapterFactory(new ItemTypeAdapterFactory());
Retrofit retrofit;
retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create(gsonBuilder.create()))
.client(okClient)
.build();
this.mApiService = retrofit.create(ApiService.class);
}
But, when I try to run, I get this exception:
04-19 08: 26: 13.666 3932-3932/com.peems.itcrowd W/System.err: javax.net.ssl.SSLHandshakeException: 04-19 08: 26: 13.666 3932-3932/com.peems.itcrowd W/System.err: at com.android.org.conscrypt.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:429) 04-19 08: 26: 13.666 3932-3932/com.peems.itcrowd W/System.err: at okhttp3.internal.connection.RealConnection.connectTls(RealConnection.java:241) 04-19 08: 26: 13.666 3932-3932/com.peems.itcrowd W/System.err: at okhttp3.internal.connection.RealConnection.establishProtocol(RealConnection.java:198) 04-19 08: 26: 13.666 3932-3932/com.peems.itcrowd W/System.err: at okhttp3.internal.connection.RealConnection.buildConnection(RealConnection.java:174) 04-19 08: 26: 13.666 3932-3932/com.peems.itcrowd W/System.err: at okhttp3.internal.connection.RealConnection.connect(RealConnection.java:114) 04-19 08: 26: 13.666 3932-3932/com.peems.itcrowd W/System.err: at okhttp3.internal.connection.StreamAllocation.findConnection(StreamAllocation.java:193) 04-19 08: 26: 13.667 3932-3932/com.peems.itcrowd W/System.err: at okhttp3.internal.connection.StreamAllocation.findHealthyConnection(StreamAllocation.java:129) 04-19 08: 26: 13.667 3932-3932/com.peems.itcrowd W/System.err: at okhttp3.internal.connection.StreamAllocation.newStream(StreamAllocation.java:98) 04-19 08: 26: 13.667 3932-3932/com.peems.itcrowd W/System.err: at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.java:42) 04-19 08: 26: 13.667 3932-3932/com.peems.itcrowd W/System.err: at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92) 04-19 08: 26: 13.667 3932-3932/com.peems.itcrowd W/System.err: at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67) 04-19 08: 26: 13.667 3932-3932/com.peems.itcrowd W/System.err: at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.java:109) 04-19 08: 26: 13.667 3932-3932/com.peems.itcrowd W/System.err: at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92) 04-19 08: 26: 13.667 3932-3932/com.peems.itcrowd W/System.err: at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67) 04-19 08: 26: 13.667 3932-3932/com.peems.itcrowd W/System.err: at okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.java:93) 04-19 08: 26: 13.667 3932-3932/com.peems.itcrowd W/System.err: at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92) 04-19 08: 26: 13.667 3932-3932/com.peems.itcrowd W/System.err: at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.java:124) 04-19 08: 26: 13.667 3932-3932/com.peems.itcrowd W/System.err: at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92) 04-19 08: 26: 13.667 3932-3932/com.peems.itcrowd W/System.err: at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67) 04-19 08: 26: 13.668 3932-3932/com.peems.itcrowd W/System.err: at okhttp3.logging.HttpLoggingInterceptor.intercept(HttpLoggingInterceptor.java:212) 04-19 08: 26: 13.668 3932-3932/com.peems.itcrowd W/System.err: at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92) 04-19 08: 26: 13.668 3932-3932/com.peems.itcrowd W/System.err: at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67) 04-19 08: 26: 13.668 3932-3932/com.peems.itcrowd W/System.err: at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:170) 04-19 08: 26: 13.668 3932-3932/com.peems.itcrowd W/System.err: at okhttp3.RealCall.access $100 (RealCall.java:33) 04-19 08: 26: 13.668 3932-3932/com.peems.itcrowd W/System.err: at okhttp3.RealCall $AsyncCall.execute(RealCall.java:120) 04-19 08: 26: 13.668 3932-3932/com.peems.itcrowd W/System.err: at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32) 04-19 08: 26: 13.669 3932-3932/com.peems.itcrowd W/System.err: at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133) 04-19 08: 26: 13.669 3932-3932/com.peems.itcrowd W/System.err: at java.util.concurrent.ThreadPoolExecutor $Worker.run(ThreadPoolExecutor.java:607) 04-19 08: 26: 13.669 3932-3932/com.peems.itcrowd W/System.err: at java.lang.Thread.run(Thread.java:761) 04-19 08: 26: 13.670 3932-3932/com.peems.itcrowd W/System.err: : javax.net.ssl.SSLHandshakeException: 04-19 08: 26: 13.670 3932-3932/com.peems.itcrowd W/System.err:... 29 04-19 08: 26: 13.671 3932-3932/com.peems.itcrowd W/System.err: : javax.net.ssl.SSLProtocolException: SSL- : ssl = 0xac0d93c0: SSL, 04-19 08: 26: 13.671 3932-3932/com.peems.itcrowd W/System.err: : 100000f7: SSL: OPENSSL_internal: WRONG_VERSION_NUMBER (/boringssl/src/ssl/tls_record.c: 192 0x9d254196: 0x00000000 ) 04-19 08: 26: 13.671 3932-3932/com.peems.itcrowd W/System.err: at com.android.org.conscrypt.NativeCrypto.SSL_do_handshake ( ) 04-19 08: 26: 13.671 3932-3932/com.peems.itcrowd W/System.err: at com.android.org.conscrypt.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:357)
EDIT:
echo -n | openssl s_client -connect api.****.com:443 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > gtux.cert
CMD, Loading 'screen' into random state -'sed' is not recognized as an internal or external command, operable program or batch file.
, .cert , 0kb.