To enable Mutual SSL Authentication (2 way SSL) in WSO2 EI 6.X.X(Docker) - ssl

There is a requirement in which client app will accept only certificate based authentication, I believe this can be achieved by enabling mutual SSL Auth in WSO2 EI.
This above scenario will applicable for both Inbound (Client APP --> WSO2 EI)and Outbound Flow(WSO2 EI --> Client APP).
Steps followed in Local system for Testing purpose:
Generating keystore and self-signed certificate:
C:\Program Files\Java\jdk1.8.0_291\bin>keytool -genkey -keyalg RSA -alias eitest -keystore "C:\path_eiserver\repository\resources\security\eitest.jks"
Exporting certificate
C:\Program Files\Java\jdk1.8.0_291\bin>keytool -export -alias eitest -file "C:\path_eiserver\repository\resources\security\eitest_public_cert.cer" -keystore "C:\path_eiserver\\repository\resources\security\eitest.jks"
Post executing above mentioned each steps, i got below WARNING.
Warning:
The JKS keystore uses a proprietary format. It is recommended to migrate to PKCS12 which is an industry standard format using "keytool -importkeystore -srckeystore C:\ei_pathserver\repository\resources\security\eitest.jks -destkeystore C:\ei_pathserver\repository\resources\security\eitest.jks -deststoretype pkcs12".
Even though got above WARNING required files generated
Can i ignore above WARNING? if YES what is the next step to make WSO2 EI REST API as secured with Mutual Authentication? if NO can i know further steps to be taken care?
References:
Ref link 1
Ref link 2
youtube referred
May I know the complete steps to achieve this Mutual Authentication in WSO2 EI?

You don't have to create new Keystores to enable MTLS. MTLS simply requires you to import the certificates that need to be validated.
Enabling MTLS for Client EI connection
Inorder to enable MTLS for the Client -> EI connection follow the steps below.
Import the Clients Public certificate to WSO2's client-trustore.jks.
Then in axis2.xml under the <transportReceiver name="https" class="org.apache.synapse.transport.passthru.PassThroughHttpSSLListener"> section add the following parameter.
<parameter name="SSLVerifyClient">require</parameter>
Note: If you add require all the connections coming to WSO2 will require MTLS validations, if you want to make MTLS validation optional you can add optional instead of require. When set to optional only if the Client sends its certificate MTLS validation will be performed.
Enabling MTLS for EI and Backend connection
In order to enable MTLS for the EI -> BE connection follow the steps below.
You can either create a separate Keystore for the connection. Or you can simply point to the existing Keystore and the Trustore.
First import the BE public cert into the Trustore you are using.
Export the Public cert used in EI and import it to the BE Trustore.
Now you can enable SSL dynamic profiles. Open axis2.xml and add the following to <transportSender name="https" class="org.apache.synapse.transport.passthru.PassThroughHttpSSLSender"> section.
<parameter name="dynamicSSLProfilesConfig">
<filePath>repository/conf/sslprofiles/sslprofiles.xml</filePath>
<fileReadInterval>3600000</fileReadInterval>
</parameter>
then create a file at repository/conf/sslprofiles/sslprofiles.xml and add the following content.
<parameter name="customSSLProfiles">
<profile>
<servers>your_server_address(e.g: something.test.com)</servers>
<KeyStore>
<Location>repository/resources/security/yourks.jks</Location>
<Type>JKS</Type>
<Password>123456</Password>
<KeyPassword>123456</KeyPassword>
</KeyStore>
<TrustStore>
<Location>repository/resources /security/yourtruststore.jks</Location>
<Type>JKS</Type>
<Password>123456</Password>
</TrustStore>
</profile>
</parameter>
With the above configuration for the connections that are made to something.test.com MTLS will be applied.

Related

How does a client get an SSL certificate from an ActiveMQ Broker?

I have an ActiveMQ Broker living on AWS. I'm trying to secure connections from clients using SSL. I have set up the broker to use SSL, but I don't quite understand where the clients are supposed to get the certificate from. Do I need to copy the cert from the broker and package it with client code? Or do I remotely retrieve the cert programmatically each time the client is launched?
Relevant SSL Setup in activemq.xml
<sslContext>
<sslContext keyStore="file:${activemq.base}/conf/broker.ks"
keyStorePassword="password" trustStore="file:${activemq.base}/conf/broker.ts"
trustStorePassword="password"/>
<transportConnectors>
<transportConnector name="openwire" uri="tcp://0.0.0.0:61616?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
<transportConnector name="ssl" uri="ssl://0.0.0.0:61714?transport.enabledProtocols=TLSv1.2"/>
</transportConnectors>
The clients connecting will be Java clients using JMS. At this point I'm using the default cert that comes packaged with the ActiveMQ installation.
As the ActiveMQ documentation states:
ActiveMQ includes key and trust stores that reference a dummy self signed cert. When you create a broker certificate and stores for your installation, either overwrite the values in the conf directory or delete the existing dummy key and trust stores so they cannot interfere)
Therefore, you should delete the existing broker.ks and broker.ts and create new ones for your installation. You've got a couple of options here.
I imagine that AWS has some sort of infrastructure to acquire SSL certificates and that those certificates would be signed by a well-known certificate authority which would be trusted implicitly by your JMS clients. A quick search turned up AWS Certificate Manager.
However, you also have the option of using a "self-signed" certificate which is, by definition, not signed by a well-known certificate authority and therefore must be explicitly trusted by your clients.
You can take the self-signed route by using the following commands:
Using keytool (from the JDK), create a certificate for the broker:
keytool -genkey -alias broker -keyalg RSA -keystore broker.ks
Export the broker's certificate so it can be shared with clients:
keytool -export -alias broker -keystore broker.ks -file broker_cert
Create a certificate/keystore for the client:
keytool -genkey -alias client -keyalg RSA -keystore client.ks
Create a truststore for the client, and import the broker's certificate. This establishes that the client "trusts" the broker:
keytool -import -alias broker -keystore client.ts -file broker_cert
When starting the client's VM, specify the following system properties:
javax.net.ssl.trustStorePassword=password
javax.net.ssl.trustStore=/path/to/client.ts
If you choose the self-signed route then you only need to generate the client.ts once and then copy that to every client. The clients will use the same truststore every time they connect (assuming the broker's certificate doesn't change).

Serving content over HTTPS

Can GraphDB Free be configured in any way to allow content to be served over HTTPS?
I'm creating a simple front-end web application using Angular2 that makes HTTP requests to the GraphDB SPARQL endpoint.
I'm using Windows IIS and the server has been setup not to trust any content this is not served over HTTPS.
Any insights would be helpful.
According the instructions in GraphDB's configuration file $GDB_HOME/conf/graphdb.properties, to enable HTTPS uncomment the following lines:
# Enable SSL (uncomment to enable)
graphdb.connector.SSLEnabled = true
graphdb.connector.scheme = https
graphdb.connector.secure = true
# GraphDB uses the Java implementation of SSL, which requires a configured key in the Java keystore.
# To setup keystore uncomment the following properties and set keystorePass and keyPass to the actual values.
graphdb.connector.keyFile = <path to the keystore file if different from ${graphdb.home}/keystore>
graphdb.connector.keystorePass = <secret>
graphdb.connector.keyAlias = graphdb
graphdb.connector.keyPass = <secret>
If you use a self-signed certificate add it to the keystore with:
keytool -genkey -alias graphdb -keyalg RSA
If you have a third-party trusted OpenSSL certificate, you would need to convert it to PKCS12 key and then import to the Java keystore with:
keytool -importkeystore -deststorepass MYPASS -srckeystore mypkcs12.p12 -srcstoretype PKCS12
For additional information on how to deal with the third party trusted certificates check this excellent link explaining in great details how to convert import private key and certificate into java keystore
Edited
To locate the $GDB_HOME directory for the desktop installation, check the GraphDB documentation.

Hitting SSL Rest end point using SoapUI works, but not using postman

I'm trying to create a SSL rest endpoint (just a hello world get request) using spring boot.
I created a self signed certificate and imported into the PKCS12 keystore using the following command, and was able to successfully add it to the keystore of Tomcat embedded within spring boot application.
I was using postman to test my endpoint. Before that, I successfully imported the client certificate as described in the link - http://blog.getpostman.com/2014/01/28/using-self-signed-certificates-with-postman/ to the Trusted Root Certificate Authorities and also in personal.
In spite of importing the client certificate, the request through postman fails. However, if I try to hit the same HTTPS endpoint using SoapUI, I get a successful response.
Note: In the link - http://blog.getpostman.com/2014/01/28/using-self-signed-certificates-with-postman/ someone had already raised a similar issue. However, not sure whether this was addressed by postman.
Any help on this is much appreciated!!!
Command used to create used to create keystore:
keytool -genkeypair -alias tomcat -storetype PKCS12 -keyalg RSA -keysize 2048 -keystore "c:\cert\keystore.p12" -validity 3650
spring boot application.properties:
server.port=8443
server.ssl.key-store=keystore.p12
server.ssl.key-store-password=changeit
server.ssl.key-store-type=PKCS12
server.ssl.key-alias=tomcat

Issue in self signed certificate

I am now trying to access the web service via https and to achieve this i have done the below.
I used the below commands to generate the self signed certificate and placed in /conf dir.
keytool -genkey -alias localhost -keyalg RSA -validity 365 –keystore server.keystore –storetype JKS
keytool -export -alias localhost –keystore server.keystore -rfc -file public.cert
keytool -import -alias localhost -file public.cert –storetype JKS -keystore server.truststore
Below is the server.xml entry
<Connector className="org.apache.catalina.connector.http.HttpConnector"
port="8443" minProcessors="5" maxProcessors="75"
enableLookups="true"
acceptCount="10" debug="0" scheme="https" secure="true">
<Factory className="org.apache.catalina.net.SSLServerSocketFactory"
keystoreFile="conf/server.keystore"
keystorePass="changeit"
truststoreFile="conf/server.truststore"
truststoreType="JKS" truststorePass="changeit"
clientAuth="false" protocol="TLS"/>
</Connector>
And now i am facing the below error.
{http://xml.apache.org/axis/}stackTrace: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: No trusted certificate found
However the error is not thrown if i add the below code in the class file accessing the webservice.
AxisProperties.setProperty("axis.socketSecureFactory","org.apache.axis.components.net.SunFakeTrustSocketFactory");
Could you please guide me in resolving this issue?
TLS is being set up on two sides: server and client. Each side must have its own key pair saved into a key store. Let's call them serverKeystore.jks and clientKeystore.jks
Then additional key store is to be created containing only public key. This one is called trust store and used for key authentication. Let's follow the same scheme and save them into serverTruststore.jks and clientTruststore.jks.
In one way TLS only server key is being authenticated.
Server must have only serverKeystore.jks provisioned in Connector.
Client must have provisioned both clientKeystore.jks and serverTruststore.jks.
In two way TLS both server and client keys are being authenticated.
Server must have serverKeystore.jks and clientTruststore.jks provisioned in Connector.
Client must have provisioned both clientKeystore.jks and serverTruststore.jks.
Client registers key stores either by specifying Java environment variable with
-Djavax.net.ssl.keyStore="path\\to\\server.keystore"
in parameters to command starting JVM, or programmatically in the code with
System.setProperty("javax.net.ssl.keyStore", "path\\to\\server.keystore");
Technically it is possible to use the same key pair both on client and server side as you did. But this compromises the private key, as it is not secret any more.
The below entry is added in the class file where the call to https would happen and it works like charm. Yet i am not sure why the xml entry is not considered.
System.setProperty("javax.net.ssl.keyStore", "path\\to\\server.keystore");
System.setProperty("javax.net.ssl.keyStorePassword", "changeit");
System.setProperty("javax.net.ssl.trustStore", "path\\to\\server.truststore");
System.setProperty("javax.net.ssl.trustStorePassword", "changeit");
PS: Both xml entry and the class entry is needed else the same error is thrown. I am yet to get a clear picture on this. Maybe someone might explain. Thanks

Worklight Adapter Mutual SSL

Followed steps to integrate Worklight with backend system. In 5.0.6 adapters should support mutual SSL.
Import cert into default.keystore with alias named cert1
Modified adapter's sslCertificateAlias as cert1
When using Worklight Studio to run deployed adapter connecting with server, it is complaining about "Unable to find certificate chain with alias: 'cert1'".
What are the steps missing?
Check "ssl.keystore.*" properties in "worklight.properties" file, after it check if the cert exists in the keystore file using keytool:
keytool -list -keystore default.keystore
Here is are steps to configure mutual SSL between adapter and backend server with self signed certificates:
generate adapter's private key in "default.keystore" and export its public certificate
import adapter's certificate into backend truestore file
in case backend hasn't CA signed certificate:
generate backend's private key in its keystore file and export public certificate
import backend's public certificate into "default.keystore" file on WL server
Check worklight.properties file. Make sure that ssl related setting point to a default.keystore.
Figured out yesterday. Have to config certificate chain in proper way.
All certifications (server cert, first level cert and root cert) have to combine into one in special order and import with private key into keystore. Then use one alias name so that Worklight adapter could find it.