I've been trying to get to add SSL connection with server and unfortunately it doesn't work - still getting
javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
.
The order of operation:
create certificate by app side
send created certificate to server
In request we got certificate to use e.g.
MIIEpzCCAo+gAwIBAgICALQwDQYJKoZIhvcNAQELBQAwgYAxCzAJBgNVBAYTAlBM[...]6AlW6gjevIU7ZP2lIZWmA9f5uPc3Js1aft3UHmVfdiTaG+rcAVsw+ck7aQ==
(ROOT_CA
)Next requests are going to be send with attached this certificate (
ROOT_CA
).
Code responsible for sending with certificate :
private void retrofitConfiguration(Context context){
OkHttpClient.Builder client = new OkHttpClient.Builder();
ProviderInstaller.installIfNeeded(context);
X509Certificate ca = loadCertificate();
KeyStore keyStore = createKeyStore(ca);
TrustManager[] trustManagers = createTrustManager(keyStore);
SSLContext sslContext = null;
sslContext = createSSLContext(trustManagers, keyStore);
X509TrustManager _trustManager = (X509TrustManager) trustManagers[0];
client.sslSocketFactory(sslContext.getSocketFactory(), _trustManager);
client.hostnameVerifier(getHostnameVerifier());
buildRetrofit(client.build());
}
private X509Certificate loadCertificate() throws CertificateException {
CertificateFactory cf = CertificateFactory.getInstance("X.509");
String ca = ROOT_CA;
byte[] decoded = Base64.decode(ca);
return (X509Certificate) cf.generateCertificate(new ByteArrayInputStream(decoded));
}
private KeyStore createKeyStore(X509Certificate ca) throws KeyStoreException, CertificateException, NoSuchAlgorithmException, IOException {
String keyStoreType = KeyStore.getDefaultType();
KeyStore keyStore = KeyStore.getInstance(keyStoreType);
keyStore.load(null, null);
keyStore.setCertificateEntry("ca", ca);
return keyStore;
}
private TrustManager[] createTrustManager(KeyStore keyStore) throws NoSuchAlgorithmException, KeyStoreException {
String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
tmf.init(keyStore);
return tmf.getTrustManagers();
}
private SSLContext createSSLContext(TrustManager[] trustManagers, KeyStore keyStore) throws KeyManagementException, NoSuchAlgorithmException, UnrecoverableKeyException, KeyStoreException {
SSLContext sslContext = SSLContext.getInstance("TLS");
KeyManagerFactory kmf = KeyManagerFactory.getInstance("X509");
kmf.init(keyStore, new char[]{0});
KeyManager[] keyManagers = kmf.getKeyManagers();
sslContext.init(keyManagers, trustManagers, null);
return sslContext;
}
private HostnameVerifier getHostnameVerifier() {
return (hostname, session) -> {
return true;
};
}
I tried to use CustomTrustManager
from https://github.com/rfreedman/android-ssl with same result.
I really don't get why it doesn't work at that point.. (went through a lot of other topic like this)
Any help would be greatly appreciated!
UPDATE
Now i am using this method :
private SSLSocketFactory getSSLSocketFactory()
throws CertificateException, KeyStoreException, IOException,
NoSuchAlgorithmException, KeyManagementException, UnrecoverableKeyException {
Certificate clientCA = parseClientCertificate();
KeyStore clientKeyStore = KeyStore.getInstance("BKS");
clientKeyStore.load(null, null);
clientKeyStore.setCertificateEntry("clientCA", clientCA);
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance("X509");
keyManagerFactory.init(clientKeyStore, null);
KeyManager[] keyManagers = keyManagerFactory.getKeyManagers();
Certificate rootCA = parseRootCertificate();
KeyStore rootKeyStore = KeyStore.getInstance(KeyStore.getDefaultType());
rootKeyStore.load(null, null);
rootKeyStore.setCertificateEntry("rootCA", rootCA);
TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmf.init(rootKeyStore);
TrustManager[] managers = tmf.getTrustManagers();
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(keyManagers, managers, null);
return sslContext.getSocketFactory();
}
And getting javax.net.ssl.SSLHandshakeException: Handshake failed
. This connection is to https and I am trying to attach my client cert to requests. (tested with okhttp3 and android 7.1.1). I went through a lot of topic in stack and can not find any working solution.
Full stack trace:
W: javax.net.ssl.SSLHandshakeException: Handshake failed
W: at com.google.android.gms.org.conscrypt.ConscryptFileDescriptorSocket.startHandshake(:com.google.android.gms@11746440:54)
W: at okhttp3.internal.connection.RealConnection.connectTls(RealConnection.java:267)
W: at okhttp3.internal.connection.RealConnection.establishProtocol(RealConnection.java:237)
W: at okhttp3.internal.connection.RealConnection.connect(RealConnection.java:148)
W: at okhttp3.internal.connection.StreamAllocation.findConnection(StreamAllocation.java:186)
W: at okhttp3.internal.connection.StreamAllocation.findHealthyConnection(StreamAllocation.java:121)
W: at okhttp3.internal.connection.StreamAllocation.newStream(StreamAllocation.java:100)
W: at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.java:42)
W: at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
W: at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67)
W: at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.java:93)
W: at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
W: at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67)
W: at okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.java:93)
W: at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
W: at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.java:120)
W: at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
W: at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67)
W: at okhttp3.logging.HttpLoggingInterceptor.intercept(HttpLoggingInterceptor.java:212)
W: at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
W: at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67)
W: at com.network.ApiClient.lambda$retrofitConfiguration$0(ApiClient.java:127)
W: at com.network.ApiClient$$Lambda$1.intercept(Unknown Source)
W: at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
W: at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67)
W: at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:179)
W: at okhttp3.RealCall.execute(RealCall.java:63)
W: at retrofit2.OkHttpCall.execute(OkHttpCall.java:174)
W: at retrofit2.adapter.rxjava.CallExecuteOnSubscribe.call(CallExecuteOnSubscribe.java:40)
W: at retrofit2.adapter.rxjava.CallExecuteOnSubscribe.call(CallExecuteOnSubscribe.java:24)
W: at retrofit2.adapter.rxjava.BodyOnSubscribe.call(BodyOnSubscribe.java:33)
W: at retrofit2.adapter.rxjava.BodyOnSubscribe.call(BodyOnSubscribe.java:25)
W: at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:48)
W: at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:30)
W: at rx.Observable.unsafeSubscribe(Observable.java:10346)
W: at rx.internal.operators.OperatorSubscribeOn$SubscribeOnSubscriber.call(OperatorSubscribeOn.java:100)
W: at rx.internal.schedulers.CachedThreadScheduler$EventLoopWorker$1.call(CachedThreadScheduler.java:230)
W: at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:55)
W: at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:428)
W: at java.util.concurrent.FutureTask.run(FutureTask.java:237)
W: at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:272)
W: at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
W: at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
W: at java.lang.Thread.run(Thread.java:761)
W: Caused by: javax.net.ssl.SSLProtocolException: SSL handshake aborted: ssl=0x7f8f068740: Failure in SSL library, usually a protocol error
W: error:10000410:SSL routines:OPENSSL_internal:SSLV3_ALERT_HANDSHAKE_FAILURE (third_party/openssl/boringssl/src/ssl/tls_record.cc:575 0x7f8f0fb180:0x00000001)
W: at com.google.android.gms.org.conscrypt.NativeCrypto.SSL_do_handshake(Native Method)
W: at com.google.android.gms.org.conscrypt.SslWrapper.doHandshake(:com.google.android.gms@11746440:2)
W: at com.google.android.gms.org.conscrypt.ConscryptFileDescriptorSocket.startHandshake(:com.google.android.gms@11746440:19)
W: ... 43 more
W: com.network.errors.RetrofitException: Handshake failed
W: at com.network.RxErrorHandlingCallAdapterFactory$RxCallAdapterWrapper.asRetrofitException(RxErrorHandlingCallAdapterFactory.java:93)
W: at com.network.RxErrorHandlingCallAdapterFactory$RxCallAdapterWrapper.access$000(RxErrorHandlingCallAdapterFactory.java:51)
W: at com.network.RxErrorHandlingCallAdapterFactory$RxCallAdapterWrapper$1.call(RxErrorHandlingCallAdapterFactory.java:71)
W: at com.network.RxErrorHandlingCallAdapterFactory$RxCallAdapterWrapper$1.call(RxErrorHandlingCallAdapterFactory.java:68)
W: at rx.internal.operators.OperatorOnErrorResumeNextViaFunction$4.onError(OperatorOnErrorResumeNextViaFunction.java:140)
W: at retrofit2.adapter.rxjava.BodyOnSubscribe$BodySubscriber.onError(BodyOnSubscribe.java:64)
W: at retrofit2.adapter.rxjava.CallArbiter.emitError(CallArbiter.java:141)
W: at retrofit2.adapter.rxjava.CallExecuteOnSubscribe.call(CallExecuteOnSubscribe.java:43)
W: at retrofit2.adapter.rxjava.CallExecuteOnSubscribe.call(CallExecuteOnSubscribe.java:24)
W: at retrofit2.adapter.rxjava.BodyOnSubscribe.call(BodyOnSubscribe.java:33)
W: at retrofit2.adapter.rxjava.BodyOnSubscribe.call(BodyOnSubscribe.java:25)
W: at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:48)
W: at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:30)
W: at rx.Observable.unsafeSubscribe(Observable.java:10346)
W: at rx.internal.operators.OperatorSubscribeOn$SubscribeOnSubscriber.call(OperatorSubscribeOn.java:100)
W: at rx.internal.schedulers.CachedThreadScheduler$EventLoopWorker$1.call(CachedThreadScheduler.java:230)
W: at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:55)
W: at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:428)
W: at java.util.concurrent.FutureTask.run(FutureTask.java:237)
W: at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:272)
W: at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
W: at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
W: at java.lang.Thread.run(Thread.java:761)
W: Caused by: javax.net.ssl.SSLHandshakeException: Handshake failed
W: at com.google.android.gms.org.conscrypt.ConscryptFileDescriptorSocket.startHandshake(:com.google.android.gms@11746440:54)
W: at okhttp3.internal.connection.RealConnection.connectTls(RealConnection.java:267)
W: at okhttp3.internal.connection.RealConnection.establishProtocol(RealConnection.java:237)
W: at okhttp3.internal.connection.RealConnection.connect(RealConnection.java:148)
W: at okhttp3.internal.connection.StreamAllocation.findConnection(StreamAllocation.java:186)
W: at okhttp3.internal.connection.StreamAllocation.findHealthyConnection(StreamAllocation.java:121)
W: at okhttp3.internal.connection.StreamAllocation.newStream(StreamAllocation.java:100)
W: at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.java:42)
W: at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
W: at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67)
W: at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.java:93)
W: at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
W: at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67)
W: at okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.java:93)
W: at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
W: at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.java:120)
W: at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
W: at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67)
W: at okhttp3.logging.HttpLoggingInterceptor.intercept(HttpLoggingInterceptor.java:212)
W: at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
W: at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67)
W: at com.network.ApiClient.lambda$retrofitConfiguration$0(ApiClient.java:127)
W: at com.network.ApiClient$$Lambda$1.intercept(Unknown Source)
W: at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
W: at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67)
W: at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:179)
W: at okhttp3.RealCall.execute(RealCall.java:63)
W: at retrofit2.OkHttpCall.execute(OkHttpCall.java:174)
W: at retrofit2.adapter.rxjava.CallExecuteOnSubscribe.call(CallExecuteOnSubscribe.java:40)
W: ... 15 more
W: Caused by: javax.net.ssl.SSLProtocolException: SSL handshake aborted: ssl=0x7f8f068740: Failure in SSL library, usually a protocol error
W: error:10000410:SSL routines:OPENSSL_internal:SSLV3_ALERT_HANDSHAKE_FAILURE (third_party/openssl/boringssl/src/ssl/tls_record.cc:575 0x7f8f0fb180:0x00000001)
W: at com.google.android.gms.org.conscrypt.NativeCrypto.SSL_do_handshake(Native Method)
W: at com.google.android.gms.org.conscrypt.SslWrapper.doHandshake(:com.google.android.gms@11746440:2)