Covering J2EE Security and WebLogic Topics

Reversed DN in WebLogic 8.1.4

If you do mutual authentication via two-way SSL, you sometimes need to pull the certificate from the request. For web applications, it’s a simple matter of grabbing the "javax.servlet.request.X509Certificate" attribute. Here’s an extract from the sample SnoopServlet.jsp that comes with WebLogic:

  try {
    // request is HttpServletRequest
    java.security.cert.X509Certificate certs [] = 
       (java.security.cert.X509Certificate [])
	request.getAttribute(
           "javax.servlet.request.X509Certificate");

    if ((certs != null) && (certs.length > 0)) {
      out.println("DN: "+
        certs[0].getSubjectDN().getName()+"<br/>");
    }
    else // certs==null
    {
      out.println("Not using SSL or client "+
        "certificate not required.");
    }
  } catch (ClassCastException cce) {
    cce.printStackTrace();
  }

The full JSP can be found at <WL_HOME>\samples\server\examples\src\examples\jsp. I cleaned it up a bit for simpler presentation here.

Notice that the code pulls the certificate and then prints the Distinguished Name (DN) from the certificate. The DN might look like "cn=Mike Fleming, ou=Engineering,o=XYZ Corp.,c=US" and it identifies the user associated with the certificate. The user certificate is always the first (i.e., zero) element in the certificates array while the issuer certificates in the certificate chain occupy subsequent slot(s). The issuers, by the way, are the Certificate Authorities that signed the certificates in the chain.

Everything I’ve said thus far is the set up for the big punchline: The order in which the DN is presented is flipped in WebLogic 8.1.4+.

As a result, running SnoopServlet in 8.1.4 would print "c=US,o=XYZ Corp.,ou=Engineering,cn=Mike Fleming" using my example above.

Now, this order reversal is not "wrong" since either order is perfectly valid. What’s upsetting is that the first example is what WebLogic has been returning since at least 7.x and now it’s suddenly a different representation.

This situation might not be a big deal depending upon what you are doing with the DN. However, if you are parsing it or passing it along for further processing, you’ll likely have to take action.

If you control the source code, the fix is easy. Instead of using

certs[0].getSubjectDN().getName()

as SnoopServlet does, use

certs[0].getSubjectX500Principal().getName()

instead. In fact, the second approach is now the preferred way of retrieving the DN as I’ll discuss momentarily.

I’ve presented the problem and provided a solution. But what bugs me is why did it change? Information on this is very hard to come by. Here’s what I uncovered along with some speculation:

Obviously, the change occurred in WebLogic 8.1.4. Versions prior to that presented the DN in the "normal" order. What happened in 8.1.4 is that the Certicom classes changed.

Certicom is the provider of much of the crypto functionality in WebLogic. In this case, the class in question is com.certicom.security.cert.internal.X509.X509V3CertImpl. This class implements the java.security.cert.X509Certificate interface and is the object you actually deal with in the example code above.

Interestingly, JDK 1.5.0 deprecates the getSubjectDN() method but WebLogic 8.1.4 uses JDK 1.4.2_05. My guess is that Certicom knew about the impending deprecation and decided to flip the order just to tick me off. 😉 Deprecation is one thing but why would they totally change the output like they did?

If you have any information on this, please leave a comment. It’s not a burning issue, of course, but I’m quite curious…