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:
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>".
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.
Thanks,
George
On 2020-12-23 6:00 a.m., Jan Just Keijser wrote:
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.
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 E7F4FBE4644BA647ADDBE261BE596757
subject: DN: CN=PIVKey E7F4FBE4644BA647ADDBE261BE596757
ID: a9bee4d72100c52f77c3fc288d2be01a34b5d44f91b3b7ea3d349b8a25752c45
Thanks,
George
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
tbh, I don't know - look through the openssl sources to see what it does, exactly.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?
yes, although if you have multiple smartcards inserted at the same time then it helps to add the slot number, e.g.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?
0:<ID>
my eap-tls code does just that: if the password is specified in the ppp config file then the user is not prompted:
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(...)?
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,
JJK
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