1Index: openssl/Configure
2diff -u openssl/Configure:1.9.2.1 openssl/Configure:1.10
3--- openssl/Configure:1.9.2.1	Sun Jan 15 16:09:40 2012
4+++ openssl/Configure	Sun Jan 15 16:30:04 2012
5@@ -10,7 +10,7 @@
6 
7 # see INSTALL for instructions.
8 
9-my $usage="Usage: Configure [no-<cipher> ...] [enable-<cipher> ...] [experimental-<cipher> ...] [-Dxxx] [-lxxx] [-Lxxx] [-fxxx] [-Kxxx] [no-hw-xxx|no-hw] [[no-]threads] [[no-]shared] [[no-]zlib|zlib-dynamic] [no-asm] [no-dso] [no-krb5] [386] [--prefix=DIR] [--openssldir=OPENSSLDIR] [--with-xxx[=vvv]] [--test-sanity] os/compiler[:flags]\n";
10+my $usage="Usage: Configure --pk11-libname=PK11_LIB_LOCATION --pk11-flavor=FLAVOR [no-<cipher> ...] [enable-<cipher> ...] [experimental-<cipher> ...] [-Dxxx] [-lxxx] [-Lxxx] [-fxxx] [-Kxxx] [no-hw-xxx|no-hw] [[no-]threads] [[no-]shared] [[no-]zlib|zlib-dynamic] [no-asm] [no-dso] [no-krb5] [386] [--prefix=DIR] [--openssldir=OPENSSLDIR] [--with-xxx[=vvv]] [--test-sanity] os/compiler[:flags]\n";
11 
12 # Options:
13 #
14@@ -23,6 +23,12 @@
15 #               default).  This needn't be set in advance, you can
16 #               just as well use "make INSTALL_PREFIX=/whatever install".
17 #
18+# --pk11-libname  PKCS#11 library name.
19+#               (No default)
20+#
21+# --pk11-flavor either crypto-accelerator or sign-only
22+#               (No default)
23+#
24 # --with-krb5-dir  Declare where Kerberos 5 lives.  The libraries are expected
25 #		to live in the subdirectory lib/ and the header files in
26 #		include/.  A value is required.
27@@ -343,7 +349,7 @@
28 "linux-armv4",	"gcc:-DTERMIO -O3 -Wall::-D_REENTRANT::-ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_INT DES_UNROLL BF_PTR:${armv4_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
29 #### IA-32 targets...
30 "linux-ia32-icc",	"icc:-DL_ENDIAN -DTERMIO -O2 -no_cpprt::-D_REENTRANT::-ldl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}:dlfcn:linux-shared:-KPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
31-"linux-elf",	"gcc:-DL_ENDIAN -DTERMIO -O3 -fomit-frame-pointer -Wall::-D_REENTRANT::-ldl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
32+"linux-elf",	"gcc:-DL_ENDIAN -DTERMIO -O3 -fomit-frame-pointer -Wall::-D_REENTRANT -pthread::-ldl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
33 "linux-aout",	"gcc:-DL_ENDIAN -DTERMIO -O3 -fomit-frame-pointer -march=i486 -Wall::(unknown):::BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_asm}:a.out",
34 ####
35 "linux-generic64","gcc:-DTERMIO -O3 -Wall::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHAR RC4_CHUNK DES_INT DES_UNROLL BF_PTR:${no_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
36@@ -351,7 +357,7 @@
37 "linux-ia64",	"gcc:-DL_ENDIAN -DTERMIO -O3 -Wall::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHUNK DES_UNROLL DES_INT:${ia64_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
38 "linux-ia64-ecc","ecc:-DL_ENDIAN -DTERMIO -O2 -Wall -no_cpprt::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHUNK DES_INT:${ia64_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
39 "linux-ia64-icc","icc:-DL_ENDIAN -DTERMIO -O2 -Wall -no_cpprt::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHUNK DES_RISC1 DES_INT:${ia64_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
40-"linux-x86_64",	"gcc:-m64 -DL_ENDIAN -DTERMIO -O3 -Wall -DMD32_REG_T=int::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHUNK DES_INT DES_UNROLL:${x86_64_asm}:elf:dlfcn:linux-shared:-fPIC:-m64:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):::64",
41+"linux-x86_64",	"gcc:-m64 -DL_ENDIAN -DTERMIO -O3 -Wall -DMD32_REG_T=int::-D_REENTRANT -pthread::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHUNK DES_INT DES_UNROLL:${x86_64_asm}:elf:dlfcn:linux-shared:-fPIC:-m64:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):::64",
42 "linux-s390x",	"gcc:-m64 -DB_ENDIAN -DTERMIO -O3 -Wall::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHAR RC4_CHUNK DES_INT DES_UNROLL:${s390x_asm}:dlfcn:linux-shared:-fPIC:-m64:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):::64",
43 #### SPARC Linux setups
44 # Ray Miller <ray.miller@computing-services.oxford.ac.uk> has patiently
45@@ -622,6 +628,10 @@
46 my $idx_arflags = $idx++;
47 my $idx_multilib = $idx++;
48 
49+# PKCS#11 engine patch
50+my $pk11_libname="";
51+my $pk11_flavor="";
52+
53 my $prefix="";
54 my $libdir="";
55 my $openssldir="";
56@@ -824,6 +834,14 @@
57 				{
58 				$flags.=$_." ";
59 				}
60+			elsif (/^--pk11-libname=(.*)$/)
61+				{
62+				$pk11_libname=$1;
63+				}
64+			elsif (/^--pk11-flavor=(.*)$/)
65+				{
66+				$pk11_flavor=$1;
67+				}
68 			elsif (/^--prefix=(.*)$/)
69 				{
70 				$prefix=$1;
71@@ -961,6 +979,22 @@
72 	exit 0;
73 }
74 
75+if (! $pk11_libname)
76+        {
77+        print STDERR "You must set --pk11-libname for PKCS#11 library.\n";
78+        print STDERR "See README.pkcs11 for more information.\n";
79+        exit 1;
80+        }
81+
82+if (! $pk11_flavor
83+    || !($pk11_flavor eq "crypto-accelerator" || $pk11_flavor eq "sign-only"))
84+	{
85+	print STDERR "You must set --pk11-flavor.\n";
86+	print STDERR "Choices are crypto-accelerator and sign-only.\n";
87+	print STDERR "See README.pkcs11 for more information.\n";
88+	exit 1;
89+	}
90+
91 if ($target =~ m/^CygWin32(-.*)$/) {
92 	$target = "Cygwin".$1;
93 }
94@@ -1036,6 +1070,25 @@
95 	$exp_cflags .= " -DOPENSSL_EXPERIMENTAL_$ALGO";
96 	}
97 
98+if ($pk11_flavor eq "crypto-accelerator")
99+	{
100+	$openssl_other_defines .= "#define OPENSSL_NO_HW_PKCS11SO\n";
101+	$default_depflags .= " -DOPENSSL_NO_HW_PKCS11SO";
102+	$depflags .= " -DOPENSSL_NO_HW_PKCS11SO";
103+	$options .= " no-hw-pkcs11so";
104+	print "    no-hw-pkcs11so  [pk11-flavor]";
105+	print " OPENSSL_NO_HW_PKCS11SO\n";
106+	}
107+else
108+	{
109+	$openssl_other_defines .= "#define OPENSSL_NO_HW_PKCS11CA\n";
110+	$default_depflags .= " -DOPENSSL_NO_HW_PKCS11CA";
111+	$depflags .= " -DOPENSSL_NO_HW_PKCS11CA";
112+	$options .= " no-hw-pkcs11ca";
113+	print "    no-hw-pkcs11ca  [pk11-flavor]";
114+	print " OPENSSL_NO_HW_PKCS11CA\n";
115+}
116+
117 my $IsMK1MF=scalar grep /^$target$/,@MK1MF_Builds;
118 
119 $exe_ext=".exe" if ($target eq "Cygwin" || $target eq "DJGPP" || $target =~ /^mingw/);
120@@ -1123,6 +1176,8 @@
121 if ($flags ne "")	{ $cflags="$flags$cflags"; }
122 else			{ $no_user_cflags=1;       }
123 
124+$cflags="-DPK11_LIB_LOCATION=\"$pk11_libname\" $cflags";
125+
126 # Kerberos settings.  The flavor must be provided from outside, either through
127 # the script "config" or manually.
128 if (!$no_krb5)
129@@ -1492,6 +1547,7 @@
130 	s/^VERSION=.*/VERSION=$version/;
131 	s/^MAJOR=.*/MAJOR=$major/;
132 	s/^MINOR=.*/MINOR=$minor/;
133+	s/^PK11_LIB_LOCATION=.*/PK11_LIB_LOCATION=$pk11_libname/;
134 	s/^SHLIB_VERSION_NUMBER=.*/SHLIB_VERSION_NUMBER=$shlib_version_number/;
135 	s/^SHLIB_VERSION_HISTORY=.*/SHLIB_VERSION_HISTORY=$shlib_version_history/;
136 	s/^SHLIB_MAJOR=.*/SHLIB_MAJOR=$shlib_major/;
137Index: openssl/Makefile.org
138diff -u openssl/Makefile.org:1.5.2.1 openssl/Makefile.org:1.5
139--- openssl/Makefile.org:1.5.2.1	Sun Jan 15 16:09:41 2012
140+++ openssl/Makefile.org	Mon Jun 13 17:13:25 2011
141@@ -26,6 +26,9 @@
142 INSTALL_PREFIX=
143 INSTALLTOP=/usr/local/ssl
144 
145+# You must set this through --pk11-libname configure option.
146+PK11_LIB_LOCATION=
147+
148 # Do not edit this manually. Use Configure --openssldir=DIR do change this!
149 OPENSSLDIR=/usr/local/ssl
150 
151Index: openssl/README.pkcs11
152diff -u /dev/null openssl/README.pkcs11:1.7
153--- /dev/null	Mon Jan 16 18:54:22 2012
154+++ openssl/README.pkcs11	Mon Jun 13 18:27:17 2011
155@@ -0,0 +1,261 @@
156+ISC modified
157+============
158+
159+The previous key naming scheme was kept for backward compatibility.
160+
161+The PKCS#11 engine exists in two flavors, crypto-accelerator and
162+sign-only. The first one is from the Solaris patch and uses the
163+PKCS#11 device for all crypto operations it supports. The second
164+is a stripped down version which provides only the useful
165+function (i.e., signature with a RSA private key in the device
166+protected key store and key loading).
167+
168+As a hint PKCS#11 boards should use the crypto-accelerator flavor,
169+external PKCS#11 devices the sign-only. SCA 6000 is an example
170+of the first, AEP Keyper of the second.
171+
172+Note it is mandatory to set a pk11-flavor (and only one) in
173+config/Configure.
174+
175+PKCS#11 engine support for OpenSSL 0.9.8l
176+=========================================
177+
178+[Nov 19, 2009]
179+
180+Contents:
181+
182+Overview
183+Revisions of the patch for 0.9.8 branch
184+FAQs
185+Feedback
186+
187+Overview
188+========
189+
190+This patch containing code available in OpenSolaris adds support for PKCS#11
191+engine into OpenSSL and implements PKCS#11 v2.20. It is to be applied against
192+OpenSSL 0.9.8l source code distribution as shipped by OpenSSL.Org. Your system
193+must provide PKCS#11 backend otherwise the patch is useless. You provide the
194+PKCS#11 library name during the build configuration phase, see below.
195+
196+Patch can be applied like this:
197+
198+	# NOTE: use gtar if on Solaris
199+	tar xfzv openssl-0.9.8l.tar.gz
200+	# now download the patch to the current directory
201+	# ...
202+	cd openssl-0.9.8l
203+	# NOTE: must use gpatch if on Solaris (is part of the system)
204+	patch -p1 < path-to/pkcs11_engine-0.9.8l.patch.2009-11-19
205+
206+It is designed to support pure acceleration for RSA, DSA, DH and all the
207+symetric ciphers and message digest algorithms that PKCS#11 and OpenSSL share
208+except for missing support for patented algorithms MDC2, RC3, RC5 and IDEA.
209+
210+According to the PKCS#11 providers installed on your machine, it can support
211+following mechanisms:
212+
213+	RSA, DSA, DH, RAND, DES-CBC, DES-EDE3-CBC, DES-ECB, DES-EDE3, RC4,
214+	AES-128-CBC, AES-192-CBC, AES-256-CBC, AES-128-ECB, AES-192-ECB,
215+	AES-256-ECB, AES-128-CTR, AES-192-CTR, AES-256-CTR, MD5, SHA1, SHA224,
216+	SHA256, SHA384, SHA512
217+
218+Note that for AES counter mode the application must provide their own EVP
219+functions since OpenSSL doesn't support counter mode through EVP yet. You may
220+see OpenSSH source code (cipher.c) to get the idea how to do that. SunSSH is an
221+example of code that uses the PKCS#11 engine and deals with the fork-safety
222+problem (see engine.c and packet.c files if interested).
223+
224+You must provide the location of PKCS#11 library in your system to the
225+configure script. You will be instructed to do that when you try to run the
226+config script:
227+
228+	$ ./config 
229+	Operating system: i86pc-whatever-solaris2
230+	Configuring for solaris-x86-cc
231+	You must set --pk11-libname for PKCS#11 library.
232+	See README.pkcs11 for more information.
233+
234+Taking openCryptoki project on Linux AMD64 box as an example, you would run
235+configure script like this:
236+
237+	./config --pk11-libname=/usr/lib64/pkcs11/PKCS11_API.so
238+
239+To check whether newly built openssl really supports PKCS#11 it's enough to run
240+"apps/openssl engine" and look for "(pkcs11) PKCS #11 engine support" in the
241+output. If you see no PKCS#11 engine support check that the built openssl binary
242+and the PKCS#11 library from --pk11-libname don't conflict on 32/64 bits.
243+
244+The patch, during various phases of development, was tested on Solaris against
245+PKCS#11 engine available from Solaris Cryptographic Framework (Solaris 10 and
246+OpenSolaris) and also on Linux using PKCS#11 libraries from openCryptoki project
247+(see openCryptoki website http://sourceforge.net/projects/opencryptoki for more
248+information). Some Linux distributions even ship those libraries with the
249+system. The patch should work on any system that is supported by OpenSSL itself
250+and has functional PKCS#11 library.
251+
252+The patch contains "RSA Security Inc. PKCS #11 Cryptographic Token Interface
253+(Cryptoki)" - files cryptoki.h, pkcs11.h, pkcs11f.h and pkcs11t.h which are
254+copyrighted by RSA Security Inc., see pkcs11.h for more information.
255+
256+Other added/modified code in this patch is copyrighted by Sun Microsystems,
257+Inc. and is released under the OpenSSL license (see LICENSE file for more
258+information).
259+
260+Revisions of the patch for 0.9.8 branch
261+=======================================
262+
263+2009-11-19
264+- adjusted for OpenSSL version 0.9.8l
265+
266+- bugs and RFEs:
267+
268+	6479874 OpenSSL should support RSA key by reference/hardware keystores
269+	6896677 PKCS#11 engine's hw_pk11_err.h needs to be split
270+	6732677 make check to trigger Solaris specific code automatic in the
271+		PKCS#11 engine
272+
273+2009-03-11
274+- adjusted for OpenSSL version 0.9.8j 
275+
276+- README.pkcs11 moved out of the patch, and is shipped together with it in a
277+  tarball instead so that it can be read before the patch is applied.
278+
279+- fixed bugs:
280+
281+	6804216 pkcs#11 engine should support a key length range for RC4
282+	6734038 Apache SSL web server using the pkcs11 engine fails to start if
283+		meta slot is disabled
284+
285+2008-12-02
286+- fixed bugs and RFEs (most of the work done by Vladimir Kotal)
287+
288+	6723504 more granular locking in PKCS#11 engine
289+	6667128 CRYPTO_LOCK_PK11_ENGINE assumption does not hold true
290+	6710420 PKCS#11 engine source should be lint clean
291+	6747327 PKCS#11 engine atfork handlers need to be aware of guys who take
292+		it seriously
293+	6746712 PKCS#11 engine source code should be cstyle clean
294+	6731380 return codes of several functions are not checked in the PKCS#11
295+		engine code
296+	6746735 PKCS#11 engine should use extended FILE space API
297+	6734038 Apache SSL web server using the pkcs11 engine fails to start if
298+		meta slot is disabled
299+
300+2008-08-01
301+- fixed bug
302+
303+	6731839 OpenSSL PKCS#11 engine no longer uses n2cp for symmetric ciphers
304+		and digests
305+
306+- Solaris specific code for slot selection made automatic
307+
308+2008-07-29
309+- update the patch to OpenSSL 0.9.8h version
310+- pkcs11t.h updated to the latest version:
311+
312+	6545665 make CKM_AES_CTR available to non-kernel users
313+
314+- fixed bugs in the engine code:
315+
316+	6602801 PK11_SESSION cache has to employ reference counting scheme for
317+		asymmetric key operations
318+	6605538 pkcs11 functions C_FindObjects[{Init,Final}]() not called
319+		atomically
320+	6607307 pkcs#11 engine can't read RSA private keys
321+	6652362 pk11_RSA_finish() is cutting corners
322+	6662112 pk11_destroy_{rsa,dsa,dh}_key_objects() use locking in
323+		suboptimal way
324+	6666625 pk11_destroy_{rsa,dsa,dh}_key_objects() should be more
325+		resilient to destroy failures
326+	6667273 OpenSSL engine should not use free() but OPENSSL_free()
327+	6670363 PKCS#11 engine fails to reuse existing symmetric keys
328+	6678135 memory corruption in pk11_DH_generate_key() in pkcs#11 engine
329+	6678503 DSA signature conversion in pk11_dsa_do_verify() ignores size
330+		of big numbers leading to failures
331+	6706562 pk11_DH_compute_key() returns 0 in case of failure instead of
332+		-1
333+	6706622 pk11_load_{pub,priv}key create corrupted RSA key references
334+	6707129 return values from BN_new() in pk11_DH_generate_key() are not
335+		checked
336+	6707274 DSA/RSA/DH PKCS#11 engine operations need to be resistant to
337+		structure reuse
338+	6707782 OpenSSL PKCS#11 engine pretends to be aware of
339+		OPENSSL_NO_{RSA,DSA,DH}
340+	defines but fails miserably
341+	6709966 make check_new_*() to return values to indicate cache hit/miss
342+	6705200 pk11_dh struct initialization in PKCS#11 engine is missing
343+		generate_params parameter
344+	6709513 PKCS#11 engine sets IV length even for ECB modes
345+	6728296 buffer length not initialized for C_(En|De)crypt_Final() in the
346+		PKCS#11 engine
347+	6728871 PKCS#11 engine must reset global_session in pk11_finish()
348+
349+- new features and enhancements:
350+
351+	6562155 OpenSSL pkcs#11 engine needs support for SHA224/256/384/512
352+	6685012 OpenSSL pkcs#11 engine needs support for new cipher modes
353+	6725903 OpenSSL PKCS#11 engine shouldn't use soft token for symmetric
354+		ciphers and digests
355+
356+2007-10-15
357+- update for 0.9.8f version
358+- update for "6607670 teach pkcs#11 engine how to use keys be reference"
359+
360+2007-10-02
361+- draft for "6607670 teach pkcs#11 engine how to use keys be reference"
362+- draft for "6607307 pkcs#11 engine can't read RSA private keys"
363+
364+2007-09-26
365+- 6375348 Using pkcs11 as the SSLCryptoDevice with Apache/OpenSSL causes
366+	  significant performance drop
367+- 6573196 memory is leaked when OpenSSL is used with PKCS#11 engine
368+
369+2007-05-25
370+- 6558630 race in OpenSSL pkcs11 engine when using symetric block ciphers
371+
372+2007-05-19
373+- initial patch for 0.9.8e using latest OpenSolaris code
374+
375+FAQs
376+====
377+
378+(1) my build failed on Linux distro with this error:
379+
380+../libcrypto.a(hw_pk11.o): In function `pk11_library_init':
381+hw_pk11.c:(.text+0x20f5): undefined reference to `pthread_atfork'
382+
383+Answer:
384+
385+	- don't use "no-threads" when configuring
386+	- if you didn't then OpenSSL failed to create a threaded library by
387+	  default. You may manually edit Configure and try again. Look for the
388+	  architecture that Configure printed, for example:
389+
390+Configured for linux-elf.
391+
392+	- then edit Configure, find string "linux-elf" (inluding the quotes),
393+	  and add flags to support threads to the 4th column of the 2nd string.
394+	  If you build with GCC then adding "-pthread" should be enough. With
395+	  "linux-elf" as an example, you would add " -pthread" right after
396+	  "-D_REENTRANT", like this:
397+
398+....-O3 -fomit-frame-pointer -Wall::-D_REENTRANT -pthread::-ldl:.....
399+
400+(2) I'm using MinGW/MSYS environment and get undeclared reference error for
401+pthread_atfork() function when trying to build OpenSSL with the patch.
402+
403+Answer:
404+
405+	Sorry, pthread_atfork() is not implemented in the current pthread-win32
406+	(as of Nov 2009). You can not use the patch there.
407+
408+
409+Feedback
410+========
411+
412+Please send feedback to security-discuss@opensolaris.org. The patch was
413+created by Jan.Pechanec@Sun.COM from code available in OpenSolaris.
414+
415+Latest version should be always available on http://blogs.sun.com/janp.
416+
417Index: openssl/crypto/opensslconf.h
418diff -u openssl/crypto/opensslconf.h:1.6.2.1 openssl/crypto/opensslconf.h:1.6
419--- openssl/crypto/opensslconf.h:1.6.2.1	Sun Jan 15 16:09:43 2012
420+++ openssl/crypto/opensslconf.h	Mon Jun 13 17:13:28 2011
421@@ -29,6 +29,9 @@
422 
423 #endif /* OPENSSL_DOING_MAKEDEPEND */
424 
425+#ifndef OPENSSL_THREADS
426+# define OPENSSL_THREADS
427+#endif
428 #ifndef OPENSSL_NO_DYNAMIC_ENGINE
429 # define OPENSSL_NO_DYNAMIC_ENGINE
430 #endif
431@@ -61,6 +64,8 @@
432 # endif
433 #endif
434 
435+#define OPENSSL_CPUID_OBJ
436+
437 /* crypto/opensslconf.h.in */
438 
439 /* Generate 80386 code? */
440@@ -107,7 +112,7 @@
441  * This enables code handling data aligned at natural CPU word
442  * boundary. See crypto/rc4/rc4_enc.c for further details.
443  */
444-#undef RC4_CHUNK
445+#define RC4_CHUNK unsigned long
446 #endif
447 #endif
448 
449@@ -115,7 +120,7 @@
450 /* If this is set to 'unsigned int' on a DEC Alpha, this gives about a
451  * %20 speed up (longs are 8 bytes, int's are 4). */
452 #ifndef DES_LONG
453-#define DES_LONG unsigned long
454+#define DES_LONG unsigned int
455 #endif
456 #endif
457 
458@@ -126,9 +131,9 @@
459 /* Should we define BN_DIV2W here? */
460 
461 /* Only one for the following should be defined */
462-#undef SIXTY_FOUR_BIT_LONG
463+#define SIXTY_FOUR_BIT_LONG
464 #undef SIXTY_FOUR_BIT
465-#define THIRTY_TWO_BIT
466+#undef THIRTY_TWO_BIT
467 #endif
468 
469 #if defined(HEADER_RC4_LOCL_H) && !defined(CONFIG_HEADER_RC4_LOCL_H)
470@@ -140,7 +145,7 @@
471 
472 #if defined(HEADER_BF_LOCL_H) && !defined(CONFIG_HEADER_BF_LOCL_H)
473 #define CONFIG_HEADER_BF_LOCL_H
474-#undef BF_PTR
475+#define BF_PTR2
476 #endif /* HEADER_BF_LOCL_H */
477 
478 #if defined(HEADER_DES_LOCL_H) && !defined(CONFIG_HEADER_DES_LOCL_H)
479@@ -170,7 +175,7 @@
480 /* Unroll the inner loop, this sometimes helps, sometimes hinders.
481  * Very mucy CPU dependant */
482 #ifndef DES_UNROLL
483-#undef DES_UNROLL
484+#define DES_UNROLL
485 #endif
486 
487 /* These default values were supplied by
488Index: openssl/crypto/bio/bss_file.c
489diff -u openssl/crypto/bio/bss_file.c:1.6.2.1 openssl/crypto/bio/bss_file.c:1.6
490--- openssl/crypto/bio/bss_file.c:1.6.2.1	Sun Jan 15 16:09:44 2012
491+++ openssl/crypto/bio/bss_file.c	Mon Jun 13 17:13:31 2011
492@@ -168,7 +168,7 @@
493 		{
494 		SYSerr(SYS_F_FOPEN,get_last_sys_error());
495 		ERR_add_error_data(5,"fopen('",filename,"','",mode,"')");
496-		if (errno == ENOENT)
497+		if ((errno == ENOENT) || ((*mode == 'r') && (errno == EACCES)))
498 			BIOerr(BIO_F_BIO_NEW_FILE,BIO_R_NO_SUCH_FILE);
499 		else
500 			BIOerr(BIO_F_BIO_NEW_FILE,ERR_R_SYS_LIB);
501Index: openssl/crypto/engine/Makefile
502diff -u openssl/crypto/engine/Makefile:1.8.2.1 openssl/crypto/engine/Makefile:1.8
503--- openssl/crypto/engine/Makefile:1.8.2.1	Sun Jan 15 16:09:46 2012
504+++ openssl/crypto/engine/Makefile	Tue Jun 14 21:51:32 2011
505@@ -21,12 +21,14 @@
506 	eng_table.c eng_pkey.c eng_fat.c eng_all.c \
507 	tb_rsa.c tb_dsa.c tb_ecdsa.c tb_dh.c tb_ecdh.c tb_rand.c tb_store.c \
508 	tb_cipher.c tb_digest.c tb_pkmeth.c tb_asnmth.c \
509-	eng_openssl.c eng_cnf.c eng_dyn.c eng_cryptodev.c
510+	eng_openssl.c eng_cnf.c eng_dyn.c eng_cryptodev.c \
511+	hw_pk11.c hw_pk11_pub.c hw_pk11so.c hw_pk11so_pub.c
512 LIBOBJ= eng_err.o eng_lib.o eng_list.o eng_init.o eng_ctrl.o \
513 	eng_table.o eng_pkey.o eng_fat.o eng_all.o \
514 	tb_rsa.o tb_dsa.o tb_ecdsa.o tb_dh.o tb_ecdh.o tb_rand.o tb_store.o \
515 	tb_cipher.o tb_digest.o tb_pkmeth.o tb_asnmth.o \
516-	eng_openssl.o eng_cnf.o eng_dyn.o eng_cryptodev.o
517+	eng_openssl.o eng_cnf.o eng_dyn.o eng_cryptodev.o \
518+	hw_pk11.o hw_pk11_pub.o hw_pk11so.o hw_pk11so_pub.o
519 
520 SRC= $(LIBSRC)
521 
522@@ -264,6 +266,83 @@
523 eng_table.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
524 eng_table.o: ../../include/openssl/x509_vfy.h ../cryptlib.h eng_int.h
525 eng_table.o: eng_table.c
526+hw_pk11.o: ../../e_os.h ../../include/openssl/aes.h
527+hw_pk11.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
528+hw_pk11.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
529+hw_pk11.o: ../../include/openssl/crypto.h ../../include/openssl/dh.h
530+hw_pk11.o: ../../include/openssl/dsa.h ../../include/openssl/dso.h
531+hw_pk11.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
532+hw_pk11.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
533+hw_pk11.o: ../../include/openssl/engine.h ../../include/openssl/err.h
534+hw_pk11.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
535+hw_pk11.o: ../../include/openssl/md5.h ../../include/openssl/obj_mac.h
536+hw_pk11.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
537+hw_pk11.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
538+hw_pk11.o: ../../include/openssl/pem.h ../../include/openssl/pem2.h
539+hw_pk11.o: ../../include/openssl/pkcs7.h ../../include/openssl/rand.h
540+hw_pk11.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
541+hw_pk11.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
542+hw_pk11.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
543+hw_pk11.o: ../../include/openssl/x509_vfy.h ../cryptlib.h cryptoki.h hw_pk11.c
544+hw_pk11.o: hw_pk11_err.c hw_pk11_err.h hw_pk11ca.h pkcs11.h pkcs11f.h pkcs11t.h
545+hw_pk11_pub.o: ../../e_os.h ../../include/openssl/asn1.h
546+hw_pk11_pub.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
547+hw_pk11_pub.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
548+hw_pk11_pub.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h
549+hw_pk11_pub.o: ../../include/openssl/dso.h ../../include/openssl/e_os2.h
550+hw_pk11_pub.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
551+hw_pk11_pub.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
552+hw_pk11_pub.o: ../../include/openssl/err.h ../../include/openssl/evp.h
553+hw_pk11_pub.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
554+hw_pk11_pub.o: ../../include/openssl/objects.h
555+hw_pk11_pub.o: ../../include/openssl/opensslconf.h
556+hw_pk11_pub.o: ../../include/openssl/opensslv.h
557+hw_pk11_pub.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pem.h
558+hw_pk11_pub.o: ../../include/openssl/pem2.h ../../include/openssl/pkcs7.h
559+hw_pk11_pub.o: ../../include/openssl/rand.h ../../include/openssl/rsa.h
560+hw_pk11_pub.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
561+hw_pk11_pub.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
562+hw_pk11_pub.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
563+hw_pk11_pub.o: ../cryptlib.h cryptoki.h hw_pk11_err.h hw_pk11_pub.c hw_pk11ca.h
564+hw_pk11_pub.o: pkcs11.h pkcs11f.h pkcs11t.h
565+hw_pk11so.o: ../../e_os.h ../../include/openssl/asn1.h
566+hw_pk11so.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
567+hw_pk11so.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
568+hw_pk11so.o: ../../include/openssl/dso.h ../../include/openssl/e_os2.h
569+hw_pk11so.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
570+hw_pk11so.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
571+hw_pk11so.o: ../../include/openssl/err.h ../../include/openssl/evp.h
572+hw_pk11so.o: ../../include/openssl/lhash.h ../../include/openssl/md5.h
573+hw_pk11so.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
574+hw_pk11so.o: ../../include/openssl/opensslconf.h
575+hw_pk11so.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
576+hw_pk11so.o: ../../include/openssl/pem.h ../../include/openssl/pem2.h
577+hw_pk11so.o: ../../include/openssl/pkcs7.h ../../include/openssl/rand.h
578+hw_pk11so.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
579+hw_pk11so.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
580+hw_pk11so.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
581+hw_pk11so.o: ../../include/openssl/x509_vfy.h ../cryptlib.h cryptoki.h
582+hw_pk11so.o: hw_pk11_err.c hw_pk11_err.h hw_pk11so.c hw_pk11so.h pkcs11.h
583+hw_pk11so.o: pkcs11f.h pkcs11t.h
584+hw_pk11so_pub.o: ../../e_os.h ../../include/openssl/asn1.h
585+hw_pk11so_pub.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
586+hw_pk11so_pub.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
587+hw_pk11so_pub.o: ../../include/openssl/dso.h ../../include/openssl/e_os2.h
588+hw_pk11so_pub.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
589+hw_pk11so_pub.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
590+hw_pk11so_pub.o: ../../include/openssl/err.h ../../include/openssl/evp.h
591+hw_pk11so_pub.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
592+hw_pk11so_pub.o: ../../include/openssl/objects.h
593+hw_pk11so_pub.o: ../../include/openssl/opensslconf.h
594+hw_pk11so_pub.o: ../../include/openssl/opensslv.h
595+hw_pk11so_pub.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pem.h
596+hw_pk11so_pub.o: ../../include/openssl/pem2.h ../../include/openssl/pkcs7.h
597+hw_pk11so_pub.o: ../../include/openssl/rand.h ../../include/openssl/rsa.h
598+hw_pk11so_pub.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
599+hw_pk11so_pub.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
600+hw_pk11so_pub.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
601+hw_pk11so_pub.o: ../cryptlib.h cryptoki.h hw_pk11_err.h hw_pk11so.h
602+hw_pk11so_pub.o: hw_pk11so_pub.c pkcs11.h pkcs11f.h pkcs11t.h
603 tb_asnmth.o: ../../e_os.h ../../include/openssl/asn1.h
604 tb_asnmth.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
605 tb_asnmth.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
606Index: openssl/crypto/engine/cryptoki.h
607diff -u /dev/null openssl/crypto/engine/cryptoki.h:1.4
608--- /dev/null	Mon Jan 16 18:54:23 2012
609+++ openssl/crypto/engine/cryptoki.h	Thu Dec 18 00:14:12 2008
610@@ -0,0 +1,103 @@
611+/*
612+ * CDDL HEADER START
613+ *
614+ * The contents of this file are subject to the terms of the
615+ * Common Development and Distribution License, Version 1.0 only
616+ * (the "License").  You may not use this file except in compliance
617+ * with the License.
618+ *
619+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
620+ * or http://www.opensolaris.org/os/licensing.
621+ * See the License for the specific language governing permissions
622+ * and limitations under the License.
623+ *
624+ * When distributing Covered Code, include this CDDL HEADER in each
625+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
626+ * If applicable, add the following below this CDDL HEADER, with the
627+ * fields enclosed by brackets "[]" replaced with your own identifying
628+ * information: Portions Copyright [yyyy] [name of copyright owner]
629+ *
630+ * CDDL HEADER END
631+ */
632+/*
633+ * Copyright 2003 Sun Microsystems, Inc.   All rights reserved.
634+ * Use is subject to license terms.
635+ */
636+
637+#ifndef	_CRYPTOKI_H
638+#define	_CRYPTOKI_H
639+
640+/* ident	"@(#)cryptoki.h	1.2	05/06/08 SMI" */
641+
642+#ifdef	__cplusplus
643+extern "C" {
644+#endif
645+
646+#ifndef	CK_PTR
647+#define	CK_PTR *
648+#endif
649+
650+#ifndef CK_DEFINE_FUNCTION
651+#define	CK_DEFINE_FUNCTION(returnType, name) returnType name
652+#endif
653+
654+#ifndef CK_DECLARE_FUNCTION
655+#define	CK_DECLARE_FUNCTION(returnType, name) returnType name
656+#endif
657+
658+#ifndef CK_DECLARE_FUNCTION_POINTER
659+#define	CK_DECLARE_FUNCTION_POINTER(returnType, name) returnType (* name)
660+#endif
661+
662+#ifndef CK_CALLBACK_FUNCTION
663+#define	CK_CALLBACK_FUNCTION(returnType, name) returnType (* name)
664+#endif
665+
666+#ifndef NULL_PTR
667+#include <unistd.h>	/* For NULL */
668+#define	NULL_PTR NULL
669+#endif
670+
671+/*
672+ * pkcs11t.h defines TRUE and FALSE in a way that upsets lint
673+ */
674+#ifndef	CK_DISABLE_TRUE_FALSE
675+#define	CK_DISABLE_TRUE_FALSE
676+#ifndef	TRUE
677+#define	TRUE	1
678+#endif /* TRUE */
679+#ifndef	FALSE
680+#define	FALSE	0
681+#endif /* FALSE */
682+#endif /* CK_DISABLE_TRUE_FALSE */
683+
684+#undef CK_PKCS11_FUNCTION_INFO
685+
686+#include "pkcs11.h"
687+
688+/* Solaris specific functions */
689+
690+#include <stdlib.h>
691+
692+/*
693+ * SUNW_C_GetMechSession will initialize the framework and do all
694+ * the necessary PKCS#11 calls to create a session capable of
695+ * providing operations on the requested mechanism
696+ */
697+CK_RV SUNW_C_GetMechSession(CK_MECHANISM_TYPE mech,
698+    CK_SESSION_HANDLE_PTR hSession);
699+
700+/*
701+ * SUNW_C_KeyToObject will create a secret key object for the given
702+ * mechanism from the rawkey data.
703+ */
704+CK_RV SUNW_C_KeyToObject(CK_SESSION_HANDLE hSession,
705+    CK_MECHANISM_TYPE mech, const void *rawkey, size_t rawkey_len,
706+    CK_OBJECT_HANDLE_PTR obj);
707+
708+
709+#ifdef	__cplusplus
710+}
711+#endif
712+
713+#endif	/* _CRYPTOKI_H */
714Index: openssl/crypto/engine/eng_all.c
715diff -u openssl/crypto/engine/eng_all.c:1.5.2.1 openssl/crypto/engine/eng_all.c:1.5
716--- openssl/crypto/engine/eng_all.c:1.5.2.1	Sun Jan 15 16:09:46 2012
717+++ openssl/crypto/engine/eng_all.c	Mon Jun 13 17:13:35 2011
718@@ -111,6 +111,14 @@
719 #if defined(OPENSSL_SYS_WIN32) && !defined(OPENSSL_NO_CAPIENG)
720 	ENGINE_load_capi();
721 #endif
722+#ifndef OPENSSL_NO_HW_PKCS11
723+#ifndef OPENSSL_NO_HW_PKCS11CA
724+	ENGINE_load_pk11ca();
725+#endif
726+#ifndef OPENSSL_NO_HW_PKCS11SO
727+	ENGINE_load_pk11so();
728+#endif
729+#endif
730 #endif
731 	}
732 
733Index: openssl/crypto/engine/engine.h
734diff -u openssl/crypto/engine/engine.h:1.5.2.1 openssl/crypto/engine/engine.h:1.5
735--- openssl/crypto/engine/engine.h:1.5.2.1	Sun Jan 15 16:09:46 2012
736+++ openssl/crypto/engine/engine.h	Mon Jun 13 17:13:36 2011
737@@ -336,6 +336,12 @@
738 void ENGINE_load_ubsec(void);
739 void ENGINE_load_padlock(void);
740 void ENGINE_load_capi(void);
741+#ifndef OPENSSL_NO_HW_PKCS11CA
742+void ENGINE_load_pk11ca(void);
743+#endif
744+#ifndef OPENSSL_NO_HW_PKCS11SO
745+void ENGINE_load_pk11so(void);
746+#endif
747 #ifndef OPENSSL_NO_GMP
748 void ENGINE_load_gmp(void);
749 #endif
750Index: openssl/crypto/engine/hw_pk11.c
751diff -u /dev/null openssl/crypto/engine/hw_pk11.c:1.30
752--- /dev/null	Mon Jan 16 18:54:23 2012
753+++ openssl/crypto/engine/hw_pk11.c	Thu Jun 16 12:31:53 2011
754@@ -0,0 +1,4057 @@
755+/*
756+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
757+ * Use is subject to license terms.
758+ */
759+
760+/* crypto/engine/hw_pk11.c */
761+/*
762+ * This product includes software developed by the OpenSSL Project for
763+ * use in the OpenSSL Toolkit (http://www.openssl.org/).
764+ *
765+ * This project also referenced hw_pkcs11-0.9.7b.patch written by
766+ * Afchine Madjlessi.
767+ */
768+/*
769+ * ====================================================================
770+ * Copyright (c) 2000-2001 The OpenSSL Project.  All rights reserved.
771+ *
772+ * Redistribution and use in source and binary forms, with or without
773+ * modification, are permitted provided that the following conditions
774+ * are met:
775+ *
776+ * 1. Redistributions of source code must retain the above copyright
777+ *    notice, this list of conditions and the following disclaimer.
778+ *
779+ * 2. Redistributions in binary form must reproduce the above copyright
780+ *    notice, this list of conditions and the following disclaimer in
781+ *    the documentation and/or other materials provided with the
782+ *    distribution.
783+ *
784+ * 3. All advertising materials mentioning features or use of this
785+ *    software must display the following acknowledgment:
786+ *    "This product includes software developed by the OpenSSL Project
787+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
788+ *
789+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
790+ *    endorse or promote products derived from this software without
791+ *    prior written permission. For written permission, please contact
792+ *    licensing@OpenSSL.org.
793+ *
794+ * 5. Products derived from this software may not be called "OpenSSL"
795+ *    nor may "OpenSSL" appear in their names without prior written
796+ *    permission of the OpenSSL Project.
797+ *
798+ * 6. Redistributions of any form whatsoever must retain the following
799+ *    acknowledgment:
800+ *    "This product includes software developed by the OpenSSL Project
801+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
802+ *
803+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
804+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
805+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
806+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
807+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
808+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
809+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
810+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
811+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
812+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
813+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
814+ * OF THE POSSIBILITY OF SUCH DAMAGE.
815+ * ====================================================================
816+ *
817+ * This product includes cryptographic software written by Eric Young
818+ * (eay@cryptsoft.com).  This product includes software written by Tim
819+ * Hudson (tjh@cryptsoft.com).
820+ *
821+ */
822+
823+#include <stdio.h>
824+#include <stdlib.h>
825+#include <string.h>
826+#include <sys/types.h>
827+
828+#include <openssl/e_os2.h>
829+#include <openssl/crypto.h>
830+#include <cryptlib.h>
831+#include <openssl/engine.h>
832+#include <openssl/dso.h>
833+#include <openssl/err.h>
834+#include <openssl/bn.h>
835+#include <openssl/md5.h>
836+#include <openssl/pem.h>
837+#ifndef OPENSSL_NO_RSA
838+#include <openssl/rsa.h>
839+#endif
840+#ifndef OPENSSL_NO_DSA
841+#include <openssl/dsa.h>
842+#endif
843+#ifndef OPENSSL_NO_DH
844+#include <openssl/dh.h>
845+#endif
846+#include <openssl/rand.h>
847+#include <openssl/objects.h>
848+#include <openssl/x509.h>
849+#include <openssl/aes.h>
850+
851+#ifdef OPENSSL_SYS_WIN32
852+typedef int pid_t;
853+#define getpid() GetCurrentProcessId()
854+#define NOPTHREADS
855+#ifndef NULL_PTR
856+#define NULL_PTR NULL
857+#endif
858+#define CK_DEFINE_FUNCTION(returnType, name) \
859+	returnType __declspec(dllexport) name
860+#define CK_DECLARE_FUNCTION(returnType, name) \
861+	returnType __declspec(dllimport) name
862+#define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
863+	returnType __declspec(dllimport) (* name)
864+#else
865+#include <signal.h>
866+#include <unistd.h>
867+#include <dlfcn.h>
868+#endif
869+
870+#ifndef NOPTHREADS
871+#include <pthread.h>
872+#endif
873+
874+#ifndef OPENSSL_NO_HW
875+#ifndef OPENSSL_NO_HW_PK11
876+#ifndef OPENSSL_NO_HW_PK11CA
877+
878+/* label for debug messages printed on stderr */
879+#define	PK11_DBG	"PKCS#11 ENGINE DEBUG"
880+/* prints a lot of debug messages on stderr about slot selection process */
881+/* #undef	DEBUG_SLOT_SELECTION */
882+/*
883+ * Solaris specific code. See comment at check_hw_mechanisms() for more
884+ * information.
885+ */
886+#if defined(__SVR4) && defined(__sun)
887+#undef	SOLARIS_HW_SLOT_SELECTION
888+#endif
889+
890+/*
891+ * AES counter mode is not supported in the OpenSSL EVP API yet and neither
892+ * there are official OIDs for mechanisms based on this mode. With our changes,
893+ * an application can define its own EVP calls for AES counter mode and then
894+ * it can make use of hardware acceleration through this engine. However, it's
895+ * better if we keep AES CTR support code under ifdef's.
896+ */
897+#define	SOLARIS_AES_CTR
898+
899+#ifdef OPENSSL_SYS_WIN32
900+#pragma pack(push, cryptoki, 1)
901+#include "cryptoki.h"
902+#include "pkcs11.h"
903+#pragma pack(pop, cryptoki)
904+#else
905+#include "cryptoki.h"
906+#include "pkcs11.h"
907+#endif
908+#include "hw_pk11ca.h"
909+#include "hw_pk11_err.c"
910+
911+#ifdef	SOLARIS_AES_CTR
912+/*
913+ * NIDs for AES counter mode that will be defined during the engine
914+ * initialization.
915+ */
916+static int NID_aes_128_ctr = NID_undef;
917+static int NID_aes_192_ctr = NID_undef;
918+static int NID_aes_256_ctr = NID_undef;
919+#endif	/* SOLARIS_AES_CTR */
920+
921+/*
922+ * We use this lock to prevent multiple C_Login()s, guard getpassphrase(),
923+ * uri_struct manipulation, and static token info. All of that is used by the
924+ * RSA keys by reference feature.
925+ */
926+#ifndef NOPTHREADS
927+pthread_mutex_t *token_lock;
928+#endif
929+
930+#ifdef	SOLARIS_HW_SLOT_SELECTION
931+/*
932+ * Tables for symmetric ciphers and digest mechs found in the pkcs11_kernel
933+ * library. See comment at check_hw_mechanisms() for more information.
934+ */
935+static int *hw_cnids;
936+static int *hw_dnids;
937+#endif	/* SOLARIS_HW_SLOT_SELECTION */
938+
939+/* PKCS#11 session caches and their locks for all operation types */
940+static PK11_CACHE session_cache[OP_MAX];
941+
942+/*
943+ * We cache the flags so that we do not have to run C_GetTokenInfo() again when
944+ * logging into the token.
945+ */
946+CK_FLAGS pubkey_token_flags;
947+
948+/*
949+ * As stated in v2.20, 11.7 Object Management Function, in section for
950+ * C_FindObjectsInit(), at most one search operation may be active at a given
951+ * time in a given session. Therefore, C_Find{,Init,Final}Objects() should be
952+ * grouped together to form one atomic search operation. This is already
953+ * ensured by the property of unique PKCS#11 session handle used for each
954+ * PK11_SESSION object.
955+ *
956+ * This is however not the biggest concern - maintaining consistency of the
957+ * underlying object store is more important. The same section of the spec also
958+ * says that one thread can be in the middle of a search operation while another
959+ * thread destroys the object matching the search template which would result in
960+ * invalid handle returned from the search operation.
961+ *
962+ * Hence, the following locks are used for both protection of the object stores.
963+ * They are also used for active list protection.
964+ */
965+#ifndef NOPTHREADS
966+pthread_mutex_t *find_lock[OP_MAX] = { NULL };
967+#endif
968+
969+/*
970+ * lists of asymmetric key handles which are active (referenced by at least one
971+ * PK11_SESSION structure, either held by a thread or present in free_session
972+ * list) for given algorithm type
973+ */
974+PK11_active *active_list[OP_MAX] = { NULL };
975+
976+/*
977+ * Create all secret key objects in a global session so that they are available
978+ * to use for other sessions. These other sessions may be opened or closed
979+ * without losing the secret key objects.
980+ */
981+static CK_SESSION_HANDLE	global_session = CK_INVALID_HANDLE;
982+
983+/* ENGINE level stuff */
984+static int pk11_init(ENGINE *e);
985+static int pk11_library_init(ENGINE *e);
986+static int pk11_finish(ENGINE *e);
987+static int pk11_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void));
988+static int pk11_destroy(ENGINE *e);
989+
990+/* RAND stuff */
991+static void pk11_rand_seed(const void *buf, int num);
992+static void pk11_rand_add(const void *buf, int num, double add_entropy);
993+static void pk11_rand_cleanup(void);
994+static int pk11_rand_bytes(unsigned char *buf, int num);
995+static int pk11_rand_status(void);
996+
997+/* These functions are also used in other files */
998+PK11_SESSION *pk11_get_session(PK11_OPTYPE optype);
999+void pk11_return_session(PK11_SESSION *sp, PK11_OPTYPE optype);
1000+
1001+/* active list manipulation functions used in this file */
1002+extern int pk11_active_delete(CK_OBJECT_HANDLE h, PK11_OPTYPE type);
1003+extern void pk11_free_active_list(PK11_OPTYPE type);
1004+
1005+#ifndef OPENSSL_NO_RSA
1006+int pk11_destroy_rsa_key_objects(PK11_SESSION *session);
1007+int pk11_destroy_rsa_object_pub(PK11_SESSION *sp, CK_BBOOL uselock);
1008+int pk11_destroy_rsa_object_priv(PK11_SESSION *sp, CK_BBOOL uselock);
1009+#endif
1010+#ifndef OPENSSL_NO_DSA
1011+int pk11_destroy_dsa_key_objects(PK11_SESSION *session);
1012+int pk11_destroy_dsa_object_pub(PK11_SESSION *sp, CK_BBOOL uselock);
1013+int pk11_destroy_dsa_object_priv(PK11_SESSION *sp, CK_BBOOL uselock);
1014+#endif
1015+#ifndef OPENSSL_NO_DH
1016+int pk11_destroy_dh_key_objects(PK11_SESSION *session);
1017+int pk11_destroy_dh_object(PK11_SESSION *session, CK_BBOOL uselock);
1018+#endif
1019+
1020+/* Local helper functions */
1021+static int pk11_free_all_sessions(void);
1022+static int pk11_free_session_list(PK11_OPTYPE optype);
1023+static int pk11_setup_session(PK11_SESSION *sp, PK11_OPTYPE optype);
1024+static int pk11_destroy_cipher_key_objects(PK11_SESSION *session);
1025+static int pk11_destroy_object(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE oh,
1026+	CK_BBOOL persistent);
1027+static const char *get_PK11_LIBNAME(void);
1028+static void free_PK11_LIBNAME(void);
1029+static long set_PK11_LIBNAME(const char *name);
1030+
1031+/* Symmetric cipher and digest support functions */
1032+static int cipher_nid_to_pk11(int nid);
1033+#ifdef	SOLARIS_AES_CTR
1034+static int pk11_add_NID(char *sn, char *ln);
1035+static int pk11_add_aes_ctr_NIDs(void);
1036+#endif	/* SOLARIS_AES_CTR */
1037+static int pk11_usable_ciphers(const int **nids);
1038+static int pk11_usable_digests(const int **nids);
1039+static int pk11_cipher_init(EVP_CIPHER_CTX *ctx, const unsigned char *key,
1040+	const unsigned char *iv, int enc);
1041+static int pk11_cipher_final(PK11_SESSION *sp);
1042+#if OPENSSL_VERSION_NUMBER < 0x10000000L
1043+static int pk11_cipher_do_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
1044+	const unsigned char *in, unsigned int inl);
1045+#else
1046+static int pk11_cipher_do_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
1047+	const unsigned char *in, size_t inl);
1048+#endif
1049+static int pk11_cipher_cleanup(EVP_CIPHER_CTX *ctx);
1050+static int pk11_engine_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
1051+	const int **nids, int nid);
1052+static int pk11_engine_digests(ENGINE *e, const EVP_MD **digest,
1053+	const int **nids, int nid);
1054+static CK_OBJECT_HANDLE pk11_get_cipher_key(EVP_CIPHER_CTX *ctx,
1055+	const unsigned char *key, CK_KEY_TYPE key_type, PK11_SESSION *sp);
1056+static int check_new_cipher_key(PK11_SESSION *sp, const unsigned char *key,
1057+	int key_len);
1058+static int md_nid_to_pk11(int nid);
1059+static int pk11_digest_init(EVP_MD_CTX *ctx);
1060+static int pk11_digest_update(EVP_MD_CTX *ctx, const void *data,
1061+	size_t count);
1062+static int pk11_digest_final(EVP_MD_CTX *ctx, unsigned char *md);
1063+static int pk11_digest_copy(EVP_MD_CTX *to, const EVP_MD_CTX *from);
1064+static int pk11_digest_cleanup(EVP_MD_CTX *ctx);
1065+
1066+static int pk11_choose_slots(int *any_slot_found);
1067+static void pk11_find_symmetric_ciphers(CK_FUNCTION_LIST_PTR pflist,
1068+    CK_SLOT_ID current_slot, int *current_slot_n_cipher,
1069+    int *local_cipher_nids);
1070+static void pk11_find_digests(CK_FUNCTION_LIST_PTR pflist,
1071+    CK_SLOT_ID current_slot, int *current_slot_n_digest,
1072+    int *local_digest_nids);
1073+static void pk11_get_symmetric_cipher(CK_FUNCTION_LIST_PTR, int slot_id,
1074+    CK_MECHANISM_TYPE mech, int *current_slot_n_cipher, int *local_cipher_nids,
1075+    int id);
1076+static void pk11_get_digest(CK_FUNCTION_LIST_PTR pflist, int slot_id,
1077+    CK_MECHANISM_TYPE mech, int *current_slot_n_digest, int *local_digest_nids,
1078+    int id);
1079+
1080+static int pk11_init_all_locks(void);
1081+static void pk11_free_all_locks(void);
1082+
1083+#ifdef	SOLARIS_HW_SLOT_SELECTION
1084+static int check_hw_mechanisms(void);
1085+static int nid_in_table(int nid, int *nid_table);
1086+#endif	/* SOLARIS_HW_SLOT_SELECTION */
1087+
1088+/* Index for the supported ciphers */
1089+enum pk11_cipher_id {
1090+	PK11_DES_CBC,
1091+	PK11_DES3_CBC,
1092+	PK11_DES_ECB,
1093+	PK11_DES3_ECB,
1094+	PK11_RC4,
1095+	PK11_AES_128_CBC,
1096+	PK11_AES_192_CBC,
1097+	PK11_AES_256_CBC,
1098+	PK11_AES_128_ECB,
1099+	PK11_AES_192_ECB,
1100+	PK11_AES_256_ECB,
1101+	PK11_BLOWFISH_CBC,
1102+#ifdef	SOLARIS_AES_CTR
1103+	PK11_AES_128_CTR,
1104+	PK11_AES_192_CTR,
1105+	PK11_AES_256_CTR,
1106+#endif	/* SOLARIS_AES_CTR */
1107+	PK11_CIPHER_MAX
1108+};
1109+
1110+/* Index for the supported digests */
1111+enum pk11_digest_id {
1112+	PK11_MD5,
1113+	PK11_SHA1,
1114+	PK11_SHA224,
1115+	PK11_SHA256,
1116+	PK11_SHA384,
1117+	PK11_SHA512,
1118+	PK11_DIGEST_MAX
1119+};
1120+
1121+#define	TRY_OBJ_DESTROY(sp, obj_hdl, retval, uselock, alg_type, priv)	\
1122+	{								\
1123+	if (uselock)							\
1124+		LOCK_OBJSTORE(alg_type);				\
1125+	if (pk11_active_delete(obj_hdl, alg_type) == 1)			\
1126+		{							\
1127+		  retval = pk11_destroy_object(sp->session, obj_hdl,	\
1128+		  priv ? sp->priv_persistent : sp->pub_persistent);	\
1129+		}							\
1130+	if (uselock)							\
1131+		UNLOCK_OBJSTORE(alg_type);				\
1132+	}
1133+
1134+static int cipher_nids[PK11_CIPHER_MAX];
1135+static int digest_nids[PK11_DIGEST_MAX];
1136+static int cipher_count		= 0;
1137+static int digest_count		= 0;
1138+static CK_BBOOL pk11_have_rsa	= CK_FALSE;
1139+static CK_BBOOL pk11_have_recover = CK_FALSE;
1140+static CK_BBOOL pk11_have_dsa	= CK_FALSE;
1141+static CK_BBOOL pk11_have_dh	= CK_FALSE;
1142+static CK_BBOOL pk11_have_random = CK_FALSE;
1143+
1144+typedef struct PK11_CIPHER_st
1145+	{
1146+	enum pk11_cipher_id	id;
1147+	int			nid;
1148+	int			iv_len;
1149+	int			min_key_len;
1150+	int			max_key_len;
1151+	CK_KEY_TYPE		key_type;
1152+	CK_MECHANISM_TYPE	mech_type;
1153+	} PK11_CIPHER;
1154+
1155+static PK11_CIPHER ciphers[] =
1156+	{
1157+	{ PK11_DES_CBC,		NID_des_cbc,		8,	 8,   8,
1158+		CKK_DES,	CKM_DES_CBC, },
1159+	{ PK11_DES3_CBC,	NID_des_ede3_cbc,	8,	24,  24,
1160+		CKK_DES3,	CKM_DES3_CBC, },
1161+	{ PK11_DES_ECB,		NID_des_ecb,		0,	 8,   8,
1162+		CKK_DES,	CKM_DES_ECB, },
1163+	{ PK11_DES3_ECB,	NID_des_ede3_ecb,	0,	24,  24,
1164+		CKK_DES3,	CKM_DES3_ECB, },
1165+	{ PK11_RC4,		NID_rc4,		0,	16, 256,
1166+		CKK_RC4,	CKM_RC4, },
1167+	{ PK11_AES_128_CBC,	NID_aes_128_cbc,	16,	16,  16,
1168+		CKK_AES,	CKM_AES_CBC, },
1169+	{ PK11_AES_192_CBC,	NID_aes_192_cbc,	16,	24,  24,
1170+		CKK_AES,	CKM_AES_CBC, },
1171+	{ PK11_AES_256_CBC,	NID_aes_256_cbc,	16,	32,  32,
1172+		CKK_AES,	CKM_AES_CBC, },
1173+	{ PK11_AES_128_ECB,	NID_aes_128_ecb,	0,	16,  16,
1174+		CKK_AES,	CKM_AES_ECB, },
1175+	{ PK11_AES_192_ECB,	NID_aes_192_ecb,	0,	24,  24,
1176+		CKK_AES,	CKM_AES_ECB, },
1177+	{ PK11_AES_256_ECB,	NID_aes_256_ecb,	0,	32,  32,
1178+		CKK_AES,	CKM_AES_ECB, },
1179+	{ PK11_BLOWFISH_CBC,	NID_bf_cbc,		8,	16,  16,
1180+		CKK_BLOWFISH,	CKM_BLOWFISH_CBC, },
1181+#ifdef	SOLARIS_AES_CTR
1182+	/* we don't know the correct NIDs until the engine is initialized */
1183+	{ PK11_AES_128_CTR,	NID_undef,		16,	16,  16,
1184+		CKK_AES,	CKM_AES_CTR, },
1185+	{ PK11_AES_192_CTR,	NID_undef,		16,	24,  24,
1186+		CKK_AES,	CKM_AES_CTR, },
1187+	{ PK11_AES_256_CTR,	NID_undef,		16,	32,  32,
1188+		CKK_AES,	CKM_AES_CTR, },
1189+#endif	/* SOLARIS_AES_CTR */
1190+	};
1191+
1192+typedef struct PK11_DIGEST_st
1193+	{
1194+	enum pk11_digest_id	id;
1195+	int			nid;
1196+	CK_MECHANISM_TYPE	mech_type;
1197+	} PK11_DIGEST;
1198+
1199+static PK11_DIGEST digests[] =
1200+	{
1201+	{PK11_MD5,	NID_md5,	CKM_MD5, },
1202+	{PK11_SHA1,	NID_sha1,	CKM_SHA_1, },
1203+	{PK11_SHA224,	NID_sha224,	CKM_SHA224, },
1204+	{PK11_SHA256,	NID_sha256,	CKM_SHA256, },
1205+	{PK11_SHA384,	NID_sha384,	CKM_SHA384, },
1206+	{PK11_SHA512,	NID_sha512,	CKM_SHA512, },
1207+	{0,		NID_undef,	0xFFFF, },
1208+	};
1209+
1210+/*
1211+ * Structure to be used for the cipher_data/md_data in
1212+ * EVP_CIPHER_CTX/EVP_MD_CTX structures in order to use the same pk11
1213+ * session in multiple cipher_update calls
1214+ */
1215+typedef struct PK11_CIPHER_STATE_st
1216+	{
1217+	PK11_SESSION	*sp;
1218+	} PK11_CIPHER_STATE;
1219+
1220+
1221+/*
1222+ * libcrypto EVP stuff - this is how we get wired to EVP so the engine gets
1223+ * called when libcrypto requests a cipher NID.
1224+ *
1225+ * Note how the PK11_CIPHER_STATE is used here.
1226+ */
1227+
1228+/* DES CBC EVP */
1229+static const EVP_CIPHER pk11_des_cbc =
1230+	{
1231+	NID_des_cbc,
1232+	8, 8, 8,
1233+	EVP_CIPH_CBC_MODE,
1234+	pk11_cipher_init,
1235+	pk11_cipher_do_cipher,
1236+	pk11_cipher_cleanup,
1237+	sizeof (PK11_CIPHER_STATE),
1238+	EVP_CIPHER_set_asn1_iv,
1239+	EVP_CIPHER_get_asn1_iv,
1240+	NULL
1241+	};
1242+
1243+/* 3DES CBC EVP */
1244+static const EVP_CIPHER pk11_3des_cbc =
1245+	{
1246+	NID_des_ede3_cbc,
1247+	8, 24, 8,
1248+	EVP_CIPH_CBC_MODE,
1249+	pk11_cipher_init,
1250+	pk11_cipher_do_cipher,
1251+	pk11_cipher_cleanup,
1252+	sizeof (PK11_CIPHER_STATE),
1253+	EVP_CIPHER_set_asn1_iv,
1254+	EVP_CIPHER_get_asn1_iv,
1255+	NULL
1256+	};
1257+
1258+/*
1259+ * ECB modes don't use an Initial Vector so that's why set_asn1_parameters and
1260+ * get_asn1_parameters fields are set to NULL.
1261+ */
1262+static const EVP_CIPHER pk11_des_ecb =
1263+	{
1264+	NID_des_ecb,
1265+	8, 8, 8,
1266+	EVP_CIPH_ECB_MODE,
1267+	pk11_cipher_init,
1268+	pk11_cipher_do_cipher,
1269+	pk11_cipher_cleanup,
1270+	sizeof (PK11_CIPHER_STATE),
1271+	NULL,
1272+	NULL,
1273+	NULL
1274+	};
1275+
1276+static const EVP_CIPHER pk11_3des_ecb =
1277+	{
1278+	NID_des_ede3_ecb,
1279+	8, 24, 8,
1280+	EVP_CIPH_ECB_MODE,
1281+	pk11_cipher_init,
1282+	pk11_cipher_do_cipher,
1283+	pk11_cipher_cleanup,
1284+	sizeof (PK11_CIPHER_STATE),
1285+	NULL,
1286+	NULL,
1287+	NULL
1288+	};
1289+
1290+
1291+static const EVP_CIPHER pk11_aes_128_cbc =
1292+	{
1293+	NID_aes_128_cbc,
1294+	16, 16, 16,
1295+	EVP_CIPH_CBC_MODE,
1296+	pk11_cipher_init,
1297+	pk11_cipher_do_cipher,
1298+	pk11_cipher_cleanup,
1299+	sizeof (PK11_CIPHER_STATE),
1300+	EVP_CIPHER_set_asn1_iv,
1301+	EVP_CIPHER_get_asn1_iv,
1302+	NULL
1303+	};
1304+
1305+static const EVP_CIPHER pk11_aes_192_cbc =
1306+	{
1307+	NID_aes_192_cbc,
1308+	16, 24, 16,
1309+	EVP_CIPH_CBC_MODE,
1310+	pk11_cipher_init,
1311+	pk11_cipher_do_cipher,
1312+	pk11_cipher_cleanup,
1313+	sizeof (PK11_CIPHER_STATE),
1314+	EVP_CIPHER_set_asn1_iv,
1315+	EVP_CIPHER_get_asn1_iv,
1316+	NULL
1317+	};
1318+
1319+static const EVP_CIPHER pk11_aes_256_cbc =
1320+	{
1321+	NID_aes_256_cbc,
1322+	16, 32, 16,
1323+	EVP_CIPH_CBC_MODE,
1324+	pk11_cipher_init,
1325+	pk11_cipher_do_cipher,
1326+	pk11_cipher_cleanup,
1327+	sizeof (PK11_CIPHER_STATE),
1328+	EVP_CIPHER_set_asn1_iv,
1329+	EVP_CIPHER_get_asn1_iv,
1330+	NULL
1331+	};
1332+
1333+/*
1334+ * ECB modes don't use IV so that's why set_asn1_parameters and
1335+ * get_asn1_parameters are set to NULL.
1336+ */
1337+static const EVP_CIPHER pk11_aes_128_ecb =
1338+	{
1339+	NID_aes_128_ecb,
1340+	16, 16, 0,
1341+	EVP_CIPH_ECB_MODE,
1342+	pk11_cipher_init,
1343+	pk11_cipher_do_cipher,
1344+	pk11_cipher_cleanup,
1345+	sizeof (PK11_CIPHER_STATE),
1346+	NULL,
1347+	NULL,
1348+	NULL
1349+	};
1350+
1351+static const EVP_CIPHER pk11_aes_192_ecb =
1352+	{
1353+	NID_aes_192_ecb,
1354+	16, 24, 0,
1355+	EVP_CIPH_ECB_MODE,
1356+	pk11_cipher_init,
1357+	pk11_cipher_do_cipher,
1358+	pk11_cipher_cleanup,
1359+	sizeof (PK11_CIPHER_STATE),
1360+	NULL,
1361+	NULL,
1362+	NULL
1363+	};
1364+
1365+static const EVP_CIPHER pk11_aes_256_ecb =
1366+	{
1367+	NID_aes_256_ecb,
1368+	16, 32, 0,
1369+	EVP_CIPH_ECB_MODE,
1370+	pk11_cipher_init,
1371+	pk11_cipher_do_cipher,
1372+	pk11_cipher_cleanup,
1373+	sizeof (PK11_CIPHER_STATE),
1374+	NULL,
1375+	NULL,
1376+	NULL
1377+	};
1378+
1379+#ifdef	SOLARIS_AES_CTR
1380+/*
1381+ * NID_undef's will be changed to the AES counter mode NIDs as soon they are
1382+ * created in pk11_library_init(). Note that the need to change these structures
1383+ * is the reason why we don't define them with the const keyword.
1384+ */
1385+static EVP_CIPHER pk11_aes_128_ctr =
1386+	{
1387+	NID_undef,
1388+	16, 16, 16,
1389+	EVP_CIPH_CBC_MODE,
1390+	pk11_cipher_init,
1391+	pk11_cipher_do_cipher,
1392+	pk11_cipher_cleanup,
1393+	sizeof (PK11_CIPHER_STATE),
1394+	EVP_CIPHER_set_asn1_iv,
1395+	EVP_CIPHER_get_asn1_iv,
1396+	NULL
1397+	};
1398+
1399+static EVP_CIPHER pk11_aes_192_ctr =
1400+	{
1401+	NID_undef,
1402+	16, 24, 16,
1403+	EVP_CIPH_CBC_MODE,
1404+	pk11_cipher_init,
1405+	pk11_cipher_do_cipher,
1406+	pk11_cipher_cleanup,
1407+	sizeof (PK11_CIPHER_STATE),
1408+	EVP_CIPHER_set_asn1_iv,
1409+	EVP_CIPHER_get_asn1_iv,
1410+	NULL
1411+	};
1412+
1413+static EVP_CIPHER pk11_aes_256_ctr =
1414+	{
1415+	NID_undef,
1416+	16, 32, 16,
1417+	EVP_CIPH_CBC_MODE,
1418+	pk11_cipher_init,
1419+	pk11_cipher_do_cipher,
1420+	pk11_cipher_cleanup,
1421+	sizeof (PK11_CIPHER_STATE),
1422+	EVP_CIPHER_set_asn1_iv,
1423+	EVP_CIPHER_get_asn1_iv,
1424+	NULL
1425+	};
1426+#endif	/* SOLARIS_AES_CTR */
1427+
1428+static const EVP_CIPHER pk11_bf_cbc =
1429+	{
1430+	NID_bf_cbc,
1431+	8, 16, 8,
1432+	EVP_CIPH_VARIABLE_LENGTH,
1433+	pk11_cipher_init,
1434+	pk11_cipher_do_cipher,
1435+	pk11_cipher_cleanup,
1436+	sizeof (PK11_CIPHER_STATE),
1437+	EVP_CIPHER_set_asn1_iv,
1438+	EVP_CIPHER_get_asn1_iv,
1439+	NULL
1440+	};
1441+
1442+static const EVP_CIPHER pk11_rc4 =
1443+	{
1444+	NID_rc4,
1445+	1, 16, 0,
1446+	EVP_CIPH_VARIABLE_LENGTH,
1447+	pk11_cipher_init,
1448+	pk11_cipher_do_cipher,
1449+	pk11_cipher_cleanup,
1450+	sizeof (PK11_CIPHER_STATE),
1451+	NULL,
1452+	NULL,
1453+	NULL
1454+	};
1455+
1456+static const EVP_MD pk11_md5 =
1457+	{
1458+	NID_md5,
1459+	NID_md5WithRSAEncryption,
1460+	MD5_DIGEST_LENGTH,
1461+	0,
1462+	pk11_digest_init,
1463+	pk11_digest_update,
1464+	pk11_digest_final,
1465+	pk11_digest_copy,
1466+	pk11_digest_cleanup,
1467+	EVP_PKEY_RSA_method,
1468+	MD5_CBLOCK,
1469+	sizeof (PK11_CIPHER_STATE),
1470+	};
1471+
1472+static const EVP_MD pk11_sha1 =
1473+	{
1474+	NID_sha1,
1475+	NID_sha1WithRSAEncryption,
1476+	SHA_DIGEST_LENGTH,
1477+	0,
1478+	pk11_digest_init,
1479+	pk11_digest_update,
1480+	pk11_digest_final,
1481+	pk11_digest_copy,
1482+	pk11_digest_cleanup,
1483+	EVP_PKEY_RSA_method,
1484+	SHA_CBLOCK,
1485+	sizeof (PK11_CIPHER_STATE),
1486+	};
1487+
1488+static const EVP_MD pk11_sha224 =
1489+	{
1490+	NID_sha224,
1491+	NID_sha224WithRSAEncryption,
1492+	SHA224_DIGEST_LENGTH,
1493+	0,
1494+	pk11_digest_init,
1495+	pk11_digest_update,
1496+	pk11_digest_final,
1497+	pk11_digest_copy,
1498+	pk11_digest_cleanup,
1499+	EVP_PKEY_RSA_method,
1500+	/* SHA-224 uses the same cblock size as SHA-256 */
1501+	SHA256_CBLOCK,
1502+	sizeof (PK11_CIPHER_STATE),
1503+	};
1504+
1505+static const EVP_MD pk11_sha256 =
1506+	{
1507+	NID_sha256,
1508+	NID_sha256WithRSAEncryption,
1509+	SHA256_DIGEST_LENGTH,
1510+	0,
1511+	pk11_digest_init,
1512+	pk11_digest_update,
1513+	pk11_digest_final,
1514+	pk11_digest_copy,
1515+	pk11_digest_cleanup,
1516+	EVP_PKEY_RSA_method,
1517+	SHA256_CBLOCK,
1518+	sizeof (PK11_CIPHER_STATE),
1519+	};
1520+
1521+static const EVP_MD pk11_sha384 =
1522+	{
1523+	NID_sha384,
1524+	NID_sha384WithRSAEncryption,
1525+	SHA384_DIGEST_LENGTH,
1526+	0,
1527+	pk11_digest_init,
1528+	pk11_digest_update,
1529+	pk11_digest_final,
1530+	pk11_digest_copy,
1531+	pk11_digest_cleanup,
1532+	EVP_PKEY_RSA_method,
1533+	/* SHA-384 uses the same cblock size as SHA-512 */
1534+	SHA512_CBLOCK,
1535+	sizeof (PK11_CIPHER_STATE),
1536+	};
1537+
1538+static const EVP_MD pk11_sha512 =
1539+	{
1540+	NID_sha512,
1541+	NID_sha512WithRSAEncryption,
1542+	SHA512_DIGEST_LENGTH,
1543+	0,
1544+	pk11_digest_init,
1545+	pk11_digest_update,
1546+	pk11_digest_final,
1547+	pk11_digest_copy,
1548+	pk11_digest_cleanup,
1549+	EVP_PKEY_RSA_method,
1550+	SHA512_CBLOCK,
1551+	sizeof (PK11_CIPHER_STATE),
1552+	};
1553+
1554+/*
1555+ * Initialization function. Sets up various PKCS#11 library components.
1556+ * The definitions for control commands specific to this engine
1557+ */
1558+#define PK11_CMD_SO_PATH		ENGINE_CMD_BASE
1559+#define PK11_CMD_PIN			(ENGINE_CMD_BASE+1)
1560+#define PK11_CMD_SLOT			(ENGINE_CMD_BASE+2)
1561+static const ENGINE_CMD_DEFN pk11_cmd_defns[] =
1562+	{
1563+		{
1564+		PK11_CMD_SO_PATH,
1565+		"SO_PATH",
1566+		"Specifies the path to the 'pkcs#11' shared library",
1567+		ENGINE_CMD_FLAG_STRING
1568+		},
1569+		{
1570+		PK11_CMD_PIN,
1571+		"PIN",
1572+		"Specifies the pin code",
1573+		ENGINE_CMD_FLAG_STRING
1574+		},
1575+		{
1576+		PK11_CMD_SLOT,
1577+		"SLOT",
1578+		"Specifies the slot (default is auto select)",
1579+		ENGINE_CMD_FLAG_NUMERIC,
1580+		},
1581+		{0, NULL, NULL, 0}
1582+	};
1583+
1584+
1585+static RAND_METHOD pk11_random =
1586+	{
1587+	pk11_rand_seed,
1588+	pk11_rand_bytes,
1589+	pk11_rand_cleanup,
1590+	pk11_rand_add,
1591+	pk11_rand_bytes,
1592+	pk11_rand_status
1593+	};
1594+
1595+
1596+/* Constants used when creating the ENGINE */
1597+#ifdef OPENSSL_NO_HW_PK11SO
1598+#error "can't load both crypto-accelerator and sign-only PKCS#11 engines"
1599+#endif
1600+static const char *engine_pk11_id = "pkcs11";
1601+static const char *engine_pk11_name =
1602+	"PKCS #11 engine support (crypto accelerator)";
1603+
1604+CK_FUNCTION_LIST_PTR pFuncList = NULL;
1605+static const char PK11_GET_FUNCTION_LIST[] = "C_GetFunctionList";
1606+
1607+/*
1608+ * This is a static string constant for the DSO file name and the function
1609+ * symbol names to bind to. We set it in the Configure script based on whether
1610+ * this is 32 or 64 bit build.
1611+ */
1612+static const char def_PK11_LIBNAME[] = PK11_LIB_LOCATION;
1613+
1614+static CK_BBOOL true = TRUE;
1615+static CK_BBOOL false = FALSE;
1616+/* Needed in hw_pk11_pub.c as well so that's why it is not static. */
1617+CK_SLOT_ID pubkey_SLOTID = 0;
1618+static CK_SLOT_ID rand_SLOTID = 0;
1619+static CK_SLOT_ID SLOTID = 0;
1620+char *pk11_pin = NULL;
1621+static CK_BBOOL pk11_library_initialized = FALSE;
1622+static CK_BBOOL pk11_atfork_initialized = FALSE;
1623+static int pk11_pid = 0;
1624+
1625+static DSO *pk11_dso = NULL;
1626+
1627+/* allocate and initialize all locks used by the engine itself */
1628+static int pk11_init_all_locks(void)
1629+	{
1630+#ifndef NOPTHREADS
1631+	int type;
1632+
1633+	if ((token_lock = OPENSSL_malloc(sizeof (pthread_mutex_t))) == NULL)
1634+		goto malloc_err;
1635+	(void) pthread_mutex_init(token_lock, NULL);
1636+
1637+#ifndef OPENSSL_NO_RSA
1638+	find_lock[OP_RSA] = OPENSSL_malloc(sizeof (pthread_mutex_t));
1639+	if (find_lock[OP_RSA] == NULL)
1640+		goto malloc_err;
1641+	(void) pthread_mutex_init(find_lock[OP_RSA], NULL);
1642+#endif /* OPENSSL_NO_RSA */
1643+
1644+#ifndef OPENSSL_NO_DSA
1645+	find_lock[OP_DSA] = OPENSSL_malloc(sizeof (pthread_mutex_t));
1646+	if (find_lock[OP_DSA] == NULL)
1647+		goto malloc_err;
1648+	(void) pthread_mutex_init(find_lock[OP_DSA], NULL);
1649+#endif /* OPENSSL_NO_DSA */
1650+
1651+#ifndef OPENSSL_NO_DH
1652+	find_lock[OP_DH] = OPENSSL_malloc(sizeof (pthread_mutex_t));
1653+	if (find_lock[OP_DH] == NULL)
1654+		goto malloc_err;
1655+	(void) pthread_mutex_init(find_lock[OP_DH], NULL);
1656+#endif /* OPENSSL_NO_DH */
1657+
1658+	for (type = 0; type < OP_MAX; type++)
1659+		{
1660+		session_cache[type].lock =
1661+		    OPENSSL_malloc(sizeof (pthread_mutex_t));
1662+		if (session_cache[type].lock == NULL)
1663+			goto malloc_err;
1664+		(void) pthread_mutex_init(session_cache[type].lock, NULL);
1665+		}
1666+
1667+	return (1);
1668+
1669+malloc_err:
1670+	pk11_free_all_locks();
1671+	PK11err(PK11_F_INIT_ALL_LOCKS, PK11_R_MALLOC_FAILURE);
1672+	return (0);
1673+#else
1674+	return (1);
1675+#endif
1676+	}
1677+
1678+static void pk11_free_all_locks(void)
1679+	{
1680+#ifndef NOPTHREADS
1681+	int type;
1682+
1683+#ifndef OPENSSL_NO_RSA
1684+	if (find_lock[OP_RSA] != NULL)
1685+		{
1686+		(void) pthread_mutex_destroy(find_lock[OP_RSA]);
1687+		OPENSSL_free(find_lock[OP_RSA]);
1688+		find_lock[OP_RSA] = NULL;
1689+		}
1690+#endif /* OPENSSL_NO_RSA */
1691+#ifndef OPENSSL_NO_DSA
1692+	if (find_lock[OP_DSA] != NULL)
1693+		{
1694+		(void) pthread_mutex_destroy(find_lock[OP_DSA]);
1695+		OPENSSL_free(find_lock[OP_DSA]);
1696+		find_lock[OP_DSA] = NULL;
1697+		}
1698+#endif /* OPENSSL_NO_DSA */
1699+#ifndef OPENSSL_NO_DH
1700+	if (find_lock[OP_DH] != NULL)
1701+		{
1702+		(void) pthread_mutex_destroy(find_lock[OP_DH]);
1703+		OPENSSL_free(find_lock[OP_DH]);
1704+		find_lock[OP_DH] = NULL;
1705+		}
1706+#endif /* OPENSSL_NO_DH */
1707+
1708+	for (type = 0; type < OP_MAX; type++)
1709+		{
1710+		if (session_cache[type].lock != NULL)
1711+			{
1712+			(void) pthread_mutex_destroy(session_cache[type].lock);
1713+			OPENSSL_free(session_cache[type].lock);
1714+			session_cache[type].lock = NULL;
1715+			}
1716+		}
1717+#endif
1718+	}
1719+
1720+/*
1721+ * This internal function is used by ENGINE_pk11() and "dynamic" ENGINE support.
1722+ */
1723+static int bind_pk11(ENGINE *e)
1724+	{
1725+#ifndef OPENSSL_NO_RSA
1726+	const RSA_METHOD *rsa = NULL;
1727+	RSA_METHOD *pk11_rsa = PK11_RSA();
1728+#endif	/* OPENSSL_NO_RSA */
1729+	if (!pk11_library_initialized)
1730+		if (!pk11_library_init(e))
1731+			return (0);
1732+
1733+	if (!ENGINE_set_id(e, engine_pk11_id) ||
1734+	    !ENGINE_set_name(e, engine_pk11_name) ||
1735+	    !ENGINE_set_ciphers(e, pk11_engine_ciphers) ||
1736+	    !ENGINE_set_digests(e, pk11_engine_digests))
1737+		return (0);
1738+#ifndef OPENSSL_NO_RSA
1739+	if (pk11_have_rsa == CK_TRUE)
1740+		{
1741+		if (!ENGINE_set_RSA(e, PK11_RSA()) ||
1742+		    !ENGINE_set_load_privkey_function(e, pk11_load_privkey) ||
1743+		    !ENGINE_set_load_pubkey_function(e, pk11_load_pubkey))
1744+			return (0);
1745+#ifdef	DEBUG_SLOT_SELECTION
1746+		fprintf(stderr, "%s: registered RSA\n", PK11_DBG);
1747+#endif	/* DEBUG_SLOT_SELECTION */
1748+		}
1749+#endif	/* OPENSSL_NO_RSA */
1750+#ifndef OPENSSL_NO_DSA
1751+	if (pk11_have_dsa == CK_TRUE)
1752+		{
1753+		if (!ENGINE_set_DSA(e, PK11_DSA()))
1754+			return (0);
1755+#ifdef	DEBUG_SLOT_SELECTION
1756+		fprintf(stderr, "%s: registered DSA\n", PK11_DBG);
1757+#endif	/* DEBUG_SLOT_SELECTION */
1758+		}
1759+#endif	/* OPENSSL_NO_DSA */
1760+#ifndef OPENSSL_NO_DH
1761+	if (pk11_have_dh == CK_TRUE)
1762+		{
1763+		if (!ENGINE_set_DH(e, PK11_DH()))
1764+			return (0);
1765+#ifdef	DEBUG_SLOT_SELECTION
1766+		fprintf(stderr, "%s: registered DH\n", PK11_DBG);
1767+#endif	/* DEBUG_SLOT_SELECTION */
1768+		}
1769+#endif	/* OPENSSL_NO_DH */
1770+	if (pk11_have_random)
1771+		{
1772+		if (!ENGINE_set_RAND(e, &pk11_random))
1773+			return (0);
1774+#ifdef	DEBUG_SLOT_SELECTION
1775+		fprintf(stderr, "%s: registered random\n", PK11_DBG);
1776+#endif	/* DEBUG_SLOT_SELECTION */
1777+		}
1778+	if (!ENGINE_set_init_function(e, pk11_init) ||
1779+	    !ENGINE_set_destroy_function(e, pk11_destroy) ||
1780+	    !ENGINE_set_finish_function(e, pk11_finish) ||
1781+	    !ENGINE_set_ctrl_function(e, pk11_ctrl) ||
1782+	    !ENGINE_set_cmd_defns(e, pk11_cmd_defns))
1783+		return (0);
1784+
1785+/*
1786+ * Apache calls OpenSSL function RSA_blinding_on() once during startup
1787+ * which in turn calls bn_mod_exp. Since we do not implement bn_mod_exp
1788+ * here, we wire it back to the OpenSSL software implementation.
1789+ * Since it is used only once, performance is not a concern.
1790+ */
1791+#ifndef OPENSSL_NO_RSA
1792+	rsa = RSA_PKCS1_SSLeay();
1793+	pk11_rsa->rsa_mod_exp = rsa->rsa_mod_exp;
1794+	pk11_rsa->bn_mod_exp = rsa->bn_mod_exp;
1795+	if (pk11_have_recover != CK_TRUE)
1796+		pk11_rsa->rsa_pub_dec = rsa->rsa_pub_dec;
1797+#endif	/* OPENSSL_NO_RSA */
1798+
1799+	/* Ensure the pk11 error handling is set up */
1800+	ERR_load_pk11_strings();
1801+
1802+	return (1);
1803+	}
1804+
1805+/* Dynamic engine support is disabled at a higher level for Solaris */
1806+#ifdef	ENGINE_DYNAMIC_SUPPORT
1807+#error  "dynamic engine not supported"
1808+static int bind_helper(ENGINE *e, const char *id)
1809+	{
1810+	if (id && (strcmp(id, engine_pk11_id) != 0))
1811+		return (0);
1812+
1813+	if (!bind_pk11(e))
1814+		return (0);
1815+
1816+	return (1);
1817+	}
1818+
1819+IMPLEMENT_DYNAMIC_CHECK_FN()
1820+IMPLEMENT_DYNAMIC_BIND_FN(bind_helper)
1821+
1822+#else
1823+static ENGINE *engine_pk11(void)
1824+	{
1825+	ENGINE *ret = ENGINE_new();
1826+
1827+	if (!ret)
1828+		return (NULL);
1829+
1830+	if (!bind_pk11(ret))
1831+		{
1832+		ENGINE_free(ret);
1833+		return (NULL);
1834+		}
1835+
1836+	return (ret);
1837+	}
1838+
1839+void
1840+ENGINE_load_pk11(void)
1841+	{
1842+	ENGINE *e_pk11 = NULL;
1843+
1844+	/*
1845+	 * Do not use dynamic PKCS#11 library on Solaris due to
1846+	 * security reasons. We will link it in statically.
1847+	 */
1848+	/* Attempt to load PKCS#11 library */
1849+	if (!pk11_dso)
1850+		pk11_dso = DSO_load(NULL, get_PK11_LIBNAME(), NULL, 0);
1851+
1852+	if (pk11_dso == NULL)
1853+		{
1854+		PK11err(PK11_F_LOAD, PK11_R_DSO_FAILURE);
1855+		return;
1856+		}
1857+
1858+	e_pk11 = engine_pk11();
1859+	if (!e_pk11)
1860+		{
1861+		DSO_free(pk11_dso);
1862+		pk11_dso = NULL;
1863+		return;
1864+		}
1865+
1866+	/*
1867+	 * At this point, the pk11 shared library is either dynamically
1868+	 * loaded or statically linked in. So, initialize the pk11
1869+	 * library before calling ENGINE_set_default since the latter
1870+	 * needs cipher and digest algorithm information
1871+	 */
1872+	if (!pk11_library_init(e_pk11))
1873+		{
1874+		DSO_free(pk11_dso);
1875+		pk11_dso = NULL;
1876+		ENGINE_free(e_pk11);
1877+		return;
1878+		}
1879+
1880+	ENGINE_add(e_pk11);
1881+
1882+	ENGINE_free(e_pk11);
1883+	ERR_clear_error();
1884+	}
1885+#endif	/* ENGINE_DYNAMIC_SUPPORT */
1886+
1887+/*
1888+ * These are the static string constants for the DSO file name and
1889+ * the function symbol names to bind to.
1890+ */
1891+static const char *PK11_LIBNAME = NULL;
1892+
1893+static const char *get_PK11_LIBNAME(void)
1894+	{
1895+	if (PK11_LIBNAME)
1896+		return (PK11_LIBNAME);
1897+
1898+	return (def_PK11_LIBNAME);
1899+	}
1900+
1901+static void free_PK11_LIBNAME(void)
1902+	{
1903+	if (PK11_LIBNAME)
1904+		OPENSSL_free((void*)PK11_LIBNAME);
1905+
1906+	PK11_LIBNAME = NULL;
1907+	}
1908+
1909+static long set_PK11_LIBNAME(const char *name)
1910+	{
1911+	free_PK11_LIBNAME();
1912+
1913+	return ((PK11_LIBNAME = BUF_strdup(name)) != NULL ? 1 : 0);
1914+	}
1915+
1916+/* acquire all engine specific mutexes before fork */
1917+static void pk11_fork_prepare(void)
1918+	{
1919+#ifndef NOPTHREADS
1920+	int i;
1921+
1922+	if (!pk11_library_initialized)
1923+		return;
1924+
1925+	LOCK_OBJSTORE(OP_RSA);
1926+	LOCK_OBJSTORE(OP_DSA);
1927+	LOCK_OBJSTORE(OP_DH);
1928+	(void) pthread_mutex_lock(token_lock);
1929+	for (i = 0; i < OP_MAX; i++)
1930+		{
1931+		(void) pthread_mutex_lock(session_cache[i].lock);
1932+		}
1933+#endif
1934+	}
1935+
1936+/* release all engine specific mutexes */
1937+static void pk11_fork_parent(void)
1938+	{
1939+#ifndef NOPTHREADS
1940+	int i;
1941+
1942+	if (!pk11_library_initialized)
1943+		return;
1944+
1945+	for (i = OP_MAX - 1; i >= 0; i--)
1946+		{
1947+		(void) pthread_mutex_unlock(session_cache[i].lock);
1948+		}
1949+	UNLOCK_OBJSTORE(OP_DH);
1950+	UNLOCK_OBJSTORE(OP_DSA);
1951+	UNLOCK_OBJSTORE(OP_RSA);
1952+	(void) pthread_mutex_unlock(token_lock);
1953+#endif
1954+	}
1955+
1956+/*
1957+ * same situation as in parent - we need to unlock all locks to make them
1958+ * accessible to all threads.
1959+ */
1960+static void pk11_fork_child(void)
1961+	{
1962+#ifndef NOPTHREADS
1963+	int i;
1964+
1965+	if (!pk11_library_initialized)
1966+		return;
1967+
1968+	for (i = OP_MAX - 1; i >= 0; i--)
1969+		{
1970+		(void) pthread_mutex_unlock(session_cache[i].lock);
1971+		}
1972+	UNLOCK_OBJSTORE(OP_DH);
1973+	UNLOCK_OBJSTORE(OP_DSA);
1974+	UNLOCK_OBJSTORE(OP_RSA);
1975+	(void) pthread_mutex_unlock(token_lock);
1976+#endif
1977+	}
1978+
1979+/* Initialization function for the pk11 engine */
1980+static int pk11_init(ENGINE *e)
1981+{
1982+	return (pk11_library_init(e));
1983+}
1984+
1985+static CK_C_INITIALIZE_ARGS pk11_init_args =
1986+	{
1987+	NULL_PTR,		/* CreateMutex */
1988+	NULL_PTR,		/* DestroyMutex */
1989+	NULL_PTR,		/* LockMutex */
1990+	NULL_PTR,		/* UnlockMutex */
1991+	CKF_OS_LOCKING_OK,	/* flags */
1992+	NULL_PTR,		/* pReserved */
1993+	};
1994+
1995+/*
1996+ * Initialization function. Sets up various PKCS#11 library components.
1997+ * It selects a slot based on predefined critiera. In the process, it also
1998+ * count how many ciphers and digests to support. Since the cipher and
1999+ * digest information is needed when setting default engine, this function
2000+ * needs to be called before calling ENGINE_set_default.
2001+ */
2002+/* ARGSUSED */
2003+static int pk11_library_init(ENGINE *e)
2004+	{
2005+	CK_C_GetFunctionList p;
2006+	CK_RV rv = CKR_OK;
2007+	CK_INFO info;
2008+	CK_ULONG ul_state_len;
2009+	int any_slot_found;
2010+	int i;
2011+#ifndef OPENSSL_SYS_WIN32
2012+	struct sigaction sigint_act, sigterm_act, sighup_act;
2013+#endif
2014+
2015+	/*
2016+	 * pk11_library_initialized is set to 0 in pk11_finish() which
2017+	 * is called from ENGINE_finish(). However, if there is still
2018+	 * at least one existing functional reference to the engine
2019+	 * (see engine(3) for more information), pk11_finish() is
2020+	 * skipped. For example, this can happen if an application
2021+	 * forgets to clear one cipher context. In case of a fork()
2022+	 * when the application is finishing the engine so that it can
2023+	 * be reinitialized in the child, forgotten functional
2024+	 * reference causes pk11_library_initialized to stay 1. In
2025+	 * that case we need the PID check so that we properly
2026+	 * initialize the engine again.
2027+	 */
2028+	if (pk11_library_initialized)
2029+		{
2030+		if (pk11_pid == getpid())
2031+			{
2032+			return (1);
2033+			}
2034+		else
2035+			{
2036+			global_session = CK_INVALID_HANDLE;
2037+			/*
2038+			 * free the locks first to prevent memory leak in case
2039+			 * the application calls fork() without finishing the
2040+			 * engine first.
2041+			 */
2042+			pk11_free_all_locks();
2043+			}
2044+		}
2045+
2046+	if (pk11_dso == NULL)
2047+		{
2048+		PK11err(PK11_F_LIBRARY_INIT, PK11_R_DSO_FAILURE);
2049+		goto err;
2050+		}
2051+
2052+#ifdef	SOLARIS_AES_CTR
2053+	/*
2054+	 * We must do this before we start working with slots since we need all
2055+	 * NIDs there.
2056+	 */
2057+	if (pk11_add_aes_ctr_NIDs() == 0)
2058+		goto err;
2059+#endif	/* SOLARIS_AES_CTR */
2060+
2061+#ifdef	SOLARIS_HW_SLOT_SELECTION
2062+	if (check_hw_mechanisms() == 0)
2063+		goto err;
2064+#endif	/* SOLARIS_HW_SLOT_SELECTION */
2065+
2066+	/* get the C_GetFunctionList function from the loaded library */
2067+	p = (CK_C_GetFunctionList)DSO_bind_func(pk11_dso,
2068+		PK11_GET_FUNCTION_LIST);
2069+	if (!p)
2070+		{
2071+		PK11err(PK11_F_LIBRARY_INIT, PK11_R_DSO_FAILURE);
2072+		goto err;
2073+		}
2074+
2075+	/* get the full function list from the loaded library */
2076+	rv = p(&pFuncList);
2077+	if (rv != CKR_OK)
2078+		{
2079+		PK11err_add_data(PK11_F_LIBRARY_INIT, PK11_R_DSO_FAILURE, rv);
2080+		goto err;
2081+		}
2082+
2083+#ifndef OPENSSL_SYS_WIN32
2084+	/* Not all PKCS#11 library are signal safe! */
2085+
2086+	(void) memset(&sigint_act, 0, sizeof(sigint_act));
2087+	(void) memset(&sigterm_act, 0, sizeof(sigterm_act));
2088+	(void) memset(&sighup_act, 0, sizeof(sighup_act));
2089+	(void) sigaction(SIGINT, NULL, &sigint_act);
2090+	(void) sigaction(SIGTERM, NULL, &sigterm_act);
2091+	(void) sigaction(SIGHUP, NULL, &sighup_act);
2092+#endif
2093+	rv = pFuncList->C_Initialize((CK_VOID_PTR)&pk11_init_args);
2094+#ifndef OPENSSL_SYS_WIN32
2095+	(void) sigaction(SIGINT, &sigint_act, NULL);
2096+	(void) sigaction(SIGTERM, &sigterm_act, NULL);
2097+	(void) sigaction(SIGHUP, &sighup_act, NULL);
2098+#endif
2099+	if ((rv != CKR_OK) && (rv != CKR_CRYPTOKI_ALREADY_INITIALIZED))
2100+		{
2101+		PK11err_add_data(PK11_F_LIBRARY_INIT, PK11_R_INITIALIZE, rv);
2102+		goto err;
2103+		}
2104+
2105+	rv = pFuncList->C_GetInfo(&info);
2106+	if (rv != CKR_OK)
2107+		{
2108+		PK11err_add_data(PK11_F_LIBRARY_INIT, PK11_R_GETINFO, rv);
2109+		goto err;
2110+		}
2111+
2112+	if (pk11_choose_slots(&any_slot_found) == 0)
2113+		goto err;
2114+
2115+	/*
2116+	 * The library we use, set in def_PK11_LIBNAME, may not offer any
2117+	 * slot(s). In that case, we must not proceed but we must not return an
2118+	 * error. The reason is that applications that try to set up the PKCS#11
2119+	 * engine don't exit on error during the engine initialization just
2120+	 * because no slot was present.
2121+	 */
2122+	if (any_slot_found == 0)
2123+		return (1);
2124+
2125+	if (global_session == CK_INVALID_HANDLE)
2126+		{
2127+		/* Open the global_session for the new process */
2128+		rv = pFuncList->C_OpenSession(SLOTID, CKF_SERIAL_SESSION,
2129+			NULL_PTR, NULL_PTR, &global_session);
2130+		if (rv != CKR_OK)
2131+			{
2132+			PK11err_add_data(PK11_F_LIBRARY_INIT,
2133+			    PK11_R_OPENSESSION, rv);
2134+			goto err;
2135+			}
2136+		}
2137+
2138+	/*
2139+	 * Disable digest if C_GetOperationState is not supported since
2140+	 * this function is required by OpenSSL digest copy function
2141+	 */
2142+	/* Keyper fails to return CKR_FUNCTION_NOT_SUPPORTED */
2143+	if (pFuncList->C_GetOperationState(global_session, NULL, &ul_state_len)
2144+			!= CKR_OK) {
2145+#ifdef	DEBUG_SLOT_SELECTION
2146+		fprintf(stderr, "%s: C_GetOperationState() not supported, "
2147+		    "setting digest_count to 0\n", PK11_DBG);
2148+#endif	/* DEBUG_SLOT_SELECTION */
2149+		digest_count = 0;
2150+	}
2151+
2152+	pk11_library_initialized = TRUE;
2153+	pk11_pid = getpid();
2154+	/*
2155+	 * if initialization of the locks fails pk11_init_all_locks()
2156+	 * will do the cleanup.
2157+	 */
2158+	if (!pk11_init_all_locks())
2159+		goto err;
2160+	for (i = 0; i < OP_MAX; i++)
2161+		session_cache[i].head = NULL;
2162+	/*
2163+	 * initialize active lists. We only use active lists
2164+	 * for asymmetric ciphers.
2165+	 */
2166+	for (i = 0; i < OP_MAX; i++)
2167+		active_list[i] = NULL;
2168+
2169+#ifndef NOPTHREADS
2170+	if (!pk11_atfork_initialized)
2171+		{
2172+		if (pthread_atfork(pk11_fork_prepare, pk11_fork_parent,
2173+		    pk11_fork_child) != 0)
2174+			{
2175+			PK11err(PK11_F_LIBRARY_INIT, PK11_R_ATFORK_FAILED);
2176+			goto err;
2177+			}
2178+		pk11_atfork_initialized = TRUE;
2179+		}
2180+#endif
2181+
2182+	return (1);
2183+
2184+err:
2185+	return (0);
2186+	}
2187+
2188+/* Destructor (complements the "ENGINE_pk11()" constructor) */
2189+/* ARGSUSED */
2190+static int pk11_destroy(ENGINE *e)
2191+	{
2192+	free_PK11_LIBNAME();
2193+	ERR_unload_pk11_strings();
2194+	if (pk11_pin) {
2195+		memset(pk11_pin, 0, strlen(pk11_pin));
2196+		OPENSSL_free((void*)pk11_pin);
2197+	}
2198+	pk11_pin = NULL;
2199+	return (1);
2200+	}
2201+
2202+/*
2203+ * Termination function to clean up the session, the token, and the pk11
2204+ * library.
2205+ */
2206+/* ARGSUSED */
2207+static int pk11_finish(ENGINE *e)
2208+	{
2209+	int i;
2210+
2211+	if (pk11_pin) {
2212+		memset(pk11_pin, 0, strlen(pk11_pin));
2213+		OPENSSL_free((void*)pk11_pin);
2214+	}
2215+	pk11_pin = NULL;
2216+
2217+	if (pk11_dso == NULL)
2218+		{
2219+		PK11err(PK11_F_FINISH, PK11_R_NOT_LOADED);
2220+		goto err;
2221+		}
2222+
2223+	OPENSSL_assert(pFuncList != NULL);
2224+
2225+	if (pk11_free_all_sessions() == 0)
2226+		goto err;
2227+
2228+	/* free all active lists */
2229+	for (i = 0; i < OP_MAX; i++)
2230+		pk11_free_active_list(i);
2231+
2232+	pFuncList->C_CloseSession(global_session);
2233+	global_session = CK_INVALID_HANDLE;
2234+
2235+	/*
2236+	 * Since we are part of a library (libcrypto.so), calling this function
2237+	 * may have side-effects.
2238+	 */
2239+#if 0
2240+	pFuncList->C_Finalize(NULL);
2241+#endif
2242+
2243+	if (!DSO_free(pk11_dso))
2244+		{
2245+		PK11err(PK11_F_FINISH, PK11_R_DSO_FAILURE);
2246+		goto err;
2247+		}
2248+	pk11_dso = NULL;
2249+	pFuncList = NULL;
2250+	pk11_library_initialized = FALSE;
2251+	pk11_pid = 0;
2252+	/*
2253+	 * There is no way how to unregister atfork handlers (other than
2254+	 * unloading the library) so we just free the locks. For this reason
2255+	 * the atfork handlers check if the engine is initialized and bail out
2256+	 * immediately if not. This is necessary in case a process finishes
2257+	 * the engine before calling fork().
2258+	 */
2259+	pk11_free_all_locks();
2260+
2261+	return (1);
2262+
2263+err:
2264+	return (0);
2265+	}
2266+
2267+/* Standard engine interface function to set the dynamic library path */
2268+/* ARGSUSED */
2269+static int pk11_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void))
2270+	{
2271+	int initialized = ((pk11_dso == NULL) ? 0 : 1);
2272+
2273+	switch (cmd)
2274+		{
2275+	case PK11_CMD_SO_PATH:
2276+		if (p == NULL)
2277+			{
2278+			PK11err(PK11_F_CTRL, ERR_R_PASSED_NULL_PARAMETER);
2279+			return (0);
2280+			}
2281+
2282+		if (initialized)
2283+			{
2284+			PK11err(PK11_F_CTRL, PK11_R_ALREADY_LOADED);
2285+			return (0);
2286+			}
2287+
2288+		return (set_PK11_LIBNAME((const char *)p));
2289+	case PK11_CMD_PIN:
2290+		if (pk11_pin) {
2291+			memset(pk11_pin, 0, strlen(pk11_pin));
2292+			OPENSSL_free((void*)pk11_pin);
2293+		}
2294+		pk11_pin = NULL;
2295+
2296+		if (p == NULL)
2297+			{
2298+			PK11err(PK11_F_CTRL, ERR_R_PASSED_NULL_PARAMETER);
2299+			return (0);
2300+			}
2301+
2302+		pk11_pin = BUF_strdup(p);
2303+		if (pk11_pin == NULL)
2304+			{
2305+			PK11err(PK11_F_GET_SESSION, PK11_R_MALLOC_FAILURE);
2306+			return (0);
2307+			}
2308+		return (1);
2309+	case PK11_CMD_SLOT:
2310+		SLOTID = (CK_SLOT_ID)i;
2311+#ifdef DEBUG_SLOT_SELECTION
2312+		fprintf(stderr, "%s: slot set\n", PK11_DBG);
2313+#endif
2314+		return (1);
2315+	default:
2316+		break;
2317+		}
2318+
2319+	PK11err(PK11_F_CTRL, PK11_R_CTRL_COMMAND_NOT_IMPLEMENTED);
2320+
2321+	return (0);
2322+	}
2323+
2324+
2325+/* Required function by the engine random interface. It does nothing here */
2326+static void pk11_rand_cleanup(void)
2327+	{
2328+	return;
2329+	}
2330+
2331+/* ARGSUSED */
2332+static void pk11_rand_add(const void *buf, int num, double add)
2333+	{
2334+	PK11_SESSION *sp;
2335+
2336+	if ((sp = pk11_get_session(OP_RAND)) == NULL)
2337+		return;
2338+
2339+	/*
2340+	 * Ignore any errors (e.g. CKR_RANDOM_SEED_NOT_SUPPORTED) since
2341+	 * the calling functions do not care anyway
2342+	 */
2343+	pFuncList->C_SeedRandom(sp->session, (unsigned char *) buf, num);
2344+	pk11_return_session(sp, OP_RAND);
2345+
2346+	return;
2347+	}
2348+
2349+static void pk11_rand_seed(const void *buf, int num)
2350+	{
2351+	pk11_rand_add(buf, num, 0);
2352+	}
2353+
2354+static int pk11_rand_bytes(unsigned char *buf, int num)
2355+	{
2356+	CK_RV rv;
2357+	PK11_SESSION *sp;
2358+
2359+	if ((sp = pk11_get_session(OP_RAND)) == NULL)
2360+		return (0);
2361+
2362+	rv = pFuncList->C_GenerateRandom(sp->session, buf, num);
2363+	if (rv != CKR_OK)
2364+		{
2365+		PK11err_add_data(PK11_F_RAND_BYTES, PK11_R_GENERATERANDOM, rv);
2366+		pk11_return_session(sp, OP_RAND);
2367+		return (0);
2368+		}
2369+
2370+	pk11_return_session(sp, OP_RAND);
2371+	return (1);
2372+	}
2373+
2374+/* Required function by the engine random interface. It does nothing here */
2375+static int pk11_rand_status(void)
2376+	{
2377+	return (1);
2378+	}
2379+
2380+/* Free all BIGNUM structures from PK11_SESSION. */
2381+static void pk11_free_nums(PK11_SESSION *sp, PK11_OPTYPE optype)
2382+	{
2383+	switch (optype)
2384+		{
2385+#ifndef	OPENSSL_NO_RSA
2386+		case OP_RSA:
2387+			if (sp->opdata_rsa_n_num != NULL)
2388+				{
2389+				BN_free(sp->opdata_rsa_n_num);
2390+				sp->opdata_rsa_n_num = NULL;
2391+				}
2392+			if (sp->opdata_rsa_e_num != NULL)
2393+				{
2394+				BN_free(sp->opdata_rsa_e_num);
2395+				sp->opdata_rsa_e_num = NULL;
2396+				}
2397+			if (sp->opdata_rsa_pn_num != NULL)
2398+				{
2399+				BN_free(sp->opdata_rsa_pn_num);
2400+				sp->opdata_rsa_pn_num = NULL;
2401+				}
2402+			if (sp->opdata_rsa_pe_num != NULL)
2403+				{
2404+				BN_free(sp->opdata_rsa_pe_num);
2405+				sp->opdata_rsa_pe_num = NULL;
2406+				}
2407+			if (sp->opdata_rsa_d_num != NULL)
2408+				{
2409+				BN_free(sp->opdata_rsa_d_num);
2410+				sp->opdata_rsa_d_num = NULL;
2411+				}
2412+			break;
2413+#endif
2414+#ifndef	OPENSSL_NO_DSA
2415+		case OP_DSA:
2416+			if (sp->opdata_dsa_pub_num != NULL)
2417+				{
2418+				BN_free(sp->opdata_dsa_pub_num);
2419+				sp->opdata_dsa_pub_num = NULL;
2420+				}
2421+			if (sp->opdata_dsa_priv_num != NULL)
2422+				{
2423+				BN_free(sp->opdata_dsa_priv_num);
2424+				sp->opdata_dsa_priv_num = NULL;
2425+				}
2426+			break;
2427+#endif
2428+#ifndef	OPENSSL_NO_DH
2429+		case OP_DH:
2430+			if (sp->opdata_dh_priv_num != NULL)
2431+				{
2432+				BN_free(sp->opdata_dh_priv_num);
2433+				sp->opdata_dh_priv_num = NULL;
2434+				}
2435+			break;
2436+#endif
2437+		default:
2438+			break;
2439+		}
2440+	}
2441+
2442+/*
2443+ * Get new PK11_SESSION structure ready for use. Every process must have
2444+ * its own freelist of PK11_SESSION structures so handle fork() here
2445+ * by destroying the old and creating new freelist.
2446+ * The returned PK11_SESSION structure is disconnected from the freelist.
2447+ */
2448+PK11_SESSION *
2449+pk11_get_session(PK11_OPTYPE optype)
2450+	{
2451+	PK11_SESSION *sp = NULL, *sp1, *freelist;
2452+#ifndef NOPTHREADS
2453+	pthread_mutex_t *freelist_lock = NULL;
2454+#endif
2455+	static pid_t pid = 0;
2456+	pid_t new_pid;
2457+	CK_RV rv;
2458+
2459+	switch (optype)
2460+		{
2461+		case OP_RSA:
2462+		case OP_DSA:
2463+		case OP_DH:
2464+		case OP_RAND:
2465+		case OP_DIGEST:
2466+		case OP_CIPHER:
2467+#ifndef NOPTHREADS
2468+			freelist_lock = session_cache[optype].lock;
2469+#endif
2470+			break;
2471+		default:
2472+			PK11err(PK11_F_GET_SESSION,
2473+				PK11_R_INVALID_OPERATION_TYPE);
2474+			return (NULL);
2475+		}
2476+#ifndef NOPTHREADS
2477+	(void) pthread_mutex_lock(freelist_lock);
2478+#else
2479+	CRYPTO_w_lock(CRYPTO_LOCK_PK11_ENGINE);
2480+#endif
2481+
2482+	/*
2483+	 * Will use it to find out if we forked. We cannot use the PID field in
2484+	 * the session structure because we could get a newly allocated session
2485+	 * here, with no PID information.
2486+	 */
2487+	if (pid == 0)
2488+		pid = getpid();
2489+
2490+	freelist = session_cache[optype].head;
2491+	sp = freelist;
2492+
2493+	/*
2494+	 * If the free list is empty, allocate new unitialized (filled
2495+	 * with zeroes) PK11_SESSION structure otherwise return first
2496+	 * structure from the freelist.
2497+	 */
2498+	if (sp == NULL)
2499+		{
2500+		if ((sp = OPENSSL_malloc(sizeof (PK11_SESSION))) == NULL)
2501+			{
2502+			PK11err(PK11_F_GET_SESSION,
2503+				PK11_R_MALLOC_FAILURE);
2504+			goto err;
2505+			}
2506+		(void) memset(sp, 0, sizeof (PK11_SESSION));
2507+
2508+		/*
2509+		 * It is a new session so it will look like a cache miss to the
2510+		 * code below. So, we must not try to to destroy its members so
2511+		 * mark them as unused.
2512+		 */
2513+		sp->opdata_rsa_priv_key = CK_INVALID_HANDLE;
2514+		sp->opdata_rsa_pub_key = CK_INVALID_HANDLE;
2515+		}
2516+	else
2517+		{
2518+		freelist = sp->next;
2519+		}
2520+
2521+	/*
2522+	 * Check whether we have forked. In that case, we must get rid of all
2523+	 * inherited sessions and start allocating new ones.
2524+	 */
2525+	if (pid != (new_pid = getpid()))
2526+		{
2527+		pid = new_pid;
2528+
2529+		/*
2530+		 * We are a new process and thus need to free any inherited
2531+		 * PK11_SESSION objects aside from the first session (sp) which
2532+		 * is the only PK11_SESSION structure we will reuse (for the
2533+		 * head of the list).
2534+		 */
2535+		while ((sp1 = freelist) != NULL)
2536+			{
2537+			freelist = sp1->next;
2538+			/*
2539+			 * NOTE: we do not want to call pk11_free_all_sessions()
2540+			 * here because it would close underlying PKCS#11
2541+			 * sessions and destroy all objects.
2542+			 */
2543+			pk11_free_nums(sp1, optype);
2544+			OPENSSL_free(sp1);
2545+			}
2546+
2547+		/* we have to free the active list as well. */
2548+		pk11_free_active_list(optype);
2549+
2550+		/* Initialize the process */
2551+		rv = pFuncList->C_Initialize((CK_VOID_PTR)&pk11_init_args);
2552+		if ((rv != CKR_OK) && (rv != CKR_CRYPTOKI_ALREADY_INITIALIZED))
2553+			{
2554+			PK11err_add_data(PK11_F_GET_SESSION, PK11_R_INITIALIZE,
2555+			    rv);
2556+			OPENSSL_free(sp);
2557+			sp = NULL;
2558+			goto err;
2559+			}
2560+
2561+		/*
2562+		 * Choose slot here since the slot table is different on this
2563+		 * process. If we are here then we must have found at least one
2564+		 * usable slot before so we don't need to check any_slot_found.
2565+		 * See pk11_library_init()'s usage of this function for more
2566+		 * information.
2567+		 */
2568+#ifdef	SOLARIS_HW_SLOT_SELECTION
2569+		if (check_hw_mechanisms() == 0)
2570+			goto err;
2571+#endif	/* SOLARIS_HW_SLOT_SELECTION */
2572+		if (pk11_choose_slots(NULL) == 0)
2573+			goto err;
2574+
2575+		/* Open the global_session for the new process */
2576+		rv = pFuncList->C_OpenSession(SLOTID, CKF_SERIAL_SESSION,
2577+			NULL_PTR, NULL_PTR, &global_session);
2578+		if (rv != CKR_OK)
2579+			{
2580+			PK11err_add_data(PK11_F_GET_SESSION, PK11_R_OPENSESSION,
2581+			    rv);
2582+			OPENSSL_free(sp);
2583+			sp = NULL;
2584+			goto err;
2585+			}
2586+
2587+		/*
2588+		 * It is an inherited session from our parent so it needs
2589+		 * re-initialization.
2590+		 */
2591+		if (pk11_setup_session(sp, optype) == 0)
2592+			{
2593+			OPENSSL_free(sp);
2594+			sp = NULL;
2595+			goto err;
2596+			}
2597+		if (pk11_token_relogin(sp->session) == 0) 
2598+			{
2599+			/*
2600+			 * We will keep the session in the cache list and let
2601+			 * the caller cope with the situation.
2602+			 */
2603+			freelist = sp;
2604+			sp = NULL;
2605+			goto err;
2606+			}
2607+		}
2608+
2609+	if (sp->pid == 0)
2610+		{
2611+		/* It is a new session and needs initialization. */
2612+		if (pk11_setup_session(sp, optype) == 0)
2613+			{
2614+			OPENSSL_free(sp);
2615+			sp = NULL;
2616+			}
2617+		}
2618+
2619+	/* set new head for the list of PK11_SESSION objects */
2620+	session_cache[optype].head = freelist;
2621+
2622+err:
2623+	if (sp != NULL)
2624+		sp->next = NULL;
2625+
2626+#ifndef NOPTHREADS
2627+	(void) pthread_mutex_unlock(freelist_lock);
2628+#else
2629+	CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
2630+#endif
2631+
2632+	return (sp);
2633+	}
2634+
2635+
2636+void
2637+pk11_return_session(PK11_SESSION *sp, PK11_OPTYPE optype)
2638+	{
2639+#ifndef NOPTHREADS
2640+	pthread_mutex_t *freelist_lock;
2641+#endif
2642+	PK11_SESSION *freelist;
2643+
2644+	/*
2645+	 * If this is a session from the parent it will be taken care of and
2646+	 * freed in pk11_get_session() as part of the post-fork clean up the
2647+	 * next time we will ask for a new session.
2648+	 */
2649+	if (sp == NULL || sp->pid != getpid())
2650+		return;
2651+
2652+	switch (optype)
2653+		{
2654+		case OP_RSA:
2655+		case OP_DSA:
2656+		case OP_DH:
2657+		case OP_RAND:
2658+		case OP_DIGEST:
2659+		case OP_CIPHER:
2660+#ifndef NOPTHREADS
2661+			freelist_lock = session_cache[optype].lock;
2662+#endif
2663+			break;
2664+		default:
2665+			PK11err(PK11_F_RETURN_SESSION,
2666+				PK11_R_INVALID_OPERATION_TYPE);
2667+			return;
2668+		}
2669+
2670+#ifndef NOPTHREADS
2671+	(void) pthread_mutex_lock(freelist_lock);
2672+#else
2673+	CRYPTO_w_lock(CRYPTO_LOCK_PK11_ENGINE);
2674+#endif
2675+	freelist = session_cache[optype].head;
2676+	sp->next = freelist;
2677+	session_cache[optype].head = sp;
2678+#ifndef NOPTHREADS
2679+	(void) pthread_mutex_unlock(freelist_lock);
2680+#else
2681+	CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
2682+#endif
2683+	}
2684+
2685+
2686+/* Destroy all objects. This function is called when the engine is finished */
2687+static int pk11_free_all_sessions()
2688+	{
2689+	int ret = 1;
2690+	int type;
2691+
2692+#ifndef OPENSSL_NO_RSA
2693+	(void) pk11_destroy_rsa_key_objects(NULL);
2694+#endif	/* OPENSSL_NO_RSA */
2695+#ifndef OPENSSL_NO_DSA
2696+	(void) pk11_destroy_dsa_key_objects(NULL);
2697+#endif	/* OPENSSL_NO_DSA */
2698+#ifndef OPENSSL_NO_DH
2699+	(void) pk11_destroy_dh_key_objects(NULL);
2700+#endif	/* OPENSSL_NO_DH */
2701+	(void) pk11_destroy_cipher_key_objects(NULL);
2702+
2703+	/*
2704+	 * We try to release as much as we can but any error means that we will
2705+	 * return 0 on exit.
2706+	 */
2707+	for (type = 0; type < OP_MAX; type++)
2708+		{
2709+		if (pk11_free_session_list(type) == 0)
2710+			ret = 0;
2711+		}
2712+
2713+	return (ret);
2714+	}
2715+
2716+/*
2717+ * Destroy session structures from the linked list specified. Free as many
2718+ * sessions as possible but any failure in C_CloseSession() means that we
2719+ * return an error on return.
2720+ */
2721+static int pk11_free_session_list(PK11_OPTYPE optype)
2722+	{
2723+	CK_RV rv;
2724+	PK11_SESSION *sp = NULL;
2725+	PK11_SESSION *freelist = NULL;
2726+	pid_t mypid = getpid();
2727+#ifndef NOPTHREADS
2728+	pthread_mutex_t *freelist_lock;
2729+#endif
2730+	int ret = 1;
2731+
2732+	switch (optype)
2733+		{
2734+		case OP_RSA:
2735+		case OP_DSA:
2736+		case OP_DH:
2737+		case OP_RAND:
2738+		case OP_DIGEST:
2739+		case OP_CIPHER:
2740+#ifndef NOPTHREADS
2741+			freelist_lock = session_cache[optype].lock;
2742+#endif
2743+			break;
2744+		default:
2745+			PK11err(PK11_F_FREE_ALL_SESSIONS,
2746+				PK11_R_INVALID_OPERATION_TYPE);
2747+			return (0);
2748+		}
2749+
2750+#ifndef NOPTHREADS
2751+	(void) pthread_mutex_lock(freelist_lock);
2752+#else
2753+	CRYPTO_w_lock(CRYPTO_LOCK_PK11_ENGINE);
2754+#endif
2755+	freelist = session_cache[optype].head;
2756+	while ((sp = freelist) != NULL)
2757+		{
2758+		if (sp->session != CK_INVALID_HANDLE && sp->pid == mypid)
2759+			{
2760+			rv = pFuncList->C_CloseSession(sp->session);
2761+			if (rv != CKR_OK)
2762+				{
2763+				PK11err_add_data(PK11_F_FREE_ALL_SESSIONS,
2764+					PK11_R_CLOSESESSION, rv);
2765+				ret = 0;
2766+				}
2767+			}
2768+		freelist = sp->next;
2769+		pk11_free_nums(sp, optype);
2770+		OPENSSL_free(sp);
2771+		}
2772+
2773+#ifndef NOPTHREADS
2774+	(void) pthread_mutex_unlock(freelist_lock);
2775+#else
2776+	CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
2777+#endif
2778+	return (ret);
2779+	}
2780+
2781+
2782+static int
2783+pk11_setup_session(PK11_SESSION *sp, PK11_OPTYPE optype)
2784+	{
2785+	CK_RV rv;
2786+	CK_SLOT_ID myslot;
2787+
2788+	switch (optype)
2789+		{
2790+		case OP_RSA:
2791+		case OP_DSA:
2792+		case OP_DH:
2793+			myslot = pubkey_SLOTID;
2794+			break;
2795+		case OP_RAND:
2796+			myslot = rand_SLOTID;
2797+			break;
2798+		case OP_DIGEST:
2799+		case OP_CIPHER:
2800+			myslot = SLOTID;
2801+			break;
2802+		default:
2803+			PK11err(PK11_F_SETUP_SESSION,
2804+			    PK11_R_INVALID_OPERATION_TYPE);
2805+			return (0);
2806+		}
2807+
2808+	sp->session = CK_INVALID_HANDLE;
2809+#ifdef	DEBUG_SLOT_SELECTION
2810+	fprintf(stderr, "%s: myslot=%d optype=%d\n", PK11_DBG, myslot, optype);
2811+#endif	/* DEBUG_SLOT_SELECTION */
2812+	rv = pFuncList->C_OpenSession(myslot, CKF_SERIAL_SESSION,
2813+		NULL_PTR, NULL_PTR, &sp->session);
2814+	if (rv == CKR_CRYPTOKI_NOT_INITIALIZED)
2815+		{
2816+		/*
2817+		 * We are probably a child process so force the
2818+		 * reinitialize of the session
2819+		 */
2820+		pk11_library_initialized = FALSE;
2821+		if (!pk11_library_init(NULL))
2822+			return (0);
2823+		rv = pFuncList->C_OpenSession(myslot, CKF_SERIAL_SESSION,
2824+			NULL_PTR, NULL_PTR, &sp->session);
2825+		}
2826+	if (rv != CKR_OK)
2827+		{
2828+		PK11err_add_data(PK11_F_SETUP_SESSION, PK11_R_OPENSESSION, rv);
2829+		return (0);
2830+		}
2831+
2832+	sp->pid = getpid();
2833+
2834+	switch (optype)
2835+		{
2836+#ifndef OPENSSL_NO_RSA
2837+		case OP_RSA:
2838+			sp->opdata_rsa_pub_key = CK_INVALID_HANDLE;
2839+			sp->opdata_rsa_priv_key = CK_INVALID_HANDLE;
2840+			sp->opdata_rsa_pub = NULL;
2841+			sp->opdata_rsa_n_num = NULL;
2842+			sp->opdata_rsa_e_num = NULL;
2843+			sp->opdata_rsa_priv = NULL;
2844+			sp->opdata_rsa_pn_num = NULL;
2845+			sp->opdata_rsa_pe_num = NULL;
2846+			sp->opdata_rsa_d_num = NULL;
2847+			break;
2848+#endif	/* OPENSSL_NO_RSA */
2849+#ifndef OPENSSL_NO_DSA
2850+		case OP_DSA:
2851+			sp->opdata_dsa_pub_key = CK_INVALID_HANDLE;
2852+			sp->opdata_dsa_priv_key = CK_INVALID_HANDLE;
2853+			sp->opdata_dsa_pub = NULL;
2854+			sp->opdata_dsa_pub_num = NULL;
2855+			sp->opdata_dsa_priv = NULL;
2856+			sp->opdata_dsa_priv_num = NULL;
2857+			break;
2858+#endif	/* OPENSSL_NO_DSA */
2859+#ifndef OPENSSL_NO_DH
2860+		case OP_DH:
2861+			sp->opdata_dh_key = CK_INVALID_HANDLE;
2862+			sp->opdata_dh = NULL;
2863+			sp->opdata_dh_priv_num = NULL;
2864+			break;
2865+#endif	/* OPENSSL_NO_DH */
2866+		case OP_CIPHER:
2867+			sp->opdata_cipher_key = CK_INVALID_HANDLE;
2868+			sp->opdata_encrypt = -1;
2869+			break;
2870+		default:
2871+			break;
2872+		}
2873+
2874+	/*
2875+	 * We always initialize the session as containing a non-persistent
2876+	 * object. The key load functions set it to persistent if that is so.
2877+	 */
2878+	sp->pub_persistent = CK_FALSE;
2879+	sp->priv_persistent = CK_FALSE;
2880+	return (1);
2881+	}
2882+
2883+#ifndef OPENSSL_NO_RSA
2884+/* Destroy RSA public key from single session. */
2885+int
2886+pk11_destroy_rsa_object_pub(PK11_SESSION *sp, CK_BBOOL uselock)
2887+	{
2888+	int ret = 0;
2889+
2890+	if (sp->opdata_rsa_pub_key != CK_INVALID_HANDLE)
2891+		{
2892+		TRY_OBJ_DESTROY(sp, sp->opdata_rsa_pub_key,
2893+		    ret, uselock, OP_RSA, CK_FALSE);
2894+		sp->opdata_rsa_pub_key = CK_INVALID_HANDLE;
2895+		sp->opdata_rsa_pub = NULL;
2896+		if (sp->opdata_rsa_n_num != NULL)
2897+			{
2898+			BN_free(sp->opdata_rsa_n_num);
2899+			sp->opdata_rsa_n_num = NULL;
2900+			}
2901+		if (sp->opdata_rsa_e_num != NULL)
2902+			{
2903+			BN_free(sp->opdata_rsa_e_num);
2904+			sp->opdata_rsa_e_num = NULL;
2905+			}
2906+		}
2907+
2908+	return (ret);
2909+	}
2910+
2911+/* Destroy RSA private key from single session. */
2912+int
2913+pk11_destroy_rsa_object_priv(PK11_SESSION *sp, CK_BBOOL uselock)
2914+	{
2915+	int ret = 0;
2916+
2917+	if (sp->opdata_rsa_priv_key != CK_INVALID_HANDLE)
2918+		{
2919+		TRY_OBJ_DESTROY(sp, sp->opdata_rsa_priv_key,
2920+		    ret, uselock, OP_RSA, CK_TRUE);
2921+		sp->opdata_rsa_priv_key = CK_INVALID_HANDLE;
2922+		sp->opdata_rsa_priv = NULL;
2923+		if (sp->opdata_rsa_d_num != NULL)
2924+			{
2925+			BN_free(sp->opdata_rsa_d_num);
2926+			sp->opdata_rsa_d_num = NULL;
2927+			}
2928+
2929+		/*
2930+		 * For the RSA key by reference code, public components 'n'/'e'
2931+		 * are the key components we use to check for the cache hit. We
2932+		 * must free those as well.
2933+		 */
2934+		if (sp->opdata_rsa_pn_num != NULL)
2935+			{
2936+			BN_free(sp->opdata_rsa_pn_num);
2937+			sp->opdata_rsa_pn_num = NULL;
2938+			}
2939+		if (sp->opdata_rsa_pe_num != NULL)
2940+			{
2941+			BN_free(sp->opdata_rsa_pe_num);
2942+			sp->opdata_rsa_pe_num = NULL;
2943+			}
2944+		}
2945+
2946+	return (ret);
2947+	}
2948+
2949+/*
2950+ * Destroy RSA key object wrapper. If session is NULL, try to destroy all
2951+ * objects in the free list.
2952+ */
2953+int
2954+pk11_destroy_rsa_key_objects(PK11_SESSION *session)
2955+	{
2956+	int ret = 1;
2957+	PK11_SESSION *sp = NULL;
2958+	PK11_SESSION *local_free_session;
2959+	CK_BBOOL uselock = TRUE;
2960+
2961+	if (session != NULL)
2962+		local_free_session = session;
2963+	else
2964+		{
2965+#ifndef NOPTHREADS
2966+		(void) pthread_mutex_lock(session_cache[OP_RSA].lock);
2967+#else
2968+		CRYPTO_w_lock(CRYPTO_LOCK_PK11_ENGINE);
2969+#endif
2970+		local_free_session = session_cache[OP_RSA].head;
2971+		uselock = FALSE;
2972+		}
2973+
2974+	/*
2975+	 * go through the list of sessions and delete key objects
2976+	 */
2977+	while ((sp = local_free_session) != NULL)
2978+		{
2979+		local_free_session = sp->next;
2980+
2981+		/*
2982+		 * Do not terminate list traversal if one of the
2983+		 * destroy operations fails.
2984+		 */
2985+		if (pk11_destroy_rsa_object_pub(sp, uselock) == 0)
2986+			{
2987+			ret = 0;
2988+			continue;
2989+			}
2990+		if (pk11_destroy_rsa_object_priv(sp, uselock) == 0)
2991+			{
2992+			ret = 0;
2993+			continue;
2994+			}
2995+		}
2996+
2997+#ifndef NOPTHREADS
2998+	if (session == NULL)
2999+		(void) pthread_mutex_unlock(session_cache[OP_RSA].lock);
3000+#else
3001+	if (session == NULL)
3002+		CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
3003+#endif
3004+
3005+	return (ret);
3006+	}
3007+#endif	/* OPENSSL_NO_RSA */
3008+
3009+#ifndef OPENSSL_NO_DSA
3010+/* Destroy DSA public key from single session. */
3011+int
3012+pk11_destroy_dsa_object_pub(PK11_SESSION *sp, CK_BBOOL uselock)
3013+	{
3014+	int ret = 0;
3015+
3016+	if (sp->opdata_dsa_pub_key != CK_INVALID_HANDLE)
3017+		{
3018+		TRY_OBJ_DESTROY(sp, sp->opdata_dsa_pub_key,
3019+		    ret, uselock, OP_DSA, CK_FALSE);
3020+		sp->opdata_dsa_pub_key = CK_INVALID_HANDLE;
3021+		sp->opdata_dsa_pub = NULL;
3022+		if (sp->opdata_dsa_pub_num != NULL)
3023+			{
3024+			BN_free(sp->opdata_dsa_pub_num);
3025+			sp->opdata_dsa_pub_num = NULL;
3026+			}
3027+		}
3028+
3029+	return (ret);
3030+	}
3031+
3032+/* Destroy DSA private key from single session. */
3033+int
3034+pk11_destroy_dsa_object_priv(PK11_SESSION *sp, CK_BBOOL uselock)
3035+	{
3036+	int ret = 0;
3037+
3038+	if (sp->opdata_dsa_priv_key != CK_INVALID_HANDLE)
3039+		{
3040+		TRY_OBJ_DESTROY(sp, sp->opdata_dsa_priv_key,
3041+		    ret, uselock, OP_DSA, CK_TRUE);
3042+		sp->opdata_dsa_priv_key = CK_INVALID_HANDLE;
3043+		sp->opdata_dsa_priv = NULL;
3044+		if (sp->opdata_dsa_priv_num != NULL)
3045+			{
3046+			BN_free(sp->opdata_dsa_priv_num);
3047+			sp->opdata_dsa_priv_num = NULL;
3048+			}
3049+		}
3050+
3051+	return (ret);
3052+	}
3053+
3054+/*
3055+ * Destroy DSA key object wrapper. If session is NULL, try to destroy all
3056+ * objects in the free list.
3057+ */
3058+int
3059+pk11_destroy_dsa_key_objects(PK11_SESSION *session)
3060+	{
3061+	int ret = 1;
3062+	PK11_SESSION *sp = NULL;
3063+	PK11_SESSION *local_free_session;
3064+	CK_BBOOL uselock = TRUE;
3065+
3066+	if (session != NULL)
3067+		local_free_session = session;
3068+	else
3069+		{
3070+#ifndef NOPTHREADS
3071+		(void) pthread_mutex_lock(session_cache[OP_DSA].lock);
3072+#else
3073+		CRYPTO_w_lock(CRYPTO_LOCK_PK11_ENGINE);
3074+#endif
3075+		local_free_session = session_cache[OP_DSA].head;
3076+		uselock = FALSE;
3077+		}
3078+
3079+	/*
3080+	 * go through the list of sessions and delete key objects
3081+	 */
3082+	while ((sp = local_free_session) != NULL)
3083+		{
3084+		local_free_session = sp->next;
3085+
3086+		/*
3087+		 * Do not terminate list traversal if one of the
3088+		 * destroy operations fails.
3089+		 */
3090+		if (pk11_destroy_dsa_object_pub(sp, uselock) == 0)
3091+			{
3092+			ret = 0;
3093+			continue;
3094+			}
3095+		if (pk11_destroy_dsa_object_priv(sp, uselock) == 0)
3096+			{
3097+			ret = 0;
3098+			continue;
3099+			}
3100+		}
3101+
3102+#ifndef NOPTHREADS
3103+	if (session == NULL)
3104+		(void) pthread_mutex_unlock(session_cache[OP_DSA].lock);
3105+#else
3106+	if (session == NULL)
3107+		CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
3108+#endif
3109+
3110+	return (ret);
3111+	}
3112+#endif	/* OPENSSL_NO_DSA */
3113+
3114+#ifndef OPENSSL_NO_DH
3115+/* Destroy DH key from single session. */
3116+int
3117+pk11_destroy_dh_object(PK11_SESSION *sp, CK_BBOOL uselock)
3118+	{
3119+	int ret = 0;
3120+
3121+	if (sp->opdata_dh_key != CK_INVALID_HANDLE)
3122+		{
3123+		TRY_OBJ_DESTROY(sp, sp->opdata_dh_key,
3124+		    ret, uselock, OP_DH, CK_TRUE);
3125+		sp->opdata_dh_key = CK_INVALID_HANDLE;
3126+		sp->opdata_dh = NULL;
3127+		if (sp->opdata_dh_priv_num != NULL)
3128+			{
3129+			BN_free(sp->opdata_dh_priv_num);
3130+			sp->opdata_dh_priv_num = NULL;
3131+			}
3132+		}
3133+
3134+	return (ret);
3135+	}
3136+
3137+/*
3138+ * Destroy DH key object wrapper.
3139+ *
3140+ * arg0: pointer to PKCS#11 engine session structure
3141+ *       if session is NULL, try to destroy all objects in the free list
3142+ */
3143+int
3144+pk11_destroy_dh_key_objects(PK11_SESSION *session)
3145+	{
3146+	int ret = 1;
3147+	PK11_SESSION *sp = NULL;
3148+	PK11_SESSION *local_free_session;
3149+	CK_BBOOL uselock = TRUE;
3150+
3151+	if (session != NULL)
3152+		local_free_session = session;
3153+	else
3154+		{
3155+#ifndef NOPTHREADS
3156+		(void) pthread_mutex_lock(session_cache[OP_DH].lock);
3157+#else
3158+		CRYPTO_w_lock(CRYPTO_LOCK_PK11_ENGINE);
3159+#endif
3160+		local_free_session = session_cache[OP_DH].head;
3161+		uselock = FALSE;
3162+		}
3163+
3164+	while ((sp = local_free_session) != NULL)
3165+		{
3166+		local_free_session = sp->next;
3167+
3168+		/*
3169+		 * Do not terminate list traversal if one of the
3170+		 * destroy operations fails.
3171+		 */
3172+		if (pk11_destroy_dh_object(sp, uselock) == 0)
3173+			{
3174+			ret = 0;
3175+			continue;
3176+			}
3177+		}
3178+
3179+#ifndef NOPTHREADS
3180+	if (session == NULL)
3181+		(void) pthread_mutex_unlock(session_cache[OP_DH].lock);
3182+#else
3183+	if (session == NULL)
3184+		CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
3185+#endif
3186+
3187+	return (ret);
3188+	}
3189+#endif	/* OPENSSL_NO_DH */
3190+
3191+static int
3192+pk11_destroy_object(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE oh,
3193+	CK_BBOOL persistent)
3194+	{
3195+	CK_RV rv;
3196+
3197+	/*
3198+	 * We never try to destroy persistent objects which are the objects
3199+	 * stored in the keystore. Also, we always use read-only sessions so
3200+	 * C_DestroyObject() would be returning CKR_SESSION_READ_ONLY here.
3201+	 */
3202+	if (persistent == CK_TRUE)
3203+		return (1);
3204+
3205+	rv = pFuncList->C_DestroyObject(session, oh);
3206+	if (rv != CKR_OK)
3207+		{
3208+		PK11err_add_data(PK11_F_DESTROY_OBJECT, PK11_R_DESTROYOBJECT,
3209+		    rv);
3210+		return (0);
3211+		}
3212+
3213+	return (1);
3214+	}
3215+
3216+
3217+/* Symmetric ciphers and digests support functions */
3218+
3219+static int
3220+cipher_nid_to_pk11(int nid)
3221+	{
3222+	int i;
3223+
3224+	for (i = 0; i < PK11_CIPHER_MAX; i++)
3225+		if (ciphers[i].nid == nid)
3226+			return (ciphers[i].id);
3227+	return (-1);
3228+	}
3229+
3230+static int
3231+pk11_usable_ciphers(const int **nids)
3232+	{
3233+	if (cipher_count > 0)
3234+		*nids = cipher_nids;
3235+	else
3236+		*nids = NULL;
3237+	return (cipher_count);
3238+	}
3239+
3240+static int
3241+pk11_usable_digests(const int **nids)
3242+	{
3243+	if (digest_count > 0)
3244+		*nids = digest_nids;
3245+	else
3246+		*nids = NULL;
3247+	return (digest_count);
3248+	}
3249+
3250+/*
3251+ * Init context for encryption or decryption using a symmetric key.
3252+ */
3253+static int pk11_init_symmetric(EVP_CIPHER_CTX *ctx, PK11_CIPHER *pcipher,
3254+	PK11_SESSION *sp, CK_MECHANISM_PTR pmech)
3255+	{
3256+	CK_RV rv;
3257+#ifdef	SOLARIS_AES_CTR
3258+	CK_AES_CTR_PARAMS ctr_params;
3259+#endif	/* SOLARIS_AES_CTR */
3260+
3261+	/*
3262+	 * We expect pmech->mechanism to be already set and
3263+	 * pParameter/ulParameterLen initialized to NULL/0 before
3264+	 * pk11_init_symetric() is called.
3265+	 */
3266+	OPENSSL_assert(pmech->mechanism != 0);
3267+	OPENSSL_assert(pmech->pParameter == NULL);
3268+	OPENSSL_assert(pmech->ulParameterLen == 0);
3269+
3270+#ifdef	SOLARIS_AES_CTR
3271+	if (ctx->cipher->nid == NID_aes_128_ctr ||
3272+	    ctx->cipher->nid == NID_aes_192_ctr ||
3273+	    ctx->cipher->nid == NID_aes_256_ctr)
3274+		{
3275+		pmech->pParameter = (void *)(&ctr_params);
3276+		pmech->ulParameterLen = sizeof (ctr_params);
3277+		/*
3278+		 * For now, we are limited to the fixed length of the counter,
3279+		 * it covers the whole counter block. That's what RFC 4344
3280+		 * needs. For more information on internal structure of the
3281+		 * counter block, see RFC 3686. If needed in the future, we can
3282+		 * add code so that the counter length can be set via
3283+		 * ENGINE_ctrl() function.
3284+		 */
3285+		ctr_params.ulCounterBits = AES_BLOCK_SIZE * 8;
3286+		OPENSSL_assert(pcipher->iv_len == AES_BLOCK_SIZE);
3287+		(void) memcpy(ctr_params.cb, ctx->iv, AES_BLOCK_SIZE);
3288+		}
3289+	else
3290+#endif	/* SOLARIS_AES_CTR */
3291+		{
3292+		if (pcipher->iv_len > 0)
3293+			{
3294+			pmech->pParameter = (void *)ctx->iv;
3295+			pmech->ulParameterLen = pcipher->iv_len;
3296+			}
3297+		}
3298+
3299+	/* if we get here, the encryption needs to be reinitialized */
3300+	if (ctx->encrypt)
3301+		rv = pFuncList->C_EncryptInit(sp->session, pmech,
3302+			sp->opdata_cipher_key);
3303+	else
3304+		rv = pFuncList->C_DecryptInit(sp->session, pmech,
3305+			sp->opdata_cipher_key);
3306+
3307+	if (rv != CKR_OK)
3308+		{
3309+		PK11err_add_data(PK11_F_CIPHER_INIT, ctx->encrypt ?
3310+		    PK11_R_ENCRYPTINIT : PK11_R_DECRYPTINIT, rv);
3311+		pk11_return_session(sp, OP_CIPHER);
3312+		return (0);
3313+		}
3314+
3315+	return (1);
3316+	}
3317+
3318+/* ARGSUSED */
3319+static int
3320+pk11_cipher_init(EVP_CIPHER_CTX *ctx, const unsigned char *key,
3321+    const unsigned char *iv, int enc)
3322+	{
3323+	CK_MECHANISM mech;
3324+	int index;
3325+	PK11_CIPHER_STATE *state = (PK11_CIPHER_STATE *) ctx->cipher_data;
3326+	PK11_SESSION *sp;
3327+	PK11_CIPHER *p_ciph_table_row;
3328+
3329+	state->sp = NULL;
3330+
3331+	index = cipher_nid_to_pk11(ctx->cipher->nid);
3332+	if (index < 0 || index >= PK11_CIPHER_MAX)
3333+		return (0);
3334+
3335+	p_ciph_table_row = &ciphers[index];
3336+	/*
3337+	 * iv_len in the ctx->cipher structure is the maximum IV length for the
3338+	 * current cipher and it must be less or equal to the IV length in our
3339+	 * ciphers table. The key length must be in the allowed interval. From
3340+	 * all cipher modes that the PKCS#11 engine supports only RC4 allows a
3341+	 * key length to be in some range, all other NIDs have a precise key
3342+	 * length. Every application can define its own EVP functions so this
3343+	 * code serves as a sanity check.
3344+	 *
3345+	 * Note that the reason why the IV length in ctx->cipher might be
3346+	 * greater than the actual length is that OpenSSL uses BLOCK_CIPHER_defs
3347+	 * macro to define functions that return EVP structures for all DES
3348+	 * modes. So, even ECB modes get 8 byte IV.
3349+	 */
3350+	if (ctx->cipher->iv_len < p_ciph_table_row->iv_len ||
3351+	    ctx->key_len < p_ciph_table_row->min_key_len ||
3352+	    ctx->key_len > p_ciph_table_row->max_key_len) {
3353+		PK11err(PK11_F_CIPHER_INIT, PK11_R_KEY_OR_IV_LEN_PROBLEM);
3354+		return (0);
3355+	}
3356+
3357+	if ((sp = pk11_get_session(OP_CIPHER)) == NULL)
3358+		return (0);
3359+
3360+	/* if applicable, the mechanism parameter is used for IV */
3361+	mech.mechanism = p_ciph_table_row->mech_type;
3362+	mech.pParameter = NULL;
3363+	mech.ulParameterLen = 0;
3364+
3365+	/* The key object is destroyed here if it is not the current key. */
3366+	(void) check_new_cipher_key(sp, key, ctx->key_len);
3367+
3368+	/*
3369+	 * If the key is the same and the encryption is also the same, then
3370+	 * just reuse it. However, we must not forget to reinitialize the
3371+	 * context that was finalized in pk11_cipher_cleanup().
3372+	 */
3373+	if (sp->opdata_cipher_key != CK_INVALID_HANDLE &&
3374+	    sp->opdata_encrypt == ctx->encrypt)
3375+		{
3376+		state->sp = sp;
3377+		if (pk11_init_symmetric(ctx, p_ciph_table_row, sp, &mech) == 0)
3378+			return (0);
3379+
3380+		return (1);
3381+		}
3382+
3383+	/*
3384+	 * Check if the key has been invalidated. If so, a new key object
3385+	 * needs to be created.
3386+	 */
3387+	if (sp->opdata_cipher_key == CK_INVALID_HANDLE)
3388+		{
3389+		sp->opdata_cipher_key = pk11_get_cipher_key(
3390+			ctx, key, p_ciph_table_row->key_type, sp);
3391+		}
3392+
3393+	if (sp->opdata_encrypt != ctx->encrypt && sp->opdata_encrypt != -1)
3394+		{
3395+		/*
3396+		 * The previous encryption/decryption is different. Need to
3397+		 * terminate the previous * active encryption/decryption here.
3398+		 */
3399+		if (!pk11_cipher_final(sp))
3400+			{
3401+			pk11_return_session(sp, OP_CIPHER);
3402+			return (0);
3403+			}
3404+		}
3405+
3406+	if (sp->opdata_cipher_key == CK_INVALID_HANDLE)
3407+		{
3408+		pk11_return_session(sp, OP_CIPHER);
3409+		return (0);
3410+		}
3411+
3412+	/* now initialize the context with a new key */
3413+	if (pk11_init_symmetric(ctx, p_ciph_table_row, sp, &mech) == 0)
3414+		return (0);
3415+
3416+	sp->opdata_encrypt = ctx->encrypt;
3417+	state->sp = sp;
3418+
3419+	return (1);
3420+	}
3421+
3422+/*
3423+ * When reusing the same key in an encryption/decryption session for a
3424+ * decryption/encryption session, we need to close the active session
3425+ * and recreate a new one. Note that the key is in the global session so
3426+ * that it needs not be recreated.
3427+ *
3428+ * It is more appropriate to use C_En/DecryptFinish here. At the time of this
3429+ * development, these two functions in the PKCS#11 libraries used return
3430+ * unexpected errors when passing in 0 length output. It may be a good
3431+ * idea to try them again if performance is a problem here and fix
3432+ * C_En/DecryptFinial if there are bugs there causing the problem.
3433+ */
3434+static int
3435+pk11_cipher_final(PK11_SESSION *sp)
3436+	{
3437+	CK_RV rv;
3438+
3439+	rv = pFuncList->C_CloseSession(sp->session);
3440+	if (rv != CKR_OK)
3441+		{
3442+		PK11err_add_data(PK11_F_CIPHER_FINAL, PK11_R_CLOSESESSION, rv);
3443+		return (0);
3444+		}
3445+
3446+	rv = pFuncList->C_OpenSession(SLOTID, CKF_SERIAL_SESSION,
3447+		NULL_PTR, NULL_PTR, &sp->session);
3448+	if (rv != CKR_OK)
3449+		{
3450+		PK11err_add_data(PK11_F_CIPHER_FINAL, PK11_R_OPENSESSION, rv);
3451+		return (0);
3452+		}
3453+
3454+	return (1);
3455+	}
3456+
3457+/*
3458+ * An engine interface function. The calling function allocates sufficient
3459+ * memory for the output buffer "out" to hold the results.
3460+ */
3461+#if OPENSSL_VERSION_NUMBER < 0x10000000L
3462+static int
3463+pk11_cipher_do_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
3464+	const unsigned char *in, unsigned int inl)
3465+#else
3466+static int
3467+pk11_cipher_do_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
3468+	const unsigned char *in, size_t inl)
3469+#endif
3470+	{
3471+	PK11_CIPHER_STATE *state = (PK11_CIPHER_STATE *) ctx->cipher_data;
3472+	PK11_SESSION *sp;
3473+	CK_RV rv;
3474+	unsigned long outl = inl;
3475+
3476+	if (state == NULL || state->sp == NULL)
3477+		return (0);
3478+
3479+	sp = (PK11_SESSION *) state->sp;
3480+
3481+	if (!inl)
3482+		return (1);
3483+
3484+	/* RC4 is the only stream cipher we support */
3485+	if (ctx->cipher->nid != NID_rc4 && (inl % ctx->cipher->block_size) != 0)
3486+		return (0);
3487+
3488+	if (ctx->encrypt)
3489+		{
3490+		rv = pFuncList->C_EncryptUpdate(sp->session,
3491+			(unsigned char *)in, inl, out, &outl);
3492+
3493+		if (rv != CKR_OK)
3494+			{
3495+			PK11err_add_data(PK11_F_CIPHER_DO_CIPHER,
3496+			    PK11_R_ENCRYPTUPDATE, rv);
3497+			return (0);
3498+			}
3499+		}
3500+	else
3501+		{
3502+		rv = pFuncList->C_DecryptUpdate(sp->session,
3503+			(unsigned char *)in, inl, out, &outl);
3504+
3505+		if (rv != CKR_OK)
3506+			{
3507+			PK11err_add_data(PK11_F_CIPHER_DO_CIPHER,
3508+			    PK11_R_DECRYPTUPDATE, rv);
3509+			return (0);
3510+			}
3511+		}
3512+
3513+	/*
3514+	 * For DES_CBC, DES3_CBC, AES_CBC, and RC4, the output size is always
3515+	 * the same size of input.
3516+	 * The application has guaranteed to call the block ciphers with
3517+	 * correctly aligned buffers.
3518+	 */
3519+	if (inl != outl)
3520+		return (0);
3521+
3522+	return (1);
3523+	}
3524+
3525+/*
3526+ * Return the session to the pool. Calling C_EncryptFinal() and C_DecryptFinal()
3527+ * here is the right thing because in EVP_DecryptFinal_ex(), engine's
3528+ * do_cipher() is not even called, and in EVP_EncryptFinal_ex() it is called but
3529+ * the engine can't find out that it's the finalizing call. We wouldn't
3530+ * necessarily have to finalize the context here since reinitializing it with
3531+ * C_(Encrypt|Decrypt)Init() should be fine but for the sake of correctness,
3532+ * let's do it. Some implementations might leak memory if the previously used
3533+ * context is initialized without finalizing it first.
3534+ */
3535+static int
3536+pk11_cipher_cleanup(EVP_CIPHER_CTX *ctx)
3537+	{
3538+	CK_RV rv;
3539+	CK_ULONG len = EVP_MAX_BLOCK_LENGTH;
3540+	CK_BYTE buf[EVP_MAX_BLOCK_LENGTH];
3541+	PK11_CIPHER_STATE *state = ctx->cipher_data;
3542+
3543+	if (state != NULL && state->sp != NULL)
3544+		{
3545+		/*
3546+		 * We are not interested in the data here, we just need to get
3547+		 * rid of the context.
3548+		 */
3549+		if (ctx->encrypt)
3550+			rv = pFuncList->C_EncryptFinal(
3551+			    state->sp->session, buf, &len);
3552+		else
3553+			rv = pFuncList->C_DecryptFinal(
3554+			    state->sp->session, buf, &len);
3555+
3556+		if (rv != CKR_OK)
3557+			{
3558+			PK11err_add_data(PK11_F_CIPHER_CLEANUP, ctx->encrypt ?
3559+			    PK11_R_ENCRYPTFINAL : PK11_R_DECRYPTFINAL, rv);
3560+			pk11_return_session(state->sp, OP_CIPHER);
3561+			return (0);
3562+			}
3563+
3564+		pk11_return_session(state->sp, OP_CIPHER);
3565+		state->sp = NULL;
3566+		}
3567+
3568+	return (1);
3569+	}
3570+
3571+/*
3572+ * Registered by the ENGINE when used to find out how to deal with
3573+ * a particular NID in the ENGINE. This says what we'll do at the
3574+ * top level - note, that list is restricted by what we answer with
3575+ */
3576+/* ARGSUSED */
3577+static int
3578+pk11_engine_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
3579+	const int **nids, int nid)
3580+	{
3581+	if (!cipher)
3582+		return (pk11_usable_ciphers(nids));
3583+
3584+	switch (nid)
3585+		{
3586+		case NID_des_ede3_cbc:
3587+			*cipher = &pk11_3des_cbc;
3588+			break;
3589+		case NID_des_cbc:
3590+			*cipher = &pk11_des_cbc;
3591+			break;
3592+		case NID_des_ede3_ecb:
3593+			*cipher = &pk11_3des_ecb;
3594+			break;
3595+		case NID_des_ecb:
3596+			*cipher = &pk11_des_ecb;
3597+			break;
3598+		case NID_aes_128_cbc:
3599+			*cipher = &pk11_aes_128_cbc;
3600+			break;
3601+		case NID_aes_192_cbc:
3602+			*cipher = &pk11_aes_192_cbc;
3603+			break;
3604+		case NID_aes_256_cbc:
3605+			*cipher = &pk11_aes_256_cbc;
3606+			break;
3607+		case NID_aes_128_ecb:
3608+			*cipher = &pk11_aes_128_ecb;
3609+			break;
3610+		case NID_aes_192_ecb:
3611+			*cipher = &pk11_aes_192_ecb;
3612+			break;
3613+		case NID_aes_256_ecb:
3614+			*cipher = &pk11_aes_256_ecb;
3615+			break;
3616+		case NID_bf_cbc:
3617+			*cipher = &pk11_bf_cbc;
3618+			break;
3619+		case NID_rc4:
3620+			*cipher = &pk11_rc4;
3621+			break;
3622+		default:
3623+#ifdef	SOLARIS_AES_CTR
3624+			/*
3625+			 * These can't be in separated cases because the NIDs
3626+			 * here are not constants.
3627+			 */
3628+			if (nid == NID_aes_128_ctr)
3629+				*cipher = &pk11_aes_128_ctr;
3630+			else if (nid == NID_aes_192_ctr)
3631+				*cipher = &pk11_aes_192_ctr;
3632+			else if (nid == NID_aes_256_ctr)
3633+				*cipher = &pk11_aes_256_ctr;
3634+			else
3635+#endif	/* SOLARIS_AES_CTR */
3636+			*cipher = NULL;
3637+			break;
3638+		}
3639+	return (*cipher != NULL);
3640+	}
3641+
3642+/* ARGSUSED */
3643+static int
3644+pk11_engine_digests(ENGINE *e, const EVP_MD **digest,
3645+	const int **nids, int nid)
3646+	{
3647+	if (!digest)
3648+		return (pk11_usable_digests(nids));
3649+
3650+	switch (nid)
3651+		{
3652+		case NID_md5:
3653+			*digest = &pk11_md5;
3654+			break;
3655+		case NID_sha1:
3656+			*digest = &pk11_sha1;
3657+			break;
3658+		case NID_sha224:
3659+			*digest = &pk11_sha224;
3660+			break;
3661+		case NID_sha256:
3662+			*digest = &pk11_sha256;
3663+			break;
3664+		case NID_sha384:
3665+			*digest = &pk11_sha384;
3666+			break;
3667+		case NID_sha512:
3668+			*digest = &pk11_sha512;
3669+			break;
3670+		default:
3671+			*digest = NULL;
3672+			break;
3673+		}
3674+	return (*digest != NULL);
3675+	}
3676+
3677+
3678+/* Create a secret key object in a PKCS#11 session */
3679+static CK_OBJECT_HANDLE pk11_get_cipher_key(EVP_CIPHER_CTX *ctx,
3680+	const unsigned char *key, CK_KEY_TYPE key_type, PK11_SESSION *sp)
3681+	{
3682+	CK_RV rv;
3683+	CK_OBJECT_HANDLE h_key = CK_INVALID_HANDLE;
3684+	CK_OBJECT_CLASS obj_key = CKO_SECRET_KEY;
3685+	CK_ULONG ul_key_attr_count = 6;
3686+
3687+	CK_ATTRIBUTE  a_key_template[] =
3688+		{
3689+		{CKA_CLASS, (void*) NULL, sizeof (CK_OBJECT_CLASS)},
3690+		{CKA_KEY_TYPE, (void*) NULL, sizeof (CK_KEY_TYPE)},
3691+		{CKA_TOKEN, &false, sizeof (false)},
3692+		{CKA_ENCRYPT, &true, sizeof (true)},
3693+		{CKA_DECRYPT, &true, sizeof (true)},
3694+		{CKA_VALUE, (void*) NULL, 0},
3695+		};
3696+
3697+	/*
3698+	 * Create secret key object in global_session. All other sessions
3699+	 * can use the key handles. Here is why:
3700+	 * OpenSSL will call EncryptInit and EncryptUpdate using a secret key.
3701+	 * It may then call DecryptInit and DecryptUpdate using the same key.
3702+	 * To use the same key object, we need to call EncryptFinal with
3703+	 * a 0 length message. Currently, this does not work for 3DES
3704+	 * mechanism. To get around this problem, we close the session and
3705+	 * then create a new session to use the same key object. When a session
3706+	 * is closed, all the object handles will be invalid. Thus, create key
3707+	 * objects in a global session, an individual session may be closed to
3708+	 * terminate the active operation.
3709+	 */
3710+	CK_SESSION_HANDLE session = global_session;
3711+	a_key_template[0].pValue = &obj_key;
3712+	a_key_template[1].pValue = &key_type;
3713+	a_key_template[5].pValue = (void *) key;
3714+	a_key_template[5].ulValueLen = (unsigned long) ctx->key_len;
3715+
3716+	rv = pFuncList->C_CreateObject(session,
3717+		a_key_template, ul_key_attr_count, &h_key);
3718+	if (rv != CKR_OK)
3719+		{
3720+		PK11err_add_data(PK11_F_GET_CIPHER_KEY, PK11_R_CREATEOBJECT,
3721+		    rv);
3722+		goto err;
3723+		}
3724+
3725+	/*
3726+	 * Save the key information used in this session.
3727+	 * The max can be saved is PK11_KEY_LEN_MAX.
3728+	 */
3729+	sp->opdata_key_len = ctx->key_len > PK11_KEY_LEN_MAX ?
3730+		PK11_KEY_LEN_MAX : ctx->key_len;
3731+	(void) memcpy(sp->opdata_key, key, sp->opdata_key_len);
3732+err:
3733+
3734+	return (h_key);
3735+	}
3736+
3737+static int
3738+md_nid_to_pk11(int nid)
3739+	{
3740+	int i;
3741+
3742+	for (i = 0; i < PK11_DIGEST_MAX; i++)
3743+		if (digests[i].nid == nid)
3744+			return (digests[i].id);
3745+	return (-1);
3746+	}
3747+
3748+static int
3749+pk11_digest_init(EVP_MD_CTX *ctx)
3750+	{
3751+	CK_RV rv;
3752+	CK_MECHANISM mech;
3753+	int index;
3754+	PK11_SESSION *sp;
3755+	PK11_DIGEST *pdp;
3756+	PK11_CIPHER_STATE *state = (PK11_CIPHER_STATE *) ctx->md_data;
3757+
3758+	state->sp = NULL;
3759+
3760+	index = md_nid_to_pk11(ctx->digest->type);
3761+	if (index < 0 || index >= PK11_DIGEST_MAX)
3762+		return (0);
3763+
3764+	pdp = &digests[index];
3765+	if ((sp = pk11_get_session(OP_DIGEST)) == NULL)
3766+		return (0);
3767+
3768+	/* at present, no parameter is needed for supported digests */
3769+	mech.mechanism = pdp->mech_type;
3770+	mech.pParameter = NULL;
3771+	mech.ulParameterLen = 0;
3772+
3773+	rv = pFuncList->C_DigestInit(sp->session, &mech);
3774+
3775+	if (rv != CKR_OK)
3776+		{
3777+		PK11err_add_data(PK11_F_DIGEST_INIT, PK11_R_DIGESTINIT, rv);
3778+		pk11_return_session(sp, OP_DIGEST);
3779+		return (0);
3780+		}
3781+
3782+	state->sp = sp;
3783+
3784+	return (1);
3785+	}
3786+
3787+static int
3788+pk11_digest_update(EVP_MD_CTX *ctx, const void *data, size_t count)
3789+	{
3790+	CK_RV rv;
3791+	PK11_CIPHER_STATE *state = (PK11_CIPHER_STATE *) ctx->md_data;
3792+
3793+	/* 0 length message will cause a failure in C_DigestFinal */
3794+	if (count == 0)
3795+		return (1);
3796+
3797+	if (state == NULL || state->sp == NULL)
3798+		return (0);
3799+
3800+	rv = pFuncList->C_DigestUpdate(state->sp->session, (CK_BYTE *) data,
3801+		count);
3802+
3803+	if (rv != CKR_OK)
3804+		{
3805+		PK11err_add_data(PK11_F_DIGEST_UPDATE, PK11_R_DIGESTUPDATE, rv);
3806+		pk11_return_session(state->sp, OP_DIGEST);
3807+		state->sp = NULL;
3808+		return (0);
3809+		}
3810+
3811+	return (1);
3812+	}
3813+
3814+static int
3815+pk11_digest_final(EVP_MD_CTX *ctx, unsigned char *md)
3816+	{
3817+	CK_RV rv;
3818+	unsigned long len;
3819+	PK11_CIPHER_STATE *state = (PK11_CIPHER_STATE *) ctx->md_data;
3820+	len = ctx->digest->md_size;
3821+
3822+	if (state == NULL || state->sp == NULL)
3823+		return (0);
3824+
3825+	rv = pFuncList->C_DigestFinal(state->sp->session, md, &len);
3826+
3827+	if (rv != CKR_OK)
3828+		{
3829+		PK11err_add_data(PK11_F_DIGEST_FINAL, PK11_R_DIGESTFINAL, rv);
3830+		pk11_return_session(state->sp, OP_DIGEST);
3831+		state->sp = NULL;
3832+		return (0);
3833+		}
3834+
3835+	if (ctx->digest->md_size != len)
3836+		return (0);
3837+
3838+	/*
3839+	 * Final is called and digest is returned, so return the session
3840+	 * to the pool
3841+	 */
3842+	pk11_return_session(state->sp, OP_DIGEST);
3843+	state->sp = NULL;
3844+
3845+	return (1);
3846+	}
3847+
3848+static int
3849+pk11_digest_copy(EVP_MD_CTX *to, const EVP_MD_CTX *from)
3850+	{
3851+	CK_RV rv;
3852+	int ret = 0;
3853+	PK11_CIPHER_STATE *state, *state_to;
3854+	CK_BYTE_PTR pstate = NULL;
3855+	CK_ULONG ul_state_len;
3856+
3857+	/* The copy-from state */
3858+	state = (PK11_CIPHER_STATE *) from->md_data;
3859+	if (state == NULL || state->sp == NULL)
3860+		goto err;
3861+
3862+	/* Initialize the copy-to state */
3863+	if (!pk11_digest_init(to))
3864+		goto err;
3865+	state_to = (PK11_CIPHER_STATE *) to->md_data;
3866+
3867+	/* Get the size of the operation state of the copy-from session */
3868+	rv = pFuncList->C_GetOperationState(state->sp->session, NULL,
3869+		&ul_state_len);
3870+
3871+	if (rv != CKR_OK)
3872+		{
3873+		PK11err_add_data(PK11_F_DIGEST_COPY, PK11_R_GET_OPERATION_STATE,
3874+		    rv);
3875+		goto err;
3876+		}
3877+	if (ul_state_len == 0)
3878+		{
3879+		goto err;
3880+		}
3881+
3882+	pstate = OPENSSL_malloc(ul_state_len);
3883+	if (pstate == NULL)
3884+		{
3885+		PK11err(PK11_F_DIGEST_COPY, PK11_R_MALLOC_FAILURE);
3886+		goto err;
3887+		}
3888+
3889+	/* Get the operation state of the copy-from session */
3890+	rv = pFuncList->C_GetOperationState(state->sp->session, pstate,
3891+		&ul_state_len);
3892+
3893+	if (rv != CKR_OK)
3894+		{
3895+		PK11err_add_data(PK11_F_DIGEST_COPY, PK11_R_GET_OPERATION_STATE,
3896+		    rv);
3897+		goto err;
3898+		}
3899+
3900+	/* Set the operation state of the copy-to session */
3901+	rv = pFuncList->C_SetOperationState(state_to->sp->session, pstate,
3902+		ul_state_len, 0, 0);
3903+
3904+	if (rv != CKR_OK)
3905+		{
3906+		PK11err_add_data(PK11_F_DIGEST_COPY,
3907+		    PK11_R_SET_OPERATION_STATE, rv);
3908+		goto err;
3909+		}
3910+
3911+	ret = 1;
3912+err:
3913+	if (pstate != NULL)
3914+		OPENSSL_free(pstate);
3915+
3916+	return (ret);
3917+	}
3918+
3919+/* Return any pending session state to the pool */
3920+static int
3921+pk11_digest_cleanup(EVP_MD_CTX *ctx)
3922+	{
3923+	PK11_CIPHER_STATE *state = ctx->md_data;
3924+	unsigned char buf[EVP_MAX_MD_SIZE];
3925+
3926+	if (state != NULL && state->sp != NULL)
3927+		{
3928+		/*
3929+		 * If state->sp is not NULL then pk11_digest_final() has not
3930+		 * been called yet. We must call it now to free any memory
3931+		 * that might have been allocated in the token when
3932+		 * pk11_digest_init() was called. pk11_digest_final()
3933+		 * will return the session to the cache.
3934+		 */
3935+		if (!pk11_digest_final(ctx, buf))
3936+			return (0);
3937+		}
3938+
3939+	return (1);
3940+	}
3941+
3942+/*
3943+ * Check if the new key is the same as the key object in the session. If the key
3944+ * is the same, no need to create a new key object. Otherwise, the old key
3945+ * object needs to be destroyed and a new one will be created. Return 1 for
3946+ * cache hit, 0 for cache miss. Note that we must check the key length first
3947+ * otherwise we could end up reusing a different, longer key with the same
3948+ * prefix.
3949+ */
3950+static int check_new_cipher_key(PK11_SESSION *sp, const unsigned char *key,
3951+	int key_len)
3952+	{
3953+	if (sp->opdata_key_len != key_len ||
3954+	    memcmp(sp->opdata_key, key, key_len) != 0)
3955+		{
3956+		(void) pk11_destroy_cipher_key_objects(sp);
3957+		return (0);
3958+		}
3959+	return (1);
3960+	}
3961+
3962+/* Destroy one or more secret key objects. */
3963+static int pk11_destroy_cipher_key_objects(PK11_SESSION *session)
3964+	{
3965+	int ret = 0;
3966+	PK11_SESSION *sp = NULL;
3967+	PK11_SESSION *local_free_session;
3968+
3969+	if (session != NULL)
3970+		local_free_session = session;
3971+	else
3972+		{
3973+#ifndef NOPTHREADS
3974+		(void) pthread_mutex_lock(session_cache[OP_CIPHER].lock);
3975+#else
3976+		CRYPTO_w_lock(CRYPTO_LOCK_PK11_ENGINE);
3977+#endif
3978+		local_free_session = session_cache[OP_CIPHER].head;
3979+		}
3980+
3981+	while ((sp = local_free_session) != NULL)
3982+		{
3983+		local_free_session = sp->next;
3984+
3985+		if (sp->opdata_cipher_key != CK_INVALID_HANDLE)
3986+			{
3987+			/*
3988+			 * The secret key object is created in the
3989+			 * global_session. See pk11_get_cipher_key().
3990+			 */
3991+			if (pk11_destroy_object(global_session,
3992+				sp->opdata_cipher_key, CK_FALSE) == 0)
3993+				goto err;
3994+			sp->opdata_cipher_key = CK_INVALID_HANDLE;
3995+			}
3996+		}
3997+	ret = 1;
3998+err:
3999+
4000+#ifndef NOPTHREADS
4001+	if (session == NULL)
4002+		(void) pthread_mutex_unlock(session_cache[OP_CIPHER].lock);
4003+#else
4004+	if (session == NULL)
4005+		CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
4006+#endif
4007+
4008+	return (ret);
4009+	}
4010+
4011+
4012+/*
4013+ * Public key mechanisms optionally supported
4014+ *
4015+ * CKM_RSA_X_509
4016+ * CKM_RSA_PKCS
4017+ * CKM_DSA
4018+ *
4019+ * The first slot that supports at least one of those mechanisms is chosen as a
4020+ * public key slot.
4021+ *
4022+ * Symmetric ciphers optionally supported
4023+ *
4024+ * CKM_DES3_CBC
4025+ * CKM_DES_CBC
4026+ * CKM_AES_CBC
4027+ * CKM_DES3_ECB
4028+ * CKM_DES_ECB
4029+ * CKM_AES_ECB
4030+ * CKM_AES_CTR
4031+ * CKM_RC4
4032+ * CKM_BLOWFISH_CBC
4033+ *
4034+ * Digests optionally supported
4035+ *
4036+ * CKM_MD5
4037+ * CKM_SHA_1
4038+ * CKM_SHA224
4039+ * CKM_SHA256
4040+ * CKM_SHA384
4041+ * CKM_SHA512
4042+ *
4043+ * The output of this function is a set of global variables indicating which
4044+ * mechanisms from RSA, DSA, DH and RAND are present, and also two arrays of
4045+ * mechanisms, one for symmetric ciphers and one for digests. Also, 3 global
4046+ * variables carry information about which slot was chosen for (a) public key
4047+ * mechanisms, (b) random operations, and (c) symmetric ciphers and digests.
4048+ */
4049+static int
4050+pk11_choose_slots(int *any_slot_found)
4051+	{
4052+	CK_SLOT_ID_PTR pSlotList = NULL_PTR;
4053+	CK_ULONG ulSlotCount = 0;
4054+	CK_MECHANISM_INFO mech_info;
4055+	CK_TOKEN_INFO token_info;
4056+	unsigned int i;
4057+	CK_RV rv;
4058+	CK_SLOT_ID best_slot_sofar = 0;
4059+	CK_BBOOL found_candidate_slot = CK_FALSE;
4060+	int slot_n_cipher = 0;
4061+	int slot_n_digest = 0;
4062+	CK_SLOT_ID current_slot = 0;
4063+	int current_slot_n_cipher = 0;
4064+	int current_slot_n_digest = 0;
4065+
4066+	int local_cipher_nids[PK11_CIPHER_MAX];
4067+	int local_digest_nids[PK11_DIGEST_MAX];
4068+
4069+	/* let's initialize the output parameter */
4070+	if (any_slot_found != NULL)
4071+		*any_slot_found = 0;
4072+
4073+	/* Get slot list for memory allocation */
4074+	rv = pFuncList->C_GetSlotList(CK_FALSE, NULL_PTR, &ulSlotCount);
4075+
4076+	if (rv != CKR_OK)
4077+		{
4078+		PK11err_add_data(PK11_F_CHOOSE_SLOT, PK11_R_GETSLOTLIST, rv);
4079+		return (0);
4080+		}
4081+
4082+	/* it's not an error if we didn't find any providers */
4083+	if (ulSlotCount == 0)
4084+		{
4085+#ifdef	DEBUG_SLOT_SELECTION
4086+		fprintf(stderr, "%s: no crypto providers found\n", PK11_DBG);
4087+#endif	/* DEBUG_SLOT_SELECTION */
4088+		return (1);
4089+		}
4090+
4091+	pSlotList = OPENSSL_malloc(ulSlotCount * sizeof (CK_SLOT_ID));
4092+
4093+	if (pSlotList == NULL)
4094+		{
4095+		PK11err(PK11_F_CHOOSE_SLOT, PK11_R_MALLOC_FAILURE);
4096+		return (0);
4097+		}
4098+
4099+	/* Get the slot list for processing */
4100+	rv = pFuncList->C_GetSlotList(CK_FALSE, pSlotList, &ulSlotCount);
4101+	if (rv != CKR_OK)
4102+		{
4103+		PK11err_add_data(PK11_F_CHOOSE_SLOT, PK11_R_GETSLOTLIST, rv);
4104+		OPENSSL_free(pSlotList);
4105+		return (0);
4106+		}
4107+
4108+#ifdef	DEBUG_SLOT_SELECTION
4109+	fprintf(stderr, "%s: provider: %s\n", PK11_DBG, def_PK11_LIBNAME);
4110+	fprintf(stderr, "%s: number of slots: %d\n", PK11_DBG, ulSlotCount);
4111+
4112+	fprintf(stderr, "%s: == checking rand slots ==\n", PK11_DBG);
4113+#endif	/* DEBUG_SLOT_SELECTION */
4114+	for (i = 0; i < ulSlotCount; i++)
4115+		{
4116+		current_slot = pSlotList[i];
4117+
4118+#ifdef	DEBUG_SLOT_SELECTION
4119+	fprintf(stderr, "%s: checking slot: %d\n", PK11_DBG, i);
4120+#endif	/* DEBUG_SLOT_SELECTION */
4121+		/* Check if slot has random support. */
4122+		rv = pFuncList->C_GetTokenInfo(current_slot, &token_info);
4123+		if (rv != CKR_OK)
4124+			continue;
4125+
4126+#ifdef	DEBUG_SLOT_SELECTION
4127+	fprintf(stderr, "%s: token label: %.32s\n", PK11_DBG, token_info.label);
4128+#endif	/* DEBUG_SLOT_SELECTION */
4129+
4130+		if (token_info.flags & CKF_RNG)
4131+			{
4132+#ifdef	DEBUG_SLOT_SELECTION
4133+	fprintf(stderr, "%s: this token has CKF_RNG flag\n", PK11_DBG);
4134+#endif	/* DEBUG_SLOT_SELECTION */
4135+			pk11_have_random = CK_TRUE;
4136+			rand_SLOTID = current_slot;
4137+			break;
4138+			}
4139+		}
4140+
4141+#ifdef	DEBUG_SLOT_SELECTION
4142+	fprintf(stderr, "%s: == checking pubkey slots ==\n", PK11_DBG);
4143+#endif	/* DEBUG_SLOT_SELECTION */
4144+
4145+	pubkey_SLOTID = pSlotList[0];
4146+	for (i = 0; i < ulSlotCount; i++)
4147+		{
4148+		CK_BBOOL slot_has_rsa = CK_FALSE;
4149+		CK_BBOOL slot_has_recover = CK_FALSE;
4150+		CK_BBOOL slot_has_dsa = CK_FALSE;
4151+		CK_BBOOL slot_has_dh = CK_FALSE;
4152+		current_slot = pSlotList[i];
4153+
4154+#ifdef	DEBUG_SLOT_SELECTION
4155+	fprintf(stderr, "%s: checking slot: %d\n", PK11_DBG, i);
4156+#endif	/* DEBUG_SLOT_SELECTION */
4157+		rv = pFuncList->C_GetTokenInfo(current_slot, &token_info);
4158+		if (rv != CKR_OK)
4159+			continue;
4160+
4161+#ifdef	DEBUG_SLOT_SELECTION
4162+	fprintf(stderr, "%s: token label: %.32s\n", PK11_DBG, token_info.label);
4163+#endif	/* DEBUG_SLOT_SELECTION */
4164+
4165+#ifndef OPENSSL_NO_RSA
4166+		/*
4167+		 * Check if this slot is capable of signing and
4168+		 * verifying with CKM_RSA_PKCS.
4169+		 */
4170+		rv = pFuncList->C_GetMechanismInfo(current_slot, CKM_RSA_PKCS,
4171+			&mech_info);
4172+
4173+		if (rv == CKR_OK && ((mech_info.flags & CKF_SIGN) &&
4174+				(mech_info.flags & CKF_VERIFY)))
4175+			{
4176+			/*
4177+			 * Check if this slot is capable of encryption,
4178+			 * decryption, sign, and verify with CKM_RSA_X_509.
4179+			 */
4180+			rv = pFuncList->C_GetMechanismInfo(current_slot,
4181+			    CKM_RSA_X_509, &mech_info);
4182+
4183+			if (rv == CKR_OK && ((mech_info.flags & CKF_SIGN) &&
4184+			    (mech_info.flags & CKF_VERIFY) &&
4185+			    (mech_info.flags & CKF_ENCRYPT) &&
4186+			    (mech_info.flags & CKF_DECRYPT)))
4187+				{
4188+				slot_has_rsa = CK_TRUE;
4189+				if (mech_info.flags & CKF_VERIFY_RECOVER)
4190+					{
4191+					slot_has_recover = CK_TRUE;
4192+					}
4193+				}
4194+			}
4195+#endif	/* OPENSSL_NO_RSA */
4196+
4197+#ifndef OPENSSL_NO_DSA
4198+		/*
4199+		 * Check if this slot is capable of signing and
4200+		 * verifying with CKM_DSA.
4201+		 */
4202+		rv = pFuncList->C_GetMechanismInfo(current_slot, CKM_DSA,
4203+			&mech_info);
4204+		if (rv == CKR_OK && ((mech_info.flags & CKF_SIGN) &&
4205+		    (mech_info.flags & CKF_VERIFY)))
4206+			{
4207+			slot_has_dsa = CK_TRUE;
4208+			}
4209+
4210+#endif	/* OPENSSL_NO_DSA */
4211+
4212+#ifndef OPENSSL_NO_DH
4213+		/*
4214+		 * Check if this slot is capable of DH key generataion and
4215+		 * derivation.
4216+		 */
4217+		rv = pFuncList->C_GetMechanismInfo(current_slot,
4218+		    CKM_DH_PKCS_KEY_PAIR_GEN, &mech_info);
4219+
4220+		if (rv == CKR_OK && (mech_info.flags & CKF_GENERATE_KEY_PAIR))
4221+			{
4222+			rv = pFuncList->C_GetMechanismInfo(current_slot,
4223+				CKM_DH_PKCS_DERIVE, &mech_info);
4224+			if (rv == CKR_OK && (mech_info.flags & CKF_DERIVE))
4225+				{
4226+				slot_has_dh = CK_TRUE;
4227+				}
4228+			}
4229+#endif	/* OPENSSL_NO_DH */
4230+
4231+		if (!found_candidate_slot &&
4232+		    (slot_has_rsa || slot_has_dsa || slot_has_dh))
4233+			{
4234+#ifdef	DEBUG_SLOT_SELECTION
4235+			fprintf(stderr,
4236+			    "%s: potential slot: %d\n", PK11_DBG, current_slot);
4237+#endif	/* DEBUG_SLOT_SELECTION */
4238+			best_slot_sofar = current_slot;
4239+			pk11_have_rsa = slot_has_rsa;
4240+			pk11_have_recover = slot_has_recover;
4241+			pk11_have_dsa = slot_has_dsa;
4242+			pk11_have_dh = slot_has_dh;
4243+			found_candidate_slot = CK_TRUE;
4244+			/*
4245+			 * Cache the flags for later use. We might
4246+			 * need those if RSA keys by reference feature
4247+			 * is used.
4248+			 */
4249+			pubkey_token_flags = token_info.flags;
4250+#ifdef	DEBUG_SLOT_SELECTION
4251+			fprintf(stderr,
4252+			    "%s: setting found_candidate_slot to CK_TRUE\n",
4253+			    PK11_DBG);
4254+			fprintf(stderr,
4255+			    "%s: best so far slot: %d\n", PK11_DBG,
4256+			    best_slot_sofar);
4257+			fprintf(stderr, "%s: pubkey flags changed to "
4258+			    "%lu.\n", PK11_DBG, pubkey_token_flags);
4259+			}
4260+		else
4261+			{
4262+			fprintf(stderr,
4263+			    "%s: no rsa/dsa/dh\n", PK11_DBG);
4264+			}
4265+#else
4266+			} /* if */
4267+#endif	/* DEBUG_SLOT_SELECTION */
4268+		} /* for */
4269+
4270+	if (found_candidate_slot == CK_TRUE)
4271+		{
4272+		pubkey_SLOTID = best_slot_sofar;
4273+		}
4274+
4275+	found_candidate_slot = CK_FALSE;
4276+	best_slot_sofar = 0;
4277+
4278+#ifdef	DEBUG_SLOT_SELECTION
4279+	fprintf(stderr, "%s: == checking cipher/digest ==\n", PK11_DBG);
4280+#endif	/* DEBUG_SLOT_SELECTION */
4281+
4282+	SLOTID = pSlotList[0];
4283+	for (i = 0; i < ulSlotCount; i++)
4284+		{
4285+#ifdef	DEBUG_SLOT_SELECTION
4286+	fprintf(stderr, "%s: checking slot: %d\n", PK11_DBG, i);
4287+#endif	/* DEBUG_SLOT_SELECTION */
4288+
4289+		current_slot = pSlotList[i];
4290+		current_slot_n_cipher = 0;
4291+		current_slot_n_digest = 0;
4292+		(void) memset(local_cipher_nids, 0, sizeof (local_cipher_nids));
4293+		(void) memset(local_digest_nids, 0, sizeof (local_digest_nids));
4294+
4295+		pk11_find_symmetric_ciphers(pFuncList, current_slot,
4296+		    &current_slot_n_cipher, local_cipher_nids);
4297+
4298+		pk11_find_digests(pFuncList, current_slot,
4299+		    &current_slot_n_digest, local_digest_nids);
4300+
4301+#ifdef	DEBUG_SLOT_SELECTION
4302+		fprintf(stderr, "%s: current_slot_n_cipher %d\n", PK11_DBG,
4303+			current_slot_n_cipher);
4304+		fprintf(stderr, "%s: current_slot_n_digest %d\n", PK11_DBG,
4305+			current_slot_n_digest);
4306+		fprintf(stderr, "%s: best so far cipher/digest slot: %d\n",
4307+			PK11_DBG, best_slot_sofar);
4308+#endif	/* DEBUG_SLOT_SELECTION */
4309+
4310+		/*
4311+		 * If the current slot supports more ciphers/digests than
4312+		 * the previous best one we change the current best to this one,
4313+		 * otherwise leave it where it is.
4314+		 */
4315+		if ((current_slot_n_cipher + current_slot_n_digest) >
4316+		    (slot_n_cipher + slot_n_digest))
4317+			{
4318+#ifdef	DEBUG_SLOT_SELECTION
4319+			fprintf(stderr,
4320+				"%s: changing best so far slot to %d\n",
4321+				PK11_DBG, current_slot);
4322+#endif	/* DEBUG_SLOT_SELECTION */
4323+			best_slot_sofar = SLOTID = current_slot;
4324+			cipher_count = slot_n_cipher = current_slot_n_cipher;
4325+			digest_count = slot_n_digest = current_slot_n_digest;
4326+			(void) memcpy(cipher_nids, local_cipher_nids,
4327+			    sizeof (local_cipher_nids));
4328+			(void) memcpy(digest_nids, local_digest_nids, 
4329+			    sizeof (local_digest_nids));
4330+			}
4331+		}
4332+
4333+#ifdef	DEBUG_SLOT_SELECTION
4334+	fprintf(stderr,
4335+	    "%s: chosen pubkey slot: %d\n", PK11_DBG, pubkey_SLOTID);
4336+	fprintf(stderr,
4337+	    "%s: chosen rand slot: %d\n", PK11_DBG, rand_SLOTID);
4338+	fprintf(stderr,
4339+	    "%s: chosen cipher/digest slot: %d\n", PK11_DBG, SLOTID);
4340+	fprintf(stderr,
4341+	    "%s: pk11_have_rsa %d\n", PK11_DBG, pk11_have_rsa);
4342+	fprintf(stderr,
4343+	    "%s: pk11_have_recover %d\n", PK11_DBG, pk11_have_recover);
4344+	fprintf(stderr,
4345+	    "%s: pk11_have_dsa %d\n", PK11_DBG, pk11_have_dsa);
4346+	fprintf(stderr,
4347+	    "%s: pk11_have_dh %d\n", PK11_DBG, pk11_have_dh);
4348+	fprintf(stderr,
4349+	    "%s: pk11_have_random %d\n", PK11_DBG, pk11_have_random);
4350+	fprintf(stderr,
4351+	    "%s: cipher_count %d\n", PK11_DBG, cipher_count);
4352+	fprintf(stderr,
4353+	    "%s: digest_count %d\n", PK11_DBG, digest_count);
4354+#endif	/* DEBUG_SLOT_SELECTION */
4355+
4356+	if (pSlotList != NULL)
4357+		OPENSSL_free(pSlotList);
4358+
4359+#ifdef	SOLARIS_HW_SLOT_SELECTION
4360+	OPENSSL_free(hw_cnids);
4361+	OPENSSL_free(hw_dnids);
4362+#endif	/* SOLARIS_HW_SLOT_SELECTION */
4363+
4364+	if (any_slot_found != NULL)
4365+		*any_slot_found = 1;
4366+	return (1);
4367+	}
4368+
4369+static void pk11_get_symmetric_cipher(CK_FUNCTION_LIST_PTR pflist,
4370+    int slot_id, CK_MECHANISM_TYPE mech, int *current_slot_n_cipher,
4371+    int *local_cipher_nids, int id)
4372+	{
4373+	CK_MECHANISM_INFO mech_info;
4374+	CK_RV rv;
4375+
4376+#ifdef	DEBUG_SLOT_SELECTION
4377+	fprintf(stderr, "%s: checking mech: %x", PK11_DBG, mech);
4378+#endif	/* DEBUG_SLOT_SELECTION */
4379+	rv = pflist->C_GetMechanismInfo(slot_id, mech, &mech_info);
4380+
4381+	if (rv != CKR_OK)
4382+		{
4383+#ifdef	DEBUG_SLOT_SELECTION
4384+		fprintf(stderr, " not found\n");
4385+#endif	/* DEBUG_SLOT_SELECTION */
4386+		return;
4387+		}
4388+
4389+	if ((mech_info.flags & CKF_ENCRYPT) &&
4390+	    (mech_info.flags & CKF_DECRYPT))
4391+		{
4392+#ifdef	SOLARIS_HW_SLOT_SELECTION
4393+		if (nid_in_table(ciphers[id].nid, hw_cnids))
4394+#endif	/* SOLARIS_HW_SLOT_SELECTION */
4395+			{
4396+#ifdef	DEBUG_SLOT_SELECTION
4397+		fprintf(stderr, " usable\n");
4398+#endif	/* DEBUG_SLOT_SELECTION */
4399+			local_cipher_nids[(*current_slot_n_cipher)++] =
4400+			    ciphers[id].nid;
4401+			}
4402+#ifdef	SOLARIS_HW_SLOT_SELECTION
4403+#ifdef	DEBUG_SLOT_SELECTION
4404+		else
4405+			{
4406+		fprintf(stderr, " rejected, software implementation only\n");
4407+			}
4408+#endif	/* DEBUG_SLOT_SELECTION */
4409+#endif	/* SOLARIS_HW_SLOT_SELECTION */
4410+		}
4411+#ifdef	DEBUG_SLOT_SELECTION
4412+	else
4413+		{
4414+		fprintf(stderr, " unusable\n");
4415+		}
4416+#endif	/* DEBUG_SLOT_SELECTION */
4417+
4418+	return;
4419+	}
4420+
4421+static void pk11_get_digest(CK_FUNCTION_LIST_PTR pflist, int slot_id,
4422+    CK_MECHANISM_TYPE mech, int *current_slot_n_digest, int *local_digest_nids,
4423+    int id)
4424+	{
4425+	CK_MECHANISM_INFO mech_info;
4426+	CK_RV rv;
4427+
4428+#ifdef	DEBUG_SLOT_SELECTION
4429+	fprintf(stderr, "%s: checking mech: %x", PK11_DBG, mech);
4430+#endif	/* DEBUG_SLOT_SELECTION */
4431+	rv = pflist->C_GetMechanismInfo(slot_id, mech, &mech_info);
4432+
4433+	if (rv != CKR_OK)
4434+		{
4435+#ifdef	DEBUG_SLOT_SELECTION
4436+		fprintf(stderr, " not found\n");
4437+#endif	/* DEBUG_SLOT_SELECTION */
4438+		return;
4439+		}
4440+
4441+	if (mech_info.flags & CKF_DIGEST)
4442+		{
4443+#ifdef	SOLARIS_HW_SLOT_SELECTION
4444+		if (nid_in_table(digests[id].nid, hw_dnids))
4445+#endif	/* SOLARIS_HW_SLOT_SELECTION */
4446+			{
4447+#ifdef	DEBUG_SLOT_SELECTION
4448+		fprintf(stderr, " usable\n");
4449+#endif	/* DEBUG_SLOT_SELECTION */
4450+			local_digest_nids[(*current_slot_n_digest)++] =
4451+			    digests[id].nid;
4452+			}
4453+#ifdef	SOLARIS_HW_SLOT_SELECTION
4454+#ifdef	DEBUG_SLOT_SELECTION
4455+		else
4456+			{
4457+		fprintf(stderr, " rejected, software implementation only\n");
4458+			}
4459+#endif	/* DEBUG_SLOT_SELECTION */
4460+#endif	/* SOLARIS_HW_SLOT_SELECTION */
4461+		}
4462+#ifdef	DEBUG_SLOT_SELECTION
4463+	else
4464+		{
4465+		fprintf(stderr, " unusable\n");
4466+		}
4467+#endif	/* DEBUG_SLOT_SELECTION */
4468+
4469+	return;
4470+	}
4471+
4472+#ifdef	SOLARIS_AES_CTR
4473+/* create a new NID when we have no OID for that mechanism */
4474+static int pk11_add_NID(char *sn, char *ln)
4475+	{
4476+	ASN1_OBJECT *o;
4477+	int nid;
4478+
4479+	if ((o = ASN1_OBJECT_create(OBJ_new_nid(1), (unsigned char *)"",
4480+	    1, sn, ln)) == NULL)
4481+		{
4482+		return (0);
4483+		}
4484+
4485+	/* will return NID_undef on error */
4486+	nid = OBJ_add_object(o);
4487+	ASN1_OBJECT_free(o);
4488+
4489+	return (nid);
4490+	}
4491+
4492+/*
4493+ * Create new NIDs for AES counter mode. OpenSSL doesn't support them now so we
4494+ * have to help ourselves here.
4495+ */
4496+static int pk11_add_aes_ctr_NIDs(void)
4497+	{
4498+	/* are we already set? */
4499+	if (NID_aes_256_ctr != NID_undef)
4500+		return (1);
4501+
4502+	/*
4503+	 * There are no official names for AES counter modes yet so we just
4504+	 * follow the format of those that exist.
4505+	 */
4506+	if ((NID_aes_128_ctr = pk11_add_NID("AES-128-CTR", "aes-128-ctr")) ==
4507+	    NID_undef)
4508+		goto err;
4509+	ciphers[PK11_AES_128_CTR].nid = pk11_aes_128_ctr.nid = NID_aes_128_ctr;
4510+	if ((NID_aes_192_ctr = pk11_add_NID("AES-192-CTR", "aes-192-ctr")) ==
4511+	    NID_undef)
4512+		goto err;
4513+	ciphers[PK11_AES_192_CTR].nid = pk11_aes_192_ctr.nid = NID_aes_192_ctr;
4514+	if ((NID_aes_256_ctr = pk11_add_NID("AES-256-CTR", "aes-256-ctr")) ==
4515+	    NID_undef)
4516+		goto err;
4517+	ciphers[PK11_AES_256_CTR].nid = pk11_aes_256_ctr.nid = NID_aes_256_ctr;
4518+	return (1);
4519+
4520+err:
4521+	PK11err(PK11_F_ADD_AES_CTR_NIDS, PK11_R_ADD_NID_FAILED);
4522+	return (0);
4523+	}
4524+#endif	/* SOLARIS_AES_CTR */
4525+
4526+/* Find what symmetric ciphers this slot supports. */
4527+static void pk11_find_symmetric_ciphers(CK_FUNCTION_LIST_PTR pflist,
4528+    CK_SLOT_ID current_slot, int *current_slot_n_cipher, int *local_cipher_nids)
4529+	{
4530+	int i;
4531+
4532+	for (i = 0; i < PK11_CIPHER_MAX; ++i)
4533+		{
4534+		pk11_get_symmetric_cipher(pflist, current_slot,
4535+		    ciphers[i].mech_type, current_slot_n_cipher,
4536+		    local_cipher_nids, ciphers[i].id);
4537+		}
4538+	}
4539+
4540+/* Find what digest algorithms this slot supports. */
4541+static void pk11_find_digests(CK_FUNCTION_LIST_PTR pflist,
4542+    CK_SLOT_ID current_slot, int *current_slot_n_digest, int *local_digest_nids)
4543+	{
4544+	int i;
4545+
4546+	for (i = 0; i < PK11_DIGEST_MAX; ++i)
4547+		{
4548+		pk11_get_digest(pflist, current_slot, digests[i].mech_type,
4549+		    current_slot_n_digest, local_digest_nids, digests[i].id);
4550+		}
4551+	}
4552+
4553+#ifdef	SOLARIS_HW_SLOT_SELECTION
4554+/*
4555+ * It would be great if we could use pkcs11_kernel directly since this library
4556+ * offers hardware slots only. That's the easiest way to achieve the situation
4557+ * where we use the hardware accelerators when present and OpenSSL native code
4558+ * otherwise. That presumes the fact that OpenSSL native code is faster than the
4559+ * code in the soft token. It's a logical assumption - Crypto Framework has some
4560+ * inherent overhead so going there for the software implementation of a
4561+ * mechanism should be logically slower in contrast to the OpenSSL native code,
4562+ * presuming that both implementations are of similar speed. For example, the
4563+ * soft token for AES is roughly three times slower than OpenSSL for 64 byte
4564+ * blocks and still 20% slower for 8KB blocks. So, if we want to ship products
4565+ * that use the PKCS#11 engine by default, we must somehow avoid that regression
4566+ * on machines without hardware acceleration. That's why switching to the
4567+ * pkcs11_kernel library seems like a very good idea.
4568+ *
4569+ * The problem is that OpenSSL built with SunStudio is roughly 2x slower for
4570+ * asymmetric operations (RSA/DSA/DH) than the soft token built with the same
4571+ * compiler. That means that if we switched to pkcs11_kernel from the libpkcs11
4572+ * library, we would have had a performance regression on machines without
4573+ * hardware acceleration for asymmetric operations for all applications that use
4574+ * the PKCS#11 engine. There is one such application - Apache web server since
4575+ * it's shipped configured to use the PKCS#11 engine by default. Having said
4576+ * that, we can't switch to the pkcs11_kernel library now and have to come with
4577+ * a solution that, on non-accelerated machines, uses the OpenSSL native code
4578+ * for all symmetric ciphers and digests while it uses the soft token for
4579+ * asymmetric operations.
4580+ *
4581+ * This is the idea: dlopen() pkcs11_kernel directly and find out what
4582+ * mechanisms are there. We don't care about duplications (more slots can
4583+ * support the same mechanism), we just want to know what mechanisms can be
4584+ * possibly supported in hardware on that particular machine. As said before,
4585+ * pkcs11_kernel will show you hardware providers only.
4586+ *
4587+ * Then, we rely on the fact that since we use libpkcs11 library we will find
4588+ * the metaslot. When we go through the metaslot's mechanisms for symmetric
4589+ * ciphers and digests, we check that any found mechanism is in the table
4590+ * created using the pkcs11_kernel library. So, as a result we have two arrays
4591+ * of mechanisms that were advertised as supported in hardware which was the
4592+ * goal of that whole excercise. Thus, we can use libpkcs11 but avoid soft token
4593+ * code for symmetric ciphers and digests. See pk11_choose_slots() for more
4594+ * information.
4595+ *
4596+ * This is Solaris specific code, if SOLARIS_HW_SLOT_SELECTION is not defined
4597+ * the code won't be used.
4598+ */
4599+#if defined(__sparcv9) || defined(__x86_64) || defined(__amd64)
4600+static const char pkcs11_kernel[] = "/usr/lib/security/64/pkcs11_kernel.so.1";
4601+#else
4602+static const char pkcs11_kernel[] = "/usr/lib/security/pkcs11_kernel.so.1";
4603+#endif
4604+
4605+/*
4606+ * Check hardware capabilities of the machines. The output are two lists,
4607+ * hw_cnids and hw_dnids, that contain hardware mechanisms found in all hardware
4608+ * providers together. They are not sorted and may contain duplicate mechanisms.
4609+ */
4610+static int check_hw_mechanisms(void)
4611+	{
4612+	int i;
4613+	CK_RV rv;
4614+	void *handle;
4615+	CK_C_GetFunctionList p;
4616+	CK_TOKEN_INFO token_info;
4617+	CK_ULONG ulSlotCount = 0;
4618+	int n_cipher = 0, n_digest = 0;
4619+	CK_FUNCTION_LIST_PTR pflist = NULL;
4620+	CK_SLOT_ID_PTR pSlotList = NULL_PTR;
4621+	int *tmp_hw_cnids = NULL, *tmp_hw_dnids = NULL;
4622+	int hw_ctable_size, hw_dtable_size;
4623+
4624+#ifdef	DEBUG_SLOT_SELECTION
4625+	fprintf(stderr, "%s: SOLARIS_HW_SLOT_SELECTION code running\n",
4626+	    PK11_DBG);
4627+#endif
4628+	if ((handle = dlopen(pkcs11_kernel, RTLD_LAZY)) == NULL)
4629+		{
4630+		PK11err(PK11_F_CHECK_HW_MECHANISMS, PK11_R_DSO_FAILURE);
4631+		goto err;
4632+		}
4633+
4634+	if ((p = (CK_C_GetFunctionList)dlsym(handle,
4635+	    PK11_GET_FUNCTION_LIST)) == NULL)
4636+		{
4637+		PK11err(PK11_F_CHECK_HW_MECHANISMS, PK11_R_DSO_FAILURE);
4638+		goto err;
4639+		}
4640+
4641+	/* get the full function list from the loaded library */
4642+	if (p(&pflist) != CKR_OK)
4643+		{
4644+		PK11err(PK11_F_CHECK_HW_MECHANISMS, PK11_R_DSO_FAILURE);
4645+		goto err;
4646+		}
4647+
4648+	rv = pflist->C_Initialize((CK_VOID_PTR)&pk11_init_args);
4649+	if ((rv != CKR_OK) && (rv != CKR_CRYPTOKI_ALREADY_INITIALIZED))
4650+		{
4651+		PK11err_add_data(PK11_F_CHECK_HW_MECHANISMS,
4652+		    PK11_R_INITIALIZE, rv);
4653+		goto err;
4654+		}
4655+
4656+	if (pflist->C_GetSlotList(0, NULL_PTR, &ulSlotCount) != CKR_OK)
4657+		{
4658+		PK11err(PK11_F_CHECK_HW_MECHANISMS, PK11_R_GETSLOTLIST);
4659+		goto err;
4660+		}
4661+
4662+	/* no slots, set the hw mechanism tables as empty */
4663+	if (ulSlotCount == 0)
4664+		{
4665+#ifdef	DEBUG_SLOT_SELECTION
4666+	fprintf(stderr, "%s: no hardware mechanisms found\n", PK11_DBG);
4667+#endif
4668+		hw_cnids = OPENSSL_malloc(sizeof (int));
4669+		hw_dnids = OPENSSL_malloc(sizeof (int));
4670+		if (hw_cnids == NULL || hw_dnids == NULL)
4671+			{
4672+			PK11err(PK11_F_CHECK_HW_MECHANISMS,
4673+			    PK11_R_MALLOC_FAILURE);
4674+			return (0);
4675+			}
4676+		/* this means empty tables */
4677+		hw_cnids[0] = NID_undef;
4678+		hw_dnids[0] = NID_undef;
4679+		return (1);
4680+		}
4681+
4682+	pSlotList = OPENSSL_malloc(ulSlotCount * sizeof (CK_SLOT_ID));
4683+	if (pSlotList == NULL)
4684+		{
4685+		PK11err(PK11_F_CHECK_HW_MECHANISMS, PK11_R_MALLOC_FAILURE);
4686+		goto err;
4687+		}
4688+
4689+	/* Get the slot list for processing */
4690+	if (pflist->C_GetSlotList(0, pSlotList, &ulSlotCount) != CKR_OK)
4691+		{
4692+		PK11err(PK11_F_CHECK_HW_MECHANISMS, PK11_R_GETSLOTLIST);
4693+		goto err;
4694+		}
4695+
4696+	/*
4697+	 * We don't care about duplicit mechanisms in multiple slots and also
4698+	 * reserve one slot for the terminal NID_undef which we use to stop the
4699+	 * search.
4700+	 */
4701+	hw_ctable_size = ulSlotCount * PK11_CIPHER_MAX + 1;
4702+	hw_dtable_size = ulSlotCount * PK11_DIGEST_MAX + 1;
4703+	tmp_hw_cnids = OPENSSL_malloc(hw_ctable_size * sizeof (int));
4704+	tmp_hw_dnids = OPENSSL_malloc(hw_dtable_size * sizeof (int));
4705+	if (tmp_hw_cnids == NULL || tmp_hw_dnids == NULL)
4706+		{
4707+		PK11err(PK11_F_CHECK_HW_MECHANISMS, PK11_R_MALLOC_FAILURE);
4708+		goto err;
4709+		}
4710+
4711+	/*
4712+	 * Do not use memset since we should not rely on the fact that NID_undef
4713+	 * is zero now.
4714+	 */
4715+	for (i = 0; i < hw_ctable_size; ++i)
4716+		tmp_hw_cnids[i] = NID_undef;
4717+	for (i = 0; i < hw_dtable_size; ++i)
4718+		tmp_hw_dnids[i] = NID_undef;
4719+
4720+#ifdef	DEBUG_SLOT_SELECTION
4721+	fprintf(stderr, "%s: provider: %s\n", PK11_DBG, pkcs11_kernel);
4722+	fprintf(stderr, "%s: found %d hardware slots\n", PK11_DBG, ulSlotCount);
4723+	fprintf(stderr, "%s: now looking for mechs supported in hw\n",
4724+	    PK11_DBG);
4725+#endif	/* DEBUG_SLOT_SELECTION */
4726+
4727+	for (i = 0; i < ulSlotCount; i++)
4728+		{
4729+		if (pflist->C_GetTokenInfo(pSlotList[i], &token_info) != CKR_OK)
4730+			continue;
4731+
4732+#ifdef	DEBUG_SLOT_SELECTION
4733+	fprintf(stderr, "%s: token label: %.32s\n", PK11_DBG, token_info.label);
4734+#endif	/* DEBUG_SLOT_SELECTION */
4735+
4736+		/*
4737+		 * We are filling the hw mech tables here. Global tables are
4738+		 * still NULL so all mechanisms are put into tmp tables.
4739+		 */
4740+		pk11_find_symmetric_ciphers(pflist, pSlotList[i],
4741+		    &n_cipher, tmp_hw_cnids);
4742+		pk11_find_digests(pflist, pSlotList[i],
4743+		    &n_digest, tmp_hw_dnids);
4744+		}
4745+
4746+	/*
4747+	 * Since we are part of a library (libcrypto.so), calling this function
4748+	 * may have side-effects. Also, C_Finalize() is triggered by
4749+	 * dlclose(3C).
4750+	 */
4751+#if 0
4752+	pflist->C_Finalize(NULL);
4753+#endif
4754+	OPENSSL_free(pSlotList);
4755+	(void) dlclose(handle);
4756+	hw_cnids = tmp_hw_cnids;
4757+	hw_dnids = tmp_hw_dnids;
4758+
4759+#ifdef	DEBUG_SLOT_SELECTION
4760+	fprintf(stderr, "%s: hw mechs check complete\n", PK11_DBG);
4761+#endif	/* DEBUG_SLOT_SELECTION */
4762+	return (1);
4763+
4764+err:
4765+	if (pSlotList != NULL)
4766+		OPENSSL_free(pSlotList);
4767+	if (tmp_hw_cnids != NULL)
4768+		OPENSSL_free(tmp_hw_cnids);
4769+	if (tmp_hw_dnids != NULL)
4770+		OPENSSL_free(tmp_hw_dnids);
4771+
4772+	return (0);
4773+	}
4774+
4775+/*
4776+ * Check presence of a NID in the table of NIDs. The table may be NULL (i.e.,
4777+ * non-existent).
4778+ */
4779+static int nid_in_table(int nid, int *nid_table)
4780+	{
4781+	int i = 0;
4782+
4783+	/*
4784+	 * a special case. NULL means that we are initializing a new
4785+	 * table.
4786+	 */
4787+	if (nid_table == NULL)
4788+		return (1);
4789+
4790+	/*
4791+	 * the table is never full, there is always at least one
4792+	 * NID_undef.
4793+	 */
4794+	while (nid_table[i] != NID_undef)
4795+		{
4796+		if (nid_table[i++] == nid)
4797+			{
4798+#ifdef	DEBUG_SLOT_SELECTION
4799+	fprintf(stderr, " (NID %d in hw table, idx %d)", nid, i);
4800+#endif	/* DEBUG_SLOT_SELECTION */
4801+			return (1);
4802+			}
4803+		}
4804+
4805+	return (0);
4806+	}
4807+#endif	/* SOLARIS_HW_SLOT_SELECTION */
4808+
4809+#endif	/* OPENSSL_NO_HW_PK11CA */
4810+#endif	/* OPENSSL_NO_HW_PK11 */
4811+#endif	/* OPENSSL_NO_HW */
4812Index: openssl/crypto/engine/hw_pk11_err.c
4813diff -u /dev/null openssl/crypto/engine/hw_pk11_err.c:1.5
4814--- /dev/null	Mon Jan 16 18:54:23 2012
4815+++ openssl/crypto/engine/hw_pk11_err.c	Tue Jun 14 00:43:26 2011
4816@@ -0,0 +1,288 @@
4817+/*
4818+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
4819+ * Use is subject to license terms.
4820+ */
4821+
4822+/* crypto/engine/hw_pk11_err.c */
4823+/*
4824+ * This product includes software developed by the OpenSSL Project for
4825+ * use in the OpenSSL Toolkit (http://www.openssl.org/).
4826+ *
4827+ * This project also referenced hw_pkcs11-0.9.7b.patch written by
4828+ * Afchine Madjlessi.
4829+ */
4830+/*
4831+ * ====================================================================
4832+ * Copyright (c) 2000-2001 The OpenSSL Project.  All rights reserved.
4833+ *
4834+ * Redistribution and use in source and binary forms, with or without
4835+ * modification, are permitted provided that the following conditions
4836+ * are met:
4837+ *
4838+ * 1. Redistributions of source code must retain the above copyright
4839+ *    notice, this list of conditions and the following disclaimer.
4840+ *
4841+ * 2. Redistributions in binary form must reproduce the above copyright
4842+ *    notice, this list of conditions and the following disclaimer in
4843+ *    the documentation and/or other materials provided with the
4844+ *    distribution.
4845+ *
4846+ * 3. All advertising materials mentioning features or use of this
4847+ *    software must display the following acknowledgment:
4848+ *    "This product includes software developed by the OpenSSL Project
4849+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
4850+ *
4851+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
4852+ *    endorse or promote products derived from this software without
4853+ *    prior written permission. For written permission, please contact
4854+ *    licensing@OpenSSL.org.
4855+ *
4856+ * 5. Products derived from this software may not be called "OpenSSL"
4857+ *    nor may "OpenSSL" appear in their names without prior written
4858+ *    permission of the OpenSSL Project.
4859+ *
4860+ * 6. Redistributions of any form whatsoever must retain the following
4861+ *    acknowledgment:
4862+ *    "This product includes software developed by the OpenSSL Project
4863+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
4864+ *
4865+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
4866+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
4867+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
4868+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
4869+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
4870+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
4871+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
4872+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
4873+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
4874+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
4875+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
4876+ * OF THE POSSIBILITY OF SUCH DAMAGE.
4877+ * ====================================================================
4878+ *
4879+ * This product includes cryptographic software written by Eric Young
4880+ * (eay@cryptsoft.com).  This product includes software written by Tim
4881+ * Hudson (tjh@cryptsoft.com).
4882+ *
4883+ */
4884+
4885+#include <stdio.h>
4886+#include <openssl/err.h>
4887+#include "hw_pk11_err.h"
4888+
4889+/* BEGIN ERROR CODES */
4890+#ifndef OPENSSL_NO_ERR
4891+static ERR_STRING_DATA pk11_str_functs[]=
4892+{
4893+{ ERR_PACK(0, PK11_F_INIT, 0),			"PK11_INIT"},
4894+{ ERR_PACK(0, PK11_F_FINISH, 0),		"PK11_FINISH"},
4895+{ ERR_PACK(0, PK11_F_DESTROY, 0),		"PK11_DESTROY"},
4896+{ ERR_PACK(0, PK11_F_CTRL, 0),			"PK11_CTRL"},
4897+{ ERR_PACK(0, PK11_F_RSA_INIT, 0),		"PK11_RSA_INIT"},
4898+{ ERR_PACK(0, PK11_F_RSA_FINISH, 0),		"PK11_RSA_FINISH"},
4899+{ ERR_PACK(0, PK11_F_GET_PUB_RSA_KEY, 0),	"PK11_GET_PUB_RSA_KEY"},
4900+{ ERR_PACK(0, PK11_F_GET_PRIV_RSA_KEY, 0),	"PK11_GET_PRIV_RSA_KEY"},
4901+{ ERR_PACK(0, PK11_F_RSA_GEN_KEY, 0),		"PK11_RSA_GEN_KEY"},
4902+{ ERR_PACK(0, PK11_F_RSA_PUB_ENC, 0),		"PK11_RSA_PUB_ENC"},
4903+{ ERR_PACK(0, PK11_F_RSA_PRIV_ENC, 0),		"PK11_RSA_PRIV_ENC"},
4904+{ ERR_PACK(0, PK11_F_RSA_PUB_DEC, 0),		"PK11_RSA_PUB_DEC"},
4905+{ ERR_PACK(0, PK11_F_RSA_PRIV_DEC, 0),		"PK11_RSA_PRIV_DEC"},
4906+{ ERR_PACK(0, PK11_F_RSA_SIGN, 0),		"PK11_RSA_SIGN"},
4907+{ ERR_PACK(0, PK11_F_RSA_VERIFY, 0),		"PK11_RSA_VERIFY"},
4908+{ ERR_PACK(0, PK11_F_RAND_ADD, 0),		"PK11_RAND_ADD"},
4909+{ ERR_PACK(0, PK11_F_RAND_BYTES, 0),		"PK11_RAND_BYTES"},
4910+{ ERR_PACK(0, PK11_F_GET_SESSION, 0),		"PK11_GET_SESSION"},
4911+{ ERR_PACK(0, PK11_F_FREE_SESSION, 0),		"PK11_FREE_SESSION"},
4912+{ ERR_PACK(0, PK11_F_LOAD_PUBKEY, 0),		"PK11_LOAD_PUBKEY"},
4913+{ ERR_PACK(0, PK11_F_LOAD_PRIVKEY, 0),		"PK11_LOAD_PRIV_KEY"},
4914+{ ERR_PACK(0, PK11_F_RSA_PUB_ENC_LOW, 0),	"PK11_RSA_PUB_ENC_LOW"},
4915+{ ERR_PACK(0, PK11_F_RSA_PRIV_ENC_LOW, 0),	"PK11_RSA_PRIV_ENC_LOW"},
4916+{ ERR_PACK(0, PK11_F_RSA_PUB_DEC_LOW, 0),	"PK11_RSA_PUB_DEC_LOW"},
4917+{ ERR_PACK(0, PK11_F_RSA_PRIV_DEC_LOW, 0),	"PK11_RSA_PRIV_DEC_LOW"},
4918+{ ERR_PACK(0, PK11_F_DSA_SIGN, 0),		"PK11_DSA_SIGN"},
4919+{ ERR_PACK(0, PK11_F_DSA_VERIFY, 0),		"PK11_DSA_VERIFY"},
4920+{ ERR_PACK(0, PK11_F_DSA_INIT, 0),		"PK11_DSA_INIT"},
4921+{ ERR_PACK(0, PK11_F_DSA_FINISH, 0),		"PK11_DSA_FINISH"},
4922+{ ERR_PACK(0, PK11_F_GET_PUB_DSA_KEY, 0),	"PK11_GET_PUB_DSA_KEY"},
4923+{ ERR_PACK(0, PK11_F_GET_PRIV_DSA_KEY, 0),	"PK11_GET_PRIV_DSA_KEY"},
4924+{ ERR_PACK(0, PK11_F_DH_INIT, 0),		"PK11_DH_INIT"},
4925+{ ERR_PACK(0, PK11_F_DH_FINISH, 0),		"PK11_DH_FINISH"},
4926+{ ERR_PACK(0, PK11_F_MOD_EXP_DH, 0),		"PK11_MOD_EXP_DH"},
4927+{ ERR_PACK(0, PK11_F_GET_DH_KEY, 0),		"PK11_GET_DH_KEY"},
4928+{ ERR_PACK(0, PK11_F_FREE_ALL_SESSIONS, 0),	"PK11_FREE_ALL_SESSIONS"},
4929+{ ERR_PACK(0, PK11_F_SETUP_SESSION, 0),		"PK11_SETUP_SESSION"},
4930+{ ERR_PACK(0, PK11_F_DESTROY_OBJECT, 0),	"PK11_DESTROY_OBJECT"},
4931+{ ERR_PACK(0, PK11_F_CIPHER_INIT, 0),		"PK11_CIPHER_INIT"},
4932+{ ERR_PACK(0, PK11_F_CIPHER_DO_CIPHER, 0),	"PK11_CIPHER_DO_CIPHER"},
4933+{ ERR_PACK(0, PK11_F_GET_CIPHER_KEY, 0),	"PK11_GET_CIPHER_KEY"},
4934+{ ERR_PACK(0, PK11_F_DIGEST_INIT, 0),		"PK11_DIGEST_INIT"},
4935+{ ERR_PACK(0, PK11_F_DIGEST_UPDATE, 0),		"PK11_DIGEST_UPDATE"},
4936+{ ERR_PACK(0, PK11_F_DIGEST_FINAL, 0),		"PK11_DIGEST_FINAL"},
4937+{ ERR_PACK(0, PK11_F_CHOOSE_SLOT, 0),		"PK11_CHOOSE_SLOT"},
4938+{ ERR_PACK(0, PK11_F_CIPHER_FINAL, 0),		"PK11_CIPHER_FINAL"},
4939+{ ERR_PACK(0, PK11_F_LIBRARY_INIT, 0),		"PK11_LIBRARY_INIT"},
4940+{ ERR_PACK(0, PK11_F_LOAD, 0),			"ENGINE_LOAD_PK11"},
4941+{ ERR_PACK(0, PK11_F_DH_GEN_KEY, 0),		"PK11_DH_GEN_KEY"},
4942+{ ERR_PACK(0, PK11_F_DH_COMP_KEY, 0),		"PK11_DH_COMP_KEY"},
4943+{ ERR_PACK(0, PK11_F_DIGEST_COPY, 0),		"PK11_DIGEST_COPY"},
4944+{ ERR_PACK(0, PK11_F_CIPHER_CLEANUP, 0),	"PK11_CIPHER_CLEANUP"},
4945+{ ERR_PACK(0, PK11_F_ACTIVE_ADD, 0),		"PK11_ACTIVE_ADD"},
4946+{ ERR_PACK(0, PK11_F_ACTIVE_DELETE, 0),		"PK11_ACTIVE_DELETE"},
4947+{ ERR_PACK(0, PK11_F_CHECK_HW_MECHANISMS, 0),	"PK11_CHECK_HW_MECHANISMS"},
4948+{ ERR_PACK(0, PK11_F_INIT_SYMMETRIC, 0),	"PK11_INIT_SYMMETRIC"},
4949+{ ERR_PACK(0, PK11_F_ADD_AES_CTR_NIDS, 0),	"PK11_ADD_AES_CTR_NIDS"},
4950+{ ERR_PACK(0, PK11_F_INIT_ALL_LOCKS, 0),	"PK11_INIT_ALL_LOCKS"},
4951+{ ERR_PACK(0, PK11_F_RETURN_SESSION, 0),	"PK11_RETURN_SESSION"},
4952+{ ERR_PACK(0, PK11_F_GET_PIN, 0),		"PK11_GET_PIN"},
4953+{ ERR_PACK(0, PK11_F_FIND_ONE_OBJECT, 0),	"PK11_FIND_ONE_OBJECT"},
4954+{ ERR_PACK(0, PK11_F_CHECK_TOKEN_ATTRS, 0),	"PK11_CHECK_TOKEN_ATTRS"},
4955+{ ERR_PACK(0, PK11_F_CACHE_PIN, 0),		"PK11_CACHE_PIN"},
4956+{ ERR_PACK(0, PK11_F_MLOCK_PIN_IN_MEMORY, 0),	"PK11_MLOCK_PIN_IN_MEMORY"},
4957+{ ERR_PACK(0, PK11_F_TOKEN_LOGIN, 0),		"PK11_TOKEN_LOGIN"},
4958+{ ERR_PACK(0, PK11_F_TOKEN_RELOGIN, 0),		"PK11_TOKEN_RELOGIN"},
4959+{ ERR_PACK(0, PK11_F_RUN_ASKPASS, 0),		"PK11_F_RUN_ASKPASS"},
4960+{ 0, NULL}
4961+};
4962+
4963+static ERR_STRING_DATA pk11_str_reasons[]=
4964+{
4965+{ PK11_R_ALREADY_LOADED,		"PKCS#11 DSO already loaded"},
4966+{ PK11_R_DSO_FAILURE,			"unable to load PKCS#11 DSO"},
4967+{ PK11_R_NOT_LOADED,			"PKCS#11 DSO not loaded"},
4968+{ PK11_R_PASSED_NULL_PARAMETER,		"null parameter passed"},
4969+{ PK11_R_COMMAND_NOT_IMPLEMENTED,	"command not implemented"},
4970+{ PK11_R_INITIALIZE,			"C_Initialize failed"},
4971+{ PK11_R_FINALIZE,			"C_Finalize failed"},
4972+{ PK11_R_GETINFO,			"C_GetInfo faile"},
4973+{ PK11_R_GETSLOTLIST,			"C_GetSlotList failed"},
4974+{ PK11_R_NO_MODULUS_OR_NO_EXPONENT,	"no modulus or no exponent"},
4975+{ PK11_R_ATTRIBUT_SENSITIVE_OR_INVALID,	"attr sensitive or invalid"},
4976+{ PK11_R_GETATTRIBUTVALUE,		"C_GetAttributeValue failed"},
4977+{ PK11_R_NO_MODULUS,			"no modulus"},
4978+{ PK11_R_NO_EXPONENT,			"no exponent"},
4979+{ PK11_R_FINDOBJECTSINIT,		"C_FindObjectsInit failed"},
4980+{ PK11_R_FINDOBJECTS,			"C_FindObjects failed"},
4981+{ PK11_R_FINDOBJECTSFINAL,		"C_FindObjectsFinal failed"},
4982+{ PK11_R_CREATEOBJECT,			"C_CreateObject failed"},
4983+{ PK11_R_DESTROYOBJECT,			"C_DestroyObject failed"},
4984+{ PK11_R_OPENSESSION,			"C_OpenSession failed"},
4985+{ PK11_R_CLOSESESSION,			"C_CloseSession failed"},
4986+{ PK11_R_ENCRYPTINIT,			"C_EncryptInit failed"},
4987+{ PK11_R_ENCRYPT,			"C_Encrypt failed"},
4988+{ PK11_R_SIGNINIT,			"C_SignInit failed"},
4989+{ PK11_R_SIGN,				"C_Sign failed"},
4990+{ PK11_R_DECRYPTINIT,			"C_DecryptInit failed"},
4991+{ PK11_R_DECRYPT,			"C_Decrypt failed"},
4992+{ PK11_R_VERIFYINIT,			"C_VerifyRecover failed"},
4993+{ PK11_R_VERIFY,			"C_Verify failed"},
4994+{ PK11_R_VERIFYRECOVERINIT,		"C_VerifyRecoverInit failed"},
4995+{ PK11_R_VERIFYRECOVER,			"C_VerifyRecover failed"},
4996+{ PK11_R_GEN_KEY,			"C_GenerateKeyPair failed"},
4997+{ PK11_R_SEEDRANDOM,			"C_SeedRandom failed"},
4998+{ PK11_R_GENERATERANDOM,		"C_GenerateRandom failed"},
4999+{ PK11_R_INVALID_MESSAGE_LENGTH,	"invalid message length"},
5000+{ PK11_R_UNKNOWN_ALGORITHM_TYPE,	"unknown algorithm type"},
5001+{ PK11_R_UNKNOWN_ASN1_OBJECT_ID,	"unknown asn1 onject id"},
5002+{ PK11_R_UNKNOWN_PADDING_TYPE,		"unknown padding type"},
5003+{ PK11_R_PADDING_CHECK_FAILED,		"padding check failed"},
5004+{ PK11_R_DIGEST_TOO_BIG,		"digest too big"},
5005+{ PK11_R_MALLOC_FAILURE,		"malloc failure"},
5006+{ PK11_R_CTRL_COMMAND_NOT_IMPLEMENTED,	"ctl command not implemented"},
5007+{ PK11_R_DATA_GREATER_THAN_MOD_LEN,	"data is bigger than mod"},
5008+{ PK11_R_DATA_TOO_LARGE_FOR_MODULUS,	"data is too larger for mod"},
5009+{ PK11_R_MISSING_KEY_COMPONENT,		"a dsa component is missing"},
5010+{ PK11_R_INVALID_SIGNATURE_LENGTH,	"invalid signature length"},
5011+{ PK11_R_INVALID_DSA_SIGNATURE_R,	"missing r in dsa verify"},
5012+{ PK11_R_INVALID_DSA_SIGNATURE_S,	"missing s in dsa verify"},
5013+{ PK11_R_INCONSISTENT_KEY,		"inconsistent key type"},
5014+{ PK11_R_ENCRYPTUPDATE,			"C_EncryptUpdate failed"},
5015+{ PK11_R_DECRYPTUPDATE,			"C_DecryptUpdate failed"},
5016+{ PK11_R_DIGESTINIT,			"C_DigestInit failed"},
5017+{ PK11_R_DIGESTUPDATE,			"C_DigestUpdate failed"},
5018+{ PK11_R_DIGESTFINAL,			"C_DigestFinal failed"},
5019+{ PK11_R_ENCRYPTFINAL,			"C_EncryptFinal failed"},
5020+{ PK11_R_DECRYPTFINAL,			"C_DecryptFinal failed"},
5021+{ PK11_R_NO_PRNG_SUPPORT,		"Slot does not support PRNG"},
5022+{ PK11_R_GETTOKENINFO,			"C_GetTokenInfo failed"},
5023+{ PK11_R_DERIVEKEY,			"C_DeriveKey failed"},
5024+{ PK11_R_GET_OPERATION_STATE,		"C_GetOperationState failed"},
5025+{ PK11_R_SET_OPERATION_STATE,		"C_SetOperationState failed"},
5026+{ PK11_R_INVALID_HANDLE,		"invalid PKCS#11 object handle"},
5027+{ PK11_R_KEY_OR_IV_LEN_PROBLEM,		"IV or key length incorrect"},
5028+{ PK11_R_INVALID_OPERATION_TYPE,	"invalid operation type"},
5029+{ PK11_R_ADD_NID_FAILED,		"failed to add NID" },
5030+{ PK11_R_ATFORK_FAILED,			"atfork() failed" },
5031+{ PK11_R_TOKEN_LOGIN_FAILED,		"C_Login() failed on token" },
5032+{ PK11_R_MORE_THAN_ONE_OBJECT_FOUND,	"more than one object found" },
5033+{ PK11_R_INVALID_PKCS11_URI,		"pkcs11 URI provided is invalid" },
5034+{ PK11_R_COULD_NOT_READ_PIN,		"could not read PIN from terminal" },
5035+{ PK11_R_PIN_NOT_READ_FROM_COMMAND,	"PIN not read from external command" },
5036+{ PK11_R_COULD_NOT_OPEN_COMMAND,	"could not popen() dialog command" },
5037+{ PK11_R_PIPE_FAILED,			"pipe() failed" },
5038+{ PK11_R_BAD_PASSPHRASE_SPEC,		"bad passphrasedialog specification" },
5039+{ PK11_R_TOKEN_NOT_INITIALIZED,		"token not initialized" },
5040+{ PK11_R_TOKEN_PIN_NOT_SET,		"token PIN required but not set" },
5041+{ PK11_R_TOKEN_PIN_NOT_PROVIDED,	"token PIN required but not provided" },
5042+{ PK11_R_MISSING_OBJECT_LABEL,		"missing mandatory 'object' keyword" },
5043+{ PK11_R_TOKEN_ATTRS_DO_NOT_MATCH,	"token attrs provided do not match" },
5044+{ PK11_R_PRIV_KEY_NOT_FOUND,		"private key not found in keystore" },
5045+{ PK11_R_NO_OBJECT_FOUND,		"specified object not found" },
5046+{ PK11_R_PIN_CACHING_POLICY_INVALID,	"PIN set but caching policy invalid" },
5047+{ PK11_R_SYSCONF_FAILED,		"sysconf() failed" },
5048+{ PK11_R_MMAP_FAILED,			"mmap() failed" },
5049+{ PK11_R_PRIV_PROC_LOCK_MEMORY_MISSING,	"PROC_LOCK_MEMORY privilege missing" },
5050+{ PK11_R_MLOCK_FAILED,			"mlock() failed" },
5051+{ PK11_R_FORK_FAILED,			"fork() failed" },
5052+{ 0,	NULL}
5053+};
5054+#endif	/* OPENSSL_NO_ERR */
5055+
5056+static int pk11_lib_error_code = 0;
5057+static int pk11_error_init = 1;
5058+
5059+static void
5060+ERR_load_pk11_strings(void)
5061+	{
5062+	if (pk11_lib_error_code == 0)
5063+		pk11_lib_error_code = ERR_get_next_error_library();
5064+
5065+	if (pk11_error_init)
5066+		{
5067+		pk11_error_init = 0;
5068+#ifndef OPENSSL_NO_ERR
5069+		ERR_load_strings(pk11_lib_error_code, pk11_str_functs);
5070+		ERR_load_strings(pk11_lib_error_code, pk11_str_reasons);
5071+#endif
5072+		}
5073+}
5074+
5075+static void
5076+ERR_unload_pk11_strings(void)
5077+	{
5078+	if (pk11_error_init == 0)
5079+		{
5080+#ifndef OPENSSL_NO_ERR
5081+		ERR_unload_strings(pk11_lib_error_code, pk11_str_functs);
5082+		ERR_unload_strings(pk11_lib_error_code, pk11_str_reasons);
5083+#endif
5084+		pk11_error_init = 1;
5085+		}
5086+}
5087+
5088+void
5089+ERR_pk11_error(int function, int reason, char *file, int line)
5090+{
5091+	if (pk11_lib_error_code == 0)
5092+		pk11_lib_error_code = ERR_get_next_error_library();
5093+	ERR_PUT_error(pk11_lib_error_code, function, reason, file, line);
5094+}
5095+
5096+void
5097+PK11err_add_data(int function, int reason, CK_RV rv)
5098+{
5099+	char tmp_buf[20];
5100+
5101+	PK11err(function, reason);
5102+	(void) BIO_snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
5103+	ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
5104+}
5105Index: openssl/crypto/engine/hw_pk11_err.h
5106diff -u /dev/null openssl/crypto/engine/hw_pk11_err.h:1.12
5107--- /dev/null	Mon Jan 16 18:54:23 2012
5108+++ openssl/crypto/engine/hw_pk11_err.h	Tue Jun 14 21:51:32 2011
5109@@ -0,0 +1,440 @@
5110+/*
5111+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
5112+ * Use is subject to license terms.
5113+ */
5114+
5115+/*
5116+ * This product includes software developed by the OpenSSL Project for
5117+ * use in the OpenSSL Toolkit (http://www.openssl.org/).
5118+ *
5119+ * This project also referenced hw_pkcs11-0.9.7b.patch written by
5120+ * Afchine Madjlessi.
5121+ */
5122+/*
5123+ * ====================================================================
5124+ * Copyright (c) 2000-2001 The OpenSSL Project.  All rights reserved.
5125+ *
5126+ * Redistribution and use in source and binary forms, with or without
5127+ * modification, are permitted provided that the following conditions
5128+ * are met:
5129+ *
5130+ * 1. Redistributions of source code must retain the above copyright
5131+ *    notice, this list of conditions and the following disclaimer.
5132+ *
5133+ * 2. Redistributions in binary form must reproduce the above copyright
5134+ *    notice, this list of conditions and the following disclaimer in
5135+ *    the documentation and/or other materials provided with the
5136+ *    distribution.
5137+ *
5138+ * 3. All advertising materials mentioning features or use of this
5139+ *    software must display the following acknowledgment:
5140+ *    "This product includes software developed by the OpenSSL Project
5141+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
5142+ *
5143+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
5144+ *    endorse or promote products derived from this software without
5145+ *    prior written permission. For written permission, please contact
5146+ *    licensing@OpenSSL.org.
5147+ *
5148+ * 5. Products derived from this software may not be called "OpenSSL"
5149+ *    nor may "OpenSSL" appear in their names without prior written
5150+ *    permission of the OpenSSL Project.
5151+ *
5152+ * 6. Redistributions of any form whatsoever must retain the following
5153+ *    acknowledgment:
5154+ *    "This product includes software developed by the OpenSSL Project
5155+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
5156+ *
5157+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
5158+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
5159+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
5160+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
5161+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
5162+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
5163+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
5164+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
5165+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
5166+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
5167+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
5168+ * OF THE POSSIBILITY OF SUCH DAMAGE.
5169+ * ====================================================================
5170+ *
5171+ * This product includes cryptographic software written by Eric Young
5172+ * (eay@cryptsoft.com).  This product includes software written by Tim
5173+ * Hudson (tjh@cryptsoft.com).
5174+ *
5175+ */
5176+
5177+#ifndef	HW_PK11_ERR_H
5178+#define	HW_PK11_ERR_H
5179+
5180+void ERR_pk11_error(int function, int reason, char *file, int line);
5181+void PK11err_add_data(int function, int reason, CK_RV rv);
5182+#define	PK11err(f, r)	ERR_pk11_error((f), (r), __FILE__, __LINE__)
5183+
5184+/* Error codes for the PK11 functions. */
5185+
5186+/* Function codes. */
5187+
5188+#define	PK11_F_INIT				100
5189+#define	PK11_F_FINISH				101
5190+#define	PK11_F_DESTROY				102
5191+#define	PK11_F_CTRL				103
5192+#define	PK11_F_RSA_INIT				104
5193+#define	PK11_F_RSA_FINISH			105
5194+#define	PK11_F_GET_PUB_RSA_KEY			106
5195+#define	PK11_F_GET_PRIV_RSA_KEY			107
5196+#define	PK11_F_RSA_GEN_KEY			108
5197+#define	PK11_F_RSA_PUB_ENC			109
5198+#define	PK11_F_RSA_PRIV_ENC			110
5199+#define	PK11_F_RSA_PUB_DEC			111
5200+#define	PK11_F_RSA_PRIV_DEC			112
5201+#define	PK11_F_RSA_SIGN				113
5202+#define	PK11_F_RSA_VERIFY			114
5203+#define	PK11_F_RAND_ADD				115
5204+#define	PK11_F_RAND_BYTES			116
5205+#define	PK11_F_GET_SESSION			117
5206+#define	PK11_F_FREE_SESSION			118
5207+#define	PK11_F_LOAD_PUBKEY			119
5208+#define	PK11_F_LOAD_PRIVKEY			120
5209+#define	PK11_F_RSA_PUB_ENC_LOW			121
5210+#define	PK11_F_RSA_PRIV_ENC_LOW			122
5211+#define	PK11_F_RSA_PUB_DEC_LOW			123
5212+#define	PK11_F_RSA_PRIV_DEC_LOW			124
5213+#define	PK11_F_DSA_SIGN				125
5214+#define	PK11_F_DSA_VERIFY			126
5215+#define	PK11_F_DSA_INIT				127
5216+#define	PK11_F_DSA_FINISH			128
5217+#define	PK11_F_GET_PUB_DSA_KEY			129
5218+#define	PK11_F_GET_PRIV_DSA_KEY			130
5219+#define	PK11_F_DH_INIT				131
5220+#define	PK11_F_DH_FINISH			132
5221+#define	PK11_F_MOD_EXP_DH			133
5222+#define	PK11_F_GET_DH_KEY			134
5223+#define	PK11_F_FREE_ALL_SESSIONS		135
5224+#define	PK11_F_SETUP_SESSION			136
5225+#define	PK11_F_DESTROY_OBJECT			137
5226+#define	PK11_F_CIPHER_INIT			138
5227+#define	PK11_F_CIPHER_DO_CIPHER			139
5228+#define	PK11_F_GET_CIPHER_KEY			140
5229+#define	PK11_F_DIGEST_INIT			141
5230+#define	PK11_F_DIGEST_UPDATE			142
5231+#define	PK11_F_DIGEST_FINAL			143
5232+#define	PK11_F_CHOOSE_SLOT			144
5233+#define	PK11_F_CIPHER_FINAL			145
5234+#define	PK11_F_LIBRARY_INIT			146
5235+#define	PK11_F_LOAD				147
5236+#define	PK11_F_DH_GEN_KEY			148
5237+#define	PK11_F_DH_COMP_KEY			149
5238+#define	PK11_F_DIGEST_COPY			150
5239+#define	PK11_F_CIPHER_CLEANUP			151
5240+#define	PK11_F_ACTIVE_ADD			152
5241+#define	PK11_F_ACTIVE_DELETE			153
5242+#define	PK11_F_CHECK_HW_MECHANISMS		154
5243+#define	PK11_F_INIT_SYMMETRIC			155
5244+#define	PK11_F_ADD_AES_CTR_NIDS			156
5245+#define	PK11_F_INIT_ALL_LOCKS			157
5246+#define	PK11_F_RETURN_SESSION			158
5247+#define	PK11_F_GET_PIN				159
5248+#define	PK11_F_FIND_ONE_OBJECT			160
5249+#define	PK11_F_CHECK_TOKEN_ATTRS		161
5250+#define	PK11_F_CACHE_PIN			162
5251+#define	PK11_F_MLOCK_PIN_IN_MEMORY		163
5252+#define	PK11_F_TOKEN_LOGIN			164
5253+#define	PK11_F_TOKEN_RELOGIN			165
5254+#define	PK11_F_RUN_ASKPASS			166
5255+
5256+/* Reason codes. */
5257+#define	PK11_R_ALREADY_LOADED 			100
5258+#define	PK11_R_DSO_FAILURE 			101
5259+#define	PK11_R_NOT_LOADED 			102
5260+#define	PK11_R_PASSED_NULL_PARAMETER 		103
5261+#define	PK11_R_COMMAND_NOT_IMPLEMENTED 		104
5262+#define	PK11_R_INITIALIZE 			105
5263+#define	PK11_R_FINALIZE 			106
5264+#define	PK11_R_GETINFO 				107
5265+#define	PK11_R_GETSLOTLIST 			108
5266+#define	PK11_R_NO_MODULUS_OR_NO_EXPONENT 	109
5267+#define	PK11_R_ATTRIBUT_SENSITIVE_OR_INVALID 	110
5268+#define	PK11_R_GETATTRIBUTVALUE 		111
5269+#define	PK11_R_NO_MODULUS 			112
5270+#define	PK11_R_NO_EXPONENT 			113
5271+#define	PK11_R_FINDOBJECTSINIT 			114
5272+#define	PK11_R_FINDOBJECTS 			115
5273+#define	PK11_R_FINDOBJECTSFINAL 		116
5274+#define	PK11_R_CREATEOBJECT 			118
5275+#define	PK11_R_DESTROYOBJECT 			119
5276+#define	PK11_R_OPENSESSION 			120
5277+#define	PK11_R_CLOSESESSION 			121
5278+#define	PK11_R_ENCRYPTINIT 			122
5279+#define	PK11_R_ENCRYPT 				123
5280+#define	PK11_R_SIGNINIT 			124
5281+#define	PK11_R_SIGN 				125
5282+#define	PK11_R_DECRYPTINIT 			126
5283+#define	PK11_R_DECRYPT 				127
5284+#define	PK11_R_VERIFYINIT 			128
5285+#define	PK11_R_VERIFY 				129
5286+#define	PK11_R_VERIFYRECOVERINIT 		130
5287+#define	PK11_R_VERIFYRECOVER 			131
5288+#define	PK11_R_GEN_KEY 				132
5289+#define	PK11_R_SEEDRANDOM 			133
5290+#define	PK11_R_GENERATERANDOM 			134
5291+#define	PK11_R_INVALID_MESSAGE_LENGTH 		135
5292+#define	PK11_R_UNKNOWN_ALGORITHM_TYPE 		136
5293+#define	PK11_R_UNKNOWN_ASN1_OBJECT_ID 		137
5294+#define	PK11_R_UNKNOWN_PADDING_TYPE 		138
5295+#define	PK11_R_PADDING_CHECK_FAILED 		139
5296+#define	PK11_R_DIGEST_TOO_BIG 			140
5297+#define	PK11_R_MALLOC_FAILURE 			141
5298+#define	PK11_R_CTRL_COMMAND_NOT_IMPLEMENTED 	142
5299+#define	PK11_R_DATA_GREATER_THAN_MOD_LEN 	143
5300+#define	PK11_R_DATA_TOO_LARGE_FOR_MODULUS 	144
5301+#define	PK11_R_MISSING_KEY_COMPONENT		145
5302+#define	PK11_R_INVALID_SIGNATURE_LENGTH		146
5303+#define	PK11_R_INVALID_DSA_SIGNATURE_R		147
5304+#define	PK11_R_INVALID_DSA_SIGNATURE_S		148
5305+#define	PK11_R_INCONSISTENT_KEY			149
5306+#define	PK11_R_ENCRYPTUPDATE			150
5307+#define	PK11_R_DECRYPTUPDATE			151
5308+#define	PK11_R_DIGESTINIT			152
5309+#define	PK11_R_DIGESTUPDATE			153
5310+#define	PK11_R_DIGESTFINAL			154
5311+#define	PK11_R_ENCRYPTFINAL			155
5312+#define	PK11_R_DECRYPTFINAL			156
5313+#define	PK11_R_NO_PRNG_SUPPORT			157
5314+#define	PK11_R_GETTOKENINFO			158
5315+#define	PK11_R_DERIVEKEY			159
5316+#define	PK11_R_GET_OPERATION_STATE		160
5317+#define	PK11_R_SET_OPERATION_STATE		161
5318+#define	PK11_R_INVALID_HANDLE			162
5319+#define	PK11_R_KEY_OR_IV_LEN_PROBLEM		163
5320+#define	PK11_R_INVALID_OPERATION_TYPE		164
5321+#define	PK11_R_ADD_NID_FAILED			165
5322+#define	PK11_R_ATFORK_FAILED			166
5323+
5324+#define	PK11_R_TOKEN_LOGIN_FAILED		167
5325+#define	PK11_R_MORE_THAN_ONE_OBJECT_FOUND	168
5326+#define	PK11_R_INVALID_PKCS11_URI		169
5327+#define	PK11_R_COULD_NOT_READ_PIN		170
5328+#define	PK11_R_COULD_NOT_OPEN_COMMAND		171
5329+#define	PK11_R_PIPE_FAILED			172
5330+#define	PK11_R_PIN_NOT_READ_FROM_COMMAND	173
5331+#define	PK11_R_BAD_PASSPHRASE_SPEC		174
5332+#define	PK11_R_TOKEN_NOT_INITIALIZED		175
5333+#define	PK11_R_TOKEN_PIN_NOT_SET		176
5334+#define	PK11_R_TOKEN_PIN_NOT_PROVIDED		177
5335+#define	PK11_R_MISSING_OBJECT_LABEL		178
5336+#define	PK11_R_TOKEN_ATTRS_DO_NOT_MATCH		179
5337+#define	PK11_R_PRIV_KEY_NOT_FOUND		180
5338+#define	PK11_R_NO_OBJECT_FOUND			181
5339+#define	PK11_R_PIN_CACHING_POLICY_INVALID	182
5340+#define	PK11_R_SYSCONF_FAILED			183
5341+#define	PK11_R_MMAP_FAILED			183
5342+#define	PK11_R_PRIV_PROC_LOCK_MEMORY_MISSING	184
5343+#define	PK11_R_MLOCK_FAILED			185
5344+#define	PK11_R_FORK_FAILED			186
5345+
5346+/* max byte length of a symetric key we support */
5347+#define	PK11_KEY_LEN_MAX			32
5348+
5349+#ifdef NOPTHREADS
5350+/*
5351+ * CRYPTO_LOCK_PK11_ENGINE lock is primarily used for the protection of the
5352+ * free_session list and active_list but generally serves as a global
5353+ * per-process lock for the whole engine.
5354+ *
5355+ * We reuse CRYPTO_LOCK_EC lock (which is defined in OpenSSL for EC method) as
5356+ * the global engine lock. This is not optimal w.r.t. performance but
5357+ * it's safe.
5358+ */
5359+#define CRYPTO_LOCK_PK11_ENGINE	CRYPTO_LOCK_EC
5360+#endif
5361+
5362+/*
5363+ * This structure encapsulates all reusable information for a PKCS#11
5364+ * session. A list of these objects is created on behalf of the
5365+ * calling application using an on-demand method. Each operation
5366+ * type (see PK11_OPTYPE below) has its own per-process list.
5367+ * Each of the lists is basically a cache for faster PKCS#11 object
5368+ * access to avoid expensive C_Find{,Init,Final}Object() calls.
5369+ *
5370+ * When a new request comes in, an object will be taken from the list
5371+ * (if there is one) or a new one is created to handle the request
5372+ * (if the list is empty). See pk11_get_session() on how it is done.
5373+ */
5374+typedef struct PK11_st_SESSION
5375+	{
5376+	struct PK11_st_SESSION	*next;
5377+	CK_SESSION_HANDLE	session;	/* PK11 session handle */
5378+	pid_t			pid;		/* Current process ID */
5379+	CK_BBOOL		pub_persistent;	/* is pub key in keystore? */
5380+	CK_BBOOL		priv_persistent;/* is priv key in keystore? */
5381+	union
5382+		{
5383+#ifndef OPENSSL_NO_RSA
5384+		struct
5385+			{
5386+			CK_OBJECT_HANDLE	rsa_pub_key; /* pub handle */
5387+			CK_OBJECT_HANDLE	rsa_priv_key; /* priv handle */
5388+			RSA			*rsa_pub; /* pub key addr */
5389+			BIGNUM			*rsa_n_num; /* pub modulus */
5390+			BIGNUM			*rsa_e_num; /* pub exponent */
5391+			RSA			*rsa_priv; /* priv key addr */
5392+			BIGNUM			*rsa_pn_num; /* pub modulus */
5393+			BIGNUM			*rsa_pe_num; /* pub exponent */
5394+			BIGNUM			*rsa_d_num; /* priv exponent */
5395+			} u_RSA;
5396+#endif /* OPENSSL_NO_RSA */
5397+#ifndef OPENSSL_NO_DSA
5398+		struct
5399+			{
5400+			CK_OBJECT_HANDLE	dsa_pub_key; /* pub handle */
5401+			CK_OBJECT_HANDLE	dsa_priv_key; /* priv handle */
5402+			DSA			*dsa_pub; /* pub key addr */
5403+			BIGNUM			*dsa_pub_num; /* pub key */
5404+			DSA			*dsa_priv; /* priv key addr */
5405+			BIGNUM			*dsa_priv_num; /* priv key */
5406+			} u_DSA;
5407+#endif /* OPENSSL_NO_DSA */
5408+#ifndef OPENSSL_NO_DH
5409+		struct
5410+			{
5411+			CK_OBJECT_HANDLE	dh_key; /* key handle */
5412+			DH			*dh; /* dh key addr */
5413+			BIGNUM			*dh_priv_num; /* priv dh key */
5414+			} u_DH;
5415+#endif /* OPENSSL_NO_DH */
5416+		struct
5417+			{
5418+			CK_OBJECT_HANDLE	cipher_key; /* key handle */
5419+			unsigned char		key[PK11_KEY_LEN_MAX];
5420+			int			key_len; /* priv key len */
5421+			int			encrypt; /* 1/0 enc/decr */
5422+			} u_cipher;
5423+		} opdata_u;
5424+	} PK11_SESSION;
5425+
5426+#define	opdata_rsa_pub_key	opdata_u.u_RSA.rsa_pub_key
5427+#define	opdata_rsa_priv_key	opdata_u.u_RSA.rsa_priv_key
5428+#define	opdata_rsa_pub		opdata_u.u_RSA.rsa_pub
5429+#define	opdata_rsa_priv		opdata_u.u_RSA.rsa_priv
5430+#define	opdata_rsa_n_num	opdata_u.u_RSA.rsa_n_num
5431+#define	opdata_rsa_e_num	opdata_u.u_RSA.rsa_e_num
5432+#define	opdata_rsa_pn_num	opdata_u.u_RSA.rsa_pn_num
5433+#define	opdata_rsa_pe_num	opdata_u.u_RSA.rsa_pe_num
5434+#define	opdata_rsa_d_num	opdata_u.u_RSA.rsa_d_num
5435+#define	opdata_dsa_pub_key	opdata_u.u_DSA.dsa_pub_key
5436+#define	opdata_dsa_priv_key	opdata_u.u_DSA.dsa_priv_key
5437+#define	opdata_dsa_pub		opdata_u.u_DSA.dsa_pub
5438+#define	opdata_dsa_pub_num	opdata_u.u_DSA.dsa_pub_num
5439+#define	opdata_dsa_priv		opdata_u.u_DSA.dsa_priv
5440+#define	opdata_dsa_priv_num	opdata_u.u_DSA.dsa_priv_num
5441+#define	opdata_dh_key		opdata_u.u_DH.dh_key
5442+#define	opdata_dh		opdata_u.u_DH.dh
5443+#define	opdata_dh_priv_num	opdata_u.u_DH.dh_priv_num
5444+#define	opdata_cipher_key	opdata_u.u_cipher.cipher_key
5445+#define	opdata_key		opdata_u.u_cipher.key
5446+#define	opdata_key_len		opdata_u.u_cipher.key_len
5447+#define	opdata_encrypt		opdata_u.u_cipher.encrypt
5448+
5449+/*
5450+ * We have 3 different groups of operation types:
5451+ *   1) asymmetric operations
5452+ *   2) random operations
5453+ *   3) symmetric and digest operations
5454+ *
5455+ * This division into groups stems from the fact that it's common that hardware
5456+ * providers may support operations from one group only. For example, hardware
5457+ * providers on UltraSPARC T2, n2rng(7d), ncp(7d), and n2cp(7d), each support
5458+ * only a single group of operations.
5459+ *
5460+ * For every group a different slot can be chosen. That means that we must have
5461+ * at least 3 different lists of cached PKCS#11 sessions since sessions from
5462+ * different groups may be initialized in different slots.
5463+ *
5464+ * To provide locking granularity in multithreaded environment, the groups are
5465+ * further splitted into types with each type having a separate session cache.
5466+ */
5467+typedef enum PK11_OPTYPE_ENUM
5468+	{
5469+	OP_RAND,
5470+	OP_RSA,
5471+	OP_DSA,
5472+	OP_DH,
5473+	OP_CIPHER,
5474+	OP_DIGEST,
5475+	OP_MAX
5476+	} PK11_OPTYPE;
5477+
5478+/*
5479+ * This structure contains the heads of the lists forming the object caches
5480+ * and locks associated with the lists.
5481+ */
5482+typedef struct PK11_st_CACHE
5483+	{
5484+	PK11_SESSION *head;
5485+#ifndef NOPTHREADS
5486+	pthread_mutex_t *lock;
5487+#endif
5488+	} PK11_CACHE;
5489+
5490+/* structure for tracking handles of asymmetric key objects */
5491+typedef struct PK11_active_st
5492+	{
5493+	CK_OBJECT_HANDLE h;
5494+	unsigned int refcnt;
5495+	struct PK11_active_st *prev;
5496+	struct PK11_active_st *next;
5497+	} PK11_active;
5498+
5499+#ifndef NOPTHREADS
5500+extern pthread_mutex_t *find_lock[];
5501+#endif
5502+extern PK11_active *active_list[];
5503+/*
5504+ * These variables are specific for the RSA keys by reference code. See
5505+ * hw_pk11_pub.c for explanation.
5506+ */
5507+extern CK_FLAGS pubkey_token_flags;
5508+
5509+#ifndef NOPTHREADS
5510+#define	LOCK_OBJSTORE(alg_type)	\
5511+	(void) pthread_mutex_lock(find_lock[alg_type])
5512+#define	UNLOCK_OBJSTORE(alg_type)	\
5513+	(void) pthread_mutex_unlock(find_lock[alg_type])
5514+#else
5515+#define	LOCK_OBJSTORE(alg_type)	\
5516+	CRYPTO_w_lock(CRYPTO_LOCK_PK11_ENGINE)
5517+#define	UNLOCK_OBJSTORE(alg_type)	\
5518+	CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE)
5519+#endif
5520+
5521+extern PK11_SESSION *pk11_get_session(PK11_OPTYPE optype);
5522+extern void pk11_return_session(PK11_SESSION *sp, PK11_OPTYPE optype);
5523+extern int pk11_token_relogin(CK_SESSION_HANDLE session);
5524+
5525+#ifndef OPENSSL_NO_RSA
5526+extern int pk11_destroy_rsa_key_objects(PK11_SESSION *session);
5527+extern int pk11_destroy_rsa_object_pub(PK11_SESSION *sp, CK_BBOOL uselock);
5528+extern int pk11_destroy_rsa_object_priv(PK11_SESSION *sp, CK_BBOOL uselock);
5529+extern EVP_PKEY *pk11_load_privkey(ENGINE *e, const char *pubkey_file,
5530+	UI_METHOD *ui_method, void *callback_data);
5531+extern EVP_PKEY *pk11_load_pubkey(ENGINE *e, const char *pubkey_file,
5532+	UI_METHOD *ui_method, void *callback_data);
5533+extern RSA_METHOD *PK11_RSA(void);
5534+#endif /* OPENSSL_NO_RSA */
5535+#ifndef OPENSSL_NO_DSA
5536+extern int pk11_destroy_dsa_key_objects(PK11_SESSION *session);
5537+extern int pk11_destroy_dsa_object_pub(PK11_SESSION *sp, CK_BBOOL uselock);
5538+extern int pk11_destroy_dsa_object_priv(PK11_SESSION *sp, CK_BBOOL uselock);
5539+extern DSA_METHOD *PK11_DSA(void);
5540+#endif /* OPENSSL_NO_DSA */
5541+#ifndef OPENSSL_NO_DH
5542+extern int pk11_destroy_dh_key_objects(PK11_SESSION *session);
5543+extern int pk11_destroy_dh_object(PK11_SESSION *sp, CK_BBOOL uselock);
5544+extern DH_METHOD *PK11_DH(void);
5545+#endif /* OPENSSL_NO_DH */
5546+
5547+extern CK_FUNCTION_LIST_PTR pFuncList;
5548+
5549+#endif /* HW_PK11_ERR_H */
5550Index: openssl/crypto/engine/hw_pk11_pub.c
5551diff -u /dev/null openssl/crypto/engine/hw_pk11_pub.c:1.37
5552--- /dev/null	Mon Jan 16 18:54:23 2012
5553+++ openssl/crypto/engine/hw_pk11_pub.c	Fri Jun 17 07:55:25 2011
5554@@ -0,0 +1,3530 @@
5555+/*
5556+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
5557+ * Use is subject to license terms.
5558+ */
5559+
5560+/* crypto/engine/hw_pk11_pub.c */
5561+/*
5562+ * This product includes software developed by the OpenSSL Project for
5563+ * use in the OpenSSL Toolkit (http://www.openssl.org/).
5564+ *
5565+ * This project also referenced hw_pkcs11-0.9.7b.patch written by
5566+ * Afchine Madjlessi.
5567+ */
5568+/*
5569+ * ====================================================================
5570+ * Copyright (c) 2000-2001 The OpenSSL Project.  All rights reserved.
5571+ *
5572+ * Redistribution and use in source and binary forms, with or without
5573+ * modification, are permitted provided that the following conditions
5574+ * are met:
5575+ *
5576+ * 1. Redistributions of source code must retain the above copyright
5577+ *    notice, this list of conditions and the following disclaimer.
5578+ *
5579+ * 2. Redistributions in binary form must reproduce the above copyright
5580+ *    notice, this list of conditions and the following disclaimer in
5581+ *    the documentation and/or other materials provided with the
5582+ *    distribution.
5583+ *
5584+ * 3. All advertising materials mentioning features or use of this
5585+ *    software must display the following acknowledgment:
5586+ *    "This product includes software developed by the OpenSSL Project
5587+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
5588+ *
5589+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
5590+ *    endorse or promote products derived from this software without
5591+ *    prior written permission. For written permission, please contact
5592+ *    licensing@OpenSSL.org.
5593+ *
5594+ * 5. Products derived from this software may not be called "OpenSSL"
5595+ *    nor may "OpenSSL" appear in their names without prior written
5596+ *    permission of the OpenSSL Project.
5597+ *
5598+ * 6. Redistributions of any form whatsoever must retain the following
5599+ *    acknowledgment:
5600+ *    "This product includes software developed by the OpenSSL Project
5601+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
5602+ *
5603+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
5604+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
5605+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
5606+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
5607+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
5608+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
5609+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
5610+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
5611+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
5612+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
5613+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
5614+ * OF THE POSSIBILITY OF SUCH DAMAGE.
5615+ * ====================================================================
5616+ *
5617+ * This product includes cryptographic software written by Eric Young
5618+ * (eay@cryptsoft.com).  This product includes software written by Tim
5619+ * Hudson (tjh@cryptsoft.com).
5620+ *
5621+ */
5622+
5623+#include <stdio.h>
5624+#include <stdlib.h>
5625+#include <string.h>
5626+#include <sys/types.h>
5627+
5628+#include <openssl/e_os2.h>
5629+#include <openssl/crypto.h>
5630+#include <cryptlib.h>
5631+#include <openssl/engine.h>
5632+#include <openssl/dso.h>
5633+#include <openssl/err.h>
5634+#include <openssl/bn.h>
5635+#include <openssl/pem.h>
5636+#ifndef OPENSSL_NO_RSA
5637+#include <openssl/rsa.h>
5638+#endif /* OPENSSL_NO_RSA */
5639+#ifndef OPENSSL_NO_DSA
5640+#include <openssl/dsa.h>
5641+#endif /* OPENSSL_NO_DSA */
5642+#ifndef OPENSSL_NO_DH
5643+#include <openssl/dh.h>
5644+#endif /* OPENSSL_NO_DH */
5645+#include <openssl/rand.h>
5646+#include <openssl/objects.h>
5647+#include <openssl/x509.h>
5648+
5649+#ifdef OPENSSL_SYS_WIN32
5650+#define NOPTHREADS
5651+typedef int pid_t;
5652+#define HAVE_GETPASSPHRASE
5653+static char *getpassphrase(const char *prompt);
5654+#ifndef NULL_PTR
5655+#define NULL_PTR NULL
5656+#endif
5657+#define CK_DEFINE_FUNCTION(returnType, name) \
5658+	returnType __declspec(dllexport) name
5659+#define CK_DECLARE_FUNCTION(returnType, name) \
5660+	returnType __declspec(dllimport) name
5661+#define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
5662+	returnType __declspec(dllimport) (* name)
5663+#else
5664+#include <unistd.h>
5665+#endif
5666+
5667+#ifndef NOPTHREADS
5668+#include <pthread.h>
5669+#endif
5670+
5671+#ifndef OPENSSL_NO_HW
5672+#ifndef OPENSSL_NO_HW_PK11
5673+#ifndef OPENSSL_NO_HW_PK11CA
5674+
5675+#ifdef OPENSSL_SYS_WIN32
5676+#pragma pack(push, cryptoki, 1)
5677+#include "cryptoki.h"
5678+#include "pkcs11.h"
5679+#pragma pack(pop, cryptoki)
5680+#else
5681+#include "cryptoki.h"
5682+#include "pkcs11.h"
5683+#endif
5684+#include "hw_pk11ca.h"
5685+#include "hw_pk11_err.h"
5686+
5687+static CK_BBOOL pk11_login_done = CK_FALSE;
5688+extern CK_SLOT_ID pubkey_SLOTID;
5689+#ifndef NOPTHREADS
5690+extern pthread_mutex_t *token_lock;
5691+#endif
5692+
5693+#if !(defined(HAVE_GETPASSPHRASE) || (defined (__SVR4) && defined (__sun)))
5694+#define getpassphrase(x)	getpass(x)
5695+#endif
5696+
5697+#ifndef OPENSSL_NO_RSA
5698+/* RSA stuff */
5699+static int pk11_RSA_public_encrypt(int flen, const unsigned char *from,
5700+	unsigned char *to, RSA *rsa, int padding);
5701+static int pk11_RSA_private_encrypt(int flen, const unsigned char *from,
5702+	unsigned char *to, RSA *rsa, int padding);
5703+static int pk11_RSA_public_decrypt(int flen, const unsigned char *from,
5704+	unsigned char *to, RSA *rsa, int padding);
5705+static int pk11_RSA_private_decrypt(int flen, const unsigned char *from,
5706+	unsigned char *to, RSA *rsa, int padding);
5707+static int pk11_RSA_init(RSA *rsa);
5708+static int pk11_RSA_finish(RSA *rsa);
5709+static int pk11_RSA_sign(int type, const unsigned char *m, unsigned int m_len,
5710+	unsigned char *sigret, unsigned int *siglen, const RSA *rsa);
5711+#if OPENSSL_VERSION_NUMBER < 0x10000000L
5712+static int pk11_RSA_verify(int dtype, const unsigned char *m,
5713+	unsigned int m_len, unsigned char *sigbuf, unsigned int siglen,
5714+	const RSA *rsa);
5715+#else
5716+static int pk11_RSA_verify(int dtype, const unsigned char *m,
5717+	unsigned int m_len, const unsigned char *sigbuf, unsigned int siglen,
5718+	const RSA *rsa);
5719+#endif
5720+EVP_PKEY *pk11_load_privkey(ENGINE*, const char *privkey_file,
5721+	UI_METHOD *ui_method, void *callback_data);
5722+EVP_PKEY *pk11_load_pubkey(ENGINE*, const char *pubkey_file,
5723+	UI_METHOD *ui_method, void *callback_data);
5724+
5725+static int pk11_RSA_public_encrypt_low(int flen, const unsigned char *from,
5726+	unsigned char *to, RSA *rsa);
5727+static int pk11_RSA_private_encrypt_low(int flen, const unsigned char *from,
5728+	unsigned char *to, RSA *rsa);
5729+static int pk11_RSA_public_decrypt_low(int flen, const unsigned char *from,
5730+	unsigned char *to, RSA *rsa);
5731+static int pk11_RSA_private_decrypt_low(int flen, const unsigned char *from,
5732+	unsigned char *to, RSA *rsa);
5733+
5734+static CK_OBJECT_HANDLE pk11_get_public_rsa_key(RSA* rsa, RSA** key_ptr,
5735+	BIGNUM **rsa_n_num, BIGNUM **rsa_e_num, CK_SESSION_HANDLE session);
5736+static CK_OBJECT_HANDLE pk11_get_private_rsa_key(RSA* rsa, RSA** key_ptr,
5737+	BIGNUM **rsa_d_num, BIGNUM **rsa_n_num, BIGNUM **rsa_e_num,
5738+	CK_SESSION_HANDLE session);
5739+
5740+static int check_new_rsa_key_pub(PK11_SESSION *sp, const RSA *rsa);
5741+static int check_new_rsa_key_priv(PK11_SESSION *sp, const RSA *rsa);
5742+#endif
5743+
5744+/* DSA stuff */
5745+#ifndef OPENSSL_NO_DSA
5746+static int pk11_DSA_init(DSA *dsa);
5747+static int pk11_DSA_finish(DSA *dsa);
5748+static DSA_SIG *pk11_dsa_do_sign(const unsigned char *dgst, int dlen,
5749+	DSA *dsa);
5750+static int pk11_dsa_do_verify(const unsigned char *dgst, int dgst_len,
5751+	DSA_SIG *sig, DSA *dsa);
5752+
5753+static CK_OBJECT_HANDLE pk11_get_public_dsa_key(DSA* dsa, DSA **key_ptr,
5754+	BIGNUM **dsa_pub_num, CK_SESSION_HANDLE session);
5755+static CK_OBJECT_HANDLE pk11_get_private_dsa_key(DSA* dsa, DSA **key_ptr,
5756+	BIGNUM **dsa_priv_num, CK_SESSION_HANDLE session);
5757+
5758+static int check_new_dsa_key_pub(PK11_SESSION *sp, DSA *dsa);
5759+static int check_new_dsa_key_priv(PK11_SESSION *sp, DSA *dsa);
5760+#endif
5761+
5762+/* DH stuff */
5763+#ifndef OPENSSL_NO_DH
5764+static int pk11_DH_init(DH *dh);
5765+static int pk11_DH_finish(DH *dh);
5766+static int pk11_DH_generate_key(DH *dh);
5767+static int pk11_DH_compute_key(unsigned char *key,
5768+	const BIGNUM *pub_key, DH *dh);
5769+
5770+static CK_OBJECT_HANDLE pk11_get_dh_key(DH* dh, DH **key_ptr,
5771+	BIGNUM **priv_key, CK_SESSION_HANDLE session);
5772+
5773+static int check_new_dh_key(PK11_SESSION *sp, DH *dh);
5774+#endif
5775+
5776+static int find_one_object(PK11_OPTYPE op, CK_SESSION_HANDLE s,
5777+	CK_ATTRIBUTE_PTR ptempl, CK_ULONG nattr, CK_OBJECT_HANDLE_PTR pkey);
5778+static int init_template_value(BIGNUM *bn, CK_VOID_PTR *pValue,
5779+	CK_ULONG *ulValueLen);
5780+static void attr_to_BN(CK_ATTRIBUTE_PTR attr, CK_BYTE attr_data[], BIGNUM **bn);
5781+
5782+static int pk11_token_login(CK_SESSION_HANDLE session, CK_BBOOL *login_done,
5783+	CK_BBOOL is_private);
5784+
5785+/* Read mode string to be used for fopen() */
5786+#if SOLARIS_OPENSSL
5787+static char *read_mode_flags = "rF";
5788+#else
5789+static char *read_mode_flags = "r";
5790+#endif
5791+
5792+/*
5793+ * increment/create reference for an asymmetric key handle via active list
5794+ * manipulation. If active list operation fails, unlock (if locked), set error
5795+ * variable and jump to the specified label.
5796+ */
5797+#define	KEY_HANDLE_REFHOLD(key_handle, alg_type, unlock, var, label)	\
5798+	{								\
5799+	if (pk11_active_add(key_handle, alg_type) < 0)			\
5800+		{							\
5801+		var = TRUE;						\
5802+		if (unlock)						\
5803+			UNLOCK_OBJSTORE(alg_type);			\
5804+		goto label;						\
5805+		}							\
5806+	}
5807+
5808+/*
5809+ * Find active list entry according to object handle and return pointer to the
5810+ * entry otherwise return NULL.
5811+ *
5812+ * This function presumes it is called with lock protecting the active list
5813+ * held.
5814+ */
5815+static PK11_active *pk11_active_find(CK_OBJECT_HANDLE h, PK11_OPTYPE type)
5816+	{
5817+	PK11_active *entry;
5818+
5819+	for (entry = active_list[type]; entry != NULL; entry = entry->next)
5820+		if (entry->h == h)
5821+			return (entry);
5822+
5823+	return (NULL);
5824+	}
5825+
5826+/*
5827+ * Search for an entry in the active list using PKCS#11 object handle as a
5828+ * search key and return refcnt of the found/created entry or -1 in case of
5829+ * failure.
5830+ *
5831+ * This function presumes it is called with lock protecting the active list
5832+ * held.
5833+ */
5834+int
5835+pk11_active_add(CK_OBJECT_HANDLE h, PK11_OPTYPE type)
5836+	{
5837+	PK11_active *entry = NULL;
5838+
5839+	if (h == CK_INVALID_HANDLE)
5840+		{
5841+		PK11err(PK11_F_ACTIVE_ADD, PK11_R_INVALID_HANDLE);
5842+		return (-1);
5843+		}
5844+
5845+	/* search for entry in the active list */
5846+	if ((entry = pk11_active_find(h, type)) != NULL)
5847+		entry->refcnt++;
5848+	else
5849+		{
5850+		/* not found, create new entry and add it to the list */
5851+		entry = OPENSSL_malloc(sizeof (PK11_active));
5852+		if (entry == NULL)
5853+			{
5854+			PK11err(PK11_F_ACTIVE_ADD, PK11_R_MALLOC_FAILURE);
5855+			return (-1);
5856+			}
5857+		entry->h = h;
5858+		entry->refcnt = 1;
5859+		entry->prev = NULL;
5860+		entry->next = NULL;
5861+		/* connect the newly created entry to the list */
5862+		if (active_list[type] == NULL)
5863+			active_list[type] = entry;
5864+		else /* make the entry first in the list */
5865+			{
5866+			entry->next = active_list[type];
5867+			active_list[type]->prev = entry;
5868+			active_list[type] = entry;
5869+			}
5870+		}
5871+
5872+	return (entry->refcnt);
5873+	}
5874+
5875+/*
5876+ * Remove active list entry from the list and free it.
5877+ *
5878+ * This function presumes it is called with lock protecting the active list
5879+ * held.
5880+ */
5881+void
5882+pk11_active_remove(PK11_active *entry, PK11_OPTYPE type)
5883+	{
5884+	PK11_active *prev_entry;
5885+
5886+	/* remove the entry from the list and free it */
5887+	if ((prev_entry = entry->prev) != NULL)
5888+		{
5889+		prev_entry->next = entry->next;
5890+		if (entry->next != NULL)
5891+			entry->next->prev = prev_entry;
5892+		}
5893+	else
5894+		{
5895+		active_list[type] = entry->next;
5896+		/* we were the first but not the only one */
5897+		if (entry->next != NULL)
5898+			entry->next->prev = NULL;
5899+		}
5900+
5901+	/* sanitization */
5902+	entry->h = CK_INVALID_HANDLE;
5903+	entry->prev = NULL;
5904+	entry->next = NULL;
5905+	OPENSSL_free(entry);
5906+	}
5907+
5908+/* Free all entries from the active list. */
5909+void
5910+pk11_free_active_list(PK11_OPTYPE type)
5911+	{
5912+	PK11_active *entry;
5913+
5914+	/* only for asymmetric types since only they have C_Find* locks. */
5915+	switch (type)
5916+		{
5917+		case OP_RSA:
5918+		case OP_DSA:
5919+		case OP_DH:
5920+			break;
5921+		default:
5922+			return;
5923+		}
5924+
5925+	/* see find_lock array definition for more info on object locking */
5926+	LOCK_OBJSTORE(type);
5927+	while ((entry = active_list[type]) != NULL)
5928+		pk11_active_remove(entry, type);
5929+	UNLOCK_OBJSTORE(type);
5930+	}
5931+
5932+/*
5933+ * Search for active list entry associated with given PKCS#11 object handle,
5934+ * decrement its refcnt and if it drops to 0, disconnect the entry and free it.
5935+ *
5936+ * Return 1 if the PKCS#11 object associated with the entry has no references,
5937+ * return 0 if there is at least one reference, -1 on error.
5938+ *
5939+ * This function presumes it is called with lock protecting the active list
5940+ * held.
5941+ */
5942+int
5943+pk11_active_delete(CK_OBJECT_HANDLE h, PK11_OPTYPE type)
5944+	{
5945+	PK11_active *entry = NULL;
5946+
5947+	if ((entry = pk11_active_find(h, type)) == NULL)
5948+		{
5949+		PK11err(PK11_F_ACTIVE_DELETE, PK11_R_INVALID_HANDLE);
5950+		return (-1);
5951+		}
5952+
5953+	OPENSSL_assert(entry->refcnt > 0);
5954+	entry->refcnt--;
5955+	if (entry->refcnt == 0)
5956+		{
5957+		pk11_active_remove(entry, type);
5958+		return (1);
5959+		}
5960+
5961+	return (0);
5962+	}
5963+
5964+#ifndef OPENSSL_NO_RSA
5965+/* Our internal RSA_METHOD that we provide pointers to */
5966+static RSA_METHOD pk11_rsa =
5967+	{
5968+	"PKCS#11 RSA method",
5969+	pk11_RSA_public_encrypt,		/* rsa_pub_encrypt */
5970+	pk11_RSA_public_decrypt,		/* rsa_pub_decrypt */
5971+	pk11_RSA_private_encrypt,		/* rsa_priv_encrypt */
5972+	pk11_RSA_private_decrypt,		/* rsa_priv_decrypt */
5973+	NULL,					/* rsa_mod_exp */
5974+	NULL,					/* bn_mod_exp */
5975+	pk11_RSA_init,				/* init */
5976+	pk11_RSA_finish,			/* finish */
5977+	RSA_FLAG_SIGN_VER,			/* flags */
5978+	NULL,					/* app_data */
5979+	pk11_RSA_sign,				/* rsa_sign */
5980+	pk11_RSA_verify				/* rsa_verify */
5981+	};
5982+
5983+RSA_METHOD *
5984+PK11_RSA(void)
5985+	{
5986+	return (&pk11_rsa);
5987+	}
5988+#endif
5989+
5990+#ifndef OPENSSL_NO_DSA
5991+/* Our internal DSA_METHOD that we provide pointers to */
5992+static DSA_METHOD pk11_dsa =
5993+	{
5994+	"PKCS#11 DSA method",
5995+	pk11_dsa_do_sign, 	/* dsa_do_sign */
5996+	NULL, 			/* dsa_sign_setup */
5997+	pk11_dsa_do_verify, 	/* dsa_do_verify */
5998+	NULL,			/* dsa_mod_exp */
5999+	NULL, 			/* bn_mod_exp */
6000+	pk11_DSA_init, 		/* init */
6001+	pk11_DSA_finish, 	/* finish */
6002+	0, 			/* flags */
6003+	NULL 			/* app_data */
6004+	};
6005+
6006+DSA_METHOD *
6007+PK11_DSA(void)
6008+	{
6009+	return (&pk11_dsa);
6010+	}
6011+#endif
6012+
6013+#ifndef OPENSSL_NO_DH
6014+/*
6015+ * PKCS #11 V2.20, section 11.2 specifies that the number of bytes needed for
6016+ * output buffer may somewhat exceed the precise number of bytes needed, but
6017+ * should not exceed it by a large amount. That may be caused, for example, by
6018+ * rounding it up to multiple of X in the underlying bignum library. 8 should be
6019+ * enough.
6020+ */
6021+#define	DH_BUF_RESERVE	8
6022+
6023+/* Our internal DH_METHOD that we provide pointers to */
6024+static DH_METHOD pk11_dh =
6025+	{
6026+	"PKCS#11 DH method",
6027+	pk11_DH_generate_key,	/* generate_key */
6028+	pk11_DH_compute_key,	/* compute_key */
6029+	NULL,			/* bn_mod_exp */
6030+	pk11_DH_init,		/* init */
6031+	pk11_DH_finish,		/* finish */
6032+	0,			/* flags */
6033+	NULL,			/* app_data */
6034+	NULL			/* generate_params */
6035+	};
6036+
6037+DH_METHOD *
6038+PK11_DH(void)
6039+	{
6040+	return (&pk11_dh);
6041+	}
6042+#endif
6043+
6044+/* Size of an SSL signature: MD5+SHA1 */
6045+#define	SSL_SIG_LENGTH		36
6046+
6047+/* Lengths of DSA data and signature */
6048+#define	DSA_DATA_LEN		20
6049+#define	DSA_SIGNATURE_LEN	40
6050+
6051+static CK_BBOOL true = TRUE;
6052+static CK_BBOOL false = FALSE;
6053+
6054+#ifndef OPENSSL_NO_RSA
6055+/*
6056+ * Similiar to OpenSSL to take advantage of the paddings. The goal is to
6057+ * support all paddings in this engine although PK11 library does not
6058+ * support all the paddings used in OpenSSL.
6059+ * The input errors should have been checked in the padding functions.
6060+ */
6061+static int pk11_RSA_public_encrypt(int flen, const unsigned char *from,
6062+		unsigned char *to, RSA *rsa, int padding)
6063+	{
6064+	int i, num = 0, r = -1;
6065+	unsigned char *buf = NULL;
6066+
6067+	num = BN_num_bytes(rsa->n);
6068+	if ((buf = (unsigned char *)OPENSSL_malloc(num)) == NULL)
6069+		{
6070+		RSAerr(PK11_F_RSA_PUB_ENC, PK11_R_MALLOC_FAILURE);
6071+		goto err;
6072+		}
6073+
6074+	switch (padding)
6075+		{
6076+	case RSA_PKCS1_PADDING:
6077+		i = RSA_padding_add_PKCS1_type_2(buf, num, from, flen);
6078+		break;
6079+#ifndef OPENSSL_NO_SHA
6080+	case RSA_PKCS1_OAEP_PADDING:
6081+		i = RSA_padding_add_PKCS1_OAEP(buf, num, from, flen, NULL, 0);
6082+		break;
6083+#endif
6084+	case RSA_SSLV23_PADDING:
6085+		i = RSA_padding_add_SSLv23(buf, num, from, flen);
6086+		break;
6087+	case RSA_NO_PADDING:
6088+		i = RSA_padding_add_none(buf, num, from, flen);
6089+		break;
6090+	default:
6091+		RSAerr(PK11_F_RSA_PUB_ENC, PK11_R_UNKNOWN_PADDING_TYPE);
6092+		goto err;
6093+		}
6094+	if (i <= 0) goto err;
6095+
6096+	/* PK11 functions are called here */
6097+	r = pk11_RSA_public_encrypt_low(num, buf, to, rsa);
6098+err:
6099+	if (buf != NULL)
6100+		{
6101+		OPENSSL_cleanse(buf, num);
6102+		OPENSSL_free(buf);
6103+		}
6104+	return (r);
6105+	}
6106+
6107+
6108+/*
6109+ * Similar to Openssl to take advantage of the paddings. The input errors
6110+ * should be catched in the padding functions
6111+ */
6112+static int pk11_RSA_private_encrypt(int flen, const unsigned char *from,
6113+	unsigned char *to, RSA *rsa, int padding)
6114+	{
6115+	int i, num = 0, r = -1;
6116+	unsigned char *buf = NULL;
6117+
6118+	num = BN_num_bytes(rsa->n);
6119+	if ((buf = (unsigned char *)OPENSSL_malloc(num)) == NULL)
6120+		{
6121+		RSAerr(PK11_F_RSA_PRIV_ENC, PK11_R_MALLOC_FAILURE);
6122+		goto err;
6123+		}
6124+
6125+	switch (padding)
6126+		{
6127+	case RSA_PKCS1_PADDING:
6128+		i = RSA_padding_add_PKCS1_type_1(buf, num, from, flen);
6129+		break;
6130+	case RSA_NO_PADDING:
6131+		i = RSA_padding_add_none(buf, num, from, flen);
6132+		break;
6133+	case RSA_SSLV23_PADDING:
6134+	default:
6135+		RSAerr(PK11_F_RSA_PRIV_ENC, PK11_R_UNKNOWN_PADDING_TYPE);
6136+		goto err;
6137+		}
6138+	if (i <= 0) goto err;
6139+
6140+	/* PK11 functions are called here */
6141+	r = pk11_RSA_private_encrypt_low(num, buf, to, rsa);
6142+err:
6143+	if (buf != NULL)
6144+		{
6145+		OPENSSL_cleanse(buf, num);
6146+		OPENSSL_free(buf);
6147+		}
6148+	return (r);
6149+	}
6150+
6151+/* Similar to OpenSSL code. Input errors are also checked here */
6152+static int pk11_RSA_private_decrypt(int flen, const unsigned char *from,
6153+	unsigned char *to, RSA *rsa, int padding)
6154+	{
6155+	BIGNUM f;
6156+	int j, num = 0, r = -1;
6157+	unsigned char *p;
6158+	unsigned char *buf = NULL;
6159+
6160+	BN_init(&f);
6161+
6162+	num = BN_num_bytes(rsa->n);
6163+
6164+	if ((buf = (unsigned char *)OPENSSL_malloc(num)) == NULL)
6165+		{
6166+		RSAerr(PK11_F_RSA_PRIV_DEC, PK11_R_MALLOC_FAILURE);
6167+		goto err;
6168+		}
6169+
6170+	/*
6171+	 * This check was for equality but PGP does evil things
6172+	 * and chops off the top '0' bytes
6173+	 */
6174+	if (flen > num)
6175+		{
6176+		RSAerr(PK11_F_RSA_PRIV_DEC,
6177+			PK11_R_DATA_GREATER_THAN_MOD_LEN);
6178+		goto err;
6179+		}
6180+
6181+	/* make data into a big number */
6182+	if (BN_bin2bn(from, (int)flen, &f) == NULL)
6183+		goto err;
6184+
6185+	if (BN_ucmp(&f, rsa->n) >= 0)
6186+		{
6187+		RSAerr(PK11_F_RSA_PRIV_DEC,
6188+			PK11_R_DATA_TOO_LARGE_FOR_MODULUS);
6189+		goto err;
6190+		}
6191+
6192+	/* PK11 functions are called here */
6193+	r = pk11_RSA_private_decrypt_low(flen, from, buf, rsa);
6194+
6195+	/*
6196+	 * PK11 CKM_RSA_X_509 mechanism pads 0's at the beginning.
6197+	 * Needs to skip these 0's paddings here.
6198+	 */
6199+	for (j = 0; j < r; j++)
6200+		if (buf[j] != 0)
6201+			break;
6202+
6203+	p = buf + j;
6204+	j = r - j;  /* j is only used with no-padding mode */
6205+
6206+	switch (padding)
6207+		{
6208+	case RSA_PKCS1_PADDING:
6209+		r = RSA_padding_check_PKCS1_type_2(to, num, p, j, num);
6210+		break;
6211+#ifndef OPENSSL_NO_SHA
6212+	case RSA_PKCS1_OAEP_PADDING:
6213+		r = RSA_padding_check_PKCS1_OAEP(to, num, p, j, num, NULL, 0);
6214+		break;
6215+#endif
6216+	case RSA_SSLV23_PADDING:
6217+		r = RSA_padding_check_SSLv23(to, num, p, j, num);
6218+		break;
6219+	case RSA_NO_PADDING:
6220+		r = RSA_padding_check_none(to, num, p, j, num);
6221+		break;
6222+	default:
6223+		RSAerr(PK11_F_RSA_PRIV_DEC, PK11_R_UNKNOWN_PADDING_TYPE);
6224+		goto err;
6225+		}
6226+	if (r < 0)
6227+		RSAerr(PK11_F_RSA_PRIV_DEC, PK11_R_PADDING_CHECK_FAILED);
6228+
6229+err:
6230+	BN_clear_free(&f);
6231+	if (buf != NULL)
6232+		{
6233+		OPENSSL_cleanse(buf, num);
6234+		OPENSSL_free(buf);
6235+		}
6236+	return (r);
6237+	}
6238+
6239+/* Similar to OpenSSL code. Input errors are also checked here */
6240+static int pk11_RSA_public_decrypt(int flen, const unsigned char *from,
6241+	unsigned char *to, RSA *rsa, int padding)
6242+	{
6243+	BIGNUM f;
6244+	int i, num = 0, r = -1;
6245+	unsigned char *p;
6246+	unsigned char *buf = NULL;
6247+
6248+	BN_init(&f);
6249+	num = BN_num_bytes(rsa->n);
6250+	buf = (unsigned char *)OPENSSL_malloc(num);
6251+	if (buf == NULL)
6252+		{
6253+		RSAerr(PK11_F_RSA_PUB_DEC, PK11_R_MALLOC_FAILURE);
6254+		goto err;
6255+		}
6256+
6257+	/*
6258+	 * This check was for equality but PGP does evil things
6259+	 * and chops off the top '0' bytes
6260+	 */
6261+	if (flen > num)
6262+		{
6263+		RSAerr(PK11_F_RSA_PUB_DEC, PK11_R_DATA_GREATER_THAN_MOD_LEN);
6264+		goto err;
6265+		}
6266+
6267+	if (BN_bin2bn(from, flen, &f) == NULL)
6268+		goto err;
6269+
6270+	if (BN_ucmp(&f, rsa->n) >= 0)
6271+		{
6272+		RSAerr(PK11_F_RSA_PUB_DEC,
6273+			PK11_R_DATA_TOO_LARGE_FOR_MODULUS);
6274+		goto err;
6275+		}
6276+
6277+	/* PK11 functions are called here */
6278+	r = pk11_RSA_public_decrypt_low(flen, from, buf, rsa);
6279+
6280+	/*
6281+	 * PK11 CKM_RSA_X_509 mechanism pads 0's at the beginning.
6282+	 * Needs to skip these 0's here
6283+	 */
6284+	for (i = 0; i < r; i++)
6285+		if (buf[i] != 0)
6286+			break;
6287+
6288+	p = buf + i;
6289+	i = r - i;  /* i is only used with no-padding mode */
6290+
6291+	switch (padding)
6292+		{
6293+	case RSA_PKCS1_PADDING:
6294+		r = RSA_padding_check_PKCS1_type_1(to, num, p, i, num);
6295+		break;
6296+	case RSA_NO_PADDING:
6297+		r = RSA_padding_check_none(to, num, p, i, num);
6298+		break;
6299+	default:
6300+		RSAerr(PK11_F_RSA_PUB_DEC, PK11_R_UNKNOWN_PADDING_TYPE);
6301+		goto err;
6302+		}
6303+	if (r < 0)
6304+		RSAerr(PK11_F_RSA_PUB_DEC, PK11_R_PADDING_CHECK_FAILED);
6305+
6306+err:
6307+	BN_clear_free(&f);
6308+	if (buf != NULL)
6309+		{
6310+		OPENSSL_cleanse(buf, num);
6311+		OPENSSL_free(buf);
6312+		}
6313+	return (r);
6314+	}
6315+
6316+/*
6317+ * This function implements RSA public encryption using C_EncryptInit and
6318+ * C_Encrypt pk11 interfaces. Note that the CKM_RSA_X_509 is used here.
6319+ * The calling function allocated sufficient memory in "to" to store results.
6320+ */
6321+static int pk11_RSA_public_encrypt_low(int flen,
6322+	const unsigned char *from, unsigned char *to, RSA *rsa)
6323+	{
6324+	CK_ULONG bytes_encrypted = flen;
6325+	int retval = -1;
6326+	CK_RV rv;
6327+	CK_MECHANISM mech_rsa = {CKM_RSA_X_509, NULL, 0};
6328+	CK_MECHANISM *p_mech = &mech_rsa;
6329+	CK_OBJECT_HANDLE h_pub_key = CK_INVALID_HANDLE;
6330+	PK11_SESSION *sp;
6331+
6332+	if ((sp = pk11_get_session(OP_RSA)) == NULL)
6333+		return (-1);
6334+
6335+	(void) check_new_rsa_key_pub(sp, rsa);
6336+
6337+	h_pub_key = sp->opdata_rsa_pub_key;
6338+	if (h_pub_key == CK_INVALID_HANDLE)
6339+		h_pub_key = sp->opdata_rsa_pub_key =
6340+			pk11_get_public_rsa_key(rsa, &sp->opdata_rsa_pub,
6341+			    &sp->opdata_rsa_n_num, &sp->opdata_rsa_e_num,
6342+			    sp->session);
6343+
6344+	if (h_pub_key != CK_INVALID_HANDLE)
6345+		{
6346+		rv = pFuncList->C_EncryptInit(sp->session, p_mech,
6347+			h_pub_key);
6348+
6349+		if (rv != CKR_OK)
6350+			{
6351+			PK11err_add_data(PK11_F_RSA_PUB_ENC_LOW,
6352+			    PK11_R_ENCRYPTINIT, rv);
6353+			pk11_return_session(sp, OP_RSA);
6354+			return (-1);
6355+			}
6356+
6357+		rv = pFuncList->C_Encrypt(sp->session,
6358+			(unsigned char *)from, flen, to, &bytes_encrypted);
6359+
6360+		if (rv != CKR_OK)
6361+			{
6362+			PK11err_add_data(PK11_F_RSA_PUB_ENC_LOW,
6363+			    PK11_R_ENCRYPT, rv);
6364+			pk11_return_session(sp, OP_RSA);
6365+			return (-1);
6366+			}
6367+		retval = bytes_encrypted;
6368+		}
6369+
6370+	pk11_return_session(sp, OP_RSA);
6371+	return (retval);
6372+	}
6373+
6374+
6375+/*
6376+ * This function implements RSA private encryption using C_SignInit and
6377+ * C_Sign pk11 APIs. Note that CKM_RSA_X_509 is used here.
6378+ * The calling function allocated sufficient memory in "to" to store results.
6379+ */
6380+static int pk11_RSA_private_encrypt_low(int flen,
6381+	const unsigned char *from, unsigned char *to, RSA *rsa)
6382+	{
6383+	CK_ULONG ul_sig_len = flen;
6384+	int retval = -1;
6385+	CK_RV rv;
6386+	CK_MECHANISM mech_rsa = {CKM_RSA_X_509, NULL, 0};
6387+	CK_MECHANISM *p_mech = &mech_rsa;
6388+	CK_OBJECT_HANDLE h_priv_key = CK_INVALID_HANDLE;
6389+	PK11_SESSION *sp;
6390+
6391+	if ((sp = pk11_get_session(OP_RSA)) == NULL)
6392+		return (-1);
6393+
6394+	(void) check_new_rsa_key_priv(sp, rsa);
6395+
6396+	h_priv_key = sp->opdata_rsa_priv_key;
6397+	if (h_priv_key == CK_INVALID_HANDLE)
6398+		{
6399+		h_priv_key = sp->opdata_rsa_priv_key =
6400+			pk11_get_private_rsa_key(rsa, &sp->opdata_rsa_priv,
6401+			    &sp->opdata_rsa_d_num, &sp->opdata_rsa_pn_num,
6402+			    &sp->opdata_rsa_pe_num, sp->session);
6403+		}
6404+
6405+	if (h_priv_key != CK_INVALID_HANDLE)
6406+		{
6407+		rv = pFuncList->C_SignInit(sp->session, p_mech,
6408+			h_priv_key);
6409+
6410+		if (rv != CKR_OK)
6411+			{
6412+			PK11err_add_data(PK11_F_RSA_PRIV_ENC_LOW,
6413+			    PK11_R_SIGNINIT, rv);
6414+			pk11_return_session(sp, OP_RSA);
6415+			return (-1);
6416+			}
6417+
6418+		rv = pFuncList->C_Sign(sp->session,
6419+			(unsigned char *)from, flen, to, &ul_sig_len);
6420+
6421+		if (rv != CKR_OK)
6422+			{
6423+			PK11err_add_data(PK11_F_RSA_PRIV_ENC_LOW, PK11_R_SIGN,
6424+			    rv);
6425+			pk11_return_session(sp, OP_RSA);
6426+			return (-1);
6427+			}
6428+
6429+		retval = ul_sig_len;
6430+		}
6431+
6432+	pk11_return_session(sp, OP_RSA);
6433+	return (retval);
6434+	}
6435+
6436+
6437+/*
6438+ * This function implements RSA private decryption using C_DecryptInit and
6439+ * C_Decrypt pk11 APIs. Note that CKM_RSA_X_509 mechanism is used here.
6440+ * The calling function allocated sufficient memory in "to" to store results.
6441+ */
6442+static int pk11_RSA_private_decrypt_low(int flen,
6443+	const unsigned char *from, unsigned char *to, RSA *rsa)
6444+	{
6445+	CK_ULONG bytes_decrypted = flen;
6446+	int retval = -1;
6447+	CK_RV rv;
6448+	CK_MECHANISM mech_rsa = {CKM_RSA_X_509, NULL, 0};
6449+	CK_MECHANISM *p_mech = &mech_rsa;
6450+	CK_OBJECT_HANDLE h_priv_key;
6451+	PK11_SESSION *sp;
6452+
6453+	if ((sp = pk11_get_session(OP_RSA)) == NULL)
6454+		return (-1);
6455+
6456+	(void) check_new_rsa_key_priv(sp, rsa);
6457+
6458+	h_priv_key = sp->opdata_rsa_priv_key;
6459+	if (h_priv_key == CK_INVALID_HANDLE)
6460+		h_priv_key = sp->opdata_rsa_priv_key =
6461+			pk11_get_private_rsa_key(rsa, &sp->opdata_rsa_priv,
6462+			    &sp->opdata_rsa_d_num, &sp->opdata_rsa_pn_num,
6463+			    &sp->opdata_rsa_pe_num, sp->session);
6464+
6465+	if (h_priv_key != CK_INVALID_HANDLE)
6466+		{
6467+		rv = pFuncList->C_DecryptInit(sp->session, p_mech,
6468+			h_priv_key);
6469+
6470+		if (rv != CKR_OK)
6471+			{
6472+			PK11err_add_data(PK11_F_RSA_PRIV_DEC_LOW,
6473+				PK11_R_DECRYPTINIT, rv);
6474+			pk11_return_session(sp, OP_RSA);
6475+			return (-1);
6476+			}
6477+
6478+		rv = pFuncList->C_Decrypt(sp->session,
6479+			(unsigned char *)from, flen, to, &bytes_decrypted);
6480+
6481+		if (rv != CKR_OK)
6482+			{
6483+			PK11err_add_data(PK11_F_RSA_PRIV_DEC_LOW,
6484+			    PK11_R_DECRYPT, rv);
6485+			pk11_return_session(sp, OP_RSA);
6486+			return (-1);
6487+			}
6488+		retval = bytes_decrypted;
6489+		}
6490+
6491+	pk11_return_session(sp, OP_RSA);
6492+	return (retval);
6493+	}
6494+
6495+
6496+/*
6497+ * This function implements RSA public decryption using C_VerifyRecoverInit
6498+ * and C_VerifyRecover pk11 APIs. Note that CKM_RSA_X_509 is used here.
6499+ * The calling function allocated sufficient memory in "to" to store results.
6500+ */
6501+static int pk11_RSA_public_decrypt_low(int flen,
6502+	const unsigned char *from, unsigned char *to, RSA *rsa)
6503+	{
6504+	CK_ULONG bytes_decrypted = flen;
6505+	int retval = -1;
6506+	CK_RV rv;
6507+	CK_MECHANISM mech_rsa = {CKM_RSA_X_509, NULL, 0};
6508+	CK_MECHANISM *p_mech = &mech_rsa;
6509+	CK_OBJECT_HANDLE h_pub_key = CK_INVALID_HANDLE;
6510+	PK11_SESSION *sp;
6511+
6512+	if ((sp = pk11_get_session(OP_RSA)) == NULL)
6513+		return (-1);
6514+
6515+	(void) check_new_rsa_key_pub(sp, rsa);
6516+
6517+	h_pub_key = sp->opdata_rsa_pub_key;
6518+	if (h_pub_key == CK_INVALID_HANDLE)
6519+		h_pub_key = sp->opdata_rsa_pub_key =
6520+			pk11_get_public_rsa_key(rsa, &sp->opdata_rsa_pub,
6521+			    &sp->opdata_rsa_n_num, &sp->opdata_rsa_e_num,
6522+			    sp->session);
6523+
6524+	if (h_pub_key != CK_INVALID_HANDLE)
6525+		{
6526+		rv = pFuncList->C_VerifyRecoverInit(sp->session,
6527+			p_mech, h_pub_key);
6528+
6529+		if (rv != CKR_OK)
6530+			{
6531+			PK11err_add_data(PK11_F_RSA_PUB_DEC_LOW,
6532+				PK11_R_VERIFYRECOVERINIT, rv);
6533+			pk11_return_session(sp, OP_RSA);
6534+			return (-1);
6535+			}
6536+
6537+		rv = pFuncList->C_VerifyRecover(sp->session,
6538+			(unsigned char *)from, flen, to, &bytes_decrypted);
6539+
6540+		if (rv != CKR_OK)
6541+			{
6542+			PK11err_add_data(PK11_F_RSA_PUB_DEC_LOW,
6543+			    PK11_R_VERIFYRECOVER, rv);
6544+			pk11_return_session(sp, OP_RSA);
6545+			return (-1);
6546+			}
6547+		retval = bytes_decrypted;
6548+		}
6549+
6550+	pk11_return_session(sp, OP_RSA);
6551+	return (retval);
6552+	}
6553+
6554+static int pk11_RSA_init(RSA *rsa)
6555+	{
6556+	/*
6557+	 * This flag in the RSA_METHOD enables the new rsa_sign,
6558+	 * rsa_verify functions. See rsa.h for details.
6559+	 */
6560+	rsa->flags |= RSA_FLAG_SIGN_VER;
6561+
6562+	return (1);
6563+	}
6564+
6565+static int pk11_RSA_finish(RSA *rsa)
6566+	{
6567+	/*
6568+	 * Since we are overloading OpenSSL's native RSA_eay_finish() we need
6569+	 * to do the same as in the original function, i.e. to free bignum
6570+	 * structures.
6571+	 */
6572+	if (rsa->_method_mod_n != NULL)
6573+		BN_MONT_CTX_free(rsa->_method_mod_n);
6574+	if (rsa->_method_mod_p != NULL)
6575+		BN_MONT_CTX_free(rsa->_method_mod_p);
6576+	if (rsa->_method_mod_q != NULL)
6577+		BN_MONT_CTX_free(rsa->_method_mod_q);
6578+
6579+	return (1);
6580+	}
6581+
6582+/*
6583+ * Standard engine interface function. Majority codes here are from
6584+ * rsa/rsa_sign.c. We replaced the decrypt function call by C_Sign of PKCS#11.
6585+ * See more details in rsa/rsa_sign.c
6586+ */
6587+static int pk11_RSA_sign(int type, const unsigned char *m, unsigned int m_len,
6588+	unsigned char *sigret, unsigned int *siglen, const RSA *rsa)
6589+	{
6590+	X509_SIG sig;
6591+	ASN1_TYPE parameter;
6592+	int i, j = 0;
6593+	unsigned char *p, *s = NULL;
6594+	X509_ALGOR algor;
6595+	ASN1_OCTET_STRING digest;
6596+	CK_RV rv;
6597+	CK_MECHANISM mech_rsa = {CKM_RSA_PKCS, NULL, 0};
6598+	CK_MECHANISM *p_mech = &mech_rsa;
6599+	CK_OBJECT_HANDLE h_priv_key;
6600+	PK11_SESSION *sp = NULL;
6601+	int ret = 0;
6602+	unsigned long ulsiglen;
6603+
6604+	/* Encode the digest */
6605+	/* Special case: SSL signature, just check the length */
6606+	if (type == NID_md5_sha1)
6607+		{
6608+		if (m_len != SSL_SIG_LENGTH)
6609+			{
6610+			PK11err(PK11_F_RSA_SIGN,
6611+				PK11_R_INVALID_MESSAGE_LENGTH);
6612+			goto err;
6613+			}
6614+		i = SSL_SIG_LENGTH;
6615+		s = (unsigned char *)m;
6616+		}
6617+	else
6618+		{
6619+		sig.algor = &algor;
6620+		sig.algor->algorithm = OBJ_nid2obj(type);
6621+		if (sig.algor->algorithm == NULL)
6622+			{
6623+			PK11err(PK11_F_RSA_SIGN,
6624+				PK11_R_UNKNOWN_ALGORITHM_TYPE);
6625+			goto err;
6626+			}
6627+		if (sig.algor->algorithm->length == 0)
6628+			{
6629+			PK11err(PK11_F_RSA_SIGN,
6630+				PK11_R_UNKNOWN_ASN1_OBJECT_ID);
6631+			goto err;
6632+			}
6633+		parameter.type = V_ASN1_NULL;
6634+		parameter.value.ptr = NULL;
6635+		sig.algor->parameter = &parameter;
6636+
6637+		sig.digest = &digest;
6638+		sig.digest->data = (unsigned char *)m;
6639+		sig.digest->length = m_len;
6640+
6641+		i = i2d_X509_SIG(&sig, NULL);
6642+		}
6643+
6644+	j = RSA_size(rsa);
6645+	if ((i - RSA_PKCS1_PADDING) > j)
6646+		{
6647+		PK11err(PK11_F_RSA_SIGN, PK11_R_DIGEST_TOO_BIG);
6648+		goto err;
6649+		}
6650+
6651+	if (type != NID_md5_sha1)
6652+		{
6653+		s = (unsigned char *)OPENSSL_malloc((unsigned int)(j + 1));
6654+		if (s == NULL)
6655+			{
6656+			PK11err(PK11_F_RSA_SIGN, PK11_R_MALLOC_FAILURE);
6657+			goto err;
6658+			}
6659+		p = s;
6660+		(void) i2d_X509_SIG(&sig, &p);
6661+		}
6662+
6663+	if ((sp = pk11_get_session(OP_RSA)) == NULL)
6664+		goto err;
6665+
6666+	(void) check_new_rsa_key_priv(sp, rsa);
6667+
6668+	h_priv_key = sp->opdata_rsa_priv_key;
6669+	if (h_priv_key == CK_INVALID_HANDLE)
6670+		h_priv_key = sp->opdata_rsa_priv_key =
6671+			pk11_get_private_rsa_key((RSA *)rsa,
6672+			    &sp->opdata_rsa_priv, &sp->opdata_rsa_d_num,
6673+			    &sp->opdata_rsa_pn_num, &sp->opdata_rsa_pe_num,
6674+			    sp->session);
6675+
6676+	if (h_priv_key != CK_INVALID_HANDLE)
6677+		{
6678+		rv = pFuncList->C_SignInit(sp->session, p_mech, h_priv_key);
6679+
6680+		if (rv != CKR_OK)
6681+			{
6682+			PK11err_add_data(PK11_F_RSA_SIGN, PK11_R_SIGNINIT, rv);
6683+			goto err;
6684+			}
6685+
6686+		ulsiglen = j;
6687+		rv = pFuncList->C_Sign(sp->session, s, i, sigret,
6688+			(CK_ULONG_PTR) &ulsiglen);
6689+		*siglen = ulsiglen;
6690+
6691+		if (rv != CKR_OK)
6692+			{
6693+			PK11err_add_data(PK11_F_RSA_SIGN, PK11_R_SIGN, rv);
6694+			goto err;
6695+			}
6696+		ret = 1;
6697+		}
6698+
6699+err:
6700+	if ((type != NID_md5_sha1) && (s != NULL))
6701+		{
6702+		(void) memset(s, 0, (unsigned int)(j + 1));
6703+		OPENSSL_free(s);
6704+		}
6705+
6706+	pk11_return_session(sp, OP_RSA);
6707+	return (ret);
6708+	}
6709+
6710+#if OPENSSL_VERSION_NUMBER < 0x10000000L
6711+static int pk11_RSA_verify(int type, const unsigned char *m,
6712+	unsigned int m_len, unsigned char *sigbuf, unsigned int siglen,
6713+	const RSA *rsa)
6714+#else
6715+static int pk11_RSA_verify(int type, const unsigned char *m,
6716+	unsigned int m_len, const unsigned char *sigbuf, unsigned int siglen,
6717+	const RSA *rsa)
6718+#endif
6719+	{
6720+	X509_SIG sig;
6721+	ASN1_TYPE parameter;
6722+	int i, j = 0;
6723+	unsigned char *p, *s = NULL;
6724+	X509_ALGOR algor;
6725+	ASN1_OCTET_STRING digest;
6726+	CK_RV rv;
6727+	CK_MECHANISM mech_rsa = {CKM_RSA_PKCS, NULL, 0};
6728+	CK_MECHANISM *p_mech = &mech_rsa;
6729+	CK_OBJECT_HANDLE h_pub_key;
6730+	PK11_SESSION *sp = NULL;
6731+	int ret = 0;
6732+
6733+	/* Encode the digest	*/
6734+	/* Special case: SSL signature, just check the length */
6735+	if (type == NID_md5_sha1)
6736+		{
6737+		if (m_len != SSL_SIG_LENGTH)
6738+			{
6739+			PK11err(PK11_F_RSA_VERIFY,
6740+				PK11_R_INVALID_MESSAGE_LENGTH);
6741+			goto err;
6742+			}
6743+		i = SSL_SIG_LENGTH;
6744+		s = (unsigned char *)m;
6745+		}
6746+	else
6747+		{
6748+		sig.algor = &algor;
6749+		sig.algor->algorithm = OBJ_nid2obj(type);
6750+		if (sig.algor->algorithm == NULL)
6751+			{
6752+			PK11err(PK11_F_RSA_VERIFY,
6753+				PK11_R_UNKNOWN_ALGORITHM_TYPE);
6754+			goto err;
6755+			}
6756+		if (sig.algor->algorithm->length == 0)
6757+			{
6758+			PK11err(PK11_F_RSA_VERIFY,
6759+				PK11_R_UNKNOWN_ASN1_OBJECT_ID);
6760+			goto err;
6761+			}
6762+		parameter.type = V_ASN1_NULL;
6763+		parameter.value.ptr = NULL;
6764+		sig.algor->parameter = &parameter;
6765+		sig.digest = &digest;
6766+		sig.digest->data = (unsigned char *)m;
6767+		sig.digest->length = m_len;
6768+		i = i2d_X509_SIG(&sig, NULL);
6769+		}
6770+
6771+	j = RSA_size(rsa);
6772+	if ((i - RSA_PKCS1_PADDING) > j)
6773+		{
6774+		PK11err(PK11_F_RSA_VERIFY, PK11_R_DIGEST_TOO_BIG);
6775+		goto err;
6776+		}
6777+
6778+	if (type != NID_md5_sha1)
6779+		{
6780+		s = (unsigned char *)OPENSSL_malloc((unsigned int)(j + 1));
6781+		if (s == NULL)
6782+			{
6783+			PK11err(PK11_F_RSA_VERIFY, PK11_R_MALLOC_FAILURE);
6784+			goto err;
6785+			}
6786+		p = s;
6787+		(void) i2d_X509_SIG(&sig, &p);
6788+		}
6789+
6790+	if ((sp = pk11_get_session(OP_RSA)) == NULL)
6791+		goto err;
6792+
6793+	(void) check_new_rsa_key_pub(sp, rsa);
6794+
6795+	h_pub_key = sp->opdata_rsa_pub_key;
6796+	if (h_pub_key == CK_INVALID_HANDLE)
6797+		h_pub_key = sp->opdata_rsa_pub_key =
6798+			pk11_get_public_rsa_key((RSA *)rsa, &sp->opdata_rsa_pub,
6799+			    &sp->opdata_rsa_n_num, &sp->opdata_rsa_e_num,
6800+			    sp->session);
6801+
6802+	if (h_pub_key != CK_INVALID_HANDLE)
6803+		{
6804+		rv = pFuncList->C_VerifyInit(sp->session, p_mech,
6805+			h_pub_key);
6806+
6807+		if (rv != CKR_OK)
6808+			{
6809+			PK11err_add_data(PK11_F_RSA_VERIFY, PK11_R_VERIFYINIT,
6810+			    rv);
6811+			goto err;
6812+			}
6813+		rv = pFuncList->C_Verify(sp->session, s, i,
6814+			(CK_BYTE_PTR)sigbuf, (CK_ULONG)siglen);
6815+
6816+		if (rv != CKR_OK)
6817+			{
6818+			PK11err_add_data(PK11_F_RSA_VERIFY, PK11_R_VERIFY, rv);
6819+			goto err;
6820+			}
6821+		ret = 1;
6822+		}
6823+
6824+err:
6825+	if ((type != NID_md5_sha1) && (s != NULL))
6826+		{
6827+		(void) memset(s, 0, (unsigned int)(j + 1));
6828+		OPENSSL_free(s);
6829+		}
6830+
6831+	pk11_return_session(sp, OP_RSA);
6832+	return (ret);
6833+	}
6834+
6835+static int hndidx_rsa = -1;
6836+
6837+#define	MAXATTR	1024
6838+
6839+/*
6840+ * Load RSA private key from a file or get its PKCS#11 handle if stored in the
6841+ * PKCS#11 token.
6842+ */
6843+/* ARGSUSED */
6844+EVP_PKEY *pk11_load_privkey(ENGINE *e, const char *privkey_file,
6845+	UI_METHOD *ui_method, void *callback_data)
6846+	{
6847+	EVP_PKEY *pkey = NULL;
6848+	FILE *privkey;
6849+	CK_OBJECT_HANDLE  h_priv_key = CK_INVALID_HANDLE;
6850+	RSA *rsa = NULL;
6851+	PK11_SESSION *sp;
6852+	/* Anything else below is needed for the key by reference extension. */
6853+	CK_RV rv;
6854+	CK_BBOOL is_token = TRUE;
6855+	CK_BBOOL rollback = FALSE;
6856+	CK_BYTE attr_data[2][MAXATTR];
6857+	CK_OBJECT_CLASS key_class = CKO_PRIVATE_KEY;
6858+	CK_OBJECT_HANDLE ks_key = CK_INVALID_HANDLE;	/* key in keystore */
6859+
6860+	/* we look for private keys only */
6861+	CK_ATTRIBUTE search_templ[] =
6862+		{
6863+		{CKA_TOKEN, &is_token, sizeof(is_token)},
6864+		{CKA_CLASS, &key_class, sizeof(key_class)},
6865+		{CKA_LABEL, NULL, 0}
6866+		};
6867+
6868+	/*
6869+	 * These public attributes are needed to initialize the OpenSSL RSA
6870+	 * structure with something we can use to look up the key. Note that we
6871+	 * never ask for private components.
6872+	 */
6873+	CK_ATTRIBUTE get_templ[] =
6874+		{
6875+		{CKA_MODULUS, (void *)attr_data[0], MAXATTR},		/* n */
6876+		{CKA_PUBLIC_EXPONENT, (void *)attr_data[1], MAXATTR},	/* e */
6877+		};
6878+
6879+	if ((sp = pk11_get_session(OP_RSA)) == NULL)
6880+		return (NULL);
6881+
6882+	/*
6883+	 * Use simple scheme "pkcs11:<KEY_LABEL>" for now.
6884+	 */
6885+	if (strstr(privkey_file, "pkcs11:") == privkey_file)
6886+		{
6887+		search_templ[2].pValue = strstr(privkey_file, ":") + 1;
6888+		search_templ[2].ulValueLen = strlen(search_templ[2].pValue);
6889+
6890+		if (pk11_token_login(sp->session, &pk11_login_done,
6891+		    CK_TRUE) == 0)
6892+			goto err;
6893+
6894+		/*
6895+		 * Now let's try to find the key in the token. It is a failure
6896+		 * if we can't find it.
6897+		 */
6898+		if (find_one_object(OP_RSA, sp->session, search_templ, 3,
6899+		    &ks_key) == 0)
6900+			goto err;
6901+
6902+		if (hndidx_rsa == -1)
6903+			hndidx_rsa = RSA_get_ex_new_index(0,
6904+				        "pkcs11 RSA HSM key handle",
6905+					NULL, NULL, NULL);
6906+
6907+		/*
6908+		 * We might have a cache hit which we could confirm
6909+		 * according to the 'n'/'e' params, RSA public pointer
6910+		 * as NULL, and non-NULL RSA private pointer. However,
6911+		 * it is easier just to recreate everything. We expect
6912+		 * the keys to be loaded once and used many times. We
6913+		 * do not check the return value because even in case
6914+		 * of failure the sp structure will have both key
6915+		 * pointer and object handle cleaned and
6916+		 * pk11_destroy_object() reports the failure to the
6917+		 * OpenSSL error message buffer.
6918+		 */
6919+		(void) pk11_destroy_rsa_object_priv(sp, TRUE);
6920+
6921+		sp->opdata_rsa_priv_key = ks_key;
6922+		/* This object shall not be deleted on a cache miss. */
6923+		sp->priv_persistent = CK_TRUE;
6924+
6925+		/*
6926+		 * Cache the RSA private structure pointer. We do not
6927+		 * use it now for key-by-ref keys but let's do it for
6928+		 * consistency reasons.
6929+		 */
6930+		if ((rsa = sp->opdata_rsa_priv = RSA_new_method(e)) == NULL)
6931+			goto err;
6932+
6933+		/*
6934+		 * Now we have to initialize an OpenSSL RSA structure,
6935+		 * everything else is 0 or NULL.
6936+		 */
6937+		rsa->flags = RSA_FLAG_SIGN_VER | RSA_FLAG_EXT_PKEY;
6938+		RSA_set_ex_data(rsa, hndidx_rsa, (void *) ks_key);
6939+
6940+		if ((rv = pFuncList->C_GetAttributeValue(sp->session, ks_key,
6941+		    get_templ, 2)) != CKR_OK)
6942+			{
6943+			PK11err_add_data(PK11_F_LOAD_PRIVKEY,
6944+					 PK11_R_GETATTRIBUTVALUE, rv);
6945+			goto err;
6946+			}
6947+
6948+		/*
6949+		 * We do not use pk11_get_private_rsa_key() here so we
6950+		 * must take care of handle management ourselves.
6951+		 */
6952+		KEY_HANDLE_REFHOLD(ks_key, OP_RSA, FALSE, rollback, err);
6953+
6954+		/*
6955+		 * Those are the sensitive components we do not want to export
6956+		 * from the token at all: rsa->(d|p|q|dmp1|dmq1|iqmp).
6957+		 */
6958+		attr_to_BN(&get_templ[0], attr_data[0], &rsa->n);
6959+		attr_to_BN(&get_templ[1], attr_data[1], &rsa->e);
6960+		/*
6961+		 * Must have 'n'/'e' components in the session structure as
6962+		 * well. They serve as a public look-up key for the private key
6963+		 * in the keystore.
6964+		 */
6965+		attr_to_BN(&get_templ[0], attr_data[0],
6966+			&sp->opdata_rsa_pn_num);
6967+		attr_to_BN(&get_templ[1], attr_data[1],
6968+			&sp->opdata_rsa_pe_num);
6969+
6970+		if ((pkey = EVP_PKEY_new()) == NULL)
6971+			goto err;
6972+
6973+		if (EVP_PKEY_assign_RSA(pkey, rsa) == 0)
6974+			goto err;
6975+		}
6976+	else if ((privkey = fopen(privkey_file, read_mode_flags)) != NULL)
6977+		{
6978+		pkey = PEM_read_PrivateKey(privkey, NULL, NULL, NULL);
6979+		(void) fclose(privkey);
6980+		if (pkey != NULL)
6981+			{
6982+			rsa = EVP_PKEY_get1_RSA(pkey);
6983+			if (rsa != NULL)
6984+				{
6985+				/*
6986+				 * This will always destroy the RSA
6987+				 * object since we have a new RSA
6988+				 * structure here.
6989+				 */
6990+				(void) check_new_rsa_key_priv(sp, rsa);
6991+				sp->priv_persistent = CK_FALSE;
6992+
6993+				h_priv_key = sp->opdata_rsa_priv_key =
6994+				    pk11_get_private_rsa_key(rsa,
6995+				    &sp->opdata_rsa_priv,
6996+				    &sp->opdata_rsa_d_num,
6997+				    &sp->opdata_rsa_pn_num,
6998+				    &sp->opdata_rsa_pe_num, sp->session);
6999+				if (h_priv_key == CK_INVALID_HANDLE)
7000+					goto err;
7001+				}
7002+			else
7003+				goto err;
7004+			}
7005+		}
7006+
7007+	pk11_return_session(sp, OP_RSA);
7008+	return (pkey);
7009+err:
7010+	pk11_return_session(sp, OP_RSA);
7011+	if (rsa != NULL)
7012+		RSA_free(rsa);
7013+	if (pkey != NULL)
7014+		{
7015+		EVP_PKEY_free(pkey);
7016+		pkey = NULL;
7017+		}
7018+	rollback = rollback;
7019+	return (pkey);
7020+	}
7021+
7022+/*
7023+ * Load RSA public key from a file or get its PKCS#11 handle if stored in the
7024+ * PKCS#11 token.
7025+ */
7026+/* ARGSUSED */
7027+EVP_PKEY *pk11_load_pubkey(ENGINE *e, const char *pubkey_file,
7028+	UI_METHOD *ui_method, void *callback_data)
7029+	{
7030+	EVP_PKEY *pkey = NULL;
7031+	FILE *pubkey;
7032+	CK_OBJECT_HANDLE h_pub_key = CK_INVALID_HANDLE;
7033+	RSA *rsa = NULL;
7034+	PK11_SESSION *sp;
7035+	/* Anything else below is needed for the key by reference extension. */
7036+	CK_RV rv;
7037+	CK_BBOOL is_token = TRUE;
7038+	CK_BYTE attr_data[2][MAXATTR];
7039+	CK_OBJECT_CLASS key_class = CKO_PUBLIC_KEY;
7040+	CK_OBJECT_HANDLE ks_key = CK_INVALID_HANDLE;	/* key in keystore */
7041+
7042+	/* we look for public keys only */
7043+	CK_ATTRIBUTE search_templ[] =
7044+		{
7045+		{CKA_TOKEN, &is_token, sizeof(is_token)},
7046+		{CKA_CLASS, &key_class, sizeof(key_class)},
7047+		{CKA_LABEL, NULL, 0}
7048+		};
7049+
7050+	/*
7051+	 * These public attributes are needed to initialize OpenSSL RSA
7052+	 * structure with something we can use to look up the key.
7053+	 */
7054+	CK_ATTRIBUTE get_templ[] =
7055+		{
7056+		{CKA_MODULUS, (void *)attr_data[0], MAXATTR},		/* n */
7057+		{CKA_PUBLIC_EXPONENT, (void *)attr_data[1], MAXATTR},	/* e */
7058+		};
7059+
7060+	if ((sp = pk11_get_session(OP_RSA)) == NULL)
7061+		return (NULL);
7062+
7063+	/*
7064+	 * Use simple scheme "pkcs11:<KEY_LABEL>" for now.
7065+	 */
7066+	if (strstr(pubkey_file, "pkcs11:") == pubkey_file)
7067+		{
7068+		search_templ[2].pValue = strstr(pubkey_file, ":") + 1;
7069+		search_templ[2].ulValueLen = strlen(search_templ[2].pValue);
7070+
7071+		if (pk11_token_login(sp->session, &pk11_login_done,
7072+		    CK_FALSE) == 0)
7073+			goto err;
7074+
7075+		/*
7076+		 * Now let's try to find the key in the token. It is a failure
7077+		 * if we can't find it.
7078+		 */
7079+		if (find_one_object(OP_RSA, sp->session, search_templ, 3,
7080+		    &ks_key) == 0)
7081+			goto err;
7082+
7083+		/*
7084+		 * We load a new public key so we will create a new RSA
7085+		 * structure. No cache hit is possible.
7086+		 */
7087+		(void) pk11_destroy_rsa_object_pub(sp, TRUE);
7088+
7089+		sp->opdata_rsa_pub_key = ks_key;
7090+		/* This object shall not be deleted on a cache miss. */
7091+		sp->pub_persistent = CK_TRUE;
7092+
7093+		/*
7094+		 * Cache the RSA public structure pointer.
7095+		 */
7096+		if ((rsa = sp->opdata_rsa_pub = RSA_new_method(e)) == NULL)
7097+			goto err;
7098+
7099+		/*
7100+		 * Now we have to initialize an OpenSSL RSA structure,
7101+		 * everything else is 0 or NULL.
7102+		 */
7103+		rsa->flags = RSA_FLAG_SIGN_VER;
7104+
7105+		if ((rv = pFuncList->C_GetAttributeValue(sp->session, ks_key,
7106+		    get_templ, 2)) != CKR_OK)
7107+			{
7108+			PK11err_add_data(PK11_F_LOAD_PUBKEY,
7109+					 PK11_R_GETATTRIBUTVALUE, rv);
7110+			goto err;
7111+			}
7112+
7113+		attr_to_BN(&get_templ[0], attr_data[0], &rsa->n);
7114+		attr_to_BN(&get_templ[1], attr_data[1], &rsa->e);
7115+
7116+		if ((pkey = EVP_PKEY_new()) == NULL)
7117+			goto err;
7118+
7119+		if (EVP_PKEY_assign_RSA(pkey, rsa) == 0)
7120+			goto err;
7121+
7122+		/*
7123+		 * Create a session object from it so that when calling
7124+		 * pk11_get_public_rsa_key() the next time, we can find it. The
7125+		 * reason why we do that is that we cannot tell from the RSA
7126+		 * structure (OpenSSL RSA structure does not have any room for
7127+		 * additional data used by the engine, for example) if it bears
7128+		 * a public key stored in the keystore or not so it's better if
7129+		 * we always have a session key. Note that this is different
7130+		 * from what we do for the private keystore objects but in that
7131+		 * case, we can tell from the RSA structure that the keystore
7132+		 * object is in play - the 'd' component is NULL in that case.
7133+		 */
7134+		h_pub_key = sp->opdata_rsa_pub_key =
7135+		    pk11_get_public_rsa_key(rsa,
7136+		    &sp->opdata_rsa_pub, &sp->opdata_rsa_n_num,
7137+		    &sp->opdata_rsa_e_num, sp->session);
7138+		if (h_pub_key == CK_INVALID_HANDLE)
7139+			goto err;
7140+		}
7141+	else if ((pubkey = fopen(pubkey_file, read_mode_flags)) != NULL)
7142+		{
7143+		pkey = PEM_read_PUBKEY(pubkey, NULL, NULL, NULL);
7144+		(void) fclose(pubkey);
7145+		if (pkey != NULL)
7146+			{
7147+			rsa = EVP_PKEY_get1_RSA(pkey);
7148+			if (rsa != NULL)
7149+				{
7150+				/*
7151+				 * This will always destroy the RSA
7152+				 * object since we have a new RSA
7153+				 * structure here.
7154+				 */
7155+				(void) check_new_rsa_key_pub(sp, rsa);
7156+				sp->pub_persistent = CK_FALSE;
7157+
7158+				h_pub_key = sp->opdata_rsa_pub_key =
7159+				    pk11_get_public_rsa_key(rsa,
7160+				    &sp->opdata_rsa_pub, &sp->opdata_rsa_n_num,
7161+				    &sp->opdata_rsa_e_num, sp->session);
7162+				if (h_pub_key == CK_INVALID_HANDLE)
7163+					goto err;
7164+				}
7165+			else
7166+				goto err;
7167+			}
7168+		}
7169+
7170+	pk11_return_session(sp, OP_RSA);
7171+	return (pkey);
7172+err:
7173+	pk11_return_session(sp, OP_RSA);
7174+	if (rsa != NULL)
7175+		RSA_free(rsa);
7176+	if (pkey != NULL)
7177+		{
7178+		EVP_PKEY_free(pkey);
7179+		pkey = NULL;
7180+		}
7181+	return (pkey);
7182+	}
7183+
7184+/*
7185+ * Create a public key object in a session from a given rsa structure.
7186+ * The *rsa_n_num and *rsa_e_num pointers are non-NULL for RSA public keys.
7187+ */
7188+static CK_OBJECT_HANDLE pk11_get_public_rsa_key(RSA *rsa,
7189+    RSA **key_ptr, BIGNUM **rsa_n_num, BIGNUM **rsa_e_num,
7190+    CK_SESSION_HANDLE session)
7191+	{
7192+	CK_RV rv;
7193+	CK_OBJECT_HANDLE h_key = CK_INVALID_HANDLE;
7194+	CK_ULONG found;
7195+	CK_OBJECT_CLASS o_key = CKO_PUBLIC_KEY;
7196+	CK_KEY_TYPE k_type = CKK_RSA;
7197+	CK_ULONG ul_key_attr_count = 8;
7198+	CK_BBOOL rollback = FALSE;
7199+
7200+	CK_ATTRIBUTE  a_key_template[] =
7201+		{
7202+		{CKA_CLASS, (void *) NULL, sizeof (CK_OBJECT_CLASS)},
7203+		{CKA_KEY_TYPE, (void *) NULL, sizeof (CK_KEY_TYPE)},
7204+		{CKA_TOKEN, &false, sizeof (true)},
7205+		{CKA_ENCRYPT, &true, sizeof (true)},
7206+		{CKA_VERIFY, &true, sizeof (true)},
7207+		{CKA_VERIFY_RECOVER, &true, sizeof (true)},
7208+		{CKA_MODULUS, (void *)NULL, 0},
7209+		{CKA_PUBLIC_EXPONENT, (void *)NULL, 0}
7210+		};
7211+
7212+	int i;
7213+
7214+	a_key_template[0].pValue = &o_key;
7215+	a_key_template[1].pValue = &k_type;
7216+
7217+	a_key_template[6].ulValueLen = BN_num_bytes(rsa->n);
7218+	a_key_template[6].pValue = (CK_VOID_PTR)OPENSSL_malloc(
7219+		(size_t)a_key_template[6].ulValueLen);
7220+	if (a_key_template[6].pValue == NULL)
7221+		{
7222+		PK11err(PK11_F_GET_PUB_RSA_KEY, PK11_R_MALLOC_FAILURE);
7223+		goto malloc_err;
7224+		}
7225+
7226+	BN_bn2bin(rsa->n, a_key_template[6].pValue);
7227+
7228+	a_key_template[7].ulValueLen = BN_num_bytes(rsa->e);
7229+	a_key_template[7].pValue = (CK_VOID_PTR)OPENSSL_malloc(
7230+		(size_t)a_key_template[7].ulValueLen);
7231+	if (a_key_template[7].pValue == NULL)
7232+		{
7233+		PK11err(PK11_F_GET_PUB_RSA_KEY, PK11_R_MALLOC_FAILURE);
7234+		goto malloc_err;
7235+		}
7236+
7237+	BN_bn2bin(rsa->e, a_key_template[7].pValue);
7238+
7239+	/* see find_lock array definition for more info on object locking */
7240+	LOCK_OBJSTORE(OP_RSA);
7241+
7242+	rv = pFuncList->C_FindObjectsInit(session, a_key_template,
7243+		ul_key_attr_count);
7244+
7245+	if (rv != CKR_OK)
7246+		{
7247+		PK11err_add_data(PK11_F_GET_PUB_RSA_KEY,
7248+		    PK11_R_FINDOBJECTSINIT, rv);
7249+		goto err;
7250+		}
7251+
7252+	rv = pFuncList->C_FindObjects(session, &h_key, 1, &found);
7253+
7254+	if (rv != CKR_OK)
7255+		{
7256+		PK11err_add_data(PK11_F_GET_PUB_RSA_KEY,
7257+		    PK11_R_FINDOBJECTS, rv);
7258+		goto err;
7259+		}
7260+
7261+	rv = pFuncList->C_FindObjectsFinal(session);
7262+
7263+	if (rv != CKR_OK)
7264+		{
7265+		PK11err_add_data(PK11_F_GET_PUB_RSA_KEY,
7266+		    PK11_R_FINDOBJECTSFINAL, rv);
7267+		goto err;
7268+		}
7269+
7270+	if (found == 0)
7271+		{
7272+		rv = pFuncList->C_CreateObject(session,
7273+			a_key_template, ul_key_attr_count, &h_key);
7274+		if (rv != CKR_OK)
7275+			{
7276+			PK11err_add_data(PK11_F_GET_PUB_RSA_KEY,
7277+			    PK11_R_CREATEOBJECT, rv);
7278+			goto err;
7279+			}
7280+		}
7281+
7282+	if (rsa_n_num != NULL)
7283+		if ((*rsa_n_num = BN_dup(rsa->n)) == NULL)
7284+			{
7285+			PK11err(PK11_F_GET_PUB_RSA_KEY, PK11_R_MALLOC_FAILURE);
7286+			rollback = TRUE;
7287+			goto err;
7288+			}
7289+	if (rsa_e_num != NULL)
7290+		if ((*rsa_e_num = BN_dup(rsa->e)) == NULL)
7291+			{
7292+			PK11err(PK11_F_GET_PUB_RSA_KEY, PK11_R_MALLOC_FAILURE);
7293+			BN_free(*rsa_n_num);
7294+			*rsa_n_num = NULL;
7295+			rollback = TRUE;
7296+			goto err;
7297+			}
7298+
7299+	/* LINTED: E_CONSTANT_CONDITION */
7300+	KEY_HANDLE_REFHOLD(h_key, OP_RSA, FALSE, rollback, err);
7301+	if (key_ptr != NULL)
7302+		*key_ptr = rsa;
7303+
7304+err:
7305+	if (rollback)
7306+		{
7307+		/*
7308+		 * We do not care about the return value from C_DestroyObject()
7309+		 * since we are doing rollback.
7310+		 */
7311+		if (found == 0)
7312+			(void) pFuncList->C_DestroyObject(session, h_key);
7313+		h_key = CK_INVALID_HANDLE;
7314+		}
7315+
7316+	UNLOCK_OBJSTORE(OP_RSA);
7317+
7318+malloc_err:
7319+	for (i = 6; i <= 7; i++)
7320+		{
7321+		if (a_key_template[i].pValue != NULL)
7322+			{
7323+			OPENSSL_free(a_key_template[i].pValue);
7324+			a_key_template[i].pValue = NULL;
7325+			}
7326+		}
7327+
7328+	return (h_key);
7329+	}
7330+
7331+/*
7332+ * Create a private key object in the session from a given rsa structure.
7333+ * The *rsa_d_num pointer is non-NULL for RSA private keys.
7334+ */
7335+static CK_OBJECT_HANDLE
7336+pk11_get_private_rsa_key(RSA *rsa, RSA **key_ptr, BIGNUM **rsa_d_num,
7337+    BIGNUM **rsa_n_num, BIGNUM **rsa_e_num, CK_SESSION_HANDLE session)
7338+	{
7339+	CK_RV rv;
7340+	CK_OBJECT_HANDLE h_key = CK_INVALID_HANDLE;
7341+	int i;
7342+	CK_ULONG found;
7343+	CK_OBJECT_CLASS o_key = CKO_PRIVATE_KEY;
7344+	CK_KEY_TYPE k_type = CKK_RSA;
7345+	CK_ULONG ul_key_attr_count = 14;
7346+	CK_BBOOL rollback = FALSE;
7347+
7348+	/* Both CKA_TOKEN and CKA_SENSITIVE have to be FALSE for session keys */
7349+	CK_ATTRIBUTE  a_key_template[] =
7350+		{
7351+		{CKA_CLASS, (void *) NULL, sizeof (CK_OBJECT_CLASS)},
7352+		{CKA_KEY_TYPE, (void *) NULL, sizeof (CK_KEY_TYPE)},
7353+		{CKA_TOKEN, &false, sizeof (true)},
7354+		{CKA_SENSITIVE, &false, sizeof (true)},
7355+		{CKA_DECRYPT, &true, sizeof (true)},
7356+		{CKA_SIGN, &true, sizeof (true)},
7357+		{CKA_MODULUS, (void *)NULL, 0},
7358+		{CKA_PUBLIC_EXPONENT, (void *)NULL, 0},
7359+		{CKA_PRIVATE_EXPONENT, (void *)NULL, 0},
7360+		{CKA_PRIME_1, (void *)NULL, 0},
7361+		{CKA_PRIME_2, (void *)NULL, 0},
7362+		{CKA_EXPONENT_1, (void *)NULL, 0},
7363+		{CKA_EXPONENT_2, (void *)NULL, 0},
7364+		{CKA_COEFFICIENT, (void *)NULL, 0},
7365+		};
7366+
7367+	if ((rsa->flags & RSA_FLAG_EXT_PKEY) != 0) {
7368+		h_key = (CK_OBJECT_HANDLE)RSA_get_ex_data(rsa, hndidx_rsa);
7369+		LOCK_OBJSTORE(OP_RSA);
7370+		goto set;
7371+	}
7372+	
7373+	a_key_template[0].pValue = &o_key;
7374+	a_key_template[1].pValue = &k_type;
7375+
7376+	/* Put the private key components into the template */
7377+	if (init_template_value(rsa->n, &a_key_template[6].pValue,
7378+		&a_key_template[6].ulValueLen) == 0 ||
7379+	    init_template_value(rsa->e, &a_key_template[7].pValue,
7380+		&a_key_template[7].ulValueLen) == 0 ||
7381+	    init_template_value(rsa->d, &a_key_template[8].pValue,
7382+		&a_key_template[8].ulValueLen) == 0 ||
7383+	    init_template_value(rsa->p, &a_key_template[9].pValue,
7384+		&a_key_template[9].ulValueLen) == 0 ||
7385+	    init_template_value(rsa->q, &a_key_template[10].pValue,
7386+		&a_key_template[10].ulValueLen) == 0 ||
7387+	    init_template_value(rsa->dmp1, &a_key_template[11].pValue,
7388+		&a_key_template[11].ulValueLen) == 0 ||
7389+	    init_template_value(rsa->dmq1, &a_key_template[12].pValue,
7390+		&a_key_template[12].ulValueLen) == 0 ||
7391+	    init_template_value(rsa->iqmp, &a_key_template[13].pValue,
7392+		&a_key_template[13].ulValueLen) == 0)
7393+		{
7394+		PK11err(PK11_F_GET_PRIV_RSA_KEY, PK11_R_MALLOC_FAILURE);
7395+		goto malloc_err;
7396+		}
7397+
7398+	/* see find_lock array definition for more info on object locking */
7399+	LOCK_OBJSTORE(OP_RSA);
7400+
7401+	/*
7402+	 * We are getting the private key but the private 'd'
7403+	 * component is NULL.  That means this is key by reference RSA
7404+	 * key. In that case, we can use only public components for
7405+	 * searching for the private key handle.
7406+	 */
7407+	if (rsa->d == NULL)
7408+		{
7409+		ul_key_attr_count = 8;
7410+		/*
7411+		 * We will perform the search in the token, not in the existing
7412+		 * session keys.
7413+		 */
7414+		a_key_template[2].pValue = &true;
7415+		}
7416+
7417+	rv = pFuncList->C_FindObjectsInit(session, a_key_template,
7418+		ul_key_attr_count);
7419+
7420+	if (rv != CKR_OK)
7421+		{
7422+		PK11err_add_data(PK11_F_GET_PRIV_RSA_KEY,
7423+		    PK11_R_FINDOBJECTSINIT, rv);
7424+		goto err;
7425+		}
7426+
7427+	rv = pFuncList->C_FindObjects(session, &h_key, 1, &found);
7428+
7429+	if (rv != CKR_OK)
7430+		{
7431+		PK11err_add_data(PK11_F_GET_PRIV_RSA_KEY,
7432+		    PK11_R_FINDOBJECTS, rv);
7433+		goto err;
7434+		}
7435+
7436+	rv = pFuncList->C_FindObjectsFinal(session);
7437+
7438+	if (rv != CKR_OK)
7439+		{
7440+		PK11err_add_data(PK11_F_GET_PRIV_RSA_KEY,
7441+		    PK11_R_FINDOBJECTSFINAL, rv);
7442+		goto err;
7443+		}
7444+
7445+	if (found == 0)
7446+		{
7447+		/*
7448+		 * We have an RSA structure with 'n'/'e' components
7449+		 * only so we tried to find the private key in the
7450+		 * keystore. If it was really a token key we have a
7451+		 * problem. Note that for other key types we just
7452+		 * create a new session key using the private
7453+		 * components from the RSA structure.
7454+		 */
7455+		if (rsa->d == NULL)
7456+			{
7457+			PK11err(PK11_F_GET_PRIV_RSA_KEY,
7458+			    PK11_R_PRIV_KEY_NOT_FOUND);
7459+			goto err;
7460+			}
7461+
7462+		rv = pFuncList->C_CreateObject(session,
7463+			a_key_template, ul_key_attr_count, &h_key);
7464+		if (rv != CKR_OK)
7465+			{
7466+			PK11err_add_data(PK11_F_GET_PRIV_RSA_KEY,
7467+				PK11_R_CREATEOBJECT, rv);
7468+			goto err;
7469+			}
7470+		}
7471+
7472+set:
7473+	if (rsa_d_num != NULL)
7474+		{
7475+		/*
7476+		 * When RSA keys by reference code is used, we never
7477+		 * extract private components from the keystore. In
7478+		 * that case 'd' was set to NULL and we expect the
7479+		 * application to properly cope with that. It is
7480+		 * documented in openssl(5). In general, if keys by
7481+		 * reference are used we expect it to be used
7482+		 * exclusively using the high level API and then there
7483+		 * is no problem. If the application expects the
7484+		 * private components to be read from the keystore
7485+		 * then that is not a supported way of usage.
7486+		 */
7487+		if (rsa->d != NULL && (*rsa_d_num = BN_dup(rsa->d)) == NULL)
7488+			{
7489+			PK11err(PK11_F_GET_PRIV_RSA_KEY, PK11_R_MALLOC_FAILURE);
7490+			rollback = TRUE;
7491+			goto err;
7492+			}
7493+		else
7494+			*rsa_d_num = NULL;
7495+		}
7496+
7497+	/*
7498+	 * For the key by reference code, we need public components as well
7499+	 * since 'd' component is always NULL. For that reason, we always cache
7500+	 * 'n'/'e' components as well.
7501+	 */
7502+	*rsa_n_num = BN_dup(rsa->n);
7503+	*rsa_e_num = BN_dup(rsa->e);
7504+
7505+	/* LINTED: E_CONSTANT_CONDITION */
7506+	KEY_HANDLE_REFHOLD(h_key, OP_RSA, FALSE, rollback, err);
7507+	if (key_ptr != NULL)
7508+		*key_ptr = rsa;
7509+
7510+err:
7511+	if (rollback)
7512+		{
7513+		/*
7514+		 * We do not care about the return value from C_DestroyObject()
7515+		 * since we are doing rollback.
7516+		 */
7517+		if (found == 0 &&
7518+		    (rsa->flags & RSA_FLAG_EXT_PKEY) == 0)
7519+			(void) pFuncList->C_DestroyObject(session, h_key);
7520+		h_key = CK_INVALID_HANDLE;
7521+		}
7522+
7523+	UNLOCK_OBJSTORE(OP_RSA);
7524+
7525+malloc_err:
7526+	/*
7527+	 * 6 to 13 entries in the key template are key components.
7528+	 * They need to be freed upon exit or error.
7529+	 */
7530+	for (i = 6; i <= 13; i++)
7531+		{
7532+		if (a_key_template[i].pValue != NULL)
7533+			{
7534+			(void) memset(a_key_template[i].pValue, 0,
7535+				a_key_template[i].ulValueLen);
7536+			OPENSSL_free(a_key_template[i].pValue);
7537+			a_key_template[i].pValue = NULL;
7538+			}
7539+		}
7540+
7541+	return (h_key);
7542+	}
7543+
7544+/*
7545+ * Check for cache miss and clean the object pointer and handle
7546+ * in such case. Return 1 for cache hit, 0 for cache miss.
7547+ */
7548+static int check_new_rsa_key_pub(PK11_SESSION *sp, const RSA *rsa)
7549+	{
7550+	/*
7551+	 * Provide protection against RSA structure reuse by making the
7552+	 * check for cache hit stronger. Only public components of RSA
7553+	 * key matter here so it is sufficient to compare them with values
7554+	 * cached in PK11_SESSION structure.
7555+	 *
7556+	 * We must check the handle as well since with key by reference, public
7557+	 * components 'n'/'e' are cached in private keys as well. That means we
7558+	 * could have a cache hit in a private key when looking for a public
7559+	 * key. That would not work, you cannot have one PKCS#11 object for
7560+	 * both data signing and verifying.
7561+	 */
7562+	if ((sp->opdata_rsa_pub != rsa) ||
7563+	    (BN_cmp(sp->opdata_rsa_n_num, rsa->n) != 0) ||
7564+	    (BN_cmp(sp->opdata_rsa_e_num, rsa->e) != 0) ||
7565+	    (sp->opdata_rsa_priv_key != CK_INVALID_HANDLE))
7566+		{
7567+		/*
7568+		 * We do not check the return value because even in case of
7569+		 * failure the sp structure will have both key pointer
7570+		 * and object handle cleaned and pk11_destroy_object()
7571+		 * reports the failure to the OpenSSL error message buffer.
7572+		 */
7573+		(void) pk11_destroy_rsa_object_pub(sp, TRUE);
7574+		return (0);
7575+		}
7576+	return (1);
7577+	}
7578+
7579+/*
7580+ * Check for cache miss and clean the object pointer and handle
7581+ * in such case. Return 1 for cache hit, 0 for cache miss.
7582+ */
7583+static int check_new_rsa_key_priv(PK11_SESSION *sp, const RSA *rsa)
7584+	{
7585+	/*
7586+	 * Provide protection against RSA structure reuse by making
7587+	 * the check for cache hit stronger. Comparing public exponent
7588+	 * of RSA key with value cached in PK11_SESSION structure
7589+	 * should be sufficient. Note that we want to compare the
7590+	 * public component since with the keys by reference
7591+	 * mechanism, private components are not in the RSA
7592+	 * structure. Also, see check_new_rsa_key_pub() about why we
7593+	 * compare the handle as well.
7594+	 */
7595+	if ((sp->opdata_rsa_priv != rsa) ||
7596+	    (BN_cmp(sp->opdata_rsa_pn_num, rsa->n) != 0) ||
7597+	    (BN_cmp(sp->opdata_rsa_pe_num, rsa->e) != 0) ||
7598+	    (sp->opdata_rsa_pn_num == NULL) ||
7599+	    (sp->opdata_rsa_pe_num == NULL) ||
7600+	    (sp->opdata_rsa_pub_key != CK_INVALID_HANDLE))
7601+		{
7602+		/*
7603+		 * We do not check the return value because even in case of
7604+		 * failure the sp structure will have both key pointer
7605+		 * and object handle cleaned and pk11_destroy_object()
7606+		 * reports the failure to the OpenSSL error message buffer.
7607+		 */
7608+		(void) pk11_destroy_rsa_object_priv(sp, TRUE);
7609+		return (0);
7610+		}
7611+	return (1);
7612+	}
7613+#endif
7614+
7615+#ifndef OPENSSL_NO_DSA
7616+/* The DSA function implementation */
7617+/* ARGSUSED */
7618+static int pk11_DSA_init(DSA *dsa)
7619+	{
7620+	return (1);
7621+	}
7622+
7623+/* ARGSUSED */
7624+static int pk11_DSA_finish(DSA *dsa)
7625+	{
7626+	return (1);
7627+	}
7628+
7629+
7630+static DSA_SIG *
7631+pk11_dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa)
7632+	{
7633+	BIGNUM *r = NULL, *s = NULL;
7634+	int i;
7635+	DSA_SIG *dsa_sig = NULL;
7636+
7637+	CK_RV rv;
7638+	CK_MECHANISM Mechanism_dsa = {CKM_DSA, NULL, 0};
7639+	CK_MECHANISM *p_mech = &Mechanism_dsa;
7640+	CK_OBJECT_HANDLE h_priv_key;
7641+
7642+	/*
7643+	 * The signature is the concatenation of r and s,
7644+	 * each is 20 bytes long
7645+	 */
7646+	unsigned char sigret[DSA_SIGNATURE_LEN];
7647+	unsigned long siglen = DSA_SIGNATURE_LEN;
7648+	unsigned int siglen2 = DSA_SIGNATURE_LEN / 2;
7649+
7650+	PK11_SESSION *sp = NULL;
7651+
7652+	if ((dsa->p == NULL) || (dsa->q == NULL) || (dsa->g == NULL))
7653+		{
7654+		PK11err(PK11_F_DSA_SIGN, PK11_R_MISSING_KEY_COMPONENT);
7655+		goto ret;
7656+		}
7657+
7658+	i = BN_num_bytes(dsa->q); /* should be 20 */
7659+	if (dlen > i)
7660+		{
7661+		PK11err(PK11_F_DSA_SIGN, PK11_R_INVALID_SIGNATURE_LENGTH);
7662+		goto ret;
7663+		}
7664+
7665+	if ((sp = pk11_get_session(OP_DSA)) == NULL)
7666+		goto ret;
7667+
7668+	(void) check_new_dsa_key_priv(sp, dsa);
7669+
7670+	h_priv_key = sp->opdata_dsa_priv_key;
7671+	if (h_priv_key == CK_INVALID_HANDLE)
7672+		h_priv_key = sp->opdata_dsa_priv_key =
7673+			pk11_get_private_dsa_key((DSA *)dsa,
7674+			    &sp->opdata_dsa_priv,
7675+			    &sp->opdata_dsa_priv_num, sp->session);
7676+
7677+	if (h_priv_key != CK_INVALID_HANDLE)
7678+		{
7679+		rv = pFuncList->C_SignInit(sp->session, p_mech, h_priv_key);
7680+
7681+		if (rv != CKR_OK)
7682+			{
7683+			PK11err_add_data(PK11_F_DSA_SIGN, PK11_R_SIGNINIT, rv);
7684+			goto ret;
7685+			}
7686+
7687+		(void) memset(sigret, 0, siglen);
7688+		rv = pFuncList->C_Sign(sp->session,
7689+			(unsigned char*) dgst, dlen, sigret,
7690+			(CK_ULONG_PTR) &siglen);
7691+
7692+		if (rv != CKR_OK)
7693+			{
7694+			PK11err_add_data(PK11_F_DSA_SIGN, PK11_R_SIGN, rv);
7695+			goto ret;
7696+			}
7697+		}
7698+
7699+
7700+	if ((s = BN_new()) == NULL)
7701+		{
7702+		PK11err(PK11_F_DSA_SIGN, PK11_R_MALLOC_FAILURE);
7703+		goto ret;
7704+		}
7705+
7706+	if ((r = BN_new()) == NULL)
7707+		{
7708+		PK11err(PK11_F_DSA_SIGN, PK11_R_MALLOC_FAILURE);
7709+		goto ret;
7710+		}
7711+
7712+	if ((dsa_sig = DSA_SIG_new()) == NULL)
7713+		{
7714+		PK11err(PK11_F_DSA_SIGN, PK11_R_MALLOC_FAILURE);
7715+		goto ret;
7716+		}
7717+
7718+	if (BN_bin2bn(sigret, siglen2, r) == NULL ||
7719+	    BN_bin2bn(&sigret[siglen2], siglen2, s) == NULL)
7720+		{
7721+		PK11err(PK11_F_DSA_SIGN, PK11_R_MALLOC_FAILURE);
7722+		goto ret;
7723+		}
7724+
7725+	dsa_sig->r = r;
7726+	dsa_sig->s = s;
7727+
7728+ret:
7729+	if (dsa_sig == NULL)
7730+		{
7731+		if (r != NULL)
7732+			BN_free(r);
7733+		if (s != NULL)
7734+			BN_free(s);
7735+		}
7736+
7737+	pk11_return_session(sp, OP_DSA);
7738+	return (dsa_sig);
7739+	}
7740+
7741+static int
7742+pk11_dsa_do_verify(const unsigned char *dgst, int dlen, DSA_SIG *sig,
7743+	DSA *dsa)
7744+	{
7745+	int i;
7746+	CK_RV rv;
7747+	int retval = 0;
7748+	CK_MECHANISM Mechanism_dsa = {CKM_DSA, NULL, 0};
7749+	CK_MECHANISM *p_mech = &Mechanism_dsa;
7750+	CK_OBJECT_HANDLE h_pub_key;
7751+
7752+	unsigned char sigbuf[DSA_SIGNATURE_LEN];
7753+	unsigned long siglen = DSA_SIGNATURE_LEN;
7754+	unsigned long siglen2 = DSA_SIGNATURE_LEN/2;
7755+
7756+	PK11_SESSION *sp = NULL;
7757+
7758+	if (BN_is_zero(sig->r) || sig->r->neg || BN_ucmp(sig->r, dsa->q) >= 0)
7759+		{
7760+		PK11err(PK11_F_DSA_VERIFY,
7761+			PK11_R_INVALID_DSA_SIGNATURE_R);
7762+		goto ret;
7763+		}
7764+
7765+	if (BN_is_zero(sig->s) || sig->s->neg || BN_ucmp(sig->s, dsa->q) >= 0)
7766+		{
7767+		PK11err(PK11_F_DSA_VERIFY,
7768+			PK11_R_INVALID_DSA_SIGNATURE_S);
7769+		goto ret;
7770+		}
7771+
7772+	i = BN_num_bytes(dsa->q); /* should be 20 */
7773+
7774+	if (dlen > i)
7775+		{
7776+		PK11err(PK11_F_DSA_VERIFY,
7777+			PK11_R_INVALID_SIGNATURE_LENGTH);
7778+		goto ret;
7779+		}
7780+
7781+	if ((sp = pk11_get_session(OP_DSA)) == NULL)
7782+		goto ret;
7783+
7784+	(void) check_new_dsa_key_pub(sp, dsa);
7785+
7786+	h_pub_key = sp->opdata_dsa_pub_key;
7787+	if (h_pub_key == CK_INVALID_HANDLE)
7788+		h_pub_key = sp->opdata_dsa_pub_key =
7789+			pk11_get_public_dsa_key((DSA *)dsa, &sp->opdata_dsa_pub,
7790+			    &sp->opdata_dsa_pub_num, sp->session);
7791+
7792+	if (h_pub_key != CK_INVALID_HANDLE)
7793+		{
7794+		rv = pFuncList->C_VerifyInit(sp->session, p_mech,
7795+			h_pub_key);
7796+
7797+		if (rv != CKR_OK)
7798+			{
7799+			PK11err_add_data(PK11_F_DSA_VERIFY, PK11_R_VERIFYINIT,
7800+			    rv);
7801+			goto ret;
7802+			}
7803+
7804+		/*
7805+		 * The representation of each of the two big numbers could
7806+		 * be shorter than DSA_SIGNATURE_LEN/2 bytes so we need
7807+		 * to act accordingly and shift if necessary.
7808+		 */
7809+		(void) memset(sigbuf, 0, siglen);
7810+		BN_bn2bin(sig->r, sigbuf + siglen2 - BN_num_bytes(sig->r));
7811+		BN_bn2bin(sig->s, &sigbuf[siglen2] + siglen2 -
7812+		    BN_num_bytes(sig->s));
7813+
7814+		rv = pFuncList->C_Verify(sp->session,
7815+			(unsigned char *) dgst, dlen, sigbuf, (CK_ULONG)siglen);
7816+
7817+		if (rv != CKR_OK)
7818+			{
7819+			PK11err_add_data(PK11_F_DSA_VERIFY, PK11_R_VERIFY, rv);
7820+			goto ret;
7821+			}
7822+		}
7823+
7824+	retval = 1;
7825+ret:
7826+
7827+	pk11_return_session(sp, OP_DSA);
7828+	return (retval);
7829+	}
7830+
7831+
7832+/*
7833+ * Create a public key object in a session from a given dsa structure.
7834+ * The *dsa_pub_num pointer is non-NULL for DSA public keys.
7835+ */
7836+static CK_OBJECT_HANDLE pk11_get_public_dsa_key(DSA* dsa,
7837+    DSA **key_ptr, BIGNUM **dsa_pub_num, CK_SESSION_HANDLE session)
7838+	{
7839+	CK_RV rv;
7840+	CK_OBJECT_CLASS o_key = CKO_PUBLIC_KEY;
7841+	CK_OBJECT_HANDLE h_key = CK_INVALID_HANDLE;
7842+	CK_ULONG found;
7843+	CK_KEY_TYPE k_type = CKK_DSA;
7844+	CK_ULONG ul_key_attr_count = 8;
7845+	CK_BBOOL rollback = FALSE;
7846+	int i;
7847+
7848+	CK_ATTRIBUTE  a_key_template[] =
7849+		{
7850+		{CKA_CLASS, (void *) NULL, sizeof (CK_OBJECT_CLASS)},
7851+		{CKA_KEY_TYPE, (void *) NULL, sizeof (CK_KEY_TYPE)},
7852+		{CKA_TOKEN, &false, sizeof (true)},
7853+		{CKA_VERIFY, &true, sizeof (true)},
7854+		{CKA_PRIME, (void *)NULL, 0},		/* p */
7855+		{CKA_SUBPRIME, (void *)NULL, 0},	/* q */
7856+		{CKA_BASE, (void *)NULL, 0},		/* g */
7857+		{CKA_VALUE, (void *)NULL, 0}		/* pub_key - y */
7858+		};
7859+
7860+	a_key_template[0].pValue = &o_key;
7861+	a_key_template[1].pValue = &k_type;
7862+
7863+	if (init_template_value(dsa->p, &a_key_template[4].pValue,
7864+		&a_key_template[4].ulValueLen) == 0 ||
7865+	    init_template_value(dsa->q, &a_key_template[5].pValue,
7866+		&a_key_template[5].ulValueLen) == 0 ||
7867+	    init_template_value(dsa->g, &a_key_template[6].pValue,
7868+		&a_key_template[6].ulValueLen) == 0 ||
7869+	    init_template_value(dsa->pub_key, &a_key_template[7].pValue,
7870+		&a_key_template[7].ulValueLen) == 0)
7871+		{
7872+		PK11err(PK11_F_GET_PUB_DSA_KEY, PK11_R_MALLOC_FAILURE);
7873+		goto malloc_err;
7874+		}
7875+
7876+	/* see find_lock array definition for more info on object locking */
7877+	LOCK_OBJSTORE(OP_DSA);
7878+	rv = pFuncList->C_FindObjectsInit(session, a_key_template,
7879+		ul_key_attr_count);
7880+
7881+	if (rv != CKR_OK)
7882+		{
7883+		PK11err_add_data(PK11_F_GET_PUB_DSA_KEY,
7884+		    PK11_R_FINDOBJECTSINIT, rv);
7885+		goto err;
7886+		}
7887+
7888+	rv = pFuncList->C_FindObjects(session, &h_key, 1, &found);
7889+
7890+	if (rv != CKR_OK)
7891+		{
7892+		PK11err_add_data(PK11_F_GET_PUB_DSA_KEY,
7893+		    PK11_R_FINDOBJECTS, rv);
7894+		goto err;
7895+		}
7896+
7897+	rv = pFuncList->C_FindObjectsFinal(session);
7898+
7899+	if (rv != CKR_OK)
7900+		{
7901+		PK11err_add_data(PK11_F_GET_PUB_DSA_KEY,
7902+		    PK11_R_FINDOBJECTSFINAL, rv);
7903+		goto err;
7904+		}
7905+
7906+	if (found == 0)
7907+		{
7908+		rv = pFuncList->C_CreateObject(session,
7909+			a_key_template, ul_key_attr_count, &h_key);
7910+		if (rv != CKR_OK)
7911+			{
7912+			PK11err_add_data(PK11_F_GET_PUB_DSA_KEY,
7913+			    PK11_R_CREATEOBJECT, rv);
7914+			goto err;
7915+			}
7916+		}
7917+
7918+	if (dsa_pub_num != NULL)
7919+		if ((*dsa_pub_num = BN_dup(dsa->pub_key)) == NULL)
7920+			{
7921+			PK11err(PK11_F_GET_PUB_DSA_KEY, PK11_R_MALLOC_FAILURE);
7922+			rollback = TRUE;
7923+			goto err;
7924+			}
7925+
7926+	/* LINTED: E_CONSTANT_CONDITION */
7927+	KEY_HANDLE_REFHOLD(h_key, OP_DSA, FALSE, rollback, err);
7928+	if (key_ptr != NULL)
7929+		*key_ptr = dsa;
7930+
7931+err:
7932+	if (rollback)
7933+		{
7934+		/*
7935+		 * We do not care about the return value from C_DestroyObject()
7936+		 * since we are doing rollback.
7937+		 */
7938+		if (found == 0)
7939+			(void) pFuncList->C_DestroyObject(session, h_key);
7940+		h_key = CK_INVALID_HANDLE;
7941+		}
7942+
7943+	UNLOCK_OBJSTORE(OP_DSA);
7944+
7945+malloc_err:
7946+	for (i = 4; i <= 7; i++)
7947+		{
7948+		if (a_key_template[i].pValue != NULL)
7949+			{
7950+			OPENSSL_free(a_key_template[i].pValue);
7951+			a_key_template[i].pValue = NULL;
7952+			}
7953+		}
7954+
7955+	return (h_key);
7956+	}
7957+
7958+/*
7959+ * Create a private key object in the session from a given dsa structure
7960+ * The *dsa_priv_num pointer is non-NULL for DSA private keys.
7961+ */
7962+static CK_OBJECT_HANDLE pk11_get_private_dsa_key(DSA* dsa,
7963+    DSA **key_ptr, BIGNUM **dsa_priv_num, CK_SESSION_HANDLE session)
7964+	{
7965+	CK_RV rv;
7966+	CK_OBJECT_HANDLE h_key = CK_INVALID_HANDLE;
7967+	CK_OBJECT_CLASS o_key = CKO_PRIVATE_KEY;
7968+	int i;
7969+	CK_ULONG found;
7970+	CK_KEY_TYPE k_type = CKK_DSA;
7971+	CK_ULONG ul_key_attr_count = 9;
7972+	CK_BBOOL rollback = FALSE;
7973+
7974+	/* Both CKA_TOKEN and CKA_SENSITIVE have to be FALSE for session keys */
7975+	CK_ATTRIBUTE  a_key_template[] =
7976+		{
7977+		{CKA_CLASS, (void *) NULL, sizeof (CK_OBJECT_CLASS)},
7978+		{CKA_KEY_TYPE, (void *) NULL, sizeof (CK_KEY_TYPE)},
7979+		{CKA_TOKEN, &false, sizeof (true)},
7980+		{CKA_SENSITIVE, &false, sizeof (true)},
7981+		{CKA_SIGN, &true, sizeof (true)},
7982+		{CKA_PRIME, (void *)NULL, 0},		/* p */
7983+		{CKA_SUBPRIME, (void *)NULL, 0},	/* q */
7984+		{CKA_BASE, (void *)NULL, 0},		/* g */
7985+		{CKA_VALUE, (void *)NULL, 0}		/* priv_key - x */
7986+		};
7987+
7988+	a_key_template[0].pValue = &o_key;
7989+	a_key_template[1].pValue = &k_type;
7990+
7991+	/* Put the private key components into the template */
7992+	if (init_template_value(dsa->p, &a_key_template[5].pValue,
7993+		&a_key_template[5].ulValueLen) == 0 ||
7994+	    init_template_value(dsa->q, &a_key_template[6].pValue,
7995+		&a_key_template[6].ulValueLen) == 0 ||
7996+	    init_template_value(dsa->g, &a_key_template[7].pValue,
7997+		&a_key_template[7].ulValueLen) == 0 ||
7998+	    init_template_value(dsa->priv_key, &a_key_template[8].pValue,
7999+		&a_key_template[8].ulValueLen) == 0)
8000+		{
8001+		PK11err(PK11_F_GET_PRIV_DSA_KEY, PK11_R_MALLOC_FAILURE);
8002+		goto malloc_err;
8003+		}
8004+
8005+	/* see find_lock array definition for more info on object locking */
8006+	LOCK_OBJSTORE(OP_DSA);
8007+	rv = pFuncList->C_FindObjectsInit(session, a_key_template,
8008+		ul_key_attr_count);
8009+
8010+	if (rv != CKR_OK)
8011+		{
8012+		PK11err_add_data(PK11_F_GET_PRIV_DSA_KEY,
8013+		    PK11_R_FINDOBJECTSINIT, rv);
8014+		goto err;
8015+		}
8016+
8017+	rv = pFuncList->C_FindObjects(session, &h_key, 1, &found);
8018+
8019+	if (rv != CKR_OK)
8020+		{
8021+		PK11err_add_data(PK11_F_GET_PRIV_DSA_KEY,
8022+		    PK11_R_FINDOBJECTS, rv);
8023+		goto err;
8024+		}
8025+
8026+	rv = pFuncList->C_FindObjectsFinal(session);
8027+
8028+	if (rv != CKR_OK)
8029+		{
8030+		PK11err_add_data(PK11_F_GET_PRIV_DSA_KEY,
8031+		    PK11_R_FINDOBJECTSFINAL, rv);
8032+		goto err;
8033+		}
8034+
8035+	if (found == 0)
8036+		{
8037+		rv = pFuncList->C_CreateObject(session,
8038+			a_key_template, ul_key_attr_count, &h_key);
8039+		if (rv != CKR_OK)
8040+			{
8041+			PK11err_add_data(PK11_F_GET_PRIV_DSA_KEY,
8042+			    PK11_R_CREATEOBJECT, rv);
8043+			goto err;
8044+			}
8045+		}
8046+
8047+	if (dsa_priv_num != NULL)
8048+		if ((*dsa_priv_num = BN_dup(dsa->priv_key)) == NULL)
8049+			{
8050+			PK11err(PK11_F_GET_PRIV_DSA_KEY, PK11_R_MALLOC_FAILURE);
8051+			rollback = TRUE;
8052+			goto err;
8053+			}
8054+
8055+	/* LINTED: E_CONSTANT_CONDITION */
8056+	KEY_HANDLE_REFHOLD(h_key, OP_DSA, FALSE, rollback, err);
8057+	if (key_ptr != NULL)
8058+		*key_ptr = dsa;
8059+
8060+err:
8061+	if (rollback)
8062+		{
8063+		/*
8064+		 * We do not care about the return value from C_DestroyObject()
8065+		 * since we are doing rollback.
8066+		 */
8067+		if (found == 0)
8068+			(void) pFuncList->C_DestroyObject(session, h_key);
8069+		h_key = CK_INVALID_HANDLE;
8070+		}
8071+
8072+	UNLOCK_OBJSTORE(OP_DSA);
8073+
8074+malloc_err:
8075+	/*
8076+	 * 5 to 8 entries in the key template are key components.
8077+	 * They need to be freed apon exit or error.
8078+	 */
8079+	for (i = 5; i <= 8; i++)
8080+		{
8081+		if (a_key_template[i].pValue != NULL)
8082+			{
8083+			(void) memset(a_key_template[i].pValue, 0,
8084+				a_key_template[i].ulValueLen);
8085+			OPENSSL_free(a_key_template[i].pValue);
8086+			a_key_template[i].pValue = NULL;
8087+			}
8088+		}
8089+
8090+	return (h_key);
8091+	}
8092+
8093+/*
8094+ * Check for cache miss and clean the object pointer and handle
8095+ * in such case. Return 1 for cache hit, 0 for cache miss.
8096+ */
8097+static int check_new_dsa_key_pub(PK11_SESSION *sp, DSA *dsa)
8098+	{
8099+	/*
8100+	 * Provide protection against DSA structure reuse by making the
8101+	 * check for cache hit stronger. Only public key component of DSA
8102+	 * key matters here so it is sufficient to compare it with value
8103+	 * cached in PK11_SESSION structure.
8104+	 */
8105+	if ((sp->opdata_dsa_pub != dsa) ||
8106+	    (BN_cmp(sp->opdata_dsa_pub_num, dsa->pub_key) != 0))
8107+		{
8108+		/*
8109+		 * We do not check the return value because even in case of
8110+		 * failure the sp structure will have both key pointer
8111+		 * and object handle cleaned and pk11_destroy_object()
8112+		 * reports the failure to the OpenSSL error message buffer.
8113+		 */
8114+		(void) pk11_destroy_dsa_object_pub(sp, TRUE);
8115+		return (0);
8116+		}
8117+	return (1);
8118+	}
8119+
8120+/*
8121+ * Check for cache miss and clean the object pointer and handle
8122+ * in such case. Return 1 for cache hit, 0 for cache miss.
8123+ */
8124+static int check_new_dsa_key_priv(PK11_SESSION *sp, DSA *dsa)
8125+	{
8126+	/*
8127+	 * Provide protection against DSA structure reuse by making the
8128+	 * check for cache hit stronger. Only private key component of DSA
8129+	 * key matters here so it is sufficient to compare it with value
8130+	 * cached in PK11_SESSION structure.
8131+	 */
8132+	if ((sp->opdata_dsa_priv != dsa) ||
8133+	    (BN_cmp(sp->opdata_dsa_priv_num, dsa->priv_key) != 0))
8134+		{
8135+		/*
8136+		 * We do not check the return value because even in case of
8137+		 * failure the sp structure will have both key pointer
8138+		 * and object handle cleaned and pk11_destroy_object()
8139+		 * reports the failure to the OpenSSL error message buffer.
8140+		 */
8141+		(void) pk11_destroy_dsa_object_priv(sp, TRUE);
8142+		return (0);
8143+		}
8144+	return (1);
8145+	}
8146+#endif
8147+
8148+
8149+#ifndef OPENSSL_NO_DH
8150+/* The DH function implementation */
8151+/* ARGSUSED */
8152+static int pk11_DH_init(DH *dh)
8153+	{
8154+	return (1);
8155+	}
8156+
8157+/* ARGSUSED */
8158+static int pk11_DH_finish(DH *dh)
8159+	{
8160+	return (1);
8161+	}
8162+
8163+/*
8164+ * Generate DH key-pair.
8165+ *
8166+ * Warning: Unlike OpenSSL's DH_generate_key(3) we ignore dh->priv_key
8167+ * and override it even if it is set. OpenSSL does not touch dh->priv_key
8168+ * if set and just computes dh->pub_key. It looks like PKCS#11 standard
8169+ * is not capable of providing this functionality. This could be a problem
8170+ * for applications relying on OpenSSL's semantics.
8171+ */
8172+static int pk11_DH_generate_key(DH *dh)
8173+	{
8174+	CK_ULONG i;
8175+	CK_RV rv, rv1;
8176+	int reuse_mem_len = 0, ret = 0;
8177+	PK11_SESSION *sp = NULL;
8178+	CK_BYTE_PTR reuse_mem;
8179+
8180+	CK_MECHANISM mechanism = {CKM_DH_PKCS_KEY_PAIR_GEN, NULL_PTR, 0};
8181+	CK_OBJECT_HANDLE h_pub_key = CK_INVALID_HANDLE;
8182+	CK_OBJECT_HANDLE h_priv_key = CK_INVALID_HANDLE;
8183+
8184+	CK_ULONG ul_pub_key_attr_count = 3;
8185+	CK_ATTRIBUTE pub_key_template[] =
8186+		{
8187+		{CKA_PRIVATE, &false, sizeof (false)},
8188+		{CKA_PRIME, (void *)NULL, 0},
8189+		{CKA_BASE, (void *)NULL, 0}
8190+		};
8191+
8192+	CK_ULONG ul_priv_key_attr_count = 3;
8193+	CK_ATTRIBUTE priv_key_template[] =
8194+		{
8195+		{CKA_PRIVATE, &false, sizeof (false)},
8196+		{CKA_SENSITIVE, &false, sizeof (false)},
8197+		{CKA_DERIVE, &true, sizeof (true)}
8198+		};
8199+
8200+	CK_ULONG pub_key_attr_result_count = 1;
8201+	CK_ATTRIBUTE pub_key_result[] =
8202+		{
8203+		{CKA_VALUE, (void *)NULL, 0}
8204+		};
8205+
8206+	CK_ULONG priv_key_attr_result_count = 1;
8207+	CK_ATTRIBUTE priv_key_result[] =
8208+		{
8209+		{CKA_VALUE, (void *)NULL, 0}
8210+		};
8211+
8212+	pub_key_template[1].ulValueLen = BN_num_bytes(dh->p);
8213+	if (pub_key_template[1].ulValueLen > 0)
8214+		{
8215+		/*
8216+		 * We must not increase ulValueLen by DH_BUF_RESERVE since that
8217+		 * could cause the same rounding problem. See definition of
8218+		 * DH_BUF_RESERVE above.
8219+		 */
8220+		pub_key_template[1].pValue =
8221+			OPENSSL_malloc(pub_key_template[1].ulValueLen +
8222+			DH_BUF_RESERVE);
8223+		if (pub_key_template[1].pValue == NULL)
8224+			{
8225+			PK11err(PK11_F_DH_GEN_KEY, PK11_R_MALLOC_FAILURE);
8226+			goto err;
8227+			}
8228+
8229+		i = BN_bn2bin(dh->p, pub_key_template[1].pValue);
8230+		}
8231+	else
8232+		goto err;
8233+
8234+	pub_key_template[2].ulValueLen = BN_num_bytes(dh->g);
8235+	if (pub_key_template[2].ulValueLen > 0)
8236+		{
8237+		pub_key_template[2].pValue =
8238+			OPENSSL_malloc(pub_key_template[2].ulValueLen +
8239+			DH_BUF_RESERVE);
8240+		if (pub_key_template[2].pValue == NULL)
8241+			{
8242+			PK11err(PK11_F_DH_GEN_KEY, PK11_R_MALLOC_FAILURE);
8243+			goto err;
8244+			}
8245+
8246+		i = BN_bn2bin(dh->g, pub_key_template[2].pValue);
8247+		}
8248+	else
8249+		goto err;
8250+
8251+	/*
8252+	 * Note: we are only using PK11_SESSION structure for getting
8253+	 *	 a session handle. The objects created in this function are
8254+	 *	 destroyed before return and thus not cached.
8255+	 */
8256+	if ((sp = pk11_get_session(OP_DH)) == NULL)
8257+		goto err;
8258+
8259+	rv = pFuncList->C_GenerateKeyPair(sp->session,
8260+	    &mechanism,
8261+	    pub_key_template,
8262+	    ul_pub_key_attr_count,
8263+	    priv_key_template,
8264+	    ul_priv_key_attr_count,
8265+	    &h_pub_key,
8266+	    &h_priv_key);
8267+	if (rv != CKR_OK)
8268+		{
8269+		PK11err_add_data(PK11_F_DH_GEN_KEY, PK11_R_GEN_KEY, rv);
8270+		goto err;
8271+		}
8272+
8273+	/*
8274+	 * Reuse the larger memory allocated. We know the larger memory
8275+	 * should be sufficient for reuse.
8276+	 */
8277+	if (pub_key_template[1].ulValueLen > pub_key_template[2].ulValueLen)
8278+		{
8279+		reuse_mem = pub_key_template[1].pValue;
8280+		reuse_mem_len = pub_key_template[1].ulValueLen + DH_BUF_RESERVE;
8281+		}
8282+	else
8283+		{
8284+		reuse_mem = pub_key_template[2].pValue;
8285+		reuse_mem_len = pub_key_template[2].ulValueLen + DH_BUF_RESERVE;
8286+		}
8287+
8288+	rv = pFuncList->C_GetAttributeValue(sp->session, h_pub_key,
8289+		pub_key_result, pub_key_attr_result_count);
8290+	rv1 = pFuncList->C_GetAttributeValue(sp->session, h_priv_key,
8291+		priv_key_result, priv_key_attr_result_count);
8292+
8293+	if (rv != CKR_OK || rv1 != CKR_OK)
8294+		{
8295+		rv = (rv != CKR_OK) ? rv : rv1;
8296+		PK11err_add_data(PK11_F_DH_GEN_KEY,
8297+		    PK11_R_GETATTRIBUTVALUE, rv);
8298+		goto err;
8299+		}
8300+
8301+	if (((CK_LONG) pub_key_result[0].ulValueLen) <= 0 ||
8302+		((CK_LONG) priv_key_result[0].ulValueLen) <= 0)
8303+		{
8304+		PK11err(PK11_F_DH_GEN_KEY, PK11_R_GETATTRIBUTVALUE);
8305+		goto err;
8306+		}
8307+
8308+	/* Reuse the memory allocated */
8309+	pub_key_result[0].pValue = reuse_mem;
8310+	pub_key_result[0].ulValueLen = reuse_mem_len;
8311+
8312+	rv = pFuncList->C_GetAttributeValue(sp->session, h_pub_key,
8313+		pub_key_result, pub_key_attr_result_count);
8314+
8315+	if (rv != CKR_OK)
8316+		{
8317+		PK11err_add_data(PK11_F_DH_GEN_KEY,
8318+		    PK11_R_GETATTRIBUTVALUE, rv);
8319+		goto err;
8320+		}
8321+
8322+	if (pub_key_result[0].type == CKA_VALUE)
8323+		{
8324+		if (dh->pub_key == NULL)
8325+			if ((dh->pub_key = BN_new()) == NULL)
8326+				{
8327+				PK11err(PK11_F_DH_GEN_KEY,
8328+					PK11_R_MALLOC_FAILURE);
8329+				goto err;
8330+				}
8331+		dh->pub_key = BN_bin2bn(pub_key_result[0].pValue,
8332+			pub_key_result[0].ulValueLen, dh->pub_key);
8333+		if (dh->pub_key == NULL)
8334+			{
8335+			PK11err(PK11_F_DH_GEN_KEY, PK11_R_MALLOC_FAILURE);
8336+			goto err;
8337+			}
8338+		}
8339+
8340+	/* Reuse the memory allocated */
8341+	priv_key_result[0].pValue = reuse_mem;
8342+	priv_key_result[0].ulValueLen = reuse_mem_len;
8343+
8344+	rv = pFuncList->C_GetAttributeValue(sp->session, h_priv_key,
8345+		priv_key_result, priv_key_attr_result_count);
8346+
8347+	if (rv != CKR_OK)
8348+		{
8349+		PK11err_add_data(PK11_F_DH_GEN_KEY,
8350+		    PK11_R_GETATTRIBUTVALUE, rv);
8351+		goto err;
8352+		}
8353+
8354+	if (priv_key_result[0].type == CKA_VALUE)
8355+		{
8356+		if (dh->priv_key == NULL)
8357+			if ((dh->priv_key = BN_new()) == NULL)
8358+				{
8359+				PK11err(PK11_F_DH_GEN_KEY,
8360+					PK11_R_MALLOC_FAILURE);
8361+				goto err;
8362+				}
8363+		dh->priv_key = BN_bin2bn(priv_key_result[0].pValue,
8364+			priv_key_result[0].ulValueLen, dh->priv_key);
8365+		if (dh->priv_key == NULL)
8366+			{
8367+			PK11err(PK11_F_DH_GEN_KEY, PK11_R_MALLOC_FAILURE);
8368+			goto err;
8369+			}
8370+		}
8371+
8372+	ret = 1;
8373+
8374+err:
8375+
8376+	if (h_pub_key != CK_INVALID_HANDLE)
8377+		{
8378+		rv = pFuncList->C_DestroyObject(sp->session, h_pub_key);
8379+		if (rv != CKR_OK)
8380+			{
8381+			PK11err_add_data(PK11_F_DH_GEN_KEY,
8382+			    PK11_R_DESTROYOBJECT, rv);
8383+			}
8384+		}
8385+
8386+	if (h_priv_key != CK_INVALID_HANDLE)
8387+		{
8388+		rv = pFuncList->C_DestroyObject(sp->session, h_priv_key);
8389+		if (rv != CKR_OK)
8390+			{
8391+			PK11err_add_data(PK11_F_DH_GEN_KEY,
8392+			    PK11_R_DESTROYOBJECT, rv);
8393+			}
8394+		}
8395+
8396+	for (i = 1; i <= 2; i++)
8397+		{
8398+		if (pub_key_template[i].pValue != NULL)
8399+			{
8400+			OPENSSL_free(pub_key_template[i].pValue);
8401+			pub_key_template[i].pValue = NULL;
8402+			}
8403+		}
8404+
8405+	pk11_return_session(sp, OP_DH);
8406+	return (ret);
8407+	}
8408+
8409+static int pk11_DH_compute_key(unsigned char *key, const BIGNUM *pub_key,
8410+	DH *dh)
8411+	{
8412+	unsigned int i;
8413+	CK_MECHANISM mechanism = {CKM_DH_PKCS_DERIVE, NULL_PTR, 0};
8414+	CK_OBJECT_CLASS key_class = CKO_SECRET_KEY;
8415+	CK_KEY_TYPE key_type = CKK_GENERIC_SECRET;
8416+	CK_OBJECT_HANDLE h_derived_key = CK_INVALID_HANDLE;
8417+	CK_OBJECT_HANDLE h_key = CK_INVALID_HANDLE;
8418+
8419+	CK_ULONG ul_priv_key_attr_count = 2;
8420+	CK_ATTRIBUTE priv_key_template[] =
8421+		{
8422+		{CKA_CLASS, (void*) NULL, sizeof (key_class)},
8423+		{CKA_KEY_TYPE, (void*) NULL, sizeof (key_type)},
8424+		};
8425+
8426+	CK_ULONG priv_key_attr_result_count = 1;
8427+	CK_ATTRIBUTE priv_key_result[] =
8428+		{
8429+		{CKA_VALUE, (void *)NULL, 0}
8430+		};
8431+
8432+	CK_RV rv;
8433+	int ret = -1;
8434+	PK11_SESSION *sp = NULL;
8435+
8436+	if (dh->priv_key == NULL)
8437+		goto err;
8438+
8439+	priv_key_template[0].pValue = &key_class;
8440+	priv_key_template[1].pValue = &key_type;
8441+
8442+	if ((sp = pk11_get_session(OP_DH)) == NULL)
8443+		goto err;
8444+
8445+	mechanism.ulParameterLen = BN_num_bytes(pub_key);
8446+	mechanism.pParameter = OPENSSL_malloc(mechanism.ulParameterLen);
8447+	if (mechanism.pParameter == NULL)
8448+		{
8449+		PK11err(PK11_F_DH_COMP_KEY, PK11_R_MALLOC_FAILURE);
8450+		goto err;
8451+		}
8452+	BN_bn2bin(pub_key, mechanism.pParameter);
8453+
8454+	(void) check_new_dh_key(sp, dh);
8455+
8456+	h_key = sp->opdata_dh_key;
8457+	if (h_key == CK_INVALID_HANDLE)
8458+		h_key = sp->opdata_dh_key =
8459+			pk11_get_dh_key((DH*) dh, &sp->opdata_dh,
8460+			    &sp->opdata_dh_priv_num, sp->session);
8461+
8462+	if (h_key == CK_INVALID_HANDLE)
8463+		{
8464+		PK11err(PK11_F_DH_COMP_KEY, PK11_R_CREATEOBJECT);
8465+		goto err;
8466+		}
8467+
8468+	rv = pFuncList->C_DeriveKey(sp->session,
8469+	    &mechanism,
8470+	    h_key,
8471+	    priv_key_template,
8472+	    ul_priv_key_attr_count,
8473+	    &h_derived_key);
8474+	if (rv != CKR_OK)
8475+		{
8476+		PK11err_add_data(PK11_F_DH_COMP_KEY, PK11_R_DERIVEKEY, rv);
8477+		goto err;
8478+		}
8479+
8480+	rv = pFuncList->C_GetAttributeValue(sp->session, h_derived_key,
8481+	    priv_key_result, priv_key_attr_result_count);
8482+
8483+	if (rv != CKR_OK)
8484+		{
8485+		PK11err_add_data(PK11_F_DH_COMP_KEY, PK11_R_GETATTRIBUTVALUE,
8486+		    rv);
8487+		goto err;
8488+		}
8489+
8490+	if (((CK_LONG) priv_key_result[0].ulValueLen) <= 0)
8491+		{
8492+		PK11err(PK11_F_DH_COMP_KEY, PK11_R_GETATTRIBUTVALUE);
8493+		goto err;
8494+		}
8495+	priv_key_result[0].pValue =
8496+		OPENSSL_malloc(priv_key_result[0].ulValueLen);
8497+	if (!priv_key_result[0].pValue)
8498+		{
8499+		PK11err(PK11_F_DH_COMP_KEY, PK11_R_MALLOC_FAILURE);
8500+		goto err;
8501+		}
8502+
8503+	rv = pFuncList->C_GetAttributeValue(sp->session, h_derived_key,
8504+		priv_key_result, priv_key_attr_result_count);
8505+
8506+	if (rv != CKR_OK)
8507+		{
8508+		PK11err_add_data(PK11_F_DH_COMP_KEY, PK11_R_GETATTRIBUTVALUE,
8509+		    rv);
8510+		goto err;
8511+		}
8512+
8513+	/*
8514+	 * OpenSSL allocates the output buffer 'key' which is the same
8515+	 * length of the public key. It is long enough for the derived key
8516+	 */
8517+	if (priv_key_result[0].type == CKA_VALUE)
8518+		{
8519+		/*
8520+		 * CKM_DH_PKCS_DERIVE mechanism is not supposed to strip
8521+		 * leading zeros from a computed shared secret. However,
8522+		 * OpenSSL always did it so we must do the same here. The
8523+		 * vagueness of the spec regarding leading zero bytes was
8524+		 * finally cleared with TLS 1.1 (RFC 4346) saying that leading
8525+		 * zeros are stripped before the computed data is used as the
8526+		 * pre-master secret.
8527+		 */
8528+		for (i = 0; i < priv_key_result[0].ulValueLen; ++i)
8529+			{
8530+			if (((char *)priv_key_result[0].pValue)[i] != 0)
8531+				break;
8532+			}
8533+
8534+		(void) memcpy(key, ((char *)priv_key_result[0].pValue) + i,
8535+			priv_key_result[0].ulValueLen - i);
8536+		ret = priv_key_result[0].ulValueLen - i;
8537+		}
8538+
8539+err:
8540+
8541+	if (h_derived_key != CK_INVALID_HANDLE)
8542+		{
8543+		rv = pFuncList->C_DestroyObject(sp->session, h_derived_key);
8544+		if (rv != CKR_OK)
8545+			{
8546+			PK11err_add_data(PK11_F_DH_COMP_KEY,
8547+			    PK11_R_DESTROYOBJECT, rv);
8548+			}
8549+		}
8550+	if (priv_key_result[0].pValue)
8551+		{
8552+		OPENSSL_free(priv_key_result[0].pValue);
8553+		priv_key_result[0].pValue = NULL;
8554+		}
8555+
8556+	if (mechanism.pParameter)
8557+		{
8558+		OPENSSL_free(mechanism.pParameter);
8559+		mechanism.pParameter = NULL;
8560+		}
8561+
8562+	pk11_return_session(sp, OP_DH);
8563+	return (ret);
8564+	}
8565+
8566+
8567+static CK_OBJECT_HANDLE pk11_get_dh_key(DH* dh,
8568+	DH **key_ptr, BIGNUM **dh_priv_num, CK_SESSION_HANDLE session)
8569+	{
8570+	CK_RV rv;
8571+	CK_OBJECT_HANDLE h_key = CK_INVALID_HANDLE;
8572+	CK_OBJECT_CLASS class = CKO_PRIVATE_KEY;
8573+	CK_KEY_TYPE key_type = CKK_DH;
8574+	CK_ULONG found;
8575+	CK_BBOOL rollback = FALSE;
8576+	int i;
8577+
8578+	CK_ULONG ul_key_attr_count = 7;
8579+	CK_ATTRIBUTE key_template[] =
8580+		{
8581+		{CKA_CLASS, (void*) NULL, sizeof (class)},
8582+		{CKA_KEY_TYPE, (void*) NULL, sizeof (key_type)},
8583+		{CKA_DERIVE, &true, sizeof (true)},
8584+		{CKA_PRIVATE, &false, sizeof (false)},
8585+		{CKA_PRIME, (void *) NULL, 0},
8586+		{CKA_BASE, (void *) NULL, 0},
8587+		{CKA_VALUE, (void *) NULL, 0},
8588+		};
8589+
8590+	key_template[0].pValue = &class;
8591+	key_template[1].pValue = &key_type;
8592+
8593+	key_template[4].ulValueLen = BN_num_bytes(dh->p);
8594+	key_template[4].pValue = (CK_VOID_PTR)OPENSSL_malloc(
8595+		(size_t)key_template[4].ulValueLen);
8596+	if (key_template[4].pValue == NULL)
8597+		{
8598+		PK11err(PK11_F_GET_DH_KEY, PK11_R_MALLOC_FAILURE);
8599+		goto malloc_err;
8600+		}
8601+
8602+	BN_bn2bin(dh->p, key_template[4].pValue);
8603+
8604+	key_template[5].ulValueLen = BN_num_bytes(dh->g);
8605+	key_template[5].pValue = (CK_VOID_PTR)OPENSSL_malloc(
8606+		(size_t)key_template[5].ulValueLen);
8607+	if (key_template[5].pValue == NULL)
8608+		{
8609+		PK11err(PK11_F_GET_DH_KEY, PK11_R_MALLOC_FAILURE);
8610+		goto malloc_err;
8611+		}
8612+
8613+	BN_bn2bin(dh->g, key_template[5].pValue);
8614+
8615+	key_template[6].ulValueLen = BN_num_bytes(dh->priv_key);
8616+	key_template[6].pValue = (CK_VOID_PTR)OPENSSL_malloc(
8617+		(size_t)key_template[6].ulValueLen);
8618+	if (key_template[6].pValue == NULL)
8619+		{
8620+		PK11err(PK11_F_GET_DH_KEY, PK11_R_MALLOC_FAILURE);
8621+		goto malloc_err;
8622+		}
8623+
8624+	BN_bn2bin(dh->priv_key, key_template[6].pValue);
8625+
8626+	/* see find_lock array definition for more info on object locking */
8627+	LOCK_OBJSTORE(OP_DH);
8628+	rv = pFuncList->C_FindObjectsInit(session, key_template,
8629+		ul_key_attr_count);
8630+
8631+	if (rv != CKR_OK)
8632+		{
8633+		PK11err_add_data(PK11_F_GET_DH_KEY, PK11_R_FINDOBJECTSINIT, rv);
8634+		goto err;
8635+		}
8636+
8637+	rv = pFuncList->C_FindObjects(session, &h_key, 1, &found);
8638+
8639+	if (rv != CKR_OK)
8640+		{
8641+		PK11err_add_data(PK11_F_GET_DH_KEY, PK11_R_FINDOBJECTS, rv);
8642+		goto err;
8643+		}
8644+
8645+	rv = pFuncList->C_FindObjectsFinal(session);
8646+
8647+	if (rv != CKR_OK)
8648+		{
8649+		PK11err_add_data(PK11_F_GET_DH_KEY, PK11_R_FINDOBJECTSFINAL,
8650+		    rv);
8651+		goto err;
8652+		}
8653+
8654+	if (found == 0)
8655+		{
8656+		rv = pFuncList->C_CreateObject(session,
8657+			key_template, ul_key_attr_count, &h_key);
8658+		if (rv != CKR_OK)
8659+			{
8660+			PK11err_add_data(PK11_F_GET_DH_KEY, PK11_R_CREATEOBJECT,
8661+			    rv);
8662+			goto err;
8663+			}
8664+		}
8665+
8666+	if (dh_priv_num != NULL)
8667+		if ((*dh_priv_num = BN_dup(dh->priv_key)) == NULL)
8668+			{
8669+			PK11err(PK11_F_GET_DH_KEY, PK11_R_MALLOC_FAILURE);
8670+			rollback = TRUE;
8671+			goto err;
8672+			}
8673+
8674+	/* LINTED: E_CONSTANT_CONDITION */
8675+	KEY_HANDLE_REFHOLD(h_key, OP_DH, FALSE, rollback, err);
8676+	if (key_ptr != NULL)
8677+		*key_ptr = dh;
8678+
8679+err:
8680+	if (rollback)
8681+		{
8682+		/*
8683+		 * We do not care about the return value from C_DestroyObject()
8684+		 * since we are doing rollback.
8685+		 */
8686+		if (found == 0)
8687+			(void) pFuncList->C_DestroyObject(session, h_key);
8688+		h_key = CK_INVALID_HANDLE;
8689+		}
8690+
8691+	UNLOCK_OBJSTORE(OP_DH);
8692+
8693+malloc_err:
8694+	for (i = 4; i <= 6; i++)
8695+		{
8696+		if (key_template[i].pValue != NULL)
8697+			{
8698+			OPENSSL_free(key_template[i].pValue);
8699+			key_template[i].pValue = NULL;
8700+			}
8701+		}
8702+
8703+	return (h_key);
8704+	}
8705+
8706+/*
8707+ * Check for cache miss and clean the object pointer and handle
8708+ * in such case. Return 1 for cache hit, 0 for cache miss.
8709+ *
8710+ * Note: we rely on pk11_destroy_dh_key_objects() to set sp->opdata_dh
8711+ *       to CK_INVALID_HANDLE even when it fails to destroy the object.
8712+ */
8713+static int check_new_dh_key(PK11_SESSION *sp, DH *dh)
8714+	{
8715+	/*
8716+	 * Provide protection against DH structure reuse by making the
8717+	 * check for cache hit stronger. Private key component of DH key
8718+	 * is unique so it is sufficient to compare it with value cached
8719+	 * in PK11_SESSION structure.
8720+	 */
8721+	if ((sp->opdata_dh != dh) ||
8722+	    (BN_cmp(sp->opdata_dh_priv_num, dh->priv_key) != 0))
8723+		{
8724+		/*
8725+		 * We do not check the return value because even in case of
8726+		 * failure the sp structure will have both key pointer
8727+		 * and object handle cleaned and pk11_destroy_object()
8728+		 * reports the failure to the OpenSSL error message buffer.
8729+		 */
8730+		(void) pk11_destroy_dh_object(sp, TRUE);
8731+		return (0);
8732+		}
8733+	return (1);
8734+	}
8735+#endif
8736+
8737+/*
8738+ * Local function to simplify key template population
8739+ * Return 0 -- error, 1 -- no error
8740+ */
8741+static int
8742+init_template_value(BIGNUM *bn, CK_VOID_PTR *p_value,
8743+	CK_ULONG *ul_value_len)
8744+	{
8745+	CK_ULONG len = 0;
8746+
8747+	/*
8748+	 * This function can be used on non-initialized BIGNUMs. It is
8749+	 * easier to check that here than individually in the callers.
8750+	 */
8751+	if (bn != NULL)
8752+		len = BN_num_bytes(bn);
8753+
8754+	if (bn == NULL || len == 0)
8755+		return (1);
8756+
8757+	*ul_value_len = len;
8758+	*p_value = (CK_VOID_PTR)OPENSSL_malloc((size_t)*ul_value_len);
8759+	if (*p_value == NULL)
8760+		return (0);
8761+
8762+	BN_bn2bin(bn, *p_value);
8763+
8764+	return (1);
8765+	}
8766+
8767+static void
8768+attr_to_BN(CK_ATTRIBUTE_PTR attr, CK_BYTE attr_data[], BIGNUM **bn)
8769+	{
8770+	if (attr->ulValueLen > 0)
8771+		*bn = BN_bin2bn(attr_data, attr->ulValueLen, NULL);
8772+	}
8773+
8774+/*
8775+ * Find one object in the token. It is an error if we can not find the
8776+ * object or if we find more objects based on the template we got.
8777+ *
8778+ * Returns:
8779+ *	1 OK
8780+ *	0 no object or more than 1 object found
8781+ */
8782+static int
8783+find_one_object(PK11_OPTYPE op, CK_SESSION_HANDLE s,
8784+    CK_ATTRIBUTE_PTR ptempl, CK_ULONG nattr, CK_OBJECT_HANDLE_PTR pkey)
8785+	{
8786+	CK_RV rv;
8787+	CK_ULONG objcnt;
8788+
8789+	LOCK_OBJSTORE(op);
8790+	if ((rv = pFuncList->C_FindObjectsInit(s, ptempl, nattr)) != CKR_OK)
8791+		{
8792+		PK11err_add_data(PK11_F_FIND_ONE_OBJECT,
8793+		    PK11_R_FINDOBJECTSINIT, rv);
8794+		goto err;
8795+		}
8796+
8797+	rv = pFuncList->C_FindObjects(s, pkey, 1, &objcnt);
8798+	if (rv != CKR_OK)
8799+		{
8800+		PK11err_add_data(PK11_F_FIND_ONE_OBJECT, PK11_R_FINDOBJECTS,
8801+		    rv);
8802+		goto err;
8803+		}
8804+
8805+	if (objcnt > 1)
8806+		{
8807+		PK11err(PK11_F_FIND_ONE_OBJECT,
8808+		    PK11_R_MORE_THAN_ONE_OBJECT_FOUND);
8809+		goto err;
8810+		}
8811+	else if (objcnt == 0)
8812+		{
8813+		PK11err(PK11_F_FIND_ONE_OBJECT, PK11_R_NO_OBJECT_FOUND);
8814+		goto err;
8815+		}
8816+
8817+	(void) pFuncList->C_FindObjectsFinal(s);
8818+	UNLOCK_OBJSTORE(op);
8819+	return (1);
8820+err:
8821+	UNLOCK_OBJSTORE(op);
8822+	return (0);
8823+	}
8824+
8825+/* from uri stuff */
8826+
8827+extern char *pk11_pin;
8828+
8829+static int pk11_get_pin(void);
8830+
8831+static int
8832+pk11_get_pin(void)
8833+{
8834+	char *pin;
8835+
8836+	/* The getpassphrase() function is not MT safe. */
8837+#ifndef NOPTHREADS
8838+	(void) pthread_mutex_lock(token_lock);
8839+#else
8840+	CRYPTO_w_lock(CRYPTO_LOCK_PK11_ENGINE);
8841+#endif
8842+	pin = getpassphrase("Enter PIN: ");
8843+	if (pin == NULL)
8844+		{
8845+		PK11err(PK11_F_GET_PIN, PK11_R_COULD_NOT_READ_PIN);
8846+#ifndef NOPTHREADS
8847+		(void) pthread_mutex_unlock(token_lock);
8848+#else
8849+		CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
8850+#endif
8851+		goto err;
8852+		}
8853+	pk11_pin = BUF_strdup(pin);
8854+	if (pk11_pin == NULL)
8855+		{
8856+		PK11err(PK11_F_LOAD_PRIVKEY, PK11_R_MALLOC_FAILURE);
8857+#ifndef NOPTHREADS
8858+		(void) pthread_mutex_unlock(token_lock);
8859+#else
8860+		CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
8861+#endif
8862+		goto err;
8863+		}
8864+	memset(pin, 0, strlen(pin));
8865+#ifndef NOPTHREADS
8866+	(void) pthread_mutex_unlock(token_lock);
8867+#else
8868+	CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
8869+#endif
8870+	return (1);
8871+err:
8872+	return (0);
8873+	}
8874+
8875+/*
8876+ * Log in to the keystore if we are supposed to do that at all. Take care of
8877+ * reading and caching the PIN etc. Log in only once even when called from
8878+ * multiple threads.
8879+ *
8880+ * Returns:
8881+ *	1 on success
8882+ *	0 on failure
8883+ */
8884+static int
8885+pk11_token_login(CK_SESSION_HANDLE session, CK_BBOOL *login_done,
8886+    CK_BBOOL is_private)
8887+	{
8888+	CK_RV rv;
8889+
8890+#if 0
8891+	/* doesn't work on the AEP Keyper??? */
8892+	if ((pubkey_token_flags & CKF_TOKEN_INITIALIZED) == 0)
8893+		{
8894+		PK11err(PK11_F_TOKEN_LOGIN,
8895+		    PK11_R_TOKEN_NOT_INITIALIZED);
8896+		goto err;
8897+		}
8898+#endif
8899+
8900+	/*
8901+	 * If login is required or needed but the PIN has not been
8902+	 * even initialized we can bail out right now. Note that we
8903+	 * are supposed to always log in if we are going to access
8904+	 * private keys. However, we may need to log in even for
8905+	 * accessing public keys in case that the CKF_LOGIN_REQUIRED
8906+	 * flag is set.
8907+	 */
8908+	if (((pubkey_token_flags & CKF_LOGIN_REQUIRED) ||
8909+	     (is_private == CK_TRUE)) &&
8910+	    (~pubkey_token_flags & CKF_USER_PIN_INITIALIZED))
8911+		{
8912+		PK11err(PK11_F_TOKEN_LOGIN, PK11_R_TOKEN_PIN_NOT_SET);
8913+		goto err;
8914+		}
8915+
8916+	/*
8917+	 * Note on locking: it is possible that more than one thread
8918+	 * gets into pk11_get_pin() so we must deal with that. We
8919+	 * cannot avoid it since we cannot guard fork() in there with
8920+	 * a lock because we could end up in a dead lock in the
8921+	 * child. Why? Remember we are in a multithreaded environment
8922+	 * so we must lock all mutexes in the prefork function to
8923+	 * avoid a situation in which a thread that did not call
8924+	 * fork() held a lock, making future unlocking impossible. We
8925+	 * lock right before C_Login().
8926+	 */
8927+	if ((pubkey_token_flags & CKF_LOGIN_REQUIRED) ||
8928+	    (is_private == CK_TRUE))
8929+		{
8930+		if (*login_done == CK_FALSE)
8931+			{
8932+			if ((pk11_pin == NULL) && (pk11_get_pin() == 0))
8933+				{
8934+				PK11err(PK11_F_TOKEN_LOGIN,
8935+				    PK11_R_TOKEN_PIN_NOT_PROVIDED);
8936+				goto err;
8937+				}
8938+			}
8939+
8940+		/*
8941+		 * Note that what we are logging into is the keystore from
8942+		 * pubkey_SLOTID because we work with OP_RSA session type here.
8943+		 * That also means that we can work with only one keystore in
8944+		 * the engine.
8945+		 *
8946+		 * We must make sure we do not try to login more than once.
8947+		 * Also, see the comment above on locking strategy.
8948+		 */
8949+
8950+#ifndef NOPTHREADS
8951+		(void) pthread_mutex_lock(token_lock);
8952+#else
8953+		(void) pthread_mutex_lock(freelist_lock);
8954+#endif
8955+		if (*login_done == CK_FALSE)
8956+			{
8957+			if ((rv = pFuncList->C_Login(session,
8958+			    CKU_USER, (CK_UTF8CHAR*)pk11_pin,
8959+			    strlen(pk11_pin))) != CKR_OK)
8960+				{
8961+				PK11err_add_data(PK11_F_TOKEN_LOGIN,
8962+				    PK11_R_TOKEN_LOGIN_FAILED, rv);
8963+				goto err_locked;
8964+				}
8965+
8966+			*login_done = CK_TRUE;
8967+
8968+			}
8969+#ifndef NOPTHREADS
8970+		(void) pthread_mutex_unlock(token_lock);
8971+#else
8972+		CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
8973+#endif
8974+		}
8975+	else
8976+		{
8977+			/*
8978+			 * If token does not require login we take it as the
8979+			 * login was done.
8980+			 */
8981+			*login_done = CK_TRUE;
8982+		}
8983+
8984+	return (1);
8985+
8986+err_locked:
8987+	if (pk11_pin) {
8988+		memset(pk11_pin, 0, strlen(pk11_pin));
8989+		OPENSSL_free((void*)pk11_pin);
8990+	}
8991+	pk11_pin = NULL;
8992+#ifndef NOPTHREADS
8993+	(void) pthread_mutex_unlock(token_lock);
8994+#else
8995+	CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
8996+#endif
8997+err:
8998+	return (0);
8999+	}
9000+
9001+/*
9002+ * Log in to the keystore in the child if we were logged in in the
9003+ * parent. There are similarities in the code with pk11_token_login()
9004+ * but still it is quite different so we need a separate function for
9005+ * this.
9006+ *
9007+ * Note that this function is called under the locked session mutex when fork is
9008+ * detected. That means that C_Login() will be called from the child just once.
9009+ *
9010+ * Returns:
9011+ *	1 on success
9012+ *	0 on failure
9013+ */
9014+int
9015+pk11_token_relogin(CK_SESSION_HANDLE session)
9016+	{
9017+	CK_RV rv;
9018+
9019+	if ((pk11_pin == NULL) && (pk11_get_pin() == 0))
9020+		goto err;
9021+
9022+#ifndef NOPTHREADS
9023+	(void) pthread_mutex_lock(token_lock);
9024+#else
9025+	(void) pthread_mutex_lock(freelist_lock);
9026+#endif
9027+	if ((rv = pFuncList->C_Login(session, CKU_USER,
9028+	    (CK_UTF8CHAR_PTR)pk11_pin, strlen(pk11_pin))) != CKR_OK)
9029+		{
9030+		PK11err_add_data(PK11_F_TOKEN_RELOGIN,
9031+		    PK11_R_TOKEN_LOGIN_FAILED, rv);
9032+#ifndef NOPTHREADS
9033+		(void) pthread_mutex_unlock(token_lock);
9034+#else
9035+		CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
9036+#endif
9037+		goto err;
9038+		}
9039+#ifndef NOPTHREADS
9040+	(void) pthread_mutex_unlock(token_lock);
9041+#else
9042+	CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
9043+#endif
9044+
9045+	return (1);
9046+err:
9047+	return (0);
9048+	}
9049+
9050+#ifdef	OPENSSL_SYS_WIN32
9051+char *getpassphrase(const char *prompt)
9052+	{
9053+	static char buf[128];
9054+	HANDLE h;
9055+	DWORD cc, mode;
9056+	int cnt;
9057+
9058+	h = GetStdHandle(STD_INPUT_HANDLE);
9059+	fputs(prompt, stderr);
9060+	fflush(stderr);
9061+	fflush(stdout);
9062+	FlushConsoleInputBuffer(h);
9063+	GetConsoleMode(h, &mode);
9064+	SetConsoleMode(h, ENABLE_PROCESSED_INPUT);
9065+
9066+	for (cnt = 0; cnt < sizeof(buf) - 1; cnt++)
9067+		{
9068+		ReadFile(h, buf + cnt, 1, &cc, NULL);
9069+		if (buf[cnt] == '\r')
9070+			break;
9071+		fputc('*', stdout);
9072+		fflush(stderr);
9073+		fflush(stdout);
9074+		}
9075+
9076+	SetConsoleMode(h, mode);
9077+	buf[cnt] = '\0';
9078+	fputs("\n", stderr);
9079+	return buf;
9080+	}
9081+#endif	/* OPENSSL_SYS_WIN32 */
9082+#endif	/* OPENSSL_NO_HW_PK11CA */
9083+#endif	/* OPENSSL_NO_HW_PK11 */
9084+#endif	/* OPENSSL_NO_HW */
9085Index: openssl/crypto/engine/hw_pk11ca.h
9086diff -u /dev/null openssl/crypto/engine/hw_pk11ca.h:1.4
9087--- /dev/null	Mon Jan 16 18:54:23 2012
9088+++ openssl/crypto/engine/hw_pk11ca.h	Wed Jun 15 21:12:20 2011
9089@@ -0,0 +1,32 @@
9090+/* Redefine all pk11/PK11 external symbols to pk11ca/PK11CA */
9091+
9092+#define token_lock			pk11ca_token_lock
9093+#define find_lock			pk11ca_find_lock
9094+#define active_list			pk11ca_active_list
9095+#define pubkey_token_flags		pk11ca_pubkey_token_flags
9096+#define pubkey_SLOTID			pk11ca_pubkey_SLOTID
9097+#define ERR_pk11_error			ERR_pk11ca_error
9098+#define PK11err_add_data		PK11CAerr_add_data
9099+#define pk11_get_session		pk11ca_get_session
9100+#define pk11_return_session		pk11ca_return_session
9101+#define pk11_active_add			pk11ca_active_add
9102+#define pk11_active_delete		pk11ca_active_delete
9103+#define pk11_active_remove		pk11ca_active_remove
9104+#define pk11_free_active_list		pk11ca_free_active_list
9105+#define pk11_destroy_rsa_key_objects	pk11ca_destroy_rsa_key_objects
9106+#define pk11_destroy_rsa_object_pub	pk11ca_destroy_rsa_object_pub
9107+#define pk11_destroy_rsa_object_priv	pk11ca_destroy_rsa_object_priv
9108+#define pk11_load_privkey		pk11ca_load_privkey
9109+#define pk11_load_pubkey		pk11ca_load_pubkey
9110+#define PK11_RSA			PK11CA_RSA
9111+#define pk11_destroy_dsa_key_objects	pk11ca_destroy_dsa_key_objects
9112+#define pk11_destroy_dsa_object_pub	pk11ca_destroy_dsa_object_pub
9113+#define pk11_destroy_dsa_object_priv	pk11ca_destroy_dsa_object_priv
9114+#define PK11_DSA			PK11CA_DSA
9115+#define pk11_destroy_dh_key_objects	pk11ca_destroy_dh_key_objects
9116+#define pk11_destroy_dh_object		pk11ca_destroy_dh_object
9117+#define PK11_DH				PK11CA_DH
9118+#define pk11_token_relogin		pk11ca_token_relogin
9119+#define pFuncList			pk11ca_pFuncList
9120+#define pk11_pin			pk11ca_pin
9121+#define ENGINE_load_pk11		ENGINE_load_pk11ca
9122Index: openssl/crypto/engine/hw_pk11so.c
9123diff -u /dev/null openssl/crypto/engine/hw_pk11so.c:1.7
9124--- /dev/null	Mon Jan 16 18:54:23 2012
9125+++ openssl/crypto/engine/hw_pk11so.c	Thu Jun 16 12:31:53 2011
9126@@ -0,0 +1,1745 @@
9127+/*
9128+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
9129+ * Use is subject to license terms.
9130+ */
9131+
9132+/* crypto/engine/hw_pk11.c */
9133+/*
9134+ * This product includes software developed by the OpenSSL Project for
9135+ * use in the OpenSSL Toolkit (http://www.openssl.org/).
9136+ *
9137+ * This project also referenced hw_pkcs11-0.9.7b.patch written by
9138+ * Afchine Madjlessi.
9139+ */
9140+/*
9141+ * ====================================================================
9142+ * Copyright (c) 2000-2001 The OpenSSL Project.  All rights reserved.
9143+ *
9144+ * Redistribution and use in source and binary forms, with or without
9145+ * modification, are permitted provided that the following conditions
9146+ * are met:
9147+ *
9148+ * 1. Redistributions of source code must retain the above copyright
9149+ *    notice, this list of conditions and the following disclaimer.
9150+ *
9151+ * 2. Redistributions in binary form must reproduce the above copyright
9152+ *    notice, this list of conditions and the following disclaimer in
9153+ *    the documentation and/or other materials provided with the
9154+ *    distribution.
9155+ *
9156+ * 3. All advertising materials mentioning features or use of this
9157+ *    software must display the following acknowledgment:
9158+ *    "This product includes software developed by the OpenSSL Project
9159+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
9160+ *
9161+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
9162+ *    endorse or promote products derived from this software without
9163+ *    prior written permission. For written permission, please contact
9164+ *    licensing@OpenSSL.org.
9165+ *
9166+ * 5. Products derived from this software may not be called "OpenSSL"
9167+ *    nor may "OpenSSL" appear in their names without prior written
9168+ *    permission of the OpenSSL Project.
9169+ *
9170+ * 6. Redistributions of any form whatsoever must retain the following
9171+ *    acknowledgment:
9172+ *    "This product includes software developed by the OpenSSL Project
9173+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
9174+ *
9175+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
9176+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
9177+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
9178+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
9179+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
9180+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
9181+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
9182+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
9183+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
9184+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
9185+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
9186+ * OF THE POSSIBILITY OF SUCH DAMAGE.
9187+ * ====================================================================
9188+ *
9189+ * This product includes cryptographic software written by Eric Young
9190+ * (eay@cryptsoft.com).  This product includes software written by Tim
9191+ * Hudson (tjh@cryptsoft.com).
9192+ *
9193+ */
9194+
9195+/* Modified to keep only RNG and RSA Sign */
9196+
9197+#ifdef OPENSSL_NO_RSA
9198+#error RSA is disabled
9199+#endif
9200+
9201+#include <stdio.h>
9202+#include <stdlib.h>
9203+#include <string.h>
9204+#include <sys/types.h>
9205+
9206+#include <openssl/e_os2.h>
9207+#include <openssl/crypto.h>
9208+#include <cryptlib.h>
9209+#include <openssl/engine.h>
9210+#include <openssl/dso.h>
9211+#include <openssl/err.h>
9212+#include <openssl/bn.h>
9213+#include <openssl/md5.h>
9214+#include <openssl/pem.h>
9215+#include <openssl/rsa.h>
9216+#include <openssl/rand.h>
9217+#include <openssl/objects.h>
9218+#include <openssl/x509.h>
9219+
9220+#ifdef OPENSSL_SYS_WIN32
9221+typedef int pid_t;
9222+#define getpid() GetCurrentProcessId()
9223+#define NOPTHREADS
9224+#ifndef NULL_PTR
9225+#define NULL_PTR NULL
9226+#endif
9227+#define CK_DEFINE_FUNCTION(returnType, name) \
9228+	returnType __declspec(dllexport) name
9229+#define CK_DECLARE_FUNCTION(returnType, name) \
9230+	returnType __declspec(dllimport) name
9231+#define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
9232+	returnType __declspec(dllimport) (* name)
9233+#else
9234+#include <signal.h>
9235+#include <unistd.h>
9236+#include <dlfcn.h>
9237+#endif
9238+
9239+#ifndef NOPTHREADS
9240+#include <pthread.h>
9241+#endif
9242+
9243+#ifndef OPENSSL_NO_HW
9244+#ifndef OPENSSL_NO_HW_PK11
9245+#ifndef OPENSSL_NO_HW_PK11SO
9246+
9247+/* label for debug messages printed on stderr */
9248+#define	PK11_DBG	"PKCS#11 ENGINE DEBUG"
9249+/* prints a lot of debug messages on stderr about slot selection process */
9250+/*#undef	DEBUG_SLOT_SELECTION */
9251+
9252+#ifndef OPENSSL_NO_DSA
9253+#define OPENSSL_NO_DSA
9254+#endif
9255+#ifndef OPENSSL_NO_DH
9256+#define OPENSSL_NO_DH
9257+#endif
9258+
9259+#ifdef OPENSSL_SYS_WIN32
9260+#pragma pack(push, cryptoki, 1)
9261+#include "cryptoki.h"
9262+#include "pkcs11.h"
9263+#pragma pack(pop, cryptoki)
9264+#else
9265+#include "cryptoki.h"
9266+#include "pkcs11.h"
9267+#endif
9268+#include "hw_pk11so.h"
9269+#include "hw_pk11_err.c"
9270+
9271+/*
9272+ * We use this lock to prevent multiple C_Login()s, guard getpassphrase(),
9273+ * uri_struct manipulation, and static token info. All of that is used by the
9274+ * RSA keys by reference feature.
9275+ */
9276+#ifndef NOPTHREADS
9277+pthread_mutex_t *token_lock;
9278+#endif
9279+
9280+/* PKCS#11 session caches and their locks for all operation types */
9281+static PK11_CACHE session_cache[OP_MAX];
9282+
9283+/*
9284+ * We cache the flags so that we do not have to run C_GetTokenInfo() again when
9285+ * logging into the token.
9286+ */
9287+CK_FLAGS pubkey_token_flags;
9288+
9289+/*
9290+ * As stated in v2.20, 11.7 Object Management Function, in section for
9291+ * C_FindObjectsInit(), at most one search operation may be active at a given
9292+ * time in a given session. Therefore, C_Find{,Init,Final}Objects() should be
9293+ * grouped together to form one atomic search operation. This is already
9294+ * ensured by the property of unique PKCS#11 session handle used for each
9295+ * PK11_SESSION object.
9296+ *
9297+ * This is however not the biggest concern - maintaining consistency of the
9298+ * underlying object store is more important. The same section of the spec also
9299+ * says that one thread can be in the middle of a search operation while another
9300+ * thread destroys the object matching the search template which would result in
9301+ * invalid handle returned from the search operation.
9302+ *
9303+ * Hence, the following locks are used for both protection of the object stores.
9304+ * They are also used for active list protection.
9305+ */
9306+#ifndef NOPTHREADS
9307+pthread_mutex_t *find_lock[OP_MAX] = { NULL };
9308+#endif
9309+
9310+/*
9311+ * lists of asymmetric key handles which are active (referenced by at least one
9312+ * PK11_SESSION structure, either held by a thread or present in free_session
9313+ * list) for given algorithm type
9314+ */
9315+PK11_active *active_list[OP_MAX] = { NULL };
9316+
9317+/*
9318+ * Create all secret key objects in a global session so that they are available
9319+ * to use for other sessions. These other sessions may be opened or closed
9320+ * without losing the secret key objects.
9321+ */
9322+static CK_SESSION_HANDLE	global_session = CK_INVALID_HANDLE;
9323+
9324+/* ENGINE level stuff */
9325+static int pk11_init(ENGINE *e);
9326+static int pk11_library_init(ENGINE *e);
9327+static int pk11_finish(ENGINE *e);
9328+static int pk11_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void));
9329+static int pk11_destroy(ENGINE *e);
9330+
9331+/* RAND stuff */
9332+static void pk11_rand_seed(const void *buf, int num);
9333+static void pk11_rand_add(const void *buf, int num, double add_entropy);
9334+static void pk11_rand_cleanup(void);
9335+static int pk11_rand_bytes(unsigned char *buf, int num);
9336+static int pk11_rand_status(void);
9337+
9338+/* These functions are also used in other files */
9339+PK11_SESSION *pk11_get_session(PK11_OPTYPE optype);
9340+void pk11_return_session(PK11_SESSION *sp, PK11_OPTYPE optype);
9341+
9342+/* active list manipulation functions used in this file */
9343+extern int pk11_active_delete(CK_OBJECT_HANDLE h, PK11_OPTYPE type);
9344+extern void pk11_free_active_list(PK11_OPTYPE type);
9345+
9346+int pk11_destroy_rsa_key_objects(PK11_SESSION *session);
9347+int pk11_destroy_rsa_object_pub(PK11_SESSION *sp, CK_BBOOL uselock);
9348+int pk11_destroy_rsa_object_priv(PK11_SESSION *sp, CK_BBOOL uselock);
9349+
9350+/* Local helper functions */
9351+static int pk11_free_all_sessions(void);
9352+static int pk11_free_session_list(PK11_OPTYPE optype);
9353+static int pk11_setup_session(PK11_SESSION *sp, PK11_OPTYPE optype);
9354+static int pk11_destroy_object(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE oh,
9355+	CK_BBOOL persistent);
9356+static const char *get_PK11_LIBNAME(void);
9357+static void free_PK11_LIBNAME(void);
9358+static long set_PK11_LIBNAME(const char *name);
9359+
9360+static int pk11_choose_slots(int *any_slot_found);
9361+
9362+static int pk11_init_all_locks(void);
9363+static void pk11_free_all_locks(void);
9364+
9365+#define	TRY_OBJ_DESTROY(sp, obj_hdl, retval, uselock, alg_type, priv)	\
9366+	{								\
9367+	if (uselock)							\
9368+		LOCK_OBJSTORE(alg_type);				\
9369+	if (pk11_active_delete(obj_hdl, alg_type) == 1)			\
9370+		{							\
9371+		  retval = pk11_destroy_object(sp->session, obj_hdl,	\
9372+		  priv ? sp->priv_persistent : sp->pub_persistent);	\
9373+		}							\
9374+	if (uselock)							\
9375+		UNLOCK_OBJSTORE(alg_type);				\
9376+	}
9377+
9378+static CK_BBOOL pk11_have_rsa	= CK_FALSE;
9379+static CK_BBOOL pk11_have_random = CK_FALSE;
9380+
9381+/*
9382+ * Initialization function. Sets up various PKCS#11 library components.
9383+ * The definitions for control commands specific to this engine
9384+ */
9385+#define PK11_CMD_SO_PATH		ENGINE_CMD_BASE
9386+#define PK11_CMD_PIN			(ENGINE_CMD_BASE+1)
9387+#define PK11_CMD_SLOT			(ENGINE_CMD_BASE+2)
9388+static const ENGINE_CMD_DEFN pk11_cmd_defns[] =
9389+	{
9390+		{
9391+		PK11_CMD_SO_PATH,
9392+		"SO_PATH",
9393+		"Specifies the path to the 'pkcs#11' shared library",
9394+		ENGINE_CMD_FLAG_STRING
9395+		},
9396+		{
9397+		PK11_CMD_PIN,
9398+		"PIN",
9399+		"Specifies the pin code",
9400+		ENGINE_CMD_FLAG_STRING
9401+		},
9402+		{
9403+		PK11_CMD_SLOT,
9404+		"SLOT",
9405+		"Specifies the slot (default is auto select)",
9406+		ENGINE_CMD_FLAG_NUMERIC,
9407+		},
9408+		{0, NULL, NULL, 0}
9409+	};
9410+
9411+
9412+static RAND_METHOD pk11_random =
9413+	{
9414+	pk11_rand_seed,
9415+	pk11_rand_bytes,
9416+	pk11_rand_cleanup,
9417+	pk11_rand_add,
9418+	pk11_rand_bytes,
9419+	pk11_rand_status
9420+	};
9421+
9422+
9423+/* Constants used when creating the ENGINE */
9424+#ifdef OPENSSL_NO_HW_PK11CA
9425+#error "can't load both crypto-accelerator and sign-only PKCS#11 engines"
9426+#endif
9427+static const char *engine_pk11_id = "pkcs11";
9428+static const char *engine_pk11_name = "PKCS #11 engine support (sign only)";
9429+
9430+CK_FUNCTION_LIST_PTR pFuncList = NULL;
9431+static const char PK11_GET_FUNCTION_LIST[] = "C_GetFunctionList";
9432+
9433+/*
9434+ * This is a static string constant for the DSO file name and the function
9435+ * symbol names to bind to. We set it in the Configure script based on whether
9436+ * this is 32 or 64 bit build.
9437+ */
9438+static const char def_PK11_LIBNAME[] = PK11_LIB_LOCATION;
9439+
9440+/* Needed in hw_pk11_pub.c as well so that's why it is not static. */
9441+CK_SLOT_ID pubkey_SLOTID = 0;
9442+static CK_SLOT_ID rand_SLOTID = 0;
9443+static CK_SLOT_ID SLOTID = 0;
9444+char *pk11_pin = NULL;
9445+static CK_BBOOL pk11_library_initialized = FALSE;
9446+static CK_BBOOL pk11_atfork_initialized = FALSE;
9447+static int pk11_pid = 0;
9448+
9449+static DSO *pk11_dso = NULL;
9450+
9451+/* allocate and initialize all locks used by the engine itself */
9452+static int pk11_init_all_locks(void)
9453+	{
9454+#ifndef NOPTHREADS
9455+	int type;
9456+
9457+	if ((token_lock = OPENSSL_malloc(sizeof (pthread_mutex_t))) == NULL)
9458+		goto malloc_err;
9459+	(void) pthread_mutex_init(token_lock, NULL);
9460+
9461+	find_lock[OP_RSA] = OPENSSL_malloc(sizeof (pthread_mutex_t));
9462+	if (find_lock[OP_RSA] == NULL)
9463+		goto malloc_err;
9464+	(void) pthread_mutex_init(find_lock[OP_RSA], NULL);
9465+
9466+	for (type = 0; type < OP_MAX; type++)
9467+		{
9468+		session_cache[type].lock =
9469+		    OPENSSL_malloc(sizeof (pthread_mutex_t));
9470+		if (session_cache[type].lock == NULL)
9471+			goto malloc_err;
9472+		(void) pthread_mutex_init(session_cache[type].lock, NULL);
9473+		}
9474+
9475+	return (1);
9476+
9477+malloc_err:
9478+	pk11_free_all_locks();
9479+	PK11err(PK11_F_INIT_ALL_LOCKS, PK11_R_MALLOC_FAILURE);
9480+	return (0);
9481+#else
9482+	return (1);
9483+#endif
9484+	}
9485+
9486+static void pk11_free_all_locks(void)
9487+	{
9488+#ifndef NOPTHREADS
9489+	int type;
9490+
9491+	if (find_lock[OP_RSA] != NULL)
9492+		{
9493+		(void) pthread_mutex_destroy(find_lock[OP_RSA]);
9494+		OPENSSL_free(find_lock[OP_RSA]);
9495+		find_lock[OP_RSA] = NULL;
9496+		}
9497+
9498+	for (type = 0; type < OP_MAX; type++)
9499+		{
9500+		if (session_cache[type].lock != NULL)
9501+			{
9502+			(void) pthread_mutex_destroy(session_cache[type].lock);
9503+			OPENSSL_free(session_cache[type].lock);
9504+			session_cache[type].lock = NULL;
9505+			}
9506+		}
9507+#endif
9508+	}
9509+
9510+/*
9511+ * This internal function is used by ENGINE_pk11() and "dynamic" ENGINE support.
9512+ */
9513+static int bind_pk11(ENGINE *e)
9514+	{
9515+	if (!pk11_library_initialized)
9516+		if (!pk11_library_init(e))
9517+			return (0);
9518+
9519+	if (!ENGINE_set_id(e, engine_pk11_id) ||
9520+	    !ENGINE_set_name(e, engine_pk11_name))
9521+		return (0);
9522+
9523+	if (pk11_have_rsa == CK_TRUE)
9524+		{
9525+		if (!ENGINE_set_RSA(e, PK11_RSA()) ||
9526+		    !ENGINE_set_load_privkey_function(e, pk11_load_privkey) ||
9527+		    !ENGINE_set_load_pubkey_function(e, pk11_load_pubkey))
9528+			return (0);
9529+#ifdef	DEBUG_SLOT_SELECTION
9530+		fprintf(stderr, "%s: registered RSA\n", PK11_DBG);
9531+#endif	/* DEBUG_SLOT_SELECTION */
9532+		}
9533+
9534+	if (pk11_have_random)
9535+		{
9536+		if (!ENGINE_set_RAND(e, &pk11_random))
9537+			return (0);
9538+#ifdef	DEBUG_SLOT_SELECTION
9539+		fprintf(stderr, "%s: registered random\n", PK11_DBG);
9540+#endif	/* DEBUG_SLOT_SELECTION */
9541+		}
9542+	if (!ENGINE_set_init_function(e, pk11_init) ||
9543+	    !ENGINE_set_destroy_function(e, pk11_destroy) ||
9544+	    !ENGINE_set_finish_function(e, pk11_finish) ||
9545+	    !ENGINE_set_ctrl_function(e, pk11_ctrl) ||
9546+	    !ENGINE_set_cmd_defns(e, pk11_cmd_defns))
9547+		return (0);
9548+
9549+	/* Ensure the pk11 error handling is set up */
9550+	ERR_load_pk11_strings();
9551+
9552+	return (1);
9553+	}
9554+
9555+/* Dynamic engine support is disabled at a higher level for Solaris */
9556+#ifdef	ENGINE_DYNAMIC_SUPPORT
9557+#error	"dynamic engine not supported"
9558+static int bind_helper(ENGINE *e, const char *id)
9559+	{
9560+	if (id && (strcmp(id, engine_pk11_id) != 0))
9561+		return (0);
9562+
9563+	if (!bind_pk11(e))
9564+		return (0);
9565+
9566+	return (1);
9567+	}
9568+
9569+IMPLEMENT_DYNAMIC_CHECK_FN()
9570+IMPLEMENT_DYNAMIC_BIND_FN(bind_helper)
9571+
9572+#else
9573+static ENGINE *engine_pk11(void)
9574+	{
9575+	ENGINE *ret = ENGINE_new();
9576+
9577+	if (!ret)
9578+		return (NULL);
9579+
9580+	if (!bind_pk11(ret))
9581+		{
9582+		ENGINE_free(ret);
9583+		return (NULL);
9584+		}
9585+
9586+	return (ret);
9587+	}
9588+
9589+void
9590+ENGINE_load_pk11(void)
9591+	{
9592+	ENGINE *e_pk11 = NULL;
9593+
9594+	/*
9595+	 * Do not use dynamic PKCS#11 library on Solaris due to
9596+	 * security reasons. We will link it in statically.
9597+	 */
9598+	/* Attempt to load PKCS#11 library */
9599+	if (!pk11_dso)
9600+		pk11_dso = DSO_load(NULL, get_PK11_LIBNAME(), NULL, 0);
9601+
9602+	if (pk11_dso == NULL)
9603+		{
9604+		PK11err(PK11_F_LOAD, PK11_R_DSO_FAILURE);
9605+		return;
9606+		}
9607+
9608+	e_pk11 = engine_pk11();
9609+	if (!e_pk11)
9610+		{
9611+		DSO_free(pk11_dso);
9612+		pk11_dso = NULL;
9613+		return;
9614+		}
9615+
9616+	/*
9617+	 * At this point, the pk11 shared library is either dynamically
9618+	 * loaded or statically linked in. So, initialize the pk11
9619+	 * library before calling ENGINE_set_default since the latter
9620+	 * needs cipher and digest algorithm information
9621+	 */
9622+	if (!pk11_library_init(e_pk11))
9623+		{
9624+		DSO_free(pk11_dso);
9625+		pk11_dso = NULL;
9626+		ENGINE_free(e_pk11);
9627+		return;
9628+		}
9629+
9630+	ENGINE_add(e_pk11);
9631+
9632+	ENGINE_free(e_pk11);
9633+	ERR_clear_error();
9634+	}
9635+#endif	/* ENGINE_DYNAMIC_SUPPORT */
9636+
9637+/*
9638+ * These are the static string constants for the DSO file name and
9639+ * the function symbol names to bind to.
9640+ */
9641+static const char *PK11_LIBNAME = NULL;
9642+
9643+static const char *get_PK11_LIBNAME(void)
9644+	{
9645+	if (PK11_LIBNAME)
9646+		return (PK11_LIBNAME);
9647+
9648+	return (def_PK11_LIBNAME);
9649+	}
9650+
9651+static void free_PK11_LIBNAME(void)
9652+	{
9653+	if (PK11_LIBNAME)
9654+		OPENSSL_free((void*)PK11_LIBNAME);
9655+
9656+	PK11_LIBNAME = NULL;
9657+	}
9658+
9659+static long set_PK11_LIBNAME(const char *name)
9660+	{
9661+	free_PK11_LIBNAME();
9662+
9663+	return ((PK11_LIBNAME = BUF_strdup(name)) != NULL ? 1 : 0);
9664+	}
9665+
9666+/* acquire all engine specific mutexes before fork */
9667+static void pk11_fork_prepare(void)
9668+	{
9669+#ifndef NOPTHREADS
9670+	int i;
9671+
9672+	if (!pk11_library_initialized)
9673+		return;
9674+
9675+	LOCK_OBJSTORE(OP_RSA);
9676+	(void) pthread_mutex_lock(token_lock);
9677+	for (i = 0; i < OP_MAX; i++)
9678+		{
9679+		(void) pthread_mutex_lock(session_cache[i].lock);
9680+		}
9681+#endif
9682+	}
9683+
9684+/* release all engine specific mutexes */
9685+static void pk11_fork_parent(void)
9686+	{
9687+#ifndef NOPTHREADS
9688+	int i;
9689+
9690+	if (!pk11_library_initialized)
9691+		return;
9692+
9693+	for (i = OP_MAX - 1; i >= 0; i--)
9694+		{
9695+		(void) pthread_mutex_unlock(session_cache[i].lock);
9696+		}
9697+	UNLOCK_OBJSTORE(OP_RSA);
9698+	(void) pthread_mutex_unlock(token_lock);
9699+#endif
9700+	}
9701+
9702+/*
9703+ * same situation as in parent - we need to unlock all locks to make them
9704+ * accessible to all threads.
9705+ */
9706+static void pk11_fork_child(void)
9707+	{
9708+#ifndef NOPTHREADS
9709+	int i;
9710+
9711+	if (!pk11_library_initialized)
9712+		return;
9713+
9714+	for (i = OP_MAX - 1; i >= 0; i--)
9715+		{
9716+		(void) pthread_mutex_unlock(session_cache[i].lock);
9717+		}
9718+	UNLOCK_OBJSTORE(OP_RSA);
9719+	(void) pthread_mutex_unlock(token_lock);
9720+#endif
9721+	}
9722+
9723+/* Initialization function for the pk11 engine */
9724+static int pk11_init(ENGINE *e)
9725+{
9726+	return (pk11_library_init(e));
9727+}
9728+
9729+static CK_C_INITIALIZE_ARGS pk11_init_args =
9730+	{
9731+	NULL_PTR,		/* CreateMutex */
9732+	NULL_PTR,		/* DestroyMutex */
9733+	NULL_PTR,		/* LockMutex */
9734+	NULL_PTR,		/* UnlockMutex */
9735+	CKF_OS_LOCKING_OK,	/* flags */
9736+	NULL_PTR,		/* pReserved */
9737+	};
9738+
9739+/*
9740+ * Initialization function. Sets up various PKCS#11 library components.
9741+ * It selects a slot based on predefined critiera. In the process, it also
9742+ * count how many ciphers and digests to support. Since the cipher and
9743+ * digest information is needed when setting default engine, this function
9744+ * needs to be called before calling ENGINE_set_default.
9745+ */
9746+/* ARGSUSED */
9747+static int pk11_library_init(ENGINE *e)
9748+	{
9749+	CK_C_GetFunctionList p;
9750+	CK_RV rv = CKR_OK;
9751+	CK_INFO info;
9752+	int any_slot_found;
9753+	int i;
9754+#ifndef OPENSSL_SYS_WIN32
9755+	struct sigaction sigint_act, sigterm_act, sighup_act;
9756+#endif
9757+
9758+	/*
9759+	 * pk11_library_initialized is set to 0 in pk11_finish() which
9760+	 * is called from ENGINE_finish(). However, if there is still
9761+	 * at least one existing functional reference to the engine
9762+	 * (see engine(3) for more information), pk11_finish() is
9763+	 * skipped. For example, this can happen if an application
9764+	 * forgets to clear one cipher context. In case of a fork()
9765+	 * when the application is finishing the engine so that it can
9766+	 * be reinitialized in the child, forgotten functional
9767+	 * reference causes pk11_library_initialized to stay 1. In
9768+	 * that case we need the PID check so that we properly
9769+	 * initialize the engine again.
9770+	 */
9771+	if (pk11_library_initialized)
9772+		{
9773+		if (pk11_pid == getpid())
9774+			{
9775+			return (1);
9776+			}
9777+		else
9778+			{
9779+			global_session = CK_INVALID_HANDLE;
9780+			/*
9781+			 * free the locks first to prevent memory leak in case
9782+			 * the application calls fork() without finishing the
9783+			 * engine first.
9784+			 */
9785+			pk11_free_all_locks();
9786+			}
9787+		}
9788+
9789+	if (pk11_dso == NULL)
9790+		{
9791+		PK11err(PK11_F_LIBRARY_INIT, PK11_R_DSO_FAILURE);
9792+		goto err;
9793+		}
9794+
9795+	/* get the C_GetFunctionList function from the loaded library */
9796+	p = (CK_C_GetFunctionList)DSO_bind_func(pk11_dso,
9797+		PK11_GET_FUNCTION_LIST);
9798+	if (!p)
9799+		{
9800+		PK11err(PK11_F_LIBRARY_INIT, PK11_R_DSO_FAILURE);
9801+		goto err;
9802+		}
9803+
9804+	/* get the full function list from the loaded library */
9805+	rv = p(&pFuncList);
9806+	if (rv != CKR_OK)
9807+		{
9808+		PK11err_add_data(PK11_F_LIBRARY_INIT, PK11_R_DSO_FAILURE, rv);
9809+		goto err;
9810+		}
9811+
9812+#ifndef OPENSSL_SYS_WIN32
9813+	/* Not all PKCS#11 library are signal safe! */
9814+
9815+	(void) memset(&sigint_act, 0, sizeof(sigint_act));
9816+	(void) memset(&sigterm_act, 0, sizeof(sigterm_act));
9817+	(void) memset(&sighup_act, 0, sizeof(sighup_act));
9818+	(void) sigaction(SIGINT, NULL, &sigint_act);
9819+	(void) sigaction(SIGTERM, NULL, &sigterm_act);
9820+	(void) sigaction(SIGHUP, NULL, &sighup_act);
9821+#endif
9822+	rv = pFuncList->C_Initialize((CK_VOID_PTR)&pk11_init_args);
9823+#ifndef OPENSSL_SYS_WIN32
9824+	(void) sigaction(SIGINT, &sigint_act, NULL);
9825+	(void) sigaction(SIGTERM, &sigterm_act, NULL);
9826+	(void) sigaction(SIGHUP, &sighup_act, NULL);
9827+#endif
9828+	if ((rv != CKR_OK) && (rv != CKR_CRYPTOKI_ALREADY_INITIALIZED))
9829+		{
9830+		PK11err_add_data(PK11_F_LIBRARY_INIT, PK11_R_INITIALIZE, rv);
9831+		goto err;
9832+		}
9833+
9834+	rv = pFuncList->C_GetInfo(&info);
9835+	if (rv != CKR_OK)
9836+		{
9837+		PK11err_add_data(PK11_F_LIBRARY_INIT, PK11_R_GETINFO, rv);
9838+		goto err;
9839+		}
9840+
9841+	if (pk11_choose_slots(&any_slot_found) == 0)
9842+		goto err;
9843+
9844+	/*
9845+	 * The library we use, set in def_PK11_LIBNAME, may not offer any
9846+	 * slot(s). In that case, we must not proceed but we must not return an
9847+	 * error. The reason is that applications that try to set up the PKCS#11
9848+	 * engine don't exit on error during the engine initialization just
9849+	 * because no slot was present.
9850+	 */
9851+	if (any_slot_found == 0)
9852+		return (1);
9853+
9854+	if (global_session == CK_INVALID_HANDLE)
9855+		{
9856+		/* Open the global_session for the new process */
9857+		rv = pFuncList->C_OpenSession(SLOTID, CKF_SERIAL_SESSION,
9858+			NULL_PTR, NULL_PTR, &global_session);
9859+		if (rv != CKR_OK)
9860+			{
9861+			PK11err_add_data(PK11_F_LIBRARY_INIT,
9862+			    PK11_R_OPENSESSION, rv);
9863+			goto err;
9864+			}
9865+		}
9866+
9867+	pk11_library_initialized = TRUE;
9868+	pk11_pid = getpid();
9869+	/*
9870+	 * if initialization of the locks fails pk11_init_all_locks()
9871+	 * will do the cleanup.
9872+	 */
9873+	if (!pk11_init_all_locks())
9874+		goto err;
9875+	for (i = 0; i < OP_MAX; i++)
9876+		session_cache[i].head = NULL;
9877+	/*
9878+	 * initialize active lists. We only use active lists
9879+	 * for asymmetric ciphers.
9880+	 */
9881+	for (i = 0; i < OP_MAX; i++)
9882+		active_list[i] = NULL;
9883+
9884+#ifndef NOPTHREADS
9885+	if (!pk11_atfork_initialized)
9886+		{
9887+		if (pthread_atfork(pk11_fork_prepare, pk11_fork_parent,
9888+		    pk11_fork_child) != 0)
9889+			{
9890+			PK11err(PK11_F_LIBRARY_INIT, PK11_R_ATFORK_FAILED);
9891+			goto err;
9892+			}
9893+		pk11_atfork_initialized = TRUE;
9894+		}
9895+#endif
9896+
9897+	return (1);
9898+
9899+err:
9900+	return (0);
9901+	}
9902+
9903+/* Destructor (complements the "ENGINE_pk11()" constructor) */
9904+/* ARGSUSED */
9905+static int pk11_destroy(ENGINE *e)
9906+	{
9907+	free_PK11_LIBNAME();
9908+	ERR_unload_pk11_strings();
9909+	if (pk11_pin) {
9910+		memset(pk11_pin, 0, strlen(pk11_pin));
9911+		OPENSSL_free((void*)pk11_pin);
9912+	}
9913+	pk11_pin = NULL;
9914+	return (1);
9915+	}
9916+
9917+/*
9918+ * Termination function to clean up the session, the token, and the pk11
9919+ * library.
9920+ */
9921+/* ARGSUSED */
9922+static int pk11_finish(ENGINE *e)
9923+	{
9924+	int i;
9925+
9926+	if (pk11_pin) {
9927+		memset(pk11_pin, 0, strlen(pk11_pin));
9928+		OPENSSL_free((void*)pk11_pin);
9929+	}
9930+	pk11_pin = NULL;
9931+
9932+	if (pk11_dso == NULL)
9933+		{
9934+		PK11err(PK11_F_FINISH, PK11_R_NOT_LOADED);
9935+		goto err;
9936+		}
9937+
9938+	OPENSSL_assert(pFuncList != NULL);
9939+
9940+	if (pk11_free_all_sessions() == 0)
9941+		goto err;
9942+
9943+	/* free all active lists */
9944+	for (i = 0; i < OP_MAX; i++)
9945+		pk11_free_active_list(i);
9946+
9947+	pFuncList->C_CloseSession(global_session);
9948+	global_session = CK_INVALID_HANDLE;
9949+
9950+	/*
9951+	 * Since we are part of a library (libcrypto.so), calling this function
9952+	 * may have side-effects.
9953+	 */
9954+#if 0
9955+	pFuncList->C_Finalize(NULL);
9956+#endif
9957+
9958+	if (!DSO_free(pk11_dso))
9959+		{
9960+		PK11err(PK11_F_FINISH, PK11_R_DSO_FAILURE);
9961+		goto err;
9962+		}
9963+	pk11_dso = NULL;
9964+	pFuncList = NULL;
9965+	pk11_library_initialized = FALSE;
9966+	pk11_pid = 0;
9967+	/*
9968+	 * There is no way how to unregister atfork handlers (other than
9969+	 * unloading the library) so we just free the locks. For this reason
9970+	 * the atfork handlers check if the engine is initialized and bail out
9971+	 * immediately if not. This is necessary in case a process finishes
9972+	 * the engine before calling fork().
9973+	 */
9974+	pk11_free_all_locks();
9975+
9976+	return (1);
9977+
9978+err:
9979+	return (0);
9980+	}
9981+
9982+/* Standard engine interface function to set the dynamic library path */
9983+/* ARGSUSED */
9984+static int pk11_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void))
9985+	{
9986+	int initialized = ((pk11_dso == NULL) ? 0 : 1);
9987+
9988+	switch (cmd)
9989+		{
9990+	case PK11_CMD_SO_PATH:
9991+		if (p == NULL)
9992+			{
9993+			PK11err(PK11_F_CTRL, ERR_R_PASSED_NULL_PARAMETER);
9994+			return (0);
9995+			}
9996+
9997+		if (initialized)
9998+			{
9999+			PK11err(PK11_F_CTRL, PK11_R_ALREADY_LOADED);
10000+			return (0);
10001+			}
10002+
10003+		return (set_PK11_LIBNAME((const char *)p));
10004+	case PK11_CMD_PIN:
10005+		if (pk11_pin) {
10006+			memset(pk11_pin, 0, strlen(pk11_pin));
10007+			OPENSSL_free((void*)pk11_pin);
10008+		}
10009+		pk11_pin = NULL;
10010+
10011+		if (p == NULL)
10012+			{
10013+			PK11err(PK11_F_CTRL, ERR_R_PASSED_NULL_PARAMETER);
10014+			return (0);
10015+			}
10016+
10017+		pk11_pin = BUF_strdup(p);
10018+		if (pk11_pin == NULL)
10019+			{
10020+			PK11err(PK11_F_GET_SESSION, PK11_R_MALLOC_FAILURE);
10021+			return (0);
10022+			}
10023+		return (1);
10024+	case PK11_CMD_SLOT:
10025+		SLOTID = (CK_SLOT_ID)i;
10026+#ifdef DEBUG_SLOT_SELECTION
10027+		fprintf(stderr, "%s: slot set\n", PK11_DBG);
10028+#endif
10029+		return (1);
10030+	default:
10031+		break;
10032+		}
10033+
10034+	PK11err(PK11_F_CTRL, PK11_R_CTRL_COMMAND_NOT_IMPLEMENTED);
10035+
10036+	return (0);
10037+	}
10038+
10039+
10040+/* Required function by the engine random interface. It does nothing here */
10041+static void pk11_rand_cleanup(void)
10042+	{
10043+	return;
10044+	}
10045+
10046+/* ARGSUSED */
10047+static void pk11_rand_add(const void *buf, int num, double add)
10048+	{
10049+	PK11_SESSION *sp;
10050+
10051+	if ((sp = pk11_get_session(OP_RAND)) == NULL)
10052+		return;
10053+
10054+	/*
10055+	 * Ignore any errors (e.g. CKR_RANDOM_SEED_NOT_SUPPORTED) since
10056+	 * the calling functions do not care anyway
10057+	 */
10058+	pFuncList->C_SeedRandom(sp->session, (unsigned char *) buf, num);
10059+	pk11_return_session(sp, OP_RAND);
10060+
10061+	return;
10062+	}
10063+
10064+static void pk11_rand_seed(const void *buf, int num)
10065+	{
10066+	pk11_rand_add(buf, num, 0);
10067+	}
10068+
10069+static int pk11_rand_bytes(unsigned char *buf, int num)
10070+	{
10071+	CK_RV rv;
10072+	PK11_SESSION *sp;
10073+
10074+	if ((sp = pk11_get_session(OP_RAND)) == NULL)
10075+		return (0);
10076+
10077+	rv = pFuncList->C_GenerateRandom(sp->session, buf, num);
10078+	if (rv != CKR_OK)
10079+		{
10080+		PK11err_add_data(PK11_F_RAND_BYTES, PK11_R_GENERATERANDOM, rv);
10081+		pk11_return_session(sp, OP_RAND);
10082+		return (0);
10083+		}
10084+
10085+	pk11_return_session(sp, OP_RAND);
10086+	return (1);
10087+	}
10088+
10089+/* Required function by the engine random interface. It does nothing here */
10090+static int pk11_rand_status(void)
10091+	{
10092+	return (1);
10093+	}
10094+
10095+/* Free all BIGNUM structures from PK11_SESSION. */
10096+static void pk11_free_nums(PK11_SESSION *sp, PK11_OPTYPE optype)
10097+	{
10098+	switch (optype)
10099+		{
10100+		case OP_RSA:
10101+			if (sp->opdata_rsa_n_num != NULL)
10102+				{
10103+				BN_free(sp->opdata_rsa_n_num);
10104+				sp->opdata_rsa_n_num = NULL;
10105+				}
10106+			if (sp->opdata_rsa_e_num != NULL)
10107+				{
10108+				BN_free(sp->opdata_rsa_e_num);
10109+				sp->opdata_rsa_e_num = NULL;
10110+				}
10111+			if (sp->opdata_rsa_pn_num != NULL)
10112+				{
10113+				BN_free(sp->opdata_rsa_pn_num);
10114+				sp->opdata_rsa_pn_num = NULL;
10115+				}
10116+			if (sp->opdata_rsa_pe_num != NULL)
10117+				{
10118+				BN_free(sp->opdata_rsa_pe_num);
10119+				sp->opdata_rsa_pe_num = NULL;
10120+				}
10121+			if (sp->opdata_rsa_d_num != NULL)
10122+				{
10123+				BN_free(sp->opdata_rsa_d_num);
10124+				sp->opdata_rsa_d_num = NULL;
10125+				}
10126+			break;
10127+		default:
10128+			break;
10129+		}
10130+	}
10131+
10132+/*
10133+ * Get new PK11_SESSION structure ready for use. Every process must have
10134+ * its own freelist of PK11_SESSION structures so handle fork() here
10135+ * by destroying the old and creating new freelist.
10136+ * The returned PK11_SESSION structure is disconnected from the freelist.
10137+ */
10138+PK11_SESSION *
10139+pk11_get_session(PK11_OPTYPE optype)
10140+	{
10141+	PK11_SESSION *sp = NULL, *sp1, *freelist;
10142+#ifndef NOPTHREADS
10143+	pthread_mutex_t *freelist_lock = NULL;
10144+#endif
10145+	static pid_t pid = 0;
10146+	pid_t new_pid;
10147+	CK_RV rv;
10148+
10149+	switch (optype)
10150+		{
10151+		case OP_RSA:
10152+		case OP_DSA:
10153+		case OP_DH:
10154+		case OP_RAND:
10155+		case OP_DIGEST:
10156+		case OP_CIPHER:
10157+#ifndef NOPTHREADS
10158+			freelist_lock = session_cache[optype].lock;
10159+#endif
10160+			break;
10161+		default:
10162+			PK11err(PK11_F_GET_SESSION,
10163+				PK11_R_INVALID_OPERATION_TYPE);
10164+			return (NULL);
10165+		}
10166+#ifndef NOPTHREADS
10167+	(void) pthread_mutex_lock(freelist_lock);
10168+#else
10169+	CRYPTO_w_lock(CRYPTO_LOCK_PK11_ENGINE);
10170+#endif
10171+
10172+	/*
10173+	 * Will use it to find out if we forked. We cannot use the PID field in
10174+	 * the session structure because we could get a newly allocated session
10175+	 * here, with no PID information.
10176+	 */
10177+	if (pid == 0)
10178+		pid = getpid();
10179+
10180+	freelist = session_cache[optype].head;
10181+	sp = freelist;
10182+
10183+	/*
10184+	 * If the free list is empty, allocate new unitialized (filled
10185+	 * with zeroes) PK11_SESSION structure otherwise return first
10186+	 * structure from the freelist.
10187+	 */
10188+	if (sp == NULL)
10189+		{
10190+		if ((sp = OPENSSL_malloc(sizeof (PK11_SESSION))) == NULL)
10191+			{
10192+			PK11err(PK11_F_GET_SESSION,
10193+				PK11_R_MALLOC_FAILURE);
10194+			goto err;
10195+			}
10196+		(void) memset(sp, 0, sizeof (PK11_SESSION));
10197+
10198+		/*
10199+		 * It is a new session so it will look like a cache miss to the
10200+		 * code below. So, we must not try to to destroy its members so
10201+		 * mark them as unused.
10202+		 */
10203+		sp->opdata_rsa_priv_key = CK_INVALID_HANDLE;
10204+		sp->opdata_rsa_pub_key = CK_INVALID_HANDLE;
10205+		}
10206+	else
10207+		{
10208+		freelist = sp->next;
10209+		}
10210+
10211+	/*
10212+	 * Check whether we have forked. In that case, we must get rid of all
10213+	 * inherited sessions and start allocating new ones.
10214+	 */
10215+	if (pid != (new_pid = getpid()))
10216+		{
10217+		pid = new_pid;
10218+
10219+		/*
10220+		 * We are a new process and thus need to free any inherited
10221+		 * PK11_SESSION objects aside from the first session (sp) which
10222+		 * is the only PK11_SESSION structure we will reuse (for the
10223+		 * head of the list).
10224+		 */
10225+		while ((sp1 = freelist) != NULL)
10226+			{
10227+			freelist = sp1->next;
10228+			/*
10229+			 * NOTE: we do not want to call pk11_free_all_sessions()
10230+			 * here because it would close underlying PKCS#11
10231+			 * sessions and destroy all objects.
10232+			 */
10233+			pk11_free_nums(sp1, optype);
10234+			OPENSSL_free(sp1);
10235+			}
10236+
10237+		/* we have to free the active list as well. */
10238+		pk11_free_active_list(optype);
10239+
10240+		/* Initialize the process */
10241+		rv = pFuncList->C_Initialize((CK_VOID_PTR)&pk11_init_args);
10242+		if ((rv != CKR_OK) && (rv != CKR_CRYPTOKI_ALREADY_INITIALIZED))
10243+			{
10244+			PK11err_add_data(PK11_F_GET_SESSION, PK11_R_INITIALIZE,
10245+			    rv);
10246+			OPENSSL_free(sp);
10247+			sp = NULL;
10248+			goto err;
10249+			}
10250+
10251+		/*
10252+		 * Choose slot here since the slot table is different on this
10253+		 * process. If we are here then we must have found at least one
10254+		 * usable slot before so we don't need to check any_slot_found.
10255+		 * See pk11_library_init()'s usage of this function for more
10256+		 * information.
10257+		 */
10258+		if (pk11_choose_slots(NULL) == 0)
10259+			goto err;
10260+
10261+		/* Open the global_session for the new process */
10262+		rv = pFuncList->C_OpenSession(SLOTID, CKF_SERIAL_SESSION,
10263+			NULL_PTR, NULL_PTR, &global_session);
10264+		if (rv != CKR_OK)
10265+			{
10266+			PK11err_add_data(PK11_F_GET_SESSION, PK11_R_OPENSESSION,
10267+			    rv);
10268+			OPENSSL_free(sp);
10269+			sp = NULL;
10270+			goto err;
10271+			}
10272+
10273+		/*
10274+		 * It is an inherited session from our parent so it needs
10275+		 * re-initialization.
10276+		 */
10277+		if (pk11_setup_session(sp, optype) == 0)
10278+			{
10279+			OPENSSL_free(sp);
10280+			sp = NULL;
10281+			goto err;
10282+			}
10283+		if (pk11_token_relogin(sp->session) == 0) 
10284+			{
10285+			/*
10286+			 * We will keep the session in the cache list and let
10287+			 * the caller cope with the situation.
10288+			 */
10289+			freelist = sp;
10290+			sp = NULL;
10291+			goto err;
10292+			}
10293+		}
10294+
10295+	if (sp->pid == 0)
10296+		{
10297+		/* It is a new session and needs initialization. */
10298+		if (pk11_setup_session(sp, optype) == 0)
10299+			{
10300+			OPENSSL_free(sp);
10301+			sp = NULL;
10302+			}
10303+		}
10304+
10305+	/* set new head for the list of PK11_SESSION objects */
10306+	session_cache[optype].head = freelist;
10307+
10308+err:
10309+	if (sp != NULL)
10310+		sp->next = NULL;
10311+
10312+#ifndef NOPTHREADS
10313+	(void) pthread_mutex_unlock(freelist_lock);
10314+#else
10315+	CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
10316+#endif
10317+
10318+	return (sp);
10319+	}
10320+
10321+
10322+void
10323+pk11_return_session(PK11_SESSION *sp, PK11_OPTYPE optype)
10324+	{
10325+#ifndef NOPTHREADS
10326+	pthread_mutex_t *freelist_lock;
10327+#endif
10328+	PK11_SESSION *freelist;
10329+
10330+	/*
10331+	 * If this is a session from the parent it will be taken care of and
10332+	 * freed in pk11_get_session() as part of the post-fork clean up the
10333+	 * next time we will ask for a new session.
10334+	 */
10335+	if (sp == NULL || sp->pid != getpid())
10336+		return;
10337+
10338+	switch (optype)
10339+		{
10340+		case OP_RSA:
10341+		case OP_DSA:
10342+		case OP_DH:
10343+		case OP_RAND:
10344+		case OP_DIGEST:
10345+		case OP_CIPHER:
10346+#ifndef NOPTHREADS
10347+			freelist_lock = session_cache[optype].lock;
10348+#endif
10349+			break;
10350+		default:
10351+			PK11err(PK11_F_RETURN_SESSION,
10352+				PK11_R_INVALID_OPERATION_TYPE);
10353+			return;
10354+		}
10355+
10356+#ifndef NOPTHREADS
10357+	(void) pthread_mutex_lock(freelist_lock);
10358+#else
10359+	CRYPTO_w_lock(CRYPTO_LOCK_PK11_ENGINE);
10360+#endif
10361+	freelist = session_cache[optype].head;
10362+	sp->next = freelist;
10363+	session_cache[optype].head = sp;
10364+#ifndef NOPTHREADS
10365+	(void) pthread_mutex_unlock(freelist_lock);
10366+#else
10367+	CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
10368+#endif
10369+	}
10370+
10371+
10372+/* Destroy all objects. This function is called when the engine is finished */
10373+static int pk11_free_all_sessions()
10374+	{
10375+	int ret = 1;
10376+	int type;
10377+
10378+	(void) pk11_destroy_rsa_key_objects(NULL);
10379+
10380+	/*
10381+	 * We try to release as much as we can but any error means that we will
10382+	 * return 0 on exit.
10383+	 */
10384+	for (type = 0; type < OP_MAX; type++)
10385+		{
10386+		if (pk11_free_session_list(type) == 0)
10387+			ret = 0;
10388+		}
10389+
10390+	return (ret);
10391+	}
10392+
10393+/*
10394+ * Destroy session structures from the linked list specified. Free as many
10395+ * sessions as possible but any failure in C_CloseSession() means that we
10396+ * return an error on return.
10397+ */
10398+static int pk11_free_session_list(PK11_OPTYPE optype)
10399+	{
10400+	CK_RV rv;
10401+	PK11_SESSION *sp = NULL;
10402+	PK11_SESSION *freelist = NULL;
10403+	pid_t mypid = getpid();
10404+#ifndef NOPTHREADS
10405+	pthread_mutex_t *freelist_lock;
10406+#endif
10407+	int ret = 1;
10408+
10409+	switch (optype)
10410+		{
10411+		case OP_RSA:
10412+		case OP_DSA:
10413+		case OP_DH:
10414+		case OP_RAND:
10415+		case OP_DIGEST:
10416+		case OP_CIPHER:
10417+#ifndef NOPTHREADS
10418+			freelist_lock = session_cache[optype].lock;
10419+#endif
10420+			break;
10421+		default:
10422+			PK11err(PK11_F_FREE_ALL_SESSIONS,
10423+				PK11_R_INVALID_OPERATION_TYPE);
10424+			return (0);
10425+		}
10426+
10427+#ifndef NOPTHREADS
10428+	(void) pthread_mutex_lock(freelist_lock);
10429+#else
10430+	CRYPTO_w_lock(CRYPTO_LOCK_PK11_ENGINE);
10431+#endif
10432+	freelist = session_cache[optype].head;
10433+	while ((sp = freelist) != NULL)
10434+		{
10435+		if (sp->session != CK_INVALID_HANDLE && sp->pid == mypid)
10436+			{
10437+			rv = pFuncList->C_CloseSession(sp->session);
10438+			if (rv != CKR_OK)
10439+				{
10440+				PK11err_add_data(PK11_F_FREE_ALL_SESSIONS,
10441+					PK11_R_CLOSESESSION, rv);
10442+				ret = 0;
10443+				}
10444+			}
10445+		freelist = sp->next;
10446+		pk11_free_nums(sp, optype);
10447+		OPENSSL_free(sp);
10448+		}
10449+
10450+#ifndef NOPTHREADS
10451+	(void) pthread_mutex_unlock(freelist_lock);
10452+#else
10453+	CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
10454+#endif
10455+	return (ret);
10456+	}
10457+
10458+
10459+static int
10460+pk11_setup_session(PK11_SESSION *sp, PK11_OPTYPE optype)
10461+	{
10462+	CK_RV rv;
10463+	CK_SLOT_ID myslot;
10464+
10465+	switch (optype)
10466+		{
10467+		case OP_RSA:
10468+			myslot = pubkey_SLOTID;
10469+			break;
10470+		case OP_RAND:
10471+			myslot = rand_SLOTID;
10472+			break;
10473+		default:
10474+			PK11err(PK11_F_SETUP_SESSION,
10475+			    PK11_R_INVALID_OPERATION_TYPE);
10476+			return (0);
10477+		}
10478+
10479+	sp->session = CK_INVALID_HANDLE;
10480+#ifdef	DEBUG_SLOT_SELECTION
10481+	fprintf(stderr, "%s: myslot=%d optype=%d\n", PK11_DBG, myslot, optype);
10482+#endif	/* DEBUG_SLOT_SELECTION */
10483+	rv = pFuncList->C_OpenSession(myslot, CKF_SERIAL_SESSION,
10484+		NULL_PTR, NULL_PTR, &sp->session);
10485+	if (rv == CKR_CRYPTOKI_NOT_INITIALIZED)
10486+		{
10487+		/*
10488+		 * We are probably a child process so force the
10489+		 * reinitialize of the session
10490+		 */
10491+		pk11_library_initialized = FALSE;
10492+		if (!pk11_library_init(NULL))
10493+			return (0);
10494+		rv = pFuncList->C_OpenSession(myslot, CKF_SERIAL_SESSION,
10495+			NULL_PTR, NULL_PTR, &sp->session);
10496+		}
10497+	if (rv != CKR_OK)
10498+		{
10499+		PK11err_add_data(PK11_F_SETUP_SESSION, PK11_R_OPENSESSION, rv);
10500+		return (0);
10501+		}
10502+
10503+	sp->pid = getpid();
10504+
10505+	if (optype == OP_RSA)
10506+		{
10507+		sp->opdata_rsa_pub_key = CK_INVALID_HANDLE;
10508+		sp->opdata_rsa_priv_key = CK_INVALID_HANDLE;
10509+		sp->opdata_rsa_pub = NULL;
10510+		sp->opdata_rsa_n_num = NULL;
10511+		sp->opdata_rsa_e_num = NULL;
10512+		sp->opdata_rsa_priv = NULL;
10513+		sp->opdata_rsa_pn_num = NULL;
10514+		sp->opdata_rsa_pe_num = NULL;
10515+		sp->opdata_rsa_d_num = NULL;
10516+		}
10517+
10518+	/*
10519+	 * We always initialize the session as containing a non-persistent
10520+	 * object. The key load functions set it to persistent if that is so.
10521+	 */
10522+	sp->pub_persistent = CK_FALSE;
10523+	sp->priv_persistent = CK_FALSE;
10524+	return (1);
10525+	}
10526+
10527+/* Destroy RSA public key from single session. */
10528+int
10529+pk11_destroy_rsa_object_pub(PK11_SESSION *sp, CK_BBOOL uselock)
10530+	{
10531+	int ret = 0;
10532+
10533+	if (sp->opdata_rsa_pub_key != CK_INVALID_HANDLE)
10534+		{
10535+		TRY_OBJ_DESTROY(sp, sp->opdata_rsa_pub_key,
10536+		    ret, uselock, OP_RSA, CK_FALSE);
10537+		sp->opdata_rsa_pub_key = CK_INVALID_HANDLE;
10538+		sp->opdata_rsa_pub = NULL;
10539+		if (sp->opdata_rsa_n_num != NULL)
10540+			{
10541+			BN_free(sp->opdata_rsa_n_num);
10542+			sp->opdata_rsa_n_num = NULL;
10543+			}
10544+		if (sp->opdata_rsa_e_num != NULL)
10545+			{
10546+			BN_free(sp->opdata_rsa_e_num);
10547+			sp->opdata_rsa_e_num = NULL;
10548+			}
10549+		}
10550+
10551+	return (ret);
10552+	}
10553+
10554+/* Destroy RSA private key from single session. */
10555+int
10556+pk11_destroy_rsa_object_priv(PK11_SESSION *sp, CK_BBOOL uselock)
10557+	{
10558+	int ret = 0;
10559+
10560+	if (sp->opdata_rsa_priv_key != CK_INVALID_HANDLE)
10561+		{
10562+		TRY_OBJ_DESTROY(sp, sp->opdata_rsa_priv_key,
10563+		    ret, uselock, OP_RSA, CK_TRUE);
10564+		sp->opdata_rsa_priv_key = CK_INVALID_HANDLE;
10565+		sp->opdata_rsa_priv = NULL;
10566+		if (sp->opdata_rsa_d_num != NULL)
10567+			{
10568+			BN_free(sp->opdata_rsa_d_num);
10569+			sp->opdata_rsa_d_num = NULL;
10570+			}
10571+
10572+		/*
10573+		 * For the RSA key by reference code, public components 'n'/'e'
10574+		 * are the key components we use to check for the cache hit. We
10575+		 * must free those as well.
10576+		 */
10577+		if (sp->opdata_rsa_pn_num != NULL)
10578+			{
10579+			BN_free(sp->opdata_rsa_pn_num);
10580+			sp->opdata_rsa_pn_num = NULL;
10581+			}
10582+		if (sp->opdata_rsa_pe_num != NULL)
10583+			{
10584+			BN_free(sp->opdata_rsa_pe_num);
10585+			sp->opdata_rsa_pe_num = NULL;
10586+			}
10587+		}
10588+
10589+	return (ret);
10590+	}
10591+
10592+/*
10593+ * Destroy RSA key object wrapper. If session is NULL, try to destroy all
10594+ * objects in the free list.
10595+ */
10596+int
10597+pk11_destroy_rsa_key_objects(PK11_SESSION *session)
10598+	{
10599+	int ret = 1;
10600+	PK11_SESSION *sp = NULL;
10601+	PK11_SESSION *local_free_session;
10602+	CK_BBOOL uselock = TRUE;
10603+
10604+	if (session != NULL)
10605+		local_free_session = session;
10606+	else
10607+		{
10608+#ifndef NOPTHREADS
10609+		(void) pthread_mutex_lock(session_cache[OP_RSA].lock);
10610+#else
10611+		CRYPTO_w_lock(CRYPTO_LOCK_PK11_ENGINE);
10612+#endif
10613+		local_free_session = session_cache[OP_RSA].head;
10614+		uselock = FALSE;
10615+		}
10616+
10617+	/*
10618+	 * go through the list of sessions and delete key objects
10619+	 */
10620+	while ((sp = local_free_session) != NULL)
10621+		{
10622+		local_free_session = sp->next;
10623+
10624+		/*
10625+		 * Do not terminate list traversal if one of the
10626+		 * destroy operations fails.
10627+		 */
10628+		if (pk11_destroy_rsa_object_pub(sp, uselock) == 0)
10629+			{
10630+			ret = 0;
10631+			continue;
10632+			}
10633+		if (pk11_destroy_rsa_object_priv(sp, uselock) == 0)
10634+			{
10635+			ret = 0;
10636+			continue;
10637+			}
10638+		}
10639+
10640+#ifndef NOPTHREADS
10641+	if (session == NULL)
10642+		(void) pthread_mutex_unlock(session_cache[OP_RSA].lock);
10643+#else
10644+	if (session == NULL)
10645+		CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
10646+#endif
10647+
10648+	return (ret);
10649+	}
10650+
10651+static int
10652+pk11_destroy_object(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE oh,
10653+	CK_BBOOL persistent)
10654+	{
10655+	CK_RV rv;
10656+
10657+	/*
10658+	 * We never try to destroy persistent objects which are the objects
10659+	 * stored in the keystore. Also, we always use read-only sessions so
10660+	 * C_DestroyObject() would be returning CKR_SESSION_READ_ONLY here.
10661+	 */
10662+	if (persistent == CK_TRUE)
10663+		return (1);
10664+
10665+	rv = pFuncList->C_DestroyObject(session, oh);
10666+	if (rv != CKR_OK)
10667+		{
10668+		PK11err_add_data(PK11_F_DESTROY_OBJECT, PK11_R_DESTROYOBJECT,
10669+		    rv);
10670+		return (0);
10671+		}
10672+
10673+	return (1);
10674+	}
10675+
10676+
10677+/*
10678+ * Public key mechanisms optionally supported
10679+ *
10680+ * CKM_RSA_PKCS
10681+ *
10682+ * The first slot that supports at least one of those mechanisms is chosen as a
10683+ * public key slot.
10684+ *
10685+ * The output of this function is a set of global variables indicating which
10686+ * mechanisms from RSA, DSA, DH and RAND are present, and also two arrays of
10687+ * mechanisms, one for symmetric ciphers and one for digests. Also, 3 global
10688+ * variables carry information about which slot was chosen for (a) public key
10689+ * mechanisms, (b) random operations, and (c) symmetric ciphers and digests.
10690+ */
10691+static int
10692+pk11_choose_slots(int *any_slot_found)
10693+	{
10694+	CK_SLOT_ID_PTR pSlotList = NULL_PTR;
10695+	CK_ULONG ulSlotCount = 0;
10696+	CK_MECHANISM_INFO mech_info;
10697+	CK_TOKEN_INFO token_info;
10698+	unsigned int i;
10699+	CK_RV rv;
10700+	CK_SLOT_ID best_slot_sofar = 0;
10701+	CK_BBOOL found_candidate_slot = CK_FALSE;
10702+	CK_SLOT_ID current_slot = 0;
10703+
10704+	/* let's initialize the output parameter */
10705+	if (any_slot_found != NULL)
10706+		*any_slot_found = 0;
10707+
10708+	/* Get slot list for memory allocation */
10709+	rv = pFuncList->C_GetSlotList(CK_FALSE, NULL_PTR, &ulSlotCount);
10710+
10711+	if (rv != CKR_OK)
10712+		{
10713+		PK11err_add_data(PK11_F_CHOOSE_SLOT, PK11_R_GETSLOTLIST, rv);
10714+		return (0);
10715+		}
10716+
10717+	/* it's not an error if we didn't find any providers */
10718+	if (ulSlotCount == 0)
10719+		{
10720+#ifdef	DEBUG_SLOT_SELECTION
10721+		fprintf(stderr, "%s: no crypto providers found\n", PK11_DBG);
10722+#endif	/* DEBUG_SLOT_SELECTION */
10723+		return (1);
10724+		}
10725+
10726+	pSlotList = OPENSSL_malloc(ulSlotCount * sizeof (CK_SLOT_ID));
10727+
10728+	if (pSlotList == NULL)
10729+		{
10730+		PK11err(PK11_F_CHOOSE_SLOT, PK11_R_MALLOC_FAILURE);
10731+		return (0);
10732+		}
10733+
10734+	/* Get the slot list for processing */
10735+	rv = pFuncList->C_GetSlotList(CK_FALSE, pSlotList, &ulSlotCount);
10736+	if (rv != CKR_OK)
10737+		{
10738+		PK11err_add_data(PK11_F_CHOOSE_SLOT, PK11_R_GETSLOTLIST, rv);
10739+		OPENSSL_free(pSlotList);
10740+		return (0);
10741+		}
10742+
10743+#ifdef	DEBUG_SLOT_SELECTION
10744+	fprintf(stderr, "%s: provider: %s\n", PK11_DBG, def_PK11_LIBNAME);
10745+	fprintf(stderr, "%s: number of slots: %d\n", PK11_DBG, ulSlotCount);
10746+
10747+	fprintf(stderr, "%s: == checking rand slots ==\n", PK11_DBG);
10748+#endif	/* DEBUG_SLOT_SELECTION */
10749+	for (i = 0; i < ulSlotCount; i++)
10750+		{
10751+		current_slot = pSlotList[i];
10752+
10753+#ifdef	DEBUG_SLOT_SELECTION
10754+	fprintf(stderr, "%s: checking slot: %d\n", PK11_DBG, i);
10755+#endif	/* DEBUG_SLOT_SELECTION */
10756+		/* Check if slot has random support. */
10757+		rv = pFuncList->C_GetTokenInfo(current_slot, &token_info);
10758+		if (rv != CKR_OK)
10759+			continue;
10760+
10761+#ifdef	DEBUG_SLOT_SELECTION
10762+	fprintf(stderr, "%s: token label: %.32s\n", PK11_DBG, token_info.label);
10763+#endif	/* DEBUG_SLOT_SELECTION */
10764+
10765+		if (token_info.flags & CKF_RNG)
10766+			{
10767+#ifdef	DEBUG_SLOT_SELECTION
10768+	fprintf(stderr, "%s: this token has CKF_RNG flag\n", PK11_DBG);
10769+#endif	/* DEBUG_SLOT_SELECTION */
10770+			pk11_have_random = CK_TRUE;
10771+			rand_SLOTID = current_slot;
10772+			break;
10773+			}
10774+		}
10775+
10776+#ifdef	DEBUG_SLOT_SELECTION
10777+	fprintf(stderr, "%s: == checking pubkey slots ==\n", PK11_DBG);
10778+#endif	/* DEBUG_SLOT_SELECTION */
10779+
10780+	pubkey_SLOTID = pSlotList[0];
10781+	for (i = 0; i < ulSlotCount; i++)
10782+		{
10783+		CK_BBOOL slot_has_rsa = CK_FALSE;
10784+		current_slot = pSlotList[i];
10785+
10786+#ifdef	DEBUG_SLOT_SELECTION
10787+	fprintf(stderr, "%s: checking slot: %d\n", PK11_DBG, i);
10788+#endif	/* DEBUG_SLOT_SELECTION */
10789+		rv = pFuncList->C_GetTokenInfo(current_slot, &token_info);
10790+		if (rv != CKR_OK)
10791+			continue;
10792+
10793+#ifdef	DEBUG_SLOT_SELECTION
10794+	fprintf(stderr, "%s: token label: %.32s\n", PK11_DBG, token_info.label);
10795+#endif	/* DEBUG_SLOT_SELECTION */
10796+
10797+		/*
10798+		 * Check if this slot is capable of signing with CKM_RSA_PKCS.
10799+		 */
10800+		rv = pFuncList->C_GetMechanismInfo(current_slot, CKM_RSA_PKCS,
10801+			&mech_info);
10802+
10803+		if (rv == CKR_OK && ((mech_info.flags & CKF_SIGN)))
10804+			{
10805+			slot_has_rsa = CK_TRUE;
10806+			}
10807+
10808+		if (!found_candidate_slot && slot_has_rsa)
10809+			{
10810+#ifdef	DEBUG_SLOT_SELECTION
10811+			fprintf(stderr,
10812+			    "%s: potential slot: %d\n", PK11_DBG, current_slot);
10813+#endif	/* DEBUG_SLOT_SELECTION */
10814+			best_slot_sofar = current_slot;
10815+			pk11_have_rsa = slot_has_rsa;
10816+			found_candidate_slot = CK_TRUE;
10817+			/*
10818+			 * Cache the flags for later use. We might
10819+			 * need those if RSA keys by reference feature
10820+			 * is used.
10821+			 */
10822+			pubkey_token_flags = token_info.flags;
10823+#ifdef	DEBUG_SLOT_SELECTION
10824+			fprintf(stderr,
10825+			    "%s: setting found_candidate_slot to CK_TRUE\n",
10826+			    PK11_DBG);
10827+			fprintf(stderr,
10828+			    "%s: best so far slot: %d\n", PK11_DBG,
10829+			    best_slot_sofar);
10830+			fprintf(stderr, "%s: pubkey flags changed to "
10831+			    "%lu.\n", PK11_DBG, pubkey_token_flags);
10832+			}
10833+		else
10834+			{
10835+			fprintf(stderr,
10836+			    "%s: no rsa\n", PK11_DBG);
10837+			}
10838+#else
10839+			} /* if */
10840+#endif	/* DEBUG_SLOT_SELECTION */
10841+		} /* for */
10842+
10843+	if (found_candidate_slot == CK_TRUE)
10844+		{
10845+		pubkey_SLOTID = best_slot_sofar;
10846+		}
10847+
10848+	/*SLOTID = pSlotList[0];*/
10849+
10850+#ifdef	DEBUG_SLOT_SELECTION
10851+	fprintf(stderr,
10852+	    "%s: chosen pubkey slot: %d\n", PK11_DBG, pubkey_SLOTID);
10853+	fprintf(stderr,
10854+	    "%s: chosen rand slot: %d\n", PK11_DBG, rand_SLOTID);
10855+	fprintf(stderr,
10856+	    "%s: pk11_have_rsa %d\n", PK11_DBG, pk11_have_rsa);
10857+	fprintf(stderr,
10858+	    "%s: pk11_have_random %d\n", PK11_DBG, pk11_have_random);
10859+#endif	/* DEBUG_SLOT_SELECTION */
10860+
10861+	if (pSlotList != NULL)
10862+		OPENSSL_free(pSlotList);
10863+
10864+	if (any_slot_found != NULL)
10865+		*any_slot_found = 1;
10866+	return (1);
10867+	}
10868+
10869+#endif	/* OPENSSL_NO_HW_PK11SO */
10870+#endif	/* OPENSSL_NO_HW_PK11 */
10871+#endif	/* OPENSSL_NO_HW */
10872Index: openssl/crypto/engine/hw_pk11so.h
10873diff -u /dev/null openssl/crypto/engine/hw_pk11so.h:1.4
10874--- /dev/null	Mon Jan 16 18:54:23 2012
10875+++ openssl/crypto/engine/hw_pk11so.h	Wed Jun 15 21:12:20 2011
10876@@ -0,0 +1,32 @@
10877+/* Redefine all pk11/PK11 external symbols to pk11so/PK11SO */
10878+
10879+#define token_lock			pk11so_token_lock
10880+#define find_lock			pk11so_find_lock
10881+#define active_list			pk11so_active_list
10882+#define pubkey_token_flags		pk11so_pubkey_token_flags
10883+#define pubkey_SLOTID			pk11so_pubkey_SLOTID
10884+#define ERR_pk11_error			ERR_pk11so_error
10885+#define PK11err_add_data		PK11SOerr_add_data
10886+#define pk11_get_session		pk11so_get_session
10887+#define pk11_return_session		pk11so_return_session
10888+#define pk11_active_add			pk11so_active_add
10889+#define pk11_active_delete		pk11so_active_delete
10890+#define pk11_active_remove		pk11so_active_remove
10891+#define pk11_free_active_list		pk11so_free_active_list
10892+#define pk11_destroy_rsa_key_objects	pk11so_destroy_rsa_key_objects
10893+#define pk11_destroy_rsa_object_pub	pk11so_destroy_rsa_object_pub
10894+#define pk11_destroy_rsa_object_priv	pk11so_destroy_rsa_object_priv
10895+#define pk11_load_privkey		pk11so_load_privkey
10896+#define pk11_load_pubkey		pk11so_load_pubkey
10897+#define PK11_RSA			PK11SO_RSA
10898+#define pk11_destroy_dsa_key_objects	pk11so_destroy_dsa_key_objects
10899+#define pk11_destroy_dsa_object_pub	pk11so_destroy_dsa_object_pub
10900+#define pk11_destroy_dsa_object_priv	pk11so_destroy_dsa_object_priv
10901+#define PK11_DSA			PK11SO_DSA
10902+#define pk11_destroy_dh_key_objects	pk11so_destroy_dh_key_objects
10903+#define pk11_destroy_dh_object		pk11so_destroy_dh_object
10904+#define PK11_DH				PK11SO_DH
10905+#define pk11_token_relogin		pk11so_token_relogin
10906+#define pFuncList			pk11so_pFuncList
10907+#define pk11_pin			pk11so_pin
10908+#define ENGINE_load_pk11		ENGINE_load_pk11so
10909Index: openssl/crypto/engine/hw_pk11so_pub.c
10910diff -u /dev/null openssl/crypto/engine/hw_pk11so_pub.c:1.7
10911--- /dev/null	Mon Jan 16 18:54:23 2012
10912+++ openssl/crypto/engine/hw_pk11so_pub.c	Fri Jun 17 07:55:25 2011
10913@@ -0,0 +1,1622 @@
10914+/*
10915+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
10916+ * Use is subject to license terms.
10917+ */
10918+
10919+/* crypto/engine/hw_pk11_pub.c */
10920+/*
10921+ * This product includes software developed by the OpenSSL Project for
10922+ * use in the OpenSSL Toolkit (http://www.openssl.org/).
10923+ *
10924+ * This project also referenced hw_pkcs11-0.9.7b.patch written by
10925+ * Afchine Madjlessi.
10926+ */
10927+/*
10928+ * ====================================================================
10929+ * Copyright (c) 2000-2001 The OpenSSL Project.  All rights reserved.
10930+ *
10931+ * Redistribution and use in source and binary forms, with or without
10932+ * modification, are permitted provided that the following conditions
10933+ * are met:
10934+ *
10935+ * 1. Redistributions of source code must retain the above copyright
10936+ *    notice, this list of conditions and the following disclaimer.
10937+ *
10938+ * 2. Redistributions in binary form must reproduce the above copyright
10939+ *    notice, this list of conditions and the following disclaimer in
10940+ *    the documentation and/or other materials provided with the
10941+ *    distribution.
10942+ *
10943+ * 3. All advertising materials mentioning features or use of this
10944+ *    software must display the following acknowledgment:
10945+ *    "This product includes software developed by the OpenSSL Project
10946+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
10947+ *
10948+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
10949+ *    endorse or promote products derived from this software without
10950+ *    prior written permission. For written permission, please contact
10951+ *    licensing@OpenSSL.org.
10952+ *
10953+ * 5. Products derived from this software may not be called "OpenSSL"
10954+ *    nor may "OpenSSL" appear in their names without prior written
10955+ *    permission of the OpenSSL Project.
10956+ *
10957+ * 6. Redistributions of any form whatsoever must retain the following
10958+ *    acknowledgment:
10959+ *    "This product includes software developed by the OpenSSL Project
10960+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
10961+ *
10962+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
10963+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
10964+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
10965+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
10966+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
10967+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
10968+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
10969+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
10970+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
10971+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
10972+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
10973+ * OF THE POSSIBILITY OF SUCH DAMAGE.
10974+ * ====================================================================
10975+ *
10976+ * This product includes cryptographic software written by Eric Young
10977+ * (eay@cryptsoft.com).  This product includes software written by Tim
10978+ * Hudson (tjh@cryptsoft.com).
10979+ *
10980+ */
10981+
10982+/* Modified to keep only RNG and RSA Sign */
10983+
10984+#ifdef OPENSSL_NO_RSA
10985+#error RSA is disabled
10986+#endif
10987+
10988+#include <stdio.h>
10989+#include <stdlib.h>
10990+#include <string.h>
10991+#include <sys/types.h>
10992+
10993+#include <openssl/e_os2.h>
10994+#include <openssl/crypto.h>
10995+#include <cryptlib.h>
10996+#include <openssl/engine.h>
10997+#include <openssl/dso.h>
10998+#include <openssl/err.h>
10999+#include <openssl/bn.h>
11000+#include <openssl/pem.h>
11001+#include <openssl/rsa.h>
11002+#include <openssl/rand.h>
11003+#include <openssl/objects.h>
11004+#include <openssl/x509.h>
11005+
11006+#ifdef OPENSSL_SYS_WIN32
11007+#define NOPTHREADS
11008+typedef int pid_t;
11009+#define HAVE_GETPASSPHRASE
11010+static char *getpassphrase(const char *prompt);
11011+#ifndef NULL_PTR
11012+#define NULL_PTR NULL
11013+#endif
11014+#define CK_DEFINE_FUNCTION(returnType, name) \
11015+	returnType __declspec(dllexport) name
11016+#define CK_DECLARE_FUNCTION(returnType, name) \
11017+	returnType __declspec(dllimport) name
11018+#define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
11019+	returnType __declspec(dllimport) (* name)
11020+#else
11021+#include <unistd.h>
11022+#endif
11023+
11024+#ifndef NOPTHREADS
11025+#include <pthread.h>
11026+#endif
11027+
11028+#ifndef OPENSSL_NO_HW
11029+#ifndef OPENSSL_NO_HW_PK11
11030+#ifndef OPENSSL_NO_HW_PK11SO
11031+
11032+#ifdef OPENSSL_SYS_WIN32
11033+#pragma pack(push, cryptoki, 1)
11034+#include "cryptoki.h"
11035+#include "pkcs11.h"
11036+#pragma pack(pop, cryptoki)
11037+#else
11038+#include "cryptoki.h"
11039+#include "pkcs11.h"
11040+#endif
11041+#include "hw_pk11so.h"
11042+#include "hw_pk11_err.h"
11043+
11044+static CK_BBOOL pk11_login_done = CK_FALSE;
11045+extern CK_SLOT_ID pubkey_SLOTID;
11046+#ifndef NOPTHREADS
11047+extern pthread_mutex_t *token_lock;
11048+#endif
11049+
11050+#if !(defined(HAVE_GETPASSPHRASE) || (defined (__SVR4) && defined (__sun)))
11051+#define getpassphrase(x)	getpass(x)
11052+#endif
11053+
11054+/* RSA stuff */
11055+static int pk11_RSA_sign(int type, const unsigned char *m, unsigned int m_len,
11056+	unsigned char *sigret, unsigned int *siglen, const RSA *rsa);
11057+EVP_PKEY *pk11_load_privkey(ENGINE*, const char *privkey_file,
11058+	UI_METHOD *ui_method, void *callback_data);
11059+EVP_PKEY *pk11_load_pubkey(ENGINE*, const char *pubkey_file,
11060+	UI_METHOD *ui_method, void *callback_data);
11061+
11062+static CK_OBJECT_HANDLE pk11_get_public_rsa_key(RSA* rsa, RSA** key_ptr,
11063+	BIGNUM **rsa_n_num, BIGNUM **rsa_e_num, CK_SESSION_HANDLE session);
11064+static CK_OBJECT_HANDLE pk11_get_private_rsa_key(RSA* rsa, RSA** key_ptr,
11065+	BIGNUM **rsa_d_num, BIGNUM **rsa_n_num, BIGNUM **rsa_e_num,
11066+	CK_SESSION_HANDLE session);
11067+
11068+static int check_new_rsa_key_pub(PK11_SESSION *sp, const RSA *rsa);
11069+static int check_new_rsa_key_priv(PK11_SESSION *sp, const RSA *rsa);
11070+
11071+static int find_one_object(PK11_OPTYPE op, CK_SESSION_HANDLE s,
11072+	CK_ATTRIBUTE_PTR ptempl, CK_ULONG nattr, CK_OBJECT_HANDLE_PTR pkey);
11073+static int init_template_value(BIGNUM *bn, CK_VOID_PTR *pValue,
11074+	CK_ULONG *ulValueLen);
11075+static void attr_to_BN(CK_ATTRIBUTE_PTR attr, CK_BYTE attr_data[], BIGNUM **bn);
11076+
11077+static int pk11_token_login(CK_SESSION_HANDLE session, CK_BBOOL *login_done,
11078+	CK_BBOOL is_private);
11079+
11080+/* Read mode string to be used for fopen() */
11081+#if SOLARIS_OPENSSL
11082+static char *read_mode_flags = "rF";
11083+#else
11084+static char *read_mode_flags = "r";
11085+#endif
11086+
11087+/*
11088+ * increment/create reference for an asymmetric key handle via active list
11089+ * manipulation. If active list operation fails, unlock (if locked), set error
11090+ * variable and jump to the specified label.
11091+ */
11092+#define	KEY_HANDLE_REFHOLD(key_handle, alg_type, unlock, var, label)	\
11093+	{								\
11094+	if (pk11_active_add(key_handle, alg_type) < 0)			\
11095+		{							\
11096+		var = TRUE;						\
11097+		if (unlock)						\
11098+			UNLOCK_OBJSTORE(alg_type);			\
11099+		goto label;						\
11100+		}							\
11101+	}
11102+
11103+/*
11104+ * Find active list entry according to object handle and return pointer to the
11105+ * entry otherwise return NULL.
11106+ *
11107+ * This function presumes it is called with lock protecting the active list
11108+ * held.
11109+ */
11110+static PK11_active *pk11_active_find(CK_OBJECT_HANDLE h, PK11_OPTYPE type)
11111+	{
11112+	PK11_active *entry;
11113+
11114+	for (entry = active_list[type]; entry != NULL; entry = entry->next)
11115+		if (entry->h == h)
11116+			return (entry);
11117+
11118+	return (NULL);
11119+	}
11120+
11121+/*
11122+ * Search for an entry in the active list using PKCS#11 object handle as a
11123+ * search key and return refcnt of the found/created entry or -1 in case of
11124+ * failure.
11125+ *
11126+ * This function presumes it is called with lock protecting the active list
11127+ * held.
11128+ */
11129+int
11130+pk11_active_add(CK_OBJECT_HANDLE h, PK11_OPTYPE type)
11131+	{
11132+	PK11_active *entry = NULL;
11133+
11134+	if (h == CK_INVALID_HANDLE)
11135+		{
11136+		PK11err(PK11_F_ACTIVE_ADD, PK11_R_INVALID_HANDLE);
11137+		return (-1);
11138+		}
11139+
11140+	/* search for entry in the active list */
11141+	if ((entry = pk11_active_find(h, type)) != NULL)
11142+		entry->refcnt++;
11143+	else
11144+		{
11145+		/* not found, create new entry and add it to the list */
11146+		entry = OPENSSL_malloc(sizeof (PK11_active));
11147+		if (entry == NULL)
11148+			{
11149+			PK11err(PK11_F_ACTIVE_ADD, PK11_R_MALLOC_FAILURE);
11150+			return (-1);
11151+			}
11152+		entry->h = h;
11153+		entry->refcnt = 1;
11154+		entry->prev = NULL;
11155+		entry->next = NULL;
11156+		/* connect the newly created entry to the list */
11157+		if (active_list[type] == NULL)
11158+			active_list[type] = entry;
11159+		else /* make the entry first in the list */
11160+			{
11161+			entry->next = active_list[type];
11162+			active_list[type]->prev = entry;
11163+			active_list[type] = entry;
11164+			}
11165+		}
11166+
11167+	return (entry->refcnt);
11168+	}
11169+
11170+/*
11171+ * Remove active list entry from the list and free it.
11172+ *
11173+ * This function presumes it is called with lock protecting the active list
11174+ * held.
11175+ */
11176+void
11177+pk11_active_remove(PK11_active *entry, PK11_OPTYPE type)
11178+	{
11179+	PK11_active *prev_entry;
11180+
11181+	/* remove the entry from the list and free it */
11182+	if ((prev_entry = entry->prev) != NULL)
11183+		{
11184+		prev_entry->next = entry->next;
11185+		if (entry->next != NULL)
11186+			entry->next->prev = prev_entry;
11187+		}
11188+	else
11189+		{
11190+		active_list[type] = entry->next;
11191+		/* we were the first but not the only one */
11192+		if (entry->next != NULL)
11193+			entry->next->prev = NULL;
11194+		}
11195+
11196+	/* sanitization */
11197+	entry->h = CK_INVALID_HANDLE;
11198+	entry->prev = NULL;
11199+	entry->next = NULL;
11200+	OPENSSL_free(entry);
11201+	}
11202+
11203+/* Free all entries from the active list. */
11204+void
11205+pk11_free_active_list(PK11_OPTYPE type)
11206+	{
11207+	PK11_active *entry;
11208+
11209+	/* only for asymmetric types since only they have C_Find* locks. */
11210+	switch (type)
11211+		{
11212+		case OP_RSA:
11213+			break;
11214+		default:
11215+			return;
11216+		}
11217+
11218+	/* see find_lock array definition for more info on object locking */
11219+	LOCK_OBJSTORE(type);
11220+	while ((entry = active_list[type]) != NULL)
11221+		pk11_active_remove(entry, type);
11222+	UNLOCK_OBJSTORE(type);
11223+	}
11224+
11225+/*
11226+ * Search for active list entry associated with given PKCS#11 object handle,
11227+ * decrement its refcnt and if it drops to 0, disconnect the entry and free it.
11228+ *
11229+ * Return 1 if the PKCS#11 object associated with the entry has no references,
11230+ * return 0 if there is at least one reference, -1 on error.
11231+ *
11232+ * This function presumes it is called with lock protecting the active list
11233+ * held.
11234+ */
11235+int
11236+pk11_active_delete(CK_OBJECT_HANDLE h, PK11_OPTYPE type)
11237+	{
11238+	PK11_active *entry = NULL;
11239+
11240+	if ((entry = pk11_active_find(h, type)) == NULL)
11241+		{
11242+		PK11err(PK11_F_ACTIVE_DELETE, PK11_R_INVALID_HANDLE);
11243+		return (-1);
11244+		}
11245+
11246+	OPENSSL_assert(entry->refcnt > 0);
11247+	entry->refcnt--;
11248+	if (entry->refcnt == 0)
11249+		{
11250+		pk11_active_remove(entry, type);
11251+		return (1);
11252+		}
11253+
11254+	return (0);
11255+	}
11256+
11257+/* Our internal RSA_METHOD that we provide pointers to */
11258+static RSA_METHOD pk11_rsa;
11259+
11260+RSA_METHOD *
11261+PK11_RSA(void)
11262+	{
11263+	const RSA_METHOD *rsa;
11264+
11265+	if (pk11_rsa.name == NULL)
11266+		{
11267+		rsa = RSA_PKCS1_SSLeay();
11268+		memcpy(&pk11_rsa, rsa, sizeof(*rsa));
11269+		pk11_rsa.name = "PKCS#11 RSA method";
11270+		pk11_rsa.rsa_sign = pk11_RSA_sign;
11271+		}
11272+	return (&pk11_rsa);
11273+	}
11274+
11275+/* Size of an SSL signature: MD5+SHA1 */
11276+#define	SSL_SIG_LENGTH		36
11277+
11278+static CK_BBOOL true = TRUE;
11279+static CK_BBOOL false = FALSE;
11280+
11281+/*
11282+ * Standard engine interface function. Majority codes here are from
11283+ * rsa/rsa_sign.c. We replaced the decrypt function call by C_Sign of PKCS#11.
11284+ * See more details in rsa/rsa_sign.c
11285+ */
11286+static int pk11_RSA_sign(int type, const unsigned char *m, unsigned int m_len,
11287+	unsigned char *sigret, unsigned int *siglen, const RSA *rsa)
11288+	{
11289+	X509_SIG sig;
11290+	ASN1_TYPE parameter;
11291+	int i, j = 0;
11292+	unsigned char *p, *s = NULL;
11293+	X509_ALGOR algor;
11294+	ASN1_OCTET_STRING digest;
11295+	CK_RV rv;
11296+	CK_MECHANISM mech_rsa = {CKM_RSA_PKCS, NULL, 0};
11297+	CK_MECHANISM *p_mech = &mech_rsa;
11298+	CK_OBJECT_HANDLE h_priv_key;
11299+	PK11_SESSION *sp = NULL;
11300+	int ret = 0;
11301+	unsigned long ulsiglen;
11302+
11303+	/* Encode the digest */
11304+	/* Special case: SSL signature, just check the length */
11305+	if (type == NID_md5_sha1)
11306+		{
11307+		if (m_len != SSL_SIG_LENGTH)
11308+			{
11309+			PK11err(PK11_F_RSA_SIGN,
11310+				PK11_R_INVALID_MESSAGE_LENGTH);
11311+			goto err;
11312+			}
11313+		i = SSL_SIG_LENGTH;
11314+		s = (unsigned char *)m;
11315+		}
11316+	else
11317+		{
11318+		sig.algor = &algor;
11319+		sig.algor->algorithm = OBJ_nid2obj(type);
11320+		if (sig.algor->algorithm == NULL)
11321+			{
11322+			PK11err(PK11_F_RSA_SIGN,
11323+				PK11_R_UNKNOWN_ALGORITHM_TYPE);
11324+			goto err;
11325+			}
11326+		if (sig.algor->algorithm->length == 0)
11327+			{
11328+			PK11err(PK11_F_RSA_SIGN,
11329+				PK11_R_UNKNOWN_ASN1_OBJECT_ID);
11330+			goto err;
11331+			}
11332+		parameter.type = V_ASN1_NULL;
11333+		parameter.value.ptr = NULL;
11334+		sig.algor->parameter = &parameter;
11335+
11336+		sig.digest = &digest;
11337+		sig.digest->data = (unsigned char *)m;
11338+		sig.digest->length = m_len;
11339+
11340+		i = i2d_X509_SIG(&sig, NULL);
11341+		}
11342+
11343+	j = RSA_size(rsa);
11344+	if ((i - RSA_PKCS1_PADDING) > j)
11345+		{
11346+		PK11err(PK11_F_RSA_SIGN, PK11_R_DIGEST_TOO_BIG);
11347+		goto err;
11348+		}
11349+
11350+	if (type != NID_md5_sha1)
11351+		{
11352+		s = (unsigned char *)OPENSSL_malloc((unsigned int)(j + 1));
11353+		if (s == NULL)
11354+			{
11355+			PK11err(PK11_F_RSA_SIGN, PK11_R_MALLOC_FAILURE);
11356+			goto err;
11357+			}
11358+		p = s;
11359+		(void) i2d_X509_SIG(&sig, &p);
11360+		}
11361+
11362+	if ((sp = pk11_get_session(OP_RSA)) == NULL)
11363+		goto err;
11364+
11365+	(void) check_new_rsa_key_priv(sp, rsa);
11366+
11367+	h_priv_key = sp->opdata_rsa_priv_key;
11368+	if (h_priv_key == CK_INVALID_HANDLE)
11369+		h_priv_key = sp->opdata_rsa_priv_key =
11370+			pk11_get_private_rsa_key((RSA *)rsa,
11371+			    &sp->opdata_rsa_priv, &sp->opdata_rsa_d_num,
11372+			    &sp->opdata_rsa_pn_num, &sp->opdata_rsa_pe_num,
11373+			    sp->session);
11374+
11375+	if (h_priv_key != CK_INVALID_HANDLE)
11376+		{
11377+		rv = pFuncList->C_SignInit(sp->session, p_mech, h_priv_key);
11378+
11379+		if (rv != CKR_OK)
11380+			{
11381+			PK11err_add_data(PK11_F_RSA_SIGN, PK11_R_SIGNINIT, rv);
11382+			goto err;
11383+			}
11384+
11385+		ulsiglen = j;
11386+		rv = pFuncList->C_Sign(sp->session, s, i, sigret,
11387+			(CK_ULONG_PTR) &ulsiglen);
11388+		*siglen = ulsiglen;
11389+
11390+		if (rv != CKR_OK)
11391+			{
11392+			PK11err_add_data(PK11_F_RSA_SIGN, PK11_R_SIGN, rv);
11393+			goto err;
11394+			}
11395+		ret = 1;
11396+		}
11397+
11398+err:
11399+	if ((type != NID_md5_sha1) && (s != NULL))
11400+		{
11401+		(void) memset(s, 0, (unsigned int)(j + 1));
11402+		OPENSSL_free(s);
11403+		}
11404+
11405+	pk11_return_session(sp, OP_RSA);
11406+	return (ret);
11407+	}
11408+
11409+static int hndidx_rsa = -1;
11410+
11411+#define	MAXATTR	1024
11412+
11413+/*
11414+ * Load RSA private key from a file or get its PKCS#11 handle if stored in the
11415+ * PKCS#11 token.
11416+ */
11417+/* ARGSUSED */
11418+EVP_PKEY *pk11_load_privkey(ENGINE *e, const char *privkey_file,
11419+	UI_METHOD *ui_method, void *callback_data)
11420+	{
11421+	EVP_PKEY *pkey = NULL;
11422+	FILE *privkey;
11423+	CK_OBJECT_HANDLE  h_priv_key = CK_INVALID_HANDLE;
11424+	RSA *rsa = NULL;
11425+	PK11_SESSION *sp;
11426+	/* Anything else below is needed for the key by reference extension. */
11427+	CK_RV rv;
11428+	CK_BBOOL is_token = TRUE;
11429+	CK_BBOOL rollback = FALSE;
11430+	CK_BYTE attr_data[2][MAXATTR];
11431+	CK_OBJECT_CLASS key_class = CKO_PRIVATE_KEY;
11432+	CK_OBJECT_HANDLE ks_key = CK_INVALID_HANDLE;	/* key in keystore */
11433+
11434+	/* we look for private keys only */
11435+	CK_ATTRIBUTE search_templ[] =
11436+		{
11437+		{CKA_TOKEN, &is_token, sizeof(is_token)},
11438+		{CKA_CLASS, &key_class, sizeof(key_class)},
11439+		{CKA_LABEL, NULL, 0}
11440+		};
11441+
11442+	/*
11443+	 * These public attributes are needed to initialize the OpenSSL RSA
11444+	 * structure with something we can use to look up the key. Note that we
11445+	 * never ask for private components.
11446+	 */
11447+	CK_ATTRIBUTE get_templ[] =
11448+		{
11449+		{CKA_MODULUS, (void *)attr_data[0], MAXATTR},		/* n */
11450+		{CKA_PUBLIC_EXPONENT, (void *)attr_data[1], MAXATTR},	/* e */
11451+		};
11452+
11453+	if ((sp = pk11_get_session(OP_RSA)) == NULL)
11454+		return (NULL);
11455+
11456+	/*
11457+	 * Use simple scheme "pkcs11:<KEY_LABEL>" for now.
11458+	 */
11459+	if (strstr(privkey_file, "pkcs11:") == privkey_file)
11460+		{
11461+		search_templ[2].pValue = strstr(privkey_file, ":") + 1;
11462+		search_templ[2].ulValueLen = strlen(search_templ[2].pValue);
11463+
11464+		if (pk11_token_login(sp->session, &pk11_login_done,
11465+		    CK_TRUE) == 0)
11466+			goto err;
11467+
11468+		/*
11469+		 * Now let's try to find the key in the token. It is a failure
11470+		 * if we can't find it.
11471+		 */
11472+		if (find_one_object(OP_RSA, sp->session, search_templ, 3,
11473+		    &ks_key) == 0)
11474+			goto err;
11475+
11476+		if (hndidx_rsa == -1)
11477+			hndidx_rsa = RSA_get_ex_new_index(0,
11478+				        "pkcs11 RSA HSM key handle",
11479+					NULL, NULL, NULL);
11480+
11481+		/*
11482+		 * We might have a cache hit which we could confirm
11483+		 * according to the 'n'/'e' params, RSA public pointer
11484+		 * as NULL, and non-NULL RSA private pointer. However,
11485+		 * it is easier just to recreate everything. We expect
11486+		 * the keys to be loaded once and used many times. We
11487+		 * do not check the return value because even in case
11488+		 * of failure the sp structure will have both key
11489+		 * pointer and object handle cleaned and
11490+		 * pk11_destroy_object() reports the failure to the
11491+		 * OpenSSL error message buffer.
11492+		 */
11493+		(void) pk11_destroy_rsa_object_priv(sp, TRUE);
11494+
11495+		sp->opdata_rsa_priv_key = ks_key;
11496+		/* This object shall not be deleted on a cache miss. */
11497+		sp->priv_persistent = CK_TRUE;
11498+
11499+		/*
11500+		 * Cache the RSA private structure pointer. We do not
11501+		 * use it now for key-by-ref keys but let's do it for
11502+		 * consistency reasons.
11503+		 */
11504+		if ((rsa = sp->opdata_rsa_priv = RSA_new_method(e)) == NULL)
11505+			goto err;
11506+
11507+		/*
11508+		 * Now we have to initialize an OpenSSL RSA structure,
11509+		 * everything else is 0 or NULL.
11510+		 */
11511+		rsa->flags = RSA_FLAG_SIGN_VER | RSA_FLAG_EXT_PKEY;
11512+		RSA_set_ex_data(rsa, hndidx_rsa, (void *) ks_key);
11513+
11514+		if ((rv = pFuncList->C_GetAttributeValue(sp->session, ks_key,
11515+		    get_templ, 2)) != CKR_OK)
11516+			{
11517+			PK11err_add_data(PK11_F_LOAD_PRIVKEY,
11518+					 PK11_R_GETATTRIBUTVALUE, rv);
11519+			goto err;
11520+			}
11521+
11522+		/*
11523+		 * We do not use pk11_get_private_rsa_key() here so we
11524+		 * must take care of handle management ourselves.
11525+		 */
11526+		KEY_HANDLE_REFHOLD(ks_key, OP_RSA, FALSE, rollback, err);
11527+
11528+		/*
11529+		 * Those are the sensitive components we do not want to export
11530+		 * from the token at all: rsa->(d|p|q|dmp1|dmq1|iqmp).
11531+		 */
11532+		attr_to_BN(&get_templ[0], attr_data[0], &rsa->n);
11533+		attr_to_BN(&get_templ[1], attr_data[1], &rsa->e);
11534+		/*
11535+		 * Must have 'n'/'e' components in the session structure as
11536+		 * well. They serve as a public look-up key for the private key
11537+		 * in the keystore.
11538+		 */
11539+		attr_to_BN(&get_templ[0], attr_data[0],
11540+			&sp->opdata_rsa_pn_num);
11541+		attr_to_BN(&get_templ[1], attr_data[1],
11542+			&sp->opdata_rsa_pe_num);
11543+
11544+		if ((pkey = EVP_PKEY_new()) == NULL)
11545+			goto err;
11546+
11547+		if (EVP_PKEY_assign_RSA(pkey, rsa) == 0)
11548+			goto err;
11549+		}
11550+	else if ((privkey = fopen(privkey_file, read_mode_flags)) != NULL)
11551+		{
11552+		pkey = PEM_read_PrivateKey(privkey, NULL, NULL, NULL);
11553+		(void) fclose(privkey);
11554+		if (pkey != NULL)
11555+			{
11556+			rsa = EVP_PKEY_get1_RSA(pkey);
11557+			if (rsa != NULL)
11558+				{
11559+				/*
11560+				 * This will always destroy the RSA
11561+				 * object since we have a new RSA
11562+				 * structure here.
11563+				 */
11564+				(void) check_new_rsa_key_priv(sp, rsa);
11565+				sp->priv_persistent = CK_FALSE;
11566+
11567+				h_priv_key = sp->opdata_rsa_priv_key =
11568+				    pk11_get_private_rsa_key(rsa,
11569+				    &sp->opdata_rsa_priv,
11570+				    &sp->opdata_rsa_d_num,
11571+				    &sp->opdata_rsa_pn_num,
11572+				    &sp->opdata_rsa_pe_num, sp->session);
11573+				if (h_priv_key == CK_INVALID_HANDLE)
11574+					goto err;
11575+				}
11576+			else
11577+				goto err;
11578+			}
11579+		}
11580+
11581+	pk11_return_session(sp, OP_RSA);
11582+	return (pkey);
11583+err:
11584+	pk11_return_session(sp, OP_RSA);
11585+	if (rsa != NULL)
11586+		RSA_free(rsa);
11587+	if (pkey != NULL)
11588+		{
11589+		EVP_PKEY_free(pkey);
11590+		pkey = NULL;
11591+		}
11592+	rollback = rollback;
11593+	return (pkey);
11594+	}
11595+
11596+/*
11597+ * Load RSA public key from a file or get its PKCS#11 handle if stored in the
11598+ * PKCS#11 token.
11599+ */
11600+/* ARGSUSED */
11601+EVP_PKEY *pk11_load_pubkey(ENGINE *e, const char *pubkey_file,
11602+	UI_METHOD *ui_method, void *callback_data)
11603+	{
11604+	EVP_PKEY *pkey = NULL;
11605+	FILE *pubkey;
11606+	CK_OBJECT_HANDLE h_pub_key = CK_INVALID_HANDLE;
11607+	RSA *rsa = NULL;
11608+	PK11_SESSION *sp;
11609+	/* Anything else below is needed for the key by reference extension. */
11610+	CK_RV rv;
11611+	CK_BBOOL is_token = TRUE;
11612+	CK_BYTE attr_data[2][MAXATTR];
11613+	CK_OBJECT_CLASS key_class = CKO_PUBLIC_KEY;
11614+	CK_OBJECT_HANDLE ks_key = CK_INVALID_HANDLE;	/* key in keystore */
11615+
11616+	/* we look for public keys only */
11617+	CK_ATTRIBUTE search_templ[] =
11618+		{
11619+		{CKA_TOKEN, &is_token, sizeof(is_token)},
11620+		{CKA_CLASS, &key_class, sizeof(key_class)},
11621+		{CKA_LABEL, NULL, 0}
11622+		};
11623+
11624+	/*
11625+	 * These public attributes are needed to initialize OpenSSL RSA
11626+	 * structure with something we can use to look up the key.
11627+	 */
11628+	CK_ATTRIBUTE get_templ[] =
11629+		{
11630+		{CKA_MODULUS, (void *)attr_data[0], MAXATTR},		/* n */
11631+		{CKA_PUBLIC_EXPONENT, (void *)attr_data[1], MAXATTR},	/* e */
11632+		};
11633+
11634+	if ((sp = pk11_get_session(OP_RSA)) == NULL)
11635+		return (NULL);
11636+
11637+	/*
11638+	 * Use simple scheme "pkcs11:<KEY_LABEL>" for now.
11639+	 */
11640+	if (strstr(pubkey_file, "pkcs11:") == pubkey_file)
11641+		{
11642+		search_templ[2].pValue = strstr(pubkey_file, ":") + 1;
11643+		search_templ[2].ulValueLen = strlen(search_templ[2].pValue);
11644+
11645+		if (pk11_token_login(sp->session, &pk11_login_done,
11646+		    CK_FALSE) == 0)
11647+			goto err;
11648+
11649+		/*
11650+		 * Now let's try to find the key in the token. It is a failure
11651+		 * if we can't find it.
11652+		 */
11653+		if (find_one_object(OP_RSA, sp->session, search_templ, 3,
11654+		    &ks_key) == 0)
11655+			goto err;
11656+
11657+		/*
11658+		 * We load a new public key so we will create a new RSA
11659+		 * structure. No cache hit is possible.
11660+		 */
11661+		(void) pk11_destroy_rsa_object_pub(sp, TRUE);
11662+
11663+		sp->opdata_rsa_pub_key = ks_key;
11664+		/* This object shall not be deleted on a cache miss. */
11665+		sp->pub_persistent = CK_TRUE;
11666+
11667+		/*
11668+		 * Cache the RSA public structure pointer.
11669+		 */
11670+		if ((rsa = sp->opdata_rsa_pub = RSA_new_method(e)) == NULL)
11671+			goto err;
11672+
11673+		/*
11674+		 * Now we have to initialize an OpenSSL RSA structure,
11675+		 * everything else is 0 or NULL.
11676+		 */
11677+		rsa->flags = RSA_FLAG_SIGN_VER;
11678+
11679+		if ((rv = pFuncList->C_GetAttributeValue(sp->session, ks_key,
11680+		    get_templ, 2)) != CKR_OK)
11681+			{
11682+			PK11err_add_data(PK11_F_LOAD_PUBKEY,
11683+					 PK11_R_GETATTRIBUTVALUE, rv);
11684+			goto err;
11685+			}
11686+
11687+		attr_to_BN(&get_templ[0], attr_data[0], &rsa->n);
11688+		attr_to_BN(&get_templ[1], attr_data[1], &rsa->e);
11689+
11690+		if ((pkey = EVP_PKEY_new()) == NULL)
11691+			goto err;
11692+
11693+		if (EVP_PKEY_assign_RSA(pkey, rsa) == 0)
11694+			goto err;
11695+
11696+		/*
11697+		 * Create a session object from it so that when calling
11698+		 * pk11_get_public_rsa_key() the next time, we can find it. The
11699+		 * reason why we do that is that we cannot tell from the RSA
11700+		 * structure (OpenSSL RSA structure does not have any room for
11701+		 * additional data used by the engine, for example) if it bears
11702+		 * a public key stored in the keystore or not so it's better if
11703+		 * we always have a session key. Note that this is different
11704+		 * from what we do for the private keystore objects but in that
11705+		 * case, we can tell from the RSA structure that the keystore
11706+		 * object is in play - the 'd' component is NULL in that case.
11707+		 */
11708+		h_pub_key = sp->opdata_rsa_pub_key =
11709+		    pk11_get_public_rsa_key(rsa,
11710+		    &sp->opdata_rsa_pub, &sp->opdata_rsa_n_num,
11711+		    &sp->opdata_rsa_e_num, sp->session);
11712+		if (h_pub_key == CK_INVALID_HANDLE)
11713+			goto err;
11714+		}
11715+	else if ((pubkey = fopen(pubkey_file, read_mode_flags)) != NULL)
11716+		{
11717+		pkey = PEM_read_PUBKEY(pubkey, NULL, NULL, NULL);
11718+		(void) fclose(pubkey);
11719+		if (pkey != NULL)
11720+			{
11721+			rsa = EVP_PKEY_get1_RSA(pkey);
11722+			if (rsa != NULL)
11723+				{
11724+				/*
11725+				 * This will always destroy the RSA
11726+				 * object since we have a new RSA
11727+				 * structure here.
11728+				 */
11729+				(void) check_new_rsa_key_pub(sp, rsa);
11730+				sp->pub_persistent = CK_FALSE;
11731+
11732+				h_pub_key = sp->opdata_rsa_pub_key =
11733+				    pk11_get_public_rsa_key(rsa,
11734+				    &sp->opdata_rsa_pub, &sp->opdata_rsa_n_num,
11735+				    &sp->opdata_rsa_e_num, sp->session);
11736+				if (h_pub_key == CK_INVALID_HANDLE)
11737+					goto err;
11738+				}
11739+			else
11740+				goto err;
11741+			}
11742+		}
11743+
11744+	pk11_return_session(sp, OP_RSA);
11745+	return (pkey);
11746+err:
11747+	pk11_return_session(sp, OP_RSA);
11748+	if (rsa != NULL)
11749+		RSA_free(rsa);
11750+	if (pkey != NULL)
11751+		{
11752+		EVP_PKEY_free(pkey);
11753+		pkey = NULL;
11754+		}
11755+	return (pkey);
11756+	}
11757+
11758+/*
11759+ * Create a public key object in a session from a given rsa structure.
11760+ * The *rsa_n_num and *rsa_e_num pointers are non-NULL for RSA public keys.
11761+ */
11762+static CK_OBJECT_HANDLE pk11_get_public_rsa_key(RSA *rsa,
11763+    RSA **key_ptr, BIGNUM **rsa_n_num, BIGNUM **rsa_e_num,
11764+    CK_SESSION_HANDLE session)
11765+	{
11766+	CK_RV rv;
11767+	CK_OBJECT_HANDLE h_key = CK_INVALID_HANDLE;
11768+	CK_ULONG found;
11769+	CK_OBJECT_CLASS o_key = CKO_PUBLIC_KEY;
11770+	CK_KEY_TYPE k_type = CKK_RSA;
11771+	CK_ULONG ul_key_attr_count = 8;
11772+	CK_BBOOL rollback = FALSE;
11773+
11774+	CK_ATTRIBUTE  a_key_template[] =
11775+		{
11776+		{CKA_CLASS, (void *) NULL, sizeof (CK_OBJECT_CLASS)},
11777+		{CKA_KEY_TYPE, (void *) NULL, sizeof (CK_KEY_TYPE)},
11778+		{CKA_TOKEN, &false, sizeof (true)},
11779+		{CKA_ENCRYPT, &true, sizeof (true)},
11780+		{CKA_VERIFY, &true, sizeof (true)},
11781+		{CKA_VERIFY_RECOVER, &true, sizeof (true)},
11782+		{CKA_MODULUS, (void *)NULL, 0},
11783+		{CKA_PUBLIC_EXPONENT, (void *)NULL, 0}
11784+		};
11785+
11786+	int i;
11787+
11788+	a_key_template[0].pValue = &o_key;
11789+	a_key_template[1].pValue = &k_type;
11790+
11791+	a_key_template[6].ulValueLen = BN_num_bytes(rsa->n);
11792+	a_key_template[6].pValue = (CK_VOID_PTR)OPENSSL_malloc(
11793+		(size_t)a_key_template[6].ulValueLen);
11794+	if (a_key_template[6].pValue == NULL)
11795+		{
11796+		PK11err(PK11_F_GET_PUB_RSA_KEY, PK11_R_MALLOC_FAILURE);
11797+		goto malloc_err;
11798+		}
11799+
11800+	BN_bn2bin(rsa->n, a_key_template[6].pValue);
11801+
11802+	a_key_template[7].ulValueLen = BN_num_bytes(rsa->e);
11803+	a_key_template[7].pValue = (CK_VOID_PTR)OPENSSL_malloc(
11804+		(size_t)a_key_template[7].ulValueLen);
11805+	if (a_key_template[7].pValue == NULL)
11806+		{
11807+		PK11err(PK11_F_GET_PUB_RSA_KEY, PK11_R_MALLOC_FAILURE);
11808+		goto malloc_err;
11809+		}
11810+
11811+	BN_bn2bin(rsa->e, a_key_template[7].pValue);
11812+
11813+	/* see find_lock array definition for more info on object locking */
11814+	LOCK_OBJSTORE(OP_RSA);
11815+
11816+	rv = pFuncList->C_FindObjectsInit(session, a_key_template,
11817+		ul_key_attr_count);
11818+
11819+	if (rv != CKR_OK)
11820+		{
11821+		PK11err_add_data(PK11_F_GET_PUB_RSA_KEY,
11822+		    PK11_R_FINDOBJECTSINIT, rv);
11823+		goto err;
11824+		}
11825+
11826+	rv = pFuncList->C_FindObjects(session, &h_key, 1, &found);
11827+
11828+	if (rv != CKR_OK)
11829+		{
11830+		PK11err_add_data(PK11_F_GET_PUB_RSA_KEY,
11831+		    PK11_R_FINDOBJECTS, rv);
11832+		goto err;
11833+		}
11834+
11835+	rv = pFuncList->C_FindObjectsFinal(session);
11836+
11837+	if (rv != CKR_OK)
11838+		{
11839+		PK11err_add_data(PK11_F_GET_PUB_RSA_KEY,
11840+		    PK11_R_FINDOBJECTSFINAL, rv);
11841+		goto err;
11842+		}
11843+
11844+	if (found == 0)
11845+		{
11846+		rv = pFuncList->C_CreateObject(session,
11847+			a_key_template, ul_key_attr_count, &h_key);
11848+		if (rv != CKR_OK)
11849+			{
11850+			PK11err_add_data(PK11_F_GET_PUB_RSA_KEY,
11851+			    PK11_R_CREATEOBJECT, rv);
11852+			goto err;
11853+			}
11854+		}
11855+
11856+	if (rsa_n_num != NULL)
11857+		if ((*rsa_n_num = BN_dup(rsa->n)) == NULL)
11858+			{
11859+			PK11err(PK11_F_GET_PUB_RSA_KEY, PK11_R_MALLOC_FAILURE);
11860+			rollback = TRUE;
11861+			goto err;
11862+			}
11863+	if (rsa_e_num != NULL)
11864+		if ((*rsa_e_num = BN_dup(rsa->e)) == NULL)
11865+			{
11866+			PK11err(PK11_F_GET_PUB_RSA_KEY, PK11_R_MALLOC_FAILURE);
11867+			BN_free(*rsa_n_num);
11868+			*rsa_n_num = NULL;
11869+			rollback = TRUE;
11870+			goto err;
11871+			}
11872+
11873+	/* LINTED: E_CONSTANT_CONDITION */
11874+	KEY_HANDLE_REFHOLD(h_key, OP_RSA, FALSE, rollback, err);
11875+	if (key_ptr != NULL)
11876+		*key_ptr = rsa;
11877+
11878+err:
11879+	if (rollback)
11880+		{
11881+		/*
11882+		 * We do not care about the return value from C_DestroyObject()
11883+		 * since we are doing rollback.
11884+		 */
11885+		if (found == 0)
11886+			(void) pFuncList->C_DestroyObject(session, h_key);
11887+		h_key = CK_INVALID_HANDLE;
11888+		}
11889+
11890+	UNLOCK_OBJSTORE(OP_RSA);
11891+
11892+malloc_err:
11893+	for (i = 6; i <= 7; i++)
11894+		{
11895+		if (a_key_template[i].pValue != NULL)
11896+			{
11897+			OPENSSL_free(a_key_template[i].pValue);
11898+			a_key_template[i].pValue = NULL;
11899+			}
11900+		}
11901+
11902+	return (h_key);
11903+	}
11904+
11905+/*
11906+ * Create a private key object in the session from a given rsa structure.
11907+ * The *rsa_d_num pointer is non-NULL for RSA private keys.
11908+ */
11909+static CK_OBJECT_HANDLE
11910+pk11_get_private_rsa_key(RSA *rsa, RSA **key_ptr, BIGNUM **rsa_d_num,
11911+    BIGNUM **rsa_n_num, BIGNUM **rsa_e_num, CK_SESSION_HANDLE session)
11912+	{
11913+	CK_RV rv;
11914+	CK_OBJECT_HANDLE h_key = CK_INVALID_HANDLE;
11915+	int i;
11916+	CK_ULONG found;
11917+	CK_OBJECT_CLASS o_key = CKO_PRIVATE_KEY;
11918+	CK_KEY_TYPE k_type = CKK_RSA;
11919+	CK_ULONG ul_key_attr_count = 14;
11920+	CK_BBOOL rollback = FALSE;
11921+
11922+	/* Both CKA_TOKEN and CKA_SENSITIVE have to be FALSE for session keys */
11923+	CK_ATTRIBUTE  a_key_template[] =
11924+		{
11925+		{CKA_CLASS, (void *) NULL, sizeof (CK_OBJECT_CLASS)},
11926+		{CKA_KEY_TYPE, (void *) NULL, sizeof (CK_KEY_TYPE)},
11927+		{CKA_TOKEN, &false, sizeof (true)},
11928+		{CKA_SENSITIVE, &false, sizeof (true)},
11929+		{CKA_DECRYPT, &true, sizeof (true)},
11930+		{CKA_SIGN, &true, sizeof (true)},
11931+		{CKA_MODULUS, (void *)NULL, 0},
11932+		{CKA_PUBLIC_EXPONENT, (void *)NULL, 0},
11933+		{CKA_PRIVATE_EXPONENT, (void *)NULL, 0},
11934+		{CKA_PRIME_1, (void *)NULL, 0},
11935+		{CKA_PRIME_2, (void *)NULL, 0},
11936+		{CKA_EXPONENT_1, (void *)NULL, 0},
11937+		{CKA_EXPONENT_2, (void *)NULL, 0},
11938+		{CKA_COEFFICIENT, (void *)NULL, 0},
11939+		};
11940+
11941+	if ((rsa->flags & RSA_FLAG_EXT_PKEY) != 0) {
11942+		h_key = (CK_OBJECT_HANDLE)RSA_get_ex_data(rsa, hndidx_rsa);
11943+		LOCK_OBJSTORE(OP_RSA);
11944+		goto set;
11945+	}
11946+	
11947+	a_key_template[0].pValue = &o_key;
11948+	a_key_template[1].pValue = &k_type;
11949+
11950+	/* Put the private key components into the template */
11951+	if (init_template_value(rsa->n, &a_key_template[6].pValue,
11952+		&a_key_template[6].ulValueLen) == 0 ||
11953+	    init_template_value(rsa->e, &a_key_template[7].pValue,
11954+		&a_key_template[7].ulValueLen) == 0 ||
11955+	    init_template_value(rsa->d, &a_key_template[8].pValue,
11956+		&a_key_template[8].ulValueLen) == 0 ||
11957+	    init_template_value(rsa->p, &a_key_template[9].pValue,
11958+		&a_key_template[9].ulValueLen) == 0 ||
11959+	    init_template_value(rsa->q, &a_key_template[10].pValue,
11960+		&a_key_template[10].ulValueLen) == 0 ||
11961+	    init_template_value(rsa->dmp1, &a_key_template[11].pValue,
11962+		&a_key_template[11].ulValueLen) == 0 ||
11963+	    init_template_value(rsa->dmq1, &a_key_template[12].pValue,
11964+		&a_key_template[12].ulValueLen) == 0 ||
11965+	    init_template_value(rsa->iqmp, &a_key_template[13].pValue,
11966+		&a_key_template[13].ulValueLen) == 0)
11967+		{
11968+		PK11err(PK11_F_GET_PRIV_RSA_KEY, PK11_R_MALLOC_FAILURE);
11969+		goto malloc_err;
11970+		}
11971+
11972+	/* see find_lock array definition for more info on object locking */
11973+	LOCK_OBJSTORE(OP_RSA);
11974+
11975+	/*
11976+	 * We are getting the private key but the private 'd'
11977+	 * component is NULL.  That means this is key by reference RSA
11978+	 * key. In that case, we can use only public components for
11979+	 * searching for the private key handle.
11980+	 */
11981+	if (rsa->d == NULL)
11982+		{
11983+		ul_key_attr_count = 8;
11984+		/*
11985+		 * We will perform the search in the token, not in the existing
11986+		 * session keys.
11987+		 */
11988+		a_key_template[2].pValue = &true;
11989+		}
11990+
11991+	rv = pFuncList->C_FindObjectsInit(session, a_key_template,
11992+		ul_key_attr_count);
11993+
11994+	if (rv != CKR_OK)
11995+		{
11996+		PK11err_add_data(PK11_F_GET_PRIV_RSA_KEY,
11997+		    PK11_R_FINDOBJECTSINIT, rv);
11998+		goto err;
11999+		}
12000+
12001+	rv = pFuncList->C_FindObjects(session, &h_key, 1, &found);
12002+
12003+	if (rv != CKR_OK)
12004+		{
12005+		PK11err_add_data(PK11_F_GET_PRIV_RSA_KEY,
12006+		    PK11_R_FINDOBJECTS, rv);
12007+		goto err;
12008+		}
12009+
12010+	rv = pFuncList->C_FindObjectsFinal(session);
12011+
12012+	if (rv != CKR_OK)
12013+		{
12014+		PK11err_add_data(PK11_F_GET_PRIV_RSA_KEY,
12015+		    PK11_R_FINDOBJECTSFINAL, rv);
12016+		goto err;
12017+		}
12018+
12019+	if (found == 0)
12020+		{
12021+		/*
12022+		 * We have an RSA structure with 'n'/'e' components
12023+		 * only so we tried to find the private key in the
12024+		 * keystore. If it was really a token key we have a
12025+		 * problem. Note that for other key types we just
12026+		 * create a new session key using the private
12027+		 * components from the RSA structure.
12028+		 */
12029+		if (rsa->d == NULL)
12030+			{
12031+			PK11err(PK11_F_GET_PRIV_RSA_KEY,
12032+			    PK11_R_PRIV_KEY_NOT_FOUND);
12033+			goto err;
12034+			}
12035+
12036+		rv = pFuncList->C_CreateObject(session,
12037+			a_key_template, ul_key_attr_count, &h_key);
12038+		if (rv != CKR_OK)
12039+			{
12040+			PK11err_add_data(PK11_F_GET_PRIV_RSA_KEY,
12041+				PK11_R_CREATEOBJECT, rv);
12042+			goto err;
12043+			}
12044+		}
12045+
12046+set:
12047+	if (rsa_d_num != NULL)
12048+		{
12049+		/*
12050+		 * When RSA keys by reference code is used, we never
12051+		 * extract private components from the keystore. In
12052+		 * that case 'd' was set to NULL and we expect the
12053+		 * application to properly cope with that. It is
12054+		 * documented in openssl(5). In general, if keys by
12055+		 * reference are used we expect it to be used
12056+		 * exclusively using the high level API and then there
12057+		 * is no problem. If the application expects the
12058+		 * private components to be read from the keystore
12059+		 * then that is not a supported way of usage.
12060+		 */
12061+		if (rsa->d != NULL && (*rsa_d_num = BN_dup(rsa->d)) == NULL)
12062+			{
12063+			PK11err(PK11_F_GET_PRIV_RSA_KEY, PK11_R_MALLOC_FAILURE);
12064+			rollback = TRUE;
12065+			goto err;
12066+			}
12067+		else
12068+			*rsa_d_num = NULL;
12069+		}
12070+
12071+	/*
12072+	 * For the key by reference code, we need public components as well
12073+	 * since 'd' component is always NULL. For that reason, we always cache
12074+	 * 'n'/'e' components as well.
12075+	 */
12076+	*rsa_n_num = BN_dup(rsa->n);
12077+	*rsa_e_num = BN_dup(rsa->e);
12078+
12079+	/* LINTED: E_CONSTANT_CONDITION */
12080+	KEY_HANDLE_REFHOLD(h_key, OP_RSA, FALSE, rollback, err);
12081+	if (key_ptr != NULL)
12082+		*key_ptr = rsa;
12083+
12084+err:
12085+	if (rollback)
12086+		{
12087+		/*
12088+		 * We do not care about the return value from C_DestroyObject()
12089+		 * since we are doing rollback.
12090+		 */
12091+		if (found == 0 &&
12092+		    (rsa->flags & RSA_FLAG_EXT_PKEY) == 0)
12093+			(void) pFuncList->C_DestroyObject(session, h_key);
12094+		h_key = CK_INVALID_HANDLE;
12095+		}
12096+
12097+	UNLOCK_OBJSTORE(OP_RSA);
12098+
12099+malloc_err:
12100+	/*
12101+	 * 6 to 13 entries in the key template are key components.
12102+	 * They need to be freed upon exit or error.
12103+	 */
12104+	for (i = 6; i <= 13; i++)
12105+		{
12106+		if (a_key_template[i].pValue != NULL)
12107+			{
12108+			(void) memset(a_key_template[i].pValue, 0,
12109+				a_key_template[i].ulValueLen);
12110+			OPENSSL_free(a_key_template[i].pValue);
12111+			a_key_template[i].pValue = NULL;
12112+			}
12113+		}
12114+
12115+	return (h_key);
12116+	}
12117+
12118+/*
12119+ * Check for cache miss and clean the object pointer and handle
12120+ * in such case. Return 1 for cache hit, 0 for cache miss.
12121+ */
12122+static int check_new_rsa_key_pub(PK11_SESSION *sp, const RSA *rsa)
12123+	{
12124+	/*
12125+	 * Provide protection against RSA structure reuse by making the
12126+	 * check for cache hit stronger. Only public components of RSA
12127+	 * key matter here so it is sufficient to compare them with values
12128+	 * cached in PK11_SESSION structure.
12129+	 *
12130+	 * We must check the handle as well since with key by reference, public
12131+	 * components 'n'/'e' are cached in private keys as well. That means we
12132+	 * could have a cache hit in a private key when looking for a public
12133+	 * key. That would not work, you cannot have one PKCS#11 object for
12134+	 * both data signing and verifying.
12135+	 */
12136+	if ((sp->opdata_rsa_pub != rsa) ||
12137+	    (BN_cmp(sp->opdata_rsa_n_num, rsa->n) != 0) ||
12138+	    (BN_cmp(sp->opdata_rsa_e_num, rsa->e) != 0) ||
12139+	    (sp->opdata_rsa_priv_key != CK_INVALID_HANDLE))
12140+		{
12141+		/*
12142+		 * We do not check the return value because even in case of
12143+		 * failure the sp structure will have both key pointer
12144+		 * and object handle cleaned and pk11_destroy_object()
12145+		 * reports the failure to the OpenSSL error message buffer.
12146+		 */
12147+		(void) pk11_destroy_rsa_object_pub(sp, TRUE);
12148+		return (0);
12149+		}
12150+	return (1);
12151+	}
12152+
12153+/*
12154+ * Check for cache miss and clean the object pointer and handle
12155+ * in such case. Return 1 for cache hit, 0 for cache miss.
12156+ */
12157+static int check_new_rsa_key_priv(PK11_SESSION *sp, const RSA *rsa)
12158+	{
12159+	/*
12160+	 * Provide protection against RSA structure reuse by making
12161+	 * the check for cache hit stronger. Comparing public exponent
12162+	 * of RSA key with value cached in PK11_SESSION structure
12163+	 * should be sufficient. Note that we want to compare the
12164+	 * public component since with the keys by reference
12165+	 * mechanism, private components are not in the RSA
12166+	 * structure. Also, see check_new_rsa_key_pub() about why we
12167+	 * compare the handle as well.
12168+	 */
12169+	if ((sp->opdata_rsa_priv != rsa) ||
12170+	    (BN_cmp(sp->opdata_rsa_pn_num, rsa->n) != 0) ||
12171+	    (BN_cmp(sp->opdata_rsa_pe_num, rsa->e) != 0) ||
12172+	    (sp->opdata_rsa_pn_num == NULL) ||
12173+	    (sp->opdata_rsa_pe_num == NULL) ||
12174+	    (sp->opdata_rsa_pub_key != CK_INVALID_HANDLE))
12175+		{
12176+		/*
12177+		 * We do not check the return value because even in case of
12178+		 * failure the sp structure will have both key pointer
12179+		 * and object handle cleaned and pk11_destroy_object()
12180+		 * reports the failure to the OpenSSL error message buffer.
12181+		 */
12182+		(void) pk11_destroy_rsa_object_priv(sp, TRUE);
12183+		return (0);
12184+		}
12185+	return (1);
12186+	}
12187+
12188+/*
12189+ * Local function to simplify key template population
12190+ * Return 0 -- error, 1 -- no error
12191+ */
12192+static int
12193+init_template_value(BIGNUM *bn, CK_VOID_PTR *p_value,
12194+	CK_ULONG *ul_value_len)
12195+	{
12196+	CK_ULONG len = 0;
12197+
12198+	/*
12199+	 * This function can be used on non-initialized BIGNUMs. It is
12200+	 * easier to check that here than individually in the callers.
12201+	 */
12202+	if (bn != NULL)
12203+		len = BN_num_bytes(bn);
12204+
12205+	if (bn == NULL || len == 0)
12206+		return (1);
12207+
12208+	*ul_value_len = len;
12209+	*p_value = (CK_VOID_PTR)OPENSSL_malloc((size_t)*ul_value_len);
12210+	if (*p_value == NULL)
12211+		return (0);
12212+
12213+	BN_bn2bin(bn, *p_value);
12214+
12215+	return (1);
12216+	}
12217+
12218+static void
12219+attr_to_BN(CK_ATTRIBUTE_PTR attr, CK_BYTE attr_data[], BIGNUM **bn)
12220+	{
12221+	if (attr->ulValueLen > 0)
12222+		*bn = BN_bin2bn(attr_data, attr->ulValueLen, NULL);
12223+	}
12224+
12225+/*
12226+ * Find one object in the token. It is an error if we can not find the
12227+ * object or if we find more objects based on the template we got.
12228+ *
12229+ * Returns:
12230+ *	1 OK
12231+ *	0 no object or more than 1 object found
12232+ */
12233+static int
12234+find_one_object(PK11_OPTYPE op, CK_SESSION_HANDLE s,
12235+    CK_ATTRIBUTE_PTR ptempl, CK_ULONG nattr, CK_OBJECT_HANDLE_PTR pkey)
12236+	{
12237+	CK_RV rv;
12238+	CK_ULONG objcnt;
12239+
12240+	LOCK_OBJSTORE(op);
12241+	if ((rv = pFuncList->C_FindObjectsInit(s, ptempl, nattr)) != CKR_OK)
12242+		{
12243+		PK11err_add_data(PK11_F_FIND_ONE_OBJECT,
12244+		    PK11_R_FINDOBJECTSINIT, rv);
12245+		goto err;
12246+		}
12247+
12248+	rv = pFuncList->C_FindObjects(s, pkey, 1, &objcnt);
12249+	if (rv != CKR_OK)
12250+		{
12251+		PK11err_add_data(PK11_F_FIND_ONE_OBJECT, PK11_R_FINDOBJECTS,
12252+		    rv);
12253+		goto err;
12254+		}
12255+
12256+	if (objcnt > 1)
12257+		{
12258+		PK11err(PK11_F_FIND_ONE_OBJECT,
12259+		    PK11_R_MORE_THAN_ONE_OBJECT_FOUND);
12260+		goto err;
12261+		}
12262+	else if (objcnt == 0)
12263+		{
12264+		PK11err(PK11_F_FIND_ONE_OBJECT, PK11_R_NO_OBJECT_FOUND);
12265+		goto err;
12266+		}
12267+
12268+	(void) pFuncList->C_FindObjectsFinal(s);
12269+	UNLOCK_OBJSTORE(op);
12270+	return (1);
12271+err:
12272+	UNLOCK_OBJSTORE(op);
12273+	return (0);
12274+	}
12275+
12276+/* from uri stuff */
12277+
12278+extern char *pk11_pin;
12279+
12280+static int pk11_get_pin(void);
12281+
12282+static int
12283+pk11_get_pin(void)
12284+{
12285+	char *pin;
12286+
12287+	/* The getpassphrase() function is not MT safe. */
12288+#ifndef NOPTHREADS
12289+	(void) pthread_mutex_lock(token_lock);
12290+#else
12291+	CRYPTO_w_lock(CRYPTO_LOCK_PK11_ENGINE);
12292+#endif
12293+	pin = getpassphrase("Enter PIN: ");
12294+	if (pin == NULL)
12295+		{
12296+		PK11err(PK11_F_GET_PIN, PK11_R_COULD_NOT_READ_PIN);
12297+#ifndef NOPTHREADS
12298+		(void) pthread_mutex_unlock(token_lock);
12299+#else
12300+		CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
12301+#endif
12302+		goto err;
12303+		}
12304+	pk11_pin = BUF_strdup(pin);
12305+	if (pk11_pin == NULL)
12306+		{
12307+		PK11err(PK11_F_LOAD_PRIVKEY, PK11_R_MALLOC_FAILURE);
12308+#ifndef NOPTHREADS
12309+		(void) pthread_mutex_unlock(token_lock);
12310+#else
12311+		CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
12312+#endif
12313+		goto err;
12314+		}
12315+	memset(pin, 0, strlen(pin));
12316+#ifndef NOPTHREADS
12317+	(void) pthread_mutex_unlock(token_lock);
12318+#else
12319+	CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
12320+#endif
12321+	return (1);
12322+err:
12323+	return (0);
12324+	}
12325+
12326+/*
12327+ * Log in to the keystore if we are supposed to do that at all. Take care of
12328+ * reading and caching the PIN etc. Log in only once even when called from
12329+ * multiple threads.
12330+ *
12331+ * Returns:
12332+ *	1 on success
12333+ *	0 on failure
12334+ */
12335+static int
12336+pk11_token_login(CK_SESSION_HANDLE session, CK_BBOOL *login_done,
12337+    CK_BBOOL is_private)
12338+	{
12339+	CK_RV rv;
12340+
12341+#if 0
12342+	/* doesn't work on the AEP Keyper??? */
12343+	if ((pubkey_token_flags & CKF_TOKEN_INITIALIZED) == 0)
12344+		{
12345+		PK11err(PK11_F_TOKEN_LOGIN,
12346+		    PK11_R_TOKEN_NOT_INITIALIZED);
12347+		goto err;
12348+		}
12349+#endif
12350+
12351+	/*
12352+	 * If login is required or needed but the PIN has not been
12353+	 * even initialized we can bail out right now. Note that we
12354+	 * are supposed to always log in if we are going to access
12355+	 * private keys. However, we may need to log in even for
12356+	 * accessing public keys in case that the CKF_LOGIN_REQUIRED
12357+	 * flag is set.
12358+	 */
12359+	if (((pubkey_token_flags & CKF_LOGIN_REQUIRED) ||
12360+	     (is_private == CK_TRUE)) &&
12361+	    (~pubkey_token_flags & CKF_USER_PIN_INITIALIZED))
12362+		{
12363+		PK11err(PK11_F_TOKEN_LOGIN, PK11_R_TOKEN_PIN_NOT_SET);
12364+		goto err;
12365+		}
12366+
12367+	/*
12368+	 * Note on locking: it is possible that more than one thread
12369+	 * gets into pk11_get_pin() so we must deal with that. We
12370+	 * cannot avoid it since we cannot guard fork() in there with
12371+	 * a lock because we could end up in a dead lock in the
12372+	 * child. Why? Remember we are in a multithreaded environment
12373+	 * so we must lock all mutexes in the prefork function to
12374+	 * avoid a situation in which a thread that did not call
12375+	 * fork() held a lock, making future unlocking impossible. We
12376+	 * lock right before C_Login().
12377+	 */
12378+	if ((pubkey_token_flags & CKF_LOGIN_REQUIRED) ||
12379+	    (is_private == CK_TRUE))
12380+		{
12381+		if (*login_done == CK_FALSE)
12382+			{
12383+			if ((pk11_pin == NULL) && (pk11_get_pin() == 0))
12384+				{
12385+				PK11err(PK11_F_TOKEN_LOGIN,
12386+				    PK11_R_TOKEN_PIN_NOT_PROVIDED);
12387+				goto err;
12388+				}
12389+			}
12390+
12391+		/*
12392+		 * Note that what we are logging into is the keystore from
12393+		 * pubkey_SLOTID because we work with OP_RSA session type here.
12394+		 * That also means that we can work with only one keystore in
12395+		 * the engine.
12396+		 *
12397+		 * We must make sure we do not try to login more than once.
12398+		 * Also, see the comment above on locking strategy.
12399+		 */
12400+
12401+#ifndef NOPTHREADS
12402+		(void) pthread_mutex_lock(token_lock);
12403+#else
12404+		(void) pthread_mutex_lock(freelist_lock);
12405+#endif
12406+		if (*login_done == CK_FALSE)
12407+			{
12408+			if ((rv = pFuncList->C_Login(session,
12409+			    CKU_USER, (CK_UTF8CHAR*)pk11_pin,
12410+			    strlen(pk11_pin))) != CKR_OK)
12411+				{
12412+				PK11err_add_data(PK11_F_TOKEN_LOGIN,
12413+				    PK11_R_TOKEN_LOGIN_FAILED, rv);
12414+				goto err_locked;
12415+				}
12416+
12417+			*login_done = CK_TRUE;
12418+
12419+			}
12420+#ifndef NOPTHREADS
12421+		(void) pthread_mutex_unlock(token_lock);
12422+#else
12423+		CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
12424+#endif
12425+		}
12426+	else
12427+		{
12428+			/*
12429+			 * If token does not require login we take it as the
12430+			 * login was done.
12431+			 */
12432+			*login_done = CK_TRUE;
12433+		}
12434+
12435+	return (1);
12436+
12437+err_locked:
12438+	if (pk11_pin) {
12439+		memset(pk11_pin, 0, strlen(pk11_pin));
12440+		OPENSSL_free((void*)pk11_pin);
12441+	}
12442+	pk11_pin = NULL;
12443+#ifndef NOPTHREADS
12444+	(void) pthread_mutex_unlock(token_lock);
12445+#else
12446+	CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
12447+#endif
12448+err:
12449+	return (0);
12450+	}
12451+
12452+/*
12453+ * Log in to the keystore in the child if we were logged in in the
12454+ * parent. There are similarities in the code with pk11_token_login()
12455+ * but still it is quite different so we need a separate function for
12456+ * this.
12457+ *
12458+ * Note that this function is called under the locked session mutex when fork is
12459+ * detected. That means that C_Login() will be called from the child just once.
12460+ *
12461+ * Returns:
12462+ *	1 on success
12463+ *	0 on failure
12464+ */
12465+int
12466+pk11_token_relogin(CK_SESSION_HANDLE session)
12467+	{
12468+	CK_RV rv;
12469+
12470+	if ((pk11_pin == NULL) && (pk11_get_pin() == 0))
12471+		goto err;
12472+
12473+#ifndef NOPTHREADS
12474+	(void) pthread_mutex_lock(token_lock);
12475+#else
12476+	(void) pthread_mutex_lock(freelist_lock);
12477+#endif
12478+	if ((rv = pFuncList->C_Login(session, CKU_USER,
12479+	    (CK_UTF8CHAR_PTR)pk11_pin, strlen(pk11_pin))) != CKR_OK)
12480+		{
12481+		PK11err_add_data(PK11_F_TOKEN_RELOGIN,
12482+		    PK11_R_TOKEN_LOGIN_FAILED, rv);
12483+#ifndef NOPTHREADS
12484+		(void) pthread_mutex_unlock(token_lock);
12485+#else
12486+		CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
12487+#endif
12488+		goto err;
12489+		}
12490+#ifndef NOPTHREADS
12491+	(void) pthread_mutex_unlock(token_lock);
12492+#else
12493+	CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
12494+#endif
12495+
12496+	return (1);
12497+err:
12498+	return (0);
12499+	}
12500+
12501+#ifdef	OPENSSL_SYS_WIN32
12502+char *getpassphrase(const char *prompt)
12503+	{
12504+	static char buf[128];
12505+	HANDLE h;
12506+	DWORD cc, mode;
12507+	int cnt;
12508+
12509+	h = GetStdHandle(STD_INPUT_HANDLE);
12510+	fputs(prompt, stderr);
12511+	fflush(stderr);
12512+	fflush(stdout);
12513+	FlushConsoleInputBuffer(h);
12514+	GetConsoleMode(h, &mode);
12515+	SetConsoleMode(h, ENABLE_PROCESSED_INPUT);
12516+
12517+	for (cnt = 0; cnt < sizeof(buf) - 1; cnt++)
12518+		{
12519+		ReadFile(h, buf + cnt, 1, &cc, NULL);
12520+		if (buf[cnt] == '\r')
12521+			break;
12522+		fputc('*', stdout);
12523+		fflush(stderr);
12524+		fflush(stdout);
12525+		}
12526+
12527+	SetConsoleMode(h, mode);
12528+	buf[cnt] = '\0';
12529+	fputs("\n", stderr);
12530+	return buf;
12531+	}
12532+#endif	/* OPENSSL_SYS_WIN32 */
12533+#endif	/* OPENSSL_NO_HW_PK11SO */
12534+#endif	/* OPENSSL_NO_HW_PK11 */
12535+#endif	/* OPENSSL_NO_HW */
12536Index: openssl/crypto/engine/pkcs11.h
12537diff -u /dev/null openssl/crypto/engine/pkcs11.h:1.1.1.1
12538--- /dev/null	Mon Jan 16 18:54:23 2012
12539+++ openssl/crypto/engine/pkcs11.h	Wed Oct 24 23:27:09 2007
12540@@ -0,0 +1,299 @@
12541+/* pkcs11.h include file for PKCS #11. */
12542+/* $Revision: 1.2.2.2 $ */
12543+
12544+/* License to copy and use this software is granted provided that it is
12545+ * identified as "RSA Security Inc. PKCS #11 Cryptographic Token Interface
12546+ * (Cryptoki)" in all material mentioning or referencing this software.
12547+
12548+ * License is also granted to make and use derivative works provided that
12549+ * such works are identified as "derived from the RSA Security Inc. PKCS #11
12550+ * Cryptographic Token Interface (Cryptoki)" in all material mentioning or 
12551+ * referencing the derived work.
12552+
12553+ * RSA Security Inc. makes no representations concerning either the 
12554+ * merchantability of this software or the suitability of this software for
12555+ * any particular purpose. It is provided "as is" without express or implied
12556+ * warranty of any kind.
12557+ */
12558+
12559+#ifndef _PKCS11_H_
12560+#define _PKCS11_H_ 1
12561+
12562+#ifdef __cplusplus
12563+extern "C" {
12564+#endif
12565+
12566+/* Before including this file (pkcs11.h) (or pkcs11t.h by
12567+ * itself), 6 platform-specific macros must be defined.  These
12568+ * macros are described below, and typical definitions for them
12569+ * are also given.  Be advised that these definitions can depend
12570+ * on both the platform and the compiler used (and possibly also
12571+ * on whether a Cryptoki library is linked statically or
12572+ * dynamically).
12573+ *
12574+ * In addition to defining these 6 macros, the packing convention
12575+ * for Cryptoki structures should be set.  The Cryptoki
12576+ * convention on packing is that structures should be 1-byte
12577+ * aligned.
12578+ *
12579+ * If you're using Microsoft Developer Studio 5.0 to produce
12580+ * Win32 stuff, this might be done by using the following
12581+ * preprocessor directive before including pkcs11.h or pkcs11t.h:
12582+ *
12583+ * #pragma pack(push, cryptoki, 1)
12584+ *
12585+ * and using the following preprocessor directive after including
12586+ * pkcs11.h or pkcs11t.h:
12587+ *
12588+ * #pragma pack(pop, cryptoki)
12589+ *
12590+ * If you're using an earlier version of Microsoft Developer
12591+ * Studio to produce Win16 stuff, this might be done by using
12592+ * the following preprocessor directive before including
12593+ * pkcs11.h or pkcs11t.h:
12594+ *
12595+ * #pragma pack(1)
12596+ *
12597+ * In a UNIX environment, you're on your own for this.  You might
12598+ * not need to do (or be able to do!) anything.
12599+ *
12600+ *
12601+ * Now for the macros:
12602+ *
12603+ *
12604+ * 1. CK_PTR: The indirection string for making a pointer to an
12605+ * object.  It can be used like this:
12606+ *
12607+ * typedef CK_BYTE CK_PTR CK_BYTE_PTR;
12608+ *
12609+ * If you're using Microsoft Developer Studio 5.0 to produce
12610+ * Win32 stuff, it might be defined by:
12611+ *
12612+ * #define CK_PTR *
12613+ *
12614+ * If you're using an earlier version of Microsoft Developer
12615+ * Studio to produce Win16 stuff, it might be defined by:
12616+ *
12617+ * #define CK_PTR far *
12618+ *
12619+ * In a typical UNIX environment, it might be defined by:
12620+ *
12621+ * #define CK_PTR *
12622+ *
12623+ *
12624+ * 2. CK_DEFINE_FUNCTION(returnType, name): A macro which makes
12625+ * an exportable Cryptoki library function definition out of a
12626+ * return type and a function name.  It should be used in the
12627+ * following fashion to define the exposed Cryptoki functions in
12628+ * a Cryptoki library:
12629+ *
12630+ * CK_DEFINE_FUNCTION(CK_RV, C_Initialize)(
12631+ *   CK_VOID_PTR pReserved
12632+ * )
12633+ * {
12634+ *   ...
12635+ * }
12636+ *
12637+ * If you're using Microsoft Developer Studio 5.0 to define a
12638+ * function in a Win32 Cryptoki .dll, it might be defined by:
12639+ *
12640+ * #define CK_DEFINE_FUNCTION(returnType, name) \
12641+ *   returnType __declspec(dllexport) name
12642+ *
12643+ * If you're using an earlier version of Microsoft Developer
12644+ * Studio to define a function in a Win16 Cryptoki .dll, it
12645+ * might be defined by:
12646+ *
12647+ * #define CK_DEFINE_FUNCTION(returnType, name) \
12648+ *   returnType __export _far _pascal name
12649+ *
12650+ * In a UNIX environment, it might be defined by:
12651+ *
12652+ * #define CK_DEFINE_FUNCTION(returnType, name) \
12653+ *   returnType name
12654+ *
12655+ *
12656+ * 3. CK_DECLARE_FUNCTION(returnType, name): A macro which makes
12657+ * an importable Cryptoki library function declaration out of a
12658+ * return type and a function name.  It should be used in the
12659+ * following fashion:
12660+ *
12661+ * extern CK_DECLARE_FUNCTION(CK_RV, C_Initialize)(
12662+ *   CK_VOID_PTR pReserved
12663+ * );
12664+ *
12665+ * If you're using Microsoft Developer Studio 5.0 to declare a
12666+ * function in a Win32 Cryptoki .dll, it might be defined by:
12667+ *
12668+ * #define CK_DECLARE_FUNCTION(returnType, name) \
12669+ *   returnType __declspec(dllimport) name
12670+ *
12671+ * If you're using an earlier version of Microsoft Developer
12672+ * Studio to declare a function in a Win16 Cryptoki .dll, it
12673+ * might be defined by:
12674+ *
12675+ * #define CK_DECLARE_FUNCTION(returnType, name) \
12676+ *   returnType __export _far _pascal name
12677+ *
12678+ * In a UNIX environment, it might be defined by:
12679+ *
12680+ * #define CK_DECLARE_FUNCTION(returnType, name) \
12681+ *   returnType name
12682+ *
12683+ *
12684+ * 4. CK_DECLARE_FUNCTION_POINTER(returnType, name): A macro
12685+ * which makes a Cryptoki API function pointer declaration or
12686+ * function pointer type declaration out of a return type and a
12687+ * function name.  It should be used in the following fashion:
12688+ *
12689+ * // Define funcPtr to be a pointer to a Cryptoki API function
12690+ * // taking arguments args and returning CK_RV.
12691+ * CK_DECLARE_FUNCTION_POINTER(CK_RV, funcPtr)(args);
12692+ *
12693+ * or
12694+ *
12695+ * // Define funcPtrType to be the type of a pointer to a
12696+ * // Cryptoki API function taking arguments args and returning
12697+ * // CK_RV, and then define funcPtr to be a variable of type
12698+ * // funcPtrType.
12699+ * typedef CK_DECLARE_FUNCTION_POINTER(CK_RV, funcPtrType)(args);
12700+ * funcPtrType funcPtr;
12701+ *
12702+ * If you're using Microsoft Developer Studio 5.0 to access
12703+ * functions in a Win32 Cryptoki .dll, in might be defined by:
12704+ *
12705+ * #define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
12706+ *   returnType __declspec(dllimport) (* name)
12707+ *
12708+ * If you're using an earlier version of Microsoft Developer
12709+ * Studio to access functions in a Win16 Cryptoki .dll, it might
12710+ * be defined by:
12711+ *
12712+ * #define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
12713+ *   returnType __export _far _pascal (* name)
12714+ *
12715+ * In a UNIX environment, it might be defined by:
12716+ *
12717+ * #define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
12718+ *   returnType (* name)
12719+ *
12720+ *
12721+ * 5. CK_CALLBACK_FUNCTION(returnType, name): A macro which makes
12722+ * a function pointer type for an application callback out of
12723+ * a return type for the callback and a name for the callback.
12724+ * It should be used in the following fashion:
12725+ *
12726+ * CK_CALLBACK_FUNCTION(CK_RV, myCallback)(args);
12727+ *
12728+ * to declare a function pointer, myCallback, to a callback
12729+ * which takes arguments args and returns a CK_RV.  It can also
12730+ * be used like this:
12731+ *
12732+ * typedef CK_CALLBACK_FUNCTION(CK_RV, myCallbackType)(args);
12733+ * myCallbackType myCallback;
12734+ *
12735+ * If you're using Microsoft Developer Studio 5.0 to do Win32
12736+ * Cryptoki development, it might be defined by:
12737+ *
12738+ * #define CK_CALLBACK_FUNCTION(returnType, name) \
12739+ *   returnType (* name)
12740+ *
12741+ * If you're using an earlier version of Microsoft Developer
12742+ * Studio to do Win16 development, it might be defined by:
12743+ *
12744+ * #define CK_CALLBACK_FUNCTION(returnType, name) \
12745+ *   returnType _far _pascal (* name)
12746+ *
12747+ * In a UNIX environment, it might be defined by:
12748+ *
12749+ * #define CK_CALLBACK_FUNCTION(returnType, name) \
12750+ *   returnType (* name)
12751+ *
12752+ *
12753+ * 6. NULL_PTR: This macro is the value of a NULL pointer.
12754+ *
12755+ * In any ANSI/ISO C environment (and in many others as well),
12756+ * this should best be defined by
12757+ *
12758+ * #ifndef NULL_PTR
12759+ * #define NULL_PTR 0
12760+ * #endif
12761+ */
12762+
12763+
12764+/* All the various Cryptoki types and #define'd values are in the
12765+ * file pkcs11t.h. */
12766+#include "pkcs11t.h"
12767+
12768+#define __PASTE(x,y)      x##y
12769+
12770+
12771+/* ==============================================================
12772+ * Define the "extern" form of all the entry points.
12773+ * ==============================================================
12774+ */
12775+
12776+#define CK_NEED_ARG_LIST  1
12777+#define CK_PKCS11_FUNCTION_INFO(name) \
12778+  extern CK_DECLARE_FUNCTION(CK_RV, name)
12779+
12780+/* pkcs11f.h has all the information about the Cryptoki
12781+ * function prototypes. */
12782+#include "pkcs11f.h"
12783+
12784+#undef CK_NEED_ARG_LIST
12785+#undef CK_PKCS11_FUNCTION_INFO
12786+
12787+
12788+/* ==============================================================
12789+ * Define the typedef form of all the entry points.  That is, for
12790+ * each Cryptoki function C_XXX, define a type CK_C_XXX which is
12791+ * a pointer to that kind of function.
12792+ * ==============================================================
12793+ */
12794+
12795+#define CK_NEED_ARG_LIST  1
12796+#define CK_PKCS11_FUNCTION_INFO(name) \
12797+  typedef CK_DECLARE_FUNCTION_POINTER(CK_RV, __PASTE(CK_,name))
12798+
12799+/* pkcs11f.h has all the information about the Cryptoki
12800+ * function prototypes. */
12801+#include "pkcs11f.h"
12802+
12803+#undef CK_NEED_ARG_LIST
12804+#undef CK_PKCS11_FUNCTION_INFO
12805+
12806+
12807+/* ==============================================================
12808+ * Define structed vector of entry points.  A CK_FUNCTION_LIST
12809+ * contains a CK_VERSION indicating a library's Cryptoki version
12810+ * and then a whole slew of function pointers to the routines in
12811+ * the library.  This type was declared, but not defined, in
12812+ * pkcs11t.h.
12813+ * ==============================================================
12814+ */
12815+
12816+#define CK_PKCS11_FUNCTION_INFO(name) \
12817+  __PASTE(CK_,name) name;
12818+  
12819+struct CK_FUNCTION_LIST {
12820+
12821+  CK_VERSION    version;  /* Cryptoki version */
12822+
12823+/* Pile all the function pointers into the CK_FUNCTION_LIST. */
12824+/* pkcs11f.h has all the information about the Cryptoki
12825+ * function prototypes. */
12826+#include "pkcs11f.h"
12827+
12828+};
12829+
12830+#undef CK_PKCS11_FUNCTION_INFO
12831+
12832+
12833+#undef __PASTE
12834+
12835+#ifdef __cplusplus
12836+}
12837+#endif
12838+
12839+#endif
12840Index: openssl/crypto/engine/pkcs11f.h
12841diff -u /dev/null openssl/crypto/engine/pkcs11f.h:1.1.1.1
12842--- /dev/null	Mon Jan 16 18:54:23 2012
12843+++ openssl/crypto/engine/pkcs11f.h	Wed Oct 24 23:27:09 2007
12844@@ -0,0 +1,912 @@
12845+/* pkcs11f.h include file for PKCS #11. */
12846+/* $Revision: 1.2.2.2 $ */
12847+
12848+/* License to copy and use this software is granted provided that it is
12849+ * identified as "RSA Security Inc. PKCS #11 Cryptographic Token Interface
12850+ * (Cryptoki)" in all material mentioning or referencing this software.
12851+
12852+ * License is also granted to make and use derivative works provided that
12853+ * such works are identified as "derived from the RSA Security Inc. PKCS #11
12854+ * Cryptographic Token Interface (Cryptoki)" in all material mentioning or 
12855+ * referencing the derived work.
12856+
12857+ * RSA Security Inc. makes no representations concerning either the 
12858+ * merchantability of this software or the suitability of this software for
12859+ * any particular purpose. It is provided "as is" without express or implied
12860+ * warranty of any kind.
12861+ */
12862+
12863+/* This header file contains pretty much everything about all the */
12864+/* Cryptoki function prototypes.  Because this information is */
12865+/* used for more than just declaring function prototypes, the */
12866+/* order of the functions appearing herein is important, and */
12867+/* should not be altered. */
12868+
12869+/* General-purpose */
12870+
12871+/* C_Initialize initializes the Cryptoki library. */
12872+CK_PKCS11_FUNCTION_INFO(C_Initialize)
12873+#ifdef CK_NEED_ARG_LIST
12874+(
12875+  CK_VOID_PTR   pInitArgs  /* if this is not NULL_PTR, it gets
12876+                            * cast to CK_C_INITIALIZE_ARGS_PTR
12877+                            * and dereferenced */
12878+);
12879+#endif
12880+
12881+
12882+/* C_Finalize indicates that an application is done with the
12883+ * Cryptoki library. */
12884+CK_PKCS11_FUNCTION_INFO(C_Finalize)
12885+#ifdef CK_NEED_ARG_LIST
12886+(
12887+  CK_VOID_PTR   pReserved  /* reserved.  Should be NULL_PTR */
12888+);
12889+#endif
12890+
12891+
12892+/* C_GetInfo returns general information about Cryptoki. */
12893+CK_PKCS11_FUNCTION_INFO(C_GetInfo)
12894+#ifdef CK_NEED_ARG_LIST
12895+(
12896+  CK_INFO_PTR   pInfo  /* location that receives information */
12897+);
12898+#endif
12899+
12900+
12901+/* C_GetFunctionList returns the function list. */
12902+CK_PKCS11_FUNCTION_INFO(C_GetFunctionList)
12903+#ifdef CK_NEED_ARG_LIST
12904+(
12905+  CK_FUNCTION_LIST_PTR_PTR ppFunctionList  /* receives pointer to
12906+                                            * function list */
12907+);
12908+#endif
12909+
12910+
12911+
12912+/* Slot and token management */
12913+
12914+/* C_GetSlotList obtains a list of slots in the system. */
12915+CK_PKCS11_FUNCTION_INFO(C_GetSlotList)
12916+#ifdef CK_NEED_ARG_LIST
12917+(
12918+  CK_BBOOL       tokenPresent,  /* only slots with tokens? */
12919+  CK_SLOT_ID_PTR pSlotList,     /* receives array of slot IDs */
12920+  CK_ULONG_PTR   pulCount       /* receives number of slots */
12921+);
12922+#endif
12923+
12924+
12925+/* C_GetSlotInfo obtains information about a particular slot in
12926+ * the system. */
12927+CK_PKCS11_FUNCTION_INFO(C_GetSlotInfo)
12928+#ifdef CK_NEED_ARG_LIST
12929+(
12930+  CK_SLOT_ID       slotID,  /* the ID of the slot */
12931+  CK_SLOT_INFO_PTR pInfo    /* receives the slot information */
12932+);
12933+#endif
12934+
12935+
12936+/* C_GetTokenInfo obtains information about a particular token
12937+ * in the system. */
12938+CK_PKCS11_FUNCTION_INFO(C_GetTokenInfo)
12939+#ifdef CK_NEED_ARG_LIST
12940+(
12941+  CK_SLOT_ID        slotID,  /* ID of the token's slot */
12942+  CK_TOKEN_INFO_PTR pInfo    /* receives the token information */
12943+);
12944+#endif
12945+
12946+
12947+/* C_GetMechanismList obtains a list of mechanism types
12948+ * supported by a token. */
12949+CK_PKCS11_FUNCTION_INFO(C_GetMechanismList)
12950+#ifdef CK_NEED_ARG_LIST
12951+(
12952+  CK_SLOT_ID            slotID,          /* ID of token's slot */
12953+  CK_MECHANISM_TYPE_PTR pMechanismList,  /* gets mech. array */
12954+  CK_ULONG_PTR          pulCount         /* gets # of mechs. */
12955+);
12956+#endif
12957+
12958+
12959+/* C_GetMechanismInfo obtains information about a particular
12960+ * mechanism possibly supported by a token. */
12961+CK_PKCS11_FUNCTION_INFO(C_GetMechanismInfo)
12962+#ifdef CK_NEED_ARG_LIST
12963+(
12964+  CK_SLOT_ID            slotID,  /* ID of the token's slot */
12965+  CK_MECHANISM_TYPE     type,    /* type of mechanism */
12966+  CK_MECHANISM_INFO_PTR pInfo    /* receives mechanism info */
12967+);
12968+#endif
12969+
12970+
12971+/* C_InitToken initializes a token. */
12972+CK_PKCS11_FUNCTION_INFO(C_InitToken)
12973+#ifdef CK_NEED_ARG_LIST
12974+/* pLabel changed from CK_CHAR_PTR to CK_UTF8CHAR_PTR for v2.10 */
12975+(
12976+  CK_SLOT_ID      slotID,    /* ID of the token's slot */
12977+  CK_UTF8CHAR_PTR pPin,      /* the SO's initial PIN */
12978+  CK_ULONG        ulPinLen,  /* length in bytes of the PIN */
12979+  CK_UTF8CHAR_PTR pLabel     /* 32-byte token label (blank padded) */
12980+);
12981+#endif
12982+
12983+
12984+/* C_InitPIN initializes the normal user's PIN. */
12985+CK_PKCS11_FUNCTION_INFO(C_InitPIN)
12986+#ifdef CK_NEED_ARG_LIST
12987+(
12988+  CK_SESSION_HANDLE hSession,  /* the session's handle */
12989+  CK_UTF8CHAR_PTR   pPin,      /* the normal user's PIN */
12990+  CK_ULONG          ulPinLen   /* length in bytes of the PIN */
12991+);
12992+#endif
12993+
12994+
12995+/* C_SetPIN modifies the PIN of the user who is logged in. */
12996+CK_PKCS11_FUNCTION_INFO(C_SetPIN)
12997+#ifdef CK_NEED_ARG_LIST
12998+(
12999+  CK_SESSION_HANDLE hSession,  /* the session's handle */
13000+  CK_UTF8CHAR_PTR   pOldPin,   /* the old PIN */
13001+  CK_ULONG          ulOldLen,  /* length of the old PIN */
13002+  CK_UTF8CHAR_PTR   pNewPin,   /* the new PIN */
13003+  CK_ULONG          ulNewLen   /* length of the new PIN */
13004+);
13005+#endif
13006+
13007+
13008+
13009+/* Session management */
13010+
13011+/* C_OpenSession opens a session between an application and a
13012+ * token. */
13013+CK_PKCS11_FUNCTION_INFO(C_OpenSession)
13014+#ifdef CK_NEED_ARG_LIST
13015+(
13016+  CK_SLOT_ID            slotID,        /* the slot's ID */
13017+  CK_FLAGS              flags,         /* from CK_SESSION_INFO */
13018+  CK_VOID_PTR           pApplication,  /* passed to callback */
13019+  CK_NOTIFY             Notify,        /* callback function */
13020+  CK_SESSION_HANDLE_PTR phSession      /* gets session handle */
13021+);
13022+#endif
13023+
13024+
13025+/* C_CloseSession closes a session between an application and a
13026+ * token. */
13027+CK_PKCS11_FUNCTION_INFO(C_CloseSession)
13028+#ifdef CK_NEED_ARG_LIST
13029+(
13030+  CK_SESSION_HANDLE hSession  /* the session's handle */
13031+);
13032+#endif
13033+
13034+
13035+/* C_CloseAllSessions closes all sessions with a token. */
13036+CK_PKCS11_FUNCTION_INFO(C_CloseAllSessions)
13037+#ifdef CK_NEED_ARG_LIST
13038+(
13039+  CK_SLOT_ID     slotID  /* the token's slot */
13040+);
13041+#endif
13042+
13043+
13044+/* C_GetSessionInfo obtains information about the session. */
13045+CK_PKCS11_FUNCTION_INFO(C_GetSessionInfo)
13046+#ifdef CK_NEED_ARG_LIST
13047+(
13048+  CK_SESSION_HANDLE   hSession,  /* the session's handle */
13049+  CK_SESSION_INFO_PTR pInfo      /* receives session info */
13050+);
13051+#endif
13052+
13053+
13054+/* C_GetOperationState obtains the state of the cryptographic operation
13055+ * in a session. */
13056+CK_PKCS11_FUNCTION_INFO(C_GetOperationState)
13057+#ifdef CK_NEED_ARG_LIST
13058+(
13059+  CK_SESSION_HANDLE hSession,             /* session's handle */
13060+  CK_BYTE_PTR       pOperationState,      /* gets state */
13061+  CK_ULONG_PTR      pulOperationStateLen  /* gets state length */
13062+);
13063+#endif
13064+
13065+
13066+/* C_SetOperationState restores the state of the cryptographic
13067+ * operation in a session. */
13068+CK_PKCS11_FUNCTION_INFO(C_SetOperationState)
13069+#ifdef CK_NEED_ARG_LIST
13070+(
13071+  CK_SESSION_HANDLE hSession,            /* session's handle */
13072+  CK_BYTE_PTR      pOperationState,      /* holds state */
13073+  CK_ULONG         ulOperationStateLen,  /* holds state length */
13074+  CK_OBJECT_HANDLE hEncryptionKey,       /* en/decryption key */
13075+  CK_OBJECT_HANDLE hAuthenticationKey    /* sign/verify key */
13076+);
13077+#endif
13078+
13079+
13080+/* C_Login logs a user into a token. */
13081+CK_PKCS11_FUNCTION_INFO(C_Login)
13082+#ifdef CK_NEED_ARG_LIST
13083+(
13084+  CK_SESSION_HANDLE hSession,  /* the session's handle */
13085+  CK_USER_TYPE      userType,  /* the user type */
13086+  CK_UTF8CHAR_PTR   pPin,      /* the user's PIN */
13087+  CK_ULONG          ulPinLen   /* the length of the PIN */
13088+);
13089+#endif
13090+
13091+
13092+/* C_Logout logs a user out from a token. */
13093+CK_PKCS11_FUNCTION_INFO(C_Logout)
13094+#ifdef CK_NEED_ARG_LIST
13095+(
13096+  CK_SESSION_HANDLE hSession  /* the session's handle */
13097+);
13098+#endif
13099+
13100+
13101+
13102+/* Object management */
13103+
13104+/* C_CreateObject creates a new object. */
13105+CK_PKCS11_FUNCTION_INFO(C_CreateObject)
13106+#ifdef CK_NEED_ARG_LIST
13107+(
13108+  CK_SESSION_HANDLE hSession,    /* the session's handle */
13109+  CK_ATTRIBUTE_PTR  pTemplate,   /* the object's template */
13110+  CK_ULONG          ulCount,     /* attributes in template */
13111+  CK_OBJECT_HANDLE_PTR phObject  /* gets new object's handle. */
13112+);
13113+#endif
13114+
13115+
13116+/* C_CopyObject copies an object, creating a new object for the
13117+ * copy. */
13118+CK_PKCS11_FUNCTION_INFO(C_CopyObject)
13119+#ifdef CK_NEED_ARG_LIST
13120+(
13121+  CK_SESSION_HANDLE    hSession,    /* the session's handle */
13122+  CK_OBJECT_HANDLE     hObject,     /* the object's handle */
13123+  CK_ATTRIBUTE_PTR     pTemplate,   /* template for new object */
13124+  CK_ULONG             ulCount,     /* attributes in template */
13125+  CK_OBJECT_HANDLE_PTR phNewObject  /* receives handle of copy */
13126+);
13127+#endif
13128+
13129+
13130+/* C_DestroyObject destroys an object. */
13131+CK_PKCS11_FUNCTION_INFO(C_DestroyObject)
13132+#ifdef CK_NEED_ARG_LIST
13133+(
13134+  CK_SESSION_HANDLE hSession,  /* the session's handle */
13135+  CK_OBJECT_HANDLE  hObject    /* the object's handle */
13136+);
13137+#endif
13138+
13139+
13140+/* C_GetObjectSize gets the size of an object in bytes. */
13141+CK_PKCS11_FUNCTION_INFO(C_GetObjectSize)
13142+#ifdef CK_NEED_ARG_LIST
13143+(
13144+  CK_SESSION_HANDLE hSession,  /* the session's handle */
13145+  CK_OBJECT_HANDLE  hObject,   /* the object's handle */
13146+  CK_ULONG_PTR      pulSize    /* receives size of object */
13147+);
13148+#endif
13149+
13150+
13151+/* C_GetAttributeValue obtains the value of one or more object
13152+ * attributes. */
13153+CK_PKCS11_FUNCTION_INFO(C_GetAttributeValue)
13154+#ifdef CK_NEED_ARG_LIST
13155+(
13156+  CK_SESSION_HANDLE hSession,   /* the session's handle */
13157+  CK_OBJECT_HANDLE  hObject,    /* the object's handle */
13158+  CK_ATTRIBUTE_PTR  pTemplate,  /* specifies attrs; gets vals */
13159+  CK_ULONG          ulCount     /* attributes in template */
13160+);
13161+#endif
13162+
13163+
13164+/* C_SetAttributeValue modifies the value of one or more object
13165+ * attributes */
13166+CK_PKCS11_FUNCTION_INFO(C_SetAttributeValue)
13167+#ifdef CK_NEED_ARG_LIST
13168+(
13169+  CK_SESSION_HANDLE hSession,   /* the session's handle */
13170+  CK_OBJECT_HANDLE  hObject,    /* the object's handle */
13171+  CK_ATTRIBUTE_PTR  pTemplate,  /* specifies attrs and values */
13172+  CK_ULONG          ulCount     /* attributes in template */
13173+);
13174+#endif
13175+
13176+
13177+/* C_FindObjectsInit initializes a search for token and session
13178+ * objects that match a template. */
13179+CK_PKCS11_FUNCTION_INFO(C_FindObjectsInit)
13180+#ifdef CK_NEED_ARG_LIST
13181+(
13182+  CK_SESSION_HANDLE hSession,   /* the session's handle */
13183+  CK_ATTRIBUTE_PTR  pTemplate,  /* attribute values to match */
13184+  CK_ULONG          ulCount     /* attrs in search template */
13185+);
13186+#endif
13187+
13188+
13189+/* C_FindObjects continues a search for token and session
13190+ * objects that match a template, obtaining additional object
13191+ * handles. */
13192+CK_PKCS11_FUNCTION_INFO(C_FindObjects)
13193+#ifdef CK_NEED_ARG_LIST
13194+(
13195+ CK_SESSION_HANDLE    hSession,          /* session's handle */
13196+ CK_OBJECT_HANDLE_PTR phObject,          /* gets obj. handles */
13197+ CK_ULONG             ulMaxObjectCount,  /* max handles to get */
13198+ CK_ULONG_PTR         pulObjectCount     /* actual # returned */
13199+);
13200+#endif
13201+
13202+
13203+/* C_FindObjectsFinal finishes a search for token and session
13204+ * objects. */
13205+CK_PKCS11_FUNCTION_INFO(C_FindObjectsFinal)
13206+#ifdef CK_NEED_ARG_LIST
13207+(
13208+  CK_SESSION_HANDLE hSession  /* the session's handle */
13209+);
13210+#endif
13211+
13212+
13213+
13214+/* Encryption and decryption */
13215+
13216+/* C_EncryptInit initializes an encryption operation. */
13217+CK_PKCS11_FUNCTION_INFO(C_EncryptInit)
13218+#ifdef CK_NEED_ARG_LIST
13219+(
13220+  CK_SESSION_HANDLE hSession,    /* the session's handle */
13221+  CK_MECHANISM_PTR  pMechanism,  /* the encryption mechanism */
13222+  CK_OBJECT_HANDLE  hKey         /* handle of encryption key */
13223+);
13224+#endif
13225+
13226+
13227+/* C_Encrypt encrypts single-part data. */
13228+CK_PKCS11_FUNCTION_INFO(C_Encrypt)
13229+#ifdef CK_NEED_ARG_LIST
13230+(
13231+  CK_SESSION_HANDLE hSession,            /* session's handle */
13232+  CK_BYTE_PTR       pData,               /* the plaintext data */
13233+  CK_ULONG          ulDataLen,           /* bytes of plaintext */
13234+  CK_BYTE_PTR       pEncryptedData,      /* gets ciphertext */
13235+  CK_ULONG_PTR      pulEncryptedDataLen  /* gets c-text size */
13236+);
13237+#endif
13238+
13239+
13240+/* C_EncryptUpdate continues a multiple-part encryption
13241+ * operation. */
13242+CK_PKCS11_FUNCTION_INFO(C_EncryptUpdate)
13243+#ifdef CK_NEED_ARG_LIST
13244+(
13245+  CK_SESSION_HANDLE hSession,           /* session's handle */
13246+  CK_BYTE_PTR       pPart,              /* the plaintext data */
13247+  CK_ULONG          ulPartLen,          /* plaintext data len */
13248+  CK_BYTE_PTR       pEncryptedPart,     /* gets ciphertext */
13249+  CK_ULONG_PTR      pulEncryptedPartLen /* gets c-text size */
13250+);
13251+#endif
13252+
13253+
13254+/* C_EncryptFinal finishes a multiple-part encryption
13255+ * operation. */
13256+CK_PKCS11_FUNCTION_INFO(C_EncryptFinal)
13257+#ifdef CK_NEED_ARG_LIST
13258+(
13259+  CK_SESSION_HANDLE hSession,                /* session handle */
13260+  CK_BYTE_PTR       pLastEncryptedPart,      /* last c-text */
13261+  CK_ULONG_PTR      pulLastEncryptedPartLen  /* gets last size */
13262+);
13263+#endif
13264+
13265+
13266+/* C_DecryptInit initializes a decryption operation. */
13267+CK_PKCS11_FUNCTION_INFO(C_DecryptInit)
13268+#ifdef CK_NEED_ARG_LIST
13269+(
13270+  CK_SESSION_HANDLE hSession,    /* the session's handle */
13271+  CK_MECHANISM_PTR  pMechanism,  /* the decryption mechanism */
13272+  CK_OBJECT_HANDLE  hKey         /* handle of decryption key */
13273+);
13274+#endif
13275+
13276+
13277+/* C_Decrypt decrypts encrypted data in a single part. */
13278+CK_PKCS11_FUNCTION_INFO(C_Decrypt)
13279+#ifdef CK_NEED_ARG_LIST
13280+(
13281+  CK_SESSION_HANDLE hSession,           /* session's handle */
13282+  CK_BYTE_PTR       pEncryptedData,     /* ciphertext */
13283+  CK_ULONG          ulEncryptedDataLen, /* ciphertext length */
13284+  CK_BYTE_PTR       pData,              /* gets plaintext */
13285+  CK_ULONG_PTR      pulDataLen          /* gets p-text size */
13286+);
13287+#endif
13288+
13289+
13290+/* C_DecryptUpdate continues a multiple-part decryption
13291+ * operation. */
13292+CK_PKCS11_FUNCTION_INFO(C_DecryptUpdate)
13293+#ifdef CK_NEED_ARG_LIST
13294+(
13295+  CK_SESSION_HANDLE hSession,            /* session's handle */
13296+  CK_BYTE_PTR       pEncryptedPart,      /* encrypted data */
13297+  CK_ULONG          ulEncryptedPartLen,  /* input length */
13298+  CK_BYTE_PTR       pPart,               /* gets plaintext */
13299+  CK_ULONG_PTR      pulPartLen           /* p-text size */
13300+);
13301+#endif
13302+
13303+
13304+/* C_DecryptFinal finishes a multiple-part decryption
13305+ * operation. */
13306+CK_PKCS11_FUNCTION_INFO(C_DecryptFinal)
13307+#ifdef CK_NEED_ARG_LIST
13308+(
13309+  CK_SESSION_HANDLE hSession,       /* the session's handle */
13310+  CK_BYTE_PTR       pLastPart,      /* gets plaintext */
13311+  CK_ULONG_PTR      pulLastPartLen  /* p-text size */
13312+);
13313+#endif
13314+
13315+
13316+
13317+/* Message digesting */
13318+
13319+/* C_DigestInit initializes a message-digesting operation. */
13320+CK_PKCS11_FUNCTION_INFO(C_DigestInit)
13321+#ifdef CK_NEED_ARG_LIST
13322+(
13323+  CK_SESSION_HANDLE hSession,   /* the session's handle */
13324+  CK_MECHANISM_PTR  pMechanism  /* the digesting mechanism */
13325+);
13326+#endif
13327+
13328+
13329+/* C_Digest digests data in a single part. */
13330+CK_PKCS11_FUNCTION_INFO(C_Digest)
13331+#ifdef CK_NEED_ARG_LIST
13332+(
13333+  CK_SESSION_HANDLE hSession,     /* the session's handle */
13334+  CK_BYTE_PTR       pData,        /* data to be digested */
13335+  CK_ULONG          ulDataLen,    /* bytes of data to digest */
13336+  CK_BYTE_PTR       pDigest,      /* gets the message digest */
13337+  CK_ULONG_PTR      pulDigestLen  /* gets digest length */
13338+);
13339+#endif
13340+
13341+
13342+/* C_DigestUpdate continues a multiple-part message-digesting
13343+ * operation. */
13344+CK_PKCS11_FUNCTION_INFO(C_DigestUpdate)
13345+#ifdef CK_NEED_ARG_LIST
13346+(
13347+  CK_SESSION_HANDLE hSession,  /* the session's handle */
13348+  CK_BYTE_PTR       pPart,     /* data to be digested */
13349+  CK_ULONG          ulPartLen  /* bytes of data to be digested */
13350+);
13351+#endif
13352+
13353+
13354+/* C_DigestKey continues a multi-part message-digesting
13355+ * operation, by digesting the value of a secret key as part of
13356+ * the data already digested. */
13357+CK_PKCS11_FUNCTION_INFO(C_DigestKey)
13358+#ifdef CK_NEED_ARG_LIST
13359+(
13360+  CK_SESSION_HANDLE hSession,  /* the session's handle */
13361+  CK_OBJECT_HANDLE  hKey       /* secret key to digest */
13362+);
13363+#endif
13364+
13365+
13366+/* C_DigestFinal finishes a multiple-part message-digesting
13367+ * operation. */
13368+CK_PKCS11_FUNCTION_INFO(C_DigestFinal)
13369+#ifdef CK_NEED_ARG_LIST
13370+(
13371+  CK_SESSION_HANDLE hSession,     /* the session's handle */
13372+  CK_BYTE_PTR       pDigest,      /* gets the message digest */
13373+  CK_ULONG_PTR      pulDigestLen  /* gets byte count of digest */
13374+);
13375+#endif
13376+
13377+
13378+
13379+/* Signing and MACing */
13380+
13381+/* C_SignInit initializes a signature (private key encryption)
13382+ * operation, where the signature is (will be) an appendix to
13383+ * the data, and plaintext cannot be recovered from the
13384+ *signature. */
13385+CK_PKCS11_FUNCTION_INFO(C_SignInit)
13386+#ifdef CK_NEED_ARG_LIST
13387+(
13388+  CK_SESSION_HANDLE hSession,    /* the session's handle */
13389+  CK_MECHANISM_PTR  pMechanism,  /* the signature mechanism */
13390+  CK_OBJECT_HANDLE  hKey         /* handle of signature key */
13391+);
13392+#endif
13393+
13394+
13395+/* C_Sign signs (encrypts with private key) data in a single
13396+ * part, where the signature is (will be) an appendix to the
13397+ * data, and plaintext cannot be recovered from the signature. */
13398+CK_PKCS11_FUNCTION_INFO(C_Sign)
13399+#ifdef CK_NEED_ARG_LIST
13400+(
13401+  CK_SESSION_HANDLE hSession,        /* the session's handle */
13402+  CK_BYTE_PTR       pData,           /* the data to sign */
13403+  CK_ULONG          ulDataLen,       /* count of bytes to sign */
13404+  CK_BYTE_PTR       pSignature,      /* gets the signature */
13405+  CK_ULONG_PTR      pulSignatureLen  /* gets signature length */
13406+);
13407+#endif
13408+
13409+
13410+/* C_SignUpdate continues a multiple-part signature operation,
13411+ * where the signature is (will be) an appendix to the data, 
13412+ * and plaintext cannot be recovered from the signature. */
13413+CK_PKCS11_FUNCTION_INFO(C_SignUpdate)
13414+#ifdef CK_NEED_ARG_LIST
13415+(
13416+  CK_SESSION_HANDLE hSession,  /* the session's handle */
13417+  CK_BYTE_PTR       pPart,     /* the data to sign */
13418+  CK_ULONG          ulPartLen  /* count of bytes to sign */
13419+);
13420+#endif
13421+
13422+
13423+/* C_SignFinal finishes a multiple-part signature operation, 
13424+ * returning the signature. */
13425+CK_PKCS11_FUNCTION_INFO(C_SignFinal)
13426+#ifdef CK_NEED_ARG_LIST
13427+(
13428+  CK_SESSION_HANDLE hSession,        /* the session's handle */
13429+  CK_BYTE_PTR       pSignature,      /* gets the signature */
13430+  CK_ULONG_PTR      pulSignatureLen  /* gets signature length */
13431+);
13432+#endif
13433+
13434+
13435+/* C_SignRecoverInit initializes a signature operation, where
13436+ * the data can be recovered from the signature. */
13437+CK_PKCS11_FUNCTION_INFO(C_SignRecoverInit)
13438+#ifdef CK_NEED_ARG_LIST
13439+(
13440+  CK_SESSION_HANDLE hSession,   /* the session's handle */
13441+  CK_MECHANISM_PTR  pMechanism, /* the signature mechanism */
13442+  CK_OBJECT_HANDLE  hKey        /* handle of the signature key */
13443+);
13444+#endif
13445+
13446+
13447+/* C_SignRecover signs data in a single operation, where the
13448+ * data can be recovered from the signature. */
13449+CK_PKCS11_FUNCTION_INFO(C_SignRecover)
13450+#ifdef CK_NEED_ARG_LIST
13451+(
13452+  CK_SESSION_HANDLE hSession,        /* the session's handle */
13453+  CK_BYTE_PTR       pData,           /* the data to sign */
13454+  CK_ULONG          ulDataLen,       /* count of bytes to sign */
13455+  CK_BYTE_PTR       pSignature,      /* gets the signature */
13456+  CK_ULONG_PTR      pulSignatureLen  /* gets signature length */
13457+);
13458+#endif
13459+
13460+
13461+
13462+/* Verifying signatures and MACs */
13463+
13464+/* C_VerifyInit initializes a verification operation, where the
13465+ * signature is an appendix to the data, and plaintext cannot
13466+ *  cannot be recovered from the signature (e.g. DSA). */
13467+CK_PKCS11_FUNCTION_INFO(C_VerifyInit)
13468+#ifdef CK_NEED_ARG_LIST
13469+(
13470+  CK_SESSION_HANDLE hSession,    /* the session's handle */
13471+  CK_MECHANISM_PTR  pMechanism,  /* the verification mechanism */
13472+  CK_OBJECT_HANDLE  hKey         /* verification key */ 
13473+);
13474+#endif
13475+
13476+
13477+/* C_Verify verifies a signature in a single-part operation, 
13478+ * where the signature is an appendix to the data, and plaintext
13479+ * cannot be recovered from the signature. */
13480+CK_PKCS11_FUNCTION_INFO(C_Verify)
13481+#ifdef CK_NEED_ARG_LIST
13482+(
13483+  CK_SESSION_HANDLE hSession,       /* the session's handle */
13484+  CK_BYTE_PTR       pData,          /* signed data */
13485+  CK_ULONG          ulDataLen,      /* length of signed data */
13486+  CK_BYTE_PTR       pSignature,     /* signature */
13487+  CK_ULONG          ulSignatureLen  /* signature length*/
13488+);
13489+#endif
13490+
13491+
13492+/* C_VerifyUpdate continues a multiple-part verification
13493+ * operation, where the signature is an appendix to the data, 
13494+ * and plaintext cannot be recovered from the signature. */
13495+CK_PKCS11_FUNCTION_INFO(C_VerifyUpdate)
13496+#ifdef CK_NEED_ARG_LIST
13497+(
13498+  CK_SESSION_HANDLE hSession,  /* the session's handle */
13499+  CK_BYTE_PTR       pPart,     /* signed data */
13500+  CK_ULONG          ulPartLen  /* length of signed data */
13501+);
13502+#endif
13503+
13504+
13505+/* C_VerifyFinal finishes a multiple-part verification
13506+ * operation, checking the signature. */
13507+CK_PKCS11_FUNCTION_INFO(C_VerifyFinal)
13508+#ifdef CK_NEED_ARG_LIST
13509+(
13510+  CK_SESSION_HANDLE hSession,       /* the session's handle */
13511+  CK_BYTE_PTR       pSignature,     /* signature to verify */
13512+  CK_ULONG          ulSignatureLen  /* signature length */
13513+);
13514+#endif
13515+
13516+
13517+/* C_VerifyRecoverInit initializes a signature verification
13518+ * operation, where the data is recovered from the signature. */
13519+CK_PKCS11_FUNCTION_INFO(C_VerifyRecoverInit)
13520+#ifdef CK_NEED_ARG_LIST
13521+(
13522+  CK_SESSION_HANDLE hSession,    /* the session's handle */
13523+  CK_MECHANISM_PTR  pMechanism,  /* the verification mechanism */
13524+  CK_OBJECT_HANDLE  hKey         /* verification key */
13525+);
13526+#endif
13527+
13528+
13529+/* C_VerifyRecover verifies a signature in a single-part
13530+ * operation, where the data is recovered from the signature. */
13531+CK_PKCS11_FUNCTION_INFO(C_VerifyRecover)
13532+#ifdef CK_NEED_ARG_LIST
13533+(
13534+  CK_SESSION_HANDLE hSession,        /* the session's handle */
13535+  CK_BYTE_PTR       pSignature,      /* signature to verify */
13536+  CK_ULONG          ulSignatureLen,  /* signature length */
13537+  CK_BYTE_PTR       pData,           /* gets signed data */
13538+  CK_ULONG_PTR      pulDataLen       /* gets signed data len */
13539+);
13540+#endif
13541+
13542+
13543+
13544+/* Dual-function cryptographic operations */
13545+
13546+/* C_DigestEncryptUpdate continues a multiple-part digesting
13547+ * and encryption operation. */
13548+CK_PKCS11_FUNCTION_INFO(C_DigestEncryptUpdate)
13549+#ifdef CK_NEED_ARG_LIST
13550+(
13551+  CK_SESSION_HANDLE hSession,            /* session's handle */
13552+  CK_BYTE_PTR       pPart,               /* the plaintext data */
13553+  CK_ULONG          ulPartLen,           /* plaintext length */
13554+  CK_BYTE_PTR       pEncryptedPart,      /* gets ciphertext */
13555+  CK_ULONG_PTR      pulEncryptedPartLen  /* gets c-text length */
13556+);
13557+#endif
13558+
13559+
13560+/* C_DecryptDigestUpdate continues a multiple-part decryption and
13561+ * digesting operation. */
13562+CK_PKCS11_FUNCTION_INFO(C_DecryptDigestUpdate)
13563+#ifdef CK_NEED_ARG_LIST
13564+(
13565+  CK_SESSION_HANDLE hSession,            /* session's handle */
13566+  CK_BYTE_PTR       pEncryptedPart,      /* ciphertext */
13567+  CK_ULONG          ulEncryptedPartLen,  /* ciphertext length */
13568+  CK_BYTE_PTR       pPart,               /* gets plaintext */
13569+  CK_ULONG_PTR      pulPartLen           /* gets plaintext len */
13570+);
13571+#endif
13572+
13573+
13574+/* C_SignEncryptUpdate continues a multiple-part signing and
13575+ * encryption operation. */
13576+CK_PKCS11_FUNCTION_INFO(C_SignEncryptUpdate)
13577+#ifdef CK_NEED_ARG_LIST
13578+(
13579+  CK_SESSION_HANDLE hSession,            /* session's handle */
13580+  CK_BYTE_PTR       pPart,               /* the plaintext data */
13581+  CK_ULONG          ulPartLen,           /* plaintext length */
13582+  CK_BYTE_PTR       pEncryptedPart,      /* gets ciphertext */
13583+  CK_ULONG_PTR      pulEncryptedPartLen  /* gets c-text length */
13584+);
13585+#endif
13586+
13587+
13588+/* C_DecryptVerifyUpdate continues a multiple-part decryption and
13589+ * verify operation. */
13590+CK_PKCS11_FUNCTION_INFO(C_DecryptVerifyUpdate)
13591+#ifdef CK_NEED_ARG_LIST
13592+(
13593+  CK_SESSION_HANDLE hSession,            /* session's handle */
13594+  CK_BYTE_PTR       pEncryptedPart,      /* ciphertext */
13595+  CK_ULONG          ulEncryptedPartLen,  /* ciphertext length */
13596+  CK_BYTE_PTR       pPart,               /* gets plaintext */
13597+  CK_ULONG_PTR      pulPartLen           /* gets p-text length */
13598+);
13599+#endif
13600+
13601+
13602+
13603+/* Key management */
13604+
13605+/* C_GenerateKey generates a secret key, creating a new key
13606+ * object. */
13607+CK_PKCS11_FUNCTION_INFO(C_GenerateKey)
13608+#ifdef CK_NEED_ARG_LIST
13609+(
13610+  CK_SESSION_HANDLE    hSession,    /* the session's handle */
13611+  CK_MECHANISM_PTR     pMechanism,  /* key generation mech. */
13612+  CK_ATTRIBUTE_PTR     pTemplate,   /* template for new key */
13613+  CK_ULONG             ulCount,     /* # of attrs in template */
13614+  CK_OBJECT_HANDLE_PTR phKey        /* gets handle of new key */
13615+);
13616+#endif
13617+
13618+
13619+/* C_GenerateKeyPair generates a public-key/private-key pair, 
13620+ * creating new key objects. */
13621+CK_PKCS11_FUNCTION_INFO(C_GenerateKeyPair)
13622+#ifdef CK_NEED_ARG_LIST
13623+(
13624+  CK_SESSION_HANDLE    hSession,                    /* session
13625+                                                     * handle */
13626+  CK_MECHANISM_PTR     pMechanism,                  /* key-gen
13627+                                                     * mech. */
13628+  CK_ATTRIBUTE_PTR     pPublicKeyTemplate,          /* template
13629+                                                     * for pub.
13630+                                                     * key */
13631+  CK_ULONG             ulPublicKeyAttributeCount,   /* # pub.
13632+                                                     * attrs. */
13633+  CK_ATTRIBUTE_PTR     pPrivateKeyTemplate,         /* template
13634+                                                     * for priv.
13635+                                                     * key */
13636+  CK_ULONG             ulPrivateKeyAttributeCount,  /* # priv.
13637+                                                     * attrs. */
13638+  CK_OBJECT_HANDLE_PTR phPublicKey,                 /* gets pub.
13639+                                                     * key
13640+                                                     * handle */
13641+  CK_OBJECT_HANDLE_PTR phPrivateKey                 /* gets
13642+                                                     * priv. key
13643+                                                     * handle */
13644+);
13645+#endif
13646+
13647+
13648+/* C_WrapKey wraps (i.e., encrypts) a key. */
13649+CK_PKCS11_FUNCTION_INFO(C_WrapKey)
13650+#ifdef CK_NEED_ARG_LIST
13651+(
13652+  CK_SESSION_HANDLE hSession,        /* the session's handle */
13653+  CK_MECHANISM_PTR  pMechanism,      /* the wrapping mechanism */
13654+  CK_OBJECT_HANDLE  hWrappingKey,    /* wrapping key */
13655+  CK_OBJECT_HANDLE  hKey,            /* key to be wrapped */
13656+  CK_BYTE_PTR       pWrappedKey,     /* gets wrapped key */
13657+  CK_ULONG_PTR      pulWrappedKeyLen /* gets wrapped key size */
13658+);
13659+#endif
13660+
13661+
13662+/* C_UnwrapKey unwraps (decrypts) a wrapped key, creating a new
13663+ * key object. */
13664+CK_PKCS11_FUNCTION_INFO(C_UnwrapKey)
13665+#ifdef CK_NEED_ARG_LIST
13666+(
13667+  CK_SESSION_HANDLE    hSession,          /* session's handle */
13668+  CK_MECHANISM_PTR     pMechanism,        /* unwrapping mech. */
13669+  CK_OBJECT_HANDLE     hUnwrappingKey,    /* unwrapping key */
13670+  CK_BYTE_PTR          pWrappedKey,       /* the wrapped key */
13671+  CK_ULONG             ulWrappedKeyLen,   /* wrapped key len */
13672+  CK_ATTRIBUTE_PTR     pTemplate,         /* new key template */
13673+  CK_ULONG             ulAttributeCount,  /* template length */
13674+  CK_OBJECT_HANDLE_PTR phKey              /* gets new handle */
13675+);
13676+#endif
13677+
13678+
13679+/* C_DeriveKey derives a key from a base key, creating a new key
13680+ * object. */
13681+CK_PKCS11_FUNCTION_INFO(C_DeriveKey)
13682+#ifdef CK_NEED_ARG_LIST
13683+(
13684+  CK_SESSION_HANDLE    hSession,          /* session's handle */
13685+  CK_MECHANISM_PTR     pMechanism,        /* key deriv. mech. */
13686+  CK_OBJECT_HANDLE     hBaseKey,          /* base key */
13687+  CK_ATTRIBUTE_PTR     pTemplate,         /* new key template */
13688+  CK_ULONG             ulAttributeCount,  /* template length */
13689+  CK_OBJECT_HANDLE_PTR phKey              /* gets new handle */
13690+);
13691+#endif
13692+
13693+
13694+
13695+/* Random number generation */
13696+
13697+/* C_SeedRandom mixes additional seed material into the token's
13698+ * random number generator. */
13699+CK_PKCS11_FUNCTION_INFO(C_SeedRandom)
13700+#ifdef CK_NEED_ARG_LIST
13701+(
13702+  CK_SESSION_HANDLE hSession,  /* the session's handle */
13703+  CK_BYTE_PTR       pSeed,     /* the seed material */
13704+  CK_ULONG          ulSeedLen  /* length of seed material */
13705+);
13706+#endif
13707+
13708+
13709+/* C_GenerateRandom generates random data. */
13710+CK_PKCS11_FUNCTION_INFO(C_GenerateRandom)
13711+#ifdef CK_NEED_ARG_LIST
13712+(
13713+  CK_SESSION_HANDLE hSession,    /* the session's handle */
13714+  CK_BYTE_PTR       RandomData,  /* receives the random data */
13715+  CK_ULONG          ulRandomLen  /* # of bytes to generate */
13716+);
13717+#endif
13718+
13719+
13720+
13721+/* Parallel function management */
13722+
13723+/* C_GetFunctionStatus is a legacy function; it obtains an
13724+ * updated status of a function running in parallel with an
13725+ * application. */
13726+CK_PKCS11_FUNCTION_INFO(C_GetFunctionStatus)
13727+#ifdef CK_NEED_ARG_LIST
13728+(
13729+  CK_SESSION_HANDLE hSession  /* the session's handle */
13730+);
13731+#endif
13732+
13733+
13734+/* C_CancelFunction is a legacy function; it cancels a function
13735+ * running in parallel. */
13736+CK_PKCS11_FUNCTION_INFO(C_CancelFunction)
13737+#ifdef CK_NEED_ARG_LIST
13738+(
13739+  CK_SESSION_HANDLE hSession  /* the session's handle */
13740+);
13741+#endif
13742+
13743+
13744+
13745+/* Functions added in for Cryptoki Version 2.01 or later */
13746+
13747+/* C_WaitForSlotEvent waits for a slot event (token insertion,
13748+ * removal, etc.) to occur. */
13749+CK_PKCS11_FUNCTION_INFO(C_WaitForSlotEvent)
13750+#ifdef CK_NEED_ARG_LIST
13751+(
13752+  CK_FLAGS flags,        /* blocking/nonblocking flag */
13753+  CK_SLOT_ID_PTR pSlot,  /* location that receives the slot ID */
13754+  CK_VOID_PTR pRserved   /* reserved.  Should be NULL_PTR */
13755+);
13756+#endif
13757Index: openssl/crypto/engine/pkcs11t.h
13758diff -u /dev/null openssl/crypto/engine/pkcs11t.h:1.2
13759--- /dev/null	Mon Jan 16 18:54:23 2012
13760+++ openssl/crypto/engine/pkcs11t.h	Sat Aug 30 11:58:07 2008
13761@@ -0,0 +1,1885 @@
13762+/* pkcs11t.h include file for PKCS #11. */
13763+/* $Revision: 1.2.2.2 $ */
13764+
13765+/* License to copy and use this software is granted provided that it is
13766+ * identified as "RSA Security Inc. PKCS #11 Cryptographic Token Interface
13767+ * (Cryptoki)" in all material mentioning or referencing this software.
13768+
13769+ * License is also granted to make and use derivative works provided that
13770+ * such works are identified as "derived from the RSA Security Inc. PKCS #11
13771+ * Cryptographic Token Interface (Cryptoki)" in all material mentioning or
13772+ * referencing the derived work.
13773+
13774+ * RSA Security Inc. makes no representations concerning either the
13775+ * merchantability of this software or the suitability of this software for
13776+ * any particular purpose. It is provided "as is" without express or implied
13777+ * warranty of any kind.
13778+ */
13779+
13780+/* See top of pkcs11.h for information about the macros that
13781+ * must be defined and the structure-packing conventions that
13782+ * must be set before including this file. */
13783+
13784+#ifndef _PKCS11T_H_
13785+#define _PKCS11T_H_ 1
13786+
13787+#define CRYPTOKI_VERSION_MAJOR 2
13788+#define CRYPTOKI_VERSION_MINOR 20
13789+#define CRYPTOKI_VERSION_AMENDMENT 3
13790+
13791+#define CK_TRUE 1
13792+#define CK_FALSE 0
13793+
13794+#ifndef CK_DISABLE_TRUE_FALSE
13795+#ifndef FALSE
13796+#define FALSE CK_FALSE
13797+#endif
13798+
13799+#ifndef TRUE
13800+#define TRUE CK_TRUE
13801+#endif
13802+#endif
13803+
13804+/* an unsigned 8-bit value */
13805+typedef unsigned char     CK_BYTE;
13806+
13807+/* an unsigned 8-bit character */
13808+typedef CK_BYTE           CK_CHAR;
13809+
13810+/* an 8-bit UTF-8 character */
13811+typedef CK_BYTE           CK_UTF8CHAR;
13812+
13813+/* a BYTE-sized Boolean flag */
13814+typedef CK_BYTE           CK_BBOOL;
13815+
13816+/* an unsigned value, at least 32 bits long */
13817+typedef unsigned long int CK_ULONG;
13818+
13819+/* a signed value, the same size as a CK_ULONG */
13820+/* CK_LONG is new for v2.0 */
13821+typedef long int          CK_LONG;
13822+
13823+/* at least 32 bits; each bit is a Boolean flag */
13824+typedef CK_ULONG          CK_FLAGS;
13825+
13826+
13827+/* some special values for certain CK_ULONG variables */
13828+#define CK_UNAVAILABLE_INFORMATION (~0UL)
13829+#define CK_EFFECTIVELY_INFINITE    0
13830+
13831+
13832+typedef CK_BYTE     CK_PTR   CK_BYTE_PTR;
13833+typedef CK_CHAR     CK_PTR   CK_CHAR_PTR;
13834+typedef CK_UTF8CHAR CK_PTR   CK_UTF8CHAR_PTR;
13835+typedef CK_ULONG    CK_PTR   CK_ULONG_PTR;
13836+typedef void        CK_PTR   CK_VOID_PTR;
13837+
13838+/* Pointer to a CK_VOID_PTR-- i.e., pointer to pointer to void */
13839+typedef CK_VOID_PTR CK_PTR CK_VOID_PTR_PTR;
13840+
13841+
13842+/* The following value is always invalid if used as a session */
13843+/* handle or object handle */
13844+#define CK_INVALID_HANDLE 0
13845+
13846+
13847+typedef struct CK_VERSION {
13848+  CK_BYTE       major;  /* integer portion of version number */
13849+  CK_BYTE       minor;  /* 1/100ths portion of version number */
13850+} CK_VERSION;
13851+
13852+typedef CK_VERSION CK_PTR CK_VERSION_PTR;
13853+
13854+
13855+typedef struct CK_INFO {
13856+  /* manufacturerID and libraryDecription have been changed from
13857+   * CK_CHAR to CK_UTF8CHAR for v2.10 */
13858+  CK_VERSION    cryptokiVersion;     /* Cryptoki interface ver */
13859+  CK_UTF8CHAR   manufacturerID[32];  /* blank padded */
13860+  CK_FLAGS      flags;               /* must be zero */
13861+
13862+  /* libraryDescription and libraryVersion are new for v2.0 */
13863+  CK_UTF8CHAR   libraryDescription[32];  /* blank padded */
13864+  CK_VERSION    libraryVersion;          /* version of library */
13865+} CK_INFO;
13866+
13867+typedef CK_INFO CK_PTR    CK_INFO_PTR;
13868+
13869+
13870+/* CK_NOTIFICATION enumerates the types of notifications that
13871+ * Cryptoki provides to an application */
13872+/* CK_NOTIFICATION has been changed from an enum to a CK_ULONG
13873+ * for v2.0 */
13874+typedef CK_ULONG CK_NOTIFICATION;
13875+#define CKN_SURRENDER       0
13876+
13877+/* The following notification is new for PKCS #11 v2.20 amendment 3 */
13878+#define CKN_OTP_CHANGED     1
13879+
13880+
13881+typedef CK_ULONG          CK_SLOT_ID;
13882+
13883+typedef CK_SLOT_ID CK_PTR CK_SLOT_ID_PTR;
13884+
13885+
13886+/* CK_SLOT_INFO provides information about a slot */
13887+typedef struct CK_SLOT_INFO {
13888+  /* slotDescription and manufacturerID have been changed from
13889+   * CK_CHAR to CK_UTF8CHAR for v2.10 */
13890+  CK_UTF8CHAR   slotDescription[64];  /* blank padded */
13891+  CK_UTF8CHAR   manufacturerID[32];   /* blank padded */
13892+  CK_FLAGS      flags;
13893+
13894+  /* hardwareVersion and firmwareVersion are new for v2.0 */
13895+  CK_VERSION    hardwareVersion;  /* version of hardware */
13896+  CK_VERSION    firmwareVersion;  /* version of firmware */
13897+} CK_SLOT_INFO;
13898+
13899+/* flags: bit flags that provide capabilities of the slot
13900+ *      Bit Flag              Mask        Meaning
13901+ */
13902+#define CKF_TOKEN_PRESENT     0x00000001  /* a token is there */
13903+#define CKF_REMOVABLE_DEVICE  0x00000002  /* removable devices*/
13904+#define CKF_HW_SLOT           0x00000004  /* hardware slot */
13905+
13906+typedef CK_SLOT_INFO CK_PTR CK_SLOT_INFO_PTR;
13907+
13908+
13909+/* CK_TOKEN_INFO provides information about a token */
13910+typedef struct CK_TOKEN_INFO {
13911+  /* label, manufacturerID, and model have been changed from
13912+   * CK_CHAR to CK_UTF8CHAR for v2.10 */
13913+  CK_UTF8CHAR   label[32];           /* blank padded */
13914+  CK_UTF8CHAR   manufacturerID[32];  /* blank padded */
13915+  CK_UTF8CHAR   model[16];           /* blank padded */
13916+  CK_CHAR       serialNumber[16];    /* blank padded */
13917+  CK_FLAGS      flags;               /* see below */
13918+
13919+  /* ulMaxSessionCount, ulSessionCount, ulMaxRwSessionCount,
13920+   * ulRwSessionCount, ulMaxPinLen, and ulMinPinLen have all been
13921+   * changed from CK_USHORT to CK_ULONG for v2.0 */
13922+  CK_ULONG      ulMaxSessionCount;     /* max open sessions */
13923+  CK_ULONG      ulSessionCount;        /* sess. now open */
13924+  CK_ULONG      ulMaxRwSessionCount;   /* max R/W sessions */
13925+  CK_ULONG      ulRwSessionCount;      /* R/W sess. now open */
13926+  CK_ULONG      ulMaxPinLen;           /* in bytes */
13927+  CK_ULONG      ulMinPinLen;           /* in bytes */
13928+  CK_ULONG      ulTotalPublicMemory;   /* in bytes */
13929+  CK_ULONG      ulFreePublicMemory;    /* in bytes */
13930+  CK_ULONG      ulTotalPrivateMemory;  /* in bytes */
13931+  CK_ULONG      ulFreePrivateMemory;   /* in bytes */
13932+
13933+  /* hardwareVersion, firmwareVersion, and time are new for
13934+   * v2.0 */
13935+  CK_VERSION    hardwareVersion;       /* version of hardware */
13936+  CK_VERSION    firmwareVersion;       /* version of firmware */
13937+  CK_CHAR       utcTime[16];           /* time */
13938+} CK_TOKEN_INFO;
13939+
13940+/* The flags parameter is defined as follows:
13941+ *      Bit Flag                    Mask        Meaning
13942+ */
13943+#define CKF_RNG                     0x00000001  /* has random #
13944+                                                 * generator */
13945+#define CKF_WRITE_PROTECTED         0x00000002  /* token is
13946+                                                 * write-
13947+                                                 * protected */
13948+#define CKF_LOGIN_REQUIRED          0x00000004  /* user must
13949+                                                 * login */
13950+#define CKF_USER_PIN_INITIALIZED    0x00000008  /* normal user's
13951+                                                 * PIN is set */
13952+
13953+/* CKF_RESTORE_KEY_NOT_NEEDED is new for v2.0.  If it is set,
13954+ * that means that *every* time the state of cryptographic
13955+ * operations of a session is successfully saved, all keys
13956+ * needed to continue those operations are stored in the state */
13957+#define CKF_RESTORE_KEY_NOT_NEEDED  0x00000020
13958+
13959+/* CKF_CLOCK_ON_TOKEN is new for v2.0.  If it is set, that means
13960+ * that the token has some sort of clock.  The time on that
13961+ * clock is returned in the token info structure */
13962+#define CKF_CLOCK_ON_TOKEN          0x00000040
13963+
13964+/* CKF_PROTECTED_AUTHENTICATION_PATH is new for v2.0.  If it is
13965+ * set, that means that there is some way for the user to login
13966+ * without sending a PIN through the Cryptoki library itself */
13967+#define CKF_PROTECTED_AUTHENTICATION_PATH 0x00000100
13968+
13969+/* CKF_DUAL_CRYPTO_OPERATIONS is new for v2.0.  If it is true,
13970+ * that means that a single session with the token can perform
13971+ * dual simultaneous cryptographic operations (digest and
13972+ * encrypt; decrypt and digest; sign and encrypt; and decrypt
13973+ * and sign) */
13974+#define CKF_DUAL_CRYPTO_OPERATIONS  0x00000200
13975+
13976+/* CKF_TOKEN_INITIALIZED if new for v2.10. If it is true, the
13977+ * token has been initialized using C_InitializeToken or an
13978+ * equivalent mechanism outside the scope of PKCS #11.
13979+ * Calling C_InitializeToken when this flag is set will cause
13980+ * the token to be reinitialized. */
13981+#define CKF_TOKEN_INITIALIZED       0x00000400
13982+
13983+/* CKF_SECONDARY_AUTHENTICATION if new for v2.10. If it is
13984+ * true, the token supports secondary authentication for
13985+ * private key objects. This flag is deprecated in v2.11 and
13986+   onwards. */
13987+#define CKF_SECONDARY_AUTHENTICATION  0x00000800
13988+
13989+/* CKF_USER_PIN_COUNT_LOW if new for v2.10. If it is true, an
13990+ * incorrect user login PIN has been entered at least once
13991+ * since the last successful authentication. */
13992+#define CKF_USER_PIN_COUNT_LOW       0x00010000
13993+
13994+/* CKF_USER_PIN_FINAL_TRY if new for v2.10. If it is true,
13995+ * supplying an incorrect user PIN will it to become locked. */
13996+#define CKF_USER_PIN_FINAL_TRY       0x00020000
13997+
13998+/* CKF_USER_PIN_LOCKED if new for v2.10. If it is true, the
13999+ * user PIN has been locked. User login to the token is not
14000+ * possible. */
14001+#define CKF_USER_PIN_LOCKED          0x00040000
14002+
14003+/* CKF_USER_PIN_TO_BE_CHANGED if new for v2.10. If it is true,
14004+ * the user PIN value is the default value set by token
14005+ * initialization or manufacturing, or the PIN has been
14006+ * expired by the card. */
14007+#define CKF_USER_PIN_TO_BE_CHANGED   0x00080000
14008+
14009+/* CKF_SO_PIN_COUNT_LOW if new for v2.10. If it is true, an
14010+ * incorrect SO login PIN has been entered at least once since
14011+ * the last successful authentication. */
14012+#define CKF_SO_PIN_COUNT_LOW         0x00100000
14013+
14014+/* CKF_SO_PIN_FINAL_TRY if new for v2.10. If it is true,
14015+ * supplying an incorrect SO PIN will it to become locked. */
14016+#define CKF_SO_PIN_FINAL_TRY         0x00200000
14017+
14018+/* CKF_SO_PIN_LOCKED if new for v2.10. If it is true, the SO
14019+ * PIN has been locked. SO login to the token is not possible.
14020+ */
14021+#define CKF_SO_PIN_LOCKED            0x00400000
14022+
14023+/* CKF_SO_PIN_TO_BE_CHANGED if new for v2.10. If it is true,
14024+ * the SO PIN value is the default value set by token
14025+ * initialization or manufacturing, or the PIN has been
14026+ * expired by the card. */
14027+#define CKF_SO_PIN_TO_BE_CHANGED     0x00800000
14028+
14029+typedef CK_TOKEN_INFO CK_PTR CK_TOKEN_INFO_PTR;
14030+
14031+
14032+/* CK_SESSION_HANDLE is a Cryptoki-assigned value that
14033+ * identifies a session */
14034+typedef CK_ULONG          CK_SESSION_HANDLE;
14035+
14036+typedef CK_SESSION_HANDLE CK_PTR CK_SESSION_HANDLE_PTR;
14037+
14038+
14039+/* CK_USER_TYPE enumerates the types of Cryptoki users */
14040+/* CK_USER_TYPE has been changed from an enum to a CK_ULONG for
14041+ * v2.0 */
14042+typedef CK_ULONG          CK_USER_TYPE;
14043+/* Security Officer */
14044+#define CKU_SO    0
14045+/* Normal user */
14046+#define CKU_USER  1
14047+/* Context specific (added in v2.20) */
14048+#define CKU_CONTEXT_SPECIFIC   2
14049+
14050+/* CK_STATE enumerates the session states */
14051+/* CK_STATE has been changed from an enum to a CK_ULONG for
14052+ * v2.0 */
14053+typedef CK_ULONG          CK_STATE;
14054+#define CKS_RO_PUBLIC_SESSION  0
14055+#define CKS_RO_USER_FUNCTIONS  1
14056+#define CKS_RW_PUBLIC_SESSION  2
14057+#define CKS_RW_USER_FUNCTIONS  3
14058+#define CKS_RW_SO_FUNCTIONS    4
14059+
14060+
14061+/* CK_SESSION_INFO provides information about a session */
14062+typedef struct CK_SESSION_INFO {
14063+  CK_SLOT_ID    slotID;
14064+  CK_STATE      state;
14065+  CK_FLAGS      flags;          /* see below */
14066+
14067+  /* ulDeviceError was changed from CK_USHORT to CK_ULONG for
14068+   * v2.0 */
14069+  CK_ULONG      ulDeviceError;  /* device-dependent error code */
14070+} CK_SESSION_INFO;
14071+
14072+/* The flags are defined in the following table:
14073+ *      Bit Flag                Mask        Meaning
14074+ */
14075+#define CKF_RW_SESSION          0x00000002  /* session is r/w */
14076+#define CKF_SERIAL_SESSION      0x00000004  /* no parallel */
14077+
14078+typedef CK_SESSION_INFO CK_PTR CK_SESSION_INFO_PTR;
14079+
14080+
14081+/* CK_OBJECT_HANDLE is a token-specific identifier for an
14082+ * object  */
14083+typedef CK_ULONG          CK_OBJECT_HANDLE;
14084+
14085+typedef CK_OBJECT_HANDLE CK_PTR CK_OBJECT_HANDLE_PTR;
14086+
14087+
14088+/* CK_OBJECT_CLASS is a value that identifies the classes (or
14089+ * types) of objects that Cryptoki recognizes.  It is defined
14090+ * as follows: */
14091+/* CK_OBJECT_CLASS was changed from CK_USHORT to CK_ULONG for
14092+ * v2.0 */
14093+typedef CK_ULONG          CK_OBJECT_CLASS;
14094+
14095+/* The following classes of objects are defined: */
14096+/* CKO_HW_FEATURE is new for v2.10 */
14097+/* CKO_DOMAIN_PARAMETERS is new for v2.11 */
14098+/* CKO_MECHANISM is new for v2.20 */
14099+#define CKO_DATA              0x00000000
14100+#define CKO_CERTIFICATE       0x00000001
14101+#define CKO_PUBLIC_KEY        0x00000002
14102+#define CKO_PRIVATE_KEY       0x00000003
14103+#define CKO_SECRET_KEY        0x00000004
14104+#define CKO_HW_FEATURE        0x00000005
14105+#define CKO_DOMAIN_PARAMETERS 0x00000006
14106+#define CKO_MECHANISM         0x00000007
14107+
14108+/* CKO_OTP_KEY is new for PKCS #11 v2.20 amendment 1 */
14109+#define CKO_OTP_KEY           0x00000008
14110+
14111+#define CKO_VENDOR_DEFINED    0x80000000
14112+
14113+typedef CK_OBJECT_CLASS CK_PTR CK_OBJECT_CLASS_PTR;
14114+
14115+/* CK_HW_FEATURE_TYPE is new for v2.10. CK_HW_FEATURE_TYPE is a
14116+ * value that identifies the hardware feature type of an object
14117+ * with CK_OBJECT_CLASS equal to CKO_HW_FEATURE. */
14118+typedef CK_ULONG          CK_HW_FEATURE_TYPE;
14119+
14120+/* The following hardware feature types are defined */
14121+/* CKH_USER_INTERFACE is new for v2.20 */
14122+#define CKH_MONOTONIC_COUNTER  0x00000001
14123+#define CKH_CLOCK           0x00000002
14124+#define CKH_USER_INTERFACE  0x00000003
14125+#define CKH_VENDOR_DEFINED  0x80000000
14126+
14127+/* CK_KEY_TYPE is a value that identifies a key type */
14128+/* CK_KEY_TYPE was changed from CK_USHORT to CK_ULONG for v2.0 */
14129+typedef CK_ULONG          CK_KEY_TYPE;
14130+
14131+/* the following key types are defined: */
14132+#define CKK_RSA             0x00000000
14133+#define CKK_DSA             0x00000001
14134+#define CKK_DH              0x00000002
14135+
14136+/* CKK_ECDSA and CKK_KEA are new for v2.0 */
14137+/* CKK_ECDSA is deprecated in v2.11, CKK_EC is preferred. */
14138+#define CKK_ECDSA           0x00000003
14139+#define CKK_EC              0x00000003
14140+#define CKK_X9_42_DH        0x00000004
14141+#define CKK_KEA             0x00000005
14142+
14143+#define CKK_GENERIC_SECRET  0x00000010
14144+#define CKK_RC2             0x00000011
14145+#define CKK_RC4             0x00000012
14146+#define CKK_DES             0x00000013
14147+#define CKK_DES2            0x00000014
14148+#define CKK_DES3            0x00000015
14149+
14150+/* all these key types are new for v2.0 */
14151+#define CKK_CAST            0x00000016
14152+#define CKK_CAST3           0x00000017
14153+/* CKK_CAST5 is deprecated in v2.11, CKK_CAST128 is preferred. */
14154+#define CKK_CAST5           0x00000018
14155+#define CKK_CAST128         0x00000018
14156+#define CKK_RC5             0x00000019
14157+#define CKK_IDEA            0x0000001A
14158+#define CKK_SKIPJACK        0x0000001B
14159+#define CKK_BATON           0x0000001C
14160+#define CKK_JUNIPER         0x0000001D
14161+#define CKK_CDMF            0x0000001E
14162+#define CKK_AES             0x0000001F
14163+
14164+/* BlowFish and TwoFish are new for v2.20 */
14165+#define CKK_BLOWFISH        0x00000020
14166+#define CKK_TWOFISH         0x00000021
14167+
14168+/* SecurID, HOTP, and ACTI are new for PKCS #11 v2.20 amendment 1 */
14169+#define CKK_SECURID         0x00000022
14170+#define CKK_HOTP            0x00000023
14171+#define CKK_ACTI            0x00000024
14172+
14173+/* Camellia is new for PKCS #11 v2.20 amendment 3 */
14174+#define CKK_CAMELLIA                   0x00000025
14175+/* ARIA is new for PKCS #11 v2.20 amendment 3 */
14176+#define CKK_ARIA                       0x00000026
14177+
14178+
14179+#define CKK_VENDOR_DEFINED  0x80000000
14180+
14181+
14182+/* CK_CERTIFICATE_TYPE is a value that identifies a certificate
14183+ * type */
14184+/* CK_CERTIFICATE_TYPE was changed from CK_USHORT to CK_ULONG
14185+ * for v2.0 */
14186+typedef CK_ULONG          CK_CERTIFICATE_TYPE;
14187+
14188+/* The following certificate types are defined: */
14189+/* CKC_X_509_ATTR_CERT is new for v2.10 */
14190+/* CKC_WTLS is new for v2.20 */
14191+#define CKC_X_509           0x00000000
14192+#define CKC_X_509_ATTR_CERT 0x00000001
14193+#define CKC_WTLS            0x00000002
14194+#define CKC_VENDOR_DEFINED  0x80000000
14195+
14196+
14197+/* CK_ATTRIBUTE_TYPE is a value that identifies an attribute
14198+ * type */
14199+/* CK_ATTRIBUTE_TYPE was changed from CK_USHORT to CK_ULONG for
14200+ * v2.0 */
14201+typedef CK_ULONG          CK_ATTRIBUTE_TYPE;
14202+
14203+/* The CKF_ARRAY_ATTRIBUTE flag identifies an attribute which
14204+   consists of an array of values. */
14205+#define CKF_ARRAY_ATTRIBUTE    0x40000000
14206+
14207+/* The following OTP-related defines are new for PKCS #11 v2.20 amendment 1
14208+   and relates to the CKA_OTP_FORMAT attribute */
14209+#define CK_OTP_FORMAT_DECIMAL      0
14210+#define CK_OTP_FORMAT_HEXADECIMAL  1
14211+#define CK_OTP_FORMAT_ALPHANUMERIC 2
14212+#define CK_OTP_FORMAT_BINARY       3
14213+
14214+/* The following OTP-related defines are new for PKCS #11 v2.20 amendment 1
14215+   and relates to the CKA_OTP_..._REQUIREMENT attributes */
14216+#define CK_OTP_PARAM_IGNORED       0
14217+#define CK_OTP_PARAM_OPTIONAL      1
14218+#define CK_OTP_PARAM_MANDATORY     2
14219+
14220+/* The following attribute types are defined: */
14221+#define CKA_CLASS              0x00000000
14222+#define CKA_TOKEN              0x00000001
14223+#define CKA_PRIVATE            0x00000002
14224+#define CKA_LABEL              0x00000003
14225+#define CKA_APPLICATION        0x00000010
14226+#define CKA_VALUE              0x00000011
14227+
14228+/* CKA_OBJECT_ID is new for v2.10 */
14229+#define CKA_OBJECT_ID          0x00000012
14230+
14231+#define CKA_CERTIFICATE_TYPE   0x00000080
14232+#define CKA_ISSUER             0x00000081
14233+#define CKA_SERIAL_NUMBER      0x00000082
14234+
14235+/* CKA_AC_ISSUER, CKA_OWNER, and CKA_ATTR_TYPES are new
14236+ * for v2.10 */
14237+#define CKA_AC_ISSUER          0x00000083
14238+#define CKA_OWNER              0x00000084
14239+#define CKA_ATTR_TYPES         0x00000085
14240+
14241+/* CKA_TRUSTED is new for v2.11 */
14242+#define CKA_TRUSTED            0x00000086
14243+
14244+/* CKA_CERTIFICATE_CATEGORY ...
14245+ * CKA_CHECK_VALUE are new for v2.20 */
14246+#define CKA_CERTIFICATE_CATEGORY        0x00000087
14247+#define CKA_JAVA_MIDP_SECURITY_DOMAIN   0x00000088
14248+#define CKA_URL                         0x00000089
14249+#define CKA_HASH_OF_SUBJECT_PUBLIC_KEY  0x0000008A
14250+#define CKA_HASH_OF_ISSUER_PUBLIC_KEY   0x0000008B
14251+#define CKA_CHECK_VALUE                 0x00000090
14252+
14253+#define CKA_KEY_TYPE           0x00000100
14254+#define CKA_SUBJECT            0x00000101
14255+#define CKA_ID                 0x00000102
14256+#define CKA_SENSITIVE          0x00000103
14257+#define CKA_ENCRYPT            0x00000104
14258+#define CKA_DECRYPT            0x00000105
14259+#define CKA_WRAP               0x00000106
14260+#define CKA_UNWRAP             0x00000107
14261+#define CKA_SIGN               0x00000108
14262+#define CKA_SIGN_RECOVER       0x00000109
14263+#define CKA_VERIFY             0x0000010A
14264+#define CKA_VERIFY_RECOVER     0x0000010B
14265+#define CKA_DERIVE             0x0000010C
14266+#define CKA_START_DATE         0x00000110
14267+#define CKA_END_DATE           0x00000111
14268+#define CKA_MODULUS            0x00000120
14269+#define CKA_MODULUS_BITS       0x00000121
14270+#define CKA_PUBLIC_EXPONENT    0x00000122
14271+#define CKA_PRIVATE_EXPONENT   0x00000123
14272+#define CKA_PRIME_1            0x00000124
14273+#define CKA_PRIME_2            0x00000125
14274+#define CKA_EXPONENT_1         0x00000126
14275+#define CKA_EXPONENT_2         0x00000127
14276+#define CKA_COEFFICIENT        0x00000128
14277+#define CKA_PRIME              0x00000130
14278+#define CKA_SUBPRIME           0x00000131
14279+#define CKA_BASE               0x00000132
14280+
14281+/* CKA_PRIME_BITS and CKA_SUB_PRIME_BITS are new for v2.11 */
14282+#define CKA_PRIME_BITS         0x00000133
14283+#define CKA_SUBPRIME_BITS      0x00000134
14284+#define CKA_SUB_PRIME_BITS     CKA_SUBPRIME_BITS
14285+/* (To retain backwards-compatibility) */
14286+
14287+#define CKA_VALUE_BITS         0x00000160
14288+#define CKA_VALUE_LEN          0x00000161
14289+
14290+/* CKA_EXTRACTABLE, CKA_LOCAL, CKA_NEVER_EXTRACTABLE,
14291+ * CKA_ALWAYS_SENSITIVE, CKA_MODIFIABLE, CKA_ECDSA_PARAMS,
14292+ * and CKA_EC_POINT are new for v2.0 */
14293+#define CKA_EXTRACTABLE        0x00000162
14294+#define CKA_LOCAL              0x00000163
14295+#define CKA_NEVER_EXTRACTABLE  0x00000164
14296+#define CKA_ALWAYS_SENSITIVE   0x00000165
14297+
14298+/* CKA_KEY_GEN_MECHANISM is new for v2.11 */
14299+#define CKA_KEY_GEN_MECHANISM  0x00000166
14300+
14301+#define CKA_MODIFIABLE         0x00000170
14302+
14303+/* CKA_ECDSA_PARAMS is deprecated in v2.11,
14304+ * CKA_EC_PARAMS is preferred. */
14305+#define CKA_ECDSA_PARAMS       0x00000180
14306+#define CKA_EC_PARAMS          0x00000180
14307+
14308+#define CKA_EC_POINT           0x00000181
14309+
14310+/* CKA_SECONDARY_AUTH, CKA_AUTH_PIN_FLAGS,
14311+ * are new for v2.10. Deprecated in v2.11 and onwards. */
14312+#define CKA_SECONDARY_AUTH     0x00000200
14313+#define CKA_AUTH_PIN_FLAGS     0x00000201
14314+
14315+/* CKA_ALWAYS_AUTHENTICATE ...
14316+ * CKA_UNWRAP_TEMPLATE are new for v2.20 */
14317+#define CKA_ALWAYS_AUTHENTICATE  0x00000202
14318+
14319+#define CKA_WRAP_WITH_TRUSTED    0x00000210
14320+#define CKA_WRAP_TEMPLATE        (CKF_ARRAY_ATTRIBUTE|0x00000211)
14321+#define CKA_UNWRAP_TEMPLATE      (CKF_ARRAY_ATTRIBUTE|0x00000212)
14322+
14323+/* CKA_OTP... atttributes are new for PKCS #11 v2.20 amendment 3. */
14324+#define CKA_OTP_FORMAT                0x00000220
14325+#define CKA_OTP_LENGTH                0x00000221
14326+#define CKA_OTP_TIME_INTERVAL         0x00000222
14327+#define CKA_OTP_USER_FRIENDLY_MODE    0x00000223
14328+#define CKA_OTP_CHALLENGE_REQUIREMENT 0x00000224
14329+#define CKA_OTP_TIME_REQUIREMENT      0x00000225
14330+#define CKA_OTP_COUNTER_REQUIREMENT   0x00000226
14331+#define CKA_OTP_PIN_REQUIREMENT       0x00000227
14332+#define CKA_OTP_COUNTER               0x0000022E
14333+#define CKA_OTP_TIME                  0x0000022F
14334+#define CKA_OTP_USER_IDENTIFIER       0x0000022A
14335+#define CKA_OTP_SERVICE_IDENTIFIER    0x0000022B
14336+#define CKA_OTP_SERVICE_LOGO          0x0000022C
14337+#define CKA_OTP_SERVICE_LOGO_TYPE     0x0000022D
14338+
14339+
14340+/* CKA_HW_FEATURE_TYPE, CKA_RESET_ON_INIT, and CKA_HAS_RESET
14341+ * are new for v2.10 */
14342+#define CKA_HW_FEATURE_TYPE    0x00000300
14343+#define CKA_RESET_ON_INIT      0x00000301
14344+#define CKA_HAS_RESET          0x00000302
14345+
14346+/* The following attributes are new for v2.20 */
14347+#define CKA_PIXEL_X                     0x00000400
14348+#define CKA_PIXEL_Y                     0x00000401
14349+#define CKA_RESOLUTION                  0x00000402
14350+#define CKA_CHAR_ROWS                   0x00000403
14351+#define CKA_CHAR_COLUMNS                0x00000404
14352+#define CKA_COLOR                       0x00000405
14353+#define CKA_BITS_PER_PIXEL              0x00000406
14354+#define CKA_CHAR_SETS                   0x00000480
14355+#define CKA_ENCODING_METHODS            0x00000481
14356+#define CKA_MIME_TYPES                  0x00000482
14357+#define CKA_MECHANISM_TYPE              0x00000500
14358+#define CKA_REQUIRED_CMS_ATTRIBUTES     0x00000501
14359+#define CKA_DEFAULT_CMS_ATTRIBUTES      0x00000502
14360+#define CKA_SUPPORTED_CMS_ATTRIBUTES    0x00000503
14361+#define CKA_ALLOWED_MECHANISMS          (CKF_ARRAY_ATTRIBUTE|0x00000600)
14362+
14363+#define CKA_VENDOR_DEFINED     0x80000000
14364+
14365+/* CK_ATTRIBUTE is a structure that includes the type, length
14366+ * and value of an attribute */
14367+typedef struct CK_ATTRIBUTE {
14368+  CK_ATTRIBUTE_TYPE type;
14369+  CK_VOID_PTR       pValue;
14370+
14371+  /* ulValueLen went from CK_USHORT to CK_ULONG for v2.0 */
14372+  CK_ULONG          ulValueLen;  /* in bytes */
14373+} CK_ATTRIBUTE;
14374+
14375+typedef CK_ATTRIBUTE CK_PTR CK_ATTRIBUTE_PTR;
14376+
14377+
14378+/* CK_DATE is a structure that defines a date */
14379+typedef struct CK_DATE{
14380+  CK_CHAR       year[4];   /* the year ("1900" - "9999") */
14381+  CK_CHAR       month[2];  /* the month ("01" - "12") */
14382+  CK_CHAR       day[2];    /* the day   ("01" - "31") */
14383+} CK_DATE;
14384+
14385+
14386+/* CK_MECHANISM_TYPE is a value that identifies a mechanism
14387+ * type */
14388+/* CK_MECHANISM_TYPE was changed from CK_USHORT to CK_ULONG for
14389+ * v2.0 */
14390+typedef CK_ULONG          CK_MECHANISM_TYPE;
14391+
14392+/* the following mechanism types are defined: */
14393+#define CKM_RSA_PKCS_KEY_PAIR_GEN      0x00000000
14394+#define CKM_RSA_PKCS                   0x00000001
14395+#define CKM_RSA_9796                   0x00000002
14396+#define CKM_RSA_X_509                  0x00000003
14397+
14398+/* CKM_MD2_RSA_PKCS, CKM_MD5_RSA_PKCS, and CKM_SHA1_RSA_PKCS
14399+ * are new for v2.0.  They are mechanisms which hash and sign */
14400+#define CKM_MD2_RSA_PKCS               0x00000004
14401+#define CKM_MD5_RSA_PKCS               0x00000005
14402+#define CKM_SHA1_RSA_PKCS              0x00000006
14403+
14404+/* CKM_RIPEMD128_RSA_PKCS, CKM_RIPEMD160_RSA_PKCS, and
14405+ * CKM_RSA_PKCS_OAEP are new for v2.10 */
14406+#define CKM_RIPEMD128_RSA_PKCS         0x00000007
14407+#define CKM_RIPEMD160_RSA_PKCS         0x00000008
14408+#define CKM_RSA_PKCS_OAEP              0x00000009
14409+
14410+/* CKM_RSA_X9_31_KEY_PAIR_GEN, CKM_RSA_X9_31, CKM_SHA1_RSA_X9_31,
14411+ * CKM_RSA_PKCS_PSS, and CKM_SHA1_RSA_PKCS_PSS are new for v2.11 */
14412+#define CKM_RSA_X9_31_KEY_PAIR_GEN     0x0000000A
14413+#define CKM_RSA_X9_31                  0x0000000B
14414+#define CKM_SHA1_RSA_X9_31             0x0000000C
14415+#define CKM_RSA_PKCS_PSS               0x0000000D
14416+#define CKM_SHA1_RSA_PKCS_PSS          0x0000000E
14417+
14418+#define CKM_DSA_KEY_PAIR_GEN           0x00000010
14419+#define CKM_DSA                        0x00000011
14420+#define CKM_DSA_SHA1                   0x00000012
14421+#define CKM_DH_PKCS_KEY_PAIR_GEN       0x00000020
14422+#define CKM_DH_PKCS_DERIVE             0x00000021
14423+
14424+/* CKM_X9_42_DH_KEY_PAIR_GEN, CKM_X9_42_DH_DERIVE,
14425+ * CKM_X9_42_DH_HYBRID_DERIVE, and CKM_X9_42_MQV_DERIVE are new for
14426+ * v2.11 */
14427+#define CKM_X9_42_DH_KEY_PAIR_GEN      0x00000030
14428+#define CKM_X9_42_DH_DERIVE            0x00000031
14429+#define CKM_X9_42_DH_HYBRID_DERIVE     0x00000032
14430+#define CKM_X9_42_MQV_DERIVE           0x00000033
14431+
14432+/* CKM_SHA256/384/512 are new for v2.20 */
14433+#define CKM_SHA256_RSA_PKCS            0x00000040
14434+#define CKM_SHA384_RSA_PKCS            0x00000041
14435+#define CKM_SHA512_RSA_PKCS            0x00000042
14436+#define CKM_SHA256_RSA_PKCS_PSS        0x00000043
14437+#define CKM_SHA384_RSA_PKCS_PSS        0x00000044
14438+#define CKM_SHA512_RSA_PKCS_PSS        0x00000045
14439+
14440+/* SHA-224 RSA mechanisms are new for PKCS #11 v2.20 amendment 3 */
14441+#define CKM_SHA224_RSA_PKCS            0x00000046
14442+#define CKM_SHA224_RSA_PKCS_PSS        0x00000047
14443+
14444+#define CKM_RC2_KEY_GEN                0x00000100
14445+#define CKM_RC2_ECB                    0x00000101
14446+#define CKM_RC2_CBC                    0x00000102
14447+#define CKM_RC2_MAC                    0x00000103
14448+
14449+/* CKM_RC2_MAC_GENERAL and CKM_RC2_CBC_PAD are new for v2.0 */
14450+#define CKM_RC2_MAC_GENERAL            0x00000104
14451+#define CKM_RC2_CBC_PAD                0x00000105
14452+
14453+#define CKM_RC4_KEY_GEN                0x00000110
14454+#define CKM_RC4                        0x00000111
14455+#define CKM_DES_KEY_GEN                0x00000120
14456+#define CKM_DES_ECB                    0x00000121
14457+#define CKM_DES_CBC                    0x00000122
14458+#define CKM_DES_MAC                    0x00000123
14459+
14460+/* CKM_DES_MAC_GENERAL and CKM_DES_CBC_PAD are new for v2.0 */
14461+#define CKM_DES_MAC_GENERAL            0x00000124
14462+#define CKM_DES_CBC_PAD                0x00000125
14463+
14464+#define CKM_DES2_KEY_GEN               0x00000130
14465+#define CKM_DES3_KEY_GEN               0x00000131
14466+#define CKM_DES3_ECB                   0x00000132
14467+#define CKM_DES3_CBC                   0x00000133
14468+#define CKM_DES3_MAC                   0x00000134
14469+
14470+/* CKM_DES3_MAC_GENERAL, CKM_DES3_CBC_PAD, CKM_CDMF_KEY_GEN,
14471+ * CKM_CDMF_ECB, CKM_CDMF_CBC, CKM_CDMF_MAC,
14472+ * CKM_CDMF_MAC_GENERAL, and CKM_CDMF_CBC_PAD are new for v2.0 */
14473+#define CKM_DES3_MAC_GENERAL           0x00000135
14474+#define CKM_DES3_CBC_PAD               0x00000136
14475+#define CKM_CDMF_KEY_GEN               0x00000140
14476+#define CKM_CDMF_ECB                   0x00000141
14477+#define CKM_CDMF_CBC                   0x00000142
14478+#define CKM_CDMF_MAC                   0x00000143
14479+#define CKM_CDMF_MAC_GENERAL           0x00000144
14480+#define CKM_CDMF_CBC_PAD               0x00000145
14481+
14482+/* the following four DES mechanisms are new for v2.20 */
14483+#define CKM_DES_OFB64                  0x00000150
14484+#define CKM_DES_OFB8                   0x00000151
14485+#define CKM_DES_CFB64                  0x00000152
14486+#define CKM_DES_CFB8                   0x00000153
14487+
14488+#define CKM_MD2                        0x00000200
14489+
14490+/* CKM_MD2_HMAC and CKM_MD2_HMAC_GENERAL are new for v2.0 */
14491+#define CKM_MD2_HMAC                   0x00000201
14492+#define CKM_MD2_HMAC_GENERAL           0x00000202
14493+
14494+#define CKM_MD5                        0x00000210
14495+
14496+/* CKM_MD5_HMAC and CKM_MD5_HMAC_GENERAL are new for v2.0 */
14497+#define CKM_MD5_HMAC                   0x00000211
14498+#define CKM_MD5_HMAC_GENERAL           0x00000212
14499+
14500+#define CKM_SHA_1                      0x00000220
14501+
14502+/* CKM_SHA_1_HMAC and CKM_SHA_1_HMAC_GENERAL are new for v2.0 */
14503+#define CKM_SHA_1_HMAC                 0x00000221
14504+#define CKM_SHA_1_HMAC_GENERAL         0x00000222
14505+
14506+/* CKM_RIPEMD128, CKM_RIPEMD128_HMAC,
14507+ * CKM_RIPEMD128_HMAC_GENERAL, CKM_RIPEMD160, CKM_RIPEMD160_HMAC,
14508+ * and CKM_RIPEMD160_HMAC_GENERAL are new for v2.10 */
14509+#define CKM_RIPEMD128                  0x00000230
14510+#define CKM_RIPEMD128_HMAC             0x00000231
14511+#define CKM_RIPEMD128_HMAC_GENERAL     0x00000232
14512+#define CKM_RIPEMD160                  0x00000240
14513+#define CKM_RIPEMD160_HMAC             0x00000241
14514+#define CKM_RIPEMD160_HMAC_GENERAL     0x00000242
14515+
14516+/* CKM_SHA256/384/512 are new for v2.20 */
14517+#define CKM_SHA256                     0x00000250
14518+#define CKM_SHA256_HMAC                0x00000251
14519+#define CKM_SHA256_HMAC_GENERAL        0x00000252
14520+
14521+/* SHA-224 is new for PKCS #11 v2.20 amendment 3 */
14522+#define CKM_SHA224                     0x00000255
14523+#define CKM_SHA224_HMAC                0x00000256
14524+#define CKM_SHA224_HMAC_GENERAL        0x00000257
14525+
14526+#define CKM_SHA384                     0x00000260
14527+#define CKM_SHA384_HMAC                0x00000261
14528+#define CKM_SHA384_HMAC_GENERAL        0x00000262
14529+#define CKM_SHA512                     0x00000270
14530+#define CKM_SHA512_HMAC                0x00000271
14531+#define CKM_SHA512_HMAC_GENERAL        0x00000272
14532+
14533+/* SecurID is new for PKCS #11 v2.20 amendment 1 */
14534+#define CKM_SECURID_KEY_GEN            0x00000280
14535+#define CKM_SECURID                    0x00000282
14536+
14537+/* HOTP is new for PKCS #11 v2.20 amendment 1 */
14538+#define CKM_HOTP_KEY_GEN    0x00000290
14539+#define CKM_HOTP            0x00000291
14540+
14541+/* ACTI is new for PKCS #11 v2.20 amendment 1 */
14542+#define CKM_ACTI            0x000002A0
14543+#define CKM_ACTI_KEY_GEN    0x000002A1
14544+
14545+/* All of the following mechanisms are new for v2.0 */
14546+/* Note that CAST128 and CAST5 are the same algorithm */
14547+#define CKM_CAST_KEY_GEN               0x00000300
14548+#define CKM_CAST_ECB                   0x00000301
14549+#define CKM_CAST_CBC                   0x00000302
14550+#define CKM_CAST_MAC                   0x00000303
14551+#define CKM_CAST_MAC_GENERAL           0x00000304
14552+#define CKM_CAST_CBC_PAD               0x00000305
14553+#define CKM_CAST3_KEY_GEN              0x00000310
14554+#define CKM_CAST3_ECB                  0x00000311
14555+#define CKM_CAST3_CBC                  0x00000312
14556+#define CKM_CAST3_MAC                  0x00000313
14557+#define CKM_CAST3_MAC_GENERAL          0x00000314
14558+#define CKM_CAST3_CBC_PAD              0x00000315
14559+#define CKM_CAST5_KEY_GEN              0x00000320
14560+#define CKM_CAST128_KEY_GEN            0x00000320
14561+#define CKM_CAST5_ECB                  0x00000321
14562+#define CKM_CAST128_ECB                0x00000321
14563+#define CKM_CAST5_CBC                  0x00000322
14564+#define CKM_CAST128_CBC                0x00000322
14565+#define CKM_CAST5_MAC                  0x00000323
14566+#define CKM_CAST128_MAC                0x00000323
14567+#define CKM_CAST5_MAC_GENERAL          0x00000324
14568+#define CKM_CAST128_MAC_GENERAL        0x00000324
14569+#define CKM_CAST5_CBC_PAD              0x00000325
14570+#define CKM_CAST128_CBC_PAD            0x00000325
14571+#define CKM_RC5_KEY_GEN                0x00000330
14572+#define CKM_RC5_ECB                    0x00000331
14573+#define CKM_RC5_CBC                    0x00000332
14574+#define CKM_RC5_MAC                    0x00000333
14575+#define CKM_RC5_MAC_GENERAL            0x00000334
14576+#define CKM_RC5_CBC_PAD                0x00000335
14577+#define CKM_IDEA_KEY_GEN               0x00000340
14578+#define CKM_IDEA_ECB                   0x00000341
14579+#define CKM_IDEA_CBC                   0x00000342
14580+#define CKM_IDEA_MAC                   0x00000343
14581+#define CKM_IDEA_MAC_GENERAL           0x00000344
14582+#define CKM_IDEA_CBC_PAD               0x00000345
14583+#define CKM_GENERIC_SECRET_KEY_GEN     0x00000350
14584+#define CKM_CONCATENATE_BASE_AND_KEY   0x00000360
14585+#define CKM_CONCATENATE_BASE_AND_DATA  0x00000362
14586+#define CKM_CONCATENATE_DATA_AND_BASE  0x00000363
14587+#define CKM_XOR_BASE_AND_DATA          0x00000364
14588+#define CKM_EXTRACT_KEY_FROM_KEY       0x00000365
14589+#define CKM_SSL3_PRE_MASTER_KEY_GEN    0x00000370
14590+#define CKM_SSL3_MASTER_KEY_DERIVE     0x00000371
14591+#define CKM_SSL3_KEY_AND_MAC_DERIVE    0x00000372
14592+
14593+/* CKM_SSL3_MASTER_KEY_DERIVE_DH, CKM_TLS_PRE_MASTER_KEY_GEN,
14594+ * CKM_TLS_MASTER_KEY_DERIVE, CKM_TLS_KEY_AND_MAC_DERIVE, and
14595+ * CKM_TLS_MASTER_KEY_DERIVE_DH are new for v2.11 */
14596+#define CKM_SSL3_MASTER_KEY_DERIVE_DH  0x00000373
14597+#define CKM_TLS_PRE_MASTER_KEY_GEN     0x00000374
14598+#define CKM_TLS_MASTER_KEY_DERIVE      0x00000375
14599+#define CKM_TLS_KEY_AND_MAC_DERIVE     0x00000376
14600+#define CKM_TLS_MASTER_KEY_DERIVE_DH   0x00000377
14601+
14602+/* CKM_TLS_PRF is new for v2.20 */
14603+#define CKM_TLS_PRF                    0x00000378
14604+
14605+#define CKM_SSL3_MD5_MAC               0x00000380
14606+#define CKM_SSL3_SHA1_MAC              0x00000381
14607+#define CKM_MD5_KEY_DERIVATION         0x00000390
14608+#define CKM_MD2_KEY_DERIVATION         0x00000391
14609+#define CKM_SHA1_KEY_DERIVATION        0x00000392
14610+
14611+/* CKM_SHA256/384/512 are new for v2.20 */
14612+#define CKM_SHA256_KEY_DERIVATION      0x00000393
14613+#define CKM_SHA384_KEY_DERIVATION      0x00000394
14614+#define CKM_SHA512_KEY_DERIVATION      0x00000395
14615+
14616+/* SHA-224 key derivation is new for PKCS #11 v2.20 amendment 3 */
14617+#define CKM_SHA224_KEY_DERIVATION      0x00000396
14618+
14619+#define CKM_PBE_MD2_DES_CBC            0x000003A0
14620+#define CKM_PBE_MD5_DES_CBC            0x000003A1
14621+#define CKM_PBE_MD5_CAST_CBC           0x000003A2
14622+#define CKM_PBE_MD5_CAST3_CBC          0x000003A3
14623+#define CKM_PBE_MD5_CAST5_CBC          0x000003A4
14624+#define CKM_PBE_MD5_CAST128_CBC        0x000003A4
14625+#define CKM_PBE_SHA1_CAST5_CBC         0x000003A5
14626+#define CKM_PBE_SHA1_CAST128_CBC       0x000003A5
14627+#define CKM_PBE_SHA1_RC4_128           0x000003A6
14628+#define CKM_PBE_SHA1_RC4_40            0x000003A7
14629+#define CKM_PBE_SHA1_DES3_EDE_CBC      0x000003A8
14630+#define CKM_PBE_SHA1_DES2_EDE_CBC      0x000003A9
14631+#define CKM_PBE_SHA1_RC2_128_CBC       0x000003AA
14632+#define CKM_PBE_SHA1_RC2_40_CBC        0x000003AB
14633+
14634+/* CKM_PKCS5_PBKD2 is new for v2.10 */
14635+#define CKM_PKCS5_PBKD2                0x000003B0
14636+
14637+#define CKM_PBA_SHA1_WITH_SHA1_HMAC    0x000003C0
14638+
14639+/* WTLS mechanisms are new for v2.20 */
14640+#define CKM_WTLS_PRE_MASTER_KEY_GEN         0x000003D0
14641+#define CKM_WTLS_MASTER_KEY_DERIVE          0x000003D1
14642+#define CKM_WTLS_MASTER_KEY_DERIVE_DH_ECC   0x000003D2
14643+#define CKM_WTLS_PRF                        0x000003D3
14644+#define CKM_WTLS_SERVER_KEY_AND_MAC_DERIVE  0x000003D4
14645+#define CKM_WTLS_CLIENT_KEY_AND_MAC_DERIVE  0x000003D5
14646+
14647+#define CKM_KEY_WRAP_LYNKS             0x00000400
14648+#define CKM_KEY_WRAP_SET_OAEP          0x00000401
14649+
14650+/* CKM_CMS_SIG is new for v2.20 */
14651+#define CKM_CMS_SIG                    0x00000500
14652+
14653+/* CKM_KIP mechanisms are new for PKCS #11 v2.20 amendment 2 */
14654+#define CKM_KIP_DERIVE                 0x00000510
14655+#define CKM_KIP_WRAP                   0x00000511
14656+#define CKM_KIP_MAC                    0x00000512
14657+
14658+/* Camellia is new for PKCS #11 v2.20 amendment 3 */
14659+#define CKM_CAMELLIA_KEY_GEN           0x00000550
14660+#define CKM_CAMELLIA_ECB               0x00000551
14661+#define CKM_CAMELLIA_CBC               0x00000552
14662+#define CKM_CAMELLIA_MAC               0x00000553
14663+#define CKM_CAMELLIA_MAC_GENERAL       0x00000554
14664+#define CKM_CAMELLIA_CBC_PAD           0x00000555
14665+#define CKM_CAMELLIA_ECB_ENCRYPT_DATA  0x00000556
14666+#define CKM_CAMELLIA_CBC_ENCRYPT_DATA  0x00000557
14667+#define CKM_CAMELLIA_CTR               0x00000558
14668+
14669+/* ARIA is new for PKCS #11 v2.20 amendment 3 */
14670+#define CKM_ARIA_KEY_GEN               0x00000560
14671+#define CKM_ARIA_ECB                   0x00000561
14672+#define CKM_ARIA_CBC                   0x00000562
14673+#define CKM_ARIA_MAC                   0x00000563
14674+#define CKM_ARIA_MAC_GENERAL           0x00000564
14675+#define CKM_ARIA_CBC_PAD               0x00000565
14676+#define CKM_ARIA_ECB_ENCRYPT_DATA      0x00000566
14677+#define CKM_ARIA_CBC_ENCRYPT_DATA      0x00000567
14678+
14679+/* Fortezza mechanisms */
14680+#define CKM_SKIPJACK_KEY_GEN           0x00001000
14681+#define CKM_SKIPJACK_ECB64             0x00001001
14682+#define CKM_SKIPJACK_CBC64             0x00001002
14683+#define CKM_SKIPJACK_OFB64             0x00001003
14684+#define CKM_SKIPJACK_CFB64             0x00001004
14685+#define CKM_SKIPJACK_CFB32             0x00001005
14686+#define CKM_SKIPJACK_CFB16             0x00001006
14687+#define CKM_SKIPJACK_CFB8              0x00001007
14688+#define CKM_SKIPJACK_WRAP              0x00001008
14689+#define CKM_SKIPJACK_PRIVATE_WRAP      0x00001009
14690+#define CKM_SKIPJACK_RELAYX            0x0000100a
14691+#define CKM_KEA_KEY_PAIR_GEN           0x00001010
14692+#define CKM_KEA_KEY_DERIVE             0x00001011
14693+#define CKM_FORTEZZA_TIMESTAMP         0x00001020
14694+#define CKM_BATON_KEY_GEN              0x00001030
14695+#define CKM_BATON_ECB128               0x00001031
14696+#define CKM_BATON_ECB96                0x00001032
14697+#define CKM_BATON_CBC128               0x00001033
14698+#define CKM_BATON_COUNTER              0x00001034
14699+#define CKM_BATON_SHUFFLE              0x00001035
14700+#define CKM_BATON_WRAP                 0x00001036
14701+
14702+/* CKM_ECDSA_KEY_PAIR_GEN is deprecated in v2.11,
14703+ * CKM_EC_KEY_PAIR_GEN is preferred */
14704+#define CKM_ECDSA_KEY_PAIR_GEN         0x00001040
14705+#define CKM_EC_KEY_PAIR_GEN            0x00001040
14706+
14707+#define CKM_ECDSA                      0x00001041
14708+#define CKM_ECDSA_SHA1                 0x00001042
14709+
14710+/* CKM_ECDH1_DERIVE, CKM_ECDH1_COFACTOR_DERIVE, and CKM_ECMQV_DERIVE
14711+ * are new for v2.11 */
14712+#define CKM_ECDH1_DERIVE               0x00001050
14713+#define CKM_ECDH1_COFACTOR_DERIVE      0x00001051
14714+#define CKM_ECMQV_DERIVE               0x00001052
14715+
14716+#define CKM_JUNIPER_KEY_GEN            0x00001060
14717+#define CKM_JUNIPER_ECB128             0x00001061
14718+#define CKM_JUNIPER_CBC128             0x00001062
14719+#define CKM_JUNIPER_COUNTER            0x00001063
14720+#define CKM_JUNIPER_SHUFFLE            0x00001064
14721+#define CKM_JUNIPER_WRAP               0x00001065
14722+#define CKM_FASTHASH                   0x00001070
14723+
14724+/* CKM_AES_KEY_GEN, CKM_AES_ECB, CKM_AES_CBC, CKM_AES_MAC,
14725+ * CKM_AES_MAC_GENERAL, CKM_AES_CBC_PAD, CKM_DSA_PARAMETER_GEN,
14726+ * CKM_DH_PKCS_PARAMETER_GEN, and CKM_X9_42_DH_PARAMETER_GEN are
14727+ * new for v2.11 */
14728+#define CKM_AES_KEY_GEN                0x00001080
14729+#define CKM_AES_ECB                    0x00001081
14730+#define CKM_AES_CBC                    0x00001082
14731+#define CKM_AES_MAC                    0x00001083
14732+#define CKM_AES_MAC_GENERAL            0x00001084
14733+#define CKM_AES_CBC_PAD                0x00001085
14734+
14735+/* AES counter mode is new for PKCS #11 v2.20 amendment 3 */
14736+#define CKM_AES_CTR                    0x00001086
14737+
14738+/* BlowFish and TwoFish are new for v2.20 */
14739+#define CKM_BLOWFISH_KEY_GEN           0x00001090
14740+#define CKM_BLOWFISH_CBC               0x00001091
14741+#define CKM_TWOFISH_KEY_GEN            0x00001092
14742+#define CKM_TWOFISH_CBC                0x00001093
14743+
14744+
14745+/* CKM_xxx_ENCRYPT_DATA mechanisms are new for v2.20 */
14746+#define CKM_DES_ECB_ENCRYPT_DATA       0x00001100
14747+#define CKM_DES_CBC_ENCRYPT_DATA       0x00001101
14748+#define CKM_DES3_ECB_ENCRYPT_DATA      0x00001102
14749+#define CKM_DES3_CBC_ENCRYPT_DATA      0x00001103
14750+#define CKM_AES_ECB_ENCRYPT_DATA       0x00001104
14751+#define CKM_AES_CBC_ENCRYPT_DATA       0x00001105
14752+
14753+#define CKM_DSA_PARAMETER_GEN          0x00002000
14754+#define CKM_DH_PKCS_PARAMETER_GEN      0x00002001
14755+#define CKM_X9_42_DH_PARAMETER_GEN     0x00002002
14756+
14757+#define CKM_VENDOR_DEFINED             0x80000000
14758+
14759+typedef CK_MECHANISM_TYPE CK_PTR CK_MECHANISM_TYPE_PTR;
14760+
14761+
14762+/* CK_MECHANISM is a structure that specifies a particular
14763+ * mechanism  */
14764+typedef struct CK_MECHANISM {
14765+  CK_MECHANISM_TYPE mechanism;
14766+  CK_VOID_PTR       pParameter;
14767+
14768+  /* ulParameterLen was changed from CK_USHORT to CK_ULONG for
14769+   * v2.0 */
14770+  CK_ULONG          ulParameterLen;  /* in bytes */
14771+} CK_MECHANISM;
14772+
14773+typedef CK_MECHANISM CK_PTR CK_MECHANISM_PTR;
14774+
14775+
14776+/* CK_MECHANISM_INFO provides information about a particular
14777+ * mechanism */
14778+typedef struct CK_MECHANISM_INFO {
14779+    CK_ULONG    ulMinKeySize;
14780+    CK_ULONG    ulMaxKeySize;
14781+    CK_FLAGS    flags;
14782+} CK_MECHANISM_INFO;
14783+
14784+/* The flags are defined as follows:
14785+ *      Bit Flag               Mask        Meaning */
14786+#define CKF_HW                 0x00000001  /* performed by HW */
14787+
14788+/* The flags CKF_ENCRYPT, CKF_DECRYPT, CKF_DIGEST, CKF_SIGN,
14789+ * CKG_SIGN_RECOVER, CKF_VERIFY, CKF_VERIFY_RECOVER,
14790+ * CKF_GENERATE, CKF_GENERATE_KEY_PAIR, CKF_WRAP, CKF_UNWRAP,
14791+ * and CKF_DERIVE are new for v2.0.  They specify whether or not
14792+ * a mechanism can be used for a particular task */
14793+#define CKF_ENCRYPT            0x00000100
14794+#define CKF_DECRYPT            0x00000200
14795+#define CKF_DIGEST             0x00000400
14796+#define CKF_SIGN               0x00000800
14797+#define CKF_SIGN_RECOVER       0x00001000
14798+#define CKF_VERIFY             0x00002000
14799+#define CKF_VERIFY_RECOVER     0x00004000
14800+#define CKF_GENERATE           0x00008000
14801+#define CKF_GENERATE_KEY_PAIR  0x00010000
14802+#define CKF_WRAP               0x00020000
14803+#define CKF_UNWRAP             0x00040000
14804+#define CKF_DERIVE             0x00080000
14805+
14806+/* CKF_EC_F_P, CKF_EC_F_2M, CKF_EC_ECPARAMETERS, CKF_EC_NAMEDCURVE,
14807+ * CKF_EC_UNCOMPRESS, and CKF_EC_COMPRESS are new for v2.11. They
14808+ * describe a token's EC capabilities not available in mechanism
14809+ * information. */
14810+#define CKF_EC_F_P             0x00100000
14811+#define CKF_EC_F_2M            0x00200000
14812+#define CKF_EC_ECPARAMETERS    0x00400000
14813+#define CKF_EC_NAMEDCURVE      0x00800000
14814+#define CKF_EC_UNCOMPRESS      0x01000000
14815+#define CKF_EC_COMPRESS        0x02000000
14816+
14817+#define CKF_EXTENSION          0x80000000 /* FALSE for this version */
14818+
14819+typedef CK_MECHANISM_INFO CK_PTR CK_MECHANISM_INFO_PTR;
14820+
14821+
14822+/* CK_RV is a value that identifies the return value of a
14823+ * Cryptoki function */
14824+/* CK_RV was changed from CK_USHORT to CK_ULONG for v2.0 */
14825+typedef CK_ULONG          CK_RV;
14826+
14827+#define CKR_OK                                0x00000000
14828+#define CKR_CANCEL                            0x00000001
14829+#define CKR_HOST_MEMORY                       0x00000002
14830+#define CKR_SLOT_ID_INVALID                   0x00000003
14831+
14832+/* CKR_FLAGS_INVALID was removed for v2.0 */
14833+
14834+/* CKR_GENERAL_ERROR and CKR_FUNCTION_FAILED are new for v2.0 */
14835+#define CKR_GENERAL_ERROR                     0x00000005
14836+#define CKR_FUNCTION_FAILED                   0x00000006
14837+
14838+/* CKR_ARGUMENTS_BAD, CKR_NO_EVENT, CKR_NEED_TO_CREATE_THREADS,
14839+ * and CKR_CANT_LOCK are new for v2.01 */
14840+#define CKR_ARGUMENTS_BAD                     0x00000007
14841+#define CKR_NO_EVENT                          0x00000008
14842+#define CKR_NEED_TO_CREATE_THREADS            0x00000009
14843+#define CKR_CANT_LOCK                         0x0000000A
14844+
14845+#define CKR_ATTRIBUTE_READ_ONLY               0x00000010
14846+#define CKR_ATTRIBUTE_SENSITIVE               0x00000011
14847+#define CKR_ATTRIBUTE_TYPE_INVALID            0x00000012
14848+#define CKR_ATTRIBUTE_VALUE_INVALID           0x00000013
14849+#define CKR_DATA_INVALID                      0x00000020
14850+#define CKR_DATA_LEN_RANGE                    0x00000021
14851+#define CKR_DEVICE_ERROR                      0x00000030
14852+#define CKR_DEVICE_MEMORY                     0x00000031
14853+#define CKR_DEVICE_REMOVED                    0x00000032
14854+#define CKR_ENCRYPTED_DATA_INVALID            0x00000040
14855+#define CKR_ENCRYPTED_DATA_LEN_RANGE          0x00000041
14856+#define CKR_FUNCTION_CANCELED                 0x00000050
14857+#define CKR_FUNCTION_NOT_PARALLEL             0x00000051
14858+
14859+/* CKR_FUNCTION_NOT_SUPPORTED is new for v2.0 */
14860+#define CKR_FUNCTION_NOT_SUPPORTED            0x00000054
14861+
14862+#define CKR_KEY_HANDLE_INVALID                0x00000060
14863+
14864+/* CKR_KEY_SENSITIVE was removed for v2.0 */
14865+
14866+#define CKR_KEY_SIZE_RANGE                    0x00000062
14867+#define CKR_KEY_TYPE_INCONSISTENT             0x00000063
14868+
14869+/* CKR_KEY_NOT_NEEDED, CKR_KEY_CHANGED, CKR_KEY_NEEDED,
14870+ * CKR_KEY_INDIGESTIBLE, CKR_KEY_FUNCTION_NOT_PERMITTED,
14871+ * CKR_KEY_NOT_WRAPPABLE, and CKR_KEY_UNEXTRACTABLE are new for
14872+ * v2.0 */
14873+#define CKR_KEY_NOT_NEEDED                    0x00000064
14874+#define CKR_KEY_CHANGED                       0x00000065
14875+#define CKR_KEY_NEEDED                        0x00000066
14876+#define CKR_KEY_INDIGESTIBLE                  0x00000067
14877+#define CKR_KEY_FUNCTION_NOT_PERMITTED        0x00000068
14878+#define CKR_KEY_NOT_WRAPPABLE                 0x00000069
14879+#define CKR_KEY_UNEXTRACTABLE                 0x0000006A
14880+
14881+#define CKR_MECHANISM_INVALID                 0x00000070
14882+#define CKR_MECHANISM_PARAM_INVALID           0x00000071
14883+
14884+/* CKR_OBJECT_CLASS_INCONSISTENT and CKR_OBJECT_CLASS_INVALID
14885+ * were removed for v2.0 */
14886+#define CKR_OBJECT_HANDLE_INVALID             0x00000082
14887+#define CKR_OPERATION_ACTIVE                  0x00000090
14888+#define CKR_OPERATION_NOT_INITIALIZED         0x00000091
14889+#define CKR_PIN_INCORRECT                     0x000000A0
14890+#define CKR_PIN_INVALID                       0x000000A1
14891+#define CKR_PIN_LEN_RANGE                     0x000000A2
14892+
14893+/* CKR_PIN_EXPIRED and CKR_PIN_LOCKED are new for v2.0 */
14894+#define CKR_PIN_EXPIRED                       0x000000A3
14895+#define CKR_PIN_LOCKED                        0x000000A4
14896+
14897+#define CKR_SESSION_CLOSED                    0x000000B0
14898+#define CKR_SESSION_COUNT                     0x000000B1
14899+#define CKR_SESSION_HANDLE_INVALID            0x000000B3
14900+#define CKR_SESSION_PARALLEL_NOT_SUPPORTED    0x000000B4
14901+#define CKR_SESSION_READ_ONLY                 0x000000B5
14902+#define CKR_SESSION_EXISTS                    0x000000B6
14903+
14904+/* CKR_SESSION_READ_ONLY_EXISTS and
14905+ * CKR_SESSION_READ_WRITE_SO_EXISTS are new for v2.0 */
14906+#define CKR_SESSION_READ_ONLY_EXISTS          0x000000B7
14907+#define CKR_SESSION_READ_WRITE_SO_EXISTS      0x000000B8
14908+
14909+#define CKR_SIGNATURE_INVALID                 0x000000C0
14910+#define CKR_SIGNATURE_LEN_RANGE               0x000000C1
14911+#define CKR_TEMPLATE_INCOMPLETE               0x000000D0
14912+#define CKR_TEMPLATE_INCONSISTENT             0x000000D1
14913+#define CKR_TOKEN_NOT_PRESENT                 0x000000E0
14914+#define CKR_TOKEN_NOT_RECOGNIZED              0x000000E1
14915+#define CKR_TOKEN_WRITE_PROTECTED             0x000000E2
14916+#define CKR_UNWRAPPING_KEY_HANDLE_INVALID     0x000000F0
14917+#define CKR_UNWRAPPING_KEY_SIZE_RANGE         0x000000F1
14918+#define CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT  0x000000F2
14919+#define CKR_USER_ALREADY_LOGGED_IN            0x00000100
14920+#define CKR_USER_NOT_LOGGED_IN                0x00000101
14921+#define CKR_USER_PIN_NOT_INITIALIZED          0x00000102
14922+#define CKR_USER_TYPE_INVALID                 0x00000103
14923+
14924+/* CKR_USER_ANOTHER_ALREADY_LOGGED_IN and CKR_USER_TOO_MANY_TYPES
14925+ * are new to v2.01 */
14926+#define CKR_USER_ANOTHER_ALREADY_LOGGED_IN    0x00000104
14927+#define CKR_USER_TOO_MANY_TYPES               0x00000105
14928+
14929+#define CKR_WRAPPED_KEY_INVALID               0x00000110
14930+#define CKR_WRAPPED_KEY_LEN_RANGE             0x00000112
14931+#define CKR_WRAPPING_KEY_HANDLE_INVALID       0x00000113
14932+#define CKR_WRAPPING_KEY_SIZE_RANGE           0x00000114
14933+#define CKR_WRAPPING_KEY_TYPE_INCONSISTENT    0x00000115
14934+#define CKR_RANDOM_SEED_NOT_SUPPORTED         0x00000120
14935+
14936+/* These are new to v2.0 */
14937+#define CKR_RANDOM_NO_RNG                     0x00000121
14938+
14939+/* These are new to v2.11 */
14940+#define CKR_DOMAIN_PARAMS_INVALID             0x00000130
14941+
14942+/* These are new to v2.0 */
14943+#define CKR_BUFFER_TOO_SMALL                  0x00000150
14944+#define CKR_SAVED_STATE_INVALID               0x00000160
14945+#define CKR_INFORMATION_SENSITIVE             0x00000170
14946+#define CKR_STATE_UNSAVEABLE                  0x00000180
14947+
14948+/* These are new to v2.01 */
14949+#define CKR_CRYPTOKI_NOT_INITIALIZED          0x00000190
14950+#define CKR_CRYPTOKI_ALREADY_INITIALIZED      0x00000191
14951+#define CKR_MUTEX_BAD                         0x000001A0
14952+#define CKR_MUTEX_NOT_LOCKED                  0x000001A1
14953+
14954+/* The following return values are new for PKCS #11 v2.20 amendment 3 */
14955+#define CKR_NEW_PIN_MODE                      0x000001B0
14956+#define CKR_NEXT_OTP                          0x000001B1
14957+
14958+/* This is new to v2.20 */
14959+#define CKR_FUNCTION_REJECTED                 0x00000200
14960+
14961+#define CKR_VENDOR_DEFINED                    0x80000000
14962+
14963+
14964+/* CK_NOTIFY is an application callback that processes events */
14965+typedef CK_CALLBACK_FUNCTION(CK_RV, CK_NOTIFY)(
14966+  CK_SESSION_HANDLE hSession,     /* the session's handle */
14967+  CK_NOTIFICATION   event,
14968+  CK_VOID_PTR       pApplication  /* passed to C_OpenSession */
14969+);
14970+
14971+
14972+/* CK_FUNCTION_LIST is a structure holding a Cryptoki spec
14973+ * version and pointers of appropriate types to all the
14974+ * Cryptoki functions */
14975+/* CK_FUNCTION_LIST is new for v2.0 */
14976+typedef struct CK_FUNCTION_LIST CK_FUNCTION_LIST;
14977+
14978+typedef CK_FUNCTION_LIST CK_PTR CK_FUNCTION_LIST_PTR;
14979+
14980+typedef CK_FUNCTION_LIST_PTR CK_PTR CK_FUNCTION_LIST_PTR_PTR;
14981+
14982+
14983+/* CK_CREATEMUTEX is an application callback for creating a
14984+ * mutex object */
14985+typedef CK_CALLBACK_FUNCTION(CK_RV, CK_CREATEMUTEX)(
14986+  CK_VOID_PTR_PTR ppMutex  /* location to receive ptr to mutex */
14987+);
14988+
14989+
14990+/* CK_DESTROYMUTEX is an application callback for destroying a
14991+ * mutex object */
14992+typedef CK_CALLBACK_FUNCTION(CK_RV, CK_DESTROYMUTEX)(
14993+  CK_VOID_PTR pMutex  /* pointer to mutex */
14994+);
14995+
14996+
14997+/* CK_LOCKMUTEX is an application callback for locking a mutex */
14998+typedef CK_CALLBACK_FUNCTION(CK_RV, CK_LOCKMUTEX)(
14999+  CK_VOID_PTR pMutex  /* pointer to mutex */
15000+);
15001+
15002+
15003+/* CK_UNLOCKMUTEX is an application callback for unlocking a
15004+ * mutex */
15005+typedef CK_CALLBACK_FUNCTION(CK_RV, CK_UNLOCKMUTEX)(
15006+  CK_VOID_PTR pMutex  /* pointer to mutex */
15007+);
15008+
15009+
15010+/* CK_C_INITIALIZE_ARGS provides the optional arguments to
15011+ * C_Initialize */
15012+typedef struct CK_C_INITIALIZE_ARGS {
15013+  CK_CREATEMUTEX CreateMutex;
15014+  CK_DESTROYMUTEX DestroyMutex;
15015+  CK_LOCKMUTEX LockMutex;
15016+  CK_UNLOCKMUTEX UnlockMutex;
15017+  CK_FLAGS flags;
15018+  CK_VOID_PTR pReserved;
15019+} CK_C_INITIALIZE_ARGS;
15020+
15021+/* flags: bit flags that provide capabilities of the slot
15022+ *      Bit Flag                           Mask       Meaning
15023+ */
15024+#define CKF_LIBRARY_CANT_CREATE_OS_THREADS 0x00000001
15025+#define CKF_OS_LOCKING_OK                  0x00000002
15026+
15027+typedef CK_C_INITIALIZE_ARGS CK_PTR CK_C_INITIALIZE_ARGS_PTR;
15028+
15029+
15030+/* additional flags for parameters to functions */
15031+
15032+/* CKF_DONT_BLOCK is for the function C_WaitForSlotEvent */
15033+#define CKF_DONT_BLOCK     1
15034+
15035+/* CK_RSA_PKCS_OAEP_MGF_TYPE is new for v2.10.
15036+ * CK_RSA_PKCS_OAEP_MGF_TYPE  is used to indicate the Message
15037+ * Generation Function (MGF) applied to a message block when
15038+ * formatting a message block for the PKCS #1 OAEP encryption
15039+ * scheme. */
15040+typedef CK_ULONG CK_RSA_PKCS_MGF_TYPE;
15041+
15042+typedef CK_RSA_PKCS_MGF_TYPE CK_PTR CK_RSA_PKCS_MGF_TYPE_PTR;
15043+
15044+/* The following MGFs are defined */
15045+/* CKG_MGF1_SHA256, CKG_MGF1_SHA384, and CKG_MGF1_SHA512
15046+ * are new for v2.20 */
15047+#define CKG_MGF1_SHA1         0x00000001
15048+#define CKG_MGF1_SHA256       0x00000002
15049+#define CKG_MGF1_SHA384       0x00000003
15050+#define CKG_MGF1_SHA512       0x00000004
15051+/* SHA-224 is new for PKCS #11 v2.20 amendment 3 */
15052+#define CKG_MGF1_SHA224       0x00000005
15053+
15054+/* CK_RSA_PKCS_OAEP_SOURCE_TYPE is new for v2.10.
15055+ * CK_RSA_PKCS_OAEP_SOURCE_TYPE  is used to indicate the source
15056+ * of the encoding parameter when formatting a message block
15057+ * for the PKCS #1 OAEP encryption scheme. */
15058+typedef CK_ULONG CK_RSA_PKCS_OAEP_SOURCE_TYPE;
15059+
15060+typedef CK_RSA_PKCS_OAEP_SOURCE_TYPE CK_PTR CK_RSA_PKCS_OAEP_SOURCE_TYPE_PTR;
15061+
15062+/* The following encoding parameter sources are defined */
15063+#define CKZ_DATA_SPECIFIED    0x00000001
15064+
15065+/* CK_RSA_PKCS_OAEP_PARAMS is new for v2.10.
15066+ * CK_RSA_PKCS_OAEP_PARAMS provides the parameters to the
15067+ * CKM_RSA_PKCS_OAEP mechanism. */
15068+typedef struct CK_RSA_PKCS_OAEP_PARAMS {
15069+        CK_MECHANISM_TYPE hashAlg;
15070+        CK_RSA_PKCS_MGF_TYPE mgf;
15071+        CK_RSA_PKCS_OAEP_SOURCE_TYPE source;
15072+        CK_VOID_PTR pSourceData;
15073+        CK_ULONG ulSourceDataLen;
15074+} CK_RSA_PKCS_OAEP_PARAMS;
15075+
15076+typedef CK_RSA_PKCS_OAEP_PARAMS CK_PTR CK_RSA_PKCS_OAEP_PARAMS_PTR;
15077+
15078+/* CK_RSA_PKCS_PSS_PARAMS is new for v2.11.
15079+ * CK_RSA_PKCS_PSS_PARAMS provides the parameters to the
15080+ * CKM_RSA_PKCS_PSS mechanism(s). */
15081+typedef struct CK_RSA_PKCS_PSS_PARAMS {
15082+        CK_MECHANISM_TYPE    hashAlg;
15083+        CK_RSA_PKCS_MGF_TYPE mgf;
15084+        CK_ULONG             sLen;
15085+} CK_RSA_PKCS_PSS_PARAMS;
15086+
15087+typedef CK_RSA_PKCS_PSS_PARAMS CK_PTR CK_RSA_PKCS_PSS_PARAMS_PTR;
15088+
15089+/* CK_EC_KDF_TYPE is new for v2.11. */
15090+typedef CK_ULONG CK_EC_KDF_TYPE;
15091+
15092+/* The following EC Key Derivation Functions are defined */
15093+#define CKD_NULL                 0x00000001
15094+#define CKD_SHA1_KDF             0x00000002
15095+
15096+/* CK_ECDH1_DERIVE_PARAMS is new for v2.11.
15097+ * CK_ECDH1_DERIVE_PARAMS provides the parameters to the
15098+ * CKM_ECDH1_DERIVE and CKM_ECDH1_COFACTOR_DERIVE mechanisms,
15099+ * where each party contributes one key pair.
15100+ */
15101+typedef struct CK_ECDH1_DERIVE_PARAMS {
15102+  CK_EC_KDF_TYPE kdf;
15103+  CK_ULONG ulSharedDataLen;
15104+  CK_BYTE_PTR pSharedData;
15105+  CK_ULONG ulPublicDataLen;
15106+  CK_BYTE_PTR pPublicData;
15107+} CK_ECDH1_DERIVE_PARAMS;
15108+
15109+typedef CK_ECDH1_DERIVE_PARAMS CK_PTR CK_ECDH1_DERIVE_PARAMS_PTR;
15110+
15111+
15112+/* CK_ECDH2_DERIVE_PARAMS is new for v2.11.
15113+ * CK_ECDH2_DERIVE_PARAMS provides the parameters to the
15114+ * CKM_ECMQV_DERIVE mechanism, where each party contributes two key pairs. */
15115+typedef struct CK_ECDH2_DERIVE_PARAMS {
15116+  CK_EC_KDF_TYPE kdf;
15117+  CK_ULONG ulSharedDataLen;
15118+  CK_BYTE_PTR pSharedData;
15119+  CK_ULONG ulPublicDataLen;
15120+  CK_BYTE_PTR pPublicData;
15121+  CK_ULONG ulPrivateDataLen;
15122+  CK_OBJECT_HANDLE hPrivateData;
15123+  CK_ULONG ulPublicDataLen2;
15124+  CK_BYTE_PTR pPublicData2;
15125+} CK_ECDH2_DERIVE_PARAMS;
15126+
15127+typedef CK_ECDH2_DERIVE_PARAMS CK_PTR CK_ECDH2_DERIVE_PARAMS_PTR;
15128+
15129+typedef struct CK_ECMQV_DERIVE_PARAMS {
15130+  CK_EC_KDF_TYPE kdf;
15131+  CK_ULONG ulSharedDataLen;
15132+  CK_BYTE_PTR pSharedData;
15133+  CK_ULONG ulPublicDataLen;
15134+  CK_BYTE_PTR pPublicData;
15135+  CK_ULONG ulPrivateDataLen;
15136+  CK_OBJECT_HANDLE hPrivateData;
15137+  CK_ULONG ulPublicDataLen2;
15138+  CK_BYTE_PTR pPublicData2;
15139+  CK_OBJECT_HANDLE publicKey;
15140+} CK_ECMQV_DERIVE_PARAMS;
15141+
15142+typedef CK_ECMQV_DERIVE_PARAMS CK_PTR CK_ECMQV_DERIVE_PARAMS_PTR;
15143+
15144+/* Typedefs and defines for the CKM_X9_42_DH_KEY_PAIR_GEN and the
15145+ * CKM_X9_42_DH_PARAMETER_GEN mechanisms (new for PKCS #11 v2.11) */
15146+typedef CK_ULONG CK_X9_42_DH_KDF_TYPE;
15147+typedef CK_X9_42_DH_KDF_TYPE CK_PTR CK_X9_42_DH_KDF_TYPE_PTR;
15148+
15149+/* The following X9.42 DH key derivation functions are defined
15150+   (besides CKD_NULL already defined : */
15151+#define CKD_SHA1_KDF_ASN1        0x00000003
15152+#define CKD_SHA1_KDF_CONCATENATE 0x00000004
15153+
15154+/* CK_X9_42_DH1_DERIVE_PARAMS is new for v2.11.
15155+ * CK_X9_42_DH1_DERIVE_PARAMS provides the parameters to the
15156+ * CKM_X9_42_DH_DERIVE key derivation mechanism, where each party
15157+ * contributes one key pair */
15158+typedef struct CK_X9_42_DH1_DERIVE_PARAMS {
15159+  CK_X9_42_DH_KDF_TYPE kdf;
15160+  CK_ULONG ulOtherInfoLen;
15161+  CK_BYTE_PTR pOtherInfo;
15162+  CK_ULONG ulPublicDataLen;
15163+  CK_BYTE_PTR pPublicData;
15164+} CK_X9_42_DH1_DERIVE_PARAMS;
15165+
15166+typedef struct CK_X9_42_DH1_DERIVE_PARAMS CK_PTR CK_X9_42_DH1_DERIVE_PARAMS_PTR;
15167+
15168+/* CK_X9_42_DH2_DERIVE_PARAMS is new for v2.11.
15169+ * CK_X9_42_DH2_DERIVE_PARAMS provides the parameters to the
15170+ * CKM_X9_42_DH_HYBRID_DERIVE and CKM_X9_42_MQV_DERIVE key derivation
15171+ * mechanisms, where each party contributes two key pairs */
15172+typedef struct CK_X9_42_DH2_DERIVE_PARAMS {
15173+  CK_X9_42_DH_KDF_TYPE kdf;
15174+  CK_ULONG ulOtherInfoLen;
15175+  CK_BYTE_PTR pOtherInfo;
15176+  CK_ULONG ulPublicDataLen;
15177+  CK_BYTE_PTR pPublicData;
15178+  CK_ULONG ulPrivateDataLen;
15179+  CK_OBJECT_HANDLE hPrivateData;
15180+  CK_ULONG ulPublicDataLen2;
15181+  CK_BYTE_PTR pPublicData2;
15182+} CK_X9_42_DH2_DERIVE_PARAMS;
15183+
15184+typedef CK_X9_42_DH2_DERIVE_PARAMS CK_PTR CK_X9_42_DH2_DERIVE_PARAMS_PTR;
15185+
15186+typedef struct CK_X9_42_MQV_DERIVE_PARAMS {
15187+  CK_X9_42_DH_KDF_TYPE kdf;
15188+  CK_ULONG ulOtherInfoLen;
15189+  CK_BYTE_PTR pOtherInfo;
15190+  CK_ULONG ulPublicDataLen;
15191+  CK_BYTE_PTR pPublicData;
15192+  CK_ULONG ulPrivateDataLen;
15193+  CK_OBJECT_HANDLE hPrivateData;
15194+  CK_ULONG ulPublicDataLen2;
15195+  CK_BYTE_PTR pPublicData2;
15196+  CK_OBJECT_HANDLE publicKey;
15197+} CK_X9_42_MQV_DERIVE_PARAMS;
15198+
15199+typedef CK_X9_42_MQV_DERIVE_PARAMS CK_PTR CK_X9_42_MQV_DERIVE_PARAMS_PTR;
15200+
15201+/* CK_KEA_DERIVE_PARAMS provides the parameters to the
15202+ * CKM_KEA_DERIVE mechanism */
15203+/* CK_KEA_DERIVE_PARAMS is new for v2.0 */
15204+typedef struct CK_KEA_DERIVE_PARAMS {
15205+  CK_BBOOL      isSender;
15206+  CK_ULONG      ulRandomLen;
15207+  CK_BYTE_PTR   pRandomA;
15208+  CK_BYTE_PTR   pRandomB;
15209+  CK_ULONG      ulPublicDataLen;
15210+  CK_BYTE_PTR   pPublicData;
15211+} CK_KEA_DERIVE_PARAMS;
15212+
15213+typedef CK_KEA_DERIVE_PARAMS CK_PTR CK_KEA_DERIVE_PARAMS_PTR;
15214+
15215+
15216+/* CK_RC2_PARAMS provides the parameters to the CKM_RC2_ECB and
15217+ * CKM_RC2_MAC mechanisms.  An instance of CK_RC2_PARAMS just
15218+ * holds the effective keysize */
15219+typedef CK_ULONG          CK_RC2_PARAMS;
15220+
15221+typedef CK_RC2_PARAMS CK_PTR CK_RC2_PARAMS_PTR;
15222+
15223+
15224+/* CK_RC2_CBC_PARAMS provides the parameters to the CKM_RC2_CBC
15225+ * mechanism */
15226+typedef struct CK_RC2_CBC_PARAMS {
15227+  /* ulEffectiveBits was changed from CK_USHORT to CK_ULONG for
15228+   * v2.0 */
15229+  CK_ULONG      ulEffectiveBits;  /* effective bits (1-1024) */
15230+
15231+  CK_BYTE       iv[8];            /* IV for CBC mode */
15232+} CK_RC2_CBC_PARAMS;
15233+
15234+typedef CK_RC2_CBC_PARAMS CK_PTR CK_RC2_CBC_PARAMS_PTR;
15235+
15236+
15237+/* CK_RC2_MAC_GENERAL_PARAMS provides the parameters for the
15238+ * CKM_RC2_MAC_GENERAL mechanism */
15239+/* CK_RC2_MAC_GENERAL_PARAMS is new for v2.0 */
15240+typedef struct CK_RC2_MAC_GENERAL_PARAMS {
15241+  CK_ULONG      ulEffectiveBits;  /* effective bits (1-1024) */
15242+  CK_ULONG      ulMacLength;      /* Length of MAC in bytes */
15243+} CK_RC2_MAC_GENERAL_PARAMS;
15244+
15245+typedef CK_RC2_MAC_GENERAL_PARAMS CK_PTR \
15246+  CK_RC2_MAC_GENERAL_PARAMS_PTR;
15247+
15248+
15249+/* CK_RC5_PARAMS provides the parameters to the CKM_RC5_ECB and
15250+ * CKM_RC5_MAC mechanisms */
15251+/* CK_RC5_PARAMS is new for v2.0 */
15252+typedef struct CK_RC5_PARAMS {
15253+  CK_ULONG      ulWordsize;  /* wordsize in bits */
15254+  CK_ULONG      ulRounds;    /* number of rounds */
15255+} CK_RC5_PARAMS;
15256+
15257+typedef CK_RC5_PARAMS CK_PTR CK_RC5_PARAMS_PTR;
15258+
15259+
15260+/* CK_RC5_CBC_PARAMS provides the parameters to the CKM_RC5_CBC
15261+ * mechanism */
15262+/* CK_RC5_CBC_PARAMS is new for v2.0 */
15263+typedef struct CK_RC5_CBC_PARAMS {
15264+  CK_ULONG      ulWordsize;  /* wordsize in bits */
15265+  CK_ULONG      ulRounds;    /* number of rounds */
15266+  CK_BYTE_PTR   pIv;         /* pointer to IV */
15267+  CK_ULONG      ulIvLen;     /* length of IV in bytes */
15268+} CK_RC5_CBC_PARAMS;
15269+
15270+typedef CK_RC5_CBC_PARAMS CK_PTR CK_RC5_CBC_PARAMS_PTR;
15271+
15272+
15273+/* CK_RC5_MAC_GENERAL_PARAMS provides the parameters for the
15274+ * CKM_RC5_MAC_GENERAL mechanism */
15275+/* CK_RC5_MAC_GENERAL_PARAMS is new for v2.0 */
15276+typedef struct CK_RC5_MAC_GENERAL_PARAMS {
15277+  CK_ULONG      ulWordsize;   /* wordsize in bits */
15278+  CK_ULONG      ulRounds;     /* number of rounds */
15279+  CK_ULONG      ulMacLength;  /* Length of MAC in bytes */
15280+} CK_RC5_MAC_GENERAL_PARAMS;
15281+
15282+typedef CK_RC5_MAC_GENERAL_PARAMS CK_PTR \
15283+  CK_RC5_MAC_GENERAL_PARAMS_PTR;
15284+
15285+
15286+/* CK_MAC_GENERAL_PARAMS provides the parameters to most block
15287+ * ciphers' MAC_GENERAL mechanisms.  Its value is the length of
15288+ * the MAC */
15289+/* CK_MAC_GENERAL_PARAMS is new for v2.0 */
15290+typedef CK_ULONG          CK_MAC_GENERAL_PARAMS;
15291+
15292+typedef CK_MAC_GENERAL_PARAMS CK_PTR CK_MAC_GENERAL_PARAMS_PTR;
15293+
15294+/* CK_DES/AES_ECB/CBC_ENCRYPT_DATA_PARAMS are new for v2.20 */
15295+typedef struct CK_DES_CBC_ENCRYPT_DATA_PARAMS {
15296+  CK_BYTE      iv[8];
15297+  CK_BYTE_PTR  pData;
15298+  CK_ULONG     length;
15299+} CK_DES_CBC_ENCRYPT_DATA_PARAMS;
15300+
15301+typedef CK_DES_CBC_ENCRYPT_DATA_PARAMS CK_PTR CK_DES_CBC_ENCRYPT_DATA_PARAMS_PTR;
15302+
15303+typedef struct CK_AES_CBC_ENCRYPT_DATA_PARAMS {
15304+  CK_BYTE      iv[16];
15305+  CK_BYTE_PTR  pData;
15306+  CK_ULONG     length;
15307+} CK_AES_CBC_ENCRYPT_DATA_PARAMS;
15308+
15309+typedef CK_AES_CBC_ENCRYPT_DATA_PARAMS CK_PTR CK_AES_CBC_ENCRYPT_DATA_PARAMS_PTR;
15310+
15311+/* CK_SKIPJACK_PRIVATE_WRAP_PARAMS provides the parameters to the
15312+ * CKM_SKIPJACK_PRIVATE_WRAP mechanism */
15313+/* CK_SKIPJACK_PRIVATE_WRAP_PARAMS is new for v2.0 */
15314+typedef struct CK_SKIPJACK_PRIVATE_WRAP_PARAMS {
15315+  CK_ULONG      ulPasswordLen;
15316+  CK_BYTE_PTR   pPassword;
15317+  CK_ULONG      ulPublicDataLen;
15318+  CK_BYTE_PTR   pPublicData;
15319+  CK_ULONG      ulPAndGLen;
15320+  CK_ULONG      ulQLen;
15321+  CK_ULONG      ulRandomLen;
15322+  CK_BYTE_PTR   pRandomA;
15323+  CK_BYTE_PTR   pPrimeP;
15324+  CK_BYTE_PTR   pBaseG;
15325+  CK_BYTE_PTR   pSubprimeQ;
15326+} CK_SKIPJACK_PRIVATE_WRAP_PARAMS;
15327+
15328+typedef CK_SKIPJACK_PRIVATE_WRAP_PARAMS CK_PTR \
15329+  CK_SKIPJACK_PRIVATE_WRAP_PTR;
15330+
15331+
15332+/* CK_SKIPJACK_RELAYX_PARAMS provides the parameters to the
15333+ * CKM_SKIPJACK_RELAYX mechanism */
15334+/* CK_SKIPJACK_RELAYX_PARAMS is new for v2.0 */
15335+typedef struct CK_SKIPJACK_RELAYX_PARAMS {
15336+  CK_ULONG      ulOldWrappedXLen;
15337+  CK_BYTE_PTR   pOldWrappedX;
15338+  CK_ULONG      ulOldPasswordLen;
15339+  CK_BYTE_PTR   pOldPassword;
15340+  CK_ULONG      ulOldPublicDataLen;
15341+  CK_BYTE_PTR   pOldPublicData;
15342+  CK_ULONG      ulOldRandomLen;
15343+  CK_BYTE_PTR   pOldRandomA;
15344+  CK_ULONG      ulNewPasswordLen;
15345+  CK_BYTE_PTR   pNewPassword;
15346+  CK_ULONG      ulNewPublicDataLen;
15347+  CK_BYTE_PTR   pNewPublicData;
15348+  CK_ULONG      ulNewRandomLen;
15349+  CK_BYTE_PTR   pNewRandomA;
15350+} CK_SKIPJACK_RELAYX_PARAMS;
15351+
15352+typedef CK_SKIPJACK_RELAYX_PARAMS CK_PTR \
15353+  CK_SKIPJACK_RELAYX_PARAMS_PTR;
15354+
15355+
15356+typedef struct CK_PBE_PARAMS {
15357+  CK_BYTE_PTR      pInitVector;
15358+  CK_UTF8CHAR_PTR  pPassword;
15359+  CK_ULONG         ulPasswordLen;
15360+  CK_BYTE_PTR      pSalt;
15361+  CK_ULONG         ulSaltLen;
15362+  CK_ULONG         ulIteration;
15363+} CK_PBE_PARAMS;
15364+
15365+typedef CK_PBE_PARAMS CK_PTR CK_PBE_PARAMS_PTR;
15366+
15367+
15368+/* CK_KEY_WRAP_SET_OAEP_PARAMS provides the parameters to the
15369+ * CKM_KEY_WRAP_SET_OAEP mechanism */
15370+/* CK_KEY_WRAP_SET_OAEP_PARAMS is new for v2.0 */
15371+typedef struct CK_KEY_WRAP_SET_OAEP_PARAMS {
15372+  CK_BYTE       bBC;     /* block contents byte */
15373+  CK_BYTE_PTR   pX;      /* extra data */
15374+  CK_ULONG      ulXLen;  /* length of extra data in bytes */
15375+} CK_KEY_WRAP_SET_OAEP_PARAMS;
15376+
15377+typedef CK_KEY_WRAP_SET_OAEP_PARAMS CK_PTR \
15378+  CK_KEY_WRAP_SET_OAEP_PARAMS_PTR;
15379+
15380+
15381+typedef struct CK_SSL3_RANDOM_DATA {
15382+  CK_BYTE_PTR  pClientRandom;
15383+  CK_ULONG     ulClientRandomLen;
15384+  CK_BYTE_PTR  pServerRandom;
15385+  CK_ULONG     ulServerRandomLen;
15386+} CK_SSL3_RANDOM_DATA;
15387+
15388+
15389+typedef struct CK_SSL3_MASTER_KEY_DERIVE_PARAMS {
15390+  CK_SSL3_RANDOM_DATA RandomInfo;
15391+  CK_VERSION_PTR pVersion;
15392+} CK_SSL3_MASTER_KEY_DERIVE_PARAMS;
15393+
15394+typedef struct CK_SSL3_MASTER_KEY_DERIVE_PARAMS CK_PTR \
15395+  CK_SSL3_MASTER_KEY_DERIVE_PARAMS_PTR;
15396+
15397+
15398+typedef struct CK_SSL3_KEY_MAT_OUT {
15399+  CK_OBJECT_HANDLE hClientMacSecret;
15400+  CK_OBJECT_HANDLE hServerMacSecret;
15401+  CK_OBJECT_HANDLE hClientKey;
15402+  CK_OBJECT_HANDLE hServerKey;
15403+  CK_BYTE_PTR      pIVClient;
15404+  CK_BYTE_PTR      pIVServer;
15405+} CK_SSL3_KEY_MAT_OUT;
15406+
15407+typedef CK_SSL3_KEY_MAT_OUT CK_PTR CK_SSL3_KEY_MAT_OUT_PTR;
15408+
15409+
15410+typedef struct CK_SSL3_KEY_MAT_PARAMS {
15411+  CK_ULONG                ulMacSizeInBits;
15412+  CK_ULONG                ulKeySizeInBits;
15413+  CK_ULONG                ulIVSizeInBits;
15414+  CK_BBOOL                bIsExport;
15415+  CK_SSL3_RANDOM_DATA     RandomInfo;
15416+  CK_SSL3_KEY_MAT_OUT_PTR pReturnedKeyMaterial;
15417+} CK_SSL3_KEY_MAT_PARAMS;
15418+
15419+typedef CK_SSL3_KEY_MAT_PARAMS CK_PTR CK_SSL3_KEY_MAT_PARAMS_PTR;
15420+
15421+/* CK_TLS_PRF_PARAMS is new for version 2.20 */
15422+typedef struct CK_TLS_PRF_PARAMS {
15423+  CK_BYTE_PTR  pSeed;
15424+  CK_ULONG     ulSeedLen;
15425+  CK_BYTE_PTR  pLabel;
15426+  CK_ULONG     ulLabelLen;
15427+  CK_BYTE_PTR  pOutput;
15428+  CK_ULONG_PTR pulOutputLen;
15429+} CK_TLS_PRF_PARAMS;
15430+
15431+typedef CK_TLS_PRF_PARAMS CK_PTR CK_TLS_PRF_PARAMS_PTR;
15432+
15433+/* WTLS is new for version 2.20 */
15434+typedef struct CK_WTLS_RANDOM_DATA {
15435+  CK_BYTE_PTR pClientRandom;
15436+  CK_ULONG    ulClientRandomLen;
15437+  CK_BYTE_PTR pServerRandom;
15438+  CK_ULONG    ulServerRandomLen;
15439+} CK_WTLS_RANDOM_DATA;
15440+
15441+typedef CK_WTLS_RANDOM_DATA CK_PTR CK_WTLS_RANDOM_DATA_PTR;
15442+
15443+typedef struct CK_WTLS_MASTER_KEY_DERIVE_PARAMS {
15444+  CK_MECHANISM_TYPE   DigestMechanism;
15445+  CK_WTLS_RANDOM_DATA RandomInfo;
15446+  CK_BYTE_PTR         pVersion;
15447+} CK_WTLS_MASTER_KEY_DERIVE_PARAMS;
15448+
15449+typedef CK_WTLS_MASTER_KEY_DERIVE_PARAMS CK_PTR \
15450+  CK_WTLS_MASTER_KEY_DERIVE_PARAMS_PTR;
15451+
15452+typedef struct CK_WTLS_PRF_PARAMS {
15453+  CK_MECHANISM_TYPE DigestMechanism;
15454+  CK_BYTE_PTR       pSeed;
15455+  CK_ULONG          ulSeedLen;
15456+  CK_BYTE_PTR       pLabel;
15457+  CK_ULONG          ulLabelLen;
15458+  CK_BYTE_PTR       pOutput;
15459+  CK_ULONG_PTR      pulOutputLen;
15460+} CK_WTLS_PRF_PARAMS;
15461+
15462+typedef CK_WTLS_PRF_PARAMS CK_PTR CK_WTLS_PRF_PARAMS_PTR;
15463+
15464+typedef struct CK_WTLS_KEY_MAT_OUT {
15465+  CK_OBJECT_HANDLE hMacSecret;
15466+  CK_OBJECT_HANDLE hKey;
15467+  CK_BYTE_PTR      pIV;
15468+} CK_WTLS_KEY_MAT_OUT;
15469+
15470+typedef CK_WTLS_KEY_MAT_OUT CK_PTR CK_WTLS_KEY_MAT_OUT_PTR;
15471+
15472+typedef struct CK_WTLS_KEY_MAT_PARAMS {
15473+  CK_MECHANISM_TYPE       DigestMechanism;
15474+  CK_ULONG                ulMacSizeInBits;
15475+  CK_ULONG                ulKeySizeInBits;
15476+  CK_ULONG                ulIVSizeInBits;
15477+  CK_ULONG                ulSequenceNumber;
15478+  CK_BBOOL                bIsExport;
15479+  CK_WTLS_RANDOM_DATA     RandomInfo;
15480+  CK_WTLS_KEY_MAT_OUT_PTR pReturnedKeyMaterial;
15481+} CK_WTLS_KEY_MAT_PARAMS;
15482+
15483+typedef CK_WTLS_KEY_MAT_PARAMS CK_PTR CK_WTLS_KEY_MAT_PARAMS_PTR;
15484+
15485+/* CMS is new for version 2.20 */
15486+typedef struct CK_CMS_SIG_PARAMS {
15487+  CK_OBJECT_HANDLE      certificateHandle;
15488+  CK_MECHANISM_PTR      pSigningMechanism;
15489+  CK_MECHANISM_PTR      pDigestMechanism;
15490+  CK_UTF8CHAR_PTR       pContentType;
15491+  CK_BYTE_PTR           pRequestedAttributes;
15492+  CK_ULONG              ulRequestedAttributesLen;
15493+  CK_BYTE_PTR           pRequiredAttributes;
15494+  CK_ULONG              ulRequiredAttributesLen;
15495+} CK_CMS_SIG_PARAMS;
15496+
15497+typedef CK_CMS_SIG_PARAMS CK_PTR CK_CMS_SIG_PARAMS_PTR;
15498+
15499+typedef struct CK_KEY_DERIVATION_STRING_DATA {
15500+  CK_BYTE_PTR pData;
15501+  CK_ULONG    ulLen;
15502+} CK_KEY_DERIVATION_STRING_DATA;
15503+
15504+typedef CK_KEY_DERIVATION_STRING_DATA CK_PTR \
15505+  CK_KEY_DERIVATION_STRING_DATA_PTR;
15506+
15507+
15508+/* The CK_EXTRACT_PARAMS is used for the
15509+ * CKM_EXTRACT_KEY_FROM_KEY mechanism.  It specifies which bit
15510+ * of the base key should be used as the first bit of the
15511+ * derived key */
15512+/* CK_EXTRACT_PARAMS is new for v2.0 */
15513+typedef CK_ULONG CK_EXTRACT_PARAMS;
15514+
15515+typedef CK_EXTRACT_PARAMS CK_PTR CK_EXTRACT_PARAMS_PTR;
15516+
15517+/* CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE is new for v2.10.
15518+ * CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE is used to
15519+ * indicate the Pseudo-Random Function (PRF) used to generate
15520+ * key bits using PKCS #5 PBKDF2. */
15521+typedef CK_ULONG CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE;
15522+
15523+typedef CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE CK_PTR CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE_PTR;
15524+
15525+/* The following PRFs are defined in PKCS #5 v2.0. */
15526+#define CKP_PKCS5_PBKD2_HMAC_SHA1 0x00000001
15527+
15528+
15529+/* CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE is new for v2.10.
15530+ * CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE is used to indicate the
15531+ * source of the salt value when deriving a key using PKCS #5
15532+ * PBKDF2. */
15533+typedef CK_ULONG CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE;
15534+
15535+typedef CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE CK_PTR CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE_PTR;
15536+
15537+/* The following salt value sources are defined in PKCS #5 v2.0. */
15538+#define CKZ_SALT_SPECIFIED        0x00000001
15539+
15540+/* CK_PKCS5_PBKD2_PARAMS is new for v2.10.
15541+ * CK_PKCS5_PBKD2_PARAMS is a structure that provides the
15542+ * parameters to the CKM_PKCS5_PBKD2 mechanism. */
15543+typedef struct CK_PKCS5_PBKD2_PARAMS {
15544+        CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE           saltSource;
15545+        CK_VOID_PTR                                pSaltSourceData;
15546+        CK_ULONG                                   ulSaltSourceDataLen;
15547+        CK_ULONG                                   iterations;
15548+        CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE prf;
15549+        CK_VOID_PTR                                pPrfData;
15550+        CK_ULONG                                   ulPrfDataLen;
15551+        CK_UTF8CHAR_PTR                            pPassword;
15552+        CK_ULONG_PTR                               ulPasswordLen;
15553+} CK_PKCS5_PBKD2_PARAMS;
15554+
15555+typedef CK_PKCS5_PBKD2_PARAMS CK_PTR CK_PKCS5_PBKD2_PARAMS_PTR;
15556+
15557+/* All CK_OTP structs are new for PKCS #11 v2.20 amendment 3 */
15558+
15559+typedef CK_ULONG CK_OTP_PARAM_TYPE;
15560+typedef CK_OTP_PARAM_TYPE CK_PARAM_TYPE; /* B/w compatibility */
15561+
15562+typedef struct CK_OTP_PARAM {
15563+    CK_OTP_PARAM_TYPE type;
15564+    CK_VOID_PTR pValue;
15565+    CK_ULONG ulValueLen;
15566+} CK_OTP_PARAM;
15567+
15568+typedef CK_OTP_PARAM CK_PTR CK_OTP_PARAM_PTR;
15569+
15570+typedef struct CK_OTP_PARAMS {
15571+    CK_OTP_PARAM_PTR pParams;
15572+    CK_ULONG ulCount;
15573+} CK_OTP_PARAMS;
15574+
15575+typedef CK_OTP_PARAMS CK_PTR CK_OTP_PARAMS_PTR;
15576+
15577+typedef struct CK_OTP_SIGNATURE_INFO {
15578+    CK_OTP_PARAM_PTR pParams;
15579+    CK_ULONG ulCount;
15580+} CK_OTP_SIGNATURE_INFO;
15581+
15582+typedef CK_OTP_SIGNATURE_INFO CK_PTR CK_OTP_SIGNATURE_INFO_PTR;
15583+
15584+/* The following OTP-related defines are new for PKCS #11 v2.20 amendment 1 */
15585+#define CK_OTP_VALUE          0
15586+#define CK_OTP_PIN            1
15587+#define CK_OTP_CHALLENGE      2
15588+#define CK_OTP_TIME           3
15589+#define CK_OTP_COUNTER        4
15590+#define CK_OTP_FLAGS          5
15591+#define CK_OTP_OUTPUT_LENGTH  6
15592+#define CK_OTP_OUTPUT_FORMAT  7
15593+
15594+/* The following OTP-related defines are new for PKCS #11 v2.20 amendment 1 */
15595+#define CKF_NEXT_OTP          0x00000001
15596+#define CKF_EXCLUDE_TIME      0x00000002
15597+#define CKF_EXCLUDE_COUNTER   0x00000004
15598+#define CKF_EXCLUDE_CHALLENGE 0x00000008
15599+#define CKF_EXCLUDE_PIN       0x00000010
15600+#define CKF_USER_FRIENDLY_OTP 0x00000020
15601+
15602+/* CK_KIP_PARAMS is new for PKCS #11 v2.20 amendment 2 */
15603+typedef struct CK_KIP_PARAMS {
15604+    CK_MECHANISM_PTR  pMechanism;
15605+    CK_OBJECT_HANDLE  hKey;
15606+    CK_BYTE_PTR       pSeed;
15607+    CK_ULONG          ulSeedLen;
15608+} CK_KIP_PARAMS;
15609+
15610+typedef CK_KIP_PARAMS CK_PTR CK_KIP_PARAMS_PTR;
15611+
15612+/* CK_AES_CTR_PARAMS is new for PKCS #11 v2.20 amendment 3 */
15613+typedef struct CK_AES_CTR_PARAMS {
15614+    CK_ULONG ulCounterBits;
15615+    CK_BYTE cb[16];
15616+} CK_AES_CTR_PARAMS;
15617+
15618+typedef CK_AES_CTR_PARAMS CK_PTR CK_AES_CTR_PARAMS_PTR;
15619+
15620+/* CK_CAMELLIA_CTR_PARAMS is new for PKCS #11 v2.20 amendment 3 */
15621+typedef struct CK_CAMELLIA_CTR_PARAMS {
15622+    CK_ULONG ulCounterBits;
15623+    CK_BYTE cb[16];
15624+} CK_CAMELLIA_CTR_PARAMS;
15625+
15626+typedef CK_CAMELLIA_CTR_PARAMS CK_PTR CK_CAMELLIA_CTR_PARAMS_PTR;
15627+
15628+/* CK_CAMELLIA_CBC_ENCRYPT_DATA_PARAMS is new for PKCS #11 v2.20 amendment 3 */
15629+typedef struct CK_CAMELLIA_CBC_ENCRYPT_DATA_PARAMS {
15630+    CK_BYTE      iv[16];
15631+    CK_BYTE_PTR  pData;
15632+    CK_ULONG     length;
15633+} CK_CAMELLIA_CBC_ENCRYPT_DATA_PARAMS;
15634+
15635+typedef CK_CAMELLIA_CBC_ENCRYPT_DATA_PARAMS CK_PTR CK_CAMELLIA_CBC_ENCRYPT_DATA_PARAMS_PTR;
15636+
15637+/* CK_ARIA_CBC_ENCRYPT_DATA_PARAMS is new for PKCS #11 v2.20 amendment 3 */
15638+typedef struct CK_ARIA_CBC_ENCRYPT_DATA_PARAMS {
15639+    CK_BYTE      iv[16];
15640+    CK_BYTE_PTR  pData;
15641+    CK_ULONG     length;
15642+} CK_ARIA_CBC_ENCRYPT_DATA_PARAMS;
15643+
15644+typedef CK_ARIA_CBC_ENCRYPT_DATA_PARAMS CK_PTR CK_ARIA_CBC_ENCRYPT_DATA_PARAMS_PTR;
15645+
15646+#endif
15647Index: openssl/test/clean_test.com
15648diff -u openssl/test/clean_test.com:1.1.2.1 openssl/test/clean_test.com:removed
15649--- openssl/test/clean_test.com:1.1.2.1	Sun Jan 15 16:09:50 2012
15650+++ openssl/test/clean_test.com	Mon Jan 16 18:54:23 2012
15651@@ -1,35 +0,0 @@
15652-$!
15653-$! Delete various test results files.
15654-$!
15655-$ def_orig = f$environment( "default")
15656-$ proc = f$environment( "procedure")
15657-$ proc_dev_dir = f$parse( "A.;", proc) - "A.;"
15658-$!
15659-$ on control_c then goto tidy
15660-$ on error then goto tidy
15661-$!
15662-$ set default 'proc_dev_dir'
15663-$!
15664-$ files := *.cms;*, *.srl;*, *.ss;*, -
15665-   cms.err;*, cms.out;*, newreq.pem;*, -
15666-   p.txt-zlib-cipher;*, -
15667-   smtst.txt;*, testkey.pem;*, testreq.pem;*, -
15668-   test_*.err;*, test_*.out;*, -
15669-   .rnd;*
15670-$!
15671-$ delim = ","
15672-$ i = 0
15673-$ loop:
15674-$    file = f$edit( f$element( i, delim, files), "trim")
15675-$    if (file .eqs. delim) then goto loop_end
15676-$    if (f$search( file) .nes. "") then -
15677-      delete 'p1' 'file'
15678-$    i = i+ 1
15679-$ goto loop
15680-$ loop_end:
15681-$!
15682-$ tidy:
15683-$ 
15684-$ if (f$type( def_orig) .nes. "") then -
15685-   set default 'def_orig'
15686-$!
15687Index: openssl/util/libeay.num
15688diff -u openssl/util/libeay.num:1.8.2.1 openssl/util/libeay.num:1.9
15689--- openssl/util/libeay.num:1.8.2.1	Sun Jan 15 16:09:52 2012
15690+++ openssl/util/libeay.num	Sun Jan 15 16:30:10 2012
15691@@ -4194,3 +4194,5 @@
15692 OPENSSL_strncasecmp                     4566	EXIST::FUNCTION:
15693 OPENSSL_gmtime                          4567	EXIST::FUNCTION:
15694 OPENSSL_gmtime_adj                      4568	EXIST::FUNCTION:
15695+ENGINE_load_pk11ca                      4569	EXIST::FUNCTION:HW_PKCS11CA,ENGINE
15696+ENGINE_load_pk11so                      4569	EXIST::FUNCTION:HW_PKCS11SO,ENGINE
15697Index: openssl/util/mk1mf.pl
15698diff -u openssl/util/mk1mf.pl:1.9.2.1 openssl/util/mk1mf.pl:1.9
15699--- openssl/util/mk1mf.pl:1.9.2.1	Sun Jan 15 16:09:52 2012
15700+++ openssl/util/mk1mf.pl	Mon Jun 13 17:13:56 2011
15701@@ -109,6 +109,8 @@
15702 	no-ecdh					- No ECDH
15703 	no-engine				- No engine
15704 	no-hw					- No hw
15705+	no-hw-pkcs11ca				- No hw PKCS#11 CA flavor
15706+	no-hw-pkcs11so				- No hw PKCS#11 SO flavor
15707 	nasm 					- Use NASM for x86 asm
15708 	nw-nasm					- Use NASM x86 asm for NetWare
15709 	nw-mwasm				- Use Metrowerks x86 asm for NetWare
15710@@ -270,6 +272,8 @@
15711 $cflags.=" -DOPENSSL_NO_GOST" if $no_gost;
15712 $cflags.=" -DOPENSSL_NO_ENGINE"   if $no_engine;
15713 $cflags.=" -DOPENSSL_NO_HW"   if $no_hw;
15714+$cflags.=" -DOPENSSL_NO_HW_PKCS11CA"   if $no_hw_pkcs11ca;
15715+$cflags.=" -DOPENSSL_NO_HW_PKCS11SO"   if $no_hw_pkcs11so;
15716 $cflags.=" -DOPENSSL_NO_JPAKE"    if $no_jpake;
15717 $cflags.= " -DZLIB" if $zlib_opt;
15718 $cflags.= " -DZLIB_SHARED" if $zlib_opt == 2;
15719@@ -335,6 +339,9 @@
15720 		$dir=$val;
15721 		}
15722 
15723+	if ($key eq "PK11_LIB_LOCATION")
15724+		{ $cflags .= " -D$key=\\\"$val\\\"" if $val ne "";}
15725+
15726 	if ($key eq "KRB5_INCLUDES")
15727 		{ $cflags .= " $val";}
15728 
15729@@ -1067,6 +1074,8 @@
15730 		"no-gost" => \$no_gost,
15731 		"no-engine" => \$no_engine,
15732 		"no-hw" => \$no_hw,
15733+		"no-hw-pkcs11ca" => \$no_hw_pkcs11ca,
15734+		"no-hw-pkcs11so" => \$no_hw_pkcs11so,
15735 		"just-ssl" =>
15736 			[\$no_rc2, \$no_idea, \$no_des, \$no_bf, \$no_cast,
15737 			  \$no_md2, \$no_sha, \$no_mdc2, \$no_dsa, \$no_dh,
15738Index: openssl/util/mkdef.pl
15739diff -u openssl/util/mkdef.pl:1.7.2.1 openssl/util/mkdef.pl:1.8
15740--- openssl/util/mkdef.pl:1.7.2.1	Sun Jan 15 16:09:52 2012
15741+++ openssl/util/mkdef.pl	Sun Jan 15 16:30:10 2012
15742@@ -94,7 +94,7 @@
15743 			 # External "algorithms"
15744 			 "FP_API", "STDIO", "SOCK", "KRB5", "DGRAM",
15745 			 # Engines
15746-			 "STATIC_ENGINE", "ENGINE", "HW", "GMP",
15747+			 "STATIC_ENGINE", "ENGINE", "HW", "GMP", "HW_PKCS11CA", "HW_PKCS11SO",
15748 			 # RFC3779
15749 			 "RFC3779",
15750 			 # TLS
15751@@ -125,6 +125,7 @@
15752 my $no_md2; my $no_md4; my $no_md5; my $no_sha; my $no_ripemd; my $no_mdc2;
15753 my $no_rsa; my $no_dsa; my $no_dh; my $no_hmac=0; my $no_aes; my $no_krb5;
15754 my $no_ec; my $no_ecdsa; my $no_ecdh; my $no_engine; my $no_hw;
15755+my $no_pkcs11ca; my $no_pkcs11so;
15756 my $no_fp_api; my $no_static_engine=1; my $no_gmp; my $no_deprecated;
15757 my $no_rfc3779; my $no_psk; my $no_tlsext; my $no_cms; my $no_capieng;
15758 my $no_jpake; my $no_ssl2;
15759@@ -218,6 +219,8 @@
15760 	elsif (/^no-ssl2$/)	{ $no_ssl2=1; }
15761 	elsif (/^no-capieng$/)	{ $no_capieng=1; }
15762 	elsif (/^no-jpake$/)	{ $no_jpake=1; }
15763+	elsif (/^no-hw-pkcs11ca$/) { $no_pkcs11ca=1; }
15764+	elsif (/^no-hw-pkcs11so$/) { $no_pkcs11so=1; }
15765 	}
15766 
15767 
15768@@ -1165,6 +1168,8 @@
15769 			if ($keyword eq "KRB5" && $no_krb5) { return 0; }
15770 			if ($keyword eq "ENGINE" && $no_engine) { return 0; }
15771 			if ($keyword eq "HW" && $no_hw) { return 0; }
15772+			if ($keyword eq "HW_PKCS11CA" && $no_pkcs11ca) { return 0; }
15773+			if ($keyword eq "HW_PKCS11SO" && $no_pkcs11so) { return 0; }
15774 			if ($keyword eq "FP_API" && $no_fp_api) { return 0; }
15775 			if ($keyword eq "STATIC_ENGINE" && $no_static_engine) { return 0; }
15776 			if ($keyword eq "GMP" && $no_gmp) { return 0; }
15777Index: openssl/util/pl/VC-32.pl
15778diff -u openssl/util/pl/VC-32.pl:1.7.2.1 openssl/util/pl/VC-32.pl:1.7
15779--- openssl/util/pl/VC-32.pl:1.7.2.1	Sun Jan 15 16:09:52 2012
15780+++ openssl/util/pl/VC-32.pl	Mon Jun 13 17:13:57 2011
15781@@ -36,7 +36,7 @@
15782     my $f = $shlib?' /MD':' /MT';
15783     $lib_cflag='/Zl' if (!$shlib);	# remove /DEFAULTLIBs from static lib
15784     $opt_cflags=$f.' /Ox';
15785-    $dbg_cflags=$f.'d /Od -DDEBUG -D_DEBUG';
15786+    $dbg_cflags=$f.'d /Od /Zi -DDEBUG -D_DEBUG';
15787     $lflags="/nologo /subsystem:console /opt:ref";
15788 
15789     *::perlasm_compile_target = sub {
15790