I was able to cobble together a solution using nsscapi.dll compiled from a nss-3.13.6 build. I then copied the additional library dependencies to my nss-3.20 build for use in my overall applicaiton.
nsscapi.dll for the purpose of signing a piece of code, is a rudimentary PKCS11 to Capi module interface for NSS. It apparently has memory leak problems, but since the scope of my use of NSS is to simply sign an XPI file occasionally, I am ok with restarting that module occasionally.
The solution involves:
nss-3.20 built out using mozilla-build, and "make nss_build_all" from within the "nss" subfolder of this package.
Visual Studio C++ Redistributable 2015 x86 version (32bit as 64bit doesn't work for this project).
Thales CAPI interface to windows (yes they have a direct PKCS11 module, but for my customized environment only CAPI and Java keystore are options so I didn't use the Thales PKCS11 module)
The PATH environment variable was modified to point to the bin and lib folders within the NSS build.
nsscapi.dll located in the nss-3.20\dist\WIN95xxx\lib\ folder was loaded into the NSS build using "modutil":
modutil -dbdir "c:\apps\certs" -add "capi" -libfile "C:\Apps\nss-3.20\dist\WIN954.0_DBG.OBJ\lib\nsscapi.dll" -mechanisms RSA:DSA:RC2:RANDOM
I already had Thales configured to populate code signing certificates to CAPI so I had code signing certs in CAPI already.
I had to use the "certificates" snap in, in mmc.exe to view the current user "Personal" certificate store. Then modify the "friendly" name of the code signing certificate I want to use to something meaningfull like "test". This is so that the NSSCAPI module can identify that certificate uniquely in the list that is has visibility to.
After that step of changing the friendly name on one of my test code signing certificates, I used the NSS signtool to display the list of available certificates:
signtool -d "c:\apps\certs" -L
I unzipped a "test.xpi" file into the "test" subfolder of "c:\apps\certs" which is a sub folder name I just made up, you can use what you want.
My list contained an entry:
- Microsoft Certificate Store:test
the * denotes it is a valid cert that can be used for codesigning in NSS
I then used signtool to sign the code in my test XPI file:
signtool -d "C:\Users\mlawson\AppData\Roaming\Mozilla\Firefox\Profiles\4jnnnb1y.default" -k "Microsoft Certificate Store":"test" test/
With success!
I apologize in advance if my formatting of this answer is off. This is my first time both posting to stack overflow, and answering a post (even if it was my own). I glossed over some of the high level steps in this post to keep it brief as some of the bigger "how to" do things like building NSS, are documented on Mozilla's site already. Thales related configurations are documented by Thales, not relevant to explain how that is configured as my use case for their CAPI interface is custom and proprietary. But the overall concept of using nsscapi.dll and this solution, applies really to anything that ties into MSCAPI and being able to use that with NSS is handy. The nsscapi.dll can also be loaded into firefox "security devices" as a module so that firefox can use CAPI as well, though I don't know how well exactly...