CXF SSL Spring configuration - Empty client certificate chain - java

I am trying to build a SSL secured Web Service client using CXF Spring configuration and I wonder how is it possible to tell to CXF to use this client certificate in my keystore.
This should exists because if my keystore holds plenty of certificate how does CXF is supposed to do to find the good one?
Here is my configuration:
<http-conf:conduit name="{urn:ihe:iti:xds-b:2007}DocumentRepositoryPortType.http-conduit">
<http-conf:client AutoRedirect="true" Connection="Keep-Alive"/>
<http-conf:tlsClientParameters secureSocketProtocol="SSL">
<sec:keyManagers keyPassword="storepass">
<sec:keyStore type="JKS" password="storepass" file="src/main/resources/keystore.jks" />
</sec:keyManagers>
<sec:trustManagers>
<sec:keyStore type="JKS" password="storepass" file="src/main/resources/truststore.jks" />
</sec:trustManagers>
<sec:cipherSuitesFilter>
<sec:include>.*_EXPORT_.*</sec:include>
<sec:include>.*_EXPORT1024_.*</sec:include>
<sec:include>.*_WITH_DES_.*</sec:include>
<sec:include>.*_WITH_NULL_.*</sec:include>
<sec:exclude>.*_DH_anon_.*</sec:exclude>
</sec:cipherSuitesFilter>
</http-conf:tlsClientParameters>
</http-conf:conduit>
In the
<sec:keyManagers keyPassword="
<sec:keyStore type="JKS" password="storepass" file="src/main/resources/keystore.jks" />
</sec:keyManagers>
section, is there a way to write something like
alias="mycertificate"
?
I searched on several Web sites but no result for the moment.
Actually my problem is that when my CXF client communicates with a SSL secured server there is a Certificate Request coming from the server in order to identify myself with a certificate. The server tells me which are the cert authorities it is waiting for, in my keystore I do have a certificate which has been certified by one of these authorities but there is no certificate transmission from my client...
Here is how it looks in the SSL logs:
CertificateRequest:
*** CertificateRequest
Cert Types: RSA, DSS,
Cert Authorities:
<CN=****, DC=****, DC=****>
Others authorities...
Empty client certificate chain:
*** Certificate chain
***
Do you guys have any idea?
Thanks in advance!

It's likely the "name" attribute on the http-conduit is wrong. It should be the Endpoint name (from within the Service element), not the PortType name.
However, I would recommend using a URL for the name.
<http-conf:conduit name="http://localhost:8080/.*" .....>
...
</http-conf>
Note the wildcard (.*) at the end to match all URL's.

Related

How to use SSL Certificate with ActiveMQ without self signed certificate

The ActiveMQ SSL documentation states:
ActiveMQ includes key and trust stores that reference a dummy self signed cert
As per configuring SSL on ActiveMQ it is mentioned to provide the file url of broker keystore file.
<bean id="SecureConnector" class="org.eclipse.jetty.server.ssl.SslSelectChannelConnector">
<property name="port" value="8162" />
<property name="keystore" value="file:${activemq.conf}/broker.ks" />
<property name="password" value="password" />
</bean>
I have purchased an SSL certificate. How can i use that with ActiveMQ? The files I have are a .cer file and a .key file.
Should I first convert the .cer files to .jks file format and then configure it in ActiveMQ Jetty?
Is that how it is supposed to be done? Maybe I am missing something completely due to lack of knowledge in this area.
I cannot use the method explained by ActiveMQ because it requires both client and broker handshake and in this case the client is the 3rd party app and we have no control there.
The certificate definitely must be in JKS format as that is the format which Java uses (and ActiveMQ is written in Java). Once the certificate is converted just reference it in the ActiveMQ configuration as described in the documentation. It should be really straight-forward.
If your certificate is signed by a trusted authority then the client will trust it implicitly and won't need to import it into a truststore of some kind. Using a truststore is necessary for "self-signed" certificates (which are used in the ActiveMQ documentation) since they are not signed by a trusted authority.

Weblogic/Java not sending Client Certificate in Mutual SSL Integration with IIS

I'm having trouble understanding why Weblogic/Java are not sending the Client certificate requested by the server(IIS server) during SSL Handshake via the CertificateRequest message.
I have already checked and tried all the other questions/answer in SO such as :
Java not providing client certificate for mutual SSL?
and similar.
I have created a custom keystore called Identity.jks with only one Certificate entry and I've follwed the WL guides (and everything else I could find on the Internet) to do the right settings.
Here are the debug logs for the SSL handshake:
*** CertificateRequest
Cert Types: RSA, DSS, ECDSA
Supported Signature Algorithms: SHA512withRSA, SHA512withECDSA, SHA256withRSA, SHA384withRSA, SHA1withRSA, SHA256withECDSA, SHA384withECDSA, SHA1withECDSA, SHA1withDSA
Cert Authorities:
<Empty>
*** ServerHelloDone
Warning: no suitable certificate found - continuing without client authentication
*** Certificate chain
<Empty>
As you can see the server sends a CertificateRequest message but for some reasons the Cert Authorities is Empty. The client (Weblogic) in this case doesn't send the certificate. As you can see there is a warning message by the developers saying:
no suitable certificate found - continuing without client authentication
When I use SoapUI instead of Weblogic to communicate with the server the handshake succeeds. SoapUI sends the certificate contained in the Identity.jks keystore.
Can it be that SoapUI is less restrictive and sends the only certificate present in the keystore anyway while Weblogic is expecting from the server to find something in the Cert Authorities:
<Empty> ?
Since I've setup weblogic to use only that key with that alias I expect it to send it...
Anyone knows what are the criteria that Weblogic uses to find a matching client certificate?
Is my interpretation of the logs correct?
Any idea/help is welcome.
I've had a similar problem with a Java HTTP client. Depending on your IIS version the server may or may not be sending the certificate list back. Newer version don't.
Ensure that you have the full certificate chain and your client certificate in the keystore.
Since there seems to be an interest, I'm answering my own question on how we fixed it.
When writing Java clients to communicate with other servers via Two-Way SSL we need to make sure that the SSL Context used to initiate the communication has been set with the Custom Identity Keystore and the Custom Trust keystore.
One convenient way to do this is to pass the Identity and Trust keystores as JVM options when a JVM process starts (on start of WebLogic or other web app server). JVM arguments can be passed in the server startup script (if present) or as command line argument.
The following is an example:
-Djavax.net.ssl.keyStore=D:\Path-to\identity.jks -Djavax.net.ssl.keyStoreType=JKS -Djavax.net.ssl.keyStorePassword=MyReallyComplexPassword -Djavax.net.ssl.trustStore=D:\Path-to\trust_keystore.jks -Djavax.net.ssl.trustStoreType=JKS -Djavax.net.ssl.trustStorePassword=MyTrustStorePassword
Where the value of javax.net.ssl.keyStore is what we called the Custom Identity Keystore and the value of javax.net.ssl.trustStore is what we called the Custom Trust Keystore.
Note: Another way to accomplish the same thing would be to load-and-set the Identity & Trust keystores directly in the client's code itself, before firing the request to the server. There are multiple examples on-line that explain how to do this.
Important: When writing a client that should communicate via Two-Way SSL make sure to never blindly trust all certificates. Many client libraries give you a boolean option TrustAllCerts that can be useful during development however if you leave it in production Two-Way SSL will NOT work. This is because by telling the SSL context to trust any certificate, the Server Certificate Exchange Key is not checked (since you trust it anyway) and thus the CertificateRequest from the server is ignored. The client will continue without sending its client certificates but, because the server expects the client to send one, the handshake process will end in failure.

Wcf with client certificate authentication doesn't work with soapui

I've a wcf service with basicHttpBinding, message security mode and certificate client credential type. I can consume this service via wcf client, but this service has to be used also in another system with a java client. I'm testing with soapui, but I obtain empty response or a security message error. I've tried variuos soapui configuration to load client certificate, but none of these worked. I exposed the service via http (non https) and this is the server wcf configuration:
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="basicEndPoint" closeTimeout="00:01:00" openTimeout="00:01:00"
receiveTimeout="00:10:00" sendTimeout="00:01:00" allowCookies="false"
bypassProxyOnLocal="false" maxBufferSize="2147483647" maxBufferPoolSize="2147483647"
maxReceivedMessageSize="2147483647" messageEncoding="Text" textEncoding="utf-8"
transferMode="Buffered" useDefaultWebProxy="true">
<readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647"
maxArrayLength="2147483647" maxBytesPerRead="2147483647"
maxNameTableCharCount="2147483647"/>
<security mode="Message">
<message clientCredentialType="Certificate" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<behaviors>
<endpointBehaviors>
<behavior name="customBehavior">
<clientCredentials>
<clientCertificate findValue="ClientSide" x509FindType="FindBySubjectName" storeLocation="LocalMachine" storeName="My"/>
<serviceCertificate>
<defaultCertificate findValue="ServerSide" x509FindType="FindBySubjectName" storeLocation="LocalMachine" storeName="My"/>
<authentication certificateValidationMode="PeerOrChainTrust"/>
</serviceCertificate>
</clientCredentials>
</behavior>
</endpointBehaviors>
</behaviors>
<client>
<endpoint address="http://localhost:8080/WebServices/ExternalServices.svc"
behaviorConfiguration="customBehavior" binding="basicHttpBinding"
bindingConfiguration="basicEndPoint" contract="ServiceReference1.IExternalServices"
name="BasicHttpBinding_IExternalServices" >
<identity>
<certificateReference findValue="ServerSide" storeName="My" storeLocation="LocalMachine" x509FindType="FindBySubjectName" />
<dns value="ServerSide"/>
</identity>
</endpoint>
<endpoint address="mex"
binding="mexHttpBinding"
contract="IMetadataExchange"/>
</client>
</system.serviceModel>
What's wrong in this settings?
Thanks in advance
I'm not an WCF expert (even not a user :P) but based on configuration:
<endpointBehaviors>
<behavior name="customBehavior">
<clientCredentials>
<clientCertificate findValue="ClientSide" x509FindType="FindBySubjectName" storeLocation="LocalMachine" storeName="My"/>
<serviceCertificate>
<defaultCertificate findValue="ServerSide" x509FindType="FindBySubjectName" storeLocation="LocalMachine" storeName="My"/>
<authentication certificateValidationMode="PeerOrChainTrust"/>
</serviceCertificate>
</clientCredentials>
</behavior>
</endpointBehaviors>
Seems that in order to hit your server endpoint you must present certificate client credentials.
So to invoke your service from SOAPUI you could do two things, first expose your service using https in order to be available for a client to present the certificate credentials. And second configure SOAPUI as follow to send the client certificate to the endpoint:
From the menu select File > Preferences, and then the SSL settings. In this panel select a keystore which contains the client key and certificate valid for the service and put the keystore password, optionally mark the required client authentication:
NOTE: Based on your configuration:
<clientCertificate findValue="ClientSide"
x509FindType="FindBySubjectName" storeLocation="LocalMachine" storeName="My"/>
A valid client certificate must be an end entity certificate issued by on the certificate authorities located in the Windows local keystore of your server.
I had hard time setting up SOAPUI for WCF testing with Client Certificate Authentication. Finally I got it work.
Faced different issues like: SNI support issues, unsigned 'To' Header Getting WCF to accept unsigned 'To' Header and other.
I would recommend to switch on WCF tracing and you can get detailed error information on the server: https://msdn.microsoft.com/en-us/library/ms732023(v=vs.110).aspx so it can be easily troubleshooted.

client/certificate authentication by server in tomcat

Can anyone tell me what is client/certificate authentication by server in tomcat, in our application we are getting certificate as part of request parameter and doing validation of certificate, does that mean we are doing client/certificate authentication? i guess we are doing certificate validation in application code which means its application level and we are not doing any client/certificate authentication at server level.. can anyone please confirm this
what is client/certificate authentication by server in tomcat
It is two way SSL authentication. When SSL is enabled on the sever, the server cert should be there client trusted certs store.
Similarly, when the client/certificate authentication is enabled, the client SSL cert should be there in server trusted cert store.
we are getting certificate as part of request parameter and doing validation of certificate, does that mean we are doing client/certificate authentication?
No. That is application validation. But, who is setting in the request parameter.
NOTE: This client cert authentication is done by Container. But, the container provides the ssl properties using request parameters.
Look here to know what properties are set by the server when the connection is secure.

How to verify the correctness of configuring mutual authentication (client certificate, server certificate) Java EE?

I am trying to write a simple application to understand the basics of configuring authentication based on client and server certificates.
I have done everything as it is explained in jave ee 5, java ee 6 tutorials
http://docs.oracle.com/javaee/6/tutorial/doc/glien.html
Opened example from javaee tutorials hello basicauthorization (just simple servlet which can be accessed only after authentication) and then reconfigured it for client certificates instead of basic authorizations
Configured web.xml
Configured glassfish-web.xml
Generated client certificate
Imported client certificate so that the server would trust it.
The problem:
When I deploy my application, and follow the link, corresponding to the application, I get a message from glassfish server HTTP Status 400 - No client certificate chain in this request".
So, it seems, that the client (browser) doesn't send the certificate with the request
I tried adding the .cer certificate to Chrome, firefox, internet explorer and they are added (no error is displayed), but as you see that doesn't help.
So, the question is:
How to get the access to my application through the web browser having client .cer certificate?
You can debug ssl on the server-side by adding (somewhere in Glassfish) system properties:
-Djavax.net.debug=all
see this page for details.
You can also debug from the client perspective using openssl tool:
openssl s_client -connect host:port -debug -msg
you should see something like this:
...
Acceptable client certificate CA names
/C=PL/O=company/OU=xx/CN=host/emailAddress=email#example.com
/C=PL/O=company/OU=xx/CN=ca/emailAddress=email#example.com
---
SSL handshake has read 2536 bytes and written 116 bytes
...
your problem is probably related to bad truststore configuration on the server-side - server sends some Acceptable client certificate CA names (or no at all), but browser doesn't have anything to offer - it doesn't have any private key+certificate issued by acceptable ca.

Categories