I'm getting certificate verification errors from a simple SSLSocket (Java 8 u45) connection to a site with a valid certificate and domain.
String hostName = "www.velocityfrequentflyer.com";
SSLSocketFactory factory = (SSLSocketFactory) SSLSocketFactory.getDefault();
SSLSocket sslsocket = (SSLSocket) factory.createSocket(hostName, 443);
SSLSession session = sslsocket.getSession();
java.security.cert.Certificate certicates[] = session.getPeerCertificates();
X509Certificate cert = (X509Certificate) certicates[0]; //the peer certificate
System.out.println("cert.getIssuerDN().getName(): " + cert.getIssuerDN().getName());
System.out.println("cert.getSubjectDN().getName(): " + cert.getSubjectDN().getName());
Exception in thread "main" javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated at sun.security.ssl.SSLSessionImpl.getPeerCertificates(SSLSessionImpl.java:431) at sslconnecting.Sslconnecting.main(Sslconnecting.java:33)
Looking at the certificate with OpenSSL everthing seems to be in order including the www. prefix and every browser I have tried this site on is happy with the certificate.
openssl s_client -showcerts -connect www.velocityfrequentflyer.com:443 | openssl x509 -noout -text | less
X509v3 extensions: X509v3 Subject Alternative Name: DNS:www.velocityfrequentflyer.com
Interestingly this works if I change the host to velocityfrequentflyer.com which has me really stumped.
Is there a way to call getPeerCertificates without JAVA doing checks?
I have tried using a TrustAll SocketFactory with the same result.
Edit 1:
After adding startHandshake() it seems its the handshake itself that is failing: ( Full SSL Debug: http://pastebin.com/ZKnjrGPR )
Exception in thread "main" javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure at sun.security.ssl.Alerts.getSSLException(Unknown Source) at sun.security.ssl.Alerts.getSSLException(Unknown Source) at sun.security.ssl.SSLSocketImpl.recvAlert(Unknown Source) at sun.security.ssl.SSLSocketImpl.readRecord(Unknown Source) at sun.security.ssl.SSLSocketImpl.performInitialHandshake(Unknown Source) at sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source) at sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source) at sslconnecting.Sslconnecting.main(Sslconnecting.java:33)
Edit 2.
Turns out the site requires insecure cipher suite RC4? The java.security configuration is set to not use them.
jdk.tls.disabledAlgorithms=SSLv3,RC4
However as soon as RC4 is allowed the handshake completes. It still doesn't explain why the handshake goes through without the www. prefix.
startHandshake()
beforegetSession()
. It shouldn't make any difference, but ... – user207421