Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Signing with GCP KMS requires the algorithm to be appended to the alias #271

Open
efetoboreakpoguma opened this issue Jan 21, 2025 · 1 comment

Comments

@efetoboreakpoguma
Copy link
Contributor

I am currently attempting to perform code signing using a private key stored in Google Cloud KMS and a code signing certificate. I discovered it fails when I don't include the algorithm in the alias (key name).

For example, this fails:

jarsigner -J-cp -Jjsign.jar `
	-J--add-modules -Jjava.sql -providerClass net.jsign.jca.JsignJcaProvider `
	-providerArg projects/project/locations/global/keyRings/keyRing -keystore NONE `
	-storetype GOOGLECLOUD -storepass <REDACTED> -certchain signing_cert.pem `
	-tsa http://timestamp.digicert.com -strict -debug D:\fileToSign.jar key/cryptoKeyVersions/1

and this passes:

jarsigner -J-cp -Jjsign.jar `
	-J--add-modules -Jjava.sql -providerClass net.jsign.jca.JsignJcaProvider `
	-providerArg projects/project/locations/global/keyRings/keyRing -keystore NONE `
	-storetype GOOGLECLOUD -storepass <REDACTED> -certchain signing_cert.pem `
	-tsa http://timestamp.digicert.com -strict -debug D:\fileToSign.jar key/cryptoKeyVersions/2:RSA

because it contains :RSA.

I discovered that it passes because there is a check for the colon here in the alias name so we never have to check the signing certificate. However, when I don't include the algorithm in the alias, it fails with this exception:

jarsigner error: java.lang.RuntimeException: Failed to load the certificate from 
 java.lang.RuntimeException: Failed to load the certificate from 
     at net.jsign.KeyStoreType.lambda$getCertificateStore$0(KeyStoreType.java:565)
     at net.jsign.jca.GoogleCloudSigningService.getCertificateChain(GoogleCloudSigningService.java:102)
     at net.jsign.jca.GoogleCloudSigningService.getPrivateKey(GoogleCloudSigningService.java:126)
     at net.jsign.jca.SigningServiceKeyStore.engineGetKey(SigningServiceKeyStore.java:36)
     at java.base/java.security.KeyStore.getKey(KeyStore.java:1057)
     at net.jsign.jca.JsignJcaProvider$JsignJcaKeyStore.engineGetKey(JsignJcaProvider.java:122)
     at java.base/java.security.KeyStore.getKey(KeyStore.java:1057)
     at jdk.jartool/sun.security.tools.jarsigner.Main.getAliasInfo(Main.java:2276)
     at jdk.jartool/sun.security.tools.jarsigner.Main.run(Main.java:282)
     at jdk.jartool/sun.security.tools.jarsigner.Main.main(Main.java:129)
 Caused by: java.io.FileNotFoundException: 
     at java.base/java.io.FileInputStream.open0(Native Method)
     at java.base/java.io.FileInputStream.open(FileInputStream.java:219)
     at java.base/java.io.FileInputStream.<init>(FileInputStream.java:157)
     at net.jsign.CertificateUtils.loadCertificateChain(CertificateUtils.java:44)
     at net.jsign.KeyStoreType.lambda$getCertificateStore$0(KeyStoreType.java:563)
     ... 9 more

As you can see, the certificate file cannot be found. The exception gets thrown from here because params.certfile() is empty.

Is this behaviour expected or have I stumbled across a bug?

@ebourg
Copy link
Owner

ebourg commented Jan 22, 2025

Thank your for the report, that's indeed a bug. GoogleCloudSigningService assumes that a certificate file was provided, because this is enforced by KeyStoreType.GOOGLECLOUD.validate(). But the Jsign JCA provider used by jarsigner bypasses this validation, and jarsigner doesn't pass the certificate file to the signing service, so this leads to an exception when loading the certificate. I'll fix this.

That said, appending the algorithm is the best approach since it saves a call to the GCP API. This isn't well documented.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants