GetAttribute ("javax.servlet.request.X509Certificate") is not installed (Spring, CXF, Jetty, JAX-RSv1.1)

My client implements two-way SSL as follows:

     private final static String KEYSTORE = "/security/client.jks"
     private final static String KEYSTORE_PASSWORD = "secret";
     private final static String KEYSTORE_TYPE = "JKS";
     private final static String TRUSTSTORE = "/security/certificates.jks"
     private final static String TRUSTSTORE_PASSWORD = "secret";
     private final static String TRUSTSTORE_TYPE = "JKS";
     ...
     KeyStore keystore = KeyStore.getInstance (KEYSTORE_TYPE);
     FileInputStream keystoreInput = new FileInputStream (new File (KEYSTORE));
     keystore.load (keystoreInput, KEYSTORE_PASSWORD.toCharArray ());
     KeyStore truststore = KeyStore.getInstance (TRUSTSTORE_TYPE);
     FileInputStream truststoreIs = new FileInputStream (new File (TRUSTSTORE));
     truststore.load (truststoreIs, TRUSTSTORE_PASSWORD.toCharArray ());
     SSLSocketFactory socketFactory = new SSLSocketFactory (keystore, KEYSTORE_PASSWORD, truststore);
     Scheme scheme = new Scheme ("https", 8543, socketFactory);
     SchemeRegistry registry = new SchemeRegistry ();
     registry.register (scheme);
     ClientConnectionManager ccm = new PoolingClientConnectionManager (registry);
     httpclient = new DefaultHttpClient (ccm);
     HttpResponse response = null;
     HttpGet httpget = new HttpGet ("https://mylocalhost.com:8543/test");
     response = httpclient.execute (httpget);
     ...

And I'm trying to get the X.509 certificate on the server side from the client through javax.servlet.http.HttpServletRequest.getAttribute ("javax.servlet.request.X509Certificate"), as described here: http://tomcat.apache.org/tomcat -5.5-doc / servletapi / javax / servlet / ServletRequest.html # getAttribute% 28java.lang.String% 29 .

I get HttpServletRequest on the server side through:
HttpServletRequest servletRequest = (HttpServletRequest) msg.get ("HTTP.REQUEST"); via the handleMessage (Message msg) method of my interceptor class, which extends AbstractPhaseInterceptor <Message>. I have to use JAX-RS 1.1.1 on the server side due to some Maven dependencies that I am not allowed to change, and therefore I can not use ContainerRequestFilter (supported by JAX-RS 2.0).

My problem is that getAttribute ("javax.servlet.request.X509Certificate") on the server side always returns null. If I check the traffic between the server and the client, I see that the certificate from the server is sent to the client, and this handshake works. But I don’t see that the client certificate is being sent to the server, and I think this is the reason why getAttribute("javax.servlet.request.X509Certificate") returns null . Does anyone know how I can solve this problem? I have already tried some other client-side implementations, but no change.

What am I doing wrong? Thank you very much in advance!

Additional Information: I saw on the server side that javax.servlet.request.ssl_session_id, javax.servlet.request.key_size and javax.servlet.request.cipher_suite are installed, but the javax.servlet.request.X509Certificate key is not set. I am using Jetty Server 8.1.15, Apache CXF 2.7.x and JAX-RS 1.1.1. I tried to configure Jetty through http://cxf.apache.org/docs/jetty-configuration.html and http://cxf.apache.org/docs/secure-jax-rs-services.html#SecureJAX-RSServices-Configuringendpoints , the attribute is still not set.

+6
source share
1 answer

The problem is resolved. It was not a problem in the code, it was a problem with the certificate. My problem was that I was new to X509 certificates, it was a handshake problem between server and client. In this case, only SSL / Handshake debugging helped me. The debug log said that the server only accepted client certificates from a specific CA, the server informed the client the required CA in the certificate request during the ServerHello message. Since the Client did not have a certificate from this CA, it did not send anything, and the connection between the client and the server was closed then, as a result of which javax.servlet.request.X509Certificate was not established.

For everyone else who might someday join in with the same issue (which seems to be a common SSL configuration issue for IBM, which is mentioned in the first link below), the following sources helped me a lot:
- http://www-01.ibm.com/support/docview.wss?uid=swg27038122&aid=1 (pages 16 and 17)
- http://java.dzone.com/articles/how-analyze-java-ssl-errors (shows what a handshake should look like)
- need help Debugging SSL handshake in tomcat (shows how to debug ssl errors in Java)
- https://thomas-leister.de/internet/eigene-openssl-certificate-authority-ca-erstellen-und-zertifikate-signieren/ (in German, but maybe you can find the English equivalent)
- https://access.redhat.com/site/documentation/en-US/Red_Hat_JBoss_Fuse/6.0/html/Web_Services_Security_Guide/files/i382674.html (continuation of the German article)
- http://www.webfarmr.eu/2010/04/import-pkcs12-private-keys-into-jks-keystores-using-java-keytool/ (how to create a keystore and trust store)

After creating your own CA, server and client certificate, and after creating the keystore and trust store for both attributes, now was installed:
- Here15_1: javax.servlet.request.X509Certificate
- Here16_2: class [Ljava.security.cert.X509Certificate;
- Here16_3: [Ljava.security.cert.X509Certificate; @ 43b8f002
Server code can now also retrieve client certificate information.

+13
source

Source: https://habr.com/ru/post/971173/


All Articles