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 /*
22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 * Copyright 2012 Milan Jurik. All rights reserved.
25 */
26
27 #include <stdlib.h>
28 #include <string.h>
29 #include <security/cryptoki.h>
30 #include <sys/crypto/common.h>
31 #include <arcfour.h>
32 #include <aes_impl.h>
33 #include <blowfish_impl.h>
34 #include <bignum.h>
35 #include <des_impl.h>
36 #include <rsa_impl.h>
37 #include "softGlobal.h"
38 #include "softObject.h"
39 #include "softSession.h"
40 #include "softKeystore.h"
41 #include "softKeystoreUtil.h"
42 #include "softCrypt.h"
43
44
45 /*
46 * This attribute table is used by the soft_lookup_attr()
47 * to validate the attributes.
48 */
49 CK_ATTRIBUTE_TYPE attr_map[] = {
50 CKA_PRIVATE,
51 CKA_LABEL,
52 CKA_APPLICATION,
53 CKA_OBJECT_ID,
54 CKA_CERTIFICATE_TYPE,
55 CKA_ISSUER,
56 CKA_SERIAL_NUMBER,
57 CKA_AC_ISSUER,
58 CKA_OWNER,
59 CKA_ATTR_TYPES,
60 CKA_SUBJECT,
61 CKA_ID,
62 CKA_SENSITIVE,
63 CKA_START_DATE,
64 CKA_END_DATE,
65 CKA_MODULUS,
66 CKA_MODULUS_BITS,
67 CKA_PUBLIC_EXPONENT,
68 CKA_PRIVATE_EXPONENT,
69 CKA_PRIME_1,
70 CKA_PRIME_2,
71 CKA_EXPONENT_1,
72 CKA_EXPONENT_2,
73 CKA_COEFFICIENT,
74 CKA_PRIME,
75 CKA_SUBPRIME,
76 CKA_BASE,
77 CKA_EXTRACTABLE,
78 CKA_LOCAL,
79 CKA_NEVER_EXTRACTABLE,
80 CKA_ALWAYS_SENSITIVE,
81 CKA_MODIFIABLE,
82 CKA_ECDSA_PARAMS,
83 CKA_EC_PARAMS,
84 CKA_EC_POINT,
85 CKA_SECONDARY_AUTH,
86 CKA_AUTH_PIN_FLAGS,
87 CKA_HW_FEATURE_TYPE,
88 CKA_RESET_ON_INIT,
89 CKA_HAS_RESET
90 };
91
92 /*
93 * attributes that exists only in public key objects
94 * Note: some attributes may also exist in one or two
95 * other object classes, but they are also listed
96 * because not all object have them.
97 */
98 CK_ATTRIBUTE_TYPE PUB_KEY_ATTRS[] =
99 {
100 CKA_SUBJECT,
101 CKA_ENCRYPT,
102 CKA_WRAP,
103 CKA_VERIFY,
104 CKA_VERIFY_RECOVER,
105 CKA_MODULUS,
106 CKA_MODULUS_BITS,
107 CKA_PUBLIC_EXPONENT,
108 CKA_PRIME,
109 CKA_SUBPRIME,
110 CKA_BASE,
111 CKA_TRUSTED,
112 CKA_ECDSA_PARAMS,
113 CKA_EC_PARAMS,
114 CKA_EC_POINT
115 };
116
117 /*
118 * attributes that exists only in private key objects
119 * Note: some attributes may also exist in one or two
120 * other object classes, but they are also listed
121 * because not all object have them.
122 */
123 CK_ATTRIBUTE_TYPE PRIV_KEY_ATTRS[] =
124 {
125 CKA_DECRYPT,
126 CKA_UNWRAP,
127 CKA_SIGN,
128 CKA_SIGN_RECOVER,
129 CKA_MODULUS,
130 CKA_PUBLIC_EXPONENT,
131 CKA_PRIVATE_EXPONENT,
132 CKA_PRIME,
133 CKA_SUBPRIME,
134 CKA_BASE,
135 CKA_PRIME_1,
136 CKA_PRIME_2,
137 CKA_EXPONENT_1,
138 CKA_EXPONENT_2,
139 CKA_COEFFICIENT,
140 CKA_VALUE_BITS,
141 CKA_SUBJECT,
142 CKA_SENSITIVE,
143 CKA_EXTRACTABLE,
144 CKA_NEVER_EXTRACTABLE,
145 CKA_ALWAYS_SENSITIVE,
146 CKA_EC_PARAMS
147 };
148
149 /*
150 * attributes that exists only in secret key objects
151 * Note: some attributes may also exist in one or two
152 * other object classes, but they are also listed
153 * because not all object have them.
154 */
155 CK_ATTRIBUTE_TYPE SECRET_KEY_ATTRS[] =
156 {
157 CKA_VALUE_LEN,
158 CKA_ENCRYPT,
159 CKA_DECRYPT,
160 CKA_WRAP,
161 CKA_UNWRAP,
162 CKA_SIGN,
163 CKA_VERIFY,
164 CKA_SENSITIVE,
165 CKA_EXTRACTABLE,
166 CKA_NEVER_EXTRACTABLE,
167 CKA_ALWAYS_SENSITIVE
168 };
169
170 /*
171 * attributes that exists only in domain parameter objects
172 * Note: some attributes may also exist in one or two
173 * other object classes, but they are also listed
174 * because not all object have them.
175 */
176 CK_ATTRIBUTE_TYPE DOMAIN_ATTRS[] =
177 {
178 CKA_PRIME,
179 CKA_SUBPRIME,
180 CKA_BASE,
181 CKA_PRIME_BITS,
182 CKA_SUBPRIME_BITS,
183 CKA_SUB_PRIME_BITS
184 };
185
186 /*
187 * attributes that exists only in hardware feature objects
188 *
189 */
190 CK_ATTRIBUTE_TYPE HARDWARE_ATTRS[] =
191 {
192 CKA_HW_FEATURE_TYPE,
193 CKA_RESET_ON_INIT,
194 CKA_HAS_RESET
195 };
196
197 /*
198 * attributes that exists only in certificate objects
199 */
200 CK_ATTRIBUTE_TYPE CERT_ATTRS[] =
201 {
202 CKA_CERTIFICATE_TYPE,
203 CKA_TRUSTED,
204 CKA_SUBJECT,
205 CKA_ID,
206 CKA_ISSUER,
207 CKA_AC_ISSUER,
208 CKA_SERIAL_NUMBER,
209 CKA_OWNER,
210 CKA_ATTR_TYPES
211 };
212
213
214 /*
215 * Validate the attribute by using binary search algorithm.
216 */
217 CK_RV
soft_lookup_attr(CK_ATTRIBUTE_TYPE type)218 soft_lookup_attr(CK_ATTRIBUTE_TYPE type)
219 {
220
221 size_t lower, middle, upper;
222
223 lower = 0;
224 upper = (sizeof (attr_map) / sizeof (CK_ATTRIBUTE_TYPE)) - 1;
225
226 while (lower <= upper) {
227 /* Always starts from middle. */
228 middle = (lower + upper) / 2;
229
230 if (type > attr_map[middle]) {
231 /* Adjust the lower bound to upper half. */
232 lower = middle + 1;
233 continue;
234 }
235
236 if (type == attr_map[middle]) {
237 /* Found it. */
238 return (CKR_OK);
239 }
240
241 if (type < attr_map[middle]) {
242 /* Adjust the upper bound to lower half. */
243 upper = middle - 1;
244 continue;
245 }
246 }
247
248 /* Failed to find the matching attribute from the attribute table. */
249 return (CKR_ATTRIBUTE_TYPE_INVALID);
250 }
251
252
253 /*
254 * Validate the attribute by using the following search algorithm:
255 *
256 * 1) Search for the most frequently used attributes first.
257 * 2) If not found, search for the usage-purpose attributes - these
258 * attributes have dense set of values, therefore compiler will
259 * optimize it with a branch table and branch to the appropriate
260 * case.
261 * 3) If still not found, use binary search for the rest of the
262 * attributes in the attr_map[] table.
263 */
264 CK_RV
soft_validate_attr(CK_ATTRIBUTE_PTR template,CK_ULONG ulAttrNum,CK_OBJECT_CLASS * class)265 soft_validate_attr(CK_ATTRIBUTE_PTR template, CK_ULONG ulAttrNum,
266 CK_OBJECT_CLASS *class)
267 {
268
269 CK_ULONG i;
270 CK_RV rv = CKR_OK;
271
272 for (i = 0; i < ulAttrNum; i++) {
273 /* First tier search */
274 switch (template[i].type) {
275 case CKA_CLASS:
276 *class = *((CK_OBJECT_CLASS*)template[i].pValue);
277 break;
278 case CKA_TOKEN:
279 break;
280 case CKA_KEY_TYPE:
281 break;
282 case CKA_VALUE:
283 break;
284 case CKA_VALUE_LEN:
285 break;
286 case CKA_VALUE_BITS:
287 break;
288 default:
289 /* Second tier search */
290 switch (template[i].type) {
291 case CKA_ENCRYPT:
292 break;
293 case CKA_DECRYPT:
294 break;
295 case CKA_WRAP:
296 break;
297 case CKA_UNWRAP:
298 break;
299 case CKA_SIGN:
300 break;
301 case CKA_SIGN_RECOVER:
302 break;
303 case CKA_VERIFY:
304 break;
305 case CKA_VERIFY_RECOVER:
306 break;
307 case CKA_DERIVE:
308 break;
309 default:
310 /* Third tier search */
311 rv = soft_lookup_attr(template[i].type);
312 if (rv != CKR_OK)
313 return (rv);
314 break;
315 }
316 break;
317 }
318 }
319 return (rv);
320 }
321
322 static void
cleanup_cert_attr(cert_attr_t * attr)323 cleanup_cert_attr(cert_attr_t *attr)
324 {
325 if (attr) {
326 if (attr->value) {
327 (void) memset(attr->value, 0, attr->length);
328 free(attr->value);
329 }
330 attr->value = NULL;
331 attr->length = 0;
332 }
333 }
334
335 static CK_RV
copy_cert_attr(cert_attr_t * src_attr,cert_attr_t ** dest_attr)336 copy_cert_attr(cert_attr_t *src_attr, cert_attr_t **dest_attr)
337 {
338 CK_RV rv = CKR_OK;
339
340 if (src_attr == NULL || dest_attr == NULL)
341 return (CKR_HOST_MEMORY);
342
343 if (src_attr->value == NULL)
344 return (CKR_HOST_MEMORY);
345
346 /* free memory if its already allocated */
347 if (*dest_attr != NULL) {
348 if ((*dest_attr)->value != (CK_BYTE *)NULL)
349 free((*dest_attr)->value);
350 } else {
351 *dest_attr = malloc(sizeof (cert_attr_t));
352 if (*dest_attr == NULL)
353 return (CKR_HOST_MEMORY);
354 }
355
356 (*dest_attr)->value = NULL;
357 (*dest_attr)->length = 0;
358
359 if (src_attr->length) {
360 (*dest_attr)->value = malloc(src_attr->length);
361 if ((*dest_attr)->value == NULL) {
362 free(*dest_attr);
363 return (CKR_HOST_MEMORY);
364 }
365
366 (void) memcpy((*dest_attr)->value, src_attr->value,
367 src_attr->length);
368 (*dest_attr)->length = src_attr->length;
369 }
370
371 return (rv);
372 }
373
374 void
soft_cleanup_cert_object(soft_object_t * object_p)375 soft_cleanup_cert_object(soft_object_t *object_p)
376 {
377 CK_CERTIFICATE_TYPE certtype = object_p->cert_type;
378
379 if (object_p->class != CKO_CERTIFICATE ||
380 OBJ_CERT(object_p) == NULL)
381 return;
382
383 if (certtype == CKC_X_509) {
384 if (X509_CERT_SUBJECT(object_p) != NULL) {
385 cleanup_cert_attr(X509_CERT_SUBJECT(object_p));
386 free(X509_CERT_SUBJECT(object_p));
387 X509_CERT_SUBJECT(object_p) = NULL;
388 }
389 if (X509_CERT_VALUE(object_p) != NULL) {
390 cleanup_cert_attr(X509_CERT_VALUE(object_p));
391 free(X509_CERT_VALUE(object_p));
392 X509_CERT_VALUE(object_p) = NULL;
393 }
394 free(OBJ_CERT(object_p));
395 } else if (certtype == CKC_X_509_ATTR_CERT) {
396 if (X509_ATTR_CERT_VALUE(object_p) != NULL) {
397 cleanup_cert_attr(X509_ATTR_CERT_VALUE(object_p));
398 free(X509_ATTR_CERT_VALUE(object_p));
399 X509_ATTR_CERT_VALUE(object_p) = NULL;
400 }
401 if (X509_ATTR_CERT_OWNER(object_p) != NULL) {
402 cleanup_cert_attr(X509_ATTR_CERT_OWNER(object_p));
403 free(X509_ATTR_CERT_OWNER(object_p));
404 X509_ATTR_CERT_OWNER(object_p) = NULL;
405 }
406 free(OBJ_CERT(object_p));
407 }
408 }
409
410 /*
411 * Clean up and release all the storage in the extra attribute list
412 * of an object.
413 */
414 void
soft_cleanup_extra_attr(soft_object_t * object_p)415 soft_cleanup_extra_attr(soft_object_t *object_p)
416 {
417
418 CK_ATTRIBUTE_INFO_PTR extra_attr;
419 CK_ATTRIBUTE_INFO_PTR tmp;
420
421 extra_attr = object_p->extra_attrlistp;
422 while (extra_attr) {
423 tmp = extra_attr->next;
424 if (extra_attr->attr.pValue)
425 /*
426 * All extra attributes in the extra attribute
427 * list have pValue points to the value of the
428 * attribute (with simple byte array type).
429 * Free the storage for the value of the attribute.
430 */
431 free(extra_attr->attr.pValue);
432
433 /* Free the storage for the attribute_info struct. */
434 free(extra_attr);
435 extra_attr = tmp;
436 }
437
438 object_p->extra_attrlistp = NULL;
439 }
440
441
442 /*
443 * Create the attribute_info struct to hold the object's attribute,
444 * and add it to the extra attribute list of an object.
445 */
446 CK_RV
soft_add_extra_attr(CK_ATTRIBUTE_PTR template,soft_object_t * object_p)447 soft_add_extra_attr(CK_ATTRIBUTE_PTR template, soft_object_t *object_p)
448 {
449
450 CK_ATTRIBUTE_INFO_PTR attrp;
451
452 /* Allocate the storage for the attribute_info struct. */
453 attrp = calloc(1, sizeof (attribute_info_t));
454 if (attrp == NULL) {
455 return (CKR_HOST_MEMORY);
456 }
457
458 /* Set up attribute_info struct. */
459 attrp->attr.type = template->type;
460 attrp->attr.ulValueLen = template->ulValueLen;
461
462 if ((template->pValue != NULL) &&
463 (template->ulValueLen > 0)) {
464 /* Allocate storage for the value of the attribute. */
465 attrp->attr.pValue = malloc(template->ulValueLen);
466 if (attrp->attr.pValue == NULL) {
467 free(attrp);
468 return (CKR_HOST_MEMORY);
469 }
470
471 (void) memcpy(attrp->attr.pValue, template->pValue,
472 template->ulValueLen);
473 } else {
474 attrp->attr.pValue = NULL;
475 }
476
477 /* Insert the new attribute in front of extra attribute list. */
478 if (object_p->extra_attrlistp == NULL) {
479 object_p->extra_attrlistp = attrp;
480 attrp->next = NULL;
481 } else {
482 attrp->next = object_p->extra_attrlistp;
483 object_p->extra_attrlistp = attrp;
484 }
485
486 return (CKR_OK);
487 }
488
489 CK_RV
soft_copy_certificate(certificate_obj_t * oldcert,certificate_obj_t ** newcert,CK_CERTIFICATE_TYPE type)490 soft_copy_certificate(certificate_obj_t *oldcert, certificate_obj_t **newcert,
491 CK_CERTIFICATE_TYPE type)
492 {
493 CK_RV rv = CKR_OK;
494 certificate_obj_t *cert;
495 x509_cert_t x509;
496 x509_attr_cert_t x509_attr;
497
498 cert = calloc(1, sizeof (certificate_obj_t));
499 if (cert == NULL) {
500 return (CKR_HOST_MEMORY);
501 }
502
503 if (type == CKC_X_509) {
504 x509 = oldcert->cert_type_u.x509;
505 if (x509.subject)
506 if ((rv = copy_cert_attr(x509.subject,
507 &cert->cert_type_u.x509.subject)))
508 return (rv);
509 if (x509.value)
510 if ((rv = copy_cert_attr(x509.value,
511 &cert->cert_type_u.x509.value)))
512 return (rv);
513 } else if (type == CKC_X_509_ATTR_CERT) {
514 x509_attr = oldcert->cert_type_u.x509_attr;
515 if (x509_attr.owner)
516 if ((rv = copy_cert_attr(x509_attr.owner,
517 &cert->cert_type_u.x509_attr.owner)))
518 return (rv);
519 if (x509_attr.value)
520 if ((rv = copy_cert_attr(x509_attr.value,
521 &cert->cert_type_u.x509_attr.value)))
522 return (rv);
523 } else {
524 /* wrong certificate type */
525 rv = CKR_ATTRIBUTE_TYPE_INVALID;
526 }
527 if (rv == CKR_OK)
528 *newcert = cert;
529 return (rv);
530 }
531
532 /*
533 * Copy the attribute_info struct from the old object to a new attribute_info
534 * struct, and add that new struct to the extra attribute list of the new
535 * object.
536 */
537 CK_RV
soft_copy_extra_attr(CK_ATTRIBUTE_INFO_PTR old_attrp,soft_object_t * object_p)538 soft_copy_extra_attr(CK_ATTRIBUTE_INFO_PTR old_attrp, soft_object_t *object_p)
539 {
540 CK_ATTRIBUTE_INFO_PTR attrp;
541
542 /* Allocate attribute_info struct. */
543 attrp = calloc(1, sizeof (attribute_info_t));
544 if (attrp == NULL) {
545 return (CKR_HOST_MEMORY);
546 }
547
548 attrp->attr.type = old_attrp->attr.type;
549 attrp->attr.ulValueLen = old_attrp->attr.ulValueLen;
550
551 if ((old_attrp->attr.pValue != NULL) &&
552 (old_attrp->attr.ulValueLen > 0)) {
553 attrp->attr.pValue = malloc(old_attrp->attr.ulValueLen);
554 if (attrp->attr.pValue == NULL) {
555 free(attrp);
556 return (CKR_HOST_MEMORY);
557 }
558
559 (void) memcpy(attrp->attr.pValue, old_attrp->attr.pValue,
560 old_attrp->attr.ulValueLen);
561 } else {
562 attrp->attr.pValue = NULL;
563 }
564
565 /* Insert the new attribute in front of extra attribute list */
566 if (object_p->extra_attrlistp == NULL) {
567 object_p->extra_attrlistp = attrp;
568 attrp->next = NULL;
569 } else {
570 attrp->next = object_p->extra_attrlistp;
571 object_p->extra_attrlistp = attrp;
572 }
573
574 return (CKR_OK);
575 }
576
577
578 /*
579 * Get the attribute triple from the extra attribute list in the object
580 * (if the specified attribute type is found), and copy it to a template.
581 * Note the type of the attribute to be copied is specified by the template,
582 * and the storage is pre-allocated for the atrribute value in the template
583 * for doing the copy.
584 */
585 CK_RV
get_extra_attr_from_object(soft_object_t * object_p,CK_ATTRIBUTE_PTR template)586 get_extra_attr_from_object(soft_object_t *object_p, CK_ATTRIBUTE_PTR template)
587 {
588
589 CK_ATTRIBUTE_INFO_PTR extra_attr;
590 CK_ATTRIBUTE_TYPE type = template->type;
591
592 extra_attr = object_p->extra_attrlistp;
593
594 while (extra_attr) {
595 if (type == extra_attr->attr.type) {
596 /* Found it. */
597 break;
598 } else {
599 /* Does not match, try next one. */
600 extra_attr = extra_attr->next;
601 }
602 }
603
604 if (extra_attr == NULL) {
605 /* A valid but un-initialized attribute. */
606 template->ulValueLen = 0;
607 return (CKR_OK);
608 }
609
610 /*
611 * We found the attribute in the extra attribute list.
612 */
613 if (template->pValue == NULL) {
614 template->ulValueLen = extra_attr->attr.ulValueLen;
615 return (CKR_OK);
616 }
617
618 if (template->ulValueLen >= extra_attr->attr.ulValueLen) {
619 /*
620 * The buffer provided by the application is large
621 * enough to hold the value of the attribute.
622 */
623 (void) memcpy(template->pValue, extra_attr->attr.pValue,
624 extra_attr->attr.ulValueLen);
625 template->ulValueLen = extra_attr->attr.ulValueLen;
626 return (CKR_OK);
627 } else {
628 /*
629 * The buffer provided by the application does
630 * not have enough space to hold the value.
631 */
632 template->ulValueLen = (CK_ULONG)-1;
633 return (CKR_BUFFER_TOO_SMALL);
634 }
635 }
636
637
638 /*
639 * Modify the attribute triple in the extra attribute list of the object
640 * if the specified attribute type is found. Otherwise, just add it to
641 * list.
642 */
643 CK_RV
set_extra_attr_to_object(soft_object_t * object_p,CK_ATTRIBUTE_TYPE type,CK_ATTRIBUTE_PTR template)644 set_extra_attr_to_object(soft_object_t *object_p, CK_ATTRIBUTE_TYPE type,
645 CK_ATTRIBUTE_PTR template)
646 {
647
648 CK_ATTRIBUTE_INFO_PTR extra_attr;
649
650 extra_attr = object_p->extra_attrlistp;
651
652 while (extra_attr) {
653 if (type == extra_attr->attr.type) {
654 /* Found it. */
655 break;
656 } else {
657 /* Does not match, try next one. */
658 extra_attr = extra_attr->next;
659 }
660 }
661
662 if (extra_attr == NULL) {
663 /*
664 * This attribute is a new one, go ahead adding it to
665 * the extra attribute list.
666 */
667 return (soft_add_extra_attr(template, object_p));
668 }
669
670 /* We found the attribute in the extra attribute list. */
671 if ((template->pValue != NULL) &&
672 (template->ulValueLen > 0)) {
673 if (template->ulValueLen > extra_attr->attr.ulValueLen) {
674 /* The old buffer is too small to hold the new value. */
675 if (extra_attr->attr.pValue != NULL)
676 /* Free storage for the old attribute value. */
677 free(extra_attr->attr.pValue);
678
679 /* Allocate storage for the new attribute value. */
680 extra_attr->attr.pValue = malloc(template->ulValueLen);
681 if (extra_attr->attr.pValue == NULL) {
682 return (CKR_HOST_MEMORY);
683 }
684 }
685
686 /* Replace the attribute with new value. */
687 extra_attr->attr.ulValueLen = template->ulValueLen;
688 (void) memcpy(extra_attr->attr.pValue, template->pValue,
689 template->ulValueLen);
690 } else {
691 extra_attr->attr.pValue = NULL;
692 }
693
694 return (CKR_OK);
695 }
696
697
698 /*
699 * Copy the big integer attribute value from template to a biginteger_t struct.
700 */
701 CK_RV
get_bigint_attr_from_template(biginteger_t * big,CK_ATTRIBUTE_PTR template)702 get_bigint_attr_from_template(biginteger_t *big, CK_ATTRIBUTE_PTR template)
703 {
704
705 if ((template->pValue != NULL) &&
706 (template->ulValueLen > 0)) {
707 /* Allocate storage for the value of the attribute. */
708 big->big_value = malloc(template->ulValueLen);
709 if (big->big_value == NULL) {
710 return (CKR_HOST_MEMORY);
711 }
712
713 (void) memcpy(big->big_value, template->pValue,
714 template->ulValueLen);
715 big->big_value_len = template->ulValueLen;
716 } else {
717 big->big_value = NULL;
718 big->big_value_len = 0;
719 }
720
721 return (CKR_OK);
722 }
723
724
725 /*
726 * Copy the big integer attribute value from a biginteger_t struct in the
727 * object to a template.
728 */
729 CK_RV
get_bigint_attr_from_object(biginteger_t * big,CK_ATTRIBUTE_PTR template)730 get_bigint_attr_from_object(biginteger_t *big, CK_ATTRIBUTE_PTR template)
731 {
732
733 if (template->pValue == NULL) {
734 template->ulValueLen = big->big_value_len;
735 return (CKR_OK);
736 }
737
738 if (big->big_value == NULL) {
739 template->ulValueLen = 0;
740 return (CKR_OK);
741 }
742
743 if (template->ulValueLen >= big->big_value_len) {
744 /*
745 * The buffer provided by the application is large
746 * enough to hold the value of the attribute.
747 */
748 (void) memcpy(template->pValue, big->big_value,
749 big->big_value_len);
750 template->ulValueLen = big->big_value_len;
751 return (CKR_OK);
752 } else {
753 /*
754 * The buffer provided by the application does
755 * not have enough space to hold the value.
756 */
757 template->ulValueLen = (CK_ULONG)-1;
758 return (CKR_BUFFER_TOO_SMALL);
759 }
760 }
761
762
763 /*
764 * Copy the boolean data type attribute value from an object for the
765 * specified attribute to the template.
766 */
767 CK_RV
get_bool_attr_from_object(soft_object_t * object_p,CK_ULONG bool_flag,CK_ATTRIBUTE_PTR template)768 get_bool_attr_from_object(soft_object_t *object_p, CK_ULONG bool_flag,
769 CK_ATTRIBUTE_PTR template)
770 {
771
772 if (template->pValue == NULL) {
773 template->ulValueLen = sizeof (CK_BBOOL);
774 return (CKR_OK);
775 }
776
777 if (template->ulValueLen >= sizeof (CK_BBOOL)) {
778 /*
779 * The buffer provided by the application is large
780 * enough to hold the value of the attribute.
781 */
782 if (object_p->bool_attr_mask & bool_flag) {
783 *((CK_BBOOL *)template->pValue) = B_TRUE;
784 } else {
785 *((CK_BBOOL *)template->pValue) = B_FALSE;
786 }
787
788 template->ulValueLen = sizeof (CK_BBOOL);
789 return (CKR_OK);
790 } else {
791 /*
792 * The buffer provided by the application does
793 * not have enough space to hold the value.
794 */
795 template->ulValueLen = (CK_ULONG)-1;
796 return (CKR_BUFFER_TOO_SMALL);
797 }
798 }
799
800 /*
801 * Set the boolean data type attribute value in the object.
802 */
803 CK_RV
set_bool_attr_to_object(soft_object_t * object_p,CK_ULONG bool_flag,CK_ATTRIBUTE_PTR template)804 set_bool_attr_to_object(soft_object_t *object_p, CK_ULONG bool_flag,
805 CK_ATTRIBUTE_PTR template)
806 {
807
808 if (*(CK_BBOOL *)template->pValue)
809 object_p->bool_attr_mask |= bool_flag;
810 else
811 object_p->bool_attr_mask &= ~bool_flag;
812
813 return (CKR_OK);
814 }
815
816
817 /*
818 * Copy the CK_ULONG data type attribute value from an object to the
819 * template.
820 */
821 CK_RV
get_ulong_attr_from_object(CK_ULONG value,CK_ATTRIBUTE_PTR template)822 get_ulong_attr_from_object(CK_ULONG value, CK_ATTRIBUTE_PTR template)
823 {
824
825 if (template->pValue == NULL) {
826 template->ulValueLen = sizeof (CK_ULONG);
827 return (CKR_OK);
828 }
829
830 if (template->ulValueLen >= sizeof (CK_ULONG)) {
831 /*
832 * The buffer provided by the application is large
833 * enough to hold the value of the attribute.
834 * It is also assumed to be correctly aligned.
835 */
836 *(CK_ULONG_PTR)template->pValue = value;
837 template->ulValueLen = sizeof (CK_ULONG);
838 return (CKR_OK);
839 } else {
840 /*
841 * The buffer provided by the application does
842 * not have enough space to hold the value.
843 */
844 template->ulValueLen = (CK_ULONG)-1;
845 return (CKR_BUFFER_TOO_SMALL);
846 }
847 }
848
849
850 /*
851 * Copy the CK_ULONG data type attribute value from a template to the
852 * object.
853 */
854 static CK_RV
get_ulong_attr_from_template(CK_ULONG * value,CK_ATTRIBUTE_PTR template)855 get_ulong_attr_from_template(CK_ULONG *value, CK_ATTRIBUTE_PTR template)
856 {
857
858 if (template->ulValueLen < sizeof (CK_ULONG))
859 return (CKR_ATTRIBUTE_VALUE_INVALID);
860
861 if (template->pValue != NULL) {
862 *value = *(CK_ULONG_PTR)template->pValue;
863 } else {
864 *value = 0;
865 }
866
867 return (CKR_OK);
868 }
869
870 /*
871 * Copy the big integer attribute value from source's biginteger_t to
872 * destination's biginteger_t.
873 */
874 void
copy_bigint_attr(biginteger_t * src,biginteger_t * dst)875 copy_bigint_attr(biginteger_t *src, biginteger_t *dst)
876 {
877
878 if ((src->big_value != NULL) &&
879 (src->big_value_len > 0)) {
880 /*
881 * To do the copy, just have dst's big_value points
882 * to src's.
883 */
884 dst->big_value = src->big_value;
885 dst->big_value_len = src->big_value_len;
886
887 /*
888 * After the copy, nullify the src's big_value pointer.
889 * It prevents any double freeing the value.
890 */
891 src->big_value = NULL;
892 src->big_value_len = 0;
893 } else {
894 dst->big_value = NULL;
895 dst->big_value_len = 0;
896 }
897 }
898
899 CK_RV
get_string_from_template(CK_ATTRIBUTE_PTR dest,CK_ATTRIBUTE_PTR src)900 get_string_from_template(CK_ATTRIBUTE_PTR dest, CK_ATTRIBUTE_PTR src)
901 {
902 if ((src->pValue != NULL) &&
903 (src->ulValueLen > 0)) {
904 /* Allocate storage for the value of the attribute. */
905 dest->pValue = malloc(src->ulValueLen);
906 if (dest->pValue == NULL) {
907 return (CKR_HOST_MEMORY);
908 }
909
910 (void) memcpy(dest->pValue, src->pValue,
911 src->ulValueLen);
912 dest->ulValueLen = src->ulValueLen;
913 dest->type = src->type;
914 } else {
915 dest->pValue = NULL;
916 dest->ulValueLen = 0;
917 dest->type = src->type;
918 }
919
920 return (CKR_OK);
921
922 }
923
924 CK_RV
get_cert_attr_from_template(cert_attr_t ** dest,CK_ATTRIBUTE_PTR src)925 get_cert_attr_from_template(cert_attr_t **dest, CK_ATTRIBUTE_PTR src)
926 {
927 if (src->pValue != NULL && src->ulValueLen > 0) {
928 /*
929 * If the attribute was already set, clear out the
930 * existing value and release the memory.
931 */
932 if (*dest != NULL) {
933 if ((*dest)->value != NULL) {
934 (void) memset((*dest)->value, 0,
935 (*dest)->length);
936 free((*dest)->value);
937 }
938 } else {
939 *dest = malloc(sizeof (cert_attr_t));
940 if (*dest == NULL) {
941 return (CKR_HOST_MEMORY);
942 }
943 (void) memset(*dest, 0, sizeof (cert_attr_t));
944 }
945 (*dest)->value = malloc(src->ulValueLen);
946 if ((*dest)->value == NULL) {
947 free(*dest);
948 *dest = NULL;
949 return (CKR_HOST_MEMORY);
950 }
951 (void) memcpy((*dest)->value, src->pValue, src->ulValueLen);
952 (*dest)->length = src->ulValueLen;
953 }
954
955 return (CKR_OK);
956 }
957
958 /*
959 * Copy the certificate attribute information to the template.
960 * If the template attribute is not big enough, set the ulValueLen=-1
961 * and return CKR_BUFFER_TOO_SMALL.
962 */
963 static CK_RV
get_cert_attr_from_object(cert_attr_t * src,CK_ATTRIBUTE_PTR template)964 get_cert_attr_from_object(cert_attr_t *src, CK_ATTRIBUTE_PTR template)
965 {
966 if (template->pValue == NULL) {
967 template->ulValueLen = src->length;
968 return (CKR_OK);
969 } else if (template->ulValueLen >= src->length) {
970 /*
971 * The buffer provided by the application is large
972 * enough to hold the value of the attribute.
973 */
974 (void) memcpy(template->pValue, src->value, src->length);
975 template->ulValueLen = src->length;
976 return (CKR_OK);
977 } else {
978 /*
979 * The buffer provided by the application does
980 * not have enough space to hold the value.
981 */
982 template->ulValueLen = (CK_ULONG)-1;
983 return (CKR_BUFFER_TOO_SMALL);
984 }
985 }
986
987 void
string_attr_cleanup(CK_ATTRIBUTE_PTR template)988 string_attr_cleanup(CK_ATTRIBUTE_PTR template)
989 {
990
991 if (template->pValue) {
992 free(template->pValue);
993 template->pValue = NULL;
994 template->ulValueLen = 0;
995 }
996 }
997
998 /*
999 * Release the storage allocated for object attribute with big integer
1000 * value.
1001 */
1002 void
bigint_attr_cleanup(biginteger_t * big)1003 bigint_attr_cleanup(biginteger_t *big)
1004 {
1005
1006 if (big == NULL)
1007 return;
1008
1009 if (big->big_value) {
1010 (void) memset(big->big_value, 0, big->big_value_len);
1011 free(big->big_value);
1012 big->big_value = NULL;
1013 big->big_value_len = 0;
1014 }
1015 }
1016
1017
1018 /*
1019 * Clean up and release all the storage allocated to hold the big integer
1020 * attributes associated with the type (i.e. class) of the object. Also,
1021 * release the storage allocated to the type of the object.
1022 */
1023 void
soft_cleanup_object_bigint_attrs(soft_object_t * object_p)1024 soft_cleanup_object_bigint_attrs(soft_object_t *object_p)
1025 {
1026
1027 CK_OBJECT_CLASS class = object_p->class;
1028 CK_KEY_TYPE keytype = object_p->key_type;
1029
1030
1031 switch (class) {
1032 case CKO_PUBLIC_KEY:
1033 if (OBJ_PUB(object_p)) {
1034 switch (keytype) {
1035 case CKK_RSA:
1036 bigint_attr_cleanup(OBJ_PUB_RSA_MOD(
1037 object_p));
1038 bigint_attr_cleanup(OBJ_PUB_RSA_PUBEXPO(
1039 object_p));
1040 break;
1041
1042 case CKK_DSA:
1043 bigint_attr_cleanup(OBJ_PUB_DSA_PRIME(
1044 object_p));
1045 bigint_attr_cleanup(OBJ_PUB_DSA_SUBPRIME(
1046 object_p));
1047 bigint_attr_cleanup(OBJ_PUB_DSA_BASE(
1048 object_p));
1049 bigint_attr_cleanup(OBJ_PUB_DSA_VALUE(
1050 object_p));
1051 break;
1052
1053 case CKK_DH:
1054 bigint_attr_cleanup(OBJ_PUB_DH_PRIME(
1055 object_p));
1056 bigint_attr_cleanup(OBJ_PUB_DH_BASE(
1057 object_p));
1058 bigint_attr_cleanup(OBJ_PUB_DH_VALUE(
1059 object_p));
1060 break;
1061
1062 case CKK_X9_42_DH:
1063 bigint_attr_cleanup(OBJ_PUB_DH942_PRIME(
1064 object_p));
1065 bigint_attr_cleanup(OBJ_PUB_DH942_BASE(
1066 object_p));
1067 bigint_attr_cleanup(OBJ_PUB_DH942_SUBPRIME(
1068 object_p));
1069 bigint_attr_cleanup(OBJ_PUB_DH942_VALUE(
1070 object_p));
1071 break;
1072 case CKK_EC:
1073 bigint_attr_cleanup(OBJ_PUB_EC_POINT(
1074 object_p));
1075 break;
1076 }
1077
1078 /* Release Public Key Object struct */
1079 free(OBJ_PUB(object_p));
1080 OBJ_PUB(object_p) = NULL;
1081 }
1082 break;
1083
1084 case CKO_PRIVATE_KEY:
1085 if (OBJ_PRI(object_p)) {
1086 switch (keytype) {
1087 case CKK_RSA:
1088 bigint_attr_cleanup(OBJ_PRI_RSA_MOD(
1089 object_p));
1090 bigint_attr_cleanup(OBJ_PRI_RSA_PUBEXPO(
1091 object_p));
1092 bigint_attr_cleanup(OBJ_PRI_RSA_PRIEXPO(
1093 object_p));
1094 bigint_attr_cleanup(OBJ_PRI_RSA_PRIME1(
1095 object_p));
1096 bigint_attr_cleanup(OBJ_PRI_RSA_PRIME2(
1097 object_p));
1098 bigint_attr_cleanup(OBJ_PRI_RSA_EXPO1(
1099 object_p));
1100 bigint_attr_cleanup(OBJ_PRI_RSA_EXPO2(
1101 object_p));
1102 bigint_attr_cleanup(OBJ_PRI_RSA_COEF(
1103 object_p));
1104 break;
1105
1106 case CKK_DSA:
1107 bigint_attr_cleanup(OBJ_PRI_DSA_PRIME(
1108 object_p));
1109 bigint_attr_cleanup(OBJ_PRI_DSA_SUBPRIME(
1110 object_p));
1111 bigint_attr_cleanup(OBJ_PRI_DSA_BASE(
1112 object_p));
1113 bigint_attr_cleanup(OBJ_PRI_DSA_VALUE(
1114 object_p));
1115 break;
1116
1117 case CKK_DH:
1118 bigint_attr_cleanup(OBJ_PRI_DH_PRIME(
1119 object_p));
1120 bigint_attr_cleanup(OBJ_PRI_DH_BASE(
1121 object_p));
1122 bigint_attr_cleanup(OBJ_PRI_DH_VALUE(
1123 object_p));
1124 break;
1125
1126 case CKK_X9_42_DH:
1127 bigint_attr_cleanup(OBJ_PRI_DH942_PRIME(
1128 object_p));
1129 bigint_attr_cleanup(OBJ_PRI_DH942_BASE(
1130 object_p));
1131 bigint_attr_cleanup(OBJ_PRI_DH942_SUBPRIME(
1132 object_p));
1133 bigint_attr_cleanup(OBJ_PRI_DH942_VALUE(
1134 object_p));
1135 break;
1136
1137 case CKK_EC:
1138 bigint_attr_cleanup(OBJ_PRI_EC_VALUE(
1139 object_p));
1140 break;
1141 }
1142
1143 /* Release Private Key Object struct. */
1144 free(OBJ_PRI(object_p));
1145 OBJ_PRI(object_p) = NULL;
1146 }
1147 break;
1148
1149 case CKO_SECRET_KEY:
1150 if (OBJ_SEC(object_p)) {
1151 /* cleanup key data area */
1152 if (OBJ_SEC_VALUE(object_p) != NULL &&
1153 OBJ_SEC_VALUE_LEN(object_p) > 0) {
1154 (void) memset(OBJ_SEC_VALUE(object_p), 0,
1155 OBJ_SEC_VALUE_LEN(object_p));
1156 free(OBJ_SEC_VALUE(object_p));
1157 }
1158 /* cleanup key schedule data area */
1159 if (OBJ_KEY_SCHED(object_p) != NULL &&
1160 OBJ_KEY_SCHED_LEN(object_p) > 0) {
1161 (void) memset(OBJ_KEY_SCHED(object_p), 0,
1162 OBJ_KEY_SCHED_LEN(object_p));
1163 free(OBJ_KEY_SCHED(object_p));
1164 }
1165
1166 /* Release Secret Key Object struct. */
1167 free(OBJ_SEC(object_p));
1168 OBJ_SEC(object_p) = NULL;
1169 }
1170 break;
1171
1172 case CKO_DOMAIN_PARAMETERS:
1173 if (OBJ_DOM(object_p)) {
1174 switch (keytype) {
1175 case CKK_DSA:
1176 bigint_attr_cleanup(OBJ_DOM_DSA_PRIME(
1177 object_p));
1178 bigint_attr_cleanup(OBJ_DOM_DSA_SUBPRIME(
1179 object_p));
1180 bigint_attr_cleanup(OBJ_DOM_DSA_BASE(
1181 object_p));
1182 break;
1183
1184 case CKK_DH:
1185 bigint_attr_cleanup(OBJ_DOM_DH_PRIME(
1186 object_p));
1187 bigint_attr_cleanup(OBJ_DOM_DH_BASE(
1188 object_p));
1189 break;
1190
1191 case CKK_X9_42_DH:
1192 bigint_attr_cleanup(OBJ_DOM_DH942_PRIME(
1193 object_p));
1194 bigint_attr_cleanup(OBJ_DOM_DH942_BASE(
1195 object_p));
1196 bigint_attr_cleanup(OBJ_DOM_DH942_SUBPRIME(
1197 object_p));
1198 break;
1199 }
1200
1201 /* Release Domain Parameters Object struct. */
1202 free(OBJ_DOM(object_p));
1203 OBJ_DOM(object_p) = NULL;
1204 }
1205 break;
1206 }
1207 }
1208
1209
1210 /*
1211 * Parse the common attributes. Return to caller with appropriate return
1212 * value to indicate if the supplied template specifies a valid attribute
1213 * with a valid value.
1214 */
1215 CK_RV
soft_parse_common_attrs(CK_ATTRIBUTE_PTR template,uchar_t * object_type)1216 soft_parse_common_attrs(CK_ATTRIBUTE_PTR template, uchar_t *object_type)
1217 {
1218
1219 CK_RV rv = CKR_OK;
1220
1221 switch (template->type) {
1222 case CKA_CLASS:
1223 break;
1224
1225 /* default boolean attributes */
1226 case CKA_TOKEN:
1227 if ((*(CK_BBOOL *)template->pValue) == B_TRUE) {
1228 if (!soft_keystore_status(KEYSTORE_INITIALIZED))
1229 return (CKR_DEVICE_REMOVED);
1230 *object_type |= TOKEN_OBJECT;
1231 }
1232 break;
1233
1234 case CKA_PRIVATE:
1235 if ((*(CK_BBOOL *)template->pValue) == B_TRUE) {
1236 (void) pthread_mutex_lock(&soft_giant_mutex);
1237 if (!soft_slot.authenticated) {
1238 /*
1239 * Check if this is the special case when
1240 * the PIN is never initialized in the keystore.
1241 * If true, we will let it pass here and let
1242 * it fail with CKR_PIN_EXPIRED later on.
1243 */
1244 if (!soft_slot.userpin_change_needed) {
1245 (void) pthread_mutex_unlock(
1246 &soft_giant_mutex);
1247 return (CKR_USER_NOT_LOGGED_IN);
1248 }
1249 }
1250 (void) pthread_mutex_unlock(&soft_giant_mutex);
1251 *object_type |= PRIVATE_OBJECT;
1252 }
1253 break;
1254
1255 case CKA_LABEL:
1256 break;
1257
1258 default:
1259 rv = CKR_TEMPLATE_INCONSISTENT;
1260 }
1261
1262 return (rv);
1263 }
1264
1265
1266 /*
1267 * Build a Public Key Object.
1268 *
1269 * - Parse the object's template, and when an error is detected such as
1270 * invalid attribute type, invalid attribute value, etc., return
1271 * with appropriate return value.
1272 * - Set up attribute mask field in the object for the supplied common
1273 * attributes that have boolean type.
1274 * - Build the attribute_info struct to hold the value of each supplied
1275 * attribute that has byte array type. Link attribute_info structs
1276 * together to form the extra attribute list of the object.
1277 * - Allocate storage for the Public Key object.
1278 * - Build the Public Key object according to the key type. Allocate
1279 * storage to hold the big integer value for the supplied attributes
1280 * that are required for a certain key type.
1281 *
1282 */
1283 CK_RV
soft_build_public_key_object(CK_ATTRIBUTE_PTR template,CK_ULONG ulAttrNum,soft_object_t * new_object,CK_ULONG mode,CK_KEY_TYPE key_type)1284 soft_build_public_key_object(CK_ATTRIBUTE_PTR template, CK_ULONG ulAttrNum,
1285 soft_object_t *new_object, CK_ULONG mode, CK_KEY_TYPE key_type)
1286 {
1287
1288 ulong_t i;
1289 CK_KEY_TYPE keytype = (CK_KEY_TYPE)~0UL;
1290 uint64_t attr_mask = PUBLIC_KEY_DEFAULT;
1291 CK_RV rv = CKR_OK;
1292 int isLabel = 0;
1293 /* Must set flags */
1294 int isModulus = 0;
1295 int isPubExpo = 0;
1296 int isPrime = 0;
1297 int isSubprime = 0;
1298 int isBase = 0;
1299 int isValue = 0;
1300 int isECParam = 0;
1301 int isECPoint = 0;
1302 /* Must not set flags */
1303 int isModulusBits = 0;
1304 CK_ULONG modulus_bits = 0;
1305
1306 biginteger_t modulus;
1307 biginteger_t pubexpo;
1308 biginteger_t prime;
1309 biginteger_t subprime;
1310 biginteger_t base;
1311 biginteger_t value;
1312 biginteger_t point;
1313 CK_ATTRIBUTE string_tmp;
1314 CK_ATTRIBUTE param_tmp;
1315
1316 public_key_obj_t *pbk;
1317 uchar_t object_type = 0;
1318
1319 CK_ATTRIBUTE defpubexpo = { CKA_PUBLIC_EXPONENT,
1320 (CK_BYTE_PTR)DEFAULT_PUB_EXPO, DEFAULT_PUB_EXPO_Len };
1321
1322 BIGNUM n;
1323
1324 /* prevent bigint_attr_cleanup from freeing invalid attr value */
1325 (void) memset(&modulus, 0x0, sizeof (biginteger_t));
1326 (void) memset(&pubexpo, 0x0, sizeof (biginteger_t));
1327 (void) memset(&prime, 0x0, sizeof (biginteger_t));
1328 (void) memset(&subprime, 0x0, sizeof (biginteger_t));
1329 (void) memset(&base, 0x0, sizeof (biginteger_t));
1330 (void) memset(&value, 0x0, sizeof (biginteger_t));
1331 (void) memset(&point, 0x0, sizeof (biginteger_t));
1332 string_tmp.pValue = NULL;
1333 param_tmp.pValue = NULL;
1334
1335 for (i = 0; i < ulAttrNum; i++) {
1336
1337 /* Public Key Object Attributes */
1338 switch (template[i].type) {
1339
1340 /* common key attributes */
1341 case CKA_KEY_TYPE:
1342 keytype = *((CK_KEY_TYPE*)template[i].pValue);
1343 break;
1344
1345 case CKA_ID:
1346 case CKA_START_DATE:
1347 case CKA_END_DATE:
1348
1349 /* common public key attribute */
1350 case CKA_SUBJECT:
1351 /*
1352 * Allocate storage to hold the attribute
1353 * value with byte array type, and add it to
1354 * the extra attribute list of the object.
1355 */
1356 rv = soft_add_extra_attr(&template[i],
1357 new_object);
1358 if (rv != CKR_OK) {
1359 goto fail_cleanup;
1360 }
1361 break;
1362
1363 /*
1364 * The following key related attribute types must
1365 * not be specified by C_CreateObject, C_GenerateKey(Pair).
1366 */
1367 case CKA_LOCAL:
1368 case CKA_KEY_GEN_MECHANISM:
1369 rv = CKR_TEMPLATE_INCONSISTENT;
1370 goto fail_cleanup;
1371
1372 /* Key related boolean attributes */
1373 case CKA_DERIVE:
1374 if (*(CK_BBOOL *)template[i].pValue)
1375 attr_mask |= DERIVE_BOOL_ON;
1376 break;
1377
1378 case CKA_ENCRYPT:
1379 if (*(CK_BBOOL *)template[i].pValue)
1380 attr_mask |= ENCRYPT_BOOL_ON;
1381 else
1382 attr_mask &= ~ENCRYPT_BOOL_ON;
1383 break;
1384
1385 case CKA_VERIFY:
1386 if (*(CK_BBOOL *)template[i].pValue)
1387 attr_mask |= VERIFY_BOOL_ON;
1388 else
1389 attr_mask &= ~VERIFY_BOOL_ON;
1390 break;
1391
1392 case CKA_VERIFY_RECOVER:
1393 if (*(CK_BBOOL *)template[i].pValue)
1394 attr_mask |= VERIFY_RECOVER_BOOL_ON;
1395 else
1396 attr_mask &= ~VERIFY_RECOVER_BOOL_ON;
1397 break;
1398
1399 case CKA_WRAP:
1400 if (*(CK_BBOOL *)template[i].pValue)
1401 attr_mask |= WRAP_BOOL_ON;
1402 else
1403 attr_mask &= ~WRAP_BOOL_ON;
1404 break;
1405
1406 case CKA_TRUSTED:
1407 if (*(CK_BBOOL *)template[i].pValue)
1408 attr_mask |= TRUSTED_BOOL_ON;
1409 break;
1410
1411 case CKA_MODIFIABLE:
1412 if ((*(CK_BBOOL *)template[i].pValue) == B_FALSE)
1413 attr_mask |= NOT_MODIFIABLE_BOOL_ON;
1414 break;
1415
1416 /*
1417 * The following key related attribute types must
1418 * be specified according to the key type by
1419 * C_CreateObject.
1420 */
1421 case CKA_MODULUS:
1422
1423 isModulus = 1;
1424 /*
1425 * Copyin big integer attribute from template
1426 * to a local variable.
1427 */
1428 rv = get_bigint_attr_from_template(&modulus,
1429 &template[i]);
1430 if (rv != CKR_OK)
1431 goto fail_cleanup;
1432
1433 /*
1434 * Modulus length needs to be between min key length and
1435 * max key length.
1436 */
1437 if ((modulus.big_value_len <
1438 MIN_RSA_KEYLENGTH_IN_BYTES) ||
1439 (modulus.big_value_len >
1440 MAX_RSA_KEYLENGTH_IN_BYTES)) {
1441 rv = CKR_ATTRIBUTE_VALUE_INVALID;
1442 goto fail_cleanup;
1443 }
1444 break;
1445
1446 case CKA_PUBLIC_EXPONENT:
1447 isPubExpo = 1;
1448 rv = get_bigint_attr_from_template(&pubexpo,
1449 &template[i]);
1450 if (rv != CKR_OK)
1451 goto fail_cleanup;
1452 break;
1453
1454 case CKA_PRIME:
1455 isPrime = 1;
1456 rv = get_bigint_attr_from_template(&prime,
1457 &template[i]);
1458 if (rv != CKR_OK)
1459 goto fail_cleanup;
1460 break;
1461
1462 case CKA_SUBPRIME:
1463 isSubprime = 1;
1464 rv = get_bigint_attr_from_template(&subprime,
1465 &template[i]);
1466 if (rv != CKR_OK)
1467 goto fail_cleanup;
1468 break;
1469
1470 case CKA_BASE:
1471 isBase = 1;
1472 rv = get_bigint_attr_from_template(&base,
1473 &template[i]);
1474 if (rv != CKR_OK)
1475 goto fail_cleanup;
1476 break;
1477
1478 case CKA_VALUE:
1479 isValue = 1;
1480 if (mode == SOFT_CREATE_OBJ) {
1481 if ((template[i].ulValueLen == 0) ||
1482 (template[i].pValue == NULL)) {
1483 rv = CKR_ATTRIBUTE_VALUE_INVALID;
1484 goto fail_cleanup;
1485 }
1486 }
1487
1488 rv = get_bigint_attr_from_template(&value,
1489 &template[i]);
1490 if (rv != CKR_OK)
1491 goto fail_cleanup;
1492 break;
1493
1494 case CKA_MODULUS_BITS:
1495 isModulusBits = 1;
1496 rv = get_ulong_attr_from_template(&modulus_bits,
1497 &template[i]);
1498 if (rv != CKR_OK)
1499 goto fail_cleanup;
1500 break;
1501
1502 case CKA_LABEL:
1503 isLabel = 1;
1504 rv = get_string_from_template(&string_tmp,
1505 &template[i]);
1506 if (rv != CKR_OK)
1507 goto fail_cleanup;
1508 break;
1509
1510 case CKA_EC_PARAMS:
1511 isECParam = 1;
1512 rv = get_string_from_template(¶m_tmp, &template[i]);
1513 if (rv != CKR_OK)
1514 goto fail_cleanup;
1515 break;
1516
1517 case CKA_EC_POINT:
1518 isECPoint = 1;
1519 rv = get_bigint_attr_from_template(&point,
1520 &template[i]);
1521 if (rv != CKR_OK)
1522 goto fail_cleanup;
1523 break;
1524
1525 default:
1526 rv = soft_parse_common_attrs(&template[i],
1527 &object_type);
1528 if (rv != CKR_OK)
1529 goto fail_cleanup;
1530 break;
1531 }
1532 } /* For */
1533
1534 /* Allocate storage for Public Key Object. */
1535 pbk = calloc(1, sizeof (public_key_obj_t));
1536 if (pbk == NULL) {
1537 rv = CKR_HOST_MEMORY;
1538 goto fail_cleanup;
1539 }
1540
1541 new_object->object_class_u.public_key = pbk;
1542 new_object->class = CKO_PUBLIC_KEY;
1543
1544 if ((mode == SOFT_CREATE_OBJ) && (keytype == (CK_KEY_TYPE)~0UL)) {
1545 rv = CKR_TEMPLATE_INCOMPLETE;
1546 goto fail_cleanup;
1547 }
1548
1549 if ((mode == SOFT_GEN_KEY) && (keytype == (CK_KEY_TYPE)~0UL)) {
1550 keytype = key_type;
1551 }
1552
1553 if ((mode == SOFT_GEN_KEY) && (keytype != key_type)) {
1554 /*
1555 * The key type specified in the template does not
1556 * match the implied key type based on the mechanism.
1557 */
1558 rv = CKR_TEMPLATE_INCONSISTENT;
1559 goto fail_cleanup;
1560 }
1561
1562 new_object->key_type = keytype;
1563
1564 /* Supported key types of the Public Key Object */
1565 switch (keytype) {
1566
1567 case CKK_RSA:
1568 if (mode == SOFT_CREATE_OBJ) {
1569 if (isModulusBits || isPrime || isSubprime ||
1570 isBase || isValue) {
1571 rv = CKR_TEMPLATE_INCONSISTENT;
1572 goto fail_cleanup;
1573 }
1574
1575 if (isModulus && isPubExpo) {
1576 /*
1577 * Derive modulus_bits attribute from modulus.
1578 * Save modulus_bits integer value to the
1579 * designated place in the public key object.
1580 */
1581 n.malloced = 0;
1582 #ifdef __sparcv9
1583 if (big_init(&n, (int)CHARLEN2BIGNUMLEN(
1584 modulus.big_value_len)) != BIG_OK) {
1585 #else /* !__sparcv9 */
1586 if (big_init(&n, CHARLEN2BIGNUMLEN(
1587 modulus.big_value_len)) != BIG_OK) {
1588 #endif /* __sparcv9 */
1589 rv = CKR_HOST_MEMORY;
1590 big_finish(&n);
1591 goto fail_cleanup;
1592 }
1593 bytestring2bignum(&n, modulus.big_value,
1594 modulus.big_value_len);
1595
1596 modulus_bits = big_bitlength(&n);
1597 KEY_PUB_RSA_MOD_BITS(pbk) = modulus_bits;
1598 big_finish(&n);
1599
1600 /*
1601 * After modulus_bits has been computed,
1602 * it is safe to move modulus and pubexpo
1603 * big integer attribute value to the
1604 * designated place in the public key object.
1605 */
1606 copy_bigint_attr(&modulus,
1607 KEY_PUB_RSA_MOD(pbk));
1608
1609 copy_bigint_attr(&pubexpo,
1610 KEY_PUB_RSA_PUBEXPO(pbk));
1611 } else {
1612 rv = CKR_TEMPLATE_INCOMPLETE;
1613 goto fail_cleanup;
1614 }
1615 } else {
1616 /* mode is SOFT_GEN_KEY */
1617
1618 if (isModulus || isPrime || isSubprime ||
1619 isBase || isValue) {
1620 rv = CKR_TEMPLATE_INCONSISTENT;
1621 goto fail_cleanup;
1622 }
1623
1624
1625 if (isModulusBits) {
1626 /*
1627 * Copy big integer attribute value to the
1628 * designated place in the public key object.
1629 */
1630 KEY_PUB_RSA_MOD_BITS(pbk) = modulus_bits;
1631 } else {
1632 rv = CKR_TEMPLATE_INCOMPLETE;
1633 goto fail_cleanup;
1634 }
1635
1636 /*
1637 * Use PKCS#11 default 0x010001 for public exponent
1638 * if not not specified in attribute template.
1639 */
1640 if (!isPubExpo) {
1641 isPubExpo = 1;
1642 rv = get_bigint_attr_from_template(&pubexpo,
1643 &defpubexpo);
1644 if (rv != CKR_OK)
1645 goto fail_cleanup;
1646 }
1647 /*
1648 * Copy big integer attribute value to the
1649 * designated place in the public key object.
1650 */
1651 copy_bigint_attr(&pubexpo, KEY_PUB_RSA_PUBEXPO(pbk));
1652 }
1653
1654 break;
1655
1656 case CKK_DSA:
1657 if (mode == SOFT_CREATE_OBJ) {
1658 if (isModulusBits || isModulus || isPubExpo) {
1659 rv = CKR_TEMPLATE_INCONSISTENT;
1660 goto fail_cleanup;
1661 }
1662
1663 if (isPrime && isSubprime && isBase && isValue) {
1664 copy_bigint_attr(&value,
1665 KEY_PUB_DSA_VALUE(pbk));
1666 } else {
1667 rv = CKR_TEMPLATE_INCOMPLETE;
1668 goto fail_cleanup;
1669 }
1670 } else {
1671 if (isModulusBits || isModulus || isPubExpo ||
1672 isValue) {
1673 rv = CKR_TEMPLATE_INCONSISTENT;
1674 goto fail_cleanup;
1675 }
1676
1677 if (!(isPrime && isSubprime && isBase)) {
1678 rv = CKR_TEMPLATE_INCOMPLETE;
1679 goto fail_cleanup;
1680 }
1681 }
1682
1683 copy_bigint_attr(&prime, KEY_PUB_DSA_PRIME(pbk));
1684
1685 copy_bigint_attr(&subprime, KEY_PUB_DSA_SUBPRIME(pbk));
1686
1687 copy_bigint_attr(&base, KEY_PUB_DSA_BASE(pbk));
1688
1689 break;
1690
1691 case CKK_DH:
1692 if (mode == SOFT_CREATE_OBJ) {
1693 if (isModulusBits || isModulus || isPubExpo ||
1694 isSubprime) {
1695 rv = CKR_TEMPLATE_INCONSISTENT;
1696 goto fail_cleanup;
1697 }
1698
1699 if (isPrime && isBase && isValue) {
1700 copy_bigint_attr(&value,
1701 KEY_PUB_DH_VALUE(pbk));
1702 } else {
1703 rv = CKR_TEMPLATE_INCOMPLETE;
1704 goto fail_cleanup;
1705 }
1706 } else {
1707 if (isModulusBits || isModulus || isPubExpo ||
1708 isSubprime || isValue) {
1709 rv = CKR_TEMPLATE_INCONSISTENT;
1710 goto fail_cleanup;
1711 }
1712
1713 if (!(isPrime && isBase)) {
1714 rv = CKR_TEMPLATE_INCOMPLETE;
1715 goto fail_cleanup;
1716 }
1717 }
1718
1719 copy_bigint_attr(&prime, KEY_PUB_DH_PRIME(pbk));
1720
1721 copy_bigint_attr(&base, KEY_PUB_DH_BASE(pbk));
1722
1723 break;
1724
1725 case CKK_X9_42_DH:
1726 if (mode == SOFT_CREATE_OBJ) {
1727 if (isModulusBits || isModulus || isPubExpo) {
1728 rv = CKR_TEMPLATE_INCONSISTENT;
1729 goto fail_cleanup;
1730 }
1731
1732 if (isPrime && isSubprime && isBase && isValue) {
1733 copy_bigint_attr(&value,
1734 KEY_PUB_DH942_VALUE(pbk));
1735 } else {
1736 rv = CKR_TEMPLATE_INCOMPLETE;
1737 goto fail_cleanup;
1738 }
1739 } else {
1740 if (isModulusBits || isModulus || isPubExpo ||
1741 isValue) {
1742 rv = CKR_TEMPLATE_INCONSISTENT;
1743 goto fail_cleanup;
1744 }
1745
1746 if (!(isPrime && isSubprime && isBase)) {
1747 rv = CKR_TEMPLATE_INCOMPLETE;
1748 goto fail_cleanup;
1749 }
1750 }
1751
1752 copy_bigint_attr(&prime, KEY_PUB_DH942_PRIME(pbk));
1753
1754 copy_bigint_attr(&base, KEY_PUB_DH942_BASE(pbk));
1755
1756 copy_bigint_attr(&subprime, KEY_PUB_DH942_SUBPRIME(pbk));
1757
1758 break;
1759
1760 case CKK_EC:
1761 if (mode == SOFT_CREATE_OBJ) {
1762 if (isModulusBits || isModulus || isPubExpo ||
1763 isPrime || isSubprime || isBase || isValue) {
1764 rv = CKR_TEMPLATE_INCONSISTENT;
1765 goto fail_cleanup;
1766
1767 } else if (!isECParam || !isECPoint) {
1768 rv = CKR_TEMPLATE_INCOMPLETE;
1769 goto fail_cleanup;
1770 }
1771 } else {
1772 if (isModulusBits || isModulus || isPubExpo ||
1773 isPrime || isSubprime || isBase || isValue) {
1774 rv = CKR_TEMPLATE_INCONSISTENT;
1775 goto fail_cleanup;
1776
1777 } else if (!isECParam) {
1778 rv = CKR_TEMPLATE_INCOMPLETE;
1779 goto fail_cleanup;
1780 }
1781 }
1782
1783 if (isECPoint) {
1784 copy_bigint_attr(&point, KEY_PUB_EC_POINT(pbk));
1785 }
1786 rv = soft_add_extra_attr(¶m_tmp, new_object);
1787 if (rv != CKR_OK)
1788 goto fail_cleanup;
1789 string_attr_cleanup(¶m_tmp);
1790 break;
1791
1792 default:
1793 rv = CKR_TEMPLATE_INCONSISTENT;
1794 goto fail_cleanup;
1795 }
1796
1797 /* Set up object. */
1798 new_object->object_type = object_type;
1799 new_object->bool_attr_mask = attr_mask;
1800 if (isLabel) {
1801 rv = soft_add_extra_attr(&string_tmp, new_object);
1802 if (rv != CKR_OK)
1803 goto fail_cleanup;
1804 string_attr_cleanup(&string_tmp);
1805 }
1806
1807 return (rv);
1808
1809 fail_cleanup:
1810 /*
1811 * cleanup the storage allocated to the local variables.
1812 */
1813 bigint_attr_cleanup(&modulus);
1814 bigint_attr_cleanup(&pubexpo);
1815 bigint_attr_cleanup(&prime);
1816 bigint_attr_cleanup(&subprime);
1817 bigint_attr_cleanup(&base);
1818 bigint_attr_cleanup(&value);
1819 bigint_attr_cleanup(&point);
1820 string_attr_cleanup(&string_tmp);
1821 string_attr_cleanup(¶m_tmp);
1822
1823 /*
1824 * cleanup the storage allocated inside the object itself.
1825 */
1826 soft_cleanup_object(new_object);
1827
1828 return (rv);
1829 }
1830
1831
1832 /*
1833 * Build a Private Key Object.
1834 *
1835 * - Parse the object's template, and when an error is detected such as
1836 * invalid attribute type, invalid attribute value, etc., return
1837 * with appropriate return value.
1838 * - Set up attribute mask field in the object for the supplied common
1839 * attributes that have boolean type.
1840 * - Build the attribute_info struct to hold the value of each supplied
1841 * attribute that has byte array type. Link attribute_info structs
1842 * together to form the extra attribute list of the object.
1843 * - Allocate storage for the Private Key object.
1844 * - Build the Private Key object according to the key type. Allocate
1845 * storage to hold the big integer value for the supplied attributes
1846 * that are required for a certain key type.
1847 *
1848 */
1849 CK_RV
1850 soft_build_private_key_object(CK_ATTRIBUTE_PTR template, CK_ULONG ulAttrNum,
1851 soft_object_t *new_object, CK_ULONG mode, CK_KEY_TYPE key_type)
1852 {
1853 ulong_t i;
1854 CK_KEY_TYPE keytype = (CK_KEY_TYPE)~0UL;
1855 uint64_t attr_mask = PRIVATE_KEY_DEFAULT;
1856 CK_RV rv = CKR_OK;
1857 int isLabel = 0;
1858 int isECParam = 0;
1859 /* Must set flags unless mode == SOFT_UNWRAP_KEY */
1860 int isModulus = 0;
1861 int isPriExpo = 0;
1862 int isPrime = 0;
1863 int isSubprime = 0;
1864 int isBase = 0;
1865 /* Must set flags if mode == SOFT_GEN_KEY */
1866 int isValue = 0;
1867 /* Must not set flags */
1868 int isValueBits = 0;
1869 CK_ULONG value_bits = 0;
1870
1871 /* Private Key RSA optional */
1872 int isPubExpo = 0;
1873 int isPrime1 = 0;
1874 int isPrime2 = 0;
1875 int isExpo1 = 0;
1876 int isExpo2 = 0;
1877 int isCoef = 0;
1878
1879 biginteger_t modulus;
1880 biginteger_t priexpo;
1881 biginteger_t prime;
1882 biginteger_t subprime;
1883 biginteger_t base;
1884 biginteger_t value;
1885
1886 biginteger_t pubexpo;
1887 biginteger_t prime1;
1888 biginteger_t prime2;
1889 biginteger_t expo1;
1890 biginteger_t expo2;
1891 biginteger_t coef;
1892 CK_ATTRIBUTE string_tmp;
1893 CK_ATTRIBUTE param_tmp;
1894 BIGNUM x, q;
1895
1896 private_key_obj_t *pvk;
1897 uchar_t object_type = 0;
1898
1899 /* prevent bigint_attr_cleanup from freeing invalid attr value */
1900 (void) memset(&modulus, 0x0, sizeof (biginteger_t));
1901 (void) memset(&priexpo, 0x0, sizeof (biginteger_t));
1902 (void) memset(&prime, 0x0, sizeof (biginteger_t));
1903 (void) memset(&subprime, 0x0, sizeof (biginteger_t));
1904 (void) memset(&base, 0x0, sizeof (biginteger_t));
1905 (void) memset(&value, 0x0, sizeof (biginteger_t));
1906 (void) memset(&pubexpo, 0x0, sizeof (biginteger_t));
1907 (void) memset(&prime1, 0x0, sizeof (biginteger_t));
1908 (void) memset(&prime2, 0x0, sizeof (biginteger_t));
1909 (void) memset(&expo1, 0x0, sizeof (biginteger_t));
1910 (void) memset(&expo2, 0x0, sizeof (biginteger_t));
1911 (void) memset(&coef, 0x0, sizeof (biginteger_t));
1912 string_tmp.pValue = NULL;
1913 param_tmp.pValue = NULL;
1914 x.malloced = 0;
1915 q.malloced = 0;
1916
1917 for (i = 0; i < ulAttrNum; i++) {
1918
1919 /* Private Key Object Attributes */
1920 switch (template[i].type) {
1921 /* common key attributes */
1922 case CKA_KEY_TYPE:
1923 keytype = *((CK_KEY_TYPE*)template[i].pValue);
1924 break;
1925
1926 case CKA_ID:
1927 case CKA_START_DATE:
1928 case CKA_END_DATE:
1929
1930 /* common private key attribute */
1931 case CKA_SUBJECT:
1932 /*
1933 * Allocate storage to hold the attribute
1934 * value with byte array type, and add it to
1935 * the extra attribute list of the object.
1936 */
1937 rv = soft_add_extra_attr(&template[i],
1938 new_object);
1939 if (rv != CKR_OK) {
1940 goto fail_cleanup;
1941 }
1942 break;
1943
1944 /*
1945 * The following key related attribute types must
1946 * not be specified by C_CreateObject or C_GenerateKey(Pair).
1947 */
1948 case CKA_LOCAL:
1949 case CKA_KEY_GEN_MECHANISM:
1950 case CKA_AUTH_PIN_FLAGS:
1951 case CKA_ALWAYS_SENSITIVE:
1952 case CKA_NEVER_EXTRACTABLE:
1953 rv = CKR_TEMPLATE_INCONSISTENT;
1954 goto fail_cleanup;
1955
1956 /* Key related boolean attributes */
1957 case CKA_DERIVE:
1958 if (*(CK_BBOOL *)template[i].pValue)
1959 attr_mask |= DERIVE_BOOL_ON;
1960 break;
1961
1962 case CKA_SENSITIVE:
1963 if (*(CK_BBOOL *)template[i].pValue)
1964 attr_mask |= SENSITIVE_BOOL_ON;
1965 break;
1966
1967 case CKA_SECONDARY_AUTH:
1968 if (*(CK_BBOOL *)template[i].pValue) {
1969 rv = CKR_ATTRIBUTE_VALUE_INVALID;
1970 goto fail_cleanup;
1971 }
1972 break;
1973
1974 case CKA_DECRYPT:
1975 if (*(CK_BBOOL *)template[i].pValue)
1976 attr_mask |= DECRYPT_BOOL_ON;
1977 else
1978 attr_mask &= ~DECRYPT_BOOL_ON;
1979 break;
1980
1981 case CKA_SIGN:
1982 if (*(CK_BBOOL *)template[i].pValue)
1983 attr_mask |= SIGN_BOOL_ON;
1984 else
1985 attr_mask &= ~SIGN_BOOL_ON;
1986 break;
1987
1988 case CKA_SIGN_RECOVER:
1989 if (*(CK_BBOOL *)template[i].pValue)
1990 attr_mask |= SIGN_RECOVER_BOOL_ON;
1991 else
1992 attr_mask &= ~SIGN_RECOVER_BOOL_ON;
1993 break;
1994
1995 case CKA_UNWRAP:
1996 if (*(CK_BBOOL *)template[i].pValue)
1997 attr_mask |= UNWRAP_BOOL_ON;
1998 else
1999 attr_mask &= ~UNWRAP_BOOL_ON;
2000 break;
2001
2002 case CKA_EXTRACTABLE:
2003 if (*(CK_BBOOL *)template[i].pValue)
2004 attr_mask |= EXTRACTABLE_BOOL_ON;
2005 else
2006 attr_mask &= ~EXTRACTABLE_BOOL_ON;
2007 break;
2008
2009 case CKA_MODIFIABLE:
2010 if ((*(CK_BBOOL *)template[i].pValue) == B_FALSE)
2011 attr_mask |= NOT_MODIFIABLE_BOOL_ON;
2012 break;
2013
2014 /*
2015 * The following key related attribute types must
2016 * be specified according to the key type by
2017 * C_CreateObject.
2018 */
2019 case CKA_MODULUS:
2020
2021 isModulus = 1;
2022 /*
2023 * Copyin big integer attribute from template
2024 * to a local variable.
2025 */
2026 rv = get_bigint_attr_from_template(&modulus,
2027 &template[i]);
2028 if (rv != CKR_OK)
2029 goto fail_cleanup;
2030
2031 /*
2032 * Modulus length needs to be between min key length and
2033 * max key length.
2034 */
2035 if ((modulus.big_value_len <
2036 MIN_RSA_KEYLENGTH_IN_BYTES) ||
2037 (modulus.big_value_len >
2038 MAX_RSA_KEYLENGTH_IN_BYTES)) {
2039 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2040 goto fail_cleanup;
2041 }
2042 break;
2043
2044 case CKA_PUBLIC_EXPONENT:
2045
2046 isPubExpo = 1;
2047 rv = get_bigint_attr_from_template(&pubexpo,
2048 &template[i]);
2049 if (rv != CKR_OK)
2050 goto fail_cleanup;
2051 break;
2052
2053 case CKA_PRIVATE_EXPONENT:
2054
2055 isPriExpo = 1;
2056 rv = get_bigint_attr_from_template(&priexpo,
2057 &template[i]);
2058 if (rv != CKR_OK)
2059 goto fail_cleanup;
2060 break;
2061
2062 case CKA_PRIME_1:
2063 isPrime1 = 1;
2064 rv = get_bigint_attr_from_template(&prime1,
2065 &template[i]);
2066 if (rv != CKR_OK)
2067 goto fail_cleanup;
2068 break;
2069
2070 case CKA_PRIME_2:
2071 isPrime2 = 1;
2072 rv = get_bigint_attr_from_template(&prime2,
2073 &template[i]);
2074 if (rv != CKR_OK)
2075 goto fail_cleanup;
2076 break;
2077
2078 case CKA_EXPONENT_1:
2079 isExpo1 = 1;
2080 rv = get_bigint_attr_from_template(&expo1,
2081 &template[i]);
2082 if (rv != CKR_OK)
2083 goto fail_cleanup;
2084 break;
2085
2086 case CKA_EXPONENT_2:
2087 isExpo2 = 1;
2088 rv = get_bigint_attr_from_template(&expo2,
2089 &template[i]);
2090 if (rv != CKR_OK)
2091 goto fail_cleanup;
2092 break;
2093
2094 case CKA_COEFFICIENT:
2095 isCoef = 1;
2096 rv = get_bigint_attr_from_template(&coef,
2097 &template[i]);
2098 if (rv != CKR_OK)
2099 goto fail_cleanup;
2100 break;
2101
2102 case CKA_PRIME:
2103 isPrime = 1;
2104 rv = get_bigint_attr_from_template(&prime,
2105 &template[i]);
2106 if (rv != CKR_OK)
2107 goto fail_cleanup;
2108 break;
2109
2110 case CKA_SUBPRIME:
2111 isSubprime = 1;
2112 rv = get_bigint_attr_from_template(&subprime,
2113 &template[i]);
2114 if (rv != CKR_OK)
2115 goto fail_cleanup;
2116 break;
2117
2118 case CKA_BASE:
2119 isBase = 1;
2120 rv = get_bigint_attr_from_template(&base,
2121 &template[i]);
2122 if (rv != CKR_OK)
2123 goto fail_cleanup;
2124 break;
2125
2126 case CKA_VALUE:
2127 isValue = 1;
2128 if (mode == SOFT_CREATE_OBJ) {
2129 if ((template[i].ulValueLen == 0) ||
2130 (template[i].pValue == NULL)) {
2131 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2132 goto fail_cleanup;
2133 }
2134 }
2135
2136 rv = get_bigint_attr_from_template(&value,
2137 &template[i]);
2138 if (rv != CKR_OK)
2139 goto fail_cleanup;
2140 break;
2141
2142 case CKA_VALUE_BITS:
2143 isValueBits = 1;
2144 rv = get_ulong_attr_from_template(&value_bits,
2145 &template[i]);
2146 if (rv != CKR_OK)
2147 goto fail_cleanup;
2148 break;
2149
2150 case CKA_LABEL:
2151 isLabel = 1;
2152 rv = get_string_from_template(&string_tmp,
2153 &template[i]);
2154 if (rv != CKR_OK)
2155 goto fail_cleanup;
2156 break;
2157
2158 case CKA_EC_PARAMS:
2159 isECParam = 1;
2160 rv = get_string_from_template(¶m_tmp,
2161 &template[i]);
2162 if (rv != CKR_OK)
2163 goto fail_cleanup;
2164 break;
2165
2166 default:
2167 rv = soft_parse_common_attrs(&template[i],
2168 &object_type);
2169 if (rv != CKR_OK)
2170 goto fail_cleanup;
2171 break;
2172
2173 }
2174 } /* For */
2175
2176 /* Allocate storage for Private Key Object. */
2177 pvk = calloc(1, sizeof (private_key_obj_t));
2178 if (pvk == NULL) {
2179 rv = CKR_HOST_MEMORY;
2180 goto fail_cleanup;
2181 }
2182
2183 new_object->object_class_u.private_key = pvk;
2184 new_object->class = CKO_PRIVATE_KEY;
2185
2186 if ((mode == SOFT_CREATE_OBJ) && (keytype == (CK_KEY_TYPE)~0UL)) {
2187 rv = CKR_TEMPLATE_INCOMPLETE;
2188 goto fail_cleanup;
2189 }
2190
2191 if (mode == SOFT_GEN_KEY) {
2192 /*
2193 * The key type is not specified in the application's
2194 * template, so we use the implied key type based on
2195 * the mechanism.
2196 */
2197 if (keytype == (CK_KEY_TYPE)~0UL) {
2198 keytype = key_type;
2199 }
2200
2201 /* If still unspecified, template is incomplete */
2202 if (keytype == (CK_KEY_TYPE)~0UL) {
2203 rv = CKR_TEMPLATE_INCOMPLETE;
2204 goto fail_cleanup;
2205 }
2206
2207 /*
2208 * The key type specified in the template does not
2209 * match the implied key type based on the mechanism.
2210 */
2211 if (keytype != key_type) {
2212 rv = CKR_TEMPLATE_INCONSISTENT;
2213 goto fail_cleanup;
2214 }
2215 }
2216
2217 if (mode == SOFT_UNWRAP_KEY) {
2218 /*
2219 * Note that, for mode SOFT_UNWRAP_KEY, key type is not
2220 * implied by the mechanism (key_type), so if it is not
2221 * specified from the attribute template (keytype), it is
2222 * incomplete.
2223 */
2224 if (keytype == (CK_KEY_TYPE)~0UL) {
2225 rv = CKR_TEMPLATE_INCOMPLETE;
2226 goto fail_cleanup;
2227 }
2228 }
2229
2230 new_object->key_type = keytype;
2231
2232 /* Supported key types of the Private Key Object */
2233 switch (keytype) {
2234 case CKK_RSA:
2235 if (isPrime || isSubprime || isBase || isValue ||
2236 isValueBits) {
2237 rv = CKR_TEMPLATE_INCONSISTENT;
2238 goto fail_cleanup;
2239 }
2240
2241 if (mode == SOFT_GEN_KEY || mode == SOFT_UNWRAP_KEY) {
2242 if (isModulus || isPubExpo || isPriExpo || isPrime1 ||
2243 isPrime2 || isExpo1 || isExpo2 || isCoef) {
2244 rv = CKR_TEMPLATE_INCONSISTENT;
2245 goto fail_cleanup;
2246 } else
2247 break;
2248 }
2249
2250 if (isModulus && isPriExpo) {
2251 /*
2252 * Copy big integer attribute value to the
2253 * designated place in the Private Key object.
2254 */
2255 copy_bigint_attr(&modulus, KEY_PRI_RSA_MOD(pvk));
2256
2257 copy_bigint_attr(&priexpo, KEY_PRI_RSA_PRIEXPO(pvk));
2258 } else {
2259 rv = CKR_TEMPLATE_INCOMPLETE;
2260 goto fail_cleanup;
2261 }
2262
2263 /* The following attributes are optional. */
2264 if (isPubExpo) {
2265 copy_bigint_attr(&pubexpo, KEY_PRI_RSA_PUBEXPO(pvk));
2266 }
2267
2268 if (isPrime1) {
2269 copy_bigint_attr(&prime1, KEY_PRI_RSA_PRIME1(pvk));
2270 }
2271
2272 if (isPrime2) {
2273 copy_bigint_attr(&prime2, KEY_PRI_RSA_PRIME2(pvk));
2274 }
2275
2276 if (isExpo1) {
2277 copy_bigint_attr(&expo1, KEY_PRI_RSA_EXPO1(pvk));
2278 }
2279
2280 if (isExpo2) {
2281 copy_bigint_attr(&expo2, KEY_PRI_RSA_EXPO2(pvk));
2282 }
2283
2284 if (isCoef) {
2285 copy_bigint_attr(&coef, KEY_PRI_RSA_COEF(pvk));
2286 }
2287 break;
2288
2289 case CKK_DSA:
2290 if (isModulus || isPubExpo || isPriExpo || isPrime1 ||
2291 isPrime2 || isExpo1 || isExpo2 || isCoef ||
2292 isValueBits) {
2293 rv = CKR_TEMPLATE_INCONSISTENT;
2294 goto fail_cleanup;
2295 }
2296
2297 if (mode == SOFT_GEN_KEY || mode == SOFT_UNWRAP_KEY) {
2298 if (isPrime || isSubprime || isBase || isValue) {
2299 rv = CKR_TEMPLATE_INCONSISTENT;
2300 goto fail_cleanup;
2301 } else
2302 break;
2303 }
2304
2305 if (isPrime && isSubprime && isBase && isValue) {
2306 /*
2307 * The private value x must be less than subprime q.
2308 * Size for big_init is in BIG_CHUNK_TYPE words.
2309 */
2310 #ifdef __sparcv9
2311 if (big_init(&x,
2312 (int)CHARLEN2BIGNUMLEN(value.big_value_len))
2313 != BIG_OK) {
2314 #else /* !__sparcv9 */
2315 if (big_init(&x,
2316 CHARLEN2BIGNUMLEN(value.big_value_len))
2317 != BIG_OK) {
2318 #endif /* __sparcv9 */
2319 rv = CKR_HOST_MEMORY;
2320 goto fail_cleanup;
2321 }
2322 #ifdef __sparcv9
2323 if (big_init(&q,
2324 (int)CHARLEN2BIGNUMLEN(subprime.big_value_len))
2325 != BIG_OK) {
2326 #else /* !__sparcv9 */
2327 if (big_init(&q,
2328 CHARLEN2BIGNUMLEN(subprime.big_value_len))
2329 != BIG_OK) {
2330 #endif /* __sparcv9 */
2331 rv = CKR_HOST_MEMORY;
2332 goto fail_cleanup;
2333 }
2334 bytestring2bignum(&x, value.big_value,
2335 value.big_value_len);
2336 bytestring2bignum(&q, subprime.big_value,
2337 subprime.big_value_len);
2338
2339 if (big_cmp_abs(&x, &q) > 0) {
2340 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2341 goto fail_cleanup;
2342 }
2343
2344 copy_bigint_attr(&prime, KEY_PRI_DSA_PRIME(pvk));
2345
2346 copy_bigint_attr(&subprime, KEY_PRI_DSA_SUBPRIME(pvk));
2347
2348 copy_bigint_attr(&base, KEY_PRI_DSA_BASE(pvk));
2349
2350 copy_bigint_attr(&value, KEY_PRI_DSA_VALUE(pvk));
2351 } else {
2352 rv = CKR_TEMPLATE_INCOMPLETE;
2353 goto fail_cleanup;
2354 }
2355 break;
2356
2357 case CKK_DH:
2358 if (isModulus || isPubExpo || isPriExpo || isPrime1 ||
2359 isPrime2 || isExpo1 || isExpo2 || isCoef ||
2360 isSubprime) {
2361 rv = CKR_TEMPLATE_INCONSISTENT;
2362 goto fail_cleanup;
2363 }
2364
2365 /* CKA_VALUE_BITS is for key gen but not unwrap */
2366 if (mode == SOFT_GEN_KEY)
2367 KEY_PRI_DH_VAL_BITS(pvk) = (isValueBits) ?
2368 value_bits : 0;
2369 else if (mode == SOFT_UNWRAP_KEY) {
2370 if (isValueBits) {
2371 rv = CKR_TEMPLATE_INCONSISTENT;
2372 goto fail_cleanup;
2373 }
2374 }
2375
2376 if (mode == SOFT_GEN_KEY || mode == SOFT_UNWRAP_KEY) {
2377 if (isPrime || isBase || isValue) {
2378 rv = CKR_TEMPLATE_INCONSISTENT;
2379 goto fail_cleanup;
2380 } else
2381 break;
2382 }
2383
2384 if (isValueBits) {
2385 rv = CKR_TEMPLATE_INCONSISTENT;
2386 goto fail_cleanup;
2387 }
2388
2389 if (isPrime && isBase && isValue) {
2390 copy_bigint_attr(&prime, KEY_PRI_DH_PRIME(pvk));
2391
2392 copy_bigint_attr(&base, KEY_PRI_DH_BASE(pvk));
2393
2394 copy_bigint_attr(&value, KEY_PRI_DH_VALUE(pvk));
2395 } else {
2396 rv = CKR_TEMPLATE_INCOMPLETE;
2397 goto fail_cleanup;
2398 }
2399 break;
2400
2401 case CKK_X9_42_DH:
2402 if (isModulus || isPubExpo || isPriExpo || isPrime1 ||
2403 isPrime2 || isExpo1 || isExpo2 || isCoef ||
2404 isValueBits) {
2405 rv = CKR_TEMPLATE_INCONSISTENT;
2406 goto fail_cleanup;
2407 }
2408
2409 if (mode == SOFT_GEN_KEY || mode == SOFT_UNWRAP_KEY) {
2410 if (isPrime || isSubprime || isBase || isValue) {
2411 rv = CKR_TEMPLATE_INCONSISTENT;
2412 goto fail_cleanup;
2413 } else
2414 break;
2415 }
2416
2417 if (isPrime && isSubprime && isBase && isValue) {
2418 copy_bigint_attr(&prime, KEY_PRI_DH942_PRIME(pvk));
2419
2420 copy_bigint_attr(&base, KEY_PRI_DH942_BASE(pvk));
2421
2422 copy_bigint_attr(&subprime,
2423 KEY_PRI_DH942_SUBPRIME(pvk));
2424
2425 copy_bigint_attr(&value, KEY_PRI_DH942_VALUE(pvk));
2426 } else {
2427 rv = CKR_TEMPLATE_INCOMPLETE;
2428 goto fail_cleanup;
2429 }
2430 break;
2431
2432 case CKK_EC:
2433 if (isModulus || isPubExpo || isPrime ||
2434 isPrime1 || isPrime2 || isExpo1 || isExpo2 || isCoef ||
2435 isValueBits || isBase) {
2436 rv = CKR_TEMPLATE_INCONSISTENT;
2437 goto fail_cleanup;
2438
2439 } else if (isECParam) {
2440 rv = soft_add_extra_attr(¶m_tmp, new_object);
2441 if (rv != CKR_OK)
2442 goto fail_cleanup;
2443 string_attr_cleanup(¶m_tmp);
2444 }
2445 if (isValue) {
2446 copy_bigint_attr(&value, KEY_PRI_EC_VALUE(pvk));
2447 }
2448 break;
2449
2450 default:
2451 rv = CKR_TEMPLATE_INCONSISTENT;
2452 goto fail_cleanup;
2453 }
2454
2455 /* Set up object. */
2456 new_object->object_type = object_type;
2457 new_object->bool_attr_mask = attr_mask;
2458 if (isLabel) {
2459 rv = soft_add_extra_attr(&string_tmp, new_object);
2460 if (rv != CKR_OK)
2461 goto fail_cleanup;
2462 string_attr_cleanup(&string_tmp);
2463 }
2464 big_finish(&x);
2465 big_finish(&q);
2466
2467 return (rv);
2468
2469 fail_cleanup:
2470 /*
2471 * cleanup the storage allocated to the local variables.
2472 */
2473 bigint_attr_cleanup(&modulus);
2474 bigint_attr_cleanup(&priexpo);
2475 bigint_attr_cleanup(&prime);
2476 bigint_attr_cleanup(&subprime);
2477 bigint_attr_cleanup(&base);
2478 bigint_attr_cleanup(&value);
2479 bigint_attr_cleanup(&pubexpo);
2480 bigint_attr_cleanup(&prime1);
2481 bigint_attr_cleanup(&prime2);
2482 bigint_attr_cleanup(&expo1);
2483 bigint_attr_cleanup(&expo2);
2484 bigint_attr_cleanup(&coef);
2485 string_attr_cleanup(&string_tmp);
2486 string_attr_cleanup(¶m_tmp);
2487 big_finish(&x);
2488 big_finish(&q);
2489
2490 /*
2491 * cleanup the storage allocated inside the object itself.
2492 */
2493 soft_cleanup_object(new_object);
2494
2495 return (rv);
2496 }
2497
2498
2499 /*
2500 * Build a Secret Key Object.
2501 *
2502 * - Parse the object's template, and when an error is detected such as
2503 * invalid attribute type, invalid attribute value, etc., return
2504 * with appropriate return value.
2505 * - Set up attribute mask field in the object for the supplied common
2506 * attributes that have boolean type.
2507 * - Build the attribute_info struct to hold the value of each supplied
2508 * attribute that has byte array type. Link attribute_info structs
2509 * together to form the extra attribute list of the object.
2510 * - Allocate storage for the Secret Key object.
2511 * - Build the Secret Key object. Allocate storage to hold the big integer
2512 * value for the attribute CKA_VALUE that is required for all the key
2513 * types supported by secret key object.
2514 * This function is called internally with mode = SOFT_CREATE_OBJ_INT.
2515 *
2516 */
2517 CK_RV
2518 soft_build_secret_key_object(CK_ATTRIBUTE_PTR template, CK_ULONG ulAttrNum,
2519 soft_object_t *new_object, CK_ULONG mode, CK_ULONG key_len,
2520 CK_KEY_TYPE key_type)
2521 {
2522
2523 ulong_t i;
2524 CK_KEY_TYPE keytype = (CK_KEY_TYPE)~0UL;
2525 uint64_t attr_mask = SECRET_KEY_DEFAULT;
2526 CK_RV rv = CKR_OK;
2527 int isLabel = 0;
2528 /* Must set flags if mode != SOFT_UNWRAP_KEY, else must not set */
2529 int isValue = 0;
2530 /* Must not set flags if mode != SOFT_UNWRAP_KEY, else optional */
2531 int isValueLen = 0;
2532
2533 CK_ATTRIBUTE string_tmp;
2534
2535 secret_key_obj_t *sck;
2536 uchar_t object_type = 0;
2537
2538 string_tmp.pValue = NULL;
2539
2540 /* Allocate storage for Secret Key Object. */
2541 sck = calloc(1, sizeof (secret_key_obj_t));
2542 if (sck == NULL) {
2543 rv = CKR_HOST_MEMORY;
2544 goto fail_cleanup;
2545 }
2546
2547 new_object->object_class_u.secret_key = sck;
2548 new_object->class = CKO_SECRET_KEY;
2549
2550 for (i = 0; i < ulAttrNum; i++) {
2551
2552 /* Secret Key Object Attributes */
2553 switch (template[i].type) {
2554
2555 /* common key attributes */
2556 case CKA_KEY_TYPE:
2557 keytype = *((CK_KEY_TYPE*)template[i].pValue);
2558 break;
2559
2560 case CKA_ID:
2561 case CKA_START_DATE:
2562 case CKA_END_DATE:
2563 /*
2564 * Allocate storage to hold the attribute
2565 * value with byte array type, and add it to
2566 * the extra attribute list of the object.
2567 */
2568 rv = soft_add_extra_attr(&template[i],
2569 new_object);
2570 if (rv != CKR_OK) {
2571 goto fail_cleanup;
2572 }
2573 break;
2574
2575 /*
2576 * The following key related attribute types must
2577 * not be specified by C_CreateObject and C_GenerateKey.
2578 */
2579 case CKA_LOCAL:
2580 case CKA_KEY_GEN_MECHANISM:
2581 case CKA_ALWAYS_SENSITIVE:
2582 case CKA_NEVER_EXTRACTABLE:
2583 rv = CKR_TEMPLATE_INCONSISTENT;
2584 goto fail_cleanup;
2585
2586 /* Key related boolean attributes */
2587 case CKA_DERIVE:
2588 if (*(CK_BBOOL *)template[i].pValue)
2589 attr_mask |= DERIVE_BOOL_ON;
2590 break;
2591
2592 case CKA_SENSITIVE:
2593 if (*(CK_BBOOL *)template[i].pValue)
2594 attr_mask |= SENSITIVE_BOOL_ON;
2595 break;
2596
2597 case CKA_ENCRYPT:
2598 if (*(CK_BBOOL *)template[i].pValue)
2599 attr_mask |= ENCRYPT_BOOL_ON;
2600 else
2601 attr_mask &= ~ENCRYPT_BOOL_ON;
2602 break;
2603
2604 case CKA_DECRYPT:
2605 if (*(CK_BBOOL *)template[i].pValue)
2606 attr_mask |= DECRYPT_BOOL_ON;
2607 else
2608 attr_mask &= ~DECRYPT_BOOL_ON;
2609 break;
2610
2611 case CKA_SIGN:
2612 if (*(CK_BBOOL *)template[i].pValue)
2613 attr_mask |= SIGN_BOOL_ON;
2614 else
2615 attr_mask &= ~SIGN_BOOL_ON;
2616 break;
2617
2618 case CKA_VERIFY:
2619 if (*(CK_BBOOL *)template[i].pValue)
2620 attr_mask |= VERIFY_BOOL_ON;
2621 else
2622 attr_mask &= ~VERIFY_BOOL_ON;
2623 break;
2624
2625 case CKA_WRAP:
2626 if (*(CK_BBOOL *)template[i].pValue)
2627 attr_mask |= WRAP_BOOL_ON;
2628 else
2629 attr_mask &= ~WRAP_BOOL_ON;
2630 break;
2631
2632 case CKA_UNWRAP:
2633 if (*(CK_BBOOL *)template[i].pValue)
2634 attr_mask |= UNWRAP_BOOL_ON;
2635 else
2636 attr_mask &= ~UNWRAP_BOOL_ON;
2637 break;
2638
2639 case CKA_EXTRACTABLE:
2640 if (*(CK_BBOOL *)template[i].pValue)
2641 attr_mask |= EXTRACTABLE_BOOL_ON;
2642 else
2643 attr_mask &= ~EXTRACTABLE_BOOL_ON;
2644 break;
2645
2646 case CKA_MODIFIABLE:
2647 if ((*(CK_BBOOL *)template[i].pValue) == B_FALSE)
2648 attr_mask |= NOT_MODIFIABLE_BOOL_ON;
2649 break;
2650
2651 case CKA_VALUE:
2652 isValue = 1;
2653 if (mode == SOFT_CREATE_OBJ) {
2654 if ((template[i].ulValueLen == 0) ||
2655 (template[i].pValue == NULL)) {
2656 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2657 goto fail_cleanup;
2658 }
2659 }
2660
2661 /*
2662 * Copyin attribute from template
2663 * to a local variable.
2664 */
2665 rv = get_bigint_attr_from_template((biginteger_t *)sck,
2666 &template[i]);
2667 if (rv != CKR_OK)
2668 goto fail_cleanup;
2669 break;
2670
2671 case CKA_VALUE_LEN:
2672 isValueLen = 1;
2673 rv = get_ulong_attr_from_template(&sck->sk_value_len,
2674 &template[i]);
2675 if (rv != CKR_OK)
2676 goto fail_cleanup;
2677 break;
2678
2679 case CKA_LABEL:
2680 isLabel = 1;
2681 rv = get_string_from_template(&string_tmp,
2682 &template[i]);
2683 if (rv != CKR_OK)
2684 goto fail_cleanup;
2685 break;
2686
2687 default:
2688 rv = soft_parse_common_attrs(&template[i],
2689 &object_type);
2690 if (rv != CKR_OK)
2691 goto fail_cleanup;
2692 break;
2693
2694 }
2695 } /* For */
2696
2697 switch (mode) {
2698 case SOFT_CREATE_OBJ:
2699 case SOFT_CREATE_OBJ_INT:
2700 case SOFT_DERIVE_KEY_DH:
2701 /*
2702 * The key type must be specified in the application's
2703 * template. Otherwise, returns error.
2704 */
2705 if (keytype == (CK_KEY_TYPE)~0UL) {
2706 rv = CKR_TEMPLATE_INCOMPLETE;
2707 goto fail_cleanup;
2708 }
2709 break;
2710
2711 case SOFT_GEN_KEY:
2712 if (keytype == (CK_KEY_TYPE)~0UL) {
2713 /*
2714 * The key type is not specified in the application's
2715 * template, so we use the implied key type based on
2716 * the mechanism.
2717 */
2718 keytype = key_type;
2719 } else {
2720 if (keytype != key_type) {
2721 /*
2722 * The key type specified in the template
2723 * does not match the implied key type based
2724 * on the mechanism.
2725 */
2726 rv = CKR_TEMPLATE_INCONSISTENT;
2727 goto fail_cleanup;
2728 }
2729 }
2730
2731 /*
2732 * If a key_len is passed as a parameter, it has to
2733 * match the one found in the template.
2734 */
2735 if (key_len > 0) {
2736 if (isValueLen && sck->sk_value_len != key_len) {
2737 rv = CKR_TEMPLATE_INCONSISTENT;
2738 goto fail_cleanup;
2739 }
2740 isValueLen = 1;
2741 sck->sk_value_len = key_len;
2742 }
2743 break;
2744
2745 case SOFT_UNWRAP_KEY:
2746 /*
2747 * Note that, for mode SOFT_UNWRAP_KEY, key type is not
2748 * implied by the mechanism (key_type), so if it is not
2749 * specified from the attribute template (keytype), it is
2750 * incomplete.
2751 */
2752 if (keytype == (CK_KEY_TYPE)~0UL) {
2753 rv = CKR_TEMPLATE_INCOMPLETE;
2754 goto fail_cleanup;
2755 }
2756 break;
2757
2758 case SOFT_DERIVE_KEY_OTHER:
2759 /*
2760 * For CKM_MD5_KEY_DERIVATION & CKM_SHA1_KEY_DERIVATION, the
2761 * key type is optional.
2762 */
2763 if (keytype == (CK_KEY_TYPE)~0UL) {
2764 keytype = key_type;
2765 }
2766 break;
2767 }
2768
2769 switch (mode) {
2770 case SOFT_CREATE_OBJ:
2771 case SOFT_CREATE_OBJ_INT:
2772 switch (keytype) {
2773 case CKK_RC4:
2774 if (!isValue) {
2775 rv = CKR_TEMPLATE_INCOMPLETE;
2776 goto fail_cleanup;
2777 }
2778 if ((sck->sk_value_len < ARCFOUR_MIN_KEY_BYTES) ||
2779 (sck->sk_value_len > ARCFOUR_MAX_KEY_BYTES)) {
2780 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2781 goto fail_cleanup;
2782 }
2783 break;
2784
2785 case CKK_GENERIC_SECRET:
2786 if (!isValue) {
2787 rv = CKR_TEMPLATE_INCOMPLETE;
2788 goto fail_cleanup;
2789 }
2790 break;
2791
2792 case CKK_AES:
2793 if (!isValue) {
2794 rv = CKR_TEMPLATE_INCOMPLETE;
2795 goto fail_cleanup;
2796 }
2797 if ((sck->sk_value_len != AES_MIN_KEY_BYTES) &&
2798 (sck->sk_value_len != AES_192_KEY_BYTES) &&
2799 (sck->sk_value_len != AES_MAX_KEY_BYTES)) {
2800 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2801 goto fail_cleanup;
2802 }
2803 break;
2804
2805 case CKK_BLOWFISH:
2806 if (!isValue) {
2807 rv = CKR_TEMPLATE_INCOMPLETE;
2808 goto fail_cleanup;
2809 }
2810 if ((sck->sk_value_len < BLOWFISH_MINBYTES) ||
2811 (sck->sk_value_len > BLOWFISH_MAXBYTES)) {
2812 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2813 goto fail_cleanup;
2814 }
2815
2816 break;
2817
2818 case CKK_DES:
2819 if (!isValue) {
2820 rv = CKR_TEMPLATE_INCOMPLETE;
2821 goto fail_cleanup;
2822 }
2823 if (sck->sk_value_len != DES_KEYSIZE) {
2824 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2825 goto fail_cleanup;
2826 }
2827 break;
2828
2829 case CKK_DES2:
2830 if (!isValue) {
2831 rv = CKR_TEMPLATE_INCOMPLETE;
2832 goto fail_cleanup;
2833 }
2834 if (sck->sk_value_len != DES2_KEYSIZE) {
2835 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2836 goto fail_cleanup;
2837 }
2838 break;
2839
2840 case CKK_DES3:
2841 if (!isValue) {
2842 rv = CKR_TEMPLATE_INCOMPLETE;
2843 goto fail_cleanup;
2844 }
2845 if (sck->sk_value_len != DES3_KEYSIZE) {
2846 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2847 goto fail_cleanup;
2848 }
2849 break;
2850
2851 default:
2852 rv = CKR_TEMPLATE_INCONSISTENT;
2853 goto fail_cleanup;
2854 }
2855
2856 if (isValueLen) {
2857 /*
2858 * Templates for internal object creation come from
2859 * applications calls to C_DeriveKey(), for which it
2860 * is OKey to pass a CKA_VALUE_LEN attribute, as
2861 * long as it does not conflict with the length of the
2862 * CKA_VALUE attribute.
2863 */
2864 if ((mode != SOFT_CREATE_OBJ_INT) ||
2865 ((key_len > 0) && sck->sk_value_len != key_len)) {
2866 rv = CKR_TEMPLATE_INCONSISTENT;
2867 goto fail_cleanup;
2868 }
2869 }
2870 break;
2871
2872 case SOFT_GEN_KEY:
2873 /* CKA_VALUE must not be specified */
2874 if (isValue) {
2875 rv = CKR_TEMPLATE_INCONSISTENT;
2876 goto fail_cleanup;
2877 }
2878
2879 switch (keytype) {
2880 /*
2881 * CKA_VALUE_LEN must be specified by C_GenerateKey
2882 * if mech is CKK_RC4, CKK_AES, CKK_GENERIC_SECRET.
2883 */
2884 case CKK_RC4:
2885 if (!isValueLen) {
2886 rv = CKR_TEMPLATE_INCOMPLETE;
2887 goto fail_cleanup;
2888 }
2889 ;
2890 if ((sck->sk_value_len < ARCFOUR_MIN_KEY_BYTES) ||
2891 (sck->sk_value_len > ARCFOUR_MAX_KEY_BYTES)) {
2892 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2893 goto fail_cleanup;
2894 }
2895 break;
2896
2897 case CKK_GENERIC_SECRET:
2898 /* arbitrary key length - no length checking */
2899 if (!isValueLen) {
2900 rv = CKR_TEMPLATE_INCOMPLETE;
2901 goto fail_cleanup;
2902 }
2903 break;
2904
2905 case CKK_AES:
2906 if (!isValueLen) {
2907 rv = CKR_TEMPLATE_INCOMPLETE;
2908 goto fail_cleanup;
2909 }
2910
2911 if ((sck->sk_value_len != AES_MIN_KEY_BYTES) &&
2912 (sck->sk_value_len != AES_192_KEY_BYTES) &&
2913 (sck->sk_value_len != AES_MAX_KEY_BYTES)) {
2914 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2915 goto fail_cleanup;
2916 }
2917
2918 break;
2919
2920 case CKK_BLOWFISH:
2921 if (!isValueLen) {
2922 rv = CKR_TEMPLATE_INCOMPLETE;
2923 goto fail_cleanup;
2924 }
2925 if ((sck->sk_value_len < BLOWFISH_MINBYTES) ||
2926 (sck->sk_value_len > BLOWFISH_MAXBYTES)) {
2927 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2928 goto fail_cleanup;
2929 }
2930
2931 break;
2932
2933 case CKK_DES:
2934 case CKK_DES2:
2935 case CKK_DES3:
2936 /* CKA_VALUE_LEN attribute does not apply to DES<n> */
2937 if (isValueLen) {
2938 rv = CKR_TEMPLATE_INCONSISTENT;
2939 goto fail_cleanup;
2940 }
2941 break;
2942
2943 default:
2944 rv = CKR_TEMPLATE_INCONSISTENT;
2945 goto fail_cleanup;
2946 }
2947 break;
2948
2949 case SOFT_UNWRAP_KEY:
2950 /*
2951 * According to v2.11 of PKCS#11 spec, neither CKA_VALUE nor
2952 * CKA_VALUE_LEN can be be specified; however v2.20 has this
2953 * restriction removed, perhaps because it makes it hard to
2954 * determine variable-length key sizes. This case statement
2955 * complied with v2.20.
2956 */
2957 if (isValue) {
2958 rv = CKR_TEMPLATE_INCONSISTENT;
2959 goto fail_cleanup;
2960 }
2961
2962 switch (keytype) {
2963 /*
2964 * CKA_VALUE_LEN is optional
2965 * if key is CKK_RC4, CKK_AES, CKK_GENERIC_SECRET
2966 * and the unwrapping mech is *_CBC_PAD.
2967 *
2968 * CKA_VALUE_LEN is required
2969 * if key is CKK_RC4, CKK_AES, CKK_GENERIC_SECRET
2970 * and the unwrapping mech is *_ECB or *_CBC.
2971 *
2972 * since mech is not known at this point, CKA_VALUE_LEN is
2973 * treated as optional and the caller needs to enforce it.
2974 */
2975 case CKK_RC4:
2976 if (isValueLen) {
2977 if ((sck->sk_value_len <
2978 ARCFOUR_MIN_KEY_BYTES) ||
2979 (sck->sk_value_len >
2980 ARCFOUR_MAX_KEY_BYTES)) {
2981 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2982 goto fail_cleanup;
2983 }
2984 }
2985 break;
2986
2987 case CKK_GENERIC_SECRET:
2988 /* arbitrary key length - no length checking */
2989 break;
2990
2991 case CKK_AES:
2992 if (isValueLen) {
2993 if ((sck->sk_value_len != AES_MIN_KEY_BYTES) &&
2994 (sck->sk_value_len != AES_192_KEY_BYTES) &&
2995 (sck->sk_value_len != AES_MAX_KEY_BYTES)) {
2996 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2997 goto fail_cleanup;
2998 }
2999 }
3000 break;
3001
3002 case CKK_BLOWFISH:
3003 if (isValueLen &&
3004 ((sck->sk_value_len < BLOWFISH_MINBYTES) ||
3005 (sck->sk_value_len > BLOWFISH_MAXBYTES))) {
3006 rv = CKR_ATTRIBUTE_VALUE_INVALID;
3007 goto fail_cleanup;
3008 }
3009 break;
3010
3011 case CKK_DES:
3012 case CKK_DES2:
3013 case CKK_DES3:
3014 /* CKA_VALUE_LEN attribute does not apply to DES<n> */
3015 if (isValueLen) {
3016 rv = CKR_TEMPLATE_INCONSISTENT;
3017 goto fail_cleanup;
3018 }
3019 break;
3020
3021 default:
3022 rv = CKR_TEMPLATE_INCONSISTENT;
3023 goto fail_cleanup;
3024 }
3025 break;
3026
3027 case SOFT_DERIVE_KEY_DH:
3028 /* CKA_VALUE must not be specified */
3029 if (isValue) {
3030 rv = CKR_TEMPLATE_INCONSISTENT;
3031 goto fail_cleanup;
3032 }
3033
3034 switch (keytype) {
3035 /*
3036 * CKA_VALUE_LEN is optional
3037 * if mech is CKK_RC4, CKK_AES, CKK_GENERIC_SECRET.
3038 */
3039 case CKK_RC4:
3040 if (isValueLen) {
3041 if ((sck->sk_value_len <
3042 ARCFOUR_MIN_KEY_BYTES) ||
3043 (sck->sk_value_len >
3044 ARCFOUR_MAX_KEY_BYTES)) {
3045 rv = CKR_ATTRIBUTE_VALUE_INVALID;
3046 goto fail_cleanup;
3047 }
3048 }
3049 break;
3050
3051 case CKK_GENERIC_SECRET:
3052 /* arbitrary key length - no length checking */
3053 break;
3054
3055 case CKK_AES:
3056 if (isValueLen) {
3057 if ((sck->sk_value_len != AES_MIN_KEY_BYTES) &&
3058 (sck->sk_value_len != AES_192_KEY_BYTES) &&
3059 (sck->sk_value_len != AES_MAX_KEY_BYTES)) {
3060 rv = CKR_ATTRIBUTE_VALUE_INVALID;
3061 goto fail_cleanup;
3062 }
3063 }
3064
3065 break;
3066
3067 case CKK_BLOWFISH:
3068 if (isValueLen &&
3069 ((sck->sk_value_len < BLOWFISH_MINBYTES) ||
3070 (sck->sk_value_len > BLOWFISH_MAXBYTES))) {
3071 rv = CKR_ATTRIBUTE_VALUE_INVALID;
3072 goto fail_cleanup;
3073 }
3074 break;
3075
3076 case CKK_DES:
3077 case CKK_DES2:
3078 case CKK_DES3:
3079 /* CKA_VALUE_LEN attribute does not apply to DES<n> */
3080 if (isValueLen) {
3081 rv = CKR_TEMPLATE_INCONSISTENT;
3082 goto fail_cleanup;
3083 }
3084 break;
3085
3086 default:
3087 rv = CKR_TEMPLATE_INCONSISTENT;
3088 goto fail_cleanup;
3089 }
3090 break;
3091
3092 case SOFT_DERIVE_KEY_OTHER:
3093 /* CKA_VALUE must not be specified */
3094 if (isValue) {
3095 rv = CKR_TEMPLATE_INCONSISTENT;
3096 goto fail_cleanup;
3097 }
3098
3099 switch (keytype) {
3100 /*
3101 * CKA_VALUE_LEN is an optional attribute for
3102 * CKM_SHA1_KEY_DERIVATION and CKM_MD5_KEY_DERIVATION
3103 * if mech is CKK_RC4, CKK_AES, CKK_GENERIC_SECRET.
3104 */
3105 case CKK_RC4:
3106 case CKK_GENERIC_SECRET:
3107 case CKK_AES:
3108 case CKK_BLOWFISH:
3109 /*
3110 * No need to check key length value here, it will be
3111 * validated later in soft_key_derive_check_length().
3112 */
3113 break;
3114
3115 case CKK_DES:
3116 case CKK_DES2:
3117 case CKK_DES3:
3118 /* CKA_VALUE_LEN attribute does not apply to DES<n> */
3119 if (isValueLen) {
3120 rv = CKR_TEMPLATE_INCONSISTENT;
3121 goto fail_cleanup;
3122 }
3123 break;
3124
3125 default:
3126 rv = CKR_TEMPLATE_INCONSISTENT;
3127 goto fail_cleanup;
3128 }
3129 break;
3130 }
3131
3132 /* Set up object. */
3133 new_object->key_type = keytype;
3134 new_object->object_type = object_type;
3135 new_object->bool_attr_mask = attr_mask;
3136 if (isLabel) {
3137 rv = soft_add_extra_attr(&string_tmp, new_object);
3138 if (rv != CKR_OK)
3139 goto fail_cleanup;
3140 string_attr_cleanup(&string_tmp);
3141 }
3142 return (rv);
3143
3144 fail_cleanup:
3145 /*
3146 * cleanup the storage allocated to the local variables.
3147 */
3148 bigint_attr_cleanup((biginteger_t *)sck);
3149 string_attr_cleanup(&string_tmp);
3150
3151 /*
3152 * cleanup the storage allocated inside the object itself.
3153 */
3154 soft_cleanup_object(new_object);
3155
3156 return (rv);
3157 }
3158
3159
3160 /*
3161 * Build a Domain Parameter Object.
3162 *
3163 * - Parse the object's template, and when an error is detected such as
3164 * invalid attribute type, invalid attribute value, etc., return
3165 * with appropriate return value.
3166 * - Allocate storage for the Domain Parameter object.
3167 * - Build the Domain Parameter object according to the key type. Allocate
3168 * storage to hold the big integer value for the supplied attributes
3169 * that are required for a certain key type.
3170 *
3171 */
3172 CK_RV
3173 soft_build_domain_parameters_object(CK_ATTRIBUTE_PTR template,
3174 CK_ULONG ulAttrNum, soft_object_t *new_object)
3175 {
3176
3177 ulong_t i;
3178 CK_KEY_TYPE keytype = (CK_KEY_TYPE)~0UL;
3179 CK_RV rv = CKR_OK;
3180 int isLabel = 0;
3181 /* Must set flags */
3182 int isPrime = 0;
3183 int isSubprime = 0;
3184 int isBase = 0;
3185 /* Must not set flags */
3186 int isPrimeBits = 0;
3187 int isSubPrimeBits = 0;
3188
3189 biginteger_t prime;
3190 biginteger_t subprime;
3191 biginteger_t base;
3192 CK_ATTRIBUTE string_tmp;
3193
3194 domain_obj_t *dom;
3195 uchar_t object_type = 0;
3196
3197 /* prevent bigint_attr_cleanup from freeing invalid attr value */
3198 (void) memset(&prime, 0x0, sizeof (biginteger_t));
3199 (void) memset(&subprime, 0x0, sizeof (biginteger_t));
3200 (void) memset(&base, 0x0, sizeof (biginteger_t));
3201 string_tmp.pValue = NULL;
3202
3203 for (i = 0; i < ulAttrNum; i++) {
3204
3205 /* Domain Parameters Object Attributes */
3206 switch (template[i].type) {
3207
3208 /* common domain parameter attribute */
3209 case CKA_KEY_TYPE:
3210 keytype = *((CK_KEY_TYPE*)template[i].pValue);
3211 break;
3212
3213 /*
3214 * The following common domain parameter attribute
3215 * must not be specified by C_CreateObject.
3216 */
3217 case CKA_LOCAL:
3218 rv = CKR_TEMPLATE_INCONSISTENT;
3219 goto fail_cleanup;
3220
3221 /*
3222 * The following domain parameter attributes must be
3223 * specified according to the key type by
3224 * C_CreateObject.
3225 */
3226 case CKA_PRIME:
3227 isPrime = 1;
3228 /*
3229 * Copyin big integer attribute from template
3230 * to a local variable.
3231 */
3232 rv = get_bigint_attr_from_template(&prime,
3233 &template[i]);
3234 if (rv != CKR_OK)
3235 goto fail_cleanup;
3236 break;
3237
3238 case CKA_SUBPRIME:
3239 isSubprime = 1;
3240 rv = get_bigint_attr_from_template(&subprime,
3241 &template[i]);
3242 if (rv != CKR_OK)
3243 goto fail_cleanup;
3244 break;
3245
3246 case CKA_BASE:
3247 isBase = 1;
3248 rv = get_bigint_attr_from_template(&base,
3249 &template[i]);
3250 if (rv != CKR_OK)
3251 goto fail_cleanup;
3252 break;
3253
3254 case CKA_PRIME_BITS:
3255 isPrimeBits = 1;
3256 break;
3257
3258 case CKA_SUB_PRIME_BITS:
3259 isSubPrimeBits = 1;
3260 break;
3261
3262 case CKA_LABEL:
3263 isLabel = 1;
3264 rv = get_string_from_template(&string_tmp,
3265 &template[i]);
3266 if (rv != CKR_OK)
3267 goto fail_cleanup;
3268 break;
3269
3270 default:
3271 rv = soft_parse_common_attrs(&template[i],
3272 &object_type);
3273 if (rv != CKR_OK)
3274 goto fail_cleanup;
3275 break;
3276
3277 }
3278 } /* For */
3279
3280 /* Allocate storage for Domain Parameters Object. */
3281 dom = calloc(1, sizeof (domain_obj_t));
3282 if (dom == NULL) {
3283 rv = CKR_HOST_MEMORY;
3284 goto fail_cleanup;
3285 }
3286
3287 new_object->object_class_u.domain = dom;
3288 new_object->class = CKO_DOMAIN_PARAMETERS;
3289
3290 if (keytype == (CK_KEY_TYPE)~0UL) {
3291 rv = CKR_TEMPLATE_INCOMPLETE;
3292 goto fail_cleanup;
3293 }
3294
3295 new_object->key_type = keytype;
3296
3297 /* Supported key types of the Domain Parameters Object */
3298 switch (keytype) {
3299 case CKK_DSA:
3300 if (isPrimeBits || isSubPrimeBits) {
3301 rv = CKR_TEMPLATE_INCONSISTENT;
3302 goto fail_cleanup;
3303 }
3304
3305 if (isPrime && isSubprime && isBase) {
3306 /*
3307 * Copy big integer attribute value to the
3308 * designated place in the domain parameter
3309 * object.
3310 */
3311 copy_bigint_attr(&prime, KEY_DOM_DSA_PRIME(dom));
3312
3313 copy_bigint_attr(&subprime, KEY_DOM_DSA_SUBPRIME(dom));
3314
3315 copy_bigint_attr(&base, KEY_DOM_DSA_BASE(dom));
3316 } else {
3317 rv = CKR_TEMPLATE_INCOMPLETE;
3318 goto fail_cleanup;
3319 }
3320 break;
3321
3322 case CKK_DH:
3323 if (isPrimeBits || isSubprime || isSubPrimeBits) {
3324 rv = CKR_TEMPLATE_INCONSISTENT;
3325 goto fail_cleanup;
3326 }
3327
3328 if (isPrime && isBase) {
3329 copy_bigint_attr(&prime, KEY_DOM_DH_PRIME(dom));
3330
3331 copy_bigint_attr(&base, KEY_DOM_DH_BASE(dom));
3332 } else {
3333 rv = CKR_TEMPLATE_INCOMPLETE;
3334 goto fail_cleanup;
3335 }
3336 break;
3337
3338 case CKK_X9_42_DH:
3339 if (isPrimeBits || isSubPrimeBits) {
3340 rv = CKR_TEMPLATE_INCONSISTENT;
3341 goto fail_cleanup;
3342 }
3343
3344 if (isPrime && isSubprime && isBase) {
3345 copy_bigint_attr(&prime, KEY_DOM_DH942_PRIME(dom));
3346
3347 copy_bigint_attr(&base, KEY_DOM_DH942_BASE(dom));
3348
3349 copy_bigint_attr(&subprime,
3350 KEY_DOM_DH942_SUBPRIME(dom));
3351 } else {
3352 rv = CKR_TEMPLATE_INCOMPLETE;
3353 goto fail_cleanup;
3354 }
3355 break;
3356
3357 default:
3358 rv = CKR_TEMPLATE_INCONSISTENT;
3359 goto fail_cleanup;
3360 }
3361
3362 new_object->object_type = object_type;
3363
3364 if (isLabel) {
3365 rv = soft_add_extra_attr(&string_tmp, new_object);
3366 if (rv != CKR_OK)
3367 goto fail_cleanup;
3368 string_attr_cleanup(&string_tmp);
3369 }
3370
3371 return (rv);
3372
3373 fail_cleanup:
3374 /*
3375 * cleanup the storage allocated to the local variables.
3376 */
3377 bigint_attr_cleanup(&prime);
3378 bigint_attr_cleanup(&subprime);
3379 bigint_attr_cleanup(&base);
3380 string_attr_cleanup(&string_tmp);
3381
3382 /*
3383 * cleanup the storage allocated inside the object itself.
3384 */
3385 soft_cleanup_object(new_object);
3386
3387 return (rv);
3388 }
3389
3390 /*
3391 * Build a Certificate Object
3392 *
3393 * - Parse the object's template, and when an error is detected such as
3394 * invalid attribute type, invalid attribute value, etc., return
3395 * with appropriate return value.
3396 * - Allocate storage for the Certificate object
3397 */
3398 static CK_RV
3399 soft_build_certificate_object(CK_ATTRIBUTE_PTR template,
3400 CK_ULONG ulAttrNum, soft_object_t *new_object,
3401 CK_CERTIFICATE_TYPE cert_type)
3402 {
3403 uint64_t attr_mask = 0;
3404 CK_RV rv = CKR_OK;
3405 CK_ULONG i;
3406 int owner_set = 0;
3407 int value_set = 0;
3408 int subject_set = 0;
3409 certificate_obj_t *cert;
3410 /* certificate type defaults to the value given as a parameter */
3411 CK_CERTIFICATE_TYPE certtype = cert_type;
3412 CK_ATTRIBUTE string_tmp;
3413 int isLabel = 0;
3414 uchar_t object_type = 0;
3415
3416 /*
3417 * Look for the certificate type attribute and do some
3418 * sanity checking before creating the structures.
3419 */
3420 for (i = 0; i < ulAttrNum; i++) {
3421 /* Certificate Object Attributes */
3422 switch (template[i].type) {
3423 case CKA_CERTIFICATE_TYPE:
3424 certtype =
3425 *((CK_CERTIFICATE_TYPE*)template[i].pValue);
3426 break;
3427 case CKA_SUBJECT:
3428 subject_set = 1;
3429 break;
3430 case CKA_OWNER:
3431 owner_set = 1;
3432 break;
3433 case CKA_VALUE:
3434 value_set = 1;
3435 break;
3436 }
3437 }
3438
3439 /* The certificate type MUST be specified */
3440 if (certtype != CKC_X_509 && certtype != CKC_X_509_ATTR_CERT)
3441 return (CKR_TEMPLATE_INCOMPLETE);
3442
3443 /*
3444 * For X.509 certs, the CKA_SUBJECT and CKA_VALUE
3445 * must be present at creation time.
3446 */
3447 if (certtype == CKC_X_509 &&
3448 (!subject_set || !value_set))
3449 return (CKR_TEMPLATE_INCOMPLETE);
3450
3451 /*
3452 * For X.509 Attribute certs, the CKA_OWNER and CKA_VALUE
3453 * must be present at creation time.
3454 */
3455 if (certtype == CKC_X_509_ATTR_CERT &&
3456 (!owner_set || !value_set))
3457 return (CKR_TEMPLATE_INCOMPLETE);
3458
3459 string_tmp.pValue = NULL;
3460 cert = calloc(1, sizeof (certificate_obj_t));
3461 if (cert == NULL) {
3462 return (CKR_HOST_MEMORY);
3463 }
3464 cert->certificate_type = certtype;
3465
3466 for (i = 0; i < ulAttrNum; i++) {
3467 /* Certificate Object Attributes */
3468 switch (certtype) {
3469 case CKC_X_509:
3470 switch (template[i].type) {
3471 case CKA_SUBJECT:
3472 rv = get_cert_attr_from_template(
3473 &cert->cert_type_u.x509.subject,
3474 &template[i]);
3475 break;
3476 case CKA_VALUE:
3477 rv = get_cert_attr_from_template(
3478 &cert->cert_type_u.x509.value,
3479 &template[i]);
3480 break;
3481 case CKA_LABEL:
3482 isLabel = 1;
3483 rv = get_string_from_template(
3484 &string_tmp,
3485 &template[i]);
3486 if (rv != CKR_OK)
3487 goto fail_cleanup;
3488 break;
3489 case CKA_ID:
3490 case CKA_ISSUER:
3491 case CKA_SERIAL_NUMBER:
3492 rv = soft_add_extra_attr(&template[i],
3493 new_object);
3494 break;
3495 case CKA_MODIFIABLE:
3496 if ((*(CK_BBOOL *)template[i].pValue) ==
3497 B_FALSE)
3498 attr_mask |=
3499 NOT_MODIFIABLE_BOOL_ON;
3500 break;
3501 case CKA_CERTIFICATE_TYPE:
3502 break;
3503 default:
3504 rv = soft_parse_common_attrs(
3505 &template[i], &object_type);
3506 if (rv != CKR_OK)
3507 goto fail_cleanup;
3508 }
3509 break;
3510 case CKC_X_509_ATTR_CERT:
3511 switch (template[i].type) {
3512 case CKA_OWNER:
3513 rv = get_cert_attr_from_template(
3514 &cert->cert_type_u.x509_attr.owner,
3515 &template[i]);
3516 break;
3517 case CKA_VALUE:
3518 rv = get_cert_attr_from_template(
3519 &cert->cert_type_u.x509_attr.value,
3520 &template[i]);
3521 break;
3522 case CKA_LABEL:
3523 isLabel = 1;
3524 rv = get_string_from_template(
3525 &string_tmp, &template[i]);
3526 if (rv != CKR_OK)
3527 goto fail_cleanup;
3528 break;
3529 case CKA_SERIAL_NUMBER:
3530 case CKA_AC_ISSUER:
3531 case CKA_ATTR_TYPES:
3532 rv = soft_add_extra_attr(&template[i],
3533 new_object);
3534 break;
3535
3536 case CKA_MODIFIABLE:
3537 if ((*(CK_BBOOL *)template[i].pValue) ==
3538 B_FALSE)
3539 attr_mask |=
3540 NOT_MODIFIABLE_BOOL_ON;
3541 break;
3542 case CKA_CERTIFICATE_TYPE:
3543 break;
3544 default:
3545 rv = soft_parse_common_attrs(
3546 &template[i], &object_type);
3547 if (rv != CKR_OK)
3548 goto fail_cleanup;
3549 break;
3550 }
3551 break;
3552 default:
3553 rv = CKR_TEMPLATE_INCOMPLETE;
3554 break;
3555 }
3556 }
3557
3558 if (rv == CKR_OK) {
3559 new_object->object_class_u.certificate = cert;
3560 new_object->class = CKO_CERTIFICATE;
3561 new_object->object_type = object_type;
3562 new_object->cert_type = certtype;
3563 new_object->bool_attr_mask = attr_mask;
3564 if (isLabel) {
3565 rv = soft_add_extra_attr(&string_tmp, new_object);
3566 if (rv != CKR_OK)
3567 goto fail_cleanup;
3568 string_attr_cleanup(&string_tmp);
3569 }
3570 }
3571
3572 fail_cleanup:
3573 if (rv != CKR_OK) {
3574 soft_cleanup_cert_object(new_object);
3575 }
3576 return (rv);
3577 }
3578
3579
3580 /*
3581 * Validate the attribute types in the object's template. Then,
3582 * call the appropriate build function according to the class of
3583 * the object specified in the template.
3584 *
3585 * Note: The following classes of objects are supported:
3586 * - CKO_PUBLIC_KEY
3587 * - CKO_PRIVATE_KEY
3588 * - CKO_SECRET_KEY
3589 * - CKO_DOMAIN_PARAMETERS
3590 * - CKO_CERTIFICATE
3591 *
3592 */
3593 CK_RV
3594 soft_build_object(CK_ATTRIBUTE_PTR template, CK_ULONG ulAttrNum,
3595 soft_object_t *new_object)
3596 {
3597
3598 CK_OBJECT_CLASS class = (CK_OBJECT_CLASS)~0UL;
3599 CK_RV rv = CKR_OK;
3600
3601 if (template == NULL) {
3602 return (CKR_ARGUMENTS_BAD);
3603 }
3604
3605 /* Validate the attribute type in the template. */
3606 rv = soft_validate_attr(template, ulAttrNum, &class);
3607 if (rv != CKR_OK)
3608 return (rv);
3609 /*
3610 * CKA_CLASS is a mandatory attribute for C_CreateObject
3611 */
3612 if (class == (CK_OBJECT_CLASS)~0UL)
3613 return (CKR_TEMPLATE_INCOMPLETE);
3614
3615 /*
3616 * Call the appropriate function based on the supported class
3617 * of the object.
3618 */
3619 switch (class) {
3620 case CKO_PUBLIC_KEY:
3621 rv = soft_build_public_key_object(template, ulAttrNum,
3622 new_object, SOFT_CREATE_OBJ, (CK_KEY_TYPE)~0UL);
3623 break;
3624
3625 case CKO_PRIVATE_KEY:
3626 rv = soft_build_private_key_object(template, ulAttrNum,
3627 new_object, SOFT_CREATE_OBJ, (CK_KEY_TYPE)~0UL);
3628 break;
3629
3630 case CKO_SECRET_KEY:
3631 rv = soft_build_secret_key_object(template, ulAttrNum,
3632 new_object, SOFT_CREATE_OBJ, 0, (CK_KEY_TYPE)~0UL);
3633 break;
3634
3635 case CKO_DOMAIN_PARAMETERS:
3636 rv = soft_build_domain_parameters_object(template, ulAttrNum,
3637 new_object);
3638 break;
3639
3640 case CKO_CERTIFICATE:
3641 rv = soft_build_certificate_object(template, ulAttrNum,
3642 new_object, (CK_CERTIFICATE_TYPE)~0UL);
3643 break;
3644
3645 case CKO_DATA:
3646 case CKO_HW_FEATURE:
3647 case CKO_VENDOR_DEFINED:
3648 default:
3649 return (CKR_ATTRIBUTE_VALUE_INVALID);
3650 }
3651
3652 return (rv);
3653 }
3654
3655 /*
3656 * Validate the attribute types in the object's template. Then,
3657 * call the appropriate build function according to the class of
3658 * the object specified in the template.
3659 *
3660 */
3661 CK_RV
3662 soft_build_key(CK_ATTRIBUTE_PTR template, CK_ULONG ulAttrNum,
3663 soft_object_t *new_object, CK_OBJECT_CLASS class, CK_KEY_TYPE key_type,
3664 CK_ULONG key_len, CK_ULONG mode)
3665 {
3666
3667 CK_RV rv = CKR_OK;
3668 CK_OBJECT_CLASS temp_class = (CK_OBJECT_CLASS)~0UL;
3669
3670 /* Validate the attribute type in the template. */
3671 if ((template != NULL) && (ulAttrNum != 0)) {
3672 rv = soft_validate_attr(template, ulAttrNum, &temp_class);
3673 if (rv != CKR_OK)
3674 return (rv);
3675 }
3676
3677 /*
3678 * If either the class from the parameter list ("class") or
3679 * the class from the template ("temp_class") is not specified,
3680 * try to use the other one.
3681 */
3682 if (temp_class == (CK_OBJECT_CLASS)~0UL) {
3683 temp_class = class;
3684 } else if (class == (CK_OBJECT_CLASS)~0UL) {
3685 class = temp_class;
3686 }
3687
3688 /* If object class is still not specified, template is incomplete. */
3689 if (class == (CK_OBJECT_CLASS)~0UL)
3690 return (CKR_TEMPLATE_INCOMPLETE);
3691
3692 /* Class should match if specified in both parameters and template. */
3693 if (class != temp_class)
3694 return (CKR_TEMPLATE_INCONSISTENT);
3695
3696 /*
3697 * Call the appropriate function based on the supported class
3698 * of the object.
3699 */
3700 switch (class) {
3701 case CKO_PUBLIC_KEY:
3702
3703 /* Unwrapping public keys is not supported. */
3704 if (mode == SOFT_UNWRAP_KEY) {
3705 rv = CKR_ATTRIBUTE_VALUE_INVALID;
3706 break;
3707 }
3708
3709 rv = soft_build_public_key_object(template, ulAttrNum,
3710 new_object, mode, key_type);
3711 break;
3712
3713 case CKO_PRIVATE_KEY:
3714
3715 rv = soft_build_private_key_object(template, ulAttrNum,
3716 new_object, mode, key_type);
3717 break;
3718
3719 case CKO_SECRET_KEY:
3720
3721 rv = soft_build_secret_key_object(template, ulAttrNum,
3722 new_object, mode, key_len, key_type);
3723 break;
3724
3725 case CKO_DOMAIN_PARAMETERS:
3726
3727 /* Unwrapping domain parameters is not supported. */
3728 if (mode == SOFT_UNWRAP_KEY) {
3729 rv = CKR_ATTRIBUTE_VALUE_INVALID;
3730 break;
3731 }
3732
3733 rv = soft_build_domain_parameters_object(template, ulAttrNum,
3734 new_object);
3735 break;
3736
3737 case CKO_DATA:
3738 case CKO_CERTIFICATE:
3739 case CKO_HW_FEATURE:
3740 case CKO_VENDOR_DEFINED:
3741 default:
3742 return (CKR_ATTRIBUTE_VALUE_INVALID);
3743 }
3744
3745 return (rv);
3746 }
3747
3748
3749 /*
3750 * Get the value of a requested attribute that is common to all supported
3751 * classes (i.e. public key, private key, secret key, domain parameters,
3752 * and certificate classes).
3753 */
3754 CK_RV
3755 soft_get_common_attrs(soft_object_t *object_p, CK_ATTRIBUTE_PTR template,
3756 uchar_t object_type)
3757 {
3758
3759 CK_RV rv = CKR_OK;
3760
3761 switch (template->type) {
3762
3763 case CKA_CLASS:
3764 return (get_ulong_attr_from_object(object_p->class,
3765 template));
3766
3767 /* default boolean attributes */
3768 case CKA_TOKEN:
3769 template->ulValueLen = sizeof (CK_BBOOL);
3770 if (template->pValue == NULL) {
3771 return (CKR_OK);
3772 }
3773 if (object_type & TOKEN_OBJECT)
3774 *((CK_BBOOL *)template->pValue) = B_TRUE;
3775 else
3776 *((CK_BBOOL *)template->pValue) = B_FALSE;
3777 break;
3778
3779 case CKA_PRIVATE:
3780
3781 template->ulValueLen = sizeof (CK_BBOOL);
3782 if (template->pValue == NULL) {
3783 return (CKR_OK);
3784 }
3785 if (object_type & PRIVATE_OBJECT)
3786 *((CK_BBOOL *)template->pValue) = B_TRUE;
3787 else
3788 *((CK_BBOOL *)template->pValue) = B_FALSE;
3789 break;
3790
3791 case CKA_MODIFIABLE:
3792 template->ulValueLen = sizeof (CK_BBOOL);
3793 if (template->pValue == NULL) {
3794 return (CKR_OK);
3795 }
3796 if ((object_p->bool_attr_mask) & NOT_MODIFIABLE_BOOL_ON)
3797 *((CK_BBOOL *)template->pValue) = B_FALSE;
3798 else
3799 *((CK_BBOOL *)template->pValue) = B_TRUE;
3800 break;
3801
3802 case CKA_LABEL:
3803 return (get_extra_attr_from_object(object_p,
3804 template));
3805
3806 default:
3807 /*
3808 * The specified attribute for the object is invalid.
3809 * (the object does not possess such an attribute.)
3810 */
3811 template->ulValueLen = (CK_ULONG)-1;
3812 return (CKR_ATTRIBUTE_TYPE_INVALID);
3813 }
3814
3815 return (rv);
3816 }
3817
3818 /*
3819 * Get the value of a requested attribute that is common to all key objects
3820 * (i.e. public key, private key and secret key).
3821 */
3822 CK_RV
3823 soft_get_common_key_attrs(soft_object_t *object_p, CK_ATTRIBUTE_PTR template)
3824 {
3825
3826 switch (template->type) {
3827
3828 case CKA_KEY_TYPE:
3829 return (get_ulong_attr_from_object(object_p->key_type,
3830 template));
3831
3832 case CKA_ID:
3833 case CKA_START_DATE:
3834 case CKA_END_DATE:
3835 /*
3836 * The above extra attributes have byte array type.
3837 */
3838 return (get_extra_attr_from_object(object_p,
3839 template));
3840
3841 /* Key related boolean attributes */
3842 case CKA_LOCAL:
3843 return (get_bool_attr_from_object(object_p,
3844 LOCAL_BOOL_ON, template));
3845
3846 case CKA_DERIVE:
3847 return (get_bool_attr_from_object(object_p,
3848 DERIVE_BOOL_ON, template));
3849
3850 case CKA_KEY_GEN_MECHANISM:
3851 return (get_ulong_attr_from_object(object_p->mechanism,
3852 template));
3853
3854 default:
3855 return (CKR_ATTRIBUTE_TYPE_INVALID);
3856 }
3857 }
3858
3859 /*
3860 * Get the value of a requested attribute of a Public Key Object.
3861 *
3862 * Rule: All the attributes in the public key object can be revealed.
3863 */
3864 CK_RV
3865 soft_get_public_key_attribute(soft_object_t *object_p,
3866 CK_ATTRIBUTE_PTR template)
3867 {
3868
3869 CK_RV rv = CKR_OK;
3870 CK_KEY_TYPE keytype = object_p->key_type;
3871
3872 switch (template->type) {
3873
3874 case CKA_SUBJECT:
3875 case CKA_EC_PARAMS:
3876 /*
3877 * The above extra attributes have byte array type.
3878 */
3879 return (get_extra_attr_from_object(object_p,
3880 template));
3881
3882 /* Key related boolean attributes */
3883 case CKA_ENCRYPT:
3884 return (get_bool_attr_from_object(object_p,
3885 ENCRYPT_BOOL_ON, template));
3886
3887 case CKA_VERIFY:
3888 return (get_bool_attr_from_object(object_p,
3889 VERIFY_BOOL_ON, template));
3890
3891 case CKA_VERIFY_RECOVER:
3892 return (get_bool_attr_from_object(object_p,
3893 VERIFY_RECOVER_BOOL_ON, template));
3894
3895 case CKA_WRAP:
3896 return (get_bool_attr_from_object(object_p,
3897 WRAP_BOOL_ON, template));
3898
3899 case CKA_TRUSTED:
3900 return (get_bool_attr_from_object(object_p,
3901 TRUSTED_BOOL_ON, template));
3902
3903 case CKA_MODULUS:
3904 /*
3905 * This attribute is valid only for RSA public key
3906 * object.
3907 */
3908 if (keytype == CKK_RSA) {
3909 return (get_bigint_attr_from_object(
3910 OBJ_PUB_RSA_MOD(object_p), template));
3911 } else {
3912 template->ulValueLen = (CK_ULONG)-1;
3913 return (CKR_ATTRIBUTE_TYPE_INVALID);
3914 }
3915
3916 case CKA_PUBLIC_EXPONENT:
3917 if (keytype == CKK_RSA) {
3918 return (get_bigint_attr_from_object(
3919 OBJ_PUB_RSA_PUBEXPO(object_p), template));
3920 } else {
3921 template->ulValueLen = (CK_ULONG)-1;
3922 return (CKR_ATTRIBUTE_TYPE_INVALID);
3923 }
3924
3925 case CKA_MODULUS_BITS:
3926 if (keytype == CKK_RSA) {
3927 return (get_ulong_attr_from_object(
3928 OBJ_PUB_RSA_MOD_BITS(object_p), template));
3929 } else {
3930 template->ulValueLen = (CK_ULONG)-1;
3931 return (CKR_ATTRIBUTE_TYPE_INVALID);
3932 }
3933
3934 case CKA_PRIME:
3935 switch (keytype) {
3936 case CKK_DSA:
3937 return (get_bigint_attr_from_object(
3938 OBJ_PUB_DSA_PRIME(object_p), template));
3939
3940 case CKK_DH:
3941 return (get_bigint_attr_from_object(
3942 OBJ_PUB_DH_PRIME(object_p), template));
3943
3944 case CKK_X9_42_DH:
3945 return (get_bigint_attr_from_object(
3946 OBJ_PUB_DH942_PRIME(object_p), template));
3947
3948 default:
3949 template->ulValueLen = (CK_ULONG)-1;
3950 return (CKR_ATTRIBUTE_TYPE_INVALID);
3951 }
3952
3953 case CKA_SUBPRIME:
3954 switch (keytype) {
3955 case CKK_DSA:
3956 return (get_bigint_attr_from_object(
3957 OBJ_PUB_DSA_SUBPRIME(object_p), template));
3958
3959 case CKK_X9_42_DH:
3960 return (get_bigint_attr_from_object(
3961 OBJ_PUB_DH942_SUBPRIME(object_p), template));
3962
3963 default:
3964 template->ulValueLen = (CK_ULONG)-1;
3965 return (CKR_ATTRIBUTE_TYPE_INVALID);
3966 }
3967
3968 case CKA_BASE:
3969 switch (keytype) {
3970 case CKK_DSA:
3971 return (get_bigint_attr_from_object(
3972 OBJ_PUB_DSA_BASE(object_p), template));
3973
3974 case CKK_DH:
3975 return (get_bigint_attr_from_object(
3976 OBJ_PUB_DH_BASE(object_p), template));
3977
3978 case CKK_X9_42_DH:
3979 return (get_bigint_attr_from_object(
3980 OBJ_PUB_DH942_BASE(object_p), template));
3981
3982 default:
3983 template->ulValueLen = (CK_ULONG)-1;
3984 return (CKR_ATTRIBUTE_TYPE_INVALID);
3985 }
3986
3987 case CKA_EC_POINT:
3988 return (get_bigint_attr_from_object(
3989 OBJ_PUB_EC_POINT(object_p), template));
3990
3991 case CKA_VALUE:
3992 switch (keytype) {
3993 case CKK_DSA:
3994 return (get_bigint_attr_from_object(
3995 OBJ_PUB_DSA_VALUE(object_p), template));
3996
3997 case CKK_DH:
3998 return (get_bigint_attr_from_object(
3999 OBJ_PUB_DH_VALUE(object_p), template));
4000
4001 case CKK_X9_42_DH:
4002 return (get_bigint_attr_from_object(
4003 OBJ_PUB_DH942_VALUE(object_p), template));
4004
4005 default:
4006 template->ulValueLen = (CK_ULONG)-1;
4007 return (CKR_ATTRIBUTE_TYPE_INVALID);
4008 }
4009
4010 default:
4011 /*
4012 * First, get the value of the request attribute defined
4013 * in the list of common key attributes. If the request
4014 * attribute is not found in that list, then get the
4015 * attribute from the list of common attributes.
4016 */
4017 rv = soft_get_common_key_attrs(object_p, template);
4018 if (rv == CKR_ATTRIBUTE_TYPE_INVALID) {
4019 rv = soft_get_common_attrs(object_p, template,
4020 object_p->object_type);
4021 }
4022 break;
4023 }
4024
4025 return (rv);
4026 }
4027
4028
4029 /*
4030 * Get the value of a requested attribute of a Private Key Object.
4031 *
4032 * Rule: All the attributes in the private key object can be revealed
4033 * except those marked with footnote number "7" when the object
4034 * has its CKA_SENSITIVE attribute set to TRUE or its
4035 * CKA_EXTRACTABLE attribute set to FALSE (p.88 in PKCS11 spec.).
4036 */
4037 CK_RV
4038 soft_get_private_key_attribute(soft_object_t *object_p,
4039 CK_ATTRIBUTE_PTR template)
4040 {
4041
4042 CK_RV rv = CKR_OK;
4043 CK_KEY_TYPE keytype = object_p->key_type;
4044
4045
4046 /*
4047 * If the following specified attributes for the private key
4048 * object cannot be revealed because the object is sensitive
4049 * or unextractable, then the ulValueLen is set to -1.
4050 */
4051 if ((object_p->bool_attr_mask & SENSITIVE_BOOL_ON) ||
4052 !(object_p->bool_attr_mask & EXTRACTABLE_BOOL_ON)) {
4053
4054 switch (template->type) {
4055 case CKA_PRIVATE_EXPONENT:
4056 case CKA_PRIME_1:
4057 case CKA_PRIME_2:
4058 case CKA_EXPONENT_1:
4059 case CKA_EXPONENT_2:
4060 case CKA_COEFFICIENT:
4061 case CKA_VALUE:
4062 template->ulValueLen = (CK_ULONG)-1;
4063 return (CKR_ATTRIBUTE_SENSITIVE);
4064 }
4065 }
4066
4067 switch (template->type) {
4068
4069 case CKA_SUBJECT:
4070 case CKA_EC_PARAMS:
4071 /*
4072 * The above extra attributes have byte array type.
4073 */
4074 return (get_extra_attr_from_object(object_p,
4075 template));
4076
4077 /* Key related boolean attributes */
4078 case CKA_SENSITIVE:
4079 return (get_bool_attr_from_object(object_p,
4080 SENSITIVE_BOOL_ON, template));
4081
4082 case CKA_SECONDARY_AUTH:
4083 return (get_bool_attr_from_object(object_p,
4084 SECONDARY_AUTH_BOOL_ON, template));
4085
4086 case CKA_DECRYPT:
4087 return (get_bool_attr_from_object(object_p,
4088 DECRYPT_BOOL_ON, template));
4089
4090 case CKA_SIGN:
4091 return (get_bool_attr_from_object(object_p,
4092 SIGN_BOOL_ON, template));
4093
4094 case CKA_SIGN_RECOVER:
4095 return (get_bool_attr_from_object(object_p,
4096 SIGN_RECOVER_BOOL_ON, template));
4097
4098 case CKA_UNWRAP:
4099 return (get_bool_attr_from_object(object_p,
4100 UNWRAP_BOOL_ON, template));
4101
4102 case CKA_EXTRACTABLE:
4103 return (get_bool_attr_from_object(object_p,
4104 EXTRACTABLE_BOOL_ON, template));
4105
4106 case CKA_ALWAYS_SENSITIVE:
4107 return (get_bool_attr_from_object(object_p,
4108 ALWAYS_SENSITIVE_BOOL_ON, template));
4109
4110 case CKA_NEVER_EXTRACTABLE:
4111 return (get_bool_attr_from_object(object_p,
4112 NEVER_EXTRACTABLE_BOOL_ON, template));
4113
4114 case CKA_MODULUS:
4115 if (keytype == CKK_RSA) {
4116 return (get_bigint_attr_from_object(
4117 OBJ_PRI_RSA_MOD(object_p), template));
4118 } else {
4119 template->ulValueLen = (CK_ULONG)-1;
4120 rv = CKR_ATTRIBUTE_TYPE_INVALID;
4121 break;
4122 }
4123
4124 case CKA_PUBLIC_EXPONENT:
4125 if (keytype == CKK_RSA) {
4126 return (get_bigint_attr_from_object(
4127 OBJ_PRI_RSA_PUBEXPO(object_p), template));
4128 } else {
4129 template->ulValueLen = (CK_ULONG)-1;
4130 rv = CKR_ATTRIBUTE_TYPE_INVALID;
4131 break;
4132 }
4133
4134 case CKA_PRIVATE_EXPONENT:
4135 if (keytype == CKK_RSA) {
4136 return (get_bigint_attr_from_object(
4137 OBJ_PRI_RSA_PRIEXPO(object_p), template));
4138 } else {
4139 template->ulValueLen = (CK_ULONG)-1;
4140 rv = CKR_ATTRIBUTE_TYPE_INVALID;
4141 break;
4142 }
4143
4144 case CKA_PRIME_1:
4145 if (keytype == CKK_RSA) {
4146 return (get_bigint_attr_from_object(
4147 OBJ_PRI_RSA_PRIME1(object_p), template));
4148 } else {
4149 template->ulValueLen = (CK_ULONG)-1;
4150 rv = CKR_ATTRIBUTE_TYPE_INVALID;
4151 break;
4152 }
4153
4154 case CKA_PRIME_2:
4155 if (keytype == CKK_RSA) {
4156 return (get_bigint_attr_from_object(
4157 OBJ_PRI_RSA_PRIME2(object_p), template));
4158 } else {
4159 template->ulValueLen = (CK_ULONG)-1;
4160 rv = CKR_ATTRIBUTE_TYPE_INVALID;
4161 break;
4162 }
4163
4164 case CKA_EXPONENT_1:
4165 if (keytype == CKK_RSA) {
4166 return (get_bigint_attr_from_object(
4167 OBJ_PRI_RSA_EXPO1(object_p), template));
4168 } else {
4169 template->ulValueLen = (CK_ULONG)-1;
4170 rv = CKR_ATTRIBUTE_TYPE_INVALID;
4171 break;
4172 }
4173
4174 case CKA_EXPONENT_2:
4175 if (keytype == CKK_RSA) {
4176 return (get_bigint_attr_from_object(
4177 OBJ_PRI_RSA_EXPO2(object_p), template));
4178 } else {
4179 template->ulValueLen = (CK_ULONG)-1;
4180 rv = CKR_ATTRIBUTE_TYPE_INVALID;
4181 break;
4182 }
4183
4184 case CKA_COEFFICIENT:
4185 if (keytype == CKK_RSA) {
4186 return (get_bigint_attr_from_object(
4187 OBJ_PRI_RSA_COEF(object_p), template));
4188 } else {
4189 template->ulValueLen = (CK_ULONG)-1;
4190 rv = CKR_ATTRIBUTE_TYPE_INVALID;
4191 break;
4192 }
4193
4194 case CKA_VALUE_BITS:
4195 if (keytype == CKK_DH) {
4196 return (get_ulong_attr_from_object(
4197 OBJ_PRI_DH_VAL_BITS(object_p), template));
4198 } else {
4199 template->ulValueLen = (CK_ULONG)-1;
4200 rv = CKR_ATTRIBUTE_TYPE_INVALID;
4201 break;
4202 }
4203
4204 case CKA_PRIME:
4205 switch (keytype) {
4206 case CKK_DSA:
4207 return (get_bigint_attr_from_object(
4208 OBJ_PRI_DSA_PRIME(object_p), template));
4209
4210 case CKK_DH:
4211 return (get_bigint_attr_from_object(
4212 OBJ_PRI_DH_PRIME(object_p), template));
4213
4214 case CKK_X9_42_DH:
4215 return (get_bigint_attr_from_object(
4216 OBJ_PRI_DH942_PRIME(object_p), template));
4217
4218 default:
4219 template->ulValueLen = (CK_ULONG)-1;
4220 return (CKR_ATTRIBUTE_TYPE_INVALID);
4221 }
4222
4223 case CKA_SUBPRIME:
4224 switch (keytype) {
4225 case CKK_DSA:
4226 return (get_bigint_attr_from_object(
4227 OBJ_PRI_DSA_SUBPRIME(object_p), template));
4228
4229 case CKK_X9_42_DH:
4230 return (get_bigint_attr_from_object(
4231 OBJ_PRI_DH942_SUBPRIME(object_p), template));
4232
4233 default:
4234 template->ulValueLen = (CK_ULONG)-1;
4235 return (CKR_ATTRIBUTE_TYPE_INVALID);
4236 }
4237
4238 case CKA_BASE:
4239 switch (keytype) {
4240 case CKK_DSA:
4241 return (get_bigint_attr_from_object(
4242 OBJ_PRI_DSA_BASE(object_p), template));
4243
4244 case CKK_DH:
4245 return (get_bigint_attr_from_object(
4246 OBJ_PRI_DH_BASE(object_p), template));
4247
4248 case CKK_X9_42_DH:
4249 return (get_bigint_attr_from_object(
4250 OBJ_PRI_DH942_BASE(object_p), template));
4251
4252 default:
4253 template->ulValueLen = (CK_ULONG)-1;
4254 return (CKR_ATTRIBUTE_TYPE_INVALID);
4255 }
4256
4257 case CKA_VALUE:
4258 switch (keytype) {
4259 case CKK_DSA:
4260 return (get_bigint_attr_from_object(
4261 OBJ_PRI_DSA_VALUE(object_p), template));
4262
4263 case CKK_DH:
4264 return (get_bigint_attr_from_object(
4265 OBJ_PRI_DH_VALUE(object_p), template));
4266
4267 case CKK_X9_42_DH:
4268 return (get_bigint_attr_from_object(
4269 OBJ_PRI_DH942_VALUE(object_p), template));
4270
4271 case CKK_EC:
4272 return (get_bigint_attr_from_object(
4273 OBJ_PRI_EC_VALUE(object_p), template));
4274
4275 default:
4276 template->ulValueLen = (CK_ULONG)-1;
4277 return (CKR_ATTRIBUTE_TYPE_INVALID);
4278 }
4279
4280 default:
4281 /*
4282 * First, get the value of the request attribute defined
4283 * in the list of common key attributes. If the request
4284 * attribute is not found in that list, then get the
4285 * attribute from the list of common attributes.
4286 */
4287 rv = soft_get_common_key_attrs(object_p, template);
4288 if (rv == CKR_ATTRIBUTE_TYPE_INVALID) {
4289 rv = soft_get_common_attrs(object_p, template,
4290 object_p->object_type);
4291 }
4292 break;
4293 }
4294
4295 return (rv);
4296 }
4297
4298
4299 /*
4300 * Get the value of a requested attribute of a Secret Key Object.
4301 *
4302 * Rule: All the attributes in the secret key object can be revealed
4303 * except those marked with footnote number "7" when the object
4304 * has its CKA_SENSITIVE attribute set to TRUE or its
4305 * CKA_EXTRACTABLE attribute set to FALSE (p.88 in PKCS11 spec.).
4306 */
4307 CK_RV
4308 soft_get_secret_key_attribute(soft_object_t *object_p,
4309 CK_ATTRIBUTE_PTR template)
4310 {
4311
4312 CK_RV rv = CKR_OK;
4313 CK_KEY_TYPE keytype = object_p->key_type;
4314
4315 switch (template->type) {
4316
4317 /* Key related boolean attributes */
4318 case CKA_SENSITIVE:
4319 return (get_bool_attr_from_object(object_p,
4320 SENSITIVE_BOOL_ON, template));
4321
4322 case CKA_ENCRYPT:
4323 return (get_bool_attr_from_object(object_p,
4324 ENCRYPT_BOOL_ON, template));
4325
4326 case CKA_DECRYPT:
4327 return (get_bool_attr_from_object(object_p,
4328 DECRYPT_BOOL_ON, template));
4329
4330 case CKA_SIGN:
4331 return (get_bool_attr_from_object(object_p,
4332 SIGN_BOOL_ON, template));
4333
4334 case CKA_VERIFY:
4335 return (get_bool_attr_from_object(object_p,
4336 VERIFY_BOOL_ON, template));
4337
4338 case CKA_WRAP:
4339 return (get_bool_attr_from_object(object_p,
4340 WRAP_BOOL_ON, template));
4341
4342 case CKA_UNWRAP:
4343 return (get_bool_attr_from_object(object_p,
4344 UNWRAP_BOOL_ON, template));
4345
4346 case CKA_EXTRACTABLE:
4347 return (get_bool_attr_from_object(object_p,
4348 EXTRACTABLE_BOOL_ON, template));
4349
4350 case CKA_ALWAYS_SENSITIVE:
4351 return (get_bool_attr_from_object(object_p,
4352 ALWAYS_SENSITIVE_BOOL_ON, template));
4353
4354 case CKA_NEVER_EXTRACTABLE:
4355 return (get_bool_attr_from_object(object_p,
4356 NEVER_EXTRACTABLE_BOOL_ON, template));
4357
4358 case CKA_VALUE:
4359 case CKA_VALUE_LEN:
4360 /*
4361 * If the specified attribute for the secret key object
4362 * cannot be revealed because the object is sensitive
4363 * or unextractable, then the ulValueLen is set to -1.
4364 */
4365 if ((object_p->bool_attr_mask & SENSITIVE_BOOL_ON) ||
4366 !(object_p->bool_attr_mask & EXTRACTABLE_BOOL_ON)) {
4367 template->ulValueLen = (CK_ULONG)-1;
4368 return (CKR_ATTRIBUTE_SENSITIVE);
4369 }
4370
4371 switch (keytype) {
4372 case CKK_RC4:
4373 case CKK_GENERIC_SECRET:
4374 case CKK_RC5:
4375 case CKK_DES:
4376 case CKK_DES2:
4377 case CKK_DES3:
4378 case CKK_CDMF:
4379 case CKK_AES:
4380 case CKK_BLOWFISH:
4381 if (template->type == CKA_VALUE_LEN) {
4382 return (get_ulong_attr_from_object(
4383 OBJ_SEC_VALUE_LEN(object_p),
4384 template));
4385 } else {
4386 return (get_bigint_attr_from_object(
4387 (biginteger_t *)OBJ_SEC(object_p),
4388 template));
4389 }
4390 default:
4391 template->ulValueLen = (CK_ULONG)-1;
4392 rv = CKR_ATTRIBUTE_TYPE_INVALID;
4393 break;
4394 }
4395 break;
4396
4397 default:
4398 /*
4399 * First, get the value of the request attribute defined
4400 * in the list of common key attributes. If the request
4401 * attribute is not found in that list, then get the
4402 * attribute from the list of common attributes.
4403 */
4404 rv = soft_get_common_key_attrs(object_p, template);
4405 if (rv == CKR_ATTRIBUTE_TYPE_INVALID) {
4406 rv = soft_get_common_attrs(object_p, template,
4407 object_p->object_type);
4408 }
4409 break;
4410 }
4411
4412 return (rv);
4413 }
4414
4415
4416 /*
4417 * Get the value of a requested attribute of a Domain Parameters Object.
4418 *
4419 * Rule: All the attributes in the domain parameters object can be revealed.
4420 */
4421 CK_RV
4422 soft_get_domain_parameters_attribute(soft_object_t *object_p,
4423 CK_ATTRIBUTE_PTR template)
4424 {
4425
4426 CK_RV rv = CKR_OK;
4427 CK_KEY_TYPE keytype = object_p->key_type;
4428
4429 switch (template->type) {
4430
4431 case CKA_KEY_TYPE:
4432 return (get_ulong_attr_from_object(keytype,
4433 template));
4434
4435 case CKA_LOCAL:
4436 return (get_bool_attr_from_object(object_p,
4437 LOCAL_BOOL_ON, template));
4438
4439 case CKA_PRIME:
4440 switch (keytype) {
4441 case CKK_DSA:
4442 return (get_bigint_attr_from_object(
4443 OBJ_DOM_DSA_PRIME(object_p), template));
4444
4445 case CKK_DH:
4446 return (get_bigint_attr_from_object(
4447 OBJ_DOM_DH_PRIME(object_p), template));
4448
4449 case CKK_X9_42_DH:
4450 return (get_bigint_attr_from_object(
4451 OBJ_DOM_DH942_PRIME(object_p), template));
4452
4453 default:
4454 template->ulValueLen = (CK_ULONG)-1;
4455 return (CKR_ATTRIBUTE_TYPE_INVALID);
4456 }
4457
4458 case CKA_SUBPRIME:
4459 switch (keytype) {
4460 case CKK_DSA:
4461 return (get_bigint_attr_from_object(
4462 OBJ_DOM_DSA_SUBPRIME(object_p), template));
4463
4464 case CKK_X9_42_DH:
4465 return (get_bigint_attr_from_object(
4466 OBJ_DOM_DH942_SUBPRIME(object_p), template));
4467
4468 default:
4469 template->ulValueLen = (CK_ULONG)-1;
4470 return (CKR_ATTRIBUTE_TYPE_INVALID);
4471 }
4472
4473 case CKA_BASE:
4474 switch (keytype) {
4475 case CKK_DSA:
4476 return (get_bigint_attr_from_object(
4477 OBJ_DOM_DSA_BASE(object_p), template));
4478
4479 case CKK_DH:
4480 return (get_bigint_attr_from_object(
4481 OBJ_DOM_DH_BASE(object_p), template));
4482
4483 case CKK_X9_42_DH:
4484 return (get_bigint_attr_from_object(
4485 OBJ_DOM_DH942_BASE(object_p), template));
4486
4487 default:
4488 template->ulValueLen = (CK_ULONG)-1;
4489 return (CKR_ATTRIBUTE_TYPE_INVALID);
4490 }
4491
4492 case CKA_PRIME_BITS:
4493 switch (keytype) {
4494 case CKK_DSA:
4495 return (get_ulong_attr_from_object(
4496 OBJ_DOM_DSA_PRIME_BITS(object_p), template));
4497
4498 case CKK_DH:
4499 return (get_ulong_attr_from_object(
4500 OBJ_DOM_DH_PRIME_BITS(object_p), template));
4501
4502 case CKK_X9_42_DH:
4503 return (get_ulong_attr_from_object(
4504 OBJ_DOM_DH942_PRIME_BITS(object_p), template));
4505
4506 default:
4507 template->ulValueLen = (CK_ULONG)-1;
4508 return (CKR_ATTRIBUTE_TYPE_INVALID);
4509 }
4510
4511 case CKA_SUB_PRIME_BITS:
4512 switch (keytype) {
4513 case CKK_X9_42_DH:
4514 return (get_ulong_attr_from_object(
4515 OBJ_DOM_DH942_SUBPRIME_BITS(object_p), template));
4516
4517 default:
4518 template->ulValueLen = (CK_ULONG)-1;
4519 return (CKR_ATTRIBUTE_TYPE_INVALID);
4520 }
4521
4522 default:
4523 /*
4524 * Get the value of a common attribute.
4525 */
4526 rv = soft_get_common_attrs(object_p, template,
4527 object_p->object_type);
4528 break;
4529 }
4530
4531 return (rv);
4532 }
4533
4534 /*
4535 * Get certificate attributes from an object.
4536 * return CKR_ATTRIBUTE_TYPE_INVALID if the requested type
4537 * does not exist in the certificate.
4538 */
4539 CK_RV
4540 soft_get_certificate_attribute(soft_object_t *object_p,
4541 CK_ATTRIBUTE_PTR template)
4542 {
4543 CK_CERTIFICATE_TYPE certtype = object_p->cert_type;
4544 cert_attr_t src;
4545
4546 switch (template->type) {
4547 case CKA_SUBJECT:
4548 if (certtype == CKC_X_509) {
4549 return (get_cert_attr_from_object(
4550 X509_CERT_SUBJECT(object_p), template));
4551 }
4552 break;
4553 case CKA_VALUE:
4554 if (certtype == CKC_X_509) {
4555 return (get_cert_attr_from_object(
4556 X509_CERT_VALUE(object_p), template));
4557 } else if (certtype == CKC_X_509_ATTR_CERT) {
4558 return (get_cert_attr_from_object(
4559 X509_ATTR_CERT_VALUE(object_p), template));
4560 }
4561 break;
4562 case CKA_OWNER:
4563 if (certtype == CKC_X_509_ATTR_CERT) {
4564 return (get_cert_attr_from_object(
4565 X509_ATTR_CERT_OWNER(object_p), template));
4566 }
4567 break;
4568 case CKA_CERTIFICATE_TYPE:
4569 src.value = (CK_BYTE *)&certtype;
4570 src.length = sizeof (certtype);
4571 return (get_cert_attr_from_object(&src, template));
4572 case CKA_TRUSTED:
4573 return (get_bool_attr_from_object(object_p,
4574 TRUSTED_BOOL_ON, template));
4575 case CKA_ID:
4576 case CKA_ISSUER:
4577 case CKA_SERIAL_NUMBER:
4578 case CKA_AC_ISSUER:
4579 case CKA_ATTR_TYPES:
4580 return (get_extra_attr_from_object(object_p,
4581 template));
4582 default:
4583 return (soft_get_common_attrs(object_p, template,
4584 object_p->object_type));
4585 }
4586
4587 /*
4588 * If we got this far, then the combination of certificate type
4589 * and requested attribute is invalid.
4590 */
4591 return (CKR_ATTRIBUTE_TYPE_INVALID);
4592 }
4593
4594 CK_RV
4595 soft_set_certificate_attribute(soft_object_t *object_p,
4596 CK_ATTRIBUTE_PTR template, boolean_t copy)
4597 {
4598 CK_CERTIFICATE_TYPE certtype = object_p->cert_type;
4599
4600 switch (template->type) {
4601 case CKA_SUBJECT:
4602 if (certtype == CKC_X_509) {
4603 /* SUBJECT attr cannot be modified. */
4604 return (CKR_ATTRIBUTE_READ_ONLY);
4605 }
4606 break;
4607 case CKA_OWNER:
4608 if (certtype == CKC_X_509_ATTR_CERT) {
4609 /* OWNER attr cannot be modified. */
4610 return (CKR_ATTRIBUTE_READ_ONLY);
4611 }
4612 break;
4613 case CKA_VALUE:
4614 /* VALUE attr cannot be modified. */
4615 return (CKR_ATTRIBUTE_READ_ONLY);
4616 case CKA_ID:
4617 case CKA_ISSUER:
4618 if (certtype == CKC_X_509) {
4619 return (set_extra_attr_to_object(object_p,
4620 template->type, template));
4621 }
4622 break;
4623 case CKA_AC_ISSUER:
4624 case CKA_ATTR_TYPES:
4625 if (certtype == CKC_X_509_ATTR_CERT) {
4626 return (set_extra_attr_to_object(object_p,
4627 template->type, template));
4628 }
4629 break;
4630 case CKA_SERIAL_NUMBER:
4631 case CKA_LABEL:
4632 return (set_extra_attr_to_object(object_p,
4633 template->type, template));
4634 default:
4635 return (soft_set_common_storage_attribute(
4636 object_p, template, copy));
4637 }
4638
4639 /*
4640 * If we got this far, then the combination of certificate type
4641 * and requested attribute is invalid.
4642 */
4643 return (CKR_ATTRIBUTE_TYPE_INVALID);
4644 }
4645
4646 /*
4647 * Call the appropriate get attribute function according to the class
4648 * of object.
4649 *
4650 * The caller of this function holds the lock on the object.
4651 */
4652 CK_RV
4653 soft_get_attribute(soft_object_t *object_p, CK_ATTRIBUTE_PTR template)
4654 {
4655
4656 CK_RV rv = CKR_OK;
4657 CK_OBJECT_CLASS class = object_p->class;
4658
4659 switch (class) {
4660 case CKO_PUBLIC_KEY:
4661 rv = soft_get_public_key_attribute(object_p, template);
4662 break;
4663
4664 case CKO_PRIVATE_KEY:
4665 rv = soft_get_private_key_attribute(object_p, template);
4666 break;
4667
4668 case CKO_SECRET_KEY:
4669 rv = soft_get_secret_key_attribute(object_p, template);
4670 break;
4671
4672 case CKO_DOMAIN_PARAMETERS:
4673 rv = soft_get_domain_parameters_attribute(object_p, template);
4674 break;
4675
4676 case CKO_CERTIFICATE:
4677 rv = soft_get_certificate_attribute(object_p, template);
4678 break;
4679
4680 default:
4681 /*
4682 * If the specified attribute for the object is invalid
4683 * (the object does not possess such as attribute), then
4684 * the ulValueLen is modified to hold the value -1.
4685 */
4686 template->ulValueLen = (CK_ULONG)-1;
4687 return (CKR_ATTRIBUTE_TYPE_INVALID);
4688 }
4689
4690 return (rv);
4691
4692 }
4693
4694 CK_RV
4695 soft_set_common_storage_attribute(soft_object_t *object_p,
4696 CK_ATTRIBUTE_PTR template, boolean_t copy)
4697 {
4698
4699 CK_RV rv = CKR_OK;
4700
4701 switch (template->type) {
4702
4703 case CKA_TOKEN:
4704 if (copy) {
4705 if ((*(CK_BBOOL *)template->pValue) == B_TRUE) {
4706 if (!soft_keystore_status(KEYSTORE_INITIALIZED))
4707 return (CKR_DEVICE_REMOVED);
4708 object_p->object_type |= TOKEN_OBJECT;
4709 }
4710 } else {
4711 rv = CKR_ATTRIBUTE_READ_ONLY;
4712 }
4713
4714 break;
4715
4716 case CKA_PRIVATE:
4717 if (copy) {
4718 if ((*(CK_BBOOL *)template->pValue) == B_TRUE) {
4719 (void) pthread_mutex_lock(&soft_giant_mutex);
4720 if (!soft_slot.authenticated) {
4721 /*
4722 * Check if this is the special case
4723 * when the PIN is never initialized
4724 * in the keystore. If true, we will
4725 * let it pass here and let it fail
4726 * with CKR_PIN_EXPIRED later on.
4727 */
4728 if (!soft_slot.userpin_change_needed) {
4729 (void) pthread_mutex_unlock(
4730 &soft_giant_mutex);
4731 return (CKR_USER_NOT_LOGGED_IN);
4732 }
4733 }
4734 (void) pthread_mutex_unlock(&soft_giant_mutex);
4735 object_p->object_type |= PRIVATE_OBJECT;
4736 }
4737 } else {
4738 rv = CKR_ATTRIBUTE_READ_ONLY;
4739 }
4740 break;
4741
4742 case CKA_MODIFIABLE:
4743 if (copy) {
4744 if ((*(CK_BBOOL *)template->pValue) == TRUE)
4745 object_p->bool_attr_mask &=
4746 ~NOT_MODIFIABLE_BOOL_ON;
4747 else
4748 object_p->bool_attr_mask |=
4749 NOT_MODIFIABLE_BOOL_ON;
4750 } else {
4751 rv = CKR_ATTRIBUTE_READ_ONLY;
4752 }
4753 break;
4754
4755 case CKA_CLASS:
4756 rv = CKR_ATTRIBUTE_READ_ONLY;
4757 break;
4758
4759 default:
4760 rv = CKR_TEMPLATE_INCONSISTENT;
4761 }
4762
4763 return (rv);
4764 }
4765
4766 /*
4767 * Set the value of an attribute that is common to all key objects
4768 * (i.e. public key, private key and secret key).
4769 */
4770 CK_RV
4771 soft_set_common_key_attribute(soft_object_t *object_p,
4772 CK_ATTRIBUTE_PTR template, boolean_t copy)
4773 {
4774
4775 switch (template->type) {
4776
4777 case CKA_LABEL:
4778 /*
4779 * Only the LABEL can be modified in the common storage
4780 * object attributes after the object is created.
4781 */
4782 return (set_extra_attr_to_object(object_p,
4783 CKA_LABEL, template));
4784
4785 case CKA_ID:
4786 return (set_extra_attr_to_object(object_p,
4787 CKA_ID, template));
4788
4789 case CKA_START_DATE:
4790 return (set_extra_attr_to_object(object_p,
4791 CKA_START_DATE, template));
4792
4793 case CKA_END_DATE:
4794 return (set_extra_attr_to_object(object_p,
4795 CKA_END_DATE, template));
4796
4797 case CKA_DERIVE:
4798 return (set_bool_attr_to_object(object_p,
4799 DERIVE_BOOL_ON, template));
4800
4801 case CKA_KEY_TYPE:
4802 case CKA_LOCAL:
4803 case CKA_KEY_GEN_MECHANISM:
4804 return (CKR_ATTRIBUTE_READ_ONLY);
4805
4806 default:
4807 return (soft_set_common_storage_attribute(object_p,
4808 template, copy));
4809
4810 }
4811
4812 }
4813
4814
4815 /*
4816 * Set the value of an attribute of a Public Key Object.
4817 *
4818 * Rule: The attributes marked with footnote number "8" in the PKCS11
4819 * spec may be modified (p.88 in PKCS11 spec.).
4820 */
4821 CK_RV
4822 soft_set_public_key_attribute(soft_object_t *object_p,
4823 CK_ATTRIBUTE_PTR template, boolean_t copy)
4824 {
4825 CK_KEY_TYPE keytype = object_p->key_type;
4826
4827 switch (template->type) {
4828
4829 case CKA_SUBJECT:
4830 return (set_extra_attr_to_object(object_p,
4831 CKA_SUBJECT, template));
4832
4833 case CKA_ENCRYPT:
4834 return (set_bool_attr_to_object(object_p,
4835 ENCRYPT_BOOL_ON, template));
4836
4837 case CKA_VERIFY:
4838 return (set_bool_attr_to_object(object_p,
4839 VERIFY_BOOL_ON, template));
4840
4841 case CKA_VERIFY_RECOVER:
4842 return (set_bool_attr_to_object(object_p,
4843 VERIFY_RECOVER_BOOL_ON, template));
4844
4845 case CKA_WRAP:
4846 return (set_bool_attr_to_object(object_p,
4847 WRAP_BOOL_ON, template));
4848
4849 case CKA_MODULUS:
4850 case CKA_MODULUS_BITS:
4851 case CKA_PUBLIC_EXPONENT:
4852 if (keytype == CKK_RSA)
4853 return (CKR_ATTRIBUTE_READ_ONLY);
4854 break;
4855
4856 case CKA_SUBPRIME:
4857 if ((keytype == CKK_DSA) ||
4858 (keytype == CKK_X9_42_DH))
4859 return (CKR_ATTRIBUTE_READ_ONLY);
4860 break;
4861
4862 case CKA_PRIME:
4863 case CKA_BASE:
4864 case CKA_VALUE:
4865 if ((keytype == CKK_DSA) ||
4866 (keytype == CKK_DH) ||
4867 (keytype == CKK_X9_42_DH))
4868 return (CKR_ATTRIBUTE_READ_ONLY);
4869 break;
4870
4871 default:
4872 /*
4873 * Set the value of a common key attribute.
4874 */
4875 return (soft_set_common_key_attribute(object_p,
4876 template, copy));
4877
4878 }
4879 /*
4880 * If we got this far, then the combination of key type
4881 * and requested attribute is invalid.
4882 */
4883 return (CKR_ATTRIBUTE_TYPE_INVALID);
4884 }
4885
4886
4887 /*
4888 * Set the value of an attribute of a Private Key Object.
4889 *
4890 * Rule: The attributes marked with footnote number "8" in the PKCS11
4891 * spec may be modified (p.88 in PKCS11 spec.).
4892 */
4893 CK_RV
4894 soft_set_private_key_attribute(soft_object_t *object_p,
4895 CK_ATTRIBUTE_PTR template, boolean_t copy)
4896 {
4897 CK_KEY_TYPE keytype = object_p->key_type;
4898
4899 switch (template->type) {
4900
4901 case CKA_SUBJECT:
4902 return (set_extra_attr_to_object(object_p,
4903 CKA_SUBJECT, template));
4904
4905 case CKA_SENSITIVE:
4906 /*
4907 * Cannot set SENSITIVE to FALSE if it is already ON.
4908 */
4909 if (((*(CK_BBOOL *)template->pValue) == B_FALSE) &&
4910 (object_p->bool_attr_mask & SENSITIVE_BOOL_ON)) {
4911 return (CKR_ATTRIBUTE_READ_ONLY);
4912 }
4913
4914 if (*(CK_BBOOL *)template->pValue)
4915 object_p->bool_attr_mask |= SENSITIVE_BOOL_ON;
4916 return (CKR_OK);
4917
4918 case CKA_DECRYPT:
4919 return (set_bool_attr_to_object(object_p,
4920 DECRYPT_BOOL_ON, template));
4921
4922 case CKA_SIGN:
4923 return (set_bool_attr_to_object(object_p,
4924 SIGN_BOOL_ON, template));
4925
4926 case CKA_SIGN_RECOVER:
4927 return (set_bool_attr_to_object(object_p,
4928 SIGN_RECOVER_BOOL_ON, template));
4929
4930 case CKA_UNWRAP:
4931 return (set_bool_attr_to_object(object_p,
4932 UNWRAP_BOOL_ON, template));
4933
4934 case CKA_EXTRACTABLE:
4935 /*
4936 * Cannot set EXTRACTABLE to TRUE if it is already OFF.
4937 */
4938 if ((*(CK_BBOOL *)template->pValue) &&
4939 !(object_p->bool_attr_mask & EXTRACTABLE_BOOL_ON)) {
4940 return (CKR_ATTRIBUTE_READ_ONLY);
4941 }
4942
4943 if ((*(CK_BBOOL *)template->pValue) == B_FALSE)
4944 object_p->bool_attr_mask &= ~EXTRACTABLE_BOOL_ON;
4945 return (CKR_OK);
4946
4947 case CKA_MODULUS:
4948 case CKA_PUBLIC_EXPONENT:
4949 case CKA_PRIVATE_EXPONENT:
4950 case CKA_PRIME_1:
4951 case CKA_PRIME_2:
4952 case CKA_EXPONENT_1:
4953 case CKA_EXPONENT_2:
4954 case CKA_COEFFICIENT:
4955 if (keytype == CKK_RSA) {
4956 return (CKR_ATTRIBUTE_READ_ONLY);
4957 }
4958 break;
4959
4960 case CKA_SUBPRIME:
4961 if ((keytype == CKK_DSA) ||
4962 (keytype == CKK_X9_42_DH))
4963 return (CKR_ATTRIBUTE_READ_ONLY);
4964 break;
4965
4966 case CKA_PRIME:
4967 case CKA_BASE:
4968 case CKA_VALUE:
4969 if ((keytype == CKK_DSA) ||
4970 (keytype == CKK_DH) ||
4971 (keytype == CKK_X9_42_DH))
4972 return (CKR_ATTRIBUTE_READ_ONLY);
4973 break;
4974
4975 case CKA_VALUE_BITS:
4976 if (keytype == CKK_DH)
4977 return (CKR_ATTRIBUTE_READ_ONLY);
4978 break;
4979
4980 default:
4981 /*
4982 * Set the value of a common key attribute.
4983 */
4984 return (soft_set_common_key_attribute(object_p,
4985 template, copy));
4986 }
4987
4988 /*
4989 * If we got this far, then the combination of key type
4990 * and requested attribute is invalid.
4991 */
4992 return (CKR_ATTRIBUTE_TYPE_INVALID);
4993 }
4994
4995 /*
4996 * Set the value of an attribute of a Secret Key Object.
4997 *
4998 * Rule: The attributes marked with footnote number "8" in the PKCS11
4999 * spec may be modified (p.88 in PKCS11 spec.).
5000 */
5001 CK_RV
5002 soft_set_secret_key_attribute(soft_object_t *object_p,
5003 CK_ATTRIBUTE_PTR template, boolean_t copy)
5004 {
5005 CK_KEY_TYPE keytype = object_p->key_type;
5006
5007 switch (template->type) {
5008
5009 case CKA_SENSITIVE:
5010 /*
5011 * Cannot set SENSITIVE to FALSE if it is already ON.
5012 */
5013 if (((*(CK_BBOOL *)template->pValue) == B_FALSE) &&
5014 (object_p->bool_attr_mask & SENSITIVE_BOOL_ON)) {
5015 return (CKR_ATTRIBUTE_READ_ONLY);
5016 }
5017
5018 if (*(CK_BBOOL *)template->pValue)
5019 object_p->bool_attr_mask |= SENSITIVE_BOOL_ON;
5020 return (CKR_OK);
5021
5022 case CKA_ENCRYPT:
5023 return (set_bool_attr_to_object(object_p,
5024 ENCRYPT_BOOL_ON, template));
5025
5026 case CKA_DECRYPT:
5027 return (set_bool_attr_to_object(object_p,
5028 DECRYPT_BOOL_ON, template));
5029
5030 case CKA_SIGN:
5031 return (set_bool_attr_to_object(object_p,
5032 SIGN_BOOL_ON, template));
5033
5034 case CKA_VERIFY:
5035 return (set_bool_attr_to_object(object_p,
5036 VERIFY_BOOL_ON, template));
5037
5038 case CKA_WRAP:
5039 return (set_bool_attr_to_object(object_p,
5040 WRAP_BOOL_ON, template));
5041
5042 case CKA_UNWRAP:
5043 return (set_bool_attr_to_object(object_p,
5044 UNWRAP_BOOL_ON, template));
5045
5046 case CKA_EXTRACTABLE:
5047 /*
5048 * Cannot set EXTRACTABLE to TRUE if it is already OFF.
5049 */
5050 if ((*(CK_BBOOL *)template->pValue) &&
5051 !(object_p->bool_attr_mask & EXTRACTABLE_BOOL_ON)) {
5052 return (CKR_ATTRIBUTE_READ_ONLY);
5053 }
5054
5055 if ((*(CK_BBOOL *)template->pValue) == B_FALSE)
5056 object_p->bool_attr_mask &= ~EXTRACTABLE_BOOL_ON;
5057 return (CKR_OK);
5058
5059 case CKA_VALUE:
5060 return (CKR_ATTRIBUTE_READ_ONLY);
5061
5062 case CKA_VALUE_LEN:
5063 if ((keytype == CKK_RC4) ||
5064 (keytype == CKK_GENERIC_SECRET) ||
5065 (keytype == CKK_AES) ||
5066 (keytype == CKK_BLOWFISH))
5067 return (CKR_ATTRIBUTE_READ_ONLY);
5068 break;
5069
5070 default:
5071 /*
5072 * Set the value of a common key attribute.
5073 */
5074 return (soft_set_common_key_attribute(object_p,
5075 template, copy));
5076
5077 }
5078 /*
5079 * If we got this far, then the combination of key type
5080 * and requested attribute is invalid.
5081 */
5082 return (CKR_ATTRIBUTE_TYPE_INVALID);
5083 }
5084
5085
5086 /*
5087 * Call the appropriate set attribute function according to the class
5088 * of object.
5089 *
5090 * The caller of this function does not hold the lock on the original
5091 * object, since this function is setting the attribute on the new object
5092 * that is being modified.
5093 *
5094 * Argument copy: TRUE when called by C_CopyObject,
5095 * FALSE when called by C_SetAttributeValue.
5096 */
5097 CK_RV
5098 soft_set_attribute(soft_object_t *object_p, CK_ATTRIBUTE_PTR template,
5099 boolean_t copy)
5100 {
5101
5102 CK_RV rv = CKR_OK;
5103 CK_OBJECT_CLASS class = object_p->class;
5104
5105 switch (class) {
5106
5107 case CKO_PUBLIC_KEY:
5108 rv = soft_set_public_key_attribute(object_p, template, copy);
5109 break;
5110
5111 case CKO_PRIVATE_KEY:
5112 rv = soft_set_private_key_attribute(object_p, template, copy);
5113 break;
5114
5115 case CKO_SECRET_KEY:
5116 rv = soft_set_secret_key_attribute(object_p, template, copy);
5117 break;
5118
5119 case CKO_DOMAIN_PARAMETERS:
5120 switch (template->type) {
5121 case CKA_LABEL:
5122 /*
5123 * Only the LABEL can be modified in the common
5124 * storage object attributes after the object is
5125 * created.
5126 */
5127 return (set_extra_attr_to_object(object_p,
5128 CKA_LABEL, template));
5129 default:
5130 return (CKR_TEMPLATE_INCONSISTENT);
5131 }
5132 case CKO_CERTIFICATE:
5133 rv = soft_set_certificate_attribute(object_p, template, copy);
5134 break;
5135
5136 default:
5137 /*
5138 * If the template specifies a value of an attribute
5139 * which is incompatible with other existing attributes
5140 * of the object, then fails with return code
5141 * CKR_TEMPLATE_INCONSISTENT.
5142 */
5143 rv = CKR_TEMPLATE_INCONSISTENT;
5144 break;
5145 }
5146
5147 return (rv);
5148 }
5149
5150 CK_RV
5151 soft_get_public_value(soft_object_t *key, CK_ATTRIBUTE_TYPE type,
5152 uchar_t *value, uint32_t *value_len)
5153 {
5154 uint32_t len = 0;
5155 switch (type) {
5156
5157 /* The following attributes belong to RSA */
5158 case CKA_MODULUS:
5159 #ifdef __sparcv9
5160 len =
5161 /* LINTED */
5162 (uint32_t)
5163 ((biginteger_t *)OBJ_PUB_RSA_MOD(key))->big_value_len;
5164 #else /* !__sparcv9 */
5165 len =
5166 ((biginteger_t *)OBJ_PUB_RSA_MOD(key))->big_value_len;
5167 #endif /* __sparcv9 */
5168
5169 /* This attribute MUST BE set */
5170 if (len == 0 || len > *value_len) {
5171 return (CKR_ATTRIBUTE_VALUE_INVALID);
5172 }
5173 *value_len = len;
5174
5175 (void) memcpy(value,
5176 ((biginteger_t *)OBJ_PUB_RSA_MOD(key))->big_value,
5177 *value_len);
5178
5179 break;
5180
5181 case CKA_PUBLIC_EXPONENT:
5182 #ifdef __sparcv9
5183 len =
5184 /* LINTED */
5185 (uint32_t)
5186 ((biginteger_t *)OBJ_PUB_RSA_PUBEXPO(key))->big_value_len;
5187 #else /* !__sparcv9 */
5188 len =
5189 ((biginteger_t *)OBJ_PUB_RSA_PUBEXPO(key))->big_value_len;
5190 #endif /* __sparcv9 */
5191
5192 /* This attribute MUST BE set */
5193 if (len == 0 || len > *value_len) {
5194 return (CKR_ATTRIBUTE_VALUE_INVALID);
5195 }
5196 *value_len = len;
5197
5198 (void) memcpy(value,
5199 ((biginteger_t *)OBJ_PUB_RSA_PUBEXPO(key))->big_value,
5200 *value_len);
5201
5202 break;
5203
5204 /* The following attributes belong to DSA and DH */
5205 case CKA_PRIME:
5206
5207 if (key->key_type == CKK_DSA)
5208 #ifdef __sparcv9
5209 len =
5210 /* LINTED */
5211 (uint32_t)
5212 ((biginteger_t *)OBJ_PUB_DSA_PRIME(key))->
5213 big_value_len;
5214 #else /* !__sparcv9 */
5215 len =
5216 ((biginteger_t *)OBJ_PUB_DSA_PRIME(key))->
5217 big_value_len;
5218 #endif /* __sparcv9 */
5219 else
5220 #ifdef __sparcv9
5221 len =
5222 /* LINTED */
5223 (uint32_t)
5224 ((biginteger_t *)OBJ_PUB_DH_PRIME(key))->
5225 big_value_len;
5226 #else /* !__sparcv9 */
5227 len =
5228 ((biginteger_t *)OBJ_PUB_DH_PRIME(key))->
5229 big_value_len;
5230 #endif /* __sparcv9 */
5231
5232 /* This attribute MUST BE set */
5233 if (len == 0 || len > *value_len) {
5234 return (CKR_ATTRIBUTE_VALUE_INVALID);
5235 }
5236 *value_len = len;
5237
5238 if (key->key_type == CKK_DSA)
5239 (void) memcpy(value,
5240 ((biginteger_t *)OBJ_PUB_DSA_PRIME(key))->big_value,
5241 *value_len);
5242 else
5243 (void) memcpy(value,
5244 ((biginteger_t *)OBJ_PUB_DH_PRIME(key))->big_value,
5245 *value_len);
5246
5247 break;
5248
5249 case CKA_SUBPRIME:
5250 #ifdef __sparcv9
5251 len =
5252 /* LINTED */
5253 (uint32_t)
5254 ((biginteger_t *)OBJ_PUB_DSA_SUBPRIME(key))->big_value_len;
5255 #else /* !__sparcv9 */
5256 len =
5257 ((biginteger_t *)OBJ_PUB_DSA_SUBPRIME(key))->big_value_len;
5258 #endif /* __sparcv9 */
5259
5260 /* This attribute MUST BE set */
5261 if (len == 0 || len > *value_len) {
5262 return (CKR_ATTRIBUTE_VALUE_INVALID);
5263 }
5264 *value_len = len;
5265
5266 (void) memcpy(value,
5267 ((biginteger_t *)OBJ_PUB_DSA_SUBPRIME(key))->big_value,
5268 *value_len);
5269
5270 break;
5271
5272 case CKA_BASE:
5273
5274 if (key->key_type == CKK_DSA)
5275 #ifdef __sparcv9
5276 len =
5277 /* LINTED */
5278 (uint32_t)
5279 ((biginteger_t *)OBJ_PUB_DSA_BASE(key))->
5280 big_value_len;
5281 #else /* !__sparcv9 */
5282 len =
5283 ((biginteger_t *)OBJ_PUB_DSA_BASE(key))->
5284 big_value_len;
5285 #endif /* __sparcv9 */
5286 else
5287 #ifdef __sparcv9
5288 len =
5289 /* LINTED */
5290 (uint32_t)
5291 ((biginteger_t *)OBJ_PUB_DH_BASE(key))->
5292 big_value_len;
5293 #else /* !__sparcv9 */
5294 len =
5295 ((biginteger_t *)OBJ_PUB_DH_BASE(key))->
5296 big_value_len;
5297 #endif /* __sparcv9 */
5298
5299 /* This attribute MUST BE set */
5300 if (len == 0 || len > *value_len) {
5301 return (CKR_ATTRIBUTE_VALUE_INVALID);
5302 }
5303 *value_len = len;
5304
5305 if (key->key_type == CKK_DSA)
5306 (void) memcpy(value,
5307 ((biginteger_t *)OBJ_PUB_DSA_BASE(key))->big_value,
5308 *value_len);
5309 else
5310 (void) memcpy(value,
5311 ((biginteger_t *)OBJ_PUB_DH_BASE(key))->big_value,
5312 *value_len);
5313 break;
5314
5315 case CKA_VALUE:
5316
5317 if (key->key_type == CKK_DSA)
5318 #ifdef __sparcv9
5319 len =
5320 /* LINTED */
5321 (uint32_t)
5322 ((biginteger_t *)OBJ_PUB_DSA_VALUE(key))->
5323 big_value_len;
5324 #else /* !__sparcv9 */
5325 len =
5326 ((biginteger_t *)OBJ_PUB_DSA_VALUE(key))->
5327 big_value_len;
5328 #endif /* __sparcv9 */
5329 else
5330 #ifdef __sparcv9
5331 len =
5332 /* LINTED */
5333 (uint32_t)
5334 ((biginteger_t *)OBJ_PUB_DH_VALUE(key))->
5335 big_value_len;
5336 #else /* !__sparcv9 */
5337 len =
5338 ((biginteger_t *)OBJ_PUB_DH_VALUE(key))->
5339 big_value_len;
5340 #endif /* __sparcv9 */
5341
5342 /* This attribute MUST BE set */
5343 if (len == 0 || len > *value_len) {
5344 return (CKR_ATTRIBUTE_VALUE_INVALID);
5345 }
5346 *value_len = len;
5347
5348 if (key->key_type == CKK_DSA)
5349 (void) memcpy(value,
5350 ((biginteger_t *)OBJ_PUB_DSA_VALUE(key))->big_value,
5351 *value_len);
5352 else
5353 (void) memcpy(value,
5354 ((biginteger_t *)OBJ_PUB_DH_VALUE(key))->big_value,
5355 *value_len);
5356
5357 break;
5358 }
5359
5360 return (CKR_OK);
5361 }
5362
5363
5364 CK_RV
5365 soft_get_private_value(soft_object_t *key, CK_ATTRIBUTE_TYPE type,
5366 uchar_t *value, uint32_t *value_len)
5367 {
5368
5369 uint32_t len = 0;
5370
5371 switch (type) {
5372
5373 /* The following attributes belong to RSA */
5374 case CKA_MODULUS:
5375 #ifdef __sparcv9
5376 len =
5377 /* LINTED */
5378 (uint32_t)
5379 ((biginteger_t *)OBJ_PRI_RSA_MOD(key))->big_value_len;
5380 #else /* !__sparcv9 */
5381 len =
5382 ((biginteger_t *)OBJ_PRI_RSA_MOD(key))->big_value_len;
5383 #endif /* __sparcv9 */
5384
5385 /* This attribute MUST BE set */
5386 if (len == 0 || len > *value_len) {
5387 return (CKR_ATTRIBUTE_VALUE_INVALID);
5388 }
5389 *value_len = len;
5390
5391 (void) memcpy(value,
5392 ((biginteger_t *)OBJ_PRI_RSA_MOD(key))->big_value,
5393 *value_len);
5394
5395 break;
5396
5397 case CKA_PRIVATE_EXPONENT:
5398 #ifdef __sparcv9
5399 len =
5400 /* LINTED */
5401 (uint32_t)
5402 ((biginteger_t *)OBJ_PRI_RSA_PRIEXPO(key))->big_value_len;
5403 #else /* !__sparcv9 */
5404 len =
5405 ((biginteger_t *)OBJ_PRI_RSA_PRIEXPO(key))->big_value_len;
5406 #endif /* __sparcv9 */
5407
5408 /* This attribute MUST BE set */
5409 if (len == 0 || len > *value_len) {
5410 return (CKR_ATTRIBUTE_VALUE_INVALID);
5411 }
5412 *value_len = len;
5413
5414 (void) memcpy(value,
5415 ((biginteger_t *)OBJ_PRI_RSA_PRIEXPO(key))->big_value,
5416 *value_len);
5417
5418 break;
5419
5420 case CKA_PRIME_1:
5421 #ifdef __sparcv9
5422 len =
5423 /* LINTED */
5424 (uint32_t)
5425 ((biginteger_t *)OBJ_PRI_RSA_PRIME1(key))->big_value_len;
5426 #else /* !__sparcv9 */
5427 len =
5428 ((biginteger_t *)OBJ_PRI_RSA_PRIME1(key))->big_value_len;
5429 #endif /* __sparcv9 */
5430
5431 if (len > *value_len) {
5432 return (CKR_ATTRIBUTE_VALUE_INVALID);
5433 }
5434 *value_len = len;
5435
5436 if (*value_len == 0) {
5437 return (CKR_OK);
5438 }
5439
5440 (void) memcpy(value,
5441 ((biginteger_t *)OBJ_PRI_RSA_PRIME1(key))->big_value,
5442 *value_len);
5443
5444 break;
5445
5446 case CKA_PRIME_2:
5447 #ifdef __sparcv9
5448 len =
5449 /* LINTED */
5450 (uint32_t)
5451 ((biginteger_t *)OBJ_PRI_RSA_PRIME2(key))->big_value_len;
5452 #else /* !__sparcv9 */
5453 len =
5454 ((biginteger_t *)OBJ_PRI_RSA_PRIME2(key))->big_value_len;
5455 #endif /* __sparcv9 */
5456
5457 if (len > *value_len) {
5458 return (CKR_ATTRIBUTE_VALUE_INVALID);
5459 }
5460 *value_len = len;
5461
5462 if (*value_len == 0) {
5463 return (CKR_OK);
5464 }
5465
5466 (void) memcpy(value,
5467 ((biginteger_t *)OBJ_PRI_RSA_PRIME2(key))->big_value,
5468 *value_len);
5469
5470 break;
5471
5472 case CKA_EXPONENT_1:
5473 #ifdef __sparcv9
5474 len =
5475 /* LINTED */
5476 (uint32_t)
5477 ((biginteger_t *)OBJ_PRI_RSA_EXPO1(key))->big_value_len;
5478 #else /* !__sparcv9 */
5479 len =
5480 ((biginteger_t *)OBJ_PRI_RSA_EXPO1(key))->big_value_len;
5481 #endif /* __sparcv9 */
5482
5483 if (len > *value_len) {
5484 return (CKR_ATTRIBUTE_VALUE_INVALID);
5485 }
5486 *value_len = len;
5487
5488 if (*value_len == 0) {
5489 return (CKR_OK);
5490 }
5491
5492 (void) memcpy(value,
5493 ((biginteger_t *)OBJ_PRI_RSA_EXPO1(key))->big_value,
5494 *value_len);
5495
5496 break;
5497
5498 case CKA_EXPONENT_2:
5499 #ifdef __sparcv9
5500 len =
5501 /* LINTED */
5502 (uint32_t)
5503 ((biginteger_t *)OBJ_PRI_RSA_EXPO2(key))->big_value_len;
5504 #else /* !__sparcv9 */
5505 len =
5506 ((biginteger_t *)OBJ_PRI_RSA_EXPO2(key))->big_value_len;
5507 #endif /* __sparcv9 */
5508
5509 if (len > *value_len) {
5510 return (CKR_ATTRIBUTE_VALUE_INVALID);
5511 }
5512 *value_len = len;
5513
5514 if (*value_len == 0) {
5515 return (CKR_OK);
5516 }
5517
5518 (void) memcpy(value,
5519 ((biginteger_t *)OBJ_PRI_RSA_EXPO2(key))->big_value,
5520 *value_len);
5521
5522 break;
5523
5524 case CKA_COEFFICIENT:
5525 #ifdef __sparcv9
5526 len =
5527 /* LINTED */
5528 (uint32_t)
5529 ((biginteger_t *)OBJ_PRI_RSA_COEF(key))->big_value_len;
5530 #else /* !__sparcv9 */
5531 len =
5532 ((biginteger_t *)OBJ_PRI_RSA_COEF(key))->big_value_len;
5533 #endif /* __sparcv9 */
5534
5535 if (len > *value_len) {
5536 return (CKR_ATTRIBUTE_VALUE_INVALID);
5537 }
5538 *value_len = len;
5539
5540 if (*value_len == 0) {
5541 return (CKR_OK);
5542 }
5543
5544 (void) memcpy(value,
5545 ((biginteger_t *)OBJ_PRI_RSA_COEF(key))->big_value,
5546 *value_len);
5547
5548 break;
5549
5550 /* The following attributes belong to DSA and DH */
5551 case CKA_PRIME:
5552
5553 if (key->key_type == CKK_DSA)
5554 #ifdef __sparcv9
5555 len =
5556 /* LINTED */
5557 (uint32_t)
5558 ((biginteger_t *)OBJ_PRI_DSA_PRIME(key))->
5559 big_value_len;
5560 #else /* !__sparcv9 */
5561 len =
5562 ((biginteger_t *)OBJ_PRI_DSA_PRIME(key))->
5563 big_value_len;
5564 #endif /* __sparcv9 */
5565 else
5566 #ifdef __sparcv9
5567 len =
5568 /* LINTED */
5569 (uint32_t)
5570 ((biginteger_t *)OBJ_PRI_DH_PRIME(key))->
5571 big_value_len;
5572 #else /* !__sparcv9 */
5573 len =
5574 ((biginteger_t *)OBJ_PRI_DH_PRIME(key))->
5575 big_value_len;
5576 #endif /* __sparcv9 */
5577
5578 /* This attribute MUST BE set */
5579 if (len == 0 || len > *value_len) {
5580 return (CKR_ATTRIBUTE_VALUE_INVALID);
5581 }
5582 *value_len = len;
5583
5584 if (key->key_type == CKK_DSA)
5585 (void) memcpy(value,
5586 ((biginteger_t *)OBJ_PRI_DSA_PRIME(key))->big_value,
5587 *value_len);
5588 else
5589 (void) memcpy(value,
5590 ((biginteger_t *)OBJ_PRI_DH_PRIME(key))->big_value,
5591 *value_len);
5592
5593 break;
5594
5595 case CKA_SUBPRIME:
5596 #ifdef __sparcv9
5597 len =
5598 /* LINTED */
5599 (uint32_t)
5600 ((biginteger_t *)OBJ_PRI_DSA_SUBPRIME(key))->big_value_len;
5601 #else /* !__sparcv9 */
5602 len =
5603 ((biginteger_t *)OBJ_PRI_DSA_SUBPRIME(key))->big_value_len;
5604 #endif /* __sparcv9 */
5605
5606 /* This attribute MUST BE set */
5607 if (len == 0 || len > *value_len) {
5608 return (CKR_ATTRIBUTE_VALUE_INVALID);
5609 }
5610 *value_len = len;
5611
5612 (void) memcpy(value,
5613 ((biginteger_t *)OBJ_PRI_DSA_SUBPRIME(key))->big_value,
5614 *value_len);
5615
5616 break;
5617
5618 case CKA_BASE:
5619
5620 if (key->key_type == CKK_DSA)
5621 #ifdef __sparcv9
5622 len =
5623 /* LINTED */
5624 (uint32_t)
5625 ((biginteger_t *)OBJ_PRI_DSA_BASE(key))->
5626 big_value_len;
5627 #else /* !__sparcv9 */
5628 len =
5629 ((biginteger_t *)OBJ_PRI_DSA_BASE(key))->
5630 big_value_len;
5631 #endif /* __sparcv9 */
5632 else
5633 #ifdef __sparcv9
5634 len =
5635 /* LINTED */
5636 (uint32_t)
5637 ((biginteger_t *)OBJ_PRI_DH_BASE(key))->
5638 big_value_len;
5639 #else /* !__sparcv9 */
5640 len =
5641 ((biginteger_t *)OBJ_PRI_DH_BASE(key))->
5642 big_value_len;
5643 #endif /* __sparcv9 */
5644
5645 /* This attribute MUST BE set */
5646 if (len == 0 || len > *value_len) {
5647 return (CKR_ATTRIBUTE_VALUE_INVALID);
5648 }
5649 *value_len = len;
5650
5651 if (key->key_type == CKK_DSA)
5652 (void) memcpy(value,
5653 ((biginteger_t *)OBJ_PRI_DSA_BASE(key))->big_value,
5654 *value_len);
5655 else
5656 (void) memcpy(value,
5657 ((biginteger_t *)OBJ_PRI_DH_BASE(key))->big_value,
5658 *value_len);
5659 break;
5660
5661 case CKA_VALUE:
5662
5663 if (key->key_type == CKK_DSA) {
5664 #ifdef __sparcv9
5665 len =
5666 /* LINTED */
5667 (uint32_t)
5668 ((biginteger_t *)OBJ_PRI_DSA_VALUE(key))->
5669 big_value_len;
5670 #else /* !__sparcv9 */
5671 len =
5672 ((biginteger_t *)OBJ_PRI_DSA_VALUE(key))->
5673 big_value_len;
5674 #endif /* __sparcv9 */
5675 } else if (key->key_type == CKK_DH) {
5676 #ifdef __sparcv9
5677 len =
5678 /* LINTED */
5679 (uint32_t)
5680 ((biginteger_t *)OBJ_PRI_DH_VALUE(key))->
5681 big_value_len;
5682 #else /* !__sparcv9 */
5683 len =
5684 ((biginteger_t *)OBJ_PRI_DH_VALUE(key))->
5685 big_value_len;
5686 #endif /* __sparcv9 */
5687 } else {
5688 #ifdef __sparcv9
5689 len =
5690 /* LINTED */
5691 (uint32_t)
5692 ((biginteger_t *)OBJ_PRI_EC_VALUE(key))->
5693 big_value_len;
5694 #else /* !__sparcv9 */
5695 len =
5696 ((biginteger_t *)OBJ_PRI_EC_VALUE(key))->
5697 big_value_len;
5698 #endif /* __sparcv9 */
5699 }
5700
5701 /* This attribute MUST BE set */
5702 if (len == 0 || len > *value_len) {
5703 return (CKR_ATTRIBUTE_VALUE_INVALID);
5704 }
5705 *value_len = len;
5706
5707 if (key->key_type == CKK_DSA) {
5708 (void) memcpy(value,
5709 ((biginteger_t *)OBJ_PRI_DSA_VALUE(key))->big_value,
5710 *value_len);
5711 } else if (key->key_type == CKK_DH) {
5712 (void) memcpy(value,
5713 ((biginteger_t *)OBJ_PRI_DH_VALUE(key))->big_value,
5714 *value_len);
5715 } else {
5716 (void) memcpy(value,
5717 ((biginteger_t *)OBJ_PRI_EC_VALUE(key))->big_value,
5718 *value_len);
5719 }
5720
5721 break;
5722 }
5723
5724 return (CKR_OK);
5725
5726 }
5727
5728 static CK_RV
5729 copy_bigint(biginteger_t *new_bigint, biginteger_t *old_bigint)
5730 {
5731 new_bigint->big_value =
5732 malloc((sizeof (CK_BYTE) * new_bigint->big_value_len));
5733
5734 if (new_bigint->big_value == NULL) {
5735 return (CKR_HOST_MEMORY);
5736 }
5737
5738 (void) memcpy(new_bigint->big_value, old_bigint->big_value,
5739 (sizeof (CK_BYTE) * new_bigint->big_value_len));
5740
5741 return (CKR_OK);
5742 }
5743
5744 static void
5745 free_public_key_attr(public_key_obj_t *pbk, CK_KEY_TYPE key_type)
5746 {
5747 if (pbk == NULL) {
5748 return;
5749 }
5750
5751 switch (key_type) {
5752 case CKK_RSA:
5753 bigint_attr_cleanup(KEY_PUB_RSA_MOD(pbk));
5754 bigint_attr_cleanup(KEY_PUB_RSA_PUBEXPO(pbk));
5755 break;
5756 case CKK_DSA:
5757 bigint_attr_cleanup(KEY_PUB_DSA_PRIME(pbk));
5758 bigint_attr_cleanup(KEY_PUB_DSA_SUBPRIME(pbk));
5759 bigint_attr_cleanup(KEY_PUB_DSA_BASE(pbk));
5760 bigint_attr_cleanup(KEY_PUB_DSA_VALUE(pbk));
5761 break;
5762 case CKK_DH:
5763 bigint_attr_cleanup(KEY_PUB_DH_PRIME(pbk));
5764 bigint_attr_cleanup(KEY_PUB_DH_BASE(pbk));
5765 bigint_attr_cleanup(KEY_PUB_DH_VALUE(pbk));
5766 break;
5767 case CKK_EC:
5768 bigint_attr_cleanup(KEY_PUB_EC_POINT(pbk));
5769 break;
5770 case CKK_X9_42_DH:
5771 bigint_attr_cleanup(KEY_PUB_DH942_PRIME(pbk));
5772 bigint_attr_cleanup(KEY_PUB_DH942_SUBPRIME(pbk));
5773 bigint_attr_cleanup(KEY_PUB_DH942_BASE(pbk));
5774 bigint_attr_cleanup(KEY_PUB_DH942_VALUE(pbk));
5775 break;
5776 default:
5777 break;
5778 }
5779 free(pbk);
5780 }
5781
5782 CK_RV
5783 soft_copy_public_key_attr(public_key_obj_t *old_pub_key_obj_p,
5784 public_key_obj_t **new_pub_key_obj_p, CK_KEY_TYPE key_type)
5785 {
5786
5787 public_key_obj_t *pbk;
5788 CK_RV rv = CKR_OK;
5789
5790 pbk = calloc(1, sizeof (public_key_obj_t));
5791 if (pbk == NULL) {
5792 return (CKR_HOST_MEMORY);
5793 }
5794
5795 switch (key_type) {
5796 case CKK_RSA:
5797 (void) memcpy(KEY_PUB_RSA(pbk),
5798 KEY_PUB_RSA(old_pub_key_obj_p),
5799 sizeof (rsa_pub_key_t));
5800 /* copy modulus */
5801 rv = copy_bigint(KEY_PUB_RSA_MOD(pbk),
5802 KEY_PUB_RSA_MOD(old_pub_key_obj_p));
5803 if (rv != CKR_OK) {
5804 free_public_key_attr(pbk, key_type);
5805 return (rv);
5806 }
5807 /* copy public exponent */
5808 rv = copy_bigint(KEY_PUB_RSA_PUBEXPO(pbk),
5809 KEY_PUB_RSA_PUBEXPO(old_pub_key_obj_p));
5810 if (rv != CKR_OK) {
5811 free_public_key_attr(pbk, key_type);
5812 return (rv);
5813 }
5814 break;
5815 case CKK_DSA:
5816 (void) memcpy(KEY_PUB_DSA(pbk),
5817 KEY_PUB_DSA(old_pub_key_obj_p),
5818 sizeof (dsa_pub_key_t));
5819
5820 /* copy prime */
5821 rv = copy_bigint(KEY_PUB_DSA_PRIME(pbk),
5822 KEY_PUB_DSA_PRIME(old_pub_key_obj_p));
5823 if (rv != CKR_OK) {
5824 free_public_key_attr(pbk, key_type);
5825 return (rv);
5826 }
5827
5828 /* copy subprime */
5829 rv = copy_bigint(KEY_PUB_DSA_SUBPRIME(pbk),
5830 KEY_PUB_DSA_SUBPRIME(old_pub_key_obj_p));
5831 if (rv != CKR_OK) {
5832 free_public_key_attr(pbk, key_type);
5833 return (rv);
5834 }
5835
5836 /* copy base */
5837 rv = copy_bigint(KEY_PUB_DSA_BASE(pbk),
5838 KEY_PUB_DSA_BASE(old_pub_key_obj_p));
5839 if (rv != CKR_OK) {
5840 free_public_key_attr(pbk, key_type);
5841 return (rv);
5842 }
5843
5844 /* copy value */
5845 rv = copy_bigint(KEY_PUB_DSA_VALUE(pbk),
5846 KEY_PUB_DSA_VALUE(old_pub_key_obj_p));
5847 if (rv != CKR_OK) {
5848 free_public_key_attr(pbk, key_type);
5849 return (rv);
5850 }
5851 break;
5852 case CKK_DH:
5853 (void) memcpy(KEY_PUB_DH(pbk),
5854 KEY_PUB_DH(old_pub_key_obj_p),
5855 sizeof (dh_pub_key_t));
5856
5857 /* copy prime */
5858 rv = copy_bigint(KEY_PUB_DH_PRIME(pbk),
5859 KEY_PUB_DH_PRIME(old_pub_key_obj_p));
5860 if (rv != CKR_OK) {
5861 free_public_key_attr(pbk, key_type);
5862 return (rv);
5863 }
5864
5865 /* copy base */
5866 rv = copy_bigint(KEY_PUB_DH_BASE(pbk),
5867 KEY_PUB_DH_BASE(old_pub_key_obj_p));
5868 if (rv != CKR_OK) {
5869 free_public_key_attr(pbk, key_type);
5870 return (rv);
5871 }
5872
5873 /* copy value */
5874 rv = copy_bigint(KEY_PUB_DH_VALUE(pbk),
5875 KEY_PUB_DH_VALUE(old_pub_key_obj_p));
5876 if (rv != CKR_OK) {
5877 free_public_key_attr(pbk, key_type);
5878 return (rv);
5879 }
5880 break;
5881 case CKK_EC:
5882 (void) memcpy(KEY_PUB_EC(pbk),
5883 KEY_PUB_EC(old_pub_key_obj_p),
5884 sizeof (ec_pub_key_t));
5885
5886 /* copy point */
5887 rv = copy_bigint(KEY_PUB_EC_POINT(pbk),
5888 KEY_PUB_EC_POINT(old_pub_key_obj_p));
5889 if (rv != CKR_OK) {
5890 free_public_key_attr(pbk, key_type);
5891 return (rv);
5892 }
5893 break;
5894 case CKK_X9_42_DH:
5895 (void) memcpy(KEY_PUB_DH942(pbk),
5896 KEY_PUB_DH942(old_pub_key_obj_p),
5897 sizeof (dh942_pub_key_t));
5898
5899 /* copy prime */
5900 rv = copy_bigint(KEY_PUB_DH942_PRIME(pbk),
5901 KEY_PUB_DH942_PRIME(old_pub_key_obj_p));
5902 if (rv != CKR_OK) {
5903 free_public_key_attr(pbk, key_type);
5904 return (rv);
5905 }
5906
5907 /* copy subprime */
5908 rv = copy_bigint(KEY_PUB_DH942_SUBPRIME(pbk),
5909 KEY_PUB_DH942_SUBPRIME(old_pub_key_obj_p));
5910 if (rv != CKR_OK) {
5911 free_public_key_attr(pbk, key_type);
5912 return (rv);
5913 }
5914
5915 /* copy base */
5916 rv = copy_bigint(KEY_PUB_DH942_BASE(pbk),
5917 KEY_PUB_DH942_BASE(old_pub_key_obj_p));
5918 if (rv != CKR_OK) {
5919 free_public_key_attr(pbk, key_type);
5920 return (rv);
5921 }
5922
5923 /* copy value */
5924 rv = copy_bigint(KEY_PUB_DH942_VALUE(pbk),
5925 KEY_PUB_DH942_VALUE(old_pub_key_obj_p));
5926 if (rv != CKR_OK) {
5927 free_public_key_attr(pbk, key_type);
5928 return (rv);
5929 }
5930 break;
5931 default:
5932 break;
5933 }
5934 *new_pub_key_obj_p = pbk;
5935 return (rv);
5936 }
5937
5938 static void
5939 free_private_key_attr(private_key_obj_t *pbk, CK_KEY_TYPE key_type)
5940 {
5941 if (pbk == NULL) {
5942 return;
5943 }
5944
5945 switch (key_type) {
5946 case CKK_RSA:
5947 bigint_attr_cleanup(KEY_PRI_RSA_MOD(pbk));
5948 bigint_attr_cleanup(KEY_PRI_RSA_PUBEXPO(pbk));
5949 bigint_attr_cleanup(KEY_PRI_RSA_PRIEXPO(pbk));
5950 bigint_attr_cleanup(KEY_PRI_RSA_PRIME1(pbk));
5951 bigint_attr_cleanup(KEY_PRI_RSA_PRIME2(pbk));
5952 bigint_attr_cleanup(KEY_PRI_RSA_EXPO1(pbk));
5953 bigint_attr_cleanup(KEY_PRI_RSA_EXPO2(pbk));
5954 bigint_attr_cleanup(KEY_PRI_RSA_COEF(pbk));
5955 break;
5956 case CKK_DSA:
5957 bigint_attr_cleanup(KEY_PRI_DSA_PRIME(pbk));
5958 bigint_attr_cleanup(KEY_PRI_DSA_SUBPRIME(pbk));
5959 bigint_attr_cleanup(KEY_PRI_DSA_BASE(pbk));
5960 bigint_attr_cleanup(KEY_PRI_DSA_VALUE(pbk));
5961 break;
5962 case CKK_DH:
5963 bigint_attr_cleanup(KEY_PRI_DH_PRIME(pbk));
5964 bigint_attr_cleanup(KEY_PRI_DH_BASE(pbk));
5965 bigint_attr_cleanup(KEY_PRI_DH_VALUE(pbk));
5966 break;
5967 case CKK_EC:
5968 bigint_attr_cleanup(KEY_PRI_EC_VALUE(pbk));
5969 break;
5970 case CKK_X9_42_DH:
5971 bigint_attr_cleanup(KEY_PRI_DH942_PRIME(pbk));
5972 bigint_attr_cleanup(KEY_PRI_DH942_SUBPRIME(pbk));
5973 bigint_attr_cleanup(KEY_PRI_DH942_BASE(pbk));
5974 bigint_attr_cleanup(KEY_PRI_DH942_VALUE(pbk));
5975 break;
5976 default:
5977 break;
5978 }
5979 free(pbk);
5980 }
5981
5982 CK_RV
5983 soft_copy_private_key_attr(private_key_obj_t *old_pri_key_obj_p,
5984 private_key_obj_t **new_pri_key_obj_p, CK_KEY_TYPE key_type)
5985 {
5986 CK_RV rv = CKR_OK;
5987 private_key_obj_t *pbk;
5988
5989 pbk = calloc(1, sizeof (private_key_obj_t));
5990 if (pbk == NULL) {
5991 return (CKR_HOST_MEMORY);
5992 }
5993
5994 switch (key_type) {
5995 case CKK_RSA:
5996 (void) memcpy(KEY_PRI_RSA(pbk),
5997 KEY_PRI_RSA(old_pri_key_obj_p),
5998 sizeof (rsa_pri_key_t));
5999 /* copy modulus */
6000 rv = copy_bigint(KEY_PRI_RSA_MOD(pbk),
6001 KEY_PRI_RSA_MOD(old_pri_key_obj_p));
6002 if (rv != CKR_OK) {
6003 free_private_key_attr(pbk, key_type);
6004 return (rv);
6005 }
6006 /* copy public exponent */
6007 rv = copy_bigint(KEY_PRI_RSA_PUBEXPO(pbk),
6008 KEY_PRI_RSA_PUBEXPO(old_pri_key_obj_p));
6009 if (rv != CKR_OK) {
6010 free_private_key_attr(pbk, key_type);
6011 return (rv);
6012 }
6013 /* copy private exponent */
6014 rv = copy_bigint(KEY_PRI_RSA_PRIEXPO(pbk),
6015 KEY_PRI_RSA_PRIEXPO(old_pri_key_obj_p));
6016 if (rv != CKR_OK) {
6017 free_private_key_attr(pbk, key_type);
6018 return (rv);
6019 }
6020 /* copy prime_1 */
6021 rv = copy_bigint(KEY_PRI_RSA_PRIME1(pbk),
6022 KEY_PRI_RSA_PRIME1(old_pri_key_obj_p));
6023 if (rv != CKR_OK) {
6024 free_private_key_attr(pbk, key_type);
6025 return (rv);
6026 }
6027 /* copy prime_2 */
6028 rv = copy_bigint(KEY_PRI_RSA_PRIME2(pbk),
6029 KEY_PRI_RSA_PRIME2(old_pri_key_obj_p));
6030 if (rv != CKR_OK) {
6031 free_private_key_attr(pbk, key_type);
6032 return (rv);
6033 }
6034 /* copy exponent_1 */
6035 rv = copy_bigint(KEY_PRI_RSA_EXPO1(pbk),
6036 KEY_PRI_RSA_EXPO1(old_pri_key_obj_p));
6037 if (rv != CKR_OK) {
6038 free_private_key_attr(pbk, key_type);
6039 return (rv);
6040 }
6041 /* copy exponent_2 */
6042 rv = copy_bigint(KEY_PRI_RSA_EXPO2(pbk),
6043 KEY_PRI_RSA_EXPO2(old_pri_key_obj_p));
6044 if (rv != CKR_OK) {
6045 free_private_key_attr(pbk, key_type);
6046 return (rv);
6047 }
6048 /* copy coefficient */
6049 rv = copy_bigint(KEY_PRI_RSA_COEF(pbk),
6050 KEY_PRI_RSA_COEF(old_pri_key_obj_p));
6051 if (rv != CKR_OK) {
6052 free_private_key_attr(pbk, key_type);
6053 return (rv);
6054 }
6055 break;
6056 case CKK_DSA:
6057 (void) memcpy(KEY_PRI_DSA(pbk),
6058 KEY_PRI_DSA(old_pri_key_obj_p),
6059 sizeof (dsa_pri_key_t));
6060
6061 /* copy prime */
6062 rv = copy_bigint(KEY_PRI_DSA_PRIME(pbk),
6063 KEY_PRI_DSA_PRIME(old_pri_key_obj_p));
6064 if (rv != CKR_OK) {
6065 free_private_key_attr(pbk, key_type);
6066 return (rv);
6067 }
6068
6069 /* copy subprime */
6070 rv = copy_bigint(KEY_PRI_DSA_SUBPRIME(pbk),
6071 KEY_PRI_DSA_SUBPRIME(old_pri_key_obj_p));
6072 if (rv != CKR_OK) {
6073 free_private_key_attr(pbk, key_type);
6074 return (rv);
6075 }
6076
6077 /* copy base */
6078 rv = copy_bigint(KEY_PRI_DSA_BASE(pbk),
6079 KEY_PRI_DSA_BASE(old_pri_key_obj_p));
6080 if (rv != CKR_OK) {
6081 free_private_key_attr(pbk, key_type);
6082 return (rv);
6083 }
6084
6085 /* copy value */
6086 rv = copy_bigint(KEY_PRI_DSA_VALUE(pbk),
6087 KEY_PRI_DSA_VALUE(old_pri_key_obj_p));
6088 if (rv != CKR_OK) {
6089 free_private_key_attr(pbk, key_type);
6090 return (rv);
6091 }
6092 break;
6093 case CKK_DH:
6094 (void) memcpy(KEY_PRI_DH(pbk),
6095 KEY_PRI_DH(old_pri_key_obj_p),
6096 sizeof (dh_pri_key_t));
6097
6098 /* copy prime */
6099 rv = copy_bigint(KEY_PRI_DH_PRIME(pbk),
6100 KEY_PRI_DH_PRIME(old_pri_key_obj_p));
6101 if (rv != CKR_OK) {
6102 free_private_key_attr(pbk, key_type);
6103 return (rv);
6104 }
6105
6106 /* copy base */
6107 rv = copy_bigint(KEY_PRI_DH_BASE(pbk),
6108 KEY_PRI_DH_BASE(old_pri_key_obj_p));
6109 if (rv != CKR_OK) {
6110 free_private_key_attr(pbk, key_type);
6111 return (rv);
6112 }
6113
6114 /* copy value */
6115 rv = copy_bigint(KEY_PRI_DH_VALUE(pbk),
6116 KEY_PRI_DH_VALUE(old_pri_key_obj_p));
6117 if (rv != CKR_OK) {
6118 free_private_key_attr(pbk, key_type);
6119 return (rv);
6120 }
6121 break;
6122 case CKK_EC:
6123 (void) memcpy(KEY_PRI_EC(pbk),
6124 KEY_PRI_EC(old_pri_key_obj_p),
6125 sizeof (ec_pri_key_t));
6126
6127 /* copy value */
6128 rv = copy_bigint(KEY_PRI_EC_VALUE(pbk),
6129 KEY_PRI_EC_VALUE(old_pri_key_obj_p));
6130 if (rv != CKR_OK) {
6131 free_private_key_attr(pbk, key_type);
6132 return (rv);
6133 }
6134 break;
6135 case CKK_X9_42_DH:
6136 (void) memcpy(KEY_PRI_DH942(pbk),
6137 KEY_PRI_DH942(old_pri_key_obj_p),
6138 sizeof (dh942_pri_key_t));
6139
6140 /* copy prime */
6141 rv = copy_bigint(KEY_PRI_DH942_PRIME(pbk),
6142 KEY_PRI_DH942_PRIME(old_pri_key_obj_p));
6143 if (rv != CKR_OK) {
6144 free_private_key_attr(pbk, key_type);
6145 return (rv);
6146 }
6147
6148 /* copy subprime */
6149 rv = copy_bigint(KEY_PRI_DH942_SUBPRIME(pbk),
6150 KEY_PRI_DH942_SUBPRIME(old_pri_key_obj_p));
6151 if (rv != CKR_OK) {
6152 free_private_key_attr(pbk, key_type);
6153 return (rv);
6154 }
6155
6156 /* copy base */
6157 rv = copy_bigint(KEY_PRI_DH942_BASE(pbk),
6158 KEY_PRI_DH942_BASE(old_pri_key_obj_p));
6159 if (rv != CKR_OK) {
6160 free_private_key_attr(pbk, key_type);
6161 return (rv);
6162 }
6163
6164 /* copy value */
6165 rv = copy_bigint(KEY_PRI_DH942_VALUE(pbk),
6166 KEY_PRI_DH942_VALUE(old_pri_key_obj_p));
6167 if (rv != CKR_OK) {
6168 free_private_key_attr(pbk, key_type);
6169 return (rv);
6170 }
6171 break;
6172 default:
6173 break;
6174 }
6175 *new_pri_key_obj_p = pbk;
6176 return (rv);
6177 }
6178
6179 static void
6180 free_domain_attr(domain_obj_t *domain, CK_KEY_TYPE key_type)
6181 {
6182 if (domain == NULL) {
6183 return;
6184 }
6185
6186 switch (key_type) {
6187 case CKK_DSA:
6188 bigint_attr_cleanup(KEY_DOM_DSA_PRIME(domain));
6189 bigint_attr_cleanup(KEY_DOM_DSA_SUBPRIME(domain));
6190 bigint_attr_cleanup(KEY_DOM_DSA_BASE(domain));
6191 break;
6192 case CKK_DH:
6193 bigint_attr_cleanup(KEY_DOM_DH_PRIME(domain));
6194 bigint_attr_cleanup(KEY_DOM_DH_BASE(domain));
6195 break;
6196 case CKK_X9_42_DH:
6197 bigint_attr_cleanup(KEY_DOM_DH942_PRIME(domain));
6198 bigint_attr_cleanup(KEY_DOM_DH942_SUBPRIME(domain));
6199 bigint_attr_cleanup(KEY_DOM_DH942_BASE(domain));
6200 break;
6201 default:
6202 break;
6203 }
6204 free(domain);
6205 }
6206
6207 CK_RV
6208 soft_copy_domain_attr(domain_obj_t *old_domain_obj_p,
6209 domain_obj_t **new_domain_obj_p, CK_KEY_TYPE key_type)
6210 {
6211 CK_RV rv = CKR_OK;
6212 domain_obj_t *domain;
6213
6214 domain = calloc(1, sizeof (domain_obj_t));
6215 if (domain == NULL) {
6216 return (CKR_HOST_MEMORY);
6217 }
6218
6219 switch (key_type) {
6220 case CKK_DSA:
6221 (void) memcpy(KEY_DOM_DSA(domain),
6222 KEY_DOM_DSA(old_domain_obj_p),
6223 sizeof (dsa_dom_key_t));
6224
6225 /* copy prime */
6226 rv = copy_bigint(KEY_DOM_DSA_PRIME(domain),
6227 KEY_DOM_DSA_PRIME(old_domain_obj_p));
6228 if (rv != CKR_OK) {
6229 free_domain_attr(domain, key_type);
6230 return (rv);
6231 }
6232
6233 /* copy subprime */
6234 rv = copy_bigint(KEY_DOM_DSA_SUBPRIME(domain),
6235 KEY_DOM_DSA_SUBPRIME(old_domain_obj_p));
6236 if (rv != CKR_OK) {
6237 free_domain_attr(domain, key_type);
6238 return (rv);
6239 }
6240
6241 /* copy base */
6242 rv = copy_bigint(KEY_DOM_DSA_BASE(domain),
6243 KEY_DOM_DSA_BASE(old_domain_obj_p));
6244 if (rv != CKR_OK) {
6245 free_domain_attr(domain, key_type);
6246 return (rv);
6247 }
6248
6249 break;
6250 case CKK_DH:
6251 (void) memcpy(KEY_DOM_DH(domain),
6252 KEY_DOM_DH(old_domain_obj_p),
6253 sizeof (dh_dom_key_t));
6254
6255 /* copy prime */
6256 rv = copy_bigint(KEY_DOM_DH_PRIME(domain),
6257 KEY_DOM_DH_PRIME(old_domain_obj_p));
6258 if (rv != CKR_OK) {
6259 free_domain_attr(domain, key_type);
6260 return (rv);
6261 }
6262
6263 /* copy base */
6264 rv = copy_bigint(KEY_DOM_DH_BASE(domain),
6265 KEY_DOM_DH_BASE(old_domain_obj_p));
6266 if (rv != CKR_OK) {
6267 free_domain_attr(domain, key_type);
6268 return (rv);
6269 }
6270
6271 break;
6272 case CKK_X9_42_DH:
6273 (void) memcpy(KEY_DOM_DH942(domain),
6274 KEY_DOM_DH942(old_domain_obj_p),
6275 sizeof (dh942_dom_key_t));
6276
6277 /* copy prime */
6278 rv = copy_bigint(KEY_DOM_DH942_PRIME(domain),
6279 KEY_DOM_DH942_PRIME(old_domain_obj_p));
6280 if (rv != CKR_OK) {
6281 free_domain_attr(domain, key_type);
6282 return (rv);
6283 }
6284
6285 /* copy subprime */
6286 rv = copy_bigint(KEY_DOM_DH942_SUBPRIME(domain),
6287 KEY_DOM_DH942_SUBPRIME(old_domain_obj_p));
6288 if (rv != CKR_OK) {
6289 free_domain_attr(domain, key_type);
6290 return (rv);
6291 }
6292
6293 /* copy base */
6294 rv = copy_bigint(KEY_DOM_DH942_BASE(domain),
6295 KEY_DOM_DH942_BASE(old_domain_obj_p));
6296 if (rv != CKR_OK) {
6297 free_domain_attr(domain, key_type);
6298 return (rv);
6299 }
6300
6301 break;
6302 default:
6303 break;
6304 }
6305 *new_domain_obj_p = domain;
6306 return (rv);
6307 }
6308
6309 CK_RV
6310 soft_copy_secret_key_attr(secret_key_obj_t *old_secret_key_obj_p,
6311 secret_key_obj_t **new_secret_key_obj_p)
6312 {
6313 secret_key_obj_t *sk;
6314
6315 sk = malloc(sizeof (secret_key_obj_t));
6316 if (sk == NULL) {
6317 return (CKR_HOST_MEMORY);
6318 }
6319 (void) memcpy(sk, old_secret_key_obj_p, sizeof (secret_key_obj_t));
6320
6321 /* copy the secret key value */
6322 sk->sk_value = malloc((sizeof (CK_BYTE) * sk->sk_value_len));
6323 if (sk->sk_value == NULL) {
6324 free(sk);
6325 return (CKR_HOST_MEMORY);
6326 }
6327 (void) memcpy(sk->sk_value, old_secret_key_obj_p->sk_value,
6328 (sizeof (CK_BYTE) * sk->sk_value_len));
6329
6330 /*
6331 * Copy the pre-expanded key schedule.
6332 */
6333 if (old_secret_key_obj_p->key_sched != NULL &&
6334 old_secret_key_obj_p->keysched_len > 0) {
6335 sk->key_sched = malloc(old_secret_key_obj_p->keysched_len);
6336 if (sk->key_sched == NULL) {
6337 free(sk);
6338 return (CKR_HOST_MEMORY);
6339 }
6340 sk->keysched_len = old_secret_key_obj_p->keysched_len;
6341 (void) memcpy(sk->key_sched, old_secret_key_obj_p->key_sched,
6342 sk->keysched_len);
6343 }
6344
6345 *new_secret_key_obj_p = sk;
6346
6347 return (CKR_OK);
6348 }
6349
6350 /*
6351 * If CKA_CLASS not given, guess CKA_CLASS using
6352 * attributes on template .
6353 *
6354 * Some attributes are specific to an object class. If one or more
6355 * of these attributes are in the template, make a list of classes
6356 * that can have these attributes. This would speed up the search later,
6357 * because we can immediately skip an object if the class of that
6358 * object can not possibly contain one of the attributes.
6359 *
6360 */
6361 void
6362 soft_process_find_attr(CK_OBJECT_CLASS *pclasses,
6363 CK_ULONG *num_result_pclasses, CK_ATTRIBUTE_PTR pTemplate,
6364 CK_ULONG ulCount)
6365 {
6366 ulong_t i;
6367 int j;
6368 boolean_t pub_found = B_FALSE,
6369 priv_found = B_FALSE,
6370 secret_found = B_FALSE,
6371 domain_found = B_FALSE,
6372 hardware_found = B_FALSE,
6373 cert_found = B_FALSE;
6374 int num_pub_key_attrs, num_priv_key_attrs,
6375 num_secret_key_attrs, num_domain_attrs,
6376 num_hardware_attrs, num_cert_attrs;
6377 int num_pclasses = 0;
6378
6379 for (i = 0; i < ulCount; i++) {
6380 if (pTemplate[i].type == CKA_CLASS) {
6381 /*
6382 * don't need to guess the class, it is specified.
6383 * Just record the class, and return.
6384 */
6385 pclasses[0] =
6386 (*((CK_OBJECT_CLASS *)pTemplate[i].pValue));
6387 *num_result_pclasses = 1;
6388 return;
6389 }
6390 }
6391
6392 num_pub_key_attrs =
6393 sizeof (PUB_KEY_ATTRS) / sizeof (CK_ATTRIBUTE_TYPE);
6394 num_priv_key_attrs =
6395 sizeof (PRIV_KEY_ATTRS) / sizeof (CK_ATTRIBUTE_TYPE);
6396 num_secret_key_attrs =
6397 sizeof (SECRET_KEY_ATTRS) / sizeof (CK_ATTRIBUTE_TYPE);
6398 num_domain_attrs =
6399 sizeof (DOMAIN_ATTRS) / sizeof (CK_ATTRIBUTE_TYPE);
6400 num_hardware_attrs =
6401 sizeof (HARDWARE_ATTRS) / sizeof (CK_ATTRIBUTE_TYPE);
6402 num_cert_attrs =
6403 sizeof (CERT_ATTRS) / sizeof (CK_ATTRIBUTE_TYPE);
6404
6405 /*
6406 * Get the list of objects class that might contain
6407 * some attributes.
6408 */
6409 for (i = 0; i < ulCount; i++) {
6410 /*
6411 * only check if this attribute can belong to public key object
6412 * class if public key object isn't already in the list
6413 */
6414 if (!pub_found) {
6415 for (j = 0; j < num_pub_key_attrs; j++) {
6416 if (pTemplate[i].type == PUB_KEY_ATTRS[j]) {
6417 pub_found = B_TRUE;
6418 pclasses[num_pclasses++] =
6419 CKO_PUBLIC_KEY;
6420 break;
6421 }
6422 }
6423 }
6424
6425 if (!priv_found) {
6426 for (j = 0; j < num_priv_key_attrs; j++) {
6427 if (pTemplate[i].type == PRIV_KEY_ATTRS[j]) {
6428 priv_found = B_TRUE;
6429 pclasses[num_pclasses++] =
6430 CKO_PRIVATE_KEY;
6431 break;
6432 }
6433 }
6434 }
6435
6436 if (!secret_found) {
6437 for (j = 0; j < num_secret_key_attrs; j++) {
6438 if (pTemplate[i].type == SECRET_KEY_ATTRS[j]) {
6439 secret_found = B_TRUE;
6440 pclasses[num_pclasses++] =
6441 CKO_SECRET_KEY;
6442 break;
6443 }
6444 }
6445 }
6446
6447 if (!domain_found) {
6448 for (j = 0; j < num_domain_attrs; j++) {
6449 if (pTemplate[i].type == DOMAIN_ATTRS[j]) {
6450 domain_found = B_TRUE;
6451 pclasses[num_pclasses++] =
6452 CKO_DOMAIN_PARAMETERS;
6453 break;
6454 }
6455 }
6456 }
6457
6458 if (!hardware_found) {
6459 for (j = 0; j < num_hardware_attrs; j++) {
6460 if (pTemplate[i].type == HARDWARE_ATTRS[j]) {
6461 hardware_found = B_TRUE;
6462 pclasses[num_pclasses++] =
6463 CKO_HW_FEATURE;
6464 break;
6465 }
6466 }
6467 }
6468
6469 if (!cert_found) {
6470 for (j = 0; j < num_cert_attrs; j++) {
6471 if (pTemplate[i].type == CERT_ATTRS[j]) {
6472 cert_found = B_TRUE;
6473 pclasses[num_pclasses++] =
6474 CKO_CERTIFICATE;
6475 break;
6476 }
6477 }
6478 }
6479 }
6480 *num_result_pclasses = num_pclasses;
6481 }
6482
6483 boolean_t
6484 soft_find_match_attrs(soft_object_t *obj, CK_OBJECT_CLASS *pclasses,
6485 CK_ULONG num_pclasses, CK_ATTRIBUTE *template, CK_ULONG num_attr)
6486 {
6487 ulong_t i;
6488 CK_ATTRIBUTE *tmpl_attr, *obj_attr;
6489 cert_attr_t *cert_attr;
6490 uint64_t attr_mask;
6491 biginteger_t *bigint;
6492 boolean_t compare_attr, compare_bigint, compare_boolean;
6493 boolean_t compare_cert_val, compare_cert_type;
6494
6495 /*
6496 * Check if the class of this object match with any
6497 * of object classes that can possibly contain the
6498 * requested attributes.
6499 */
6500 if (num_pclasses > 0) {
6501 for (i = 0; i < num_pclasses; i++) {
6502 if (obj->class == pclasses[i]) {
6503 break;
6504 }
6505 }
6506 if (i == num_pclasses) {
6507 /*
6508 * this object can't possibly contain one or
6509 * more attributes, don't need to check this object
6510 */
6511 return (B_FALSE);
6512 }
6513 }
6514
6515 /* need to examine everything */
6516 for (i = 0; i < num_attr; i++) {
6517 tmpl_attr = &(template[i]);
6518 compare_attr = B_FALSE;
6519 compare_bigint = B_FALSE;
6520 compare_boolean = B_FALSE;
6521 compare_cert_val = B_FALSE;
6522 compare_cert_type = B_FALSE;
6523 switch (tmpl_attr->type) {
6524 /* First, check the most common attributes */
6525 case CKA_CLASS:
6526 if (*((CK_OBJECT_CLASS *)tmpl_attr->pValue) !=
6527 obj->class) {
6528 return (B_FALSE);
6529 }
6530 break;
6531 case CKA_KEY_TYPE:
6532 if (*((CK_KEY_TYPE *)tmpl_attr->pValue) !=
6533 obj->key_type) {
6534 return (B_FALSE);
6535 }
6536 break;
6537 case CKA_ENCRYPT:
6538 attr_mask = (obj->bool_attr_mask) & ENCRYPT_BOOL_ON;
6539 compare_boolean = B_TRUE;
6540 break;
6541 case CKA_DECRYPT:
6542 attr_mask = (obj->bool_attr_mask) & DECRYPT_BOOL_ON;
6543 compare_boolean = B_TRUE;
6544 break;
6545 case CKA_WRAP:
6546 attr_mask = (obj->bool_attr_mask) & WRAP_BOOL_ON;
6547 compare_boolean = B_TRUE;
6548 break;
6549 case CKA_UNWRAP:
6550 attr_mask = (obj->bool_attr_mask) & UNWRAP_BOOL_ON;
6551 compare_boolean = B_TRUE;
6552 break;
6553 case CKA_SIGN:
6554 attr_mask = (obj->bool_attr_mask) & SIGN_BOOL_ON;
6555 compare_boolean = B_TRUE;
6556 break;
6557 case CKA_SIGN_RECOVER:
6558 attr_mask = (obj->bool_attr_mask) &
6559 SIGN_RECOVER_BOOL_ON;
6560 compare_boolean = B_TRUE;
6561 break;
6562 case CKA_VERIFY:
6563 attr_mask = (obj->bool_attr_mask) & VERIFY_BOOL_ON;
6564 compare_boolean = B_TRUE;
6565 break;
6566 case CKA_VERIFY_RECOVER:
6567 attr_mask = (obj->bool_attr_mask) &
6568 VERIFY_RECOVER_BOOL_ON;
6569 compare_boolean = B_TRUE;
6570 break;
6571 case CKA_DERIVE:
6572 attr_mask = (obj->bool_attr_mask) & DERIVE_BOOL_ON;
6573 compare_boolean = B_TRUE;
6574 break;
6575 case CKA_LOCAL:
6576 attr_mask = (obj->bool_attr_mask) & LOCAL_BOOL_ON;
6577 compare_boolean = B_TRUE;
6578 break;
6579 case CKA_SENSITIVE:
6580 attr_mask = (obj->bool_attr_mask) & SENSITIVE_BOOL_ON;
6581 compare_boolean = B_TRUE;
6582 break;
6583 case CKA_SECONDARY_AUTH:
6584 attr_mask = (obj->bool_attr_mask) &
6585 SECONDARY_AUTH_BOOL_ON;
6586 compare_boolean = B_TRUE;
6587 break;
6588 case CKA_TRUSTED:
6589 attr_mask = (obj->bool_attr_mask) & TRUSTED_BOOL_ON;
6590 compare_boolean = B_TRUE;
6591 break;
6592 case CKA_EXTRACTABLE:
6593 attr_mask = (obj->bool_attr_mask) &
6594 EXTRACTABLE_BOOL_ON;
6595 compare_boolean = B_TRUE;
6596 break;
6597 case CKA_ALWAYS_SENSITIVE:
6598 attr_mask = (obj->bool_attr_mask) &
6599 ALWAYS_SENSITIVE_BOOL_ON;
6600 compare_boolean = B_TRUE;
6601 break;
6602 case CKA_NEVER_EXTRACTABLE:
6603 attr_mask = (obj->bool_attr_mask) &
6604 NEVER_EXTRACTABLE_BOOL_ON;
6605 compare_boolean = B_TRUE;
6606 break;
6607 case CKA_TOKEN:
6608 attr_mask = (obj->object_type) & TOKEN_OBJECT;
6609 compare_boolean = B_TRUE;
6610 break;
6611 case CKA_PRIVATE:
6612 attr_mask = (obj->object_type) & PRIVATE_OBJECT;
6613 compare_boolean = B_TRUE;
6614 break;
6615 case CKA_MODIFIABLE:
6616 {
6617 CK_BBOOL bval;
6618 attr_mask = (obj->bool_attr_mask) &
6619 NOT_MODIFIABLE_BOOL_ON;
6620
6621 if (attr_mask) {
6622 bval = FALSE;
6623 } else {
6624 bval = TRUE;
6625 }
6626 if (bval != *((CK_BBOOL *)tmpl_attr->pValue)) {
6627 return (B_FALSE);
6628 }
6629 break;
6630 }
6631 case CKA_OWNER:
6632 /*
6633 * For X.509 attribute certificate object, get its
6634 * CKA_OWNER attribute from the x509_attr_cert_t struct.
6635 */
6636 if ((obj->class == CKO_CERTIFICATE) &&
6637 (obj->cert_type == CKC_X_509_ATTR_CERT)) {
6638 cert_attr = X509_ATTR_CERT_OWNER(obj);
6639 compare_cert_val = B_TRUE;
6640 }
6641 break;
6642 case CKA_SUBJECT:
6643 /*
6644 * For X.509 certificate object, get its CKA_SUBJECT
6645 * attribute from the x509_cert_t struct (not from
6646 * the extra_attrlistp).
6647 */
6648 if ((obj->class == CKO_CERTIFICATE) &&
6649 (obj->cert_type == CKC_X_509)) {
6650 cert_attr = X509_CERT_SUBJECT(obj);
6651 compare_cert_val = B_TRUE;
6652 break;
6653 }
6654 /*FALLTHRU*/
6655 case CKA_ID:
6656 case CKA_START_DATE:
6657 case CKA_END_DATE:
6658 case CKA_KEY_GEN_MECHANISM:
6659 case CKA_LABEL:
6660 case CKA_ISSUER:
6661 case CKA_SERIAL_NUMBER:
6662 case CKA_AC_ISSUER:
6663 case CKA_ATTR_TYPES:
6664 /* find these attributes from extra_attrlistp */
6665 obj_attr = get_extra_attr(tmpl_attr->type, obj);
6666 compare_attr = B_TRUE;
6667 break;
6668 case CKA_CERTIFICATE_TYPE:
6669 compare_cert_type = B_TRUE;
6670 break;
6671 case CKA_VALUE_LEN:
6672 /* only secret key has this attribute */
6673 if (obj->class == CKO_SECRET_KEY) {
6674 if (*((CK_ULONG *)tmpl_attr->pValue) !=
6675 OBJ_SEC_VALUE_LEN(obj)) {
6676 return (B_FALSE);
6677 }
6678 } else {
6679 return (B_FALSE);
6680 }
6681 break;
6682 case CKA_VALUE:
6683 switch (obj->class) {
6684 case CKO_SECRET_KEY:
6685 /*
6686 * secret_key_obj_t is the same as
6687 * biginteger_t
6688 */
6689 bigint = (biginteger_t *)OBJ_SEC(obj);
6690 compare_bigint = B_TRUE;
6691 break;
6692 case CKO_PRIVATE_KEY:
6693 if (obj->key_type == CKK_DSA) {
6694 bigint = OBJ_PRI_DSA_VALUE(obj);
6695 } else if (obj->key_type == CKK_DH) {
6696 bigint = OBJ_PRI_DH_VALUE(obj);
6697 } else if (obj->key_type == CKK_X9_42_DH) {
6698 bigint = OBJ_PRI_DH942_VALUE(obj);
6699 } else {
6700 return (B_FALSE);
6701 }
6702 compare_bigint = B_TRUE;
6703 break;
6704 case CKO_PUBLIC_KEY:
6705 if (obj->key_type == CKK_DSA) {
6706 bigint = OBJ_PUB_DSA_VALUE(obj);
6707 } else if (obj->key_type == CKK_DH) {
6708 bigint = OBJ_PUB_DH_VALUE(obj);
6709 } else if (obj->key_type == CKK_X9_42_DH) {
6710 bigint = OBJ_PUB_DH942_VALUE(obj);
6711 } else {
6712 return (B_FALSE);
6713 }
6714 compare_bigint = B_TRUE;
6715 break;
6716 case CKO_CERTIFICATE:
6717 if (obj->cert_type == CKC_X_509) {
6718 cert_attr = X509_CERT_VALUE(obj);
6719 } else if (obj->cert_type ==
6720 CKC_X_509_ATTR_CERT) {
6721 cert_attr = X509_ATTR_CERT_VALUE(obj);
6722 }
6723 compare_cert_val = B_TRUE;
6724 break;
6725 default:
6726 return (B_FALSE);
6727 }
6728 break;
6729 case CKA_MODULUS:
6730 /* only RSA public and private key have this attr */
6731 if (obj->key_type == CKK_RSA) {
6732 if (obj->class == CKO_PUBLIC_KEY) {
6733 bigint = OBJ_PUB_RSA_MOD(obj);
6734 } else if (obj->class == CKO_PRIVATE_KEY) {
6735 bigint = OBJ_PRI_RSA_MOD(obj);
6736 } else {
6737 return (B_FALSE);
6738 }
6739 compare_bigint = B_TRUE;
6740 } else {
6741 return (B_FALSE);
6742 }
6743 break;
6744 case CKA_MODULUS_BITS:
6745 /* only RSA public key has this attribute */
6746 if ((obj->key_type == CKK_RSA) &&
6747 (obj->class == CKO_PUBLIC_KEY)) {
6748 CK_ULONG mod_bits = OBJ_PUB_RSA_MOD_BITS(obj);
6749 if (mod_bits !=
6750 *((CK_ULONG *)tmpl_attr->pValue)) {
6751 return (B_FALSE);
6752 }
6753 } else {
6754 return (B_FALSE);
6755 }
6756 break;
6757 case CKA_PUBLIC_EXPONENT:
6758 /* only RSA public and private key have this attr */
6759 if (obj->key_type == CKK_RSA) {
6760 if (obj->class == CKO_PUBLIC_KEY) {
6761 bigint = OBJ_PUB_RSA_PUBEXPO(obj);
6762 } else if (obj->class == CKO_PRIVATE_KEY) {
6763 bigint = OBJ_PRI_RSA_PUBEXPO(obj);
6764 } else {
6765 return (B_FALSE);
6766 }
6767 compare_bigint = B_TRUE;
6768 } else {
6769 return (B_FALSE);
6770 }
6771 break;
6772 case CKA_PRIVATE_EXPONENT:
6773 /* only RSA private key has this attribute */
6774 if ((obj->key_type == CKK_RSA) &&
6775 (obj->class == CKO_PRIVATE_KEY)) {
6776 bigint = OBJ_PRI_RSA_PRIEXPO(obj);
6777 compare_bigint = B_TRUE;
6778 } else {
6779 return (B_FALSE);
6780 }
6781 break;
6782 case CKA_PRIME_1:
6783 /* only RSA private key has this attribute */
6784 if ((obj->key_type == CKK_RSA) &&
6785 (obj->class == CKO_PRIVATE_KEY)) {
6786 bigint = OBJ_PRI_RSA_PRIME1(obj);
6787 compare_bigint = B_TRUE;
6788 } else {
6789 return (B_FALSE);
6790 }
6791 break;
6792 case CKA_PRIME_2:
6793 /* only RSA private key has this attribute */
6794 if ((obj->key_type == CKK_RSA) &&
6795 (obj->class == CKO_PRIVATE_KEY)) {
6796 bigint = OBJ_PRI_RSA_PRIME2(obj);
6797 compare_bigint = B_TRUE;
6798 } else {
6799 return (B_FALSE);
6800 }
6801 break;
6802 case CKA_EXPONENT_1:
6803 /* only RSA private key has this attribute */
6804 if ((obj->key_type == CKK_RSA) &&
6805 (obj->class == CKO_PRIVATE_KEY)) {
6806 bigint = OBJ_PRI_RSA_EXPO1(obj);
6807 compare_bigint = B_TRUE;
6808 } else {
6809 return (B_FALSE);
6810 }
6811 break;
6812 case CKA_EXPONENT_2:
6813 /* only RSA private key has this attribute */
6814 if ((obj->key_type == CKK_RSA) &&
6815 (obj->class == CKO_PRIVATE_KEY)) {
6816 bigint = OBJ_PRI_RSA_EXPO2(obj);
6817 compare_bigint = B_TRUE;
6818 } else {
6819 return (B_FALSE);
6820 }
6821 break;
6822 case CKA_COEFFICIENT:
6823 /* only RSA private key has this attribute */
6824 if ((obj->key_type == CKK_RSA) &&
6825 (obj->class == CKO_PRIVATE_KEY)) {
6826 bigint = OBJ_PRI_RSA_COEF(obj);
6827 compare_bigint = B_TRUE;
6828 } else {
6829 return (B_FALSE);
6830 }
6831 break;
6832 case CKA_VALUE_BITS:
6833 /* only Diffie-Hellman private key has this attr */
6834 if ((obj->key_type == CKK_DH) &&
6835 (obj->class == CKO_PRIVATE_KEY)) {
6836 CK_ULONG val_bits = OBJ_PRI_DH_VAL_BITS(obj);
6837 if (val_bits !=
6838 *((CK_ULONG *)tmpl_attr->pValue)) {
6839 return (B_FALSE);
6840 }
6841 } else {
6842 return (B_FALSE);
6843 }
6844 break;
6845 case CKA_PRIME:
6846 if (obj->class == CKO_PUBLIC_KEY) {
6847 switch (obj->key_type) {
6848 case CKK_DSA:
6849 bigint = OBJ_PUB_DSA_PRIME(obj);
6850 break;
6851 case CKK_DH:
6852 bigint = OBJ_PUB_DH_PRIME(obj);
6853 break;
6854 case CKK_X9_42_DH:
6855 bigint = OBJ_PUB_DH942_PRIME(obj);
6856 break;
6857 default:
6858 return (B_FALSE);
6859 }
6860 } else if (obj->class == CKO_PRIVATE_KEY) {
6861 switch (obj->key_type) {
6862 case CKK_DSA:
6863 bigint = OBJ_PRI_DSA_PRIME(obj);
6864 break;
6865 case CKK_DH:
6866 bigint = OBJ_PRI_DH_PRIME(obj);
6867 break;
6868 case CKK_X9_42_DH:
6869 bigint = OBJ_PRI_DH942_PRIME(obj);
6870 break;
6871 default:
6872 return (B_FALSE);
6873 }
6874 } else if (obj->class == CKO_DOMAIN_PARAMETERS) {
6875 switch (obj->key_type) {
6876 case CKK_DSA:
6877 bigint = OBJ_DOM_DSA_PRIME(obj);
6878 break;
6879 case CKK_DH:
6880 bigint = OBJ_DOM_DH_PRIME(obj);
6881 break;
6882 case CKK_X9_42_DH:
6883 bigint = OBJ_DOM_DH942_PRIME(obj);
6884 break;
6885 default:
6886 return (B_FALSE);
6887 }
6888 } else {
6889 return (B_FALSE);
6890 }
6891 compare_bigint = B_TRUE;
6892 break;
6893 case CKA_SUBPRIME:
6894 if (obj->class == CKO_PUBLIC_KEY) {
6895 switch (obj->key_type) {
6896 case CKK_DSA:
6897 bigint = OBJ_PUB_DSA_SUBPRIME(obj);
6898 break;
6899 case CKK_X9_42_DH:
6900 bigint = OBJ_PUB_DH942_SUBPRIME(obj);
6901 break;
6902 default:
6903 return (B_FALSE);
6904 }
6905 } else if (obj->class == CKO_PRIVATE_KEY) {
6906 switch (obj->key_type) {
6907 case CKK_DSA:
6908 bigint = OBJ_PRI_DSA_SUBPRIME(obj);
6909 break;
6910 case CKK_X9_42_DH:
6911 bigint = OBJ_PRI_DH942_SUBPRIME(obj);
6912 break;
6913 default:
6914 return (B_FALSE);
6915 }
6916 } else if (obj->class == CKO_DOMAIN_PARAMETERS) {
6917 switch (obj->key_type) {
6918 case CKK_DSA:
6919 bigint = OBJ_DOM_DSA_SUBPRIME(obj);
6920 break;
6921 case CKK_X9_42_DH:
6922 bigint = OBJ_DOM_DH942_SUBPRIME(obj);
6923 break;
6924 default:
6925 return (B_FALSE);
6926 }
6927 } else {
6928 return (B_FALSE);
6929 }
6930 compare_bigint = B_TRUE;
6931 break;
6932 case CKA_BASE:
6933 if (obj->class == CKO_PUBLIC_KEY) {
6934 switch (obj->key_type) {
6935 case CKK_DSA:
6936 bigint = OBJ_PUB_DSA_BASE(obj);
6937 break;
6938 case CKK_DH:
6939 bigint = OBJ_PUB_DH_BASE(obj);
6940 break;
6941 case CKK_X9_42_DH:
6942 bigint = OBJ_PUB_DH942_BASE(obj);
6943 break;
6944 default:
6945 return (B_FALSE);
6946 }
6947 } else if (obj->class == CKO_PRIVATE_KEY) {
6948 switch (obj->key_type) {
6949 case CKK_DSA:
6950 bigint = OBJ_PRI_DSA_BASE(obj);
6951 break;
6952 case CKK_DH:
6953 bigint = OBJ_PRI_DH_BASE(obj);
6954 break;
6955 case CKK_X9_42_DH:
6956 bigint = OBJ_PRI_DH942_BASE(obj);
6957 break;
6958 default:
6959 return (B_FALSE);
6960 }
6961 } else if (obj->class == CKO_DOMAIN_PARAMETERS) {
6962 switch (obj->key_type) {
6963 case CKK_DSA:
6964 bigint = OBJ_DOM_DSA_BASE(obj);
6965 break;
6966 case CKK_DH:
6967 bigint = OBJ_DOM_DH_BASE(obj);
6968 break;
6969 case CKK_X9_42_DH:
6970 bigint = OBJ_DOM_DH942_BASE(obj);
6971 break;
6972 default:
6973 return (B_FALSE);
6974 }
6975 } else {
6976 return (B_FALSE);
6977 }
6978 compare_bigint = B_TRUE;
6979 break;
6980 case CKA_PRIME_BITS:
6981 if (obj->class == CKO_DOMAIN_PARAMETERS) {
6982 CK_ULONG prime_bits;
6983 if (obj->key_type == CKK_DSA) {
6984 prime_bits =
6985 OBJ_DOM_DSA_PRIME_BITS(obj);
6986 } else if (obj->key_type == CKK_DH) {
6987 prime_bits =
6988 OBJ_DOM_DH_PRIME_BITS(obj);
6989 } else if (obj->key_type == CKK_X9_42_DH) {
6990 prime_bits =
6991 OBJ_DOM_DH942_PRIME_BITS(obj);
6992 } else {
6993 return (B_FALSE);
6994 }
6995 if (prime_bits !=
6996 *((CK_ULONG *)tmpl_attr->pValue)) {
6997 return (B_FALSE);
6998 }
6999 } else {
7000 return (B_FALSE);
7001 }
7002 break;
7003 case CKA_SUBPRIME_BITS:
7004 if ((obj->class == CKO_DOMAIN_PARAMETERS) &&
7005 (obj->key_type == CKK_X9_42_DH)) {
7006 CK_ULONG subprime_bits =
7007 OBJ_DOM_DH942_SUBPRIME_BITS(obj);
7008 if (subprime_bits !=
7009 *((CK_ULONG *)tmpl_attr->pValue)) {
7010 return (B_FALSE);
7011 }
7012 } else {
7013 return (B_FALSE);
7014 }
7015 break;
7016 default:
7017 /*
7018 * any other attributes are currently not supported.
7019 * so, it's not possible for them to be in the
7020 * object
7021 */
7022 return (B_FALSE);
7023 }
7024 if (compare_boolean) {
7025 CK_BBOOL bval;
7026
7027 if (attr_mask) {
7028 bval = TRUE;
7029 } else {
7030 bval = FALSE;
7031 }
7032 if (bval != *((CK_BBOOL *)tmpl_attr->pValue)) {
7033 return (B_FALSE);
7034 }
7035 } else if (compare_bigint) {
7036 if (bigint == NULL) {
7037 return (B_FALSE);
7038 }
7039 if (tmpl_attr->ulValueLen != bigint->big_value_len) {
7040 return (B_FALSE);
7041 }
7042 if (memcmp(tmpl_attr->pValue, bigint->big_value,
7043 tmpl_attr->ulValueLen) != 0) {
7044 return (B_FALSE);
7045 }
7046 } else if (compare_attr) {
7047 if (obj_attr == NULL) {
7048 /*
7049 * The attribute type is valid, and its value
7050 * has not been initialized in the object. In
7051 * this case, it only matches the template's
7052 * attribute if the template's value length
7053 * is 0.
7054 */
7055 if (tmpl_attr->ulValueLen != 0)
7056 return (B_FALSE);
7057 } else {
7058 if (tmpl_attr->ulValueLen !=
7059 obj_attr->ulValueLen) {
7060 return (B_FALSE);
7061 }
7062 if (memcmp(tmpl_attr->pValue, obj_attr->pValue,
7063 tmpl_attr->ulValueLen) != 0) {
7064 return (B_FALSE);
7065 }
7066 }
7067 } else if (compare_cert_val) {
7068 if (cert_attr == NULL) {
7069 /* specific attribute not found */
7070 return (B_FALSE);
7071 }
7072 if (tmpl_attr->ulValueLen != cert_attr->length) {
7073 return (B_FALSE);
7074 }
7075 if (memcmp(tmpl_attr->pValue, cert_attr->value,
7076 tmpl_attr->ulValueLen) != 0) {
7077 return (B_FALSE);
7078 }
7079 } else if (compare_cert_type) {
7080 if (memcmp(tmpl_attr->pValue, &(obj->cert_type),
7081 tmpl_attr->ulValueLen) != 0) {
7082 return (B_FALSE);
7083 }
7084 }
7085 }
7086 return (B_TRUE);
7087 }
7088
7089 CK_ATTRIBUTE_PTR
7090 get_extra_attr(CK_ATTRIBUTE_TYPE type, soft_object_t *obj)
7091 {
7092 CK_ATTRIBUTE_INFO_PTR tmp;
7093
7094 tmp = obj->extra_attrlistp;
7095 while (tmp != NULL) {
7096 if (tmp->attr.type == type) {
7097 return (&(tmp->attr));
7098 }
7099 tmp = tmp->next;
7100 }
7101 /* if get there, the specified attribute is not found */
7102 return (NULL);
7103 }
7104