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 == 0)
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 = 0;
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
3252 cert = kmf_get_attr_ptr(KMF_CERT_DATA_ATTR, attrlist, numattr);
3253 if (cert != NULL) {
3254 id.Data = NULL;
3255 id.Length = 0;
3256 rv = kmf_get_cert_id_data(cert, &id);
3257 if (rv != KMF_OK) {
3258 goto cleanup;
3259 }
3260
3261 rv = DerDecodeSignedCertificate((const KMF_DATA *)cert, &x509);
3262 if (rv != KMF_OK) {
3263 goto cleanup;
3264 }
3265
3266 rv = DerEncodeName(&x509->certificate.subject, &subject);
3267 if (rv != KMF_OK) {
3268 goto cleanup;
3269 }
3270 SETATTR(templ, i, CKA_SUBJECT, subject.Data, subject.Length);
3271 i++;
3272
3273 rv = kmf_get_cert_start_date_str(handle, cert, ¬before);
3274 if (rv != KMF_OK) {
3275 goto cleanup;
3276 }
3277 start = convertDate(notbefore);
3278 free(notbefore);
3279
3280 rv = kmf_get_cert_end_date_str(handle, cert, ¬after);
3281 if (rv != KMF_OK) {
3282 goto cleanup;
3283 }
3284 end = convertDate(notafter);
3285 free(notafter);
3286 if (id.Data != NULL && id.Data != NULL && id.Length > 0) {
3287 SETATTR(templ, i, CKA_ID, id.Data, id.Length);
3288 i++;
3289 }
3290 if (start != NULL) {
3291 /*
3292 * This makes some potentially dangerous assumptions:
3293 * 1. that the startdate in the parameter block is
3294 * properly formatted as YYYYMMDD
3295 * 2. That the CK_DATE structure is always the same.
3296 */
3297 (void) memcpy(&startdate, start, sizeof (CK_DATE));
3298 SETATTR(templ, i, CKA_START_DATE, &startdate,
3299 sizeof (startdate));
3300 i++;
3301 }
3302 if (end != NULL) {
3303 (void) memcpy(&enddate, end, sizeof (CK_DATE));
3304 SETATTR(templ, i, CKA_END_DATE, &enddate,
3305 sizeof (enddate));
3306 i++;
3307 }
3308
3309 if ((rv = kmf_get_cert_ku(cert, &kuext)) != KMF_OK &&
3310 rv != KMF_ERR_EXTENSION_NOT_FOUND)
3311 goto cleanup;
3312
3313 kufound = (rv == KMF_OK);
3314 rv = KMF_OK; /* reset if we got KMF_ERR_EXTENSION_NOT_FOUND */
3315 }
3316
3317 /*
3318 * Only set the KeyUsage stuff if the KU extension was present.
3319 */
3320 if (kufound) {
3321 CK_BBOOL condition;
3322
3323 condition = (kuext.KeyUsageBits & KMF_keyEncipherment) ?
3324 B_TRUE : B_FALSE;
3325 SETATTR(templ, i, CKA_UNWRAP, &condition, sizeof (CK_BBOOL));
3326 i++;
3327 condition = (kuext.KeyUsageBits & KMF_dataEncipherment) ?
3328 B_TRUE : B_FALSE;
3329 SETATTR(templ, i, CKA_DECRYPT, &condition, sizeof (CK_BBOOL));
3330 i++;
3331 condition = (kuext.KeyUsageBits & KMF_digitalSignature) ?
3332 B_TRUE : B_FALSE;
3333 SETATTR(templ, i, CKA_SIGN, &condition, sizeof (CK_BBOOL));
3334 i++;
3335 condition = (kuext.KeyUsageBits & KMF_digitalSignature) ?
3336 B_TRUE : B_FALSE;
3337 SETATTR(templ, i, CKA_SIGN_RECOVER, &condition,
3338 sizeof (CK_BBOOL));
3339 i++;
3340
3341 }
3342
3343 if (keylabel != NULL) {
3344 SETATTR(templ, i, CKA_LABEL, keylabel, strlen(keylabel));
3345 i++;
3346 }
3347 if (id.Data == NULL && rawkey->id.Data != NULL) {
3348 SETATTR(templ, i, CKA_ID, rawkey->id.Data,
3349 rawkey->id.Length);
3350 i++;
3351 }
3352 if (keytype == CKK_RSA) {
3353 SETATTR(templ, i, CKA_MODULUS,
3354 rawkey->rawdata.rsa.mod.val,
3355 rawkey->rawdata.rsa.mod.len);
3356 i++;
3357 SETATTR(templ, i, CKA_PUBLIC_EXPONENT,
3358 rawkey->rawdata.rsa.pubexp.val,
3359 rawkey->rawdata.rsa.pubexp.len);
3360 i++;
3361 if (rawkey->rawdata.rsa.priexp.val != NULL) {
3362 SETATTR(templ, i, CKA_PRIVATE_EXPONENT,
3363 rawkey->rawdata.rsa.priexp.val,
3364 rawkey->rawdata.rsa.priexp.len);
3365 i++;
3366 }
3367 if (rawkey->rawdata.rsa.prime1.val != NULL) {
3368 SETATTR(templ, i, CKA_PRIME_1,
3369 rawkey->rawdata.rsa.prime1.val,
3370 rawkey->rawdata.rsa.prime1.len);
3371 i++;
3372 }
3373 if (rawkey->rawdata.rsa.prime2.val != NULL) {
3374 SETATTR(templ, i, CKA_PRIME_2,
3375 rawkey->rawdata.rsa.prime2.val,
3376 rawkey->rawdata.rsa.prime2.len);
3377 i++;
3378 }
3379 if (rawkey->rawdata.rsa.exp1.val != NULL) {
3380 SETATTR(templ, i, CKA_EXPONENT_1,
3381 rawkey->rawdata.rsa.exp1.val,
3382 rawkey->rawdata.rsa.exp1.len);
3383 i++;
3384 }
3385 if (rawkey->rawdata.rsa.exp2.val != NULL) {
3386 SETATTR(templ, i, CKA_EXPONENT_2,
3387 rawkey->rawdata.rsa.exp2.val,
3388 rawkey->rawdata.rsa.exp2.len);
3389 i++;
3390 }
3391 if (rawkey->rawdata.rsa.coef.val != NULL) {
3392 SETATTR(templ, i, CKA_COEFFICIENT,
3393 rawkey->rawdata.rsa.coef.val,
3394 rawkey->rawdata.rsa.coef.len);
3395 i++;
3396 }
3397 } else if (keytype == CKK_DSA) {
3398 SETATTR(templ, i, CKA_PRIME,
3399 rawkey->rawdata.dsa.prime.val,
3400 rawkey->rawdata.dsa.prime.len);
3401 i++;
3402 SETATTR(templ, i, CKA_SUBPRIME,
3403 rawkey->rawdata.dsa.subprime.val,
3404 rawkey->rawdata.dsa.subprime.len);
3405 i++;
3406 SETATTR(templ, i, CKA_BASE,
3407 rawkey->rawdata.dsa.base.val,
3408 rawkey->rawdata.dsa.base.len);
3409 i++;
3410 SETATTR(templ, i, CKA_VALUE,
3411 rawkey->rawdata.dsa.value.val,
3412 rawkey->rawdata.dsa.value.len);
3413 i++;
3414 } else if (keytype == CKK_EC) {
3415 SETATTR(templ, i, CKA_SIGN, &cktrue, sizeof (cktrue));
3416 i++;
3417 SETATTR(templ, i, CKA_DERIVE, &cktrue, sizeof (cktrue));
3418 i++;
3419 SETATTR(templ, i, CKA_VALUE,
3420 rawkey->rawdata.ec.value.val,
3421 rawkey->rawdata.ec.value.len);
3422 i++;
3423 SETATTR(templ, i, CKA_EC_PARAMS,
3424 rawkey->rawdata.ec.params.Data,
3425 rawkey->rawdata.ec.params.Length);
3426 i++;
3427 }
3428
3429 ckrv = C_CreateObject(kmfh->pk11handle, templ, i, &keyobj);
3430 if (ckrv != CKR_OK) {
3431 SET_ERROR(kmfh, ckrv);
3432
3433 /* Report authentication failures to the caller */
3434 if (ckrv == CKR_USER_NOT_LOGGED_IN ||
3435 ckrv == CKR_PIN_INCORRECT ||
3436 ckrv == CKR_PIN_INVALID ||
3437 ckrv == CKR_PIN_EXPIRED ||
3438 ckrv == CKR_PIN_LOCKED ||
3439 ckrv == CKR_SESSION_READ_ONLY)
3440 rv = KMF_ERR_AUTH_FAILED;
3441 else
3442 rv = KMF_ERR_INTERNAL;
3443 }
3444 cleanup:
3445 if (start != NULL)
3446 free(start);
3447 if (end != NULL)
3448 free(end);
3449 kmf_free_data(&id);
3450 kmf_free_data(&subject);
3451 kmf_free_signed_cert(x509);
3452 free(x509);
3453
3454 return (rv);
3455 }
3456
3457 KMF_RETURN
KMFPK11_CreateSymKey(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)3458 KMFPK11_CreateSymKey(KMF_HANDLE_T handle,
3459 int numattr, KMF_ATTRIBUTE *attrlist)
3460 {
3461 KMF_RETURN rv = KMF_OK;
3462 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
3463 CK_RV ckrv;
3464 CK_SESSION_HANDLE hSession = kmfh->pk11handle;
3465 CK_OBJECT_HANDLE keyhandle;
3466 CK_MECHANISM keyGenMech;
3467 CK_OBJECT_CLASS class = CKO_SECRET_KEY;
3468 CK_ULONG secKeyType;
3469 CK_ULONG secKeyLen; /* for RC4 and AES */
3470 CK_BBOOL true = TRUE;
3471 CK_BBOOL false = FALSE;
3472 CK_ATTRIBUTE templ[15];
3473 CK_BYTE *keydata = NULL;
3474 int i = 0;
3475 KMF_KEY_HANDLE *symkey;
3476 KMF_KEY_ALG keytype;
3477 uint32_t keylen = 0;
3478 uint32_t attrkeylen = 0;
3479 uint32_t keylen_size = sizeof (uint32_t);
3480 char *keylabel = NULL;
3481 KMF_CREDENTIAL *cred = NULL;
3482 uint32_t is_sensitive = B_FALSE;
3483 uint32_t is_not_extractable = B_FALSE;
3484
3485 if (kmfh == NULL)
3486 return (KMF_ERR_UNINITIALIZED);
3487
3488 if (kmfh->pk11handle == CK_INVALID_HANDLE)
3489 return (KMF_ERR_NO_TOKEN_SELECTED);
3490
3491 symkey = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr);
3492 if (symkey == NULL)
3493 return (KMF_ERR_BAD_PARAMETER);
3494
3495 rv = kmf_get_attr(KMF_KEYALG_ATTR, attrlist, numattr,
3496 (void *)&keytype, NULL);
3497 if (rv != KMF_OK)
3498 return (KMF_ERR_BAD_PARAMETER);
3499
3500 keylabel = kmf_get_attr_ptr(KMF_KEYLABEL_ATTR, attrlist, numattr);
3501 if (keylabel == NULL)
3502 return (KMF_ERR_BAD_PARAMETER);
3503
3504 rv = kmf_get_attr(KMF_SENSITIVE_BOOL_ATTR, attrlist, numattr,
3505 (void *)&is_sensitive, NULL);
3506 if (rv != KMF_OK)
3507 return (KMF_ERR_BAD_PARAMETER);
3508
3509 rv = kmf_get_attr(KMF_NON_EXTRACTABLE_BOOL_ATTR, attrlist, numattr,
3510 (void *)&is_not_extractable, NULL);
3511 if (rv != KMF_OK)
3512 return (KMF_ERR_BAD_PARAMETER);
3513
3514 /*
3515 * For AES, RC4, DES and 3DES, call C_GenerateKey() to create a key.
3516 *
3517 * For a generic secret key, because it may not be supported in
3518 * C_GenerateKey() for some PKCS11 providers, we will handle it
3519 * differently.
3520 */
3521 if (keytype == KMF_GENERIC_SECRET) {
3522 rv = create_generic_secret_key(handle, numattr,
3523 attrlist, &keyhandle);
3524 if (rv != KMF_OK)
3525 goto out;
3526 else
3527 goto setup;
3528 }
3529
3530 rv = kmf_get_attr(KMF_KEY_DATA_ATTR, attrlist, numattr,
3531 NULL, &attrkeylen);
3532 if (rv == KMF_OK && attrkeylen > 0) {
3533 keydata = kmf_get_attr_ptr(KMF_KEY_DATA_ATTR, attrlist,
3534 numattr);
3535 } else {
3536 keydata = NULL;
3537 attrkeylen = 0;
3538 rv = KMF_OK;
3539 }
3540 if (keydata != NULL) {
3541 if (keytype == KMF_DES && attrkeylen != 8) {
3542 rv = KMF_ERR_BAD_KEY_SIZE;
3543 goto out;
3544 }
3545 if (keytype == KMF_DES3 && attrkeylen != 24) {
3546 rv = KMF_ERR_BAD_KEY_SIZE;
3547 goto out;
3548 }
3549 /*
3550 * This may override what the user gave on the
3551 * command line.
3552 */
3553 keylen = attrkeylen * 8; /* bytes to bits */
3554 } else {
3555 /*
3556 * If keydata was not given, key length must be
3557 * provided.
3558 */
3559 rv = kmf_get_attr(KMF_KEYLENGTH_ATTR, attrlist, numattr,
3560 &keylen, &keylen_size);
3561 if (rv == KMF_ERR_ATTR_NOT_FOUND &&
3562 (keytype == KMF_DES || keytype == KMF_DES3))
3563 /* keylength is not required for DES and 3DES */
3564 rv = KMF_OK;
3565 if (rv != KMF_OK)
3566 return (KMF_ERR_BAD_PARAMETER);
3567 }
3568
3569 if ((keylen % 8) != 0) {
3570 return (KMF_ERR_BAD_KEY_SIZE);
3571 }
3572 secKeyLen = keylen / 8; /* in bytes for RC4/AES */
3573
3574 /*
3575 * Only set CKA_VALUE_LEN if the key data was not given and
3576 * we are creating an RC4 or AES key.
3577 */
3578 if (keydata == NULL &&
3579 (keytype == KMF_AES || keytype == KMF_RC4)) {
3580 SETATTR(templ, i, CKA_VALUE_LEN, &secKeyLen,
3581 sizeof (secKeyLen));
3582 i++;
3583 }
3584
3585 /* Other keytypes */
3586 keyGenMech.pParameter = NULL_PTR;
3587 keyGenMech.ulParameterLen = 0;
3588 switch (keytype) {
3589 case KMF_AES:
3590 keyGenMech.mechanism = CKM_AES_KEY_GEN;
3591 secKeyType = CKK_AES;
3592 break;
3593 case KMF_RC4:
3594 keyGenMech.mechanism = CKM_RC4_KEY_GEN;
3595 secKeyType = CKK_RC4;
3596 break;
3597 case KMF_DES:
3598 keyGenMech.mechanism = CKM_DES_KEY_GEN;
3599 secKeyType = CKK_DES;
3600 break;
3601 case KMF_DES3:
3602 keyGenMech.mechanism = CKM_DES3_KEY_GEN;
3603 secKeyType = CKK_DES3;
3604 break;
3605 default:
3606 return (KMF_ERR_BAD_KEY_TYPE);
3607 }
3608 if (keydata != NULL) {
3609 SETATTR(templ, i, CKA_VALUE, keydata, secKeyLen);
3610 i++;
3611 }
3612 SETATTR(templ, i, CKA_CLASS, &class, sizeof (class));
3613 i++;
3614 SETATTR(templ, i, CKA_KEY_TYPE, &secKeyType, sizeof (secKeyType));
3615 i++;
3616
3617 if (keylabel != NULL) {
3618 SETATTR(templ, i, CKA_LABEL, keylabel, strlen(keylabel));
3619 i++;
3620 }
3621
3622 if (is_sensitive == B_TRUE) {
3623 SETATTR(templ, i, CKA_SENSITIVE, &true, sizeof (true));
3624 } else {
3625 SETATTR(templ, i, CKA_SENSITIVE, &false, sizeof (false));
3626 }
3627 i++;
3628
3629 if (is_not_extractable == B_TRUE) {
3630 SETATTR(templ, i, CKA_EXTRACTABLE, &false, sizeof (false));
3631 } else {
3632 SETATTR(templ, i, CKA_EXTRACTABLE, &true, sizeof (true));
3633 }
3634 i++;
3635
3636 SETATTR(templ, i, CKA_TOKEN, &true, sizeof (true));
3637 i++;
3638 SETATTR(templ, i, CKA_PRIVATE, &true, sizeof (true));
3639 i++;
3640 SETATTR(templ, i, CKA_ENCRYPT, &true, sizeof (true));
3641 i++;
3642 SETATTR(templ, i, CKA_DECRYPT, &true, sizeof (true));
3643 i++;
3644 SETATTR(templ, i, CKA_SIGN, &true, sizeof (true));
3645 i++;
3646 SETATTR(templ, i, CKA_VERIFY, &true, sizeof (true));
3647 i++;
3648
3649 cred = kmf_get_attr_ptr(KMF_CREDENTIAL_ATTR, attrlist, numattr);
3650 if (cred == NULL)
3651 return (KMF_ERR_BAD_PARAMETER);
3652
3653 rv = pk11_authenticate(handle, cred);
3654 if (rv != KMF_OK) {
3655 return (rv);
3656 }
3657
3658 /* If the key data was given, use C_CreateObject */
3659 if (keydata != NULL) {
3660 ckrv = C_CreateObject(hSession, templ, i, &keyhandle);
3661 } else {
3662 ckrv = C_GenerateKey(hSession, &keyGenMech, templ, i,
3663 &keyhandle);
3664 }
3665 if (ckrv != CKR_OK) {
3666 if (ckrv == CKR_USER_NOT_LOGGED_IN ||
3667 ckrv == CKR_PIN_INCORRECT ||
3668 ckrv == CKR_PIN_INVALID ||
3669 ckrv == CKR_PIN_EXPIRED ||
3670 ckrv == CKR_PIN_LOCKED ||
3671 ckrv == CKR_SESSION_READ_ONLY)
3672 rv = KMF_ERR_AUTH_FAILED;
3673 else
3674 rv = KMF_ERR_KEYGEN_FAILED;
3675 SET_ERROR(kmfh, ckrv);
3676 goto out;
3677 }
3678
3679 setup:
3680 symkey->kstype = KMF_KEYSTORE_PK11TOKEN;
3681 symkey->keyalg = keytype;
3682 symkey->keyclass = KMF_SYMMETRIC;
3683 symkey->israw = FALSE;
3684 symkey->keyp = (void *)keyhandle;
3685
3686 out:
3687 return (rv);
3688 }
3689
3690 KMF_RETURN
KMFPK11_GetSymKeyValue(KMF_HANDLE_T handle,KMF_KEY_HANDLE * symkey,KMF_RAW_SYM_KEY * rkey)3691 KMFPK11_GetSymKeyValue(KMF_HANDLE_T handle, KMF_KEY_HANDLE *symkey,
3692 KMF_RAW_SYM_KEY *rkey)
3693 {
3694 KMF_RETURN rv = KMF_OK;
3695 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
3696
3697 if (kmfh == NULL)
3698 return (KMF_ERR_UNINITIALIZED);
3699
3700 if (kmfh->pk11handle == CK_INVALID_HANDLE)
3701 return (KMF_ERR_NO_TOKEN_SELECTED);
3702
3703 if (symkey == NULL || rkey == NULL)
3704 return (KMF_ERR_BAD_PARAMETER);
3705 else if (symkey->keyclass != KMF_SYMMETRIC)
3706 return (KMF_ERR_BAD_KEY_CLASS);
3707
3708 /*
3709 * If the key is already in "raw" format, copy the data
3710 * to the new record if possible.
3711 */
3712 if (symkey->israw) {
3713 KMF_RAW_KEY_DATA *rawkey = (KMF_RAW_KEY_DATA *)symkey->keyp;
3714
3715 if (rawkey == NULL)
3716 return (KMF_ERR_BAD_KEYHANDLE);
3717 if (rawkey->sensitive)
3718 return (KMF_ERR_SENSITIVE_KEY);
3719 if (rawkey->not_extractable)
3720 return (KMF_ERR_UNEXTRACTABLE_KEY);
3721
3722 if (rawkey->rawdata.sym.keydata.val == NULL ||
3723 rawkey->rawdata.sym.keydata.len == 0)
3724 return (KMF_ERR_GETKEYVALUE_FAILED);
3725
3726 rkey->keydata.len = rawkey->rawdata.sym.keydata.len;
3727 if ((rkey->keydata.val = malloc(rkey->keydata.len)) == NULL)
3728 return (KMF_ERR_MEMORY);
3729 (void) memcpy(rkey->keydata.val,
3730 rawkey->rawdata.sym.keydata.val, rkey->keydata.len);
3731 } else {
3732 rv = get_raw_sym(kmfh, (CK_OBJECT_HANDLE)symkey->keyp, rkey);
3733 }
3734
3735 return (rv);
3736 }
3737
3738 KMF_RETURN
KMFPK11_SetTokenPin(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)3739 KMFPK11_SetTokenPin(KMF_HANDLE_T handle,
3740 int numattr, KMF_ATTRIBUTE *attrlist)
3741 {
3742 KMF_RETURN ret = KMF_OK;
3743 CK_RV rv = CKR_OK;
3744 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
3745 CK_SESSION_HANDLE session = 0;
3746 KMF_CREDENTIAL *oldcred;
3747 KMF_CREDENTIAL *newcred;
3748 CK_SLOT_ID slotid;
3749 CK_USER_TYPE user = CKU_USER;
3750
3751 if (handle == NULL || attrlist == NULL || numattr == 0)
3752 return (KMF_ERR_BAD_PARAMETER);
3753
3754 oldcred = kmf_get_attr_ptr(KMF_CREDENTIAL_ATTR, attrlist, numattr);
3755 if (oldcred == NULL)
3756 return (KMF_ERR_BAD_PARAMETER);
3757
3758 newcred = kmf_get_attr_ptr(KMF_NEWPIN_ATTR, attrlist, numattr);
3759 if (newcred == NULL)
3760 return (KMF_ERR_BAD_PARAMETER);
3761
3762 rv = kmf_get_attr(KMF_SLOT_ID_ATTR, attrlist, numattr,
3763 (void *)&slotid, NULL);
3764 if (rv != KMF_OK) {
3765 char *tokenlabel = NULL;
3766 /*
3767 * If a slot wasn't given, the user must pass
3768 * a token label so we can find the slot here.
3769 */
3770 tokenlabel = kmf_get_attr_ptr(KMF_TOKEN_LABEL_ATTR, attrlist,
3771 numattr);
3772 if (tokenlabel == NULL)
3773 return (KMF_ERR_BAD_PARAMETER);
3774
3775 rv = kmf_pk11_token_lookup(handle, tokenlabel, &slotid);
3776 if (rv != KMF_OK)
3777 return (rv);
3778 }
3779 rv = kmf_get_attr(KMF_PK11_USER_TYPE_ATTR, attrlist, numattr,
3780 (void *)&user, NULL);
3781 if (rv != CKR_OK)
3782 user = CKU_USER;
3783
3784 rv = C_OpenSession(slotid, CKF_SERIAL_SESSION | CKF_RW_SESSION,
3785 NULL, NULL, &session);
3786 if (rv != CKR_OK) {
3787 SET_ERROR(kmfh, rv);
3788 ret = KMF_ERR_UNINITIALIZED;
3789 goto end;
3790 }
3791
3792 rv = C_Login(session, user, (CK_BYTE *)oldcred->cred,
3793 oldcred->credlen);
3794 if (rv != CKR_OK) {
3795 SET_ERROR(kmfh, rv);
3796 if (rv == CKR_PIN_INCORRECT ||
3797 rv == CKR_PIN_INVALID ||
3798 rv == CKR_PIN_EXPIRED ||
3799 rv == CKR_PIN_LOCKED)
3800 ret = KMF_ERR_AUTH_FAILED;
3801 else
3802 ret = KMF_ERR_INTERNAL;
3803
3804 goto end;
3805 }
3806
3807 rv = C_SetPIN(session,
3808 (CK_BYTE *)oldcred->cred, oldcred->credlen,
3809 (CK_BYTE *)newcred->cred, newcred->credlen);
3810
3811 if (rv != CKR_OK) {
3812 SET_ERROR(kmfh, rv);
3813 if (rv == CKR_PIN_INCORRECT ||
3814 rv == CKR_PIN_INVALID ||
3815 rv == CKR_PIN_EXPIRED ||
3816 rv == CKR_PIN_LOCKED)
3817 ret = KMF_ERR_AUTH_FAILED;
3818 else
3819 ret = KMF_ERR_INTERNAL;
3820 }
3821 end:
3822 if (session != 0)
3823 (void) C_CloseSession(session);
3824 return (ret);
3825 }
3826
3827 static KMF_RETURN
create_generic_secret_key(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist,CK_OBJECT_HANDLE * key)3828 create_generic_secret_key(KMF_HANDLE_T handle,
3829 int numattr, KMF_ATTRIBUTE *attrlist, CK_OBJECT_HANDLE *key)
3830 {
3831 KMF_RETURN rv = KMF_OK;
3832 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
3833 CK_RV ckrv;
3834 CK_SESSION_HANDLE hSession = kmfh->pk11handle;
3835 CK_OBJECT_CLASS class = CKO_SECRET_KEY;
3836 CK_ULONG secKeyType = CKK_GENERIC_SECRET;
3837 CK_ULONG secKeyLen;
3838 CK_BBOOL true = TRUE;
3839 CK_BBOOL false = FALSE;
3840 CK_ATTRIBUTE templ[15];
3841 int i;
3842 int random_fd = -1;
3843 int nread;
3844 int freebuf = 0;
3845 char *buf = NULL;
3846 uint32_t keylen = 0, attrkeylen = 0;
3847 char *keylabel = NULL;
3848 KMF_CREDENTIAL *cred;
3849 uint32_t is_sensitive, is_not_extractable;
3850
3851 keylabel = kmf_get_attr_ptr(KMF_KEYLABEL_ATTR, attrlist, numattr);
3852 if (keylabel == NULL)
3853 return (KMF_ERR_BAD_PARAMETER);
3854
3855 cred = kmf_get_attr_ptr(KMF_CREDENTIAL_ATTR, attrlist, numattr);
3856 if (cred == NULL)
3857 return (KMF_ERR_BAD_PARAMETER);
3858
3859 rv = kmf_get_attr(KMF_SENSITIVE_BOOL_ATTR, attrlist, numattr,
3860 (void *)&is_sensitive, NULL);
3861 if (rv != KMF_OK)
3862 return (KMF_ERR_BAD_PARAMETER);
3863
3864 rv = kmf_get_attr(KMF_NON_EXTRACTABLE_BOOL_ATTR, attrlist, numattr,
3865 (void *)&is_not_extractable, NULL);
3866 if (rv != KMF_OK)
3867 return (KMF_ERR_BAD_PARAMETER);
3868
3869 rv = kmf_get_attr(KMF_KEY_DATA_ATTR, attrlist, numattr,
3870 NULL, &attrkeylen);
3871 if (rv == KMF_OK && attrkeylen > 0) {
3872 buf = kmf_get_attr_ptr(KMF_KEY_DATA_ATTR, attrlist,
3873 numattr);
3874 secKeyLen = attrkeylen;
3875 } else {
3876 buf = NULL;
3877 rv = KMF_OK;
3878 }
3879 if (buf == NULL) {
3880 /*
3881 * If the key data was not given, key length must
3882 * be provided.
3883 */
3884 rv = kmf_get_attr(KMF_KEYLENGTH_ATTR, attrlist, numattr,
3885 &keylen, NULL);
3886 if (rv != KMF_OK)
3887 return (KMF_ERR_BAD_PARAMETER);
3888
3889 /*
3890 * Check the key size.
3891 */
3892 if ((keylen % 8) != 0) {
3893 return (KMF_ERR_BAD_KEY_SIZE);
3894 } else {
3895 secKeyLen = keylen/8; /* in bytes */
3896 }
3897
3898 /*
3899 * Generate a random number with the key size first.
3900 */
3901 buf = malloc(secKeyLen);
3902 if (buf == NULL)
3903 return (KMF_ERR_MEMORY);
3904
3905 freebuf = 1;
3906 while ((random_fd = open(DEV_RANDOM, O_RDONLY)) < 0) {
3907 if (errno != EINTR)
3908 break;
3909 }
3910
3911 if (random_fd < 0) {
3912 rv = KMF_ERR_KEYGEN_FAILED;
3913 goto out;
3914 }
3915
3916 nread = read(random_fd, buf, secKeyLen);
3917 if (nread <= 0 || nread != secKeyLen) {
3918 rv = KMF_ERR_KEYGEN_FAILED;
3919 goto out;
3920 }
3921 }
3922
3923 /*
3924 * Authenticate into the token and call C_CreateObject to generate
3925 * a generic secret token key.
3926 */
3927 rv = pk11_authenticate(handle, cred);
3928 if (rv != KMF_OK) {
3929 goto out;
3930 }
3931
3932 i = 0;
3933 SETATTR(templ, i, CKA_CLASS, &class, sizeof (class));
3934 i++;
3935 SETATTR(templ, i, CKA_KEY_TYPE, &secKeyType, sizeof (secKeyType));
3936 i++;
3937 SETATTR(templ, i, CKA_VALUE, buf, secKeyLen);
3938 i++;
3939
3940 if (keylabel != NULL) {
3941 SETATTR(templ, i, CKA_LABEL, keylabel, strlen(keylabel));
3942 i++;
3943 }
3944
3945 if (is_sensitive == B_TRUE) {
3946 SETATTR(templ, i, CKA_SENSITIVE, &true, sizeof (true));
3947 } else {
3948 SETATTR(templ, i, CKA_SENSITIVE, &false, sizeof (false));
3949 }
3950 i++;
3951
3952 if (is_not_extractable == B_TRUE) {
3953 SETATTR(templ, i, CKA_EXTRACTABLE, &false, sizeof (false));
3954 } else {
3955 SETATTR(templ, i, CKA_EXTRACTABLE, &true, sizeof (true));
3956 }
3957 i++;
3958
3959 SETATTR(templ, i, CKA_TOKEN, &true, sizeof (true));
3960 i++;
3961 SETATTR(templ, i, CKA_PRIVATE, &true, sizeof (true));
3962 i++;
3963 SETATTR(templ, i, CKA_SIGN, &true, sizeof (true));
3964 i++;
3965
3966 ckrv = C_CreateObject(hSession, templ, i, key);
3967 if (ckrv != CKR_OK) {
3968 if (ckrv == CKR_USER_NOT_LOGGED_IN ||
3969 ckrv == CKR_PIN_INCORRECT ||
3970 ckrv == CKR_PIN_INVALID ||
3971 ckrv == CKR_PIN_EXPIRED ||
3972 ckrv == CKR_PIN_LOCKED ||
3973 ckrv == CKR_SESSION_READ_ONLY)
3974 rv = KMF_ERR_AUTH_FAILED;
3975 else
3976 rv = KMF_ERR_KEYGEN_FAILED;
3977 SET_ERROR(kmfh, ckrv);
3978 }
3979
3980 out:
3981 if (buf != NULL && freebuf)
3982 free(buf);
3983
3984 if (random_fd != -1)
3985 (void) close(random_fd);
3986
3987 return (rv);
3988 }
3989
3990 KMF_RETURN
KMFPK11_StoreKey(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attlist)3991 KMFPK11_StoreKey(KMF_HANDLE_T handle,
3992 int numattr,
3993 KMF_ATTRIBUTE *attlist)
3994 {
3995 KMF_RETURN rv = KMF_OK;
3996 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
3997 KMF_CREDENTIAL cred = { NULL, 0 };
3998 KMF_KEY_HANDLE *key;
3999 KMF_RAW_KEY_DATA *rawkey = NULL;
4000 CK_BBOOL btrue = TRUE;
4001 CK_ATTRIBUTE tokenattr[1];
4002 CK_OBJECT_HANDLE newobj;
4003 CK_RV ckrv;
4004
4005 if (kmfh == NULL)
4006 return (KMF_ERR_UNINITIALIZED);
4007
4008 if (kmfh->pk11handle == CK_INVALID_HANDLE)
4009 return (KMF_ERR_NO_TOKEN_SELECTED);
4010
4011 rv = kmf_get_attr(KMF_CREDENTIAL_ATTR, attlist, numattr,
4012 (void *)&cred, NULL);
4013 if (rv != KMF_OK)
4014 return (KMF_ERR_BAD_PARAMETER);
4015
4016 rv = pk11_authenticate(handle, &cred);
4017 if (rv != KMF_OK)
4018 return (rv);
4019
4020 key = kmf_get_attr_ptr(KMF_PUBKEY_HANDLE_ATTR, attlist, numattr);
4021 if (key == NULL) {
4022 key = kmf_get_attr_ptr(KMF_PRIVKEY_HANDLE_ATTR, attlist,
4023 numattr);
4024 if (key == NULL)
4025 rawkey = kmf_get_attr_ptr(KMF_RAW_KEY_ATTR, attlist,
4026 numattr);
4027 }
4028 if (key == NULL && rawkey == NULL)
4029 return (KMF_ERR_ATTR_NOT_FOUND);
4030
4031 if (rawkey != NULL) {
4032 rv = store_raw_key(handle, attlist, numattr, rawkey);
4033 } else if (key && key->kstype == KMF_KEYSTORE_PK11TOKEN) {
4034
4035 SETATTR(tokenattr, 0, CKA_TOKEN, &btrue, sizeof (btrue));
4036 /* Copy the key object to the token */
4037 ckrv = C_CopyObject(kmfh->pk11handle,
4038 (CK_OBJECT_HANDLE)key->keyp, tokenattr, 1, &newobj);
4039 if (ckrv != CKR_OK) {
4040 SET_ERROR(kmfh, ckrv);
4041 return (KMF_ERR_INTERNAL);
4042 }
4043
4044 /* Replace the object handle with the new token-based one */
4045 ckrv = C_DestroyObject(kmfh->pk11handle,
4046 (CK_OBJECT_HANDLE)key->keyp);
4047 if (ckrv != CKR_OK) {
4048 SET_ERROR(kmfh, ckrv);
4049 return (KMF_ERR_INTERNAL);
4050 }
4051 key->keyp = (void *)newobj;
4052 } else {
4053 rv = KMF_ERR_BAD_PARAMETER;
4054 }
4055
4056 return (rv);
4057 }
4058
4059
4060 KMF_RETURN
KMFPK11_ExportPK12(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)4061 KMFPK11_ExportPK12(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
4062 {
4063 KMF_RETURN rv = KMF_OK;
4064 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
4065 KMF_CREDENTIAL *cred = NULL;
4066 KMF_CREDENTIAL *p12cred = NULL;
4067 char *filename = NULL;
4068 KMF_X509_DER_CERT *certlist = NULL;
4069 KMF_KEY_HANDLE *keylist = NULL;
4070 uint32_t numcerts;
4071 uint32_t numkeys;
4072 char *certlabel = NULL;
4073 char *issuer = NULL;
4074 char *subject = NULL;
4075 KMF_BIGINT *serial = NULL;
4076 KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_PK11TOKEN;
4077 KMF_ATTRIBUTE fc_attrlist[16];
4078 int i;
4079
4080 if (kmfh == NULL)
4081 return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */
4082
4083 if (kmfh->pk11handle == CK_INVALID_HANDLE)
4084 return (KMF_ERR_NO_TOKEN_SELECTED);
4085
4086 /* First get the required attributes */
4087 cred = kmf_get_attr_ptr(KMF_CREDENTIAL_ATTR, attrlist, numattr);
4088 if (cred == NULL)
4089 return (KMF_ERR_BAD_PARAMETER);
4090
4091 p12cred = kmf_get_attr_ptr(KMF_PK12CRED_ATTR, attrlist, numattr);
4092 if (p12cred == NULL)
4093 return (KMF_ERR_BAD_PARAMETER);
4094
4095 filename = kmf_get_attr_ptr(KMF_OUTPUT_FILENAME_ATTR, attrlist,
4096 numattr);
4097 if (filename == NULL)
4098 return (KMF_ERR_BAD_PARAMETER);
4099
4100 /* Find all the certificates that match the searching criteria */
4101 i = 0;
4102 kmf_set_attr_at_index(fc_attrlist, i,
4103 KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype));
4104 i++;
4105
4106 kmf_set_attr_at_index(fc_attrlist, i,
4107 KMF_COUNT_ATTR, &numcerts, sizeof (uint32_t));
4108 i++;
4109
4110 certlabel = kmf_get_attr_ptr(KMF_CERT_LABEL_ATTR, attrlist, numattr);
4111 if (certlabel != NULL) {
4112 kmf_set_attr_at_index(fc_attrlist, i,
4113 KMF_CERT_LABEL_ATTR, certlabel, strlen(certlabel));
4114 i++;
4115 }
4116
4117 issuer = kmf_get_attr_ptr(KMF_ISSUER_NAME_ATTR, attrlist, numattr);
4118 if (issuer != NULL) {
4119 kmf_set_attr_at_index(fc_attrlist, i,
4120 KMF_ISSUER_NAME_ATTR, issuer, strlen(issuer));
4121 i++;
4122 }
4123
4124 subject = kmf_get_attr_ptr(KMF_SUBJECT_NAME_ATTR, attrlist, numattr);
4125 if (subject != NULL) {
4126 kmf_set_attr_at_index(fc_attrlist, i,
4127 KMF_SUBJECT_NAME_ATTR, subject, strlen(subject));
4128 i++;
4129 }
4130
4131 serial = kmf_get_attr_ptr(KMF_BIGINT_ATTR, attrlist, numattr);
4132 if (serial != NULL) {
4133 kmf_set_attr_at_index(fc_attrlist, i,
4134 KMF_BIGINT_ATTR, serial, sizeof (KMF_BIGINT));
4135 i++;
4136 }
4137
4138 rv = KMFPK11_FindCert(handle, i, fc_attrlist);
4139
4140 if (rv == KMF_OK && numcerts > 0) {
4141 certlist = (KMF_X509_DER_CERT *)malloc(numcerts *
4142 sizeof (KMF_X509_DER_CERT));
4143 if (certlist == NULL)
4144 return (KMF_ERR_MEMORY);
4145
4146 (void) memset(certlist, 0, numcerts *
4147 sizeof (KMF_X509_DER_CERT));
4148
4149 kmf_set_attr_at_index(fc_attrlist, i, KMF_X509_DER_CERT_ATTR,
4150 certlist, sizeof (KMF_X509_DER_CERT));
4151 i++;
4152
4153 rv = kmf_find_cert(handle, i, fc_attrlist);
4154 if (rv != KMF_OK) {
4155 free(certlist);
4156 return (rv);
4157 }
4158 } else {
4159 return (rv);
4160 }
4161
4162 /* For each certificate, find the matching private key */
4163 numkeys = 0;
4164 for (i = 0; i < numcerts; i++) {
4165 KMF_ATTRIBUTE fk_attrlist[16];
4166 int j = 0;
4167 KMF_KEY_HANDLE newkey;
4168 KMF_ENCODE_FORMAT format = KMF_FORMAT_RAWKEY;
4169
4170 kmf_set_attr_at_index(fk_attrlist, j,
4171 KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype));
4172 j++;
4173
4174 kmf_set_attr_at_index(fk_attrlist, j,
4175 KMF_ENCODE_FORMAT_ATTR, &format, sizeof (format));
4176 j++;
4177
4178 kmf_set_attr_at_index(fk_attrlist, j,
4179 KMF_CREDENTIAL_ATTR, cred, sizeof (KMF_CREDENTIAL));
4180 j++;
4181
4182 kmf_set_attr_at_index(fk_attrlist, j,
4183 KMF_CERT_DATA_ATTR, &certlist[i].certificate,
4184 sizeof (KMF_DATA));
4185 j++;
4186
4187 kmf_set_attr_at_index(fk_attrlist, j,
4188 KMF_KEY_HANDLE_ATTR, &newkey, sizeof (KMF_KEY_HANDLE));
4189 j++;
4190
4191 rv = KMFPK11_FindPrikeyByCert(handle, j, fk_attrlist);
4192 if (rv == KMF_OK) {
4193 numkeys++;
4194 keylist = realloc(keylist,
4195 numkeys * sizeof (KMF_KEY_HANDLE));
4196 if (keylist == NULL) {
4197 rv = KMF_ERR_MEMORY;
4198 goto out;
4199 }
4200 keylist[numkeys - 1] = newkey;
4201 } else if (rv == KMF_ERR_KEY_NOT_FOUND) {
4202 /* it is OK if a key is not found */
4203 rv = KMF_OK;
4204 }
4205 }
4206
4207 if (rv != KMF_OK)
4208 goto out;
4209
4210 rv = kmf_build_pk12(handle, numcerts, certlist, numkeys, keylist,
4211 p12cred, filename);
4212
4213 out:
4214 if (certlist != NULL) {
4215 for (i = 0; i < numcerts; i++)
4216 kmf_free_kmf_cert(handle, &certlist[i]);
4217 free(certlist);
4218 }
4219 if (keylist != NULL) {
4220 for (i = 0; i < numkeys; i++)
4221 kmf_free_kmf_key(handle, &keylist[i]);
4222 free(keylist);
4223 }
4224
4225 return (rv);
4226 }
4227