Hi,
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,
"2b2586c684d69b670c0a805edf514e720f2b757d8e2faa0b3a7ff23d1ccfc7ba",
transfer_pin, &cb_data);
SSL_CTX_use_PrivateKey(sslContext, privateKey);
(I have been using the code in
https://github.com/jjkeijser/ppp/blob/eap-tls/pppd/eap-tls.c as a guide.)
This seems be successful. However, when I start the mutual
authentication with
SSL_connect(ssl)
, 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)
{
. . .
#ifndef OPENSSL_NO_RSA
* /***
** * 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)) ;
else
#endif
. . .
}
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
https://github.com/jjkeijser/ppp/blob/eap-tls/pppd/eap-tls.c
Thanks,
George
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
https://github.com/jjkeijser/ppp/blob/eap-tls/pppd/eap-tls.c 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,
JJK