private key not available for client_cert_cb

George whippet0 at
Tue Jan 5 06:39:36 UTC 2021


     I was looking at the  code in and 
realized I forgot to call ENGINE_ctrl_cmd(...) to setup 
"LOAD_CERT_CTRL". However, when I do this, the callback function is no 
longer being called during the mutual authentication handshake. I'm 
wondering if I have the parameter "cert_info.s_slot_cert_id" incorrectly 
configured. Here is what my code looks like:

        const char* s_slot_cert_id;
        X509* cert;
    } cert_info;
    *cert_info.s_slot_cert_id =
    cert_info.cert = NULL;

    *ENGINE_ctrl_cmd(engine, "LOAD_CERT_CTRL", 0, &cert_info, NULL, 0);*
    *SSL_CTX_use_certificate(sslContext, cert_info.cert);*

I tried manually using LOAD_CERT_CTRL in the openssl shell but I cannot 
seem to get it to work and cannot find any examples of how to use it.  
Is the syntax for *LOAD_CERT_CTRL* correct? I am 
using***"LOAD_CERT_CTRL:<certificate Object ID>".*

    OpenSSL> engine -vvvv -t dynamic -pre
    -pre ID:pkcs11 -pre LIST_ADD:1 -pre LOAD -pre
    "MODULE_PATH:C:\Program Files (x86)\HID
    Global\ActivClient\\acpkcs211.dll" -pre PIN:123456 -pre FORCE_LOGIN

    *(dynamic) Dynamic engine loading support
    [Success]: ID:pkcs11
    [Success]: LIST_ADD:1
    [Success]: LOAD
    [Success]: MODULE_PATH:C:\Program Files (x86)\HID
    [Success]: PIN:123456
    [Success]: FORCE_LOGIN
    **4196:error:260AB086:engine routines:ENGINE_ctrl_cmd_string:cmd not
    Loaded: (pkcs11) pkcs11 engine
          [ available ]
          SO_PATH: Specifies the path to the 'pkcs11' engine shared library
               (input flags): STRING
          MODULE_PATH: Specifies the path to the PKCS#11 module shared
               (input flags): STRING
          PIN: Specifies the pin code
               (input flags): STRING
          VERBOSE: Print additional details
               (input flags): NO_INPUT
          QUIET: Remove additional details
               (input flags): NO_INPUT
    *LOAD_CERT_CTRL: Get the certificate from card**
    **          (input flags): [Internal]*
          INIT_ARGS: Specifies additional initialization arguments to
    the PKCS#11 module
               (input flags): STRING
          SET_USER_INTERFACE: Set the global user interface (internal)
               (input flags): [Internal]
          SET_CALLBACK_DATA: Set the global user interface extra data
               (input flags): [Internal]
          FORCE_LOGIN: Force login to the PKCS#11 module
               (input flags): NO_INPUT

I'm using the certificate object ID 
"a9bee4d72100c52f77c3fc288d2be01a34b5d44f91b3b7ea3d349b8a25752c45" for 
LOAD_CERT_CTRL. Is this right? (I also tried adding "0:" in front of it 
to indicate slot 0, but that did not work either.

    C:\Program Files\OpenSC Project\OpenSC\tools>pkcs11-tool
    --module="C:\Program Files\HID Global\ActivClient/acpkcs211.dll" -l -O
    Using slot 0 with a present token (0x0)
    Certificate Object; type = X.509 cert
       label:      Card Authentication - PIVKey
       subject:    DN: CN=PIVKey E7F4FBE4644BA647ADDBE261BE596757
    *ID: a9bee4d72100c52f77c3fc288d2be01a34b5d44f91b3b7ea3d349b8a25752c45*


On 2020-12-23 6:00 a.m., Jan Just Keijser wrote:
> Hi,
> On 20/12/20 09:39, George wrote:
>> Hi,
>>    I tried running the "s_client" command and it appears to be working.
>> I guess there must be something wrong in my code.
> it is good news that the s_client command is working - it means there 
> is something wrong with your code but you have everything at hand to 
> fix it: download the openssl 1.0.2 tarball / zip file and look for the 
> files
>   apps/s_client.c
>   apps/apps.c
> that contains all of the code that the 's_client' command uses to make 
> a connection and my bet is that is also does not call ENGINE_init
>> My crash occurs when I call
>>     ENGINE_init(pkey_engine);
>> I notice your code does not call this function.  Is this needed 
>> needed? If so, when/where should it be called?
> tbh,  I don't know - look through the openssl sources to see what it 
> does, exactly.
>> What exactly is the definition of "pkey_identifier" in
>>     ENGINE_load_private_key(pkey_engine, *pkey_identifier*,
>>     transfer_pin, &cb_data) ?
>> I'm not clear on what this value should be. Can you give an example 
>> of what it would look like?
>> I have the following on my smart card:
>>     Private Key Object; RSA
>>       label:      Authentication - *
>>     *ID:**2b2586c684d69b670c0a805edf514e720f2b757d8e2faa0b3a7ff23d1ccfc7ba*
>>       Usage:      unwrap
>>       Access:     sensitive, never extractable
>>       Allowed mechanisms: RSA-PKCS,RSA-X-509
>> Would the *pkey_identifier* be the *ID* in the above?
> yes, although if you have multiple smartcards inserted at the same 
> time then it helps to add the slot number, e.g.
>   0:<ID>
>> What exactly is "prompt_info" in the structure PW_CB_DATA?
>> i.e.
>> typedef struct pw_cb_data {
>>     const void* password;
>>     const char* *prompt_info;*
>> } PW_CB_DATA;
>> Can you give an example of what it might look like?
>> Is the value of cb_data populated by the transfer_pin callback 
>> functions, or should it already contain a value when 
>> ENGINE_load_private_key is called?
>> Is there a way to skip the callback transfer_pin and use a hard coded 
>> pin for test purposes when calling ENGINE_load_private_key(...)?
> my eap-tls code does just that: if the password is specified in the 
> ppp config file then the user is not prompted:
>     if (pkey_engine)
>     {
>         EVP_PKEY   *pkey = NULL;
>         PW_CB_DATA  cb_data;
>         UI_METHOD* transfer_pin = NULL;
>         cb_data.password = passwd;
>         cb_data.prompt_info = pkey_identifier;
> HTH,
>> On 2020-12-19 8:05 p.m., Jan Just Keijser wrote:
>>> I'd say no engine/pkcs11 module should trigger exceptions - that's 
>>> an error in the pkcs11 module.
>>> Something you can try is this:
>>> run the 'openssl.exe' command:
>>> openssl engine -t dynamic -pre 
>>> "SO_PATH:C:\\Users\\whipp\\junk4\\libp11-libp11-0.4.11\\src\\pkcs11.dll" 
>>> -pre ID:pkcs11 -pre LIST_ADD:1 -pre LOAD -pre 
>>> "MODULE_PATH:C:\Program Files (x86)\HID 
>>> Global\ActivClient\\acpkcs211.dll"
>>> then on the OpenSSL prompt , try
>>>   s_client -keyform engine -key 0:<key-id>  -cert "clientcert.pem"  
>>> -connect remote_host:remote_port
>>> that should start a TLS connection and use the pcks11 engine to ask 
>>> for the key , identified by <key-id> in slot 0 (adjust the slot 
>>> number if your smart card starts at number 1 etc.
>>> HTH,
>>> JJK

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <>

More information about the openssl-users mailing list