Nitrokey HSM2 in Windows

Hi, I can connect to Nitrokey HSM2 using OpenSC Tools, but I cannot connect to it from XCA. I installed both in 64 bits, I successfully added PKCS#11 Provider: “C:\Program Files (x86)\OpenSC Project\OpenSC\pkcs11\opensc-pkcs11.dll” but when I press on Token → Manage Security Tokens, I receive the following error: No security token found.
I also tried to connect to Nitrokey HSM2 from openssl:
openssl -engine dynamic -pre ID:pkcs11 -pre SO_PATH:“C:\Program Files\OpenSC Project\OpenSC\pkcs11\opensc-pkcs11.dll” -pre LIST_ADD:1 -pre LOAD -pre MODULE_PATH:“C:\Program Files\OpenSC Project\OpenSC\pkcs11\opensc-pkcs11.dll”
Invalid command ‘-engine’; type “help” for a list.
So how could I create self-signed certificate in Windows using Nitrokey HSM2?

Note the “x86” part. That seems to be 32-bit. Maybe it won’t work with other parts being 64-bit?

1 Like

I tried also “C:\Program Files\OpenSC Project\OpenSC’\pkcs11\opensc-pkcs11.dll”, it doesn’t work either. I tried when both - openssl and OpenSC projects are 32 bits, and openssl, OpenSC - 64 bits, it doesn’t work

I think you forgot a command here. This is usually something without a hyphen…

yes, typo, the command is: openssl engine dynamic -pre ID:pkcs11 -pre SO_PATH:“C:\Program Files\OpenSC Project\OpenSC\pkcs11\opensc-pkcs11.dll” -pre LIST_ADD:1 -pre LOAD -pre MODULE_PATH:“C:\Program Files\OpenSC Project\OpenSC\pkcs11\opensc-pkcs11.dll” but it really doesn’t matter, the only way I succeeded to create a certificate is in Linux!

a few things to try:

which openssl version and do you run it in a cmd.exe, powershell or cygwin?

what is the error message?

what happens when the dll is in the same directory?

smart card shell sees the HSM?

openssl version 3.2.0, run in cmd.exe. dll is in PATH, smart card shell of course connects to HSM.

I usually use it in Linux but tried this on my NitroHSM with Windows 10. Does this match your setup / error messages you experience?

System

  • Win10 latest patches
  • scsh3.17.610 → Initialized blank device with default keys, public key or pin auth, 4 key domains, default PINs (reset for this test)
  • installed sc-hsm-middleware-x64-2.12.msi (was already installed)
  • installed OpenSC-0.22.0_win64.msi (was already installed)
  • installed precompiled binary of OpenSSL from Win32/Win64 OpenSSL Installer for Windows - Shining Light Productions

Command outputs

C:\Program Files\OpenSC Project\OpenSC\tools>opensc-tool.exe -l
# Detected readers (pcsc)
Nr.  Card  Features  Name
0    Yes             Nitrokey Nitrokey HSM 0


"C:\Program Files\OpenSSL-Win64\bin\openssl.exe" --version
OpenSSL 3.2.0 23 Nov 2023 (Library: OpenSSL 3.2.0 23 Nov 2023)


dir "C:\Program Files\OpenSC Project\OpenSC\pkcs11\opensc-pkcs11.dll"
 Volume in drive C is Windows
 Volume Serial Number is D462-71C6

 Directory of C:\Program Files\OpenSC Project\OpenSC\pkcs11

08/10/2021  10:04 AM         3,872,256 opensc-pkcs11.dll
               1 File(s)      3,872,256 bytes
               0 Dir(s)  50,741,764,096 bytes free


"C:\Program Files\OpenSSL-Win64\bin\openssl.exe" engine dynamic -pre ID:pkcs11 -pre SO_PATH:"C:\Program Files\OpenSC Project\OpenSC\pkcs11\opensc-pkcs11.dll" -pre LIST_ADD:1 -pre LOAD -pre MODULE_PATH:"C:\Program Files\OpenSC Project\OpenSC\pkcs11\opensc-pkcs11.dll" -pre LIST_DEVICES
(dynamic) Dynamic engine loading support
[Success]: ID:pkcs11
[Success]: SO_PATH:C:\Program Files\OpenSC Project\OpenSC\pkcs11\opensc-pkcs11.dll
[Success]: LIST_ADD:1
[Failure]: LOAD
1C550000:error:1280006A:DSO support routines:win32_bind_func:could not bind to the requested symbol name:crypto\dso\dso_win32.c:182:symname(bind_engine)
1C550000:error:1280006A:DSO support routines:DSO_bind_func:could not bind to the requested symbol name:crypto\dso\dso_lib.c:171:
1C550000:error:13000068:engine routines:dynamic_load:DSO failure:crypto\engine\eng_dyn.c:451:
[Failure]: MODULE_PATH:C:\Program Files\OpenSC Project\OpenSC\pkcs11\opensc-pkcs11.dll
1C550000:error:13000089:engine routines:int_ctrl_helper:invalid cmd name:crypto\engine\eng_ctrl.c:90:
1C550000:error:13000089:engine routines:ENGINE_ctrl_cmd_string:invalid cmd name:crypto\engine\eng_ctrl.c:253:
[Failure]: LIST_DEVICES
1C550000:error:13000089:engine routines:int_ctrl_helper:invalid cmd name:crypto\engine\eng_ctrl.c:90:
1C550000:error:13000089:engine routines:ENGINE_ctrl_cmd_string:invalid cmd name:crypto\engine\eng_ctrl.c:253:



systeminfo | findstr /B /C:"OS Name" /C:"OS Version"
OS Name:                   Microsoft Windows 10 Pro
OS Version:                10.0.19045 N/A Build 19045



C:\Users\rottmrei>"C:\Program Files\OpenSSL-Win64\bin\openssl.exe" engine dynamic -pre ID:pkcs11 -pre SO_PATH:"C:\Windows\System32\sc-hsm-pkcs11.dll" -pre LIST_ADD:1 -pre LOAD -pre MODULE_PATH:"C:\Windows\System32\sc-hsm-pkcs11.dll" -pre LIST_DEVICES
(dynamic) Dynamic engine loading support
[Success]: ID:pkcs11
[Success]: SO_PATH:C:\Windows\System32\sc-hsm-pkcs11.dll
[Success]: LIST_ADD:1
[Failure]: LOAD
701F0000:error:1280006A:DSO support routines:win32_bind_func:could not bind to the requested symbol name:crypto\dso\dso_win32.c:182:symname(bind_engine)
701F0000:error:1280006A:DSO support routines:DSO_bind_func:could not bind to the requested symbol name:crypto\dso\dso_lib.c:171:
701F0000:error:13000068:engine routines:dynamic_load:DSO failure:crypto\engine\eng_dyn.c:451:
[Failure]: MODULE_PATH:C:\Windows\System32\sc-hsm-pkcs11.dll
701F0000:error:13000089:engine routines:int_ctrl_helper:invalid cmd name:crypto\engine\eng_ctrl.c:90:
701F0000:error:13000089:engine routines:ENGINE_ctrl_cmd_string:invalid cmd name:crypto\engine\eng_ctrl.c:253:
[Failure]: LIST_DEVICES
701F0000:error:13000089:engine routines:int_ctrl_helper:invalid cmd name:crypto\engine\eng_ctrl.c:90:
701F0000:error:13000089:engine routines:ENGINE_ctrl_cmd_string:invalid cmd name:crypto\engine\eng_ctrl.c:253:

I also tried the openssl commands with both pkcs11 dlls in an Administrator shell.

To my understanding, this should list the available devices.

I tested this also with a blank Debian:

  • debian 12
  • latest git version of sc-hsm-embedded
  • openssl from repo
$ openssl engine dynamic -pre ID:pkcs11 -pre SO_PATH:/usr/local/lib/libsc-hsm-pkcs11.so -pre LIST_ADD:1 -pre LOAD -pre MODULE_PATH:/usr/local/lib/libsc-hsm-pkcs11.so -pre LIST_DEVICES
(dynamic) Dynamic engine loading support
[Success]: ID:pkcs11
[Success]: SO_PATH:/usr/local/lib/libsc-hsm-pkcs11.so
[Success]: LIST_ADD:1
[Failure]: LOAD
40D71BFFFF7E0000:error:1280006A:DSO support routines:dlfcn_bind_func:could not bind to the requested symbol name:../crypto/dso/dso_dlfcn.c:188:symname(bind_engine): /usr/local/lib/libsc-hsm-pkcs11.so: undefined symbol: bind_engine
40D71BFFFF7E0000:error:1280006A:DSO support routines:DSO_bind_func:could not bind to the requested symbol name:../crypto/dso/dso_lib.c:176:
40D71BFFFF7E0000:error:13000068:engine routines:dynamic_load:DSO failure:../crypto/engine/eng_dyn.c:455:
[Failure]: MODULE_PATH:/usr/local/lib/libsc-hsm-pkcs11.so
40D71BFFFF7E0000:error:13000089:engine routines:int_ctrl_helper:invalid cmd name:../crypto/engine/eng_ctrl.c:90:
40D71BFFFF7E0000:error:13000089:engine routines:ENGINE_ctrl_cmd_string:invalid cmd name:../crypto/engine/eng_ctrl.c:258:
[Failure]: LIST_DEVICES
40D71BFFFF7E0000:error:13000089:engine routines:int_ctrl_helper:invalid cmd name:../crypto/engine/eng_ctrl.c:90:
40D71BFFFF7E0000:error:13000089:engine routines:ENGINE_ctrl_cmd_string:invalid cmd name:../crypto/engine/eng_ctrl.c:258:



dpkg -l openssl
Desired=Unknown/Install/Remove/Purge/Hold
| Status=Not/Inst/Conf-files/Unpacked/halF-conf/Half-inst/trig-aWait/Trig-pend
|/ Err?=(none)/Reinst-required (Status,Err: uppercase=bad)
||/ Name           Version          Architecture Description
+++-==============-================-============-====================================================
ii  openssl        3.0.11-1~deb12u2 amd64        Secure Sockets Layer toolkit - cryptographic utility

Here are some basic tests:

t=`mktemp -d`
cat > $t/openssl.cnf <<"eof"
HOME                    = .
openssl_conf = openssl_init
config_diagnostics = 1
oid_section = new_oids
[ new_oids ]
tsa_policy1 = 1.2.3.4.1
tsa_policy2 = 1.2.3.4.5.6
tsa_policy3 = 1.2.3.4.5.7
[openssl_init]
[ ca ]
[ CA_default ]
policy          = policy_match
[ policy_match ]
countryName             = match
stateOrProvinceName     = match
organizationName        = match
organizationalUnitName  = optional
commonName              = supplied
emailAddress            = optional
[ policy_anything ]
countryName             = optional
stateOrProvinceName     = optional
localityName            = optional
organizationName        = optional
organizationalUnitName  = optional
commonName              = supplied
emailAddress            = optional
[ req ]
default_bits            = 2048
default_keyfile         = privkey.pem
distinguished_name      = req_distinguished_name
attributes              = req_attributes
string_mask = utf8only
[ req_distinguished_name ]
countryName                     = Country Name (2 letter code)
countryName_default             = AU
countryName_min                 = 2
countryName_max                 = 2
stateOrProvinceName             = State or Province Name (full name)
stateOrProvinceName_default     = Some-State
localityName                    = Locality Name (eg, city)
0.organizationName              = Organization Name (eg, company)
0.organizationName_default      = Internet Widgits Pty Ltd
organizationalUnitName          = Organizational Unit Name (eg, section)
commonName                      = Common Name (e.g. server FQDN or YOUR name)
commonName_max                  = 64
emailAddress                    = Email Address
emailAddress_max                = 64
[ req_attributes ]
challengePassword               = A challenge password
challengePassword_min           = 4
challengePassword_max           = 20
unstructuredName                = An optional company name
[ usr_cert ]
basicConstraints=CA:FALSE
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid,issuer
[ v3_req ]
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
[ v3_ca ]
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid:always,issuer
basicConstraints = critical,CA:true
[ crl_ext ]
authorityKeyIdentifier=keyid:always
[ proxy_cert_ext ]
basicConstraints=CA:FALSE
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid,issuer
proxyCertInfo=critical,language:id-ppl-anyLanguage,pathlen:3,policy:foo
[ tsa ]
[ tsa_config1 ]
server = pki.certificate.fi:8700
path = pkix/
extracertsout = insta.extracerts.pem
subject = "/CN=openssl-cmp-test"
newkey = insta.priv.pem
certout = insta.cert.pem
[ir]
cmd = ir
[cr]
cmd = cr
[kur]
cmd = kur
[rr]
cmd = rr
[openssl_init]
engines=engine_section
[engine_section]
pkcs11 = pkcs11_section
[pkcs11_section]
engine_id = pkcs11
dynamic_path = /usr/local/lib/libsc-hsm-pkcs11.so
MODULE_PATH = libsc-hsm-pkcs11.so
init = 0
eof
export OPENSSL_CONF=$t/openssl.cnf


openssl engine pkcs11 -t
FATAL: Startup failure (dev note: apps_startup()) for openssl
40D75790937F0000:error:1280006A:DSO support routines:dlfcn_bind_func:could not bind to the requested symbol name:../crypto/dso/dso_dlfcn.c:188:symname(bind_engine): /usr/local/lib/libsc-hsm-pkcs11.so: undefined symbol: bind_engine
40D75790937F0000:error:1280006A:DSO support routines:DSO_bind_func:could not bind to the requested symbol name:../crypto/dso/dso_lib.c:176:
40D75790937F0000:error:13000068:engine routines:dynamic_load:DSO failure:../crypto/engine/eng_dyn.c:455:
40D75790937F0000:error:13000066:engine routines:int_engine_configure:engine configuration error:../crypto/engine/eng_cnf.c:139:section=pkcs11_section, name=dynamic_path, value=/usr/local/lib/libsc-hsm-pkcs11.so
40D75790937F0000:error:0700006D:configuration file routines:module_run:module initialization error:../crypto/conf/conf_mod.c:276:module=engines, value=engine_section retcode=-1



$ pkcs11-tool --module /usr/local/lib/libsc-hsm-pkcs11.so --list-slots
Available slots:
Slot 0 (0x1): Nitrokey Nitrokey HSM (DENK0***0         ) 00 00
  token label        : dev
  token manufacturer : CardContact (www.cardcontact.de)
  token model        : SmartCard-HSM
  token flags        : login required, rng, token initialized, PIN initialized
  hardware version   : 5.0
  firmware version   : 3.4
  serial num         : **0
  pin min/max        : 6/16

@sc-hsm is this supposed to work with openssl like that?

Thank you very much for your investigation, I received the same kind of errors, so I just opened VirtualBox with Ubuntu 20.04 and created certificate there. IMHO, it is really strange that the product which has to work in Windows, doesn’t have full driver support for all operations.

I’m not using Windows, but the error message implies, that OpenSSL tries to load a DLL with the OpenSSL-Engine Interface. That is usually provided by libp11.

libp11 will then load the PKCS#11 DLL for the token at hand. So you have to have OpenSSL and libp11 installed on the Windows machine.

Yes, I downloaded libp11 (32 and 64 bits) and copied it into directory of OpenSC\pkcs-11 but it didn’t help. I have Windows 10 64 bits.

But then you need to specify the DLL of the engine-pkcs11 in SO_PATH, the PKCS#11 library of the token must be in MODULE_PATH.

OpenSSL has only the internal engine API. You need to load an engine module that maps the PKCS#11 API of the token to the engine API of OpenSSL. On Linux that is typically configured when libp11 is installed. Don’t know how that is done on Windows.

I always suggest to use XCA, because that saves you the hassle to correctly configure the OpenSSL stack.

And coming back to the initial question: If you installed OpenSC, can you see the token using sc-hsm-tool ?

If that works, can you see the token with pkcs11-tool ?

If that works, then the issue with XCA is probably that some other process blocks the token. You can try and enable OpenSC logging to see if the DLL loads and reports errors ?

Yes, in Windows, sc-hsm-tool and pkcs11-tool are successfully communicates with token. XCA - no token found, and yes, both pkcs11 directory and xca directory are in PATH.
It’s not so critical for me, because I need to create root certificate only once, so I have created it in Ubuntu, I am not the developer of OpenSC/XCA, I just wondered why it doesn’t work. In Windows using openssl I can sign with Nitrokey HSM2 and after that read this public key using pkcs11-tool to file and validate the signature using openssl.