Authentication with HTTPS and client certificates

Authentication with HTTPS and client certificates

In the IVOA security standards, requests to RESTful service can be authenticated by HTTPS with client certificates. This is the less-common form of HTTPS authentication in which the client is authenticated to the service. The authentication is performed by the web-server; for Java web-services this is typically Apache Tomcat.

The IVOA use of HTTPS matches the IETF standards except for two points:

  1. the client need not authenticate the server;
  2. the server must accept proxy certificates according to RFC 3820.

These extra requirements mean that HTTPS code in the JDK, and in web servers is insufficient for the IVOA standard. The security facade provides classes to fix this.

For the client

The details in HTTPS in the client are handled by the JDK class java.net.HttpsURLConnection, which can be obtained from a java.net.URL for an HTTPS URL.

import java.net.URL;
import java.net.HttpsURLConnection;
URL u = new URL("https://some.where/some/thing");
HttpsURLConnection c = (HttpsURLConnection) u.openConnection();
      

The connection can now be set up to suit the IVOA standard using a SecurityGuard.

import org.astrogrid.security.SecurityGuard;
SecurityGuard sg = new SecurityGuard();
sg.signOn(...);
sg.configureHttps(c);
      

The signOn() call obtains the certificates and key needed to authenticate the connection. See the guide to signing on to the IVO for details.

The configureHttps() call does two things sets the HttpsURLConnection to trust all identity certificates sent to the client by the service. This effectively disables authentication of the service by the client. By doing so, it allows the client to work with self-signed server-certficates which would normally be rejected by the HttpsURLConnection.

The configureHttps() call also associates with the connection the certificate chain and key obtained by the SecurityGuard when the user signed on to the IVO. I.e., it authenticates the connection in the user's name, not with some arbitrary identity chosen by the JDK.

The configureHttps() call needs an HttpsURLConnection to set up the authentication. If it gets instead an HttpURLConnection (the superclass of HttpsURLConnection), then it does nothing and returns sliently. This is by design: it allows you to call configureHttps() on all HTTP connections without distinguishing the HTTPS ones in the application code.

For the service

The authentication is done by the web server before the web service is informed of the request. The service can receive the results of authentication in a specialized sub-class of SecurityGuard.

import org.astrogrid.security.HttpsServiceSecurityGuard;
HttpsServiceSecurityGuard sg = new HttpsServiceSecurityGuard();
// request is the HttpServletReqiest passed by the servlet container
sg.loadHttpsAuthentication(request);
     

If authentication was successful, the loadHttpAuthentication() call will load into the security guard

  • an X500Principal stating the user's identity;
  • the certificate chain used in the authentication;
  • an identity certificate (i.e. the "end-entity" certificate in the chain from which the user's X500Principal was read.

If the authentication was unsuccessful, then the guard will not contain the identity certificate and X500Principal. The certficate chain may or may not be present, depending on how the servlet container is configured. Note that failed authentication may cause the HTTPS request to be rejected without the web service being called at all. The web.xml configuration of the web application determines this.

For Tomcat

The security-facade packages org.astrogrid.security.rfc3820.tomcat5 and org.astrogrid.security.rfc3820.tomcat6 contain an implementation of SSL that supports RFC3820 (proxy certificates). This can be added to a Tomcat installation to bring that installation up to IVOA standards. The former package works with Tomcat 5.5 and the latter with Tomcat 6.0.

The SSL code is an intimate part of the Tomcat server and the jars must be added to the Tomcat installation itself. For Tomcat 5.5, put the jars in Tomcat's server/lib directory. For Tomcat 6.0, put them in Tomcat's lib directory. Simply including the jars within a web-application doesn't work.

The following jars must be added.

  • astrogrid-security
  • Bouncy Castle JCE "provider"

Previous versions of the security library needed Globus and Crytix jars. Starting with v2010.1, these are no longer needed for the SSL implementation and should be removed from Tomcat. (Classes in those jars are still needed by some other parts of the security libary and the jars should not be removed from web applications.)

Operation of HTTPS with client authentication requires two sets of cryptographic credentials: a private key and identity-certficate for the host; and a set of trust anchors against which to check the client credentials. There are many ways to encode these, but Tomcat only supports a few options. The SSL implementation in the security facade supports the same encodings as standard Tomcat.

All the installed credentials must be in key-store files of JKS format (binary ".jks" files). PKCS#12 format (binary ".p12" files) is not supported, nor is the PEM format (the one with listable, base-64 encoded credentials, as used by OpenSSL). The host credentials may be in the same key-store as the trust anchors, or the trust anchors may be in one key-store and the host credentials in another. The credentials may not spread across more than two key-stores, and the host's private key and certificate must be in the same keystore.

In a JKS store, each credential entry has an "alias" which must be known to retrieve the credentials. An entry under one alias may be the private key and certificate for a party - the host, in this case - or the trust anchor for one certificate authority.

Tomcat needs to be able to pick out the entry for the host credentials. The default alias for these is "tomcat". If they are stored under a different alias then that alias must be declared when configuring Tomcat. Tomcat does not care what aliases are set for the trust-anchor entries.

JKS stores have passwords to protect the credentials. Tomcat expects to unlock the store or stores with a password. The default password is "changeit". If a different password is set, then it must be declared in the Tomcat configuration. If two key-stores are used the password should be the same for both.

Private keys within JKS stores may encrypted and the encryption unlocked by a own password. Tomcat expects either that the host's private key does not have a password or that the key-encryption password is the same as the password for the store.

Tomcat must be configured to use the AstroGrid implementation. Simply adding the extra jars to Tomcat does not activate the extra code.

In Tomcat's server.xml file, there are Connector elements. Typically, there will be one HTTP connector bound to port 8080. For HTTPS, there must be another connector bound to another port, 8443 by default. For an HTTPS connection with the RC3820 support, the configuration follows this pattern.

     <Connector port="8443"
     acceptCount="100" connectionTimeout="20000" disableUploadTimeout="true"
     maxSpareThreads="75" maxThreads="150" minSpareThreads="25"
     scheme="https" secure="true" clientAuth="true" sslProtocol="TLS"
     SSLEnabled="true"
     keystoreFile="/home/agrid/ag01.jks"
     truststoreFile="/home/agrid/ag01.jks"
     SSLImplementation="org.astrogrid.security.rfc3820.tomcat5.JSSEImplementation"/>
                

for Tomcat 5.5, or

     <Connector port="8443"
     acceptCount="100" connectionTimeout="20000" disableUploadTimeout="true"
     maxSpareThreads="75" maxThreads="150" minSpareThreads="25"
     scheme="https" secure="true" clientAuth="true" sslProtocol="TLS"
     SSLEnabled="true"
     keystoreFile="/home/agrid/ag01.jks"
     truststoreFile="/home/agrid/ag01.jks"
     SSLImplementation="org.astrogrid.security.rfc3820.tomcat6.JSSEImplementation"/>
                

for Tomcat 6.0.

The SSLImplementation attribute names the class that introduces the SSL implementation. If this attribute is ommited (or misspelt!) then Tomcat defaults silently to its native implementation.

The other important attributes work as follows.

secure="true"
This turns on SSL.
sslProtocol="TLS"
This selects the version of the SSL protocol. TLS (v1.0 implied) is the preferred value for all Tomcats.
clientAuth="true"
This forces Tomcat to authenticate all requests on this port. If this is set to false (Tomcat's default), then no requests are authenticated.
keystoreFile
This names the JKS store in which the host credentials are kept.
truststoreFile
This names the JKS store in which the trust anchors are kept.
keystorePass
This is the password for the JKS store holding the host credentials. If the password is set to the default value ("changeit"), then this attribute may be left out.
truststorePass
This is the password for the JKS store holding the trust anchors. If the password is set to the default value ("changeit"), then this attribute may be left out.
keyAlias
This is the alias under which the host credentials are stored in the JKS store. If the default alias ("tomcat") is used, or if the host credentials are the only entry in the store (i.e. the trust anchors are in a separate store) then this attribute may be left out.

The documentation for the Tomcat SSL implementation offers attributes to configure the type of store, implying that PKCS#12 stores can be used. This doesn't work (as of Tomcat 5.5.20) in either Tomcat's implementation or the AstroGrid extension.