jsign icon indicating copy to clipboard operation
jsign copied to clipboard

Azure Trusted Signing: Explicitly specify Microsoft ACS Timestamp Server URL

Open jo-tools opened this issue 11 months ago • 2 comments

This command works: jsign --storetype TRUSTEDSIGNING --keystore ${ACS_ENDPOINT} --storepass ${AZURE_ACCESS_TOKEN} --alias ${ACS_ACCOUNT_NAME}/${ACS_CERTIFICATE_PROFILE_NAME} --replace "./**/*.exe"


When trying to explicitly specify the Microsoft ACS Timestamp Server with --tsaurl http://timestamp.acs.microsoft.com:

jsign --storetype TRUSTEDSIGNING --keystore ${ACS_ENDPOINT} --storepass ${AZURE_ACCESS_TOKEN} --alias ${ACS_ACCOUNT_NAME}/${ACS_CERTIFICATE_PROFILE_NAME} --tsaurl http://timestamp.acs.microsoft.com --replace "./**/*.exe"

This fails with error:

net.jsign.timestamp.TimestampingException: Unable to complete the timestamping after 3 attempts
	at net.jsign.timestamp.Timestamper.timestamp(Timestamper.java:134)
	at net.jsign.AuthenticodeSigner.createSignedData(AuthenticodeSigner.java:416)
	at net.jsign.AuthenticodeSigner.sign(AuthenticodeSigner.java:370)
	at net.jsign.SignerHelper.sign(SignerHelper.java:454)
	at net.jsign.SignerHelper.execute(SignerHelper.java:305)
	at net.jsign.JsignCLI.execute(JsignCLI.java:221)
	at net.jsign.JsignCLI.main(JsignCLI.java:57)
	Suppressed: net.jsign.timestamp.TimestampingException: Unable to complete the timestamping
		at net.jsign.timestamp.AuthenticodeTimestamper.timestamp(AuthenticodeTimestamper.java:59)
		at net.jsign.timestamp.Timestamper.timestamp(Timestamper.java:150)
		... 6 more
	Caused by: net.jsign.bouncycastle.cms.CMSException: Malformed content.
		at net.jsign.bouncycastle.cms.CMSUtils.readContentInfo(Unknown Source)
		at net.jsign.bouncycastle.cms.CMSUtils.readContentInfo(Unknown Source)
		at net.jsign.bouncycastle.cms.CMSSignedData.<init>(Unknown Source)
		at net.jsign.timestamp.AuthenticodeTimestamper.timestamp(AuthenticodeTimestamper.java:57)
		... 7 more
	Caused by: java.lang.ClassCastException: class net.jsign.bouncycastle.asn1.DLSequence cannot be cast to class net.jsign.bouncycastle.asn1.ASN1ObjectIdentifier (net.jsign.bouncycastle.asn1.DLSequence and net.jsign.bouncycastle.asn1.ASN1ObjectIdentifier are in unnamed module of loader 'app')
		at net.jsign.bouncycastle.asn1.cms.ContentInfo.<init>(Unknown Source)
		at net.jsign.bouncycastle.asn1.cms.ContentInfo.getInstance(Unknown Source)
		... 11 more
	Suppressed: net.jsign.timestamp.TimestampingException: Unable to complete the timestamping
		at net.jsign.timestamp.AuthenticodeTimestamper.timestamp(AuthenticodeTimestamper.java:59)
		at net.jsign.timestamp.Timestamper.timestamp(Timestamper.java:150)
		... 6 more
	Caused by: net.jsign.bouncycastle.cms.CMSException: Malformed content.
		at net.jsign.bouncycastle.cms.CMSUtils.readContentInfo(Unknown Source)
		at net.jsign.bouncycastle.cms.CMSUtils.readContentInfo(Unknown Source)
		at net.jsign.bouncycastle.cms.CMSSignedData.<init>(Unknown Source)
		at net.jsign.timestamp.AuthenticodeTimestamper.timestamp(AuthenticodeTimestamper.java:57)
		... 7 more
	Caused by: java.lang.ClassCastException: class net.jsign.bouncycastle.asn1.DLSequence cannot be cast to class net.jsign.bouncycastle.asn1.ASN1ObjectIdentifier (net.jsign.bouncycastle.asn1.DLSequence and net.jsign.bouncycastle.asn1.ASN1ObjectIdentifier are in unnamed module of loader 'app')
		at net.jsign.bouncycastle.asn1.cms.ContentInfo.<init>(Unknown Source)
		at net.jsign.bouncycastle.asn1.cms.ContentInfo.getInstance(Unknown Source)
		... 11 more
	Suppressed: net.jsign.timestamp.TimestampingException: Unable to complete the timestamping
		at net.jsign.timestamp.AuthenticodeTimestamper.timestamp(AuthenticodeTimestamper.java:59)
		at net.jsign.timestamp.Timestamper.timestamp(Timestamper.java:150)
		... 6 more
	Caused by: net.jsign.bouncycastle.cms.CMSException: Malformed content.
		at net.jsign.bouncycastle.cms.CMSUtils.readContentInfo(Unknown Source)
		at net.jsign.bouncycastle.cms.CMSUtils.readContentInfo(Unknown Source)
		at net.jsign.bouncycastle.cms.CMSSignedData.<init>(Unknown Source)
		at net.jsign.timestamp.AuthenticodeTimestamper.timestamp(AuthenticodeTimestamper.java:57)
		... 7 more
	Caused by: java.lang.ClassCastException: class net.jsign.bouncycastle.asn1.DLSequence cannot be cast to class net.jsign.bouncycastle.asn1.ASN1ObjectIdentifier (net.jsign.bouncycastle.asn1.DLSequence and net.jsign.bouncycastle.asn1.ASN1ObjectIdentifier are in unnamed module of loader 'app')
		at net.jsign.bouncycastle.asn1.cms.ContentInfo.<init>(Unknown Source)
		at net.jsign.bouncycastle.asn1.cms.ContentInfo.getInstance(Unknown Source)
		... 11 more
Try `jsign --help' for more information.

The same error with both --tsaurl http://timestamp.acs.microsoft.com and --tsmode Authenticode:

jsign --storetype TRUSTEDSIGNING --keystore ${ACS_ENDPOINT} --storepass ${AZURE_ACCESS_TOKEN} --alias ${ACS_ACCOUNT_NAME}/${ACS_CERTIFICATE_PROFILE_NAME} --tsaurl http://timestamp.acs.microsoft.com --tsmode Authenticode --replace "./**/*.exe"


However, success with both --tsaurl http://timestamp.acs.microsoft.com and --tsmode RFC3161 :

jsign --storetype TRUSTEDSIGNING --keystore ${ACS_ENDPOINT} --storepass ${AZURE_ACCESS_TOKEN} --alias ${ACS_ACCOUNT_NAME}/${ACS_CERTIFICATE_PROFILE_NAME} --tsaurl http://timestamp.acs.microsoft.com --tsmode RFC3161 --replace "./**/*.exe"


Why do we get an error when

  • adding --tsaurl http://timestamp.acs.microsoft.com
  • adding --tsaurl http://timestamp.acs.microsoft.com and --tsmode Authenticode

Is this expected and "by design"?

jo-tools avatar Mar 06 '25 21:03 jo-tools

The tsmode defaults to Authenticode but http://timestamp.acs.microsoft.com supports only RFC3161. That's why tsaurl alone or tsaurl with tsmode Authenticode fail.

That said, with --storetype TRUSTEDSIGNING you can simply remove the timestamping options because it's enabled automatically (using the same Microsoft endpoint).

A potential improvement would be to keep a list of known endpoints with the supported protocols and let Jsign select the right one automatically. Another idea would be to switch the protocol on the next try following a server error.

ebourg avatar Mar 06 '25 23:03 ebourg

Thank you for the response.


tsmode defaults to Authenticode

This should be added to the Documentation.

-m,--tsmode <MODE> The timestamping mode (RFC3161 or Authenticode), default: Authenticode


Another idea would be to switch the protocol on the next try following a server error.

I would suggest: ONLY if --tsmode has NOT been explicitly set then

  • default to Authenticode
  • incase of a Timestamp Server not supporting this mode, automatically try the other mode as well
    • ...and maybe cache this information in a local preference...

A potential improvement would be to keep a list of known endpoints with the supported protocols and let Jsign select the right one automatically.

Certainly would be nice to have. However, in order not needing to update jsign when the Timestamp Servers change their supported protocols I think the above would be good enough.

Should you consider a default mode for selected Timestamp Servers, then add this information/list to the Documentation, too. That would change the current behavior (a default mode if not specified).

jo-tools avatar Mar 07 '25 17:03 jo-tools