1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 *
21 * PKCS11 token KMF Plugin
22 *
23 * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
24 */
25
26 #include <stdio.h> /* debugging only */
27 #include <errno.h>
28 #include <values.h>
29
30 #include <kmfapiP.h>
31 #include <ber_der.h>
32 #include <fcntl.h>
33 #include <sha1.h>
34 #include <bignum.h>
35
36 #include <cryptoutil.h>
37 #include <security/cryptoki.h>
38 #include <security/pkcs11.h>
39
40 #define DEV_RANDOM "/dev/random"
41
42 #define SETATTR(t, n, atype, value, size) \
43 t[n].type = atype; \
44 t[n].pValue = (CK_BYTE *)value; \
45 t[n].ulValueLen = (CK_ULONG)size;
46
47 #define SET_ERROR(h, c) h->lasterr.kstype = KMF_KEYSTORE_PK11TOKEN; \
48 h->lasterr.errcode = c;
49
50 typedef struct _objlist {
51 CK_OBJECT_HANDLE handle;
52 struct _objlist *next;
53 } OBJLIST;
54
55 static KMF_RETURN
56 search_certs(KMF_HANDLE_T, char *, char *, char *, KMF_BIGINT *,
57 boolean_t, KMF_CERT_VALIDITY, OBJLIST **, uint32_t *);
58
59 static CK_RV
60 getObjectLabel(KMF_HANDLE_T, CK_OBJECT_HANDLE, char **);
61
62 static KMF_RETURN
63 keyObj2RawKey(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_RAW_KEY_DATA **);
64
65 static KMF_RETURN
66 create_generic_secret_key(KMF_HANDLE_T,
67 int, KMF_ATTRIBUTE *, CK_OBJECT_HANDLE *);
68
69 KMF_RETURN
70 KMFPK11_ConfigureKeystore(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
71
72 KMF_RETURN
73 KMFPK11_FindCert(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
74
75 void
76 KMFPK11_FreeKMFCert(KMF_HANDLE_T,
77 KMF_X509_DER_CERT *kmf_cert);
78
79 KMF_RETURN
80 KMFPK11_StoreCert(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
81
82 KMF_RETURN
83 KMFPK11_ImportCert(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
84
85 KMF_RETURN
86 KMFPK11_DeleteCert(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
87
88 KMF_RETURN
89 KMFPK11_CreateKeypair(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
90
91 KMF_RETURN
92 KMFPK11_StoreKey(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
93
94 KMF_RETURN
95 KMFPK11_DeleteKey(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
96
97 KMF_RETURN
98 KMFPK11_EncodePubKeyData(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_DATA *);
99
100 KMF_RETURN
101 KMFPK11_SignData(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_OID *,
102 KMF_DATA *, KMF_DATA *);
103
104 KMF_RETURN
105 KMFPK11_GetErrorString(KMF_HANDLE_T, char **);
106
107 KMF_RETURN
108 KMFPK11_FindPrikeyByCert(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
109
110 KMF_RETURN
111 KMFPK11_DecryptData(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_OID *,
112 KMF_DATA *, KMF_DATA *);
113
114 KMF_RETURN
115 KMFPK11_FindKey(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
116
117 KMF_RETURN
118 KMFPK11_CreateSymKey(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
119
120 KMF_RETURN
121 KMFPK11_GetSymKeyValue(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_RAW_SYM_KEY *);
122
123 KMF_RETURN
124 KMFPK11_SetTokenPin(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
125
126 KMF_RETURN
127 KMFPK11_ExportPK12(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
128
129
130 static
131 KMF_PLUGIN_FUNCLIST pk11token_plugin_table =
132 {
133 1, /* Version */
134 KMFPK11_ConfigureKeystore,
135 KMFPK11_FindCert,
136 KMFPK11_FreeKMFCert,
137 KMFPK11_StoreCert,
138 KMFPK11_ImportCert,
139 NULL, /* ImportCRL */
140 KMFPK11_DeleteCert,
141 NULL, /* DeleteCRL */
142 KMFPK11_CreateKeypair,
143 KMFPK11_FindKey,
144 KMFPK11_EncodePubKeyData,
145 KMFPK11_SignData,
146 KMFPK11_DeleteKey,
147 NULL, /* ListCRL */
148 NULL, /* FindCRL */
149 NULL, /* FindCertInCRL */
150 KMFPK11_GetErrorString,
151 KMFPK11_FindPrikeyByCert,
152 KMFPK11_DecryptData,
153 KMFPK11_ExportPK12,
154 KMFPK11_CreateSymKey,
155 KMFPK11_GetSymKeyValue,
156 KMFPK11_SetTokenPin,
157 KMFPK11_StoreKey,
158 NULL /* Finalize */
159 };
160
161 KMF_PLUGIN_FUNCLIST *
KMF_Plugin_Initialize()162 KMF_Plugin_Initialize()
163 {
164 return (&pk11token_plugin_table);
165 }
166
167 KMF_RETURN
KMFPK11_ConfigureKeystore(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)168 KMFPK11_ConfigureKeystore(KMF_HANDLE_T handle,
169 int numattr, KMF_ATTRIBUTE *attrlist)
170 {
171 KMF_RETURN rv = KMF_OK;
172 char *label;
173 boolean_t readonly = B_TRUE;
174
175 label = kmf_get_attr_ptr(KMF_TOKEN_LABEL_ATTR, attrlist, numattr);
176 if (label == NULL) {
177 return (KMF_ERR_BAD_PARAMETER);
178 }
179
180 /* "readonly" is optional. Default is TRUE */
181 (void) kmf_get_attr(KMF_READONLY_ATTR, attrlist, numattr,
182 (void *)&readonly, NULL);
183
184 rv = kmf_select_token(handle, label, readonly);
185
186 return (rv);
187 }
188
189 static KMF_RETURN
pk11_authenticate(KMF_HANDLE_T handle,KMF_CREDENTIAL * cred)190 pk11_authenticate(KMF_HANDLE_T handle,
191 KMF_CREDENTIAL *cred)
192 {
193
194 CK_RV ck_rv = CKR_OK;
195 CK_SESSION_HANDLE hSession = (CK_SESSION_HANDLE)handle->pk11handle;
196
197 if (hSession == NULL)
198 return (KMF_ERR_NO_TOKEN_SELECTED);
199
200 if (cred == NULL || cred->cred == NULL) {
201 return (KMF_ERR_BAD_PARAMETER);
202 }
203
204 if ((ck_rv = C_Login(hSession, CKU_USER, (uchar_t *)cred->cred,
205 cred->credlen)) != CKR_OK) {
206 if (ck_rv != CKR_USER_ALREADY_LOGGED_IN) {
207 handle->lasterr.kstype = KMF_KEYSTORE_PK11TOKEN;
208 handle->lasterr.errcode = ck_rv;
209 return (KMF_ERR_AUTH_FAILED);
210 }
211 }
212
213 return (KMF_OK);
214 }
215
216 static KMF_RETURN
PK11Cert2KMFCert(KMF_HANDLE * kmfh,CK_OBJECT_HANDLE hObj,KMF_X509_DER_CERT * kmfcert)217 PK11Cert2KMFCert(KMF_HANDLE *kmfh, CK_OBJECT_HANDLE hObj,
218 KMF_X509_DER_CERT *kmfcert)
219 {
220 KMF_RETURN rv = 0;
221 CK_RV ckrv = CKR_OK;
222
223 CK_CERTIFICATE_TYPE cktype;
224 CK_OBJECT_CLASS class;
225 CK_ULONG subject_len, value_len, issuer_len, serno_len, id_len;
226 CK_BYTE *subject = NULL, *value = NULL;
227 char *label = NULL;
228 CK_ATTRIBUTE templ[10];
229
230 (void) memset(templ, 0, 10 * sizeof (CK_ATTRIBUTE));
231 SETATTR(templ, 0, CKA_CLASS, &class, sizeof (class));
232
233 /* Is this a certificate object ? */
234 ckrv = C_GetAttributeValue(kmfh->pk11handle, hObj, templ, 1);
235 if (ckrv != CKR_OK || class != CKO_CERTIFICATE) {
236 SET_ERROR(kmfh, ckrv);
237 return (KMF_ERR_INTERNAL);
238 }
239
240 SETATTR(templ, 0, CKA_CERTIFICATE_TYPE, &cktype, sizeof (cktype));
241 ckrv = C_GetAttributeValue(kmfh->pk11handle, hObj, templ, 1);
242
243 if (ckrv != CKR_OK || cktype != CKC_X_509) {
244 SET_ERROR(kmfh, ckrv);
245 return (ckrv);
246 } else {
247 int i = 0;
248 /* What attributes are available and how big are they? */
249 subject_len = issuer_len = serno_len = id_len = value_len = 0;
250
251 SETATTR(templ, i, CKA_SUBJECT, NULL, subject_len);
252 i++;
253 SETATTR(templ, i, CKA_ISSUER, NULL, issuer_len);
254 i++;
255 SETATTR(templ, i, CKA_SERIAL_NUMBER, NULL, serno_len);
256 i++;
257 SETATTR(templ, i, CKA_ID, NULL, id_len);
258 i++;
259 SETATTR(templ, i, CKA_VALUE, NULL, value_len);
260 i++;
261
262 /*
263 * Query the object with NULL values in the pValue spot
264 * so we know how much space to allocate for each field.
265 */
266 ckrv = C_GetAttributeValue(kmfh->pk11handle, hObj, templ, i);
267 if (ckrv != CKR_OK) {
268 SET_ERROR(kmfh, ckrv);
269 return (KMF_ERR_INTERNAL); /* TODO - Error messages ? */
270 }
271
272 subject_len = templ[0].ulValueLen;
273 issuer_len = templ[1].ulValueLen;
274 serno_len = templ[2].ulValueLen;
275 id_len = templ[3].ulValueLen;
276 value_len = templ[4].ulValueLen;
277
278 /*
279 * For PKCS#11 CKC_X_509 certificate objects,
280 * the following attributes must be defined.
281 * CKA_SUBJECT, CKA_ID, CKA_ISSUER, CKA_SERIAL_NUMBER,
282 * CKA_VALUE.
283 */
284 if (subject_len == 0 || issuer_len == 0 ||
285 serno_len == 0 || value_len == 0) {
286 return (KMF_ERR_INTERNAL);
287 }
288
289 /* Only fetch the value field if we are saving the data */
290 if (kmfcert != NULL) {
291 int i = 0;
292 value = malloc(value_len);
293 if (value == NULL) {
294 rv = KMF_ERR_MEMORY;
295 goto errout;
296 }
297
298 SETATTR(templ, i, CKA_VALUE, value, value_len);
299 i++;
300
301 /* re-query the object with room for the value attr */
302 ckrv = C_GetAttributeValue(kmfh->pk11handle, hObj,
303 templ, i);
304
305 if (ckrv != CKR_OK) {
306 SET_ERROR(kmfh, ckrv);
307 rv = KMF_ERR_INTERNAL;
308 goto errout;
309 }
310
311 kmfcert->certificate.Data = value;
312 kmfcert->certificate.Length = value_len;
313 kmfcert->kmf_private.flags |= KMF_FLAG_CERT_SIGNED;
314 kmfcert->kmf_private.keystore_type =
315 KMF_KEYSTORE_PK11TOKEN;
316
317 ckrv = getObjectLabel(kmfh, hObj, &label);
318 if (ckrv == CKR_OK && label != NULL) {
319 kmfcert->kmf_private.label = (char *)label;
320 }
321
322 rv = KMF_OK;
323 }
324 }
325
326 errout:
327 if (rv != KMF_OK) {
328 if (subject)
329 free(subject);
330 if (value)
331 free(value);
332
333 if (kmfcert) {
334 kmfcert->certificate.Data = NULL;
335 kmfcert->certificate.Length = 0;
336 }
337 }
338 return (rv);
339 }
340
341 static void
free_objlist(OBJLIST * head)342 free_objlist(OBJLIST *head)
343 {
344 OBJLIST *temp = head;
345
346 while (temp != NULL) {
347 head = head->next;
348 free(temp);
349 temp = head;
350 }
351 }
352
353 /*
354 * The caller should make sure that the templ->pValue is NULL since
355 * it will be overwritten below.
356 */
357 static KMF_RETURN
get_attr(KMF_HANDLE * kmfh,CK_OBJECT_HANDLE obj,CK_ATTRIBUTE * templ)358 get_attr(KMF_HANDLE *kmfh, CK_OBJECT_HANDLE obj,
359 CK_ATTRIBUTE *templ)
360 {
361 CK_RV rv;
362
363 rv = C_GetAttributeValue(kmfh->pk11handle, obj, templ, 1);
364 if (rv != CKR_OK) {
365 SET_ERROR(kmfh, rv);
366 return (KMF_ERR_INTERNAL);
367 }
368
369 if (templ->ulValueLen > 0) {
370 templ->pValue = malloc(templ->ulValueLen);
371 if (templ->pValue == NULL)
372 return (KMF_ERR_MEMORY);
373
374 rv = C_GetAttributeValue(kmfh->pk11handle, obj, templ, 1);
375 if (rv != CKR_OK) {
376 SET_ERROR(kmfh, rv);
377 return (KMF_ERR_INTERNAL);
378 }
379 }
380
381 return (KMF_OK);
382 }
383
384 /*
385 * Match a certificate with an issuer and/or subject name.
386 * This is tricky because we cannot reliably compare DER encodings
387 * because RDNs may have their AV-pairs in different orders even
388 * if the values are the same. You must compare individual
389 * AV pairs for the RDNs.
390 *
391 * RETURN: 0 for a match, non-zero for a non-match.
392 */
393 static KMF_RETURN
matchcert(KMF_HANDLE * kmfh,CK_OBJECT_HANDLE obj,KMF_X509_NAME * issuer,KMF_X509_NAME * subject)394 matchcert(KMF_HANDLE *kmfh, CK_OBJECT_HANDLE obj,
395 KMF_X509_NAME *issuer, KMF_X509_NAME *subject)
396 {
397 KMF_RETURN rv = KMF_OK;
398 CK_ATTRIBUTE certattr;
399 KMF_DATA name;
400 KMF_X509_NAME dn;
401
402 if (issuer->numberOfRDNs > 0) {
403 certattr.type = CKA_ISSUER;
404 certattr.pValue = NULL;
405 certattr.ulValueLen = 0;
406
407 rv = get_attr(kmfh, obj, &certattr);
408
409 if (rv == KMF_OK) {
410 name.Data = certattr.pValue;
411 name.Length = certattr.ulValueLen;
412 rv = DerDecodeName(&name, &dn);
413 if (rv == KMF_OK) {
414 rv = kmf_compare_rdns(issuer, &dn);
415 kmf_free_dn(&dn);
416 }
417 free(certattr.pValue);
418 }
419
420 if (rv != KMF_OK)
421 return (rv);
422 }
423 if (subject->numberOfRDNs > 0) {
424 certattr.type = CKA_SUBJECT;
425 certattr.pValue = NULL;
426 certattr.ulValueLen = 0;
427
428 rv = get_attr(kmfh, obj, &certattr);
429
430 if (rv == KMF_OK) {
431 name.Data = certattr.pValue;
432 name.Length = certattr.ulValueLen;
433 rv = DerDecodeName(&name, &dn);
434 if (rv == KMF_OK) {
435 rv = kmf_compare_rdns(subject, &dn);
436 kmf_free_dn(&dn);
437 }
438 free(certattr.pValue);
439 }
440 }
441
442 return (rv);
443 }
444
445 /*
446 * delete "curr" node from the "newlist".
447 */
448 static void
pk11_delete_obj_from_list(OBJLIST ** newlist,OBJLIST ** prev,OBJLIST ** curr)449 pk11_delete_obj_from_list(OBJLIST **newlist,
450 OBJLIST **prev, OBJLIST **curr)
451 {
452
453 if (*curr == *newlist) {
454 /* first node in the list */
455 *newlist = (*curr)->next;
456 *prev = (*curr)->next;
457 free(*curr);
458 *curr = *newlist;
459 } else {
460 (*prev)->next = (*curr)->next;
461 free(*curr);
462 *curr = (*prev)->next;
463 }
464 }
465
466 /*
467 * search_certs
468 *
469 * Because this code is shared by the FindCert and
470 * DeleteCert functions, put it in a separate routine
471 * to save some work and make code easier to debug and
472 * read.
473 */
474 static KMF_RETURN
search_certs(KMF_HANDLE_T handle,char * label,char * issuer,char * subject,KMF_BIGINT * serial,boolean_t private,KMF_CERT_VALIDITY validity,OBJLIST ** objlist,uint32_t * numobj)475 search_certs(KMF_HANDLE_T handle,
476 char *label, char *issuer, char *subject, KMF_BIGINT *serial,
477 boolean_t private, KMF_CERT_VALIDITY validity,
478 OBJLIST **objlist, uint32_t *numobj)
479 {
480 KMF_RETURN rv = KMF_OK;
481 CK_RV ckrv = CKR_OK;
482 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
483 CK_ATTRIBUTE templ[10];
484 CK_BBOOL true = TRUE;
485 CK_OBJECT_CLASS oclass = CKO_CERTIFICATE;
486 CK_CERTIFICATE_TYPE ctype = CKC_X_509;
487 KMF_X509_NAME subjectDN, issuerDN;
488 int i;
489 OBJLIST *newlist, *tail;
490 CK_ULONG num = 0;
491 uint32_t num_ok_certs = 0; /* number of non-expired or expired certs */
492
493 (void) memset(&templ, 0, 10 * sizeof (CK_ATTRIBUTE));
494 (void) memset(&issuerDN, 0, sizeof (KMF_X509_NAME));
495 (void) memset(&subjectDN, 0, sizeof (KMF_X509_NAME));
496 i = 0;
497 SETATTR(templ, i, CKA_TOKEN, &true, sizeof (true)); i++;
498 SETATTR(templ, i, CKA_CLASS, &oclass, sizeof (oclass)); i++;
499 SETATTR(templ, i, CKA_CERTIFICATE_TYPE, &ctype, sizeof (ctype)); i++;
500
501 if (label != NULL && strlen(label)) {
502 SETATTR(templ, i, CKA_LABEL, label, strlen(label));
503 i++;
504 }
505 if (private) {
506 SETATTR(templ, i, CKA_PRIVATE, &true, sizeof (true)); i++;
507 }
508
509 if (issuer != NULL && strlen(issuer)) {
510 if ((rv = kmf_dn_parser(issuer, &issuerDN)) != KMF_OK)
511 return (rv);
512 }
513 if (subject != NULL && strlen(subject)) {
514 if ((rv = kmf_dn_parser(subject, &subjectDN)) != KMF_OK)
515 return (rv);
516 }
517
518 if (serial != NULL && serial->val != NULL && serial->len > 0) {
519 SETATTR(templ, i, CKA_SERIAL_NUMBER, serial->val, serial->len);
520 i++;
521 }
522
523 (*numobj) = 0;
524 *objlist = NULL;
525 newlist = NULL;
526
527 ckrv = C_FindObjectsInit(kmfh->pk11handle, templ, i);
528 if (ckrv != CKR_OK)
529 goto cleanup;
530
531 tail = newlist = NULL;
532 while (ckrv == CKR_OK) {
533 CK_OBJECT_HANDLE tObj;
534 ckrv = C_FindObjects(kmfh->pk11handle, &tObj, 1, &num);
535 if (ckrv != CKR_OK || num == 0)
536 break;
537
538 /*
539 * 'matchcert' returns 0 if subject/issuer match
540 *
541 * If no match, move on to the next one
542 */
543 if (matchcert(kmfh, tObj, &issuerDN, &subjectDN))
544 continue;
545
546 if (newlist == NULL) {
547 newlist = malloc(sizeof (OBJLIST));
548 if (newlist == NULL) {
549 rv = KMF_ERR_MEMORY;
550 break;
551 }
552 newlist->handle = tObj;
553 newlist->next = NULL;
554 tail = newlist;
555 } else {
556 tail->next = malloc(sizeof (OBJLIST));
557 if (tail->next != NULL) {
558 tail = tail->next;
559 } else {
560 rv = KMF_ERR_MEMORY;
561 break;
562 }
563 tail->handle = tObj;
564 tail->next = NULL;
565 }
566 (*numobj)++;
567 }
568 ckrv = C_FindObjectsFinal(kmfh->pk11handle);
569
570 cleanup:
571 if (ckrv != CKR_OK) {
572 SET_ERROR(kmfh, ckrv);
573 rv = KMF_ERR_INTERNAL;
574 if (newlist != NULL) {
575 free_objlist(newlist);
576 *numobj = 0;
577 newlist = NULL;
578 }
579 } else {
580 if (validity == KMF_ALL_CERTS) {
581 *objlist = newlist;
582 } else {
583 OBJLIST *node, *prev;
584 KMF_X509_DER_CERT tmp_kmf_cert;
585 uint32_t i = 0;
586
587 node = prev = newlist;
588 /*
589 * Now check to see if any found certificate is expired
590 * or valid.
591 */
592 while (node != NULL && i < (*numobj)) {
593 (void) memset(&tmp_kmf_cert, 0,
594 sizeof (KMF_X509_DER_CERT));
595 rv = PK11Cert2KMFCert(kmfh, node->handle,
596 &tmp_kmf_cert);
597 if (rv != KMF_OK) {
598 goto cleanup1;
599 }
600
601 rv = kmf_check_cert_date(handle,
602 &tmp_kmf_cert.certificate);
603
604 if (validity == KMF_NONEXPIRED_CERTS) {
605 if (rv == KMF_OK) {
606 num_ok_certs++;
607 prev = node;
608 node = node->next;
609 } else if (rv ==
610 KMF_ERR_VALIDITY_PERIOD) {
611 /*
612 * expired - remove it from list
613 */
614 pk11_delete_obj_from_list(
615 &newlist, &prev, &node);
616 } else {
617 goto cleanup1;
618 }
619 }
620
621 if (validity == KMF_EXPIRED_CERTS) {
622 if (rv == KMF_ERR_VALIDITY_PERIOD) {
623 num_ok_certs++;
624 prev = node;
625 node = node->next;
626 rv = KMF_OK;
627 } else if (rv == KMF_OK) {
628 /*
629 * valid - remove it from list
630 */
631 pk11_delete_obj_from_list(
632 &newlist, &prev, &node);
633 } else {
634 goto cleanup1;
635 }
636 }
637 i++;
638 kmf_free_kmf_cert(handle, &tmp_kmf_cert);
639 }
640 *numobj = num_ok_certs;
641 *objlist = newlist;
642 }
643 }
644
645 cleanup1:
646 if (rv != KMF_OK && newlist != NULL) {
647 free_objlist(newlist);
648 *numobj = 0;
649 *objlist = NULL;
650 }
651
652 if (issuer != NULL)
653 kmf_free_dn(&issuerDN);
654
655 if (subject != NULL)
656 kmf_free_dn(&subjectDN);
657
658 return (rv);
659 }
660
661 /*
662 * The caller may pass a NULL value for kmf_cert below and the function will
663 * just return the number of certs found (in num_certs).
664 */
665 KMF_RETURN
KMFPK11_FindCert(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)666 KMFPK11_FindCert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
667 {
668 KMF_RETURN rv = 0;
669 uint32_t want_certs;
670 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
671 OBJLIST *objlist = NULL;
672 uint32_t *num_certs;
673 KMF_X509_DER_CERT *kmf_cert = NULL;
674 char *certlabel = NULL;
675 char *issuer = NULL;
676 char *subject = NULL;
677 KMF_BIGINT *serial = NULL;
678 KMF_CERT_VALIDITY validity;
679 KMF_CREDENTIAL *cred = NULL;
680 boolean_t private;
681
682 if (kmfh == NULL)
683 return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */
684
685 if (kmfh->pk11handle == CK_INVALID_HANDLE)
686 return (KMF_ERR_NO_TOKEN_SELECTED);
687
688 num_certs = kmf_get_attr_ptr(KMF_COUNT_ATTR, attrlist, numattr);
689 if (num_certs == NULL)
690 return (KMF_ERR_BAD_PARAMETER);
691
692 if (*num_certs > 0)
693 want_certs = *num_certs;
694 else
695 want_certs = MAXINT; /* count them all */
696
697 *num_certs = 0;
698
699 /* Get the optional returned certificate list */
700 kmf_cert = kmf_get_attr_ptr(KMF_X509_DER_CERT_ATTR, attrlist,
701 numattr);
702
703 /* Get optional search criteria attributes */
704 certlabel = kmf_get_attr_ptr(KMF_CERT_LABEL_ATTR, attrlist, numattr);
705 issuer = kmf_get_attr_ptr(KMF_ISSUER_NAME_ATTR, attrlist, numattr);
706 subject = kmf_get_attr_ptr(KMF_SUBJECT_NAME_ATTR, attrlist, numattr);
707 serial = kmf_get_attr_ptr(KMF_BIGINT_ATTR, attrlist, numattr);
708
709 rv = kmf_get_attr(KMF_CERT_VALIDITY_ATTR, attrlist, numattr,
710 &validity, NULL);
711 if (rv != KMF_OK) {
712 validity = KMF_ALL_CERTS;
713 rv = KMF_OK;
714 }
715
716 rv = kmf_get_attr(KMF_PRIVATE_BOOL_ATTR, attrlist, numattr,
717 (void *)&private, NULL);
718 if (rv != KMF_OK) {
719 private = B_FALSE;
720 rv = KMF_OK;
721 }
722
723 cred = kmf_get_attr_ptr(KMF_CREDENTIAL_ATTR, attrlist, numattr);
724 if (cred != NULL) {
725 rv = pk11_authenticate(handle, cred);
726 if (rv != KMF_OK)
727 return (rv);
728 }
729
730 /* Start searching */
731 rv = search_certs(handle, certlabel, issuer, subject, serial, private,
732 validity, &objlist, num_certs);
733
734 if (rv == KMF_OK && objlist != NULL && kmf_cert != NULL) {
735 OBJLIST *node = objlist;
736 int i = 0;
737 while (node != NULL && i < want_certs) {
738 rv = PK11Cert2KMFCert(kmfh, node->handle,
739 &kmf_cert[i]);
740 i++;
741 node = node->next;
742 }
743 }
744
745 if (objlist != NULL)
746 free_objlist(objlist);
747
748 if (*num_certs == 0)
749 rv = KMF_ERR_CERT_NOT_FOUND;
750
751 return (rv);
752 }
753
754 /*ARGSUSED*/
755 void
KMFPK11_FreeKMFCert(KMF_HANDLE_T handle,KMF_X509_DER_CERT * kmf_cert)756 KMFPK11_FreeKMFCert(KMF_HANDLE_T handle, KMF_X509_DER_CERT *kmf_cert)
757 {
758 if (kmf_cert != NULL && kmf_cert->certificate.Data != NULL) {
759 free(kmf_cert->certificate.Data);
760 kmf_cert->certificate.Data = NULL;
761 kmf_cert->certificate.Length = 0;
762
763 if (kmf_cert->kmf_private.label != NULL) {
764 free(kmf_cert->kmf_private.label);
765 kmf_cert->kmf_private.label = NULL;
766 }
767 }
768 }
769
770 KMF_RETURN
KMFPK11_EncodePubKeyData(KMF_HANDLE_T handle,KMF_KEY_HANDLE * pKey,KMF_DATA * eData)771 KMFPK11_EncodePubKeyData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *pKey,
772 KMF_DATA *eData)
773 {
774 KMF_RETURN ret = KMF_OK;
775 CK_RV rv;
776 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
777 CK_OBJECT_CLASS ckObjClass = CKO_PUBLIC_KEY;
778 CK_KEY_TYPE ckKeyType;
779 KMF_DATA Modulus, Exponent, Prime, Subprime, Base, Value;
780 KMF_OID *Algorithm;
781 BerElement *asn1 = NULL;
782 BerValue *PubKeyParams = NULL, *EncodedKey = NULL;
783 KMF_X509_SPKI spki;
784 CK_BYTE ec_params[256], ec_point[256];
785
786 CK_ATTRIBUTE rsaTemplate[4];
787 CK_ATTRIBUTE dsaTemplate[6];
788 CK_ATTRIBUTE ecdsaTemplate[6];
789
790 if (kmfh == NULL)
791 return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */
792
793 if (kmfh->pk11handle == CK_INVALID_HANDLE)
794 return (KMF_ERR_NO_TOKEN_SELECTED);
795
796 if (pKey == NULL || pKey->keyp == CK_INVALID_HANDLE)
797 return (KMF_ERR_BAD_PARAMETER);
798
799 (void) memset(&Modulus, 0, sizeof (Modulus));
800 (void) memset(&Exponent, 0, sizeof (Exponent));
801 (void) memset(&Prime, 0, sizeof (Prime));
802 (void) memset(&Subprime, 0, sizeof (Subprime));
803 (void) memset(&Base, 0, sizeof (Base));
804 (void) memset(&Value, 0, sizeof (Value));
805
806 switch (pKey->keyalg) {
807 case KMF_RSA:
808 SETATTR(rsaTemplate, 0, CKA_CLASS, &ckObjClass,
809 sizeof (ckObjClass));
810 SETATTR(rsaTemplate, 1, CKA_KEY_TYPE, &ckKeyType,
811 sizeof (ckKeyType));
812 SETATTR(rsaTemplate, 2, CKA_MODULUS, Modulus.Data,
813 Modulus.Length);
814 SETATTR(rsaTemplate, 3, CKA_PUBLIC_EXPONENT,
815 Exponent.Data, Exponent.Length);
816 /* Get the length of the fields */
817 rv = C_GetAttributeValue(kmfh->pk11handle,
818 (CK_OBJECT_HANDLE)pKey->keyp, rsaTemplate, 4);
819 if (rv != CKR_OK) {
820 SET_ERROR(kmfh, rv);
821 return (KMF_ERR_BAD_PARAMETER);
822 }
823
824 Modulus.Length = rsaTemplate[2].ulValueLen;
825 Modulus.Data = malloc(Modulus.Length);
826 if (Modulus.Data == NULL)
827 return (KMF_ERR_MEMORY);
828
829 Exponent.Length = rsaTemplate[3].ulValueLen;
830 Exponent.Data = malloc(Exponent.Length);
831 if (Exponent.Data == NULL) {
832 free(Modulus.Data);
833 return (KMF_ERR_MEMORY);
834 }
835
836 SETATTR(rsaTemplate, 2, CKA_MODULUS, Modulus.Data,
837 Modulus.Length);
838 SETATTR(rsaTemplate, 3, CKA_PUBLIC_EXPONENT,
839 Exponent.Data, Exponent.Length);
840 /* Now get the values */
841 rv = C_GetAttributeValue(kmfh->pk11handle,
842 (CK_OBJECT_HANDLE)pKey->keyp, rsaTemplate, 4);
843 if (rv != CKR_OK) {
844 SET_ERROR(kmfh, rv);
845 free(Modulus.Data);
846 free(Exponent.Data);
847 return (KMF_ERR_BAD_PARAMETER);
848 }
849
850 /*
851 * This is the KEY algorithm, not the
852 * signature algorithm.
853 */
854 Algorithm = x509_algid_to_algoid(KMF_ALGID_RSA);
855 if (Algorithm != NULL) {
856
857 /* Encode the RSA Key Data */
858 if ((asn1 = kmfder_alloc()) == NULL) {
859 free(Modulus.Data);
860 free(Exponent.Data);
861 return (KMF_ERR_MEMORY);
862 }
863 if (kmfber_printf(asn1, "{II}", Modulus.Data,
864 Modulus.Length, Exponent.Data,
865 Exponent.Length) == -1) {
866 kmfber_free(asn1, 1);
867 free(Modulus.Data);
868 free(Exponent.Data);
869 return (KMF_ERR_ENCODING);
870 }
871 if (kmfber_flatten(asn1, &EncodedKey) == -1) {
872 kmfber_free(asn1, 1);
873 free(Modulus.Data);
874 free(Exponent.Data);
875 return (KMF_ERR_ENCODING);
876 }
877 kmfber_free(asn1, 1);
878 }
879
880 free(Exponent.Data);
881 free(Modulus.Data);
882
883 break;
884 case KMF_DSA:
885 SETATTR(dsaTemplate, 0, CKA_CLASS, &ckObjClass,
886 sizeof (ckObjClass));
887 SETATTR(dsaTemplate, 1, CKA_KEY_TYPE, &ckKeyType,
888 sizeof (ckKeyType));
889 SETATTR(dsaTemplate, 2, CKA_PRIME, Prime.Data,
890 Prime.Length);
891 SETATTR(dsaTemplate, 3, CKA_SUBPRIME, Subprime.Data,
892 Subprime.Length);
893 SETATTR(dsaTemplate, 4, CKA_BASE, Base.Data,
894 Base.Length);
895 SETATTR(dsaTemplate, 5, CKA_VALUE, Value.Data,
896 Value.Length);
897
898 /* Get the length of the fields */
899 rv = C_GetAttributeValue(kmfh->pk11handle,
900 (CK_OBJECT_HANDLE)pKey->keyp, dsaTemplate, 6);
901 if (rv != CKR_OK) {
902 SET_ERROR(kmfh, rv);
903 return (KMF_ERR_BAD_PARAMETER);
904 }
905 Prime.Length = dsaTemplate[2].ulValueLen;
906 Prime.Data = malloc(Prime.Length);
907 if (Prime.Data == NULL) {
908 return (KMF_ERR_MEMORY);
909 }
910
911 Subprime.Length = dsaTemplate[3].ulValueLen;
912 Subprime.Data = malloc(Subprime.Length);
913 if (Subprime.Data == NULL) {
914 free(Prime.Data);
915 return (KMF_ERR_MEMORY);
916 }
917
918 Base.Length = dsaTemplate[4].ulValueLen;
919 Base.Data = malloc(Base.Length);
920 if (Base.Data == NULL) {
921 free(Prime.Data);
922 free(Subprime.Data);
923 return (KMF_ERR_MEMORY);
924 }
925
926 Value.Length = dsaTemplate[5].ulValueLen;
927 Value.Data = malloc(Value.Length);
928 if (Value.Data == NULL) {
929 free(Prime.Data);
930 free(Subprime.Data);
931 free(Base.Data);
932 return (KMF_ERR_MEMORY);
933 }
934 SETATTR(dsaTemplate, 2, CKA_PRIME, Prime.Data,
935 Prime.Length);
936 SETATTR(dsaTemplate, 3, CKA_SUBPRIME, Subprime.Data,
937 Subprime.Length);
938 SETATTR(dsaTemplate, 4, CKA_BASE, Base.Data,
939 Base.Length);
940 SETATTR(dsaTemplate, 5, CKA_VALUE, Value.Data,
941 Value.Length);
942
943 /* Now get the values */
944 rv = C_GetAttributeValue(kmfh->pk11handle,
945 (CK_OBJECT_HANDLE)pKey->keyp, dsaTemplate, 6);
946 if (rv != CKR_OK) {
947 free(Prime.Data);
948 free(Subprime.Data);
949 free(Base.Data);
950 free(Value.Data);
951 SET_ERROR(kmfh, rv);
952 return (KMF_ERR_BAD_PARAMETER);
953 }
954 /*
955 * This is the KEY algorithm, not the
956 * signature algorithm.
957 */
958 Algorithm = x509_algid_to_algoid(KMF_ALGID_DSA);
959
960 /* Encode the DSA Algorithm Parameters */
961 if ((asn1 = kmfder_alloc()) == NULL) {
962 free(Prime.Data);
963 free(Subprime.Data);
964 free(Base.Data);
965 free(Value.Data);
966 return (KMF_ERR_MEMORY);
967 }
968
969 if (kmfber_printf(asn1, "{III}", Prime.Data,
970 Prime.Length, Subprime.Data, Subprime.Length,
971 Base.Data, Base.Length) == -1) {
972
973 kmfber_free(asn1, 1);
974 free(Prime.Data);
975 free(Subprime.Data);
976 free(Base.Data);
977 free(Value.Data);
978 return (KMF_ERR_ENCODING);
979 }
980 if (kmfber_flatten(asn1, &PubKeyParams) == -1) {
981 kmfber_free(asn1, 1);
982 free(Prime.Data);
983 free(Subprime.Data);
984 free(Base.Data);
985 free(Value.Data);
986 return (KMF_ERR_ENCODING);
987 }
988 kmfber_free(asn1, 1);
989 free(Prime.Data);
990 free(Subprime.Data);
991 free(Base.Data);
992
993 /* Encode the DSA Key Value */
994 if ((asn1 = kmfder_alloc()) == NULL) {
995 free(Value.Data);
996 return (KMF_ERR_MEMORY);
997 }
998
999 if (kmfber_printf(asn1, "I",
1000 Value.Data, Value.Length) == -1) {
1001 kmfber_free(asn1, 1);
1002 free(Value.Data);
1003 return (KMF_ERR_ENCODING);
1004 }
1005 if (kmfber_flatten(asn1, &EncodedKey) == -1) {
1006 kmfber_free(asn1, 1);
1007 free(Value.Data);
1008 return (KMF_ERR_ENCODING);
1009 }
1010 kmfber_free(asn1, 1);
1011 free(Value.Data);
1012 break;
1013 case KMF_ECDSA:
1014 /* The EC_PARAMS are the PubKey algorithm parameters */
1015 PubKeyParams = calloc(1, sizeof (BerValue));
1016 if (PubKeyParams == NULL)
1017 return (KMF_ERR_MEMORY);
1018 EncodedKey = calloc(1, sizeof (BerValue));
1019 if (EncodedKey == NULL) {
1020 free(PubKeyParams);
1021 return (KMF_ERR_MEMORY);
1022 }
1023 SETATTR(ecdsaTemplate, 0, CKA_EC_PARAMS,
1024 &ec_params, sizeof (ec_params));
1025 SETATTR(ecdsaTemplate, 1, CKA_EC_POINT,
1026 &ec_point, sizeof (ec_point));
1027
1028 /* Get the length of the fields */
1029 rv = C_GetAttributeValue(kmfh->pk11handle,
1030 (CK_OBJECT_HANDLE)pKey->keyp,
1031 ecdsaTemplate, 2);
1032 if (rv != CKR_OK) {
1033 SET_ERROR(kmfh, rv);
1034 return (KMF_ERR_BAD_PARAMETER);
1035 }
1036 /* The params are to be used as algorithm parameters */
1037 PubKeyParams->bv_val = (char *)ec_params;
1038 PubKeyParams->bv_len = ecdsaTemplate[0].ulValueLen;
1039 /*
1040 * The EC_POINT is to be used as the subject pub key.
1041 */
1042 EncodedKey->bv_val = (char *)ec_point;
1043 EncodedKey->bv_len = ecdsaTemplate[1].ulValueLen;
1044
1045 /* Use the EC_PUBLIC_KEY OID */
1046 Algorithm = (KMF_OID *)&KMFOID_EC_PUBLIC_KEY;
1047 break;
1048 default:
1049 return (KMF_ERR_BAD_PARAMETER);
1050 }
1051
1052 /* Now, build an SPKI structure for the final encoding step */
1053 spki.algorithm.algorithm = *Algorithm;
1054 if (PubKeyParams != NULL) {
1055 spki.algorithm.parameters.Data =
1056 (uchar_t *)PubKeyParams->bv_val;
1057 spki.algorithm.parameters.Length = PubKeyParams->bv_len;
1058 } else {
1059 spki.algorithm.parameters.Data = NULL;
1060 spki.algorithm.parameters.Length = 0;
1061 }
1062
1063 if (EncodedKey != NULL) {
1064 spki.subjectPublicKey.Data = (uchar_t *)EncodedKey->bv_val;
1065 spki.subjectPublicKey.Length = EncodedKey->bv_len;
1066 } else {
1067 spki.subjectPublicKey.Data = NULL;
1068 spki.subjectPublicKey.Length = 0;
1069 }
1070
1071 /* Finally, encode the entire SPKI record */
1072 ret = DerEncodeSPKI(&spki, eData);
1073
1074 cleanup:
1075 if (EncodedKey) {
1076 if (pKey->keyalg != KMF_ECDSA)
1077 free(EncodedKey->bv_val);
1078 free(EncodedKey);
1079 }
1080
1081 if (PubKeyParams) {
1082 if (pKey->keyalg != KMF_ECDSA)
1083 free(PubKeyParams->bv_val);
1084 free(PubKeyParams);
1085 }
1086
1087 return (ret);
1088 }
1089
1090 static KMF_RETURN
CreateCertObject(KMF_HANDLE_T handle,char * label,KMF_DATA * pcert)1091 CreateCertObject(KMF_HANDLE_T handle, char *label, KMF_DATA *pcert)
1092 {
1093 KMF_RETURN rv = 0;
1094 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
1095
1096 KMF_X509_CERTIFICATE *signed_cert_ptr = NULL;
1097 KMF_DATA data;
1098 KMF_DATA Id;
1099
1100 CK_RV ckrv;
1101 CK_ULONG subject_len, issuer_len, serno_len;
1102 CK_BYTE *subject, *issuer, *serial, nullserno;
1103 CK_BBOOL true = TRUE;
1104 CK_CERTIFICATE_TYPE certtype = CKC_X_509;
1105 CK_OBJECT_CLASS certClass = CKO_CERTIFICATE;
1106 CK_ATTRIBUTE x509templ[11];
1107 CK_OBJECT_HANDLE hCert = NULL;
1108 int i;
1109
1110 if (kmfh == NULL)
1111 return (KMF_ERR_INTERNAL); /* should not happen */
1112
1113 if (kmfh->pk11handle == CK_INVALID_HANDLE)
1114 return (KMF_ERR_INTERNAL); /* should not happen */
1115
1116 if (pcert == NULL || pcert->Data == NULL || pcert->Length == 0)
1117 return (KMF_ERR_INTERNAL); /* should not happen */
1118
1119 /*
1120 * The data *must* be a DER encoded X.509 certificate.
1121 * Convert it to a CSSM cert and then parse the fields so
1122 * the PKCS#11 attributes can be filled in correctly.
1123 */
1124 rv = DerDecodeSignedCertificate((const KMF_DATA *)pcert,
1125 &signed_cert_ptr);
1126 if (rv != KMF_OK) {
1127 return (KMF_ERR_ENCODING);
1128 }
1129
1130 /*
1131 * Encode fields into PKCS#11 attributes.
1132 */
1133
1134 /* Get the subject name */
1135 rv = DerEncodeName(&signed_cert_ptr->certificate.subject, &data);
1136 if (rv == KMF_OK) {
1137 subject = data.Data;
1138 subject_len = data.Length;
1139 } else {
1140 rv = KMF_ERR_ENCODING;
1141 goto cleanup;
1142 }
1143
1144 /* Encode the issuer */
1145 rv = DerEncodeName(&signed_cert_ptr->certificate.issuer, &data);
1146 if (rv == KMF_OK) {
1147 issuer = data.Data;
1148 issuer_len = data.Length;
1149 } else {
1150 rv = KMF_ERR_ENCODING;
1151 goto cleanup;
1152 }
1153
1154 /* Encode serial number */
1155 if (signed_cert_ptr->certificate.serialNumber.len > 0 &&
1156 signed_cert_ptr->certificate.serialNumber.val != NULL) {
1157 serial = signed_cert_ptr->certificate.serialNumber.val;
1158 serno_len = signed_cert_ptr->certificate.serialNumber.len;
1159 } else {
1160 /*
1161 * RFC3280 says to gracefully handle certs with serial numbers
1162 * of 0.
1163 */
1164 nullserno = '\0';
1165 serial = &nullserno;
1166 serno_len = 1;
1167 }
1168
1169 /* Generate an ID from the SPKI data */
1170 rv = GetIDFromSPKI(&signed_cert_ptr->certificate.subjectPublicKeyInfo,
1171 &Id);
1172
1173 if (rv != KMF_OK) {
1174 goto cleanup;
1175 }
1176
1177 i = 0;
1178 SETATTR(x509templ, i, CKA_CLASS, &certClass, sizeof (certClass)); i++;
1179 SETATTR(x509templ, i, CKA_CERTIFICATE_TYPE, &certtype,
1180 sizeof (certtype));
1181 i++;
1182 SETATTR(x509templ, i, CKA_TOKEN, &true, sizeof (true)); i++;
1183 SETATTR(x509templ, i, CKA_SUBJECT, subject, subject_len); i++;
1184 SETATTR(x509templ, i, CKA_ISSUER, issuer, issuer_len); i++;
1185 SETATTR(x509templ, i, CKA_SERIAL_NUMBER, serial, serno_len); i++;
1186 SETATTR(x509templ, i, CKA_VALUE, pcert->Data, pcert->Length); i++;
1187 SETATTR(x509templ, i, CKA_ID, Id.Data, Id.Length); i++;
1188 if (label != NULL && strlen(label)) {
1189 SETATTR(x509templ, i, CKA_LABEL, label, strlen(label)); i++;
1190 }
1191 /*
1192 * The cert object handle is actually "leaked" here. If the app
1193 * really wants to clean up the data space, it will have to call
1194 * KMF_DeleteCert and specify the softtoken keystore.
1195 */
1196 ckrv = C_CreateObject(kmfh->pk11handle, x509templ, i, &hCert);
1197 if (ckrv != CKR_OK) {
1198 /* Report authentication failures to the caller */
1199 if (ckrv == CKR_USER_NOT_LOGGED_IN ||
1200 ckrv == CKR_PIN_INCORRECT ||
1201 ckrv == CKR_PIN_INVALID ||
1202 ckrv == CKR_PIN_EXPIRED ||
1203 ckrv == CKR_PIN_LOCKED ||
1204 ckrv == CKR_SESSION_READ_ONLY)
1205 rv = KMF_ERR_AUTH_FAILED;
1206 else
1207 rv = KMF_ERR_INTERNAL;
1208 SET_ERROR(kmfh, ckrv);
1209 }
1210 free(subject);
1211 free(issuer);
1212
1213 cleanup:
1214 if (Id.Data != NULL)
1215 free(Id.Data);
1216
1217 if (signed_cert_ptr) {
1218 kmf_free_signed_cert(signed_cert_ptr);
1219 free(signed_cert_ptr);
1220 }
1221 return (rv);
1222 }
1223
1224
1225 KMF_RETURN
KMFPK11_StoreCert(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)1226 KMFPK11_StoreCert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
1227 {
1228 KMF_RETURN rv = 0;
1229 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
1230 KMF_DATA *cert = NULL;
1231 KMF_CREDENTIAL *cred = NULL;
1232 char *label = NULL;
1233
1234 if (kmfh == NULL)
1235 return (KMF_ERR_UNINITIALIZED);
1236
1237 if (kmfh->pk11handle == CK_INVALID_HANDLE)
1238 return (KMF_ERR_NO_TOKEN_SELECTED);
1239
1240 cert = kmf_get_attr_ptr(KMF_CERT_DATA_ATTR, attrlist, numattr);
1241 if (cert == NULL || cert->Data == NULL || cert->Length == 0)
1242 return (KMF_ERR_BAD_PARAMETER);
1243
1244 /* label attribute is optional */
1245 label = kmf_get_attr_ptr(KMF_CERT_LABEL_ATTR, attrlist, numattr);
1246
1247 cred = kmf_get_attr_ptr(KMF_CREDENTIAL_ATTR, attrlist, numattr);
1248 if (cred != NULL) {
1249 rv = pk11_authenticate(handle, cred);
1250 if (rv != KMF_OK)
1251 return (rv);
1252 }
1253
1254 rv = CreateCertObject(handle, label, cert);
1255 return (rv);
1256 }
1257
1258 KMF_RETURN
KMFPK11_ImportCert(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)1259 KMFPK11_ImportCert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
1260 {
1261 KMF_RETURN rv = 0;
1262 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
1263 char *certfile = NULL;
1264 char *label = NULL;
1265 KMF_ENCODE_FORMAT format;
1266 KMF_CREDENTIAL *cred = NULL;
1267 KMF_DATA cert1 = { 0, NULL };
1268 KMF_DATA cert2 = { 0, NULL };
1269
1270 if (kmfh == NULL)
1271 return (KMF_ERR_UNINITIALIZED);
1272
1273 if (kmfh->pk11handle == CK_INVALID_HANDLE)
1274 return (KMF_ERR_NO_TOKEN_SELECTED);
1275
1276 /*
1277 * Get the input cert filename attribute, check if it is a valid
1278 * certificate and auto-detect the file format of it.
1279 */
1280 certfile = kmf_get_attr_ptr(KMF_CERT_FILENAME_ATTR, attrlist, numattr);
1281 if (certfile == NULL)
1282 return (KMF_ERR_BAD_PARAMETER);
1283
1284 rv = kmf_is_cert_file(handle, certfile, &format);
1285 if (rv != KMF_OK)
1286 return (rv);
1287
1288 /* Read in the CERT file */
1289 rv = kmf_read_input_file(handle, certfile, &cert1);
1290 if (rv != KMF_OK) {
1291 return (rv);
1292 }
1293
1294 /* The label attribute is optional */
1295 label = kmf_get_attr_ptr(KMF_CERT_LABEL_ATTR, attrlist, numattr);
1296
1297 /*
1298 * If the input certificate is in PEM format, we need to convert
1299 * it to DER first.
1300 */
1301 if (format == KMF_FORMAT_PEM) {
1302 int derlen;
1303 rv = kmf_pem_to_der(cert1.Data, cert1.Length,
1304 &cert2.Data, &derlen);
1305 if (rv != KMF_OK) {
1306 goto out;
1307 }
1308 cert2.Length = (size_t)derlen;
1309 }
1310
1311 cred = kmf_get_attr_ptr(KMF_CREDENTIAL_ATTR, attrlist, numattr);
1312 if (cred != NULL) {
1313 rv = pk11_authenticate(handle, cred);
1314 if (rv != KMF_OK)
1315 return (rv);
1316 }
1317
1318 rv = CreateCertObject(handle, label,
1319 format == KMF_FORMAT_ASN1 ? &cert1 : &cert2);
1320
1321 out:
1322 if (cert1.Data != NULL) {
1323 free(cert1.Data);
1324 }
1325
1326 if (cert2.Data != NULL) {
1327 free(cert2.Data);
1328 }
1329
1330 return (rv);
1331 }
1332
1333 KMF_RETURN
KMFPK11_DeleteCert(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)1334 KMFPK11_DeleteCert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
1335 {
1336 KMF_RETURN rv = 0;
1337 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
1338 OBJLIST *objlist;
1339 uint32_t numObjects = 0;
1340 char *certlabel = NULL;
1341 char *issuer = NULL;
1342 char *subject = NULL;
1343 KMF_BIGINT *serial = NULL;
1344 KMF_CERT_VALIDITY validity;
1345 boolean_t private;
1346
1347 if (kmfh == NULL)
1348 return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */
1349
1350 if (kmfh->pk11handle == CK_INVALID_HANDLE)
1351 return (KMF_ERR_NO_TOKEN_SELECTED);
1352
1353
1354 /* Get the search criteria attributes. They are all optional. */
1355 certlabel = kmf_get_attr_ptr(KMF_CERT_LABEL_ATTR, attrlist, numattr);
1356 issuer = kmf_get_attr_ptr(KMF_ISSUER_NAME_ATTR, attrlist, numattr);
1357 subject = kmf_get_attr_ptr(KMF_SUBJECT_NAME_ATTR, attrlist, numattr);
1358 serial = kmf_get_attr_ptr(KMF_BIGINT_ATTR, attrlist, numattr);
1359
1360 rv = kmf_get_attr(KMF_CERT_VALIDITY_ATTR, attrlist, numattr,
1361 &validity, NULL);
1362 if (rv != KMF_OK) {
1363 validity = KMF_ALL_CERTS;
1364 rv = KMF_OK;
1365 }
1366
1367 rv = kmf_get_attr(KMF_PRIVATE_BOOL_ATTR, attrlist, numattr,
1368 (void *)&private, NULL);
1369 if (rv != KMF_OK) {
1370 private = B_FALSE;
1371 rv = KMF_OK;
1372 }
1373
1374 /*
1375 * Start searching for certificates that match the criteria and
1376 * delete them.
1377 */
1378 objlist = NULL;
1379 rv = search_certs(handle, certlabel, issuer, subject, serial,
1380 private, validity, &objlist, &numObjects);
1381
1382 if (rv == KMF_OK && objlist != NULL) {
1383 OBJLIST *node = objlist;
1384
1385 while (node != NULL) {
1386 CK_RV ckrv;
1387 ckrv = C_DestroyObject(kmfh->pk11handle, node->handle);
1388 if (ckrv != CKR_OK) {
1389 SET_ERROR(kmfh, ckrv);
1390 rv = KMF_ERR_INTERNAL;
1391 break;
1392 }
1393 node = node->next;
1394 }
1395 free_objlist(objlist);
1396 }
1397
1398 if (rv == KMF_OK && numObjects == 0)
1399 rv = KMF_ERR_CERT_NOT_FOUND;
1400
1401 out:
1402 return (rv);
1403 }
1404
1405 static CK_RV
gendsa_keypair(KMF_HANDLE * kmfh,boolean_t storekey,CK_OBJECT_HANDLE * pubKey,CK_OBJECT_HANDLE * priKey)1406 gendsa_keypair(KMF_HANDLE *kmfh, boolean_t storekey,
1407 CK_OBJECT_HANDLE *pubKey,
1408 CK_OBJECT_HANDLE *priKey)
1409 {
1410 CK_RV ckrv = CKR_OK;
1411 CK_SESSION_HANDLE hSession = kmfh->pk11handle;
1412 static CK_ULONG dsaKeyType = CKK_DSA;
1413 static CK_BBOOL true = TRUE;
1414 static CK_BBOOL false = FALSE;
1415 static CK_OBJECT_CLASS priClass = CKO_PRIVATE_KEY;
1416 static CK_OBJECT_CLASS pubClass = CKO_PUBLIC_KEY;
1417
1418 static CK_BYTE ckDsaPrime[128] = {
1419 0xb2, 0x6b, 0xc3, 0xfb, 0xe3, 0x26, 0xf4, 0xc2,
1420 0xcf, 0xdd, 0xf9, 0xae, 0x3e, 0x39, 0x7f, 0x9c,
1421 0xa7, 0x73, 0xc3, 0x00, 0xa3, 0x50, 0x67, 0xc3,
1422 0xab, 0x49, 0x2c, 0xea, 0x59, 0x10, 0xa4, 0xbc,
1423 0x09, 0x94, 0xa9, 0x05, 0x3b, 0x0d, 0x35, 0x3c,
1424 0x55, 0x52, 0x47, 0xf0, 0xe3, 0x72, 0x5b, 0xe8,
1425 0x72, 0xa0, 0x71, 0x1c, 0x23, 0x4f, 0x6d, 0xe8,
1426 0xac, 0xe5, 0x21, 0x1b, 0xc0, 0xd8, 0x42, 0xd3,
1427 0x87, 0xae, 0x83, 0x5e, 0x52, 0x7e, 0x46, 0x09,
1428 0xb5, 0xc7, 0x3d, 0xd6, 0x00, 0xf5, 0xf2, 0x9c,
1429 0x84, 0x30, 0x81, 0x7e, 0x7b, 0x30, 0x5b, 0xd5,
1430 0xab, 0xd0, 0x2f, 0x21, 0xb3, 0xd8, 0xed, 0xdb,
1431 0x97, 0x77, 0xe4, 0x7e, 0x6c, 0xcc, 0xb9, 0x6b,
1432 0xdd, 0xaa, 0x96, 0x04, 0xe7, 0xd4, 0x55, 0x11,
1433 0x53, 0xab, 0xba, 0x95, 0x9a, 0xa2, 0x8c, 0x27,
1434 0xd9, 0xcf, 0xad, 0xf3, 0xcf, 0x3a, 0x0c, 0x4b};
1435
1436 static CK_BYTE ckDsaSubPrime[20] = {
1437 0xa4, 0x5f, 0x2a, 0x27, 0x09, 0x49, 0xb6, 0xfe,
1438 0x73, 0xeb, 0x95, 0x7d, 0x00, 0xf3, 0x42, 0xfc,
1439 0x78, 0x47, 0xb0, 0xd5};
1440
1441 static CK_BYTE ckDsaBase[128] = {
1442 0x5c, 0x57, 0x16, 0x49, 0xef, 0xc8, 0xfb, 0x4b,
1443 0xee, 0x07, 0x45, 0x3b, 0x6a, 0x1d, 0xf3, 0xe5,
1444 0xeb, 0xee, 0xad, 0x11, 0x13, 0xe3, 0x52, 0xe3,
1445 0x0d, 0xc0, 0x21, 0x25, 0xfa, 0xf0, 0x93, 0x1c,
1446 0x53, 0x4d, 0xdc, 0x0d, 0x76, 0xd2, 0xfe, 0xc2,
1447 0xd7, 0x72, 0x64, 0x69, 0x53, 0x3d, 0x33, 0xbd,
1448 0xe1, 0x34, 0xf2, 0x5a, 0x67, 0x83, 0xe0, 0xd3,
1449 0x1c, 0xd6, 0x41, 0x4d, 0x16, 0xe8, 0x6c, 0x5a,
1450 0x07, 0x95, 0x21, 0x9a, 0xa3, 0xc4, 0xb9, 0x05,
1451 0x9d, 0x11, 0xcb, 0xc8, 0xc4, 0x9d, 0x00, 0x1a,
1452 0xf4, 0x85, 0x2a, 0xa9, 0x20, 0x3c, 0xba, 0x67,
1453 0xe5, 0xed, 0x31, 0xb2, 0x11, 0xfb, 0x1f, 0x73,
1454 0xec, 0x61, 0x29, 0xad, 0xc7, 0x68, 0xb2, 0x3f,
1455 0x38, 0xea, 0xd9, 0x87, 0x83, 0x9e, 0x7e, 0x19,
1456 0x18, 0xdd, 0xc2, 0xc3, 0x5b, 0x16, 0x6d, 0xce,
1457 0xcf, 0x88, 0x91, 0x07, 0xe0, 0x2b, 0xa8, 0x54 };
1458
1459 static CK_ATTRIBUTE ckDsaPubKeyTemplate[] = {
1460 { CKA_CLASS, &pubClass, sizeof (pubClass) },
1461 { CKA_KEY_TYPE, &dsaKeyType, sizeof (dsaKeyType) },
1462 { CKA_TOKEN, &true, sizeof (true)},
1463 { CKA_PRIVATE, &false, sizeof (false)},
1464 { CKA_PRIME, &ckDsaPrime, sizeof (ckDsaPrime) },
1465 { CKA_SUBPRIME, &ckDsaSubPrime, sizeof (ckDsaSubPrime)},
1466 { CKA_BASE, &ckDsaBase, sizeof (ckDsaBase) },
1467 { CKA_VERIFY, &true, sizeof (true) },
1468 };
1469
1470 #define NUMBER_DSA_PUB_TEMPLATES (sizeof (ckDsaPubKeyTemplate) / \
1471 sizeof (CK_ATTRIBUTE))
1472 #define MAX_DSA_PUB_TEMPLATES (sizeof (ckDsaPubKeyTemplate) / \
1473 sizeof (CK_ATTRIBUTE))
1474
1475 static CK_ATTRIBUTE ckDsaPriKeyTemplate[] = {
1476 {CKA_CLASS, &priClass, sizeof (priClass)},
1477 {CKA_KEY_TYPE, &dsaKeyType, sizeof (dsaKeyType)},
1478 {CKA_TOKEN, &true, sizeof (true)},
1479 {CKA_PRIVATE, &true, sizeof (true)},
1480 {CKA_SIGN, &true, sizeof (true)},
1481 };
1482
1483 #define NUMBER_DSA_PRI_TEMPLATES (sizeof (ckDsaPriKeyTemplate) / \
1484 sizeof (CK_ATTRIBUTE))
1485 #define MAX_DSA_PRI_TEMPLATES (sizeof (ckDsaPriKeyTemplate) / \
1486 sizeof (CK_ATTRIBUTE))
1487 CK_MECHANISM keyGenMech = {CKM_DSA_KEY_PAIR_GEN, NULL, 0};
1488
1489 SETATTR(ckDsaPriKeyTemplate, 2, CKA_TOKEN,
1490 (storekey ? &true : &false), sizeof (CK_BBOOL));
1491
1492 ckrv = C_GenerateKeyPair(hSession, &keyGenMech,
1493 ckDsaPubKeyTemplate,
1494 (sizeof (ckDsaPubKeyTemplate)/sizeof (CK_ATTRIBUTE)),
1495 ckDsaPriKeyTemplate,
1496 (sizeof (ckDsaPriKeyTemplate)/sizeof (CK_ATTRIBUTE)),
1497 pubKey, priKey);
1498 if (ckrv != CKR_OK) {
1499 SET_ERROR(kmfh, ckrv);
1500 return (KMF_ERR_KEYGEN_FAILED);
1501 }
1502
1503 return (ckrv);
1504 }
1505
1506 static CK_RV
genrsa_keypair(KMF_HANDLE * kmfh,CK_ULONG modulusBits,boolean_t storekey,KMF_BIGINT * rsaexp,CK_OBJECT_HANDLE * pubKey,CK_OBJECT_HANDLE * priKey)1507 genrsa_keypair(KMF_HANDLE *kmfh, CK_ULONG modulusBits,
1508 boolean_t storekey, KMF_BIGINT *rsaexp,
1509 CK_OBJECT_HANDLE *pubKey,
1510 CK_OBJECT_HANDLE *priKey)
1511 {
1512 CK_RV ckrv = CKR_OK;
1513 CK_SESSION_HANDLE hSession = kmfh->pk11handle;
1514 CK_ATTRIBUTE rsaPubKeyTemplate[16];
1515 CK_ATTRIBUTE rsaPriKeyTemplate[16];
1516 CK_MECHANISM keyGenMech = {CKM_RSA_PKCS_KEY_PAIR_GEN, NULL, 0};
1517 int numpubattr = 0, numpriattr = 0;
1518 static CK_BYTE PubExpo[3] = {0x01, 0x00, 0x01};
1519 static CK_BBOOL true = TRUE;
1520 static CK_BBOOL false = FALSE;
1521
1522 SETATTR(rsaPubKeyTemplate, numpubattr, CKA_TOKEN,
1523 (storekey ? &true : &false), sizeof (CK_BBOOL));
1524 numpubattr++;
1525
1526 SETATTR(rsaPubKeyTemplate, numpubattr, CKA_MODULUS_BITS,
1527 &modulusBits, sizeof (modulusBits));
1528 numpubattr++;
1529
1530 if (rsaexp != NULL && (rsaexp->len > 0 && rsaexp->val != NULL)) {
1531 SETATTR(rsaPubKeyTemplate, numpubattr,
1532 CKA_PUBLIC_EXPONENT,
1533 rsaexp->val, rsaexp->len);
1534 numpubattr++;
1535 } else {
1536 SETATTR(rsaPubKeyTemplate, numpubattr,
1537 CKA_PUBLIC_EXPONENT, &PubExpo, sizeof (PubExpo));
1538 numpubattr++;
1539 }
1540 SETATTR(rsaPubKeyTemplate, numpubattr, CKA_ENCRYPT,
1541 &true, sizeof (true));
1542 numpubattr++;
1543 SETATTR(rsaPubKeyTemplate, numpubattr, CKA_VERIFY,
1544 &true, sizeof (true));
1545 numpubattr++;
1546 SETATTR(rsaPubKeyTemplate, numpubattr, CKA_WRAP,
1547 &true, sizeof (true));
1548 numpubattr++;
1549
1550 SETATTR(rsaPriKeyTemplate, numpriattr, CKA_TOKEN,
1551 (storekey ? &true : &false), sizeof (CK_BBOOL));
1552 numpriattr++;
1553 SETATTR(rsaPriKeyTemplate, numpriattr, CKA_PRIVATE, &true,
1554 sizeof (true));
1555 numpriattr++;
1556 SETATTR(rsaPriKeyTemplate, numpriattr, CKA_DECRYPT, &true,
1557 sizeof (true));
1558 numpriattr++;
1559 SETATTR(rsaPriKeyTemplate, numpriattr, CKA_SIGN, &true,
1560 sizeof (true));
1561 numpriattr++;
1562 SETATTR(rsaPriKeyTemplate, numpriattr, CKA_UNWRAP, &true,
1563 sizeof (true));
1564 numpriattr++;
1565
1566 ckrv = C_GenerateKeyPair(hSession, &keyGenMech,
1567 rsaPubKeyTemplate, numpubattr,
1568 rsaPriKeyTemplate, numpriattr,
1569 pubKey, priKey);
1570 if (ckrv != CKR_OK) {
1571 SET_ERROR(kmfh, ckrv);
1572 return (ckrv);
1573 }
1574
1575 return (ckrv);
1576 }
1577
1578 static CK_RV
genecc_keypair(KMF_HANDLE * kmfh,boolean_t ontoken,KMF_OID * curveoid,CK_OBJECT_HANDLE * pubKey,CK_OBJECT_HANDLE * priKey)1579 genecc_keypair(KMF_HANDLE *kmfh,
1580 boolean_t ontoken,
1581 KMF_OID *curveoid,
1582 CK_OBJECT_HANDLE *pubKey,
1583 CK_OBJECT_HANDLE *priKey)
1584 {
1585 CK_RV ckrv;
1586 CK_SESSION_HANDLE hSession = kmfh->pk11handle;
1587 CK_MECHANISM keyGenMech = {CKM_EC_KEY_PAIR_GEN, NULL, 0};
1588 const ulong_t publicKey = CKO_PUBLIC_KEY;
1589 const ulong_t privateKey = CKO_PRIVATE_KEY;
1590 const ulong_t keytype = CKK_EC;
1591 static CK_BBOOL true = TRUE;
1592 static CK_BBOOL false = FALSE;
1593 CK_ATTRIBUTE public_template[6];
1594 CK_ATTRIBUTE private_template[6];
1595 int numpubattr, numpriattr;
1596
1597 numpubattr = 0;
1598 SETATTR(public_template, numpubattr, CKA_CLASS,
1599 &publicKey, sizeof (publicKey));
1600 numpubattr++;
1601 SETATTR(public_template, numpubattr, CKA_KEY_TYPE,
1602 &keytype, sizeof (keytype));
1603 numpubattr++;
1604 SETATTR(public_template, numpubattr, CKA_EC_PARAMS,
1605 curveoid->Data, curveoid->Length);
1606 numpubattr++;
1607 SETATTR(public_template, numpubattr, CKA_TOKEN,
1608 ontoken ? &true : &false, sizeof (true));
1609 numpubattr++;
1610 SETATTR(public_template, numpubattr, CKA_VERIFY,
1611 &true, sizeof (true));
1612 numpubattr++;
1613 SETATTR(public_template, numpubattr, CKA_PRIVATE,
1614 &false, sizeof (false));
1615 numpubattr++;
1616
1617 numpriattr = 0;
1618 SETATTR(private_template, numpriattr, CKA_CLASS,
1619 &privateKey, sizeof (privateKey));
1620 numpriattr++;
1621 SETATTR(private_template, numpriattr, CKA_KEY_TYPE,
1622 &keytype, sizeof (keytype));
1623 numpriattr++;
1624 SETATTR(private_template, numpriattr, CKA_TOKEN,
1625 ontoken ? &true : &false, sizeof (true));
1626 numpriattr++;
1627 SETATTR(private_template, numpriattr, CKA_PRIVATE,
1628 &true, sizeof (true));
1629 numpriattr++;
1630 SETATTR(private_template, numpriattr, CKA_SIGN,
1631 &true, sizeof (true));
1632 numpriattr++;
1633 SETATTR(private_template, numpriattr, CKA_DERIVE,
1634 &true, sizeof (true));
1635 numpriattr++;
1636
1637 ckrv = C_GenerateKeyPair(hSession, &keyGenMech,
1638 public_template, numpubattr,
1639 private_template, numpriattr,
1640 pubKey, priKey);
1641 if (ckrv != CKR_OK) {
1642 SET_ERROR(kmfh, ckrv);
1643 return (ckrv);
1644 }
1645
1646 return (ckrv);
1647 }
1648
1649 KMF_RETURN
KMFPK11_CreateKeypair(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attlist)1650 KMFPK11_CreateKeypair(KMF_HANDLE_T handle,
1651 int numattr,
1652 KMF_ATTRIBUTE *attlist)
1653 {
1654 KMF_RETURN rv = KMF_OK;
1655 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
1656 KMF_DATA IDInput, IDOutput;
1657 KMF_CREDENTIAL *cred;
1658 KMF_KEY_ALG keytype = KMF_RSA;
1659 KMF_KEY_HANDLE *pubkey, *privkey;
1660
1661 CK_RV ckrv = 0;
1662 CK_SESSION_HANDLE hSession = kmfh->pk11handle;
1663 CK_ATTRIBUTE labelattr[1];
1664 CK_ATTRIBUTE idattr[1];
1665 CK_OBJECT_HANDLE pubKey, priKey;
1666
1667 char IDHashData[SHA1_HASH_LENGTH];
1668 static CK_ULONG modulusBits = 1024;
1669 uint32_t modulusBits_size = sizeof (CK_ULONG);
1670 SHA1_CTX ctx;
1671 boolean_t storekey = TRUE;
1672 char *keylabel = NULL;
1673
1674 if (kmfh == NULL)
1675 return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */
1676
1677 if (kmfh->pk11handle == CK_INVALID_HANDLE)
1678 return (KMF_ERR_NO_TOKEN_SELECTED);
1679
1680 /* "storekey" is optional. Default is TRUE */
1681 (void) kmf_get_attr(KMF_STOREKEY_BOOL_ATTR, attlist, numattr,
1682 &storekey, NULL);
1683
1684 cred = kmf_get_attr_ptr(KMF_CREDENTIAL_ATTR, attlist, numattr);
1685 if (cred == NULL)
1686 return (KMF_ERR_BAD_PARAMETER);
1687
1688 rv = pk11_authenticate(handle, cred);
1689 if (rv != KMF_OK)
1690 return (rv);
1691
1692 /* keytype is optional. KMF_RSA is default */
1693 (void) kmf_get_attr(KMF_KEYALG_ATTR, attlist, numattr,
1694 (void *)&keytype, NULL);
1695
1696 pubkey = kmf_get_attr_ptr(KMF_PUBKEY_HANDLE_ATTR, attlist, numattr);
1697 if (pubkey == NULL)
1698 return (KMF_ERR_BAD_PARAMETER);
1699
1700 privkey = kmf_get_attr_ptr(KMF_PRIVKEY_HANDLE_ATTR, attlist, numattr);
1701 if (privkey == NULL)
1702 return (KMF_ERR_BAD_PARAMETER);
1703
1704 (void) memset(pubkey, 0, sizeof (KMF_KEY_HANDLE));
1705 (void) memset(privkey, 0, sizeof (KMF_KEY_HANDLE));
1706 if (keytype == KMF_RSA) {
1707 CK_BYTE *modulus = NULL;
1708 CK_ULONG modulusLength = 0;
1709 KMF_BIGINT *rsaexp = NULL;
1710 CK_ATTRIBUTE modattr[1];
1711
1712 rv = kmf_get_attr(KMF_KEYLENGTH_ATTR, attlist, numattr,
1713 &modulusBits, &modulusBits_size);
1714 if (rv == KMF_ERR_ATTR_NOT_FOUND)
1715 /* Default modulusBits = 1024 */
1716 rv = KMF_OK;
1717 if (rv != KMF_OK)
1718 return (KMF_ERR_BAD_PARAMETER);
1719
1720 rsaexp = kmf_get_attr_ptr(KMF_RSAEXP_ATTR, attlist, numattr);
1721
1722 /* Generate the RSA keypair */
1723 ckrv = genrsa_keypair(kmfh, modulusBits, storekey,
1724 rsaexp, &pubKey, &priKey);
1725
1726 if (ckrv != CKR_OK)
1727 return (KMF_ERR_BAD_PARAMETER);
1728
1729 privkey->kstype = KMF_KEYSTORE_PK11TOKEN;
1730 privkey->keyalg = KMF_RSA;
1731 privkey->keyclass = KMF_ASYM_PRI;
1732 privkey->keyp = (void *)priKey;
1733
1734 pubkey->kstype = KMF_KEYSTORE_PK11TOKEN;
1735 pubkey->keyalg = KMF_RSA;
1736 pubkey->keyclass = KMF_ASYM_PUB;
1737 pubkey->keyp = (void *)pubKey;
1738
1739 SETATTR(modattr, 0, CKA_MODULUS, NULL, modulusLength);
1740 /* Get the Modulus field to use as input for creating the ID */
1741 ckrv = C_GetAttributeValue(kmfh->pk11handle,
1742 (CK_OBJECT_HANDLE)pubKey, modattr, 1);
1743 if (ckrv != CKR_OK) {
1744 SET_ERROR(kmfh, ckrv);
1745 return (KMF_ERR_BAD_PARAMETER);
1746 }
1747
1748 modulusLength = modattr[0].ulValueLen;
1749 modulus = malloc(modulusLength);
1750 if (modulus == NULL)
1751 return (KMF_ERR_MEMORY);
1752
1753 modattr[0].pValue = modulus;
1754 ckrv = C_GetAttributeValue(kmfh->pk11handle,
1755 (CK_OBJECT_HANDLE)pubKey, modattr, 1);
1756 if (ckrv != CKR_OK) {
1757 SET_ERROR(kmfh, ckrv);
1758 free(modulus);
1759 return (KMF_ERR_BAD_PARAMETER);
1760 }
1761
1762 IDInput.Data = modulus;
1763 IDInput.Length = modulusLength;
1764
1765 } else if (keytype == KMF_DSA) {
1766 CK_BYTE *keyvalue;
1767 CK_ULONG valueLen;
1768 CK_ATTRIBUTE valattr[1];
1769
1770 /* Generate the DSA keypair */
1771 ckrv = gendsa_keypair(kmfh, storekey, &pubKey, &priKey);
1772 if (ckrv != CKR_OK)
1773 return (KMF_ERR_BAD_PARAMETER);
1774
1775 privkey->kstype = KMF_KEYSTORE_PK11TOKEN;
1776 privkey->keyalg = KMF_DSA;
1777 privkey->keyclass = KMF_ASYM_PRI;
1778 privkey->keyp = (void *)priKey;
1779
1780 pubkey->kstype = KMF_KEYSTORE_PK11TOKEN;
1781 pubkey->keyalg = KMF_DSA;
1782 pubkey->keyclass = KMF_ASYM_PUB;
1783 pubkey->keyp = (void *)pubKey;
1784
1785 /* Get the Public Value to use as input for creating the ID */
1786 SETATTR(valattr, 0, CKA_VALUE, NULL, &valueLen);
1787
1788 ckrv = C_GetAttributeValue(hSession,
1789 (CK_OBJECT_HANDLE)pubKey, valattr, 1);
1790 if (ckrv != CKR_OK) {
1791 SET_ERROR(kmfh, ckrv);
1792 return (KMF_ERR_BAD_PARAMETER);
1793 }
1794
1795 valueLen = valattr[0].ulValueLen;
1796 keyvalue = malloc(valueLen);
1797 if (keyvalue == NULL)
1798 return (KMF_ERR_MEMORY);
1799
1800 valattr[0].pValue = keyvalue;
1801 ckrv = C_GetAttributeValue(hSession,
1802 (CK_OBJECT_HANDLE)pubKey, valattr, 1);
1803 if (ckrv != CKR_OK) {
1804 SET_ERROR(kmfh, ckrv);
1805 free(keyvalue);
1806 return (KMF_ERR_BAD_PARAMETER);
1807 }
1808
1809 IDInput.Data = keyvalue;
1810 IDInput.Length = valueLen;
1811 } else if (keytype == KMF_ECDSA) {
1812 CK_BYTE *keyvalue;
1813 CK_ULONG valueLen;
1814 CK_ATTRIBUTE valattr[1];
1815 KMF_OID *eccoid = kmf_get_attr_ptr(KMF_ECC_CURVE_OID_ATTR,
1816 attlist, numattr);
1817
1818 if (eccoid == NULL)
1819 return (KMF_ERR_BAD_PARAMETER);
1820
1821 ckrv = genecc_keypair(kmfh, storekey, eccoid,
1822 &pubKey, &priKey);
1823 if (ckrv != CKR_OK)
1824 return (KMF_ERR_BAD_PARAMETER);
1825
1826 privkey->kstype = KMF_KEYSTORE_PK11TOKEN;
1827 privkey->keyalg = KMF_ECDSA;
1828 privkey->keyclass = KMF_ASYM_PRI;
1829 privkey->keyp = (void *)priKey;
1830
1831 pubkey->kstype = KMF_KEYSTORE_PK11TOKEN;
1832 pubkey->keyalg = KMF_ECDSA;
1833 pubkey->keyclass = KMF_ASYM_PUB;
1834 pubkey->keyp = (void *)pubKey;
1835
1836 /* Get the EC_POINT to use as input for creating the ID */
1837 SETATTR(valattr, 0, CKA_EC_POINT, NULL, &valueLen);
1838
1839 ckrv = C_GetAttributeValue(hSession,
1840 (CK_OBJECT_HANDLE)pubKey, valattr, 1);
1841 if (ckrv != CKR_OK) {
1842 SET_ERROR(kmfh, ckrv);
1843 return (KMF_ERR_BAD_PARAMETER);
1844 }
1845
1846 valueLen = valattr[0].ulValueLen;
1847 keyvalue = malloc(valueLen);
1848 if (keyvalue == NULL)
1849 return (KMF_ERR_MEMORY);
1850
1851 valattr[0].pValue = keyvalue;
1852 ckrv = C_GetAttributeValue(hSession,
1853 (CK_OBJECT_HANDLE)pubKey, valattr, 1);
1854 if (ckrv != CKR_OK) {
1855 SET_ERROR(kmfh, ckrv);
1856 free(keyvalue);
1857 return (KMF_ERR_BAD_PARAMETER);
1858 }
1859
1860 IDInput.Data = keyvalue;
1861 IDInput.Length = valueLen;
1862 } else {
1863 return (KMF_ERR_BAD_PARAMETER);
1864 }
1865
1866 keylabel = kmf_get_attr_ptr(KMF_KEYLABEL_ATTR, attlist, numattr);
1867 if (keylabel != NULL && strlen(keylabel)) {
1868 SETATTR(labelattr, 0, CKA_LABEL, keylabel, strlen(keylabel));
1869
1870 /* Set the CKA_LABEL if one was indicated */
1871 if ((ckrv = C_SetAttributeValue(hSession, pubKey,
1872 labelattr, 1)) != CKR_OK) {
1873 SET_ERROR(kmfh, ckrv);
1874 rv = KMF_ERR_INTERNAL;
1875 goto cleanup;
1876 }
1877 pubkey->keylabel = (char *)strdup(keylabel);
1878 if (pubkey->keylabel == NULL) {
1879 rv = KMF_ERR_MEMORY;
1880 goto cleanup;
1881 }
1882 if ((ckrv = C_SetAttributeValue(hSession, priKey,
1883 labelattr, 1)) != CKR_OK) {
1884 SET_ERROR(kmfh, ckrv);
1885 rv = KMF_ERR_INTERNAL;
1886 goto cleanup;
1887 }
1888 privkey->keylabel = (char *)strdup(keylabel);
1889 if (privkey->keylabel == NULL) {
1890 rv = KMF_ERR_MEMORY;
1891 goto cleanup;
1892 }
1893 } else {
1894 rv = KMF_OK;
1895 }
1896
1897 /* Now, assign a CKA_ID value so it can be searched */
1898 /* ID_Input was assigned above in the RSA or DSA keygen section */
1899 IDOutput.Data = (uchar_t *)IDHashData;
1900 IDOutput.Length = sizeof (IDHashData);
1901
1902 SHA1Init(&ctx);
1903 SHA1Update(&ctx, IDInput.Data, IDInput.Length);
1904 SHA1Final(IDOutput.Data, &ctx);
1905
1906 IDOutput.Length = SHA1_DIGEST_LENGTH;
1907
1908 free(IDInput.Data);
1909
1910 if (rv != CKR_OK) {
1911 goto cleanup;
1912 }
1913 SETATTR(idattr, 0, CKA_ID, IDOutput.Data, IDOutput.Length);
1914 if ((ckrv = C_SetAttributeValue(hSession, pubKey,
1915 idattr, 1)) != CKR_OK) {
1916 SET_ERROR(kmfh, ckrv);
1917 rv = KMF_ERR_INTERNAL;
1918 goto cleanup;
1919 }
1920 if ((ckrv = C_SetAttributeValue(hSession, priKey,
1921 idattr, 1)) != CKR_OK) {
1922 SET_ERROR(kmfh, ckrv);
1923 rv = KMF_ERR_INTERNAL;
1924 goto cleanup;
1925 }
1926
1927 cleanup:
1928 if (rv != KMF_OK) {
1929 if (pubKey != CK_INVALID_HANDLE)
1930 (void) C_DestroyObject(hSession, pubKey);
1931 if (priKey != CK_INVALID_HANDLE)
1932 (void) C_DestroyObject(hSession, priKey);
1933
1934 if (privkey->keylabel)
1935 free(privkey->keylabel);
1936 if (pubkey->keylabel)
1937 free(pubkey->keylabel);
1938 }
1939 return (rv);
1940 }
1941
1942 KMF_RETURN
KMFPK11_DeleteKey(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)1943 KMFPK11_DeleteKey(KMF_HANDLE_T handle,
1944 int numattr, KMF_ATTRIBUTE *attrlist)
1945 {
1946 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
1947 CK_RV ckrv = CKR_OK;
1948 KMF_RETURN rv = KMF_OK;
1949 KMF_KEY_HANDLE *key;
1950 KMF_CREDENTIAL cred;
1951 boolean_t destroy = B_TRUE;
1952
1953 if (kmfh == NULL)
1954 return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */
1955
1956 if (kmfh->pk11handle == CK_INVALID_HANDLE)
1957 return (KMF_ERR_NO_TOKEN_SELECTED);
1958
1959 key = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr);
1960 if (key == NULL || key->keyp == NULL)
1961 return (KMF_ERR_BAD_PARAMETER);
1962
1963 if (key->keyclass != KMF_ASYM_PUB &&
1964 key->keyclass != KMF_ASYM_PRI &&
1965 key->keyclass != KMF_SYMMETRIC)
1966 return (KMF_ERR_BAD_KEY_CLASS);
1967
1968 /* "destroy" is optional. Default is TRUE */
1969 (void) kmf_get_attr(KMF_DESTROY_BOOL_ATTR, attrlist, numattr,
1970 (void *)&destroy, NULL);
1971
1972 if (destroy) {
1973 rv = kmf_get_attr(KMF_CREDENTIAL_ATTR, attrlist, numattr,
1974 (void *)&cred, NULL);
1975 if (rv != KMF_OK)
1976 return (KMF_ERR_BAD_PARAMETER);
1977
1978 rv = pk11_authenticate(handle, &cred);
1979 if (rv != KMF_OK) {
1980 return (rv);
1981 }
1982 }
1983
1984 if (!key->israw && destroy)
1985 ckrv = C_DestroyObject(kmfh->pk11handle,
1986 (CK_OBJECT_HANDLE)key->keyp);
1987
1988 if (ckrv != CKR_OK) {
1989 SET_ERROR(kmfh, ckrv);
1990 /* Report authentication failures to the caller */
1991 if (ckrv == CKR_PIN_EXPIRED || ckrv == CKR_SESSION_READ_ONLY)
1992 rv = KMF_ERR_AUTH_FAILED;
1993 else
1994 rv = KMF_ERR_INTERNAL;
1995 }
1996 return (rv);
1997 }
1998
1999 KMF_RETURN
KMFPK11_SignData(KMF_HANDLE_T handle,KMF_KEY_HANDLE * keyp,KMF_OID * algOID,KMF_DATA * tobesigned,KMF_DATA * output)2000 KMFPK11_SignData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *keyp,
2001 KMF_OID *algOID,
2002 KMF_DATA *tobesigned,
2003 KMF_DATA *output)
2004 {
2005 KMF_RETURN rv = KMF_OK;
2006 CK_RV ckrv;
2007 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
2008 CK_SESSION_HANDLE hSession = kmfh->pk11handle;
2009 CK_MECHANISM mechanism;
2010 CK_MECHANISM_TYPE mechtype, hashmech;
2011 CK_KEY_TYPE keytype;
2012 KMF_ALGORITHM_INDEX AlgId;
2013 KMF_DATA hashData = { 0, NULL };
2014 uchar_t digest[1024];
2015 CK_ATTRIBUTE subprime = { CKA_SUBPRIME, NULL, 0 };
2016
2017 if (kmfh == NULL)
2018 return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */
2019
2020 if (kmfh->pk11handle == CK_INVALID_HANDLE)
2021 return (KMF_ERR_NO_TOKEN_SELECTED);
2022
2023 if (keyp == NULL || algOID == NULL ||
2024 tobesigned == NULL || output == NULL)
2025 return (KMF_ERR_BAD_PARAMETER);
2026
2027 /* These functions are available to the plugin from libkmf */
2028 AlgId = x509_algoid_to_algid(algOID);
2029 if (AlgId == KMF_ALGID_NONE)
2030 return (KMF_ERR_BAD_PARAMETER);
2031
2032 /* Get the PKCS11 signing key type and mechtype */
2033 if (get_pk11_data(AlgId, &keytype, &mechtype, &hashmech, 0))
2034 return (KMF_ERR_BAD_PARAMETER);
2035
2036 (void) memset(digest, 0, sizeof (digest));
2037 hashData.Data = digest;
2038 hashData.Length = sizeof (digest);
2039 rv = PKCS_DigestData(handle, hSession, hashmech, tobesigned, &hashData,
2040 (mechtype == CKM_RSA_PKCS));
2041 if (rv)
2042 return (rv);
2043
2044 if (mechtype == CKM_DSA && hashmech == CKM_SHA256) {
2045 /*
2046 * FIPS 186-3 says that when signing with DSA
2047 * the hash must be truncated to the size of the
2048 * subprime.
2049 */
2050 ckrv = C_GetAttributeValue(hSession,
2051 (CK_OBJECT_HANDLE)keyp->keyp,
2052 &subprime, 1);
2053 if (ckrv != CKR_OK) {
2054 SET_ERROR(kmfh, ckrv);
2055 return (KMF_ERR_INTERNAL);
2056 }
2057 hashData.Length = subprime.ulValueLen;
2058 }
2059
2060 /* the mechtype from the 'get_pk11_info' refers to the signing */
2061 mechanism.mechanism = mechtype;
2062 mechanism.pParameter = NULL;
2063 mechanism.ulParameterLen = 0;
2064
2065 ckrv = C_SignInit(hSession, &mechanism, (CK_OBJECT_HANDLE)keyp->keyp);
2066 if (ckrv != CKR_OK) {
2067 SET_ERROR(kmfh, ckrv);
2068 return (KMF_ERR_INTERNAL);
2069 }
2070
2071 ckrv = C_Sign(hSession, hashData.Data, hashData.Length,
2072 output->Data, (CK_ULONG *)&output->Length);
2073
2074 if (ckrv != CKR_OK) {
2075 SET_ERROR(kmfh, ckrv);
2076 return (KMF_ERR_INTERNAL);
2077 }
2078
2079 return (KMF_OK);
2080 }
2081
2082 KMF_RETURN
KMFPK11_GetErrorString(KMF_HANDLE_T handle,char ** msgstr)2083 KMFPK11_GetErrorString(KMF_HANDLE_T handle, char **msgstr)
2084 {
2085 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
2086
2087 *msgstr = NULL;
2088 if (kmfh->lasterr.errcode != 0) {
2089 char *e = pkcs11_strerror(kmfh->lasterr.errcode);
2090 if (e == NULL || (*msgstr = (char *)strdup(e)) == NULL) {
2091 return (KMF_ERR_MEMORY);
2092 }
2093 }
2094
2095 return (KMF_OK);
2096 }
2097
2098 static CK_RV
getObjectKeytype(KMF_HANDLE_T handle,CK_OBJECT_HANDLE obj,CK_ULONG * keytype)2099 getObjectKeytype(KMF_HANDLE_T handle, CK_OBJECT_HANDLE obj,
2100 CK_ULONG *keytype)
2101 {
2102 CK_RV rv = CKR_OK;
2103 CK_ATTRIBUTE templ;
2104 CK_ULONG len = sizeof (CK_ULONG);
2105 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
2106
2107 templ.type = CKA_KEY_TYPE;
2108 templ.pValue = keytype;
2109 templ.ulValueLen = len;
2110
2111 rv = C_GetAttributeValue(kmfh->pk11handle, obj, &templ, 1);
2112
2113 return (rv);
2114
2115 }
2116
2117 static CK_RV
getObjectLabel(KMF_HANDLE_T handle,CK_OBJECT_HANDLE obj,char ** outlabel)2118 getObjectLabel(KMF_HANDLE_T handle, CK_OBJECT_HANDLE obj,
2119 char **outlabel)
2120 {
2121 CK_RV rv = CKR_OK;
2122 CK_ATTRIBUTE templ;
2123 char Label[BUFSIZ];
2124 CK_ULONG len = sizeof (Label);
2125 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
2126
2127 (void) memset(Label, 0, len);
2128 templ.type = CKA_LABEL;
2129 templ.pValue = Label;
2130 templ.ulValueLen = len;
2131
2132 rv = C_GetAttributeValue(kmfh->pk11handle, obj, &templ, 1);
2133 if (rv == CKR_OK) {
2134 *outlabel = (char *)strdup(Label);
2135 } else {
2136 *outlabel = NULL;
2137 }
2138 return (rv);
2139 }
2140
2141 static CK_RV
getObjectKeyclass(KMF_HANDLE_T handle,CK_OBJECT_HANDLE obj,KMF_KEY_CLASS * keyclass)2142 getObjectKeyclass(KMF_HANDLE_T handle, CK_OBJECT_HANDLE obj,
2143 KMF_KEY_CLASS *keyclass)
2144 {
2145 CK_RV rv = CKR_OK;
2146 CK_ATTRIBUTE templ;
2147 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
2148 CK_OBJECT_CLASS class;
2149
2150 templ.type = CKA_CLASS;
2151 templ.pValue = &class;
2152 templ.ulValueLen = sizeof (CK_OBJECT_CLASS);
2153
2154 rv = C_GetAttributeValue(kmfh->pk11handle, obj, &templ, 1);
2155 if (rv == CKR_OK) {
2156 if (class == CKO_PUBLIC_KEY) {
2157 *keyclass = KMF_ASYM_PUB;
2158 } else if (class == CKO_PRIVATE_KEY) {
2159 *keyclass = KMF_ASYM_PRI;
2160 } else if (class == CKO_SECRET_KEY) {
2161 *keyclass = KMF_SYMMETRIC;
2162 }
2163 } else {
2164 *keyclass = KMF_KEYCLASS_NONE;
2165 }
2166 return (rv);
2167 }
2168
2169 KMF_RETURN
KMFPK11_FindPrikeyByCert(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)2170 KMFPK11_FindPrikeyByCert(KMF_HANDLE_T handle, int numattr,
2171 KMF_ATTRIBUTE *attrlist)
2172 {
2173 KMF_X509_SPKI *pubkey;
2174 KMF_X509_CERTIFICATE *SignerCert = NULL;
2175 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
2176 KMF_RETURN rv = KMF_OK;
2177 CK_RV ckrv = CKR_OK;
2178 CK_ATTRIBUTE templ[4];
2179 CK_OBJECT_HANDLE pri_obj = CK_INVALID_HANDLE;
2180 CK_ULONG obj_count;
2181 CK_OBJECT_CLASS objClass = CKO_PRIVATE_KEY;
2182 CK_BBOOL true = TRUE;
2183 KMF_DATA Id = { 0, NULL };
2184 KMF_KEY_HANDLE *key = NULL;
2185 KMF_DATA *cert = NULL;
2186 KMF_CREDENTIAL cred;
2187 KMF_ENCODE_FORMAT format = KMF_FORMAT_UNDEF;
2188 CK_ULONG keytype;
2189
2190 /* Get the key handle */
2191 key = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr);
2192 if (key == NULL)
2193 return (KMF_ERR_BAD_PARAMETER);
2194
2195 /* Get the optional encoded format */
2196 (void) kmf_get_attr(KMF_ENCODE_FORMAT_ATTR, attrlist, numattr,
2197 (void *)&format, NULL);
2198
2199 /* Decode the signer cert so we can get the SPKI data */
2200 cert = kmf_get_attr_ptr(KMF_CERT_DATA_ATTR, attrlist, numattr);
2201 if (cert == NULL || cert->Data == NULL)
2202 return (KMF_ERR_BAD_PARAMETER);
2203
2204 if ((rv = DerDecodeSignedCertificate(cert,
2205 &SignerCert)) != KMF_OK)
2206 return (rv);
2207
2208 /* Get the public key info from the signer certificate */
2209 pubkey = &SignerCert->certificate.subjectPublicKeyInfo;
2210
2211 /* Generate an ID from the SPKI data */
2212 rv = GetIDFromSPKI(pubkey, &Id);
2213 if (rv != KMF_OK) {
2214 goto errout;
2215 }
2216
2217 /* Get the credential and login */
2218 rv = kmf_get_attr(KMF_CREDENTIAL_ATTR, attrlist, numattr,
2219 (void *)&cred, NULL);
2220 if (rv != KMF_OK)
2221 return (KMF_ERR_BAD_PARAMETER);
2222
2223 rv = pk11_authenticate(handle, &cred);
2224 if (rv != KMF_OK) {
2225 return (rv);
2226 }
2227
2228 /* Start searching */
2229 SETATTR(templ, 0, CKA_CLASS, &objClass, sizeof (objClass));
2230 SETATTR(templ, 1, CKA_TOKEN, &true, sizeof (true));
2231 SETATTR(templ, 2, CKA_PRIVATE, &true, sizeof (true));
2232 SETATTR(templ, 3, CKA_ID, Id.Data, Id.Length);
2233
2234 if ((ckrv = C_FindObjectsInit(kmfh->pk11handle, templ, 4)) != CKR_OK) {
2235 SET_ERROR(kmfh, ckrv);
2236 rv = KMF_ERR_INTERNAL;
2237 goto errout;
2238 }
2239
2240 if ((ckrv = C_FindObjects(kmfh->pk11handle, &pri_obj, 1,
2241 &obj_count)) != CKR_OK) {
2242 SET_ERROR(kmfh, ckrv);
2243 rv = KMF_ERR_INTERNAL;
2244 goto errout;
2245 }
2246
2247 if (obj_count == 0) {
2248 SET_ERROR(kmfh, ckrv);
2249 rv = KMF_ERR_KEY_NOT_FOUND;
2250 goto errout;
2251 }
2252
2253 key->kstype = KMF_KEYSTORE_PK11TOKEN;
2254 key->keyclass = KMF_ASYM_PRI;
2255 key->keyp = (void *)pri_obj;
2256 key->israw = FALSE;
2257
2258 (void) C_FindObjectsFinal(kmfh->pk11handle);
2259
2260 ckrv = getObjectLabel(handle, (CK_OBJECT_HANDLE)key->keyp,
2261 &key->keylabel);
2262 if (ckrv != CKR_OK) {
2263 SET_ERROR(handle, ckrv);
2264 rv = KMF_ERR_INTERNAL;
2265 } else {
2266 rv = KMF_OK;
2267 }
2268
2269 /*
2270 * The key->keyalg value is needed if we need to convert the key
2271 * to raw key. However, the key->keyalg value will not be set if
2272 * this function is not called thru the kmf_find_prikey_by_cert()
2273 * framework function. To be safe, we will get the keytype from
2274 * the key object and set key->keyalg value here.
2275 */
2276 ckrv = getObjectKeytype(handle, (CK_OBJECT_HANDLE)key->keyp,
2277 &keytype);
2278 if (ckrv != CKR_OK) {
2279 SET_ERROR(handle, ckrv);
2280 rv = KMF_ERR_INTERNAL;
2281 } else {
2282 rv = KMF_OK;
2283 }
2284
2285 if (keytype == CKK_RSA)
2286 key->keyalg = KMF_RSA;
2287 else if (keytype == CKK_DSA)
2288 key->keyalg = KMF_DSA;
2289 else if (keytype == CKK_EC)
2290 key->keyalg = KMF_ECDSA;
2291 else {
2292 /* For asymmetric keys, we only support RSA and DSA */
2293 rv = KMF_ERR_KEY_NOT_FOUND;
2294 goto errout;
2295 }
2296
2297 if (rv == KMF_OK && format == KMF_FORMAT_RAWKEY) {
2298 KMF_RAW_KEY_DATA *rkey = NULL;
2299 rv = keyObj2RawKey(handle, key, &rkey);
2300 if (rv == KMF_OK) {
2301 key->keyp = rkey;
2302 key->israw = TRUE;
2303 }
2304 }
2305
2306 errout:
2307 if (Id.Data != NULL)
2308 free(Id.Data);
2309
2310 if (SignerCert != NULL) {
2311 kmf_free_signed_cert(SignerCert);
2312 free(SignerCert);
2313 }
2314 return (rv);
2315 }
2316
2317 KMF_RETURN
KMFPK11_DecryptData(KMF_HANDLE_T handle,KMF_KEY_HANDLE * key,KMF_OID * algOID,KMF_DATA * ciphertext,KMF_DATA * output)2318 KMFPK11_DecryptData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *key,
2319 KMF_OID *algOID, KMF_DATA *ciphertext,
2320 KMF_DATA *output)
2321 {
2322 CK_RV ckrv;
2323 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
2324 CK_SESSION_HANDLE hSession = kmfh->pk11handle;
2325 CK_MECHANISM mechanism;
2326 CK_MECHANISM_TYPE mechtype;
2327 CK_KEY_TYPE keytype;
2328 KMF_ALGORITHM_INDEX AlgId;
2329 CK_ULONG out_len = 0, block_len = 0, total_decrypted = 0;
2330 uint8_t *in_data, *out_data;
2331 int i, blocks;
2332 CK_ATTRIBUTE ckTemplate[1];
2333
2334 if (kmfh == NULL)
2335 return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */
2336
2337 if (kmfh->pk11handle == CK_INVALID_HANDLE)
2338 return (KMF_ERR_NO_TOKEN_SELECTED);
2339
2340 if (key == NULL || algOID == NULL ||
2341 ciphertext == NULL || output == NULL)
2342 return (KMF_ERR_BAD_PARAMETER);
2343
2344 AlgId = x509_algoid_to_algid(algOID);
2345 if (AlgId == KMF_ALGID_NONE)
2346 return (KMF_ERR_BAD_PARAMETER);
2347
2348 /* Map the Algorithm ID to a PKCS#11 mechanism */
2349 if (get_pk11_data(AlgId, &keytype, &mechtype, NULL, 0))
2350 return (KMF_ERR_BAD_PARAMETER);
2351
2352 mechanism.mechanism = mechtype;
2353 mechanism.pParameter = NULL;
2354 mechanism.ulParameterLen = 0;
2355
2356 SETATTR(ckTemplate, 0, CKA_MODULUS, (CK_BYTE *)NULL,
2357 sizeof (CK_ULONG));
2358
2359 /* Get the modulus length */
2360 ckrv = C_GetAttributeValue(hSession,
2361 (CK_OBJECT_HANDLE)key->keyp, ckTemplate, 1);
2362
2363 if (ckrv != CKR_OK) {
2364 SET_ERROR(kmfh, ckrv);
2365 return (KMF_ERR_INTERNAL);
2366 }
2367
2368 block_len = ckTemplate[0].ulValueLen;
2369
2370 /* Compute the number of times to do single-part decryption */
2371 blocks = ciphertext->Length/block_len;
2372
2373 out_data = output->Data;
2374 in_data = ciphertext->Data;
2375 out_len = block_len - 11;
2376
2377 for (i = 0; i < blocks; i++) {
2378 ckrv = C_DecryptInit(hSession, &mechanism,
2379 (CK_OBJECT_HANDLE)key->keyp);
2380
2381 if (ckrv != CKR_OK) {
2382 SET_ERROR(kmfh, ckrv);
2383 return (KMF_ERR_INTERNAL);
2384 }
2385
2386 ckrv = C_Decrypt(hSession, in_data, block_len,
2387 out_data, (CK_ULONG *)&out_len);
2388
2389 if (ckrv != CKR_OK) {
2390 SET_ERROR(kmfh, ckrv);
2391 return (KMF_ERR_INTERNAL);
2392 }
2393
2394 out_data += out_len;
2395 total_decrypted += out_len;
2396 in_data += block_len;
2397
2398 }
2399
2400 output->Length = total_decrypted;
2401 return (KMF_OK);
2402 }
2403
2404 static void
attr2bigint(CK_ATTRIBUTE_PTR attr,KMF_BIGINT * big)2405 attr2bigint(CK_ATTRIBUTE_PTR attr, KMF_BIGINT *big)
2406 {
2407 big->val = attr->pValue;
2408 big->len = attr->ulValueLen;
2409 }
2410
2411 static KMF_RETURN
get_bigint_attr(CK_SESSION_HANDLE sess,CK_OBJECT_HANDLE obj,CK_ATTRIBUTE_TYPE attrtype,KMF_BIGINT * bigint)2412 get_bigint_attr(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj,
2413 CK_ATTRIBUTE_TYPE attrtype, KMF_BIGINT *bigint)
2414 {
2415 CK_RV ckrv;
2416 CK_ATTRIBUTE attr;
2417
2418 attr.type = attrtype;
2419 attr.pValue = NULL;
2420 attr.ulValueLen = 0;
2421
2422 if ((ckrv = C_GetAttributeValue(sess, obj,
2423 &attr, 1)) != CKR_OK) {
2424 /* Mask this error so the caller can continue */
2425 if (ckrv == CKR_ATTRIBUTE_TYPE_INVALID)
2426 return (KMF_OK);
2427 else
2428 return (KMF_ERR_INTERNAL);
2429 }
2430 if (attr.ulValueLen > 0 && bigint != NULL) {
2431 attr.pValue = malloc(attr.ulValueLen);
2432 if (attr.pValue == NULL)
2433 return (KMF_ERR_MEMORY);
2434
2435 if ((ckrv = C_GetAttributeValue(sess, obj,
2436 &attr, 1)) != CKR_OK)
2437 if (ckrv != CKR_OK) {
2438 free(attr.pValue);
2439 return (KMF_ERR_INTERNAL);
2440 }
2441
2442 bigint->val = attr.pValue;
2443 bigint->len = attr.ulValueLen;
2444 }
2445 return (KMF_OK);
2446 }
2447
2448 static KMF_RETURN
get_raw_rsa(KMF_HANDLE * kmfh,CK_OBJECT_HANDLE obj,KMF_RAW_RSA_KEY * rawrsa)2449 get_raw_rsa(KMF_HANDLE *kmfh, CK_OBJECT_HANDLE obj, KMF_RAW_RSA_KEY *rawrsa)
2450 {
2451 KMF_RETURN rv = KMF_OK;
2452 CK_RV ckrv;
2453 CK_SESSION_HANDLE sess = kmfh->pk11handle;
2454 CK_ATTRIBUTE rsa_pri_attrs[2] = {
2455 { CKA_MODULUS, NULL, 0 },
2456 { CKA_PUBLIC_EXPONENT, NULL, 0 }
2457 };
2458 CK_ULONG count = sizeof (rsa_pri_attrs) / sizeof (CK_ATTRIBUTE);
2459 int i;
2460
2461 if (rawrsa == NULL)
2462 return (KMF_ERR_BAD_PARAMETER);
2463
2464 (void) memset(rawrsa, 0, sizeof (KMF_RAW_RSA_KEY));
2465 if ((ckrv = C_GetAttributeValue(sess, obj,
2466 rsa_pri_attrs, count)) != CKR_OK) {
2467 SET_ERROR(kmfh, ckrv);
2468 /* Tell the caller know why the key data cannot be retrieved. */
2469 if (ckrv == CKR_ATTRIBUTE_SENSITIVE)
2470 return (KMF_ERR_SENSITIVE_KEY);
2471 else if (ckrv == CKR_KEY_UNEXTRACTABLE)
2472 return (KMF_ERR_UNEXTRACTABLE_KEY);
2473 else
2474 return (KMF_ERR_INTERNAL);
2475 }
2476
2477 /* Allocate memory for each attribute. */
2478 for (i = 0; i < count; i++) {
2479 if (rsa_pri_attrs[i].ulValueLen == (CK_ULONG)-1 ||
2480 rsa_pri_attrs[i].ulValueLen == 0) {
2481 rsa_pri_attrs[i].ulValueLen = 0;
2482 continue;
2483 }
2484 if ((rsa_pri_attrs[i].pValue =
2485 malloc(rsa_pri_attrs[i].ulValueLen)) == NULL) {
2486 rv = KMF_ERR_MEMORY;
2487 goto end;
2488 }
2489 }
2490 /* Now that we have space, really get the attributes */
2491 if ((ckrv = C_GetAttributeValue(sess, obj,
2492 rsa_pri_attrs, count)) != CKR_OK) {
2493 SET_ERROR(kmfh, ckrv);
2494 rv = KMF_ERR_INTERNAL;
2495 goto end;
2496 }
2497 i = 0;
2498 attr2bigint(&(rsa_pri_attrs[i++]), &rawrsa->mod);
2499 attr2bigint(&(rsa_pri_attrs[i++]), &rawrsa->pubexp);
2500
2501 /* Now get the optional parameters */
2502 rv = get_bigint_attr(sess, obj, CKA_PRIVATE_EXPONENT, &rawrsa->priexp);
2503 if (rv != KMF_OK)
2504 goto end;
2505 rv = get_bigint_attr(sess, obj, CKA_PRIME_1, &rawrsa->prime1);
2506 if (rv != KMF_OK)
2507 goto end;
2508 rv = get_bigint_attr(sess, obj, CKA_PRIME_2, &rawrsa->prime2);
2509 if (rv != KMF_OK)
2510 goto end;
2511 rv = get_bigint_attr(sess, obj, CKA_EXPONENT_1, &rawrsa->exp1);
2512 if (rv != KMF_OK)
2513 goto end;
2514 rv = get_bigint_attr(sess, obj, CKA_EXPONENT_2, &rawrsa->exp2);
2515 if (rv != KMF_OK)
2516 goto end;
2517 rv = get_bigint_attr(sess, obj, CKA_COEFFICIENT, &rawrsa->coef);
2518 if (rv != KMF_OK)
2519 goto end;
2520
2521 end:
2522 if (rv != KMF_OK) {
2523 for (i = 0; i < count; i++) {
2524 if (rsa_pri_attrs[i].pValue != NULL)
2525 free(rsa_pri_attrs[i].pValue);
2526 }
2527 if (rawrsa->priexp.val)
2528 free(rawrsa->priexp.val);
2529 if (rawrsa->prime1.val)
2530 free(rawrsa->prime1.val);
2531 if (rawrsa->prime2.val)
2532 free(rawrsa->prime2.val);
2533 if (rawrsa->exp1.val)
2534 free(rawrsa->exp1.val);
2535 if (rawrsa->exp2.val)
2536 free(rawrsa->exp2.val);
2537 if (rawrsa->coef.val)
2538 free(rawrsa->coef.val);
2539 (void) memset(rawrsa, 0, sizeof (KMF_RAW_RSA_KEY));
2540 }
2541 return (rv);
2542 }
2543
2544 #define DSA_PRIME_BUFSIZE CHARLEN2BIGNUMLEN(1024) /* 8192 bits */
2545 #define DSA_PRIVATE_BUFSIZE BIG_CHUNKS_FOR_160BITS /* 160 bits */
2546
2547 /*
2548 * This function calculates the pubkey value from the prime,
2549 * base and private key values of a DSA key.
2550 */
2551 static KMF_RETURN
compute_dsa_pubvalue(KMF_RAW_DSA_KEY * rawdsa)2552 compute_dsa_pubvalue(KMF_RAW_DSA_KEY *rawdsa)
2553 {
2554 KMF_RETURN rv = KMF_OK;
2555 BIGNUM p, g, x, y;
2556 BIG_ERR_CODE err;
2557 uchar_t *pubvalue;
2558 uint32_t pubvalue_len;
2559
2560 if ((err = big_init1(&p, DSA_PRIME_BUFSIZE, NULL, 0)) != BIG_OK) {
2561 rv = KMF_ERR_MEMORY;
2562 return (rv);
2563 }
2564 bytestring2bignum(&p, rawdsa->prime.val, rawdsa->prime.len);
2565
2566 if ((err = big_init1(&g, DSA_PRIME_BUFSIZE, NULL, 0)) != BIG_OK) {
2567 rv = KMF_ERR_MEMORY;
2568 goto ret1;
2569 }
2570 bytestring2bignum(&g, rawdsa->base.val, rawdsa->base.len);
2571
2572 if ((err = big_init1(&x, DSA_PRIVATE_BUFSIZE, NULL, 0)) != BIG_OK) {
2573 rv = KMF_ERR_MEMORY;
2574 goto ret2;
2575 }
2576 bytestring2bignum(&x, rawdsa->value.val, rawdsa->value.len);
2577
2578 if ((err = big_init1(&y, DSA_PRIME_BUFSIZE, NULL, 0)) != BIG_OK) {
2579 rv = KMF_ERR_MEMORY;
2580 goto ret3;
2581 }
2582
2583 err = big_modexp(&y, &g, &x, &p, NULL);
2584 if (err != BIG_OK) {
2585 rv = KMF_ERR_INTERNAL;
2586 goto ret3;
2587 }
2588
2589 pubvalue_len = y.len * (int)sizeof (uint32_t);
2590 if ((pubvalue = malloc(pubvalue_len)) == NULL) {
2591 rv = KMF_ERR_MEMORY;
2592 goto ret4;
2593 }
2594 bignum2bytestring(pubvalue, &y, pubvalue_len);
2595
2596 rawdsa->pubvalue.val = pubvalue;
2597 rawdsa->pubvalue.len = pubvalue_len;
2598
2599 ret4:
2600 big_finish(&y);
2601 ret3:
2602 big_finish(&x);
2603 ret2:
2604 big_finish(&g);
2605 ret1:
2606 big_finish(&p);
2607 return (rv);
2608 }
2609
2610 static KMF_RETURN
get_raw_ec(KMF_HANDLE * kmfh,CK_OBJECT_HANDLE obj,KMF_RAW_EC_KEY * rawec)2611 get_raw_ec(KMF_HANDLE *kmfh, CK_OBJECT_HANDLE obj, KMF_RAW_EC_KEY *rawec)
2612 {
2613 KMF_RETURN rv = KMF_OK;
2614 CK_RV ckrv;
2615 CK_SESSION_HANDLE sess = kmfh->pk11handle;
2616 CK_ATTRIBUTE ec_attrs[2] = {
2617 { CKA_EC_PARAMS, NULL, 0},
2618 { CKA_VALUE, NULL, 0}
2619 };
2620 CK_ULONG count = sizeof (ec_attrs) / sizeof (CK_ATTRIBUTE);
2621 int i;
2622
2623 if ((ckrv = C_GetAttributeValue(sess, obj,
2624 ec_attrs, 2)) != CKR_OK) {
2625 SET_ERROR(kmfh, ckrv);
2626
2627 /* Tell the caller know why the key data cannot be retrieved. */
2628 if (ckrv == CKR_ATTRIBUTE_SENSITIVE)
2629 return (KMF_ERR_SENSITIVE_KEY);
2630 else if (ckrv == CKR_KEY_UNEXTRACTABLE)
2631 return (KMF_ERR_UNEXTRACTABLE_KEY);
2632 return (KMF_ERR_INTERNAL);
2633 }
2634 for (i = 0; i < count; i++) {
2635 if (ec_attrs[i].ulValueLen == (CK_ULONG)-1 ||
2636 ec_attrs[i].ulValueLen == 0) {
2637 ec_attrs[i].ulValueLen = 0;
2638 continue;
2639 }
2640 if ((ec_attrs[i].pValue =
2641 malloc(ec_attrs[i].ulValueLen)) == NULL) {
2642 rv = KMF_ERR_MEMORY;
2643 goto end;
2644 }
2645 }
2646 if ((ckrv = C_GetAttributeValue(sess, obj,
2647 ec_attrs, count)) != CKR_OK) {
2648 SET_ERROR(kmfh, ckrv);
2649 rv = KMF_ERR_INTERNAL;
2650 goto end;
2651 }
2652
2653 rawec->params.Data = ec_attrs[0].pValue;
2654 rawec->params.Length = ec_attrs[0].ulValueLen;
2655 rawec->value.val = ec_attrs[1].pValue;
2656 rawec->value.len = ec_attrs[1].ulValueLen;
2657
2658 end:
2659 if (rv != KMF_OK) {
2660 for (i = 0; i < count; i++) {
2661 if (ec_attrs[i].pValue != NULL)
2662 free(ec_attrs[i].pValue);
2663 }
2664 (void) memset(rawec, 0, sizeof (KMF_RAW_EC_KEY));
2665 }
2666 return (rv);
2667 }
2668
2669 static KMF_RETURN
get_raw_dsa(KMF_HANDLE * kmfh,CK_OBJECT_HANDLE obj,KMF_RAW_DSA_KEY * rawdsa)2670 get_raw_dsa(KMF_HANDLE *kmfh, CK_OBJECT_HANDLE obj, KMF_RAW_DSA_KEY *rawdsa)
2671 {
2672 KMF_RETURN rv = KMF_OK;
2673 CK_RV ckrv;
2674 CK_SESSION_HANDLE sess = kmfh->pk11handle;
2675 CK_ATTRIBUTE dsa_pri_attrs[8] = {
2676 { CKA_PRIME, NULL, 0 },
2677 { CKA_SUBPRIME, NULL, 0 },
2678 { CKA_BASE, NULL, 0 },
2679 { CKA_VALUE, NULL, 0 }
2680 };
2681 CK_ULONG count = sizeof (dsa_pri_attrs) / sizeof (CK_ATTRIBUTE);
2682 int i;
2683
2684 if ((ckrv = C_GetAttributeValue(sess, obj,
2685 dsa_pri_attrs, count)) != CKR_OK) {
2686 SET_ERROR(kmfh, ckrv);
2687
2688 /* Tell the caller know why the key data cannot be retrieved. */
2689 if (ckrv == CKR_ATTRIBUTE_SENSITIVE)
2690 return (KMF_ERR_SENSITIVE_KEY);
2691 else if (ckrv == CKR_KEY_UNEXTRACTABLE)
2692 return (KMF_ERR_UNEXTRACTABLE_KEY);
2693 return (KMF_ERR_INTERNAL);
2694 }
2695
2696 /* Allocate memory for each attribute. */
2697 for (i = 0; i < count; i++) {
2698 if (dsa_pri_attrs[i].ulValueLen == (CK_ULONG)-1 ||
2699 dsa_pri_attrs[i].ulValueLen == 0) {
2700 dsa_pri_attrs[i].ulValueLen = 0;
2701 continue;
2702 }
2703 if ((dsa_pri_attrs[i].pValue =
2704 malloc(dsa_pri_attrs[i].ulValueLen)) == NULL) {
2705 rv = KMF_ERR_MEMORY;
2706 goto end;
2707 }
2708 }
2709 if ((ckrv = C_GetAttributeValue(sess, obj,
2710 dsa_pri_attrs, count)) != CKR_OK) {
2711 SET_ERROR(kmfh, ckrv);
2712 rv = KMF_ERR_INTERNAL;
2713 goto end;
2714 }
2715
2716 /* Fill in all the temp variables. They are all required. */
2717 i = 0;
2718 attr2bigint(&(dsa_pri_attrs[i++]), &rawdsa->prime);
2719 attr2bigint(&(dsa_pri_attrs[i++]), &rawdsa->subprime);
2720 attr2bigint(&(dsa_pri_attrs[i++]), &rawdsa->base);
2721 attr2bigint(&(dsa_pri_attrs[i++]), &rawdsa->value);
2722
2723 /* Compute the public key value and store it */
2724 rv = compute_dsa_pubvalue(rawdsa);
2725
2726 end:
2727 if (rv != KMF_OK) {
2728 for (i = 0; i < count; i++) {
2729 if (dsa_pri_attrs[i].pValue != NULL)
2730 free(dsa_pri_attrs[i].pValue);
2731 }
2732 (void) memset(rawdsa, 0, sizeof (KMF_RAW_DSA_KEY));
2733 }
2734 return (rv);
2735 }
2736
2737 static KMF_RETURN
get_raw_sym(KMF_HANDLE * kmfh,CK_OBJECT_HANDLE obj,KMF_RAW_SYM_KEY * rawsym)2738 get_raw_sym(KMF_HANDLE *kmfh, CK_OBJECT_HANDLE obj, KMF_RAW_SYM_KEY *rawsym)
2739 {
2740 KMF_RETURN rv = KMF_OK;
2741 CK_RV ckrv;
2742 CK_SESSION_HANDLE sess = kmfh->pk11handle;
2743 CK_ATTRIBUTE sym_attr[1];
2744 CK_ULONG value_len = 0;
2745
2746 /* find the key length first */
2747 sym_attr[0].type = CKA_VALUE;
2748 sym_attr[0].pValue = NULL;
2749 sym_attr[0].ulValueLen = value_len;
2750 if ((ckrv = C_GetAttributeValue(sess, obj, sym_attr, 1)) != CKR_OK) {
2751 rawsym->keydata.val = NULL;
2752 rawsym->keydata.len = 0;
2753 if (ckrv == CKR_ATTRIBUTE_SENSITIVE) {
2754 return (KMF_ERR_SENSITIVE_KEY);
2755 } else if (ckrv == CKR_KEY_UNEXTRACTABLE) {
2756 return (KMF_ERR_UNEXTRACTABLE_KEY);
2757 } else {
2758 SET_ERROR(kmfh, ckrv);
2759 return (KMF_ERR_INTERNAL);
2760 }
2761 }
2762
2763 /* Allocate memory for pValue */
2764 sym_attr[0].pValue = malloc(sym_attr[0].ulValueLen);
2765 if (sym_attr[0].pValue == NULL) {
2766 return (KMF_ERR_MEMORY);
2767 }
2768
2769 /* get the key data */
2770 if ((ckrv = C_GetAttributeValue(sess, obj, sym_attr, 1)) != CKR_OK) {
2771 SET_ERROR(kmfh, ckrv);
2772 free(sym_attr[0].pValue);
2773 return (KMF_ERR_INTERNAL);
2774 }
2775
2776 rawsym->keydata.val = sym_attr[0].pValue;
2777 rawsym->keydata.len = sym_attr[0].ulValueLen;
2778 return (rv);
2779 }
2780
2781 static KMF_RETURN
keyObj2RawKey(KMF_HANDLE_T handle,KMF_KEY_HANDLE * inkey,KMF_RAW_KEY_DATA ** outkey)2782 keyObj2RawKey(KMF_HANDLE_T handle, KMF_KEY_HANDLE *inkey,
2783 KMF_RAW_KEY_DATA **outkey)
2784 {
2785 KMF_RETURN rv = KMF_OK;
2786 KMF_RAW_KEY_DATA *rkey;
2787 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
2788
2789 rkey = malloc(sizeof (KMF_RAW_KEY_DATA));
2790 if (rkey == NULL)
2791 return (KMF_ERR_MEMORY);
2792
2793 (void) memset(rkey, 0, sizeof (KMF_RAW_KEY_DATA));
2794
2795 rkey->keytype = inkey->keyalg;
2796
2797 if (inkey->keyalg == KMF_RSA) {
2798 rv = get_raw_rsa(kmfh, (CK_OBJECT_HANDLE)inkey->keyp,
2799 &rkey->rawdata.rsa);
2800 } else if (inkey->keyalg == KMF_DSA) {
2801 rv = get_raw_dsa(kmfh, (CK_OBJECT_HANDLE)inkey->keyp,
2802 &rkey->rawdata.dsa);
2803 } else if (inkey->keyalg == KMF_AES ||
2804 inkey->keyalg == KMF_RC4 ||
2805 inkey->keyalg == KMF_DES ||
2806 inkey->keyalg == KMF_DES3 ||
2807 inkey->keyalg == KMF_GENERIC_SECRET) {
2808 rv = get_raw_sym(kmfh, (CK_OBJECT_HANDLE)inkey->keyp,
2809 &rkey->rawdata.sym);
2810 /*
2811 * If sensitive or non-extractable, mark them as such
2812 * but return "OK" status so the keys get counted
2813 * when doing FindKey operations.
2814 */
2815 if (rv == KMF_ERR_SENSITIVE_KEY) {
2816 rkey->sensitive = B_TRUE;
2817 rv = KMF_OK;
2818 } else if (rv == KMF_ERR_UNEXTRACTABLE_KEY) {
2819 rkey->not_extractable = B_TRUE;
2820 rv = KMF_OK;
2821 }
2822 } else if (inkey->keyalg == KMF_ECDSA) {
2823 rv = get_raw_ec(kmfh, (CK_OBJECT_HANDLE)inkey->keyp,
2824 &rkey->rawdata.ec);
2825 } else {
2826 rv = KMF_ERR_BAD_PARAMETER;
2827 }
2828
2829 if (rv == KMF_OK) {
2830 *outkey = rkey;
2831 } else if (rkey != NULL) {
2832 free(rkey);
2833 *outkey = NULL;
2834 }
2835
2836 return (rv);
2837 }
2838
2839
2840 static KMF_RETURN
kmf2pk11keytype(KMF_KEY_ALG keyalg,CK_KEY_TYPE * type)2841 kmf2pk11keytype(KMF_KEY_ALG keyalg, CK_KEY_TYPE *type)
2842 {
2843 switch (keyalg) {
2844 case KMF_RSA:
2845 *type = CKK_RSA;
2846 break;
2847 case KMF_DSA:
2848 *type = CKK_DSA;
2849 break;
2850 case KMF_ECDSA:
2851 *type = CKK_EC;
2852 break;
2853 case KMF_AES:
2854 *type = CKK_AES;
2855 break;
2856 case KMF_RC4:
2857 *type = CKK_RC4;
2858 break;
2859 case KMF_DES:
2860 *type = CKK_DES;
2861 break;
2862 case KMF_DES3:
2863 *type = CKK_DES3;
2864 break;
2865 case KMF_GENERIC_SECRET:
2866 *type = CKK_GENERIC_SECRET;
2867 break;
2868 default:
2869 return (KMF_ERR_BAD_KEY_TYPE);
2870 }
2871
2872 return (KMF_OK);
2873 }
2874
2875 static int
IDStringToData(char * idstr,KMF_DATA * iddata)2876 IDStringToData(char *idstr, KMF_DATA *iddata)
2877 {
2878 int len, i;
2879 char *iddup, *byte;
2880 uint_t lvalue;
2881
2882 if (idstr == NULL || !strlen(idstr))
2883 return (-1);
2884
2885 iddup = (char *)strdup(idstr);
2886 if (iddup == NULL)
2887 return (KMF_ERR_MEMORY);
2888
2889 len = strlen(iddup) / 3 + 1;
2890 iddata->Data = malloc(len);
2891 if (iddata->Data == NULL)
2892 return (KMF_ERR_MEMORY);
2893 (void) memset(iddata->Data, 0, len);
2894 iddata->Length = len;
2895
2896 byte = strtok(iddup, ":");
2897 if (byte == NULL) {
2898 free(iddup);
2899 free(iddata->Data);
2900 iddata->Data = NULL;
2901 iddata->Length = 0;
2902 return (-1);
2903 }
2904
2905 i = 0;
2906 do {
2907 (void) sscanf(byte, "%x", &lvalue);
2908 iddata->Data[i++] = (uchar_t)(lvalue & 0x000000FF);
2909 byte = strtok(NULL, ":");
2910 } while (byte != NULL && i < len);
2911
2912 iddata->Length = i;
2913 free(iddup);
2914 return (0);
2915 }
2916
2917 KMF_RETURN
KMFPK11_FindKey(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)2918 KMFPK11_FindKey(KMF_HANDLE_T handle,
2919 int numattr, KMF_ATTRIBUTE *attrlist)
2920 {
2921 KMF_RETURN rv = KMF_OK;
2922 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
2923 uint32_t want_keys, i;
2924 CK_RV ckrv;
2925 CK_ATTRIBUTE pTmpl[10];
2926 CK_OBJECT_CLASS class;
2927 CK_BBOOL true = TRUE;
2928 CK_ULONG alg;
2929 boolean_t is_token = B_TRUE, is_private = B_FALSE;
2930 KMF_KEY_HANDLE *keys;
2931 uint32_t *numkeys;
2932 KMF_CREDENTIAL *cred = NULL;
2933 KMF_KEY_CLASS keyclass = KMF_KEYCLASS_NONE;
2934 char *findLabel, *idstr;
2935 KMF_KEY_ALG keytype = KMF_KEYALG_NONE;
2936 KMF_ENCODE_FORMAT format;
2937
2938 if (kmfh == NULL)
2939 return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */
2940
2941 if (kmfh->pk11handle == CK_INVALID_HANDLE)
2942 return (KMF_ERR_NO_TOKEN_SELECTED);
2943
2944 numkeys = kmf_get_attr_ptr(KMF_COUNT_ATTR, attrlist, numattr);
2945 if (numkeys == NULL)
2946 return (KMF_ERR_BAD_PARAMETER);
2947
2948 if (*numkeys > 0)
2949 want_keys = *numkeys;
2950 else
2951 want_keys = MAXINT; /* count them all */
2952
2953 /* keyclass is optional */
2954 (void) kmf_get_attr(KMF_KEYCLASS_ATTR, attrlist, numattr,
2955 (void *)&keyclass, NULL);
2956
2957 if (keyclass == KMF_ASYM_PUB) {
2958 class = CKO_PUBLIC_KEY;
2959 } else if (keyclass == KMF_ASYM_PRI) {
2960 class = CKO_PRIVATE_KEY;
2961 } else if (keyclass == KMF_SYMMETRIC) {
2962 class = CKO_SECRET_KEY;
2963 }
2964
2965 rv = kmf_get_attr(KMF_TOKEN_BOOL_ATTR, attrlist, numattr,
2966 (void *)&is_token, NULL);
2967 if (rv != KMF_OK)
2968 return (rv);
2969
2970 i = 0;
2971 if (is_token) {
2972 SETATTR(pTmpl, i, CKA_TOKEN, &true, sizeof (true));
2973 i++;
2974 }
2975
2976 if (keyclass != KMF_KEYCLASS_NONE) {
2977 SETATTR(pTmpl, i, CKA_CLASS, &class, sizeof (class));
2978 i++;
2979 }
2980
2981 findLabel = kmf_get_attr_ptr(KMF_KEYLABEL_ATTR, attrlist, numattr);
2982
2983 if (findLabel != NULL && strlen(findLabel)) {
2984 SETATTR(pTmpl, i, CKA_LABEL, findLabel, strlen(findLabel));
2985 i++;
2986 }
2987 /* keytype is optional */
2988 (void) kmf_get_attr(KMF_KEYALG_ATTR, attrlist, numattr,
2989 (void *)&keytype, NULL);
2990
2991 if (keytype != 0) {
2992 rv = kmf2pk11keytype(keytype, &alg);
2993 if (rv != KMF_OK) {
2994 return (KMF_ERR_BAD_KEY_TYPE);
2995 }
2996 SETATTR(pTmpl, i, CKA_KEY_TYPE, &alg, sizeof (alg));
2997 i++;
2998 }
2999
3000 idstr = kmf_get_attr_ptr(KMF_IDSTR_ATTR, attrlist, numattr);
3001
3002 if (idstr != NULL) {
3003 KMF_DATA iddata = { 0, NULL };
3004
3005 /*
3006 * ID String parameter is assumed to be of form:
3007 * XX:XX:XX:XX:XX ... :XX
3008 * where XX is a hex number.
3009 *
3010 * We must convert this back to binary in order to
3011 * use it in a search.
3012 */
3013 rv = IDStringToData(idstr, &iddata);
3014 if (rv == KMF_OK) {
3015 SETATTR(pTmpl, i, CKA_ID, iddata.Data, iddata.Length);
3016 i++;
3017 } else {
3018 return (rv);
3019 }
3020 }
3021
3022 /* is_private is optional */
3023 (void) kmf_get_attr(KMF_PRIVATE_BOOL_ATTR, attrlist, numattr,
3024 (void *)&is_private, NULL);
3025
3026 if (is_private) {
3027 SETATTR(pTmpl, i, CKA_PRIVATE, &true, sizeof (true));
3028 i++;
3029 }
3030
3031 /*
3032 * Authenticate if the object is a token object,
3033 * a private or secred key, or if the user passed in credentials.
3034 */
3035 cred = kmf_get_attr_ptr(KMF_CREDENTIAL_ATTR, attrlist, numattr);
3036 if (cred != NULL) {
3037 rv = pk11_authenticate(handle, cred);
3038 if (rv != KMF_OK)
3039 return (rv);
3040 }
3041
3042 keys = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr);
3043 /* it is okay to have "keys" contains NULL */
3044
3045 ckrv = C_FindObjectsInit(kmfh->pk11handle, pTmpl, i);
3046 if (ckrv == CKR_OK) {
3047 CK_ULONG obj_count, n = 0;
3048 while (ckrv == CKR_OK && n < want_keys) {
3049 CK_OBJECT_HANDLE hObj;
3050
3051 ckrv = C_FindObjects(kmfh->pk11handle, &hObj,
3052 1, &obj_count);
3053 if (ckrv == CKR_OK && obj_count == 1) {
3054 if (keys != NULL) {
3055 CK_ULONG keytype;
3056 keys[n].kstype = KMF_KEYSTORE_PK11TOKEN;
3057 keys[n].israw = FALSE;
3058 keys[n].keyp = (void *)hObj;
3059
3060 ckrv = getObjectKeytype(handle,
3061 (CK_OBJECT_HANDLE)keys[n].keyp,
3062 &keytype);
3063 if (ckrv != CKR_OK)
3064 goto end;
3065
3066 ckrv = getObjectLabel(handle,
3067 (CK_OBJECT_HANDLE)keys[n].keyp,
3068 &(keys[n].keylabel));
3069 if (ckrv != CKR_OK)
3070 goto end;
3071
3072 if (keyclass == KMF_KEYCLASS_NONE) {
3073 ckrv = getObjectKeyclass(handle,
3074 (CK_OBJECT_HANDLE)
3075 keys[n].keyp,
3076 &(keys[n].keyclass));
3077 if (ckrv != CKR_OK)
3078 goto end;
3079 } else {
3080 keys[n].keyclass = keyclass;
3081 }
3082 if (keytype == CKK_RSA) {
3083 keys[n].keyalg = KMF_RSA;
3084 } else if (keytype == CKK_DSA) {
3085 keys[n].keyalg = KMF_DSA;
3086 } else if (keytype == CKK_EC) {
3087 keys[n].keyalg = KMF_ECDSA;
3088 } else if (keytype == CKK_AES) {
3089 keys[n].keyalg = KMF_AES;
3090 keys[n].keyclass =
3091 KMF_SYMMETRIC;
3092 } else if (keytype == CKK_RC4) {
3093 keys[n].keyalg = KMF_RC4;
3094 keys[n].keyclass =
3095 KMF_SYMMETRIC;
3096 } else if (keytype == CKK_DES) {
3097 keys[n].keyalg = KMF_DES;
3098 keys[n].keyclass =
3099 KMF_SYMMETRIC;
3100 } else if (keytype == CKK_DES3) {
3101 keys[n].keyalg = KMF_DES3;
3102 keys[n].keyclass =
3103 KMF_SYMMETRIC;
3104 } else if (keytype ==
3105 CKK_GENERIC_SECRET) {
3106 keys[n].keyalg =
3107 KMF_GENERIC_SECRET;
3108 keys[n].keyclass =
3109 KMF_SYMMETRIC;
3110 }
3111
3112 }
3113 n++;
3114 } else {
3115 break;
3116 }
3117 }
3118 ckrv = C_FindObjectsFinal(kmfh->pk11handle);
3119
3120 /* "numkeys" indicates the number that were actually found */
3121 *numkeys = n;
3122 }
3123
3124 if (ckrv == KMF_OK && keys != NULL && (*numkeys) > 0) {
3125 if ((rv = kmf_get_attr(KMF_ENCODE_FORMAT_ATTR, attrlist,
3126 numattr, (void *)&format, NULL)) == KMF_OK) {
3127 if (format == KMF_FORMAT_RAWKEY ||
3128 format == KMF_FORMAT_PEM) {
3129 /* Convert keys to "rawkey" format */
3130 for (i = 0; i < (*numkeys); i++) {
3131 KMF_RAW_KEY_DATA *rkey = NULL;
3132 rv = keyObj2RawKey(handle, &keys[i],
3133 &rkey);
3134 if (rv == KMF_OK) {
3135 keys[i].keyp = rkey;
3136 keys[i].israw = TRUE;
3137 } else {
3138 break;
3139 }
3140 }
3141 }
3142 } else {
3143 rv = KMF_OK; /* format is optional */
3144 }
3145 }
3146
3147 end:
3148 if (ckrv != CKR_OK) {
3149 SET_ERROR(kmfh, ckrv);
3150 /* Report authentication failures to the caller */
3151 if (ckrv == CKR_USER_NOT_LOGGED_IN ||
3152 ckrv == CKR_PIN_INCORRECT ||
3153 ckrv == CKR_PIN_INVALID ||
3154 ckrv == CKR_PIN_EXPIRED ||
3155 ckrv == CKR_PIN_LOCKED ||
3156 ckrv == CKR_SESSION_READ_ONLY)
3157 rv = KMF_ERR_AUTH_FAILED;
3158 else
3159 rv = KMF_ERR_INTERNAL;
3160 } else if ((*numkeys) == 0) {
3161 rv = KMF_ERR_KEY_NOT_FOUND;
3162 }
3163
3164 return (rv);
3165 }
3166
3167 static char *
convertDate(char * fulldate)3168 convertDate(char *fulldate)
3169 {
3170 struct tm tms;
3171 char newtime[9];
3172
3173 (void) strptime(fulldate, "%b %d %T %Y %Z", &tms);
3174
3175 if (tms.tm_year < 69)
3176 tms.tm_year += 100;
3177
3178 (void) strftime(newtime, sizeof (newtime), "m%d", &tms);
3179
3180 newtime[8] = 0;
3181
3182 /* memory returned must be freed by the caller */
3183 return ((char *)strdup(newtime));
3184 }
3185
3186 static KMF_RETURN
store_raw_key(KMF_HANDLE_T handle,KMF_ATTRIBUTE * attrlist,int numattr,KMF_RAW_KEY_DATA * rawkey)3187 store_raw_key(KMF_HANDLE_T handle,
3188 KMF_ATTRIBUTE *attrlist, int numattr,
3189 KMF_RAW_KEY_DATA *rawkey)
3190 {
3191 KMF_RETURN rv = KMF_OK;
3192 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
3193 int i;
3194 CK_RV ckrv = CKR_OK;
3195 CK_ATTRIBUTE templ[32];
3196 CK_OBJECT_HANDLE keyobj;
3197 CK_KEY_TYPE keytype;
3198 CK_OBJECT_CLASS oClass = CKO_PRIVATE_KEY;
3199 CK_BBOOL cktrue = TRUE;
3200 CK_DATE startdate, enddate;
3201 KMF_DATA id = { 0, NULL };
3202 KMF_DATA subject = { 0, NULL };
3203 KMF_X509EXT_KEY_USAGE kuext;
3204 KMF_X509_CERTIFICATE *x509 = NULL;
3205 CK_BBOOL kufound = B_FALSE;
3206 KMF_DATA *cert = NULL;
3207 char *notbefore = NULL, *start = NULL;
3208 char *notafter = NULL, *end = NULL;
3209 char *keylabel = NULL;
3210 KMF_CREDENTIAL *cred = NULL;
3211
3212 if (kmfh == NULL)
3213 return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */
3214
3215 if (kmfh->pk11handle == CK_INVALID_HANDLE)
3216 return (KMF_ERR_NO_TOKEN_SELECTED);
3217
3218 if (rawkey->keytype == KMF_RSA)
3219 keytype = CKK_RSA;
3220 else if (rawkey->keytype == KMF_DSA)
3221 keytype = CKK_DSA;
3222 else if (rawkey->keytype == KMF_ECDSA)
3223 keytype = CKK_EC;
3224 else
3225 return (KMF_ERR_BAD_PARAMETER);
3226
3227 cred = kmf_get_attr_ptr(KMF_CREDENTIAL_ATTR, attrlist, numattr);
3228 if (cred != NULL) {
3229 rv = pk11_authenticate(handle, cred);
3230 if (rv != KMF_OK)
3231 return (rv);
3232 }
3233
3234 keylabel = kmf_get_attr_ptr(KMF_KEYLABEL_ATTR, attrlist, numattr);
3235 /*
3236 * If the caller did not specify a label, see if the raw key
3237 * came with one (possible if it came from a PKCS#12 file).
3238 */
3239 if (keylabel == NULL) {
3240 keylabel = rawkey->label;
3241 }
3242
3243 i = 0;
3244 SETATTR(templ, i, CKA_CLASS, &oClass, sizeof (CK_OBJECT_CLASS)); i++;
3245 SETATTR(templ, i, CKA_KEY_TYPE, &keytype, sizeof (keytype)); i++;
3246 SETATTR(templ, i, CKA_TOKEN, &cktrue, sizeof (cktrue)); i++;
3247 SETATTR(templ, i, CKA_PRIVATE, &cktrue, sizeof (cktrue)); i++;
3248 if (keytype != CKK_EC)
3249 SETATTR(templ, i, CKA_DECRYPT, &cktrue, sizeof (cktrue)); i++;
3250
3251 cert = kmf_get_attr_ptr(KMF_CERT_DATA_ATTR, attrlist, numattr);
3252 if (cert != NULL) {
3253 id.Data = NULL;
3254 id.Length = 0;
3255 rv = kmf_get_cert_id_data(cert, &id);
3256 if (rv != KMF_OK) {
3257 goto cleanup;
3258 }
3259
3260 rv = DerDecodeSignedCertificate((const KMF_DATA *)cert, &x509);
3261 if (rv != KMF_OK) {
3262 goto cleanup;
3263 }
3264
3265 rv = DerEncodeName(&x509->certificate.subject, &subject);
3266 if (rv != KMF_OK) {
3267 goto cleanup;
3268 }
3269 SETATTR(templ, i, CKA_SUBJECT, subject.Data, subject.Length);
3270 i++;
3271
3272 rv = kmf_get_cert_start_date_str(handle, cert, ¬before);
3273 if (rv != KMF_OK) {
3274 goto cleanup;
3275 }
3276 start = convertDate(notbefore);
3277 free(notbefore);
3278
3279 rv = kmf_get_cert_end_date_str(handle, cert, ¬after);
3280 if (rv != KMF_OK) {
3281 goto cleanup;
3282 }
3283 end = convertDate(notafter);
3284 free(notafter);
3285 if (id.Data != NULL && id.Data != NULL && id.Length > 0) {
3286 SETATTR(templ, i, CKA_ID, id.Data, id.Length);
3287 i++;
3288 }
3289 if (start != NULL) {
3290 /*
3291 * This makes some potentially dangerous assumptions:
3292 * 1. that the startdate in the parameter block is
3293 * properly formatted as YYYYMMDD
3294 * 2. That the CK_DATE structure is always the same.
3295 */
3296 (void) memcpy(&startdate, start, sizeof (CK_DATE));
3297 SETATTR(templ, i, CKA_START_DATE, &startdate,
3298 sizeof (startdate));
3299 i++;
3300 }
3301 if (end != NULL) {
3302 (void) memcpy(&enddate, end, sizeof (CK_DATE));
3303 SETATTR(templ, i, CKA_END_DATE, &enddate,
3304 sizeof (enddate));
3305 i++;
3306 }
3307
3308 if ((rv = kmf_get_cert_ku(cert, &kuext)) != KMF_OK &&
3309 rv != KMF_ERR_EXTENSION_NOT_FOUND)
3310 goto cleanup;
3311
3312 kufound = (rv == KMF_OK);
3313 rv = KMF_OK; /* reset if we got KMF_ERR_EXTENSION_NOT_FOUND */
3314 }
3315
3316 /*
3317 * Only set the KeyUsage stuff if the KU extension was present.
3318 */
3319 if (kufound) {
3320 CK_BBOOL condition;
3321
3322 condition = (kuext.KeyUsageBits & KMF_keyEncipherment) ?
3323 B_TRUE : B_FALSE;
3324 SETATTR(templ, i, CKA_UNWRAP, &condition, sizeof (CK_BBOOL));
3325 i++;
3326 condition = (kuext.KeyUsageBits & KMF_dataEncipherment) ?
3327 B_TRUE : B_FALSE;
3328 SETATTR(templ, i, CKA_DECRYPT, &condition, sizeof (CK_BBOOL));
3329 i++;
3330 condition = (kuext.KeyUsageBits & KMF_digitalSignature) ?
3331 B_TRUE : B_FALSE;
3332 SETATTR(templ, i, CKA_SIGN, &condition, sizeof (CK_BBOOL));
3333 i++;
3334 condition = (kuext.KeyUsageBits & KMF_digitalSignature) ?
3335 B_TRUE : B_FALSE;
3336 SETATTR(templ, i, CKA_SIGN_RECOVER, &condition,
3337 sizeof (CK_BBOOL));
3338 i++;
3339
3340 }
3341
3342 if (keylabel != NULL) {
3343 SETATTR(templ, i, CKA_LABEL, keylabel, strlen(keylabel));
3344 i++;
3345 }
3346 if (id.Data == NULL && rawkey->id.Data != NULL) {
3347 SETATTR(templ, i, CKA_ID, rawkey->id.Data,
3348 rawkey->id.Length);
3349 i++;
3350 }
3351 if (keytype == CKK_RSA) {
3352 SETATTR(templ, i, CKA_MODULUS,
3353 rawkey->rawdata.rsa.mod.val,
3354 rawkey->rawdata.rsa.mod.len);
3355 i++;
3356 SETATTR(templ, i, CKA_PUBLIC_EXPONENT,
3357 rawkey->rawdata.rsa.pubexp.val,
3358 rawkey->rawdata.rsa.pubexp.len);
3359 i++;
3360 if (rawkey->rawdata.rsa.priexp.val != NULL) {
3361 SETATTR(templ, i, CKA_PRIVATE_EXPONENT,
3362 rawkey->rawdata.rsa.priexp.val,
3363 rawkey->rawdata.rsa.priexp.len);
3364 i++;
3365 }
3366 if (rawkey->rawdata.rsa.prime1.val != NULL) {
3367 SETATTR(templ, i, CKA_PRIME_1,
3368 rawkey->rawdata.rsa.prime1.val,
3369 rawkey->rawdata.rsa.prime1.len);
3370 i++;
3371 }
3372 if (rawkey->rawdata.rsa.prime2.val != NULL) {
3373 SETATTR(templ, i, CKA_PRIME_2,
3374 rawkey->rawdata.rsa.prime2.val,
3375 rawkey->rawdata.rsa.prime2.len);
3376 i++;
3377 }
3378 if (rawkey->rawdata.rsa.exp1.val != NULL) {
3379 SETATTR(templ, i, CKA_EXPONENT_1,
3380 rawkey->rawdata.rsa.exp1.val,
3381 rawkey->rawdata.rsa.exp1.len);
3382 i++;
3383 }
3384 if (rawkey->rawdata.rsa.exp2.val != NULL) {
3385 SETATTR(templ, i, CKA_EXPONENT_2,
3386 rawkey->rawdata.rsa.exp2.val,
3387 rawkey->rawdata.rsa.exp2.len);
3388 i++;
3389 }
3390 if (rawkey->rawdata.rsa.coef.val != NULL) {
3391 SETATTR(templ, i, CKA_COEFFICIENT,
3392 rawkey->rawdata.rsa.coef.val,
3393 rawkey->rawdata.rsa.coef.len);
3394 i++;
3395 }
3396 } else if (keytype == CKK_DSA) {
3397 SETATTR(templ, i, CKA_PRIME,
3398 rawkey->rawdata.dsa.prime.val,
3399 rawkey->rawdata.dsa.prime.len);
3400 i++;
3401 SETATTR(templ, i, CKA_SUBPRIME,
3402 rawkey->rawdata.dsa.subprime.val,
3403 rawkey->rawdata.dsa.subprime.len);
3404 i++;
3405 SETATTR(templ, i, CKA_BASE,
3406 rawkey->rawdata.dsa.base.val,
3407 rawkey->rawdata.dsa.base.len);
3408 i++;
3409 SETATTR(templ, i, CKA_VALUE,
3410 rawkey->rawdata.dsa.value.val,
3411 rawkey->rawdata.dsa.value.len);
3412 i++;
3413 } else if (keytype == CKK_EC) {
3414 SETATTR(templ, i, CKA_SIGN, &cktrue, sizeof (cktrue));
3415 i++;
3416 SETATTR(templ, i, CKA_DERIVE, &cktrue, sizeof (cktrue));
3417 i++;
3418 SETATTR(templ, i, CKA_VALUE,
3419 rawkey->rawdata.ec.value.val,
3420 rawkey->rawdata.ec.value.len);
3421 i++;
3422 SETATTR(templ, i, CKA_EC_PARAMS,
3423 rawkey->rawdata.ec.params.Data,
3424 rawkey->rawdata.ec.params.Length);
3425 i++;
3426 }
3427
3428 ckrv = C_CreateObject(kmfh->pk11handle, templ, i, &keyobj);
3429 if (ckrv != CKR_OK) {
3430 SET_ERROR(kmfh, ckrv);
3431
3432 /* Report authentication failures to the caller */
3433 if (ckrv == CKR_USER_NOT_LOGGED_IN ||
3434 ckrv == CKR_PIN_INCORRECT ||
3435 ckrv == CKR_PIN_INVALID ||
3436 ckrv == CKR_PIN_EXPIRED ||
3437 ckrv == CKR_PIN_LOCKED ||
3438 ckrv == CKR_SESSION_READ_ONLY)
3439 rv = KMF_ERR_AUTH_FAILED;
3440 else
3441 rv = KMF_ERR_INTERNAL;
3442 }
3443 cleanup:
3444 if (start != NULL)
3445 free(start);
3446 if (end != NULL)
3447 free(end);
3448 kmf_free_data(&id);
3449 kmf_free_data(&subject);
3450 kmf_free_signed_cert(x509);
3451 free(x509);
3452
3453 return (rv);
3454 }
3455
3456 KMF_RETURN
KMFPK11_CreateSymKey(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)3457 KMFPK11_CreateSymKey(KMF_HANDLE_T handle,
3458 int numattr, KMF_ATTRIBUTE *attrlist)
3459 {
3460 KMF_RETURN rv = KMF_OK;
3461 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
3462 CK_RV ckrv;
3463 CK_SESSION_HANDLE hSession = kmfh->pk11handle;
3464 CK_OBJECT_HANDLE keyhandle;
3465 CK_MECHANISM keyGenMech;
3466 CK_OBJECT_CLASS class = CKO_SECRET_KEY;
3467 CK_ULONG secKeyType;
3468 CK_ULONG secKeyLen; /* for RC4 and AES */
3469 CK_BBOOL true = TRUE;
3470 CK_BBOOL false = FALSE;
3471 CK_ATTRIBUTE templ[15];
3472 CK_BYTE *keydata = NULL;
3473 int i = 0;
3474 KMF_KEY_HANDLE *symkey;
3475 KMF_KEY_ALG keytype;
3476 uint32_t keylen = 0;
3477 uint32_t attrkeylen = 0;
3478 uint32_t keylen_size = sizeof (uint32_t);
3479 char *keylabel = NULL;
3480 KMF_CREDENTIAL *cred = NULL;
3481 uint32_t is_sensitive = B_FALSE;
3482 uint32_t is_not_extractable = B_FALSE;
3483
3484 if (kmfh == NULL)
3485 return (KMF_ERR_UNINITIALIZED);
3486
3487 if (kmfh->pk11handle == CK_INVALID_HANDLE)
3488 return (KMF_ERR_NO_TOKEN_SELECTED);
3489
3490 symkey = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr);
3491 if (symkey == NULL)
3492 return (KMF_ERR_BAD_PARAMETER);
3493
3494 rv = kmf_get_attr(KMF_KEYALG_ATTR, attrlist, numattr,
3495 (void *)&keytype, NULL);
3496 if (rv != KMF_OK)
3497 return (KMF_ERR_BAD_PARAMETER);
3498
3499 keylabel = kmf_get_attr_ptr(KMF_KEYLABEL_ATTR, attrlist, numattr);
3500 if (keylabel == NULL)
3501 return (KMF_ERR_BAD_PARAMETER);
3502
3503 rv = kmf_get_attr(KMF_SENSITIVE_BOOL_ATTR, attrlist, numattr,
3504 (void *)&is_sensitive, NULL);
3505 if (rv != KMF_OK)
3506 return (KMF_ERR_BAD_PARAMETER);
3507
3508 rv = kmf_get_attr(KMF_NON_EXTRACTABLE_BOOL_ATTR, attrlist, numattr,
3509 (void *)&is_not_extractable, NULL);
3510 if (rv != KMF_OK)
3511 return (KMF_ERR_BAD_PARAMETER);
3512
3513 /*
3514 * For AES, RC4, DES and 3DES, call C_GenerateKey() to create a key.
3515 *
3516 * For a generic secret key, because it may not be supported in
3517 * C_GenerateKey() for some PKCS11 providers, we will handle it
3518 * differently.
3519 */
3520 if (keytype == KMF_GENERIC_SECRET) {
3521 rv = create_generic_secret_key(handle, numattr,
3522 attrlist, &keyhandle);
3523 if (rv != KMF_OK)
3524 goto out;
3525 else
3526 goto setup;
3527 }
3528
3529 rv = kmf_get_attr(KMF_KEY_DATA_ATTR, attrlist, numattr,
3530 NULL, &attrkeylen);
3531 if (rv == KMF_OK && attrkeylen > 0) {
3532 keydata = kmf_get_attr_ptr(KMF_KEY_DATA_ATTR, attrlist,
3533 numattr);
3534 } else {
3535 keydata = NULL;
3536 attrkeylen = 0;
3537 rv = KMF_OK;
3538 }
3539 if (keydata != NULL) {
3540 if (keytype == KMF_DES && attrkeylen != 8) {
3541 rv = KMF_ERR_BAD_KEY_SIZE;
3542 goto out;
3543 }
3544 if (keytype == KMF_DES3 && attrkeylen != 24) {
3545 rv = KMF_ERR_BAD_KEY_SIZE;
3546 goto out;
3547 }
3548 /*
3549 * This may override what the user gave on the
3550 * command line.
3551 */
3552 keylen = attrkeylen * 8; /* bytes to bits */
3553 } else {
3554 /*
3555 * If keydata was not given, key length must be
3556 * provided.
3557 */
3558 rv = kmf_get_attr(KMF_KEYLENGTH_ATTR, attrlist, numattr,
3559 &keylen, &keylen_size);
3560 if (rv == KMF_ERR_ATTR_NOT_FOUND &&
3561 (keytype == KMF_DES || keytype == KMF_DES3))
3562 /* keylength is not required for DES and 3DES */
3563 rv = KMF_OK;
3564 if (rv != KMF_OK)
3565 return (KMF_ERR_BAD_PARAMETER);
3566 }
3567
3568 if ((keylen % 8) != 0) {
3569 return (KMF_ERR_BAD_KEY_SIZE);
3570 }
3571 secKeyLen = keylen / 8; /* in bytes for RC4/AES */
3572
3573 /*
3574 * Only set CKA_VALUE_LEN if the key data was not given and
3575 * we are creating an RC4 or AES key.
3576 */
3577 if (keydata == NULL &&
3578 (keytype == KMF_AES || keytype == KMF_RC4)) {
3579 SETATTR(templ, i, CKA_VALUE_LEN, &secKeyLen,
3580 sizeof (secKeyLen));
3581 i++;
3582 }
3583
3584 /* Other keytypes */
3585 keyGenMech.pParameter = NULL_PTR;
3586 keyGenMech.ulParameterLen = 0;
3587 switch (keytype) {
3588 case KMF_AES:
3589 keyGenMech.mechanism = CKM_AES_KEY_GEN;
3590 secKeyType = CKK_AES;
3591 break;
3592 case KMF_RC4:
3593 keyGenMech.mechanism = CKM_RC4_KEY_GEN;
3594 secKeyType = CKK_RC4;
3595 break;
3596 case KMF_DES:
3597 keyGenMech.mechanism = CKM_DES_KEY_GEN;
3598 secKeyType = CKK_DES;
3599 break;
3600 case KMF_DES3:
3601 keyGenMech.mechanism = CKM_DES3_KEY_GEN;
3602 secKeyType = CKK_DES3;
3603 break;
3604 default:
3605 return (KMF_ERR_BAD_KEY_TYPE);
3606 }
3607 if (keydata != NULL) {
3608 SETATTR(templ, i, CKA_VALUE, keydata, secKeyLen);
3609 i++;
3610 }
3611 SETATTR(templ, i, CKA_CLASS, &class, sizeof (class));
3612 i++;
3613 SETATTR(templ, i, CKA_KEY_TYPE, &secKeyType, sizeof (secKeyType));
3614 i++;
3615
3616 if (keylabel != NULL) {
3617 SETATTR(templ, i, CKA_LABEL, keylabel, strlen(keylabel));
3618 i++;
3619 }
3620
3621 if (is_sensitive == B_TRUE) {
3622 SETATTR(templ, i, CKA_SENSITIVE, &true, sizeof (true));
3623 } else {
3624 SETATTR(templ, i, CKA_SENSITIVE, &false, sizeof (false));
3625 }
3626 i++;
3627
3628 if (is_not_extractable == B_TRUE) {
3629 SETATTR(templ, i, CKA_EXTRACTABLE, &false, sizeof (false));
3630 } else {
3631 SETATTR(templ, i, CKA_EXTRACTABLE, &true, sizeof (true));
3632 }
3633 i++;
3634
3635 SETATTR(templ, i, CKA_TOKEN, &true, sizeof (true));
3636 i++;
3637 SETATTR(templ, i, CKA_PRIVATE, &true, sizeof (true));
3638 i++;
3639 SETATTR(templ, i, CKA_ENCRYPT, &true, sizeof (true));
3640 i++;
3641 SETATTR(templ, i, CKA_DECRYPT, &true, sizeof (true));
3642 i++;
3643 SETATTR(templ, i, CKA_SIGN, &true, sizeof (true));
3644 i++;
3645 SETATTR(templ, i, CKA_VERIFY, &true, sizeof (true));
3646 i++;
3647
3648 cred = kmf_get_attr_ptr(KMF_CREDENTIAL_ATTR, attrlist, numattr);
3649 if (cred == NULL)
3650 return (KMF_ERR_BAD_PARAMETER);
3651
3652 rv = pk11_authenticate(handle, cred);
3653 if (rv != KMF_OK) {
3654 return (rv);
3655 }
3656
3657 /* If the key data was given, use C_CreateObject */
3658 if (keydata != NULL) {
3659 ckrv = C_CreateObject(hSession, templ, i, &keyhandle);
3660 } else {
3661 ckrv = C_GenerateKey(hSession, &keyGenMech, templ, i,
3662 &keyhandle);
3663 }
3664 if (ckrv != CKR_OK) {
3665 if (ckrv == CKR_USER_NOT_LOGGED_IN ||
3666 ckrv == CKR_PIN_INCORRECT ||
3667 ckrv == CKR_PIN_INVALID ||
3668 ckrv == CKR_PIN_EXPIRED ||
3669 ckrv == CKR_PIN_LOCKED ||
3670 ckrv == CKR_SESSION_READ_ONLY)
3671 rv = KMF_ERR_AUTH_FAILED;
3672 else
3673 rv = KMF_ERR_KEYGEN_FAILED;
3674 SET_ERROR(kmfh, ckrv);
3675 goto out;
3676 }
3677
3678 setup:
3679 symkey->kstype = KMF_KEYSTORE_PK11TOKEN;
3680 symkey->keyalg = keytype;
3681 symkey->keyclass = KMF_SYMMETRIC;
3682 symkey->israw = FALSE;
3683 symkey->keyp = (void *)keyhandle;
3684
3685 out:
3686 return (rv);
3687 }
3688
3689 KMF_RETURN
KMFPK11_GetSymKeyValue(KMF_HANDLE_T handle,KMF_KEY_HANDLE * symkey,KMF_RAW_SYM_KEY * rkey)3690 KMFPK11_GetSymKeyValue(KMF_HANDLE_T handle, KMF_KEY_HANDLE *symkey,
3691 KMF_RAW_SYM_KEY *rkey)
3692 {
3693 KMF_RETURN rv = KMF_OK;
3694 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
3695
3696 if (kmfh == NULL)
3697 return (KMF_ERR_UNINITIALIZED);
3698
3699 if (kmfh->pk11handle == CK_INVALID_HANDLE)
3700 return (KMF_ERR_NO_TOKEN_SELECTED);
3701
3702 if (symkey == NULL || rkey == NULL)
3703 return (KMF_ERR_BAD_PARAMETER);
3704 else if (symkey->keyclass != KMF_SYMMETRIC)
3705 return (KMF_ERR_BAD_KEY_CLASS);
3706
3707 /*
3708 * If the key is already in "raw" format, copy the data
3709 * to the new record if possible.
3710 */
3711 if (symkey->israw) {
3712 KMF_RAW_KEY_DATA *rawkey = (KMF_RAW_KEY_DATA *)symkey->keyp;
3713
3714 if (rawkey == NULL)
3715 return (KMF_ERR_BAD_KEYHANDLE);
3716 if (rawkey->sensitive)
3717 return (KMF_ERR_SENSITIVE_KEY);
3718 if (rawkey->not_extractable)
3719 return (KMF_ERR_UNEXTRACTABLE_KEY);
3720
3721 if (rawkey->rawdata.sym.keydata.val == NULL ||
3722 rawkey->rawdata.sym.keydata.len == 0)
3723 return (KMF_ERR_GETKEYVALUE_FAILED);
3724
3725 rkey->keydata.len = rawkey->rawdata.sym.keydata.len;
3726 if ((rkey->keydata.val = malloc(rkey->keydata.len)) == NULL)
3727 return (KMF_ERR_MEMORY);
3728 (void) memcpy(rkey->keydata.val,
3729 rawkey->rawdata.sym.keydata.val, rkey->keydata.len);
3730 } else {
3731 rv = get_raw_sym(kmfh, (CK_OBJECT_HANDLE)symkey->keyp, rkey);
3732 }
3733
3734 return (rv);
3735 }
3736
3737 KMF_RETURN
KMFPK11_SetTokenPin(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)3738 KMFPK11_SetTokenPin(KMF_HANDLE_T handle,
3739 int numattr, KMF_ATTRIBUTE *attrlist)
3740 {
3741 KMF_RETURN ret = KMF_OK;
3742 CK_RV rv = CKR_OK;
3743 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
3744 CK_SESSION_HANDLE session = NULL;
3745 KMF_CREDENTIAL *oldcred;
3746 KMF_CREDENTIAL *newcred;
3747 CK_SLOT_ID slotid;
3748 CK_USER_TYPE user = CKU_USER;
3749
3750 if (handle == NULL || attrlist == NULL || numattr == 0)
3751 return (KMF_ERR_BAD_PARAMETER);
3752
3753 oldcred = kmf_get_attr_ptr(KMF_CREDENTIAL_ATTR, attrlist, numattr);
3754 if (oldcred == NULL)
3755 return (KMF_ERR_BAD_PARAMETER);
3756
3757 newcred = kmf_get_attr_ptr(KMF_NEWPIN_ATTR, attrlist, numattr);
3758 if (newcred == NULL)
3759 return (KMF_ERR_BAD_PARAMETER);
3760
3761 rv = kmf_get_attr(KMF_SLOT_ID_ATTR, attrlist, numattr,
3762 (void *)&slotid, NULL);
3763 if (rv != KMF_OK) {
3764 char *tokenlabel = NULL;
3765 /*
3766 * If a slot wasn't given, the user must pass
3767 * a token label so we can find the slot here.
3768 */
3769 tokenlabel = kmf_get_attr_ptr(KMF_TOKEN_LABEL_ATTR, attrlist,
3770 numattr);
3771 if (tokenlabel == NULL)
3772 return (KMF_ERR_BAD_PARAMETER);
3773
3774 rv = kmf_pk11_token_lookup(handle, tokenlabel, &slotid);
3775 if (rv != KMF_OK)
3776 return (rv);
3777 }
3778 rv = kmf_get_attr(KMF_PK11_USER_TYPE_ATTR, attrlist, numattr,
3779 (void *)&user, NULL);
3780 if (rv != CKR_OK)
3781 user = CKU_USER;
3782
3783 rv = C_OpenSession(slotid, CKF_SERIAL_SESSION | CKF_RW_SESSION,
3784 NULL, NULL, &session);
3785 if (rv != CKR_OK) {
3786 SET_ERROR(kmfh, rv);
3787 ret = KMF_ERR_UNINITIALIZED;
3788 goto end;
3789 }
3790
3791 rv = C_Login(session, user, (CK_BYTE *)oldcred->cred,
3792 oldcred->credlen);
3793 if (rv != CKR_OK) {
3794 SET_ERROR(kmfh, rv);
3795 if (rv == CKR_PIN_INCORRECT ||
3796 rv == CKR_PIN_INVALID ||
3797 rv == CKR_PIN_EXPIRED ||
3798 rv == CKR_PIN_LOCKED)
3799 ret = KMF_ERR_AUTH_FAILED;
3800 else
3801 ret = KMF_ERR_INTERNAL;
3802
3803 goto end;
3804 }
3805
3806 rv = C_SetPIN(session,
3807 (CK_BYTE *)oldcred->cred, oldcred->credlen,
3808 (CK_BYTE *)newcred->cred, newcred->credlen);
3809
3810 if (rv != CKR_OK) {
3811 SET_ERROR(kmfh, rv);
3812 if (rv == CKR_PIN_INCORRECT ||
3813 rv == CKR_PIN_INVALID ||
3814 rv == CKR_PIN_EXPIRED ||
3815 rv == CKR_PIN_LOCKED)
3816 ret = KMF_ERR_AUTH_FAILED;
3817 else
3818 ret = KMF_ERR_INTERNAL;
3819 }
3820 end:
3821 if (session != NULL)
3822 (void) C_CloseSession(session);
3823 return (ret);
3824 }
3825
3826 static KMF_RETURN
create_generic_secret_key(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist,CK_OBJECT_HANDLE * key)3827 create_generic_secret_key(KMF_HANDLE_T handle,
3828 int numattr, KMF_ATTRIBUTE *attrlist, CK_OBJECT_HANDLE *key)
3829 {
3830 KMF_RETURN rv = KMF_OK;
3831 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
3832 CK_RV ckrv;
3833 CK_SESSION_HANDLE hSession = kmfh->pk11handle;
3834 CK_OBJECT_CLASS class = CKO_SECRET_KEY;
3835 CK_ULONG secKeyType = CKK_GENERIC_SECRET;
3836 CK_ULONG secKeyLen;
3837 CK_BBOOL true = TRUE;
3838 CK_BBOOL false = FALSE;
3839 CK_ATTRIBUTE templ[15];
3840 int i;
3841 int random_fd = -1;
3842 int nread;
3843 int freebuf = 0;
3844 char *buf = NULL;
3845 uint32_t keylen = 0, attrkeylen = 0;
3846 char *keylabel = NULL;
3847 KMF_CREDENTIAL *cred;
3848 uint32_t is_sensitive, is_not_extractable;
3849
3850 keylabel = kmf_get_attr_ptr(KMF_KEYLABEL_ATTR, attrlist, numattr);
3851 if (keylabel == NULL)
3852 return (KMF_ERR_BAD_PARAMETER);
3853
3854 cred = kmf_get_attr_ptr(KMF_CREDENTIAL_ATTR, attrlist, numattr);
3855 if (cred == NULL)
3856 return (KMF_ERR_BAD_PARAMETER);
3857
3858 rv = kmf_get_attr(KMF_SENSITIVE_BOOL_ATTR, attrlist, numattr,
3859 (void *)&is_sensitive, NULL);
3860 if (rv != KMF_OK)
3861 return (KMF_ERR_BAD_PARAMETER);
3862
3863 rv = kmf_get_attr(KMF_NON_EXTRACTABLE_BOOL_ATTR, attrlist, numattr,
3864 (void *)&is_not_extractable, NULL);
3865 if (rv != KMF_OK)
3866 return (KMF_ERR_BAD_PARAMETER);
3867
3868 rv = kmf_get_attr(KMF_KEY_DATA_ATTR, attrlist, numattr,
3869 NULL, &attrkeylen);
3870 if (rv == KMF_OK && attrkeylen > 0) {
3871 buf = kmf_get_attr_ptr(KMF_KEY_DATA_ATTR, attrlist,
3872 numattr);
3873 secKeyLen = attrkeylen;
3874 } else {
3875 buf = NULL;
3876 rv = KMF_OK;
3877 }
3878 if (buf == NULL) {
3879 /*
3880 * If the key data was not given, key length must
3881 * be provided.
3882 */
3883 rv = kmf_get_attr(KMF_KEYLENGTH_ATTR, attrlist, numattr,
3884 &keylen, NULL);
3885 if (rv != KMF_OK)
3886 return (KMF_ERR_BAD_PARAMETER);
3887
3888 /*
3889 * Check the key size.
3890 */
3891 if ((keylen % 8) != 0) {
3892 return (KMF_ERR_BAD_KEY_SIZE);
3893 } else {
3894 secKeyLen = keylen/8; /* in bytes */
3895 }
3896
3897 /*
3898 * Generate a random number with the key size first.
3899 */
3900 buf = malloc(secKeyLen);
3901 if (buf == NULL)
3902 return (KMF_ERR_MEMORY);
3903
3904 freebuf = 1;
3905 while ((random_fd = open(DEV_RANDOM, O_RDONLY)) < 0) {
3906 if (errno != EINTR)
3907 break;
3908 }
3909
3910 if (random_fd < 0) {
3911 rv = KMF_ERR_KEYGEN_FAILED;
3912 goto out;
3913 }
3914
3915 nread = read(random_fd, buf, secKeyLen);
3916 if (nread <= 0 || nread != secKeyLen) {
3917 rv = KMF_ERR_KEYGEN_FAILED;
3918 goto out;
3919 }
3920 }
3921
3922 /*
3923 * Authenticate into the token and call C_CreateObject to generate
3924 * a generic secret token key.
3925 */
3926 rv = pk11_authenticate(handle, cred);
3927 if (rv != KMF_OK) {
3928 goto out;
3929 }
3930
3931 i = 0;
3932 SETATTR(templ, i, CKA_CLASS, &class, sizeof (class));
3933 i++;
3934 SETATTR(templ, i, CKA_KEY_TYPE, &secKeyType, sizeof (secKeyType));
3935 i++;
3936 SETATTR(templ, i, CKA_VALUE, buf, secKeyLen);
3937 i++;
3938
3939 if (keylabel != NULL) {
3940 SETATTR(templ, i, CKA_LABEL, keylabel, strlen(keylabel));
3941 i++;
3942 }
3943
3944 if (is_sensitive == B_TRUE) {
3945 SETATTR(templ, i, CKA_SENSITIVE, &true, sizeof (true));
3946 } else {
3947 SETATTR(templ, i, CKA_SENSITIVE, &false, sizeof (false));
3948 }
3949 i++;
3950
3951 if (is_not_extractable == B_TRUE) {
3952 SETATTR(templ, i, CKA_EXTRACTABLE, &false, sizeof (false));
3953 } else {
3954 SETATTR(templ, i, CKA_EXTRACTABLE, &true, sizeof (true));
3955 }
3956 i++;
3957
3958 SETATTR(templ, i, CKA_TOKEN, &true, sizeof (true));
3959 i++;
3960 SETATTR(templ, i, CKA_PRIVATE, &true, sizeof (true));
3961 i++;
3962 SETATTR(templ, i, CKA_SIGN, &true, sizeof (true));
3963 i++;
3964
3965 ckrv = C_CreateObject(hSession, templ, i, key);
3966 if (ckrv != CKR_OK) {
3967 if (ckrv == CKR_USER_NOT_LOGGED_IN ||
3968 ckrv == CKR_PIN_INCORRECT ||
3969 ckrv == CKR_PIN_INVALID ||
3970 ckrv == CKR_PIN_EXPIRED ||
3971 ckrv == CKR_PIN_LOCKED ||
3972 ckrv == CKR_SESSION_READ_ONLY)
3973 rv = KMF_ERR_AUTH_FAILED;
3974 else
3975 rv = KMF_ERR_KEYGEN_FAILED;
3976 SET_ERROR(kmfh, ckrv);
3977 }
3978
3979 out:
3980 if (buf != NULL && freebuf)
3981 free(buf);
3982
3983 if (random_fd != -1)
3984 (void) close(random_fd);
3985
3986 return (rv);
3987 }
3988
3989 KMF_RETURN
KMFPK11_StoreKey(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attlist)3990 KMFPK11_StoreKey(KMF_HANDLE_T handle,
3991 int numattr,
3992 KMF_ATTRIBUTE *attlist)
3993 {
3994 KMF_RETURN rv = KMF_OK;
3995 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
3996 KMF_CREDENTIAL cred = { NULL, 0 };
3997 KMF_KEY_HANDLE *key;
3998 KMF_RAW_KEY_DATA *rawkey = NULL;
3999 CK_BBOOL btrue = TRUE;
4000 CK_ATTRIBUTE tokenattr[1];
4001 CK_OBJECT_HANDLE newobj;
4002 CK_RV ckrv;
4003
4004 if (kmfh == NULL)
4005 return (KMF_ERR_UNINITIALIZED);
4006
4007 if (kmfh->pk11handle == CK_INVALID_HANDLE)
4008 return (KMF_ERR_NO_TOKEN_SELECTED);
4009
4010 rv = kmf_get_attr(KMF_CREDENTIAL_ATTR, attlist, numattr,
4011 (void *)&cred, NULL);
4012 if (rv != KMF_OK)
4013 return (KMF_ERR_BAD_PARAMETER);
4014
4015 rv = pk11_authenticate(handle, &cred);
4016 if (rv != KMF_OK)
4017 return (rv);
4018
4019 key = kmf_get_attr_ptr(KMF_PUBKEY_HANDLE_ATTR, attlist, numattr);
4020 if (key == NULL) {
4021 key = kmf_get_attr_ptr(KMF_PRIVKEY_HANDLE_ATTR, attlist,
4022 numattr);
4023 if (key == NULL)
4024 rawkey = kmf_get_attr_ptr(KMF_RAW_KEY_ATTR, attlist,
4025 numattr);
4026 }
4027 if (key == NULL && rawkey == NULL)
4028 return (KMF_ERR_ATTR_NOT_FOUND);
4029
4030 if (rawkey != NULL) {
4031 rv = store_raw_key(handle, attlist, numattr, rawkey);
4032 } else if (key && key->kstype == KMF_KEYSTORE_PK11TOKEN) {
4033
4034 SETATTR(tokenattr, 0, CKA_TOKEN, &btrue, sizeof (btrue));
4035 /* Copy the key object to the token */
4036 ckrv = C_CopyObject(kmfh->pk11handle,
4037 (CK_OBJECT_HANDLE)key->keyp, tokenattr, 1, &newobj);
4038 if (ckrv != CKR_OK) {
4039 SET_ERROR(kmfh, ckrv);
4040 return (KMF_ERR_INTERNAL);
4041 }
4042
4043 /* Replace the object handle with the new token-based one */
4044 ckrv = C_DestroyObject(kmfh->pk11handle,
4045 (CK_OBJECT_HANDLE)key->keyp);
4046 if (ckrv != CKR_OK) {
4047 SET_ERROR(kmfh, ckrv);
4048 return (KMF_ERR_INTERNAL);
4049 }
4050 key->keyp = (void *)newobj;
4051 } else {
4052 rv = KMF_ERR_BAD_PARAMETER;
4053 }
4054
4055 return (rv);
4056 }
4057
4058
4059 KMF_RETURN
KMFPK11_ExportPK12(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)4060 KMFPK11_ExportPK12(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
4061 {
4062 KMF_RETURN rv = KMF_OK;
4063 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
4064 KMF_CREDENTIAL *cred = NULL;
4065 KMF_CREDENTIAL *p12cred = NULL;
4066 char *filename = NULL;
4067 KMF_X509_DER_CERT *certlist = NULL;
4068 KMF_KEY_HANDLE *keylist = NULL;
4069 uint32_t numcerts;
4070 uint32_t numkeys;
4071 char *certlabel = NULL;
4072 char *issuer = NULL;
4073 char *subject = NULL;
4074 KMF_BIGINT *serial = NULL;
4075 KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_PK11TOKEN;
4076 KMF_ATTRIBUTE fc_attrlist[16];
4077 int i;
4078
4079 if (kmfh == NULL)
4080 return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */
4081
4082 if (kmfh->pk11handle == CK_INVALID_HANDLE)
4083 return (KMF_ERR_NO_TOKEN_SELECTED);
4084
4085 /* First get the required attributes */
4086 cred = kmf_get_attr_ptr(KMF_CREDENTIAL_ATTR, attrlist, numattr);
4087 if (cred == NULL)
4088 return (KMF_ERR_BAD_PARAMETER);
4089
4090 p12cred = kmf_get_attr_ptr(KMF_PK12CRED_ATTR, attrlist, numattr);
4091 if (p12cred == NULL)
4092 return (KMF_ERR_BAD_PARAMETER);
4093
4094 filename = kmf_get_attr_ptr(KMF_OUTPUT_FILENAME_ATTR, attrlist,
4095 numattr);
4096 if (filename == NULL)
4097 return (KMF_ERR_BAD_PARAMETER);
4098
4099 /* Find all the certificates that match the searching criteria */
4100 i = 0;
4101 kmf_set_attr_at_index(fc_attrlist, i,
4102 KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype));
4103 i++;
4104
4105 kmf_set_attr_at_index(fc_attrlist, i,
4106 KMF_COUNT_ATTR, &numcerts, sizeof (uint32_t));
4107 i++;
4108
4109 certlabel = kmf_get_attr_ptr(KMF_CERT_LABEL_ATTR, attrlist, numattr);
4110 if (certlabel != NULL) {
4111 kmf_set_attr_at_index(fc_attrlist, i,
4112 KMF_CERT_LABEL_ATTR, certlabel, strlen(certlabel));
4113 i++;
4114 }
4115
4116 issuer = kmf_get_attr_ptr(KMF_ISSUER_NAME_ATTR, attrlist, numattr);
4117 if (issuer != NULL) {
4118 kmf_set_attr_at_index(fc_attrlist, i,
4119 KMF_ISSUER_NAME_ATTR, issuer, strlen(issuer));
4120 i++;
4121 }
4122
4123 subject = kmf_get_attr_ptr(KMF_SUBJECT_NAME_ATTR, attrlist, numattr);
4124 if (subject != NULL) {
4125 kmf_set_attr_at_index(fc_attrlist, i,
4126 KMF_SUBJECT_NAME_ATTR, subject, strlen(subject));
4127 i++;
4128 }
4129
4130 serial = kmf_get_attr_ptr(KMF_BIGINT_ATTR, attrlist, numattr);
4131 if (serial != NULL) {
4132 kmf_set_attr_at_index(fc_attrlist, i,
4133 KMF_BIGINT_ATTR, serial, sizeof (KMF_BIGINT));
4134 i++;
4135 }
4136
4137 rv = KMFPK11_FindCert(handle, i, fc_attrlist);
4138
4139 if (rv == KMF_OK && numcerts > 0) {
4140 certlist = (KMF_X509_DER_CERT *)malloc(numcerts *
4141 sizeof (KMF_X509_DER_CERT));
4142 if (certlist == NULL)
4143 return (KMF_ERR_MEMORY);
4144
4145 (void) memset(certlist, 0, numcerts *
4146 sizeof (KMF_X509_DER_CERT));
4147
4148 kmf_set_attr_at_index(fc_attrlist, i, KMF_X509_DER_CERT_ATTR,
4149 certlist, sizeof (KMF_X509_DER_CERT));
4150 i++;
4151
4152 rv = kmf_find_cert(handle, i, fc_attrlist);
4153 if (rv != KMF_OK) {
4154 free(certlist);
4155 return (rv);
4156 }
4157 } else {
4158 return (rv);
4159 }
4160
4161 /* For each certificate, find the matching private key */
4162 numkeys = 0;
4163 for (i = 0; i < numcerts; i++) {
4164 KMF_ATTRIBUTE fk_attrlist[16];
4165 int j = 0;
4166 KMF_KEY_HANDLE newkey;
4167 KMF_ENCODE_FORMAT format = KMF_FORMAT_RAWKEY;
4168
4169 kmf_set_attr_at_index(fk_attrlist, j,
4170 KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype));
4171 j++;
4172
4173 kmf_set_attr_at_index(fk_attrlist, j,
4174 KMF_ENCODE_FORMAT_ATTR, &format, sizeof (format));
4175 j++;
4176
4177 kmf_set_attr_at_index(fk_attrlist, j,
4178 KMF_CREDENTIAL_ATTR, cred, sizeof (KMF_CREDENTIAL));
4179 j++;
4180
4181 kmf_set_attr_at_index(fk_attrlist, j,
4182 KMF_CERT_DATA_ATTR, &certlist[i].certificate,
4183 sizeof (KMF_DATA));
4184 j++;
4185
4186 kmf_set_attr_at_index(fk_attrlist, j,
4187 KMF_KEY_HANDLE_ATTR, &newkey, sizeof (KMF_KEY_HANDLE));
4188 j++;
4189
4190 rv = KMFPK11_FindPrikeyByCert(handle, j, fk_attrlist);
4191 if (rv == KMF_OK) {
4192 numkeys++;
4193 keylist = realloc(keylist,
4194 numkeys * sizeof (KMF_KEY_HANDLE));
4195 if (keylist == NULL) {
4196 rv = KMF_ERR_MEMORY;
4197 goto out;
4198 }
4199 keylist[numkeys - 1] = newkey;
4200 } else if (rv == KMF_ERR_KEY_NOT_FOUND) {
4201 /* it is OK if a key is not found */
4202 rv = KMF_OK;
4203 }
4204 }
4205
4206 if (rv != KMF_OK)
4207 goto out;
4208
4209 rv = kmf_build_pk12(handle, numcerts, certlist, numkeys, keylist,
4210 p12cred, filename);
4211
4212 out:
4213 if (certlist != NULL) {
4214 for (i = 0; i < numcerts; i++)
4215 kmf_free_kmf_cert(handle, &certlist[i]);
4216 free(certlist);
4217 }
4218 if (keylist != NULL) {
4219 for (i = 0; i < numkeys; i++)
4220 kmf_free_kmf_key(handle, &keylist[i]);
4221 free(keylist);
4222 }
4223
4224 return (rv);
4225 }
4226