osslsigncode AWS CloudHSM PKCS#11 Support
Hi, I am currently trying to use the -pkcs11engine optoion and using the AWS CloudHSM PKCS#11 library. Currently, I am getting the following error:
osslsigncode sign \
-pkcs11engine /usr/lib/x86_64-linux-gnu/engines-3/cloudhsm.so \ -pkcs11module /opt/cloudhsm/lib/libcloudhsm_pkcs11.so \
-certs dev.crt \
-key 123 \
-n "TEST" \
-i http://timestamp.digicert.com \
-in db.exe \
-out db-signed.exe
Engine "cloudhsm" set.
Failed to set pkcs11 engine MODULE_PATH to '/opt/cloudhsm/lib/libcloudhsm_pkcs11.so'
Are there only a few supported PKCS#11 libraries? Thanks.
I'm confused with your configuration. If you're using a dedicated cloudhsm.so engine for OpenSSL then what's the reason of specifying a PKCS#11 module as a paramter? In seems perfectly normal that a dedicated cloudhsm.so engine does not support the pkcs11-specific MODULE_PATH control command. A PKCS#11 module would only be needed for a generic pkcs11.so engine.
Got it, I was just under the impression both needed to be specified. Here is where I am at now:
osslsigncode sign -pkcs11engine /usr/lib/x86_64-linux-gnu/engines-3/cloudhsm.so -certs cert.crt -key fake_pvt.pem -n "TEST" -i http://timestamp.digicert.com -in db.exe -out db.exe-signed
Engine "cloudhsm" set.
Failed to load private key fake_pvt.pem
Failed to read key or certificates
40FCFA0140000000:error:1300007D:engine routines:ENGINE_load_private_key:no load function:../crypto/engine/eng_pkey.c:74:
Failed
cloudhsm.so I believe is the pointer to AWS' OpenSSL Dynamic Engine. Generally, installing this engine would allow for such commands:
$ openssl s_server -cert server.crt -key server.key -engine cloudhsm
where server.key is not an actual key, but a "fake" key that is a reference to the real one.
The keys I have in this HSM are non-extractable, so when giving -key fake_pvt.pem above, its a "fake pvt key". I am not really sure where else I can proceed here, as I think this is my only option in using this tool since the other methods require actually having the private key on disk. Here are some additional information I can get regarding AWS' HSM:
/opt/cloudhsm/lib/libcloudhsm_openssl.so is the shared library for the AWS CloudHSM OpenSSL Dynamic Engine. This library enables OpenSSL to interface with AWS CloudHSM hardware security modules for cryptographic operations [1].
/opt/cloudhsm/lib/libcloudhsm_pkcs11.so is the PKCS #11 library for AWS CloudHSM. This library is part of the CloudHSM Client SDK and is installed when you set up the PKCS #11 library for AWS CloudHSM [2].
[1] https://docs.aws.amazon.com/cloudhsm/latest/userguide/openssl3-use-library.html [2] https://docs.aws.amazon.com/cloudhsm/latest/userguide/install-pkcs11-v3.html
Any other insights would be much appreciated!
How should cloudhsm know which key do you want to use? The documentation is thin on the details how to select the key. Maybe you can list the keys somehow (using cloudhsm CLI tool maybe) and figure out what is the right name for the key you are trying to use?
Example working parameters:
./osslsigncode sign
-pkcs11engine /var/task/pkcs11.so
-pkcs11module /var/task/libcloudhsm_pkcs11.so
-certs CLOUDHSM_CODE_CERT_FILE
-key pkcs11:token=hsm1;object=CLOUDHSM_PKCS_KEY_LABEL
-readpass CLOUDHSM_CREDS_FILE
-ts http://timestamp.digicert.com
-i https://www.example.com/
-n Named
-h sha256
-in file
-out outfile
libcloudhsm_pkcs11.so from cloudhsm-pkcs11-latest package pkcs11.so from compiling https://github.com/OpenSC/libp11 with a patch to force login, as CloudHSM can be weird and disconnect you if you try without login first.
You should be able to find your key label by using the CloudHSM CLI. If you haven't generated the actual cert file to use yet, you need to generate your CSR first. I made a comment about that in https://github.com/mtrojnar/osslsigncode/issues/106
@ZachNo thanks for the comment, definitely made some progress here:
osslsigncode sign
-pkcs11engine /usr/lib/x86_64-linux-gnu/engines-3/pkcs11.so
-pkcs11module /opt/cloudhsm/lib/libcloudhsm_pkcs11.so
-certs MY_CERT
-key "pkcs11:token=hsm1;object=MY_LABEL"
-readpass creds.txt
-ts http://timestamp.digicert.com
-i https://www.example.com/
-n "test" -h sha256
-in db.exe -out db.exe-signed
Engine "pkcs11" set.
Unable to enumerate private keys
Failed to checking the consistency of a private key: pkcs11:token=hsm1;object=MY_LABEL
with a public key in any X509 certificate: <MY CERT>
Creating a new signature failed
Unable to prepare new signature
40FCFA0140000000:error:05800074:x509 certificate routines:X509_check_private_key:key values mismatch:../crypto/x509/x509_cmp.c:408:
Failed
I am positive that the same key used to sign MY_CERT is the key corresponding to MY_LABEL. Does this have something to do with that patch you had to do for libp11? Are you able to please point me to what exactly I need to patch in libp11 to force the login?
Does the cert have to be a EV code signing cert (same as what I'd use in windows sign tool?). I am just using a plain old self-signed cert created via openssl.
Appreciate your assistance!
The Unable to enumerate private keys may be the login issue. It's CloudHSM's generic error for "we didn't get back data we wanted" I believe.
Seems like libp11 was refactored around since I made a patch, but I believe the current patch would be https://github.com/OpenSC/libp11/blob/7022a03077c73d63388a3ae52a429665d276e746/src/util_uri.c#L1120 change this line to if (0) { so that it always skips trying to load objects without first logging in.
Try to use the -login option to force login to the token.
Ah yeah, that commit (#389) is newer than when I was troubleshooting this process. Good to know.
@alecrevangelista, does using the -login option to force token login resolve the issue, so we can close it?