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 if (EncodedKey) {
1075 if (pKey->keyalg != KMF_ECDSA)
1076 free(EncodedKey->bv_val);
1077 free(EncodedKey);
1078 }
1079
1080 if (PubKeyParams) {
1081 if (pKey->keyalg != KMF_ECDSA)
1082 free(PubKeyParams->bv_val);
1083 free(PubKeyParams);
1084 }
1085
1086 return (ret);
1087 }
1088
1089 static KMF_RETURN
CreateCertObject(KMF_HANDLE_T handle,char * label,KMF_DATA * pcert)1090 CreateCertObject(KMF_HANDLE_T handle, char *label, KMF_DATA *pcert)
1091 {
1092 KMF_RETURN rv = 0;
1093 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
1094
1095 KMF_X509_CERTIFICATE *signed_cert_ptr = NULL;
1096 KMF_DATA data;
1097 KMF_DATA Id;
1098
1099 CK_RV ckrv;
1100 CK_ULONG subject_len, issuer_len, serno_len;
1101 CK_BYTE *subject, *issuer, *serial, nullserno;
1102 CK_BBOOL true = TRUE;
1103 CK_CERTIFICATE_TYPE certtype = CKC_X_509;
1104 CK_OBJECT_CLASS certClass = CKO_CERTIFICATE;
1105 CK_ATTRIBUTE x509templ[11];
1106 CK_OBJECT_HANDLE hCert = 0;
1107 int i;
1108
1109 if (kmfh == NULL)
1110 return (KMF_ERR_INTERNAL); /* should not happen */
1111
1112 if (kmfh->pk11handle == CK_INVALID_HANDLE)
1113 return (KMF_ERR_INTERNAL); /* should not happen */
1114
1115 if (pcert == NULL || pcert->Data == NULL || pcert->Length == 0)
1116 return (KMF_ERR_INTERNAL); /* should not happen */
1117
1118 /*
1119 * The data *must* be a DER encoded X.509 certificate.
1120 * Convert it to a CSSM cert and then parse the fields so
1121 * the PKCS#11 attributes can be filled in correctly.
1122 */
1123 rv = DerDecodeSignedCertificate((const KMF_DATA *)pcert,
1124 &signed_cert_ptr);
1125 if (rv != KMF_OK) {
1126 return (KMF_ERR_ENCODING);
1127 }
1128
1129 /*
1130 * Encode fields into PKCS#11 attributes.
1131 */
1132
1133 /* Get the subject name */
1134 rv = DerEncodeName(&signed_cert_ptr->certificate.subject, &data);
1135 if (rv == KMF_OK) {
1136 subject = data.Data;
1137 subject_len = data.Length;
1138 } else {
1139 rv = KMF_ERR_ENCODING;
1140 goto cleanup;
1141 }
1142
1143 /* Encode the issuer */
1144 rv = DerEncodeName(&signed_cert_ptr->certificate.issuer, &data);
1145 if (rv == KMF_OK) {
1146 issuer = data.Data;
1147 issuer_len = data.Length;
1148 } else {
1149 rv = KMF_ERR_ENCODING;
1150 goto cleanup;
1151 }
1152
1153 /* Encode serial number */
1154 if (signed_cert_ptr->certificate.serialNumber.len > 0 &&
1155 signed_cert_ptr->certificate.serialNumber.val != NULL) {
1156 serial = signed_cert_ptr->certificate.serialNumber.val;
1157 serno_len = signed_cert_ptr->certificate.serialNumber.len;
1158 } else {
1159 /*
1160 * RFC3280 says to gracefully handle certs with serial numbers
1161 * of 0.
1162 */
1163 nullserno = '\0';
1164 serial = &nullserno;
1165 serno_len = 1;
1166 }
1167
1168 /* Generate an ID from the SPKI data */
1169 rv = GetIDFromSPKI(&signed_cert_ptr->certificate.subjectPublicKeyInfo,
1170 &Id);
1171
1172 if (rv != KMF_OK) {
1173 goto cleanup;
1174 }
1175
1176 i = 0;
1177 SETATTR(x509templ, i, CKA_CLASS, &certClass, sizeof (certClass)); i++;
1178 SETATTR(x509templ, i, CKA_CERTIFICATE_TYPE, &certtype,
1179 sizeof (certtype));
1180 i++;
1181 SETATTR(x509templ, i, CKA_TOKEN, &true, sizeof (true)); i++;
1182 SETATTR(x509templ, i, CKA_SUBJECT, subject, subject_len); i++;
1183 SETATTR(x509templ, i, CKA_ISSUER, issuer, issuer_len); i++;
1184 SETATTR(x509templ, i, CKA_SERIAL_NUMBER, serial, serno_len); i++;
1185 SETATTR(x509templ, i, CKA_VALUE, pcert->Data, pcert->Length); i++;
1186 SETATTR(x509templ, i, CKA_ID, Id.Data, Id.Length); i++;
1187 if (label != NULL && strlen(label)) {
1188 SETATTR(x509templ, i, CKA_LABEL, label, strlen(label)); i++;
1189 }
1190 /*
1191 * The cert object handle is actually "leaked" here. If the app
1192 * really wants to clean up the data space, it will have to call
1193 * KMF_DeleteCert and specify the softtoken keystore.
1194 */
1195 ckrv = C_CreateObject(kmfh->pk11handle, x509templ, i, &hCert);
1196 if (ckrv != CKR_OK) {
1197 /* Report authentication failures to the caller */
1198 if (ckrv == CKR_USER_NOT_LOGGED_IN ||
1199 ckrv == CKR_PIN_INCORRECT ||
1200 ckrv == CKR_PIN_INVALID ||
1201 ckrv == CKR_PIN_EXPIRED ||
1202 ckrv == CKR_PIN_LOCKED ||
1203 ckrv == CKR_SESSION_READ_ONLY)
1204 rv = KMF_ERR_AUTH_FAILED;
1205 else
1206 rv = KMF_ERR_INTERNAL;
1207 SET_ERROR(kmfh, ckrv);
1208 }
1209 free(subject);
1210 free(issuer);
1211
1212 cleanup:
1213 if (Id.Data != NULL)
1214 free(Id.Data);
1215
1216 if (signed_cert_ptr) {
1217 kmf_free_signed_cert(signed_cert_ptr);
1218 free(signed_cert_ptr);
1219 }
1220 return (rv);
1221 }
1222
1223
1224 KMF_RETURN
KMFPK11_StoreCert(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)1225 KMFPK11_StoreCert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
1226 {
1227 KMF_RETURN rv = 0;
1228 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
1229 KMF_DATA *cert = NULL;
1230 KMF_CREDENTIAL *cred = NULL;
1231 char *label = NULL;
1232
1233 if (kmfh == NULL)
1234 return (KMF_ERR_UNINITIALIZED);
1235
1236 if (kmfh->pk11handle == CK_INVALID_HANDLE)
1237 return (KMF_ERR_NO_TOKEN_SELECTED);
1238
1239 cert = kmf_get_attr_ptr(KMF_CERT_DATA_ATTR, attrlist, numattr);
1240 if (cert == NULL || cert->Data == NULL || cert->Length == 0)
1241 return (KMF_ERR_BAD_PARAMETER);
1242
1243 /* label attribute is optional */
1244 label = kmf_get_attr_ptr(KMF_CERT_LABEL_ATTR, attrlist, numattr);
1245
1246 cred = kmf_get_attr_ptr(KMF_CREDENTIAL_ATTR, attrlist, numattr);
1247 if (cred != NULL) {
1248 rv = pk11_authenticate(handle, cred);
1249 if (rv != KMF_OK)
1250 return (rv);
1251 }
1252
1253 rv = CreateCertObject(handle, label, cert);
1254 return (rv);
1255 }
1256
1257 KMF_RETURN
KMFPK11_ImportCert(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)1258 KMFPK11_ImportCert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
1259 {
1260 KMF_RETURN rv = 0;
1261 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
1262 char *certfile = NULL;
1263 char *label = NULL;
1264 KMF_ENCODE_FORMAT format;
1265 KMF_CREDENTIAL *cred = NULL;
1266 KMF_DATA cert1 = { 0, NULL };
1267 KMF_DATA cert2 = { 0, NULL };
1268
1269 if (kmfh == NULL)
1270 return (KMF_ERR_UNINITIALIZED);
1271
1272 if (kmfh->pk11handle == CK_INVALID_HANDLE)
1273 return (KMF_ERR_NO_TOKEN_SELECTED);
1274
1275 /*
1276 * Get the input cert filename attribute, check if it is a valid
1277 * certificate and auto-detect the file format of it.
1278 */
1279 certfile = kmf_get_attr_ptr(KMF_CERT_FILENAME_ATTR, attrlist, numattr);
1280 if (certfile == NULL)
1281 return (KMF_ERR_BAD_PARAMETER);
1282
1283 rv = kmf_is_cert_file(handle, certfile, &format);
1284 if (rv != KMF_OK)
1285 return (rv);
1286
1287 /* Read in the CERT file */
1288 rv = kmf_read_input_file(handle, certfile, &cert1);
1289 if (rv != KMF_OK) {
1290 return (rv);
1291 }
1292
1293 /* The label attribute is optional */
1294 label = kmf_get_attr_ptr(KMF_CERT_LABEL_ATTR, attrlist, numattr);
1295
1296 /*
1297 * If the input certificate is in PEM format, we need to convert
1298 * it to DER first.
1299 */
1300 if (format == KMF_FORMAT_PEM) {
1301 int derlen;
1302 rv = kmf_pem_to_der(cert1.Data, cert1.Length,
1303 &cert2.Data, &derlen);
1304 if (rv != KMF_OK) {
1305 goto out;
1306 }
1307 cert2.Length = (size_t)derlen;
1308 }
1309
1310 cred = kmf_get_attr_ptr(KMF_CREDENTIAL_ATTR, attrlist, numattr);
1311 if (cred != NULL) {
1312 rv = pk11_authenticate(handle, cred);
1313 if (rv != KMF_OK)
1314 return (rv);
1315 }
1316
1317 rv = CreateCertObject(handle, label,
1318 format == KMF_FORMAT_ASN1 ? &cert1 : &cert2);
1319
1320 out:
1321 if (cert1.Data != NULL) {
1322 free(cert1.Data);
1323 }
1324
1325 if (cert2.Data != NULL) {
1326 free(cert2.Data);
1327 }
1328
1329 return (rv);
1330 }
1331
1332 KMF_RETURN
KMFPK11_DeleteCert(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)1333 KMFPK11_DeleteCert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
1334 {
1335 KMF_RETURN rv = 0;
1336 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
1337 OBJLIST *objlist;
1338 uint32_t numObjects = 0;
1339 char *certlabel = NULL;
1340 char *issuer = NULL;
1341 char *subject = NULL;
1342 KMF_BIGINT *serial = NULL;
1343 KMF_CERT_VALIDITY validity;
1344 boolean_t private;
1345
1346 if (kmfh == NULL)
1347 return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */
1348
1349 if (kmfh->pk11handle == CK_INVALID_HANDLE)
1350 return (KMF_ERR_NO_TOKEN_SELECTED);
1351
1352
1353 /* Get the search criteria attributes. They are all optional. */
1354 certlabel = kmf_get_attr_ptr(KMF_CERT_LABEL_ATTR, attrlist, numattr);
1355 issuer = kmf_get_attr_ptr(KMF_ISSUER_NAME_ATTR, attrlist, numattr);
1356 subject = kmf_get_attr_ptr(KMF_SUBJECT_NAME_ATTR, attrlist, numattr);
1357 serial = kmf_get_attr_ptr(KMF_BIGINT_ATTR, attrlist, numattr);
1358
1359 rv = kmf_get_attr(KMF_CERT_VALIDITY_ATTR, attrlist, numattr,
1360 &validity, NULL);
1361 if (rv != KMF_OK) {
1362 validity = KMF_ALL_CERTS;
1363 rv = KMF_OK;
1364 }
1365
1366 rv = kmf_get_attr(KMF_PRIVATE_BOOL_ATTR, attrlist, numattr,
1367 (void *)&private, NULL);
1368 if (rv != KMF_OK) {
1369 private = B_FALSE;
1370 rv = KMF_OK;
1371 }
1372
1373 /*
1374 * Start searching for certificates that match the criteria and
1375 * delete them.
1376 */
1377 objlist = NULL;
1378 rv = search_certs(handle, certlabel, issuer, subject, serial,
1379 private, validity, &objlist, &numObjects);
1380
1381 if (rv == KMF_OK && objlist != NULL) {
1382 OBJLIST *node = objlist;
1383
1384 while (node != NULL) {
1385 CK_RV ckrv;
1386 ckrv = C_DestroyObject(kmfh->pk11handle, node->handle);
1387 if (ckrv != CKR_OK) {
1388 SET_ERROR(kmfh, ckrv);
1389 rv = KMF_ERR_INTERNAL;
1390 break;
1391 }
1392 node = node->next;
1393 }
1394 free_objlist(objlist);
1395 }
1396
1397 if (rv == KMF_OK && numObjects == 0)
1398 rv = KMF_ERR_CERT_NOT_FOUND;
1399
1400 return (rv);
1401 }
1402
1403 static CK_RV
gendsa_keypair(KMF_HANDLE * kmfh,boolean_t storekey,CK_OBJECT_HANDLE * pubKey,CK_OBJECT_HANDLE * priKey)1404 gendsa_keypair(KMF_HANDLE *kmfh, boolean_t storekey,
1405 CK_OBJECT_HANDLE *pubKey,
1406 CK_OBJECT_HANDLE *priKey)
1407 {
1408 CK_RV ckrv = CKR_OK;
1409 CK_SESSION_HANDLE hSession = kmfh->pk11handle;
1410 static CK_ULONG dsaKeyType = CKK_DSA;
1411 static CK_BBOOL true = TRUE;
1412 static CK_BBOOL false = FALSE;
1413 static CK_OBJECT_CLASS priClass = CKO_PRIVATE_KEY;
1414 static CK_OBJECT_CLASS pubClass = CKO_PUBLIC_KEY;
1415
1416 static CK_BYTE ckDsaPrime[128] = {
1417 0xb2, 0x6b, 0xc3, 0xfb, 0xe3, 0x26, 0xf4, 0xc2,
1418 0xcf, 0xdd, 0xf9, 0xae, 0x3e, 0x39, 0x7f, 0x9c,
1419 0xa7, 0x73, 0xc3, 0x00, 0xa3, 0x50, 0x67, 0xc3,
1420 0xab, 0x49, 0x2c, 0xea, 0x59, 0x10, 0xa4, 0xbc,
1421 0x09, 0x94, 0xa9, 0x05, 0x3b, 0x0d, 0x35, 0x3c,
1422 0x55, 0x52, 0x47, 0xf0, 0xe3, 0x72, 0x5b, 0xe8,
1423 0x72, 0xa0, 0x71, 0x1c, 0x23, 0x4f, 0x6d, 0xe8,
1424 0xac, 0xe5, 0x21, 0x1b, 0xc0, 0xd8, 0x42, 0xd3,
1425 0x87, 0xae, 0x83, 0x5e, 0x52, 0x7e, 0x46, 0x09,
1426 0xb5, 0xc7, 0x3d, 0xd6, 0x00, 0xf5, 0xf2, 0x9c,
1427 0x84, 0x30, 0x81, 0x7e, 0x7b, 0x30, 0x5b, 0xd5,
1428 0xab, 0xd0, 0x2f, 0x21, 0xb3, 0xd8, 0xed, 0xdb,
1429 0x97, 0x77, 0xe4, 0x7e, 0x6c, 0xcc, 0xb9, 0x6b,
1430 0xdd, 0xaa, 0x96, 0x04, 0xe7, 0xd4, 0x55, 0x11,
1431 0x53, 0xab, 0xba, 0x95, 0x9a, 0xa2, 0x8c, 0x27,
1432 0xd9, 0xcf, 0xad, 0xf3, 0xcf, 0x3a, 0x0c, 0x4b};
1433
1434 static CK_BYTE ckDsaSubPrime[20] = {
1435 0xa4, 0x5f, 0x2a, 0x27, 0x09, 0x49, 0xb6, 0xfe,
1436 0x73, 0xeb, 0x95, 0x7d, 0x00, 0xf3, 0x42, 0xfc,
1437 0x78, 0x47, 0xb0, 0xd5};
1438
1439 static CK_BYTE ckDsaBase[128] = {
1440 0x5c, 0x57, 0x16, 0x49, 0xef, 0xc8, 0xfb, 0x4b,
1441 0xee, 0x07, 0x45, 0x3b, 0x6a, 0x1d, 0xf3, 0xe5,
1442 0xeb, 0xee, 0xad, 0x11, 0x13, 0xe3, 0x52, 0xe3,
1443 0x0d, 0xc0, 0x21, 0x25, 0xfa, 0xf0, 0x93, 0x1c,
1444 0x53, 0x4d, 0xdc, 0x0d, 0x76, 0xd2, 0xfe, 0xc2,
1445 0xd7, 0x72, 0x64, 0x69, 0x53, 0x3d, 0x33, 0xbd,
1446 0xe1, 0x34, 0xf2, 0x5a, 0x67, 0x83, 0xe0, 0xd3,
1447 0x1c, 0xd6, 0x41, 0x4d, 0x16, 0xe8, 0x6c, 0x5a,
1448 0x07, 0x95, 0x21, 0x9a, 0xa3, 0xc4, 0xb9, 0x05,
1449 0x9d, 0x11, 0xcb, 0xc8, 0xc4, 0x9d, 0x00, 0x1a,
1450 0xf4, 0x85, 0x2a, 0xa9, 0x20, 0x3c, 0xba, 0x67,
1451 0xe5, 0xed, 0x31, 0xb2, 0x11, 0xfb, 0x1f, 0x73,
1452 0xec, 0x61, 0x29, 0xad, 0xc7, 0x68, 0xb2, 0x3f,
1453 0x38, 0xea, 0xd9, 0x87, 0x83, 0x9e, 0x7e, 0x19,
1454 0x18, 0xdd, 0xc2, 0xc3, 0x5b, 0x16, 0x6d, 0xce,
1455 0xcf, 0x88, 0x91, 0x07, 0xe0, 0x2b, 0xa8, 0x54 };
1456
1457 static CK_ATTRIBUTE ckDsaPubKeyTemplate[] = {
1458 { CKA_CLASS, &pubClass, sizeof (pubClass) },
1459 { CKA_KEY_TYPE, &dsaKeyType, sizeof (dsaKeyType) },
1460 { CKA_TOKEN, &true, sizeof (true)},
1461 { CKA_PRIVATE, &false, sizeof (false)},
1462 { CKA_PRIME, &ckDsaPrime, sizeof (ckDsaPrime) },
1463 { CKA_SUBPRIME, &ckDsaSubPrime, sizeof (ckDsaSubPrime)},
1464 { CKA_BASE, &ckDsaBase, sizeof (ckDsaBase) },
1465 { CKA_VERIFY, &true, sizeof (true) },
1466 };
1467
1468 #define NUMBER_DSA_PUB_TEMPLATES (sizeof (ckDsaPubKeyTemplate) / \
1469 sizeof (CK_ATTRIBUTE))
1470 #define MAX_DSA_PUB_TEMPLATES (sizeof (ckDsaPubKeyTemplate) / \
1471 sizeof (CK_ATTRIBUTE))
1472
1473 static CK_ATTRIBUTE ckDsaPriKeyTemplate[] = {
1474 {CKA_CLASS, &priClass, sizeof (priClass)},
1475 {CKA_KEY_TYPE, &dsaKeyType, sizeof (dsaKeyType)},
1476 {CKA_TOKEN, &true, sizeof (true)},
1477 {CKA_PRIVATE, &true, sizeof (true)},
1478 {CKA_SIGN, &true, sizeof (true)},
1479 };
1480
1481 #define NUMBER_DSA_PRI_TEMPLATES (sizeof (ckDsaPriKeyTemplate) / \
1482 sizeof (CK_ATTRIBUTE))
1483 #define MAX_DSA_PRI_TEMPLATES (sizeof (ckDsaPriKeyTemplate) / \
1484 sizeof (CK_ATTRIBUTE))
1485 CK_MECHANISM keyGenMech = {CKM_DSA_KEY_PAIR_GEN, NULL, 0};
1486
1487 SETATTR(ckDsaPriKeyTemplate, 2, CKA_TOKEN,
1488 (storekey ? &true : &false), sizeof (CK_BBOOL));
1489
1490 ckrv = C_GenerateKeyPair(hSession, &keyGenMech,
1491 ckDsaPubKeyTemplate,
1492 (sizeof (ckDsaPubKeyTemplate)/sizeof (CK_ATTRIBUTE)),
1493 ckDsaPriKeyTemplate,
1494 (sizeof (ckDsaPriKeyTemplate)/sizeof (CK_ATTRIBUTE)),
1495 pubKey, priKey);
1496 if (ckrv != CKR_OK) {
1497 SET_ERROR(kmfh, ckrv);
1498 return (KMF_ERR_KEYGEN_FAILED);
1499 }
1500
1501 return (ckrv);
1502 }
1503
1504 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)1505 genrsa_keypair(KMF_HANDLE *kmfh, CK_ULONG modulusBits,
1506 boolean_t storekey, KMF_BIGINT *rsaexp,
1507 CK_OBJECT_HANDLE *pubKey,
1508 CK_OBJECT_HANDLE *priKey)
1509 {
1510 CK_RV ckrv = CKR_OK;
1511 CK_SESSION_HANDLE hSession = kmfh->pk11handle;
1512 CK_ATTRIBUTE rsaPubKeyTemplate[16];
1513 CK_ATTRIBUTE rsaPriKeyTemplate[16];
1514 CK_MECHANISM keyGenMech = {CKM_RSA_PKCS_KEY_PAIR_GEN, NULL, 0};
1515 int numpubattr = 0, numpriattr = 0;
1516 static CK_BYTE PubExpo[3] = {0x01, 0x00, 0x01};
1517 static CK_BBOOL true = TRUE;
1518 static CK_BBOOL false = FALSE;
1519
1520 SETATTR(rsaPubKeyTemplate, numpubattr, CKA_TOKEN,
1521 (storekey ? &true : &false), sizeof (CK_BBOOL));
1522 numpubattr++;
1523
1524 SETATTR(rsaPubKeyTemplate, numpubattr, CKA_MODULUS_BITS,
1525 &modulusBits, sizeof (modulusBits));
1526 numpubattr++;
1527
1528 if (rsaexp != NULL && (rsaexp->len > 0 && rsaexp->val != NULL)) {
1529 SETATTR(rsaPubKeyTemplate, numpubattr,
1530 CKA_PUBLIC_EXPONENT,
1531 rsaexp->val, rsaexp->len);
1532 numpubattr++;
1533 } else {
1534 SETATTR(rsaPubKeyTemplate, numpubattr,
1535 CKA_PUBLIC_EXPONENT, &PubExpo, sizeof (PubExpo));
1536 numpubattr++;
1537 }
1538 SETATTR(rsaPubKeyTemplate, numpubattr, CKA_ENCRYPT,
1539 &true, sizeof (true));
1540 numpubattr++;
1541 SETATTR(rsaPubKeyTemplate, numpubattr, CKA_VERIFY,
1542 &true, sizeof (true));
1543 numpubattr++;
1544 SETATTR(rsaPubKeyTemplate, numpubattr, CKA_WRAP,
1545 &true, sizeof (true));
1546 numpubattr++;
1547
1548 SETATTR(rsaPriKeyTemplate, numpriattr, CKA_TOKEN,
1549 (storekey ? &true : &false), sizeof (CK_BBOOL));
1550 numpriattr++;
1551 SETATTR(rsaPriKeyTemplate, numpriattr, CKA_PRIVATE, &true,
1552 sizeof (true));
1553 numpriattr++;
1554 SETATTR(rsaPriKeyTemplate, numpriattr, CKA_DECRYPT, &true,
1555 sizeof (true));
1556 numpriattr++;
1557 SETATTR(rsaPriKeyTemplate, numpriattr, CKA_SIGN, &true,
1558 sizeof (true));
1559 numpriattr++;
1560 SETATTR(rsaPriKeyTemplate, numpriattr, CKA_UNWRAP, &true,
1561 sizeof (true));
1562 numpriattr++;
1563
1564 ckrv = C_GenerateKeyPair(hSession, &keyGenMech,
1565 rsaPubKeyTemplate, numpubattr,
1566 rsaPriKeyTemplate, numpriattr,
1567 pubKey, priKey);
1568 if (ckrv != CKR_OK) {
1569 SET_ERROR(kmfh, ckrv);
1570 return (ckrv);
1571 }
1572
1573 return (ckrv);
1574 }
1575
1576 static CK_RV
genecc_keypair(KMF_HANDLE * kmfh,boolean_t ontoken,KMF_OID * curveoid,CK_OBJECT_HANDLE * pubKey,CK_OBJECT_HANDLE * priKey)1577 genecc_keypair(KMF_HANDLE *kmfh,
1578 boolean_t ontoken,
1579 KMF_OID *curveoid,
1580 CK_OBJECT_HANDLE *pubKey,
1581 CK_OBJECT_HANDLE *priKey)
1582 {
1583 CK_RV ckrv;
1584 CK_SESSION_HANDLE hSession = kmfh->pk11handle;
1585 CK_MECHANISM keyGenMech = {CKM_EC_KEY_PAIR_GEN, NULL, 0};
1586 const ulong_t publicKey = CKO_PUBLIC_KEY;
1587 const ulong_t privateKey = CKO_PRIVATE_KEY;
1588 const ulong_t keytype = CKK_EC;
1589 static CK_BBOOL true = TRUE;
1590 static CK_BBOOL false = FALSE;
1591 CK_ATTRIBUTE public_template[6];
1592 CK_ATTRIBUTE private_template[6];
1593 int numpubattr, numpriattr;
1594
1595 numpubattr = 0;
1596 SETATTR(public_template, numpubattr, CKA_CLASS,
1597 &publicKey, sizeof (publicKey));
1598 numpubattr++;
1599 SETATTR(public_template, numpubattr, CKA_KEY_TYPE,
1600 &keytype, sizeof (keytype));
1601 numpubattr++;
1602 SETATTR(public_template, numpubattr, CKA_EC_PARAMS,
1603 curveoid->Data, curveoid->Length);
1604 numpubattr++;
1605 SETATTR(public_template, numpubattr, CKA_TOKEN,
1606 ontoken ? &true : &false, sizeof (true));
1607 numpubattr++;
1608 SETATTR(public_template, numpubattr, CKA_VERIFY,
1609 &true, sizeof (true));
1610 numpubattr++;
1611 SETATTR(public_template, numpubattr, CKA_PRIVATE,
1612 &false, sizeof (false));
1613 numpubattr++;
1614
1615 numpriattr = 0;
1616 SETATTR(private_template, numpriattr, CKA_CLASS,
1617 &privateKey, sizeof (privateKey));
1618 numpriattr++;
1619 SETATTR(private_template, numpriattr, CKA_KEY_TYPE,
1620 &keytype, sizeof (keytype));
1621 numpriattr++;
1622 SETATTR(private_template, numpriattr, CKA_TOKEN,
1623 ontoken ? &true : &false, sizeof (true));
1624 numpriattr++;
1625 SETATTR(private_template, numpriattr, CKA_PRIVATE,
1626 &true, sizeof (true));
1627 numpriattr++;
1628 SETATTR(private_template, numpriattr, CKA_SIGN,
1629 &true, sizeof (true));
1630 numpriattr++;
1631 SETATTR(private_template, numpriattr, CKA_DERIVE,
1632 &true, sizeof (true));
1633 numpriattr++;
1634
1635 ckrv = C_GenerateKeyPair(hSession, &keyGenMech,
1636 public_template, numpubattr,
1637 private_template, numpriattr,
1638 pubKey, priKey);
1639 if (ckrv != CKR_OK) {
1640 SET_ERROR(kmfh, ckrv);
1641 return (ckrv);
1642 }
1643
1644 return (ckrv);
1645 }
1646
1647 KMF_RETURN
KMFPK11_CreateKeypair(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attlist)1648 KMFPK11_CreateKeypair(KMF_HANDLE_T handle,
1649 int numattr,
1650 KMF_ATTRIBUTE *attlist)
1651 {
1652 KMF_RETURN rv = KMF_OK;
1653 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
1654 KMF_DATA IDInput, IDOutput;
1655 KMF_CREDENTIAL *cred;
1656 KMF_KEY_ALG keytype = KMF_RSA;
1657 KMF_KEY_HANDLE *pubkey, *privkey;
1658
1659 CK_RV ckrv = 0;
1660 CK_SESSION_HANDLE hSession = kmfh->pk11handle;
1661 CK_ATTRIBUTE labelattr[1];
1662 CK_ATTRIBUTE idattr[1];
1663 CK_OBJECT_HANDLE pubKey, priKey;
1664
1665 char IDHashData[SHA1_HASH_LENGTH];
1666 static CK_ULONG modulusBits = 1024;
1667 uint32_t modulusBits_size = sizeof (CK_ULONG);
1668 SHA1_CTX ctx;
1669 boolean_t storekey = TRUE;
1670 char *keylabel = NULL;
1671
1672 if (kmfh == NULL)
1673 return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */
1674
1675 if (kmfh->pk11handle == CK_INVALID_HANDLE)
1676 return (KMF_ERR_NO_TOKEN_SELECTED);
1677
1678 /* "storekey" is optional. Default is TRUE */
1679 (void) kmf_get_attr(KMF_STOREKEY_BOOL_ATTR, attlist, numattr,
1680 &storekey, NULL);
1681
1682 cred = kmf_get_attr_ptr(KMF_CREDENTIAL_ATTR, attlist, numattr);
1683 if (cred == NULL)
1684 return (KMF_ERR_BAD_PARAMETER);
1685
1686 rv = pk11_authenticate(handle, cred);
1687 if (rv != KMF_OK)
1688 return (rv);
1689
1690 /* keytype is optional. KMF_RSA is default */
1691 (void) kmf_get_attr(KMF_KEYALG_ATTR, attlist, numattr,
1692 (void *)&keytype, NULL);
1693
1694 pubkey = kmf_get_attr_ptr(KMF_PUBKEY_HANDLE_ATTR, attlist, numattr);
1695 if (pubkey == NULL)
1696 return (KMF_ERR_BAD_PARAMETER);
1697
1698 privkey = kmf_get_attr_ptr(KMF_PRIVKEY_HANDLE_ATTR, attlist, numattr);
1699 if (privkey == NULL)
1700 return (KMF_ERR_BAD_PARAMETER);
1701
1702 (void) memset(pubkey, 0, sizeof (KMF_KEY_HANDLE));
1703 (void) memset(privkey, 0, sizeof (KMF_KEY_HANDLE));
1704 if (keytype == KMF_RSA) {
1705 CK_BYTE *modulus = NULL;
1706 CK_ULONG modulusLength = 0;
1707 KMF_BIGINT *rsaexp = NULL;
1708 CK_ATTRIBUTE modattr[1];
1709
1710 rv = kmf_get_attr(KMF_KEYLENGTH_ATTR, attlist, numattr,
1711 &modulusBits, &modulusBits_size);
1712 if (rv == KMF_ERR_ATTR_NOT_FOUND)
1713 /* Default modulusBits = 1024 */
1714 rv = KMF_OK;
1715 if (rv != KMF_OK)
1716 return (KMF_ERR_BAD_PARAMETER);
1717
1718 rsaexp = kmf_get_attr_ptr(KMF_RSAEXP_ATTR, attlist, numattr);
1719
1720 /* Generate the RSA keypair */
1721 ckrv = genrsa_keypair(kmfh, modulusBits, storekey,
1722 rsaexp, &pubKey, &priKey);
1723
1724 if (ckrv != CKR_OK)
1725 return (KMF_ERR_BAD_PARAMETER);
1726
1727 privkey->kstype = KMF_KEYSTORE_PK11TOKEN;
1728 privkey->keyalg = KMF_RSA;
1729 privkey->keyclass = KMF_ASYM_PRI;
1730 privkey->keyp = (void *)priKey;
1731
1732 pubkey->kstype = KMF_KEYSTORE_PK11TOKEN;
1733 pubkey->keyalg = KMF_RSA;
1734 pubkey->keyclass = KMF_ASYM_PUB;
1735 pubkey->keyp = (void *)pubKey;
1736
1737 SETATTR(modattr, 0, CKA_MODULUS, NULL, modulusLength);
1738 /* Get the Modulus field to use as input for creating the ID */
1739 ckrv = C_GetAttributeValue(kmfh->pk11handle,
1740 (CK_OBJECT_HANDLE)pubKey, modattr, 1);
1741 if (ckrv != CKR_OK) {
1742 SET_ERROR(kmfh, ckrv);
1743 return (KMF_ERR_BAD_PARAMETER);
1744 }
1745
1746 modulusLength = modattr[0].ulValueLen;
1747 modulus = malloc(modulusLength);
1748 if (modulus == NULL)
1749 return (KMF_ERR_MEMORY);
1750
1751 modattr[0].pValue = modulus;
1752 ckrv = C_GetAttributeValue(kmfh->pk11handle,
1753 (CK_OBJECT_HANDLE)pubKey, modattr, 1);
1754 if (ckrv != CKR_OK) {
1755 SET_ERROR(kmfh, ckrv);
1756 free(modulus);
1757 return (KMF_ERR_BAD_PARAMETER);
1758 }
1759
1760 IDInput.Data = modulus;
1761 IDInput.Length = modulusLength;
1762
1763 } else if (keytype == KMF_DSA) {
1764 CK_BYTE *keyvalue;
1765 CK_ULONG valueLen;
1766 CK_ATTRIBUTE valattr[1];
1767
1768 /* Generate the DSA keypair */
1769 ckrv = gendsa_keypair(kmfh, storekey, &pubKey, &priKey);
1770 if (ckrv != CKR_OK)
1771 return (KMF_ERR_BAD_PARAMETER);
1772
1773 privkey->kstype = KMF_KEYSTORE_PK11TOKEN;
1774 privkey->keyalg = KMF_DSA;
1775 privkey->keyclass = KMF_ASYM_PRI;
1776 privkey->keyp = (void *)priKey;
1777
1778 pubkey->kstype = KMF_KEYSTORE_PK11TOKEN;
1779 pubkey->keyalg = KMF_DSA;
1780 pubkey->keyclass = KMF_ASYM_PUB;
1781 pubkey->keyp = (void *)pubKey;
1782
1783 /* Get the Public Value to use as input for creating the ID */
1784 SETATTR(valattr, 0, CKA_VALUE, NULL, &valueLen);
1785
1786 ckrv = C_GetAttributeValue(hSession,
1787 (CK_OBJECT_HANDLE)pubKey, valattr, 1);
1788 if (ckrv != CKR_OK) {
1789 SET_ERROR(kmfh, ckrv);
1790 return (KMF_ERR_BAD_PARAMETER);
1791 }
1792
1793 valueLen = valattr[0].ulValueLen;
1794 keyvalue = malloc(valueLen);
1795 if (keyvalue == NULL)
1796 return (KMF_ERR_MEMORY);
1797
1798 valattr[0].pValue = keyvalue;
1799 ckrv = C_GetAttributeValue(hSession,
1800 (CK_OBJECT_HANDLE)pubKey, valattr, 1);
1801 if (ckrv != CKR_OK) {
1802 SET_ERROR(kmfh, ckrv);
1803 free(keyvalue);
1804 return (KMF_ERR_BAD_PARAMETER);
1805 }
1806
1807 IDInput.Data = keyvalue;
1808 IDInput.Length = valueLen;
1809 } else if (keytype == KMF_ECDSA) {
1810 CK_BYTE *keyvalue;
1811 CK_ULONG valueLen;
1812 CK_ATTRIBUTE valattr[1];
1813 KMF_OID *eccoid = kmf_get_attr_ptr(KMF_ECC_CURVE_OID_ATTR,
1814 attlist, numattr);
1815
1816 if (eccoid == NULL)
1817 return (KMF_ERR_BAD_PARAMETER);
1818
1819 ckrv = genecc_keypair(kmfh, storekey, eccoid,
1820 &pubKey, &priKey);
1821 if (ckrv != CKR_OK)
1822 return (KMF_ERR_BAD_PARAMETER);
1823
1824 privkey->kstype = KMF_KEYSTORE_PK11TOKEN;
1825 privkey->keyalg = KMF_ECDSA;
1826 privkey->keyclass = KMF_ASYM_PRI;
1827 privkey->keyp = (void *)priKey;
1828
1829 pubkey->kstype = KMF_KEYSTORE_PK11TOKEN;
1830 pubkey->keyalg = KMF_ECDSA;
1831 pubkey->keyclass = KMF_ASYM_PUB;
1832 pubkey->keyp = (void *)pubKey;
1833
1834 /* Get the EC_POINT to use as input for creating the ID */
1835 SETATTR(valattr, 0, CKA_EC_POINT, NULL, &valueLen);
1836
1837 ckrv = C_GetAttributeValue(hSession,
1838 (CK_OBJECT_HANDLE)pubKey, valattr, 1);
1839 if (ckrv != CKR_OK) {
1840 SET_ERROR(kmfh, ckrv);
1841 return (KMF_ERR_BAD_PARAMETER);
1842 }
1843
1844 valueLen = valattr[0].ulValueLen;
1845 keyvalue = malloc(valueLen);
1846 if (keyvalue == NULL)
1847 return (KMF_ERR_MEMORY);
1848
1849 valattr[0].pValue = keyvalue;
1850 ckrv = C_GetAttributeValue(hSession,
1851 (CK_OBJECT_HANDLE)pubKey, valattr, 1);
1852 if (ckrv != CKR_OK) {
1853 SET_ERROR(kmfh, ckrv);
1854 free(keyvalue);
1855 return (KMF_ERR_BAD_PARAMETER);
1856 }
1857
1858 IDInput.Data = keyvalue;
1859 IDInput.Length = valueLen;
1860 } else {
1861 return (KMF_ERR_BAD_PARAMETER);
1862 }
1863
1864 keylabel = kmf_get_attr_ptr(KMF_KEYLABEL_ATTR, attlist, numattr);
1865 if (keylabel != NULL && strlen(keylabel)) {
1866 SETATTR(labelattr, 0, CKA_LABEL, keylabel, strlen(keylabel));
1867
1868 /* Set the CKA_LABEL if one was indicated */
1869 if ((ckrv = C_SetAttributeValue(hSession, pubKey,
1870 labelattr, 1)) != CKR_OK) {
1871 SET_ERROR(kmfh, ckrv);
1872 rv = KMF_ERR_INTERNAL;
1873 goto cleanup;
1874 }
1875 pubkey->keylabel = (char *)strdup(keylabel);
1876 if (pubkey->keylabel == NULL) {
1877 rv = KMF_ERR_MEMORY;
1878 goto cleanup;
1879 }
1880 if ((ckrv = C_SetAttributeValue(hSession, priKey,
1881 labelattr, 1)) != CKR_OK) {
1882 SET_ERROR(kmfh, ckrv);
1883 rv = KMF_ERR_INTERNAL;
1884 goto cleanup;
1885 }
1886 privkey->keylabel = (char *)strdup(keylabel);
1887 if (privkey->keylabel == NULL) {
1888 rv = KMF_ERR_MEMORY;
1889 goto cleanup;
1890 }
1891 } else {
1892 rv = KMF_OK;
1893 }
1894
1895 /* Now, assign a CKA_ID value so it can be searched */
1896 /* ID_Input was assigned above in the RSA or DSA keygen section */
1897 IDOutput.Data = (uchar_t *)IDHashData;
1898 IDOutput.Length = sizeof (IDHashData);
1899
1900 SHA1Init(&ctx);
1901 SHA1Update(&ctx, IDInput.Data, IDInput.Length);
1902 SHA1Final(IDOutput.Data, &ctx);
1903
1904 IDOutput.Length = SHA1_DIGEST_LENGTH;
1905
1906 free(IDInput.Data);
1907
1908 if (rv != CKR_OK) {
1909 goto cleanup;
1910 }
1911 SETATTR(idattr, 0, CKA_ID, IDOutput.Data, IDOutput.Length);
1912 if ((ckrv = C_SetAttributeValue(hSession, pubKey,
1913 idattr, 1)) != CKR_OK) {
1914 SET_ERROR(kmfh, ckrv);
1915 rv = KMF_ERR_INTERNAL;
1916 goto cleanup;
1917 }
1918 if ((ckrv = C_SetAttributeValue(hSession, priKey,
1919 idattr, 1)) != CKR_OK) {
1920 SET_ERROR(kmfh, ckrv);
1921 rv = KMF_ERR_INTERNAL;
1922 goto cleanup;
1923 }
1924
1925 cleanup:
1926 if (rv != KMF_OK) {
1927 if (pubKey != CK_INVALID_HANDLE)
1928 (void) C_DestroyObject(hSession, pubKey);
1929 if (priKey != CK_INVALID_HANDLE)
1930 (void) C_DestroyObject(hSession, priKey);
1931
1932 if (privkey->keylabel)
1933 free(privkey->keylabel);
1934 if (pubkey->keylabel)
1935 free(pubkey->keylabel);
1936 }
1937 return (rv);
1938 }
1939
1940 KMF_RETURN
KMFPK11_DeleteKey(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)1941 KMFPK11_DeleteKey(KMF_HANDLE_T handle,
1942 int numattr, KMF_ATTRIBUTE *attrlist)
1943 {
1944 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
1945 CK_RV ckrv = CKR_OK;
1946 KMF_RETURN rv = KMF_OK;
1947 KMF_KEY_HANDLE *key;
1948 KMF_CREDENTIAL cred;
1949 boolean_t destroy = B_TRUE;
1950
1951 if (kmfh == NULL)
1952 return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */
1953
1954 if (kmfh->pk11handle == CK_INVALID_HANDLE)
1955 return (KMF_ERR_NO_TOKEN_SELECTED);
1956
1957 key = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr);
1958 if (key == NULL || key->keyp == NULL)
1959 return (KMF_ERR_BAD_PARAMETER);
1960
1961 if (key->keyclass != KMF_ASYM_PUB &&
1962 key->keyclass != KMF_ASYM_PRI &&
1963 key->keyclass != KMF_SYMMETRIC)
1964 return (KMF_ERR_BAD_KEY_CLASS);
1965
1966 /* "destroy" is optional. Default is TRUE */
1967 (void) kmf_get_attr(KMF_DESTROY_BOOL_ATTR, attrlist, numattr,
1968 (void *)&destroy, NULL);
1969
1970 if (destroy) {
1971 rv = kmf_get_attr(KMF_CREDENTIAL_ATTR, attrlist, numattr,
1972 (void *)&cred, NULL);
1973 if (rv != KMF_OK)
1974 return (KMF_ERR_BAD_PARAMETER);
1975
1976 rv = pk11_authenticate(handle, &cred);
1977 if (rv != KMF_OK) {
1978 return (rv);
1979 }
1980 }
1981
1982 if (!key->israw && destroy)
1983 ckrv = C_DestroyObject(kmfh->pk11handle,
1984 (CK_OBJECT_HANDLE)key->keyp);
1985
1986 if (ckrv != CKR_OK) {
1987 SET_ERROR(kmfh, ckrv);
1988 /* Report authentication failures to the caller */
1989 if (ckrv == CKR_PIN_EXPIRED || ckrv == CKR_SESSION_READ_ONLY)
1990 rv = KMF_ERR_AUTH_FAILED;
1991 else
1992 rv = KMF_ERR_INTERNAL;
1993 }
1994 return (rv);
1995 }
1996
1997 KMF_RETURN
KMFPK11_SignData(KMF_HANDLE_T handle,KMF_KEY_HANDLE * keyp,KMF_OID * algOID,KMF_DATA * tobesigned,KMF_DATA * output)1998 KMFPK11_SignData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *keyp,
1999 KMF_OID *algOID,
2000 KMF_DATA *tobesigned,
2001 KMF_DATA *output)
2002 {
2003 KMF_RETURN rv = KMF_OK;
2004 CK_RV ckrv;
2005 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
2006 CK_SESSION_HANDLE hSession = kmfh->pk11handle;
2007 CK_MECHANISM mechanism;
2008 CK_MECHANISM_TYPE mechtype, hashmech;
2009 CK_KEY_TYPE keytype;
2010 KMF_ALGORITHM_INDEX AlgId;
2011 KMF_DATA hashData = { 0, NULL };
2012 uchar_t digest[1024];
2013 CK_ATTRIBUTE subprime = { CKA_SUBPRIME, NULL, 0 };
2014
2015 if (kmfh == NULL)
2016 return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */
2017
2018 if (kmfh->pk11handle == CK_INVALID_HANDLE)
2019 return (KMF_ERR_NO_TOKEN_SELECTED);
2020
2021 if (keyp == NULL || algOID == NULL ||
2022 tobesigned == NULL || output == NULL)
2023 return (KMF_ERR_BAD_PARAMETER);
2024
2025 /* These functions are available to the plugin from libkmf */
2026 AlgId = x509_algoid_to_algid(algOID);
2027 if (AlgId == KMF_ALGID_NONE)
2028 return (KMF_ERR_BAD_PARAMETER);
2029
2030 /* Get the PKCS11 signing key type and mechtype */
2031 if (get_pk11_data(AlgId, &keytype, &mechtype, &hashmech, 0))
2032 return (KMF_ERR_BAD_PARAMETER);
2033
2034 (void) memset(digest, 0, sizeof (digest));
2035 hashData.Data = digest;
2036 hashData.Length = sizeof (digest);
2037 rv = PKCS_DigestData(handle, hSession, hashmech, tobesigned, &hashData,
2038 (mechtype == CKM_RSA_PKCS));
2039 if (rv)
2040 return (rv);
2041
2042 if (mechtype == CKM_DSA && hashmech == CKM_SHA256) {
2043 /*
2044 * FIPS 186-3 says that when signing with DSA
2045 * the hash must be truncated to the size of the
2046 * subprime.
2047 */
2048 ckrv = C_GetAttributeValue(hSession,
2049 (CK_OBJECT_HANDLE)keyp->keyp,
2050 &subprime, 1);
2051 if (ckrv != CKR_OK) {
2052 SET_ERROR(kmfh, ckrv);
2053 return (KMF_ERR_INTERNAL);
2054 }
2055 hashData.Length = subprime.ulValueLen;
2056 }
2057
2058 /* the mechtype from the 'get_pk11_info' refers to the signing */
2059 mechanism.mechanism = mechtype;
2060 mechanism.pParameter = NULL;
2061 mechanism.ulParameterLen = 0;
2062
2063 ckrv = C_SignInit(hSession, &mechanism, (CK_OBJECT_HANDLE)keyp->keyp);
2064 if (ckrv != CKR_OK) {
2065 SET_ERROR(kmfh, ckrv);
2066 return (KMF_ERR_INTERNAL);
2067 }
2068
2069 ckrv = C_Sign(hSession, hashData.Data, hashData.Length,
2070 output->Data, (CK_ULONG *)&output->Length);
2071
2072 if (ckrv != CKR_OK) {
2073 SET_ERROR(kmfh, ckrv);
2074 return (KMF_ERR_INTERNAL);
2075 }
2076
2077 return (KMF_OK);
2078 }
2079
2080 KMF_RETURN
KMFPK11_GetErrorString(KMF_HANDLE_T handle,char ** msgstr)2081 KMFPK11_GetErrorString(KMF_HANDLE_T handle, char **msgstr)
2082 {
2083 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
2084
2085 *msgstr = NULL;
2086 if (kmfh->lasterr.errcode != 0) {
2087 char *e = pkcs11_strerror(kmfh->lasterr.errcode);
2088 if (e == NULL || (*msgstr = (char *)strdup(e)) == NULL) {
2089 return (KMF_ERR_MEMORY);
2090 }
2091 }
2092
2093 return (KMF_OK);
2094 }
2095
2096 static CK_RV
getObjectKeytype(KMF_HANDLE_T handle,CK_OBJECT_HANDLE obj,CK_ULONG * keytype)2097 getObjectKeytype(KMF_HANDLE_T handle, CK_OBJECT_HANDLE obj,
2098 CK_ULONG *keytype)
2099 {
2100 CK_RV rv = CKR_OK;
2101 CK_ATTRIBUTE templ;
2102 CK_ULONG len = sizeof (CK_ULONG);
2103 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
2104
2105 templ.type = CKA_KEY_TYPE;
2106 templ.pValue = keytype;
2107 templ.ulValueLen = len;
2108
2109 rv = C_GetAttributeValue(kmfh->pk11handle, obj, &templ, 1);
2110
2111 return (rv);
2112
2113 }
2114
2115 static CK_RV
getObjectLabel(KMF_HANDLE_T handle,CK_OBJECT_HANDLE obj,char ** outlabel)2116 getObjectLabel(KMF_HANDLE_T handle, CK_OBJECT_HANDLE obj,
2117 char **outlabel)
2118 {
2119 CK_RV rv = CKR_OK;
2120 CK_ATTRIBUTE templ;
2121 char Label[BUFSIZ];
2122 CK_ULONG len = sizeof (Label);
2123 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
2124
2125 (void) memset(Label, 0, len);
2126 templ.type = CKA_LABEL;
2127 templ.pValue = Label;
2128 templ.ulValueLen = len;
2129
2130 rv = C_GetAttributeValue(kmfh->pk11handle, obj, &templ, 1);
2131 if (rv == CKR_OK) {
2132 *outlabel = (char *)strdup(Label);
2133 } else {
2134 *outlabel = NULL;
2135 }
2136 return (rv);
2137 }
2138
2139 static CK_RV
getObjectKeyclass(KMF_HANDLE_T handle,CK_OBJECT_HANDLE obj,KMF_KEY_CLASS * keyclass)2140 getObjectKeyclass(KMF_HANDLE_T handle, CK_OBJECT_HANDLE obj,
2141 KMF_KEY_CLASS *keyclass)
2142 {
2143 CK_RV rv = CKR_OK;
2144 CK_ATTRIBUTE templ;
2145 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
2146 CK_OBJECT_CLASS class;
2147
2148 templ.type = CKA_CLASS;
2149 templ.pValue = &class;
2150 templ.ulValueLen = sizeof (CK_OBJECT_CLASS);
2151
2152 rv = C_GetAttributeValue(kmfh->pk11handle, obj, &templ, 1);
2153 if (rv == CKR_OK) {
2154 if (class == CKO_PUBLIC_KEY) {
2155 *keyclass = KMF_ASYM_PUB;
2156 } else if (class == CKO_PRIVATE_KEY) {
2157 *keyclass = KMF_ASYM_PRI;
2158 } else if (class == CKO_SECRET_KEY) {
2159 *keyclass = KMF_SYMMETRIC;
2160 }
2161 } else {
2162 *keyclass = KMF_KEYCLASS_NONE;
2163 }
2164 return (rv);
2165 }
2166
2167 KMF_RETURN
KMFPK11_FindPrikeyByCert(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)2168 KMFPK11_FindPrikeyByCert(KMF_HANDLE_T handle, int numattr,
2169 KMF_ATTRIBUTE *attrlist)
2170 {
2171 KMF_X509_SPKI *pubkey;
2172 KMF_X509_CERTIFICATE *SignerCert = NULL;
2173 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
2174 KMF_RETURN rv = KMF_OK;
2175 CK_RV ckrv = CKR_OK;
2176 CK_ATTRIBUTE templ[4];
2177 CK_OBJECT_HANDLE pri_obj = CK_INVALID_HANDLE;
2178 CK_ULONG obj_count;
2179 CK_OBJECT_CLASS objClass = CKO_PRIVATE_KEY;
2180 CK_BBOOL true = TRUE;
2181 KMF_DATA Id = { 0, NULL };
2182 KMF_KEY_HANDLE *key = NULL;
2183 KMF_DATA *cert = NULL;
2184 KMF_CREDENTIAL cred;
2185 KMF_ENCODE_FORMAT format = KMF_FORMAT_UNDEF;
2186 CK_ULONG keytype;
2187
2188 /* Get the key handle */
2189 key = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr);
2190 if (key == NULL)
2191 return (KMF_ERR_BAD_PARAMETER);
2192
2193 /* Get the optional encoded format */
2194 (void) kmf_get_attr(KMF_ENCODE_FORMAT_ATTR, attrlist, numattr,
2195 (void *)&format, NULL);
2196
2197 /* Decode the signer cert so we can get the SPKI data */
2198 cert = kmf_get_attr_ptr(KMF_CERT_DATA_ATTR, attrlist, numattr);
2199 if (cert == NULL || cert->Data == NULL)
2200 return (KMF_ERR_BAD_PARAMETER);
2201
2202 if ((rv = DerDecodeSignedCertificate(cert,
2203 &SignerCert)) != KMF_OK)
2204 return (rv);
2205
2206 /* Get the public key info from the signer certificate */
2207 pubkey = &SignerCert->certificate.subjectPublicKeyInfo;
2208
2209 /* Generate an ID from the SPKI data */
2210 rv = GetIDFromSPKI(pubkey, &Id);
2211 if (rv != KMF_OK) {
2212 goto errout;
2213 }
2214
2215 /* Get the credential and login */
2216 rv = kmf_get_attr(KMF_CREDENTIAL_ATTR, attrlist, numattr,
2217 (void *)&cred, NULL);
2218 if (rv != KMF_OK)
2219 return (KMF_ERR_BAD_PARAMETER);
2220
2221 rv = pk11_authenticate(handle, &cred);
2222 if (rv != KMF_OK) {
2223 return (rv);
2224 }
2225
2226 /* Start searching */
2227 SETATTR(templ, 0, CKA_CLASS, &objClass, sizeof (objClass));
2228 SETATTR(templ, 1, CKA_TOKEN, &true, sizeof (true));
2229 SETATTR(templ, 2, CKA_PRIVATE, &true, sizeof (true));
2230 SETATTR(templ, 3, CKA_ID, Id.Data, Id.Length);
2231
2232 if ((ckrv = C_FindObjectsInit(kmfh->pk11handle, templ, 4)) != CKR_OK) {
2233 SET_ERROR(kmfh, ckrv);
2234 rv = KMF_ERR_INTERNAL;
2235 goto errout;
2236 }
2237
2238 if ((ckrv = C_FindObjects(kmfh->pk11handle, &pri_obj, 1,
2239 &obj_count)) != CKR_OK) {
2240 SET_ERROR(kmfh, ckrv);
2241 rv = KMF_ERR_INTERNAL;
2242 goto errout;
2243 }
2244
2245 if (obj_count == 0) {
2246 SET_ERROR(kmfh, ckrv);
2247 rv = KMF_ERR_KEY_NOT_FOUND;
2248 goto errout;
2249 }
2250
2251 key->kstype = KMF_KEYSTORE_PK11TOKEN;
2252 key->keyclass = KMF_ASYM_PRI;
2253 key->keyp = (void *)pri_obj;
2254 key->israw = FALSE;
2255
2256 (void) C_FindObjectsFinal(kmfh->pk11handle);
2257
2258 ckrv = getObjectLabel(handle, (CK_OBJECT_HANDLE)key->keyp,
2259 &key->keylabel);
2260 if (ckrv != CKR_OK) {
2261 SET_ERROR(handle, ckrv);
2262 rv = KMF_ERR_INTERNAL;
2263 } else {
2264 rv = KMF_OK;
2265 }
2266
2267 /*
2268 * The key->keyalg value is needed if we need to convert the key
2269 * to raw key. However, the key->keyalg value will not be set if
2270 * this function is not called thru the kmf_find_prikey_by_cert()
2271 * framework function. To be safe, we will get the keytype from
2272 * the key object and set key->keyalg value here.
2273 */
2274 ckrv = getObjectKeytype(handle, (CK_OBJECT_HANDLE)key->keyp,
2275 &keytype);
2276 if (ckrv != CKR_OK) {
2277 SET_ERROR(handle, ckrv);
2278 rv = KMF_ERR_INTERNAL;
2279 } else {
2280 rv = KMF_OK;
2281 }
2282
2283 if (keytype == CKK_RSA)
2284 key->keyalg = KMF_RSA;
2285 else if (keytype == CKK_DSA)
2286 key->keyalg = KMF_DSA;
2287 else if (keytype == CKK_EC)
2288 key->keyalg = KMF_ECDSA;
2289 else {
2290 /* For asymmetric keys, we only support RSA and DSA */
2291 rv = KMF_ERR_KEY_NOT_FOUND;
2292 goto errout;
2293 }
2294
2295 if (rv == KMF_OK && format == KMF_FORMAT_RAWKEY) {
2296 KMF_RAW_KEY_DATA *rkey = NULL;
2297 rv = keyObj2RawKey(handle, key, &rkey);
2298 if (rv == KMF_OK) {
2299 key->keyp = rkey;
2300 key->israw = TRUE;
2301 }
2302 }
2303
2304 errout:
2305 if (Id.Data != NULL)
2306 free(Id.Data);
2307
2308 if (SignerCert != NULL) {
2309 kmf_free_signed_cert(SignerCert);
2310 free(SignerCert);
2311 }
2312 return (rv);
2313 }
2314
2315 KMF_RETURN
KMFPK11_DecryptData(KMF_HANDLE_T handle,KMF_KEY_HANDLE * key,KMF_OID * algOID,KMF_DATA * ciphertext,KMF_DATA * output)2316 KMFPK11_DecryptData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *key,
2317 KMF_OID *algOID, KMF_DATA *ciphertext,
2318 KMF_DATA *output)
2319 {
2320 CK_RV ckrv;
2321 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
2322 CK_SESSION_HANDLE hSession = kmfh->pk11handle;
2323 CK_MECHANISM mechanism;
2324 CK_MECHANISM_TYPE mechtype;
2325 CK_KEY_TYPE keytype;
2326 KMF_ALGORITHM_INDEX AlgId;
2327 CK_ULONG out_len = 0, block_len = 0, total_decrypted = 0;
2328 uint8_t *in_data, *out_data;
2329 int i, blocks;
2330 CK_ATTRIBUTE ckTemplate[1];
2331
2332 if (kmfh == NULL)
2333 return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */
2334
2335 if (kmfh->pk11handle == CK_INVALID_HANDLE)
2336 return (KMF_ERR_NO_TOKEN_SELECTED);
2337
2338 if (key == NULL || algOID == NULL ||
2339 ciphertext == NULL || output == NULL)
2340 return (KMF_ERR_BAD_PARAMETER);
2341
2342 AlgId = x509_algoid_to_algid(algOID);
2343 if (AlgId == KMF_ALGID_NONE)
2344 return (KMF_ERR_BAD_PARAMETER);
2345
2346 /* Map the Algorithm ID to a PKCS#11 mechanism */
2347 if (get_pk11_data(AlgId, &keytype, &mechtype, NULL, 0))
2348 return (KMF_ERR_BAD_PARAMETER);
2349
2350 mechanism.mechanism = mechtype;
2351 mechanism.pParameter = NULL;
2352 mechanism.ulParameterLen = 0;
2353
2354 SETATTR(ckTemplate, 0, CKA_MODULUS, (CK_BYTE *)NULL,
2355 sizeof (CK_ULONG));
2356
2357 /* Get the modulus length */
2358 ckrv = C_GetAttributeValue(hSession,
2359 (CK_OBJECT_HANDLE)key->keyp, ckTemplate, 1);
2360
2361 if (ckrv != CKR_OK) {
2362 SET_ERROR(kmfh, ckrv);
2363 return (KMF_ERR_INTERNAL);
2364 }
2365
2366 block_len = ckTemplate[0].ulValueLen;
2367
2368 /* Compute the number of times to do single-part decryption */
2369 blocks = ciphertext->Length/block_len;
2370
2371 out_data = output->Data;
2372 in_data = ciphertext->Data;
2373 out_len = block_len - 11;
2374
2375 for (i = 0; i < blocks; i++) {
2376 ckrv = C_DecryptInit(hSession, &mechanism,
2377 (CK_OBJECT_HANDLE)key->keyp);
2378
2379 if (ckrv != CKR_OK) {
2380 SET_ERROR(kmfh, ckrv);
2381 return (KMF_ERR_INTERNAL);
2382 }
2383
2384 ckrv = C_Decrypt(hSession, in_data, block_len,
2385 out_data, (CK_ULONG *)&out_len);
2386
2387 if (ckrv != CKR_OK) {
2388 SET_ERROR(kmfh, ckrv);
2389 return (KMF_ERR_INTERNAL);
2390 }
2391
2392 out_data += out_len;
2393 total_decrypted += out_len;
2394 in_data += block_len;
2395
2396 }
2397
2398 output->Length = total_decrypted;
2399 return (KMF_OK);
2400 }
2401
2402 static void
attr2bigint(CK_ATTRIBUTE_PTR attr,KMF_BIGINT * big)2403 attr2bigint(CK_ATTRIBUTE_PTR attr, KMF_BIGINT *big)
2404 {
2405 big->val = attr->pValue;
2406 big->len = attr->ulValueLen;
2407 }
2408
2409 static KMF_RETURN
get_bigint_attr(CK_SESSION_HANDLE sess,CK_OBJECT_HANDLE obj,CK_ATTRIBUTE_TYPE attrtype,KMF_BIGINT * bigint)2410 get_bigint_attr(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj,
2411 CK_ATTRIBUTE_TYPE attrtype, KMF_BIGINT *bigint)
2412 {
2413 CK_RV ckrv;
2414 CK_ATTRIBUTE attr;
2415
2416 attr.type = attrtype;
2417 attr.pValue = NULL;
2418 attr.ulValueLen = 0;
2419
2420 if ((ckrv = C_GetAttributeValue(sess, obj,
2421 &attr, 1)) != CKR_OK) {
2422 /* Mask this error so the caller can continue */
2423 if (ckrv == CKR_ATTRIBUTE_TYPE_INVALID)
2424 return (KMF_OK);
2425 else
2426 return (KMF_ERR_INTERNAL);
2427 }
2428 if (attr.ulValueLen > 0 && bigint != NULL) {
2429 attr.pValue = malloc(attr.ulValueLen);
2430 if (attr.pValue == NULL)
2431 return (KMF_ERR_MEMORY);
2432
2433 if ((ckrv = C_GetAttributeValue(sess, obj,
2434 &attr, 1)) != CKR_OK)
2435 if (ckrv != CKR_OK) {
2436 free(attr.pValue);
2437 return (KMF_ERR_INTERNAL);
2438 }
2439
2440 bigint->val = attr.pValue;
2441 bigint->len = attr.ulValueLen;
2442 }
2443 return (KMF_OK);
2444 }
2445
2446 static KMF_RETURN
get_raw_rsa(KMF_HANDLE * kmfh,CK_OBJECT_HANDLE obj,KMF_RAW_RSA_KEY * rawrsa)2447 get_raw_rsa(KMF_HANDLE *kmfh, CK_OBJECT_HANDLE obj, KMF_RAW_RSA_KEY *rawrsa)
2448 {
2449 KMF_RETURN rv = KMF_OK;
2450 CK_RV ckrv;
2451 CK_SESSION_HANDLE sess = kmfh->pk11handle;
2452 CK_ATTRIBUTE rsa_pri_attrs[2] = {
2453 { CKA_MODULUS, NULL, 0 },
2454 { CKA_PUBLIC_EXPONENT, NULL, 0 }
2455 };
2456 CK_ULONG count = sizeof (rsa_pri_attrs) / sizeof (CK_ATTRIBUTE);
2457 int i;
2458
2459 if (rawrsa == NULL)
2460 return (KMF_ERR_BAD_PARAMETER);
2461
2462 (void) memset(rawrsa, 0, sizeof (KMF_RAW_RSA_KEY));
2463 if ((ckrv = C_GetAttributeValue(sess, obj,
2464 rsa_pri_attrs, count)) != CKR_OK) {
2465 SET_ERROR(kmfh, ckrv);
2466 /* Tell the caller know why the key data cannot be retrieved. */
2467 if (ckrv == CKR_ATTRIBUTE_SENSITIVE)
2468 return (KMF_ERR_SENSITIVE_KEY);
2469 else if (ckrv == CKR_KEY_UNEXTRACTABLE)
2470 return (KMF_ERR_UNEXTRACTABLE_KEY);
2471 else
2472 return (KMF_ERR_INTERNAL);
2473 }
2474
2475 /* Allocate memory for each attribute. */
2476 for (i = 0; i < count; i++) {
2477 if (rsa_pri_attrs[i].ulValueLen == (CK_ULONG)-1 ||
2478 rsa_pri_attrs[i].ulValueLen == 0) {
2479 rsa_pri_attrs[i].ulValueLen = 0;
2480 continue;
2481 }
2482 if ((rsa_pri_attrs[i].pValue =
2483 malloc(rsa_pri_attrs[i].ulValueLen)) == NULL) {
2484 rv = KMF_ERR_MEMORY;
2485 goto end;
2486 }
2487 }
2488 /* Now that we have space, really get the attributes */
2489 if ((ckrv = C_GetAttributeValue(sess, obj,
2490 rsa_pri_attrs, count)) != CKR_OK) {
2491 SET_ERROR(kmfh, ckrv);
2492 rv = KMF_ERR_INTERNAL;
2493 goto end;
2494 }
2495 i = 0;
2496 attr2bigint(&(rsa_pri_attrs[i++]), &rawrsa->mod);
2497 attr2bigint(&(rsa_pri_attrs[i++]), &rawrsa->pubexp);
2498
2499 /* Now get the optional parameters */
2500 rv = get_bigint_attr(sess, obj, CKA_PRIVATE_EXPONENT, &rawrsa->priexp);
2501 if (rv != KMF_OK)
2502 goto end;
2503 rv = get_bigint_attr(sess, obj, CKA_PRIME_1, &rawrsa->prime1);
2504 if (rv != KMF_OK)
2505 goto end;
2506 rv = get_bigint_attr(sess, obj, CKA_PRIME_2, &rawrsa->prime2);
2507 if (rv != KMF_OK)
2508 goto end;
2509 rv = get_bigint_attr(sess, obj, CKA_EXPONENT_1, &rawrsa->exp1);
2510 if (rv != KMF_OK)
2511 goto end;
2512 rv = get_bigint_attr(sess, obj, CKA_EXPONENT_2, &rawrsa->exp2);
2513 if (rv != KMF_OK)
2514 goto end;
2515 rv = get_bigint_attr(sess, obj, CKA_COEFFICIENT, &rawrsa->coef);
2516 if (rv != KMF_OK)
2517 goto end;
2518
2519 end:
2520 if (rv != KMF_OK) {
2521 for (i = 0; i < count; i++) {
2522 if (rsa_pri_attrs[i].pValue != NULL)
2523 free(rsa_pri_attrs[i].pValue);
2524 }
2525 if (rawrsa->priexp.val)
2526 free(rawrsa->priexp.val);
2527 if (rawrsa->prime1.val)
2528 free(rawrsa->prime1.val);
2529 if (rawrsa->prime2.val)
2530 free(rawrsa->prime2.val);
2531 if (rawrsa->exp1.val)
2532 free(rawrsa->exp1.val);
2533 if (rawrsa->exp2.val)
2534 free(rawrsa->exp2.val);
2535 if (rawrsa->coef.val)
2536 free(rawrsa->coef.val);
2537 (void) memset(rawrsa, 0, sizeof (KMF_RAW_RSA_KEY));
2538 }
2539 return (rv);
2540 }
2541
2542 #define DSA_PRIME_BUFSIZE CHARLEN2BIGNUMLEN(1024) /* 8192 bits */
2543 #define DSA_PRIVATE_BUFSIZE BIG_CHUNKS_FOR_160BITS /* 160 bits */
2544
2545 /*
2546 * This function calculates the pubkey value from the prime,
2547 * base and private key values of a DSA key.
2548 */
2549 static KMF_RETURN
compute_dsa_pubvalue(KMF_RAW_DSA_KEY * rawdsa)2550 compute_dsa_pubvalue(KMF_RAW_DSA_KEY *rawdsa)
2551 {
2552 KMF_RETURN rv = KMF_OK;
2553 BIGNUM p, g, x, y;
2554 BIG_ERR_CODE err;
2555 uchar_t *pubvalue;
2556 uint32_t pubvalue_len;
2557
2558 if ((err = big_init1(&p, DSA_PRIME_BUFSIZE, NULL, 0)) != BIG_OK) {
2559 rv = KMF_ERR_MEMORY;
2560 return (rv);
2561 }
2562 bytestring2bignum(&p, rawdsa->prime.val, rawdsa->prime.len);
2563
2564 if ((err = big_init1(&g, DSA_PRIME_BUFSIZE, NULL, 0)) != BIG_OK) {
2565 rv = KMF_ERR_MEMORY;
2566 goto ret1;
2567 }
2568 bytestring2bignum(&g, rawdsa->base.val, rawdsa->base.len);
2569
2570 if ((err = big_init1(&x, DSA_PRIVATE_BUFSIZE, NULL, 0)) != BIG_OK) {
2571 rv = KMF_ERR_MEMORY;
2572 goto ret2;
2573 }
2574 bytestring2bignum(&x, rawdsa->value.val, rawdsa->value.len);
2575
2576 if ((err = big_init1(&y, DSA_PRIME_BUFSIZE, NULL, 0)) != BIG_OK) {
2577 rv = KMF_ERR_MEMORY;
2578 goto ret3;
2579 }
2580
2581 err = big_modexp(&y, &g, &x, &p, NULL);
2582 if (err != BIG_OK) {
2583 rv = KMF_ERR_INTERNAL;
2584 goto ret3;
2585 }
2586
2587 pubvalue_len = y.len * (int)sizeof (uint32_t);
2588 if ((pubvalue = malloc(pubvalue_len)) == NULL) {
2589 rv = KMF_ERR_MEMORY;
2590 goto ret4;
2591 }
2592 bignum2bytestring(pubvalue, &y, pubvalue_len);
2593
2594 rawdsa->pubvalue.val = pubvalue;
2595 rawdsa->pubvalue.len = pubvalue_len;
2596
2597 ret4:
2598 big_finish(&y);
2599 ret3:
2600 big_finish(&x);
2601 ret2:
2602 big_finish(&g);
2603 ret1:
2604 big_finish(&p);
2605 return (rv);
2606 }
2607
2608 static KMF_RETURN
get_raw_ec(KMF_HANDLE * kmfh,CK_OBJECT_HANDLE obj,KMF_RAW_EC_KEY * rawec)2609 get_raw_ec(KMF_HANDLE *kmfh, CK_OBJECT_HANDLE obj, KMF_RAW_EC_KEY *rawec)
2610 {
2611 KMF_RETURN rv = KMF_OK;
2612 CK_RV ckrv;
2613 CK_SESSION_HANDLE sess = kmfh->pk11handle;
2614 CK_ATTRIBUTE ec_attrs[2] = {
2615 { CKA_EC_PARAMS, NULL, 0},
2616 { CKA_VALUE, NULL, 0}
2617 };
2618 CK_ULONG count = sizeof (ec_attrs) / sizeof (CK_ATTRIBUTE);
2619 int i;
2620
2621 if ((ckrv = C_GetAttributeValue(sess, obj,
2622 ec_attrs, 2)) != CKR_OK) {
2623 SET_ERROR(kmfh, ckrv);
2624
2625 /* Tell the caller know why the key data cannot be retrieved. */
2626 if (ckrv == CKR_ATTRIBUTE_SENSITIVE)
2627 return (KMF_ERR_SENSITIVE_KEY);
2628 else if (ckrv == CKR_KEY_UNEXTRACTABLE)
2629 return (KMF_ERR_UNEXTRACTABLE_KEY);
2630 return (KMF_ERR_INTERNAL);
2631 }
2632 for (i = 0; i < count; i++) {
2633 if (ec_attrs[i].ulValueLen == (CK_ULONG)-1 ||
2634 ec_attrs[i].ulValueLen == 0) {
2635 ec_attrs[i].ulValueLen = 0;
2636 continue;
2637 }
2638 if ((ec_attrs[i].pValue =
2639 malloc(ec_attrs[i].ulValueLen)) == NULL) {
2640 rv = KMF_ERR_MEMORY;
2641 goto end;
2642 }
2643 }
2644 if ((ckrv = C_GetAttributeValue(sess, obj,
2645 ec_attrs, count)) != CKR_OK) {
2646 SET_ERROR(kmfh, ckrv);
2647 rv = KMF_ERR_INTERNAL;
2648 goto end;
2649 }
2650
2651 rawec->params.Data = ec_attrs[0].pValue;
2652 rawec->params.Length = ec_attrs[0].ulValueLen;
2653 rawec->value.val = ec_attrs[1].pValue;
2654 rawec->value.len = ec_attrs[1].ulValueLen;
2655
2656 end:
2657 if (rv != KMF_OK) {
2658 for (i = 0; i < count; i++) {
2659 if (ec_attrs[i].pValue != NULL)
2660 free(ec_attrs[i].pValue);
2661 }
2662 (void) memset(rawec, 0, sizeof (KMF_RAW_EC_KEY));
2663 }
2664 return (rv);
2665 }
2666
2667 static KMF_RETURN
get_raw_dsa(KMF_HANDLE * kmfh,CK_OBJECT_HANDLE obj,KMF_RAW_DSA_KEY * rawdsa)2668 get_raw_dsa(KMF_HANDLE *kmfh, CK_OBJECT_HANDLE obj, KMF_RAW_DSA_KEY *rawdsa)
2669 {
2670 KMF_RETURN rv = KMF_OK;
2671 CK_RV ckrv;
2672 CK_SESSION_HANDLE sess = kmfh->pk11handle;
2673 CK_ATTRIBUTE dsa_pri_attrs[8] = {
2674 { CKA_PRIME, NULL, 0 },
2675 { CKA_SUBPRIME, NULL, 0 },
2676 { CKA_BASE, NULL, 0 },
2677 { CKA_VALUE, NULL, 0 }
2678 };
2679 CK_ULONG count = sizeof (dsa_pri_attrs) / sizeof (CK_ATTRIBUTE);
2680 int i;
2681
2682 if ((ckrv = C_GetAttributeValue(sess, obj,
2683 dsa_pri_attrs, count)) != CKR_OK) {
2684 SET_ERROR(kmfh, ckrv);
2685
2686 /* Tell the caller know why the key data cannot be retrieved. */
2687 if (ckrv == CKR_ATTRIBUTE_SENSITIVE)
2688 return (KMF_ERR_SENSITIVE_KEY);
2689 else if (ckrv == CKR_KEY_UNEXTRACTABLE)
2690 return (KMF_ERR_UNEXTRACTABLE_KEY);
2691 return (KMF_ERR_INTERNAL);
2692 }
2693
2694 /* Allocate memory for each attribute. */
2695 for (i = 0; i < count; i++) {
2696 if (dsa_pri_attrs[i].ulValueLen == (CK_ULONG)-1 ||
2697 dsa_pri_attrs[i].ulValueLen == 0) {
2698 dsa_pri_attrs[i].ulValueLen = 0;
2699 continue;
2700 }
2701 if ((dsa_pri_attrs[i].pValue =
2702 malloc(dsa_pri_attrs[i].ulValueLen)) == NULL) {
2703 rv = KMF_ERR_MEMORY;
2704 goto end;
2705 }
2706 }
2707 if ((ckrv = C_GetAttributeValue(sess, obj,
2708 dsa_pri_attrs, count)) != CKR_OK) {
2709 SET_ERROR(kmfh, ckrv);
2710 rv = KMF_ERR_INTERNAL;
2711 goto end;
2712 }
2713
2714 /* Fill in all the temp variables. They are all required. */
2715 i = 0;
2716 attr2bigint(&(dsa_pri_attrs[i++]), &rawdsa->prime);
2717 attr2bigint(&(dsa_pri_attrs[i++]), &rawdsa->subprime);
2718 attr2bigint(&(dsa_pri_attrs[i++]), &rawdsa->base);
2719 attr2bigint(&(dsa_pri_attrs[i++]), &rawdsa->value);
2720
2721 /* Compute the public key value and store it */
2722 rv = compute_dsa_pubvalue(rawdsa);
2723
2724 end:
2725 if (rv != KMF_OK) {
2726 for (i = 0; i < count; i++) {
2727 if (dsa_pri_attrs[i].pValue != NULL)
2728 free(dsa_pri_attrs[i].pValue);
2729 }
2730 (void) memset(rawdsa, 0, sizeof (KMF_RAW_DSA_KEY));
2731 }
2732 return (rv);
2733 }
2734
2735 static KMF_RETURN
get_raw_sym(KMF_HANDLE * kmfh,CK_OBJECT_HANDLE obj,KMF_RAW_SYM_KEY * rawsym)2736 get_raw_sym(KMF_HANDLE *kmfh, CK_OBJECT_HANDLE obj, KMF_RAW_SYM_KEY *rawsym)
2737 {
2738 KMF_RETURN rv = KMF_OK;
2739 CK_RV ckrv;
2740 CK_SESSION_HANDLE sess = kmfh->pk11handle;
2741 CK_ATTRIBUTE sym_attr[1];
2742 CK_ULONG value_len = 0;
2743
2744 /* find the key length first */
2745 sym_attr[0].type = CKA_VALUE;
2746 sym_attr[0].pValue = NULL;
2747 sym_attr[0].ulValueLen = value_len;
2748 if ((ckrv = C_GetAttributeValue(sess, obj, sym_attr, 1)) != CKR_OK) {
2749 rawsym->keydata.val = NULL;
2750 rawsym->keydata.len = 0;
2751 if (ckrv == CKR_ATTRIBUTE_SENSITIVE) {
2752 return (KMF_ERR_SENSITIVE_KEY);
2753 } else if (ckrv == CKR_KEY_UNEXTRACTABLE) {
2754 return (KMF_ERR_UNEXTRACTABLE_KEY);
2755 } else {
2756 SET_ERROR(kmfh, ckrv);
2757 return (KMF_ERR_INTERNAL);
2758 }
2759 }
2760
2761 /* Allocate memory for pValue */
2762 sym_attr[0].pValue = malloc(sym_attr[0].ulValueLen);
2763 if (sym_attr[0].pValue == NULL) {
2764 return (KMF_ERR_MEMORY);
2765 }
2766
2767 /* get the key data */
2768 if ((ckrv = C_GetAttributeValue(sess, obj, sym_attr, 1)) != CKR_OK) {
2769 SET_ERROR(kmfh, ckrv);
2770 free(sym_attr[0].pValue);
2771 return (KMF_ERR_INTERNAL);
2772 }
2773
2774 rawsym->keydata.val = sym_attr[0].pValue;
2775 rawsym->keydata.len = sym_attr[0].ulValueLen;
2776 return (rv);
2777 }
2778
2779 static KMF_RETURN
keyObj2RawKey(KMF_HANDLE_T handle,KMF_KEY_HANDLE * inkey,KMF_RAW_KEY_DATA ** outkey)2780 keyObj2RawKey(KMF_HANDLE_T handle, KMF_KEY_HANDLE *inkey,
2781 KMF_RAW_KEY_DATA **outkey)
2782 {
2783 KMF_RETURN rv = KMF_OK;
2784 KMF_RAW_KEY_DATA *rkey;
2785 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
2786
2787 rkey = malloc(sizeof (KMF_RAW_KEY_DATA));
2788 if (rkey == NULL)
2789 return (KMF_ERR_MEMORY);
2790
2791 (void) memset(rkey, 0, sizeof (KMF_RAW_KEY_DATA));
2792
2793 rkey->keytype = inkey->keyalg;
2794
2795 if (inkey->keyalg == KMF_RSA) {
2796 rv = get_raw_rsa(kmfh, (CK_OBJECT_HANDLE)inkey->keyp,
2797 &rkey->rawdata.rsa);
2798 } else if (inkey->keyalg == KMF_DSA) {
2799 rv = get_raw_dsa(kmfh, (CK_OBJECT_HANDLE)inkey->keyp,
2800 &rkey->rawdata.dsa);
2801 } else if (inkey->keyalg == KMF_AES ||
2802 inkey->keyalg == KMF_RC4 ||
2803 inkey->keyalg == KMF_DES ||
2804 inkey->keyalg == KMF_DES3 ||
2805 inkey->keyalg == KMF_GENERIC_SECRET) {
2806 rv = get_raw_sym(kmfh, (CK_OBJECT_HANDLE)inkey->keyp,
2807 &rkey->rawdata.sym);
2808 /*
2809 * If sensitive or non-extractable, mark them as such
2810 * but return "OK" status so the keys get counted
2811 * when doing FindKey operations.
2812 */
2813 if (rv == KMF_ERR_SENSITIVE_KEY) {
2814 rkey->sensitive = B_TRUE;
2815 rv = KMF_OK;
2816 } else if (rv == KMF_ERR_UNEXTRACTABLE_KEY) {
2817 rkey->not_extractable = B_TRUE;
2818 rv = KMF_OK;
2819 }
2820 } else if (inkey->keyalg == KMF_ECDSA) {
2821 rv = get_raw_ec(kmfh, (CK_OBJECT_HANDLE)inkey->keyp,
2822 &rkey->rawdata.ec);
2823 } else {
2824 rv = KMF_ERR_BAD_PARAMETER;
2825 }
2826
2827 if (rv == KMF_OK) {
2828 *outkey = rkey;
2829 } else if (rkey != NULL) {
2830 free(rkey);
2831 *outkey = NULL;
2832 }
2833
2834 return (rv);
2835 }
2836
2837
2838 static KMF_RETURN
kmf2pk11keytype(KMF_KEY_ALG keyalg,CK_KEY_TYPE * type)2839 kmf2pk11keytype(KMF_KEY_ALG keyalg, CK_KEY_TYPE *type)
2840 {
2841 switch (keyalg) {
2842 case KMF_RSA:
2843 *type = CKK_RSA;
2844 break;
2845 case KMF_DSA:
2846 *type = CKK_DSA;
2847 break;
2848 case KMF_ECDSA:
2849 *type = CKK_EC;
2850 break;
2851 case KMF_AES:
2852 *type = CKK_AES;
2853 break;
2854 case KMF_RC4:
2855 *type = CKK_RC4;
2856 break;
2857 case KMF_DES:
2858 *type = CKK_DES;
2859 break;
2860 case KMF_DES3:
2861 *type = CKK_DES3;
2862 break;
2863 case KMF_GENERIC_SECRET:
2864 *type = CKK_GENERIC_SECRET;
2865 break;
2866 default:
2867 return (KMF_ERR_BAD_KEY_TYPE);
2868 }
2869
2870 return (KMF_OK);
2871 }
2872
2873 static int
IDStringToData(char * idstr,KMF_DATA * iddata)2874 IDStringToData(char *idstr, KMF_DATA *iddata)
2875 {
2876 int len, i;
2877 char *iddup, *byte;
2878 uint_t lvalue;
2879
2880 if (idstr == NULL || !strlen(idstr))
2881 return (-1);
2882
2883 iddup = (char *)strdup(idstr);
2884 if (iddup == NULL)
2885 return (KMF_ERR_MEMORY);
2886
2887 len = strlen(iddup) / 3 + 1;
2888 iddata->Data = malloc(len);
2889 if (iddata->Data == NULL)
2890 return (KMF_ERR_MEMORY);
2891 (void) memset(iddata->Data, 0, len);
2892 iddata->Length = len;
2893
2894 byte = strtok(iddup, ":");
2895 if (byte == NULL) {
2896 free(iddup);
2897 free(iddata->Data);
2898 iddata->Data = NULL;
2899 iddata->Length = 0;
2900 return (-1);
2901 }
2902
2903 i = 0;
2904 do {
2905 (void) sscanf(byte, "%x", &lvalue);
2906 iddata->Data[i++] = (uchar_t)(lvalue & 0x000000FF);
2907 byte = strtok(NULL, ":");
2908 } while (byte != NULL && i < len);
2909
2910 iddata->Length = i;
2911 free(iddup);
2912 return (0);
2913 }
2914
2915 KMF_RETURN
KMFPK11_FindKey(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)2916 KMFPK11_FindKey(KMF_HANDLE_T handle,
2917 int numattr, KMF_ATTRIBUTE *attrlist)
2918 {
2919 KMF_RETURN rv = KMF_OK;
2920 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
2921 uint32_t want_keys, i;
2922 CK_RV ckrv;
2923 CK_ATTRIBUTE pTmpl[10];
2924 CK_OBJECT_CLASS class;
2925 CK_BBOOL true = TRUE;
2926 CK_ULONG alg;
2927 boolean_t is_token = B_TRUE, is_private = B_FALSE;
2928 KMF_KEY_HANDLE *keys;
2929 uint32_t *numkeys;
2930 KMF_CREDENTIAL *cred = NULL;
2931 KMF_KEY_CLASS keyclass = KMF_KEYCLASS_NONE;
2932 char *findLabel, *idstr;
2933 KMF_KEY_ALG keytype = KMF_KEYALG_NONE;
2934 KMF_ENCODE_FORMAT format;
2935
2936 if (kmfh == NULL)
2937 return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */
2938
2939 if (kmfh->pk11handle == CK_INVALID_HANDLE)
2940 return (KMF_ERR_NO_TOKEN_SELECTED);
2941
2942 numkeys = kmf_get_attr_ptr(KMF_COUNT_ATTR, attrlist, numattr);
2943 if (numkeys == NULL)
2944 return (KMF_ERR_BAD_PARAMETER);
2945
2946 if (*numkeys > 0)
2947 want_keys = *numkeys;
2948 else
2949 want_keys = MAXINT; /* count them all */
2950
2951 /* keyclass is optional */
2952 (void) kmf_get_attr(KMF_KEYCLASS_ATTR, attrlist, numattr,
2953 (void *)&keyclass, NULL);
2954
2955 if (keyclass == KMF_ASYM_PUB) {
2956 class = CKO_PUBLIC_KEY;
2957 } else if (keyclass == KMF_ASYM_PRI) {
2958 class = CKO_PRIVATE_KEY;
2959 } else if (keyclass == KMF_SYMMETRIC) {
2960 class = CKO_SECRET_KEY;
2961 }
2962
2963 rv = kmf_get_attr(KMF_TOKEN_BOOL_ATTR, attrlist, numattr,
2964 (void *)&is_token, NULL);
2965 if (rv != KMF_OK)
2966 return (rv);
2967
2968 i = 0;
2969 if (is_token) {
2970 SETATTR(pTmpl, i, CKA_TOKEN, &true, sizeof (true));
2971 i++;
2972 }
2973
2974 if (keyclass != KMF_KEYCLASS_NONE) {
2975 SETATTR(pTmpl, i, CKA_CLASS, &class, sizeof (class));
2976 i++;
2977 }
2978
2979 findLabel = kmf_get_attr_ptr(KMF_KEYLABEL_ATTR, attrlist, numattr);
2980
2981 if (findLabel != NULL && strlen(findLabel)) {
2982 SETATTR(pTmpl, i, CKA_LABEL, findLabel, strlen(findLabel));
2983 i++;
2984 }
2985 /* keytype is optional */
2986 (void) kmf_get_attr(KMF_KEYALG_ATTR, attrlist, numattr,
2987 (void *)&keytype, NULL);
2988
2989 if (keytype != 0) {
2990 rv = kmf2pk11keytype(keytype, &alg);
2991 if (rv != KMF_OK) {
2992 return (KMF_ERR_BAD_KEY_TYPE);
2993 }
2994 SETATTR(pTmpl, i, CKA_KEY_TYPE, &alg, sizeof (alg));
2995 i++;
2996 }
2997
2998 idstr = kmf_get_attr_ptr(KMF_IDSTR_ATTR, attrlist, numattr);
2999
3000 if (idstr != NULL) {
3001 KMF_DATA iddata = { 0, NULL };
3002
3003 /*
3004 * ID String parameter is assumed to be of form:
3005 * XX:XX:XX:XX:XX ... :XX
3006 * where XX is a hex number.
3007 *
3008 * We must convert this back to binary in order to
3009 * use it in a search.
3010 */
3011 rv = IDStringToData(idstr, &iddata);
3012 if (rv == KMF_OK) {
3013 SETATTR(pTmpl, i, CKA_ID, iddata.Data, iddata.Length);
3014 i++;
3015 } else {
3016 return (rv);
3017 }
3018 }
3019
3020 /* is_private is optional */
3021 (void) kmf_get_attr(KMF_PRIVATE_BOOL_ATTR, attrlist, numattr,
3022 (void *)&is_private, NULL);
3023
3024 if (is_private) {
3025 SETATTR(pTmpl, i, CKA_PRIVATE, &true, sizeof (true));
3026 i++;
3027 }
3028
3029 /*
3030 * Authenticate if the object is a token object,
3031 * a private or secred key, or if the user passed in credentials.
3032 */
3033 cred = kmf_get_attr_ptr(KMF_CREDENTIAL_ATTR, attrlist, numattr);
3034 if (cred != NULL) {
3035 rv = pk11_authenticate(handle, cred);
3036 if (rv != KMF_OK)
3037 return (rv);
3038 }
3039
3040 keys = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr);
3041 /* it is okay to have "keys" contains NULL */
3042
3043 ckrv = C_FindObjectsInit(kmfh->pk11handle, pTmpl, i);
3044 if (ckrv == CKR_OK) {
3045 CK_ULONG obj_count, n = 0;
3046 while (ckrv == CKR_OK && n < want_keys) {
3047 CK_OBJECT_HANDLE hObj;
3048
3049 ckrv = C_FindObjects(kmfh->pk11handle, &hObj,
3050 1, &obj_count);
3051 if (ckrv == CKR_OK && obj_count == 1) {
3052 if (keys != NULL) {
3053 CK_ULONG keytype;
3054 keys[n].kstype = KMF_KEYSTORE_PK11TOKEN;
3055 keys[n].israw = FALSE;
3056 keys[n].keyp = (void *)hObj;
3057
3058 ckrv = getObjectKeytype(handle,
3059 (CK_OBJECT_HANDLE)keys[n].keyp,
3060 &keytype);
3061 if (ckrv != CKR_OK)
3062 goto end;
3063
3064 ckrv = getObjectLabel(handle,
3065 (CK_OBJECT_HANDLE)keys[n].keyp,
3066 &(keys[n].keylabel));
3067 if (ckrv != CKR_OK)
3068 goto end;
3069
3070 if (keyclass == KMF_KEYCLASS_NONE) {
3071 ckrv = getObjectKeyclass(handle,
3072 (CK_OBJECT_HANDLE)
3073 keys[n].keyp,
3074 &(keys[n].keyclass));
3075 if (ckrv != CKR_OK)
3076 goto end;
3077 } else {
3078 keys[n].keyclass = keyclass;
3079 }
3080 if (keytype == CKK_RSA) {
3081 keys[n].keyalg = KMF_RSA;
3082 } else if (keytype == CKK_DSA) {
3083 keys[n].keyalg = KMF_DSA;
3084 } else if (keytype == CKK_EC) {
3085 keys[n].keyalg = KMF_ECDSA;
3086 } else if (keytype == CKK_AES) {
3087 keys[n].keyalg = KMF_AES;
3088 keys[n].keyclass =
3089 KMF_SYMMETRIC;
3090 } else if (keytype == CKK_RC4) {
3091 keys[n].keyalg = KMF_RC4;
3092 keys[n].keyclass =
3093 KMF_SYMMETRIC;
3094 } else if (keytype == CKK_DES) {
3095 keys[n].keyalg = KMF_DES;
3096 keys[n].keyclass =
3097 KMF_SYMMETRIC;
3098 } else if (keytype == CKK_DES3) {
3099 keys[n].keyalg = KMF_DES3;
3100 keys[n].keyclass =
3101 KMF_SYMMETRIC;
3102 } else if (keytype ==
3103 CKK_GENERIC_SECRET) {
3104 keys[n].keyalg =
3105 KMF_GENERIC_SECRET;
3106 keys[n].keyclass =
3107 KMF_SYMMETRIC;
3108 }
3109
3110 }
3111 n++;
3112 } else {
3113 break;
3114 }
3115 }
3116 ckrv = C_FindObjectsFinal(kmfh->pk11handle);
3117
3118 /* "numkeys" indicates the number that were actually found */
3119 *numkeys = n;
3120 }
3121
3122 if (ckrv == KMF_OK && keys != NULL && (*numkeys) > 0) {
3123 if ((rv = kmf_get_attr(KMF_ENCODE_FORMAT_ATTR, attrlist,
3124 numattr, (void *)&format, NULL)) == KMF_OK) {
3125 if (format == KMF_FORMAT_RAWKEY ||
3126 format == KMF_FORMAT_PEM) {
3127 /* Convert keys to "rawkey" format */
3128 for (i = 0; i < (*numkeys); i++) {
3129 KMF_RAW_KEY_DATA *rkey = NULL;
3130 rv = keyObj2RawKey(handle, &keys[i],
3131 &rkey);
3132 if (rv == KMF_OK) {
3133 keys[i].keyp = rkey;
3134 keys[i].israw = TRUE;
3135 } else {
3136 break;
3137 }
3138 }
3139 }
3140 } else {
3141 rv = KMF_OK; /* format is optional */
3142 }
3143 }
3144
3145 end:
3146 if (ckrv != CKR_OK) {
3147 SET_ERROR(kmfh, ckrv);
3148 /* Report authentication failures to the caller */
3149 if (ckrv == CKR_USER_NOT_LOGGED_IN ||
3150 ckrv == CKR_PIN_INCORRECT ||
3151 ckrv == CKR_PIN_INVALID ||
3152 ckrv == CKR_PIN_EXPIRED ||
3153 ckrv == CKR_PIN_LOCKED ||
3154 ckrv == CKR_SESSION_READ_ONLY)
3155 rv = KMF_ERR_AUTH_FAILED;
3156 else
3157 rv = KMF_ERR_INTERNAL;
3158 } else if ((*numkeys) == 0) {
3159 rv = KMF_ERR_KEY_NOT_FOUND;
3160 }
3161
3162 return (rv);
3163 }
3164
3165 static char *
convertDate(char * fulldate)3166 convertDate(char *fulldate)
3167 {
3168 struct tm tms;
3169 char newtime[9];
3170
3171 (void) strptime(fulldate, "%b %d %T %Y %Z", &tms);
3172
3173 if (tms.tm_year < 69)
3174 tms.tm_year += 100;
3175
3176 (void) strftime(newtime, sizeof (newtime), "m%d", &tms);
3177
3178 newtime[8] = 0;
3179
3180 /* memory returned must be freed by the caller */
3181 return ((char *)strdup(newtime));
3182 }
3183
3184 static KMF_RETURN
store_raw_key(KMF_HANDLE_T handle,KMF_ATTRIBUTE * attrlist,int numattr,KMF_RAW_KEY_DATA * rawkey)3185 store_raw_key(KMF_HANDLE_T handle,
3186 KMF_ATTRIBUTE *attrlist, int numattr,
3187 KMF_RAW_KEY_DATA *rawkey)
3188 {
3189 KMF_RETURN rv = KMF_OK;
3190 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
3191 int i;
3192 CK_RV ckrv = CKR_OK;
3193 CK_ATTRIBUTE templ[32];
3194 CK_OBJECT_HANDLE keyobj;
3195 CK_KEY_TYPE keytype;
3196 CK_OBJECT_CLASS oClass = CKO_PRIVATE_KEY;
3197 CK_BBOOL cktrue = TRUE;
3198 CK_DATE startdate, enddate;
3199 KMF_DATA id = { 0, NULL };
3200 KMF_DATA subject = { 0, NULL };
3201 KMF_X509EXT_KEY_USAGE kuext;
3202 KMF_X509_CERTIFICATE *x509 = NULL;
3203 CK_BBOOL kufound = B_FALSE;
3204 KMF_DATA *cert = NULL;
3205 char *notbefore = NULL, *start = NULL;
3206 char *notafter = NULL, *end = NULL;
3207 char *keylabel = NULL;
3208 KMF_CREDENTIAL *cred = NULL;
3209
3210 if (kmfh == NULL)
3211 return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */
3212
3213 if (kmfh->pk11handle == CK_INVALID_HANDLE)
3214 return (KMF_ERR_NO_TOKEN_SELECTED);
3215
3216 if (rawkey->keytype == KMF_RSA)
3217 keytype = CKK_RSA;
3218 else if (rawkey->keytype == KMF_DSA)
3219 keytype = CKK_DSA;
3220 else if (rawkey->keytype == KMF_ECDSA)
3221 keytype = CKK_EC;
3222 else
3223 return (KMF_ERR_BAD_PARAMETER);
3224
3225 cred = kmf_get_attr_ptr(KMF_CREDENTIAL_ATTR, attrlist, numattr);
3226 if (cred != NULL) {
3227 rv = pk11_authenticate(handle, cred);
3228 if (rv != KMF_OK)
3229 return (rv);
3230 }
3231
3232 keylabel = kmf_get_attr_ptr(KMF_KEYLABEL_ATTR, attrlist, numattr);
3233 /*
3234 * If the caller did not specify a label, see if the raw key
3235 * came with one (possible if it came from a PKCS#12 file).
3236 */
3237 if (keylabel == NULL) {
3238 keylabel = rawkey->label;
3239 }
3240
3241 i = 0;
3242 SETATTR(templ, i, CKA_CLASS, &oClass, sizeof (CK_OBJECT_CLASS)); i++;
3243 SETATTR(templ, i, CKA_KEY_TYPE, &keytype, sizeof (keytype)); i++;
3244 SETATTR(templ, i, CKA_TOKEN, &cktrue, sizeof (cktrue)); i++;
3245 SETATTR(templ, i, CKA_PRIVATE, &cktrue, sizeof (cktrue)); i++;
3246 if (keytype != CKK_EC) {
3247 SETATTR(templ, i, CKA_DECRYPT, &cktrue, sizeof (cktrue)); i++;
3248 }
3249
3250 cert = kmf_get_attr_ptr(KMF_CERT_DATA_ATTR, attrlist, numattr);
3251 if (cert != NULL) {
3252 id.Data = NULL;
3253 id.Length = 0;
3254 rv = kmf_get_cert_id_data(cert, &id);
3255 if (rv != KMF_OK) {
3256 goto cleanup;
3257 }
3258
3259 rv = DerDecodeSignedCertificate((const KMF_DATA *)cert, &x509);
3260 if (rv != KMF_OK) {
3261 goto cleanup;
3262 }
3263
3264 rv = DerEncodeName(&x509->certificate.subject, &subject);
3265 if (rv != KMF_OK) {
3266 goto cleanup;
3267 }
3268 SETATTR(templ, i, CKA_SUBJECT, subject.Data, subject.Length);
3269 i++;
3270
3271 rv = kmf_get_cert_start_date_str(handle, cert, ¬before);
3272 if (rv != KMF_OK) {
3273 goto cleanup;
3274 }
3275 start = convertDate(notbefore);
3276 free(notbefore);
3277
3278 rv = kmf_get_cert_end_date_str(handle, cert, ¬after);
3279 if (rv != KMF_OK) {
3280 goto cleanup;
3281 }
3282 end = convertDate(notafter);
3283 free(notafter);
3284 if (id.Data != NULL && id.Data != NULL && id.Length > 0) {
3285 SETATTR(templ, i, CKA_ID, id.Data, id.Length);
3286 i++;
3287 }
3288 if (start != NULL) {
3289 /*
3290 * This makes some potentially dangerous assumptions:
3291 * 1. that the startdate in the parameter block is
3292 * properly formatted as YYYYMMDD
3293 * 2. That the CK_DATE structure is always the same.
3294 */
3295 (void) memcpy(&startdate, start, sizeof (CK_DATE));
3296 SETATTR(templ, i, CKA_START_DATE, &startdate,
3297 sizeof (startdate));
3298 i++;
3299 }
3300 if (end != NULL) {
3301 (void) memcpy(&enddate, end, sizeof (CK_DATE));
3302 SETATTR(templ, i, CKA_END_DATE, &enddate,
3303 sizeof (enddate));
3304 i++;
3305 }
3306
3307 if ((rv = kmf_get_cert_ku(cert, &kuext)) != KMF_OK &&
3308 rv != KMF_ERR_EXTENSION_NOT_FOUND)
3309 goto cleanup;
3310
3311 kufound = (rv == KMF_OK);
3312 rv = KMF_OK; /* reset if we got KMF_ERR_EXTENSION_NOT_FOUND */
3313 }
3314
3315 /*
3316 * Only set the KeyUsage stuff if the KU extension was present.
3317 */
3318 if (kufound) {
3319 CK_BBOOL condition;
3320
3321 condition = (kuext.KeyUsageBits & KMF_keyEncipherment) ?
3322 B_TRUE : B_FALSE;
3323 SETATTR(templ, i, CKA_UNWRAP, &condition, sizeof (CK_BBOOL));
3324 i++;
3325 condition = (kuext.KeyUsageBits & KMF_dataEncipherment) ?
3326 B_TRUE : B_FALSE;
3327 SETATTR(templ, i, CKA_DECRYPT, &condition, sizeof (CK_BBOOL));
3328 i++;
3329 condition = (kuext.KeyUsageBits & KMF_digitalSignature) ?
3330 B_TRUE : B_FALSE;
3331 SETATTR(templ, i, CKA_SIGN, &condition, sizeof (CK_BBOOL));
3332 i++;
3333 condition = (kuext.KeyUsageBits & KMF_digitalSignature) ?
3334 B_TRUE : B_FALSE;
3335 SETATTR(templ, i, CKA_SIGN_RECOVER, &condition,
3336 sizeof (CK_BBOOL));
3337 i++;
3338
3339 }
3340
3341 if (keylabel != NULL) {
3342 SETATTR(templ, i, CKA_LABEL, keylabel, strlen(keylabel));
3343 i++;
3344 }
3345 if (id.Data == NULL && rawkey->id.Data != NULL) {
3346 SETATTR(templ, i, CKA_ID, rawkey->id.Data,
3347 rawkey->id.Length);
3348 i++;
3349 }
3350 if (keytype == CKK_RSA) {
3351 SETATTR(templ, i, CKA_MODULUS,
3352 rawkey->rawdata.rsa.mod.val,
3353 rawkey->rawdata.rsa.mod.len);
3354 i++;
3355 SETATTR(templ, i, CKA_PUBLIC_EXPONENT,
3356 rawkey->rawdata.rsa.pubexp.val,
3357 rawkey->rawdata.rsa.pubexp.len);
3358 i++;
3359 if (rawkey->rawdata.rsa.priexp.val != NULL) {
3360 SETATTR(templ, i, CKA_PRIVATE_EXPONENT,
3361 rawkey->rawdata.rsa.priexp.val,
3362 rawkey->rawdata.rsa.priexp.len);
3363 i++;
3364 }
3365 if (rawkey->rawdata.rsa.prime1.val != NULL) {
3366 SETATTR(templ, i, CKA_PRIME_1,
3367 rawkey->rawdata.rsa.prime1.val,
3368 rawkey->rawdata.rsa.prime1.len);
3369 i++;
3370 }
3371 if (rawkey->rawdata.rsa.prime2.val != NULL) {
3372 SETATTR(templ, i, CKA_PRIME_2,
3373 rawkey->rawdata.rsa.prime2.val,
3374 rawkey->rawdata.rsa.prime2.len);
3375 i++;
3376 }
3377 if (rawkey->rawdata.rsa.exp1.val != NULL) {
3378 SETATTR(templ, i, CKA_EXPONENT_1,
3379 rawkey->rawdata.rsa.exp1.val,
3380 rawkey->rawdata.rsa.exp1.len);
3381 i++;
3382 }
3383 if (rawkey->rawdata.rsa.exp2.val != NULL) {
3384 SETATTR(templ, i, CKA_EXPONENT_2,
3385 rawkey->rawdata.rsa.exp2.val,
3386 rawkey->rawdata.rsa.exp2.len);
3387 i++;
3388 }
3389 if (rawkey->rawdata.rsa.coef.val != NULL) {
3390 SETATTR(templ, i, CKA_COEFFICIENT,
3391 rawkey->rawdata.rsa.coef.val,
3392 rawkey->rawdata.rsa.coef.len);
3393 i++;
3394 }
3395 } else if (keytype == CKK_DSA) {
3396 SETATTR(templ, i, CKA_PRIME,
3397 rawkey->rawdata.dsa.prime.val,
3398 rawkey->rawdata.dsa.prime.len);
3399 i++;
3400 SETATTR(templ, i, CKA_SUBPRIME,
3401 rawkey->rawdata.dsa.subprime.val,
3402 rawkey->rawdata.dsa.subprime.len);
3403 i++;
3404 SETATTR(templ, i, CKA_BASE,
3405 rawkey->rawdata.dsa.base.val,
3406 rawkey->rawdata.dsa.base.len);
3407 i++;
3408 SETATTR(templ, i, CKA_VALUE,
3409 rawkey->rawdata.dsa.value.val,
3410 rawkey->rawdata.dsa.value.len);
3411 i++;
3412 } else if (keytype == CKK_EC) {
3413 SETATTR(templ, i, CKA_SIGN, &cktrue, sizeof (cktrue));
3414 i++;
3415 SETATTR(templ, i, CKA_DERIVE, &cktrue, sizeof (cktrue));
3416 i++;
3417 SETATTR(templ, i, CKA_VALUE,
3418 rawkey->rawdata.ec.value.val,
3419 rawkey->rawdata.ec.value.len);
3420 i++;
3421 SETATTR(templ, i, CKA_EC_PARAMS,
3422 rawkey->rawdata.ec.params.Data,
3423 rawkey->rawdata.ec.params.Length);
3424 i++;
3425 }
3426
3427 ckrv = C_CreateObject(kmfh->pk11handle, templ, i, &keyobj);
3428 if (ckrv != CKR_OK) {
3429 SET_ERROR(kmfh, ckrv);
3430
3431 /* Report authentication failures to the caller */
3432 if (ckrv == CKR_USER_NOT_LOGGED_IN ||
3433 ckrv == CKR_PIN_INCORRECT ||
3434 ckrv == CKR_PIN_INVALID ||
3435 ckrv == CKR_PIN_EXPIRED ||
3436 ckrv == CKR_PIN_LOCKED ||
3437 ckrv == CKR_SESSION_READ_ONLY)
3438 rv = KMF_ERR_AUTH_FAILED;
3439 else
3440 rv = KMF_ERR_INTERNAL;
3441 }
3442 cleanup:
3443 if (start != NULL)
3444 free(start);
3445 if (end != NULL)
3446 free(end);
3447 kmf_free_data(&id);
3448 kmf_free_data(&subject);
3449 kmf_free_signed_cert(x509);
3450 free(x509);
3451
3452 return (rv);
3453 }
3454
3455 KMF_RETURN
KMFPK11_CreateSymKey(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)3456 KMFPK11_CreateSymKey(KMF_HANDLE_T handle,
3457 int numattr, KMF_ATTRIBUTE *attrlist)
3458 {
3459 KMF_RETURN rv = KMF_OK;
3460 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
3461 CK_RV ckrv;
3462 CK_SESSION_HANDLE hSession = kmfh->pk11handle;
3463 CK_OBJECT_HANDLE keyhandle;
3464 CK_MECHANISM keyGenMech;
3465 CK_OBJECT_CLASS class = CKO_SECRET_KEY;
3466 CK_ULONG secKeyType;
3467 CK_ULONG secKeyLen; /* for RC4 and AES */
3468 CK_BBOOL true = TRUE;
3469 CK_BBOOL false = FALSE;
3470 CK_ATTRIBUTE templ[15];
3471 CK_BYTE *keydata = NULL;
3472 int i = 0;
3473 KMF_KEY_HANDLE *symkey;
3474 KMF_KEY_ALG keytype;
3475 uint32_t keylen = 0;
3476 uint32_t attrkeylen = 0;
3477 uint32_t keylen_size = sizeof (uint32_t);
3478 char *keylabel = NULL;
3479 KMF_CREDENTIAL *cred = NULL;
3480 uint32_t is_sensitive = B_FALSE;
3481 uint32_t is_not_extractable = B_FALSE;
3482
3483 if (kmfh == NULL)
3484 return (KMF_ERR_UNINITIALIZED);
3485
3486 if (kmfh->pk11handle == CK_INVALID_HANDLE)
3487 return (KMF_ERR_NO_TOKEN_SELECTED);
3488
3489 symkey = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr);
3490 if (symkey == NULL)
3491 return (KMF_ERR_BAD_PARAMETER);
3492
3493 rv = kmf_get_attr(KMF_KEYALG_ATTR, attrlist, numattr,
3494 (void *)&keytype, NULL);
3495 if (rv != KMF_OK)
3496 return (KMF_ERR_BAD_PARAMETER);
3497
3498 keylabel = kmf_get_attr_ptr(KMF_KEYLABEL_ATTR, attrlist, numattr);
3499 if (keylabel == NULL)
3500 return (KMF_ERR_BAD_PARAMETER);
3501
3502 rv = kmf_get_attr(KMF_SENSITIVE_BOOL_ATTR, attrlist, numattr,
3503 (void *)&is_sensitive, NULL);
3504 if (rv != KMF_OK)
3505 return (KMF_ERR_BAD_PARAMETER);
3506
3507 rv = kmf_get_attr(KMF_NON_EXTRACTABLE_BOOL_ATTR, attrlist, numattr,
3508 (void *)&is_not_extractable, NULL);
3509 if (rv != KMF_OK)
3510 return (KMF_ERR_BAD_PARAMETER);
3511
3512 /*
3513 * For AES, RC4, DES and 3DES, call C_GenerateKey() to create a key.
3514 *
3515 * For a generic secret key, because it may not be supported in
3516 * C_GenerateKey() for some PKCS11 providers, we will handle it
3517 * differently.
3518 */
3519 if (keytype == KMF_GENERIC_SECRET) {
3520 rv = create_generic_secret_key(handle, numattr,
3521 attrlist, &keyhandle);
3522 if (rv != KMF_OK)
3523 goto out;
3524 else
3525 goto setup;
3526 }
3527
3528 rv = kmf_get_attr(KMF_KEY_DATA_ATTR, attrlist, numattr,
3529 NULL, &attrkeylen);
3530 if (rv == KMF_OK && attrkeylen > 0) {
3531 keydata = kmf_get_attr_ptr(KMF_KEY_DATA_ATTR, attrlist,
3532 numattr);
3533 } else {
3534 keydata = NULL;
3535 attrkeylen = 0;
3536 rv = KMF_OK;
3537 }
3538 if (keydata != NULL) {
3539 if (keytype == KMF_DES && attrkeylen != 8) {
3540 rv = KMF_ERR_BAD_KEY_SIZE;
3541 goto out;
3542 }
3543 if (keytype == KMF_DES3 && attrkeylen != 24) {
3544 rv = KMF_ERR_BAD_KEY_SIZE;
3545 goto out;
3546 }
3547 /*
3548 * This may override what the user gave on the
3549 * command line.
3550 */
3551 keylen = attrkeylen * 8; /* bytes to bits */
3552 } else {
3553 /*
3554 * If keydata was not given, key length must be
3555 * provided.
3556 */
3557 rv = kmf_get_attr(KMF_KEYLENGTH_ATTR, attrlist, numattr,
3558 &keylen, &keylen_size);
3559 if (rv == KMF_ERR_ATTR_NOT_FOUND &&
3560 (keytype == KMF_DES || keytype == KMF_DES3))
3561 /* keylength is not required for DES and 3DES */
3562 rv = KMF_OK;
3563 if (rv != KMF_OK)
3564 return (KMF_ERR_BAD_PARAMETER);
3565 }
3566
3567 if ((keylen % 8) != 0) {
3568 return (KMF_ERR_BAD_KEY_SIZE);
3569 }
3570 secKeyLen = keylen / 8; /* in bytes for RC4/AES */
3571
3572 /*
3573 * Only set CKA_VALUE_LEN if the key data was not given and
3574 * we are creating an RC4 or AES key.
3575 */
3576 if (keydata == NULL &&
3577 (keytype == KMF_AES || keytype == KMF_RC4)) {
3578 SETATTR(templ, i, CKA_VALUE_LEN, &secKeyLen,
3579 sizeof (secKeyLen));
3580 i++;
3581 }
3582
3583 /* Other keytypes */
3584 keyGenMech.pParameter = NULL_PTR;
3585 keyGenMech.ulParameterLen = 0;
3586 switch (keytype) {
3587 case KMF_AES:
3588 keyGenMech.mechanism = CKM_AES_KEY_GEN;
3589 secKeyType = CKK_AES;
3590 break;
3591 case KMF_RC4:
3592 keyGenMech.mechanism = CKM_RC4_KEY_GEN;
3593 secKeyType = CKK_RC4;
3594 break;
3595 case KMF_DES:
3596 keyGenMech.mechanism = CKM_DES_KEY_GEN;
3597 secKeyType = CKK_DES;
3598 break;
3599 case KMF_DES3:
3600 keyGenMech.mechanism = CKM_DES3_KEY_GEN;
3601 secKeyType = CKK_DES3;
3602 break;
3603 default:
3604 return (KMF_ERR_BAD_KEY_TYPE);
3605 }
3606 if (keydata != NULL) {
3607 SETATTR(templ, i, CKA_VALUE, keydata, secKeyLen);
3608 i++;
3609 }
3610 SETATTR(templ, i, CKA_CLASS, &class, sizeof (class));
3611 i++;
3612 SETATTR(templ, i, CKA_KEY_TYPE, &secKeyType, sizeof (secKeyType));
3613 i++;
3614
3615 if (keylabel != NULL) {
3616 SETATTR(templ, i, CKA_LABEL, keylabel, strlen(keylabel));
3617 i++;
3618 }
3619
3620 if (is_sensitive == B_TRUE) {
3621 SETATTR(templ, i, CKA_SENSITIVE, &true, sizeof (true));
3622 } else {
3623 SETATTR(templ, i, CKA_SENSITIVE, &false, sizeof (false));
3624 }
3625 i++;
3626
3627 if (is_not_extractable == B_TRUE) {
3628 SETATTR(templ, i, CKA_EXTRACTABLE, &false, sizeof (false));
3629 } else {
3630 SETATTR(templ, i, CKA_EXTRACTABLE, &true, sizeof (true));
3631 }
3632 i++;
3633
3634 SETATTR(templ, i, CKA_TOKEN, &true, sizeof (true));
3635 i++;
3636 SETATTR(templ, i, CKA_PRIVATE, &true, sizeof (true));
3637 i++;
3638 SETATTR(templ, i, CKA_ENCRYPT, &true, sizeof (true));
3639 i++;
3640 SETATTR(templ, i, CKA_DECRYPT, &true, sizeof (true));
3641 i++;
3642 SETATTR(templ, i, CKA_SIGN, &true, sizeof (true));
3643 i++;
3644 SETATTR(templ, i, CKA_VERIFY, &true, sizeof (true));
3645 i++;
3646
3647 cred = kmf_get_attr_ptr(KMF_CREDENTIAL_ATTR, attrlist, numattr);
3648 if (cred == NULL)
3649 return (KMF_ERR_BAD_PARAMETER);
3650
3651 rv = pk11_authenticate(handle, cred);
3652 if (rv != KMF_OK) {
3653 return (rv);
3654 }
3655
3656 /* If the key data was given, use C_CreateObject */
3657 if (keydata != NULL) {
3658 ckrv = C_CreateObject(hSession, templ, i, &keyhandle);
3659 } else {
3660 ckrv = C_GenerateKey(hSession, &keyGenMech, templ, i,
3661 &keyhandle);
3662 }
3663 if (ckrv != CKR_OK) {
3664 if (ckrv == CKR_USER_NOT_LOGGED_IN ||
3665 ckrv == CKR_PIN_INCORRECT ||
3666 ckrv == CKR_PIN_INVALID ||
3667 ckrv == CKR_PIN_EXPIRED ||
3668 ckrv == CKR_PIN_LOCKED ||
3669 ckrv == CKR_SESSION_READ_ONLY)
3670 rv = KMF_ERR_AUTH_FAILED;
3671 else
3672 rv = KMF_ERR_KEYGEN_FAILED;
3673 SET_ERROR(kmfh, ckrv);
3674 goto out;
3675 }
3676
3677 setup:
3678 symkey->kstype = KMF_KEYSTORE_PK11TOKEN;
3679 symkey->keyalg = keytype;
3680 symkey->keyclass = KMF_SYMMETRIC;
3681 symkey->israw = FALSE;
3682 symkey->keyp = (void *)keyhandle;
3683
3684 out:
3685 return (rv);
3686 }
3687
3688 KMF_RETURN
KMFPK11_GetSymKeyValue(KMF_HANDLE_T handle,KMF_KEY_HANDLE * symkey,KMF_RAW_SYM_KEY * rkey)3689 KMFPK11_GetSymKeyValue(KMF_HANDLE_T handle, KMF_KEY_HANDLE *symkey,
3690 KMF_RAW_SYM_KEY *rkey)
3691 {
3692 KMF_RETURN rv = KMF_OK;
3693 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
3694
3695 if (kmfh == NULL)
3696 return (KMF_ERR_UNINITIALIZED);
3697
3698 if (kmfh->pk11handle == CK_INVALID_HANDLE)
3699 return (KMF_ERR_NO_TOKEN_SELECTED);
3700
3701 if (symkey == NULL || rkey == NULL)
3702 return (KMF_ERR_BAD_PARAMETER);
3703 else if (symkey->keyclass != KMF_SYMMETRIC)
3704 return (KMF_ERR_BAD_KEY_CLASS);
3705
3706 /*
3707 * If the key is already in "raw" format, copy the data
3708 * to the new record if possible.
3709 */
3710 if (symkey->israw) {
3711 KMF_RAW_KEY_DATA *rawkey = (KMF_RAW_KEY_DATA *)symkey->keyp;
3712
3713 if (rawkey == NULL)
3714 return (KMF_ERR_BAD_KEYHANDLE);
3715 if (rawkey->sensitive)
3716 return (KMF_ERR_SENSITIVE_KEY);
3717 if (rawkey->not_extractable)
3718 return (KMF_ERR_UNEXTRACTABLE_KEY);
3719
3720 if (rawkey->rawdata.sym.keydata.val == NULL ||
3721 rawkey->rawdata.sym.keydata.len == 0)
3722 return (KMF_ERR_GETKEYVALUE_FAILED);
3723
3724 rkey->keydata.len = rawkey->rawdata.sym.keydata.len;
3725 if ((rkey->keydata.val = malloc(rkey->keydata.len)) == NULL)
3726 return (KMF_ERR_MEMORY);
3727 (void) memcpy(rkey->keydata.val,
3728 rawkey->rawdata.sym.keydata.val, rkey->keydata.len);
3729 } else {
3730 rv = get_raw_sym(kmfh, (CK_OBJECT_HANDLE)symkey->keyp, rkey);
3731 }
3732
3733 return (rv);
3734 }
3735
3736 KMF_RETURN
KMFPK11_SetTokenPin(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)3737 KMFPK11_SetTokenPin(KMF_HANDLE_T handle,
3738 int numattr, KMF_ATTRIBUTE *attrlist)
3739 {
3740 KMF_RETURN ret = KMF_OK;
3741 CK_RV rv = CKR_OK;
3742 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
3743 CK_SESSION_HANDLE session = 0;
3744 KMF_CREDENTIAL *oldcred;
3745 KMF_CREDENTIAL *newcred;
3746 CK_SLOT_ID slotid;
3747 CK_USER_TYPE user = CKU_USER;
3748
3749 if (handle == NULL || attrlist == NULL || numattr == 0)
3750 return (KMF_ERR_BAD_PARAMETER);
3751
3752 oldcred = kmf_get_attr_ptr(KMF_CREDENTIAL_ATTR, attrlist, numattr);
3753 if (oldcred == NULL)
3754 return (KMF_ERR_BAD_PARAMETER);
3755
3756 newcred = kmf_get_attr_ptr(KMF_NEWPIN_ATTR, attrlist, numattr);
3757 if (newcred == NULL)
3758 return (KMF_ERR_BAD_PARAMETER);
3759
3760 rv = kmf_get_attr(KMF_SLOT_ID_ATTR, attrlist, numattr,
3761 (void *)&slotid, NULL);
3762 if (rv != KMF_OK) {
3763 char *tokenlabel = NULL;
3764 /*
3765 * If a slot wasn't given, the user must pass
3766 * a token label so we can find the slot here.
3767 */
3768 tokenlabel = kmf_get_attr_ptr(KMF_TOKEN_LABEL_ATTR, attrlist,
3769 numattr);
3770 if (tokenlabel == NULL)
3771 return (KMF_ERR_BAD_PARAMETER);
3772
3773 rv = kmf_pk11_token_lookup(handle, tokenlabel, &slotid);
3774 if (rv != KMF_OK)
3775 return (rv);
3776 }
3777 rv = kmf_get_attr(KMF_PK11_USER_TYPE_ATTR, attrlist, numattr,
3778 (void *)&user, NULL);
3779 if (rv != CKR_OK)
3780 user = CKU_USER;
3781
3782 rv = C_OpenSession(slotid, CKF_SERIAL_SESSION | CKF_RW_SESSION,
3783 NULL, NULL, &session);
3784 if (rv != CKR_OK) {
3785 SET_ERROR(kmfh, rv);
3786 ret = KMF_ERR_UNINITIALIZED;
3787 goto end;
3788 }
3789
3790 rv = C_Login(session, user, (CK_BYTE *)oldcred->cred,
3791 oldcred->credlen);
3792 if (rv != CKR_OK) {
3793 SET_ERROR(kmfh, rv);
3794 if (rv == CKR_PIN_INCORRECT ||
3795 rv == CKR_PIN_INVALID ||
3796 rv == CKR_PIN_EXPIRED ||
3797 rv == CKR_PIN_LOCKED)
3798 ret = KMF_ERR_AUTH_FAILED;
3799 else
3800 ret = KMF_ERR_INTERNAL;
3801
3802 goto end;
3803 }
3804
3805 rv = C_SetPIN(session,
3806 (CK_BYTE *)oldcred->cred, oldcred->credlen,
3807 (CK_BYTE *)newcred->cred, newcred->credlen);
3808
3809 if (rv != CKR_OK) {
3810 SET_ERROR(kmfh, rv);
3811 if (rv == CKR_PIN_INCORRECT ||
3812 rv == CKR_PIN_INVALID ||
3813 rv == CKR_PIN_EXPIRED ||
3814 rv == CKR_PIN_LOCKED)
3815 ret = KMF_ERR_AUTH_FAILED;
3816 else
3817 ret = KMF_ERR_INTERNAL;
3818 }
3819 end:
3820 if (session != 0)
3821 (void) C_CloseSession(session);
3822 return (ret);
3823 }
3824
3825 static KMF_RETURN
create_generic_secret_key(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist,CK_OBJECT_HANDLE * key)3826 create_generic_secret_key(KMF_HANDLE_T handle,
3827 int numattr, KMF_ATTRIBUTE *attrlist, CK_OBJECT_HANDLE *key)
3828 {
3829 KMF_RETURN rv = KMF_OK;
3830 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
3831 CK_RV ckrv;
3832 CK_SESSION_HANDLE hSession = kmfh->pk11handle;
3833 CK_OBJECT_CLASS class = CKO_SECRET_KEY;
3834 CK_ULONG secKeyType = CKK_GENERIC_SECRET;
3835 CK_ULONG secKeyLen;
3836 CK_BBOOL true = TRUE;
3837 CK_BBOOL false = FALSE;
3838 CK_ATTRIBUTE templ[15];
3839 int i;
3840 int random_fd = -1;
3841 int nread;
3842 int freebuf = 0;
3843 char *buf = NULL;
3844 uint32_t keylen = 0, attrkeylen = 0;
3845 char *keylabel = NULL;
3846 KMF_CREDENTIAL *cred;
3847 uint32_t is_sensitive, is_not_extractable;
3848
3849 keylabel = kmf_get_attr_ptr(KMF_KEYLABEL_ATTR, attrlist, numattr);
3850 if (keylabel == NULL)
3851 return (KMF_ERR_BAD_PARAMETER);
3852
3853 cred = kmf_get_attr_ptr(KMF_CREDENTIAL_ATTR, attrlist, numattr);
3854 if (cred == NULL)
3855 return (KMF_ERR_BAD_PARAMETER);
3856
3857 rv = kmf_get_attr(KMF_SENSITIVE_BOOL_ATTR, attrlist, numattr,
3858 (void *)&is_sensitive, NULL);
3859 if (rv != KMF_OK)
3860 return (KMF_ERR_BAD_PARAMETER);
3861
3862 rv = kmf_get_attr(KMF_NON_EXTRACTABLE_BOOL_ATTR, attrlist, numattr,
3863 (void *)&is_not_extractable, NULL);
3864 if (rv != KMF_OK)
3865 return (KMF_ERR_BAD_PARAMETER);
3866
3867 rv = kmf_get_attr(KMF_KEY_DATA_ATTR, attrlist, numattr,
3868 NULL, &attrkeylen);
3869 if (rv == KMF_OK && attrkeylen > 0) {
3870 buf = kmf_get_attr_ptr(KMF_KEY_DATA_ATTR, attrlist,
3871 numattr);
3872 secKeyLen = attrkeylen;
3873 } else {
3874 buf = NULL;
3875 rv = KMF_OK;
3876 }
3877 if (buf == NULL) {
3878 /*
3879 * If the key data was not given, key length must
3880 * be provided.
3881 */
3882 rv = kmf_get_attr(KMF_KEYLENGTH_ATTR, attrlist, numattr,
3883 &keylen, NULL);
3884 if (rv != KMF_OK)
3885 return (KMF_ERR_BAD_PARAMETER);
3886
3887 /*
3888 * Check the key size.
3889 */
3890 if ((keylen % 8) != 0) {
3891 return (KMF_ERR_BAD_KEY_SIZE);
3892 } else {
3893 secKeyLen = keylen/8; /* in bytes */
3894 }
3895
3896 /*
3897 * Generate a random number with the key size first.
3898 */
3899 buf = malloc(secKeyLen);
3900 if (buf == NULL)
3901 return (KMF_ERR_MEMORY);
3902
3903 freebuf = 1;
3904 while ((random_fd = open(DEV_RANDOM, O_RDONLY)) < 0) {
3905 if (errno != EINTR)
3906 break;
3907 }
3908
3909 if (random_fd < 0) {
3910 rv = KMF_ERR_KEYGEN_FAILED;
3911 goto out;
3912 }
3913
3914 nread = read(random_fd, buf, secKeyLen);
3915 if (nread <= 0 || nread != secKeyLen) {
3916 rv = KMF_ERR_KEYGEN_FAILED;
3917 goto out;
3918 }
3919 }
3920
3921 /*
3922 * Authenticate into the token and call C_CreateObject to generate
3923 * a generic secret token key.
3924 */
3925 rv = pk11_authenticate(handle, cred);
3926 if (rv != KMF_OK) {
3927 goto out;
3928 }
3929
3930 i = 0;
3931 SETATTR(templ, i, CKA_CLASS, &class, sizeof (class));
3932 i++;
3933 SETATTR(templ, i, CKA_KEY_TYPE, &secKeyType, sizeof (secKeyType));
3934 i++;
3935 SETATTR(templ, i, CKA_VALUE, buf, secKeyLen);
3936 i++;
3937
3938 if (keylabel != NULL) {
3939 SETATTR(templ, i, CKA_LABEL, keylabel, strlen(keylabel));
3940 i++;
3941 }
3942
3943 if (is_sensitive == B_TRUE) {
3944 SETATTR(templ, i, CKA_SENSITIVE, &true, sizeof (true));
3945 } else {
3946 SETATTR(templ, i, CKA_SENSITIVE, &false, sizeof (false));
3947 }
3948 i++;
3949
3950 if (is_not_extractable == B_TRUE) {
3951 SETATTR(templ, i, CKA_EXTRACTABLE, &false, sizeof (false));
3952 } else {
3953 SETATTR(templ, i, CKA_EXTRACTABLE, &true, sizeof (true));
3954 }
3955 i++;
3956
3957 SETATTR(templ, i, CKA_TOKEN, &true, sizeof (true));
3958 i++;
3959 SETATTR(templ, i, CKA_PRIVATE, &true, sizeof (true));
3960 i++;
3961 SETATTR(templ, i, CKA_SIGN, &true, sizeof (true));
3962 i++;
3963
3964 ckrv = C_CreateObject(hSession, templ, i, key);
3965 if (ckrv != CKR_OK) {
3966 if (ckrv == CKR_USER_NOT_LOGGED_IN ||
3967 ckrv == CKR_PIN_INCORRECT ||
3968 ckrv == CKR_PIN_INVALID ||
3969 ckrv == CKR_PIN_EXPIRED ||
3970 ckrv == CKR_PIN_LOCKED ||
3971 ckrv == CKR_SESSION_READ_ONLY)
3972 rv = KMF_ERR_AUTH_FAILED;
3973 else
3974 rv = KMF_ERR_KEYGEN_FAILED;
3975 SET_ERROR(kmfh, ckrv);
3976 }
3977
3978 out:
3979 if (buf != NULL && freebuf)
3980 free(buf);
3981
3982 if (random_fd != -1)
3983 (void) close(random_fd);
3984
3985 return (rv);
3986 }
3987
3988 KMF_RETURN
KMFPK11_StoreKey(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attlist)3989 KMFPK11_StoreKey(KMF_HANDLE_T handle,
3990 int numattr,
3991 KMF_ATTRIBUTE *attlist)
3992 {
3993 KMF_RETURN rv = KMF_OK;
3994 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
3995 KMF_CREDENTIAL cred = { NULL, 0 };
3996 KMF_KEY_HANDLE *key;
3997 KMF_RAW_KEY_DATA *rawkey = NULL;
3998 CK_BBOOL btrue = TRUE;
3999 CK_ATTRIBUTE tokenattr[1];
4000 CK_OBJECT_HANDLE newobj;
4001 CK_RV ckrv;
4002
4003 if (kmfh == NULL)
4004 return (KMF_ERR_UNINITIALIZED);
4005
4006 if (kmfh->pk11handle == CK_INVALID_HANDLE)
4007 return (KMF_ERR_NO_TOKEN_SELECTED);
4008
4009 rv = kmf_get_attr(KMF_CREDENTIAL_ATTR, attlist, numattr,
4010 (void *)&cred, NULL);
4011 if (rv != KMF_OK)
4012 return (KMF_ERR_BAD_PARAMETER);
4013
4014 rv = pk11_authenticate(handle, &cred);
4015 if (rv != KMF_OK)
4016 return (rv);
4017
4018 key = kmf_get_attr_ptr(KMF_PUBKEY_HANDLE_ATTR, attlist, numattr);
4019 if (key == NULL) {
4020 key = kmf_get_attr_ptr(KMF_PRIVKEY_HANDLE_ATTR, attlist,
4021 numattr);
4022 if (key == NULL)
4023 rawkey = kmf_get_attr_ptr(KMF_RAW_KEY_ATTR, attlist,
4024 numattr);
4025 }
4026 if (key == NULL && rawkey == NULL)
4027 return (KMF_ERR_ATTR_NOT_FOUND);
4028
4029 if (rawkey != NULL) {
4030 rv = store_raw_key(handle, attlist, numattr, rawkey);
4031 } else if (key && key->kstype == KMF_KEYSTORE_PK11TOKEN) {
4032
4033 SETATTR(tokenattr, 0, CKA_TOKEN, &btrue, sizeof (btrue));
4034 /* Copy the key object to the token */
4035 ckrv = C_CopyObject(kmfh->pk11handle,
4036 (CK_OBJECT_HANDLE)key->keyp, tokenattr, 1, &newobj);
4037 if (ckrv != CKR_OK) {
4038 SET_ERROR(kmfh, ckrv);
4039 return (KMF_ERR_INTERNAL);
4040 }
4041
4042 /* Replace the object handle with the new token-based one */
4043 ckrv = C_DestroyObject(kmfh->pk11handle,
4044 (CK_OBJECT_HANDLE)key->keyp);
4045 if (ckrv != CKR_OK) {
4046 SET_ERROR(kmfh, ckrv);
4047 return (KMF_ERR_INTERNAL);
4048 }
4049 key->keyp = (void *)newobj;
4050 } else {
4051 rv = KMF_ERR_BAD_PARAMETER;
4052 }
4053
4054 return (rv);
4055 }
4056
4057
4058 KMF_RETURN
KMFPK11_ExportPK12(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)4059 KMFPK11_ExportPK12(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
4060 {
4061 KMF_RETURN rv = KMF_OK;
4062 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
4063 KMF_CREDENTIAL *cred = NULL;
4064 KMF_CREDENTIAL *p12cred = NULL;
4065 char *filename = NULL;
4066 KMF_X509_DER_CERT *certlist = NULL;
4067 KMF_KEY_HANDLE *keylist = NULL;
4068 uint32_t numcerts;
4069 uint32_t numkeys;
4070 char *certlabel = NULL;
4071 char *issuer = NULL;
4072 char *subject = NULL;
4073 KMF_BIGINT *serial = NULL;
4074 KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_PK11TOKEN;
4075 KMF_ATTRIBUTE fc_attrlist[16];
4076 int i;
4077
4078 if (kmfh == NULL)
4079 return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */
4080
4081 if (kmfh->pk11handle == CK_INVALID_HANDLE)
4082 return (KMF_ERR_NO_TOKEN_SELECTED);
4083
4084 /* First get the required attributes */
4085 cred = kmf_get_attr_ptr(KMF_CREDENTIAL_ATTR, attrlist, numattr);
4086 if (cred == NULL)
4087 return (KMF_ERR_BAD_PARAMETER);
4088
4089 p12cred = kmf_get_attr_ptr(KMF_PK12CRED_ATTR, attrlist, numattr);
4090 if (p12cred == NULL)
4091 return (KMF_ERR_BAD_PARAMETER);
4092
4093 filename = kmf_get_attr_ptr(KMF_OUTPUT_FILENAME_ATTR, attrlist,
4094 numattr);
4095 if (filename == NULL)
4096 return (KMF_ERR_BAD_PARAMETER);
4097
4098 /* Find all the certificates that match the searching criteria */
4099 i = 0;
4100 kmf_set_attr_at_index(fc_attrlist, i,
4101 KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype));
4102 i++;
4103
4104 kmf_set_attr_at_index(fc_attrlist, i,
4105 KMF_COUNT_ATTR, &numcerts, sizeof (uint32_t));
4106 i++;
4107
4108 certlabel = kmf_get_attr_ptr(KMF_CERT_LABEL_ATTR, attrlist, numattr);
4109 if (certlabel != NULL) {
4110 kmf_set_attr_at_index(fc_attrlist, i,
4111 KMF_CERT_LABEL_ATTR, certlabel, strlen(certlabel));
4112 i++;
4113 }
4114
4115 issuer = kmf_get_attr_ptr(KMF_ISSUER_NAME_ATTR, attrlist, numattr);
4116 if (issuer != NULL) {
4117 kmf_set_attr_at_index(fc_attrlist, i,
4118 KMF_ISSUER_NAME_ATTR, issuer, strlen(issuer));
4119 i++;
4120 }
4121
4122 subject = kmf_get_attr_ptr(KMF_SUBJECT_NAME_ATTR, attrlist, numattr);
4123 if (subject != NULL) {
4124 kmf_set_attr_at_index(fc_attrlist, i,
4125 KMF_SUBJECT_NAME_ATTR, subject, strlen(subject));
4126 i++;
4127 }
4128
4129 serial = kmf_get_attr_ptr(KMF_BIGINT_ATTR, attrlist, numattr);
4130 if (serial != NULL) {
4131 kmf_set_attr_at_index(fc_attrlist, i,
4132 KMF_BIGINT_ATTR, serial, sizeof (KMF_BIGINT));
4133 i++;
4134 }
4135
4136 rv = KMFPK11_FindCert(handle, i, fc_attrlist);
4137
4138 if (rv == KMF_OK && numcerts > 0) {
4139 certlist = (KMF_X509_DER_CERT *)malloc(numcerts *
4140 sizeof (KMF_X509_DER_CERT));
4141 if (certlist == NULL)
4142 return (KMF_ERR_MEMORY);
4143
4144 (void) memset(certlist, 0, numcerts *
4145 sizeof (KMF_X509_DER_CERT));
4146
4147 kmf_set_attr_at_index(fc_attrlist, i, KMF_X509_DER_CERT_ATTR,
4148 certlist, sizeof (KMF_X509_DER_CERT));
4149 i++;
4150
4151 rv = kmf_find_cert(handle, i, fc_attrlist);
4152 if (rv != KMF_OK) {
4153 free(certlist);
4154 return (rv);
4155 }
4156 } else {
4157 return (rv);
4158 }
4159
4160 /* For each certificate, find the matching private key */
4161 numkeys = 0;
4162 for (i = 0; i < numcerts; i++) {
4163 KMF_ATTRIBUTE fk_attrlist[16];
4164 int j = 0;
4165 KMF_KEY_HANDLE newkey;
4166 KMF_ENCODE_FORMAT format = KMF_FORMAT_RAWKEY;
4167
4168 kmf_set_attr_at_index(fk_attrlist, j,
4169 KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype));
4170 j++;
4171
4172 kmf_set_attr_at_index(fk_attrlist, j,
4173 KMF_ENCODE_FORMAT_ATTR, &format, sizeof (format));
4174 j++;
4175
4176 kmf_set_attr_at_index(fk_attrlist, j,
4177 KMF_CREDENTIAL_ATTR, cred, sizeof (KMF_CREDENTIAL));
4178 j++;
4179
4180 kmf_set_attr_at_index(fk_attrlist, j,
4181 KMF_CERT_DATA_ATTR, &certlist[i].certificate,
4182 sizeof (KMF_DATA));
4183 j++;
4184
4185 kmf_set_attr_at_index(fk_attrlist, j,
4186 KMF_KEY_HANDLE_ATTR, &newkey, sizeof (KMF_KEY_HANDLE));
4187 j++;
4188
4189 rv = KMFPK11_FindPrikeyByCert(handle, j, fk_attrlist);
4190 if (rv == KMF_OK) {
4191 numkeys++;
4192 keylist = realloc(keylist,
4193 numkeys * sizeof (KMF_KEY_HANDLE));
4194 if (keylist == NULL) {
4195 rv = KMF_ERR_MEMORY;
4196 goto out;
4197 }
4198 keylist[numkeys - 1] = newkey;
4199 } else if (rv == KMF_ERR_KEY_NOT_FOUND) {
4200 /* it is OK if a key is not found */
4201 rv = KMF_OK;
4202 }
4203 }
4204
4205 if (rv != KMF_OK)
4206 goto out;
4207
4208 rv = kmf_build_pk12(handle, numcerts, certlist, numkeys, keylist,
4209 p12cred, filename);
4210
4211 out:
4212 if (certlist != NULL) {
4213 for (i = 0; i < numcerts; i++)
4214 kmf_free_kmf_cert(handle, &certlist[i]);
4215 free(certlist);
4216 }
4217 if (keylist != NULL) {
4218 for (i = 0; i < numkeys; i++)
4219 kmf_free_kmf_key(handle, &keylist[i]);
4220 free(keylist);
4221 }
4222
4223 return (rv);
4224 }
4225