Hello:

Has anyone out there had any problems interfacing OpenSSL
to a PKCS11 device? We are using the scheme outlined in
the attached post from Steven Reddie which describes how
to add function pointers that replace the standard BSafe
crypto calls. The problem is that the code that handles the
decryption of the temporary key (e.g. s3_srvr.c) always uses
the cert context's rsa_temp object rather than the one with the
custom function pointers. This logic is in turn driven by 
the setting of use_rsa_tmp to 1 in ssl3_send_server_key_exchange().
Mr. Reddie's post mentions the setting of RSA_FLAG_EXT_PKEY which I
suspect fixes this behavior but this flag does not exist in
the version of ssleay that we are using, or in openSSL 0.95.
Any pointers as to how to get this to work is greatly appreciated.

After working around the above issue by forcing use_rsa_tmp to false
I can get it to call by HSM decrypt function but then C_Decrypt() returns
"encrypted data invalid". I believe this is due to a padding mismatch
between the client which encrypts using BSafe and what the HSM expects,
but a review the of the code that generates the keys & padding mechanism
appears to be okay. Again any tips on how to resolve this are appreciated.

TIA, 

Eric Gilbertson
[EMAIL PROTECTED]

____________________________________________________________________


What I have written is only for RSA operations.  Looking at the OpenSSL
source it appears that supporting anything else would require changes to
OpenSSL.  The RSA-side of OpenSSL provides an easy way to hook-in via the
RSA_METHOD structure and the RSA_new_method function (similar hooks for DSA
et al would make extending this so much simpler).  I have written code to
allow a key to be loaded via PKCS#11 and then to be used for public/private
encrypt/decrypt operations.  Sign/Verify operations are performed by OpenSSL
by doing the digest (hash) in software and then calling
private-encrypt/public-decrypt.  It took me a while to figure things out,
but the final result is some really simple code.  Here is a general
overview:

Create your own RSA_METHOD with pointers to your own public/private
encrypt/decrypt functions, and setting flags to RSA_METHOD_FLAG_NO_CHECK.

PKCS11_get_key():
        * get a handle to the PKCS#11 key (by whatever means is appropriate
to your application)
        * create an RSA key (RSA structure) by calling RSA_new_method and
passing
           in pointer to your RSA_METHOD structure
        * get the public modulus from the PKCS#11 key, use BN_bin2bn and
store it in RSA->n
          (this is necessary for OpenSSL code to determine the size of the
key)
        * [***HACK***] set RSA->p to the handle of the PKCS#11 key
        * Set the RSA_FLAG_EXT_PKEY bit in RSA->flags
        * create an EVP_PKEY, set the type to EVP_PKEY_RSA, and set pkey.ptr
to point to your RSA structure
        * return the EVP_PKEY

public/private encrypt/decrypt functions (callbacks in your RSA_METHOD
structure):
        * get the PKCS#11 key handle from RSA->p
        * use mechanism CKM_RSA_PKCS
        * public encrypt is performed using C_Encrypt
        * public decrypt is performed using C_VerifyRecover (note 1)
        * private encrypt is performed using C_Sign (note 1)
        * private decrypt is performed using C_Decrypt
        * NOTE 1: Thanks to Dr Stephen Henson for explaining this to me.

The reason that I allow OpenSSL to do the digest and only do the
encrypt/decrypt via PKCS#11 is that SSL requires an encrypt of a
concatenated MD5 and SHA1 buffer which PKCS#11 does not allow via C_Sign, so
I chose to not do Sign/Verify as an atomic PKCS#11 operation.

I hope this helps.

Steven
______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
Development Mailing List                       [EMAIL PROTECTED]
Automated List Manager                           [EMAIL PROTECTED]

Reply via email to