cancel
Showing results for 
Search instead for 
Did you mean: 

Update the client certificate before expiry automatically via SAP CPI and groovy(openssl command)

AmanVarshney
Product and Topic Expert
Product and Topic Expert

Hello Community,

I hope you all are doing great and safe.

I have a situation where the receiver service will get their certificate renewed every 2 months and to skip manual dependency of certificate updating in keystore we have Security Content api to use, but how to programmatically fetch the certificate from the service host?

I have been trying through an option running openssl commands via groovy to fetch the certificates which can be scheduled via Cloud Integration every 2 months.

I would like to hear your views on this thought or any other implemented solutions.

*********************************************************************************************************

Update: A new improvement request https://influence.sap.com/sap/ino/#/idea/268386 has been raised for the functionality implementation as an API.

Please vote the idea to avail the functionality fast. 🙂

Accepted Solutions (1)

Accepted Solutions (1)

Ivan-Mirisola
Product and Topic Expert
Product and Topic Expert
0 Kudos

Hi avar,

You can use the CPI APIs to update a certificate in the keystore.

Here is the API documentation:

https://api.sap.com/api/SecurityContent/overview

Here is an example of how to update a certificate using the API:

https://help.sap.com/viewer/368c481cd6954bdfa5d0435479fd4eaf/Cloud/en-US/be3a0b92a4a446a3ac8637e2521...

Best regards,
Ivan

AmanVarshney
Product and Topic Expert
Product and Topic Expert
0 Kudos

Hello ivan.mirisola ,

Thankyou so much for responding.

I happily agree to your suggestion to update the certificate via Security Content API.

But I am more interested to fetch certificate from the host via groovy and skip any manual downloads. As per my current research openssl commands do support certificate fetching and groovy do support openssl commands directly. Hence I am trying to run on groovy statements as below sample. I want to know if someone already has experience with the same.

def command="openssl s_client -servername google.com -connect google.com:443"; 
def proc = command.execute();
Ivan-Mirisola
Product and Topic Expert
Product and Topic Expert

Hi avar,

Sorry for the misunderstanding. The following code runs under Goovy Interpreter and is able to extract Google's certificate into Base64/MIME format.

Please adapt it to your needs.

import java.security.cert.X509Certificate;
import java.util.Base64;

import javax.net.ssl.SSLPeerUnverifiedException;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;

public class ExtractCert {

    public static void main(String[] args) throws Exception {
        SSLSocketFactory factory = (SSLSocketFactory) SSLSocketFactory.getDefault();
        SSLSocket socket = (SSLSocket)factory.createSocket("www.google.com", 443);

        //Connect to the peer
        SSLSession session = socket.getSession();
        X509Certificate cert;

        //Get the peer's first certificate offered during TLS - which should be the server's certificate
        try {
          cert = (X509Certificate) session.getPeerCertificates()[0];
        } catch (SSLPeerUnverifiedException e) {
          System.err.println(session.getPeerHost() + " did not present a valid cert.");
          return;
        }

        String sDNName = cert.getIssuerDN().getName(); // Server's DN Name
        String sDEREncoded = 
			"-----BEGIN CERTIFICATE-----\n" + 
			Base64.getMimeEncoder().encodeToString(cert.getEncoded()) +
			"\n-----END CERTIFICATE-----"; // Server's Certificate encoded in Base64/MIME
        
        System.out.println("sDNName: " + sDNName);
        System.out.println("sDEREncoded: " + sDEREncoded);

    }
}

Hope this helps.

Best regards,
Ivan

Answers (1)

Answers (1)

AmanVarshney
Product and Topic Expert
Product and Topic Expert

Thankyou ivan.mirisola and Cheers!

The shared code helped and the required certificates content is being fetched now. Sharing the groovy code for the community 🙂

import com.sap.gateway.ip.core.customdev.util.Message;

import java.security.cert.X509Certificate;
import java.util.Base64;
import java.util.HashMap;
import javax.net.ssl.*;

def Message processData(Message message) {
    
        SSLSocketFactory factory = (SSLSocketFactory) SSLSocketFactory.getDefault();
        SSLSocket socket = (SSLSocket)factory.createSocket("www.google.com", 443);


        //Connect to the peer
        SSLSession session = socket.getSession();
        X509Certificate cert;

        //Get the peer's first certificate offered during TLS - which should be the server's certificate
        try {
          cert = (X509Certificate) session.getPeerCertificates()[0];
        } catch (SSLPeerUnverifiedException e) {
            throw new Exception(session.getPeerHost() + " did not present a valid cert.");
        }

        def sDNName = cert.getIssuerDN().getName(); // Server's DN Name
        def sDEREncoded = 
			"-----BEGIN CERTIFICATE-----\n" + 
			Base64.getMimeEncoder().encodeToString(cert.getEncoded()) +
			"\n-----END CERTIFICATE-----"; // Server's Certificate encoded in Base64/MIME
       //Set Properties 
       message.setProperty("sDNName", sDNName);
       message.setProperty("sDEREncoded", sDEREncoded);
       return message;
}