Trust anchor for certificate path not found when using more than 3g, but works fine via WiFi

My android project uses api 15. I connect to the server via https using the HttpsURLConnection class. Everything works fine on WiFi, but if I turn off WiFi and go through 3g, I get the following:

javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found. at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:413) at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:257) at libcore.net.http.HttpConnection.setupSecureSocket(HttpConnection.java:210) at libcore.net.http.HttpsURLConnectionImpl$HttpsEngine.makeSslConnection(HttpsURLConnectionImpl.java:477) at libcore.net.http.HttpsURLConnectionImpl$HttpsEngine.connect(HttpsURLConnectionImpl.java:432) at libcore.net.http.HttpEngine.sendSocketRequest(HttpEngine.java:282) at libcore.net.http.HttpEngine.sendRequest(HttpEngine.java:232) at libcore.net.http.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:80) at libcore.net.http.HttpURLConnectionImpl.getOutputStream(HttpURLConnectionImpl.java:188) at libcore.net.http.HttpsURLConnectionImpl.getOutputStream(HttpsURLConnectionImpl.java:280) 

If I do something wrong, why will it work via Wi-Fi?

A bit more info here.

If I use openssl to view server certificate information,

 echo | openssl s_client -connect myserver.com:443 

returns a self-signed server level certificate, whereas

 echo | openssl s_client -connect myserver.com:443 -servername myserver.com 

returns the "correct" certificate. I have several vhosts on my server, each with its own certificate issued by rapidssl, so I think that means I need to use a client with TLS support. At least this is my interpretation of the message that I see in my Apache log at startup:

 Name-based SSL virtual hosts only work for clients with TLS server name indication support 

If I'm right so far, does this mean that my 3G mobile network may depend on TLS or is there something else that I have to do?

I can get things to work on 3g by subclassing DefaultHttpClient and import a keystore containing self-signed server certificates, but this is definitely not my preferred option.

+7
source share
1 answer

Adding the -servername parameter simply sets the Server Name Indication field in the Client Hello message, which helps us choose the right certificate if the target host contains a lot, as in your case. However, this is not a problem.

During SSL confirmation, certificates are delivered in pairs of the subject / issuer, forming a chain of certificates.

those. The google.com certificate chain is as follows:

 openssl s_client -connect google.com:443 CONNECTED(00000003) depth=2 C = US, O = GeoTrust Inc., CN = GeoTrust Global CA verify error:num=20:unable to get local issuer certificate verify return:0 --- Certificate chain 0 s:/C=US/ST=California/L=Mountain View/O=Google Inc/CN=*.google.com i:/C=US/O=Google Inc/CN=Google Internet Authority G2 1 s:/C=US/O=Google Inc/CN=Google Internet Authority G2 i:/C=US/O=GeoTrust Inc./CN=GeoTrust Global CA 2 s:/C=US/O=GeoTrust Inc./CN=GeoTrust Global CA i:/C=US/O=Equifax/OU=Equifax Secure Certificate Authority --- 

After receiving, the client tries to check all issuers in the chain from the bottom up (root). If the client could not verify the root certificate, the message Trust anchor for certification path not found appears.

So, back to the Wi-Fi / 3G problem, your mobile DNS network may not be able to resolve the address of one of the medium issuers in the certificate chain.

UPDATE:

You can put certificates of your issuers in your APK and add them through your TrustManager to your code. This approach can overcome the limitations of the access network (if any).

0
source

All Articles