RE: private key not available for client_cert_cb

2021-01-12 Thread Michael Wojcik
> From: openssl-users  On Behalf Of George
> Sent: Tuesday, 12 January, 2021 00:18

> I'm running this in Windows 10 and when I load the smart card middleware
> PKCS11 DLL, I see the exception:
> Exception thrown at 0x773046D2 in GENCom.exe: Microsoft C++ exception:
> unsigned long at memory location 0x07FCFA00.

OK. If I were debugging libp11, it would be useful to know what the exception 
actually was, but as it is all I can say is that it seems to be a libp11 
problem. As you noted further below:

> It looks like someone else using a smart card has also encountered similar
> problems in Windows but there is no real answer as to why they are occurring:
> https://www.codeproject.com/Questions/1254182/Smart-card-apis-throw-first-chance-
> exceptions-but

You'll probably have to just swallow the exceptions and retry until it works or 
your code decides to give up and return an error. Maybe one of the libp11 
maintainers or someone else using the library will dig into it at some point.

--
Michael Wojcik


Re: private key not available for client_cert_cb

2021-01-11 Thread George
I'm running this in Windows 10 and when I load the smart card middleware 
PKCS11 DLL, I see the exception:


   Exception thrown at 0x773046D2 in GENCom.exe: Microsoft C++
   exception: unsigned long at memory location 0x07FCFA00.


During mutual authentication, I also see alot of other exceptions such as:

   Exception thrown at 0x773046D2 in GENCom.exe: Microsoft C++
   exception: AI::Middleware::CMWException at memory location 0x032FD2D0.


I traced them down to various PKCS11 calls on the card in libp11.
e.g.
the function call to C_GetSlotList(...) in the file p11_slot.c triggers 
an exception:


   int pkcs11_enumerate_slots(PKCS11_CTX *ctx, PKCS11_SLOT **slotp,
   unsigned int *countp)
   {
   . . .
   *rv = cpriv->method->C_GetSlotList(FALSE, NULL_PTR, );*
   . . .
   }


It is interesting to note that this function seems to get called 
multiple times and it eventually works. I do not fully understand 
how/why the code does that and if this is the design intent. The 
exceptions don't seem to have any effect on the functionality, but I 
still need to understand why they are occurring.


It looks like someone else using a smart card has also encountered 
similar problems in Windows but there is no real answer as to why they 
are occurring:

https://www.codeproject.com/Questions/1254182/Smart-card-apis-throw-first-chance-exceptions-but



Thanks,
George


On 2021-01-11 9:41 a.m., Michael Wojcik wrote:

From: openssl-users  On Behalf Of George
Sent: Sunday, 10 January, 2021 21:01
Right now I am using the "libp11" DLL (i.e. libp11-libp11-0.4.11\src\pkcs11.dll)
with my PKCS11 smart card middleware DLL. Should I be using the OpenSC pkcs11 
DLL
instead of my middleware DLL if I am using libp1?

Honestly, I have no idea. It's been years since I worked with PKCS#11, and then 
I was using a single piece of test hardware. I got it working with OpenSSL 
using the OpenSC modules, but that may have been specific to my case.


Do you know if it is normal to see exceptions related to the PKCS11 function 
calls
in the libp11 code? For example, I can see  the following function generate an
exception on C_GetSlotList(...) multiple times but it eventually is successful.
Is this normal behaviour?

What sort of "exception"? A Windows exception? UNIX signal? C++ exception?

My initial guess would be that this is a timing issue - maybe the device needs 
some time to become available, for example. But that's just a guess. Maybe 
someone with more experience with a variety of HSMs and PKCS#11 will weigh in.

--
Michael Wojcik




Re: private key not available for client_cert_cb

2021-01-11 Thread George
I found out what my problem is! I'm running it in FIPS mode and this 
causes the PKCS11 engine to fail during mutual authentication. I 
eventually traced the problem to the following issue:

https://bugzilla.redhat.com/show_bug.cgi?id=1827535

It looks like there is a bug in libp11. Once I made the suggested 
workaround, it worked.

My original code, which is based on
https://github.com/jjkeijser/ppp/blob/eap-tls/pppd/eap-tls.c
worked perfectly after I added in the libp11 fix.  :)


Thanks!
George


On 2021-01-11 11:01 a.m., Jan Just Keijser wrote:

Hi,

On 08/01/21 22:35, George wrote:

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, _info, NULL, 0);
    SSL_CTX_use_certificate(sslContext, cert_info.cert);

    EVP_PKEY* privateKey = ENGINE_load_private_key(engine, 
"2b2586c684d69b670c0a805edf514e720f2b757d8e2faa0b3a7ff23d1ccfc7ba", 
transfer_pin, _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



if you read through the code blob that Michael pointed you to, you 
will find that this flag needs to be set *under certain circumstances* 
when using smartcards. It has to do mostly with the situation where

- private key is on the smart card
- the public key/certificate is NOT on the smart card
- you ask OpenSSL to verify the private key without explicitly 
providing a public key.


I've never run into this issue, but then again, I have not tested very 
often the case where the certificate was not present on the HSM/smart 
card but the private key is.  YMMV.


As for using pksc11helper versus using libp11: that is just a matter 
of taste. I used the engine_pkcs11 + libp11 route for the eap-tls code 
, mostly because it was the first "working" set of tools I found at 
the time.


You can also take the "pkcs11helper" route, which is what OpenVPN does 
(see https://github.com/openvpn). Both methods have pro's and con's.


Do you run into problems if you DO not set the 
RSA_METHOD_FLAG_NO_CHECK flag?  All that flag does is to stop OpenSSL 
from verifying that a public key/cert and private key match/belong 
together for RSA keys only; if your smartcard supports EC keys then 
this flag will do you no good.


HTH,

JJK





Re: private key not available for client_cert_cb

2021-01-11 Thread Jan Just Keijser

Hi,

On 08/01/21 22:35, George wrote:

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, _info, NULL, 0);
    SSL_CTX_use_certificate(sslContext, cert_info.cert);

    EVP_PKEY* privateKey = ENGINE_load_private_key(engine, 
"2b2586c684d69b670c0a805edf514e720f2b757d8e2faa0b3a7ff23d1ccfc7ba", 
transfer_pin, _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



if you read through the code blob that Michael pointed you to, you will 
find that this flag needs to be set *under certain circumstances* when 
using smartcards. It has to do mostly with the situation where

- private key is on the smart card
- the public key/certificate is NOT on the smart card
- you ask OpenSSL to verify the private key without explicitly providing 
a public key.


I've never run into this issue, but then again, I have not tested very 
often the case where the certificate was not present on the HSM/smart 
card but the private key is.  YMMV.


As for using pksc11helper versus using libp11: that is just a matter of 
taste. I used the engine_pkcs11 + libp11 route for the eap-tls code , 
mostly because it was the first "working" set of tools I found at the time.


You can also take the "pkcs11helper" route, which is what OpenVPN does 
(see https://github.com/openvpn).  Both methods have pro's and con's.


Do you run into problems if you DO not set the RSA_METHOD_FLAG_NO_CHECK 
flag?  All that flag does is to stop OpenSSL from verifying that a 
public key/cert and private key match/belong together for RSA keys only; 
if your smartcard supports EC keys then this flag will do you no good.


HTH,

JJK



RE: private key not available for client_cert_cb

2021-01-11 Thread Michael Wojcik
> From: openssl-users  On Behalf Of George
> Sent: Sunday, 10 January, 2021 21:01

> Right now I am using the "libp11" DLL (i.e. 
> libp11-libp11-0.4.11\src\pkcs11.dll)
> with my PKCS11 smart card middleware DLL. Should I be using the OpenSC pkcs11 
> DLL
> instead of my middleware DLL if I am using libp1?

Honestly, I have no idea. It's been years since I worked with PKCS#11, and then 
I was using a single piece of test hardware. I got it working with OpenSSL 
using the OpenSC modules, but that may have been specific to my case.

> Do you know if it is normal to see exceptions related to the PKCS11 function 
> calls
> in the libp11 code? For example, I can see  the following function generate an
> exception on C_GetSlotList(...) multiple times but it eventually is 
> successful.
> Is this normal behaviour?

What sort of "exception"? A Windows exception? UNIX signal? C++ exception?

My initial guess would be that this is a timing issue - maybe the device needs 
some time to become available, for example. But that's just a guess. Maybe 
someone with more experience with a variety of HSMs and PKCS#11 will weigh in.

--
Michael Wojcik


Re: private key not available for client_cert_cb

2021-01-10 Thread George

Hi,

    I had a look at the pkcs11-helper and can see where the 
RSA_METHOD_FLAG_NO_CHECK is being set. It's using a session object 
called pkcs11h_openssl_session_t, which I do not see in the libp11 or 
openSC code.


Right now I am using the "libp11" DLL (i.e. 
libp11-libp11-0.4.11\src\pkcs11.dll) with my PKCS11 smart card 
middleware DLL. Should I be using the OpenSC pkcs11 DLL instead of my 
middleware DLL if I am using libp1?


Do you know if it is normal to see exceptions related to the PKCS11 
function calls in the libp11 code? For example, I can see the following 
function generate an exception on C_GetSlotList(...) multiple times but 
it eventually is successful.  Is this normal behaviour?


int pkcs11_enumerate_slots(PKCS11_CTX *ctx, PKCS11_SLOT **slotp, 
unsigned int *countp)

{
. . .
    rv = cpriv->method->C_GetSlotList(FALSE, NULL_PTR, );
. . .
}


Thanks,
George



On 2021-01-08 6:32 p.m., Michael Wojcik wrote:

From: openssl-users  On Behalf Of George
Sent: Friday, 8 January, 2021 14:35
The comment indicates that the flag RSA_METHOD_FLAG_NO_CHECK should be set
for smart cards[...]
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?

If memory serves, the PKCS#11 implementation invoked by the pkcs11 engine is 
supposed to set it.

See for example this patch to OpenSC's pkcs11-helper library:

https://github.com/OpenSC/pkcs11-helper/commit/5198bb1e557dfd4109bea41c086825bf6ebdd9f3

(That patch actually is to set a different flag, but it shows the code in 
question.)

I know, that's probably not terribly helpful.

If you do a web search for something like

 pkcs11 "RSA_METHOD_FLAG_NO_CHECK"

you'll probably find a number of hits where other people ran into similar 
problems.

Isn't PKCS#11 grand? If you're bored with all the interoperability problems of 
X.509, PKIX, and TLS, we have good news!

--
Michael Wojcik




RE: private key not available for client_cert_cb

2021-01-08 Thread Michael Wojcik
> From: openssl-users  On Behalf Of George
> Sent: Friday, 8 January, 2021 14:35

> The comment indicates that the flag RSA_METHOD_FLAG_NO_CHECK should be set
> for smart cards[...]

> 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?

If memory serves, the PKCS#11 implementation invoked by the pkcs11 engine is 
supposed to set it.

See for example this patch to OpenSC's pkcs11-helper library:

https://github.com/OpenSC/pkcs11-helper/commit/5198bb1e557dfd4109bea41c086825bf6ebdd9f3

(That patch actually is to set a different flag, but it shows the code in 
question.)

I know, that's probably not terribly helpful.

If you do a web search for something like

pkcs11 "RSA_METHOD_FLAG_NO_CHECK"

you'll probably find a number of hits where other people ran into similar 
problems.

Isn't PKCS#11 grand? If you're bored with all the interoperability problems of 
X.509, PKIX, and TLS, we have good news!

--
Michael Wojcik


Re: private key not available for client_cert_cb

2021-01-08 Thread George

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, _info, NULL, 0);
    SSL_CTX_use_certificate(sslContext, cert_info.cert);

    EVP_PKEY* privateKey = ENGINE_load_private_key(engine, 
"2b2586c684d69b670c0a805edf514e720f2b757d8e2faa0b3a7ff23d1ccfc7ba", 
transfer_pin, _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, _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:".*


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" -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>



Re: private key not available for client_cert_cb

2021-01-05 Thread Jan Just Keijser

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, _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:".*


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" -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



Re: private key not available for client_cert_cb

2021-01-04 Thread George

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, _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:".*


   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" -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

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, _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 - *

Re: private key not available for client_cert_cb

2020-12-23 Thread Jan Just Keijser

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, _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:




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,

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:  -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  in slot 0 (adjust the slot 
number if your smart card starts at number 1 etc.


HTH,

JJK








Re: private key not available for client_cert_cb

2020-12-20 Thread George

Hi,

   I tried running the "s_client" command and it appears to be working.

I guess there must be something wrong in my code.
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?


What exactly is the definition of "pkey_identifier" in

   ENGINE_load_private_key(pkey_engine, *pkey_identifier*,
   transfer_pin, _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?


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(...)?




Thanks!
George


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:  -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  in slot 0 (adjust the slot number 
if your smart card starts at number 1 etc.


HTH,

JJK






Re: private key not available for client_cert_cb

2020-12-19 Thread Jan Just Keijser

Hi,

On 19/12/20 04:48, George wrote:

Hi,

  I narrowed the problem down to
ENGINE_set_default(pkey_engine, ENGINE_METHOD_ALL)

This causes the initial exception
Exception thrown at 0x757346D2 in GENCom.exe: Microsoft C++ exception: 
unsigned long at memory location 0x006FCD68.


It looks like some of the Engine methods cause an exception, but not 
all of them:

*
Works:*
ENGINE_METHOD_CIPHERS
ENGINE_METHOD_DIGESTS
ENGINE_METHOD_DSA
ENGINE_METHOD_DH
ENGINE_METHOD_RAND
ENGINE_METHOD_PKEY_ASN1_METHS

*Causes An Exception:*
ENGINE_METHOD_RSA
ENGINE_METHOD_ECDH
ENGINE_METHOD_ECDSA
ENGINE_METHOD_PKEY_METHS


Is that normal behaviour, or is something wrong? Is there a way to 
find the supported engine methods to avoid triggering an exception?


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:  -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  in slot 0 (adjust the slot number if 
your smart card starts at number 1 etc.


HTH,

JJK





It seems like alot of other smaple code I have looked at calls
ENGINE_init(pkey_engine);

Is the needed? When I call it, it always returns with "0". Should it 
be returning with "1"?


I did some testing in the OpenSSL command line, and here is what I found:

- The command line "speed" test appears to be fine:

OpenSSL> speed -engine pkcs11
engine "pkcs11" set.
Doing mdc2 for 3s on 16 size blocks: 2688737 mdc2's in 2.98s
Doing mdc2 for 3s on 64 size blocks: 880529 mdc2's in 3.00s
Doing mdc2 for 3s on 256 size blocks: 240916 mdc2's in 2.98s
Doing mdc2 for 3s on 1024 size blocks: 61287 mdc2's in 3.00s
Doing mdc2 for 3s on 8192 size blocks: 7774 mdc2's in 2.98s
.
.
.

-  I also tried the following, which successfully created the PEM
files:

OpenSSL> req -engine pkcs11 -new -key
"pkcs11:object=Authentication -
*;type=private;pin-value=123456" -keyform engine -out req2.pem
-text -x509 -subj "/CN=*"
OpenSSL> x509 -engine pkcs11 -signkey
"pkcs11:object=Authentication -
*;type=private;pin-value=123456" -keyform engine -in req2.pem
-out cert2.pem





Thanks,
George


On 2020-12-18 3:40 a.m., Jan Just Keijser wrote:

Hi,

On 18/12/20 06:21, George wrote:

Hi,

   I'm able to setup the engine now, but as soon as I attempt to 
execute the command

ENGINE_set_default(pkey_engine, ENGINE_METHOD_ALL);
,I see all kinds of middleware exceptions being generated:

Exception thrown at 0x773046D2 in GENCom.exe: Microsoft C++ 
exception: unsigned long at memory location 0x07FCFA00.
Exception thrown at 0x773046D2 in GENCom.exe: Microsoft C++ 
exception: AI::Middleware::CMWException at memory location 0x032FD2D0.
Exception thrown at 0x773046D2 in GENCom.exe: Microsoft C++ 
exception: AI::Middleware::CMWException at memory location 0x032FD2D0.
Exception thrown at 0x773046D2 in GENCom.exe: Microsoft C++ 
exception: AI::Middleware::CMWException at memory location 0x032FD2D0.
Exception thrown at 0x773046D2 in GENCom.exe: Microsoft C++ 
exception: AI::Middleware::CMWException at memory location 0x032FD2D0.
Exception thrown at 0x773046D2 in GENCom.exe: Microsoft C++ 
exception: AI::Middleware::CMWException at memory location 0x032FD2D0.
Exception thrown at 0x773046D2 in GENCom.exe: Microsoft C++ 
exception: AI::Middleware::CMWException at memory location 0x032FD2D0.
Exception thrown at 0x773046D2 in GENCom.exe: Microsoft C++ 
exception: AI::Middleware::CMWException at memory location 0x032FD2D0.
Exception thrown at 0x773046D2 in GENCom.exe: Microsoft C++ 
exception: AI::Middleware::CMWException at memory location 0x032FD2D0.

.
.
.


Do you have any idea what is causing these errors? Am I missing 
something in the configuration? When I use the OpenSSL command line 
debugger, there are no errors:


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"

(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

Loaded: (pkcs11) pkcs11 engine
 [ available ]
OpenSSL>


Here is what my simplified code looks like:

char* enginePluginLibrary = 

Re: private key not available for client_cert_cb

2020-12-18 Thread George

Hi,

  I narrowed the problem down to
ENGINE_set_default(pkey_engine, ENGINE_METHOD_ALL)

This causes the initial exception
Exception thrown at 0x757346D2 in GENCom.exe: Microsoft C++ exception: 
unsigned long at memory location 0x006FCD68.


It looks like some of the Engine methods cause an exception, but not all 
of them:

*
Works:*
ENGINE_METHOD_CIPHERS
ENGINE_METHOD_DIGESTS
ENGINE_METHOD_DSA
ENGINE_METHOD_DH
ENGINE_METHOD_RAND
ENGINE_METHOD_PKEY_ASN1_METHS

*Causes An Exception:*
ENGINE_METHOD_RSA
ENGINE_METHOD_ECDH
ENGINE_METHOD_ECDSA
ENGINE_METHOD_PKEY_METHS


Is that normal behaviour, or is something wrong? Is there a way to find 
the supported engine methods to avoid triggering an exception?


It seems like alot of other smaple code I have looked at calls
ENGINE_init(pkey_engine);

Is the needed? When I call it, it always returns with "0". Should it be 
returning with "1"?


I did some testing in the OpenSSL command line, and here is what I found:

   - The command line "speed" test appears to be fine:

   OpenSSL> speed -engine pkcs11
   engine "pkcs11" set.
   Doing mdc2 for 3s on 16 size blocks: 2688737 mdc2's in 2.98s
   Doing mdc2 for 3s on 64 size blocks: 880529 mdc2's in 3.00s
   Doing mdc2 for 3s on 256 size blocks: 240916 mdc2's in 2.98s
   Doing mdc2 for 3s on 1024 size blocks: 61287 mdc2's in 3.00s
   Doing mdc2 for 3s on 8192 size blocks: 7774 mdc2's in 2.98s
   .
   .
   .

   -  I also tried the following, which successfully created the PEM files:

   OpenSSL> req -engine pkcs11 -new -key
   "pkcs11:object=Authentication - *;type=private;pin-value=123456"
   -keyform engine -out req2.pem -text -x509 -subj "/CN=*"
   OpenSSL> x509 -engine pkcs11 -signkey
   "pkcs11:object=Authentication - *;type=private;pin-value=123456"
   -keyform engine -in req2.pem -out cert2.pem





Thanks,
George


On 2020-12-18 3:40 a.m., Jan Just Keijser wrote:

Hi,

On 18/12/20 06:21, George wrote:

Hi,

   I'm able to setup the engine now, but as soon as I attempt to 
execute the command

ENGINE_set_default(pkey_engine, ENGINE_METHOD_ALL);
,I see all kinds of middleware exceptions being generated:

Exception thrown at 0x773046D2 in GENCom.exe: Microsoft C++ 
exception: unsigned long at memory location 0x07FCFA00.
Exception thrown at 0x773046D2 in GENCom.exe: Microsoft C++ 
exception: AI::Middleware::CMWException at memory location 0x032FD2D0.
Exception thrown at 0x773046D2 in GENCom.exe: Microsoft C++ 
exception: AI::Middleware::CMWException at memory location 0x032FD2D0.
Exception thrown at 0x773046D2 in GENCom.exe: Microsoft C++ 
exception: AI::Middleware::CMWException at memory location 0x032FD2D0.
Exception thrown at 0x773046D2 in GENCom.exe: Microsoft C++ 
exception: AI::Middleware::CMWException at memory location 0x032FD2D0.
Exception thrown at 0x773046D2 in GENCom.exe: Microsoft C++ 
exception: AI::Middleware::CMWException at memory location 0x032FD2D0.
Exception thrown at 0x773046D2 in GENCom.exe: Microsoft C++ 
exception: AI::Middleware::CMWException at memory location 0x032FD2D0.
Exception thrown at 0x773046D2 in GENCom.exe: Microsoft C++ 
exception: AI::Middleware::CMWException at memory location 0x032FD2D0.
Exception thrown at 0x773046D2 in GENCom.exe: Microsoft C++ 
exception: AI::Middleware::CMWException at memory location 0x032FD2D0.

.
.
.


Do you have any idea what is causing these errors? Am I missing 
something in the configuration? When I use the OpenSSL command line 
debugger, there are no errors:


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"

(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

Loaded: (pkcs11) pkcs11 engine
 [ available ]
OpenSSL>


Here is what my simplified code looks like:

char* enginePluginLibrary = 
"C:\\Users\\whipp\\junk4\\libp11-libp11-0.4.11\\src\\pkcs11.dll";
char* pkcs11MiddlewareLibrary = "C:\\Program Files (x86)\\HID 
Global\\ActivClient\\acpkcs211.dll";

ENGINE_load_builtin_engines();
ENGINE_register_all_complete();
ENGINE *pkey_engine = ENGINE_by_id("dynamic");

ENGINE_ctrl_cmd_string(pkey_engine, "SO_PATH", enginePluginLibrary, 0);
ENGINE_ctrl_cmd_string(pkey_engine, "ID", "pkcs11", 0);
ENGINE_ctrl_cmd_string(pkey_engine, "LIST_ADD", "1", 0);
ENGINE_ctrl_cmd_string(pkey_engine, "LOAD", NULL, 0);
ENGINE_ctrl_cmd_string(pkey_engine, "MODULE_PATH", 
pkcs11MiddlewareLibrary, 0);

ENGINE_set_default(pkey_engine, ENGINE_METHOD_ALL);


main difference between the OPENSSL.EXE example and your code is that 
last call:


here's wat "ENGINE_set_default(pkey_engine, ENGINE_METHOD_ALL)" does:


int 

Re: private key not available for client_cert_cb

2020-12-18 Thread Jan Just Keijser

Hi,

On 18/12/20 06:21, George wrote:

Hi,

   I'm able to setup the engine now, but as soon as I attempt to 
execute the command

ENGINE_set_default(pkey_engine, ENGINE_METHOD_ALL);
,I see all kinds of middleware exceptions being generated:

Exception thrown at 0x773046D2 in GENCom.exe: Microsoft C++ exception: 
unsigned long at memory location 0x07FCFA00.
Exception thrown at 0x773046D2 in GENCom.exe: Microsoft C++ exception: 
AI::Middleware::CMWException at memory location 0x032FD2D0.
Exception thrown at 0x773046D2 in GENCom.exe: Microsoft C++ exception: 
AI::Middleware::CMWException at memory location 0x032FD2D0.
Exception thrown at 0x773046D2 in GENCom.exe: Microsoft C++ exception: 
AI::Middleware::CMWException at memory location 0x032FD2D0.
Exception thrown at 0x773046D2 in GENCom.exe: Microsoft C++ exception: 
AI::Middleware::CMWException at memory location 0x032FD2D0.
Exception thrown at 0x773046D2 in GENCom.exe: Microsoft C++ exception: 
AI::Middleware::CMWException at memory location 0x032FD2D0.
Exception thrown at 0x773046D2 in GENCom.exe: Microsoft C++ exception: 
AI::Middleware::CMWException at memory location 0x032FD2D0.
Exception thrown at 0x773046D2 in GENCom.exe: Microsoft C++ exception: 
AI::Middleware::CMWException at memory location 0x032FD2D0.
Exception thrown at 0x773046D2 in GENCom.exe: Microsoft C++ exception: 
AI::Middleware::CMWException at memory location 0x032FD2D0.

.
.
.


Do you have any idea what is causing these errors? Am I missing 
something in the configuration? When I use the OpenSSL command line 
debugger, there are no errors:


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"

(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

Loaded: (pkcs11) pkcs11 engine
 [ available ]
OpenSSL>


Here is what my simplified code looks like:

char* enginePluginLibrary = 
"C:\\Users\\whipp\\junk4\\libp11-libp11-0.4.11\\src\\pkcs11.dll";
char* pkcs11MiddlewareLibrary = "C:\\Program Files (x86)\\HID 
Global\\ActivClient\\acpkcs211.dll";

ENGINE_load_builtin_engines();
ENGINE_register_all_complete();
ENGINE *pkey_engine = ENGINE_by_id("dynamic");

ENGINE_ctrl_cmd_string(pkey_engine, "SO_PATH", enginePluginLibrary, 0);
ENGINE_ctrl_cmd_string(pkey_engine, "ID", "pkcs11", 0);
ENGINE_ctrl_cmd_string(pkey_engine, "LIST_ADD", "1", 0);
ENGINE_ctrl_cmd_string(pkey_engine, "LOAD", NULL, 0);
ENGINE_ctrl_cmd_string(pkey_engine, "MODULE_PATH", 
pkcs11MiddlewareLibrary, 0);

ENGINE_set_default(pkey_engine, ENGINE_METHOD_ALL);


main difference between the OPENSSL.EXE example and your code is that 
last call:


here's wat "ENGINE_set_default(pkey_engine, ENGINE_METHOD_ALL)" does:


int ENGINE_set_default(ENGINE *e, unsigned int flags)
{
    if ((flags & ENGINE_METHOD_CIPHERS) && !ENGINE_set_default_ciphers(e))
    return 0;
    if ((flags & ENGINE_METHOD_DIGESTS) && !ENGINE_set_default_digests(e))
    return 0;
#ifndef OPENSSL_NO_RSA
    if ((flags & ENGINE_METHOD_RSA) && !ENGINE_set_default_RSA(e))
    return 0;
#endif
#ifndef OPENSSL_NO_DSA
    if ((flags & ENGINE_METHOD_DSA) && !ENGINE_set_default_DSA(e))
    return 0;
#endif
#ifndef OPENSSL_NO_DH
    if ((flags & ENGINE_METHOD_DH) && !ENGINE_set_default_DH(e))
    return 0;
#endif
#ifndef OPENSSL_NO_ECDH
    if ((flags & ENGINE_METHOD_ECDH) && !ENGINE_set_default_ECDH(e))
    return 0;
#endif
#ifndef OPENSSL_NO_ECDSA
    if ((flags & ENGINE_METHOD_ECDSA) && !ENGINE_set_default_ECDSA(e))
    return 0;
#endif
    if ((flags & ENGINE_METHOD_RAND) && !ENGINE_set_default_RAND(e))
    return 0;
    if ((flags & ENGINE_METHOD_PKEY_METHS)
    && !ENGINE_set_default_pkey_meths(e))
    return 0;
    if ((flags & ENGINE_METHOD_PKEY_ASN1_METHS)
    && !ENGINE_set_default_pkey_asn1_meths(e))
    return 0;
    return 1;
}

(from the openssl 1.0.2 source tree)
It could be that one of those methods is not throwing the errors with 
your smart card.
I'd advise you to test your smart card capabilities . It might also be 
useful to do more command line testing with your smartcard using


  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"


and then try out certain operations, like encrypt/decrypt or simply use 
the command

  speed

and watch for any errors - that should give you a hint which method is 
not supported by your smart card.


HTH,

JJK


On 2020-12-17 8:39 p.m., Jan Just Keijser wrote:

On 17/12/20 14:55, George wrote:
Ok. So I use the 

Re: private key not available for client_cert_cb

2020-12-17 Thread George

Hi,

   I'm able to setup the engine now, but as soon as I attempt to 
execute the command

ENGINE_set_default(pkey_engine, ENGINE_METHOD_ALL);
,I see all kinds of middleware exceptions being generated:

Exception thrown at 0x773046D2 in GENCom.exe: Microsoft C++ exception: 
unsigned long at memory location 0x07FCFA00.
Exception thrown at 0x773046D2 in GENCom.exe: Microsoft C++ exception: 
AI::Middleware::CMWException at memory location 0x032FD2D0.
Exception thrown at 0x773046D2 in GENCom.exe: Microsoft C++ exception: 
AI::Middleware::CMWException at memory location 0x032FD2D0.
Exception thrown at 0x773046D2 in GENCom.exe: Microsoft C++ exception: 
AI::Middleware::CMWException at memory location 0x032FD2D0.
Exception thrown at 0x773046D2 in GENCom.exe: Microsoft C++ exception: 
AI::Middleware::CMWException at memory location 0x032FD2D0.
Exception thrown at 0x773046D2 in GENCom.exe: Microsoft C++ exception: 
AI::Middleware::CMWException at memory location 0x032FD2D0.
Exception thrown at 0x773046D2 in GENCom.exe: Microsoft C++ exception: 
AI::Middleware::CMWException at memory location 0x032FD2D0.
Exception thrown at 0x773046D2 in GENCom.exe: Microsoft C++ exception: 
AI::Middleware::CMWException at memory location 0x032FD2D0.
Exception thrown at 0x773046D2 in GENCom.exe: Microsoft C++ exception: 
AI::Middleware::CMWException at memory location 0x032FD2D0.

.
.
.


Do you have any idea what is causing these errors? Am I missing 
something in the configuration? When I use the OpenSSL command line 
debugger, there are no errors:


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"

(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

Loaded: (pkcs11) pkcs11 engine
 [ available ]
OpenSSL>


Here is what my simplified code looks like:

char* enginePluginLibrary = 
"C:\\Users\\whipp\\junk4\\libp11-libp11-0.4.11\\src\\pkcs11.dll";
char* pkcs11MiddlewareLibrary = "C:\\Program Files (x86)\\HID 
Global\\ActivClient\\acpkcs211.dll";

ENGINE_load_builtin_engines();
ENGINE_register_all_complete();
ENGINE *pkey_engine = ENGINE_by_id("dynamic");

ENGINE_ctrl_cmd_string(pkey_engine, "SO_PATH", enginePluginLibrary, 0);
ENGINE_ctrl_cmd_string(pkey_engine, "ID", "pkcs11", 0);
ENGINE_ctrl_cmd_string(pkey_engine, "LIST_ADD", "1", 0);
ENGINE_ctrl_cmd_string(pkey_engine, "LOAD", NULL, 0);
ENGINE_ctrl_cmd_string(pkey_engine, "MODULE_PATH", 
pkcs11MiddlewareLibrary, 0);

ENGINE_set_default(pkey_engine, ENGINE_METHOD_ALL);


Thanks!
George



On 2020-12-17 8:39 p.m., Jan Just Keijser wrote:

On 17/12/20 14:55, George wrote:
Ok. So I use the libp11 project DLL file for the SO_PATH and my smart 
card middleware DLL for the MODULE_PATH when setting up the OpenSSL 
Engine?




yes just like in the example I posted below.

I would recommend the p11 wiki page to do it using the command line 
first - much easier to test & debug.


JJK



Re: private key not available for client_cert_cb

2020-12-17 Thread Jan Just Keijser

On 17/12/20 14:55, George wrote:
Ok. So I use the libp11 project DLL file for the SO_PATH and my smart 
card middleware DLL for the MODULE_PATH when setting up the OpenSSL 
Engine?




yes just like in the example I posted below.

I would recommend the p11 wiki page to do it using the command line 
first - much easier to test & debug.


JJK




On 2020-12-17 3:22 a.m., Jan Just Keijser wrote:

Hi,

On 16/12/20 20:26, George wrote:

Hi,

   I've been looking at the code in the pppd EAP-TLS patch, but I 
can't seem to load the engine with the pkcs11 DLL. It is failing 
with the error:


error:2507606A:DSO support routines:WIN32_BIND_FUNC:could not bind 
to the requested symbol name


I've verified the path is correct.

I am using OpenSSL1.0.2u with the FIPS Object Module 2.0.16 in 
Windows 10. Do I need to do anything special to allow loading of 
DLLs in OpenSSL?


Here is what I am trying to do:

    char* engine_name = 
"C:\\Users\\whipp\\junk4\\ActivClient\\acpkcs211.dll";

    ENGINE_load_builtin_engines();
    ENGINE_register_all_complete();
    ENGINE *pkey_engine = ENGINE_by_id("dynamic");
    ENGINE_ctrl_cmd_string(pkey_engine, "SO_PATH", engine_name, 0);
    ENGINE_ctrl_cmd_string(pkey_engine, "ID", "pkcs11", 0);
    ENGINE_ctrl_cmd_string(pkey_engine, "LOAD", NULL, 0);

Do you see anything wrong with this?



I forgot to mention that loading a PKCS11 driver from within OpenSSL 
is a 2 stage rocket:


first stage:  load the engine_pkcs11 module using

    char* engine_name = "|C:\\Windows\\System32\\pkcs11.dll"|

This is a separate piece of code and is part of the libp11 project:
https://github.com/OpenSC/libp11

(it also has a nice wiki that explains how to do it on the command 
line using OPENSSL.EXE)


Then create an openssl.cnf section like this:

|openssl_conf = openssl_init [openssl_init] engines = engine_section 
[engine_section] pkcs11 = pkcs11_section [pkcs11_section] engine_id = 
pkcs11 dynamic_path = "C:\Windows\System32\opensc-pkcs11.dll" 
MODULE_path = "||C:\Users\whipp\junk4\ActivClient\acpkcs211.dll" PIN = "0001password" 
init = 0|


and load that (see the EAP-TLS code for an example or read
https://stackoverflow.com/questions/41119744/pkcs11-engine-for-openssl
for a similar question).

HTH,

JJK





On 2020-12-15 4:38 a.m., Jan Just Keijser wrote:

Hi,

On 14/12/20 21:01, George wrote:
Ok, so I am not actually going to populate EVP_PKEY with a private 
key in the callback function:

int (*client_cert_cb)(SSL *ssl, X509 **x509, *EVP_PKEY **pkey*)?

Instead, I will call
EVP_PKEY *ENGINE_load_private_key(ENGINE *e, const char *key_id, 
UI_METHOD *ui_method, void *callback_data);
to get the EVP_PKEY, which will be used by OpenSSL to access the 
Smart Card.


Once I get the resulting EVP_PKEY using 
ENGINE_load_private_key(...), how do I assign it to pkey in the 
callback function?

If I had private key I would use something like
EVP_PKEY_assign_RSA(..)
Since I don't actually have a private key, should I use something 
else?


like Michael pointed out, my  eap-tls code is just an example of 
how you could handle a pkcs11 device; it does not us a callback at 
all, but my code loads the client cert+key upfront and avoids 
having to use a client callback altogether.


I guess you could also use a client callback for this (perhaps in 
combination with SSL_CTX_set_client_cert_engine()) . In that case 
you would get the (pseudo) key from the engine like this
   EVP_PKEY *engine_key = ENGINE_load_private_key(ENGINE *e, const 
char *key_id, UI_METHOD *ui_method, void *callback_data);

and then set
  pkey = _key;
and see if that works.
Note that the ENGINE_load_private_key() function *does* return a 
EVP_PKEY struct but that does not mean the entire private key is 
contained in it; a private key consists of a modulus and a private 
part (exponent, prime1, prime2, exponent1, exponent2 etc). the 
ENGINE_load_private_key() call will return a struct containing the 
modulus but not the rest. You then use the engine to do the actual 
encryption and decryption.


HTH,

JJK












Re: private key not available for client_cert_cb

2020-12-17 Thread George
Ok. So I use the libp11 project DLL file for the SO_PATH and my smart 
card middleware DLL for the MODULE_PATH when setting up the OpenSSL Engine?



Thanks,
George



On 2020-12-17 3:22 a.m., Jan Just Keijser wrote:

Hi,

On 16/12/20 20:26, George wrote:

Hi,

   I've been looking at the code in the pppd EAP-TLS patch, but I 
can't seem to load the engine with the pkcs11 DLL. It is failing with 
the error:


error:2507606A:DSO support routines:WIN32_BIND_FUNC:could not bind to 
the requested symbol name


I've verified the path is correct.

I am using OpenSSL1.0.2u with the FIPS Object Module 2.0.16 in 
Windows 10. Do I need to do anything special to allow loading of DLLs 
in OpenSSL?


Here is what I am trying to do:

    char* engine_name = 
"C:\\Users\\whipp\\junk4\\ActivClient\\acpkcs211.dll";

    ENGINE_load_builtin_engines();
    ENGINE_register_all_complete();
    ENGINE *pkey_engine = ENGINE_by_id("dynamic");
    ENGINE_ctrl_cmd_string(pkey_engine, "SO_PATH", engine_name, 0);
    ENGINE_ctrl_cmd_string(pkey_engine, "ID", "pkcs11", 0);
    ENGINE_ctrl_cmd_string(pkey_engine, "LOAD", NULL, 0);

Do you see anything wrong with this?



I forgot to mention that loading a PKCS11 driver from within OpenSSL 
is a 2 stage rocket:


first stage:  load the engine_pkcs11 module using

    char* engine_name = "|C:\\Windows\\System32\\pkcs11.dll"|

This is a separate piece of code and is part of the libp11 project:
https://github.com/OpenSC/libp11

(it also has a nice wiki that explains how to do it on the command 
line using OPENSSL.EXE)


Then create an openssl.cnf section like this:

|openssl_conf = openssl_init [openssl_init] engines = engine_section 
[engine_section] pkcs11 = pkcs11_section [pkcs11_section] engine_id = 
pkcs11 dynamic_path = "C:\Windows\System32\opensc-pkcs11.dll" 
MODULE_path = "||C:\Users\whipp\junk4\ActivClient\acpkcs211.dll" PIN = "0001password" 
init = 0|


and load that (see the EAP-TLS code for an example or read
https://stackoverflow.com/questions/41119744/pkcs11-engine-for-openssl
for a similar question).

HTH,

JJK





On 2020-12-15 4:38 a.m., Jan Just Keijser wrote:

Hi,

On 14/12/20 21:01, George wrote:
Ok, so I am not actually going to populate EVP_PKEY with a private 
key in the callback function:

int (*client_cert_cb)(SSL *ssl, X509 **x509, *EVP_PKEY **pkey*)?

Instead, I will call
EVP_PKEY *ENGINE_load_private_key(ENGINE *e, const char *key_id, 
UI_METHOD *ui_method, void *callback_data);
to get the EVP_PKEY, which will be used by OpenSSL to access the 
Smart Card.


Once I get the resulting EVP_PKEY using 
ENGINE_load_private_key(...), how do I assign it to pkey in the 
callback function?

If I had private key I would use something like
EVP_PKEY_assign_RSA(..)
Since I don't actually have a private key, should I use something else?

like Michael pointed out, my  eap-tls code is just an example of how 
you could handle a pkcs11 device; it does not us a callback at all, 
but my code loads the client cert+key upfront and avoids having to 
use a client callback altogether.


I guess you could also use a client callback for this (perhaps in 
combination with SSL_CTX_set_client_cert_engine()) . In that case 
you would get the (pseudo) key from the engine like this
   EVP_PKEY *engine_key = ENGINE_load_private_key(ENGINE *e, const 
char *key_id, UI_METHOD *ui_method, void *callback_data);

and then set
  pkey = _key;
and see if that works.
Note that the ENGINE_load_private_key() function *does* return a 
EVP_PKEY struct but that does not mean the entire private key is 
contained in it; a private key consists of a modulus and a private 
part (exponent, prime1, prime2, exponent1, exponent2 etc). the 
ENGINE_load_private_key() call will return a struct containing the 
modulus but not the rest. You then use the engine to do the actual 
encryption and decryption.


HTH,

JJK










Re: private key not available for client_cert_cb

2020-12-17 Thread Jan Just Keijser

Hi,

On 16/12/20 20:26, George wrote:

Hi,

   I've been looking at the code in the pppd EAP-TLS patch, but I 
can't seem to load the engine with the pkcs11 DLL. It is failing with 
the error:


error:2507606A:DSO support routines:WIN32_BIND_FUNC:could not bind to 
the requested symbol name


I've verified the path is correct.

I am using OpenSSL1.0.2u with the FIPS Object Module 2.0.16  in 
Windows 10. Do I need to do anything special to allow loading of DLLs 
in OpenSSL?


Here is what I am trying to do:

    char* engine_name = 
"C:\\Users\\whipp\\junk4\\ActivClient\\acpkcs211.dll";

    ENGINE_load_builtin_engines();
    ENGINE_register_all_complete();
    ENGINE *pkey_engine = ENGINE_by_id("dynamic");
    ENGINE_ctrl_cmd_string(pkey_engine, "SO_PATH", engine_name, 0);
    ENGINE_ctrl_cmd_string(pkey_engine, "ID", "pkcs11", 0);
    ENGINE_ctrl_cmd_string(pkey_engine, "LOAD", NULL, 0);

Do you see anything wrong with this?



I forgot to mention that loading a PKCS11 driver from within OpenSSL is 
a 2 stage rocket:


first stage:  load the engine_pkcs11 module using

    char* engine_name = "|C:\\Windows\\System32\\pkcs11.dll"|

This is a separate piece of code and is part of the libp11 project:
  https://github.com/OpenSC/libp11

(it also has a nice wiki that explains how to do it on the command line 
using OPENSSL.EXE)


Then create an openssl.cnf section like this:

|openssl_conf = openssl_init [openssl_init] engines = engine_section 
[engine_section] pkcs11 = pkcs11_section [pkcs11_section] engine_id = 
pkcs11 dynamic_path = "C:\Windows\System32\opensc-pkcs11.dll" 
MODULE_path = "||C:\Users\whipp\junk4\ActivClient\acpkcs211.dll" PIN = "0001password" 
init = 0|



and load that (see the EAP-TLS code for an example or read
https://stackoverflow.com/questions/41119744/pkcs11-engine-for-openssl
for a similar question).

HTH,

JJK





On 2020-12-15 4:38 a.m., Jan Just Keijser wrote:

Hi,

On 14/12/20 21:01, George wrote:
Ok, so I am not actually going to populate EVP_PKEY with a private 
key in the callback function:

int (*client_cert_cb)(SSL *ssl, X509 **x509, *EVP_PKEY **pkey*)?

Instead, I will call
EVP_PKEY *ENGINE_load_private_key(ENGINE *e, const char *key_id, 
UI_METHOD *ui_method, void *callback_data);
to get the EVP_PKEY, which will be used by OpenSSL to access the 
Smart Card.


Once I get the resulting EVP_PKEY using 
ENGINE_load_private_key(...), how do I assign it to pkey in the 
callback function?

If I had private key I would use something like
EVP_PKEY_assign_RSA(..)
Since I don't actually have a private key, should I use something else?

like Michael pointed out, my  eap-tls code is just an example of how 
you could handle a pkcs11 device; it does not us a callback at all, 
but my code loads the client cert+key upfront and avoids having to 
use a client callback altogether.


I guess you could also use a client callback for this (perhaps in 
combination with SSL_CTX_set_client_cert_engine()) . In that case you 
would get the (pseudo) key from the engine like this
   EVP_PKEY *engine_key = ENGINE_load_private_key(ENGINE *e, const 
char *key_id, UI_METHOD *ui_method, void *callback_data);

and then set
  pkey = _key;
and see if that works.
Note that the ENGINE_load_private_key() function *does* return a 
EVP_PKEY struct but that does not mean the entire private key is 
contained in it; a private key consists of a modulus and a private 
part (exponent, prime1, prime2, exponent1, exponent2 etc). the 
ENGINE_load_private_key() call will return a struct containing the 
modulus but not the rest. You then use the engine to do the actual 
encryption and decryption.


HTH,

JJK








Re: private key not available for client_cert_cb

2020-12-16 Thread George

Hi,

   I've been looking at the code in the pppd EAP-TLS patch, but I can't 
seem to load the engine with the pkcs11 DLL. It is failing with the error:


error:2507606A:DSO support routines:WIN32_BIND_FUNC:could not bind to 
the requested symbol name


I've verified the path is correct.

I am using OpenSSL1.0.2u with the FIPS Object Module 2.0.16  in Windows 
10. Do I need to do anything special to allow loading of DLLs in OpenSSL?


Here is what I am trying to do:

    char* engine_name = 
"C:\\Users\\whipp\\junk4\\ActivClient\\acpkcs211.dll";

    ENGINE_load_builtin_engines();
    ENGINE_register_all_complete();
    ENGINE *pkey_engine = ENGINE_by_id("dynamic");
    ENGINE_ctrl_cmd_string(pkey_engine, "SO_PATH", engine_name, 0);
    ENGINE_ctrl_cmd_string(pkey_engine, "ID", "pkcs11", 0);
    ENGINE_ctrl_cmd_string(pkey_engine, "LOAD", NULL, 0);

Do you see anything wrong with this?


Thanks,
George

On 2020-12-15 4:38 a.m., Jan Just Keijser wrote:

Hi,

On 14/12/20 21:01, George wrote:
Ok, so I am not actually going to populate EVP_PKEY with a private 
key in the callback function:

int (*client_cert_cb)(SSL *ssl, X509 **x509, *EVP_PKEY **pkey*)?

Instead, I will call
EVP_PKEY *ENGINE_load_private_key(ENGINE *e, const char *key_id, 
UI_METHOD *ui_method, void *callback_data);
to get the EVP_PKEY, which will be used by OpenSSL to access the 
Smart Card.


Once I get the resulting EVP_PKEY using ENGINE_load_private_key(...), 
how do I assign it to pkey in the callback function?

If I had private key I would use something like
EVP_PKEY_assign_RSA(..)
Since I don't actually have a private key, should I use something else?

like Michael pointed out, my  eap-tls code is just an example of how 
you could handle a pkcs11 device; it does not us a callback at all, 
but my code loads the client cert+key upfront and avoids having to use 
a client callback altogether.


I guess you could also use a client callback for this (perhaps in 
combination with SSL_CTX_set_client_cert_engine()) . In that case you 
would get the (pseudo) key from the engine like this
   EVP_PKEY *engine_key = ENGINE_load_private_key(ENGINE *e, const 
char *key_id, UI_METHOD *ui_method, void *callback_data);

and then set
  pkey = _key;
and see if that works.
Note that the ENGINE_load_private_key() function *does* return a 
EVP_PKEY struct but that does not mean the entire private key is 
contained in it; a private key consists of a modulus and a private 
part (exponent, prime1, prime2, exponent1, exponent2 etc). the 
ENGINE_load_private_key() call will return a struct containing the 
modulus but not the rest. You then use the engine to do the actual 
encryption and decryption.


HTH,

JJK






Re: private key not available for client_cert_cb

2020-12-15 Thread Jan Just Keijser

Hi,

On 14/12/20 21:01, George wrote:
Ok, so I am not actually going to populate EVP_PKEY with a private key 
in the callback function:

int (*client_cert_cb)(SSL *ssl, X509 **x509, *EVP_PKEY **pkey*)?

Instead, I will call
EVP_PKEY *ENGINE_load_private_key(ENGINE *e, const char *key_id, 
UI_METHOD *ui_method, void *callback_data);
to get the EVP_PKEY, which will be used by OpenSSL to access the Smart 
Card.


Once I get the resulting EVP_PKEY using ENGINE_load_private_key(...), 
how do I assign it to pkey in the callback function?

If I had private key I would use something like
EVP_PKEY_assign_RSA(..)
Since I don't actually have a private key, should I use something else?

like Michael pointed out, my  eap-tls code is just an example of how you 
could handle a pkcs11 device; it does not us a callback at all, but my 
code loads the client cert+key upfront and avoids having to use a client 
callback altogether.


I guess you could also use a client callback for this (perhaps in 
combination with SSL_CTX_set_client_cert_engine()) . In that case you 
would get the (pseudo) key from the engine like this
   EVP_PKEY *engine_key = ENGINE_load_private_key(ENGINE *e, const char 
*key_id, UI_METHOD *ui_method, void *callback_data);

and then set
  pkey = _key;
and see if that works.
Note that the ENGINE_load_private_key() function *does* return a 
EVP_PKEY struct but that does not mean the entire private key is 
contained in it; a private key consists of a modulus and a private part 
(exponent, prime1, prime2, exponent1, exponent2 etc). the 
ENGINE_load_private_key() call will return a struct containing the 
modulus but not the rest. You then use the engine to do the actual 
encryption and decryption.


HTH,

JJK





Thanks,
George


On 2020-12-14 12:59 p.m., Michael Wojcik wrote:


You can't get the private key from the smartcard. Instead, you have to let the 
engine do the encryption. I don't know what ENGINE_load_private_key actually 
does - in my PKCS#11 work I didn't have to get into this - but I suspect it 
just puts a key identifier into pkey.

Then what ought to happen is that you pass that pkey to OpenSSL where you need an 
EVP_PKEY, and OpenSSL will call the engine's appropriate method for whatever it needs to 
do, and the engine will tell the smartcard "do this thing using the key with this 
identifier".

I suggest you refer to a example such as the PPP code that Jan cited to see how 
it does this sort of thing.

Or you can take the approach that Paul suggests in his reply of writing your 
own engine specifically for your hardware, if you don't need generic PKCS#11 
support. Basically, PKCS#11 gives you support for more devices, and in 
principle should do some of the work for you; but as Paul suggests, the PKCS#11 
API and its dependence on external drivers and libraries means it's not easy to 
work with. In some cases where you only need to support one type of device (or 
a family of devices that all use the same driver / library) it might well be 
easier to just write a simple engine that only supports the features you need. 
You can use the source for the existing engines in OpenSSL to get an idea of 
what that looks like.

A few years back I forked the OpenSSL CAPI engine to make some fixes and 
enhancements, and that was pretty straightforward.

So if you have a well-documented API for your particular smartcard, with handy functions 
like "do this to get an RSA signature of a blob of data with this key ID and these 
parameters", you may want to try Paul's route. Really depends on your requirements 
and what kind of support you already have for your device.

And all of this changes in 3.0 with the new "provider" architecture, so you'll 
get to take another crack at it soon.

--
Michael Wojcik






RE: private key not available for client_cert_cb

2020-12-14 Thread Michael Wojcik
> From: openssl-users  On Behalf Of George
> Sent: Monday, 14 December, 2020 13:01

> Once I get  the resulting EVP_PKEY using ENGINE_load_private_key(...),
> how do I assign it to pkey in the callback function?

I don't know offhand. As I said in my other message, that's not an area I had 
to get into when I was working with PKCS#11 some years ago.

My advice is to look at existing examples, such as the code Jan pointed you to.

--
Michael Wojcik


Re: private key not available for client_cert_cb

2020-12-14 Thread George
Ok, so I am not actually going to populate EVP_PKEY with a private key 
in the callback function:

int (*client_cert_cb)(SSL *ssl, X509 **x509, *EVP_PKEY **pkey*)?

Instead, I will call
EVP_PKEY *ENGINE_load_private_key(ENGINE *e, const char *key_id, 
UI_METHOD *ui_method, void *callback_data);

to get the EVP_PKEY, which will be used by OpenSSL to access the Smart Card.

Once I get the resulting EVP_PKEY using ENGINE_load_private_key(...), 
how do I assign it to pkey in the callback function?

If I had private key I would use something like
EVP_PKEY_assign_RSA(..)
Since I don't actually have a private key, should I use something else?



Thanks,
George


On 2020-12-14 12:59 p.m., Michael Wojcik wrote:


You can't get the private key from the smartcard. Instead, you have to let the 
engine do the encryption. I don't know what ENGINE_load_private_key actually 
does - in my PKCS#11 work I didn't have to get into this - but I suspect it 
just puts a key identifier into pkey.

Then what ought to happen is that you pass that pkey to OpenSSL where you need an 
EVP_PKEY, and OpenSSL will call the engine's appropriate method for whatever it needs to 
do, and the engine will tell the smartcard "do this thing using the key with this 
identifier".

I suggest you refer to a example such as the PPP code that Jan cited to see how 
it does this sort of thing.

Or you can take the approach that Paul suggests in his reply of writing your 
own engine specifically for your hardware, if you don't need generic PKCS#11 
support. Basically, PKCS#11 gives you support for more devices, and in 
principle should do some of the work for you; but as Paul suggests, the PKCS#11 
API and its dependence on external drivers and libraries means it's not easy to 
work with. In some cases where you only need to support one type of device (or 
a family of devices that all use the same driver / library) it might well be 
easier to just write a simple engine that only supports the features you need. 
You can use the source for the existing engines in OpenSSL to get an idea of 
what that looks like.

A few years back I forked the OpenSSL CAPI engine to make some fixes and 
enhancements, and that was pretty straightforward.

So if you have a well-documented API for your particular smartcard, with handy functions 
like "do this to get an RSA signature of a blob of data with this key ID and these 
parameters", you may want to try Paul's route. Really depends on your requirements 
and what kind of support you already have for your device.

And all of this changes in 3.0 with the new "provider" architecture, so you'll 
get to take another crack at it soon.

--
Michael Wojcik




RE: private key not available for client_cert_cb

2020-12-14 Thread Michael Wojcik
> From: openssl-users  On Behalf Of George
> Sent: Monday, 14 December, 2020 09:36

>   I see what you mean. So once I have everything setup, i use the following
> to get the private key:
> EVP_PKEY *pkey = ENGINE_load_private_key(...);
>
> Will pkey actually contain the private key from the smart card?

It had better not.

> I thought it was not possible to get a private key from a smart card?

That's the point of the smartcard (or other HSM), yes.

> Once I have pkey, do I simply use it within the client_cert_cb callback 
> function?

You can't get the private key from the smartcard. Instead, you have to let the 
engine do the encryption. I don't know what ENGINE_load_private_key actually 
does - in my PKCS#11 work I didn't have to get into this - but I suspect it 
just puts a key identifier into pkey.

Then what ought to happen is that you pass that pkey to OpenSSL where you need 
an EVP_PKEY, and OpenSSL will call the engine's appropriate method for whatever 
it needs to do, and the engine will tell the smartcard "do this thing using the 
key with this identifier".

I suggest you refer to a example such as the PPP code that Jan cited to see how 
it does this sort of thing.

Or you can take the approach that Paul suggests in his reply of writing your 
own engine specifically for your hardware, if you don't need generic PKCS#11 
support. Basically, PKCS#11 gives you support for more devices, and in 
principle should do some of the work for you; but as Paul suggests, the PKCS#11 
API and its dependence on external drivers and libraries means it's not easy to 
work with. In some cases where you only need to support one type of device (or 
a family of devices that all use the same driver / library) it might well be 
easier to just write a simple engine that only supports the features you need. 
You can use the source for the existing engines in OpenSSL to get an idea of 
what that looks like.

A few years back I forked the OpenSSL CAPI engine to make some fixes and 
enhancements, and that was pretty straightforward.

So if you have a well-documented API for your particular smartcard, with handy 
functions like "do this to get an RSA signature of a blob of data with this key 
ID and these parameters", you may want to try Paul's route. Really depends on 
your requirements and what kind of support you already have for your device.

And all of this changes in 3.0 with the new "provider" architecture, so you'll 
get to take another crack at it soon.

--
Michael Wojcik


Re: private key not available for client_cert_cb

2020-12-14 Thread Paul Nelson
How I did this:

1) You can make up your own EVP_PKEY that uses your own engine implementation 
and attach a data ptr to it
EVP_PKEY* returnPKey;
returnPKey = EVP_PKEY_new();
if( returnPKey )
{
ENGINE* engine = ENGINE_by_id(YOUR_ENGINE_ID);
RSA* sc_rsa = RSA_new_method(engine);
if( sc_rsa )
{
// attach a reference to a structure holding 
your smart card middleware info
RSA_set_ex_data(sc_rsa, 
ENGINE_smartcard_rsa_idx_middleware(),
(void*)middleware->handle);

EVP_PKEY* pk = X509_get_pubkey( returnCert );
if( pk )
{
sc_rsa->e = BN_new();
sc_rsa->n = BN_new();
BN_copy(sc_rsa->e, pk->pkey.rsa->e);
BN_copy(sc_rsa->n, pk->pkey.rsa->n);
EVP_PKEY_free(pk);

EVP_PKEY_set1_RSA(returnPKey, sc_rsa);
RSA_free(sc_rsa);

*outCert = make this X509 from your smart 
card certificate;
*outpkey = returnPKey;
}
else
LogError("smartcards_fetch_identity can't 
get pubkey\n");
}

Then for your engine you will need some methods to configure it as follows:
void ENGINE_load_smartcard_keychain(void);
/*
 * ENGINE_tss_keychain_rsa_idx_middleware returns a ex_data index where engine 
user should store the
 *  pointer to the info needed to use the middleware
 */
int ENGINE_smartcard_rsa_idx_middleware(void);

Your ENGINE_load_smartcard_keychain method should set global values that get 
returned by ENGINE_smartcard_rsa_idx_middleware:
gMiddlewareRSAIndex = RSA_get_ex_new_index(0x1234, NULL, NULL, NULL, 
NULL);

Configure your engine filling in an RSA_METHOD structure with what you will 
need. You don’t really need all the methods in RSA_METHOD structure, and if you 
don’t need them add a stub that returns a 0. I did not need either of the 
mod_exp method or the public key encrypt and decrypt methods. I also did not 
need the verify or keygen methods. Your init and finish methods just need to 
return 1.
I set the RSA_METHOD flags to 
RSA_FLAG_FIPS_METHOD|RSA_METHOD_FLAG_NO_CHECK|RSA_FLAG_CACHE_PUBLIC 

This leaves the cipher methods for private key encrypt/decrypt and sign. The 
private key methods will be where all the work is done.  Write a function to 
perform the smartcard ‘crypt’ method and use it in private encrypt/decrypt and 
the signing methods. You will need to pay attention to padding and make sure 
you know how to pad for PKCS1 type 1.  The RSA_SSLV23_PADDING is not required 
and you can just return an error if you get called with this. 

I handle the PIN entry requirement by having the engine return a specific error 
if the PIN is needed, then handle the PIN entry in the application.  Once the 
PIN is entered and available to the middleware, I retry the connection.

The trick is to get a pointer to your middleware implementation from the 
private key engine methods like this:

my_middleware_handle =
(my_middleware_handle)RSA_get_ex_data(rsa, gMiddlewareRSAIndex);

I found that writing the engine was more straightforward that attempting to use 
PKCS11.

> On Dec 14, 2020, at 1:08 AM, George  wrote:
> 
> Hi,
> 
>I'm new to OpenSSL and am trying to set up mutual authentication in a 
> client. The client is setup with OpenSSL 1.0.2u. and the client's certificate 
> + private key is stored on a Smart Card.  When the client receives a 
> certificate request from the server during the mutual authentication 
> handshake, the OpenSSL client_cert_cb callback function is automatically 
> invoked. The problem is that client_cert_cb requires a private key. 
> Unfortunately, it is not possible to get a private key from a Smart Card. Is 
> there a way to send a certificate to the server without needing the private 
> key?
> 
> I'm setting up the callback function with:
>  
> void SSL_CTX_set_client_cert_cb(SSL_CTX *ctx, int (*client_cert_cb)(SSL *ssl, 
> X509 **x509, EVP_PKEY **pkey));
> 
> 
> Here is a sample of what my code looks like when I set this up:
> 
> SSL_CTX_set_client_cert_cb(context, openSSLClientAuthenticationCallBack);
> 
> int openSSLClientAuthenticationCallBack(SSL *ssl, X509 **x509, EVP_PKEY 
> **pkey)
> {
> . . .
> }
> 
> 
> I can access the 

Re: private key not available for client_cert_cb

2020-12-14 Thread George

Hi Michael,

   I see what you mean. So once I have everything setup, i use the 
following to get the private key:
EVP_PKEY *pkey = ENGINE_load_private_key(pkey_engine, pkey_identifier, 
transfer_pin, _data);


Will pkey actually contain the private key from the smart card? I 
thought it was not possible to get a private key from a smart card?


Once I have pkey, do I simply use it within the /client_cert_cb/ 
callback function?



Thanks,
George


On 2020-12-14 10:58 a.m., Michael Wojcik wrote:

From: openssl-users  On Behalf Of George
Sent: Monday, 14 December, 2020 08:15
   Thanks for your response. It looks like I don't already have the PPP and 
PPPD.

You don't need PPP to use a smartcard or other PKCS#11 device. Jan just 
mentioned the source as a exemplar of the interactions your code will need to 
have with OpenSSL.


Are there any other ways to get the Smart Card to work without needing to
install additional software?

Probably not.

OpenSSL's PKCS#11 Engine implements the PKCS#11 API. That API needs a way to 
talk to the particular PKCS#11-compatible hardware you're using. That means it 
needs a driver, and generally some configuration as well.

It's been a few years since I last played around with this - I got OpenSSL 
working with a NitroKey as part of a code-signing spike - but you'll need to 
investigate PKCS#11 support for your particular device. There are Open Source 
projects such as OpenSC which may give you part or all of what you need to get 
OpenSSL's PKCS#11 Engine working with your hardware.

When I did it, it wasn't trivial. I spent a couple of days on investigation and 
experimenting before I got anything working, and a couple more days making sure 
I understood the entire process and documenting procedures that worked 
consistently. (With some applications I had persistent problems such as Windows 
insisting on prompting for the device PIN instead of letting me supply it 
programmatically, but I think that was only when using Microsoft APIs rather 
than going through OpenSSL.)

If the client certificate uses a public key that corresponds to a private key 
on the smartcard, though, that's what you'll have to do. You can't use a 
certificate as a proof of identity without the corresponding private key. (Some 
HSMs and other crypto devices have support for exporting private keys, often as 
multiple shares, for backup and cloning purposes. Using that to get the private 
key for direct use defeats the whole purpose of an HSM, of course, so that 
shouldn't be used to bypass the card.)

--
Michael Wojcik




RE: private key not available for client_cert_cb

2020-12-14 Thread Michael Wojcik
> From: openssl-users  On Behalf Of George
> Sent: Monday, 14 December, 2020 08:15

>   Thanks for your response. It looks like I don't already have the PPP and 
> PPPD.

You don't need PPP to use a smartcard or other PKCS#11 device. Jan just 
mentioned the source as a exemplar of the interactions your code will need to 
have with OpenSSL.

> Are there any other ways to get the Smart Card to work without needing to
> install additional software?

Probably not.

OpenSSL's PKCS#11 Engine implements the PKCS#11 API. That API needs a way to 
talk to the particular PKCS#11-compatible hardware you're using. That means it 
needs a driver, and generally some configuration as well.

It's been a few years since I last played around with this - I got OpenSSL 
working with a NitroKey as part of a code-signing spike - but you'll need to 
investigate PKCS#11 support for your particular device. There are Open Source 
projects such as OpenSC which may give you part or all of what you need to get 
OpenSSL's PKCS#11 Engine working with your hardware.

When I did it, it wasn't trivial. I spent a couple of days on investigation and 
experimenting before I got anything working, and a couple more days making sure 
I understood the entire process and documenting procedures that worked 
consistently. (With some applications I had persistent problems such as Windows 
insisting on prompting for the device PIN instead of letting me supply it 
programmatically, but I think that was only when using Microsoft APIs rather 
than going through OpenSSL.)

If the client certificate uses a public key that corresponds to a private key 
on the smartcard, though, that's what you'll have to do. You can't use a 
certificate as a proof of identity without the corresponding private key. (Some 
HSMs and other crypto devices have support for exporting private keys, often as 
multiple shares, for backup and cloning purposes. Using that to get the private 
key for direct use defeats the whole purpose of an HSM, of course, so that 
shouldn't be used to bypass the card.)

--
Michael Wojcik


Re: private key not available for client_cert_cb

2020-12-14 Thread George

Hi Jan,

   Thanks for your response. It looks like I don't already have the PPP 
and PPPD. Do I need to download and install the following?

https://github.com/jjkeijser/ppp/tree/eap-tls

I am using OpenSSL in Windows 10 and compiled it with Visual Studio 
2019. Will this EAP-TLS code compile/work with Visual Studio in Windows?


Are there any other ways to get the Smart Card to work without needing 
to install additional software?



Thanks!
George



On 2020-12-14 3:51 a.m., Jan Just Keijser wrote:

Hi,

On 14/12/20 08:08, George wrote:

Hi,

   I'm new to OpenSSL and am trying to set up mutual authentication 
in a client. The client is setup with OpenSSL 1.0.2u. and the 
client's certificate + private key is stored on a Smart Card.  When 
the client receives a certificate request from the server during the 
mutual authentication handshake, the OpenSSL /client_cert_cb/ 
callback function is automatically invoked. The problem is that 
/client_cert_cb/ requires a private key. Unfortunately, it is not 
possible to get a private key from a Smart Card. Is there a way to 
send a certificate to the server without needing the private key?


I'm setting up the callback function with:

void SSL_CTX_set_client_cert_cb(SSL_CTX *ctx, int 
(*client_cert_cb)(SSL *ssl, X509 **x509, EVP_PKEY **pkey));



Here is a sample of what my code looks like when I set this up:

SSL_CTX_set_client_cert_cb(context, 
*openSSLClientAuthenticationCallBack*);


int *openSSLClientAuthenticationCallBack*(SSL *ssl, X509 **x509, 
EVP_PKEY **pkey)

{
. . .
}


I can access the Smart Card using the PKCS#11 interface and I'm able 
to get the certificate and sign it, etc. However, I cannot get the 
actual private key from the Smart Card.


Does anyone know how I can get around this problem?



to use a pkcs#11 smartcard you normally use the OpenSSL pkcs11 engine 
; you then do something like:


    engine_name = "pkcs11";
    ENGINE_register_all_complete();
    pkey_engine = ENGINE_by_id( "dynamic" );
    if (pkey_engine)
    {
    if (!ENGINE_ctrl_cmd_string(pkey_engine, "SO_PATH", 
engine_name, 0)

 || !ENGINE_ctrl_cmd_string(pkey_engine, "LOAD", NULL, 0))
    {
    warn( "EAP-TLS: Error loading dynamic engine '%s'", 
engine_name );

    log_ssl_errors();
    ENGINE_free(e);
    pkey_engine = NULL;
    }
    }
    }

    if (pkey_engine)
    {
    if(!ENGINE_set_default(pkey_engine, ENGINE_METHOD_ALL))
    }
    pkey_engine = eaptls_ssl_load_engine( "pkcs11" );
    pkey = ENGINE_load_private_key(pkey_engine, pkey_identifier, 
transfer_pin, _data);

    SSL_CTX_use_PrivateKey(ctx, pkey);

where "transfer_pin" is a callback UI function to query the user for 
the pkcs11 device password.


More detailed code can be found in my pppd EAP-TLS patch, file 
eap-tls.c at

https://github.com/jjkeijser/ppp/blob/eap-tls/pppd/eap-tls.c

(and search for pkey_engine)

HTH,

JJK





Re: private key not available for client_cert_cb

2020-12-14 Thread Jan Just Keijser

Hi,

On 14/12/20 08:08, George wrote:

Hi,

   I'm new to OpenSSL and am trying to set up mutual authentication in 
a client. The client is setup with OpenSSL 1.0.2u. and the client's 
certificate + private key is stored on a Smart Card.  When the client 
receives a certificate request from the server during the mutual 
authentication handshake, the OpenSSL /client_cert_cb/ callback 
function is automatically invoked. The problem is that 
/client_cert_cb/ requires a private key. Unfortunately, it is not 
possible to get a private key from a Smart Card. Is there a way to 
send a certificate to the server without needing the private key?


I'm setting up the callback function with:

void SSL_CTX_set_client_cert_cb(SSL_CTX *ctx, int 
(*client_cert_cb)(SSL *ssl, X509 **x509, EVP_PKEY **pkey));



Here is a sample of what my code looks like when I set this up:

SSL_CTX_set_client_cert_cb(context, 
*openSSLClientAuthenticationCallBack*);


int *openSSLClientAuthenticationCallBack*(SSL *ssl, X509 **x509, 
EVP_PKEY **pkey)

{
. . .
}


I can access the Smart Card using the PKCS#11 interface and I'm able 
to get the certificate and sign it, etc. However, I cannot get the 
actual private key from the Smart Card.


Does anyone know how I can get around this problem?



to use a pkcs#11 smartcard you normally use the OpenSSL pkcs11 engine ; 
you then do something like:


    engine_name = "pkcs11";
    ENGINE_register_all_complete();
    pkey_engine = ENGINE_by_id( "dynamic" );
    if (pkey_engine)
    {
    if (!ENGINE_ctrl_cmd_string(pkey_engine, "SO_PATH", 
engine_name, 0)

 || !ENGINE_ctrl_cmd_string(pkey_engine, "LOAD", NULL, 0))
    {
    warn( "EAP-TLS: Error loading dynamic engine '%s'", 
engine_name );

    log_ssl_errors();
    ENGINE_free(e);
    pkey_engine = NULL;
    }
    }
    }

    if (pkey_engine)
    {
    if(!ENGINE_set_default(pkey_engine, ENGINE_METHOD_ALL))
    }
    pkey_engine = eaptls_ssl_load_engine( "pkcs11" );
    pkey = ENGINE_load_private_key(pkey_engine, pkey_identifier, 
transfer_pin, _data);

    SSL_CTX_use_PrivateKey(ctx, pkey);

where "transfer_pin" is a callback UI function to query the user for the 
pkcs11 device password.


More detailed code can be found in my pppd EAP-TLS patch, file eap-tls.c at
  https://github.com/jjkeijser/ppp/blob/eap-tls/pppd/eap-tls.c

(and search for pkey_engine)

HTH,

JJK