The ability to sign Java jar files, or z/OS modules, has been around for many years. Using this the loader checks the digital signature in the object. This digital signature is a checksum of the object, and this checksum is encrypted and stored with the object. At load time, the loader calculates the checksum, and decrypts the checksum in the object and checks they match.
MQ now supports this for some of its objects; downloadable .zip, .tar and .gz files.
For some of these you need to download the public key to use. This raises the problem that an evil person may have taken the object, removed the official signing information, and added their own stuff. You then download their public certificate – see it works, it must be official.
To prevent this you can do the checksum on the public certificate, and make that available along with the official public key. (This is the chicken and egg problem. You need the certificate to be able to check the main code, and how to you check the certificate, without a certificate to check?)
On Linux you can calculate the checksum of a file using
this gives 53c34cd374d7b08522423533ef2019b4aa0109a595fbaeab8ee6f927cb6c93ad, which is the same as the value on the IBM site. So this matches.
release level: 22.214.171.124-IBM-MQ-Sigs-Certs
Continuous Delivery: 9.2.4 IBM MQ file signatures, checksums and certificates
Platforms: AIX 64-bit, pSeries, Linux 64-bit,x86_64, Linux 64-bit,zSeries, Linux PPC64LE, Windows 64-bit, x86, z/OS
This page is an httpS page, with the certificate issued by a proper Certificate Authority, and trusted third party. If you trust this CA, you can trust the IBM page.
When you click download, it downloads
- 126.96.36.199-IBM-MQ-Sigs-Certs.tar.gz.sha256sum – this file content has 53c34cd374d7b08522423533ef2019b4aa0109a595fbaeab8ee6f927cb6c93ad
The value in the sha256sum file matches the value of the sha256sum 188.8.131.52-IBM-MQ-Sigs-Certs.tar.gz command.
As you can trust the security chain from the web page, through to the downloads, you can trust the .gz file.
Java has had the capability to sign a jar for at least 10 years.
The jarsigner command takes a jar file, a keystore with private key and calculates the checksum. It then encrypts it, and creates some files in the jar. For example
jarsigner -keystore trust.jks -storepass zpassword checkTLS.jar signer
- the keystore called trust.jks,
- with password zpassword
- the checkTLS.jar file
- and uses the certificate with alias name signer. This certificate must have extendedKeyUsage with codeSigning.
The jar file now has some additional files which can be seen using jar -tvf checkTLS.jar command.
- META-INF/SIGNER.SF . This is the Signature File.
- META-INF/SIGNER.EC .This is the public key to be used.
Where SIGNER is the name of the alias of the private key in the keystore, used to sign the jar file. The jar file can be signed many times by different private keys.
To verify the signature you can use
- jarsigner -verify checkTLS.jar
- jarsigner -verbose -certs -verify checkTLS.jar
The jarsigner -verbose -certs -verify checkTLS.jar gave me
- Signed by "CN=signer, O=cpwebuser, C=GB" Digest algorithm: SHA-256 Signature algorithm: SHA256withECDSA, 256-bit key jar verified. Warning: This jar contains entries whose certificate chain is invalid. Reason: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target This jar contains signatures that do not include a timestamp. Without a timestamp, users may not be able to validate this jar after any of the signer certificates expire (as early as 2024-11-03). The signer certificate will expire on 2024-11-03.
This shows that the jar file is consistent with the checksumming, but the certificate cannot be validated.
I can tell it which keystore to use to validate the certificate, using
jarsigner –keystore trust.jks -certs -verify checkTLS.jar
With the -verbose option you also get (with some of the output rearranged for clarity). The “s” or “sm” at the front of an object entry is s=signature verified, and m=entry listed in the manifest.
s = signature was verified m = entry is listed in manifest k = at least one certificate was found in keystore i = at least one certificate was found in identity scope s 1402 Wed Dec 22 14:27:52 GMT 2021 META-INF/MANIFEST.MF >>> Signer X.509, CN=signer, O=cpwebuser, C=GB [certificate is valid from 22/12/21 14:51 to 30/01/25 16:46] X.509, CN=SSCA256, OU=CA, O=SSS, C=GB [certificate is valid from 04/11/21 15:48 to 03/11/24 15:48] [Invalid certificate chain: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target] 1579 Wed Dec 22 16:12:04 GMT 2021 META-INF/SIGNER.SF 1373 Wed Dec 22 16:12:04 GMT 2021 META-INF/SIGNER.EC sm 54 Sat Jan 30 14:48:52 GMT 2021 checkTLS/checkTLS.manifest >>> Signer X.509, CN=signer, O=cpwebuser, C=GB [certificate is valid from 22/12/21 14:51 to 30/01/25 16:46] X.509, CN=SSCA256, OU=CA, O=SSS, C=GB [certificate is valid from 04/11/21 15:48 to 03/11/24 15:48] [Invalid certificate chain: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target]
When I downloaded the MQ 9.2.4 client and ran the jarsigner …. -verbose command the output included
sm 642 Thu Nov 04 16:01:46 GMT 2021 wlp/lib/extract/IFixUtils$ParsedIFix.class [entry was signed on 04/11/21 17:58] >>> Signer X.509, CN=International Business Machines Corporation, OU=IBM CCSS, O=International Business Machines Corporation, L=Armonk, ST=New York, C=US [certificate is valid from 25/08/21 01:00 to 26/08/23 00:59] X.509, CN=DigiCert Trusted G4 Code Signing RSA4096 SHA384 2021 CA1, O="DigiCert, Inc.", C=US [certificate is valid from 29/04/21 01:00 to 29/04/36 00:59] X.509, CN=DigiCert Trusted Root G4, OU=www.digicert.com, O=DigiCert Inc, C=US [trusted certificate] ...
This shows that the certificate used to sign the component of the jar file was signed by CN=International Business Machines Corporation, which was in turn signed by CN=DigiCert Trusted G4 Code Signing RSA4096 SHA384 2021 CA1. The jarsigner program was able to use its public certificate to validate the CA, and so validate the IBM certficiate, and so validate the checksum.