I have a problem verifying Verisign certificate when trying to connect with HttpsURLConnection to our server.
Current certification chain: $openssl s_client -connect host:443
0 s:/C=AT/ST=xxx/L=xxx/O=xxx/CN=host i:/C=US/O=VeriSign, Inc./OU=VeriSign Trust Network/OU=Terms of use at https://www.verisign.com/rpa (c)10/CN=VeriSign Class 3 International Server CA - G3 1 s:/C=US/O=VeriSign, Inc./OU=VeriSign Trust Network/OU=Terms of use at https://www.verisign.com/rpa (c)10/CN=VeriSign Class 3 International Server CA - G3 i:/C=US/O=VeriSign, Inc./OU=VeriSign Trust Network/OU=(c) 2006 VeriSign, Inc. - For authorized use only/CN=VeriSign Class 3 Public Primary Certification Auth ority - G5 2 s:/C=US/O=VeriSign, Inc./OU=VeriSign Trust Network/OU=(c) 2006 VeriSign, Inc. - For authorized use only/CN=VeriSign Class 3 Public Primary Certification Auth ority - G5 i:/C=US/O=VeriSign, Inc./OU=Class 3 Public Primary Certification Authority 3 s:/C=US/O=VeriSign, Inc./OU=Class 3 Public Primary Certification Authority i:/C=US/O=VeriSign, Inc./OU=Class 3 Public Primary Certification Authority
I am sure that I downloaded and added all the certificates in KeyStore, but I still get the exception: " javax.net.ssl.SSLException: certificate without a trusted server " and the reason for this is java.security.cert.CertificateException: java.security.cert.CertPathValidatorException: TrustAnchor found but certificate validation failed.
My code to get the connection:
String keyStoreType = KeyStore.getDefaultType(); KeyStore keyStore = KeyStore.getInstance(keyStoreType); keyStore.load(null, null); keyStore.setCertificateEntry("verisign_0", getVerisign0()); keyStore.setCertificateEntry("verisign_1", getVerisign1()); keyStore.setCertificateEntry("verisign_2", getVerisign2()); keyStore.setCertificateEntry("verisign_3", getVerisign3()); String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm(); TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm); tmf.init(keyStore); SSLContext context = SSLContext.getInstance("TLS"); context.init(null, tmf.getTrustManagers(), null); HttpsURLConnection urlConnection = (HttpsURLConnection) url.openConnection(); urlConnection.setSSLSocketFactory(context.getSocketFactory()); return urlConnection;
a problem occurs when connection.connect() called. All getVerisign () methods return the correct certificates. Is there any step that I forgot? Maybe a special order in which certificates should be added?
Just to clarify, I used this particular technique with swisssign certificates, and it worked. I ran into this problem because some of the Android 2.1, 2.2 devices do not have some root certificates. Thanks in advance.
Stacktrace:
[0] = { java.lang.StackTraceElement@830078967208 }"org.apache.harmony.xnet.provider.jsse.TrustManagerImpl.checkServerTrusted(TrustManagerImpl.java:168)" [1] = { java.lang.StackTraceElement@830078967584 }"org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:366)" [2] = { java.lang.StackTraceElement@830078967960 }"org.apache.harmony.luni.internal.net.www.protocol.http.HttpConnection.getSecureSocket(HttpConnection.java:168)" [3] = { java.lang.StackTraceElement@830078968368 }"org.apache.harmony.luni.internal.net.www.protocol.https.HttpsURLConnectionImpl$HttpsEngine.connect(HttpsURLConnectionImpl.java:399)" [4] = { java.lang.StackTraceElement@830078968816 }"org.apache.harmony.luni.internal.net.www.protocol.https.HttpsURLConnectionImpl.connect(HttpsURLConnectionImpl.java:147)"