3

I try to use SOAPConnection to call https, and I have already point to keystore and truststore as follow:

    System.setProperty("javax.net.ssl.keyStore", "C:/kei/tasks/MIP/Cert/ccc_acp.keystore");
    System.setProperty("javax.net.ssl.keyStorePassword", "password");
    System.setProperty("javax.net.ssl.trustStore", "C:/kei/tasks/MIP/Cert/trusteaistore.keystore");
    System.setProperty("javax.net.ssl.trustStorePassword", "password");
    System.setProperty("javax.net.debug", "all");

but I still get the

javax.net.ssl.SSLHandshakeException: java.security.cert.CertificateException: No subject alternative names present

I google and find the follow temporary solution

System.setProperty( "sun.security.ssl.allowUnsafeRenegotiation", "true" );

but even I set allowUnsafeRenegotation to true, I still get the

javax.net.ssl.SSLHandshakeException: java.security.cert.CertificateException: No subject alternative names present

And I try to use SOAPUI 5.1.3, and in preference> ssl, I set the keystore and keystore password (but no place to set truststore), this time I can connect to my target server through https!

so

1) why soapUI 5.1.3 does not need to set truststore (but only keystore), but still can connect to https server?

2) why use system property to point to the same keystore, but I cannot connect to https server using SOAPConnection?

3) why I set allowUnsafeRenegotitation system property to true, but it seems it still check the public cert. of the https server, and return CertificateException?

***************** edit on 15/5/2015

I post the code here

public static void main(String args[]){ 
    System.setProperty("javax.net.ssl.keyStore", "C:/kei/tasks/MIP/Cert/ccc_acp.keystore");
    System.setProperty("javax.net.ssl.keyStorePassword", "password");
    MipCccSoapTest mipCccSoapTest = new MipCccSoapTest();
    mipCccSoapTest.testHttpConnection();        
}

private void testHttpConnection(){
    try{
        doTrustToCertificates();            
         URL url = new URL("https://10.7.3.43:9443/iboss/CustomerCareM1");
         HttpsURLConnection conn = (HttpsURLConnection)url.openConnection(); 
         HttpsURLConnection.getDefaultSSLSocketFactory();
         System.out.println("ResponseCoede ="+conn.getResponseCode());
    }catch(Exception ex){
        ex.printStackTrace();
    }
    System.exit(0);
    //end testing
}

// trusting all certificate 
 public void doTrustToCertificates() throws Exception {
    Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());
    TrustManager[] trustAllCerts = new TrustManager[]{
            new X509TrustManager() {
                public X509Certificate[] getAcceptedIssuers() {
                    return null;
                }

                public void checkServerTrusted(X509Certificate[] certs, String authType) throws CertificateException {
                    return;
                }

                public void checkClientTrusted(X509Certificate[] certs, String authType) throws CertificateException {
                    return;
                }
            }
    };

    SSLContext sc = SSLContext.getInstance("SSL");
    sc.init(null, trustAllCerts, new SecureRandom());
    HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
    HostnameVerifier hv = new HostnameVerifier() {
        public boolean verify(String urlHostName, SSLSession session) {
            if (!urlHostName.equalsIgnoreCase(session.getPeerHost())) {
                System.out.println("Warning: URL host '" + urlHostName + "' is different to SSLSession host '" + session.getPeerHost() + "'.");
            }
            return true;
        }
    };
    HttpsURLConnection.setDefaultHostnameVerifier(hv);
}

and I get the following error

javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure at sun.security.ssl.Alerts.getSSLException(Unknown Source)

but the keystore should be correct as I use the same keystore in SOAPUI 5.1.3 which can successfully call the server.

**************** edit on 18/5/2015 *************

After I comment out the following code

Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());
    TrustManager[] trustAllCerts = new TrustManager[]{
            new X509TrustManager() {
                public X509Certificate[] getAcceptedIssuers() {
                    return null;
                }

                public void checkServerTrusted(X509Certificate[] certs, String authType) throws CertificateException {
                    return;
                }

                public void checkClientTrusted(X509Certificate[] certs, String authType) throws CertificateException {
                    return;
                }
            }
    };

    SSLContext sc = SSLContext.getInstance("SSL");
    sc.init(null, trustAllCerts, new SecureRandom());
    HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());

it can connect to the https server now.

user1169587
  • 1,104
  • 2
  • 17
  • 34

1 Answers1

4

javax.net.ssl.SSLHandshakeException: java.security.cert.CertificateException: No subject alternative names present

This is a problem with the servers certificate. You need to fix it there by adding a subject alternative section with the proper information so that it can be successfully validated. It has nothing to do with the trust chain, so no changes to keyStore or trustStore help. More information might be given if the servers URL or certificate would be known.

System.setProperty( "sun.security.ssl.allowUnsafeRenegotiation", "true" );

This is a TLS protocol level thing and has nothing to do with certificate validation.

In case you cannot fix the servers certificate see SSLHandshakeException: No subject alternative names present for a possible workaround (first hit when googling for this error message!).

Community
  • 1
  • 1
Steffen Ullrich
  • 114,247
  • 10
  • 131
  • 172
  • I can get rid of the "No subject alternative names present" now by calling a doTrustToCertificates() function, but then another error "javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure at sun.security.ssl.Alerts.getSSLException(Unknown Source)" thrown, I post related information in my edited question as quite difficult to post in comment here. – user1169587 May 15 '15 at 10:01
  • @user1169587: unfortunately it looks like you've included any hack you could found on the internet into your code without understanding what it does (disable secure renegotiation, disable trust chain, use custom hostname verification...). Based on this it is not clear what you code is actually doing, which means it is not really possible to help. I recommend you start from scratch and use proper default verification in the client and use a proper certificate at the server (i.e. trusted and matching the hostname) so you don't need any workarounds in the code. – Steffen Ullrich May 15 '15 at 10:37
  • In real case, I will pass a soap message to the HTTPS server and expect to receive a soap message from that server. Attached code is just a trimmed down version in connection part – user1169587 May 15 '15 at 12:10
  • The problem is that your code is full of hacks (workarounds) which might work as intended or not and might cause strange effects when used together. And some of these workarounds disable essential parts of the security TLS should provide. I will not help to make such rotten workarounds reliable, instead the cause of the problem (certificate of the server) should be fixed and the default security settings used. And BTW, if the server certificate is for a hostname you should include the hostname in the URL and not the IP. – Steffen Ullrich May 15 '15 at 12:38
  • can connect now, as I wrongly set the keyManager to null in sc.init(...) before, and I will try to get the correct cert. if allowed to do so, thanks – user1169587 May 17 '15 at 16:31