private key not available for client_cert_cb

George whippet0 at
Fri Jan 8 21:35:05 UTC 2021


    I have been trying to setup mutual authentication using a smart card 
but I can't seem to get the OpenSSL Engine to send a response back to 
the server containing client's certificate from the smart card.

I'm using the following to configure the certificate and private key:

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

     EVP_PKEY* privateKey = ENGINE_load_private_key(engine, 
transfer_pin, &cb_data);
     SSL_CTX_use_PrivateKey(sslContext, privateKey);

(I have been using the code in  as a guide.)

This seems be successful. However, when I start the mutual 
authentication with
, the mutual authentications handshake fails. I can see the server 
requesting the certificate from the client and the client sends back an 
ACK for this message. However, the client does not send the certificate 
to the server.

I was looking through the OpenSSL code openssl-1.0.2u\ssl\ssl_rsa.c and 
noticed something interesting. The comment indicates that the flag 
*RSA_METHOD_FLAG_NO_CHECK* should be set for smart cards:

static int ssl_set_pkey(CERT *c, EVP_PKEY *pkey)
  . . .
*   /***
**         * Don't check the public/private key, this is mostly for smart**
**         * cards.**
**         */*
         if ((pkey->type == EVP_PKEY_RSA) &&
             (RSA_flags(pkey->pkey.rsa) & RSA_METHOD_FLAG_NO_CHECK)) ;
. . .

However, it is not actually set when I use a debugger to inspect the 
flag. Does it need to be set? If so, how is this done? I could not find 
anything related to this in


On 2021-01-05 11:51 a.m., Jan Just Keijser wrote:
> Hi,
> On 05/01/21 07:39, George wrote:
>> Hi,
>>     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:
>>     struct
>>     {
>>        const char* s_slot_cert_id;
>>        X509* cert;
>>     } cert_info;
>>     *cert_info.s_slot_cert_id =
>>     "a9bee4d72100c52f77c3fc288d2be01a34b5d44f91b3b7ea3d349b8a25752c45";*
>>     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
>>     "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" -pre PIN:123456 -pre
>>     FORCE_LOGIN *-pre
>>     "LOAD_CERT_CTRL:a9bee4d72100c52f77c3fc288d2be01a34b5d44f91b3b7ea3d349b8a25752c45"
>>     *(dynamic) Dynamic engine loading support
>>     [Success]:
>>     SO_PATH:C:\\Users\\whipp\\junk4\\libp11-libp11-0.4.11\\src\\pkcs11.dll
>>     [Success]: ID:pkcs11
>>     [Success]: LIST_ADD:1
>>     [Success]: LOAD
>>     [Success]: MODULE_PATH:C:\Program Files (x86)\HID
>>     Global\ActivClient\\acpkcs211.dll
>>     [Success]: PIN:123456
>>     [Success]: FORCE_LOGIN
>>     *[Failure]:
>>     LOAD_CERT_CTRL:a9bee4d72100c52f77c3fc288d2be01a34b5d44f91b3b7ea3d349b8a25752c45**
>>     **4196:error:260AB086:engine routines:ENGINE_ctrl_cmd_string:cmd
>>     not executable:.\crypto\engine\eng_ctrl.c:316:*
>>     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
>>     library
>>               (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
>>     (internal)
>>               (input flags): [Internal]
>>          FORCE_LOGIN: Force login to the PKCS#11 module
>>               (input flags): NO_INPUT
>>     OpenSSL>
>> 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.
> this has little to do with OpenSSL at the moment and more with libp11 
> - perhaps someone more knowledgable on the libp11 mailing list can 
> help you.
> I'd try to use
>   -post LOAD_CERT_CTRL
> instead of '-pre', as you want this done after the engine has been loaded.
> The cert ID does look OK. Note that if you want to use the s_client 
> command that you canNOT specify the certificate form '-certform 
> engine' as the code does not grok that.
> HTH,

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

More information about the openssl-users mailing list