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