ignore some files
[tridge/bind9.git] / contrib / pkcs11-keygen / openssl-0.9.8g-patch
1 diff -r -u -N openssl-0.9.8g/Configure openssl/Configure
2 --- openssl-0.9.8g/Configure    2007-09-16 14:24:17.000000000 +0200
3 +++ openssl/Configure   2007-10-25 01:27:08.000000000 +0200
4 @@ -10,7 +10,7 @@
5  
6  # see INSTALL for instructions.
7  
8 -my $usage="Usage: Configure [no-<cipher> ...] [enable-<cipher> ...] [-Dxxx] [-lxxx] [-Lxxx] [-fxxx] [-Kxxx] [no-hw-xxx|no-hw] [[no-]threads] [[no-]shared] [[no-]zlib|zlib-dynamic] [no-asm] [no-dso] [no-krb5] [386] [--prefix=DIR] [--openssldir=OPENSSLDIR] [--with-xxx[=vvv]] [--test-sanity] os/compiler[:flags]\n";
9 +my $usage="Usage: Configure  --pk11-libname=PK11_LIB_LOCATION [no-<cipher> ...] [enable-<cipher> ...] [-Dxxx] [-lxxx] [-Lxxx] [-fxxx] [-Kxxx] [no-hw-xxx|no-hw] [[no-]threads] [[no-]shared] [[no-]zlib|zlib-dynamic] [no-asm] [no-dso] [no-krb5] [386] [--prefix=DIR] [--openssldir=OPENSSLDIR] [--with-xxx[=vvv]] [--test-sanity] os/compiler[:flags]\n";
10  
11  # Options:
12  #
13 @@ -19,6 +19,9 @@
14  # --prefix      prefix for the OpenSSL include, lib and bin directories
15  #               (Default: the OPENSSLDIR directory)
16  #
17 +# --pk11_libname  PKCS#11 library name.
18 +#               (Default: none)
19 +#
20  # --install_prefix  Additional prefix for package builders (empty by
21  #               default).  This needn't be set in advance, you can
22  #               just as well use "make INSTALL_PREFIX=/whatever install".
23 @@ -560,6 +563,8 @@
24  my $idx_ranlib = $idx++;
25  my $idx_arflags = $idx++;
26  
27 +my $pk11_libname="";
28 +
29  my $prefix="";
30  my $openssldir="";
31  my $exe_ext="";
32 @@ -738,6 +743,10 @@
33                                 {
34                                 $flags.=$_." ";
35                                 }
36 +                        elsif (/^--pk11-libname=(.*)$/)
37 +                                {
38 +                                $pk11_libname=$1;
39 +                                }
40                         elsif (/^--prefix=(.*)$/)
41                                 {
42                                 $prefix=$1;
43 @@ -861,6 +870,13 @@
44         exit 0;
45  }
46  
47 +if (! $pk11_libname)
48 +        {
49 +        print STDERR "You must set --pk11-libname for PKCS#11 library.\n";
50 +        print STDERR "See README.pkcs11 for more information.\n";
51 +        exit 1;
52 +        }
53 +
54  if ($target =~ m/^CygWin32(-.*)$/) {
55         $target = "Cygwin".$1;
56  }
57 @@ -986,6 +1002,8 @@
58  if ($flags ne "")      { $cflags="$flags$cflags"; }
59  else                   { $no_user_cflags=1;       }
60  
61 +$cflags="-DPK11_LIB_LOCATION=\"$pk11_libname\" $cflags";
62 +
63  # Kerberos settings.  The flavor must be provided from outside, either through
64  # the script "config" or manually.
65  if (!$no_krb5)
66 @@ -1319,6 +1337,7 @@
67         s/^VERSION=.*/VERSION=$version/;
68         s/^MAJOR=.*/MAJOR=$major/;
69         s/^MINOR=.*/MINOR=$minor/;
70 +       s/^PK11_LIB_LOCATION=.*/PK11_LIB_LOCATION=$pk11_libname/;
71         s/^SHLIB_VERSION_NUMBER=.*/SHLIB_VERSION_NUMBER=$shlib_version_number/;
72         s/^SHLIB_VERSION_HISTORY=.*/SHLIB_VERSION_HISTORY=$shlib_version_history/;
73         s/^SHLIB_MAJOR=.*/SHLIB_MAJOR=$shlib_major/;
74 diff -r -u -N openssl-0.9.8g/crypto/engine/cryptoki.h openssl/crypto/engine/cryptoki.h
75 --- openssl-0.9.8g/crypto/engine/cryptoki.h     1970-01-01 01:00:00.000000000 +0100
76 +++ openssl/crypto/engine/cryptoki.h    2007-10-25 01:27:09.000000000 +0200
77 @@ -0,0 +1,103 @@
78 +/*
79 + * CDDL HEADER START
80 + *
81 + * The contents of this file are subject to the terms of the
82 + * Common Development and Distribution License, Version 1.0 only
83 + * (the "License").  You may not use this file except in compliance
84 + * with the License.
85 + *
86 + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
87 + * or http://www.opensolaris.org/os/licensing.
88 + * See the License for the specific language governing permissions
89 + * and limitations under the License.
90 + *
91 + * When distributing Covered Code, include this CDDL HEADER in each
92 + * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
93 + * If applicable, add the following below this CDDL HEADER, with the
94 + * fields enclosed by brackets "[]" replaced with your own identifying
95 + * information: Portions Copyright [yyyy] [name of copyright owner]
96 + *
97 + * CDDL HEADER END
98 + */
99 +/*
100 + * Copyright 2003 Sun Microsystems, Inc.   All rights reserved.
101 + * Use is subject to license terms.
102 + */
103 +
104 +#ifndef        _CRYPTOKI_H
105 +#define        _CRYPTOKI_H
106 +
107 +#pragma ident  "@(#)cryptoki.h 1.2     05/06/08 SMI"
108 +
109 +#ifdef __cplusplus
110 +extern "C" {
111 +#endif
112 +
113 +#ifndef        CK_PTR
114 +#define        CK_PTR *
115 +#endif
116 +
117 +#ifndef CK_DEFINE_FUNCTION
118 +#define        CK_DEFINE_FUNCTION(returnType, name) returnType name
119 +#endif
120 +
121 +#ifndef CK_DECLARE_FUNCTION
122 +#define        CK_DECLARE_FUNCTION(returnType, name) returnType name
123 +#endif
124 +
125 +#ifndef CK_DECLARE_FUNCTION_POINTER
126 +#define        CK_DECLARE_FUNCTION_POINTER(returnType, name) returnType (* name)
127 +#endif
128 +
129 +#ifndef CK_CALLBACK_FUNCTION
130 +#define        CK_CALLBACK_FUNCTION(returnType, name) returnType (* name)
131 +#endif
132 +
133 +#ifndef NULL_PTR
134 +#include <unistd.h>    /* For NULL */
135 +#define        NULL_PTR NULL
136 +#endif
137 +
138 +/*
139 + * pkcs11t.h defines TRUE and FALSE in a way that upsets lint
140 + */
141 +#ifndef        CK_DISABLE_TRUE_FALSE
142 +#define        CK_DISABLE_TRUE_FALSE
143 +#ifndef        TRUE
144 +#define        TRUE    1
145 +#endif /* TRUE */
146 +#ifndef        FALSE
147 +#define        FALSE   0
148 +#endif /* FALSE */
149 +#endif /* CK_DISABLE_TRUE_FALSE */
150 +
151 +#undef CK_PKCS11_FUNCTION_INFO
152 +
153 +#include "pkcs11.h"
154 +
155 +/* Solaris specific functions */
156 +
157 +#include <stdlib.h>
158 +
159 +/*
160 + * SUNW_C_GetMechSession will initialize the framework and do all
161 + * the necessary PKCS#11 calls to create a session capable of
162 + * providing operations on the requested mechanism
163 + */
164 +CK_RV SUNW_C_GetMechSession(CK_MECHANISM_TYPE mech,
165 +    CK_SESSION_HANDLE_PTR hSession);
166 +
167 +/*
168 + * SUNW_C_KeyToObject will create a secret key object for the given
169 + * mechanism from the rawkey data.
170 + */
171 +CK_RV SUNW_C_KeyToObject(CK_SESSION_HANDLE hSession,
172 +    CK_MECHANISM_TYPE mech, const void *rawkey, size_t rawkey_len,
173 +    CK_OBJECT_HANDLE_PTR obj);
174 +
175 +
176 +#ifdef __cplusplus
177 +}
178 +#endif
179 +
180 +#endif /* _CRYPTOKI_H */
181 diff -r -u -N openssl-0.9.8g/crypto/engine/eng_all.c openssl/crypto/engine/eng_all.c
182 --- openssl-0.9.8g/crypto/engine/eng_all.c      2007-01-04 23:55:25.000000000 +0100
183 +++ openssl/crypto/engine/eng_all.c     2007-10-25 01:27:09.000000000 +0200
184 @@ -107,6 +107,9 @@
185  #if defined(__OpenBSD__) || defined(__FreeBSD__)
186         ENGINE_load_cryptodev();
187  #endif
188 +#ifndef OPENSSL_NO_HW_PKCS11
189 +       ENGINE_load_pk11();
190 +#endif
191  #endif
192         }
193  
194 diff -r -u -N openssl-0.9.8g/crypto/engine/engine.h openssl/crypto/engine/engine.h
195 --- openssl-0.9.8g/crypto/engine/engine.h       2005-11-06 18:48:59.000000000 +0100
196 +++ openssl/crypto/engine/engine.h      2007-10-25 01:27:09.000000000 +0200
197 @@ -332,6 +332,7 @@
198  void ENGINE_load_ubsec(void);
199  #endif
200  void ENGINE_load_cryptodev(void);
201 +void ENGINE_load_pk11(void);
202  void ENGINE_load_padlock(void);
203  void ENGINE_load_builtin_engines(void);
204  
205 diff -r -u -N openssl-0.9.8g/crypto/engine/hw_pk11.c openssl/crypto/engine/hw_pk11.c
206 --- openssl-0.9.8g/crypto/engine/hw_pk11.c      1970-01-01 01:00:00.000000000 +0100
207 +++ openssl/crypto/engine/hw_pk11.c     2007-10-29 23:31:11.000000000 +0100
208 @@ -0,0 +1,2153 @@
209 +/*
210 + * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
211 + * Use is subject to license terms.
212 + */
213 +
214 +#pragma ident  "@(#)hw_pk11.c  1.12    07/07/05 SMI"
215 +
216 +/* crypto/engine/hw_pk11.c */
217 +/* This product includes software developed by the OpenSSL Project for 
218 + * use in the OpenSSL Toolkit (http://www.openssl.org/).
219 + *
220 + * This project also referenced hw_pkcs11-0.9.7b.patch written by 
221 + * Afchine Madjlessi.
222 + */
223 +/* ====================================================================
224 + * Copyright (c) 2000-2001 The OpenSSL Project.  All rights reserved.
225 + *
226 + * Redistribution and use in source and binary forms, with or without
227 + * modification, are permitted provided that the following conditions
228 + * are met:
229 + *
230 + * 1. Redistributions of source code must retain the above copyright
231 + *    notice, this list of conditions and the following disclaimer. 
232 + *
233 + * 2. Redistributions in binary form must reproduce the above copyright
234 + *    notice, this list of conditions and the following disclaimer in
235 + *    the documentation and/or other materials provided with the
236 + *    distribution.
237 + *
238 + * 3. All advertising materials mentioning features or use of this
239 + *    software must display the following acknowledgment:
240 + *    "This product includes software developed by the OpenSSL Project
241 + *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
242 + *
243 + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
244 + *    endorse or promote products derived from this software without
245 + *    prior written permission. For written permission, please contact
246 + *    licensing@OpenSSL.org.
247 + *
248 + * 5. Products derived from this software may not be called "OpenSSL"
249 + *    nor may "OpenSSL" appear in their names without prior written
250 + *    permission of the OpenSSL Project.
251 + *
252 + * 6. Redistributions of any form whatsoever must retain the following
253 + *    acknowledgment:
254 + *    "This product includes software developed by the OpenSSL Project
255 + *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
256 + *
257 + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
258 + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
259 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
260 + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
261 + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
262 + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
263 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
264 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
265 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
266 + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
267 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
268 + * OF THE POSSIBILITY OF SUCH DAMAGE.
269 + * ====================================================================
270 + *
271 + * This product includes cryptographic software written by Eric Young
272 + * (eay@cryptsoft.com).  This product includes software written by Tim
273 + * Hudson (tjh@cryptsoft.com).
274 + *
275 + */
276 +
277 +#include <stdio.h>
278 +#include <assert.h>
279 +#include <stdlib.h>
280 +#include <string.h>
281 +#include <sys/types.h>
282 +#include <unistd.h>
283 +
284 +#include <openssl/e_os2.h>
285 +#include <openssl/engine.h>
286 +#include <openssl/dso.h>
287 +#include <openssl/err.h>
288 +#include <openssl/bn.h>
289 +#include <openssl/md5.h>
290 +#include <openssl/pem.h>
291 +#include <openssl/rsa.h>
292 +#include <openssl/rand.h>
293 +#include <openssl/objects.h>
294 +#include <openssl/x509.h>
295 +#include <cryptlib.h>
296 +
297 +#ifndef OPENSSL_NO_HW
298 +#ifndef OPENSSL_NO_HW_PK11
299 +
300 +#undef DEBUG_SLOT_SELECTION
301 +
302 +#include "cryptoki.h"
303 +#include "pkcs11.h"
304 +#include "hw_pk11_err.c"
305 +
306 +
307 +/* The head of the free PK11 session list */
308 +static struct PK11_SESSION_st *free_session = NULL;
309 +
310 +/* Create all secret key objects in a global session so that they are available
311 + * to use for other sessions. These other sessions may be opened or closed
312 + * without losing the secret key objects */
313 +static CK_SESSION_HANDLE       global_session = CK_INVALID_HANDLE;
314 +
315 +/* ENGINE level stuff */
316 +static int pk11_init(ENGINE *e);
317 +static int pk11_library_init(ENGINE *e);
318 +static int pk11_finish(ENGINE *e);
319 +static int pk11_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)());
320 +static int pk11_destroy(ENGINE *e);
321 +
322 +/* RAND stuff */
323 +static void pk11_rand_seed(const void *buf, int num);
324 +static void pk11_rand_add(const void *buf, int num, double add_entropy);
325 +static void pk11_rand_cleanup(void);
326 +static int pk11_rand_bytes(unsigned char *buf, int num);
327 +static int pk11_rand_status(void);
328 +
329 +/* These functions are also used in other files */
330 +PK11_SESSION *pk11_get_session();
331 +void pk11_return_session(PK11_SESSION *sp);
332 +int pk11_destroy_rsa_key_objects(PK11_SESSION *session);
333 +int pk11_destroy_dsa_key_objects(PK11_SESSION *session);
334 +int pk11_destroy_dh_key_objects(PK11_SESSION *session);
335 +
336 +/* Local helper functions */
337 +static int pk11_free_all_sessions();
338 +static int pk11_setup_session(PK11_SESSION *sp);
339 +static int pk11_destroy_cipher_key_objects(PK11_SESSION *session);
340 +static int pk11_destroy_object(CK_SESSION_HANDLE session, 
341 +       CK_OBJECT_HANDLE oh);
342 +static const char *get_PK11_LIBNAME(void);
343 +static void free_PK11_LIBNAME(void);
344 +static long set_PK11_LIBNAME(const char *name);
345 +
346 +/* Symmetric cipher and digest support functions */
347 +static int cipher_nid_to_pk11(int nid);
348 +static int pk11_usable_ciphers(const int **nids);
349 +static int pk11_usable_digests(const int **nids);
350 +static int pk11_cipher_init(EVP_CIPHER_CTX *ctx, const unsigned char *key,
351 +       const unsigned char *iv, int enc);
352 +static int pk11_cipher_final(PK11_SESSION *sp);
353 +static int pk11_cipher_do_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
354 +       const unsigned char *in, unsigned int inl);
355 +static int pk11_cipher_cleanup(EVP_CIPHER_CTX *ctx);
356 +static int pk11_engine_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
357 +       const int **nids, int nid);
358 +static int pk11_engine_digests(ENGINE *e, const EVP_MD **digest,
359 +       const int **nids, int nid);
360 +static CK_OBJECT_HANDLE pk11_get_cipher_key(EVP_CIPHER_CTX *ctx, 
361 +       const unsigned char *key, CK_KEY_TYPE key_type, PK11_SESSION *sp);
362 +static void check_new_cipher_key(PK11_SESSION *sp, const unsigned char *key);
363 +static int md_nid_to_pk11(int nid);
364 +static int pk11_digest_init(EVP_MD_CTX *ctx);
365 +static int pk11_digest_update(EVP_MD_CTX *ctx,const void *data,
366 +       size_t count);
367 +static int pk11_digest_final(EVP_MD_CTX *ctx,unsigned char *md);
368 +static int pk11_digest_copy(EVP_MD_CTX *to,const EVP_MD_CTX *from);
369 +static int pk11_digest_cleanup(EVP_MD_CTX *ctx);
370 +
371 +static int pk11_choose_slot();
372 +static int pk11_count_symmetric_cipher(int slot_id, CK_MECHANISM_TYPE mech,
373 +    int *current_slot_n_cipher, int *local_cipher_nids, int id);
374 +static int pk11_count_digest(int slot_id, CK_MECHANISM_TYPE mech,
375 +    int *current_slot_n_digest, int *local_digest_nids, int id);
376 +
377 +/* Index for the supported ciphers */
378 +#define PK11_DES_CBC           0
379 +#define PK11_DES3_CBC          1
380 +#define PK11_AES_CBC           2
381 +#define PK11_RC4               3
382 +
383 +/* Index for the supported digests */
384 +#define PK11_MD5               0
385 +#define PK11_SHA1              1
386 +
387 +#define PK11_CIPHER_MAX                4       /* Max num of ciphers supported */
388 +#define PK11_DIGEST_MAX                2       /* Max num of digests supported */
389 +
390 +#define PK11_KEY_LEN_MAX       24
391 +
392 +static int cipher_nids[PK11_CIPHER_MAX];
393 +static int digest_nids[PK11_DIGEST_MAX];
394 +static int cipher_count                = 0;
395 +static int digest_count                = 0;
396 +static CK_BBOOL pk11_have_rsa  = CK_FALSE;
397 +static CK_BBOOL pk11_have_dsa  = CK_FALSE;
398 +static CK_BBOOL pk11_have_dh   = CK_FALSE;
399 +static CK_BBOOL pk11_have_random = CK_FALSE;
400 +
401 +typedef struct PK11_CIPHER_st 
402 +       {
403 +       int             id;
404 +       int             nid;
405 +       int             ivmax;
406 +       int             key_len;
407 +       CK_KEY_TYPE     key_type;
408 +       CK_MECHANISM_TYPE       mech_type;
409 +       } PK11_CIPHER;
410 +
411 +static PK11_CIPHER ciphers[] = 
412 +       {
413 +       {PK11_DES_CBC,  NID_des_cbc,      8,  8,   CKK_DES,  CKM_DES_CBC, },
414 +       {PK11_DES3_CBC, NID_des_ede3_cbc, 8,  24,  CKK_DES3, CKM_DES3_CBC, },
415 +       {PK11_AES_CBC,  NID_aes_128_cbc,  16, 16,  CKK_AES,  CKM_AES_CBC, },
416 +       {PK11_RC4,      NID_rc4,          0,  16,  CKK_RC4,  CKM_RC4, },
417 +       };
418 +
419 +typedef struct PK11_DIGEST_st
420 +       {
421 +       int             id;
422 +       int             nid;
423 +       CK_MECHANISM_TYPE       mech_type;
424 +       } PK11_DIGEST;
425 +
426 +static PK11_DIGEST digests[] = 
427 +       {
428 +       {PK11_MD5,      NID_md5,        CKM_MD5, },
429 +       {PK11_SHA1,     NID_sha1,       CKM_SHA_1, },
430 +       {0,             NID_undef,      0xFFFF, },
431 +       };
432 +
433 +/* Structure to be used for the cipher_data/md_data in 
434 + * EVP_CIPHER_CTX/EVP_MD_CTX structures in order to use the same 
435 + * pk11 session in multiple cipher_update calls
436 + */
437 +typedef struct PK11_CIPHER_STATE_st
438 +       {
439 +       PK11_SESSION    *sp;
440 +       } PK11_CIPHER_STATE;
441 +
442 +
443 +/* libcrypto EVP stuff - this is how we get wired to EVP so the engine
444 + * gets called when libcrypto requests a cipher NID.
445 + * Note how the PK11_CIPHER_STATE is used here.
446 + */
447 +
448 +/* DES CBC EVP */
449 +static const EVP_CIPHER pk11_des_cbc = 
450 +       {
451 +       NID_des_cbc,
452 +       8, 8, 8,
453 +       EVP_CIPH_CBC_MODE,
454 +       pk11_cipher_init,
455 +       pk11_cipher_do_cipher,
456 +       pk11_cipher_cleanup,
457 +       sizeof(PK11_CIPHER_STATE),
458 +       EVP_CIPHER_set_asn1_iv,
459 +       EVP_CIPHER_get_asn1_iv,
460 +       NULL
461 +       };
462 +
463 +/* 3DES CBC EVP */
464 +static const EVP_CIPHER pk11_3des_cbc = 
465 +       {
466 +       NID_des_ede3_cbc,
467 +       8, 24, 8,
468 +       EVP_CIPH_CBC_MODE,
469 +       pk11_cipher_init,
470 +       pk11_cipher_do_cipher,
471 +       pk11_cipher_cleanup,
472 +       sizeof(PK11_CIPHER_STATE),
473 +       EVP_CIPHER_set_asn1_iv,
474 +       EVP_CIPHER_get_asn1_iv,
475 +       NULL
476 +       };
477 +
478 +static const EVP_CIPHER pk11_aes_cbc = 
479 +       {
480 +       NID_aes_128_cbc,
481 +       16, 16, 16,
482 +       EVP_CIPH_CBC_MODE,
483 +       pk11_cipher_init,
484 +       pk11_cipher_do_cipher,
485 +       pk11_cipher_cleanup,
486 +       sizeof(PK11_CIPHER_STATE),
487 +       EVP_CIPHER_set_asn1_iv,
488 +       EVP_CIPHER_get_asn1_iv,
489 +       NULL
490 +       };
491 +
492 +static const EVP_CIPHER pk11_rc4 =
493 +       {
494 +       NID_rc4,
495 +       1,16,0,
496 +       EVP_CIPH_VARIABLE_LENGTH,
497 +       pk11_cipher_init,
498 +       pk11_cipher_do_cipher,
499 +       pk11_cipher_cleanup,
500 +       sizeof(PK11_CIPHER_STATE),
501 +       NULL,
502 +       NULL,
503 +       NULL
504 +       };
505 +
506 +static const EVP_MD pk11_md5 =
507 +       {
508 +       NID_md5,
509 +       NID_md5WithRSAEncryption,
510 +       MD5_DIGEST_LENGTH,
511 +       0,
512 +       pk11_digest_init,
513 +       pk11_digest_update,
514 +       pk11_digest_final,
515 +       pk11_digest_copy,
516 +       pk11_digest_cleanup,
517 +       EVP_PKEY_RSA_method,
518 +       MD5_CBLOCK,
519 +       sizeof(PK11_CIPHER_STATE),
520 +       };
521 +
522 +static const EVP_MD pk11_sha1 =
523 +       {
524 +       NID_sha1,
525 +       NID_sha1WithRSAEncryption,
526 +       SHA_DIGEST_LENGTH,
527 +       0,
528 +       pk11_digest_init,
529 +       pk11_digest_update,
530 +       pk11_digest_final,
531 +       pk11_digest_copy,
532 +       pk11_digest_cleanup,
533 +       EVP_PKEY_RSA_method,
534 +       SHA_CBLOCK,
535 +       sizeof(PK11_CIPHER_STATE),
536 +       };
537 +
538 +/* Initialization function. Sets up various pk11 library components.
539 + */
540 +/* The definitions for control commands specific to this engine
541 + */
542 +#define PK11_CMD_SO_PATH               ENGINE_CMD_BASE
543 +#define PK11_CMD_PIN                   (ENGINE_CMD_BASE+1)
544 +#define PK11_CMD_SLOT                  (ENGINE_CMD_BASE+2)
545 +static const ENGINE_CMD_DEFN pk11_cmd_defns[] =
546 +       {
547 +               {
548 +               PK11_CMD_SO_PATH,
549 +               "SO_PATH",
550 +               "Specifies the path to the 'pkcs#11' shared library",
551 +               ENGINE_CMD_FLAG_STRING
552 +               },
553 +               {
554 +               PK11_CMD_PIN,
555 +               "PIN",
556 +               "Specifies the pin code",
557 +               ENGINE_CMD_FLAG_STRING
558 +               },
559 +               {
560 +               PK11_CMD_SLOT,
561 +               "SLOT",
562 +               "Specifies the slot (default is auto select)",
563 +               ENGINE_CMD_FLAG_NUMERIC,
564 +               },
565 +               {0, NULL, NULL, 0}
566 +       };
567 +
568 +
569 +static RAND_METHOD pk11_random =
570 +       {
571 +       pk11_rand_seed,
572 +       pk11_rand_bytes,
573 +       pk11_rand_cleanup,
574 +       pk11_rand_add,
575 +       pk11_rand_bytes,
576 +       pk11_rand_status
577 +       };
578 +
579 +
580 +/* Constants used when creating the ENGINE
581 + */
582 +static const char *engine_pk11_id = "pkcs11";
583 +static const char *engine_pk11_name = "PKCS #11 engine support";
584 +
585 +CK_FUNCTION_LIST_PTR pFuncList = NULL;
586 +static const char PK11_GET_FUNCTION_LIST[] = "C_GetFunctionList";
587 +
588 +/* Cryptoki library
589 + */
590 +static const char def_PK11_LIBNAME[] = PK11_LIB_LOCATION;
591 +
592 +static CK_BBOOL true = TRUE;
593 +static CK_BBOOL false = FALSE;
594 +static CK_SLOT_ID SLOTID = 0;
595 +static int pk11_auto_slot = 1;
596 +char *pk11_pin;
597 +static int pk11_library_initialized = 0;
598 +
599 +static DSO *pk11_dso = NULL;
600 +
601 +/*
602 + * This internal function is used by ENGINE_pk11() and "dynamic" ENGINE support.
603 + */
604 +static int bind_pk11(ENGINE *e)
605 +       {
606 +       const RSA_METHOD *rsa = NULL;
607 +       RSA_METHOD *pk11_rsa = PK11_RSA();
608 +
609 +       if (!pk11_library_initialized)
610 +               pk11_library_init(e);
611 +
612 +       if(!ENGINE_set_id(e, engine_pk11_id) ||
613 +          !ENGINE_set_name(e, engine_pk11_name) ||
614 +          !ENGINE_set_ciphers(e, pk11_engine_ciphers) ||
615 +          !ENGINE_set_digests(e, pk11_engine_digests))
616 +               return 0;
617 +#ifndef OPENSSL_NO_RSA
618 +       if(pk11_have_rsa == CK_TRUE)
619 +               {
620 +               if(!ENGINE_set_RSA(e, PK11_RSA()) ||
621 +                  !ENGINE_set_load_privkey_function(e, pk11_load_privkey) ||
622 +                  !ENGINE_set_load_pubkey_function(e, pk11_load_pubkey))
623 +                       return 0;
624 +#ifdef DEBUG_SLOT_SELECTION
625 +               fprintf(stderr, "OPENSSL_PKCS#11_ENGINE: registered RSA\n");
626 +#endif /* DEBUG_SLOT_SELECTION */
627 +               }
628 +#endif
629 +#ifndef OPENSSL_NO_DSA
630 +       if(pk11_have_dsa == CK_TRUE)
631 +               {       
632 +               if (!ENGINE_set_DSA(e, PK11_DSA()))
633 +                       return 0;
634 +#ifdef DEBUG_SLOT_SELECTION
635 +               fprintf(stderr, "OPENSSL_PKCS#11_ENGINE: registered DSA\n");
636 +#endif /* DEBUG_SLOT_SELECTION */
637 +               }
638 +#endif
639 +#ifndef OPENSSL_NO_DH
640 +       if(pk11_have_dh == CK_TRUE)
641 +               {
642 +               if (!ENGINE_set_DH(e, PK11_DH()))
643 +                       return 0;
644 +#ifdef DEBUG_SLOT_SELECTION
645 +               fprintf(stderr, "OPENSSL_PKCS#11_ENGINE: registered DH\n");
646 +#endif /* DEBUG_SLOT_SELECTION */
647 +               }
648 +#endif
649 +       if(pk11_have_random)
650 +               {
651 +               if(!ENGINE_set_RAND(e, &pk11_random))
652 +                       return 0;
653 +#ifdef DEBUG_SLOT_SELECTION
654 +               fprintf(stderr, "OPENSSL_PKCS#11_ENGINE: registered random\n");
655 +#endif /* DEBUG_SLOT_SELECTION */
656 +               }
657 +       if(!ENGINE_set_init_function(e, pk11_init) ||
658 +          !ENGINE_set_destroy_function(e, pk11_destroy) ||
659 +          !ENGINE_set_finish_function(e, pk11_finish) ||
660 +          !ENGINE_set_ctrl_function(e, pk11_ctrl) ||
661 +          !ENGINE_set_cmd_defns(e, pk11_cmd_defns))
662 +               return 0;
663 +
664 +/* Apache calls OpenSSL function RSA_blinding_on() once during startup
665 + * which in turn calls bn_mod_exp. Since we do not implement bn_mod_exp
666 + * here, we wire it back to the OpenSSL software implementation. 
667 + * Since it is used only once, performance is not a concern. */
668 +#ifndef OPENSSL_NO_RSA
669 +        rsa = RSA_PKCS1_SSLeay();
670 +        pk11_rsa->rsa_mod_exp = rsa->rsa_mod_exp;
671 +        pk11_rsa->bn_mod_exp = rsa->bn_mod_exp;
672 +#endif
673 +
674 +       /* Ensure the pk11 error handling is set up */
675 +       ERR_load_pk11_strings();
676 +       
677 +       return 1;
678 +       }
679 +
680 +/* Dynamic engine support is disabled at a higher level for Solaris
681 + */
682 +#ifdef ENGINE_DYNAMIC_SUPPORT
683 +static int bind_helper(ENGINE *e, const char *id)
684 +       {
685 +       if (id && (strcmp(id, engine_pk11_id) != 0))
686 +               return 0;
687 +
688 +       if (!bind_pk11(e))
689 +               return 0;
690 +
691 +       return 1;
692 +       }          
693 +
694 +IMPLEMENT_DYNAMIC_CHECK_FN()
695 +IMPLEMENT_DYNAMIC_BIND_FN(bind_helper)
696 +
697 +#else
698 +static ENGINE *engine_pk11(void)
699 +       {
700 +       ENGINE *ret = ENGINE_new();
701 +
702 +       if (!ret)
703 +               return NULL;
704 +
705 +       if (!bind_pk11(ret))
706 +               {
707 +               ENGINE_free(ret);
708 +               return NULL;
709 +               }
710 +
711 +       return ret;
712 +       }
713 +
714 +void ENGINE_load_pk11(void)
715 +       {
716 +       ENGINE *e_pk11 = NULL;
717 +
718 +       /* Do not use dynamic PKCS#11 library on Solaris due to 
719 +        * security reasons. We will link it in statically
720 +        */
721 +       /* Attempt to load PKCS#11 library 
722 +        */
723 +       if (!pk11_dso)
724 +               pk11_dso = DSO_load(NULL, get_PK11_LIBNAME(), NULL, 0);
725 +
726 +       if (pk11_dso == NULL)
727 +               {
728 +               PK11err(PK11_F_LOAD, PK11_R_DSO_FAILURE);
729 +               return;
730 +               }
731 +
732 +       e_pk11 = engine_pk11();
733 +       if (!e_pk11) 
734 +               {
735 +               DSO_free(pk11_dso);
736 +               pk11_dso = NULL;
737 +               return;
738 +               }
739 +
740 +       /* At this point, the pk11 shared library is either dynamically
741 +        * loaded or statically linked in. So, initialize the pk11 
742 +        * library before calling ENGINE_set_default since the latter 
743 +        * needs cipher and digest algorithm information
744 +        */
745 +       if (!pk11_library_init(e_pk11))
746 +               {
747 +               DSO_free(pk11_dso);
748 +               pk11_dso = NULL;
749 +               ENGINE_free(e_pk11);
750 +               return;
751 +               }
752 +
753 +       ENGINE_add(e_pk11);
754 +
755 +       ENGINE_free(e_pk11);
756 +       ERR_clear_error();
757 +       }
758 +#endif
759 +
760 +/* These are the static string constants for the DSO file name and 
761 + * the function symbol names to bind to. 
762 + */
763 +static const char *PK11_LIBNAME = NULL;
764 +
765 +static const char *get_PK11_LIBNAME(void)
766 +       {
767 +       if (PK11_LIBNAME)
768 +               return PK11_LIBNAME;
769 +
770 +       return def_PK11_LIBNAME;
771 +       }
772 +
773 +static void free_PK11_LIBNAME(void)
774 +       {
775 +       if (PK11_LIBNAME)
776 +               OPENSSL_free((void*)PK11_LIBNAME);
777 +
778 +       PK11_LIBNAME = NULL;
779 +       }
780 +
781 +static long set_PK11_LIBNAME(const char *name)
782 +       {
783 +       free_PK11_LIBNAME();
784 +
785 +       return ((PK11_LIBNAME = BUF_strdup(name)) != NULL ? 1 : 0);
786 +       }
787 +
788 +/* Initialization function for the pk11 engine */
789 +static int pk11_init(ENGINE *e)
790 +{
791 +       return pk11_library_init(e);
792 +}
793 +
794 +/* Initialization function. Sets up various pk11 library components.
795 + * It selects a slot based on predefined critiera. In the process, it also
796 + * count how many ciphers and digests to support. Since the cipher and
797 + * digest information is needed when setting default engine, this function
798 + * needs to be called before calling ENGINE_set_default.
799 + */
800 +static int pk11_library_init(ENGINE *e)
801 +       {
802 +       CK_C_GetFunctionList p;
803 +       CK_RV rv = CKR_OK;
804 +       CK_INFO info;
805 +       CK_ULONG ul_state_len;
806 +       char tmp_buf[20];
807 +
808 +       if (pk11_library_initialized)
809 +               return 1;
810 +       
811 +       if (pk11_dso == NULL)
812 +               {
813 +               PK11err(PK11_F_LIBRARY_INIT, PK11_R_DSO_FAILURE);
814 +               goto err;
815 +               }
816 +
817 +       /* get the C_GetFunctionList function from the loaded library
818 +        */
819 +       p = (CK_C_GetFunctionList)DSO_bind_func(pk11_dso, 
820 +               PK11_GET_FUNCTION_LIST);
821 +       if ( !p )
822 +               {
823 +               PK11err(PK11_F_LIBRARY_INIT, PK11_R_DSO_FAILURE);
824 +               goto err;
825 +               }
826
827 +       /* get the full function list from the loaded library 
828 +        */
829 +       rv = p(&pFuncList);
830 +       if (rv != CKR_OK)
831 +               {
832 +               PK11err(PK11_F_LIBRARY_INIT, PK11_R_DSO_FAILURE);
833 +               snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
834 +               ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
835 +               goto err;
836 +               }
837
838 +       rv = pFuncList->C_Initialize(NULL_PTR);
839 +       if ((rv != CKR_OK) && (rv != CKR_CRYPTOKI_ALREADY_INITIALIZED))
840 +               {
841 +               PK11err(PK11_F_LIBRARY_INIT, PK11_R_INITIALIZE);
842 +               snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
843 +               ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
844 +               goto err;
845 +               }
846 +
847 +       rv = pFuncList->C_GetInfo(&info);
848 +       if (rv != CKR_OK) 
849 +               {
850 +               PK11err(PK11_F_LIBRARY_INIT, PK11_R_GETINFO);
851 +               snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
852 +               ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
853 +               goto err;
854 +               }
855 +
856 +       if (pk11_choose_slot() == 0)
857 +               goto err;
858 +
859 +       if (global_session == CK_INVALID_HANDLE)
860 +               {
861 +               /* Open the global_session for the new process */
862 +               rv = pFuncList->C_OpenSession(SLOTID, CKF_SERIAL_SESSION,
863 +                       NULL_PTR, NULL_PTR, &global_session);
864 +               if (rv != CKR_OK)
865 +                       {
866 +                       PK11err(PK11_F_LIBRARY_INIT, PK11_R_OPENSESSION);
867 +                       snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
868 +                       ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
869 +                       goto err;
870 +                       }
871 +               }
872 +
873 +       /* Disable digest if C_GetOperationState is not supported since
874 +        * this function is required by OpenSSL digest copy function */
875 +       if (pFuncList->C_GetOperationState(global_session, NULL, &ul_state_len)
876 +                       == CKR_FUNCTION_NOT_SUPPORTED)
877 +               digest_count = 0;
878 +
879 +       pk11_library_initialized = 1;
880 +       return 1;
881 +
882 +err:
883 +
884 +       return 0;
885 +       }
886 +
887 +/* Destructor (complements the "ENGINE_pk11()" constructor)
888 + */
889 +static int pk11_destroy(ENGINE *e)
890 +       {
891 +       free_PK11_LIBNAME();
892 +       ERR_unload_pk11_strings();
893 +       if (pk11_pin) {
894 +               memset(pk11_pin, 0, strlen(pk11_pin));
895 +               OPENSSL_free((void*)pk11_pin);
896 +       }
897 +       pk11_pin = NULL;
898 +       return 1;
899 +       }
900 +
901 +/* Termination function to clean up the session, the token, and 
902 + * the pk11 library.
903 + */
904 +static int pk11_finish(ENGINE *e)
905 +       {
906 +
907 +       if (pk11_pin) {
908 +               memset(pk11_pin, 0, strlen(pk11_pin));
909 +               OPENSSL_free((void*)pk11_pin);
910 +       }
911 +       pk11_pin = NULL;
912 +
913 +       if (pk11_dso == NULL)
914 +               {
915 +               PK11err(PK11_F_FINISH, PK11_R_NOT_LOADED);
916 +               goto err;
917 +               }
918 +
919 +       assert(pFuncList != NULL);
920 +
921 +       if (pk11_free_all_sessions() == 0)
922 +               goto err;
923 +
924 +       pFuncList->C_CloseSession(global_session);
925 +       
926 +       /* Since we are part of a library (libcrypto.so), calling this
927 +        * function may have side-effects.
928 +       pFuncList->C_Finalize(NULL);
929 +        */
930 +
931 +       if (!DSO_free(pk11_dso))
932 +               {
933 +               PK11err(PK11_F_FINISH, PK11_R_DSO_FAILURE);
934 +               goto err;
935 +               }
936 +       pk11_dso = NULL;
937 +       pFuncList = NULL;
938 +       pk11_library_initialized = 0;
939 +
940 +       return 1;
941 +
942 +err:
943 +       return 0;
944 +       }
945 +
946 +/* Standard engine interface function to set the dynamic library path */
947 +static int pk11_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)())
948 +       {
949 +       int initialized = ((pk11_dso == NULL) ? 0 : 1);
950 +
951 +       switch(cmd)
952 +               {
953 +       case PK11_CMD_SO_PATH:
954 +               if (p == NULL)
955 +                       {
956 +                       PK11err(PK11_F_CTRL, ERR_R_PASSED_NULL_PARAMETER);
957 +                       return 0;
958 +                       }
959 +
960 +               if (initialized)
961 +                       {
962 +                       PK11err(PK11_F_CTRL, PK11_R_ALREADY_LOADED);
963 +                       return 0;
964 +                       }
965 +
966 +               return set_PK11_LIBNAME((const char*)p);
967 +       case PK11_CMD_PIN:
968 +               if (pk11_pin) {
969 +                       memset(pk11_pin, 0, strlen(pk11_pin));
970 +                       OPENSSL_free((void*)pk11_pin);
971 +               }
972 +               pk11_pin = NULL;
973 +
974 +               if (p == NULL)
975 +                       {
976 +                       PK11err(PK11_F_CTRL, ERR_R_PASSED_NULL_PARAMETER);
977 +                       return 0;
978 +                       }
979 +
980 +               pk11_pin = BUF_strdup(p);
981 +               if (pk11_pin == NULL)
982 +                       {
983 +                       PK11err(PK11_F_GET_SESSION, PK11_R_MALLOC_FAILURE);
984 +                       return 0;
985 +                       }
986 +               return 1;
987 +       case PK11_CMD_SLOT:
988 +               SLOTID = (CK_SLOT_ID)i;
989 +#ifdef DEBUG_SLOT_SELECTION
990 +               fprintf(stderr, "OPENSSL_PKCS#11_ENGINE: slot set\n");
991 +#endif
992 +               return 1;
993 +       default:
994 +               break;
995 +               }
996 +
997 +       PK11err(PK11_F_CTRL,PK11_R_CTRL_COMMAND_NOT_IMPLEMENTED);
998 +
999 +       return 0;
1000 +       }
1001 +
1002 +
1003 +/* Required function by the engine random interface. It does nothing here
1004 + */
1005 +static void pk11_rand_cleanup(void)
1006 +       {
1007 +       return;
1008 +       }
1009 +
1010 +static void pk11_rand_add(const void *buf, int num, double add)
1011 +       {
1012 +       PK11_SESSION *sp;
1013 +
1014 +       if ((sp = pk11_get_session()) == NULL)
1015 +               return;
1016 +
1017 +       /* Ignore any errors (e.g. CKR_RANDOM_SEED_NOT_SUPPORTED) since 
1018 +        * the calling functions do not care anyway
1019 +        */
1020 +       pFuncList->C_SeedRandom(sp->session, (unsigned char *) buf, num);
1021 +       pk11_return_session(sp);
1022 +
1023 +       return;
1024 +       }
1025 +
1026 +static void pk11_rand_seed(const void *buf, int num)
1027 +       {
1028 +       pk11_rand_add(buf, num, 0);
1029 +       }
1030 +
1031 +static int pk11_rand_bytes(unsigned char *buf, int num)
1032 +       {
1033 +       CK_RV rv;
1034 +       PK11_SESSION *sp;
1035 +       
1036 +       if ((sp = pk11_get_session()) == NULL)
1037 +               return 0;
1038 +       
1039 +       rv = pFuncList->C_GenerateRandom(sp->session, buf, num);
1040 +       if (rv != CKR_OK)
1041 +               {
1042 +               char tmp_buf[20];
1043 +               PK11err(PK11_F_RAND_BYTES, PK11_R_GENERATERANDOM);
1044 +               snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
1045 +               ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
1046 +               pk11_return_session(sp);
1047 +               return 0;
1048 +               }
1049 +
1050 +       pk11_return_session(sp);
1051 +       return 1;
1052 +       }
1053 +
1054 +
1055 +/* Required function by the engine random interface. It does nothing here
1056 + */
1057 +static int pk11_rand_status(void)
1058 +       {
1059 +       return 1;
1060 +       }
1061 +
1062 +
1063 +PK11_SESSION *pk11_get_session()
1064 +       {
1065 +       PK11_SESSION *sp, *sp1;
1066 +       CK_RV rv;
1067 +       char tmp_buf[20];
1068 +
1069 +       CRYPTO_w_lock(CRYPTO_LOCK_PK11_ENGINE);
1070 +       if ((sp = free_session) == NULL)
1071 +               {
1072 +               if ((sp = OPENSSL_malloc(sizeof(PK11_SESSION))) == NULL)
1073 +                       {
1074 +                       PK11err(PK11_F_GET_SESSION, 
1075 +                               PK11_R_MALLOC_FAILURE);
1076 +                       goto err;
1077 +                       }
1078 +               memset(sp, 0, sizeof(PK11_SESSION));
1079 +               }
1080 +       else
1081 +               {
1082 +               free_session = sp->next;
1083 +               }
1084 +
1085 +       if (sp->pid != 0 && sp->pid != getpid())
1086 +               {
1087 +               /* We are a new process and thus need to free any inherated
1088 +                * PK11_SESSION objects.
1089 +                */
1090 +               while ((sp1 = free_session) != NULL)
1091 +                       {
1092 +                       free_session = sp1->next;
1093 +                       OPENSSL_free(sp1);
1094 +                       }
1095 +
1096 +               /* Initialize the process */
1097 +               rv = pFuncList->C_Initialize(NULL_PTR);
1098 +               if ((rv != CKR_OK) && (rv != CKR_CRYPTOKI_ALREADY_INITIALIZED))
1099 +                       {
1100 +                       PK11err(PK11_F_GET_SESSION, PK11_R_INITIALIZE);
1101 +                       snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
1102 +                       ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
1103 +                       OPENSSL_free(sp);
1104 +                       sp = NULL;
1105 +                       goto err;
1106 +                       }
1107 +
1108 +               /* Choose slot here since the slot table is different on 
1109 +                * this process.
1110 +                */
1111 +               if (pk11_choose_slot() == 0)
1112 +                       goto err;
1113 +
1114 +               /* Open the global_session for the new process */
1115 +               rv = pFuncList->C_OpenSession(SLOTID, CKF_SERIAL_SESSION,
1116 +                       NULL_PTR, NULL_PTR, &global_session);
1117 +               if (rv != CKR_OK)
1118 +                       {
1119 +                       PK11err(PK11_F_GET_SESSION, PK11_R_OPENSESSION);
1120 +                       snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
1121 +                       ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
1122 +                       OPENSSL_free(sp);
1123 +                       sp = NULL;
1124 +                       goto err;
1125 +                       }
1126 +
1127 +               /* It is an inherited session and needs re-initialization.
1128 +                */
1129 +               if (pk11_setup_session(sp) == 0)
1130 +                       {
1131 +                       OPENSSL_free(sp);
1132 +                       sp = NULL;
1133 +                       }
1134 +               }
1135 +       else if (sp->pid == 0)
1136 +               {
1137 +               /* It is a new session and needs initialization.
1138 +                */
1139 +               if (pk11_setup_session(sp) == 0)
1140 +                       {
1141 +                       OPENSSL_free(sp);
1142 +                       sp = NULL;
1143 +                       }
1144 +               }
1145 +
1146 +err:
1147 +       if (sp)
1148 +               sp->next = NULL;
1149 +
1150 +       CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
1151 +
1152 +       return sp;
1153 +       }
1154 +
1155 +
1156 +void pk11_return_session(PK11_SESSION *sp)
1157 +       {
1158 +       if (sp == NULL || sp->pid != getpid())
1159 +               return;
1160 +
1161 +       
1162 +       CRYPTO_w_lock(CRYPTO_LOCK_PK11_ENGINE);
1163 +
1164 +       sp->next = free_session;
1165 +       free_session = sp;
1166 +
1167 +       CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
1168 +       }
1169 +
1170 +
1171 +/* Destroy all objects. This function is called when the engine is finished
1172 + */
1173 +static int pk11_free_all_sessions()
1174 +       {
1175 +       CK_RV rv;
1176 +       PK11_SESSION *sp = NULL;
1177 +       pid_t mypid = getpid();
1178 +       int ret = 0;
1179 +
1180 +       pk11_destroy_rsa_key_objects(NULL);
1181 +       pk11_destroy_dsa_key_objects(NULL);
1182 +       pk11_destroy_dh_key_objects(NULL);
1183 +       pk11_destroy_cipher_key_objects(NULL);
1184 +       
1185 +       CRYPTO_w_lock(CRYPTO_LOCK_PK11_ENGINE);
1186 +       while ((sp = free_session) != NULL)
1187 +               {
1188 +               if (sp->session != CK_INVALID_HANDLE && sp->pid == mypid)
1189 +                       {
1190 +                       rv = pFuncList->C_CloseSession(sp->session);
1191 +                       if (rv != CKR_OK)
1192 +                               {
1193 +                               char tmp_buf[20];
1194 +                               PK11err(PK11_F_FREE_ALL_SESSIONS, 
1195 +                                       PK11_R_CLOSESESSION);
1196 +                               snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
1197 +                               ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
1198 +                               }
1199 +                       }
1200 +               if (sp->session_cipher != CK_INVALID_HANDLE && sp->pid == mypid)
1201 +                       {
1202 +                       rv = pFuncList->C_CloseSession(sp->session_cipher);
1203 +                       if (rv != CKR_OK)
1204 +                               {
1205 +                               char tmp_buf[20];
1206 +                               PK11err(PK11_F_FREE_ALL_SESSIONS, 
1207 +                                       PK11_R_CLOSESESSION);
1208 +                               snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
1209 +                               ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
1210 +                               }
1211 +                       }
1212 +               free_session = sp->next;
1213 +               OPENSSL_free(sp);
1214 +               }
1215 +       ret = 1;
1216 +err:
1217 +       CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
1218 +
1219 +       return ret;
1220 +       }
1221 +
1222 +
1223 +static int pk11_setup_session(PK11_SESSION *sp)
1224 +       {
1225 +       CK_RV rv;
1226 +       sp->session = CK_INVALID_HANDLE;
1227 +       rv = pFuncList->C_OpenSession(SLOTID, CKF_SERIAL_SESSION,
1228 +               NULL_PTR, NULL_PTR, &sp->session);
1229 +       if (rv == CKR_CRYPTOKI_NOT_INITIALIZED)
1230 +               {
1231 +               /*
1232 +                * We are probably a child process so force the
1233 +                * reinitialize of the session
1234 +                */
1235 +               pk11_library_initialized = 0;
1236 +               (void) pk11_library_init(NULL);
1237 +               rv = pFuncList->C_OpenSession(SLOTID, CKF_SERIAL_SESSION,
1238 +                       NULL_PTR, NULL_PTR, &sp->session);
1239 +               }
1240 +       if (rv != CKR_OK)
1241 +               {
1242 +               char tmp_buf[20];
1243 +               PK11err(PK11_F_SETUP_SESSION, PK11_R_OPENSESSION);
1244 +               snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
1245 +               ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
1246 +               return 0;
1247 +               }
1248 +
1249 +       sp->session_cipher = CK_INVALID_HANDLE;
1250 +       rv = pFuncList->C_OpenSession(SLOTID, CKF_SERIAL_SESSION,
1251 +               NULL_PTR, NULL_PTR, &sp->session_cipher);
1252 +       if (rv != CKR_OK)
1253 +               {
1254 +               char tmp_buf[20];
1255 +
1256 +               (void) pFuncList->C_CloseSession(sp->session);
1257 +               sp->session = CK_INVALID_HANDLE;
1258 +
1259 +               PK11err(PK11_F_SETUP_SESSION, PK11_R_OPENSESSION);
1260 +               snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
1261 +               ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
1262 +               return 0;
1263 +               }
1264 +
1265 +       sp->pid = getpid();
1266 +       sp->rsa_pub_key = CK_INVALID_HANDLE;
1267 +       sp->rsa_priv_key = CK_INVALID_HANDLE;
1268 +       sp->dsa_pub_key = CK_INVALID_HANDLE;
1269 +       sp->dsa_priv_key = CK_INVALID_HANDLE;
1270 +       sp->dh_key = CK_INVALID_HANDLE;
1271 +       sp->cipher_key = CK_INVALID_HANDLE;
1272 +       sp->rsa = NULL;
1273 +       sp->dsa = NULL;
1274 +       sp->dh = NULL;
1275 +       sp->encrypt = -1;
1276 +
1277 +       return 1;
1278 +       }
1279 +
1280 +int pk11_destroy_rsa_key_objects(PK11_SESSION *session)
1281 +       {
1282 +       int ret = 0;
1283 +       PK11_SESSION *sp = NULL;
1284 +       PK11_SESSION *local_free_session;
1285 +
1286 +       CRYPTO_w_lock(CRYPTO_LOCK_PK11_ENGINE);
1287 +       if (session)
1288 +               local_free_session = session;
1289 +       else
1290 +               local_free_session = free_session;
1291 +       while ((sp = local_free_session) != NULL)
1292 +               {
1293 +               local_free_session = sp->next;
1294 +
1295 +               if (sp->rsa_pub_key != CK_INVALID_HANDLE)
1296 +                       {
1297 +                       if (pk11_destroy_object(sp->session, 
1298 +                               sp->rsa_pub_key) == 0)
1299 +                               goto err;
1300 +                       sp->rsa_pub_key = CK_INVALID_HANDLE;
1301 +                       }
1302 +
1303 +               if (sp->rsa_priv_key != CK_INVALID_HANDLE)
1304 +                       {
1305 +                       if ((sp->rsa->flags & RSA_FLAG_EXT_PKEY) == 0 &&
1306 +                           pk11_destroy_object(sp->session, 
1307 +                               sp->rsa_priv_key) == 0)
1308 +                               goto err;
1309 +                       sp->rsa_priv_key = CK_INVALID_HANDLE;
1310 +                       }
1311 +
1312 +               sp->rsa = NULL;
1313 +               }
1314 +       ret = 1;
1315 +err:
1316 +       CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
1317 +
1318 +       return ret;
1319 +       }
1320 +
1321 +int pk11_destroy_dsa_key_objects(PK11_SESSION *session)
1322 +       {
1323 +       int ret = 0;
1324 +       PK11_SESSION *sp = NULL;
1325 +       PK11_SESSION *local_free_session;
1326 +
1327 +       CRYPTO_w_lock(CRYPTO_LOCK_PK11_ENGINE);
1328 +       if (session)
1329 +               local_free_session = session;
1330 +       else
1331 +               local_free_session = free_session;
1332 +       while ((sp = local_free_session) != NULL)
1333 +               {
1334 +               local_free_session = sp->next;
1335 +
1336 +               if (sp->dsa_pub_key != CK_INVALID_HANDLE)
1337 +                       {
1338 +                       if (pk11_destroy_object(sp->session, 
1339 +                               sp->dsa_pub_key) == 0)
1340 +                               goto err;
1341 +                       sp->dsa_pub_key = CK_INVALID_HANDLE;
1342 +                       }
1343 +
1344 +               if (sp->dsa_priv_key != CK_INVALID_HANDLE)
1345 +                       {
1346 +                       if (pk11_destroy_object(sp->session, 
1347 +                               sp->dsa_priv_key) == 0)
1348 +                               goto err;
1349 +                       sp->dsa_priv_key = CK_INVALID_HANDLE;
1350 +                       }
1351 +
1352 +               sp->dsa = NULL;
1353 +               }
1354 +       ret = 1;
1355 +err:
1356 +       CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
1357 +
1358 +       return ret;
1359 +       }
1360 +
1361 +int pk11_destroy_dh_key_objects(PK11_SESSION *session)
1362 +       {
1363 +       int ret = 0;
1364 +       PK11_SESSION *sp = NULL;
1365 +       PK11_SESSION *local_free_session;
1366 +
1367 +       CRYPTO_w_lock(CRYPTO_LOCK_PK11_ENGINE);
1368 +       if (session)
1369 +               local_free_session = session;
1370 +       else
1371 +               local_free_session = free_session;
1372 +       while ((sp = local_free_session) != NULL)
1373 +               {
1374 +               local_free_session = sp->next;
1375 +
1376 +               if (sp->dh_key != CK_INVALID_HANDLE)
1377 +                       {
1378 +                       if (pk11_destroy_object(sp->session, 
1379 +                               sp->dh_key) == 0)
1380 +                               goto err;
1381 +                       sp->dh_key = CK_INVALID_HANDLE;
1382 +                       }
1383 +
1384 +               sp->dh = NULL;
1385 +               }
1386 +       ret = 1;
1387 +err:
1388 +       CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
1389 +
1390 +       return ret;
1391 +       }
1392 +
1393 +static int pk11_destroy_object(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE oh)
1394 +       {
1395 +       CK_RV rv;
1396 +       rv = pFuncList->C_DestroyObject(session, oh);
1397 +       if (rv != CKR_OK)
1398 +               {
1399 +               char tmp_buf[20];
1400 +               PK11err(PK11_F_DESTROY_OBJECT, PK11_R_DESTROYOBJECT);
1401 +               snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
1402 +               ERR_add_error_data(2, "PK11 CK_RV=0X", 
1403 +                       tmp_buf);
1404 +               return 0;
1405 +               }
1406 +
1407 +       return 1;
1408 +       }
1409 +
1410 +
1411 +/* Symmetric ciphers and digests support functions
1412 + */
1413 +
1414 +static int
1415 +cipher_nid_to_pk11(int nid)
1416 +       {
1417 +       int i;
1418 +
1419 +       for (i = 0; i < PK11_CIPHER_MAX; i++)
1420 +               if (ciphers[i].nid == nid)
1421 +                       return (ciphers[i].id);
1422 +       return (-1);
1423 +       }
1424 +
1425 +static int
1426 +pk11_usable_ciphers(const int **nids)
1427 +       {
1428 +       if (cipher_count > 0)
1429 +               *nids = cipher_nids;
1430 +       else
1431 +               *nids = NULL;
1432 +       return (cipher_count);
1433 +       }
1434 +
1435 +static int
1436 +pk11_usable_digests(const int **nids)
1437 +       {
1438 +       if (digest_count > 0)
1439 +               *nids = digest_nids;
1440 +       else
1441 +               *nids = NULL;
1442 +       return (digest_count);
1443 +       }
1444 +
1445 +static int
1446 +pk11_cipher_init(EVP_CIPHER_CTX *ctx, const unsigned char *key,
1447 +    const unsigned char *iv, int enc)
1448 +       {
1449 +       CK_RV rv;
1450 +       CK_MECHANISM mech;
1451 +       int index;
1452 +       PK11_CIPHER_STATE *state = (PK11_CIPHER_STATE *) ctx->cipher_data;
1453 +       PK11_SESSION *sp;
1454 +       PK11_CIPHER *pcp;
1455 +       char tmp_buf[20];
1456 +       
1457 +       state->sp = NULL;
1458 +
1459 +       index = cipher_nid_to_pk11(ctx->cipher->nid);
1460 +       if (index < 0 || index >= PK11_CIPHER_MAX)
1461 +               return 0;
1462 +
1463 +       pcp = &ciphers[index];
1464 +       if (ctx->cipher->iv_len > pcp->ivmax || ctx->key_len != pcp->key_len)
1465 +               return 0;
1466 +
1467 +       if ((sp = pk11_get_session()) == NULL)
1468 +               return 0;
1469 +
1470 +       /* if applicable, the mechanism parameter is used for IV */
1471 +       mech.mechanism = pcp->mech_type;
1472 +       mech.pParameter = NULL;
1473 +       mech.ulParameterLen = 0;
1474 +
1475 +       /* The key object is destroyed here if it is not the current key
1476 +        */
1477 +       check_new_cipher_key(sp, key);
1478 +       
1479 +       /* If the key is the same and the encryption is also the same,
1480 +        * then just reuse it
1481 +        */
1482 +       if (sp->cipher_key != CK_INVALID_HANDLE && sp->encrypt == ctx->encrypt)
1483 +               {
1484 +               state->sp = sp;
1485 +               return 1;
1486 +               }
1487 +
1488 +       /* Check if the key has been invalidated. If so, a new key object
1489 +        * needs to be created.
1490 +        */
1491 +       if (sp->cipher_key == CK_INVALID_HANDLE)
1492 +               {
1493 +               sp->cipher_key = pk11_get_cipher_key(
1494 +                       ctx, key, pcp->key_type, sp);
1495 +               }
1496 +
1497 +       if (sp->encrypt != ctx->encrypt && sp->encrypt != -1)
1498 +               {
1499 +               /* The previous encryption/decryption
1500 +                * is different. Need to terminate the previous
1501 +                * active encryption/decryption here
1502 +                */
1503 +               if (!pk11_cipher_final(sp))
1504 +                       {
1505 +                       pk11_return_session(sp);
1506 +                       return 0;
1507 +                       }
1508 +               }
1509 +
1510 +       if (sp->cipher_key == CK_INVALID_HANDLE)
1511 +               {
1512 +               pk11_return_session(sp);
1513 +               return 0;
1514 +               }
1515 +
1516 +       if (ctx->cipher->iv_len > 0)
1517 +               {
1518 +               mech.pParameter = (void *) ctx->iv;
1519 +               mech.ulParameterLen = ctx->cipher->iv_len;
1520 +               }
1521 +
1522 +       /* If we get here, the encryption needs to be reinitialized */
1523 +       if (ctx->encrypt)
1524 +               {
1525 +               rv = pFuncList->C_EncryptInit(sp->session_cipher, &mech, 
1526 +                       sp->cipher_key);
1527 +
1528 +               if (rv != CKR_OK)
1529 +                       {
1530 +                       PK11err(PK11_F_CIPHER_INIT, PK11_R_ENCRYPTINIT);
1531 +                       snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
1532 +                       ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
1533 +                       pk11_return_session(sp);
1534 +                       return 0;
1535 +                       }
1536 +               }
1537 +       else
1538 +               {
1539 +               rv = pFuncList->C_DecryptInit(sp->session_cipher, &mech, 
1540 +                       sp->cipher_key);
1541 +
1542 +               if (rv != CKR_OK)
1543 +                       {
1544 +                       PK11err(PK11_F_CIPHER_INIT, PK11_R_DECRYPTINIT);
1545 +                       snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
1546 +                       ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
1547 +                       pk11_return_session(sp);
1548 +                       return 0;
1549 +                       }
1550 +               }
1551 +
1552 +       sp->encrypt = ctx->encrypt;
1553 +       state->sp = sp;
1554 +
1555 +       return 1;
1556 +       }
1557 +
1558 +/* When reusing the same key in an encryption/decryption session for a 
1559 + * decryption/encryption session, we need to close the active session
1560 + * and recreate a new one. Note that the key is in the global session so
1561 + * that it needs not be recreated.
1562 + *
1563 + * It is more appropriate to use C_En/DecryptFinish here. At the time of this
1564 + * development, these two functions in the PKCS#11 libraries used return
1565 + * unexpected errors when passing in 0 length output. It may be a good
1566 + * idea to try them again if performance is a problem here and fix
1567 + * C_En/DecryptFinial if there are bugs there causing the problem.
1568 + */
1569 +static int
1570 +pk11_cipher_final(PK11_SESSION *sp)
1571 +       {
1572 +       CK_RV rv;
1573 +       char tmp_buf[20];
1574 +
1575 +       rv = pFuncList->C_CloseSession(sp->session_cipher);
1576 +       if (rv != CKR_OK)
1577 +               {
1578 +               PK11err(PK11_F_CIPHER_FINAL, PK11_R_CLOSESESSION);
1579 +               snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
1580 +               ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
1581 +               return 0;
1582 +               }
1583 +
1584 +       rv = pFuncList->C_OpenSession(SLOTID, CKF_SERIAL_SESSION,
1585 +               NULL_PTR, NULL_PTR, &sp->session_cipher);
1586 +       if (rv != CKR_OK)
1587 +               {
1588 +               PK11err(PK11_F_CIPHER_FINAL, PK11_R_OPENSESSION);
1589 +               snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
1590 +               ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
1591 +               return 0;
1592 +               }
1593 +
1594 +       return 1;
1595 +       }
1596 +
1597 +/* An engine interface function. The calling function allocates sufficient
1598 + * memory for the output buffer "out" to hold the results */
1599 +static int
1600 +pk11_cipher_do_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
1601 +       const unsigned char *in, unsigned int inl)
1602 +       {
1603 +       PK11_CIPHER_STATE *state = (PK11_CIPHER_STATE *) ctx->cipher_data;
1604 +       PK11_SESSION *sp;
1605 +       CK_RV rv;
1606 +       unsigned long outl = inl;
1607 +       char tmp_buf[20];
1608 +
1609 +       if (state == NULL || state->sp == NULL)
1610 +               return 0;
1611 +
1612 +       sp = (PK11_SESSION *) state->sp;
1613 +
1614 +       if (!inl)
1615 +               return 1;
1616 +
1617 +       /* RC4 is the only stream cipher we support */
1618 +       if (ctx->cipher->nid != NID_rc4 && (inl % ctx->cipher->block_size) != 0)
1619 +               return 0;
1620 +
1621 +       if (ctx->encrypt)
1622 +               {
1623 +               rv = pFuncList->C_EncryptUpdate(sp->session_cipher, 
1624 +                       (unsigned char *)in, inl, out, &outl);
1625 +
1626 +               if (rv != CKR_OK)
1627 +                       {
1628 +                       PK11err(PK11_F_CIPHER_DO_CIPHER, 
1629 +                               PK11_R_ENCRYPTUPDATE);
1630 +                       snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
1631 +                       ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
1632 +                       return 0;
1633 +                       }
1634 +               }
1635 +       else
1636 +               {
1637 +               rv = pFuncList->C_DecryptUpdate(sp->session_cipher, 
1638 +                       (unsigned char *)in, inl, out, &outl);
1639 +
1640 +               if (rv != CKR_OK)
1641 +                       {
1642 +                       PK11err(PK11_F_CIPHER_DO_CIPHER, 
1643 +                               PK11_R_DECRYPTUPDATE);
1644 +                       snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
1645 +                       ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
1646 +                       return 0;
1647 +                       }
1648 +               }
1649 +
1650 +       /* for DES_CBC, DES3_CBC, AES_CBC, and RC4, the output size is always
1651 +        * the same size of input
1652 +        * The application has guaranteed to call the block ciphers with 
1653 +        * correctly aligned buffers.
1654 +        */
1655 +       if (inl != outl)
1656 +               return 0;
1657 +
1658 +       return 1;
1659 +       }
1660 +
1661 +/* Return the session to the pool. The C_EncryptFinal and C_DecryptFinal are
1662 + * not used. Once a secret key is initialized, it is used until destroyed.
1663 + */
1664 +static int
1665 +pk11_cipher_cleanup(EVP_CIPHER_CTX *ctx)
1666 +       {
1667 +       PK11_CIPHER_STATE *state = ctx->cipher_data;
1668 +
1669 +       if (state != NULL && state->sp != NULL)
1670 +               {
1671 +               pk11_return_session(state->sp);
1672 +               state->sp = NULL;
1673 +               }
1674 +
1675 +       return 1;
1676 +       }
1677 +
1678 +/* Registered by the ENGINE when used to find out how to deal with
1679 + * a particular NID in the ENGINE. This says what we'll do at the
1680 + * top level - note, that list is restricted by what we answer with
1681 + */
1682 +static int
1683 +pk11_engine_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
1684 +       const int **nids, int nid)
1685 +       {
1686 +       if (!cipher)
1687 +               return (pk11_usable_ciphers(nids));
1688 +
1689 +       switch (nid)
1690 +               {
1691 +               case NID_des_ede3_cbc:
1692 +                       *cipher = &pk11_3des_cbc;
1693 +                       break;
1694 +               case NID_des_cbc:
1695 +                       *cipher = &pk11_des_cbc;
1696 +                       break;
1697 +               case NID_aes_128_cbc:
1698 +                       *cipher = &pk11_aes_cbc;
1699 +                       break;
1700 +               case NID_rc4:
1701 +                       *cipher = &pk11_rc4;
1702 +                       break;
1703 +               default:
1704 +                       *cipher = NULL;
1705 +                       break;
1706 +               }
1707 +       return (*cipher != NULL);
1708 +       }
1709 +
1710 +static int
1711 +pk11_engine_digests(ENGINE *e, const EVP_MD **digest,
1712 +       const int **nids, int nid)
1713 +       {
1714 +       if (!digest)
1715 +               return (pk11_usable_digests(nids));
1716 +
1717 +       switch (nid)
1718 +               {
1719 +               case NID_md5:
1720 +                       *digest = &pk11_md5; 
1721 +                       break;
1722 +               case NID_sha1:
1723 +                       *digest = &pk11_sha1; 
1724 +                       break;
1725 +               default:
1726 +                       *digest = NULL;
1727 +                       break;
1728 +               }
1729 +       return (*digest != NULL);
1730 +       }
1731 +
1732 +
1733 +/* Create a secret key object in a PKCS#11 session
1734 + */
1735 +static CK_OBJECT_HANDLE pk11_get_cipher_key(EVP_CIPHER_CTX *ctx, 
1736 +       const unsigned char *key, CK_KEY_TYPE key_type, PK11_SESSION *sp)
1737 +       {
1738 +       CK_RV rv;
1739 +       CK_OBJECT_HANDLE h_key = CK_INVALID_HANDLE;
1740 +       CK_OBJECT_CLASS obj_key = CKO_SECRET_KEY;
1741 +       CK_ULONG ul_key_attr_count = 6;
1742 +       char tmp_buf[20];
1743 +
1744 +       CK_ATTRIBUTE  a_key_template[] =
1745 +               {
1746 +               {CKA_CLASS, (void*) NULL, sizeof(CK_OBJECT_CLASS)},
1747 +               {CKA_KEY_TYPE, (void*) NULL, sizeof(CK_KEY_TYPE)},
1748 +               {CKA_TOKEN, &false, sizeof(false)},
1749 +               {CKA_ENCRYPT, &true, sizeof(true)},
1750 +               {CKA_DECRYPT, &true, sizeof(true)},
1751 +               {CKA_VALUE, (void*) NULL, 0},
1752 +               };
1753 +
1754 +       /* Create secret key object in global_session. All other sessions
1755 +        * can use the key handles. Here is why:
1756 +        * OpenSSL will call EncryptInit and EncryptUpdate using a secret key.
1757 +        * It may then call DecryptInit and DecryptUpdate using the same key.
1758 +        * To use the same key object, we need to call EncryptFinal with
1759 +        * a 0 length message. Currently, this does not work for 3DES 
1760 +        * mechanism. To get around this problem, we close the session and
1761 +        * then create a new session to use the same key object. When a session
1762 +        * is closed, all the object handles will be invalid. Thus, create key 
1763 +        * objects in a global session, an individual session may be closed to
1764 +        * terminate the active operation.
1765 +        */
1766 +       CK_SESSION_HANDLE session = global_session;
1767 +       a_key_template[0].pValue = &obj_key;
1768 +       a_key_template[1].pValue = &key_type;
1769 +       a_key_template[5].pValue = (void *) key;
1770 +       a_key_template[5].ulValueLen = (unsigned long) ctx->key_len;
1771 +
1772 +       rv = pFuncList->C_CreateObject(session, 
1773 +               a_key_template, ul_key_attr_count, &h_key);
1774 +       if (rv != CKR_OK)
1775 +               {
1776 +               PK11err(PK11_F_GET_CIPHER_KEY, PK11_R_CREATEOBJECT);
1777 +               snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
1778 +               ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
1779 +               goto err;
1780 +               }
1781 +
1782 +       /* Save the key information used in this session.
1783 +        * The max can be saved is PK11_KEY_LEN_MAX.
1784 +        */
1785 +       sp->key_len = ctx->key_len > PK11_KEY_LEN_MAX ? 
1786 +               PK11_KEY_LEN_MAX : ctx->key_len;
1787 +       memcpy(sp->key, key, sp->key_len);
1788 +err:
1789 +
1790 +       return h_key;
1791 +       }
1792 +
1793 +static int
1794 +md_nid_to_pk11(int nid)
1795 +       {
1796 +       int i;
1797 +
1798 +       for (i = 0; i < PK11_DIGEST_MAX; i++)
1799 +               if (digests[i].nid == nid)
1800 +                       return (digests[i].id);
1801 +       return (-1);
1802 +       }
1803 +
1804 +static int 
1805 +pk11_digest_init(EVP_MD_CTX *ctx)
1806 +        { 
1807 +       CK_RV rv;
1808 +       CK_MECHANISM mech;
1809 +       int index;
1810 +       PK11_SESSION *sp;
1811 +       PK11_DIGEST *pdp;
1812 +       PK11_CIPHER_STATE *state = (PK11_CIPHER_STATE *) ctx->md_data;
1813 +       
1814 +       state->sp = NULL;
1815 +
1816 +       index = md_nid_to_pk11(ctx->digest->type);
1817 +       if (index < 0 || index >= PK11_DIGEST_MAX)
1818 +               return 0;
1819 +
1820 +       pdp = &digests[index];
1821 +       if ((sp = pk11_get_session()) == NULL)
1822 +               return 0;
1823 +
1824 +       /* at present, no parameter is needed for supported digests */
1825 +       mech.mechanism = pdp->mech_type;
1826 +       mech.pParameter = NULL;
1827 +       mech.ulParameterLen = 0;
1828 +
1829 +       rv = pFuncList->C_DigestInit(sp->session, &mech);
1830 +
1831 +       if (rv != CKR_OK)
1832 +               {
1833 +               char tmp_buf[20];
1834 +               PK11err(PK11_F_DIGEST_INIT, PK11_R_DIGESTINIT);
1835 +               snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
1836 +               ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
1837 +               pk11_return_session(sp);
1838 +               return 0;
1839 +               }
1840 +
1841 +       state->sp = sp;
1842 +
1843 +       return 1;
1844 +       }
1845 +
1846 +static int 
1847 +pk11_digest_update(EVP_MD_CTX *ctx,const void *data,size_t count)
1848 +        { 
1849 +       CK_RV rv;
1850 +       PK11_CIPHER_STATE *state = (PK11_CIPHER_STATE *) ctx->md_data;
1851 +       
1852 +       /* 0 length message will cause a failure in C_DigestFinal */
1853 +       if (count == 0)
1854 +               return 1;
1855 +
1856 +       if (state == NULL || state->sp == NULL)
1857 +               return 0;
1858 +
1859 +       rv = pFuncList->C_DigestUpdate(state->sp->session, (CK_BYTE *) data,
1860 +               count);
1861 +
1862 +       if (rv != CKR_OK)
1863 +               {
1864 +               char tmp_buf[20];
1865 +               PK11err(PK11_F_DIGEST_UPDATE, PK11_R_DIGESTUPDATE);
1866 +               snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
1867 +               ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
1868 +               pk11_return_session(state->sp);
1869 +               state->sp = NULL;
1870 +               return 0;
1871 +               }
1872 +
1873 +       return 1;
1874 +       }
1875 +
1876 +static int 
1877 +pk11_digest_final(EVP_MD_CTX *ctx,unsigned char *md)
1878 +        { 
1879 +       CK_RV rv;
1880 +       unsigned long len;
1881 +       PK11_CIPHER_STATE *state = (PK11_CIPHER_STATE *) ctx->md_data;
1882 +       len = ctx->digest->md_size;
1883 +       
1884 +       if (state == NULL || state->sp == NULL)
1885 +               return 0;
1886 +
1887 +       rv = pFuncList->C_DigestFinal(state->sp->session, md, &len);
1888 +
1889 +       if (rv != CKR_OK)
1890 +               {
1891 +               char tmp_buf[20];
1892 +               PK11err(PK11_F_DIGEST_FINAL, PK11_R_DIGESTFINAL);
1893 +               snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
1894 +               ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
1895 +               pk11_return_session(state->sp);
1896 +               state->sp = NULL;
1897 +               return 0;
1898 +               }
1899 +
1900 +       if (ctx->digest->md_size != len)
1901 +               return 0;
1902 +
1903 +       /* Final is called and digest is returned, so return the session
1904 +        * to the pool
1905 +        */
1906 +       pk11_return_session(state->sp);
1907 +       state->sp = NULL;
1908 +
1909 +       return 1;
1910 +       }
1911 +
1912 +static int 
1913 +pk11_digest_copy(EVP_MD_CTX *to,const EVP_MD_CTX *from)
1914 +        { 
1915 +       CK_RV rv;
1916 +       int ret = 0;
1917 +       PK11_CIPHER_STATE *state, *state_to;
1918 +       CK_BYTE_PTR pstate = NULL;
1919 +       CK_ULONG ul_state_len;
1920 +       char tmp_buf[20];
1921 +       
1922 +       /* The copy-from state */
1923 +       state = (PK11_CIPHER_STATE *) from->md_data;
1924 +       if (state == NULL || state->sp == NULL)
1925 +               goto err;
1926 +
1927 +       /* Initialize the copy-to state */
1928 +       if (!pk11_digest_init(to))
1929 +               goto err;
1930 +       state_to = (PK11_CIPHER_STATE *) to->md_data;
1931 +
1932 +       /* Get the size of the operation state of the copy-from session */
1933 +       rv = pFuncList->C_GetOperationState(state->sp->session, NULL, 
1934 +               &ul_state_len);
1935 +
1936 +       if (rv != CKR_OK)
1937 +               {
1938 +               PK11err(PK11_F_DIGEST_COPY, PK11_R_GET_OPERATION_STATE);
1939 +               snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
1940 +               ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
1941 +               goto err;
1942 +               }
1943 +       if (ul_state_len == 0)
1944 +               {
1945 +               goto err;
1946 +               }
1947 +
1948 +       pstate = OPENSSL_malloc(ul_state_len);
1949 +       if (pstate == NULL)
1950 +               {
1951 +               RSAerr(PK11_F_DIGEST_COPY, PK11_R_MALLOC_FAILURE);
1952 +               goto err;
1953 +               }
1954 +
1955 +       /* Get the operation state of the copy-from session */
1956 +       rv = pFuncList->C_GetOperationState(state->sp->session, pstate, 
1957 +               &ul_state_len);
1958 +
1959 +       if (rv != CKR_OK)
1960 +               {
1961 +               PK11err(PK11_F_DIGEST_COPY, PK11_R_GET_OPERATION_STATE);
1962 +               snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
1963 +               ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
1964 +               goto err;
1965 +               }
1966 +
1967 +       /* Set the operation state of the copy-to session */
1968 +       rv = pFuncList->C_SetOperationState(state_to->sp->session, pstate, 
1969 +               ul_state_len, 0, 0);
1970 +
1971 +       if (rv != CKR_OK)
1972 +               {
1973 +               PK11err(PK11_F_DIGEST_COPY, PK11_R_SET_OPERATION_STATE);
1974 +               snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
1975 +               ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
1976 +               goto err;
1977 +               }
1978 +
1979 +       ret = 1;
1980 +err:
1981 +       if (pstate != NULL)
1982 +               OPENSSL_free(pstate);
1983 +
1984 +       return ret;
1985 +       }
1986 +
1987 +/* Return any pending session state to the pool */
1988 +static int
1989 +pk11_digest_cleanup(EVP_MD_CTX *ctx)
1990 +       {
1991 +       PK11_CIPHER_STATE *state = ctx->md_data;
1992 +       unsigned char buf[EVP_MAX_MD_SIZE];
1993 +
1994 +       if (state != NULL && state->sp != NULL)
1995 +               {
1996 +               /*
1997 +                * If state->sp is not NULL then pk11_digest_final() has not
1998 +                * been called yet. We must call it now to free any memory
1999 +                * that might have been allocated in the token when
2000 +                * pk11_digest_init() was called.
2001 +                */
2002 +               pk11_digest_final(ctx,buf);
2003 +               pk11_return_session(state->sp);
2004 +               state->sp = NULL;
2005 +               }
2006 +
2007 +       return 1;
2008 +       }
2009 +
2010 +/* Check if the new key is the same as the key object in the session.
2011 + * If the key is the same, no need to create a new key object. Otherwise,
2012 + * the old key object needs to be destroyed and a new one will be created
2013 + */
2014 +static void check_new_cipher_key(PK11_SESSION *sp, const unsigned char *key)
2015 +       {
2016 +       if (memcmp(sp->key, key, sp->key_len) != 0)
2017 +               pk11_destroy_cipher_key_objects(sp);
2018 +       }
2019 +
2020 +/* Destroy one or more secret key objects. 
2021 + */
2022 +static int pk11_destroy_cipher_key_objects(PK11_SESSION *session)
2023 +       {
2024 +       int ret = 0;
2025 +       PK11_SESSION *sp = NULL;
2026 +       PK11_SESSION *local_free_session;
2027 +
2028 +       CRYPTO_w_lock(CRYPTO_LOCK_PK11_ENGINE);
2029 +       if (session)
2030 +               local_free_session = session;
2031 +       else
2032 +               local_free_session = free_session;
2033 +       while ((sp = local_free_session) != NULL)
2034 +               {
2035 +               local_free_session = sp->next;
2036 +
2037 +               if (sp->cipher_key != CK_INVALID_HANDLE)
2038 +                       {
2039 +                       /* The secret key object is created in the 
2040 +                        * global_session. See pk11_get_cipher_key
2041 +                        */
2042 +                       if (pk11_destroy_object(global_session, 
2043 +                               sp->cipher_key) == 0)
2044 +                               goto err;
2045 +                       sp->cipher_key = CK_INVALID_HANDLE;
2046 +                       }
2047 +               }
2048 +       ret = 1;
2049 +err:
2050 +       CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
2051 +
2052 +       return ret;
2053 +       }
2054 +
2055 +
2056 +/*
2057 + * Required mechanisms
2058 + *
2059 + * CKM_RSA_X_509
2060 + * CKM_RSA_PKCS
2061 + * CKM_DSA
2062 + *
2063 + * As long as these required mechanisms are met, it will return success. 
2064 + * Otherwise, it will return failure and the engine initialization will fail. 
2065 + * The application will then decide whether to use another engine or 
2066 + * no engine.
2067 + *
2068 + * Symmetric ciphers optionally supported
2069 + *
2070 + * CKM_DES3_CBC
2071 + * CKM_DES_CBC
2072 + * CKM_AES_CBC
2073 + * CKM_RC4
2074 + *
2075 + * Digests optionally supported
2076 + *
2077 + * CKM_MD5
2078 + * CKM_SHA_1
2079 + */
2080 +
2081 +static int 
2082 +pk11_choose_slot()
2083 +       {
2084 +       CK_SLOT_ID_PTR pSlotList = NULL_PTR;
2085 +       CK_ULONG ulSlotCount = 0;
2086 +       CK_MECHANISM_INFO mech_info;
2087 +       CK_TOKEN_INFO token_info;
2088 +       int i;
2089 +       CK_RV rv;
2090 +       CK_SLOT_ID best_slot_sofar;
2091 +       CK_BBOOL found_candidate_slot = CK_FALSE;
2092 +       int slot_n_cipher = 0;
2093 +       int slot_n_digest = 0;
2094 +       CK_SLOT_ID current_slot = 0;
2095 +       int current_slot_n_cipher = 0;
2096 +       int current_slot_n_digest = 0;
2097 +
2098 +       int local_cipher_nids[PK11_CIPHER_MAX];
2099 +       int local_digest_nids[PK11_DIGEST_MAX];
2100 +       char tmp_buf[20];
2101 +       int retval = 0;
2102 +
2103 +       if (!pk11_auto_slot)
2104 +               return 1;
2105 +
2106 +       /* Get slot list for memory alloction */
2107 +       rv = pFuncList->C_GetSlotList(0, NULL_PTR, &ulSlotCount);
2108 +
2109 +       if (rv != CKR_OK)
2110 +               {
2111 +               PK11err(PK11_F_CHOOSE_SLOT, PK11_R_GETSLOTLIST);
2112 +               snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
2113 +               ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
2114 +               return retval;
2115 +               }
2116 +
2117 +       if (ulSlotCount == 0) 
2118 +               {
2119 +               PK11err(PK11_F_CHOOSE_SLOT, PK11_R_GETSLOTLIST);
2120 +               return retval;
2121 +               }
2122 +
2123 +       pSlotList = OPENSSL_malloc(ulSlotCount * sizeof (CK_SLOT_ID));
2124 +
2125 +       if (pSlotList == NULL) 
2126 +               {
2127 +               RSAerr(PK11_F_CHOOSE_SLOT,PK11_R_MALLOC_FAILURE);
2128 +               return retval;
2129 +               }
2130 +
2131 +       /* Get the slot list for processing */
2132 +       rv = pFuncList->C_GetSlotList(0, pSlotList, &ulSlotCount);
2133 +       if (rv != CKR_OK) 
2134 +               {
2135 +               PK11err(PK11_F_CHOOSE_SLOT, PK11_R_GETSLOTLIST);
2136 +               snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
2137 +               ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
2138 +               OPENSSL_free(pSlotList);
2139 +               return retval;
2140 +               }
2141 +
2142 +       for (i = 0; i < ulSlotCount; i++) 
2143 +               {
2144 +               CK_BBOOL slot_has_rsa = CK_FALSE;
2145 +               CK_BBOOL slot_has_dsa = CK_FALSE;
2146 +               CK_BBOOL slot_has_dh = CK_FALSE;
2147 +               current_slot = pSlotList[i];
2148 +               current_slot_n_cipher = 0;
2149 +               current_slot_n_digest = 0;
2150 +               memset(local_cipher_nids, 0, sizeof(local_cipher_nids));
2151 +               memset(local_digest_nids, 0, sizeof(local_digest_nids));
2152 +
2153 +#ifdef DEBUG_SLOT_SELECTION
2154 +               fprintf(stderr, "OPENSSL_PKCS#11_ENGINE: checking slot: %d\n",
2155 +                   current_slot);
2156 +#endif
2157 +               /* Check if slot has random support. */
2158 +               rv = pFuncList->C_GetTokenInfo(current_slot, &token_info);
2159 +               if (rv != CKR_OK)
2160 +                       continue;
2161 +
2162 +               if (token_info.flags & CKF_RNG)
2163 +                       pk11_have_random = CK_TRUE;
2164 +
2165 +               /*
2166 +                * Check if this slot is capable of signing and
2167 +                * verifying with CKM_RSA_PKCS.
2168 +                */
2169 +               rv = pFuncList->C_GetMechanismInfo(current_slot, CKM_RSA_PKCS, 
2170 +                       &mech_info);
2171 +
2172 +               if (rv == CKR_OK && ((mech_info.flags & CKF_SIGN) &&
2173 +                               (mech_info.flags & CKF_VERIFY)))
2174 +                       {
2175 +                       /*
2176 +                        * Check if this slot is capable of encryption,
2177 +                        * decryption, sign, and verify with CKM_RSA_X_509.
2178 +                        */
2179 +                       rv = pFuncList->C_GetMechanismInfo(current_slot,
2180 +                         CKM_RSA_X_509, &mech_info);
2181 +
2182 +                       if (rv == CKR_OK && ((mech_info.flags & CKF_SIGN) &&
2183 +                           (mech_info.flags & CKF_VERIFY) &&
2184 +                           (mech_info.flags & CKF_ENCRYPT) &&
2185 +                           (mech_info.flags & CKF_VERIFY_RECOVER) &&
2186 +                           (mech_info.flags & CKF_DECRYPT)))
2187 +                               slot_has_rsa = CK_TRUE;
2188 +                       }
2189 +
2190 +               /*
2191 +                * Check if this slot is capable of signing and
2192 +                * verifying with CKM_DSA.
2193 +                */
2194 +               rv = pFuncList->C_GetMechanismInfo(current_slot, CKM_DSA, 
2195 +                       &mech_info);
2196 +               if (rv == CKR_OK && ((mech_info.flags & CKF_SIGN) &&
2197 +                   (mech_info.flags & CKF_VERIFY)))
2198 +                       slot_has_dsa = CK_TRUE;
2199 +
2200 +               /*
2201 +                * Check if this slot is capable of DH key generataion and
2202 +                * derivation.
2203 +                */
2204 +               rv = pFuncList->C_GetMechanismInfo(current_slot,
2205 +                 CKM_DH_PKCS_KEY_PAIR_GEN, &mech_info);
2206 +
2207 +               if (rv == CKR_OK && (mech_info.flags & CKF_GENERATE_KEY_PAIR))
2208 +                       {    
2209 +                       rv = pFuncList->C_GetMechanismInfo(current_slot,
2210 +                               CKM_DH_PKCS_DERIVE, &mech_info);
2211 +                       if (rv == CKR_OK && (mech_info.flags & CKF_DERIVE))
2212 +                               slot_has_dh = CK_TRUE;
2213 +                       }
2214 +
2215 +               if (!found_candidate_slot &&
2216 +                   (slot_has_rsa || slot_has_dsa || slot_has_dh))
2217 +                       {
2218 +#ifdef DEBUG_SLOT_SELECTION
2219 +                       fprintf(stderr,
2220 +                           "OPENSSL_PKCS#11_ENGINE: potential slot: %d\n",
2221 +                           current_slot);
2222 +#endif
2223 +                       best_slot_sofar = current_slot;
2224 +                       pk11_have_rsa = slot_has_rsa;
2225 +                       pk11_have_dsa = slot_has_dsa;
2226 +                       pk11_have_dh = slot_has_dh;
2227 +                       found_candidate_slot = CK_TRUE;
2228 +#ifdef DEBUG_SLOT_SELECTION
2229 +                       fprintf(stderr,
2230 +                           "OPENSSL_PKCS#11_ENGINE: best so far slot: %d\n",
2231 +                           best_slot_sofar);
2232 +#endif
2233 +                       }
2234 +
2235 +               /* Count symmetric cipher support. */
2236 +               if (!pk11_count_symmetric_cipher(current_slot, CKM_DES_CBC,
2237 +                               &current_slot_n_cipher, local_cipher_nids,
2238 +                               PK11_DES_CBC))
2239 +                       continue;
2240 +               if (!pk11_count_symmetric_cipher(current_slot, CKM_DES3_CBC,
2241 +                               &current_slot_n_cipher, local_cipher_nids,
2242 +                               PK11_DES3_CBC))
2243 +                       continue;
2244 +               if (!pk11_count_symmetric_cipher(current_slot, CKM_AES_CBC,
2245 +                               &current_slot_n_cipher, local_cipher_nids,
2246 +                               PK11_AES_CBC))
2247 +                       continue;
2248 +               if (!pk11_count_symmetric_cipher(current_slot, CKM_RC4,
2249 +                               &current_slot_n_cipher, local_cipher_nids,
2250 +                               PK11_RC4))
2251 +                       continue;
2252 +
2253 +               /* Count digest support */
2254 +               if (!pk11_count_digest(current_slot, CKM_MD5,
2255 +                               &current_slot_n_digest, local_digest_nids,
2256 +                               PK11_MD5))
2257 +                       continue;
2258 +               if (!pk11_count_digest(current_slot, CKM_SHA_1,
2259 +                               &current_slot_n_digest, local_digest_nids,
2260 +                               PK11_SHA1))
2261 +                       continue;
2262 +
2263 +               /*
2264 +                * If the current slot supports more ciphers/digests than 
2265 +                * the previous best one we change the current best to this one.
2266 +                * otherwise leave it where it is.
2267 +                */
2268 +               if (((current_slot_n_cipher > slot_n_cipher) &&
2269 +                   (current_slot_n_digest > slot_n_digest)) &&
2270 +                   ((slot_has_rsa == pk11_have_rsa) &&
2271 +                    (slot_has_dsa == pk11_have_dsa) &&
2272 +                    (slot_has_dh == pk11_have_dh)))
2273 +                       {
2274 +                       best_slot_sofar = current_slot;
2275 +                       slot_n_cipher = current_slot_n_cipher;
2276 +                       slot_n_digest = current_slot_n_digest;
2277 +
2278 +                       memcpy(cipher_nids, local_cipher_nids, 
2279 +                               sizeof(local_cipher_nids));
2280 +                       memcpy(digest_nids, local_digest_nids, 
2281 +                               sizeof(local_digest_nids));
2282 +                       }
2283 +
2284 +               }
2285 +
2286 +       if (found_candidate_slot)
2287 +               {
2288 +               cipher_count = slot_n_cipher;
2289 +               digest_count = slot_n_digest;
2290 +               SLOTID = best_slot_sofar;
2291 +               retval = 1;
2292 +               }
2293 +       else
2294 +               {
2295 +               cipher_count = 0;
2296 +               digest_count = 0;
2297 +               }
2298 +
2299 +#ifdef DEBUG_SLOT_SELECTION
2300 +       fprintf(stderr,
2301 +         "OPENSSL_PKCS#11_ENGINE: choose slot: %d\n", SLOTID);
2302 +       fprintf(stderr,
2303 +         "OPENSSL_PKCS#11_ENGINE: pk11_have_rsa %d\n", pk11_have_rsa);
2304 +       fprintf(stderr,
2305 +         "OPENSSL_PKCS#11_ENGINE: pk11_have_dsa %d\n", pk11_have_dsa);
2306 +       fprintf(stderr,
2307 +         "OPENSSL_PKCS#11_ENGINE: pk11_have_dh %d\n", pk11_have_dh);
2308 +       fprintf(stderr,
2309 +         "OPENSSL_PKCS#11_ENGINE: pk11_have_random %d\n", pk11_have_random);
2310 +#endif /* DEBUG_SLOT_SELECTION */
2311 +               
2312 +       if (pSlotList)
2313 +               OPENSSL_free(pSlotList);
2314 +
2315 +       return retval;
2316 +       }
2317 +
2318 +static int pk11_count_symmetric_cipher(int slot_id, CK_MECHANISM_TYPE mech,
2319 +    int *current_slot_n_cipher, int *local_cipher_nids, int id)
2320 +       {
2321 +       CK_MECHANISM_INFO mech_info;
2322 +       CK_RV rv;
2323 +
2324 +       rv = pFuncList->C_GetMechanismInfo(slot_id, mech, &mech_info);
2325 +
2326 +       if (rv != CKR_OK) 
2327 +               return 0;
2328 +
2329 +       if ((mech_info.flags & CKF_ENCRYPT) &&
2330 +                       (mech_info.flags & CKF_DECRYPT))
2331 +               {
2332 +               local_cipher_nids[(*current_slot_n_cipher)++] = ciphers[id].nid;
2333 +               }
2334 +
2335 +       return 1;
2336 +       }
2337 +
2338 +
2339 +static int pk11_count_digest(int slot_id, CK_MECHANISM_TYPE mech,
2340 +    int *current_slot_n_digest, int *local_digest_nids, int id)
2341 +       {
2342 +       CK_MECHANISM_INFO mech_info;
2343 +       CK_RV rv;
2344 +
2345 +       rv = pFuncList->C_GetMechanismInfo(slot_id, mech, &mech_info);
2346 +
2347 +       if (rv != CKR_OK) 
2348 +               return 0;
2349 +
2350 +       if (mech_info.flags & CKF_DIGEST)
2351 +               {
2352 +               local_digest_nids[(*current_slot_n_digest)++] = digests[id].nid;
2353 +               }
2354 +
2355 +       return 1;
2356 +       }
2357 +
2358 +
2359 +#endif
2360 +#endif
2361 +
2362 diff -r -u -N openssl-0.9.8g/crypto/engine/hw_pk11_err.c openssl/crypto/engine/hw_pk11_err.c
2363 --- openssl-0.9.8g/crypto/engine/hw_pk11_err.c  1970-01-01 01:00:00.000000000 +0100
2364 +++ openssl/crypto/engine/hw_pk11_err.c 2007-10-25 01:27:09.000000000 +0200
2365 @@ -0,0 +1,233 @@
2366 +/*
2367 + * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
2368 + * Use is subject to license terms.
2369 + */
2370 +#pragma ident  "@(#)hw_pk11_err.c      1.2     04/06/22 SMI"
2371 +
2372 +/* crypto/engine/hw_pk11_err.c */
2373 +/* This product includes software developed by the OpenSSL Project for 
2374 + * use in the OpenSSL Toolkit (http://www.openssl.org/).
2375 + *
2376 + * This project also referenced hw_pkcs11-0.9.7b.patch written by 
2377 + * Afchine Madjlessi.
2378 + */
2379 +/* ====================================================================
2380 + * Copyright (c) 2000-2001 The OpenSSL Project.  All rights reserved.
2381 + *
2382 + * Redistribution and use in source and binary forms, with or without
2383 + * modification, are permitted provided that the following conditions
2384 + * are met:
2385 + *
2386 + * 1. Redistributions of source code must retain the above copyright
2387 + *    notice, this list of conditions and the following disclaimer. 
2388 + *
2389 + * 2. Redistributions in binary form must reproduce the above copyright
2390 + *    notice, this list of conditions and the following disclaimer in
2391 + *    the documentation and/or other materials provided with the
2392 + *    distribution.
2393 + *
2394 + * 3. All advertising materials mentioning features or use of this
2395 + *    software must display the following acknowledgment:
2396 + *    "This product includes software developed by the OpenSSL Project
2397 + *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
2398 + *
2399 + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
2400 + *    endorse or promote products derived from this software without
2401 + *    prior written permission. For written permission, please contact
2402 + *    licensing@OpenSSL.org.
2403 + *
2404 + * 5. Products derived from this software may not be called "OpenSSL"
2405 + *    nor may "OpenSSL" appear in their names without prior written
2406 + *    permission of the OpenSSL Project.
2407 + *
2408 + * 6. Redistributions of any form whatsoever must retain the following
2409 + *    acknowledgment:
2410 + *    "This product includes software developed by the OpenSSL Project
2411 + *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
2412 + *
2413 + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
2414 + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2415 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
2416 + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
2417 + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2418 + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
2419 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
2420 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2421 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
2422 + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2423 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
2424 + * OF THE POSSIBILITY OF SUCH DAMAGE.
2425 + * ====================================================================
2426 + *
2427 + * This product includes cryptographic software written by Eric Young
2428 + * (eay@cryptsoft.com).  This product includes software written by Tim
2429 + * Hudson (tjh@cryptsoft.com).
2430 + *
2431 + */
2432 +
2433 +#include <stdio.h>
2434 +#include <openssl/err.h>
2435 +#include "hw_pk11_err.h"
2436 +
2437 +/* BEGIN ERROR CODES */
2438 +#ifndef OPENSSL_NO_ERR
2439 +static ERR_STRING_DATA pk11_str_functs[]=
2440 +{
2441 +    {ERR_PACK(0,PK11_F_INIT,0),                    "PK11_INIT"},
2442 +    {ERR_PACK(0,PK11_F_FINISH,0),          "PK11_FINISH"},
2443 +    {ERR_PACK(0,PK11_F_DESTROY,0),         "PK11_DESTROY"},
2444 +    {ERR_PACK(0,PK11_F_CTRL,0),                    "PK11_CTRL"},
2445 +    {ERR_PACK(0,PK11_F_RSA_INIT,0),        "PK11_RSA_INIT"},
2446 +    {ERR_PACK(0,PK11_F_RSA_FINISH,0),      "PK11_RSA_FINISH"},
2447 +    {ERR_PACK(0,PK11_F_GET_PUB_RSA_KEY,0),  "PK11_GET_PUB_RSA_KEY"},
2448 +    {ERR_PACK(0,PK11_F_GET_PRIV_RSA_KEY,0), "PK11_GET_PRIV_RSA_KEY"},
2449 +    {ERR_PACK(0,PK11_F_RSA_GEN_KEY,0),      "PK11_RSA_GEN_KEY"},
2450 +    {ERR_PACK(0,PK11_F_RSA_PUB_ENC,0),      "PK11_RSA_PUB_ENC"},
2451 +    {ERR_PACK(0,PK11_F_RSA_PRIV_ENC,0),     "PK11_RSA_PRIV_ENC"},
2452 +    {ERR_PACK(0,PK11_F_RSA_PUB_DEC,0),      "PK11_RSA_PUB_DEC"},
2453 +    {ERR_PACK(0,PK11_F_RSA_PRIV_DEC,0),     "PK11_RSA_PRIV_DEC"},
2454 +    {ERR_PACK(0,PK11_F_RSA_SIGN,0),        "PK11_RSA_SIGN"},
2455 +    {ERR_PACK(0,PK11_F_RSA_VERIFY,0),      "PK11_RSA_VERIFY"},
2456 +    {ERR_PACK(0,PK11_F_RAND_ADD,0),        "PK11_RAND_ADD"},
2457 +    {ERR_PACK(0,PK11_F_RAND_BYTES,0),      "PK11_RAND_BYTES"},
2458 +    {ERR_PACK(0,PK11_F_GET_SESSION,0),      "PK11_GET_SESSION"},
2459 +    {ERR_PACK(0,PK11_F_FREE_SESSION,0),     "PK11_FREE_SESSION"},
2460 +    {ERR_PACK(0,PK11_F_LOAD_PUBKEY,0),      "PK11_LOAD_PUBKEY"},
2461 +    {ERR_PACK(0,PK11_F_LOAD_PRIVKEY,0),     "PK11_LOAD_PRIV_KEY"},
2462 +    {ERR_PACK(0,PK11_F_RSA_PUB_ENC_LOW,0),  "PK11_RSA_PUB_ENC_LOW"},
2463 +    {ERR_PACK(0,PK11_F_RSA_PRIV_ENC_LOW,0), "PK11_RSA_PRIV_ENC_LOW"},
2464 +    {ERR_PACK(0,PK11_F_RSA_PUB_DEC_LOW,0),  "PK11_RSA_PUB_DEC_LOW"},
2465 +    {ERR_PACK(0,PK11_F_RSA_PRIV_DEC_LOW,0), "PK11_RSA_PRIV_DEC_LOW"},
2466 +    {ERR_PACK(0,PK11_F_DSA_SIGN,0),         "PK11_DSA_SIGN"},
2467 +    {ERR_PACK(0,PK11_F_DSA_VERIFY,0),       "PK11_DSA_VERIFY"},
2468 +    {ERR_PACK(0,PK11_F_DSA_INIT,0),         "PK11_DSA_INIT"},
2469 +    {ERR_PACK(0,PK11_F_DSA_FINISH,0),       "PK11_DSA_FINISH"},
2470 +    {ERR_PACK(0,PK11_F_GET_PUB_DSA_KEY,0),  "PK11_GET_PUB_DSA_KEY"},
2471 +    {ERR_PACK(0,PK11_F_GET_PRIV_DSA_KEY,0), "PK11_GET_PRIV_DSA_KEY"},
2472 +    {ERR_PACK(0,PK11_F_DH_INIT,0),          "PK11_DH_INIT"},
2473 +    {ERR_PACK(0,PK11_F_DH_FINISH,0),        "PK11_DH_FINISH"},
2474 +    {ERR_PACK(0,PK11_F_MOD_EXP_DH,0),       "PK11_MOD_EXP_DH"},
2475 +    {ERR_PACK(0,PK11_F_GET_DH_KEY,0),       "PK11_GET_DH_KEY"},
2476 +    {ERR_PACK(0,PK11_F_FREE_ALL_SESSIONS,0),"PK11_FREE_ALL_SESSIONS"},
2477 +    {ERR_PACK(0,PK11_F_SETUP_SESSION,0),    "PK11_SETUP_SESSION"},
2478 +    {ERR_PACK(0,PK11_F_DESTROY_OBJECT,0),   "PK11_DESTROY_OBJECT"},
2479 +    {ERR_PACK(0,PK11_F_CIPHER_INIT,0),      "PK11_CIPHER_INIT"},
2480 +    {ERR_PACK(0,PK11_F_CIPHER_DO_CIPHER,0), "PK11_CIPHER_DO_CIPHER"},
2481 +    {ERR_PACK(0,PK11_F_GET_CIPHER_KEY,0),   "PK11_GET_CIPHER_KEY"},
2482 +    {ERR_PACK(0,PK11_F_DIGEST_INIT,0),      "PK11_DIGEST_INIT"},
2483 +    {ERR_PACK(0,PK11_F_DIGEST_UPDATE,0),    "PK11_DIGEST_UPDATE"},
2484 +    {ERR_PACK(0,PK11_F_DIGEST_FINAL,0),     "PK11_DIGEST_FINAL"},
2485 +    {ERR_PACK(0,PK11_F_CHOOSE_SLOT,0),      "PK11_CHOOSE_SLOT"},
2486 +    {ERR_PACK(0,PK11_F_CIPHER_FINAL,0),     "PK11_CIPHER_FINAL"},
2487 +    {ERR_PACK(0,PK11_F_LIBRARY_INIT,0),     "PK11_LIBRARY_INIT"},
2488 +    {ERR_PACK(0,PK11_F_LOAD,0),             "ENGINE_LOAD_PK11"},
2489 +    {ERR_PACK(0,PK11_F_DH_GEN_KEY,0),       "PK11_DH_GEN_KEY"},
2490 +    {ERR_PACK(0,PK11_F_DH_COMP_KEY,0),      "PK11_DH_COMP_KEY"},
2491 +    {ERR_PACK(0,PK11_F_DIGEST_COPY,0),      "PK11_DIGEST_COPY"},
2492 +    {0,NULL}
2493 +};
2494 +
2495 +static ERR_STRING_DATA pk11_str_reasons[]=
2496 +{
2497 +    {PK11_R_ALREADY_LOADED                 ,"PKCS#11 DSO already loaded"},
2498 +    {PK11_R_DSO_FAILURE                    ,"unable to load PKCS#11 DSO"},
2499 +    {PK11_R_NOT_LOADED                     ,"PKCS#11 DSO not loaded"},
2500 +    {PK11_R_PASSED_NULL_PARAMETER          ,"null parameter passed"},
2501 +    {PK11_R_COMMAND_NOT_IMPLEMENTED        ,"command not implemented"},
2502 +    {PK11_R_INITIALIZE                     ,"C_Initialize failed"},
2503 +    {PK11_R_FINALIZE                       ,"C_Finalize failed"},
2504 +    {PK11_R_GETINFO                        ,"C_GetInfo faile"},
2505 +    {PK11_R_GETSLOTLIST                    ,"C_GetSlotList failed"},
2506 +    {PK11_R_NO_MODULUS_OR_NO_EXPONENT      ,"no modulus or no exponent"},
2507 +    {PK11_R_ATTRIBUT_SENSITIVE_OR_INVALID  ,"attr sensitive or invalid"},
2508 +    {PK11_R_GETATTRIBUTVALUE               ,"C_GetAttributeValue failed"},
2509 +    {PK11_R_NO_MODULUS                     ,"no modulus"},
2510 +    {PK11_R_NO_EXPONENT                    ,"no exponent"},
2511 +    {PK11_R_FINDOBJECTSINIT                ,"C_FindObjectsInit failed"},
2512 +    {PK11_R_FINDOBJECTS                    ,"C_FindObjects failed"},
2513 +    {PK11_R_FINDOBJECTSFINAL               ,"C_FindObjectsFinal failed"},
2514 +    {PK11_R_CREATEOBJECT                   ,"C_CreateObject failed"},
2515 +    {PK11_R_DESTROYOBJECT                  ,"C_DestroyObject failed"},
2516 +    {PK11_R_OPENSESSION                    ,"C_OpenSession failed"},
2517 +    {PK11_R_CLOSESESSION                   ,"C_CloseSession failed"},
2518 +    {PK11_R_ENCRYPTINIT                    ,"C_EncryptInit failed"},
2519 +    {PK11_R_ENCRYPT                        ,"C_Encrypt failed"},
2520 +    {PK11_R_SIGNINIT                       ,"C_SignInit failed"},
2521 +    {PK11_R_SIGN                           ,"C_Sign failed"},
2522 +    {PK11_R_DECRYPTINIT                    ,"C_DecryptInit failed"},
2523 +    {PK11_R_DECRYPT                        ,"C_Decrypt failed"},
2524 +    {PK11_R_VERIFYINIT                     ,"C_VerifyRecover failed"},
2525 +    {PK11_R_VERIFY                         ,"C_Verify failed   "},
2526 +    {PK11_R_VERIFYRECOVERINIT              ,"C_VerifyRecoverInit failed"},
2527 +    {PK11_R_VERIFYRECOVER                  ,"C_VerifyRecover failed"},
2528 +    {PK11_R_GEN_KEY                        ,"C_GenerateKeyPair failed"},
2529 +    {PK11_R_SEEDRANDOM                     ,"C_SeedRandom failed"},
2530 +    {PK11_R_GENERATERANDOM                 ,"C_GenerateRandom failed"},
2531 +    {PK11_R_INVALID_MESSAGE_LENGTH         ,"invalid message length"},
2532 +    {PK11_R_UNKNOWN_ALGORITHM_TYPE         ,"unknown algorithm type"},
2533 +    {PK11_R_UNKNOWN_ASN1_OBJECT_ID         ,"unknown asn1 onject id"},
2534 +    {PK11_R_UNKNOWN_PADDING_TYPE           ,"unknown padding type"},
2535 +    {PK11_R_PADDING_CHECK_FAILED           ,"padding check failed"},
2536 +    {PK11_R_DIGEST_TOO_BIG                 ,"digest too big"},
2537 +    {PK11_R_MALLOC_FAILURE                 ,"malloc failure"},
2538 +    {PK11_R_CTRL_COMMAND_NOT_IMPLEMENTED   ,"ctl command not implemented"},
2539 +    {PK11_R_DATA_GREATER_THAN_MOD_LEN      ,"data is bigger than mod"},
2540 +    {PK11_R_DATA_TOO_LARGE_FOR_MODULUS     ,"data is too larger for mod"},
2541 +    {PK11_R_MISSING_KEY_COMPONENT          ,"a dsa component is missing"},
2542 +    {PK11_R_INVALID_SIGNATURE_LENGTH       ,"invalid signature length"},
2543 +    {PK11_R_INVALID_DSA_SIGNATURE_R        ,"missing r in dsa verify"},
2544 +    {PK11_R_INVALID_DSA_SIGNATURE_S        ,"missing s in dsa verify"},
2545 +    {PK11_R_INCONSISTENT_KEY               ,"inconsistent key type"},
2546 +    {PK11_R_ENCRYPTUPDATE                  ,"C_EncryptUpdate failed"},
2547 +    {PK11_R_DECRYPTUPDATE                  ,"C_DecryptUpdate failed"},
2548 +    {PK11_R_DIGESTINIT                     ,"C_DigestInit failed"},
2549 +    {PK11_R_DIGESTUPDATE                   ,"C_DigestUpdate failed"},
2550 +    {PK11_R_DIGESTFINAL                    ,"C_DigestFinal failed"},
2551 +    {PK11_R_ENCRYPTFINAL                   ,"C_EncryptFinal failed"},
2552 +    {PK11_R_DECRYPTFINAL                   ,"C_DecryptFinal failed"},
2553 +    {PK11_R_NO_PRNG_SUPPORT                ,"Slot does not support PRNG"},
2554 +    {PK11_R_GETTOKENINFO                   ,"C_GetTokenInfo failed"},
2555 +    {PK11_R_DERIVEKEY                      ,"C_DeriveKey failed"},
2556 +    {PK11_R_GET_OPERATION_STATE            ,"C_GetOperationState failed"},
2557 +    {PK11_R_SET_OPERATION_STATE            ,"C_SetOperationState failed"},
2558 +    {0,NULL}
2559 +};
2560 +
2561 +#endif 
2562 +
2563 +static int pk11_lib_error_code=0;
2564 +static int pk11_error_init=1;
2565 +
2566 +static void ERR_load_pk11_strings(void)
2567 +{
2568 +    if (pk11_lib_error_code == 0)
2569 +       pk11_lib_error_code = ERR_get_next_error_library();
2570 +
2571 +    if (pk11_error_init)
2572 +    {
2573 +       pk11_error_init=0;
2574 +#ifndef OPENSSL_NO_ERR
2575 +       ERR_load_strings(pk11_lib_error_code,pk11_str_functs);
2576 +       ERR_load_strings(pk11_lib_error_code,pk11_str_reasons);
2577 +#endif
2578 +    }
2579 +}
2580 +
2581 +static void ERR_unload_pk11_strings(void)
2582 +{
2583 +    if (pk11_error_init == 0)
2584 +    {
2585 +#ifndef OPENSSL_NO_ERR
2586 +       ERR_unload_strings(pk11_lib_error_code,pk11_str_functs);
2587 +       ERR_unload_strings(pk11_lib_error_code,pk11_str_reasons);
2588 +#endif
2589 +       pk11_error_init = 1;
2590 +    }
2591 +}
2592 +
2593 +static void ERR_pk11_error(int function, int reason, char *file, int line)
2594 +{
2595 +    if (pk11_lib_error_code == 0)
2596 +       pk11_lib_error_code=ERR_get_next_error_library();
2597 +    ERR_PUT_error(pk11_lib_error_code,function,reason,file,line);
2598 +}
2599 diff -r -u -N openssl-0.9.8g/crypto/engine/hw_pk11_err.h openssl/crypto/engine/hw_pk11_err.h
2600 --- openssl-0.9.8g/crypto/engine/hw_pk11_err.h  1970-01-01 01:00:00.000000000 +0100
2601 +++ openssl/crypto/engine/hw_pk11_err.h 2008-01-31 16:14:07.000000000 +0100
2602 @@ -0,0 +1,247 @@
2603 +/*
2604 + * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
2605 + * Use is subject to license terms.
2606 + */
2607 +#pragma ident  "@(#)hw_pk11_err.h      1.2     04/06/22 SMI"
2608 +
2609 +/* crypto/engine/hw_pk11_err.h */
2610 +/* This product includes software developed by the OpenSSL Project for 
2611 + * use in the OpenSSL Toolkit (http://www.openssl.org/).
2612 + *
2613 + * This project also referenced hw_pkcs11-0.9.7b.patch written by 
2614 + * Afchine Madjlessi.
2615 + */
2616 +/* ====================================================================
2617 + * Copyright (c) 2000-2001 The OpenSSL Project.  All rights reserved.
2618 + *
2619 + * Redistribution and use in source and binary forms, with or without
2620 + * modification, are permitted provided that the following conditions
2621 + * are met:
2622 + *
2623 + * 1. Redistributions of source code must retain the above copyright
2624 + *    notice, this list of conditions and the following disclaimer. 
2625 + *
2626 + * 2. Redistributions in binary form must reproduce the above copyright
2627 + *    notice, this list of conditions and the following disclaimer in
2628 + *    the documentation and/or other materials provided with the
2629 + *    distribution.
2630 + *
2631 + * 3. All advertising materials mentioning features or use of this
2632 + *    software must display the following acknowledgment:
2633 + *    "This product includes software developed by the OpenSSL Project
2634 + *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
2635 + *
2636 + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
2637 + *    endorse or promote products derived from this software without
2638 + *    prior written permission. For written permission, please contact
2639 + *    licensing@OpenSSL.org.
2640 + *
2641 + * 5. Products derived from this software may not be called "OpenSSL"
2642 + *    nor may "OpenSSL" appear in their names without prior written
2643 + *    permission of the OpenSSL Project.
2644 + *
2645 + * 6. Redistributions of any form whatsoever must retain the following
2646 + *    acknowledgment:
2647 + *    "This product includes software developed by the OpenSSL Project
2648 + *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
2649 + *
2650 + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
2651 + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2652 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
2653 + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
2654 + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2655 + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
2656 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
2657 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2658 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
2659 + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2660 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
2661 + * OF THE POSSIBILITY OF SUCH DAMAGE.
2662 + * ====================================================================
2663 + *
2664 + * This product includes cryptographic software written by Eric Young
2665 + * (eay@cryptsoft.com).  This product includes software written by Tim
2666 + * Hudson (tjh@cryptsoft.com).
2667 + *
2668 + */
2669 +
2670 +#ifndef HW_PK11_ERR_H
2671 +#define HW_PK11_ERR_H
2672 +
2673 +/* CRYPTO_LOCK_RSA is defined in OpenSSL for RSA method. Since this pk11
2674 + * engine replaces RSA method, we may reuse this lock here.
2675 + */
2676 +#define CRYPTO_LOCK_PK11_ENGINE CRYPTO_LOCK_RSA
2677 +
2678 +static void ERR_load_pk11_strings(void);
2679 +static void ERR_pk11_error(int function, int reason, char *file, int line);
2680 +#define PK11err(f,r) ERR_pk11_error((f),(r),__FILE__,__LINE__)
2681 +
2682 +/* Error codes for the PK11 functions. */
2683 +
2684 +/* Function codes. */
2685 +
2686 +#define PK11_F_INIT                            100
2687 +#define PK11_F_FINISH                          101
2688 +#define PK11_F_DESTROY                                 102
2689 +#define PK11_F_CTRL                            103
2690 +#define PK11_F_RSA_INIT                        104
2691 +#define PK11_F_RSA_FINISH                      105
2692 +#define PK11_F_GET_PUB_RSA_KEY                         106
2693 +#define PK11_F_GET_PRIV_RSA_KEY                107
2694 +#define PK11_F_RSA_GEN_KEY                     108
2695 +#define PK11_F_RSA_PUB_ENC                     109
2696 +#define PK11_F_RSA_PRIV_ENC                    110
2697 +#define PK11_F_RSA_PUB_DEC                     111
2698 +#define PK11_F_RSA_PRIV_DEC                    112
2699 +#define PK11_F_RSA_SIGN                        113
2700 +#define PK11_F_RSA_VERIFY                      114
2701 +#define PK11_F_RAND_ADD                        115
2702 +#define PK11_F_RAND_BYTES                      116
2703 +#define PK11_F_GET_SESSION                     117
2704 +#define PK11_F_FREE_SESSION                    118
2705 +#define PK11_F_LOAD_PUBKEY                     119
2706 +#define PK11_F_LOAD_PRIVKEY                    120
2707 +#define PK11_F_RSA_PUB_ENC_LOW                         121
2708 +#define PK11_F_RSA_PRIV_ENC_LOW                122
2709 +#define PK11_F_RSA_PUB_DEC_LOW                         123
2710 +#define PK11_F_RSA_PRIV_DEC_LOW                124
2711 +#define PK11_F_DSA_SIGN                                125
2712 +#define PK11_F_DSA_VERIFY                      126
2713 +#define PK11_F_DSA_INIT                                127
2714 +#define PK11_F_DSA_FINISH                      128
2715 +#define PK11_F_GET_PUB_DSA_KEY                         129
2716 +#define PK11_F_GET_PRIV_DSA_KEY                130
2717 +#define PK11_F_DH_INIT                                 131
2718 +#define PK11_F_DH_FINISH                       132
2719 +#define PK11_F_MOD_EXP_DH                      133
2720 +#define PK11_F_GET_DH_KEY                      134
2721 +#define PK11_F_FREE_ALL_SESSIONS               135
2722 +#define PK11_F_SETUP_SESSION                   136
2723 +#define PK11_F_DESTROY_OBJECT                  137
2724 +#define PK11_F_CIPHER_INIT                     138
2725 +#define PK11_F_CIPHER_DO_CIPHER                        139
2726 +#define PK11_F_GET_CIPHER_KEY                  140
2727 +#define PK11_F_DIGEST_INIT                     141
2728 +#define PK11_F_DIGEST_UPDATE                   142
2729 +#define PK11_F_DIGEST_FINAL                    143
2730 +#define PK11_F_CHOOSE_SLOT                     144
2731 +#define PK11_F_CIPHER_FINAL                    145
2732 +#define PK11_F_LIBRARY_INIT                    146
2733 +#define PK11_F_LOAD                            147
2734 +#define PK11_F_DH_GEN_KEY                      148
2735 +#define PK11_F_DH_COMP_KEY                     149
2736 +#define PK11_F_DIGEST_COPY                     150
2737 +
2738 +/* Reason codes. */
2739 +#define PK11_R_ALREADY_LOADED                  100
2740 +#define PK11_R_DSO_FAILURE                     101
2741 +#define PK11_R_NOT_LOADED                      102
2742 +#define PK11_R_PASSED_NULL_PARAMETER           103
2743 +#define PK11_R_COMMAND_NOT_IMPLEMENTED                 104
2744 +#define PK11_R_INITIALIZE                      105
2745 +#define PK11_R_FINALIZE                        106
2746 +#define PK11_R_GETINFO                                 107
2747 +#define PK11_R_GETSLOTLIST                     108
2748 +#define PK11_R_NO_MODULUS_OR_NO_EXPONENT       109
2749 +#define PK11_R_ATTRIBUT_SENSITIVE_OR_INVALID   110
2750 +#define PK11_R_GETATTRIBUTVALUE                111
2751 +#define PK11_R_NO_MODULUS                      112
2752 +#define PK11_R_NO_EXPONENT                     113
2753 +#define PK11_R_FINDOBJECTSINIT                         114
2754 +#define PK11_R_FINDOBJECTS                     115
2755 +#define PK11_R_FINDOBJECTSFINAL                116
2756 +#define PK11_R_CREATEOBJECT                    118
2757 +#define PK11_R_DESTROYOBJECT                   119
2758 +#define PK11_R_OPENSESSION                     120
2759 +#define PK11_R_CLOSESESSION                    121
2760 +#define PK11_R_ENCRYPTINIT                     122
2761 +#define PK11_R_ENCRYPT                                 123
2762 +#define PK11_R_SIGNINIT                        124
2763 +#define PK11_R_SIGN                            125
2764 +#define PK11_R_DECRYPTINIT                     126
2765 +#define PK11_R_DECRYPT                                 127
2766 +#define PK11_R_VERIFYINIT                      128
2767 +#define PK11_R_VERIFY                          129
2768 +#define PK11_R_VERIFYRECOVERINIT               130
2769 +#define PK11_R_VERIFYRECOVER                   131
2770 +#define PK11_R_GEN_KEY                                 132
2771 +#define PK11_R_SEEDRANDOM                      133
2772 +#define PK11_R_GENERATERANDOM                  134
2773 +#define PK11_R_INVALID_MESSAGE_LENGTH          135
2774 +#define PK11_R_UNKNOWN_ALGORITHM_TYPE          136
2775 +#define PK11_R_UNKNOWN_ASN1_OBJECT_ID          137
2776 +#define PK11_R_UNKNOWN_PADDING_TYPE            138
2777 +#define PK11_R_PADDING_CHECK_FAILED            139
2778 +#define PK11_R_DIGEST_TOO_BIG                  140
2779 +#define PK11_R_MALLOC_FAILURE                  141
2780 +#define PK11_R_CTRL_COMMAND_NOT_IMPLEMENTED    142
2781 +#define PK11_R_DATA_GREATER_THAN_MOD_LEN       143
2782 +#define PK11_R_DATA_TOO_LARGE_FOR_MODULUS      144
2783 +#define PK11_R_MISSING_KEY_COMPONENT           145
2784 +#define PK11_R_INVALID_SIGNATURE_LENGTH                146
2785 +#define PK11_R_INVALID_DSA_SIGNATURE_R         147
2786 +#define PK11_R_INVALID_DSA_SIGNATURE_S         148
2787 +#define PK11_R_INCONSISTENT_KEY                        149
2788 +#define PK11_R_ENCRYPTUPDATE                   150
2789 +#define PK11_R_DECRYPTUPDATE                   151
2790 +#define PK11_R_DIGESTINIT                      152
2791 +#define PK11_R_DIGESTUPDATE                    153
2792 +#define PK11_R_DIGESTFINAL                     154
2793 +#define PK11_R_ENCRYPTFINAL                    155
2794 +#define PK11_R_DECRYPTFINAL                    156
2795 +#define PK11_R_NO_PRNG_SUPPORT                 157
2796 +#define PK11_R_GETTOKENINFO                    158
2797 +#define PK11_R_DERIVEKEY                       159
2798 +#define PK11_R_GET_OPERATION_STATE             160
2799 +#define PK11_R_SET_OPERATION_STATE             161
2800 +#define PK11_R_INVALID_PIN                     162
2801 +#define PK11_R_TOO_MANY_OBJECTS                        163
2802 +#define PK11_R_OBJECT_NOT_FOUND                        164
2803 +
2804 +/* This structure encapsulates all reusable information for a PKCS#11
2805 + * session. A list of this object is created on behalf of the
2806 + * calling application using an on-demand method. When a new request
2807 + * comes in, an object will be taken from the list (if there is one)
2808 + * or a new one is created to handle the request. Note that not all
2809 + * fields are used for every application. For example, an RSA-only
2810 + * application only uses the RSA related fields */
2811 +typedef struct PK11_SESSION_st
2812 +        {
2813 +        struct PK11_SESSION_st *next;
2814 +        CK_SESSION_HANDLE       session;        /* PK11 session handle */
2815 +        CK_SESSION_HANDLE       session_cipher; /* PK11 sess handle for ciph */
2816 +        pid_t                   pid;            /* Current process ID */
2817 +        CK_OBJECT_HANDLE        rsa_pub_key;    /* RSA key handle in the sess */
2818 +       CK_OBJECT_HANDLE        rsa_priv_key;   /* RSA private key handle */
2819 +        CK_OBJECT_HANDLE        dsa_pub_key;    /* DSA pub key handle */
2820 +        CK_OBJECT_HANDLE        dsa_priv_key;   /* DSA priv key handle */
2821 +        CK_OBJECT_HANDLE        dh_key;         /* RSA pub key handle for DH */
2822 +        CK_OBJECT_HANDLE        cipher_key;     /* Cipher key handle */
2823 +        RSA                     *rsa;   /* Address of the RSA struct */
2824 +        void                    *dsa;   /* Address of the DSA structure */
2825 +        void                    *dh;    /* Address of the DH */
2826 +        unsigned char           key[24];/* Save the private key here */
2827 +        int                     key_len;/* Saved private key length */
2828 +        int                     encrypt;/* 1/0 for encrypt/decrypt */
2829 +        } PK11_SESSION;
2830 +
2831 +extern PK11_SESSION *pk11_get_session();
2832 +extern void pk11_return_session(PK11_SESSION *sp);
2833 +
2834 +extern int pk11_destroy_rsa_key_objects(PK11_SESSION *session);
2835 +extern int pk11_destroy_dsa_key_objects(PK11_SESSION *session);
2836 +extern int pk11_destroy_dh_key_objects(PK11_SESSION *session);
2837 +
2838 +extern RSA_METHOD *PK11_RSA(void);
2839 +extern DSA_METHOD *PK11_DSA(void);
2840 +extern DH_METHOD *PK11_DH(void);
2841 +
2842 +extern EVP_PKEY *pk11_load_privkey(ENGINE*, const char* pubkey_file,
2843 +        UI_METHOD *ui_method, void *callback_data);
2844 +extern EVP_PKEY *pk11_load_pubkey(ENGINE*, const char* pubkey_file,
2845 +        UI_METHOD *ui_method, void *callback_data);
2846 +
2847 +extern CK_FUNCTION_LIST_PTR pFuncList;
2848 +
2849 +#endif /* HW_PK11_ERR_H */
2850 diff -r -u -N openssl-0.9.8g/crypto/engine/hw_pk11_pub.c openssl/crypto/engine/hw_pk11_pub.c
2851 --- openssl-0.9.8g/crypto/engine/hw_pk11_pub.c  1970-01-01 01:00:00.000000000 +0100
2852 +++ openssl/crypto/engine/hw_pk11_pub.c 2008-03-17 15:15:49.000000000 +0100
2853 @@ -0,0 +1,2616 @@
2854 +/*
2855 + * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
2856 + * Use is subject to license terms.
2857 + */
2858 +#pragma ident  "@(#)hw_pk11_pub.c      1.4     07/05/10 SMI"
2859 +
2860 +/* crypto/engine/hw_pk11_pub.c */
2861 +/* This product includes software developed by the OpenSSL Project for 
2862 + * use in the OpenSSL Toolkit (http://www.openssl.org/).
2863 + *
2864 + * This project also referenced hw_pkcs11-0.9.7b.patch written by 
2865 + * Afchine Madjlessi.
2866 + */
2867 +/* ====================================================================
2868 + * Copyright (c) 2000-2001 The OpenSSL Project.  All rights reserved.
2869 + *
2870 + * Redistribution and use in source and binary forms, with or without
2871 + * modification, are permitted provided that the following conditions
2872 + * are met:
2873 + *
2874 + * 1. Redistributions of source code must retain the above copyright
2875 + *    notice, this list of conditions and the following disclaimer. 
2876 + *
2877 + * 2. Redistributions in binary form must reproduce the above copyright
2878 + *    notice, this list of conditions and the following disclaimer in
2879 + *    the documentation and/or other materials provided with the
2880 + *    distribution.
2881 + *
2882 + * 3. All advertising materials mentioning features or use of this
2883 + *    software must display the following acknowledgment:
2884 + *    "This product includes software developed by the OpenSSL Project
2885 + *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
2886 + *
2887 + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
2888 + *    endorse or promote products derived from this software without
2889 + *    prior written permission. For written permission, please contact
2890 + *    licensing@OpenSSL.org.
2891 + *
2892 + * 5. Products derived from this software may not be called "OpenSSL"
2893 + *    nor may "OpenSSL" appear in their names without prior written
2894 + *    permission of the OpenSSL Project.
2895 + *
2896 + * 6. Redistributions of any form whatsoever must retain the following
2897 + *    acknowledgment:
2898 + *    "This product includes software developed by the OpenSSL Project
2899 + *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
2900 + *
2901 + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
2902 + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2903 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
2904 + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
2905 + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2906 + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
2907 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
2908 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2909 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
2910 + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2911 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
2912 + * OF THE POSSIBILITY OF SUCH DAMAGE.
2913 + * ====================================================================
2914 + *
2915 + * This product includes cryptographic software written by Eric Young
2916 + * (eay@cryptsoft.com).  This product includes software written by Tim
2917 + * Hudson (tjh@cryptsoft.com).
2918 + *
2919 + */
2920 +
2921 +#include <stdio.h>
2922 +#include <assert.h>
2923 +#include <stdlib.h>
2924 +#include <string.h>
2925 +#include <sys/types.h>
2926 +#include <unistd.h>
2927 +
2928 +#include <openssl/e_os2.h>
2929 +#include <openssl/engine.h>
2930 +#include <openssl/dso.h>
2931 +#include <openssl/err.h>
2932 +#include <openssl/bn.h>
2933 +#include <openssl/pem.h>
2934 +#include <openssl/rsa.h>
2935 +#include <openssl/rand.h>
2936 +#include <openssl/objects.h>
2937 +#include <openssl/x509.h>
2938 +#include <cryptlib.h>
2939 +
2940 +#ifndef OPENSSL_NO_HW
2941 +#ifndef OPENSSL_NO_HW_PK11
2942 +
2943 +#include "cryptoki.h"
2944 +#include "pkcs11.h"
2945 +#include "hw_pk11_err.c"
2946 +
2947 +#ifndef OPENSSL_NO_RSA
2948 +/* RSA stuff */
2949 +static int pk11_RSA_public_encrypt(int flen, const unsigned char *from, 
2950 +       unsigned char *to, RSA *rsa, int padding);
2951 +static int pk11_RSA_private_encrypt(int flen, const unsigned char *from, 
2952 +       unsigned char *to, RSA *rsa, int padding);
2953 +static int pk11_RSA_public_decrypt(int flen, const unsigned char *from, 
2954 +       unsigned char *to, RSA *rsa, int padding);
2955 +static int pk11_RSA_private_decrypt(int flen, const unsigned char *from, 
2956 +       unsigned char *to, RSA *rsa, int padding);
2957 +static int pk11_RSA_init(RSA *rsa);
2958 +static int pk11_RSA_finish(RSA *rsa);
2959 +static int pk11_RSA_sign(int type, const unsigned char *m, unsigned int m_len,
2960 +       unsigned char *sigret, unsigned int *siglen, const RSA *rsa);
2961 +static int pk11_RSA_verify(int dtype, const unsigned char *m, 
2962 +       unsigned int m_len, unsigned char *sigbuf, unsigned int siglen, 
2963 +       const RSA *rsa);
2964 +EVP_PKEY *pk11_load_privkey(ENGINE*, const char* pubkey_file,
2965 +       UI_METHOD *ui_method, void *callback_data);
2966 +EVP_PKEY *pk11_load_pubkey(ENGINE*, const char* pubkey_file,
2967 +       UI_METHOD *ui_method, void *callback_data);
2968 +
2969 +static int pk11_RSA_public_encrypt_low(int flen, const unsigned char *from, 
2970 +       unsigned char *to, RSA *rsa);
2971 +static int pk11_RSA_private_encrypt_low(int flen, const unsigned char *from, 
2972 +       unsigned char *to, RSA *rsa);
2973 +static int pk11_RSA_public_decrypt_low(int flen, const unsigned char *from, 
2974 +       unsigned char *to, RSA *rsa);
2975 +static int pk11_RSA_private_decrypt_low(int flen, const unsigned char *from, 
2976 +       unsigned char *to, RSA *rsa);
2977 +
2978 +static CK_OBJECT_HANDLE pk11_get_public_rsa_key(RSA* rsa, PK11_SESSION *sp);
2979 +static CK_OBJECT_HANDLE pk11_get_private_rsa_key(RSA* rsa, 
2980 +       PK11_SESSION *sp);
2981 +#endif
2982 +
2983 +/* DSA stuff */
2984 +#ifndef OPENSSL_NO_DSA
2985 +static int pk11_DSA_init(DSA *dsa);
2986 +static int pk11_DSA_finish(DSA *dsa);
2987 +static DSA_SIG *pk11_dsa_do_sign(const unsigned char *dgst, int dlen, 
2988 +       DSA *dsa);
2989 +static int pk11_dsa_do_verify(const unsigned char *dgst, int dgst_len,
2990 +       DSA_SIG *sig, DSA *dsa);
2991 +
2992 +static CK_OBJECT_HANDLE pk11_get_public_dsa_key(DSA* dsa,
2993 +       PK11_SESSION *sp);
2994 +static CK_OBJECT_HANDLE pk11_get_private_dsa_key(DSA* dsa, 
2995 +       PK11_SESSION *sp);
2996 +#endif
2997 +
2998 +/* DH stuff */
2999 +#ifndef OPENSSL_NO_DH
3000 +static int pk11_DH_init(DH *dh);
3001 +static int pk11_DH_finish(DH *dh);
3002 +static int pk11_DH_generate_key(DH *dh);
3003 +static int pk11_DH_compute_key(unsigned char *key,
3004 +       const BIGNUM *pub_key,DH *dh);
3005 +
3006 +static CK_OBJECT_HANDLE pk11_get_dh_key(DH* dh, PK11_SESSION *sp);
3007 +#endif
3008 +
3009 +static int init_template_value(BIGNUM *bn, CK_VOID_PTR *pValue,
3010 +        CK_ULONG *ulValueLen);
3011 +static void check_new_rsa_key(PK11_SESSION *sp, void *rsa);
3012 +static void check_new_dsa_key(PK11_SESSION *sp, void *dsa);
3013 +static void check_new_dh_key(PK11_SESSION *sp, void *dh);
3014 +static void attr_to_BN(CK_ATTRIBUTE_PTR attr, CK_BYTE attr_data[], BIGNUM **bn);
3015 +
3016 +
3017 +#ifndef OPENSSL_NO_RSA
3018 +/* Our internal RSA_METHOD that we provide pointers to */
3019 +static RSA_METHOD pk11_rsa =
3020 +       {
3021 +       "PKCS#11 RSA method",
3022 +       pk11_RSA_public_encrypt,                /* rsa_pub_encrypt */
3023 +       pk11_RSA_public_decrypt,                /* rsa_pub_decrypt */
3024 +       pk11_RSA_private_encrypt,               /* rsa_priv_encrypt */
3025 +       pk11_RSA_private_decrypt,               /* rsa_priv_decrypt */
3026 +       NULL,                                   /* rsa_mod_exp */
3027 +       NULL,                                   /* bn_mod_exp */
3028 +       pk11_RSA_init,                          /* init */
3029 +       pk11_RSA_finish,                        /* finish */
3030 +       RSA_FLAG_SIGN_VER,                      /* flags */
3031 +       NULL,                                   /* app_data */
3032 +       pk11_RSA_sign,                          /* rsa_sign */
3033 +       pk11_RSA_verify/*,*/                    /* rsa_verify */
3034 +       };
3035 +
3036 +RSA_METHOD *PK11_RSA(void)
3037 +       {
3038 +       return(&pk11_rsa);
3039 +       }
3040 +#endif
3041 +
3042 +#ifndef OPENSSL_NO_DSA
3043 +/* Our internal DSA_METHOD that we provide pointers to */
3044 +static DSA_METHOD pk11_dsa =
3045 +       {
3046 +       "PKCS#11 DSA method",
3047 +       pk11_dsa_do_sign,       /* dsa_do_sign */
3048 +       NULL,                   /* dsa_sign_setup */
3049 +       pk11_dsa_do_verify,     /* dsa_do_verify */
3050 +       NULL,                   /* dsa_mod_exp */
3051 +       NULL,                   /* bn_mod_exp */
3052 +       pk11_DSA_init,          /* init */
3053 +       pk11_DSA_finish,        /* finish */
3054 +       0,                      /* flags */
3055 +       NULL                    /* app_data */
3056 +       };
3057 +
3058 +DSA_METHOD *PK11_DSA(void)
3059 +       {
3060 +       return(&pk11_dsa);
3061 +       }
3062 +
3063 +#endif
3064 +
3065 +
3066 +#ifndef OPENSSL_NO_DH
3067 +/* Our internal DH_METHOD that we provide pointers to */
3068 +static DH_METHOD pk11_dh =
3069 +       {
3070 +       "PKCS#11 DH method",
3071 +       pk11_DH_generate_key,   /* generate_key */
3072 +       pk11_DH_compute_key,    /* compute_key */
3073 +       NULL,                   /* bn_mod_exp */
3074 +       pk11_DH_init,           /* init */
3075 +       pk11_DH_finish,         /* finish */
3076 +       0,                      /* flags */
3077 +       NULL                    /* app_data */
3078 +       };
3079 +
3080 +DH_METHOD *PK11_DH(void)
3081 +       {
3082 +       return(&pk11_dh);
3083 +       }
3084 +#endif
3085 +
3086 +/* Size of an SSL signature: MD5+SHA1
3087 + */
3088 +#define SSL_SIG_LENGTH          36
3089 +
3090 +/* Lengths of DSA data and signature
3091 + */
3092 +#define DSA_DATA_LEN            20
3093 +#define DSA_SIGNATURE_LEN       40
3094 +
3095 +static CK_BBOOL true = TRUE;
3096 +static CK_BBOOL false = FALSE;
3097 +
3098 +#ifndef OPENSSL_NO_RSA
3099 +
3100 +/* Similiar to Openssl to take advantage of the paddings. The goal is to
3101 + * support all paddings in this engine although PK11 library does not 
3102 + * support all the paddings used in OpenSSL. 
3103 + * The input errors should have been checked in the padding functions
3104 + */
3105 +static int pk11_RSA_public_encrypt(int flen, const unsigned char *from,
3106 +               unsigned char *to, RSA *rsa, int padding)
3107 +       {
3108 +       int i,num=0,r= -1;
3109 +       unsigned char *buf=NULL;
3110 +
3111 +       num=BN_num_bytes(rsa->n);
3112 +       if ((buf=(unsigned char *)OPENSSL_malloc(num)) == NULL)
3113 +               {
3114 +               RSAerr(PK11_F_RSA_PUB_ENC,PK11_R_MALLOC_FAILURE);
3115 +               goto err;
3116 +               }
3117 +
3118 +       switch (padding)
3119 +               {
3120 +       case RSA_PKCS1_PADDING:
3121 +               i=RSA_padding_add_PKCS1_type_2(buf,num,from,flen);
3122 +               break;
3123 +#ifndef OPENSSL_NO_SHA
3124 +       case RSA_PKCS1_OAEP_PADDING:
3125 +               i=RSA_padding_add_PKCS1_OAEP(buf,num,from,flen,NULL,0);
3126 +               break;
3127 +#endif
3128 +       case RSA_SSLV23_PADDING:
3129 +               i=RSA_padding_add_SSLv23(buf,num,from,flen);
3130 +               break;
3131 +       case RSA_NO_PADDING:
3132 +               i=RSA_padding_add_none(buf,num,from,flen);
3133 +               break;
3134 +       default:
3135 +               RSAerr(PK11_F_RSA_PUB_ENC,PK11_R_UNKNOWN_PADDING_TYPE);
3136 +               goto err;
3137 +               }
3138 +       if (i <= 0) goto err;
3139 +
3140 +       /* PK11 functions are called here */
3141 +       r = pk11_RSA_public_encrypt_low(num, buf, to, rsa);
3142 +err:
3143 +       if (buf != NULL) 
3144 +               {
3145 +               OPENSSL_cleanse(buf,num);
3146 +               OPENSSL_free(buf);
3147 +               }
3148 +       return(r);
3149 +       }
3150 +
3151 +
3152 +/* Similar to Openssl to take advantage of the paddings. The input errors
3153 + * should be catched in the padding functions
3154 + */
3155 +static int pk11_RSA_private_encrypt(int flen, const unsigned char *from,
3156 +            unsigned char *to, RSA *rsa, int padding)
3157 +       {
3158 +       int i,num=0,r= -1;
3159 +       unsigned char *buf=NULL;
3160 +
3161 +       num=BN_num_bytes(rsa->n);
3162 +       if ((buf=(unsigned char *)OPENSSL_malloc(num)) == NULL)
3163 +               {
3164 +               RSAerr(PK11_F_RSA_PRIV_ENC,PK11_R_MALLOC_FAILURE);
3165 +               goto err;
3166 +               }
3167 +
3168 +       switch (padding)
3169 +               {
3170 +       case RSA_PKCS1_PADDING:
3171 +               i=RSA_padding_add_PKCS1_type_1(buf,num,from,flen);
3172 +               break;
3173 +       case RSA_NO_PADDING:
3174 +               i=RSA_padding_add_none(buf,num,from,flen);
3175 +               break;
3176 +       case RSA_SSLV23_PADDING:
3177 +       default:
3178 +               RSAerr(PK11_F_RSA_PRIV_ENC,PK11_R_UNKNOWN_PADDING_TYPE);
3179 +               goto err;
3180 +               }
3181 +       if (i <= 0) goto err;
3182 +
3183 +       /* PK11 functions are called here */
3184 +       r=pk11_RSA_private_encrypt_low(num, buf, to, rsa);
3185 +err:
3186 +       if (buf != NULL)
3187 +               {
3188 +               OPENSSL_cleanse(buf,num);
3189 +               OPENSSL_free(buf);
3190 +               }
3191 +       return(r);
3192 +       }
3193 +
3194 +/* Similar to Openssl. Input errors are also checked here
3195 + */
3196 +static int pk11_RSA_private_decrypt(int flen, const unsigned char *from,
3197 +            unsigned char *to, RSA *rsa, int padding)
3198 +       {
3199 +       BIGNUM f;
3200 +       int j,num=0,r= -1;
3201 +       unsigned char *p;
3202 +       unsigned char *buf=NULL;
3203 +
3204 +       BN_init(&f);
3205 +
3206 +       num=BN_num_bytes(rsa->n);
3207 +
3208 +       if ((buf=(unsigned char *)OPENSSL_malloc(num)) == NULL)
3209 +               {
3210 +               RSAerr(PK11_F_RSA_PRIV_DEC,PK11_R_MALLOC_FAILURE);
3211 +               goto err;
3212 +               }
3213 +
3214 +       /* This check was for equality but PGP does evil things
3215 +        * and chops off the top '0' bytes */
3216 +       if (flen > num)
3217 +               {
3218 +               RSAerr(PK11_F_RSA_PRIV_DEC,
3219 +                       PK11_R_DATA_GREATER_THAN_MOD_LEN);
3220 +               goto err;
3221 +               }
3222 +
3223 +       /* make data into a big number */
3224 +       if (BN_bin2bn(from,(int)flen,&f) == NULL) goto err;
3225 +
3226 +       if (BN_ucmp(&f, rsa->n) >= 0)
3227 +               {
3228 +               RSAerr(PK11_F_RSA_PRIV_DEC,
3229 +                       PK11_R_DATA_TOO_LARGE_FOR_MODULUS);
3230 +               goto err;
3231 +               }
3232 +
3233 +       /* PK11 functions are called here */
3234 +       r = pk11_RSA_private_decrypt_low(flen, from, buf, rsa);
3235 +
3236 +       /* PK11 CKM_RSA_X_509 mechanism pads 0's at the beginning.
3237 +        * Needs to skip these 0's paddings here */
3238 +       for (j = 0; j < r; j++)
3239 +               if (buf[j] != 0)
3240 +                       break;
3241 +
3242 +       p = buf + j;
3243 +       j = r - j;  /* j is only used with no-padding mode */
3244 +
3245 +       switch (padding)
3246 +               {
3247 +       case RSA_PKCS1_PADDING:
3248 +               r=RSA_padding_check_PKCS1_type_2(to,num,p,j,num);
3249 +               break;
3250 +#ifndef OPENSSL_NO_SHA
3251 +       case RSA_PKCS1_OAEP_PADDING:
3252 +               r=RSA_padding_check_PKCS1_OAEP(to,num,p,j,num,NULL,0);
3253 +               break;
3254 +#endif
3255 +       case RSA_SSLV23_PADDING:
3256 +               r=RSA_padding_check_SSLv23(to,num,p,j,num);
3257 +               break;
3258 +       case RSA_NO_PADDING:
3259 +               r=RSA_padding_check_none(to,num,p,j,num);
3260 +               break;
3261 +       default:
3262 +               RSAerr(PK11_F_RSA_PRIV_DEC,PK11_R_UNKNOWN_PADDING_TYPE);
3263 +               goto err;
3264 +               }
3265 +       if (r < 0)
3266 +               RSAerr(PK11_F_RSA_PRIV_DEC,PK11_R_PADDING_CHECK_FAILED);
3267 +
3268 +err:
3269 +       BN_clear_free(&f);
3270 +       if (buf != NULL)
3271 +               {
3272 +               OPENSSL_cleanse(buf,num);
3273 +               OPENSSL_free(buf);
3274 +               }
3275 +       return(r);
3276 +       }
3277 +
3278 +/* Similar to Openssl. Input errors are also checked here
3279 + */
3280 +static int pk11_RSA_public_decrypt(int flen, const unsigned char *from,
3281 +            unsigned char *to, RSA *rsa, int padding)
3282 +       {
3283 +       BIGNUM f;
3284 +       int i,num=0,r= -1;
3285 +       unsigned char *p;
3286 +       unsigned char *buf=NULL;
3287 +
3288 +       BN_init(&f);
3289 +       num=BN_num_bytes(rsa->n);
3290 +       buf=(unsigned char *)OPENSSL_malloc(num);
3291 +       if (buf == NULL)
3292 +               {
3293 +               RSAerr(PK11_F_RSA_PUB_DEC,PK11_R_MALLOC_FAILURE);
3294 +               goto err;
3295 +               }
3296 +
3297 +       /* This check was for equality but PGP does evil things
3298 +        * and chops off the top '0' bytes */
3299 +       if (flen > num)
3300 +               {
3301 +               RSAerr(PK11_F_RSA_PUB_DEC,PK11_R_DATA_GREATER_THAN_MOD_LEN);
3302 +               goto err;
3303 +               }
3304 +
3305 +       if (BN_bin2bn(from,flen,&f) == NULL) goto err;
3306 +
3307 +       if (BN_ucmp(&f, rsa->n) >= 0)
3308 +               {
3309 +               RSAerr(PK11_F_RSA_PUB_DEC,
3310 +                       PK11_R_DATA_TOO_LARGE_FOR_MODULUS);
3311 +               goto err;
3312 +               }
3313 +
3314 +       /* PK11 functions are called here */
3315 +       r = pk11_RSA_public_decrypt_low(flen, from, buf, rsa);
3316 +
3317 +       /* PK11 CKM_RSA_X_509 mechanism pads 0's at the beginning.
3318 +        * Needs to skip these 0's here */
3319 +       for (i = 0; i < r; i++)
3320 +               if (buf[i] != 0)
3321 +                       break;
3322 +
3323 +       p = buf + i;
3324 +       i = r - i;  /* i is only used with no-padding mode */
3325 +
3326 +       switch (padding)
3327 +               {
3328 +       case RSA_PKCS1_PADDING:
3329 +               r=RSA_padding_check_PKCS1_type_1(to,num,p,i,num);
3330 +               break;
3331 +       case RSA_NO_PADDING:
3332 +               r=RSA_padding_check_none(to,num,p,i,num);
3333 +               break;
3334 +       default:
3335 +               RSAerr(PK11_F_RSA_PUB_DEC,PK11_R_UNKNOWN_PADDING_TYPE);
3336 +               goto err;
3337 +               }
3338 +       if (r < 0)
3339 +               RSAerr(PK11_F_RSA_PUB_DEC,PK11_R_PADDING_CHECK_FAILED);
3340 +
3341 +err:
3342 +       BN_clear_free(&f);
3343 +       if (buf != NULL)
3344 +               {
3345 +               OPENSSL_cleanse(buf,num);
3346 +               OPENSSL_free(buf);
3347 +               }
3348 +       return(r);
3349 +       }
3350 +
3351 +/* This function implements RSA public encryption using C_EncryptInit and
3352 + * C_Encrypt pk11 interfaces. Note that the CKM_RSA_X_509 is used here.
3353 + * The calling function allocated sufficient memory in "to" to store results.
3354 + */
3355 +static int pk11_RSA_public_encrypt_low(int flen,
3356 +       const unsigned char *from, unsigned char *to, RSA *rsa)
3357 +       {
3358 +       CK_ULONG bytes_encrypted=flen;
3359 +       int retval = -1;
3360 +       CK_RV rv;
3361 +       CK_MECHANISM mech_rsa = {CKM_RSA_X_509, NULL, 0};
3362 +       CK_MECHANISM *p_mech = &mech_rsa;
3363 +       CK_OBJECT_HANDLE h_pub_key = CK_INVALID_HANDLE;
3364 +       PK11_SESSION *sp;
3365 +       char tmp_buf[20];
3366 +       
3367 +       if ((sp = pk11_get_session()) == NULL)
3368 +               return -1;
3369 +
3370 +       check_new_rsa_key(sp, (void *) rsa);
3371 +       
3372 +       h_pub_key = sp->rsa_pub_key;
3373 +       if (h_pub_key == CK_INVALID_HANDLE)
3374 +               h_pub_key = sp->rsa_pub_key = 
3375 +                       pk11_get_public_rsa_key(rsa, sp);
3376 +
3377 +       if (h_pub_key != CK_INVALID_HANDLE)
3378 +               {
3379 +               rv = pFuncList->C_EncryptInit(sp->session, p_mech, 
3380 +                       h_pub_key);
3381 +
3382 +               if (rv != CKR_OK)
3383 +                       {
3384 +                       PK11err(PK11_F_RSA_PUB_ENC_LOW, 
3385 +                               PK11_R_ENCRYPTINIT);
3386 +                       snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
3387 +                       ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
3388 +                       pk11_return_session(sp);
3389 +                       return -1;
3390 +                       }
3391 +       
3392 +               rv = pFuncList->C_Encrypt(sp->session, 
3393 +                       (unsigned char *)from, flen, to, &bytes_encrypted);
3394 +
3395 +               if (rv != CKR_OK)
3396 +                       {
3397 +                       PK11err(PK11_F_RSA_PUB_ENC_LOW, PK11_R_ENCRYPT);
3398 +                       snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
3399 +                       ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
3400 +                       pk11_return_session(sp);
3401 +                       return -1;
3402 +                       }
3403 +               retval = bytes_encrypted;
3404 +               }
3405 +       
3406 +       pk11_return_session(sp);
3407 +       return retval;
3408 +       }
3409 +
3410 +
3411 +/* This function implements RSA private encryption using C_SignInit and 
3412 + * C_Sign pk11 APIs. Note that CKM_RSA_X_509 is used here.
3413 + * The calling function allocated sufficient memory in "to" to store results.
3414 + */
3415 +static int pk11_RSA_private_encrypt_low(int flen,
3416 +       const unsigned char *from, unsigned char *to, RSA *rsa)
3417 +       {
3418 +       CK_ULONG ul_sig_len=flen;
3419 +       int retval = -1;
3420 +       CK_RV rv;
3421 +       CK_MECHANISM mech_rsa = {CKM_RSA_X_509, NULL, 0};
3422 +       CK_MECHANISM *p_mech = &mech_rsa;
3423 +       CK_OBJECT_HANDLE h_priv_key= CK_INVALID_HANDLE;
3424 +       PK11_SESSION *sp;
3425 +       char tmp_buf[20];
3426 +       
3427 +       if ((sp = pk11_get_session()) == NULL)
3428 +               return -1;
3429 +       
3430 +       check_new_rsa_key(sp, (void *) rsa);
3431 +       
3432 +       h_priv_key = sp->rsa_priv_key;
3433 +       if (h_priv_key == CK_INVALID_HANDLE)
3434 +               h_priv_key = sp->rsa_priv_key = 
3435 +                       pk11_get_private_rsa_key(rsa, sp);
3436 +       
3437 +       if (h_priv_key != CK_INVALID_HANDLE)
3438 +               {
3439 +               rv = pFuncList->C_SignInit(sp->session, p_mech, 
3440 +                       h_priv_key);
3441 +
3442 +               if (rv != CKR_OK)
3443 +                       {
3444 +                       PK11err(PK11_F_RSA_PRIV_ENC_LOW, PK11_R_SIGNINIT);
3445 +                       snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
3446 +                       ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
3447 +                       pk11_return_session(sp);
3448 +                       return -1;
3449 +                       }
3450 +       
3451 +               rv = pFuncList->C_Sign(sp->session, 
3452 +                       (unsigned char *)from, flen, to, &ul_sig_len);
3453 +
3454 +               if (rv != CKR_OK)
3455 +                       {
3456 +                       PK11err(PK11_F_RSA_PRIV_ENC_LOW, PK11_R_SIGN);
3457 +                       snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
3458 +                       ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
3459 +                       pk11_return_session(sp);
3460 +                       return -1;
3461 +                       }
3462 +
3463 +               retval = ul_sig_len;
3464 +               }
3465 +       
3466 +       pk11_return_session(sp);
3467 +       return retval;
3468 +       }
3469 +
3470 +
3471 +/* This function implements RSA private decryption using C_DecryptInit and
3472 + * C_Decrypt pk11 APIs. Note that CKM_RSA_X_509 mechanism is used here.
3473 + * The calling function allocated sufficient memory in "to" to store results.
3474 + */
3475 +static int pk11_RSA_private_decrypt_low(int flen,
3476 +       const unsigned char *from, unsigned char *to, RSA *rsa)
3477 +       {
3478 +       CK_ULONG bytes_decrypted = flen;
3479 +       int retval = -1;
3480 +       CK_RV rv;
3481 +       CK_MECHANISM mech_rsa = {CKM_RSA_X_509, NULL, 0};
3482 +       CK_MECHANISM *p_mech = &mech_rsa;
3483 +       CK_OBJECT_HANDLE h_priv_key;
3484 +       PK11_SESSION *sp;
3485 +       char tmp_buf[20];
3486 +       
3487 +       if ((sp = pk11_get_session()) == NULL)
3488 +               return -1;
3489 +       
3490 +       check_new_rsa_key(sp, (void *) rsa);
3491 +       
3492 +       h_priv_key = sp->rsa_priv_key;
3493 +       if (h_priv_key == CK_INVALID_HANDLE)
3494 +               h_priv_key = sp->rsa_priv_key = 
3495 +                       pk11_get_private_rsa_key(rsa, sp);
3496 +
3497 +       if (h_priv_key != CK_INVALID_HANDLE)
3498 +               {
3499 +               rv = pFuncList->C_DecryptInit(sp->session, p_mech, 
3500 +                       h_priv_key);
3501 +
3502 +               if (rv != CKR_OK)
3503 +                       {
3504 +                       PK11err(PK11_F_RSA_PRIV_DEC_LOW, 
3505 +                               PK11_R_DECRYPTINIT);
3506 +                       snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
3507 +                       ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
3508 +                       pk11_return_session(sp);
3509 +                       return -1;
3510 +                       }
3511 +       
3512 +               rv = pFuncList->C_Decrypt(sp->session, 
3513 +                       (unsigned char *)from, flen, to, &bytes_decrypted);
3514 +
3515 +               if (rv != CKR_OK)
3516 +                       {
3517 +                       PK11err(PK11_F_RSA_PRIV_DEC_LOW, PK11_R_DECRYPT);
3518 +                       snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
3519 +                       ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
3520 +                       pk11_return_session(sp);
3521 +                       return -1;
3522 +                       }
3523 +               retval = bytes_decrypted;
3524 +               }
3525 +
3526 +       pk11_return_session(sp);
3527 +       return retval;
3528 +       }
3529 +
3530 +
3531 +/* This function implements RSA public decryption using C_VerifyRecoverInit 
3532 + * and C_VerifyRecover pk11 APIs. Note that CKM_RSA_X_509 is used here.
3533 + * The calling function allocated sufficient memory in "to" to store results.
3534 + */
3535 +static int pk11_RSA_public_decrypt_low(int flen,
3536 +       const unsigned char *from, unsigned char *to, RSA *rsa)
3537 +       {
3538 +       CK_ULONG bytes_decrypted = flen;
3539 +       int retval = -1;
3540 +       CK_RV rv;
3541 +       CK_MECHANISM mech_rsa = {CKM_RSA_X_509, NULL, 0};
3542 +       CK_MECHANISM *p_mech = &mech_rsa;
3543 +       CK_OBJECT_HANDLE h_pub_key = CK_INVALID_HANDLE;
3544 +       PK11_SESSION *sp;
3545 +       char tmp_buf[20];
3546 +       
3547 +       if ((sp = pk11_get_session()) == NULL)
3548 +               return -1;
3549 +       
3550 +       check_new_rsa_key(sp, (void *) rsa);
3551 +       
3552 +       h_pub_key = sp->rsa_pub_key;
3553 +       if (h_pub_key == CK_INVALID_HANDLE)
3554 +               h_pub_key = sp->rsa_pub_key = 
3555 +                       pk11_get_public_rsa_key(rsa, sp);
3556 +
3557 +       if (h_pub_key != CK_INVALID_HANDLE)
3558 +               {       
3559 +               rv = pFuncList->C_VerifyRecoverInit(sp->session, 
3560 +                       p_mech, h_pub_key);
3561 +
3562 +               if (rv != CKR_OK)
3563 +                       {
3564 +                       PK11err(PK11_F_RSA_PUB_DEC_LOW, 
3565 +                               PK11_R_VERIFYRECOVERINIT);
3566 +                       snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
3567 +                       ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
3568 +                       pk11_return_session(sp);
3569 +                       return -1;
3570 +                       }
3571 +       
3572 +               rv = pFuncList->C_VerifyRecover(sp->session, 
3573 +                       (unsigned char *)from, flen, to, &bytes_decrypted);
3574 +
3575 +               if (rv != CKR_OK)
3576 +                       {
3577 +                       PK11err(PK11_F_RSA_PUB_DEC_LOW, 
3578 +                               PK11_R_VERIFYRECOVER);
3579 +                       snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
3580 +                       ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
3581 +                       pk11_return_session(sp);
3582 +                       return -1;
3583 +                       }
3584 +               retval = bytes_decrypted;
3585 +               }
3586 +
3587 +       pk11_return_session(sp);
3588 +       return retval;
3589 +       }
3590 +
3591 +
3592 +static int pk11_RSA_init(RSA *rsa)
3593 +       {
3594 +       /* This flag in the RSA_METHOD enables the new rsa_sign, 
3595 +        * rsa_verify functions. See rsa.h for details. */
3596 +       rsa->flags |= RSA_FLAG_SIGN_VER;
3597 +
3598 +       return 1;
3599 +       }
3600 +
3601 +
3602 +static int pk11_RSA_finish(RSA *rsa)
3603 +       {
3604 +       if (rsa->_method_mod_n != NULL)
3605 +               BN_MONT_CTX_free(rsa->_method_mod_n);
3606 +       if (rsa->_method_mod_p != NULL)
3607 +               BN_MONT_CTX_free(rsa->_method_mod_p);
3608 +       if (rsa->_method_mod_q != NULL)
3609 +               BN_MONT_CTX_free(rsa->_method_mod_q);
3610 +       
3611 +       return pk11_destroy_rsa_key_objects(NULL);
3612 +       }
3613 +
3614 +
3615 +/* Standard engine interface function. Majority codes here are from 
3616 + * rsa/rsa_sign.c. We replaced the decrypt function call by C_Sign of PKCS#11.
3617 + * See more details in rsa/rsa_sign.c */
3618 +static int pk11_RSA_sign(int type, const unsigned char *m, unsigned int m_len,
3619 +       unsigned char *sigret, unsigned int *siglen, const RSA *rsa)
3620 +       {
3621 +       X509_SIG sig;
3622 +       ASN1_TYPE parameter;
3623 +       int i,j;
3624 +       unsigned char *p,*s = NULL;
3625 +       X509_ALGOR algor;
3626 +       ASN1_OCTET_STRING digest;
3627 +       CK_RV rv;
3628 +       CK_MECHANISM mech_rsa = {CKM_RSA_PKCS, NULL, 0};
3629 +       CK_MECHANISM *p_mech = &mech_rsa;
3630 +       CK_OBJECT_HANDLE h_priv_key;
3631 +       PK11_SESSION *sp = NULL;
3632 +       int ret = 0;
3633 +       char tmp_buf[20];
3634 +       unsigned long ulsiglen;
3635 +
3636 +       /* Encode the digest */
3637 +       /* Special case: SSL signature, just check the length */
3638 +       if (type == NID_md5_sha1)
3639 +               {
3640 +               if (m_len != SSL_SIG_LENGTH)
3641 +                       {
3642 +                       PK11err(PK11_F_RSA_SIGN, 
3643 +                               PK11_R_INVALID_MESSAGE_LENGTH);
3644 +                       goto err;
3645 +                       }
3646 +               i = SSL_SIG_LENGTH;
3647 +               s = (unsigned char *)m;
3648 +               }
3649 +       else
3650 +               {
3651 +               sig.algor= &algor;
3652 +               sig.algor->algorithm=OBJ_nid2obj(type);
3653 +               if (sig.algor->algorithm == NULL)
3654 +                       {
3655 +                       PK11err(PK11_F_RSA_SIGN, 
3656 +                               PK11_R_UNKNOWN_ALGORITHM_TYPE);
3657 +                       goto err;
3658 +                       }
3659 +               if (sig.algor->algorithm->length == 0)
3660 +                       {
3661 +                       PK11err(PK11_F_RSA_SIGN, 
3662 +                               PK11_R_UNKNOWN_ASN1_OBJECT_ID);
3663 +                       goto err;
3664 +                       }
3665 +               parameter.type=V_ASN1_NULL;
3666 +               parameter.value.ptr=NULL;
3667 +               sig.algor->parameter= &parameter;
3668 +       
3669 +               sig.digest= &digest;
3670 +               sig.digest->data=(unsigned char *)m;
3671 +               sig.digest->length=m_len;
3672 +       
3673 +               i=i2d_X509_SIG(&sig,NULL);
3674 +               }
3675 +       
3676 +       j=RSA_size(rsa);
3677 +       if ((i-RSA_PKCS1_PADDING) > j)
3678 +               {
3679 +               PK11err(PK11_F_RSA_SIGN, PK11_R_DIGEST_TOO_BIG);
3680 +               goto err;
3681 +               }
3682 +       
3683 +       if (type != NID_md5_sha1)
3684 +               {
3685 +               s=(unsigned char *)OPENSSL_malloc((unsigned int)j+1);
3686 +               if (s == NULL)
3687 +                       {
3688 +                       PK11err(PK11_F_RSA_SIGN, PK11_R_MALLOC_FAILURE);
3689 +                       goto err;
3690 +                       }
3691 +               p=s;
3692 +               i2d_X509_SIG(&sig,&p);
3693 +               }
3694 +       
3695 +       if ((sp = pk11_get_session()) == NULL)
3696 +               goto err;
3697 +
3698 +       check_new_rsa_key(sp, (void *) rsa);
3699 +       
3700 +       h_priv_key = sp->rsa_priv_key;
3701 +       if (h_priv_key == CK_INVALID_HANDLE)
3702 +               h_priv_key = sp->rsa_priv_key = 
3703 +                       pk11_get_private_rsa_key((RSA *)rsa, sp);
3704 +
3705 +       if (h_priv_key != CK_INVALID_HANDLE)
3706 +               {
3707 +               rv = pFuncList->C_SignInit(sp->session, p_mech, h_priv_key);
3708 +
3709 +               if (rv != CKR_OK)
3710 +                       {
3711 +                       PK11err(PK11_F_RSA_SIGN, PK11_R_SIGNINIT);
3712 +                       snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
3713 +                       ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
3714 +                       goto err;
3715 +                       }
3716 +
3717 +               ulsiglen = j;
3718 +               rv = pFuncList->C_Sign(sp->session, s, i, sigret, 
3719 +                       (CK_ULONG_PTR) &ulsiglen);
3720 +               *siglen = ulsiglen;
3721 +
3722 +               if (rv != CKR_OK)
3723 +                       {
3724 +                       PK11err(PK11_F_RSA_SIGN, PK11_R_SIGN);
3725 +                       snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
3726 +                       ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
3727 +                       goto err;
3728 +                       }
3729 +               ret = 1;
3730 +               }
3731 +
3732 +err:
3733 +       if (type != NID_md5_sha1)
3734 +               {
3735 +               memset(s,0,(unsigned int)j+1);
3736 +               OPENSSL_free(s);
3737 +               }
3738 +       
3739 +       pk11_return_session(sp);
3740 +       return ret;
3741 +       }
3742 +
3743 +static int pk11_RSA_verify(int type, const unsigned char *m,
3744 +       unsigned int m_len, unsigned char *sigbuf, unsigned int siglen,
3745 +       const RSA *rsa)
3746 +       {
3747 +       X509_SIG sig;
3748 +       ASN1_TYPE parameter;
3749 +       int i,j;
3750 +       unsigned char *p,*s = NULL;
3751 +       X509_ALGOR algor;
3752 +       ASN1_OCTET_STRING digest;
3753 +       CK_RV rv;
3754 +       CK_MECHANISM mech_rsa = {CKM_RSA_PKCS, NULL, 0};
3755 +       CK_MECHANISM *p_mech = &mech_rsa;
3756 +       CK_OBJECT_HANDLE h_pub_key;
3757 +       PK11_SESSION *sp = NULL;
3758 +       int ret = 0;
3759 +       char tmp_buf[20];
3760 +
3761 +       /* Encode the digest    */
3762 +       /* Special case: SSL signature, just check the length */
3763 +       if (type == NID_md5_sha1)
3764 +               {
3765 +               if (m_len != SSL_SIG_LENGTH)
3766 +                       {
3767 +                       PK11err(PK11_F_RSA_VERIFY, 
3768 +                               PK11_R_INVALID_MESSAGE_LENGTH);
3769 +                       goto err;
3770 +                       }
3771 +               i = SSL_SIG_LENGTH;
3772 +               s = (unsigned char *)m;
3773 +               }
3774 +       else
3775 +               {
3776 +               sig.algor= &algor;
3777 +               sig.algor->algorithm=OBJ_nid2obj(type);
3778 +               if (sig.algor->algorithm == NULL)
3779 +                       {
3780 +                       PK11err(PK11_F_RSA_VERIFY, 
3781 +                               PK11_R_UNKNOWN_ALGORITHM_TYPE);
3782 +                       goto err;
3783 +                       }
3784 +               if (sig.algor->algorithm->length == 0)
3785 +                       {
3786 +                       PK11err(PK11_F_RSA_VERIFY, 
3787 +                               PK11_R_UNKNOWN_ASN1_OBJECT_ID);
3788 +                       goto err;
3789 +                       }
3790 +               parameter.type=V_ASN1_NULL;
3791 +               parameter.value.ptr=NULL;
3792 +               sig.algor->parameter= &parameter;
3793 +               sig.digest= &digest;
3794 +               sig.digest->data=(unsigned char *)m;
3795 +               sig.digest->length=m_len;
3796 +               i=i2d_X509_SIG(&sig,NULL);
3797 +               }
3798 +       
3799 +       j=RSA_size(rsa);
3800 +       if ((i-RSA_PKCS1_PADDING) > j)
3801 +               {
3802 +               PK11err(PK11_F_RSA_VERIFY, PK11_R_DIGEST_TOO_BIG);
3803 +               goto err;
3804 +               }
3805 +       
3806 +       if (type != NID_md5_sha1)
3807 +               {
3808 +               s=(unsigned char *)OPENSSL_malloc((unsigned int)j+1);
3809 +               if (s == NULL)
3810 +                       {
3811 +                       PK11err(PK11_F_RSA_VERIFY, PK11_R_MALLOC_FAILURE);
3812 +                       goto err;
3813 +                       }
3814 +               p=s;
3815 +               i2d_X509_SIG(&sig,&p);
3816 +               }
3817 +       
3818 +       if ((sp = pk11_get_session()) == NULL)
3819 +               goto err;
3820 +       
3821 +       check_new_rsa_key(sp, (void *) rsa);
3822 +       
3823 +       h_pub_key = sp->rsa_pub_key;
3824 +       if (h_pub_key == CK_INVALID_HANDLE)
3825 +               h_pub_key = sp->rsa_pub_key = 
3826 +                       pk11_get_public_rsa_key((RSA *)rsa, sp);
3827 +
3828 +       if (h_pub_key != CK_INVALID_HANDLE)
3829 +               {
3830 +               rv = pFuncList->C_VerifyInit(sp->session, p_mech, 
3831 +                       h_pub_key);
3832 +
3833 +               if (rv != CKR_OK)
3834 +                       {
3835 +                       PK11err(PK11_F_RSA_VERIFY, PK11_R_VERIFYINIT);
3836 +                       snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
3837 +                       ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
3838 +                       goto err;
3839 +                       }
3840 +               rv = pFuncList->C_Verify(sp->session, s, i, sigbuf, 
3841 +                       (CK_ULONG)siglen);
3842 +
3843 +               if (rv != CKR_OK)
3844 +                       {
3845 +                       PK11err(PK11_F_RSA_VERIFY, PK11_R_VERIFY);
3846 +                       snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
3847 +                       ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
3848 +                       goto err;
3849 +                       }
3850 +               ret = 1;
3851 +               }
3852 +
3853 +err:
3854 +       if (type != NID_md5_sha1)
3855 +               {
3856 +               memset(s,0,(unsigned int)siglen);
3857 +               OPENSSL_free(s);
3858 +               }
3859 +
3860 +       pk11_return_session(sp);
3861 +       return ret;
3862 +       }
3863 +
3864 +static int hndidx_rsa = -1;
3865 +
3866 +struct key_info {
3867 +       CK_OBJECT_HANDLE handle;
3868 +       CK_SESSION_HANDLE session;
3869 +};
3870 +
3871 +/* Destroy the object when the last reference to it has gone.
3872 + */
3873 +static void hndidx_free(void *obj, void *item, CRYPTO_EX_DATA *ad,
3874 +                       int ind, long argl, void *argp)
3875 +{
3876 +       struct key_info *key_info = item;
3877 +       CK_RV rv;
3878 +       char tmp_buf[20];
3879 +
3880 +       if (key_info != NULL)
3881 +               {
3882 +                rv = pFuncList->C_DestroyObject(key_info->session,
3883 +                                               key_info->handle);
3884 +                if (rv != CKR_OK)
3885 +                        {
3886 +                        PK11err(PK11_F_DESTROY_OBJECT, PK11_R_DESTROYOBJECT);
3887 +                        snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
3888 +                        ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
3889 +                        }
3890 +               free(item);
3891 +               }
3892 +}
3893 +
3894 +EVP_PKEY *pk11_load_privkey(ENGINE* e, const char* privkey_file,
3895 +       UI_METHOD *ui_method, void *callback_data)
3896 +       {
3897 +       EVP_PKEY *pkey=NULL;
3898 +       FILE *privkey;
3899 +       CK_OBJECT_HANDLE  h_priv_key = CK_INVALID_HANDLE;
3900 +       RSA *rsa;
3901 +       PK11_SESSION *sp;
3902 +       /* everything else below needed for key by reference extension */
3903 +       char tmp_buf[20];
3904 +       CK_RV rv;
3905 +       CK_ULONG objcnt = 0;
3906 +       CK_BBOOL is_token = TRUE;
3907 +       CK_BYTE attr_data[2][1024];
3908 +       CK_OBJECT_CLASS key_class = CKO_PRIVATE_KEY;
3909 +       CK_OBJECT_HANDLE ks_key = CK_INVALID_HANDLE;    /* key in keystore */
3910 +       struct key_info *key_info = NULL; 
3911 +       extern char *pk11_pin;
3912 +
3913 +       /* we look for private keys only */
3914 +       CK_ATTRIBUTE search_templ[] =
3915 +               {
3916 +               {CKA_TOKEN, &is_token, sizeof(is_token)},
3917 +               {CKA_CLASS, &key_class, sizeof(key_class)},
3918 +               {CKA_LABEL, NULL, 0}
3919 +               };
3920 +
3921 +       /* these attributes are needed to initialize OpenSSL RSA structure */
3922 +       CK_ATTRIBUTE get_templ[] =
3923 +               {
3924 +               {CKA_MODULUS, (void *)attr_data[0], 1024},          /* n */
3925 +               {CKA_PUBLIC_EXPONENT, (void *)attr_data[1], 1024},  /* e */
3926 +               };
3927 +
3928 +       if ((sp = pk11_get_session()) == NULL)
3929 +               return NULL;
3930 +
3931 +       /*
3932 +        * Use simple scheme "pkcs11:<KEY_LABEL>" for now.
3933 +        */
3934 +       if (strstr(privkey_file, "pkcs11:") == privkey_file)
3935 +               {
3936 +               search_templ[2].pValue = strstr(privkey_file, ":") + 1;
3937 +               search_templ[2].ulValueLen = strlen(search_templ[2].pValue);
3938 +
3939 +               if (pk11_pin == NULL)
3940 +#ifndef OPENCRYPTOKI
3941 +                       pk11_pin = getpassphrase("Enter PIN: ");
3942 +#else
3943 +                       pk11_pin = getpass("Enter PIN: ");
3944 +#endif
3945 +               if ((rv = pFuncList->C_Login(sp->session, CKU_USER, (CK_UTF8CHAR*)pk11_pin,
3946 +                   strlen(pk11_pin))) != CKR_OK && rv != CKR_USER_ALREADY_LOGGED_IN)
3947 +                       {
3948 +                       fprintf(stderr, "C_Login -> %lx\n", rv);
3949 +                       PK11err(PK11_F_LOAD_PRIVKEY, PK11_R_INVALID_PIN);
3950 +                       snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
3951 +                       ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
3952 +                       goto err;
3953 +                       }
3954 +
3955 +               CRYPTO_w_lock(CRYPTO_LOCK_PK11_ENGINE);
3956 +               if ((rv = pFuncList->C_FindObjectsInit(sp->session,
3957 +                   search_templ, 3)) != CKR_OK)
3958 +                       {
3959 +                       CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
3960 +                       PK11err(PK11_F_LOAD_PRIVKEY, PK11_R_FINDOBJECTSINIT);
3961 +                       snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
3962 +                       ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
3963 +                       goto err;
3964 +                       }
3965 +
3966 +               rv = pFuncList->C_FindObjects(sp->session, &ks_key, 1, &objcnt);
3967 +               if (rv != CKR_OK)
3968 +                       {
3969 +                       CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
3970 +                       PK11err(PK11_F_LOAD_PRIVKEY, PK11_R_FINDOBJECTS);
3971 +                       snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
3972 +                       ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
3973 +                       goto err;
3974 +                       }
3975 +
3976 +               if (objcnt > 1)
3977 +                       {
3978 +                       CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
3979 +                       PK11err(PK11_F_LOAD_PRIVKEY, PK11_R_TOO_MANY_OBJECTS);
3980 +                       snprintf(tmp_buf, sizeof (tmp_buf), "%lu", objcnt);
3981 +                       ERR_add_error_data(2,
3982 +                               "PK11 too many objects:", tmp_buf);
3983 +                       goto err;
3984 +                       }
3985 +
3986 +               if (objcnt != 1)
3987 +                       {
3988 +                       CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
3989 +                       PK11err(PK11_F_LOAD_PRIVKEY, PK11_R_OBJECT_NOT_FOUND);
3990 +                       ERR_add_error_data(1, "PK11 object not found");
3991 +                       goto err;
3992 +                       }
3993 +
3994 +               (void) pFuncList->C_FindObjectsFinal(sp->session);
3995 +               CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
3996 +
3997 +               if (hndidx_rsa == -1)
3998 +                       hndidx_rsa = RSA_get_ex_new_index(0,
3999 +                                       "pkcs11 RSA HSM key handle",
4000 +                                       NULL, NULL, hndidx_free);
4001 +
4002 +               key_info = malloc(sizeof(struct key_info));
4003 +               if (key_info == NULL)
4004 +                       goto err;
4005 +
4006 +               pkey = EVP_PKEY_new();
4007 +               if (pkey == NULL)
4008 +                       goto err;
4009 +
4010 +               rsa = RSA_new();
4011 +               if (rsa == NULL) {
4012 +                       EVP_PKEY_free(pkey);
4013 +                       pkey = NULL;
4014 +                       goto err;
4015 +               }
4016 +               EVP_PKEY_set1_RSA(pkey, rsa);
4017 +
4018 +               if ((rv = pFuncList->C_GetAttributeValue(sp->session, ks_key,
4019 +                   get_templ, 2)) != CKR_OK)
4020 +                       {
4021 +                       PK11err(PK11_F_LOAD_PRIVKEY, PK11_R_GETATTRIBUTVALUE);
4022 +                       snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
4023 +                       ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
4024 +                       EVP_PKEY_free(pkey);
4025 +                       pkey = NULL;
4026 +                       goto err;
4027 +                       }
4028 +
4029 +               /*
4030 +                * Now we have to initialize an OpenSSL RSA structure,
4031 +                * everything else is 0 or NULL.
4032 +                */
4033 +               rsa->meth = &pk11_rsa;
4034 +               rsa->engine = e;
4035 +               rsa->references = 2;
4036 +               rsa->flags = RSA_FLAG_SIGN_VER | RSA_FLAG_EXT_PKEY;
4037 +               key_info->handle = ks_key;
4038 +               key_info->session = sp->session;
4039 +               RSA_set_ex_data(rsa, hndidx_rsa, key_info);
4040 +               key_info = NULL;
4041 +               sp->rsa = rsa;
4042 +               sp->rsa_priv_key = ks_key;
4043 +
4044 +               attr_to_BN(&get_templ[0], attr_data[0], &rsa->n);
4045 +#ifdef OPENCRYPTOKI
4046 +               /* openCryptoki bug workaround */
4047 +               if (get_templ[1].ulValueLen == 0) {
4048 +                       get_templ[1].ulValueLen = 1;
4049 +                       attr_data[1][0] = 3;
4050 +               }
4051 +#endif
4052 +               attr_to_BN(&get_templ[1], attr_data[1], &rsa->e);
4053 +               }
4054 +       else if ((privkey=fopen(privkey_file,"r")) != NULL)
4055 +               {
4056 +               pkey = PEM_read_PrivateKey(privkey, NULL, NULL, NULL);
4057 +               fclose(privkey);
4058 +               if (pkey)
4059 +                       {
4060 +                       rsa = EVP_PKEY_get1_RSA(pkey);
4061 +
4062 +                       if (rsa)
4063 +                               {
4064 +                               check_new_rsa_key(sp, (void *) rsa);
4065 +       
4066 +                               h_priv_key = pk11_get_private_rsa_key(rsa,
4067 +                               sp);
4068 +                       if (h_priv_key == CK_INVALID_HANDLE)
4069 +                               {
4070 +                               EVP_PKEY_free(pkey);
4071 +                               pkey = NULL;
4072 +                               }
4073 +                       }
4074 +               else
4075 +                       {
4076 +                       EVP_PKEY_free(pkey);
4077 +                       pkey = NULL;
4078 +                       }
4079 +               }
4080 +       }
4081 +
4082 +err:
4083 +       if (key_info != NULL)
4084 +               free(key_info);
4085 +       pk11_return_session(sp);
4086 +       return(pkey);
4087 +       }
4088 +
4089 +EVP_PKEY *pk11_load_pubkey(ENGINE* e, const char* pubkey_file,
4090 +       UI_METHOD *ui_method, void *callback_data)
4091 +       {
4092 +       EVP_PKEY *pkey=NULL;
4093 +       FILE *pubkey;
4094 +       CK_OBJECT_HANDLE  h_pub_key = CK_INVALID_HANDLE;
4095 +       RSA *rsa;
4096 +       PK11_SESSION *sp;
4097 +       /* everything else below needed for key by reference extension */
4098 +       char tmp_buf[20];
4099 +       CK_RV rv;
4100 +       CK_ULONG objcnt = 0;
4101 +       CK_BBOOL is_token = TRUE;
4102 +       CK_BYTE attr_data[2][1024];
4103 +       CK_OBJECT_CLASS key_class = CKO_PUBLIC_KEY;
4104 +       CK_OBJECT_HANDLE ks_key = CK_INVALID_HANDLE;    /* key in keystore */
4105 +       extern char *pk11_pin;
4106 +
4107 +       /* we look for private keys only */
4108 +       CK_ATTRIBUTE search_templ[] =
4109 +               {
4110 +               {CKA_TOKEN, &is_token, sizeof(is_token)},
4111 +               {CKA_CLASS, &key_class, sizeof(key_class)},
4112 +               {CKA_LABEL, NULL, 0}
4113 +               };
4114 +
4115 +       /* these attributes are needed to initialize OpenSSL RSA structure */
4116 +       CK_ATTRIBUTE get_templ[] =
4117 +               {
4118 +               {CKA_MODULUS, (void *)attr_data[0], 1024},          /* n */
4119 +               {CKA_PUBLIC_EXPONENT, (void *)attr_data[1], 1024},  /* e */
4120 +               };
4121 +
4122 +       if ((sp = pk11_get_session()) == NULL)
4123 +               return NULL;
4124 +
4125 +       /*
4126 +        * Use simple scheme "pkcs11:<KEY_LABEL>" for now.
4127 +        */
4128 +       if (strstr(pubkey_file, "pkcs11:") == pubkey_file)
4129 +               {
4130 +               search_templ[2].pValue = strstr(pubkey_file, ":") + 1;
4131 +               search_templ[2].ulValueLen = strlen(search_templ[2].pValue);
4132 +
4133 +#define ALLWAYS_LOGIN
4134 +#ifdef ALLWAYS_LOGIN
4135 +               if (pk11_pin == NULL)
4136 +#ifndef OPENCRYPTOKI
4137 +                       pk11_pin = getpassphrase("Enter PIN: ");
4138 +#else
4139 +                       pk11_pin = getpass("Enter PIN: ");
4140 +#endif
4141 +               if ((rv = pFuncList->C_Login(sp->session, CKU_USER, (CK_UTF8CHAR*)pk11_pin,
4142 +                   strlen(pk11_pin))) != CKR_OK && rv != CKR_USER_ALREADY_LOGGED_IN)
4143 +                       {
4144 +                       fprintf(stderr, "C_Login -> %lx\n", rv);
4145 +                       PK11err(PK11_F_LOAD_PUBKEY, PK11_R_INVALID_PIN);
4146 +                       snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
4147 +                       ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
4148 +                       goto err;
4149 +                       }
4150 +#endif
4151 +
4152 +               CRYPTO_w_lock(CRYPTO_LOCK_PK11_ENGINE);
4153 +               if (pFuncList->C_FindObjectsInit(sp->session, search_templ, 3) != CKR_OK)
4154 +                       {
4155 +                       CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
4156 +                       PK11err(PK11_F_LOAD_PUBKEY, PK11_R_FINDOBJECTSINIT);
4157 +                       snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
4158 +                       ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
4159 +                       goto err;
4160 +                       }
4161 +               rv = pFuncList->C_FindObjects(sp->session, &ks_key, 1, &objcnt);
4162 +               if (rv != CKR_OK)
4163 +                       {
4164 +                       CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
4165 +                       PK11err(PK11_F_LOAD_PUBKEY, PK11_R_FINDOBJECTS);
4166 +                       snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
4167 +                       ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
4168 +                       goto err;
4169 +                       }
4170 +
4171 +               if (objcnt > 1)
4172 +                       {
4173 +                       CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
4174 +                       PK11err(PK11_F_LOAD_PUBKEY, PK11_R_TOO_MANY_OBJECTS);
4175 +                       snprintf(tmp_buf, sizeof (tmp_buf), "%lu", objcnt);
4176 +                       ERR_add_error_data(2,
4177 +                               "PK11 too many objects:", tmp_buf);
4178 +                       goto err;
4179 +                       }
4180 +
4181 +               if (objcnt != 1)
4182 +                       {
4183 +                       CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
4184 +                       PK11err(PK11_F_LOAD_PUBKEY, PK11_R_OBJECT_NOT_FOUND);
4185 +                       ERR_add_error_data(1, "PK11 object not found");
4186 +                       goto err;
4187 +                       }
4188 +
4189 +               (void) pFuncList->C_FindObjectsFinal(sp->session);
4190 +               CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
4191 +
4192 +               sp->rsa_pub_key = ks_key;
4193 +               pkey = malloc(sizeof(EVP_PKEY));
4194 +               bzero(pkey, sizeof(EVP_PKEY));
4195 +               pkey->type = EVP_PKEY_RSA;
4196 +               pkey->references = 1;
4197 +
4198 +               rsa = pkey->pkey.rsa = sp->rsa = malloc(sizeof(RSA));
4199 +               bzero(rsa, sizeof(RSA));
4200 +
4201 +               if (pFuncList->C_GetAttributeValue(sp->session, ks_key,
4202 +                   get_templ, 3) != CKR_OK)
4203 +                       {
4204 +                       PK11err(PK11_F_LOAD_PUBKEY, PK11_R_GETATTRIBUTVALUE);
4205 +                       snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
4206 +                       ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
4207 +                       goto err;
4208 +                       }
4209 +
4210 +               /*
4211 +                * Now we have to initialize an OpenSSL RSA structure,
4212 +                * everything else is 0 or NULL.
4213 +                */
4214 +               rsa->meth = &pk11_rsa;
4215 +               rsa->engine = e;
4216 +               rsa->references = 2;
4217 +               rsa->flags = RSA_FLAG_SIGN_VER;
4218 +
4219 +               attr_to_BN(&get_templ[0], attr_data[0], &rsa->n);
4220 +               attr_to_BN(&get_templ[1], attr_data[1], &rsa->e);
4221 +               }
4222 +       else if ((pubkey=fopen(pubkey_file,"r")) != NULL)
4223 +               {
4224 +               pkey = PEM_read_PUBKEY(pubkey, NULL, NULL, NULL);
4225 +               fclose(pubkey);
4226 +               if (pkey)
4227 +                       {
4228 +                       rsa = EVP_PKEY_get1_RSA(pkey);
4229 +                       if (rsa)
4230 +                               {
4231 +                               check_new_rsa_key(sp, (void *) rsa);
4232 +       
4233 +                               h_pub_key = pk11_get_public_rsa_key(rsa, sp);
4234 +                               if (h_pub_key == CK_INVALID_HANDLE)
4235 +                                       {
4236 +                                       EVP_PKEY_free(pkey);
4237 +                                       pkey = NULL;
4238 +                                       }
4239 +                               }
4240 +                       else
4241 +                               {
4242 +                               EVP_PKEY_free(pkey);
4243 +                               pkey = NULL;
4244 +                               }
4245 +                       }
4246 +               }
4247 +
4248 +err:
4249 +       pk11_return_session(sp);
4250 +       return(pkey);
4251 +       }
4252 +
4253 +/* Create a public key object in a session from a given rsa structure.
4254 + */
4255 +static CK_OBJECT_HANDLE pk11_get_public_rsa_key(RSA* rsa, PK11_SESSION *sp)
4256 +       {
4257 +       CK_RV rv;
4258 +       CK_OBJECT_HANDLE h_key = CK_INVALID_HANDLE;
4259 +       CK_ULONG found;
4260 +       CK_OBJECT_CLASS o_key = CKO_PUBLIC_KEY;
4261 +       CK_KEY_TYPE k_type = CKK_RSA;
4262 +       CK_ULONG ul_key_attr_count = 7;
4263 +       char tmp_buf[20];
4264 +
4265 +       CK_ATTRIBUTE  a_key_template[] =
4266 +               {
4267 +               {CKA_CLASS, (void *) NULL, sizeof(CK_OBJECT_CLASS)},
4268 +               {CKA_KEY_TYPE, (void *) NULL, sizeof(CK_KEY_TYPE)},
4269 +               {CKA_TOKEN, &false, sizeof(true)},
4270 +               {CKA_ENCRYPT, &true, sizeof(true)},
4271 +               {CKA_VERIFY_RECOVER, &true, sizeof(true)},
4272 +               {CKA_MODULUS, (void *)NULL, 0},
4273 +               {CKA_PUBLIC_EXPONENT, (void *)NULL, 0}
4274 +               };
4275 +
4276 +       int i;
4277 +       CK_SESSION_HANDLE session = sp->session;
4278 +
4279 +       a_key_template[0].pValue = &o_key;
4280 +       a_key_template[1].pValue = &k_type;
4281 +
4282 +       a_key_template[5].ulValueLen = BN_num_bytes(rsa->n);
4283 +       a_key_template[5].pValue = (CK_VOID_PTR)OPENSSL_malloc(
4284 +               (size_t)a_key_template[5].ulValueLen);
4285 +       if (a_key_template[5].pValue == NULL)
4286 +               {
4287 +               PK11err(PK11_F_GET_PUB_RSA_KEY, PK11_R_MALLOC_FAILURE);
4288 +               goto err;
4289 +               }
4290 +
4291 +       BN_bn2bin(rsa->n, a_key_template[5].pValue);
4292 +
4293 +       a_key_template[6].ulValueLen = BN_num_bytes(rsa->e);
4294 +       a_key_template[6].pValue = (CK_VOID_PTR)OPENSSL_malloc(
4295 +               (size_t)a_key_template[6].ulValueLen);
4296 +       if (a_key_template[6].pValue == NULL)
4297 +               {
4298 +               PK11err(PK11_F_GET_PUB_RSA_KEY, PK11_R_MALLOC_FAILURE);
4299 +               goto err;
4300 +               }
4301 +
4302 +       BN_bn2bin(rsa->e, a_key_template[6].pValue);
4303 +
4304 +       rv = pFuncList->C_FindObjectsInit(session, a_key_template, 
4305 +               ul_key_attr_count);
4306 +
4307 +       if (rv != CKR_OK)
4308 +               {
4309 +               PK11err(PK11_F_GET_PUB_RSA_KEY, PK11_R_FINDOBJECTSINIT);
4310 +               snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
4311 +               ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
4312 +               goto err;
4313 +               }
4314 +
4315 +       rv = pFuncList->C_FindObjects(session, &h_key, 1, &found);
4316 +
4317 +       if (rv != CKR_OK)
4318 +               {
4319 +               PK11err(PK11_F_GET_PUB_RSA_KEY, PK11_R_FINDOBJECTS);
4320 +               snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
4321 +               ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
4322 +               goto err;
4323 +               }
4324 +
4325 +       rv = pFuncList->C_FindObjectsFinal(session);
4326 +
4327 +       if (rv != CKR_OK)
4328 +               {
4329 +               PK11err(PK11_F_GET_PUB_RSA_KEY, PK11_R_FINDOBJECTSFINAL);
4330 +               snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
4331 +               ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
4332 +               goto err;
4333 +               }
4334 +
4335 +       if (found == 0)
4336 +               {
4337 +               rv = pFuncList->C_CreateObject(session, 
4338 +                       a_key_template, ul_key_attr_count, &h_key);
4339 +               if (rv != CKR_OK)
4340 +                       {
4341 +                       PK11err(PK11_F_GET_PUB_RSA_KEY, 
4342 +                               PK11_R_CREATEOBJECT);
4343 +                       snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
4344 +                       ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
4345 +                       goto err;
4346 +                       }
4347 +               }
4348 +
4349 +       sp->rsa = rsa;
4350 +
4351 + err:
4352 +       for (i = 5; i <= 6; i++)
4353 +               {
4354 +               if (a_key_template[i].pValue != NULL)
4355 +                       {
4356 +                       OPENSSL_free(a_key_template[i].pValue);
4357 +                       a_key_template[i].pValue = NULL;
4358 +                       }
4359 +               }
4360 +
4361 +       return h_key;
4362 +
4363 +       }
4364 +
4365 +/* Create a private key object in the session from a given rsa structure
4366 + */
4367 +static CK_OBJECT_HANDLE pk11_get_private_rsa_key(RSA* rsa, PK11_SESSION *sp)
4368 +       {
4369 +       CK_RV rv;
4370 +       CK_OBJECT_HANDLE h_key = CK_INVALID_HANDLE;
4371 +       int i;
4372 +       CK_ULONG found;
4373 +       CK_OBJECT_CLASS o_key = CKO_PRIVATE_KEY;
4374 +       CK_KEY_TYPE k_type = CKK_RSA;
4375 +       CK_ULONG ul_key_attr_count = 14;
4376 +       char tmp_buf[20];
4377 +
4378 +       /* Both CKA_TOKEN and CKA_SENSITIVE have to be FALSE for session keys
4379 +        */
4380 +       CK_ATTRIBUTE  a_key_template[] =
4381 +               {
4382 +               {CKA_CLASS, (void *) NULL, sizeof(CK_OBJECT_CLASS)},
4383 +               {CKA_KEY_TYPE, (void *) NULL, sizeof(CK_KEY_TYPE)},
4384 +               {CKA_TOKEN, &false, sizeof(true)},
4385 +               {CKA_SENSITIVE, &false, sizeof(true)},
4386 +               {CKA_DECRYPT, &true, sizeof(true)},
4387 +               {CKA_SIGN, &true, sizeof(true)},
4388 +               {CKA_MODULUS, (void *)NULL, 0},
4389 +               {CKA_PUBLIC_EXPONENT, (void *)NULL, 0},
4390 +               {CKA_PRIVATE_EXPONENT, (void *)NULL, 0},
4391 +               {CKA_PRIME_1, (void *)NULL, 0},
4392 +               {CKA_PRIME_2, (void *)NULL, 0},
4393 +               {CKA_EXPONENT_1, (void *)NULL, 0},
4394 +               {CKA_EXPONENT_2, (void *)NULL, 0},
4395 +               {CKA_COEFFICIENT, (void *)NULL, 0}
4396 +               };
4397 +       CK_SESSION_HANDLE session = sp->session;
4398 +
4399 +       if ((rsa->flags & RSA_FLAG_EXT_PKEY) != 0) {
4400 +               sp->rsa = rsa;
4401 +               return (*(CK_OBJECT_HANDLE_PTR)RSA_get_ex_data(rsa, hndidx_rsa));
4402 +       }
4403 +       
4404 +       a_key_template[0].pValue = &o_key;
4405 +       a_key_template[1].pValue = &k_type;
4406 +
4407 +       /* Put the private key components into the template */
4408 +       if (init_template_value(rsa->n, &a_key_template[6].pValue,
4409 +               &a_key_template[6].ulValueLen) == 0 ||
4410 +           init_template_value(rsa->e, &a_key_template[7].pValue,
4411 +               &a_key_template[7].ulValueLen) == 0 ||
4412 +           init_template_value(rsa->d, &a_key_template[8].pValue,
4413 +               &a_key_template[8].ulValueLen) == 0 ||
4414 +           init_template_value(rsa->p, &a_key_template[9].pValue,
4415 +               &a_key_template[9].ulValueLen) == 0 ||
4416 +           init_template_value(rsa->q, &a_key_template[10].pValue,
4417 +               &a_key_template[10].ulValueLen) == 0 ||
4418 +           init_template_value(rsa->dmp1, &a_key_template[11].pValue,
4419 +               &a_key_template[11].ulValueLen) == 0 ||
4420 +           init_template_value(rsa->dmq1, &a_key_template[12].pValue,
4421 +               &a_key_template[12].ulValueLen) == 0 ||
4422 +           init_template_value(rsa->iqmp, &a_key_template[13].pValue,
4423 +               &a_key_template[13].ulValueLen) == 0)
4424 +               {
4425 +               PK11err(PK11_F_GET_PRIV_RSA_KEY, PK11_R_MALLOC_FAILURE);
4426 +               goto err;
4427 +               }
4428 +
4429 +       rv = pFuncList->C_FindObjectsInit(session, a_key_template, 
4430 +               ul_key_attr_count);
4431 +
4432 +       if (rv != CKR_OK)
4433 +               {
4434 +               PK11err(PK11_F_GET_PRIV_RSA_KEY, PK11_R_FINDOBJECTSINIT);
4435 +               snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
4436 +               ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
4437 +               goto err;
4438 +               }
4439 +
4440 +       rv = pFuncList->C_FindObjects(session, &h_key, 1, &found);
4441 +
4442 +       if (rv != CKR_OK)
4443 +               {
4444 +               PK11err(PK11_F_GET_PRIV_RSA_KEY, PK11_R_FINDOBJECTS);
4445 +               snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
4446 +               ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
4447 +               goto err;
4448 +               }
4449 +
4450 +       rv = pFuncList->C_FindObjectsFinal(session);
4451 +
4452 +       if (rv != CKR_OK)
4453 +               {
4454 +               PK11err(PK11_F_GET_PRIV_RSA_KEY, PK11_R_FINDOBJECTSFINAL);
4455 +               snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
4456 +               ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
4457 +               goto err;
4458 +               }
4459 +
4460 +       if (found == 0)
4461 +               {
4462 +               rv = pFuncList->C_CreateObject(session, 
4463 +                       a_key_template, ul_key_attr_count, &h_key);
4464 +               if (rv != CKR_OK)
4465 +                       {
4466 +                       PK11err(PK11_F_GET_PRIV_RSA_KEY, 
4467 +                               PK11_R_CREATEOBJECT);
4468 +                       snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
4469 +                       ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
4470 +                       goto err;
4471 +                       }
4472 +               }
4473 +
4474 +       sp->rsa = rsa;
4475 +
4476 + err:
4477 +       /* 6 to 13 entries in the key template are key components
4478 +        * They need to be freed apon exit or error.
4479 +        */
4480 +       for (i = 6; i <= 13; i++)
4481 +               {
4482 +               if (a_key_template[i].pValue != NULL)
4483 +                       {
4484 +                       memset(a_key_template[i].pValue, 0, 
4485 +                               a_key_template[i].ulValueLen);
4486 +                       OPENSSL_free(a_key_template[i].pValue);
4487 +                       a_key_template[i].pValue = NULL;
4488 +                       }
4489 +               }
4490 +
4491 +       return h_key;
4492 +       }
4493 +
4494 +#endif
4495 +
4496 +
4497 +#ifndef OPENSSL_NO_DSA
4498 +/* The DSA function implementation
4499 + */
4500 +static int pk11_DSA_init(DSA *dsa)
4501 +       {
4502 +       return 1;
4503 +       }
4504 +
4505 +
4506 +static int pk11_DSA_finish(DSA *dsa)
4507 +       {
4508 +       return pk11_destroy_dsa_key_objects(NULL);
4509 +       }
4510 +
4511 +
4512 +static DSA_SIG *
4513 +pk11_dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa)
4514 +       {
4515 +       BIGNUM *r = NULL, *s = NULL;
4516 +       int i;
4517 +       DSA_SIG *dsa_sig = NULL;
4518 +
4519 +       CK_RV rv;
4520 +       CK_MECHANISM Mechanism_dsa = {CKM_DSA, NULL, 0};
4521 +       CK_MECHANISM *p_mech = &Mechanism_dsa;
4522 +       CK_OBJECT_HANDLE h_priv_key;
4523 +
4524 +       /* The signature is the concatenation of r and s, 
4525 +        * each is 20 bytes long
4526 +        */
4527 +       unsigned char sigret[DSA_SIGNATURE_LEN];
4528 +       unsigned long siglen = DSA_SIGNATURE_LEN;
4529 +       unsigned int siglen2 = DSA_SIGNATURE_LEN / 2;
4530 +
4531 +       PK11_SESSION *sp = NULL;
4532 +       char tmp_buf[20];
4533 +
4534 +       if ((dsa->p == NULL) || (dsa->q == NULL) || (dsa->g == NULL)) 
4535 +               {
4536 +               PK11err(PK11_F_DSA_SIGN, PK11_R_MISSING_KEY_COMPONENT);
4537 +               goto ret;
4538 +               }
4539 +
4540 +       i=BN_num_bytes(dsa->q); /* should be 20 */
4541 +       if (dlen > i)
4542 +               {
4543 +               PK11err(PK11_F_DSA_SIGN, PK11_R_INVALID_SIGNATURE_LENGTH);
4544 +               goto ret;
4545 +               }
4546 +
4547 +       if ((sp = pk11_get_session()) == NULL)
4548 +               goto ret;
4549 +
4550 +       check_new_dsa_key(sp, (void *) dsa);
4551 +
4552 +       h_priv_key = sp->dsa_priv_key;
4553 +       if (h_priv_key == CK_INVALID_HANDLE)
4554 +               h_priv_key = sp->dsa_priv_key =
4555 +                       pk11_get_private_dsa_key((DSA *)dsa, sp);
4556 +
4557 +       if (h_priv_key != CK_INVALID_HANDLE)
4558 +               {
4559 +               rv = pFuncList->C_SignInit(sp->session, p_mech, h_priv_key);
4560 +
4561 +               if (rv != CKR_OK)
4562 +                       {
4563 +                       PK11err(PK11_F_DSA_SIGN, PK11_R_SIGNINIT);
4564 +                       snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
4565 +                       ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
4566 +                       goto ret;
4567 +                       }
4568 +
4569 +               memset(sigret, 0, siglen);
4570 +               rv = pFuncList->C_Sign(sp->session, 
4571 +                       (unsigned char*) dgst, dlen, sigret, 
4572 +                       (CK_ULONG_PTR) &siglen);
4573 +
4574 +               if (rv != CKR_OK)
4575 +                       {
4576 +                       PK11err(PK11_F_DSA_SIGN, PK11_R_SIGN);
4577 +                       snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
4578 +                       ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
4579 +                       goto ret;
4580 +                       }
4581 +               }
4582 +
4583 +
4584 +       if ((s = BN_new()) == NULL)
4585 +               {
4586 +               PK11err(PK11_F_DSA_SIGN, PK11_R_MALLOC_FAILURE);
4587 +               goto ret;
4588 +               }
4589 +
4590 +       if ((r = BN_new()) == NULL)
4591 +               {
4592 +               PK11err(PK11_F_DSA_SIGN, PK11_R_MALLOC_FAILURE);
4593 +               goto ret;
4594 +               }
4595 +
4596 +       if ((dsa_sig = DSA_SIG_new()) == NULL)
4597 +               {
4598 +               PK11err(PK11_F_DSA_SIGN, PK11_R_MALLOC_FAILURE);
4599 +               goto ret;
4600 +               }
4601 +
4602 +       BN_bin2bn(sigret, siglen2, r);
4603 +       BN_bin2bn(&sigret[siglen2], siglen2, s);
4604 +
4605 +       dsa_sig->r = r;
4606 +       dsa_sig->s = s;
4607 +
4608 +ret:
4609 +       if (dsa_sig == NULL) 
4610 +               {
4611 +               if (r != NULL)
4612 +                       BN_free(r);
4613 +               if (s != NULL)
4614 +                       BN_free(s);
4615 +               }
4616 +
4617 +       pk11_return_session(sp);
4618 +       return (dsa_sig);
4619 +       }
4620 +
4621 +static int
4622 +pk11_dsa_do_verify(const unsigned char *dgst, int dlen, DSA_SIG *sig,
4623 +       DSA *dsa)
4624 +       {
4625 +       int i;
4626 +       CK_RV rv;
4627 +       int retval = 0;
4628 +       CK_MECHANISM Mechanism_dsa = {CKM_DSA, NULL, 0};
4629 +       CK_MECHANISM *p_mech = &Mechanism_dsa;
4630 +       CK_OBJECT_HANDLE h_pub_key;
4631 +
4632 +       unsigned char sigbuf[DSA_SIGNATURE_LEN];
4633 +       unsigned long siglen = DSA_SIGNATURE_LEN;
4634 +       unsigned long siglen2 = DSA_SIGNATURE_LEN/2;
4635 +
4636 +       PK11_SESSION *sp = NULL;
4637 +       char tmp_buf[20];
4638 +
4639 +       if (BN_is_zero(sig->r) || sig->r->neg || BN_ucmp(sig->r, dsa->q) >= 0)
4640 +               {
4641 +               PK11err(PK11_F_DSA_VERIFY, 
4642 +                       PK11_R_INVALID_DSA_SIGNATURE_R);
4643 +               goto ret;
4644 +               }
4645 +
4646 +       if (BN_is_zero(sig->s) || sig->s->neg || BN_ucmp(sig->s, dsa->q) >= 0) 
4647 +               {
4648 +               PK11err(PK11_F_DSA_VERIFY, 
4649 +                       PK11_R_INVALID_DSA_SIGNATURE_S);
4650 +               goto ret;
4651 +               }
4652 +
4653 +       i = BN_num_bytes(dsa->q); /* should be 20 */
4654 +
4655 +       if (dlen > i)
4656 +               {
4657 +               PK11err(PK11_F_DSA_VERIFY, 
4658 +                       PK11_R_INVALID_SIGNATURE_LENGTH);
4659 +               goto ret;
4660 +               }
4661 +
4662 +       if ((sp = pk11_get_session()) == NULL)
4663 +               goto ret;
4664 +       
4665 +       check_new_dsa_key(sp, (void *) dsa);
4666 +
4667 +       h_pub_key = sp->dsa_pub_key;
4668 +       if (h_pub_key == CK_INVALID_HANDLE)
4669 +               h_pub_key = sp->dsa_pub_key = 
4670 +                       pk11_get_public_dsa_key((DSA *)dsa, sp);
4671 +
4672 +       if (h_pub_key != CK_INVALID_HANDLE)
4673 +               {
4674 +               rv = pFuncList->C_VerifyInit(sp->session, p_mech, 
4675 +                       h_pub_key);
4676 +
4677 +               if (rv != CKR_OK)
4678 +                       {
4679 +                       PK11err(PK11_F_DSA_VERIFY, PK11_R_VERIFYINIT);
4680 +                       snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
4681 +                       ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
4682 +                       goto ret;
4683 +                       }
4684 +
4685 +               memset(sigbuf, 0, siglen);
4686 +               BN_bn2bin(sig->r, sigbuf);
4687 +               BN_bn2bin(sig->s, &sigbuf[siglen2]);
4688 +               
4689 +               rv = pFuncList->C_Verify(sp->session, 
4690 +                       (unsigned char *) dgst, dlen, sigbuf, (CK_ULONG)siglen);
4691 +
4692 +               if (rv != CKR_OK)
4693 +                       {
4694 +                       PK11err(PK11_F_DSA_VERIFY, PK11_R_VERIFY);
4695 +                       snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
4696 +                       ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
4697 +                       goto ret;
4698 +                       }
4699 +               }
4700 +
4701 +       retval = 1;
4702 +ret:
4703 +
4704 +       pk11_return_session(sp);
4705 +       return retval;
4706 +       }
4707 +
4708 +
4709 +/* Create a public key object in a session from a given dsa structure.
4710 + */
4711 +static CK_OBJECT_HANDLE pk11_get_public_dsa_key(DSA* dsa, PK11_SESSION *sp)
4712 +       {
4713 +       CK_RV rv;
4714 +       CK_OBJECT_CLASS o_key = CKO_PUBLIC_KEY;
4715 +       CK_OBJECT_HANDLE h_key = CK_INVALID_HANDLE;
4716 +       CK_ULONG found;
4717 +       CK_KEY_TYPE k_type = CKK_DSA;
4718 +       CK_ULONG ul_key_attr_count = 8;
4719 +       int i;
4720 +       char tmp_buf[20];
4721 +
4722 +       CK_ATTRIBUTE  a_key_template[] =
4723 +               {
4724 +               {CKA_CLASS, (void *) NULL, sizeof(CK_OBJECT_CLASS)},
4725 +               {CKA_KEY_TYPE, (void *) NULL, sizeof(CK_KEY_TYPE)},
4726 +               {CKA_TOKEN, &false, sizeof(true)},
4727 +               {CKA_VERIFY, &true, sizeof(true)},
4728 +               {CKA_PRIME, (void *)NULL, 0},           /* p */
4729 +               {CKA_SUBPRIME, (void *)NULL, 0},        /* q */
4730 +               {CKA_BASE, (void *)NULL, 0},            /* g */
4731 +               {CKA_VALUE, (void *)NULL, 0}            /* pub_key - y */
4732 +               };
4733 +       CK_SESSION_HANDLE session = sp->session;
4734 +
4735 +       a_key_template[0].pValue = &o_key;
4736 +       a_key_template[1].pValue = &k_type;
4737 +
4738 +       if (init_template_value(dsa->p, &a_key_template[4].pValue,
4739 +               &a_key_template[4].ulValueLen) == 0 ||
4740 +           init_template_value(dsa->q, &a_key_template[5].pValue,
4741 +               &a_key_template[5].ulValueLen) == 0 ||
4742 +           init_template_value(dsa->g, &a_key_template[6].pValue,
4743 +               &a_key_template[6].ulValueLen) == 0 ||
4744 +           init_template_value(dsa->pub_key, &a_key_template[7].pValue,
4745 +               &a_key_template[7].ulValueLen) == 0)
4746 +               {
4747 +               PK11err(PK11_F_GET_PUB_DSA_KEY, PK11_R_MALLOC_FAILURE);
4748 +               goto err;
4749 +               }
4750 +
4751 +       rv = pFuncList->C_FindObjectsInit(session, a_key_template, 
4752 +               ul_key_attr_count);
4753 +
4754 +       if (rv != CKR_OK)
4755 +               {
4756 +               PK11err(PK11_F_GET_PUB_DSA_KEY, PK11_R_FINDOBJECTSINIT);
4757 +               snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
4758 +               ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
4759 +               goto err;
4760 +               }
4761 +
4762 +       rv = pFuncList->C_FindObjects(session, &h_key, 1, &found);
4763 +
4764 +       if (rv != CKR_OK)
4765 +               {
4766 +               PK11err(PK11_F_GET_PUB_DSA_KEY, PK11_R_FINDOBJECTS);
4767 +               snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
4768 +               ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
4769 +               goto err;
4770 +               }
4771 +
4772 +       rv = pFuncList->C_FindObjectsFinal(session);
4773 +
4774 +       if (rv != CKR_OK)
4775 +               {
4776 +               PK11err(PK11_F_GET_PUB_DSA_KEY, PK11_R_FINDOBJECTSFINAL);
4777 +               snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
4778 +               ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
4779 +               goto err;
4780 +               }
4781 +
4782 +       if (found == 0)
4783 +               {
4784 +               rv = pFuncList->C_CreateObject(session, 
4785 +                       a_key_template, ul_key_attr_count, &h_key);
4786 +               if (rv != CKR_OK)
4787 +                       {
4788 +                       PK11err(PK11_F_GET_PUB_DSA_KEY, 
4789 +                               PK11_R_CREATEOBJECT);
4790 +                       snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
4791 +                       ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
4792 +                       goto err;
4793 +                       }
4794 +               }
4795 +
4796 +       sp->dsa = dsa;
4797 +
4798 + err:
4799 +       for (i = 4; i <= 7; i++)
4800 +               {
4801 +               if (a_key_template[i].pValue != NULL)
4802 +                       {
4803 +                       OPENSSL_free(a_key_template[i].pValue);
4804 +                       a_key_template[i].pValue = NULL;
4805 +                       }
4806 +               }
4807 +
4808 +       return h_key;
4809 +
4810 +       }
4811 +
4812 +/* Create a private key object in the session from a given dsa structure
4813 + */
4814 +static CK_OBJECT_HANDLE pk11_get_private_dsa_key(DSA* dsa, PK11_SESSION *sp)
4815 +       {
4816 +       CK_RV rv;
4817 +       CK_OBJECT_HANDLE h_key = CK_INVALID_HANDLE;
4818 +       CK_OBJECT_CLASS o_key = CKO_PRIVATE_KEY;
4819 +       int i;
4820 +       char tmp_buf[20];
4821 +       CK_ULONG found;
4822 +       CK_KEY_TYPE k_type = CKK_DSA;
4823 +       CK_ULONG ul_key_attr_count = 9;
4824 +
4825 +       /* Both CKA_TOKEN and CKA_SENSITIVE have to be FALSE for session keys
4826 +        */
4827 +       CK_ATTRIBUTE  a_key_template[] =
4828 +               {
4829 +               {CKA_CLASS, (void *) NULL, sizeof(CK_OBJECT_CLASS)},
4830 +               {CKA_KEY_TYPE, (void *) NULL, sizeof(CK_KEY_TYPE)},
4831 +               {CKA_TOKEN, &false, sizeof(true)},
4832 +               {CKA_SENSITIVE, &false, sizeof(true)},
4833 +               {CKA_SIGN, &true, sizeof(true)},
4834 +               {CKA_PRIME, (void *)NULL, 0},           /* p */
4835 +               {CKA_SUBPRIME, (void *)NULL, 0},        /* q */
4836 +               {CKA_BASE, (void *)NULL, 0},            /* g */
4837 +               {CKA_VALUE, (void *)NULL, 0}            /* priv_key - x */
4838 +               };
4839 +       CK_SESSION_HANDLE session = sp->session;
4840 +
4841 +       a_key_template[0].pValue = &o_key;
4842 +       a_key_template[1].pValue = &k_type;
4843 +
4844 +       /* Put the private key components into the template
4845 +        */
4846 +       if (init_template_value(dsa->p, &a_key_template[5].pValue,
4847 +               &a_key_template[5].ulValueLen) == 0 ||
4848 +           init_template_value(dsa->q, &a_key_template[6].pValue,
4849 +               &a_key_template[6].ulValueLen) == 0 ||
4850 +           init_template_value(dsa->g, &a_key_template[7].pValue,
4851 +               &a_key_template[7].ulValueLen) == 0 ||
4852 +           init_template_value(dsa->priv_key, &a_key_template[8].pValue,
4853 +               &a_key_template[8].ulValueLen) == 0)
4854 +               {
4855 +               PK11err(PK11_F_GET_PRIV_DSA_KEY, PK11_R_MALLOC_FAILURE);
4856 +               goto err;
4857 +               }
4858 +
4859 +       rv = pFuncList->C_FindObjectsInit(session, a_key_template, 
4860 +               ul_key_attr_count);
4861 +
4862 +       if (rv != CKR_OK)
4863 +               {
4864 +               PK11err(PK11_F_GET_PRIV_DSA_KEY, PK11_R_FINDOBJECTSINIT);
4865 +               snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
4866 +               ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
4867 +               goto err;
4868 +               }
4869 +
4870 +       rv = pFuncList->C_FindObjects(session, &h_key, 1, &found);
4871 +
4872 +       if (rv != CKR_OK)
4873 +               {
4874 +               PK11err(PK11_F_GET_PRIV_DSA_KEY, PK11_R_FINDOBJECTS);
4875 +               snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
4876 +               ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
4877 +               goto err;
4878 +               }
4879 +
4880 +       rv = pFuncList->C_FindObjectsFinal(session);
4881 +
4882 +       if (rv != CKR_OK)
4883 +               {
4884 +               PK11err(PK11_F_GET_PRIV_DSA_KEY, PK11_R_FINDOBJECTSFINAL);
4885 +               snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
4886 +               ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
4887 +               goto err;
4888 +               }
4889 +
4890 +       if (found == 0)
4891 +               {
4892 +               rv = pFuncList->C_CreateObject(session, 
4893 +                       a_key_template, ul_key_attr_count, &h_key);
4894 +               if (rv != CKR_OK)
4895 +                       {
4896 +                       PK11err(PK11_F_GET_PRIV_DSA_KEY, 
4897 +                               PK11_R_CREATEOBJECT);
4898 +                       snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
4899 +                       ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
4900 +                       goto err;
4901 +                       }
4902 +               }
4903 +
4904 +       sp->dsa = dsa;
4905 +
4906 +err:
4907 +       /* 5 to 8 entries in the key template are key components
4908 +        * They need to be freed apon exit or error.
4909 +        */
4910 +       for (i = 5; i <= 8; i++)
4911 +               {
4912 +               if (a_key_template[i].pValue != NULL)
4913 +                       {
4914 +                       memset(a_key_template[i].pValue, 0,
4915 +                               a_key_template[i].ulValueLen);
4916 +                       OPENSSL_free(a_key_template[i].pValue);
4917 +                       a_key_template[i].pValue = NULL;
4918 +                       }
4919 +               }
4920 +
4921 +       return h_key;
4922 +
4923 +       }
4924 +#endif
4925 +
4926 +
4927 +#ifndef OPENSSL_NO_DH
4928 +
4929 +/* The DH function implementation
4930 + */
4931 +static int pk11_DH_init(DH *dh)
4932 +       {
4933 +       return 1;
4934 +       }
4935 +
4936 +
4937 +static int pk11_DH_finish(DH *dh)
4938 +       {
4939 +       return pk11_destroy_dh_key_objects(NULL);
4940 +       }
4941 +
4942 +static int pk11_DH_generate_key(DH *dh)
4943 +       {
4944 +       CK_ULONG i;
4945 +       CK_RV rv, rv1;
4946 +       int ret = 0;
4947 +       PK11_SESSION *sp = NULL;
4948 +       char tmp_buf[20];
4949 +       CK_BYTE_PTR reuse_mem;
4950 +
4951 +       CK_MECHANISM mechanism = {CKM_DH_PKCS_KEY_PAIR_GEN, NULL_PTR, 0};
4952 +       CK_OBJECT_HANDLE h_pub_key = CK_INVALID_HANDLE;
4953 +       CK_OBJECT_HANDLE h_priv_key = CK_INVALID_HANDLE;
4954 +
4955 +       CK_ULONG ul_pub_key_attr_count = 3; 
4956 +       CK_ATTRIBUTE pub_key_template[] =
4957 +               {
4958 +               {CKA_PRIVATE, &false, sizeof(false)},
4959 +               {CKA_PRIME, (void *)NULL, 0},
4960 +               {CKA_BASE, (void *)NULL, 0}
4961 +               };
4962 +
4963 +       CK_ULONG ul_priv_key_attr_count = 3; 
4964 +       CK_ATTRIBUTE priv_key_template[] =
4965 +               {
4966 +               {CKA_PRIVATE, &false, sizeof(false)},
4967 +               {CKA_SENSITIVE, &false, sizeof(false)},
4968 +               {CKA_DERIVE, &true, sizeof(true)}
4969 +               };
4970 +
4971 +       CK_ULONG pub_key_attr_result_count = 1;
4972 +       CK_ATTRIBUTE pub_key_result[] =
4973 +               {
4974 +               {CKA_VALUE, (void *)NULL, 0}
4975 +               };
4976 +
4977 +       CK_ULONG priv_key_attr_result_count = 1;
4978 +       CK_ATTRIBUTE priv_key_result[] =
4979 +               {
4980 +               {CKA_VALUE, (void *)NULL, 0}
4981 +               };
4982 +
4983 +       pub_key_template[1].ulValueLen = BN_num_bytes(dh->p);
4984 +       if (pub_key_template[1].ulValueLen > 0)
4985 +               {
4986 +               pub_key_template[1].pValue = 
4987 +                       OPENSSL_malloc(pub_key_template[1].ulValueLen);
4988 +               if (pub_key_template[1].pValue == NULL)
4989 +                       {
4990 +                       PK11err(PK11_F_DH_GEN_KEY, PK11_R_MALLOC_FAILURE);
4991 +                       goto err;
4992 +                       }
4993 +
4994 +               i = BN_bn2bin(dh->p, pub_key_template[1].pValue);
4995 +               }
4996 +       else
4997 +               goto err;
4998 +
4999 +       pub_key_template[2].ulValueLen = BN_num_bytes(dh->g);
5000 +       if (pub_key_template[2].ulValueLen > 0)
5001 +               {
5002 +               pub_key_template[2].pValue = 
5003 +                       OPENSSL_malloc(pub_key_template[2].ulValueLen);
5004 +               if (pub_key_template[2].pValue == NULL)
5005 +                       {
5006 +                       PK11err(PK11_F_DH_GEN_KEY, PK11_R_MALLOC_FAILURE);
5007 +                       goto err;
5008 +                       }
5009 +
5010 +               i = BN_bn2bin(dh->g, pub_key_template[2].pValue);
5011 +               }
5012 +       else
5013 +               goto err;
5014 +
5015 +       if ((sp = pk11_get_session()) == NULL)
5016 +               goto err;
5017 +       
5018 +       rv = pFuncList->C_GenerateKeyPair(sp->session,
5019 +                          &mechanism,
5020 +                          pub_key_template,
5021 +                          ul_pub_key_attr_count,
5022 +                          priv_key_template,
5023 +                          ul_priv_key_attr_count,
5024 +                          &h_pub_key,
5025 +                          &h_priv_key);
5026 +       if (rv != CKR_OK)
5027 +               {
5028 +               PK11err(PK11_F_DH_GEN_KEY, PK11_R_GEN_KEY);
5029 +               snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
5030 +               ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
5031 +               goto err;
5032 +               }
5033 +
5034 +       /* Reuse the larger memory allocated. We know the larger memory
5035 +        * is sufficient for reuse */
5036 +       if (pub_key_template[1].ulValueLen > pub_key_template[2].ulValueLen)
5037 +               reuse_mem = pub_key_template[1].pValue;
5038 +       else
5039 +               reuse_mem = pub_key_template[2].pValue;
5040 +
5041 +       rv = pFuncList->C_GetAttributeValue(sp->session, h_pub_key, 
5042 +               pub_key_result, pub_key_attr_result_count);
5043 +       rv1 = pFuncList->C_GetAttributeValue(sp->session, h_priv_key, 
5044 +               priv_key_result, priv_key_attr_result_count);
5045 +
5046 +       if (rv != CKR_OK || rv1 != CKR_OK)
5047 +               {
5048 +               rv = (rv != CKR_OK) ? rv : rv1;
5049 +               PK11err(PK11_F_DH_GEN_KEY, PK11_R_GETATTRIBUTVALUE);
5050 +               snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
5051 +               ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
5052 +               goto err;
5053 +               }
5054 +
5055 +       if (((CK_LONG) pub_key_result[0].ulValueLen) <= 0 ||
5056 +               ((CK_LONG) priv_key_result[0].ulValueLen) <= 0)
5057 +               {
5058 +               PK11err(PK11_F_DH_GEN_KEY, PK11_R_GETATTRIBUTVALUE);
5059 +               goto err;
5060 +               }
5061 +       
5062 +       /* Reuse the memory allocated */
5063 +       pub_key_result[0].pValue = reuse_mem;
5064 +
5065 +       rv = pFuncList->C_GetAttributeValue(sp->session, h_pub_key, 
5066 +               pub_key_result, pub_key_attr_result_count);
5067 +
5068 +       if (rv != CKR_OK)
5069 +               {
5070 +               PK11err(PK11_F_DH_GEN_KEY, PK11_R_GETATTRIBUTVALUE);
5071 +               snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
5072 +               ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
5073 +               goto err;
5074 +               }
5075 +
5076 +       if (pub_key_result[0].type == CKA_VALUE)
5077 +               {
5078 +               if (dh->pub_key == NULL)
5079 +                       dh->pub_key = BN_new();
5080 +               dh->pub_key = BN_bin2bn(pub_key_result[0].pValue, 
5081 +                       pub_key_result[0].ulValueLen, dh->pub_key);
5082 +               }
5083 +
5084 +       /* Reuse the memory allocated */
5085 +       priv_key_result[0].pValue = reuse_mem;
5086 +
5087 +       rv = pFuncList->C_GetAttributeValue(sp->session, h_priv_key, 
5088 +               priv_key_result, priv_key_attr_result_count);
5089 +
5090 +       if (rv != CKR_OK)
5091 +               {
5092 +               PK11err(PK11_F_DH_GEN_KEY, PK11_R_GETATTRIBUTVALUE);
5093 +               snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
5094 +               ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
5095 +               goto err;
5096 +               }
5097 +
5098 +       if (priv_key_result[0].type == CKA_VALUE)
5099 +               {
5100 +               if (dh->priv_key == NULL)
5101 +                       dh->priv_key = BN_new();
5102 +               dh->priv_key = BN_bin2bn(priv_key_result[0].pValue, 
5103 +                       priv_key_result[0].ulValueLen, dh->priv_key);
5104 +               }
5105 +
5106 +       ret = 1;
5107 +
5108 +err:
5109 +        
5110 +       if (h_pub_key != CK_INVALID_HANDLE)
5111 +               {
5112 +               rv = pFuncList->C_DestroyObject(sp->session, h_pub_key);
5113 +               if (rv != CKR_OK)
5114 +                       {
5115 +                       PK11err(PK11_F_DH_GEN_KEY, PK11_R_DESTROYOBJECT);
5116 +                       snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
5117 +                       ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
5118 +                       }
5119 +               }
5120 +
5121 +       if (h_priv_key != CK_INVALID_HANDLE)
5122 +               {
5123 +               rv = pFuncList->C_DestroyObject(sp->session, h_priv_key);
5124 +               if (rv != CKR_OK)
5125 +                       {
5126 +                       PK11err(PK11_F_DH_GEN_KEY, PK11_R_DESTROYOBJECT);
5127 +                       snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
5128 +                       ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
5129 +                       }
5130 +               }
5131 +
5132 +       for (i = 1; i <= 2; i++)
5133 +               {
5134 +               if (pub_key_template[i].pValue != NULL)
5135 +                       {
5136 +                       OPENSSL_free(pub_key_template[i].pValue);
5137 +                       pub_key_template[i].pValue = NULL;
5138 +                       }
5139 +               }
5140 +
5141 +       pk11_return_session(sp);
5142 +       return ret;
5143 +       }
5144 +
5145 +static int pk11_DH_compute_key(unsigned char *key,const BIGNUM *pub_key,DH *dh)
5146 +       {
5147 +       int i;
5148 +       CK_MECHANISM mechanism = {CKM_DH_PKCS_DERIVE, NULL_PTR, 0};
5149 +       CK_OBJECT_CLASS key_class = CKO_SECRET_KEY;
5150 +       CK_KEY_TYPE key_type = CKK_GENERIC_SECRET;
5151 +       CK_OBJECT_HANDLE h_derived_key = CK_INVALID_HANDLE;
5152 +       CK_OBJECT_HANDLE h_key = CK_INVALID_HANDLE;
5153 +
5154 +       CK_ULONG ul_priv_key_attr_count = 2;
5155 +       CK_ATTRIBUTE priv_key_template[] =
5156 +               {
5157 +               {CKA_CLASS, (void*) NULL, sizeof(key_class)},
5158 +               {CKA_KEY_TYPE, (void*) NULL,  sizeof(key_type)},
5159 +               };
5160 +
5161 +       CK_ULONG priv_key_attr_result_count = 1;
5162 +       CK_ATTRIBUTE priv_key_result[] =
5163 +               {
5164 +               {CKA_VALUE, (void *)NULL, 0}
5165 +               };
5166 +
5167 +       CK_RV rv;
5168 +       int ret = 0;
5169 +       PK11_SESSION *sp = NULL;
5170 +       char tmp_buf[20];
5171 +
5172 +       priv_key_template[0].pValue = &key_class;
5173 +       priv_key_template[1].pValue = &key_type;
5174 +
5175 +       if ((sp = pk11_get_session()) == NULL)
5176 +               goto err;
5177 +
5178 +       mechanism.ulParameterLen = BN_num_bytes(pub_key);
5179 +       mechanism.pParameter = OPENSSL_malloc(mechanism.ulParameterLen);
5180 +       if (mechanism.pParameter == NULL)
5181 +               {
5182 +               PK11err(PK11_F_DH_COMP_KEY, PK11_R_MALLOC_FAILURE);
5183 +               goto err;
5184 +               }
5185 +       BN_bn2bin(pub_key, mechanism.pParameter);
5186 +
5187 +       check_new_dh_key(sp, dh);
5188 +
5189 +       h_key = sp->dh_key;
5190 +       if (h_key == CK_INVALID_HANDLE)
5191 +               h_key = sp->dh_key = pk11_get_dh_key((DH*) dh, sp);
5192 +
5193 +       if (h_key == CK_INVALID_HANDLE)
5194 +               {
5195 +               PK11err(PK11_F_DH_COMP_KEY, PK11_R_CREATEOBJECT);
5196 +               goto err;
5197 +               }
5198 +
5199 +       rv = pFuncList->C_DeriveKey(sp->session,
5200 +                          &mechanism,
5201 +                          h_key,
5202 +                          priv_key_template,
5203 +                          ul_priv_key_attr_count,
5204 +                          &h_derived_key);
5205 +       if (rv != CKR_OK)
5206 +               {
5207 +               PK11err(PK11_F_DH_COMP_KEY, PK11_R_DERIVEKEY);
5208 +               snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
5209 +               ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
5210 +               goto err;
5211 +               }
5212 +
5213 +       rv = pFuncList->C_GetAttributeValue(sp->session, h_derived_key, 
5214 +               priv_key_result, priv_key_attr_result_count);
5215 +
5216 +       if (rv != CKR_OK)
5217 +               {
5218 +               PK11err(PK11_F_DH_COMP_KEY, PK11_R_GETATTRIBUTVALUE);
5219 +               snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
5220 +               ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
5221 +               goto err;
5222 +               }
5223 +
5224 +       if (((CK_LONG) priv_key_result[0].ulValueLen) <= 0)
5225 +               {
5226 +               PK11err(PK11_F_DH_COMP_KEY, PK11_R_GETATTRIBUTVALUE);
5227 +               goto err;
5228 +               }
5229 +       priv_key_result[0].pValue = 
5230 +               OPENSSL_malloc(priv_key_result[0].ulValueLen);
5231 +       if (!priv_key_result[0].pValue)
5232 +               {
5233 +               PK11err(PK11_F_DH_COMP_KEY, PK11_R_MALLOC_FAILURE);
5234 +               goto err;
5235 +               }
5236 +
5237 +       rv = pFuncList->C_GetAttributeValue(sp->session, h_derived_key, 
5238 +               priv_key_result, priv_key_attr_result_count);
5239 +
5240 +       if (rv != CKR_OK)
5241 +               {
5242 +               PK11err(PK11_F_DH_COMP_KEY, PK11_R_GETATTRIBUTVALUE);
5243 +               snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
5244 +               ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
5245 +               goto err;
5246 +               }
5247 +
5248 +       /* OpenSSL allocates the output buffer 'key' which is the same
5249 +        * length of the public key. It is long enough for the derived key */
5250 +       if (priv_key_result[0].type == CKA_VALUE)
5251 +               {
5252 +               /* CKM_DH_PKCS_DERIVE mechanism is not supposed to strip
5253 +                * leading zeros from a computed shared secret. However,
5254 +                * OpenSSL always did it so we must do the same here. The
5255 +                * vagueness of the spec regarding leading zero bytes was
5256 +                * finally cleared with TLS 1.1 (RFC 4346) saying that leading
5257 +                * zeros are stripped before the computed data is used as the
5258 +                * pre-master secret.
5259 +                */
5260 +               for (i = 0; i < priv_key_result[0].ulValueLen; ++i)
5261 +                       {
5262 +                       if (((char *) priv_key_result[0].pValue)[i] != 0)
5263 +                               break;
5264 +                       }
5265 +
5266 +               memcpy(key, ((char *) priv_key_result[0].pValue) + i, 
5267 +                       priv_key_result[0].ulValueLen - i);
5268 +               ret = priv_key_result[0].ulValueLen - i;
5269 +               }
5270 +
5271 +err:
5272 +
5273 +       if (h_derived_key != CK_INVALID_HANDLE)
5274 +               {
5275 +               rv = pFuncList->C_DestroyObject(sp->session, h_derived_key);
5276 +               if (rv != CKR_OK)
5277 +                       {
5278 +                       PK11err(PK11_F_DH_COMP_KEY, PK11_R_DESTROYOBJECT);
5279 +                       snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
5280 +                       ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
5281 +                       }
5282 +               }
5283 +       if (priv_key_result[0].pValue)
5284 +               { 
5285 +               OPENSSL_free(priv_key_result[0].pValue);
5286 +               priv_key_result[0].pValue = NULL;
5287 +               }
5288 +
5289 +       if (mechanism.pParameter)
5290 +               {
5291 +               OPENSSL_free(mechanism.pParameter);
5292 +               mechanism.pParameter = NULL;
5293 +               }
5294 +
5295 +       pk11_return_session(sp);
5296 +       return ret;
5297 +       }
5298 +
5299 +
5300 +static CK_OBJECT_HANDLE pk11_get_dh_key(DH* dh, PK11_SESSION *sp)
5301 +       {
5302 +       CK_RV rv;
5303 +       CK_OBJECT_HANDLE h_key = CK_INVALID_HANDLE;
5304 +       CK_OBJECT_CLASS class = CKO_PRIVATE_KEY;
5305 +       CK_KEY_TYPE key_type = CKK_DH;
5306 +       CK_ULONG found;
5307 +       int i;
5308 +       char tmp_buf[20];
5309 +
5310 +       CK_ULONG ul_key_attr_count = 7;
5311 +       CK_ATTRIBUTE key_template[] =
5312 +               {
5313 +               {CKA_CLASS, (void*) NULL, sizeof(class)},
5314 +               {CKA_KEY_TYPE, (void*) NULL, sizeof(key_type)},
5315 +               {CKA_DERIVE, &true, sizeof(true)},
5316 +               {CKA_PRIVATE, &false, sizeof(false)},
5317 +               {CKA_PRIME, (void *) NULL, 0},
5318 +               {CKA_BASE, (void *) NULL, 0},
5319 +               {CKA_VALUE, (void *) NULL, 0},
5320 +               };
5321 +
5322 +       CK_SESSION_HANDLE session = sp->session;
5323 +
5324 +       key_template[0].pValue = &class;
5325 +       key_template[1].pValue = &key_type;
5326 +
5327 +       key_template[4].ulValueLen = BN_num_bytes(dh->p);
5328 +       key_template[4].pValue = (CK_VOID_PTR)OPENSSL_malloc(
5329 +               (size_t)key_template[4].ulValueLen);
5330 +       if (key_template[4].pValue == NULL)
5331 +               {
5332 +               PK11err(PK11_F_GET_DH_KEY, PK11_R_MALLOC_FAILURE);
5333 +               goto err;
5334 +               }
5335 +
5336 +       BN_bn2bin(dh->p, key_template[4].pValue);
5337 +
5338 +       key_template[5].ulValueLen = BN_num_bytes(dh->g);
5339 +       key_template[5].pValue = (CK_VOID_PTR)OPENSSL_malloc(
5340 +               (size_t)key_template[5].ulValueLen);
5341 +       if (key_template[5].pValue == NULL)
5342 +               {
5343 +               PK11err(PK11_F_GET_DH_KEY, PK11_R_MALLOC_FAILURE);
5344 +               goto err;
5345 +               }
5346 +
5347 +       BN_bn2bin(dh->g, key_template[5].pValue);
5348 +
5349 +       key_template[6].ulValueLen = BN_num_bytes(dh->priv_key);
5350 +       key_template[6].pValue = (CK_VOID_PTR)OPENSSL_malloc(
5351 +               (size_t)key_template[6].ulValueLen);
5352 +       if (key_template[6].pValue == NULL)
5353 +               {
5354 +               PK11err(PK11_F_GET_DH_KEY, PK11_R_MALLOC_FAILURE);
5355 +               goto err;
5356 +               }
5357 +
5358 +       BN_bn2bin(dh->priv_key, key_template[6].pValue);
5359 +
5360 +       rv = pFuncList->C_FindObjectsInit(session, key_template, 
5361 +               ul_key_attr_count);
5362 +
5363 +       if (rv != CKR_OK)
5364 +               {
5365 +               PK11err(PK11_F_GET_DH_KEY, PK11_R_FINDOBJECTSINIT);
5366 +               snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
5367 +               ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
5368 +               goto err;
5369 +               }
5370 +
5371 +       rv = pFuncList->C_FindObjects(session, &h_key, 1, &found);
5372 +
5373 +       if (rv != CKR_OK)
5374 +               {
5375 +               PK11err(PK11_F_GET_DH_KEY, PK11_R_FINDOBJECTS);
5376 +               snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
5377 +               ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
5378 +               goto err;
5379 +               }
5380 +
5381 +       rv = pFuncList->C_FindObjectsFinal(session);
5382 +
5383 +       if (rv != CKR_OK)
5384 +               {
5385 +               PK11err(PK11_F_GET_DH_KEY, PK11_R_FINDOBJECTSFINAL);
5386 +               snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
5387 +               ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
5388 +               goto err;
5389 +               }
5390 +
5391 +       if (found == 0)
5392 +               {
5393 +               rv = pFuncList->C_CreateObject(session, 
5394 +                       key_template, ul_key_attr_count, &h_key);
5395 +               if (rv != CKR_OK)
5396 +                       {
5397 +                       PK11err(PK11_F_GET_DH_KEY, PK11_R_CREATEOBJECT);
5398 +                       snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
5399 +                       ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
5400 +                       goto err;
5401 +                       }
5402 +               }
5403 +
5404 +       sp->dh = dh;
5405 +
5406 + err:
5407 +       for (i = 4; i <= 6; i++)
5408 +               {
5409 +               if (key_template[i].pValue != NULL)
5410 +                       {
5411 +                       OPENSSL_free(key_template[i].pValue);
5412 +                       key_template[i].pValue = NULL;
5413 +                       }
5414 +               }
5415 +
5416 +       return h_key;
5417 +       }
5418 +
5419 +#endif
5420 +
5421 +/* Local function to simplify key template population
5422 + * Return 0 -- error, 1 -- no error
5423 + */
5424 +static int init_template_value(BIGNUM *bn, CK_VOID_PTR *p_value, 
5425 +       CK_ULONG *ul_value_len)
5426 +       {
5427 +       CK_ULONG len = BN_num_bytes(bn);
5428 +       if (len == 0)
5429 +               return 1;
5430 +
5431 +       *ul_value_len = len;
5432 +       *p_value = (CK_VOID_PTR)OPENSSL_malloc((size_t) *ul_value_len);
5433 +       if (*p_value == NULL)
5434 +               return 0;
5435 +
5436 +       BN_bn2bin(bn, *p_value);
5437 +
5438 +       return 1;
5439 +       }
5440 +
5441 +static void attr_to_BN(CK_ATTRIBUTE_PTR attr, CK_BYTE attr_data[], BIGNUM **bn)
5442 +       {
5443 +               if (attr->ulValueLen > 0)
5444 +                       {
5445 +                       *bn = BN_bin2bn(attr_data, attr->ulValueLen, NULL);
5446 +                       }
5447 +       }
5448 +
5449 +static void check_new_rsa_key(PK11_SESSION *sp, void *rsa)
5450 +       {
5451 +       if (sp->rsa != rsa)
5452 +               pk11_destroy_rsa_key_objects(sp);
5453 +       }
5454 +
5455 +static void check_new_dsa_key(PK11_SESSION *sp, void *dsa)
5456 +       {
5457 +       if (sp->dsa != dsa)
5458 +               pk11_destroy_dsa_key_objects(sp);
5459 +       }
5460 +
5461 +static void check_new_dh_key(PK11_SESSION *sp, void *dh)
5462 +       {
5463 +       if (sp->dh != dh)
5464 +               pk11_destroy_dh_key_objects(sp);
5465 +       }
5466 +
5467 +
5468 +#endif
5469 +#endif
5470 diff -r -u -N openssl-0.9.8g/crypto/engine/Makefile openssl/crypto/engine/Makefile
5471 --- openssl-0.9.8g/crypto/engine/Makefile       2005-07-16 13:13:05.000000000 +0200
5472 +++ openssl/crypto/engine/Makefile      2007-10-25 01:27:09.000000000 +0200
5473 @@ -21,12 +21,14 @@
5474         eng_table.c eng_pkey.c eng_fat.c eng_all.c \
5475         tb_rsa.c tb_dsa.c tb_ecdsa.c tb_dh.c tb_ecdh.c tb_rand.c tb_store.c \
5476         tb_cipher.c tb_digest.c \
5477 -       eng_openssl.c eng_cnf.c eng_dyn.c eng_cryptodev.c eng_padlock.c
5478 +       eng_openssl.c eng_cnf.c eng_dyn.c eng_cryptodev.c eng_padlock.c \
5479 +       hw_pk11.c hw_pk11_pub.c
5480  LIBOBJ= eng_err.o eng_lib.o eng_list.o eng_init.o eng_ctrl.o \
5481         eng_table.o eng_pkey.o eng_fat.o eng_all.o \
5482         tb_rsa.o tb_dsa.o tb_ecdsa.o tb_dh.o tb_ecdh.o tb_rand.o tb_store.o \
5483         tb_cipher.o tb_digest.o \
5484 -       eng_openssl.o eng_cnf.o eng_dyn.o eng_cryptodev.o eng_padlock.o
5485 +       eng_openssl.o eng_cnf.o eng_dyn.o eng_cryptodev.o eng_padlock.o \
5486 +       hw_pk11.o hw_pk11_pub.o
5487  
5488  SRC= $(LIBSRC)
5489  
5490 @@ -212,6 +214,54 @@
5491  eng_table.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
5492  eng_table.o: ../../include/openssl/symhacks.h ../cryptlib.h eng_int.h
5493  eng_table.o: eng_table.c
5494 +hw_pk11.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
5495 +hw_pk11.o: ../../include/openssl/engine.h ../../include/openssl/ossl_typ.h
5496 +hw_pk11.o: ../../include/openssl/bn.h ../../include/openssl/rsa.h
5497 +hw_pk11.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
5498 +hw_pk11.o: ../../include/openssl/crypto.h ../../include/openssl/stack.h
5499 +hw_pk11.o: ../../include/openssl/safestack.h ../../include/openssl/opensslv.h
5500 +hw_pk11.o: ../../include/openssl/symhacks.h ../../include/openssl/dsa.h
5501 +hw_pk11.o: ../../include/openssl/dh.h ../../include/openssl/rand.h
5502 +hw_pk11.o: ../../include/openssl/ui.h ../../include/openssl/err.h
5503 +hw_pk11.o: ../../include/openssl/lhash.h ../../include/openssl/dso.h
5504 +hw_pk11.o: ../../include/openssl/pem.h ../../include/openssl/evp.h
5505 +hw_pk11.o: ../../include/openssl/md2.h ../../include/openssl/md4.h
5506 +hw_pk11.o: ../../include/openssl/md5.h ../../include/openssl/sha.h
5507 +hw_pk11.o: ../../include/openssl/ripemd.h ../../include/openssl/des.h
5508 +hw_pk11.o: ../../include/openssl/des_old.h ../../include/openssl/ui_compat.h
5509 +hw_pk11.o: ../../include/openssl/rc4.h ../../include/openssl/rc2.h
5510 +hw_pk11.o: ../../crypto/rc5/rc5.h ../../include/openssl/blowfish.h
5511 +hw_pk11.o: ../../include/openssl/cast.h ../../include/openssl/idea.h
5512 +hw_pk11.o: ../../crypto/mdc2/mdc2.h ../../include/openssl/aes.h
5513 +hw_pk11.o: ../../include/openssl/objects.h ../../include/openssl/obj_mac.h
5514 +hw_pk11.o: ../../include/openssl/x509.h ../../include/openssl/buffer.h
5515 +hw_pk11.o: ../../include/openssl/x509_vfy.h ../../include/openssl/pkcs7.h
5516 +hw_pk11.o: ../../include/openssl/pem2.h ../cryptlib.h
5517 +hw_pk11.o: ../../e_os.h hw_pk11_err.c hw_pk11_err.h hw_pk11.c
5518 +hw_pk11_pub.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
5519 +hw_pk11_pub.o: ../../include/openssl/engine.h ../../include/openssl/ossl_typ.h
5520 +hw_pk11_pub.o: ../../include/openssl/bn.h ../../include/openssl/rsa.h
5521 +hw_pk11_pub.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
5522 +hw_pk11_pub.o: ../../include/openssl/crypto.h ../../include/openssl/stack.h
5523 +hw_pk11_pub.o: ../../include/openssl/safestack.h ../../include/openssl/opensslv.h
5524 +hw_pk11_pub.o: ../../include/openssl/symhacks.h ../../include/openssl/dsa.h
5525 +hw_pk11_pub.o: ../../include/openssl/dh.h ../../include/openssl/rand.h
5526 +hw_pk11_pub.o: ../../include/openssl/ui.h ../../include/openssl/err.h
5527 +hw_pk11_pub.o: ../../include/openssl/lhash.h ../../include/openssl/dso.h
5528 +hw_pk11_pub.o: ../../include/openssl/pem.h ../../include/openssl/evp.h
5529 +hw_pk11_pub.o: ../../include/openssl/md2.h ../../include/openssl/md4.h
5530 +hw_pk11_pub.o: ../../include/openssl/md5.h ../../include/openssl/sha.h
5531 +hw_pk11_pub.o: ../../include/openssl/ripemd.h ../../include/openssl/des.h
5532 +hw_pk11_pub.o: ../../include/openssl/des_old.h ../../include/openssl/ui_compat.h
5533 +hw_pk11_pub.o: ../../include/openssl/rc4.h ../../include/openssl/rc2.h
5534 +hw_pk11_pub.o: ../../crypto/rc5/rc5.h ../../include/openssl/blowfish.h
5535 +hw_pk11_pub.o: ../../include/openssl/cast.h ../../include/openssl/idea.h
5536 +hw_pk11_pub.o: ../../crypto/mdc2/mdc2.h ../../include/openssl/aes.h
5537 +hw_pk11_pub.o: ../../include/openssl/objects.h ../../include/openssl/obj_mac.h
5538 +hw_pk11_pub.o: ../../include/openssl/x509.h ../../include/openssl/buffer.h
5539 +hw_pk11_pub.o: ../../include/openssl/x509_vfy.h ../../include/openssl/pkcs7.h
5540 +hw_pk11_pub.o: ../../include/openssl/pem2.h ../cryptlib.h
5541 +hw_pk11_pub.o: ../../e_os.h hw_pk11_err.c hw_pk11_err.h hw_pk11_pub.c
5542  tb_cipher.o: ../../e_os.h ../../include/openssl/bio.h
5543  tb_cipher.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
5544  tb_cipher.o: ../../include/openssl/e_os2.h ../../include/openssl/engine.h
5545 diff -r -u -N openssl-0.9.8g/crypto/engine/pkcs11f.h openssl/crypto/engine/pkcs11f.h
5546 --- openssl-0.9.8g/crypto/engine/pkcs11f.h      1970-01-01 01:00:00.000000000 +0100
5547 +++ openssl/crypto/engine/pkcs11f.h     2007-10-25 01:27:09.000000000 +0200
5548 @@ -0,0 +1,912 @@
5549 +/* pkcs11f.h include file for PKCS #11. */
5550 +/* $Revision: 1.2 $ */
5551 +
5552 +/* License to copy and use this software is granted provided that it is
5553 + * identified as "RSA Security Inc. PKCS #11 Cryptographic Token Interface
5554 + * (Cryptoki)" in all material mentioning or referencing this software.
5555 +
5556 + * License is also granted to make and use derivative works provided that
5557 + * such works are identified as "derived from the RSA Security Inc. PKCS #11
5558 + * Cryptographic Token Interface (Cryptoki)" in all material mentioning or 
5559 + * referencing the derived work.
5560 +
5561 + * RSA Security Inc. makes no representations concerning either the 
5562 + * merchantability of this software or the suitability of this software for
5563 + * any particular purpose. It is provided "as is" without express or implied
5564 + * warranty of any kind.
5565 + */
5566 +
5567 +/* This header file contains pretty much everything about all the */
5568 +/* Cryptoki function prototypes.  Because this information is */
5569 +/* used for more than just declaring function prototypes, the */
5570 +/* order of the functions appearing herein is important, and */
5571 +/* should not be altered. */
5572 +
5573 +/* General-purpose */
5574 +
5575 +/* C_Initialize initializes the Cryptoki library. */
5576 +CK_PKCS11_FUNCTION_INFO(C_Initialize)
5577 +#ifdef CK_NEED_ARG_LIST
5578 +(
5579 +  CK_VOID_PTR   pInitArgs  /* if this is not NULL_PTR, it gets
5580 +                            * cast to CK_C_INITIALIZE_ARGS_PTR
5581 +                            * and dereferenced */
5582 +);
5583 +#endif
5584 +
5585 +
5586 +/* C_Finalize indicates that an application is done with the
5587 + * Cryptoki library. */
5588 +CK_PKCS11_FUNCTION_INFO(C_Finalize)
5589 +#ifdef CK_NEED_ARG_LIST
5590 +(
5591 +  CK_VOID_PTR   pReserved  /* reserved.  Should be NULL_PTR */
5592 +);
5593 +#endif
5594 +
5595 +
5596 +/* C_GetInfo returns general information about Cryptoki. */
5597 +CK_PKCS11_FUNCTION_INFO(C_GetInfo)
5598 +#ifdef CK_NEED_ARG_LIST
5599 +(
5600 +  CK_INFO_PTR   pInfo  /* location that receives information */
5601 +);
5602 +#endif
5603 +
5604 +
5605 +/* C_GetFunctionList returns the function list. */
5606 +CK_PKCS11_FUNCTION_INFO(C_GetFunctionList)
5607 +#ifdef CK_NEED_ARG_LIST
5608 +(
5609 +  CK_FUNCTION_LIST_PTR_PTR ppFunctionList  /* receives pointer to
5610 +                                            * function list */
5611 +);
5612 +#endif
5613 +
5614 +
5615 +
5616 +/* Slot and token management */
5617 +
5618 +/* C_GetSlotList obtains a list of slots in the system. */
5619 +CK_PKCS11_FUNCTION_INFO(C_GetSlotList)
5620 +#ifdef CK_NEED_ARG_LIST
5621 +(
5622 +  CK_BBOOL       tokenPresent,  /* only slots with tokens? */
5623 +  CK_SLOT_ID_PTR pSlotList,     /* receives array of slot IDs */
5624 +  CK_ULONG_PTR   pulCount       /* receives number of slots */
5625 +);
5626 +#endif
5627 +
5628 +
5629 +/* C_GetSlotInfo obtains information about a particular slot in
5630 + * the system. */
5631 +CK_PKCS11_FUNCTION_INFO(C_GetSlotInfo)
5632 +#ifdef CK_NEED_ARG_LIST
5633 +(
5634 +  CK_SLOT_ID       slotID,  /* the ID of the slot */
5635 +  CK_SLOT_INFO_PTR pInfo    /* receives the slot information */
5636 +);
5637 +#endif
5638 +
5639 +
5640 +/* C_GetTokenInfo obtains information about a particular token
5641 + * in the system. */
5642 +CK_PKCS11_FUNCTION_INFO(C_GetTokenInfo)
5643 +#ifdef CK_NEED_ARG_LIST
5644 +(
5645 +  CK_SLOT_ID        slotID,  /* ID of the token's slot */
5646 +  CK_TOKEN_INFO_PTR pInfo    /* receives the token information */
5647 +);
5648 +#endif
5649 +
5650 +
5651 +/* C_GetMechanismList obtains a list of mechanism types
5652 + * supported by a token. */
5653 +CK_PKCS11_FUNCTION_INFO(C_GetMechanismList)
5654 +#ifdef CK_NEED_ARG_LIST
5655 +(
5656 +  CK_SLOT_ID            slotID,          /* ID of token's slot */
5657 +  CK_MECHANISM_TYPE_PTR pMechanismList,  /* gets mech. array */
5658 +  CK_ULONG_PTR          pulCount         /* gets # of mechs. */
5659 +);
5660 +#endif
5661 +
5662 +
5663 +/* C_GetMechanismInfo obtains information about a particular
5664 + * mechanism possibly supported by a token. */
5665 +CK_PKCS11_FUNCTION_INFO(C_GetMechanismInfo)
5666 +#ifdef CK_NEED_ARG_LIST
5667 +(
5668 +  CK_SLOT_ID            slotID,  /* ID of the token's slot */
5669 +  CK_MECHANISM_TYPE     type,    /* type of mechanism */
5670 +  CK_MECHANISM_INFO_PTR pInfo    /* receives mechanism info */
5671 +);
5672 +#endif
5673 +
5674 +
5675 +/* C_InitToken initializes a token. */
5676 +CK_PKCS11_FUNCTION_INFO(C_InitToken)
5677 +#ifdef CK_NEED_ARG_LIST
5678 +/* pLabel changed from CK_CHAR_PTR to CK_UTF8CHAR_PTR for v2.10 */
5679 +(
5680 +  CK_SLOT_ID      slotID,    /* ID of the token's slot */
5681 +  CK_UTF8CHAR_PTR pPin,      /* the SO's initial PIN */
5682 +  CK_ULONG        ulPinLen,  /* length in bytes of the PIN */
5683 +  CK_UTF8CHAR_PTR pLabel     /* 32-byte token label (blank padded) */
5684 +);
5685 +#endif
5686 +
5687 +
5688 +/* C_InitPIN initializes the normal user's PIN. */
5689 +CK_PKCS11_FUNCTION_INFO(C_InitPIN)
5690 +#ifdef CK_NEED_ARG_LIST
5691 +(
5692 +  CK_SESSION_HANDLE hSession,  /* the session's handle */
5693 +  CK_UTF8CHAR_PTR   pPin,      /* the normal user's PIN */
5694 +  CK_ULONG          ulPinLen   /* length in bytes of the PIN */
5695 +);
5696 +#endif
5697 +
5698 +
5699 +/* C_SetPIN modifies the PIN of the user who is logged in. */
5700 +CK_PKCS11_FUNCTION_INFO(C_SetPIN)
5701 +#ifdef CK_NEED_ARG_LIST
5702 +(
5703 +  CK_SESSION_HANDLE hSession,  /* the session's handle */
5704 +  CK_UTF8CHAR_PTR   pOldPin,   /* the old PIN */
5705 +  CK_ULONG          ulOldLen,  /* length of the old PIN */
5706 +  CK_UTF8CHAR_PTR   pNewPin,   /* the new PIN */
5707 +  CK_ULONG          ulNewLen   /* length of the new PIN */
5708 +);
5709 +#endif
5710 +
5711 +
5712 +
5713 +/* Session management */
5714 +
5715 +/* C_OpenSession opens a session between an application and a
5716 + * token. */
5717 +CK_PKCS11_FUNCTION_INFO(C_OpenSession)
5718 +#ifdef CK_NEED_ARG_LIST
5719 +(
5720 +  CK_SLOT_ID            slotID,        /* the slot's ID */
5721 +  CK_FLAGS              flags,         /* from CK_SESSION_INFO */
5722 +  CK_VOID_PTR           pApplication,  /* passed to callback */
5723 +  CK_NOTIFY             Notify,        /* callback function */
5724 +  CK_SESSION_HANDLE_PTR phSession      /* gets session handle */
5725 +);
5726 +#endif
5727 +
5728 +
5729 +/* C_CloseSession closes a session between an application and a
5730 + * token. */
5731 +CK_PKCS11_FUNCTION_INFO(C_CloseSession)
5732 +#ifdef CK_NEED_ARG_LIST
5733 +(
5734 +  CK_SESSION_HANDLE hSession  /* the session's handle */
5735 +);
5736 +#endif
5737 +
5738 +
5739 +/* C_CloseAllSessions closes all sessions with a token. */
5740 +CK_PKCS11_FUNCTION_INFO(C_CloseAllSessions)
5741 +#ifdef CK_NEED_ARG_LIST
5742 +(
5743 +  CK_SLOT_ID     slotID  /* the token's slot */
5744 +);
5745 +#endif
5746 +
5747 +
5748 +/* C_GetSessionInfo obtains information about the session. */
5749 +CK_PKCS11_FUNCTION_INFO(C_GetSessionInfo)
5750 +#ifdef CK_NEED_ARG_LIST
5751 +(
5752 +  CK_SESSION_HANDLE   hSession,  /* the session's handle */
5753 +  CK_SESSION_INFO_PTR pInfo      /* receives session info */
5754 +);
5755 +#endif
5756 +
5757 +
5758 +/* C_GetOperationState obtains the state of the cryptographic operation
5759 + * in a session. */
5760 +CK_PKCS11_FUNCTION_INFO(C_GetOperationState)
5761 +#ifdef CK_NEED_ARG_LIST
5762 +(
5763 +  CK_SESSION_HANDLE hSession,             /* session's handle */
5764 +  CK_BYTE_PTR       pOperationState,      /* gets state */
5765 +  CK_ULONG_PTR      pulOperationStateLen  /* gets state length */
5766 +);
5767 +#endif
5768 +
5769 +
5770 +/* C_SetOperationState restores the state of the cryptographic
5771 + * operation in a session. */
5772 +CK_PKCS11_FUNCTION_INFO(C_SetOperationState)
5773 +#ifdef CK_NEED_ARG_LIST
5774 +(
5775 +  CK_SESSION_HANDLE hSession,            /* session's handle */
5776 +  CK_BYTE_PTR      pOperationState,      /* holds state */
5777 +  CK_ULONG         ulOperationStateLen,  /* holds state length */
5778 +  CK_OBJECT_HANDLE hEncryptionKey,       /* en/decryption key */
5779 +  CK_OBJECT_HANDLE hAuthenticationKey    /* sign/verify key */
5780 +);
5781 +#endif
5782 +
5783 +
5784 +/* C_Login logs a user into a token. */
5785 +CK_PKCS11_FUNCTION_INFO(C_Login)
5786 +#ifdef CK_NEED_ARG_LIST
5787 +(
5788 +  CK_SESSION_HANDLE hSession,  /* the session's handle */
5789 +  CK_USER_TYPE      userType,  /* the user type */
5790 +  CK_UTF8CHAR_PTR   pPin,      /* the user's PIN */
5791 +  CK_ULONG          ulPinLen   /* the length of the PIN */
5792 +);
5793 +#endif
5794 +
5795 +
5796 +/* C_Logout logs a user out from a token. */
5797 +CK_PKCS11_FUNCTION_INFO(C_Logout)
5798 +#ifdef CK_NEED_ARG_LIST
5799 +(
5800 +  CK_SESSION_HANDLE hSession  /* the session's handle */
5801 +);
5802 +#endif
5803 +
5804 +
5805 +
5806 +/* Object management */
5807 +
5808 +/* C_CreateObject creates a new object. */
5809 +CK_PKCS11_FUNCTION_INFO(C_CreateObject)
5810 +#ifdef CK_NEED_ARG_LIST
5811 +(
5812 +  CK_SESSION_HANDLE hSession,    /* the session's handle */
5813 +  CK_ATTRIBUTE_PTR  pTemplate,   /* the object's template */
5814 +  CK_ULONG          ulCount,     /* attributes in template */
5815 +  CK_OBJECT_HANDLE_PTR phObject  /* gets new object's handle. */
5816 +);
5817 +#endif
5818 +
5819 +
5820 +/* C_CopyObject copies an object, creating a new object for the
5821 + * copy. */
5822 +CK_PKCS11_FUNCTION_INFO(C_CopyObject)
5823 +#ifdef CK_NEED_ARG_LIST
5824 +(
5825 +  CK_SESSION_HANDLE    hSession,    /* the session's handle */
5826 +  CK_OBJECT_HANDLE     hObject,     /* the object's handle */
5827 +  CK_ATTRIBUTE_PTR     pTemplate,   /* template for new object */
5828 +  CK_ULONG             ulCount,     /* attributes in template */
5829 +  CK_OBJECT_HANDLE_PTR phNewObject  /* receives handle of copy */
5830 +);
5831 +#endif
5832 +
5833 +
5834 +/* C_DestroyObject destroys an object. */
5835 +CK_PKCS11_FUNCTION_INFO(C_DestroyObject)
5836 +#ifdef CK_NEED_ARG_LIST
5837 +(
5838 +  CK_SESSION_HANDLE hSession,  /* the session's handle */
5839 +  CK_OBJECT_HANDLE  hObject    /* the object's handle */
5840 +);
5841 +#endif
5842 +
5843 +
5844 +/* C_GetObjectSize gets the size of an object in bytes. */
5845 +CK_PKCS11_FUNCTION_INFO(C_GetObjectSize)
5846 +#ifdef CK_NEED_ARG_LIST
5847 +(
5848 +  CK_SESSION_HANDLE hSession,  /* the session's handle */
5849 +  CK_OBJECT_HANDLE  hObject,   /* the object's handle */
5850 +  CK_ULONG_PTR      pulSize    /* receives size of object */
5851 +);
5852 +#endif
5853 +
5854 +
5855 +/* C_GetAttributeValue obtains the value of one or more object
5856 + * attributes. */
5857 +CK_PKCS11_FUNCTION_INFO(C_GetAttributeValue)
5858 +#ifdef CK_NEED_ARG_LIST
5859 +(
5860 +  CK_SESSION_HANDLE hSession,   /* the session's handle */
5861 +  CK_OBJECT_HANDLE  hObject,    /* the object's handle */
5862 +  CK_ATTRIBUTE_PTR  pTemplate,  /* specifies attrs; gets vals */
5863 +  CK_ULONG          ulCount     /* attributes in template */
5864 +);
5865 +#endif
5866 +
5867 +
5868 +/* C_SetAttributeValue modifies the value of one or more object
5869 + * attributes */
5870 +CK_PKCS11_FUNCTION_INFO(C_SetAttributeValue)
5871 +#ifdef CK_NEED_ARG_LIST
5872 +(
5873 +  CK_SESSION_HANDLE hSession,   /* the session's handle */
5874 +  CK_OBJECT_HANDLE  hObject,    /* the object's handle */
5875 +  CK_ATTRIBUTE_PTR  pTemplate,  /* specifies attrs and values */
5876 +  CK_ULONG          ulCount     /* attributes in template */
5877 +);
5878 +#endif
5879 +
5880 +
5881 +/* C_FindObjectsInit initializes a search for token and session
5882 + * objects that match a template. */
5883 +CK_PKCS11_FUNCTION_INFO(C_FindObjectsInit)
5884 +#ifdef CK_NEED_ARG_LIST
5885 +(
5886 +  CK_SESSION_HANDLE hSession,   /* the session's handle */
5887 +  CK_ATTRIBUTE_PTR  pTemplate,  /* attribute values to match */
5888 +  CK_ULONG          ulCount     /* attrs in search template */
5889 +);
5890 +#endif
5891 +
5892 +
5893 +/* C_FindObjects continues a search for token and session
5894 + * objects that match a template, obtaining additional object
5895 + * handles. */
5896 +CK_PKCS11_FUNCTION_INFO(C_FindObjects)
5897 +#ifdef CK_NEED_ARG_LIST
5898 +(
5899 + CK_SESSION_HANDLE    hSession,          /* session's handle */
5900 + CK_OBJECT_HANDLE_PTR phObject,          /* gets obj. handles */
5901 + CK_ULONG             ulMaxObjectCount,  /* max handles to get */
5902 + CK_ULONG_PTR         pulObjectCount     /* actual # returned */
5903 +);
5904 +#endif
5905 +
5906 +
5907 +/* C_FindObjectsFinal finishes a search for token and session
5908 + * objects. */
5909 +CK_PKCS11_FUNCTION_INFO(C_FindObjectsFinal)
5910 +#ifdef CK_NEED_ARG_LIST
5911 +(
5912 +  CK_SESSION_HANDLE hSession  /* the session's handle */
5913 +);
5914 +#endif
5915 +
5916 +
5917 +
5918 +/* Encryption and decryption */
5919 +
5920 +/* C_EncryptInit initializes an encryption operation. */
5921 +CK_PKCS11_FUNCTION_INFO(C_EncryptInit)
5922 +#ifdef CK_NEED_ARG_LIST
5923 +(
5924 +  CK_SESSION_HANDLE hSession,    /* the session's handle */
5925 +  CK_MECHANISM_PTR  pMechanism,  /* the encryption mechanism */
5926 +  CK_OBJECT_HANDLE  hKey         /* handle of encryption key */
5927 +);
5928 +#endif
5929 +
5930 +
5931 +/* C_Encrypt encrypts single-part data. */
5932 +CK_PKCS11_FUNCTION_INFO(C_Encrypt)
5933 +#ifdef CK_NEED_ARG_LIST
5934 +(
5935 +  CK_SESSION_HANDLE hSession,            /* session's handle */
5936 +  CK_BYTE_PTR       pData,               /* the plaintext data */
5937 +  CK_ULONG          ulDataLen,           /* bytes of plaintext */
5938 +  CK_BYTE_PTR       pEncryptedData,      /* gets ciphertext */
5939 +  CK_ULONG_PTR      pulEncryptedDataLen  /* gets c-text size */
5940 +);
5941 +#endif
5942 +
5943 +
5944 +/* C_EncryptUpdate continues a multiple-part encryption
5945 + * operation. */
5946 +CK_PKCS11_FUNCTION_INFO(C_EncryptUpdate)
5947 +#ifdef CK_NEED_ARG_LIST
5948 +(
5949 +  CK_SESSION_HANDLE hSession,           /* session's handle */
5950 +  CK_BYTE_PTR       pPart,              /* the plaintext data */
5951 +  CK_ULONG          ulPartLen,          /* plaintext data len */
5952 +  CK_BYTE_PTR       pEncryptedPart,     /* gets ciphertext */
5953 +  CK_ULONG_PTR      pulEncryptedPartLen /* gets c-text size */
5954 +);
5955 +#endif
5956 +
5957 +
5958 +/* C_EncryptFinal finishes a multiple-part encryption
5959 + * operation. */
5960 +CK_PKCS11_FUNCTION_INFO(C_EncryptFinal)
5961 +#ifdef CK_NEED_ARG_LIST
5962 +(
5963 +  CK_SESSION_HANDLE hSession,                /* session handle */
5964 +  CK_BYTE_PTR       pLastEncryptedPart,      /* last c-text */
5965 +  CK_ULONG_PTR      pulLastEncryptedPartLen  /* gets last size */
5966 +);
5967 +#endif
5968 +
5969 +
5970 +/* C_DecryptInit initializes a decryption operation. */
5971 +CK_PKCS11_FUNCTION_INFO(C_DecryptInit)
5972 +#ifdef CK_NEED_ARG_LIST
5973 +(
5974 +  CK_SESSION_HANDLE hSession,    /* the session's handle */
5975 +  CK_MECHANISM_PTR  pMechanism,  /* the decryption mechanism */
5976 +  CK_OBJECT_HANDLE  hKey         /* handle of decryption key */
5977 +);
5978 +#endif
5979 +
5980 +
5981 +/* C_Decrypt decrypts encrypted data in a single part. */
5982 +CK_PKCS11_FUNCTION_INFO(C_Decrypt)
5983 +#ifdef CK_NEED_ARG_LIST
5984 +(
5985 +  CK_SESSION_HANDLE hSession,           /* session's handle */
5986 +  CK_BYTE_PTR       pEncryptedData,     /* ciphertext */
5987 +  CK_ULONG          ulEncryptedDataLen, /* ciphertext length */
5988 +  CK_BYTE_PTR       pData,              /* gets plaintext */
5989 +  CK_ULONG_PTR      pulDataLen          /* gets p-text size */
5990 +);
5991 +#endif
5992 +
5993 +
5994 +/* C_DecryptUpdate continues a multiple-part decryption
5995 + * operation. */
5996 +CK_PKCS11_FUNCTION_INFO(C_DecryptUpdate)
5997 +#ifdef CK_NEED_ARG_LIST
5998 +(
5999 +  CK_SESSION_HANDLE hSession,            /* session's handle */
6000 +  CK_BYTE_PTR       pEncryptedPart,      /* encrypted data */
6001 +  CK_ULONG          ulEncryptedPartLen,  /* input length */
6002 +  CK_BYTE_PTR       pPart,               /* gets plaintext */
6003 +  CK_ULONG_PTR      pulPartLen           /* p-text size */
6004 +);
6005 +#endif
6006 +
6007 +
6008 +/* C_DecryptFinal finishes a multiple-part decryption
6009 + * operation. */
6010 +CK_PKCS11_FUNCTION_INFO(C_DecryptFinal)
6011 +#ifdef CK_NEED_ARG_LIST
6012 +(
6013 +  CK_SESSION_HANDLE hSession,       /* the session's handle */
6014 +  CK_BYTE_PTR       pLastPart,      /* gets plaintext */
6015 +  CK_ULONG_PTR      pulLastPartLen  /* p-text size */
6016 +);
6017 +#endif
6018 +
6019 +
6020 +
6021 +/* Message digesting */
6022 +
6023 +/* C_DigestInit initializes a message-digesting operation. */
6024 +CK_PKCS11_FUNCTION_INFO(C_DigestInit)
6025 +#ifdef CK_NEED_ARG_LIST
6026 +(
6027 +  CK_SESSION_HANDLE hSession,   /* the session's handle */
6028 +  CK_MECHANISM_PTR  pMechanism  /* the digesting mechanism */
6029 +);
6030 +#endif
6031 +
6032 +
6033 +/* C_Digest digests data in a single part. */
6034 +CK_PKCS11_FUNCTION_INFO(C_Digest)
6035 +#ifdef CK_NEED_ARG_LIST
6036 +(
6037 +  CK_SESSION_HANDLE hSession,     /* the session's handle */
6038 +  CK_BYTE_PTR       pData,        /* data to be digested */
6039 +  CK_ULONG          ulDataLen,    /* bytes of data to digest */
6040 +  CK_BYTE_PTR       pDigest,      /* gets the message digest */
6041 +  CK_ULONG_PTR      pulDigestLen  /* gets digest length */
6042 +);
6043 +#endif
6044 +
6045 +
6046 +/* C_DigestUpdate continues a multiple-part message-digesting
6047 + * operation. */
6048 +CK_PKCS11_FUNCTION_INFO(C_DigestUpdate)
6049 +#ifdef CK_NEED_ARG_LIST
6050 +(
6051 +  CK_SESSION_HANDLE hSession,  /* the session's handle */
6052 +  CK_BYTE_PTR       pPart,     /* data to be digested */
6053 +  CK_ULONG          ulPartLen  /* bytes of data to be digested */
6054 +);
6055 +#endif
6056 +
6057 +
6058 +/* C_DigestKey continues a multi-part message-digesting
6059 + * operation, by digesting the value of a secret key as part of
6060 + * the data already digested. */
6061 +CK_PKCS11_FUNCTION_INFO(C_DigestKey)
6062 +#ifdef CK_NEED_ARG_LIST
6063 +(
6064 +  CK_SESSION_HANDLE hSession,  /* the session's handle */
6065 +  CK_OBJECT_HANDLE  hKey       /* secret key to digest */
6066 +);
6067 +#endif
6068 +
6069 +
6070 +/* C_DigestFinal finishes a multiple-part message-digesting
6071 + * operation. */
6072 +CK_PKCS11_FUNCTION_INFO(C_DigestFinal)
6073 +#ifdef CK_NEED_ARG_LIST
6074 +(
6075 +  CK_SESSION_HANDLE hSession,     /* the session's handle */
6076 +  CK_BYTE_PTR       pDigest,      /* gets the message digest */
6077 +  CK_ULONG_PTR      pulDigestLen  /* gets byte count of digest */
6078 +);
6079 +#endif
6080 +
6081 +
6082 +
6083 +/* Signing and MACing */
6084 +
6085 +/* C_SignInit initializes a signature (private key encryption)
6086 + * operation, where the signature is (will be) an appendix to
6087 + * the data, and plaintext cannot be recovered from the
6088 + *signature. */
6089 +CK_PKCS11_FUNCTION_INFO(C_SignInit)
6090 +#ifdef CK_NEED_ARG_LIST
6091 +(
6092 +  CK_SESSION_HANDLE hSession,    /* the session's handle */
6093 +  CK_MECHANISM_PTR  pMechanism,  /* the signature mechanism */
6094 +  CK_OBJECT_HANDLE  hKey         /* handle of signature key */
6095 +);
6096 +#endif
6097 +
6098 +
6099 +/* C_Sign signs (encrypts with private key) data in a single
6100 + * part, where the signature is (will be) an appendix to the
6101 + * data, and plaintext cannot be recovered from the signature. */
6102 +CK_PKCS11_FUNCTION_INFO(C_Sign)
6103 +#ifdef CK_NEED_ARG_LIST
6104 +(
6105 +  CK_SESSION_HANDLE hSession,        /* the session's handle */
6106 +  CK_BYTE_PTR       pData,           /* the data to sign */
6107 +  CK_ULONG          ulDataLen,       /* count of bytes to sign */
6108 +  CK_BYTE_PTR       pSignature,      /* gets the signature */
6109 +  CK_ULONG_PTR      pulSignatureLen  /* gets signature length */
6110 +);
6111 +#endif
6112 +
6113 +
6114 +/* C_SignUpdate continues a multiple-part signature operation,
6115 + * where the signature is (will be) an appendix to the data, 
6116 + * and plaintext cannot be recovered from the signature. */
6117 +CK_PKCS11_FUNCTION_INFO(C_SignUpdate)
6118 +#ifdef CK_NEED_ARG_LIST
6119 +(
6120 +  CK_SESSION_HANDLE hSession,  /* the session's handle */
6121 +  CK_BYTE_PTR       pPart,     /* the data to sign */
6122 +  CK_ULONG          ulPartLen  /* count of bytes to sign */
6123 +);
6124 +#endif
6125 +
6126 +
6127 +/* C_SignFinal finishes a multiple-part signature operation, 
6128 + * returning the signature. */
6129 +CK_PKCS11_FUNCTION_INFO(C_SignFinal)
6130 +#ifdef CK_NEED_ARG_LIST
6131 +(
6132 +  CK_SESSION_HANDLE hSession,        /* the session's handle */
6133 +  CK_BYTE_PTR       pSignature,      /* gets the signature */
6134 +  CK_ULONG_PTR      pulSignatureLen  /* gets signature length */
6135 +);
6136 +#endif
6137 +
6138 +
6139 +/* C_SignRecoverInit initializes a signature operation, where
6140 + * the data can be recovered from the signature. */
6141 +CK_PKCS11_FUNCTION_INFO(C_SignRecoverInit)
6142 +#ifdef CK_NEED_ARG_LIST
6143 +(
6144 +  CK_SESSION_HANDLE hSession,   /* the session's handle */
6145 +  CK_MECHANISM_PTR  pMechanism, /* the signature mechanism */
6146 +  CK_OBJECT_HANDLE  hKey        /* handle of the signature key */
6147 +);
6148 +#endif
6149 +
6150 +
6151 +/* C_SignRecover signs data in a single operation, where the
6152 + * data can be recovered from the signature. */
6153 +CK_PKCS11_FUNCTION_INFO(C_SignRecover)
6154 +#ifdef CK_NEED_ARG_LIST
6155 +(
6156 +  CK_SESSION_HANDLE hSession,        /* the session's handle */
6157 +  CK_BYTE_PTR       pData,           /* the data to sign */
6158 +  CK_ULONG          ulDataLen,       /* count of bytes to sign */
6159 +  CK_BYTE_PTR       pSignature,      /* gets the signature */
6160 +  CK_ULONG_PTR      pulSignatureLen  /* gets signature length */
6161 +);
6162 +#endif
6163 +
6164 +
6165 +
6166 +/* Verifying signatures and MACs */
6167 +
6168 +/* C_VerifyInit initializes a verification operation, where the
6169 + * signature is an appendix to the data, and plaintext cannot
6170 + *  cannot be recovered from the signature (e.g. DSA). */
6171 +CK_PKCS11_FUNCTION_INFO(C_VerifyInit)
6172 +#ifdef CK_NEED_ARG_LIST
6173 +(
6174 +  CK_SESSION_HANDLE hSession,    /* the session's handle */
6175 +  CK_MECHANISM_PTR  pMechanism,  /* the verification mechanism */
6176 +  CK_OBJECT_HANDLE  hKey         /* verification key */ 
6177 +);
6178 +#endif
6179 +
6180 +
6181 +/* C_Verify verifies a signature in a single-part operation, 
6182 + * where the signature is an appendix to the data, and plaintext
6183 + * cannot be recovered from the signature. */
6184 +CK_PKCS11_FUNCTION_INFO(C_Verify)
6185 +#ifdef CK_NEED_ARG_LIST
6186 +(
6187 +  CK_SESSION_HANDLE hSession,       /* the session's handle */
6188 +  CK_BYTE_PTR       pData,          /* signed data */
6189 +  CK_ULONG          ulDataLen,      /* length of signed data */
6190 +  CK_BYTE_PTR       pSignature,     /* signature */
6191 +  CK_ULONG          ulSignatureLen  /* signature length*/
6192 +);
6193 +#endif
6194 +
6195 +
6196 +/* C_VerifyUpdate continues a multiple-part verification
6197 + * operation, where the signature is an appendix to the data, 
6198 + * and plaintext cannot be recovered from the signature. */
6199 +CK_PKCS11_FUNCTION_INFO(C_VerifyUpdate)
6200 +#ifdef CK_NEED_ARG_LIST
6201 +(
6202 +  CK_SESSION_HANDLE hSession,  /* the session's handle */
6203 +  CK_BYTE_PTR       pPart,     /* signed data */
6204 +  CK_ULONG          ulPartLen  /* length of signed data */
6205 +);
6206 +#endif
6207 +
6208 +
6209 +/* C_VerifyFinal finishes a multiple-part verification
6210 + * operation, checking the signature. */
6211 +CK_PKCS11_FUNCTION_INFO(C_VerifyFinal)
6212 +#ifdef CK_NEED_ARG_LIST
6213 +(
6214 +  CK_SESSION_HANDLE hSession,       /* the session's handle */
6215 +  CK_BYTE_PTR       pSignature,     /* signature to verify */
6216 +  CK_ULONG          ulSignatureLen  /* signature length */
6217 +);
6218 +#endif
6219 +
6220 +
6221 +/* C_VerifyRecoverInit initializes a signature verification
6222 + * operation, where the data is recovered from the signature. */
6223 +CK_PKCS11_FUNCTION_INFO(C_VerifyRecoverInit)
6224 +#ifdef CK_NEED_ARG_LIST
6225 +(
6226 +  CK_SESSION_HANDLE hSession,    /* the session's handle */
6227 +  CK_MECHANISM_PTR  pMechanism,  /* the verification mechanism */
6228 +  CK_OBJECT_HANDLE  hKey         /* verification key */
6229 +);
6230 +#endif
6231 +
6232 +
6233 +/* C_VerifyRecover verifies a signature in a single-part
6234 + * operation, where the data is recovered from the signature. */
6235 +CK_PKCS11_FUNCTION_INFO(C_VerifyRecover)
6236 +#ifdef CK_NEED_ARG_LIST
6237 +(
6238 +  CK_SESSION_HANDLE hSession,        /* the session's handle */
6239 +  CK_BYTE_PTR       pSignature,      /* signature to verify */
6240 +  CK_ULONG          ulSignatureLen,  /* signature length */
6241 +  CK_BYTE_PTR       pData,           /* gets signed data */
6242 +  CK_ULONG_PTR      pulDataLen       /* gets signed data len */
6243 +);
6244 +#endif
6245 +
6246 +
6247 +
6248 +/* Dual-function cryptographic operations */
6249 +
6250 +/* C_DigestEncryptUpdate continues a multiple-part digesting
6251 + * and encryption operation. */
6252 +CK_PKCS11_FUNCTION_INFO(C_DigestEncryptUpdate)
6253 +#ifdef CK_NEED_ARG_LIST
6254 +(
6255 +  CK_SESSION_HANDLE hSession,            /* session's handle */
6256 +  CK_BYTE_PTR       pPart,               /* the plaintext data */
6257 +  CK_ULONG          ulPartLen,           /* plaintext length */
6258 +  CK_BYTE_PTR       pEncryptedPart,      /* gets ciphertext */
6259 +  CK_ULONG_PTR      pulEncryptedPartLen  /* gets c-text length */
6260 +);
6261 +#endif
6262 +
6263 +
6264 +/* C_DecryptDigestUpdate continues a multiple-part decryption and
6265 + * digesting operation. */
6266 +CK_PKCS11_FUNCTION_INFO(C_DecryptDigestUpdate)
6267 +#ifdef CK_NEED_ARG_LIST
6268 +(
6269 +  CK_SESSION_HANDLE hSession,            /* session's handle */
6270 +  CK_BYTE_PTR       pEncryptedPart,      /* ciphertext */
6271 +  CK_ULONG          ulEncryptedPartLen,  /* ciphertext length */
6272 +  CK_BYTE_PTR       pPart,               /* gets plaintext */
6273 +  CK_ULONG_PTR      pulPartLen           /* gets plaintext len */
6274 +);
6275 +#endif
6276 +
6277 +
6278 +/* C_SignEncryptUpdate continues a multiple-part signing and
6279 + * encryption operation. */
6280 +CK_PKCS11_FUNCTION_INFO(C_SignEncryptUpdate)
6281 +#ifdef CK_NEED_ARG_LIST
6282 +(
6283 +  CK_SESSION_HANDLE hSession,            /* session's handle */
6284 +  CK_BYTE_PTR       pPart,               /* the plaintext data */
6285 +  CK_ULONG          ulPartLen,           /* plaintext length */
6286 +  CK_BYTE_PTR       pEncryptedPart,      /* gets ciphertext */
6287 +  CK_ULONG_PTR      pulEncryptedPartLen  /* gets c-text length */
6288 +);
6289 +#endif
6290 +
6291 +
6292 +/* C_DecryptVerifyUpdate continues a multiple-part decryption and
6293 + * verify operation. */
6294 +CK_PKCS11_FUNCTION_INFO(C_DecryptVerifyUpdate)
6295 +#ifdef CK_NEED_ARG_LIST
6296 +(
6297 +  CK_SESSION_HANDLE hSession,            /* session's handle */
6298 +  CK_BYTE_PTR       pEncryptedPart,      /* ciphertext */
6299 +  CK_ULONG          ulEncryptedPartLen,  /* ciphertext length */
6300 +  CK_BYTE_PTR       pPart,               /* gets plaintext */
6301 +  CK_ULONG_PTR      pulPartLen           /* gets p-text length */
6302 +);
6303 +#endif
6304 +
6305 +
6306 +
6307 +/* Key management */
6308 +
6309 +/* C_GenerateKey generates a secret key, creating a new key
6310 + * object. */
6311 +CK_PKCS11_FUNCTION_INFO(C_GenerateKey)
6312 +#ifdef CK_NEED_ARG_LIST
6313 +(
6314 +  CK_SESSION_HANDLE    hSession,    /* the session's handle */
6315 +  CK_MECHANISM_PTR     pMechanism,  /* key generation mech. */
6316 +  CK_ATTRIBUTE_PTR     pTemplate,   /* template for new key */
6317 +  CK_ULONG             ulCount,     /* # of attrs in template */
6318 +  CK_OBJECT_HANDLE_PTR phKey        /* gets handle of new key */
6319 +);
6320 +#endif
6321 +
6322 +
6323 +/* C_GenerateKeyPair generates a public-key/private-key pair, 
6324 + * creating new key objects. */
6325 +CK_PKCS11_FUNCTION_INFO(C_GenerateKeyPair)
6326 +#ifdef CK_NEED_ARG_LIST
6327 +(
6328 +  CK_SESSION_HANDLE    hSession,                    /* session
6329 +                                                     * handle */
6330 +  CK_MECHANISM_PTR     pMechanism,                  /* key-gen
6331 +                                                     * mech. */
6332 +  CK_ATTRIBUTE_PTR     pPublicKeyTemplate,          /* template
6333 +                                                     * for pub.
6334 +                                                     * key */
6335 +  CK_ULONG             ulPublicKeyAttributeCount,   /* # pub.
6336 +                                                     * attrs. */
6337 +  CK_ATTRIBUTE_PTR     pPrivateKeyTemplate,         /* template
6338 +                                                     * for priv.
6339 +                                                     * key */
6340 +  CK_ULONG             ulPrivateKeyAttributeCount,  /* # priv.
6341 +                                                     * attrs. */
6342 +  CK_OBJECT_HANDLE_PTR phPublicKey,                 /* gets pub.
6343 +                                                     * key
6344 +                                                     * handle */
6345 +  CK_OBJECT_HANDLE_PTR phPrivateKey                 /* gets
6346 +                                                     * priv. key
6347 +                                                     * handle */
6348 +);
6349 +#endif
6350 +
6351 +
6352 +/* C_WrapKey wraps (i.e., encrypts) a key. */
6353 +CK_PKCS11_FUNCTION_INFO(C_WrapKey)
6354 +#ifdef CK_NEED_ARG_LIST
6355 +(
6356 +  CK_SESSION_HANDLE hSession,        /* the session's handle */
6357 +  CK_MECHANISM_PTR  pMechanism,      /* the wrapping mechanism */
6358 +  CK_OBJECT_HANDLE  hWrappingKey,    /* wrapping key */
6359 +  CK_OBJECT_HANDLE  hKey,            /* key to be wrapped */
6360 +  CK_BYTE_PTR       pWrappedKey,     /* gets wrapped key */
6361 +  CK_ULONG_PTR      pulWrappedKeyLen /* gets wrapped key size */
6362 +);
6363 +#endif
6364 +
6365 +
6366 +/* C_UnwrapKey unwraps (decrypts) a wrapped key, creating a new
6367 + * key object. */
6368 +CK_PKCS11_FUNCTION_INFO(C_UnwrapKey)
6369 +#ifdef CK_NEED_ARG_LIST
6370 +(
6371 +  CK_SESSION_HANDLE    hSession,          /* session's handle */
6372 +  CK_MECHANISM_PTR     pMechanism,        /* unwrapping mech. */
6373 +  CK_OBJECT_HANDLE     hUnwrappingKey,    /* unwrapping key */
6374 +  CK_BYTE_PTR          pWrappedKey,       /* the wrapped key */
6375 +  CK_ULONG             ulWrappedKeyLen,   /* wrapped key len */
6376 +  CK_ATTRIBUTE_PTR     pTemplate,         /* new key template */
6377 +  CK_ULONG             ulAttributeCount,  /* template length */
6378 +  CK_OBJECT_HANDLE_PTR phKey              /* gets new handle */
6379 +);
6380 +#endif
6381 +
6382 +
6383 +/* C_DeriveKey derives a key from a base key, creating a new key
6384 + * object. */
6385 +CK_PKCS11_FUNCTION_INFO(C_DeriveKey)
6386 +#ifdef CK_NEED_ARG_LIST
6387 +(
6388 +  CK_SESSION_HANDLE    hSession,          /* session's handle */
6389 +  CK_MECHANISM_PTR     pMechanism,        /* key deriv. mech. */
6390 +  CK_OBJECT_HANDLE     hBaseKey,          /* base key */
6391 +  CK_ATTRIBUTE_PTR     pTemplate,         /* new key template */
6392 +  CK_ULONG             ulAttributeCount,  /* template length */
6393 +  CK_OBJECT_HANDLE_PTR phKey              /* gets new handle */
6394 +);
6395 +#endif
6396 +
6397 +
6398 +
6399 +/* Random number generation */
6400 +
6401 +/* C_SeedRandom mixes additional seed material into the token's
6402 + * random number generator. */
6403 +CK_PKCS11_FUNCTION_INFO(C_SeedRandom)
6404 +#ifdef CK_NEED_ARG_LIST
6405 +(
6406 +  CK_SESSION_HANDLE hSession,  /* the session's handle */
6407 +  CK_BYTE_PTR       pSeed,     /* the seed material */
6408 +  CK_ULONG          ulSeedLen  /* length of seed material */
6409 +);
6410 +#endif
6411 +
6412 +
6413 +/* C_GenerateRandom generates random data. */
6414 +CK_PKCS11_FUNCTION_INFO(C_GenerateRandom)
6415 +#ifdef CK_NEED_ARG_LIST
6416 +(
6417 +  CK_SESSION_HANDLE hSession,    /* the session's handle */
6418 +  CK_BYTE_PTR       RandomData,  /* receives the random data */
6419 +  CK_ULONG          ulRandomLen  /* # of bytes to generate */
6420 +);
6421 +#endif
6422 +
6423 +
6424 +
6425 +/* Parallel function management */
6426 +
6427 +/* C_GetFunctionStatus is a legacy function; it obtains an
6428 + * updated status of a function running in parallel with an
6429 + * application. */
6430 +CK_PKCS11_FUNCTION_INFO(C_GetFunctionStatus)
6431 +#ifdef CK_NEED_ARG_LIST
6432 +(
6433 +  CK_SESSION_HANDLE hSession  /* the session's handle */
6434 +);
6435 +#endif
6436 +
6437 +
6438 +/* C_CancelFunction is a legacy function; it cancels a function
6439 + * running in parallel. */
6440 +CK_PKCS11_FUNCTION_INFO(C_CancelFunction)
6441 +#ifdef CK_NEED_ARG_LIST
6442 +(
6443 +  CK_SESSION_HANDLE hSession  /* the session's handle */
6444 +);
6445 +#endif
6446 +
6447 +
6448 +
6449 +/* Functions added in for Cryptoki Version 2.01 or later */
6450 +
6451 +/* C_WaitForSlotEvent waits for a slot event (token insertion,
6452 + * removal, etc.) to occur. */
6453 +CK_PKCS11_FUNCTION_INFO(C_WaitForSlotEvent)
6454 +#ifdef CK_NEED_ARG_LIST
6455 +(
6456 +  CK_FLAGS flags,        /* blocking/nonblocking flag */
6457 +  CK_SLOT_ID_PTR pSlot,  /* location that receives the slot ID */
6458 +  CK_VOID_PTR pRserved   /* reserved.  Should be NULL_PTR */
6459 +);
6460 +#endif
6461 diff -r -u -N openssl-0.9.8g/crypto/engine/pkcs11.h openssl/crypto/engine/pkcs11.h
6462 --- openssl-0.9.8g/crypto/engine/pkcs11.h       1970-01-01 01:00:00.000000000 +0100
6463 +++ openssl/crypto/engine/pkcs11.h      2007-10-25 01:27:09.000000000 +0200
6464 @@ -0,0 +1,299 @@
6465 +/* pkcs11.h include file for PKCS #11. */
6466 +/* $Revision: 1.2 $ */
6467 +
6468 +/* License to copy and use this software is granted provided that it is
6469 + * identified as "RSA Security Inc. PKCS #11 Cryptographic Token Interface
6470 + * (Cryptoki)" in all material mentioning or referencing this software.
6471 +
6472 + * License is also granted to make and use derivative works provided that
6473 + * such works are identified as "derived from the RSA Security Inc. PKCS #11
6474 + * Cryptographic Token Interface (Cryptoki)" in all material mentioning or 
6475 + * referencing the derived work.
6476 +
6477 + * RSA Security Inc. makes no representations concerning either the 
6478 + * merchantability of this software or the suitability of this software for
6479 + * any particular purpose. It is provided "as is" without express or implied
6480 + * warranty of any kind.
6481 + */
6482 +
6483 +#ifndef _PKCS11_H_
6484 +#define _PKCS11_H_ 1
6485 +
6486 +#ifdef __cplusplus
6487 +extern "C" {
6488 +#endif
6489 +
6490 +/* Before including this file (pkcs11.h) (or pkcs11t.h by
6491 + * itself), 6 platform-specific macros must be defined.  These
6492 + * macros are described below, and typical definitions for them
6493 + * are also given.  Be advised that these definitions can depend
6494 + * on both the platform and the compiler used (and possibly also
6495 + * on whether a Cryptoki library is linked statically or
6496 + * dynamically).
6497 + *
6498 + * In addition to defining these 6 macros, the packing convention
6499 + * for Cryptoki structures should be set.  The Cryptoki
6500 + * convention on packing is that structures should be 1-byte
6501 + * aligned.
6502 + *
6503 + * If you're using Microsoft Developer Studio 5.0 to produce
6504 + * Win32 stuff, this might be done by using the following
6505 + * preprocessor directive before including pkcs11.h or pkcs11t.h:
6506 + *
6507 + * #pragma pack(push, cryptoki, 1)
6508 + *
6509 + * and using the following preprocessor directive after including
6510 + * pkcs11.h or pkcs11t.h:
6511 + *
6512 + * #pragma pack(pop, cryptoki)
6513 + *
6514 + * If you're using an earlier version of Microsoft Developer
6515 + * Studio to produce Win16 stuff, this might be done by using
6516 + * the following preprocessor directive before including
6517 + * pkcs11.h or pkcs11t.h:
6518 + *
6519 + * #pragma pack(1)
6520 + *
6521 + * In a UNIX environment, you're on your own for this.  You might
6522 + * not need to do (or be able to do!) anything.
6523 + *
6524 + *
6525 + * Now for the macros:
6526 + *
6527 + *
6528 + * 1. CK_PTR: The indirection string for making a pointer to an
6529 + * object.  It can be used like this:
6530 + *
6531 + * typedef CK_BYTE CK_PTR CK_BYTE_PTR;
6532 + *
6533 + * If you're using Microsoft Developer Studio 5.0 to produce
6534 + * Win32 stuff, it might be defined by:
6535 + *
6536 + * #define CK_PTR *
6537 + *
6538 + * If you're using an earlier version of Microsoft Developer
6539 + * Studio to produce Win16 stuff, it might be defined by:
6540 + *
6541 + * #define CK_PTR far *
6542 + *
6543 + * In a typical UNIX environment, it might be defined by:
6544 + *
6545 + * #define CK_PTR *
6546 + *
6547 + *
6548 + * 2. CK_DEFINE_FUNCTION(returnType, name): A macro which makes
6549 + * an exportable Cryptoki library function definition out of a
6550 + * return type and a function name.  It should be used in the
6551 + * following fashion to define the exposed Cryptoki functions in
6552 + * a Cryptoki library:
6553 + *
6554 + * CK_DEFINE_FUNCTION(CK_RV, C_Initialize)(
6555 + *   CK_VOID_PTR pReserved
6556 + * )
6557 + * {
6558 + *   ...
6559 + * }
6560 + *
6561 + * If you're using Microsoft Developer Studio 5.0 to define a
6562 + * function in a Win32 Cryptoki .dll, it might be defined by:
6563 + *
6564 + * #define CK_DEFINE_FUNCTION(returnType, name) \
6565 + *   returnType __declspec(dllexport) name
6566 + *
6567 + * If you're using an earlier version of Microsoft Developer
6568 + * Studio to define a function in a Win16 Cryptoki .dll, it
6569 + * might be defined by:
6570 + *
6571 + * #define CK_DEFINE_FUNCTION(returnType, name) \
6572 + *   returnType __export _far _pascal name
6573 + *
6574 + * In a UNIX environment, it might be defined by:
6575 + *
6576 + * #define CK_DEFINE_FUNCTION(returnType, name) \
6577 + *   returnType name
6578 + *
6579 + *
6580 + * 3. CK_DECLARE_FUNCTION(returnType, name): A macro which makes
6581 + * an importable Cryptoki library function declaration out of a
6582 + * return type and a function name.  It should be used in the
6583 + * following fashion:
6584 + *
6585 + * extern CK_DECLARE_FUNCTION(CK_RV, C_Initialize)(
6586 + *   CK_VOID_PTR pReserved
6587 + * );
6588 + *
6589 + * If you're using Microsoft Developer Studio 5.0 to declare a
6590 + * function in a Win32 Cryptoki .dll, it might be defined by:
6591 + *
6592 + * #define CK_DECLARE_FUNCTION(returnType, name) \
6593 + *   returnType __declspec(dllimport) name
6594 + *
6595 + * If you're using an earlier version of Microsoft Developer
6596 + * Studio to declare a function in a Win16 Cryptoki .dll, it
6597 + * might be defined by:
6598 + *
6599 + * #define CK_DECLARE_FUNCTION(returnType, name) \
6600 + *   returnType __export _far _pascal name
6601 + *
6602 + * In a UNIX environment, it might be defined by:
6603 + *
6604 + * #define CK_DECLARE_FUNCTION(returnType, name) \
6605 + *   returnType name
6606 + *
6607 + *
6608 + * 4. CK_DECLARE_FUNCTION_POINTER(returnType, name): A macro
6609 + * which makes a Cryptoki API function pointer declaration or
6610 + * function pointer type declaration out of a return type and a
6611 + * function name.  It should be used in the following fashion:
6612 + *
6613 + * // Define funcPtr to be a pointer to a Cryptoki API function
6614 + * // taking arguments args and returning CK_RV.
6615 + * CK_DECLARE_FUNCTION_POINTER(CK_RV, funcPtr)(args);
6616 + *
6617 + * or
6618 + *
6619 + * // Define funcPtrType to be the type of a pointer to a
6620 + * // Cryptoki API function taking arguments args and returning
6621 + * // CK_RV, and then define funcPtr to be a variable of type
6622 + * // funcPtrType.
6623 + * typedef CK_DECLARE_FUNCTION_POINTER(CK_RV, funcPtrType)(args);
6624 + * funcPtrType funcPtr;
6625 + *
6626 + * If you're using Microsoft Developer Studio 5.0 to access
6627 + * functions in a Win32 Cryptoki .dll, in might be defined by:
6628 + *
6629 + * #define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
6630 + *   returnType __declspec(dllimport) (* name)
6631 + *
6632 + * If you're using an earlier version of Microsoft Developer
6633 + * Studio to access functions in a Win16 Cryptoki .dll, it might
6634 + * be defined by:
6635 + *
6636 + * #define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
6637 + *   returnType __export _far _pascal (* name)
6638 + *
6639 + * In a UNIX environment, it might be defined by:
6640 + *
6641 + * #define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
6642 + *   returnType (* name)
6643 + *
6644 + *
6645 + * 5. CK_CALLBACK_FUNCTION(returnType, name): A macro which makes
6646 + * a function pointer type for an application callback out of
6647 + * a return type for the callback and a name for the callback.
6648 + * It should be used in the following fashion:
6649 + *
6650 + * CK_CALLBACK_FUNCTION(CK_RV, myCallback)(args);
6651 + *
6652 + * to declare a function pointer, myCallback, to a callback
6653 + * which takes arguments args and returns a CK_RV.  It can also
6654 + * be used like this:
6655 + *
6656 + * typedef CK_CALLBACK_FUNCTION(CK_RV, myCallbackType)(args);
6657 + * myCallbackType myCallback;
6658 + *
6659 + * If you're using Microsoft Developer Studio 5.0 to do Win32
6660 + * Cryptoki development, it might be defined by:
6661 + *
6662 + * #define CK_CALLBACK_FUNCTION(returnType, name) \
6663 + *   returnType (* name)
6664 + *
6665 + * If you're using an earlier version of Microsoft Developer
6666 + * Studio to do Win16 development, it might be defined by:
6667 + *
6668 + * #define CK_CALLBACK_FUNCTION(returnType, name) \
6669 + *   returnType _far _pascal (* name)
6670 + *
6671 + * In a UNIX environment, it might be defined by:
6672 + *
6673 + * #define CK_CALLBACK_FUNCTION(returnType, name) \
6674 + *   returnType (* name)
6675 + *
6676 + *
6677 + * 6. NULL_PTR: This macro is the value of a NULL pointer.
6678 + *
6679 + * In any ANSI/ISO C environment (and in many others as well),
6680 + * this should best be defined by
6681 + *
6682 + * #ifndef NULL_PTR
6683 + * #define NULL_PTR 0
6684 + * #endif
6685 + */
6686 +
6687 +
6688 +/* All the various Cryptoki types and #define'd values are in the
6689 + * file pkcs11t.h. */
6690 +#include "pkcs11t.h"
6691 +
6692 +#define __PASTE(x,y)      x##y
6693 +
6694 +
6695 +/* ==============================================================
6696 + * Define the "extern" form of all the entry points.
6697 + * ==============================================================
6698 + */
6699 +
6700 +#define CK_NEED_ARG_LIST  1
6701 +#define CK_PKCS11_FUNCTION_INFO(name) \
6702 +  extern CK_DECLARE_FUNCTION(CK_RV, name)
6703 +
6704 +/* pkcs11f.h has all the information about the Cryptoki
6705 + * function prototypes. */
6706 +#include "pkcs11f.h"
6707 +
6708 +#undef CK_NEED_ARG_LIST
6709 +#undef CK_PKCS11_FUNCTION_INFO
6710 +
6711 +
6712 +/* ==============================================================
6713 + * Define the typedef form of all the entry points.  That is, for
6714 + * each Cryptoki function C_XXX, define a type CK_C_XXX which is
6715 + * a pointer to that kind of function.
6716 + * ==============================================================
6717 + */
6718 +
6719 +#define CK_NEED_ARG_LIST  1
6720 +#define CK_PKCS11_FUNCTION_INFO(name) \
6721 +  typedef CK_DECLARE_FUNCTION_POINTER(CK_RV, __PASTE(CK_,name))
6722 +
6723 +/* pkcs11f.h has all the information about the Cryptoki
6724 + * function prototypes. */
6725 +#include "pkcs11f.h"
6726 +
6727 +#undef CK_NEED_ARG_LIST
6728 +#undef CK_PKCS11_FUNCTION_INFO
6729 +
6730 +
6731 +/* ==============================================================
6732 + * Define structed vector of entry points.  A CK_FUNCTION_LIST
6733 + * contains a CK_VERSION indicating a library's Cryptoki version
6734 + * and then a whole slew of function pointers to the routines in
6735 + * the library.  This type was declared, but not defined, in
6736 + * pkcs11t.h.
6737 + * ==============================================================
6738 + */
6739 +
6740 +#define CK_PKCS11_FUNCTION_INFO(name) \
6741 +  __PASTE(CK_,name) name;
6742 +  
6743 +struct CK_FUNCTION_LIST {
6744 +
6745 +  CK_VERSION    version;  /* Cryptoki version */
6746 +
6747 +/* Pile all the function pointers into the CK_FUNCTION_LIST. */
6748 +/* pkcs11f.h has all the information about the Cryptoki
6749 + * function prototypes. */
6750 +#include "pkcs11f.h"
6751 +
6752 +};
6753 +
6754 +#undef CK_PKCS11_FUNCTION_INFO
6755 +
6756 +
6757 +#undef __PASTE
6758 +
6759 +#ifdef __cplusplus
6760 +}
6761 +#endif
6762 +
6763 +#endif
6764 diff -r -u -N openssl-0.9.8g/crypto/engine/pkcs11t.h openssl/crypto/engine/pkcs11t.h
6765 --- openssl-0.9.8g/crypto/engine/pkcs11t.h      1970-01-01 01:00:00.000000000 +0100
6766 +++ openssl/crypto/engine/pkcs11t.h     2007-10-25 01:27:09.000000000 +0200
6767 @@ -0,0 +1,1685 @@
6768 +/* pkcs11t.h include file for PKCS #11. */\r
6769 +/* $Revision: 1.2 $ */\r
6770 +\r
6771 +/* License to copy and use this software is granted provided that it is
6772 + * identified as "RSA Security Inc. PKCS #11 Cryptographic Token Interface
6773 + * (Cryptoki)" in all material mentioning or referencing this software.
6774 +
6775 + * License is also granted to make and use derivative works provided that
6776 + * such works are identified as "derived from the RSA Security Inc. PKCS #11
6777 + * Cryptographic Token Interface (Cryptoki)" in all material mentioning or
6778 + * referencing the derived work.
6779 +
6780 + * RSA Security Inc. makes no representations concerning either the
6781 + * merchantability of this software or the suitability of this software for
6782 + * any particular purpose. It is provided "as is" without express or implied
6783 + * warranty of any kind.
6784 + */
6785 +
6786 +/* See top of pkcs11.h for information about the macros that
6787 + * must be defined and the structure-packing conventions that
6788 + * must be set before including this file. */
6789 +
6790 +#ifndef _PKCS11T_H_
6791 +#define _PKCS11T_H_ 1
6792 +
6793 +#define CK_TRUE 1
6794 +#define CK_FALSE 0
6795 +
6796 +#ifndef CK_DISABLE_TRUE_FALSE
6797 +#ifndef FALSE
6798 +#define FALSE CK_FALSE
6799 +#endif
6800 +
6801 +#ifndef TRUE
6802 +#define TRUE CK_TRUE
6803 +#endif
6804 +#endif
6805 +
6806 +/* an unsigned 8-bit value */
6807 +typedef unsigned char     CK_BYTE;
6808 +
6809 +/* an unsigned 8-bit character */
6810 +typedef CK_BYTE           CK_CHAR;
6811 +
6812 +/* an 8-bit UTF-8 character */
6813 +typedef CK_BYTE           CK_UTF8CHAR;
6814 +
6815 +/* a BYTE-sized Boolean flag */
6816 +typedef CK_BYTE           CK_BBOOL;
6817 +
6818 +/* an unsigned value, at least 32 bits long */
6819 +typedef unsigned long int CK_ULONG;
6820 +
6821 +/* a signed value, the same size as a CK_ULONG */
6822 +/* CK_LONG is new for v2.0 */
6823 +typedef long int          CK_LONG;
6824 +
6825 +/* at least 32 bits; each bit is a Boolean flag */
6826 +typedef CK_ULONG          CK_FLAGS;
6827 +
6828 +
6829 +/* some special values for certain CK_ULONG variables */
6830 +#define CK_UNAVAILABLE_INFORMATION (~0UL)
6831 +#define CK_EFFECTIVELY_INFINITE    0
6832 +
6833 +
6834 +typedef CK_BYTE     CK_PTR   CK_BYTE_PTR;
6835 +typedef CK_CHAR     CK_PTR   CK_CHAR_PTR;
6836 +typedef CK_UTF8CHAR CK_PTR   CK_UTF8CHAR_PTR;
6837 +typedef CK_ULONG    CK_PTR   CK_ULONG_PTR;
6838 +typedef void        CK_PTR   CK_VOID_PTR;
6839 +
6840 +/* Pointer to a CK_VOID_PTR-- i.e., pointer to pointer to void */
6841 +typedef CK_VOID_PTR CK_PTR CK_VOID_PTR_PTR;
6842 +
6843 +
6844 +/* The following value is always invalid if used as a session */
6845 +/* handle or object handle */
6846 +#define CK_INVALID_HANDLE 0
6847 +
6848 +
6849 +typedef struct CK_VERSION {
6850 +  CK_BYTE       major;  /* integer portion of version number */
6851 +  CK_BYTE       minor;  /* 1/100ths portion of version number */
6852 +} CK_VERSION;
6853 +
6854 +typedef CK_VERSION CK_PTR CK_VERSION_PTR;
6855 +
6856 +
6857 +typedef struct CK_INFO {
6858 +  /* manufacturerID and libraryDecription have been changed from
6859 +   * CK_CHAR to CK_UTF8CHAR for v2.10 */
6860 +  CK_VERSION    cryptokiVersion;     /* Cryptoki interface ver */
6861 +  CK_UTF8CHAR   manufacturerID[32];  /* blank padded */
6862 +  CK_FLAGS      flags;               /* must be zero */
6863 +
6864 +  /* libraryDescription and libraryVersion are new for v2.0 */
6865 +  CK_UTF8CHAR   libraryDescription[32];  /* blank padded */
6866 +  CK_VERSION    libraryVersion;          /* version of library */
6867 +} CK_INFO;
6868 +
6869 +typedef CK_INFO CK_PTR    CK_INFO_PTR;
6870 +
6871 +
6872 +/* CK_NOTIFICATION enumerates the types of notifications that
6873 + * Cryptoki provides to an application */
6874 +/* CK_NOTIFICATION has been changed from an enum to a CK_ULONG
6875 + * for v2.0 */
6876 +typedef CK_ULONG CK_NOTIFICATION;
6877 +#define CKN_SURRENDER       0
6878 +
6879 +
6880 +typedef CK_ULONG          CK_SLOT_ID;
6881 +
6882 +typedef CK_SLOT_ID CK_PTR CK_SLOT_ID_PTR;
6883 +
6884 +
6885 +/* CK_SLOT_INFO provides information about a slot */
6886 +typedef struct CK_SLOT_INFO {
6887 +  /* slotDescription and manufacturerID have been changed from
6888 +   * CK_CHAR to CK_UTF8CHAR for v2.10 */
6889 +  CK_UTF8CHAR   slotDescription[64];  /* blank padded */
6890 +  CK_UTF8CHAR   manufacturerID[32];   /* blank padded */
6891 +  CK_FLAGS      flags;
6892 +
6893 +  /* hardwareVersion and firmwareVersion are new for v2.0 */
6894 +  CK_VERSION    hardwareVersion;  /* version of hardware */
6895 +  CK_VERSION    firmwareVersion;  /* version of firmware */
6896 +} CK_SLOT_INFO;
6897 +
6898 +/* flags: bit flags that provide capabilities of the slot
6899 + *      Bit Flag              Mask        Meaning
6900 + */
6901 +#define CKF_TOKEN_PRESENT     0x00000001  /* a token is there */
6902 +#define CKF_REMOVABLE_DEVICE  0x00000002  /* removable devices*/
6903 +#define CKF_HW_SLOT           0x00000004  /* hardware slot */
6904 +
6905 +typedef CK_SLOT_INFO CK_PTR CK_SLOT_INFO_PTR;
6906 +
6907 +
6908 +/* CK_TOKEN_INFO provides information about a token */
6909 +typedef struct CK_TOKEN_INFO {
6910 +  /* label, manufacturerID, and model have been changed from
6911 +   * CK_CHAR to CK_UTF8CHAR for v2.10 */
6912 +  CK_UTF8CHAR   label[32];           /* blank padded */
6913 +  CK_UTF8CHAR   manufacturerID[32];  /* blank padded */
6914 +  CK_UTF8CHAR   model[16];           /* blank padded */
6915 +  CK_CHAR       serialNumber[16];    /* blank padded */
6916 +  CK_FLAGS      flags;               /* see below */
6917 +
6918 +  /* ulMaxSessionCount, ulSessionCount, ulMaxRwSessionCount,
6919 +   * ulRwSessionCount, ulMaxPinLen, and ulMinPinLen have all been
6920 +   * changed from CK_USHORT to CK_ULONG for v2.0 */
6921 +  CK_ULONG      ulMaxSessionCount;     /* max open sessions */
6922 +  CK_ULONG      ulSessionCount;        /* sess. now open */
6923 +  CK_ULONG      ulMaxRwSessionCount;   /* max R/W sessions */
6924 +  CK_ULONG      ulRwSessionCount;      /* R/W sess. now open */
6925 +  CK_ULONG      ulMaxPinLen;           /* in bytes */
6926 +  CK_ULONG      ulMinPinLen;           /* in bytes */
6927 +  CK_ULONG      ulTotalPublicMemory;   /* in bytes */
6928 +  CK_ULONG      ulFreePublicMemory;    /* in bytes */
6929 +  CK_ULONG      ulTotalPrivateMemory;  /* in bytes */
6930 +  CK_ULONG      ulFreePrivateMemory;   /* in bytes */
6931 +
6932 +  /* hardwareVersion, firmwareVersion, and time are new for
6933 +   * v2.0 */
6934 +  CK_VERSION    hardwareVersion;       /* version of hardware */
6935 +  CK_VERSION    firmwareVersion;       /* version of firmware */
6936 +  CK_CHAR       utcTime[16];           /* time */
6937 +} CK_TOKEN_INFO;
6938 +
6939 +/* The flags parameter is defined as follows:
6940 + *      Bit Flag                    Mask        Meaning
6941 + */
6942 +#define CKF_RNG                     0x00000001  /* has random #
6943 +                                                 * generator */
6944 +#define CKF_WRITE_PROTECTED         0x00000002  /* token is
6945 +                                                 * write-
6946 +                                                 * protected */
6947 +#define CKF_LOGIN_REQUIRED          0x00000004  /* user must
6948 +                                                 * login */
6949 +#define CKF_USER_PIN_INITIALIZED    0x00000008  /* normal user's
6950 +                                                 * PIN is set */
6951 +
6952 +/* CKF_RESTORE_KEY_NOT_NEEDED is new for v2.0.  If it is set,
6953 + * that means that *every* time the state of cryptographic
6954 + * operations of a session is successfully saved, all keys
6955 + * needed to continue those operations are stored in the state */
6956 +#define CKF_RESTORE_KEY_NOT_NEEDED  0x00000020
6957 +
6958 +/* CKF_CLOCK_ON_TOKEN is new for v2.0.  If it is set, that means
6959 + * that the token has some sort of clock.  The time on that
6960 + * clock is returned in the token info structure */
6961 +#define CKF_CLOCK_ON_TOKEN          0x00000040
6962 +
6963 +/* CKF_PROTECTED_AUTHENTICATION_PATH is new for v2.0.  If it is
6964 + * set, that means that there is some way for the user to login
6965 + * without sending a PIN through the Cryptoki library itself */
6966 +#define CKF_PROTECTED_AUTHENTICATION_PATH 0x00000100
6967 +
6968 +/* CKF_DUAL_CRYPTO_OPERATIONS is new for v2.0.  If it is true,
6969 + * that means that a single session with the token can perform
6970 + * dual simultaneous cryptographic operations (digest and
6971 + * encrypt; decrypt and digest; sign and encrypt; and decrypt
6972 + * and sign) */
6973 +#define CKF_DUAL_CRYPTO_OPERATIONS  0x00000200
6974 +
6975 +/* CKF_TOKEN_INITIALIZED if new for v2.10. If it is true, the
6976 + * token has been initialized using C_InitializeToken or an
6977 + * equivalent mechanism outside the scope of PKCS #11.
6978 + * Calling C_InitializeToken when this flag is set will cause
6979 + * the token to be reinitialized. */
6980 +#define CKF_TOKEN_INITIALIZED       0x00000400
6981 +
6982 +/* CKF_SECONDARY_AUTHENTICATION if new for v2.10. If it is
6983 + * true, the token supports secondary authentication for
6984 + * private key objects. This flag is deprecated in v2.11 and
6985 +   onwards. */
6986 +#define CKF_SECONDARY_AUTHENTICATION  0x00000800
6987 +
6988 +/* CKF_USER_PIN_COUNT_LOW if new for v2.10. If it is true, an
6989 + * incorrect user login PIN has been entered at least once
6990 + * since the last successful authentication. */
6991 +#define CKF_USER_PIN_COUNT_LOW       0x00010000
6992 +
6993 +/* CKF_USER_PIN_FINAL_TRY if new for v2.10. If it is true,
6994 + * supplying an incorrect user PIN will it to become locked. */
6995 +#define CKF_USER_PIN_FINAL_TRY       0x00020000
6996 +
6997 +/* CKF_USER_PIN_LOCKED if new for v2.10. If it is true, the
6998 + * user PIN has been locked. User login to the token is not
6999 + * possible. */
7000 +#define CKF_USER_PIN_LOCKED          0x00040000
7001 +
7002 +/* CKF_USER_PIN_TO_BE_CHANGED if new for v2.10. If it is true,
7003 + * the user PIN value is the default value set by token
7004 + * initialization or manufacturing, or the PIN has been
7005 + * expired by the card. */
7006 +#define CKF_USER_PIN_TO_BE_CHANGED   0x00080000
7007 +
7008 +/* CKF_SO_PIN_COUNT_LOW if new for v2.10. If it is true, an
7009 + * incorrect SO login PIN has been entered at least once since
7010 + * the last successful authentication. */
7011 +#define CKF_SO_PIN_COUNT_LOW         0x00100000
7012 +
7013 +/* CKF_SO_PIN_FINAL_TRY if new for v2.10. If it is true,
7014 + * supplying an incorrect SO PIN will it to become locked. */
7015 +#define CKF_SO_PIN_FINAL_TRY         0x00200000
7016 +
7017 +/* CKF_SO_PIN_LOCKED if new for v2.10. If it is true, the SO
7018 + * PIN has been locked. SO login to the token is not possible.
7019 + */
7020 +#define CKF_SO_PIN_LOCKED            0x00400000
7021 +
7022 +/* CKF_SO_PIN_TO_BE_CHANGED if new for v2.10. If it is true,
7023 + * the SO PIN value is the default value set by token
7024 + * initialization or manufacturing, or the PIN has been
7025 + * expired by the card. */
7026 +#define CKF_SO_PIN_TO_BE_CHANGED     0x00800000
7027 +
7028 +typedef CK_TOKEN_INFO CK_PTR CK_TOKEN_INFO_PTR;
7029 +
7030 +
7031 +/* CK_SESSION_HANDLE is a Cryptoki-assigned value that
7032 + * identifies a session */
7033 +typedef CK_ULONG          CK_SESSION_HANDLE;
7034 +
7035 +typedef CK_SESSION_HANDLE CK_PTR CK_SESSION_HANDLE_PTR;
7036 +
7037 +
7038 +/* CK_USER_TYPE enumerates the types of Cryptoki users */
7039 +/* CK_USER_TYPE has been changed from an enum to a CK_ULONG for
7040 + * v2.0 */
7041 +typedef CK_ULONG          CK_USER_TYPE;
7042 +/* Security Officer */
7043 +#define CKU_SO    0
7044 +/* Normal user */
7045 +#define CKU_USER  1
7046 +/* Context specific (added in v2.20) */
7047 +#define CKU_CONTEXT_SPECIFIC   2
7048 +
7049 +/* CK_STATE enumerates the session states */
7050 +/* CK_STATE has been changed from an enum to a CK_ULONG for
7051 + * v2.0 */
7052 +typedef CK_ULONG          CK_STATE;
7053 +#define CKS_RO_PUBLIC_SESSION  0
7054 +#define CKS_RO_USER_FUNCTIONS  1
7055 +#define CKS_RW_PUBLIC_SESSION  2
7056 +#define CKS_RW_USER_FUNCTIONS  3
7057 +#define CKS_RW_SO_FUNCTIONS    4
7058 +
7059 +
7060 +/* CK_SESSION_INFO provides information about a session */
7061 +typedef struct CK_SESSION_INFO {
7062 +  CK_SLOT_ID    slotID;
7063 +  CK_STATE      state;
7064 +  CK_FLAGS      flags;          /* see below */
7065 +
7066 +  /* ulDeviceError was changed from CK_USHORT to CK_ULONG for
7067 +   * v2.0 */
7068 +  CK_ULONG      ulDeviceError;  /* device-dependent error code */
7069 +} CK_SESSION_INFO;
7070 +
7071 +/* The flags are defined in the following table:
7072 + *      Bit Flag                Mask        Meaning
7073 + */
7074 +#define CKF_RW_SESSION          0x00000002  /* session is r/w */
7075 +#define CKF_SERIAL_SESSION      0x00000004  /* no parallel */
7076 +
7077 +typedef CK_SESSION_INFO CK_PTR CK_SESSION_INFO_PTR;
7078 +
7079 +
7080 +/* CK_OBJECT_HANDLE is a token-specific identifier for an
7081 + * object  */
7082 +typedef CK_ULONG          CK_OBJECT_HANDLE;
7083 +
7084 +typedef CK_OBJECT_HANDLE CK_PTR CK_OBJECT_HANDLE_PTR;
7085 +
7086 +
7087 +/* CK_OBJECT_CLASS is a value that identifies the classes (or
7088 + * types) of objects that Cryptoki recognizes.  It is defined
7089 + * as follows: */
7090 +/* CK_OBJECT_CLASS was changed from CK_USHORT to CK_ULONG for
7091 + * v2.0 */
7092 +typedef CK_ULONG          CK_OBJECT_CLASS;
7093 +
7094 +/* The following classes of objects are defined: */
7095 +/* CKO_HW_FEATURE is new for v2.10 */
7096 +/* CKO_DOMAIN_PARAMETERS is new for v2.11 */
7097 +/* CKO_MECHANISM is new for v2.20 */
7098 +#define CKO_DATA              0x00000000
7099 +#define CKO_CERTIFICATE       0x00000001
7100 +#define CKO_PUBLIC_KEY        0x00000002
7101 +#define CKO_PRIVATE_KEY       0x00000003
7102 +#define CKO_SECRET_KEY        0x00000004
7103 +#define CKO_HW_FEATURE        0x00000005
7104 +#define CKO_DOMAIN_PARAMETERS 0x00000006
7105 +#define CKO_MECHANISM         0x00000007
7106 +#define CKO_VENDOR_DEFINED    0x80000000
7107 +
7108 +typedef CK_OBJECT_CLASS CK_PTR CK_OBJECT_CLASS_PTR;
7109 +
7110 +/* CK_HW_FEATURE_TYPE is new for v2.10. CK_HW_FEATURE_TYPE is a
7111 + * value that identifies the hardware feature type of an object
7112 + * with CK_OBJECT_CLASS equal to CKO_HW_FEATURE. */
7113 +typedef CK_ULONG          CK_HW_FEATURE_TYPE;
7114 +
7115 +/* The following hardware feature types are defined */
7116 +/* CKH_USER_INTERFACE is new for v2.20 */
7117 +#define CKH_MONOTONIC_COUNTER  0x00000001
7118 +#define CKH_CLOCK           0x00000002
7119 +#define CKH_USER_INTERFACE  0x00000003
7120 +#define CKH_VENDOR_DEFINED  0x80000000
7121 +
7122 +/* CK_KEY_TYPE is a value that identifies a key type */
7123 +/* CK_KEY_TYPE was changed from CK_USHORT to CK_ULONG for v2.0 */
7124 +typedef CK_ULONG          CK_KEY_TYPE;
7125 +
7126 +/* the following key types are defined: */
7127 +#define CKK_RSA             0x00000000
7128 +#define CKK_DSA             0x00000001
7129 +#define CKK_DH              0x00000002
7130 +
7131 +/* CKK_ECDSA and CKK_KEA are new for v2.0 */
7132 +/* CKK_ECDSA is deprecated in v2.11, CKK_EC is preferred. */
7133 +#define CKK_ECDSA           0x00000003
7134 +#define CKK_EC              0x00000003
7135 +#define CKK_X9_42_DH        0x00000004
7136 +#define CKK_KEA             0x00000005
7137 +
7138 +#define CKK_GENERIC_SECRET  0x00000010
7139 +#define CKK_RC2             0x00000011
7140 +#define CKK_RC4             0x00000012
7141 +#define CKK_DES             0x00000013
7142 +#define CKK_DES2            0x00000014
7143 +#define CKK_DES3            0x00000015
7144 +
7145 +/* all these key types are new for v2.0 */
7146 +#define CKK_CAST            0x00000016
7147 +#define CKK_CAST3           0x00000017
7148 +/* CKK_CAST5 is deprecated in v2.11, CKK_CAST128 is preferred. */
7149 +#define CKK_CAST5           0x00000018
7150 +#define CKK_CAST128         0x00000018
7151 +#define CKK_RC5             0x00000019
7152 +#define CKK_IDEA            0x0000001A
7153 +#define CKK_SKIPJACK        0x0000001B
7154 +#define CKK_BATON           0x0000001C
7155 +#define CKK_JUNIPER         0x0000001D
7156 +#define CKK_CDMF            0x0000001E
7157 +#define CKK_AES             0x0000001F
7158 +
7159 +/* BlowFish and TwoFish are new for v2.20 */
7160 +#define CKK_BLOWFISH        0x00000020
7161 +#define CKK_TWOFISH         0x00000021
7162 +
7163 +#define CKK_VENDOR_DEFINED  0x80000000
7164 +
7165 +
7166 +/* CK_CERTIFICATE_TYPE is a value that identifies a certificate
7167 + * type */
7168 +/* CK_CERTIFICATE_TYPE was changed from CK_USHORT to CK_ULONG
7169 + * for v2.0 */
7170 +typedef CK_ULONG          CK_CERTIFICATE_TYPE;
7171 +
7172 +/* The following certificate types are defined: */
7173 +/* CKC_X_509_ATTR_CERT is new for v2.10 */
7174 +/* CKC_WTLS is new for v2.20 */
7175 +#define CKC_X_509           0x00000000
7176 +#define CKC_X_509_ATTR_CERT 0x00000001
7177 +#define CKC_WTLS            0x00000002
7178 +#define CKC_VENDOR_DEFINED  0x80000000
7179 +
7180 +
7181 +/* CK_ATTRIBUTE_TYPE is a value that identifies an attribute
7182 + * type */
7183 +/* CK_ATTRIBUTE_TYPE was changed from CK_USHORT to CK_ULONG for
7184 + * v2.0 */
7185 +typedef CK_ULONG          CK_ATTRIBUTE_TYPE;
7186 +
7187 +/* The CKF_ARRAY_ATTRIBUTE flag identifies an attribute which
7188 +   consists of an array of values. */
7189 +#define CKF_ARRAY_ATTRIBUTE    0x40000000
7190 +
7191 +/* The following attribute types are defined: */
7192 +#define CKA_CLASS              0x00000000
7193 +#define CKA_TOKEN              0x00000001
7194 +#define CKA_PRIVATE            0x00000002
7195 +#define CKA_LABEL              0x00000003
7196 +#define CKA_APPLICATION        0x00000010
7197 +#define CKA_VALUE              0x00000011
7198 +
7199 +/* CKA_OBJECT_ID is new for v2.10 */
7200 +#define CKA_OBJECT_ID          0x00000012
7201 +
7202 +#define CKA_CERTIFICATE_TYPE   0x00000080
7203 +#define CKA_ISSUER             0x00000081
7204 +#define CKA_SERIAL_NUMBER      0x00000082
7205 +
7206 +/* CKA_AC_ISSUER, CKA_OWNER, and CKA_ATTR_TYPES are new
7207 + * for v2.10 */
7208 +#define CKA_AC_ISSUER          0x00000083
7209 +#define CKA_OWNER              0x00000084
7210 +#define CKA_ATTR_TYPES         0x00000085
7211 +
7212 +/* CKA_TRUSTED is new for v2.11 */
7213 +#define CKA_TRUSTED            0x00000086
7214 +
7215 +/* CKA_CERTIFICATE_CATEGORY ...
7216 + * CKA_CHECK_VALUE are new for v2.20 */
7217 +#define CKA_CERTIFICATE_CATEGORY        0x00000087
7218 +#define CKA_JAVA_MIDP_SECURITY_DOMAIN   0x00000088
7219 +#define CKA_URL                         0x00000089
7220 +#define CKA_HASH_OF_SUBJECT_PUBLIC_KEY  0x0000008A
7221 +#define CKA_HASH_OF_ISSUER_PUBLIC_KEY   0x0000008B
7222 +#define CKA_CHECK_VALUE                 0x00000090
7223 +
7224 +#define CKA_KEY_TYPE           0x00000100
7225 +#define CKA_SUBJECT            0x00000101
7226 +#define CKA_ID                 0x00000102
7227 +#define CKA_SENSITIVE          0x00000103
7228 +#define CKA_ENCRYPT            0x00000104
7229 +#define CKA_DECRYPT            0x00000105
7230 +#define CKA_WRAP               0x00000106
7231 +#define CKA_UNWRAP             0x00000107
7232 +#define CKA_SIGN               0x00000108
7233 +#define CKA_SIGN_RECOVER       0x00000109
7234 +#define CKA_VERIFY             0x0000010A
7235 +#define CKA_VERIFY_RECOVER     0x0000010B
7236 +#define CKA_DERIVE             0x0000010C
7237 +#define CKA_START_DATE         0x00000110
7238 +#define CKA_END_DATE           0x00000111
7239 +#define CKA_MODULUS            0x00000120
7240 +#define CKA_MODULUS_BITS       0x00000121
7241 +#define CKA_PUBLIC_EXPONENT    0x00000122
7242 +#define CKA_PRIVATE_EXPONENT   0x00000123
7243 +#define CKA_PRIME_1            0x00000124
7244 +#define CKA_PRIME_2            0x00000125
7245 +#define CKA_EXPONENT_1         0x00000126
7246 +#define CKA_EXPONENT_2         0x00000127
7247 +#define CKA_COEFFICIENT        0x00000128
7248 +#define CKA_PRIME              0x00000130
7249 +#define CKA_SUBPRIME           0x00000131
7250 +#define CKA_BASE               0x00000132
7251 +
7252 +/* CKA_PRIME_BITS and CKA_SUB_PRIME_BITS are new for v2.11 */
7253 +#define CKA_PRIME_BITS         0x00000133
7254 +#define CKA_SUBPRIME_BITS      0x00000134
7255 +#define CKA_SUB_PRIME_BITS     CKA_SUBPRIME_BITS
7256 +/* (To retain backwards-compatibility) */
7257 +
7258 +#define CKA_VALUE_BITS         0x00000160
7259 +#define CKA_VALUE_LEN          0x00000161
7260 +
7261 +/* CKA_EXTRACTABLE, CKA_LOCAL, CKA_NEVER_EXTRACTABLE,
7262 + * CKA_ALWAYS_SENSITIVE, CKA_MODIFIABLE, CKA_ECDSA_PARAMS,
7263 + * and CKA_EC_POINT are new for v2.0 */
7264 +#define CKA_EXTRACTABLE        0x00000162
7265 +#define CKA_LOCAL              0x00000163
7266 +#define CKA_NEVER_EXTRACTABLE  0x00000164
7267 +#define CKA_ALWAYS_SENSITIVE   0x00000165
7268 +
7269 +/* CKA_KEY_GEN_MECHANISM is new for v2.11 */
7270 +#define CKA_KEY_GEN_MECHANISM  0x00000166
7271 +
7272 +#define CKA_MODIFIABLE         0x00000170
7273 +
7274 +/* CKA_ECDSA_PARAMS is deprecated in v2.11,
7275 + * CKA_EC_PARAMS is preferred. */
7276 +#define CKA_ECDSA_PARAMS       0x00000180
7277 +#define CKA_EC_PARAMS          0x00000180
7278 +
7279 +#define CKA_EC_POINT           0x00000181
7280 +
7281 +/* CKA_SECONDARY_AUTH, CKA_AUTH_PIN_FLAGS,
7282 + * are new for v2.10. Deprecated in v2.11 and onwards. */
7283 +#define CKA_SECONDARY_AUTH     0x00000200
7284 +#define CKA_AUTH_PIN_FLAGS     0x00000201
7285 +
7286 +/* CKA_ALWAYS_AUTHENTICATE ...
7287 + * CKA_UNWRAP_TEMPLATE are new for v2.20 */
7288 +#define CKA_ALWAYS_AUTHENTICATE  0x00000202
7289 +
7290 +#define CKA_WRAP_WITH_TRUSTED    0x00000210
7291 +#define CKA_WRAP_TEMPLATE        (CKF_ARRAY_ATTRIBUTE|0x00000211)
7292 +#define CKA_UNWRAP_TEMPLATE      (CKF_ARRAY_ATTRIBUTE|0x00000212)
7293 +
7294 +/* CKA_HW_FEATURE_TYPE, CKA_RESET_ON_INIT, and CKA_HAS_RESET
7295 + * are new for v2.10 */
7296 +#define CKA_HW_FEATURE_TYPE    0x00000300
7297 +#define CKA_RESET_ON_INIT      0x00000301
7298 +#define CKA_HAS_RESET          0x00000302
7299 +
7300 +/* The following attributes are new for v2.20 */
7301 +#define CKA_PIXEL_X                     0x00000400
7302 +#define CKA_PIXEL_Y                     0x00000401
7303 +#define CKA_RESOLUTION                  0x00000402
7304 +#define CKA_CHAR_ROWS                   0x00000403
7305 +#define CKA_CHAR_COLUMNS                0x00000404
7306 +#define CKA_COLOR                       0x00000405
7307 +#define CKA_BITS_PER_PIXEL              0x00000406
7308 +#define CKA_CHAR_SETS                   0x00000480
7309 +#define CKA_ENCODING_METHODS            0x00000481
7310 +#define CKA_MIME_TYPES                  0x00000482
7311 +#define CKA_MECHANISM_TYPE              0x00000500
7312 +#define CKA_REQUIRED_CMS_ATTRIBUTES     0x00000501
7313 +#define CKA_DEFAULT_CMS_ATTRIBUTES      0x00000502
7314 +#define CKA_SUPPORTED_CMS_ATTRIBUTES    0x00000503
7315 +#define CKA_ALLOWED_MECHANISMS          (CKF_ARRAY_ATTRIBUTE|0x00000600)
7316 +
7317 +#define CKA_VENDOR_DEFINED     0x80000000
7318 +
7319 +
7320 +/* CK_ATTRIBUTE is a structure that includes the type, length
7321 + * and value of an attribute */
7322 +typedef struct CK_ATTRIBUTE {
7323 +  CK_ATTRIBUTE_TYPE type;
7324 +  CK_VOID_PTR       pValue;
7325 +
7326 +  /* ulValueLen went from CK_USHORT to CK_ULONG for v2.0 */
7327 +  CK_ULONG          ulValueLen;  /* in bytes */
7328 +} CK_ATTRIBUTE;
7329 +
7330 +typedef CK_ATTRIBUTE CK_PTR CK_ATTRIBUTE_PTR;
7331 +
7332 +
7333 +/* CK_DATE is a structure that defines a date */
7334 +typedef struct CK_DATE{
7335 +  CK_CHAR       year[4];   /* the year ("1900" - "9999") */
7336 +  CK_CHAR       month[2];  /* the month ("01" - "12") */
7337 +  CK_CHAR       day[2];    /* the day   ("01" - "31") */
7338 +} CK_DATE;
7339 +
7340 +
7341 +/* CK_MECHANISM_TYPE is a value that identifies a mechanism
7342 + * type */
7343 +/* CK_MECHANISM_TYPE was changed from CK_USHORT to CK_ULONG for
7344 + * v2.0 */
7345 +typedef CK_ULONG          CK_MECHANISM_TYPE;
7346 +
7347 +/* the following mechanism types are defined: */
7348 +#define CKM_RSA_PKCS_KEY_PAIR_GEN      0x00000000
7349 +#define CKM_RSA_PKCS                   0x00000001
7350 +#define CKM_RSA_9796                   0x00000002
7351 +#define CKM_RSA_X_509                  0x00000003
7352 +
7353 +/* CKM_MD2_RSA_PKCS, CKM_MD5_RSA_PKCS, and CKM_SHA1_RSA_PKCS
7354 + * are new for v2.0.  They are mechanisms which hash and sign */
7355 +#define CKM_MD2_RSA_PKCS               0x00000004
7356 +#define CKM_MD5_RSA_PKCS               0x00000005
7357 +#define CKM_SHA1_RSA_PKCS              0x00000006
7358 +
7359 +/* CKM_RIPEMD128_RSA_PKCS, CKM_RIPEMD160_RSA_PKCS, and
7360 + * CKM_RSA_PKCS_OAEP are new for v2.10 */
7361 +#define CKM_RIPEMD128_RSA_PKCS         0x00000007
7362 +#define CKM_RIPEMD160_RSA_PKCS         0x00000008
7363 +#define CKM_RSA_PKCS_OAEP              0x00000009
7364 +
7365 +/* CKM_RSA_X9_31_KEY_PAIR_GEN, CKM_RSA_X9_31, CKM_SHA1_RSA_X9_31,
7366 + * CKM_RSA_PKCS_PSS, and CKM_SHA1_RSA_PKCS_PSS are new for v2.11 */
7367 +#define CKM_RSA_X9_31_KEY_PAIR_GEN     0x0000000A
7368 +#define CKM_RSA_X9_31                  0x0000000B
7369 +#define CKM_SHA1_RSA_X9_31             0x0000000C
7370 +#define CKM_RSA_PKCS_PSS               0x0000000D
7371 +#define CKM_SHA1_RSA_PKCS_PSS          0x0000000E
7372 +
7373 +#define CKM_DSA_KEY_PAIR_GEN           0x00000010
7374 +#define CKM_DSA                        0x00000011
7375 +#define CKM_DSA_SHA1                   0x00000012
7376 +#define CKM_DH_PKCS_KEY_PAIR_GEN       0x00000020
7377 +#define CKM_DH_PKCS_DERIVE             0x00000021
7378 +
7379 +/* CKM_X9_42_DH_KEY_PAIR_GEN, CKM_X9_42_DH_DERIVE,
7380 + * CKM_X9_42_DH_HYBRID_DERIVE, and CKM_X9_42_MQV_DERIVE are new for
7381 + * v2.11 */
7382 +#define CKM_X9_42_DH_KEY_PAIR_GEN      0x00000030
7383 +#define CKM_X9_42_DH_DERIVE            0x00000031
7384 +#define CKM_X9_42_DH_HYBRID_DERIVE     0x00000032
7385 +#define CKM_X9_42_MQV_DERIVE           0x00000033
7386 +
7387 +/* CKM_SHA256/384/512 are new for v2.20 */
7388 +#define CKM_SHA256_RSA_PKCS            0x00000040
7389 +#define CKM_SHA384_RSA_PKCS            0x00000041
7390 +#define CKM_SHA512_RSA_PKCS            0x00000042
7391 +#define CKM_SHA256_RSA_PKCS_PSS        0x00000043
7392 +#define CKM_SHA384_RSA_PKCS_PSS        0x00000044
7393 +#define CKM_SHA512_RSA_PKCS_PSS        0x00000045
7394 +
7395 +#define CKM_RC2_KEY_GEN                0x00000100
7396 +#define CKM_RC2_ECB                    0x00000101
7397 +#define CKM_RC2_CBC                    0x00000102
7398 +#define CKM_RC2_MAC                    0x00000103
7399 +
7400 +/* CKM_RC2_MAC_GENERAL and CKM_RC2_CBC_PAD are new for v2.0 */
7401 +#define CKM_RC2_MAC_GENERAL            0x00000104
7402 +#define CKM_RC2_CBC_PAD                0x00000105
7403 +
7404 +#define CKM_RC4_KEY_GEN                0x00000110
7405 +#define CKM_RC4                        0x00000111
7406 +#define CKM_DES_KEY_GEN                0x00000120
7407 +#define CKM_DES_ECB                    0x00000121
7408 +#define CKM_DES_CBC                    0x00000122
7409 +#define CKM_DES_MAC                    0x00000123
7410 +
7411 +/* CKM_DES_MAC_GENERAL and CKM_DES_CBC_PAD are new for v2.0 */
7412 +#define CKM_DES_MAC_GENERAL            0x00000124
7413 +#define CKM_DES_CBC_PAD                0x00000125
7414 +
7415 +#define CKM_DES2_KEY_GEN               0x00000130
7416 +#define CKM_DES3_KEY_GEN               0x00000131
7417 +#define CKM_DES3_ECB                   0x00000132
7418 +#define CKM_DES3_CBC                   0x00000133
7419 +#define CKM_DES3_MAC                   0x00000134
7420 +
7421 +/* CKM_DES3_MAC_GENERAL, CKM_DES3_CBC_PAD, CKM_CDMF_KEY_GEN,
7422 + * CKM_CDMF_ECB, CKM_CDMF_CBC, CKM_CDMF_MAC,
7423 + * CKM_CDMF_MAC_GENERAL, and CKM_CDMF_CBC_PAD are new for v2.0 */
7424 +#define CKM_DES3_MAC_GENERAL           0x00000135
7425 +#define CKM_DES3_CBC_PAD               0x00000136
7426 +#define CKM_CDMF_KEY_GEN               0x00000140
7427 +#define CKM_CDMF_ECB                   0x00000141
7428 +#define CKM_CDMF_CBC                   0x00000142
7429 +#define CKM_CDMF_MAC                   0x00000143
7430 +#define CKM_CDMF_MAC_GENERAL           0x00000144
7431 +#define CKM_CDMF_CBC_PAD               0x00000145
7432 +
7433 +/* the following four DES mechanisms are new for v2.20 */
7434 +#define CKM_DES_OFB64                  0x00000150
7435 +#define CKM_DES_OFB8                   0x00000151
7436 +#define CKM_DES_CFB64                  0x00000152
7437 +#define CKM_DES_CFB8                   0x00000153
7438 +
7439 +#define CKM_MD2                        0x00000200
7440 +
7441 +/* CKM_MD2_HMAC and CKM_MD2_HMAC_GENERAL are new for v2.0 */
7442 +#define CKM_MD2_HMAC                   0x00000201
7443 +#define CKM_MD2_HMAC_GENERAL           0x00000202
7444 +
7445 +#define CKM_MD5                        0x00000210
7446 +
7447 +/* CKM_MD5_HMAC and CKM_MD5_HMAC_GENERAL are new for v2.0 */
7448 +#define CKM_MD5_HMAC                   0x00000211
7449 +#define CKM_MD5_HMAC_GENERAL           0x00000212
7450 +
7451 +#define CKM_SHA_1                      0x00000220
7452 +
7453 +/* CKM_SHA_1_HMAC and CKM_SHA_1_HMAC_GENERAL are new for v2.0 */
7454 +#define CKM_SHA_1_HMAC                 0x00000221
7455 +#define CKM_SHA_1_HMAC_GENERAL         0x00000222
7456 +
7457 +/* CKM_RIPEMD128, CKM_RIPEMD128_HMAC,
7458 + * CKM_RIPEMD128_HMAC_GENERAL, CKM_RIPEMD160, CKM_RIPEMD160_HMAC,
7459 + * and CKM_RIPEMD160_HMAC_GENERAL are new for v2.10 */
7460 +#define CKM_RIPEMD128                  0x00000230
7461 +#define CKM_RIPEMD128_HMAC             0x00000231
7462 +#define CKM_RIPEMD128_HMAC_GENERAL     0x00000232
7463 +#define CKM_RIPEMD160                  0x00000240
7464 +#define CKM_RIPEMD160_HMAC             0x00000241
7465 +#define CKM_RIPEMD160_HMAC_GENERAL     0x00000242
7466 +
7467 +/* CKM_SHA256/384/512 are new for v2.20 */
7468 +#define CKM_SHA256                     0x00000250
7469 +#define CKM_SHA256_HMAC                0x00000251
7470 +#define CKM_SHA256_HMAC_GENERAL        0x00000252
7471 +#define CKM_SHA384                     0x00000260
7472 +#define CKM_SHA384_HMAC                0x00000261
7473 +#define CKM_SHA384_HMAC_GENERAL        0x00000262
7474 +#define CKM_SHA512                     0x00000270
7475 +#define CKM_SHA512_HMAC                0x00000271
7476 +#define CKM_SHA512_HMAC_GENERAL        0x00000272
7477 +
7478 +/* All of the following mechanisms are new for v2.0 */
7479 +/* Note that CAST128 and CAST5 are the same algorithm */
7480 +#define CKM_CAST_KEY_GEN               0x00000300
7481 +#define CKM_CAST_ECB                   0x00000301
7482 +#define CKM_CAST_CBC                   0x00000302
7483 +#define CKM_CAST_MAC                   0x00000303
7484 +#define CKM_CAST_MAC_GENERAL           0x00000304
7485 +#define CKM_CAST_CBC_PAD               0x00000305
7486 +#define CKM_CAST3_KEY_GEN              0x00000310
7487 +#define CKM_CAST3_ECB                  0x00000311
7488 +#define CKM_CAST3_CBC                  0x00000312
7489 +#define CKM_CAST3_MAC                  0x00000313
7490 +#define CKM_CAST3_MAC_GENERAL          0x00000314
7491 +#define CKM_CAST3_CBC_PAD              0x00000315
7492 +#define CKM_CAST5_KEY_GEN              0x00000320
7493 +#define CKM_CAST128_KEY_GEN            0x00000320
7494 +#define CKM_CAST5_ECB                  0x00000321
7495 +#define CKM_CAST128_ECB                0x00000321
7496 +#define CKM_CAST5_CBC                  0x00000322
7497 +#define CKM_CAST128_CBC                0x00000322
7498 +#define CKM_CAST5_MAC                  0x00000323
7499 +#define CKM_CAST128_MAC                0x00000323
7500 +#define CKM_CAST5_MAC_GENERAL          0x00000324
7501 +#define CKM_CAST128_MAC_GENERAL        0x00000324
7502 +#define CKM_CAST5_CBC_PAD              0x00000325
7503 +#define CKM_CAST128_CBC_PAD            0x00000325
7504 +#define CKM_RC5_KEY_GEN                0x00000330
7505 +#define CKM_RC5_ECB                    0x00000331
7506 +#define CKM_RC5_CBC                    0x00000332
7507 +#define CKM_RC5_MAC                    0x00000333
7508 +#define CKM_RC5_MAC_GENERAL            0x00000334
7509 +#define CKM_RC5_CBC_PAD                0x00000335
7510 +#define CKM_IDEA_KEY_GEN               0x00000340
7511 +#define CKM_IDEA_ECB                   0x00000341
7512 +#define CKM_IDEA_CBC                   0x00000342
7513 +#define CKM_IDEA_MAC                   0x00000343
7514 +#define CKM_IDEA_MAC_GENERAL           0x00000344
7515 +#define CKM_IDEA_CBC_PAD               0x00000345
7516 +#define CKM_GENERIC_SECRET_KEY_GEN     0x00000350
7517 +#define CKM_CONCATENATE_BASE_AND_KEY   0x00000360
7518 +#define CKM_CONCATENATE_BASE_AND_DATA  0x00000362
7519 +#define CKM_CONCATENATE_DATA_AND_BASE  0x00000363
7520 +#define CKM_XOR_BASE_AND_DATA          0x00000364
7521 +#define CKM_EXTRACT_KEY_FROM_KEY       0x00000365
7522 +#define CKM_SSL3_PRE_MASTER_KEY_GEN    0x00000370
7523 +#define CKM_SSL3_MASTER_KEY_DERIVE     0x00000371
7524 +#define CKM_SSL3_KEY_AND_MAC_DERIVE    0x00000372
7525 +
7526 +/* CKM_SSL3_MASTER_KEY_DERIVE_DH, CKM_TLS_PRE_MASTER_KEY_GEN,
7527 + * CKM_TLS_MASTER_KEY_DERIVE, CKM_TLS_KEY_AND_MAC_DERIVE, and
7528 + * CKM_TLS_MASTER_KEY_DERIVE_DH are new for v2.11 */
7529 +#define CKM_SSL3_MASTER_KEY_DERIVE_DH  0x00000373
7530 +#define CKM_TLS_PRE_MASTER_KEY_GEN     0x00000374
7531 +#define CKM_TLS_MASTER_KEY_DERIVE      0x00000375
7532 +#define CKM_TLS_KEY_AND_MAC_DERIVE     0x00000376
7533 +#define CKM_TLS_MASTER_KEY_DERIVE_DH   0x00000377
7534 +
7535 +/* CKM_TLS_PRF is new for v2.20 */
7536 +#define CKM_TLS_PRF                    0x00000378
7537 +
7538 +#define CKM_SSL3_MD5_MAC               0x00000380
7539 +#define CKM_SSL3_SHA1_MAC              0x00000381
7540 +#define CKM_MD5_KEY_DERIVATION         0x00000390
7541 +#define CKM_MD2_KEY_DERIVATION         0x00000391
7542 +#define CKM_SHA1_KEY_DERIVATION        0x00000392
7543 +
7544 +/* CKM_SHA256/384/512 are new for v2.20 */
7545 +#define CKM_SHA256_KEY_DERIVATION      0x00000393
7546 +#define CKM_SHA384_KEY_DERIVATION      0x00000394
7547 +#define CKM_SHA512_KEY_DERIVATION      0x00000395
7548 +
7549 +#define CKM_PBE_MD2_DES_CBC            0x000003A0
7550 +#define CKM_PBE_MD5_DES_CBC            0x000003A1
7551 +#define CKM_PBE_MD5_CAST_CBC           0x000003A2
7552 +#define CKM_PBE_MD5_CAST3_CBC          0x000003A3
7553 +#define CKM_PBE_MD5_CAST5_CBC          0x000003A4
7554 +#define CKM_PBE_MD5_CAST128_CBC        0x000003A4
7555 +#define CKM_PBE_SHA1_CAST5_CBC         0x000003A5
7556 +#define CKM_PBE_SHA1_CAST128_CBC       0x000003A5
7557 +#define CKM_PBE_SHA1_RC4_128           0x000003A6
7558 +#define CKM_PBE_SHA1_RC4_40            0x000003A7
7559 +#define CKM_PBE_SHA1_DES3_EDE_CBC      0x000003A8
7560 +#define CKM_PBE_SHA1_DES2_EDE_CBC      0x000003A9
7561 +#define CKM_PBE_SHA1_RC2_128_CBC       0x000003AA
7562 +#define CKM_PBE_SHA1_RC2_40_CBC        0x000003AB
7563 +
7564 +/* CKM_PKCS5_PBKD2 is new for v2.10 */
7565 +#define CKM_PKCS5_PBKD2                0x000003B0
7566 +
7567 +#define CKM_PBA_SHA1_WITH_SHA1_HMAC    0x000003C0
7568 +
7569 +/* WTLS mechanisms are new for v2.20 */
7570 +#define CKM_WTLS_PRE_MASTER_KEY_GEN         0x000003D0
7571 +#define CKM_WTLS_MASTER_KEY_DERIVE          0x000003D1
7572 +#define CKM_WTLS_MASTER_KEY_DERIVE_DH_ECC   0x000003D2
7573 +#define CKM_WTLS_PRF                        0x000003D3
7574 +#define CKM_WTLS_SERVER_KEY_AND_MAC_DERIVE  0x000003D4
7575 +#define CKM_WTLS_CLIENT_KEY_AND_MAC_DERIVE  0x000003D5
7576 +
7577 +#define CKM_KEY_WRAP_LYNKS             0x00000400
7578 +#define CKM_KEY_WRAP_SET_OAEP          0x00000401
7579 +
7580 +/* CKM_CMS_SIG is new for v2.20 */
7581 +#define CKM_CMS_SIG                    0x00000500
7582 +
7583 +/* Fortezza mechanisms */
7584 +#define CKM_SKIPJACK_KEY_GEN           0x00001000
7585 +#define CKM_SKIPJACK_ECB64             0x00001001
7586 +#define CKM_SKIPJACK_CBC64             0x00001002
7587 +#define CKM_SKIPJACK_OFB64             0x00001003
7588 +#define CKM_SKIPJACK_CFB64             0x00001004
7589 +#define CKM_SKIPJACK_CFB32             0x00001005
7590 +#define CKM_SKIPJACK_CFB16             0x00001006
7591 +#define CKM_SKIPJACK_CFB8              0x00001007
7592 +#define CKM_SKIPJACK_WRAP              0x00001008
7593 +#define CKM_SKIPJACK_PRIVATE_WRAP      0x00001009
7594 +#define CKM_SKIPJACK_RELAYX            0x0000100a
7595 +#define CKM_KEA_KEY_PAIR_GEN           0x00001010
7596 +#define CKM_KEA_KEY_DERIVE             0x00001011
7597 +#define CKM_FORTEZZA_TIMESTAMP         0x00001020
7598 +#define CKM_BATON_KEY_GEN              0x00001030
7599 +#define CKM_BATON_ECB128               0x00001031
7600 +#define CKM_BATON_ECB96                0x00001032
7601 +#define CKM_BATON_CBC128               0x00001033
7602 +#define CKM_BATON_COUNTER              0x00001034
7603 +#define CKM_BATON_SHUFFLE              0x00001035
7604 +#define CKM_BATON_WRAP                 0x00001036
7605 +
7606 +/* CKM_ECDSA_KEY_PAIR_GEN is deprecated in v2.11,
7607 + * CKM_EC_KEY_PAIR_GEN is preferred */
7608 +#define CKM_ECDSA_KEY_PAIR_GEN         0x00001040
7609 +#define CKM_EC_KEY_PAIR_GEN            0x00001040
7610 +
7611 +#define CKM_ECDSA                      0x00001041
7612 +#define CKM_ECDSA_SHA1                 0x00001042
7613 +
7614 +/* CKM_ECDH1_DERIVE, CKM_ECDH1_COFACTOR_DERIVE, and CKM_ECMQV_DERIVE
7615 + * are new for v2.11 */
7616 +#define CKM_ECDH1_DERIVE               0x00001050
7617 +#define CKM_ECDH1_COFACTOR_DERIVE      0x00001051
7618 +#define CKM_ECMQV_DERIVE               0x00001052
7619 +
7620 +#define CKM_JUNIPER_KEY_GEN            0x00001060
7621 +#define CKM_JUNIPER_ECB128             0x00001061
7622 +#define CKM_JUNIPER_CBC128             0x00001062
7623 +#define CKM_JUNIPER_COUNTER            0x00001063
7624 +#define CKM_JUNIPER_SHUFFLE            0x00001064
7625 +#define CKM_JUNIPER_WRAP               0x00001065
7626 +#define CKM_FASTHASH                   0x00001070
7627 +
7628 +/* CKM_AES_KEY_GEN, CKM_AES_ECB, CKM_AES_CBC, CKM_AES_MAC,
7629 + * CKM_AES_MAC_GENERAL, CKM_AES_CBC_PAD, CKM_DSA_PARAMETER_GEN,
7630 + * CKM_DH_PKCS_PARAMETER_GEN, and CKM_X9_42_DH_PARAMETER_GEN are
7631 + * new for v2.11 */
7632 +#define CKM_AES_KEY_GEN                0x00001080
7633 +#define CKM_AES_ECB                    0x00001081
7634 +#define CKM_AES_CBC                    0x00001082
7635 +#define CKM_AES_MAC                    0x00001083
7636 +#define CKM_AES_MAC_GENERAL            0x00001084
7637 +#define CKM_AES_CBC_PAD                0x00001085
7638 +
7639 +/* BlowFish and TwoFish are new for v2.20 */
7640 +#define CKM_BLOWFISH_KEY_GEN           0x00001090
7641 +#define CKM_BLOWFISH_CBC               0x00001091
7642 +#define CKM_TWOFISH_KEY_GEN            0x00001092
7643 +#define CKM_TWOFISH_CBC                0x00001093
7644 +
7645 +
7646 +/* CKM_xxx_ENCRYPT_DATA mechanisms are new for v2.20 */
7647 +#define CKM_DES_ECB_ENCRYPT_DATA       0x00001100
7648 +#define CKM_DES_CBC_ENCRYPT_DATA       0x00001101
7649 +#define CKM_DES3_ECB_ENCRYPT_DATA      0x00001102
7650 +#define CKM_DES3_CBC_ENCRYPT_DATA      0x00001103
7651 +#define CKM_AES_ECB_ENCRYPT_DATA       0x00001104
7652 +#define CKM_AES_CBC_ENCRYPT_DATA       0x00001105
7653 +
7654 +#define CKM_DSA_PARAMETER_GEN          0x00002000
7655 +#define CKM_DH_PKCS_PARAMETER_GEN      0x00002001
7656 +#define CKM_X9_42_DH_PARAMETER_GEN     0x00002002
7657 +
7658 +#define CKM_VENDOR_DEFINED             0x80000000
7659 +
7660 +typedef CK_MECHANISM_TYPE CK_PTR CK_MECHANISM_TYPE_PTR;
7661 +
7662 +
7663 +/* CK_MECHANISM is a structure that specifies a particular
7664 + * mechanism  */
7665 +typedef struct CK_MECHANISM {
7666 +  CK_MECHANISM_TYPE mechanism;
7667 +  CK_VOID_PTR       pParameter;
7668 +
7669 +  /* ulParameterLen was changed from CK_USHORT to CK_ULONG for
7670 +   * v2.0 */
7671 +  CK_ULONG          ulParameterLen;  /* in bytes */
7672 +} CK_MECHANISM;
7673 +
7674 +typedef CK_MECHANISM CK_PTR CK_MECHANISM_PTR;
7675 +
7676 +
7677 +/* CK_MECHANISM_INFO provides information about a particular
7678 + * mechanism */
7679 +typedef struct CK_MECHANISM_INFO {
7680 +    CK_ULONG    ulMinKeySize;
7681 +    CK_ULONG    ulMaxKeySize;
7682 +    CK_FLAGS    flags;
7683 +} CK_MECHANISM_INFO;
7684 +
7685 +/* The flags are defined as follows:
7686 + *      Bit Flag               Mask        Meaning */
7687 +#define CKF_HW                 0x00000001  /* performed by HW */
7688 +
7689 +/* The flags CKF_ENCRYPT, CKF_DECRYPT, CKF_DIGEST, CKF_SIGN,
7690 + * CKG_SIGN_RECOVER, CKF_VERIFY, CKF_VERIFY_RECOVER,
7691 + * CKF_GENERATE, CKF_GENERATE_KEY_PAIR, CKF_WRAP, CKF_UNWRAP,
7692 + * and CKF_DERIVE are new for v2.0.  They specify whether or not
7693 + * a mechanism can be used for a particular task */
7694 +#define CKF_ENCRYPT            0x00000100
7695 +#define CKF_DECRYPT            0x00000200
7696 +#define CKF_DIGEST             0x00000400
7697 +#define CKF_SIGN               0x00000800
7698 +#define CKF_SIGN_RECOVER       0x00001000
7699 +#define CKF_VERIFY             0x00002000
7700 +#define CKF_VERIFY_RECOVER     0x00004000
7701 +#define CKF_GENERATE           0x00008000
7702 +#define CKF_GENERATE_KEY_PAIR  0x00010000
7703 +#define CKF_WRAP               0x00020000
7704 +#define CKF_UNWRAP             0x00040000
7705 +#define CKF_DERIVE             0x00080000
7706 +
7707 +/* CKF_EC_F_P, CKF_EC_F_2M, CKF_EC_ECPARAMETERS, CKF_EC_NAMEDCURVE,
7708 + * CKF_EC_UNCOMPRESS, and CKF_EC_COMPRESS are new for v2.11. They
7709 + * describe a token's EC capabilities not available in mechanism
7710 + * information. */
7711 +#define CKF_EC_F_P             0x00100000
7712 +#define CKF_EC_F_2M            0x00200000
7713 +#define CKF_EC_ECPARAMETERS    0x00400000
7714 +#define CKF_EC_NAMEDCURVE      0x00800000
7715 +#define CKF_EC_UNCOMPRESS      0x01000000
7716 +#define CKF_EC_COMPRESS        0x02000000
7717 +
7718 +#define CKF_EXTENSION          0x80000000 /* FALSE for this version */
7719 +
7720 +typedef CK_MECHANISM_INFO CK_PTR CK_MECHANISM_INFO_PTR;
7721 +
7722 +
7723 +/* CK_RV is a value that identifies the return value of a
7724 + * Cryptoki function */
7725 +/* CK_RV was changed from CK_USHORT to CK_ULONG for v2.0 */
7726 +typedef CK_ULONG          CK_RV;
7727 +
7728 +#define CKR_OK                                0x00000000
7729 +#define CKR_CANCEL                            0x00000001
7730 +#define CKR_HOST_MEMORY                       0x00000002
7731 +#define CKR_SLOT_ID_INVALID                   0x00000003
7732 +
7733 +/* CKR_FLAGS_INVALID was removed for v2.0 */
7734 +
7735 +/* CKR_GENERAL_ERROR and CKR_FUNCTION_FAILED are new for v2.0 */
7736 +#define CKR_GENERAL_ERROR                     0x00000005
7737 +#define CKR_FUNCTION_FAILED                   0x00000006
7738 +
7739 +/* CKR_ARGUMENTS_BAD, CKR_NO_EVENT, CKR_NEED_TO_CREATE_THREADS,
7740 + * and CKR_CANT_LOCK are new for v2.01 */
7741 +#define CKR_ARGUMENTS_BAD                     0x00000007
7742 +#define CKR_NO_EVENT                          0x00000008
7743 +#define CKR_NEED_TO_CREATE_THREADS            0x00000009
7744 +#define CKR_CANT_LOCK                         0x0000000A
7745 +
7746 +#define CKR_ATTRIBUTE_READ_ONLY               0x00000010
7747 +#define CKR_ATTRIBUTE_SENSITIVE               0x00000011
7748 +#define CKR_ATTRIBUTE_TYPE_INVALID            0x00000012
7749 +#define CKR_ATTRIBUTE_VALUE_INVALID           0x00000013
7750 +#define CKR_DATA_INVALID                      0x00000020
7751 +#define CKR_DATA_LEN_RANGE                    0x00000021
7752 +#define CKR_DEVICE_ERROR                      0x00000030
7753 +#define CKR_DEVICE_MEMORY                     0x00000031
7754 +#define CKR_DEVICE_REMOVED                    0x00000032
7755 +#define CKR_ENCRYPTED_DATA_INVALID            0x00000040
7756 +#define CKR_ENCRYPTED_DATA_LEN_RANGE          0x00000041
7757 +#define CKR_FUNCTION_CANCELED                 0x00000050
7758 +#define CKR_FUNCTION_NOT_PARALLEL             0x00000051
7759 +
7760 +/* CKR_FUNCTION_NOT_SUPPORTED is new for v2.0 */
7761 +#define CKR_FUNCTION_NOT_SUPPORTED            0x00000054
7762 +
7763 +#define CKR_KEY_HANDLE_INVALID                0x00000060
7764 +
7765 +/* CKR_KEY_SENSITIVE was removed for v2.0 */
7766 +
7767 +#define CKR_KEY_SIZE_RANGE                    0x00000062
7768 +#define CKR_KEY_TYPE_INCONSISTENT             0x00000063
7769 +
7770 +/* CKR_KEY_NOT_NEEDED, CKR_KEY_CHANGED, CKR_KEY_NEEDED,
7771 + * CKR_KEY_INDIGESTIBLE, CKR_KEY_FUNCTION_NOT_PERMITTED,
7772 + * CKR_KEY_NOT_WRAPPABLE, and CKR_KEY_UNEXTRACTABLE are new for
7773 + * v2.0 */
7774 +#define CKR_KEY_NOT_NEEDED                    0x00000064
7775 +#define CKR_KEY_CHANGED                       0x00000065
7776 +#define CKR_KEY_NEEDED                        0x00000066
7777 +#define CKR_KEY_INDIGESTIBLE                  0x00000067
7778 +#define CKR_KEY_FUNCTION_NOT_PERMITTED        0x00000068
7779 +#define CKR_KEY_NOT_WRAPPABLE                 0x00000069
7780 +#define CKR_KEY_UNEXTRACTABLE                 0x0000006A
7781 +
7782 +#define CKR_MECHANISM_INVALID                 0x00000070
7783 +#define CKR_MECHANISM_PARAM_INVALID           0x00000071
7784 +
7785 +/* CKR_OBJECT_CLASS_INCONSISTENT and CKR_OBJECT_CLASS_INVALID
7786 + * were removed for v2.0 */
7787 +#define CKR_OBJECT_HANDLE_INVALID             0x00000082
7788 +#define CKR_OPERATION_ACTIVE                  0x00000090
7789 +#define CKR_OPERATION_NOT_INITIALIZED         0x00000091
7790 +#define CKR_PIN_INCORRECT                     0x000000A0
7791 +#define CKR_PIN_INVALID                       0x000000A1
7792 +#define CKR_PIN_LEN_RANGE                     0x000000A2
7793 +
7794 +/* CKR_PIN_EXPIRED and CKR_PIN_LOCKED are new for v2.0 */
7795 +#define CKR_PIN_EXPIRED                       0x000000A3
7796 +#define CKR_PIN_LOCKED                        0x000000A4
7797 +
7798 +#define CKR_SESSION_CLOSED                    0x000000B0
7799 +#define CKR_SESSION_COUNT                     0x000000B1
7800 +#define CKR_SESSION_HANDLE_INVALID            0x000000B3
7801 +#define CKR_SESSION_PARALLEL_NOT_SUPPORTED    0x000000B4
7802 +#define CKR_SESSION_READ_ONLY                 0x000000B5
7803 +#define CKR_SESSION_EXISTS                    0x000000B6
7804 +
7805 +/* CKR_SESSION_READ_ONLY_EXISTS and
7806 + * CKR_SESSION_READ_WRITE_SO_EXISTS are new for v2.0 */
7807 +#define CKR_SESSION_READ_ONLY_EXISTS          0x000000B7
7808 +#define CKR_SESSION_READ_WRITE_SO_EXISTS      0x000000B8
7809 +
7810 +#define CKR_SIGNATURE_INVALID                 0x000000C0
7811 +#define CKR_SIGNATURE_LEN_RANGE               0x000000C1
7812 +#define CKR_TEMPLATE_INCOMPLETE               0x000000D0
7813 +#define CKR_TEMPLATE_INCONSISTENT             0x000000D1
7814 +#define CKR_TOKEN_NOT_PRESENT                 0x000000E0
7815 +#define CKR_TOKEN_NOT_RECOGNIZED              0x000000E1
7816 +#define CKR_TOKEN_WRITE_PROTECTED             0x000000E2
7817 +#define CKR_UNWRAPPING_KEY_HANDLE_INVALID     0x000000F0
7818 +#define CKR_UNWRAPPING_KEY_SIZE_RANGE         0x000000F1
7819 +#define CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT  0x000000F2
7820 +#define CKR_USER_ALREADY_LOGGED_IN            0x00000100
7821 +#define CKR_USER_NOT_LOGGED_IN                0x00000101
7822 +#define CKR_USER_PIN_NOT_INITIALIZED          0x00000102
7823 +#define CKR_USER_TYPE_INVALID                 0x00000103
7824 +
7825 +/* CKR_USER_ANOTHER_ALREADY_LOGGED_IN and CKR_USER_TOO_MANY_TYPES
7826 + * are new to v2.01 */
7827 +#define CKR_USER_ANOTHER_ALREADY_LOGGED_IN    0x00000104
7828 +#define CKR_USER_TOO_MANY_TYPES               0x00000105
7829 +
7830 +#define CKR_WRAPPED_KEY_INVALID               0x00000110
7831 +#define CKR_WRAPPED_KEY_LEN_RANGE             0x00000112
7832 +#define CKR_WRAPPING_KEY_HANDLE_INVALID       0x00000113
7833 +#define CKR_WRAPPING_KEY_SIZE_RANGE           0x00000114
7834 +#define CKR_WRAPPING_KEY_TYPE_INCONSISTENT    0x00000115
7835 +#define CKR_RANDOM_SEED_NOT_SUPPORTED         0x00000120
7836 +
7837 +/* These are new to v2.0 */
7838 +#define CKR_RANDOM_NO_RNG                     0x00000121
7839 +
7840 +/* These are new to v2.11 */
7841 +#define CKR_DOMAIN_PARAMS_INVALID             0x00000130
7842 +
7843 +/* These are new to v2.0 */
7844 +#define CKR_BUFFER_TOO_SMALL                  0x00000150
7845 +#define CKR_SAVED_STATE_INVALID               0x00000160
7846 +#define CKR_INFORMATION_SENSITIVE             0x00000170
7847 +#define CKR_STATE_UNSAVEABLE                  0x00000180
7848 +
7849 +/* These are new to v2.01 */
7850 +#define CKR_CRYPTOKI_NOT_INITIALIZED          0x00000190
7851 +#define CKR_CRYPTOKI_ALREADY_INITIALIZED      0x00000191
7852 +#define CKR_MUTEX_BAD                         0x000001A0
7853 +#define CKR_MUTEX_NOT_LOCKED                  0x000001A1
7854 +
7855 +/* This is new to v2.20 */
7856 +#define CKR_FUNCTION_REJECTED                 0x00000200
7857 +
7858 +#define CKR_VENDOR_DEFINED                    0x80000000
7859 +
7860 +
7861 +/* CK_NOTIFY is an application callback that processes events */
7862 +typedef CK_CALLBACK_FUNCTION(CK_RV, CK_NOTIFY)(
7863 +  CK_SESSION_HANDLE hSession,     /* the session's handle */
7864 +  CK_NOTIFICATION   event,
7865 +  CK_VOID_PTR       pApplication  /* passed to C_OpenSession */
7866 +);
7867 +
7868 +
7869 +/* CK_FUNCTION_LIST is a structure holding a Cryptoki spec
7870 + * version and pointers of appropriate types to all the
7871 + * Cryptoki functions */
7872 +/* CK_FUNCTION_LIST is new for v2.0 */
7873 +typedef struct CK_FUNCTION_LIST CK_FUNCTION_LIST;
7874 +
7875 +typedef CK_FUNCTION_LIST CK_PTR CK_FUNCTION_LIST_PTR;
7876 +
7877 +typedef CK_FUNCTION_LIST_PTR CK_PTR CK_FUNCTION_LIST_PTR_PTR;
7878 +
7879 +
7880 +/* CK_CREATEMUTEX is an application callback for creating a
7881 + * mutex object */
7882 +typedef CK_CALLBACK_FUNCTION(CK_RV, CK_CREATEMUTEX)(
7883 +  CK_VOID_PTR_PTR ppMutex  /* location to receive ptr to mutex */
7884 +);
7885 +
7886 +
7887 +/* CK_DESTROYMUTEX is an application callback for destroying a
7888 + * mutex object */
7889 +typedef CK_CALLBACK_FUNCTION(CK_RV, CK_DESTROYMUTEX)(
7890 +  CK_VOID_PTR pMutex  /* pointer to mutex */
7891 +);
7892 +
7893 +
7894 +/* CK_LOCKMUTEX is an application callback for locking a mutex */
7895 +typedef CK_CALLBACK_FUNCTION(CK_RV, CK_LOCKMUTEX)(
7896 +  CK_VOID_PTR pMutex  /* pointer to mutex */
7897 +);
7898 +
7899 +
7900 +/* CK_UNLOCKMUTEX is an application callback for unlocking a
7901 + * mutex */
7902 +typedef CK_CALLBACK_FUNCTION(CK_RV, CK_UNLOCKMUTEX)(
7903 +  CK_VOID_PTR pMutex  /* pointer to mutex */
7904 +);
7905 +
7906 +
7907 +/* CK_C_INITIALIZE_ARGS provides the optional arguments to
7908 + * C_Initialize */
7909 +typedef struct CK_C_INITIALIZE_ARGS {
7910 +  CK_CREATEMUTEX CreateMutex;
7911 +  CK_DESTROYMUTEX DestroyMutex;
7912 +  CK_LOCKMUTEX LockMutex;
7913 +  CK_UNLOCKMUTEX UnlockMutex;
7914 +  CK_FLAGS flags;
7915 +  CK_VOID_PTR pReserved;
7916 +} CK_C_INITIALIZE_ARGS;
7917 +
7918 +/* flags: bit flags that provide capabilities of the slot
7919 + *      Bit Flag                           Mask       Meaning
7920 + */
7921 +#define CKF_LIBRARY_CANT_CREATE_OS_THREADS 0x00000001
7922 +#define CKF_OS_LOCKING_OK                  0x00000002
7923 +
7924 +typedef CK_C_INITIALIZE_ARGS CK_PTR CK_C_INITIALIZE_ARGS_PTR;
7925 +
7926 +
7927 +/* additional flags for parameters to functions */
7928 +
7929 +/* CKF_DONT_BLOCK is for the function C_WaitForSlotEvent */
7930 +#define CKF_DONT_BLOCK     1
7931 +
7932 +/* CK_RSA_PKCS_OAEP_MGF_TYPE is new for v2.10.
7933 + * CK_RSA_PKCS_OAEP_MGF_TYPE  is used to indicate the Message
7934 + * Generation Function (MGF) applied to a message block when
7935 + * formatting a message block for the PKCS #1 OAEP encryption
7936 + * scheme. */
7937 +typedef CK_ULONG CK_RSA_PKCS_MGF_TYPE;
7938 +
7939 +typedef CK_RSA_PKCS_MGF_TYPE CK_PTR CK_RSA_PKCS_MGF_TYPE_PTR;
7940 +
7941 +/* The following MGFs are defined */
7942 +/* CKG_MGF1_SHA256, CKG_MGF1_SHA384, and CKG_MGF1_SHA512
7943 + * are new for v2.20 */
7944 +#define CKG_MGF1_SHA1         0x00000001
7945 +#define CKG_MGF1_SHA256       0x00000002
7946 +#define CKG_MGF1_SHA384       0x00000003
7947 +#define CKG_MGF1_SHA512       0x00000004
7948 +
7949 +/* CK_RSA_PKCS_OAEP_SOURCE_TYPE is new for v2.10.
7950 + * CK_RSA_PKCS_OAEP_SOURCE_TYPE  is used to indicate the source
7951 + * of the encoding parameter when formatting a message block
7952 + * for the PKCS #1 OAEP encryption scheme. */
7953 +typedef CK_ULONG CK_RSA_PKCS_OAEP_SOURCE_TYPE;
7954 +
7955 +typedef CK_RSA_PKCS_OAEP_SOURCE_TYPE CK_PTR CK_RSA_PKCS_OAEP_SOURCE_TYPE_PTR;
7956 +
7957 +/* The following encoding parameter sources are defined */
7958 +#define CKZ_DATA_SPECIFIED    0x00000001
7959 +
7960 +/* CK_RSA_PKCS_OAEP_PARAMS is new for v2.10.
7961 + * CK_RSA_PKCS_OAEP_PARAMS provides the parameters to the
7962 + * CKM_RSA_PKCS_OAEP mechanism. */
7963 +typedef struct CK_RSA_PKCS_OAEP_PARAMS {
7964 +        CK_MECHANISM_TYPE hashAlg;
7965 +        CK_RSA_PKCS_MGF_TYPE mgf;
7966 +        CK_RSA_PKCS_OAEP_SOURCE_TYPE source;
7967 +        CK_VOID_PTR pSourceData;
7968 +        CK_ULONG ulSourceDataLen;
7969 +} CK_RSA_PKCS_OAEP_PARAMS;
7970 +
7971 +typedef CK_RSA_PKCS_OAEP_PARAMS CK_PTR CK_RSA_PKCS_OAEP_PARAMS_PTR;
7972 +
7973 +/* CK_RSA_PKCS_PSS_PARAMS is new for v2.11.
7974 + * CK_RSA_PKCS_PSS_PARAMS provides the parameters to the
7975 + * CKM_RSA_PKCS_PSS mechanism(s). */
7976 +typedef struct CK_RSA_PKCS_PSS_PARAMS {
7977 +        CK_MECHANISM_TYPE    hashAlg;
7978 +        CK_RSA_PKCS_MGF_TYPE mgf;
7979 +        CK_ULONG             sLen;
7980 +} CK_RSA_PKCS_PSS_PARAMS;
7981 +
7982 +typedef CK_RSA_PKCS_PSS_PARAMS CK_PTR CK_RSA_PKCS_PSS_PARAMS_PTR;
7983 +
7984 +/* CK_EC_KDF_TYPE is new for v2.11. */
7985 +typedef CK_ULONG CK_EC_KDF_TYPE;
7986 +
7987 +/* The following EC Key Derivation Functions are defined */
7988 +#define CKD_NULL                 0x00000001
7989 +#define CKD_SHA1_KDF             0x00000002
7990 +
7991 +/* CK_ECDH1_DERIVE_PARAMS is new for v2.11.
7992 + * CK_ECDH1_DERIVE_PARAMS provides the parameters to the
7993 + * CKM_ECDH1_DERIVE and CKM_ECDH1_COFACTOR_DERIVE mechanisms,
7994 + * where each party contributes one key pair.
7995 + */
7996 +typedef struct CK_ECDH1_DERIVE_PARAMS {
7997 +  CK_EC_KDF_TYPE kdf;
7998 +  CK_ULONG ulSharedDataLen;
7999 +  CK_BYTE_PTR pSharedData;
8000 +  CK_ULONG ulPublicDataLen;
8001 +  CK_BYTE_PTR pPublicData;
8002 +} CK_ECDH1_DERIVE_PARAMS;
8003 +
8004 +typedef CK_ECDH1_DERIVE_PARAMS CK_PTR CK_ECDH1_DERIVE_PARAMS_PTR;
8005 +
8006 +
8007 +/* CK_ECDH2_DERIVE_PARAMS is new for v2.11.
8008 + * CK_ECDH2_DERIVE_PARAMS provides the parameters to the
8009 + * CKM_ECMQV_DERIVE mechanism, where each party contributes two key pairs. */
8010 +typedef struct CK_ECDH2_DERIVE_PARAMS {
8011 +  CK_EC_KDF_TYPE kdf;
8012 +  CK_ULONG ulSharedDataLen;
8013 +  CK_BYTE_PTR pSharedData;
8014 +  CK_ULONG ulPublicDataLen;
8015 +  CK_BYTE_PTR pPublicData;
8016 +  CK_ULONG ulPrivateDataLen;
8017 +  CK_OBJECT_HANDLE hPrivateData;
8018 +  CK_ULONG ulPublicDataLen2;
8019 +  CK_BYTE_PTR pPublicData2;
8020 +} CK_ECDH2_DERIVE_PARAMS;
8021 +
8022 +typedef CK_ECDH2_DERIVE_PARAMS CK_PTR CK_ECDH2_DERIVE_PARAMS_PTR;
8023 +
8024 +typedef struct CK_ECMQV_DERIVE_PARAMS {
8025 +  CK_EC_KDF_TYPE kdf;
8026 +  CK_ULONG ulSharedDataLen;
8027 +  CK_BYTE_PTR pSharedData;
8028 +  CK_ULONG ulPublicDataLen;
8029 +  CK_BYTE_PTR pPublicData;
8030 +  CK_ULONG ulPrivateDataLen;
8031 +  CK_OBJECT_HANDLE hPrivateData;
8032 +  CK_ULONG ulPublicDataLen2;
8033 +  CK_BYTE_PTR pPublicData2;
8034 +  CK_OBJECT_HANDLE publicKey;
8035 +} CK_ECMQV_DERIVE_PARAMS;
8036 +
8037 +typedef CK_ECMQV_DERIVE_PARAMS CK_PTR CK_ECMQV_DERIVE_PARAMS_PTR;
8038 +
8039 +/* Typedefs and defines for the CKM_X9_42_DH_KEY_PAIR_GEN and the
8040 + * CKM_X9_42_DH_PARAMETER_GEN mechanisms (new for PKCS #11 v2.11) */
8041 +typedef CK_ULONG CK_X9_42_DH_KDF_TYPE;
8042 +typedef CK_X9_42_DH_KDF_TYPE CK_PTR CK_X9_42_DH_KDF_TYPE_PTR;
8043 +
8044 +/* The following X9.42 DH key derivation functions are defined
8045 +   (besides CKD_NULL already defined : */
8046 +#define CKD_SHA1_KDF_ASN1        0x00000003
8047 +#define CKD_SHA1_KDF_CONCATENATE 0x00000004
8048 +
8049 +/* CK_X9_42_DH1_DERIVE_PARAMS is new for v2.11.
8050 + * CK_X9_42_DH1_DERIVE_PARAMS provides the parameters to the
8051 + * CKM_X9_42_DH_DERIVE key derivation mechanism, where each party
8052 + * contributes one key pair */
8053 +typedef struct CK_X9_42_DH1_DERIVE_PARAMS {
8054 +  CK_X9_42_DH_KDF_TYPE kdf;
8055 +  CK_ULONG ulOtherInfoLen;
8056 +  CK_BYTE_PTR pOtherInfo;
8057 +  CK_ULONG ulPublicDataLen;
8058 +  CK_BYTE_PTR pPublicData;
8059 +} CK_X9_42_DH1_DERIVE_PARAMS;
8060 +
8061 +typedef struct CK_X9_42_DH1_DERIVE_PARAMS CK_PTR CK_X9_42_DH1_DERIVE_PARAMS_PTR;
8062 +
8063 +/* CK_X9_42_DH2_DERIVE_PARAMS is new for v2.11.
8064 + * CK_X9_42_DH2_DERIVE_PARAMS provides the parameters to the
8065 + * CKM_X9_42_DH_HYBRID_DERIVE and CKM_X9_42_MQV_DERIVE key derivation
8066 + * mechanisms, where each party contributes two key pairs */
8067 +typedef struct CK_X9_42_DH2_DERIVE_PARAMS {
8068 +  CK_X9_42_DH_KDF_TYPE kdf;
8069 +  CK_ULONG ulOtherInfoLen;
8070 +  CK_BYTE_PTR pOtherInfo;
8071 +  CK_ULONG ulPublicDataLen;
8072 +  CK_BYTE_PTR pPublicData;
8073 +  CK_ULONG ulPrivateDataLen;
8074 +  CK_OBJECT_HANDLE hPrivateData;
8075 +  CK_ULONG ulPublicDataLen2;
8076 +  CK_BYTE_PTR pPublicData2;
8077 +} CK_X9_42_DH2_DERIVE_PARAMS;
8078 +
8079 +typedef CK_X9_42_DH2_DERIVE_PARAMS CK_PTR CK_X9_42_DH2_DERIVE_PARAMS_PTR;
8080 +
8081 +typedef struct CK_X9_42_MQV_DERIVE_PARAMS {
8082 +  CK_X9_42_DH_KDF_TYPE kdf;
8083 +  CK_ULONG ulOtherInfoLen;
8084 +  CK_BYTE_PTR pOtherInfo;
8085 +  CK_ULONG ulPublicDataLen;
8086 +  CK_BYTE_PTR pPublicData;
8087 +  CK_ULONG ulPrivateDataLen;
8088 +  CK_OBJECT_HANDLE hPrivateData;
8089 +  CK_ULONG ulPublicDataLen2;
8090 +  CK_BYTE_PTR pPublicData2;
8091 +  CK_OBJECT_HANDLE publicKey;
8092 +} CK_X9_42_MQV_DERIVE_PARAMS;
8093 +
8094 +typedef CK_X9_42_MQV_DERIVE_PARAMS CK_PTR CK_X9_42_MQV_DERIVE_PARAMS_PTR;
8095 +
8096 +/* CK_KEA_DERIVE_PARAMS provides the parameters to the
8097 + * CKM_KEA_DERIVE mechanism */
8098 +/* CK_KEA_DERIVE_PARAMS is new for v2.0 */
8099 +typedef struct CK_KEA_DERIVE_PARAMS {
8100 +  CK_BBOOL      isSender;
8101 +  CK_ULONG      ulRandomLen;
8102 +  CK_BYTE_PTR   pRandomA;
8103 +  CK_BYTE_PTR   pRandomB;
8104 +  CK_ULONG      ulPublicDataLen;
8105 +  CK_BYTE_PTR   pPublicData;
8106 +} CK_KEA_DERIVE_PARAMS;
8107 +
8108 +typedef CK_KEA_DERIVE_PARAMS CK_PTR CK_KEA_DERIVE_PARAMS_PTR;
8109 +
8110 +
8111 +/* CK_RC2_PARAMS provides the parameters to the CKM_RC2_ECB and
8112 + * CKM_RC2_MAC mechanisms.  An instance of CK_RC2_PARAMS just
8113 + * holds the effective keysize */
8114 +typedef CK_ULONG          CK_RC2_PARAMS;
8115 +
8116 +typedef CK_RC2_PARAMS CK_PTR CK_RC2_PARAMS_PTR;
8117 +
8118 +
8119 +/* CK_RC2_CBC_PARAMS provides the parameters to the CKM_RC2_CBC
8120 + * mechanism */
8121 +typedef struct CK_RC2_CBC_PARAMS {
8122 +  /* ulEffectiveBits was changed from CK_USHORT to CK_ULONG for
8123 +   * v2.0 */
8124 +  CK_ULONG      ulEffectiveBits;  /* effective bits (1-1024) */
8125 +
8126 +  CK_BYTE       iv[8];            /* IV for CBC mode */
8127 +} CK_RC2_CBC_PARAMS;
8128 +
8129 +typedef CK_RC2_CBC_PARAMS CK_PTR CK_RC2_CBC_PARAMS_PTR;
8130 +
8131 +
8132 +/* CK_RC2_MAC_GENERAL_PARAMS provides the parameters for the
8133 + * CKM_RC2_MAC_GENERAL mechanism */
8134 +/* CK_RC2_MAC_GENERAL_PARAMS is new for v2.0 */
8135 +typedef struct CK_RC2_MAC_GENERAL_PARAMS {
8136 +  CK_ULONG      ulEffectiveBits;  /* effective bits (1-1024) */
8137 +  CK_ULONG      ulMacLength;      /* Length of MAC in bytes */
8138 +} CK_RC2_MAC_GENERAL_PARAMS;
8139 +
8140 +typedef CK_RC2_MAC_GENERAL_PARAMS CK_PTR \
8141 +  CK_RC2_MAC_GENERAL_PARAMS_PTR;
8142 +
8143 +
8144 +/* CK_RC5_PARAMS provides the parameters to the CKM_RC5_ECB and
8145 + * CKM_RC5_MAC mechanisms */
8146 +/* CK_RC5_PARAMS is new for v2.0 */
8147 +typedef struct CK_RC5_PARAMS {
8148 +  CK_ULONG      ulWordsize;  /* wordsize in bits */
8149 +  CK_ULONG      ulRounds;    /* number of rounds */
8150 +} CK_RC5_PARAMS;
8151 +
8152 +typedef CK_RC5_PARAMS CK_PTR CK_RC5_PARAMS_PTR;
8153 +
8154 +
8155 +/* CK_RC5_CBC_PARAMS provides the parameters to the CKM_RC5_CBC
8156 + * mechanism */
8157 +/* CK_RC5_CBC_PARAMS is new for v2.0 */
8158 +typedef struct CK_RC5_CBC_PARAMS {
8159 +  CK_ULONG      ulWordsize;  /* wordsize in bits */
8160 +  CK_ULONG      ulRounds;    /* number of rounds */
8161 +  CK_BYTE_PTR   pIv;         /* pointer to IV */
8162 +  CK_ULONG      ulIvLen;     /* length of IV in bytes */
8163 +} CK_RC5_CBC_PARAMS;
8164 +
8165 +typedef CK_RC5_CBC_PARAMS CK_PTR CK_RC5_CBC_PARAMS_PTR;
8166 +
8167 +
8168 +/* CK_RC5_MAC_GENERAL_PARAMS provides the parameters for the
8169 + * CKM_RC5_MAC_GENERAL mechanism */
8170 +/* CK_RC5_MAC_GENERAL_PARAMS is new for v2.0 */
8171 +typedef struct CK_RC5_MAC_GENERAL_PARAMS {
8172 +  CK_ULONG      ulWordsize;   /* wordsize in bits */
8173 +  CK_ULONG      ulRounds;     /* number of rounds */
8174 +  CK_ULONG      ulMacLength;  /* Length of MAC in bytes */
8175 +} CK_RC5_MAC_GENERAL_PARAMS;
8176 +
8177 +typedef CK_RC5_MAC_GENERAL_PARAMS CK_PTR \
8178 +  CK_RC5_MAC_GENERAL_PARAMS_PTR;
8179 +
8180 +
8181 +/* CK_MAC_GENERAL_PARAMS provides the parameters to most block
8182 + * ciphers' MAC_GENERAL mechanisms.  Its value is the length of
8183 + * the MAC */
8184 +/* CK_MAC_GENERAL_PARAMS is new for v2.0 */
8185 +typedef CK_ULONG          CK_MAC_GENERAL_PARAMS;
8186 +
8187 +typedef CK_MAC_GENERAL_PARAMS CK_PTR CK_MAC_GENERAL_PARAMS_PTR;
8188 +
8189 +/* CK_DES/AES_ECB/CBC_ENCRYPT_DATA_PARAMS are new for v2.20 */
8190 +typedef struct CK_DES_CBC_ENCRYPT_DATA_PARAMS {
8191 +  CK_BYTE      iv[8];
8192 +  CK_BYTE_PTR  pData;
8193 +  CK_ULONG     length;
8194 +} CK_DES_CBC_ENCRYPT_DATA_PARAMS;
8195 +
8196 +typedef CK_DES_CBC_ENCRYPT_DATA_PARAMS CK_PTR CK_DES_CBC_ENCRYPT_DATA_PARAMS_PTR;
8197 +
8198 +typedef struct CK_AES_CBC_ENCRYPT_DATA_PARAMS {
8199 +  CK_BYTE      iv[16];
8200 +  CK_BYTE_PTR  pData;
8201 +  CK_ULONG     length;
8202 +} CK_AES_CBC_ENCRYPT_DATA_PARAMS;
8203 +
8204 +typedef CK_AES_CBC_ENCRYPT_DATA_PARAMS CK_PTR CK_AES_CBC_ENCRYPT_DATA_PARAMS_PTR;
8205 +
8206 +/* CK_SKIPJACK_PRIVATE_WRAP_PARAMS provides the parameters to the
8207 + * CKM_SKIPJACK_PRIVATE_WRAP mechanism */
8208 +/* CK_SKIPJACK_PRIVATE_WRAP_PARAMS is new for v2.0 */
8209 +typedef struct CK_SKIPJACK_PRIVATE_WRAP_PARAMS {
8210 +  CK_ULONG      ulPasswordLen;
8211 +  CK_BYTE_PTR   pPassword;
8212 +  CK_ULONG      ulPublicDataLen;
8213 +  CK_BYTE_PTR   pPublicData;
8214 +  CK_ULONG      ulPAndGLen;
8215 +  CK_ULONG      ulQLen;
8216 +  CK_ULONG      ulRandomLen;
8217 +  CK_BYTE_PTR   pRandomA;
8218 +  CK_BYTE_PTR   pPrimeP;
8219 +  CK_BYTE_PTR   pBaseG;
8220 +  CK_BYTE_PTR   pSubprimeQ;
8221 +} CK_SKIPJACK_PRIVATE_WRAP_PARAMS;
8222 +
8223 +typedef CK_SKIPJACK_PRIVATE_WRAP_PARAMS CK_PTR \
8224 +  CK_SKIPJACK_PRIVATE_WRAP_PTR;
8225 +
8226 +
8227 +/* CK_SKIPJACK_RELAYX_PARAMS provides the parameters to the
8228 + * CKM_SKIPJACK_RELAYX mechanism */
8229 +/* CK_SKIPJACK_RELAYX_PARAMS is new for v2.0 */
8230 +typedef struct CK_SKIPJACK_RELAYX_PARAMS {
8231 +  CK_ULONG      ulOldWrappedXLen;
8232 +  CK_BYTE_PTR   pOldWrappedX;
8233 +  CK_ULONG      ulOldPasswordLen;
8234 +  CK_BYTE_PTR   pOldPassword;
8235 +  CK_ULONG      ulOldPublicDataLen;
8236 +  CK_BYTE_PTR   pOldPublicData;
8237 +  CK_ULONG      ulOldRandomLen;
8238 +  CK_BYTE_PTR   pOldRandomA;
8239 +  CK_ULONG      ulNewPasswordLen;
8240 +  CK_BYTE_PTR   pNewPassword;
8241 +  CK_ULONG      ulNewPublicDataLen;
8242 +  CK_BYTE_PTR   pNewPublicData;
8243 +  CK_ULONG      ulNewRandomLen;
8244 +  CK_BYTE_PTR   pNewRandomA;
8245 +} CK_SKIPJACK_RELAYX_PARAMS;
8246 +
8247 +typedef CK_SKIPJACK_RELAYX_PARAMS CK_PTR \
8248 +  CK_SKIPJACK_RELAYX_PARAMS_PTR;
8249 +
8250 +
8251 +typedef struct CK_PBE_PARAMS {
8252 +  CK_BYTE_PTR      pInitVector;
8253 +  CK_UTF8CHAR_PTR  pPassword;
8254 +  CK_ULONG         ulPasswordLen;
8255 +  CK_BYTE_PTR      pSalt;
8256 +  CK_ULONG         ulSaltLen;
8257 +  CK_ULONG         ulIteration;
8258 +} CK_PBE_PARAMS;
8259 +
8260 +typedef CK_PBE_PARAMS CK_PTR CK_PBE_PARAMS_PTR;
8261 +
8262 +
8263 +/* CK_KEY_WRAP_SET_OAEP_PARAMS provides the parameters to the
8264 + * CKM_KEY_WRAP_SET_OAEP mechanism */
8265 +/* CK_KEY_WRAP_SET_OAEP_PARAMS is new for v2.0 */
8266 +typedef struct CK_KEY_WRAP_SET_OAEP_PARAMS {
8267 +  CK_BYTE       bBC;     /* block contents byte */
8268 +  CK_BYTE_PTR   pX;      /* extra data */
8269 +  CK_ULONG      ulXLen;  /* length of extra data in bytes */
8270 +} CK_KEY_WRAP_SET_OAEP_PARAMS;
8271 +
8272 +typedef CK_KEY_WRAP_SET_OAEP_PARAMS CK_PTR \
8273 +  CK_KEY_WRAP_SET_OAEP_PARAMS_PTR;
8274 +
8275 +
8276 +typedef struct CK_SSL3_RANDOM_DATA {
8277 +  CK_BYTE_PTR  pClientRandom;
8278 +  CK_ULONG     ulClientRandomLen;
8279 +  CK_BYTE_PTR  pServerRandom;
8280 +  CK_ULONG     ulServerRandomLen;
8281 +} CK_SSL3_RANDOM_DATA;
8282 +
8283 +
8284 +typedef struct CK_SSL3_MASTER_KEY_DERIVE_PARAMS {
8285 +  CK_SSL3_RANDOM_DATA RandomInfo;
8286 +  CK_VERSION_PTR pVersion;
8287 +} CK_SSL3_MASTER_KEY_DERIVE_PARAMS;
8288 +
8289 +typedef struct CK_SSL3_MASTER_KEY_DERIVE_PARAMS CK_PTR \
8290 +  CK_SSL3_MASTER_KEY_DERIVE_PARAMS_PTR;
8291 +
8292 +
8293 +typedef struct CK_SSL3_KEY_MAT_OUT {
8294 +  CK_OBJECT_HANDLE hClientMacSecret;
8295 +  CK_OBJECT_HANDLE hServerMacSecret;
8296 +  CK_OBJECT_HANDLE hClientKey;
8297 +  CK_OBJECT_HANDLE hServerKey;
8298 +  CK_BYTE_PTR      pIVClient;
8299 +  CK_BYTE_PTR      pIVServer;
8300 +} CK_SSL3_KEY_MAT_OUT;
8301 +
8302 +typedef CK_SSL3_KEY_MAT_OUT CK_PTR CK_SSL3_KEY_MAT_OUT_PTR;
8303 +
8304 +
8305 +typedef struct CK_SSL3_KEY_MAT_PARAMS {
8306 +  CK_ULONG                ulMacSizeInBits;
8307 +  CK_ULONG                ulKeySizeInBits;
8308 +  CK_ULONG                ulIVSizeInBits;
8309 +  CK_BBOOL                bIsExport;
8310 +  CK_SSL3_RANDOM_DATA     RandomInfo;
8311 +  CK_SSL3_KEY_MAT_OUT_PTR pReturnedKeyMaterial;
8312 +} CK_SSL3_KEY_MAT_PARAMS;
8313 +
8314 +typedef CK_SSL3_KEY_MAT_PARAMS CK_PTR CK_SSL3_KEY_MAT_PARAMS_PTR;
8315 +
8316 +/* CK_TLS_PRF_PARAMS is new for version 2.20 */
8317 +typedef struct CK_TLS_PRF_PARAMS {
8318 +  CK_BYTE_PTR  pSeed;
8319 +  CK_ULONG     ulSeedLen;
8320 +  CK_BYTE_PTR  pLabel;
8321 +  CK_ULONG     ulLabelLen;
8322 +  CK_BYTE_PTR  pOutput;
8323 +  CK_ULONG_PTR pulOutputLen;
8324 +} CK_TLS_PRF_PARAMS;
8325 +
8326 +typedef CK_TLS_PRF_PARAMS CK_PTR CK_TLS_PRF_PARAMS_PTR;
8327 +
8328 +/* WTLS is new for version 2.20 */
8329 +typedef struct CK_WTLS_RANDOM_DATA {
8330 +  CK_BYTE_PTR pClientRandom;
8331 +  CK_ULONG    ulClientRandomLen;
8332 +  CK_BYTE_PTR pServerRandom;
8333 +  CK_ULONG    ulServerRandomLen;
8334 +} CK_WTLS_RANDOM_DATA;
8335 +
8336 +typedef CK_WTLS_RANDOM_DATA CK_PTR CK_WTLS_RANDOM_DATA_PTR;
8337 +
8338 +typedef struct CK_WTLS_MASTER_KEY_DERIVE_PARAMS {
8339 +  CK_MECHANISM_TYPE   DigestMechanism;
8340 +  CK_WTLS_RANDOM_DATA RandomInfo;
8341 +  CK_BYTE_PTR         pVersion;
8342 +} CK_WTLS_MASTER_KEY_DERIVE_PARAMS;
8343 +
8344 +typedef CK_WTLS_MASTER_KEY_DERIVE_PARAMS CK_PTR \
8345 +  CK_WTLS_MASTER_KEY_DERIVE_PARAMS_PTR;
8346 +
8347 +typedef struct CK_WTLS_PRF_PARAMS {
8348 +  CK_MECHANISM_TYPE DigestMechanism;
8349 +  CK_BYTE_PTR       pSeed;
8350 +  CK_ULONG          ulSeedLen;
8351 +  CK_BYTE_PTR       pLabel;
8352 +  CK_ULONG          ulLabelLen;
8353 +  CK_BYTE_PTR       pOutput;
8354 +  CK_ULONG_PTR      pulOutputLen;
8355 +} CK_WTLS_PRF_PARAMS;
8356 +
8357 +typedef CK_WTLS_PRF_PARAMS CK_PTR CK_WTLS_PRF_PARAMS_PTR;
8358 +
8359 +typedef struct CK_WTLS_KEY_MAT_OUT {
8360 +  CK_OBJECT_HANDLE hMacSecret;
8361 +  CK_OBJECT_HANDLE hKey;
8362 +  CK_BYTE_PTR      pIV;
8363 +} CK_WTLS_KEY_MAT_OUT;
8364 +
8365 +typedef CK_WTLS_KEY_MAT_OUT CK_PTR CK_WTLS_KEY_MAT_OUT_PTR;
8366 +
8367 +typedef struct CK_WTLS_KEY_MAT_PARAMS {
8368 +  CK_MECHANISM_TYPE       DigestMechanism;
8369 +  CK_ULONG                ulMacSizeInBits;
8370 +  CK_ULONG                ulKeySizeInBits;
8371 +  CK_ULONG                ulIVSizeInBits;
8372 +  CK_ULONG                ulSequenceNumber;
8373 +  CK_BBOOL                bIsExport;
8374 +  CK_WTLS_RANDOM_DATA     RandomInfo;
8375 +  CK_WTLS_KEY_MAT_OUT_PTR pReturnedKeyMaterial;
8376 +} CK_WTLS_KEY_MAT_PARAMS;
8377 +
8378 +typedef CK_WTLS_KEY_MAT_PARAMS CK_PTR CK_WTLS_KEY_MAT_PARAMS_PTR;
8379 +
8380 +/* CMS is new for version 2.20 */
8381 +typedef struct CK_CMS_SIG_PARAMS {
8382 +  CK_OBJECT_HANDLE      certificateHandle;
8383 +  CK_MECHANISM_PTR      pSigningMechanism;
8384 +  CK_MECHANISM_PTR      pDigestMechanism;
8385 +  CK_UTF8CHAR_PTR       pContentType;
8386 +  CK_BYTE_PTR           pRequestedAttributes;
8387 +  CK_ULONG              ulRequestedAttributesLen;
8388 +  CK_BYTE_PTR           pRequiredAttributes;
8389 +  CK_ULONG              ulRequiredAttributesLen;
8390 +} CK_CMS_SIG_PARAMS;
8391 +
8392 +typedef CK_CMS_SIG_PARAMS CK_PTR CK_CMS_SIG_PARAMS_PTR;
8393 +
8394 +typedef struct CK_KEY_DERIVATION_STRING_DATA {
8395 +  CK_BYTE_PTR pData;
8396 +  CK_ULONG    ulLen;
8397 +} CK_KEY_DERIVATION_STRING_DATA;
8398 +
8399 +typedef CK_KEY_DERIVATION_STRING_DATA CK_PTR \
8400 +  CK_KEY_DERIVATION_STRING_DATA_PTR;
8401 +
8402 +
8403 +/* The CK_EXTRACT_PARAMS is used for the
8404 + * CKM_EXTRACT_KEY_FROM_KEY mechanism.  It specifies which bit
8405 + * of the base key should be used as the first bit of the
8406 + * derived key */
8407 +/* CK_EXTRACT_PARAMS is new for v2.0 */
8408 +typedef CK_ULONG CK_EXTRACT_PARAMS;
8409 +
8410 +typedef CK_EXTRACT_PARAMS CK_PTR CK_EXTRACT_PARAMS_PTR;
8411 +
8412 +/* CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE is new for v2.10.
8413 + * CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE is used to
8414 + * indicate the Pseudo-Random Function (PRF) used to generate
8415 + * key bits using PKCS #5 PBKDF2. */
8416 +typedef CK_ULONG CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE;
8417 +
8418 +typedef CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE CK_PTR CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE_PTR;
8419 +
8420 +/* The following PRFs are defined in PKCS #5 v2.0. */
8421 +#define CKP_PKCS5_PBKD2_HMAC_SHA1 0x00000001
8422 +
8423 +
8424 +/* CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE is new for v2.10.
8425 + * CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE is used to indicate the
8426 + * source of the salt value when deriving a key using PKCS #5
8427 + * PBKDF2. */
8428 +typedef CK_ULONG CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE;
8429 +
8430 +typedef CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE CK_PTR CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE_PTR;
8431 +
8432 +/* The following salt value sources are defined in PKCS #5 v2.0. */
8433 +#define CKZ_SALT_SPECIFIED        0x00000001
8434 +
8435 +/* CK_PKCS5_PBKD2_PARAMS is new for v2.10.
8436 + * CK_PKCS5_PBKD2_PARAMS is a structure that provides the
8437 + * parameters to the CKM_PKCS5_PBKD2 mechanism. */
8438 +typedef struct CK_PKCS5_PBKD2_PARAMS {
8439 +        CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE           saltSource;
8440 +        CK_VOID_PTR                                pSaltSourceData;
8441 +        CK_ULONG                                   ulSaltSourceDataLen;
8442 +        CK_ULONG                                   iterations;
8443 +        CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE prf;
8444 +        CK_VOID_PTR                                pPrfData;
8445 +        CK_ULONG                                   ulPrfDataLen;
8446 +        CK_UTF8CHAR_PTR                            pPassword;
8447 +        CK_ULONG_PTR                               ulPasswordLen;
8448 +} CK_PKCS5_PBKD2_PARAMS;
8449 +
8450 +typedef CK_PKCS5_PBKD2_PARAMS CK_PTR CK_PKCS5_PBKD2_PARAMS_PTR;
8451 +
8452 +#endif
8453 diff -r -u -N openssl-0.9.8g/demos/easy_tls/cacerts.pem openssl/demos/easy_tls/cacerts.pem
8454 --- openssl-0.9.8g/demos/easy_tls/cacerts.pem   2001-09-17 21:06:57.000000000 +0200
8455 +++ openssl/demos/easy_tls/cacerts.pem  2007-10-25 01:27:09.000000000 +0200
8456 @@ -1,4 +1,4 @@
8457 -$Id: openssl-0.9.8g-patch,v 1.2 2008/03/31 14:42:50 fdupont Exp $
8458 +$Id: openssl-0.9.8g-patch,v 1.2 2008/03/31 14:42:50 fdupont Exp $
8459  
8460  issuer= /C=AU/ST=Queensland/O=CryptSoft Pty Ltd/CN=Test PCA (1024 bit)
8461  subject=/C=AU/ST=Queensland/O=CryptSoft Pty Ltd/CN=Test CA (1024 bit)
8462 diff -r -u -N openssl-0.9.8g/demos/easy_tls/cert.pem openssl/demos/easy_tls/cert.pem
8463 --- openssl-0.9.8g/demos/easy_tls/cert.pem      2001-09-17 21:06:57.000000000 +0200
8464 +++ openssl/demos/easy_tls/cert.pem     2007-10-25 01:27:09.000000000 +0200
8465 @@ -1,4 +1,4 @@
8466 -$Id: openssl-0.9.8g-patch,v 1.2 2008/03/31 14:42:50 fdupont Exp $
8467 +$Id: openssl-0.9.8g-patch,v 1.2 2008/03/31 14:42:50 fdupont Exp $
8468  
8469  Example certificate and key.
8470  
8471 diff -r -u -N openssl-0.9.8g/demos/easy_tls/easy-tls.c openssl/demos/easy_tls/easy-tls.c
8472 --- openssl-0.9.8g/demos/easy_tls/easy-tls.c    2002-03-05 10:07:16.000000000 +0100
8473 +++ openssl/demos/easy_tls/easy-tls.c   2007-10-25 01:27:09.000000000 +0200
8474 @@ -1,7 +1,7 @@
8475  /* -*- Mode: C; c-file-style: "bsd" -*- */
8476  /*
8477   * easy-tls.c -- generic TLS proxy.
8478 - * $Id: openssl-0.9.8g-patch,v 1.2 2008/03/31 14:42:50 fdupont Exp $
8479 + * $Id: openssl-0.9.8g-patch,v 1.2 2008/03/31 14:42:50 fdupont Exp $
8480   */
8481  /*
8482   (c) Copyright 1999 Bodo Moeller.  All rights reserved.
8483 @@ -73,7 +73,7 @@
8484   */
8485  
8486  static char const rcsid[] =
8487 -"$Id: openssl-0.9.8g-patch,v 1.2 2008/03/31 14:42:50 fdupont Exp $";
8488 +"$Id: openssl-0.9.8g-patch,v 1.2 2008/03/31 14:42:50 fdupont Exp $";
8489  
8490  #include <assert.h>
8491  #include <errno.h>
8492 diff -r -u -N openssl-0.9.8g/demos/easy_tls/easy-tls.h openssl/demos/easy_tls/easy-tls.h
8493 --- openssl-0.9.8g/demos/easy_tls/easy-tls.h    2001-09-17 21:06:59.000000000 +0200
8494 +++ openssl/demos/easy_tls/easy-tls.h   2007-10-25 01:27:09.000000000 +0200
8495 @@ -1,7 +1,7 @@
8496  /* -*- Mode: C; c-file-style: "bsd" -*- */
8497  /*
8498   * easy-tls.h -- generic TLS proxy.
8499 - * $Id: openssl-0.9.8g-patch,v 1.2 2008/03/31 14:42:50 fdupont Exp $
8500 + * $Id: openssl-0.9.8g-patch,v 1.2 2008/03/31 14:42:50 fdupont Exp $
8501   */
8502  /*
8503   * (c) Copyright 1999 Bodo Moeller.  All rights reserved.
8504 diff -r -u -N openssl-0.9.8g/demos/easy_tls/Makefile openssl/demos/easy_tls/Makefile
8505 --- openssl-0.9.8g/demos/easy_tls/Makefile      2001-09-18 11:15:40.000000000 +0200
8506 +++ openssl/demos/easy_tls/Makefile     2007-10-25 01:27:09.000000000 +0200
8507 @@ -1,5 +1,5 @@
8508  # Makefile for easy-tls example application (rudimentary client and server)
8509 -# $Id: openssl-0.9.8g-patch,v 1.2 2008/03/31 14:42:50 fdupont Exp $
8510 +# $Id: openssl-0.9.8g-patch,v 1.2 2008/03/31 14:42:50 fdupont Exp $
8511  
8512  SOLARIS_CFLAGS=-Wall -pedantic -g -O2
8513  SOLARIS_LIBS=-lxnet
8514 diff -r -u -N openssl-0.9.8g/demos/easy_tls/test.c openssl/demos/easy_tls/test.c
8515 --- openssl-0.9.8g/demos/easy_tls/test.c        2001-09-17 21:06:59.000000000 +0200
8516 +++ openssl/demos/easy_tls/test.c       2007-10-25 01:27:09.000000000 +0200
8517 @@ -1,5 +1,5 @@
8518  /* test.c */
8519 -/* $Id: openssl-0.9.8g-patch,v 1.2 2008/03/31 14:42:50 fdupont Exp $ */
8520 +/* $Id: openssl-0.9.8g-patch,v 1.2 2008/03/31 14:42:50 fdupont Exp $ */
8521  
8522  #define L_PORT 9999
8523  #define C_PORT 443
8524 diff -r -u -N openssl-0.9.8g/demos/easy_tls/test.h openssl/demos/easy_tls/test.h
8525 --- openssl-0.9.8g/demos/easy_tls/test.h        2001-09-17 21:07:00.000000000 +0200
8526 +++ openssl/demos/easy_tls/test.h       2007-10-25 01:27:09.000000000 +0200
8527 @@ -1,5 +1,5 @@
8528  /* test.h */
8529 -/* $Id: openssl-0.9.8g-patch,v 1.2 2008/03/31 14:42:50 fdupont Exp $ */
8530 +/* $Id: openssl-0.9.8g-patch,v 1.2 2008/03/31 14:42:50 fdupont Exp $ */
8531  
8532  
8533  void test_process_init(int fd, int client_p, void *apparg);
8534 diff -r -u -N openssl-0.9.8g/engines/vendor_defns/hwcryptohook.h openssl/engines/vendor_defns/hwcryptohook.h
8535 --- openssl-0.9.8g/engines/vendor_defns/hwcryptohook.h  2002-10-11 19:10:59.000000000 +0200
8536 +++ openssl/engines/vendor_defns/hwcryptohook.h 2007-10-25 01:27:09.000000000 +0200
8537 @@ -65,7 +65,7 @@
8538   * please contact nCipher.
8539   *
8540   *
8541 - * $Id: openssl-0.9.8g-patch,v 1.2 2008/03/31 14:42:50 fdupont Exp $
8542 + * $Id: openssl-0.9.8g-patch,v 1.2 2008/03/31 14:42:50 fdupont Exp $
8543   */
8544  
8545  #ifndef HWCRYPTOHOOK_H
8546 diff -r -u -N openssl-0.9.8g/Makefile.org openssl/Makefile.org
8547 --- openssl-0.9.8g/Makefile.org 2007-04-24 01:49:54.000000000 +0200
8548 +++ openssl/Makefile.org        2007-10-25 01:27:08.000000000 +0200
8549 @@ -26,6 +26,9 @@
8550  INSTALL_PREFIX=
8551  INSTALLTOP=/usr/local/ssl
8552  
8553 +# You must set this through --pk11-libname configure option.
8554 +PK11_LIB_LOCATION=
8555 +
8556  # Do not edit this manually. Use Configure --openssldir=DIR do change this!
8557  OPENSSLDIR=/usr/local/ssl
8558  
8559 diff -r -u -N openssl-0.9.8g/README.pkcs11 openssl/README.pkcs11
8560 --- openssl-0.9.8g/README.pkcs11        1970-01-01 01:00:00.000000000 +0100
8561 +++ openssl/README.pkcs11       2008-01-31 15:24:32.000000000 +0100
8562 @@ -0,0 +1,153 @@
8563 +PKCS#11 engine support for OpenSSL 0.9.8g
8564 +=========================================
8565 +
8566 +[Nov 21, 2007]
8567 +
8568 +This patch containing code available in OpenSolaris adds support for PKCS#11
8569 +engine into OpenSSL and implements PKCS#11 v2.20. It is to be applied against
8570 +OpenSSL 0.9.8g. Your system must provide PKCS#11 backend otherwise the patch
8571 +is useless.
8572 +
8573 +Patch can be applied like this:
8574 +
8575 +       tar xfzv openssl-0.9.8g.tar.gz
8576 +       cd openssl-0.9.8g
8577 +       patch -p1 < ../pkcs11_engine-0.9.8g.patch.2007-11-21
8578 +
8579 +It is designed to support pure acceleration for RSA, DSA, DH and all the
8580 +symetric ciphers and message digest algorithms that PKCS#11 and OpenSSL share
8581 +except for missing support for patented algorithms MDC2, RC3, RC5 and IDEA.
8582 +
8583 +It also contains experimental code for accessing RSA keys stored in pkcs#11 key
8584 +stores by reference. See below for more information.
8585 +
8586 +You must provide the location of PKCS#11 library in your system to the
8587 +configure script, eg. if you use libraries from openCryptoki project on Linux
8588 +AMD64 box, run configure like this:
8589 +
8590 +       ./config --pk11-libname=/usr/lib64/pkcs11/PKCS11_API.so
8591 +
8592 +To check whether newly built openssl really supports PKCS#11 it's enough to
8593 +run "apps/openssl engine" and look for "(pkcs11) PKCS #11 engine support" in
8594 +the output.
8595 +
8596 +This patch was tested on Solaris against PKCS#11 engine available from Solaris
8597 +Cryptographic Framework (Solaris 10 and OpenSolaris) and also on Linux using
8598 +PKCS#11 libraries from openCryptoki project (see openCryptoki website
8599 +http://sourceforge.net/projects/opencryptoki for more information). Some Linux
8600 +distributions even ship those libraries with the system. The patch should work
8601 +on any system that is supported by OpenSSL itself and has functional PKCS#11
8602 +library.
8603 +
8604 +The patch contains "RSA Security Inc. PKCS #11 Cryptographic Token Interface
8605 +(Cryptoki)" - files cryptoki.h, pkcs11.h, pkcs11f.h and pkcs11t.h which are
8606 +copyrighted by RSA Security Inc., see pkcs11.h for more information.
8607 +
8608 +Other added/modified code in this patch is copyrighted by Sun Microsystems,
8609 +Inc. and is released under the OpenSSL license (see LICENSE file for more
8610 +information).
8611 +
8612 +Revisions of patch for 0.9.8 branch
8613 +===================================
8614 +
8615 +2007-11-21
8616 +- update for 0.9.8g version 
8617 +- fixes in the draft code for "6607670 teach pkcs#11 engine how to use keys
8618 +  be reference" so that it doesn't coredump when the referenced key is not
8619 +  present
8620 +
8621 +2007-10-15
8622 +- update for 0.9.8f version 
8623 +- update for "6607670 teach pkcs#11 engine how to use keys be reference"
8624 +
8625 +2007-10-02
8626 +- draft for "6607670 teach pkcs#11 engine how to use keys be reference"
8627 +- draft for "6607307 pkcs#11 engine can't read RSA private keys"
8628 +
8629 +2007-09-26
8630 +- 6375348 Using pkcs11 as the SSLCryptoDevice with Apache/OpenSSL causes
8631 +         significant performance drop
8632 +- 6573196 memory is leaked when OpenSSL is used with PKCS#11 engine
8633 +
8634 +2007-05-25
8635 +- 6558630 race in OpenSSL pkcs11 engine when using symetric block ciphers
8636 +
8637 +2007-05-19
8638 +- initial patch for 0.9.8e using latest OpenSolaris code
8639 +
8640 +Notes
8641 +=====
8642 +
8643 +This patch version contains not very well tested code for referencing RSA keys
8644 +in keystores by labels. That code might and might not end up in OpenSolaris
8645 +code base in the future. If you use this particular functionality with this
8646 +patch I would be very grateful to get any feedback from you (please see my
8647 +contact in the bottom).
8648 +
8649 +Issues
8650 +------
8651 +- can't reference public keys inside of certificates using certificate label
8652 +- can't reference symetric keys
8653 +- simple references in form of "pkcs11:LABEL" only are supported now. This is
8654 +  supposed to be changed according to discussion on pkcs11 mailing list; comma
8655 +  separated list of attributes is planned to be used.
8656 +- getpassphrase(3c) is used for entering the PIN. This should be changed to a
8657 +  more general approach; to check if the process has allocated tty and use
8658 +  other means of entering the PIN if not.
8659 +
8660 +Usage
8661 +-----
8662 +See examples below using Solaris's pktool(1):
8663 +
8664 +# list private keys (note "mycert" label. Basically, we can't generate a
8665 +# pub/priv key pair with pktool(1) without creating a certificate. This should
8666 +# be changed in the future).
8667 +$ pktool list objtype=private
8668 +Enter PIN for Sun Software PKCS#11 softtoken  : 
8669 +Found 1 keys.
8670 +Key #1 - RSA private key:  mycert
8671 +
8672 +# this file is going to be signed
8673 +$ cat test
8674 +hello
8675 +
8676 +# sign it, note "pkcs11:mycert" private key's label
8677 +$ openssl rsautl -inkey pkcs11:mycert -out test2 -in test -sign -keyform e -engine pkcs11
8678 +engine "pkcs11" set.
8679 +Enter PIN:
8680 +
8681 +# export the certificate out of the keyring
8682 +$ pktool export keystore=pkcs11 label=mycert outfile=mycert.cert outformat=pem
8683 +Warning: file "mycert.cert" exists, will be overwritten.
8684 +Continue with export? y
8685 +
8686 +# verify using OpenSSL without pkcs#11 engine and with the certificate in the
8687 +# file. This is proof of concept that a file signed with key by reference is
8688 +# successfully verified when stock OpenSSL is used (I didn't have public key
8689 +# in the keystore, only the certificate. There is no way to reference a public
8690 +# key inside of the certificate).
8691 +$ openssl rsautl -verify -inkey mycert.cert -certin -in test2
8692 +hello
8693 +
8694 +API
8695 +---
8696 +You can use ENGINE_load_public_key() and ENGINE_load_private_key() functions
8697 +only. The 2nd parameter of those calls is the one to use for "pkcs11:LABEL"
8698 +filename overloading. If used that way, both functions will look for the key
8699 +in the available keystores. Only one such key must be present. The private key
8700 +is never extracted from the keystore. See OpenSSL's engine(3) or header file
8701 +openssl/engine.h for more information.
8702 +
8703 +Note that those functions return a pointer to EVP_PKEY structure that contains
8704 +all necessary information for accesing the key by label then. The pointer can be
8705 +used in other functions that work with RSA keys - X509_sign() for example. See
8706 +source code in apps/ subdirectory for reference.
8707 +
8708 +Feedback
8709 +========
8710 +
8711 +Please send feedback to security-discuss@opensolaris.org. The patch was
8712 +created by Jan.Pechanec@Sun.COM from code available in OpenSolaris.
8713 +
8714 +Latest version should be always available on http://blogs.sun.com/janp.
8715 +