Greg, I'm not sure about the state of PKCS#11 support in relation to the
latest snapshot, however I can give you some answers in relation to the
latest release, OpenSSL 0.9.4.

Firstly, I work for a US company and I am unsure about the current state of
the export restrictions, and therefore whether or not I can provide source
code.  Can someone who has kept up-to-date with this please fill me in?  The
code that I have written requires no changes to the OpenSSL code so perhaps
it is possible for me to give you the additional source.

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
--
Steven Reddie <[EMAIL PROTECTED]>
Senior Software Developer
OpenDirectory Lab, Computer Associates Pty Ltd (Australia)
______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
Development Mailing List                       [EMAIL PROTECTED]
Automated List Manager                           [EMAIL PROTECTED]

Reply via email to