Automating Code Signing with latest E-Business Suite Signing Improvements - Part 4

August 22, 2024

Johannes Michler PROMATIS Horus Oracle


Executive Vice President – Head of Platforms & Development

Last week, Oracle released a major re-work of its article on Signing JAR Files for Oracle E-Business Suite Release 12 (Doc ID 1591073.1). Taking into consideration that all major public Code Signing CAs now require Hardware Security Module (HSM) based storage of the private key this was long awaited. In previous parts of this blog series I've covered how we can workaround the limitations of jarsigning in E-Business Suite, see part 1, part 2 and part 3.

In this 4th part we'll cover how this procedure can be improved by using these latest patches to E-Business Suite.

Installation of required patches

To take advantage of the new procedures you have to apply a couple of patches (see 1591073.1) for more details:

adop phase=prepare,apply,finalize,cutover,cleanup patches=36492441
adop phase=prepare,apply,actualize_all,finalize,cutover,cleanup patches=36407980,36505379,36555711,36499096 finalize_mode=full mtrestart=no cleanup_mode=full

Note: The Support note explicitly states that you have to apply 36492441 first, so it seems that this has to be done in 2 patching cycles.

Implementation of a customjarsign.sh for Certum

Without doing anything in addition applying those patches still signs the jars in KEYSTORE mode (the same way as before). However now you have the possibility to write your own/modified customarsign.sh script that calls more advanced signing commands. In my case I've changed that file to have the main custom signing method as follows:

signjar_custom () # $1 name of 1 JAR file
{
echo "INFO: Signing JAR '$1' with certum..."
zip -d ${jar} 'META-INF/*.SF' 'META-INF/*.RSA'
scp $1 certum@172.31.2.199:/tmp/signing-dummy.jar
retry_count=0
while true; do
ssh certum@172.31.2.199 "/home/certum/SS-9.1.11.0-dist/jre/bin/jarsigner -keystore NONE -tsa \"http://time.certum.pl\" -certchain /home/certum/mychain.pem -storetype PKCS11 -providerClass sun.security.pkcs11.SunPKCS11 -providerArg /home/certum/provider_simplysign.cfg -storepass 12345 /tmp/signing-dummy.jar 4F4F410D0356A9110B16AC9C73BD6F59" | tee -a ~/customsign.log
if [ ${PIPESTATUS[0]} -eq 0 ]; then
break
fi
if [ $retry_count -eq 0 ]; then
ssh certum@172.31.2.199 "echo \"Please start certum on Cloud Manager\" | mailx -s \"Please start and sign in to Certum for patching/signing!\" XX@promatis.de"
fi
retry_count=$((retry_count + 1))
echo `date`":in retry-loop for $1 , iteration $retry_count" >> ~/customsign.log
echo "signing failed; will try again in 5 seconds. Press q to abort"
read -t 5 -n 1 key
if [ "$key" = 'q' ]; then
echo "Loop aborted by user."
return 1
fi
JAR_EXISTS_FILE=/home/oracle/NO_JAR_SIGNING
if [ -f "$JAR_EXISTS_FILE" ]; then
echo "/home/oracle/NO_JAR_SIGNING exists. Exit with error" | tee -a ~/customsign.log
return 1
fi
done
scp certum@172.31.2.199:/tmp/signing-dummy.jar $1
echo "`date`signing of $1 succesful" >> ~/customsign.log
return 0
}

Now let us walk through this step by step:

  • first of all, this relies on the idea of part 3 of the blog series to copy the jar file to be signed (residing in $1) to the cloud manager VM on 172.31.2.199.
  • Before doing this, we remove any old signatures in the jar file - even though this may not always be necessary; it shouldn't harm either
  • Then we copy the jar to be signed to /tmp/signing-dummy.jar on the signing compute instance
  • after that we call the jarsigner over there through ssh
  • and finally if everything worked fine we copy the signed /tmp/singing-dummy.jar back to the original place and return as successful

As you have probably noticed there is some additional code though:

  • First of all logging is not working that nice when just handing out everything to stdout, so that's why I've decided to put everything relevant to ~/customsign.log
  • Furthermore, the process to sign using the Certum tools requires an up-to-date login/token. Since that may or may not be available I've decided to query for the signing result status and then go into a loop checking again every 5 seconds.

Since there is no real way to interact with the user through adjss / adadmin/adop I've decided to have the following workarounds:

  1. On the first fail of signing I write an E-Mail to myself asking myself to start the signing tool
  2. For testing purposes and when calling customsign.sh directly I allow to abort the endless loop by pressing "q"
  3. For PROD scenarios where I'm somehow unable to get a token and still want to continue the overall cycle (of course then without signing the jars) I check for a ~/NO_JAR_SIGNING file and if that exists I exit the script with an error.

Unit Testing the script

The support note describes an easy way to unit-test the script; keep in mind to do some testing both with the Certum tool started and not started. At the end you should have a result similar to:


successful test calling

Using the new CUSTOM method

Once unit testing is successful you have to copy the customjarsign.sh file to $APPL_TOP_NE/ad/admin/customjarsign.sh.

Afterwards you can change the signing mode to CUSTOM:

adjss -mode CUSTOM

Once that is done you can test in a more realistic way by calling:

adjss -sign

That should produce a result as follows:

Successful test using adjss

Keep in mind to also do some negative testing (stopped and only later on started SignTool) as well.

Re-Signing using adadmin

After all the tests were successful you can simply call adadmin (or apply a patch) which should call your customjarsign.sh script and sign modified .jar files "on the fly".

Summary

The new jar-sign-tooling released by Oracle makes Code Signing a lot more convenient again. Beside of using Certum there is an even more convenient "partial implementation" already provided in the script from Oracle that uses the digicert signing which should work entirely without user interaction. If you can spare the additional $$ it is probably easier to go for digicert instead of certum thus.