Dear Madame or Sir
I have a java callout reading the client certificate chain out of an HTTP header:
messageContext.getRequestMessage().getHeadersAsObject("javax.servlet.request.X509Certificate");
The trace shows that the returned value is of type Object[] and that the first element of this Array is of type java.security.cert.X509Certificate []
CDR.JWSTCredentialMapper.getUser.objCerts[] | [Ljava.lang.Object;@47b95597 |
---|---|
CDR.JWSTCredentialMapper.getUser.objCerts[0] | [Ljava.security.cert.X509Certificate;@1f774476 |
Unfortunately when I try to cast the first element of the array to java.security.cert.X509Certificate [] I get
Exception: java.lang.ClassCastException: java.lang.String cannot be cast to [Ljava.security.cert.X509Certificate;
How can I extract the X509Certificate object?
Gladly awaiting your answer
Kind Regards
Carlo De Rossi
Hi Carlo
What is "CDR.JWSTCredentialMapper.getUser.objCerts[]" ?
is that a context variable name?
I think you are getting a ClassCastException.
It would be good to see the Java code that triggers this exception, along with the exact exception message with the line number included, correlated to where in your source code that line number is.
Can you provide that?
Also, you are using "messageContext.getRequestMessage().getHeadersAsObject("javax.servlet.request.X509Certificate");"
I'm not sure that method will do for you, what you want.
I think Maybe your cert, passed in the header, looks like...a very long base64 encoded (PEM-encoded) string. Simply casting that to an X509Certificate is not going to work. (Even though there is a method named getHeadersAsObject() which seems to say "I can do this for you", it's not possible to arbitrarily convert between string forms and objects in Java.)
There are libraries that can de-serialize from certs in PEM-encoded form into actual cert objects. Or, you can "do it yourself" by base64-decoding the string, then converting that byte array into a ByteArrayInputStream and reading the Cert that way.
private static X509Certificate certStringToCert(String s) throws InvalidKeySpecException, CertificateException, UnsupportedEncodingException { if (s==null) return null; s = s.trim(); if (s.startsWith("-----BEGIN CERTIFICATE-----") && s.endsWith("-----END CERTIFICATE-----")) { // This is an X509 cert; // Strip the prefix and suffix. s = s.substring(27, s.length() - 25); } // else, assume it is a bare base-64 encoded string s = s.replaceAll("\\\\n",""); s = s.replaceAll("[\\r|\\n| ]",""); // base64-decode it, and produce a public key from the result byte[] certBytes = Base64.decodeBase64(s); ByteArrayInputStream is = new ByteArrayInputStream(certBytes); CertificateFactory fact = CertificateFactory.getInstance("X.509"); X509Certificate cer = (X509Certificate) fact.generateCertificate(is); return cer; }
Ciao Dino
thanks for your answer.
The problem is that a Java Callout has no access to the client certificate (public key, two way TSL), a callout can only access the client certificate's Common Name (CN) via property: hence I modified my TomCAT client to send the Public Keys certificate chain (Client certificate and CAs) as a standard Java header. Unfortunately the JAX-RS library I was using had a bug and did not serialized properly the objects: I am using the Jersey (JAX-RS RI) library now and it works fine.
It would be good if it would be possible to access the client's certificate chain as object (javax.servlet.request.X509Certificate[]).
Problem solved by now 🙂
Thanks for your help!
ciao
carlo
User | Count |
---|---|
7 | |
2 | |
2 | |
2 | |
1 |