SSL handshake exception despite custom X509TrustManager - android

I have been using the approach with a custom trust manager to avoid SSL handshake exceptions
static {
try {
SSLContext ctx = SSLContext.getInstance("TLS");
ctx.init(null, new TrustManager[]{
new X509TrustManager() {
public void checkClientTrusted(X509Certificate[] chain, String authType) {
}
public void checkServerTrusted(X509Certificate[] chain, String authType) {
}
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[]{};
}
}
}, null);
HttpsURLConnection.setDefaultSSLSocketFactory(ctx.getSocketFactory());
} catch (NoSuchAlgorithmException | KeyManagementException e) {
e.printStackTrace();
}
HttpsURLConnection.setDefaultHostnameVerifier((hostname, session) -> true);
}
and then using JSoup to get the page contents:
Document document = Jsoup.connect(url).timeout(TIMEOUT).userAgent(USER_AGENT_MOZILLA).get();
But recently I ran against an url on which that approach didn't work.
http://feeds.dzone.com/link/18931/15381195/what-are-microservices-2
I got that exception again
Interesting that running that code in a JUnit test doesn't cause any problems. I assume it's because the corresponding certificate is available on my PC.
But if I run the Android app with that code, be it physical device or emulator the exception would be thrown.
I can also open the url in the browser on physical device or emulator.
Any ideas why the approach fails on that url?
Below is the output ( e.printStackTrace() )
W/System.err: javax.net.ssl.SSLHandshakeException: Handshake failed
W/System.err: at com.android.org.conscrypt.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:429)
W/System.err: at com.android.okhttp.Connection.connectTls(Connection.java:235)
at com.android.okhttp.Connection.connectSocket(Connection.java:199)
at com.android.okhttp.Connection.connect(Connection.java:172)
at com.android.okhttp.Connection.connectAndSetOwner(Connection.java:367)
at com.android.okhttp.OkHttpClient$1.connectAndSetOwner(OkHttpClient.java:130)
at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:329)
W/System.err: at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:246)
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:457)
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:126)
at com.android.okhttp.internal.huc.DelegatingHttpsURLConnection.connect(DelegatingHttpsURLConnection.java:89)
at com.android.okhttp.internal.huc.HttpsURLConnectionImpl.connect(HttpsURLConnectionImpl.java)
at org.jsoup.helper.HttpConnection$Response.execute(HttpConnection.java:732)
at org.jsoup.helper.HttpConnection$Response.execute(HttpConnection.java:759)
at org.jsoup.helper.HttpConnection$Response.execute(HttpConnection.java:707)
W/System.err: at org.jsoup.helper.HttpConnection.execute(HttpConnection.java:297)
at org.jsoup.helper.HttpConnection.get(HttpConnection.java:286)
at com.denis.aristov.tts.web.DZoneProcessor.extractPlainText(DZoneProcessor.java:69)
at com.denis.aristov.tts.web.WebContentProcessor.lambda$buildRequests$0(WebContentProcessor.java:177)
at com.denis.aristov.tts.web.-$$Lambda$WebContentProcessor$pTY0-1VHYsJSt_VDuccv_skDjX4.call(lambda)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
at java.lang.Thread.run(Thread.java:761)
Suppressed: javax.net.ssl.SSLHandshakeException: Handshake failed
... 24 more
W/System.err: Suppressed: javax.net.ssl.SSLHandshakeException: Handshake failed
... 24 more
Caused by: javax.net.ssl.SSLProtocolException: SSL handshake terminated: ssl=0xa29cf980: Failure in SSL library, usually a protocol error
error:10000410:SSL routines:OPENSSL_internal:SSLV3_ALERT_HANDSHAKE_FAILURE (external/boringssl/src/ssl/s3_pkt.c:610 0x8f555da0:0x00000001)
error:1000009a:SSL routines:OPENSSL_internal:HANDSHAKE_FAILURE_ON_CLIENT_HELLO (external/boringssl/src/ssl/s3_clnt.c:764 0xa0030266:0x00000000)
W/System.err: at com.android.org.conscrypt.NativeCrypto.SSL_do_handshake(Native Method)
at com.android.org.conscrypt.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:357)
... 23 more
Caused by: javax.net.ssl.SSLProtocolException: SSL handshake terminated: ssl=0xa29cf980: Failure in SSL library, usually a protocol error
error:1000043e:SSL routines:OPENSSL_internal:TLSV1_ALERT_INAPPROPRIATE_FALLBACK (external/boringssl/src/ssl/s3_pkt.c:610 0x8f555e00:0x00000001)
at com.android.org.conscrypt.NativeCrypto.SSL_do_handshake(Native Method)
at com.android.org.conscrypt.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:357)
... 23 more
Caused by: javax.net.ssl.SSLProtocolException: SSL handshake terminated: ssl=0xa29cf980: Failure in SSL library, usually a protocol error
error:1000043e:SSL routines:OPENSSL_internal:TLSV1_ALERT_INAPPROPRIATE_FALLBACK (external/boringssl/src/ssl/s3_pkt.c:610 0x8f555e00:0x00000001)
at com.android.org.conscrypt.NativeCrypto.SSL_do_handshake(Native Method)
W/System.err: at com.android.org.conscrypt.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:357)
... 23 more
I'm using Android 7 (API Level 27)
I used the site https://www.ssllabs.com/ssltest/ to scan the SSL server and it reported:
This server supports TLS 1.0 and TLS 1.1. Grade capped to B.
This server supports TLS 1.3.
However the site suggested me to scan not the original hostname feeds.dzone.com but feedpress.me (because of redirection perhaps)

Try this
static {
try {
SSLContext ctx = SSLContext.getInstance("TLS");
ctx.init(null, new TrustManager[]{
new X509TrustManager() {
public void checkClientTrusted(X509Certificate[] chain, String authType) {
}
public void checkServerTrusted(X509Certificate[] chain, String authType) {
}
public X509Certificate[] getAcceptedIssuers() {
new java.security.cert.X509Certificate[]{};
}
}
}, new java.security.SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(ctx.getSocketFactory());
} catch (NoSuchAlgorithmException | KeyManagementException e) {
e.printStackTrace();
}
HttpsURLConnection.setDefaultHostnameVerifier((hostname, session) -> true);
}

Related

For SMACK 4.3.4 How do I update a default certificate needed for client connection to server?

I have written an Android application using SMACK 4.3.4. Everything has been working great until today, when I started getting connection errors.
I am using a public, online XMPP server for my testing (chatserver.space). I have not to this point had to do anything with certificates. It all "just worked". So clearly there is some default certificate somewhere that has expired (see the Caused by: java.security.cert.CertPathValidatorException: timestamp check failed portion of the stacktrace below), I just don't understand where it is and what I need to do to bump the date properly.
Here is the code from my app (standard SMACK connection stuff):
public void connect() throws Exception {
Timber.d("Lifecycle: XMPPConnectionMgr connect() attempted HOST: %s, PORT: %d, DOMAIN: %s", XMPP_HOST, XMPP_PORT, XMPP_DOMAIN);
if (xmppConnection == null) {
XMPPTCPConnectionConfiguration.Builder connConfigBuilder = XMPPTCPConnectionConfiguration.builder();
try {
connConfigBuilder
.setHost(XMPP_HOST) // Name of your Host
.setPort(XMPP_PORT) // Your Port for accepting c2s connection
.setXmppDomain(XMPP_DOMAIN)
.setSecurityMode(XMPPTCPConnectionConfiguration.SecurityMode.required);
xmppConnection = new XMPPTCPConnection(connConfigBuilder.build());
xmppConnection.addConnectionListener(this);
Set<String> blacklist = SASLAuthentication.getBlacklistedSASLMechanisms();
Timber.d("Lifecycle: Blacklist contents: %s", blacklist.toString());
Map<String,String> registered = SASLAuthentication.getRegisterdSASLMechanisms();
Timber.d("Lifecycle: registered SASLAuthentication mechanisms: %s", registered.toString());
} catch (XmppStringprepException e) {
Timber.d("XMPPConnectionMgr could not connect to XMPP Server: %s", e.getMessage());
throw new Exception(String.format(InTouch.getInstance().getApplicationContext().getString(R.string.exception_communications_connection),
e.getMessage()));
}
}
try {
if ( !xmppConnection.isConnected() ) {
xmppConnection.connect();
}
} catch (SmackException e) {
Timber.d("XMPPConnectionMgr got Exception trying to connect to XMPP Server: %s", e.getMessage());
throw new Exception(String.format(InTouch.getInstance().getApplicationContext().getString(R.string.exception_communications_connection),
e.getMessage()));
} catch (IOException e) {
Timber.d("XMPPConnectionMgr got IOException trying to connect to XMPP Server: %s", e.getMessage());
throw new Exception(String.format(InTouch.getInstance().getApplicationContext().getString(R.string.exception_communications_connection),
e.getMessage()));
} catch (XMPPException e) {
Timber.d("XMPPConnectionMgr got Exception trying to connect to XMPP Server: %s", e.getMessage());
throw new Exception(String.format(InTouch.getInstance().getApplicationContext().getString(R.string.exception_communications_connection),
e.getMessage()));
} catch (InterruptedException e) {
Timber.d("XMPPConnectionMgr got InterruptedException trying to connect to XMPP Server: %s", e.getMessage());
throw new Exception(String.format(InTouch.getInstance().getApplicationContext().getString(R.string.exception_communications_connection),
e.getMessage()));
}
}
The full stack trace is as follows:
2019-07-22 21:01:46.942 1511-1929/com.reddragon.intouch W/AbstractXMPPConnection: Connection XMPPTCPConnection[not-authenticated] (0) closed with error
javax.net.ssl.SSLHandshakeException: Chain validation failed
at com.android.org.conscrypt.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:361)
at com.android.org.conscrypt.OpenSSLSocketImpl.waitForHandshake(OpenSSLSocketImpl.java:690)
at com.android.org.conscrypt.OpenSSLSocketImpl.getInputStream(OpenSSLSocketImpl.java:652)
at org.jivesoftware.smack.tcp.XMPPTCPConnection.initReaderAndWriter(XMPPTCPConnection.java:703)
at org.jivesoftware.smack.tcp.XMPPTCPConnection.proceedTLSReceived(XMPPTCPConnection.java:853)
at org.jivesoftware.smack.tcp.XMPPTCPConnection.access$2000(XMPPTCPConnection.java:155)
at org.jivesoftware.smack.tcp.XMPPTCPConnection$PacketReader.parsePackets(XMPPTCPConnection.java:1171)
at org.jivesoftware.smack.tcp.XMPPTCPConnection$PacketReader.access$1000(XMPPTCPConnection.java:1092)
at org.jivesoftware.smack.tcp.XMPPTCPConnection$PacketReader$1.run(XMPPTCPConnection.java:1112)
at java.lang.Thread.run(Thread.java:764)
Caused by: java.security.cert.CertificateException: Chain validation failed
at com.android.org.conscrypt.TrustManagerImpl.verifyChain(TrustManagerImpl.java:788)
at com.android.org.conscrypt.TrustManagerImpl.checkTrustedRecursive(TrustManagerImpl.java:612)
at com.android.org.conscrypt.TrustManagerImpl.checkTrustedRecursive(TrustManagerImpl.java:633)
at com.android.org.conscrypt.TrustManagerImpl.checkTrustedRecursive(TrustManagerImpl.java:678)
at com.android.org.conscrypt.TrustManagerImpl.checkTrusted(TrustManagerImpl.java:499)
at com.android.org.conscrypt.TrustManagerImpl.checkTrusted(TrustManagerImpl.java:422)
at com.android.org.conscrypt.TrustManagerImpl.getTrustedChainForServer(TrustManagerImpl.java:343)
at android.security.net.config.NetworkSecurityTrustManager.checkServerTrusted(NetworkSecurityTrustManager.java:94)
at android.security.net.config.RootTrustManager.checkServerTrusted(RootTrustManager.java:88)
at com.android.org.conscrypt.Platform.checkServerTrusted(Platform.java:203)
at com.android.org.conscrypt.OpenSSLSocketImpl.verifyCertificateChain(OpenSSLSocketImpl.java:607)
at com.android.org.conscrypt.NativeCrypto.SSL_do_handshake(Native Method)
at com.android.org.conscrypt.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:357)
at com.android.org.conscrypt.OpenSSLSocketImpl.waitForHandshake(OpenSSLSocketImpl.java:690) 
at com.android.org.conscrypt.OpenSSLSocketImpl.getInputStream(OpenSSLSocketImpl.java:652) 
at org.jivesoftware.smack.tcp.XMPPTCPConnection.initReaderAndWriter(XMPPTCPConnection.java:703) 
at org.jivesoftware.smack.tcp.XMPPTCPConnection.proceedTLSReceived(XMPPTCPConnection.java:853) 
at org.jivesoftware.smack.tcp.XMPPTCPConnection.access$2000(XMPPTCPConnection.java:155) 
at org.jivesoftware.smack.tcp.XMPPTCPConnection$PacketReader.parsePackets(XMPPTCPConnection.java:1171) 
at org.jivesoftware.smack.tcp.XMPPTCPConnection$PacketReader.access$1000(XMPPTCPConnection.java:1092) 
at org.jivesoftware.smack.tcp.XMPPTCPConnection$PacketReader$1.run(XMPPTCPConnection.java:1112) 
at java.lang.Thread.run(Thread.java:764) 
Caused by: java.security.cert.CertPathValidatorException: timestamp check failed
at sun.security.provider.certpath.PKIXMasterCertPathValidator.validate(PKIXMasterCertPathValidator.java:133)
at sun.security.provider.certpath.PKIXCertPathValidator.validate(PKIXCertPathValidator.java:225)
at sun.security.provider.certpath.PKIXCertPathValidator.validate(PKIXCertPathValidator.java:143)
at sun.security.provider.certpath.PKIXCertPathValidator.engineValidate(PKIXCertPathValidator.java:79)
at com.android.org.conscrypt.DelegatingCertPathValidator.engineValidate(DelegatingCertPathValidator.java:44)
at java.security.cert.CertPathValidator.validate(CertPathValidator.java:301)
at com.android.org.conscrypt.TrustManagerImpl.verifyChain(TrustManagerImpl.java:784)
at com.android.org.conscrypt.TrustManagerImpl.checkTrustedRecursive(TrustManagerImpl.java:612) 
at com.android.org.conscrypt.TrustManagerImpl.checkTrustedRecursive(TrustManagerImpl.java:633) 
at com.android.org.conscrypt.TrustManagerImpl.checkTrustedRecursive(TrustManagerImpl.java:678) 
at com.android.org.conscrypt.TrustManagerImpl.checkTrusted(TrustManagerImpl.java:499) 
at com.android.org.conscrypt.TrustManagerImpl.checkTrusted(TrustManagerImpl.java:422) 
at com.android.org.conscrypt.TrustManagerImpl.getTrustedChainForServer(TrustManagerImpl.java:343) 
at android.security.net.config.NetworkSecurityTrustManager.checkServerTrusted(NetworkSecurityTrustManager.java:94) 
at android.security.net.config.RootTrustManager.checkServerTrusted(RootTrustManager.java:88) 
at com.android.org.conscrypt.Platform.checkServerTrusted(Platform.java:203) 
at com.android.org.conscrypt.OpenSSLSocketImpl.verifyCertificateChain(OpenSSLSocketImpl.java:607) 
at com.android.org.conscrypt.NativeCrypto.SSL_do_handshake(Native Method) 
at com.android.org.conscrypt.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:357) 
at com.android.org.conscrypt.OpenSSLSocketImpl.waitForHandshake(OpenSSLSocketImpl.java:690) 
at com.android.org.conscrypt.OpenSSLSocketImpl.getInputStream(OpenSSLSocketImpl.java:652) 
at org.jivesoftware.smack.tcp.XMPPTCPConnection.initReaderAndWriter(XMPPTCPConnection.java:703) 
at org.jivesoftware.smack.tcp.XMPPTCPConnection.proceedTLSReceived(XMPPTCPConnection.java:853) 
at org.jivesoftware.smack.tcp.XMPPTCPConnection.access$2000(XMPPTCPConnection.java:155) 
at org.jivesoftware.smack.tcp.XMPPTCPConnection$PacketReader.parsePackets(XMPPTCPConnection.java:1171) 
at org.jivesoftware.smack.tcp.XMPPTCPConnection$PacketReader.access$1000(XMPPTCPConnection.java:1092) 
at org.jivesoftware.smack.tcp.XMPPTCPConnection$PacketReader$1.run(XMPPTCPConnection.java:1112) 
at java.lang.Thread.run(Thread.java:764) 
Caused by: java.security.cert.CertificateExpiredException: Certificate expired at Mon Jul 22 12:04:58 MDT 2019 (compared to Mon Jul 22 21:01:46 MDT 2019)
at com.android.org.conscrypt.OpenSSLX509Certificate.checkValidity(OpenSSLX509Certificate.java:244)
at sun.security.provider.certpath.BasicChecker.verifyTimestamp(BasicChecker.java:194)
at sun.security.provider.certpath.BasicChecker.check(BasicChecker.java:144)
at sun.security.provider.certpath.PKIXMasterCertPathValidator.validate(PKIXMasterCertPathValidator.java:125)
at sun.security.provider.certpath.PKIXCertPathValidator.validate(PKIXCertPathValidator.java:225) 
at sun.security.provider.certpath.PKIXCertPathValidator.validate(PKIXCertPathValidator.java:143) 
at sun.security.provider.certpath.PKIXCertPathValidator.engineValidate(PKIXCertPathValidator.java:79) 
at com.android.org.conscrypt.DelegatingCertPathValidator.engineValidate(DelegatingCertPathValidator.java:44) 
at java.security.cert.CertPathValidator.validate(CertPathValidator.java:301) 
at com.android.org.conscrypt.TrustManagerImpl.verifyChain(TrustManagerImpl.java:784) 
at com.android.org.conscrypt.TrustManagerImpl.checkTrustedRecursive(TrustManagerImpl.java:612) 
at com.android.org.conscrypt.TrustManagerImpl.checkTrustedRecursive(TrustManagerImpl.java:633) 
at com.android.org.conscrypt.TrustManagerImpl.checkTrustedRecursive(TrustManagerImpl.java:678) 
at com.android.org.conscrypt.TrustManagerImpl.checkTrusted(TrustManagerImpl.java:499) 
at com.android.org.conscrypt.TrustManagerImpl.checkTrusted(TrustManagerImpl.java:422) 
at com.android.org.conscrypt.TrustManagerImpl.getTrustedChainForServer(TrustManagerImpl.java:343) 
at android.security.net.config.NetworkSecurityTrustManager.checkServerTrusted(NetworkSecurityTrustManager.java:94) 
at android.security.net.config.RootTrustManager.checkServerTrusted(RootTrustManager.java:88) 
at com.android.org.conscrypt.Platform.checkServerTrusted(Platform.java:203) 
at com.android.org.conscrypt.OpenSSLSocketImpl.verifyCertificateChain(OpenSSLSocketImpl.java:607) 
at com.android.org.conscrypt.NativeCrypto.SSL_do_handshake(Native Method) 
at com.android.org.conscrypt.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:357) 
at com.android.org.conscrypt.OpenSSLSocketImpl.waitForHandshake(OpenSSLSocketImpl.java:690) 
at com.android.org.conscrypt.OpenSSLSocketImpl.getInputStream(OpenSSLSocketImpl.java:652) 
at org.jivesoftware.smack.tcp.XMPPTCPConnection.initReaderAndWriter(XMPPTCPConnection.java:703) 
at org.jivesoftware.smack.tcp.XMPPTCPConnection.proceedTLSReceived(XMPPTCPConnection.java:853) 
at org.jivesoftware.smack.tcp.XMPPTCPConnection.access$2000(XMPPTCPConnection.java:155) 
at org.jivesoftware.smack.tcp.XMPPTCPConnection$PacketReader.parsePackets(XMPPTCPConnection.java:1171) 
at org.jivesoftware.smack.tcp.XMPPTCPConnection$PacketReader.access$1000(XMPPTCPConnection.java:1092) 
at org.jivesoftware.smack.tcp.XMPPTCPConnection$PacketReader$1.run(XMPPTCPConnection.java:1112) 
at java.lang.Thread.run(Thread.java:764) 
Looking at the output of openssl:
wojtek#atlantiscity.local ~ $ openssl s_client -connect xmpp.chatserver.space:5222 -xmpphost chatserver.space < /dev/null -starttls xmpp | openssl x509 -noout -dates
depth=2 O = Digital Signature Trust Co., CN = DST Root CA X3
verify return:1
depth=1 C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3
verify return:1
depth=0 CN = chatserver.space
verify return:1
poll error
notBefore=Jul 22 06:45:13 2019 GMT
notAfter=Oct 20 06:45:13 2019 GMT
It looks like they just renewed their certificate, so most likely you were served outdated certificate from the server (as would CertPathValidatorException: timestamp check failed indicate). Unfortunately you can't do anything in this case - server owner has to update the certificate on the server.
You could circumvent certificate verification but *THIS IS VERY, HIGHLY DISCOURAGED* (thus I won't go into details how to do it)

SSLV3_ALERT_CERTIFICATE_UNKNOWN during handshake in Android Q version

I have added self-signed certificate for client-server communication
using "TLSv1" protocol working perfectly in all device, but in Android Q preview during the handshake process getting the following exception
The error can be generated from procedtoUnsafe or adding exception from browser
D/FA: Logging event (FE): user_engagement(_e), Bundle[{firebase_event_origin(_o)=auto, engagement_time_msec(_et)=9551, firebase_screen_class(_sc)=HomeActivity, firebase_screen_id(_si)=-2452361814686810599}]
D/FA: Connected to remote service
W/antra.rdservic: Accessing hidden method Ljava/net/InetAddress;->holder()Ljava/net/InetAddress$InetAddressHolder; (greylist, reflection, allowed)
W/antra.rdservic: Accessing hidden method Ljava/net/InetAddress$InetAddressHolder;->getOriginalHostName()Ljava/lang/String; (greylist-max-o, reflection, denied)
W/antra.rdservic: Accessing hidden method Ldalvik/system/CloseGuard;->close()V (greylist,core-platform-api, linking, allowed)
W/System.err: javax.net.ssl.SSLHandshakeException: Handshake failed
W/System.err: at com.google.android.gms.org.conscrypt.ConscryptFileDescriptorSocket.startHandshake(:com.google.android.gms#17122037#17.1.22 (100400-245988633):35)
W/System.err: at com.google.android.gms.org.conscrypt.ConscryptFileDescriptorSocket.waitForHandshake(:com.google.android.gms#17122037#17.1.22 (100400-245988633):1)
W/System.err: at com.google.android.gms.org.conscrypt.ConscryptFileDescriptorSocket.getOutputStream(:com.google.android.gms#17122037#17.1.22 (100400-245988633):5)
W/System.err: at com.mantra.rdservice.sslservice.SslServer.runSecureServer(SslServer.java:121)
W/System.err: at com.mantra.rdservice.sslservice.SslServer.runServer(SslServer.java:157)
W/System.err: at com.mantra.rdservice.sslservice.SslServer.findPort(SslServer.java:106)
W/System.err: at com.mantra.rdservice.sslservice.SecureService$1.run(SecureService.java:74)
W/System.err: at java.lang.Thread.run(Thread.java:919)
W/System.err: Caused by: javax.net.ssl.SSLProtocolException: SSL handshake aborted: ssl=0xc386a398: Failure in SSL library, usually a protocol error
W/System.err: error:10000416:SSL routines:OPENSSL_internal:SSLV3_ALERT_CERTIFICATE_UNKNOWN (third_party/openssl/boringssl/src/ssl/tls_record.cc:587 0xc5e7a888:0x00000001)
W/System.err: at com.google.android.gms.org.conscrypt.NativeCrypto.SSL_do_handshake(Native Method)
W/System.err: at com.google.android.gms.org.conscrypt.NativeSsl.doHandshake(:com.google.android.gms#17122037#17.1.22 (100400-245988633):7)
W/System.err: at com.google.android.gms.org.conscrypt.ConscryptFileDescriptorSocket.startHandshake(:com.google.android.gms#17122037#17.1.22 (100400-245988633):14)
W/System.err: ... 7 more
W/antra.rdservic: Accessing hidden method Ljava/net/InetAddress$InetAddressHolder;->getOriginalHostName()Ljava/lang/String; (greylist-max-o, reflection, denied)
W/antra.rdservic: Accessing hidden method Ljava/net/InetAddress$InetAddressHolder;->getOriginalHostName()Ljava/lang/String; (greylist-max-o, reflection, denied)
i have added function that created connection
Loopback ="127.0.0.1";
private void runSecureServer(final int port) throws Exception {
final ServerSocket socket = createSSLSocket();
socket.bind(new InetSocketAddress(Loopback, port));
socket.setReuseAddress(true);
this._url = "https://" + Loopback + ":" + String.valueOf(port) + "/";
while (true) {
try {
Socket client = socket.accept();
PrintWriter outputStream = new PrintWriter(client.getOutputStream(), true);
BufferedReader inputStream = new BufferedReader(new InputStreamReader(client.getInputStream()));
StringBuilder finalData = new StringBuilder();
String inputLine;
while ((inputLine = inputStream.readLine()) != null && !inputLine.equals("")) {
finalData.append(inputLine).append("\r\n");
}
executorService.execute(new HttpProcessor(ctx, _url, client, outputStream, inputStream, finalData.toString()));
} catch (Exception ex) {
ex.printStackTrace();
socket.close();
runServer(port);
break;
}
}
}
I have referred StackOverflow question but no solution found

retrofit + okhttp on android 4 ssl

I found out that android 4 doesn't play well with ssl , when trying to contact an api with https it causes a crash
javax.net.ssl.SSLException: SSL handshake aborted: ssl=0xb8dbad20: I/O error during system call, Connection reset by peer
Here's what i tried from other similar questions:
if (Build.VERSION.SDK_INT >= 16 && Build.VERSION.SDK_INT < 22) {
try {
Logger.e("under lolipop");
SSLContext sc = SSLContext.getInstance("TLS");
sc.init(null, new TrustManager[] { new MyTrustManager() }, new SecureRandom());
client.sslSocketFactory(sc.getSocketFactory());
} catch (Exception e) {
Logger.e("HTTPS"+ e.getMessage() );
}
}
Which didn't effect the outcome
And
if (Build.VERSION.SDK_INT >= 16 && Build.VERSION.SDK_INT < 22) {
try {
client.sslSocketFactory(new TLSSocketFactory(), (X509TrustManager)trustAllCerts[0])
.build();
Logger.e("SETUP TRUST SSL");
return client.build();
} catch (KeyManagementException e) {
Logger.e("SETUP TRUST SSL Failed "+e.getMessage());
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
Logger.e("SETUP TRUST SSL Failed "+e.getMessage());
e.printStackTrace();
}
}
return client.build();
}
final TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {
#Override
public void checkClientTrusted(
java.security.cert.X509Certificate[] chain,
String authType) throws CertificateException {
}
#Override
public void checkServerTrusted(
java.security.cert.X509Certificate[] chain,
String authType) throws CertificateException {
}
#Override
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return new java.security.cert.X509Certificate[0];
}
} };
This code gives a different error :
java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
Is there anyway to fix this , I must support android 4 and also use https ,
Any help will do !
I ran into a similar issue on Android 4.4 some time ago when our backend dropped support for TLS 1.0 and 1.1. I solved this by installing a new security provider with Google Play Services ProviderInstaller.
In your apps gradle.build file add
implementation "com.google.android.gms:play-services-auth:16.0.1"
In your startup Activity call ProviderInstaller.installIfNeeded() as early as possible. Here is an example method that tries to install the provider:
private static void installGooglePlayServicesProvider(Context context) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { //Devices with Android 5.1+ should support TLS 1.x out of the box
try {
ProviderInstaller.installIfNeeded(context);
} catch (GooglePlayServicesRepairableException e) {
Log.e("ProviderInstaller", "Google Play Services is out of date!", e);
GoogleApiAvailability.getInstance().showErrorNotification(context, e.getConnectionStatusCode());
} catch (GooglePlayServicesNotAvailableException e) {
Log.e("ProviderInstaller", "Google Play Services is unavailable!", e);
}
}
}
For more information on ProviderInstaller see Goolge developer page:
Patch the security provider with ProviderInstaller
When using TLS 1.2 you might have to force enable support on some devices.
Take a look at the following acticle and their Tls12SocketFactory implementation: Working with TLS 1.2 on Android 4.4 and Lower
Okhttp 3.13.x has dropped support for TLS1.2 and below and only support for Android API 21+. You will have to use Okhttp 3.12.x version branch for using it with Android 4.x devices.
More here

Reduced file size when uploading files using Dropbox Core API v2

We are using Dropbox API v2 in our Android app to upload database files (.db) to a user's Dropbox App folder. Below is the code for uploading file:
InputStream inputStream = null;
FileMetadata obj = null;
try {
inputStream = new FileInputStream(dbFile);
obj = mDbxClient.files().uploadBuilder(remoteFilePath)
.withMode(WriteMode.OVERWRITE)
.uploadAndFinish(inputStream);
} catch (DbxException | IOException e) {
obj = null;
mException = e;
} finally {
if (inputStream != null)
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
The same file is uploaded in quick succession 3-4 times.
Now, everything works fine when Internet speed is fast (4G, Wifi) but when a user switches to 2G/3G network, the file isn't uploaded fully. The callback method onUploadComplete() is called but the file size here has drastically reduced. I have attached the version history of a database file.
https://www.dropbox.com/s/s7y43707ic1kqxg/dropbox.jpg?dl=0
You can see that the file size suddenly reduces to 104KB. This becomes a corrupt database file.
Is there any way to fix this?
Should I change the upload method? (maybe use UploadSession()
Or
Uploads shouldn't be called in quick succession?
Please guide
EDIT:
Below is the call to upload file:
AsyncTaskCompat.executeParallel(new DropboxUploadFileTask(DropboxClientFactory.getClient(), new DropboxUploadFileTask.Callback() {
#Override
public void onUploadComplete(FileMetadata result) {
String message = result.getName() + " size " + result.getSize() + " modified " +
java.text.DateFormat.getDateTimeInstance().format(result.getClientModified());
Log.i("BKSync upload ends: ", message);
}
#Override
public void onError(Exception e) {
Log.e("BKSync", "Failed to upload file.", e);
}
}, context), glDbName, "");
class DropboxUploadFileTask extends AsyncTask<String, Void, FileMetadata> {
private final DbxClientV2 mDbxClient;
private final Callback mCallback;
private Exception mException;
private Context mContext;
public interface Callback {
void onUploadComplete(FileMetadata result);
void onError(Exception e);
}
DropboxUploadFileTask(DbxClientV2 dbxClient, Callback callback, Context context) {
mDbxClient = dbxClient;
mCallback = callback;
mContext = context;
}
#Override
protected void onPreExecute() {
Log.e("BKSync", "upload starts");
}
#Override
protected void onPostExecute(FileMetadata result) {
Log.e("BKSync", "upload ends");
super.onPostExecute(result);
if (mException != null) {
mCallback.onError(mException);
} else if (result == null) {
mCallback.onError(null);
} else {
mCallback.onUploadComplete(result);
}
}
#Override
protected FileMetadata doInBackground(String... params) {
String dbFileName = params[0];
File dbFile = mContext.getDatabasePath(dbFileName);
String remoteFolderPath = params[1];
String remoteFileName = dbFile.getName();
InputStream inputStream = null;
FileMetadata obj = null;
try {
inputStream = new FileInputStream(dbFile);
obj = mDbxClient.files().uploadBuilder(remoteFolderPath + "/" + remoteFileName)
.withMode(WriteMode.OVERWRITE)
.uploadAndFinish(inputStream);
} catch (DbxException | IOException e) {
obj = null;
mException = e;
Log.e("BKSync", "exception1");
mException.printStackTrace();
} finally {
if (inputStream != null)
try {
inputStream.close();
} catch (IOException e) {
Log.e("BKSync", "exception2");
e.printStackTrace();
}
}
return obj;
}
}
And below is the log:
05-29 12:08:06.322 11232-11232/com.bk E/BKSync: upload starts
05-29 12:08:13.129 11232-11232/com.bk E/BKSync: upload ends
05-29 12:08:13.130 11232-11232/com.bk I/BKSync upload ends:: demo2_local.db size 692224 modified May 29, 2018 12:08:13 PM
05-29 12:08:13.471 11232-11232/com.bk E/BKSync: upload starts
05-29 12:08:22.992 11232-11232/com.bk E/BKSync: upload ends
05-29 12:08:22.993 11232-11232/com.bk I/BKSync upload ends:: demo2_local.db size 692224 modified May 29, 2018 12:08:23 PM
05-29 12:08:45.181 11232-11232/com.bk E/BKSync: upload starts
05-29 12:08:48.692 11232-11232/com.bk E/BKSync: upload starts
05-29 12:08:49.137 11232-11232/com.bk E/BKSync: upload starts
05-29 12:08:51.962 11232-11232/com.bk E/BKSync: upload starts
f05-29 12:09:24.183 11232-30020/com.bk E/BKSync: exception1
05-29 12:09:24.184 11232-30020/com.bk W/System.err: com.dropbox.core.NetworkIOException: Unable to resolve host "content.dropboxapi.com": No address associated with hostname
at com.dropbox.core.DbxUploader.finish(DbxUploader.java:235)
at com.dropbox.core.DbxUploader.uploadAndFinish(DbxUploader.java:106)
at com.dropbox.core.v2.DbxUploadStyleBuilder.uploadAndFinish(DbxUploadStyleBuilder.java:92)
05-29 12:09:24.185 11232-30020/com.bk W/System.err: at com.bk.DropboxUploadFileTask.doInBackground(DropboxUploadFileTask.java:81)
at com.bkbk.DropboxUploadFileTask.doInBackground(DropboxUploadFileTask.java:20)
at android.os.AsyncTask$2.call(AsyncTask.java:304)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
at java.lang.Thread.run(Thread.java:762)
05-29 12:09:24.189 11232-30020/com.bk W/System.err: Caused by: java.net.UnknownHostException: Unable to resolve host "content.dropboxapi.com": No address associated with hostname
at java.net.Inet6AddressImpl.lookupHostByName(Inet6AddressImpl.java:125)
at java.net.Inet6AddressImpl.lookupAllHostAddr(Inet6AddressImpl.java:74)
at java.net.InetAddress.getAllByName(InetAddress.java:752)
at okhttp3.Dns$1.lookup(Dns.java:39)
at okhttp3.internal.connection.RouteSelector.resetNextInetSocketAddress(RouteSelector.java:185)
at okhttp3.internal.connection.RouteSelector.nextProxy(RouteSelector.java:149)
at okhttp3.internal.connection.RouteSelector.next(RouteSelector.java:84)
05-29 12:09:24.190 11232-30020/com.bk W/System.err: at okhttp3.internal.connection.StreamAllocation.findConnection(StreamAllocation.java:213)
at okhttp3.internal.connection.StreamAllocation.findHealthyConnection(StreamAllocation.java:134)
at okhttp3.internal.connection.StreamAllocation.newStream(StreamAllocation.java:113)
at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.java:42)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
05-29 12:09:24.193 11232-30020/com.bk W/System.err: at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.java:93)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
05-29 12:09:24.194 11232-30020/com.bk W/System.err: at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
at okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.java:93)
05-29 12:09:24.195 11232-30020/com.bk W/System.err: at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.java:125)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:200)
at okhttp3.RealCall$AsyncCall.execute(RealCall.java:147)
at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32)
... 3 more
05-29 12:09:24.196 11232-30020/com.bk W/System.err: Caused by: android.system.GaiException: android_getaddrinfo failed: EAI_NODATA (No address associated with hostname)
at libcore.io.Posix.android_getaddrinfo(Native Method)
at libcore.io.ForwardingOs.android_getaddrinfo(ForwardingOs.java:55)
at java.net.Inet6AddressImpl.lookupHostByName(Inet6AddressImpl.java:106)
... 26 more
05-29 12:09:24.211 11232-11232/com.bk E/BKSync: upload ends
Failed to upload file.
05-29 12:09:24.300 11232-11232/com.bk E/BKSync: upload starts
05-29 12:09:24.314 11232-30020/com.bk E/BKSync: exception1
05-29 12:09:24.315 11232-30020/com.bk W/System.err: com.dropbox.core.NetworkIOException: Pipe closed
at com.dropbox.core.DbxUploader.uploadAndFinish(DbxUploader.java:103)
at com.dropbox.core.v2.DbxUploadStyleBuilder.uploadAndFinish(DbxUploadStyleBuilder.java:92)
at com.bk.DropboxUploadFileTask.doInBackground(DropboxUploadFileTask.java:81)
at com.bk.DropboxUploadFileTask.doInBackground(DropboxUploadFileTask.java:20)
at android.os.AsyncTask$2.call(AsyncTask.java:304)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
05-29 12:09:24.316 11232-30020/com.bk W/System.err: at java.lang.Thread.run(Thread.java:762)
Caused by: com.dropbox.core.util.IOUtil$WriteException: Pipe closed
at com.dropbox.core.util.IOUtil.copyStreamToStream(IOUtil.java:61)
at com.dropbox.core.util.IOUtil.copyStreamToStream(IOUtil.java:68)
at com.dropbox.core.util.IOUtil.copyStreamToStream(IOUtil.java:43)
at com.dropbox.core.http.HttpRequestor$Uploader.upload(HttpRequestor.java:98)
at com.dropbox.core.DbxUploader.uploadAndFinish(DbxUploader.java:98)
... 8 more
05-29 12:09:24.318 11232-30020/com.bk W/System.err: Caused by: java.io.IOException: Pipe closed
at java.io.PipedInputStream.checkStateForReceive(PipedInputStream.java:267)
at java.io.PipedInputStream.receive(PipedInputStream.java:233)
at java.io.PipedOutputStream.write(PipedOutputStream.java:149)
at com.dropbox.core.util.IOUtil.copyStreamToStream(IOUtil.java:59)
... 12 more
05-29 12:09:24.441 11232-11232/com.bk E/BKSync: upload ends
05-29 12:09:24.442 11232-11232/com.bk E/BKSync: Failed to upload file.
com.dropbox.core.NetworkIOException: Pipe closed
at com.dropbox.core.DbxUploader.uploadAndFinish(DbxUploader.java:103)
at com.dropbox.core.v2.DbxUploadStyleBuilder.uploadAndFinish(DbxUploadStyleBuilder.java:92)
at com.bk.DropboxUploadFileTask.doInBackground(DropboxUploadFileTask.java:81)
at com.bk.DropboxUploadFileTask.doInBackground(DropboxUploadFileTask.java:20)
at android.os.AsyncTask$2.call(AsyncTask.java:304)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
at java.lang.Thread.run(Thread.java:762)
Caused by: com.dropbox.core.util.IOUtil$WriteException: Pipe closed
at com.dropbox.core.util.IOUtil.copyStreamToStream(IOUtil.java:61)
at com.dropbox.core.util.IOUtil.copyStreamToStream(IOUtil.java:68)
at com.dropbox.core.util.IOUtil.copyStreamToStream(IOUtil.java:43)
at com.dropbox.core.http.HttpRequestor$Uploader.upload(HttpRequestor.java:98)
at com.dropbox.core.DbxUploader.uploadAndFinish(DbxUploader.java:98)
at com.dropbox.core.v2.DbxUploadStyleBuilder.uploadAndFinish(DbxUploadStyleBuilder.java:92) 
at com.bk.DropboxUploadFileTask.doInBackground(DropboxUploadFileTask.java:81) 
at com.bk.DropboxUploadFileTask.doInBackground(DropboxUploadFileTask.java:20) 
at android.os.AsyncTask$2.call(AsyncTask.java:304) 
at java.util.concurrent.FutureTask.run(FutureTask.java:237) 
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133) 
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607) 
at java.lang.Thread.run(Thread.java:762) 
Caused by: java.io.IOException: Pipe closed
at java.io.PipedInputStream.checkStateForReceive(PipedInputStream.java:267)
at java.io.PipedInputStream.receive(PipedInputStream.java:233)
at java.io.PipedOutputStream.write(PipedOutputStream.java:149)
at com.dropbox.core.util.IOUtil.copyStreamToStream(IOUtil.java:59)
at com.dropbox.core.util.IOUtil.copyStreamToStream(IOUtil.java:68) 
at com.dropbox.core.util.IOUtil.copyStreamToStream(IOUtil.java:43) 
at com.dropbox.core.http.HttpRequestor$Uploader.upload(HttpRequestor.java:98) 
at com.dropbox.core.DbxUploader.uploadAndFinish(DbxUploader.java:98) 
at com.dropbox.core.v2.DbxUploadStyleBuilder.uploadAndFinish(DbxUploadStyleBuilder.java:92) 
at com.bk.DropboxUploadFileTask.doInBackground(DropboxUploadFileTask.java:81) 
at com.bk.DropboxUploadFileTask.doInBackground(DropboxUploadFileTask.java:20) 
at android.os.AsyncTask$2.call(AsyncTask.java:304) 
at java.util.concurrent.FutureTask.run(FutureTask.java:237) 
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133) 
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607) 
at java.lang.Thread.run(Thread.java:762) 
As you can see, exceptions raised by the app.
Issue occurs when user starts upload on 4G and then due to incoming call, network switches to 3G. File size on Dropbox reduces drastically then.
Please help.
I've created an issue on github: https://github.com/dropbox/dropbox-sdk-java/issues/191 for tracking. It looks like a bug in Uploader code. But we don't have plan to immediately fix it and release a new version.
So my suggestion of work around would be:
If you get an error and meanwhile the partial file was uploaded to Dropbox, please make sure you retry after error.
If you don't get error and the partial file was saved. (unlikely). You may want to compare the content hash of the file you just uploaded. The content hash is returned as the result of upload. And for the hash function you can refer https://www.dropbox.com/developers/reference/content-hash

java.io.IOException: Hostname was not verified [duplicate]

This question already has answers here:
Https Connection Android
(11 answers)
Closed 7 months ago.
I am trying to connect to a URL from a my Android app in Andorid Version 4.1.1, and I get the error indicated in the Title of my question, but when I tried to connect the same URL from Andorid Version 4.0.4 or 3.1, all works fine.
The Code fragment :
try {
.
.
.
URL url = new URL(urlStr);
Log.i(TAG,"[ URL ] " + urlStr);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
int size = conn.getContentLength();
int responsecode = conn.getResponseCode();
Log.d(TAG, "Responsecode: " + responsecode);
.
.
.
} catch (Exception e) {
e.printStackTrace();
}
private static void trustAllHosts() {
TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return new java.security.cert.X509Certificate[] {};
}
public void checkClientTrusted(X509Certificate[] chain,
String authType) throws CertificateException {
}
public void checkServerTrusted(X509Certificate[] chain,
String authType) throws CertificateException {
}
} };
try {
SSLContext sc = SSLContext.getInstance("TLS");
sc.init(null, trustAllCerts, new java.security.SecureRandom());
HttpsURLConnection
.setDefaultSSLSocketFactory(sc.getSocketFactory());
} catch (Exception e) {
System.out.println("IOException : HTTPSRequest::trustAllHosts");
e.printStackTrace();
}
}
But here i clear one thing is that "Maybe certificate is that self-signed certificates and is not including them in a KeyStore.
I do not understand why this excepton occure only in Android Verison 4.1.1 OS
Thanks.
FULL STACK TRACE
01-31 10:26:08.348: W/System.err(3158): java.io.IOException: Hostname <URL> was not verified
01-31 10:26:08.348: W/System.err(3158): at libcore.net.http.HttpConnection.verifySecureSocketHostname(HttpConnection.java:223)
01-31 10:26:08.348: W/System.err(3158): at libcore.net.http.HttpsURLConnectionImpl$HttpsEngine.connect(HttpsURLConnectionImpl.java:446)
01-31 10:26:08.348: W/System.err(3158): at libcore.net.http.HttpEngine.sendSocketRequest(HttpEngine.java:289)
01-31 10:26:08.348: W/System.err(3158): at libcore.net.http.HttpEngine.sendRequest(HttpEngine.java:239)
01-31 10:26:08.348: W/System.err(3158): at libcore.net.http.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:273)
01-31 10:26:08.348: W/System.err(3158): at libcore.net.http.HttpURLConnectionImpl.getHeaderField(HttpURLConnectionImpl.java:130)
01-31 10:26:08.348: W/System.err(3158): at java.net.URLConnection.getHeaderFieldInt(URLConnection.java:544)
01-31 10:26:08.348: W/System.err(3158): at java.net.URLConnection.getContentLength(URLConnection.java:316)
01-31 10:26:08.348: W/System.err(3158): at libcore.net.http.HttpsURLConnectionImpl.getContentLength(HttpsURLConnectionImpl.java:191)
01-31 10:26:08.348: W/System.err(3158): at com.ih.util.HelpVideoServices$downloadTask.run(HelpVideoServices.java:172)
In case you are running with certificates that doesn't mean anything and you want to bypass them you also need to add a null host name verifier to make this code work
HttpsURLConnection.setDefaultHostnameVerifier(new NullHostNameVerifier());
SSLContext context = SSLContext.getInstance("TLS");
context.init(null, new X509TrustManager[]{new NullX509TrustManager()}, new SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(context.getSocketFactory());
And the code for the host:
import javax.net.ssl.HostnameVerifier ;
import javax.net.ssl.SSLSession;
public class NullHostNameVerifier implements HostnameVerifier {
#Override
public boolean verify(String hostname, SSLSession session) {
Log.i("RestUtilImpl", "Approving certificate for " + hostname);
return true;
}
}
This needs to run once, but if you are making changes to your connection object you might need to run it again.
In addition to #Noam's answer, this is a complete example:
/**
* Disables the SSL certificate checking for new instances of {#link HttpsURLConnection} This has been created to
* aid testing on a local box, not for use on production.
*/
private static void disableSSLCertificateChecking() {
TrustManager[] trustAllCerts = new TrustManager[] {
new X509TrustManager() {
#Override
public void checkClientTrusted(java.security.cert.X509Certificate[] x509Certificates, String s) throws java.security.cert.CertificateException {
// not implemented
}
#Override
public void checkServerTrusted(java.security.cert.X509Certificate[] x509Certificates, String s) throws java.security.cert.CertificateException {
// not implemented
}
#Override
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null;
}
}
};
try {
HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {
#Override
public boolean verify(String s, SSLSession sslSession) {
return true;
}
});
SSLContext sc = SSLContext.getInstance("TLS");
sc.init(null, trustAllCerts, new java.security.SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
} catch (KeyManagementException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
}
Hope it helps
This might happen because the CN (Common Name) you have declared on your SSL does not mach the actual URL you are sending your HTTP request too.
If so, create a new SSL and enter the currect CN. That should fix the problem.
I experienced this problem in 4.1.1 and 4.1.2, using HTTPSUrlConnection.
After some poking around I discovered that it was because the Apache server I am dealing with has multiple virtual hosts serving https traffic, resulting in SNI issues in Android - at least prior to JellyBean (I have unconfirmed reports that it was working in JB).
In my case there were 3 virtual hosts serving https traffic:
mydomain.com
api.mydomain.com (the one I was trying to deal with)
admin.mydomain.com
Probing api.* with openssl_client like this:
openssl s_client -debug -connect api.mydomain.com:443
... always returned the root domain's certificate - buried in the output was something like:
Certificate chain
0 s:/OU=Domain Control Validated/CN=mydomain.com
...
... specifying the server name in the openssl_client command-line:
openssl s_client -debug -servername api.mydomain.com -connect api.mydomain.com:443
... returned the certificate I was expecting to see:
Certificate chain
0 s:/OU=Domain Control Validated/CN=api.mydomain.com
I was able to resolve the problem by moving the root domain virtual-host to a different physical host.
It seems that the Android HostnameVerifier can live with multiple sub-domain's side-by-side as virtual hosts, but having the root domain as a virtual-host in the same apache caused issues.
I am not a sys-admin/dev-ops and so it is possible that there are Apache config options that could have resolved the problem that I am not aware of.
Please note SSL Certificate work only by Domain not work by IP address.
if you use IP ,insert below code
HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier()
{
#Override
public boolean verify(String hostname, SSLSession session)
{
if(hostname.equals("127.0.0.1"))
return true;
}
});
Android can't set up SSL connection, I suppose. Maybe your certificate for other host name, not the one you establish connection to. Read docs here and here.
This works better for me --> CHANGING StrictHostnameVerifier()
https://developer.android.com/reference/org/apache/http/conn/ssl/StrictHostnameVerifier
Example
HostnameVerifier hostnameVerifier = new HostnameVerifier() {
#Override
public boolean verify(String hostname, SSLSession session) {
HostnameVerifier hv = new StrictHostnameVerifier();
return hv.verify("example.com", session);
}
};
Use Example https://developer.android.com/training/articles/security-ssl#java
// Tell the URLConnection to use our HostnameVerifier
URL url = new URL("https://example.org/");
HttpsURLConnection urlConnection =
(HttpsURLConnection)url.openConnection();
urlConnection.setHostnameVerifier(hostnameVerifier);
From Amazon documentation:
Bucket Restrictions
"When using virtual hosted–style buckets with SSL, the SSL wild card certificate only matches buckets that do not contain periods. To work around this, use HTTP or write your own certificate verification logic."
The easiest way seems to create a unique bucket name without periods:
Instead of "bucketname.mycompany.com", something like "bucketnamemycompany" or any other DNS-compliant bucket name.
In Kotlin:
fun HttpsURLConnection.trustCert() {
try {
//Accepts every hostname
this.hostnameVerifier = HostnameVerifier { hostname, _ ->
println(hostname) //To be hardcoded/as needed
true
}
val trustMgr:Array<TrustManager> = arrayOf(object : X509TrustManager {
override fun checkClientTrusted(certs: Array<out X509Certificate>?, authType: String?) {}
override fun checkServerTrusted(certs: Array<out X509Certificate>?, authType: String?) {}
override fun getAcceptedIssuers(): Array<X509Certificate>? = null
})
this.sslSocketFactory = SSLContext.getInstance("TLS").also {
it.init(null, trustMgr, SecureRandom())
}.socketFactory
} catch (e: Exception) {
prinntln("SSL self-signed certificate processing error due to ${e.message}")
}
}
Usage:
val conn = URL(Uri.Builder().also {
it.scheme("https")
it.encodedAuthority("$serverIp:$serverPort")
}.build().toString()).openConnection() as HttpsURLConnection
conn.trustCert()
val respCode = conn.responseCode
if(respCode == 200) {
//do something (eg: read inputStream)
}

Categories

Resources