9642 PKCS#11 softtoken should use explicit_bzero
[unleashed.git] / usr / src / lib / pkcs11 / pkcs11_softtoken / common / softAttributeUtil.c
blob7c81043e431073b4f9ac5c8436067037cd6c3ac1
1 /*
2 * CDDL HEADER START
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.
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.
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]
19 * CDDL HEADER END
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 * Copyright (c) 2018, Joyent, Inc.
28 #include <stdlib.h>
29 #include <string.h>
30 #include <security/cryptoki.h>
31 #include <sys/crypto/common.h>
32 #include <arcfour.h>
33 #include <aes_impl.h>
34 #include <blowfish_impl.h>
35 #include <bignum.h>
36 #include <des_impl.h>
37 #include <rsa_impl.h>
38 #include "softGlobal.h"
39 #include "softObject.h"
40 #include "softSession.h"
41 #include "softKeystore.h"
42 #include "softKeystoreUtil.h"
43 #include "softCrypt.h"
47 * This attribute table is used by the soft_lookup_attr()
48 * to validate the attributes.
50 CK_ATTRIBUTE_TYPE attr_map[] = {
51 CKA_PRIVATE,
52 CKA_LABEL,
53 CKA_APPLICATION,
54 CKA_OBJECT_ID,
55 CKA_CERTIFICATE_TYPE,
56 CKA_ISSUER,
57 CKA_SERIAL_NUMBER,
58 CKA_AC_ISSUER,
59 CKA_OWNER,
60 CKA_ATTR_TYPES,
61 CKA_SUBJECT,
62 CKA_ID,
63 CKA_SENSITIVE,
64 CKA_START_DATE,
65 CKA_END_DATE,
66 CKA_MODULUS,
67 CKA_MODULUS_BITS,
68 CKA_PUBLIC_EXPONENT,
69 CKA_PRIVATE_EXPONENT,
70 CKA_PRIME_1,
71 CKA_PRIME_2,
72 CKA_EXPONENT_1,
73 CKA_EXPONENT_2,
74 CKA_COEFFICIENT,
75 CKA_PRIME,
76 CKA_SUBPRIME,
77 CKA_BASE,
78 CKA_EXTRACTABLE,
79 CKA_LOCAL,
80 CKA_NEVER_EXTRACTABLE,
81 CKA_ALWAYS_SENSITIVE,
82 CKA_MODIFIABLE,
83 CKA_ECDSA_PARAMS,
84 CKA_EC_PARAMS,
85 CKA_EC_POINT,
86 CKA_SECONDARY_AUTH,
87 CKA_AUTH_PIN_FLAGS,
88 CKA_HW_FEATURE_TYPE,
89 CKA_RESET_ON_INIT,
90 CKA_HAS_RESET
94 * attributes that exists only in public key objects
95 * Note: some attributes may also exist in one or two
96 * other object classes, but they are also listed
97 * because not all object have them.
99 CK_ATTRIBUTE_TYPE PUB_KEY_ATTRS[] =
101 CKA_SUBJECT,
102 CKA_ENCRYPT,
103 CKA_WRAP,
104 CKA_VERIFY,
105 CKA_VERIFY_RECOVER,
106 CKA_MODULUS,
107 CKA_MODULUS_BITS,
108 CKA_PUBLIC_EXPONENT,
109 CKA_PRIME,
110 CKA_SUBPRIME,
111 CKA_BASE,
112 CKA_TRUSTED,
113 CKA_ECDSA_PARAMS,
114 CKA_EC_PARAMS,
115 CKA_EC_POINT
119 * attributes that exists only in private key objects
120 * Note: some attributes may also exist in one or two
121 * other object classes, but they are also listed
122 * because not all object have them.
124 CK_ATTRIBUTE_TYPE PRIV_KEY_ATTRS[] =
126 CKA_DECRYPT,
127 CKA_UNWRAP,
128 CKA_SIGN,
129 CKA_SIGN_RECOVER,
130 CKA_MODULUS,
131 CKA_PUBLIC_EXPONENT,
132 CKA_PRIVATE_EXPONENT,
133 CKA_PRIME,
134 CKA_SUBPRIME,
135 CKA_BASE,
136 CKA_PRIME_1,
137 CKA_PRIME_2,
138 CKA_EXPONENT_1,
139 CKA_EXPONENT_2,
140 CKA_COEFFICIENT,
141 CKA_VALUE_BITS,
142 CKA_SUBJECT,
143 CKA_SENSITIVE,
144 CKA_EXTRACTABLE,
145 CKA_NEVER_EXTRACTABLE,
146 CKA_ALWAYS_SENSITIVE,
147 CKA_EC_PARAMS
151 * attributes that exists only in secret key objects
152 * Note: some attributes may also exist in one or two
153 * other object classes, but they are also listed
154 * because not all object have them.
156 CK_ATTRIBUTE_TYPE SECRET_KEY_ATTRS[] =
158 CKA_VALUE_LEN,
159 CKA_ENCRYPT,
160 CKA_DECRYPT,
161 CKA_WRAP,
162 CKA_UNWRAP,
163 CKA_SIGN,
164 CKA_VERIFY,
165 CKA_SENSITIVE,
166 CKA_EXTRACTABLE,
167 CKA_NEVER_EXTRACTABLE,
168 CKA_ALWAYS_SENSITIVE
172 * attributes that exists only in domain parameter objects
173 * Note: some attributes may also exist in one or two
174 * other object classes, but they are also listed
175 * because not all object have them.
177 CK_ATTRIBUTE_TYPE DOMAIN_ATTRS[] =
179 CKA_PRIME,
180 CKA_SUBPRIME,
181 CKA_BASE,
182 CKA_PRIME_BITS,
183 CKA_SUBPRIME_BITS,
184 CKA_SUB_PRIME_BITS
188 * attributes that exists only in hardware feature objects
191 CK_ATTRIBUTE_TYPE HARDWARE_ATTRS[] =
193 CKA_HW_FEATURE_TYPE,
194 CKA_RESET_ON_INIT,
195 CKA_HAS_RESET
199 * attributes that exists only in certificate objects
201 CK_ATTRIBUTE_TYPE CERT_ATTRS[] =
203 CKA_CERTIFICATE_TYPE,
204 CKA_TRUSTED,
205 CKA_SUBJECT,
206 CKA_ID,
207 CKA_ISSUER,
208 CKA_AC_ISSUER,
209 CKA_SERIAL_NUMBER,
210 CKA_OWNER,
211 CKA_ATTR_TYPES
216 * Validate the attribute by using binary search algorithm.
218 CK_RV
219 soft_lookup_attr(CK_ATTRIBUTE_TYPE type)
222 size_t lower, middle, upper;
224 lower = 0;
225 upper = (sizeof (attr_map) / sizeof (CK_ATTRIBUTE_TYPE)) - 1;
227 while (lower <= upper) {
228 /* Always starts from middle. */
229 middle = (lower + upper) / 2;
231 if (type > attr_map[middle]) {
232 /* Adjust the lower bound to upper half. */
233 lower = middle + 1;
234 continue;
237 if (type == attr_map[middle]) {
238 /* Found it. */
239 return (CKR_OK);
242 if (type < attr_map[middle]) {
243 /* Adjust the upper bound to lower half. */
244 upper = middle - 1;
245 continue;
249 /* Failed to find the matching attribute from the attribute table. */
250 return (CKR_ATTRIBUTE_TYPE_INVALID);
255 * Validate the attribute by using the following search algorithm:
257 * 1) Search for the most frequently used attributes first.
258 * 2) If not found, search for the usage-purpose attributes - these
259 * attributes have dense set of values, therefore compiler will
260 * optimize it with a branch table and branch to the appropriate
261 * case.
262 * 3) If still not found, use binary search for the rest of the
263 * attributes in the attr_map[] table.
265 CK_RV
266 soft_validate_attr(CK_ATTRIBUTE_PTR template, CK_ULONG ulAttrNum,
267 CK_OBJECT_CLASS *class)
270 CK_ULONG i;
271 CK_RV rv = CKR_OK;
273 for (i = 0; i < ulAttrNum; i++) {
274 /* First tier search */
275 switch (template[i].type) {
276 case CKA_CLASS:
277 *class = *((CK_OBJECT_CLASS*)template[i].pValue);
278 break;
279 case CKA_TOKEN:
280 break;
281 case CKA_KEY_TYPE:
282 break;
283 case CKA_VALUE:
284 break;
285 case CKA_VALUE_LEN:
286 break;
287 case CKA_VALUE_BITS:
288 break;
289 default:
290 /* Second tier search */
291 switch (template[i].type) {
292 case CKA_ENCRYPT:
293 break;
294 case CKA_DECRYPT:
295 break;
296 case CKA_WRAP:
297 break;
298 case CKA_UNWRAP:
299 break;
300 case CKA_SIGN:
301 break;
302 case CKA_SIGN_RECOVER:
303 break;
304 case CKA_VERIFY:
305 break;
306 case CKA_VERIFY_RECOVER:
307 break;
308 case CKA_DERIVE:
309 break;
310 default:
311 /* Third tier search */
312 rv = soft_lookup_attr(template[i].type);
313 if (rv != CKR_OK)
314 return (rv);
315 break;
317 break;
320 return (rv);
323 static void
324 cleanup_cert_attr(cert_attr_t *attr)
326 if (attr != NULL) {
327 freezero(attr->value, attr->length);
328 attr->value = NULL;
329 attr->length = 0;
333 static CK_RV
334 copy_cert_attr(cert_attr_t *src_attr, cert_attr_t **dest_attr)
336 CK_RV rv = CKR_OK;
338 if (src_attr == NULL || dest_attr == NULL)
339 return (CKR_HOST_MEMORY);
341 if (src_attr->value == NULL)
342 return (CKR_HOST_MEMORY);
344 /* free memory if its already allocated */
345 if (*dest_attr != NULL) {
346 cleanup_cert_attr(*dest_attr);
347 } else {
348 *dest_attr = malloc(sizeof (cert_attr_t));
349 if (*dest_attr == NULL)
350 return (CKR_HOST_MEMORY);
353 (*dest_attr)->value = NULL;
354 (*dest_attr)->length = 0;
356 if (src_attr->length) {
357 (*dest_attr)->value = malloc(src_attr->length);
358 if ((*dest_attr)->value == NULL) {
359 free(*dest_attr);
360 return (CKR_HOST_MEMORY);
363 (void) memcpy((*dest_attr)->value, src_attr->value,
364 src_attr->length);
365 (*dest_attr)->length = src_attr->length;
368 return (rv);
371 void
372 soft_cleanup_cert_object(soft_object_t *object_p)
374 CK_CERTIFICATE_TYPE certtype = object_p->cert_type;
376 if (object_p->class != CKO_CERTIFICATE ||
377 OBJ_CERT(object_p) == NULL)
378 return;
380 if (certtype == CKC_X_509) {
381 if (X509_CERT_SUBJECT(object_p) != NULL) {
382 cleanup_cert_attr(X509_CERT_SUBJECT(object_p));
383 free(X509_CERT_SUBJECT(object_p));
384 X509_CERT_SUBJECT(object_p) = NULL;
386 if (X509_CERT_VALUE(object_p) != NULL) {
387 cleanup_cert_attr(X509_CERT_VALUE(object_p));
388 free(X509_CERT_VALUE(object_p));
389 X509_CERT_VALUE(object_p) = NULL;
391 free(OBJ_CERT(object_p));
392 } else if (certtype == CKC_X_509_ATTR_CERT) {
393 if (X509_ATTR_CERT_VALUE(object_p) != NULL) {
394 cleanup_cert_attr(X509_ATTR_CERT_VALUE(object_p));
395 free(X509_ATTR_CERT_VALUE(object_p));
396 X509_ATTR_CERT_VALUE(object_p) = NULL;
398 if (X509_ATTR_CERT_OWNER(object_p) != NULL) {
399 cleanup_cert_attr(X509_ATTR_CERT_OWNER(object_p));
400 free(X509_ATTR_CERT_OWNER(object_p));
401 X509_ATTR_CERT_OWNER(object_p) = NULL;
403 free(OBJ_CERT(object_p));
408 * Clean up and release all the storage in the extra attribute list
409 * of an object.
411 void
412 soft_cleanup_extra_attr(soft_object_t *object_p)
415 CK_ATTRIBUTE_INFO_PTR extra_attr;
416 CK_ATTRIBUTE_INFO_PTR tmp;
418 extra_attr = object_p->extra_attrlistp;
419 while (extra_attr) {
420 tmp = extra_attr->next;
421 if (extra_attr->attr.pValue != NULL) {
423 * All extra attributes in the extra attribute
424 * list have pValue points to the value of the
425 * attribute (with simple byte array type).
426 * Free the storage for the value of the attribute.
428 freezero(extra_attr->attr.pValue,
429 extra_attr->attr.ulValueLen);
432 /* Free the storage for the attribute_info struct. */
433 free(extra_attr);
434 extra_attr = tmp;
437 object_p->extra_attrlistp = NULL;
442 * Create the attribute_info struct to hold the object's attribute,
443 * and add it to the extra attribute list of an object.
445 CK_RV
446 soft_add_extra_attr(CK_ATTRIBUTE_PTR template, soft_object_t *object_p)
449 CK_ATTRIBUTE_INFO_PTR attrp;
451 /* Allocate the storage for the attribute_info struct. */
452 attrp = calloc(1, sizeof (attribute_info_t));
453 if (attrp == NULL) {
454 return (CKR_HOST_MEMORY);
457 /* Set up attribute_info struct. */
458 attrp->attr.type = template->type;
459 attrp->attr.ulValueLen = template->ulValueLen;
461 if ((template->pValue != NULL) &&
462 (template->ulValueLen > 0)) {
463 /* Allocate storage for the value of the attribute. */
464 attrp->attr.pValue = malloc(template->ulValueLen);
465 if (attrp->attr.pValue == NULL) {
466 free(attrp);
467 return (CKR_HOST_MEMORY);
470 (void) memcpy(attrp->attr.pValue, template->pValue,
471 template->ulValueLen);
472 } else {
473 attrp->attr.pValue = NULL;
476 /* Insert the new attribute in front of extra attribute list. */
477 if (object_p->extra_attrlistp == NULL) {
478 object_p->extra_attrlistp = attrp;
479 attrp->next = NULL;
480 } else {
481 attrp->next = object_p->extra_attrlistp;
482 object_p->extra_attrlistp = attrp;
485 return (CKR_OK);
488 CK_RV
489 soft_copy_certificate(certificate_obj_t *oldcert, certificate_obj_t **newcert,
490 CK_CERTIFICATE_TYPE type)
492 CK_RV rv = CKR_OK;
493 certificate_obj_t *cert;
494 x509_cert_t x509;
495 x509_attr_cert_t x509_attr;
497 cert = calloc(1, sizeof (certificate_obj_t));
498 if (cert == NULL) {
499 return (CKR_HOST_MEMORY);
502 if (type == CKC_X_509) {
503 x509 = oldcert->cert_type_u.x509;
504 if (x509.subject)
505 if ((rv = copy_cert_attr(x509.subject,
506 &cert->cert_type_u.x509.subject)))
507 return (rv);
508 if (x509.value)
509 if ((rv = copy_cert_attr(x509.value,
510 &cert->cert_type_u.x509.value)))
511 return (rv);
512 } else if (type == CKC_X_509_ATTR_CERT) {
513 x509_attr = oldcert->cert_type_u.x509_attr;
514 if (x509_attr.owner)
515 if ((rv = copy_cert_attr(x509_attr.owner,
516 &cert->cert_type_u.x509_attr.owner)))
517 return (rv);
518 if (x509_attr.value)
519 if ((rv = copy_cert_attr(x509_attr.value,
520 &cert->cert_type_u.x509_attr.value)))
521 return (rv);
522 } else {
523 /* wrong certificate type */
524 rv = CKR_ATTRIBUTE_TYPE_INVALID;
526 if (rv == CKR_OK)
527 *newcert = cert;
528 return (rv);
532 * Copy the attribute_info struct from the old object to a new attribute_info
533 * struct, and add that new struct to the extra attribute list of the new
534 * object.
536 CK_RV
537 soft_copy_extra_attr(CK_ATTRIBUTE_INFO_PTR old_attrp, soft_object_t *object_p)
539 CK_ATTRIBUTE_INFO_PTR attrp;
541 /* Allocate attribute_info struct. */
542 attrp = calloc(1, sizeof (attribute_info_t));
543 if (attrp == NULL) {
544 return (CKR_HOST_MEMORY);
547 attrp->attr.type = old_attrp->attr.type;
548 attrp->attr.ulValueLen = old_attrp->attr.ulValueLen;
550 if ((old_attrp->attr.pValue != NULL) &&
551 (old_attrp->attr.ulValueLen > 0)) {
552 attrp->attr.pValue = malloc(old_attrp->attr.ulValueLen);
553 if (attrp->attr.pValue == NULL) {
554 free(attrp);
555 return (CKR_HOST_MEMORY);
558 (void) memcpy(attrp->attr.pValue, old_attrp->attr.pValue,
559 old_attrp->attr.ulValueLen);
560 } else {
561 attrp->attr.pValue = NULL;
564 /* Insert the new attribute in front of extra attribute list */
565 if (object_p->extra_attrlistp == NULL) {
566 object_p->extra_attrlistp = attrp;
567 attrp->next = NULL;
568 } else {
569 attrp->next = object_p->extra_attrlistp;
570 object_p->extra_attrlistp = attrp;
573 return (CKR_OK);
578 * Get the attribute triple from the extra attribute list in the object
579 * (if the specified attribute type is found), and copy it to a template.
580 * Note the type of the attribute to be copied is specified by the template,
581 * and the storage is pre-allocated for the atrribute value in the template
582 * for doing the copy.
584 CK_RV
585 get_extra_attr_from_object(soft_object_t *object_p, CK_ATTRIBUTE_PTR template)
588 CK_ATTRIBUTE_INFO_PTR extra_attr;
589 CK_ATTRIBUTE_TYPE type = template->type;
591 extra_attr = object_p->extra_attrlistp;
593 while (extra_attr) {
594 if (type == extra_attr->attr.type) {
595 /* Found it. */
596 break;
597 } else {
598 /* Does not match, try next one. */
599 extra_attr = extra_attr->next;
603 if (extra_attr == NULL) {
604 /* A valid but un-initialized attribute. */
605 template->ulValueLen = 0;
606 return (CKR_OK);
610 * We found the attribute in the extra attribute list.
612 if (template->pValue == NULL) {
613 template->ulValueLen = extra_attr->attr.ulValueLen;
614 return (CKR_OK);
617 if (template->ulValueLen >= extra_attr->attr.ulValueLen) {
619 * The buffer provided by the application is large
620 * enough to hold the value of the attribute.
622 (void) memcpy(template->pValue, extra_attr->attr.pValue,
623 extra_attr->attr.ulValueLen);
624 template->ulValueLen = extra_attr->attr.ulValueLen;
625 return (CKR_OK);
626 } else {
628 * The buffer provided by the application does
629 * not have enough space to hold the value.
631 template->ulValueLen = (CK_ULONG)-1;
632 return (CKR_BUFFER_TOO_SMALL);
638 * Modify the attribute triple in the extra attribute list of the object
639 * if the specified attribute type is found. Otherwise, just add it to
640 * list.
642 CK_RV
643 set_extra_attr_to_object(soft_object_t *object_p, CK_ATTRIBUTE_TYPE type,
644 CK_ATTRIBUTE_PTR template)
647 CK_ATTRIBUTE_INFO_PTR extra_attr;
649 extra_attr = object_p->extra_attrlistp;
651 while (extra_attr) {
652 if (type == extra_attr->attr.type) {
653 /* Found it. */
654 break;
655 } else {
656 /* Does not match, try next one. */
657 extra_attr = extra_attr->next;
661 if (extra_attr == NULL) {
663 * This attribute is a new one, go ahead adding it to
664 * the extra attribute list.
666 return (soft_add_extra_attr(template, object_p));
669 /* We found the attribute in the extra attribute list. */
670 if ((template->pValue != NULL) &&
671 (template->ulValueLen > 0)) {
672 if (template->ulValueLen > extra_attr->attr.ulValueLen) {
673 /* The old buffer is too small to hold the new value. */
674 if (extra_attr->attr.pValue != NULL) {
675 /* Free storage for the old attribute value. */
676 freezero(extra_attr->attr.pValue,
677 extra_attr->attr.ulValueLen);
680 /* Allocate storage for the new attribute value. */
681 extra_attr->attr.pValue = malloc(template->ulValueLen);
682 if (extra_attr->attr.pValue == NULL) {
683 return (CKR_HOST_MEMORY);
687 /* Replace the attribute with new value. */
688 extra_attr->attr.ulValueLen = template->ulValueLen;
689 (void) memcpy(extra_attr->attr.pValue, template->pValue,
690 template->ulValueLen);
691 } else {
692 extra_attr->attr.pValue = NULL;
695 return (CKR_OK);
700 * Copy the big integer attribute value from template to a biginteger_t struct.
702 CK_RV
703 get_bigint_attr_from_template(biginteger_t *big, CK_ATTRIBUTE_PTR template)
706 if ((template->pValue != NULL) &&
707 (template->ulValueLen > 0)) {
708 /* Allocate storage for the value of the attribute. */
709 big->big_value = malloc(template->ulValueLen);
710 if (big->big_value == NULL) {
711 return (CKR_HOST_MEMORY);
714 (void) memcpy(big->big_value, template->pValue,
715 template->ulValueLen);
716 big->big_value_len = template->ulValueLen;
717 } else {
718 big->big_value = NULL;
719 big->big_value_len = 0;
722 return (CKR_OK);
727 * Copy the big integer attribute value from a biginteger_t struct in the
728 * object to a template.
730 CK_RV
731 get_bigint_attr_from_object(biginteger_t *big, CK_ATTRIBUTE_PTR template)
734 if (template->pValue == NULL) {
735 template->ulValueLen = big->big_value_len;
736 return (CKR_OK);
739 if (big->big_value == NULL) {
740 template->ulValueLen = 0;
741 return (CKR_OK);
744 if (template->ulValueLen >= big->big_value_len) {
746 * The buffer provided by the application is large
747 * enough to hold the value of the attribute.
749 (void) memcpy(template->pValue, big->big_value,
750 big->big_value_len);
751 template->ulValueLen = big->big_value_len;
752 return (CKR_OK);
753 } else {
755 * The buffer provided by the application does
756 * not have enough space to hold the value.
758 template->ulValueLen = (CK_ULONG)-1;
759 return (CKR_BUFFER_TOO_SMALL);
765 * Copy the boolean data type attribute value from an object for the
766 * specified attribute to the template.
768 CK_RV
769 get_bool_attr_from_object(soft_object_t *object_p, CK_ULONG bool_flag,
770 CK_ATTRIBUTE_PTR template)
773 if (template->pValue == NULL) {
774 template->ulValueLen = sizeof (CK_BBOOL);
775 return (CKR_OK);
778 if (template->ulValueLen >= sizeof (CK_BBOOL)) {
780 * The buffer provided by the application is large
781 * enough to hold the value of the attribute.
783 if (object_p->bool_attr_mask & bool_flag) {
784 *((CK_BBOOL *)template->pValue) = B_TRUE;
785 } else {
786 *((CK_BBOOL *)template->pValue) = B_FALSE;
789 template->ulValueLen = sizeof (CK_BBOOL);
790 return (CKR_OK);
791 } else {
793 * The buffer provided by the application does
794 * not have enough space to hold the value.
796 template->ulValueLen = (CK_ULONG)-1;
797 return (CKR_BUFFER_TOO_SMALL);
802 * Set the boolean data type attribute value in the object.
804 CK_RV
805 set_bool_attr_to_object(soft_object_t *object_p, CK_ULONG bool_flag,
806 CK_ATTRIBUTE_PTR template)
809 if (*(CK_BBOOL *)template->pValue)
810 object_p->bool_attr_mask |= bool_flag;
811 else
812 object_p->bool_attr_mask &= ~bool_flag;
814 return (CKR_OK);
819 * Copy the CK_ULONG data type attribute value from an object to the
820 * template.
822 CK_RV
823 get_ulong_attr_from_object(CK_ULONG value, CK_ATTRIBUTE_PTR template)
826 if (template->pValue == NULL) {
827 template->ulValueLen = sizeof (CK_ULONG);
828 return (CKR_OK);
831 if (template->ulValueLen >= sizeof (CK_ULONG)) {
833 * The buffer provided by the application is large
834 * enough to hold the value of the attribute.
835 * It is also assumed to be correctly aligned.
837 *(CK_ULONG_PTR)template->pValue = value;
838 template->ulValueLen = sizeof (CK_ULONG);
839 return (CKR_OK);
840 } else {
842 * The buffer provided by the application does
843 * not have enough space to hold the value.
845 template->ulValueLen = (CK_ULONG)-1;
846 return (CKR_BUFFER_TOO_SMALL);
852 * Copy the CK_ULONG data type attribute value from a template to the
853 * object.
855 static CK_RV
856 get_ulong_attr_from_template(CK_ULONG *value, CK_ATTRIBUTE_PTR template)
859 if (template->ulValueLen < sizeof (CK_ULONG))
860 return (CKR_ATTRIBUTE_VALUE_INVALID);
862 if (template->pValue != NULL) {
863 *value = *(CK_ULONG_PTR)template->pValue;
864 } else {
865 *value = 0;
868 return (CKR_OK);
872 * Copy the big integer attribute value from source's biginteger_t to
873 * destination's biginteger_t.
875 void
876 copy_bigint_attr(biginteger_t *src, biginteger_t *dst)
879 if ((src->big_value != NULL) &&
880 (src->big_value_len > 0)) {
882 * To do the copy, just have dst's big_value points
883 * to src's.
885 dst->big_value = src->big_value;
886 dst->big_value_len = src->big_value_len;
889 * After the copy, nullify the src's big_value pointer.
890 * It prevents any double freeing the value.
892 src->big_value = NULL;
893 src->big_value_len = 0;
894 } else {
895 dst->big_value = NULL;
896 dst->big_value_len = 0;
900 CK_RV
901 get_string_from_template(CK_ATTRIBUTE_PTR dest, CK_ATTRIBUTE_PTR src)
903 if ((src->pValue != NULL) &&
904 (src->ulValueLen > 0)) {
905 /* Allocate storage for the value of the attribute. */
906 dest->pValue = malloc(src->ulValueLen);
907 if (dest->pValue == NULL) {
908 return (CKR_HOST_MEMORY);
911 (void) memcpy(dest->pValue, src->pValue,
912 src->ulValueLen);
913 dest->ulValueLen = src->ulValueLen;
914 dest->type = src->type;
915 } else {
916 dest->pValue = NULL;
917 dest->ulValueLen = 0;
918 dest->type = src->type;
921 return (CKR_OK);
925 CK_RV
926 get_cert_attr_from_template(cert_attr_t **dest, CK_ATTRIBUTE_PTR src)
928 if (src->pValue != NULL && src->ulValueLen > 0) {
930 * If the attribute was already set, clear out the
931 * existing value and release the memory.
933 if (*dest != NULL) {
934 cleanup_cert_attr(*dest);
935 } else {
936 *dest = malloc(sizeof (cert_attr_t));
937 if (*dest == NULL) {
938 return (CKR_HOST_MEMORY);
940 (void) memset(*dest, 0, sizeof (cert_attr_t));
942 (*dest)->value = malloc(src->ulValueLen);
943 if ((*dest)->value == NULL) {
944 free(*dest);
945 *dest = NULL;
946 return (CKR_HOST_MEMORY);
948 (void) memcpy((*dest)->value, src->pValue, src->ulValueLen);
949 (*dest)->length = src->ulValueLen;
952 return (CKR_OK);
956 * Copy the certificate attribute information to the template.
957 * If the template attribute is not big enough, set the ulValueLen=-1
958 * and return CKR_BUFFER_TOO_SMALL.
960 static CK_RV
961 get_cert_attr_from_object(cert_attr_t *src, CK_ATTRIBUTE_PTR template)
963 if (template->pValue == NULL) {
964 template->ulValueLen = src->length;
965 return (CKR_OK);
966 } else if (template->ulValueLen >= src->length) {
968 * The buffer provided by the application is large
969 * enough to hold the value of the attribute.
971 (void) memcpy(template->pValue, src->value, src->length);
972 template->ulValueLen = src->length;
973 return (CKR_OK);
974 } else {
976 * The buffer provided by the application does
977 * not have enough space to hold the value.
979 template->ulValueLen = (CK_ULONG)-1;
980 return (CKR_BUFFER_TOO_SMALL);
984 void
985 string_attr_cleanup(CK_ATTRIBUTE_PTR template)
987 freezero(template->pValue, template->ulValueLen);
988 template->pValue = NULL;
989 template->ulValueLen = 0;
993 * Release the storage allocated for object attribute with big integer
994 * value.
996 void
997 bigint_attr_cleanup(biginteger_t *big)
1000 if (big == NULL)
1001 return;
1003 freezero(big->big_value, big->big_value_len);
1004 big->big_value = NULL;
1005 big->big_value_len = 0;
1010 * Clean up and release all the storage allocated to hold the big integer
1011 * attributes associated with the type (i.e. class) of the object. Also,
1012 * release the storage allocated to the type of the object.
1014 void
1015 soft_cleanup_object_bigint_attrs(soft_object_t *object_p)
1018 CK_OBJECT_CLASS class = object_p->class;
1019 CK_KEY_TYPE keytype = object_p->key_type;
1022 switch (class) {
1023 case CKO_PUBLIC_KEY:
1024 if (OBJ_PUB(object_p)) {
1025 switch (keytype) {
1026 case CKK_RSA:
1027 bigint_attr_cleanup(OBJ_PUB_RSA_MOD(
1028 object_p));
1029 bigint_attr_cleanup(OBJ_PUB_RSA_PUBEXPO(
1030 object_p));
1031 break;
1033 case CKK_DSA:
1034 bigint_attr_cleanup(OBJ_PUB_DSA_PRIME(
1035 object_p));
1036 bigint_attr_cleanup(OBJ_PUB_DSA_SUBPRIME(
1037 object_p));
1038 bigint_attr_cleanup(OBJ_PUB_DSA_BASE(
1039 object_p));
1040 bigint_attr_cleanup(OBJ_PUB_DSA_VALUE(
1041 object_p));
1042 break;
1044 case CKK_DH:
1045 bigint_attr_cleanup(OBJ_PUB_DH_PRIME(
1046 object_p));
1047 bigint_attr_cleanup(OBJ_PUB_DH_BASE(
1048 object_p));
1049 bigint_attr_cleanup(OBJ_PUB_DH_VALUE(
1050 object_p));
1051 break;
1053 case CKK_X9_42_DH:
1054 bigint_attr_cleanup(OBJ_PUB_DH942_PRIME(
1055 object_p));
1056 bigint_attr_cleanup(OBJ_PUB_DH942_BASE(
1057 object_p));
1058 bigint_attr_cleanup(OBJ_PUB_DH942_SUBPRIME(
1059 object_p));
1060 bigint_attr_cleanup(OBJ_PUB_DH942_VALUE(
1061 object_p));
1062 break;
1063 case CKK_EC:
1064 bigint_attr_cleanup(OBJ_PUB_EC_POINT(
1065 object_p));
1066 break;
1069 /* Release Public Key Object struct */
1070 free(OBJ_PUB(object_p));
1071 OBJ_PUB(object_p) = NULL;
1073 break;
1075 case CKO_PRIVATE_KEY:
1076 if (OBJ_PRI(object_p)) {
1077 switch (keytype) {
1078 case CKK_RSA:
1079 bigint_attr_cleanup(OBJ_PRI_RSA_MOD(
1080 object_p));
1081 bigint_attr_cleanup(OBJ_PRI_RSA_PUBEXPO(
1082 object_p));
1083 bigint_attr_cleanup(OBJ_PRI_RSA_PRIEXPO(
1084 object_p));
1085 bigint_attr_cleanup(OBJ_PRI_RSA_PRIME1(
1086 object_p));
1087 bigint_attr_cleanup(OBJ_PRI_RSA_PRIME2(
1088 object_p));
1089 bigint_attr_cleanup(OBJ_PRI_RSA_EXPO1(
1090 object_p));
1091 bigint_attr_cleanup(OBJ_PRI_RSA_EXPO2(
1092 object_p));
1093 bigint_attr_cleanup(OBJ_PRI_RSA_COEF(
1094 object_p));
1095 break;
1097 case CKK_DSA:
1098 bigint_attr_cleanup(OBJ_PRI_DSA_PRIME(
1099 object_p));
1100 bigint_attr_cleanup(OBJ_PRI_DSA_SUBPRIME(
1101 object_p));
1102 bigint_attr_cleanup(OBJ_PRI_DSA_BASE(
1103 object_p));
1104 bigint_attr_cleanup(OBJ_PRI_DSA_VALUE(
1105 object_p));
1106 break;
1108 case CKK_DH:
1109 bigint_attr_cleanup(OBJ_PRI_DH_PRIME(
1110 object_p));
1111 bigint_attr_cleanup(OBJ_PRI_DH_BASE(
1112 object_p));
1113 bigint_attr_cleanup(OBJ_PRI_DH_VALUE(
1114 object_p));
1115 break;
1117 case CKK_X9_42_DH:
1118 bigint_attr_cleanup(OBJ_PRI_DH942_PRIME(
1119 object_p));
1120 bigint_attr_cleanup(OBJ_PRI_DH942_BASE(
1121 object_p));
1122 bigint_attr_cleanup(OBJ_PRI_DH942_SUBPRIME(
1123 object_p));
1124 bigint_attr_cleanup(OBJ_PRI_DH942_VALUE(
1125 object_p));
1126 break;
1128 case CKK_EC:
1129 bigint_attr_cleanup(OBJ_PRI_EC_VALUE(
1130 object_p));
1131 break;
1134 /* Release Private Key Object struct. */
1135 free(OBJ_PRI(object_p));
1136 OBJ_PRI(object_p) = NULL;
1138 break;
1140 case CKO_SECRET_KEY:
1141 if (OBJ_SEC(object_p)) {
1142 /* cleanup key data area */
1143 if (OBJ_SEC_VALUE(object_p) != NULL &&
1144 OBJ_SEC_VALUE_LEN(object_p) > 0) {
1145 freezero(OBJ_SEC_VALUE(object_p),
1146 OBJ_SEC_VALUE_LEN(object_p));
1148 /* cleanup key schedule data area */
1149 if (OBJ_KEY_SCHED(object_p) != NULL &&
1150 OBJ_KEY_SCHED_LEN(object_p) > 0) {
1151 freezero(OBJ_KEY_SCHED(object_p),
1152 OBJ_KEY_SCHED_LEN(object_p));
1155 /* Release Secret Key Object struct. */
1156 free(OBJ_SEC(object_p));
1157 OBJ_SEC(object_p) = NULL;
1159 break;
1161 case CKO_DOMAIN_PARAMETERS:
1162 if (OBJ_DOM(object_p)) {
1163 switch (keytype) {
1164 case CKK_DSA:
1165 bigint_attr_cleanup(OBJ_DOM_DSA_PRIME(
1166 object_p));
1167 bigint_attr_cleanup(OBJ_DOM_DSA_SUBPRIME(
1168 object_p));
1169 bigint_attr_cleanup(OBJ_DOM_DSA_BASE(
1170 object_p));
1171 break;
1173 case CKK_DH:
1174 bigint_attr_cleanup(OBJ_DOM_DH_PRIME(
1175 object_p));
1176 bigint_attr_cleanup(OBJ_DOM_DH_BASE(
1177 object_p));
1178 break;
1180 case CKK_X9_42_DH:
1181 bigint_attr_cleanup(OBJ_DOM_DH942_PRIME(
1182 object_p));
1183 bigint_attr_cleanup(OBJ_DOM_DH942_BASE(
1184 object_p));
1185 bigint_attr_cleanup(OBJ_DOM_DH942_SUBPRIME(
1186 object_p));
1187 break;
1190 /* Release Domain Parameters Object struct. */
1191 free(OBJ_DOM(object_p));
1192 OBJ_DOM(object_p) = NULL;
1194 break;
1200 * Parse the common attributes. Return to caller with appropriate return
1201 * value to indicate if the supplied template specifies a valid attribute
1202 * with a valid value.
1204 CK_RV
1205 soft_parse_common_attrs(CK_ATTRIBUTE_PTR template, uchar_t *object_type)
1208 CK_RV rv = CKR_OK;
1210 switch (template->type) {
1211 case CKA_CLASS:
1212 break;
1214 /* default boolean attributes */
1215 case CKA_TOKEN:
1216 if ((*(CK_BBOOL *)template->pValue) == B_TRUE) {
1217 if (!soft_keystore_status(KEYSTORE_INITIALIZED))
1218 return (CKR_DEVICE_REMOVED);
1219 *object_type |= TOKEN_OBJECT;
1221 break;
1223 case CKA_PRIVATE:
1224 if ((*(CK_BBOOL *)template->pValue) == B_TRUE) {
1225 (void) pthread_mutex_lock(&soft_giant_mutex);
1226 if (!soft_slot.authenticated) {
1228 * Check if this is the special case when
1229 * the PIN is never initialized in the keystore.
1230 * If true, we will let it pass here and let
1231 * it fail with CKR_PIN_EXPIRED later on.
1233 if (!soft_slot.userpin_change_needed) {
1234 (void) pthread_mutex_unlock(
1235 &soft_giant_mutex);
1236 return (CKR_USER_NOT_LOGGED_IN);
1239 (void) pthread_mutex_unlock(&soft_giant_mutex);
1240 *object_type |= PRIVATE_OBJECT;
1242 break;
1244 case CKA_LABEL:
1245 break;
1247 default:
1248 rv = CKR_TEMPLATE_INCONSISTENT;
1251 return (rv);
1256 * Build a Public Key Object.
1258 * - Parse the object's template, and when an error is detected such as
1259 * invalid attribute type, invalid attribute value, etc., return
1260 * with appropriate return value.
1261 * - Set up attribute mask field in the object for the supplied common
1262 * attributes that have boolean type.
1263 * - Build the attribute_info struct to hold the value of each supplied
1264 * attribute that has byte array type. Link attribute_info structs
1265 * together to form the extra attribute list of the object.
1266 * - Allocate storage for the Public Key object.
1267 * - Build the Public Key object according to the key type. Allocate
1268 * storage to hold the big integer value for the supplied attributes
1269 * that are required for a certain key type.
1272 CK_RV
1273 soft_build_public_key_object(CK_ATTRIBUTE_PTR template, CK_ULONG ulAttrNum,
1274 soft_object_t *new_object, CK_ULONG mode, CK_KEY_TYPE key_type)
1277 ulong_t i;
1278 CK_KEY_TYPE keytype = (CK_KEY_TYPE)~0UL;
1279 uint64_t attr_mask = PUBLIC_KEY_DEFAULT;
1280 CK_RV rv = CKR_OK;
1281 int isLabel = 0;
1282 /* Must set flags */
1283 int isModulus = 0;
1284 int isPubExpo = 0;
1285 int isPrime = 0;
1286 int isSubprime = 0;
1287 int isBase = 0;
1288 int isValue = 0;
1289 int isECParam = 0;
1290 int isECPoint = 0;
1291 /* Must not set flags */
1292 int isModulusBits = 0;
1293 CK_ULONG modulus_bits = 0;
1295 biginteger_t modulus;
1296 biginteger_t pubexpo;
1297 biginteger_t prime;
1298 biginteger_t subprime;
1299 biginteger_t base;
1300 biginteger_t value;
1301 biginteger_t point;
1302 CK_ATTRIBUTE string_tmp;
1303 CK_ATTRIBUTE param_tmp;
1305 public_key_obj_t *pbk;
1306 uchar_t object_type = 0;
1308 CK_ATTRIBUTE defpubexpo = { CKA_PUBLIC_EXPONENT,
1309 (CK_BYTE_PTR)DEFAULT_PUB_EXPO, DEFAULT_PUB_EXPO_Len };
1311 BIGNUM n;
1313 /* prevent bigint_attr_cleanup from freeing invalid attr value */
1314 (void) memset(&modulus, 0x0, sizeof (biginteger_t));
1315 (void) memset(&pubexpo, 0x0, sizeof (biginteger_t));
1316 (void) memset(&prime, 0x0, sizeof (biginteger_t));
1317 (void) memset(&subprime, 0x0, sizeof (biginteger_t));
1318 (void) memset(&base, 0x0, sizeof (biginteger_t));
1319 (void) memset(&value, 0x0, sizeof (biginteger_t));
1320 (void) memset(&point, 0x0, sizeof (biginteger_t));
1321 string_tmp.pValue = NULL;
1322 param_tmp.pValue = NULL;
1324 for (i = 0; i < ulAttrNum; i++) {
1326 /* Public Key Object Attributes */
1327 switch (template[i].type) {
1329 /* common key attributes */
1330 case CKA_KEY_TYPE:
1331 keytype = *((CK_KEY_TYPE*)template[i].pValue);
1332 break;
1334 case CKA_ID:
1335 case CKA_START_DATE:
1336 case CKA_END_DATE:
1338 /* common public key attribute */
1339 case CKA_SUBJECT:
1341 * Allocate storage to hold the attribute
1342 * value with byte array type, and add it to
1343 * the extra attribute list of the object.
1345 rv = soft_add_extra_attr(&template[i],
1346 new_object);
1347 if (rv != CKR_OK) {
1348 goto fail_cleanup;
1350 break;
1353 * The following key related attribute types must
1354 * not be specified by C_CreateObject, C_GenerateKey(Pair).
1356 case CKA_LOCAL:
1357 case CKA_KEY_GEN_MECHANISM:
1358 rv = CKR_TEMPLATE_INCONSISTENT;
1359 goto fail_cleanup;
1361 /* Key related boolean attributes */
1362 case CKA_DERIVE:
1363 if (*(CK_BBOOL *)template[i].pValue)
1364 attr_mask |= DERIVE_BOOL_ON;
1365 break;
1367 case CKA_ENCRYPT:
1368 if (*(CK_BBOOL *)template[i].pValue)
1369 attr_mask |= ENCRYPT_BOOL_ON;
1370 else
1371 attr_mask &= ~ENCRYPT_BOOL_ON;
1372 break;
1374 case CKA_VERIFY:
1375 if (*(CK_BBOOL *)template[i].pValue)
1376 attr_mask |= VERIFY_BOOL_ON;
1377 else
1378 attr_mask &= ~VERIFY_BOOL_ON;
1379 break;
1381 case CKA_VERIFY_RECOVER:
1382 if (*(CK_BBOOL *)template[i].pValue)
1383 attr_mask |= VERIFY_RECOVER_BOOL_ON;
1384 else
1385 attr_mask &= ~VERIFY_RECOVER_BOOL_ON;
1386 break;
1388 case CKA_WRAP:
1389 if (*(CK_BBOOL *)template[i].pValue)
1390 attr_mask |= WRAP_BOOL_ON;
1391 else
1392 attr_mask &= ~WRAP_BOOL_ON;
1393 break;
1395 case CKA_TRUSTED:
1396 if (*(CK_BBOOL *)template[i].pValue)
1397 attr_mask |= TRUSTED_BOOL_ON;
1398 break;
1400 case CKA_MODIFIABLE:
1401 if ((*(CK_BBOOL *)template[i].pValue) == B_FALSE)
1402 attr_mask |= NOT_MODIFIABLE_BOOL_ON;
1403 break;
1406 * The following key related attribute types must
1407 * be specified according to the key type by
1408 * C_CreateObject.
1410 case CKA_MODULUS:
1412 isModulus = 1;
1414 * Copyin big integer attribute from template
1415 * to a local variable.
1417 rv = get_bigint_attr_from_template(&modulus,
1418 &template[i]);
1419 if (rv != CKR_OK)
1420 goto fail_cleanup;
1423 * Modulus length needs to be between min key length and
1424 * max key length.
1426 if ((modulus.big_value_len <
1427 MIN_RSA_KEYLENGTH_IN_BYTES) ||
1428 (modulus.big_value_len >
1429 MAX_RSA_KEYLENGTH_IN_BYTES)) {
1430 rv = CKR_ATTRIBUTE_VALUE_INVALID;
1431 goto fail_cleanup;
1433 break;
1435 case CKA_PUBLIC_EXPONENT:
1436 isPubExpo = 1;
1437 rv = get_bigint_attr_from_template(&pubexpo,
1438 &template[i]);
1439 if (rv != CKR_OK)
1440 goto fail_cleanup;
1441 break;
1443 case CKA_PRIME:
1444 isPrime = 1;
1445 rv = get_bigint_attr_from_template(&prime,
1446 &template[i]);
1447 if (rv != CKR_OK)
1448 goto fail_cleanup;
1449 break;
1451 case CKA_SUBPRIME:
1452 isSubprime = 1;
1453 rv = get_bigint_attr_from_template(&subprime,
1454 &template[i]);
1455 if (rv != CKR_OK)
1456 goto fail_cleanup;
1457 break;
1459 case CKA_BASE:
1460 isBase = 1;
1461 rv = get_bigint_attr_from_template(&base,
1462 &template[i]);
1463 if (rv != CKR_OK)
1464 goto fail_cleanup;
1465 break;
1467 case CKA_VALUE:
1468 isValue = 1;
1469 if (mode == SOFT_CREATE_OBJ) {
1470 if ((template[i].ulValueLen == 0) ||
1471 (template[i].pValue == NULL)) {
1472 rv = CKR_ATTRIBUTE_VALUE_INVALID;
1473 goto fail_cleanup;
1477 rv = get_bigint_attr_from_template(&value,
1478 &template[i]);
1479 if (rv != CKR_OK)
1480 goto fail_cleanup;
1481 break;
1483 case CKA_MODULUS_BITS:
1484 isModulusBits = 1;
1485 rv = get_ulong_attr_from_template(&modulus_bits,
1486 &template[i]);
1487 if (rv != CKR_OK)
1488 goto fail_cleanup;
1489 break;
1491 case CKA_LABEL:
1492 isLabel = 1;
1493 rv = get_string_from_template(&string_tmp,
1494 &template[i]);
1495 if (rv != CKR_OK)
1496 goto fail_cleanup;
1497 break;
1499 case CKA_EC_PARAMS:
1500 isECParam = 1;
1501 rv = get_string_from_template(&param_tmp, &template[i]);
1502 if (rv != CKR_OK)
1503 goto fail_cleanup;
1504 break;
1506 case CKA_EC_POINT:
1507 isECPoint = 1;
1508 rv = get_bigint_attr_from_template(&point,
1509 &template[i]);
1510 if (rv != CKR_OK)
1511 goto fail_cleanup;
1512 break;
1514 default:
1515 rv = soft_parse_common_attrs(&template[i],
1516 &object_type);
1517 if (rv != CKR_OK)
1518 goto fail_cleanup;
1519 break;
1521 } /* For */
1523 /* Allocate storage for Public Key Object. */
1524 pbk = calloc(1, sizeof (public_key_obj_t));
1525 if (pbk == NULL) {
1526 rv = CKR_HOST_MEMORY;
1527 goto fail_cleanup;
1530 new_object->object_class_u.public_key = pbk;
1531 new_object->class = CKO_PUBLIC_KEY;
1533 if ((mode == SOFT_CREATE_OBJ) && (keytype == (CK_KEY_TYPE)~0UL)) {
1534 rv = CKR_TEMPLATE_INCOMPLETE;
1535 goto fail_cleanup;
1538 if ((mode == SOFT_GEN_KEY) && (keytype == (CK_KEY_TYPE)~0UL)) {
1539 keytype = key_type;
1542 if ((mode == SOFT_GEN_KEY) && (keytype != key_type)) {
1544 * The key type specified in the template does not
1545 * match the implied key type based on the mechanism.
1547 rv = CKR_TEMPLATE_INCONSISTENT;
1548 goto fail_cleanup;
1551 new_object->key_type = keytype;
1553 /* Supported key types of the Public Key Object */
1554 switch (keytype) {
1556 case CKK_RSA:
1557 if (mode == SOFT_CREATE_OBJ) {
1558 if (isModulusBits || isPrime || isSubprime ||
1559 isBase || isValue) {
1560 rv = CKR_TEMPLATE_INCONSISTENT;
1561 goto fail_cleanup;
1564 if (isModulus && isPubExpo) {
1566 * Derive modulus_bits attribute from modulus.
1567 * Save modulus_bits integer value to the
1568 * designated place in the public key object.
1570 n.malloced = 0;
1571 #ifdef __sparcv9
1572 if (big_init(&n, (int)CHARLEN2BIGNUMLEN(
1573 modulus.big_value_len)) != BIG_OK) {
1574 #else /* !__sparcv9 */
1575 if (big_init(&n, CHARLEN2BIGNUMLEN(
1576 modulus.big_value_len)) != BIG_OK) {
1577 #endif /* __sparcv9 */
1578 rv = CKR_HOST_MEMORY;
1579 big_finish(&n);
1580 goto fail_cleanup;
1582 bytestring2bignum(&n, modulus.big_value,
1583 modulus.big_value_len);
1585 modulus_bits = big_bitlength(&n);
1586 KEY_PUB_RSA_MOD_BITS(pbk) = modulus_bits;
1587 big_finish(&n);
1590 * After modulus_bits has been computed,
1591 * it is safe to move modulus and pubexpo
1592 * big integer attribute value to the
1593 * designated place in the public key object.
1595 copy_bigint_attr(&modulus,
1596 KEY_PUB_RSA_MOD(pbk));
1598 copy_bigint_attr(&pubexpo,
1599 KEY_PUB_RSA_PUBEXPO(pbk));
1600 } else {
1601 rv = CKR_TEMPLATE_INCOMPLETE;
1602 goto fail_cleanup;
1604 } else {
1605 /* mode is SOFT_GEN_KEY */
1607 if (isModulus || isPrime || isSubprime ||
1608 isBase || isValue) {
1609 rv = CKR_TEMPLATE_INCONSISTENT;
1610 goto fail_cleanup;
1614 if (isModulusBits) {
1616 * Copy big integer attribute value to the
1617 * designated place in the public key object.
1619 KEY_PUB_RSA_MOD_BITS(pbk) = modulus_bits;
1620 } else {
1621 rv = CKR_TEMPLATE_INCOMPLETE;
1622 goto fail_cleanup;
1626 * Use PKCS#11 default 0x010001 for public exponent
1627 * if not not specified in attribute template.
1629 if (!isPubExpo) {
1630 isPubExpo = 1;
1631 rv = get_bigint_attr_from_template(&pubexpo,
1632 &defpubexpo);
1633 if (rv != CKR_OK)
1634 goto fail_cleanup;
1637 * Copy big integer attribute value to the
1638 * designated place in the public key object.
1640 copy_bigint_attr(&pubexpo, KEY_PUB_RSA_PUBEXPO(pbk));
1643 break;
1645 case CKK_DSA:
1646 if (mode == SOFT_CREATE_OBJ) {
1647 if (isModulusBits || isModulus || isPubExpo) {
1648 rv = CKR_TEMPLATE_INCONSISTENT;
1649 goto fail_cleanup;
1652 if (isPrime && isSubprime && isBase && isValue) {
1653 copy_bigint_attr(&value,
1654 KEY_PUB_DSA_VALUE(pbk));
1655 } else {
1656 rv = CKR_TEMPLATE_INCOMPLETE;
1657 goto fail_cleanup;
1659 } else {
1660 if (isModulusBits || isModulus || isPubExpo ||
1661 isValue) {
1662 rv = CKR_TEMPLATE_INCONSISTENT;
1663 goto fail_cleanup;
1666 if (!(isPrime && isSubprime && isBase)) {
1667 rv = CKR_TEMPLATE_INCOMPLETE;
1668 goto fail_cleanup;
1672 copy_bigint_attr(&prime, KEY_PUB_DSA_PRIME(pbk));
1674 copy_bigint_attr(&subprime, KEY_PUB_DSA_SUBPRIME(pbk));
1676 copy_bigint_attr(&base, KEY_PUB_DSA_BASE(pbk));
1678 break;
1680 case CKK_DH:
1681 if (mode == SOFT_CREATE_OBJ) {
1682 if (isModulusBits || isModulus || isPubExpo ||
1683 isSubprime) {
1684 rv = CKR_TEMPLATE_INCONSISTENT;
1685 goto fail_cleanup;
1688 if (isPrime && isBase && isValue) {
1689 copy_bigint_attr(&value,
1690 KEY_PUB_DH_VALUE(pbk));
1691 } else {
1692 rv = CKR_TEMPLATE_INCOMPLETE;
1693 goto fail_cleanup;
1695 } else {
1696 if (isModulusBits || isModulus || isPubExpo ||
1697 isSubprime || isValue) {
1698 rv = CKR_TEMPLATE_INCONSISTENT;
1699 goto fail_cleanup;
1702 if (!(isPrime && isBase)) {
1703 rv = CKR_TEMPLATE_INCOMPLETE;
1704 goto fail_cleanup;
1708 copy_bigint_attr(&prime, KEY_PUB_DH_PRIME(pbk));
1710 copy_bigint_attr(&base, KEY_PUB_DH_BASE(pbk));
1712 break;
1714 case CKK_X9_42_DH:
1715 if (mode == SOFT_CREATE_OBJ) {
1716 if (isModulusBits || isModulus || isPubExpo) {
1717 rv = CKR_TEMPLATE_INCONSISTENT;
1718 goto fail_cleanup;
1721 if (isPrime && isSubprime && isBase && isValue) {
1722 copy_bigint_attr(&value,
1723 KEY_PUB_DH942_VALUE(pbk));
1724 } else {
1725 rv = CKR_TEMPLATE_INCOMPLETE;
1726 goto fail_cleanup;
1728 } else {
1729 if (isModulusBits || isModulus || isPubExpo ||
1730 isValue) {
1731 rv = CKR_TEMPLATE_INCONSISTENT;
1732 goto fail_cleanup;
1735 if (!(isPrime && isSubprime && isBase)) {
1736 rv = CKR_TEMPLATE_INCOMPLETE;
1737 goto fail_cleanup;
1741 copy_bigint_attr(&prime, KEY_PUB_DH942_PRIME(pbk));
1743 copy_bigint_attr(&base, KEY_PUB_DH942_BASE(pbk));
1745 copy_bigint_attr(&subprime, KEY_PUB_DH942_SUBPRIME(pbk));
1747 break;
1749 case CKK_EC:
1750 if (mode == SOFT_CREATE_OBJ) {
1751 if (isModulusBits || isModulus || isPubExpo ||
1752 isPrime || isSubprime || isBase || isValue) {
1753 rv = CKR_TEMPLATE_INCONSISTENT;
1754 goto fail_cleanup;
1756 } else if (!isECParam || !isECPoint) {
1757 rv = CKR_TEMPLATE_INCOMPLETE;
1758 goto fail_cleanup;
1760 } else {
1761 if (isModulusBits || isModulus || isPubExpo ||
1762 isPrime || isSubprime || isBase || isValue) {
1763 rv = CKR_TEMPLATE_INCONSISTENT;
1764 goto fail_cleanup;
1766 } else if (!isECParam) {
1767 rv = CKR_TEMPLATE_INCOMPLETE;
1768 goto fail_cleanup;
1772 if (isECPoint) {
1773 copy_bigint_attr(&point, KEY_PUB_EC_POINT(pbk));
1775 rv = soft_add_extra_attr(&param_tmp, new_object);
1776 if (rv != CKR_OK)
1777 goto fail_cleanup;
1778 string_attr_cleanup(&param_tmp);
1779 break;
1781 default:
1782 rv = CKR_TEMPLATE_INCONSISTENT;
1783 goto fail_cleanup;
1786 /* Set up object. */
1787 new_object->object_type = object_type;
1788 new_object->bool_attr_mask = attr_mask;
1789 if (isLabel) {
1790 rv = soft_add_extra_attr(&string_tmp, new_object);
1791 if (rv != CKR_OK)
1792 goto fail_cleanup;
1793 string_attr_cleanup(&string_tmp);
1796 return (rv);
1798 fail_cleanup:
1800 * cleanup the storage allocated to the local variables.
1802 bigint_attr_cleanup(&modulus);
1803 bigint_attr_cleanup(&pubexpo);
1804 bigint_attr_cleanup(&prime);
1805 bigint_attr_cleanup(&subprime);
1806 bigint_attr_cleanup(&base);
1807 bigint_attr_cleanup(&value);
1808 bigint_attr_cleanup(&point);
1809 string_attr_cleanup(&string_tmp);
1810 string_attr_cleanup(&param_tmp);
1813 * cleanup the storage allocated inside the object itself.
1815 soft_cleanup_object(new_object);
1817 return (rv);
1822 * Build a Private Key Object.
1824 * - Parse the object's template, and when an error is detected such as
1825 * invalid attribute type, invalid attribute value, etc., return
1826 * with appropriate return value.
1827 * - Set up attribute mask field in the object for the supplied common
1828 * attributes that have boolean type.
1829 * - Build the attribute_info struct to hold the value of each supplied
1830 * attribute that has byte array type. Link attribute_info structs
1831 * together to form the extra attribute list of the object.
1832 * - Allocate storage for the Private Key object.
1833 * - Build the Private Key object according to the key type. Allocate
1834 * storage to hold the big integer value for the supplied attributes
1835 * that are required for a certain key type.
1838 CK_RV
1839 soft_build_private_key_object(CK_ATTRIBUTE_PTR template, CK_ULONG ulAttrNum,
1840 soft_object_t *new_object, CK_ULONG mode, CK_KEY_TYPE key_type)
1842 ulong_t i;
1843 CK_KEY_TYPE keytype = (CK_KEY_TYPE)~0UL;
1844 uint64_t attr_mask = PRIVATE_KEY_DEFAULT;
1845 CK_RV rv = CKR_OK;
1846 int isLabel = 0;
1847 int isECParam = 0;
1848 /* Must set flags unless mode == SOFT_UNWRAP_KEY */
1849 int isModulus = 0;
1850 int isPriExpo = 0;
1851 int isPrime = 0;
1852 int isSubprime = 0;
1853 int isBase = 0;
1854 /* Must set flags if mode == SOFT_GEN_KEY */
1855 int isValue = 0;
1856 /* Must not set flags */
1857 int isValueBits = 0;
1858 CK_ULONG value_bits = 0;
1860 /* Private Key RSA optional */
1861 int isPubExpo = 0;
1862 int isPrime1 = 0;
1863 int isPrime2 = 0;
1864 int isExpo1 = 0;
1865 int isExpo2 = 0;
1866 int isCoef = 0;
1868 biginteger_t modulus;
1869 biginteger_t priexpo;
1870 biginteger_t prime;
1871 biginteger_t subprime;
1872 biginteger_t base;
1873 biginteger_t value;
1875 biginteger_t pubexpo;
1876 biginteger_t prime1;
1877 biginteger_t prime2;
1878 biginteger_t expo1;
1879 biginteger_t expo2;
1880 biginteger_t coef;
1881 CK_ATTRIBUTE string_tmp;
1882 CK_ATTRIBUTE param_tmp;
1883 BIGNUM x, q;
1885 private_key_obj_t *pvk;
1886 uchar_t object_type = 0;
1888 /* prevent bigint_attr_cleanup from freeing invalid attr value */
1889 (void) memset(&modulus, 0x0, sizeof (biginteger_t));
1890 (void) memset(&priexpo, 0x0, sizeof (biginteger_t));
1891 (void) memset(&prime, 0x0, sizeof (biginteger_t));
1892 (void) memset(&subprime, 0x0, sizeof (biginteger_t));
1893 (void) memset(&base, 0x0, sizeof (biginteger_t));
1894 (void) memset(&value, 0x0, sizeof (biginteger_t));
1895 (void) memset(&pubexpo, 0x0, sizeof (biginteger_t));
1896 (void) memset(&prime1, 0x0, sizeof (biginteger_t));
1897 (void) memset(&prime2, 0x0, sizeof (biginteger_t));
1898 (void) memset(&expo1, 0x0, sizeof (biginteger_t));
1899 (void) memset(&expo2, 0x0, sizeof (biginteger_t));
1900 (void) memset(&coef, 0x0, sizeof (biginteger_t));
1901 string_tmp.pValue = NULL;
1902 param_tmp.pValue = NULL;
1903 x.malloced = 0;
1904 q.malloced = 0;
1906 for (i = 0; i < ulAttrNum; i++) {
1908 /* Private Key Object Attributes */
1909 switch (template[i].type) {
1910 /* common key attributes */
1911 case CKA_KEY_TYPE:
1912 keytype = *((CK_KEY_TYPE*)template[i].pValue);
1913 break;
1915 case CKA_ID:
1916 case CKA_START_DATE:
1917 case CKA_END_DATE:
1919 /* common private key attribute */
1920 case CKA_SUBJECT:
1922 * Allocate storage to hold the attribute
1923 * value with byte array type, and add it to
1924 * the extra attribute list of the object.
1926 rv = soft_add_extra_attr(&template[i],
1927 new_object);
1928 if (rv != CKR_OK) {
1929 goto fail_cleanup;
1931 break;
1934 * The following key related attribute types must
1935 * not be specified by C_CreateObject or C_GenerateKey(Pair).
1937 case CKA_LOCAL:
1938 case CKA_KEY_GEN_MECHANISM:
1939 case CKA_AUTH_PIN_FLAGS:
1940 case CKA_ALWAYS_SENSITIVE:
1941 case CKA_NEVER_EXTRACTABLE:
1942 rv = CKR_TEMPLATE_INCONSISTENT;
1943 goto fail_cleanup;
1945 /* Key related boolean attributes */
1946 case CKA_DERIVE:
1947 if (*(CK_BBOOL *)template[i].pValue)
1948 attr_mask |= DERIVE_BOOL_ON;
1949 break;
1951 case CKA_SENSITIVE:
1952 if (*(CK_BBOOL *)template[i].pValue)
1953 attr_mask |= SENSITIVE_BOOL_ON;
1954 break;
1956 case CKA_SECONDARY_AUTH:
1957 if (*(CK_BBOOL *)template[i].pValue) {
1958 rv = CKR_ATTRIBUTE_VALUE_INVALID;
1959 goto fail_cleanup;
1961 break;
1963 case CKA_DECRYPT:
1964 if (*(CK_BBOOL *)template[i].pValue)
1965 attr_mask |= DECRYPT_BOOL_ON;
1966 else
1967 attr_mask &= ~DECRYPT_BOOL_ON;
1968 break;
1970 case CKA_SIGN:
1971 if (*(CK_BBOOL *)template[i].pValue)
1972 attr_mask |= SIGN_BOOL_ON;
1973 else
1974 attr_mask &= ~SIGN_BOOL_ON;
1975 break;
1977 case CKA_SIGN_RECOVER:
1978 if (*(CK_BBOOL *)template[i].pValue)
1979 attr_mask |= SIGN_RECOVER_BOOL_ON;
1980 else
1981 attr_mask &= ~SIGN_RECOVER_BOOL_ON;
1982 break;
1984 case CKA_UNWRAP:
1985 if (*(CK_BBOOL *)template[i].pValue)
1986 attr_mask |= UNWRAP_BOOL_ON;
1987 else
1988 attr_mask &= ~UNWRAP_BOOL_ON;
1989 break;
1991 case CKA_EXTRACTABLE:
1992 if (*(CK_BBOOL *)template[i].pValue)
1993 attr_mask |= EXTRACTABLE_BOOL_ON;
1994 else
1995 attr_mask &= ~EXTRACTABLE_BOOL_ON;
1996 break;
1998 case CKA_MODIFIABLE:
1999 if ((*(CK_BBOOL *)template[i].pValue) == B_FALSE)
2000 attr_mask |= NOT_MODIFIABLE_BOOL_ON;
2001 break;
2004 * The following key related attribute types must
2005 * be specified according to the key type by
2006 * C_CreateObject.
2008 case CKA_MODULUS:
2010 isModulus = 1;
2012 * Copyin big integer attribute from template
2013 * to a local variable.
2015 rv = get_bigint_attr_from_template(&modulus,
2016 &template[i]);
2017 if (rv != CKR_OK)
2018 goto fail_cleanup;
2021 * Modulus length needs to be between min key length and
2022 * max key length.
2024 if ((modulus.big_value_len <
2025 MIN_RSA_KEYLENGTH_IN_BYTES) ||
2026 (modulus.big_value_len >
2027 MAX_RSA_KEYLENGTH_IN_BYTES)) {
2028 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2029 goto fail_cleanup;
2031 break;
2033 case CKA_PUBLIC_EXPONENT:
2035 isPubExpo = 1;
2036 rv = get_bigint_attr_from_template(&pubexpo,
2037 &template[i]);
2038 if (rv != CKR_OK)
2039 goto fail_cleanup;
2040 break;
2042 case CKA_PRIVATE_EXPONENT:
2044 isPriExpo = 1;
2045 rv = get_bigint_attr_from_template(&priexpo,
2046 &template[i]);
2047 if (rv != CKR_OK)
2048 goto fail_cleanup;
2049 break;
2051 case CKA_PRIME_1:
2052 isPrime1 = 1;
2053 rv = get_bigint_attr_from_template(&prime1,
2054 &template[i]);
2055 if (rv != CKR_OK)
2056 goto fail_cleanup;
2057 break;
2059 case CKA_PRIME_2:
2060 isPrime2 = 1;
2061 rv = get_bigint_attr_from_template(&prime2,
2062 &template[i]);
2063 if (rv != CKR_OK)
2064 goto fail_cleanup;
2065 break;
2067 case CKA_EXPONENT_1:
2068 isExpo1 = 1;
2069 rv = get_bigint_attr_from_template(&expo1,
2070 &template[i]);
2071 if (rv != CKR_OK)
2072 goto fail_cleanup;
2073 break;
2075 case CKA_EXPONENT_2:
2076 isExpo2 = 1;
2077 rv = get_bigint_attr_from_template(&expo2,
2078 &template[i]);
2079 if (rv != CKR_OK)
2080 goto fail_cleanup;
2081 break;
2083 case CKA_COEFFICIENT:
2084 isCoef = 1;
2085 rv = get_bigint_attr_from_template(&coef,
2086 &template[i]);
2087 if (rv != CKR_OK)
2088 goto fail_cleanup;
2089 break;
2091 case CKA_PRIME:
2092 isPrime = 1;
2093 rv = get_bigint_attr_from_template(&prime,
2094 &template[i]);
2095 if (rv != CKR_OK)
2096 goto fail_cleanup;
2097 break;
2099 case CKA_SUBPRIME:
2100 isSubprime = 1;
2101 rv = get_bigint_attr_from_template(&subprime,
2102 &template[i]);
2103 if (rv != CKR_OK)
2104 goto fail_cleanup;
2105 break;
2107 case CKA_BASE:
2108 isBase = 1;
2109 rv = get_bigint_attr_from_template(&base,
2110 &template[i]);
2111 if (rv != CKR_OK)
2112 goto fail_cleanup;
2113 break;
2115 case CKA_VALUE:
2116 isValue = 1;
2117 if (mode == SOFT_CREATE_OBJ) {
2118 if ((template[i].ulValueLen == 0) ||
2119 (template[i].pValue == NULL)) {
2120 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2121 goto fail_cleanup;
2125 rv = get_bigint_attr_from_template(&value,
2126 &template[i]);
2127 if (rv != CKR_OK)
2128 goto fail_cleanup;
2129 break;
2131 case CKA_VALUE_BITS:
2132 isValueBits = 1;
2133 rv = get_ulong_attr_from_template(&value_bits,
2134 &template[i]);
2135 if (rv != CKR_OK)
2136 goto fail_cleanup;
2137 break;
2139 case CKA_LABEL:
2140 isLabel = 1;
2141 rv = get_string_from_template(&string_tmp,
2142 &template[i]);
2143 if (rv != CKR_OK)
2144 goto fail_cleanup;
2145 break;
2147 case CKA_EC_PARAMS:
2148 isECParam = 1;
2149 rv = get_string_from_template(&param_tmp,
2150 &template[i]);
2151 if (rv != CKR_OK)
2152 goto fail_cleanup;
2153 break;
2155 default:
2156 rv = soft_parse_common_attrs(&template[i],
2157 &object_type);
2158 if (rv != CKR_OK)
2159 goto fail_cleanup;
2160 break;
2163 } /* For */
2165 /* Allocate storage for Private Key Object. */
2166 pvk = calloc(1, sizeof (private_key_obj_t));
2167 if (pvk == NULL) {
2168 rv = CKR_HOST_MEMORY;
2169 goto fail_cleanup;
2172 new_object->object_class_u.private_key = pvk;
2173 new_object->class = CKO_PRIVATE_KEY;
2175 if ((mode == SOFT_CREATE_OBJ) && (keytype == (CK_KEY_TYPE)~0UL)) {
2176 rv = CKR_TEMPLATE_INCOMPLETE;
2177 goto fail_cleanup;
2180 if (mode == SOFT_GEN_KEY) {
2182 * The key type is not specified in the application's
2183 * template, so we use the implied key type based on
2184 * the mechanism.
2186 if (keytype == (CK_KEY_TYPE)~0UL) {
2187 keytype = key_type;
2190 /* If still unspecified, template is incomplete */
2191 if (keytype == (CK_KEY_TYPE)~0UL) {
2192 rv = CKR_TEMPLATE_INCOMPLETE;
2193 goto fail_cleanup;
2197 * The key type specified in the template does not
2198 * match the implied key type based on the mechanism.
2200 if (keytype != key_type) {
2201 rv = CKR_TEMPLATE_INCONSISTENT;
2202 goto fail_cleanup;
2206 if (mode == SOFT_UNWRAP_KEY) {
2208 * Note that, for mode SOFT_UNWRAP_KEY, key type is not
2209 * implied by the mechanism (key_type), so if it is not
2210 * specified from the attribute template (keytype), it is
2211 * incomplete.
2213 if (keytype == (CK_KEY_TYPE)~0UL) {
2214 rv = CKR_TEMPLATE_INCOMPLETE;
2215 goto fail_cleanup;
2219 new_object->key_type = keytype;
2221 /* Supported key types of the Private Key Object */
2222 switch (keytype) {
2223 case CKK_RSA:
2224 if (isPrime || isSubprime || isBase || isValue ||
2225 isValueBits) {
2226 rv = CKR_TEMPLATE_INCONSISTENT;
2227 goto fail_cleanup;
2230 if (mode == SOFT_GEN_KEY || mode == SOFT_UNWRAP_KEY) {
2231 if (isModulus || isPubExpo || isPriExpo || isPrime1 ||
2232 isPrime2 || isExpo1 || isExpo2 || isCoef) {
2233 rv = CKR_TEMPLATE_INCONSISTENT;
2234 goto fail_cleanup;
2235 } else
2236 break;
2239 if (isModulus && isPriExpo) {
2241 * Copy big integer attribute value to the
2242 * designated place in the Private Key object.
2244 copy_bigint_attr(&modulus, KEY_PRI_RSA_MOD(pvk));
2246 copy_bigint_attr(&priexpo, KEY_PRI_RSA_PRIEXPO(pvk));
2247 } else {
2248 rv = CKR_TEMPLATE_INCOMPLETE;
2249 goto fail_cleanup;
2252 /* The following attributes are optional. */
2253 if (isPubExpo) {
2254 copy_bigint_attr(&pubexpo, KEY_PRI_RSA_PUBEXPO(pvk));
2257 if (isPrime1) {
2258 copy_bigint_attr(&prime1, KEY_PRI_RSA_PRIME1(pvk));
2261 if (isPrime2) {
2262 copy_bigint_attr(&prime2, KEY_PRI_RSA_PRIME2(pvk));
2265 if (isExpo1) {
2266 copy_bigint_attr(&expo1, KEY_PRI_RSA_EXPO1(pvk));
2269 if (isExpo2) {
2270 copy_bigint_attr(&expo2, KEY_PRI_RSA_EXPO2(pvk));
2273 if (isCoef) {
2274 copy_bigint_attr(&coef, KEY_PRI_RSA_COEF(pvk));
2276 break;
2278 case CKK_DSA:
2279 if (isModulus || isPubExpo || isPriExpo || isPrime1 ||
2280 isPrime2 || isExpo1 || isExpo2 || isCoef ||
2281 isValueBits) {
2282 rv = CKR_TEMPLATE_INCONSISTENT;
2283 goto fail_cleanup;
2286 if (mode == SOFT_GEN_KEY || mode == SOFT_UNWRAP_KEY) {
2287 if (isPrime || isSubprime || isBase || isValue) {
2288 rv = CKR_TEMPLATE_INCONSISTENT;
2289 goto fail_cleanup;
2290 } else
2291 break;
2294 if (isPrime && isSubprime && isBase && isValue) {
2296 * The private value x must be less than subprime q.
2297 * Size for big_init is in BIG_CHUNK_TYPE words.
2299 #ifdef __sparcv9
2300 if (big_init(&x,
2301 (int)CHARLEN2BIGNUMLEN(value.big_value_len))
2302 != BIG_OK) {
2303 #else /* !__sparcv9 */
2304 if (big_init(&x,
2305 CHARLEN2BIGNUMLEN(value.big_value_len))
2306 != BIG_OK) {
2307 #endif /* __sparcv9 */
2308 rv = CKR_HOST_MEMORY;
2309 goto fail_cleanup;
2311 #ifdef __sparcv9
2312 if (big_init(&q,
2313 (int)CHARLEN2BIGNUMLEN(subprime.big_value_len))
2314 != BIG_OK) {
2315 #else /* !__sparcv9 */
2316 if (big_init(&q,
2317 CHARLEN2BIGNUMLEN(subprime.big_value_len))
2318 != BIG_OK) {
2319 #endif /* __sparcv9 */
2320 rv = CKR_HOST_MEMORY;
2321 goto fail_cleanup;
2323 bytestring2bignum(&x, value.big_value,
2324 value.big_value_len);
2325 bytestring2bignum(&q, subprime.big_value,
2326 subprime.big_value_len);
2328 if (big_cmp_abs(&x, &q) > 0) {
2329 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2330 goto fail_cleanup;
2333 copy_bigint_attr(&prime, KEY_PRI_DSA_PRIME(pvk));
2335 copy_bigint_attr(&subprime, KEY_PRI_DSA_SUBPRIME(pvk));
2337 copy_bigint_attr(&base, KEY_PRI_DSA_BASE(pvk));
2339 copy_bigint_attr(&value, KEY_PRI_DSA_VALUE(pvk));
2340 } else {
2341 rv = CKR_TEMPLATE_INCOMPLETE;
2342 goto fail_cleanup;
2344 break;
2346 case CKK_DH:
2347 if (isModulus || isPubExpo || isPriExpo || isPrime1 ||
2348 isPrime2 || isExpo1 || isExpo2 || isCoef ||
2349 isSubprime) {
2350 rv = CKR_TEMPLATE_INCONSISTENT;
2351 goto fail_cleanup;
2354 /* CKA_VALUE_BITS is for key gen but not unwrap */
2355 if (mode == SOFT_GEN_KEY)
2356 KEY_PRI_DH_VAL_BITS(pvk) = (isValueBits) ?
2357 value_bits : 0;
2358 else if (mode == SOFT_UNWRAP_KEY) {
2359 if (isValueBits) {
2360 rv = CKR_TEMPLATE_INCONSISTENT;
2361 goto fail_cleanup;
2365 if (mode == SOFT_GEN_KEY || mode == SOFT_UNWRAP_KEY) {
2366 if (isPrime || isBase || isValue) {
2367 rv = CKR_TEMPLATE_INCONSISTENT;
2368 goto fail_cleanup;
2369 } else
2370 break;
2373 if (isValueBits) {
2374 rv = CKR_TEMPLATE_INCONSISTENT;
2375 goto fail_cleanup;
2378 if (isPrime && isBase && isValue) {
2379 copy_bigint_attr(&prime, KEY_PRI_DH_PRIME(pvk));
2381 copy_bigint_attr(&base, KEY_PRI_DH_BASE(pvk));
2383 copy_bigint_attr(&value, KEY_PRI_DH_VALUE(pvk));
2384 } else {
2385 rv = CKR_TEMPLATE_INCOMPLETE;
2386 goto fail_cleanup;
2388 break;
2390 case CKK_X9_42_DH:
2391 if (isModulus || isPubExpo || isPriExpo || isPrime1 ||
2392 isPrime2 || isExpo1 || isExpo2 || isCoef ||
2393 isValueBits) {
2394 rv = CKR_TEMPLATE_INCONSISTENT;
2395 goto fail_cleanup;
2398 if (mode == SOFT_GEN_KEY || mode == SOFT_UNWRAP_KEY) {
2399 if (isPrime || isSubprime || isBase || isValue) {
2400 rv = CKR_TEMPLATE_INCONSISTENT;
2401 goto fail_cleanup;
2402 } else
2403 break;
2406 if (isPrime && isSubprime && isBase && isValue) {
2407 copy_bigint_attr(&prime, KEY_PRI_DH942_PRIME(pvk));
2409 copy_bigint_attr(&base, KEY_PRI_DH942_BASE(pvk));
2411 copy_bigint_attr(&subprime,
2412 KEY_PRI_DH942_SUBPRIME(pvk));
2414 copy_bigint_attr(&value, KEY_PRI_DH942_VALUE(pvk));
2415 } else {
2416 rv = CKR_TEMPLATE_INCOMPLETE;
2417 goto fail_cleanup;
2419 break;
2421 case CKK_EC:
2422 if (isModulus || isPubExpo || isPrime ||
2423 isPrime1 || isPrime2 || isExpo1 || isExpo2 || isCoef ||
2424 isValueBits || isBase) {
2425 rv = CKR_TEMPLATE_INCONSISTENT;
2426 goto fail_cleanup;
2428 } else if (isECParam) {
2429 rv = soft_add_extra_attr(&param_tmp, new_object);
2430 if (rv != CKR_OK)
2431 goto fail_cleanup;
2432 string_attr_cleanup(&param_tmp);
2434 if (isValue) {
2435 copy_bigint_attr(&value, KEY_PRI_EC_VALUE(pvk));
2437 break;
2439 default:
2440 rv = CKR_TEMPLATE_INCONSISTENT;
2441 goto fail_cleanup;
2444 /* Set up object. */
2445 new_object->object_type = object_type;
2446 new_object->bool_attr_mask = attr_mask;
2447 if (isLabel) {
2448 rv = soft_add_extra_attr(&string_tmp, new_object);
2449 if (rv != CKR_OK)
2450 goto fail_cleanup;
2451 string_attr_cleanup(&string_tmp);
2453 big_finish(&x);
2454 big_finish(&q);
2456 return (rv);
2458 fail_cleanup:
2460 * cleanup the storage allocated to the local variables.
2462 bigint_attr_cleanup(&modulus);
2463 bigint_attr_cleanup(&priexpo);
2464 bigint_attr_cleanup(&prime);
2465 bigint_attr_cleanup(&subprime);
2466 bigint_attr_cleanup(&base);
2467 bigint_attr_cleanup(&value);
2468 bigint_attr_cleanup(&pubexpo);
2469 bigint_attr_cleanup(&prime1);
2470 bigint_attr_cleanup(&prime2);
2471 bigint_attr_cleanup(&expo1);
2472 bigint_attr_cleanup(&expo2);
2473 bigint_attr_cleanup(&coef);
2474 string_attr_cleanup(&string_tmp);
2475 string_attr_cleanup(&param_tmp);
2476 big_finish(&x);
2477 big_finish(&q);
2480 * cleanup the storage allocated inside the object itself.
2482 soft_cleanup_object(new_object);
2484 return (rv);
2489 * Build a Secret Key Object.
2491 * - Parse the object's template, and when an error is detected such as
2492 * invalid attribute type, invalid attribute value, etc., return
2493 * with appropriate return value.
2494 * - Set up attribute mask field in the object for the supplied common
2495 * attributes that have boolean type.
2496 * - Build the attribute_info struct to hold the value of each supplied
2497 * attribute that has byte array type. Link attribute_info structs
2498 * together to form the extra attribute list of the object.
2499 * - Allocate storage for the Secret Key object.
2500 * - Build the Secret Key object. Allocate storage to hold the big integer
2501 * value for the attribute CKA_VALUE that is required for all the key
2502 * types supported by secret key object.
2503 * This function is called internally with mode = SOFT_CREATE_OBJ_INT.
2506 CK_RV
2507 soft_build_secret_key_object(CK_ATTRIBUTE_PTR template, CK_ULONG ulAttrNum,
2508 soft_object_t *new_object, CK_ULONG mode, CK_ULONG key_len,
2509 CK_KEY_TYPE key_type)
2512 ulong_t i;
2513 CK_KEY_TYPE keytype = (CK_KEY_TYPE)~0UL;
2514 uint64_t attr_mask = SECRET_KEY_DEFAULT;
2515 CK_RV rv = CKR_OK;
2516 int isLabel = 0;
2517 /* Must set flags if mode != SOFT_UNWRAP_KEY, else must not set */
2518 int isValue = 0;
2519 /* Must not set flags if mode != SOFT_UNWRAP_KEY, else optional */
2520 int isValueLen = 0;
2522 CK_ATTRIBUTE string_tmp;
2524 secret_key_obj_t *sck;
2525 uchar_t object_type = 0;
2527 string_tmp.pValue = NULL;
2529 /* Allocate storage for Secret Key Object. */
2530 sck = calloc(1, sizeof (secret_key_obj_t));
2531 if (sck == NULL) {
2532 rv = CKR_HOST_MEMORY;
2533 goto fail_cleanup;
2536 new_object->object_class_u.secret_key = sck;
2537 new_object->class = CKO_SECRET_KEY;
2539 for (i = 0; i < ulAttrNum; i++) {
2541 /* Secret Key Object Attributes */
2542 switch (template[i].type) {
2544 /* common key attributes */
2545 case CKA_KEY_TYPE:
2546 keytype = *((CK_KEY_TYPE*)template[i].pValue);
2547 break;
2549 case CKA_ID:
2550 case CKA_START_DATE:
2551 case CKA_END_DATE:
2553 * Allocate storage to hold the attribute
2554 * value with byte array type, and add it to
2555 * the extra attribute list of the object.
2557 rv = soft_add_extra_attr(&template[i],
2558 new_object);
2559 if (rv != CKR_OK) {
2560 goto fail_cleanup;
2562 break;
2565 * The following key related attribute types must
2566 * not be specified by C_CreateObject and C_GenerateKey.
2568 case CKA_LOCAL:
2569 case CKA_KEY_GEN_MECHANISM:
2570 case CKA_ALWAYS_SENSITIVE:
2571 case CKA_NEVER_EXTRACTABLE:
2572 rv = CKR_TEMPLATE_INCONSISTENT;
2573 goto fail_cleanup;
2575 /* Key related boolean attributes */
2576 case CKA_DERIVE:
2577 if (*(CK_BBOOL *)template[i].pValue)
2578 attr_mask |= DERIVE_BOOL_ON;
2579 break;
2581 case CKA_SENSITIVE:
2582 if (*(CK_BBOOL *)template[i].pValue)
2583 attr_mask |= SENSITIVE_BOOL_ON;
2584 break;
2586 case CKA_ENCRYPT:
2587 if (*(CK_BBOOL *)template[i].pValue)
2588 attr_mask |= ENCRYPT_BOOL_ON;
2589 else
2590 attr_mask &= ~ENCRYPT_BOOL_ON;
2591 break;
2593 case CKA_DECRYPT:
2594 if (*(CK_BBOOL *)template[i].pValue)
2595 attr_mask |= DECRYPT_BOOL_ON;
2596 else
2597 attr_mask &= ~DECRYPT_BOOL_ON;
2598 break;
2600 case CKA_SIGN:
2601 if (*(CK_BBOOL *)template[i].pValue)
2602 attr_mask |= SIGN_BOOL_ON;
2603 else
2604 attr_mask &= ~SIGN_BOOL_ON;
2605 break;
2607 case CKA_VERIFY:
2608 if (*(CK_BBOOL *)template[i].pValue)
2609 attr_mask |= VERIFY_BOOL_ON;
2610 else
2611 attr_mask &= ~VERIFY_BOOL_ON;
2612 break;
2614 case CKA_WRAP:
2615 if (*(CK_BBOOL *)template[i].pValue)
2616 attr_mask |= WRAP_BOOL_ON;
2617 else
2618 attr_mask &= ~WRAP_BOOL_ON;
2619 break;
2621 case CKA_UNWRAP:
2622 if (*(CK_BBOOL *)template[i].pValue)
2623 attr_mask |= UNWRAP_BOOL_ON;
2624 else
2625 attr_mask &= ~UNWRAP_BOOL_ON;
2626 break;
2628 case CKA_EXTRACTABLE:
2629 if (*(CK_BBOOL *)template[i].pValue)
2630 attr_mask |= EXTRACTABLE_BOOL_ON;
2631 else
2632 attr_mask &= ~EXTRACTABLE_BOOL_ON;
2633 break;
2635 case CKA_MODIFIABLE:
2636 if ((*(CK_BBOOL *)template[i].pValue) == B_FALSE)
2637 attr_mask |= NOT_MODIFIABLE_BOOL_ON;
2638 break;
2640 case CKA_VALUE:
2641 isValue = 1;
2642 if (mode == SOFT_CREATE_OBJ) {
2643 if ((template[i].ulValueLen == 0) ||
2644 (template[i].pValue == NULL)) {
2645 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2646 goto fail_cleanup;
2651 * Copyin attribute from template
2652 * to a local variable.
2654 rv = get_bigint_attr_from_template((biginteger_t *)sck,
2655 &template[i]);
2656 if (rv != CKR_OK)
2657 goto fail_cleanup;
2658 break;
2660 case CKA_VALUE_LEN:
2661 isValueLen = 1;
2662 rv = get_ulong_attr_from_template(&sck->sk_value_len,
2663 &template[i]);
2664 if (rv != CKR_OK)
2665 goto fail_cleanup;
2666 break;
2668 case CKA_LABEL:
2669 isLabel = 1;
2670 rv = get_string_from_template(&string_tmp,
2671 &template[i]);
2672 if (rv != CKR_OK)
2673 goto fail_cleanup;
2674 break;
2676 default:
2677 rv = soft_parse_common_attrs(&template[i],
2678 &object_type);
2679 if (rv != CKR_OK)
2680 goto fail_cleanup;
2681 break;
2684 } /* For */
2686 switch (mode) {
2687 case SOFT_CREATE_OBJ:
2688 case SOFT_CREATE_OBJ_INT:
2689 case SOFT_DERIVE_KEY_DH:
2691 * The key type must be specified in the application's
2692 * template. Otherwise, returns error.
2694 if (keytype == (CK_KEY_TYPE)~0UL) {
2695 rv = CKR_TEMPLATE_INCOMPLETE;
2696 goto fail_cleanup;
2698 break;
2700 case SOFT_GEN_KEY:
2701 if (keytype == (CK_KEY_TYPE)~0UL) {
2703 * The key type is not specified in the application's
2704 * template, so we use the implied key type based on
2705 * the mechanism.
2707 keytype = key_type;
2708 } else {
2709 if (keytype != key_type) {
2711 * The key type specified in the template
2712 * does not match the implied key type based
2713 * on the mechanism.
2715 rv = CKR_TEMPLATE_INCONSISTENT;
2716 goto fail_cleanup;
2721 * If a key_len is passed as a parameter, it has to
2722 * match the one found in the template.
2724 if (key_len > 0) {
2725 if (isValueLen && sck->sk_value_len != key_len) {
2726 rv = CKR_TEMPLATE_INCONSISTENT;
2727 goto fail_cleanup;
2729 isValueLen = 1;
2730 sck->sk_value_len = key_len;
2732 break;
2734 case SOFT_UNWRAP_KEY:
2736 * Note that, for mode SOFT_UNWRAP_KEY, key type is not
2737 * implied by the mechanism (key_type), so if it is not
2738 * specified from the attribute template (keytype), it is
2739 * incomplete.
2741 if (keytype == (CK_KEY_TYPE)~0UL) {
2742 rv = CKR_TEMPLATE_INCOMPLETE;
2743 goto fail_cleanup;
2745 break;
2747 case SOFT_DERIVE_KEY_OTHER:
2749 * For CKM_MD5_KEY_DERIVATION & CKM_SHA1_KEY_DERIVATION, the
2750 * key type is optional.
2752 if (keytype == (CK_KEY_TYPE)~0UL) {
2753 keytype = key_type;
2755 break;
2758 switch (mode) {
2759 case SOFT_CREATE_OBJ:
2760 case SOFT_CREATE_OBJ_INT:
2761 switch (keytype) {
2762 case CKK_RC4:
2763 if (!isValue) {
2764 rv = CKR_TEMPLATE_INCOMPLETE;
2765 goto fail_cleanup;
2767 if ((sck->sk_value_len < ARCFOUR_MIN_KEY_BYTES) ||
2768 (sck->sk_value_len > ARCFOUR_MAX_KEY_BYTES)) {
2769 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2770 goto fail_cleanup;
2772 break;
2774 case CKK_GENERIC_SECRET:
2775 if (!isValue) {
2776 rv = CKR_TEMPLATE_INCOMPLETE;
2777 goto fail_cleanup;
2779 break;
2781 case CKK_AES:
2782 if (!isValue) {
2783 rv = CKR_TEMPLATE_INCOMPLETE;
2784 goto fail_cleanup;
2786 if ((sck->sk_value_len != AES_MIN_KEY_BYTES) &&
2787 (sck->sk_value_len != AES_192_KEY_BYTES) &&
2788 (sck->sk_value_len != AES_MAX_KEY_BYTES)) {
2789 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2790 goto fail_cleanup;
2792 break;
2794 case CKK_BLOWFISH:
2795 if (!isValue) {
2796 rv = CKR_TEMPLATE_INCOMPLETE;
2797 goto fail_cleanup;
2799 if ((sck->sk_value_len < BLOWFISH_MINBYTES) ||
2800 (sck->sk_value_len > BLOWFISH_MAXBYTES)) {
2801 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2802 goto fail_cleanup;
2805 break;
2807 case CKK_DES:
2808 if (!isValue) {
2809 rv = CKR_TEMPLATE_INCOMPLETE;
2810 goto fail_cleanup;
2812 if (sck->sk_value_len != DES_KEYSIZE) {
2813 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2814 goto fail_cleanup;
2816 break;
2818 case CKK_DES2:
2819 if (!isValue) {
2820 rv = CKR_TEMPLATE_INCOMPLETE;
2821 goto fail_cleanup;
2823 if (sck->sk_value_len != DES2_KEYSIZE) {
2824 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2825 goto fail_cleanup;
2827 break;
2829 case CKK_DES3:
2830 if (!isValue) {
2831 rv = CKR_TEMPLATE_INCOMPLETE;
2832 goto fail_cleanup;
2834 if (sck->sk_value_len != DES3_KEYSIZE) {
2835 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2836 goto fail_cleanup;
2838 break;
2840 default:
2841 rv = CKR_TEMPLATE_INCONSISTENT;
2842 goto fail_cleanup;
2845 if (isValueLen) {
2847 * Templates for internal object creation come from
2848 * applications calls to C_DeriveKey(), for which it
2849 * is OKey to pass a CKA_VALUE_LEN attribute, as
2850 * long as it does not conflict with the length of the
2851 * CKA_VALUE attribute.
2853 if ((mode != SOFT_CREATE_OBJ_INT) ||
2854 ((key_len > 0) && sck->sk_value_len != key_len)) {
2855 rv = CKR_TEMPLATE_INCONSISTENT;
2856 goto fail_cleanup;
2859 break;
2861 case SOFT_GEN_KEY:
2862 /* CKA_VALUE must not be specified */
2863 if (isValue) {
2864 rv = CKR_TEMPLATE_INCONSISTENT;
2865 goto fail_cleanup;
2868 switch (keytype) {
2870 * CKA_VALUE_LEN must be specified by C_GenerateKey
2871 * if mech is CKK_RC4, CKK_AES, CKK_GENERIC_SECRET.
2873 case CKK_RC4:
2874 if (!isValueLen) {
2875 rv = CKR_TEMPLATE_INCOMPLETE;
2876 goto fail_cleanup;
2879 if ((sck->sk_value_len < ARCFOUR_MIN_KEY_BYTES) ||
2880 (sck->sk_value_len > ARCFOUR_MAX_KEY_BYTES)) {
2881 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2882 goto fail_cleanup;
2884 break;
2886 case CKK_GENERIC_SECRET:
2887 /* arbitrary key length - no length checking */
2888 if (!isValueLen) {
2889 rv = CKR_TEMPLATE_INCOMPLETE;
2890 goto fail_cleanup;
2892 break;
2894 case CKK_AES:
2895 if (!isValueLen) {
2896 rv = CKR_TEMPLATE_INCOMPLETE;
2897 goto fail_cleanup;
2900 if ((sck->sk_value_len != AES_MIN_KEY_BYTES) &&
2901 (sck->sk_value_len != AES_192_KEY_BYTES) &&
2902 (sck->sk_value_len != AES_MAX_KEY_BYTES)) {
2903 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2904 goto fail_cleanup;
2907 break;
2909 case CKK_BLOWFISH:
2910 if (!isValueLen) {
2911 rv = CKR_TEMPLATE_INCOMPLETE;
2912 goto fail_cleanup;
2914 if ((sck->sk_value_len < BLOWFISH_MINBYTES) ||
2915 (sck->sk_value_len > BLOWFISH_MAXBYTES)) {
2916 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2917 goto fail_cleanup;
2920 break;
2922 case CKK_DES:
2923 case CKK_DES2:
2924 case CKK_DES3:
2925 /* CKA_VALUE_LEN attribute does not apply to DES<n> */
2926 if (isValueLen) {
2927 rv = CKR_TEMPLATE_INCONSISTENT;
2928 goto fail_cleanup;
2930 break;
2932 default:
2933 rv = CKR_TEMPLATE_INCONSISTENT;
2934 goto fail_cleanup;
2936 break;
2938 case SOFT_UNWRAP_KEY:
2940 * According to v2.11 of PKCS#11 spec, neither CKA_VALUE nor
2941 * CKA_VALUE_LEN can be be specified; however v2.20 has this
2942 * restriction removed, perhaps because it makes it hard to
2943 * determine variable-length key sizes. This case statement
2944 * complied with v2.20.
2946 if (isValue) {
2947 rv = CKR_TEMPLATE_INCONSISTENT;
2948 goto fail_cleanup;
2951 switch (keytype) {
2953 * CKA_VALUE_LEN is optional
2954 * if key is CKK_RC4, CKK_AES, CKK_GENERIC_SECRET
2955 * and the unwrapping mech is *_CBC_PAD.
2957 * CKA_VALUE_LEN is required
2958 * if key is CKK_RC4, CKK_AES, CKK_GENERIC_SECRET
2959 * and the unwrapping mech is *_ECB or *_CBC.
2961 * since mech is not known at this point, CKA_VALUE_LEN is
2962 * treated as optional and the caller needs to enforce it.
2964 case CKK_RC4:
2965 if (isValueLen) {
2966 if ((sck->sk_value_len <
2967 ARCFOUR_MIN_KEY_BYTES) ||
2968 (sck->sk_value_len >
2969 ARCFOUR_MAX_KEY_BYTES)) {
2970 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2971 goto fail_cleanup;
2974 break;
2976 case CKK_GENERIC_SECRET:
2977 /* arbitrary key length - no length checking */
2978 break;
2980 case CKK_AES:
2981 if (isValueLen) {
2982 if ((sck->sk_value_len != AES_MIN_KEY_BYTES) &&
2983 (sck->sk_value_len != AES_192_KEY_BYTES) &&
2984 (sck->sk_value_len != AES_MAX_KEY_BYTES)) {
2985 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2986 goto fail_cleanup;
2989 break;
2991 case CKK_BLOWFISH:
2992 if (isValueLen &&
2993 ((sck->sk_value_len < BLOWFISH_MINBYTES) ||
2994 (sck->sk_value_len > BLOWFISH_MAXBYTES))) {
2995 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2996 goto fail_cleanup;
2998 break;
3000 case CKK_DES:
3001 case CKK_DES2:
3002 case CKK_DES3:
3003 /* CKA_VALUE_LEN attribute does not apply to DES<n> */
3004 if (isValueLen) {
3005 rv = CKR_TEMPLATE_INCONSISTENT;
3006 goto fail_cleanup;
3008 break;
3010 default:
3011 rv = CKR_TEMPLATE_INCONSISTENT;
3012 goto fail_cleanup;
3014 break;
3016 case SOFT_DERIVE_KEY_DH:
3017 /* CKA_VALUE must not be specified */
3018 if (isValue) {
3019 rv = CKR_TEMPLATE_INCONSISTENT;
3020 goto fail_cleanup;
3023 switch (keytype) {
3025 * CKA_VALUE_LEN is optional
3026 * if mech is CKK_RC4, CKK_AES, CKK_GENERIC_SECRET.
3028 case CKK_RC4:
3029 if (isValueLen) {
3030 if ((sck->sk_value_len <
3031 ARCFOUR_MIN_KEY_BYTES) ||
3032 (sck->sk_value_len >
3033 ARCFOUR_MAX_KEY_BYTES)) {
3034 rv = CKR_ATTRIBUTE_VALUE_INVALID;
3035 goto fail_cleanup;
3038 break;
3040 case CKK_GENERIC_SECRET:
3041 /* arbitrary key length - no length checking */
3042 break;
3044 case CKK_AES:
3045 if (isValueLen) {
3046 if ((sck->sk_value_len != AES_MIN_KEY_BYTES) &&
3047 (sck->sk_value_len != AES_192_KEY_BYTES) &&
3048 (sck->sk_value_len != AES_MAX_KEY_BYTES)) {
3049 rv = CKR_ATTRIBUTE_VALUE_INVALID;
3050 goto fail_cleanup;
3054 break;
3056 case CKK_BLOWFISH:
3057 if (isValueLen &&
3058 ((sck->sk_value_len < BLOWFISH_MINBYTES) ||
3059 (sck->sk_value_len > BLOWFISH_MAXBYTES))) {
3060 rv = CKR_ATTRIBUTE_VALUE_INVALID;
3061 goto fail_cleanup;
3063 break;
3065 case CKK_DES:
3066 case CKK_DES2:
3067 case CKK_DES3:
3068 /* CKA_VALUE_LEN attribute does not apply to DES<n> */
3069 if (isValueLen) {
3070 rv = CKR_TEMPLATE_INCONSISTENT;
3071 goto fail_cleanup;
3073 break;
3075 default:
3076 rv = CKR_TEMPLATE_INCONSISTENT;
3077 goto fail_cleanup;
3079 break;
3081 case SOFT_DERIVE_KEY_OTHER:
3082 /* CKA_VALUE must not be specified */
3083 if (isValue) {
3084 rv = CKR_TEMPLATE_INCONSISTENT;
3085 goto fail_cleanup;
3088 switch (keytype) {
3090 * CKA_VALUE_LEN is an optional attribute for
3091 * CKM_SHA1_KEY_DERIVATION and CKM_MD5_KEY_DERIVATION
3092 * if mech is CKK_RC4, CKK_AES, CKK_GENERIC_SECRET.
3094 case CKK_RC4:
3095 case CKK_GENERIC_SECRET:
3096 case CKK_AES:
3097 case CKK_BLOWFISH:
3099 * No need to check key length value here, it will be
3100 * validated later in soft_key_derive_check_length().
3102 break;
3104 case CKK_DES:
3105 case CKK_DES2:
3106 case CKK_DES3:
3107 /* CKA_VALUE_LEN attribute does not apply to DES<n> */
3108 if (isValueLen) {
3109 rv = CKR_TEMPLATE_INCONSISTENT;
3110 goto fail_cleanup;
3112 break;
3114 default:
3115 rv = CKR_TEMPLATE_INCONSISTENT;
3116 goto fail_cleanup;
3118 break;
3121 /* Set up object. */
3122 new_object->key_type = keytype;
3123 new_object->object_type = object_type;
3124 new_object->bool_attr_mask = attr_mask;
3125 if (isLabel) {
3126 rv = soft_add_extra_attr(&string_tmp, new_object);
3127 if (rv != CKR_OK)
3128 goto fail_cleanup;
3129 string_attr_cleanup(&string_tmp);
3131 return (rv);
3133 fail_cleanup:
3135 * cleanup the storage allocated to the local variables.
3137 bigint_attr_cleanup((biginteger_t *)sck);
3138 string_attr_cleanup(&string_tmp);
3141 * cleanup the storage allocated inside the object itself.
3143 soft_cleanup_object(new_object);
3145 return (rv);
3150 * Build a Domain Parameter Object.
3152 * - Parse the object's template, and when an error is detected such as
3153 * invalid attribute type, invalid attribute value, etc., return
3154 * with appropriate return value.
3155 * - Allocate storage for the Domain Parameter object.
3156 * - Build the Domain Parameter object according to the key type. Allocate
3157 * storage to hold the big integer value for the supplied attributes
3158 * that are required for a certain key type.
3161 CK_RV
3162 soft_build_domain_parameters_object(CK_ATTRIBUTE_PTR template,
3163 CK_ULONG ulAttrNum, soft_object_t *new_object)
3166 ulong_t i;
3167 CK_KEY_TYPE keytype = (CK_KEY_TYPE)~0UL;
3168 CK_RV rv = CKR_OK;
3169 int isLabel = 0;
3170 /* Must set flags */
3171 int isPrime = 0;
3172 int isSubprime = 0;
3173 int isBase = 0;
3174 /* Must not set flags */
3175 int isPrimeBits = 0;
3176 int isSubPrimeBits = 0;
3178 biginteger_t prime;
3179 biginteger_t subprime;
3180 biginteger_t base;
3181 CK_ATTRIBUTE string_tmp;
3183 domain_obj_t *dom;
3184 uchar_t object_type = 0;
3186 /* prevent bigint_attr_cleanup from freeing invalid attr value */
3187 (void) memset(&prime, 0x0, sizeof (biginteger_t));
3188 (void) memset(&subprime, 0x0, sizeof (biginteger_t));
3189 (void) memset(&base, 0x0, sizeof (biginteger_t));
3190 string_tmp.pValue = NULL;
3192 for (i = 0; i < ulAttrNum; i++) {
3194 /* Domain Parameters Object Attributes */
3195 switch (template[i].type) {
3197 /* common domain parameter attribute */
3198 case CKA_KEY_TYPE:
3199 keytype = *((CK_KEY_TYPE*)template[i].pValue);
3200 break;
3203 * The following common domain parameter attribute
3204 * must not be specified by C_CreateObject.
3206 case CKA_LOCAL:
3207 rv = CKR_TEMPLATE_INCONSISTENT;
3208 goto fail_cleanup;
3211 * The following domain parameter attributes must be
3212 * specified according to the key type by
3213 * C_CreateObject.
3215 case CKA_PRIME:
3216 isPrime = 1;
3218 * Copyin big integer attribute from template
3219 * to a local variable.
3221 rv = get_bigint_attr_from_template(&prime,
3222 &template[i]);
3223 if (rv != CKR_OK)
3224 goto fail_cleanup;
3225 break;
3227 case CKA_SUBPRIME:
3228 isSubprime = 1;
3229 rv = get_bigint_attr_from_template(&subprime,
3230 &template[i]);
3231 if (rv != CKR_OK)
3232 goto fail_cleanup;
3233 break;
3235 case CKA_BASE:
3236 isBase = 1;
3237 rv = get_bigint_attr_from_template(&base,
3238 &template[i]);
3239 if (rv != CKR_OK)
3240 goto fail_cleanup;
3241 break;
3243 case CKA_PRIME_BITS:
3244 isPrimeBits = 1;
3245 break;
3247 case CKA_SUB_PRIME_BITS:
3248 isSubPrimeBits = 1;
3249 break;
3251 case CKA_LABEL:
3252 isLabel = 1;
3253 rv = get_string_from_template(&string_tmp,
3254 &template[i]);
3255 if (rv != CKR_OK)
3256 goto fail_cleanup;
3257 break;
3259 default:
3260 rv = soft_parse_common_attrs(&template[i],
3261 &object_type);
3262 if (rv != CKR_OK)
3263 goto fail_cleanup;
3264 break;
3267 } /* For */
3269 /* Allocate storage for Domain Parameters Object. */
3270 dom = calloc(1, sizeof (domain_obj_t));
3271 if (dom == NULL) {
3272 rv = CKR_HOST_MEMORY;
3273 goto fail_cleanup;
3276 new_object->object_class_u.domain = dom;
3277 new_object->class = CKO_DOMAIN_PARAMETERS;
3279 if (keytype == (CK_KEY_TYPE)~0UL) {
3280 rv = CKR_TEMPLATE_INCOMPLETE;
3281 goto fail_cleanup;
3284 new_object->key_type = keytype;
3286 /* Supported key types of the Domain Parameters Object */
3287 switch (keytype) {
3288 case CKK_DSA:
3289 if (isPrimeBits || isSubPrimeBits) {
3290 rv = CKR_TEMPLATE_INCONSISTENT;
3291 goto fail_cleanup;
3294 if (isPrime && isSubprime && isBase) {
3296 * Copy big integer attribute value to the
3297 * designated place in the domain parameter
3298 * object.
3300 copy_bigint_attr(&prime, KEY_DOM_DSA_PRIME(dom));
3302 copy_bigint_attr(&subprime, KEY_DOM_DSA_SUBPRIME(dom));
3304 copy_bigint_attr(&base, KEY_DOM_DSA_BASE(dom));
3305 } else {
3306 rv = CKR_TEMPLATE_INCOMPLETE;
3307 goto fail_cleanup;
3309 break;
3311 case CKK_DH:
3312 if (isPrimeBits || isSubprime || isSubPrimeBits) {
3313 rv = CKR_TEMPLATE_INCONSISTENT;
3314 goto fail_cleanup;
3317 if (isPrime && isBase) {
3318 copy_bigint_attr(&prime, KEY_DOM_DH_PRIME(dom));
3320 copy_bigint_attr(&base, KEY_DOM_DH_BASE(dom));
3321 } else {
3322 rv = CKR_TEMPLATE_INCOMPLETE;
3323 goto fail_cleanup;
3325 break;
3327 case CKK_X9_42_DH:
3328 if (isPrimeBits || isSubPrimeBits) {
3329 rv = CKR_TEMPLATE_INCONSISTENT;
3330 goto fail_cleanup;
3333 if (isPrime && isSubprime && isBase) {
3334 copy_bigint_attr(&prime, KEY_DOM_DH942_PRIME(dom));
3336 copy_bigint_attr(&base, KEY_DOM_DH942_BASE(dom));
3338 copy_bigint_attr(&subprime,
3339 KEY_DOM_DH942_SUBPRIME(dom));
3340 } else {
3341 rv = CKR_TEMPLATE_INCOMPLETE;
3342 goto fail_cleanup;
3344 break;
3346 default:
3347 rv = CKR_TEMPLATE_INCONSISTENT;
3348 goto fail_cleanup;
3351 new_object->object_type = object_type;
3353 if (isLabel) {
3354 rv = soft_add_extra_attr(&string_tmp, new_object);
3355 if (rv != CKR_OK)
3356 goto fail_cleanup;
3357 string_attr_cleanup(&string_tmp);
3360 return (rv);
3362 fail_cleanup:
3364 * cleanup the storage allocated to the local variables.
3366 bigint_attr_cleanup(&prime);
3367 bigint_attr_cleanup(&subprime);
3368 bigint_attr_cleanup(&base);
3369 string_attr_cleanup(&string_tmp);
3372 * cleanup the storage allocated inside the object itself.
3374 soft_cleanup_object(new_object);
3376 return (rv);
3380 * Build a Certificate Object
3382 * - Parse the object's template, and when an error is detected such as
3383 * invalid attribute type, invalid attribute value, etc., return
3384 * with appropriate return value.
3385 * - Allocate storage for the Certificate object
3387 static CK_RV
3388 soft_build_certificate_object(CK_ATTRIBUTE_PTR template,
3389 CK_ULONG ulAttrNum, soft_object_t *new_object,
3390 CK_CERTIFICATE_TYPE cert_type)
3392 uint64_t attr_mask = 0;
3393 CK_RV rv = CKR_OK;
3394 CK_ULONG i;
3395 int owner_set = 0;
3396 int value_set = 0;
3397 int subject_set = 0;
3398 certificate_obj_t *cert;
3399 /* certificate type defaults to the value given as a parameter */
3400 CK_CERTIFICATE_TYPE certtype = cert_type;
3401 CK_ATTRIBUTE string_tmp;
3402 int isLabel = 0;
3403 uchar_t object_type = 0;
3406 * Look for the certificate type attribute and do some
3407 * sanity checking before creating the structures.
3409 for (i = 0; i < ulAttrNum; i++) {
3410 /* Certificate Object Attributes */
3411 switch (template[i].type) {
3412 case CKA_CERTIFICATE_TYPE:
3413 certtype =
3414 *((CK_CERTIFICATE_TYPE*)template[i].pValue);
3415 break;
3416 case CKA_SUBJECT:
3417 subject_set = 1;
3418 break;
3419 case CKA_OWNER:
3420 owner_set = 1;
3421 break;
3422 case CKA_VALUE:
3423 value_set = 1;
3424 break;
3428 /* The certificate type MUST be specified */
3429 if (certtype != CKC_X_509 && certtype != CKC_X_509_ATTR_CERT)
3430 return (CKR_TEMPLATE_INCOMPLETE);
3433 * For X.509 certs, the CKA_SUBJECT and CKA_VALUE
3434 * must be present at creation time.
3436 if (certtype == CKC_X_509 &&
3437 (!subject_set || !value_set))
3438 return (CKR_TEMPLATE_INCOMPLETE);
3441 * For X.509 Attribute certs, the CKA_OWNER and CKA_VALUE
3442 * must be present at creation time.
3444 if (certtype == CKC_X_509_ATTR_CERT &&
3445 (!owner_set || !value_set))
3446 return (CKR_TEMPLATE_INCOMPLETE);
3448 string_tmp.pValue = NULL;
3449 cert = calloc(1, sizeof (certificate_obj_t));
3450 if (cert == NULL) {
3451 return (CKR_HOST_MEMORY);
3453 cert->certificate_type = certtype;
3455 for (i = 0; i < ulAttrNum; i++) {
3456 /* Certificate Object Attributes */
3457 switch (certtype) {
3458 case CKC_X_509:
3459 switch (template[i].type) {
3460 case CKA_SUBJECT:
3461 rv = get_cert_attr_from_template(
3462 &cert->cert_type_u.x509.subject,
3463 &template[i]);
3464 break;
3465 case CKA_VALUE:
3466 rv = get_cert_attr_from_template(
3467 &cert->cert_type_u.x509.value,
3468 &template[i]);
3469 break;
3470 case CKA_LABEL:
3471 isLabel = 1;
3472 rv = get_string_from_template(
3473 &string_tmp,
3474 &template[i]);
3475 if (rv != CKR_OK)
3476 goto fail_cleanup;
3477 break;
3478 case CKA_ID:
3479 case CKA_ISSUER:
3480 case CKA_SERIAL_NUMBER:
3481 rv = soft_add_extra_attr(&template[i],
3482 new_object);
3483 break;
3484 case CKA_MODIFIABLE:
3485 if ((*(CK_BBOOL *)template[i].pValue) ==
3486 B_FALSE)
3487 attr_mask |=
3488 NOT_MODIFIABLE_BOOL_ON;
3489 break;
3490 case CKA_CERTIFICATE_TYPE:
3491 break;
3492 default:
3493 rv = soft_parse_common_attrs(
3494 &template[i], &object_type);
3495 if (rv != CKR_OK)
3496 goto fail_cleanup;
3498 break;
3499 case CKC_X_509_ATTR_CERT:
3500 switch (template[i].type) {
3501 case CKA_OWNER:
3502 rv = get_cert_attr_from_template(
3503 &cert->cert_type_u.x509_attr.owner,
3504 &template[i]);
3505 break;
3506 case CKA_VALUE:
3507 rv = get_cert_attr_from_template(
3508 &cert->cert_type_u.x509_attr.value,
3509 &template[i]);
3510 break;
3511 case CKA_LABEL:
3512 isLabel = 1;
3513 rv = get_string_from_template(
3514 &string_tmp, &template[i]);
3515 if (rv != CKR_OK)
3516 goto fail_cleanup;
3517 break;
3518 case CKA_SERIAL_NUMBER:
3519 case CKA_AC_ISSUER:
3520 case CKA_ATTR_TYPES:
3521 rv = soft_add_extra_attr(&template[i],
3522 new_object);
3523 break;
3525 case CKA_MODIFIABLE:
3526 if ((*(CK_BBOOL *)template[i].pValue) ==
3527 B_FALSE)
3528 attr_mask |=
3529 NOT_MODIFIABLE_BOOL_ON;
3530 break;
3531 case CKA_CERTIFICATE_TYPE:
3532 break;
3533 default:
3534 rv = soft_parse_common_attrs(
3535 &template[i], &object_type);
3536 if (rv != CKR_OK)
3537 goto fail_cleanup;
3538 break;
3540 break;
3541 default:
3542 rv = CKR_TEMPLATE_INCOMPLETE;
3543 break;
3547 if (rv == CKR_OK) {
3548 new_object->object_class_u.certificate = cert;
3549 new_object->class = CKO_CERTIFICATE;
3550 new_object->object_type = object_type;
3551 new_object->cert_type = certtype;
3552 new_object->bool_attr_mask = attr_mask;
3553 if (isLabel) {
3554 rv = soft_add_extra_attr(&string_tmp, new_object);
3555 if (rv != CKR_OK)
3556 goto fail_cleanup;
3557 string_attr_cleanup(&string_tmp);
3561 fail_cleanup:
3562 if (rv != CKR_OK) {
3563 soft_cleanup_cert_object(new_object);
3565 return (rv);
3570 * Validate the attribute types in the object's template. Then,
3571 * call the appropriate build function according to the class of
3572 * the object specified in the template.
3574 * Note: The following classes of objects are supported:
3575 * - CKO_PUBLIC_KEY
3576 * - CKO_PRIVATE_KEY
3577 * - CKO_SECRET_KEY
3578 * - CKO_DOMAIN_PARAMETERS
3579 * - CKO_CERTIFICATE
3582 CK_RV
3583 soft_build_object(CK_ATTRIBUTE_PTR template, CK_ULONG ulAttrNum,
3584 soft_object_t *new_object)
3587 CK_OBJECT_CLASS class = (CK_OBJECT_CLASS)~0UL;
3588 CK_RV rv = CKR_OK;
3590 if (template == NULL) {
3591 return (CKR_ARGUMENTS_BAD);
3594 /* Validate the attribute type in the template. */
3595 rv = soft_validate_attr(template, ulAttrNum, &class);
3596 if (rv != CKR_OK)
3597 return (rv);
3599 * CKA_CLASS is a mandatory attribute for C_CreateObject
3601 if (class == (CK_OBJECT_CLASS)~0UL)
3602 return (CKR_TEMPLATE_INCOMPLETE);
3605 * Call the appropriate function based on the supported class
3606 * of the object.
3608 switch (class) {
3609 case CKO_PUBLIC_KEY:
3610 rv = soft_build_public_key_object(template, ulAttrNum,
3611 new_object, SOFT_CREATE_OBJ, (CK_KEY_TYPE)~0UL);
3612 break;
3614 case CKO_PRIVATE_KEY:
3615 rv = soft_build_private_key_object(template, ulAttrNum,
3616 new_object, SOFT_CREATE_OBJ, (CK_KEY_TYPE)~0UL);
3617 break;
3619 case CKO_SECRET_KEY:
3620 rv = soft_build_secret_key_object(template, ulAttrNum,
3621 new_object, SOFT_CREATE_OBJ, 0, (CK_KEY_TYPE)~0UL);
3622 break;
3624 case CKO_DOMAIN_PARAMETERS:
3625 rv = soft_build_domain_parameters_object(template, ulAttrNum,
3626 new_object);
3627 break;
3629 case CKO_CERTIFICATE:
3630 rv = soft_build_certificate_object(template, ulAttrNum,
3631 new_object, (CK_CERTIFICATE_TYPE)~0UL);
3632 break;
3634 case CKO_DATA:
3635 case CKO_HW_FEATURE:
3636 case CKO_VENDOR_DEFINED:
3637 default:
3638 return (CKR_ATTRIBUTE_VALUE_INVALID);
3641 return (rv);
3645 * Validate the attribute types in the object's template. Then,
3646 * call the appropriate build function according to the class of
3647 * the object specified in the template.
3650 CK_RV
3651 soft_build_key(CK_ATTRIBUTE_PTR template, CK_ULONG ulAttrNum,
3652 soft_object_t *new_object, CK_OBJECT_CLASS class, CK_KEY_TYPE key_type,
3653 CK_ULONG key_len, CK_ULONG mode)
3656 CK_RV rv = CKR_OK;
3657 CK_OBJECT_CLASS temp_class = (CK_OBJECT_CLASS)~0UL;
3659 /* Validate the attribute type in the template. */
3660 if ((template != NULL) && (ulAttrNum != 0)) {
3661 rv = soft_validate_attr(template, ulAttrNum, &temp_class);
3662 if (rv != CKR_OK)
3663 return (rv);
3667 * If either the class from the parameter list ("class") or
3668 * the class from the template ("temp_class") is not specified,
3669 * try to use the other one.
3671 if (temp_class == (CK_OBJECT_CLASS)~0UL) {
3672 temp_class = class;
3673 } else if (class == (CK_OBJECT_CLASS)~0UL) {
3674 class = temp_class;
3677 /* If object class is still not specified, template is incomplete. */
3678 if (class == (CK_OBJECT_CLASS)~0UL)
3679 return (CKR_TEMPLATE_INCOMPLETE);
3681 /* Class should match if specified in both parameters and template. */
3682 if (class != temp_class)
3683 return (CKR_TEMPLATE_INCONSISTENT);
3686 * Call the appropriate function based on the supported class
3687 * of the object.
3689 switch (class) {
3690 case CKO_PUBLIC_KEY:
3692 /* Unwrapping public keys is not supported. */
3693 if (mode == SOFT_UNWRAP_KEY) {
3694 rv = CKR_ATTRIBUTE_VALUE_INVALID;
3695 break;
3698 rv = soft_build_public_key_object(template, ulAttrNum,
3699 new_object, mode, key_type);
3700 break;
3702 case CKO_PRIVATE_KEY:
3704 rv = soft_build_private_key_object(template, ulAttrNum,
3705 new_object, mode, key_type);
3706 break;
3708 case CKO_SECRET_KEY:
3710 rv = soft_build_secret_key_object(template, ulAttrNum,
3711 new_object, mode, key_len, key_type);
3712 break;
3714 case CKO_DOMAIN_PARAMETERS:
3716 /* Unwrapping domain parameters is not supported. */
3717 if (mode == SOFT_UNWRAP_KEY) {
3718 rv = CKR_ATTRIBUTE_VALUE_INVALID;
3719 break;
3722 rv = soft_build_domain_parameters_object(template, ulAttrNum,
3723 new_object);
3724 break;
3726 case CKO_DATA:
3727 case CKO_CERTIFICATE:
3728 case CKO_HW_FEATURE:
3729 case CKO_VENDOR_DEFINED:
3730 default:
3731 return (CKR_ATTRIBUTE_VALUE_INVALID);
3734 return (rv);
3739 * Get the value of a requested attribute that is common to all supported
3740 * classes (i.e. public key, private key, secret key, domain parameters,
3741 * and certificate classes).
3743 CK_RV
3744 soft_get_common_attrs(soft_object_t *object_p, CK_ATTRIBUTE_PTR template,
3745 uchar_t object_type)
3748 CK_RV rv = CKR_OK;
3750 switch (template->type) {
3752 case CKA_CLASS:
3753 return (get_ulong_attr_from_object(object_p->class,
3754 template));
3756 /* default boolean attributes */
3757 case CKA_TOKEN:
3758 template->ulValueLen = sizeof (CK_BBOOL);
3759 if (template->pValue == NULL) {
3760 return (CKR_OK);
3762 if (object_type & TOKEN_OBJECT)
3763 *((CK_BBOOL *)template->pValue) = B_TRUE;
3764 else
3765 *((CK_BBOOL *)template->pValue) = B_FALSE;
3766 break;
3768 case CKA_PRIVATE:
3770 template->ulValueLen = sizeof (CK_BBOOL);
3771 if (template->pValue == NULL) {
3772 return (CKR_OK);
3774 if (object_type & PRIVATE_OBJECT)
3775 *((CK_BBOOL *)template->pValue) = B_TRUE;
3776 else
3777 *((CK_BBOOL *)template->pValue) = B_FALSE;
3778 break;
3780 case CKA_MODIFIABLE:
3781 template->ulValueLen = sizeof (CK_BBOOL);
3782 if (template->pValue == NULL) {
3783 return (CKR_OK);
3785 if ((object_p->bool_attr_mask) & NOT_MODIFIABLE_BOOL_ON)
3786 *((CK_BBOOL *)template->pValue) = B_FALSE;
3787 else
3788 *((CK_BBOOL *)template->pValue) = B_TRUE;
3789 break;
3791 case CKA_LABEL:
3792 return (get_extra_attr_from_object(object_p,
3793 template));
3795 default:
3797 * The specified attribute for the object is invalid.
3798 * (the object does not possess such an attribute.)
3800 template->ulValueLen = (CK_ULONG)-1;
3801 return (CKR_ATTRIBUTE_TYPE_INVALID);
3804 return (rv);
3808 * Get the value of a requested attribute that is common to all key objects
3809 * (i.e. public key, private key and secret key).
3811 CK_RV
3812 soft_get_common_key_attrs(soft_object_t *object_p, CK_ATTRIBUTE_PTR template)
3815 switch (template->type) {
3817 case CKA_KEY_TYPE:
3818 return (get_ulong_attr_from_object(object_p->key_type,
3819 template));
3821 case CKA_ID:
3822 case CKA_START_DATE:
3823 case CKA_END_DATE:
3825 * The above extra attributes have byte array type.
3827 return (get_extra_attr_from_object(object_p,
3828 template));
3830 /* Key related boolean attributes */
3831 case CKA_LOCAL:
3832 return (get_bool_attr_from_object(object_p,
3833 LOCAL_BOOL_ON, template));
3835 case CKA_DERIVE:
3836 return (get_bool_attr_from_object(object_p,
3837 DERIVE_BOOL_ON, template));
3839 case CKA_KEY_GEN_MECHANISM:
3840 return (get_ulong_attr_from_object(object_p->mechanism,
3841 template));
3843 default:
3844 return (CKR_ATTRIBUTE_TYPE_INVALID);
3849 * Get the value of a requested attribute of a Public Key Object.
3851 * Rule: All the attributes in the public key object can be revealed.
3853 CK_RV
3854 soft_get_public_key_attribute(soft_object_t *object_p,
3855 CK_ATTRIBUTE_PTR template)
3858 CK_RV rv = CKR_OK;
3859 CK_KEY_TYPE keytype = object_p->key_type;
3861 switch (template->type) {
3863 case CKA_SUBJECT:
3864 case CKA_EC_PARAMS:
3866 * The above extra attributes have byte array type.
3868 return (get_extra_attr_from_object(object_p,
3869 template));
3871 /* Key related boolean attributes */
3872 case CKA_ENCRYPT:
3873 return (get_bool_attr_from_object(object_p,
3874 ENCRYPT_BOOL_ON, template));
3876 case CKA_VERIFY:
3877 return (get_bool_attr_from_object(object_p,
3878 VERIFY_BOOL_ON, template));
3880 case CKA_VERIFY_RECOVER:
3881 return (get_bool_attr_from_object(object_p,
3882 VERIFY_RECOVER_BOOL_ON, template));
3884 case CKA_WRAP:
3885 return (get_bool_attr_from_object(object_p,
3886 WRAP_BOOL_ON, template));
3888 case CKA_TRUSTED:
3889 return (get_bool_attr_from_object(object_p,
3890 TRUSTED_BOOL_ON, template));
3892 case CKA_MODULUS:
3894 * This attribute is valid only for RSA public key
3895 * object.
3897 if (keytype == CKK_RSA) {
3898 return (get_bigint_attr_from_object(
3899 OBJ_PUB_RSA_MOD(object_p), template));
3900 } else {
3901 template->ulValueLen = (CK_ULONG)-1;
3902 return (CKR_ATTRIBUTE_TYPE_INVALID);
3905 case CKA_PUBLIC_EXPONENT:
3906 if (keytype == CKK_RSA) {
3907 return (get_bigint_attr_from_object(
3908 OBJ_PUB_RSA_PUBEXPO(object_p), template));
3909 } else {
3910 template->ulValueLen = (CK_ULONG)-1;
3911 return (CKR_ATTRIBUTE_TYPE_INVALID);
3914 case CKA_MODULUS_BITS:
3915 if (keytype == CKK_RSA) {
3916 return (get_ulong_attr_from_object(
3917 OBJ_PUB_RSA_MOD_BITS(object_p), template));
3918 } else {
3919 template->ulValueLen = (CK_ULONG)-1;
3920 return (CKR_ATTRIBUTE_TYPE_INVALID);
3923 case CKA_PRIME:
3924 switch (keytype) {
3925 case CKK_DSA:
3926 return (get_bigint_attr_from_object(
3927 OBJ_PUB_DSA_PRIME(object_p), template));
3929 case CKK_DH:
3930 return (get_bigint_attr_from_object(
3931 OBJ_PUB_DH_PRIME(object_p), template));
3933 case CKK_X9_42_DH:
3934 return (get_bigint_attr_from_object(
3935 OBJ_PUB_DH942_PRIME(object_p), template));
3937 default:
3938 template->ulValueLen = (CK_ULONG)-1;
3939 return (CKR_ATTRIBUTE_TYPE_INVALID);
3942 case CKA_SUBPRIME:
3943 switch (keytype) {
3944 case CKK_DSA:
3945 return (get_bigint_attr_from_object(
3946 OBJ_PUB_DSA_SUBPRIME(object_p), template));
3948 case CKK_X9_42_DH:
3949 return (get_bigint_attr_from_object(
3950 OBJ_PUB_DH942_SUBPRIME(object_p), template));
3952 default:
3953 template->ulValueLen = (CK_ULONG)-1;
3954 return (CKR_ATTRIBUTE_TYPE_INVALID);
3957 case CKA_BASE:
3958 switch (keytype) {
3959 case CKK_DSA:
3960 return (get_bigint_attr_from_object(
3961 OBJ_PUB_DSA_BASE(object_p), template));
3963 case CKK_DH:
3964 return (get_bigint_attr_from_object(
3965 OBJ_PUB_DH_BASE(object_p), template));
3967 case CKK_X9_42_DH:
3968 return (get_bigint_attr_from_object(
3969 OBJ_PUB_DH942_BASE(object_p), template));
3971 default:
3972 template->ulValueLen = (CK_ULONG)-1;
3973 return (CKR_ATTRIBUTE_TYPE_INVALID);
3976 case CKA_EC_POINT:
3977 return (get_bigint_attr_from_object(
3978 OBJ_PUB_EC_POINT(object_p), template));
3980 case CKA_VALUE:
3981 switch (keytype) {
3982 case CKK_DSA:
3983 return (get_bigint_attr_from_object(
3984 OBJ_PUB_DSA_VALUE(object_p), template));
3986 case CKK_DH:
3987 return (get_bigint_attr_from_object(
3988 OBJ_PUB_DH_VALUE(object_p), template));
3990 case CKK_X9_42_DH:
3991 return (get_bigint_attr_from_object(
3992 OBJ_PUB_DH942_VALUE(object_p), template));
3994 default:
3995 template->ulValueLen = (CK_ULONG)-1;
3996 return (CKR_ATTRIBUTE_TYPE_INVALID);
3999 default:
4001 * First, get the value of the request attribute defined
4002 * in the list of common key attributes. If the request
4003 * attribute is not found in that list, then get the
4004 * attribute from the list of common attributes.
4006 rv = soft_get_common_key_attrs(object_p, template);
4007 if (rv == CKR_ATTRIBUTE_TYPE_INVALID) {
4008 rv = soft_get_common_attrs(object_p, template,
4009 object_p->object_type);
4011 break;
4014 return (rv);
4019 * Get the value of a requested attribute of a Private Key Object.
4021 * Rule: All the attributes in the private key object can be revealed
4022 * except those marked with footnote number "7" when the object
4023 * has its CKA_SENSITIVE attribute set to TRUE or its
4024 * CKA_EXTRACTABLE attribute set to FALSE (p.88 in PKCS11 spec.).
4026 CK_RV
4027 soft_get_private_key_attribute(soft_object_t *object_p,
4028 CK_ATTRIBUTE_PTR template)
4031 CK_RV rv = CKR_OK;
4032 CK_KEY_TYPE keytype = object_p->key_type;
4036 * If the following specified attributes for the private key
4037 * object cannot be revealed because the object is sensitive
4038 * or unextractable, then the ulValueLen is set to -1.
4040 if ((object_p->bool_attr_mask & SENSITIVE_BOOL_ON) ||
4041 !(object_p->bool_attr_mask & EXTRACTABLE_BOOL_ON)) {
4043 switch (template->type) {
4044 case CKA_PRIVATE_EXPONENT:
4045 case CKA_PRIME_1:
4046 case CKA_PRIME_2:
4047 case CKA_EXPONENT_1:
4048 case CKA_EXPONENT_2:
4049 case CKA_COEFFICIENT:
4050 case CKA_VALUE:
4051 template->ulValueLen = (CK_ULONG)-1;
4052 return (CKR_ATTRIBUTE_SENSITIVE);
4056 switch (template->type) {
4058 case CKA_SUBJECT:
4059 case CKA_EC_PARAMS:
4061 * The above extra attributes have byte array type.
4063 return (get_extra_attr_from_object(object_p,
4064 template));
4066 /* Key related boolean attributes */
4067 case CKA_SENSITIVE:
4068 return (get_bool_attr_from_object(object_p,
4069 SENSITIVE_BOOL_ON, template));
4071 case CKA_SECONDARY_AUTH:
4072 return (get_bool_attr_from_object(object_p,
4073 SECONDARY_AUTH_BOOL_ON, template));
4075 case CKA_DECRYPT:
4076 return (get_bool_attr_from_object(object_p,
4077 DECRYPT_BOOL_ON, template));
4079 case CKA_SIGN:
4080 return (get_bool_attr_from_object(object_p,
4081 SIGN_BOOL_ON, template));
4083 case CKA_SIGN_RECOVER:
4084 return (get_bool_attr_from_object(object_p,
4085 SIGN_RECOVER_BOOL_ON, template));
4087 case CKA_UNWRAP:
4088 return (get_bool_attr_from_object(object_p,
4089 UNWRAP_BOOL_ON, template));
4091 case CKA_EXTRACTABLE:
4092 return (get_bool_attr_from_object(object_p,
4093 EXTRACTABLE_BOOL_ON, template));
4095 case CKA_ALWAYS_SENSITIVE:
4096 return (get_bool_attr_from_object(object_p,
4097 ALWAYS_SENSITIVE_BOOL_ON, template));
4099 case CKA_NEVER_EXTRACTABLE:
4100 return (get_bool_attr_from_object(object_p,
4101 NEVER_EXTRACTABLE_BOOL_ON, template));
4103 case CKA_MODULUS:
4104 if (keytype == CKK_RSA) {
4105 return (get_bigint_attr_from_object(
4106 OBJ_PRI_RSA_MOD(object_p), template));
4107 } else {
4108 template->ulValueLen = (CK_ULONG)-1;
4109 rv = CKR_ATTRIBUTE_TYPE_INVALID;
4110 break;
4113 case CKA_PUBLIC_EXPONENT:
4114 if (keytype == CKK_RSA) {
4115 return (get_bigint_attr_from_object(
4116 OBJ_PRI_RSA_PUBEXPO(object_p), template));
4117 } else {
4118 template->ulValueLen = (CK_ULONG)-1;
4119 rv = CKR_ATTRIBUTE_TYPE_INVALID;
4120 break;
4123 case CKA_PRIVATE_EXPONENT:
4124 if (keytype == CKK_RSA) {
4125 return (get_bigint_attr_from_object(
4126 OBJ_PRI_RSA_PRIEXPO(object_p), template));
4127 } else {
4128 template->ulValueLen = (CK_ULONG)-1;
4129 rv = CKR_ATTRIBUTE_TYPE_INVALID;
4130 break;
4133 case CKA_PRIME_1:
4134 if (keytype == CKK_RSA) {
4135 return (get_bigint_attr_from_object(
4136 OBJ_PRI_RSA_PRIME1(object_p), template));
4137 } else {
4138 template->ulValueLen = (CK_ULONG)-1;
4139 rv = CKR_ATTRIBUTE_TYPE_INVALID;
4140 break;
4143 case CKA_PRIME_2:
4144 if (keytype == CKK_RSA) {
4145 return (get_bigint_attr_from_object(
4146 OBJ_PRI_RSA_PRIME2(object_p), template));
4147 } else {
4148 template->ulValueLen = (CK_ULONG)-1;
4149 rv = CKR_ATTRIBUTE_TYPE_INVALID;
4150 break;
4153 case CKA_EXPONENT_1:
4154 if (keytype == CKK_RSA) {
4155 return (get_bigint_attr_from_object(
4156 OBJ_PRI_RSA_EXPO1(object_p), template));
4157 } else {
4158 template->ulValueLen = (CK_ULONG)-1;
4159 rv = CKR_ATTRIBUTE_TYPE_INVALID;
4160 break;
4163 case CKA_EXPONENT_2:
4164 if (keytype == CKK_RSA) {
4165 return (get_bigint_attr_from_object(
4166 OBJ_PRI_RSA_EXPO2(object_p), template));
4167 } else {
4168 template->ulValueLen = (CK_ULONG)-1;
4169 rv = CKR_ATTRIBUTE_TYPE_INVALID;
4170 break;
4173 case CKA_COEFFICIENT:
4174 if (keytype == CKK_RSA) {
4175 return (get_bigint_attr_from_object(
4176 OBJ_PRI_RSA_COEF(object_p), template));
4177 } else {
4178 template->ulValueLen = (CK_ULONG)-1;
4179 rv = CKR_ATTRIBUTE_TYPE_INVALID;
4180 break;
4183 case CKA_VALUE_BITS:
4184 if (keytype == CKK_DH) {
4185 return (get_ulong_attr_from_object(
4186 OBJ_PRI_DH_VAL_BITS(object_p), template));
4187 } else {
4188 template->ulValueLen = (CK_ULONG)-1;
4189 rv = CKR_ATTRIBUTE_TYPE_INVALID;
4190 break;
4193 case CKA_PRIME:
4194 switch (keytype) {
4195 case CKK_DSA:
4196 return (get_bigint_attr_from_object(
4197 OBJ_PRI_DSA_PRIME(object_p), template));
4199 case CKK_DH:
4200 return (get_bigint_attr_from_object(
4201 OBJ_PRI_DH_PRIME(object_p), template));
4203 case CKK_X9_42_DH:
4204 return (get_bigint_attr_from_object(
4205 OBJ_PRI_DH942_PRIME(object_p), template));
4207 default:
4208 template->ulValueLen = (CK_ULONG)-1;
4209 return (CKR_ATTRIBUTE_TYPE_INVALID);
4212 case CKA_SUBPRIME:
4213 switch (keytype) {
4214 case CKK_DSA:
4215 return (get_bigint_attr_from_object(
4216 OBJ_PRI_DSA_SUBPRIME(object_p), template));
4218 case CKK_X9_42_DH:
4219 return (get_bigint_attr_from_object(
4220 OBJ_PRI_DH942_SUBPRIME(object_p), template));
4222 default:
4223 template->ulValueLen = (CK_ULONG)-1;
4224 return (CKR_ATTRIBUTE_TYPE_INVALID);
4227 case CKA_BASE:
4228 switch (keytype) {
4229 case CKK_DSA:
4230 return (get_bigint_attr_from_object(
4231 OBJ_PRI_DSA_BASE(object_p), template));
4233 case CKK_DH:
4234 return (get_bigint_attr_from_object(
4235 OBJ_PRI_DH_BASE(object_p), template));
4237 case CKK_X9_42_DH:
4238 return (get_bigint_attr_from_object(
4239 OBJ_PRI_DH942_BASE(object_p), template));
4241 default:
4242 template->ulValueLen = (CK_ULONG)-1;
4243 return (CKR_ATTRIBUTE_TYPE_INVALID);
4246 case CKA_VALUE:
4247 switch (keytype) {
4248 case CKK_DSA:
4249 return (get_bigint_attr_from_object(
4250 OBJ_PRI_DSA_VALUE(object_p), template));
4252 case CKK_DH:
4253 return (get_bigint_attr_from_object(
4254 OBJ_PRI_DH_VALUE(object_p), template));
4256 case CKK_X9_42_DH:
4257 return (get_bigint_attr_from_object(
4258 OBJ_PRI_DH942_VALUE(object_p), template));
4260 case CKK_EC:
4261 return (get_bigint_attr_from_object(
4262 OBJ_PRI_EC_VALUE(object_p), template));
4264 default:
4265 template->ulValueLen = (CK_ULONG)-1;
4266 return (CKR_ATTRIBUTE_TYPE_INVALID);
4269 default:
4271 * First, get the value of the request attribute defined
4272 * in the list of common key attributes. If the request
4273 * attribute is not found in that list, then get the
4274 * attribute from the list of common attributes.
4276 rv = soft_get_common_key_attrs(object_p, template);
4277 if (rv == CKR_ATTRIBUTE_TYPE_INVALID) {
4278 rv = soft_get_common_attrs(object_p, template,
4279 object_p->object_type);
4281 break;
4284 return (rv);
4289 * Get the value of a requested attribute of a Secret Key Object.
4291 * Rule: All the attributes in the secret key object can be revealed
4292 * except those marked with footnote number "7" when the object
4293 * has its CKA_SENSITIVE attribute set to TRUE or its
4294 * CKA_EXTRACTABLE attribute set to FALSE (p.88 in PKCS11 spec.).
4296 CK_RV
4297 soft_get_secret_key_attribute(soft_object_t *object_p,
4298 CK_ATTRIBUTE_PTR template)
4301 CK_RV rv = CKR_OK;
4302 CK_KEY_TYPE keytype = object_p->key_type;
4304 switch (template->type) {
4306 /* Key related boolean attributes */
4307 case CKA_SENSITIVE:
4308 return (get_bool_attr_from_object(object_p,
4309 SENSITIVE_BOOL_ON, template));
4311 case CKA_ENCRYPT:
4312 return (get_bool_attr_from_object(object_p,
4313 ENCRYPT_BOOL_ON, template));
4315 case CKA_DECRYPT:
4316 return (get_bool_attr_from_object(object_p,
4317 DECRYPT_BOOL_ON, template));
4319 case CKA_SIGN:
4320 return (get_bool_attr_from_object(object_p,
4321 SIGN_BOOL_ON, template));
4323 case CKA_VERIFY:
4324 return (get_bool_attr_from_object(object_p,
4325 VERIFY_BOOL_ON, template));
4327 case CKA_WRAP:
4328 return (get_bool_attr_from_object(object_p,
4329 WRAP_BOOL_ON, template));
4331 case CKA_UNWRAP:
4332 return (get_bool_attr_from_object(object_p,
4333 UNWRAP_BOOL_ON, template));
4335 case CKA_EXTRACTABLE:
4336 return (get_bool_attr_from_object(object_p,
4337 EXTRACTABLE_BOOL_ON, template));
4339 case CKA_ALWAYS_SENSITIVE:
4340 return (get_bool_attr_from_object(object_p,
4341 ALWAYS_SENSITIVE_BOOL_ON, template));
4343 case CKA_NEVER_EXTRACTABLE:
4344 return (get_bool_attr_from_object(object_p,
4345 NEVER_EXTRACTABLE_BOOL_ON, template));
4347 case CKA_VALUE:
4348 case CKA_VALUE_LEN:
4350 * If the specified attribute for the secret key object
4351 * cannot be revealed because the object is sensitive
4352 * or unextractable, then the ulValueLen is set to -1.
4354 if ((object_p->bool_attr_mask & SENSITIVE_BOOL_ON) ||
4355 !(object_p->bool_attr_mask & EXTRACTABLE_BOOL_ON)) {
4356 template->ulValueLen = (CK_ULONG)-1;
4357 return (CKR_ATTRIBUTE_SENSITIVE);
4360 switch (keytype) {
4361 case CKK_RC4:
4362 case CKK_GENERIC_SECRET:
4363 case CKK_RC5:
4364 case CKK_DES:
4365 case CKK_DES2:
4366 case CKK_DES3:
4367 case CKK_CDMF:
4368 case CKK_AES:
4369 case CKK_BLOWFISH:
4370 if (template->type == CKA_VALUE_LEN) {
4371 return (get_ulong_attr_from_object(
4372 OBJ_SEC_VALUE_LEN(object_p),
4373 template));
4374 } else {
4375 return (get_bigint_attr_from_object(
4376 (biginteger_t *)OBJ_SEC(object_p),
4377 template));
4379 default:
4380 template->ulValueLen = (CK_ULONG)-1;
4381 rv = CKR_ATTRIBUTE_TYPE_INVALID;
4382 break;
4384 break;
4386 default:
4388 * First, get the value of the request attribute defined
4389 * in the list of common key attributes. If the request
4390 * attribute is not found in that list, then get the
4391 * attribute from the list of common attributes.
4393 rv = soft_get_common_key_attrs(object_p, template);
4394 if (rv == CKR_ATTRIBUTE_TYPE_INVALID) {
4395 rv = soft_get_common_attrs(object_p, template,
4396 object_p->object_type);
4398 break;
4401 return (rv);
4406 * Get the value of a requested attribute of a Domain Parameters Object.
4408 * Rule: All the attributes in the domain parameters object can be revealed.
4410 CK_RV
4411 soft_get_domain_parameters_attribute(soft_object_t *object_p,
4412 CK_ATTRIBUTE_PTR template)
4415 CK_RV rv = CKR_OK;
4416 CK_KEY_TYPE keytype = object_p->key_type;
4418 switch (template->type) {
4420 case CKA_KEY_TYPE:
4421 return (get_ulong_attr_from_object(keytype,
4422 template));
4424 case CKA_LOCAL:
4425 return (get_bool_attr_from_object(object_p,
4426 LOCAL_BOOL_ON, template));
4428 case CKA_PRIME:
4429 switch (keytype) {
4430 case CKK_DSA:
4431 return (get_bigint_attr_from_object(
4432 OBJ_DOM_DSA_PRIME(object_p), template));
4434 case CKK_DH:
4435 return (get_bigint_attr_from_object(
4436 OBJ_DOM_DH_PRIME(object_p), template));
4438 case CKK_X9_42_DH:
4439 return (get_bigint_attr_from_object(
4440 OBJ_DOM_DH942_PRIME(object_p), template));
4442 default:
4443 template->ulValueLen = (CK_ULONG)-1;
4444 return (CKR_ATTRIBUTE_TYPE_INVALID);
4447 case CKA_SUBPRIME:
4448 switch (keytype) {
4449 case CKK_DSA:
4450 return (get_bigint_attr_from_object(
4451 OBJ_DOM_DSA_SUBPRIME(object_p), template));
4453 case CKK_X9_42_DH:
4454 return (get_bigint_attr_from_object(
4455 OBJ_DOM_DH942_SUBPRIME(object_p), template));
4457 default:
4458 template->ulValueLen = (CK_ULONG)-1;
4459 return (CKR_ATTRIBUTE_TYPE_INVALID);
4462 case CKA_BASE:
4463 switch (keytype) {
4464 case CKK_DSA:
4465 return (get_bigint_attr_from_object(
4466 OBJ_DOM_DSA_BASE(object_p), template));
4468 case CKK_DH:
4469 return (get_bigint_attr_from_object(
4470 OBJ_DOM_DH_BASE(object_p), template));
4472 case CKK_X9_42_DH:
4473 return (get_bigint_attr_from_object(
4474 OBJ_DOM_DH942_BASE(object_p), template));
4476 default:
4477 template->ulValueLen = (CK_ULONG)-1;
4478 return (CKR_ATTRIBUTE_TYPE_INVALID);
4481 case CKA_PRIME_BITS:
4482 switch (keytype) {
4483 case CKK_DSA:
4484 return (get_ulong_attr_from_object(
4485 OBJ_DOM_DSA_PRIME_BITS(object_p), template));
4487 case CKK_DH:
4488 return (get_ulong_attr_from_object(
4489 OBJ_DOM_DH_PRIME_BITS(object_p), template));
4491 case CKK_X9_42_DH:
4492 return (get_ulong_attr_from_object(
4493 OBJ_DOM_DH942_PRIME_BITS(object_p), template));
4495 default:
4496 template->ulValueLen = (CK_ULONG)-1;
4497 return (CKR_ATTRIBUTE_TYPE_INVALID);
4500 case CKA_SUB_PRIME_BITS:
4501 switch (keytype) {
4502 case CKK_X9_42_DH:
4503 return (get_ulong_attr_from_object(
4504 OBJ_DOM_DH942_SUBPRIME_BITS(object_p), template));
4506 default:
4507 template->ulValueLen = (CK_ULONG)-1;
4508 return (CKR_ATTRIBUTE_TYPE_INVALID);
4511 default:
4513 * Get the value of a common attribute.
4515 rv = soft_get_common_attrs(object_p, template,
4516 object_p->object_type);
4517 break;
4520 return (rv);
4524 * Get certificate attributes from an object.
4525 * return CKR_ATTRIBUTE_TYPE_INVALID if the requested type
4526 * does not exist in the certificate.
4528 CK_RV
4529 soft_get_certificate_attribute(soft_object_t *object_p,
4530 CK_ATTRIBUTE_PTR template)
4532 CK_CERTIFICATE_TYPE certtype = object_p->cert_type;
4533 cert_attr_t src;
4535 switch (template->type) {
4536 case CKA_SUBJECT:
4537 if (certtype == CKC_X_509) {
4538 return (get_cert_attr_from_object(
4539 X509_CERT_SUBJECT(object_p), template));
4541 break;
4542 case CKA_VALUE:
4543 if (certtype == CKC_X_509) {
4544 return (get_cert_attr_from_object(
4545 X509_CERT_VALUE(object_p), template));
4546 } else if (certtype == CKC_X_509_ATTR_CERT) {
4547 return (get_cert_attr_from_object(
4548 X509_ATTR_CERT_VALUE(object_p), template));
4550 break;
4551 case CKA_OWNER:
4552 if (certtype == CKC_X_509_ATTR_CERT) {
4553 return (get_cert_attr_from_object(
4554 X509_ATTR_CERT_OWNER(object_p), template));
4556 break;
4557 case CKA_CERTIFICATE_TYPE:
4558 src.value = (CK_BYTE *)&certtype;
4559 src.length = sizeof (certtype);
4560 return (get_cert_attr_from_object(&src, template));
4561 case CKA_TRUSTED:
4562 return (get_bool_attr_from_object(object_p,
4563 TRUSTED_BOOL_ON, template));
4564 case CKA_ID:
4565 case CKA_ISSUER:
4566 case CKA_SERIAL_NUMBER:
4567 case CKA_AC_ISSUER:
4568 case CKA_ATTR_TYPES:
4569 return (get_extra_attr_from_object(object_p,
4570 template));
4571 default:
4572 return (soft_get_common_attrs(object_p, template,
4573 object_p->object_type));
4577 * If we got this far, then the combination of certificate type
4578 * and requested attribute is invalid.
4580 return (CKR_ATTRIBUTE_TYPE_INVALID);
4583 CK_RV
4584 soft_set_certificate_attribute(soft_object_t *object_p,
4585 CK_ATTRIBUTE_PTR template, boolean_t copy)
4587 CK_CERTIFICATE_TYPE certtype = object_p->cert_type;
4589 switch (template->type) {
4590 case CKA_SUBJECT:
4591 if (certtype == CKC_X_509) {
4592 /* SUBJECT attr cannot be modified. */
4593 return (CKR_ATTRIBUTE_READ_ONLY);
4595 break;
4596 case CKA_OWNER:
4597 if (certtype == CKC_X_509_ATTR_CERT) {
4598 /* OWNER attr cannot be modified. */
4599 return (CKR_ATTRIBUTE_READ_ONLY);
4601 break;
4602 case CKA_VALUE:
4603 /* VALUE attr cannot be modified. */
4604 return (CKR_ATTRIBUTE_READ_ONLY);
4605 case CKA_ID:
4606 case CKA_ISSUER:
4607 if (certtype == CKC_X_509) {
4608 return (set_extra_attr_to_object(object_p,
4609 template->type, template));
4611 break;
4612 case CKA_AC_ISSUER:
4613 case CKA_ATTR_TYPES:
4614 if (certtype == CKC_X_509_ATTR_CERT) {
4615 return (set_extra_attr_to_object(object_p,
4616 template->type, template));
4618 break;
4619 case CKA_SERIAL_NUMBER:
4620 case CKA_LABEL:
4621 return (set_extra_attr_to_object(object_p,
4622 template->type, template));
4623 default:
4624 return (soft_set_common_storage_attribute(
4625 object_p, template, copy));
4629 * If we got this far, then the combination of certificate type
4630 * and requested attribute is invalid.
4632 return (CKR_ATTRIBUTE_TYPE_INVALID);
4636 * Call the appropriate get attribute function according to the class
4637 * of object.
4639 * The caller of this function holds the lock on the object.
4641 CK_RV
4642 soft_get_attribute(soft_object_t *object_p, CK_ATTRIBUTE_PTR template)
4645 CK_RV rv = CKR_OK;
4646 CK_OBJECT_CLASS class = object_p->class;
4648 switch (class) {
4649 case CKO_PUBLIC_KEY:
4650 rv = soft_get_public_key_attribute(object_p, template);
4651 break;
4653 case CKO_PRIVATE_KEY:
4654 rv = soft_get_private_key_attribute(object_p, template);
4655 break;
4657 case CKO_SECRET_KEY:
4658 rv = soft_get_secret_key_attribute(object_p, template);
4659 break;
4661 case CKO_DOMAIN_PARAMETERS:
4662 rv = soft_get_domain_parameters_attribute(object_p, template);
4663 break;
4665 case CKO_CERTIFICATE:
4666 rv = soft_get_certificate_attribute(object_p, template);
4667 break;
4669 default:
4671 * If the specified attribute for the object is invalid
4672 * (the object does not possess such as attribute), then
4673 * the ulValueLen is modified to hold the value -1.
4675 template->ulValueLen = (CK_ULONG)-1;
4676 return (CKR_ATTRIBUTE_TYPE_INVALID);
4679 return (rv);
4683 CK_RV
4684 soft_set_common_storage_attribute(soft_object_t *object_p,
4685 CK_ATTRIBUTE_PTR template, boolean_t copy)
4688 CK_RV rv = CKR_OK;
4690 switch (template->type) {
4692 case CKA_TOKEN:
4693 if (copy) {
4694 if ((*(CK_BBOOL *)template->pValue) == B_TRUE) {
4695 if (!soft_keystore_status(KEYSTORE_INITIALIZED))
4696 return (CKR_DEVICE_REMOVED);
4697 object_p->object_type |= TOKEN_OBJECT;
4699 } else {
4700 rv = CKR_ATTRIBUTE_READ_ONLY;
4703 break;
4705 case CKA_PRIVATE:
4706 if (copy) {
4707 if ((*(CK_BBOOL *)template->pValue) == B_TRUE) {
4708 (void) pthread_mutex_lock(&soft_giant_mutex);
4709 if (!soft_slot.authenticated) {
4711 * Check if this is the special case
4712 * when the PIN is never initialized
4713 * in the keystore. If true, we will
4714 * let it pass here and let it fail
4715 * with CKR_PIN_EXPIRED later on.
4717 if (!soft_slot.userpin_change_needed) {
4718 (void) pthread_mutex_unlock(
4719 &soft_giant_mutex);
4720 return (CKR_USER_NOT_LOGGED_IN);
4723 (void) pthread_mutex_unlock(&soft_giant_mutex);
4724 object_p->object_type |= PRIVATE_OBJECT;
4726 } else {
4727 rv = CKR_ATTRIBUTE_READ_ONLY;
4729 break;
4731 case CKA_MODIFIABLE:
4732 if (copy) {
4733 if ((*(CK_BBOOL *)template->pValue) == TRUE)
4734 object_p->bool_attr_mask &=
4735 ~NOT_MODIFIABLE_BOOL_ON;
4736 else
4737 object_p->bool_attr_mask |=
4738 NOT_MODIFIABLE_BOOL_ON;
4739 } else {
4740 rv = CKR_ATTRIBUTE_READ_ONLY;
4742 break;
4744 case CKA_CLASS:
4745 rv = CKR_ATTRIBUTE_READ_ONLY;
4746 break;
4748 default:
4749 rv = CKR_TEMPLATE_INCONSISTENT;
4752 return (rv);
4756 * Set the value of an attribute that is common to all key objects
4757 * (i.e. public key, private key and secret key).
4759 CK_RV
4760 soft_set_common_key_attribute(soft_object_t *object_p,
4761 CK_ATTRIBUTE_PTR template, boolean_t copy)
4764 switch (template->type) {
4766 case CKA_LABEL:
4768 * Only the LABEL can be modified in the common storage
4769 * object attributes after the object is created.
4771 return (set_extra_attr_to_object(object_p,
4772 CKA_LABEL, template));
4774 case CKA_ID:
4775 return (set_extra_attr_to_object(object_p,
4776 CKA_ID, template));
4778 case CKA_START_DATE:
4779 return (set_extra_attr_to_object(object_p,
4780 CKA_START_DATE, template));
4782 case CKA_END_DATE:
4783 return (set_extra_attr_to_object(object_p,
4784 CKA_END_DATE, template));
4786 case CKA_DERIVE:
4787 return (set_bool_attr_to_object(object_p,
4788 DERIVE_BOOL_ON, template));
4790 case CKA_KEY_TYPE:
4791 case CKA_LOCAL:
4792 case CKA_KEY_GEN_MECHANISM:
4793 return (CKR_ATTRIBUTE_READ_ONLY);
4795 default:
4796 return (soft_set_common_storage_attribute(object_p,
4797 template, copy));
4805 * Set the value of an attribute of a Public Key Object.
4807 * Rule: The attributes marked with footnote number "8" in the PKCS11
4808 * spec may be modified (p.88 in PKCS11 spec.).
4810 CK_RV
4811 soft_set_public_key_attribute(soft_object_t *object_p,
4812 CK_ATTRIBUTE_PTR template, boolean_t copy)
4814 CK_KEY_TYPE keytype = object_p->key_type;
4816 switch (template->type) {
4818 case CKA_SUBJECT:
4819 return (set_extra_attr_to_object(object_p,
4820 CKA_SUBJECT, template));
4822 case CKA_ENCRYPT:
4823 return (set_bool_attr_to_object(object_p,
4824 ENCRYPT_BOOL_ON, template));
4826 case CKA_VERIFY:
4827 return (set_bool_attr_to_object(object_p,
4828 VERIFY_BOOL_ON, template));
4830 case CKA_VERIFY_RECOVER:
4831 return (set_bool_attr_to_object(object_p,
4832 VERIFY_RECOVER_BOOL_ON, template));
4834 case CKA_WRAP:
4835 return (set_bool_attr_to_object(object_p,
4836 WRAP_BOOL_ON, template));
4838 case CKA_MODULUS:
4839 case CKA_MODULUS_BITS:
4840 case CKA_PUBLIC_EXPONENT:
4841 if (keytype == CKK_RSA)
4842 return (CKR_ATTRIBUTE_READ_ONLY);
4843 break;
4845 case CKA_SUBPRIME:
4846 if ((keytype == CKK_DSA) ||
4847 (keytype == CKK_X9_42_DH))
4848 return (CKR_ATTRIBUTE_READ_ONLY);
4849 break;
4851 case CKA_PRIME:
4852 case CKA_BASE:
4853 case CKA_VALUE:
4854 if ((keytype == CKK_DSA) ||
4855 (keytype == CKK_DH) ||
4856 (keytype == CKK_X9_42_DH))
4857 return (CKR_ATTRIBUTE_READ_ONLY);
4858 break;
4860 default:
4862 * Set the value of a common key attribute.
4864 return (soft_set_common_key_attribute(object_p,
4865 template, copy));
4869 * If we got this far, then the combination of key type
4870 * and requested attribute is invalid.
4872 return (CKR_ATTRIBUTE_TYPE_INVALID);
4877 * Set the value of an attribute of a Private Key Object.
4879 * Rule: The attributes marked with footnote number "8" in the PKCS11
4880 * spec may be modified (p.88 in PKCS11 spec.).
4882 CK_RV
4883 soft_set_private_key_attribute(soft_object_t *object_p,
4884 CK_ATTRIBUTE_PTR template, boolean_t copy)
4886 CK_KEY_TYPE keytype = object_p->key_type;
4888 switch (template->type) {
4890 case CKA_SUBJECT:
4891 return (set_extra_attr_to_object(object_p,
4892 CKA_SUBJECT, template));
4894 case CKA_SENSITIVE:
4896 * Cannot set SENSITIVE to FALSE if it is already ON.
4898 if (((*(CK_BBOOL *)template->pValue) == B_FALSE) &&
4899 (object_p->bool_attr_mask & SENSITIVE_BOOL_ON)) {
4900 return (CKR_ATTRIBUTE_READ_ONLY);
4903 if (*(CK_BBOOL *)template->pValue)
4904 object_p->bool_attr_mask |= SENSITIVE_BOOL_ON;
4905 return (CKR_OK);
4907 case CKA_DECRYPT:
4908 return (set_bool_attr_to_object(object_p,
4909 DECRYPT_BOOL_ON, template));
4911 case CKA_SIGN:
4912 return (set_bool_attr_to_object(object_p,
4913 SIGN_BOOL_ON, template));
4915 case CKA_SIGN_RECOVER:
4916 return (set_bool_attr_to_object(object_p,
4917 SIGN_RECOVER_BOOL_ON, template));
4919 case CKA_UNWRAP:
4920 return (set_bool_attr_to_object(object_p,
4921 UNWRAP_BOOL_ON, template));
4923 case CKA_EXTRACTABLE:
4925 * Cannot set EXTRACTABLE to TRUE if it is already OFF.
4927 if ((*(CK_BBOOL *)template->pValue) &&
4928 !(object_p->bool_attr_mask & EXTRACTABLE_BOOL_ON)) {
4929 return (CKR_ATTRIBUTE_READ_ONLY);
4932 if ((*(CK_BBOOL *)template->pValue) == B_FALSE)
4933 object_p->bool_attr_mask &= ~EXTRACTABLE_BOOL_ON;
4934 return (CKR_OK);
4936 case CKA_MODULUS:
4937 case CKA_PUBLIC_EXPONENT:
4938 case CKA_PRIVATE_EXPONENT:
4939 case CKA_PRIME_1:
4940 case CKA_PRIME_2:
4941 case CKA_EXPONENT_1:
4942 case CKA_EXPONENT_2:
4943 case CKA_COEFFICIENT:
4944 if (keytype == CKK_RSA) {
4945 return (CKR_ATTRIBUTE_READ_ONLY);
4947 break;
4949 case CKA_SUBPRIME:
4950 if ((keytype == CKK_DSA) ||
4951 (keytype == CKK_X9_42_DH))
4952 return (CKR_ATTRIBUTE_READ_ONLY);
4953 break;
4955 case CKA_PRIME:
4956 case CKA_BASE:
4957 case CKA_VALUE:
4958 if ((keytype == CKK_DSA) ||
4959 (keytype == CKK_DH) ||
4960 (keytype == CKK_X9_42_DH))
4961 return (CKR_ATTRIBUTE_READ_ONLY);
4962 break;
4964 case CKA_VALUE_BITS:
4965 if (keytype == CKK_DH)
4966 return (CKR_ATTRIBUTE_READ_ONLY);
4967 break;
4969 default:
4971 * Set the value of a common key attribute.
4973 return (soft_set_common_key_attribute(object_p,
4974 template, copy));
4978 * If we got this far, then the combination of key type
4979 * and requested attribute is invalid.
4981 return (CKR_ATTRIBUTE_TYPE_INVALID);
4985 * Set the value of an attribute of a Secret Key Object.
4987 * Rule: The attributes marked with footnote number "8" in the PKCS11
4988 * spec may be modified (p.88 in PKCS11 spec.).
4990 CK_RV
4991 soft_set_secret_key_attribute(soft_object_t *object_p,
4992 CK_ATTRIBUTE_PTR template, boolean_t copy)
4994 CK_KEY_TYPE keytype = object_p->key_type;
4996 switch (template->type) {
4998 case CKA_SENSITIVE:
5000 * Cannot set SENSITIVE to FALSE if it is already ON.
5002 if (((*(CK_BBOOL *)template->pValue) == B_FALSE) &&
5003 (object_p->bool_attr_mask & SENSITIVE_BOOL_ON)) {
5004 return (CKR_ATTRIBUTE_READ_ONLY);
5007 if (*(CK_BBOOL *)template->pValue)
5008 object_p->bool_attr_mask |= SENSITIVE_BOOL_ON;
5009 return (CKR_OK);
5011 case CKA_ENCRYPT:
5012 return (set_bool_attr_to_object(object_p,
5013 ENCRYPT_BOOL_ON, template));
5015 case CKA_DECRYPT:
5016 return (set_bool_attr_to_object(object_p,
5017 DECRYPT_BOOL_ON, template));
5019 case CKA_SIGN:
5020 return (set_bool_attr_to_object(object_p,
5021 SIGN_BOOL_ON, template));
5023 case CKA_VERIFY:
5024 return (set_bool_attr_to_object(object_p,
5025 VERIFY_BOOL_ON, template));
5027 case CKA_WRAP:
5028 return (set_bool_attr_to_object(object_p,
5029 WRAP_BOOL_ON, template));
5031 case CKA_UNWRAP:
5032 return (set_bool_attr_to_object(object_p,
5033 UNWRAP_BOOL_ON, template));
5035 case CKA_EXTRACTABLE:
5037 * Cannot set EXTRACTABLE to TRUE if it is already OFF.
5039 if ((*(CK_BBOOL *)template->pValue) &&
5040 !(object_p->bool_attr_mask & EXTRACTABLE_BOOL_ON)) {
5041 return (CKR_ATTRIBUTE_READ_ONLY);
5044 if ((*(CK_BBOOL *)template->pValue) == B_FALSE)
5045 object_p->bool_attr_mask &= ~EXTRACTABLE_BOOL_ON;
5046 return (CKR_OK);
5048 case CKA_VALUE:
5049 return (CKR_ATTRIBUTE_READ_ONLY);
5051 case CKA_VALUE_LEN:
5052 if ((keytype == CKK_RC4) ||
5053 (keytype == CKK_GENERIC_SECRET) ||
5054 (keytype == CKK_AES) ||
5055 (keytype == CKK_BLOWFISH))
5056 return (CKR_ATTRIBUTE_READ_ONLY);
5057 break;
5059 default:
5061 * Set the value of a common key attribute.
5063 return (soft_set_common_key_attribute(object_p,
5064 template, copy));
5068 * If we got this far, then the combination of key type
5069 * and requested attribute is invalid.
5071 return (CKR_ATTRIBUTE_TYPE_INVALID);
5076 * Call the appropriate set attribute function according to the class
5077 * of object.
5079 * The caller of this function does not hold the lock on the original
5080 * object, since this function is setting the attribute on the new object
5081 * that is being modified.
5083 * Argument copy: TRUE when called by C_CopyObject,
5084 * FALSE when called by C_SetAttributeValue.
5086 CK_RV
5087 soft_set_attribute(soft_object_t *object_p, CK_ATTRIBUTE_PTR template,
5088 boolean_t copy)
5091 CK_RV rv = CKR_OK;
5092 CK_OBJECT_CLASS class = object_p->class;
5094 switch (class) {
5096 case CKO_PUBLIC_KEY:
5097 rv = soft_set_public_key_attribute(object_p, template, copy);
5098 break;
5100 case CKO_PRIVATE_KEY:
5101 rv = soft_set_private_key_attribute(object_p, template, copy);
5102 break;
5104 case CKO_SECRET_KEY:
5105 rv = soft_set_secret_key_attribute(object_p, template, copy);
5106 break;
5108 case CKO_DOMAIN_PARAMETERS:
5109 switch (template->type) {
5110 case CKA_LABEL:
5112 * Only the LABEL can be modified in the common
5113 * storage object attributes after the object is
5114 * created.
5116 return (set_extra_attr_to_object(object_p,
5117 CKA_LABEL, template));
5118 default:
5119 return (CKR_TEMPLATE_INCONSISTENT);
5121 case CKO_CERTIFICATE:
5122 rv = soft_set_certificate_attribute(object_p, template, copy);
5123 break;
5125 default:
5127 * If the template specifies a value of an attribute
5128 * which is incompatible with other existing attributes
5129 * of the object, then fails with return code
5130 * CKR_TEMPLATE_INCONSISTENT.
5132 rv = CKR_TEMPLATE_INCONSISTENT;
5133 break;
5136 return (rv);
5139 CK_RV
5140 soft_get_public_value(soft_object_t *key, CK_ATTRIBUTE_TYPE type,
5141 uchar_t *value, uint32_t *value_len)
5143 uint32_t len = 0;
5144 switch (type) {
5146 /* The following attributes belong to RSA */
5147 case CKA_MODULUS:
5148 #ifdef __sparcv9
5149 len =
5150 /* LINTED */
5151 (uint32_t)
5152 ((biginteger_t *)OBJ_PUB_RSA_MOD(key))->big_value_len;
5153 #else /* !__sparcv9 */
5154 len =
5155 ((biginteger_t *)OBJ_PUB_RSA_MOD(key))->big_value_len;
5156 #endif /* __sparcv9 */
5158 /* This attribute MUST BE set */
5159 if (len == 0 || len > *value_len) {
5160 return (CKR_ATTRIBUTE_VALUE_INVALID);
5162 *value_len = len;
5164 (void) memcpy(value,
5165 ((biginteger_t *)OBJ_PUB_RSA_MOD(key))->big_value,
5166 *value_len);
5168 break;
5170 case CKA_PUBLIC_EXPONENT:
5171 #ifdef __sparcv9
5172 len =
5173 /* LINTED */
5174 (uint32_t)
5175 ((biginteger_t *)OBJ_PUB_RSA_PUBEXPO(key))->big_value_len;
5176 #else /* !__sparcv9 */
5177 len =
5178 ((biginteger_t *)OBJ_PUB_RSA_PUBEXPO(key))->big_value_len;
5179 #endif /* __sparcv9 */
5181 /* This attribute MUST BE set */
5182 if (len == 0 || len > *value_len) {
5183 return (CKR_ATTRIBUTE_VALUE_INVALID);
5185 *value_len = len;
5187 (void) memcpy(value,
5188 ((biginteger_t *)OBJ_PUB_RSA_PUBEXPO(key))->big_value,
5189 *value_len);
5191 break;
5193 /* The following attributes belong to DSA and DH */
5194 case CKA_PRIME:
5196 if (key->key_type == CKK_DSA)
5197 #ifdef __sparcv9
5198 len =
5199 /* LINTED */
5200 (uint32_t)
5201 ((biginteger_t *)OBJ_PUB_DSA_PRIME(key))->
5202 big_value_len;
5203 #else /* !__sparcv9 */
5204 len =
5205 ((biginteger_t *)OBJ_PUB_DSA_PRIME(key))->
5206 big_value_len;
5207 #endif /* __sparcv9 */
5208 else
5209 #ifdef __sparcv9
5210 len =
5211 /* LINTED */
5212 (uint32_t)
5213 ((biginteger_t *)OBJ_PUB_DH_PRIME(key))->
5214 big_value_len;
5215 #else /* !__sparcv9 */
5216 len =
5217 ((biginteger_t *)OBJ_PUB_DH_PRIME(key))->
5218 big_value_len;
5219 #endif /* __sparcv9 */
5221 /* This attribute MUST BE set */
5222 if (len == 0 || len > *value_len) {
5223 return (CKR_ATTRIBUTE_VALUE_INVALID);
5225 *value_len = len;
5227 if (key->key_type == CKK_DSA)
5228 (void) memcpy(value,
5229 ((biginteger_t *)OBJ_PUB_DSA_PRIME(key))->big_value,
5230 *value_len);
5231 else
5232 (void) memcpy(value,
5233 ((biginteger_t *)OBJ_PUB_DH_PRIME(key))->big_value,
5234 *value_len);
5236 break;
5238 case CKA_SUBPRIME:
5239 #ifdef __sparcv9
5240 len =
5241 /* LINTED */
5242 (uint32_t)
5243 ((biginteger_t *)OBJ_PUB_DSA_SUBPRIME(key))->big_value_len;
5244 #else /* !__sparcv9 */
5245 len =
5246 ((biginteger_t *)OBJ_PUB_DSA_SUBPRIME(key))->big_value_len;
5247 #endif /* __sparcv9 */
5249 /* This attribute MUST BE set */
5250 if (len == 0 || len > *value_len) {
5251 return (CKR_ATTRIBUTE_VALUE_INVALID);
5253 *value_len = len;
5255 (void) memcpy(value,
5256 ((biginteger_t *)OBJ_PUB_DSA_SUBPRIME(key))->big_value,
5257 *value_len);
5259 break;
5261 case CKA_BASE:
5263 if (key->key_type == CKK_DSA)
5264 #ifdef __sparcv9
5265 len =
5266 /* LINTED */
5267 (uint32_t)
5268 ((biginteger_t *)OBJ_PUB_DSA_BASE(key))->
5269 big_value_len;
5270 #else /* !__sparcv9 */
5271 len =
5272 ((biginteger_t *)OBJ_PUB_DSA_BASE(key))->
5273 big_value_len;
5274 #endif /* __sparcv9 */
5275 else
5276 #ifdef __sparcv9
5277 len =
5278 /* LINTED */
5279 (uint32_t)
5280 ((biginteger_t *)OBJ_PUB_DH_BASE(key))->
5281 big_value_len;
5282 #else /* !__sparcv9 */
5283 len =
5284 ((biginteger_t *)OBJ_PUB_DH_BASE(key))->
5285 big_value_len;
5286 #endif /* __sparcv9 */
5288 /* This attribute MUST BE set */
5289 if (len == 0 || len > *value_len) {
5290 return (CKR_ATTRIBUTE_VALUE_INVALID);
5292 *value_len = len;
5294 if (key->key_type == CKK_DSA)
5295 (void) memcpy(value,
5296 ((biginteger_t *)OBJ_PUB_DSA_BASE(key))->big_value,
5297 *value_len);
5298 else
5299 (void) memcpy(value,
5300 ((biginteger_t *)OBJ_PUB_DH_BASE(key))->big_value,
5301 *value_len);
5302 break;
5304 case CKA_VALUE:
5306 if (key->key_type == CKK_DSA)
5307 #ifdef __sparcv9
5308 len =
5309 /* LINTED */
5310 (uint32_t)
5311 ((biginteger_t *)OBJ_PUB_DSA_VALUE(key))->
5312 big_value_len;
5313 #else /* !__sparcv9 */
5314 len =
5315 ((biginteger_t *)OBJ_PUB_DSA_VALUE(key))->
5316 big_value_len;
5317 #endif /* __sparcv9 */
5318 else
5319 #ifdef __sparcv9
5320 len =
5321 /* LINTED */
5322 (uint32_t)
5323 ((biginteger_t *)OBJ_PUB_DH_VALUE(key))->
5324 big_value_len;
5325 #else /* !__sparcv9 */
5326 len =
5327 ((biginteger_t *)OBJ_PUB_DH_VALUE(key))->
5328 big_value_len;
5329 #endif /* __sparcv9 */
5331 /* This attribute MUST BE set */
5332 if (len == 0 || len > *value_len) {
5333 return (CKR_ATTRIBUTE_VALUE_INVALID);
5335 *value_len = len;
5337 if (key->key_type == CKK_DSA)
5338 (void) memcpy(value,
5339 ((biginteger_t *)OBJ_PUB_DSA_VALUE(key))->big_value,
5340 *value_len);
5341 else
5342 (void) memcpy(value,
5343 ((biginteger_t *)OBJ_PUB_DH_VALUE(key))->big_value,
5344 *value_len);
5346 break;
5349 return (CKR_OK);
5353 CK_RV
5354 soft_get_private_value(soft_object_t *key, CK_ATTRIBUTE_TYPE type,
5355 uchar_t *value, uint32_t *value_len)
5358 uint32_t len = 0;
5360 switch (type) {
5362 /* The following attributes belong to RSA */
5363 case CKA_MODULUS:
5364 #ifdef __sparcv9
5365 len =
5366 /* LINTED */
5367 (uint32_t)
5368 ((biginteger_t *)OBJ_PRI_RSA_MOD(key))->big_value_len;
5369 #else /* !__sparcv9 */
5370 len =
5371 ((biginteger_t *)OBJ_PRI_RSA_MOD(key))->big_value_len;
5372 #endif /* __sparcv9 */
5374 /* This attribute MUST BE set */
5375 if (len == 0 || len > *value_len) {
5376 return (CKR_ATTRIBUTE_VALUE_INVALID);
5378 *value_len = len;
5380 (void) memcpy(value,
5381 ((biginteger_t *)OBJ_PRI_RSA_MOD(key))->big_value,
5382 *value_len);
5384 break;
5386 case CKA_PRIVATE_EXPONENT:
5387 #ifdef __sparcv9
5388 len =
5389 /* LINTED */
5390 (uint32_t)
5391 ((biginteger_t *)OBJ_PRI_RSA_PRIEXPO(key))->big_value_len;
5392 #else /* !__sparcv9 */
5393 len =
5394 ((biginteger_t *)OBJ_PRI_RSA_PRIEXPO(key))->big_value_len;
5395 #endif /* __sparcv9 */
5397 /* This attribute MUST BE set */
5398 if (len == 0 || len > *value_len) {
5399 return (CKR_ATTRIBUTE_VALUE_INVALID);
5401 *value_len = len;
5403 (void) memcpy(value,
5404 ((biginteger_t *)OBJ_PRI_RSA_PRIEXPO(key))->big_value,
5405 *value_len);
5407 break;
5409 case CKA_PRIME_1:
5410 #ifdef __sparcv9
5411 len =
5412 /* LINTED */
5413 (uint32_t)
5414 ((biginteger_t *)OBJ_PRI_RSA_PRIME1(key))->big_value_len;
5415 #else /* !__sparcv9 */
5416 len =
5417 ((biginteger_t *)OBJ_PRI_RSA_PRIME1(key))->big_value_len;
5418 #endif /* __sparcv9 */
5420 if (len > *value_len) {
5421 return (CKR_ATTRIBUTE_VALUE_INVALID);
5423 *value_len = len;
5425 if (*value_len == 0) {
5426 return (CKR_OK);
5429 (void) memcpy(value,
5430 ((biginteger_t *)OBJ_PRI_RSA_PRIME1(key))->big_value,
5431 *value_len);
5433 break;
5435 case CKA_PRIME_2:
5436 #ifdef __sparcv9
5437 len =
5438 /* LINTED */
5439 (uint32_t)
5440 ((biginteger_t *)OBJ_PRI_RSA_PRIME2(key))->big_value_len;
5441 #else /* !__sparcv9 */
5442 len =
5443 ((biginteger_t *)OBJ_PRI_RSA_PRIME2(key))->big_value_len;
5444 #endif /* __sparcv9 */
5446 if (len > *value_len) {
5447 return (CKR_ATTRIBUTE_VALUE_INVALID);
5449 *value_len = len;
5451 if (*value_len == 0) {
5452 return (CKR_OK);
5455 (void) memcpy(value,
5456 ((biginteger_t *)OBJ_PRI_RSA_PRIME2(key))->big_value,
5457 *value_len);
5459 break;
5461 case CKA_EXPONENT_1:
5462 #ifdef __sparcv9
5463 len =
5464 /* LINTED */
5465 (uint32_t)
5466 ((biginteger_t *)OBJ_PRI_RSA_EXPO1(key))->big_value_len;
5467 #else /* !__sparcv9 */
5468 len =
5469 ((biginteger_t *)OBJ_PRI_RSA_EXPO1(key))->big_value_len;
5470 #endif /* __sparcv9 */
5472 if (len > *value_len) {
5473 return (CKR_ATTRIBUTE_VALUE_INVALID);
5475 *value_len = len;
5477 if (*value_len == 0) {
5478 return (CKR_OK);
5481 (void) memcpy(value,
5482 ((biginteger_t *)OBJ_PRI_RSA_EXPO1(key))->big_value,
5483 *value_len);
5485 break;
5487 case CKA_EXPONENT_2:
5488 #ifdef __sparcv9
5489 len =
5490 /* LINTED */
5491 (uint32_t)
5492 ((biginteger_t *)OBJ_PRI_RSA_EXPO2(key))->big_value_len;
5493 #else /* !__sparcv9 */
5494 len =
5495 ((biginteger_t *)OBJ_PRI_RSA_EXPO2(key))->big_value_len;
5496 #endif /* __sparcv9 */
5498 if (len > *value_len) {
5499 return (CKR_ATTRIBUTE_VALUE_INVALID);
5501 *value_len = len;
5503 if (*value_len == 0) {
5504 return (CKR_OK);
5507 (void) memcpy(value,
5508 ((biginteger_t *)OBJ_PRI_RSA_EXPO2(key))->big_value,
5509 *value_len);
5511 break;
5513 case CKA_COEFFICIENT:
5514 #ifdef __sparcv9
5515 len =
5516 /* LINTED */
5517 (uint32_t)
5518 ((biginteger_t *)OBJ_PRI_RSA_COEF(key))->big_value_len;
5519 #else /* !__sparcv9 */
5520 len =
5521 ((biginteger_t *)OBJ_PRI_RSA_COEF(key))->big_value_len;
5522 #endif /* __sparcv9 */
5524 if (len > *value_len) {
5525 return (CKR_ATTRIBUTE_VALUE_INVALID);
5527 *value_len = len;
5529 if (*value_len == 0) {
5530 return (CKR_OK);
5533 (void) memcpy(value,
5534 ((biginteger_t *)OBJ_PRI_RSA_COEF(key))->big_value,
5535 *value_len);
5537 break;
5539 /* The following attributes belong to DSA and DH */
5540 case CKA_PRIME:
5542 if (key->key_type == CKK_DSA)
5543 #ifdef __sparcv9
5544 len =
5545 /* LINTED */
5546 (uint32_t)
5547 ((biginteger_t *)OBJ_PRI_DSA_PRIME(key))->
5548 big_value_len;
5549 #else /* !__sparcv9 */
5550 len =
5551 ((biginteger_t *)OBJ_PRI_DSA_PRIME(key))->
5552 big_value_len;
5553 #endif /* __sparcv9 */
5554 else
5555 #ifdef __sparcv9
5556 len =
5557 /* LINTED */
5558 (uint32_t)
5559 ((biginteger_t *)OBJ_PRI_DH_PRIME(key))->
5560 big_value_len;
5561 #else /* !__sparcv9 */
5562 len =
5563 ((biginteger_t *)OBJ_PRI_DH_PRIME(key))->
5564 big_value_len;
5565 #endif /* __sparcv9 */
5567 /* This attribute MUST BE set */
5568 if (len == 0 || len > *value_len) {
5569 return (CKR_ATTRIBUTE_VALUE_INVALID);
5571 *value_len = len;
5573 if (key->key_type == CKK_DSA)
5574 (void) memcpy(value,
5575 ((biginteger_t *)OBJ_PRI_DSA_PRIME(key))->big_value,
5576 *value_len);
5577 else
5578 (void) memcpy(value,
5579 ((biginteger_t *)OBJ_PRI_DH_PRIME(key))->big_value,
5580 *value_len);
5582 break;
5584 case CKA_SUBPRIME:
5585 #ifdef __sparcv9
5586 len =
5587 /* LINTED */
5588 (uint32_t)
5589 ((biginteger_t *)OBJ_PRI_DSA_SUBPRIME(key))->big_value_len;
5590 #else /* !__sparcv9 */
5591 len =
5592 ((biginteger_t *)OBJ_PRI_DSA_SUBPRIME(key))->big_value_len;
5593 #endif /* __sparcv9 */
5595 /* This attribute MUST BE set */
5596 if (len == 0 || len > *value_len) {
5597 return (CKR_ATTRIBUTE_VALUE_INVALID);
5599 *value_len = len;
5601 (void) memcpy(value,
5602 ((biginteger_t *)OBJ_PRI_DSA_SUBPRIME(key))->big_value,
5603 *value_len);
5605 break;
5607 case CKA_BASE:
5609 if (key->key_type == CKK_DSA)
5610 #ifdef __sparcv9
5611 len =
5612 /* LINTED */
5613 (uint32_t)
5614 ((biginteger_t *)OBJ_PRI_DSA_BASE(key))->
5615 big_value_len;
5616 #else /* !__sparcv9 */
5617 len =
5618 ((biginteger_t *)OBJ_PRI_DSA_BASE(key))->
5619 big_value_len;
5620 #endif /* __sparcv9 */
5621 else
5622 #ifdef __sparcv9
5623 len =
5624 /* LINTED */
5625 (uint32_t)
5626 ((biginteger_t *)OBJ_PRI_DH_BASE(key))->
5627 big_value_len;
5628 #else /* !__sparcv9 */
5629 len =
5630 ((biginteger_t *)OBJ_PRI_DH_BASE(key))->
5631 big_value_len;
5632 #endif /* __sparcv9 */
5634 /* This attribute MUST BE set */
5635 if (len == 0 || len > *value_len) {
5636 return (CKR_ATTRIBUTE_VALUE_INVALID);
5638 *value_len = len;
5640 if (key->key_type == CKK_DSA)
5641 (void) memcpy(value,
5642 ((biginteger_t *)OBJ_PRI_DSA_BASE(key))->big_value,
5643 *value_len);
5644 else
5645 (void) memcpy(value,
5646 ((biginteger_t *)OBJ_PRI_DH_BASE(key))->big_value,
5647 *value_len);
5648 break;
5650 case CKA_VALUE:
5652 if (key->key_type == CKK_DSA) {
5653 #ifdef __sparcv9
5654 len =
5655 /* LINTED */
5656 (uint32_t)
5657 ((biginteger_t *)OBJ_PRI_DSA_VALUE(key))->
5658 big_value_len;
5659 #else /* !__sparcv9 */
5660 len =
5661 ((biginteger_t *)OBJ_PRI_DSA_VALUE(key))->
5662 big_value_len;
5663 #endif /* __sparcv9 */
5664 } else if (key->key_type == CKK_DH) {
5665 #ifdef __sparcv9
5666 len =
5667 /* LINTED */
5668 (uint32_t)
5669 ((biginteger_t *)OBJ_PRI_DH_VALUE(key))->
5670 big_value_len;
5671 #else /* !__sparcv9 */
5672 len =
5673 ((biginteger_t *)OBJ_PRI_DH_VALUE(key))->
5674 big_value_len;
5675 #endif /* __sparcv9 */
5676 } else {
5677 #ifdef __sparcv9
5678 len =
5679 /* LINTED */
5680 (uint32_t)
5681 ((biginteger_t *)OBJ_PRI_EC_VALUE(key))->
5682 big_value_len;
5683 #else /* !__sparcv9 */
5684 len =
5685 ((biginteger_t *)OBJ_PRI_EC_VALUE(key))->
5686 big_value_len;
5687 #endif /* __sparcv9 */
5690 /* This attribute MUST BE set */
5691 if (len == 0 || len > *value_len) {
5692 return (CKR_ATTRIBUTE_VALUE_INVALID);
5694 *value_len = len;
5696 if (key->key_type == CKK_DSA) {
5697 (void) memcpy(value,
5698 ((biginteger_t *)OBJ_PRI_DSA_VALUE(key))->big_value,
5699 *value_len);
5700 } else if (key->key_type == CKK_DH) {
5701 (void) memcpy(value,
5702 ((biginteger_t *)OBJ_PRI_DH_VALUE(key))->big_value,
5703 *value_len);
5704 } else {
5705 (void) memcpy(value,
5706 ((biginteger_t *)OBJ_PRI_EC_VALUE(key))->big_value,
5707 *value_len);
5710 break;
5713 return (CKR_OK);
5717 static CK_RV
5718 copy_bigint(biginteger_t *new_bigint, biginteger_t *old_bigint)
5720 new_bigint->big_value =
5721 malloc((sizeof (CK_BYTE) * new_bigint->big_value_len));
5723 if (new_bigint->big_value == NULL) {
5724 return (CKR_HOST_MEMORY);
5727 (void) memcpy(new_bigint->big_value, old_bigint->big_value,
5728 (sizeof (CK_BYTE) * new_bigint->big_value_len));
5730 return (CKR_OK);
5733 static void
5734 free_public_key_attr(public_key_obj_t *pbk, CK_KEY_TYPE key_type)
5736 if (pbk == NULL) {
5737 return;
5740 switch (key_type) {
5741 case CKK_RSA:
5742 bigint_attr_cleanup(KEY_PUB_RSA_MOD(pbk));
5743 bigint_attr_cleanup(KEY_PUB_RSA_PUBEXPO(pbk));
5744 break;
5745 case CKK_DSA:
5746 bigint_attr_cleanup(KEY_PUB_DSA_PRIME(pbk));
5747 bigint_attr_cleanup(KEY_PUB_DSA_SUBPRIME(pbk));
5748 bigint_attr_cleanup(KEY_PUB_DSA_BASE(pbk));
5749 bigint_attr_cleanup(KEY_PUB_DSA_VALUE(pbk));
5750 break;
5751 case CKK_DH:
5752 bigint_attr_cleanup(KEY_PUB_DH_PRIME(pbk));
5753 bigint_attr_cleanup(KEY_PUB_DH_BASE(pbk));
5754 bigint_attr_cleanup(KEY_PUB_DH_VALUE(pbk));
5755 break;
5756 case CKK_EC:
5757 bigint_attr_cleanup(KEY_PUB_EC_POINT(pbk));
5758 break;
5759 case CKK_X9_42_DH:
5760 bigint_attr_cleanup(KEY_PUB_DH942_PRIME(pbk));
5761 bigint_attr_cleanup(KEY_PUB_DH942_SUBPRIME(pbk));
5762 bigint_attr_cleanup(KEY_PUB_DH942_BASE(pbk));
5763 bigint_attr_cleanup(KEY_PUB_DH942_VALUE(pbk));
5764 break;
5765 default:
5766 break;
5768 free(pbk);
5771 CK_RV
5772 soft_copy_public_key_attr(public_key_obj_t *old_pub_key_obj_p,
5773 public_key_obj_t **new_pub_key_obj_p, CK_KEY_TYPE key_type)
5776 public_key_obj_t *pbk;
5777 CK_RV rv = CKR_OK;
5779 pbk = calloc(1, sizeof (public_key_obj_t));
5780 if (pbk == NULL) {
5781 return (CKR_HOST_MEMORY);
5784 switch (key_type) {
5785 case CKK_RSA:
5786 (void) memcpy(KEY_PUB_RSA(pbk),
5787 KEY_PUB_RSA(old_pub_key_obj_p),
5788 sizeof (rsa_pub_key_t));
5789 /* copy modulus */
5790 rv = copy_bigint(KEY_PUB_RSA_MOD(pbk),
5791 KEY_PUB_RSA_MOD(old_pub_key_obj_p));
5792 if (rv != CKR_OK) {
5793 free_public_key_attr(pbk, key_type);
5794 return (rv);
5796 /* copy public exponent */
5797 rv = copy_bigint(KEY_PUB_RSA_PUBEXPO(pbk),
5798 KEY_PUB_RSA_PUBEXPO(old_pub_key_obj_p));
5799 if (rv != CKR_OK) {
5800 free_public_key_attr(pbk, key_type);
5801 return (rv);
5803 break;
5804 case CKK_DSA:
5805 (void) memcpy(KEY_PUB_DSA(pbk),
5806 KEY_PUB_DSA(old_pub_key_obj_p),
5807 sizeof (dsa_pub_key_t));
5809 /* copy prime */
5810 rv = copy_bigint(KEY_PUB_DSA_PRIME(pbk),
5811 KEY_PUB_DSA_PRIME(old_pub_key_obj_p));
5812 if (rv != CKR_OK) {
5813 free_public_key_attr(pbk, key_type);
5814 return (rv);
5817 /* copy subprime */
5818 rv = copy_bigint(KEY_PUB_DSA_SUBPRIME(pbk),
5819 KEY_PUB_DSA_SUBPRIME(old_pub_key_obj_p));
5820 if (rv != CKR_OK) {
5821 free_public_key_attr(pbk, key_type);
5822 return (rv);
5825 /* copy base */
5826 rv = copy_bigint(KEY_PUB_DSA_BASE(pbk),
5827 KEY_PUB_DSA_BASE(old_pub_key_obj_p));
5828 if (rv != CKR_OK) {
5829 free_public_key_attr(pbk, key_type);
5830 return (rv);
5833 /* copy value */
5834 rv = copy_bigint(KEY_PUB_DSA_VALUE(pbk),
5835 KEY_PUB_DSA_VALUE(old_pub_key_obj_p));
5836 if (rv != CKR_OK) {
5837 free_public_key_attr(pbk, key_type);
5838 return (rv);
5840 break;
5841 case CKK_DH:
5842 (void) memcpy(KEY_PUB_DH(pbk),
5843 KEY_PUB_DH(old_pub_key_obj_p),
5844 sizeof (dh_pub_key_t));
5846 /* copy prime */
5847 rv = copy_bigint(KEY_PUB_DH_PRIME(pbk),
5848 KEY_PUB_DH_PRIME(old_pub_key_obj_p));
5849 if (rv != CKR_OK) {
5850 free_public_key_attr(pbk, key_type);
5851 return (rv);
5854 /* copy base */
5855 rv = copy_bigint(KEY_PUB_DH_BASE(pbk),
5856 KEY_PUB_DH_BASE(old_pub_key_obj_p));
5857 if (rv != CKR_OK) {
5858 free_public_key_attr(pbk, key_type);
5859 return (rv);
5862 /* copy value */
5863 rv = copy_bigint(KEY_PUB_DH_VALUE(pbk),
5864 KEY_PUB_DH_VALUE(old_pub_key_obj_p));
5865 if (rv != CKR_OK) {
5866 free_public_key_attr(pbk, key_type);
5867 return (rv);
5869 break;
5870 case CKK_EC:
5871 (void) memcpy(KEY_PUB_EC(pbk),
5872 KEY_PUB_EC(old_pub_key_obj_p),
5873 sizeof (ec_pub_key_t));
5875 /* copy point */
5876 rv = copy_bigint(KEY_PUB_EC_POINT(pbk),
5877 KEY_PUB_EC_POINT(old_pub_key_obj_p));
5878 if (rv != CKR_OK) {
5879 free_public_key_attr(pbk, key_type);
5880 return (rv);
5882 break;
5883 case CKK_X9_42_DH:
5884 (void) memcpy(KEY_PUB_DH942(pbk),
5885 KEY_PUB_DH942(old_pub_key_obj_p),
5886 sizeof (dh942_pub_key_t));
5888 /* copy prime */
5889 rv = copy_bigint(KEY_PUB_DH942_PRIME(pbk),
5890 KEY_PUB_DH942_PRIME(old_pub_key_obj_p));
5891 if (rv != CKR_OK) {
5892 free_public_key_attr(pbk, key_type);
5893 return (rv);
5896 /* copy subprime */
5897 rv = copy_bigint(KEY_PUB_DH942_SUBPRIME(pbk),
5898 KEY_PUB_DH942_SUBPRIME(old_pub_key_obj_p));
5899 if (rv != CKR_OK) {
5900 free_public_key_attr(pbk, key_type);
5901 return (rv);
5904 /* copy base */
5905 rv = copy_bigint(KEY_PUB_DH942_BASE(pbk),
5906 KEY_PUB_DH942_BASE(old_pub_key_obj_p));
5907 if (rv != CKR_OK) {
5908 free_public_key_attr(pbk, key_type);
5909 return (rv);
5912 /* copy value */
5913 rv = copy_bigint(KEY_PUB_DH942_VALUE(pbk),
5914 KEY_PUB_DH942_VALUE(old_pub_key_obj_p));
5915 if (rv != CKR_OK) {
5916 free_public_key_attr(pbk, key_type);
5917 return (rv);
5919 break;
5920 default:
5921 break;
5923 *new_pub_key_obj_p = pbk;
5924 return (rv);
5927 static void
5928 free_private_key_attr(private_key_obj_t *pbk, CK_KEY_TYPE key_type)
5930 if (pbk == NULL) {
5931 return;
5934 switch (key_type) {
5935 case CKK_RSA:
5936 bigint_attr_cleanup(KEY_PRI_RSA_MOD(pbk));
5937 bigint_attr_cleanup(KEY_PRI_RSA_PUBEXPO(pbk));
5938 bigint_attr_cleanup(KEY_PRI_RSA_PRIEXPO(pbk));
5939 bigint_attr_cleanup(KEY_PRI_RSA_PRIME1(pbk));
5940 bigint_attr_cleanup(KEY_PRI_RSA_PRIME2(pbk));
5941 bigint_attr_cleanup(KEY_PRI_RSA_EXPO1(pbk));
5942 bigint_attr_cleanup(KEY_PRI_RSA_EXPO2(pbk));
5943 bigint_attr_cleanup(KEY_PRI_RSA_COEF(pbk));
5944 break;
5945 case CKK_DSA:
5946 bigint_attr_cleanup(KEY_PRI_DSA_PRIME(pbk));
5947 bigint_attr_cleanup(KEY_PRI_DSA_SUBPRIME(pbk));
5948 bigint_attr_cleanup(KEY_PRI_DSA_BASE(pbk));
5949 bigint_attr_cleanup(KEY_PRI_DSA_VALUE(pbk));
5950 break;
5951 case CKK_DH:
5952 bigint_attr_cleanup(KEY_PRI_DH_PRIME(pbk));
5953 bigint_attr_cleanup(KEY_PRI_DH_BASE(pbk));
5954 bigint_attr_cleanup(KEY_PRI_DH_VALUE(pbk));
5955 break;
5956 case CKK_EC:
5957 bigint_attr_cleanup(KEY_PRI_EC_VALUE(pbk));
5958 break;
5959 case CKK_X9_42_DH:
5960 bigint_attr_cleanup(KEY_PRI_DH942_PRIME(pbk));
5961 bigint_attr_cleanup(KEY_PRI_DH942_SUBPRIME(pbk));
5962 bigint_attr_cleanup(KEY_PRI_DH942_BASE(pbk));
5963 bigint_attr_cleanup(KEY_PRI_DH942_VALUE(pbk));
5964 break;
5965 default:
5966 break;
5968 free(pbk);
5971 CK_RV
5972 soft_copy_private_key_attr(private_key_obj_t *old_pri_key_obj_p,
5973 private_key_obj_t **new_pri_key_obj_p, CK_KEY_TYPE key_type)
5975 CK_RV rv = CKR_OK;
5976 private_key_obj_t *pbk;
5978 pbk = calloc(1, sizeof (private_key_obj_t));
5979 if (pbk == NULL) {
5980 return (CKR_HOST_MEMORY);
5983 switch (key_type) {
5984 case CKK_RSA:
5985 (void) memcpy(KEY_PRI_RSA(pbk),
5986 KEY_PRI_RSA(old_pri_key_obj_p),
5987 sizeof (rsa_pri_key_t));
5988 /* copy modulus */
5989 rv = copy_bigint(KEY_PRI_RSA_MOD(pbk),
5990 KEY_PRI_RSA_MOD(old_pri_key_obj_p));
5991 if (rv != CKR_OK) {
5992 free_private_key_attr(pbk, key_type);
5993 return (rv);
5995 /* copy public exponent */
5996 rv = copy_bigint(KEY_PRI_RSA_PUBEXPO(pbk),
5997 KEY_PRI_RSA_PUBEXPO(old_pri_key_obj_p));
5998 if (rv != CKR_OK) {
5999 free_private_key_attr(pbk, key_type);
6000 return (rv);
6002 /* copy private exponent */
6003 rv = copy_bigint(KEY_PRI_RSA_PRIEXPO(pbk),
6004 KEY_PRI_RSA_PRIEXPO(old_pri_key_obj_p));
6005 if (rv != CKR_OK) {
6006 free_private_key_attr(pbk, key_type);
6007 return (rv);
6009 /* copy prime_1 */
6010 rv = copy_bigint(KEY_PRI_RSA_PRIME1(pbk),
6011 KEY_PRI_RSA_PRIME1(old_pri_key_obj_p));
6012 if (rv != CKR_OK) {
6013 free_private_key_attr(pbk, key_type);
6014 return (rv);
6016 /* copy prime_2 */
6017 rv = copy_bigint(KEY_PRI_RSA_PRIME2(pbk),
6018 KEY_PRI_RSA_PRIME2(old_pri_key_obj_p));
6019 if (rv != CKR_OK) {
6020 free_private_key_attr(pbk, key_type);
6021 return (rv);
6023 /* copy exponent_1 */
6024 rv = copy_bigint(KEY_PRI_RSA_EXPO1(pbk),
6025 KEY_PRI_RSA_EXPO1(old_pri_key_obj_p));
6026 if (rv != CKR_OK) {
6027 free_private_key_attr(pbk, key_type);
6028 return (rv);
6030 /* copy exponent_2 */
6031 rv = copy_bigint(KEY_PRI_RSA_EXPO2(pbk),
6032 KEY_PRI_RSA_EXPO2(old_pri_key_obj_p));
6033 if (rv != CKR_OK) {
6034 free_private_key_attr(pbk, key_type);
6035 return (rv);
6037 /* copy coefficient */
6038 rv = copy_bigint(KEY_PRI_RSA_COEF(pbk),
6039 KEY_PRI_RSA_COEF(old_pri_key_obj_p));
6040 if (rv != CKR_OK) {
6041 free_private_key_attr(pbk, key_type);
6042 return (rv);
6044 break;
6045 case CKK_DSA:
6046 (void) memcpy(KEY_PRI_DSA(pbk),
6047 KEY_PRI_DSA(old_pri_key_obj_p),
6048 sizeof (dsa_pri_key_t));
6050 /* copy prime */
6051 rv = copy_bigint(KEY_PRI_DSA_PRIME(pbk),
6052 KEY_PRI_DSA_PRIME(old_pri_key_obj_p));
6053 if (rv != CKR_OK) {
6054 free_private_key_attr(pbk, key_type);
6055 return (rv);
6058 /* copy subprime */
6059 rv = copy_bigint(KEY_PRI_DSA_SUBPRIME(pbk),
6060 KEY_PRI_DSA_SUBPRIME(old_pri_key_obj_p));
6061 if (rv != CKR_OK) {
6062 free_private_key_attr(pbk, key_type);
6063 return (rv);
6066 /* copy base */
6067 rv = copy_bigint(KEY_PRI_DSA_BASE(pbk),
6068 KEY_PRI_DSA_BASE(old_pri_key_obj_p));
6069 if (rv != CKR_OK) {
6070 free_private_key_attr(pbk, key_type);
6071 return (rv);
6074 /* copy value */
6075 rv = copy_bigint(KEY_PRI_DSA_VALUE(pbk),
6076 KEY_PRI_DSA_VALUE(old_pri_key_obj_p));
6077 if (rv != CKR_OK) {
6078 free_private_key_attr(pbk, key_type);
6079 return (rv);
6081 break;
6082 case CKK_DH:
6083 (void) memcpy(KEY_PRI_DH(pbk),
6084 KEY_PRI_DH(old_pri_key_obj_p),
6085 sizeof (dh_pri_key_t));
6087 /* copy prime */
6088 rv = copy_bigint(KEY_PRI_DH_PRIME(pbk),
6089 KEY_PRI_DH_PRIME(old_pri_key_obj_p));
6090 if (rv != CKR_OK) {
6091 free_private_key_attr(pbk, key_type);
6092 return (rv);
6095 /* copy base */
6096 rv = copy_bigint(KEY_PRI_DH_BASE(pbk),
6097 KEY_PRI_DH_BASE(old_pri_key_obj_p));
6098 if (rv != CKR_OK) {
6099 free_private_key_attr(pbk, key_type);
6100 return (rv);
6103 /* copy value */
6104 rv = copy_bigint(KEY_PRI_DH_VALUE(pbk),
6105 KEY_PRI_DH_VALUE(old_pri_key_obj_p));
6106 if (rv != CKR_OK) {
6107 free_private_key_attr(pbk, key_type);
6108 return (rv);
6110 break;
6111 case CKK_EC:
6112 (void) memcpy(KEY_PRI_EC(pbk),
6113 KEY_PRI_EC(old_pri_key_obj_p),
6114 sizeof (ec_pri_key_t));
6116 /* copy value */
6117 rv = copy_bigint(KEY_PRI_EC_VALUE(pbk),
6118 KEY_PRI_EC_VALUE(old_pri_key_obj_p));
6119 if (rv != CKR_OK) {
6120 free_private_key_attr(pbk, key_type);
6121 return (rv);
6123 break;
6124 case CKK_X9_42_DH:
6125 (void) memcpy(KEY_PRI_DH942(pbk),
6126 KEY_PRI_DH942(old_pri_key_obj_p),
6127 sizeof (dh942_pri_key_t));
6129 /* copy prime */
6130 rv = copy_bigint(KEY_PRI_DH942_PRIME(pbk),
6131 KEY_PRI_DH942_PRIME(old_pri_key_obj_p));
6132 if (rv != CKR_OK) {
6133 free_private_key_attr(pbk, key_type);
6134 return (rv);
6137 /* copy subprime */
6138 rv = copy_bigint(KEY_PRI_DH942_SUBPRIME(pbk),
6139 KEY_PRI_DH942_SUBPRIME(old_pri_key_obj_p));
6140 if (rv != CKR_OK) {
6141 free_private_key_attr(pbk, key_type);
6142 return (rv);
6145 /* copy base */
6146 rv = copy_bigint(KEY_PRI_DH942_BASE(pbk),
6147 KEY_PRI_DH942_BASE(old_pri_key_obj_p));
6148 if (rv != CKR_OK) {
6149 free_private_key_attr(pbk, key_type);
6150 return (rv);
6153 /* copy value */
6154 rv = copy_bigint(KEY_PRI_DH942_VALUE(pbk),
6155 KEY_PRI_DH942_VALUE(old_pri_key_obj_p));
6156 if (rv != CKR_OK) {
6157 free_private_key_attr(pbk, key_type);
6158 return (rv);
6160 break;
6161 default:
6162 break;
6164 *new_pri_key_obj_p = pbk;
6165 return (rv);
6168 static void
6169 free_domain_attr(domain_obj_t *domain, CK_KEY_TYPE key_type)
6171 if (domain == NULL) {
6172 return;
6175 switch (key_type) {
6176 case CKK_DSA:
6177 bigint_attr_cleanup(KEY_DOM_DSA_PRIME(domain));
6178 bigint_attr_cleanup(KEY_DOM_DSA_SUBPRIME(domain));
6179 bigint_attr_cleanup(KEY_DOM_DSA_BASE(domain));
6180 break;
6181 case CKK_DH:
6182 bigint_attr_cleanup(KEY_DOM_DH_PRIME(domain));
6183 bigint_attr_cleanup(KEY_DOM_DH_BASE(domain));
6184 break;
6185 case CKK_X9_42_DH:
6186 bigint_attr_cleanup(KEY_DOM_DH942_PRIME(domain));
6187 bigint_attr_cleanup(KEY_DOM_DH942_SUBPRIME(domain));
6188 bigint_attr_cleanup(KEY_DOM_DH942_BASE(domain));
6189 break;
6190 default:
6191 break;
6193 free(domain);
6196 CK_RV
6197 soft_copy_domain_attr(domain_obj_t *old_domain_obj_p,
6198 domain_obj_t **new_domain_obj_p, CK_KEY_TYPE key_type)
6200 CK_RV rv = CKR_OK;
6201 domain_obj_t *domain;
6203 domain = calloc(1, sizeof (domain_obj_t));
6204 if (domain == NULL) {
6205 return (CKR_HOST_MEMORY);
6208 switch (key_type) {
6209 case CKK_DSA:
6210 (void) memcpy(KEY_DOM_DSA(domain),
6211 KEY_DOM_DSA(old_domain_obj_p),
6212 sizeof (dsa_dom_key_t));
6214 /* copy prime */
6215 rv = copy_bigint(KEY_DOM_DSA_PRIME(domain),
6216 KEY_DOM_DSA_PRIME(old_domain_obj_p));
6217 if (rv != CKR_OK) {
6218 free_domain_attr(domain, key_type);
6219 return (rv);
6222 /* copy subprime */
6223 rv = copy_bigint(KEY_DOM_DSA_SUBPRIME(domain),
6224 KEY_DOM_DSA_SUBPRIME(old_domain_obj_p));
6225 if (rv != CKR_OK) {
6226 free_domain_attr(domain, key_type);
6227 return (rv);
6230 /* copy base */
6231 rv = copy_bigint(KEY_DOM_DSA_BASE(domain),
6232 KEY_DOM_DSA_BASE(old_domain_obj_p));
6233 if (rv != CKR_OK) {
6234 free_domain_attr(domain, key_type);
6235 return (rv);
6238 break;
6239 case CKK_DH:
6240 (void) memcpy(KEY_DOM_DH(domain),
6241 KEY_DOM_DH(old_domain_obj_p),
6242 sizeof (dh_dom_key_t));
6244 /* copy prime */
6245 rv = copy_bigint(KEY_DOM_DH_PRIME(domain),
6246 KEY_DOM_DH_PRIME(old_domain_obj_p));
6247 if (rv != CKR_OK) {
6248 free_domain_attr(domain, key_type);
6249 return (rv);
6252 /* copy base */
6253 rv = copy_bigint(KEY_DOM_DH_BASE(domain),
6254 KEY_DOM_DH_BASE(old_domain_obj_p));
6255 if (rv != CKR_OK) {
6256 free_domain_attr(domain, key_type);
6257 return (rv);
6260 break;
6261 case CKK_X9_42_DH:
6262 (void) memcpy(KEY_DOM_DH942(domain),
6263 KEY_DOM_DH942(old_domain_obj_p),
6264 sizeof (dh942_dom_key_t));
6266 /* copy prime */
6267 rv = copy_bigint(KEY_DOM_DH942_PRIME(domain),
6268 KEY_DOM_DH942_PRIME(old_domain_obj_p));
6269 if (rv != CKR_OK) {
6270 free_domain_attr(domain, key_type);
6271 return (rv);
6274 /* copy subprime */
6275 rv = copy_bigint(KEY_DOM_DH942_SUBPRIME(domain),
6276 KEY_DOM_DH942_SUBPRIME(old_domain_obj_p));
6277 if (rv != CKR_OK) {
6278 free_domain_attr(domain, key_type);
6279 return (rv);
6282 /* copy base */
6283 rv = copy_bigint(KEY_DOM_DH942_BASE(domain),
6284 KEY_DOM_DH942_BASE(old_domain_obj_p));
6285 if (rv != CKR_OK) {
6286 free_domain_attr(domain, key_type);
6287 return (rv);
6290 break;
6291 default:
6292 break;
6294 *new_domain_obj_p = domain;
6295 return (rv);
6298 CK_RV
6299 soft_copy_secret_key_attr(secret_key_obj_t *old_secret_key_obj_p,
6300 secret_key_obj_t **new_secret_key_obj_p)
6302 secret_key_obj_t *sk;
6304 sk = malloc(sizeof (secret_key_obj_t));
6305 if (sk == NULL) {
6306 return (CKR_HOST_MEMORY);
6308 (void) memcpy(sk, old_secret_key_obj_p, sizeof (secret_key_obj_t));
6310 /* copy the secret key value */
6311 sk->sk_value = malloc(sk->sk_value_len);
6312 if (sk->sk_value == NULL) {
6313 free(sk);
6314 return (CKR_HOST_MEMORY);
6316 (void) memcpy(sk->sk_value, old_secret_key_obj_p->sk_value,
6317 (sizeof (CK_BYTE) * sk->sk_value_len));
6320 * Copy the pre-expanded key schedule.
6322 if (old_secret_key_obj_p->key_sched != NULL &&
6323 old_secret_key_obj_p->keysched_len > 0) {
6324 sk->key_sched = malloc(old_secret_key_obj_p->keysched_len);
6325 if (sk->key_sched == NULL) {
6326 freezero(sk->sk_value, sk->sk_value_len);
6327 free(sk);
6328 return (CKR_HOST_MEMORY);
6330 sk->keysched_len = old_secret_key_obj_p->keysched_len;
6331 (void) memcpy(sk->key_sched, old_secret_key_obj_p->key_sched,
6332 sk->keysched_len);
6335 *new_secret_key_obj_p = sk;
6337 return (CKR_OK);
6341 * If CKA_CLASS not given, guess CKA_CLASS using
6342 * attributes on template .
6344 * Some attributes are specific to an object class. If one or more
6345 * of these attributes are in the template, make a list of classes
6346 * that can have these attributes. This would speed up the search later,
6347 * because we can immediately skip an object if the class of that
6348 * object can not possibly contain one of the attributes.
6351 void
6352 soft_process_find_attr(CK_OBJECT_CLASS *pclasses,
6353 CK_ULONG *num_result_pclasses, CK_ATTRIBUTE_PTR pTemplate,
6354 CK_ULONG ulCount)
6356 ulong_t i;
6357 int j;
6358 boolean_t pub_found = B_FALSE,
6359 priv_found = B_FALSE,
6360 secret_found = B_FALSE,
6361 domain_found = B_FALSE,
6362 hardware_found = B_FALSE,
6363 cert_found = B_FALSE;
6364 int num_pub_key_attrs, num_priv_key_attrs,
6365 num_secret_key_attrs, num_domain_attrs,
6366 num_hardware_attrs, num_cert_attrs;
6367 int num_pclasses = 0;
6369 for (i = 0; i < ulCount; i++) {
6370 if (pTemplate[i].type == CKA_CLASS) {
6372 * don't need to guess the class, it is specified.
6373 * Just record the class, and return.
6375 pclasses[0] =
6376 (*((CK_OBJECT_CLASS *)pTemplate[i].pValue));
6377 *num_result_pclasses = 1;
6378 return;
6382 num_pub_key_attrs =
6383 sizeof (PUB_KEY_ATTRS) / sizeof (CK_ATTRIBUTE_TYPE);
6384 num_priv_key_attrs =
6385 sizeof (PRIV_KEY_ATTRS) / sizeof (CK_ATTRIBUTE_TYPE);
6386 num_secret_key_attrs =
6387 sizeof (SECRET_KEY_ATTRS) / sizeof (CK_ATTRIBUTE_TYPE);
6388 num_domain_attrs =
6389 sizeof (DOMAIN_ATTRS) / sizeof (CK_ATTRIBUTE_TYPE);
6390 num_hardware_attrs =
6391 sizeof (HARDWARE_ATTRS) / sizeof (CK_ATTRIBUTE_TYPE);
6392 num_cert_attrs =
6393 sizeof (CERT_ATTRS) / sizeof (CK_ATTRIBUTE_TYPE);
6396 * Get the list of objects class that might contain
6397 * some attributes.
6399 for (i = 0; i < ulCount; i++) {
6401 * only check if this attribute can belong to public key object
6402 * class if public key object isn't already in the list
6404 if (!pub_found) {
6405 for (j = 0; j < num_pub_key_attrs; j++) {
6406 if (pTemplate[i].type == PUB_KEY_ATTRS[j]) {
6407 pub_found = B_TRUE;
6408 pclasses[num_pclasses++] =
6409 CKO_PUBLIC_KEY;
6410 break;
6415 if (!priv_found) {
6416 for (j = 0; j < num_priv_key_attrs; j++) {
6417 if (pTemplate[i].type == PRIV_KEY_ATTRS[j]) {
6418 priv_found = B_TRUE;
6419 pclasses[num_pclasses++] =
6420 CKO_PRIVATE_KEY;
6421 break;
6426 if (!secret_found) {
6427 for (j = 0; j < num_secret_key_attrs; j++) {
6428 if (pTemplate[i].type == SECRET_KEY_ATTRS[j]) {
6429 secret_found = B_TRUE;
6430 pclasses[num_pclasses++] =
6431 CKO_SECRET_KEY;
6432 break;
6437 if (!domain_found) {
6438 for (j = 0; j < num_domain_attrs; j++) {
6439 if (pTemplate[i].type == DOMAIN_ATTRS[j]) {
6440 domain_found = B_TRUE;
6441 pclasses[num_pclasses++] =
6442 CKO_DOMAIN_PARAMETERS;
6443 break;
6448 if (!hardware_found) {
6449 for (j = 0; j < num_hardware_attrs; j++) {
6450 if (pTemplate[i].type == HARDWARE_ATTRS[j]) {
6451 hardware_found = B_TRUE;
6452 pclasses[num_pclasses++] =
6453 CKO_HW_FEATURE;
6454 break;
6459 if (!cert_found) {
6460 for (j = 0; j < num_cert_attrs; j++) {
6461 if (pTemplate[i].type == CERT_ATTRS[j]) {
6462 cert_found = B_TRUE;
6463 pclasses[num_pclasses++] =
6464 CKO_CERTIFICATE;
6465 break;
6470 *num_result_pclasses = num_pclasses;
6473 boolean_t
6474 soft_find_match_attrs(soft_object_t *obj, CK_OBJECT_CLASS *pclasses,
6475 CK_ULONG num_pclasses, CK_ATTRIBUTE *template, CK_ULONG num_attr)
6477 ulong_t i;
6478 CK_ATTRIBUTE *tmpl_attr, *obj_attr;
6479 cert_attr_t *cert_attr;
6480 uint64_t attr_mask;
6481 biginteger_t *bigint;
6482 boolean_t compare_attr, compare_bigint, compare_boolean;
6483 boolean_t compare_cert_val, compare_cert_type;
6486 * Check if the class of this object match with any
6487 * of object classes that can possibly contain the
6488 * requested attributes.
6490 if (num_pclasses > 0) {
6491 for (i = 0; i < num_pclasses; i++) {
6492 if (obj->class == pclasses[i]) {
6493 break;
6496 if (i == num_pclasses) {
6498 * this object can't possibly contain one or
6499 * more attributes, don't need to check this object
6501 return (B_FALSE);
6505 /* need to examine everything */
6506 for (i = 0; i < num_attr; i++) {
6507 tmpl_attr = &(template[i]);
6508 compare_attr = B_FALSE;
6509 compare_bigint = B_FALSE;
6510 compare_boolean = B_FALSE;
6511 compare_cert_val = B_FALSE;
6512 compare_cert_type = B_FALSE;
6513 switch (tmpl_attr->type) {
6514 /* First, check the most common attributes */
6515 case CKA_CLASS:
6516 if (*((CK_OBJECT_CLASS *)tmpl_attr->pValue) !=
6517 obj->class) {
6518 return (B_FALSE);
6520 break;
6521 case CKA_KEY_TYPE:
6522 if (*((CK_KEY_TYPE *)tmpl_attr->pValue) !=
6523 obj->key_type) {
6524 return (B_FALSE);
6526 break;
6527 case CKA_ENCRYPT:
6528 attr_mask = (obj->bool_attr_mask) & ENCRYPT_BOOL_ON;
6529 compare_boolean = B_TRUE;
6530 break;
6531 case CKA_DECRYPT:
6532 attr_mask = (obj->bool_attr_mask) & DECRYPT_BOOL_ON;
6533 compare_boolean = B_TRUE;
6534 break;
6535 case CKA_WRAP:
6536 attr_mask = (obj->bool_attr_mask) & WRAP_BOOL_ON;
6537 compare_boolean = B_TRUE;
6538 break;
6539 case CKA_UNWRAP:
6540 attr_mask = (obj->bool_attr_mask) & UNWRAP_BOOL_ON;
6541 compare_boolean = B_TRUE;
6542 break;
6543 case CKA_SIGN:
6544 attr_mask = (obj->bool_attr_mask) & SIGN_BOOL_ON;
6545 compare_boolean = B_TRUE;
6546 break;
6547 case CKA_SIGN_RECOVER:
6548 attr_mask = (obj->bool_attr_mask) &
6549 SIGN_RECOVER_BOOL_ON;
6550 compare_boolean = B_TRUE;
6551 break;
6552 case CKA_VERIFY:
6553 attr_mask = (obj->bool_attr_mask) & VERIFY_BOOL_ON;
6554 compare_boolean = B_TRUE;
6555 break;
6556 case CKA_VERIFY_RECOVER:
6557 attr_mask = (obj->bool_attr_mask) &
6558 VERIFY_RECOVER_BOOL_ON;
6559 compare_boolean = B_TRUE;
6560 break;
6561 case CKA_DERIVE:
6562 attr_mask = (obj->bool_attr_mask) & DERIVE_BOOL_ON;
6563 compare_boolean = B_TRUE;
6564 break;
6565 case CKA_LOCAL:
6566 attr_mask = (obj->bool_attr_mask) & LOCAL_BOOL_ON;
6567 compare_boolean = B_TRUE;
6568 break;
6569 case CKA_SENSITIVE:
6570 attr_mask = (obj->bool_attr_mask) & SENSITIVE_BOOL_ON;
6571 compare_boolean = B_TRUE;
6572 break;
6573 case CKA_SECONDARY_AUTH:
6574 attr_mask = (obj->bool_attr_mask) &
6575 SECONDARY_AUTH_BOOL_ON;
6576 compare_boolean = B_TRUE;
6577 break;
6578 case CKA_TRUSTED:
6579 attr_mask = (obj->bool_attr_mask) & TRUSTED_BOOL_ON;
6580 compare_boolean = B_TRUE;
6581 break;
6582 case CKA_EXTRACTABLE:
6583 attr_mask = (obj->bool_attr_mask) &
6584 EXTRACTABLE_BOOL_ON;
6585 compare_boolean = B_TRUE;
6586 break;
6587 case CKA_ALWAYS_SENSITIVE:
6588 attr_mask = (obj->bool_attr_mask) &
6589 ALWAYS_SENSITIVE_BOOL_ON;
6590 compare_boolean = B_TRUE;
6591 break;
6592 case CKA_NEVER_EXTRACTABLE:
6593 attr_mask = (obj->bool_attr_mask) &
6594 NEVER_EXTRACTABLE_BOOL_ON;
6595 compare_boolean = B_TRUE;
6596 break;
6597 case CKA_TOKEN:
6598 attr_mask = (obj->object_type) & TOKEN_OBJECT;
6599 compare_boolean = B_TRUE;
6600 break;
6601 case CKA_PRIVATE:
6602 attr_mask = (obj->object_type) & PRIVATE_OBJECT;
6603 compare_boolean = B_TRUE;
6604 break;
6605 case CKA_MODIFIABLE:
6607 CK_BBOOL bval;
6608 attr_mask = (obj->bool_attr_mask) &
6609 NOT_MODIFIABLE_BOOL_ON;
6611 if (attr_mask) {
6612 bval = FALSE;
6613 } else {
6614 bval = TRUE;
6616 if (bval != *((CK_BBOOL *)tmpl_attr->pValue)) {
6617 return (B_FALSE);
6619 break;
6621 case CKA_OWNER:
6623 * For X.509 attribute certificate object, get its
6624 * CKA_OWNER attribute from the x509_attr_cert_t struct.
6626 if ((obj->class == CKO_CERTIFICATE) &&
6627 (obj->cert_type == CKC_X_509_ATTR_CERT)) {
6628 cert_attr = X509_ATTR_CERT_OWNER(obj);
6629 compare_cert_val = B_TRUE;
6631 break;
6632 case CKA_SUBJECT:
6634 * For X.509 certificate object, get its CKA_SUBJECT
6635 * attribute from the x509_cert_t struct (not from
6636 * the extra_attrlistp).
6638 if ((obj->class == CKO_CERTIFICATE) &&
6639 (obj->cert_type == CKC_X_509)) {
6640 cert_attr = X509_CERT_SUBJECT(obj);
6641 compare_cert_val = B_TRUE;
6642 break;
6644 /*FALLTHRU*/
6645 case CKA_ID:
6646 case CKA_START_DATE:
6647 case CKA_END_DATE:
6648 case CKA_KEY_GEN_MECHANISM:
6649 case CKA_LABEL:
6650 case CKA_ISSUER:
6651 case CKA_SERIAL_NUMBER:
6652 case CKA_AC_ISSUER:
6653 case CKA_ATTR_TYPES:
6654 /* find these attributes from extra_attrlistp */
6655 obj_attr = get_extra_attr(tmpl_attr->type, obj);
6656 compare_attr = B_TRUE;
6657 break;
6658 case CKA_CERTIFICATE_TYPE:
6659 compare_cert_type = B_TRUE;
6660 break;
6661 case CKA_VALUE_LEN:
6662 /* only secret key has this attribute */
6663 if (obj->class == CKO_SECRET_KEY) {
6664 if (*((CK_ULONG *)tmpl_attr->pValue) !=
6665 OBJ_SEC_VALUE_LEN(obj)) {
6666 return (B_FALSE);
6668 } else {
6669 return (B_FALSE);
6671 break;
6672 case CKA_VALUE:
6673 switch (obj->class) {
6674 case CKO_SECRET_KEY:
6676 * secret_key_obj_t is the same as
6677 * biginteger_t
6679 bigint = (biginteger_t *)OBJ_SEC(obj);
6680 compare_bigint = B_TRUE;
6681 break;
6682 case CKO_PRIVATE_KEY:
6683 if (obj->key_type == CKK_DSA) {
6684 bigint = OBJ_PRI_DSA_VALUE(obj);
6685 } else if (obj->key_type == CKK_DH) {
6686 bigint = OBJ_PRI_DH_VALUE(obj);
6687 } else if (obj->key_type == CKK_X9_42_DH) {
6688 bigint = OBJ_PRI_DH942_VALUE(obj);
6689 } else {
6690 return (B_FALSE);
6692 compare_bigint = B_TRUE;
6693 break;
6694 case CKO_PUBLIC_KEY:
6695 if (obj->key_type == CKK_DSA) {
6696 bigint = OBJ_PUB_DSA_VALUE(obj);
6697 } else if (obj->key_type == CKK_DH) {
6698 bigint = OBJ_PUB_DH_VALUE(obj);
6699 } else if (obj->key_type == CKK_X9_42_DH) {
6700 bigint = OBJ_PUB_DH942_VALUE(obj);
6701 } else {
6702 return (B_FALSE);
6704 compare_bigint = B_TRUE;
6705 break;
6706 case CKO_CERTIFICATE:
6707 if (obj->cert_type == CKC_X_509) {
6708 cert_attr = X509_CERT_VALUE(obj);
6709 } else if (obj->cert_type ==
6710 CKC_X_509_ATTR_CERT) {
6711 cert_attr = X509_ATTR_CERT_VALUE(obj);
6713 compare_cert_val = B_TRUE;
6714 break;
6715 default:
6716 return (B_FALSE);
6718 break;
6719 case CKA_MODULUS:
6720 /* only RSA public and private key have this attr */
6721 if (obj->key_type == CKK_RSA) {
6722 if (obj->class == CKO_PUBLIC_KEY) {
6723 bigint = OBJ_PUB_RSA_MOD(obj);
6724 } else if (obj->class == CKO_PRIVATE_KEY) {
6725 bigint = OBJ_PRI_RSA_MOD(obj);
6726 } else {
6727 return (B_FALSE);
6729 compare_bigint = B_TRUE;
6730 } else {
6731 return (B_FALSE);
6733 break;
6734 case CKA_MODULUS_BITS:
6735 /* only RSA public key has this attribute */
6736 if ((obj->key_type == CKK_RSA) &&
6737 (obj->class == CKO_PUBLIC_KEY)) {
6738 CK_ULONG mod_bits = OBJ_PUB_RSA_MOD_BITS(obj);
6739 if (mod_bits !=
6740 *((CK_ULONG *)tmpl_attr->pValue)) {
6741 return (B_FALSE);
6743 } else {
6744 return (B_FALSE);
6746 break;
6747 case CKA_PUBLIC_EXPONENT:
6748 /* only RSA public and private key have this attr */
6749 if (obj->key_type == CKK_RSA) {
6750 if (obj->class == CKO_PUBLIC_KEY) {
6751 bigint = OBJ_PUB_RSA_PUBEXPO(obj);
6752 } else if (obj->class == CKO_PRIVATE_KEY) {
6753 bigint = OBJ_PRI_RSA_PUBEXPO(obj);
6754 } else {
6755 return (B_FALSE);
6757 compare_bigint = B_TRUE;
6758 } else {
6759 return (B_FALSE);
6761 break;
6762 case CKA_PRIVATE_EXPONENT:
6763 /* only RSA private key has this attribute */
6764 if ((obj->key_type == CKK_RSA) &&
6765 (obj->class == CKO_PRIVATE_KEY)) {
6766 bigint = OBJ_PRI_RSA_PRIEXPO(obj);
6767 compare_bigint = B_TRUE;
6768 } else {
6769 return (B_FALSE);
6771 break;
6772 case CKA_PRIME_1:
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_PRIME1(obj);
6777 compare_bigint = B_TRUE;
6778 } else {
6779 return (B_FALSE);
6781 break;
6782 case CKA_PRIME_2:
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_PRIME2(obj);
6787 compare_bigint = B_TRUE;
6788 } else {
6789 return (B_FALSE);
6791 break;
6792 case CKA_EXPONENT_1:
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_EXPO1(obj);
6797 compare_bigint = B_TRUE;
6798 } else {
6799 return (B_FALSE);
6801 break;
6802 case CKA_EXPONENT_2:
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_EXPO2(obj);
6807 compare_bigint = B_TRUE;
6808 } else {
6809 return (B_FALSE);
6811 break;
6812 case CKA_COEFFICIENT:
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_COEF(obj);
6817 compare_bigint = B_TRUE;
6818 } else {
6819 return (B_FALSE);
6821 break;
6822 case CKA_VALUE_BITS:
6823 /* only Diffie-Hellman private key has this attr */
6824 if ((obj->key_type == CKK_DH) &&
6825 (obj->class == CKO_PRIVATE_KEY)) {
6826 CK_ULONG val_bits = OBJ_PRI_DH_VAL_BITS(obj);
6827 if (val_bits !=
6828 *((CK_ULONG *)tmpl_attr->pValue)) {
6829 return (B_FALSE);
6831 } else {
6832 return (B_FALSE);
6834 break;
6835 case CKA_PRIME:
6836 if (obj->class == CKO_PUBLIC_KEY) {
6837 switch (obj->key_type) {
6838 case CKK_DSA:
6839 bigint = OBJ_PUB_DSA_PRIME(obj);
6840 break;
6841 case CKK_DH:
6842 bigint = OBJ_PUB_DH_PRIME(obj);
6843 break;
6844 case CKK_X9_42_DH:
6845 bigint = OBJ_PUB_DH942_PRIME(obj);
6846 break;
6847 default:
6848 return (B_FALSE);
6850 } else if (obj->class == CKO_PRIVATE_KEY) {
6851 switch (obj->key_type) {
6852 case CKK_DSA:
6853 bigint = OBJ_PRI_DSA_PRIME(obj);
6854 break;
6855 case CKK_DH:
6856 bigint = OBJ_PRI_DH_PRIME(obj);
6857 break;
6858 case CKK_X9_42_DH:
6859 bigint = OBJ_PRI_DH942_PRIME(obj);
6860 break;
6861 default:
6862 return (B_FALSE);
6864 } else if (obj->class == CKO_DOMAIN_PARAMETERS) {
6865 switch (obj->key_type) {
6866 case CKK_DSA:
6867 bigint = OBJ_DOM_DSA_PRIME(obj);
6868 break;
6869 case CKK_DH:
6870 bigint = OBJ_DOM_DH_PRIME(obj);
6871 break;
6872 case CKK_X9_42_DH:
6873 bigint = OBJ_DOM_DH942_PRIME(obj);
6874 break;
6875 default:
6876 return (B_FALSE);
6878 } else {
6879 return (B_FALSE);
6881 compare_bigint = B_TRUE;
6882 break;
6883 case CKA_SUBPRIME:
6884 if (obj->class == CKO_PUBLIC_KEY) {
6885 switch (obj->key_type) {
6886 case CKK_DSA:
6887 bigint = OBJ_PUB_DSA_SUBPRIME(obj);
6888 break;
6889 case CKK_X9_42_DH:
6890 bigint = OBJ_PUB_DH942_SUBPRIME(obj);
6891 break;
6892 default:
6893 return (B_FALSE);
6895 } else if (obj->class == CKO_PRIVATE_KEY) {
6896 switch (obj->key_type) {
6897 case CKK_DSA:
6898 bigint = OBJ_PRI_DSA_SUBPRIME(obj);
6899 break;
6900 case CKK_X9_42_DH:
6901 bigint = OBJ_PRI_DH942_SUBPRIME(obj);
6902 break;
6903 default:
6904 return (B_FALSE);
6906 } else if (obj->class == CKO_DOMAIN_PARAMETERS) {
6907 switch (obj->key_type) {
6908 case CKK_DSA:
6909 bigint = OBJ_DOM_DSA_SUBPRIME(obj);
6910 break;
6911 case CKK_X9_42_DH:
6912 bigint = OBJ_DOM_DH942_SUBPRIME(obj);
6913 break;
6914 default:
6915 return (B_FALSE);
6917 } else {
6918 return (B_FALSE);
6920 compare_bigint = B_TRUE;
6921 break;
6922 case CKA_BASE:
6923 if (obj->class == CKO_PUBLIC_KEY) {
6924 switch (obj->key_type) {
6925 case CKK_DSA:
6926 bigint = OBJ_PUB_DSA_BASE(obj);
6927 break;
6928 case CKK_DH:
6929 bigint = OBJ_PUB_DH_BASE(obj);
6930 break;
6931 case CKK_X9_42_DH:
6932 bigint = OBJ_PUB_DH942_BASE(obj);
6933 break;
6934 default:
6935 return (B_FALSE);
6937 } else if (obj->class == CKO_PRIVATE_KEY) {
6938 switch (obj->key_type) {
6939 case CKK_DSA:
6940 bigint = OBJ_PRI_DSA_BASE(obj);
6941 break;
6942 case CKK_DH:
6943 bigint = OBJ_PRI_DH_BASE(obj);
6944 break;
6945 case CKK_X9_42_DH:
6946 bigint = OBJ_PRI_DH942_BASE(obj);
6947 break;
6948 default:
6949 return (B_FALSE);
6951 } else if (obj->class == CKO_DOMAIN_PARAMETERS) {
6952 switch (obj->key_type) {
6953 case CKK_DSA:
6954 bigint = OBJ_DOM_DSA_BASE(obj);
6955 break;
6956 case CKK_DH:
6957 bigint = OBJ_DOM_DH_BASE(obj);
6958 break;
6959 case CKK_X9_42_DH:
6960 bigint = OBJ_DOM_DH942_BASE(obj);
6961 break;
6962 default:
6963 return (B_FALSE);
6965 } else {
6966 return (B_FALSE);
6968 compare_bigint = B_TRUE;
6969 break;
6970 case CKA_PRIME_BITS:
6971 if (obj->class == CKO_DOMAIN_PARAMETERS) {
6972 CK_ULONG prime_bits;
6973 if (obj->key_type == CKK_DSA) {
6974 prime_bits =
6975 OBJ_DOM_DSA_PRIME_BITS(obj);
6976 } else if (obj->key_type == CKK_DH) {
6977 prime_bits =
6978 OBJ_DOM_DH_PRIME_BITS(obj);
6979 } else if (obj->key_type == CKK_X9_42_DH) {
6980 prime_bits =
6981 OBJ_DOM_DH942_PRIME_BITS(obj);
6982 } else {
6983 return (B_FALSE);
6985 if (prime_bits !=
6986 *((CK_ULONG *)tmpl_attr->pValue)) {
6987 return (B_FALSE);
6989 } else {
6990 return (B_FALSE);
6992 break;
6993 case CKA_SUBPRIME_BITS:
6994 if ((obj->class == CKO_DOMAIN_PARAMETERS) &&
6995 (obj->key_type == CKK_X9_42_DH)) {
6996 CK_ULONG subprime_bits =
6997 OBJ_DOM_DH942_SUBPRIME_BITS(obj);
6998 if (subprime_bits !=
6999 *((CK_ULONG *)tmpl_attr->pValue)) {
7000 return (B_FALSE);
7002 } else {
7003 return (B_FALSE);
7005 break;
7006 default:
7008 * any other attributes are currently not supported.
7009 * so, it's not possible for them to be in the
7010 * object
7012 return (B_FALSE);
7014 if (compare_boolean) {
7015 CK_BBOOL bval;
7017 if (attr_mask) {
7018 bval = TRUE;
7019 } else {
7020 bval = FALSE;
7022 if (bval != *((CK_BBOOL *)tmpl_attr->pValue)) {
7023 return (B_FALSE);
7025 } else if (compare_bigint) {
7026 if (bigint == NULL) {
7027 return (B_FALSE);
7029 if (tmpl_attr->ulValueLen != bigint->big_value_len) {
7030 return (B_FALSE);
7032 if (memcmp(tmpl_attr->pValue, bigint->big_value,
7033 tmpl_attr->ulValueLen) != 0) {
7034 return (B_FALSE);
7036 } else if (compare_attr) {
7037 if (obj_attr == NULL) {
7039 * The attribute type is valid, and its value
7040 * has not been initialized in the object. In
7041 * this case, it only matches the template's
7042 * attribute if the template's value length
7043 * is 0.
7045 if (tmpl_attr->ulValueLen != 0)
7046 return (B_FALSE);
7047 } else {
7048 if (tmpl_attr->ulValueLen !=
7049 obj_attr->ulValueLen) {
7050 return (B_FALSE);
7052 if (memcmp(tmpl_attr->pValue, obj_attr->pValue,
7053 tmpl_attr->ulValueLen) != 0) {
7054 return (B_FALSE);
7057 } else if (compare_cert_val) {
7058 if (cert_attr == NULL) {
7059 /* specific attribute not found */
7060 return (B_FALSE);
7062 if (tmpl_attr->ulValueLen != cert_attr->length) {
7063 return (B_FALSE);
7065 if (memcmp(tmpl_attr->pValue, cert_attr->value,
7066 tmpl_attr->ulValueLen) != 0) {
7067 return (B_FALSE);
7069 } else if (compare_cert_type) {
7070 if (memcmp(tmpl_attr->pValue, &(obj->cert_type),
7071 tmpl_attr->ulValueLen) != 0) {
7072 return (B_FALSE);
7076 return (B_TRUE);
7079 CK_ATTRIBUTE_PTR
7080 get_extra_attr(CK_ATTRIBUTE_TYPE type, soft_object_t *obj)
7082 CK_ATTRIBUTE_INFO_PTR tmp;
7084 tmp = obj->extra_attrlistp;
7085 while (tmp != NULL) {
7086 if (tmp->attr.type == type) {
7087 return (&(tmp->attr));
7089 tmp = tmp->next;
7091 /* if get there, the specified attribute is not found */
7092 return (NULL);