etc/services - sync with NetBSD-8
[minix.git] / external / bsd / bind / dist / bin / pkcs11 / openssl-0.9.8zc-patch
bloba2e88daf0ad4c7e0466f8e1ac245373739b8d18b
1 Index: openssl/Configure
2 diff -u openssl/Configure:1.8.6.1.4.1.2.1 openssl/Configure:1.8.2.2
3 --- openssl/Configure:1.8.6.1.4.1.2.1   Thu Jul  3 12:12:31 2014
4 +++ openssl/Configure   Thu Jul  3 12:31:57 2014
5 @@ -12,7 +12,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] [enable-montasm] [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] [enable-montasm] [no-asm] [no-dso] [no-krb5] [386] [--prefix=DIR] [--openssldir=OPENSSLDIR] [--with-xxx[=vvv]] [--test-sanity] os/compiler[:flags]\n";
12  # Options:
13  #
14 @@ -25,6 +25,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)
21 +# --pk11-flavor either crypto-accelerator or sign-only
22 +#               (No default)
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 @@ -336,7 +342,7 @@
28  "linux-ppc",   "gcc:-DB_ENDIAN -DTERMIO -O3 -Wall::-D_REENTRANT::-ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_RISC1 DES_UNROLL::linux_ppc32.o::::::::::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_out_asm}",
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 @@ -344,7 +350,7 @@
37  "linux-ia64",  "gcc:-DL_ENDIAN -DTERMIO -O3 -Wall::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHUNK:${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:${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:${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}:dlfcn:linux-shared:-fPIC:-m64:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
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}:dlfcn:linux-shared:-fPIC:-m64:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
42  #### SPARC Linux setups
43  # Ray Miller <ray.miller@computing-services.oxford.ac.uk> has patiently
44  # assisted with debugging of following two configs.
45 @@ -591,6 +597,10 @@
46  my $idx_ranlib = $idx++;
47  my $idx_arflags = $idx++;
49 +# PKCS#11 engine patch
50 +my $pk11_libname="";
51 +my $pk11_flavor="";
53  my $prefix="";
54  my $libdir="";
55  my $openssldir="";
56 @@ -829,6 +839,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 @@ -964,6 +982,22 @@
72         exit 0;
73  }
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 +        }
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 +       }
91  if ($target =~ m/^CygWin32(-.*)$/) {
92         $target = "Cygwin".$1;
93  }
94 @@ -1079,6 +1113,25 @@
95         print "\n";
96         }
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";
117  my $IsMK1MF=scalar grep /^$target$/,@MK1MF_Builds;
119  $IsMK1MF=1 if ($target eq "mingw" && $^O ne "cygwin" && !is_msys());
120 @@ -1130,6 +1183,8 @@
121  if ($flags ne "")      { $cflags="$flags$cflags"; }
122  else                   { $no_user_cflags=1;       }
124 +$cflags="-DPK11_LIB_LOCATION=\"$pk11_libname\" $cflags";
126  # Kerberos settings.  The flavor must be provided from outside, either through
127  # the script "config" or manually.
128  if (!$no_krb5)
129 @@ -1493,6 +1548,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/;
137 Index: openssl/Makefile.org
138 diff -u openssl/Makefile.org:1.4.6.1.6.1 openssl/Makefile.org:1.4.2.1
139 --- openssl/Makefile.org:1.4.6.1.6.1    Thu Jul  3 12:12:31 2014
140 +++ openssl/Makefile.org        Thu Jul  3 12:31:58 2014
141 @@ -26,6 +26,9 @@
142  INSTALL_PREFIX=
143  INSTALLTOP=/usr/local/ssl
145 +# You must set this through --pk11-libname configure option.
146 +PK11_LIB_LOCATION=
148  # Do not edit this manually. Use Configure --openssldir=DIR do change this!
149  OPENSSLDIR=/usr/local/ssl
151 Index: openssl/README.pkcs11
152 diff -u /dev/null openssl/README.pkcs11:1.6.4.2
153 --- /dev/null   Fri Jan  2 13:56:40 2015
154 +++ openssl/README.pkcs11       Fri Oct  4 14:45:25 2013
155 @@ -0,0 +1,266 @@
156 +ISC modified
157 +============
159 +The previous key naming scheme was kept for backward compatibility.
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).
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.
172 +Note it is mandatory to set a pk11-flavor (and only one) in
173 +config/Configure.
175 +It is highly recommended to compile in (vs. as a DSO) the engine.
176 +The way to configure this is system dependent, on Unixes it is no-shared
177 +(and is in general the default), on WIN32 it is enable-static-engine
178 +(and still enable to build the OpenSSL libraries as DLLs).
180 +PKCS#11 engine support for OpenSSL 0.9.8l
181 +=========================================
183 +[Nov 19, 2009]
185 +Contents:
187 +Overview
188 +Revisions of the patch for 0.9.8 branch
189 +FAQs
190 +Feedback
192 +Overview
193 +========
195 +This patch containing code available in OpenSolaris adds support for PKCS#11
196 +engine into OpenSSL and implements PKCS#11 v2.20. It is to be applied against
197 +OpenSSL 0.9.8l source code distribution as shipped by OpenSSL.Org. Your system
198 +must provide PKCS#11 backend otherwise the patch is useless. You provide the
199 +PKCS#11 library name during the build configuration phase, see below.
201 +Patch can be applied like this:
203 +       # NOTE: use gtar if on Solaris
204 +       tar xfzv openssl-0.9.8l.tar.gz
205 +       # now download the patch to the current directory
206 +       # ...
207 +       cd openssl-0.9.8l
208 +       # NOTE: must use gpatch if on Solaris (is part of the system)
209 +       patch -p1 < path-to/pkcs11_engine-0.9.8l.patch.2009-11-19
211 +It is designed to support pure acceleration for RSA, DSA, DH and all the
212 +symetric ciphers and message digest algorithms that PKCS#11 and OpenSSL share
213 +except for missing support for patented algorithms MDC2, RC3, RC5 and IDEA.
215 +According to the PKCS#11 providers installed on your machine, it can support
216 +following mechanisms:
218 +       RSA, DSA, DH, RAND, DES-CBC, DES-EDE3-CBC, DES-ECB, DES-EDE3, RC4,
219 +       AES-128-CBC, AES-192-CBC, AES-256-CBC, AES-128-ECB, AES-192-ECB,
220 +       AES-256-ECB, AES-128-CTR, AES-192-CTR, AES-256-CTR, MD5, SHA1, SHA224,
221 +       SHA256, SHA384, SHA512
223 +Note that for AES counter mode the application must provide their own EVP
224 +functions since OpenSSL doesn't support counter mode through EVP yet. You may
225 +see OpenSSH source code (cipher.c) to get the idea how to do that. SunSSH is an
226 +example of code that uses the PKCS#11 engine and deals with the fork-safety
227 +problem (see engine.c and packet.c files if interested).
229 +You must provide the location of PKCS#11 library in your system to the
230 +configure script. You will be instructed to do that when you try to run the
231 +config script:
233 +       $ ./config 
234 +       Operating system: i86pc-whatever-solaris2
235 +       Configuring for solaris-x86-cc
236 +       You must set --pk11-libname for PKCS#11 library.
237 +       See README.pkcs11 for more information.
239 +Taking openCryptoki project on Linux AMD64 box as an example, you would run
240 +configure script like this:
242 +       ./config --pk11-libname=/usr/lib64/pkcs11/PKCS11_API.so
244 +To check whether newly built openssl really supports PKCS#11 it's enough to run
245 +"apps/openssl engine" and look for "(pkcs11) PKCS #11 engine support" in the
246 +output. If you see no PKCS#11 engine support check that the built openssl binary
247 +and the PKCS#11 library from --pk11-libname don't conflict on 32/64 bits.
249 +The patch, during various phases of development, was tested on Solaris against
250 +PKCS#11 engine available from Solaris Cryptographic Framework (Solaris 10 and
251 +OpenSolaris) and also on Linux using PKCS#11 libraries from openCryptoki project
252 +(see openCryptoki website http://sourceforge.net/projects/opencryptoki for more
253 +information). Some Linux distributions even ship those libraries with the
254 +system. The patch should work on any system that is supported by OpenSSL itself
255 +and has functional PKCS#11 library.
257 +The patch contains "RSA Security Inc. PKCS #11 Cryptographic Token Interface
258 +(Cryptoki)" - files cryptoki.h, pkcs11.h, pkcs11f.h and pkcs11t.h which are
259 +copyrighted by RSA Security Inc., see pkcs11.h for more information.
261 +Other added/modified code in this patch is copyrighted by Sun Microsystems,
262 +Inc. and is released under the OpenSSL license (see LICENSE file for more
263 +information).
265 +Revisions of the patch for 0.9.8 branch
266 +=======================================
268 +2009-11-19
269 +- adjusted for OpenSSL version 0.9.8l
271 +- bugs and RFEs:
273 +       6479874 OpenSSL should support RSA key by reference/hardware keystores
274 +       6896677 PKCS#11 engine's hw_pk11_err.h needs to be split
275 +       6732677 make check to trigger Solaris specific code automatic in the
276 +               PKCS#11 engine
278 +2009-03-11
279 +- adjusted for OpenSSL version 0.9.8j 
281 +- README.pkcs11 moved out of the patch, and is shipped together with it in a
282 +  tarball instead so that it can be read before the patch is applied.
284 +- fixed bugs:
286 +       6804216 pkcs#11 engine should support a key length range for RC4
287 +       6734038 Apache SSL web server using the pkcs11 engine fails to start if
288 +               meta slot is disabled
290 +2008-12-02
291 +- fixed bugs and RFEs (most of the work done by Vladimir Kotal)
293 +       6723504 more granular locking in PKCS#11 engine
294 +       6667128 CRYPTO_LOCK_PK11_ENGINE assumption does not hold true
295 +       6710420 PKCS#11 engine source should be lint clean
296 +       6747327 PKCS#11 engine atfork handlers need to be aware of guys who take
297 +               it seriously
298 +       6746712 PKCS#11 engine source code should be cstyle clean
299 +       6731380 return codes of several functions are not checked in the PKCS#11
300 +               engine code
301 +       6746735 PKCS#11 engine should use extended FILE space API
302 +       6734038 Apache SSL web server using the pkcs11 engine fails to start if
303 +               meta slot is disabled
305 +2008-08-01
306 +- fixed bug
308 +       6731839 OpenSSL PKCS#11 engine no longer uses n2cp for symmetric ciphers
309 +               and digests
311 +- Solaris specific code for slot selection made automatic
313 +2008-07-29
314 +- update the patch to OpenSSL 0.9.8h version
315 +- pkcs11t.h updated to the latest version:
317 +       6545665 make CKM_AES_CTR available to non-kernel users
319 +- fixed bugs in the engine code:
321 +       6602801 PK11_SESSION cache has to employ reference counting scheme for
322 +               asymmetric key operations
323 +       6605538 pkcs11 functions C_FindObjects[{Init,Final}]() not called
324 +               atomically
325 +       6607307 pkcs#11 engine can't read RSA private keys
326 +       6652362 pk11_RSA_finish() is cutting corners
327 +       6662112 pk11_destroy_{rsa,dsa,dh}_key_objects() use locking in
328 +               suboptimal way
329 +       6666625 pk11_destroy_{rsa,dsa,dh}_key_objects() should be more
330 +               resilient to destroy failures
331 +       6667273 OpenSSL engine should not use free() but OPENSSL_free()
332 +       6670363 PKCS#11 engine fails to reuse existing symmetric keys
333 +       6678135 memory corruption in pk11_DH_generate_key() in pkcs#11 engine
334 +       6678503 DSA signature conversion in pk11_dsa_do_verify() ignores size
335 +               of big numbers leading to failures
336 +       6706562 pk11_DH_compute_key() returns 0 in case of failure instead of
337 +               -1
338 +       6706622 pk11_load_{pub,priv}key create corrupted RSA key references
339 +       6707129 return values from BN_new() in pk11_DH_generate_key() are not
340 +               checked
341 +       6707274 DSA/RSA/DH PKCS#11 engine operations need to be resistant to
342 +               structure reuse
343 +       6707782 OpenSSL PKCS#11 engine pretends to be aware of
344 +               OPENSSL_NO_{RSA,DSA,DH}
345 +       defines but fails miserably
346 +       6709966 make check_new_*() to return values to indicate cache hit/miss
347 +       6705200 pk11_dh struct initialization in PKCS#11 engine is missing
348 +               generate_params parameter
349 +       6709513 PKCS#11 engine sets IV length even for ECB modes
350 +       6728296 buffer length not initialized for C_(En|De)crypt_Final() in the
351 +               PKCS#11 engine
352 +       6728871 PKCS#11 engine must reset global_session in pk11_finish()
354 +- new features and enhancements:
356 +       6562155 OpenSSL pkcs#11 engine needs support for SHA224/256/384/512
357 +       6685012 OpenSSL pkcs#11 engine needs support for new cipher modes
358 +       6725903 OpenSSL PKCS#11 engine shouldn't use soft token for symmetric
359 +               ciphers and digests
361 +2007-10-15
362 +- update for 0.9.8f version
363 +- update for "6607670 teach pkcs#11 engine how to use keys be reference"
365 +2007-10-02
366 +- draft for "6607670 teach pkcs#11 engine how to use keys be reference"
367 +- draft for "6607307 pkcs#11 engine can't read RSA private keys"
369 +2007-09-26
370 +- 6375348 Using pkcs11 as the SSLCryptoDevice with Apache/OpenSSL causes
371 +         significant performance drop
372 +- 6573196 memory is leaked when OpenSSL is used with PKCS#11 engine
374 +2007-05-25
375 +- 6558630 race in OpenSSL pkcs11 engine when using symetric block ciphers
377 +2007-05-19
378 +- initial patch for 0.9.8e using latest OpenSolaris code
380 +FAQs
381 +====
383 +(1) my build failed on Linux distro with this error:
385 +../libcrypto.a(hw_pk11.o): In function `pk11_library_init':
386 +hw_pk11.c:(.text+0x20f5): undefined reference to `pthread_atfork'
388 +Answer:
390 +       - don't use "no-threads" when configuring
391 +       - if you didn't then OpenSSL failed to create a threaded library by
392 +         default. You may manually edit Configure and try again. Look for the
393 +         architecture that Configure printed, for example:
395 +Configured for linux-elf.
397 +       - then edit Configure, find string "linux-elf" (inluding the quotes),
398 +         and add flags to support threads to the 4th column of the 2nd string.
399 +         If you build with GCC then adding "-pthread" should be enough. With
400 +         "linux-elf" as an example, you would add " -pthread" right after
401 +         "-D_REENTRANT", like this:
403 +....-O3 -fomit-frame-pointer -Wall::-D_REENTRANT -pthread::-ldl:.....
405 +(2) I'm using MinGW/MSYS environment and get undeclared reference error for
406 +pthread_atfork() function when trying to build OpenSSL with the patch.
408 +Answer:
410 +       Sorry, pthread_atfork() is not implemented in the current pthread-win32
411 +       (as of Nov 2009). You can not use the patch there.
414 +Feedback
415 +========
417 +Please send feedback to security-discuss@opensolaris.org. The patch was
418 +created by Jan.Pechanec@Sun.COM from code available in OpenSolaris.
420 +Latest version should be always available on http://blogs.sun.com/janp.
422 Index: openssl/crypto/opensslconf.h
423 diff -u openssl/crypto/opensslconf.h:1.5.10.1 openssl/crypto/opensslconf.h:1.5
424 --- openssl/crypto/opensslconf.h:1.5.10.1       Sun Jan 15 15:45:34 2012
425 +++ openssl/crypto/opensslconf.h        Fri Sep  4 10:43:21 2009
426 @@ -38,6 +38,9 @@
428  #endif /* OPENSSL_DOING_MAKEDEPEND */
430 +#ifndef OPENSSL_THREADS
431 +# define OPENSSL_THREADS
432 +#endif
433  #ifndef OPENSSL_NO_DYNAMIC_ENGINE
434  # define OPENSSL_NO_DYNAMIC_ENGINE
435  #endif
436 @@ -79,6 +82,8 @@
437  # endif
438  #endif
440 +#define OPENSSL_CPUID_OBJ
442  /* crypto/opensslconf.h.in */
444  #ifdef OPENSSL_DOING_MAKEDEPEND
445 @@ -140,7 +145,7 @@
446   * This enables code handling data aligned at natural CPU word
447   * boundary. See crypto/rc4/rc4_enc.c for further details.
448   */
449 -#undef RC4_CHUNK
450 +#define RC4_CHUNK unsigned long
451  #endif
452  #endif
454 @@ -148,7 +153,7 @@
455  /* If this is set to 'unsigned int' on a DEC Alpha, this gives about a
456   * %20 speed up (longs are 8 bytes, int's are 4). */
457  #ifndef DES_LONG
458 -#define DES_LONG unsigned long
459 +#define DES_LONG unsigned int
460  #endif
461  #endif
463 @@ -162,9 +167,9 @@
464  /* The prime number generation stuff may not work when
465   * EIGHT_BIT but I don't care since I've only used this mode
466   * for debuging the bignum libraries */
467 -#undef SIXTY_FOUR_BIT_LONG
468 +#define SIXTY_FOUR_BIT_LONG
469  #undef SIXTY_FOUR_BIT
470 -#define THIRTY_TWO_BIT
471 +#undef THIRTY_TWO_BIT
472  #undef SIXTEEN_BIT
473  #undef EIGHT_BIT
474  #endif
475 @@ -178,7 +183,7 @@
477  #if defined(HEADER_BF_LOCL_H) && !defined(CONFIG_HEADER_BF_LOCL_H)
478  #define CONFIG_HEADER_BF_LOCL_H
479 -#undef BF_PTR
480 +#define BF_PTR2
481  #endif /* HEADER_BF_LOCL_H */
483  #if defined(HEADER_DES_LOCL_H) && !defined(CONFIG_HEADER_DES_LOCL_H)
484 @@ -208,7 +213,7 @@
485  /* Unroll the inner loop, this sometimes helps, sometimes hinders.
486   * Very mucy CPU dependant */
487  #ifndef DES_UNROLL
488 -#undef DES_UNROLL
489 +#define DES_UNROLL
490  #endif
492  /* These default values were supplied by
493 Index: openssl/crypto/bio/bss_file.c
494 diff -u openssl/crypto/bio/bss_file.c:1.5.6.1 openssl/crypto/bio/bss_file.c:1.5
495 --- openssl/crypto/bio/bss_file.c:1.5.6.1       Sun Jan 15 15:45:35 2012
496 +++ openssl/crypto/bio/bss_file.c       Mon Jun 13 14:25:17 2011
497 @@ -125,7 +125,7 @@
498                 {
499                 SYSerr(SYS_F_FOPEN,get_last_sys_error());
500                 ERR_add_error_data(5,"fopen('",filename,"','",mode,"')");
501 -               if (errno == ENOENT)
502 +               if ((errno == ENOENT) || ((*mode == 'r') && (errno == EACCES)))
503                         BIOerr(BIO_F_BIO_NEW_FILE,BIO_R_NO_SUCH_FILE);
504                 else
505                         BIOerr(BIO_F_BIO_NEW_FILE,ERR_R_SYS_LIB);
506 Index: openssl/crypto/engine/Makefile
507 diff -u openssl/crypto/engine/Makefile:1.6.6.1 openssl/crypto/engine/Makefile:1.6
508 --- openssl/crypto/engine/Makefile:1.6.6.1      Sun Jan 15 15:45:35 2012
509 +++ openssl/crypto/engine/Makefile      Mon Jun 13 14:25:19 2011
510 @@ -21,12 +21,14 @@
511         eng_table.c eng_pkey.c eng_fat.c eng_all.c \
512         tb_rsa.c tb_dsa.c tb_ecdsa.c tb_dh.c tb_ecdh.c tb_rand.c tb_store.c \
513         tb_cipher.c tb_digest.c \
514 -       eng_openssl.c eng_cnf.c eng_dyn.c eng_cryptodev.c eng_padlock.c
515 +       eng_openssl.c eng_cnf.c eng_dyn.c eng_cryptodev.c eng_padlock.c \
516 +       hw_pk11.c hw_pk11_pub.c hw_pk11so.c hw_pk11so_pub.c
517  LIBOBJ= eng_err.o eng_lib.o eng_list.o eng_init.o eng_ctrl.o \
518         eng_table.o eng_pkey.o eng_fat.o eng_all.o \
519         tb_rsa.o tb_dsa.o tb_ecdsa.o tb_dh.o tb_ecdh.o tb_rand.o tb_store.o \
520         tb_cipher.o tb_digest.o \
521 -       eng_openssl.o eng_cnf.o eng_dyn.o eng_cryptodev.o eng_padlock.o
522 +       eng_openssl.o eng_cnf.o eng_dyn.o eng_cryptodev.o eng_padlock.o \
523 +       hw_pk11.o hw_pk11_pub.o hw_pk11so.o hw_pk11so_pub.o
525  SRC= $(LIBSRC)
527 @@ -288,6 +290,102 @@
528  eng_table.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
529  eng_table.o: ../../include/openssl/x509_vfy.h ../cryptlib.h eng_int.h
530  eng_table.o: eng_table.c
531 +hw_pk11.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
532 +hw_pk11.o: ../../include/openssl/engine.h ../../include/openssl/ossl_typ.h
533 +hw_pk11.o: ../../include/openssl/bn.h ../../include/openssl/rsa.h
534 +hw_pk11.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
535 +hw_pk11.o: ../../include/openssl/crypto.h ../../include/openssl/stack.h
536 +hw_pk11.o: ../../include/openssl/safestack.h ../../include/openssl/opensslv.h
537 +hw_pk11.o: ../../include/openssl/symhacks.h ../../include/openssl/dsa.h
538 +hw_pk11.o: ../../include/openssl/dh.h ../../include/openssl/rand.h
539 +hw_pk11.o: ../../include/openssl/ui.h ../../include/openssl/err.h
540 +hw_pk11.o: ../../include/openssl/lhash.h ../../include/openssl/dso.h
541 +hw_pk11.o: ../../include/openssl/pem.h ../../include/openssl/evp.h
542 +hw_pk11.o: ../../include/openssl/md2.h ../../include/openssl/md4.h
543 +hw_pk11.o: ../../include/openssl/md5.h ../../include/openssl/sha.h
544 +hw_pk11.o: ../../include/openssl/ripemd.h ../../include/openssl/des.h
545 +hw_pk11.o: ../../include/openssl/des_old.h ../../include/openssl/ui_compat.h
546 +hw_pk11.o: ../../include/openssl/rc4.h ../../include/openssl/rc2.h
547 +hw_pk11.o: ../../crypto/rc5/rc5.h ../../include/openssl/blowfish.h
548 +hw_pk11.o: ../../include/openssl/cast.h ../../include/openssl/idea.h
549 +hw_pk11.o: ../../crypto/mdc2/mdc2.h ../../include/openssl/aes.h
550 +hw_pk11.o: ../../include/openssl/objects.h ../../include/openssl/obj_mac.h
551 +hw_pk11.o: ../../include/openssl/x509.h ../../include/openssl/buffer.h
552 +hw_pk11.o: ../../include/openssl/x509_vfy.h ../../include/openssl/pkcs7.h
553 +hw_pk11.o: ../../include/openssl/pem2.h ../cryptlib.h
554 +hw_pk11.o: ../../e_os.h hw_pk11_err.c hw_pk11_err.h hw_pk11.c
555 +hw_pk11_pub.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
556 +hw_pk11_pub.o: ../../include/openssl/engine.h ../../include/openssl/ossl_typ.h
557 +hw_pk11_pub.o: ../../include/openssl/bn.h ../../include/openssl/rsa.h
558 +hw_pk11_pub.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
559 +hw_pk11_pub.o: ../../include/openssl/crypto.h ../../include/openssl/stack.h
560 +hw_pk11_pub.o: ../../include/openssl/safestack.h ../../include/openssl/opensslv.h
561 +hw_pk11_pub.o: ../../include/openssl/symhacks.h ../../include/openssl/dsa.h
562 +hw_pk11_pub.o: ../../include/openssl/dh.h ../../include/openssl/rand.h
563 +hw_pk11_pub.o: ../../include/openssl/ui.h ../../include/openssl/err.h
564 +hw_pk11_pub.o: ../../include/openssl/lhash.h ../../include/openssl/dso.h
565 +hw_pk11_pub.o: ../../include/openssl/pem.h ../../include/openssl/evp.h
566 +hw_pk11_pub.o: ../../include/openssl/md2.h ../../include/openssl/md4.h
567 +hw_pk11_pub.o: ../../include/openssl/md5.h ../../include/openssl/sha.h
568 +hw_pk11_pub.o: ../../include/openssl/ripemd.h ../../include/openssl/des.h
569 +hw_pk11_pub.o: ../../include/openssl/des_old.h ../../include/openssl/ui_compat.h
570 +hw_pk11_pub.o: ../../include/openssl/rc4.h ../../include/openssl/rc2.h
571 +hw_pk11_pub.o: ../../crypto/rc5/rc5.h ../../include/openssl/blowfish.h
572 +hw_pk11_pub.o: ../../include/openssl/cast.h ../../include/openssl/idea.h
573 +hw_pk11_pub.o: ../../crypto/mdc2/mdc2.h ../../include/openssl/aes.h
574 +hw_pk11_pub.o: ../../include/openssl/objects.h ../../include/openssl/obj_mac.h
575 +hw_pk11_pub.o: ../../include/openssl/x509.h ../../include/openssl/buffer.h
576 +hw_pk11_pub.o: ../../include/openssl/x509_vfy.h ../../include/openssl/pkcs7.h
577 +hw_pk11_pub.o: ../../include/openssl/pem2.h ../cryptlib.h
578 +hw_pk11_pub.o: ../../e_os.h hw_pk11_err.c hw_pk11_err.h hw_pk11_pub.c
579 +hw_pk11so.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
580 +hw_pk11so.o: ../../include/openssl/engine.h ../../include/openssl/ossl_typ.h
581 +hw_pk11so.o: ../../include/openssl/bn.h ../../include/openssl/rsa.h
582 +hw_pk11so.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
583 +hw_pk11so.o: ../../include/openssl/crypto.h ../../include/openssl/stack.h
584 +hw_pk11so.o: ../../include/openssl/safestack.h ../../include/openssl/opensslv.h
585 +hw_pk11so.o: ../../include/openssl/symhacks.h ../../include/openssl/dsa.h
586 +hw_pk11so.o: ../../include/openssl/dh.h ../../include/openssl/rand.h
587 +hw_pk11so.o: ../../include/openssl/ui.h ../../include/openssl/err.h
588 +hw_pk11so.o: ../../include/openssl/lhash.h ../../include/openssl/dso.h
589 +hw_pk11so.o: ../../include/openssl/pem.h ../../include/openssl/evp.h
590 +hw_pk11so.o: ../../include/openssl/md2.h ../../include/openssl/md4.h
591 +hw_pk11so.o: ../../include/openssl/md5.h ../../include/openssl/sha.h
592 +hw_pk11so.o: ../../include/openssl/ripemd.h ../../include/openssl/des.h
593 +hw_pk11so.o: ../../include/openssl/des_old.h ../../include/openssl/ui_compat.h
594 +hw_pk11so.o: ../../include/openssl/rc4.h ../../include/openssl/rc2.h
595 +hw_pk11so.o: ../../crypto/rc5/rc5.h ../../include/openssl/blowfish.h
596 +hw_pk11so.o: ../../include/openssl/cast.h ../../include/openssl/idea.h
597 +hw_pk11so.o: ../../crypto/mdc2/mdc2.h ../../include/openssl/aes.h
598 +hw_pk11so.o: ../../include/openssl/objects.h ../../include/openssl/obj_mac.h
599 +hw_pk11so.o: ../../include/openssl/x509.h ../../include/openssl/buffer.h
600 +hw_pk11so.o: ../../include/openssl/x509_vfy.h ../../include/openssl/pkcs7.h
601 +hw_pk11so.o: ../../include/openssl/pem2.h ../cryptlib.h
602 +hw_pk11so.o: ../../e_os.h hw_pk11_err.c hw_pk11_err.h hw_pk11so.c
603 +hw_pk11so_pub.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
604 +hw_pk11so_pub.o: ../../include/openssl/engine.h ../../include/openssl/ossl_typ.h
605 +hw_pk11so_pub.o: ../../include/openssl/bn.h ../../include/openssl/rsa.h
606 +hw_pk11so_pub.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
607 +hw_pk11so_pub.o: ../../include/openssl/crypto.h ../../include/openssl/stack.h
608 +hw_pk11so_pub.o: ../../include/openssl/safestack.h ../../include/openssl/opensslv.h
609 +hw_pk11so_pub.o: ../../include/openssl/symhacks.h ../../include/openssl/dsa.h
610 +hw_pk11so_pub.o: ../../include/openssl/dh.h ../../include/openssl/rand.h
611 +hw_pk11so_pub.o: ../../include/openssl/ui.h ../../include/openssl/err.h
612 +hw_pk11so_pub.o: ../../include/openssl/lhash.h ../../include/openssl/dso.h
613 +hw_pk11so_pub.o: ../../include/openssl/pem.h ../../include/openssl/evp.h
614 +hw_pk11so_pub.o: ../../include/openssl/md2.h ../../include/openssl/md4.h
615 +hw_pk11so_pub.o: ../../include/openssl/md5.h ../../include/openssl/sha.h
616 +hw_pk11so_pub.o: ../../include/openssl/ripemd.h ../../include/openssl/des.h
617 +hw_pk11so_pub.o: ../../include/openssl/des_old.h ../../include/openssl/ui_compat.h
618 +hw_pk11so_pub.o: ../../include/openssl/rc4.h ../../include/openssl/rc2.h
619 +hw_pk11so_pub.o: ../../crypto/rc5/rc5.h ../../include/openssl/blowfish.h
620 +hw_pk11so_pub.o: ../../include/openssl/cast.h ../../include/openssl/idea.h
621 +hw_pk11so_pub.o: ../../crypto/mdc2/mdc2.h ../../include/openssl/aes.h
622 +hw_pk11so_pub.o: ../../include/openssl/objects.h ../../include/openssl/obj_mac.h
623 +hw_pk11so_pub.o: ../../include/openssl/x509.h ../../include/openssl/buffer.h
624 +hw_pk11so_pub.o: ../../include/openssl/x509_vfy.h ../../include/openssl/pkcs7.h
625 +hw_pk11so_pub.o: ../../include/openssl/pem2.h ../cryptlib.h
626 +hw_pk11so_pub.o: ../../e_os.h hw_pk11_err.c hw_pk11_err.h hw_pk11so_pub.c
627  tb_cipher.o: ../../e_os.h ../../include/openssl/asn1.h
628  tb_cipher.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
629  tb_cipher.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
630 Index: openssl/crypto/engine/cryptoki.h
631 diff -u /dev/null openssl/crypto/engine/cryptoki.h:1.4
632 --- /dev/null   Fri Jan  2 13:56:40 2015
633 +++ openssl/crypto/engine/cryptoki.h    Thu Dec 18 00:14:12 2008
634 @@ -0,0 +1,103 @@
636 + * CDDL HEADER START
637 + *
638 + * The contents of this file are subject to the terms of the
639 + * Common Development and Distribution License, Version 1.0 only
640 + * (the "License").  You may not use this file except in compliance
641 + * with the License.
642 + *
643 + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
644 + * or http://www.opensolaris.org/os/licensing.
645 + * See the License for the specific language governing permissions
646 + * and limitations under the License.
647 + *
648 + * When distributing Covered Code, include this CDDL HEADER in each
649 + * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
650 + * If applicable, add the following below this CDDL HEADER, with the
651 + * fields enclosed by brackets "[]" replaced with your own identifying
652 + * information: Portions Copyright [yyyy] [name of copyright owner]
653 + *
654 + * CDDL HEADER END
655 + */
657 + * Copyright 2003 Sun Microsystems, Inc.   All rights reserved.
658 + * Use is subject to license terms.
659 + */
661 +#ifndef        _CRYPTOKI_H
662 +#define        _CRYPTOKI_H
664 +/* ident       "@(#)cryptoki.h 1.2     05/06/08 SMI" */
666 +#ifdef __cplusplus
667 +extern "C" {
668 +#endif
670 +#ifndef        CK_PTR
671 +#define        CK_PTR *
672 +#endif
674 +#ifndef CK_DEFINE_FUNCTION
675 +#define        CK_DEFINE_FUNCTION(returnType, name) returnType name
676 +#endif
678 +#ifndef CK_DECLARE_FUNCTION
679 +#define        CK_DECLARE_FUNCTION(returnType, name) returnType name
680 +#endif
682 +#ifndef CK_DECLARE_FUNCTION_POINTER
683 +#define        CK_DECLARE_FUNCTION_POINTER(returnType, name) returnType (* name)
684 +#endif
686 +#ifndef CK_CALLBACK_FUNCTION
687 +#define        CK_CALLBACK_FUNCTION(returnType, name) returnType (* name)
688 +#endif
690 +#ifndef NULL_PTR
691 +#include <unistd.h>    /* For NULL */
692 +#define        NULL_PTR NULL
693 +#endif
696 + * pkcs11t.h defines TRUE and FALSE in a way that upsets lint
697 + */
698 +#ifndef        CK_DISABLE_TRUE_FALSE
699 +#define        CK_DISABLE_TRUE_FALSE
700 +#ifndef        TRUE
701 +#define        TRUE    1
702 +#endif /* TRUE */
703 +#ifndef        FALSE
704 +#define        FALSE   0
705 +#endif /* FALSE */
706 +#endif /* CK_DISABLE_TRUE_FALSE */
708 +#undef CK_PKCS11_FUNCTION_INFO
710 +#include "pkcs11.h"
712 +/* Solaris specific functions */
714 +#include <stdlib.h>
717 + * SUNW_C_GetMechSession will initialize the framework and do all
718 + * the necessary PKCS#11 calls to create a session capable of
719 + * providing operations on the requested mechanism
720 + */
721 +CK_RV SUNW_C_GetMechSession(CK_MECHANISM_TYPE mech,
722 +    CK_SESSION_HANDLE_PTR hSession);
725 + * SUNW_C_KeyToObject will create a secret key object for the given
726 + * mechanism from the rawkey data.
727 + */
728 +CK_RV SUNW_C_KeyToObject(CK_SESSION_HANDLE hSession,
729 +    CK_MECHANISM_TYPE mech, const void *rawkey, size_t rawkey_len,
730 +    CK_OBJECT_HANDLE_PTR obj);
733 +#ifdef __cplusplus
735 +#endif
737 +#endif /* _CRYPTOKI_H */
738 Index: openssl/crypto/engine/eng_all.c
739 diff -u openssl/crypto/engine/eng_all.c:1.4.6.1.6.1 openssl/crypto/engine/eng_all.c:1.4.2.1
740 --- openssl/crypto/engine/eng_all.c:1.4.6.1.6.1 Thu Jul  3 12:12:33 2014
741 +++ openssl/crypto/engine/eng_all.c     Thu Jul  3 12:31:59 2014
742 @@ -110,6 +110,14 @@
743  #if defined(__OpenBSD__) || defined(__FreeBSD__) || defined(HAVE_CRYPTODEV)
744         ENGINE_load_cryptodev();
745  #endif
746 +#ifndef OPENSSL_NO_HW_PKCS11
747 +#ifndef OPENSSL_NO_HW_PKCS11CA
748 +       ENGINE_load_pk11ca();
749 +#endif
750 +#ifndef OPENSSL_NO_HW_PKCS11SO
751 +       ENGINE_load_pk11so();
752 +#endif
753 +#endif
754  #endif
755         }
757 Index: openssl/crypto/engine/engine.h
758 diff -u openssl/crypto/engine/engine.h:1.4.6.1.6.1 openssl/crypto/engine/engine.h:1.4.2.1
759 --- openssl/crypto/engine/engine.h:1.4.6.1.6.1  Thu Jul  3 12:12:33 2014
760 +++ openssl/crypto/engine/engine.h      Thu Jul  3 12:32:00 2014
761 @@ -344,6 +344,12 @@
762  void ENGINE_load_cryptodev(void);
763  void ENGINE_load_padlock(void);
764  void ENGINE_load_builtin_engines(void);
765 +#ifndef OPENSSL_NO_HW_PKCS11CA
766 +void ENGINE_load_pk11ca(void);
767 +#endif
768 +#ifndef OPENSSL_NO_HW_PKCS11SO
769 +void ENGINE_load_pk11so(void);
770 +#endif
772  /* Get and set global flags (ENGINE_TABLE_FLAG_***) for the implementation
773   * "registry" handling. */
774 Index: openssl/crypto/engine/hw_pk11.c
775 diff -u /dev/null openssl/crypto/engine/hw_pk11.c:1.26.4.4
776 --- /dev/null   Fri Jan  2 13:56:40 2015
777 +++ openssl/crypto/engine/hw_pk11.c     Fri Oct  4 14:45:25 2013
778 @@ -0,0 +1,4116 @@
780 + * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
781 + * Use is subject to license terms.
782 + */
784 +/* crypto/engine/hw_pk11.c */
786 + * This product includes software developed by the OpenSSL Project for
787 + * use in the OpenSSL Toolkit (http://www.openssl.org/).
788 + *
789 + * This project also referenced hw_pkcs11-0.9.7b.patch written by
790 + * Afchine Madjlessi.
791 + */
793 + * ====================================================================
794 + * Copyright (c) 2000-2001 The OpenSSL Project.  All rights reserved.
795 + *
796 + * Redistribution and use in source and binary forms, with or without
797 + * modification, are permitted provided that the following conditions
798 + * are met:
799 + *
800 + * 1. Redistributions of source code must retain the above copyright
801 + *    notice, this list of conditions and the following disclaimer.
802 + *
803 + * 2. Redistributions in binary form must reproduce the above copyright
804 + *    notice, this list of conditions and the following disclaimer in
805 + *    the documentation and/or other materials provided with the
806 + *    distribution.
807 + *
808 + * 3. All advertising materials mentioning features or use of this
809 + *    software must display the following acknowledgment:
810 + *    "This product includes software developed by the OpenSSL Project
811 + *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
812 + *
813 + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
814 + *    endorse or promote products derived from this software without
815 + *    prior written permission. For written permission, please contact
816 + *    licensing@OpenSSL.org.
817 + *
818 + * 5. Products derived from this software may not be called "OpenSSL"
819 + *    nor may "OpenSSL" appear in their names without prior written
820 + *    permission of the OpenSSL Project.
821 + *
822 + * 6. Redistributions of any form whatsoever must retain the following
823 + *    acknowledgment:
824 + *    "This product includes software developed by the OpenSSL Project
825 + *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
826 + *
827 + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
828 + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
829 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
830 + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
831 + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
832 + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
833 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
834 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
835 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
836 + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
837 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
838 + * OF THE POSSIBILITY OF SUCH DAMAGE.
839 + * ====================================================================
840 + *
841 + * This product includes cryptographic software written by Eric Young
842 + * (eay@cryptsoft.com).  This product includes software written by Tim
843 + * Hudson (tjh@cryptsoft.com).
844 + *
845 + */
847 +#include <stdio.h>
848 +#include <stdlib.h>
849 +#include <string.h>
850 +#include <sys/types.h>
852 +#include <openssl/e_os2.h>
853 +#include <openssl/crypto.h>
854 +#include <cryptlib.h>
855 +#include <openssl/engine.h>
856 +#include <openssl/dso.h>
857 +#include <openssl/err.h>
858 +#include <openssl/bn.h>
859 +#include <openssl/md5.h>
860 +#include <openssl/pem.h>
861 +#ifndef OPENSSL_NO_RSA
862 +#include <openssl/rsa.h>
863 +#endif
864 +#ifndef OPENSSL_NO_DSA
865 +#include <openssl/dsa.h>
866 +#endif
867 +#ifndef OPENSSL_NO_DH
868 +#include <openssl/dh.h>
869 +#endif
870 +#include <openssl/rand.h>
871 +#include <openssl/objects.h>
872 +#include <openssl/x509.h>
873 +#include <openssl/aes.h>
874 +#include <openssl/des.h>
876 +#ifdef OPENSSL_SYS_WIN32
877 +typedef int pid_t;
878 +#define getpid() GetCurrentProcessId()
879 +#define NOPTHREADS
880 +#ifndef NULL_PTR
881 +#define NULL_PTR NULL
882 +#endif
883 +#define CK_DEFINE_FUNCTION(returnType, name) \
884 +       returnType __declspec(dllexport) name
885 +#define CK_DECLARE_FUNCTION(returnType, name) \
886 +       returnType __declspec(dllimport) name
887 +#define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
888 +       returnType __declspec(dllimport) (* name)
889 +#else
890 +#include <signal.h>
891 +#include <unistd.h>
892 +#include <dlfcn.h>
893 +#endif
895 +/* Debug mutexes */
896 +/*#undef DEBUG_MUTEX */
897 +#define DEBUG_MUTEX
899 +#ifndef NOPTHREADS
900 +/* for pthread error check on Linuxes */
901 +#ifdef DEBUG_MUTEX
902 +#define __USE_UNIX98
903 +#endif
904 +#include <pthread.h>
905 +#endif
907 +#ifndef OPENSSL_NO_HW
908 +#ifndef OPENSSL_NO_HW_PK11
909 +#ifndef OPENSSL_NO_HW_PK11CA
911 +/* label for debug messages printed on stderr */
912 +#define        PK11_DBG        "PKCS#11 ENGINE DEBUG"
913 +/* prints a lot of debug messages on stderr about slot selection process */
914 +/* #undef      DEBUG_SLOT_SELECTION */
916 + * Solaris specific code. See comment at check_hw_mechanisms() for more
917 + * information.
918 + */
919 +#if defined(__SVR4) && defined(__sun)
920 +#undef SOLARIS_HW_SLOT_SELECTION
921 +#endif
924 + * AES counter mode is not supported in the OpenSSL EVP API yet and neither
925 + * there are official OIDs for mechanisms based on this mode. With our changes,
926 + * an application can define its own EVP calls for AES counter mode and then
927 + * it can make use of hardware acceleration through this engine. However, it's
928 + * better if we keep AES CTR support code under ifdef's.
929 + */
930 +#define        SOLARIS_AES_CTR
932 +#ifdef OPENSSL_SYS_WIN32
933 +#pragma pack(push, cryptoki, 1)
934 +#include "cryptoki.h"
935 +#include "pkcs11.h"
936 +#pragma pack(pop, cryptoki)
937 +#else
938 +#include "cryptoki.h"
939 +#include "pkcs11.h"
940 +#endif
941 +#include "hw_pk11ca.h"
942 +#include "hw_pk11_err.c"
944 +#ifdef SOLARIS_AES_CTR
946 + * NIDs for AES counter mode that will be defined during the engine
947 + * initialization.
948 + */
949 +static int NID_aes_128_ctr = NID_undef;
950 +static int NID_aes_192_ctr = NID_undef;
951 +static int NID_aes_256_ctr = NID_undef;
952 +#endif /* SOLARIS_AES_CTR */
955 + * We use this lock to prevent multiple C_Login()s, guard getpassphrase(),
956 + * uri_struct manipulation, and static token info. All of that is used by the
957 + * RSA keys by reference feature.
958 + */
959 +#ifndef NOPTHREADS
960 +pthread_mutex_t *token_lock;
961 +#endif
963 +#ifdef SOLARIS_HW_SLOT_SELECTION
965 + * Tables for symmetric ciphers and digest mechs found in the pkcs11_kernel
966 + * library. See comment at check_hw_mechanisms() for more information.
967 + */
968 +static int *hw_cnids;
969 +static int *hw_dnids;
970 +#endif /* SOLARIS_HW_SLOT_SELECTION */
972 +/* PKCS#11 session caches and their locks for all operation types */
973 +static PK11_CACHE session_cache[OP_MAX];
976 + * We cache the flags so that we do not have to run C_GetTokenInfo() again when
977 + * logging into the token.
978 + */
979 +CK_FLAGS pubkey_token_flags;
982 + * As stated in v2.20, 11.7 Object Management Function, in section for
983 + * C_FindObjectsInit(), at most one search operation may be active at a given
984 + * time in a given session. Therefore, C_Find{,Init,Final}Objects() should be
985 + * grouped together to form one atomic search operation. This is already
986 + * ensured by the property of unique PKCS#11 session handle used for each
987 + * PK11_SESSION object.
988 + *
989 + * This is however not the biggest concern - maintaining consistency of the
990 + * underlying object store is more important. The same section of the spec also
991 + * says that one thread can be in the middle of a search operation while another
992 + * thread destroys the object matching the search template which would result in
993 + * invalid handle returned from the search operation.
994 + *
995 + * Hence, the following locks are used for both protection of the object stores.
996 + * They are also used for active list protection.
997 + */
998 +#ifndef NOPTHREADS
999 +pthread_mutex_t *find_lock[OP_MAX] = { NULL };
1000 +#endif
1003 + * lists of asymmetric key handles which are active (referenced by at least one
1004 + * PK11_SESSION structure, either held by a thread or present in free_session
1005 + * list) for given algorithm type
1006 + */
1007 +PK11_active *active_list[OP_MAX] = { NULL };
1010 + * Create all secret key objects in a global session so that they are available
1011 + * to use for other sessions. These other sessions may be opened or closed
1012 + * without losing the secret key objects.
1013 + */
1014 +static CK_SESSION_HANDLE       global_session = CK_INVALID_HANDLE;
1016 +/* ENGINE level stuff */
1017 +static int pk11_init(ENGINE *e);
1018 +static int pk11_library_init(ENGINE *e);
1019 +static int pk11_finish(ENGINE *e);
1020 +static int pk11_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void));
1021 +static int pk11_destroy(ENGINE *e);
1023 +/* RAND stuff */
1024 +static void pk11_rand_seed(const void *buf, int num);
1025 +static void pk11_rand_add(const void *buf, int num, double add_entropy);
1026 +static void pk11_rand_cleanup(void);
1027 +static int pk11_rand_bytes(unsigned char *buf, int num);
1028 +static int pk11_rand_status(void);
1030 +/* These functions are also used in other files */
1031 +PK11_SESSION *pk11_get_session(PK11_OPTYPE optype);
1032 +void pk11_return_session(PK11_SESSION *sp, PK11_OPTYPE optype);
1034 +/* active list manipulation functions used in this file */
1035 +extern int pk11_active_delete(CK_OBJECT_HANDLE h, PK11_OPTYPE type);
1036 +extern void pk11_free_active_list(PK11_OPTYPE type);
1038 +#ifndef OPENSSL_NO_RSA
1039 +int pk11_destroy_rsa_key_objects(PK11_SESSION *session);
1040 +int pk11_destroy_rsa_object_pub(PK11_SESSION *sp, CK_BBOOL uselock);
1041 +int pk11_destroy_rsa_object_priv(PK11_SESSION *sp, CK_BBOOL uselock);
1042 +#endif
1043 +#ifndef OPENSSL_NO_DSA
1044 +int pk11_destroy_dsa_key_objects(PK11_SESSION *session);
1045 +int pk11_destroy_dsa_object_pub(PK11_SESSION *sp, CK_BBOOL uselock);
1046 +int pk11_destroy_dsa_object_priv(PK11_SESSION *sp, CK_BBOOL uselock);
1047 +#endif
1048 +#ifndef OPENSSL_NO_DH
1049 +int pk11_destroy_dh_key_objects(PK11_SESSION *session);
1050 +int pk11_destroy_dh_object(PK11_SESSION *session, CK_BBOOL uselock);
1051 +#endif
1053 +/* Local helper functions */
1054 +static int pk11_free_all_sessions(void);
1055 +static int pk11_free_session_list(PK11_OPTYPE optype);
1056 +static int pk11_setup_session(PK11_SESSION *sp, PK11_OPTYPE optype);
1057 +static int pk11_destroy_cipher_key_objects(PK11_SESSION *session);
1058 +static int pk11_destroy_object(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE oh,
1059 +       CK_BBOOL persistent);
1060 +static const char *get_PK11_LIBNAME(void);
1061 +static void free_PK11_LIBNAME(void);
1062 +static long set_PK11_LIBNAME(const char *name);
1064 +/* Symmetric cipher and digest support functions */
1065 +static int cipher_nid_to_pk11(int nid);
1066 +#ifdef SOLARIS_AES_CTR
1067 +static int pk11_add_NID(char *sn, char *ln);
1068 +static int pk11_add_aes_ctr_NIDs(void);
1069 +#endif /* SOLARIS_AES_CTR */
1070 +static int pk11_usable_ciphers(const int **nids);
1071 +static int pk11_usable_digests(const int **nids);
1072 +static int pk11_cipher_init(EVP_CIPHER_CTX *ctx, const unsigned char *key,
1073 +       const unsigned char *iv, int enc);
1074 +static int pk11_cipher_final(PK11_SESSION *sp);
1075 +#if OPENSSL_VERSION_NUMBER < 0x10000000L
1076 +static int pk11_cipher_do_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
1077 +       const unsigned char *in, unsigned int inl);
1078 +#else
1079 +static int pk11_cipher_do_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
1080 +       const unsigned char *in, size_t inl);
1081 +#endif
1082 +static int pk11_cipher_cleanup(EVP_CIPHER_CTX *ctx);
1083 +static int pk11_engine_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
1084 +       const int **nids, int nid);
1085 +static int pk11_engine_digests(ENGINE *e, const EVP_MD **digest,
1086 +       const int **nids, int nid);
1087 +static CK_OBJECT_HANDLE pk11_get_cipher_key(EVP_CIPHER_CTX *ctx,
1088 +       const unsigned char *key, CK_KEY_TYPE key_type, PK11_SESSION *sp);
1089 +static int check_new_cipher_key(PK11_SESSION *sp, const unsigned char *key,
1090 +       int key_len);
1091 +static int md_nid_to_pk11(int nid);
1092 +static int pk11_digest_init(EVP_MD_CTX *ctx);
1093 +static int pk11_digest_update(EVP_MD_CTX *ctx, const void *data,
1094 +       size_t count);
1095 +static int pk11_digest_final(EVP_MD_CTX *ctx, unsigned char *md);
1096 +static int pk11_digest_copy(EVP_MD_CTX *to, const EVP_MD_CTX *from);
1097 +static int pk11_digest_cleanup(EVP_MD_CTX *ctx);
1099 +static int pk11_choose_slots(int *any_slot_found);
1100 +static void pk11_find_symmetric_ciphers(CK_FUNCTION_LIST_PTR pflist,
1101 +    CK_SLOT_ID current_slot, int *current_slot_n_cipher,
1102 +    int *local_cipher_nids);
1103 +static void pk11_find_digests(CK_FUNCTION_LIST_PTR pflist,
1104 +    CK_SLOT_ID current_slot, int *current_slot_n_digest,
1105 +    int *local_digest_nids);
1106 +static void pk11_get_symmetric_cipher(CK_FUNCTION_LIST_PTR, int slot_id,
1107 +    CK_MECHANISM_TYPE mech, int *current_slot_n_cipher, int *local_cipher_nids,
1108 +    int id);
1109 +static void pk11_get_digest(CK_FUNCTION_LIST_PTR pflist, int slot_id,
1110 +    CK_MECHANISM_TYPE mech, int *current_slot_n_digest, int *local_digest_nids,
1111 +    int id);
1113 +static int pk11_init_all_locks(void);
1114 +static void pk11_free_all_locks(void);
1116 +#ifdef SOLARIS_HW_SLOT_SELECTION
1117 +static int check_hw_mechanisms(void);
1118 +static int nid_in_table(int nid, int *nid_table);
1119 +#endif /* SOLARIS_HW_SLOT_SELECTION */
1121 +/* Index for the supported ciphers */
1122 +enum pk11_cipher_id {
1123 +       PK11_DES_CBC,
1124 +       PK11_DES3_CBC,
1125 +       PK11_DES_ECB,
1126 +       PK11_DES3_ECB,
1127 +       PK11_RC4,
1128 +       PK11_AES_128_CBC,
1129 +       PK11_AES_192_CBC,
1130 +       PK11_AES_256_CBC,
1131 +       PK11_AES_128_ECB,
1132 +       PK11_AES_192_ECB,
1133 +       PK11_AES_256_ECB,
1134 +       PK11_BLOWFISH_CBC,
1135 +#ifdef SOLARIS_AES_CTR
1136 +       PK11_AES_128_CTR,
1137 +       PK11_AES_192_CTR,
1138 +       PK11_AES_256_CTR,
1139 +#endif /* SOLARIS_AES_CTR */
1140 +       PK11_CIPHER_MAX
1143 +/* Index for the supported digests */
1144 +enum pk11_digest_id {
1145 +       PK11_MD5,
1146 +       PK11_SHA1,
1147 +       PK11_SHA224,
1148 +       PK11_SHA256,
1149 +       PK11_SHA384,
1150 +       PK11_SHA512,
1151 +       PK11_DIGEST_MAX
1154 +#define        TRY_OBJ_DESTROY(sp, obj_hdl, retval, uselock, alg_type, priv)   \
1155 +       {                                                               \
1156 +       if (uselock)                                                    \
1157 +               LOCK_OBJSTORE(alg_type);                                \
1158 +       if (pk11_active_delete(obj_hdl, alg_type) == 1)                 \
1159 +               {                                                       \
1160 +                 retval = pk11_destroy_object(sp->session, obj_hdl,    \
1161 +                 priv ? sp->priv_persistent : sp->pub_persistent);     \
1162 +               }                                                       \
1163 +       if (uselock)                                                    \
1164 +               UNLOCK_OBJSTORE(alg_type);                              \
1165 +       }
1167 +static int cipher_nids[PK11_CIPHER_MAX];
1168 +static int digest_nids[PK11_DIGEST_MAX];
1169 +static int cipher_count                = 0;
1170 +static int digest_count                = 0;
1171 +static CK_BBOOL pk11_have_rsa  = CK_FALSE;
1172 +static CK_BBOOL pk11_have_recover = CK_FALSE;
1173 +static CK_BBOOL pk11_have_dsa  = CK_FALSE;
1174 +static CK_BBOOL pk11_have_dh   = CK_FALSE;
1175 +static CK_BBOOL pk11_have_random = CK_FALSE;
1177 +typedef struct PK11_CIPHER_st
1178 +       {
1179 +       enum pk11_cipher_id     id;
1180 +       int                     nid;
1181 +       int                     iv_len;
1182 +       int                     min_key_len;
1183 +       int                     max_key_len;
1184 +       CK_KEY_TYPE             key_type;
1185 +       CK_MECHANISM_TYPE       mech_type;
1186 +       } PK11_CIPHER;
1188 +static PK11_CIPHER ciphers[] =
1189 +       {
1190 +       { PK11_DES_CBC,         NID_des_cbc,            8,       8,   8,
1191 +               CKK_DES,        CKM_DES_CBC, },
1192 +       { PK11_DES3_CBC,        NID_des_ede3_cbc,       8,      24,  24,
1193 +               CKK_DES3,       CKM_DES3_CBC, },
1194 +       { PK11_DES_ECB,         NID_des_ecb,            0,       8,   8,
1195 +               CKK_DES,        CKM_DES_ECB, },
1196 +       { PK11_DES3_ECB,        NID_des_ede3_ecb,       0,      24,  24,
1197 +               CKK_DES3,       CKM_DES3_ECB, },
1198 +       { PK11_RC4,             NID_rc4,                0,      16, 256,
1199 +               CKK_RC4,        CKM_RC4, },
1200 +       { PK11_AES_128_CBC,     NID_aes_128_cbc,        16,     16,  16,
1201 +               CKK_AES,        CKM_AES_CBC, },
1202 +       { PK11_AES_192_CBC,     NID_aes_192_cbc,        16,     24,  24,
1203 +               CKK_AES,        CKM_AES_CBC, },
1204 +       { PK11_AES_256_CBC,     NID_aes_256_cbc,        16,     32,  32,
1205 +               CKK_AES,        CKM_AES_CBC, },
1206 +       { PK11_AES_128_ECB,     NID_aes_128_ecb,        0,      16,  16,
1207 +               CKK_AES,        CKM_AES_ECB, },
1208 +       { PK11_AES_192_ECB,     NID_aes_192_ecb,        0,      24,  24,
1209 +               CKK_AES,        CKM_AES_ECB, },
1210 +       { PK11_AES_256_ECB,     NID_aes_256_ecb,        0,      32,  32,
1211 +               CKK_AES,        CKM_AES_ECB, },
1212 +       { PK11_BLOWFISH_CBC,    NID_bf_cbc,             8,      16,  16,
1213 +               CKK_BLOWFISH,   CKM_BLOWFISH_CBC, },
1214 +#ifdef SOLARIS_AES_CTR
1215 +       /* we don't know the correct NIDs until the engine is initialized */
1216 +       { PK11_AES_128_CTR,     NID_undef,              16,     16,  16,
1217 +               CKK_AES,        CKM_AES_CTR, },
1218 +       { PK11_AES_192_CTR,     NID_undef,              16,     24,  24,
1219 +               CKK_AES,        CKM_AES_CTR, },
1220 +       { PK11_AES_256_CTR,     NID_undef,              16,     32,  32,
1221 +               CKK_AES,        CKM_AES_CTR, },
1222 +#endif /* SOLARIS_AES_CTR */
1223 +       };
1225 +typedef struct PK11_DIGEST_st
1226 +       {
1227 +       enum pk11_digest_id     id;
1228 +       int                     nid;
1229 +       CK_MECHANISM_TYPE       mech_type;
1230 +       } PK11_DIGEST;
1232 +static PK11_DIGEST digests[] =
1233 +       {
1234 +       {PK11_MD5,      NID_md5,        CKM_MD5, },
1235 +       {PK11_SHA1,     NID_sha1,       CKM_SHA_1, },
1236 +       {PK11_SHA224,   NID_sha224,     CKM_SHA224, },
1237 +       {PK11_SHA256,   NID_sha256,     CKM_SHA256, },
1238 +       {PK11_SHA384,   NID_sha384,     CKM_SHA384, },
1239 +       {PK11_SHA512,   NID_sha512,     CKM_SHA512, },
1240 +       {0,             NID_undef,      0xFFFF, },
1241 +       };
1244 + * Structure to be used for the cipher_data/md_data in
1245 + * EVP_CIPHER_CTX/EVP_MD_CTX structures in order to use the same pk11
1246 + * session in multiple cipher_update calls
1247 + */
1248 +typedef struct PK11_CIPHER_STATE_st
1249 +       {
1250 +       PK11_SESSION    *sp;
1251 +       } PK11_CIPHER_STATE;
1255 + * libcrypto EVP stuff - this is how we get wired to EVP so the engine gets
1256 + * called when libcrypto requests a cipher NID.
1257 + *
1258 + * Note how the PK11_CIPHER_STATE is used here.
1259 + */
1261 +/* DES CBC EVP */
1262 +static const EVP_CIPHER pk11_des_cbc =
1263 +       {
1264 +       NID_des_cbc,
1265 +       8, 8, 8,
1266 +       EVP_CIPH_CBC_MODE,
1267 +       pk11_cipher_init,
1268 +       pk11_cipher_do_cipher,
1269 +       pk11_cipher_cleanup,
1270 +       sizeof (PK11_CIPHER_STATE),
1271 +       EVP_CIPHER_set_asn1_iv,
1272 +       EVP_CIPHER_get_asn1_iv,
1273 +       NULL
1274 +       };
1276 +/* 3DES CBC EVP */
1277 +static const EVP_CIPHER pk11_3des_cbc =
1278 +       {
1279 +       NID_des_ede3_cbc,
1280 +       8, 24, 8,
1281 +       EVP_CIPH_CBC_MODE,
1282 +       pk11_cipher_init,
1283 +       pk11_cipher_do_cipher,
1284 +       pk11_cipher_cleanup,
1285 +       sizeof (PK11_CIPHER_STATE),
1286 +       EVP_CIPHER_set_asn1_iv,
1287 +       EVP_CIPHER_get_asn1_iv,
1288 +       NULL
1289 +       };
1292 + * ECB modes don't use an Initial Vector so that's why set_asn1_parameters and
1293 + * get_asn1_parameters fields are set to NULL.
1294 + */
1295 +static const EVP_CIPHER pk11_des_ecb =
1296 +       {
1297 +       NID_des_ecb,
1298 +       8, 8, 8,
1299 +       EVP_CIPH_ECB_MODE,
1300 +       pk11_cipher_init,
1301 +       pk11_cipher_do_cipher,
1302 +       pk11_cipher_cleanup,
1303 +       sizeof (PK11_CIPHER_STATE),
1304 +       NULL,
1305 +       NULL,
1306 +       NULL
1307 +       };
1309 +static const EVP_CIPHER pk11_3des_ecb =
1310 +       {
1311 +       NID_des_ede3_ecb,
1312 +       8, 24, 8,
1313 +       EVP_CIPH_ECB_MODE,
1314 +       pk11_cipher_init,
1315 +       pk11_cipher_do_cipher,
1316 +       pk11_cipher_cleanup,
1317 +       sizeof (PK11_CIPHER_STATE),
1318 +       NULL,
1319 +       NULL,
1320 +       NULL
1321 +       };
1324 +static const EVP_CIPHER pk11_aes_128_cbc =
1325 +       {
1326 +       NID_aes_128_cbc,
1327 +       16, 16, 16,
1328 +       EVP_CIPH_CBC_MODE,
1329 +       pk11_cipher_init,
1330 +       pk11_cipher_do_cipher,
1331 +       pk11_cipher_cleanup,
1332 +       sizeof (PK11_CIPHER_STATE),
1333 +       EVP_CIPHER_set_asn1_iv,
1334 +       EVP_CIPHER_get_asn1_iv,
1335 +       NULL
1336 +       };
1338 +static const EVP_CIPHER pk11_aes_192_cbc =
1339 +       {
1340 +       NID_aes_192_cbc,
1341 +       16, 24, 16,
1342 +       EVP_CIPH_CBC_MODE,
1343 +       pk11_cipher_init,
1344 +       pk11_cipher_do_cipher,
1345 +       pk11_cipher_cleanup,
1346 +       sizeof (PK11_CIPHER_STATE),
1347 +       EVP_CIPHER_set_asn1_iv,
1348 +       EVP_CIPHER_get_asn1_iv,
1349 +       NULL
1350 +       };
1352 +static const EVP_CIPHER pk11_aes_256_cbc =
1353 +       {
1354 +       NID_aes_256_cbc,
1355 +       16, 32, 16,
1356 +       EVP_CIPH_CBC_MODE,
1357 +       pk11_cipher_init,
1358 +       pk11_cipher_do_cipher,
1359 +       pk11_cipher_cleanup,
1360 +       sizeof (PK11_CIPHER_STATE),
1361 +       EVP_CIPHER_set_asn1_iv,
1362 +       EVP_CIPHER_get_asn1_iv,
1363 +       NULL
1364 +       };
1367 + * ECB modes don't use IV so that's why set_asn1_parameters and
1368 + * get_asn1_parameters are set to NULL.
1369 + */
1370 +static const EVP_CIPHER pk11_aes_128_ecb =
1371 +       {
1372 +       NID_aes_128_ecb,
1373 +       16, 16, 0,
1374 +       EVP_CIPH_ECB_MODE,
1375 +       pk11_cipher_init,
1376 +       pk11_cipher_do_cipher,
1377 +       pk11_cipher_cleanup,
1378 +       sizeof (PK11_CIPHER_STATE),
1379 +       NULL,
1380 +       NULL,
1381 +       NULL
1382 +       };
1384 +static const EVP_CIPHER pk11_aes_192_ecb =
1385 +       {
1386 +       NID_aes_192_ecb,
1387 +       16, 24, 0,
1388 +       EVP_CIPH_ECB_MODE,
1389 +       pk11_cipher_init,
1390 +       pk11_cipher_do_cipher,
1391 +       pk11_cipher_cleanup,
1392 +       sizeof (PK11_CIPHER_STATE),
1393 +       NULL,
1394 +       NULL,
1395 +       NULL
1396 +       };
1398 +static const EVP_CIPHER pk11_aes_256_ecb =
1399 +       {
1400 +       NID_aes_256_ecb,
1401 +       16, 32, 0,
1402 +       EVP_CIPH_ECB_MODE,
1403 +       pk11_cipher_init,
1404 +       pk11_cipher_do_cipher,
1405 +       pk11_cipher_cleanup,
1406 +       sizeof (PK11_CIPHER_STATE),
1407 +       NULL,
1408 +       NULL,
1409 +       NULL
1410 +       };
1412 +#ifdef SOLARIS_AES_CTR
1414 + * NID_undef's will be changed to the AES counter mode NIDs as soon they are
1415 + * created in pk11_library_init(). Note that the need to change these structures
1416 + * is the reason why we don't define them with the const keyword.
1417 + */
1418 +static EVP_CIPHER pk11_aes_128_ctr =
1419 +       {
1420 +       NID_undef,
1421 +       16, 16, 16,
1422 +       EVP_CIPH_CBC_MODE,
1423 +       pk11_cipher_init,
1424 +       pk11_cipher_do_cipher,
1425 +       pk11_cipher_cleanup,
1426 +       sizeof (PK11_CIPHER_STATE),
1427 +       EVP_CIPHER_set_asn1_iv,
1428 +       EVP_CIPHER_get_asn1_iv,
1429 +       NULL
1430 +       };
1432 +static EVP_CIPHER pk11_aes_192_ctr =
1433 +       {
1434 +       NID_undef,
1435 +       16, 24, 16,
1436 +       EVP_CIPH_CBC_MODE,
1437 +       pk11_cipher_init,
1438 +       pk11_cipher_do_cipher,
1439 +       pk11_cipher_cleanup,
1440 +       sizeof (PK11_CIPHER_STATE),
1441 +       EVP_CIPHER_set_asn1_iv,
1442 +       EVP_CIPHER_get_asn1_iv,
1443 +       NULL
1444 +       };
1446 +static EVP_CIPHER pk11_aes_256_ctr =
1447 +       {
1448 +       NID_undef,
1449 +       16, 32, 16,
1450 +       EVP_CIPH_CBC_MODE,
1451 +       pk11_cipher_init,
1452 +       pk11_cipher_do_cipher,
1453 +       pk11_cipher_cleanup,
1454 +       sizeof (PK11_CIPHER_STATE),
1455 +       EVP_CIPHER_set_asn1_iv,
1456 +       EVP_CIPHER_get_asn1_iv,
1457 +       NULL
1458 +       };
1459 +#endif /* SOLARIS_AES_CTR */
1461 +static const EVP_CIPHER pk11_bf_cbc =
1462 +       {
1463 +       NID_bf_cbc,
1464 +       8, 16, 8,
1465 +       EVP_CIPH_VARIABLE_LENGTH,
1466 +       pk11_cipher_init,
1467 +       pk11_cipher_do_cipher,
1468 +       pk11_cipher_cleanup,
1469 +       sizeof (PK11_CIPHER_STATE),
1470 +       EVP_CIPHER_set_asn1_iv,
1471 +       EVP_CIPHER_get_asn1_iv,
1472 +       NULL
1473 +       };
1475 +static const EVP_CIPHER pk11_rc4 =
1476 +       {
1477 +       NID_rc4,
1478 +       1, 16, 0,
1479 +       EVP_CIPH_VARIABLE_LENGTH,
1480 +       pk11_cipher_init,
1481 +       pk11_cipher_do_cipher,
1482 +       pk11_cipher_cleanup,
1483 +       sizeof (PK11_CIPHER_STATE),
1484 +       NULL,
1485 +       NULL,
1486 +       NULL
1487 +       };
1489 +static const EVP_MD pk11_md5 =
1490 +       {
1491 +       NID_md5,
1492 +       NID_md5WithRSAEncryption,
1493 +       MD5_DIGEST_LENGTH,
1494 +       0,
1495 +       pk11_digest_init,
1496 +       pk11_digest_update,
1497 +       pk11_digest_final,
1498 +       pk11_digest_copy,
1499 +       pk11_digest_cleanup,
1500 +       EVP_PKEY_RSA_method,
1501 +       MD5_CBLOCK,
1502 +       sizeof (PK11_CIPHER_STATE),
1503 +       };
1505 +static const EVP_MD pk11_sha1 =
1506 +       {
1507 +       NID_sha1,
1508 +       NID_sha1WithRSAEncryption,
1509 +       SHA_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 +       SHA_CBLOCK,
1518 +       sizeof (PK11_CIPHER_STATE),
1519 +       };
1521 +static const EVP_MD pk11_sha224 =
1522 +       {
1523 +       NID_sha224,
1524 +       NID_sha224WithRSAEncryption,
1525 +       SHA224_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-224 uses the same cblock size as SHA-256 */
1534 +       SHA256_CBLOCK,
1535 +       sizeof (PK11_CIPHER_STATE),
1536 +       };
1538 +static const EVP_MD pk11_sha256 =
1539 +       {
1540 +       NID_sha256,
1541 +       NID_sha256WithRSAEncryption,
1542 +       SHA256_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 +       SHA256_CBLOCK,
1551 +       sizeof (PK11_CIPHER_STATE),
1552 +       };
1554 +static const EVP_MD pk11_sha384 =
1555 +       {
1556 +       NID_sha384,
1557 +       NID_sha384WithRSAEncryption,
1558 +       SHA384_DIGEST_LENGTH,
1559 +       0,
1560 +       pk11_digest_init,
1561 +       pk11_digest_update,
1562 +       pk11_digest_final,
1563 +       pk11_digest_copy,
1564 +       pk11_digest_cleanup,
1565 +       EVP_PKEY_RSA_method,
1566 +       /* SHA-384 uses the same cblock size as SHA-512 */
1567 +       SHA512_CBLOCK,
1568 +       sizeof (PK11_CIPHER_STATE),
1569 +       };
1571 +static const EVP_MD pk11_sha512 =
1572 +       {
1573 +       NID_sha512,
1574 +       NID_sha512WithRSAEncryption,
1575 +       SHA512_DIGEST_LENGTH,
1576 +       0,
1577 +       pk11_digest_init,
1578 +       pk11_digest_update,
1579 +       pk11_digest_final,
1580 +       pk11_digest_copy,
1581 +       pk11_digest_cleanup,
1582 +       EVP_PKEY_RSA_method,
1583 +       SHA512_CBLOCK,
1584 +       sizeof (PK11_CIPHER_STATE),
1585 +       };
1588 + * Initialization function. Sets up various PKCS#11 library components.
1589 + * The definitions for control commands specific to this engine
1590 + */
1591 +#define PK11_CMD_SO_PATH               ENGINE_CMD_BASE
1592 +#define PK11_CMD_PIN                   (ENGINE_CMD_BASE+1)
1593 +#define PK11_CMD_SLOT                  (ENGINE_CMD_BASE+2)
1594 +static const ENGINE_CMD_DEFN pk11_cmd_defns[] =
1595 +       {
1596 +               {
1597 +               PK11_CMD_SO_PATH,
1598 +               "SO_PATH",
1599 +               "Specifies the path to the 'pkcs#11' shared library",
1600 +               ENGINE_CMD_FLAG_STRING
1601 +               },
1602 +               {
1603 +               PK11_CMD_PIN,
1604 +               "PIN",
1605 +               "Specifies the pin code",
1606 +               ENGINE_CMD_FLAG_STRING
1607 +               },
1608 +               {
1609 +               PK11_CMD_SLOT,
1610 +               "SLOT",
1611 +               "Specifies the slot (default is auto select)",
1612 +               ENGINE_CMD_FLAG_NUMERIC,
1613 +               },
1614 +               {0, NULL, NULL, 0}
1615 +       };
1618 +static RAND_METHOD pk11_random =
1619 +       {
1620 +       pk11_rand_seed,
1621 +       pk11_rand_bytes,
1622 +       pk11_rand_cleanup,
1623 +       pk11_rand_add,
1624 +       pk11_rand_bytes,
1625 +       pk11_rand_status
1626 +       };
1629 +/* Constants used when creating the ENGINE */
1630 +#ifdef OPENSSL_NO_HW_PK11SO
1631 +#error "can't load both crypto-accelerator and sign-only PKCS#11 engines"
1632 +#endif
1633 +static const char *engine_pk11_id = "pkcs11";
1634 +static const char *engine_pk11_name =
1635 +       "PKCS #11 engine support (crypto accelerator)";
1637 +CK_FUNCTION_LIST_PTR pFuncList = NULL;
1638 +static const char PK11_GET_FUNCTION_LIST[] = "C_GetFunctionList";
1641 + * This is a static string constant for the DSO file name and the function
1642 + * symbol names to bind to. We set it in the Configure script based on whether
1643 + * this is 32 or 64 bit build.
1644 + */
1645 +static const char def_PK11_LIBNAME[] = PK11_LIB_LOCATION;
1647 +static CK_BBOOL mytrue = TRUE;
1648 +static CK_BBOOL myfalse = FALSE;
1649 +/* Needed in hw_pk11_pub.c as well so that's why it is not static. */
1650 +CK_SLOT_ID pubkey_SLOTID = 0;
1651 +static CK_SLOT_ID rand_SLOTID = 0;
1652 +static CK_SLOT_ID SLOTID = 0;
1653 +char *pk11_pin = NULL;
1654 +static CK_BBOOL pk11_library_initialized = FALSE;
1655 +static CK_BBOOL pk11_atfork_initialized = FALSE;
1656 +static int pk11_pid = 0;
1658 +static DSO *pk11_dso = NULL;
1660 +/* allocate and initialize all locks used by the engine itself */
1661 +static int pk11_init_all_locks(void)
1662 +       {
1663 +#ifndef NOPTHREADS
1664 +       int type;
1665 +       pthread_mutexattr_t attr;
1667 +       if (pthread_mutexattr_init(&attr) != 0)
1668 +       {
1669 +               PK11err(PK11_F_INIT_ALL_LOCKS, 100);
1670 +               return (0);
1671 +       }
1673 +#ifdef DEBUG_MUTEX
1674 +       if (pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK) != 0)
1675 +       {
1676 +               PK11err(PK11_F_INIT_ALL_LOCKS, 101);
1677 +               return (0);
1678 +       }
1679 +#endif
1681 +       if ((token_lock = OPENSSL_malloc(sizeof (pthread_mutex_t))) == NULL)
1682 +               goto malloc_err;
1683 +       (void) pthread_mutex_init(token_lock, &attr);
1685 +#ifndef OPENSSL_NO_RSA
1686 +       find_lock[OP_RSA] = OPENSSL_malloc(sizeof (pthread_mutex_t));
1687 +       if (find_lock[OP_RSA] == NULL)
1688 +               goto malloc_err;
1689 +       (void) pthread_mutex_init(find_lock[OP_RSA], &attr);
1690 +#endif /* OPENSSL_NO_RSA */
1692 +#ifndef OPENSSL_NO_DSA
1693 +       find_lock[OP_DSA] = OPENSSL_malloc(sizeof (pthread_mutex_t));
1694 +       if (find_lock[OP_DSA] == NULL)
1695 +               goto malloc_err;
1696 +       (void) pthread_mutex_init(find_lock[OP_DSA], &attr);
1697 +#endif /* OPENSSL_NO_DSA */
1699 +#ifndef OPENSSL_NO_DH
1700 +       find_lock[OP_DH] = OPENSSL_malloc(sizeof (pthread_mutex_t));
1701 +       if (find_lock[OP_DH] == NULL)
1702 +               goto malloc_err;
1703 +       (void) pthread_mutex_init(find_lock[OP_DH], &attr);
1704 +#endif /* OPENSSL_NO_DH */
1706 +       for (type = 0; type < OP_MAX; type++)
1707 +               {
1708 +               session_cache[type].lock =
1709 +                   OPENSSL_malloc(sizeof (pthread_mutex_t));
1710 +               if (session_cache[type].lock == NULL)
1711 +                       goto malloc_err;
1712 +               (void) pthread_mutex_init(session_cache[type].lock, &attr);
1713 +               }
1715 +       return (1);
1717 +malloc_err:
1718 +       pk11_free_all_locks();
1719 +       PK11err(PK11_F_INIT_ALL_LOCKS, PK11_R_MALLOC_FAILURE);
1720 +       return (0);
1721 +#else
1722 +       return (1);
1723 +#endif
1724 +       }
1726 +static void pk11_free_all_locks(void)
1727 +       {
1728 +#ifndef NOPTHREADS
1729 +       int type;
1731 +       if (token_lock != NULL)
1732 +               {
1733 +               (void) pthread_mutex_destroy(token_lock);
1734 +               OPENSSL_free(token_lock);
1735 +               token_lock = NULL;
1736 +               }
1738 +#ifndef OPENSSL_NO_RSA
1739 +       if (find_lock[OP_RSA] != NULL)
1740 +               {
1741 +               (void) pthread_mutex_destroy(find_lock[OP_RSA]);
1742 +               OPENSSL_free(find_lock[OP_RSA]);
1743 +               find_lock[OP_RSA] = NULL;
1744 +               }
1745 +#endif /* OPENSSL_NO_RSA */
1746 +#ifndef OPENSSL_NO_DSA
1747 +       if (find_lock[OP_DSA] != NULL)
1748 +               {
1749 +               (void) pthread_mutex_destroy(find_lock[OP_DSA]);
1750 +               OPENSSL_free(find_lock[OP_DSA]);
1751 +               find_lock[OP_DSA] = NULL;
1752 +               }
1753 +#endif /* OPENSSL_NO_DSA */
1754 +#ifndef OPENSSL_NO_DH
1755 +       if (find_lock[OP_DH] != NULL)
1756 +               {
1757 +               (void) pthread_mutex_destroy(find_lock[OP_DH]);
1758 +               OPENSSL_free(find_lock[OP_DH]);
1759 +               find_lock[OP_DH] = NULL;
1760 +               }
1761 +#endif /* OPENSSL_NO_DH */
1763 +       for (type = 0; type < OP_MAX; type++)
1764 +               {
1765 +               if (session_cache[type].lock != NULL)
1766 +                       {
1767 +                       (void) pthread_mutex_destroy(session_cache[type].lock);
1768 +                       OPENSSL_free(session_cache[type].lock);
1769 +                       session_cache[type].lock = NULL;
1770 +                       }
1771 +               }
1772 +#endif
1773 +       }
1776 + * This internal function is used by ENGINE_pk11() and "dynamic" ENGINE support.
1777 + */
1778 +static int bind_pk11(ENGINE *e)
1779 +       {
1780 +#ifndef OPENSSL_NO_RSA
1781 +       const RSA_METHOD *rsa = NULL;
1782 +       RSA_METHOD *pk11_rsa = PK11_RSA();
1783 +#endif /* OPENSSL_NO_RSA */
1784 +       if (!pk11_library_initialized)
1785 +               if (!pk11_library_init(e))
1786 +                       return (0);
1788 +       if (!ENGINE_set_id(e, engine_pk11_id) ||
1789 +           !ENGINE_set_name(e, engine_pk11_name) ||
1790 +           !ENGINE_set_ciphers(e, pk11_engine_ciphers) ||
1791 +           !ENGINE_set_digests(e, pk11_engine_digests))
1792 +               return (0);
1793 +#ifndef OPENSSL_NO_RSA
1794 +       if (pk11_have_rsa == CK_TRUE)
1795 +               {
1796 +               if (!ENGINE_set_RSA(e, PK11_RSA()) ||
1797 +                   !ENGINE_set_load_privkey_function(e, pk11_load_privkey) ||
1798 +                   !ENGINE_set_load_pubkey_function(e, pk11_load_pubkey))
1799 +                       return (0);
1800 +#ifdef DEBUG_SLOT_SELECTION
1801 +               fprintf(stderr, "%s: registered RSA\n", PK11_DBG);
1802 +#endif /* DEBUG_SLOT_SELECTION */
1803 +               }
1804 +#endif /* OPENSSL_NO_RSA */
1805 +#ifndef OPENSSL_NO_DSA
1806 +       if (pk11_have_dsa == CK_TRUE)
1807 +               {
1808 +               if (!ENGINE_set_DSA(e, PK11_DSA()))
1809 +                       return (0);
1810 +#ifdef DEBUG_SLOT_SELECTION
1811 +               fprintf(stderr, "%s: registered DSA\n", PK11_DBG);
1812 +#endif /* DEBUG_SLOT_SELECTION */
1813 +               }
1814 +#endif /* OPENSSL_NO_DSA */
1815 +#ifndef OPENSSL_NO_DH
1816 +       if (pk11_have_dh == CK_TRUE)
1817 +               {
1818 +               if (!ENGINE_set_DH(e, PK11_DH()))
1819 +                       return (0);
1820 +#ifdef DEBUG_SLOT_SELECTION
1821 +               fprintf(stderr, "%s: registered DH\n", PK11_DBG);
1822 +#endif /* DEBUG_SLOT_SELECTION */
1823 +               }
1824 +#endif /* OPENSSL_NO_DH */
1825 +       if (pk11_have_random)
1826 +               {
1827 +               if (!ENGINE_set_RAND(e, &pk11_random))
1828 +                       return (0);
1829 +#ifdef DEBUG_SLOT_SELECTION
1830 +               fprintf(stderr, "%s: registered random\n", PK11_DBG);
1831 +#endif /* DEBUG_SLOT_SELECTION */
1832 +               }
1833 +       if (!ENGINE_set_init_function(e, pk11_init) ||
1834 +           !ENGINE_set_destroy_function(e, pk11_destroy) ||
1835 +           !ENGINE_set_finish_function(e, pk11_finish) ||
1836 +           !ENGINE_set_ctrl_function(e, pk11_ctrl) ||
1837 +           !ENGINE_set_cmd_defns(e, pk11_cmd_defns))
1838 +               return (0);
1841 + * Apache calls OpenSSL function RSA_blinding_on() once during startup
1842 + * which in turn calls bn_mod_exp. Since we do not implement bn_mod_exp
1843 + * here, we wire it back to the OpenSSL software implementation.
1844 + * Since it is used only once, performance is not a concern.
1845 + */
1846 +#ifndef OPENSSL_NO_RSA
1847 +       rsa = RSA_PKCS1_SSLeay();
1848 +       pk11_rsa->rsa_mod_exp = rsa->rsa_mod_exp;
1849 +       pk11_rsa->bn_mod_exp = rsa->bn_mod_exp;
1850 +       if (pk11_have_recover != CK_TRUE)
1851 +               pk11_rsa->rsa_pub_dec = rsa->rsa_pub_dec;
1852 +#endif /* OPENSSL_NO_RSA */
1854 +       /* Ensure the pk11 error handling is set up */
1855 +       ERR_load_pk11_strings();
1857 +       return (1);
1858 +       }
1860 +/* Dynamic engine support is disabled at a higher level for Solaris */
1861 +#ifdef ENGINE_DYNAMIC_SUPPORT
1862 +#error  "dynamic engine not supported"
1863 +static int bind_helper(ENGINE *e, const char *id)
1864 +       {
1865 +       if (id && (strcmp(id, engine_pk11_id) != 0))
1866 +               return (0);
1868 +       if (!bind_pk11(e))
1869 +               return (0);
1871 +       return (1);
1872 +       }
1874 +IMPLEMENT_DYNAMIC_CHECK_FN()
1875 +IMPLEMENT_DYNAMIC_BIND_FN(bind_helper)
1877 +#else
1878 +static ENGINE *engine_pk11(void)
1879 +       {
1880 +       ENGINE *ret = ENGINE_new();
1882 +       if (!ret)
1883 +               return (NULL);
1885 +       if (!bind_pk11(ret))
1886 +               {
1887 +               ENGINE_free(ret);
1888 +               return (NULL);
1889 +               }
1891 +       return (ret);
1892 +       }
1894 +void
1895 +ENGINE_load_pk11(void)
1896 +       {
1897 +       ENGINE *e_pk11 = NULL;
1899 +       /*
1900 +        * Do not use dynamic PKCS#11 library on Solaris due to
1901 +        * security reasons. We will link it in statically.
1902 +        */
1903 +       /* Attempt to load PKCS#11 library */
1904 +       if (!pk11_dso)
1905 +               pk11_dso = DSO_load(NULL, get_PK11_LIBNAME(), NULL, 0);
1907 +       if (pk11_dso == NULL)
1908 +               {
1909 +               PK11err(PK11_F_LOAD, PK11_R_DSO_FAILURE);
1910 +               return;
1911 +               }
1913 +       e_pk11 = engine_pk11();
1914 +       if (!e_pk11)
1915 +               {
1916 +               DSO_free(pk11_dso);
1917 +               pk11_dso = NULL;
1918 +               return;
1919 +               }
1921 +       /*
1922 +        * At this point, the pk11 shared library is either dynamically
1923 +        * loaded or statically linked in. So, initialize the pk11
1924 +        * library before calling ENGINE_set_default since the latter
1925 +        * needs cipher and digest algorithm information
1926 +        */
1927 +       if (!pk11_library_init(e_pk11))
1928 +               {
1929 +               DSO_free(pk11_dso);
1930 +               pk11_dso = NULL;
1931 +               ENGINE_free(e_pk11);
1932 +               return;
1933 +               }
1935 +       ENGINE_add(e_pk11);
1937 +       ENGINE_free(e_pk11);
1938 +       ERR_clear_error();
1939 +       }
1940 +#endif /* ENGINE_DYNAMIC_SUPPORT */
1943 + * These are the static string constants for the DSO file name and
1944 + * the function symbol names to bind to.
1945 + */
1946 +static const char *PK11_LIBNAME = NULL;
1948 +static const char *get_PK11_LIBNAME(void)
1949 +       {
1950 +       if (PK11_LIBNAME)
1951 +               return (PK11_LIBNAME);
1953 +       return (def_PK11_LIBNAME);
1954 +       }
1956 +static void free_PK11_LIBNAME(void)
1957 +       {
1958 +       if (PK11_LIBNAME)
1959 +               OPENSSL_free((void*)PK11_LIBNAME);
1961 +       PK11_LIBNAME = NULL;
1962 +       }
1964 +static long set_PK11_LIBNAME(const char *name)
1965 +       {
1966 +       free_PK11_LIBNAME();
1968 +       return ((PK11_LIBNAME = BUF_strdup(name)) != NULL ? 1 : 0);
1969 +       }
1971 +/* acquire all engine specific mutexes before fork */
1972 +static void pk11_fork_prepare(void)
1973 +       {
1974 +#ifndef NOPTHREADS
1975 +       int i;
1977 +       if (!pk11_library_initialized)
1978 +               return;
1980 +       LOCK_OBJSTORE(OP_RSA);
1981 +       LOCK_OBJSTORE(OP_DSA);
1982 +       LOCK_OBJSTORE(OP_DH);
1983 +       OPENSSL_assert(pthread_mutex_lock(token_lock) == 0);
1984 +       for (i = 0; i < OP_MAX; i++)
1985 +               {
1986 +               OPENSSL_assert(pthread_mutex_lock(session_cache[i].lock) == 0);
1987 +               }
1988 +#endif
1989 +       }
1991 +/* release all engine specific mutexes */
1992 +static void pk11_fork_parent(void)
1993 +       {
1994 +#ifndef NOPTHREADS
1995 +       int i;
1997 +       if (!pk11_library_initialized)
1998 +               return;
2000 +       for (i = OP_MAX - 1; i >= 0; i--)
2001 +               {
2002 +               OPENSSL_assert(pthread_mutex_unlock(session_cache[i].lock) == 0);
2003 +               }
2004 +       UNLOCK_OBJSTORE(OP_DH);
2005 +       UNLOCK_OBJSTORE(OP_DSA);
2006 +       UNLOCK_OBJSTORE(OP_RSA);
2007 +       OPENSSL_assert(pthread_mutex_unlock(token_lock) == 0);
2008 +#endif
2009 +       }
2012 + * same situation as in parent - we need to unlock all locks to make them
2013 + * accessible to all threads.
2014 + */
2015 +static void pk11_fork_child(void)
2016 +       {
2017 +#ifndef NOPTHREADS
2018 +       int i;
2020 +       if (!pk11_library_initialized)
2021 +               return;
2023 +       for (i = OP_MAX - 1; i >= 0; i--)
2024 +               {
2025 +               OPENSSL_assert(pthread_mutex_unlock(session_cache[i].lock) == 0);
2026 +               }
2027 +       UNLOCK_OBJSTORE(OP_DH);
2028 +       UNLOCK_OBJSTORE(OP_DSA);
2029 +       UNLOCK_OBJSTORE(OP_RSA);
2030 +       OPENSSL_assert(pthread_mutex_unlock(token_lock) == 0);
2031 +#endif
2032 +       }
2034 +/* Initialization function for the pk11 engine */
2035 +static int pk11_init(ENGINE *e)
2037 +       return (pk11_library_init(e));
2040 +static CK_C_INITIALIZE_ARGS pk11_init_args =
2041 +       {
2042 +       NULL_PTR,               /* CreateMutex */
2043 +       NULL_PTR,               /* DestroyMutex */
2044 +       NULL_PTR,               /* LockMutex */
2045 +       NULL_PTR,               /* UnlockMutex */
2046 +       CKF_OS_LOCKING_OK,      /* flags */
2047 +       NULL_PTR,               /* pReserved */
2048 +       };
2051 + * Initialization function. Sets up various PKCS#11 library components.
2052 + * It selects a slot based on predefined critiera. In the process, it also
2053 + * count how many ciphers and digests to support. Since the cipher and
2054 + * digest information is needed when setting default engine, this function
2055 + * needs to be called before calling ENGINE_set_default.
2056 + */
2057 +/* ARGSUSED */
2058 +static int pk11_library_init(ENGINE *e)
2059 +       {
2060 +       CK_C_GetFunctionList p;
2061 +       CK_RV rv = CKR_OK;
2062 +       CK_INFO info;
2063 +       CK_ULONG ul_state_len;
2064 +       int any_slot_found;
2065 +       int i;
2066 +#ifndef OPENSSL_SYS_WIN32
2067 +       struct sigaction sigint_act, sigterm_act, sighup_act;
2068 +#endif
2070 +       /*
2071 +        * pk11_library_initialized is set to 0 in pk11_finish() which
2072 +        * is called from ENGINE_finish(). However, if there is still
2073 +        * at least one existing functional reference to the engine
2074 +        * (see engine(3) for more information), pk11_finish() is
2075 +        * skipped. For example, this can happen if an application
2076 +        * forgets to clear one cipher context. In case of a fork()
2077 +        * when the application is finishing the engine so that it can
2078 +        * be reinitialized in the child, forgotten functional
2079 +        * reference causes pk11_library_initialized to stay 1. In
2080 +        * that case we need the PID check so that we properly
2081 +        * initialize the engine again.
2082 +        */
2083 +       if (pk11_library_initialized)
2084 +               {
2085 +               if (pk11_pid == getpid())
2086 +                       {
2087 +                       return (1);
2088 +                       }
2089 +               else
2090 +                       {
2091 +                       global_session = CK_INVALID_HANDLE;
2092 +                       /*
2093 +                        * free the locks first to prevent memory leak in case
2094 +                        * the application calls fork() without finishing the
2095 +                        * engine first.
2096 +                        */
2097 +                       pk11_free_all_locks();
2098 +                       }
2099 +               }
2101 +       if (pk11_dso == NULL)
2102 +               {
2103 +               PK11err(PK11_F_LIBRARY_INIT, PK11_R_DSO_FAILURE);
2104 +               goto err;
2105 +               }
2107 +#ifdef SOLARIS_AES_CTR
2108 +       /*
2109 +        * We must do this before we start working with slots since we need all
2110 +        * NIDs there.
2111 +        */
2112 +       if (pk11_add_aes_ctr_NIDs() == 0)
2113 +               goto err;
2114 +#endif /* SOLARIS_AES_CTR */
2116 +#ifdef SOLARIS_HW_SLOT_SELECTION
2117 +       if (check_hw_mechanisms() == 0)
2118 +               goto err;
2119 +#endif /* SOLARIS_HW_SLOT_SELECTION */
2121 +       /* get the C_GetFunctionList function from the loaded library */
2122 +       p = (CK_C_GetFunctionList)DSO_bind_func(pk11_dso,
2123 +               PK11_GET_FUNCTION_LIST);
2124 +       if (!p)
2125 +               {
2126 +               PK11err(PK11_F_LIBRARY_INIT, PK11_R_DSO_FAILURE);
2127 +               goto err;
2128 +               }
2130 +       /* get the full function list from the loaded library */
2131 +       rv = p(&pFuncList);
2132 +       if (rv != CKR_OK)
2133 +               {
2134 +               PK11err_add_data(PK11_F_LIBRARY_INIT, PK11_R_DSO_FAILURE, rv);
2135 +               goto err;
2136 +               }
2138 +#ifndef OPENSSL_SYS_WIN32
2139 +       /* Not all PKCS#11 library are signal safe! */
2141 +       (void) memset(&sigint_act, 0, sizeof(sigint_act));
2142 +       (void) memset(&sigterm_act, 0, sizeof(sigterm_act));
2143 +       (void) memset(&sighup_act, 0, sizeof(sighup_act));
2144 +       (void) sigaction(SIGINT, NULL, &sigint_act);
2145 +       (void) sigaction(SIGTERM, NULL, &sigterm_act);
2146 +       (void) sigaction(SIGHUP, NULL, &sighup_act);
2147 +#endif
2148 +       rv = pFuncList->C_Initialize((CK_VOID_PTR)&pk11_init_args);
2149 +#ifndef OPENSSL_SYS_WIN32
2150 +       (void) sigaction(SIGINT, &sigint_act, NULL);
2151 +       (void) sigaction(SIGTERM, &sigterm_act, NULL);
2152 +       (void) sigaction(SIGHUP, &sighup_act, NULL);
2153 +#endif
2154 +       if ((rv != CKR_OK) && (rv != CKR_CRYPTOKI_ALREADY_INITIALIZED))
2155 +               {
2156 +               PK11err_add_data(PK11_F_LIBRARY_INIT, PK11_R_INITIALIZE, rv);
2157 +               goto err;
2158 +               }
2160 +       rv = pFuncList->C_GetInfo(&info);
2161 +       if (rv != CKR_OK)
2162 +               {
2163 +               PK11err_add_data(PK11_F_LIBRARY_INIT, PK11_R_GETINFO, rv);
2164 +               goto err;
2165 +               }
2167 +       if (pk11_choose_slots(&any_slot_found) == 0)
2168 +               goto err;
2170 +       /*
2171 +        * The library we use, set in def_PK11_LIBNAME, may not offer any
2172 +        * slot(s). In that case, we must not proceed but we must not return an
2173 +        * error. The reason is that applications that try to set up the PKCS#11
2174 +        * engine don't exit on error during the engine initialization just
2175 +        * because no slot was present.
2176 +        */
2177 +       if (any_slot_found == 0)
2178 +               return (1);
2180 +       if (global_session == CK_INVALID_HANDLE)
2181 +               {
2182 +               /* Open the global_session for the new process */
2183 +               rv = pFuncList->C_OpenSession(SLOTID, CKF_SERIAL_SESSION,
2184 +                       NULL_PTR, NULL_PTR, &global_session);
2185 +               if (rv != CKR_OK)
2186 +                       {
2187 +                       PK11err_add_data(PK11_F_LIBRARY_INIT,
2188 +                           PK11_R_OPENSESSION, rv);
2189 +                       goto err;
2190 +                       }
2191 +               }
2193 +       /*
2194 +        * Disable digest if C_GetOperationState is not supported since
2195 +        * this function is required by OpenSSL digest copy function
2196 +        */
2197 +       /* Keyper fails to return CKR_FUNCTION_NOT_SUPPORTED */
2198 +       if (pFuncList->C_GetOperationState(global_session, NULL, &ul_state_len)
2199 +                       != CKR_OK) {
2200 +#ifdef DEBUG_SLOT_SELECTION
2201 +               fprintf(stderr, "%s: C_GetOperationState() not supported, "
2202 +                   "setting digest_count to 0\n", PK11_DBG);
2203 +#endif /* DEBUG_SLOT_SELECTION */
2204 +               digest_count = 0;
2205 +       }
2207 +       pk11_library_initialized = TRUE;
2208 +       pk11_pid = getpid();
2209 +       /*
2210 +        * if initialization of the locks fails pk11_init_all_locks()
2211 +        * will do the cleanup.
2212 +        */
2213 +       if (!pk11_init_all_locks())
2214 +               goto err;
2215 +       for (i = 0; i < OP_MAX; i++)
2216 +               session_cache[i].head = NULL;
2217 +       /*
2218 +        * initialize active lists. We only use active lists
2219 +        * for asymmetric ciphers.
2220 +        */
2221 +       for (i = 0; i < OP_MAX; i++)
2222 +               active_list[i] = NULL;
2224 +#ifndef NOPTHREADS
2225 +       if (!pk11_atfork_initialized)
2226 +               {
2227 +               if (pthread_atfork(pk11_fork_prepare, pk11_fork_parent,
2228 +                   pk11_fork_child) != 0)
2229 +                       {
2230 +                       PK11err(PK11_F_LIBRARY_INIT, PK11_R_ATFORK_FAILED);
2231 +                       goto err;
2232 +                       }
2233 +               pk11_atfork_initialized = TRUE;
2234 +               }
2235 +#endif
2237 +       return (1);
2239 +err:
2240 +       return (0);
2241 +       }
2243 +/* Destructor (complements the "ENGINE_pk11()" constructor) */
2244 +/* ARGSUSED */
2245 +static int pk11_destroy(ENGINE *e)
2246 +       {
2247 +       free_PK11_LIBNAME();
2248 +       ERR_unload_pk11_strings();
2249 +       if (pk11_pin) {
2250 +               memset(pk11_pin, 0, strlen(pk11_pin));
2251 +               OPENSSL_free((void*)pk11_pin);
2252 +       }
2253 +       pk11_pin = NULL;
2254 +       return (1);
2255 +       }
2258 + * Termination function to clean up the session, the token, and the pk11
2259 + * library.
2260 + */
2261 +/* ARGSUSED */
2262 +static int pk11_finish(ENGINE *e)
2263 +       {
2264 +       int i;
2266 +       if (pk11_pin) {
2267 +               memset(pk11_pin, 0, strlen(pk11_pin));
2268 +               OPENSSL_free((void*)pk11_pin);
2269 +       }
2270 +       pk11_pin = NULL;
2272 +       if (pk11_dso == NULL)
2273 +               {
2274 +               PK11err(PK11_F_FINISH, PK11_R_NOT_LOADED);
2275 +               goto err;
2276 +               }
2278 +       OPENSSL_assert(pFuncList != NULL);
2280 +       if (pk11_free_all_sessions() == 0)
2281 +               goto err;
2283 +       /* free all active lists */
2284 +       for (i = 0; i < OP_MAX; i++)
2285 +               pk11_free_active_list(i);
2287 +       pFuncList->C_CloseSession(global_session);
2288 +       global_session = CK_INVALID_HANDLE;
2290 +       /*
2291 +        * Since we are part of a library (libcrypto.so), calling this function
2292 +        * may have side-effects.
2293 +        */
2294 +#if 0
2295 +       pFuncList->C_Finalize(NULL);
2296 +#endif
2298 +       if (!DSO_free(pk11_dso))
2299 +               {
2300 +               PK11err(PK11_F_FINISH, PK11_R_DSO_FAILURE);
2301 +               goto err;
2302 +               }
2303 +       pk11_dso = NULL;
2304 +       pFuncList = NULL;
2305 +       pk11_library_initialized = FALSE;
2306 +       pk11_pid = 0;
2307 +       /*
2308 +        * There is no way how to unregister atfork handlers (other than
2309 +        * unloading the library) so we just free the locks. For this reason
2310 +        * the atfork handlers check if the engine is initialized and bail out
2311 +        * immediately if not. This is necessary in case a process finishes
2312 +        * the engine before calling fork().
2313 +        */
2314 +       pk11_free_all_locks();
2316 +       return (1);
2318 +err:
2319 +       return (0);
2320 +       }
2322 +/* Standard engine interface function to set the dynamic library path */
2323 +/* ARGSUSED */
2324 +static int pk11_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void))
2325 +       {
2326 +       int initialized = ((pk11_dso == NULL) ? 0 : 1);
2328 +       switch (cmd)
2329 +               {
2330 +       case PK11_CMD_SO_PATH:
2331 +               if (p == NULL)
2332 +                       {
2333 +                       PK11err(PK11_F_CTRL, ERR_R_PASSED_NULL_PARAMETER);
2334 +                       return (0);
2335 +                       }
2337 +               if (initialized)
2338 +                       {
2339 +                       PK11err(PK11_F_CTRL, PK11_R_ALREADY_LOADED);
2340 +                       return (0);
2341 +                       }
2343 +               return (set_PK11_LIBNAME((const char *)p));
2344 +       case PK11_CMD_PIN:
2345 +               if (pk11_pin) {
2346 +                       memset(pk11_pin, 0, strlen(pk11_pin));
2347 +                       OPENSSL_free((void*)pk11_pin);
2348 +               }
2349 +               pk11_pin = NULL;
2351 +               if (p == NULL)
2352 +                       {
2353 +                       PK11err(PK11_F_CTRL, ERR_R_PASSED_NULL_PARAMETER);
2354 +                       return (0);
2355 +                       }
2357 +               pk11_pin = BUF_strdup(p);
2358 +               if (pk11_pin == NULL)
2359 +                       {
2360 +                       PK11err(PK11_F_GET_SESSION, PK11_R_MALLOC_FAILURE);
2361 +                       return (0);
2362 +                       }
2363 +               return (1);
2364 +       case PK11_CMD_SLOT:
2365 +               SLOTID = (CK_SLOT_ID)i;
2366 +#ifdef DEBUG_SLOT_SELECTION
2367 +               fprintf(stderr, "%s: slot set\n", PK11_DBG);
2368 +#endif
2369 +               return (1);
2370 +       default:
2371 +               break;
2372 +               }
2374 +       PK11err(PK11_F_CTRL, PK11_R_CTRL_COMMAND_NOT_IMPLEMENTED);
2376 +       return (0);
2377 +       }
2380 +/* Required function by the engine random interface. It does nothing here */
2381 +static void pk11_rand_cleanup(void)
2382 +       {
2383 +       return;
2384 +       }
2386 +/* ARGSUSED */
2387 +static void pk11_rand_add(const void *buf, int num, double add)
2388 +       {
2389 +       PK11_SESSION *sp;
2391 +       if ((sp = pk11_get_session(OP_RAND)) == NULL)
2392 +               return;
2394 +       /*
2395 +        * Ignore any errors (e.g. CKR_RANDOM_SEED_NOT_SUPPORTED) since
2396 +        * the calling functions do not care anyway
2397 +        */
2398 +       pFuncList->C_SeedRandom(sp->session, (unsigned char *) buf, num);
2399 +       pk11_return_session(sp, OP_RAND);
2401 +       return;
2402 +       }
2404 +static void pk11_rand_seed(const void *buf, int num)
2405 +       {
2406 +       pk11_rand_add(buf, num, 0);
2407 +       }
2409 +static int pk11_rand_bytes(unsigned char *buf, int num)
2410 +       {
2411 +       CK_RV rv;
2412 +       PK11_SESSION *sp;
2414 +       if ((sp = pk11_get_session(OP_RAND)) == NULL)
2415 +               return (0);
2417 +       rv = pFuncList->C_GenerateRandom(sp->session, buf, num);
2418 +       if (rv != CKR_OK)
2419 +               {
2420 +               PK11err_add_data(PK11_F_RAND_BYTES, PK11_R_GENERATERANDOM, rv);
2421 +               pk11_return_session(sp, OP_RAND);
2422 +               return (0);
2423 +               }
2425 +       pk11_return_session(sp, OP_RAND);
2426 +       return (1);
2427 +       }
2429 +/* Required function by the engine random interface. It does nothing here */
2430 +static int pk11_rand_status(void)
2431 +       {
2432 +       return (1);
2433 +       }
2435 +/* Free all BIGNUM structures from PK11_SESSION. */
2436 +static void pk11_free_nums(PK11_SESSION *sp, PK11_OPTYPE optype)
2437 +       {
2438 +       switch (optype)
2439 +               {
2440 +#ifndef        OPENSSL_NO_RSA
2441 +               case OP_RSA:
2442 +                       if (sp->opdata_rsa_n_num != NULL)
2443 +                               {
2444 +                               BN_free(sp->opdata_rsa_n_num);
2445 +                               sp->opdata_rsa_n_num = NULL;
2446 +                               }
2447 +                       if (sp->opdata_rsa_e_num != NULL)
2448 +                               {
2449 +                               BN_free(sp->opdata_rsa_e_num);
2450 +                               sp->opdata_rsa_e_num = NULL;
2451 +                               }
2452 +                       if (sp->opdata_rsa_pn_num != NULL)
2453 +                               {
2454 +                               BN_free(sp->opdata_rsa_pn_num);
2455 +                               sp->opdata_rsa_pn_num = NULL;
2456 +                               }
2457 +                       if (sp->opdata_rsa_pe_num != NULL)
2458 +                               {
2459 +                               BN_free(sp->opdata_rsa_pe_num);
2460 +                               sp->opdata_rsa_pe_num = NULL;
2461 +                               }
2462 +                       if (sp->opdata_rsa_d_num != NULL)
2463 +                               {
2464 +                               BN_free(sp->opdata_rsa_d_num);
2465 +                               sp->opdata_rsa_d_num = NULL;
2466 +                               }
2467 +                       break;
2468 +#endif
2469 +#ifndef        OPENSSL_NO_DSA
2470 +               case OP_DSA:
2471 +                       if (sp->opdata_dsa_pub_num != NULL)
2472 +                               {
2473 +                               BN_free(sp->opdata_dsa_pub_num);
2474 +                               sp->opdata_dsa_pub_num = NULL;
2475 +                               }
2476 +                       if (sp->opdata_dsa_priv_num != NULL)
2477 +                               {
2478 +                               BN_free(sp->opdata_dsa_priv_num);
2479 +                               sp->opdata_dsa_priv_num = NULL;
2480 +                               }
2481 +                       break;
2482 +#endif
2483 +#ifndef        OPENSSL_NO_DH
2484 +               case OP_DH:
2485 +                       if (sp->opdata_dh_priv_num != NULL)
2486 +                               {
2487 +                               BN_free(sp->opdata_dh_priv_num);
2488 +                               sp->opdata_dh_priv_num = NULL;
2489 +                               }
2490 +                       break;
2491 +#endif
2492 +               default:
2493 +                       break;
2494 +               }
2495 +       }
2498 + * Get new PK11_SESSION structure ready for use. Every process must have
2499 + * its own freelist of PK11_SESSION structures so handle fork() here
2500 + * by destroying the old and creating new freelist.
2501 + * The returned PK11_SESSION structure is disconnected from the freelist.
2502 + */
2503 +PK11_SESSION *
2504 +pk11_get_session(PK11_OPTYPE optype)
2505 +       {
2506 +       PK11_SESSION *sp = NULL, *sp1, *freelist;
2507 +#ifndef NOPTHREADS
2508 +       pthread_mutex_t *freelist_lock = NULL;
2509 +#endif
2510 +       static pid_t pid = 0;
2511 +       pid_t new_pid;
2512 +       CK_RV rv;
2514 +       switch (optype)
2515 +               {
2516 +               case OP_RSA:
2517 +               case OP_DSA:
2518 +               case OP_DH:
2519 +               case OP_RAND:
2520 +               case OP_DIGEST:
2521 +               case OP_CIPHER:
2522 +#ifndef NOPTHREADS
2523 +                       freelist_lock = session_cache[optype].lock;
2524 +#endif
2525 +                       break;
2526 +               default:
2527 +                       PK11err(PK11_F_GET_SESSION,
2528 +                               PK11_R_INVALID_OPERATION_TYPE);
2529 +                       return (NULL);
2530 +               }
2531 +#ifndef NOPTHREADS
2532 +       OPENSSL_assert(pthread_mutex_lock(freelist_lock) == 0);
2533 +#else
2534 +       CRYPTO_w_lock(CRYPTO_LOCK_PK11_ENGINE);
2535 +#endif
2537 +       /*
2538 +        * Will use it to find out if we forked. We cannot use the PID field in
2539 +        * the session structure because we could get a newly allocated session
2540 +        * here, with no PID information.
2541 +        */
2542 +       if (pid == 0)
2543 +               pid = getpid();
2545 +       freelist = session_cache[optype].head;
2546 +       sp = freelist;
2548 +       /*
2549 +        * If the free list is empty, allocate new unitialized (filled
2550 +        * with zeroes) PK11_SESSION structure otherwise return first
2551 +        * structure from the freelist.
2552 +        */
2553 +       if (sp == NULL)
2554 +               {
2555 +               if ((sp = OPENSSL_malloc(sizeof (PK11_SESSION))) == NULL)
2556 +                       {
2557 +                       PK11err(PK11_F_GET_SESSION,
2558 +                               PK11_R_MALLOC_FAILURE);
2559 +                       goto err;
2560 +                       }
2561 +               (void) memset(sp, 0, sizeof (PK11_SESSION));
2563 +               /*
2564 +                * It is a new session so it will look like a cache miss to the
2565 +                * code below. So, we must not try to to destroy its members so
2566 +                * mark them as unused.
2567 +                */
2568 +               sp->opdata_rsa_priv_key = CK_INVALID_HANDLE;
2569 +               sp->opdata_rsa_pub_key = CK_INVALID_HANDLE;
2570 +               }
2571 +       else
2572 +               {
2573 +               freelist = sp->next;
2574 +               }
2576 +       /*
2577 +        * Check whether we have forked. In that case, we must get rid of all
2578 +        * inherited sessions and start allocating new ones.
2579 +        */
2580 +       if (pid != (new_pid = getpid()))
2581 +               {
2582 +               pid = new_pid;
2584 +               /*
2585 +                * We are a new process and thus need to free any inherited
2586 +                * PK11_SESSION objects aside from the first session (sp) which
2587 +                * is the only PK11_SESSION structure we will reuse (for the
2588 +                * head of the list).
2589 +                */
2590 +               while ((sp1 = freelist) != NULL)
2591 +                       {
2592 +                       freelist = sp1->next;
2593 +                       /*
2594 +                        * NOTE: we do not want to call pk11_free_all_sessions()
2595 +                        * here because it would close underlying PKCS#11
2596 +                        * sessions and destroy all objects.
2597 +                        */
2598 +                       pk11_free_nums(sp1, optype);
2599 +                       OPENSSL_free(sp1);
2600 +                       }
2602 +               /* we have to free the active list as well. */
2603 +               pk11_free_active_list(optype);
2605 +               /* Initialize the process */
2606 +               rv = pFuncList->C_Initialize((CK_VOID_PTR)&pk11_init_args);
2607 +               if ((rv != CKR_OK) && (rv != CKR_CRYPTOKI_ALREADY_INITIALIZED))
2608 +                       {
2609 +                       PK11err_add_data(PK11_F_GET_SESSION, PK11_R_INITIALIZE,
2610 +                           rv);
2611 +                       OPENSSL_free(sp);
2612 +                       sp = NULL;
2613 +                       goto err;
2614 +                       }
2616 +               /*
2617 +                * Choose slot here since the slot table is different on this
2618 +                * process. If we are here then we must have found at least one
2619 +                * usable slot before so we don't need to check any_slot_found.
2620 +                * See pk11_library_init()'s usage of this function for more
2621 +                * information.
2622 +                */
2623 +#ifdef SOLARIS_HW_SLOT_SELECTION
2624 +               if (check_hw_mechanisms() == 0)
2625 +                       goto err;
2626 +#endif /* SOLARIS_HW_SLOT_SELECTION */
2627 +               if (pk11_choose_slots(NULL) == 0)
2628 +                       goto err;
2630 +               /* Open the global_session for the new process */
2631 +               rv = pFuncList->C_OpenSession(SLOTID, CKF_SERIAL_SESSION,
2632 +                       NULL_PTR, NULL_PTR, &global_session);
2633 +               if (rv != CKR_OK)
2634 +                       {
2635 +                       PK11err_add_data(PK11_F_GET_SESSION, PK11_R_OPENSESSION,
2636 +                           rv);
2637 +                       OPENSSL_free(sp);
2638 +                       sp = NULL;
2639 +                       goto err;
2640 +                       }
2642 +               /*
2643 +                * It is an inherited session from our parent so it needs
2644 +                * re-initialization.
2645 +                */
2646 +               if (pk11_setup_session(sp, optype) == 0)
2647 +                       {
2648 +                       OPENSSL_free(sp);
2649 +                       sp = NULL;
2650 +                       goto err;
2651 +                       }
2652 +               if (pk11_token_relogin(sp->session) == 0) 
2653 +                       {
2654 +                       /*
2655 +                        * We will keep the session in the cache list and let
2656 +                        * the caller cope with the situation.
2657 +                        */
2658 +                       freelist = sp;
2659 +                       sp = NULL;
2660 +                       goto err;
2661 +                       }
2662 +               }
2664 +       if (sp->pid == 0)
2665 +               {
2666 +               /* It is a new session and needs initialization. */
2667 +               if (pk11_setup_session(sp, optype) == 0)
2668 +                       {
2669 +                       OPENSSL_free(sp);
2670 +                       sp = NULL;
2671 +                       }
2672 +               }
2674 +       /* set new head for the list of PK11_SESSION objects */
2675 +       session_cache[optype].head = freelist;
2677 +err:
2678 +       if (sp != NULL)
2679 +               sp->next = NULL;
2681 +#ifndef NOPTHREADS
2682 +       OPENSSL_assert(pthread_mutex_unlock(freelist_lock) == 0);
2683 +#else
2684 +       CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
2685 +#endif
2687 +       return (sp);
2688 +       }
2691 +void
2692 +pk11_return_session(PK11_SESSION *sp, PK11_OPTYPE optype)
2693 +       {
2694 +#ifndef NOPTHREADS
2695 +       pthread_mutex_t *freelist_lock;
2696 +#endif
2697 +       PK11_SESSION *freelist;
2699 +       /*
2700 +        * If this is a session from the parent it will be taken care of and
2701 +        * freed in pk11_get_session() as part of the post-fork clean up the
2702 +        * next time we will ask for a new session.
2703 +        */
2704 +       if (sp == NULL || sp->pid != getpid())
2705 +               return;
2707 +       switch (optype)
2708 +               {
2709 +               case OP_RSA:
2710 +               case OP_DSA:
2711 +               case OP_DH:
2712 +               case OP_RAND:
2713 +               case OP_DIGEST:
2714 +               case OP_CIPHER:
2715 +#ifndef NOPTHREADS
2716 +                       freelist_lock = session_cache[optype].lock;
2717 +#endif
2718 +                       break;
2719 +               default:
2720 +                       PK11err(PK11_F_RETURN_SESSION,
2721 +                               PK11_R_INVALID_OPERATION_TYPE);
2722 +                       return;
2723 +               }
2725 +#ifndef NOPTHREADS
2726 +       OPENSSL_assert(pthread_mutex_lock(freelist_lock) == 0);
2727 +#else
2728 +       CRYPTO_w_lock(CRYPTO_LOCK_PK11_ENGINE);
2729 +#endif
2730 +       freelist = session_cache[optype].head;
2731 +       sp->next = freelist;
2732 +       session_cache[optype].head = sp;
2733 +#ifndef NOPTHREADS
2734 +       OPENSSL_assert(pthread_mutex_unlock(freelist_lock) == 0);
2735 +#else
2736 +       CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
2737 +#endif
2738 +       }
2741 +/* Destroy all objects. This function is called when the engine is finished */
2742 +static int pk11_free_all_sessions()
2743 +       {
2744 +       int ret = 1;
2745 +       int type;
2747 +#ifndef OPENSSL_NO_RSA
2748 +       (void) pk11_destroy_rsa_key_objects(NULL);
2749 +#endif /* OPENSSL_NO_RSA */
2750 +#ifndef OPENSSL_NO_DSA
2751 +       (void) pk11_destroy_dsa_key_objects(NULL);
2752 +#endif /* OPENSSL_NO_DSA */
2753 +#ifndef OPENSSL_NO_DH
2754 +       (void) pk11_destroy_dh_key_objects(NULL);
2755 +#endif /* OPENSSL_NO_DH */
2756 +       (void) pk11_destroy_cipher_key_objects(NULL);
2758 +       /*
2759 +        * We try to release as much as we can but any error means that we will
2760 +        * return 0 on exit.
2761 +        */
2762 +       for (type = 0; type < OP_MAX; type++)
2763 +               {
2764 +               if (pk11_free_session_list(type) == 0)
2765 +                       ret = 0;
2766 +               }
2768 +       return (ret);
2769 +       }
2772 + * Destroy session structures from the linked list specified. Free as many
2773 + * sessions as possible but any failure in C_CloseSession() means that we
2774 + * return an error on return.
2775 + */
2776 +static int pk11_free_session_list(PK11_OPTYPE optype)
2777 +       {
2778 +       CK_RV rv;
2779 +       PK11_SESSION *sp = NULL;
2780 +       PK11_SESSION *freelist = NULL;
2781 +       pid_t mypid = getpid();
2782 +#ifndef NOPTHREADS
2783 +       pthread_mutex_t *freelist_lock;
2784 +#endif
2785 +       int ret = 1;
2787 +       switch (optype)
2788 +               {
2789 +               case OP_RSA:
2790 +               case OP_DSA:
2791 +               case OP_DH:
2792 +               case OP_RAND:
2793 +               case OP_DIGEST:
2794 +               case OP_CIPHER:
2795 +#ifndef NOPTHREADS
2796 +                       freelist_lock = session_cache[optype].lock;
2797 +#endif
2798 +                       break;
2799 +               default:
2800 +                       PK11err(PK11_F_FREE_ALL_SESSIONS,
2801 +                               PK11_R_INVALID_OPERATION_TYPE);
2802 +                       return (0);
2803 +               }
2805 +#ifndef NOPTHREADS
2806 +       OPENSSL_assert(pthread_mutex_lock(freelist_lock) == 0);
2807 +#else
2808 +       CRYPTO_w_lock(CRYPTO_LOCK_PK11_ENGINE);
2809 +#endif
2810 +       freelist = session_cache[optype].head;
2811 +       while ((sp = freelist) != NULL)
2812 +               {
2813 +               if (sp->session != CK_INVALID_HANDLE && sp->pid == mypid)
2814 +                       {
2815 +                       rv = pFuncList->C_CloseSession(sp->session);
2816 +                       if (rv != CKR_OK)
2817 +                               {
2818 +                               PK11err_add_data(PK11_F_FREE_ALL_SESSIONS,
2819 +                                       PK11_R_CLOSESESSION, rv);
2820 +                               ret = 0;
2821 +                               }
2822 +                       }
2823 +               freelist = sp->next;
2824 +               pk11_free_nums(sp, optype);
2825 +               OPENSSL_free(sp);
2826 +               }
2828 +#ifndef NOPTHREADS
2829 +       OPENSSL_assert(pthread_mutex_unlock(freelist_lock) == 0);
2830 +#else
2831 +       CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
2832 +#endif
2833 +       return (ret);
2834 +       }
2837 +static int
2838 +pk11_setup_session(PK11_SESSION *sp, PK11_OPTYPE optype)
2839 +       {
2840 +       CK_RV rv;
2841 +       CK_SLOT_ID myslot;
2843 +       switch (optype)
2844 +               {
2845 +               case OP_RSA:
2846 +               case OP_DSA:
2847 +               case OP_DH:
2848 +                       myslot = pubkey_SLOTID;
2849 +                       break;
2850 +               case OP_RAND:
2851 +                       myslot = rand_SLOTID;
2852 +                       break;
2853 +               case OP_DIGEST:
2854 +               case OP_CIPHER:
2855 +                       myslot = SLOTID;
2856 +                       break;
2857 +               default:
2858 +                       PK11err(PK11_F_SETUP_SESSION,
2859 +                           PK11_R_INVALID_OPERATION_TYPE);
2860 +                       return (0);
2861 +               }
2863 +       sp->session = CK_INVALID_HANDLE;
2864 +#ifdef DEBUG_SLOT_SELECTION
2865 +       fprintf(stderr, "%s: myslot=%d optype=%d\n", PK11_DBG, myslot, optype);
2866 +#endif /* DEBUG_SLOT_SELECTION */
2867 +       rv = pFuncList->C_OpenSession(myslot, CKF_SERIAL_SESSION,
2868 +               NULL_PTR, NULL_PTR, &sp->session);
2869 +       if (rv == CKR_CRYPTOKI_NOT_INITIALIZED)
2870 +               {
2871 +               /*
2872 +                * We are probably a child process so force the
2873 +                * reinitialize of the session
2874 +                */
2875 +               pk11_library_initialized = FALSE;
2876 +               if (!pk11_library_init(NULL))
2877 +                       return (0);
2878 +               rv = pFuncList->C_OpenSession(myslot, CKF_SERIAL_SESSION,
2879 +                       NULL_PTR, NULL_PTR, &sp->session);
2880 +               }
2881 +       if (rv != CKR_OK)
2882 +               {
2883 +               PK11err_add_data(PK11_F_SETUP_SESSION, PK11_R_OPENSESSION, rv);
2884 +               return (0);
2885 +               }
2887 +       sp->pid = getpid();
2889 +       switch (optype)
2890 +               {
2891 +#ifndef OPENSSL_NO_RSA
2892 +               case OP_RSA:
2893 +                       sp->opdata_rsa_pub_key = CK_INVALID_HANDLE;
2894 +                       sp->opdata_rsa_priv_key = CK_INVALID_HANDLE;
2895 +                       sp->opdata_rsa_pub = NULL;
2896 +                       sp->opdata_rsa_n_num = NULL;
2897 +                       sp->opdata_rsa_e_num = NULL;
2898 +                       sp->opdata_rsa_priv = NULL;
2899 +                       sp->opdata_rsa_pn_num = NULL;
2900 +                       sp->opdata_rsa_pe_num = NULL;
2901 +                       sp->opdata_rsa_d_num = NULL;
2902 +                       break;
2903 +#endif /* OPENSSL_NO_RSA */
2904 +#ifndef OPENSSL_NO_DSA
2905 +               case OP_DSA:
2906 +                       sp->opdata_dsa_pub_key = CK_INVALID_HANDLE;
2907 +                       sp->opdata_dsa_priv_key = CK_INVALID_HANDLE;
2908 +                       sp->opdata_dsa_pub = NULL;
2909 +                       sp->opdata_dsa_pub_num = NULL;
2910 +                       sp->opdata_dsa_priv = NULL;
2911 +                       sp->opdata_dsa_priv_num = NULL;
2912 +                       break;
2913 +#endif /* OPENSSL_NO_DSA */
2914 +#ifndef OPENSSL_NO_DH
2915 +               case OP_DH:
2916 +                       sp->opdata_dh_key = CK_INVALID_HANDLE;
2917 +                       sp->opdata_dh = NULL;
2918 +                       sp->opdata_dh_priv_num = NULL;
2919 +                       break;
2920 +#endif /* OPENSSL_NO_DH */
2921 +               case OP_CIPHER:
2922 +                       sp->opdata_cipher_key = CK_INVALID_HANDLE;
2923 +                       sp->opdata_encrypt = -1;
2924 +                       break;
2925 +               default:
2926 +                       break;
2927 +               }
2929 +       /*
2930 +        * We always initialize the session as containing a non-persistent
2931 +        * object. The key load functions set it to persistent if that is so.
2932 +        */
2933 +       sp->pub_persistent = CK_FALSE;
2934 +       sp->priv_persistent = CK_FALSE;
2935 +       return (1);
2936 +       }
2938 +#ifndef OPENSSL_NO_RSA
2939 +/* Destroy RSA public key from single session. */
2940 +int
2941 +pk11_destroy_rsa_object_pub(PK11_SESSION *sp, CK_BBOOL uselock)
2942 +       {
2943 +       int ret = 0;
2945 +       if (sp->opdata_rsa_pub_key != CK_INVALID_HANDLE)
2946 +               {
2947 +               TRY_OBJ_DESTROY(sp, sp->opdata_rsa_pub_key,
2948 +                   ret, uselock, OP_RSA, CK_FALSE);
2949 +               sp->opdata_rsa_pub_key = CK_INVALID_HANDLE;
2950 +               sp->opdata_rsa_pub = NULL;
2951 +               if (sp->opdata_rsa_n_num != NULL)
2952 +                       {
2953 +                       BN_free(sp->opdata_rsa_n_num);
2954 +                       sp->opdata_rsa_n_num = NULL;
2955 +                       }
2956 +               if (sp->opdata_rsa_e_num != NULL)
2957 +                       {
2958 +                       BN_free(sp->opdata_rsa_e_num);
2959 +                       sp->opdata_rsa_e_num = NULL;
2960 +                       }
2961 +               }
2963 +       return (ret);
2964 +       }
2966 +/* Destroy RSA private key from single session. */
2967 +int
2968 +pk11_destroy_rsa_object_priv(PK11_SESSION *sp, CK_BBOOL uselock)
2969 +       {
2970 +       int ret = 0;
2972 +       if (sp->opdata_rsa_priv_key != CK_INVALID_HANDLE)
2973 +               {
2974 +               TRY_OBJ_DESTROY(sp, sp->opdata_rsa_priv_key,
2975 +                   ret, uselock, OP_RSA, CK_TRUE);
2976 +               sp->opdata_rsa_priv_key = CK_INVALID_HANDLE;
2977 +               sp->opdata_rsa_priv = NULL;
2978 +               if (sp->opdata_rsa_d_num != NULL)
2979 +                       {
2980 +                       BN_free(sp->opdata_rsa_d_num);
2981 +                       sp->opdata_rsa_d_num = NULL;
2982 +                       }
2984 +               /*
2985 +                * For the RSA key by reference code, public components 'n'/'e'
2986 +                * are the key components we use to check for the cache hit. We
2987 +                * must free those as well.
2988 +                */
2989 +               if (sp->opdata_rsa_pn_num != NULL)
2990 +                       {
2991 +                       BN_free(sp->opdata_rsa_pn_num);
2992 +                       sp->opdata_rsa_pn_num = NULL;
2993 +                       }
2994 +               if (sp->opdata_rsa_pe_num != NULL)
2995 +                       {
2996 +                       BN_free(sp->opdata_rsa_pe_num);
2997 +                       sp->opdata_rsa_pe_num = NULL;
2998 +                       }
2999 +               }
3001 +       return (ret);
3002 +       }
3005 + * Destroy RSA key object wrapper. If session is NULL, try to destroy all
3006 + * objects in the free list.
3007 + */
3008 +int
3009 +pk11_destroy_rsa_key_objects(PK11_SESSION *session)
3010 +       {
3011 +       int ret = 1;
3012 +       PK11_SESSION *sp = NULL;
3013 +       PK11_SESSION *local_free_session;
3014 +       CK_BBOOL uselock = TRUE;
3016 +       if (session != NULL)
3017 +               local_free_session = session;
3018 +       else
3019 +               {
3020 +#ifndef NOPTHREADS
3021 +               OPENSSL_assert(pthread_mutex_lock(session_cache[OP_RSA].lock) == 0);
3022 +#else
3023 +               CRYPTO_w_lock(CRYPTO_LOCK_PK11_ENGINE);
3024 +#endif
3025 +               local_free_session = session_cache[OP_RSA].head;
3026 +               uselock = FALSE;
3027 +               }
3029 +       /*
3030 +        * go through the list of sessions and delete key objects
3031 +        */
3032 +       while ((sp = local_free_session) != NULL)
3033 +               {
3034 +               local_free_session = sp->next;
3036 +               /*
3037 +                * Do not terminate list traversal if one of the
3038 +                * destroy operations fails.
3039 +                */
3040 +               if (pk11_destroy_rsa_object_pub(sp, uselock) == 0)
3041 +                       {
3042 +                       ret = 0;
3043 +                       continue;
3044 +                       }
3045 +               if (pk11_destroy_rsa_object_priv(sp, uselock) == 0)
3046 +                       {
3047 +                       ret = 0;
3048 +                       continue;
3049 +                       }
3050 +               }
3052 +#ifndef NOPTHREADS
3053 +       if (session == NULL)
3054 +               OPENSSL_assert(pthread_mutex_unlock(session_cache[OP_RSA].lock) == 0);
3055 +#else
3056 +       if (session == NULL)
3057 +               CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
3058 +#endif
3060 +       return (ret);
3061 +       }
3062 +#endif /* OPENSSL_NO_RSA */
3064 +#ifndef OPENSSL_NO_DSA
3065 +/* Destroy DSA public key from single session. */
3066 +int
3067 +pk11_destroy_dsa_object_pub(PK11_SESSION *sp, CK_BBOOL uselock)
3068 +       {
3069 +       int ret = 0;
3071 +       if (sp->opdata_dsa_pub_key != CK_INVALID_HANDLE)
3072 +               {
3073 +               TRY_OBJ_DESTROY(sp, sp->opdata_dsa_pub_key,
3074 +                   ret, uselock, OP_DSA, CK_FALSE);
3075 +               sp->opdata_dsa_pub_key = CK_INVALID_HANDLE;
3076 +               sp->opdata_dsa_pub = NULL;
3077 +               if (sp->opdata_dsa_pub_num != NULL)
3078 +                       {
3079 +                       BN_free(sp->opdata_dsa_pub_num);
3080 +                       sp->opdata_dsa_pub_num = NULL;
3081 +                       }
3082 +               }
3084 +       return (ret);
3085 +       }
3087 +/* Destroy DSA private key from single session. */
3088 +int
3089 +pk11_destroy_dsa_object_priv(PK11_SESSION *sp, CK_BBOOL uselock)
3090 +       {
3091 +       int ret = 0;
3093 +       if (sp->opdata_dsa_priv_key != CK_INVALID_HANDLE)
3094 +               {
3095 +               TRY_OBJ_DESTROY(sp, sp->opdata_dsa_priv_key,
3096 +                   ret, uselock, OP_DSA, CK_TRUE);
3097 +               sp->opdata_dsa_priv_key = CK_INVALID_HANDLE;
3098 +               sp->opdata_dsa_priv = NULL;
3099 +               if (sp->opdata_dsa_priv_num != NULL)
3100 +                       {
3101 +                       BN_free(sp->opdata_dsa_priv_num);
3102 +                       sp->opdata_dsa_priv_num = NULL;
3103 +                       }
3104 +               }
3106 +       return (ret);
3107 +       }
3110 + * Destroy DSA key object wrapper. If session is NULL, try to destroy all
3111 + * objects in the free list.
3112 + */
3113 +int
3114 +pk11_destroy_dsa_key_objects(PK11_SESSION *session)
3115 +       {
3116 +       int ret = 1;
3117 +       PK11_SESSION *sp = NULL;
3118 +       PK11_SESSION *local_free_session;
3119 +       CK_BBOOL uselock = TRUE;
3121 +       if (session != NULL)
3122 +               local_free_session = session;
3123 +       else
3124 +               {
3125 +#ifndef NOPTHREADS
3126 +               OPENSSL_assert(pthread_mutex_lock(session_cache[OP_DSA].lock) == 0);
3127 +#else
3128 +               CRYPTO_w_lock(CRYPTO_LOCK_PK11_ENGINE);
3129 +#endif
3130 +               local_free_session = session_cache[OP_DSA].head;
3131 +               uselock = FALSE;
3132 +               }
3134 +       /*
3135 +        * go through the list of sessions and delete key objects
3136 +        */
3137 +       while ((sp = local_free_session) != NULL)
3138 +               {
3139 +               local_free_session = sp->next;
3141 +               /*
3142 +                * Do not terminate list traversal if one of the
3143 +                * destroy operations fails.
3144 +                */
3145 +               if (pk11_destroy_dsa_object_pub(sp, uselock) == 0)
3146 +                       {
3147 +                       ret = 0;
3148 +                       continue;
3149 +                       }
3150 +               if (pk11_destroy_dsa_object_priv(sp, uselock) == 0)
3151 +                       {
3152 +                       ret = 0;
3153 +                       continue;
3154 +                       }
3155 +               }
3157 +#ifndef NOPTHREADS
3158 +       if (session == NULL)
3159 +               OPENSSL_assert(pthread_mutex_unlock(session_cache[OP_DSA].lock) == 0);
3160 +#else
3161 +       if (session == NULL)
3162 +               CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
3163 +#endif
3165 +       return (ret);
3166 +       }
3167 +#endif /* OPENSSL_NO_DSA */
3169 +#ifndef OPENSSL_NO_DH
3170 +/* Destroy DH key from single session. */
3171 +int
3172 +pk11_destroy_dh_object(PK11_SESSION *sp, CK_BBOOL uselock)
3173 +       {
3174 +       int ret = 0;
3176 +       if (sp->opdata_dh_key != CK_INVALID_HANDLE)
3177 +               {
3178 +               TRY_OBJ_DESTROY(sp, sp->opdata_dh_key,
3179 +                   ret, uselock, OP_DH, CK_TRUE);
3180 +               sp->opdata_dh_key = CK_INVALID_HANDLE;
3181 +               sp->opdata_dh = NULL;
3182 +               if (sp->opdata_dh_priv_num != NULL)
3183 +                       {
3184 +                       BN_free(sp->opdata_dh_priv_num);
3185 +                       sp->opdata_dh_priv_num = NULL;
3186 +                       }
3187 +               }
3189 +       return (ret);
3190 +       }
3193 + * Destroy DH key object wrapper.
3194 + *
3195 + * arg0: pointer to PKCS#11 engine session structure
3196 + *       if session is NULL, try to destroy all objects in the free list
3197 + */
3198 +int
3199 +pk11_destroy_dh_key_objects(PK11_SESSION *session)
3200 +       {
3201 +       int ret = 1;
3202 +       PK11_SESSION *sp = NULL;
3203 +       PK11_SESSION *local_free_session;
3204 +       CK_BBOOL uselock = TRUE;
3206 +       if (session != NULL)
3207 +               local_free_session = session;
3208 +       else
3209 +               {
3210 +#ifndef NOPTHREADS
3211 +               OPENSSL_assert(pthread_mutex_lock(session_cache[OP_DH].lock) == 0);
3212 +#else
3213 +               CRYPTO_w_lock(CRYPTO_LOCK_PK11_ENGINE);
3214 +#endif
3215 +               local_free_session = session_cache[OP_DH].head;
3216 +               uselock = FALSE;
3217 +               }
3219 +       while ((sp = local_free_session) != NULL)
3220 +               {
3221 +               local_free_session = sp->next;
3223 +               /*
3224 +                * Do not terminate list traversal if one of the
3225 +                * destroy operations fails.
3226 +                */
3227 +               if (pk11_destroy_dh_object(sp, uselock) == 0)
3228 +                       {
3229 +                       ret = 0;
3230 +                       continue;
3231 +                       }
3232 +               }
3234 +#ifndef NOPTHREADS
3235 +       if (session == NULL)
3236 +               OPENSSL_assert(pthread_mutex_unlock(session_cache[OP_DH].lock) == 0);
3237 +#else
3238 +       if (session == NULL)
3239 +               CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
3240 +#endif
3242 +       return (ret);
3243 +       }
3244 +#endif /* OPENSSL_NO_DH */
3246 +static int
3247 +pk11_destroy_object(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE oh,
3248 +       CK_BBOOL persistent)
3249 +       {
3250 +       CK_RV rv;
3252 +       /*
3253 +        * We never try to destroy persistent objects which are the objects
3254 +        * stored in the keystore. Also, we always use read-only sessions so
3255 +        * C_DestroyObject() would be returning CKR_SESSION_READ_ONLY here.
3256 +        */
3257 +       if (persistent == CK_TRUE)
3258 +               return (1);
3260 +       rv = pFuncList->C_DestroyObject(session, oh);
3261 +       if (rv != CKR_OK)
3262 +               {
3263 +               PK11err_add_data(PK11_F_DESTROY_OBJECT, PK11_R_DESTROYOBJECT,
3264 +                   rv);
3265 +               return (0);
3266 +               }
3268 +       return (1);
3269 +       }
3272 +/* Symmetric ciphers and digests support functions */
3274 +static int
3275 +cipher_nid_to_pk11(int nid)
3276 +       {
3277 +       int i;
3279 +       for (i = 0; i < PK11_CIPHER_MAX; i++)
3280 +               if (ciphers[i].nid == nid)
3281 +                       return (ciphers[i].id);
3282 +       return (-1);
3283 +       }
3285 +static int
3286 +pk11_usable_ciphers(const int **nids)
3287 +       {
3288 +       if (cipher_count > 0)
3289 +               *nids = cipher_nids;
3290 +       else
3291 +               *nids = NULL;
3292 +       return (cipher_count);
3293 +       }
3295 +static int
3296 +pk11_usable_digests(const int **nids)
3297 +       {
3298 +       if (digest_count > 0)
3299 +               *nids = digest_nids;
3300 +       else
3301 +               *nids = NULL;
3302 +       return (digest_count);
3303 +       }
3306 + * Init context for encryption or decryption using a symmetric key.
3307 + */
3308 +static int pk11_init_symmetric(EVP_CIPHER_CTX *ctx, PK11_CIPHER *pcipher,
3309 +       PK11_SESSION *sp, CK_MECHANISM_PTR pmech)
3310 +       {
3311 +       CK_RV rv;
3312 +#ifdef SOLARIS_AES_CTR
3313 +       CK_AES_CTR_PARAMS ctr_params;
3314 +#endif /* SOLARIS_AES_CTR */
3316 +       /*
3317 +        * We expect pmech->mechanism to be already set and
3318 +        * pParameter/ulParameterLen initialized to NULL/0 before
3319 +        * pk11_init_symetric() is called.
3320 +        */
3321 +       OPENSSL_assert(pmech->mechanism != 0);
3322 +       OPENSSL_assert(pmech->pParameter == NULL);
3323 +       OPENSSL_assert(pmech->ulParameterLen == 0);
3325 +#ifdef SOLARIS_AES_CTR
3326 +       if (ctx->cipher->nid == NID_aes_128_ctr ||
3327 +           ctx->cipher->nid == NID_aes_192_ctr ||
3328 +           ctx->cipher->nid == NID_aes_256_ctr)
3329 +               {
3330 +               pmech->pParameter = (void *)(&ctr_params);
3331 +               pmech->ulParameterLen = sizeof (ctr_params);
3332 +               /*
3333 +                * For now, we are limited to the fixed length of the counter,
3334 +                * it covers the whole counter block. That's what RFC 4344
3335 +                * needs. For more information on internal structure of the
3336 +                * counter block, see RFC 3686. If needed in the future, we can
3337 +                * add code so that the counter length can be set via
3338 +                * ENGINE_ctrl() function.
3339 +                */
3340 +               ctr_params.ulCounterBits = AES_BLOCK_SIZE * 8;
3341 +               OPENSSL_assert(pcipher->iv_len == AES_BLOCK_SIZE);
3342 +               (void) memcpy(ctr_params.cb, ctx->iv, AES_BLOCK_SIZE);
3343 +               }
3344 +       else
3345 +#endif /* SOLARIS_AES_CTR */
3346 +               {
3347 +               if (pcipher->iv_len > 0)
3348 +                       {
3349 +                       pmech->pParameter = (void *)ctx->iv;
3350 +                       pmech->ulParameterLen = pcipher->iv_len;
3351 +                       }
3352 +               }
3354 +       /* if we get here, the encryption needs to be reinitialized */
3355 +       if (ctx->encrypt)
3356 +               rv = pFuncList->C_EncryptInit(sp->session, pmech,
3357 +                       sp->opdata_cipher_key);
3358 +       else
3359 +               rv = pFuncList->C_DecryptInit(sp->session, pmech,
3360 +                       sp->opdata_cipher_key);
3362 +       if (rv != CKR_OK)
3363 +               {
3364 +               PK11err_add_data(PK11_F_CIPHER_INIT, ctx->encrypt ?
3365 +                   PK11_R_ENCRYPTINIT : PK11_R_DECRYPTINIT, rv);
3366 +               pk11_return_session(sp, OP_CIPHER);
3367 +               return (0);
3368 +               }
3370 +       return (1);
3371 +       }
3373 +/* ARGSUSED */
3374 +static int
3375 +pk11_cipher_init(EVP_CIPHER_CTX *ctx, const unsigned char *key,
3376 +    const unsigned char *iv, int enc)
3377 +       {
3378 +       CK_MECHANISM mech;
3379 +       int index;
3380 +       PK11_CIPHER_STATE *state = (PK11_CIPHER_STATE *) ctx->cipher_data;
3381 +       PK11_SESSION *sp;
3382 +       PK11_CIPHER *p_ciph_table_row;
3384 +       state->sp = NULL;
3386 +       index = cipher_nid_to_pk11(ctx->cipher->nid);
3387 +       if (index < 0 || index >= PK11_CIPHER_MAX)
3388 +               return (0);
3390 +       p_ciph_table_row = &ciphers[index];
3391 +       /*
3392 +        * iv_len in the ctx->cipher structure is the maximum IV length for the
3393 +        * current cipher and it must be less or equal to the IV length in our
3394 +        * ciphers table. The key length must be in the allowed interval. From
3395 +        * all cipher modes that the PKCS#11 engine supports only RC4 allows a
3396 +        * key length to be in some range, all other NIDs have a precise key
3397 +        * length. Every application can define its own EVP functions so this
3398 +        * code serves as a sanity check.
3399 +        *
3400 +        * Note that the reason why the IV length in ctx->cipher might be
3401 +        * greater than the actual length is that OpenSSL uses BLOCK_CIPHER_defs
3402 +        * macro to define functions that return EVP structures for all DES
3403 +        * modes. So, even ECB modes get 8 byte IV.
3404 +        */
3405 +       if (ctx->cipher->iv_len < p_ciph_table_row->iv_len ||
3406 +           ctx->key_len < p_ciph_table_row->min_key_len ||
3407 +           ctx->key_len > p_ciph_table_row->max_key_len) {
3408 +               PK11err(PK11_F_CIPHER_INIT, PK11_R_KEY_OR_IV_LEN_PROBLEM);
3409 +               return (0);
3410 +       }
3412 +       if ((sp = pk11_get_session(OP_CIPHER)) == NULL)
3413 +               return (0);
3415 +       /* if applicable, the mechanism parameter is used for IV */
3416 +       mech.mechanism = p_ciph_table_row->mech_type;
3417 +       mech.pParameter = NULL;
3418 +       mech.ulParameterLen = 0;
3420 +       /* The key object is destroyed here if it is not the current key. */
3421 +       (void) check_new_cipher_key(sp, key, ctx->key_len);
3423 +       /*
3424 +        * If the key is the same and the encryption is also the same, then
3425 +        * just reuse it. However, we must not forget to reinitialize the
3426 +        * context that was finalized in pk11_cipher_cleanup().
3427 +        */
3428 +       if (sp->opdata_cipher_key != CK_INVALID_HANDLE &&
3429 +           sp->opdata_encrypt == ctx->encrypt)
3430 +               {
3431 +               state->sp = sp;
3432 +               if (pk11_init_symmetric(ctx, p_ciph_table_row, sp, &mech) == 0)
3433 +                       return (0);
3435 +               return (1);
3436 +               }
3438 +       /*
3439 +        * Check if the key has been invalidated. If so, a new key object
3440 +        * needs to be created.
3441 +        */
3442 +       if (sp->opdata_cipher_key == CK_INVALID_HANDLE)
3443 +               {
3444 +               sp->opdata_cipher_key = pk11_get_cipher_key(
3445 +                       ctx, key, p_ciph_table_row->key_type, sp);
3446 +               }
3448 +       if (sp->opdata_encrypt != ctx->encrypt && sp->opdata_encrypt != -1)
3449 +               {
3450 +               /*
3451 +                * The previous encryption/decryption is different. Need to
3452 +                * terminate the previous * active encryption/decryption here.
3453 +                */
3454 +               if (!pk11_cipher_final(sp))
3455 +                       {
3456 +                       pk11_return_session(sp, OP_CIPHER);
3457 +                       return (0);
3458 +                       }
3459 +               }
3461 +       if (sp->opdata_cipher_key == CK_INVALID_HANDLE)
3462 +               {
3463 +               pk11_return_session(sp, OP_CIPHER);
3464 +               return (0);
3465 +               }
3467 +       /* now initialize the context with a new key */
3468 +       if (pk11_init_symmetric(ctx, p_ciph_table_row, sp, &mech) == 0)
3469 +               return (0);
3471 +       sp->opdata_encrypt = ctx->encrypt;
3472 +       state->sp = sp;
3474 +       return (1);
3475 +       }
3478 + * When reusing the same key in an encryption/decryption session for a
3479 + * decryption/encryption session, we need to close the active session
3480 + * and recreate a new one. Note that the key is in the global session so
3481 + * that it needs not be recreated.
3482 + *
3483 + * It is more appropriate to use C_En/DecryptFinish here. At the time of this
3484 + * development, these two functions in the PKCS#11 libraries used return
3485 + * unexpected errors when passing in 0 length output. It may be a good
3486 + * idea to try them again if performance is a problem here and fix
3487 + * C_En/DecryptFinial if there are bugs there causing the problem.
3488 + */
3489 +static int
3490 +pk11_cipher_final(PK11_SESSION *sp)
3491 +       {
3492 +       CK_RV rv;
3494 +       rv = pFuncList->C_CloseSession(sp->session);
3495 +       if (rv != CKR_OK)
3496 +               {
3497 +               PK11err_add_data(PK11_F_CIPHER_FINAL, PK11_R_CLOSESESSION, rv);
3498 +               return (0);
3499 +               }
3501 +       rv = pFuncList->C_OpenSession(SLOTID, CKF_SERIAL_SESSION,
3502 +               NULL_PTR, NULL_PTR, &sp->session);
3503 +       if (rv != CKR_OK)
3504 +               {
3505 +               PK11err_add_data(PK11_F_CIPHER_FINAL, PK11_R_OPENSESSION, rv);
3506 +               return (0);
3507 +               }
3509 +       return (1);
3510 +       }
3513 + * An engine interface function. The calling function allocates sufficient
3514 + * memory for the output buffer "out" to hold the results.
3515 + */
3516 +#if OPENSSL_VERSION_NUMBER < 0x10000000L
3517 +static int
3518 +pk11_cipher_do_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
3519 +       const unsigned char *in, unsigned int inl)
3520 +#else
3521 +static int
3522 +pk11_cipher_do_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
3523 +       const unsigned char *in, size_t inl)
3524 +#endif
3525 +       {
3526 +       PK11_CIPHER_STATE *state = (PK11_CIPHER_STATE *) ctx->cipher_data;
3527 +       PK11_SESSION *sp;
3528 +       CK_RV rv;
3529 +       unsigned long outl = inl;
3531 +       if (state == NULL || state->sp == NULL)
3532 +               return (0);
3534 +       sp = (PK11_SESSION *) state->sp;
3536 +       if (!inl)
3537 +               return (1);
3539 +       /* RC4 is the only stream cipher we support */
3540 +       if (ctx->cipher->nid != NID_rc4 && (inl % ctx->cipher->block_size) != 0)
3541 +               return (0);
3543 +       if (ctx->encrypt)
3544 +               {
3545 +               rv = pFuncList->C_EncryptUpdate(sp->session,
3546 +                       (unsigned char *)in, inl, out, &outl);
3548 +               if (rv != CKR_OK)
3549 +                       {
3550 +                       PK11err_add_data(PK11_F_CIPHER_DO_CIPHER,
3551 +                           PK11_R_ENCRYPTUPDATE, rv);
3552 +                       return (0);
3553 +                       }
3554 +               }
3555 +       else
3556 +               {
3557 +               rv = pFuncList->C_DecryptUpdate(sp->session,
3558 +                       (unsigned char *)in, inl, out, &outl);
3560 +               if (rv != CKR_OK)
3561 +                       {
3562 +                       PK11err_add_data(PK11_F_CIPHER_DO_CIPHER,
3563 +                           PK11_R_DECRYPTUPDATE, rv);
3564 +                       return (0);
3565 +                       }
3566 +               }
3568 +       /*
3569 +        * For DES_CBC, DES3_CBC, AES_CBC, and RC4, the output size is always
3570 +        * the same size of input.
3571 +        * The application has guaranteed to call the block ciphers with
3572 +        * correctly aligned buffers.
3573 +        */
3574 +       if (inl != outl)
3575 +               return (0);
3577 +       return (1);
3578 +       }
3581 + * Return the session to the pool. Calling C_EncryptFinal() and C_DecryptFinal()
3582 + * here is the right thing because in EVP_DecryptFinal_ex(), engine's
3583 + * do_cipher() is not even called, and in EVP_EncryptFinal_ex() it is called but
3584 + * the engine can't find out that it's the finalizing call. We wouldn't
3585 + * necessarily have to finalize the context here since reinitializing it with
3586 + * C_(Encrypt|Decrypt)Init() should be fine but for the sake of correctness,
3587 + * let's do it. Some implementations might leak memory if the previously used
3588 + * context is initialized without finalizing it first.
3589 + */
3590 +static int
3591 +pk11_cipher_cleanup(EVP_CIPHER_CTX *ctx)
3592 +       {
3593 +       CK_RV rv;
3594 +       CK_ULONG len = EVP_MAX_BLOCK_LENGTH;
3595 +       CK_BYTE buf[EVP_MAX_BLOCK_LENGTH];
3596 +       PK11_CIPHER_STATE *state = ctx->cipher_data;
3598 +       if (state != NULL && state->sp != NULL)
3599 +               {
3600 +               /*
3601 +                * We are not interested in the data here, we just need to get
3602 +                * rid of the context.
3603 +                */
3604 +               if (ctx->encrypt)
3605 +                       rv = pFuncList->C_EncryptFinal(
3606 +                           state->sp->session, buf, &len);
3607 +               else
3608 +                       rv = pFuncList->C_DecryptFinal(
3609 +                           state->sp->session, buf, &len);
3611 +               if (rv != CKR_OK)
3612 +                       {
3613 +                       PK11err_add_data(PK11_F_CIPHER_CLEANUP, ctx->encrypt ?
3614 +                           PK11_R_ENCRYPTFINAL : PK11_R_DECRYPTFINAL, rv);
3615 +                       pk11_return_session(state->sp, OP_CIPHER);
3616 +                       return (0);
3617 +                       }
3619 +               pk11_return_session(state->sp, OP_CIPHER);
3620 +               state->sp = NULL;
3621 +               }
3623 +       return (1);
3624 +       }
3627 + * Registered by the ENGINE when used to find out how to deal with
3628 + * a particular NID in the ENGINE. This says what we'll do at the
3629 + * top level - note, that list is restricted by what we answer with
3630 + */
3631 +/* ARGSUSED */
3632 +static int
3633 +pk11_engine_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
3634 +       const int **nids, int nid)
3635 +       {
3636 +       if (!cipher)
3637 +               return (pk11_usable_ciphers(nids));
3639 +       switch (nid)
3640 +               {
3641 +               case NID_des_ede3_cbc:
3642 +                       *cipher = &pk11_3des_cbc;
3643 +                       break;
3644 +               case NID_des_cbc:
3645 +                       *cipher = &pk11_des_cbc;
3646 +                       break;
3647 +               case NID_des_ede3_ecb:
3648 +                       *cipher = &pk11_3des_ecb;
3649 +                       break;
3650 +               case NID_des_ecb:
3651 +                       *cipher = &pk11_des_ecb;
3652 +                       break;
3653 +               case NID_aes_128_cbc:
3654 +                       *cipher = &pk11_aes_128_cbc;
3655 +                       break;
3656 +               case NID_aes_192_cbc:
3657 +                       *cipher = &pk11_aes_192_cbc;
3658 +                       break;
3659 +               case NID_aes_256_cbc:
3660 +                       *cipher = &pk11_aes_256_cbc;
3661 +                       break;
3662 +               case NID_aes_128_ecb:
3663 +                       *cipher = &pk11_aes_128_ecb;
3664 +                       break;
3665 +               case NID_aes_192_ecb:
3666 +                       *cipher = &pk11_aes_192_ecb;
3667 +                       break;
3668 +               case NID_aes_256_ecb:
3669 +                       *cipher = &pk11_aes_256_ecb;
3670 +                       break;
3671 +               case NID_bf_cbc:
3672 +                       *cipher = &pk11_bf_cbc;
3673 +                       break;
3674 +               case NID_rc4:
3675 +                       *cipher = &pk11_rc4;
3676 +                       break;
3677 +               default:
3678 +#ifdef SOLARIS_AES_CTR
3679 +                       /*
3680 +                        * These can't be in separated cases because the NIDs
3681 +                        * here are not constants.
3682 +                        */
3683 +                       if (nid == NID_aes_128_ctr)
3684 +                               *cipher = &pk11_aes_128_ctr;
3685 +                       else if (nid == NID_aes_192_ctr)
3686 +                               *cipher = &pk11_aes_192_ctr;
3687 +                       else if (nid == NID_aes_256_ctr)
3688 +                               *cipher = &pk11_aes_256_ctr;
3689 +                       else
3690 +#endif /* SOLARIS_AES_CTR */
3691 +                       *cipher = NULL;
3692 +                       break;
3693 +               }
3694 +       return (*cipher != NULL);
3695 +       }
3697 +/* ARGSUSED */
3698 +static int
3699 +pk11_engine_digests(ENGINE *e, const EVP_MD **digest,
3700 +       const int **nids, int nid)
3701 +       {
3702 +       if (!digest)
3703 +               return (pk11_usable_digests(nids));
3705 +       switch (nid)
3706 +               {
3707 +               case NID_md5:
3708 +                       *digest = &pk11_md5;
3709 +                       break;
3710 +               case NID_sha1:
3711 +                       *digest = &pk11_sha1;
3712 +                       break;
3713 +               case NID_sha224:
3714 +                       *digest = &pk11_sha224;
3715 +                       break;
3716 +               case NID_sha256:
3717 +                       *digest = &pk11_sha256;
3718 +                       break;
3719 +               case NID_sha384:
3720 +                       *digest = &pk11_sha384;
3721 +                       break;
3722 +               case NID_sha512:
3723 +                       *digest = &pk11_sha512;
3724 +                       break;
3725 +               default:
3726 +                       *digest = NULL;
3727 +                       break;
3728 +               }
3729 +       return (*digest != NULL);
3730 +       }
3733 +/* Create a secret key object in a PKCS#11 session */
3734 +static CK_OBJECT_HANDLE pk11_get_cipher_key(EVP_CIPHER_CTX *ctx,
3735 +       const unsigned char *key, CK_KEY_TYPE key_type, PK11_SESSION *sp)
3736 +       {
3737 +       CK_RV rv;
3738 +       CK_OBJECT_HANDLE h_key = CK_INVALID_HANDLE;
3739 +       CK_OBJECT_CLASS obj_key = CKO_SECRET_KEY;
3740 +       CK_ULONG ul_key_attr_count = 6;
3741 +       unsigned char key_buf[PK11_KEY_LEN_MAX];
3743 +       CK_ATTRIBUTE  a_key_template[] =
3744 +               {
3745 +               {CKA_CLASS, (void*) NULL, sizeof (CK_OBJECT_CLASS)},
3746 +               {CKA_KEY_TYPE, (void*) NULL, sizeof (CK_KEY_TYPE)},
3747 +               {CKA_TOKEN, &myfalse, sizeof (myfalse)},
3748 +               {CKA_ENCRYPT, &mytrue, sizeof (mytrue)},
3749 +               {CKA_DECRYPT, &mytrue, sizeof (mytrue)},
3750 +               {CKA_VALUE, (void*) NULL, 0},
3751 +               };
3753 +       /*
3754 +        * Create secret key object in global_session. All other sessions
3755 +        * can use the key handles. Here is why:
3756 +        * OpenSSL will call EncryptInit and EncryptUpdate using a secret key.
3757 +        * It may then call DecryptInit and DecryptUpdate using the same key.
3758 +        * To use the same key object, we need to call EncryptFinal with
3759 +        * a 0 length message. Currently, this does not work for 3DES
3760 +        * mechanism. To get around this problem, we close the session and
3761 +        * then create a new session to use the same key object. When a session
3762 +        * is closed, all the object handles will be invalid. Thus, create key
3763 +        * objects in a global session, an individual session may be closed to
3764 +        * terminate the active operation.
3765 +        */
3766 +       CK_SESSION_HANDLE session = global_session;
3767 +       a_key_template[0].pValue = &obj_key;
3768 +       a_key_template[1].pValue = &key_type;
3769 +       if (ctx->key_len > PK11_KEY_LEN_MAX)
3770 +               {
3771 +               a_key_template[5].pValue = (void *) key;
3772 +               }
3773 +       else
3774 +               {
3775 +               memset(key_buf, 0, PK11_KEY_LEN_MAX);
3776 +               memcpy(key_buf, key, ctx->key_len);
3777 +               if ((key_type == CKK_DES) ||
3778 +                   (key_type == CKK_DES2) ||
3779 +                   (key_type == CKK_DES3))
3780 +                       DES_fixup_key_parity((DES_cblock *) &key_buf[0]);
3781 +               if ((key_type == CKK_DES2) ||
3782 +                   (key_type == CKK_DES3))
3783 +                       DES_fixup_key_parity((DES_cblock *) &key_buf[8]);
3784 +               if (key_type == CKK_DES3)
3785 +                       DES_fixup_key_parity((DES_cblock *) &key_buf[16]);
3786 +               a_key_template[5].pValue = (void *) key_buf;
3787 +               }
3788 +       a_key_template[5].ulValueLen = (unsigned long) ctx->key_len;
3790 +       rv = pFuncList->C_CreateObject(session,
3791 +               a_key_template, ul_key_attr_count, &h_key);
3792 +       if (rv != CKR_OK)
3793 +               {
3794 +               memset(key_buf, 0, PK11_KEY_LEN_MAX);
3795 +               PK11err_add_data(PK11_F_GET_CIPHER_KEY, PK11_R_CREATEOBJECT,
3796 +                   rv);
3797 +               goto err;
3798 +               }
3800 +       /*
3801 +        * Save the key information used in this session.
3802 +        * The max can be saved is PK11_KEY_LEN_MAX.
3803 +        */
3804 +       if (ctx->key_len > PK11_KEY_LEN_MAX)
3805 +               {
3806 +               sp->opdata_key_len = PK11_KEY_LEN_MAX;
3807 +               (void) memcpy(sp->opdata_key, key, sp->opdata_key_len);
3808 +               }
3809 +       else
3810 +               {
3811 +               sp->opdata_key_len = ctx->key_len;
3812 +               (void) memcpy(sp->opdata_key, key_buf, sp->opdata_key_len);
3813 +               }
3814 +       memset(key_buf, 0, PK11_KEY_LEN_MAX);
3815 +err:
3817 +       return (h_key);
3818 +       }
3820 +static int
3821 +md_nid_to_pk11(int nid)
3822 +       {
3823 +       int i;
3825 +       for (i = 0; i < PK11_DIGEST_MAX; i++)
3826 +               if (digests[i].nid == nid)
3827 +                       return (digests[i].id);
3828 +       return (-1);
3829 +       }
3831 +static int
3832 +pk11_digest_init(EVP_MD_CTX *ctx)
3833 +       {
3834 +       CK_RV rv;
3835 +       CK_MECHANISM mech;
3836 +       int index;
3837 +       PK11_SESSION *sp;
3838 +       PK11_DIGEST *pdp;
3839 +       PK11_CIPHER_STATE *state = (PK11_CIPHER_STATE *) ctx->md_data;
3841 +       state->sp = NULL;
3843 +       index = md_nid_to_pk11(ctx->digest->type);
3844 +       if (index < 0 || index >= PK11_DIGEST_MAX)
3845 +               return (0);
3847 +       pdp = &digests[index];
3848 +       if ((sp = pk11_get_session(OP_DIGEST)) == NULL)
3849 +               return (0);
3851 +       /* at present, no parameter is needed for supported digests */
3852 +       mech.mechanism = pdp->mech_type;
3853 +       mech.pParameter = NULL;
3854 +       mech.ulParameterLen = 0;
3856 +       rv = pFuncList->C_DigestInit(sp->session, &mech);
3858 +       if (rv != CKR_OK)
3859 +               {
3860 +               PK11err_add_data(PK11_F_DIGEST_INIT, PK11_R_DIGESTINIT, rv);
3861 +               pk11_return_session(sp, OP_DIGEST);
3862 +               return (0);
3863 +               }
3865 +       state->sp = sp;
3867 +       return (1);
3868 +       }
3870 +static int
3871 +pk11_digest_update(EVP_MD_CTX *ctx, const void *data, size_t count)
3872 +       {
3873 +       CK_RV rv;
3874 +       PK11_CIPHER_STATE *state = (PK11_CIPHER_STATE *) ctx->md_data;
3876 +       /* 0 length message will cause a failure in C_DigestFinal */
3877 +       if (count == 0)
3878 +               return (1);
3880 +       if (state == NULL || state->sp == NULL)
3881 +               return (0);
3883 +       rv = pFuncList->C_DigestUpdate(state->sp->session, (CK_BYTE *) data,
3884 +               count);
3886 +       if (rv != CKR_OK)
3887 +               {
3888 +               PK11err_add_data(PK11_F_DIGEST_UPDATE, PK11_R_DIGESTUPDATE, rv);
3889 +               pk11_return_session(state->sp, OP_DIGEST);
3890 +               state->sp = NULL;
3891 +               return (0);
3892 +               }
3894 +       return (1);
3895 +       }
3897 +static int
3898 +pk11_digest_final(EVP_MD_CTX *ctx, unsigned char *md)
3899 +       {
3900 +       CK_RV rv;
3901 +       unsigned long len;
3902 +       PK11_CIPHER_STATE *state = (PK11_CIPHER_STATE *) ctx->md_data;
3903 +       len = ctx->digest->md_size;
3905 +       if (state == NULL || state->sp == NULL)
3906 +               return (0);
3908 +       rv = pFuncList->C_DigestFinal(state->sp->session, md, &len);
3910 +       if (rv != CKR_OK)
3911 +               {
3912 +               PK11err_add_data(PK11_F_DIGEST_FINAL, PK11_R_DIGESTFINAL, rv);
3913 +               pk11_return_session(state->sp, OP_DIGEST);
3914 +               state->sp = NULL;
3915 +               return (0);
3916 +               }
3918 +       if (ctx->digest->md_size != len)
3919 +               return (0);
3921 +       /*
3922 +        * Final is called and digest is returned, so return the session
3923 +        * to the pool
3924 +        */
3925 +       pk11_return_session(state->sp, OP_DIGEST);
3926 +       state->sp = NULL;
3928 +       return (1);
3929 +       }
3931 +static int
3932 +pk11_digest_copy(EVP_MD_CTX *to, const EVP_MD_CTX *from)
3933 +       {
3934 +       CK_RV rv;
3935 +       int ret = 0;
3936 +       PK11_CIPHER_STATE *state, *state_to;
3937 +       CK_BYTE_PTR pstate = NULL;
3938 +       CK_ULONG ul_state_len;
3940 +       /* The copy-from state */
3941 +       state = (PK11_CIPHER_STATE *) from->md_data;
3942 +       if (state == NULL || state->sp == NULL)
3943 +               goto err;
3945 +       /* Initialize the copy-to state */
3946 +       if (!pk11_digest_init(to))
3947 +               goto err;
3948 +       state_to = (PK11_CIPHER_STATE *) to->md_data;
3950 +       /* Get the size of the operation state of the copy-from session */
3951 +       rv = pFuncList->C_GetOperationState(state->sp->session, NULL,
3952 +               &ul_state_len);
3954 +       if (rv != CKR_OK)
3955 +               {
3956 +               PK11err_add_data(PK11_F_DIGEST_COPY, PK11_R_GET_OPERATION_STATE,
3957 +                   rv);
3958 +               goto err;
3959 +               }
3960 +       if (ul_state_len == 0)
3961 +               {
3962 +               goto err;
3963 +               }
3965 +       pstate = OPENSSL_malloc(ul_state_len);
3966 +       if (pstate == NULL)
3967 +               {
3968 +               PK11err(PK11_F_DIGEST_COPY, PK11_R_MALLOC_FAILURE);
3969 +               goto err;
3970 +               }
3972 +       /* Get the operation state of the copy-from session */
3973 +       rv = pFuncList->C_GetOperationState(state->sp->session, pstate,
3974 +               &ul_state_len);
3976 +       if (rv != CKR_OK)
3977 +               {
3978 +               PK11err_add_data(PK11_F_DIGEST_COPY, PK11_R_GET_OPERATION_STATE,
3979 +                   rv);
3980 +               goto err;
3981 +               }
3983 +       /* Set the operation state of the copy-to session */
3984 +       rv = pFuncList->C_SetOperationState(state_to->sp->session, pstate,
3985 +               ul_state_len, 0, 0);
3987 +       if (rv != CKR_OK)
3988 +               {
3989 +               PK11err_add_data(PK11_F_DIGEST_COPY,
3990 +                   PK11_R_SET_OPERATION_STATE, rv);
3991 +               goto err;
3992 +               }
3994 +       ret = 1;
3995 +err:
3996 +       if (pstate != NULL)
3997 +               OPENSSL_free(pstate);
3999 +       return (ret);
4000 +       }
4002 +/* Return any pending session state to the pool */
4003 +static int
4004 +pk11_digest_cleanup(EVP_MD_CTX *ctx)
4005 +       {
4006 +       PK11_CIPHER_STATE *state = ctx->md_data;
4007 +       unsigned char buf[EVP_MAX_MD_SIZE];
4009 +       if (state != NULL && state->sp != NULL)
4010 +               {
4011 +               /*
4012 +                * If state->sp is not NULL then pk11_digest_final() has not
4013 +                * been called yet. We must call it now to free any memory
4014 +                * that might have been allocated in the token when
4015 +                * pk11_digest_init() was called. pk11_digest_final()
4016 +                * will return the session to the cache.
4017 +                */
4018 +               if (!pk11_digest_final(ctx, buf))
4019 +                       return (0);
4020 +               }
4022 +       return (1);
4023 +       }
4026 + * Check if the new key is the same as the key object in the session. If the key
4027 + * is the same, no need to create a new key object. Otherwise, the old key
4028 + * object needs to be destroyed and a new one will be created. Return 1 for
4029 + * cache hit, 0 for cache miss. Note that we must check the key length first
4030 + * otherwise we could end up reusing a different, longer key with the same
4031 + * prefix.
4032 + */
4033 +static int check_new_cipher_key(PK11_SESSION *sp, const unsigned char *key,
4034 +       int key_len)
4035 +       {
4036 +       if (sp->opdata_key_len != key_len ||
4037 +           memcmp(sp->opdata_key, key, key_len) != 0)
4038 +               {
4039 +               (void) pk11_destroy_cipher_key_objects(sp);
4040 +               return (0);
4041 +               }
4042 +       return (1);
4043 +       }
4045 +/* Destroy one or more secret key objects. */
4046 +static int pk11_destroy_cipher_key_objects(PK11_SESSION *session)
4047 +       {
4048 +       int ret = 0;
4049 +       PK11_SESSION *sp = NULL;
4050 +       PK11_SESSION *local_free_session;
4052 +       if (session != NULL)
4053 +               local_free_session = session;
4054 +       else
4055 +               {
4056 +#ifndef NOPTHREADS
4057 +               OPENSSL_assert(pthread_mutex_lock(session_cache[OP_CIPHER].lock) == 0);
4058 +#else
4059 +               CRYPTO_w_lock(CRYPTO_LOCK_PK11_ENGINE);
4060 +#endif
4061 +               local_free_session = session_cache[OP_CIPHER].head;
4062 +               }
4064 +       while ((sp = local_free_session) != NULL)
4065 +               {
4066 +               local_free_session = sp->next;
4068 +               if (sp->opdata_cipher_key != CK_INVALID_HANDLE)
4069 +                       {
4070 +                       /*
4071 +                        * The secret key object is created in the
4072 +                        * global_session. See pk11_get_cipher_key().
4073 +                        */
4074 +                       if (pk11_destroy_object(global_session,
4075 +                               sp->opdata_cipher_key, CK_FALSE) == 0)
4076 +                               goto err;
4077 +                       sp->opdata_cipher_key = CK_INVALID_HANDLE;
4078 +                       }
4079 +               }
4080 +       ret = 1;
4081 +err:
4083 +#ifndef NOPTHREADS
4084 +       if (session == NULL)
4085 +               OPENSSL_assert(pthread_mutex_unlock(session_cache[OP_CIPHER].lock) == 0);
4086 +#else
4087 +       if (session == NULL)
4088 +               CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
4089 +#endif
4091 +       return (ret);
4092 +       }
4096 + * Public key mechanisms optionally supported
4097 + *
4098 + * CKM_RSA_X_509
4099 + * CKM_RSA_PKCS
4100 + * CKM_DSA
4101 + *
4102 + * The first slot that supports at least one of those mechanisms is chosen as a
4103 + * public key slot.
4104 + *
4105 + * Symmetric ciphers optionally supported
4106 + *
4107 + * CKM_DES3_CBC
4108 + * CKM_DES_CBC
4109 + * CKM_AES_CBC
4110 + * CKM_DES3_ECB
4111 + * CKM_DES_ECB
4112 + * CKM_AES_ECB
4113 + * CKM_AES_CTR
4114 + * CKM_RC4
4115 + * CKM_BLOWFISH_CBC
4116 + *
4117 + * Digests optionally supported
4118 + *
4119 + * CKM_MD5
4120 + * CKM_SHA_1
4121 + * CKM_SHA224
4122 + * CKM_SHA256
4123 + * CKM_SHA384
4124 + * CKM_SHA512
4125 + *
4126 + * The output of this function is a set of global variables indicating which
4127 + * mechanisms from RSA, DSA, DH and RAND are present, and also two arrays of
4128 + * mechanisms, one for symmetric ciphers and one for digests. Also, 3 global
4129 + * variables carry information about which slot was chosen for (a) public key
4130 + * mechanisms, (b) random operations, and (c) symmetric ciphers and digests.
4131 + */
4132 +static int
4133 +pk11_choose_slots(int *any_slot_found)
4134 +       {
4135 +       CK_SLOT_ID_PTR pSlotList = NULL_PTR;
4136 +       CK_ULONG ulSlotCount = 0;
4137 +       CK_MECHANISM_INFO mech_info;
4138 +       CK_TOKEN_INFO token_info;
4139 +       unsigned int i;
4140 +       CK_RV rv;
4141 +       CK_SLOT_ID best_slot_sofar = 0;
4142 +       CK_BBOOL found_candidate_slot = CK_FALSE;
4143 +       int slot_n_cipher = 0;
4144 +       int slot_n_digest = 0;
4145 +       CK_SLOT_ID current_slot = 0;
4146 +       int current_slot_n_cipher = 0;
4147 +       int current_slot_n_digest = 0;
4149 +       int local_cipher_nids[PK11_CIPHER_MAX];
4150 +       int local_digest_nids[PK11_DIGEST_MAX];
4152 +       /* let's initialize the output parameter */
4153 +       if (any_slot_found != NULL)
4154 +               *any_slot_found = 0;
4156 +       /* Get slot list for memory allocation */
4157 +       rv = pFuncList->C_GetSlotList(CK_FALSE, NULL_PTR, &ulSlotCount);
4159 +       if (rv != CKR_OK)
4160 +               {
4161 +               PK11err_add_data(PK11_F_CHOOSE_SLOT, PK11_R_GETSLOTLIST, rv);
4162 +               return (0);
4163 +               }
4165 +       /* it's not an error if we didn't find any providers */
4166 +       if (ulSlotCount == 0)
4167 +               {
4168 +#ifdef DEBUG_SLOT_SELECTION
4169 +               fprintf(stderr, "%s: no crypto providers found\n", PK11_DBG);
4170 +#endif /* DEBUG_SLOT_SELECTION */
4171 +               return (1);
4172 +               }
4174 +       pSlotList = OPENSSL_malloc(ulSlotCount * sizeof (CK_SLOT_ID));
4176 +       if (pSlotList == NULL)
4177 +               {
4178 +               PK11err(PK11_F_CHOOSE_SLOT, PK11_R_MALLOC_FAILURE);
4179 +               return (0);
4180 +               }
4182 +       /* Get the slot list for processing */
4183 +       rv = pFuncList->C_GetSlotList(CK_FALSE, pSlotList, &ulSlotCount);
4184 +       if (rv != CKR_OK)
4185 +               {
4186 +               PK11err_add_data(PK11_F_CHOOSE_SLOT, PK11_R_GETSLOTLIST, rv);
4187 +               OPENSSL_free(pSlotList);
4188 +               return (0);
4189 +               }
4191 +#ifdef DEBUG_SLOT_SELECTION
4192 +       fprintf(stderr, "%s: provider: %s\n", PK11_DBG, def_PK11_LIBNAME);
4193 +       fprintf(stderr, "%s: number of slots: %d\n", PK11_DBG, ulSlotCount);
4195 +       fprintf(stderr, "%s: == checking rand slots ==\n", PK11_DBG);
4196 +#endif /* DEBUG_SLOT_SELECTION */
4197 +       for (i = 0; i < ulSlotCount; i++)
4198 +               {
4199 +               current_slot = pSlotList[i];
4201 +#ifdef DEBUG_SLOT_SELECTION
4202 +       fprintf(stderr, "%s: checking slot: %d\n", PK11_DBG, i);
4203 +#endif /* DEBUG_SLOT_SELECTION */
4204 +               /* Check if slot has random support. */
4205 +               rv = pFuncList->C_GetTokenInfo(current_slot, &token_info);
4206 +               if (rv != CKR_OK)
4207 +                       continue;
4209 +#ifdef DEBUG_SLOT_SELECTION
4210 +       fprintf(stderr, "%s: token label: %.32s\n", PK11_DBG, token_info.label);
4211 +#endif /* DEBUG_SLOT_SELECTION */
4213 +               if (token_info.flags & CKF_RNG)
4214 +                       {
4215 +#ifdef DEBUG_SLOT_SELECTION
4216 +       fprintf(stderr, "%s: this token has CKF_RNG flag\n", PK11_DBG);
4217 +#endif /* DEBUG_SLOT_SELECTION */
4218 +                       pk11_have_random = CK_TRUE;
4219 +                       rand_SLOTID = current_slot;
4220 +                       break;
4221 +                       }
4222 +               }
4224 +#ifdef DEBUG_SLOT_SELECTION
4225 +       fprintf(stderr, "%s: == checking pubkey slots ==\n", PK11_DBG);
4226 +#endif /* DEBUG_SLOT_SELECTION */
4228 +       pubkey_SLOTID = pSlotList[0];
4229 +       for (i = 0; i < ulSlotCount; i++)
4230 +               {
4231 +               CK_BBOOL slot_has_rsa = CK_FALSE;
4232 +               CK_BBOOL slot_has_recover = CK_FALSE;
4233 +               CK_BBOOL slot_has_dsa = CK_FALSE;
4234 +               CK_BBOOL slot_has_dh = CK_FALSE;
4235 +               current_slot = pSlotList[i];
4237 +#ifdef DEBUG_SLOT_SELECTION
4238 +       fprintf(stderr, "%s: checking slot: %d\n", PK11_DBG, i);
4239 +#endif /* DEBUG_SLOT_SELECTION */
4240 +               rv = pFuncList->C_GetTokenInfo(current_slot, &token_info);
4241 +               if (rv != CKR_OK)
4242 +                       continue;
4244 +#ifdef DEBUG_SLOT_SELECTION
4245 +       fprintf(stderr, "%s: token label: %.32s\n", PK11_DBG, token_info.label);
4246 +#endif /* DEBUG_SLOT_SELECTION */
4248 +#ifndef OPENSSL_NO_RSA
4249 +               /*
4250 +                * Check if this slot is capable of signing and
4251 +                * verifying with CKM_RSA_PKCS.
4252 +                */
4253 +               rv = pFuncList->C_GetMechanismInfo(current_slot, CKM_RSA_PKCS,
4254 +                       &mech_info);
4256 +               if (rv == CKR_OK && ((mech_info.flags & CKF_SIGN) &&
4257 +                               (mech_info.flags & CKF_VERIFY)))
4258 +                       {
4259 +                       /*
4260 +                        * Check if this slot is capable of encryption,
4261 +                        * decryption, sign, and verify with CKM_RSA_X_509.
4262 +                        */
4263 +                       rv = pFuncList->C_GetMechanismInfo(current_slot,
4264 +                           CKM_RSA_X_509, &mech_info);
4266 +                       if (rv == CKR_OK && ((mech_info.flags & CKF_SIGN) &&
4267 +                           (mech_info.flags & CKF_VERIFY) &&
4268 +                           (mech_info.flags & CKF_ENCRYPT) &&
4269 +                           (mech_info.flags & CKF_DECRYPT)))
4270 +                               {
4271 +                               slot_has_rsa = CK_TRUE;
4272 +                               if (mech_info.flags & CKF_VERIFY_RECOVER)
4273 +                                       {
4274 +                                       slot_has_recover = CK_TRUE;
4275 +                                       }
4276 +                               }
4277 +                       }
4278 +#endif /* OPENSSL_NO_RSA */
4280 +#ifndef OPENSSL_NO_DSA
4281 +               /*
4282 +                * Check if this slot is capable of signing and
4283 +                * verifying with CKM_DSA.
4284 +                */
4285 +               rv = pFuncList->C_GetMechanismInfo(current_slot, CKM_DSA,
4286 +                       &mech_info);
4287 +               if (rv == CKR_OK && ((mech_info.flags & CKF_SIGN) &&
4288 +                   (mech_info.flags & CKF_VERIFY)))
4289 +                       {
4290 +                       slot_has_dsa = CK_TRUE;
4291 +                       }
4293 +#endif /* OPENSSL_NO_DSA */
4295 +#ifndef OPENSSL_NO_DH
4296 +               /*
4297 +                * Check if this slot is capable of DH key generataion and
4298 +                * derivation.
4299 +                */
4300 +               rv = pFuncList->C_GetMechanismInfo(current_slot,
4301 +                   CKM_DH_PKCS_KEY_PAIR_GEN, &mech_info);
4303 +               if (rv == CKR_OK && (mech_info.flags & CKF_GENERATE_KEY_PAIR))
4304 +                       {
4305 +                       rv = pFuncList->C_GetMechanismInfo(current_slot,
4306 +                               CKM_DH_PKCS_DERIVE, &mech_info);
4307 +                       if (rv == CKR_OK && (mech_info.flags & CKF_DERIVE))
4308 +                               {
4309 +                               slot_has_dh = CK_TRUE;
4310 +                               }
4311 +                       }
4312 +#endif /* OPENSSL_NO_DH */
4314 +               if (!found_candidate_slot &&
4315 +                   (slot_has_rsa || slot_has_dsa || slot_has_dh))
4316 +                       {
4317 +#ifdef DEBUG_SLOT_SELECTION
4318 +                       fprintf(stderr,
4319 +                           "%s: potential slot: %d\n", PK11_DBG, current_slot);
4320 +#endif /* DEBUG_SLOT_SELECTION */
4321 +                       best_slot_sofar = current_slot;
4322 +                       pk11_have_rsa = slot_has_rsa;
4323 +                       pk11_have_recover = slot_has_recover;
4324 +                       pk11_have_dsa = slot_has_dsa;
4325 +                       pk11_have_dh = slot_has_dh;
4326 +                       found_candidate_slot = CK_TRUE;
4327 +                       /*
4328 +                        * Cache the flags for later use. We might
4329 +                        * need those if RSA keys by reference feature
4330 +                        * is used.
4331 +                        */
4332 +                       pubkey_token_flags = token_info.flags;
4333 +#ifdef DEBUG_SLOT_SELECTION
4334 +                       fprintf(stderr,
4335 +                           "%s: setting found_candidate_slot to CK_TRUE\n",
4336 +                           PK11_DBG);
4337 +                       fprintf(stderr,
4338 +                           "%s: best so far slot: %d\n", PK11_DBG,
4339 +                           best_slot_sofar);
4340 +                       fprintf(stderr, "%s: pubkey flags changed to "
4341 +                           "%lu.\n", PK11_DBG, pubkey_token_flags);
4342 +                       }
4343 +               else
4344 +                       {
4345 +                       fprintf(stderr,
4346 +                           "%s: no rsa/dsa/dh\n", PK11_DBG);
4347 +                       }
4348 +#else
4349 +                       } /* if */
4350 +#endif /* DEBUG_SLOT_SELECTION */
4351 +               } /* for */
4353 +       if (found_candidate_slot == CK_TRUE)
4354 +               {
4355 +               pubkey_SLOTID = best_slot_sofar;
4356 +               }
4358 +       found_candidate_slot = CK_FALSE;
4359 +       best_slot_sofar = 0;
4361 +#ifdef DEBUG_SLOT_SELECTION
4362 +       fprintf(stderr, "%s: == checking cipher/digest ==\n", PK11_DBG);
4363 +#endif /* DEBUG_SLOT_SELECTION */
4365 +       SLOTID = pSlotList[0];
4366 +       for (i = 0; i < ulSlotCount; i++)
4367 +               {
4368 +#ifdef DEBUG_SLOT_SELECTION
4369 +       fprintf(stderr, "%s: checking slot: %d\n", PK11_DBG, i);
4370 +#endif /* DEBUG_SLOT_SELECTION */
4372 +               current_slot = pSlotList[i];
4373 +               current_slot_n_cipher = 0;
4374 +               current_slot_n_digest = 0;
4375 +               (void) memset(local_cipher_nids, 0, sizeof (local_cipher_nids));
4376 +               (void) memset(local_digest_nids, 0, sizeof (local_digest_nids));
4378 +               pk11_find_symmetric_ciphers(pFuncList, current_slot,
4379 +                   &current_slot_n_cipher, local_cipher_nids);
4381 +               pk11_find_digests(pFuncList, current_slot,
4382 +                   &current_slot_n_digest, local_digest_nids);
4384 +#ifdef DEBUG_SLOT_SELECTION
4385 +               fprintf(stderr, "%s: current_slot_n_cipher %d\n", PK11_DBG,
4386 +                       current_slot_n_cipher);
4387 +               fprintf(stderr, "%s: current_slot_n_digest %d\n", PK11_DBG,
4388 +                       current_slot_n_digest);
4389 +               fprintf(stderr, "%s: best so far cipher/digest slot: %d\n",
4390 +                       PK11_DBG, best_slot_sofar);
4391 +#endif /* DEBUG_SLOT_SELECTION */
4393 +               /*
4394 +                * If the current slot supports more ciphers/digests than
4395 +                * the previous best one we change the current best to this one,
4396 +                * otherwise leave it where it is.
4397 +                */
4398 +               if ((current_slot_n_cipher + current_slot_n_digest) >
4399 +                   (slot_n_cipher + slot_n_digest))
4400 +                       {
4401 +#ifdef DEBUG_SLOT_SELECTION
4402 +                       fprintf(stderr,
4403 +                               "%s: changing best so far slot to %d\n",
4404 +                               PK11_DBG, current_slot);
4405 +#endif /* DEBUG_SLOT_SELECTION */
4406 +                       best_slot_sofar = SLOTID = current_slot;
4407 +                       cipher_count = slot_n_cipher = current_slot_n_cipher;
4408 +                       digest_count = slot_n_digest = current_slot_n_digest;
4409 +                       (void) memcpy(cipher_nids, local_cipher_nids,
4410 +                           sizeof (local_cipher_nids));
4411 +                       (void) memcpy(digest_nids, local_digest_nids, 
4412 +                           sizeof (local_digest_nids));
4413 +                       }
4414 +               }
4416 +#ifdef DEBUG_SLOT_SELECTION
4417 +       fprintf(stderr,
4418 +           "%s: chosen pubkey slot: %d\n", PK11_DBG, pubkey_SLOTID);
4419 +       fprintf(stderr,
4420 +           "%s: chosen rand slot: %d\n", PK11_DBG, rand_SLOTID);
4421 +       fprintf(stderr,
4422 +           "%s: chosen cipher/digest slot: %d\n", PK11_DBG, SLOTID);
4423 +       fprintf(stderr,
4424 +           "%s: pk11_have_rsa %d\n", PK11_DBG, pk11_have_rsa);
4425 +       fprintf(stderr,
4426 +           "%s: pk11_have_recover %d\n", PK11_DBG, pk11_have_recover);
4427 +       fprintf(stderr,
4428 +           "%s: pk11_have_dsa %d\n", PK11_DBG, pk11_have_dsa);
4429 +       fprintf(stderr,
4430 +           "%s: pk11_have_dh %d\n", PK11_DBG, pk11_have_dh);
4431 +       fprintf(stderr,
4432 +           "%s: pk11_have_random %d\n", PK11_DBG, pk11_have_random);
4433 +       fprintf(stderr,
4434 +           "%s: cipher_count %d\n", PK11_DBG, cipher_count);
4435 +       fprintf(stderr,
4436 +           "%s: digest_count %d\n", PK11_DBG, digest_count);
4437 +#endif /* DEBUG_SLOT_SELECTION */
4439 +       if (pSlotList != NULL)
4440 +               OPENSSL_free(pSlotList);
4442 +#ifdef SOLARIS_HW_SLOT_SELECTION
4443 +       OPENSSL_free(hw_cnids);
4444 +       OPENSSL_free(hw_dnids);
4445 +#endif /* SOLARIS_HW_SLOT_SELECTION */
4447 +       if (any_slot_found != NULL)
4448 +               *any_slot_found = 1;
4449 +       return (1);
4450 +       }
4452 +static void pk11_get_symmetric_cipher(CK_FUNCTION_LIST_PTR pflist,
4453 +    int slot_id, CK_MECHANISM_TYPE mech, int *current_slot_n_cipher,
4454 +    int *local_cipher_nids, int id)
4455 +       {
4456 +       CK_MECHANISM_INFO mech_info;
4457 +       CK_RV rv;
4459 +#ifdef DEBUG_SLOT_SELECTION
4460 +       fprintf(stderr, "%s: checking mech: %x", PK11_DBG, mech);
4461 +#endif /* DEBUG_SLOT_SELECTION */
4462 +       rv = pflist->C_GetMechanismInfo(slot_id, mech, &mech_info);
4464 +       if (rv != CKR_OK)
4465 +               {
4466 +#ifdef DEBUG_SLOT_SELECTION
4467 +               fprintf(stderr, " not found\n");
4468 +#endif /* DEBUG_SLOT_SELECTION */
4469 +               return;
4470 +               }
4472 +       if ((mech_info.flags & CKF_ENCRYPT) &&
4473 +           (mech_info.flags & CKF_DECRYPT))
4474 +               {
4475 +#ifdef SOLARIS_HW_SLOT_SELECTION
4476 +               if (nid_in_table(ciphers[id].nid, hw_cnids))
4477 +#endif /* SOLARIS_HW_SLOT_SELECTION */
4478 +                       {
4479 +#ifdef DEBUG_SLOT_SELECTION
4480 +               fprintf(stderr, " usable\n");
4481 +#endif /* DEBUG_SLOT_SELECTION */
4482 +                       local_cipher_nids[(*current_slot_n_cipher)++] =
4483 +                           ciphers[id].nid;
4484 +                       }
4485 +#ifdef SOLARIS_HW_SLOT_SELECTION
4486 +#ifdef DEBUG_SLOT_SELECTION
4487 +               else
4488 +                       {
4489 +               fprintf(stderr, " rejected, software implementation only\n");
4490 +                       }
4491 +#endif /* DEBUG_SLOT_SELECTION */
4492 +#endif /* SOLARIS_HW_SLOT_SELECTION */
4493 +               }
4494 +#ifdef DEBUG_SLOT_SELECTION
4495 +       else
4496 +               {
4497 +               fprintf(stderr, " unusable\n");
4498 +               }
4499 +#endif /* DEBUG_SLOT_SELECTION */
4501 +       return;
4502 +       }
4504 +static void pk11_get_digest(CK_FUNCTION_LIST_PTR pflist, int slot_id,
4505 +    CK_MECHANISM_TYPE mech, int *current_slot_n_digest, int *local_digest_nids,
4506 +    int id)
4507 +       {
4508 +       CK_MECHANISM_INFO mech_info;
4509 +       CK_RV rv;
4511 +#ifdef DEBUG_SLOT_SELECTION
4512 +       fprintf(stderr, "%s: checking mech: %x", PK11_DBG, mech);
4513 +#endif /* DEBUG_SLOT_SELECTION */
4514 +       rv = pflist->C_GetMechanismInfo(slot_id, mech, &mech_info);
4516 +       if (rv != CKR_OK)
4517 +               {
4518 +#ifdef DEBUG_SLOT_SELECTION
4519 +               fprintf(stderr, " not found\n");
4520 +#endif /* DEBUG_SLOT_SELECTION */
4521 +               return;
4522 +               }
4524 +       if (mech_info.flags & CKF_DIGEST)
4525 +               {
4526 +#ifdef SOLARIS_HW_SLOT_SELECTION
4527 +               if (nid_in_table(digests[id].nid, hw_dnids))
4528 +#endif /* SOLARIS_HW_SLOT_SELECTION */
4529 +                       {
4530 +#ifdef DEBUG_SLOT_SELECTION
4531 +               fprintf(stderr, " usable\n");
4532 +#endif /* DEBUG_SLOT_SELECTION */
4533 +                       local_digest_nids[(*current_slot_n_digest)++] =
4534 +                           digests[id].nid;
4535 +                       }
4536 +#ifdef SOLARIS_HW_SLOT_SELECTION
4537 +#ifdef DEBUG_SLOT_SELECTION
4538 +               else
4539 +                       {
4540 +               fprintf(stderr, " rejected, software implementation only\n");
4541 +                       }
4542 +#endif /* DEBUG_SLOT_SELECTION */
4543 +#endif /* SOLARIS_HW_SLOT_SELECTION */
4544 +               }
4545 +#ifdef DEBUG_SLOT_SELECTION
4546 +       else
4547 +               {
4548 +               fprintf(stderr, " unusable\n");
4549 +               }
4550 +#endif /* DEBUG_SLOT_SELECTION */
4552 +       return;
4553 +       }
4555 +#ifdef SOLARIS_AES_CTR
4556 +/* create a new NID when we have no OID for that mechanism */
4557 +static int pk11_add_NID(char *sn, char *ln)
4558 +       {
4559 +       ASN1_OBJECT *o;
4560 +       int nid;
4562 +       if ((o = ASN1_OBJECT_create(OBJ_new_nid(1), (unsigned char *)"",
4563 +           1, sn, ln)) == NULL)
4564 +               {
4565 +               return (0);
4566 +               }
4568 +       /* will return NID_undef on error */
4569 +       nid = OBJ_add_object(o);
4570 +       ASN1_OBJECT_free(o);
4572 +       return (nid);
4573 +       }
4576 + * Create new NIDs for AES counter mode. OpenSSL doesn't support them now so we
4577 + * have to help ourselves here.
4578 + */
4579 +static int pk11_add_aes_ctr_NIDs(void)
4580 +       {
4581 +       /* are we already set? */
4582 +       if (NID_aes_256_ctr != NID_undef)
4583 +               return (1);
4585 +       /*
4586 +        * There are no official names for AES counter modes yet so we just
4587 +        * follow the format of those that exist.
4588 +        */
4589 +       if ((NID_aes_128_ctr = pk11_add_NID("AES-128-CTR", "aes-128-ctr")) ==
4590 +           NID_undef)
4591 +               goto err;
4592 +       ciphers[PK11_AES_128_CTR].nid = pk11_aes_128_ctr.nid = NID_aes_128_ctr;
4593 +       if ((NID_aes_192_ctr = pk11_add_NID("AES-192-CTR", "aes-192-ctr")) ==
4594 +           NID_undef)
4595 +               goto err;
4596 +       ciphers[PK11_AES_192_CTR].nid = pk11_aes_192_ctr.nid = NID_aes_192_ctr;
4597 +       if ((NID_aes_256_ctr = pk11_add_NID("AES-256-CTR", "aes-256-ctr")) ==
4598 +           NID_undef)
4599 +               goto err;
4600 +       ciphers[PK11_AES_256_CTR].nid = pk11_aes_256_ctr.nid = NID_aes_256_ctr;
4601 +       return (1);
4603 +err:
4604 +       PK11err(PK11_F_ADD_AES_CTR_NIDS, PK11_R_ADD_NID_FAILED);
4605 +       return (0);
4606 +       }
4607 +#endif /* SOLARIS_AES_CTR */
4609 +/* Find what symmetric ciphers this slot supports. */
4610 +static void pk11_find_symmetric_ciphers(CK_FUNCTION_LIST_PTR pflist,
4611 +    CK_SLOT_ID current_slot, int *current_slot_n_cipher, int *local_cipher_nids)
4612 +       {
4613 +       int i;
4615 +       for (i = 0; i < PK11_CIPHER_MAX; ++i)
4616 +               {
4617 +               pk11_get_symmetric_cipher(pflist, current_slot,
4618 +                   ciphers[i].mech_type, current_slot_n_cipher,
4619 +                   local_cipher_nids, ciphers[i].id);
4620 +               }
4621 +       }
4623 +/* Find what digest algorithms this slot supports. */
4624 +static void pk11_find_digests(CK_FUNCTION_LIST_PTR pflist,
4625 +    CK_SLOT_ID current_slot, int *current_slot_n_digest, int *local_digest_nids)
4626 +       {
4627 +       int i;
4629 +       for (i = 0; i < PK11_DIGEST_MAX; ++i)
4630 +               {
4631 +               pk11_get_digest(pflist, current_slot, digests[i].mech_type,
4632 +                   current_slot_n_digest, local_digest_nids, digests[i].id);
4633 +               }
4634 +       }
4636 +#ifdef SOLARIS_HW_SLOT_SELECTION
4638 + * It would be great if we could use pkcs11_kernel directly since this library
4639 + * offers hardware slots only. That's the easiest way to achieve the situation
4640 + * where we use the hardware accelerators when present and OpenSSL native code
4641 + * otherwise. That presumes the fact that OpenSSL native code is faster than the
4642 + * code in the soft token. It's a logical assumption - Crypto Framework has some
4643 + * inherent overhead so going there for the software implementation of a
4644 + * mechanism should be logically slower in contrast to the OpenSSL native code,
4645 + * presuming that both implementations are of similar speed. For example, the
4646 + * soft token for AES is roughly three times slower than OpenSSL for 64 byte
4647 + * blocks and still 20% slower for 8KB blocks. So, if we want to ship products
4648 + * that use the PKCS#11 engine by default, we must somehow avoid that regression
4649 + * on machines without hardware acceleration. That's why switching to the
4650 + * pkcs11_kernel library seems like a very good idea.
4651 + *
4652 + * The problem is that OpenSSL built with SunStudio is roughly 2x slower for
4653 + * asymmetric operations (RSA/DSA/DH) than the soft token built with the same
4654 + * compiler. That means that if we switched to pkcs11_kernel from the libpkcs11
4655 + * library, we would have had a performance regression on machines without
4656 + * hardware acceleration for asymmetric operations for all applications that use
4657 + * the PKCS#11 engine. There is one such application - Apache web server since
4658 + * it's shipped configured to use the PKCS#11 engine by default. Having said
4659 + * that, we can't switch to the pkcs11_kernel library now and have to come with
4660 + * a solution that, on non-accelerated machines, uses the OpenSSL native code
4661 + * for all symmetric ciphers and digests while it uses the soft token for
4662 + * asymmetric operations.
4663 + *
4664 + * This is the idea: dlopen() pkcs11_kernel directly and find out what
4665 + * mechanisms are there. We don't care about duplications (more slots can
4666 + * support the same mechanism), we just want to know what mechanisms can be
4667 + * possibly supported in hardware on that particular machine. As said before,
4668 + * pkcs11_kernel will show you hardware providers only.
4669 + *
4670 + * Then, we rely on the fact that since we use libpkcs11 library we will find
4671 + * the metaslot. When we go through the metaslot's mechanisms for symmetric
4672 + * ciphers and digests, we check that any found mechanism is in the table
4673 + * created using the pkcs11_kernel library. So, as a result we have two arrays
4674 + * of mechanisms that were advertised as supported in hardware which was the
4675 + * goal of that whole excercise. Thus, we can use libpkcs11 but avoid soft token
4676 + * code for symmetric ciphers and digests. See pk11_choose_slots() for more
4677 + * information.
4678 + *
4679 + * This is Solaris specific code, if SOLARIS_HW_SLOT_SELECTION is not defined
4680 + * the code won't be used.
4681 + */
4682 +#if defined(__sparcv9) || defined(__x86_64) || defined(__amd64)
4683 +static const char pkcs11_kernel[] = "/usr/lib/security/64/pkcs11_kernel.so.1";
4684 +#else
4685 +static const char pkcs11_kernel[] = "/usr/lib/security/pkcs11_kernel.so.1";
4686 +#endif
4689 + * Check hardware capabilities of the machines. The output are two lists,
4690 + * hw_cnids and hw_dnids, that contain hardware mechanisms found in all hardware
4691 + * providers together. They are not sorted and may contain duplicate mechanisms.
4692 + */
4693 +static int check_hw_mechanisms(void)
4694 +       {
4695 +       int i;
4696 +       CK_RV rv;
4697 +       void *handle;
4698 +       CK_C_GetFunctionList p;
4699 +       CK_TOKEN_INFO token_info;
4700 +       CK_ULONG ulSlotCount = 0;
4701 +       int n_cipher = 0, n_digest = 0;
4702 +       CK_FUNCTION_LIST_PTR pflist = NULL;
4703 +       CK_SLOT_ID_PTR pSlotList = NULL_PTR;
4704 +       int *tmp_hw_cnids = NULL, *tmp_hw_dnids = NULL;
4705 +       int hw_ctable_size, hw_dtable_size;
4707 +#ifdef DEBUG_SLOT_SELECTION
4708 +       fprintf(stderr, "%s: SOLARIS_HW_SLOT_SELECTION code running\n",
4709 +           PK11_DBG);
4710 +#endif
4711 +       if ((handle = dlopen(pkcs11_kernel, RTLD_LAZY)) == NULL)
4712 +               {
4713 +               PK11err(PK11_F_CHECK_HW_MECHANISMS, PK11_R_DSO_FAILURE);
4714 +               goto err;
4715 +               }
4717 +       if ((p = (CK_C_GetFunctionList)dlsym(handle,
4718 +           PK11_GET_FUNCTION_LIST)) == NULL)
4719 +               {
4720 +               PK11err(PK11_F_CHECK_HW_MECHANISMS, PK11_R_DSO_FAILURE);
4721 +               goto err;
4722 +               }
4724 +       /* get the full function list from the loaded library */
4725 +       if (p(&pflist) != CKR_OK)
4726 +               {
4727 +               PK11err(PK11_F_CHECK_HW_MECHANISMS, PK11_R_DSO_FAILURE);
4728 +               goto err;
4729 +               }
4731 +       rv = pflist->C_Initialize((CK_VOID_PTR)&pk11_init_args);
4732 +       if ((rv != CKR_OK) && (rv != CKR_CRYPTOKI_ALREADY_INITIALIZED))
4733 +               {
4734 +               PK11err_add_data(PK11_F_CHECK_HW_MECHANISMS,
4735 +                   PK11_R_INITIALIZE, rv);
4736 +               goto err;
4737 +               }
4739 +       if (pflist->C_GetSlotList(0, NULL_PTR, &ulSlotCount) != CKR_OK)
4740 +               {
4741 +               PK11err(PK11_F_CHECK_HW_MECHANISMS, PK11_R_GETSLOTLIST);
4742 +               goto err;
4743 +               }
4745 +       /* no slots, set the hw mechanism tables as empty */
4746 +       if (ulSlotCount == 0)
4747 +               {
4748 +#ifdef DEBUG_SLOT_SELECTION
4749 +       fprintf(stderr, "%s: no hardware mechanisms found\n", PK11_DBG);
4750 +#endif
4751 +               hw_cnids = OPENSSL_malloc(sizeof (int));
4752 +               hw_dnids = OPENSSL_malloc(sizeof (int));
4753 +               if (hw_cnids == NULL || hw_dnids == NULL)
4754 +                       {
4755 +                       PK11err(PK11_F_CHECK_HW_MECHANISMS,
4756 +                           PK11_R_MALLOC_FAILURE);
4757 +                       return (0);
4758 +                       }
4759 +               /* this means empty tables */
4760 +               hw_cnids[0] = NID_undef;
4761 +               hw_dnids[0] = NID_undef;
4762 +               return (1);
4763 +               }
4765 +       pSlotList = OPENSSL_malloc(ulSlotCount * sizeof (CK_SLOT_ID));
4766 +       if (pSlotList == NULL)
4767 +               {
4768 +               PK11err(PK11_F_CHECK_HW_MECHANISMS, PK11_R_MALLOC_FAILURE);
4769 +               goto err;
4770 +               }
4772 +       /* Get the slot list for processing */
4773 +       if (pflist->C_GetSlotList(0, pSlotList, &ulSlotCount) != CKR_OK)
4774 +               {
4775 +               PK11err(PK11_F_CHECK_HW_MECHANISMS, PK11_R_GETSLOTLIST);
4776 +               goto err;
4777 +               }
4779 +       /*
4780 +        * We don't care about duplicit mechanisms in multiple slots and also
4781 +        * reserve one slot for the terminal NID_undef which we use to stop the
4782 +        * search.
4783 +        */
4784 +       hw_ctable_size = ulSlotCount * PK11_CIPHER_MAX + 1;
4785 +       hw_dtable_size = ulSlotCount * PK11_DIGEST_MAX + 1;
4786 +       tmp_hw_cnids = OPENSSL_malloc(hw_ctable_size * sizeof (int));
4787 +       tmp_hw_dnids = OPENSSL_malloc(hw_dtable_size * sizeof (int));
4788 +       if (tmp_hw_cnids == NULL || tmp_hw_dnids == NULL)
4789 +               {
4790 +               PK11err(PK11_F_CHECK_HW_MECHANISMS, PK11_R_MALLOC_FAILURE);
4791 +               goto err;
4792 +               }
4794 +       /*
4795 +        * Do not use memset since we should not rely on the fact that NID_undef
4796 +        * is zero now.
4797 +        */
4798 +       for (i = 0; i < hw_ctable_size; ++i)
4799 +               tmp_hw_cnids[i] = NID_undef;
4800 +       for (i = 0; i < hw_dtable_size; ++i)
4801 +               tmp_hw_dnids[i] = NID_undef;
4803 +#ifdef DEBUG_SLOT_SELECTION
4804 +       fprintf(stderr, "%s: provider: %s\n", PK11_DBG, pkcs11_kernel);
4805 +       fprintf(stderr, "%s: found %d hardware slots\n", PK11_DBG, ulSlotCount);
4806 +       fprintf(stderr, "%s: now looking for mechs supported in hw\n",
4807 +           PK11_DBG);
4808 +#endif /* DEBUG_SLOT_SELECTION */
4810 +       for (i = 0; i < ulSlotCount; i++)
4811 +               {
4812 +               if (pflist->C_GetTokenInfo(pSlotList[i], &token_info) != CKR_OK)
4813 +                       continue;
4815 +#ifdef DEBUG_SLOT_SELECTION
4816 +       fprintf(stderr, "%s: token label: %.32s\n", PK11_DBG, token_info.label);
4817 +#endif /* DEBUG_SLOT_SELECTION */
4819 +               /*
4820 +                * We are filling the hw mech tables here. Global tables are
4821 +                * still NULL so all mechanisms are put into tmp tables.
4822 +                */
4823 +               pk11_find_symmetric_ciphers(pflist, pSlotList[i],
4824 +                   &n_cipher, tmp_hw_cnids);
4825 +               pk11_find_digests(pflist, pSlotList[i],
4826 +                   &n_digest, tmp_hw_dnids);
4827 +               }
4829 +       /*
4830 +        * Since we are part of a library (libcrypto.so), calling this function
4831 +        * may have side-effects. Also, C_Finalize() is triggered by
4832 +        * dlclose(3C).
4833 +        */
4834 +#if 0
4835 +       pflist->C_Finalize(NULL);
4836 +#endif
4837 +       OPENSSL_free(pSlotList);
4838 +       (void) dlclose(handle);
4839 +       hw_cnids = tmp_hw_cnids;
4840 +       hw_dnids = tmp_hw_dnids;
4842 +#ifdef DEBUG_SLOT_SELECTION
4843 +       fprintf(stderr, "%s: hw mechs check complete\n", PK11_DBG);
4844 +#endif /* DEBUG_SLOT_SELECTION */
4845 +       return (1);
4847 +err:
4848 +       if (pSlotList != NULL)
4849 +               OPENSSL_free(pSlotList);
4850 +       if (tmp_hw_cnids != NULL)
4851 +               OPENSSL_free(tmp_hw_cnids);
4852 +       if (tmp_hw_dnids != NULL)
4853 +               OPENSSL_free(tmp_hw_dnids);
4855 +       return (0);
4856 +       }
4859 + * Check presence of a NID in the table of NIDs. The table may be NULL (i.e.,
4860 + * non-existent).
4861 + */
4862 +static int nid_in_table(int nid, int *nid_table)
4863 +       {
4864 +       int i = 0;
4866 +       /*
4867 +        * a special case. NULL means that we are initializing a new
4868 +        * table.
4869 +        */
4870 +       if (nid_table == NULL)
4871 +               return (1);
4873 +       /*
4874 +        * the table is never full, there is always at least one
4875 +        * NID_undef.
4876 +        */
4877 +       while (nid_table[i] != NID_undef)
4878 +               {
4879 +               if (nid_table[i++] == nid)
4880 +                       {
4881 +#ifdef DEBUG_SLOT_SELECTION
4882 +       fprintf(stderr, " (NID %d in hw table, idx %d)", nid, i);
4883 +#endif /* DEBUG_SLOT_SELECTION */
4884 +                       return (1);
4885 +                       }
4886 +               }
4888 +       return (0);
4889 +       }
4890 +#endif /* SOLARIS_HW_SLOT_SELECTION */
4892 +#endif /* OPENSSL_NO_HW_PK11CA */
4893 +#endif /* OPENSSL_NO_HW_PK11 */
4894 +#endif /* OPENSSL_NO_HW */
4895 Index: openssl/crypto/engine/hw_pk11_err.c
4896 diff -u /dev/null openssl/crypto/engine/hw_pk11_err.c:1.4.10.1
4897 --- /dev/null   Fri Jan  2 13:56:40 2015
4898 +++ openssl/crypto/engine/hw_pk11_err.c Tue Jun 14 21:52:40 2011
4899 @@ -0,0 +1,288 @@
4901 + * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
4902 + * Use is subject to license terms.
4903 + */
4905 +/* crypto/engine/hw_pk11_err.c */
4907 + * This product includes software developed by the OpenSSL Project for
4908 + * use in the OpenSSL Toolkit (http://www.openssl.org/).
4909 + *
4910 + * This project also referenced hw_pkcs11-0.9.7b.patch written by
4911 + * Afchine Madjlessi.
4912 + */
4914 + * ====================================================================
4915 + * Copyright (c) 2000-2001 The OpenSSL Project.  All rights reserved.
4916 + *
4917 + * Redistribution and use in source and binary forms, with or without
4918 + * modification, are permitted provided that the following conditions
4919 + * are met:
4920 + *
4921 + * 1. Redistributions of source code must retain the above copyright
4922 + *    notice, this list of conditions and the following disclaimer.
4923 + *
4924 + * 2. Redistributions in binary form must reproduce the above copyright
4925 + *    notice, this list of conditions and the following disclaimer in
4926 + *    the documentation and/or other materials provided with the
4927 + *    distribution.
4928 + *
4929 + * 3. All advertising materials mentioning features or use of this
4930 + *    software must display the following acknowledgment:
4931 + *    "This product includes software developed by the OpenSSL Project
4932 + *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
4933 + *
4934 + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
4935 + *    endorse or promote products derived from this software without
4936 + *    prior written permission. For written permission, please contact
4937 + *    licensing@OpenSSL.org.
4938 + *
4939 + * 5. Products derived from this software may not be called "OpenSSL"
4940 + *    nor may "OpenSSL" appear in their names without prior written
4941 + *    permission of the OpenSSL Project.
4942 + *
4943 + * 6. Redistributions of any form whatsoever must retain the following
4944 + *    acknowledgment:
4945 + *    "This product includes software developed by the OpenSSL Project
4946 + *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
4947 + *
4948 + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
4949 + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
4950 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
4951 + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
4952 + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
4953 + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
4954 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
4955 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
4956 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
4957 + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
4958 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
4959 + * OF THE POSSIBILITY OF SUCH DAMAGE.
4960 + * ====================================================================
4961 + *
4962 + * This product includes cryptographic software written by Eric Young
4963 + * (eay@cryptsoft.com).  This product includes software written by Tim
4964 + * Hudson (tjh@cryptsoft.com).
4965 + *
4966 + */
4968 +#include <stdio.h>
4969 +#include <openssl/err.h>
4970 +#include "hw_pk11_err.h"
4972 +/* BEGIN ERROR CODES */
4973 +#ifndef OPENSSL_NO_ERR
4974 +static ERR_STRING_DATA pk11_str_functs[]=
4976 +{ ERR_PACK(0, PK11_F_INIT, 0),                 "PK11_INIT"},
4977 +{ ERR_PACK(0, PK11_F_FINISH, 0),               "PK11_FINISH"},
4978 +{ ERR_PACK(0, PK11_F_DESTROY, 0),              "PK11_DESTROY"},
4979 +{ ERR_PACK(0, PK11_F_CTRL, 0),                 "PK11_CTRL"},
4980 +{ ERR_PACK(0, PK11_F_RSA_INIT, 0),             "PK11_RSA_INIT"},
4981 +{ ERR_PACK(0, PK11_F_RSA_FINISH, 0),           "PK11_RSA_FINISH"},
4982 +{ ERR_PACK(0, PK11_F_GET_PUB_RSA_KEY, 0),      "PK11_GET_PUB_RSA_KEY"},
4983 +{ ERR_PACK(0, PK11_F_GET_PRIV_RSA_KEY, 0),     "PK11_GET_PRIV_RSA_KEY"},
4984 +{ ERR_PACK(0, PK11_F_RSA_GEN_KEY, 0),          "PK11_RSA_GEN_KEY"},
4985 +{ ERR_PACK(0, PK11_F_RSA_PUB_ENC, 0),          "PK11_RSA_PUB_ENC"},
4986 +{ ERR_PACK(0, PK11_F_RSA_PRIV_ENC, 0),         "PK11_RSA_PRIV_ENC"},
4987 +{ ERR_PACK(0, PK11_F_RSA_PUB_DEC, 0),          "PK11_RSA_PUB_DEC"},
4988 +{ ERR_PACK(0, PK11_F_RSA_PRIV_DEC, 0),         "PK11_RSA_PRIV_DEC"},
4989 +{ ERR_PACK(0, PK11_F_RSA_SIGN, 0),             "PK11_RSA_SIGN"},
4990 +{ ERR_PACK(0, PK11_F_RSA_VERIFY, 0),           "PK11_RSA_VERIFY"},
4991 +{ ERR_PACK(0, PK11_F_RAND_ADD, 0),             "PK11_RAND_ADD"},
4992 +{ ERR_PACK(0, PK11_F_RAND_BYTES, 0),           "PK11_RAND_BYTES"},
4993 +{ ERR_PACK(0, PK11_F_GET_SESSION, 0),          "PK11_GET_SESSION"},
4994 +{ ERR_PACK(0, PK11_F_FREE_SESSION, 0),         "PK11_FREE_SESSION"},
4995 +{ ERR_PACK(0, PK11_F_LOAD_PUBKEY, 0),          "PK11_LOAD_PUBKEY"},
4996 +{ ERR_PACK(0, PK11_F_LOAD_PRIVKEY, 0),         "PK11_LOAD_PRIV_KEY"},
4997 +{ ERR_PACK(0, PK11_F_RSA_PUB_ENC_LOW, 0),      "PK11_RSA_PUB_ENC_LOW"},
4998 +{ ERR_PACK(0, PK11_F_RSA_PRIV_ENC_LOW, 0),     "PK11_RSA_PRIV_ENC_LOW"},
4999 +{ ERR_PACK(0, PK11_F_RSA_PUB_DEC_LOW, 0),      "PK11_RSA_PUB_DEC_LOW"},
5000 +{ ERR_PACK(0, PK11_F_RSA_PRIV_DEC_LOW, 0),     "PK11_RSA_PRIV_DEC_LOW"},
5001 +{ ERR_PACK(0, PK11_F_DSA_SIGN, 0),             "PK11_DSA_SIGN"},
5002 +{ ERR_PACK(0, PK11_F_DSA_VERIFY, 0),           "PK11_DSA_VERIFY"},
5003 +{ ERR_PACK(0, PK11_F_DSA_INIT, 0),             "PK11_DSA_INIT"},
5004 +{ ERR_PACK(0, PK11_F_DSA_FINISH, 0),           "PK11_DSA_FINISH"},
5005 +{ ERR_PACK(0, PK11_F_GET_PUB_DSA_KEY, 0),      "PK11_GET_PUB_DSA_KEY"},
5006 +{ ERR_PACK(0, PK11_F_GET_PRIV_DSA_KEY, 0),     "PK11_GET_PRIV_DSA_KEY"},
5007 +{ ERR_PACK(0, PK11_F_DH_INIT, 0),              "PK11_DH_INIT"},
5008 +{ ERR_PACK(0, PK11_F_DH_FINISH, 0),            "PK11_DH_FINISH"},
5009 +{ ERR_PACK(0, PK11_F_MOD_EXP_DH, 0),           "PK11_MOD_EXP_DH"},
5010 +{ ERR_PACK(0, PK11_F_GET_DH_KEY, 0),           "PK11_GET_DH_KEY"},
5011 +{ ERR_PACK(0, PK11_F_FREE_ALL_SESSIONS, 0),    "PK11_FREE_ALL_SESSIONS"},
5012 +{ ERR_PACK(0, PK11_F_SETUP_SESSION, 0),                "PK11_SETUP_SESSION"},
5013 +{ ERR_PACK(0, PK11_F_DESTROY_OBJECT, 0),       "PK11_DESTROY_OBJECT"},
5014 +{ ERR_PACK(0, PK11_F_CIPHER_INIT, 0),          "PK11_CIPHER_INIT"},
5015 +{ ERR_PACK(0, PK11_F_CIPHER_DO_CIPHER, 0),     "PK11_CIPHER_DO_CIPHER"},
5016 +{ ERR_PACK(0, PK11_F_GET_CIPHER_KEY, 0),       "PK11_GET_CIPHER_KEY"},
5017 +{ ERR_PACK(0, PK11_F_DIGEST_INIT, 0),          "PK11_DIGEST_INIT"},
5018 +{ ERR_PACK(0, PK11_F_DIGEST_UPDATE, 0),                "PK11_DIGEST_UPDATE"},
5019 +{ ERR_PACK(0, PK11_F_DIGEST_FINAL, 0),         "PK11_DIGEST_FINAL"},
5020 +{ ERR_PACK(0, PK11_F_CHOOSE_SLOT, 0),          "PK11_CHOOSE_SLOT"},
5021 +{ ERR_PACK(0, PK11_F_CIPHER_FINAL, 0),         "PK11_CIPHER_FINAL"},
5022 +{ ERR_PACK(0, PK11_F_LIBRARY_INIT, 0),         "PK11_LIBRARY_INIT"},
5023 +{ ERR_PACK(0, PK11_F_LOAD, 0),                 "ENGINE_LOAD_PK11"},
5024 +{ ERR_PACK(0, PK11_F_DH_GEN_KEY, 0),           "PK11_DH_GEN_KEY"},
5025 +{ ERR_PACK(0, PK11_F_DH_COMP_KEY, 0),          "PK11_DH_COMP_KEY"},
5026 +{ ERR_PACK(0, PK11_F_DIGEST_COPY, 0),          "PK11_DIGEST_COPY"},
5027 +{ ERR_PACK(0, PK11_F_CIPHER_CLEANUP, 0),       "PK11_CIPHER_CLEANUP"},
5028 +{ ERR_PACK(0, PK11_F_ACTIVE_ADD, 0),           "PK11_ACTIVE_ADD"},
5029 +{ ERR_PACK(0, PK11_F_ACTIVE_DELETE, 0),                "PK11_ACTIVE_DELETE"},
5030 +{ ERR_PACK(0, PK11_F_CHECK_HW_MECHANISMS, 0),  "PK11_CHECK_HW_MECHANISMS"},
5031 +{ ERR_PACK(0, PK11_F_INIT_SYMMETRIC, 0),       "PK11_INIT_SYMMETRIC"},
5032 +{ ERR_PACK(0, PK11_F_ADD_AES_CTR_NIDS, 0),     "PK11_ADD_AES_CTR_NIDS"},
5033 +{ ERR_PACK(0, PK11_F_INIT_ALL_LOCKS, 0),       "PK11_INIT_ALL_LOCKS"},
5034 +{ ERR_PACK(0, PK11_F_RETURN_SESSION, 0),       "PK11_RETURN_SESSION"},
5035 +{ ERR_PACK(0, PK11_F_GET_PIN, 0),              "PK11_GET_PIN"},
5036 +{ ERR_PACK(0, PK11_F_FIND_ONE_OBJECT, 0),      "PK11_FIND_ONE_OBJECT"},
5037 +{ ERR_PACK(0, PK11_F_CHECK_TOKEN_ATTRS, 0),    "PK11_CHECK_TOKEN_ATTRS"},
5038 +{ ERR_PACK(0, PK11_F_CACHE_PIN, 0),            "PK11_CACHE_PIN"},
5039 +{ ERR_PACK(0, PK11_F_MLOCK_PIN_IN_MEMORY, 0),  "PK11_MLOCK_PIN_IN_MEMORY"},
5040 +{ ERR_PACK(0, PK11_F_TOKEN_LOGIN, 0),          "PK11_TOKEN_LOGIN"},
5041 +{ ERR_PACK(0, PK11_F_TOKEN_RELOGIN, 0),                "PK11_TOKEN_RELOGIN"},
5042 +{ ERR_PACK(0, PK11_F_RUN_ASKPASS, 0),          "PK11_F_RUN_ASKPASS"},
5043 +{ 0, NULL}
5046 +static ERR_STRING_DATA pk11_str_reasons[]=
5048 +{ PK11_R_ALREADY_LOADED,               "PKCS#11 DSO already loaded"},
5049 +{ PK11_R_DSO_FAILURE,                  "unable to load PKCS#11 DSO"},
5050 +{ PK11_R_NOT_LOADED,                   "PKCS#11 DSO not loaded"},
5051 +{ PK11_R_PASSED_NULL_PARAMETER,                "null parameter passed"},
5052 +{ PK11_R_COMMAND_NOT_IMPLEMENTED,      "command not implemented"},
5053 +{ PK11_R_INITIALIZE,                   "C_Initialize failed"},
5054 +{ PK11_R_FINALIZE,                     "C_Finalize failed"},
5055 +{ PK11_R_GETINFO,                      "C_GetInfo faile"},
5056 +{ PK11_R_GETSLOTLIST,                  "C_GetSlotList failed"},
5057 +{ PK11_R_NO_MODULUS_OR_NO_EXPONENT,    "no modulus or no exponent"},
5058 +{ PK11_R_ATTRIBUT_SENSITIVE_OR_INVALID,        "attr sensitive or invalid"},
5059 +{ PK11_R_GETATTRIBUTVALUE,             "C_GetAttributeValue failed"},
5060 +{ PK11_R_NO_MODULUS,                   "no modulus"},
5061 +{ PK11_R_NO_EXPONENT,                  "no exponent"},
5062 +{ PK11_R_FINDOBJECTSINIT,              "C_FindObjectsInit failed"},
5063 +{ PK11_R_FINDOBJECTS,                  "C_FindObjects failed"},
5064 +{ PK11_R_FINDOBJECTSFINAL,             "C_FindObjectsFinal failed"},
5065 +{ PK11_R_CREATEOBJECT,                 "C_CreateObject failed"},
5066 +{ PK11_R_DESTROYOBJECT,                        "C_DestroyObject failed"},
5067 +{ PK11_R_OPENSESSION,                  "C_OpenSession failed"},
5068 +{ PK11_R_CLOSESESSION,                 "C_CloseSession failed"},
5069 +{ PK11_R_ENCRYPTINIT,                  "C_EncryptInit failed"},
5070 +{ PK11_R_ENCRYPT,                      "C_Encrypt failed"},
5071 +{ PK11_R_SIGNINIT,                     "C_SignInit failed"},
5072 +{ PK11_R_SIGN,                         "C_Sign failed"},
5073 +{ PK11_R_DECRYPTINIT,                  "C_DecryptInit failed"},
5074 +{ PK11_R_DECRYPT,                      "C_Decrypt failed"},
5075 +{ PK11_R_VERIFYINIT,                   "C_VerifyRecover failed"},
5076 +{ PK11_R_VERIFY,                       "C_Verify failed"},
5077 +{ PK11_R_VERIFYRECOVERINIT,            "C_VerifyRecoverInit failed"},
5078 +{ PK11_R_VERIFYRECOVER,                        "C_VerifyRecover failed"},
5079 +{ PK11_R_GEN_KEY,                      "C_GenerateKeyPair failed"},
5080 +{ PK11_R_SEEDRANDOM,                   "C_SeedRandom failed"},
5081 +{ PK11_R_GENERATERANDOM,               "C_GenerateRandom failed"},
5082 +{ PK11_R_INVALID_MESSAGE_LENGTH,       "invalid message length"},
5083 +{ PK11_R_UNKNOWN_ALGORITHM_TYPE,       "unknown algorithm type"},
5084 +{ PK11_R_UNKNOWN_ASN1_OBJECT_ID,       "unknown asn1 onject id"},
5085 +{ PK11_R_UNKNOWN_PADDING_TYPE,         "unknown padding type"},
5086 +{ PK11_R_PADDING_CHECK_FAILED,         "padding check failed"},
5087 +{ PK11_R_DIGEST_TOO_BIG,               "digest too big"},
5088 +{ PK11_R_MALLOC_FAILURE,               "malloc failure"},
5089 +{ PK11_R_CTRL_COMMAND_NOT_IMPLEMENTED, "ctl command not implemented"},
5090 +{ PK11_R_DATA_GREATER_THAN_MOD_LEN,    "data is bigger than mod"},
5091 +{ PK11_R_DATA_TOO_LARGE_FOR_MODULUS,   "data is too larger for mod"},
5092 +{ PK11_R_MISSING_KEY_COMPONENT,                "a dsa component is missing"},
5093 +{ PK11_R_INVALID_SIGNATURE_LENGTH,     "invalid signature length"},
5094 +{ PK11_R_INVALID_DSA_SIGNATURE_R,      "missing r in dsa verify"},
5095 +{ PK11_R_INVALID_DSA_SIGNATURE_S,      "missing s in dsa verify"},
5096 +{ PK11_R_INCONSISTENT_KEY,             "inconsistent key type"},
5097 +{ PK11_R_ENCRYPTUPDATE,                        "C_EncryptUpdate failed"},
5098 +{ PK11_R_DECRYPTUPDATE,                        "C_DecryptUpdate failed"},
5099 +{ PK11_R_DIGESTINIT,                   "C_DigestInit failed"},
5100 +{ PK11_R_DIGESTUPDATE,                 "C_DigestUpdate failed"},
5101 +{ PK11_R_DIGESTFINAL,                  "C_DigestFinal failed"},
5102 +{ PK11_R_ENCRYPTFINAL,                 "C_EncryptFinal failed"},
5103 +{ PK11_R_DECRYPTFINAL,                 "C_DecryptFinal failed"},
5104 +{ PK11_R_NO_PRNG_SUPPORT,              "Slot does not support PRNG"},
5105 +{ PK11_R_GETTOKENINFO,                 "C_GetTokenInfo failed"},
5106 +{ PK11_R_DERIVEKEY,                    "C_DeriveKey failed"},
5107 +{ PK11_R_GET_OPERATION_STATE,          "C_GetOperationState failed"},
5108 +{ PK11_R_SET_OPERATION_STATE,          "C_SetOperationState failed"},
5109 +{ PK11_R_INVALID_HANDLE,               "invalid PKCS#11 object handle"},
5110 +{ PK11_R_KEY_OR_IV_LEN_PROBLEM,                "IV or key length incorrect"},
5111 +{ PK11_R_INVALID_OPERATION_TYPE,       "invalid operation type"},
5112 +{ PK11_R_ADD_NID_FAILED,               "failed to add NID" },
5113 +{ PK11_R_ATFORK_FAILED,                        "atfork() failed" },
5114 +{ PK11_R_TOKEN_LOGIN_FAILED,           "C_Login() failed on token" },
5115 +{ PK11_R_MORE_THAN_ONE_OBJECT_FOUND,   "more than one object found" },
5116 +{ PK11_R_INVALID_PKCS11_URI,           "pkcs11 URI provided is invalid" },
5117 +{ PK11_R_COULD_NOT_READ_PIN,           "could not read PIN from terminal" },
5118 +{ PK11_R_PIN_NOT_READ_FROM_COMMAND,    "PIN not read from external command" },
5119 +{ PK11_R_COULD_NOT_OPEN_COMMAND,       "could not popen() dialog command" },
5120 +{ PK11_R_PIPE_FAILED,                  "pipe() failed" },
5121 +{ PK11_R_BAD_PASSPHRASE_SPEC,          "bad passphrasedialog specification" },
5122 +{ PK11_R_TOKEN_NOT_INITIALIZED,                "token not initialized" },
5123 +{ PK11_R_TOKEN_PIN_NOT_SET,            "token PIN required but not set" },
5124 +{ PK11_R_TOKEN_PIN_NOT_PROVIDED,       "token PIN required but not provided" },
5125 +{ PK11_R_MISSING_OBJECT_LABEL,         "missing mandatory 'object' keyword" },
5126 +{ PK11_R_TOKEN_ATTRS_DO_NOT_MATCH,     "token attrs provided do not match" },
5127 +{ PK11_R_PRIV_KEY_NOT_FOUND,           "private key not found in keystore" },
5128 +{ PK11_R_NO_OBJECT_FOUND,              "specified object not found" },
5129 +{ PK11_R_PIN_CACHING_POLICY_INVALID,   "PIN set but caching policy invalid" },
5130 +{ PK11_R_SYSCONF_FAILED,               "sysconf() failed" },
5131 +{ PK11_R_MMAP_FAILED,                  "mmap() failed" },
5132 +{ PK11_R_PRIV_PROC_LOCK_MEMORY_MISSING,        "PROC_LOCK_MEMORY privilege missing" },
5133 +{ PK11_R_MLOCK_FAILED,                 "mlock() failed" },
5134 +{ PK11_R_FORK_FAILED,                  "fork() failed" },
5135 +{ 0,   NULL}
5137 +#endif /* OPENSSL_NO_ERR */
5139 +static int pk11_lib_error_code = 0;
5140 +static int pk11_error_init = 1;
5142 +static void
5143 +ERR_load_pk11_strings(void)
5144 +       {
5145 +       if (pk11_lib_error_code == 0)
5146 +               pk11_lib_error_code = ERR_get_next_error_library();
5148 +       if (pk11_error_init)
5149 +               {
5150 +               pk11_error_init = 0;
5151 +#ifndef OPENSSL_NO_ERR
5152 +               ERR_load_strings(pk11_lib_error_code, pk11_str_functs);
5153 +               ERR_load_strings(pk11_lib_error_code, pk11_str_reasons);
5154 +#endif
5155 +               }
5158 +static void
5159 +ERR_unload_pk11_strings(void)
5160 +       {
5161 +       if (pk11_error_init == 0)
5162 +               {
5163 +#ifndef OPENSSL_NO_ERR
5164 +               ERR_unload_strings(pk11_lib_error_code, pk11_str_functs);
5165 +               ERR_unload_strings(pk11_lib_error_code, pk11_str_reasons);
5166 +#endif
5167 +               pk11_error_init = 1;
5168 +               }
5171 +void
5172 +ERR_pk11_error(int function, int reason, char *file, int line)
5174 +       if (pk11_lib_error_code == 0)
5175 +               pk11_lib_error_code = ERR_get_next_error_library();
5176 +       ERR_PUT_error(pk11_lib_error_code, function, reason, file, line);
5179 +void
5180 +PK11err_add_data(int function, int reason, CK_RV rv)
5182 +       char tmp_buf[20];
5184 +       PK11err(function, reason);
5185 +       (void) BIO_snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
5186 +       ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
5188 Index: openssl/crypto/engine/hw_pk11_err.h
5189 diff -u /dev/null openssl/crypto/engine/hw_pk11_err.h:1.9.10.2
5190 --- /dev/null   Fri Jan  2 13:56:40 2015
5191 +++ openssl/crypto/engine/hw_pk11_err.h Fri Oct  4 14:45:25 2013
5192 @@ -0,0 +1,440 @@
5194 + * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
5195 + * Use is subject to license terms.
5196 + */
5199 + * This product includes software developed by the OpenSSL Project for
5200 + * use in the OpenSSL Toolkit (http://www.openssl.org/).
5201 + *
5202 + * This project also referenced hw_pkcs11-0.9.7b.patch written by
5203 + * Afchine Madjlessi.
5204 + */
5206 + * ====================================================================
5207 + * Copyright (c) 2000-2001 The OpenSSL Project.  All rights reserved.
5208 + *
5209 + * Redistribution and use in source and binary forms, with or without
5210 + * modification, are permitted provided that the following conditions
5211 + * are met:
5212 + *
5213 + * 1. Redistributions of source code must retain the above copyright
5214 + *    notice, this list of conditions and the following disclaimer.
5215 + *
5216 + * 2. Redistributions in binary form must reproduce the above copyright
5217 + *    notice, this list of conditions and the following disclaimer in
5218 + *    the documentation and/or other materials provided with the
5219 + *    distribution.
5220 + *
5221 + * 3. All advertising materials mentioning features or use of this
5222 + *    software must display the following acknowledgment:
5223 + *    "This product includes software developed by the OpenSSL Project
5224 + *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
5225 + *
5226 + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
5227 + *    endorse or promote products derived from this software without
5228 + *    prior written permission. For written permission, please contact
5229 + *    licensing@OpenSSL.org.
5230 + *
5231 + * 5. Products derived from this software may not be called "OpenSSL"
5232 + *    nor may "OpenSSL" appear in their names without prior written
5233 + *    permission of the OpenSSL Project.
5234 + *
5235 + * 6. Redistributions of any form whatsoever must retain the following
5236 + *    acknowledgment:
5237 + *    "This product includes software developed by the OpenSSL Project
5238 + *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
5239 + *
5240 + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
5241 + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
5242 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
5243 + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
5244 + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
5245 + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
5246 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
5247 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
5248 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
5249 + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
5250 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
5251 + * OF THE POSSIBILITY OF SUCH DAMAGE.
5252 + * ====================================================================
5253 + *
5254 + * This product includes cryptographic software written by Eric Young
5255 + * (eay@cryptsoft.com).  This product includes software written by Tim
5256 + * Hudson (tjh@cryptsoft.com).
5257 + *
5258 + */
5260 +#ifndef        HW_PK11_ERR_H
5261 +#define        HW_PK11_ERR_H
5263 +void ERR_pk11_error(int function, int reason, char *file, int line);
5264 +void PK11err_add_data(int function, int reason, CK_RV rv);
5265 +#define        PK11err(f, r)   ERR_pk11_error((f), (r), __FILE__, __LINE__)
5267 +/* Error codes for the PK11 functions. */
5269 +/* Function codes. */
5271 +#define        PK11_F_INIT                             100
5272 +#define        PK11_F_FINISH                           101
5273 +#define        PK11_F_DESTROY                          102
5274 +#define        PK11_F_CTRL                             103
5275 +#define        PK11_F_RSA_INIT                         104
5276 +#define        PK11_F_RSA_FINISH                       105
5277 +#define        PK11_F_GET_PUB_RSA_KEY                  106
5278 +#define        PK11_F_GET_PRIV_RSA_KEY                 107
5279 +#define        PK11_F_RSA_GEN_KEY                      108
5280 +#define        PK11_F_RSA_PUB_ENC                      109
5281 +#define        PK11_F_RSA_PRIV_ENC                     110
5282 +#define        PK11_F_RSA_PUB_DEC                      111
5283 +#define        PK11_F_RSA_PRIV_DEC                     112
5284 +#define        PK11_F_RSA_SIGN                         113
5285 +#define        PK11_F_RSA_VERIFY                       114
5286 +#define        PK11_F_RAND_ADD                         115
5287 +#define        PK11_F_RAND_BYTES                       116
5288 +#define        PK11_F_GET_SESSION                      117
5289 +#define        PK11_F_FREE_SESSION                     118
5290 +#define        PK11_F_LOAD_PUBKEY                      119
5291 +#define        PK11_F_LOAD_PRIVKEY                     120
5292 +#define        PK11_F_RSA_PUB_ENC_LOW                  121
5293 +#define        PK11_F_RSA_PRIV_ENC_LOW                 122
5294 +#define        PK11_F_RSA_PUB_DEC_LOW                  123
5295 +#define        PK11_F_RSA_PRIV_DEC_LOW                 124
5296 +#define        PK11_F_DSA_SIGN                         125
5297 +#define        PK11_F_DSA_VERIFY                       126
5298 +#define        PK11_F_DSA_INIT                         127
5299 +#define        PK11_F_DSA_FINISH                       128
5300 +#define        PK11_F_GET_PUB_DSA_KEY                  129
5301 +#define        PK11_F_GET_PRIV_DSA_KEY                 130
5302 +#define        PK11_F_DH_INIT                          131
5303 +#define        PK11_F_DH_FINISH                        132
5304 +#define        PK11_F_MOD_EXP_DH                       133
5305 +#define        PK11_F_GET_DH_KEY                       134
5306 +#define        PK11_F_FREE_ALL_SESSIONS                135
5307 +#define        PK11_F_SETUP_SESSION                    136
5308 +#define        PK11_F_DESTROY_OBJECT                   137
5309 +#define        PK11_F_CIPHER_INIT                      138
5310 +#define        PK11_F_CIPHER_DO_CIPHER                 139
5311 +#define        PK11_F_GET_CIPHER_KEY                   140
5312 +#define        PK11_F_DIGEST_INIT                      141
5313 +#define        PK11_F_DIGEST_UPDATE                    142
5314 +#define        PK11_F_DIGEST_FINAL                     143
5315 +#define        PK11_F_CHOOSE_SLOT                      144
5316 +#define        PK11_F_CIPHER_FINAL                     145
5317 +#define        PK11_F_LIBRARY_INIT                     146
5318 +#define        PK11_F_LOAD                             147
5319 +#define        PK11_F_DH_GEN_KEY                       148
5320 +#define        PK11_F_DH_COMP_KEY                      149
5321 +#define        PK11_F_DIGEST_COPY                      150
5322 +#define        PK11_F_CIPHER_CLEANUP                   151
5323 +#define        PK11_F_ACTIVE_ADD                       152
5324 +#define        PK11_F_ACTIVE_DELETE                    153
5325 +#define        PK11_F_CHECK_HW_MECHANISMS              154
5326 +#define        PK11_F_INIT_SYMMETRIC                   155
5327 +#define        PK11_F_ADD_AES_CTR_NIDS                 156
5328 +#define        PK11_F_INIT_ALL_LOCKS                   157
5329 +#define        PK11_F_RETURN_SESSION                   158
5330 +#define        PK11_F_GET_PIN                          159
5331 +#define        PK11_F_FIND_ONE_OBJECT                  160
5332 +#define        PK11_F_CHECK_TOKEN_ATTRS                161
5333 +#define        PK11_F_CACHE_PIN                        162
5334 +#define        PK11_F_MLOCK_PIN_IN_MEMORY              163
5335 +#define        PK11_F_TOKEN_LOGIN                      164
5336 +#define        PK11_F_TOKEN_RELOGIN                    165
5337 +#define        PK11_F_RUN_ASKPASS                      166
5339 +/* Reason codes. */
5340 +#define        PK11_R_ALREADY_LOADED                   100
5341 +#define        PK11_R_DSO_FAILURE                      101
5342 +#define        PK11_R_NOT_LOADED                       102
5343 +#define        PK11_R_PASSED_NULL_PARAMETER            103
5344 +#define        PK11_R_COMMAND_NOT_IMPLEMENTED          104
5345 +#define        PK11_R_INITIALIZE                       105
5346 +#define        PK11_R_FINALIZE                         106
5347 +#define        PK11_R_GETINFO                          107
5348 +#define        PK11_R_GETSLOTLIST                      108
5349 +#define        PK11_R_NO_MODULUS_OR_NO_EXPONENT        109
5350 +#define        PK11_R_ATTRIBUT_SENSITIVE_OR_INVALID    110
5351 +#define        PK11_R_GETATTRIBUTVALUE                 111
5352 +#define        PK11_R_NO_MODULUS                       112
5353 +#define        PK11_R_NO_EXPONENT                      113
5354 +#define        PK11_R_FINDOBJECTSINIT                  114
5355 +#define        PK11_R_FINDOBJECTS                      115
5356 +#define        PK11_R_FINDOBJECTSFINAL                 116
5357 +#define        PK11_R_CREATEOBJECT                     118
5358 +#define        PK11_R_DESTROYOBJECT                    119
5359 +#define        PK11_R_OPENSESSION                      120
5360 +#define        PK11_R_CLOSESESSION                     121
5361 +#define        PK11_R_ENCRYPTINIT                      122
5362 +#define        PK11_R_ENCRYPT                          123
5363 +#define        PK11_R_SIGNINIT                         124
5364 +#define        PK11_R_SIGN                             125
5365 +#define        PK11_R_DECRYPTINIT                      126
5366 +#define        PK11_R_DECRYPT                          127
5367 +#define        PK11_R_VERIFYINIT                       128
5368 +#define        PK11_R_VERIFY                           129
5369 +#define        PK11_R_VERIFYRECOVERINIT                130
5370 +#define        PK11_R_VERIFYRECOVER                    131
5371 +#define        PK11_R_GEN_KEY                          132
5372 +#define        PK11_R_SEEDRANDOM                       133
5373 +#define        PK11_R_GENERATERANDOM                   134
5374 +#define        PK11_R_INVALID_MESSAGE_LENGTH           135
5375 +#define        PK11_R_UNKNOWN_ALGORITHM_TYPE           136
5376 +#define        PK11_R_UNKNOWN_ASN1_OBJECT_ID           137
5377 +#define        PK11_R_UNKNOWN_PADDING_TYPE             138
5378 +#define        PK11_R_PADDING_CHECK_FAILED             139
5379 +#define        PK11_R_DIGEST_TOO_BIG                   140
5380 +#define        PK11_R_MALLOC_FAILURE                   141
5381 +#define        PK11_R_CTRL_COMMAND_NOT_IMPLEMENTED     142
5382 +#define        PK11_R_DATA_GREATER_THAN_MOD_LEN        143
5383 +#define        PK11_R_DATA_TOO_LARGE_FOR_MODULUS       144
5384 +#define        PK11_R_MISSING_KEY_COMPONENT            145
5385 +#define        PK11_R_INVALID_SIGNATURE_LENGTH         146
5386 +#define        PK11_R_INVALID_DSA_SIGNATURE_R          147
5387 +#define        PK11_R_INVALID_DSA_SIGNATURE_S          148
5388 +#define        PK11_R_INCONSISTENT_KEY                 149
5389 +#define        PK11_R_ENCRYPTUPDATE                    150
5390 +#define        PK11_R_DECRYPTUPDATE                    151
5391 +#define        PK11_R_DIGESTINIT                       152
5392 +#define        PK11_R_DIGESTUPDATE                     153
5393 +#define        PK11_R_DIGESTFINAL                      154
5394 +#define        PK11_R_ENCRYPTFINAL                     155
5395 +#define        PK11_R_DECRYPTFINAL                     156
5396 +#define        PK11_R_NO_PRNG_SUPPORT                  157
5397 +#define        PK11_R_GETTOKENINFO                     158
5398 +#define        PK11_R_DERIVEKEY                        159
5399 +#define        PK11_R_GET_OPERATION_STATE              160
5400 +#define        PK11_R_SET_OPERATION_STATE              161
5401 +#define        PK11_R_INVALID_HANDLE                   162
5402 +#define        PK11_R_KEY_OR_IV_LEN_PROBLEM            163
5403 +#define        PK11_R_INVALID_OPERATION_TYPE           164
5404 +#define        PK11_R_ADD_NID_FAILED                   165
5405 +#define        PK11_R_ATFORK_FAILED                    166
5407 +#define        PK11_R_TOKEN_LOGIN_FAILED               167
5408 +#define        PK11_R_MORE_THAN_ONE_OBJECT_FOUND       168
5409 +#define        PK11_R_INVALID_PKCS11_URI               169
5410 +#define        PK11_R_COULD_NOT_READ_PIN               170
5411 +#define        PK11_R_COULD_NOT_OPEN_COMMAND           171
5412 +#define        PK11_R_PIPE_FAILED                      172
5413 +#define        PK11_R_PIN_NOT_READ_FROM_COMMAND        173
5414 +#define        PK11_R_BAD_PASSPHRASE_SPEC              174
5415 +#define        PK11_R_TOKEN_NOT_INITIALIZED            175
5416 +#define        PK11_R_TOKEN_PIN_NOT_SET                176
5417 +#define        PK11_R_TOKEN_PIN_NOT_PROVIDED           177
5418 +#define        PK11_R_MISSING_OBJECT_LABEL             178
5419 +#define        PK11_R_TOKEN_ATTRS_DO_NOT_MATCH         179
5420 +#define        PK11_R_PRIV_KEY_NOT_FOUND               180
5421 +#define        PK11_R_NO_OBJECT_FOUND                  181
5422 +#define        PK11_R_PIN_CACHING_POLICY_INVALID       182
5423 +#define        PK11_R_SYSCONF_FAILED                   183
5424 +#define        PK11_R_MMAP_FAILED                      183
5425 +#define        PK11_R_PRIV_PROC_LOCK_MEMORY_MISSING    184
5426 +#define        PK11_R_MLOCK_FAILED                     185
5427 +#define        PK11_R_FORK_FAILED                      186
5429 +/* max byte length of a symetric key we support */
5430 +#define        PK11_KEY_LEN_MAX                        32
5432 +#ifdef NOPTHREADS
5434 + * CRYPTO_LOCK_PK11_ENGINE lock is primarily used for the protection of the
5435 + * free_session list and active_list but generally serves as a global
5436 + * per-process lock for the whole engine.
5437 + *
5438 + * We reuse CRYPTO_LOCK_EC lock (which is defined in OpenSSL for EC method) as
5439 + * the global engine lock. This is not optimal w.r.t. performance but
5440 + * it's safe.
5441 + */
5442 +#define CRYPTO_LOCK_PK11_ENGINE        CRYPTO_LOCK_EC
5443 +#endif
5446 + * This structure encapsulates all reusable information for a PKCS#11
5447 + * session. A list of these objects is created on behalf of the
5448 + * calling application using an on-demand method. Each operation
5449 + * type (see PK11_OPTYPE below) has its own per-process list.
5450 + * Each of the lists is basically a cache for faster PKCS#11 object
5451 + * access to avoid expensive C_Find{,Init,Final}Object() calls.
5452 + *
5453 + * When a new request comes in, an object will be taken from the list
5454 + * (if there is one) or a new one is created to handle the request
5455 + * (if the list is empty). See pk11_get_session() on how it is done.
5456 + */
5457 +typedef struct PK11_st_SESSION
5458 +       {
5459 +       struct PK11_st_SESSION  *next;
5460 +       CK_SESSION_HANDLE       session;        /* PK11 session handle */
5461 +       pid_t                   pid;            /* Current process ID */
5462 +       CK_BBOOL                pub_persistent; /* is pub key in keystore? */
5463 +       CK_BBOOL                priv_persistent;/* is priv key in keystore? */
5464 +       union
5465 +               {
5466 +#ifndef OPENSSL_NO_RSA
5467 +               struct
5468 +                       {
5469 +                       CK_OBJECT_HANDLE        rsa_pub_key; /* pub handle */
5470 +                       CK_OBJECT_HANDLE        rsa_priv_key; /* priv handle */
5471 +                       RSA                     *rsa_pub; /* pub key addr */
5472 +                       BIGNUM                  *rsa_n_num; /* pub modulus */
5473 +                       BIGNUM                  *rsa_e_num; /* pub exponent */
5474 +                       RSA                     *rsa_priv; /* priv key addr */
5475 +                       BIGNUM                  *rsa_pn_num; /* pub modulus */
5476 +                       BIGNUM                  *rsa_pe_num; /* pub exponent */
5477 +                       BIGNUM                  *rsa_d_num; /* priv exponent */
5478 +                       } u_RSA;
5479 +#endif /* OPENSSL_NO_RSA */
5480 +#ifndef OPENSSL_NO_DSA
5481 +               struct
5482 +                       {
5483 +                       CK_OBJECT_HANDLE        dsa_pub_key; /* pub handle */
5484 +                       CK_OBJECT_HANDLE        dsa_priv_key; /* priv handle */
5485 +                       DSA                     *dsa_pub; /* pub key addr */
5486 +                       BIGNUM                  *dsa_pub_num; /* pub key */
5487 +                       DSA                     *dsa_priv; /* priv key addr */
5488 +                       BIGNUM                  *dsa_priv_num; /* priv key */
5489 +                       } u_DSA;
5490 +#endif /* OPENSSL_NO_DSA */
5491 +#ifndef OPENSSL_NO_DH
5492 +               struct
5493 +                       {
5494 +                       CK_OBJECT_HANDLE        dh_key; /* key handle */
5495 +                       DH                      *dh; /* dh key addr */
5496 +                       BIGNUM                  *dh_priv_num; /* priv dh key */
5497 +                       } u_DH;
5498 +#endif /* OPENSSL_NO_DH */
5499 +               struct
5500 +                       {
5501 +                       CK_OBJECT_HANDLE        cipher_key; /* key handle */
5502 +                       unsigned char           key[PK11_KEY_LEN_MAX];
5503 +                       int                     key_len; /* priv key len */
5504 +                       int                     encrypt; /* 1/0 enc/decr */
5505 +                       } u_cipher;
5506 +               } opdata_u;
5507 +       } PK11_SESSION;
5509 +#define        opdata_rsa_pub_key      opdata_u.u_RSA.rsa_pub_key
5510 +#define        opdata_rsa_priv_key     opdata_u.u_RSA.rsa_priv_key
5511 +#define        opdata_rsa_pub          opdata_u.u_RSA.rsa_pub
5512 +#define        opdata_rsa_priv         opdata_u.u_RSA.rsa_priv
5513 +#define        opdata_rsa_n_num        opdata_u.u_RSA.rsa_n_num
5514 +#define        opdata_rsa_e_num        opdata_u.u_RSA.rsa_e_num
5515 +#define        opdata_rsa_pn_num       opdata_u.u_RSA.rsa_pn_num
5516 +#define        opdata_rsa_pe_num       opdata_u.u_RSA.rsa_pe_num
5517 +#define        opdata_rsa_d_num        opdata_u.u_RSA.rsa_d_num
5518 +#define        opdata_dsa_pub_key      opdata_u.u_DSA.dsa_pub_key
5519 +#define        opdata_dsa_priv_key     opdata_u.u_DSA.dsa_priv_key
5520 +#define        opdata_dsa_pub          opdata_u.u_DSA.dsa_pub
5521 +#define        opdata_dsa_pub_num      opdata_u.u_DSA.dsa_pub_num
5522 +#define        opdata_dsa_priv         opdata_u.u_DSA.dsa_priv
5523 +#define        opdata_dsa_priv_num     opdata_u.u_DSA.dsa_priv_num
5524 +#define        opdata_dh_key           opdata_u.u_DH.dh_key
5525 +#define        opdata_dh               opdata_u.u_DH.dh
5526 +#define        opdata_dh_priv_num      opdata_u.u_DH.dh_priv_num
5527 +#define        opdata_cipher_key       opdata_u.u_cipher.cipher_key
5528 +#define        opdata_key              opdata_u.u_cipher.key
5529 +#define        opdata_key_len          opdata_u.u_cipher.key_len
5530 +#define        opdata_encrypt          opdata_u.u_cipher.encrypt
5533 + * We have 3 different groups of operation types:
5534 + *   1) asymmetric operations
5535 + *   2) random operations
5536 + *   3) symmetric and digest operations
5537 + *
5538 + * This division into groups stems from the fact that it's common that hardware
5539 + * providers may support operations from one group only. For example, hardware
5540 + * providers on UltraSPARC T2, n2rng(7d), ncp(7d), and n2cp(7d), each support
5541 + * only a single group of operations.
5542 + *
5543 + * For every group a different slot can be chosen. That means that we must have
5544 + * at least 3 different lists of cached PKCS#11 sessions since sessions from
5545 + * different groups may be initialized in different slots.
5546 + *
5547 + * To provide locking granularity in multithreaded environment, the groups are
5548 + * further splitted into types with each type having a separate session cache.
5549 + */
5550 +typedef enum PK11_OPTYPE_ENUM
5551 +       {
5552 +       OP_RAND,
5553 +       OP_RSA,
5554 +       OP_DSA,
5555 +       OP_DH,
5556 +       OP_CIPHER,
5557 +       OP_DIGEST,
5558 +       OP_MAX
5559 +       } PK11_OPTYPE;
5562 + * This structure contains the heads of the lists forming the object caches
5563 + * and locks associated with the lists.
5564 + */
5565 +typedef struct PK11_st_CACHE
5566 +       {
5567 +       PK11_SESSION *head;
5568 +#ifndef NOPTHREADS
5569 +       pthread_mutex_t *lock;
5570 +#endif
5571 +       } PK11_CACHE;
5573 +/* structure for tracking handles of asymmetric key objects */
5574 +typedef struct PK11_active_st
5575 +       {
5576 +       CK_OBJECT_HANDLE h;
5577 +       unsigned int refcnt;
5578 +       struct PK11_active_st *prev;
5579 +       struct PK11_active_st *next;
5580 +       } PK11_active;
5582 +#ifndef NOPTHREADS
5583 +extern pthread_mutex_t *find_lock[];
5584 +#endif
5585 +extern PK11_active *active_list[];
5587 + * These variables are specific for the RSA keys by reference code. See
5588 + * hw_pk11_pub.c for explanation.
5589 + */
5590 +extern CK_FLAGS pubkey_token_flags;
5592 +#ifndef NOPTHREADS
5593 +#define        LOCK_OBJSTORE(alg_type) \
5594 +       OPENSSL_assert(pthread_mutex_lock(find_lock[alg_type]) == 0)
5595 +#define        UNLOCK_OBJSTORE(alg_type)       \
5596 +       OPENSSL_assert(pthread_mutex_unlock(find_lock[alg_type]) == 0)
5597 +#else
5598 +#define        LOCK_OBJSTORE(alg_type) \
5599 +       CRYPTO_w_lock(CRYPTO_LOCK_PK11_ENGINE)
5600 +#define        UNLOCK_OBJSTORE(alg_type)       \
5601 +       CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE)
5602 +#endif
5604 +extern PK11_SESSION *pk11_get_session(PK11_OPTYPE optype);
5605 +extern void pk11_return_session(PK11_SESSION *sp, PK11_OPTYPE optype);
5606 +extern int pk11_token_relogin(CK_SESSION_HANDLE session);
5608 +#ifndef OPENSSL_NO_RSA
5609 +extern int pk11_destroy_rsa_key_objects(PK11_SESSION *session);
5610 +extern int pk11_destroy_rsa_object_pub(PK11_SESSION *sp, CK_BBOOL uselock);
5611 +extern int pk11_destroy_rsa_object_priv(PK11_SESSION *sp, CK_BBOOL uselock);
5612 +extern EVP_PKEY *pk11_load_privkey(ENGINE *e, const char *pubkey_file,
5613 +       UI_METHOD *ui_method, void *callback_data);
5614 +extern EVP_PKEY *pk11_load_pubkey(ENGINE *e, const char *pubkey_file,
5615 +       UI_METHOD *ui_method, void *callback_data);
5616 +extern RSA_METHOD *PK11_RSA(void);
5617 +#endif /* OPENSSL_NO_RSA */
5618 +#ifndef OPENSSL_NO_DSA
5619 +extern int pk11_destroy_dsa_key_objects(PK11_SESSION *session);
5620 +extern int pk11_destroy_dsa_object_pub(PK11_SESSION *sp, CK_BBOOL uselock);
5621 +extern int pk11_destroy_dsa_object_priv(PK11_SESSION *sp, CK_BBOOL uselock);
5622 +extern DSA_METHOD *PK11_DSA(void);
5623 +#endif /* OPENSSL_NO_DSA */
5624 +#ifndef OPENSSL_NO_DH
5625 +extern int pk11_destroy_dh_key_objects(PK11_SESSION *session);
5626 +extern int pk11_destroy_dh_object(PK11_SESSION *sp, CK_BBOOL uselock);
5627 +extern DH_METHOD *PK11_DH(void);
5628 +#endif /* OPENSSL_NO_DH */
5630 +extern CK_FUNCTION_LIST_PTR pFuncList;
5632 +#endif /* HW_PK11_ERR_H */
5633 Index: openssl/crypto/engine/hw_pk11_pub.c
5634 diff -u /dev/null openssl/crypto/engine/hw_pk11_pub.c:1.32.4.7
5635 --- /dev/null   Fri Jan  2 13:56:40 2015
5636 +++ openssl/crypto/engine/hw_pk11_pub.c Fri Oct  4 14:45:25 2013
5637 @@ -0,0 +1,3556 @@
5639 + * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
5640 + * Use is subject to license terms.
5641 + */
5643 +/* crypto/engine/hw_pk11_pub.c */
5645 + * This product includes software developed by the OpenSSL Project for
5646 + * use in the OpenSSL Toolkit (http://www.openssl.org/).
5647 + *
5648 + * This project also referenced hw_pkcs11-0.9.7b.patch written by
5649 + * Afchine Madjlessi.
5650 + */
5652 + * ====================================================================
5653 + * Copyright (c) 2000-2001 The OpenSSL Project.  All rights reserved.
5654 + *
5655 + * Redistribution and use in source and binary forms, with or without
5656 + * modification, are permitted provided that the following conditions
5657 + * are met:
5658 + *
5659 + * 1. Redistributions of source code must retain the above copyright
5660 + *    notice, this list of conditions and the following disclaimer.
5661 + *
5662 + * 2. Redistributions in binary form must reproduce the above copyright
5663 + *    notice, this list of conditions and the following disclaimer in
5664 + *    the documentation and/or other materials provided with the
5665 + *    distribution.
5666 + *
5667 + * 3. All advertising materials mentioning features or use of this
5668 + *    software must display the following acknowledgment:
5669 + *    "This product includes software developed by the OpenSSL Project
5670 + *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
5671 + *
5672 + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
5673 + *    endorse or promote products derived from this software without
5674 + *    prior written permission. For written permission, please contact
5675 + *    licensing@OpenSSL.org.
5676 + *
5677 + * 5. Products derived from this software may not be called "OpenSSL"
5678 + *    nor may "OpenSSL" appear in their names without prior written
5679 + *    permission of the OpenSSL Project.
5680 + *
5681 + * 6. Redistributions of any form whatsoever must retain the following
5682 + *    acknowledgment:
5683 + *    "This product includes software developed by the OpenSSL Project
5684 + *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
5685 + *
5686 + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
5687 + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
5688 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
5689 + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
5690 + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
5691 + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
5692 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
5693 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
5694 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
5695 + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
5696 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
5697 + * OF THE POSSIBILITY OF SUCH DAMAGE.
5698 + * ====================================================================
5699 + *
5700 + * This product includes cryptographic software written by Eric Young
5701 + * (eay@cryptsoft.com).  This product includes software written by Tim
5702 + * Hudson (tjh@cryptsoft.com).
5703 + *
5704 + */
5706 +#include <stdio.h>
5707 +#include <stdlib.h>
5708 +#include <string.h>
5709 +#include <sys/types.h>
5711 +#include <openssl/e_os2.h>
5712 +#include <openssl/crypto.h>
5713 +#include <cryptlib.h>
5714 +#include <openssl/engine.h>
5715 +#include <openssl/dso.h>
5716 +#include <openssl/err.h>
5717 +#include <openssl/bn.h>
5718 +#include <openssl/pem.h>
5719 +#ifndef OPENSSL_NO_RSA
5720 +#include <openssl/rsa.h>
5721 +#endif /* OPENSSL_NO_RSA */
5722 +#ifndef OPENSSL_NO_DSA
5723 +#include <openssl/dsa.h>
5724 +#endif /* OPENSSL_NO_DSA */
5725 +#ifndef OPENSSL_NO_DH
5726 +#include <openssl/dh.h>
5727 +#endif /* OPENSSL_NO_DH */
5728 +#include <openssl/rand.h>
5729 +#include <openssl/objects.h>
5730 +#include <openssl/x509.h>
5732 +#ifdef OPENSSL_SYS_WIN32
5733 +#define NOPTHREADS
5734 +typedef int pid_t;
5735 +#define HAVE_GETPASSPHRASE
5736 +static char *getpassphrase(const char *prompt);
5737 +#ifndef NULL_PTR
5738 +#define NULL_PTR NULL
5739 +#endif
5740 +#define CK_DEFINE_FUNCTION(returnType, name) \
5741 +       returnType __declspec(dllexport) name
5742 +#define CK_DECLARE_FUNCTION(returnType, name) \
5743 +       returnType __declspec(dllimport) name
5744 +#define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
5745 +       returnType __declspec(dllimport) (* name)
5746 +#else
5747 +#include <unistd.h>
5748 +#endif
5750 +#ifndef NOPTHREADS
5751 +#include <pthread.h>
5752 +#endif
5754 +#ifndef OPENSSL_NO_HW
5755 +#ifndef OPENSSL_NO_HW_PK11
5756 +#ifndef OPENSSL_NO_HW_PK11CA
5758 +#ifdef OPENSSL_SYS_WIN32
5759 +#pragma pack(push, cryptoki, 1)
5760 +#include "cryptoki.h"
5761 +#include "pkcs11.h"
5762 +#pragma pack(pop, cryptoki)
5763 +#else
5764 +#include "cryptoki.h"
5765 +#include "pkcs11.h"
5766 +#endif
5767 +#include "hw_pk11ca.h"
5768 +#include "hw_pk11_err.h"
5770 +static CK_BBOOL pk11_login_done = CK_FALSE;
5771 +extern CK_SLOT_ID pubkey_SLOTID;
5772 +#ifndef NOPTHREADS
5773 +extern pthread_mutex_t *token_lock;
5774 +#endif
5776 +#if !(defined(HAVE_GETPASSPHRASE) || (defined (__SVR4) && defined (__sun)))
5777 +#define getpassphrase(x)       getpass(x)
5778 +#endif
5780 +#ifndef OPENSSL_NO_RSA
5781 +/* RSA stuff */
5782 +static int pk11_RSA_public_encrypt(int flen, const unsigned char *from,
5783 +       unsigned char *to, RSA *rsa, int padding);
5784 +static int pk11_RSA_private_encrypt(int flen, const unsigned char *from,
5785 +       unsigned char *to, RSA *rsa, int padding);
5786 +static int pk11_RSA_public_decrypt(int flen, const unsigned char *from,
5787 +       unsigned char *to, RSA *rsa, int padding);
5788 +static int pk11_RSA_private_decrypt(int flen, const unsigned char *from,
5789 +       unsigned char *to, RSA *rsa, int padding);
5790 +static int pk11_RSA_init(RSA *rsa);
5791 +static int pk11_RSA_finish(RSA *rsa);
5792 +static int pk11_RSA_sign(int type, const unsigned char *m, unsigned int m_len,
5793 +       unsigned char *sigret, unsigned int *siglen, const RSA *rsa);
5794 +#if OPENSSL_VERSION_NUMBER < 0x10000000L
5795 +static int pk11_RSA_verify(int dtype, const unsigned char *m,
5796 +       unsigned int m_len, unsigned char *sigbuf, unsigned int siglen,
5797 +       const RSA *rsa);
5798 +#else
5799 +static int pk11_RSA_verify(int dtype, const unsigned char *m,
5800 +       unsigned int m_len, const unsigned char *sigbuf, unsigned int siglen,
5801 +       const RSA *rsa);
5802 +#endif
5803 +EVP_PKEY *pk11_load_privkey(ENGINE*, const char *privkey_file,
5804 +       UI_METHOD *ui_method, void *callback_data);
5805 +EVP_PKEY *pk11_load_pubkey(ENGINE*, const char *pubkey_file,
5806 +       UI_METHOD *ui_method, void *callback_data);
5808 +static int pk11_RSA_public_encrypt_low(int flen, const unsigned char *from,
5809 +       unsigned char *to, RSA *rsa);
5810 +static int pk11_RSA_private_encrypt_low(int flen, const unsigned char *from,
5811 +       unsigned char *to, RSA *rsa);
5812 +static int pk11_RSA_public_decrypt_low(int flen, const unsigned char *from,
5813 +       unsigned char *to, RSA *rsa);
5814 +static int pk11_RSA_private_decrypt_low(int flen, const unsigned char *from,
5815 +       unsigned char *to, RSA *rsa);
5817 +static CK_OBJECT_HANDLE pk11_get_public_rsa_key(RSA* rsa, RSA** key_ptr,
5818 +       BIGNUM **rsa_n_num, BIGNUM **rsa_e_num, CK_SESSION_HANDLE session);
5819 +static CK_OBJECT_HANDLE pk11_get_private_rsa_key(RSA* rsa, RSA** key_ptr,
5820 +       BIGNUM **rsa_d_num, BIGNUM **rsa_n_num, BIGNUM **rsa_e_num,
5821 +       CK_SESSION_HANDLE session);
5823 +static int check_new_rsa_key_pub(PK11_SESSION *sp, const RSA *rsa);
5824 +static int check_new_rsa_key_priv(PK11_SESSION *sp, const RSA *rsa);
5825 +#endif
5827 +/* DSA stuff */
5828 +#ifndef OPENSSL_NO_DSA
5829 +static int pk11_DSA_init(DSA *dsa);
5830 +static int pk11_DSA_finish(DSA *dsa);
5831 +static DSA_SIG *pk11_dsa_do_sign(const unsigned char *dgst, int dlen,
5832 +       DSA *dsa);
5833 +static int pk11_dsa_do_verify(const unsigned char *dgst, int dgst_len,
5834 +       DSA_SIG *sig, DSA *dsa);
5836 +static CK_OBJECT_HANDLE pk11_get_public_dsa_key(DSA* dsa, DSA **key_ptr,
5837 +       BIGNUM **dsa_pub_num, CK_SESSION_HANDLE session);
5838 +static CK_OBJECT_HANDLE pk11_get_private_dsa_key(DSA* dsa, DSA **key_ptr,
5839 +       BIGNUM **dsa_priv_num, CK_SESSION_HANDLE session);
5841 +static int check_new_dsa_key_pub(PK11_SESSION *sp, DSA *dsa);
5842 +static int check_new_dsa_key_priv(PK11_SESSION *sp, DSA *dsa);
5843 +#endif
5845 +/* DH stuff */
5846 +#ifndef OPENSSL_NO_DH
5847 +static int pk11_DH_init(DH *dh);
5848 +static int pk11_DH_finish(DH *dh);
5849 +static int pk11_DH_generate_key(DH *dh);
5850 +static int pk11_DH_compute_key(unsigned char *key,
5851 +       const BIGNUM *pub_key, DH *dh);
5853 +static CK_OBJECT_HANDLE pk11_get_dh_key(DH* dh, DH **key_ptr,
5854 +       BIGNUM **priv_key, CK_SESSION_HANDLE session);
5856 +static int check_new_dh_key(PK11_SESSION *sp, DH *dh);
5857 +#endif
5859 +static int find_one_object(PK11_OPTYPE op, CK_SESSION_HANDLE s,
5860 +       CK_ATTRIBUTE_PTR ptempl, CK_ULONG nattr, CK_OBJECT_HANDLE_PTR pkey);
5861 +static int init_template_value(BIGNUM *bn, CK_VOID_PTR *pValue,
5862 +       CK_ULONG *ulValueLen);
5863 +static void attr_to_BN(CK_ATTRIBUTE_PTR attr, CK_BYTE attr_data[], BIGNUM **bn);
5865 +static int pk11_token_login(CK_SESSION_HANDLE session, CK_BBOOL *login_done,
5866 +       CK_BBOOL is_private);
5868 +/* Read mode string to be used for fopen() */
5869 +#if SOLARIS_OPENSSL
5870 +static char *read_mode_flags = "rF";
5871 +#else
5872 +static char *read_mode_flags = "r";
5873 +#endif
5876 + * increment/create reference for an asymmetric key handle via active list
5877 + * manipulation. If active list operation fails, unlock (if locked), set error
5878 + * variable and jump to the specified label.
5879 + */
5880 +#define        KEY_HANDLE_REFHOLD(key_handle, alg_type, unlock, var, label)    \
5881 +       {                                                               \
5882 +       if (pk11_active_add(key_handle, alg_type) < 0)                  \
5883 +               {                                                       \
5884 +               var = TRUE;                                             \
5885 +               if (unlock)                                             \
5886 +                       UNLOCK_OBJSTORE(alg_type);                      \
5887 +               goto label;                                             \
5888 +               }                                                       \
5889 +       }
5892 + * Find active list entry according to object handle and return pointer to the
5893 + * entry otherwise return NULL.
5894 + *
5895 + * This function presumes it is called with lock protecting the active list
5896 + * held.
5897 + */
5898 +static PK11_active *pk11_active_find(CK_OBJECT_HANDLE h, PK11_OPTYPE type)
5899 +       {
5900 +       PK11_active *entry;
5902 +       for (entry = active_list[type]; entry != NULL; entry = entry->next)
5903 +               if (entry->h == h)
5904 +                       return (entry);
5906 +       return (NULL);
5907 +       }
5910 + * Search for an entry in the active list using PKCS#11 object handle as a
5911 + * search key and return refcnt of the found/created entry or -1 in case of
5912 + * failure.
5913 + *
5914 + * This function presumes it is called with lock protecting the active list
5915 + * held.
5916 + */
5917 +int
5918 +pk11_active_add(CK_OBJECT_HANDLE h, PK11_OPTYPE type)
5919 +       {
5920 +       PK11_active *entry = NULL;
5922 +       if (h == CK_INVALID_HANDLE)
5923 +               {
5924 +               PK11err(PK11_F_ACTIVE_ADD, PK11_R_INVALID_HANDLE);
5925 +               return (-1);
5926 +               }
5928 +       /* search for entry in the active list */
5929 +       if ((entry = pk11_active_find(h, type)) != NULL)
5930 +               entry->refcnt++;
5931 +       else
5932 +               {
5933 +               /* not found, create new entry and add it to the list */
5934 +               entry = OPENSSL_malloc(sizeof (PK11_active));
5935 +               if (entry == NULL)
5936 +                       {
5937 +                       PK11err(PK11_F_ACTIVE_ADD, PK11_R_MALLOC_FAILURE);
5938 +                       return (-1);
5939 +                       }
5940 +               entry->h = h;
5941 +               entry->refcnt = 1;
5942 +               entry->prev = NULL;
5943 +               entry->next = NULL;
5944 +               /* connect the newly created entry to the list */
5945 +               if (active_list[type] == NULL)
5946 +                       active_list[type] = entry;
5947 +               else /* make the entry first in the list */
5948 +                       {
5949 +                       entry->next = active_list[type];
5950 +                       active_list[type]->prev = entry;
5951 +                       active_list[type] = entry;
5952 +                       }
5953 +               }
5955 +       return (entry->refcnt);
5956 +       }
5959 + * Remove active list entry from the list and free it.
5960 + *
5961 + * This function presumes it is called with lock protecting the active list
5962 + * held.
5963 + */
5964 +void
5965 +pk11_active_remove(PK11_active *entry, PK11_OPTYPE type)
5966 +       {
5967 +       PK11_active *prev_entry;
5969 +       /* remove the entry from the list and free it */
5970 +       if ((prev_entry = entry->prev) != NULL)
5971 +               {
5972 +               prev_entry->next = entry->next;
5973 +               if (entry->next != NULL)
5974 +                       entry->next->prev = prev_entry;
5975 +               }
5976 +       else
5977 +               {
5978 +               active_list[type] = entry->next;
5979 +               /* we were the first but not the only one */
5980 +               if (entry->next != NULL)
5981 +                       entry->next->prev = NULL;
5982 +               }
5984 +       /* sanitization */
5985 +       entry->h = CK_INVALID_HANDLE;
5986 +       entry->prev = NULL;
5987 +       entry->next = NULL;
5988 +       OPENSSL_free(entry);
5989 +       }
5991 +/* Free all entries from the active list. */
5992 +void
5993 +pk11_free_active_list(PK11_OPTYPE type)
5994 +       {
5995 +       PK11_active *entry;
5997 +       /* only for asymmetric types since only they have C_Find* locks. */
5998 +       switch (type)
5999 +               {
6000 +               case OP_RSA:
6001 +               case OP_DSA:
6002 +               case OP_DH:
6003 +                       break;
6004 +               default:
6005 +                       return;
6006 +               }
6008 +       /* see find_lock array definition for more info on object locking */
6009 +       LOCK_OBJSTORE(type);
6010 +       while ((entry = active_list[type]) != NULL)
6011 +               pk11_active_remove(entry, type);
6012 +       UNLOCK_OBJSTORE(type);
6013 +       }
6016 + * Search for active list entry associated with given PKCS#11 object handle,
6017 + * decrement its refcnt and if it drops to 0, disconnect the entry and free it.
6018 + *
6019 + * Return 1 if the PKCS#11 object associated with the entry has no references,
6020 + * return 0 if there is at least one reference, -1 on error.
6021 + *
6022 + * This function presumes it is called with lock protecting the active list
6023 + * held.
6024 + */
6025 +int
6026 +pk11_active_delete(CK_OBJECT_HANDLE h, PK11_OPTYPE type)
6027 +       {
6028 +       PK11_active *entry = NULL;
6030 +       if ((entry = pk11_active_find(h, type)) == NULL)
6031 +               {
6032 +               PK11err(PK11_F_ACTIVE_DELETE, PK11_R_INVALID_HANDLE);
6033 +               return (-1);
6034 +               }
6036 +       OPENSSL_assert(entry->refcnt > 0);
6037 +       entry->refcnt--;
6038 +       if (entry->refcnt == 0)
6039 +               {
6040 +               pk11_active_remove(entry, type);
6041 +               return (1);
6042 +               }
6044 +       return (0);
6045 +       }
6047 +#ifndef OPENSSL_NO_RSA
6048 +/* Our internal RSA_METHOD that we provide pointers to */
6049 +static RSA_METHOD pk11_rsa =
6050 +       {
6051 +       "PKCS#11 RSA method",
6052 +       pk11_RSA_public_encrypt,                /* rsa_pub_encrypt */
6053 +       pk11_RSA_public_decrypt,                /* rsa_pub_decrypt */
6054 +       pk11_RSA_private_encrypt,               /* rsa_priv_encrypt */
6055 +       pk11_RSA_private_decrypt,               /* rsa_priv_decrypt */
6056 +       NULL,                                   /* rsa_mod_exp */
6057 +       NULL,                                   /* bn_mod_exp */
6058 +       pk11_RSA_init,                          /* init */
6059 +       pk11_RSA_finish,                        /* finish */
6060 +       RSA_FLAG_SIGN_VER,                      /* flags */
6061 +       NULL,                                   /* app_data */
6062 +       pk11_RSA_sign,                          /* rsa_sign */
6063 +       pk11_RSA_verify                         /* rsa_verify */
6064 +       };
6066 +RSA_METHOD *
6067 +PK11_RSA(void)
6068 +       {
6069 +       return (&pk11_rsa);
6070 +       }
6071 +#endif
6073 +#ifndef OPENSSL_NO_DSA
6074 +/* Our internal DSA_METHOD that we provide pointers to */
6075 +static DSA_METHOD pk11_dsa =
6076 +       {
6077 +       "PKCS#11 DSA method",
6078 +       pk11_dsa_do_sign,       /* dsa_do_sign */
6079 +       NULL,                   /* dsa_sign_setup */
6080 +       pk11_dsa_do_verify,     /* dsa_do_verify */
6081 +       NULL,                   /* dsa_mod_exp */
6082 +       NULL,                   /* bn_mod_exp */
6083 +       pk11_DSA_init,          /* init */
6084 +       pk11_DSA_finish,        /* finish */
6085 +       0,                      /* flags */
6086 +       NULL                    /* app_data */
6087 +       };
6089 +DSA_METHOD *
6090 +PK11_DSA(void)
6091 +       {
6092 +       return (&pk11_dsa);
6093 +       }
6094 +#endif
6096 +#ifndef OPENSSL_NO_DH
6098 + * PKCS #11 V2.20, section 11.2 specifies that the number of bytes needed for
6099 + * output buffer may somewhat exceed the precise number of bytes needed, but
6100 + * should not exceed it by a large amount. That may be caused, for example, by
6101 + * rounding it up to multiple of X in the underlying bignum library. 8 should be
6102 + * enough.
6103 + */
6104 +#define        DH_BUF_RESERVE  8
6106 +/* Our internal DH_METHOD that we provide pointers to */
6107 +static DH_METHOD pk11_dh =
6108 +       {
6109 +       "PKCS#11 DH method",
6110 +       pk11_DH_generate_key,   /* generate_key */
6111 +       pk11_DH_compute_key,    /* compute_key */
6112 +       NULL,                   /* bn_mod_exp */
6113 +       pk11_DH_init,           /* init */
6114 +       pk11_DH_finish,         /* finish */
6115 +       0,                      /* flags */
6116 +       NULL,                   /* app_data */
6117 +       NULL                    /* generate_params */
6118 +       };
6120 +DH_METHOD *
6121 +PK11_DH(void)
6122 +       {
6123 +       return (&pk11_dh);
6124 +       }
6125 +#endif
6127 +/* Size of an SSL signature: MD5+SHA1 */
6128 +#define        SSL_SIG_LENGTH          36
6130 +/* Lengths of DSA data and signature */
6131 +#define        DSA_DATA_LEN            20
6132 +#define        DSA_SIGNATURE_LEN       40
6134 +static CK_BBOOL mytrue = TRUE;
6135 +static CK_BBOOL myfalse = FALSE;
6137 +#ifndef OPENSSL_NO_RSA
6139 + * Similiar to OpenSSL to take advantage of the paddings. The goal is to
6140 + * support all paddings in this engine although PK11 library does not
6141 + * support all the paddings used in OpenSSL.
6142 + * The input errors should have been checked in the padding functions.
6143 + */
6144 +static int pk11_RSA_public_encrypt(int flen, const unsigned char *from,
6145 +               unsigned char *to, RSA *rsa, int padding)
6146 +       {
6147 +       int i, num = 0, r = -1;
6148 +       unsigned char *buf = NULL;
6150 +       num = BN_num_bytes(rsa->n);
6151 +       if ((buf = (unsigned char *)OPENSSL_malloc(num)) == NULL)
6152 +               {
6153 +               RSAerr(PK11_F_RSA_PUB_ENC, PK11_R_MALLOC_FAILURE);
6154 +               goto err;
6155 +               }
6157 +       switch (padding)
6158 +               {
6159 +       case RSA_PKCS1_PADDING:
6160 +               i = RSA_padding_add_PKCS1_type_2(buf, num, from, flen);
6161 +               break;
6162 +#ifndef OPENSSL_NO_SHA
6163 +       case RSA_PKCS1_OAEP_PADDING:
6164 +               i = RSA_padding_add_PKCS1_OAEP(buf, num, from, flen, NULL, 0);
6165 +               break;
6166 +#endif
6167 +       case RSA_SSLV23_PADDING:
6168 +               i = RSA_padding_add_SSLv23(buf, num, from, flen);
6169 +               break;
6170 +       case RSA_NO_PADDING:
6171 +               i = RSA_padding_add_none(buf, num, from, flen);
6172 +               break;
6173 +       default:
6174 +               RSAerr(PK11_F_RSA_PUB_ENC, PK11_R_UNKNOWN_PADDING_TYPE);
6175 +               goto err;
6176 +               }
6177 +       if (i <= 0) goto err;
6179 +       /* PK11 functions are called here */
6180 +       r = pk11_RSA_public_encrypt_low(num, buf, to, rsa);
6181 +err:
6182 +       if (buf != NULL)
6183 +               {
6184 +               OPENSSL_cleanse(buf, num);
6185 +               OPENSSL_free(buf);
6186 +               }
6187 +       return (r);
6188 +       }
6192 + * Similar to Openssl to take advantage of the paddings. The input errors
6193 + * should be catched in the padding functions
6194 + */
6195 +static int pk11_RSA_private_encrypt(int flen, const unsigned char *from,
6196 +       unsigned char *to, RSA *rsa, int padding)
6197 +       {
6198 +       int i, num = 0, r = -1;
6199 +       unsigned char *buf = NULL;
6201 +       num = BN_num_bytes(rsa->n);
6202 +       if ((buf = (unsigned char *)OPENSSL_malloc(num)) == NULL)
6203 +               {
6204 +               RSAerr(PK11_F_RSA_PRIV_ENC, PK11_R_MALLOC_FAILURE);
6205 +               goto err;
6206 +               }
6208 +       switch (padding)
6209 +               {
6210 +       case RSA_PKCS1_PADDING:
6211 +               i = RSA_padding_add_PKCS1_type_1(buf, num, from, flen);
6212 +               break;
6213 +       case RSA_NO_PADDING:
6214 +               i = RSA_padding_add_none(buf, num, from, flen);
6215 +               break;
6216 +       case RSA_SSLV23_PADDING:
6217 +       default:
6218 +               RSAerr(PK11_F_RSA_PRIV_ENC, PK11_R_UNKNOWN_PADDING_TYPE);
6219 +               goto err;
6220 +               }
6221 +       if (i <= 0) goto err;
6223 +       /* PK11 functions are called here */
6224 +       r = pk11_RSA_private_encrypt_low(num, buf, to, rsa);
6225 +err:
6226 +       if (buf != NULL)
6227 +               {
6228 +               OPENSSL_cleanse(buf, num);
6229 +               OPENSSL_free(buf);
6230 +               }
6231 +       return (r);
6232 +       }
6234 +/* Similar to OpenSSL code. Input errors are also checked here */
6235 +static int pk11_RSA_private_decrypt(int flen, const unsigned char *from,
6236 +       unsigned char *to, RSA *rsa, int padding)
6237 +       {
6238 +       BIGNUM f;
6239 +       int j, num = 0, r = -1;
6240 +       unsigned char *p;
6241 +       unsigned char *buf = NULL;
6243 +       BN_init(&f);
6245 +       num = BN_num_bytes(rsa->n);
6247 +       if ((buf = (unsigned char *)OPENSSL_malloc(num)) == NULL)
6248 +               {
6249 +               RSAerr(PK11_F_RSA_PRIV_DEC, PK11_R_MALLOC_FAILURE);
6250 +               goto err;
6251 +               }
6253 +       /*
6254 +        * This check was for equality but PGP does evil things
6255 +        * and chops off the top '0' bytes
6256 +        */
6257 +       if (flen > num)
6258 +               {
6259 +               RSAerr(PK11_F_RSA_PRIV_DEC,
6260 +                       PK11_R_DATA_GREATER_THAN_MOD_LEN);
6261 +               goto err;
6262 +               }
6264 +       /* make data into a big number */
6265 +       if (BN_bin2bn(from, (int)flen, &f) == NULL)
6266 +               goto err;
6268 +       if (BN_ucmp(&f, rsa->n) >= 0)
6269 +               {
6270 +               RSAerr(PK11_F_RSA_PRIV_DEC,
6271 +                       PK11_R_DATA_TOO_LARGE_FOR_MODULUS);
6272 +               goto err;
6273 +               }
6275 +       /* PK11 functions are called here */
6276 +       r = pk11_RSA_private_decrypt_low(flen, from, buf, rsa);
6278 +       /*
6279 +        * PK11 CKM_RSA_X_509 mechanism pads 0's at the beginning.
6280 +        * Needs to skip these 0's paddings here.
6281 +        */
6282 +       for (j = 0; j < r; j++)
6283 +               if (buf[j] != 0)
6284 +                       break;
6286 +       p = buf + j;
6287 +       j = r - j;  /* j is only used with no-padding mode */
6289 +       switch (padding)
6290 +               {
6291 +       case RSA_PKCS1_PADDING:
6292 +               r = RSA_padding_check_PKCS1_type_2(to, num, p, j, num);
6293 +               break;
6294 +#ifndef OPENSSL_NO_SHA
6295 +       case RSA_PKCS1_OAEP_PADDING:
6296 +               r = RSA_padding_check_PKCS1_OAEP(to, num, p, j, num, NULL, 0);
6297 +               break;
6298 +#endif
6299 +       case RSA_SSLV23_PADDING:
6300 +               r = RSA_padding_check_SSLv23(to, num, p, j, num);
6301 +               break;
6302 +       case RSA_NO_PADDING:
6303 +               r = RSA_padding_check_none(to, num, p, j, num);
6304 +               break;
6305 +       default:
6306 +               RSAerr(PK11_F_RSA_PRIV_DEC, PK11_R_UNKNOWN_PADDING_TYPE);
6307 +               goto err;
6308 +               }
6309 +       if (r < 0)
6310 +               RSAerr(PK11_F_RSA_PRIV_DEC, PK11_R_PADDING_CHECK_FAILED);
6312 +err:
6313 +       BN_clear_free(&f);
6314 +       if (buf != NULL)
6315 +               {
6316 +               OPENSSL_cleanse(buf, num);
6317 +               OPENSSL_free(buf);
6318 +               }
6319 +       return (r);
6320 +       }
6322 +/* Similar to OpenSSL code. Input errors are also checked here */
6323 +static int pk11_RSA_public_decrypt(int flen, const unsigned char *from,
6324 +       unsigned char *to, RSA *rsa, int padding)
6325 +       {
6326 +       BIGNUM f;
6327 +       int i, num = 0, r = -1;
6328 +       unsigned char *p;
6329 +       unsigned char *buf = NULL;
6331 +       BN_init(&f);
6332 +       num = BN_num_bytes(rsa->n);
6333 +       buf = (unsigned char *)OPENSSL_malloc(num);
6334 +       if (buf == NULL)
6335 +               {
6336 +               RSAerr(PK11_F_RSA_PUB_DEC, PK11_R_MALLOC_FAILURE);
6337 +               goto err;
6338 +               }
6340 +       /*
6341 +        * This check was for equality but PGP does evil things
6342 +        * and chops off the top '0' bytes
6343 +        */
6344 +       if (flen > num)
6345 +               {
6346 +               RSAerr(PK11_F_RSA_PUB_DEC, PK11_R_DATA_GREATER_THAN_MOD_LEN);
6347 +               goto err;
6348 +               }
6350 +       if (BN_bin2bn(from, flen, &f) == NULL)
6351 +               goto err;
6353 +       if (BN_ucmp(&f, rsa->n) >= 0)
6354 +               {
6355 +               RSAerr(PK11_F_RSA_PUB_DEC,
6356 +                       PK11_R_DATA_TOO_LARGE_FOR_MODULUS);
6357 +               goto err;
6358 +               }
6360 +       /* PK11 functions are called here */
6361 +       r = pk11_RSA_public_decrypt_low(flen, from, buf, rsa);
6363 +       /*
6364 +        * PK11 CKM_RSA_X_509 mechanism pads 0's at the beginning.
6365 +        * Needs to skip these 0's here
6366 +        */
6367 +       for (i = 0; i < r; i++)
6368 +               if (buf[i] != 0)
6369 +                       break;
6371 +       p = buf + i;
6372 +       i = r - i;  /* i is only used with no-padding mode */
6374 +       switch (padding)
6375 +               {
6376 +       case RSA_PKCS1_PADDING:
6377 +               r = RSA_padding_check_PKCS1_type_1(to, num, p, i, num);
6378 +               break;
6379 +       case RSA_NO_PADDING:
6380 +               r = RSA_padding_check_none(to, num, p, i, num);
6381 +               break;
6382 +       default:
6383 +               RSAerr(PK11_F_RSA_PUB_DEC, PK11_R_UNKNOWN_PADDING_TYPE);
6384 +               goto err;
6385 +               }
6386 +       if (r < 0)
6387 +               RSAerr(PK11_F_RSA_PUB_DEC, PK11_R_PADDING_CHECK_FAILED);
6389 +err:
6390 +       BN_clear_free(&f);
6391 +       if (buf != NULL)
6392 +               {
6393 +               OPENSSL_cleanse(buf, num);
6394 +               OPENSSL_free(buf);
6395 +               }
6396 +       return (r);
6397 +       }
6400 + * This function implements RSA public encryption using C_EncryptInit and
6401 + * C_Encrypt pk11 interfaces. Note that the CKM_RSA_X_509 is used here.
6402 + * The calling function allocated sufficient memory in "to" to store results.
6403 + */
6404 +static int pk11_RSA_public_encrypt_low(int flen,
6405 +       const unsigned char *from, unsigned char *to, RSA *rsa)
6406 +       {
6407 +       CK_ULONG bytes_encrypted = flen;
6408 +       int retval = -1;
6409 +       CK_RV rv;
6410 +       CK_MECHANISM mech_rsa = {CKM_RSA_X_509, NULL, 0};
6411 +       CK_MECHANISM *p_mech = &mech_rsa;
6412 +       CK_OBJECT_HANDLE h_pub_key = CK_INVALID_HANDLE;
6413 +       PK11_SESSION *sp;
6415 +       if ((sp = pk11_get_session(OP_RSA)) == NULL)
6416 +               return (-1);
6418 +       (void) check_new_rsa_key_pub(sp, rsa);
6420 +       h_pub_key = sp->opdata_rsa_pub_key;
6421 +       if (h_pub_key == CK_INVALID_HANDLE)
6422 +               h_pub_key = sp->opdata_rsa_pub_key =
6423 +                       pk11_get_public_rsa_key(rsa, &sp->opdata_rsa_pub,
6424 +                           &sp->opdata_rsa_n_num, &sp->opdata_rsa_e_num,
6425 +                           sp->session);
6427 +       if (h_pub_key != CK_INVALID_HANDLE)
6428 +               {
6429 +               rv = pFuncList->C_EncryptInit(sp->session, p_mech,
6430 +                       h_pub_key);
6432 +               if (rv != CKR_OK)
6433 +                       {
6434 +                       PK11err_add_data(PK11_F_RSA_PUB_ENC_LOW,
6435 +                           PK11_R_ENCRYPTINIT, rv);
6436 +                       pk11_return_session(sp, OP_RSA);
6437 +                       return (-1);
6438 +                       }
6440 +               rv = pFuncList->C_Encrypt(sp->session,
6441 +                       (unsigned char *)from, flen, to, &bytes_encrypted);
6443 +               if (rv != CKR_OK)
6444 +                       {
6445 +                       PK11err_add_data(PK11_F_RSA_PUB_ENC_LOW,
6446 +                           PK11_R_ENCRYPT, rv);
6447 +                       pk11_return_session(sp, OP_RSA);
6448 +                       return (-1);
6449 +                       }
6450 +               retval = bytes_encrypted;
6451 +               }
6453 +       pk11_return_session(sp, OP_RSA);
6454 +       return (retval);
6455 +       }
6459 + * This function implements RSA private encryption using C_SignInit and
6460 + * C_Sign pk11 APIs. Note that CKM_RSA_X_509 is used here.
6461 + * The calling function allocated sufficient memory in "to" to store results.
6462 + */
6463 +static int pk11_RSA_private_encrypt_low(int flen,
6464 +       const unsigned char *from, unsigned char *to, RSA *rsa)
6465 +       {
6466 +       CK_ULONG ul_sig_len = flen;
6467 +       int retval = -1;
6468 +       CK_RV rv;
6469 +       CK_MECHANISM mech_rsa = {CKM_RSA_X_509, NULL, 0};
6470 +       CK_MECHANISM *p_mech = &mech_rsa;
6471 +       CK_OBJECT_HANDLE h_priv_key = CK_INVALID_HANDLE;
6472 +       PK11_SESSION *sp;
6474 +       if ((sp = pk11_get_session(OP_RSA)) == NULL)
6475 +               return (-1);
6477 +       (void) check_new_rsa_key_priv(sp, rsa);
6479 +       h_priv_key = sp->opdata_rsa_priv_key;
6480 +       if (h_priv_key == CK_INVALID_HANDLE)
6481 +               {
6482 +               h_priv_key = sp->opdata_rsa_priv_key =
6483 +                       pk11_get_private_rsa_key(rsa, &sp->opdata_rsa_priv,
6484 +                           &sp->opdata_rsa_d_num, &sp->opdata_rsa_pn_num,
6485 +                           &sp->opdata_rsa_pe_num, sp->session);
6486 +               }
6488 +       if (h_priv_key != CK_INVALID_HANDLE)
6489 +               {
6490 +               rv = pFuncList->C_SignInit(sp->session, p_mech,
6491 +                       h_priv_key);
6493 +               if (rv != CKR_OK)
6494 +                       {
6495 +                       PK11err_add_data(PK11_F_RSA_PRIV_ENC_LOW,
6496 +                           PK11_R_SIGNINIT, rv);
6497 +                       pk11_return_session(sp, OP_RSA);
6498 +                       return (-1);
6499 +                       }
6501 +               rv = pFuncList->C_Sign(sp->session,
6502 +                       (unsigned char *)from, flen, to, &ul_sig_len);
6504 +               if (rv != CKR_OK)
6505 +                       {
6506 +                       PK11err_add_data(PK11_F_RSA_PRIV_ENC_LOW, PK11_R_SIGN,
6507 +                           rv);
6508 +                       pk11_return_session(sp, OP_RSA);
6509 +                       return (-1);
6510 +                       }
6512 +               retval = ul_sig_len;
6513 +               }
6515 +       pk11_return_session(sp, OP_RSA);
6516 +       return (retval);
6517 +       }
6521 + * This function implements RSA private decryption using C_DecryptInit and
6522 + * C_Decrypt pk11 APIs. Note that CKM_RSA_X_509 mechanism is used here.
6523 + * The calling function allocated sufficient memory in "to" to store results.
6524 + */
6525 +static int pk11_RSA_private_decrypt_low(int flen,
6526 +       const unsigned char *from, unsigned char *to, RSA *rsa)
6527 +       {
6528 +       CK_ULONG bytes_decrypted = flen;
6529 +       int retval = -1;
6530 +       CK_RV rv;
6531 +       CK_MECHANISM mech_rsa = {CKM_RSA_X_509, NULL, 0};
6532 +       CK_MECHANISM *p_mech = &mech_rsa;
6533 +       CK_OBJECT_HANDLE h_priv_key;
6534 +       PK11_SESSION *sp;
6536 +       if ((sp = pk11_get_session(OP_RSA)) == NULL)
6537 +               return (-1);
6539 +       (void) check_new_rsa_key_priv(sp, rsa);
6541 +       h_priv_key = sp->opdata_rsa_priv_key;
6542 +       if (h_priv_key == CK_INVALID_HANDLE)
6543 +               h_priv_key = sp->opdata_rsa_priv_key =
6544 +                       pk11_get_private_rsa_key(rsa, &sp->opdata_rsa_priv,
6545 +                           &sp->opdata_rsa_d_num, &sp->opdata_rsa_pn_num,
6546 +                           &sp->opdata_rsa_pe_num, sp->session);
6548 +       if (h_priv_key != CK_INVALID_HANDLE)
6549 +               {
6550 +               rv = pFuncList->C_DecryptInit(sp->session, p_mech,
6551 +                       h_priv_key);
6553 +               if (rv != CKR_OK)
6554 +                       {
6555 +                       PK11err_add_data(PK11_F_RSA_PRIV_DEC_LOW,
6556 +                               PK11_R_DECRYPTINIT, rv);
6557 +                       pk11_return_session(sp, OP_RSA);
6558 +                       return (-1);
6559 +                       }
6561 +               rv = pFuncList->C_Decrypt(sp->session,
6562 +                       (unsigned char *)from, flen, to, &bytes_decrypted);
6564 +               if (rv != CKR_OK)
6565 +                       {
6566 +                       PK11err_add_data(PK11_F_RSA_PRIV_DEC_LOW,
6567 +                           PK11_R_DECRYPT, rv);
6568 +                       pk11_return_session(sp, OP_RSA);
6569 +                       return (-1);
6570 +                       }
6571 +               retval = bytes_decrypted;
6572 +               }
6574 +       pk11_return_session(sp, OP_RSA);
6575 +       return (retval);
6576 +       }
6580 + * This function implements RSA public decryption using C_VerifyRecoverInit
6581 + * and C_VerifyRecover pk11 APIs. Note that CKM_RSA_X_509 is used here.
6582 + * The calling function allocated sufficient memory in "to" to store results.
6583 + */
6584 +static int pk11_RSA_public_decrypt_low(int flen,
6585 +       const unsigned char *from, unsigned char *to, RSA *rsa)
6586 +       {
6587 +       CK_ULONG bytes_decrypted = flen;
6588 +       int retval = -1;
6589 +       CK_RV rv;
6590 +       CK_MECHANISM mech_rsa = {CKM_RSA_X_509, NULL, 0};
6591 +       CK_MECHANISM *p_mech = &mech_rsa;
6592 +       CK_OBJECT_HANDLE h_pub_key = CK_INVALID_HANDLE;
6593 +       PK11_SESSION *sp;
6595 +       if ((sp = pk11_get_session(OP_RSA)) == NULL)
6596 +               return (-1);
6598 +       (void) check_new_rsa_key_pub(sp, rsa);
6600 +       h_pub_key = sp->opdata_rsa_pub_key;
6601 +       if (h_pub_key == CK_INVALID_HANDLE)
6602 +               h_pub_key = sp->opdata_rsa_pub_key =
6603 +                       pk11_get_public_rsa_key(rsa, &sp->opdata_rsa_pub,
6604 +                           &sp->opdata_rsa_n_num, &sp->opdata_rsa_e_num,
6605 +                           sp->session);
6607 +       if (h_pub_key != CK_INVALID_HANDLE)
6608 +               {
6609 +               rv = pFuncList->C_VerifyRecoverInit(sp->session,
6610 +                       p_mech, h_pub_key);
6612 +               if (rv != CKR_OK)
6613 +                       {
6614 +                       PK11err_add_data(PK11_F_RSA_PUB_DEC_LOW,
6615 +                               PK11_R_VERIFYRECOVERINIT, rv);
6616 +                       pk11_return_session(sp, OP_RSA);
6617 +                       return (-1);
6618 +                       }
6620 +               rv = pFuncList->C_VerifyRecover(sp->session,
6621 +                       (unsigned char *)from, flen, to, &bytes_decrypted);
6623 +               if (rv != CKR_OK)
6624 +                       {
6625 +                       PK11err_add_data(PK11_F_RSA_PUB_DEC_LOW,
6626 +                           PK11_R_VERIFYRECOVER, rv);
6627 +                       pk11_return_session(sp, OP_RSA);
6628 +                       return (-1);
6629 +                       }
6630 +               retval = bytes_decrypted;
6631 +               }
6633 +       pk11_return_session(sp, OP_RSA);
6634 +       return (retval);
6635 +       }
6637 +static int pk11_RSA_init(RSA *rsa)
6638 +       {
6639 +       /*
6640 +        * This flag in the RSA_METHOD enables the new rsa_sign,
6641 +        * rsa_verify functions. See rsa.h for details.
6642 +        */
6643 +       rsa->flags |= RSA_FLAG_SIGN_VER;
6645 +       return (1);
6646 +       }
6648 +static int pk11_RSA_finish(RSA *rsa)
6649 +       {
6650 +       /*
6651 +        * Since we are overloading OpenSSL's native RSA_eay_finish() we need
6652 +        * to do the same as in the original function, i.e. to free bignum
6653 +        * structures.
6654 +        */
6655 +       if (rsa->_method_mod_n != NULL)
6656 +               BN_MONT_CTX_free(rsa->_method_mod_n);
6657 +       if (rsa->_method_mod_p != NULL)
6658 +               BN_MONT_CTX_free(rsa->_method_mod_p);
6659 +       if (rsa->_method_mod_q != NULL)
6660 +               BN_MONT_CTX_free(rsa->_method_mod_q);
6662 +       return (1);
6663 +       }
6666 + * Standard engine interface function. Majority codes here are from
6667 + * rsa/rsa_sign.c. We replaced the decrypt function call by C_Sign of PKCS#11.
6668 + * See more details in rsa/rsa_sign.c
6669 + */
6670 +static int pk11_RSA_sign(int type, const unsigned char *m, unsigned int m_len,
6671 +       unsigned char *sigret, unsigned int *siglen, const RSA *rsa)
6672 +       {
6673 +       X509_SIG sig;
6674 +       ASN1_TYPE parameter;
6675 +       int i, j = 0;
6676 +       unsigned char *p, *s = NULL;
6677 +       X509_ALGOR algor;
6678 +       ASN1_OCTET_STRING digest;
6679 +       CK_RV rv;
6680 +       CK_MECHANISM mech_rsa = {CKM_RSA_PKCS, NULL, 0};
6681 +       CK_MECHANISM *p_mech = &mech_rsa;
6682 +       CK_OBJECT_HANDLE h_priv_key;
6683 +       PK11_SESSION *sp = NULL;
6684 +       int ret = 0;
6685 +       unsigned long ulsiglen;
6687 +       /* Encode the digest */
6688 +       /* Special case: SSL signature, just check the length */
6689 +       if (type == NID_md5_sha1)
6690 +               {
6691 +               if (m_len != SSL_SIG_LENGTH)
6692 +                       {
6693 +                       PK11err(PK11_F_RSA_SIGN,
6694 +                               PK11_R_INVALID_MESSAGE_LENGTH);
6695 +                       goto err;
6696 +                       }
6697 +               i = SSL_SIG_LENGTH;
6698 +               s = (unsigned char *)m;
6699 +               }
6700 +       else
6701 +               {
6702 +               sig.algor = &algor;
6703 +               sig.algor->algorithm = OBJ_nid2obj(type);
6704 +               if (sig.algor->algorithm == NULL)
6705 +                       {
6706 +                       PK11err(PK11_F_RSA_SIGN,
6707 +                               PK11_R_UNKNOWN_ALGORITHM_TYPE);
6708 +                       goto err;
6709 +                       }
6710 +               if (sig.algor->algorithm->length == 0)
6711 +                       {
6712 +                       PK11err(PK11_F_RSA_SIGN,
6713 +                               PK11_R_UNKNOWN_ASN1_OBJECT_ID);
6714 +                       goto err;
6715 +                       }
6716 +               parameter.type = V_ASN1_NULL;
6717 +               parameter.value.ptr = NULL;
6718 +               sig.algor->parameter = &parameter;
6720 +               sig.digest = &digest;
6721 +               sig.digest->data = (unsigned char *)m;
6722 +               sig.digest->length = m_len;
6724 +               i = i2d_X509_SIG(&sig, NULL);
6725 +               }
6727 +       j = RSA_size(rsa);
6728 +       if ((i - RSA_PKCS1_PADDING) > j)
6729 +               {
6730 +               PK11err(PK11_F_RSA_SIGN, PK11_R_DIGEST_TOO_BIG);
6731 +               goto err;
6732 +               }
6734 +       if (type != NID_md5_sha1)
6735 +               {
6736 +               s = (unsigned char *)OPENSSL_malloc((unsigned int)(j + 1));
6737 +               if (s == NULL)
6738 +                       {
6739 +                       PK11err(PK11_F_RSA_SIGN, PK11_R_MALLOC_FAILURE);
6740 +                       goto err;
6741 +                       }
6742 +               p = s;
6743 +               (void) i2d_X509_SIG(&sig, &p);
6744 +               }
6746 +       if ((sp = pk11_get_session(OP_RSA)) == NULL)
6747 +               goto err;
6749 +       (void) check_new_rsa_key_priv(sp, rsa);
6751 +       h_priv_key = sp->opdata_rsa_priv_key;
6752 +       if (h_priv_key == CK_INVALID_HANDLE)
6753 +               h_priv_key = sp->opdata_rsa_priv_key =
6754 +                       pk11_get_private_rsa_key((RSA *)rsa,
6755 +                           &sp->opdata_rsa_priv, &sp->opdata_rsa_d_num,
6756 +                           &sp->opdata_rsa_pn_num, &sp->opdata_rsa_pe_num,
6757 +                           sp->session);
6759 +       if (h_priv_key != CK_INVALID_HANDLE)
6760 +               {
6761 +               rv = pFuncList->C_SignInit(sp->session, p_mech, h_priv_key);
6763 +               if (rv != CKR_OK)
6764 +                       {
6765 +                       PK11err_add_data(PK11_F_RSA_SIGN, PK11_R_SIGNINIT, rv);
6766 +                       goto err;
6767 +                       }
6769 +               ulsiglen = j;
6770 +               rv = pFuncList->C_Sign(sp->session, s, i, sigret,
6771 +                       (CK_ULONG_PTR) &ulsiglen);
6772 +               *siglen = ulsiglen;
6774 +               if (rv != CKR_OK)
6775 +                       {
6776 +                       PK11err_add_data(PK11_F_RSA_SIGN, PK11_R_SIGN, rv);
6777 +                       goto err;
6778 +                       }
6779 +               ret = 1;
6780 +               }
6782 +err:
6783 +       if ((type != NID_md5_sha1) && (s != NULL))
6784 +               {
6785 +               (void) memset(s, 0, (unsigned int)(j + 1));
6786 +               OPENSSL_free(s);
6787 +               }
6789 +       pk11_return_session(sp, OP_RSA);
6790 +       return (ret);
6791 +       }
6793 +#if OPENSSL_VERSION_NUMBER < 0x10000000L
6794 +static int pk11_RSA_verify(int type, const unsigned char *m,
6795 +       unsigned int m_len, unsigned char *sigbuf, unsigned int siglen,
6796 +       const RSA *rsa)
6797 +#else
6798 +static int pk11_RSA_verify(int type, const unsigned char *m,
6799 +       unsigned int m_len, const unsigned char *sigbuf, unsigned int siglen,
6800 +       const RSA *rsa)
6801 +#endif
6802 +       {
6803 +       X509_SIG sig;
6804 +       ASN1_TYPE parameter;
6805 +       int i, j = 0;
6806 +       unsigned char *p, *s = NULL;
6807 +       X509_ALGOR algor;
6808 +       ASN1_OCTET_STRING digest;
6809 +       CK_RV rv;
6810 +       CK_MECHANISM mech_rsa = {CKM_RSA_PKCS, NULL, 0};
6811 +       CK_MECHANISM *p_mech = &mech_rsa;
6812 +       CK_OBJECT_HANDLE h_pub_key;
6813 +       PK11_SESSION *sp = NULL;
6814 +       int ret = 0;
6816 +       /* Encode the digest    */
6817 +       /* Special case: SSL signature, just check the length */
6818 +       if (type == NID_md5_sha1)
6819 +               {
6820 +               if (m_len != SSL_SIG_LENGTH)
6821 +                       {
6822 +                       PK11err(PK11_F_RSA_VERIFY,
6823 +                               PK11_R_INVALID_MESSAGE_LENGTH);
6824 +                       goto err;
6825 +                       }
6826 +               i = SSL_SIG_LENGTH;
6827 +               s = (unsigned char *)m;
6828 +               }
6829 +       else
6830 +               {
6831 +               sig.algor = &algor;
6832 +               sig.algor->algorithm = OBJ_nid2obj(type);
6833 +               if (sig.algor->algorithm == NULL)
6834 +                       {
6835 +                       PK11err(PK11_F_RSA_VERIFY,
6836 +                               PK11_R_UNKNOWN_ALGORITHM_TYPE);
6837 +                       goto err;
6838 +                       }
6839 +               if (sig.algor->algorithm->length == 0)
6840 +                       {
6841 +                       PK11err(PK11_F_RSA_VERIFY,
6842 +                               PK11_R_UNKNOWN_ASN1_OBJECT_ID);
6843 +                       goto err;
6844 +                       }
6845 +               parameter.type = V_ASN1_NULL;
6846 +               parameter.value.ptr = NULL;
6847 +               sig.algor->parameter = &parameter;
6848 +               sig.digest = &digest;
6849 +               sig.digest->data = (unsigned char *)m;
6850 +               sig.digest->length = m_len;
6851 +               i = i2d_X509_SIG(&sig, NULL);
6852 +               }
6854 +       j = RSA_size(rsa);
6855 +       if ((i - RSA_PKCS1_PADDING) > j)
6856 +               {
6857 +               PK11err(PK11_F_RSA_VERIFY, PK11_R_DIGEST_TOO_BIG);
6858 +               goto err;
6859 +               }
6861 +       if (type != NID_md5_sha1)
6862 +               {
6863 +               s = (unsigned char *)OPENSSL_malloc((unsigned int)(j + 1));
6864 +               if (s == NULL)
6865 +                       {
6866 +                       PK11err(PK11_F_RSA_VERIFY, PK11_R_MALLOC_FAILURE);
6867 +                       goto err;
6868 +                       }
6869 +               p = s;
6870 +               (void) i2d_X509_SIG(&sig, &p);
6871 +               }
6873 +       if ((sp = pk11_get_session(OP_RSA)) == NULL)
6874 +               goto err;
6876 +       (void) check_new_rsa_key_pub(sp, rsa);
6878 +       h_pub_key = sp->opdata_rsa_pub_key;
6879 +       if (h_pub_key == CK_INVALID_HANDLE)
6880 +               h_pub_key = sp->opdata_rsa_pub_key =
6881 +                       pk11_get_public_rsa_key((RSA *)rsa, &sp->opdata_rsa_pub,
6882 +                           &sp->opdata_rsa_n_num, &sp->opdata_rsa_e_num,
6883 +                           sp->session);
6885 +       if (h_pub_key != CK_INVALID_HANDLE)
6886 +               {
6887 +               rv = pFuncList->C_VerifyInit(sp->session, p_mech,
6888 +                       h_pub_key);
6890 +               if (rv != CKR_OK)
6891 +                       {
6892 +                       PK11err_add_data(PK11_F_RSA_VERIFY, PK11_R_VERIFYINIT,
6893 +                           rv);
6894 +                       goto err;
6895 +                       }
6896 +               rv = pFuncList->C_Verify(sp->session, s, i,
6897 +                       (CK_BYTE_PTR)sigbuf, (CK_ULONG)siglen);
6899 +               if (rv != CKR_OK)
6900 +                       {
6901 +                       PK11err_add_data(PK11_F_RSA_VERIFY, PK11_R_VERIFY, rv);
6902 +                       goto err;
6903 +                       }
6904 +               ret = 1;
6905 +               }
6907 +err:
6908 +       if ((type != NID_md5_sha1) && (s != NULL))
6909 +               {
6910 +               (void) memset(s, 0, (unsigned int)(j + 1));
6911 +               OPENSSL_free(s);
6912 +               }
6914 +       pk11_return_session(sp, OP_RSA);
6915 +       return (ret);
6916 +       }
6918 +static int hndidx_rsa = -1;
6920 +#define        MAXATTR 1024
6923 + * Load RSA private key from a file or get its PKCS#11 handle if stored in the
6924 + * PKCS#11 token.
6925 + */
6926 +/* ARGSUSED */
6927 +EVP_PKEY *pk11_load_privkey(ENGINE *e, const char *privkey_file,
6928 +       UI_METHOD *ui_method, void *callback_data)
6929 +       {
6930 +       EVP_PKEY *pkey = NULL;
6931 +       FILE *privkey;
6932 +       CK_OBJECT_HANDLE  h_priv_key = CK_INVALID_HANDLE;
6933 +       RSA *rsa = NULL;
6934 +       PK11_SESSION *sp;
6935 +       /* Anything else below is needed for the key by reference extension. */
6936 +       CK_RV rv;
6937 +       CK_BBOOL is_token = TRUE;
6938 +       CK_BBOOL rollback = FALSE;
6939 +       CK_BYTE attr_data[2][MAXATTR];
6940 +       CK_OBJECT_CLASS key_class = CKO_PRIVATE_KEY;
6941 +       CK_OBJECT_HANDLE ks_key = CK_INVALID_HANDLE;    /* key in keystore */
6943 +       /* we look for private keys only */
6944 +       CK_ATTRIBUTE search_templ[] =
6945 +               {
6946 +               {CKA_TOKEN, &is_token, sizeof(is_token)},
6947 +               {CKA_CLASS, &key_class, sizeof(key_class)},
6948 +               {CKA_LABEL, NULL, 0}
6949 +               };
6951 +       /*
6952 +        * These public attributes are needed to initialize the OpenSSL RSA
6953 +        * structure with something we can use to look up the key. Note that we
6954 +        * never ask for private components.
6955 +        */
6956 +       CK_ATTRIBUTE get_templ[] =
6957 +               {
6958 +               {CKA_MODULUS, (void *)attr_data[0], MAXATTR},           /* n */
6959 +               {CKA_PUBLIC_EXPONENT, (void *)attr_data[1], MAXATTR},   /* e */
6960 +               };
6962 +       if ((sp = pk11_get_session(OP_RSA)) == NULL)
6963 +               return (NULL);
6965 +       /*
6966 +        * Use simple scheme "pkcs11:<KEY_LABEL>" for now.
6967 +        */
6968 +       if (strstr(privkey_file, "pkcs11:") == privkey_file)
6969 +               {
6970 +               search_templ[2].pValue = strstr(privkey_file, ":") + 1;
6971 +               search_templ[2].ulValueLen = strlen(search_templ[2].pValue);
6973 +               if (pk11_token_login(sp->session, &pk11_login_done,
6974 +                   CK_TRUE) == 0)
6975 +                       goto err;
6977 +               /* see find_lock array definition
6978 +                  for more info on object locking */
6979 +               LOCK_OBJSTORE(OP_RSA);
6981 +               /*
6982 +                * Now let's try to find the key in the token. It is a failure
6983 +                * if we can't find it.
6984 +                */
6985 +               if (find_one_object(OP_RSA, sp->session, search_templ, 3,
6986 +                   &ks_key) == 0)
6987 +                       {
6988 +                       UNLOCK_OBJSTORE(OP_RSA);
6989 +                       goto err;
6990 +                       }
6992 +               if (hndidx_rsa == -1)
6993 +                       hndidx_rsa = RSA_get_ex_new_index(0,
6994 +                                       "pkcs11 RSA HSM key handle",
6995 +                                       NULL, NULL, NULL);
6997 +               /*
6998 +                * We might have a cache hit which we could confirm
6999 +                * according to the 'n'/'e' params, RSA public pointer
7000 +                * as NULL, and non-NULL RSA private pointer. However,
7001 +                * it is easier just to recreate everything. We expect
7002 +                * the keys to be loaded once and used many times. We
7003 +                * do not check the return value because even in case
7004 +                * of failure the sp structure will have both key
7005 +                * pointer and object handle cleaned and
7006 +                * pk11_destroy_object() reports the failure to the
7007 +                * OpenSSL error message buffer.
7008 +                */
7009 +               (void) pk11_destroy_rsa_object_priv(sp, FALSE);
7011 +               sp->opdata_rsa_priv_key = ks_key;
7012 +               /* This object shall not be deleted on a cache miss. */
7013 +               sp->priv_persistent = CK_TRUE;
7015 +               /*
7016 +                * Cache the RSA private structure pointer. We do not
7017 +                * use it now for key-by-ref keys but let's do it for
7018 +                * consistency reasons.
7019 +                */
7020 +               if ((rsa = sp->opdata_rsa_priv = RSA_new_method(e)) == NULL)
7021 +                       {
7022 +                       UNLOCK_OBJSTORE(OP_RSA);
7023 +                       goto err;
7024 +                       }
7026 +               /*
7027 +                * Now we have to initialize an OpenSSL RSA structure,
7028 +                * everything else is 0 or NULL.
7029 +                */
7030 +               rsa->flags = RSA_FLAG_SIGN_VER | RSA_FLAG_EXT_PKEY;
7031 +               RSA_set_ex_data(rsa, hndidx_rsa, (void *) ks_key);
7033 +               if ((rv = pFuncList->C_GetAttributeValue(sp->session, ks_key,
7034 +                   get_templ, 2)) != CKR_OK)
7035 +                       {
7036 +                       UNLOCK_OBJSTORE(OP_RSA);
7037 +                       PK11err_add_data(PK11_F_LOAD_PRIVKEY,
7038 +                                        PK11_R_GETATTRIBUTVALUE, rv);
7039 +                       goto err;
7040 +                       }
7042 +               /*
7043 +                * We do not use pk11_get_private_rsa_key() here so we
7044 +                * must take care of handle management ourselves.
7045 +                */
7046 +               KEY_HANDLE_REFHOLD(ks_key, OP_RSA, TRUE, rollback, err);
7048 +               /*
7049 +                * Those are the sensitive components we do not want to export
7050 +                * from the token at all: rsa->(d|p|q|dmp1|dmq1|iqmp).
7051 +                */
7052 +               attr_to_BN(&get_templ[0], attr_data[0], &rsa->n);
7053 +               attr_to_BN(&get_templ[1], attr_data[1], &rsa->e);
7054 +               /*
7055 +                * Must have 'n'/'e' components in the session structure as
7056 +                * well. They serve as a public look-up key for the private key
7057 +                * in the keystore.
7058 +                */
7059 +               attr_to_BN(&get_templ[0], attr_data[0],
7060 +                       &sp->opdata_rsa_pn_num);
7061 +               attr_to_BN(&get_templ[1], attr_data[1],
7062 +                       &sp->opdata_rsa_pe_num);
7064 +               UNLOCK_OBJSTORE(OP_RSA);
7066 +               if ((pkey = EVP_PKEY_new()) == NULL)
7067 +                       goto err;
7069 +               if (EVP_PKEY_assign_RSA(pkey, rsa) == 0)
7070 +                       goto err;
7071 +               }
7072 +       else if ((privkey = fopen(privkey_file, read_mode_flags)) != NULL)
7073 +               {
7074 +               pkey = PEM_read_PrivateKey(privkey, NULL, NULL, NULL);
7075 +               (void) fclose(privkey);
7076 +               if (pkey != NULL)
7077 +                       {
7078 +                       rsa = EVP_PKEY_get1_RSA(pkey);
7079 +                       if (rsa != NULL)
7080 +                               {
7081 +                               /*
7082 +                                * This will always destroy the RSA
7083 +                                * object since we have a new RSA
7084 +                                * structure here.
7085 +                                */
7086 +                               (void) check_new_rsa_key_priv(sp, rsa);
7087 +                               sp->priv_persistent = CK_FALSE;
7089 +                               h_priv_key = sp->opdata_rsa_priv_key =
7090 +                                   pk11_get_private_rsa_key(rsa,
7091 +                                   &sp->opdata_rsa_priv,
7092 +                                   &sp->opdata_rsa_d_num,
7093 +                                   &sp->opdata_rsa_pn_num,
7094 +                                   &sp->opdata_rsa_pe_num, sp->session);
7095 +                               if (h_priv_key == CK_INVALID_HANDLE)
7096 +                                       goto err;
7097 +                               }
7098 +                       else
7099 +                               goto err;
7100 +                       }
7101 +               }
7103 +       pk11_return_session(sp, OP_RSA);
7104 +       return (pkey);
7105 +err:
7106 +       pk11_return_session(sp, OP_RSA);
7107 +       if (rsa != NULL)
7108 +               RSA_free(rsa);
7109 +       if (pkey != NULL)
7110 +               {
7111 +               EVP_PKEY_free(pkey);
7112 +               pkey = NULL;
7113 +               }
7114 +       rollback = rollback;
7115 +       return (pkey);
7116 +       }
7119 + * Load RSA public key from a file or get its PKCS#11 handle if stored in the
7120 + * PKCS#11 token.
7121 + */
7122 +/* ARGSUSED */
7123 +EVP_PKEY *pk11_load_pubkey(ENGINE *e, const char *pubkey_file,
7124 +       UI_METHOD *ui_method, void *callback_data)
7125 +       {
7126 +       EVP_PKEY *pkey = NULL;
7127 +       FILE *pubkey;
7128 +       CK_OBJECT_HANDLE h_pub_key = CK_INVALID_HANDLE;
7129 +       RSA *rsa = NULL;
7130 +       PK11_SESSION *sp;
7131 +       /* Anything else below is needed for the key by reference extension. */
7132 +       CK_RV rv;
7133 +       CK_BBOOL is_token = TRUE;
7134 +       CK_BYTE attr_data[2][MAXATTR];
7135 +       CK_OBJECT_CLASS key_class = CKO_PUBLIC_KEY;
7136 +       CK_OBJECT_HANDLE ks_key = CK_INVALID_HANDLE;    /* key in keystore */
7138 +       /* we look for public keys only */
7139 +       CK_ATTRIBUTE search_templ[] =
7140 +               {
7141 +               {CKA_TOKEN, &is_token, sizeof(is_token)},
7142 +               {CKA_CLASS, &key_class, sizeof(key_class)},
7143 +               {CKA_LABEL, NULL, 0}
7144 +               };
7146 +       /*
7147 +        * These public attributes are needed to initialize OpenSSL RSA
7148 +        * structure with something we can use to look up the key.
7149 +        */
7150 +       CK_ATTRIBUTE get_templ[] =
7151 +               {
7152 +               {CKA_MODULUS, (void *)attr_data[0], MAXATTR},           /* n */
7153 +               {CKA_PUBLIC_EXPONENT, (void *)attr_data[1], MAXATTR},   /* e */
7154 +               };
7156 +       if ((sp = pk11_get_session(OP_RSA)) == NULL)
7157 +               return (NULL);
7159 +       /*
7160 +        * Use simple scheme "pkcs11:<KEY_LABEL>" for now.
7161 +        */
7162 +       if (strstr(pubkey_file, "pkcs11:") == pubkey_file)
7163 +               {
7164 +               search_templ[2].pValue = strstr(pubkey_file, ":") + 1;
7165 +               search_templ[2].ulValueLen = strlen(search_templ[2].pValue);
7167 +               if (pk11_token_login(sp->session, &pk11_login_done,
7168 +                   CK_FALSE) == 0)
7169 +                       goto err;
7171 +               /* see find_lock array definition
7172 +                  for more info on object locking */
7173 +               LOCK_OBJSTORE(OP_RSA);
7175 +               /*
7176 +                * Now let's try to find the key in the token. It is a failure
7177 +                * if we can't find it.
7178 +                */
7179 +               if (find_one_object(OP_RSA, sp->session, search_templ, 3,
7180 +                   &ks_key) == 0)
7181 +                       {
7182 +                       UNLOCK_OBJSTORE(OP_RSA);
7183 +                       goto err;
7184 +                       }
7186 +               /*
7187 +                * We load a new public key so we will create a new RSA
7188 +                * structure. No cache hit is possible.
7189 +                */
7190 +               (void) pk11_destroy_rsa_object_pub(sp, FALSE);
7192 +               sp->opdata_rsa_pub_key = ks_key;
7193 +               /* This object shall not be deleted on a cache miss. */
7194 +               sp->pub_persistent = CK_TRUE;
7196 +               /*
7197 +                * Cache the RSA public structure pointer.
7198 +                */
7199 +               if ((rsa = sp->opdata_rsa_pub = RSA_new_method(e)) == NULL)
7200 +                       {
7201 +                       UNLOCK_OBJSTORE(OP_RSA);
7202 +                       goto err;
7203 +                       }
7205 +               /*
7206 +                * Now we have to initialize an OpenSSL RSA structure,
7207 +                * everything else is 0 or NULL.
7208 +                */
7209 +               rsa->flags = RSA_FLAG_SIGN_VER;
7211 +               if ((rv = pFuncList->C_GetAttributeValue(sp->session, ks_key,
7212 +                   get_templ, 2)) != CKR_OK)
7213 +                       {
7214 +                       UNLOCK_OBJSTORE(OP_RSA);
7215 +                       PK11err_add_data(PK11_F_LOAD_PUBKEY,
7216 +                                        PK11_R_GETATTRIBUTVALUE, rv);
7217 +                       goto err;
7218 +                       }
7220 +               attr_to_BN(&get_templ[0], attr_data[0], &rsa->n);
7221 +               attr_to_BN(&get_templ[1], attr_data[1], &rsa->e);
7223 +               UNLOCK_OBJSTORE(OP_RSA);
7225 +               if ((pkey = EVP_PKEY_new()) == NULL)
7226 +                       goto err;
7228 +               if (EVP_PKEY_assign_RSA(pkey, rsa) == 0)
7229 +                       goto err;
7231 +               /*
7232 +                * Create a session object from it so that when calling
7233 +                * pk11_get_public_rsa_key() the next time, we can find it. The
7234 +                * reason why we do that is that we cannot tell from the RSA
7235 +                * structure (OpenSSL RSA structure does not have any room for
7236 +                * additional data used by the engine, for example) if it bears
7237 +                * a public key stored in the keystore or not so it's better if
7238 +                * we always have a session key. Note that this is different
7239 +                * from what we do for the private keystore objects but in that
7240 +                * case, we can tell from the RSA structure that the keystore
7241 +                * object is in play - the 'd' component is NULL in that case.
7242 +                */
7243 +               h_pub_key = sp->opdata_rsa_pub_key =
7244 +                   pk11_get_public_rsa_key(rsa,
7245 +                   &sp->opdata_rsa_pub, &sp->opdata_rsa_n_num,
7246 +                   &sp->opdata_rsa_e_num, sp->session);
7247 +               if (h_pub_key == CK_INVALID_HANDLE)
7248 +                       goto err;
7249 +               }
7250 +       else if ((pubkey = fopen(pubkey_file, read_mode_flags)) != NULL)
7251 +               {
7252 +               pkey = PEM_read_PUBKEY(pubkey, NULL, NULL, NULL);
7253 +               (void) fclose(pubkey);
7254 +               if (pkey != NULL)
7255 +                       {
7256 +                       rsa = EVP_PKEY_get1_RSA(pkey);
7257 +                       if (rsa != NULL)
7258 +                               {
7259 +                               /*
7260 +                                * This will always destroy the RSA
7261 +                                * object since we have a new RSA
7262 +                                * structure here.
7263 +                                */
7264 +                               (void) check_new_rsa_key_pub(sp, rsa);
7265 +                               sp->pub_persistent = CK_FALSE;
7267 +                               h_pub_key = sp->opdata_rsa_pub_key =
7268 +                                   pk11_get_public_rsa_key(rsa,
7269 +                                   &sp->opdata_rsa_pub, &sp->opdata_rsa_n_num,
7270 +                                   &sp->opdata_rsa_e_num, sp->session);
7271 +                               if (h_pub_key == CK_INVALID_HANDLE)
7272 +                                       goto err;
7273 +                               }
7274 +                       else
7275 +                               goto err;
7276 +                       }
7277 +               }
7279 +       pk11_return_session(sp, OP_RSA);
7280 +       return (pkey);
7281 +err:
7282 +       pk11_return_session(sp, OP_RSA);
7283 +       if (rsa != NULL)
7284 +               RSA_free(rsa);
7285 +       if (pkey != NULL)
7286 +               {
7287 +               EVP_PKEY_free(pkey);
7288 +               pkey = NULL;
7289 +               }
7290 +       return (pkey);
7291 +       }
7294 + * Create a public key object in a session from a given rsa structure.
7295 + * The *rsa_n_num and *rsa_e_num pointers are non-NULL for RSA public keys.
7296 + */
7297 +static CK_OBJECT_HANDLE pk11_get_public_rsa_key(RSA *rsa,
7298 +    RSA **key_ptr, BIGNUM **rsa_n_num, BIGNUM **rsa_e_num,
7299 +    CK_SESSION_HANDLE session)
7300 +       {
7301 +       CK_RV rv;
7302 +       CK_OBJECT_HANDLE h_key = CK_INVALID_HANDLE;
7303 +       CK_ULONG found;
7304 +       CK_OBJECT_CLASS o_key = CKO_PUBLIC_KEY;
7305 +       CK_KEY_TYPE k_type = CKK_RSA;
7306 +       CK_ULONG ul_key_attr_count = 8;
7307 +       CK_BBOOL rollback = FALSE;
7309 +       CK_ATTRIBUTE  a_key_template[] =
7310 +               {
7311 +               {CKA_CLASS, (void *) NULL, sizeof (CK_OBJECT_CLASS)},
7312 +               {CKA_KEY_TYPE, (void *) NULL, sizeof (CK_KEY_TYPE)},
7313 +               {CKA_TOKEN, &myfalse, sizeof (myfalse)},
7314 +               {CKA_ENCRYPT, &mytrue, sizeof (mytrue)},
7315 +               {CKA_VERIFY, &mytrue, sizeof (mytrue)},
7316 +               {CKA_VERIFY_RECOVER, &mytrue, sizeof (mytrue)},
7317 +               {CKA_MODULUS, (void *)NULL, 0},
7318 +               {CKA_PUBLIC_EXPONENT, (void *)NULL, 0}
7319 +               };
7321 +       int i;
7323 +       a_key_template[0].pValue = &o_key;
7324 +       a_key_template[1].pValue = &k_type;
7326 +       a_key_template[6].ulValueLen = BN_num_bytes(rsa->n);
7327 +       a_key_template[6].pValue = (CK_VOID_PTR)OPENSSL_malloc(
7328 +               (size_t)a_key_template[6].ulValueLen);
7329 +       if (a_key_template[6].pValue == NULL)
7330 +               {
7331 +               PK11err(PK11_F_GET_PUB_RSA_KEY, PK11_R_MALLOC_FAILURE);
7332 +               goto malloc_err;
7333 +               }
7335 +       BN_bn2bin(rsa->n, a_key_template[6].pValue);
7337 +       a_key_template[7].ulValueLen = BN_num_bytes(rsa->e);
7338 +       a_key_template[7].pValue = (CK_VOID_PTR)OPENSSL_malloc(
7339 +               (size_t)a_key_template[7].ulValueLen);
7340 +       if (a_key_template[7].pValue == NULL)
7341 +               {
7342 +               PK11err(PK11_F_GET_PUB_RSA_KEY, PK11_R_MALLOC_FAILURE);
7343 +               goto malloc_err;
7344 +               }
7346 +       BN_bn2bin(rsa->e, a_key_template[7].pValue);
7348 +       /* see find_lock array definition for more info on object locking */
7349 +       LOCK_OBJSTORE(OP_RSA);
7351 +       rv = pFuncList->C_FindObjectsInit(session, a_key_template,
7352 +               ul_key_attr_count);
7354 +       if (rv != CKR_OK)
7355 +               {
7356 +               PK11err_add_data(PK11_F_GET_PUB_RSA_KEY,
7357 +                   PK11_R_FINDOBJECTSINIT, rv);
7358 +               goto err;
7359 +               }
7361 +       rv = pFuncList->C_FindObjects(session, &h_key, 1, &found);
7363 +       if (rv != CKR_OK)
7364 +               {
7365 +               (void) pFuncList->C_FindObjectsFinal(session);
7366 +               PK11err_add_data(PK11_F_GET_PUB_RSA_KEY,
7367 +                   PK11_R_FINDOBJECTS, rv);
7368 +               goto err;
7369 +               }
7371 +       rv = pFuncList->C_FindObjectsFinal(session);
7373 +       if (rv != CKR_OK)
7374 +               {
7375 +               PK11err_add_data(PK11_F_GET_PUB_RSA_KEY,
7376 +                   PK11_R_FINDOBJECTSFINAL, rv);
7377 +               goto err;
7378 +               }
7380 +       if (found == 0)
7381 +               {
7382 +               rv = pFuncList->C_CreateObject(session,
7383 +                       a_key_template, ul_key_attr_count, &h_key);
7384 +               if (rv != CKR_OK)
7385 +                       {
7386 +                       PK11err_add_data(PK11_F_GET_PUB_RSA_KEY,
7387 +                           PK11_R_CREATEOBJECT, rv);
7388 +                       goto err;
7389 +                       }
7390 +               }
7392 +       if (rsa_n_num != NULL)
7393 +               if ((*rsa_n_num = BN_dup(rsa->n)) == NULL)
7394 +                       {
7395 +                       PK11err(PK11_F_GET_PUB_RSA_KEY, PK11_R_MALLOC_FAILURE);
7396 +                       rollback = TRUE;
7397 +                       goto err;
7398 +                       }
7399 +       if (rsa_e_num != NULL)
7400 +               if ((*rsa_e_num = BN_dup(rsa->e)) == NULL)
7401 +                       {
7402 +                       PK11err(PK11_F_GET_PUB_RSA_KEY, PK11_R_MALLOC_FAILURE);
7403 +                       BN_free(*rsa_n_num);
7404 +                       *rsa_n_num = NULL;
7405 +                       rollback = TRUE;
7406 +                       goto err;
7407 +                       }
7409 +       /* LINTED: E_CONSTANT_CONDITION */
7410 +       KEY_HANDLE_REFHOLD(h_key, OP_RSA, FALSE, rollback, err);
7411 +       if (key_ptr != NULL)
7412 +               *key_ptr = rsa;
7414 +err:
7415 +       if (rollback)
7416 +               {
7417 +               /*
7418 +                * We do not care about the return value from C_DestroyObject()
7419 +                * since we are doing rollback.
7420 +                */
7421 +               if (found == 0)
7422 +                       (void) pFuncList->C_DestroyObject(session, h_key);
7423 +               h_key = CK_INVALID_HANDLE;
7424 +               }
7426 +       UNLOCK_OBJSTORE(OP_RSA);
7428 +malloc_err:
7429 +       for (i = 6; i <= 7; i++)
7430 +               {
7431 +               if (a_key_template[i].pValue != NULL)
7432 +                       {
7433 +                       OPENSSL_free(a_key_template[i].pValue);
7434 +                       a_key_template[i].pValue = NULL;
7435 +                       }
7436 +               }
7438 +       return (h_key);
7439 +       }
7442 + * Create a private key object in the session from a given rsa structure.
7443 + * The *rsa_d_num pointer is non-NULL for RSA private keys.
7444 + */
7445 +static CK_OBJECT_HANDLE
7446 +pk11_get_private_rsa_key(RSA *rsa, RSA **key_ptr, BIGNUM **rsa_d_num,
7447 +    BIGNUM **rsa_n_num, BIGNUM **rsa_e_num, CK_SESSION_HANDLE session)
7448 +       {
7449 +       CK_RV rv;
7450 +       CK_OBJECT_HANDLE h_key = CK_INVALID_HANDLE;
7451 +       int i;
7452 +       CK_ULONG found;
7453 +       CK_OBJECT_CLASS o_key = CKO_PRIVATE_KEY;
7454 +       CK_KEY_TYPE k_type = CKK_RSA;
7455 +       CK_ULONG ul_key_attr_count = 14;
7456 +       CK_BBOOL rollback = FALSE;
7458 +       /* Both CKA_TOKEN and CKA_SENSITIVE have to be FALSE for session keys */
7459 +       CK_ATTRIBUTE  a_key_template[] =
7460 +               {
7461 +               {CKA_CLASS, (void *) NULL, sizeof (CK_OBJECT_CLASS)},
7462 +               {CKA_KEY_TYPE, (void *) NULL, sizeof (CK_KEY_TYPE)},
7463 +               {CKA_TOKEN, &myfalse, sizeof (myfalse)},
7464 +               {CKA_SENSITIVE, &myfalse, sizeof (myfalse)},
7465 +               {CKA_DECRYPT, &mytrue, sizeof (mytrue)},
7466 +               {CKA_SIGN, &mytrue, sizeof (mytrue)},
7467 +               {CKA_MODULUS, (void *)NULL, 0},
7468 +               {CKA_PUBLIC_EXPONENT, (void *)NULL, 0},
7469 +               {CKA_PRIVATE_EXPONENT, (void *)NULL, 0},
7470 +               {CKA_PRIME_1, (void *)NULL, 0},
7471 +               {CKA_PRIME_2, (void *)NULL, 0},
7472 +               {CKA_EXPONENT_1, (void *)NULL, 0},
7473 +               {CKA_EXPONENT_2, (void *)NULL, 0},
7474 +               {CKA_COEFFICIENT, (void *)NULL, 0},
7475 +               };
7477 +       if ((rsa->flags & RSA_FLAG_EXT_PKEY) != 0) {
7478 +               h_key = (CK_OBJECT_HANDLE)RSA_get_ex_data(rsa, hndidx_rsa);
7479 +               LOCK_OBJSTORE(OP_RSA);
7480 +               goto set;
7481 +       }
7482 +       
7483 +       a_key_template[0].pValue = &o_key;
7484 +       a_key_template[1].pValue = &k_type;
7486 +       /* Put the private key components into the template */
7487 +       if (init_template_value(rsa->n, &a_key_template[6].pValue,
7488 +               &a_key_template[6].ulValueLen) == 0 ||
7489 +           init_template_value(rsa->e, &a_key_template[7].pValue,
7490 +               &a_key_template[7].ulValueLen) == 0 ||
7491 +           init_template_value(rsa->d, &a_key_template[8].pValue,
7492 +               &a_key_template[8].ulValueLen) == 0 ||
7493 +           init_template_value(rsa->p, &a_key_template[9].pValue,
7494 +               &a_key_template[9].ulValueLen) == 0 ||
7495 +           init_template_value(rsa->q, &a_key_template[10].pValue,
7496 +               &a_key_template[10].ulValueLen) == 0 ||
7497 +           init_template_value(rsa->dmp1, &a_key_template[11].pValue,
7498 +               &a_key_template[11].ulValueLen) == 0 ||
7499 +           init_template_value(rsa->dmq1, &a_key_template[12].pValue,
7500 +               &a_key_template[12].ulValueLen) == 0 ||
7501 +           init_template_value(rsa->iqmp, &a_key_template[13].pValue,
7502 +               &a_key_template[13].ulValueLen) == 0)
7503 +               {
7504 +               PK11err(PK11_F_GET_PRIV_RSA_KEY, PK11_R_MALLOC_FAILURE);
7505 +               goto malloc_err;
7506 +               }
7508 +       /* see find_lock array definition for more info on object locking */
7509 +       LOCK_OBJSTORE(OP_RSA);
7511 +       /*
7512 +        * We are getting the private key but the private 'd'
7513 +        * component is NULL.  That means this is key by reference RSA
7514 +        * key. In that case, we can use only public components for
7515 +        * searching for the private key handle.
7516 +        */
7517 +       if (rsa->d == NULL)
7518 +               {
7519 +               ul_key_attr_count = 8;
7520 +               /*
7521 +                * We will perform the search in the token, not in the existing
7522 +                * session keys.
7523 +                */
7524 +               a_key_template[2].pValue = &mytrue;
7525 +               }
7527 +       rv = pFuncList->C_FindObjectsInit(session, a_key_template,
7528 +               ul_key_attr_count);
7530 +       if (rv != CKR_OK)
7531 +               {
7532 +               PK11err_add_data(PK11_F_GET_PRIV_RSA_KEY,
7533 +                   PK11_R_FINDOBJECTSINIT, rv);
7534 +               goto err;
7535 +               }
7537 +       rv = pFuncList->C_FindObjects(session, &h_key, 1, &found);
7539 +       if (rv != CKR_OK)
7540 +               {
7541 +               (void) pFuncList->C_FindObjectsFinal(session);
7542 +               PK11err_add_data(PK11_F_GET_PRIV_RSA_KEY,
7543 +                   PK11_R_FINDOBJECTS, rv);
7544 +               goto err;
7545 +               }
7547 +       rv = pFuncList->C_FindObjectsFinal(session);
7549 +       if (rv != CKR_OK)
7550 +               {
7551 +               PK11err_add_data(PK11_F_GET_PRIV_RSA_KEY,
7552 +                   PK11_R_FINDOBJECTSFINAL, rv);
7553 +               goto err;
7554 +               }
7556 +       if (found == 0)
7557 +               {
7558 +               /*
7559 +                * We have an RSA structure with 'n'/'e' components
7560 +                * only so we tried to find the private key in the
7561 +                * keystore. If it was really a token key we have a
7562 +                * problem. Note that for other key types we just
7563 +                * create a new session key using the private
7564 +                * components from the RSA structure.
7565 +                */
7566 +               if (rsa->d == NULL)
7567 +                       {
7568 +                       PK11err(PK11_F_GET_PRIV_RSA_KEY,
7569 +                           PK11_R_PRIV_KEY_NOT_FOUND);
7570 +                       goto err;
7571 +                       }
7573 +               rv = pFuncList->C_CreateObject(session,
7574 +                       a_key_template, ul_key_attr_count, &h_key);
7575 +               if (rv != CKR_OK)
7576 +                       {
7577 +                       PK11err_add_data(PK11_F_GET_PRIV_RSA_KEY,
7578 +                               PK11_R_CREATEOBJECT, rv);
7579 +                       goto err;
7580 +                       }
7581 +               }
7583 +set:
7584 +       if (rsa_d_num != NULL)
7585 +               {
7586 +               /*
7587 +                * When RSA keys by reference code is used, we never
7588 +                * extract private components from the keystore. In
7589 +                * that case 'd' was set to NULL and we expect the
7590 +                * application to properly cope with that. It is
7591 +                * documented in openssl(5). In general, if keys by
7592 +                * reference are used we expect it to be used
7593 +                * exclusively using the high level API and then there
7594 +                * is no problem. If the application expects the
7595 +                * private components to be read from the keystore
7596 +                * then that is not a supported way of usage.
7597 +                */
7598 +               if (rsa->d != NULL && (*rsa_d_num = BN_dup(rsa->d)) == NULL)
7599 +                       {
7600 +                       PK11err(PK11_F_GET_PRIV_RSA_KEY, PK11_R_MALLOC_FAILURE);
7601 +                       rollback = TRUE;
7602 +                       goto err;
7603 +                       }
7604 +               else
7605 +                       *rsa_d_num = NULL;
7606 +               }
7608 +       /*
7609 +        * For the key by reference code, we need public components as well
7610 +        * since 'd' component is always NULL. For that reason, we always cache
7611 +        * 'n'/'e' components as well.
7612 +        */
7613 +       *rsa_n_num = BN_dup(rsa->n);
7614 +       *rsa_e_num = BN_dup(rsa->e);
7616 +       /* LINTED: E_CONSTANT_CONDITION */
7617 +       KEY_HANDLE_REFHOLD(h_key, OP_RSA, FALSE, rollback, err);
7618 +       if (key_ptr != NULL)
7619 +               *key_ptr = rsa;
7621 +err:
7622 +       if (rollback)
7623 +               {
7624 +               /*
7625 +                * We do not care about the return value from C_DestroyObject()
7626 +                * since we are doing rollback.
7627 +                */
7628 +               if (found == 0 &&
7629 +                   (rsa->flags & RSA_FLAG_EXT_PKEY) == 0)
7630 +                       (void) pFuncList->C_DestroyObject(session, h_key);
7631 +               h_key = CK_INVALID_HANDLE;
7632 +               }
7634 +       UNLOCK_OBJSTORE(OP_RSA);
7636 +malloc_err:
7637 +       /*
7638 +        * 6 to 13 entries in the key template are key components.
7639 +        * They need to be freed upon exit or error.
7640 +        */
7641 +       for (i = 6; i <= 13; i++)
7642 +               {
7643 +               if (a_key_template[i].pValue != NULL)
7644 +                       {
7645 +                       (void) memset(a_key_template[i].pValue, 0,
7646 +                               a_key_template[i].ulValueLen);
7647 +                       OPENSSL_free(a_key_template[i].pValue);
7648 +                       a_key_template[i].pValue = NULL;
7649 +                       }
7650 +               }
7652 +       return (h_key);
7653 +       }
7656 + * Check for cache miss and clean the object pointer and handle
7657 + * in such case. Return 1 for cache hit, 0 for cache miss.
7658 + */
7659 +static int check_new_rsa_key_pub(PK11_SESSION *sp, const RSA *rsa)
7660 +       {
7661 +       /*
7662 +        * Provide protection against RSA structure reuse by making the
7663 +        * check for cache hit stronger. Only public components of RSA
7664 +        * key matter here so it is sufficient to compare them with values
7665 +        * cached in PK11_SESSION structure.
7666 +        *
7667 +        * We must check the handle as well since with key by reference, public
7668 +        * components 'n'/'e' are cached in private keys as well. That means we
7669 +        * could have a cache hit in a private key when looking for a public
7670 +        * key. That would not work, you cannot have one PKCS#11 object for
7671 +        * both data signing and verifying.
7672 +        */
7673 +       if ((sp->opdata_rsa_pub != rsa) ||
7674 +           (BN_cmp(sp->opdata_rsa_n_num, rsa->n) != 0) ||
7675 +           (BN_cmp(sp->opdata_rsa_e_num, rsa->e) != 0) ||
7676 +           (sp->opdata_rsa_priv_key != CK_INVALID_HANDLE))
7677 +               {
7678 +               /*
7679 +                * We do not check the return value because even in case of
7680 +                * failure the sp structure will have both key pointer
7681 +                * and object handle cleaned and pk11_destroy_object()
7682 +                * reports the failure to the OpenSSL error message buffer.
7683 +                */
7684 +               (void) pk11_destroy_rsa_object_pub(sp, TRUE);
7685 +               return (0);
7686 +               }
7687 +       return (1);
7688 +       }
7691 + * Check for cache miss and clean the object pointer and handle
7692 + * in such case. Return 1 for cache hit, 0 for cache miss.
7693 + */
7694 +static int check_new_rsa_key_priv(PK11_SESSION *sp, const RSA *rsa)
7695 +       {
7696 +       /*
7697 +        * Provide protection against RSA structure reuse by making
7698 +        * the check for cache hit stronger. Comparing public exponent
7699 +        * of RSA key with value cached in PK11_SESSION structure
7700 +        * should be sufficient. Note that we want to compare the
7701 +        * public component since with the keys by reference
7702 +        * mechanism, private components are not in the RSA
7703 +        * structure. Also, see check_new_rsa_key_pub() about why we
7704 +        * compare the handle as well.
7705 +        */
7706 +       if ((sp->opdata_rsa_priv != rsa) ||
7707 +           (BN_cmp(sp->opdata_rsa_pn_num, rsa->n) != 0) ||
7708 +           (BN_cmp(sp->opdata_rsa_pe_num, rsa->e) != 0) ||
7709 +           (sp->opdata_rsa_pn_num == NULL) ||
7710 +           (sp->opdata_rsa_pe_num == NULL) ||
7711 +           (sp->opdata_rsa_pub_key != CK_INVALID_HANDLE))
7712 +               {
7713 +               /*
7714 +                * We do not check the return value because even in case of
7715 +                * failure the sp structure will have both key pointer
7716 +                * and object handle cleaned and pk11_destroy_object()
7717 +                * reports the failure to the OpenSSL error message buffer.
7718 +                */
7719 +               (void) pk11_destroy_rsa_object_priv(sp, TRUE);
7720 +               return (0);
7721 +               }
7722 +       return (1);
7723 +       }
7724 +#endif
7726 +#ifndef OPENSSL_NO_DSA
7727 +/* The DSA function implementation */
7728 +/* ARGSUSED */
7729 +static int pk11_DSA_init(DSA *dsa)
7730 +       {
7731 +       return (1);
7732 +       }
7734 +/* ARGSUSED */
7735 +static int pk11_DSA_finish(DSA *dsa)
7736 +       {
7737 +       return (1);
7738 +       }
7741 +static DSA_SIG *
7742 +pk11_dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa)
7743 +       {
7744 +       BIGNUM *r = NULL, *s = NULL;
7745 +       int i;
7746 +       DSA_SIG *dsa_sig = NULL;
7748 +       CK_RV rv;
7749 +       CK_MECHANISM Mechanism_dsa = {CKM_DSA, NULL, 0};
7750 +       CK_MECHANISM *p_mech = &Mechanism_dsa;
7751 +       CK_OBJECT_HANDLE h_priv_key;
7753 +       /*
7754 +        * The signature is the concatenation of r and s,
7755 +        * each is 20 bytes long
7756 +        */
7757 +       unsigned char sigret[DSA_SIGNATURE_LEN];
7758 +       unsigned long siglen = DSA_SIGNATURE_LEN;
7759 +       unsigned int siglen2 = DSA_SIGNATURE_LEN / 2;
7761 +       PK11_SESSION *sp = NULL;
7763 +       if ((dsa->p == NULL) || (dsa->q == NULL) || (dsa->g == NULL))
7764 +               {
7765 +               PK11err(PK11_F_DSA_SIGN, PK11_R_MISSING_KEY_COMPONENT);
7766 +               goto ret;
7767 +               }
7769 +       i = BN_num_bytes(dsa->q); /* should be 20 */
7770 +       if (dlen > i)
7771 +               {
7772 +               PK11err(PK11_F_DSA_SIGN, PK11_R_INVALID_SIGNATURE_LENGTH);
7773 +               goto ret;
7774 +               }
7776 +       if ((sp = pk11_get_session(OP_DSA)) == NULL)
7777 +               goto ret;
7779 +       (void) check_new_dsa_key_priv(sp, dsa);
7781 +       h_priv_key = sp->opdata_dsa_priv_key;
7782 +       if (h_priv_key == CK_INVALID_HANDLE)
7783 +               h_priv_key = sp->opdata_dsa_priv_key =
7784 +                       pk11_get_private_dsa_key((DSA *)dsa,
7785 +                           &sp->opdata_dsa_priv,
7786 +                           &sp->opdata_dsa_priv_num, sp->session);
7788 +       if (h_priv_key != CK_INVALID_HANDLE)
7789 +               {
7790 +               rv = pFuncList->C_SignInit(sp->session, p_mech, h_priv_key);
7792 +               if (rv != CKR_OK)
7793 +                       {
7794 +                       PK11err_add_data(PK11_F_DSA_SIGN, PK11_R_SIGNINIT, rv);
7795 +                       goto ret;
7796 +                       }
7798 +               (void) memset(sigret, 0, siglen);
7799 +               rv = pFuncList->C_Sign(sp->session,
7800 +                       (unsigned char*) dgst, dlen, sigret,
7801 +                       (CK_ULONG_PTR) &siglen);
7803 +               if (rv != CKR_OK)
7804 +                       {
7805 +                       PK11err_add_data(PK11_F_DSA_SIGN, PK11_R_SIGN, rv);
7806 +                       goto ret;
7807 +                       }
7808 +               }
7811 +       if ((s = BN_new()) == NULL)
7812 +               {
7813 +               PK11err(PK11_F_DSA_SIGN, PK11_R_MALLOC_FAILURE);
7814 +               goto ret;
7815 +               }
7817 +       if ((r = BN_new()) == NULL)
7818 +               {
7819 +               PK11err(PK11_F_DSA_SIGN, PK11_R_MALLOC_FAILURE);
7820 +               goto ret;
7821 +               }
7823 +       if ((dsa_sig = DSA_SIG_new()) == NULL)
7824 +               {
7825 +               PK11err(PK11_F_DSA_SIGN, PK11_R_MALLOC_FAILURE);
7826 +               goto ret;
7827 +               }
7829 +       if (BN_bin2bn(sigret, siglen2, r) == NULL ||
7830 +           BN_bin2bn(&sigret[siglen2], siglen2, s) == NULL)
7831 +               {
7832 +               PK11err(PK11_F_DSA_SIGN, PK11_R_MALLOC_FAILURE);
7833 +               goto ret;
7834 +               }
7836 +       dsa_sig->r = r;
7837 +       dsa_sig->s = s;
7839 +ret:
7840 +       if (dsa_sig == NULL)
7841 +               {
7842 +               if (r != NULL)
7843 +                       BN_free(r);
7844 +               if (s != NULL)
7845 +                       BN_free(s);
7846 +               }
7848 +       pk11_return_session(sp, OP_DSA);
7849 +       return (dsa_sig);
7850 +       }
7852 +static int
7853 +pk11_dsa_do_verify(const unsigned char *dgst, int dlen, DSA_SIG *sig,
7854 +       DSA *dsa)
7855 +       {
7856 +       int i;
7857 +       CK_RV rv;
7858 +       int retval = 0;
7859 +       CK_MECHANISM Mechanism_dsa = {CKM_DSA, NULL, 0};
7860 +       CK_MECHANISM *p_mech = &Mechanism_dsa;
7861 +       CK_OBJECT_HANDLE h_pub_key;
7863 +       unsigned char sigbuf[DSA_SIGNATURE_LEN];
7864 +       unsigned long siglen = DSA_SIGNATURE_LEN;
7865 +       unsigned long siglen2 = DSA_SIGNATURE_LEN/2;
7867 +       PK11_SESSION *sp = NULL;
7869 +       if (BN_is_zero(sig->r) || sig->r->neg || BN_ucmp(sig->r, dsa->q) >= 0)
7870 +               {
7871 +               PK11err(PK11_F_DSA_VERIFY,
7872 +                       PK11_R_INVALID_DSA_SIGNATURE_R);
7873 +               goto ret;
7874 +               }
7876 +       if (BN_is_zero(sig->s) || sig->s->neg || BN_ucmp(sig->s, dsa->q) >= 0)
7877 +               {
7878 +               PK11err(PK11_F_DSA_VERIFY,
7879 +                       PK11_R_INVALID_DSA_SIGNATURE_S);
7880 +               goto ret;
7881 +               }
7883 +       i = BN_num_bytes(dsa->q); /* should be 20 */
7885 +       if (dlen > i)
7886 +               {
7887 +               PK11err(PK11_F_DSA_VERIFY,
7888 +                       PK11_R_INVALID_SIGNATURE_LENGTH);
7889 +               goto ret;
7890 +               }
7892 +       if ((sp = pk11_get_session(OP_DSA)) == NULL)
7893 +               goto ret;
7895 +       (void) check_new_dsa_key_pub(sp, dsa);
7897 +       h_pub_key = sp->opdata_dsa_pub_key;
7898 +       if (h_pub_key == CK_INVALID_HANDLE)
7899 +               h_pub_key = sp->opdata_dsa_pub_key =
7900 +                       pk11_get_public_dsa_key((DSA *)dsa, &sp->opdata_dsa_pub,
7901 +                           &sp->opdata_dsa_pub_num, sp->session);
7903 +       if (h_pub_key != CK_INVALID_HANDLE)
7904 +               {
7905 +               rv = pFuncList->C_VerifyInit(sp->session, p_mech,
7906 +                       h_pub_key);
7908 +               if (rv != CKR_OK)
7909 +                       {
7910 +                       PK11err_add_data(PK11_F_DSA_VERIFY, PK11_R_VERIFYINIT,
7911 +                           rv);
7912 +                       goto ret;
7913 +                       }
7915 +               /*
7916 +                * The representation of each of the two big numbers could
7917 +                * be shorter than DSA_SIGNATURE_LEN/2 bytes so we need
7918 +                * to act accordingly and shift if necessary.
7919 +                */
7920 +               (void) memset(sigbuf, 0, siglen);
7921 +               BN_bn2bin(sig->r, sigbuf + siglen2 - BN_num_bytes(sig->r));
7922 +               BN_bn2bin(sig->s, &sigbuf[siglen2] + siglen2 -
7923 +                   BN_num_bytes(sig->s));
7925 +               rv = pFuncList->C_Verify(sp->session,
7926 +                       (unsigned char *) dgst, dlen, sigbuf, (CK_ULONG)siglen);
7928 +               if (rv != CKR_OK)
7929 +                       {
7930 +                       PK11err_add_data(PK11_F_DSA_VERIFY, PK11_R_VERIFY, rv);
7931 +                       goto ret;
7932 +                       }
7933 +               }
7935 +       retval = 1;
7936 +ret:
7938 +       pk11_return_session(sp, OP_DSA);
7939 +       return (retval);
7940 +       }
7944 + * Create a public key object in a session from a given dsa structure.
7945 + * The *dsa_pub_num pointer is non-NULL for DSA public keys.
7946 + */
7947 +static CK_OBJECT_HANDLE pk11_get_public_dsa_key(DSA* dsa,
7948 +    DSA **key_ptr, BIGNUM **dsa_pub_num, CK_SESSION_HANDLE session)
7949 +       {
7950 +       CK_RV rv;
7951 +       CK_OBJECT_CLASS o_key = CKO_PUBLIC_KEY;
7952 +       CK_OBJECT_HANDLE h_key = CK_INVALID_HANDLE;
7953 +       CK_ULONG found;
7954 +       CK_KEY_TYPE k_type = CKK_DSA;
7955 +       CK_ULONG ul_key_attr_count = 8;
7956 +       CK_BBOOL rollback = FALSE;
7957 +       int i;
7959 +       CK_ATTRIBUTE  a_key_template[] =
7960 +               {
7961 +               {CKA_CLASS, (void *) NULL, sizeof (CK_OBJECT_CLASS)},
7962 +               {CKA_KEY_TYPE, (void *) NULL, sizeof (CK_KEY_TYPE)},
7963 +               {CKA_TOKEN, &myfalse, sizeof (myfalse)},
7964 +               {CKA_VERIFY, &mytrue, sizeof (mytrue)},
7965 +               {CKA_PRIME, (void *)NULL, 0},           /* p */
7966 +               {CKA_SUBPRIME, (void *)NULL, 0},        /* q */
7967 +               {CKA_BASE, (void *)NULL, 0},            /* g */
7968 +               {CKA_VALUE, (void *)NULL, 0}            /* pub_key - y */
7969 +               };
7971 +       a_key_template[0].pValue = &o_key;
7972 +       a_key_template[1].pValue = &k_type;
7974 +       if (init_template_value(dsa->p, &a_key_template[4].pValue,
7975 +               &a_key_template[4].ulValueLen) == 0 ||
7976 +           init_template_value(dsa->q, &a_key_template[5].pValue,
7977 +               &a_key_template[5].ulValueLen) == 0 ||
7978 +           init_template_value(dsa->g, &a_key_template[6].pValue,
7979 +               &a_key_template[6].ulValueLen) == 0 ||
7980 +           init_template_value(dsa->pub_key, &a_key_template[7].pValue,
7981 +               &a_key_template[7].ulValueLen) == 0)
7982 +               {
7983 +               PK11err(PK11_F_GET_PUB_DSA_KEY, PK11_R_MALLOC_FAILURE);
7984 +               goto malloc_err;
7985 +               }
7987 +       /* see find_lock array definition for more info on object locking */
7988 +       LOCK_OBJSTORE(OP_DSA);
7989 +       rv = pFuncList->C_FindObjectsInit(session, a_key_template,
7990 +               ul_key_attr_count);
7992 +       if (rv != CKR_OK)
7993 +               {
7994 +               PK11err_add_data(PK11_F_GET_PUB_DSA_KEY,
7995 +                   PK11_R_FINDOBJECTSINIT, rv);
7996 +               goto err;
7997 +               }
7999 +       rv = pFuncList->C_FindObjects(session, &h_key, 1, &found);
8001 +       if (rv != CKR_OK)
8002 +               {
8003 +               (void) pFuncList->C_FindObjectsFinal(session);
8004 +               PK11err_add_data(PK11_F_GET_PUB_DSA_KEY,
8005 +                   PK11_R_FINDOBJECTS, rv);
8006 +               goto err;
8007 +               }
8009 +       rv = pFuncList->C_FindObjectsFinal(session);
8011 +       if (rv != CKR_OK)
8012 +               {
8013 +               PK11err_add_data(PK11_F_GET_PUB_DSA_KEY,
8014 +                   PK11_R_FINDOBJECTSFINAL, rv);
8015 +               goto err;
8016 +               }
8018 +       if (found == 0)
8019 +               {
8020 +               rv = pFuncList->C_CreateObject(session,
8021 +                       a_key_template, ul_key_attr_count, &h_key);
8022 +               if (rv != CKR_OK)
8023 +                       {
8024 +                       PK11err_add_data(PK11_F_GET_PUB_DSA_KEY,
8025 +                           PK11_R_CREATEOBJECT, rv);
8026 +                       goto err;
8027 +                       }
8028 +               }
8030 +       if (dsa_pub_num != NULL)
8031 +               if ((*dsa_pub_num = BN_dup(dsa->pub_key)) == NULL)
8032 +                       {
8033 +                       PK11err(PK11_F_GET_PUB_DSA_KEY, PK11_R_MALLOC_FAILURE);
8034 +                       rollback = TRUE;
8035 +                       goto err;
8036 +                       }
8038 +       /* LINTED: E_CONSTANT_CONDITION */
8039 +       KEY_HANDLE_REFHOLD(h_key, OP_DSA, FALSE, rollback, err);
8040 +       if (key_ptr != NULL)
8041 +               *key_ptr = dsa;
8043 +err:
8044 +       if (rollback)
8045 +               {
8046 +               /*
8047 +                * We do not care about the return value from C_DestroyObject()
8048 +                * since we are doing rollback.
8049 +                */
8050 +               if (found == 0)
8051 +                       (void) pFuncList->C_DestroyObject(session, h_key);
8052 +               h_key = CK_INVALID_HANDLE;
8053 +               }
8055 +       UNLOCK_OBJSTORE(OP_DSA);
8057 +malloc_err:
8058 +       for (i = 4; i <= 7; i++)
8059 +               {
8060 +               if (a_key_template[i].pValue != NULL)
8061 +                       {
8062 +                       OPENSSL_free(a_key_template[i].pValue);
8063 +                       a_key_template[i].pValue = NULL;
8064 +                       }
8065 +               }
8067 +       return (h_key);
8068 +       }
8071 + * Create a private key object in the session from a given dsa structure
8072 + * The *dsa_priv_num pointer is non-NULL for DSA private keys.
8073 + */
8074 +static CK_OBJECT_HANDLE pk11_get_private_dsa_key(DSA* dsa,
8075 +    DSA **key_ptr, BIGNUM **dsa_priv_num, CK_SESSION_HANDLE session)
8076 +       {
8077 +       CK_RV rv;
8078 +       CK_OBJECT_HANDLE h_key = CK_INVALID_HANDLE;
8079 +       CK_OBJECT_CLASS o_key = CKO_PRIVATE_KEY;
8080 +       int i;
8081 +       CK_ULONG found;
8082 +       CK_KEY_TYPE k_type = CKK_DSA;
8083 +       CK_ULONG ul_key_attr_count = 9;
8084 +       CK_BBOOL rollback = FALSE;
8086 +       /* Both CKA_TOKEN and CKA_SENSITIVE have to be FALSE for session keys */
8087 +       CK_ATTRIBUTE  a_key_template[] =
8088 +               {
8089 +               {CKA_CLASS, (void *) NULL, sizeof (CK_OBJECT_CLASS)},
8090 +               {CKA_KEY_TYPE, (void *) NULL, sizeof (CK_KEY_TYPE)},
8091 +               {CKA_TOKEN, &myfalse, sizeof (myfalse)},
8092 +               {CKA_SENSITIVE, &myfalse, sizeof (myfalse)},
8093 +               {CKA_SIGN, &mytrue, sizeof (mytrue)},
8094 +               {CKA_PRIME, (void *)NULL, 0},           /* p */
8095 +               {CKA_SUBPRIME, (void *)NULL, 0},        /* q */
8096 +               {CKA_BASE, (void *)NULL, 0},            /* g */
8097 +               {CKA_VALUE, (void *)NULL, 0}            /* priv_key - x */
8098 +               };
8100 +       a_key_template[0].pValue = &o_key;
8101 +       a_key_template[1].pValue = &k_type;
8103 +       /* Put the private key components into the template */
8104 +       if (init_template_value(dsa->p, &a_key_template[5].pValue,
8105 +               &a_key_template[5].ulValueLen) == 0 ||
8106 +           init_template_value(dsa->q, &a_key_template[6].pValue,
8107 +               &a_key_template[6].ulValueLen) == 0 ||
8108 +           init_template_value(dsa->g, &a_key_template[7].pValue,
8109 +               &a_key_template[7].ulValueLen) == 0 ||
8110 +           init_template_value(dsa->priv_key, &a_key_template[8].pValue,
8111 +               &a_key_template[8].ulValueLen) == 0)
8112 +               {
8113 +               PK11err(PK11_F_GET_PRIV_DSA_KEY, PK11_R_MALLOC_FAILURE);
8114 +               goto malloc_err;
8115 +               }
8117 +       /* see find_lock array definition for more info on object locking */
8118 +       LOCK_OBJSTORE(OP_DSA);
8119 +       rv = pFuncList->C_FindObjectsInit(session, a_key_template,
8120 +               ul_key_attr_count);
8122 +       if (rv != CKR_OK)
8123 +               {
8124 +               PK11err_add_data(PK11_F_GET_PRIV_DSA_KEY,
8125 +                   PK11_R_FINDOBJECTSINIT, rv);
8126 +               goto err;
8127 +               }
8129 +       rv = pFuncList->C_FindObjects(session, &h_key, 1, &found);
8131 +       if (rv != CKR_OK)
8132 +               {
8133 +               (void) pFuncList->C_FindObjectsFinal(session);
8134 +               PK11err_add_data(PK11_F_GET_PRIV_DSA_KEY,
8135 +                   PK11_R_FINDOBJECTS, rv);
8136 +               goto err;
8137 +               }
8139 +       rv = pFuncList->C_FindObjectsFinal(session);
8141 +       if (rv != CKR_OK)
8142 +               {
8143 +               PK11err_add_data(PK11_F_GET_PRIV_DSA_KEY,
8144 +                   PK11_R_FINDOBJECTSFINAL, rv);
8145 +               goto err;
8146 +               }
8148 +       if (found == 0)
8149 +               {
8150 +               rv = pFuncList->C_CreateObject(session,
8151 +                       a_key_template, ul_key_attr_count, &h_key);
8152 +               if (rv != CKR_OK)
8153 +                       {
8154 +                       PK11err_add_data(PK11_F_GET_PRIV_DSA_KEY,
8155 +                           PK11_R_CREATEOBJECT, rv);
8156 +                       goto err;
8157 +                       }
8158 +               }
8160 +       if (dsa_priv_num != NULL)
8161 +               if ((*dsa_priv_num = BN_dup(dsa->priv_key)) == NULL)
8162 +                       {
8163 +                       PK11err(PK11_F_GET_PRIV_DSA_KEY, PK11_R_MALLOC_FAILURE);
8164 +                       rollback = TRUE;
8165 +                       goto err;
8166 +                       }
8168 +       /* LINTED: E_CONSTANT_CONDITION */
8169 +       KEY_HANDLE_REFHOLD(h_key, OP_DSA, FALSE, rollback, err);
8170 +       if (key_ptr != NULL)
8171 +               *key_ptr = dsa;
8173 +err:
8174 +       if (rollback)
8175 +               {
8176 +               /*
8177 +                * We do not care about the return value from C_DestroyObject()
8178 +                * since we are doing rollback.
8179 +                */
8180 +               if (found == 0)
8181 +                       (void) pFuncList->C_DestroyObject(session, h_key);
8182 +               h_key = CK_INVALID_HANDLE;
8183 +               }
8185 +       UNLOCK_OBJSTORE(OP_DSA);
8187 +malloc_err:
8188 +       /*
8189 +        * 5 to 8 entries in the key template are key components.
8190 +        * They need to be freed apon exit or error.
8191 +        */
8192 +       for (i = 5; i <= 8; i++)
8193 +               {
8194 +               if (a_key_template[i].pValue != NULL)
8195 +                       {
8196 +                       (void) memset(a_key_template[i].pValue, 0,
8197 +                               a_key_template[i].ulValueLen);
8198 +                       OPENSSL_free(a_key_template[i].pValue);
8199 +                       a_key_template[i].pValue = NULL;
8200 +                       }
8201 +               }
8203 +       return (h_key);
8204 +       }
8207 + * Check for cache miss and clean the object pointer and handle
8208 + * in such case. Return 1 for cache hit, 0 for cache miss.
8209 + */
8210 +static int check_new_dsa_key_pub(PK11_SESSION *sp, DSA *dsa)
8211 +       {
8212 +       /*
8213 +        * Provide protection against DSA structure reuse by making the
8214 +        * check for cache hit stronger. Only public key component of DSA
8215 +        * key matters here so it is sufficient to compare it with value
8216 +        * cached in PK11_SESSION structure.
8217 +        */
8218 +       if ((sp->opdata_dsa_pub != dsa) ||
8219 +           (BN_cmp(sp->opdata_dsa_pub_num, dsa->pub_key) != 0))
8220 +               {
8221 +               /*
8222 +                * We do not check the return value because even in case of
8223 +                * failure the sp structure will have both key pointer
8224 +                * and object handle cleaned and pk11_destroy_object()
8225 +                * reports the failure to the OpenSSL error message buffer.
8226 +                */
8227 +               (void) pk11_destroy_dsa_object_pub(sp, TRUE);
8228 +               return (0);
8229 +               }
8230 +       return (1);
8231 +       }
8234 + * Check for cache miss and clean the object pointer and handle
8235 + * in such case. Return 1 for cache hit, 0 for cache miss.
8236 + */
8237 +static int check_new_dsa_key_priv(PK11_SESSION *sp, DSA *dsa)
8238 +       {
8239 +       /*
8240 +        * Provide protection against DSA structure reuse by making the
8241 +        * check for cache hit stronger. Only private key component of DSA
8242 +        * key matters here so it is sufficient to compare it with value
8243 +        * cached in PK11_SESSION structure.
8244 +        */
8245 +       if ((sp->opdata_dsa_priv != dsa) ||
8246 +           (BN_cmp(sp->opdata_dsa_priv_num, dsa->priv_key) != 0))
8247 +               {
8248 +               /*
8249 +                * We do not check the return value because even in case of
8250 +                * failure the sp structure will have both key pointer
8251 +                * and object handle cleaned and pk11_destroy_object()
8252 +                * reports the failure to the OpenSSL error message buffer.
8253 +                */
8254 +               (void) pk11_destroy_dsa_object_priv(sp, TRUE);
8255 +               return (0);
8256 +               }
8257 +       return (1);
8258 +       }
8259 +#endif
8262 +#ifndef OPENSSL_NO_DH
8263 +/* The DH function implementation */
8264 +/* ARGSUSED */
8265 +static int pk11_DH_init(DH *dh)
8266 +       {
8267 +       return (1);
8268 +       }
8270 +/* ARGSUSED */
8271 +static int pk11_DH_finish(DH *dh)
8272 +       {
8273 +       return (1);
8274 +       }
8277 + * Generate DH key-pair.
8278 + *
8279 + * Warning: Unlike OpenSSL's DH_generate_key(3) we ignore dh->priv_key
8280 + * and override it even if it is set. OpenSSL does not touch dh->priv_key
8281 + * if set and just computes dh->pub_key. It looks like PKCS#11 standard
8282 + * is not capable of providing this functionality. This could be a problem
8283 + * for applications relying on OpenSSL's semantics.
8284 + */
8285 +static int pk11_DH_generate_key(DH *dh)
8286 +       {
8287 +       CK_ULONG i;
8288 +       CK_RV rv, rv1;
8289 +       int reuse_mem_len = 0, ret = 0;
8290 +       PK11_SESSION *sp = NULL;
8291 +       CK_BYTE_PTR reuse_mem;
8293 +       CK_MECHANISM mechanism = {CKM_DH_PKCS_KEY_PAIR_GEN, NULL_PTR, 0};
8294 +       CK_OBJECT_HANDLE h_pub_key = CK_INVALID_HANDLE;
8295 +       CK_OBJECT_HANDLE h_priv_key = CK_INVALID_HANDLE;
8297 +       CK_ULONG ul_pub_key_attr_count = 3;
8298 +       CK_ATTRIBUTE pub_key_template[] =
8299 +               {
8300 +               {CKA_PRIVATE, &myfalse, sizeof (myfalse)},
8301 +               {CKA_PRIME, (void *)NULL, 0},
8302 +               {CKA_BASE, (void *)NULL, 0}
8303 +               };
8305 +       CK_ULONG ul_priv_key_attr_count = 3;
8306 +       CK_ATTRIBUTE priv_key_template[] =
8307 +               {
8308 +               {CKA_PRIVATE, &myfalse, sizeof (myfalse)},
8309 +               {CKA_SENSITIVE, &myfalse, sizeof (myfalse)},
8310 +               {CKA_DERIVE, &mytrue, sizeof (mytrue)}
8311 +               };
8313 +       CK_ULONG pub_key_attr_result_count = 1;
8314 +       CK_ATTRIBUTE pub_key_result[] =
8315 +               {
8316 +               {CKA_VALUE, (void *)NULL, 0}
8317 +               };
8319 +       CK_ULONG priv_key_attr_result_count = 1;
8320 +       CK_ATTRIBUTE priv_key_result[] =
8321 +               {
8322 +               {CKA_VALUE, (void *)NULL, 0}
8323 +               };
8325 +       pub_key_template[1].ulValueLen = BN_num_bytes(dh->p);
8326 +       if (pub_key_template[1].ulValueLen > 0)
8327 +               {
8328 +               /*
8329 +                * We must not increase ulValueLen by DH_BUF_RESERVE since that
8330 +                * could cause the same rounding problem. See definition of
8331 +                * DH_BUF_RESERVE above.
8332 +                */
8333 +               pub_key_template[1].pValue =
8334 +                       OPENSSL_malloc(pub_key_template[1].ulValueLen +
8335 +                       DH_BUF_RESERVE);
8336 +               if (pub_key_template[1].pValue == NULL)
8337 +                       {
8338 +                       PK11err(PK11_F_DH_GEN_KEY, PK11_R_MALLOC_FAILURE);
8339 +                       goto err;
8340 +                       }
8342 +               i = BN_bn2bin(dh->p, pub_key_template[1].pValue);
8343 +               }
8344 +       else
8345 +               goto err;
8347 +       pub_key_template[2].ulValueLen = BN_num_bytes(dh->g);
8348 +       if (pub_key_template[2].ulValueLen > 0)
8349 +               {
8350 +               pub_key_template[2].pValue =
8351 +                       OPENSSL_malloc(pub_key_template[2].ulValueLen +
8352 +                       DH_BUF_RESERVE);
8353 +               if (pub_key_template[2].pValue == NULL)
8354 +                       {
8355 +                       PK11err(PK11_F_DH_GEN_KEY, PK11_R_MALLOC_FAILURE);
8356 +                       goto err;
8357 +                       }
8359 +               i = BN_bn2bin(dh->g, pub_key_template[2].pValue);
8360 +               }
8361 +       else
8362 +               goto err;
8364 +       /*
8365 +        * Note: we are only using PK11_SESSION structure for getting
8366 +        *       a session handle. The objects created in this function are
8367 +        *       destroyed before return and thus not cached.
8368 +        */
8369 +       if ((sp = pk11_get_session(OP_DH)) == NULL)
8370 +               goto err;
8372 +       rv = pFuncList->C_GenerateKeyPair(sp->session,
8373 +           &mechanism,
8374 +           pub_key_template,
8375 +           ul_pub_key_attr_count,
8376 +           priv_key_template,
8377 +           ul_priv_key_attr_count,
8378 +           &h_pub_key,
8379 +           &h_priv_key);
8380 +       if (rv != CKR_OK)
8381 +               {
8382 +               PK11err_add_data(PK11_F_DH_GEN_KEY, PK11_R_GEN_KEY, rv);
8383 +               goto err;
8384 +               }
8386 +       /*
8387 +        * Reuse the larger memory allocated. We know the larger memory
8388 +        * should be sufficient for reuse.
8389 +        */
8390 +       if (pub_key_template[1].ulValueLen > pub_key_template[2].ulValueLen)
8391 +               {
8392 +               reuse_mem = pub_key_template[1].pValue;
8393 +               reuse_mem_len = pub_key_template[1].ulValueLen + DH_BUF_RESERVE;
8394 +               }
8395 +       else
8396 +               {
8397 +               reuse_mem = pub_key_template[2].pValue;
8398 +               reuse_mem_len = pub_key_template[2].ulValueLen + DH_BUF_RESERVE;
8399 +               }
8401 +       rv = pFuncList->C_GetAttributeValue(sp->session, h_pub_key,
8402 +               pub_key_result, pub_key_attr_result_count);
8403 +       rv1 = pFuncList->C_GetAttributeValue(sp->session, h_priv_key,
8404 +               priv_key_result, priv_key_attr_result_count);
8406 +       if (rv != CKR_OK || rv1 != CKR_OK)
8407 +               {
8408 +               rv = (rv != CKR_OK) ? rv : rv1;
8409 +               PK11err_add_data(PK11_F_DH_GEN_KEY,
8410 +                   PK11_R_GETATTRIBUTVALUE, rv);
8411 +               goto err;
8412 +               }
8414 +       if (((CK_LONG) pub_key_result[0].ulValueLen) <= 0 ||
8415 +               ((CK_LONG) priv_key_result[0].ulValueLen) <= 0)
8416 +               {
8417 +               PK11err(PK11_F_DH_GEN_KEY, PK11_R_GETATTRIBUTVALUE);
8418 +               goto err;
8419 +               }
8421 +       /* Reuse the memory allocated */
8422 +       pub_key_result[0].pValue = reuse_mem;
8423 +       pub_key_result[0].ulValueLen = reuse_mem_len;
8425 +       rv = pFuncList->C_GetAttributeValue(sp->session, h_pub_key,
8426 +               pub_key_result, pub_key_attr_result_count);
8428 +       if (rv != CKR_OK)
8429 +               {
8430 +               PK11err_add_data(PK11_F_DH_GEN_KEY,
8431 +                   PK11_R_GETATTRIBUTVALUE, rv);
8432 +               goto err;
8433 +               }
8435 +       if (pub_key_result[0].type == CKA_VALUE)
8436 +               {
8437 +               if (dh->pub_key == NULL)
8438 +                       if ((dh->pub_key = BN_new()) == NULL)
8439 +                               {
8440 +                               PK11err(PK11_F_DH_GEN_KEY,
8441 +                                       PK11_R_MALLOC_FAILURE);
8442 +                               goto err;
8443 +                               }
8444 +               dh->pub_key = BN_bin2bn(pub_key_result[0].pValue,
8445 +                       pub_key_result[0].ulValueLen, dh->pub_key);
8446 +               if (dh->pub_key == NULL)
8447 +                       {
8448 +                       PK11err(PK11_F_DH_GEN_KEY, PK11_R_MALLOC_FAILURE);
8449 +                       goto err;
8450 +                       }
8451 +               }
8453 +       /* Reuse the memory allocated */
8454 +       priv_key_result[0].pValue = reuse_mem;
8455 +       priv_key_result[0].ulValueLen = reuse_mem_len;
8457 +       rv = pFuncList->C_GetAttributeValue(sp->session, h_priv_key,
8458 +               priv_key_result, priv_key_attr_result_count);
8460 +       if (rv != CKR_OK)
8461 +               {
8462 +               PK11err_add_data(PK11_F_DH_GEN_KEY,
8463 +                   PK11_R_GETATTRIBUTVALUE, rv);
8464 +               goto err;
8465 +               }
8467 +       if (priv_key_result[0].type == CKA_VALUE)
8468 +               {
8469 +               if (dh->priv_key == NULL)
8470 +                       if ((dh->priv_key = BN_new()) == NULL)
8471 +                               {
8472 +                               PK11err(PK11_F_DH_GEN_KEY,
8473 +                                       PK11_R_MALLOC_FAILURE);
8474 +                               goto err;
8475 +                               }
8476 +               dh->priv_key = BN_bin2bn(priv_key_result[0].pValue,
8477 +                       priv_key_result[0].ulValueLen, dh->priv_key);
8478 +               if (dh->priv_key == NULL)
8479 +                       {
8480 +                       PK11err(PK11_F_DH_GEN_KEY, PK11_R_MALLOC_FAILURE);
8481 +                       goto err;
8482 +                       }
8483 +               }
8485 +       ret = 1;
8487 +err:
8489 +       if (h_pub_key != CK_INVALID_HANDLE)
8490 +               {
8491 +               rv = pFuncList->C_DestroyObject(sp->session, h_pub_key);
8492 +               if (rv != CKR_OK)
8493 +                       {
8494 +                       PK11err_add_data(PK11_F_DH_GEN_KEY,
8495 +                           PK11_R_DESTROYOBJECT, rv);
8496 +                       }
8497 +               }
8499 +       if (h_priv_key != CK_INVALID_HANDLE)
8500 +               {
8501 +               rv = pFuncList->C_DestroyObject(sp->session, h_priv_key);
8502 +               if (rv != CKR_OK)
8503 +                       {
8504 +                       PK11err_add_data(PK11_F_DH_GEN_KEY,
8505 +                           PK11_R_DESTROYOBJECT, rv);
8506 +                       }
8507 +               }
8509 +       for (i = 1; i <= 2; i++)
8510 +               {
8511 +               if (pub_key_template[i].pValue != NULL)
8512 +                       {
8513 +                       OPENSSL_free(pub_key_template[i].pValue);
8514 +                       pub_key_template[i].pValue = NULL;
8515 +                       }
8516 +               }
8518 +       pk11_return_session(sp, OP_DH);
8519 +       return (ret);
8520 +       }
8522 +static int pk11_DH_compute_key(unsigned char *key, const BIGNUM *pub_key,
8523 +       DH *dh)
8524 +       {
8525 +       unsigned int i;
8526 +       CK_MECHANISM mechanism = {CKM_DH_PKCS_DERIVE, NULL_PTR, 0};
8527 +       CK_OBJECT_CLASS key_class = CKO_SECRET_KEY;
8528 +       CK_KEY_TYPE key_type = CKK_GENERIC_SECRET;
8529 +       CK_OBJECT_HANDLE h_derived_key = CK_INVALID_HANDLE;
8530 +       CK_OBJECT_HANDLE h_key = CK_INVALID_HANDLE;
8532 +       CK_ULONG seclen;
8533 +       CK_ULONG ul_priv_key_attr_count = 3;
8534 +       CK_ATTRIBUTE priv_key_template[] =
8535 +               {
8536 +               {CKA_CLASS, (void*) NULL, sizeof (key_class)},
8537 +               {CKA_KEY_TYPE, (void*) NULL, sizeof (key_type)},
8538 +               {CKA_VALUE_LEN, &seclen, sizeof (seclen)},
8539 +               };
8541 +       CK_ULONG priv_key_attr_result_count = 1;
8542 +       CK_ATTRIBUTE priv_key_result[] =
8543 +               {
8544 +               {CKA_VALUE, (void *)NULL, 0}
8545 +               };
8547 +       CK_RV rv;
8548 +       int ret = -1;
8549 +       PK11_SESSION *sp = NULL;
8551 +       if (dh->priv_key == NULL)
8552 +               goto err;
8554 +       priv_key_template[0].pValue = &key_class;
8555 +       priv_key_template[1].pValue = &key_type;
8556 +       seclen = BN_num_bytes(dh->p);
8558 +       if ((sp = pk11_get_session(OP_DH)) == NULL)
8559 +               goto err;
8561 +       mechanism.ulParameterLen = BN_num_bytes(pub_key);
8562 +       mechanism.pParameter = OPENSSL_malloc(mechanism.ulParameterLen);
8563 +       if (mechanism.pParameter == NULL)
8564 +               {
8565 +               PK11err(PK11_F_DH_COMP_KEY, PK11_R_MALLOC_FAILURE);
8566 +               goto err;
8567 +               }
8568 +       BN_bn2bin(pub_key, mechanism.pParameter);
8570 +       (void) check_new_dh_key(sp, dh);
8572 +       h_key = sp->opdata_dh_key;
8573 +       if (h_key == CK_INVALID_HANDLE)
8574 +               h_key = sp->opdata_dh_key =
8575 +                       pk11_get_dh_key((DH*) dh, &sp->opdata_dh,
8576 +                           &sp->opdata_dh_priv_num, sp->session);
8578 +       if (h_key == CK_INVALID_HANDLE)
8579 +               {
8580 +               PK11err(PK11_F_DH_COMP_KEY, PK11_R_CREATEOBJECT);
8581 +               goto err;
8582 +               }
8584 +       rv = pFuncList->C_DeriveKey(sp->session,
8585 +           &mechanism,
8586 +           h_key,
8587 +           priv_key_template,
8588 +           ul_priv_key_attr_count,
8589 +           &h_derived_key);
8590 +       if (rv != CKR_OK)
8591 +               {
8592 +               PK11err_add_data(PK11_F_DH_COMP_KEY, PK11_R_DERIVEKEY, rv);
8593 +               goto err;
8594 +               }
8596 +       rv = pFuncList->C_GetAttributeValue(sp->session, h_derived_key,
8597 +           priv_key_result, priv_key_attr_result_count);
8599 +       if (rv != CKR_OK)
8600 +               {
8601 +               PK11err_add_data(PK11_F_DH_COMP_KEY, PK11_R_GETATTRIBUTVALUE,
8602 +                   rv);
8603 +               goto err;
8604 +               }
8606 +       if (((CK_LONG) priv_key_result[0].ulValueLen) <= 0)
8607 +               {
8608 +               PK11err(PK11_F_DH_COMP_KEY, PK11_R_GETATTRIBUTVALUE);
8609 +               goto err;
8610 +               }
8611 +       priv_key_result[0].pValue =
8612 +               OPENSSL_malloc(priv_key_result[0].ulValueLen);
8613 +       if (!priv_key_result[0].pValue)
8614 +               {
8615 +               PK11err(PK11_F_DH_COMP_KEY, PK11_R_MALLOC_FAILURE);
8616 +               goto err;
8617 +               }
8619 +       rv = pFuncList->C_GetAttributeValue(sp->session, h_derived_key,
8620 +               priv_key_result, priv_key_attr_result_count);
8622 +       if (rv != CKR_OK)
8623 +               {
8624 +               PK11err_add_data(PK11_F_DH_COMP_KEY, PK11_R_GETATTRIBUTVALUE,
8625 +                   rv);
8626 +               goto err;
8627 +               }
8629 +       /*
8630 +        * OpenSSL allocates the output buffer 'key' which is the same
8631 +        * length of the public key. It is long enough for the derived key
8632 +        */
8633 +       if (priv_key_result[0].type == CKA_VALUE)
8634 +               {
8635 +               /*
8636 +                * CKM_DH_PKCS_DERIVE mechanism is not supposed to strip
8637 +                * leading zeros from a computed shared secret. However,
8638 +                * OpenSSL always did it so we must do the same here. The
8639 +                * vagueness of the spec regarding leading zero bytes was
8640 +                * finally cleared with TLS 1.1 (RFC 4346) saying that leading
8641 +                * zeros are stripped before the computed data is used as the
8642 +                * pre-master secret.
8643 +                */
8644 +               for (i = 0; i < priv_key_result[0].ulValueLen; ++i)
8645 +                       {
8646 +                       if (((char *)priv_key_result[0].pValue)[i] != 0)
8647 +                               break;
8648 +                       }
8650 +               (void) memcpy(key, ((char *)priv_key_result[0].pValue) + i,
8651 +                       priv_key_result[0].ulValueLen - i);
8652 +               ret = priv_key_result[0].ulValueLen - i;
8653 +               }
8655 +err:
8657 +       if (h_derived_key != CK_INVALID_HANDLE)
8658 +               {
8659 +               rv = pFuncList->C_DestroyObject(sp->session, h_derived_key);
8660 +               if (rv != CKR_OK)
8661 +                       {
8662 +                       PK11err_add_data(PK11_F_DH_COMP_KEY,
8663 +                           PK11_R_DESTROYOBJECT, rv);
8664 +                       }
8665 +               }
8666 +       if (priv_key_result[0].pValue)
8667 +               {
8668 +               OPENSSL_free(priv_key_result[0].pValue);
8669 +               priv_key_result[0].pValue = NULL;
8670 +               }
8672 +       if (mechanism.pParameter)
8673 +               {
8674 +               OPENSSL_free(mechanism.pParameter);
8675 +               mechanism.pParameter = NULL;
8676 +               }
8678 +       pk11_return_session(sp, OP_DH);
8679 +       return (ret);
8680 +       }
8683 +static CK_OBJECT_HANDLE pk11_get_dh_key(DH* dh,
8684 +       DH **key_ptr, BIGNUM **dh_priv_num, CK_SESSION_HANDLE session)
8685 +       {
8686 +       CK_RV rv;
8687 +       CK_OBJECT_HANDLE h_key = CK_INVALID_HANDLE;
8688 +       CK_OBJECT_CLASS class = CKO_PRIVATE_KEY;
8689 +       CK_KEY_TYPE key_type = CKK_DH;
8690 +       CK_ULONG found;
8691 +       CK_BBOOL rollback = FALSE;
8692 +       int i;
8694 +       CK_ULONG ul_key_attr_count = 7;
8695 +       CK_ATTRIBUTE key_template[] =
8696 +               {
8697 +               {CKA_CLASS, (void*) NULL, sizeof (class)},
8698 +               {CKA_KEY_TYPE, (void*) NULL, sizeof (key_type)},
8699 +               {CKA_DERIVE, &mytrue, sizeof (mytrue)},
8700 +               {CKA_PRIVATE, &myfalse, sizeof (myfalse)},
8701 +               {CKA_PRIME, (void *) NULL, 0},
8702 +               {CKA_BASE, (void *) NULL, 0},
8703 +               {CKA_VALUE, (void *) NULL, 0},
8704 +               };
8706 +       key_template[0].pValue = &class;
8707 +       key_template[1].pValue = &key_type;
8709 +       key_template[4].ulValueLen = BN_num_bytes(dh->p);
8710 +       key_template[4].pValue = (CK_VOID_PTR)OPENSSL_malloc(
8711 +               (size_t)key_template[4].ulValueLen);
8712 +       if (key_template[4].pValue == NULL)
8713 +               {
8714 +               PK11err(PK11_F_GET_DH_KEY, PK11_R_MALLOC_FAILURE);
8715 +               goto malloc_err;
8716 +               }
8718 +       BN_bn2bin(dh->p, key_template[4].pValue);
8720 +       key_template[5].ulValueLen = BN_num_bytes(dh->g);
8721 +       key_template[5].pValue = (CK_VOID_PTR)OPENSSL_malloc(
8722 +               (size_t)key_template[5].ulValueLen);
8723 +       if (key_template[5].pValue == NULL)
8724 +               {
8725 +               PK11err(PK11_F_GET_DH_KEY, PK11_R_MALLOC_FAILURE);
8726 +               goto malloc_err;
8727 +               }
8729 +       BN_bn2bin(dh->g, key_template[5].pValue);
8731 +       key_template[6].ulValueLen = BN_num_bytes(dh->priv_key);
8732 +       key_template[6].pValue = (CK_VOID_PTR)OPENSSL_malloc(
8733 +               (size_t)key_template[6].ulValueLen);
8734 +       if (key_template[6].pValue == NULL)
8735 +               {
8736 +               PK11err(PK11_F_GET_DH_KEY, PK11_R_MALLOC_FAILURE);
8737 +               goto malloc_err;
8738 +               }
8740 +       BN_bn2bin(dh->priv_key, key_template[6].pValue);
8742 +       /* see find_lock array definition for more info on object locking */
8743 +       LOCK_OBJSTORE(OP_DH);
8744 +       rv = pFuncList->C_FindObjectsInit(session, key_template,
8745 +               ul_key_attr_count);
8747 +       if (rv != CKR_OK)
8748 +               {
8749 +               PK11err_add_data(PK11_F_GET_DH_KEY, PK11_R_FINDOBJECTSINIT, rv);
8750 +               goto err;
8751 +               }
8753 +       rv = pFuncList->C_FindObjects(session, &h_key, 1, &found);
8755 +       if (rv != CKR_OK)
8756 +               {
8757 +               (void) pFuncList->C_FindObjectsFinal(session);
8758 +               PK11err_add_data(PK11_F_GET_DH_KEY, PK11_R_FINDOBJECTS, rv);
8759 +               goto err;
8760 +               }
8762 +       rv = pFuncList->C_FindObjectsFinal(session);
8764 +       if (rv != CKR_OK)
8765 +               {
8766 +               PK11err_add_data(PK11_F_GET_DH_KEY, PK11_R_FINDOBJECTSFINAL,
8767 +                   rv);
8768 +               goto err;
8769 +               }
8771 +       if (found == 0)
8772 +               {
8773 +               rv = pFuncList->C_CreateObject(session,
8774 +                       key_template, ul_key_attr_count, &h_key);
8775 +               if (rv != CKR_OK)
8776 +                       {
8777 +                       PK11err_add_data(PK11_F_GET_DH_KEY, PK11_R_CREATEOBJECT,
8778 +                           rv);
8779 +                       goto err;
8780 +                       }
8781 +               }
8783 +       if (dh_priv_num != NULL)
8784 +               if ((*dh_priv_num = BN_dup(dh->priv_key)) == NULL)
8785 +                       {
8786 +                       PK11err(PK11_F_GET_DH_KEY, PK11_R_MALLOC_FAILURE);
8787 +                       rollback = TRUE;
8788 +                       goto err;
8789 +                       }
8791 +       /* LINTED: E_CONSTANT_CONDITION */
8792 +       KEY_HANDLE_REFHOLD(h_key, OP_DH, FALSE, rollback, err);
8793 +       if (key_ptr != NULL)
8794 +               *key_ptr = dh;
8796 +err:
8797 +       if (rollback)
8798 +               {
8799 +               /*
8800 +                * We do not care about the return value from C_DestroyObject()
8801 +                * since we are doing rollback.
8802 +                */
8803 +               if (found == 0)
8804 +                       (void) pFuncList->C_DestroyObject(session, h_key);
8805 +               h_key = CK_INVALID_HANDLE;
8806 +               }
8808 +       UNLOCK_OBJSTORE(OP_DH);
8810 +malloc_err:
8811 +       for (i = 4; i <= 6; i++)
8812 +               {
8813 +               if (key_template[i].pValue != NULL)
8814 +                       {
8815 +                       OPENSSL_free(key_template[i].pValue);
8816 +                       key_template[i].pValue = NULL;
8817 +                       }
8818 +               }
8820 +       return (h_key);
8821 +       }
8824 + * Check for cache miss and clean the object pointer and handle
8825 + * in such case. Return 1 for cache hit, 0 for cache miss.
8826 + *
8827 + * Note: we rely on pk11_destroy_dh_key_objects() to set sp->opdata_dh
8828 + *       to CK_INVALID_HANDLE even when it fails to destroy the object.
8829 + */
8830 +static int check_new_dh_key(PK11_SESSION *sp, DH *dh)
8831 +       {
8832 +       /*
8833 +        * Provide protection against DH structure reuse by making the
8834 +        * check for cache hit stronger. Private key component of DH key
8835 +        * is unique so it is sufficient to compare it with value cached
8836 +        * in PK11_SESSION structure.
8837 +        */
8838 +       if ((sp->opdata_dh != dh) ||
8839 +           (BN_cmp(sp->opdata_dh_priv_num, dh->priv_key) != 0))
8840 +               {
8841 +               /*
8842 +                * We do not check the return value because even in case of
8843 +                * failure the sp structure will have both key pointer
8844 +                * and object handle cleaned and pk11_destroy_object()
8845 +                * reports the failure to the OpenSSL error message buffer.
8846 +                */
8847 +               (void) pk11_destroy_dh_object(sp, TRUE);
8848 +               return (0);
8849 +               }
8850 +       return (1);
8851 +       }
8852 +#endif
8855 + * Local function to simplify key template population
8856 + * Return 0 -- error, 1 -- no error
8857 + */
8858 +static int
8859 +init_template_value(BIGNUM *bn, CK_VOID_PTR *p_value,
8860 +       CK_ULONG *ul_value_len)
8861 +       {
8862 +       CK_ULONG len = 0;
8864 +       /*
8865 +        * This function can be used on non-initialized BIGNUMs. It is
8866 +        * easier to check that here than individually in the callers.
8867 +        */
8868 +       if (bn != NULL)
8869 +               len = BN_num_bytes(bn);
8871 +       if (bn == NULL || len == 0)
8872 +               return (1);
8874 +       *ul_value_len = len;
8875 +       *p_value = (CK_VOID_PTR)OPENSSL_malloc((size_t)*ul_value_len);
8876 +       if (*p_value == NULL)
8877 +               return (0);
8879 +       BN_bn2bin(bn, *p_value);
8881 +       return (1);
8882 +       }
8884 +static void
8885 +attr_to_BN(CK_ATTRIBUTE_PTR attr, CK_BYTE attr_data[], BIGNUM **bn)
8886 +       {
8887 +       if (attr->ulValueLen > 0)
8888 +               *bn = BN_bin2bn(attr_data, attr->ulValueLen, NULL);
8889 +       }
8892 + * Find one object in the token. It is an error if we can not find the
8893 + * object or if we find more objects based on the template we got.
8894 + * Assume object store locked.
8895 + *
8896 + * Returns:
8897 + *     1 OK
8898 + *     0 no object or more than 1 object found
8899 + */
8900 +static int
8901 +find_one_object(PK11_OPTYPE op, CK_SESSION_HANDLE s,
8902 +    CK_ATTRIBUTE_PTR ptempl, CK_ULONG nattr, CK_OBJECT_HANDLE_PTR pkey)
8903 +       {
8904 +       CK_RV rv;
8905 +       CK_ULONG objcnt;
8907 +       if ((rv = pFuncList->C_FindObjectsInit(s, ptempl, nattr)) != CKR_OK)
8908 +               {
8909 +               PK11err_add_data(PK11_F_FIND_ONE_OBJECT,
8910 +                   PK11_R_FINDOBJECTSINIT, rv);
8911 +               return (0);
8912 +               }
8914 +       rv = pFuncList->C_FindObjects(s, pkey, 1, &objcnt);
8915 +       if (rv != CKR_OK)
8916 +               {
8917 +               (void) pFuncList->C_FindObjectsFinal(s);
8918 +               PK11err_add_data(PK11_F_FIND_ONE_OBJECT, PK11_R_FINDOBJECTS,
8919 +                   rv);
8920 +               return (0);
8921 +               }
8923 +       (void) pFuncList->C_FindObjectsFinal(s);
8925 +       if (objcnt > 1)
8926 +               {
8927 +               PK11err(PK11_F_FIND_ONE_OBJECT,
8928 +                   PK11_R_MORE_THAN_ONE_OBJECT_FOUND);
8929 +               return (0);
8930 +               }
8931 +       else if (objcnt == 0)
8932 +               {
8933 +               PK11err(PK11_F_FIND_ONE_OBJECT, PK11_R_NO_OBJECT_FOUND);
8934 +               return (0);
8935 +               }
8936 +       return (1);
8937 +       }
8939 +/* from uri stuff */
8941 +extern char *pk11_pin;
8943 +static int pk11_get_pin(void);
8945 +static int
8946 +pk11_get_pin(void)
8948 +       char *pin;
8950 +       /* The getpassphrase() function is not MT safe. */
8951 +#ifndef NOPTHREADS
8952 +       OPENSSL_assert(pthread_mutex_lock(token_lock) == 0);
8953 +#else
8954 +       CRYPTO_w_lock(CRYPTO_LOCK_PK11_ENGINE);
8955 +#endif
8956 +       pin = getpassphrase("Enter PIN: ");
8957 +       if (pin == NULL)
8958 +               {
8959 +               PK11err(PK11_F_GET_PIN, PK11_R_COULD_NOT_READ_PIN);
8960 +#ifndef NOPTHREADS
8961 +               OPENSSL_assert(pthread_mutex_unlock(token_lock) == 0);
8962 +#else
8963 +               CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
8964 +#endif
8965 +               return (0);
8966 +               }
8967 +       pk11_pin = BUF_strdup(pin);
8968 +       if (pk11_pin == NULL)
8969 +               {
8970 +               PK11err(PK11_F_LOAD_PRIVKEY, PK11_R_MALLOC_FAILURE);
8971 +#ifndef NOPTHREADS
8972 +               OPENSSL_assert(pthread_mutex_unlock(token_lock) == 0);
8973 +#else
8974 +               CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
8975 +#endif
8976 +               return (0);
8977 +               }
8978 +       memset(pin, 0, strlen(pin));
8979 +#ifndef NOPTHREADS
8980 +       OPENSSL_assert(pthread_mutex_unlock(token_lock) == 0);
8981 +#else
8982 +       CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
8983 +#endif
8984 +       return (1);
8985 +       }
8988 + * Log in to the keystore if we are supposed to do that at all. Take care of
8989 + * reading and caching the PIN etc. Log in only once even when called from
8990 + * multiple threads.
8991 + *
8992 + * Returns:
8993 + *     1 on success
8994 + *     0 on failure
8995 + */
8996 +static int
8997 +pk11_token_login(CK_SESSION_HANDLE session, CK_BBOOL *login_done,
8998 +    CK_BBOOL is_private)
8999 +       {
9000 +       CK_RV rv;
9002 +#if 0
9003 +       /* doesn't work on the AEP Keyper??? */
9004 +       if ((pubkey_token_flags & CKF_TOKEN_INITIALIZED) == 0)
9005 +               {
9006 +               PK11err(PK11_F_TOKEN_LOGIN,
9007 +                   PK11_R_TOKEN_NOT_INITIALIZED);
9008 +               return (0);
9009 +               }
9010 +#endif
9012 +       /*
9013 +        * If login is required or needed but the PIN has not been
9014 +        * even initialized we can bail out right now. Note that we
9015 +        * are supposed to always log in if we are going to access
9016 +        * private keys. However, we may need to log in even for
9017 +        * accessing public keys in case that the CKF_LOGIN_REQUIRED
9018 +        * flag is set.
9019 +        */
9020 +       if (((pubkey_token_flags & CKF_LOGIN_REQUIRED) ||
9021 +            (is_private == CK_TRUE)) &&
9022 +           (~pubkey_token_flags & CKF_USER_PIN_INITIALIZED))
9023 +               {
9024 +               PK11err(PK11_F_TOKEN_LOGIN, PK11_R_TOKEN_PIN_NOT_SET);
9025 +               return (0);
9026 +               }
9028 +       /*
9029 +        * Note on locking: it is possible that more than one thread
9030 +        * gets into pk11_get_pin() so we must deal with that. We
9031 +        * cannot avoid it since we cannot guard fork() in there with
9032 +        * a lock because we could end up in a dead lock in the
9033 +        * child. Why? Remember we are in a multithreaded environment
9034 +        * so we must lock all mutexes in the prefork function to
9035 +        * avoid a situation in which a thread that did not call
9036 +        * fork() held a lock, making future unlocking impossible. We
9037 +        * lock right before C_Login().
9038 +        */
9039 +       if ((pubkey_token_flags & CKF_LOGIN_REQUIRED) ||
9040 +           (is_private == CK_TRUE))
9041 +               {
9042 +               if (*login_done == CK_FALSE)
9043 +                       {
9044 +                       if ((pk11_pin == NULL) && (pk11_get_pin() == 0))
9045 +                               {
9046 +                               PK11err(PK11_F_TOKEN_LOGIN,
9047 +                                   PK11_R_TOKEN_PIN_NOT_PROVIDED);
9048 +                               return (0);
9049 +                               }
9050 +                       }
9052 +               /*
9053 +                * Note that what we are logging into is the keystore from
9054 +                * pubkey_SLOTID because we work with OP_RSA session type here.
9055 +                * That also means that we can work with only one keystore in
9056 +                * the engine.
9057 +                *
9058 +                * We must make sure we do not try to login more than once.
9059 +                * Also, see the comment above on locking strategy.
9060 +                */
9062 +#ifndef NOPTHREADS
9063 +               OPENSSL_assert(pthread_mutex_lock(token_lock) == 0);
9064 +#else
9065 +               CRYPTO_w_lock(CRYPTO_LOCK_PK11_ENGINE);
9066 +#endif
9067 +               if (*login_done == CK_FALSE)
9068 +                       {
9069 +                       if ((rv = pFuncList->C_Login(session,
9070 +                           CKU_USER, (CK_UTF8CHAR*)pk11_pin,
9071 +                           strlen(pk11_pin))) != CKR_OK)
9072 +                               {
9073 +                               PK11err_add_data(PK11_F_TOKEN_LOGIN,
9074 +                                   PK11_R_TOKEN_LOGIN_FAILED, rv);
9075 +                               goto err_locked;
9076 +                               }
9078 +                       *login_done = CK_TRUE;
9080 +                       }
9081 +#ifndef NOPTHREADS
9082 +               OPENSSL_assert(pthread_mutex_unlock(token_lock) == 0);
9083 +#else
9084 +               CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
9085 +#endif
9086 +               }
9087 +       else
9088 +               {
9089 +                       /*
9090 +                        * If token does not require login we take it as the
9091 +                        * login was done.
9092 +                        */
9093 +                       *login_done = CK_TRUE;
9094 +               }
9096 +       return (1);
9098 +err_locked:
9099 +       if (pk11_pin) {
9100 +               memset(pk11_pin, 0, strlen(pk11_pin));
9101 +               OPENSSL_free((void*)pk11_pin);
9102 +       }
9103 +       pk11_pin = NULL;
9104 +#ifndef NOPTHREADS
9105 +       OPENSSL_assert(pthread_mutex_unlock(token_lock) == 0);
9106 +#else
9107 +       CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
9108 +#endif
9109 +       return (0);
9110 +       }
9113 + * Log in to the keystore in the child if we were logged in in the
9114 + * parent. There are similarities in the code with pk11_token_login()
9115 + * but still it is quite different so we need a separate function for
9116 + * this.
9117 + *
9118 + * Note that this function is called under the locked session mutex when fork is
9119 + * detected. That means that C_Login() will be called from the child just once.
9120 + *
9121 + * Returns:
9122 + *     1 on success
9123 + *     0 on failure
9124 + */
9125 +int
9126 +pk11_token_relogin(CK_SESSION_HANDLE session)
9127 +       {
9128 +       CK_RV rv;
9130 +       if ((pk11_pin == NULL) && (pk11_get_pin() == 0))
9131 +               return (0);
9133 +#ifndef NOPTHREADS
9134 +       OPENSSL_assert(pthread_mutex_lock(token_lock) == 0);
9135 +#else
9136 +       CRYPTO_w_lock(CRYPTO_LOCK_PK11_ENGINE);
9137 +#endif
9138 +       if ((rv = pFuncList->C_Login(session, CKU_USER,
9139 +           (CK_UTF8CHAR_PTR)pk11_pin, strlen(pk11_pin))) != CKR_OK)
9140 +               {
9141 +               PK11err_add_data(PK11_F_TOKEN_RELOGIN,
9142 +                   PK11_R_TOKEN_LOGIN_FAILED, rv);
9143 +#ifndef NOPTHREADS
9144 +               OPENSSL_assert(pthread_mutex_unlock(token_lock) == 0);
9145 +#else
9146 +               CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
9147 +#endif
9148 +               return (0);
9149 +               }
9150 +#ifndef NOPTHREADS
9151 +       OPENSSL_assert(pthread_mutex_unlock(token_lock) == 0);
9152 +#else
9153 +       CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
9154 +#endif
9156 +       return (1);
9157 +       }
9159 +#ifdef OPENSSL_SYS_WIN32
9160 +char *getpassphrase(const char *prompt)
9161 +       {
9162 +       static char buf[128];
9163 +       HANDLE h;
9164 +       DWORD cc, mode;
9165 +       int cnt;
9167 +       h = GetStdHandle(STD_INPUT_HANDLE);
9168 +       fputs(prompt, stderr);
9169 +       fflush(stderr);
9170 +       fflush(stdout);
9171 +       FlushConsoleInputBuffer(h);
9172 +       GetConsoleMode(h, &mode);
9173 +       SetConsoleMode(h, ENABLE_PROCESSED_INPUT);
9175 +       for (cnt = 0; cnt < sizeof(buf) - 1; cnt++)
9176 +               {
9177 +               ReadFile(h, buf + cnt, 1, &cc, NULL);
9178 +               if (buf[cnt] == '\r')
9179 +                       break;
9180 +               fputc('*', stdout);
9181 +               fflush(stderr);
9182 +               fflush(stdout);
9183 +               }
9185 +       SetConsoleMode(h, mode);
9186 +       buf[cnt] = '\0';
9187 +       fputs("\n", stderr);
9188 +       return buf;
9189 +       }
9190 +#endif /* OPENSSL_SYS_WIN32 */
9191 +#endif /* OPENSSL_NO_HW_PK11CA */
9192 +#endif /* OPENSSL_NO_HW_PK11 */
9193 +#endif /* OPENSSL_NO_HW */
9194 Index: openssl/crypto/engine/hw_pk11ca.h
9195 diff -u /dev/null openssl/crypto/engine/hw_pk11ca.h:1.2.4.2
9196 --- /dev/null   Fri Jan  2 13:56:41 2015
9197 +++ openssl/crypto/engine/hw_pk11ca.h   Wed Jun 15 21:12:32 2011
9198 @@ -0,0 +1,32 @@
9199 +/* Redefine all pk11/PK11 external symbols to pk11ca/PK11CA */
9201 +#define token_lock                     pk11ca_token_lock
9202 +#define find_lock                      pk11ca_find_lock
9203 +#define active_list                    pk11ca_active_list
9204 +#define pubkey_token_flags             pk11ca_pubkey_token_flags
9205 +#define pubkey_SLOTID                  pk11ca_pubkey_SLOTID
9206 +#define ERR_pk11_error                 ERR_pk11ca_error
9207 +#define PK11err_add_data               PK11CAerr_add_data
9208 +#define pk11_get_session               pk11ca_get_session
9209 +#define pk11_return_session            pk11ca_return_session
9210 +#define pk11_active_add                        pk11ca_active_add
9211 +#define pk11_active_delete             pk11ca_active_delete
9212 +#define pk11_active_remove             pk11ca_active_remove
9213 +#define pk11_free_active_list          pk11ca_free_active_list
9214 +#define pk11_destroy_rsa_key_objects   pk11ca_destroy_rsa_key_objects
9215 +#define pk11_destroy_rsa_object_pub    pk11ca_destroy_rsa_object_pub
9216 +#define pk11_destroy_rsa_object_priv   pk11ca_destroy_rsa_object_priv
9217 +#define pk11_load_privkey              pk11ca_load_privkey
9218 +#define pk11_load_pubkey               pk11ca_load_pubkey
9219 +#define PK11_RSA                       PK11CA_RSA
9220 +#define pk11_destroy_dsa_key_objects   pk11ca_destroy_dsa_key_objects
9221 +#define pk11_destroy_dsa_object_pub    pk11ca_destroy_dsa_object_pub
9222 +#define pk11_destroy_dsa_object_priv   pk11ca_destroy_dsa_object_priv
9223 +#define PK11_DSA                       PK11CA_DSA
9224 +#define pk11_destroy_dh_key_objects    pk11ca_destroy_dh_key_objects
9225 +#define pk11_destroy_dh_object         pk11ca_destroy_dh_object
9226 +#define PK11_DH                                PK11CA_DH
9227 +#define pk11_token_relogin             pk11ca_token_relogin
9228 +#define pFuncList                      pk11ca_pFuncList
9229 +#define pk11_pin                       pk11ca_pin
9230 +#define ENGINE_load_pk11               ENGINE_load_pk11ca
9231 Index: openssl/crypto/engine/hw_pk11so.c
9232 diff -u /dev/null openssl/crypto/engine/hw_pk11so.c:1.3.4.3
9233 --- /dev/null   Fri Jan  2 13:56:41 2015
9234 +++ openssl/crypto/engine/hw_pk11so.c   Fri Oct  4 14:45:25 2013
9235 @@ -0,0 +1,1775 @@
9237 + * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
9238 + * Use is subject to license terms.
9239 + */
9241 +/* crypto/engine/hw_pk11.c */
9243 + * This product includes software developed by the OpenSSL Project for
9244 + * use in the OpenSSL Toolkit (http://www.openssl.org/).
9245 + *
9246 + * This project also referenced hw_pkcs11-0.9.7b.patch written by
9247 + * Afchine Madjlessi.
9248 + */
9250 + * ====================================================================
9251 + * Copyright (c) 2000-2001 The OpenSSL Project.  All rights reserved.
9252 + *
9253 + * Redistribution and use in source and binary forms, with or without
9254 + * modification, are permitted provided that the following conditions
9255 + * are met:
9256 + *
9257 + * 1. Redistributions of source code must retain the above copyright
9258 + *    notice, this list of conditions and the following disclaimer.
9259 + *
9260 + * 2. Redistributions in binary form must reproduce the above copyright
9261 + *    notice, this list of conditions and the following disclaimer in
9262 + *    the documentation and/or other materials provided with the
9263 + *    distribution.
9264 + *
9265 + * 3. All advertising materials mentioning features or use of this
9266 + *    software must display the following acknowledgment:
9267 + *    "This product includes software developed by the OpenSSL Project
9268 + *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
9269 + *
9270 + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
9271 + *    endorse or promote products derived from this software without
9272 + *    prior written permission. For written permission, please contact
9273 + *    licensing@OpenSSL.org.
9274 + *
9275 + * 5. Products derived from this software may not be called "OpenSSL"
9276 + *    nor may "OpenSSL" appear in their names without prior written
9277 + *    permission of the OpenSSL Project.
9278 + *
9279 + * 6. Redistributions of any form whatsoever must retain the following
9280 + *    acknowledgment:
9281 + *    "This product includes software developed by the OpenSSL Project
9282 + *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
9283 + *
9284 + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
9285 + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
9286 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
9287 + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
9288 + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
9289 + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
9290 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
9291 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
9292 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
9293 + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
9294 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
9295 + * OF THE POSSIBILITY OF SUCH DAMAGE.
9296 + * ====================================================================
9297 + *
9298 + * This product includes cryptographic software written by Eric Young
9299 + * (eay@cryptsoft.com).  This product includes software written by Tim
9300 + * Hudson (tjh@cryptsoft.com).
9301 + *
9302 + */
9304 +/* Modified to keep only RNG and RSA Sign */
9306 +#ifdef OPENSSL_NO_RSA
9307 +#error RSA is disabled
9308 +#endif
9310 +#include <stdio.h>
9311 +#include <stdlib.h>
9312 +#include <string.h>
9313 +#include <sys/types.h>
9315 +#include <openssl/e_os2.h>
9316 +#include <openssl/crypto.h>
9317 +#include <cryptlib.h>
9318 +#include <openssl/engine.h>
9319 +#include <openssl/dso.h>
9320 +#include <openssl/err.h>
9321 +#include <openssl/bn.h>
9322 +#include <openssl/md5.h>
9323 +#include <openssl/pem.h>
9324 +#include <openssl/rsa.h>
9325 +#include <openssl/rand.h>
9326 +#include <openssl/objects.h>
9327 +#include <openssl/x509.h>
9329 +#ifdef OPENSSL_SYS_WIN32
9330 +typedef int pid_t;
9331 +#define getpid() GetCurrentProcessId()
9332 +#define NOPTHREADS
9333 +#ifndef NULL_PTR
9334 +#define NULL_PTR NULL
9335 +#endif
9336 +#define CK_DEFINE_FUNCTION(returnType, name) \
9337 +       returnType __declspec(dllexport) name
9338 +#define CK_DECLARE_FUNCTION(returnType, name) \
9339 +       returnType __declspec(dllimport) name
9340 +#define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
9341 +       returnType __declspec(dllimport) (* name)
9342 +#else
9343 +#include <signal.h>
9344 +#include <unistd.h>
9345 +#include <dlfcn.h>
9346 +#endif
9348 +/* Debug mutexes */
9349 +/*#undef DEBUG_MUTEX */
9350 +#define DEBUG_MUTEX
9352 +#ifndef NOPTHREADS
9353 +/* for pthread error check on Linuxes */
9354 +#ifdef DEBUG_MUTEX
9355 +#define __USE_UNIX98
9356 +#endif
9357 +#include <pthread.h>
9358 +#endif
9360 +#ifndef OPENSSL_NO_HW
9361 +#ifndef OPENSSL_NO_HW_PK11
9362 +#ifndef OPENSSL_NO_HW_PK11SO
9364 +/* label for debug messages printed on stderr */
9365 +#define        PK11_DBG        "PKCS#11 ENGINE DEBUG"
9366 +/* prints a lot of debug messages on stderr about slot selection process */
9367 +/*#undef       DEBUG_SLOT_SELECTION */
9369 +#ifndef OPENSSL_NO_DSA
9370 +#define OPENSSL_NO_DSA
9371 +#endif
9372 +#ifndef OPENSSL_NO_DH
9373 +#define OPENSSL_NO_DH
9374 +#endif
9376 +#ifdef OPENSSL_SYS_WIN32
9377 +#pragma pack(push, cryptoki, 1)
9378 +#include "cryptoki.h"
9379 +#include "pkcs11.h"
9380 +#pragma pack(pop, cryptoki)
9381 +#else
9382 +#include "cryptoki.h"
9383 +#include "pkcs11.h"
9384 +#endif
9385 +#include "hw_pk11so.h"
9386 +#include "hw_pk11_err.c"
9389 + * We use this lock to prevent multiple C_Login()s, guard getpassphrase(),
9390 + * uri_struct manipulation, and static token info. All of that is used by the
9391 + * RSA keys by reference feature.
9392 + */
9393 +#ifndef NOPTHREADS
9394 +pthread_mutex_t *token_lock;
9395 +#endif
9397 +/* PKCS#11 session caches and their locks for all operation types */
9398 +static PK11_CACHE session_cache[OP_MAX];
9401 + * We cache the flags so that we do not have to run C_GetTokenInfo() again when
9402 + * logging into the token.
9403 + */
9404 +CK_FLAGS pubkey_token_flags;
9407 + * As stated in v2.20, 11.7 Object Management Function, in section for
9408 + * C_FindObjectsInit(), at most one search operation may be active at a given
9409 + * time in a given session. Therefore, C_Find{,Init,Final}Objects() should be
9410 + * grouped together to form one atomic search operation. This is already
9411 + * ensured by the property of unique PKCS#11 session handle used for each
9412 + * PK11_SESSION object.
9413 + *
9414 + * This is however not the biggest concern - maintaining consistency of the
9415 + * underlying object store is more important. The same section of the spec also
9416 + * says that one thread can be in the middle of a search operation while another
9417 + * thread destroys the object matching the search template which would result in
9418 + * invalid handle returned from the search operation.
9419 + *
9420 + * Hence, the following locks are used for both protection of the object stores.
9421 + * They are also used for active list protection.
9422 + */
9423 +#ifndef NOPTHREADS
9424 +pthread_mutex_t *find_lock[OP_MAX] = { NULL };
9425 +#endif
9428 + * lists of asymmetric key handles which are active (referenced by at least one
9429 + * PK11_SESSION structure, either held by a thread or present in free_session
9430 + * list) for given algorithm type
9431 + */
9432 +PK11_active *active_list[OP_MAX] = { NULL };
9435 + * Create all secret key objects in a global session so that they are available
9436 + * to use for other sessions. These other sessions may be opened or closed
9437 + * without losing the secret key objects.
9438 + */
9439 +static CK_SESSION_HANDLE       global_session = CK_INVALID_HANDLE;
9441 +/* ENGINE level stuff */
9442 +static int pk11_init(ENGINE *e);
9443 +static int pk11_library_init(ENGINE *e);
9444 +static int pk11_finish(ENGINE *e);
9445 +static int pk11_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void));
9446 +static int pk11_destroy(ENGINE *e);
9448 +/* RAND stuff */
9449 +static void pk11_rand_seed(const void *buf, int num);
9450 +static void pk11_rand_add(const void *buf, int num, double add_entropy);
9451 +static void pk11_rand_cleanup(void);
9452 +static int pk11_rand_bytes(unsigned char *buf, int num);
9453 +static int pk11_rand_status(void);
9455 +/* These functions are also used in other files */
9456 +PK11_SESSION *pk11_get_session(PK11_OPTYPE optype);
9457 +void pk11_return_session(PK11_SESSION *sp, PK11_OPTYPE optype);
9459 +/* active list manipulation functions used in this file */
9460 +extern int pk11_active_delete(CK_OBJECT_HANDLE h, PK11_OPTYPE type);
9461 +extern void pk11_free_active_list(PK11_OPTYPE type);
9463 +int pk11_destroy_rsa_key_objects(PK11_SESSION *session);
9464 +int pk11_destroy_rsa_object_pub(PK11_SESSION *sp, CK_BBOOL uselock);
9465 +int pk11_destroy_rsa_object_priv(PK11_SESSION *sp, CK_BBOOL uselock);
9467 +/* Local helper functions */
9468 +static int pk11_free_all_sessions(void);
9469 +static int pk11_free_session_list(PK11_OPTYPE optype);
9470 +static int pk11_setup_session(PK11_SESSION *sp, PK11_OPTYPE optype);
9471 +static int pk11_destroy_object(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE oh,
9472 +       CK_BBOOL persistent);
9473 +static const char *get_PK11_LIBNAME(void);
9474 +static void free_PK11_LIBNAME(void);
9475 +static long set_PK11_LIBNAME(const char *name);
9477 +static int pk11_choose_slots(int *any_slot_found);
9479 +static int pk11_init_all_locks(void);
9480 +static void pk11_free_all_locks(void);
9482 +#define        TRY_OBJ_DESTROY(sp, obj_hdl, retval, uselock, alg_type, priv)   \
9483 +       {                                                               \
9484 +       if (uselock)                                                    \
9485 +               LOCK_OBJSTORE(alg_type);                                \
9486 +       if (pk11_active_delete(obj_hdl, alg_type) == 1)                 \
9487 +               {                                                       \
9488 +                 retval = pk11_destroy_object(sp->session, obj_hdl,    \
9489 +                 priv ? sp->priv_persistent : sp->pub_persistent);     \
9490 +               }                                                       \
9491 +       if (uselock)                                                    \
9492 +               UNLOCK_OBJSTORE(alg_type);                              \
9493 +       }
9495 +static CK_BBOOL pk11_have_rsa  = CK_FALSE;
9496 +static CK_BBOOL pk11_have_random = CK_FALSE;
9499 + * Initialization function. Sets up various PKCS#11 library components.
9500 + * The definitions for control commands specific to this engine
9501 + */
9502 +#define PK11_CMD_SO_PATH               ENGINE_CMD_BASE
9503 +#define PK11_CMD_PIN                   (ENGINE_CMD_BASE+1)
9504 +#define PK11_CMD_SLOT                  (ENGINE_CMD_BASE+2)
9505 +static const ENGINE_CMD_DEFN pk11_cmd_defns[] =
9506 +       {
9507 +               {
9508 +               PK11_CMD_SO_PATH,
9509 +               "SO_PATH",
9510 +               "Specifies the path to the 'pkcs#11' shared library",
9511 +               ENGINE_CMD_FLAG_STRING
9512 +               },
9513 +               {
9514 +               PK11_CMD_PIN,
9515 +               "PIN",
9516 +               "Specifies the pin code",
9517 +               ENGINE_CMD_FLAG_STRING
9518 +               },
9519 +               {
9520 +               PK11_CMD_SLOT,
9521 +               "SLOT",
9522 +               "Specifies the slot (default is auto select)",
9523 +               ENGINE_CMD_FLAG_NUMERIC,
9524 +               },
9525 +               {0, NULL, NULL, 0}
9526 +       };
9529 +static RAND_METHOD pk11_random =
9530 +       {
9531 +       pk11_rand_seed,
9532 +       pk11_rand_bytes,
9533 +       pk11_rand_cleanup,
9534 +       pk11_rand_add,
9535 +       pk11_rand_bytes,
9536 +       pk11_rand_status
9537 +       };
9540 +/* Constants used when creating the ENGINE */
9541 +#ifdef OPENSSL_NO_HW_PK11CA
9542 +#error "can't load both crypto-accelerator and sign-only PKCS#11 engines"
9543 +#endif
9544 +static const char *engine_pk11_id = "pkcs11";
9545 +static const char *engine_pk11_name = "PKCS #11 engine support (sign only)";
9547 +CK_FUNCTION_LIST_PTR pFuncList = NULL;
9548 +static const char PK11_GET_FUNCTION_LIST[] = "C_GetFunctionList";
9551 + * This is a static string constant for the DSO file name and the function
9552 + * symbol names to bind to. We set it in the Configure script based on whether
9553 + * this is 32 or 64 bit build.
9554 + */
9555 +static const char def_PK11_LIBNAME[] = PK11_LIB_LOCATION;
9557 +/* Needed in hw_pk11_pub.c as well so that's why it is not static. */
9558 +CK_SLOT_ID pubkey_SLOTID = 0;
9559 +static CK_SLOT_ID rand_SLOTID = 0;
9560 +static CK_SLOT_ID SLOTID = 0;
9561 +char *pk11_pin = NULL;
9562 +static CK_BBOOL pk11_library_initialized = FALSE;
9563 +static CK_BBOOL pk11_atfork_initialized = FALSE;
9564 +static int pk11_pid = 0;
9566 +static DSO *pk11_dso = NULL;
9568 +/* allocate and initialize all locks used by the engine itself */
9569 +static int pk11_init_all_locks(void)
9570 +       {
9571 +#ifndef NOPTHREADS
9572 +       int type;
9573 +       pthread_mutexattr_t attr;
9575 +       if (pthread_mutexattr_init(&attr) != 0)
9576 +       {
9577 +               PK11err(PK11_F_INIT_ALL_LOCKS, 100);
9578 +               return (0);
9579 +       }
9581 +#ifdef DEBUG_MUTEX
9582 +       if (pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK) != 0)
9583 +       {
9584 +               PK11err(PK11_F_INIT_ALL_LOCKS, 101);
9585 +               return (0);
9586 +       }
9587 +#endif
9589 +       if ((token_lock = OPENSSL_malloc(sizeof (pthread_mutex_t))) == NULL)
9590 +               goto malloc_err;
9591 +       (void) pthread_mutex_init(token_lock, &attr);
9593 +       find_lock[OP_RSA] = OPENSSL_malloc(sizeof (pthread_mutex_t));
9594 +       if (find_lock[OP_RSA] == NULL)
9595 +               goto malloc_err;
9596 +       (void) pthread_mutex_init(find_lock[OP_RSA], &attr);
9598 +       for (type = 0; type < OP_MAX; type++)
9599 +               {
9600 +               session_cache[type].lock =
9601 +                   OPENSSL_malloc(sizeof (pthread_mutex_t));
9602 +               if (session_cache[type].lock == NULL)
9603 +                       goto malloc_err;
9604 +               (void) pthread_mutex_init(session_cache[type].lock, &attr);
9605 +               }
9607 +       return (1);
9609 +malloc_err:
9610 +       pk11_free_all_locks();
9611 +       PK11err(PK11_F_INIT_ALL_LOCKS, PK11_R_MALLOC_FAILURE);
9612 +       return (0);
9613 +#else
9614 +       return (1);
9615 +#endif
9616 +       }
9618 +static void pk11_free_all_locks(void)
9619 +       {
9620 +#ifndef NOPTHREADS
9621 +       int type;
9623 +       if (token_lock != NULL)
9624 +               {
9625 +               (void) pthread_mutex_destroy(token_lock);
9626 +               OPENSSL_free(token_lock);
9627 +               token_lock = NULL;
9628 +               }
9630 +       if (find_lock[OP_RSA] != NULL)
9631 +               {
9632 +               (void) pthread_mutex_destroy(find_lock[OP_RSA]);
9633 +               OPENSSL_free(find_lock[OP_RSA]);
9634 +               find_lock[OP_RSA] = NULL;
9635 +               }
9637 +       for (type = 0; type < OP_MAX; type++)
9638 +               {
9639 +               if (session_cache[type].lock != NULL)
9640 +                       {
9641 +                       (void) pthread_mutex_destroy(session_cache[type].lock);
9642 +                       OPENSSL_free(session_cache[type].lock);
9643 +                       session_cache[type].lock = NULL;
9644 +                       }
9645 +               }
9646 +#endif
9647 +       }
9650 + * This internal function is used by ENGINE_pk11() and "dynamic" ENGINE support.
9651 + */
9652 +static int bind_pk11(ENGINE *e)
9653 +       {
9654 +       if (!pk11_library_initialized)
9655 +               if (!pk11_library_init(e))
9656 +                       return (0);
9658 +       if (!ENGINE_set_id(e, engine_pk11_id) ||
9659 +           !ENGINE_set_name(e, engine_pk11_name))
9660 +               return (0);
9662 +       if (pk11_have_rsa == CK_TRUE)
9663 +               {
9664 +               if (!ENGINE_set_RSA(e, PK11_RSA()) ||
9665 +                   !ENGINE_set_load_privkey_function(e, pk11_load_privkey) ||
9666 +                   !ENGINE_set_load_pubkey_function(e, pk11_load_pubkey))
9667 +                       return (0);
9668 +#ifdef DEBUG_SLOT_SELECTION
9669 +               fprintf(stderr, "%s: registered RSA\n", PK11_DBG);
9670 +#endif /* DEBUG_SLOT_SELECTION */
9671 +               }
9673 +       if (pk11_have_random)
9674 +               {
9675 +               if (!ENGINE_set_RAND(e, &pk11_random))
9676 +                       return (0);
9677 +#ifdef DEBUG_SLOT_SELECTION
9678 +               fprintf(stderr, "%s: registered random\n", PK11_DBG);
9679 +#endif /* DEBUG_SLOT_SELECTION */
9680 +               }
9681 +       if (!ENGINE_set_init_function(e, pk11_init) ||
9682 +           !ENGINE_set_destroy_function(e, pk11_destroy) ||
9683 +           !ENGINE_set_finish_function(e, pk11_finish) ||
9684 +           !ENGINE_set_ctrl_function(e, pk11_ctrl) ||
9685 +           !ENGINE_set_cmd_defns(e, pk11_cmd_defns))
9686 +               return (0);
9688 +       /* Ensure the pk11 error handling is set up */
9689 +       ERR_load_pk11_strings();
9691 +       return (1);
9692 +       }
9694 +/* Dynamic engine support is disabled at a higher level for Solaris */
9695 +#ifdef ENGINE_DYNAMIC_SUPPORT
9696 +#error "dynamic engine not supported"
9697 +static int bind_helper(ENGINE *e, const char *id)
9698 +       {
9699 +       if (id && (strcmp(id, engine_pk11_id) != 0))
9700 +               return (0);
9702 +       if (!bind_pk11(e))
9703 +               return (0);
9705 +       return (1);
9706 +       }
9708 +IMPLEMENT_DYNAMIC_CHECK_FN()
9709 +IMPLEMENT_DYNAMIC_BIND_FN(bind_helper)
9711 +#else
9712 +static ENGINE *engine_pk11(void)
9713 +       {
9714 +       ENGINE *ret = ENGINE_new();
9716 +       if (!ret)
9717 +               return (NULL);
9719 +       if (!bind_pk11(ret))
9720 +               {
9721 +               ENGINE_free(ret);
9722 +               return (NULL);
9723 +               }
9725 +       return (ret);
9726 +       }
9728 +void
9729 +ENGINE_load_pk11(void)
9730 +       {
9731 +       ENGINE *e_pk11 = NULL;
9733 +       /*
9734 +        * Do not use dynamic PKCS#11 library on Solaris due to
9735 +        * security reasons. We will link it in statically.
9736 +        */
9737 +       /* Attempt to load PKCS#11 library */
9738 +       if (!pk11_dso)
9739 +               pk11_dso = DSO_load(NULL, get_PK11_LIBNAME(), NULL, 0);
9741 +       if (pk11_dso == NULL)
9742 +               {
9743 +               PK11err(PK11_F_LOAD, PK11_R_DSO_FAILURE);
9744 +               return;
9745 +               }
9747 +       e_pk11 = engine_pk11();
9748 +       if (!e_pk11)
9749 +               {
9750 +               DSO_free(pk11_dso);
9751 +               pk11_dso = NULL;
9752 +               return;
9753 +               }
9755 +       /*
9756 +        * At this point, the pk11 shared library is either dynamically
9757 +        * loaded or statically linked in. So, initialize the pk11
9758 +        * library before calling ENGINE_set_default since the latter
9759 +        * needs cipher and digest algorithm information
9760 +        */
9761 +       if (!pk11_library_init(e_pk11))
9762 +               {
9763 +               DSO_free(pk11_dso);
9764 +               pk11_dso = NULL;
9765 +               ENGINE_free(e_pk11);
9766 +               return;
9767 +               }
9769 +       ENGINE_add(e_pk11);
9771 +       ENGINE_free(e_pk11);
9772 +       ERR_clear_error();
9773 +       }
9774 +#endif /* ENGINE_DYNAMIC_SUPPORT */
9777 + * These are the static string constants for the DSO file name and
9778 + * the function symbol names to bind to.
9779 + */
9780 +static const char *PK11_LIBNAME = NULL;
9782 +static const char *get_PK11_LIBNAME(void)
9783 +       {
9784 +       if (PK11_LIBNAME)
9785 +               return (PK11_LIBNAME);
9787 +       return (def_PK11_LIBNAME);
9788 +       }
9790 +static void free_PK11_LIBNAME(void)
9791 +       {
9792 +       if (PK11_LIBNAME)
9793 +               OPENSSL_free((void*)PK11_LIBNAME);
9795 +       PK11_LIBNAME = NULL;
9796 +       }
9798 +static long set_PK11_LIBNAME(const char *name)
9799 +       {
9800 +       free_PK11_LIBNAME();
9802 +       return ((PK11_LIBNAME = BUF_strdup(name)) != NULL ? 1 : 0);
9803 +       }
9805 +/* acquire all engine specific mutexes before fork */
9806 +static void pk11_fork_prepare(void)
9807 +       {
9808 +#ifndef NOPTHREADS
9809 +       int i;
9811 +       if (!pk11_library_initialized)
9812 +               return;
9814 +       LOCK_OBJSTORE(OP_RSA);
9815 +       OPENSSL_assert(pthread_mutex_lock(token_lock) == 0);
9816 +       for (i = 0; i < OP_MAX; i++)
9817 +               {
9818 +               OPENSSL_assert(pthread_mutex_lock(session_cache[i].lock) == 0);
9819 +               }
9820 +#endif
9821 +       }
9823 +/* release all engine specific mutexes */
9824 +static void pk11_fork_parent(void)
9825 +       {
9826 +#ifndef NOPTHREADS
9827 +       int i;
9829 +       if (!pk11_library_initialized)
9830 +               return;
9832 +       for (i = OP_MAX - 1; i >= 0; i--)
9833 +               {
9834 +               OPENSSL_assert(pthread_mutex_unlock(session_cache[i].lock) == 0);
9835 +               }
9836 +       UNLOCK_OBJSTORE(OP_RSA);
9837 +       OPENSSL_assert(pthread_mutex_unlock(token_lock) == 0);
9838 +#endif
9839 +       }
9842 + * same situation as in parent - we need to unlock all locks to make them
9843 + * accessible to all threads.
9844 + */
9845 +static void pk11_fork_child(void)
9846 +       {
9847 +#ifndef NOPTHREADS
9848 +       int i;
9850 +       if (!pk11_library_initialized)
9851 +               return;
9853 +       for (i = OP_MAX - 1; i >= 0; i--)
9854 +               {
9855 +               OPENSSL_assert(pthread_mutex_unlock(session_cache[i].lock) == 0);
9856 +               }
9857 +       UNLOCK_OBJSTORE(OP_RSA);
9858 +       OPENSSL_assert(pthread_mutex_unlock(token_lock) == 0);
9859 +#endif
9860 +       }
9862 +/* Initialization function for the pk11 engine */
9863 +static int pk11_init(ENGINE *e)
9865 +       return (pk11_library_init(e));
9868 +static CK_C_INITIALIZE_ARGS pk11_init_args =
9869 +       {
9870 +       NULL_PTR,               /* CreateMutex */
9871 +       NULL_PTR,               /* DestroyMutex */
9872 +       NULL_PTR,               /* LockMutex */
9873 +       NULL_PTR,               /* UnlockMutex */
9874 +       CKF_OS_LOCKING_OK,      /* flags */
9875 +       NULL_PTR,               /* pReserved */
9876 +       };
9879 + * Initialization function. Sets up various PKCS#11 library components.
9880 + * It selects a slot based on predefined critiera. In the process, it also
9881 + * count how many ciphers and digests to support. Since the cipher and
9882 + * digest information is needed when setting default engine, this function
9883 + * needs to be called before calling ENGINE_set_default.
9884 + */
9885 +/* ARGSUSED */
9886 +static int pk11_library_init(ENGINE *e)
9887 +       {
9888 +       CK_C_GetFunctionList p;
9889 +       CK_RV rv = CKR_OK;
9890 +       CK_INFO info;
9891 +       int any_slot_found;
9892 +       int i;
9893 +#ifndef OPENSSL_SYS_WIN32
9894 +       struct sigaction sigint_act, sigterm_act, sighup_act;
9895 +#endif
9897 +       /*
9898 +        * pk11_library_initialized is set to 0 in pk11_finish() which
9899 +        * is called from ENGINE_finish(). However, if there is still
9900 +        * at least one existing functional reference to the engine
9901 +        * (see engine(3) for more information), pk11_finish() is
9902 +        * skipped. For example, this can happen if an application
9903 +        * forgets to clear one cipher context. In case of a fork()
9904 +        * when the application is finishing the engine so that it can
9905 +        * be reinitialized in the child, forgotten functional
9906 +        * reference causes pk11_library_initialized to stay 1. In
9907 +        * that case we need the PID check so that we properly
9908 +        * initialize the engine again.
9909 +        */
9910 +       if (pk11_library_initialized)
9911 +               {
9912 +               if (pk11_pid == getpid())
9913 +                       {
9914 +                       return (1);
9915 +                       }
9916 +               else
9917 +                       {
9918 +                       global_session = CK_INVALID_HANDLE;
9919 +                       /*
9920 +                        * free the locks first to prevent memory leak in case
9921 +                        * the application calls fork() without finishing the
9922 +                        * engine first.
9923 +                        */
9924 +                       pk11_free_all_locks();
9925 +                       }
9926 +               }
9928 +       if (pk11_dso == NULL)
9929 +               {
9930 +               PK11err(PK11_F_LIBRARY_INIT, PK11_R_DSO_FAILURE);
9931 +               goto err;
9932 +               }
9934 +       /* get the C_GetFunctionList function from the loaded library */
9935 +       p = (CK_C_GetFunctionList)DSO_bind_func(pk11_dso,
9936 +               PK11_GET_FUNCTION_LIST);
9937 +       if (!p)
9938 +               {
9939 +               PK11err(PK11_F_LIBRARY_INIT, PK11_R_DSO_FAILURE);
9940 +               goto err;
9941 +               }
9943 +       /* get the full function list from the loaded library */
9944 +       rv = p(&pFuncList);
9945 +       if (rv != CKR_OK)
9946 +               {
9947 +               PK11err_add_data(PK11_F_LIBRARY_INIT, PK11_R_DSO_FAILURE, rv);
9948 +               goto err;
9949 +               }
9951 +#ifndef OPENSSL_SYS_WIN32
9952 +       /* Not all PKCS#11 library are signal safe! */
9954 +       (void) memset(&sigint_act, 0, sizeof(sigint_act));
9955 +       (void) memset(&sigterm_act, 0, sizeof(sigterm_act));
9956 +       (void) memset(&sighup_act, 0, sizeof(sighup_act));
9957 +       (void) sigaction(SIGINT, NULL, &sigint_act);
9958 +       (void) sigaction(SIGTERM, NULL, &sigterm_act);
9959 +       (void) sigaction(SIGHUP, NULL, &sighup_act);
9960 +#endif
9961 +       rv = pFuncList->C_Initialize((CK_VOID_PTR)&pk11_init_args);
9962 +#ifndef OPENSSL_SYS_WIN32
9963 +       (void) sigaction(SIGINT, &sigint_act, NULL);
9964 +       (void) sigaction(SIGTERM, &sigterm_act, NULL);
9965 +       (void) sigaction(SIGHUP, &sighup_act, NULL);
9966 +#endif
9967 +       if ((rv != CKR_OK) && (rv != CKR_CRYPTOKI_ALREADY_INITIALIZED))
9968 +               {
9969 +               PK11err_add_data(PK11_F_LIBRARY_INIT, PK11_R_INITIALIZE, rv);
9970 +               goto err;
9971 +               }
9973 +       rv = pFuncList->C_GetInfo(&info);
9974 +       if (rv != CKR_OK)
9975 +               {
9976 +               PK11err_add_data(PK11_F_LIBRARY_INIT, PK11_R_GETINFO, rv);
9977 +               goto err;
9978 +               }
9980 +       if (pk11_choose_slots(&any_slot_found) == 0)
9981 +               goto err;
9983 +       /*
9984 +        * The library we use, set in def_PK11_LIBNAME, may not offer any
9985 +        * slot(s). In that case, we must not proceed but we must not return an
9986 +        * error. The reason is that applications that try to set up the PKCS#11
9987 +        * engine don't exit on error during the engine initialization just
9988 +        * because no slot was present.
9989 +        */
9990 +       if (any_slot_found == 0)
9991 +               return (1);
9993 +       if (global_session == CK_INVALID_HANDLE)
9994 +               {
9995 +               /* Open the global_session for the new process */
9996 +               rv = pFuncList->C_OpenSession(SLOTID, CKF_SERIAL_SESSION,
9997 +                       NULL_PTR, NULL_PTR, &global_session);
9998 +               if (rv != CKR_OK)
9999 +                       {
10000 +                       PK11err_add_data(PK11_F_LIBRARY_INIT,
10001 +                           PK11_R_OPENSESSION, rv);
10002 +                       goto err;
10003 +                       }
10004 +               }
10006 +       pk11_library_initialized = TRUE;
10007 +       pk11_pid = getpid();
10008 +       /*
10009 +        * if initialization of the locks fails pk11_init_all_locks()
10010 +        * will do the cleanup.
10011 +        */
10012 +       if (!pk11_init_all_locks())
10013 +               goto err;
10014 +       for (i = 0; i < OP_MAX; i++)
10015 +               session_cache[i].head = NULL;
10016 +       /*
10017 +        * initialize active lists. We only use active lists
10018 +        * for asymmetric ciphers.
10019 +        */
10020 +       for (i = 0; i < OP_MAX; i++)
10021 +               active_list[i] = NULL;
10023 +#ifndef NOPTHREADS
10024 +       if (!pk11_atfork_initialized)
10025 +               {
10026 +               if (pthread_atfork(pk11_fork_prepare, pk11_fork_parent,
10027 +                   pk11_fork_child) != 0)
10028 +                       {
10029 +                       PK11err(PK11_F_LIBRARY_INIT, PK11_R_ATFORK_FAILED);
10030 +                       goto err;
10031 +                       }
10032 +               pk11_atfork_initialized = TRUE;
10033 +               }
10034 +#endif
10036 +       return (1);
10038 +err:
10039 +       return (0);
10040 +       }
10042 +/* Destructor (complements the "ENGINE_pk11()" constructor) */
10043 +/* ARGSUSED */
10044 +static int pk11_destroy(ENGINE *e)
10045 +       {
10046 +       free_PK11_LIBNAME();
10047 +       ERR_unload_pk11_strings();
10048 +       if (pk11_pin) {
10049 +               memset(pk11_pin, 0, strlen(pk11_pin));
10050 +               OPENSSL_free((void*)pk11_pin);
10051 +       }
10052 +       pk11_pin = NULL;
10053 +       return (1);
10054 +       }
10057 + * Termination function to clean up the session, the token, and the pk11
10058 + * library.
10059 + */
10060 +/* ARGSUSED */
10061 +static int pk11_finish(ENGINE *e)
10062 +       {
10063 +       int i;
10065 +       if (pk11_pin) {
10066 +               memset(pk11_pin, 0, strlen(pk11_pin));
10067 +               OPENSSL_free((void*)pk11_pin);
10068 +       }
10069 +       pk11_pin = NULL;
10071 +       if (pk11_dso == NULL)
10072 +               {
10073 +               PK11err(PK11_F_FINISH, PK11_R_NOT_LOADED);
10074 +               goto err;
10075 +               }
10077 +       OPENSSL_assert(pFuncList != NULL);
10079 +       if (pk11_free_all_sessions() == 0)
10080 +               goto err;
10082 +       /* free all active lists */
10083 +       for (i = 0; i < OP_MAX; i++)
10084 +               pk11_free_active_list(i);
10086 +       pFuncList->C_CloseSession(global_session);
10087 +       global_session = CK_INVALID_HANDLE;
10089 +       /*
10090 +        * Since we are part of a library (libcrypto.so), calling this function
10091 +        * may have side-effects.
10092 +        */
10093 +#if 0
10094 +       pFuncList->C_Finalize(NULL);
10095 +#endif
10097 +       if (!DSO_free(pk11_dso))
10098 +               {
10099 +               PK11err(PK11_F_FINISH, PK11_R_DSO_FAILURE);
10100 +               goto err;
10101 +               }
10102 +       pk11_dso = NULL;
10103 +       pFuncList = NULL;
10104 +       pk11_library_initialized = FALSE;
10105 +       pk11_pid = 0;
10106 +       /*
10107 +        * There is no way how to unregister atfork handlers (other than
10108 +        * unloading the library) so we just free the locks. For this reason
10109 +        * the atfork handlers check if the engine is initialized and bail out
10110 +        * immediately if not. This is necessary in case a process finishes
10111 +        * the engine before calling fork().
10112 +        */
10113 +       pk11_free_all_locks();
10115 +       return (1);
10117 +err:
10118 +       return (0);
10119 +       }
10121 +/* Standard engine interface function to set the dynamic library path */
10122 +/* ARGSUSED */
10123 +static int pk11_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void))
10124 +       {
10125 +       int initialized = ((pk11_dso == NULL) ? 0 : 1);
10127 +       switch (cmd)
10128 +               {
10129 +       case PK11_CMD_SO_PATH:
10130 +               if (p == NULL)
10131 +                       {
10132 +                       PK11err(PK11_F_CTRL, ERR_R_PASSED_NULL_PARAMETER);
10133 +                       return (0);
10134 +                       }
10136 +               if (initialized)
10137 +                       {
10138 +                       PK11err(PK11_F_CTRL, PK11_R_ALREADY_LOADED);
10139 +                       return (0);
10140 +                       }
10142 +               return (set_PK11_LIBNAME((const char *)p));
10143 +       case PK11_CMD_PIN:
10144 +               if (pk11_pin) {
10145 +                       memset(pk11_pin, 0, strlen(pk11_pin));
10146 +                       OPENSSL_free((void*)pk11_pin);
10147 +               }
10148 +               pk11_pin = NULL;
10150 +               if (p == NULL)
10151 +                       {
10152 +                       PK11err(PK11_F_CTRL, ERR_R_PASSED_NULL_PARAMETER);
10153 +                       return (0);
10154 +                       }
10156 +               pk11_pin = BUF_strdup(p);
10157 +               if (pk11_pin == NULL)
10158 +                       {
10159 +                       PK11err(PK11_F_GET_SESSION, PK11_R_MALLOC_FAILURE);
10160 +                       return (0);
10161 +                       }
10162 +               return (1);
10163 +       case PK11_CMD_SLOT:
10164 +               SLOTID = (CK_SLOT_ID)i;
10165 +#ifdef DEBUG_SLOT_SELECTION
10166 +               fprintf(stderr, "%s: slot set\n", PK11_DBG);
10167 +#endif
10168 +               return (1);
10169 +       default:
10170 +               break;
10171 +               }
10173 +       PK11err(PK11_F_CTRL, PK11_R_CTRL_COMMAND_NOT_IMPLEMENTED);
10175 +       return (0);
10176 +       }
10179 +/* Required function by the engine random interface. It does nothing here */
10180 +static void pk11_rand_cleanup(void)
10181 +       {
10182 +       return;
10183 +       }
10185 +/* ARGSUSED */
10186 +static void pk11_rand_add(const void *buf, int num, double add)
10187 +       {
10188 +       PK11_SESSION *sp;
10190 +       if ((sp = pk11_get_session(OP_RAND)) == NULL)
10191 +               return;
10193 +       /*
10194 +        * Ignore any errors (e.g. CKR_RANDOM_SEED_NOT_SUPPORTED) since
10195 +        * the calling functions do not care anyway
10196 +        */
10197 +       pFuncList->C_SeedRandom(sp->session, (unsigned char *) buf, num);
10198 +       pk11_return_session(sp, OP_RAND);
10200 +       return;
10201 +       }
10203 +static void pk11_rand_seed(const void *buf, int num)
10204 +       {
10205 +       pk11_rand_add(buf, num, 0);
10206 +       }
10208 +static int pk11_rand_bytes(unsigned char *buf, int num)
10209 +       {
10210 +       CK_RV rv;
10211 +       PK11_SESSION *sp;
10213 +       if ((sp = pk11_get_session(OP_RAND)) == NULL)
10214 +               return (0);
10216 +       rv = pFuncList->C_GenerateRandom(sp->session, buf, num);
10217 +       if (rv != CKR_OK)
10218 +               {
10219 +               PK11err_add_data(PK11_F_RAND_BYTES, PK11_R_GENERATERANDOM, rv);
10220 +               pk11_return_session(sp, OP_RAND);
10221 +               return (0);
10222 +               }
10224 +       pk11_return_session(sp, OP_RAND);
10225 +       return (1);
10226 +       }
10228 +/* Required function by the engine random interface. It does nothing here */
10229 +static int pk11_rand_status(void)
10230 +       {
10231 +       return (1);
10232 +       }
10234 +/* Free all BIGNUM structures from PK11_SESSION. */
10235 +static void pk11_free_nums(PK11_SESSION *sp, PK11_OPTYPE optype)
10236 +       {
10237 +       switch (optype)
10238 +               {
10239 +               case OP_RSA:
10240 +                       if (sp->opdata_rsa_n_num != NULL)
10241 +                               {
10242 +                               BN_free(sp->opdata_rsa_n_num);
10243 +                               sp->opdata_rsa_n_num = NULL;
10244 +                               }
10245 +                       if (sp->opdata_rsa_e_num != NULL)
10246 +                               {
10247 +                               BN_free(sp->opdata_rsa_e_num);
10248 +                               sp->opdata_rsa_e_num = NULL;
10249 +                               }
10250 +                       if (sp->opdata_rsa_pn_num != NULL)
10251 +                               {
10252 +                               BN_free(sp->opdata_rsa_pn_num);
10253 +                               sp->opdata_rsa_pn_num = NULL;
10254 +                               }
10255 +                       if (sp->opdata_rsa_pe_num != NULL)
10256 +                               {
10257 +                               BN_free(sp->opdata_rsa_pe_num);
10258 +                               sp->opdata_rsa_pe_num = NULL;
10259 +                               }
10260 +                       if (sp->opdata_rsa_d_num != NULL)
10261 +                               {
10262 +                               BN_free(sp->opdata_rsa_d_num);
10263 +                               sp->opdata_rsa_d_num = NULL;
10264 +                               }
10265 +                       break;
10266 +               default:
10267 +                       break;
10268 +               }
10269 +       }
10272 + * Get new PK11_SESSION structure ready for use. Every process must have
10273 + * its own freelist of PK11_SESSION structures so handle fork() here
10274 + * by destroying the old and creating new freelist.
10275 + * The returned PK11_SESSION structure is disconnected from the freelist.
10276 + */
10277 +PK11_SESSION *
10278 +pk11_get_session(PK11_OPTYPE optype)
10279 +       {
10280 +       PK11_SESSION *sp = NULL, *sp1, *freelist;
10281 +#ifndef NOPTHREADS
10282 +       pthread_mutex_t *freelist_lock = NULL;
10283 +#endif
10284 +       static pid_t pid = 0;
10285 +       pid_t new_pid;
10286 +       CK_RV rv;
10288 +       switch (optype)
10289 +               {
10290 +               case OP_RSA:
10291 +               case OP_DSA:
10292 +               case OP_DH:
10293 +               case OP_RAND:
10294 +               case OP_DIGEST:
10295 +               case OP_CIPHER:
10296 +#ifndef NOPTHREADS
10297 +                       freelist_lock = session_cache[optype].lock;
10298 +#endif
10299 +                       break;
10300 +               default:
10301 +                       PK11err(PK11_F_GET_SESSION,
10302 +                               PK11_R_INVALID_OPERATION_TYPE);
10303 +                       return (NULL);
10304 +               }
10305 +#ifndef NOPTHREADS
10306 +       OPENSSL_assert(pthread_mutex_lock(freelist_lock) == 0);
10307 +#else
10308 +       CRYPTO_w_lock(CRYPTO_LOCK_PK11_ENGINE);
10309 +#endif
10311 +       /*
10312 +        * Will use it to find out if we forked. We cannot use the PID field in
10313 +        * the session structure because we could get a newly allocated session
10314 +        * here, with no PID information.
10315 +        */
10316 +       if (pid == 0)
10317 +               pid = getpid();
10319 +       freelist = session_cache[optype].head;
10320 +       sp = freelist;
10322 +       /*
10323 +        * If the free list is empty, allocate new unitialized (filled
10324 +        * with zeroes) PK11_SESSION structure otherwise return first
10325 +        * structure from the freelist.
10326 +        */
10327 +       if (sp == NULL)
10328 +               {
10329 +               if ((sp = OPENSSL_malloc(sizeof (PK11_SESSION))) == NULL)
10330 +                       {
10331 +                       PK11err(PK11_F_GET_SESSION,
10332 +                               PK11_R_MALLOC_FAILURE);
10333 +                       goto err;
10334 +                       }
10335 +               (void) memset(sp, 0, sizeof (PK11_SESSION));
10337 +               /*
10338 +                * It is a new session so it will look like a cache miss to the
10339 +                * code below. So, we must not try to to destroy its members so
10340 +                * mark them as unused.
10341 +                */
10342 +               sp->opdata_rsa_priv_key = CK_INVALID_HANDLE;
10343 +               sp->opdata_rsa_pub_key = CK_INVALID_HANDLE;
10344 +               }
10345 +       else
10346 +               {
10347 +               freelist = sp->next;
10348 +               }
10350 +       /*
10351 +        * Check whether we have forked. In that case, we must get rid of all
10352 +        * inherited sessions and start allocating new ones.
10353 +        */
10354 +       if (pid != (new_pid = getpid()))
10355 +               {
10356 +               pid = new_pid;
10358 +               /*
10359 +                * We are a new process and thus need to free any inherited
10360 +                * PK11_SESSION objects aside from the first session (sp) which
10361 +                * is the only PK11_SESSION structure we will reuse (for the
10362 +                * head of the list).
10363 +                */
10364 +               while ((sp1 = freelist) != NULL)
10365 +                       {
10366 +                       freelist = sp1->next;
10367 +                       /*
10368 +                        * NOTE: we do not want to call pk11_free_all_sessions()
10369 +                        * here because it would close underlying PKCS#11
10370 +                        * sessions and destroy all objects.
10371 +                        */
10372 +                       pk11_free_nums(sp1, optype);
10373 +                       OPENSSL_free(sp1);
10374 +                       }
10376 +               /* we have to free the active list as well. */
10377 +               pk11_free_active_list(optype);
10379 +               /* Initialize the process */
10380 +               rv = pFuncList->C_Initialize((CK_VOID_PTR)&pk11_init_args);
10381 +               if ((rv != CKR_OK) && (rv != CKR_CRYPTOKI_ALREADY_INITIALIZED))
10382 +                       {
10383 +                       PK11err_add_data(PK11_F_GET_SESSION, PK11_R_INITIALIZE,
10384 +                           rv);
10385 +                       OPENSSL_free(sp);
10386 +                       sp = NULL;
10387 +                       goto err;
10388 +                       }
10390 +               /*
10391 +                * Choose slot here since the slot table is different on this
10392 +                * process. If we are here then we must have found at least one
10393 +                * usable slot before so we don't need to check any_slot_found.
10394 +                * See pk11_library_init()'s usage of this function for more
10395 +                * information.
10396 +                */
10397 +               if (pk11_choose_slots(NULL) == 0)
10398 +                       goto err;
10400 +               /* Open the global_session for the new process */
10401 +               rv = pFuncList->C_OpenSession(SLOTID, CKF_SERIAL_SESSION,
10402 +                       NULL_PTR, NULL_PTR, &global_session);
10403 +               if (rv != CKR_OK)
10404 +                       {
10405 +                       PK11err_add_data(PK11_F_GET_SESSION, PK11_R_OPENSESSION,
10406 +                           rv);
10407 +                       OPENSSL_free(sp);
10408 +                       sp = NULL;
10409 +                       goto err;
10410 +                       }
10412 +               /*
10413 +                * It is an inherited session from our parent so it needs
10414 +                * re-initialization.
10415 +                */
10416 +               if (pk11_setup_session(sp, optype) == 0)
10417 +                       {
10418 +                       OPENSSL_free(sp);
10419 +                       sp = NULL;
10420 +                       goto err;
10421 +                       }
10422 +               if (pk11_token_relogin(sp->session) == 0) 
10423 +                       {
10424 +                       /*
10425 +                        * We will keep the session in the cache list and let
10426 +                        * the caller cope with the situation.
10427 +                        */
10428 +                       freelist = sp;
10429 +                       sp = NULL;
10430 +                       goto err;
10431 +                       }
10432 +               }
10434 +       if (sp->pid == 0)
10435 +               {
10436 +               /* It is a new session and needs initialization. */
10437 +               if (pk11_setup_session(sp, optype) == 0)
10438 +                       {
10439 +                       OPENSSL_free(sp);
10440 +                       sp = NULL;
10441 +                       }
10442 +               }
10444 +       /* set new head for the list of PK11_SESSION objects */
10445 +       session_cache[optype].head = freelist;
10447 +err:
10448 +       if (sp != NULL)
10449 +               sp->next = NULL;
10451 +#ifndef NOPTHREADS
10452 +       OPENSSL_assert(pthread_mutex_unlock(freelist_lock) == 0);
10453 +#else
10454 +       CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
10455 +#endif
10457 +       return (sp);
10458 +       }
10461 +void
10462 +pk11_return_session(PK11_SESSION *sp, PK11_OPTYPE optype)
10463 +       {
10464 +#ifndef NOPTHREADS
10465 +       pthread_mutex_t *freelist_lock;
10466 +#endif
10467 +       PK11_SESSION *freelist;
10469 +       /*
10470 +        * If this is a session from the parent it will be taken care of and
10471 +        * freed in pk11_get_session() as part of the post-fork clean up the
10472 +        * next time we will ask for a new session.
10473 +        */
10474 +       if (sp == NULL || sp->pid != getpid())
10475 +               return;
10477 +       switch (optype)
10478 +               {
10479 +               case OP_RSA:
10480 +               case OP_DSA:
10481 +               case OP_DH:
10482 +               case OP_RAND:
10483 +               case OP_DIGEST:
10484 +               case OP_CIPHER:
10485 +#ifndef NOPTHREADS
10486 +                       freelist_lock = session_cache[optype].lock;
10487 +#endif
10488 +                       break;
10489 +               default:
10490 +                       PK11err(PK11_F_RETURN_SESSION,
10491 +                               PK11_R_INVALID_OPERATION_TYPE);
10492 +                       return;
10493 +               }
10495 +#ifndef NOPTHREADS
10496 +       OPENSSL_assert(pthread_mutex_lock(freelist_lock) == 0);
10497 +#else
10498 +       CRYPTO_w_lock(CRYPTO_LOCK_PK11_ENGINE);
10499 +#endif
10500 +       freelist = session_cache[optype].head;
10501 +       sp->next = freelist;
10502 +       session_cache[optype].head = sp;
10503 +#ifndef NOPTHREADS
10504 +       OPENSSL_assert(pthread_mutex_unlock(freelist_lock) == 0);
10505 +#else
10506 +       CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
10507 +#endif
10508 +       }
10511 +/* Destroy all objects. This function is called when the engine is finished */
10512 +static int pk11_free_all_sessions()
10513 +       {
10514 +       int ret = 1;
10515 +       int type;
10517 +       (void) pk11_destroy_rsa_key_objects(NULL);
10519 +       /*
10520 +        * We try to release as much as we can but any error means that we will
10521 +        * return 0 on exit.
10522 +        */
10523 +       for (type = 0; type < OP_MAX; type++)
10524 +               {
10525 +               if (pk11_free_session_list(type) == 0)
10526 +                       ret = 0;
10527 +               }
10529 +       return (ret);
10530 +       }
10533 + * Destroy session structures from the linked list specified. Free as many
10534 + * sessions as possible but any failure in C_CloseSession() means that we
10535 + * return an error on return.
10536 + */
10537 +static int pk11_free_session_list(PK11_OPTYPE optype)
10538 +       {
10539 +       CK_RV rv;
10540 +       PK11_SESSION *sp = NULL;
10541 +       PK11_SESSION *freelist = NULL;
10542 +       pid_t mypid = getpid();
10543 +#ifndef NOPTHREADS
10544 +       pthread_mutex_t *freelist_lock;
10545 +#endif
10546 +       int ret = 1;
10548 +       switch (optype)
10549 +               {
10550 +               case OP_RSA:
10551 +               case OP_DSA:
10552 +               case OP_DH:
10553 +               case OP_RAND:
10554 +               case OP_DIGEST:
10555 +               case OP_CIPHER:
10556 +#ifndef NOPTHREADS
10557 +                       freelist_lock = session_cache[optype].lock;
10558 +#endif
10559 +                       break;
10560 +               default:
10561 +                       PK11err(PK11_F_FREE_ALL_SESSIONS,
10562 +                               PK11_R_INVALID_OPERATION_TYPE);
10563 +                       return (0);
10564 +               }
10566 +#ifndef NOPTHREADS
10567 +       OPENSSL_assert(pthread_mutex_lock(freelist_lock) == 0);
10568 +#else
10569 +       CRYPTO_w_lock(CRYPTO_LOCK_PK11_ENGINE);
10570 +#endif
10571 +       freelist = session_cache[optype].head;
10572 +       while ((sp = freelist) != NULL)
10573 +               {
10574 +               if (sp->session != CK_INVALID_HANDLE && sp->pid == mypid)
10575 +                       {
10576 +                       rv = pFuncList->C_CloseSession(sp->session);
10577 +                       if (rv != CKR_OK)
10578 +                               {
10579 +                               PK11err_add_data(PK11_F_FREE_ALL_SESSIONS,
10580 +                                       PK11_R_CLOSESESSION, rv);
10581 +                               ret = 0;
10582 +                               }
10583 +                       }
10584 +               freelist = sp->next;
10585 +               pk11_free_nums(sp, optype);
10586 +               OPENSSL_free(sp);
10587 +               }
10589 +#ifndef NOPTHREADS
10590 +       OPENSSL_assert(pthread_mutex_unlock(freelist_lock) == 0);
10591 +#else
10592 +       CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
10593 +#endif
10594 +       return (ret);
10595 +       }
10598 +static int
10599 +pk11_setup_session(PK11_SESSION *sp, PK11_OPTYPE optype)
10600 +       {
10601 +       CK_RV rv;
10602 +       CK_SLOT_ID myslot;
10604 +       switch (optype)
10605 +               {
10606 +               case OP_RSA:
10607 +                       myslot = pubkey_SLOTID;
10608 +                       break;
10609 +               case OP_RAND:
10610 +                       myslot = rand_SLOTID;
10611 +                       break;
10612 +               default:
10613 +                       PK11err(PK11_F_SETUP_SESSION,
10614 +                           PK11_R_INVALID_OPERATION_TYPE);
10615 +                       return (0);
10616 +               }
10618 +       sp->session = CK_INVALID_HANDLE;
10619 +#ifdef DEBUG_SLOT_SELECTION
10620 +       fprintf(stderr, "%s: myslot=%d optype=%d\n", PK11_DBG, myslot, optype);
10621 +#endif /* DEBUG_SLOT_SELECTION */
10622 +       rv = pFuncList->C_OpenSession(myslot, CKF_SERIAL_SESSION,
10623 +               NULL_PTR, NULL_PTR, &sp->session);
10624 +       if (rv == CKR_CRYPTOKI_NOT_INITIALIZED)
10625 +               {
10626 +               /*
10627 +                * We are probably a child process so force the
10628 +                * reinitialize of the session
10629 +                */
10630 +               pk11_library_initialized = FALSE;
10631 +               if (!pk11_library_init(NULL))
10632 +                       return (0);
10633 +               rv = pFuncList->C_OpenSession(myslot, CKF_SERIAL_SESSION,
10634 +                       NULL_PTR, NULL_PTR, &sp->session);
10635 +               }
10636 +       if (rv != CKR_OK)
10637 +               {
10638 +               PK11err_add_data(PK11_F_SETUP_SESSION, PK11_R_OPENSESSION, rv);
10639 +               return (0);
10640 +               }
10642 +       sp->pid = getpid();
10644 +       if (optype == OP_RSA)
10645 +               {
10646 +               sp->opdata_rsa_pub_key = CK_INVALID_HANDLE;
10647 +               sp->opdata_rsa_priv_key = CK_INVALID_HANDLE;
10648 +               sp->opdata_rsa_pub = NULL;
10649 +               sp->opdata_rsa_n_num = NULL;
10650 +               sp->opdata_rsa_e_num = NULL;
10651 +               sp->opdata_rsa_priv = NULL;
10652 +               sp->opdata_rsa_pn_num = NULL;
10653 +               sp->opdata_rsa_pe_num = NULL;
10654 +               sp->opdata_rsa_d_num = NULL;
10655 +               }
10657 +       /*
10658 +        * We always initialize the session as containing a non-persistent
10659 +        * object. The key load functions set it to persistent if that is so.
10660 +        */
10661 +       sp->pub_persistent = CK_FALSE;
10662 +       sp->priv_persistent = CK_FALSE;
10663 +       return (1);
10664 +       }
10666 +/* Destroy RSA public key from single session. */
10667 +int
10668 +pk11_destroy_rsa_object_pub(PK11_SESSION *sp, CK_BBOOL uselock)
10669 +       {
10670 +       int ret = 0;
10672 +       if (sp->opdata_rsa_pub_key != CK_INVALID_HANDLE)
10673 +               {
10674 +               TRY_OBJ_DESTROY(sp, sp->opdata_rsa_pub_key,
10675 +                   ret, uselock, OP_RSA, CK_FALSE);
10676 +               sp->opdata_rsa_pub_key = CK_INVALID_HANDLE;
10677 +               sp->opdata_rsa_pub = NULL;
10678 +               if (sp->opdata_rsa_n_num != NULL)
10679 +                       {
10680 +                       BN_free(sp->opdata_rsa_n_num);
10681 +                       sp->opdata_rsa_n_num = NULL;
10682 +                       }
10683 +               if (sp->opdata_rsa_e_num != NULL)
10684 +                       {
10685 +                       BN_free(sp->opdata_rsa_e_num);
10686 +                       sp->opdata_rsa_e_num = NULL;
10687 +                       }
10688 +               }
10690 +       return (ret);
10691 +       }
10693 +/* Destroy RSA private key from single session. */
10694 +int
10695 +pk11_destroy_rsa_object_priv(PK11_SESSION *sp, CK_BBOOL uselock)
10696 +       {
10697 +       int ret = 0;
10699 +       if (sp->opdata_rsa_priv_key != CK_INVALID_HANDLE)
10700 +               {
10701 +               TRY_OBJ_DESTROY(sp, sp->opdata_rsa_priv_key,
10702 +                   ret, uselock, OP_RSA, CK_TRUE);
10703 +               sp->opdata_rsa_priv_key = CK_INVALID_HANDLE;
10704 +               sp->opdata_rsa_priv = NULL;
10705 +               if (sp->opdata_rsa_d_num != NULL)
10706 +                       {
10707 +                       BN_free(sp->opdata_rsa_d_num);
10708 +                       sp->opdata_rsa_d_num = NULL;
10709 +                       }
10711 +               /*
10712 +                * For the RSA key by reference code, public components 'n'/'e'
10713 +                * are the key components we use to check for the cache hit. We
10714 +                * must free those as well.
10715 +                */
10716 +               if (sp->opdata_rsa_pn_num != NULL)
10717 +                       {
10718 +                       BN_free(sp->opdata_rsa_pn_num);
10719 +                       sp->opdata_rsa_pn_num = NULL;
10720 +                       }
10721 +               if (sp->opdata_rsa_pe_num != NULL)
10722 +                       {
10723 +                       BN_free(sp->opdata_rsa_pe_num);
10724 +                       sp->opdata_rsa_pe_num = NULL;
10725 +                       }
10726 +               }
10728 +       return (ret);
10729 +       }
10732 + * Destroy RSA key object wrapper. If session is NULL, try to destroy all
10733 + * objects in the free list.
10734 + */
10735 +int
10736 +pk11_destroy_rsa_key_objects(PK11_SESSION *session)
10737 +       {
10738 +       int ret = 1;
10739 +       PK11_SESSION *sp = NULL;
10740 +       PK11_SESSION *local_free_session;
10741 +       CK_BBOOL uselock = TRUE;
10743 +       if (session != NULL)
10744 +               local_free_session = session;
10745 +       else
10746 +               {
10747 +#ifndef NOPTHREADS
10748 +               OPENSSL_assert(pthread_mutex_lock(session_cache[OP_RSA].lock) == 0);
10749 +#else
10750 +               CRYPTO_w_lock(CRYPTO_LOCK_PK11_ENGINE);
10751 +#endif
10752 +               local_free_session = session_cache[OP_RSA].head;
10753 +               uselock = FALSE;
10754 +               }
10756 +       /*
10757 +        * go through the list of sessions and delete key objects
10758 +        */
10759 +       while ((sp = local_free_session) != NULL)
10760 +               {
10761 +               local_free_session = sp->next;
10763 +               /*
10764 +                * Do not terminate list traversal if one of the
10765 +                * destroy operations fails.
10766 +                */
10767 +               if (pk11_destroy_rsa_object_pub(sp, uselock) == 0)
10768 +                       {
10769 +                       ret = 0;
10770 +                       continue;
10771 +                       }
10772 +               if (pk11_destroy_rsa_object_priv(sp, uselock) == 0)
10773 +                       {
10774 +                       ret = 0;
10775 +                       continue;
10776 +                       }
10777 +               }
10779 +#ifndef NOPTHREADS
10780 +       if (session == NULL)
10781 +               OPENSSL_assert(pthread_mutex_unlock(session_cache[OP_RSA].lock) == 0);
10782 +#else
10783 +       if (session == NULL)
10784 +               CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
10785 +#endif
10787 +       return (ret);
10788 +       }
10790 +static int
10791 +pk11_destroy_object(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE oh,
10792 +       CK_BBOOL persistent)
10793 +       {
10794 +       CK_RV rv;
10796 +       /*
10797 +        * We never try to destroy persistent objects which are the objects
10798 +        * stored in the keystore. Also, we always use read-only sessions so
10799 +        * C_DestroyObject() would be returning CKR_SESSION_READ_ONLY here.
10800 +        */
10801 +       if (persistent == CK_TRUE)
10802 +               return (1);
10804 +       rv = pFuncList->C_DestroyObject(session, oh);
10805 +       if (rv != CKR_OK)
10806 +               {
10807 +               PK11err_add_data(PK11_F_DESTROY_OBJECT, PK11_R_DESTROYOBJECT,
10808 +                   rv);
10809 +               return (0);
10810 +               }
10812 +       return (1);
10813 +       }
10817 + * Public key mechanisms optionally supported
10818 + *
10819 + * CKM_RSA_PKCS
10820 + *
10821 + * The first slot that supports at least one of those mechanisms is chosen as a
10822 + * public key slot.
10823 + *
10824 + * The output of this function is a set of global variables indicating which
10825 + * mechanisms from RSA, DSA, DH and RAND are present, and also two arrays of
10826 + * mechanisms, one for symmetric ciphers and one for digests. Also, 3 global
10827 + * variables carry information about which slot was chosen for (a) public key
10828 + * mechanisms, (b) random operations, and (c) symmetric ciphers and digests.
10829 + */
10830 +static int
10831 +pk11_choose_slots(int *any_slot_found)
10832 +       {
10833 +       CK_SLOT_ID_PTR pSlotList = NULL_PTR;
10834 +       CK_ULONG ulSlotCount = 0;
10835 +       CK_MECHANISM_INFO mech_info;
10836 +       CK_TOKEN_INFO token_info;
10837 +       unsigned int i;
10838 +       CK_RV rv;
10839 +       CK_SLOT_ID best_slot_sofar = 0;
10840 +       CK_BBOOL found_candidate_slot = CK_FALSE;
10841 +       CK_SLOT_ID current_slot = 0;
10843 +       /* let's initialize the output parameter */
10844 +       if (any_slot_found != NULL)
10845 +               *any_slot_found = 0;
10847 +       /* Get slot list for memory allocation */
10848 +       rv = pFuncList->C_GetSlotList(CK_FALSE, NULL_PTR, &ulSlotCount);
10850 +       if (rv != CKR_OK)
10851 +               {
10852 +               PK11err_add_data(PK11_F_CHOOSE_SLOT, PK11_R_GETSLOTLIST, rv);
10853 +               return (0);
10854 +               }
10856 +       /* it's not an error if we didn't find any providers */
10857 +       if (ulSlotCount == 0)
10858 +               {
10859 +#ifdef DEBUG_SLOT_SELECTION
10860 +               fprintf(stderr, "%s: no crypto providers found\n", PK11_DBG);
10861 +#endif /* DEBUG_SLOT_SELECTION */
10862 +               return (1);
10863 +               }
10865 +       pSlotList = OPENSSL_malloc(ulSlotCount * sizeof (CK_SLOT_ID));
10867 +       if (pSlotList == NULL)
10868 +               {
10869 +               PK11err(PK11_F_CHOOSE_SLOT, PK11_R_MALLOC_FAILURE);
10870 +               return (0);
10871 +               }
10873 +       /* Get the slot list for processing */
10874 +       rv = pFuncList->C_GetSlotList(CK_FALSE, pSlotList, &ulSlotCount);
10875 +       if (rv != CKR_OK)
10876 +               {
10877 +               PK11err_add_data(PK11_F_CHOOSE_SLOT, PK11_R_GETSLOTLIST, rv);
10878 +               OPENSSL_free(pSlotList);
10879 +               return (0);
10880 +               }
10882 +#ifdef DEBUG_SLOT_SELECTION
10883 +       fprintf(stderr, "%s: provider: %s\n", PK11_DBG, def_PK11_LIBNAME);
10884 +       fprintf(stderr, "%s: number of slots: %d\n", PK11_DBG, ulSlotCount);
10886 +       fprintf(stderr, "%s: == checking rand slots ==\n", PK11_DBG);
10887 +#endif /* DEBUG_SLOT_SELECTION */
10888 +       for (i = 0; i < ulSlotCount; i++)
10889 +               {
10890 +               current_slot = pSlotList[i];
10892 +#ifdef DEBUG_SLOT_SELECTION
10893 +       fprintf(stderr, "%s: checking slot: %d\n", PK11_DBG, i);
10894 +#endif /* DEBUG_SLOT_SELECTION */
10895 +               /* Check if slot has random support. */
10896 +               rv = pFuncList->C_GetTokenInfo(current_slot, &token_info);
10897 +               if (rv != CKR_OK)
10898 +                       continue;
10900 +#ifdef DEBUG_SLOT_SELECTION
10901 +       fprintf(stderr, "%s: token label: %.32s\n", PK11_DBG, token_info.label);
10902 +#endif /* DEBUG_SLOT_SELECTION */
10904 +               if (token_info.flags & CKF_RNG)
10905 +                       {
10906 +#ifdef DEBUG_SLOT_SELECTION
10907 +       fprintf(stderr, "%s: this token has CKF_RNG flag\n", PK11_DBG);
10908 +#endif /* DEBUG_SLOT_SELECTION */
10909 +                       pk11_have_random = CK_TRUE;
10910 +                       rand_SLOTID = current_slot;
10911 +                       break;
10912 +                       }
10913 +               }
10915 +#ifdef DEBUG_SLOT_SELECTION
10916 +       fprintf(stderr, "%s: == checking pubkey slots ==\n", PK11_DBG);
10917 +#endif /* DEBUG_SLOT_SELECTION */
10919 +       pubkey_SLOTID = pSlotList[0];
10920 +       for (i = 0; i < ulSlotCount; i++)
10921 +               {
10922 +               CK_BBOOL slot_has_rsa = CK_FALSE;
10923 +               current_slot = pSlotList[i];
10925 +#ifdef DEBUG_SLOT_SELECTION
10926 +       fprintf(stderr, "%s: checking slot: %d\n", PK11_DBG, i);
10927 +#endif /* DEBUG_SLOT_SELECTION */
10928 +               rv = pFuncList->C_GetTokenInfo(current_slot, &token_info);
10929 +               if (rv != CKR_OK)
10930 +                       continue;
10932 +#ifdef DEBUG_SLOT_SELECTION
10933 +       fprintf(stderr, "%s: token label: %.32s\n", PK11_DBG, token_info.label);
10934 +#endif /* DEBUG_SLOT_SELECTION */
10936 +               /*
10937 +                * Check if this slot is capable of signing with CKM_RSA_PKCS.
10938 +                */
10939 +               rv = pFuncList->C_GetMechanismInfo(current_slot, CKM_RSA_PKCS,
10940 +                       &mech_info);
10942 +               if (rv == CKR_OK && ((mech_info.flags & CKF_SIGN)))
10943 +                       {
10944 +                       slot_has_rsa = CK_TRUE;
10945 +                       }
10947 +               if (!found_candidate_slot && slot_has_rsa)
10948 +                       {
10949 +#ifdef DEBUG_SLOT_SELECTION
10950 +                       fprintf(stderr,
10951 +                           "%s: potential slot: %d\n", PK11_DBG, current_slot);
10952 +#endif /* DEBUG_SLOT_SELECTION */
10953 +                       best_slot_sofar = current_slot;
10954 +                       pk11_have_rsa = slot_has_rsa;
10955 +                       found_candidate_slot = CK_TRUE;
10956 +                       /*
10957 +                        * Cache the flags for later use. We might
10958 +                        * need those if RSA keys by reference feature
10959 +                        * is used.
10960 +                        */
10961 +                       pubkey_token_flags = token_info.flags;
10962 +#ifdef DEBUG_SLOT_SELECTION
10963 +                       fprintf(stderr,
10964 +                           "%s: setting found_candidate_slot to CK_TRUE\n",
10965 +                           PK11_DBG);
10966 +                       fprintf(stderr,
10967 +                           "%s: best so far slot: %d\n", PK11_DBG,
10968 +                           best_slot_sofar);
10969 +                       fprintf(stderr, "%s: pubkey flags changed to "
10970 +                           "%lu.\n", PK11_DBG, pubkey_token_flags);
10971 +                       }
10972 +               else
10973 +                       {
10974 +                       fprintf(stderr,
10975 +                           "%s: no rsa\n", PK11_DBG);
10976 +                       }
10977 +#else
10978 +                       } /* if */
10979 +#endif /* DEBUG_SLOT_SELECTION */
10980 +               } /* for */
10982 +       if (found_candidate_slot == CK_TRUE)
10983 +               {
10984 +               pubkey_SLOTID = best_slot_sofar;
10985 +               }
10987 +       /*SLOTID = pSlotList[0];*/
10989 +#ifdef DEBUG_SLOT_SELECTION
10990 +       fprintf(stderr,
10991 +           "%s: chosen pubkey slot: %d\n", PK11_DBG, pubkey_SLOTID);
10992 +       fprintf(stderr,
10993 +           "%s: chosen rand slot: %d\n", PK11_DBG, rand_SLOTID);
10994 +       fprintf(stderr,
10995 +           "%s: pk11_have_rsa %d\n", PK11_DBG, pk11_have_rsa);
10996 +       fprintf(stderr,
10997 +           "%s: pk11_have_random %d\n", PK11_DBG, pk11_have_random);
10998 +#endif /* DEBUG_SLOT_SELECTION */
11000 +       if (pSlotList != NULL)
11001 +               OPENSSL_free(pSlotList);
11003 +       if (any_slot_found != NULL)
11004 +               *any_slot_found = 1;
11005 +       return (1);
11006 +       }
11008 +#endif /* OPENSSL_NO_HW_PK11SO */
11009 +#endif /* OPENSSL_NO_HW_PK11 */
11010 +#endif /* OPENSSL_NO_HW */
11011 Index: openssl/crypto/engine/hw_pk11so.h
11012 diff -u /dev/null openssl/crypto/engine/hw_pk11so.h:1.2.4.2
11013 --- /dev/null   Fri Jan  2 13:56:41 2015
11014 +++ openssl/crypto/engine/hw_pk11so.h   Wed Jun 15 21:12:32 2011
11015 @@ -0,0 +1,32 @@
11016 +/* Redefine all pk11/PK11 external symbols to pk11so/PK11SO */
11018 +#define token_lock                     pk11so_token_lock
11019 +#define find_lock                      pk11so_find_lock
11020 +#define active_list                    pk11so_active_list
11021 +#define pubkey_token_flags             pk11so_pubkey_token_flags
11022 +#define pubkey_SLOTID                  pk11so_pubkey_SLOTID
11023 +#define ERR_pk11_error                 ERR_pk11so_error
11024 +#define PK11err_add_data               PK11SOerr_add_data
11025 +#define pk11_get_session               pk11so_get_session
11026 +#define pk11_return_session            pk11so_return_session
11027 +#define pk11_active_add                        pk11so_active_add
11028 +#define pk11_active_delete             pk11so_active_delete
11029 +#define pk11_active_remove             pk11so_active_remove
11030 +#define pk11_free_active_list          pk11so_free_active_list
11031 +#define pk11_destroy_rsa_key_objects   pk11so_destroy_rsa_key_objects
11032 +#define pk11_destroy_rsa_object_pub    pk11so_destroy_rsa_object_pub
11033 +#define pk11_destroy_rsa_object_priv   pk11so_destroy_rsa_object_priv
11034 +#define pk11_load_privkey              pk11so_load_privkey
11035 +#define pk11_load_pubkey               pk11so_load_pubkey
11036 +#define PK11_RSA                       PK11SO_RSA
11037 +#define pk11_destroy_dsa_key_objects   pk11so_destroy_dsa_key_objects
11038 +#define pk11_destroy_dsa_object_pub    pk11so_destroy_dsa_object_pub
11039 +#define pk11_destroy_dsa_object_priv   pk11so_destroy_dsa_object_priv
11040 +#define PK11_DSA                       PK11SO_DSA
11041 +#define pk11_destroy_dh_key_objects    pk11so_destroy_dh_key_objects
11042 +#define pk11_destroy_dh_object         pk11so_destroy_dh_object
11043 +#define PK11_DH                                PK11SO_DH
11044 +#define pk11_token_relogin             pk11so_token_relogin
11045 +#define pFuncList                      pk11so_pFuncList
11046 +#define pk11_pin                       pk11so_pin
11047 +#define ENGINE_load_pk11               ENGINE_load_pk11so
11048 Index: openssl/crypto/engine/hw_pk11so_pub.c
11049 diff -u /dev/null openssl/crypto/engine/hw_pk11so_pub.c:1.2.4.6
11050 --- /dev/null   Fri Jan  2 13:56:41 2015
11051 +++ openssl/crypto/engine/hw_pk11so_pub.c       Fri Oct  4 14:45:25 2013
11052 @@ -0,0 +1,1642 @@
11054 + * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
11055 + * Use is subject to license terms.
11056 + */
11058 +/* crypto/engine/hw_pk11_pub.c */
11060 + * This product includes software developed by the OpenSSL Project for
11061 + * use in the OpenSSL Toolkit (http://www.openssl.org/).
11062 + *
11063 + * This project also referenced hw_pkcs11-0.9.7b.patch written by
11064 + * Afchine Madjlessi.
11065 + */
11067 + * ====================================================================
11068 + * Copyright (c) 2000-2001 The OpenSSL Project.  All rights reserved.
11069 + *
11070 + * Redistribution and use in source and binary forms, with or without
11071 + * modification, are permitted provided that the following conditions
11072 + * are met:
11073 + *
11074 + * 1. Redistributions of source code must retain the above copyright
11075 + *    notice, this list of conditions and the following disclaimer.
11076 + *
11077 + * 2. Redistributions in binary form must reproduce the above copyright
11078 + *    notice, this list of conditions and the following disclaimer in
11079 + *    the documentation and/or other materials provided with the
11080 + *    distribution.
11081 + *
11082 + * 3. All advertising materials mentioning features or use of this
11083 + *    software must display the following acknowledgment:
11084 + *    "This product includes software developed by the OpenSSL Project
11085 + *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
11086 + *
11087 + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
11088 + *    endorse or promote products derived from this software without
11089 + *    prior written permission. For written permission, please contact
11090 + *    licensing@OpenSSL.org.
11091 + *
11092 + * 5. Products derived from this software may not be called "OpenSSL"
11093 + *    nor may "OpenSSL" appear in their names without prior written
11094 + *    permission of the OpenSSL Project.
11095 + *
11096 + * 6. Redistributions of any form whatsoever must retain the following
11097 + *    acknowledgment:
11098 + *    "This product includes software developed by the OpenSSL Project
11099 + *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
11100 + *
11101 + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
11102 + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
11103 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
11104 + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
11105 + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
11106 + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
11107 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
11108 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
11109 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
11110 + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
11111 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
11112 + * OF THE POSSIBILITY OF SUCH DAMAGE.
11113 + * ====================================================================
11114 + *
11115 + * This product includes cryptographic software written by Eric Young
11116 + * (eay@cryptsoft.com).  This product includes software written by Tim
11117 + * Hudson (tjh@cryptsoft.com).
11118 + *
11119 + */
11121 +/* Modified to keep only RNG and RSA Sign */
11123 +#ifdef OPENSSL_NO_RSA
11124 +#error RSA is disabled
11125 +#endif
11127 +#include <stdio.h>
11128 +#include <stdlib.h>
11129 +#include <string.h>
11130 +#include <sys/types.h>
11132 +#include <openssl/e_os2.h>
11133 +#include <openssl/crypto.h>
11134 +#include <cryptlib.h>
11135 +#include <openssl/engine.h>
11136 +#include <openssl/dso.h>
11137 +#include <openssl/err.h>
11138 +#include <openssl/bn.h>
11139 +#include <openssl/pem.h>
11140 +#include <openssl/rsa.h>
11141 +#include <openssl/rand.h>
11142 +#include <openssl/objects.h>
11143 +#include <openssl/x509.h>
11145 +#ifdef OPENSSL_SYS_WIN32
11146 +#define NOPTHREADS
11147 +typedef int pid_t;
11148 +#define HAVE_GETPASSPHRASE
11149 +static char *getpassphrase(const char *prompt);
11150 +#ifndef NULL_PTR
11151 +#define NULL_PTR NULL
11152 +#endif
11153 +#define CK_DEFINE_FUNCTION(returnType, name) \
11154 +       returnType __declspec(dllexport) name
11155 +#define CK_DECLARE_FUNCTION(returnType, name) \
11156 +       returnType __declspec(dllimport) name
11157 +#define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
11158 +       returnType __declspec(dllimport) (* name)
11159 +#else
11160 +#include <unistd.h>
11161 +#endif
11163 +#ifndef NOPTHREADS
11164 +#include <pthread.h>
11165 +#endif
11167 +#ifndef OPENSSL_NO_HW
11168 +#ifndef OPENSSL_NO_HW_PK11
11169 +#ifndef OPENSSL_NO_HW_PK11SO
11171 +#ifdef OPENSSL_SYS_WIN32
11172 +#pragma pack(push, cryptoki, 1)
11173 +#include "cryptoki.h"
11174 +#include "pkcs11.h"
11175 +#pragma pack(pop, cryptoki)
11176 +#else
11177 +#include "cryptoki.h"
11178 +#include "pkcs11.h"
11179 +#endif
11180 +#include "hw_pk11so.h"
11181 +#include "hw_pk11_err.h"
11183 +static CK_BBOOL pk11_login_done = CK_FALSE;
11184 +extern CK_SLOT_ID pubkey_SLOTID;
11185 +#ifndef NOPTHREADS
11186 +extern pthread_mutex_t *token_lock;
11187 +#endif
11189 +#if !(defined(HAVE_GETPASSPHRASE) || (defined (__SVR4) && defined (__sun)))
11190 +#define getpassphrase(x)       getpass(x)
11191 +#endif
11193 +/* RSA stuff */
11194 +static int pk11_RSA_sign(int type, const unsigned char *m, unsigned int m_len,
11195 +       unsigned char *sigret, unsigned int *siglen, const RSA *rsa);
11196 +EVP_PKEY *pk11_load_privkey(ENGINE*, const char *privkey_file,
11197 +       UI_METHOD *ui_method, void *callback_data);
11198 +EVP_PKEY *pk11_load_pubkey(ENGINE*, const char *pubkey_file,
11199 +       UI_METHOD *ui_method, void *callback_data);
11201 +static CK_OBJECT_HANDLE pk11_get_public_rsa_key(RSA* rsa, RSA** key_ptr,
11202 +       BIGNUM **rsa_n_num, BIGNUM **rsa_e_num, CK_SESSION_HANDLE session);
11203 +static CK_OBJECT_HANDLE pk11_get_private_rsa_key(RSA* rsa, RSA** key_ptr,
11204 +       BIGNUM **rsa_d_num, BIGNUM **rsa_n_num, BIGNUM **rsa_e_num,
11205 +       CK_SESSION_HANDLE session);
11207 +static int check_new_rsa_key_pub(PK11_SESSION *sp, const RSA *rsa);
11208 +static int check_new_rsa_key_priv(PK11_SESSION *sp, const RSA *rsa);
11210 +static int find_one_object(PK11_OPTYPE op, CK_SESSION_HANDLE s,
11211 +       CK_ATTRIBUTE_PTR ptempl, CK_ULONG nattr, CK_OBJECT_HANDLE_PTR pkey);
11212 +static int init_template_value(BIGNUM *bn, CK_VOID_PTR *pValue,
11213 +       CK_ULONG *ulValueLen);
11214 +static void attr_to_BN(CK_ATTRIBUTE_PTR attr, CK_BYTE attr_data[], BIGNUM **bn);
11216 +static int pk11_token_login(CK_SESSION_HANDLE session, CK_BBOOL *login_done,
11217 +       CK_BBOOL is_private);
11219 +/* Read mode string to be used for fopen() */
11220 +#if SOLARIS_OPENSSL
11221 +static char *read_mode_flags = "rF";
11222 +#else
11223 +static char *read_mode_flags = "r";
11224 +#endif
11227 + * increment/create reference for an asymmetric key handle via active list
11228 + * manipulation. If active list operation fails, unlock (if locked), set error
11229 + * variable and jump to the specified label.
11230 + */
11231 +#define        KEY_HANDLE_REFHOLD(key_handle, alg_type, unlock, var, label)    \
11232 +       {                                                               \
11233 +       if (pk11_active_add(key_handle, alg_type) < 0)                  \
11234 +               {                                                       \
11235 +               var = TRUE;                                             \
11236 +               if (unlock)                                             \
11237 +                       UNLOCK_OBJSTORE(alg_type);                      \
11238 +               goto label;                                             \
11239 +               }                                                       \
11240 +       }
11243 + * Find active list entry according to object handle and return pointer to the
11244 + * entry otherwise return NULL.
11245 + *
11246 + * This function presumes it is called with lock protecting the active list
11247 + * held.
11248 + */
11249 +static PK11_active *pk11_active_find(CK_OBJECT_HANDLE h, PK11_OPTYPE type)
11250 +       {
11251 +       PK11_active *entry;
11253 +       for (entry = active_list[type]; entry != NULL; entry = entry->next)
11254 +               if (entry->h == h)
11255 +                       return (entry);
11257 +       return (NULL);
11258 +       }
11261 + * Search for an entry in the active list using PKCS#11 object handle as a
11262 + * search key and return refcnt of the found/created entry or -1 in case of
11263 + * failure.
11264 + *
11265 + * This function presumes it is called with lock protecting the active list
11266 + * held.
11267 + */
11268 +int
11269 +pk11_active_add(CK_OBJECT_HANDLE h, PK11_OPTYPE type)
11270 +       {
11271 +       PK11_active *entry = NULL;
11273 +       if (h == CK_INVALID_HANDLE)
11274 +               {
11275 +               PK11err(PK11_F_ACTIVE_ADD, PK11_R_INVALID_HANDLE);
11276 +               return (-1);
11277 +               }
11279 +       /* search for entry in the active list */
11280 +       if ((entry = pk11_active_find(h, type)) != NULL)
11281 +               entry->refcnt++;
11282 +       else
11283 +               {
11284 +               /* not found, create new entry and add it to the list */
11285 +               entry = OPENSSL_malloc(sizeof (PK11_active));
11286 +               if (entry == NULL)
11287 +                       {
11288 +                       PK11err(PK11_F_ACTIVE_ADD, PK11_R_MALLOC_FAILURE);
11289 +                       return (-1);
11290 +                       }
11291 +               entry->h = h;
11292 +               entry->refcnt = 1;
11293 +               entry->prev = NULL;
11294 +               entry->next = NULL;
11295 +               /* connect the newly created entry to the list */
11296 +               if (active_list[type] == NULL)
11297 +                       active_list[type] = entry;
11298 +               else /* make the entry first in the list */
11299 +                       {
11300 +                       entry->next = active_list[type];
11301 +                       active_list[type]->prev = entry;
11302 +                       active_list[type] = entry;
11303 +                       }
11304 +               }
11306 +       return (entry->refcnt);
11307 +       }
11310 + * Remove active list entry from the list and free it.
11311 + *
11312 + * This function presumes it is called with lock protecting the active list
11313 + * held.
11314 + */
11315 +void
11316 +pk11_active_remove(PK11_active *entry, PK11_OPTYPE type)
11317 +       {
11318 +       PK11_active *prev_entry;
11320 +       /* remove the entry from the list and free it */
11321 +       if ((prev_entry = entry->prev) != NULL)
11322 +               {
11323 +               prev_entry->next = entry->next;
11324 +               if (entry->next != NULL)
11325 +                       entry->next->prev = prev_entry;
11326 +               }
11327 +       else
11328 +               {
11329 +               active_list[type] = entry->next;
11330 +               /* we were the first but not the only one */
11331 +               if (entry->next != NULL)
11332 +                       entry->next->prev = NULL;
11333 +               }
11335 +       /* sanitization */
11336 +       entry->h = CK_INVALID_HANDLE;
11337 +       entry->prev = NULL;
11338 +       entry->next = NULL;
11339 +       OPENSSL_free(entry);
11340 +       }
11342 +/* Free all entries from the active list. */
11343 +void
11344 +pk11_free_active_list(PK11_OPTYPE type)
11345 +       {
11346 +       PK11_active *entry;
11348 +       /* only for asymmetric types since only they have C_Find* locks. */
11349 +       switch (type)
11350 +               {
11351 +               case OP_RSA:
11352 +                       break;
11353 +               default:
11354 +                       return;
11355 +               }
11357 +       /* see find_lock array definition for more info on object locking */
11358 +       LOCK_OBJSTORE(type);
11359 +       while ((entry = active_list[type]) != NULL)
11360 +               pk11_active_remove(entry, type);
11361 +       UNLOCK_OBJSTORE(type);
11362 +       }
11365 + * Search for active list entry associated with given PKCS#11 object handle,
11366 + * decrement its refcnt and if it drops to 0, disconnect the entry and free it.
11367 + *
11368 + * Return 1 if the PKCS#11 object associated with the entry has no references,
11369 + * return 0 if there is at least one reference, -1 on error.
11370 + *
11371 + * This function presumes it is called with lock protecting the active list
11372 + * held.
11373 + */
11374 +int
11375 +pk11_active_delete(CK_OBJECT_HANDLE h, PK11_OPTYPE type)
11376 +       {
11377 +       PK11_active *entry = NULL;
11379 +       if ((entry = pk11_active_find(h, type)) == NULL)
11380 +               {
11381 +               PK11err(PK11_F_ACTIVE_DELETE, PK11_R_INVALID_HANDLE);
11382 +               return (-1);
11383 +               }
11385 +       OPENSSL_assert(entry->refcnt > 0);
11386 +       entry->refcnt--;
11387 +       if (entry->refcnt == 0)
11388 +               {
11389 +               pk11_active_remove(entry, type);
11390 +               return (1);
11391 +               }
11393 +       return (0);
11394 +       }
11396 +/* Our internal RSA_METHOD that we provide pointers to */
11397 +static RSA_METHOD pk11_rsa;
11399 +RSA_METHOD *
11400 +PK11_RSA(void)
11401 +       {
11402 +       const RSA_METHOD *rsa;
11404 +       if (pk11_rsa.name == NULL)
11405 +               {
11406 +               rsa = RSA_PKCS1_SSLeay();
11407 +               memcpy(&pk11_rsa, rsa, sizeof(*rsa));
11408 +               pk11_rsa.name = "PKCS#11 RSA method";
11409 +               pk11_rsa.rsa_sign = pk11_RSA_sign;
11410 +               }
11411 +       return (&pk11_rsa);
11412 +       }
11414 +/* Size of an SSL signature: MD5+SHA1 */
11415 +#define        SSL_SIG_LENGTH          36
11417 +static CK_BBOOL mytrue = TRUE;
11418 +static CK_BBOOL myfalse = FALSE;
11421 + * Standard engine interface function. Majority codes here are from
11422 + * rsa/rsa_sign.c. We replaced the decrypt function call by C_Sign of PKCS#11.
11423 + * See more details in rsa/rsa_sign.c
11424 + */
11425 +static int pk11_RSA_sign(int type, const unsigned char *m, unsigned int m_len,
11426 +       unsigned char *sigret, unsigned int *siglen, const RSA *rsa)
11427 +       {
11428 +       X509_SIG sig;
11429 +       ASN1_TYPE parameter;
11430 +       int i, j = 0;
11431 +       unsigned char *p, *s = NULL;
11432 +       X509_ALGOR algor;
11433 +       ASN1_OCTET_STRING digest;
11434 +       CK_RV rv;
11435 +       CK_MECHANISM mech_rsa = {CKM_RSA_PKCS, NULL, 0};
11436 +       CK_MECHANISM *p_mech = &mech_rsa;
11437 +       CK_OBJECT_HANDLE h_priv_key;
11438 +       PK11_SESSION *sp = NULL;
11439 +       int ret = 0;
11440 +       unsigned long ulsiglen;
11442 +       /* Encode the digest */
11443 +       /* Special case: SSL signature, just check the length */
11444 +       if (type == NID_md5_sha1)
11445 +               {
11446 +               if (m_len != SSL_SIG_LENGTH)
11447 +                       {
11448 +                       PK11err(PK11_F_RSA_SIGN,
11449 +                               PK11_R_INVALID_MESSAGE_LENGTH);
11450 +                       goto err;
11451 +                       }
11452 +               i = SSL_SIG_LENGTH;
11453 +               s = (unsigned char *)m;
11454 +               }
11455 +       else
11456 +               {
11457 +               sig.algor = &algor;
11458 +               sig.algor->algorithm = OBJ_nid2obj(type);
11459 +               if (sig.algor->algorithm == NULL)
11460 +                       {
11461 +                       PK11err(PK11_F_RSA_SIGN,
11462 +                               PK11_R_UNKNOWN_ALGORITHM_TYPE);
11463 +                       goto err;
11464 +                       }
11465 +               if (sig.algor->algorithm->length == 0)
11466 +                       {
11467 +                       PK11err(PK11_F_RSA_SIGN,
11468 +                               PK11_R_UNKNOWN_ASN1_OBJECT_ID);
11469 +                       goto err;
11470 +                       }
11471 +               parameter.type = V_ASN1_NULL;
11472 +               parameter.value.ptr = NULL;
11473 +               sig.algor->parameter = &parameter;
11475 +               sig.digest = &digest;
11476 +               sig.digest->data = (unsigned char *)m;
11477 +               sig.digest->length = m_len;
11479 +               i = i2d_X509_SIG(&sig, NULL);
11480 +               }
11482 +       j = RSA_size(rsa);
11483 +       if ((i - RSA_PKCS1_PADDING) > j)
11484 +               {
11485 +               PK11err(PK11_F_RSA_SIGN, PK11_R_DIGEST_TOO_BIG);
11486 +               goto err;
11487 +               }
11489 +       if (type != NID_md5_sha1)
11490 +               {
11491 +               s = (unsigned char *)OPENSSL_malloc((unsigned int)(j + 1));
11492 +               if (s == NULL)
11493 +                       {
11494 +                       PK11err(PK11_F_RSA_SIGN, PK11_R_MALLOC_FAILURE);
11495 +                       goto err;
11496 +                       }
11497 +               p = s;
11498 +               (void) i2d_X509_SIG(&sig, &p);
11499 +               }
11501 +       if ((sp = pk11_get_session(OP_RSA)) == NULL)
11502 +               goto err;
11504 +       (void) check_new_rsa_key_priv(sp, rsa);
11506 +       h_priv_key = sp->opdata_rsa_priv_key;
11507 +       if (h_priv_key == CK_INVALID_HANDLE)
11508 +               h_priv_key = sp->opdata_rsa_priv_key =
11509 +                       pk11_get_private_rsa_key((RSA *)rsa,
11510 +                           &sp->opdata_rsa_priv, &sp->opdata_rsa_d_num,
11511 +                           &sp->opdata_rsa_pn_num, &sp->opdata_rsa_pe_num,
11512 +                           sp->session);
11514 +       if (h_priv_key != CK_INVALID_HANDLE)
11515 +               {
11516 +               rv = pFuncList->C_SignInit(sp->session, p_mech, h_priv_key);
11518 +               if (rv != CKR_OK)
11519 +                       {
11520 +                       PK11err_add_data(PK11_F_RSA_SIGN, PK11_R_SIGNINIT, rv);
11521 +                       goto err;
11522 +                       }
11524 +               ulsiglen = j;
11525 +               rv = pFuncList->C_Sign(sp->session, s, i, sigret,
11526 +                       (CK_ULONG_PTR) &ulsiglen);
11527 +               *siglen = ulsiglen;
11529 +               if (rv != CKR_OK)
11530 +                       {
11531 +                       PK11err_add_data(PK11_F_RSA_SIGN, PK11_R_SIGN, rv);
11532 +                       goto err;
11533 +                       }
11534 +               ret = 1;
11535 +               }
11537 +err:
11538 +       if ((type != NID_md5_sha1) && (s != NULL))
11539 +               {
11540 +               (void) memset(s, 0, (unsigned int)(j + 1));
11541 +               OPENSSL_free(s);
11542 +               }
11544 +       pk11_return_session(sp, OP_RSA);
11545 +       return (ret);
11546 +       }
11548 +static int hndidx_rsa = -1;
11550 +#define        MAXATTR 1024
11553 + * Load RSA private key from a file or get its PKCS#11 handle if stored in the
11554 + * PKCS#11 token.
11555 + */
11556 +/* ARGSUSED */
11557 +EVP_PKEY *pk11_load_privkey(ENGINE *e, const char *privkey_file,
11558 +       UI_METHOD *ui_method, void *callback_data)
11559 +       {
11560 +       EVP_PKEY *pkey = NULL;
11561 +       FILE *privkey;
11562 +       CK_OBJECT_HANDLE  h_priv_key = CK_INVALID_HANDLE;
11563 +       RSA *rsa = NULL;
11564 +       PK11_SESSION *sp;
11565 +       /* Anything else below is needed for the key by reference extension. */
11566 +       CK_RV rv;
11567 +       CK_BBOOL is_token = TRUE;
11568 +       CK_BBOOL rollback = FALSE;
11569 +       CK_BYTE attr_data[2][MAXATTR];
11570 +       CK_OBJECT_CLASS key_class = CKO_PRIVATE_KEY;
11571 +       CK_OBJECT_HANDLE ks_key = CK_INVALID_HANDLE;    /* key in keystore */
11573 +       /* we look for private keys only */
11574 +       CK_ATTRIBUTE search_templ[] =
11575 +               {
11576 +               {CKA_TOKEN, &is_token, sizeof(is_token)},
11577 +               {CKA_CLASS, &key_class, sizeof(key_class)},
11578 +               {CKA_LABEL, NULL, 0}
11579 +               };
11581 +       /*
11582 +        * These public attributes are needed to initialize the OpenSSL RSA
11583 +        * structure with something we can use to look up the key. Note that we
11584 +        * never ask for private components.
11585 +        */
11586 +       CK_ATTRIBUTE get_templ[] =
11587 +               {
11588 +               {CKA_MODULUS, (void *)attr_data[0], MAXATTR},           /* n */
11589 +               {CKA_PUBLIC_EXPONENT, (void *)attr_data[1], MAXATTR},   /* e */
11590 +               };
11592 +       if ((sp = pk11_get_session(OP_RSA)) == NULL)
11593 +               return (NULL);
11595 +       /*
11596 +        * Use simple scheme "pkcs11:<KEY_LABEL>" for now.
11597 +        */
11598 +       if (strstr(privkey_file, "pkcs11:") == privkey_file)
11599 +               {
11600 +               search_templ[2].pValue = strstr(privkey_file, ":") + 1;
11601 +               search_templ[2].ulValueLen = strlen(search_templ[2].pValue);
11603 +               if (pk11_token_login(sp->session, &pk11_login_done,
11604 +                   CK_TRUE) == 0)
11605 +                       goto err;
11607 +               /* see find_lock array definition
11608 +                  for more info on object locking */
11609 +               LOCK_OBJSTORE(OP_RSA);
11611 +               /*
11612 +                * Now let's try to find the key in the token. It is a failure
11613 +                * if we can't find it.
11614 +                */
11615 +               if (find_one_object(OP_RSA, sp->session, search_templ, 3,
11616 +                   &ks_key) == 0)
11617 +                       {
11618 +                       UNLOCK_OBJSTORE(OP_RSA);
11619 +                       goto err;
11620 +                       }
11622 +               if (hndidx_rsa == -1)
11623 +                       hndidx_rsa = RSA_get_ex_new_index(0,
11624 +                                       "pkcs11 RSA HSM key handle",
11625 +                                       NULL, NULL, NULL);
11627 +               /*
11628 +                * We might have a cache hit which we could confirm
11629 +                * according to the 'n'/'e' params, RSA public pointer
11630 +                * as NULL, and non-NULL RSA private pointer. However,
11631 +                * it is easier just to recreate everything. We expect
11632 +                * the keys to be loaded once and used many times. We
11633 +                * do not check the return value because even in case
11634 +                * of failure the sp structure will have both key
11635 +                * pointer and object handle cleaned and
11636 +                * pk11_destroy_object() reports the failure to the
11637 +                * OpenSSL error message buffer.
11638 +                */
11639 +               (void) pk11_destroy_rsa_object_priv(sp, FALSE);
11641 +               sp->opdata_rsa_priv_key = ks_key;
11642 +               /* This object shall not be deleted on a cache miss. */
11643 +               sp->priv_persistent = CK_TRUE;
11645 +               /*
11646 +                * Cache the RSA private structure pointer. We do not
11647 +                * use it now for key-by-ref keys but let's do it for
11648 +                * consistency reasons.
11649 +                */
11650 +               if ((rsa = sp->opdata_rsa_priv = RSA_new_method(e)) == NULL)
11651 +                       {
11652 +                       UNLOCK_OBJSTORE(OP_RSA);
11653 +                       goto err;
11654 +                       }
11656 +               /*
11657 +                * Now we have to initialize an OpenSSL RSA structure,
11658 +                * everything else is 0 or NULL.
11659 +                */
11660 +               rsa->flags = RSA_FLAG_SIGN_VER | RSA_FLAG_EXT_PKEY;
11661 +               RSA_set_ex_data(rsa, hndidx_rsa, (void *) ks_key);
11663 +               if ((rv = pFuncList->C_GetAttributeValue(sp->session, ks_key,
11664 +                   get_templ, 2)) != CKR_OK)
11665 +                       {
11666 +                       UNLOCK_OBJSTORE(OP_RSA);
11667 +                       PK11err_add_data(PK11_F_LOAD_PRIVKEY,
11668 +                                        PK11_R_GETATTRIBUTVALUE, rv);
11669 +                       goto err;
11670 +                       }
11672 +               /*
11673 +                * We do not use pk11_get_private_rsa_key() here so we
11674 +                * must take care of handle management ourselves.
11675 +                */
11676 +               KEY_HANDLE_REFHOLD(ks_key, OP_RSA, TRUE, rollback, err);
11678 +               /*
11679 +                * Those are the sensitive components we do not want to export
11680 +                * from the token at all: rsa->(d|p|q|dmp1|dmq1|iqmp).
11681 +                */
11682 +               attr_to_BN(&get_templ[0], attr_data[0], &rsa->n);
11683 +               attr_to_BN(&get_templ[1], attr_data[1], &rsa->e);
11684 +               /*
11685 +                * Must have 'n'/'e' components in the session structure as
11686 +                * well. They serve as a public look-up key for the private key
11687 +                * in the keystore.
11688 +                */
11689 +               attr_to_BN(&get_templ[0], attr_data[0],
11690 +                       &sp->opdata_rsa_pn_num);
11691 +               attr_to_BN(&get_templ[1], attr_data[1],
11692 +                       &sp->opdata_rsa_pe_num);
11694 +               UNLOCK_OBJSTORE(OP_RSA);
11696 +               if ((pkey = EVP_PKEY_new()) == NULL)
11697 +                       goto err;
11699 +               if (EVP_PKEY_assign_RSA(pkey, rsa) == 0)
11700 +                       goto err;
11701 +               }
11702 +       else if ((privkey = fopen(privkey_file, read_mode_flags)) != NULL)
11703 +               {
11704 +               pkey = PEM_read_PrivateKey(privkey, NULL, NULL, NULL);
11705 +               (void) fclose(privkey);
11706 +               if (pkey != NULL)
11707 +                       {
11708 +                       rsa = EVP_PKEY_get1_RSA(pkey);
11709 +                       if (rsa != NULL)
11710 +                               {
11711 +                               /*
11712 +                                * This will always destroy the RSA
11713 +                                * object since we have a new RSA
11714 +                                * structure here.
11715 +                                */
11716 +                               (void) check_new_rsa_key_priv(sp, rsa);
11717 +                               sp->priv_persistent = CK_FALSE;
11719 +                               h_priv_key = sp->opdata_rsa_priv_key =
11720 +                                   pk11_get_private_rsa_key(rsa,
11721 +                                   &sp->opdata_rsa_priv,
11722 +                                   &sp->opdata_rsa_d_num,
11723 +                                   &sp->opdata_rsa_pn_num,
11724 +                                   &sp->opdata_rsa_pe_num, sp->session);
11725 +                               if (h_priv_key == CK_INVALID_HANDLE)
11726 +                                       goto err;
11727 +                               }
11728 +                       else
11729 +                               goto err;
11730 +                       }
11731 +               }
11733 +       pk11_return_session(sp, OP_RSA);
11734 +       return (pkey);
11735 +err:
11736 +       pk11_return_session(sp, OP_RSA);
11737 +       if (rsa != NULL)
11738 +               RSA_free(rsa);
11739 +       if (pkey != NULL)
11740 +               {
11741 +               EVP_PKEY_free(pkey);
11742 +               pkey = NULL;
11743 +               }
11744 +       rollback = rollback;
11745 +       return (pkey);
11746 +       }
11749 + * Load RSA public key from a file or get its PKCS#11 handle if stored in the
11750 + * PKCS#11 token.
11751 + */
11752 +/* ARGSUSED */
11753 +EVP_PKEY *pk11_load_pubkey(ENGINE *e, const char *pubkey_file,
11754 +       UI_METHOD *ui_method, void *callback_data)
11755 +       {
11756 +       EVP_PKEY *pkey = NULL;
11757 +       FILE *pubkey;
11758 +       CK_OBJECT_HANDLE h_pub_key = CK_INVALID_HANDLE;
11759 +       RSA *rsa = NULL;
11760 +       PK11_SESSION *sp;
11761 +       /* Anything else below is needed for the key by reference extension. */
11762 +       CK_RV rv;
11763 +       CK_BBOOL is_token = TRUE;
11764 +       CK_BYTE attr_data[2][MAXATTR];
11765 +       CK_OBJECT_CLASS key_class = CKO_PUBLIC_KEY;
11766 +       CK_OBJECT_HANDLE ks_key = CK_INVALID_HANDLE;    /* key in keystore */
11768 +       /* we look for public keys only */
11769 +       CK_ATTRIBUTE search_templ[] =
11770 +               {
11771 +               {CKA_TOKEN, &is_token, sizeof(is_token)},
11772 +               {CKA_CLASS, &key_class, sizeof(key_class)},
11773 +               {CKA_LABEL, NULL, 0}
11774 +               };
11776 +       /*
11777 +        * These public attributes are needed to initialize OpenSSL RSA
11778 +        * structure with something we can use to look up the key.
11779 +        */
11780 +       CK_ATTRIBUTE get_templ[] =
11781 +               {
11782 +               {CKA_MODULUS, (void *)attr_data[0], MAXATTR},           /* n */
11783 +               {CKA_PUBLIC_EXPONENT, (void *)attr_data[1], MAXATTR},   /* e */
11784 +               };
11786 +       if ((sp = pk11_get_session(OP_RSA)) == NULL)
11787 +               return (NULL);
11789 +       /*
11790 +        * Use simple scheme "pkcs11:<KEY_LABEL>" for now.
11791 +        */
11792 +       if (strstr(pubkey_file, "pkcs11:") == pubkey_file)
11793 +               {
11794 +               search_templ[2].pValue = strstr(pubkey_file, ":") + 1;
11795 +               search_templ[2].ulValueLen = strlen(search_templ[2].pValue);
11797 +               if (pk11_token_login(sp->session, &pk11_login_done,
11798 +                   CK_FALSE) == 0)
11799 +                       goto err;
11801 +               /* see find_lock array definition
11802 +                  for more info on object locking */
11803 +               LOCK_OBJSTORE(OP_RSA);
11805 +               /*
11806 +                * Now let's try to find the key in the token. It is a failure
11807 +                * if we can't find it.
11808 +                */
11809 +               if (find_one_object(OP_RSA, sp->session, search_templ, 3,
11810 +                   &ks_key) == 0)
11811 +                       {
11812 +                       UNLOCK_OBJSTORE(OP_RSA);
11813 +                       goto err;
11814 +                       }
11816 +               /*
11817 +                * We load a new public key so we will create a new RSA
11818 +                * structure. No cache hit is possible.
11819 +                */
11820 +               (void) pk11_destroy_rsa_object_pub(sp, FALSE);
11822 +               sp->opdata_rsa_pub_key = ks_key;
11823 +               /* This object shall not be deleted on a cache miss. */
11824 +               sp->pub_persistent = CK_TRUE;
11826 +               /*
11827 +                * Cache the RSA public structure pointer.
11828 +                */
11829 +               if ((rsa = sp->opdata_rsa_pub = RSA_new_method(e)) == NULL)
11830 +                       {
11831 +                       UNLOCK_OBJSTORE(OP_RSA);
11832 +                       goto err;
11833 +                       }
11835 +               /*
11836 +                * Now we have to initialize an OpenSSL RSA structure,
11837 +                * everything else is 0 or NULL.
11838 +                */
11839 +               rsa->flags = RSA_FLAG_SIGN_VER;
11841 +               if ((rv = pFuncList->C_GetAttributeValue(sp->session, ks_key,
11842 +                   get_templ, 2)) != CKR_OK)
11843 +                       {
11844 +                       UNLOCK_OBJSTORE(OP_RSA);
11845 +                       PK11err_add_data(PK11_F_LOAD_PUBKEY,
11846 +                                        PK11_R_GETATTRIBUTVALUE, rv);
11847 +                       goto err;
11848 +                       }
11850 +               attr_to_BN(&get_templ[0], attr_data[0], &rsa->n);
11851 +               attr_to_BN(&get_templ[1], attr_data[1], &rsa->e);
11853 +               UNLOCK_OBJSTORE(OP_RSA);
11855 +               if ((pkey = EVP_PKEY_new()) == NULL)
11856 +                       goto err;
11858 +               if (EVP_PKEY_assign_RSA(pkey, rsa) == 0)
11859 +                       goto err;
11861 +               /*
11862 +                * Create a session object from it so that when calling
11863 +                * pk11_get_public_rsa_key() the next time, we can find it. The
11864 +                * reason why we do that is that we cannot tell from the RSA
11865 +                * structure (OpenSSL RSA structure does not have any room for
11866 +                * additional data used by the engine, for example) if it bears
11867 +                * a public key stored in the keystore or not so it's better if
11868 +                * we always have a session key. Note that this is different
11869 +                * from what we do for the private keystore objects but in that
11870 +                * case, we can tell from the RSA structure that the keystore
11871 +                * object is in play - the 'd' component is NULL in that case.
11872 +                */
11873 +               h_pub_key = sp->opdata_rsa_pub_key =
11874 +                   pk11_get_public_rsa_key(rsa,
11875 +                   &sp->opdata_rsa_pub, &sp->opdata_rsa_n_num,
11876 +                   &sp->opdata_rsa_e_num, sp->session);
11877 +               if (h_pub_key == CK_INVALID_HANDLE)
11878 +                       goto err;
11879 +               }
11880 +       else if ((pubkey = fopen(pubkey_file, read_mode_flags)) != NULL)
11881 +               {
11882 +               pkey = PEM_read_PUBKEY(pubkey, NULL, NULL, NULL);
11883 +               (void) fclose(pubkey);
11884 +               if (pkey != NULL)
11885 +                       {
11886 +                       rsa = EVP_PKEY_get1_RSA(pkey);
11887 +                       if (rsa != NULL)
11888 +                               {
11889 +                               /*
11890 +                                * This will always destroy the RSA
11891 +                                * object since we have a new RSA
11892 +                                * structure here.
11893 +                                */
11894 +                               (void) check_new_rsa_key_pub(sp, rsa);
11895 +                               sp->pub_persistent = CK_FALSE;
11897 +                               h_pub_key = sp->opdata_rsa_pub_key =
11898 +                                   pk11_get_public_rsa_key(rsa,
11899 +                                   &sp->opdata_rsa_pub, &sp->opdata_rsa_n_num,
11900 +                                   &sp->opdata_rsa_e_num, sp->session);
11901 +                               if (h_pub_key == CK_INVALID_HANDLE)
11902 +                                       goto err;
11903 +                               }
11904 +                       else
11905 +                               goto err;
11906 +                       }
11907 +               }
11909 +       pk11_return_session(sp, OP_RSA);
11910 +       return (pkey);
11911 +err:
11912 +       pk11_return_session(sp, OP_RSA);
11913 +       if (rsa != NULL)
11914 +               RSA_free(rsa);
11915 +       if (pkey != NULL)
11916 +               {
11917 +               EVP_PKEY_free(pkey);
11918 +               pkey = NULL;
11919 +               }
11920 +       return (pkey);
11921 +       }
11924 + * Create a public key object in a session from a given rsa structure.
11925 + * The *rsa_n_num and *rsa_e_num pointers are non-NULL for RSA public keys.
11926 + */
11927 +static CK_OBJECT_HANDLE pk11_get_public_rsa_key(RSA *rsa,
11928 +    RSA **key_ptr, BIGNUM **rsa_n_num, BIGNUM **rsa_e_num,
11929 +    CK_SESSION_HANDLE session)
11930 +       {
11931 +       CK_RV rv;
11932 +       CK_OBJECT_HANDLE h_key = CK_INVALID_HANDLE;
11933 +       CK_ULONG found;
11934 +       CK_OBJECT_CLASS o_key = CKO_PUBLIC_KEY;
11935 +       CK_KEY_TYPE k_type = CKK_RSA;
11936 +       CK_ULONG ul_key_attr_count = 8;
11937 +       CK_BBOOL rollback = FALSE;
11939 +       CK_ATTRIBUTE  a_key_template[] =
11940 +               {
11941 +               {CKA_CLASS, (void *) NULL, sizeof (CK_OBJECT_CLASS)},
11942 +               {CKA_KEY_TYPE, (void *) NULL, sizeof (CK_KEY_TYPE)},
11943 +               {CKA_TOKEN, &myfalse, sizeof (myfalse)},
11944 +               {CKA_ENCRYPT, &mytrue, sizeof (mytrue)},
11945 +               {CKA_VERIFY, &mytrue, sizeof (mytrue)},
11946 +               {CKA_VERIFY_RECOVER, &mytrue, sizeof (mytrue)},
11947 +               {CKA_MODULUS, (void *)NULL, 0},
11948 +               {CKA_PUBLIC_EXPONENT, (void *)NULL, 0}
11949 +               };
11951 +       int i;
11953 +       a_key_template[0].pValue = &o_key;
11954 +       a_key_template[1].pValue = &k_type;
11956 +       a_key_template[6].ulValueLen = BN_num_bytes(rsa->n);
11957 +       a_key_template[6].pValue = (CK_VOID_PTR)OPENSSL_malloc(
11958 +               (size_t)a_key_template[6].ulValueLen);
11959 +       if (a_key_template[6].pValue == NULL)
11960 +               {
11961 +               PK11err(PK11_F_GET_PUB_RSA_KEY, PK11_R_MALLOC_FAILURE);
11962 +               goto malloc_err;
11963 +               }
11965 +       BN_bn2bin(rsa->n, a_key_template[6].pValue);
11967 +       a_key_template[7].ulValueLen = BN_num_bytes(rsa->e);
11968 +       a_key_template[7].pValue = (CK_VOID_PTR)OPENSSL_malloc(
11969 +               (size_t)a_key_template[7].ulValueLen);
11970 +       if (a_key_template[7].pValue == NULL)
11971 +               {
11972 +               PK11err(PK11_F_GET_PUB_RSA_KEY, PK11_R_MALLOC_FAILURE);
11973 +               goto malloc_err;
11974 +               }
11976 +       BN_bn2bin(rsa->e, a_key_template[7].pValue);
11978 +       /* see find_lock array definition for more info on object locking */
11979 +       LOCK_OBJSTORE(OP_RSA);
11981 +       rv = pFuncList->C_FindObjectsInit(session, a_key_template,
11982 +               ul_key_attr_count);
11984 +       if (rv != CKR_OK)
11985 +               {
11986 +               PK11err_add_data(PK11_F_GET_PUB_RSA_KEY,
11987 +                   PK11_R_FINDOBJECTSINIT, rv);
11988 +               goto err;
11989 +               }
11991 +       rv = pFuncList->C_FindObjects(session, &h_key, 1, &found);
11993 +       if (rv != CKR_OK)
11994 +               {
11995 +               (void) pFuncList->C_FindObjectsFinal(session);
11996 +               PK11err_add_data(PK11_F_GET_PUB_RSA_KEY,
11997 +                   PK11_R_FINDOBJECTS, rv);
11998 +               goto err;
11999 +               }
12001 +       rv = pFuncList->C_FindObjectsFinal(session);
12003 +       if (rv != CKR_OK)
12004 +               {
12005 +               PK11err_add_data(PK11_F_GET_PUB_RSA_KEY,
12006 +                   PK11_R_FINDOBJECTSFINAL, rv);
12007 +               goto err;
12008 +               }
12010 +       if (found == 0)
12011 +               {
12012 +               rv = pFuncList->C_CreateObject(session,
12013 +                       a_key_template, ul_key_attr_count, &h_key);
12014 +               if (rv != CKR_OK)
12015 +                       {
12016 +                       PK11err_add_data(PK11_F_GET_PUB_RSA_KEY,
12017 +                           PK11_R_CREATEOBJECT, rv);
12018 +                       goto err;
12019 +                       }
12020 +               }
12022 +       if (rsa_n_num != NULL)
12023 +               if ((*rsa_n_num = BN_dup(rsa->n)) == NULL)
12024 +                       {
12025 +                       PK11err(PK11_F_GET_PUB_RSA_KEY, PK11_R_MALLOC_FAILURE);
12026 +                       rollback = TRUE;
12027 +                       goto err;
12028 +                       }
12029 +       if (rsa_e_num != NULL)
12030 +               if ((*rsa_e_num = BN_dup(rsa->e)) == NULL)
12031 +                       {
12032 +                       PK11err(PK11_F_GET_PUB_RSA_KEY, PK11_R_MALLOC_FAILURE);
12033 +                       BN_free(*rsa_n_num);
12034 +                       *rsa_n_num = NULL;
12035 +                       rollback = TRUE;
12036 +                       goto err;
12037 +                       }
12039 +       /* LINTED: E_CONSTANT_CONDITION */
12040 +       KEY_HANDLE_REFHOLD(h_key, OP_RSA, FALSE, rollback, err);
12041 +       if (key_ptr != NULL)
12042 +               *key_ptr = rsa;
12044 +err:
12045 +       if (rollback)
12046 +               {
12047 +               /*
12048 +                * We do not care about the return value from C_DestroyObject()
12049 +                * since we are doing rollback.
12050 +                */
12051 +               if (found == 0)
12052 +                       (void) pFuncList->C_DestroyObject(session, h_key);
12053 +               h_key = CK_INVALID_HANDLE;
12054 +               }
12056 +       UNLOCK_OBJSTORE(OP_RSA);
12058 +malloc_err:
12059 +       for (i = 6; i <= 7; i++)
12060 +               {
12061 +               if (a_key_template[i].pValue != NULL)
12062 +                       {
12063 +                       OPENSSL_free(a_key_template[i].pValue);
12064 +                       a_key_template[i].pValue = NULL;
12065 +                       }
12066 +               }
12068 +       return (h_key);
12069 +       }
12072 + * Create a private key object in the session from a given rsa structure.
12073 + * The *rsa_d_num pointer is non-NULL for RSA private keys.
12074 + */
12075 +static CK_OBJECT_HANDLE
12076 +pk11_get_private_rsa_key(RSA *rsa, RSA **key_ptr, BIGNUM **rsa_d_num,
12077 +    BIGNUM **rsa_n_num, BIGNUM **rsa_e_num, CK_SESSION_HANDLE session)
12078 +       {
12079 +       CK_RV rv;
12080 +       CK_OBJECT_HANDLE h_key = CK_INVALID_HANDLE;
12081 +       int i;
12082 +       CK_ULONG found;
12083 +       CK_OBJECT_CLASS o_key = CKO_PRIVATE_KEY;
12084 +       CK_KEY_TYPE k_type = CKK_RSA;
12085 +       CK_ULONG ul_key_attr_count = 14;
12086 +       CK_BBOOL rollback = FALSE;
12088 +       /* Both CKA_TOKEN and CKA_SENSITIVE have to be FALSE for session keys */
12089 +       CK_ATTRIBUTE  a_key_template[] =
12090 +               {
12091 +               {CKA_CLASS, (void *) NULL, sizeof (CK_OBJECT_CLASS)},
12092 +               {CKA_KEY_TYPE, (void *) NULL, sizeof (CK_KEY_TYPE)},
12093 +               {CKA_TOKEN, &myfalse, sizeof (myfalse)},
12094 +               {CKA_SENSITIVE, &myfalse, sizeof (myfalse)},
12095 +               {CKA_DECRYPT, &mytrue, sizeof (mytrue)},
12096 +               {CKA_SIGN, &mytrue, sizeof (mytrue)},
12097 +               {CKA_MODULUS, (void *)NULL, 0},
12098 +               {CKA_PUBLIC_EXPONENT, (void *)NULL, 0},
12099 +               {CKA_PRIVATE_EXPONENT, (void *)NULL, 0},
12100 +               {CKA_PRIME_1, (void *)NULL, 0},
12101 +               {CKA_PRIME_2, (void *)NULL, 0},
12102 +               {CKA_EXPONENT_1, (void *)NULL, 0},
12103 +               {CKA_EXPONENT_2, (void *)NULL, 0},
12104 +               {CKA_COEFFICIENT, (void *)NULL, 0},
12105 +               };
12107 +       if ((rsa->flags & RSA_FLAG_EXT_PKEY) != 0) {
12108 +               h_key = (CK_OBJECT_HANDLE)RSA_get_ex_data(rsa, hndidx_rsa);
12109 +               LOCK_OBJSTORE(OP_RSA);
12110 +               goto set;
12111 +       }
12112 +       
12113 +       a_key_template[0].pValue = &o_key;
12114 +       a_key_template[1].pValue = &k_type;
12116 +       /* Put the private key components into the template */
12117 +       if (init_template_value(rsa->n, &a_key_template[6].pValue,
12118 +               &a_key_template[6].ulValueLen) == 0 ||
12119 +           init_template_value(rsa->e, &a_key_template[7].pValue,
12120 +               &a_key_template[7].ulValueLen) == 0 ||
12121 +           init_template_value(rsa->d, &a_key_template[8].pValue,
12122 +               &a_key_template[8].ulValueLen) == 0 ||
12123 +           init_template_value(rsa->p, &a_key_template[9].pValue,
12124 +               &a_key_template[9].ulValueLen) == 0 ||
12125 +           init_template_value(rsa->q, &a_key_template[10].pValue,
12126 +               &a_key_template[10].ulValueLen) == 0 ||
12127 +           init_template_value(rsa->dmp1, &a_key_template[11].pValue,
12128 +               &a_key_template[11].ulValueLen) == 0 ||
12129 +           init_template_value(rsa->dmq1, &a_key_template[12].pValue,
12130 +               &a_key_template[12].ulValueLen) == 0 ||
12131 +           init_template_value(rsa->iqmp, &a_key_template[13].pValue,
12132 +               &a_key_template[13].ulValueLen) == 0)
12133 +               {
12134 +               PK11err(PK11_F_GET_PRIV_RSA_KEY, PK11_R_MALLOC_FAILURE);
12135 +               goto malloc_err;
12136 +               }
12138 +       /* see find_lock array definition for more info on object locking */
12139 +       LOCK_OBJSTORE(OP_RSA);
12141 +       /*
12142 +        * We are getting the private key but the private 'd'
12143 +        * component is NULL.  That means this is key by reference RSA
12144 +        * key. In that case, we can use only public components for
12145 +        * searching for the private key handle.
12146 +        */
12147 +       if (rsa->d == NULL)
12148 +               {
12149 +               ul_key_attr_count = 8;
12150 +               /*
12151 +                * We will perform the search in the token, not in the existing
12152 +                * session keys.
12153 +                */
12154 +               a_key_template[2].pValue = &mytrue;
12155 +               }
12157 +       rv = pFuncList->C_FindObjectsInit(session, a_key_template,
12158 +               ul_key_attr_count);
12160 +       if (rv != CKR_OK)
12161 +               {
12162 +               PK11err_add_data(PK11_F_GET_PRIV_RSA_KEY,
12163 +                   PK11_R_FINDOBJECTSINIT, rv);
12164 +               goto err;
12165 +               }
12167 +       rv = pFuncList->C_FindObjects(session, &h_key, 1, &found);
12169 +       if (rv != CKR_OK)
12170 +               {
12171 +               (void) pFuncList->C_FindObjectsFinal(session);
12172 +               PK11err_add_data(PK11_F_GET_PRIV_RSA_KEY,
12173 +                   PK11_R_FINDOBJECTS, rv);
12174 +               goto err;
12175 +               }
12177 +       rv = pFuncList->C_FindObjectsFinal(session);
12179 +       if (rv != CKR_OK)
12180 +               {
12181 +               PK11err_add_data(PK11_F_GET_PRIV_RSA_KEY,
12182 +                   PK11_R_FINDOBJECTSFINAL, rv);
12183 +               goto err;
12184 +               }
12186 +       if (found == 0)
12187 +               {
12188 +               /*
12189 +                * We have an RSA structure with 'n'/'e' components
12190 +                * only so we tried to find the private key in the
12191 +                * keystore. If it was really a token key we have a
12192 +                * problem. Note that for other key types we just
12193 +                * create a new session key using the private
12194 +                * components from the RSA structure.
12195 +                */
12196 +               if (rsa->d == NULL)
12197 +                       {
12198 +                       PK11err(PK11_F_GET_PRIV_RSA_KEY,
12199 +                           PK11_R_PRIV_KEY_NOT_FOUND);
12200 +                       goto err;
12201 +                       }
12203 +               rv = pFuncList->C_CreateObject(session,
12204 +                       a_key_template, ul_key_attr_count, &h_key);
12205 +               if (rv != CKR_OK)
12206 +                       {
12207 +                       PK11err_add_data(PK11_F_GET_PRIV_RSA_KEY,
12208 +                               PK11_R_CREATEOBJECT, rv);
12209 +                       goto err;
12210 +                       }
12211 +               }
12213 +set:
12214 +       if (rsa_d_num != NULL)
12215 +               {
12216 +               /*
12217 +                * When RSA keys by reference code is used, we never
12218 +                * extract private components from the keystore. In
12219 +                * that case 'd' was set to NULL and we expect the
12220 +                * application to properly cope with that. It is
12221 +                * documented in openssl(5). In general, if keys by
12222 +                * reference are used we expect it to be used
12223 +                * exclusively using the high level API and then there
12224 +                * is no problem. If the application expects the
12225 +                * private components to be read from the keystore
12226 +                * then that is not a supported way of usage.
12227 +                */
12228 +               if (rsa->d != NULL && (*rsa_d_num = BN_dup(rsa->d)) == NULL)
12229 +                       {
12230 +                       PK11err(PK11_F_GET_PRIV_RSA_KEY, PK11_R_MALLOC_FAILURE);
12231 +                       rollback = TRUE;
12232 +                       goto err;
12233 +                       }
12234 +               else
12235 +                       *rsa_d_num = NULL;
12236 +               }
12238 +       /*
12239 +        * For the key by reference code, we need public components as well
12240 +        * since 'd' component is always NULL. For that reason, we always cache
12241 +        * 'n'/'e' components as well.
12242 +        */
12243 +       *rsa_n_num = BN_dup(rsa->n);
12244 +       *rsa_e_num = BN_dup(rsa->e);
12246 +       /* LINTED: E_CONSTANT_CONDITION */
12247 +       KEY_HANDLE_REFHOLD(h_key, OP_RSA, FALSE, rollback, err);
12248 +       if (key_ptr != NULL)
12249 +               *key_ptr = rsa;
12251 +err:
12252 +       if (rollback)
12253 +               {
12254 +               /*
12255 +                * We do not care about the return value from C_DestroyObject()
12256 +                * since we are doing rollback.
12257 +                */
12258 +               if (found == 0 &&
12259 +                   (rsa->flags & RSA_FLAG_EXT_PKEY) == 0)
12260 +                       (void) pFuncList->C_DestroyObject(session, h_key);
12261 +               h_key = CK_INVALID_HANDLE;
12262 +               }
12264 +       UNLOCK_OBJSTORE(OP_RSA);
12266 +malloc_err:
12267 +       /*
12268 +        * 6 to 13 entries in the key template are key components.
12269 +        * They need to be freed upon exit or error.
12270 +        */
12271 +       for (i = 6; i <= 13; i++)
12272 +               {
12273 +               if (a_key_template[i].pValue != NULL)
12274 +                       {
12275 +                       (void) memset(a_key_template[i].pValue, 0,
12276 +                               a_key_template[i].ulValueLen);
12277 +                       OPENSSL_free(a_key_template[i].pValue);
12278 +                       a_key_template[i].pValue = NULL;
12279 +                       }
12280 +               }
12282 +       return (h_key);
12283 +       }
12286 + * Check for cache miss and clean the object pointer and handle
12287 + * in such case. Return 1 for cache hit, 0 for cache miss.
12288 + */
12289 +static int check_new_rsa_key_pub(PK11_SESSION *sp, const RSA *rsa)
12290 +       {
12291 +       /*
12292 +        * Provide protection against RSA structure reuse by making the
12293 +        * check for cache hit stronger. Only public components of RSA
12294 +        * key matter here so it is sufficient to compare them with values
12295 +        * cached in PK11_SESSION structure.
12296 +        *
12297 +        * We must check the handle as well since with key by reference, public
12298 +        * components 'n'/'e' are cached in private keys as well. That means we
12299 +        * could have a cache hit in a private key when looking for a public
12300 +        * key. That would not work, you cannot have one PKCS#11 object for
12301 +        * both data signing and verifying.
12302 +        */
12303 +       if ((sp->opdata_rsa_pub != rsa) ||
12304 +           (BN_cmp(sp->opdata_rsa_n_num, rsa->n) != 0) ||
12305 +           (BN_cmp(sp->opdata_rsa_e_num, rsa->e) != 0) ||
12306 +           (sp->opdata_rsa_priv_key != CK_INVALID_HANDLE))
12307 +               {
12308 +               /*
12309 +                * We do not check the return value because even in case of
12310 +                * failure the sp structure will have both key pointer
12311 +                * and object handle cleaned and pk11_destroy_object()
12312 +                * reports the failure to the OpenSSL error message buffer.
12313 +                */
12314 +               (void) pk11_destroy_rsa_object_pub(sp, TRUE);
12315 +               return (0);
12316 +               }
12317 +       return (1);
12318 +       }
12321 + * Check for cache miss and clean the object pointer and handle
12322 + * in such case. Return 1 for cache hit, 0 for cache miss.
12323 + */
12324 +static int check_new_rsa_key_priv(PK11_SESSION *sp, const RSA *rsa)
12325 +       {
12326 +       /*
12327 +        * Provide protection against RSA structure reuse by making
12328 +        * the check for cache hit stronger. Comparing public exponent
12329 +        * of RSA key with value cached in PK11_SESSION structure
12330 +        * should be sufficient. Note that we want to compare the
12331 +        * public component since with the keys by reference
12332 +        * mechanism, private components are not in the RSA
12333 +        * structure. Also, see check_new_rsa_key_pub() about why we
12334 +        * compare the handle as well.
12335 +        */
12336 +       if ((sp->opdata_rsa_priv != rsa) ||
12337 +           (BN_cmp(sp->opdata_rsa_pn_num, rsa->n) != 0) ||
12338 +           (BN_cmp(sp->opdata_rsa_pe_num, rsa->e) != 0) ||
12339 +           (sp->opdata_rsa_pn_num == NULL) ||
12340 +           (sp->opdata_rsa_pe_num == NULL) ||
12341 +           (sp->opdata_rsa_pub_key != CK_INVALID_HANDLE))
12342 +               {
12343 +               /*
12344 +                * We do not check the return value because even in case of
12345 +                * failure the sp structure will have both key pointer
12346 +                * and object handle cleaned and pk11_destroy_object()
12347 +                * reports the failure to the OpenSSL error message buffer.
12348 +                */
12349 +               (void) pk11_destroy_rsa_object_priv(sp, TRUE);
12350 +               return (0);
12351 +               }
12352 +       return (1);
12353 +       }
12356 + * Local function to simplify key template population
12357 + * Return 0 -- error, 1 -- no error
12358 + */
12359 +static int
12360 +init_template_value(BIGNUM *bn, CK_VOID_PTR *p_value,
12361 +       CK_ULONG *ul_value_len)
12362 +       {
12363 +       CK_ULONG len = 0;
12365 +       /*
12366 +        * This function can be used on non-initialized BIGNUMs. It is
12367 +        * easier to check that here than individually in the callers.
12368 +        */
12369 +       if (bn != NULL)
12370 +               len = BN_num_bytes(bn);
12372 +       if (bn == NULL || len == 0)
12373 +               return (1);
12375 +       *ul_value_len = len;
12376 +       *p_value = (CK_VOID_PTR)OPENSSL_malloc((size_t)*ul_value_len);
12377 +       if (*p_value == NULL)
12378 +               return (0);
12380 +       BN_bn2bin(bn, *p_value);
12382 +       return (1);
12383 +       }
12385 +static void
12386 +attr_to_BN(CK_ATTRIBUTE_PTR attr, CK_BYTE attr_data[], BIGNUM **bn)
12387 +       {
12388 +       if (attr->ulValueLen > 0)
12389 +               *bn = BN_bin2bn(attr_data, attr->ulValueLen, NULL);
12390 +       }
12393 + * Find one object in the token. It is an error if we can not find the
12394 + * object or if we find more objects based on the template we got.
12395 + * Assume object store locked.
12396 + *
12397 + * Returns:
12398 + *     1 OK
12399 + *     0 no object or more than 1 object found
12400 + */
12401 +static int
12402 +find_one_object(PK11_OPTYPE op, CK_SESSION_HANDLE s,
12403 +    CK_ATTRIBUTE_PTR ptempl, CK_ULONG nattr, CK_OBJECT_HANDLE_PTR pkey)
12404 +       {
12405 +       CK_RV rv;
12406 +       CK_ULONG objcnt;
12408 +       if ((rv = pFuncList->C_FindObjectsInit(s, ptempl, nattr)) != CKR_OK)
12409 +               {
12410 +               PK11err_add_data(PK11_F_FIND_ONE_OBJECT,
12411 +                   PK11_R_FINDOBJECTSINIT, rv);
12412 +               return (0);
12413 +               }
12415 +       rv = pFuncList->C_FindObjects(s, pkey, 1, &objcnt);
12416 +       if (rv != CKR_OK)
12417 +               {
12418 +               (void) pFuncList->C_FindObjectsFinal(s);
12419 +               PK11err_add_data(PK11_F_FIND_ONE_OBJECT, PK11_R_FINDOBJECTS,
12420 +                   rv);
12421 +               return (0);
12422 +               }
12424 +       (void) pFuncList->C_FindObjectsFinal(s);
12426 +       if (objcnt > 1)
12427 +               {
12428 +               PK11err(PK11_F_FIND_ONE_OBJECT,
12429 +                   PK11_R_MORE_THAN_ONE_OBJECT_FOUND);
12430 +               return (0);
12431 +               }
12432 +       else if (objcnt == 0)
12433 +               {
12434 +               PK11err(PK11_F_FIND_ONE_OBJECT, PK11_R_NO_OBJECT_FOUND);
12435 +               return (0);
12436 +               }
12437 +       return (1);
12438 +       }
12440 +/* from uri stuff */
12442 +extern char *pk11_pin;
12444 +static int pk11_get_pin(void);
12446 +static int
12447 +pk11_get_pin(void)
12449 +       char *pin;
12451 +       /* The getpassphrase() function is not MT safe. */
12452 +#ifndef NOPTHREADS
12453 +       OPENSSL_assert(pthread_mutex_lock(token_lock) == 0);
12454 +#else
12455 +       CRYPTO_w_lock(CRYPTO_LOCK_PK11_ENGINE);
12456 +#endif
12457 +       pin = getpassphrase("Enter PIN: ");
12458 +       if (pin == NULL)
12459 +               {
12460 +               PK11err(PK11_F_GET_PIN, PK11_R_COULD_NOT_READ_PIN);
12461 +#ifndef NOPTHREADS
12462 +               OPENSSL_assert(pthread_mutex_unlock(token_lock) == 0);
12463 +#else
12464 +               CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
12465 +#endif
12466 +               return (0);
12467 +               }
12468 +       pk11_pin = BUF_strdup(pin);
12469 +       if (pk11_pin == NULL)
12470 +               {
12471 +               PK11err(PK11_F_LOAD_PRIVKEY, PK11_R_MALLOC_FAILURE);
12472 +#ifndef NOPTHREADS
12473 +               OPENSSL_assert(pthread_mutex_unlock(token_lock) == 0);
12474 +#else
12475 +               CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
12476 +#endif
12477 +               return (0);
12478 +               }
12479 +       memset(pin, 0, strlen(pin));
12480 +#ifndef NOPTHREADS
12481 +       OPENSSL_assert(pthread_mutex_unlock(token_lock) == 0);
12482 +#else
12483 +       CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
12484 +#endif
12485 +       return (1);
12486 +       }
12489 + * Log in to the keystore if we are supposed to do that at all. Take care of
12490 + * reading and caching the PIN etc. Log in only once even when called from
12491 + * multiple threads.
12492 + *
12493 + * Returns:
12494 + *     1 on success
12495 + *     0 on failure
12496 + */
12497 +static int
12498 +pk11_token_login(CK_SESSION_HANDLE session, CK_BBOOL *login_done,
12499 +    CK_BBOOL is_private)
12500 +       {
12501 +       CK_RV rv;
12503 +#if 0
12504 +       /* doesn't work on the AEP Keyper??? */
12505 +       if ((pubkey_token_flags & CKF_TOKEN_INITIALIZED) == 0)
12506 +               {
12507 +               PK11err(PK11_F_TOKEN_LOGIN,
12508 +                   PK11_R_TOKEN_NOT_INITIALIZED);
12509 +               return (0);
12510 +               }
12511 +#endif
12513 +       /*
12514 +        * If login is required or needed but the PIN has not been
12515 +        * even initialized we can bail out right now. Note that we
12516 +        * are supposed to always log in if we are going to access
12517 +        * private keys. However, we may need to log in even for
12518 +        * accessing public keys in case that the CKF_LOGIN_REQUIRED
12519 +        * flag is set.
12520 +        */
12521 +       if (((pubkey_token_flags & CKF_LOGIN_REQUIRED) ||
12522 +            (is_private == CK_TRUE)) &&
12523 +           (~pubkey_token_flags & CKF_USER_PIN_INITIALIZED))
12524 +               {
12525 +               PK11err(PK11_F_TOKEN_LOGIN, PK11_R_TOKEN_PIN_NOT_SET);
12526 +               return (0);
12527 +               }
12529 +       /*
12530 +        * Note on locking: it is possible that more than one thread
12531 +        * gets into pk11_get_pin() so we must deal with that. We
12532 +        * cannot avoid it since we cannot guard fork() in there with
12533 +        * a lock because we could end up in a dead lock in the
12534 +        * child. Why? Remember we are in a multithreaded environment
12535 +        * so we must lock all mutexes in the prefork function to
12536 +        * avoid a situation in which a thread that did not call
12537 +        * fork() held a lock, making future unlocking impossible. We
12538 +        * lock right before C_Login().
12539 +        */
12540 +       if ((pubkey_token_flags & CKF_LOGIN_REQUIRED) ||
12541 +           (is_private == CK_TRUE))
12542 +               {
12543 +               if (*login_done == CK_FALSE)
12544 +                       {
12545 +                       if ((pk11_pin == NULL) && (pk11_get_pin() == 0))
12546 +                               {
12547 +                               PK11err(PK11_F_TOKEN_LOGIN,
12548 +                                   PK11_R_TOKEN_PIN_NOT_PROVIDED);
12549 +                               return (0);
12550 +                               }
12551 +                       }
12553 +               /*
12554 +                * Note that what we are logging into is the keystore from
12555 +                * pubkey_SLOTID because we work with OP_RSA session type here.
12556 +                * That also means that we can work with only one keystore in
12557 +                * the engine.
12558 +                *
12559 +                * We must make sure we do not try to login more than once.
12560 +                * Also, see the comment above on locking strategy.
12561 +                */
12563 +#ifndef NOPTHREADS
12564 +               OPENSSL_assert(pthread_mutex_lock(token_lock) == 0);
12565 +#else
12566 +               CRYPTO_w_lock(CRYPTO_LOCK_PK11_ENGINE);
12567 +#endif
12568 +               if (*login_done == CK_FALSE)
12569 +                       {
12570 +                       if ((rv = pFuncList->C_Login(session,
12571 +                           CKU_USER, (CK_UTF8CHAR*)pk11_pin,
12572 +                           strlen(pk11_pin))) != CKR_OK)
12573 +                               {
12574 +                               PK11err_add_data(PK11_F_TOKEN_LOGIN,
12575 +                                   PK11_R_TOKEN_LOGIN_FAILED, rv);
12576 +                               goto err_locked;
12577 +                               }
12579 +                       *login_done = CK_TRUE;
12581 +                       }
12582 +#ifndef NOPTHREADS
12583 +               OPENSSL_assert(pthread_mutex_unlock(token_lock) == 0);
12584 +#else
12585 +               CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
12586 +#endif
12587 +               }
12588 +       else
12589 +               {
12590 +                       /*
12591 +                        * If token does not require login we take it as the
12592 +                        * login was done.
12593 +                        */
12594 +                       *login_done = CK_TRUE;
12595 +               }
12597 +       return (1);
12599 +err_locked:
12600 +       if (pk11_pin) {
12601 +               memset(pk11_pin, 0, strlen(pk11_pin));
12602 +               OPENSSL_free((void*)pk11_pin);
12603 +       }
12604 +       pk11_pin = NULL;
12605 +#ifndef NOPTHREADS
12606 +       OPENSSL_assert(pthread_mutex_unlock(token_lock) == 0);
12607 +#else
12608 +       CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
12609 +#endif
12610 +       return (0);
12611 +       }
12614 + * Log in to the keystore in the child if we were logged in in the
12615 + * parent. There are similarities in the code with pk11_token_login()
12616 + * but still it is quite different so we need a separate function for
12617 + * this.
12618 + *
12619 + * Note that this function is called under the locked session mutex when fork is
12620 + * detected. That means that C_Login() will be called from the child just once.
12621 + *
12622 + * Returns:
12623 + *     1 on success
12624 + *     0 on failure
12625 + */
12626 +int
12627 +pk11_token_relogin(CK_SESSION_HANDLE session)
12628 +       {
12629 +       CK_RV rv;
12631 +       if ((pk11_pin == NULL) && (pk11_get_pin() == 0))
12632 +               return (0);
12634 +#ifndef NOPTHREADS
12635 +       OPENSSL_assert(pthread_mutex_lock(token_lock) == 0);
12636 +#else
12637 +       CRYPTO_w_lock(CRYPTO_LOCK_PK11_ENGINE);
12638 +#endif
12639 +       if ((rv = pFuncList->C_Login(session, CKU_USER,
12640 +           (CK_UTF8CHAR_PTR)pk11_pin, strlen(pk11_pin))) != CKR_OK)
12641 +               {
12642 +               PK11err_add_data(PK11_F_TOKEN_RELOGIN,
12643 +                   PK11_R_TOKEN_LOGIN_FAILED, rv);
12644 +#ifndef NOPTHREADS
12645 +               OPENSSL_assert(pthread_mutex_unlock(token_lock) == 0);
12646 +#else
12647 +               CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
12648 +#endif
12649 +               return (0);
12650 +               }
12651 +#ifndef NOPTHREADS
12652 +       OPENSSL_assert(pthread_mutex_unlock(token_lock) == 0);
12653 +#else
12654 +       CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
12655 +#endif
12657 +       return (1);
12658 +       }
12660 +#ifdef OPENSSL_SYS_WIN32
12661 +char *getpassphrase(const char *prompt)
12662 +       {
12663 +       static char buf[128];
12664 +       HANDLE h;
12665 +       DWORD cc, mode;
12666 +       int cnt;
12668 +       h = GetStdHandle(STD_INPUT_HANDLE);
12669 +       fputs(prompt, stderr);
12670 +       fflush(stderr);
12671 +       fflush(stdout);
12672 +       FlushConsoleInputBuffer(h);
12673 +       GetConsoleMode(h, &mode);
12674 +       SetConsoleMode(h, ENABLE_PROCESSED_INPUT);
12676 +       for (cnt = 0; cnt < sizeof(buf) - 1; cnt++)
12677 +               {
12678 +               ReadFile(h, buf + cnt, 1, &cc, NULL);
12679 +               if (buf[cnt] == '\r')
12680 +                       break;
12681 +               fputc('*', stdout);
12682 +               fflush(stderr);
12683 +               fflush(stdout);
12684 +               }
12686 +       SetConsoleMode(h, mode);
12687 +       buf[cnt] = '\0';
12688 +       fputs("\n", stderr);
12689 +       return buf;
12690 +       }
12691 +#endif /* OPENSSL_SYS_WIN32 */
12692 +#endif /* OPENSSL_NO_HW_PK11SO */
12693 +#endif /* OPENSSL_NO_HW_PK11 */
12694 +#endif /* OPENSSL_NO_HW */
12695 Index: openssl/crypto/engine/pkcs11.h
12696 diff -u /dev/null openssl/crypto/engine/pkcs11.h:1.1.1.1
12697 --- /dev/null   Fri Jan  2 13:56:41 2015
12698 +++ openssl/crypto/engine/pkcs11.h      Wed Oct 24 23:27:09 2007
12699 @@ -0,0 +1,299 @@
12700 +/* pkcs11.h include file for PKCS #11. */
12701 +/* Revision: 1.1.1.1  */
12703 +/* License to copy and use this software is granted provided that it is
12704 + * identified as "RSA Security Inc. PKCS #11 Cryptographic Token Interface
12705 + * (Cryptoki)" in all material mentioning or referencing this software.
12707 + * License is also granted to make and use derivative works provided that
12708 + * such works are identified as "derived from the RSA Security Inc. PKCS #11
12709 + * Cryptographic Token Interface (Cryptoki)" in all material mentioning or 
12710 + * referencing the derived work.
12712 + * RSA Security Inc. makes no representations concerning either the 
12713 + * merchantability of this software or the suitability of this software for
12714 + * any particular purpose. It is provided "as is" without express or implied
12715 + * warranty of any kind.
12716 + */
12718 +#ifndef _PKCS11_H_
12719 +#define _PKCS11_H_ 1
12721 +#ifdef __cplusplus
12722 +extern "C" {
12723 +#endif
12725 +/* Before including this file (pkcs11.h) (or pkcs11t.h by
12726 + * itself), 6 platform-specific macros must be defined.  These
12727 + * macros are described below, and typical definitions for them
12728 + * are also given.  Be advised that these definitions can depend
12729 + * on both the platform and the compiler used (and possibly also
12730 + * on whether a Cryptoki library is linked statically or
12731 + * dynamically).
12732 + *
12733 + * In addition to defining these 6 macros, the packing convention
12734 + * for Cryptoki structures should be set.  The Cryptoki
12735 + * convention on packing is that structures should be 1-byte
12736 + * aligned.
12737 + *
12738 + * If you're using Microsoft Developer Studio 5.0 to produce
12739 + * Win32 stuff, this might be done by using the following
12740 + * preprocessor directive before including pkcs11.h or pkcs11t.h:
12741 + *
12742 + * #pragma pack(push, cryptoki, 1)
12743 + *
12744 + * and using the following preprocessor directive after including
12745 + * pkcs11.h or pkcs11t.h:
12746 + *
12747 + * #pragma pack(pop, cryptoki)
12748 + *
12749 + * If you're using an earlier version of Microsoft Developer
12750 + * Studio to produce Win16 stuff, this might be done by using
12751 + * the following preprocessor directive before including
12752 + * pkcs11.h or pkcs11t.h:
12753 + *
12754 + * #pragma pack(1)
12755 + *
12756 + * In a UNIX environment, you're on your own for this.  You might
12757 + * not need to do (or be able to do!) anything.
12758 + *
12759 + *
12760 + * Now for the macros:
12761 + *
12762 + *
12763 + * 1. CK_PTR: The indirection string for making a pointer to an
12764 + * object.  It can be used like this:
12765 + *
12766 + * typedef CK_BYTE CK_PTR CK_BYTE_PTR;
12767 + *
12768 + * If you're using Microsoft Developer Studio 5.0 to produce
12769 + * Win32 stuff, it might be defined by:
12770 + *
12771 + * #define CK_PTR *
12772 + *
12773 + * If you're using an earlier version of Microsoft Developer
12774 + * Studio to produce Win16 stuff, it might be defined by:
12775 + *
12776 + * #define CK_PTR far *
12777 + *
12778 + * In a typical UNIX environment, it might be defined by:
12779 + *
12780 + * #define CK_PTR *
12781 + *
12782 + *
12783 + * 2. CK_DEFINE_FUNCTION(returnType, name): A macro which makes
12784 + * an exportable Cryptoki library function definition out of a
12785 + * return type and a function name.  It should be used in the
12786 + * following fashion to define the exposed Cryptoki functions in
12787 + * a Cryptoki library:
12788 + *
12789 + * CK_DEFINE_FUNCTION(CK_RV, C_Initialize)(
12790 + *   CK_VOID_PTR pReserved
12791 + * )
12792 + * {
12793 + *   ...
12794 + * }
12795 + *
12796 + * If you're using Microsoft Developer Studio 5.0 to define a
12797 + * function in a Win32 Cryptoki .dll, it might be defined by:
12798 + *
12799 + * #define CK_DEFINE_FUNCTION(returnType, name) \
12800 + *   returnType __declspec(dllexport) name
12801 + *
12802 + * If you're using an earlier version of Microsoft Developer
12803 + * Studio to define a function in a Win16 Cryptoki .dll, it
12804 + * might be defined by:
12805 + *
12806 + * #define CK_DEFINE_FUNCTION(returnType, name) \
12807 + *   returnType __export _far _pascal name
12808 + *
12809 + * In a UNIX environment, it might be defined by:
12810 + *
12811 + * #define CK_DEFINE_FUNCTION(returnType, name) \
12812 + *   returnType name
12813 + *
12814 + *
12815 + * 3. CK_DECLARE_FUNCTION(returnType, name): A macro which makes
12816 + * an importable Cryptoki library function declaration out of a
12817 + * return type and a function name.  It should be used in the
12818 + * following fashion:
12819 + *
12820 + * extern CK_DECLARE_FUNCTION(CK_RV, C_Initialize)(
12821 + *   CK_VOID_PTR pReserved
12822 + * );
12823 + *
12824 + * If you're using Microsoft Developer Studio 5.0 to declare a
12825 + * function in a Win32 Cryptoki .dll, it might be defined by:
12826 + *
12827 + * #define CK_DECLARE_FUNCTION(returnType, name) \
12828 + *   returnType __declspec(dllimport) name
12829 + *
12830 + * If you're using an earlier version of Microsoft Developer
12831 + * Studio to declare a function in a Win16 Cryptoki .dll, it
12832 + * might be defined by:
12833 + *
12834 + * #define CK_DECLARE_FUNCTION(returnType, name) \
12835 + *   returnType __export _far _pascal name
12836 + *
12837 + * In a UNIX environment, it might be defined by:
12838 + *
12839 + * #define CK_DECLARE_FUNCTION(returnType, name) \
12840 + *   returnType name
12841 + *
12842 + *
12843 + * 4. CK_DECLARE_FUNCTION_POINTER(returnType, name): A macro
12844 + * which makes a Cryptoki API function pointer declaration or
12845 + * function pointer type declaration out of a return type and a
12846 + * function name.  It should be used in the following fashion:
12847 + *
12848 + * // Define funcPtr to be a pointer to a Cryptoki API function
12849 + * // taking arguments args and returning CK_RV.
12850 + * CK_DECLARE_FUNCTION_POINTER(CK_RV, funcPtr)(args);
12851 + *
12852 + * or
12853 + *
12854 + * // Define funcPtrType to be the type of a pointer to a
12855 + * // Cryptoki API function taking arguments args and returning
12856 + * // CK_RV, and then define funcPtr to be a variable of type
12857 + * // funcPtrType.
12858 + * typedef CK_DECLARE_FUNCTION_POINTER(CK_RV, funcPtrType)(args);
12859 + * funcPtrType funcPtr;
12860 + *
12861 + * If you're using Microsoft Developer Studio 5.0 to access
12862 + * functions in a Win32 Cryptoki .dll, in might be defined by:
12863 + *
12864 + * #define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
12865 + *   returnType __declspec(dllimport) (* name)
12866 + *
12867 + * If you're using an earlier version of Microsoft Developer
12868 + * Studio to access functions in a Win16 Cryptoki .dll, it might
12869 + * be defined by:
12870 + *
12871 + * #define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
12872 + *   returnType __export _far _pascal (* name)
12873 + *
12874 + * In a UNIX environment, it might be defined by:
12875 + *
12876 + * #define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
12877 + *   returnType (* name)
12878 + *
12879 + *
12880 + * 5. CK_CALLBACK_FUNCTION(returnType, name): A macro which makes
12881 + * a function pointer type for an application callback out of
12882 + * a return type for the callback and a name for the callback.
12883 + * It should be used in the following fashion:
12884 + *
12885 + * CK_CALLBACK_FUNCTION(CK_RV, myCallback)(args);
12886 + *
12887 + * to declare a function pointer, myCallback, to a callback
12888 + * which takes arguments args and returns a CK_RV.  It can also
12889 + * be used like this:
12890 + *
12891 + * typedef CK_CALLBACK_FUNCTION(CK_RV, myCallbackType)(args);
12892 + * myCallbackType myCallback;
12893 + *
12894 + * If you're using Microsoft Developer Studio 5.0 to do Win32
12895 + * Cryptoki development, it might be defined by:
12896 + *
12897 + * #define CK_CALLBACK_FUNCTION(returnType, name) \
12898 + *   returnType (* name)
12899 + *
12900 + * If you're using an earlier version of Microsoft Developer
12901 + * Studio to do Win16 development, it might be defined by:
12902 + *
12903 + * #define CK_CALLBACK_FUNCTION(returnType, name) \
12904 + *   returnType _far _pascal (* name)
12905 + *
12906 + * In a UNIX environment, it might be defined by:
12907 + *
12908 + * #define CK_CALLBACK_FUNCTION(returnType, name) \
12909 + *   returnType (* name)
12910 + *
12911 + *
12912 + * 6. NULL_PTR: This macro is the value of a NULL pointer.
12913 + *
12914 + * In any ANSI/ISO C environment (and in many others as well),
12915 + * this should best be defined by
12916 + *
12917 + * #ifndef NULL_PTR
12918 + * #define NULL_PTR 0
12919 + * #endif
12920 + */
12923 +/* All the various Cryptoki types and #define'd values are in the
12924 + * file pkcs11t.h. */
12925 +#include "pkcs11t.h"
12927 +#define __PASTE(x,y)      x##y
12930 +/* ==============================================================
12931 + * Define the "extern" form of all the entry points.
12932 + * ==============================================================
12933 + */
12935 +#define CK_NEED_ARG_LIST  1
12936 +#define CK_PKCS11_FUNCTION_INFO(name) \
12937 +  extern CK_DECLARE_FUNCTION(CK_RV, name)
12939 +/* pkcs11f.h has all the information about the Cryptoki
12940 + * function prototypes. */
12941 +#include "pkcs11f.h"
12943 +#undef CK_NEED_ARG_LIST
12944 +#undef CK_PKCS11_FUNCTION_INFO
12947 +/* ==============================================================
12948 + * Define the typedef form of all the entry points.  That is, for
12949 + * each Cryptoki function C_XXX, define a type CK_C_XXX which is
12950 + * a pointer to that kind of function.
12951 + * ==============================================================
12952 + */
12954 +#define CK_NEED_ARG_LIST  1
12955 +#define CK_PKCS11_FUNCTION_INFO(name) \
12956 +  typedef CK_DECLARE_FUNCTION_POINTER(CK_RV, __PASTE(CK_,name))
12958 +/* pkcs11f.h has all the information about the Cryptoki
12959 + * function prototypes. */
12960 +#include "pkcs11f.h"
12962 +#undef CK_NEED_ARG_LIST
12963 +#undef CK_PKCS11_FUNCTION_INFO
12966 +/* ==============================================================
12967 + * Define structed vector of entry points.  A CK_FUNCTION_LIST
12968 + * contains a CK_VERSION indicating a library's Cryptoki version
12969 + * and then a whole slew of function pointers to the routines in
12970 + * the library.  This type was declared, but not defined, in
12971 + * pkcs11t.h.
12972 + * ==============================================================
12973 + */
12975 +#define CK_PKCS11_FUNCTION_INFO(name) \
12976 +  __PASTE(CK_,name) name;
12977 +  
12978 +struct CK_FUNCTION_LIST {
12980 +  CK_VERSION    version;  /* Cryptoki version */
12982 +/* Pile all the function pointers into the CK_FUNCTION_LIST. */
12983 +/* pkcs11f.h has all the information about the Cryptoki
12984 + * function prototypes. */
12985 +#include "pkcs11f.h"
12989 +#undef CK_PKCS11_FUNCTION_INFO
12992 +#undef __PASTE
12994 +#ifdef __cplusplus
12996 +#endif
12998 +#endif
12999 Index: openssl/crypto/engine/pkcs11f.h
13000 diff -u /dev/null openssl/crypto/engine/pkcs11f.h:1.1.1.1
13001 --- /dev/null   Fri Jan  2 13:56:41 2015
13002 +++ openssl/crypto/engine/pkcs11f.h     Wed Oct 24 23:27:09 2007
13003 @@ -0,0 +1,912 @@
13004 +/* pkcs11f.h include file for PKCS #11. */
13005 +/* Revision: 1.1.1.1  */
13007 +/* License to copy and use this software is granted provided that it is
13008 + * identified as "RSA Security Inc. PKCS #11 Cryptographic Token Interface
13009 + * (Cryptoki)" in all material mentioning or referencing this software.
13011 + * License is also granted to make and use derivative works provided that
13012 + * such works are identified as "derived from the RSA Security Inc. PKCS #11
13013 + * Cryptographic Token Interface (Cryptoki)" in all material mentioning or 
13014 + * referencing the derived work.
13016 + * RSA Security Inc. makes no representations concerning either the 
13017 + * merchantability of this software or the suitability of this software for
13018 + * any particular purpose. It is provided "as is" without express or implied
13019 + * warranty of any kind.
13020 + */
13022 +/* This header file contains pretty much everything about all the */
13023 +/* Cryptoki function prototypes.  Because this information is */
13024 +/* used for more than just declaring function prototypes, the */
13025 +/* order of the functions appearing herein is important, and */
13026 +/* should not be altered. */
13028 +/* General-purpose */
13030 +/* C_Initialize initializes the Cryptoki library. */
13031 +CK_PKCS11_FUNCTION_INFO(C_Initialize)
13032 +#ifdef CK_NEED_ARG_LIST
13034 +  CK_VOID_PTR   pInitArgs  /* if this is not NULL_PTR, it gets
13035 +                            * cast to CK_C_INITIALIZE_ARGS_PTR
13036 +                            * and dereferenced */
13038 +#endif
13041 +/* C_Finalize indicates that an application is done with the
13042 + * Cryptoki library. */
13043 +CK_PKCS11_FUNCTION_INFO(C_Finalize)
13044 +#ifdef CK_NEED_ARG_LIST
13046 +  CK_VOID_PTR   pReserved  /* reserved.  Should be NULL_PTR */
13048 +#endif
13051 +/* C_GetInfo returns general information about Cryptoki. */
13052 +CK_PKCS11_FUNCTION_INFO(C_GetInfo)
13053 +#ifdef CK_NEED_ARG_LIST
13055 +  CK_INFO_PTR   pInfo  /* location that receives information */
13057 +#endif
13060 +/* C_GetFunctionList returns the function list. */
13061 +CK_PKCS11_FUNCTION_INFO(C_GetFunctionList)
13062 +#ifdef CK_NEED_ARG_LIST
13064 +  CK_FUNCTION_LIST_PTR_PTR ppFunctionList  /* receives pointer to
13065 +                                            * function list */
13067 +#endif
13071 +/* Slot and token management */
13073 +/* C_GetSlotList obtains a list of slots in the system. */
13074 +CK_PKCS11_FUNCTION_INFO(C_GetSlotList)
13075 +#ifdef CK_NEED_ARG_LIST
13077 +  CK_BBOOL       tokenPresent,  /* only slots with tokens? */
13078 +  CK_SLOT_ID_PTR pSlotList,     /* receives array of slot IDs */
13079 +  CK_ULONG_PTR   pulCount       /* receives number of slots */
13081 +#endif
13084 +/* C_GetSlotInfo obtains information about a particular slot in
13085 + * the system. */
13086 +CK_PKCS11_FUNCTION_INFO(C_GetSlotInfo)
13087 +#ifdef CK_NEED_ARG_LIST
13089 +  CK_SLOT_ID       slotID,  /* the ID of the slot */
13090 +  CK_SLOT_INFO_PTR pInfo    /* receives the slot information */
13092 +#endif
13095 +/* C_GetTokenInfo obtains information about a particular token
13096 + * in the system. */
13097 +CK_PKCS11_FUNCTION_INFO(C_GetTokenInfo)
13098 +#ifdef CK_NEED_ARG_LIST
13100 +  CK_SLOT_ID        slotID,  /* ID of the token's slot */
13101 +  CK_TOKEN_INFO_PTR pInfo    /* receives the token information */
13103 +#endif
13106 +/* C_GetMechanismList obtains a list of mechanism types
13107 + * supported by a token. */
13108 +CK_PKCS11_FUNCTION_INFO(C_GetMechanismList)
13109 +#ifdef CK_NEED_ARG_LIST
13111 +  CK_SLOT_ID            slotID,          /* ID of token's slot */
13112 +  CK_MECHANISM_TYPE_PTR pMechanismList,  /* gets mech. array */
13113 +  CK_ULONG_PTR          pulCount         /* gets # of mechs. */
13115 +#endif
13118 +/* C_GetMechanismInfo obtains information about a particular
13119 + * mechanism possibly supported by a token. */
13120 +CK_PKCS11_FUNCTION_INFO(C_GetMechanismInfo)
13121 +#ifdef CK_NEED_ARG_LIST
13123 +  CK_SLOT_ID            slotID,  /* ID of the token's slot */
13124 +  CK_MECHANISM_TYPE     type,    /* type of mechanism */
13125 +  CK_MECHANISM_INFO_PTR pInfo    /* receives mechanism info */
13127 +#endif
13130 +/* C_InitToken initializes a token. */
13131 +CK_PKCS11_FUNCTION_INFO(C_InitToken)
13132 +#ifdef CK_NEED_ARG_LIST
13133 +/* pLabel changed from CK_CHAR_PTR to CK_UTF8CHAR_PTR for v2.10 */
13135 +  CK_SLOT_ID      slotID,    /* ID of the token's slot */
13136 +  CK_UTF8CHAR_PTR pPin,      /* the SO's initial PIN */
13137 +  CK_ULONG        ulPinLen,  /* length in bytes of the PIN */
13138 +  CK_UTF8CHAR_PTR pLabel     /* 32-byte token label (blank padded) */
13140 +#endif
13143 +/* C_InitPIN initializes the normal user's PIN. */
13144 +CK_PKCS11_FUNCTION_INFO(C_InitPIN)
13145 +#ifdef CK_NEED_ARG_LIST
13147 +  CK_SESSION_HANDLE hSession,  /* the session's handle */
13148 +  CK_UTF8CHAR_PTR   pPin,      /* the normal user's PIN */
13149 +  CK_ULONG          ulPinLen   /* length in bytes of the PIN */
13151 +#endif
13154 +/* C_SetPIN modifies the PIN of the user who is logged in. */
13155 +CK_PKCS11_FUNCTION_INFO(C_SetPIN)
13156 +#ifdef CK_NEED_ARG_LIST
13158 +  CK_SESSION_HANDLE hSession,  /* the session's handle */
13159 +  CK_UTF8CHAR_PTR   pOldPin,   /* the old PIN */
13160 +  CK_ULONG          ulOldLen,  /* length of the old PIN */
13161 +  CK_UTF8CHAR_PTR   pNewPin,   /* the new PIN */
13162 +  CK_ULONG          ulNewLen   /* length of the new PIN */
13164 +#endif
13168 +/* Session management */
13170 +/* C_OpenSession opens a session between an application and a
13171 + * token. */
13172 +CK_PKCS11_FUNCTION_INFO(C_OpenSession)
13173 +#ifdef CK_NEED_ARG_LIST
13175 +  CK_SLOT_ID            slotID,        /* the slot's ID */
13176 +  CK_FLAGS              flags,         /* from CK_SESSION_INFO */
13177 +  CK_VOID_PTR           pApplication,  /* passed to callback */
13178 +  CK_NOTIFY             Notify,        /* callback function */
13179 +  CK_SESSION_HANDLE_PTR phSession      /* gets session handle */
13181 +#endif
13184 +/* C_CloseSession closes a session between an application and a
13185 + * token. */
13186 +CK_PKCS11_FUNCTION_INFO(C_CloseSession)
13187 +#ifdef CK_NEED_ARG_LIST
13189 +  CK_SESSION_HANDLE hSession  /* the session's handle */
13191 +#endif
13194 +/* C_CloseAllSessions closes all sessions with a token. */
13195 +CK_PKCS11_FUNCTION_INFO(C_CloseAllSessions)
13196 +#ifdef CK_NEED_ARG_LIST
13198 +  CK_SLOT_ID     slotID  /* the token's slot */
13200 +#endif
13203 +/* C_GetSessionInfo obtains information about the session. */
13204 +CK_PKCS11_FUNCTION_INFO(C_GetSessionInfo)
13205 +#ifdef CK_NEED_ARG_LIST
13207 +  CK_SESSION_HANDLE   hSession,  /* the session's handle */
13208 +  CK_SESSION_INFO_PTR pInfo      /* receives session info */
13210 +#endif
13213 +/* C_GetOperationState obtains the state of the cryptographic operation
13214 + * in a session. */
13215 +CK_PKCS11_FUNCTION_INFO(C_GetOperationState)
13216 +#ifdef CK_NEED_ARG_LIST
13218 +  CK_SESSION_HANDLE hSession,             /* session's handle */
13219 +  CK_BYTE_PTR       pOperationState,      /* gets state */
13220 +  CK_ULONG_PTR      pulOperationStateLen  /* gets state length */
13222 +#endif
13225 +/* C_SetOperationState restores the state of the cryptographic
13226 + * operation in a session. */
13227 +CK_PKCS11_FUNCTION_INFO(C_SetOperationState)
13228 +#ifdef CK_NEED_ARG_LIST
13230 +  CK_SESSION_HANDLE hSession,            /* session's handle */
13231 +  CK_BYTE_PTR      pOperationState,      /* holds state */
13232 +  CK_ULONG         ulOperationStateLen,  /* holds state length */
13233 +  CK_OBJECT_HANDLE hEncryptionKey,       /* en/decryption key */
13234 +  CK_OBJECT_HANDLE hAuthenticationKey    /* sign/verify key */
13236 +#endif
13239 +/* C_Login logs a user into a token. */
13240 +CK_PKCS11_FUNCTION_INFO(C_Login)
13241 +#ifdef CK_NEED_ARG_LIST
13243 +  CK_SESSION_HANDLE hSession,  /* the session's handle */
13244 +  CK_USER_TYPE      userType,  /* the user type */
13245 +  CK_UTF8CHAR_PTR   pPin,      /* the user's PIN */
13246 +  CK_ULONG          ulPinLen   /* the length of the PIN */
13248 +#endif
13251 +/* C_Logout logs a user out from a token. */
13252 +CK_PKCS11_FUNCTION_INFO(C_Logout)
13253 +#ifdef CK_NEED_ARG_LIST
13255 +  CK_SESSION_HANDLE hSession  /* the session's handle */
13257 +#endif
13261 +/* Object management */
13263 +/* C_CreateObject creates a new object. */
13264 +CK_PKCS11_FUNCTION_INFO(C_CreateObject)
13265 +#ifdef CK_NEED_ARG_LIST
13267 +  CK_SESSION_HANDLE hSession,    /* the session's handle */
13268 +  CK_ATTRIBUTE_PTR  pTemplate,   /* the object's template */
13269 +  CK_ULONG          ulCount,     /* attributes in template */
13270 +  CK_OBJECT_HANDLE_PTR phObject  /* gets new object's handle. */
13272 +#endif
13275 +/* C_CopyObject copies an object, creating a new object for the
13276 + * copy. */
13277 +CK_PKCS11_FUNCTION_INFO(C_CopyObject)
13278 +#ifdef CK_NEED_ARG_LIST
13280 +  CK_SESSION_HANDLE    hSession,    /* the session's handle */
13281 +  CK_OBJECT_HANDLE     hObject,     /* the object's handle */
13282 +  CK_ATTRIBUTE_PTR     pTemplate,   /* template for new object */
13283 +  CK_ULONG             ulCount,     /* attributes in template */
13284 +  CK_OBJECT_HANDLE_PTR phNewObject  /* receives handle of copy */
13286 +#endif
13289 +/* C_DestroyObject destroys an object. */
13290 +CK_PKCS11_FUNCTION_INFO(C_DestroyObject)
13291 +#ifdef CK_NEED_ARG_LIST
13293 +  CK_SESSION_HANDLE hSession,  /* the session's handle */
13294 +  CK_OBJECT_HANDLE  hObject    /* the object's handle */
13296 +#endif
13299 +/* C_GetObjectSize gets the size of an object in bytes. */
13300 +CK_PKCS11_FUNCTION_INFO(C_GetObjectSize)
13301 +#ifdef CK_NEED_ARG_LIST
13303 +  CK_SESSION_HANDLE hSession,  /* the session's handle */
13304 +  CK_OBJECT_HANDLE  hObject,   /* the object's handle */
13305 +  CK_ULONG_PTR      pulSize    /* receives size of object */
13307 +#endif
13310 +/* C_GetAttributeValue obtains the value of one or more object
13311 + * attributes. */
13312 +CK_PKCS11_FUNCTION_INFO(C_GetAttributeValue)
13313 +#ifdef CK_NEED_ARG_LIST
13315 +  CK_SESSION_HANDLE hSession,   /* the session's handle */
13316 +  CK_OBJECT_HANDLE  hObject,    /* the object's handle */
13317 +  CK_ATTRIBUTE_PTR  pTemplate,  /* specifies attrs; gets vals */
13318 +  CK_ULONG          ulCount     /* attributes in template */
13320 +#endif
13323 +/* C_SetAttributeValue modifies the value of one or more object
13324 + * attributes */
13325 +CK_PKCS11_FUNCTION_INFO(C_SetAttributeValue)
13326 +#ifdef CK_NEED_ARG_LIST
13328 +  CK_SESSION_HANDLE hSession,   /* the session's handle */
13329 +  CK_OBJECT_HANDLE  hObject,    /* the object's handle */
13330 +  CK_ATTRIBUTE_PTR  pTemplate,  /* specifies attrs and values */
13331 +  CK_ULONG          ulCount     /* attributes in template */
13333 +#endif
13336 +/* C_FindObjectsInit initializes a search for token and session
13337 + * objects that match a template. */
13338 +CK_PKCS11_FUNCTION_INFO(C_FindObjectsInit)
13339 +#ifdef CK_NEED_ARG_LIST
13341 +  CK_SESSION_HANDLE hSession,   /* the session's handle */
13342 +  CK_ATTRIBUTE_PTR  pTemplate,  /* attribute values to match */
13343 +  CK_ULONG          ulCount     /* attrs in search template */
13345 +#endif
13348 +/* C_FindObjects continues a search for token and session
13349 + * objects that match a template, obtaining additional object
13350 + * handles. */
13351 +CK_PKCS11_FUNCTION_INFO(C_FindObjects)
13352 +#ifdef CK_NEED_ARG_LIST
13354 + CK_SESSION_HANDLE    hSession,          /* session's handle */
13355 + CK_OBJECT_HANDLE_PTR phObject,          /* gets obj. handles */
13356 + CK_ULONG             ulMaxObjectCount,  /* max handles to get */
13357 + CK_ULONG_PTR         pulObjectCount     /* actual # returned */
13359 +#endif
13362 +/* C_FindObjectsFinal finishes a search for token and session
13363 + * objects. */
13364 +CK_PKCS11_FUNCTION_INFO(C_FindObjectsFinal)
13365 +#ifdef CK_NEED_ARG_LIST
13367 +  CK_SESSION_HANDLE hSession  /* the session's handle */
13369 +#endif
13373 +/* Encryption and decryption */
13375 +/* C_EncryptInit initializes an encryption operation. */
13376 +CK_PKCS11_FUNCTION_INFO(C_EncryptInit)
13377 +#ifdef CK_NEED_ARG_LIST
13379 +  CK_SESSION_HANDLE hSession,    /* the session's handle */
13380 +  CK_MECHANISM_PTR  pMechanism,  /* the encryption mechanism */
13381 +  CK_OBJECT_HANDLE  hKey         /* handle of encryption key */
13383 +#endif
13386 +/* C_Encrypt encrypts single-part data. */
13387 +CK_PKCS11_FUNCTION_INFO(C_Encrypt)
13388 +#ifdef CK_NEED_ARG_LIST
13390 +  CK_SESSION_HANDLE hSession,            /* session's handle */
13391 +  CK_BYTE_PTR       pData,               /* the plaintext data */
13392 +  CK_ULONG          ulDataLen,           /* bytes of plaintext */
13393 +  CK_BYTE_PTR       pEncryptedData,      /* gets ciphertext */
13394 +  CK_ULONG_PTR      pulEncryptedDataLen  /* gets c-text size */
13396 +#endif
13399 +/* C_EncryptUpdate continues a multiple-part encryption
13400 + * operation. */
13401 +CK_PKCS11_FUNCTION_INFO(C_EncryptUpdate)
13402 +#ifdef CK_NEED_ARG_LIST
13404 +  CK_SESSION_HANDLE hSession,           /* session's handle */
13405 +  CK_BYTE_PTR       pPart,              /* the plaintext data */
13406 +  CK_ULONG          ulPartLen,          /* plaintext data len */
13407 +  CK_BYTE_PTR       pEncryptedPart,     /* gets ciphertext */
13408 +  CK_ULONG_PTR      pulEncryptedPartLen /* gets c-text size */
13410 +#endif
13413 +/* C_EncryptFinal finishes a multiple-part encryption
13414 + * operation. */
13415 +CK_PKCS11_FUNCTION_INFO(C_EncryptFinal)
13416 +#ifdef CK_NEED_ARG_LIST
13418 +  CK_SESSION_HANDLE hSession,                /* session handle */
13419 +  CK_BYTE_PTR       pLastEncryptedPart,      /* last c-text */
13420 +  CK_ULONG_PTR      pulLastEncryptedPartLen  /* gets last size */
13422 +#endif
13425 +/* C_DecryptInit initializes a decryption operation. */
13426 +CK_PKCS11_FUNCTION_INFO(C_DecryptInit)
13427 +#ifdef CK_NEED_ARG_LIST
13429 +  CK_SESSION_HANDLE hSession,    /* the session's handle */
13430 +  CK_MECHANISM_PTR  pMechanism,  /* the decryption mechanism */
13431 +  CK_OBJECT_HANDLE  hKey         /* handle of decryption key */
13433 +#endif
13436 +/* C_Decrypt decrypts encrypted data in a single part. */
13437 +CK_PKCS11_FUNCTION_INFO(C_Decrypt)
13438 +#ifdef CK_NEED_ARG_LIST
13440 +  CK_SESSION_HANDLE hSession,           /* session's handle */
13441 +  CK_BYTE_PTR       pEncryptedData,     /* ciphertext */
13442 +  CK_ULONG          ulEncryptedDataLen, /* ciphertext length */
13443 +  CK_BYTE_PTR       pData,              /* gets plaintext */
13444 +  CK_ULONG_PTR      pulDataLen          /* gets p-text size */
13446 +#endif
13449 +/* C_DecryptUpdate continues a multiple-part decryption
13450 + * operation. */
13451 +CK_PKCS11_FUNCTION_INFO(C_DecryptUpdate)
13452 +#ifdef CK_NEED_ARG_LIST
13454 +  CK_SESSION_HANDLE hSession,            /* session's handle */
13455 +  CK_BYTE_PTR       pEncryptedPart,      /* encrypted data */
13456 +  CK_ULONG          ulEncryptedPartLen,  /* input length */
13457 +  CK_BYTE_PTR       pPart,               /* gets plaintext */
13458 +  CK_ULONG_PTR      pulPartLen           /* p-text size */
13460 +#endif
13463 +/* C_DecryptFinal finishes a multiple-part decryption
13464 + * operation. */
13465 +CK_PKCS11_FUNCTION_INFO(C_DecryptFinal)
13466 +#ifdef CK_NEED_ARG_LIST
13468 +  CK_SESSION_HANDLE hSession,       /* the session's handle */
13469 +  CK_BYTE_PTR       pLastPart,      /* gets plaintext */
13470 +  CK_ULONG_PTR      pulLastPartLen  /* p-text size */
13472 +#endif
13476 +/* Message digesting */
13478 +/* C_DigestInit initializes a message-digesting operation. */
13479 +CK_PKCS11_FUNCTION_INFO(C_DigestInit)
13480 +#ifdef CK_NEED_ARG_LIST
13482 +  CK_SESSION_HANDLE hSession,   /* the session's handle */
13483 +  CK_MECHANISM_PTR  pMechanism  /* the digesting mechanism */
13485 +#endif
13488 +/* C_Digest digests data in a single part. */
13489 +CK_PKCS11_FUNCTION_INFO(C_Digest)
13490 +#ifdef CK_NEED_ARG_LIST
13492 +  CK_SESSION_HANDLE hSession,     /* the session's handle */
13493 +  CK_BYTE_PTR       pData,        /* data to be digested */
13494 +  CK_ULONG          ulDataLen,    /* bytes of data to digest */
13495 +  CK_BYTE_PTR       pDigest,      /* gets the message digest */
13496 +  CK_ULONG_PTR      pulDigestLen  /* gets digest length */
13498 +#endif
13501 +/* C_DigestUpdate continues a multiple-part message-digesting
13502 + * operation. */
13503 +CK_PKCS11_FUNCTION_INFO(C_DigestUpdate)
13504 +#ifdef CK_NEED_ARG_LIST
13506 +  CK_SESSION_HANDLE hSession,  /* the session's handle */
13507 +  CK_BYTE_PTR       pPart,     /* data to be digested */
13508 +  CK_ULONG          ulPartLen  /* bytes of data to be digested */
13510 +#endif
13513 +/* C_DigestKey continues a multi-part message-digesting
13514 + * operation, by digesting the value of a secret key as part of
13515 + * the data already digested. */
13516 +CK_PKCS11_FUNCTION_INFO(C_DigestKey)
13517 +#ifdef CK_NEED_ARG_LIST
13519 +  CK_SESSION_HANDLE hSession,  /* the session's handle */
13520 +  CK_OBJECT_HANDLE  hKey       /* secret key to digest */
13522 +#endif
13525 +/* C_DigestFinal finishes a multiple-part message-digesting
13526 + * operation. */
13527 +CK_PKCS11_FUNCTION_INFO(C_DigestFinal)
13528 +#ifdef CK_NEED_ARG_LIST
13530 +  CK_SESSION_HANDLE hSession,     /* the session's handle */
13531 +  CK_BYTE_PTR       pDigest,      /* gets the message digest */
13532 +  CK_ULONG_PTR      pulDigestLen  /* gets byte count of digest */
13534 +#endif
13538 +/* Signing and MACing */
13540 +/* C_SignInit initializes a signature (private key encryption)
13541 + * operation, where the signature is (will be) an appendix to
13542 + * the data, and plaintext cannot be recovered from the
13543 + *signature. */
13544 +CK_PKCS11_FUNCTION_INFO(C_SignInit)
13545 +#ifdef CK_NEED_ARG_LIST
13547 +  CK_SESSION_HANDLE hSession,    /* the session's handle */
13548 +  CK_MECHANISM_PTR  pMechanism,  /* the signature mechanism */
13549 +  CK_OBJECT_HANDLE  hKey         /* handle of signature key */
13551 +#endif
13554 +/* C_Sign signs (encrypts with private key) data in a single
13555 + * part, where the signature is (will be) an appendix to the
13556 + * data, and plaintext cannot be recovered from the signature. */
13557 +CK_PKCS11_FUNCTION_INFO(C_Sign)
13558 +#ifdef CK_NEED_ARG_LIST
13560 +  CK_SESSION_HANDLE hSession,        /* the session's handle */
13561 +  CK_BYTE_PTR       pData,           /* the data to sign */
13562 +  CK_ULONG          ulDataLen,       /* count of bytes to sign */
13563 +  CK_BYTE_PTR       pSignature,      /* gets the signature */
13564 +  CK_ULONG_PTR      pulSignatureLen  /* gets signature length */
13566 +#endif
13569 +/* C_SignUpdate continues a multiple-part signature operation,
13570 + * where the signature is (will be) an appendix to the data, 
13571 + * and plaintext cannot be recovered from the signature. */
13572 +CK_PKCS11_FUNCTION_INFO(C_SignUpdate)
13573 +#ifdef CK_NEED_ARG_LIST
13575 +  CK_SESSION_HANDLE hSession,  /* the session's handle */
13576 +  CK_BYTE_PTR       pPart,     /* the data to sign */
13577 +  CK_ULONG          ulPartLen  /* count of bytes to sign */
13579 +#endif
13582 +/* C_SignFinal finishes a multiple-part signature operation, 
13583 + * returning the signature. */
13584 +CK_PKCS11_FUNCTION_INFO(C_SignFinal)
13585 +#ifdef CK_NEED_ARG_LIST
13587 +  CK_SESSION_HANDLE hSession,        /* the session's handle */
13588 +  CK_BYTE_PTR       pSignature,      /* gets the signature */
13589 +  CK_ULONG_PTR      pulSignatureLen  /* gets signature length */
13591 +#endif
13594 +/* C_SignRecoverInit initializes a signature operation, where
13595 + * the data can be recovered from the signature. */
13596 +CK_PKCS11_FUNCTION_INFO(C_SignRecoverInit)
13597 +#ifdef CK_NEED_ARG_LIST
13599 +  CK_SESSION_HANDLE hSession,   /* the session's handle */
13600 +  CK_MECHANISM_PTR  pMechanism, /* the signature mechanism */
13601 +  CK_OBJECT_HANDLE  hKey        /* handle of the signature key */
13603 +#endif
13606 +/* C_SignRecover signs data in a single operation, where the
13607 + * data can be recovered from the signature. */
13608 +CK_PKCS11_FUNCTION_INFO(C_SignRecover)
13609 +#ifdef CK_NEED_ARG_LIST
13611 +  CK_SESSION_HANDLE hSession,        /* the session's handle */
13612 +  CK_BYTE_PTR       pData,           /* the data to sign */
13613 +  CK_ULONG          ulDataLen,       /* count of bytes to sign */
13614 +  CK_BYTE_PTR       pSignature,      /* gets the signature */
13615 +  CK_ULONG_PTR      pulSignatureLen  /* gets signature length */
13617 +#endif
13621 +/* Verifying signatures and MACs */
13623 +/* C_VerifyInit initializes a verification operation, where the
13624 + * signature is an appendix to the data, and plaintext cannot
13625 + *  cannot be recovered from the signature (e.g. DSA). */
13626 +CK_PKCS11_FUNCTION_INFO(C_VerifyInit)
13627 +#ifdef CK_NEED_ARG_LIST
13629 +  CK_SESSION_HANDLE hSession,    /* the session's handle */
13630 +  CK_MECHANISM_PTR  pMechanism,  /* the verification mechanism */
13631 +  CK_OBJECT_HANDLE  hKey         /* verification key */ 
13633 +#endif
13636 +/* C_Verify verifies a signature in a single-part operation, 
13637 + * where the signature is an appendix to the data, and plaintext
13638 + * cannot be recovered from the signature. */
13639 +CK_PKCS11_FUNCTION_INFO(C_Verify)
13640 +#ifdef CK_NEED_ARG_LIST
13642 +  CK_SESSION_HANDLE hSession,       /* the session's handle */
13643 +  CK_BYTE_PTR       pData,          /* signed data */
13644 +  CK_ULONG          ulDataLen,      /* length of signed data */
13645 +  CK_BYTE_PTR       pSignature,     /* signature */
13646 +  CK_ULONG          ulSignatureLen  /* signature length*/
13648 +#endif
13651 +/* C_VerifyUpdate continues a multiple-part verification
13652 + * operation, where the signature is an appendix to the data, 
13653 + * and plaintext cannot be recovered from the signature. */
13654 +CK_PKCS11_FUNCTION_INFO(C_VerifyUpdate)
13655 +#ifdef CK_NEED_ARG_LIST
13657 +  CK_SESSION_HANDLE hSession,  /* the session's handle */
13658 +  CK_BYTE_PTR       pPart,     /* signed data */
13659 +  CK_ULONG          ulPartLen  /* length of signed data */
13661 +#endif
13664 +/* C_VerifyFinal finishes a multiple-part verification
13665 + * operation, checking the signature. */
13666 +CK_PKCS11_FUNCTION_INFO(C_VerifyFinal)
13667 +#ifdef CK_NEED_ARG_LIST
13669 +  CK_SESSION_HANDLE hSession,       /* the session's handle */
13670 +  CK_BYTE_PTR       pSignature,     /* signature to verify */
13671 +  CK_ULONG          ulSignatureLen  /* signature length */
13673 +#endif
13676 +/* C_VerifyRecoverInit initializes a signature verification
13677 + * operation, where the data is recovered from the signature. */
13678 +CK_PKCS11_FUNCTION_INFO(C_VerifyRecoverInit)
13679 +#ifdef CK_NEED_ARG_LIST
13681 +  CK_SESSION_HANDLE hSession,    /* the session's handle */
13682 +  CK_MECHANISM_PTR  pMechanism,  /* the verification mechanism */
13683 +  CK_OBJECT_HANDLE  hKey         /* verification key */
13685 +#endif
13688 +/* C_VerifyRecover verifies a signature in a single-part
13689 + * operation, where the data is recovered from the signature. */
13690 +CK_PKCS11_FUNCTION_INFO(C_VerifyRecover)
13691 +#ifdef CK_NEED_ARG_LIST
13693 +  CK_SESSION_HANDLE hSession,        /* the session's handle */
13694 +  CK_BYTE_PTR       pSignature,      /* signature to verify */
13695 +  CK_ULONG          ulSignatureLen,  /* signature length */
13696 +  CK_BYTE_PTR       pData,           /* gets signed data */
13697 +  CK_ULONG_PTR      pulDataLen       /* gets signed data len */
13699 +#endif
13703 +/* Dual-function cryptographic operations */
13705 +/* C_DigestEncryptUpdate continues a multiple-part digesting
13706 + * and encryption operation. */
13707 +CK_PKCS11_FUNCTION_INFO(C_DigestEncryptUpdate)
13708 +#ifdef CK_NEED_ARG_LIST
13710 +  CK_SESSION_HANDLE hSession,            /* session's handle */
13711 +  CK_BYTE_PTR       pPart,               /* the plaintext data */
13712 +  CK_ULONG          ulPartLen,           /* plaintext length */
13713 +  CK_BYTE_PTR       pEncryptedPart,      /* gets ciphertext */
13714 +  CK_ULONG_PTR      pulEncryptedPartLen  /* gets c-text length */
13716 +#endif
13719 +/* C_DecryptDigestUpdate continues a multiple-part decryption and
13720 + * digesting operation. */
13721 +CK_PKCS11_FUNCTION_INFO(C_DecryptDigestUpdate)
13722 +#ifdef CK_NEED_ARG_LIST
13724 +  CK_SESSION_HANDLE hSession,            /* session's handle */
13725 +  CK_BYTE_PTR       pEncryptedPart,      /* ciphertext */
13726 +  CK_ULONG          ulEncryptedPartLen,  /* ciphertext length */
13727 +  CK_BYTE_PTR       pPart,               /* gets plaintext */
13728 +  CK_ULONG_PTR      pulPartLen           /* gets plaintext len */
13730 +#endif
13733 +/* C_SignEncryptUpdate continues a multiple-part signing and
13734 + * encryption operation. */
13735 +CK_PKCS11_FUNCTION_INFO(C_SignEncryptUpdate)
13736 +#ifdef CK_NEED_ARG_LIST
13738 +  CK_SESSION_HANDLE hSession,            /* session's handle */
13739 +  CK_BYTE_PTR       pPart,               /* the plaintext data */
13740 +  CK_ULONG          ulPartLen,           /* plaintext length */
13741 +  CK_BYTE_PTR       pEncryptedPart,      /* gets ciphertext */
13742 +  CK_ULONG_PTR      pulEncryptedPartLen  /* gets c-text length */
13744 +#endif
13747 +/* C_DecryptVerifyUpdate continues a multiple-part decryption and
13748 + * verify operation. */
13749 +CK_PKCS11_FUNCTION_INFO(C_DecryptVerifyUpdate)
13750 +#ifdef CK_NEED_ARG_LIST
13752 +  CK_SESSION_HANDLE hSession,            /* session's handle */
13753 +  CK_BYTE_PTR       pEncryptedPart,      /* ciphertext */
13754 +  CK_ULONG          ulEncryptedPartLen,  /* ciphertext length */
13755 +  CK_BYTE_PTR       pPart,               /* gets plaintext */
13756 +  CK_ULONG_PTR      pulPartLen           /* gets p-text length */
13758 +#endif
13762 +/* Key management */
13764 +/* C_GenerateKey generates a secret key, creating a new key
13765 + * object. */
13766 +CK_PKCS11_FUNCTION_INFO(C_GenerateKey)
13767 +#ifdef CK_NEED_ARG_LIST
13769 +  CK_SESSION_HANDLE    hSession,    /* the session's handle */
13770 +  CK_MECHANISM_PTR     pMechanism,  /* key generation mech. */
13771 +  CK_ATTRIBUTE_PTR     pTemplate,   /* template for new key */
13772 +  CK_ULONG             ulCount,     /* # of attrs in template */
13773 +  CK_OBJECT_HANDLE_PTR phKey        /* gets handle of new key */
13775 +#endif
13778 +/* C_GenerateKeyPair generates a public-key/private-key pair, 
13779 + * creating new key objects. */
13780 +CK_PKCS11_FUNCTION_INFO(C_GenerateKeyPair)
13781 +#ifdef CK_NEED_ARG_LIST
13783 +  CK_SESSION_HANDLE    hSession,                    /* session
13784 +                                                     * handle */
13785 +  CK_MECHANISM_PTR     pMechanism,                  /* key-gen
13786 +                                                     * mech. */
13787 +  CK_ATTRIBUTE_PTR     pPublicKeyTemplate,          /* template
13788 +                                                     * for pub.
13789 +                                                     * key */
13790 +  CK_ULONG             ulPublicKeyAttributeCount,   /* # pub.
13791 +                                                     * attrs. */
13792 +  CK_ATTRIBUTE_PTR     pPrivateKeyTemplate,         /* template
13793 +                                                     * for priv.
13794 +                                                     * key */
13795 +  CK_ULONG             ulPrivateKeyAttributeCount,  /* # priv.
13796 +                                                     * attrs. */
13797 +  CK_OBJECT_HANDLE_PTR phPublicKey,                 /* gets pub.
13798 +                                                     * key
13799 +                                                     * handle */
13800 +  CK_OBJECT_HANDLE_PTR phPrivateKey                 /* gets
13801 +                                                     * priv. key
13802 +                                                     * handle */
13804 +#endif
13807 +/* C_WrapKey wraps (i.e., encrypts) a key. */
13808 +CK_PKCS11_FUNCTION_INFO(C_WrapKey)
13809 +#ifdef CK_NEED_ARG_LIST
13811 +  CK_SESSION_HANDLE hSession,        /* the session's handle */
13812 +  CK_MECHANISM_PTR  pMechanism,      /* the wrapping mechanism */
13813 +  CK_OBJECT_HANDLE  hWrappingKey,    /* wrapping key */
13814 +  CK_OBJECT_HANDLE  hKey,            /* key to be wrapped */
13815 +  CK_BYTE_PTR       pWrappedKey,     /* gets wrapped key */
13816 +  CK_ULONG_PTR      pulWrappedKeyLen /* gets wrapped key size */
13818 +#endif
13821 +/* C_UnwrapKey unwraps (decrypts) a wrapped key, creating a new
13822 + * key object. */
13823 +CK_PKCS11_FUNCTION_INFO(C_UnwrapKey)
13824 +#ifdef CK_NEED_ARG_LIST
13826 +  CK_SESSION_HANDLE    hSession,          /* session's handle */
13827 +  CK_MECHANISM_PTR     pMechanism,        /* unwrapping mech. */
13828 +  CK_OBJECT_HANDLE     hUnwrappingKey,    /* unwrapping key */
13829 +  CK_BYTE_PTR          pWrappedKey,       /* the wrapped key */
13830 +  CK_ULONG             ulWrappedKeyLen,   /* wrapped key len */
13831 +  CK_ATTRIBUTE_PTR     pTemplate,         /* new key template */
13832 +  CK_ULONG             ulAttributeCount,  /* template length */
13833 +  CK_OBJECT_HANDLE_PTR phKey              /* gets new handle */
13835 +#endif
13838 +/* C_DeriveKey derives a key from a base key, creating a new key
13839 + * object. */
13840 +CK_PKCS11_FUNCTION_INFO(C_DeriveKey)
13841 +#ifdef CK_NEED_ARG_LIST
13843 +  CK_SESSION_HANDLE    hSession,          /* session's handle */
13844 +  CK_MECHANISM_PTR     pMechanism,        /* key deriv. mech. */
13845 +  CK_OBJECT_HANDLE     hBaseKey,          /* base key */
13846 +  CK_ATTRIBUTE_PTR     pTemplate,         /* new key template */
13847 +  CK_ULONG             ulAttributeCount,  /* template length */
13848 +  CK_OBJECT_HANDLE_PTR phKey              /* gets new handle */
13850 +#endif
13854 +/* Random number generation */
13856 +/* C_SeedRandom mixes additional seed material into the token's
13857 + * random number generator. */
13858 +CK_PKCS11_FUNCTION_INFO(C_SeedRandom)
13859 +#ifdef CK_NEED_ARG_LIST
13861 +  CK_SESSION_HANDLE hSession,  /* the session's handle */
13862 +  CK_BYTE_PTR       pSeed,     /* the seed material */
13863 +  CK_ULONG          ulSeedLen  /* length of seed material */
13865 +#endif
13868 +/* C_GenerateRandom generates random data. */
13869 +CK_PKCS11_FUNCTION_INFO(C_GenerateRandom)
13870 +#ifdef CK_NEED_ARG_LIST
13872 +  CK_SESSION_HANDLE hSession,    /* the session's handle */
13873 +  CK_BYTE_PTR       RandomData,  /* receives the random data */
13874 +  CK_ULONG          ulRandomLen  /* # of bytes to generate */
13876 +#endif
13880 +/* Parallel function management */
13882 +/* C_GetFunctionStatus is a legacy function; it obtains an
13883 + * updated status of a function running in parallel with an
13884 + * application. */
13885 +CK_PKCS11_FUNCTION_INFO(C_GetFunctionStatus)
13886 +#ifdef CK_NEED_ARG_LIST
13888 +  CK_SESSION_HANDLE hSession  /* the session's handle */
13890 +#endif
13893 +/* C_CancelFunction is a legacy function; it cancels a function
13894 + * running in parallel. */
13895 +CK_PKCS11_FUNCTION_INFO(C_CancelFunction)
13896 +#ifdef CK_NEED_ARG_LIST
13898 +  CK_SESSION_HANDLE hSession  /* the session's handle */
13900 +#endif
13904 +/* Functions added in for Cryptoki Version 2.01 or later */
13906 +/* C_WaitForSlotEvent waits for a slot event (token insertion,
13907 + * removal, etc.) to occur. */
13908 +CK_PKCS11_FUNCTION_INFO(C_WaitForSlotEvent)
13909 +#ifdef CK_NEED_ARG_LIST
13911 +  CK_FLAGS flags,        /* blocking/nonblocking flag */
13912 +  CK_SLOT_ID_PTR pSlot,  /* location that receives the slot ID */
13913 +  CK_VOID_PTR pRserved   /* reserved.  Should be NULL_PTR */
13915 +#endif
13916 Index: openssl/crypto/engine/pkcs11t.h
13917 diff -u /dev/null openssl/crypto/engine/pkcs11t.h:1.2
13918 --- /dev/null   Fri Jan  2 13:56:41 2015
13919 +++ openssl/crypto/engine/pkcs11t.h     Sat Aug 30 11:58:07 2008
13920 @@ -0,0 +1,1885 @@
13921 +/* pkcs11t.h include file for PKCS #11. */
13922 +/* Revision: 1.2  */
13924 +/* License to copy and use this software is granted provided that it is
13925 + * identified as "RSA Security Inc. PKCS #11 Cryptographic Token Interface
13926 + * (Cryptoki)" in all material mentioning or referencing this software.
13928 + * License is also granted to make and use derivative works provided that
13929 + * such works are identified as "derived from the RSA Security Inc. PKCS #11
13930 + * Cryptographic Token Interface (Cryptoki)" in all material mentioning or
13931 + * referencing the derived work.
13933 + * RSA Security Inc. makes no representations concerning either the
13934 + * merchantability of this software or the suitability of this software for
13935 + * any particular purpose. It is provided "as is" without express or implied
13936 + * warranty of any kind.
13937 + */
13939 +/* See top of pkcs11.h for information about the macros that
13940 + * must be defined and the structure-packing conventions that
13941 + * must be set before including this file. */
13943 +#ifndef _PKCS11T_H_
13944 +#define _PKCS11T_H_ 1
13946 +#define CRYPTOKI_VERSION_MAJOR 2
13947 +#define CRYPTOKI_VERSION_MINOR 20
13948 +#define CRYPTOKI_VERSION_AMENDMENT 3
13950 +#define CK_TRUE 1
13951 +#define CK_FALSE 0
13953 +#ifndef CK_DISABLE_TRUE_FALSE
13954 +#ifndef FALSE
13955 +#define FALSE CK_FALSE
13956 +#endif
13958 +#ifndef TRUE
13959 +#define TRUE CK_TRUE
13960 +#endif
13961 +#endif
13963 +/* an unsigned 8-bit value */
13964 +typedef unsigned char     CK_BYTE;
13966 +/* an unsigned 8-bit character */
13967 +typedef CK_BYTE           CK_CHAR;
13969 +/* an 8-bit UTF-8 character */
13970 +typedef CK_BYTE           CK_UTF8CHAR;
13972 +/* a BYTE-sized Boolean flag */
13973 +typedef CK_BYTE           CK_BBOOL;
13975 +/* an unsigned value, at least 32 bits long */
13976 +typedef unsigned long int CK_ULONG;
13978 +/* a signed value, the same size as a CK_ULONG */
13979 +/* CK_LONG is new for v2.0 */
13980 +typedef long int          CK_LONG;
13982 +/* at least 32 bits; each bit is a Boolean flag */
13983 +typedef CK_ULONG          CK_FLAGS;
13986 +/* some special values for certain CK_ULONG variables */
13987 +#define CK_UNAVAILABLE_INFORMATION (~0UL)
13988 +#define CK_EFFECTIVELY_INFINITE    0
13991 +typedef CK_BYTE     CK_PTR   CK_BYTE_PTR;
13992 +typedef CK_CHAR     CK_PTR   CK_CHAR_PTR;
13993 +typedef CK_UTF8CHAR CK_PTR   CK_UTF8CHAR_PTR;
13994 +typedef CK_ULONG    CK_PTR   CK_ULONG_PTR;
13995 +typedef void        CK_PTR   CK_VOID_PTR;
13997 +/* Pointer to a CK_VOID_PTR-- i.e., pointer to pointer to void */
13998 +typedef CK_VOID_PTR CK_PTR CK_VOID_PTR_PTR;
14001 +/* The following value is always invalid if used as a session */
14002 +/* handle or object handle */
14003 +#define CK_INVALID_HANDLE 0
14006 +typedef struct CK_VERSION {
14007 +  CK_BYTE       major;  /* integer portion of version number */
14008 +  CK_BYTE       minor;  /* 1/100ths portion of version number */
14009 +} CK_VERSION;
14011 +typedef CK_VERSION CK_PTR CK_VERSION_PTR;
14014 +typedef struct CK_INFO {
14015 +  /* manufacturerID and libraryDecription have been changed from
14016 +   * CK_CHAR to CK_UTF8CHAR for v2.10 */
14017 +  CK_VERSION    cryptokiVersion;     /* Cryptoki interface ver */
14018 +  CK_UTF8CHAR   manufacturerID[32];  /* blank padded */
14019 +  CK_FLAGS      flags;               /* must be zero */
14021 +  /* libraryDescription and libraryVersion are new for v2.0 */
14022 +  CK_UTF8CHAR   libraryDescription[32];  /* blank padded */
14023 +  CK_VERSION    libraryVersion;          /* version of library */
14024 +} CK_INFO;
14026 +typedef CK_INFO CK_PTR    CK_INFO_PTR;
14029 +/* CK_NOTIFICATION enumerates the types of notifications that
14030 + * Cryptoki provides to an application */
14031 +/* CK_NOTIFICATION has been changed from an enum to a CK_ULONG
14032 + * for v2.0 */
14033 +typedef CK_ULONG CK_NOTIFICATION;
14034 +#define CKN_SURRENDER       0
14036 +/* The following notification is new for PKCS #11 v2.20 amendment 3 */
14037 +#define CKN_OTP_CHANGED     1
14040 +typedef CK_ULONG          CK_SLOT_ID;
14042 +typedef CK_SLOT_ID CK_PTR CK_SLOT_ID_PTR;
14045 +/* CK_SLOT_INFO provides information about a slot */
14046 +typedef struct CK_SLOT_INFO {
14047 +  /* slotDescription and manufacturerID have been changed from
14048 +   * CK_CHAR to CK_UTF8CHAR for v2.10 */
14049 +  CK_UTF8CHAR   slotDescription[64];  /* blank padded */
14050 +  CK_UTF8CHAR   manufacturerID[32];   /* blank padded */
14051 +  CK_FLAGS      flags;
14053 +  /* hardwareVersion and firmwareVersion are new for v2.0 */
14054 +  CK_VERSION    hardwareVersion;  /* version of hardware */
14055 +  CK_VERSION    firmwareVersion;  /* version of firmware */
14056 +} CK_SLOT_INFO;
14058 +/* flags: bit flags that provide capabilities of the slot
14059 + *      Bit Flag              Mask        Meaning
14060 + */
14061 +#define CKF_TOKEN_PRESENT     0x00000001  /* a token is there */
14062 +#define CKF_REMOVABLE_DEVICE  0x00000002  /* removable devices*/
14063 +#define CKF_HW_SLOT           0x00000004  /* hardware slot */
14065 +typedef CK_SLOT_INFO CK_PTR CK_SLOT_INFO_PTR;
14068 +/* CK_TOKEN_INFO provides information about a token */
14069 +typedef struct CK_TOKEN_INFO {
14070 +  /* label, manufacturerID, and model have been changed from
14071 +   * CK_CHAR to CK_UTF8CHAR for v2.10 */
14072 +  CK_UTF8CHAR   label[32];           /* blank padded */
14073 +  CK_UTF8CHAR   manufacturerID[32];  /* blank padded */
14074 +  CK_UTF8CHAR   model[16];           /* blank padded */
14075 +  CK_CHAR       serialNumber[16];    /* blank padded */
14076 +  CK_FLAGS      flags;               /* see below */
14078 +  /* ulMaxSessionCount, ulSessionCount, ulMaxRwSessionCount,
14079 +   * ulRwSessionCount, ulMaxPinLen, and ulMinPinLen have all been
14080 +   * changed from CK_USHORT to CK_ULONG for v2.0 */
14081 +  CK_ULONG      ulMaxSessionCount;     /* max open sessions */
14082 +  CK_ULONG      ulSessionCount;        /* sess. now open */
14083 +  CK_ULONG      ulMaxRwSessionCount;   /* max R/W sessions */
14084 +  CK_ULONG      ulRwSessionCount;      /* R/W sess. now open */
14085 +  CK_ULONG      ulMaxPinLen;           /* in bytes */
14086 +  CK_ULONG      ulMinPinLen;           /* in bytes */
14087 +  CK_ULONG      ulTotalPublicMemory;   /* in bytes */
14088 +  CK_ULONG      ulFreePublicMemory;    /* in bytes */
14089 +  CK_ULONG      ulTotalPrivateMemory;  /* in bytes */
14090 +  CK_ULONG      ulFreePrivateMemory;   /* in bytes */
14092 +  /* hardwareVersion, firmwareVersion, and time are new for
14093 +   * v2.0 */
14094 +  CK_VERSION    hardwareVersion;       /* version of hardware */
14095 +  CK_VERSION    firmwareVersion;       /* version of firmware */
14096 +  CK_CHAR       utcTime[16];           /* time */
14097 +} CK_TOKEN_INFO;
14099 +/* The flags parameter is defined as follows:
14100 + *      Bit Flag                    Mask        Meaning
14101 + */
14102 +#define CKF_RNG                     0x00000001  /* has random #
14103 +                                                 * generator */
14104 +#define CKF_WRITE_PROTECTED         0x00000002  /* token is
14105 +                                                 * write-
14106 +                                                 * protected */
14107 +#define CKF_LOGIN_REQUIRED          0x00000004  /* user must
14108 +                                                 * login */
14109 +#define CKF_USER_PIN_INITIALIZED    0x00000008  /* normal user's
14110 +                                                 * PIN is set */
14112 +/* CKF_RESTORE_KEY_NOT_NEEDED is new for v2.0.  If it is set,
14113 + * that means that *every* time the state of cryptographic
14114 + * operations of a session is successfully saved, all keys
14115 + * needed to continue those operations are stored in the state */
14116 +#define CKF_RESTORE_KEY_NOT_NEEDED  0x00000020
14118 +/* CKF_CLOCK_ON_TOKEN is new for v2.0.  If it is set, that means
14119 + * that the token has some sort of clock.  The time on that
14120 + * clock is returned in the token info structure */
14121 +#define CKF_CLOCK_ON_TOKEN          0x00000040
14123 +/* CKF_PROTECTED_AUTHENTICATION_PATH is new for v2.0.  If it is
14124 + * set, that means that there is some way for the user to login
14125 + * without sending a PIN through the Cryptoki library itself */
14126 +#define CKF_PROTECTED_AUTHENTICATION_PATH 0x00000100
14128 +/* CKF_DUAL_CRYPTO_OPERATIONS is new for v2.0.  If it is true,
14129 + * that means that a single session with the token can perform
14130 + * dual simultaneous cryptographic operations (digest and
14131 + * encrypt; decrypt and digest; sign and encrypt; and decrypt
14132 + * and sign) */
14133 +#define CKF_DUAL_CRYPTO_OPERATIONS  0x00000200
14135 +/* CKF_TOKEN_INITIALIZED if new for v2.10. If it is true, the
14136 + * token has been initialized using C_InitializeToken or an
14137 + * equivalent mechanism outside the scope of PKCS #11.
14138 + * Calling C_InitializeToken when this flag is set will cause
14139 + * the token to be reinitialized. */
14140 +#define CKF_TOKEN_INITIALIZED       0x00000400
14142 +/* CKF_SECONDARY_AUTHENTICATION if new for v2.10. If it is
14143 + * true, the token supports secondary authentication for
14144 + * private key objects. This flag is deprecated in v2.11 and
14145 +   onwards. */
14146 +#define CKF_SECONDARY_AUTHENTICATION  0x00000800
14148 +/* CKF_USER_PIN_COUNT_LOW if new for v2.10. If it is true, an
14149 + * incorrect user login PIN has been entered at least once
14150 + * since the last successful authentication. */
14151 +#define CKF_USER_PIN_COUNT_LOW       0x00010000
14153 +/* CKF_USER_PIN_FINAL_TRY if new for v2.10. If it is true,
14154 + * supplying an incorrect user PIN will it to become locked. */
14155 +#define CKF_USER_PIN_FINAL_TRY       0x00020000
14157 +/* CKF_USER_PIN_LOCKED if new for v2.10. If it is true, the
14158 + * user PIN has been locked. User login to the token is not
14159 + * possible. */
14160 +#define CKF_USER_PIN_LOCKED          0x00040000
14162 +/* CKF_USER_PIN_TO_BE_CHANGED if new for v2.10. If it is true,
14163 + * the user PIN value is the default value set by token
14164 + * initialization or manufacturing, or the PIN has been
14165 + * expired by the card. */
14166 +#define CKF_USER_PIN_TO_BE_CHANGED   0x00080000
14168 +/* CKF_SO_PIN_COUNT_LOW if new for v2.10. If it is true, an
14169 + * incorrect SO login PIN has been entered at least once since
14170 + * the last successful authentication. */
14171 +#define CKF_SO_PIN_COUNT_LOW         0x00100000
14173 +/* CKF_SO_PIN_FINAL_TRY if new for v2.10. If it is true,
14174 + * supplying an incorrect SO PIN will it to become locked. */
14175 +#define CKF_SO_PIN_FINAL_TRY         0x00200000
14177 +/* CKF_SO_PIN_LOCKED if new for v2.10. If it is true, the SO
14178 + * PIN has been locked. SO login to the token is not possible.
14179 + */
14180 +#define CKF_SO_PIN_LOCKED            0x00400000
14182 +/* CKF_SO_PIN_TO_BE_CHANGED if new for v2.10. If it is true,
14183 + * the SO PIN value is the default value set by token
14184 + * initialization or manufacturing, or the PIN has been
14185 + * expired by the card. */
14186 +#define CKF_SO_PIN_TO_BE_CHANGED     0x00800000
14188 +typedef CK_TOKEN_INFO CK_PTR CK_TOKEN_INFO_PTR;
14191 +/* CK_SESSION_HANDLE is a Cryptoki-assigned value that
14192 + * identifies a session */
14193 +typedef CK_ULONG          CK_SESSION_HANDLE;
14195 +typedef CK_SESSION_HANDLE CK_PTR CK_SESSION_HANDLE_PTR;
14198 +/* CK_USER_TYPE enumerates the types of Cryptoki users */
14199 +/* CK_USER_TYPE has been changed from an enum to a CK_ULONG for
14200 + * v2.0 */
14201 +typedef CK_ULONG          CK_USER_TYPE;
14202 +/* Security Officer */
14203 +#define CKU_SO    0
14204 +/* Normal user */
14205 +#define CKU_USER  1
14206 +/* Context specific (added in v2.20) */
14207 +#define CKU_CONTEXT_SPECIFIC   2
14209 +/* CK_STATE enumerates the session states */
14210 +/* CK_STATE has been changed from an enum to a CK_ULONG for
14211 + * v2.0 */
14212 +typedef CK_ULONG          CK_STATE;
14213 +#define CKS_RO_PUBLIC_SESSION  0
14214 +#define CKS_RO_USER_FUNCTIONS  1
14215 +#define CKS_RW_PUBLIC_SESSION  2
14216 +#define CKS_RW_USER_FUNCTIONS  3
14217 +#define CKS_RW_SO_FUNCTIONS    4
14220 +/* CK_SESSION_INFO provides information about a session */
14221 +typedef struct CK_SESSION_INFO {
14222 +  CK_SLOT_ID    slotID;
14223 +  CK_STATE      state;
14224 +  CK_FLAGS      flags;          /* see below */
14226 +  /* ulDeviceError was changed from CK_USHORT to CK_ULONG for
14227 +   * v2.0 */
14228 +  CK_ULONG      ulDeviceError;  /* device-dependent error code */
14229 +} CK_SESSION_INFO;
14231 +/* The flags are defined in the following table:
14232 + *      Bit Flag                Mask        Meaning
14233 + */
14234 +#define CKF_RW_SESSION          0x00000002  /* session is r/w */
14235 +#define CKF_SERIAL_SESSION      0x00000004  /* no parallel */
14237 +typedef CK_SESSION_INFO CK_PTR CK_SESSION_INFO_PTR;
14240 +/* CK_OBJECT_HANDLE is a token-specific identifier for an
14241 + * object  */
14242 +typedef CK_ULONG          CK_OBJECT_HANDLE;
14244 +typedef CK_OBJECT_HANDLE CK_PTR CK_OBJECT_HANDLE_PTR;
14247 +/* CK_OBJECT_CLASS is a value that identifies the classes (or
14248 + * types) of objects that Cryptoki recognizes.  It is defined
14249 + * as follows: */
14250 +/* CK_OBJECT_CLASS was changed from CK_USHORT to CK_ULONG for
14251 + * v2.0 */
14252 +typedef CK_ULONG          CK_OBJECT_CLASS;
14254 +/* The following classes of objects are defined: */
14255 +/* CKO_HW_FEATURE is new for v2.10 */
14256 +/* CKO_DOMAIN_PARAMETERS is new for v2.11 */
14257 +/* CKO_MECHANISM is new for v2.20 */
14258 +#define CKO_DATA              0x00000000
14259 +#define CKO_CERTIFICATE       0x00000001
14260 +#define CKO_PUBLIC_KEY        0x00000002
14261 +#define CKO_PRIVATE_KEY       0x00000003
14262 +#define CKO_SECRET_KEY        0x00000004
14263 +#define CKO_HW_FEATURE        0x00000005
14264 +#define CKO_DOMAIN_PARAMETERS 0x00000006
14265 +#define CKO_MECHANISM         0x00000007
14267 +/* CKO_OTP_KEY is new for PKCS #11 v2.20 amendment 1 */
14268 +#define CKO_OTP_KEY           0x00000008
14270 +#define CKO_VENDOR_DEFINED    0x80000000
14272 +typedef CK_OBJECT_CLASS CK_PTR CK_OBJECT_CLASS_PTR;
14274 +/* CK_HW_FEATURE_TYPE is new for v2.10. CK_HW_FEATURE_TYPE is a
14275 + * value that identifies the hardware feature type of an object
14276 + * with CK_OBJECT_CLASS equal to CKO_HW_FEATURE. */
14277 +typedef CK_ULONG          CK_HW_FEATURE_TYPE;
14279 +/* The following hardware feature types are defined */
14280 +/* CKH_USER_INTERFACE is new for v2.20 */
14281 +#define CKH_MONOTONIC_COUNTER  0x00000001
14282 +#define CKH_CLOCK           0x00000002
14283 +#define CKH_USER_INTERFACE  0x00000003
14284 +#define CKH_VENDOR_DEFINED  0x80000000
14286 +/* CK_KEY_TYPE is a value that identifies a key type */
14287 +/* CK_KEY_TYPE was changed from CK_USHORT to CK_ULONG for v2.0 */
14288 +typedef CK_ULONG          CK_KEY_TYPE;
14290 +/* the following key types are defined: */
14291 +#define CKK_RSA             0x00000000
14292 +#define CKK_DSA             0x00000001
14293 +#define CKK_DH              0x00000002
14295 +/* CKK_ECDSA and CKK_KEA are new for v2.0 */
14296 +/* CKK_ECDSA is deprecated in v2.11, CKK_EC is preferred. */
14297 +#define CKK_ECDSA           0x00000003
14298 +#define CKK_EC              0x00000003
14299 +#define CKK_X9_42_DH        0x00000004
14300 +#define CKK_KEA             0x00000005
14302 +#define CKK_GENERIC_SECRET  0x00000010
14303 +#define CKK_RC2             0x00000011
14304 +#define CKK_RC4             0x00000012
14305 +#define CKK_DES             0x00000013
14306 +#define CKK_DES2            0x00000014
14307 +#define CKK_DES3            0x00000015
14309 +/* all these key types are new for v2.0 */
14310 +#define CKK_CAST            0x00000016
14311 +#define CKK_CAST3           0x00000017
14312 +/* CKK_CAST5 is deprecated in v2.11, CKK_CAST128 is preferred. */
14313 +#define CKK_CAST5           0x00000018
14314 +#define CKK_CAST128         0x00000018
14315 +#define CKK_RC5             0x00000019
14316 +#define CKK_IDEA            0x0000001A
14317 +#define CKK_SKIPJACK        0x0000001B
14318 +#define CKK_BATON           0x0000001C
14319 +#define CKK_JUNIPER         0x0000001D
14320 +#define CKK_CDMF            0x0000001E
14321 +#define CKK_AES             0x0000001F
14323 +/* BlowFish and TwoFish are new for v2.20 */
14324 +#define CKK_BLOWFISH        0x00000020
14325 +#define CKK_TWOFISH         0x00000021
14327 +/* SecurID, HOTP, and ACTI are new for PKCS #11 v2.20 amendment 1 */
14328 +#define CKK_SECURID         0x00000022
14329 +#define CKK_HOTP            0x00000023
14330 +#define CKK_ACTI            0x00000024
14332 +/* Camellia is new for PKCS #11 v2.20 amendment 3 */
14333 +#define CKK_CAMELLIA                   0x00000025
14334 +/* ARIA is new for PKCS #11 v2.20 amendment 3 */
14335 +#define CKK_ARIA                       0x00000026
14338 +#define CKK_VENDOR_DEFINED  0x80000000
14341 +/* CK_CERTIFICATE_TYPE is a value that identifies a certificate
14342 + * type */
14343 +/* CK_CERTIFICATE_TYPE was changed from CK_USHORT to CK_ULONG
14344 + * for v2.0 */
14345 +typedef CK_ULONG          CK_CERTIFICATE_TYPE;
14347 +/* The following certificate types are defined: */
14348 +/* CKC_X_509_ATTR_CERT is new for v2.10 */
14349 +/* CKC_WTLS is new for v2.20 */
14350 +#define CKC_X_509           0x00000000
14351 +#define CKC_X_509_ATTR_CERT 0x00000001
14352 +#define CKC_WTLS            0x00000002
14353 +#define CKC_VENDOR_DEFINED  0x80000000
14356 +/* CK_ATTRIBUTE_TYPE is a value that identifies an attribute
14357 + * type */
14358 +/* CK_ATTRIBUTE_TYPE was changed from CK_USHORT to CK_ULONG for
14359 + * v2.0 */
14360 +typedef CK_ULONG          CK_ATTRIBUTE_TYPE;
14362 +/* The CKF_ARRAY_ATTRIBUTE flag identifies an attribute which
14363 +   consists of an array of values. */
14364 +#define CKF_ARRAY_ATTRIBUTE    0x40000000
14366 +/* The following OTP-related defines are new for PKCS #11 v2.20 amendment 1
14367 +   and relates to the CKA_OTP_FORMAT attribute */
14368 +#define CK_OTP_FORMAT_DECIMAL      0
14369 +#define CK_OTP_FORMAT_HEXADECIMAL  1
14370 +#define CK_OTP_FORMAT_ALPHANUMERIC 2
14371 +#define CK_OTP_FORMAT_BINARY       3
14373 +/* The following OTP-related defines are new for PKCS #11 v2.20 amendment 1
14374 +   and relates to the CKA_OTP_..._REQUIREMENT attributes */
14375 +#define CK_OTP_PARAM_IGNORED       0
14376 +#define CK_OTP_PARAM_OPTIONAL      1
14377 +#define CK_OTP_PARAM_MANDATORY     2
14379 +/* The following attribute types are defined: */
14380 +#define CKA_CLASS              0x00000000
14381 +#define CKA_TOKEN              0x00000001
14382 +#define CKA_PRIVATE            0x00000002
14383 +#define CKA_LABEL              0x00000003
14384 +#define CKA_APPLICATION        0x00000010
14385 +#define CKA_VALUE              0x00000011
14387 +/* CKA_OBJECT_ID is new for v2.10 */
14388 +#define CKA_OBJECT_ID          0x00000012
14390 +#define CKA_CERTIFICATE_TYPE   0x00000080
14391 +#define CKA_ISSUER             0x00000081
14392 +#define CKA_SERIAL_NUMBER      0x00000082
14394 +/* CKA_AC_ISSUER, CKA_OWNER, and CKA_ATTR_TYPES are new
14395 + * for v2.10 */
14396 +#define CKA_AC_ISSUER          0x00000083
14397 +#define CKA_OWNER              0x00000084
14398 +#define CKA_ATTR_TYPES         0x00000085
14400 +/* CKA_TRUSTED is new for v2.11 */
14401 +#define CKA_TRUSTED            0x00000086
14403 +/* CKA_CERTIFICATE_CATEGORY ...
14404 + * CKA_CHECK_VALUE are new for v2.20 */
14405 +#define CKA_CERTIFICATE_CATEGORY        0x00000087
14406 +#define CKA_JAVA_MIDP_SECURITY_DOMAIN   0x00000088
14407 +#define CKA_URL                         0x00000089
14408 +#define CKA_HASH_OF_SUBJECT_PUBLIC_KEY  0x0000008A
14409 +#define CKA_HASH_OF_ISSUER_PUBLIC_KEY   0x0000008B
14410 +#define CKA_CHECK_VALUE                 0x00000090
14412 +#define CKA_KEY_TYPE           0x00000100
14413 +#define CKA_SUBJECT            0x00000101
14414 +#define CKA_ID                 0x00000102
14415 +#define CKA_SENSITIVE          0x00000103
14416 +#define CKA_ENCRYPT            0x00000104
14417 +#define CKA_DECRYPT            0x00000105
14418 +#define CKA_WRAP               0x00000106
14419 +#define CKA_UNWRAP             0x00000107
14420 +#define CKA_SIGN               0x00000108
14421 +#define CKA_SIGN_RECOVER       0x00000109
14422 +#define CKA_VERIFY             0x0000010A
14423 +#define CKA_VERIFY_RECOVER     0x0000010B
14424 +#define CKA_DERIVE             0x0000010C
14425 +#define CKA_START_DATE         0x00000110
14426 +#define CKA_END_DATE           0x00000111
14427 +#define CKA_MODULUS            0x00000120
14428 +#define CKA_MODULUS_BITS       0x00000121
14429 +#define CKA_PUBLIC_EXPONENT    0x00000122
14430 +#define CKA_PRIVATE_EXPONENT   0x00000123
14431 +#define CKA_PRIME_1            0x00000124
14432 +#define CKA_PRIME_2            0x00000125
14433 +#define CKA_EXPONENT_1         0x00000126
14434 +#define CKA_EXPONENT_2         0x00000127
14435 +#define CKA_COEFFICIENT        0x00000128
14436 +#define CKA_PRIME              0x00000130
14437 +#define CKA_SUBPRIME           0x00000131
14438 +#define CKA_BASE               0x00000132
14440 +/* CKA_PRIME_BITS and CKA_SUB_PRIME_BITS are new for v2.11 */
14441 +#define CKA_PRIME_BITS         0x00000133
14442 +#define CKA_SUBPRIME_BITS      0x00000134
14443 +#define CKA_SUB_PRIME_BITS     CKA_SUBPRIME_BITS
14444 +/* (To retain backwards-compatibility) */
14446 +#define CKA_VALUE_BITS         0x00000160
14447 +#define CKA_VALUE_LEN          0x00000161
14449 +/* CKA_EXTRACTABLE, CKA_LOCAL, CKA_NEVER_EXTRACTABLE,
14450 + * CKA_ALWAYS_SENSITIVE, CKA_MODIFIABLE, CKA_ECDSA_PARAMS,
14451 + * and CKA_EC_POINT are new for v2.0 */
14452 +#define CKA_EXTRACTABLE        0x00000162
14453 +#define CKA_LOCAL              0x00000163
14454 +#define CKA_NEVER_EXTRACTABLE  0x00000164
14455 +#define CKA_ALWAYS_SENSITIVE   0x00000165
14457 +/* CKA_KEY_GEN_MECHANISM is new for v2.11 */
14458 +#define CKA_KEY_GEN_MECHANISM  0x00000166
14460 +#define CKA_MODIFIABLE         0x00000170
14462 +/* CKA_ECDSA_PARAMS is deprecated in v2.11,
14463 + * CKA_EC_PARAMS is preferred. */
14464 +#define CKA_ECDSA_PARAMS       0x00000180
14465 +#define CKA_EC_PARAMS          0x00000180
14467 +#define CKA_EC_POINT           0x00000181
14469 +/* CKA_SECONDARY_AUTH, CKA_AUTH_PIN_FLAGS,
14470 + * are new for v2.10. Deprecated in v2.11 and onwards. */
14471 +#define CKA_SECONDARY_AUTH     0x00000200
14472 +#define CKA_AUTH_PIN_FLAGS     0x00000201
14474 +/* CKA_ALWAYS_AUTHENTICATE ...
14475 + * CKA_UNWRAP_TEMPLATE are new for v2.20 */
14476 +#define CKA_ALWAYS_AUTHENTICATE  0x00000202
14478 +#define CKA_WRAP_WITH_TRUSTED    0x00000210
14479 +#define CKA_WRAP_TEMPLATE        (CKF_ARRAY_ATTRIBUTE|0x00000211)
14480 +#define CKA_UNWRAP_TEMPLATE      (CKF_ARRAY_ATTRIBUTE|0x00000212)
14482 +/* CKA_OTP... atttributes are new for PKCS #11 v2.20 amendment 3. */
14483 +#define CKA_OTP_FORMAT                0x00000220
14484 +#define CKA_OTP_LENGTH                0x00000221
14485 +#define CKA_OTP_TIME_INTERVAL         0x00000222
14486 +#define CKA_OTP_USER_FRIENDLY_MODE    0x00000223
14487 +#define CKA_OTP_CHALLENGE_REQUIREMENT 0x00000224
14488 +#define CKA_OTP_TIME_REQUIREMENT      0x00000225
14489 +#define CKA_OTP_COUNTER_REQUIREMENT   0x00000226
14490 +#define CKA_OTP_PIN_REQUIREMENT       0x00000227
14491 +#define CKA_OTP_COUNTER               0x0000022E
14492 +#define CKA_OTP_TIME                  0x0000022F
14493 +#define CKA_OTP_USER_IDENTIFIER       0x0000022A
14494 +#define CKA_OTP_SERVICE_IDENTIFIER    0x0000022B
14495 +#define CKA_OTP_SERVICE_LOGO          0x0000022C
14496 +#define CKA_OTP_SERVICE_LOGO_TYPE     0x0000022D
14499 +/* CKA_HW_FEATURE_TYPE, CKA_RESET_ON_INIT, and CKA_HAS_RESET
14500 + * are new for v2.10 */
14501 +#define CKA_HW_FEATURE_TYPE    0x00000300
14502 +#define CKA_RESET_ON_INIT      0x00000301
14503 +#define CKA_HAS_RESET          0x00000302
14505 +/* The following attributes are new for v2.20 */
14506 +#define CKA_PIXEL_X                     0x00000400
14507 +#define CKA_PIXEL_Y                     0x00000401
14508 +#define CKA_RESOLUTION                  0x00000402
14509 +#define CKA_CHAR_ROWS                   0x00000403
14510 +#define CKA_CHAR_COLUMNS                0x00000404
14511 +#define CKA_COLOR                       0x00000405
14512 +#define CKA_BITS_PER_PIXEL              0x00000406
14513 +#define CKA_CHAR_SETS                   0x00000480
14514 +#define CKA_ENCODING_METHODS            0x00000481
14515 +#define CKA_MIME_TYPES                  0x00000482
14516 +#define CKA_MECHANISM_TYPE              0x00000500
14517 +#define CKA_REQUIRED_CMS_ATTRIBUTES     0x00000501
14518 +#define CKA_DEFAULT_CMS_ATTRIBUTES      0x00000502
14519 +#define CKA_SUPPORTED_CMS_ATTRIBUTES    0x00000503
14520 +#define CKA_ALLOWED_MECHANISMS          (CKF_ARRAY_ATTRIBUTE|0x00000600)
14522 +#define CKA_VENDOR_DEFINED     0x80000000
14524 +/* CK_ATTRIBUTE is a structure that includes the type, length
14525 + * and value of an attribute */
14526 +typedef struct CK_ATTRIBUTE {
14527 +  CK_ATTRIBUTE_TYPE type;
14528 +  CK_VOID_PTR       pValue;
14530 +  /* ulValueLen went from CK_USHORT to CK_ULONG for v2.0 */
14531 +  CK_ULONG          ulValueLen;  /* in bytes */
14532 +} CK_ATTRIBUTE;
14534 +typedef CK_ATTRIBUTE CK_PTR CK_ATTRIBUTE_PTR;
14537 +/* CK_DATE is a structure that defines a date */
14538 +typedef struct CK_DATE{
14539 +  CK_CHAR       year[4];   /* the year ("1900" - "9999") */
14540 +  CK_CHAR       month[2];  /* the month ("01" - "12") */
14541 +  CK_CHAR       day[2];    /* the day   ("01" - "31") */
14542 +} CK_DATE;
14545 +/* CK_MECHANISM_TYPE is a value that identifies a mechanism
14546 + * type */
14547 +/* CK_MECHANISM_TYPE was changed from CK_USHORT to CK_ULONG for
14548 + * v2.0 */
14549 +typedef CK_ULONG          CK_MECHANISM_TYPE;
14551 +/* the following mechanism types are defined: */
14552 +#define CKM_RSA_PKCS_KEY_PAIR_GEN      0x00000000
14553 +#define CKM_RSA_PKCS                   0x00000001
14554 +#define CKM_RSA_9796                   0x00000002
14555 +#define CKM_RSA_X_509                  0x00000003
14557 +/* CKM_MD2_RSA_PKCS, CKM_MD5_RSA_PKCS, and CKM_SHA1_RSA_PKCS
14558 + * are new for v2.0.  They are mechanisms which hash and sign */
14559 +#define CKM_MD2_RSA_PKCS               0x00000004
14560 +#define CKM_MD5_RSA_PKCS               0x00000005
14561 +#define CKM_SHA1_RSA_PKCS              0x00000006
14563 +/* CKM_RIPEMD128_RSA_PKCS, CKM_RIPEMD160_RSA_PKCS, and
14564 + * CKM_RSA_PKCS_OAEP are new for v2.10 */
14565 +#define CKM_RIPEMD128_RSA_PKCS         0x00000007
14566 +#define CKM_RIPEMD160_RSA_PKCS         0x00000008
14567 +#define CKM_RSA_PKCS_OAEP              0x00000009
14569 +/* CKM_RSA_X9_31_KEY_PAIR_GEN, CKM_RSA_X9_31, CKM_SHA1_RSA_X9_31,
14570 + * CKM_RSA_PKCS_PSS, and CKM_SHA1_RSA_PKCS_PSS are new for v2.11 */
14571 +#define CKM_RSA_X9_31_KEY_PAIR_GEN     0x0000000A
14572 +#define CKM_RSA_X9_31                  0x0000000B
14573 +#define CKM_SHA1_RSA_X9_31             0x0000000C
14574 +#define CKM_RSA_PKCS_PSS               0x0000000D
14575 +#define CKM_SHA1_RSA_PKCS_PSS          0x0000000E
14577 +#define CKM_DSA_KEY_PAIR_GEN           0x00000010
14578 +#define CKM_DSA                        0x00000011
14579 +#define CKM_DSA_SHA1                   0x00000012
14580 +#define CKM_DH_PKCS_KEY_PAIR_GEN       0x00000020
14581 +#define CKM_DH_PKCS_DERIVE             0x00000021
14583 +/* CKM_X9_42_DH_KEY_PAIR_GEN, CKM_X9_42_DH_DERIVE,
14584 + * CKM_X9_42_DH_HYBRID_DERIVE, and CKM_X9_42_MQV_DERIVE are new for
14585 + * v2.11 */
14586 +#define CKM_X9_42_DH_KEY_PAIR_GEN      0x00000030
14587 +#define CKM_X9_42_DH_DERIVE            0x00000031
14588 +#define CKM_X9_42_DH_HYBRID_DERIVE     0x00000032
14589 +#define CKM_X9_42_MQV_DERIVE           0x00000033
14591 +/* CKM_SHA256/384/512 are new for v2.20 */
14592 +#define CKM_SHA256_RSA_PKCS            0x00000040
14593 +#define CKM_SHA384_RSA_PKCS            0x00000041
14594 +#define CKM_SHA512_RSA_PKCS            0x00000042
14595 +#define CKM_SHA256_RSA_PKCS_PSS        0x00000043
14596 +#define CKM_SHA384_RSA_PKCS_PSS        0x00000044
14597 +#define CKM_SHA512_RSA_PKCS_PSS        0x00000045
14599 +/* SHA-224 RSA mechanisms are new for PKCS #11 v2.20 amendment 3 */
14600 +#define CKM_SHA224_RSA_PKCS            0x00000046
14601 +#define CKM_SHA224_RSA_PKCS_PSS        0x00000047
14603 +#define CKM_RC2_KEY_GEN                0x00000100
14604 +#define CKM_RC2_ECB                    0x00000101
14605 +#define CKM_RC2_CBC                    0x00000102
14606 +#define CKM_RC2_MAC                    0x00000103
14608 +/* CKM_RC2_MAC_GENERAL and CKM_RC2_CBC_PAD are new for v2.0 */
14609 +#define CKM_RC2_MAC_GENERAL            0x00000104
14610 +#define CKM_RC2_CBC_PAD                0x00000105
14612 +#define CKM_RC4_KEY_GEN                0x00000110
14613 +#define CKM_RC4                        0x00000111
14614 +#define CKM_DES_KEY_GEN                0x00000120
14615 +#define CKM_DES_ECB                    0x00000121
14616 +#define CKM_DES_CBC                    0x00000122
14617 +#define CKM_DES_MAC                    0x00000123
14619 +/* CKM_DES_MAC_GENERAL and CKM_DES_CBC_PAD are new for v2.0 */
14620 +#define CKM_DES_MAC_GENERAL            0x00000124
14621 +#define CKM_DES_CBC_PAD                0x00000125
14623 +#define CKM_DES2_KEY_GEN               0x00000130
14624 +#define CKM_DES3_KEY_GEN               0x00000131
14625 +#define CKM_DES3_ECB                   0x00000132
14626 +#define CKM_DES3_CBC                   0x00000133
14627 +#define CKM_DES3_MAC                   0x00000134
14629 +/* CKM_DES3_MAC_GENERAL, CKM_DES3_CBC_PAD, CKM_CDMF_KEY_GEN,
14630 + * CKM_CDMF_ECB, CKM_CDMF_CBC, CKM_CDMF_MAC,
14631 + * CKM_CDMF_MAC_GENERAL, and CKM_CDMF_CBC_PAD are new for v2.0 */
14632 +#define CKM_DES3_MAC_GENERAL           0x00000135
14633 +#define CKM_DES3_CBC_PAD               0x00000136
14634 +#define CKM_CDMF_KEY_GEN               0x00000140
14635 +#define CKM_CDMF_ECB                   0x00000141
14636 +#define CKM_CDMF_CBC                   0x00000142
14637 +#define CKM_CDMF_MAC                   0x00000143
14638 +#define CKM_CDMF_MAC_GENERAL           0x00000144
14639 +#define CKM_CDMF_CBC_PAD               0x00000145
14641 +/* the following four DES mechanisms are new for v2.20 */
14642 +#define CKM_DES_OFB64                  0x00000150
14643 +#define CKM_DES_OFB8                   0x00000151
14644 +#define CKM_DES_CFB64                  0x00000152
14645 +#define CKM_DES_CFB8                   0x00000153
14647 +#define CKM_MD2                        0x00000200
14649 +/* CKM_MD2_HMAC and CKM_MD2_HMAC_GENERAL are new for v2.0 */
14650 +#define CKM_MD2_HMAC                   0x00000201
14651 +#define CKM_MD2_HMAC_GENERAL           0x00000202
14653 +#define CKM_MD5                        0x00000210
14655 +/* CKM_MD5_HMAC and CKM_MD5_HMAC_GENERAL are new for v2.0 */
14656 +#define CKM_MD5_HMAC                   0x00000211
14657 +#define CKM_MD5_HMAC_GENERAL           0x00000212
14659 +#define CKM_SHA_1                      0x00000220
14661 +/* CKM_SHA_1_HMAC and CKM_SHA_1_HMAC_GENERAL are new for v2.0 */
14662 +#define CKM_SHA_1_HMAC                 0x00000221
14663 +#define CKM_SHA_1_HMAC_GENERAL         0x00000222
14665 +/* CKM_RIPEMD128, CKM_RIPEMD128_HMAC,
14666 + * CKM_RIPEMD128_HMAC_GENERAL, CKM_RIPEMD160, CKM_RIPEMD160_HMAC,
14667 + * and CKM_RIPEMD160_HMAC_GENERAL are new for v2.10 */
14668 +#define CKM_RIPEMD128                  0x00000230
14669 +#define CKM_RIPEMD128_HMAC             0x00000231
14670 +#define CKM_RIPEMD128_HMAC_GENERAL     0x00000232
14671 +#define CKM_RIPEMD160                  0x00000240
14672 +#define CKM_RIPEMD160_HMAC             0x00000241
14673 +#define CKM_RIPEMD160_HMAC_GENERAL     0x00000242
14675 +/* CKM_SHA256/384/512 are new for v2.20 */
14676 +#define CKM_SHA256                     0x00000250
14677 +#define CKM_SHA256_HMAC                0x00000251
14678 +#define CKM_SHA256_HMAC_GENERAL        0x00000252
14680 +/* SHA-224 is new for PKCS #11 v2.20 amendment 3 */
14681 +#define CKM_SHA224                     0x00000255
14682 +#define CKM_SHA224_HMAC                0x00000256
14683 +#define CKM_SHA224_HMAC_GENERAL        0x00000257
14685 +#define CKM_SHA384                     0x00000260
14686 +#define CKM_SHA384_HMAC                0x00000261
14687 +#define CKM_SHA384_HMAC_GENERAL        0x00000262
14688 +#define CKM_SHA512                     0x00000270
14689 +#define CKM_SHA512_HMAC                0x00000271
14690 +#define CKM_SHA512_HMAC_GENERAL        0x00000272
14692 +/* SecurID is new for PKCS #11 v2.20 amendment 1 */
14693 +#define CKM_SECURID_KEY_GEN            0x00000280
14694 +#define CKM_SECURID                    0x00000282
14696 +/* HOTP is new for PKCS #11 v2.20 amendment 1 */
14697 +#define CKM_HOTP_KEY_GEN    0x00000290
14698 +#define CKM_HOTP            0x00000291
14700 +/* ACTI is new for PKCS #11 v2.20 amendment 1 */
14701 +#define CKM_ACTI            0x000002A0
14702 +#define CKM_ACTI_KEY_GEN    0x000002A1
14704 +/* All of the following mechanisms are new for v2.0 */
14705 +/* Note that CAST128 and CAST5 are the same algorithm */
14706 +#define CKM_CAST_KEY_GEN               0x00000300
14707 +#define CKM_CAST_ECB                   0x00000301
14708 +#define CKM_CAST_CBC                   0x00000302
14709 +#define CKM_CAST_MAC                   0x00000303
14710 +#define CKM_CAST_MAC_GENERAL           0x00000304
14711 +#define CKM_CAST_CBC_PAD               0x00000305
14712 +#define CKM_CAST3_KEY_GEN              0x00000310
14713 +#define CKM_CAST3_ECB                  0x00000311
14714 +#define CKM_CAST3_CBC                  0x00000312
14715 +#define CKM_CAST3_MAC                  0x00000313
14716 +#define CKM_CAST3_MAC_GENERAL          0x00000314
14717 +#define CKM_CAST3_CBC_PAD              0x00000315
14718 +#define CKM_CAST5_KEY_GEN              0x00000320
14719 +#define CKM_CAST128_KEY_GEN            0x00000320
14720 +#define CKM_CAST5_ECB                  0x00000321
14721 +#define CKM_CAST128_ECB                0x00000321
14722 +#define CKM_CAST5_CBC                  0x00000322
14723 +#define CKM_CAST128_CBC                0x00000322
14724 +#define CKM_CAST5_MAC                  0x00000323
14725 +#define CKM_CAST128_MAC                0x00000323
14726 +#define CKM_CAST5_MAC_GENERAL          0x00000324
14727 +#define CKM_CAST128_MAC_GENERAL        0x00000324
14728 +#define CKM_CAST5_CBC_PAD              0x00000325
14729 +#define CKM_CAST128_CBC_PAD            0x00000325
14730 +#define CKM_RC5_KEY_GEN                0x00000330
14731 +#define CKM_RC5_ECB                    0x00000331
14732 +#define CKM_RC5_CBC                    0x00000332
14733 +#define CKM_RC5_MAC                    0x00000333
14734 +#define CKM_RC5_MAC_GENERAL            0x00000334
14735 +#define CKM_RC5_CBC_PAD                0x00000335
14736 +#define CKM_IDEA_KEY_GEN               0x00000340
14737 +#define CKM_IDEA_ECB                   0x00000341
14738 +#define CKM_IDEA_CBC                   0x00000342
14739 +#define CKM_IDEA_MAC                   0x00000343
14740 +#define CKM_IDEA_MAC_GENERAL           0x00000344
14741 +#define CKM_IDEA_CBC_PAD               0x00000345
14742 +#define CKM_GENERIC_SECRET_KEY_GEN     0x00000350
14743 +#define CKM_CONCATENATE_BASE_AND_KEY   0x00000360
14744 +#define CKM_CONCATENATE_BASE_AND_DATA  0x00000362
14745 +#define CKM_CONCATENATE_DATA_AND_BASE  0x00000363
14746 +#define CKM_XOR_BASE_AND_DATA          0x00000364
14747 +#define CKM_EXTRACT_KEY_FROM_KEY       0x00000365
14748 +#define CKM_SSL3_PRE_MASTER_KEY_GEN    0x00000370
14749 +#define CKM_SSL3_MASTER_KEY_DERIVE     0x00000371
14750 +#define CKM_SSL3_KEY_AND_MAC_DERIVE    0x00000372
14752 +/* CKM_SSL3_MASTER_KEY_DERIVE_DH, CKM_TLS_PRE_MASTER_KEY_GEN,
14753 + * CKM_TLS_MASTER_KEY_DERIVE, CKM_TLS_KEY_AND_MAC_DERIVE, and
14754 + * CKM_TLS_MASTER_KEY_DERIVE_DH are new for v2.11 */
14755 +#define CKM_SSL3_MASTER_KEY_DERIVE_DH  0x00000373
14756 +#define CKM_TLS_PRE_MASTER_KEY_GEN     0x00000374
14757 +#define CKM_TLS_MASTER_KEY_DERIVE      0x00000375
14758 +#define CKM_TLS_KEY_AND_MAC_DERIVE     0x00000376
14759 +#define CKM_TLS_MASTER_KEY_DERIVE_DH   0x00000377
14761 +/* CKM_TLS_PRF is new for v2.20 */
14762 +#define CKM_TLS_PRF                    0x00000378
14764 +#define CKM_SSL3_MD5_MAC               0x00000380
14765 +#define CKM_SSL3_SHA1_MAC              0x00000381
14766 +#define CKM_MD5_KEY_DERIVATION         0x00000390
14767 +#define CKM_MD2_KEY_DERIVATION         0x00000391
14768 +#define CKM_SHA1_KEY_DERIVATION        0x00000392
14770 +/* CKM_SHA256/384/512 are new for v2.20 */
14771 +#define CKM_SHA256_KEY_DERIVATION      0x00000393
14772 +#define CKM_SHA384_KEY_DERIVATION      0x00000394
14773 +#define CKM_SHA512_KEY_DERIVATION      0x00000395
14775 +/* SHA-224 key derivation is new for PKCS #11 v2.20 amendment 3 */
14776 +#define CKM_SHA224_KEY_DERIVATION      0x00000396
14778 +#define CKM_PBE_MD2_DES_CBC            0x000003A0
14779 +#define CKM_PBE_MD5_DES_CBC            0x000003A1
14780 +#define CKM_PBE_MD5_CAST_CBC           0x000003A2
14781 +#define CKM_PBE_MD5_CAST3_CBC          0x000003A3
14782 +#define CKM_PBE_MD5_CAST5_CBC          0x000003A4
14783 +#define CKM_PBE_MD5_CAST128_CBC        0x000003A4
14784 +#define CKM_PBE_SHA1_CAST5_CBC         0x000003A5
14785 +#define CKM_PBE_SHA1_CAST128_CBC       0x000003A5
14786 +#define CKM_PBE_SHA1_RC4_128           0x000003A6
14787 +#define CKM_PBE_SHA1_RC4_40            0x000003A7
14788 +#define CKM_PBE_SHA1_DES3_EDE_CBC      0x000003A8
14789 +#define CKM_PBE_SHA1_DES2_EDE_CBC      0x000003A9
14790 +#define CKM_PBE_SHA1_RC2_128_CBC       0x000003AA
14791 +#define CKM_PBE_SHA1_RC2_40_CBC        0x000003AB
14793 +/* CKM_PKCS5_PBKD2 is new for v2.10 */
14794 +#define CKM_PKCS5_PBKD2                0x000003B0
14796 +#define CKM_PBA_SHA1_WITH_SHA1_HMAC    0x000003C0
14798 +/* WTLS mechanisms are new for v2.20 */
14799 +#define CKM_WTLS_PRE_MASTER_KEY_GEN         0x000003D0
14800 +#define CKM_WTLS_MASTER_KEY_DERIVE          0x000003D1
14801 +#define CKM_WTLS_MASTER_KEY_DERIVE_DH_ECC   0x000003D2
14802 +#define CKM_WTLS_PRF                        0x000003D3
14803 +#define CKM_WTLS_SERVER_KEY_AND_MAC_DERIVE  0x000003D4
14804 +#define CKM_WTLS_CLIENT_KEY_AND_MAC_DERIVE  0x000003D5
14806 +#define CKM_KEY_WRAP_LYNKS             0x00000400
14807 +#define CKM_KEY_WRAP_SET_OAEP          0x00000401
14809 +/* CKM_CMS_SIG is new for v2.20 */
14810 +#define CKM_CMS_SIG                    0x00000500
14812 +/* CKM_KIP mechanisms are new for PKCS #11 v2.20 amendment 2 */
14813 +#define CKM_KIP_DERIVE                 0x00000510
14814 +#define CKM_KIP_WRAP                   0x00000511
14815 +#define CKM_KIP_MAC                    0x00000512
14817 +/* Camellia is new for PKCS #11 v2.20 amendment 3 */
14818 +#define CKM_CAMELLIA_KEY_GEN           0x00000550
14819 +#define CKM_CAMELLIA_ECB               0x00000551
14820 +#define CKM_CAMELLIA_CBC               0x00000552
14821 +#define CKM_CAMELLIA_MAC               0x00000553
14822 +#define CKM_CAMELLIA_MAC_GENERAL       0x00000554
14823 +#define CKM_CAMELLIA_CBC_PAD           0x00000555
14824 +#define CKM_CAMELLIA_ECB_ENCRYPT_DATA  0x00000556
14825 +#define CKM_CAMELLIA_CBC_ENCRYPT_DATA  0x00000557
14826 +#define CKM_CAMELLIA_CTR               0x00000558
14828 +/* ARIA is new for PKCS #11 v2.20 amendment 3 */
14829 +#define CKM_ARIA_KEY_GEN               0x00000560
14830 +#define CKM_ARIA_ECB                   0x00000561
14831 +#define CKM_ARIA_CBC                   0x00000562
14832 +#define CKM_ARIA_MAC                   0x00000563
14833 +#define CKM_ARIA_MAC_GENERAL           0x00000564
14834 +#define CKM_ARIA_CBC_PAD               0x00000565
14835 +#define CKM_ARIA_ECB_ENCRYPT_DATA      0x00000566
14836 +#define CKM_ARIA_CBC_ENCRYPT_DATA      0x00000567
14838 +/* Fortezza mechanisms */
14839 +#define CKM_SKIPJACK_KEY_GEN           0x00001000
14840 +#define CKM_SKIPJACK_ECB64             0x00001001
14841 +#define CKM_SKIPJACK_CBC64             0x00001002
14842 +#define CKM_SKIPJACK_OFB64             0x00001003
14843 +#define CKM_SKIPJACK_CFB64             0x00001004
14844 +#define CKM_SKIPJACK_CFB32             0x00001005
14845 +#define CKM_SKIPJACK_CFB16             0x00001006
14846 +#define CKM_SKIPJACK_CFB8              0x00001007
14847 +#define CKM_SKIPJACK_WRAP              0x00001008
14848 +#define CKM_SKIPJACK_PRIVATE_WRAP      0x00001009
14849 +#define CKM_SKIPJACK_RELAYX            0x0000100a
14850 +#define CKM_KEA_KEY_PAIR_GEN           0x00001010
14851 +#define CKM_KEA_KEY_DERIVE             0x00001011
14852 +#define CKM_FORTEZZA_TIMESTAMP         0x00001020
14853 +#define CKM_BATON_KEY_GEN              0x00001030
14854 +#define CKM_BATON_ECB128               0x00001031
14855 +#define CKM_BATON_ECB96                0x00001032
14856 +#define CKM_BATON_CBC128               0x00001033
14857 +#define CKM_BATON_COUNTER              0x00001034
14858 +#define CKM_BATON_SHUFFLE              0x00001035
14859 +#define CKM_BATON_WRAP                 0x00001036
14861 +/* CKM_ECDSA_KEY_PAIR_GEN is deprecated in v2.11,
14862 + * CKM_EC_KEY_PAIR_GEN is preferred */
14863 +#define CKM_ECDSA_KEY_PAIR_GEN         0x00001040
14864 +#define CKM_EC_KEY_PAIR_GEN            0x00001040
14866 +#define CKM_ECDSA                      0x00001041
14867 +#define CKM_ECDSA_SHA1                 0x00001042
14869 +/* CKM_ECDH1_DERIVE, CKM_ECDH1_COFACTOR_DERIVE, and CKM_ECMQV_DERIVE
14870 + * are new for v2.11 */
14871 +#define CKM_ECDH1_DERIVE               0x00001050
14872 +#define CKM_ECDH1_COFACTOR_DERIVE      0x00001051
14873 +#define CKM_ECMQV_DERIVE               0x00001052
14875 +#define CKM_JUNIPER_KEY_GEN            0x00001060
14876 +#define CKM_JUNIPER_ECB128             0x00001061
14877 +#define CKM_JUNIPER_CBC128             0x00001062
14878 +#define CKM_JUNIPER_COUNTER            0x00001063
14879 +#define CKM_JUNIPER_SHUFFLE            0x00001064
14880 +#define CKM_JUNIPER_WRAP               0x00001065
14881 +#define CKM_FASTHASH                   0x00001070
14883 +/* CKM_AES_KEY_GEN, CKM_AES_ECB, CKM_AES_CBC, CKM_AES_MAC,
14884 + * CKM_AES_MAC_GENERAL, CKM_AES_CBC_PAD, CKM_DSA_PARAMETER_GEN,
14885 + * CKM_DH_PKCS_PARAMETER_GEN, and CKM_X9_42_DH_PARAMETER_GEN are
14886 + * new for v2.11 */
14887 +#define CKM_AES_KEY_GEN                0x00001080
14888 +#define CKM_AES_ECB                    0x00001081
14889 +#define CKM_AES_CBC                    0x00001082
14890 +#define CKM_AES_MAC                    0x00001083
14891 +#define CKM_AES_MAC_GENERAL            0x00001084
14892 +#define CKM_AES_CBC_PAD                0x00001085
14894 +/* AES counter mode is new for PKCS #11 v2.20 amendment 3 */
14895 +#define CKM_AES_CTR                    0x00001086
14897 +/* BlowFish and TwoFish are new for v2.20 */
14898 +#define CKM_BLOWFISH_KEY_GEN           0x00001090
14899 +#define CKM_BLOWFISH_CBC               0x00001091
14900 +#define CKM_TWOFISH_KEY_GEN            0x00001092
14901 +#define CKM_TWOFISH_CBC                0x00001093
14904 +/* CKM_xxx_ENCRYPT_DATA mechanisms are new for v2.20 */
14905 +#define CKM_DES_ECB_ENCRYPT_DATA       0x00001100
14906 +#define CKM_DES_CBC_ENCRYPT_DATA       0x00001101
14907 +#define CKM_DES3_ECB_ENCRYPT_DATA      0x00001102
14908 +#define CKM_DES3_CBC_ENCRYPT_DATA      0x00001103
14909 +#define CKM_AES_ECB_ENCRYPT_DATA       0x00001104
14910 +#define CKM_AES_CBC_ENCRYPT_DATA       0x00001105
14912 +#define CKM_DSA_PARAMETER_GEN          0x00002000
14913 +#define CKM_DH_PKCS_PARAMETER_GEN      0x00002001
14914 +#define CKM_X9_42_DH_PARAMETER_GEN     0x00002002
14916 +#define CKM_VENDOR_DEFINED             0x80000000
14918 +typedef CK_MECHANISM_TYPE CK_PTR CK_MECHANISM_TYPE_PTR;
14921 +/* CK_MECHANISM is a structure that specifies a particular
14922 + * mechanism  */
14923 +typedef struct CK_MECHANISM {
14924 +  CK_MECHANISM_TYPE mechanism;
14925 +  CK_VOID_PTR       pParameter;
14927 +  /* ulParameterLen was changed from CK_USHORT to CK_ULONG for
14928 +   * v2.0 */
14929 +  CK_ULONG          ulParameterLen;  /* in bytes */
14930 +} CK_MECHANISM;
14932 +typedef CK_MECHANISM CK_PTR CK_MECHANISM_PTR;
14935 +/* CK_MECHANISM_INFO provides information about a particular
14936 + * mechanism */
14937 +typedef struct CK_MECHANISM_INFO {
14938 +    CK_ULONG    ulMinKeySize;
14939 +    CK_ULONG    ulMaxKeySize;
14940 +    CK_FLAGS    flags;
14941 +} CK_MECHANISM_INFO;
14943 +/* The flags are defined as follows:
14944 + *      Bit Flag               Mask        Meaning */
14945 +#define CKF_HW                 0x00000001  /* performed by HW */
14947 +/* The flags CKF_ENCRYPT, CKF_DECRYPT, CKF_DIGEST, CKF_SIGN,
14948 + * CKG_SIGN_RECOVER, CKF_VERIFY, CKF_VERIFY_RECOVER,
14949 + * CKF_GENERATE, CKF_GENERATE_KEY_PAIR, CKF_WRAP, CKF_UNWRAP,
14950 + * and CKF_DERIVE are new for v2.0.  They specify whether or not
14951 + * a mechanism can be used for a particular task */
14952 +#define CKF_ENCRYPT            0x00000100
14953 +#define CKF_DECRYPT            0x00000200
14954 +#define CKF_DIGEST             0x00000400
14955 +#define CKF_SIGN               0x00000800
14956 +#define CKF_SIGN_RECOVER       0x00001000
14957 +#define CKF_VERIFY             0x00002000
14958 +#define CKF_VERIFY_RECOVER     0x00004000
14959 +#define CKF_GENERATE           0x00008000
14960 +#define CKF_GENERATE_KEY_PAIR  0x00010000
14961 +#define CKF_WRAP               0x00020000
14962 +#define CKF_UNWRAP             0x00040000
14963 +#define CKF_DERIVE             0x00080000
14965 +/* CKF_EC_F_P, CKF_EC_F_2M, CKF_EC_ECPARAMETERS, CKF_EC_NAMEDCURVE,
14966 + * CKF_EC_UNCOMPRESS, and CKF_EC_COMPRESS are new for v2.11. They
14967 + * describe a token's EC capabilities not available in mechanism
14968 + * information. */
14969 +#define CKF_EC_F_P             0x00100000
14970 +#define CKF_EC_F_2M            0x00200000
14971 +#define CKF_EC_ECPARAMETERS    0x00400000
14972 +#define CKF_EC_NAMEDCURVE      0x00800000
14973 +#define CKF_EC_UNCOMPRESS      0x01000000
14974 +#define CKF_EC_COMPRESS        0x02000000
14976 +#define CKF_EXTENSION          0x80000000 /* FALSE for this version */
14978 +typedef CK_MECHANISM_INFO CK_PTR CK_MECHANISM_INFO_PTR;
14981 +/* CK_RV is a value that identifies the return value of a
14982 + * Cryptoki function */
14983 +/* CK_RV was changed from CK_USHORT to CK_ULONG for v2.0 */
14984 +typedef CK_ULONG          CK_RV;
14986 +#define CKR_OK                                0x00000000
14987 +#define CKR_CANCEL                            0x00000001
14988 +#define CKR_HOST_MEMORY                       0x00000002
14989 +#define CKR_SLOT_ID_INVALID                   0x00000003
14991 +/* CKR_FLAGS_INVALID was removed for v2.0 */
14993 +/* CKR_GENERAL_ERROR and CKR_FUNCTION_FAILED are new for v2.0 */
14994 +#define CKR_GENERAL_ERROR                     0x00000005
14995 +#define CKR_FUNCTION_FAILED                   0x00000006
14997 +/* CKR_ARGUMENTS_BAD, CKR_NO_EVENT, CKR_NEED_TO_CREATE_THREADS,
14998 + * and CKR_CANT_LOCK are new for v2.01 */
14999 +#define CKR_ARGUMENTS_BAD                     0x00000007
15000 +#define CKR_NO_EVENT                          0x00000008
15001 +#define CKR_NEED_TO_CREATE_THREADS            0x00000009
15002 +#define CKR_CANT_LOCK                         0x0000000A
15004 +#define CKR_ATTRIBUTE_READ_ONLY               0x00000010
15005 +#define CKR_ATTRIBUTE_SENSITIVE               0x00000011
15006 +#define CKR_ATTRIBUTE_TYPE_INVALID            0x00000012
15007 +#define CKR_ATTRIBUTE_VALUE_INVALID           0x00000013
15008 +#define CKR_DATA_INVALID                      0x00000020
15009 +#define CKR_DATA_LEN_RANGE                    0x00000021
15010 +#define CKR_DEVICE_ERROR                      0x00000030
15011 +#define CKR_DEVICE_MEMORY                     0x00000031
15012 +#define CKR_DEVICE_REMOVED                    0x00000032
15013 +#define CKR_ENCRYPTED_DATA_INVALID            0x00000040
15014 +#define CKR_ENCRYPTED_DATA_LEN_RANGE          0x00000041
15015 +#define CKR_FUNCTION_CANCELED                 0x00000050
15016 +#define CKR_FUNCTION_NOT_PARALLEL             0x00000051
15018 +/* CKR_FUNCTION_NOT_SUPPORTED is new for v2.0 */
15019 +#define CKR_FUNCTION_NOT_SUPPORTED            0x00000054
15021 +#define CKR_KEY_HANDLE_INVALID                0x00000060
15023 +/* CKR_KEY_SENSITIVE was removed for v2.0 */
15025 +#define CKR_KEY_SIZE_RANGE                    0x00000062
15026 +#define CKR_KEY_TYPE_INCONSISTENT             0x00000063
15028 +/* CKR_KEY_NOT_NEEDED, CKR_KEY_CHANGED, CKR_KEY_NEEDED,
15029 + * CKR_KEY_INDIGESTIBLE, CKR_KEY_FUNCTION_NOT_PERMITTED,
15030 + * CKR_KEY_NOT_WRAPPABLE, and CKR_KEY_UNEXTRACTABLE are new for
15031 + * v2.0 */
15032 +#define CKR_KEY_NOT_NEEDED                    0x00000064
15033 +#define CKR_KEY_CHANGED                       0x00000065
15034 +#define CKR_KEY_NEEDED                        0x00000066
15035 +#define CKR_KEY_INDIGESTIBLE                  0x00000067
15036 +#define CKR_KEY_FUNCTION_NOT_PERMITTED        0x00000068
15037 +#define CKR_KEY_NOT_WRAPPABLE                 0x00000069
15038 +#define CKR_KEY_UNEXTRACTABLE                 0x0000006A
15040 +#define CKR_MECHANISM_INVALID                 0x00000070
15041 +#define CKR_MECHANISM_PARAM_INVALID           0x00000071
15043 +/* CKR_OBJECT_CLASS_INCONSISTENT and CKR_OBJECT_CLASS_INVALID
15044 + * were removed for v2.0 */
15045 +#define CKR_OBJECT_HANDLE_INVALID             0x00000082
15046 +#define CKR_OPERATION_ACTIVE                  0x00000090
15047 +#define CKR_OPERATION_NOT_INITIALIZED         0x00000091
15048 +#define CKR_PIN_INCORRECT                     0x000000A0
15049 +#define CKR_PIN_INVALID                       0x000000A1
15050 +#define CKR_PIN_LEN_RANGE                     0x000000A2
15052 +/* CKR_PIN_EXPIRED and CKR_PIN_LOCKED are new for v2.0 */
15053 +#define CKR_PIN_EXPIRED                       0x000000A3
15054 +#define CKR_PIN_LOCKED                        0x000000A4
15056 +#define CKR_SESSION_CLOSED                    0x000000B0
15057 +#define CKR_SESSION_COUNT                     0x000000B1
15058 +#define CKR_SESSION_HANDLE_INVALID            0x000000B3
15059 +#define CKR_SESSION_PARALLEL_NOT_SUPPORTED    0x000000B4
15060 +#define CKR_SESSION_READ_ONLY                 0x000000B5
15061 +#define CKR_SESSION_EXISTS                    0x000000B6
15063 +/* CKR_SESSION_READ_ONLY_EXISTS and
15064 + * CKR_SESSION_READ_WRITE_SO_EXISTS are new for v2.0 */
15065 +#define CKR_SESSION_READ_ONLY_EXISTS          0x000000B7
15066 +#define CKR_SESSION_READ_WRITE_SO_EXISTS      0x000000B8
15068 +#define CKR_SIGNATURE_INVALID                 0x000000C0
15069 +#define CKR_SIGNATURE_LEN_RANGE               0x000000C1
15070 +#define CKR_TEMPLATE_INCOMPLETE               0x000000D0
15071 +#define CKR_TEMPLATE_INCONSISTENT             0x000000D1
15072 +#define CKR_TOKEN_NOT_PRESENT                 0x000000E0
15073 +#define CKR_TOKEN_NOT_RECOGNIZED              0x000000E1
15074 +#define CKR_TOKEN_WRITE_PROTECTED             0x000000E2
15075 +#define CKR_UNWRAPPING_KEY_HANDLE_INVALID     0x000000F0
15076 +#define CKR_UNWRAPPING_KEY_SIZE_RANGE         0x000000F1
15077 +#define CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT  0x000000F2
15078 +#define CKR_USER_ALREADY_LOGGED_IN            0x00000100
15079 +#define CKR_USER_NOT_LOGGED_IN                0x00000101
15080 +#define CKR_USER_PIN_NOT_INITIALIZED          0x00000102
15081 +#define CKR_USER_TYPE_INVALID                 0x00000103
15083 +/* CKR_USER_ANOTHER_ALREADY_LOGGED_IN and CKR_USER_TOO_MANY_TYPES
15084 + * are new to v2.01 */
15085 +#define CKR_USER_ANOTHER_ALREADY_LOGGED_IN    0x00000104
15086 +#define CKR_USER_TOO_MANY_TYPES               0x00000105
15088 +#define CKR_WRAPPED_KEY_INVALID               0x00000110
15089 +#define CKR_WRAPPED_KEY_LEN_RANGE             0x00000112
15090 +#define CKR_WRAPPING_KEY_HANDLE_INVALID       0x00000113
15091 +#define CKR_WRAPPING_KEY_SIZE_RANGE           0x00000114
15092 +#define CKR_WRAPPING_KEY_TYPE_INCONSISTENT    0x00000115
15093 +#define CKR_RANDOM_SEED_NOT_SUPPORTED         0x00000120
15095 +/* These are new to v2.0 */
15096 +#define CKR_RANDOM_NO_RNG                     0x00000121
15098 +/* These are new to v2.11 */
15099 +#define CKR_DOMAIN_PARAMS_INVALID             0x00000130
15101 +/* These are new to v2.0 */
15102 +#define CKR_BUFFER_TOO_SMALL                  0x00000150
15103 +#define CKR_SAVED_STATE_INVALID               0x00000160
15104 +#define CKR_INFORMATION_SENSITIVE             0x00000170
15105 +#define CKR_STATE_UNSAVEABLE                  0x00000180
15107 +/* These are new to v2.01 */
15108 +#define CKR_CRYPTOKI_NOT_INITIALIZED          0x00000190
15109 +#define CKR_CRYPTOKI_ALREADY_INITIALIZED      0x00000191
15110 +#define CKR_MUTEX_BAD                         0x000001A0
15111 +#define CKR_MUTEX_NOT_LOCKED                  0x000001A1
15113 +/* The following return values are new for PKCS #11 v2.20 amendment 3 */
15114 +#define CKR_NEW_PIN_MODE                      0x000001B0
15115 +#define CKR_NEXT_OTP                          0x000001B1
15117 +/* This is new to v2.20 */
15118 +#define CKR_FUNCTION_REJECTED                 0x00000200
15120 +#define CKR_VENDOR_DEFINED                    0x80000000
15123 +/* CK_NOTIFY is an application callback that processes events */
15124 +typedef CK_CALLBACK_FUNCTION(CK_RV, CK_NOTIFY)(
15125 +  CK_SESSION_HANDLE hSession,     /* the session's handle */
15126 +  CK_NOTIFICATION   event,
15127 +  CK_VOID_PTR       pApplication  /* passed to C_OpenSession */
15131 +/* CK_FUNCTION_LIST is a structure holding a Cryptoki spec
15132 + * version and pointers of appropriate types to all the
15133 + * Cryptoki functions */
15134 +/* CK_FUNCTION_LIST is new for v2.0 */
15135 +typedef struct CK_FUNCTION_LIST CK_FUNCTION_LIST;
15137 +typedef CK_FUNCTION_LIST CK_PTR CK_FUNCTION_LIST_PTR;
15139 +typedef CK_FUNCTION_LIST_PTR CK_PTR CK_FUNCTION_LIST_PTR_PTR;
15142 +/* CK_CREATEMUTEX is an application callback for creating a
15143 + * mutex object */
15144 +typedef CK_CALLBACK_FUNCTION(CK_RV, CK_CREATEMUTEX)(
15145 +  CK_VOID_PTR_PTR ppMutex  /* location to receive ptr to mutex */
15149 +/* CK_DESTROYMUTEX is an application callback for destroying a
15150 + * mutex object */
15151 +typedef CK_CALLBACK_FUNCTION(CK_RV, CK_DESTROYMUTEX)(
15152 +  CK_VOID_PTR pMutex  /* pointer to mutex */
15156 +/* CK_LOCKMUTEX is an application callback for locking a mutex */
15157 +typedef CK_CALLBACK_FUNCTION(CK_RV, CK_LOCKMUTEX)(
15158 +  CK_VOID_PTR pMutex  /* pointer to mutex */
15162 +/* CK_UNLOCKMUTEX is an application callback for unlocking a
15163 + * mutex */
15164 +typedef CK_CALLBACK_FUNCTION(CK_RV, CK_UNLOCKMUTEX)(
15165 +  CK_VOID_PTR pMutex  /* pointer to mutex */
15169 +/* CK_C_INITIALIZE_ARGS provides the optional arguments to
15170 + * C_Initialize */
15171 +typedef struct CK_C_INITIALIZE_ARGS {
15172 +  CK_CREATEMUTEX CreateMutex;
15173 +  CK_DESTROYMUTEX DestroyMutex;
15174 +  CK_LOCKMUTEX LockMutex;
15175 +  CK_UNLOCKMUTEX UnlockMutex;
15176 +  CK_FLAGS flags;
15177 +  CK_VOID_PTR pReserved;
15178 +} CK_C_INITIALIZE_ARGS;
15180 +/* flags: bit flags that provide capabilities of the slot
15181 + *      Bit Flag                           Mask       Meaning
15182 + */
15183 +#define CKF_LIBRARY_CANT_CREATE_OS_THREADS 0x00000001
15184 +#define CKF_OS_LOCKING_OK                  0x00000002
15186 +typedef CK_C_INITIALIZE_ARGS CK_PTR CK_C_INITIALIZE_ARGS_PTR;
15189 +/* additional flags for parameters to functions */
15191 +/* CKF_DONT_BLOCK is for the function C_WaitForSlotEvent */
15192 +#define CKF_DONT_BLOCK     1
15194 +/* CK_RSA_PKCS_OAEP_MGF_TYPE is new for v2.10.
15195 + * CK_RSA_PKCS_OAEP_MGF_TYPE  is used to indicate the Message
15196 + * Generation Function (MGF) applied to a message block when
15197 + * formatting a message block for the PKCS #1 OAEP encryption
15198 + * scheme. */
15199 +typedef CK_ULONG CK_RSA_PKCS_MGF_TYPE;
15201 +typedef CK_RSA_PKCS_MGF_TYPE CK_PTR CK_RSA_PKCS_MGF_TYPE_PTR;
15203 +/* The following MGFs are defined */
15204 +/* CKG_MGF1_SHA256, CKG_MGF1_SHA384, and CKG_MGF1_SHA512
15205 + * are new for v2.20 */
15206 +#define CKG_MGF1_SHA1         0x00000001
15207 +#define CKG_MGF1_SHA256       0x00000002
15208 +#define CKG_MGF1_SHA384       0x00000003
15209 +#define CKG_MGF1_SHA512       0x00000004
15210 +/* SHA-224 is new for PKCS #11 v2.20 amendment 3 */
15211 +#define CKG_MGF1_SHA224       0x00000005
15213 +/* CK_RSA_PKCS_OAEP_SOURCE_TYPE is new for v2.10.
15214 + * CK_RSA_PKCS_OAEP_SOURCE_TYPE  is used to indicate the source
15215 + * of the encoding parameter when formatting a message block
15216 + * for the PKCS #1 OAEP encryption scheme. */
15217 +typedef CK_ULONG CK_RSA_PKCS_OAEP_SOURCE_TYPE;
15219 +typedef CK_RSA_PKCS_OAEP_SOURCE_TYPE CK_PTR CK_RSA_PKCS_OAEP_SOURCE_TYPE_PTR;
15221 +/* The following encoding parameter sources are defined */
15222 +#define CKZ_DATA_SPECIFIED    0x00000001
15224 +/* CK_RSA_PKCS_OAEP_PARAMS is new for v2.10.
15225 + * CK_RSA_PKCS_OAEP_PARAMS provides the parameters to the
15226 + * CKM_RSA_PKCS_OAEP mechanism. */
15227 +typedef struct CK_RSA_PKCS_OAEP_PARAMS {
15228 +        CK_MECHANISM_TYPE hashAlg;
15229 +        CK_RSA_PKCS_MGF_TYPE mgf;
15230 +        CK_RSA_PKCS_OAEP_SOURCE_TYPE source;
15231 +        CK_VOID_PTR pSourceData;
15232 +        CK_ULONG ulSourceDataLen;
15233 +} CK_RSA_PKCS_OAEP_PARAMS;
15235 +typedef CK_RSA_PKCS_OAEP_PARAMS CK_PTR CK_RSA_PKCS_OAEP_PARAMS_PTR;
15237 +/* CK_RSA_PKCS_PSS_PARAMS is new for v2.11.
15238 + * CK_RSA_PKCS_PSS_PARAMS provides the parameters to the
15239 + * CKM_RSA_PKCS_PSS mechanism(s). */
15240 +typedef struct CK_RSA_PKCS_PSS_PARAMS {
15241 +        CK_MECHANISM_TYPE    hashAlg;
15242 +        CK_RSA_PKCS_MGF_TYPE mgf;
15243 +        CK_ULONG             sLen;
15244 +} CK_RSA_PKCS_PSS_PARAMS;
15246 +typedef CK_RSA_PKCS_PSS_PARAMS CK_PTR CK_RSA_PKCS_PSS_PARAMS_PTR;
15248 +/* CK_EC_KDF_TYPE is new for v2.11. */
15249 +typedef CK_ULONG CK_EC_KDF_TYPE;
15251 +/* The following EC Key Derivation Functions are defined */
15252 +#define CKD_NULL                 0x00000001
15253 +#define CKD_SHA1_KDF             0x00000002
15255 +/* CK_ECDH1_DERIVE_PARAMS is new for v2.11.
15256 + * CK_ECDH1_DERIVE_PARAMS provides the parameters to the
15257 + * CKM_ECDH1_DERIVE and CKM_ECDH1_COFACTOR_DERIVE mechanisms,
15258 + * where each party contributes one key pair.
15259 + */
15260 +typedef struct CK_ECDH1_DERIVE_PARAMS {
15261 +  CK_EC_KDF_TYPE kdf;
15262 +  CK_ULONG ulSharedDataLen;
15263 +  CK_BYTE_PTR pSharedData;
15264 +  CK_ULONG ulPublicDataLen;
15265 +  CK_BYTE_PTR pPublicData;
15266 +} CK_ECDH1_DERIVE_PARAMS;
15268 +typedef CK_ECDH1_DERIVE_PARAMS CK_PTR CK_ECDH1_DERIVE_PARAMS_PTR;
15271 +/* CK_ECDH2_DERIVE_PARAMS is new for v2.11.
15272 + * CK_ECDH2_DERIVE_PARAMS provides the parameters to the
15273 + * CKM_ECMQV_DERIVE mechanism, where each party contributes two key pairs. */
15274 +typedef struct CK_ECDH2_DERIVE_PARAMS {
15275 +  CK_EC_KDF_TYPE kdf;
15276 +  CK_ULONG ulSharedDataLen;
15277 +  CK_BYTE_PTR pSharedData;
15278 +  CK_ULONG ulPublicDataLen;
15279 +  CK_BYTE_PTR pPublicData;
15280 +  CK_ULONG ulPrivateDataLen;
15281 +  CK_OBJECT_HANDLE hPrivateData;
15282 +  CK_ULONG ulPublicDataLen2;
15283 +  CK_BYTE_PTR pPublicData2;
15284 +} CK_ECDH2_DERIVE_PARAMS;
15286 +typedef CK_ECDH2_DERIVE_PARAMS CK_PTR CK_ECDH2_DERIVE_PARAMS_PTR;
15288 +typedef struct CK_ECMQV_DERIVE_PARAMS {
15289 +  CK_EC_KDF_TYPE kdf;
15290 +  CK_ULONG ulSharedDataLen;
15291 +  CK_BYTE_PTR pSharedData;
15292 +  CK_ULONG ulPublicDataLen;
15293 +  CK_BYTE_PTR pPublicData;
15294 +  CK_ULONG ulPrivateDataLen;
15295 +  CK_OBJECT_HANDLE hPrivateData;
15296 +  CK_ULONG ulPublicDataLen2;
15297 +  CK_BYTE_PTR pPublicData2;
15298 +  CK_OBJECT_HANDLE publicKey;
15299 +} CK_ECMQV_DERIVE_PARAMS;
15301 +typedef CK_ECMQV_DERIVE_PARAMS CK_PTR CK_ECMQV_DERIVE_PARAMS_PTR;
15303 +/* Typedefs and defines for the CKM_X9_42_DH_KEY_PAIR_GEN and the
15304 + * CKM_X9_42_DH_PARAMETER_GEN mechanisms (new for PKCS #11 v2.11) */
15305 +typedef CK_ULONG CK_X9_42_DH_KDF_TYPE;
15306 +typedef CK_X9_42_DH_KDF_TYPE CK_PTR CK_X9_42_DH_KDF_TYPE_PTR;
15308 +/* The following X9.42 DH key derivation functions are defined
15309 +   (besides CKD_NULL already defined : */
15310 +#define CKD_SHA1_KDF_ASN1        0x00000003
15311 +#define CKD_SHA1_KDF_CONCATENATE 0x00000004
15313 +/* CK_X9_42_DH1_DERIVE_PARAMS is new for v2.11.
15314 + * CK_X9_42_DH1_DERIVE_PARAMS provides the parameters to the
15315 + * CKM_X9_42_DH_DERIVE key derivation mechanism, where each party
15316 + * contributes one key pair */
15317 +typedef struct CK_X9_42_DH1_DERIVE_PARAMS {
15318 +  CK_X9_42_DH_KDF_TYPE kdf;
15319 +  CK_ULONG ulOtherInfoLen;
15320 +  CK_BYTE_PTR pOtherInfo;
15321 +  CK_ULONG ulPublicDataLen;
15322 +  CK_BYTE_PTR pPublicData;
15323 +} CK_X9_42_DH1_DERIVE_PARAMS;
15325 +typedef struct CK_X9_42_DH1_DERIVE_PARAMS CK_PTR CK_X9_42_DH1_DERIVE_PARAMS_PTR;
15327 +/* CK_X9_42_DH2_DERIVE_PARAMS is new for v2.11.
15328 + * CK_X9_42_DH2_DERIVE_PARAMS provides the parameters to the
15329 + * CKM_X9_42_DH_HYBRID_DERIVE and CKM_X9_42_MQV_DERIVE key derivation
15330 + * mechanisms, where each party contributes two key pairs */
15331 +typedef struct CK_X9_42_DH2_DERIVE_PARAMS {
15332 +  CK_X9_42_DH_KDF_TYPE kdf;
15333 +  CK_ULONG ulOtherInfoLen;
15334 +  CK_BYTE_PTR pOtherInfo;
15335 +  CK_ULONG ulPublicDataLen;
15336 +  CK_BYTE_PTR pPublicData;
15337 +  CK_ULONG ulPrivateDataLen;
15338 +  CK_OBJECT_HANDLE hPrivateData;
15339 +  CK_ULONG ulPublicDataLen2;
15340 +  CK_BYTE_PTR pPublicData2;
15341 +} CK_X9_42_DH2_DERIVE_PARAMS;
15343 +typedef CK_X9_42_DH2_DERIVE_PARAMS CK_PTR CK_X9_42_DH2_DERIVE_PARAMS_PTR;
15345 +typedef struct CK_X9_42_MQV_DERIVE_PARAMS {
15346 +  CK_X9_42_DH_KDF_TYPE kdf;
15347 +  CK_ULONG ulOtherInfoLen;
15348 +  CK_BYTE_PTR pOtherInfo;
15349 +  CK_ULONG ulPublicDataLen;
15350 +  CK_BYTE_PTR pPublicData;
15351 +  CK_ULONG ulPrivateDataLen;
15352 +  CK_OBJECT_HANDLE hPrivateData;
15353 +  CK_ULONG ulPublicDataLen2;
15354 +  CK_BYTE_PTR pPublicData2;
15355 +  CK_OBJECT_HANDLE publicKey;
15356 +} CK_X9_42_MQV_DERIVE_PARAMS;
15358 +typedef CK_X9_42_MQV_DERIVE_PARAMS CK_PTR CK_X9_42_MQV_DERIVE_PARAMS_PTR;
15360 +/* CK_KEA_DERIVE_PARAMS provides the parameters to the
15361 + * CKM_KEA_DERIVE mechanism */
15362 +/* CK_KEA_DERIVE_PARAMS is new for v2.0 */
15363 +typedef struct CK_KEA_DERIVE_PARAMS {
15364 +  CK_BBOOL      isSender;
15365 +  CK_ULONG      ulRandomLen;
15366 +  CK_BYTE_PTR   pRandomA;
15367 +  CK_BYTE_PTR   pRandomB;
15368 +  CK_ULONG      ulPublicDataLen;
15369 +  CK_BYTE_PTR   pPublicData;
15370 +} CK_KEA_DERIVE_PARAMS;
15372 +typedef CK_KEA_DERIVE_PARAMS CK_PTR CK_KEA_DERIVE_PARAMS_PTR;
15375 +/* CK_RC2_PARAMS provides the parameters to the CKM_RC2_ECB and
15376 + * CKM_RC2_MAC mechanisms.  An instance of CK_RC2_PARAMS just
15377 + * holds the effective keysize */
15378 +typedef CK_ULONG          CK_RC2_PARAMS;
15380 +typedef CK_RC2_PARAMS CK_PTR CK_RC2_PARAMS_PTR;
15383 +/* CK_RC2_CBC_PARAMS provides the parameters to the CKM_RC2_CBC
15384 + * mechanism */
15385 +typedef struct CK_RC2_CBC_PARAMS {
15386 +  /* ulEffectiveBits was changed from CK_USHORT to CK_ULONG for
15387 +   * v2.0 */
15388 +  CK_ULONG      ulEffectiveBits;  /* effective bits (1-1024) */
15390 +  CK_BYTE       iv[8];            /* IV for CBC mode */
15391 +} CK_RC2_CBC_PARAMS;
15393 +typedef CK_RC2_CBC_PARAMS CK_PTR CK_RC2_CBC_PARAMS_PTR;
15396 +/* CK_RC2_MAC_GENERAL_PARAMS provides the parameters for the
15397 + * CKM_RC2_MAC_GENERAL mechanism */
15398 +/* CK_RC2_MAC_GENERAL_PARAMS is new for v2.0 */
15399 +typedef struct CK_RC2_MAC_GENERAL_PARAMS {
15400 +  CK_ULONG      ulEffectiveBits;  /* effective bits (1-1024) */
15401 +  CK_ULONG      ulMacLength;      /* Length of MAC in bytes */
15402 +} CK_RC2_MAC_GENERAL_PARAMS;
15404 +typedef CK_RC2_MAC_GENERAL_PARAMS CK_PTR \
15405 +  CK_RC2_MAC_GENERAL_PARAMS_PTR;
15408 +/* CK_RC5_PARAMS provides the parameters to the CKM_RC5_ECB and
15409 + * CKM_RC5_MAC mechanisms */
15410 +/* CK_RC5_PARAMS is new for v2.0 */
15411 +typedef struct CK_RC5_PARAMS {
15412 +  CK_ULONG      ulWordsize;  /* wordsize in bits */
15413 +  CK_ULONG      ulRounds;    /* number of rounds */
15414 +} CK_RC5_PARAMS;
15416 +typedef CK_RC5_PARAMS CK_PTR CK_RC5_PARAMS_PTR;
15419 +/* CK_RC5_CBC_PARAMS provides the parameters to the CKM_RC5_CBC
15420 + * mechanism */
15421 +/* CK_RC5_CBC_PARAMS is new for v2.0 */
15422 +typedef struct CK_RC5_CBC_PARAMS {
15423 +  CK_ULONG      ulWordsize;  /* wordsize in bits */
15424 +  CK_ULONG      ulRounds;    /* number of rounds */
15425 +  CK_BYTE_PTR   pIv;         /* pointer to IV */
15426 +  CK_ULONG      ulIvLen;     /* length of IV in bytes */
15427 +} CK_RC5_CBC_PARAMS;
15429 +typedef CK_RC5_CBC_PARAMS CK_PTR CK_RC5_CBC_PARAMS_PTR;
15432 +/* CK_RC5_MAC_GENERAL_PARAMS provides the parameters for the
15433 + * CKM_RC5_MAC_GENERAL mechanism */
15434 +/* CK_RC5_MAC_GENERAL_PARAMS is new for v2.0 */
15435 +typedef struct CK_RC5_MAC_GENERAL_PARAMS {
15436 +  CK_ULONG      ulWordsize;   /* wordsize in bits */
15437 +  CK_ULONG      ulRounds;     /* number of rounds */
15438 +  CK_ULONG      ulMacLength;  /* Length of MAC in bytes */
15439 +} CK_RC5_MAC_GENERAL_PARAMS;
15441 +typedef CK_RC5_MAC_GENERAL_PARAMS CK_PTR \
15442 +  CK_RC5_MAC_GENERAL_PARAMS_PTR;
15445 +/* CK_MAC_GENERAL_PARAMS provides the parameters to most block
15446 + * ciphers' MAC_GENERAL mechanisms.  Its value is the length of
15447 + * the MAC */
15448 +/* CK_MAC_GENERAL_PARAMS is new for v2.0 */
15449 +typedef CK_ULONG          CK_MAC_GENERAL_PARAMS;
15451 +typedef CK_MAC_GENERAL_PARAMS CK_PTR CK_MAC_GENERAL_PARAMS_PTR;
15453 +/* CK_DES/AES_ECB/CBC_ENCRYPT_DATA_PARAMS are new for v2.20 */
15454 +typedef struct CK_DES_CBC_ENCRYPT_DATA_PARAMS {
15455 +  CK_BYTE      iv[8];
15456 +  CK_BYTE_PTR  pData;
15457 +  CK_ULONG     length;
15458 +} CK_DES_CBC_ENCRYPT_DATA_PARAMS;
15460 +typedef CK_DES_CBC_ENCRYPT_DATA_PARAMS CK_PTR CK_DES_CBC_ENCRYPT_DATA_PARAMS_PTR;
15462 +typedef struct CK_AES_CBC_ENCRYPT_DATA_PARAMS {
15463 +  CK_BYTE      iv[16];
15464 +  CK_BYTE_PTR  pData;
15465 +  CK_ULONG     length;
15466 +} CK_AES_CBC_ENCRYPT_DATA_PARAMS;
15468 +typedef CK_AES_CBC_ENCRYPT_DATA_PARAMS CK_PTR CK_AES_CBC_ENCRYPT_DATA_PARAMS_PTR;
15470 +/* CK_SKIPJACK_PRIVATE_WRAP_PARAMS provides the parameters to the
15471 + * CKM_SKIPJACK_PRIVATE_WRAP mechanism */
15472 +/* CK_SKIPJACK_PRIVATE_WRAP_PARAMS is new for v2.0 */
15473 +typedef struct CK_SKIPJACK_PRIVATE_WRAP_PARAMS {
15474 +  CK_ULONG      ulPasswordLen;
15475 +  CK_BYTE_PTR   pPassword;
15476 +  CK_ULONG      ulPublicDataLen;
15477 +  CK_BYTE_PTR   pPublicData;
15478 +  CK_ULONG      ulPAndGLen;
15479 +  CK_ULONG      ulQLen;
15480 +  CK_ULONG      ulRandomLen;
15481 +  CK_BYTE_PTR   pRandomA;
15482 +  CK_BYTE_PTR   pPrimeP;
15483 +  CK_BYTE_PTR   pBaseG;
15484 +  CK_BYTE_PTR   pSubprimeQ;
15485 +} CK_SKIPJACK_PRIVATE_WRAP_PARAMS;
15487 +typedef CK_SKIPJACK_PRIVATE_WRAP_PARAMS CK_PTR \
15488 +  CK_SKIPJACK_PRIVATE_WRAP_PTR;
15491 +/* CK_SKIPJACK_RELAYX_PARAMS provides the parameters to the
15492 + * CKM_SKIPJACK_RELAYX mechanism */
15493 +/* CK_SKIPJACK_RELAYX_PARAMS is new for v2.0 */
15494 +typedef struct CK_SKIPJACK_RELAYX_PARAMS {
15495 +  CK_ULONG      ulOldWrappedXLen;
15496 +  CK_BYTE_PTR   pOldWrappedX;
15497 +  CK_ULONG      ulOldPasswordLen;
15498 +  CK_BYTE_PTR   pOldPassword;
15499 +  CK_ULONG      ulOldPublicDataLen;
15500 +  CK_BYTE_PTR   pOldPublicData;
15501 +  CK_ULONG      ulOldRandomLen;
15502 +  CK_BYTE_PTR   pOldRandomA;
15503 +  CK_ULONG      ulNewPasswordLen;
15504 +  CK_BYTE_PTR   pNewPassword;
15505 +  CK_ULONG      ulNewPublicDataLen;
15506 +  CK_BYTE_PTR   pNewPublicData;
15507 +  CK_ULONG      ulNewRandomLen;
15508 +  CK_BYTE_PTR   pNewRandomA;
15509 +} CK_SKIPJACK_RELAYX_PARAMS;
15511 +typedef CK_SKIPJACK_RELAYX_PARAMS CK_PTR \
15512 +  CK_SKIPJACK_RELAYX_PARAMS_PTR;
15515 +typedef struct CK_PBE_PARAMS {
15516 +  CK_BYTE_PTR      pInitVector;
15517 +  CK_UTF8CHAR_PTR  pPassword;
15518 +  CK_ULONG         ulPasswordLen;
15519 +  CK_BYTE_PTR      pSalt;
15520 +  CK_ULONG         ulSaltLen;
15521 +  CK_ULONG         ulIteration;
15522 +} CK_PBE_PARAMS;
15524 +typedef CK_PBE_PARAMS CK_PTR CK_PBE_PARAMS_PTR;
15527 +/* CK_KEY_WRAP_SET_OAEP_PARAMS provides the parameters to the
15528 + * CKM_KEY_WRAP_SET_OAEP mechanism */
15529 +/* CK_KEY_WRAP_SET_OAEP_PARAMS is new for v2.0 */
15530 +typedef struct CK_KEY_WRAP_SET_OAEP_PARAMS {
15531 +  CK_BYTE       bBC;     /* block contents byte */
15532 +  CK_BYTE_PTR   pX;      /* extra data */
15533 +  CK_ULONG      ulXLen;  /* length of extra data in bytes */
15534 +} CK_KEY_WRAP_SET_OAEP_PARAMS;
15536 +typedef CK_KEY_WRAP_SET_OAEP_PARAMS CK_PTR \
15537 +  CK_KEY_WRAP_SET_OAEP_PARAMS_PTR;
15540 +typedef struct CK_SSL3_RANDOM_DATA {
15541 +  CK_BYTE_PTR  pClientRandom;
15542 +  CK_ULONG     ulClientRandomLen;
15543 +  CK_BYTE_PTR  pServerRandom;
15544 +  CK_ULONG     ulServerRandomLen;
15545 +} CK_SSL3_RANDOM_DATA;
15548 +typedef struct CK_SSL3_MASTER_KEY_DERIVE_PARAMS {
15549 +  CK_SSL3_RANDOM_DATA RandomInfo;
15550 +  CK_VERSION_PTR pVersion;
15551 +} CK_SSL3_MASTER_KEY_DERIVE_PARAMS;
15553 +typedef struct CK_SSL3_MASTER_KEY_DERIVE_PARAMS CK_PTR \
15554 +  CK_SSL3_MASTER_KEY_DERIVE_PARAMS_PTR;
15557 +typedef struct CK_SSL3_KEY_MAT_OUT {
15558 +  CK_OBJECT_HANDLE hClientMacSecret;
15559 +  CK_OBJECT_HANDLE hServerMacSecret;
15560 +  CK_OBJECT_HANDLE hClientKey;
15561 +  CK_OBJECT_HANDLE hServerKey;
15562 +  CK_BYTE_PTR      pIVClient;
15563 +  CK_BYTE_PTR      pIVServer;
15564 +} CK_SSL3_KEY_MAT_OUT;
15566 +typedef CK_SSL3_KEY_MAT_OUT CK_PTR CK_SSL3_KEY_MAT_OUT_PTR;
15569 +typedef struct CK_SSL3_KEY_MAT_PARAMS {
15570 +  CK_ULONG                ulMacSizeInBits;
15571 +  CK_ULONG                ulKeySizeInBits;
15572 +  CK_ULONG                ulIVSizeInBits;
15573 +  CK_BBOOL                bIsExport;
15574 +  CK_SSL3_RANDOM_DATA     RandomInfo;
15575 +  CK_SSL3_KEY_MAT_OUT_PTR pReturnedKeyMaterial;
15576 +} CK_SSL3_KEY_MAT_PARAMS;
15578 +typedef CK_SSL3_KEY_MAT_PARAMS CK_PTR CK_SSL3_KEY_MAT_PARAMS_PTR;
15580 +/* CK_TLS_PRF_PARAMS is new for version 2.20 */
15581 +typedef struct CK_TLS_PRF_PARAMS {
15582 +  CK_BYTE_PTR  pSeed;
15583 +  CK_ULONG     ulSeedLen;
15584 +  CK_BYTE_PTR  pLabel;
15585 +  CK_ULONG     ulLabelLen;
15586 +  CK_BYTE_PTR  pOutput;
15587 +  CK_ULONG_PTR pulOutputLen;
15588 +} CK_TLS_PRF_PARAMS;
15590 +typedef CK_TLS_PRF_PARAMS CK_PTR CK_TLS_PRF_PARAMS_PTR;
15592 +/* WTLS is new for version 2.20 */
15593 +typedef struct CK_WTLS_RANDOM_DATA {
15594 +  CK_BYTE_PTR pClientRandom;
15595 +  CK_ULONG    ulClientRandomLen;
15596 +  CK_BYTE_PTR pServerRandom;
15597 +  CK_ULONG    ulServerRandomLen;
15598 +} CK_WTLS_RANDOM_DATA;
15600 +typedef CK_WTLS_RANDOM_DATA CK_PTR CK_WTLS_RANDOM_DATA_PTR;
15602 +typedef struct CK_WTLS_MASTER_KEY_DERIVE_PARAMS {
15603 +  CK_MECHANISM_TYPE   DigestMechanism;
15604 +  CK_WTLS_RANDOM_DATA RandomInfo;
15605 +  CK_BYTE_PTR         pVersion;
15606 +} CK_WTLS_MASTER_KEY_DERIVE_PARAMS;
15608 +typedef CK_WTLS_MASTER_KEY_DERIVE_PARAMS CK_PTR \
15609 +  CK_WTLS_MASTER_KEY_DERIVE_PARAMS_PTR;
15611 +typedef struct CK_WTLS_PRF_PARAMS {
15612 +  CK_MECHANISM_TYPE DigestMechanism;
15613 +  CK_BYTE_PTR       pSeed;
15614 +  CK_ULONG          ulSeedLen;
15615 +  CK_BYTE_PTR       pLabel;
15616 +  CK_ULONG          ulLabelLen;
15617 +  CK_BYTE_PTR       pOutput;
15618 +  CK_ULONG_PTR      pulOutputLen;
15619 +} CK_WTLS_PRF_PARAMS;
15621 +typedef CK_WTLS_PRF_PARAMS CK_PTR CK_WTLS_PRF_PARAMS_PTR;
15623 +typedef struct CK_WTLS_KEY_MAT_OUT {
15624 +  CK_OBJECT_HANDLE hMacSecret;
15625 +  CK_OBJECT_HANDLE hKey;
15626 +  CK_BYTE_PTR      pIV;
15627 +} CK_WTLS_KEY_MAT_OUT;
15629 +typedef CK_WTLS_KEY_MAT_OUT CK_PTR CK_WTLS_KEY_MAT_OUT_PTR;
15631 +typedef struct CK_WTLS_KEY_MAT_PARAMS {
15632 +  CK_MECHANISM_TYPE       DigestMechanism;
15633 +  CK_ULONG                ulMacSizeInBits;
15634 +  CK_ULONG                ulKeySizeInBits;
15635 +  CK_ULONG                ulIVSizeInBits;
15636 +  CK_ULONG                ulSequenceNumber;
15637 +  CK_BBOOL                bIsExport;
15638 +  CK_WTLS_RANDOM_DATA     RandomInfo;
15639 +  CK_WTLS_KEY_MAT_OUT_PTR pReturnedKeyMaterial;
15640 +} CK_WTLS_KEY_MAT_PARAMS;
15642 +typedef CK_WTLS_KEY_MAT_PARAMS CK_PTR CK_WTLS_KEY_MAT_PARAMS_PTR;
15644 +/* CMS is new for version 2.20 */
15645 +typedef struct CK_CMS_SIG_PARAMS {
15646 +  CK_OBJECT_HANDLE      certificateHandle;
15647 +  CK_MECHANISM_PTR      pSigningMechanism;
15648 +  CK_MECHANISM_PTR      pDigestMechanism;
15649 +  CK_UTF8CHAR_PTR       pContentType;
15650 +  CK_BYTE_PTR           pRequestedAttributes;
15651 +  CK_ULONG              ulRequestedAttributesLen;
15652 +  CK_BYTE_PTR           pRequiredAttributes;
15653 +  CK_ULONG              ulRequiredAttributesLen;
15654 +} CK_CMS_SIG_PARAMS;
15656 +typedef CK_CMS_SIG_PARAMS CK_PTR CK_CMS_SIG_PARAMS_PTR;
15658 +typedef struct CK_KEY_DERIVATION_STRING_DATA {
15659 +  CK_BYTE_PTR pData;
15660 +  CK_ULONG    ulLen;
15661 +} CK_KEY_DERIVATION_STRING_DATA;
15663 +typedef CK_KEY_DERIVATION_STRING_DATA CK_PTR \
15664 +  CK_KEY_DERIVATION_STRING_DATA_PTR;
15667 +/* The CK_EXTRACT_PARAMS is used for the
15668 + * CKM_EXTRACT_KEY_FROM_KEY mechanism.  It specifies which bit
15669 + * of the base key should be used as the first bit of the
15670 + * derived key */
15671 +/* CK_EXTRACT_PARAMS is new for v2.0 */
15672 +typedef CK_ULONG CK_EXTRACT_PARAMS;
15674 +typedef CK_EXTRACT_PARAMS CK_PTR CK_EXTRACT_PARAMS_PTR;
15676 +/* CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE is new for v2.10.
15677 + * CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE is used to
15678 + * indicate the Pseudo-Random Function (PRF) used to generate
15679 + * key bits using PKCS #5 PBKDF2. */
15680 +typedef CK_ULONG CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE;
15682 +typedef CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE CK_PTR CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE_PTR;
15684 +/* The following PRFs are defined in PKCS #5 v2.0. */
15685 +#define CKP_PKCS5_PBKD2_HMAC_SHA1 0x00000001
15688 +/* CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE is new for v2.10.
15689 + * CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE is used to indicate the
15690 + * source of the salt value when deriving a key using PKCS #5
15691 + * PBKDF2. */
15692 +typedef CK_ULONG CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE;
15694 +typedef CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE CK_PTR CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE_PTR;
15696 +/* The following salt value sources are defined in PKCS #5 v2.0. */
15697 +#define CKZ_SALT_SPECIFIED        0x00000001
15699 +/* CK_PKCS5_PBKD2_PARAMS is new for v2.10.
15700 + * CK_PKCS5_PBKD2_PARAMS is a structure that provides the
15701 + * parameters to the CKM_PKCS5_PBKD2 mechanism. */
15702 +typedef struct CK_PKCS5_PBKD2_PARAMS {
15703 +        CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE           saltSource;
15704 +        CK_VOID_PTR                                pSaltSourceData;
15705 +        CK_ULONG                                   ulSaltSourceDataLen;
15706 +        CK_ULONG                                   iterations;
15707 +        CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE prf;
15708 +        CK_VOID_PTR                                pPrfData;
15709 +        CK_ULONG                                   ulPrfDataLen;
15710 +        CK_UTF8CHAR_PTR                            pPassword;
15711 +        CK_ULONG_PTR                               ulPasswordLen;
15712 +} CK_PKCS5_PBKD2_PARAMS;
15714 +typedef CK_PKCS5_PBKD2_PARAMS CK_PTR CK_PKCS5_PBKD2_PARAMS_PTR;
15716 +/* All CK_OTP structs are new for PKCS #11 v2.20 amendment 3 */
15718 +typedef CK_ULONG CK_OTP_PARAM_TYPE;
15719 +typedef CK_OTP_PARAM_TYPE CK_PARAM_TYPE; /* B/w compatibility */
15721 +typedef struct CK_OTP_PARAM {
15722 +    CK_OTP_PARAM_TYPE type;
15723 +    CK_VOID_PTR pValue;
15724 +    CK_ULONG ulValueLen;
15725 +} CK_OTP_PARAM;
15727 +typedef CK_OTP_PARAM CK_PTR CK_OTP_PARAM_PTR;
15729 +typedef struct CK_OTP_PARAMS {
15730 +    CK_OTP_PARAM_PTR pParams;
15731 +    CK_ULONG ulCount;
15732 +} CK_OTP_PARAMS;
15734 +typedef CK_OTP_PARAMS CK_PTR CK_OTP_PARAMS_PTR;
15736 +typedef struct CK_OTP_SIGNATURE_INFO {
15737 +    CK_OTP_PARAM_PTR pParams;
15738 +    CK_ULONG ulCount;
15739 +} CK_OTP_SIGNATURE_INFO;
15741 +typedef CK_OTP_SIGNATURE_INFO CK_PTR CK_OTP_SIGNATURE_INFO_PTR;
15743 +/* The following OTP-related defines are new for PKCS #11 v2.20 amendment 1 */
15744 +#define CK_OTP_VALUE          0
15745 +#define CK_OTP_PIN            1
15746 +#define CK_OTP_CHALLENGE      2
15747 +#define CK_OTP_TIME           3
15748 +#define CK_OTP_COUNTER        4
15749 +#define CK_OTP_FLAGS          5
15750 +#define CK_OTP_OUTPUT_LENGTH  6
15751 +#define CK_OTP_OUTPUT_FORMAT  7
15753 +/* The following OTP-related defines are new for PKCS #11 v2.20 amendment 1 */
15754 +#define CKF_NEXT_OTP          0x00000001
15755 +#define CKF_EXCLUDE_TIME      0x00000002
15756 +#define CKF_EXCLUDE_COUNTER   0x00000004
15757 +#define CKF_EXCLUDE_CHALLENGE 0x00000008
15758 +#define CKF_EXCLUDE_PIN       0x00000010
15759 +#define CKF_USER_FRIENDLY_OTP 0x00000020
15761 +/* CK_KIP_PARAMS is new for PKCS #11 v2.20 amendment 2 */
15762 +typedef struct CK_KIP_PARAMS {
15763 +    CK_MECHANISM_PTR  pMechanism;
15764 +    CK_OBJECT_HANDLE  hKey;
15765 +    CK_BYTE_PTR       pSeed;
15766 +    CK_ULONG          ulSeedLen;
15767 +} CK_KIP_PARAMS;
15769 +typedef CK_KIP_PARAMS CK_PTR CK_KIP_PARAMS_PTR;
15771 +/* CK_AES_CTR_PARAMS is new for PKCS #11 v2.20 amendment 3 */
15772 +typedef struct CK_AES_CTR_PARAMS {
15773 +    CK_ULONG ulCounterBits;
15774 +    CK_BYTE cb[16];
15775 +} CK_AES_CTR_PARAMS;
15777 +typedef CK_AES_CTR_PARAMS CK_PTR CK_AES_CTR_PARAMS_PTR;
15779 +/* CK_CAMELLIA_CTR_PARAMS is new for PKCS #11 v2.20 amendment 3 */
15780 +typedef struct CK_CAMELLIA_CTR_PARAMS {
15781 +    CK_ULONG ulCounterBits;
15782 +    CK_BYTE cb[16];
15783 +} CK_CAMELLIA_CTR_PARAMS;
15785 +typedef CK_CAMELLIA_CTR_PARAMS CK_PTR CK_CAMELLIA_CTR_PARAMS_PTR;
15787 +/* CK_CAMELLIA_CBC_ENCRYPT_DATA_PARAMS is new for PKCS #11 v2.20 amendment 3 */
15788 +typedef struct CK_CAMELLIA_CBC_ENCRYPT_DATA_PARAMS {
15789 +    CK_BYTE      iv[16];
15790 +    CK_BYTE_PTR  pData;
15791 +    CK_ULONG     length;
15792 +} CK_CAMELLIA_CBC_ENCRYPT_DATA_PARAMS;
15794 +typedef CK_CAMELLIA_CBC_ENCRYPT_DATA_PARAMS CK_PTR CK_CAMELLIA_CBC_ENCRYPT_DATA_PARAMS_PTR;
15796 +/* CK_ARIA_CBC_ENCRYPT_DATA_PARAMS is new for PKCS #11 v2.20 amendment 3 */
15797 +typedef struct CK_ARIA_CBC_ENCRYPT_DATA_PARAMS {
15798 +    CK_BYTE      iv[16];
15799 +    CK_BYTE_PTR  pData;
15800 +    CK_ULONG     length;
15801 +} CK_ARIA_CBC_ENCRYPT_DATA_PARAMS;
15803 +typedef CK_ARIA_CBC_ENCRYPT_DATA_PARAMS CK_PTR CK_ARIA_CBC_ENCRYPT_DATA_PARAMS_PTR;
15805 +#endif
15806 Index: openssl/util/libeay.num
15807 diff -u openssl/util/libeay.num:1.7.6.1.4.1.2.1 openssl/util/libeay.num:1.7.2.2
15808 --- openssl/util/libeay.num:1.7.6.1.4.1.2.1     Thu Jul  3 12:12:37 2014
15809 +++ openssl/util/libeay.num     Thu Jul  3 12:32:04 2014
15810 @@ -3730,3 +3730,5 @@
15811  pqueue_size                             4114   EXIST::FUNCTION:
15812  OPENSSL_uni2asc                         4115   EXIST:NETWARE:FUNCTION:
15813  OPENSSL_asc2uni                         4116   EXIST:NETWARE:FUNCTION:
15814 +ENGINE_load_pk11ca                      4117   EXIST::FUNCTION:HW_PKCS11CA,ENGINE
15815 +ENGINE_load_pk11so                      4117   EXIST::FUNCTION:HW_PKCS11SO,ENGINE
15816 Index: openssl/util/mk1mf.pl
15817 diff -u openssl/util/mk1mf.pl:1.8.6.1 openssl/util/mk1mf.pl:1.8
15818 --- openssl/util/mk1mf.pl:1.8.6.1       Sun Jan 15 15:45:40 2012
15819 +++ openssl/util/mk1mf.pl       Mon Jun 13 14:25:25 2011
15820 @@ -87,6 +87,8 @@
15821         no-ecdh                                 - No ECDH
15822         no-engine                               - No engine
15823         no-hw                                   - No hw
15824 +       no-hw-pkcs11ca                          - No hw PKCS#11 CA flavor
15825 +       no-hw-pkcs11so                          - No hw PKCS#11 SO flavor
15826         nasm                                    - Use NASM for x86 asm
15827         nw-nasm                                 - Use NASM x86 asm for NetWare
15828         nw-mwasm                                - Use Metrowerks x86 asm for NetWare
15829 @@ -242,6 +244,8 @@
15830  $cflags.=" -DOPENSSL_NO_ECDH" if $no_ecdh;
15831  $cflags.=" -DOPENSSL_NO_ENGINE"   if $no_engine;
15832  $cflags.=" -DOPENSSL_NO_HW"   if $no_hw;
15833 +$cflags.=" -DOPENSSL_NO_HW_PKCS11CA"   if $no_hw_pkcs11ca;
15834 +$cflags.=" -DOPENSSL_NO_HW_PKCS11SO"   if $no_hw_pkcs11so;
15835  $cflags.=" -DOPENSSL_FIPS"    if $fips;
15836  $cflags.= " -DZLIB" if $zlib_opt;
15837  $cflags.= " -DZLIB_SHARED" if $zlib_opt == 2;
15838 @@ -316,6 +320,9 @@
15839                 $dir=$val;
15840                 }
15842 +       if ($key eq "PK11_LIB_LOCATION")
15843 +               { $cflags .= " -D$key=\\\"$val\\\"" if $val ne "";}
15845         if ($key eq "KRB5_INCLUDES")
15846                 { $cflags .= " $val";}
15848 @@ -1301,6 +1308,8 @@
15849                 "no-ecdh" => \$no_ecdh,
15850                 "no-engine" => \$no_engine,
15851                 "no-hw" => \$no_hw,
15852 +               "no-hw-pkcs11ca" => \$no_hw_pkcs11ca,
15853 +               "no-hw-pkcs11so" => \$no_hw_pkcs11so,
15854                 "just-ssl" =>
15855                         [\$no_rc2, \$no_idea, \$no_des, \$no_bf, \$no_cast,
15856                           \$no_md2, \$no_sha, \$no_mdc2, \$no_dsa, \$no_dh,
15857 Index: openssl/util/mkdef.pl
15858 diff -u openssl/util/mkdef.pl:1.6.6.1 openssl/util/mkdef.pl:1.6
15859 --- openssl/util/mkdef.pl:1.6.6.1       Sun Jan 15 15:45:40 2012
15860 +++ openssl/util/mkdef.pl       Mon Jun 13 14:25:25 2011
15861 @@ -93,7 +93,7 @@
15862                          # External "algorithms"
15863                          "FP_API", "STDIO", "SOCK", "KRB5", "DGRAM",
15864                          # Engines
15865 -                        "STATIC_ENGINE", "ENGINE", "HW", "GMP",
15866 +                        "STATIC_ENGINE", "ENGINE", "HW", "GMP", "HW_PKCS11CA", "HW_PKCS11SO",
15867                          # RFC3779 support 
15868                          "RFC3779",
15869                          # TLS extension support
15870 @@ -122,6 +122,7 @@
15871  my $no_md2; my $no_md4; my $no_md5; my $no_sha; my $no_ripemd; my $no_mdc2;
15872  my $no_rsa; my $no_dsa; my $no_dh; my $no_hmac=0; my $no_aes; my $no_krb5;
15873  my $no_ec; my $no_ecdsa; my $no_ecdh; my $no_engine; my $no_hw; my $no_camellia;
15874 +my $no_pkcs11ca; my $no_pkcs11so;
15875  my $no_seed;
15876  my $no_fp_api; my $no_static_engine; my $no_gmp; my $no_deprecated;
15877  my $no_rfc3779; my $no_tlsext; my $no_cms; my $no_capieng; my $no_jpake;
15878 @@ -214,6 +215,8 @@
15879         elsif (/^no-cms$/)      { $no_cms=1; }
15880         elsif (/^no-capieng$/)  { $no_capieng=1; }
15881         elsif (/^no-jpake$/)    { $no_jpake=1; }
15882 +       elsif (/^no-hw-pkcs11ca$/) { $no_pkcs11ca=1; }
15883 +       elsif (/^no-hw-pkcs11so$/) { $no_pkcs11so=1; }
15884         }
15887 @@ -1155,6 +1158,8 @@
15888                         if ($keyword eq "KRB5" && $no_krb5) { return 0; }
15889                         if ($keyword eq "ENGINE" && $no_engine) { return 0; }
15890                         if ($keyword eq "HW" && $no_hw) { return 0; }
15891 +                       if ($keyword eq "HW_PKCS11CA" && $no_pkcs11ca) { return 0; }
15892 +                       if ($keyword eq "HW_PKCS11SO" && $no_pkcs11so) { return 0; }
15893                         if ($keyword eq "FP_API" && $no_fp_api) { return 0; }
15894                         if ($keyword eq "STATIC_ENGINE" && $no_static_engine) { return 0; }
15895                         if ($keyword eq "GMP" && $no_gmp) { return 0; }
15896 Index: openssl/util/pl/VC-32.pl
15897 diff -u openssl/util/pl/VC-32.pl:1.6.6.1.2.1.4.1 openssl/util/pl/VC-32.pl:1.6.2.2
15898 --- openssl/util/pl/VC-32.pl:1.6.6.1.2.1.4.1    Thu Jul  3 12:12:38 2014
15899 +++ openssl/util/pl/VC-32.pl    Thu Jul  3 12:32:04 2014
15900 @@ -52,7 +52,7 @@
15901      my $f = $shlib || $fips ?' /MD':' /MT';
15902      $lib_cflag='/Zl' if (!$shlib);     # remove /DEFAULTLIBs from static lib
15903      $opt_cflags=$f.' /Ox';
15904 -    $dbg_cflags=$f.'d /Od -DDEBUG -D_DEBUG';
15905 +    $dbg_cflags=$f.'d /Od /Zi -DDEBUG -D_DEBUG';
15906      $lflags="/nologo /subsystem:console /opt:ref";
15907      }
15908  elsif ($FLAVOR =~ /CE/)