Microsoft's C# Code to Sign HLKX via an HSM

I won’t rehash everything here; for background on EV signing SYSDEV submissions, see this thread:
https://www.osronline.com/showthread.cfm?link=278314

I don’t have my head in kernel drivers all the time, it’s something I come back to when there’s some anomaly to investigate or on the rare occasions when some new feature is needed. These drivers are for special-purpose equipment and don’t release with Windows. They’ve never been submitted to SYSDEV before, so I ended up learning about new Windows 10 signing requirements quite late, when build 1607 Secure Boot machines started being deployed.

HCK and HLK tests have passed, so I’m now trying to sign the combined HLKX package with my employer’s EV certificate, which is installed on a Safenet Luna HSM. The HLK controller doesn’t have a trust relationship with the HSM, isn’t on its domain, and is, in fact, on its own little network. And of course signtool.exe hasn’t been updated to support the package format used for HLKX, because that’d be too easy.

Instead, Microsoft makes some C# source available to supposedly help developers in this situation:
https://docs.microsoft.com/en-us/windows-hardware/test/hlk/user/hlk-signing-with-an-hsm

On StackOverflow someone even had some success using this:
https://stackoverflow.com/questions/35732109/can-i-sign-hlkx-file-manually-using-ev-certificate-to-submit-on-the-microsoft-w

I’ve tried this on a remote machine that has a trust relationship with the HSM and can successfully sign an EXE with the EV certificate via signtool, but get a “signing key is not loaded” exception when PackageDigitalSignatureManager.Sign is called — I’m guessing because the certificate actually installed on that machine contains only the public key. The private key never leaves the HSM appliance.

So what can be done to this code to tell it how to do the signing with the private key in the HSM? Signtool knows how to do such a thing, but I do not.

I’ve tried two approaches at the following link, but so far have received an “access denied” error from the first approach (even running as admin) and a “keyset is not defined” exception from the second. Here’s the link:
https://forums.asp.net/t/1531893.aspx?How+can+you+add+CSP+information+to+an+X509+certificate+programmatically

I know this is a weird crypto-related issue in C# I’m putting before an audience more comfortable with IRQLs and such, but given the context I thought perhaps someone here had already been through this and lived to tell the story.

It’s looking like I may have to create a Server 2016 VM on the domain, establish trust with the HSM, install the HLK controller, and import/sign the packages from there — assuming that the HLK controller will know how to work with the HSM.

I know Microsoft had good intentions with this EV signing, but I don’t think they’ve thought this through very well. The HLK controller typically lives in a world well removed from EV certificates. Microsoft might well consider grafting their own code sample into signtool.exe to save everyone a lot of grief.

Thanks for your patience and advice,
Dave

Turns out I was very close to a working solution. Where I was getting the “keyset is not defined” error, it was because I was building for 32-bit but the CSP (cryptographic service provider) on the machine was 64-bit, so it wasn’t loading up. Once I rebuilt for 64-bits it signed the package without any fuss.

What I have owes a lot to the URLs in my original post, but I’ll see if I can clean up what I have and share it here for the next guy. Thanks to anyone who endured the pain of reading my message, this signing stuff isn’t a great deal of fun!

Dave

Please do