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