ebourg / jsign

Java implementation of Microsoft Authenticode for signing Windows executables, installers & scripts

Home Page:https://ebourg.github.io/jsign

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Business Central App support

dantheperson opened this issue · comments

Hello,

I am trying to sign a Microsoft Business Central App prior to uploading the AppSource.

However i get the error jsign: Unsupported file:

Does the tool support the MS App format?

https://learn.microsoft.com/en-us/dynamics365/business-central/dev-itpro/developer/devenv-sign-extension

That's the first time I hear about this format, thank you for bringing this to my attention. Jsign doesn't support it but I can investigate if it could be implemented. Do you know where I could download a signed app file?

I could provide a copy of our signed app

Some details about the file format that may be useful:
https://www.linkedin.com/pulse/business-central-runtime-packages-gregor-alujevic

We currently use the DigiCert Windows Utility, but looking for something that support Google KMS

Thank you for the link. It looks like the name of the format is actually NAVX. Could you send a test file, signed and unsigned, to ebourg@apache.org? I'll get a look.

I've found a signed NAVX file linked to this StackOverflow question: https://stackoverflow.com/questions/63439023

Here are my first observations:

  • This is a ZIP file with a 40 byte header starting and ending with NAVX
  • The size of the file (unsigned and without the header) is located at the offset 28 of the header (on at least 4 bytes, maybe 8 since the following 4 bytes are all zero)
  • The signature is directly appended at the end of the zip file. It is prefixed and suffixed by the string NXSB (which probably stands for NAVX Signature Block)
  • The SpcSipInfo structure in the signature has the version 1 and the UUID is C8EAD600-FC04-0000-5828-F30400000000
  • The content hashed in the signature is simply the full file, with the header included

Signing NAVX files looks really simple, I should be able to implement it but I'll need some help for the tests:

  • I need a simple test file, such as an empty .app file
  • signtool can't verify signed NAVX files unless Microsoft Dynamics 365 is installed, and I don't have a license for that application. So someone else will have to confirm the signature generated by Jsign is correct.

A few things to check:

  • Is the header modified when the file is signed? There might be a flag indicating that the file is signed
  • If the file can be signed multiple times, is there only one NXSB block?

@dantheperson I've pushed an initial implementation on the navx branch, could you give it a try please?

Ok i'm getting this error:

root@instance-1:~# java -jar /mnt/c/certificate/dan/jsign-5.1-SNAPSHOT.jar --storetype GOOGLECLOUD --storepass $(gcloud auth application-default print-access-token) --keystore projects/xm-cloudbuild/locations/us/keyRings/build-ring --alias bc-connector-sign-1 --certfile /mnt/c/certificate/hsm-cert/commercebuild_holdings_inc.p7b /mnt/c/certificate/commercebuild_commercebuild\ B2B\ \&\ B2C\ eCommerce_1.1.0.29.app
Adding Authenticode signature to /mnt/c/certificate/commercebuild_commercebuild B2B & B2C eCommerce_1.1.0.29.app
jsign: Couldn't sign /mnt/c/certificate/commercebuild_commercebuild B2B & B2C eCommerce_1.1.0.29.app
java.security.SignatureException: Signature verification failed, the private key doesn't match the certificate
        at net.jsign.AuthenticodeSigner.verify(AuthenticodeSigner.java:492)
        at net.jsign.AuthenticodeSigner.createSignedData(AuthenticodeSigner.java:376)
        at net.jsign.AuthenticodeSigner.sign(AuthenticodeSigner.java:348)
        at net.jsign.SignerHelper.sign(SignerHelper.java:394)
        at net.jsign.JsignCLI.execute(JsignCLI.java:132)
        at net.jsign.JsignCLI.main(JsignCLI.java:40)
Try `java -jar jsign.jar --help' for more information.

I'm gonna to and create a self-signed certificate to rule out the private key issue being genuine. This is the first time attempting to use a cert generated with a google KMS HMS private key.

Also, are there any algorithm limitations in your Google KMS support?

I notice the example Goggle give is using their favoured ec-sign-p256-sha256, while my private key is RSA_SIGN_PKCS1_4096_SHA256
https://cloud.google.com/kms/docs/reference/pkcs11-jsign
This difference has blocked me using SignTool.exe with their Windows CNG provider as it only supports that one EC Algo.

With a self-signed cert the command completes successfully, and the file is updated, but i don't see the signature details in the windows GUI, no 'Digital Signatures' tab, maybe that is normal for self signed certs?
image

Signature verification failed, the private key doesn't match the certificate

This means the public key in the certificate isn't the right one for the private key in Google KMS.

Also, are there any algorithm limitations in your Google KMS support?

The only limitation I'm aware of is related to the key padding. Usually PSS doesn't work, PKCS#1 v1.5 should be used instead

Also with the self signed cert, SignTool verfiy doesn't recognise the Signature. v1.1.0.28 is signed with our previous cert using the DigiCert Util, and v1.1.0.29 signed with the self-signed cert using jsign.

C:\certificate>SignTool.exe verify "commercebuild_commercebuild B2B & B2C eCommerce_1.1.0.28.app"
File: commercebuild_commercebuild B2B & B2C eCommerce_1.1.0.28.app
Index  Algorithm  Timestamp
========================================
SignTool Error: A certificate chain processed, but terminated in a root
        certificate which is not trusted by the trust provider.

Number of errors: 1

C:\certificate>SignTool.exe verify "commercebuild_commercebuild B2B & B2C eCommerce_1.1.0.29.app"
File: commercebuild_commercebuild B2B & B2C eCommerce_1.1.0.29.app
Index  Algorithm  Timestamp
========================================
SignTool Error: No signature found.

Number of errors: 1

I don't see the signature details in the windows GUI, no 'Digital Signatures' tab, maybe that is normal for self signed certs?

No unfortunately it doesn't work. I've been able to install the demo version of Microsoft Dynamics NAV 2018 from here and I have the same result with my test file.

But now I can use signtool and inspect the signatures generated. One thing I've noticed so far is the SpcSipInfo UUID which changes for every file, that's really unsual. Even the same file signed twice can get a different UUID, I wonder if the value is random.

Regarding the private key not matching, Jsign is correct there, I have confirmed using
openssl x509 -in /mnt/c/certificate/hsm-cert/standalone.pem -pubkey -noout
vs
gcloud kms keys versions get-public-key

DigiCert have reissued the cert against the old private key and not against the new CSR i supplied.

I've figured out the isssue, the signature block also contains an offset on 4 bytes. Now the Digital Signatures tab shows up in the file properties, and the signature is valid on the test file. Could you give it another try?

Legend!
it's working with my self-signed cert.
Now i just need to wait to get my cert reissued by the CA, hopefully they don't stuff up the reissue this time.

Did you understand the requirement around having business central installed on the machine? I didn't follow why signing a binary requires BC installed, I am guessing this somehow extends SignTool to support BusinessCentral NAV Apps? The more pertinent question is, will this be a requirement of JSign? I'd like to produce a docker image with Jsign that can automate our signing process, at the moment it's all very manual.

I will get back to you with progress and let you know if the signed app gets accepted by the MS AppSource verification, that's the true test, if we can get our binary into the app store.

To partially answer my own question. Seems MS Authenticode has an extensible FileFormat API called Subject Interface Packages. No doubt installing business central on windows installs the NAV SIP.
https://specterops.io/wp-content/uploads/sites/3/2022/06/SpecterOps_Subverting_Trust_in_Windows.pdf

Indeed, Microsoft Dynamics NAV registers its own SIP implementation (NavSip.dll) when installed. Jsign doesn't need it of course.

Finally got our cert reissued against the Google KMS HMS key last night. Can confirm the Business Central/NAV support is all good, Jsigned app was accepted into Microsoft AppSource.
Thank you very much for adding support.

Great! Thank you for the feedback.