Skip to Content

Introduction

We recently had an issue with a new certificate we were trying to install. The certificate was used to encrypt and sign the messages sent to an external site. This was a new certificate and it’s understandable that it may have issues. However the most intriguing part was that the certificate was behaving very differently on different platforms. When the certificate didn’t work, we tried asking the business for a new certificate but their response was that the certificate works with a Microsoft based application and hence the issue will be on PI side.

Analysis:

We were using a Java map for encrypting and signing the messages and hence had some idea about which part in the certificate loading process the error was happening. Before we proceed, just a quick note about certificate aliases:

All key store entries ( keys and certificates ) are accessed via unique aliases. Further, aliases are case-insensitive — mycertalias and MYcertAlias would refer to the same entry.

The certificate key extraction from a keystore essentially involves three steps:

  1. Load the certificate from keystore
  2. Enumerate over certificate aliases
  3. Extract the key / certificate using the alias
  • We enabled logging in the Java code and saw that there is no issue in loading the certificate.
//ks is Keystore ks.load(new FileInputStream(“/tmp/cert.pfx”), “password”.toCharArray());

The certificate loading is fine. If we look at ks.size() it returns 1.

Enumerating over the aliases outputs the alias — so far so good

Enumeration<?> en = ks.aliases();

String alias = (String)en.nextElement();

However, if we extract the certificate using the alias, we get a null back !

X509Certificate x509cert = ((X509Certificate)ks.getCertificate(alias));

The error message we got from our logs . I have replaced the actual alias by <alias_guid>.

Looking at the different parts involved, we were trying to isolate the issue in the following parts:

  • JVM : We wanted to see if different JVM gives different results with the same certificate.
  • JCE : JCE doesn’t come standard with standard JAVA installation and has to be extended by installing a Java Cryptography Extension. It can be from Oracle and the extension can be downloaded from this link. SAP PI Java Application Server uses a JCE from IAIK.

Tests to check certificate in different environments:

Tests in alternative environments:

  • This is where the problem got more interesting . We thought that there is something wrong with the certificate and we should be able to replicate the problem in a different environment.

Test1 : NWDS : Standalone test ( on Windows environment) : Default JVM / JCE

Keystore size is : 1
Keystore provider is : SunJSSE version 1.6
Keystore type is : PKCS12
Alias is : <alias_guid>
Contains alias: <alias_guid>true
Expiry date of public key : Mon Dec 02 09:12:29 EST 2019

So we didn’t find any issues when testing on local PC. We thought that perhaps something is wrong with the JVM running on PI servers. We tried a second test in unix environment where our PI servers are hosted.

Test2 : NWDS : Standalone test ( on Unix environment) with IBM JCE

Keystore size is : 3
Keystore provider is : is IBMJCE version 1.2
Keystore type is : PKCS12
Alias is : <alias_guid>
Contains alias: <alias_guid>true
Expiry date of public key : Mon Dec 02 09:12:29 EST 2019

Then we thought that perhaps IAIK JCE is having issues .So did one more test.

Test3 : NWDS : Standalone test ( on Windows environment) using IAIK JCE provider. 

By now we were suspecting IAIK JCE library to have issues. However, we couldn’t get access to the version of JCE library running on PI server. We tested with IAIK version 5.51 which can be downloaded for tests.

Keystore size is : 2
Keystore provider is : IAIK version 5.51
Keystore type is : PKCS12
Alias is : <alias_guid>
Contains alias: <alias_guid>true
Expiry date of public key : Mon Dec 02 09:12:29 EST 2019

Workaround:

As these tests were not conclusive where the error was but we had a fair idea that there was an issue with the certificate alias. As a workaround, we changed the certificate alias.

OpenSSL:

OpenSSL is a Swiss army knife for SSL tools and it came to our rescue when we came to realise that the only way to get the certificate working will be to modify it.

Some examples :

– To extract unencrypted key file

openssl pkcs12 -in <filename.pfx> -nocerts -nodes -out <clientcert.key>

-Extract client certificate

openssl pkcs12 -in <filename.pfx> -clcerts -nokeys -out <clientcert.cer>

-Extract CA certificate ( root and all intermediate certs)

openssl pkcs12 -in <filename.pfx> -cacerts -nokeys -chain -out <cacerts.cer>

So we were able to extract the client certificate . Sample screen shot with the alias name ( friendly name ).

Initial workaround:

To extract the private key, run the OpenSSL command:

openssl pkcs12 -in <filename>.pfx -nocerts -out key.pem

To extract the certificate (public key), run the OpenSSL command:

openssl pkcs12 -in <filename>.pfx -clcerts -nokeys -out cert.pem

We then used openssl to assemble the certifcate.

Example of adding alias for a certificate:

openssl pkcs12 -export -in my-cert.crt -inkey my-priv-key.key -certfile my-ca-bundle -out my-pfx.pfx -name “alias”

So this provided a workaround to use a new alias and get the messages working.

However, we were still not very sure why the difference is coming on different platforms.

I then copied the parts of Java map related to loading the certificate as an adapter module so that it can be easily tested in different PI versions . I then launched a SAP PO instance in SAP CAL library ( which has PO version PO 7.5 ) and surprisingly the issue persisted there as well.

Easier workaround

Raising a SAP incident and getting an easier workaround.

As the issue with the certificate was coming only in SAP PI application server and it was fine everywhere, we raised a SAP incident. The issue seems to be for the version of IAIK JCE library we are using in its handling of non printable characters in alias name. We were also suggested a workaround which is much easier to use then openssl.

The steps are very simple:

  • Use an existing certificate view in NWA. Import the certificate.
  • Now export the certificate using NWA.

The certificate can be downloaded and has a different valid alias name.

Before we modified the certificate we were getting the below trace.

11/02/2018 15:37:29.512 Information Alias is <alias_guid>
11/02/2018 15:37:29.512 Information Alias length is 39
11/02/2018 15:37:29.512 Information Contains alias: <alias_guid> true
11/02/2018 15:37:29.521 Information while trying to invoke the method java.security.cert.X509Certificate.getType() of a null object loaded from local variable x509cert

Now it gets loaded .

11/02/2018 15:34:38.347 Information Alias is mycert
11/02/2018 15:34:38.347 Information Alias length is 6
11/02/2018 15:34:38.356 Information Cert type is X.509
11/02/2018 15:34:38.356 Information Valid till : Sun Dec 01 22:12:29 UTC 2019

Conclusion and key takeaways:

The key takeaways from this blog:

  • Typical steps involved in using a certificate involves loading a certificate, extracting the alias attribute and then using the alias to get the keys / certificates.
  • SAP PI NWA Keystore sets the alias names as the file name and hence can be used to fix issues with alias name.
  • Later versionf os SAP PI/PO 7.5 have the issue fixed according to SAP. However, I haven’t tested it – SAP PO Cal has IAIKJCE version 3.181 where the issue still persisted.
  • I have created an adapter module which can be used to test across different systems .The EAR file can be downloaded from https://github.com/viksingh/CheckCert

 

 

To report this post you need to login first.

Be the first to leave a comment

You must be Logged on to comment or reply to a post.

Leave a Reply