ebourg / jsign

Java implementation of Microsoft Authenticode for signing Windows executables, installers & scripts
https://ebourg.github.io/jsign
Apache License 2.0
250 stars 107 forks source link

Business Central App support #167

Closed dantheperson closed 10 months ago

dantheperson commented 11 months ago

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

ebourg commented 11 months ago

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?

dantheperson commented 11 months ago

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

ebourg commented 10 months ago

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.

ebourg commented 10 months ago

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

Here are my first observations:

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

ebourg commented 10 months ago

A few things to check:

ebourg commented 10 months ago

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

dantheperson commented 10 months ago

Omg, thanks so much, I will try that on Monday at the latest, middle of the weekend here at the mo.

On Sat, 5 Aug 2023, 11:56 Emmanuel Bourg, @.***> wrote:

@dantheperson https://github.com/dantheperson I've pushed an initial implementation on the navx branch https://github.com/ebourg/jsign/tree/navx, could you give it a try please?

— Reply to this email directly, view it on GitHub https://github.com/ebourg/jsign/issues/167#issuecomment-1666288422, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABGIY6YLBTN7C7S2SM53YADXTWD2VANCNFSM6AAAAAA3DVGVCM . You are receiving this because you were mentioned.Message ID: @.***>

dantheperson commented 10 months ago

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.

dantheperson commented 10 months ago

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

ebourg commented 10 months ago

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

dantheperson commented 10 months ago

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
ebourg commented 10 months ago

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.

dantheperson commented 10 months ago

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.

ebourg commented 10 months ago

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?

dantheperson commented 10 months ago

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.

dantheperson commented 10 months ago

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

ebourg commented 10 months ago

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

dantheperson commented 10 months ago

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.

ebourg commented 10 months ago

Great! Thank you for the feedback.