1 /* |
|
2 * Copyright (c) 2004, 2014, Oracle and/or its affiliates. All rights reserved. |
|
3 * |
|
4 */ |
|
5 |
|
6 /* crypto/engine/e_pk11_pub.c */ |
|
7 /* |
|
8 * This product includes software developed by the OpenSSL Project for |
|
9 * use in the OpenSSL Toolkit (http://www.openssl.org/). |
|
10 * |
|
11 * This project also referenced hw_pkcs11-0.9.7b.patch written by |
|
12 * Afchine Madjlessi. |
|
13 */ |
|
14 /* |
|
15 * ==================================================================== |
|
16 * Copyright (c) 2000-2001 The OpenSSL Project. All rights reserved. |
|
17 * |
|
18 * Redistribution and use in source and binary forms, with or without |
|
19 * modification, are permitted provided that the following conditions |
|
20 * are met: |
|
21 * |
|
22 * 1. Redistributions of source code must retain the above copyright |
|
23 * notice, this list of conditions and the following disclaimer. |
|
24 * |
|
25 * 2. Redistributions in binary form must reproduce the above copyright |
|
26 * notice, this list of conditions and the following disclaimer in |
|
27 * the documentation and/or other materials provided with the |
|
28 * distribution. |
|
29 * |
|
30 * 3. All advertising materials mentioning features or use of this |
|
31 * software must display the following acknowledgment: |
|
32 * "This product includes software developed by the OpenSSL Project |
|
33 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" |
|
34 * |
|
35 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to |
|
36 * endorse or promote products derived from this software without |
|
37 * prior written permission. For written permission, please contact |
|
38 * [email protected]. |
|
39 * |
|
40 * 5. Products derived from this software may not be called "OpenSSL" |
|
41 * nor may "OpenSSL" appear in their names without prior written |
|
42 * permission of the OpenSSL Project. |
|
43 * |
|
44 * 6. Redistributions of any form whatsoever must retain the following |
|
45 * acknowledgment: |
|
46 * "This product includes software developed by the OpenSSL Project |
|
47 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" |
|
48 * |
|
49 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY |
|
50 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
|
51 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
|
52 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR |
|
53 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
|
54 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
|
55 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
|
56 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
|
57 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, |
|
58 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
|
59 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED |
|
60 * OF THE POSSIBILITY OF SUCH DAMAGE. |
|
61 * ==================================================================== |
|
62 * |
|
63 * This product includes cryptographic software written by Eric Young |
|
64 * ([email protected]). This product includes software written by Tim |
|
65 * Hudson ([email protected]). |
|
66 * |
|
67 */ |
|
68 |
|
69 #include <stdio.h> |
|
70 #include <stdlib.h> |
|
71 #include <string.h> |
|
72 #include <sys/types.h> |
|
73 #include <unistd.h> |
|
74 #include <strings.h> |
|
75 |
|
76 #include <openssl/e_os2.h> |
|
77 #include <openssl/crypto.h> |
|
78 #include <openssl/engine.h> |
|
79 #include <openssl/dso.h> |
|
80 #include <openssl/err.h> |
|
81 #include <openssl/bn.h> |
|
82 #include <openssl/pem.h> |
|
83 #ifndef OPENSSL_NO_RSA |
|
84 #include <openssl/rsa.h> |
|
85 #endif /* OPENSSL_NO_RSA */ |
|
86 #ifndef OPENSSL_NO_DSA |
|
87 #include <openssl/dsa.h> |
|
88 #endif /* OPENSSL_NO_DSA */ |
|
89 #ifndef OPENSSL_NO_DH |
|
90 #include <openssl/dh.h> |
|
91 #endif /* OPENSSL_NO_DH */ |
|
92 #include <openssl/rand.h> |
|
93 #include <openssl/objects.h> |
|
94 #include <openssl/x509.h> |
|
95 #include <pthread.h> |
|
96 #include <libgen.h> |
|
97 |
|
98 #ifndef OPENSSL_NO_HW |
|
99 #ifndef OPENSSL_NO_HW_PK11 |
|
100 |
|
101 #include <security/cryptoki.h> |
|
102 #include <security/pkcs11.h> |
|
103 #include "e_pk11.h" |
|
104 #include "e_pk11_uri.h" |
|
105 |
|
106 static CK_BBOOL pk11_login_done = CK_FALSE; |
|
107 extern CK_SLOT_ID pubkey_SLOTID; |
|
108 |
|
109 /* |
|
110 * During the reinitialization after a detected fork we will try to login to the |
|
111 * token using the passphrasedialog keyword that we inherit from the parent. |
|
112 */ |
|
113 char *passphrasedialog; |
|
114 |
|
115 #ifndef OPENSSL_NO_RSA |
|
116 /* RSA stuff */ |
|
117 static int pk11_RSA_public_encrypt(int flen, const unsigned char *from, |
|
118 unsigned char *to, RSA *rsa, int padding); |
|
119 static int pk11_RSA_private_encrypt(int flen, const unsigned char *from, |
|
120 unsigned char *to, RSA *rsa, int padding); |
|
121 static int pk11_RSA_public_decrypt(int flen, const unsigned char *from, |
|
122 unsigned char *to, RSA *rsa, int padding); |
|
123 static int pk11_RSA_private_decrypt(int flen, const unsigned char *from, |
|
124 unsigned char *to, RSA *rsa, int padding); |
|
125 static int pk11_RSA_init(RSA *rsa); |
|
126 static int pk11_RSA_finish(RSA *rsa); |
|
127 static int pk11_RSA_sign(int type, const unsigned char *m, unsigned int m_len, |
|
128 unsigned char *sigret, unsigned int *siglen, const RSA *rsa); |
|
129 static int pk11_RSA_verify(int dtype, const unsigned char *m, |
|
130 unsigned int m_len, unsigned char *sigbuf, unsigned int siglen, |
|
131 const RSA *rsa); |
|
132 EVP_PKEY *pk11_load_privkey(ENGINE*, const char *privkey_id, |
|
133 UI_METHOD *ui_method, void *callback_data); |
|
134 EVP_PKEY *pk11_load_pubkey(ENGINE*, const char *pubkey_id, |
|
135 UI_METHOD *ui_method, void *callback_data); |
|
136 |
|
137 static int pk11_RSA_public_encrypt_low(int flen, const unsigned char *from, |
|
138 unsigned char *to, RSA *rsa); |
|
139 static int pk11_RSA_private_encrypt_low(int flen, const unsigned char *from, |
|
140 unsigned char *to, RSA *rsa); |
|
141 static int pk11_RSA_public_decrypt_low(int flen, const unsigned char *from, |
|
142 unsigned char *to, RSA *rsa); |
|
143 static int pk11_RSA_private_decrypt_low(int flen, const unsigned char *from, |
|
144 unsigned char *to, RSA *rsa); |
|
145 |
|
146 static CK_OBJECT_HANDLE pk11_get_public_rsa_key(RSA* rsa, PK11_SESSION *sp); |
|
147 static CK_OBJECT_HANDLE pk11_get_private_rsa_key(RSA* rsa, PK11_SESSION *sp); |
|
148 |
|
149 static int pk11_check_new_rsa_key_pub(PK11_SESSION *sp, const RSA *rsa); |
|
150 static int pk11_check_new_rsa_key_priv(PK11_SESSION *sp, const RSA *rsa); |
|
151 #endif |
|
152 |
|
153 /* DSA stuff */ |
|
154 #ifndef OPENSSL_NO_DSA |
|
155 static int pk11_DSA_init(DSA *dsa); |
|
156 static int pk11_DSA_finish(DSA *dsa); |
|
157 static DSA_SIG *pk11_dsa_do_sign(const unsigned char *dgst, int dlen, |
|
158 DSA *dsa); |
|
159 static int pk11_dsa_do_verify(const unsigned char *dgst, int dgst_len, |
|
160 DSA_SIG *sig, DSA *dsa); |
|
161 |
|
162 static CK_OBJECT_HANDLE pk11_get_public_dsa_key(DSA* dsa, DSA **key_ptr, |
|
163 BIGNUM **dsa_pub_num, CK_SESSION_HANDLE session); |
|
164 static CK_OBJECT_HANDLE pk11_get_private_dsa_key(DSA* dsa, DSA **key_ptr, |
|
165 BIGNUM **dsa_priv_num, CK_SESSION_HANDLE session); |
|
166 |
|
167 static int check_new_dsa_key_pub(PK11_SESSION *sp, DSA *dsa); |
|
168 static int check_new_dsa_key_priv(PK11_SESSION *sp, DSA *dsa); |
|
169 #endif |
|
170 |
|
171 /* DH stuff */ |
|
172 #ifndef OPENSSL_NO_DH |
|
173 static int pk11_DH_init(DH *dh); |
|
174 static int pk11_DH_finish(DH *dh); |
|
175 static int pk11_DH_generate_key(DH *dh); |
|
176 static int pk11_DH_compute_key(unsigned char *key, |
|
177 const BIGNUM *pub_key, DH *dh); |
|
178 |
|
179 static CK_OBJECT_HANDLE pk11_get_dh_key(DH* dh, DH **key_ptr, |
|
180 BIGNUM **priv_key, CK_SESSION_HANDLE session); |
|
181 |
|
182 static int check_new_dh_key(PK11_SESSION *sp, DH *dh); |
|
183 #endif |
|
184 |
|
185 static int find_one_object(PK11_OPTYPE op, CK_SESSION_HANDLE s, |
|
186 CK_ATTRIBUTE_PTR ptempl, CK_ULONG nattr, CK_OBJECT_HANDLE_PTR pkey); |
|
187 static int init_template_value(BIGNUM *bn, CK_VOID_PTR *pValue, |
|
188 CK_ULONG *ulValueLen); |
|
189 static void attr_to_BN(CK_ATTRIBUTE_PTR attr, CK_BYTE attr_data[], BIGNUM **bn); |
|
190 |
|
191 /* Read mode string to be used for fopen() */ |
|
192 #if SOLARIS_OPENSSL |
|
193 static char *read_mode_flags = "rF"; |
|
194 #else |
|
195 static char *read_mode_flags = "r"; |
|
196 #endif |
|
197 |
|
198 /* |
|
199 * Increment existing or create a new reference for an asymmetric key PKCS#11 |
|
200 * object handle in the active object list. If the operation fails, unlock (if |
|
201 * locked), set error variable and jump to the specified label. We use this list |
|
202 * so that we can track how many references to the PKCS#11 objects are used from |
|
203 * all our sessions structures. If we are replacing an object reference in the |
|
204 * session structure and the ref count for the reference being replaced gets to |
|
205 * 0 we know that we can safely free the object itself via C_ObjectDestroy(). |
|
206 * See also TRY_OBJ_DESTROY. |
|
207 */ |
|
208 #define KEY_HANDLE_REFHOLD(key_handle, alg_type, unlock, var, label) \ |
|
209 { \ |
|
210 if (pk11_active_add(key_handle, alg_type) < 0) \ |
|
211 { \ |
|
212 var = CK_TRUE; \ |
|
213 if (unlock) \ |
|
214 UNLOCK_OBJSTORE(alg_type); \ |
|
215 goto label; \ |
|
216 } \ |
|
217 } |
|
218 |
|
219 /* |
|
220 * Find active list entry according to object handle and return pointer to the |
|
221 * entry otherwise return NULL. |
|
222 * |
|
223 * This function presumes it is called with lock protecting the active list |
|
224 * held. |
|
225 */ |
|
226 static PK11_active *pk11_active_find(CK_OBJECT_HANDLE h, PK11_OPTYPE type) |
|
227 { |
|
228 PK11_active *entry; |
|
229 |
|
230 for (entry = active_list[type]; entry != NULL; entry = entry->next) |
|
231 if (entry->h == h) |
|
232 return (entry); |
|
233 |
|
234 return (NULL); |
|
235 } |
|
236 |
|
237 /* |
|
238 * Search for an entry in the active list using PKCS#11 object handle as a |
|
239 * search key and return refcnt of the found/created entry or -1 in case of |
|
240 * failure. |
|
241 * |
|
242 * This function presumes it is called with lock protecting the active list |
|
243 * held. |
|
244 */ |
|
245 int |
|
246 pk11_active_add(CK_OBJECT_HANDLE h, PK11_OPTYPE type) |
|
247 { |
|
248 PK11_active *entry = NULL; |
|
249 |
|
250 if (h == CK_INVALID_HANDLE) |
|
251 { |
|
252 PK11err(PK11_F_ACTIVE_ADD, PK11_R_INVALID_HANDLE); |
|
253 return (-1); |
|
254 } |
|
255 |
|
256 /* search for entry in the active list */ |
|
257 if ((entry = pk11_active_find(h, type)) != NULL) |
|
258 entry->refcnt++; |
|
259 else |
|
260 { |
|
261 /* not found, create new entry and add it to the list */ |
|
262 entry = OPENSSL_malloc(sizeof (PK11_active)); |
|
263 if (entry == NULL) |
|
264 { |
|
265 PK11err(PK11_F_ACTIVE_ADD, PK11_R_MALLOC_FAILURE); |
|
266 return (-1); |
|
267 } |
|
268 entry->h = h; |
|
269 entry->refcnt = 1; |
|
270 entry->prev = NULL; |
|
271 entry->next = NULL; |
|
272 /* connect the newly created entry to the list */ |
|
273 if (active_list[type] == NULL) |
|
274 active_list[type] = entry; |
|
275 else /* make the entry first in the list */ |
|
276 { |
|
277 entry->next = active_list[type]; |
|
278 active_list[type]->prev = entry; |
|
279 active_list[type] = entry; |
|
280 } |
|
281 } |
|
282 |
|
283 return (entry->refcnt); |
|
284 } |
|
285 |
|
286 /* |
|
287 * Remove active list entry from the list and free it. |
|
288 * |
|
289 * This function presumes it is called with lock protecting the active list |
|
290 * held. |
|
291 */ |
|
292 void |
|
293 pk11_active_remove(PK11_active *entry, PK11_OPTYPE type) |
|
294 { |
|
295 PK11_active *prev_entry; |
|
296 |
|
297 /* remove the entry from the list and free it */ |
|
298 if ((prev_entry = entry->prev) != NULL) |
|
299 { |
|
300 prev_entry->next = entry->next; |
|
301 if (entry->next != NULL) |
|
302 entry->next->prev = prev_entry; |
|
303 } |
|
304 else |
|
305 { |
|
306 active_list[type] = entry->next; |
|
307 /* we were the first but not the only one */ |
|
308 if (entry->next != NULL) |
|
309 entry->next->prev = NULL; |
|
310 } |
|
311 |
|
312 /* sanitization */ |
|
313 entry->h = CK_INVALID_HANDLE; |
|
314 entry->prev = NULL; |
|
315 entry->next = NULL; |
|
316 OPENSSL_free(entry); |
|
317 } |
|
318 |
|
319 /* Free all entries from the active list. */ |
|
320 void |
|
321 pk11_free_active_list(PK11_OPTYPE type) |
|
322 { |
|
323 PK11_active *entry; |
|
324 |
|
325 /* only for asymmetric types since only they have C_Find* locks. */ |
|
326 switch (type) |
|
327 { |
|
328 case OP_RSA: |
|
329 case OP_DSA: |
|
330 case OP_DH: |
|
331 break; |
|
332 default: |
|
333 return; |
|
334 } |
|
335 |
|
336 /* see find_lock array definition for more info on object locking */ |
|
337 LOCK_OBJSTORE(type); |
|
338 while ((entry = active_list[type]) != NULL) |
|
339 pk11_active_remove(entry, type); |
|
340 UNLOCK_OBJSTORE(type); |
|
341 } |
|
342 |
|
343 /* |
|
344 * Search for active list entry associated with given PKCS#11 object handle, |
|
345 * decrement its refcnt and if it drops to 0, disconnect the entry and free it. |
|
346 * |
|
347 * Return 1 if the PKCS#11 object associated with the entry has no references, |
|
348 * return 0 if there is at least one reference, -1 on error. |
|
349 * |
|
350 * This function presumes it is called with lock protecting the active list |
|
351 * held. |
|
352 */ |
|
353 int |
|
354 pk11_active_delete(CK_OBJECT_HANDLE h, PK11_OPTYPE type) |
|
355 { |
|
356 PK11_active *entry = NULL; |
|
357 |
|
358 if ((entry = pk11_active_find(h, type)) == NULL) |
|
359 { |
|
360 PK11err(PK11_F_ACTIVE_DELETE, PK11_R_INVALID_HANDLE); |
|
361 return (-1); |
|
362 } |
|
363 |
|
364 OPENSSL_assert(entry->refcnt > 0); |
|
365 entry->refcnt--; |
|
366 if (entry->refcnt == 0) |
|
367 { |
|
368 pk11_active_remove(entry, type); |
|
369 return (1); |
|
370 } |
|
371 |
|
372 return (0); |
|
373 } |
|
374 |
|
375 #ifndef OPENSSL_NO_RSA |
|
376 /* Our internal RSA_METHOD that we provide pointers to */ |
|
377 static RSA_METHOD pk11_rsa = |
|
378 { |
|
379 "PKCS#11 RSA method", |
|
380 pk11_RSA_public_encrypt, /* rsa_pub_encrypt */ |
|
381 pk11_RSA_public_decrypt, /* rsa_pub_decrypt */ |
|
382 pk11_RSA_private_encrypt, /* rsa_priv_encrypt */ |
|
383 pk11_RSA_private_decrypt, /* rsa_priv_decrypt */ |
|
384 NULL, /* rsa_mod_exp */ |
|
385 NULL, /* bn_mod_exp */ |
|
386 pk11_RSA_init, /* init */ |
|
387 pk11_RSA_finish, /* finish */ |
|
388 RSA_FLAG_SIGN_VER, /* flags */ |
|
389 NULL, /* app_data */ |
|
390 pk11_RSA_sign, /* rsa_sign */ |
|
391 pk11_RSA_verify /* rsa_verify */ |
|
392 }; |
|
393 |
|
394 RSA_METHOD * |
|
395 PK11_RSA(void) |
|
396 { |
|
397 return (&pk11_rsa); |
|
398 } |
|
399 #endif |
|
400 |
|
401 #ifndef OPENSSL_NO_DSA |
|
402 /* Our internal DSA_METHOD that we provide pointers to */ |
|
403 static DSA_METHOD pk11_dsa = |
|
404 { |
|
405 "PKCS#11 DSA method", |
|
406 pk11_dsa_do_sign, /* dsa_do_sign */ |
|
407 NULL, /* dsa_sign_setup */ |
|
408 pk11_dsa_do_verify, /* dsa_do_verify */ |
|
409 NULL, /* dsa_mod_exp */ |
|
410 NULL, /* bn_mod_exp */ |
|
411 pk11_DSA_init, /* init */ |
|
412 pk11_DSA_finish, /* finish */ |
|
413 0, /* flags */ |
|
414 NULL /* app_data */ |
|
415 }; |
|
416 |
|
417 DSA_METHOD * |
|
418 PK11_DSA(void) |
|
419 { |
|
420 return (&pk11_dsa); |
|
421 } |
|
422 #endif |
|
423 |
|
424 #ifndef OPENSSL_NO_DH |
|
425 /* |
|
426 * PKCS #11 V2.20, section 11.2 specifies that the number of bytes needed for |
|
427 * output buffer may somewhat exceed the precise number of bytes needed, but |
|
428 * should not exceed it by a large amount. That may be caused, for example, by |
|
429 * rounding it up to multiple of X in the underlying bignum library. 8 should be |
|
430 * enough. |
|
431 */ |
|
432 #define DH_BUF_RESERVE 8 |
|
433 |
|
434 /* Our internal DH_METHOD that we provide pointers to */ |
|
435 static DH_METHOD pk11_dh = |
|
436 { |
|
437 "PKCS#11 DH method", |
|
438 pk11_DH_generate_key, /* generate_key */ |
|
439 pk11_DH_compute_key, /* compute_key */ |
|
440 NULL, /* bn_mod_exp */ |
|
441 pk11_DH_init, /* init */ |
|
442 pk11_DH_finish, /* finish */ |
|
443 0, /* flags */ |
|
444 NULL, /* app_data */ |
|
445 NULL /* generate_params */ |
|
446 }; |
|
447 |
|
448 DH_METHOD * |
|
449 PK11_DH(void) |
|
450 { |
|
451 return (&pk11_dh); |
|
452 } |
|
453 #endif |
|
454 |
|
455 /* Size of an SSL signature: MD5+SHA1 */ |
|
456 #define SSL_SIG_LENGTH 36 |
|
457 |
|
458 /* Lengths of DSA data and signature */ |
|
459 #define DSA_DATA_LEN 20 |
|
460 #define DSA_SIGNATURE_LEN 40 |
|
461 |
|
462 #ifndef OPENSSL_NO_RSA |
|
463 /* |
|
464 * Similiar to OpenSSL to take advantage of the paddings. The goal is to |
|
465 * support all paddings in this engine although PK11 library does not |
|
466 * support all the paddings used in OpenSSL. |
|
467 * The input errors should have been checked in the padding functions. |
|
468 */ |
|
469 static int pk11_RSA_public_encrypt(int flen, const unsigned char *from, |
|
470 unsigned char *to, RSA *rsa, int padding) |
|
471 { |
|
472 int i, num = 0, r = -1; |
|
473 unsigned char *buf = NULL; |
|
474 |
|
475 num = BN_num_bytes(rsa->n); |
|
476 if ((buf = (unsigned char *)OPENSSL_malloc(num)) == NULL) |
|
477 { |
|
478 PK11err(PK11_F_RSA_PUB_ENC, PK11_R_MALLOC_FAILURE); |
|
479 goto err; |
|
480 } |
|
481 |
|
482 switch (padding) |
|
483 { |
|
484 case RSA_PKCS1_PADDING: |
|
485 i = RSA_padding_add_PKCS1_type_2(buf, num, from, flen); |
|
486 break; |
|
487 #ifndef OPENSSL_NO_SHA |
|
488 case RSA_PKCS1_OAEP_PADDING: |
|
489 i = RSA_padding_add_PKCS1_OAEP(buf, num, from, flen, NULL, 0); |
|
490 break; |
|
491 #endif |
|
492 case RSA_SSLV23_PADDING: |
|
493 i = RSA_padding_add_SSLv23(buf, num, from, flen); |
|
494 break; |
|
495 case RSA_NO_PADDING: |
|
496 i = RSA_padding_add_none(buf, num, from, flen); |
|
497 break; |
|
498 default: |
|
499 PK11err(PK11_F_RSA_PUB_ENC, PK11_R_UNKNOWN_PADDING_TYPE); |
|
500 goto err; |
|
501 } |
|
502 if (i <= 0) goto err; |
|
503 |
|
504 /* PK11 functions are called here */ |
|
505 r = pk11_RSA_public_encrypt_low(num, buf, to, rsa); |
|
506 err: |
|
507 if (buf != NULL) |
|
508 { |
|
509 OPENSSL_cleanse(buf, num); |
|
510 OPENSSL_free(buf); |
|
511 } |
|
512 return (r); |
|
513 } |
|
514 |
|
515 |
|
516 /* |
|
517 * Similar to Openssl to take advantage of the paddings. The input errors |
|
518 * should be catched in the padding functions |
|
519 */ |
|
520 static int pk11_RSA_private_encrypt(int flen, const unsigned char *from, |
|
521 unsigned char *to, RSA *rsa, int padding) |
|
522 { |
|
523 int i, num = 0, r = -1; |
|
524 unsigned char *buf = NULL; |
|
525 |
|
526 num = BN_num_bytes(rsa->n); |
|
527 if ((buf = (unsigned char *)OPENSSL_malloc(num)) == NULL) |
|
528 { |
|
529 PK11err(PK11_F_RSA_PRIV_ENC, PK11_R_MALLOC_FAILURE); |
|
530 goto err; |
|
531 } |
|
532 |
|
533 switch (padding) |
|
534 { |
|
535 case RSA_PKCS1_PADDING: |
|
536 i = RSA_padding_add_PKCS1_type_1(buf, num, from, flen); |
|
537 break; |
|
538 case RSA_NO_PADDING: |
|
539 i = RSA_padding_add_none(buf, num, from, flen); |
|
540 break; |
|
541 case RSA_SSLV23_PADDING: |
|
542 default: |
|
543 PK11err(PK11_F_RSA_PRIV_ENC, PK11_R_UNKNOWN_PADDING_TYPE); |
|
544 goto err; |
|
545 } |
|
546 if (i <= 0) goto err; |
|
547 |
|
548 /* PK11 functions are called here */ |
|
549 r = pk11_RSA_private_encrypt_low(num, buf, to, rsa); |
|
550 err: |
|
551 if (buf != NULL) |
|
552 { |
|
553 OPENSSL_cleanse(buf, num); |
|
554 OPENSSL_free(buf); |
|
555 } |
|
556 return (r); |
|
557 } |
|
558 |
|
559 /* Similar to OpenSSL code. Input errors are also checked here */ |
|
560 static int pk11_RSA_private_decrypt(int flen, const unsigned char *from, |
|
561 unsigned char *to, RSA *rsa, int padding) |
|
562 { |
|
563 BIGNUM f; |
|
564 int j, num = 0, r = -1; |
|
565 unsigned char *p; |
|
566 unsigned char *buf = NULL; |
|
567 |
|
568 BN_init(&f); |
|
569 |
|
570 num = BN_num_bytes(rsa->n); |
|
571 |
|
572 if ((buf = (unsigned char *)OPENSSL_malloc(num)) == NULL) |
|
573 { |
|
574 PK11err(PK11_F_RSA_PRIV_DEC, PK11_R_MALLOC_FAILURE); |
|
575 goto err; |
|
576 } |
|
577 |
|
578 /* |
|
579 * This check was for equality but PGP does evil things |
|
580 * and chops off the top '0' bytes |
|
581 */ |
|
582 if (flen > num) |
|
583 { |
|
584 PK11err(PK11_F_RSA_PRIV_DEC, |
|
585 PK11_R_DATA_GREATER_THAN_MOD_LEN); |
|
586 goto err; |
|
587 } |
|
588 |
|
589 /* make data into a big number */ |
|
590 if (BN_bin2bn(from, (int)flen, &f) == NULL) |
|
591 goto err; |
|
592 |
|
593 if (BN_ucmp(&f, rsa->n) >= 0) |
|
594 { |
|
595 PK11err(PK11_F_RSA_PRIV_DEC, |
|
596 PK11_R_DATA_TOO_LARGE_FOR_MODULUS); |
|
597 goto err; |
|
598 } |
|
599 |
|
600 /* PK11 functions are called here */ |
|
601 r = pk11_RSA_private_decrypt_low(flen, from, buf, rsa); |
|
602 |
|
603 /* |
|
604 * PK11 CKM_RSA_X_509 mechanism pads 0's at the beginning. |
|
605 * Needs to skip these 0's paddings here. |
|
606 */ |
|
607 for (j = 0; j < r; j++) |
|
608 if (buf[j] != 0) |
|
609 break; |
|
610 |
|
611 p = buf + j; |
|
612 j = r - j; /* j is only used with no-padding mode */ |
|
613 |
|
614 switch (padding) |
|
615 { |
|
616 case RSA_PKCS1_PADDING: |
|
617 r = RSA_padding_check_PKCS1_type_2(to, num, p, j, num); |
|
618 break; |
|
619 #ifndef OPENSSL_NO_SHA |
|
620 case RSA_PKCS1_OAEP_PADDING: |
|
621 r = RSA_padding_check_PKCS1_OAEP(to, num, p, j, num, NULL, 0); |
|
622 break; |
|
623 #endif |
|
624 case RSA_SSLV23_PADDING: |
|
625 r = RSA_padding_check_SSLv23(to, num, p, j, num); |
|
626 break; |
|
627 case RSA_NO_PADDING: |
|
628 r = RSA_padding_check_none(to, num, p, j, num); |
|
629 break; |
|
630 default: |
|
631 PK11err(PK11_F_RSA_PRIV_DEC, PK11_R_UNKNOWN_PADDING_TYPE); |
|
632 goto err; |
|
633 } |
|
634 if (r < 0) |
|
635 PK11err(PK11_F_RSA_PRIV_DEC, PK11_R_PADDING_CHECK_FAILED); |
|
636 |
|
637 err: |
|
638 BN_clear_free(&f); |
|
639 if (buf != NULL) |
|
640 { |
|
641 OPENSSL_cleanse(buf, num); |
|
642 OPENSSL_free(buf); |
|
643 } |
|
644 return (r); |
|
645 } |
|
646 |
|
647 /* Similar to OpenSSL code. Input errors are also checked here */ |
|
648 static int pk11_RSA_public_decrypt(int flen, const unsigned char *from, |
|
649 unsigned char *to, RSA *rsa, int padding) |
|
650 { |
|
651 BIGNUM f; |
|
652 int i, num = 0, r = -1; |
|
653 unsigned char *p; |
|
654 unsigned char *buf = NULL; |
|
655 |
|
656 BN_init(&f); |
|
657 num = BN_num_bytes(rsa->n); |
|
658 buf = (unsigned char *)OPENSSL_malloc(num); |
|
659 if (buf == NULL) |
|
660 { |
|
661 PK11err(PK11_F_RSA_PUB_DEC, PK11_R_MALLOC_FAILURE); |
|
662 goto err; |
|
663 } |
|
664 |
|
665 /* |
|
666 * This check was for equality but PGP does evil things |
|
667 * and chops off the top '0' bytes |
|
668 */ |
|
669 if (flen > num) |
|
670 { |
|
671 PK11err(PK11_F_RSA_PUB_DEC, PK11_R_DATA_GREATER_THAN_MOD_LEN); |
|
672 goto err; |
|
673 } |
|
674 |
|
675 if (BN_bin2bn(from, flen, &f) == NULL) |
|
676 goto err; |
|
677 |
|
678 if (BN_ucmp(&f, rsa->n) >= 0) |
|
679 { |
|
680 PK11err(PK11_F_RSA_PUB_DEC, |
|
681 PK11_R_DATA_TOO_LARGE_FOR_MODULUS); |
|
682 goto err; |
|
683 } |
|
684 |
|
685 /* PK11 functions are called here */ |
|
686 r = pk11_RSA_public_decrypt_low(flen, from, buf, rsa); |
|
687 |
|
688 /* |
|
689 * PK11 CKM_RSA_X_509 mechanism pads 0's at the beginning. |
|
690 * Needs to skip these 0's here |
|
691 */ |
|
692 for (i = 0; i < r; i++) |
|
693 if (buf[i] != 0) |
|
694 break; |
|
695 |
|
696 p = buf + i; |
|
697 i = r - i; /* i is only used with no-padding mode */ |
|
698 |
|
699 switch (padding) |
|
700 { |
|
701 case RSA_PKCS1_PADDING: |
|
702 r = RSA_padding_check_PKCS1_type_1(to, num, p, i, num); |
|
703 break; |
|
704 case RSA_NO_PADDING: |
|
705 r = RSA_padding_check_none(to, num, p, i, num); |
|
706 break; |
|
707 default: |
|
708 PK11err(PK11_F_RSA_PUB_DEC, PK11_R_UNKNOWN_PADDING_TYPE); |
|
709 goto err; |
|
710 } |
|
711 if (r < 0) |
|
712 PK11err(PK11_F_RSA_PUB_DEC, PK11_R_PADDING_CHECK_FAILED); |
|
713 |
|
714 err: |
|
715 BN_clear_free(&f); |
|
716 if (buf != NULL) |
|
717 { |
|
718 OPENSSL_cleanse(buf, num); |
|
719 OPENSSL_free(buf); |
|
720 } |
|
721 return (r); |
|
722 } |
|
723 |
|
724 /* |
|
725 * This function implements RSA public encryption using C_EncryptInit and |
|
726 * C_Encrypt pk11 interfaces. Note that the CKM_RSA_X_509 is used here. |
|
727 * The calling function allocated sufficient memory in "to" to store results. |
|
728 */ |
|
729 static int pk11_RSA_public_encrypt_low(int flen, |
|
730 const unsigned char *from, unsigned char *to, RSA *rsa) |
|
731 { |
|
732 CK_ULONG bytes_encrypted = flen; |
|
733 int retval = -1; |
|
734 CK_RV rv; |
|
735 CK_MECHANISM mech_rsa = {CKM_RSA_X_509, NULL, 0}; |
|
736 CK_MECHANISM *p_mech = &mech_rsa; |
|
737 CK_OBJECT_HANDLE h_pub_key = CK_INVALID_HANDLE; |
|
738 PK11_SESSION *sp; |
|
739 |
|
740 if ((sp = pk11_get_session(OP_RSA)) == NULL) |
|
741 return (-1); |
|
742 |
|
743 (void) pk11_check_new_rsa_key_pub(sp, rsa); |
|
744 |
|
745 h_pub_key = sp->opdata_rsa_pub_key; |
|
746 if (h_pub_key == CK_INVALID_HANDLE) |
|
747 h_pub_key = sp->opdata_rsa_pub_key = |
|
748 pk11_get_public_rsa_key(rsa, sp); |
|
749 |
|
750 if (h_pub_key != CK_INVALID_HANDLE) |
|
751 { |
|
752 rv = pFuncList->C_EncryptInit(sp->session, p_mech, |
|
753 h_pub_key); |
|
754 |
|
755 if (rv != CKR_OK) |
|
756 { |
|
757 PK11err_add_data(PK11_F_RSA_PUB_ENC_LOW, |
|
758 PK11_R_ENCRYPTINIT, rv); |
|
759 pk11_return_session(sp, OP_RSA); |
|
760 return (-1); |
|
761 } |
|
762 |
|
763 rv = pFuncList->C_Encrypt(sp->session, |
|
764 (unsigned char *)from, flen, to, &bytes_encrypted); |
|
765 |
|
766 if (rv != CKR_OK) |
|
767 { |
|
768 PK11err_add_data(PK11_F_RSA_PUB_ENC_LOW, |
|
769 PK11_R_ENCRYPT, rv); |
|
770 pk11_return_session(sp, OP_RSA); |
|
771 return (-1); |
|
772 } |
|
773 retval = bytes_encrypted; |
|
774 } |
|
775 |
|
776 pk11_return_session(sp, OP_RSA); |
|
777 return (retval); |
|
778 } |
|
779 |
|
780 |
|
781 /* |
|
782 * This function implements RSA private encryption using C_SignInit and |
|
783 * C_Sign pk11 APIs. Note that CKM_RSA_X_509 is used here. |
|
784 * The calling function allocated sufficient memory in "to" to store results. |
|
785 */ |
|
786 static int pk11_RSA_private_encrypt_low(int flen, |
|
787 const unsigned char *from, unsigned char *to, RSA *rsa) |
|
788 { |
|
789 CK_ULONG ul_sig_len = flen; |
|
790 int retval = -1; |
|
791 CK_RV rv; |
|
792 CK_MECHANISM mech_rsa = {CKM_RSA_X_509, NULL, 0}; |
|
793 CK_MECHANISM *p_mech = &mech_rsa; |
|
794 CK_OBJECT_HANDLE h_priv_key = CK_INVALID_HANDLE; |
|
795 PK11_SESSION *sp; |
|
796 |
|
797 if ((sp = pk11_get_session(OP_RSA)) == NULL) |
|
798 return (-1); |
|
799 |
|
800 (void) pk11_check_new_rsa_key_priv(sp, rsa); |
|
801 |
|
802 h_priv_key = sp->opdata_rsa_priv_key; |
|
803 if (h_priv_key == CK_INVALID_HANDLE) |
|
804 h_priv_key = sp->opdata_rsa_priv_key = |
|
805 pk11_get_private_rsa_key(rsa, sp); |
|
806 |
|
807 if (h_priv_key != CK_INVALID_HANDLE) |
|
808 { |
|
809 rv = pFuncList->C_SignInit(sp->session, p_mech, |
|
810 h_priv_key); |
|
811 |
|
812 if (rv != CKR_OK) |
|
813 { |
|
814 PK11err_add_data(PK11_F_RSA_PRIV_ENC_LOW, |
|
815 PK11_R_SIGNINIT, rv); |
|
816 pk11_return_session(sp, OP_RSA); |
|
817 return (-1); |
|
818 } |
|
819 |
|
820 rv = pFuncList->C_Sign(sp->session, |
|
821 (unsigned char *)from, flen, to, &ul_sig_len); |
|
822 |
|
823 if (rv != CKR_OK) |
|
824 { |
|
825 PK11err_add_data(PK11_F_RSA_PRIV_ENC_LOW, PK11_R_SIGN, |
|
826 rv); |
|
827 pk11_return_session(sp, OP_RSA); |
|
828 return (-1); |
|
829 } |
|
830 |
|
831 retval = ul_sig_len; |
|
832 } |
|
833 |
|
834 pk11_return_session(sp, OP_RSA); |
|
835 return (retval); |
|
836 } |
|
837 |
|
838 |
|
839 /* |
|
840 * This function implements RSA private decryption using C_DecryptInit and |
|
841 * C_Decrypt pk11 APIs. Note that CKM_RSA_X_509 mechanism is used here. |
|
842 * The calling function allocated sufficient memory in "to" to store results. |
|
843 */ |
|
844 static int pk11_RSA_private_decrypt_low(int flen, |
|
845 const unsigned char *from, unsigned char *to, RSA *rsa) |
|
846 { |
|
847 CK_ULONG bytes_decrypted = flen; |
|
848 int retval = -1; |
|
849 CK_RV rv; |
|
850 CK_MECHANISM mech_rsa = {CKM_RSA_X_509, NULL, 0}; |
|
851 CK_MECHANISM *p_mech = &mech_rsa; |
|
852 CK_OBJECT_HANDLE h_priv_key; |
|
853 PK11_SESSION *sp; |
|
854 |
|
855 if ((sp = pk11_get_session(OP_RSA)) == NULL) |
|
856 return (-1); |
|
857 |
|
858 (void) pk11_check_new_rsa_key_priv(sp, rsa); |
|
859 |
|
860 h_priv_key = sp->opdata_rsa_priv_key; |
|
861 if (h_priv_key == CK_INVALID_HANDLE) |
|
862 h_priv_key = sp->opdata_rsa_priv_key = |
|
863 pk11_get_private_rsa_key(rsa, sp); |
|
864 |
|
865 if (h_priv_key != CK_INVALID_HANDLE) |
|
866 { |
|
867 rv = pFuncList->C_DecryptInit(sp->session, p_mech, |
|
868 h_priv_key); |
|
869 |
|
870 if (rv != CKR_OK) |
|
871 { |
|
872 PK11err_add_data(PK11_F_RSA_PRIV_DEC_LOW, |
|
873 PK11_R_DECRYPTINIT, rv); |
|
874 pk11_return_session(sp, OP_RSA); |
|
875 return (-1); |
|
876 } |
|
877 |
|
878 rv = pFuncList->C_Decrypt(sp->session, |
|
879 (unsigned char *)from, flen, to, &bytes_decrypted); |
|
880 |
|
881 if (rv != CKR_OK) |
|
882 { |
|
883 PK11err_add_data(PK11_F_RSA_PRIV_DEC_LOW, |
|
884 PK11_R_DECRYPT, rv); |
|
885 pk11_return_session(sp, OP_RSA); |
|
886 return (-1); |
|
887 } |
|
888 retval = bytes_decrypted; |
|
889 } |
|
890 |
|
891 pk11_return_session(sp, OP_RSA); |
|
892 return (retval); |
|
893 } |
|
894 |
|
895 |
|
896 /* |
|
897 * This function implements RSA public decryption using C_VerifyRecoverInit |
|
898 * and C_VerifyRecover pk11 APIs. Note that CKM_RSA_X_509 is used here. |
|
899 * The calling function allocated sufficient memory in "to" to store results. |
|
900 */ |
|
901 static int pk11_RSA_public_decrypt_low(int flen, |
|
902 const unsigned char *from, unsigned char *to, RSA *rsa) |
|
903 { |
|
904 CK_ULONG bytes_decrypted = flen; |
|
905 int retval = -1; |
|
906 CK_RV rv; |
|
907 CK_MECHANISM mech_rsa = {CKM_RSA_X_509, NULL, 0}; |
|
908 CK_MECHANISM *p_mech = &mech_rsa; |
|
909 CK_OBJECT_HANDLE h_pub_key = CK_INVALID_HANDLE; |
|
910 PK11_SESSION *sp; |
|
911 |
|
912 if ((sp = pk11_get_session(OP_RSA)) == NULL) |
|
913 return (-1); |
|
914 |
|
915 (void) pk11_check_new_rsa_key_pub(sp, rsa); |
|
916 |
|
917 h_pub_key = sp->opdata_rsa_pub_key; |
|
918 if (h_pub_key == CK_INVALID_HANDLE) |
|
919 h_pub_key = sp->opdata_rsa_pub_key = |
|
920 pk11_get_public_rsa_key(rsa, sp); |
|
921 |
|
922 if (h_pub_key != CK_INVALID_HANDLE) |
|
923 { |
|
924 rv = pFuncList->C_VerifyRecoverInit(sp->session, |
|
925 p_mech, h_pub_key); |
|
926 |
|
927 if (rv != CKR_OK) |
|
928 { |
|
929 PK11err_add_data(PK11_F_RSA_PUB_DEC_LOW, |
|
930 PK11_R_VERIFYRECOVERINIT, rv); |
|
931 pk11_return_session(sp, OP_RSA); |
|
932 return (-1); |
|
933 } |
|
934 |
|
935 rv = pFuncList->C_VerifyRecover(sp->session, |
|
936 (unsigned char *)from, flen, to, &bytes_decrypted); |
|
937 |
|
938 if (rv != CKR_OK) |
|
939 { |
|
940 PK11err_add_data(PK11_F_RSA_PUB_DEC_LOW, |
|
941 PK11_R_VERIFYRECOVER, rv); |
|
942 pk11_return_session(sp, OP_RSA); |
|
943 return (-1); |
|
944 } |
|
945 retval = bytes_decrypted; |
|
946 } |
|
947 |
|
948 pk11_return_session(sp, OP_RSA); |
|
949 return (retval); |
|
950 } |
|
951 |
|
952 static int pk11_RSA_init(RSA *rsa) |
|
953 { |
|
954 /* |
|
955 * This flag in the RSA_METHOD enables the new rsa_sign, |
|
956 * rsa_verify functions. See rsa.h for details. |
|
957 */ |
|
958 rsa->flags |= RSA_FLAG_SIGN_VER; |
|
959 |
|
960 return (1); |
|
961 } |
|
962 |
|
963 static int pk11_RSA_finish(RSA *rsa) |
|
964 { |
|
965 /* |
|
966 * Since we are overloading OpenSSL's native RSA_eay_finish() we need |
|
967 * to do the same as in the original function, i.e. to free bignum |
|
968 * structures. |
|
969 */ |
|
970 if (rsa->_method_mod_n != NULL) |
|
971 BN_MONT_CTX_free(rsa->_method_mod_n); |
|
972 if (rsa->_method_mod_p != NULL) |
|
973 BN_MONT_CTX_free(rsa->_method_mod_p); |
|
974 if (rsa->_method_mod_q != NULL) |
|
975 BN_MONT_CTX_free(rsa->_method_mod_q); |
|
976 |
|
977 return (1); |
|
978 } |
|
979 |
|
980 /* |
|
981 * Standard engine interface function. Majority codes here are from |
|
982 * rsa/rsa_sign.c. We replaced the decrypt function call by C_Sign of PKCS#11. |
|
983 * See more details in rsa/rsa_sign.c |
|
984 */ |
|
985 static int pk11_RSA_sign(int type, const unsigned char *m, unsigned int m_len, |
|
986 unsigned char *sigret, unsigned int *siglen, const RSA *rsa) |
|
987 { |
|
988 X509_SIG sig; |
|
989 ASN1_TYPE parameter; |
|
990 int i, j; |
|
991 unsigned char *p, *s = NULL; |
|
992 X509_ALGOR algor; |
|
993 ASN1_OCTET_STRING digest; |
|
994 CK_RV rv; |
|
995 CK_MECHANISM mech_rsa = {CKM_RSA_PKCS, NULL, 0}; |
|
996 CK_MECHANISM *p_mech = &mech_rsa; |
|
997 CK_OBJECT_HANDLE h_priv_key; |
|
998 PK11_SESSION *sp = NULL; |
|
999 int ret = 0; |
|
1000 unsigned long ulsiglen; |
|
1001 |
|
1002 /* Encode the digest */ |
|
1003 /* Special case: SSL signature, just check the length */ |
|
1004 if (type == NID_md5_sha1) |
|
1005 { |
|
1006 if (m_len != SSL_SIG_LENGTH) |
|
1007 { |
|
1008 PK11err(PK11_F_RSA_SIGN, |
|
1009 PK11_R_INVALID_MESSAGE_LENGTH); |
|
1010 goto err; |
|
1011 } |
|
1012 i = SSL_SIG_LENGTH; |
|
1013 s = (unsigned char *)m; |
|
1014 } |
|
1015 else |
|
1016 { |
|
1017 sig.algor = &algor; |
|
1018 sig.algor->algorithm = OBJ_nid2obj(type); |
|
1019 if (sig.algor->algorithm == NULL) |
|
1020 { |
|
1021 PK11err(PK11_F_RSA_SIGN, |
|
1022 PK11_R_UNKNOWN_ALGORITHM_TYPE); |
|
1023 goto err; |
|
1024 } |
|
1025 if (sig.algor->algorithm->length == 0) |
|
1026 { |
|
1027 PK11err(PK11_F_RSA_SIGN, |
|
1028 PK11_R_UNKNOWN_ASN1_OBJECT_ID); |
|
1029 goto err; |
|
1030 } |
|
1031 parameter.type = V_ASN1_NULL; |
|
1032 parameter.value.ptr = NULL; |
|
1033 sig.algor->parameter = ¶meter; |
|
1034 |
|
1035 sig.digest = &digest; |
|
1036 sig.digest->data = (unsigned char *)m; |
|
1037 sig.digest->length = m_len; |
|
1038 |
|
1039 i = i2d_X509_SIG(&sig, NULL); |
|
1040 } |
|
1041 |
|
1042 j = RSA_size(rsa); |
|
1043 if ((i - RSA_PKCS1_PADDING) > j) |
|
1044 { |
|
1045 PK11err(PK11_F_RSA_SIGN, PK11_R_DIGEST_TOO_BIG); |
|
1046 goto err; |
|
1047 } |
|
1048 |
|
1049 if (type != NID_md5_sha1) |
|
1050 { |
|
1051 s = (unsigned char *)OPENSSL_malloc((unsigned int)(j + 1)); |
|
1052 if (s == NULL) |
|
1053 { |
|
1054 PK11err(PK11_F_RSA_SIGN, PK11_R_MALLOC_FAILURE); |
|
1055 goto err; |
|
1056 } |
|
1057 p = s; |
|
1058 (void) i2d_X509_SIG(&sig, &p); |
|
1059 } |
|
1060 |
|
1061 if ((sp = pk11_get_session(OP_RSA)) == NULL) |
|
1062 goto err; |
|
1063 |
|
1064 (void) pk11_check_new_rsa_key_priv(sp, rsa); |
|
1065 |
|
1066 h_priv_key = sp->opdata_rsa_priv_key; |
|
1067 if (h_priv_key == CK_INVALID_HANDLE) |
|
1068 h_priv_key = sp->opdata_rsa_priv_key = |
|
1069 pk11_get_private_rsa_key((RSA *)rsa, sp); |
|
1070 |
|
1071 if (h_priv_key != CK_INVALID_HANDLE) |
|
1072 { |
|
1073 rv = pFuncList->C_SignInit(sp->session, p_mech, h_priv_key); |
|
1074 |
|
1075 if (rv != CKR_OK) |
|
1076 { |
|
1077 PK11err_add_data(PK11_F_RSA_SIGN, PK11_R_SIGNINIT, rv); |
|
1078 goto err; |
|
1079 } |
|
1080 |
|
1081 ulsiglen = j; |
|
1082 rv = pFuncList->C_Sign(sp->session, s, i, sigret, |
|
1083 (CK_ULONG_PTR) &ulsiglen); |
|
1084 *siglen = ulsiglen; |
|
1085 |
|
1086 if (rv != CKR_OK) |
|
1087 { |
|
1088 PK11err_add_data(PK11_F_RSA_SIGN, PK11_R_SIGN, rv); |
|
1089 goto err; |
|
1090 } |
|
1091 ret = 1; |
|
1092 } |
|
1093 |
|
1094 err: |
|
1095 if (type != NID_md5_sha1) |
|
1096 { |
|
1097 (void) memset(s, 0, (unsigned int)(j + 1)); |
|
1098 OPENSSL_free(s); |
|
1099 } |
|
1100 |
|
1101 pk11_return_session(sp, OP_RSA); |
|
1102 return (ret); |
|
1103 } |
|
1104 |
|
1105 static int pk11_RSA_verify(int type, const unsigned char *m, |
|
1106 unsigned int m_len, unsigned char *sigbuf, unsigned int siglen, |
|
1107 const RSA *rsa) |
|
1108 { |
|
1109 X509_SIG sig; |
|
1110 ASN1_TYPE parameter; |
|
1111 int i, j; |
|
1112 unsigned char *p, *s = NULL; |
|
1113 X509_ALGOR algor; |
|
1114 ASN1_OCTET_STRING digest; |
|
1115 CK_RV rv; |
|
1116 CK_MECHANISM mech_rsa = {CKM_RSA_PKCS, NULL, 0}; |
|
1117 CK_MECHANISM *p_mech = &mech_rsa; |
|
1118 CK_OBJECT_HANDLE h_pub_key; |
|
1119 PK11_SESSION *sp = NULL; |
|
1120 int ret = 0; |
|
1121 |
|
1122 /* Encode the digest */ |
|
1123 /* Special case: SSL signature, just check the length */ |
|
1124 if (type == NID_md5_sha1) |
|
1125 { |
|
1126 if (m_len != SSL_SIG_LENGTH) |
|
1127 { |
|
1128 PK11err(PK11_F_RSA_VERIFY, |
|
1129 PK11_R_INVALID_MESSAGE_LENGTH); |
|
1130 goto err; |
|
1131 } |
|
1132 i = SSL_SIG_LENGTH; |
|
1133 s = (unsigned char *)m; |
|
1134 } |
|
1135 else |
|
1136 { |
|
1137 sig.algor = &algor; |
|
1138 sig.algor->algorithm = OBJ_nid2obj(type); |
|
1139 if (sig.algor->algorithm == NULL) |
|
1140 { |
|
1141 PK11err(PK11_F_RSA_VERIFY, |
|
1142 PK11_R_UNKNOWN_ALGORITHM_TYPE); |
|
1143 goto err; |
|
1144 } |
|
1145 if (sig.algor->algorithm->length == 0) |
|
1146 { |
|
1147 PK11err(PK11_F_RSA_VERIFY, |
|
1148 PK11_R_UNKNOWN_ASN1_OBJECT_ID); |
|
1149 goto err; |
|
1150 } |
|
1151 parameter.type = V_ASN1_NULL; |
|
1152 parameter.value.ptr = NULL; |
|
1153 sig.algor->parameter = ¶meter; |
|
1154 sig.digest = &digest; |
|
1155 sig.digest->data = (unsigned char *)m; |
|
1156 sig.digest->length = m_len; |
|
1157 i = i2d_X509_SIG(&sig, NULL); |
|
1158 } |
|
1159 |
|
1160 j = RSA_size(rsa); |
|
1161 if ((i - RSA_PKCS1_PADDING) > j) |
|
1162 { |
|
1163 PK11err(PK11_F_RSA_VERIFY, PK11_R_DIGEST_TOO_BIG); |
|
1164 goto err; |
|
1165 } |
|
1166 |
|
1167 if (type != NID_md5_sha1) |
|
1168 { |
|
1169 s = (unsigned char *)OPENSSL_malloc((unsigned int)(j + 1)); |
|
1170 if (s == NULL) |
|
1171 { |
|
1172 PK11err(PK11_F_RSA_VERIFY, PK11_R_MALLOC_FAILURE); |
|
1173 goto err; |
|
1174 } |
|
1175 p = s; |
|
1176 (void) i2d_X509_SIG(&sig, &p); |
|
1177 } |
|
1178 |
|
1179 if ((sp = pk11_get_session(OP_RSA)) == NULL) |
|
1180 goto err; |
|
1181 |
|
1182 (void) pk11_check_new_rsa_key_pub(sp, rsa); |
|
1183 |
|
1184 h_pub_key = sp->opdata_rsa_pub_key; |
|
1185 if (h_pub_key == CK_INVALID_HANDLE) |
|
1186 h_pub_key = sp->opdata_rsa_pub_key = |
|
1187 pk11_get_public_rsa_key((RSA *)rsa, sp); |
|
1188 |
|
1189 if (h_pub_key != CK_INVALID_HANDLE) |
|
1190 { |
|
1191 rv = pFuncList->C_VerifyInit(sp->session, p_mech, |
|
1192 h_pub_key); |
|
1193 |
|
1194 if (rv != CKR_OK) |
|
1195 { |
|
1196 PK11err_add_data(PK11_F_RSA_VERIFY, PK11_R_VERIFYINIT, |
|
1197 rv); |
|
1198 goto err; |
|
1199 } |
|
1200 rv = pFuncList->C_Verify(sp->session, s, i, sigbuf, |
|
1201 (CK_ULONG)siglen); |
|
1202 |
|
1203 if (rv != CKR_OK) |
|
1204 { |
|
1205 PK11err_add_data(PK11_F_RSA_VERIFY, PK11_R_VERIFY, rv); |
|
1206 goto err; |
|
1207 } |
|
1208 ret = 1; |
|
1209 } |
|
1210 |
|
1211 err: |
|
1212 if (type != NID_md5_sha1) |
|
1213 { |
|
1214 (void) memset(s, 0, (unsigned int)siglen); |
|
1215 OPENSSL_free(s); |
|
1216 } |
|
1217 |
|
1218 pk11_return_session(sp, OP_RSA); |
|
1219 return (ret); |
|
1220 } |
|
1221 |
|
1222 #define MAXATTR 1024 |
|
1223 /* |
|
1224 * Load RSA private key from a file or get its PKCS#11 handle if stored in the |
|
1225 * PKCS#11 token. |
|
1226 */ |
|
1227 /* ARGSUSED */ |
|
1228 EVP_PKEY *pk11_load_privkey(ENGINE* e, const char *privkey_id, |
|
1229 UI_METHOD *ui_method, void *callback_data) |
|
1230 { |
|
1231 EVP_PKEY *pkey = NULL; |
|
1232 FILE *privkey; |
|
1233 CK_OBJECT_HANDLE h_priv_key = CK_INVALID_HANDLE; |
|
1234 RSA *rsa = NULL; |
|
1235 PK11_SESSION *sp; |
|
1236 /* Anything else below is needed for the key by reference extension. */ |
|
1237 const char *file; |
|
1238 int ret; |
|
1239 pkcs11_uri uri_struct; |
|
1240 CK_RV rv; |
|
1241 CK_BBOOL is_token = CK_TRUE; |
|
1242 CK_BBOOL rollback = CK_FALSE; |
|
1243 CK_BYTE attr_data[8][MAXATTR]; |
|
1244 CK_OBJECT_CLASS key_class = CKO_PRIVATE_KEY; |
|
1245 CK_OBJECT_HANDLE ks_key = CK_INVALID_HANDLE; /* key in keystore */ |
|
1246 |
|
1247 /* We look for private keys only. */ |
|
1248 CK_ATTRIBUTE search_templ[] = |
|
1249 { |
|
1250 {CKA_TOKEN, &is_token, sizeof (is_token)}, |
|
1251 {CKA_CLASS, &key_class, sizeof (key_class)}, |
|
1252 {CKA_LABEL, NULL, 0} |
|
1253 }; |
|
1254 |
|
1255 /* |
|
1256 * These public attributes are needed to initialize the OpenSSL RSA |
|
1257 * structure with something we can use to look up the key. Note that we |
|
1258 * never ask for private components. |
|
1259 */ |
|
1260 CK_ATTRIBUTE get_templ[] = |
|
1261 { |
|
1262 {CKA_MODULUS, (void *)attr_data[0], MAXATTR}, /* n */ |
|
1263 {CKA_PUBLIC_EXPONENT, (void *)attr_data[1], MAXATTR}, /* e */ |
|
1264 }; |
|
1265 |
|
1266 if ((sp = pk11_get_session(OP_RSA)) == NULL) |
|
1267 return (NULL); |
|
1268 |
|
1269 /* |
|
1270 * The next function will decide whether we are going to access keys in |
|
1271 * the token or read them from plain files. It all depends on what is in |
|
1272 * the 'privkey_id' parameter. |
|
1273 */ |
|
1274 ret = pk11_process_pkcs11_uri(privkey_id, &uri_struct, &file); |
|
1275 |
|
1276 if (ret == 0) |
|
1277 goto err; |
|
1278 |
|
1279 /* We will try to access a key from a PKCS#11 token. */ |
|
1280 if (ret == 1) |
|
1281 { |
|
1282 if (pk11_check_token_attrs(&uri_struct) == 0) |
|
1283 goto err; |
|
1284 |
|
1285 search_templ[2].pValue = uri_struct.object; |
|
1286 search_templ[2].ulValueLen = strlen(search_templ[2].pValue); |
|
1287 |
|
1288 if (pk11_token_login(sp->session, &pk11_login_done, |
|
1289 &uri_struct, CK_TRUE) == 0) |
|
1290 goto err; |
|
1291 |
|
1292 /* |
|
1293 * Now let's try to find the key in the token. It is a failure |
|
1294 * if we can't find it. |
|
1295 */ |
|
1296 if (find_one_object(OP_RSA, sp->session, search_templ, 3, |
|
1297 &ks_key) == 0) |
|
1298 goto err; |
|
1299 |
|
1300 /* |
|
1301 * Free the structure now. Note that we use uri_struct's field |
|
1302 * directly in the template so we cannot free it until the find |
|
1303 * is done. |
|
1304 */ |
|
1305 pk11_free_pkcs11_uri(&uri_struct, 0); |
|
1306 |
|
1307 /* |
|
1308 * We might have a cache hit which we could confirm according to |
|
1309 * the 'n'/'e' params, RSA public pointer as NULL, and non-NULL |
|
1310 * RSA private pointer. However, it is easier just to recreate |
|
1311 * everything. We expect the keys to be loaded once and used |
|
1312 * many times. We do not check the return value because even in |
|
1313 * case of failure the sp structure will have both key pointer |
|
1314 * and object handle cleaned and pk11_destroy_object() reports |
|
1315 * the failure to the OpenSSL error message buffer. |
|
1316 */ |
|
1317 (void) pk11_destroy_rsa_object_priv(sp, CK_TRUE); |
|
1318 |
|
1319 sp->opdata_rsa_priv_key = ks_key; |
|
1320 /* This object shall not be deleted on a cache miss. */ |
|
1321 sp->persistent = CK_TRUE; |
|
1322 |
|
1323 if ((rsa = sp->opdata_rsa_priv = RSA_new_method(e)) == NULL) |
|
1324 goto err; |
|
1325 |
|
1326 if ((rv = pFuncList->C_GetAttributeValue(sp->session, ks_key, |
|
1327 get_templ, 2)) != CKR_OK) |
|
1328 { |
|
1329 PK11err_add_data(PK11_F_LOAD_PRIVKEY, |
|
1330 PK11_R_GETATTRIBUTVALUE, rv); |
|
1331 goto err; |
|
1332 } |
|
1333 |
|
1334 /* |
|
1335 * Cache the RSA private structure pointer. We do not use it now |
|
1336 * for key-by-ref keys but let's do it for consistency reasons. |
|
1337 */ |
|
1338 sp->opdata_rsa_priv = rsa; |
|
1339 |
|
1340 /* |
|
1341 * We do not use pk11_get_private_rsa_key() here so we must take |
|
1342 * care of handle management ourselves. |
|
1343 */ |
|
1344 KEY_HANDLE_REFHOLD(ks_key, OP_RSA, CK_FALSE, rollback, err); |
|
1345 |
|
1346 /* |
|
1347 * Those are the sensitive components we do not want to export |
|
1348 * from the token at all: rsa->(d|p|q|dmp1|dmq1|iqmp). |
|
1349 */ |
|
1350 attr_to_BN(&get_templ[0], attr_data[0], &rsa->n); |
|
1351 attr_to_BN(&get_templ[1], attr_data[1], &rsa->e); |
|
1352 /* |
|
1353 * Must have 'n'/'e' components in the session structure as |
|
1354 * well. They serve as a public look-up key for the private key |
|
1355 * in the keystore. |
|
1356 */ |
|
1357 attr_to_BN(&get_templ[0], attr_data[0], &sp->opdata_rsa_n_num); |
|
1358 attr_to_BN(&get_templ[1], attr_data[1], &sp->opdata_rsa_e_num); |
|
1359 |
|
1360 if ((pkey = EVP_PKEY_new()) == NULL) |
|
1361 goto err; |
|
1362 |
|
1363 if (EVP_PKEY_set1_RSA(pkey, rsa) == 0) |
|
1364 goto err; |
|
1365 } |
|
1366 else |
|
1367 if ((privkey = fopen(file, read_mode_flags)) != NULL) |
|
1368 { |
|
1369 pkey = PEM_read_PrivateKey(privkey, NULL, NULL, NULL); |
|
1370 (void) fclose(privkey); |
|
1371 if (pkey != NULL) |
|
1372 { |
|
1373 rsa = EVP_PKEY_get1_RSA(pkey); |
|
1374 if (rsa != NULL) |
|
1375 { |
|
1376 (void) pk11_check_new_rsa_key_priv(sp, |
|
1377 rsa); |
|
1378 |
|
1379 h_priv_key = sp->opdata_rsa_priv_key = |
|
1380 pk11_get_private_rsa_key(rsa, sp); |
|
1381 if (h_priv_key == CK_INVALID_HANDLE) |
|
1382 goto err; |
|
1383 } |
|
1384 else |
|
1385 goto err; |
|
1386 } |
|
1387 } |
|
1388 |
|
1389 pk11_return_session(sp, OP_RSA); |
|
1390 return (pkey); |
|
1391 err: |
|
1392 if (rsa != NULL) |
|
1393 RSA_free(rsa); |
|
1394 if (pkey != NULL) |
|
1395 { |
|
1396 EVP_PKEY_free(pkey); |
|
1397 pkey = NULL; |
|
1398 } |
|
1399 return (pkey); |
|
1400 } |
|
1401 |
|
1402 /* Load RSA public key from a file or load it from the PKCS#11 token. */ |
|
1403 /* ARGSUSED */ |
|
1404 EVP_PKEY *pk11_load_pubkey(ENGINE* e, const char *pubkey_id, |
|
1405 UI_METHOD *ui_method, void *callback_data) |
|
1406 { |
|
1407 EVP_PKEY *pkey = NULL; |
|
1408 FILE *pubkey; |
|
1409 CK_OBJECT_HANDLE h_pub_key = CK_INVALID_HANDLE; |
|
1410 RSA *rsa = NULL; |
|
1411 PK11_SESSION *sp; |
|
1412 /* everything else below needed for key by reference extension */ |
|
1413 int ret; |
|
1414 const char *file; |
|
1415 pkcs11_uri uri_struct; |
|
1416 CK_RV rv; |
|
1417 CK_BBOOL is_token = CK_TRUE; |
|
1418 CK_BYTE attr_data[2][MAXATTR]; |
|
1419 CK_OBJECT_CLASS key_class = CKO_PUBLIC_KEY; |
|
1420 CK_OBJECT_HANDLE ks_key = CK_INVALID_HANDLE; /* key in keystore */ |
|
1421 |
|
1422 CK_ATTRIBUTE search_templ[] = |
|
1423 { |
|
1424 {CKA_TOKEN, &is_token, sizeof (is_token)}, |
|
1425 {CKA_CLASS, &key_class, sizeof (key_class)}, |
|
1426 {CKA_LABEL, NULL, 0} |
|
1427 }; |
|
1428 |
|
1429 /* |
|
1430 * These public attributes are needed to initialize OpenSSL RSA |
|
1431 * structure with something we can use to look up the key. |
|
1432 */ |
|
1433 CK_ATTRIBUTE get_templ[] = |
|
1434 { |
|
1435 {CKA_MODULUS, (void *)attr_data[0], MAXATTR}, /* n */ |
|
1436 {CKA_PUBLIC_EXPONENT, (void *)attr_data[1], MAXATTR}, /* e */ |
|
1437 }; |
|
1438 |
|
1439 if ((sp = pk11_get_session(OP_RSA)) == NULL) |
|
1440 return (NULL); |
|
1441 |
|
1442 ret = pk11_process_pkcs11_uri(pubkey_id, &uri_struct, &file); |
|
1443 |
|
1444 if (ret == 0) |
|
1445 goto err; |
|
1446 |
|
1447 if (ret == 1) |
|
1448 { |
|
1449 if (pk11_check_token_attrs(&uri_struct) == 0) |
|
1450 goto err; |
|
1451 |
|
1452 search_templ[2].pValue = uri_struct.object; |
|
1453 search_templ[2].ulValueLen = strlen(search_templ[2].pValue); |
|
1454 |
|
1455 if (pk11_token_login(sp->session, &pk11_login_done, |
|
1456 &uri_struct, CK_FALSE) == 0) |
|
1457 goto err; |
|
1458 |
|
1459 if (find_one_object(OP_RSA, sp->session, search_templ, 3, |
|
1460 &ks_key) == 0) |
|
1461 { |
|
1462 goto err; |
|
1463 } |
|
1464 |
|
1465 /* |
|
1466 * Free the structure now. Note that we use uri_struct's field |
|
1467 * directly in the template so we can't free until find is done. |
|
1468 */ |
|
1469 pk11_free_pkcs11_uri(&uri_struct, 0); |
|
1470 /* |
|
1471 * We load a new public key so we will create a new RSA |
|
1472 * structure. No cache hit is possible. |
|
1473 */ |
|
1474 (void) pk11_destroy_rsa_object_pub(sp, CK_TRUE); |
|
1475 sp->opdata_rsa_pub_key = ks_key; |
|
1476 |
|
1477 if ((rsa = sp->opdata_rsa_pub = RSA_new_method(e)) == NULL) |
|
1478 goto err; |
|
1479 |
|
1480 if ((rv = pFuncList->C_GetAttributeValue(sp->session, ks_key, |
|
1481 get_templ, 2)) != CKR_OK) |
|
1482 { |
|
1483 PK11err_add_data(PK11_F_LOAD_PUBKEY, |
|
1484 PK11_R_GETATTRIBUTVALUE, rv); |
|
1485 goto err; |
|
1486 } |
|
1487 |
|
1488 /* |
|
1489 * Cache the RSA public structure pointer. |
|
1490 */ |
|
1491 sp->opdata_rsa_pub = rsa; |
|
1492 |
|
1493 /* |
|
1494 * These are the sensitive components we do not want to export |
|
1495 * from the token at all: rsa->(d|p|q|dmp1|dmq1|iqmp). |
|
1496 */ |
|
1497 attr_to_BN(&get_templ[0], attr_data[0], &rsa->n); |
|
1498 attr_to_BN(&get_templ[1], attr_data[1], &rsa->e); |
|
1499 |
|
1500 if ((pkey = EVP_PKEY_new()) == NULL) |
|
1501 goto err; |
|
1502 |
|
1503 if (EVP_PKEY_set1_RSA(pkey, rsa) == 0) |
|
1504 goto err; |
|
1505 |
|
1506 /* |
|
1507 * Create a session object from it so that when calling |
|
1508 * pk11_get_public_rsa_key() the next time, we can find it. The |
|
1509 * reason why we do that is that we cannot tell from the RSA |
|
1510 * structure (OpenSSL RSA structure does not have any room for |
|
1511 * additional data used by the engine, for example) if it bears |
|
1512 * a public key stored in the keystore or not so it's better if |
|
1513 * we always have a session key. Note that this is different |
|
1514 * from what we do for the private keystore objects but in that |
|
1515 * case, we can tell from the RSA structure that the keystore |
|
1516 * object is in play - the 'd' component is NULL in that case. |
|
1517 */ |
|
1518 h_pub_key = sp->opdata_rsa_pub_key = |
|
1519 pk11_get_public_rsa_key(rsa, sp); |
|
1520 if (h_pub_key == CK_INVALID_HANDLE) |
|
1521 goto err; |
|
1522 } |
|
1523 else |
|
1524 if ((pubkey = fopen(file, read_mode_flags)) != NULL) |
|
1525 { |
|
1526 pkey = PEM_read_PUBKEY(pubkey, NULL, NULL, NULL); |
|
1527 (void) fclose(pubkey); |
|
1528 if (pkey != NULL) |
|
1529 { |
|
1530 rsa = EVP_PKEY_get1_RSA(pkey); |
|
1531 if (rsa != NULL) |
|
1532 { |
|
1533 /* |
|
1534 * This will always destroy the RSA |
|
1535 * object since we have a new RSA |
|
1536 * structure here. |
|
1537 */ |
|
1538 (void) pk11_check_new_rsa_key_pub(sp, |
|
1539 rsa); |
|
1540 |
|
1541 h_pub_key = sp->opdata_rsa_pub_key = |
|
1542 pk11_get_public_rsa_key(rsa, sp); |
|
1543 if (h_pub_key == CK_INVALID_HANDLE) |
|
1544 { |
|
1545 EVP_PKEY_free(pkey); |
|
1546 pkey = NULL; |
|
1547 } |
|
1548 } |
|
1549 else |
|
1550 { |
|
1551 EVP_PKEY_free(pkey); |
|
1552 pkey = NULL; |
|
1553 } |
|
1554 } |
|
1555 } |
|
1556 |
|
1557 pk11_return_session(sp, OP_RSA); |
|
1558 return (pkey); |
|
1559 err: |
|
1560 if (rsa != NULL) |
|
1561 RSA_free(rsa); |
|
1562 if (pkey != NULL) |
|
1563 { |
|
1564 EVP_PKEY_free(pkey); |
|
1565 pkey = NULL; |
|
1566 } |
|
1567 return (pkey); |
|
1568 } |
|
1569 |
|
1570 /* |
|
1571 * Get a public key object in a session from a given rsa structure. If the |
|
1572 * PKCS#11 session object already exists it is found, reused, and |
|
1573 * the counter in the active object list incremented. If not found, a new |
|
1574 * session object is created and put also onto the active object list. |
|
1575 * |
|
1576 * We use the session field from sp, and we cache rsa->(n|e) in |
|
1577 * opdata_rsa_(n|e|d)_num, respectively. |
|
1578 */ |
|
1579 static CK_OBJECT_HANDLE |
|
1580 pk11_get_public_rsa_key(RSA* rsa, PK11_SESSION *sp) |
|
1581 { |
|
1582 CK_RV rv; |
|
1583 CK_OBJECT_HANDLE h_key = CK_INVALID_HANDLE; |
|
1584 CK_ULONG found; |
|
1585 CK_OBJECT_CLASS o_key = CKO_PUBLIC_KEY; |
|
1586 CK_KEY_TYPE k_type = CKK_RSA; |
|
1587 CK_ULONG ul_key_attr_count = 7; |
|
1588 CK_BBOOL rollback = CK_FALSE; |
|
1589 |
|
1590 CK_ATTRIBUTE a_key_template[] = |
|
1591 { |
|
1592 {CKA_CLASS, (void *) NULL, sizeof (CK_OBJECT_CLASS)}, |
|
1593 {CKA_KEY_TYPE, (void *) NULL, sizeof (CK_KEY_TYPE)}, |
|
1594 {CKA_TOKEN, &pk11_false, sizeof (pk11_false)}, |
|
1595 {CKA_ENCRYPT, &pk11_true, sizeof (pk11_true)}, |
|
1596 {CKA_VERIFY_RECOVER, &pk11_true, sizeof (pk11_true)}, |
|
1597 {CKA_MODULUS, (void *)NULL, 0}, |
|
1598 {CKA_PUBLIC_EXPONENT, (void *)NULL, 0} |
|
1599 }; |
|
1600 |
|
1601 int i; |
|
1602 |
|
1603 a_key_template[0].pValue = &o_key; |
|
1604 a_key_template[1].pValue = &k_type; |
|
1605 |
|
1606 a_key_template[5].ulValueLen = BN_num_bytes(rsa->n); |
|
1607 a_key_template[5].pValue = (CK_VOID_PTR)OPENSSL_malloc( |
|
1608 (size_t)a_key_template[5].ulValueLen); |
|
1609 if (a_key_template[5].pValue == NULL) |
|
1610 { |
|
1611 PK11err(PK11_F_GET_PUB_RSA_KEY, PK11_R_MALLOC_FAILURE); |
|
1612 goto malloc_err; |
|
1613 } |
|
1614 |
|
1615 BN_bn2bin(rsa->n, a_key_template[5].pValue); |
|
1616 |
|
1617 a_key_template[6].ulValueLen = BN_num_bytes(rsa->e); |
|
1618 a_key_template[6].pValue = (CK_VOID_PTR)OPENSSL_malloc( |
|
1619 (size_t)a_key_template[6].ulValueLen); |
|
1620 if (a_key_template[6].pValue == NULL) |
|
1621 { |
|
1622 PK11err(PK11_F_GET_PUB_RSA_KEY, PK11_R_MALLOC_FAILURE); |
|
1623 goto malloc_err; |
|
1624 } |
|
1625 |
|
1626 BN_bn2bin(rsa->e, a_key_template[6].pValue); |
|
1627 |
|
1628 /* see find_lock array definition for more info on object locking */ |
|
1629 LOCK_OBJSTORE(OP_RSA); |
|
1630 |
|
1631 rv = pFuncList->C_FindObjectsInit(sp->session, a_key_template, |
|
1632 ul_key_attr_count); |
|
1633 |
|
1634 if (rv != CKR_OK) |
|
1635 { |
|
1636 PK11err_add_data(PK11_F_GET_PUB_RSA_KEY, |
|
1637 PK11_R_FINDOBJECTSINIT, rv); |
|
1638 goto err; |
|
1639 } |
|
1640 |
|
1641 rv = pFuncList->C_FindObjects(sp->session, &h_key, 1, &found); |
|
1642 |
|
1643 if (rv != CKR_OK) |
|
1644 { |
|
1645 PK11err_add_data(PK11_F_GET_PUB_RSA_KEY, |
|
1646 PK11_R_FINDOBJECTS, rv); |
|
1647 goto err; |
|
1648 } |
|
1649 |
|
1650 rv = pFuncList->C_FindObjectsFinal(sp->session); |
|
1651 |
|
1652 if (rv != CKR_OK) |
|
1653 { |
|
1654 PK11err_add_data(PK11_F_GET_PUB_RSA_KEY, |
|
1655 PK11_R_FINDOBJECTSFINAL, rv); |
|
1656 goto err; |
|
1657 } |
|
1658 |
|
1659 if (found == 0) |
|
1660 { |
|
1661 rv = pFuncList->C_CreateObject(sp->session, |
|
1662 a_key_template, ul_key_attr_count, &h_key); |
|
1663 if (rv != CKR_OK) |
|
1664 { |
|
1665 PK11err_add_data(PK11_F_GET_PUB_RSA_KEY, |
|
1666 PK11_R_CREATEOBJECT, rv); |
|
1667 goto err; |
|
1668 } |
|
1669 } |
|
1670 |
|
1671 if ((sp->opdata_rsa_n_num = BN_dup(rsa->n)) == NULL) |
|
1672 { |
|
1673 PK11err(PK11_F_GET_PUB_RSA_KEY, PK11_R_MALLOC_FAILURE); |
|
1674 rollback = CK_TRUE; |
|
1675 goto err; |
|
1676 } |
|
1677 |
|
1678 if ((sp->opdata_rsa_e_num = BN_dup(rsa->e)) == NULL) |
|
1679 { |
|
1680 PK11err(PK11_F_GET_PUB_RSA_KEY, PK11_R_MALLOC_FAILURE); |
|
1681 BN_free(sp->opdata_rsa_n_num); |
|
1682 sp->opdata_rsa_n_num = NULL; |
|
1683 rollback = CK_TRUE; |
|
1684 goto err; |
|
1685 } |
|
1686 |
|
1687 /* LINTED: E_CONSTANT_CONDITION */ |
|
1688 KEY_HANDLE_REFHOLD(h_key, OP_RSA, CK_FALSE, rollback, err); |
|
1689 sp->opdata_rsa_pub = rsa; |
|
1690 |
|
1691 err: |
|
1692 if (rollback) |
|
1693 { |
|
1694 /* |
|
1695 * We do not care about the return value from C_DestroyObject() |
|
1696 * since we are doing rollback. |
|
1697 */ |
|
1698 if (found == 0) |
|
1699 (void) pFuncList->C_DestroyObject(sp->session, h_key); |
|
1700 h_key = CK_INVALID_HANDLE; |
|
1701 } |
|
1702 |
|
1703 UNLOCK_OBJSTORE(OP_RSA); |
|
1704 |
|
1705 malloc_err: |
|
1706 for (i = 5; i <= 6; i++) |
|
1707 { |
|
1708 if (a_key_template[i].pValue != NULL) |
|
1709 { |
|
1710 OPENSSL_free(a_key_template[i].pValue); |
|
1711 a_key_template[i].pValue = NULL; |
|
1712 } |
|
1713 } |
|
1714 |
|
1715 return (h_key); |
|
1716 } |
|
1717 |
|
1718 /* |
|
1719 * Function similar to pk11_get_public_rsa_key(). In addition to 'n' and 'e' |
|
1720 * components, it also caches 'd' if present. Note that if RSA keys by reference |
|
1721 * are used, 'd' is never extracted from the token in which case it would be |
|
1722 * NULL here. |
|
1723 */ |
|
1724 static CK_OBJECT_HANDLE |
|
1725 pk11_get_private_rsa_key(RSA* rsa, PK11_SESSION *sp) |
|
1726 { |
|
1727 CK_RV rv; |
|
1728 CK_OBJECT_HANDLE h_key = CK_INVALID_HANDLE; |
|
1729 int i; |
|
1730 CK_ULONG found; |
|
1731 CK_OBJECT_CLASS o_key = CKO_PRIVATE_KEY; |
|
1732 CK_KEY_TYPE k_type = CKK_RSA; |
|
1733 CK_ULONG ul_key_attr_count = 14; |
|
1734 CK_BBOOL rollback = CK_FALSE; |
|
1735 |
|
1736 /* |
|
1737 * Both CKA_TOKEN and CKA_SENSITIVE have to be CK_FALSE for session keys |
|
1738 */ |
|
1739 CK_ATTRIBUTE a_key_template[] = |
|
1740 { |
|
1741 {CKA_CLASS, (void *) NULL, sizeof (CK_OBJECT_CLASS)}, |
|
1742 {CKA_KEY_TYPE, (void *) NULL, sizeof (CK_KEY_TYPE)}, |
|
1743 {CKA_TOKEN, &pk11_false, sizeof (pk11_false)}, |
|
1744 {CKA_SENSITIVE, &pk11_false, sizeof (pk11_false)}, |
|
1745 {CKA_DECRYPT, &pk11_true, sizeof (pk11_true)}, |
|
1746 {CKA_SIGN, &pk11_true, sizeof (pk11_true)}, |
|
1747 {CKA_MODULUS, (void *)NULL, 0}, |
|
1748 {CKA_PUBLIC_EXPONENT, (void *)NULL, 0}, |
|
1749 {CKA_PRIVATE_EXPONENT, (void *)NULL, 0}, |
|
1750 {CKA_PRIME_1, (void *)NULL, 0}, |
|
1751 {CKA_PRIME_2, (void *)NULL, 0}, |
|
1752 {CKA_EXPONENT_1, (void *)NULL, 0}, |
|
1753 {CKA_EXPONENT_2, (void *)NULL, 0}, |
|
1754 {CKA_COEFFICIENT, (void *)NULL, 0}, |
|
1755 }; |
|
1756 |
|
1757 a_key_template[0].pValue = &o_key; |
|
1758 a_key_template[1].pValue = &k_type; |
|
1759 |
|
1760 /* Put the private key components into the template */ |
|
1761 if (init_template_value(rsa->n, &a_key_template[6].pValue, |
|
1762 &a_key_template[6].ulValueLen) == 0 || |
|
1763 init_template_value(rsa->e, &a_key_template[7].pValue, |
|
1764 &a_key_template[7].ulValueLen) == 0 || |
|
1765 init_template_value(rsa->d, &a_key_template[8].pValue, |
|
1766 &a_key_template[8].ulValueLen) == 0 || |
|
1767 init_template_value(rsa->p, &a_key_template[9].pValue, |
|
1768 &a_key_template[9].ulValueLen) == 0 || |
|
1769 init_template_value(rsa->q, &a_key_template[10].pValue, |
|
1770 &a_key_template[10].ulValueLen) == 0 || |
|
1771 init_template_value(rsa->dmp1, &a_key_template[11].pValue, |
|
1772 &a_key_template[11].ulValueLen) == 0 || |
|
1773 init_template_value(rsa->dmq1, &a_key_template[12].pValue, |
|
1774 &a_key_template[12].ulValueLen) == 0 || |
|
1775 init_template_value(rsa->iqmp, &a_key_template[13].pValue, |
|
1776 &a_key_template[13].ulValueLen) == 0) |
|
1777 { |
|
1778 PK11err(PK11_F_GET_PRIV_RSA_KEY, PK11_R_MALLOC_FAILURE); |
|
1779 goto malloc_err; |
|
1780 } |
|
1781 |
|
1782 /* see find_lock array definition for more info on object locking */ |
|
1783 LOCK_OBJSTORE(OP_RSA); |
|
1784 |
|
1785 /* |
|
1786 * We are getting the private key but the private 'd' component is NULL. |
|
1787 * That means this is key by reference RSA key. In that case, we can |
|
1788 * use only public components for searching for the private key handle. |
|
1789 */ |
|
1790 if (rsa->d == NULL) |
|
1791 { |
|
1792 ul_key_attr_count = 8; |
|
1793 /* |
|
1794 * We will perform the search in the token, not in the existing |
|
1795 * session keys. |
|
1796 */ |
|
1797 a_key_template[2].pValue = &pk11_true; |
|
1798 } |
|
1799 |
|
1800 rv = pFuncList->C_FindObjectsInit(sp->session, a_key_template, |
|
1801 ul_key_attr_count); |
|
1802 |
|
1803 if (rv != CKR_OK) |
|
1804 { |
|
1805 PK11err_add_data(PK11_F_GET_PRIV_RSA_KEY, |
|
1806 PK11_R_FINDOBJECTSINIT, rv); |
|
1807 goto err; |
|
1808 } |
|
1809 |
|
1810 rv = pFuncList->C_FindObjects(sp->session, &h_key, 1, &found); |
|
1811 |
|
1812 if (rv != CKR_OK) |
|
1813 { |
|
1814 PK11err_add_data(PK11_F_GET_PRIV_RSA_KEY, |
|
1815 PK11_R_FINDOBJECTS, rv); |
|
1816 goto err; |
|
1817 } |
|
1818 |
|
1819 rv = pFuncList->C_FindObjectsFinal(sp->session); |
|
1820 |
|
1821 if (rv != CKR_OK) |
|
1822 { |
|
1823 PK11err_add_data(PK11_F_GET_PRIV_RSA_KEY, |
|
1824 PK11_R_FINDOBJECTSFINAL, rv); |
|
1825 goto err; |
|
1826 } |
|
1827 |
|
1828 if (found == 0) |
|
1829 { |
|
1830 /* |
|
1831 * We have an RSA structure with 'n'/'e' components only so we |
|
1832 * tried to find the private key in the keystore. If it was |
|
1833 * really a token key we have a problem. Note that for other key |
|
1834 * types we just create a new session key using the private |
|
1835 * components from the RSA structure. |
|
1836 */ |
|
1837 if (rsa->d == NULL) |
|
1838 { |
|
1839 PK11err(PK11_F_GET_PRIV_RSA_KEY, |
|
1840 PK11_R_PRIV_KEY_NOT_FOUND); |
|
1841 goto err; |
|
1842 } |
|
1843 |
|
1844 rv = pFuncList->C_CreateObject(sp->session, |
|
1845 a_key_template, ul_key_attr_count, &h_key); |
|
1846 if (rv != CKR_OK) |
|
1847 { |
|
1848 PK11err_add_data(PK11_F_GET_PRIV_RSA_KEY, |
|
1849 PK11_R_CREATEOBJECT, rv); |
|
1850 goto err; |
|
1851 } |
|
1852 } |
|
1853 |
|
1854 /* |
|
1855 * When RSA keys by reference code is used, we never extract private |
|
1856 * components from the keystore. In that case 'd' was set to NULL and we |
|
1857 * expect the application to properly cope with that. It is documented |
|
1858 * in openssl(5). In general, if keys by reference are used we expect it |
|
1859 * to be used exclusively using the high level API and then there is no |
|
1860 * problem. If the application expects the private components to be read |
|
1861 * from the keystore then that is not a supported way of usage. |
|
1862 */ |
|
1863 if (rsa->d != NULL) |
|
1864 { |
|
1865 if ((sp->opdata_rsa_d_num = BN_dup(rsa->d)) == NULL) |
|
1866 { |
|
1867 PK11err(PK11_F_GET_PRIV_RSA_KEY, PK11_R_MALLOC_FAILURE); |
|
1868 rollback = CK_TRUE; |
|
1869 goto err; |
|
1870 } |
|
1871 } |
|
1872 else |
|
1873 sp->opdata_rsa_d_num = NULL; |
|
1874 |
|
1875 /* |
|
1876 * For the key by reference code, we need public components as well |
|
1877 * since 'd' component is always NULL. For that reason, we always cache |
|
1878 * 'n'/'e' components as well. |
|
1879 */ |
|
1880 if ((sp->opdata_rsa_n_num = BN_dup(rsa->n)) == NULL) |
|
1881 { |
|
1882 PK11err(PK11_F_GET_PUB_RSA_KEY, PK11_R_MALLOC_FAILURE); |
|
1883 sp->opdata_rsa_n_num = NULL; |
|
1884 rollback = CK_TRUE; |
|
1885 goto err; |
|
1886 } |
|
1887 if ((sp->opdata_rsa_e_num = BN_dup(rsa->e)) == NULL) |
|
1888 { |
|
1889 PK11err(PK11_F_GET_PUB_RSA_KEY, PK11_R_MALLOC_FAILURE); |
|
1890 BN_free(sp->opdata_rsa_n_num); |
|
1891 sp->opdata_rsa_n_num = NULL; |
|
1892 rollback = CK_TRUE; |
|
1893 goto err; |
|
1894 } |
|
1895 |
|
1896 /* LINTED: E_CONSTANT_CONDITION */ |
|
1897 KEY_HANDLE_REFHOLD(h_key, OP_RSA, CK_FALSE, rollback, err); |
|
1898 sp->opdata_rsa_priv = rsa; |
|
1899 |
|
1900 err: |
|
1901 if (rollback) |
|
1902 { |
|
1903 /* |
|
1904 * We do not care about the return value from C_DestroyObject() |
|
1905 * since we are doing rollback. |
|
1906 */ |
|
1907 if (found == 0) |
|
1908 (void) pFuncList->C_DestroyObject(sp->session, h_key); |
|
1909 h_key = CK_INVALID_HANDLE; |
|
1910 } |
|
1911 |
|
1912 UNLOCK_OBJSTORE(OP_RSA); |
|
1913 |
|
1914 malloc_err: |
|
1915 /* |
|
1916 * 6 to 13 entries in the key template are key components. |
|
1917 * They need to be freed upon exit or error. |
|
1918 */ |
|
1919 for (i = 6; i <= 13; i++) |
|
1920 { |
|
1921 if (a_key_template[i].pValue != NULL) |
|
1922 { |
|
1923 (void) memset(a_key_template[i].pValue, 0, |
|
1924 a_key_template[i].ulValueLen); |
|
1925 OPENSSL_free(a_key_template[i].pValue); |
|
1926 a_key_template[i].pValue = NULL; |
|
1927 } |
|
1928 } |
|
1929 |
|
1930 return (h_key); |
|
1931 } |
|
1932 |
|
1933 /* |
|
1934 * Check for cache miss. Objects are cleaned only if we have a full cache miss, |
|
1935 * meaning that it's a different RSA key pair. Return 1 for cache hit, 0 for |
|
1936 * cache miss. |
|
1937 */ |
|
1938 static int |
|
1939 pk11_check_new_rsa_key_pub(PK11_SESSION *sp, const RSA *rsa) |
|
1940 { |
|
1941 /* |
|
1942 * Provide protection against RSA structure reuse by making the |
|
1943 * check for cache hit stronger. Only public components of RSA |
|
1944 * key matter here so it is sufficient to compare them with values |
|
1945 * cached in PK11_SESSION structure. |
|
1946 * |
|
1947 * We must check the handle as well since with key by reference, public |
|
1948 * components 'n'/'e' are cached in private keys as well. That means we |
|
1949 * could have a cache hit in a private key when looking for a public |
|
1950 * key. That would not work, you cannot have one PKCS#11 object for |
|
1951 * both data signing and verifying. |
|
1952 */ |
|
1953 if (sp->opdata_rsa_pub == rsa && |
|
1954 BN_cmp(sp->opdata_rsa_n_num, rsa->n) == 0 && |
|
1955 BN_cmp(sp->opdata_rsa_e_num, rsa->e) == 0) |
|
1956 { |
|
1957 if (sp->opdata_rsa_pub_key != CK_INVALID_HANDLE) |
|
1958 return (1); |
|
1959 else |
|
1960 /* |
|
1961 * No public key object yet but we have the right RSA |
|
1962 * structure with potentially existing private key |
|
1963 * object. We can just create a public object and move |
|
1964 * on with this session structure. |
|
1965 */ |
|
1966 return (0); |
|
1967 } |
|
1968 |
|
1969 /* |
|
1970 * A different RSA key pair was using this session structure previously |
|
1971 * or it's an empty structure. Destroy what we can. |
|
1972 */ |
|
1973 (void) pk11_destroy_rsa_object_pub(sp, CK_TRUE); |
|
1974 (void) pk11_destroy_rsa_object_priv(sp, CK_TRUE); |
|
1975 return (0); |
|
1976 } |
|
1977 |
|
1978 /* |
|
1979 * Check for cache miss. Objects are cleaned only if we have a full cache miss, |
|
1980 * meaning that it's a different RSA key pair. Return 1 for cache hit, 0 for |
|
1981 * cache miss. |
|
1982 */ |
|
1983 static int |
|
1984 pk11_check_new_rsa_key_priv(PK11_SESSION *sp, const RSA *rsa) |
|
1985 { |
|
1986 /* |
|
1987 * Provide protection against RSA structure reuse by making the |
|
1988 * check for cache hit stronger. Comparing public exponent of RSA |
|
1989 * key with value cached in PK11_SESSION structure should |
|
1990 * be sufficient. Note that we want to compare the public component |
|
1991 * since with the keys by reference mechanism, private components are |
|
1992 * not in the RSA structure. Also, see pk11_check_new_rsa_key_pub() |
|
1993 * about why we compare the handle as well. |
|
1994 */ |
|
1995 if (sp->opdata_rsa_priv == rsa && |
|
1996 BN_cmp(sp->opdata_rsa_n_num, rsa->n) == 0 && |
|
1997 BN_cmp(sp->opdata_rsa_e_num, rsa->e) == 0) |
|
1998 { |
|
1999 if (sp->opdata_rsa_priv_key != CK_INVALID_HANDLE) |
|
2000 return (1); |
|
2001 else |
|
2002 /* |
|
2003 * No private key object yet but we have the right RSA |
|
2004 * structure with potentially existing public key |
|
2005 * object. We can just create a private object and move |
|
2006 * on with this session structure. |
|
2007 */ |
|
2008 return (0); |
|
2009 } |
|
2010 |
|
2011 /* |
|
2012 * A different RSA key pair was using this session structure previously |
|
2013 * or it's an empty structure. Destroy what we can. |
|
2014 */ |
|
2015 (void) pk11_destroy_rsa_object_priv(sp, CK_TRUE); |
|
2016 (void) pk11_destroy_rsa_object_pub(sp, CK_TRUE); |
|
2017 return (0); |
|
2018 } |
|
2019 #endif |
|
2020 |
|
2021 #ifndef OPENSSL_NO_DSA |
|
2022 /* The DSA function implementation */ |
|
2023 /* ARGSUSED */ |
|
2024 static int pk11_DSA_init(DSA *dsa) |
|
2025 { |
|
2026 return (1); |
|
2027 } |
|
2028 |
|
2029 /* ARGSUSED */ |
|
2030 static int pk11_DSA_finish(DSA *dsa) |
|
2031 { |
|
2032 return (1); |
|
2033 } |
|
2034 |
|
2035 |
|
2036 static DSA_SIG * |
|
2037 pk11_dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa) |
|
2038 { |
|
2039 BIGNUM *r = NULL, *s = NULL; |
|
2040 int i; |
|
2041 DSA_SIG *dsa_sig = NULL; |
|
2042 |
|
2043 CK_RV rv; |
|
2044 CK_MECHANISM Mechanism_dsa = {CKM_DSA, NULL, 0}; |
|
2045 CK_MECHANISM *p_mech = &Mechanism_dsa; |
|
2046 CK_OBJECT_HANDLE h_priv_key; |
|
2047 |
|
2048 /* |
|
2049 * The signature is the concatenation of r and s, |
|
2050 * each is 20 bytes long |
|
2051 */ |
|
2052 unsigned char sigret[DSA_SIGNATURE_LEN]; |
|
2053 unsigned long siglen = DSA_SIGNATURE_LEN; |
|
2054 unsigned int siglen2 = DSA_SIGNATURE_LEN / 2; |
|
2055 |
|
2056 PK11_SESSION *sp = NULL; |
|
2057 |
|
2058 if ((dsa->p == NULL) || (dsa->q == NULL) || (dsa->g == NULL)) |
|
2059 { |
|
2060 PK11err(PK11_F_DSA_SIGN, PK11_R_MISSING_KEY_COMPONENT); |
|
2061 goto ret; |
|
2062 } |
|
2063 |
|
2064 i = BN_num_bytes(dsa->q); /* should be 20 */ |
|
2065 if (dlen > i) |
|
2066 { |
|
2067 PK11err(PK11_F_DSA_SIGN, PK11_R_INVALID_SIGNATURE_LENGTH); |
|
2068 goto ret; |
|
2069 } |
|
2070 |
|
2071 if ((sp = pk11_get_session(OP_DSA)) == NULL) |
|
2072 goto ret; |
|
2073 |
|
2074 (void) check_new_dsa_key_priv(sp, dsa); |
|
2075 |
|
2076 h_priv_key = sp->opdata_dsa_priv_key; |
|
2077 if (h_priv_key == CK_INVALID_HANDLE) |
|
2078 h_priv_key = sp->opdata_dsa_priv_key = |
|
2079 pk11_get_private_dsa_key((DSA *)dsa, |
|
2080 &sp->opdata_dsa_priv, |
|
2081 &sp->opdata_dsa_priv_num, sp->session); |
|
2082 |
|
2083 if (h_priv_key != CK_INVALID_HANDLE) |
|
2084 { |
|
2085 rv = pFuncList->C_SignInit(sp->session, p_mech, h_priv_key); |
|
2086 |
|
2087 if (rv != CKR_OK) |
|
2088 { |
|
2089 PK11err_add_data(PK11_F_DSA_SIGN, PK11_R_SIGNINIT, rv); |
|
2090 goto ret; |
|
2091 } |
|
2092 |
|
2093 (void) memset(sigret, 0, siglen); |
|
2094 rv = pFuncList->C_Sign(sp->session, |
|
2095 (unsigned char *) dgst, dlen, sigret, |
|
2096 (CK_ULONG_PTR) &siglen); |
|
2097 |
|
2098 if (rv != CKR_OK) |
|
2099 { |
|
2100 PK11err_add_data(PK11_F_DSA_SIGN, PK11_R_SIGN, rv); |
|
2101 goto ret; |
|
2102 } |
|
2103 } |
|
2104 |
|
2105 |
|
2106 if ((s = BN_new()) == NULL) |
|
2107 { |
|
2108 PK11err(PK11_F_DSA_SIGN, PK11_R_MALLOC_FAILURE); |
|
2109 goto ret; |
|
2110 } |
|
2111 |
|
2112 if ((r = BN_new()) == NULL) |
|
2113 { |
|
2114 PK11err(PK11_F_DSA_SIGN, PK11_R_MALLOC_FAILURE); |
|
2115 goto ret; |
|
2116 } |
|
2117 |
|
2118 if ((dsa_sig = DSA_SIG_new()) == NULL) |
|
2119 { |
|
2120 PK11err(PK11_F_DSA_SIGN, PK11_R_MALLOC_FAILURE); |
|
2121 goto ret; |
|
2122 } |
|
2123 |
|
2124 if (BN_bin2bn(sigret, siglen2, r) == NULL || |
|
2125 BN_bin2bn(&sigret[siglen2], siglen2, s) == NULL) |
|
2126 { |
|
2127 PK11err(PK11_F_DSA_SIGN, PK11_R_MALLOC_FAILURE); |
|
2128 goto ret; |
|
2129 } |
|
2130 |
|
2131 dsa_sig->r = r; |
|
2132 dsa_sig->s = s; |
|
2133 |
|
2134 ret: |
|
2135 if (dsa_sig == NULL) |
|
2136 { |
|
2137 if (r != NULL) |
|
2138 BN_free(r); |
|
2139 if (s != NULL) |
|
2140 BN_free(s); |
|
2141 } |
|
2142 |
|
2143 pk11_return_session(sp, OP_DSA); |
|
2144 return (dsa_sig); |
|
2145 } |
|
2146 |
|
2147 static int |
|
2148 pk11_dsa_do_verify(const unsigned char *dgst, int dlen, DSA_SIG *sig, |
|
2149 DSA *dsa) |
|
2150 { |
|
2151 int i; |
|
2152 CK_RV rv; |
|
2153 int retval = 0; |
|
2154 CK_MECHANISM Mechanism_dsa = {CKM_DSA, NULL, 0}; |
|
2155 CK_MECHANISM *p_mech = &Mechanism_dsa; |
|
2156 CK_OBJECT_HANDLE h_pub_key; |
|
2157 |
|
2158 unsigned char sigbuf[DSA_SIGNATURE_LEN]; |
|
2159 unsigned long siglen = DSA_SIGNATURE_LEN; |
|
2160 unsigned long siglen2 = DSA_SIGNATURE_LEN/2; |
|
2161 |
|
2162 PK11_SESSION *sp = NULL; |
|
2163 |
|
2164 if (BN_is_zero(sig->r) || sig->r->neg || BN_ucmp(sig->r, dsa->q) >= 0) |
|
2165 { |
|
2166 PK11err(PK11_F_DSA_VERIFY, |
|
2167 PK11_R_INVALID_DSA_SIGNATURE_R); |
|
2168 goto ret; |
|
2169 } |
|
2170 |
|
2171 if (BN_is_zero(sig->s) || sig->s->neg || BN_ucmp(sig->s, dsa->q) >= 0) |
|
2172 { |
|
2173 PK11err(PK11_F_DSA_VERIFY, |
|
2174 PK11_R_INVALID_DSA_SIGNATURE_S); |
|
2175 goto ret; |
|
2176 } |
|
2177 |
|
2178 i = BN_num_bytes(dsa->q); /* should be 20 */ |
|
2179 |
|
2180 if (dlen > i) |
|
2181 { |
|
2182 PK11err(PK11_F_DSA_VERIFY, |
|
2183 PK11_R_INVALID_SIGNATURE_LENGTH); |
|
2184 goto ret; |
|
2185 } |
|
2186 |
|
2187 if ((sp = pk11_get_session(OP_DSA)) == NULL) |
|
2188 goto ret; |
|
2189 |
|
2190 (void) check_new_dsa_key_pub(sp, dsa); |
|
2191 |
|
2192 h_pub_key = sp->opdata_dsa_pub_key; |
|
2193 if (h_pub_key == CK_INVALID_HANDLE) |
|
2194 h_pub_key = sp->opdata_dsa_pub_key = |
|
2195 pk11_get_public_dsa_key((DSA *)dsa, &sp->opdata_dsa_pub, |
|
2196 &sp->opdata_dsa_pub_num, sp->session); |
|
2197 |
|
2198 if (h_pub_key != CK_INVALID_HANDLE) |
|
2199 { |
|
2200 rv = pFuncList->C_VerifyInit(sp->session, p_mech, |
|
2201 h_pub_key); |
|
2202 |
|
2203 if (rv != CKR_OK) |
|
2204 { |
|
2205 PK11err_add_data(PK11_F_DSA_VERIFY, PK11_R_VERIFYINIT, |
|
2206 rv); |
|
2207 goto ret; |
|
2208 } |
|
2209 |
|
2210 /* |
|
2211 * The representation of each of the two big numbers could |
|
2212 * be shorter than DSA_SIGNATURE_LEN/2 bytes so we need |
|
2213 * to act accordingly and shift if necessary. |
|
2214 */ |
|
2215 (void) memset(sigbuf, 0, siglen); |
|
2216 BN_bn2bin(sig->r, sigbuf + siglen2 - BN_num_bytes(sig->r)); |
|
2217 BN_bn2bin(sig->s, &sigbuf[siglen2] + siglen2 - |
|
2218 BN_num_bytes(sig->s)); |
|
2219 |
|
2220 rv = pFuncList->C_Verify(sp->session, |
|
2221 (unsigned char *) dgst, dlen, sigbuf, (CK_ULONG)siglen); |
|
2222 |
|
2223 if (rv != CKR_OK) |
|
2224 { |
|
2225 PK11err_add_data(PK11_F_DSA_VERIFY, PK11_R_VERIFY, rv); |
|
2226 goto ret; |
|
2227 } |
|
2228 } |
|
2229 |
|
2230 retval = 1; |
|
2231 ret: |
|
2232 |
|
2233 pk11_return_session(sp, OP_DSA); |
|
2234 return (retval); |
|
2235 } |
|
2236 |
|
2237 |
|
2238 /* |
|
2239 * Create a public key object in a session from a given dsa structure. |
|
2240 * The *dsa_pub_num pointer is non-NULL for DSA public keys. |
|
2241 */ |
|
2242 static CK_OBJECT_HANDLE pk11_get_public_dsa_key(DSA* dsa, |
|
2243 DSA **key_ptr, BIGNUM **dsa_pub_num, CK_SESSION_HANDLE session) |
|
2244 { |
|
2245 CK_RV rv; |
|
2246 CK_OBJECT_CLASS o_key = CKO_PUBLIC_KEY; |
|
2247 CK_OBJECT_HANDLE h_key = CK_INVALID_HANDLE; |
|
2248 CK_ULONG found; |
|
2249 CK_KEY_TYPE k_type = CKK_DSA; |
|
2250 CK_ULONG ul_key_attr_count = 8; |
|
2251 CK_BBOOL rollback = CK_FALSE; |
|
2252 int i; |
|
2253 |
|
2254 CK_ATTRIBUTE a_key_template[] = |
|
2255 { |
|
2256 {CKA_CLASS, (void *) NULL, sizeof (CK_OBJECT_CLASS)}, |
|
2257 {CKA_KEY_TYPE, (void *) NULL, sizeof (CK_KEY_TYPE)}, |
|
2258 {CKA_TOKEN, &pk11_false, sizeof (pk11_false)}, |
|
2259 {CKA_VERIFY, &pk11_true, sizeof (pk11_true)}, |
|
2260 {CKA_PRIME, (void *)NULL, 0}, /* p */ |
|
2261 {CKA_SUBPRIME, (void *)NULL, 0}, /* q */ |
|
2262 {CKA_BASE, (void *)NULL, 0}, /* g */ |
|
2263 {CKA_VALUE, (void *)NULL, 0} /* pub_key - y */ |
|
2264 }; |
|
2265 |
|
2266 a_key_template[0].pValue = &o_key; |
|
2267 a_key_template[1].pValue = &k_type; |
|
2268 |
|
2269 if (init_template_value(dsa->p, &a_key_template[4].pValue, |
|
2270 &a_key_template[4].ulValueLen) == 0 || |
|
2271 init_template_value(dsa->q, &a_key_template[5].pValue, |
|
2272 &a_key_template[5].ulValueLen) == 0 || |
|
2273 init_template_value(dsa->g, &a_key_template[6].pValue, |
|
2274 &a_key_template[6].ulValueLen) == 0 || |
|
2275 init_template_value(dsa->pub_key, &a_key_template[7].pValue, |
|
2276 &a_key_template[7].ulValueLen) == 0) |
|
2277 { |
|
2278 PK11err(PK11_F_GET_PUB_DSA_KEY, PK11_R_MALLOC_FAILURE); |
|
2279 goto malloc_err; |
|
2280 } |
|
2281 |
|
2282 /* see find_lock array definition for more info on object locking */ |
|
2283 LOCK_OBJSTORE(OP_DSA); |
|
2284 rv = pFuncList->C_FindObjectsInit(session, a_key_template, |
|
2285 ul_key_attr_count); |
|
2286 |
|
2287 if (rv != CKR_OK) |
|
2288 { |
|
2289 PK11err_add_data(PK11_F_GET_PUB_DSA_KEY, |
|
2290 PK11_R_FINDOBJECTSINIT, rv); |
|
2291 goto err; |
|
2292 } |
|
2293 |
|
2294 rv = pFuncList->C_FindObjects(session, &h_key, 1, &found); |
|
2295 |
|
2296 if (rv != CKR_OK) |
|
2297 { |
|
2298 PK11err_add_data(PK11_F_GET_PUB_DSA_KEY, |
|
2299 PK11_R_FINDOBJECTS, rv); |
|
2300 goto err; |
|
2301 } |
|
2302 |
|
2303 rv = pFuncList->C_FindObjectsFinal(session); |
|
2304 |
|
2305 if (rv != CKR_OK) |
|
2306 { |
|
2307 PK11err_add_data(PK11_F_GET_PUB_DSA_KEY, |
|
2308 PK11_R_FINDOBJECTSFINAL, rv); |
|
2309 goto err; |
|
2310 } |
|
2311 |
|
2312 if (found == 0) |
|
2313 { |
|
2314 rv = pFuncList->C_CreateObject(session, |
|
2315 a_key_template, ul_key_attr_count, &h_key); |
|
2316 if (rv != CKR_OK) |
|
2317 { |
|
2318 PK11err_add_data(PK11_F_GET_PUB_DSA_KEY, |
|
2319 PK11_R_CREATEOBJECT, rv); |
|
2320 goto err; |
|
2321 } |
|
2322 } |
|
2323 |
|
2324 if (dsa_pub_num != NULL) |
|
2325 if ((*dsa_pub_num = BN_dup(dsa->pub_key)) == NULL) |
|
2326 { |
|
2327 PK11err(PK11_F_GET_PUB_DSA_KEY, PK11_R_MALLOC_FAILURE); |
|
2328 rollback = CK_TRUE; |
|
2329 goto err; |
|
2330 } |
|
2331 |
|
2332 /* LINTED: E_CONSTANT_CONDITION */ |
|
2333 KEY_HANDLE_REFHOLD(h_key, OP_DSA, CK_FALSE, rollback, err); |
|
2334 if (key_ptr != NULL) |
|
2335 *key_ptr = dsa; |
|
2336 |
|
2337 err: |
|
2338 if (rollback) |
|
2339 { |
|
2340 /* |
|
2341 * We do not care about the return value from C_DestroyObject() |
|
2342 * since we are doing rollback. |
|
2343 */ |
|
2344 if (found == 0) |
|
2345 (void) pFuncList->C_DestroyObject(session, h_key); |
|
2346 h_key = CK_INVALID_HANDLE; |
|
2347 } |
|
2348 |
|
2349 UNLOCK_OBJSTORE(OP_DSA); |
|
2350 |
|
2351 malloc_err: |
|
2352 for (i = 4; i <= 7; i++) |
|
2353 { |
|
2354 if (a_key_template[i].pValue != NULL) |
|
2355 { |
|
2356 OPENSSL_free(a_key_template[i].pValue); |
|
2357 a_key_template[i].pValue = NULL; |
|
2358 } |
|
2359 } |
|
2360 |
|
2361 return (h_key); |
|
2362 } |
|
2363 |
|
2364 /* |
|
2365 * Create a private key object in the session from a given dsa structure |
|
2366 * The *dsa_priv_num pointer is non-NULL for DSA private keys. |
|
2367 */ |
|
2368 static CK_OBJECT_HANDLE pk11_get_private_dsa_key(DSA* dsa, |
|
2369 DSA **key_ptr, BIGNUM **dsa_priv_num, CK_SESSION_HANDLE session) |
|
2370 { |
|
2371 CK_RV rv; |
|
2372 CK_OBJECT_HANDLE h_key = CK_INVALID_HANDLE; |
|
2373 CK_OBJECT_CLASS o_key = CKO_PRIVATE_KEY; |
|
2374 int i; |
|
2375 CK_ULONG found; |
|
2376 CK_KEY_TYPE k_type = CKK_DSA; |
|
2377 CK_ULONG ul_key_attr_count = 9; |
|
2378 CK_BBOOL rollback = CK_FALSE; |
|
2379 |
|
2380 /* |
|
2381 * Both CKA_TOKEN and CKA_SENSITIVE have to be CK_FALSE for session keys |
|
2382 */ |
|
2383 CK_ATTRIBUTE a_key_template[] = |
|
2384 { |
|
2385 {CKA_CLASS, (void *) NULL, sizeof (CK_OBJECT_CLASS)}, |
|
2386 {CKA_KEY_TYPE, (void *) NULL, sizeof (CK_KEY_TYPE)}, |
|
2387 {CKA_TOKEN, &pk11_false, sizeof (pk11_false)}, |
|
2388 {CKA_SENSITIVE, &pk11_false, sizeof (pk11_false)}, |
|
2389 {CKA_SIGN, &pk11_true, sizeof (pk11_true)}, |
|
2390 {CKA_PRIME, (void *)NULL, 0}, /* p */ |
|
2391 {CKA_SUBPRIME, (void *)NULL, 0}, /* q */ |
|
2392 {CKA_BASE, (void *)NULL, 0}, /* g */ |
|
2393 {CKA_VALUE, (void *)NULL, 0} /* priv_key - x */ |
|
2394 }; |
|
2395 |
|
2396 a_key_template[0].pValue = &o_key; |
|
2397 a_key_template[1].pValue = &k_type; |
|
2398 |
|
2399 /* Put the private key components into the template */ |
|
2400 if (init_template_value(dsa->p, &a_key_template[5].pValue, |
|
2401 &a_key_template[5].ulValueLen) == 0 || |
|
2402 init_template_value(dsa->q, &a_key_template[6].pValue, |
|
2403 &a_key_template[6].ulValueLen) == 0 || |
|
2404 init_template_value(dsa->g, &a_key_template[7].pValue, |
|
2405 &a_key_template[7].ulValueLen) == 0 || |
|
2406 init_template_value(dsa->priv_key, &a_key_template[8].pValue, |
|
2407 &a_key_template[8].ulValueLen) == 0) |
|
2408 { |
|
2409 PK11err(PK11_F_GET_PRIV_DSA_KEY, PK11_R_MALLOC_FAILURE); |
|
2410 goto malloc_err; |
|
2411 } |
|
2412 |
|
2413 /* see find_lock array definition for more info on object locking */ |
|
2414 LOCK_OBJSTORE(OP_DSA); |
|
2415 rv = pFuncList->C_FindObjectsInit(session, a_key_template, |
|
2416 ul_key_attr_count); |
|
2417 |
|
2418 if (rv != CKR_OK) |
|
2419 { |
|
2420 PK11err_add_data(PK11_F_GET_PRIV_DSA_KEY, |
|
2421 PK11_R_FINDOBJECTSINIT, rv); |
|
2422 goto err; |
|
2423 } |
|
2424 |
|
2425 rv = pFuncList->C_FindObjects(session, &h_key, 1, &found); |
|
2426 |
|
2427 if (rv != CKR_OK) |
|
2428 { |
|
2429 PK11err_add_data(PK11_F_GET_PRIV_DSA_KEY, |
|
2430 PK11_R_FINDOBJECTS, rv); |
|
2431 goto err; |
|
2432 } |
|
2433 |
|
2434 rv = pFuncList->C_FindObjectsFinal(session); |
|
2435 |
|
2436 if (rv != CKR_OK) |
|
2437 { |
|
2438 PK11err_add_data(PK11_F_GET_PRIV_DSA_KEY, |
|
2439 PK11_R_FINDOBJECTSFINAL, rv); |
|
2440 goto err; |
|
2441 } |
|
2442 |
|
2443 if (found == 0) |
|
2444 { |
|
2445 rv = pFuncList->C_CreateObject(session, |
|
2446 a_key_template, ul_key_attr_count, &h_key); |
|
2447 if (rv != CKR_OK) |
|
2448 { |
|
2449 PK11err_add_data(PK11_F_GET_PRIV_DSA_KEY, |
|
2450 PK11_R_CREATEOBJECT, rv); |
|
2451 goto err; |
|
2452 } |
|
2453 } |
|
2454 |
|
2455 if (dsa_priv_num != NULL) |
|
2456 if ((*dsa_priv_num = BN_dup(dsa->priv_key)) == NULL) |
|
2457 { |
|
2458 PK11err(PK11_F_GET_PRIV_DSA_KEY, PK11_R_MALLOC_FAILURE); |
|
2459 rollback = CK_TRUE; |
|
2460 goto err; |
|
2461 } |
|
2462 |
|
2463 /* LINTED: E_CONSTANT_CONDITION */ |
|
2464 KEY_HANDLE_REFHOLD(h_key, OP_DSA, CK_FALSE, rollback, err); |
|
2465 if (key_ptr != NULL) |
|
2466 *key_ptr = dsa; |
|
2467 |
|
2468 err: |
|
2469 if (rollback) |
|
2470 { |
|
2471 /* |
|
2472 * We do not care about the return value from C_DestroyObject() |
|
2473 * since we are doing rollback. |
|
2474 */ |
|
2475 if (found == 0) |
|
2476 (void) pFuncList->C_DestroyObject(session, h_key); |
|
2477 h_key = CK_INVALID_HANDLE; |
|
2478 } |
|
2479 |
|
2480 UNLOCK_OBJSTORE(OP_DSA); |
|
2481 |
|
2482 malloc_err: |
|
2483 /* |
|
2484 * 5 to 8 entries in the key template are key components. |
|
2485 * They need to be freed apon exit or error. |
|
2486 */ |
|
2487 for (i = 5; i <= 8; i++) |
|
2488 { |
|
2489 if (a_key_template[i].pValue != NULL) |
|
2490 { |
|
2491 (void) memset(a_key_template[i].pValue, 0, |
|
2492 a_key_template[i].ulValueLen); |
|
2493 OPENSSL_free(a_key_template[i].pValue); |
|
2494 a_key_template[i].pValue = NULL; |
|
2495 } |
|
2496 } |
|
2497 |
|
2498 return (h_key); |
|
2499 } |
|
2500 |
|
2501 /* |
|
2502 * Check for cache miss and clean the object pointer and handle |
|
2503 * in such case. Return 1 for cache hit, 0 for cache miss. |
|
2504 */ |
|
2505 static int check_new_dsa_key_pub(PK11_SESSION *sp, DSA *dsa) |
|
2506 { |
|
2507 /* |
|
2508 * Provide protection against DSA structure reuse by making the |
|
2509 * check for cache hit stronger. Only public key component of DSA |
|
2510 * key matters here so it is sufficient to compare it with value |
|
2511 * cached in PK11_SESSION structure. |
|
2512 */ |
|
2513 if ((sp->opdata_dsa_pub != dsa) || |
|
2514 (BN_cmp(sp->opdata_dsa_pub_num, dsa->pub_key) != 0)) |
|
2515 { |
|
2516 /* |
|
2517 * We do not check the return value because even in case of |
|
2518 * failure the sp structure will have both key pointer |
|
2519 * and object handle cleaned and pk11_destroy_object() |
|
2520 * reports the failure to the OpenSSL error message buffer. |
|
2521 */ |
|
2522 (void) pk11_destroy_dsa_object_pub(sp, CK_TRUE); |
|
2523 return (0); |
|
2524 } |
|
2525 return (1); |
|
2526 } |
|
2527 |
|
2528 /* |
|
2529 * Check for cache miss and clean the object pointer and handle |
|
2530 * in such case. Return 1 for cache hit, 0 for cache miss. |
|
2531 */ |
|
2532 static int check_new_dsa_key_priv(PK11_SESSION *sp, DSA *dsa) |
|
2533 { |
|
2534 /* |
|
2535 * Provide protection against DSA structure reuse by making the |
|
2536 * check for cache hit stronger. Only private key component of DSA |
|
2537 * key matters here so it is sufficient to compare it with value |
|
2538 * cached in PK11_SESSION structure. |
|
2539 */ |
|
2540 if ((sp->opdata_dsa_priv != dsa) || |
|
2541 (BN_cmp(sp->opdata_dsa_priv_num, dsa->priv_key) != 0)) |
|
2542 { |
|
2543 /* |
|
2544 * We do not check the return value because even in case of |
|
2545 * failure the sp structure will have both key pointer |
|
2546 * and object handle cleaned and pk11_destroy_object() |
|
2547 * reports the failure to the OpenSSL error message buffer. |
|
2548 */ |
|
2549 (void) pk11_destroy_dsa_object_priv(sp, CK_TRUE); |
|
2550 return (0); |
|
2551 } |
|
2552 return (1); |
|
2553 } |
|
2554 #endif |
|
2555 |
|
2556 |
|
2557 #ifndef OPENSSL_NO_DH |
|
2558 /* The DH function implementation */ |
|
2559 /* ARGSUSED */ |
|
2560 static int pk11_DH_init(DH *dh) |
|
2561 { |
|
2562 return (1); |
|
2563 } |
|
2564 |
|
2565 /* ARGSUSED */ |
|
2566 static int pk11_DH_finish(DH *dh) |
|
2567 { |
|
2568 return (1); |
|
2569 } |
|
2570 |
|
2571 /* |
|
2572 * Generate DH key-pair. |
|
2573 * |
|
2574 * Warning: Unlike OpenSSL's DH_generate_key(3) we ignore dh->priv_key |
|
2575 * and override it even if it is set. OpenSSL does not touch dh->priv_key |
|
2576 * if set and just computes dh->pub_key. It looks like PKCS#11 standard |
|
2577 * is not capable of providing this functionality. This could be a problem |
|
2578 * for applications relying on OpenSSL's semantics. |
|
2579 */ |
|
2580 static int pk11_DH_generate_key(DH *dh) |
|
2581 { |
|
2582 CK_ULONG i; |
|
2583 CK_RV rv, rv1; |
|
2584 int reuse_mem_len = 0, ret = 0; |
|
2585 PK11_SESSION *sp = NULL; |
|
2586 CK_BYTE_PTR reuse_mem; |
|
2587 |
|
2588 CK_MECHANISM mechanism = {CKM_DH_PKCS_KEY_PAIR_GEN, NULL_PTR, 0}; |
|
2589 CK_OBJECT_HANDLE h_pub_key = CK_INVALID_HANDLE; |
|
2590 CK_OBJECT_HANDLE h_priv_key = CK_INVALID_HANDLE; |
|
2591 |
|
2592 CK_ULONG ul_pub_key_attr_count = 3; |
|
2593 CK_ATTRIBUTE pub_key_template[] = |
|
2594 { |
|
2595 {CKA_PRIVATE, &pk11_false, sizeof (pk11_false)}, |
|
2596 {CKA_PRIME, (void *)NULL, 0}, |
|
2597 {CKA_BASE, (void *)NULL, 0} |
|
2598 }; |
|
2599 |
|
2600 CK_ULONG ul_priv_key_attr_count = 3; |
|
2601 CK_ATTRIBUTE priv_key_template[] = |
|
2602 { |
|
2603 {CKA_PRIVATE, &pk11_false, sizeof (pk11_false)}, |
|
2604 {CKA_SENSITIVE, &pk11_false, sizeof (pk11_false)}, |
|
2605 {CKA_DERIVE, &pk11_true, sizeof (pk11_true)} |
|
2606 }; |
|
2607 |
|
2608 CK_ULONG pub_key_attr_result_count = 1; |
|
2609 CK_ATTRIBUTE pub_key_result[] = |
|
2610 { |
|
2611 {CKA_VALUE, (void *)NULL, 0} |
|
2612 }; |
|
2613 |
|
2614 CK_ULONG priv_key_attr_result_count = 1; |
|
2615 CK_ATTRIBUTE priv_key_result[] = |
|
2616 { |
|
2617 {CKA_VALUE, (void *)NULL, 0} |
|
2618 }; |
|
2619 |
|
2620 pub_key_template[1].ulValueLen = BN_num_bytes(dh->p); |
|
2621 if (pub_key_template[1].ulValueLen > 0) |
|
2622 { |
|
2623 /* |
|
2624 * We must not increase ulValueLen by DH_BUF_RESERVE since that |
|
2625 * could cause the same rounding problem. See definition of |
|
2626 * DH_BUF_RESERVE above. |
|
2627 */ |
|
2628 pub_key_template[1].pValue = |
|
2629 OPENSSL_malloc(pub_key_template[1].ulValueLen + |
|
2630 DH_BUF_RESERVE); |
|
2631 if (pub_key_template[1].pValue == NULL) |
|
2632 { |
|
2633 PK11err(PK11_F_DH_GEN_KEY, PK11_R_MALLOC_FAILURE); |
|
2634 goto err; |
|
2635 } |
|
2636 |
|
2637 i = BN_bn2bin(dh->p, pub_key_template[1].pValue); |
|
2638 } |
|
2639 else |
|
2640 goto err; |
|
2641 |
|
2642 pub_key_template[2].ulValueLen = BN_num_bytes(dh->g); |
|
2643 if (pub_key_template[2].ulValueLen > 0) |
|
2644 { |
|
2645 pub_key_template[2].pValue = |
|
2646 OPENSSL_malloc(pub_key_template[2].ulValueLen + |
|
2647 DH_BUF_RESERVE); |
|
2648 if (pub_key_template[2].pValue == NULL) |
|
2649 { |
|
2650 PK11err(PK11_F_DH_GEN_KEY, PK11_R_MALLOC_FAILURE); |
|
2651 goto err; |
|
2652 } |
|
2653 |
|
2654 i = BN_bn2bin(dh->g, pub_key_template[2].pValue); |
|
2655 } |
|
2656 else |
|
2657 goto err; |
|
2658 |
|
2659 /* |
|
2660 * Note: we are only using PK11_SESSION structure for getting |
|
2661 * a session handle. The objects created in this function are |
|
2662 * destroyed before return and thus not cached. |
|
2663 */ |
|
2664 if ((sp = pk11_get_session(OP_DH)) == NULL) |
|
2665 goto err; |
|
2666 |
|
2667 rv = pFuncList->C_GenerateKeyPair(sp->session, |
|
2668 &mechanism, |
|
2669 pub_key_template, |
|
2670 ul_pub_key_attr_count, |
|
2671 priv_key_template, |
|
2672 ul_priv_key_attr_count, |
|
2673 &h_pub_key, |
|
2674 &h_priv_key); |
|
2675 if (rv != CKR_OK) |
|
2676 { |
|
2677 PK11err_add_data(PK11_F_DH_GEN_KEY, PK11_R_GEN_KEY, rv); |
|
2678 goto err; |
|
2679 } |
|
2680 |
|
2681 /* |
|
2682 * Reuse the larger memory allocated. We know the larger memory |
|
2683 * should be sufficient for reuse. |
|
2684 */ |
|
2685 if (pub_key_template[1].ulValueLen > pub_key_template[2].ulValueLen) |
|
2686 { |
|
2687 reuse_mem = pub_key_template[1].pValue; |
|
2688 reuse_mem_len = pub_key_template[1].ulValueLen + DH_BUF_RESERVE; |
|
2689 } |
|
2690 else |
|
2691 { |
|
2692 reuse_mem = pub_key_template[2].pValue; |
|
2693 reuse_mem_len = pub_key_template[2].ulValueLen + DH_BUF_RESERVE; |
|
2694 } |
|
2695 |
|
2696 rv = pFuncList->C_GetAttributeValue(sp->session, h_pub_key, |
|
2697 pub_key_result, pub_key_attr_result_count); |
|
2698 rv1 = pFuncList->C_GetAttributeValue(sp->session, h_priv_key, |
|
2699 priv_key_result, priv_key_attr_result_count); |
|
2700 |
|
2701 if (rv != CKR_OK || rv1 != CKR_OK) |
|
2702 { |
|
2703 rv = (rv != CKR_OK) ? rv : rv1; |
|
2704 PK11err_add_data(PK11_F_DH_GEN_KEY, |
|
2705 PK11_R_GETATTRIBUTVALUE, rv); |
|
2706 goto err; |
|
2707 } |
|
2708 |
|
2709 if (((CK_LONG) pub_key_result[0].ulValueLen) <= 0 || |
|
2710 ((CK_LONG) priv_key_result[0].ulValueLen) <= 0) |
|
2711 { |
|
2712 PK11err(PK11_F_DH_GEN_KEY, PK11_R_GETATTRIBUTVALUE); |
|
2713 goto err; |
|
2714 } |
|
2715 |
|
2716 /* Reuse the memory allocated */ |
|
2717 pub_key_result[0].pValue = reuse_mem; |
|
2718 pub_key_result[0].ulValueLen = reuse_mem_len; |
|
2719 |
|
2720 rv = pFuncList->C_GetAttributeValue(sp->session, h_pub_key, |
|
2721 pub_key_result, pub_key_attr_result_count); |
|
2722 |
|
2723 if (rv != CKR_OK) |
|
2724 { |
|
2725 PK11err_add_data(PK11_F_DH_GEN_KEY, |
|
2726 PK11_R_GETATTRIBUTVALUE, rv); |
|
2727 goto err; |
|
2728 } |
|
2729 |
|
2730 if (pub_key_result[0].type == CKA_VALUE) |
|
2731 { |
|
2732 if (dh->pub_key == NULL) |
|
2733 if ((dh->pub_key = BN_new()) == NULL) |
|
2734 { |
|
2735 PK11err(PK11_F_DH_GEN_KEY, |
|
2736 PK11_R_MALLOC_FAILURE); |
|
2737 goto err; |
|
2738 } |
|
2739 dh->pub_key = BN_bin2bn(pub_key_result[0].pValue, |
|
2740 pub_key_result[0].ulValueLen, dh->pub_key); |
|
2741 if (dh->pub_key == NULL) |
|
2742 { |
|
2743 PK11err(PK11_F_DH_GEN_KEY, PK11_R_MALLOC_FAILURE); |
|
2744 goto err; |
|
2745 } |
|
2746 } |
|
2747 |
|
2748 /* Reuse the memory allocated */ |
|
2749 priv_key_result[0].pValue = reuse_mem; |
|
2750 priv_key_result[0].ulValueLen = reuse_mem_len; |
|
2751 |
|
2752 rv = pFuncList->C_GetAttributeValue(sp->session, h_priv_key, |
|
2753 priv_key_result, priv_key_attr_result_count); |
|
2754 |
|
2755 if (rv != CKR_OK) |
|
2756 { |
|
2757 PK11err_add_data(PK11_F_DH_GEN_KEY, |
|
2758 PK11_R_GETATTRIBUTVALUE, rv); |
|
2759 goto err; |
|
2760 } |
|
2761 |
|
2762 if (priv_key_result[0].type == CKA_VALUE) |
|
2763 { |
|
2764 if (dh->priv_key == NULL) |
|
2765 if ((dh->priv_key = BN_new()) == NULL) |
|
2766 { |
|
2767 PK11err(PK11_F_DH_GEN_KEY, |
|
2768 PK11_R_MALLOC_FAILURE); |
|
2769 goto err; |
|
2770 } |
|
2771 dh->priv_key = BN_bin2bn(priv_key_result[0].pValue, |
|
2772 priv_key_result[0].ulValueLen, dh->priv_key); |
|
2773 if (dh->priv_key == NULL) |
|
2774 { |
|
2775 PK11err(PK11_F_DH_GEN_KEY, PK11_R_MALLOC_FAILURE); |
|
2776 goto err; |
|
2777 } |
|
2778 } |
|
2779 |
|
2780 ret = 1; |
|
2781 |
|
2782 err: |
|
2783 |
|
2784 if (h_pub_key != CK_INVALID_HANDLE) |
|
2785 { |
|
2786 rv = pFuncList->C_DestroyObject(sp->session, h_pub_key); |
|
2787 if (rv != CKR_OK) |
|
2788 { |
|
2789 PK11err_add_data(PK11_F_DH_GEN_KEY, |
|
2790 PK11_R_DESTROYOBJECT, rv); |
|
2791 } |
|
2792 } |
|
2793 |
|
2794 if (h_priv_key != CK_INVALID_HANDLE) |
|
2795 { |
|
2796 rv = pFuncList->C_DestroyObject(sp->session, h_priv_key); |
|
2797 if (rv != CKR_OK) |
|
2798 { |
|
2799 PK11err_add_data(PK11_F_DH_GEN_KEY, |
|
2800 PK11_R_DESTROYOBJECT, rv); |
|
2801 } |
|
2802 } |
|
2803 |
|
2804 for (i = 1; i <= 2; i++) |
|
2805 { |
|
2806 if (pub_key_template[i].pValue != NULL) |
|
2807 { |
|
2808 OPENSSL_free(pub_key_template[i].pValue); |
|
2809 pub_key_template[i].pValue = NULL; |
|
2810 } |
|
2811 } |
|
2812 |
|
2813 pk11_return_session(sp, OP_DH); |
|
2814 return (ret); |
|
2815 } |
|
2816 |
|
2817 static int pk11_DH_compute_key(unsigned char *key, const BIGNUM *pub_key, |
|
2818 DH *dh) |
|
2819 { |
|
2820 int i; |
|
2821 CK_MECHANISM mechanism = {CKM_DH_PKCS_DERIVE, NULL_PTR, 0}; |
|
2822 CK_OBJECT_CLASS key_class = CKO_SECRET_KEY; |
|
2823 CK_KEY_TYPE key_type = CKK_GENERIC_SECRET; |
|
2824 CK_OBJECT_HANDLE h_derived_key = CK_INVALID_HANDLE; |
|
2825 CK_OBJECT_HANDLE h_key = CK_INVALID_HANDLE; |
|
2826 |
|
2827 CK_ULONG ul_priv_key_attr_count = 2; |
|
2828 CK_ATTRIBUTE priv_key_template[] = |
|
2829 { |
|
2830 {CKA_CLASS, (void*) NULL, sizeof (key_class)}, |
|
2831 {CKA_KEY_TYPE, (void*) NULL, sizeof (key_type)}, |
|
2832 }; |
|
2833 |
|
2834 CK_ULONG priv_key_attr_result_count = 1; |
|
2835 CK_ATTRIBUTE priv_key_result[] = |
|
2836 { |
|
2837 {CKA_VALUE, (void *)NULL, 0} |
|
2838 }; |
|
2839 |
|
2840 CK_RV rv; |
|
2841 int ret = -1; |
|
2842 PK11_SESSION *sp = NULL; |
|
2843 |
|
2844 if (dh->priv_key == NULL) |
|
2845 goto err; |
|
2846 |
|
2847 priv_key_template[0].pValue = &key_class; |
|
2848 priv_key_template[1].pValue = &key_type; |
|
2849 |
|
2850 if ((sp = pk11_get_session(OP_DH)) == NULL) |
|
2851 goto err; |
|
2852 |
|
2853 mechanism.ulParameterLen = BN_num_bytes(pub_key); |
|
2854 mechanism.pParameter = OPENSSL_malloc(mechanism.ulParameterLen); |
|
2855 if (mechanism.pParameter == NULL) |
|
2856 { |
|
2857 PK11err(PK11_F_DH_COMP_KEY, PK11_R_MALLOC_FAILURE); |
|
2858 goto err; |
|
2859 } |
|
2860 BN_bn2bin(pub_key, mechanism.pParameter); |
|
2861 |
|
2862 (void) check_new_dh_key(sp, dh); |
|
2863 |
|
2864 h_key = sp->opdata_dh_key; |
|
2865 if (h_key == CK_INVALID_HANDLE) |
|
2866 h_key = sp->opdata_dh_key = |
|
2867 pk11_get_dh_key((DH*) dh, &sp->opdata_dh, |
|
2868 &sp->opdata_dh_priv_num, sp->session); |
|
2869 |
|
2870 if (h_key == CK_INVALID_HANDLE) |
|
2871 { |
|
2872 PK11err(PK11_F_DH_COMP_KEY, PK11_R_CREATEOBJECT); |
|
2873 goto err; |
|
2874 } |
|
2875 |
|
2876 rv = pFuncList->C_DeriveKey(sp->session, |
|
2877 &mechanism, |
|
2878 h_key, |
|
2879 priv_key_template, |
|
2880 ul_priv_key_attr_count, |
|
2881 &h_derived_key); |
|
2882 if (rv != CKR_OK) |
|
2883 { |
|
2884 PK11err_add_data(PK11_F_DH_COMP_KEY, PK11_R_DERIVEKEY, rv); |
|
2885 goto err; |
|
2886 } |
|
2887 |
|
2888 rv = pFuncList->C_GetAttributeValue(sp->session, h_derived_key, |
|
2889 priv_key_result, priv_key_attr_result_count); |
|
2890 |
|
2891 if (rv != CKR_OK) |
|
2892 { |
|
2893 PK11err_add_data(PK11_F_DH_COMP_KEY, PK11_R_GETATTRIBUTVALUE, |
|
2894 rv); |
|
2895 goto err; |
|
2896 } |
|
2897 |
|
2898 if (((CK_LONG) priv_key_result[0].ulValueLen) <= 0) |
|
2899 { |
|
2900 PK11err(PK11_F_DH_COMP_KEY, PK11_R_GETATTRIBUTVALUE); |
|
2901 goto err; |
|
2902 } |
|
2903 priv_key_result[0].pValue = |
|
2904 OPENSSL_malloc(priv_key_result[0].ulValueLen); |
|
2905 if (!priv_key_result[0].pValue) |
|
2906 { |
|
2907 PK11err(PK11_F_DH_COMP_KEY, PK11_R_MALLOC_FAILURE); |
|
2908 goto err; |
|
2909 } |
|
2910 |
|
2911 rv = pFuncList->C_GetAttributeValue(sp->session, h_derived_key, |
|
2912 priv_key_result, priv_key_attr_result_count); |
|
2913 |
|
2914 if (rv != CKR_OK) |
|
2915 { |
|
2916 PK11err_add_data(PK11_F_DH_COMP_KEY, PK11_R_GETATTRIBUTVALUE, |
|
2917 rv); |
|
2918 goto err; |
|
2919 } |
|
2920 |
|
2921 /* |
|
2922 * OpenSSL allocates the output buffer 'key' which is the same |
|
2923 * length of the public key. It is long enough for the derived key |
|
2924 */ |
|
2925 if (priv_key_result[0].type == CKA_VALUE) |
|
2926 { |
|
2927 /* |
|
2928 * CKM_DH_PKCS_DERIVE mechanism is not supposed to strip |
|
2929 * leading zeros from a computed shared secret. However, |
|
2930 * OpenSSL always did it so we must do the same here. The |
|
2931 * vagueness of the spec regarding leading zero bytes was |
|
2932 * finally cleared with TLS 1.1 (RFC 4346) saying that leading |
|
2933 * zeros are stripped before the computed data is used as the |
|
2934 * pre-master secret. |
|
2935 */ |
|
2936 for (i = 0; i < priv_key_result[0].ulValueLen; ++i) |
|
2937 { |
|
2938 if (((char *)priv_key_result[0].pValue)[i] != 0) |
|
2939 break; |
|
2940 } |
|
2941 |
|
2942 (void) memcpy(key, ((char *)priv_key_result[0].pValue) + i, |
|
2943 priv_key_result[0].ulValueLen - i); |
|
2944 ret = priv_key_result[0].ulValueLen - i; |
|
2945 } |
|
2946 |
|
2947 err: |
|
2948 |
|
2949 if (h_derived_key != CK_INVALID_HANDLE) |
|
2950 { |
|
2951 rv = pFuncList->C_DestroyObject(sp->session, h_derived_key); |
|
2952 if (rv != CKR_OK) |
|
2953 { |
|
2954 PK11err_add_data(PK11_F_DH_COMP_KEY, |
|
2955 PK11_R_DESTROYOBJECT, rv); |
|
2956 } |
|
2957 } |
|
2958 if (priv_key_result[0].pValue) |
|
2959 { |
|
2960 OPENSSL_free(priv_key_result[0].pValue); |
|
2961 priv_key_result[0].pValue = NULL; |
|
2962 } |
|
2963 |
|
2964 if (mechanism.pParameter) |
|
2965 { |
|
2966 OPENSSL_free(mechanism.pParameter); |
|
2967 mechanism.pParameter = NULL; |
|
2968 } |
|
2969 |
|
2970 pk11_return_session(sp, OP_DH); |
|
2971 return (ret); |
|
2972 } |
|
2973 |
|
2974 |
|
2975 static CK_OBJECT_HANDLE pk11_get_dh_key(DH* dh, |
|
2976 DH **key_ptr, BIGNUM **dh_priv_num, CK_SESSION_HANDLE session) |
|
2977 { |
|
2978 CK_RV rv; |
|
2979 CK_OBJECT_HANDLE h_key = CK_INVALID_HANDLE; |
|
2980 CK_OBJECT_CLASS class = CKO_PRIVATE_KEY; |
|
2981 CK_KEY_TYPE key_type = CKK_DH; |
|
2982 CK_ULONG found; |
|
2983 CK_BBOOL rollback = CK_FALSE; |
|
2984 int i; |
|
2985 |
|
2986 CK_ULONG ul_key_attr_count = 7; |
|
2987 CK_ATTRIBUTE key_template[] = |
|
2988 { |
|
2989 {CKA_CLASS, (void*) NULL, sizeof (class)}, |
|
2990 {CKA_KEY_TYPE, (void*) NULL, sizeof (key_type)}, |
|
2991 {CKA_DERIVE, &pk11_true, sizeof (pk11_true)}, |
|
2992 {CKA_PRIVATE, &pk11_false, sizeof (pk11_false)}, |
|
2993 {CKA_PRIME, (void *) NULL, 0}, |
|
2994 {CKA_BASE, (void *) NULL, 0}, |
|
2995 {CKA_VALUE, (void *) NULL, 0}, |
|
2996 }; |
|
2997 |
|
2998 key_template[0].pValue = &class; |
|
2999 key_template[1].pValue = &key_type; |
|
3000 |
|
3001 key_template[4].ulValueLen = BN_num_bytes(dh->p); |
|
3002 key_template[4].pValue = (CK_VOID_PTR)OPENSSL_malloc( |
|
3003 (size_t)key_template[4].ulValueLen); |
|
3004 if (key_template[4].pValue == NULL) |
|
3005 { |
|
3006 PK11err(PK11_F_GET_DH_KEY, PK11_R_MALLOC_FAILURE); |
|
3007 goto malloc_err; |
|
3008 } |
|
3009 |
|
3010 BN_bn2bin(dh->p, key_template[4].pValue); |
|
3011 |
|
3012 key_template[5].ulValueLen = BN_num_bytes(dh->g); |
|
3013 key_template[5].pValue = (CK_VOID_PTR)OPENSSL_malloc( |
|
3014 (size_t)key_template[5].ulValueLen); |
|
3015 if (key_template[5].pValue == NULL) |
|
3016 { |
|
3017 PK11err(PK11_F_GET_DH_KEY, PK11_R_MALLOC_FAILURE); |
|
3018 goto malloc_err; |
|
3019 } |
|
3020 |
|
3021 BN_bn2bin(dh->g, key_template[5].pValue); |
|
3022 |
|
3023 key_template[6].ulValueLen = BN_num_bytes(dh->priv_key); |
|
3024 key_template[6].pValue = (CK_VOID_PTR)OPENSSL_malloc( |
|
3025 (size_t)key_template[6].ulValueLen); |
|
3026 if (key_template[6].pValue == NULL) |
|
3027 { |
|
3028 PK11err(PK11_F_GET_DH_KEY, PK11_R_MALLOC_FAILURE); |
|
3029 goto malloc_err; |
|
3030 } |
|
3031 |
|
3032 BN_bn2bin(dh->priv_key, key_template[6].pValue); |
|
3033 |
|
3034 /* see find_lock array definition for more info on object locking */ |
|
3035 LOCK_OBJSTORE(OP_DH); |
|
3036 rv = pFuncList->C_FindObjectsInit(session, key_template, |
|
3037 ul_key_attr_count); |
|
3038 |
|
3039 if (rv != CKR_OK) |
|
3040 { |
|
3041 PK11err_add_data(PK11_F_GET_DH_KEY, PK11_R_FINDOBJECTSINIT, rv); |
|
3042 goto err; |
|
3043 } |
|
3044 |
|
3045 rv = pFuncList->C_FindObjects(session, &h_key, 1, &found); |
|
3046 |
|
3047 if (rv != CKR_OK) |
|
3048 { |
|
3049 PK11err_add_data(PK11_F_GET_DH_KEY, PK11_R_FINDOBJECTS, rv); |
|
3050 goto err; |
|
3051 } |
|
3052 |
|
3053 rv = pFuncList->C_FindObjectsFinal(session); |
|
3054 |
|
3055 if (rv != CKR_OK) |
|
3056 { |
|
3057 PK11err_add_data(PK11_F_GET_DH_KEY, PK11_R_FINDOBJECTSFINAL, |
|
3058 rv); |
|
3059 goto err; |
|
3060 } |
|
3061 |
|
3062 if (found == 0) |
|
3063 { |
|
3064 rv = pFuncList->C_CreateObject(session, |
|
3065 key_template, ul_key_attr_count, &h_key); |
|
3066 if (rv != CKR_OK) |
|
3067 { |
|
3068 PK11err_add_data(PK11_F_GET_DH_KEY, PK11_R_CREATEOBJECT, |
|
3069 rv); |
|
3070 goto err; |
|
3071 } |
|
3072 } |
|
3073 |
|
3074 if (dh_priv_num != NULL) |
|
3075 if ((*dh_priv_num = BN_dup(dh->priv_key)) == NULL) |
|
3076 { |
|
3077 PK11err(PK11_F_GET_DH_KEY, PK11_R_MALLOC_FAILURE); |
|
3078 rollback = CK_TRUE; |
|
3079 goto err; |
|
3080 } |
|
3081 |
|
3082 /* LINTED: E_CONSTANT_CONDITION */ |
|
3083 KEY_HANDLE_REFHOLD(h_key, OP_DH, CK_FALSE, rollback, err); |
|
3084 if (key_ptr != NULL) |
|
3085 *key_ptr = dh; |
|
3086 |
|
3087 err: |
|
3088 if (rollback) |
|
3089 { |
|
3090 /* |
|
3091 * We do not care about the return value from C_DestroyObject() |
|
3092 * since we are doing rollback. |
|
3093 */ |
|
3094 if (found == 0) |
|
3095 (void) pFuncList->C_DestroyObject(session, h_key); |
|
3096 h_key = CK_INVALID_HANDLE; |
|
3097 } |
|
3098 |
|
3099 UNLOCK_OBJSTORE(OP_DH); |
|
3100 |
|
3101 malloc_err: |
|
3102 for (i = 4; i <= 6; i++) |
|
3103 { |
|
3104 if (key_template[i].pValue != NULL) |
|
3105 { |
|
3106 OPENSSL_free(key_template[i].pValue); |
|
3107 key_template[i].pValue = NULL; |
|
3108 } |
|
3109 } |
|
3110 |
|
3111 return (h_key); |
|
3112 } |
|
3113 |
|
3114 /* |
|
3115 * Check for cache miss and clean the object pointer and handle |
|
3116 * in such case. Return 1 for cache hit, 0 for cache miss. |
|
3117 * |
|
3118 * Note: we rely on pk11_destroy_dh_key_objects() to set sp->opdata_dh |
|
3119 * to CK_INVALID_HANDLE even when it fails to destroy the object. |
|
3120 */ |
|
3121 static int check_new_dh_key(PK11_SESSION *sp, DH *dh) |
|
3122 { |
|
3123 /* |
|
3124 * Provide protection against DH structure reuse by making the |
|
3125 * check for cache hit stronger. Private key component of DH key |
|
3126 * is unique so it is sufficient to compare it with value cached |
|
3127 * in PK11_SESSION structure. |
|
3128 */ |
|
3129 if ((sp->opdata_dh != dh) || |
|
3130 (BN_cmp(sp->opdata_dh_priv_num, dh->priv_key) != 0)) |
|
3131 { |
|
3132 /* |
|
3133 * We do not check the return value because even in case of |
|
3134 * failure the sp structure will have both key pointer |
|
3135 * and object handle cleaned and pk11_destroy_object() |
|
3136 * reports the failure to the OpenSSL error message buffer. |
|
3137 */ |
|
3138 (void) pk11_destroy_dh_object(sp, CK_TRUE); |
|
3139 return (0); |
|
3140 } |
|
3141 return (1); |
|
3142 } |
|
3143 #endif |
|
3144 |
|
3145 /* |
|
3146 * Local function to simplify key template population |
|
3147 * Return 0 -- error, 1 -- no error |
|
3148 */ |
|
3149 static int |
|
3150 init_template_value(BIGNUM *bn, CK_VOID_PTR *p_value, |
|
3151 CK_ULONG *ul_value_len) |
|
3152 { |
|
3153 CK_ULONG len; |
|
3154 |
|
3155 /* |
|
3156 * This function can be used on non-initialized BIGNUMs. It is easier to |
|
3157 * check that here than individually in the callers. |
|
3158 */ |
|
3159 if (bn != NULL) |
|
3160 len = BN_num_bytes(bn); |
|
3161 |
|
3162 if (bn == NULL || len == 0) |
|
3163 return (1); |
|
3164 |
|
3165 *ul_value_len = len; |
|
3166 *p_value = (CK_VOID_PTR)OPENSSL_malloc((size_t)*ul_value_len); |
|
3167 if (*p_value == NULL) |
|
3168 return (0); |
|
3169 |
|
3170 BN_bn2bin(bn, *p_value); |
|
3171 |
|
3172 return (1); |
|
3173 } |
|
3174 |
|
3175 static void |
|
3176 attr_to_BN(CK_ATTRIBUTE_PTR attr, CK_BYTE attr_data[], BIGNUM **bn) |
|
3177 { |
|
3178 if (attr->ulValueLen > 0) |
|
3179 *bn = BN_bin2bn(attr_data, attr->ulValueLen, NULL); |
|
3180 } |
|
3181 |
|
3182 /* |
|
3183 * Find one object in the token. It is an error if we can not find the object or |
|
3184 * if we find more objects based on the template we got. |
|
3185 * |
|
3186 * Returns: |
|
3187 * 1 OK |
|
3188 * 0 no object or more than 1 object found |
|
3189 */ |
|
3190 static int |
|
3191 find_one_object(PK11_OPTYPE op, CK_SESSION_HANDLE s, |
|
3192 CK_ATTRIBUTE_PTR ptempl, CK_ULONG nattr, CK_OBJECT_HANDLE_PTR pkey) |
|
3193 { |
|
3194 CK_RV rv; |
|
3195 CK_ULONG objcnt; |
|
3196 |
|
3197 LOCK_OBJSTORE(op); |
|
3198 if ((rv = pFuncList->C_FindObjectsInit(s, ptempl, nattr)) != CKR_OK) |
|
3199 { |
|
3200 PK11err_add_data(PK11_F_FIND_ONE_OBJECT, |
|
3201 PK11_R_FINDOBJECTSINIT, rv); |
|
3202 goto err; |
|
3203 } |
|
3204 |
|
3205 rv = pFuncList->C_FindObjects(s, pkey, 1, &objcnt); |
|
3206 if (rv != CKR_OK) |
|
3207 { |
|
3208 PK11err_add_data(PK11_F_FIND_ONE_OBJECT, PK11_R_FINDOBJECTS, |
|
3209 rv); |
|
3210 goto err; |
|
3211 } |
|
3212 |
|
3213 if (objcnt > 1) |
|
3214 { |
|
3215 PK11err(PK11_F_FIND_ONE_OBJECT, |
|
3216 PK11_R_MORE_THAN_ONE_OBJECT_FOUND); |
|
3217 goto err; |
|
3218 } |
|
3219 else |
|
3220 if (objcnt == 0) |
|
3221 { |
|
3222 PK11err(PK11_F_FIND_ONE_OBJECT, PK11_R_NO_OBJECT_FOUND); |
|
3223 goto err; |
|
3224 } |
|
3225 |
|
3226 (void) pFuncList->C_FindObjectsFinal(s); |
|
3227 UNLOCK_OBJSTORE(op); |
|
3228 return (1); |
|
3229 err: |
|
3230 UNLOCK_OBJSTORE(op); |
|
3231 return (0); |
|
3232 } |
|
3233 |
|
3234 #endif /* OPENSSL_NO_HW_PK11 */ |
|
3235 #endif /* OPENSSL_NO_HW */ |
|