In this post I will walk you through the certificate creation process and testing the mutual authentication with Salesforce
First you have to make sure mutual authentication is enabled in your organization or else please create a case with Salesforce support to enable mutual authentication in your organization
You have to follow this Certificate Generation Process to generate the public and private key
- Generate the Certificate Signing Request (CSR) for the client certificate the API client will present when attempting to establish the mutually authenticated TLS connection to Salesforce. It’s important that the client certificate be signed by one of the salesforce.com trusted root certificate authorities.
Use this command to create a CSR and private key
openssl req -out CSR.csr -new -newkey rsa:2048 -nodes -keyout privateKey.key
Fill this information
Country Name (2 letter code) [AU]: FR State or Province Name (full name) [Some-State]: XXX Locality Name (eg, city) :XXX Organization Name (eg, company) [Internet Widgits Pty Ltd]:COMPANY NAME Organizational Unit Name (eg, section) : Common Name (e.g. server FQDN or YOUR name) :XXXXXX Email Address :-*Blank*- A challenge password :-*Blank*- An optional company name :-*Blank*-
- Once the certificate is signed you will get p7b format, you have to convert it to pem format using this openssl command
openssl pkcs7 -in pub.p7b -inform DER -out public.pem -print_certs
Copy the PEM file and change the extension to CRT and upload the certificate to the organization at Security Controls | Certificate and Key Management. Upload the signed client certificate to the Mutual Authentication Certificates table in order for Salesforce to properly validate the client certificates presented by the client when initiating an inbound mutually authenticated TLS connection.
Enable the Enforce SSL/TLS Mutual Authentication user permission for the API client user. This permission forces the use of port 8443 for secure connections. This permission can be added to a profile or assigned to an individual user with a permission set.
Enable the “Enforce SSL/TLS Mutual Authentication” user permission for an “API Only” user. This “API Only” user configures the API client to connect on port 8443 to present the signed client certificate
Click Upload Mutual Authentication Certificate.
Give your certificate a label and name and click Choose File to locate the certificate.
Click Save to finish the upload process.
And now we have to create a complete p12 file using this openssl command
openssl pkcs12 -export -out complete.p12 -inkey private.key -in public.crt
You can test using curl commands but to simplify the testing I will be using SOAPUI which doesnt need complete pem file. In case if you need the pem you can generate it using this command
openssl pkcs12 -in complete.p12 -out complete.pem
In SoapUI create a project from the Partner WSDL
Use the login method
Send this request to test.salesforce.com/services/soap/u/33.0 (in case of prod login.salesforce.com/services/soap/u/33.0)
<?xml version="1.0" encoding="utf-8" ?> <env:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"> <env:Body> <n1:login xmlns:n1="urn:partner.soap.sforce.com"> <n1:username>email@example.com</n1:username> <n1:password>xxx</n1:password> </n1:login> </env:Body> </env:Envelope>
you will receive a session Id and with this you will be able to do the mutual auth testing.
You have to install the complete certificate in the SoapUI keystore
Goto SOAPUI Preferences
Click on SSL Settings
Browse to p12 and enter the password in the keystore password field
Use the Query method to send this information to XX.salesforce.com/services/soap/u/33.0(XX will be the instance name retrieved in the login call)
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:urn="urn:partner.soap.sforce.com"> <soapenv:Header> <urn:SessionHeader> <urn:sessionId>00Dg0000006RLJ1!AQ0AQFvsjYf.rgdEeF7aDWqXbPfut1qoEtxTDg.aAPvilob3W3kArHxFV.cQPv4e5H3Sgl6tg9AjfLPkpt5zDoKB9BS.eDJe</urn:sessionId> </urn:SessionHeader> </soapenv:Header> <soapenv:Body> <urn:query> <urn:queryString>SELECT ID,NAME FROM USER</urn:queryString> </urn:query> </soapenv:Body> </soapenv:Envelope>
You will get this error as we haven't specified the 8443 port
Add the port 8443 in the url - XX.salesforce.com:8443/services/soap/u/33.0
Voila it working :)