PKCS#11 engine support for OpenSSL 0.9.8g ========================================= [Nov 21, 2007] This patch containing code available in OpenSolaris adds support for PKCS#11 engine into OpenSSL and implements PKCS#11 v2.20. It is to be applied against OpenSSL 0.9.8g. Your system must provide PKCS#11 backend otherwise the patch is useless. Patch can be applied like this: tar xfzv openssl-0.9.8g.tar.gz cd openssl-0.9.8g patch -p1 < ../pkcs11_engine-0.9.8g.patch.2007-11-21 It is designed to support pure acceleration for RSA, DSA, DH and all the symetric ciphers and message digest algorithms that PKCS#11 and OpenSSL share except for missing support for patented algorithms MDC2, RC3, RC5 and IDEA. It also contains experimental code for accessing RSA keys stored in pkcs#11 key stores by reference. See below for more information. You must provide the location of PKCS#11 library in your system to the configure script, eg. if you use libraries from openCryptoki project on Linux AMD64 box, run configure like this: ./config --pk11-libname=/usr/lib64/pkcs11/PKCS11_API.so To check whether newly built openssl really supports PKCS#11 it's enough to run "apps/openssl engine" and look for "(pkcs11) PKCS #11 engine support" in the output. This patch was tested on Solaris against PKCS#11 engine available from Solaris Cryptographic Framework (Solaris 10 and OpenSolaris) and also on Linux using PKCS#11 libraries from openCryptoki project (see openCryptoki website http://sourceforge.net/projects/opencryptoki for more information). Some Linux distributions even ship those libraries with the system. The patch should work on any system that is supported by OpenSSL itself and has functional PKCS#11 library. The patch contains "RSA Security Inc. PKCS #11 Cryptographic Token Interface (Cryptoki)" - files cryptoki.h, pkcs11.h, pkcs11f.h and pkcs11t.h which are copyrighted by RSA Security Inc., see pkcs11.h for more information. Other added/modified code in this patch is copyrighted by Sun Microsystems, Inc. and is released under the OpenSSL license (see LICENSE file for more information). Revisions of patch for 0.9.8 branch =================================== 2007-11-21 - update for 0.9.8g version - fixes in the draft code for "6607670 teach pkcs#11 engine how to use keys be reference" so that it doesn't coredump when the referenced key is not present 2007-10-15 - update for 0.9.8f version - update for "6607670 teach pkcs#11 engine how to use keys be reference" 2007-10-02 - draft for "6607670 teach pkcs#11 engine how to use keys be reference" - draft for "6607307 pkcs#11 engine can't read RSA private keys" 2007-09-26 - 6375348 Using pkcs11 as the SSLCryptoDevice with Apache/OpenSSL causes significant performance drop - 6573196 memory is leaked when OpenSSL is used with PKCS#11 engine 2007-05-25 - 6558630 race in OpenSSL pkcs11 engine when using symetric block ciphers 2007-05-19 - initial patch for 0.9.8e using latest OpenSolaris code Notes ===== This patch version contains not very well tested code for referencing RSA keys in keystores by labels. That code might and might not end up in OpenSolaris code base in the future. If you use this particular functionality with this patch I would be very grateful to get any feedback from you (please see my contact in the bottom). Issues ------ - can't reference public keys inside of certificates using certificate label - can't reference symetric keys - simple references in form of "pkcs11:LABEL" only are supported now. This is supposed to be changed according to discussion on pkcs11 mailing list; comma separated list of attributes is planned to be used. - getpassphrase(3c) is used for entering the PIN. This should be changed to a more general approach; to check if the process has allocated tty and use other means of entering the PIN if not. Usage ----- See examples below using Solaris's pktool(1): # list private keys (note "mycert" label. Basically, we can't generate a # pub/priv key pair with pktool(1) without creating a certificate. This should # be changed in the future). $ pktool list objtype=private Enter PIN for Sun Software PKCS#11 softtoken : Found 1 keys. Key #1 - RSA private key: mycert # this file is going to be signed $ cat test hello # sign it, note "pkcs11:mycert" private key's label $ openssl rsautl -inkey pkcs11:mycert -out test2 -in test -sign -keyform e -engine pkcs11 engine "pkcs11" set. Enter PIN: # export the certificate out of the keyring $ pktool export keystore=pkcs11 label=mycert outfile=mycert.cert outformat=pem Warning: file "mycert.cert" exists, will be overwritten. Continue with export? y # verify using OpenSSL without pkcs#11 engine and with the certificate in the # file. This is proof of concept that a file signed with key by reference is # successfully verified when stock OpenSSL is used (I didn't have public key # in the keystore, only the certificate. There is no way to reference a public # key inside of the certificate). $ openssl rsautl -verify -inkey mycert.cert -certin -in test2 hello API --- You can use ENGINE_load_public_key() and ENGINE_load_private_key() functions only. The 2nd parameter of those calls is the one to use for "pkcs11:LABEL" filename overloading. If used that way, both functions will look for the key in the available keystores. Only one such key must be present. The private key is never extracted from the keystore. See OpenSSL's engine(3) or header file openssl/engine.h for more information. Note that those functions return a pointer to EVP_PKEY structure that contains all necessary information for accesing the key by label then. The pointer can be used in other functions that work with RSA keys - X509_sign() for example. See source code in apps/ subdirectory for reference. Feedback ======== Please send feedback to security-discuss@opensolaris.org. The patch was created by Jan.Pechanec@Sun.COM from code available in OpenSolaris. Latest version should be always available on http://blogs.sun.com/janp.