SSL Error

Proper forum for all questions related to xServer INTERNET = the Azure based cloud solution. This forum deals with the architecture topics such as load balancing, available profiles and standard server settings.
Please be aware that questions about core functionality such as routing, mapping, geocoding in general should be placed in the xServers dedicated forum ;-)
frank.essenberger
Posts: 12
Joined: Mon Feb 29, 2016 2:26 pm

SSL Error

Post by frank.essenberger »

We are currently developing a Cloud Application making use of the xServer Internet Service. We use the Java API to do the service calls. On the local Tomcat development environment everything works fine and the results look good.

However, if we deploy the application to the Cloud System (a SAP HANA Cloud Platform with Tomcat runtime) we get the following exception on calling the PTV service:

sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

So there is a problem with the certificate chain and from the exception it seems like PTV is using the Sun libaries for building the SSL context. For the javax.net.ssl libary there are methods like:

javax.net.ssl.SSLContext.setDefault(myContext); //trust all context
javax.net.ssl.HttpsURLConnection.setDefaultHostnameVerifier(hv);
javax.net.ssl.HttpsURLConnection.setDefaultSSLSocketFactory(myContext.getSocketFactory());


My question is now, how can I add a trustsore/trusmanager to the PTV client using the Java API?

Regards
Frank Essenberger
frank.essenberger
Posts: 12
Joined: Mon Feb 29, 2016 2:26 pm

Re: SSL Error

Post by frank.essenberger »

I just wanted to give a bit more information, why it is working in the local environment and not on real the server. The local tomcat per default is setup to trust all majar CAs. However the actual SAP HCP is much more strict and trusts only the following CAs:
https://help.hana.ondemand.com/help/fra ... d4668.html

However, the certificate used by PTV is not in the list. Although all browser accept the GeoTrust CA. In principle one has to do the steps described as in this post:

https://scn.sap.com/thread/3686449

for the connection Client used by the PTV Java API. Would be great to get support on setting this topic.

Regrads
Frank Essenberger
Attachments
GeoTrust CA of PTV.
GeoTrust CA of PTV.
User avatar
Oliver Heilig
Posts: 154
Joined: Tue May 13, 2014 12:10 pm
Location: Karlsruhe, Germany
Contact:

Re: SSL Error

Post by Oliver Heilig »

Hi Fank,

the additional work to make SAP run with SSL WebServices is a known issue, and there are different methods to solve this. One would be to simply copy the certificate on the TrustManager of the system, like explained here http://rz10.de/2011/02/ssl-webservices-im-sap-nutzen/

As far as I see, the custom Java TrustManager code in the article you mentioned should also work with the Java clients that come with xServer, as the initialization is done on a global object. You are right, having this code inside the client would make the integration more easy. We need to discuss this with the xServer-Team.

I will write back later when I have news.

Regards

Oliver
User avatar
Bernd Welter
Site Admin
Posts: 2564
Joined: Mon Apr 14, 2014 10:28 am
Contact:

Re: SSL Error

Post by Bernd Welter »

And by the way:
there is a dedicated HTTPS chapter available in the online documentation:

http://xserver.ptvgroup.com/fileadmin/f ... _HTTPS.htm

We recommend to use SSL via a PROXY server to get rid of such issues ;-)

Best regards Bernd
User avatar
Oliver Heilig
Posts: 154
Joined: Tue May 13, 2014 12:10 pm
Location: Karlsruhe, Germany
Contact:

Re: SSL Error

Post by Oliver Heilig »

@Bernd: To avoid some misconceptions: xServer internet fully supports SSL and the certificate chain. The problem is the custom SSL-Handling on the SAP side.

Oliver
frank.essenberger
Posts: 12
Joined: Mon Feb 29, 2016 2:26 pm

Re: SSL Error

Post by frank.essenberger »

Hello again,

thank you for the support. However, I am still having the problem getting the connection to work. What does the statement:
"...the custom truststrore should work..., as the initialization is done on a global object"
precisely mean? The PTV java client running on the server, must at some point make the https call to the xServer in the internet. Which truststore is loaded there? Since I set the default SSL socket factory and default Host name verifier without success, it seems to be some other object.
In the meantime I did some further testing,and was able to get the SSL handshake to work. So my trust everything objects are working (I did the test with the appache http client):

Code: Select all

SSLContext myContext = SSLContext.getInstance("SSL");	  
//MyTrustManager trust everything    
myContext.init(null, new TrustManager[] { new MyTrustManager() },  new java.security.SecureRandom());	
//MyHostNameVerifier says true to all hosts
SSLSocketFactory sf = new SSLSocketFactory(myContext, new MyHostNameVerifier());
	    
HttpClient client = new DefaultHttpClient();
Scheme scheme = new Scheme("https",sf,443);
client.getConnectionManager().getSchemeRegistry().register(scheme);
//Connection test		    	    
HttpGet httpGet = new HttpGet("https://xlocate-eu-n-test.cloud.ptvgroup.com/xlocate/ws/XLocate");
//gives status 401, but goes beyond SSL handshake.
HttpResponse response = client.execute(httpGet);
So in principle I have to do the same within the PTV java client in some way - and use of course the ptv certificates instead of the trust all dummies. I had a look at the .jar files and in the third party libaries folder. I did not see the appache http client so perhaps the basic httpConnection from the javax package is used.

Now, I would like to comment on the post from yesterday. I totally agree with Oliver, that the xServer internet fully supports SSL, which is easy to see by just poking the server with any modern browser and investigating the SSL handshake.
However, the current problem is the java client from PTV running on a SAP cloud server. We have to add the certificates to the trust list of this server and make sure that the client uses them.

The link Oliver mentioned is for an onPremise system. We are aiming for the Hana Cloud System. So you find the list of supported CA for this cloud system:
https://help.hana.ondemand.com/help/fra ... d4668.html
and from there the remark, that for different CA cert you have to enable trust by hand:
https://help.hana.ondemand.com/help/fra ... 46045.html
Which is in principle a nice example (very analogous to the one I did), if you have the control over the https call, but what if you use an external client like the PTV one? This is the problem we are facing at the moment.

It would be great, if we could find some solution. I also contacted our mentor of the SAP to see if there is some support, but in general they are rather strict with respect to server settings.

Regards
Frank
frank.essenberger
Posts: 12
Joined: Mon Feb 29, 2016 2:26 pm

Re: SSL Error

Post by frank.essenberger »

Hello together,

I have heard that PTV is currently discussing and working on the problem. Thanks a lot for this support. Since we have quite a tough deadline for the delivery of our product it would be great if we find a quick and easy solution. Here I would like to also post a few ideas.

Variant 1 - Get create and parse method.
Today I used a redirect of the PTV request to a servlet to have a look at the XML data send to the server. I got something like this for the xLocate server:

Code: Select all

<?xml version="1.0"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <soap:Body>
    <ns3:findAddresses xmlns:ns1="http://wrappertypes.service.jabba.ptvag.com" xmlns:ns2="http://common.xserver.ptvag.com" xmlns:ns3="http://types.xlocate.xserver.ptvag.com" xmlns:ns0="http://xlocate.xserver.ptvag.com" xmlns:ns5="http://baseservices.service.jabba.ptvag.com" xmlns:ns4="http://exception.core.jabba.ptvag.com">
      <ns3:ArrayOfAddress_1>
        <ns0:Address street="Weinberg Campus" city="Halle (Saale)" postCode="06120"/>
        <ns0:Address street="Klammstraße 7" city="Garmisch-Partenkirchen" postCode="82467"/>
        <ns0:Address street="Rudower Chausse 9" city="Berlin" postCode="12489"/>
        <ns0:Address street="Sophienstraße 1" city="Berlin" postCode="12203"/>
        <ns0:Address street="Marathonalle" city="Berlin" postCode="14052"/>
        <ns0:Address street="Klammstraße 7" city="Garmisch-Partenkirchen" postCode="82467"/>
        <ns0:Address street="Weinberg Campus" city="Halle (Saale)" postCode="06120"/>
        <ns0:Address street="Marathonalle" city="Berlin" postCode="14052"/>
        <ns0:Address street="Gutleutstraße 13" city="Frankfurt am Main" postCode="60329"/>
        <ns0:Address street="Klammstraße 7" city="Garmisch-Partenkirchen" postCode="82467"/>
        <ns0:Address street="Gutleutstraße 13" city="Frankfurt am Main" postCode="60329"/>
        <ns0:Address street="Sophienstraße 1" city="Berlin" postCode="12203"/>
      </ns3:ArrayOfAddress_1>
      <ns3:ArrayOfSearchOptionBase_2 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>
      <ns3:ArrayOfSortOption_3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>
      <ns3:ArrayOfResultField_4 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>
      <ns3:CallerContext_5 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>
    </ns3:findAddresses>
  </soap:Body>
</soap:Envelope>
In the header was also anauthorization field containing the User:Password pair. (The user was xtok and the password my token. When I tried to do a login with this pair it did not work, but this is not important at the moment :D )
The idea is now, that you provide methods to generate the XML request and to parse the response to the form like AddressResponse[]. So that the steps done by the findAddresses operation are split in two steps:
  • -generate the XML request
    -parse the response data from XML to the object representation
These methods have to be present somewhere in the coding already, they are just not visible. Then one could use whatever client one prefers between the two steps, for actually firing the request to the xServer.

Variant 2 - Pass a HttpClient into the PTV Client
This idea assumes, that you use some interface for the HttpClient in your implementation. You could add an optional parameter to the ClientFactory.createClient() where you pass an argument implementing the HttpClient interface. If this argument is given in the factory, this custom object is used for making the http calls. If not the deafult object is used. The user could then pass a client like this

Code: Select all

	    SSLSocketFactory sf = new SSLSocketFactory(myContext, new MyHostNameVerifier());	    
	    HttpClient client = new DefaultHttpClient();
	    Scheme scheme = new Scheme("https",sf,443);
	    client.getConnectionManager().getSchemeRegistry().register(scheme);
to the factory and include any needed certificates in the myContext. I hope the ideas helped to clearify even more what we have in mind and were a bit helpful. Have a nice weekend and I hope to hear from you in the next week.

Regards
Frank Essenberger
User avatar
Bernd Welter
Site Admin
Posts: 2564
Joined: Mon Apr 14, 2014 10:28 am
Contact:

Re: SSL Error

Post by Bernd Welter »

Hello together,

here is a first approach to the issue...

Set useHttpsURLConnectionDefaultSslSocketFactory=true in CXF Config. This will ensure that custom SSL socket factories will be supported when provided via source.
It is then possible to extend the existing keystore with own certificates or to create a "detour" around the certificate check.
The later approach requires the following steps
  • Spring is required to enable editing of useHttpsURLConnectionDefaultSslSocketFactory via configuration (we used Spring 3.2)
  • The classpath has to contain the CXF configuration cxf.xml with the following content:

    Code: Select all

    <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:http-conf="http://cxf.apache.org/transports/http/configuration" xsi:schemaLocation="http://cxf.apache.org/transports/http/configuration http://cxf.apache.org/schemas/configuration/http-conf.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
       <http-conf:conduit name="*.http-conduit">
          <http-conf:tlsClientParameters useHttpsURLConnectionDefaultSslSocketFactory="true" />
       </http-conf:conduit>
    </beans>
  • Now you can "detour" the certificate check via the following source code:

    Code: Select all

    // Create a trust manager that does not validate certificate chains
    TrustManager[] trustAllCerts = new TrustManager[] {
        new X509TrustManager() {
            public java.security.cert.X509Certificate[] getAcceptedIssuers() { 
                return new java.security.cert.X509Certificate[0];
            } 
            public void checkClientTrusted(java.security.cert.X509Certificate[] certs, String authType) {
            //
            } 
            public void checkServerTrusted(java.security.cert.X509Certificate[] certs, String authType) {
            //
            }
        }                                         
    }; 
    // Install the all-trusting trust manager
    try {
        SSLContext sc = SSLContext.getInstance("SSL"); 
        sc.init(null, trustAllCerts, new java.security.SecureRandom());
        HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
    } 
    catch (GeneralSecurityException e) {
    
    }
Feedback is welcome!

Best regards Bernd
frank.essenberger
Posts: 12
Joined: Mon Feb 29, 2016 2:26 pm

Re: SSL Error

Post by frank.essenberger »

Good morning,

I just tested the proposed way and it worked just fine. Since this forum is also good for other people to look things up remember, that the classpath for the cxf.xml config is the WEB-INF/classes folder if you use a standard web project. I put it initally next to the web.xml just in the WEB-INF, which is not correct.

Now I will replace the trust all manager with a correct truststore containing the PTV certificates, but this should work without any problems. Thanks for adding or pointing out the possibility to enable a custom sslSocketFactory.

Regards
Frank Essenberger
User avatar
Oliver Heilig
Posts: 154
Joined: Tue May 13, 2014 12:10 pm
Location: Karlsruhe, Germany
Contact:

Re: SSL Error

Post by Oliver Heilig »

Hello Frank,

that's good to hear. We now also have a version running where we use a custom keystore and merge it with the default keystore programmatically. So the official SSL certificate trust chain can be used. We're going to document this in the DevGuide.

Oliver
Post Reply