Quantcast



Docs


Blogs


Forums


Samples


Media


Labs


Resources

 




DevCentral > Weblogs > Joe Pruitt - A Software Architect's take on Network Security
 Web Services, SSL, and self-signed server certificates
posted on Friday, March 25, 2005 3:14 PM

This question has come up again recently by a customer and I thought I'd post about it again. The customer downloaded the SDK, compiled the java sample applications, and tried to run them against one of their BIG-IPs. To their surprise the following error was presented: No trusted certificate was found.

Now is when I need to step back a bit and talk about SSL trust. You all have probably seen the warning message that occasionally pops up when browsing to a website encrypted with SSL. This is due to the fact that one of the following conditions in the certificate is not valid:

  1. The certificate is not signed by a trusted certificate authority (CA)
  2. The certificate date is invalid (expired, etc.)
  3. The name embedded in the certificate does not match the hostname in the URL used to access the site

If any of these conditions are met, then the browser will "warn" the user that something may be amiss and that they should proceed with caution. Well, the same security mechanisms are in place in the various networking libraries in the java and .NET runtimes. During the SSL negotiation process, if the server certificate isn't found to pass all the security criteria, then, by default, the connection will not be allowed.

In general, most of our customers don't get their BIG-IP certificates signed by a CA, but rely on the default self-signed certificate created by the system. This is a no-no for policy issue #1 above.

The .NET platform provides a way to override the default certificate policy via the System.Net.ServicePointManager.CertificatePolicy. You can easily whip up your own override and tell the underlying runtime to use your policy instead. Whalah, problem solved. You can check out this article I wrote on the .NET solution: Configuring .NET SSL Security in a Trusted Environment

But for java, it's a bit trickier. I have yet to find a way at runtime to override the policy section of the SSL core routines. Also, Apache WS-SOAP and Apache Axis do things a bit differently under the seams so a common solution for all java platforms seems not possible. If anyone out there knows how to do this, PLEASE let me know. I'll throw some F5 goodies your way if I get something working that I can include in the SDK.

With the java toolkits, you must install take steps on the client side to make security policy #1 true. To do this, you must install the server certificate in the local truststore which basically tells the client runtime that the server is a "trusted" source. How do you do this you ask? Well, there are several ways.

1. The brute force approach.
A while back I wrote a article discribing how to manually install the certificate in your client truststore by security copying (scp) it from the BIG-IP to your client machine, and then using the jdk's keytool command to import it into the truststore. This article can be found here: Configuring SSL Communications with Apache SOAP

2. The "somewhat" automated approach.
I got to thinking that there has to be a programmatic access to the certificate when initiating a SSL connection and I knew there were classes that could be used to access the truststore, so I went to writing a little client side utility to do the grunt work for option 1. I introduced installCert.java into the 4.6.2 version of the iControl SDK. This is now available in the Code Share section on DevCentral, as well as in the 4.6.2 and 9.0 versions of the iControl SDK. Do a Search in the DevCentral forums for installCert and you'll find some topics related to it's usage.

Hopefully this clears things up a bit for everyone. Again, if anyone has a solution to the runtime override of the java security policy with Apache WS-SOAP and Axis, PLEASE let me know. I'm very interested!!!

-Joe

 

[Listening to: Siva - Smashing Pumpkins - Gish (04:20)]

Categories:  


Email This
  del.icio.us
      

Feedback


7/6/2005 1:58 PM
Gravatar Ok, with .NET you can set a property, but with Axis you have the source, so all you need is to patch the org.apache.axis.components.net.JSSEocketFactory axis.jar class like this:

import java.security.cert.*;

import javax.net.ssl.*;

protected void initFactory() throws IOException {
try {
SSLContext sc = null;
// create a trust manager that does not validate certificate chains
TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {
public X509Certificate[] getAcceptedIssuers() {
return null;
}

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
sc = SSLContext.getInstance("SSL");
sc.init(null, trustAllCerts, new java.security.SecureRandom());
sslFactory = (SSLSocketFactory)sc.getSocketFactory();
} catch (Exception e) {
e.printStackTrace();
}
}

and you are done. You can download the patched version from http://www.frank-buss.de/tmp/axis.jar. Should be integrated in Axis as a setting. Then you can use it for example like this:


import javax.xml.rpc.*;

import org.apache.axis.client.Call;
import org.apache.axis.client.Service;
import org.apache.axis.encoding.*;

public class LastTest {
public static void main(String args[]) throws Exception {
String endPoint = "https://somewhere/something/services/SomeWebservice?wsdl";

Service service = new Service();
Call call = (Call) service.createCall();
call.setProperty(javax.xml.rpc.Call.SOAPACTION_USE_PROPERTY, new Boolean(true));
call.setTargetEndpointAddress(new java.net.URL(endPoint));
call.setOperation("echo");

call.addParameter("test", XMLType.XSD_STRING, ParameterMode.IN);
call.setReturnType(XMLType.XSD_STRING);

Object ret = call.invoke(new Object[] { "Hallo" });
System.out.println("result: " + ret);
}
}
Frank Buss

7/6/2005 2:08 PM
Gravatar again me: I was pasting it from my test application, please change the endpoint line in my comment to

String endPoint = "https://somewhere/something/services/SomeWebservice?wsdl"
Frank Buss

7/6/2005 2:27 PM
Gravatar Frank, thanks for the pointer. I haven't posted this solution to my blog (I guess I should). A DevCentral user uploaded a sample class to our CodeShare section that will hook itself into the stack without a rebuild of the 3rd party library (I've tested with axis and WSSOAP). Check out the <b>XTrust JSSE Provider</b> sample over in CodeShare. Your calling application needs only the following line:

XTrustProvider.install();

Pretty slick...

-Joe
Joe Pruitt

7/6/2005 2:46 PM
Gravatar
Joe Pruitt

7/7/2005 1:27 AM
Gravatar Thanks, installing it as a security provider algorithm is better.
Frank Buss

8/29/2005 6:50 AM
Gravatar Hello,

I am using Axis Web Service Server and JBuilder9 as Editor, and tomcat as web server

I developed a Web Service,

also I ctreated a business in IBM site Test

When I send a query by name to find my service I found it but when tried to publish my service (using Web services Explorer)to that location I got the following exception :

failed to authenticate with the operate site IBM site Test : ...SSLHandshakeException: could not find trusted certificate.

knowing that I have already created a trusted self-signed certificate (using keytool) then

exported and imported that certificate as trusted in "C:\JBuilder9\jdk1.4\jre\lib\security"

and I added a path (keystoreFile="c:\jbuilder9\jdk1.4\jre\lib\security\myService.jks") to this

file in server.xml and remove the comment tags around the Connector element.

and retarted tomcat.

please send me a reply to aribi_noureddine@yahoo.fr

Thanks,
ARIBI Noureddine

8/29/2005 10:24 AM
Gravatar I don't have much experience with publishing web services with JBuilder.

I'm not quite sure about the pubish process but it could be that you are trying to publish to the IBM server which is SSL encrypted and you haven't added it's certificate into the trust store on your client.

Check out the XTrustProvider class highlighted in my blog as well as in CodeShare. It allows a hook into the J2SE connection layer to bypass checking of unsigned certificates. Adding this to your application may or may not solve the problem.

-Joe
Joe Pruitt

12/15/2005 10:48 AM
Gravatar Could anybody provide me with patched axis.jar or any other solution to plug my SSLContext or SSLSocketFactory to axis call. I can't set System property of TrustStore because I have other soap requests using different Trust Stores. I need to find a way to set TrustStore dynamically in my code. Any help is greatly appretiated.
Galina Rogoinsky

3/12/2007 1:02 PM
Gravatar - This says "Check out the XTrust JSSE Provider sample over in CodeShare.", yet there is no such sample, even after registering. I realize this is an old topic, but I'm still interested in looking at the indicated code.
- Thanks for your time...
Rags

3/14/2007 10:48 AM
Gravatar The CodeShare link has been fixed in the post and the XTrustProvider.java source file has been added to the CodeShare with the topic: JavaTrustProvider.

Enjoy!
Joe Pruitt
 Leave Feedback
Title  
Name  
Email
Url
Comments   
Please add 4 and 5 and type the answer here: