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]