Jython Journeys

Notes about my work with jython and python

Installing an all-trusting security provider on java and jython.

with one comment

Back in 2007, I updated the jython socket module to support client-side ssl sockets. This post will describe how to configure jython so that it behaves like cpython, in relation to acceptance of SSL certificates.

The support was very basic, because it is an implementation of the existing core cpython ssl socket support, which is really basic, merely allowing a client to make an SSL connection to a server. Cpython has no server-side SSL support in the standard library (although multiple 3rd party modules do support it), and it has no support for certificate management or verification. So basically the cpython ssl support is really only useful for testing; without certificate verification, it’s not really usable in scenarios where authentication actually matters, e.g. E-commerce.

Because the jython socket module is layered on top of java socket libraries, it automatically inherits java behaviour in relation to certificate validation; java by default always validates certificates.

Which is great, if you want certificate validation; it means that you can use the jython ssl support when counterparty authentication actually matters, because it will always verify that the server certificate is valid, and will refuse to form a connection if the certificate is not valid.

However, this is problematic for jython users who want to use the jython ssl support like they would use the cpython ssl support: for testing. In testing phases, it’s very common for users to create and test with their own self-signed certificates; installing real production certificates may be difficult for a number of operational reasons.

As described above, this is not a problem for cpython users. But jython users have to go an extra step in order to be able to use self-signed certificates. There are two choices

  1. Add the self signed certificate to the JVM configuration. To do that, read this Sun article on Installing and Configuring SSL Support.
  2. Install a custom java Security Provider which simply trusts all certificates. WARNING: Installing a security provider that accepts all certificates leaves you open to all forms of impersonation and other identity-verification failures; only use it for testing purposes! To install a custom security provider requires writing some java. I’ll explain it below.

In order to change the Java trust decision process, you have to create an X509TrustManager. Java TrustManagers are based on an exception model; the trust manager is called to determine if a given client, server or issuer is trusted. If not, the TrustManager should raise a CertificateException. Which means that if a TrustManager wishes to trust everyone, it simply should not raise exceptions when a trust request is made.

But you can’t just create and install a TrustManager; TrustManagers are created by a TrustManagerFactory, so you have to create and install one of those. And in order to do that, you have to create and install a java.security.Provider. Sounds complex?

Well, thankfully it’s not that complex, as you can see in the code sample from this article on the ZXTC KnowledgeHub: Using the Control API with Java. I have reproduced that code here.

 
// Example java.security.Provider implementation
// that trusts ALL SSL certificates
// Regardless of whether they are valid or not
 
// Store this code in a file called MyProvider.java
 
import java.security.Security;
import java.security.KeyStore;
import java.security.Provider;
import java.security.cert.X509Certificate;
import javax.net.ssl.ManagerFactoryParameters;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactorySpi;
import javax.net.ssl.X509TrustManager;
 
public class MyProvider extends Provider
{
  public MyProvider()
  {
    super("MyProvider", 1.0, "Trust certificates");
    put("TrustManagerFactory.TrustAllCertificates", MyTrustManagerFactory.class.getName());
  }
 
  protected static class MyTrustManagerFactory extends TrustManagerFactorySpi
  {
    public MyTrustManagerFactory()
      {}
    protected void engineInit( KeyStore keystore )
      {}
    protected void engineInit(ManagerFactoryParameters mgrparams )
      {}
    protected TrustManager[] engineGetTrustManagers()
    {
      return new TrustManager[] {new MyX509TrustManager()};
    }
  }
 
  protected static class MyX509TrustManager implements X509TrustManager
  {
    public void checkClientTrusted(X509Certificate[] chain, String authType)
      {}
    public void checkServerTrusted(X509Certificate[] chain, String authType)
      {}
    public X509Certificate[] getAcceptedIssuers()
      { return null; }
  }
 
}

This class should be stored in a file called MyProvider.java, and compiled with javac to generate a MyProvider.class file, which you should place in the classpath.

Once that’s complete, execute the following piece of jython

java.security.Security.addProvider(MyProvider())
java.security.Security.setProperty("ssl.TrustManagerFactory.algorithm", "TrustAllCertificates");

And your code should now start accepting all SSL certificates, regardless of whether they are valid or not.

This issue came up on jython-users, where a jython user was wondering why, after he had installed his own TrustManagerFactory, he could access an HTTPS url on a server with an invalid certificate, without problems, when using java.net.URL.

But when he tried to use jython’s urllib2, it failed with a java.security.cert.CertPathValidatorException. The reason for that is that the jython urllib2 module does not use java.net.URL; it uses the jython socket module directly. So over-riding the default TrustManagerFactory for the javax.net.ssl.HttpsURLConnection class has no effect on anything but instances of the HttpsURLConnection class. Which happens to be the class that java.net.URL uses to make HTTPS connections.

Read the jython-users post HTTPS and invalid certs for more details.

Lastly, this information is reproduced on the Jython Socket Module Wiki page, which I try to keep up-to-date as much as possible.

Written by alan.kennedy

August 29th, 2008 at 4:38 pm

Posted in jython

Tagged with ,