Merge commit '06307114472bd8aad5ff18ccdb8e25f128ae6652'
[unleashed.git] / usr / src / lib / pkcs11 / pkcs11_softtoken / common / softAttributeUtil.c
blobd2fda815bde31fb951d221f37fa956b841430861
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;
422 * All extra attributes in the extra attribute
423 * list have pValue points to the value of the
424 * attribute (with simple byte array type).
425 * Free the storage for the value of the attribute.
427 freezero(extra_attr->attr.pValue,
428 extra_attr->attr.ulValueLen);
430 /* Free the storage for the attribute_info struct. */
431 free(extra_attr);
432 extra_attr = tmp;
435 object_p->extra_attrlistp = NULL;
440 * Create the attribute_info struct to hold the object's attribute,
441 * and add it to the extra attribute list of an object.
443 CK_RV
444 soft_add_extra_attr(CK_ATTRIBUTE_PTR template, soft_object_t *object_p)
447 CK_ATTRIBUTE_INFO_PTR attrp;
449 /* Allocate the storage for the attribute_info struct. */
450 attrp = calloc(1, sizeof (attribute_info_t));
451 if (attrp == NULL) {
452 return (CKR_HOST_MEMORY);
455 /* Set up attribute_info struct. */
456 attrp->attr.type = template->type;
457 attrp->attr.ulValueLen = template->ulValueLen;
459 if ((template->pValue != NULL) &&
460 (template->ulValueLen > 0)) {
461 /* Allocate storage for the value of the attribute. */
462 attrp->attr.pValue = malloc(template->ulValueLen);
463 if (attrp->attr.pValue == NULL) {
464 free(attrp);
465 return (CKR_HOST_MEMORY);
468 (void) memcpy(attrp->attr.pValue, template->pValue,
469 template->ulValueLen);
470 } else {
471 attrp->attr.pValue = NULL;
474 /* Insert the new attribute in front of extra attribute list. */
475 if (object_p->extra_attrlistp == NULL) {
476 object_p->extra_attrlistp = attrp;
477 attrp->next = NULL;
478 } else {
479 attrp->next = object_p->extra_attrlistp;
480 object_p->extra_attrlistp = attrp;
483 return (CKR_OK);
486 CK_RV
487 soft_copy_certificate(certificate_obj_t *oldcert, certificate_obj_t **newcert,
488 CK_CERTIFICATE_TYPE type)
490 CK_RV rv = CKR_OK;
491 certificate_obj_t *cert;
492 x509_cert_t x509;
493 x509_attr_cert_t x509_attr;
495 cert = calloc(1, sizeof (certificate_obj_t));
496 if (cert == NULL) {
497 return (CKR_HOST_MEMORY);
500 if (type == CKC_X_509) {
501 x509 = oldcert->cert_type_u.x509;
502 if (x509.subject)
503 if ((rv = copy_cert_attr(x509.subject,
504 &cert->cert_type_u.x509.subject)))
505 return (rv);
506 if (x509.value)
507 if ((rv = copy_cert_attr(x509.value,
508 &cert->cert_type_u.x509.value)))
509 return (rv);
510 } else if (type == CKC_X_509_ATTR_CERT) {
511 x509_attr = oldcert->cert_type_u.x509_attr;
512 if (x509_attr.owner)
513 if ((rv = copy_cert_attr(x509_attr.owner,
514 &cert->cert_type_u.x509_attr.owner)))
515 return (rv);
516 if (x509_attr.value)
517 if ((rv = copy_cert_attr(x509_attr.value,
518 &cert->cert_type_u.x509_attr.value)))
519 return (rv);
520 } else {
521 /* wrong certificate type */
522 rv = CKR_ATTRIBUTE_TYPE_INVALID;
524 if (rv == CKR_OK)
525 *newcert = cert;
526 return (rv);
530 * Copy the attribute_info struct from the old object to a new attribute_info
531 * struct, and add that new struct to the extra attribute list of the new
532 * object.
534 CK_RV
535 soft_copy_extra_attr(CK_ATTRIBUTE_INFO_PTR old_attrp, soft_object_t *object_p)
537 CK_ATTRIBUTE_INFO_PTR attrp;
539 /* Allocate attribute_info struct. */
540 attrp = calloc(1, sizeof (attribute_info_t));
541 if (attrp == NULL) {
542 return (CKR_HOST_MEMORY);
545 attrp->attr.type = old_attrp->attr.type;
546 attrp->attr.ulValueLen = old_attrp->attr.ulValueLen;
548 if ((old_attrp->attr.pValue != NULL) &&
549 (old_attrp->attr.ulValueLen > 0)) {
550 attrp->attr.pValue = malloc(old_attrp->attr.ulValueLen);
551 if (attrp->attr.pValue == NULL) {
552 free(attrp);
553 return (CKR_HOST_MEMORY);
556 (void) memcpy(attrp->attr.pValue, old_attrp->attr.pValue,
557 old_attrp->attr.ulValueLen);
558 } else {
559 attrp->attr.pValue = NULL;
562 /* Insert the new attribute in front of extra attribute list */
563 if (object_p->extra_attrlistp == NULL) {
564 object_p->extra_attrlistp = attrp;
565 attrp->next = NULL;
566 } else {
567 attrp->next = object_p->extra_attrlistp;
568 object_p->extra_attrlistp = attrp;
571 return (CKR_OK);
576 * Get the attribute triple from the extra attribute list in the object
577 * (if the specified attribute type is found), and copy it to a template.
578 * Note the type of the attribute to be copied is specified by the template,
579 * and the storage is pre-allocated for the atrribute value in the template
580 * for doing the copy.
582 CK_RV
583 get_extra_attr_from_object(soft_object_t *object_p, CK_ATTRIBUTE_PTR template)
586 CK_ATTRIBUTE_INFO_PTR extra_attr;
587 CK_ATTRIBUTE_TYPE type = template->type;
589 extra_attr = object_p->extra_attrlistp;
591 while (extra_attr) {
592 if (type == extra_attr->attr.type) {
593 /* Found it. */
594 break;
595 } else {
596 /* Does not match, try next one. */
597 extra_attr = extra_attr->next;
601 if (extra_attr == NULL) {
602 /* A valid but un-initialized attribute. */
603 template->ulValueLen = 0;
604 return (CKR_OK);
608 * We found the attribute in the extra attribute list.
610 if (template->pValue == NULL) {
611 template->ulValueLen = extra_attr->attr.ulValueLen;
612 return (CKR_OK);
615 if (template->ulValueLen >= extra_attr->attr.ulValueLen) {
617 * The buffer provided by the application is large
618 * enough to hold the value of the attribute.
620 (void) memcpy(template->pValue, extra_attr->attr.pValue,
621 extra_attr->attr.ulValueLen);
622 template->ulValueLen = extra_attr->attr.ulValueLen;
623 return (CKR_OK);
624 } else {
626 * The buffer provided by the application does
627 * not have enough space to hold the value.
629 template->ulValueLen = (CK_ULONG)-1;
630 return (CKR_BUFFER_TOO_SMALL);
636 * Modify the attribute triple in the extra attribute list of the object
637 * if the specified attribute type is found. Otherwise, just add it to
638 * list.
640 CK_RV
641 set_extra_attr_to_object(soft_object_t *object_p, CK_ATTRIBUTE_TYPE type,
642 CK_ATTRIBUTE_PTR template)
645 CK_ATTRIBUTE_INFO_PTR extra_attr;
647 extra_attr = object_p->extra_attrlistp;
649 while (extra_attr) {
650 if (type == extra_attr->attr.type) {
651 /* Found it. */
652 break;
653 } else {
654 /* Does not match, try next one. */
655 extra_attr = extra_attr->next;
659 if (extra_attr == NULL) {
661 * This attribute is a new one, go ahead adding it to
662 * the extra attribute list.
664 return (soft_add_extra_attr(template, object_p));
667 /* We found the attribute in the extra attribute list. */
668 if ((template->pValue != NULL) &&
669 (template->ulValueLen > 0)) {
670 if (template->ulValueLen > extra_attr->attr.ulValueLen) {
671 /* The old buffer is too small to hold the new value. */
672 /* Free storage for the old attribute value. */
673 freezero(extra_attr->attr.pValue,
674 extra_attr->attr.ulValueLen);
676 /* Allocate storage for the new attribute value. */
677 extra_attr->attr.pValue = malloc(template->ulValueLen);
678 if (extra_attr->attr.pValue == NULL) {
679 return (CKR_HOST_MEMORY);
683 /* Replace the attribute with new value. */
684 extra_attr->attr.ulValueLen = template->ulValueLen;
685 (void) memcpy(extra_attr->attr.pValue, template->pValue,
686 template->ulValueLen);
687 } else {
688 extra_attr->attr.pValue = NULL;
691 return (CKR_OK);
696 * Copy the big integer attribute value from template to a biginteger_t struct.
698 CK_RV
699 get_bigint_attr_from_template(biginteger_t *big, CK_ATTRIBUTE_PTR template)
702 if ((template->pValue != NULL) &&
703 (template->ulValueLen > 0)) {
704 /* Allocate storage for the value of the attribute. */
705 big->big_value = malloc(template->ulValueLen);
706 if (big->big_value == NULL) {
707 return (CKR_HOST_MEMORY);
710 (void) memcpy(big->big_value, template->pValue,
711 template->ulValueLen);
712 big->big_value_len = template->ulValueLen;
713 } else {
714 big->big_value = NULL;
715 big->big_value_len = 0;
718 return (CKR_OK);
723 * Copy the big integer attribute value from a biginteger_t struct in the
724 * object to a template.
726 CK_RV
727 get_bigint_attr_from_object(biginteger_t *big, CK_ATTRIBUTE_PTR template)
730 if (template->pValue == NULL) {
731 template->ulValueLen = big->big_value_len;
732 return (CKR_OK);
735 if (big->big_value == NULL) {
736 template->ulValueLen = 0;
737 return (CKR_OK);
740 if (template->ulValueLen >= big->big_value_len) {
742 * The buffer provided by the application is large
743 * enough to hold the value of the attribute.
745 (void) memcpy(template->pValue, big->big_value,
746 big->big_value_len);
747 template->ulValueLen = big->big_value_len;
748 return (CKR_OK);
749 } else {
751 * The buffer provided by the application does
752 * not have enough space to hold the value.
754 template->ulValueLen = (CK_ULONG)-1;
755 return (CKR_BUFFER_TOO_SMALL);
761 * Copy the boolean data type attribute value from an object for the
762 * specified attribute to the template.
764 CK_RV
765 get_bool_attr_from_object(soft_object_t *object_p, CK_ULONG bool_flag,
766 CK_ATTRIBUTE_PTR template)
769 if (template->pValue == NULL) {
770 template->ulValueLen = sizeof (CK_BBOOL);
771 return (CKR_OK);
774 if (template->ulValueLen >= sizeof (CK_BBOOL)) {
776 * The buffer provided by the application is large
777 * enough to hold the value of the attribute.
779 if (object_p->bool_attr_mask & bool_flag) {
780 *((CK_BBOOL *)template->pValue) = B_TRUE;
781 } else {
782 *((CK_BBOOL *)template->pValue) = B_FALSE;
785 template->ulValueLen = sizeof (CK_BBOOL);
786 return (CKR_OK);
787 } else {
789 * The buffer provided by the application does
790 * not have enough space to hold the value.
792 template->ulValueLen = (CK_ULONG)-1;
793 return (CKR_BUFFER_TOO_SMALL);
798 * Set the boolean data type attribute value in the object.
800 CK_RV
801 set_bool_attr_to_object(soft_object_t *object_p, CK_ULONG bool_flag,
802 CK_ATTRIBUTE_PTR template)
805 if (*(CK_BBOOL *)template->pValue)
806 object_p->bool_attr_mask |= bool_flag;
807 else
808 object_p->bool_attr_mask &= ~bool_flag;
810 return (CKR_OK);
815 * Copy the CK_ULONG data type attribute value from an object to the
816 * template.
818 CK_RV
819 get_ulong_attr_from_object(CK_ULONG value, CK_ATTRIBUTE_PTR template)
822 if (template->pValue == NULL) {
823 template->ulValueLen = sizeof (CK_ULONG);
824 return (CKR_OK);
827 if (template->ulValueLen >= sizeof (CK_ULONG)) {
829 * The buffer provided by the application is large
830 * enough to hold the value of the attribute.
831 * It is also assumed to be correctly aligned.
833 *(CK_ULONG_PTR)template->pValue = value;
834 template->ulValueLen = sizeof (CK_ULONG);
835 return (CKR_OK);
836 } else {
838 * The buffer provided by the application does
839 * not have enough space to hold the value.
841 template->ulValueLen = (CK_ULONG)-1;
842 return (CKR_BUFFER_TOO_SMALL);
848 * Copy the CK_ULONG data type attribute value from a template to the
849 * object.
851 static CK_RV
852 get_ulong_attr_from_template(CK_ULONG *value, CK_ATTRIBUTE_PTR template)
855 if (template->ulValueLen < sizeof (CK_ULONG))
856 return (CKR_ATTRIBUTE_VALUE_INVALID);
858 if (template->pValue != NULL) {
859 *value = *(CK_ULONG_PTR)template->pValue;
860 } else {
861 *value = 0;
864 return (CKR_OK);
868 * Copy the big integer attribute value from source's biginteger_t to
869 * destination's biginteger_t.
871 void
872 copy_bigint_attr(biginteger_t *src, biginteger_t *dst)
875 if ((src->big_value != NULL) &&
876 (src->big_value_len > 0)) {
878 * To do the copy, just have dst's big_value points
879 * to src's.
881 dst->big_value = src->big_value;
882 dst->big_value_len = src->big_value_len;
885 * After the copy, nullify the src's big_value pointer.
886 * It prevents any double freeing the value.
888 src->big_value = NULL;
889 src->big_value_len = 0;
890 } else {
891 dst->big_value = NULL;
892 dst->big_value_len = 0;
896 CK_RV
897 get_string_from_template(CK_ATTRIBUTE_PTR dest, CK_ATTRIBUTE_PTR src)
899 if ((src->pValue != NULL) &&
900 (src->ulValueLen > 0)) {
901 /* Allocate storage for the value of the attribute. */
902 dest->pValue = malloc(src->ulValueLen);
903 if (dest->pValue == NULL) {
904 return (CKR_HOST_MEMORY);
907 (void) memcpy(dest->pValue, src->pValue,
908 src->ulValueLen);
909 dest->ulValueLen = src->ulValueLen;
910 dest->type = src->type;
911 } else {
912 dest->pValue = NULL;
913 dest->ulValueLen = 0;
914 dest->type = src->type;
917 return (CKR_OK);
921 CK_RV
922 get_cert_attr_from_template(cert_attr_t **dest, CK_ATTRIBUTE_PTR src)
924 if (src->pValue != NULL && src->ulValueLen > 0) {
926 * If the attribute was already set, clear out the
927 * existing value and release the memory.
929 if (*dest != NULL) {
930 cleanup_cert_attr(*dest);
931 } else {
932 *dest = malloc(sizeof (cert_attr_t));
933 if (*dest == NULL) {
934 return (CKR_HOST_MEMORY);
936 (void) memset(*dest, 0, sizeof (cert_attr_t));
938 (*dest)->value = malloc(src->ulValueLen);
939 if ((*dest)->value == NULL) {
940 free(*dest);
941 *dest = NULL;
942 return (CKR_HOST_MEMORY);
944 (void) memcpy((*dest)->value, src->pValue, src->ulValueLen);
945 (*dest)->length = src->ulValueLen;
948 return (CKR_OK);
952 * Copy the certificate attribute information to the template.
953 * If the template attribute is not big enough, set the ulValueLen=-1
954 * and return CKR_BUFFER_TOO_SMALL.
956 static CK_RV
957 get_cert_attr_from_object(cert_attr_t *src, CK_ATTRIBUTE_PTR template)
959 if (template->pValue == NULL) {
960 template->ulValueLen = src->length;
961 return (CKR_OK);
962 } else if (template->ulValueLen >= src->length) {
964 * The buffer provided by the application is large
965 * enough to hold the value of the attribute.
967 (void) memcpy(template->pValue, src->value, src->length);
968 template->ulValueLen = src->length;
969 return (CKR_OK);
970 } else {
972 * The buffer provided by the application does
973 * not have enough space to hold the value.
975 template->ulValueLen = (CK_ULONG)-1;
976 return (CKR_BUFFER_TOO_SMALL);
980 void
981 string_attr_cleanup(CK_ATTRIBUTE_PTR template)
983 freezero(template->pValue, template->ulValueLen);
984 template->pValue = NULL;
985 template->ulValueLen = 0;
989 * Release the storage allocated for object attribute with big integer
990 * value.
992 void
993 bigint_attr_cleanup(biginteger_t *big)
996 if (big == NULL)
997 return;
999 freezero(big->big_value, big->big_value_len);
1000 big->big_value = NULL;
1001 big->big_value_len = 0;
1006 * Clean up and release all the storage allocated to hold the big integer
1007 * attributes associated with the type (i.e. class) of the object. Also,
1008 * release the storage allocated to the type of the object.
1010 void
1011 soft_cleanup_object_bigint_attrs(soft_object_t *object_p)
1014 CK_OBJECT_CLASS class = object_p->class;
1015 CK_KEY_TYPE keytype = object_p->key_type;
1018 switch (class) {
1019 case CKO_PUBLIC_KEY:
1020 if (OBJ_PUB(object_p)) {
1021 switch (keytype) {
1022 case CKK_RSA:
1023 bigint_attr_cleanup(OBJ_PUB_RSA_MOD(
1024 object_p));
1025 bigint_attr_cleanup(OBJ_PUB_RSA_PUBEXPO(
1026 object_p));
1027 break;
1029 case CKK_DSA:
1030 bigint_attr_cleanup(OBJ_PUB_DSA_PRIME(
1031 object_p));
1032 bigint_attr_cleanup(OBJ_PUB_DSA_SUBPRIME(
1033 object_p));
1034 bigint_attr_cleanup(OBJ_PUB_DSA_BASE(
1035 object_p));
1036 bigint_attr_cleanup(OBJ_PUB_DSA_VALUE(
1037 object_p));
1038 break;
1040 case CKK_DH:
1041 bigint_attr_cleanup(OBJ_PUB_DH_PRIME(
1042 object_p));
1043 bigint_attr_cleanup(OBJ_PUB_DH_BASE(
1044 object_p));
1045 bigint_attr_cleanup(OBJ_PUB_DH_VALUE(
1046 object_p));
1047 break;
1049 case CKK_X9_42_DH:
1050 bigint_attr_cleanup(OBJ_PUB_DH942_PRIME(
1051 object_p));
1052 bigint_attr_cleanup(OBJ_PUB_DH942_BASE(
1053 object_p));
1054 bigint_attr_cleanup(OBJ_PUB_DH942_SUBPRIME(
1055 object_p));
1056 bigint_attr_cleanup(OBJ_PUB_DH942_VALUE(
1057 object_p));
1058 break;
1059 case CKK_EC:
1060 bigint_attr_cleanup(OBJ_PUB_EC_POINT(
1061 object_p));
1062 break;
1065 /* Release Public Key Object struct */
1066 free(OBJ_PUB(object_p));
1067 OBJ_PUB(object_p) = NULL;
1069 break;
1071 case CKO_PRIVATE_KEY:
1072 if (OBJ_PRI(object_p)) {
1073 switch (keytype) {
1074 case CKK_RSA:
1075 bigint_attr_cleanup(OBJ_PRI_RSA_MOD(
1076 object_p));
1077 bigint_attr_cleanup(OBJ_PRI_RSA_PUBEXPO(
1078 object_p));
1079 bigint_attr_cleanup(OBJ_PRI_RSA_PRIEXPO(
1080 object_p));
1081 bigint_attr_cleanup(OBJ_PRI_RSA_PRIME1(
1082 object_p));
1083 bigint_attr_cleanup(OBJ_PRI_RSA_PRIME2(
1084 object_p));
1085 bigint_attr_cleanup(OBJ_PRI_RSA_EXPO1(
1086 object_p));
1087 bigint_attr_cleanup(OBJ_PRI_RSA_EXPO2(
1088 object_p));
1089 bigint_attr_cleanup(OBJ_PRI_RSA_COEF(
1090 object_p));
1091 break;
1093 case CKK_DSA:
1094 bigint_attr_cleanup(OBJ_PRI_DSA_PRIME(
1095 object_p));
1096 bigint_attr_cleanup(OBJ_PRI_DSA_SUBPRIME(
1097 object_p));
1098 bigint_attr_cleanup(OBJ_PRI_DSA_BASE(
1099 object_p));
1100 bigint_attr_cleanup(OBJ_PRI_DSA_VALUE(
1101 object_p));
1102 break;
1104 case CKK_DH:
1105 bigint_attr_cleanup(OBJ_PRI_DH_PRIME(
1106 object_p));
1107 bigint_attr_cleanup(OBJ_PRI_DH_BASE(
1108 object_p));
1109 bigint_attr_cleanup(OBJ_PRI_DH_VALUE(
1110 object_p));
1111 break;
1113 case CKK_X9_42_DH:
1114 bigint_attr_cleanup(OBJ_PRI_DH942_PRIME(
1115 object_p));
1116 bigint_attr_cleanup(OBJ_PRI_DH942_BASE(
1117 object_p));
1118 bigint_attr_cleanup(OBJ_PRI_DH942_SUBPRIME(
1119 object_p));
1120 bigint_attr_cleanup(OBJ_PRI_DH942_VALUE(
1121 object_p));
1122 break;
1124 case CKK_EC:
1125 bigint_attr_cleanup(OBJ_PRI_EC_VALUE(
1126 object_p));
1127 break;
1130 /* Release Private Key Object struct. */
1131 free(OBJ_PRI(object_p));
1132 OBJ_PRI(object_p) = NULL;
1134 break;
1136 case CKO_SECRET_KEY:
1137 if (OBJ_SEC(object_p)) {
1138 /* cleanup key data area */
1139 if (OBJ_SEC_VALUE(object_p) != NULL &&
1140 OBJ_SEC_VALUE_LEN(object_p) > 0) {
1141 freezero(OBJ_SEC_VALUE(object_p),
1142 OBJ_SEC_VALUE_LEN(object_p));
1144 /* cleanup key schedule data area */
1145 if (OBJ_KEY_SCHED(object_p) != NULL &&
1146 OBJ_KEY_SCHED_LEN(object_p) > 0) {
1147 freezero(OBJ_KEY_SCHED(object_p),
1148 OBJ_KEY_SCHED_LEN(object_p));
1151 /* Release Secret Key Object struct. */
1152 free(OBJ_SEC(object_p));
1153 OBJ_SEC(object_p) = NULL;
1155 break;
1157 case CKO_DOMAIN_PARAMETERS:
1158 if (OBJ_DOM(object_p)) {
1159 switch (keytype) {
1160 case CKK_DSA:
1161 bigint_attr_cleanup(OBJ_DOM_DSA_PRIME(
1162 object_p));
1163 bigint_attr_cleanup(OBJ_DOM_DSA_SUBPRIME(
1164 object_p));
1165 bigint_attr_cleanup(OBJ_DOM_DSA_BASE(
1166 object_p));
1167 break;
1169 case CKK_DH:
1170 bigint_attr_cleanup(OBJ_DOM_DH_PRIME(
1171 object_p));
1172 bigint_attr_cleanup(OBJ_DOM_DH_BASE(
1173 object_p));
1174 break;
1176 case CKK_X9_42_DH:
1177 bigint_attr_cleanup(OBJ_DOM_DH942_PRIME(
1178 object_p));
1179 bigint_attr_cleanup(OBJ_DOM_DH942_BASE(
1180 object_p));
1181 bigint_attr_cleanup(OBJ_DOM_DH942_SUBPRIME(
1182 object_p));
1183 break;
1186 /* Release Domain Parameters Object struct. */
1187 free(OBJ_DOM(object_p));
1188 OBJ_DOM(object_p) = NULL;
1190 break;
1196 * Parse the common attributes. Return to caller with appropriate return
1197 * value to indicate if the supplied template specifies a valid attribute
1198 * with a valid value.
1200 CK_RV
1201 soft_parse_common_attrs(CK_ATTRIBUTE_PTR template, uchar_t *object_type)
1204 CK_RV rv = CKR_OK;
1206 switch (template->type) {
1207 case CKA_CLASS:
1208 break;
1210 /* default boolean attributes */
1211 case CKA_TOKEN:
1212 if ((*(CK_BBOOL *)template->pValue) == B_TRUE) {
1213 if (!soft_keystore_status(KEYSTORE_INITIALIZED))
1214 return (CKR_DEVICE_REMOVED);
1215 *object_type |= TOKEN_OBJECT;
1217 break;
1219 case CKA_PRIVATE:
1220 if ((*(CK_BBOOL *)template->pValue) == B_TRUE) {
1221 (void) pthread_mutex_lock(&soft_giant_mutex);
1222 if (!soft_slot.authenticated) {
1224 * Check if this is the special case when
1225 * the PIN is never initialized in the keystore.
1226 * If true, we will let it pass here and let
1227 * it fail with CKR_PIN_EXPIRED later on.
1229 if (!soft_slot.userpin_change_needed) {
1230 (void) pthread_mutex_unlock(
1231 &soft_giant_mutex);
1232 return (CKR_USER_NOT_LOGGED_IN);
1235 (void) pthread_mutex_unlock(&soft_giant_mutex);
1236 *object_type |= PRIVATE_OBJECT;
1238 break;
1240 case CKA_LABEL:
1241 break;
1243 default:
1244 rv = CKR_TEMPLATE_INCONSISTENT;
1247 return (rv);
1252 * Build a Public Key Object.
1254 * - Parse the object's template, and when an error is detected such as
1255 * invalid attribute type, invalid attribute value, etc., return
1256 * with appropriate return value.
1257 * - Set up attribute mask field in the object for the supplied common
1258 * attributes that have boolean type.
1259 * - Build the attribute_info struct to hold the value of each supplied
1260 * attribute that has byte array type. Link attribute_info structs
1261 * together to form the extra attribute list of the object.
1262 * - Allocate storage for the Public Key object.
1263 * - Build the Public Key object according to the key type. Allocate
1264 * storage to hold the big integer value for the supplied attributes
1265 * that are required for a certain key type.
1268 CK_RV
1269 soft_build_public_key_object(CK_ATTRIBUTE_PTR template, CK_ULONG ulAttrNum,
1270 soft_object_t *new_object, CK_ULONG mode, CK_KEY_TYPE key_type)
1273 ulong_t i;
1274 CK_KEY_TYPE keytype = (CK_KEY_TYPE)~0UL;
1275 uint64_t attr_mask = PUBLIC_KEY_DEFAULT;
1276 CK_RV rv = CKR_OK;
1277 int isLabel = 0;
1278 /* Must set flags */
1279 int isModulus = 0;
1280 int isPubExpo = 0;
1281 int isPrime = 0;
1282 int isSubprime = 0;
1283 int isBase = 0;
1284 int isValue = 0;
1285 int isECParam = 0;
1286 int isECPoint = 0;
1287 /* Must not set flags */
1288 int isModulusBits = 0;
1289 CK_ULONG modulus_bits = 0;
1291 biginteger_t modulus;
1292 biginteger_t pubexpo;
1293 biginteger_t prime;
1294 biginteger_t subprime;
1295 biginteger_t base;
1296 biginteger_t value;
1297 biginteger_t point;
1298 CK_ATTRIBUTE string_tmp;
1299 CK_ATTRIBUTE param_tmp;
1301 public_key_obj_t *pbk;
1302 uchar_t object_type = 0;
1304 CK_ATTRIBUTE defpubexpo = { CKA_PUBLIC_EXPONENT,
1305 (CK_BYTE_PTR)DEFAULT_PUB_EXPO, DEFAULT_PUB_EXPO_Len };
1307 BIGNUM n;
1309 /* prevent bigint_attr_cleanup from freeing invalid attr value */
1310 (void) memset(&modulus, 0x0, sizeof (biginteger_t));
1311 (void) memset(&pubexpo, 0x0, sizeof (biginteger_t));
1312 (void) memset(&prime, 0x0, sizeof (biginteger_t));
1313 (void) memset(&subprime, 0x0, sizeof (biginteger_t));
1314 (void) memset(&base, 0x0, sizeof (biginteger_t));
1315 (void) memset(&value, 0x0, sizeof (biginteger_t));
1316 (void) memset(&point, 0x0, sizeof (biginteger_t));
1317 string_tmp.pValue = NULL;
1318 param_tmp.pValue = NULL;
1320 for (i = 0; i < ulAttrNum; i++) {
1322 /* Public Key Object Attributes */
1323 switch (template[i].type) {
1325 /* common key attributes */
1326 case CKA_KEY_TYPE:
1327 keytype = *((CK_KEY_TYPE*)template[i].pValue);
1328 break;
1330 case CKA_ID:
1331 case CKA_START_DATE:
1332 case CKA_END_DATE:
1334 /* common public key attribute */
1335 case CKA_SUBJECT:
1337 * Allocate storage to hold the attribute
1338 * value with byte array type, and add it to
1339 * the extra attribute list of the object.
1341 rv = soft_add_extra_attr(&template[i],
1342 new_object);
1343 if (rv != CKR_OK) {
1344 goto fail_cleanup;
1346 break;
1349 * The following key related attribute types must
1350 * not be specified by C_CreateObject, C_GenerateKey(Pair).
1352 case CKA_LOCAL:
1353 case CKA_KEY_GEN_MECHANISM:
1354 rv = CKR_TEMPLATE_INCONSISTENT;
1355 goto fail_cleanup;
1357 /* Key related boolean attributes */
1358 case CKA_DERIVE:
1359 if (*(CK_BBOOL *)template[i].pValue)
1360 attr_mask |= DERIVE_BOOL_ON;
1361 break;
1363 case CKA_ENCRYPT:
1364 if (*(CK_BBOOL *)template[i].pValue)
1365 attr_mask |= ENCRYPT_BOOL_ON;
1366 else
1367 attr_mask &= ~ENCRYPT_BOOL_ON;
1368 break;
1370 case CKA_VERIFY:
1371 if (*(CK_BBOOL *)template[i].pValue)
1372 attr_mask |= VERIFY_BOOL_ON;
1373 else
1374 attr_mask &= ~VERIFY_BOOL_ON;
1375 break;
1377 case CKA_VERIFY_RECOVER:
1378 if (*(CK_BBOOL *)template[i].pValue)
1379 attr_mask |= VERIFY_RECOVER_BOOL_ON;
1380 else
1381 attr_mask &= ~VERIFY_RECOVER_BOOL_ON;
1382 break;
1384 case CKA_WRAP:
1385 if (*(CK_BBOOL *)template[i].pValue)
1386 attr_mask |= WRAP_BOOL_ON;
1387 else
1388 attr_mask &= ~WRAP_BOOL_ON;
1389 break;
1391 case CKA_TRUSTED:
1392 if (*(CK_BBOOL *)template[i].pValue)
1393 attr_mask |= TRUSTED_BOOL_ON;
1394 break;
1396 case CKA_MODIFIABLE:
1397 if ((*(CK_BBOOL *)template[i].pValue) == B_FALSE)
1398 attr_mask |= NOT_MODIFIABLE_BOOL_ON;
1399 break;
1402 * The following key related attribute types must
1403 * be specified according to the key type by
1404 * C_CreateObject.
1406 case CKA_MODULUS:
1408 isModulus = 1;
1410 * Copyin big integer attribute from template
1411 * to a local variable.
1413 rv = get_bigint_attr_from_template(&modulus,
1414 &template[i]);
1415 if (rv != CKR_OK)
1416 goto fail_cleanup;
1419 * Modulus length needs to be between min key length and
1420 * max key length.
1422 if ((modulus.big_value_len <
1423 MIN_RSA_KEYLENGTH_IN_BYTES) ||
1424 (modulus.big_value_len >
1425 MAX_RSA_KEYLENGTH_IN_BYTES)) {
1426 rv = CKR_ATTRIBUTE_VALUE_INVALID;
1427 goto fail_cleanup;
1429 break;
1431 case CKA_PUBLIC_EXPONENT:
1432 isPubExpo = 1;
1433 rv = get_bigint_attr_from_template(&pubexpo,
1434 &template[i]);
1435 if (rv != CKR_OK)
1436 goto fail_cleanup;
1437 break;
1439 case CKA_PRIME:
1440 isPrime = 1;
1441 rv = get_bigint_attr_from_template(&prime,
1442 &template[i]);
1443 if (rv != CKR_OK)
1444 goto fail_cleanup;
1445 break;
1447 case CKA_SUBPRIME:
1448 isSubprime = 1;
1449 rv = get_bigint_attr_from_template(&subprime,
1450 &template[i]);
1451 if (rv != CKR_OK)
1452 goto fail_cleanup;
1453 break;
1455 case CKA_BASE:
1456 isBase = 1;
1457 rv = get_bigint_attr_from_template(&base,
1458 &template[i]);
1459 if (rv != CKR_OK)
1460 goto fail_cleanup;
1461 break;
1463 case CKA_VALUE:
1464 isValue = 1;
1465 if (mode == SOFT_CREATE_OBJ) {
1466 if ((template[i].ulValueLen == 0) ||
1467 (template[i].pValue == NULL)) {
1468 rv = CKR_ATTRIBUTE_VALUE_INVALID;
1469 goto fail_cleanup;
1473 rv = get_bigint_attr_from_template(&value,
1474 &template[i]);
1475 if (rv != CKR_OK)
1476 goto fail_cleanup;
1477 break;
1479 case CKA_MODULUS_BITS:
1480 isModulusBits = 1;
1481 rv = get_ulong_attr_from_template(&modulus_bits,
1482 &template[i]);
1483 if (rv != CKR_OK)
1484 goto fail_cleanup;
1485 break;
1487 case CKA_LABEL:
1488 isLabel = 1;
1489 rv = get_string_from_template(&string_tmp,
1490 &template[i]);
1491 if (rv != CKR_OK)
1492 goto fail_cleanup;
1493 break;
1495 case CKA_EC_PARAMS:
1496 isECParam = 1;
1497 rv = get_string_from_template(&param_tmp, &template[i]);
1498 if (rv != CKR_OK)
1499 goto fail_cleanup;
1500 break;
1502 case CKA_EC_POINT:
1503 isECPoint = 1;
1504 rv = get_bigint_attr_from_template(&point,
1505 &template[i]);
1506 if (rv != CKR_OK)
1507 goto fail_cleanup;
1508 break;
1510 default:
1511 rv = soft_parse_common_attrs(&template[i],
1512 &object_type);
1513 if (rv != CKR_OK)
1514 goto fail_cleanup;
1515 break;
1517 } /* For */
1519 /* Allocate storage for Public Key Object. */
1520 pbk = calloc(1, sizeof (public_key_obj_t));
1521 if (pbk == NULL) {
1522 rv = CKR_HOST_MEMORY;
1523 goto fail_cleanup;
1526 new_object->object_class_u.public_key = pbk;
1527 new_object->class = CKO_PUBLIC_KEY;
1529 if ((mode == SOFT_CREATE_OBJ) && (keytype == (CK_KEY_TYPE)~0UL)) {
1530 rv = CKR_TEMPLATE_INCOMPLETE;
1531 goto fail_cleanup;
1534 if ((mode == SOFT_GEN_KEY) && (keytype == (CK_KEY_TYPE)~0UL)) {
1535 keytype = key_type;
1538 if ((mode == SOFT_GEN_KEY) && (keytype != key_type)) {
1540 * The key type specified in the template does not
1541 * match the implied key type based on the mechanism.
1543 rv = CKR_TEMPLATE_INCONSISTENT;
1544 goto fail_cleanup;
1547 new_object->key_type = keytype;
1549 /* Supported key types of the Public Key Object */
1550 switch (keytype) {
1552 case CKK_RSA:
1553 if (mode == SOFT_CREATE_OBJ) {
1554 if (isModulusBits || isPrime || isSubprime ||
1555 isBase || isValue) {
1556 rv = CKR_TEMPLATE_INCONSISTENT;
1557 goto fail_cleanup;
1560 if (isModulus && isPubExpo) {
1562 * Derive modulus_bits attribute from modulus.
1563 * Save modulus_bits integer value to the
1564 * designated place in the public key object.
1566 n.malloced = 0;
1567 if (big_init(&n, CHARLEN2BIGNUMLEN(
1568 modulus.big_value_len)) != BIG_OK) {
1569 rv = CKR_HOST_MEMORY;
1570 big_finish(&n);
1571 goto fail_cleanup;
1573 bytestring2bignum(&n, modulus.big_value,
1574 modulus.big_value_len);
1576 modulus_bits = big_bitlength(&n);
1577 KEY_PUB_RSA_MOD_BITS(pbk) = modulus_bits;
1578 big_finish(&n);
1581 * After modulus_bits has been computed,
1582 * it is safe to move modulus and pubexpo
1583 * big integer attribute value to the
1584 * designated place in the public key object.
1586 copy_bigint_attr(&modulus,
1587 KEY_PUB_RSA_MOD(pbk));
1589 copy_bigint_attr(&pubexpo,
1590 KEY_PUB_RSA_PUBEXPO(pbk));
1591 } else {
1592 rv = CKR_TEMPLATE_INCOMPLETE;
1593 goto fail_cleanup;
1595 } else {
1596 /* mode is SOFT_GEN_KEY */
1598 if (isModulus || isPrime || isSubprime ||
1599 isBase || isValue) {
1600 rv = CKR_TEMPLATE_INCONSISTENT;
1601 goto fail_cleanup;
1605 if (isModulusBits) {
1607 * Copy big integer attribute value to the
1608 * designated place in the public key object.
1610 KEY_PUB_RSA_MOD_BITS(pbk) = modulus_bits;
1611 } else {
1612 rv = CKR_TEMPLATE_INCOMPLETE;
1613 goto fail_cleanup;
1617 * Use PKCS#11 default 0x010001 for public exponent
1618 * if not not specified in attribute template.
1620 if (!isPubExpo) {
1621 isPubExpo = 1;
1622 rv = get_bigint_attr_from_template(&pubexpo,
1623 &defpubexpo);
1624 if (rv != CKR_OK)
1625 goto fail_cleanup;
1628 * Copy big integer attribute value to the
1629 * designated place in the public key object.
1631 copy_bigint_attr(&pubexpo, KEY_PUB_RSA_PUBEXPO(pbk));
1634 break;
1636 case CKK_DSA:
1637 if (mode == SOFT_CREATE_OBJ) {
1638 if (isModulusBits || isModulus || isPubExpo) {
1639 rv = CKR_TEMPLATE_INCONSISTENT;
1640 goto fail_cleanup;
1643 if (isPrime && isSubprime && isBase && isValue) {
1644 copy_bigint_attr(&value,
1645 KEY_PUB_DSA_VALUE(pbk));
1646 } else {
1647 rv = CKR_TEMPLATE_INCOMPLETE;
1648 goto fail_cleanup;
1650 } else {
1651 if (isModulusBits || isModulus || isPubExpo ||
1652 isValue) {
1653 rv = CKR_TEMPLATE_INCONSISTENT;
1654 goto fail_cleanup;
1657 if (!(isPrime && isSubprime && isBase)) {
1658 rv = CKR_TEMPLATE_INCOMPLETE;
1659 goto fail_cleanup;
1663 copy_bigint_attr(&prime, KEY_PUB_DSA_PRIME(pbk));
1665 copy_bigint_attr(&subprime, KEY_PUB_DSA_SUBPRIME(pbk));
1667 copy_bigint_attr(&base, KEY_PUB_DSA_BASE(pbk));
1669 break;
1671 case CKK_DH:
1672 if (mode == SOFT_CREATE_OBJ) {
1673 if (isModulusBits || isModulus || isPubExpo ||
1674 isSubprime) {
1675 rv = CKR_TEMPLATE_INCONSISTENT;
1676 goto fail_cleanup;
1679 if (isPrime && isBase && isValue) {
1680 copy_bigint_attr(&value,
1681 KEY_PUB_DH_VALUE(pbk));
1682 } else {
1683 rv = CKR_TEMPLATE_INCOMPLETE;
1684 goto fail_cleanup;
1686 } else {
1687 if (isModulusBits || isModulus || isPubExpo ||
1688 isSubprime || isValue) {
1689 rv = CKR_TEMPLATE_INCONSISTENT;
1690 goto fail_cleanup;
1693 if (!(isPrime && isBase)) {
1694 rv = CKR_TEMPLATE_INCOMPLETE;
1695 goto fail_cleanup;
1699 copy_bigint_attr(&prime, KEY_PUB_DH_PRIME(pbk));
1701 copy_bigint_attr(&base, KEY_PUB_DH_BASE(pbk));
1703 break;
1705 case CKK_X9_42_DH:
1706 if (mode == SOFT_CREATE_OBJ) {
1707 if (isModulusBits || isModulus || isPubExpo) {
1708 rv = CKR_TEMPLATE_INCONSISTENT;
1709 goto fail_cleanup;
1712 if (isPrime && isSubprime && isBase && isValue) {
1713 copy_bigint_attr(&value,
1714 KEY_PUB_DH942_VALUE(pbk));
1715 } else {
1716 rv = CKR_TEMPLATE_INCOMPLETE;
1717 goto fail_cleanup;
1719 } else {
1720 if (isModulusBits || isModulus || isPubExpo ||
1721 isValue) {
1722 rv = CKR_TEMPLATE_INCONSISTENT;
1723 goto fail_cleanup;
1726 if (!(isPrime && isSubprime && isBase)) {
1727 rv = CKR_TEMPLATE_INCOMPLETE;
1728 goto fail_cleanup;
1732 copy_bigint_attr(&prime, KEY_PUB_DH942_PRIME(pbk));
1734 copy_bigint_attr(&base, KEY_PUB_DH942_BASE(pbk));
1736 copy_bigint_attr(&subprime, KEY_PUB_DH942_SUBPRIME(pbk));
1738 break;
1740 case CKK_EC:
1741 if (mode == SOFT_CREATE_OBJ) {
1742 if (isModulusBits || isModulus || isPubExpo ||
1743 isPrime || isSubprime || isBase || isValue) {
1744 rv = CKR_TEMPLATE_INCONSISTENT;
1745 goto fail_cleanup;
1747 } else if (!isECParam || !isECPoint) {
1748 rv = CKR_TEMPLATE_INCOMPLETE;
1749 goto fail_cleanup;
1751 } else {
1752 if (isModulusBits || isModulus || isPubExpo ||
1753 isPrime || isSubprime || isBase || isValue) {
1754 rv = CKR_TEMPLATE_INCONSISTENT;
1755 goto fail_cleanup;
1757 } else if (!isECParam) {
1758 rv = CKR_TEMPLATE_INCOMPLETE;
1759 goto fail_cleanup;
1763 if (isECPoint) {
1764 copy_bigint_attr(&point, KEY_PUB_EC_POINT(pbk));
1766 rv = soft_add_extra_attr(&param_tmp, new_object);
1767 if (rv != CKR_OK)
1768 goto fail_cleanup;
1769 string_attr_cleanup(&param_tmp);
1770 break;
1772 default:
1773 rv = CKR_TEMPLATE_INCONSISTENT;
1774 goto fail_cleanup;
1777 /* Set up object. */
1778 new_object->object_type = object_type;
1779 new_object->bool_attr_mask = attr_mask;
1780 if (isLabel) {
1781 rv = soft_add_extra_attr(&string_tmp, new_object);
1782 if (rv != CKR_OK)
1783 goto fail_cleanup;
1784 string_attr_cleanup(&string_tmp);
1787 return (rv);
1789 fail_cleanup:
1791 * cleanup the storage allocated to the local variables.
1793 bigint_attr_cleanup(&modulus);
1794 bigint_attr_cleanup(&pubexpo);
1795 bigint_attr_cleanup(&prime);
1796 bigint_attr_cleanup(&subprime);
1797 bigint_attr_cleanup(&base);
1798 bigint_attr_cleanup(&value);
1799 bigint_attr_cleanup(&point);
1800 string_attr_cleanup(&string_tmp);
1801 string_attr_cleanup(&param_tmp);
1804 * cleanup the storage allocated inside the object itself.
1806 soft_cleanup_object(new_object);
1808 return (rv);
1813 * Build a Private Key Object.
1815 * - Parse the object's template, and when an error is detected such as
1816 * invalid attribute type, invalid attribute value, etc., return
1817 * with appropriate return value.
1818 * - Set up attribute mask field in the object for the supplied common
1819 * attributes that have boolean type.
1820 * - Build the attribute_info struct to hold the value of each supplied
1821 * attribute that has byte array type. Link attribute_info structs
1822 * together to form the extra attribute list of the object.
1823 * - Allocate storage for the Private Key object.
1824 * - Build the Private Key object according to the key type. Allocate
1825 * storage to hold the big integer value for the supplied attributes
1826 * that are required for a certain key type.
1829 CK_RV
1830 soft_build_private_key_object(CK_ATTRIBUTE_PTR template, CK_ULONG ulAttrNum,
1831 soft_object_t *new_object, CK_ULONG mode, CK_KEY_TYPE key_type)
1833 ulong_t i;
1834 CK_KEY_TYPE keytype = (CK_KEY_TYPE)~0UL;
1835 uint64_t attr_mask = PRIVATE_KEY_DEFAULT;
1836 CK_RV rv = CKR_OK;
1837 int isLabel = 0;
1838 int isECParam = 0;
1839 /* Must set flags unless mode == SOFT_UNWRAP_KEY */
1840 int isModulus = 0;
1841 int isPriExpo = 0;
1842 int isPrime = 0;
1843 int isSubprime = 0;
1844 int isBase = 0;
1845 /* Must set flags if mode == SOFT_GEN_KEY */
1846 int isValue = 0;
1847 /* Must not set flags */
1848 int isValueBits = 0;
1849 CK_ULONG value_bits = 0;
1851 /* Private Key RSA optional */
1852 int isPubExpo = 0;
1853 int isPrime1 = 0;
1854 int isPrime2 = 0;
1855 int isExpo1 = 0;
1856 int isExpo2 = 0;
1857 int isCoef = 0;
1859 biginteger_t modulus;
1860 biginteger_t priexpo;
1861 biginteger_t prime;
1862 biginteger_t subprime;
1863 biginteger_t base;
1864 biginteger_t value;
1866 biginteger_t pubexpo;
1867 biginteger_t prime1;
1868 biginteger_t prime2;
1869 biginteger_t expo1;
1870 biginteger_t expo2;
1871 biginteger_t coef;
1872 CK_ATTRIBUTE string_tmp;
1873 CK_ATTRIBUTE param_tmp;
1874 BIGNUM x, q;
1876 private_key_obj_t *pvk;
1877 uchar_t object_type = 0;
1879 /* prevent bigint_attr_cleanup from freeing invalid attr value */
1880 (void) memset(&modulus, 0x0, sizeof (biginteger_t));
1881 (void) memset(&priexpo, 0x0, sizeof (biginteger_t));
1882 (void) memset(&prime, 0x0, sizeof (biginteger_t));
1883 (void) memset(&subprime, 0x0, sizeof (biginteger_t));
1884 (void) memset(&base, 0x0, sizeof (biginteger_t));
1885 (void) memset(&value, 0x0, sizeof (biginteger_t));
1886 (void) memset(&pubexpo, 0x0, sizeof (biginteger_t));
1887 (void) memset(&prime1, 0x0, sizeof (biginteger_t));
1888 (void) memset(&prime2, 0x0, sizeof (biginteger_t));
1889 (void) memset(&expo1, 0x0, sizeof (biginteger_t));
1890 (void) memset(&expo2, 0x0, sizeof (biginteger_t));
1891 (void) memset(&coef, 0x0, sizeof (biginteger_t));
1892 string_tmp.pValue = NULL;
1893 param_tmp.pValue = NULL;
1894 x.malloced = 0;
1895 q.malloced = 0;
1897 for (i = 0; i < ulAttrNum; i++) {
1899 /* Private Key Object Attributes */
1900 switch (template[i].type) {
1901 /* common key attributes */
1902 case CKA_KEY_TYPE:
1903 keytype = *((CK_KEY_TYPE*)template[i].pValue);
1904 break;
1906 case CKA_ID:
1907 case CKA_START_DATE:
1908 case CKA_END_DATE:
1910 /* common private key attribute */
1911 case CKA_SUBJECT:
1913 * Allocate storage to hold the attribute
1914 * value with byte array type, and add it to
1915 * the extra attribute list of the object.
1917 rv = soft_add_extra_attr(&template[i],
1918 new_object);
1919 if (rv != CKR_OK) {
1920 goto fail_cleanup;
1922 break;
1925 * The following key related attribute types must
1926 * not be specified by C_CreateObject or C_GenerateKey(Pair).
1928 case CKA_LOCAL:
1929 case CKA_KEY_GEN_MECHANISM:
1930 case CKA_AUTH_PIN_FLAGS:
1931 case CKA_ALWAYS_SENSITIVE:
1932 case CKA_NEVER_EXTRACTABLE:
1933 rv = CKR_TEMPLATE_INCONSISTENT;
1934 goto fail_cleanup;
1936 /* Key related boolean attributes */
1937 case CKA_DERIVE:
1938 if (*(CK_BBOOL *)template[i].pValue)
1939 attr_mask |= DERIVE_BOOL_ON;
1940 break;
1942 case CKA_SENSITIVE:
1943 if (*(CK_BBOOL *)template[i].pValue)
1944 attr_mask |= SENSITIVE_BOOL_ON;
1945 break;
1947 case CKA_SECONDARY_AUTH:
1948 if (*(CK_BBOOL *)template[i].pValue) {
1949 rv = CKR_ATTRIBUTE_VALUE_INVALID;
1950 goto fail_cleanup;
1952 break;
1954 case CKA_DECRYPT:
1955 if (*(CK_BBOOL *)template[i].pValue)
1956 attr_mask |= DECRYPT_BOOL_ON;
1957 else
1958 attr_mask &= ~DECRYPT_BOOL_ON;
1959 break;
1961 case CKA_SIGN:
1962 if (*(CK_BBOOL *)template[i].pValue)
1963 attr_mask |= SIGN_BOOL_ON;
1964 else
1965 attr_mask &= ~SIGN_BOOL_ON;
1966 break;
1968 case CKA_SIGN_RECOVER:
1969 if (*(CK_BBOOL *)template[i].pValue)
1970 attr_mask |= SIGN_RECOVER_BOOL_ON;
1971 else
1972 attr_mask &= ~SIGN_RECOVER_BOOL_ON;
1973 break;
1975 case CKA_UNWRAP:
1976 if (*(CK_BBOOL *)template[i].pValue)
1977 attr_mask |= UNWRAP_BOOL_ON;
1978 else
1979 attr_mask &= ~UNWRAP_BOOL_ON;
1980 break;
1982 case CKA_EXTRACTABLE:
1983 if (*(CK_BBOOL *)template[i].pValue)
1984 attr_mask |= EXTRACTABLE_BOOL_ON;
1985 else
1986 attr_mask &= ~EXTRACTABLE_BOOL_ON;
1987 break;
1989 case CKA_MODIFIABLE:
1990 if ((*(CK_BBOOL *)template[i].pValue) == B_FALSE)
1991 attr_mask |= NOT_MODIFIABLE_BOOL_ON;
1992 break;
1995 * The following key related attribute types must
1996 * be specified according to the key type by
1997 * C_CreateObject.
1999 case CKA_MODULUS:
2001 isModulus = 1;
2003 * Copyin big integer attribute from template
2004 * to a local variable.
2006 rv = get_bigint_attr_from_template(&modulus,
2007 &template[i]);
2008 if (rv != CKR_OK)
2009 goto fail_cleanup;
2012 * Modulus length needs to be between min key length and
2013 * max key length.
2015 if ((modulus.big_value_len <
2016 MIN_RSA_KEYLENGTH_IN_BYTES) ||
2017 (modulus.big_value_len >
2018 MAX_RSA_KEYLENGTH_IN_BYTES)) {
2019 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2020 goto fail_cleanup;
2022 break;
2024 case CKA_PUBLIC_EXPONENT:
2026 isPubExpo = 1;
2027 rv = get_bigint_attr_from_template(&pubexpo,
2028 &template[i]);
2029 if (rv != CKR_OK)
2030 goto fail_cleanup;
2031 break;
2033 case CKA_PRIVATE_EXPONENT:
2035 isPriExpo = 1;
2036 rv = get_bigint_attr_from_template(&priexpo,
2037 &template[i]);
2038 if (rv != CKR_OK)
2039 goto fail_cleanup;
2040 break;
2042 case CKA_PRIME_1:
2043 isPrime1 = 1;
2044 rv = get_bigint_attr_from_template(&prime1,
2045 &template[i]);
2046 if (rv != CKR_OK)
2047 goto fail_cleanup;
2048 break;
2050 case CKA_PRIME_2:
2051 isPrime2 = 1;
2052 rv = get_bigint_attr_from_template(&prime2,
2053 &template[i]);
2054 if (rv != CKR_OK)
2055 goto fail_cleanup;
2056 break;
2058 case CKA_EXPONENT_1:
2059 isExpo1 = 1;
2060 rv = get_bigint_attr_from_template(&expo1,
2061 &template[i]);
2062 if (rv != CKR_OK)
2063 goto fail_cleanup;
2064 break;
2066 case CKA_EXPONENT_2:
2067 isExpo2 = 1;
2068 rv = get_bigint_attr_from_template(&expo2,
2069 &template[i]);
2070 if (rv != CKR_OK)
2071 goto fail_cleanup;
2072 break;
2074 case CKA_COEFFICIENT:
2075 isCoef = 1;
2076 rv = get_bigint_attr_from_template(&coef,
2077 &template[i]);
2078 if (rv != CKR_OK)
2079 goto fail_cleanup;
2080 break;
2082 case CKA_PRIME:
2083 isPrime = 1;
2084 rv = get_bigint_attr_from_template(&prime,
2085 &template[i]);
2086 if (rv != CKR_OK)
2087 goto fail_cleanup;
2088 break;
2090 case CKA_SUBPRIME:
2091 isSubprime = 1;
2092 rv = get_bigint_attr_from_template(&subprime,
2093 &template[i]);
2094 if (rv != CKR_OK)
2095 goto fail_cleanup;
2096 break;
2098 case CKA_BASE:
2099 isBase = 1;
2100 rv = get_bigint_attr_from_template(&base,
2101 &template[i]);
2102 if (rv != CKR_OK)
2103 goto fail_cleanup;
2104 break;
2106 case CKA_VALUE:
2107 isValue = 1;
2108 if (mode == SOFT_CREATE_OBJ) {
2109 if ((template[i].ulValueLen == 0) ||
2110 (template[i].pValue == NULL)) {
2111 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2112 goto fail_cleanup;
2116 rv = get_bigint_attr_from_template(&value,
2117 &template[i]);
2118 if (rv != CKR_OK)
2119 goto fail_cleanup;
2120 break;
2122 case CKA_VALUE_BITS:
2123 isValueBits = 1;
2124 rv = get_ulong_attr_from_template(&value_bits,
2125 &template[i]);
2126 if (rv != CKR_OK)
2127 goto fail_cleanup;
2128 break;
2130 case CKA_LABEL:
2131 isLabel = 1;
2132 rv = get_string_from_template(&string_tmp,
2133 &template[i]);
2134 if (rv != CKR_OK)
2135 goto fail_cleanup;
2136 break;
2138 case CKA_EC_PARAMS:
2139 isECParam = 1;
2140 rv = get_string_from_template(&param_tmp,
2141 &template[i]);
2142 if (rv != CKR_OK)
2143 goto fail_cleanup;
2144 break;
2146 default:
2147 rv = soft_parse_common_attrs(&template[i],
2148 &object_type);
2149 if (rv != CKR_OK)
2150 goto fail_cleanup;
2151 break;
2154 } /* For */
2156 /* Allocate storage for Private Key Object. */
2157 pvk = calloc(1, sizeof (private_key_obj_t));
2158 if (pvk == NULL) {
2159 rv = CKR_HOST_MEMORY;
2160 goto fail_cleanup;
2163 new_object->object_class_u.private_key = pvk;
2164 new_object->class = CKO_PRIVATE_KEY;
2166 if ((mode == SOFT_CREATE_OBJ) && (keytype == (CK_KEY_TYPE)~0UL)) {
2167 rv = CKR_TEMPLATE_INCOMPLETE;
2168 goto fail_cleanup;
2171 if (mode == SOFT_GEN_KEY) {
2173 * The key type is not specified in the application's
2174 * template, so we use the implied key type based on
2175 * the mechanism.
2177 if (keytype == (CK_KEY_TYPE)~0UL) {
2178 keytype = key_type;
2181 /* If still unspecified, template is incomplete */
2182 if (keytype == (CK_KEY_TYPE)~0UL) {
2183 rv = CKR_TEMPLATE_INCOMPLETE;
2184 goto fail_cleanup;
2188 * The key type specified in the template does not
2189 * match the implied key type based on the mechanism.
2191 if (keytype != key_type) {
2192 rv = CKR_TEMPLATE_INCONSISTENT;
2193 goto fail_cleanup;
2197 if (mode == SOFT_UNWRAP_KEY) {
2199 * Note that, for mode SOFT_UNWRAP_KEY, key type is not
2200 * implied by the mechanism (key_type), so if it is not
2201 * specified from the attribute template (keytype), it is
2202 * incomplete.
2204 if (keytype == (CK_KEY_TYPE)~0UL) {
2205 rv = CKR_TEMPLATE_INCOMPLETE;
2206 goto fail_cleanup;
2210 new_object->key_type = keytype;
2212 /* Supported key types of the Private Key Object */
2213 switch (keytype) {
2214 case CKK_RSA:
2215 if (isPrime || isSubprime || isBase || isValue ||
2216 isValueBits) {
2217 rv = CKR_TEMPLATE_INCONSISTENT;
2218 goto fail_cleanup;
2221 if (mode == SOFT_GEN_KEY || mode == SOFT_UNWRAP_KEY) {
2222 if (isModulus || isPubExpo || isPriExpo || isPrime1 ||
2223 isPrime2 || isExpo1 || isExpo2 || isCoef) {
2224 rv = CKR_TEMPLATE_INCONSISTENT;
2225 goto fail_cleanup;
2226 } else
2227 break;
2230 if (isModulus && isPriExpo) {
2232 * Copy big integer attribute value to the
2233 * designated place in the Private Key object.
2235 copy_bigint_attr(&modulus, KEY_PRI_RSA_MOD(pvk));
2237 copy_bigint_attr(&priexpo, KEY_PRI_RSA_PRIEXPO(pvk));
2238 } else {
2239 rv = CKR_TEMPLATE_INCOMPLETE;
2240 goto fail_cleanup;
2243 /* The following attributes are optional. */
2244 if (isPubExpo) {
2245 copy_bigint_attr(&pubexpo, KEY_PRI_RSA_PUBEXPO(pvk));
2248 if (isPrime1) {
2249 copy_bigint_attr(&prime1, KEY_PRI_RSA_PRIME1(pvk));
2252 if (isPrime2) {
2253 copy_bigint_attr(&prime2, KEY_PRI_RSA_PRIME2(pvk));
2256 if (isExpo1) {
2257 copy_bigint_attr(&expo1, KEY_PRI_RSA_EXPO1(pvk));
2260 if (isExpo2) {
2261 copy_bigint_attr(&expo2, KEY_PRI_RSA_EXPO2(pvk));
2264 if (isCoef) {
2265 copy_bigint_attr(&coef, KEY_PRI_RSA_COEF(pvk));
2267 break;
2269 case CKK_DSA:
2270 if (isModulus || isPubExpo || isPriExpo || isPrime1 ||
2271 isPrime2 || isExpo1 || isExpo2 || isCoef ||
2272 isValueBits) {
2273 rv = CKR_TEMPLATE_INCONSISTENT;
2274 goto fail_cleanup;
2277 if (mode == SOFT_GEN_KEY || mode == SOFT_UNWRAP_KEY) {
2278 if (isPrime || isSubprime || isBase || isValue) {
2279 rv = CKR_TEMPLATE_INCONSISTENT;
2280 goto fail_cleanup;
2281 } else
2282 break;
2285 if (isPrime && isSubprime && isBase && isValue) {
2287 * The private value x must be less than subprime q.
2288 * Size for big_init is in BIG_CHUNK_TYPE words.
2290 if (big_init(&x,
2291 CHARLEN2BIGNUMLEN(value.big_value_len))
2292 != BIG_OK) {
2293 rv = CKR_HOST_MEMORY;
2294 goto fail_cleanup;
2296 if (big_init(&q,
2297 CHARLEN2BIGNUMLEN(subprime.big_value_len))
2298 != BIG_OK) {
2299 rv = CKR_HOST_MEMORY;
2300 goto fail_cleanup;
2302 bytestring2bignum(&x, value.big_value,
2303 value.big_value_len);
2304 bytestring2bignum(&q, subprime.big_value,
2305 subprime.big_value_len);
2307 if (big_cmp_abs(&x, &q) > 0) {
2308 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2309 goto fail_cleanup;
2312 copy_bigint_attr(&prime, KEY_PRI_DSA_PRIME(pvk));
2314 copy_bigint_attr(&subprime, KEY_PRI_DSA_SUBPRIME(pvk));
2316 copy_bigint_attr(&base, KEY_PRI_DSA_BASE(pvk));
2318 copy_bigint_attr(&value, KEY_PRI_DSA_VALUE(pvk));
2319 } else {
2320 rv = CKR_TEMPLATE_INCOMPLETE;
2321 goto fail_cleanup;
2323 break;
2325 case CKK_DH:
2326 if (isModulus || isPubExpo || isPriExpo || isPrime1 ||
2327 isPrime2 || isExpo1 || isExpo2 || isCoef ||
2328 isSubprime) {
2329 rv = CKR_TEMPLATE_INCONSISTENT;
2330 goto fail_cleanup;
2333 /* CKA_VALUE_BITS is for key gen but not unwrap */
2334 if (mode == SOFT_GEN_KEY)
2335 KEY_PRI_DH_VAL_BITS(pvk) = (isValueBits) ?
2336 value_bits : 0;
2337 else if (mode == SOFT_UNWRAP_KEY) {
2338 if (isValueBits) {
2339 rv = CKR_TEMPLATE_INCONSISTENT;
2340 goto fail_cleanup;
2344 if (mode == SOFT_GEN_KEY || mode == SOFT_UNWRAP_KEY) {
2345 if (isPrime || isBase || isValue) {
2346 rv = CKR_TEMPLATE_INCONSISTENT;
2347 goto fail_cleanup;
2348 } else
2349 break;
2352 if (isValueBits) {
2353 rv = CKR_TEMPLATE_INCONSISTENT;
2354 goto fail_cleanup;
2357 if (isPrime && isBase && isValue) {
2358 copy_bigint_attr(&prime, KEY_PRI_DH_PRIME(pvk));
2360 copy_bigint_attr(&base, KEY_PRI_DH_BASE(pvk));
2362 copy_bigint_attr(&value, KEY_PRI_DH_VALUE(pvk));
2363 } else {
2364 rv = CKR_TEMPLATE_INCOMPLETE;
2365 goto fail_cleanup;
2367 break;
2369 case CKK_X9_42_DH:
2370 if (isModulus || isPubExpo || isPriExpo || isPrime1 ||
2371 isPrime2 || isExpo1 || isExpo2 || isCoef ||
2372 isValueBits) {
2373 rv = CKR_TEMPLATE_INCONSISTENT;
2374 goto fail_cleanup;
2377 if (mode == SOFT_GEN_KEY || mode == SOFT_UNWRAP_KEY) {
2378 if (isPrime || isSubprime || isBase || isValue) {
2379 rv = CKR_TEMPLATE_INCONSISTENT;
2380 goto fail_cleanup;
2381 } else
2382 break;
2385 if (isPrime && isSubprime && isBase && isValue) {
2386 copy_bigint_attr(&prime, KEY_PRI_DH942_PRIME(pvk));
2388 copy_bigint_attr(&base, KEY_PRI_DH942_BASE(pvk));
2390 copy_bigint_attr(&subprime,
2391 KEY_PRI_DH942_SUBPRIME(pvk));
2393 copy_bigint_attr(&value, KEY_PRI_DH942_VALUE(pvk));
2394 } else {
2395 rv = CKR_TEMPLATE_INCOMPLETE;
2396 goto fail_cleanup;
2398 break;
2400 case CKK_EC:
2401 if (isModulus || isPubExpo || isPrime ||
2402 isPrime1 || isPrime2 || isExpo1 || isExpo2 || isCoef ||
2403 isValueBits || isBase) {
2404 rv = CKR_TEMPLATE_INCONSISTENT;
2405 goto fail_cleanup;
2407 } else if (isECParam) {
2408 rv = soft_add_extra_attr(&param_tmp, new_object);
2409 if (rv != CKR_OK)
2410 goto fail_cleanup;
2411 string_attr_cleanup(&param_tmp);
2413 if (isValue) {
2414 copy_bigint_attr(&value, KEY_PRI_EC_VALUE(pvk));
2416 break;
2418 default:
2419 rv = CKR_TEMPLATE_INCONSISTENT;
2420 goto fail_cleanup;
2423 /* Set up object. */
2424 new_object->object_type = object_type;
2425 new_object->bool_attr_mask = attr_mask;
2426 if (isLabel) {
2427 rv = soft_add_extra_attr(&string_tmp, new_object);
2428 if (rv != CKR_OK)
2429 goto fail_cleanup;
2430 string_attr_cleanup(&string_tmp);
2432 big_finish(&x);
2433 big_finish(&q);
2435 return (rv);
2437 fail_cleanup:
2439 * cleanup the storage allocated to the local variables.
2441 bigint_attr_cleanup(&modulus);
2442 bigint_attr_cleanup(&priexpo);
2443 bigint_attr_cleanup(&prime);
2444 bigint_attr_cleanup(&subprime);
2445 bigint_attr_cleanup(&base);
2446 bigint_attr_cleanup(&value);
2447 bigint_attr_cleanup(&pubexpo);
2448 bigint_attr_cleanup(&prime1);
2449 bigint_attr_cleanup(&prime2);
2450 bigint_attr_cleanup(&expo1);
2451 bigint_attr_cleanup(&expo2);
2452 bigint_attr_cleanup(&coef);
2453 string_attr_cleanup(&string_tmp);
2454 string_attr_cleanup(&param_tmp);
2455 big_finish(&x);
2456 big_finish(&q);
2459 * cleanup the storage allocated inside the object itself.
2461 soft_cleanup_object(new_object);
2463 return (rv);
2468 * Build a Secret Key Object.
2470 * - Parse the object's template, and when an error is detected such as
2471 * invalid attribute type, invalid attribute value, etc., return
2472 * with appropriate return value.
2473 * - Set up attribute mask field in the object for the supplied common
2474 * attributes that have boolean type.
2475 * - Build the attribute_info struct to hold the value of each supplied
2476 * attribute that has byte array type. Link attribute_info structs
2477 * together to form the extra attribute list of the object.
2478 * - Allocate storage for the Secret Key object.
2479 * - Build the Secret Key object. Allocate storage to hold the big integer
2480 * value for the attribute CKA_VALUE that is required for all the key
2481 * types supported by secret key object.
2482 * This function is called internally with mode = SOFT_CREATE_OBJ_INT.
2485 CK_RV
2486 soft_build_secret_key_object(CK_ATTRIBUTE_PTR template, CK_ULONG ulAttrNum,
2487 soft_object_t *new_object, CK_ULONG mode, CK_ULONG key_len,
2488 CK_KEY_TYPE key_type)
2491 ulong_t i;
2492 CK_KEY_TYPE keytype = (CK_KEY_TYPE)~0UL;
2493 uint64_t attr_mask = SECRET_KEY_DEFAULT;
2494 CK_RV rv = CKR_OK;
2495 int isLabel = 0;
2496 /* Must set flags if mode != SOFT_UNWRAP_KEY, else must not set */
2497 int isValue = 0;
2498 /* Must not set flags if mode != SOFT_UNWRAP_KEY, else optional */
2499 int isValueLen = 0;
2501 CK_ATTRIBUTE string_tmp;
2503 secret_key_obj_t *sck;
2504 uchar_t object_type = 0;
2506 string_tmp.pValue = NULL;
2508 /* Allocate storage for Secret Key Object. */
2509 sck = calloc(1, sizeof (secret_key_obj_t));
2510 if (sck == NULL) {
2511 rv = CKR_HOST_MEMORY;
2512 goto fail_cleanup;
2515 new_object->object_class_u.secret_key = sck;
2516 new_object->class = CKO_SECRET_KEY;
2518 for (i = 0; i < ulAttrNum; i++) {
2520 /* Secret Key Object Attributes */
2521 switch (template[i].type) {
2523 /* common key attributes */
2524 case CKA_KEY_TYPE:
2525 keytype = *((CK_KEY_TYPE*)template[i].pValue);
2526 break;
2528 case CKA_ID:
2529 case CKA_START_DATE:
2530 case CKA_END_DATE:
2532 * Allocate storage to hold the attribute
2533 * value with byte array type, and add it to
2534 * the extra attribute list of the object.
2536 rv = soft_add_extra_attr(&template[i],
2537 new_object);
2538 if (rv != CKR_OK) {
2539 goto fail_cleanup;
2541 break;
2544 * The following key related attribute types must
2545 * not be specified by C_CreateObject and C_GenerateKey.
2547 case CKA_LOCAL:
2548 case CKA_KEY_GEN_MECHANISM:
2549 case CKA_ALWAYS_SENSITIVE:
2550 case CKA_NEVER_EXTRACTABLE:
2551 rv = CKR_TEMPLATE_INCONSISTENT;
2552 goto fail_cleanup;
2554 /* Key related boolean attributes */
2555 case CKA_DERIVE:
2556 if (*(CK_BBOOL *)template[i].pValue)
2557 attr_mask |= DERIVE_BOOL_ON;
2558 break;
2560 case CKA_SENSITIVE:
2561 if (*(CK_BBOOL *)template[i].pValue)
2562 attr_mask |= SENSITIVE_BOOL_ON;
2563 break;
2565 case CKA_ENCRYPT:
2566 if (*(CK_BBOOL *)template[i].pValue)
2567 attr_mask |= ENCRYPT_BOOL_ON;
2568 else
2569 attr_mask &= ~ENCRYPT_BOOL_ON;
2570 break;
2572 case CKA_DECRYPT:
2573 if (*(CK_BBOOL *)template[i].pValue)
2574 attr_mask |= DECRYPT_BOOL_ON;
2575 else
2576 attr_mask &= ~DECRYPT_BOOL_ON;
2577 break;
2579 case CKA_SIGN:
2580 if (*(CK_BBOOL *)template[i].pValue)
2581 attr_mask |= SIGN_BOOL_ON;
2582 else
2583 attr_mask &= ~SIGN_BOOL_ON;
2584 break;
2586 case CKA_VERIFY:
2587 if (*(CK_BBOOL *)template[i].pValue)
2588 attr_mask |= VERIFY_BOOL_ON;
2589 else
2590 attr_mask &= ~VERIFY_BOOL_ON;
2591 break;
2593 case CKA_WRAP:
2594 if (*(CK_BBOOL *)template[i].pValue)
2595 attr_mask |= WRAP_BOOL_ON;
2596 else
2597 attr_mask &= ~WRAP_BOOL_ON;
2598 break;
2600 case CKA_UNWRAP:
2601 if (*(CK_BBOOL *)template[i].pValue)
2602 attr_mask |= UNWRAP_BOOL_ON;
2603 else
2604 attr_mask &= ~UNWRAP_BOOL_ON;
2605 break;
2607 case CKA_EXTRACTABLE:
2608 if (*(CK_BBOOL *)template[i].pValue)
2609 attr_mask |= EXTRACTABLE_BOOL_ON;
2610 else
2611 attr_mask &= ~EXTRACTABLE_BOOL_ON;
2612 break;
2614 case CKA_MODIFIABLE:
2615 if ((*(CK_BBOOL *)template[i].pValue) == B_FALSE)
2616 attr_mask |= NOT_MODIFIABLE_BOOL_ON;
2617 break;
2619 case CKA_VALUE:
2620 isValue = 1;
2621 if (mode == SOFT_CREATE_OBJ) {
2622 if ((template[i].ulValueLen == 0) ||
2623 (template[i].pValue == NULL)) {
2624 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2625 goto fail_cleanup;
2630 * Copyin attribute from template
2631 * to a local variable.
2633 rv = get_bigint_attr_from_template((biginteger_t *)sck,
2634 &template[i]);
2635 if (rv != CKR_OK)
2636 goto fail_cleanup;
2637 break;
2639 case CKA_VALUE_LEN:
2640 isValueLen = 1;
2641 rv = get_ulong_attr_from_template(&sck->sk_value_len,
2642 &template[i]);
2643 if (rv != CKR_OK)
2644 goto fail_cleanup;
2645 break;
2647 case CKA_LABEL:
2648 isLabel = 1;
2649 rv = get_string_from_template(&string_tmp,
2650 &template[i]);
2651 if (rv != CKR_OK)
2652 goto fail_cleanup;
2653 break;
2655 default:
2656 rv = soft_parse_common_attrs(&template[i],
2657 &object_type);
2658 if (rv != CKR_OK)
2659 goto fail_cleanup;
2660 break;
2663 } /* For */
2665 switch (mode) {
2666 case SOFT_CREATE_OBJ:
2667 case SOFT_CREATE_OBJ_INT:
2668 case SOFT_DERIVE_KEY_DH:
2670 * The key type must be specified in the application's
2671 * template. Otherwise, returns error.
2673 if (keytype == (CK_KEY_TYPE)~0UL) {
2674 rv = CKR_TEMPLATE_INCOMPLETE;
2675 goto fail_cleanup;
2677 break;
2679 case SOFT_GEN_KEY:
2680 if (keytype == (CK_KEY_TYPE)~0UL) {
2682 * The key type is not specified in the application's
2683 * template, so we use the implied key type based on
2684 * the mechanism.
2686 keytype = key_type;
2687 } else {
2688 if (keytype != key_type) {
2690 * The key type specified in the template
2691 * does not match the implied key type based
2692 * on the mechanism.
2694 rv = CKR_TEMPLATE_INCONSISTENT;
2695 goto fail_cleanup;
2700 * If a key_len is passed as a parameter, it has to
2701 * match the one found in the template.
2703 if (key_len > 0) {
2704 if (isValueLen && sck->sk_value_len != key_len) {
2705 rv = CKR_TEMPLATE_INCONSISTENT;
2706 goto fail_cleanup;
2708 isValueLen = 1;
2709 sck->sk_value_len = key_len;
2711 break;
2713 case SOFT_UNWRAP_KEY:
2715 * Note that, for mode SOFT_UNWRAP_KEY, key type is not
2716 * implied by the mechanism (key_type), so if it is not
2717 * specified from the attribute template (keytype), it is
2718 * incomplete.
2720 if (keytype == (CK_KEY_TYPE)~0UL) {
2721 rv = CKR_TEMPLATE_INCOMPLETE;
2722 goto fail_cleanup;
2724 break;
2726 case SOFT_DERIVE_KEY_OTHER:
2728 * For CKM_MD5_KEY_DERIVATION & CKM_SHA1_KEY_DERIVATION, the
2729 * key type is optional.
2731 if (keytype == (CK_KEY_TYPE)~0UL) {
2732 keytype = key_type;
2734 break;
2737 switch (mode) {
2738 case SOFT_CREATE_OBJ:
2739 case SOFT_CREATE_OBJ_INT:
2740 switch (keytype) {
2741 case CKK_RC4:
2742 if (!isValue) {
2743 rv = CKR_TEMPLATE_INCOMPLETE;
2744 goto fail_cleanup;
2746 if ((sck->sk_value_len < ARCFOUR_MIN_KEY_BYTES) ||
2747 (sck->sk_value_len > ARCFOUR_MAX_KEY_BYTES)) {
2748 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2749 goto fail_cleanup;
2751 break;
2753 case CKK_GENERIC_SECRET:
2754 if (!isValue) {
2755 rv = CKR_TEMPLATE_INCOMPLETE;
2756 goto fail_cleanup;
2758 break;
2760 case CKK_AES:
2761 if (!isValue) {
2762 rv = CKR_TEMPLATE_INCOMPLETE;
2763 goto fail_cleanup;
2765 if ((sck->sk_value_len != AES_MIN_KEY_BYTES) &&
2766 (sck->sk_value_len != AES_192_KEY_BYTES) &&
2767 (sck->sk_value_len != AES_MAX_KEY_BYTES)) {
2768 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2769 goto fail_cleanup;
2771 break;
2773 case CKK_BLOWFISH:
2774 if (!isValue) {
2775 rv = CKR_TEMPLATE_INCOMPLETE;
2776 goto fail_cleanup;
2778 if ((sck->sk_value_len < BLOWFISH_MINBYTES) ||
2779 (sck->sk_value_len > BLOWFISH_MAXBYTES)) {
2780 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2781 goto fail_cleanup;
2784 break;
2786 case CKK_DES:
2787 if (!isValue) {
2788 rv = CKR_TEMPLATE_INCOMPLETE;
2789 goto fail_cleanup;
2791 if (sck->sk_value_len != DES_KEYSIZE) {
2792 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2793 goto fail_cleanup;
2795 break;
2797 case CKK_DES2:
2798 if (!isValue) {
2799 rv = CKR_TEMPLATE_INCOMPLETE;
2800 goto fail_cleanup;
2802 if (sck->sk_value_len != DES2_KEYSIZE) {
2803 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2804 goto fail_cleanup;
2806 break;
2808 case CKK_DES3:
2809 if (!isValue) {
2810 rv = CKR_TEMPLATE_INCOMPLETE;
2811 goto fail_cleanup;
2813 if (sck->sk_value_len != DES3_KEYSIZE) {
2814 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2815 goto fail_cleanup;
2817 break;
2819 default:
2820 rv = CKR_TEMPLATE_INCONSISTENT;
2821 goto fail_cleanup;
2824 if (isValueLen) {
2826 * Templates for internal object creation come from
2827 * applications calls to C_DeriveKey(), for which it
2828 * is OKey to pass a CKA_VALUE_LEN attribute, as
2829 * long as it does not conflict with the length of the
2830 * CKA_VALUE attribute.
2832 if ((mode != SOFT_CREATE_OBJ_INT) ||
2833 ((key_len > 0) && sck->sk_value_len != key_len)) {
2834 rv = CKR_TEMPLATE_INCONSISTENT;
2835 goto fail_cleanup;
2838 break;
2840 case SOFT_GEN_KEY:
2841 /* CKA_VALUE must not be specified */
2842 if (isValue) {
2843 rv = CKR_TEMPLATE_INCONSISTENT;
2844 goto fail_cleanup;
2847 switch (keytype) {
2849 * CKA_VALUE_LEN must be specified by C_GenerateKey
2850 * if mech is CKK_RC4, CKK_AES, CKK_GENERIC_SECRET.
2852 case CKK_RC4:
2853 if (!isValueLen) {
2854 rv = CKR_TEMPLATE_INCOMPLETE;
2855 goto fail_cleanup;
2858 if ((sck->sk_value_len < ARCFOUR_MIN_KEY_BYTES) ||
2859 (sck->sk_value_len > ARCFOUR_MAX_KEY_BYTES)) {
2860 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2861 goto fail_cleanup;
2863 break;
2865 case CKK_GENERIC_SECRET:
2866 /* arbitrary key length - no length checking */
2867 if (!isValueLen) {
2868 rv = CKR_TEMPLATE_INCOMPLETE;
2869 goto fail_cleanup;
2871 break;
2873 case CKK_AES:
2874 if (!isValueLen) {
2875 rv = CKR_TEMPLATE_INCOMPLETE;
2876 goto fail_cleanup;
2879 if ((sck->sk_value_len != AES_MIN_KEY_BYTES) &&
2880 (sck->sk_value_len != AES_192_KEY_BYTES) &&
2881 (sck->sk_value_len != AES_MAX_KEY_BYTES)) {
2882 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2883 goto fail_cleanup;
2886 break;
2888 case CKK_BLOWFISH:
2889 if (!isValueLen) {
2890 rv = CKR_TEMPLATE_INCOMPLETE;
2891 goto fail_cleanup;
2893 if ((sck->sk_value_len < BLOWFISH_MINBYTES) ||
2894 (sck->sk_value_len > BLOWFISH_MAXBYTES)) {
2895 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2896 goto fail_cleanup;
2899 break;
2901 case CKK_DES:
2902 case CKK_DES2:
2903 case CKK_DES3:
2904 /* CKA_VALUE_LEN attribute does not apply to DES<n> */
2905 if (isValueLen) {
2906 rv = CKR_TEMPLATE_INCONSISTENT;
2907 goto fail_cleanup;
2909 break;
2911 default:
2912 rv = CKR_TEMPLATE_INCONSISTENT;
2913 goto fail_cleanup;
2915 break;
2917 case SOFT_UNWRAP_KEY:
2919 * According to v2.11 of PKCS#11 spec, neither CKA_VALUE nor
2920 * CKA_VALUE_LEN can be be specified; however v2.20 has this
2921 * restriction removed, perhaps because it makes it hard to
2922 * determine variable-length key sizes. This case statement
2923 * complied with v2.20.
2925 if (isValue) {
2926 rv = CKR_TEMPLATE_INCONSISTENT;
2927 goto fail_cleanup;
2930 switch (keytype) {
2932 * CKA_VALUE_LEN is optional
2933 * if key is CKK_RC4, CKK_AES, CKK_GENERIC_SECRET
2934 * and the unwrapping mech is *_CBC_PAD.
2936 * CKA_VALUE_LEN is required
2937 * if key is CKK_RC4, CKK_AES, CKK_GENERIC_SECRET
2938 * and the unwrapping mech is *_ECB or *_CBC.
2940 * since mech is not known at this point, CKA_VALUE_LEN is
2941 * treated as optional and the caller needs to enforce it.
2943 case CKK_RC4:
2944 if (isValueLen) {
2945 if ((sck->sk_value_len <
2946 ARCFOUR_MIN_KEY_BYTES) ||
2947 (sck->sk_value_len >
2948 ARCFOUR_MAX_KEY_BYTES)) {
2949 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2950 goto fail_cleanup;
2953 break;
2955 case CKK_GENERIC_SECRET:
2956 /* arbitrary key length - no length checking */
2957 break;
2959 case CKK_AES:
2960 if (isValueLen) {
2961 if ((sck->sk_value_len != AES_MIN_KEY_BYTES) &&
2962 (sck->sk_value_len != AES_192_KEY_BYTES) &&
2963 (sck->sk_value_len != AES_MAX_KEY_BYTES)) {
2964 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2965 goto fail_cleanup;
2968 break;
2970 case CKK_BLOWFISH:
2971 if (isValueLen &&
2972 ((sck->sk_value_len < BLOWFISH_MINBYTES) ||
2973 (sck->sk_value_len > BLOWFISH_MAXBYTES))) {
2974 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2975 goto fail_cleanup;
2977 break;
2979 case CKK_DES:
2980 case CKK_DES2:
2981 case CKK_DES3:
2982 /* CKA_VALUE_LEN attribute does not apply to DES<n> */
2983 if (isValueLen) {
2984 rv = CKR_TEMPLATE_INCONSISTENT;
2985 goto fail_cleanup;
2987 break;
2989 default:
2990 rv = CKR_TEMPLATE_INCONSISTENT;
2991 goto fail_cleanup;
2993 break;
2995 case SOFT_DERIVE_KEY_DH:
2996 /* CKA_VALUE must not be specified */
2997 if (isValue) {
2998 rv = CKR_TEMPLATE_INCONSISTENT;
2999 goto fail_cleanup;
3002 switch (keytype) {
3004 * CKA_VALUE_LEN is optional
3005 * if mech is CKK_RC4, CKK_AES, CKK_GENERIC_SECRET.
3007 case CKK_RC4:
3008 if (isValueLen) {
3009 if ((sck->sk_value_len <
3010 ARCFOUR_MIN_KEY_BYTES) ||
3011 (sck->sk_value_len >
3012 ARCFOUR_MAX_KEY_BYTES)) {
3013 rv = CKR_ATTRIBUTE_VALUE_INVALID;
3014 goto fail_cleanup;
3017 break;
3019 case CKK_GENERIC_SECRET:
3020 /* arbitrary key length - no length checking */
3021 break;
3023 case CKK_AES:
3024 if (isValueLen) {
3025 if ((sck->sk_value_len != AES_MIN_KEY_BYTES) &&
3026 (sck->sk_value_len != AES_192_KEY_BYTES) &&
3027 (sck->sk_value_len != AES_MAX_KEY_BYTES)) {
3028 rv = CKR_ATTRIBUTE_VALUE_INVALID;
3029 goto fail_cleanup;
3033 break;
3035 case CKK_BLOWFISH:
3036 if (isValueLen &&
3037 ((sck->sk_value_len < BLOWFISH_MINBYTES) ||
3038 (sck->sk_value_len > BLOWFISH_MAXBYTES))) {
3039 rv = CKR_ATTRIBUTE_VALUE_INVALID;
3040 goto fail_cleanup;
3042 break;
3044 case CKK_DES:
3045 case CKK_DES2:
3046 case CKK_DES3:
3047 /* CKA_VALUE_LEN attribute does not apply to DES<n> */
3048 if (isValueLen) {
3049 rv = CKR_TEMPLATE_INCONSISTENT;
3050 goto fail_cleanup;
3052 break;
3054 default:
3055 rv = CKR_TEMPLATE_INCONSISTENT;
3056 goto fail_cleanup;
3058 break;
3060 case SOFT_DERIVE_KEY_OTHER:
3061 /* CKA_VALUE must not be specified */
3062 if (isValue) {
3063 rv = CKR_TEMPLATE_INCONSISTENT;
3064 goto fail_cleanup;
3067 switch (keytype) {
3069 * CKA_VALUE_LEN is an optional attribute for
3070 * CKM_SHA1_KEY_DERIVATION and CKM_MD5_KEY_DERIVATION
3071 * if mech is CKK_RC4, CKK_AES, CKK_GENERIC_SECRET.
3073 case CKK_RC4:
3074 case CKK_GENERIC_SECRET:
3075 case CKK_AES:
3076 case CKK_BLOWFISH:
3078 * No need to check key length value here, it will be
3079 * validated later in soft_key_derive_check_length().
3081 break;
3083 case CKK_DES:
3084 case CKK_DES2:
3085 case CKK_DES3:
3086 /* CKA_VALUE_LEN attribute does not apply to DES<n> */
3087 if (isValueLen) {
3088 rv = CKR_TEMPLATE_INCONSISTENT;
3089 goto fail_cleanup;
3091 break;
3093 default:
3094 rv = CKR_TEMPLATE_INCONSISTENT;
3095 goto fail_cleanup;
3097 break;
3100 /* Set up object. */
3101 new_object->key_type = keytype;
3102 new_object->object_type = object_type;
3103 new_object->bool_attr_mask = attr_mask;
3104 if (isLabel) {
3105 rv = soft_add_extra_attr(&string_tmp, new_object);
3106 if (rv != CKR_OK)
3107 goto fail_cleanup;
3108 string_attr_cleanup(&string_tmp);
3110 return (rv);
3112 fail_cleanup:
3114 * cleanup the storage allocated to the local variables.
3116 bigint_attr_cleanup((biginteger_t *)sck);
3117 string_attr_cleanup(&string_tmp);
3120 * cleanup the storage allocated inside the object itself.
3122 soft_cleanup_object(new_object);
3124 return (rv);
3129 * Build a Domain Parameter Object.
3131 * - Parse the object's template, and when an error is detected such as
3132 * invalid attribute type, invalid attribute value, etc., return
3133 * with appropriate return value.
3134 * - Allocate storage for the Domain Parameter object.
3135 * - Build the Domain Parameter object according to the key type. Allocate
3136 * storage to hold the big integer value for the supplied attributes
3137 * that are required for a certain key type.
3140 CK_RV
3141 soft_build_domain_parameters_object(CK_ATTRIBUTE_PTR template,
3142 CK_ULONG ulAttrNum, soft_object_t *new_object)
3145 ulong_t i;
3146 CK_KEY_TYPE keytype = (CK_KEY_TYPE)~0UL;
3147 CK_RV rv = CKR_OK;
3148 int isLabel = 0;
3149 /* Must set flags */
3150 int isPrime = 0;
3151 int isSubprime = 0;
3152 int isBase = 0;
3153 /* Must not set flags */
3154 int isPrimeBits = 0;
3155 int isSubPrimeBits = 0;
3157 biginteger_t prime;
3158 biginteger_t subprime;
3159 biginteger_t base;
3160 CK_ATTRIBUTE string_tmp;
3162 domain_obj_t *dom;
3163 uchar_t object_type = 0;
3165 /* prevent bigint_attr_cleanup from freeing invalid attr value */
3166 (void) memset(&prime, 0x0, sizeof (biginteger_t));
3167 (void) memset(&subprime, 0x0, sizeof (biginteger_t));
3168 (void) memset(&base, 0x0, sizeof (biginteger_t));
3169 string_tmp.pValue = NULL;
3171 for (i = 0; i < ulAttrNum; i++) {
3173 /* Domain Parameters Object Attributes */
3174 switch (template[i].type) {
3176 /* common domain parameter attribute */
3177 case CKA_KEY_TYPE:
3178 keytype = *((CK_KEY_TYPE*)template[i].pValue);
3179 break;
3182 * The following common domain parameter attribute
3183 * must not be specified by C_CreateObject.
3185 case CKA_LOCAL:
3186 rv = CKR_TEMPLATE_INCONSISTENT;
3187 goto fail_cleanup;
3190 * The following domain parameter attributes must be
3191 * specified according to the key type by
3192 * C_CreateObject.
3194 case CKA_PRIME:
3195 isPrime = 1;
3197 * Copyin big integer attribute from template
3198 * to a local variable.
3200 rv = get_bigint_attr_from_template(&prime,
3201 &template[i]);
3202 if (rv != CKR_OK)
3203 goto fail_cleanup;
3204 break;
3206 case CKA_SUBPRIME:
3207 isSubprime = 1;
3208 rv = get_bigint_attr_from_template(&subprime,
3209 &template[i]);
3210 if (rv != CKR_OK)
3211 goto fail_cleanup;
3212 break;
3214 case CKA_BASE:
3215 isBase = 1;
3216 rv = get_bigint_attr_from_template(&base,
3217 &template[i]);
3218 if (rv != CKR_OK)
3219 goto fail_cleanup;
3220 break;
3222 case CKA_PRIME_BITS:
3223 isPrimeBits = 1;
3224 break;
3226 case CKA_SUB_PRIME_BITS:
3227 isSubPrimeBits = 1;
3228 break;
3230 case CKA_LABEL:
3231 isLabel = 1;
3232 rv = get_string_from_template(&string_tmp,
3233 &template[i]);
3234 if (rv != CKR_OK)
3235 goto fail_cleanup;
3236 break;
3238 default:
3239 rv = soft_parse_common_attrs(&template[i],
3240 &object_type);
3241 if (rv != CKR_OK)
3242 goto fail_cleanup;
3243 break;
3246 } /* For */
3248 /* Allocate storage for Domain Parameters Object. */
3249 dom = calloc(1, sizeof (domain_obj_t));
3250 if (dom == NULL) {
3251 rv = CKR_HOST_MEMORY;
3252 goto fail_cleanup;
3255 new_object->object_class_u.domain = dom;
3256 new_object->class = CKO_DOMAIN_PARAMETERS;
3258 if (keytype == (CK_KEY_TYPE)~0UL) {
3259 rv = CKR_TEMPLATE_INCOMPLETE;
3260 goto fail_cleanup;
3263 new_object->key_type = keytype;
3265 /* Supported key types of the Domain Parameters Object */
3266 switch (keytype) {
3267 case CKK_DSA:
3268 if (isPrimeBits || isSubPrimeBits) {
3269 rv = CKR_TEMPLATE_INCONSISTENT;
3270 goto fail_cleanup;
3273 if (isPrime && isSubprime && isBase) {
3275 * Copy big integer attribute value to the
3276 * designated place in the domain parameter
3277 * object.
3279 copy_bigint_attr(&prime, KEY_DOM_DSA_PRIME(dom));
3281 copy_bigint_attr(&subprime, KEY_DOM_DSA_SUBPRIME(dom));
3283 copy_bigint_attr(&base, KEY_DOM_DSA_BASE(dom));
3284 } else {
3285 rv = CKR_TEMPLATE_INCOMPLETE;
3286 goto fail_cleanup;
3288 break;
3290 case CKK_DH:
3291 if (isPrimeBits || isSubprime || isSubPrimeBits) {
3292 rv = CKR_TEMPLATE_INCONSISTENT;
3293 goto fail_cleanup;
3296 if (isPrime && isBase) {
3297 copy_bigint_attr(&prime, KEY_DOM_DH_PRIME(dom));
3299 copy_bigint_attr(&base, KEY_DOM_DH_BASE(dom));
3300 } else {
3301 rv = CKR_TEMPLATE_INCOMPLETE;
3302 goto fail_cleanup;
3304 break;
3306 case CKK_X9_42_DH:
3307 if (isPrimeBits || isSubPrimeBits) {
3308 rv = CKR_TEMPLATE_INCONSISTENT;
3309 goto fail_cleanup;
3312 if (isPrime && isSubprime && isBase) {
3313 copy_bigint_attr(&prime, KEY_DOM_DH942_PRIME(dom));
3315 copy_bigint_attr(&base, KEY_DOM_DH942_BASE(dom));
3317 copy_bigint_attr(&subprime,
3318 KEY_DOM_DH942_SUBPRIME(dom));
3319 } else {
3320 rv = CKR_TEMPLATE_INCOMPLETE;
3321 goto fail_cleanup;
3323 break;
3325 default:
3326 rv = CKR_TEMPLATE_INCONSISTENT;
3327 goto fail_cleanup;
3330 new_object->object_type = object_type;
3332 if (isLabel) {
3333 rv = soft_add_extra_attr(&string_tmp, new_object);
3334 if (rv != CKR_OK)
3335 goto fail_cleanup;
3336 string_attr_cleanup(&string_tmp);
3339 return (rv);
3341 fail_cleanup:
3343 * cleanup the storage allocated to the local variables.
3345 bigint_attr_cleanup(&prime);
3346 bigint_attr_cleanup(&subprime);
3347 bigint_attr_cleanup(&base);
3348 string_attr_cleanup(&string_tmp);
3351 * cleanup the storage allocated inside the object itself.
3353 soft_cleanup_object(new_object);
3355 return (rv);
3359 * Build a Certificate Object
3361 * - Parse the object's template, and when an error is detected such as
3362 * invalid attribute type, invalid attribute value, etc., return
3363 * with appropriate return value.
3364 * - Allocate storage for the Certificate object
3366 static CK_RV
3367 soft_build_certificate_object(CK_ATTRIBUTE_PTR template,
3368 CK_ULONG ulAttrNum, soft_object_t *new_object,
3369 CK_CERTIFICATE_TYPE cert_type)
3371 uint64_t attr_mask = 0;
3372 CK_RV rv = CKR_OK;
3373 CK_ULONG i;
3374 int owner_set = 0;
3375 int value_set = 0;
3376 int subject_set = 0;
3377 certificate_obj_t *cert;
3378 /* certificate type defaults to the value given as a parameter */
3379 CK_CERTIFICATE_TYPE certtype = cert_type;
3380 CK_ATTRIBUTE string_tmp;
3381 int isLabel = 0;
3382 uchar_t object_type = 0;
3385 * Look for the certificate type attribute and do some
3386 * sanity checking before creating the structures.
3388 for (i = 0; i < ulAttrNum; i++) {
3389 /* Certificate Object Attributes */
3390 switch (template[i].type) {
3391 case CKA_CERTIFICATE_TYPE:
3392 certtype =
3393 *((CK_CERTIFICATE_TYPE*)template[i].pValue);
3394 break;
3395 case CKA_SUBJECT:
3396 subject_set = 1;
3397 break;
3398 case CKA_OWNER:
3399 owner_set = 1;
3400 break;
3401 case CKA_VALUE:
3402 value_set = 1;
3403 break;
3407 /* The certificate type MUST be specified */
3408 if (certtype != CKC_X_509 && certtype != CKC_X_509_ATTR_CERT)
3409 return (CKR_TEMPLATE_INCOMPLETE);
3412 * For X.509 certs, the CKA_SUBJECT and CKA_VALUE
3413 * must be present at creation time.
3415 if (certtype == CKC_X_509 &&
3416 (!subject_set || !value_set))
3417 return (CKR_TEMPLATE_INCOMPLETE);
3420 * For X.509 Attribute certs, the CKA_OWNER and CKA_VALUE
3421 * must be present at creation time.
3423 if (certtype == CKC_X_509_ATTR_CERT &&
3424 (!owner_set || !value_set))
3425 return (CKR_TEMPLATE_INCOMPLETE);
3427 string_tmp.pValue = NULL;
3428 cert = calloc(1, sizeof (certificate_obj_t));
3429 if (cert == NULL) {
3430 return (CKR_HOST_MEMORY);
3432 cert->certificate_type = certtype;
3434 for (i = 0; i < ulAttrNum; i++) {
3435 /* Certificate Object Attributes */
3436 switch (certtype) {
3437 case CKC_X_509:
3438 switch (template[i].type) {
3439 case CKA_SUBJECT:
3440 rv = get_cert_attr_from_template(
3441 &cert->cert_type_u.x509.subject,
3442 &template[i]);
3443 break;
3444 case CKA_VALUE:
3445 rv = get_cert_attr_from_template(
3446 &cert->cert_type_u.x509.value,
3447 &template[i]);
3448 break;
3449 case CKA_LABEL:
3450 isLabel = 1;
3451 rv = get_string_from_template(
3452 &string_tmp,
3453 &template[i]);
3454 if (rv != CKR_OK)
3455 goto fail_cleanup;
3456 break;
3457 case CKA_ID:
3458 case CKA_ISSUER:
3459 case CKA_SERIAL_NUMBER:
3460 rv = soft_add_extra_attr(&template[i],
3461 new_object);
3462 break;
3463 case CKA_MODIFIABLE:
3464 if ((*(CK_BBOOL *)template[i].pValue) ==
3465 B_FALSE)
3466 attr_mask |=
3467 NOT_MODIFIABLE_BOOL_ON;
3468 break;
3469 case CKA_CERTIFICATE_TYPE:
3470 break;
3471 default:
3472 rv = soft_parse_common_attrs(
3473 &template[i], &object_type);
3474 if (rv != CKR_OK)
3475 goto fail_cleanup;
3477 break;
3478 case CKC_X_509_ATTR_CERT:
3479 switch (template[i].type) {
3480 case CKA_OWNER:
3481 rv = get_cert_attr_from_template(
3482 &cert->cert_type_u.x509_attr.owner,
3483 &template[i]);
3484 break;
3485 case CKA_VALUE:
3486 rv = get_cert_attr_from_template(
3487 &cert->cert_type_u.x509_attr.value,
3488 &template[i]);
3489 break;
3490 case CKA_LABEL:
3491 isLabel = 1;
3492 rv = get_string_from_template(
3493 &string_tmp, &template[i]);
3494 if (rv != CKR_OK)
3495 goto fail_cleanup;
3496 break;
3497 case CKA_SERIAL_NUMBER:
3498 case CKA_AC_ISSUER:
3499 case CKA_ATTR_TYPES:
3500 rv = soft_add_extra_attr(&template[i],
3501 new_object);
3502 break;
3504 case CKA_MODIFIABLE:
3505 if ((*(CK_BBOOL *)template[i].pValue) ==
3506 B_FALSE)
3507 attr_mask |=
3508 NOT_MODIFIABLE_BOOL_ON;
3509 break;
3510 case CKA_CERTIFICATE_TYPE:
3511 break;
3512 default:
3513 rv = soft_parse_common_attrs(
3514 &template[i], &object_type);
3515 if (rv != CKR_OK)
3516 goto fail_cleanup;
3517 break;
3519 break;
3520 default:
3521 rv = CKR_TEMPLATE_INCOMPLETE;
3522 break;
3526 if (rv == CKR_OK) {
3527 new_object->object_class_u.certificate = cert;
3528 new_object->class = CKO_CERTIFICATE;
3529 new_object->object_type = object_type;
3530 new_object->cert_type = certtype;
3531 new_object->bool_attr_mask = attr_mask;
3532 if (isLabel) {
3533 rv = soft_add_extra_attr(&string_tmp, new_object);
3534 if (rv != CKR_OK)
3535 goto fail_cleanup;
3536 string_attr_cleanup(&string_tmp);
3540 fail_cleanup:
3541 if (rv != CKR_OK) {
3542 soft_cleanup_cert_object(new_object);
3544 return (rv);
3549 * Validate the attribute types in the object's template. Then,
3550 * call the appropriate build function according to the class of
3551 * the object specified in the template.
3553 * Note: The following classes of objects are supported:
3554 * - CKO_PUBLIC_KEY
3555 * - CKO_PRIVATE_KEY
3556 * - CKO_SECRET_KEY
3557 * - CKO_DOMAIN_PARAMETERS
3558 * - CKO_CERTIFICATE
3561 CK_RV
3562 soft_build_object(CK_ATTRIBUTE_PTR template, CK_ULONG ulAttrNum,
3563 soft_object_t *new_object)
3566 CK_OBJECT_CLASS class = (CK_OBJECT_CLASS)~0UL;
3567 CK_RV rv = CKR_OK;
3569 if (template == NULL) {
3570 return (CKR_ARGUMENTS_BAD);
3573 /* Validate the attribute type in the template. */
3574 rv = soft_validate_attr(template, ulAttrNum, &class);
3575 if (rv != CKR_OK)
3576 return (rv);
3578 * CKA_CLASS is a mandatory attribute for C_CreateObject
3580 if (class == (CK_OBJECT_CLASS)~0UL)
3581 return (CKR_TEMPLATE_INCOMPLETE);
3584 * Call the appropriate function based on the supported class
3585 * of the object.
3587 switch (class) {
3588 case CKO_PUBLIC_KEY:
3589 rv = soft_build_public_key_object(template, ulAttrNum,
3590 new_object, SOFT_CREATE_OBJ, (CK_KEY_TYPE)~0UL);
3591 break;
3593 case CKO_PRIVATE_KEY:
3594 rv = soft_build_private_key_object(template, ulAttrNum,
3595 new_object, SOFT_CREATE_OBJ, (CK_KEY_TYPE)~0UL);
3596 break;
3598 case CKO_SECRET_KEY:
3599 rv = soft_build_secret_key_object(template, ulAttrNum,
3600 new_object, SOFT_CREATE_OBJ, 0, (CK_KEY_TYPE)~0UL);
3601 break;
3603 case CKO_DOMAIN_PARAMETERS:
3604 rv = soft_build_domain_parameters_object(template, ulAttrNum,
3605 new_object);
3606 break;
3608 case CKO_CERTIFICATE:
3609 rv = soft_build_certificate_object(template, ulAttrNum,
3610 new_object, (CK_CERTIFICATE_TYPE)~0UL);
3611 break;
3613 case CKO_DATA:
3614 case CKO_HW_FEATURE:
3615 case CKO_VENDOR_DEFINED:
3616 default:
3617 return (CKR_ATTRIBUTE_VALUE_INVALID);
3620 return (rv);
3624 * Validate the attribute types in the object's template. Then,
3625 * call the appropriate build function according to the class of
3626 * the object specified in the template.
3629 CK_RV
3630 soft_build_key(CK_ATTRIBUTE_PTR template, CK_ULONG ulAttrNum,
3631 soft_object_t *new_object, CK_OBJECT_CLASS class, CK_KEY_TYPE key_type,
3632 CK_ULONG key_len, CK_ULONG mode)
3635 CK_RV rv = CKR_OK;
3636 CK_OBJECT_CLASS temp_class = (CK_OBJECT_CLASS)~0UL;
3638 /* Validate the attribute type in the template. */
3639 if ((template != NULL) && (ulAttrNum != 0)) {
3640 rv = soft_validate_attr(template, ulAttrNum, &temp_class);
3641 if (rv != CKR_OK)
3642 return (rv);
3646 * If either the class from the parameter list ("class") or
3647 * the class from the template ("temp_class") is not specified,
3648 * try to use the other one.
3650 if (temp_class == (CK_OBJECT_CLASS)~0UL) {
3651 temp_class = class;
3652 } else if (class == (CK_OBJECT_CLASS)~0UL) {
3653 class = temp_class;
3656 /* If object class is still not specified, template is incomplete. */
3657 if (class == (CK_OBJECT_CLASS)~0UL)
3658 return (CKR_TEMPLATE_INCOMPLETE);
3660 /* Class should match if specified in both parameters and template. */
3661 if (class != temp_class)
3662 return (CKR_TEMPLATE_INCONSISTENT);
3665 * Call the appropriate function based on the supported class
3666 * of the object.
3668 switch (class) {
3669 case CKO_PUBLIC_KEY:
3671 /* Unwrapping public keys is not supported. */
3672 if (mode == SOFT_UNWRAP_KEY) {
3673 rv = CKR_ATTRIBUTE_VALUE_INVALID;
3674 break;
3677 rv = soft_build_public_key_object(template, ulAttrNum,
3678 new_object, mode, key_type);
3679 break;
3681 case CKO_PRIVATE_KEY:
3683 rv = soft_build_private_key_object(template, ulAttrNum,
3684 new_object, mode, key_type);
3685 break;
3687 case CKO_SECRET_KEY:
3689 rv = soft_build_secret_key_object(template, ulAttrNum,
3690 new_object, mode, key_len, key_type);
3691 break;
3693 case CKO_DOMAIN_PARAMETERS:
3695 /* Unwrapping domain parameters is not supported. */
3696 if (mode == SOFT_UNWRAP_KEY) {
3697 rv = CKR_ATTRIBUTE_VALUE_INVALID;
3698 break;
3701 rv = soft_build_domain_parameters_object(template, ulAttrNum,
3702 new_object);
3703 break;
3705 case CKO_DATA:
3706 case CKO_CERTIFICATE:
3707 case CKO_HW_FEATURE:
3708 case CKO_VENDOR_DEFINED:
3709 default:
3710 return (CKR_ATTRIBUTE_VALUE_INVALID);
3713 return (rv);
3718 * Get the value of a requested attribute that is common to all supported
3719 * classes (i.e. public key, private key, secret key, domain parameters,
3720 * and certificate classes).
3722 CK_RV
3723 soft_get_common_attrs(soft_object_t *object_p, CK_ATTRIBUTE_PTR template,
3724 uchar_t object_type)
3727 CK_RV rv = CKR_OK;
3729 switch (template->type) {
3731 case CKA_CLASS:
3732 return (get_ulong_attr_from_object(object_p->class,
3733 template));
3735 /* default boolean attributes */
3736 case CKA_TOKEN:
3737 template->ulValueLen = sizeof (CK_BBOOL);
3738 if (template->pValue == NULL) {
3739 return (CKR_OK);
3741 if (object_type & TOKEN_OBJECT)
3742 *((CK_BBOOL *)template->pValue) = B_TRUE;
3743 else
3744 *((CK_BBOOL *)template->pValue) = B_FALSE;
3745 break;
3747 case CKA_PRIVATE:
3749 template->ulValueLen = sizeof (CK_BBOOL);
3750 if (template->pValue == NULL) {
3751 return (CKR_OK);
3753 if (object_type & PRIVATE_OBJECT)
3754 *((CK_BBOOL *)template->pValue) = B_TRUE;
3755 else
3756 *((CK_BBOOL *)template->pValue) = B_FALSE;
3757 break;
3759 case CKA_MODIFIABLE:
3760 template->ulValueLen = sizeof (CK_BBOOL);
3761 if (template->pValue == NULL) {
3762 return (CKR_OK);
3764 if ((object_p->bool_attr_mask) & NOT_MODIFIABLE_BOOL_ON)
3765 *((CK_BBOOL *)template->pValue) = B_FALSE;
3766 else
3767 *((CK_BBOOL *)template->pValue) = B_TRUE;
3768 break;
3770 case CKA_LABEL:
3771 return (get_extra_attr_from_object(object_p,
3772 template));
3774 default:
3776 * The specified attribute for the object is invalid.
3777 * (the object does not possess such an attribute.)
3779 template->ulValueLen = (CK_ULONG)-1;
3780 return (CKR_ATTRIBUTE_TYPE_INVALID);
3783 return (rv);
3787 * Get the value of a requested attribute that is common to all key objects
3788 * (i.e. public key, private key and secret key).
3790 CK_RV
3791 soft_get_common_key_attrs(soft_object_t *object_p, CK_ATTRIBUTE_PTR template)
3794 switch (template->type) {
3796 case CKA_KEY_TYPE:
3797 return (get_ulong_attr_from_object(object_p->key_type,
3798 template));
3800 case CKA_ID:
3801 case CKA_START_DATE:
3802 case CKA_END_DATE:
3804 * The above extra attributes have byte array type.
3806 return (get_extra_attr_from_object(object_p,
3807 template));
3809 /* Key related boolean attributes */
3810 case CKA_LOCAL:
3811 return (get_bool_attr_from_object(object_p,
3812 LOCAL_BOOL_ON, template));
3814 case CKA_DERIVE:
3815 return (get_bool_attr_from_object(object_p,
3816 DERIVE_BOOL_ON, template));
3818 case CKA_KEY_GEN_MECHANISM:
3819 return (get_ulong_attr_from_object(object_p->mechanism,
3820 template));
3822 default:
3823 return (CKR_ATTRIBUTE_TYPE_INVALID);
3828 * Get the value of a requested attribute of a Public Key Object.
3830 * Rule: All the attributes in the public key object can be revealed.
3832 CK_RV
3833 soft_get_public_key_attribute(soft_object_t *object_p,
3834 CK_ATTRIBUTE_PTR template)
3837 CK_RV rv = CKR_OK;
3838 CK_KEY_TYPE keytype = object_p->key_type;
3840 switch (template->type) {
3842 case CKA_SUBJECT:
3843 case CKA_EC_PARAMS:
3845 * The above extra attributes have byte array type.
3847 return (get_extra_attr_from_object(object_p,
3848 template));
3850 /* Key related boolean attributes */
3851 case CKA_ENCRYPT:
3852 return (get_bool_attr_from_object(object_p,
3853 ENCRYPT_BOOL_ON, template));
3855 case CKA_VERIFY:
3856 return (get_bool_attr_from_object(object_p,
3857 VERIFY_BOOL_ON, template));
3859 case CKA_VERIFY_RECOVER:
3860 return (get_bool_attr_from_object(object_p,
3861 VERIFY_RECOVER_BOOL_ON, template));
3863 case CKA_WRAP:
3864 return (get_bool_attr_from_object(object_p,
3865 WRAP_BOOL_ON, template));
3867 case CKA_TRUSTED:
3868 return (get_bool_attr_from_object(object_p,
3869 TRUSTED_BOOL_ON, template));
3871 case CKA_MODULUS:
3873 * This attribute is valid only for RSA public key
3874 * object.
3876 if (keytype == CKK_RSA) {
3877 return (get_bigint_attr_from_object(
3878 OBJ_PUB_RSA_MOD(object_p), template));
3879 } else {
3880 template->ulValueLen = (CK_ULONG)-1;
3881 return (CKR_ATTRIBUTE_TYPE_INVALID);
3884 case CKA_PUBLIC_EXPONENT:
3885 if (keytype == CKK_RSA) {
3886 return (get_bigint_attr_from_object(
3887 OBJ_PUB_RSA_PUBEXPO(object_p), template));
3888 } else {
3889 template->ulValueLen = (CK_ULONG)-1;
3890 return (CKR_ATTRIBUTE_TYPE_INVALID);
3893 case CKA_MODULUS_BITS:
3894 if (keytype == CKK_RSA) {
3895 return (get_ulong_attr_from_object(
3896 OBJ_PUB_RSA_MOD_BITS(object_p), template));
3897 } else {
3898 template->ulValueLen = (CK_ULONG)-1;
3899 return (CKR_ATTRIBUTE_TYPE_INVALID);
3902 case CKA_PRIME:
3903 switch (keytype) {
3904 case CKK_DSA:
3905 return (get_bigint_attr_from_object(
3906 OBJ_PUB_DSA_PRIME(object_p), template));
3908 case CKK_DH:
3909 return (get_bigint_attr_from_object(
3910 OBJ_PUB_DH_PRIME(object_p), template));
3912 case CKK_X9_42_DH:
3913 return (get_bigint_attr_from_object(
3914 OBJ_PUB_DH942_PRIME(object_p), template));
3916 default:
3917 template->ulValueLen = (CK_ULONG)-1;
3918 return (CKR_ATTRIBUTE_TYPE_INVALID);
3921 case CKA_SUBPRIME:
3922 switch (keytype) {
3923 case CKK_DSA:
3924 return (get_bigint_attr_from_object(
3925 OBJ_PUB_DSA_SUBPRIME(object_p), template));
3927 case CKK_X9_42_DH:
3928 return (get_bigint_attr_from_object(
3929 OBJ_PUB_DH942_SUBPRIME(object_p), template));
3931 default:
3932 template->ulValueLen = (CK_ULONG)-1;
3933 return (CKR_ATTRIBUTE_TYPE_INVALID);
3936 case CKA_BASE:
3937 switch (keytype) {
3938 case CKK_DSA:
3939 return (get_bigint_attr_from_object(
3940 OBJ_PUB_DSA_BASE(object_p), template));
3942 case CKK_DH:
3943 return (get_bigint_attr_from_object(
3944 OBJ_PUB_DH_BASE(object_p), template));
3946 case CKK_X9_42_DH:
3947 return (get_bigint_attr_from_object(
3948 OBJ_PUB_DH942_BASE(object_p), template));
3950 default:
3951 template->ulValueLen = (CK_ULONG)-1;
3952 return (CKR_ATTRIBUTE_TYPE_INVALID);
3955 case CKA_EC_POINT:
3956 return (get_bigint_attr_from_object(
3957 OBJ_PUB_EC_POINT(object_p), template));
3959 case CKA_VALUE:
3960 switch (keytype) {
3961 case CKK_DSA:
3962 return (get_bigint_attr_from_object(
3963 OBJ_PUB_DSA_VALUE(object_p), template));
3965 case CKK_DH:
3966 return (get_bigint_attr_from_object(
3967 OBJ_PUB_DH_VALUE(object_p), template));
3969 case CKK_X9_42_DH:
3970 return (get_bigint_attr_from_object(
3971 OBJ_PUB_DH942_VALUE(object_p), template));
3973 default:
3974 template->ulValueLen = (CK_ULONG)-1;
3975 return (CKR_ATTRIBUTE_TYPE_INVALID);
3978 default:
3980 * First, get the value of the request attribute defined
3981 * in the list of common key attributes. If the request
3982 * attribute is not found in that list, then get the
3983 * attribute from the list of common attributes.
3985 rv = soft_get_common_key_attrs(object_p, template);
3986 if (rv == CKR_ATTRIBUTE_TYPE_INVALID) {
3987 rv = soft_get_common_attrs(object_p, template,
3988 object_p->object_type);
3990 break;
3993 return (rv);
3998 * Get the value of a requested attribute of a Private Key Object.
4000 * Rule: All the attributes in the private key object can be revealed
4001 * except those marked with footnote number "7" when the object
4002 * has its CKA_SENSITIVE attribute set to TRUE or its
4003 * CKA_EXTRACTABLE attribute set to FALSE (p.88 in PKCS11 spec.).
4005 CK_RV
4006 soft_get_private_key_attribute(soft_object_t *object_p,
4007 CK_ATTRIBUTE_PTR template)
4010 CK_RV rv = CKR_OK;
4011 CK_KEY_TYPE keytype = object_p->key_type;
4015 * If the following specified attributes for the private key
4016 * object cannot be revealed because the object is sensitive
4017 * or unextractable, then the ulValueLen is set to -1.
4019 if ((object_p->bool_attr_mask & SENSITIVE_BOOL_ON) ||
4020 !(object_p->bool_attr_mask & EXTRACTABLE_BOOL_ON)) {
4022 switch (template->type) {
4023 case CKA_PRIVATE_EXPONENT:
4024 case CKA_PRIME_1:
4025 case CKA_PRIME_2:
4026 case CKA_EXPONENT_1:
4027 case CKA_EXPONENT_2:
4028 case CKA_COEFFICIENT:
4029 case CKA_VALUE:
4030 template->ulValueLen = (CK_ULONG)-1;
4031 return (CKR_ATTRIBUTE_SENSITIVE);
4035 switch (template->type) {
4037 case CKA_SUBJECT:
4038 case CKA_EC_PARAMS:
4040 * The above extra attributes have byte array type.
4042 return (get_extra_attr_from_object(object_p,
4043 template));
4045 /* Key related boolean attributes */
4046 case CKA_SENSITIVE:
4047 return (get_bool_attr_from_object(object_p,
4048 SENSITIVE_BOOL_ON, template));
4050 case CKA_SECONDARY_AUTH:
4051 return (get_bool_attr_from_object(object_p,
4052 SECONDARY_AUTH_BOOL_ON, template));
4054 case CKA_DECRYPT:
4055 return (get_bool_attr_from_object(object_p,
4056 DECRYPT_BOOL_ON, template));
4058 case CKA_SIGN:
4059 return (get_bool_attr_from_object(object_p,
4060 SIGN_BOOL_ON, template));
4062 case CKA_SIGN_RECOVER:
4063 return (get_bool_attr_from_object(object_p,
4064 SIGN_RECOVER_BOOL_ON, template));
4066 case CKA_UNWRAP:
4067 return (get_bool_attr_from_object(object_p,
4068 UNWRAP_BOOL_ON, template));
4070 case CKA_EXTRACTABLE:
4071 return (get_bool_attr_from_object(object_p,
4072 EXTRACTABLE_BOOL_ON, template));
4074 case CKA_ALWAYS_SENSITIVE:
4075 return (get_bool_attr_from_object(object_p,
4076 ALWAYS_SENSITIVE_BOOL_ON, template));
4078 case CKA_NEVER_EXTRACTABLE:
4079 return (get_bool_attr_from_object(object_p,
4080 NEVER_EXTRACTABLE_BOOL_ON, template));
4082 case CKA_MODULUS:
4083 if (keytype == CKK_RSA) {
4084 return (get_bigint_attr_from_object(
4085 OBJ_PRI_RSA_MOD(object_p), template));
4086 } else {
4087 template->ulValueLen = (CK_ULONG)-1;
4088 rv = CKR_ATTRIBUTE_TYPE_INVALID;
4089 break;
4092 case CKA_PUBLIC_EXPONENT:
4093 if (keytype == CKK_RSA) {
4094 return (get_bigint_attr_from_object(
4095 OBJ_PRI_RSA_PUBEXPO(object_p), template));
4096 } else {
4097 template->ulValueLen = (CK_ULONG)-1;
4098 rv = CKR_ATTRIBUTE_TYPE_INVALID;
4099 break;
4102 case CKA_PRIVATE_EXPONENT:
4103 if (keytype == CKK_RSA) {
4104 return (get_bigint_attr_from_object(
4105 OBJ_PRI_RSA_PRIEXPO(object_p), template));
4106 } else {
4107 template->ulValueLen = (CK_ULONG)-1;
4108 rv = CKR_ATTRIBUTE_TYPE_INVALID;
4109 break;
4112 case CKA_PRIME_1:
4113 if (keytype == CKK_RSA) {
4114 return (get_bigint_attr_from_object(
4115 OBJ_PRI_RSA_PRIME1(object_p), template));
4116 } else {
4117 template->ulValueLen = (CK_ULONG)-1;
4118 rv = CKR_ATTRIBUTE_TYPE_INVALID;
4119 break;
4122 case CKA_PRIME_2:
4123 if (keytype == CKK_RSA) {
4124 return (get_bigint_attr_from_object(
4125 OBJ_PRI_RSA_PRIME2(object_p), template));
4126 } else {
4127 template->ulValueLen = (CK_ULONG)-1;
4128 rv = CKR_ATTRIBUTE_TYPE_INVALID;
4129 break;
4132 case CKA_EXPONENT_1:
4133 if (keytype == CKK_RSA) {
4134 return (get_bigint_attr_from_object(
4135 OBJ_PRI_RSA_EXPO1(object_p), template));
4136 } else {
4137 template->ulValueLen = (CK_ULONG)-1;
4138 rv = CKR_ATTRIBUTE_TYPE_INVALID;
4139 break;
4142 case CKA_EXPONENT_2:
4143 if (keytype == CKK_RSA) {
4144 return (get_bigint_attr_from_object(
4145 OBJ_PRI_RSA_EXPO2(object_p), template));
4146 } else {
4147 template->ulValueLen = (CK_ULONG)-1;
4148 rv = CKR_ATTRIBUTE_TYPE_INVALID;
4149 break;
4152 case CKA_COEFFICIENT:
4153 if (keytype == CKK_RSA) {
4154 return (get_bigint_attr_from_object(
4155 OBJ_PRI_RSA_COEF(object_p), template));
4156 } else {
4157 template->ulValueLen = (CK_ULONG)-1;
4158 rv = CKR_ATTRIBUTE_TYPE_INVALID;
4159 break;
4162 case CKA_VALUE_BITS:
4163 if (keytype == CKK_DH) {
4164 return (get_ulong_attr_from_object(
4165 OBJ_PRI_DH_VAL_BITS(object_p), template));
4166 } else {
4167 template->ulValueLen = (CK_ULONG)-1;
4168 rv = CKR_ATTRIBUTE_TYPE_INVALID;
4169 break;
4172 case CKA_PRIME:
4173 switch (keytype) {
4174 case CKK_DSA:
4175 return (get_bigint_attr_from_object(
4176 OBJ_PRI_DSA_PRIME(object_p), template));
4178 case CKK_DH:
4179 return (get_bigint_attr_from_object(
4180 OBJ_PRI_DH_PRIME(object_p), template));
4182 case CKK_X9_42_DH:
4183 return (get_bigint_attr_from_object(
4184 OBJ_PRI_DH942_PRIME(object_p), template));
4186 default:
4187 template->ulValueLen = (CK_ULONG)-1;
4188 return (CKR_ATTRIBUTE_TYPE_INVALID);
4191 case CKA_SUBPRIME:
4192 switch (keytype) {
4193 case CKK_DSA:
4194 return (get_bigint_attr_from_object(
4195 OBJ_PRI_DSA_SUBPRIME(object_p), template));
4197 case CKK_X9_42_DH:
4198 return (get_bigint_attr_from_object(
4199 OBJ_PRI_DH942_SUBPRIME(object_p), template));
4201 default:
4202 template->ulValueLen = (CK_ULONG)-1;
4203 return (CKR_ATTRIBUTE_TYPE_INVALID);
4206 case CKA_BASE:
4207 switch (keytype) {
4208 case CKK_DSA:
4209 return (get_bigint_attr_from_object(
4210 OBJ_PRI_DSA_BASE(object_p), template));
4212 case CKK_DH:
4213 return (get_bigint_attr_from_object(
4214 OBJ_PRI_DH_BASE(object_p), template));
4216 case CKK_X9_42_DH:
4217 return (get_bigint_attr_from_object(
4218 OBJ_PRI_DH942_BASE(object_p), template));
4220 default:
4221 template->ulValueLen = (CK_ULONG)-1;
4222 return (CKR_ATTRIBUTE_TYPE_INVALID);
4225 case CKA_VALUE:
4226 switch (keytype) {
4227 case CKK_DSA:
4228 return (get_bigint_attr_from_object(
4229 OBJ_PRI_DSA_VALUE(object_p), template));
4231 case CKK_DH:
4232 return (get_bigint_attr_from_object(
4233 OBJ_PRI_DH_VALUE(object_p), template));
4235 case CKK_X9_42_DH:
4236 return (get_bigint_attr_from_object(
4237 OBJ_PRI_DH942_VALUE(object_p), template));
4239 case CKK_EC:
4240 return (get_bigint_attr_from_object(
4241 OBJ_PRI_EC_VALUE(object_p), template));
4243 default:
4244 template->ulValueLen = (CK_ULONG)-1;
4245 return (CKR_ATTRIBUTE_TYPE_INVALID);
4248 default:
4250 * First, get the value of the request attribute defined
4251 * in the list of common key attributes. If the request
4252 * attribute is not found in that list, then get the
4253 * attribute from the list of common attributes.
4255 rv = soft_get_common_key_attrs(object_p, template);
4256 if (rv == CKR_ATTRIBUTE_TYPE_INVALID) {
4257 rv = soft_get_common_attrs(object_p, template,
4258 object_p->object_type);
4260 break;
4263 return (rv);
4268 * Get the value of a requested attribute of a Secret Key Object.
4270 * Rule: All the attributes in the secret key object can be revealed
4271 * except those marked with footnote number "7" when the object
4272 * has its CKA_SENSITIVE attribute set to TRUE or its
4273 * CKA_EXTRACTABLE attribute set to FALSE (p.88 in PKCS11 spec.).
4275 CK_RV
4276 soft_get_secret_key_attribute(soft_object_t *object_p,
4277 CK_ATTRIBUTE_PTR template)
4280 CK_RV rv = CKR_OK;
4281 CK_KEY_TYPE keytype = object_p->key_type;
4283 switch (template->type) {
4285 /* Key related boolean attributes */
4286 case CKA_SENSITIVE:
4287 return (get_bool_attr_from_object(object_p,
4288 SENSITIVE_BOOL_ON, template));
4290 case CKA_ENCRYPT:
4291 return (get_bool_attr_from_object(object_p,
4292 ENCRYPT_BOOL_ON, template));
4294 case CKA_DECRYPT:
4295 return (get_bool_attr_from_object(object_p,
4296 DECRYPT_BOOL_ON, template));
4298 case CKA_SIGN:
4299 return (get_bool_attr_from_object(object_p,
4300 SIGN_BOOL_ON, template));
4302 case CKA_VERIFY:
4303 return (get_bool_attr_from_object(object_p,
4304 VERIFY_BOOL_ON, template));
4306 case CKA_WRAP:
4307 return (get_bool_attr_from_object(object_p,
4308 WRAP_BOOL_ON, template));
4310 case CKA_UNWRAP:
4311 return (get_bool_attr_from_object(object_p,
4312 UNWRAP_BOOL_ON, template));
4314 case CKA_EXTRACTABLE:
4315 return (get_bool_attr_from_object(object_p,
4316 EXTRACTABLE_BOOL_ON, template));
4318 case CKA_ALWAYS_SENSITIVE:
4319 return (get_bool_attr_from_object(object_p,
4320 ALWAYS_SENSITIVE_BOOL_ON, template));
4322 case CKA_NEVER_EXTRACTABLE:
4323 return (get_bool_attr_from_object(object_p,
4324 NEVER_EXTRACTABLE_BOOL_ON, template));
4326 case CKA_VALUE:
4327 case CKA_VALUE_LEN:
4329 * If the specified attribute for the secret key object
4330 * cannot be revealed because the object is sensitive
4331 * or unextractable, then the ulValueLen is set to -1.
4333 if ((object_p->bool_attr_mask & SENSITIVE_BOOL_ON) ||
4334 !(object_p->bool_attr_mask & EXTRACTABLE_BOOL_ON)) {
4335 template->ulValueLen = (CK_ULONG)-1;
4336 return (CKR_ATTRIBUTE_SENSITIVE);
4339 switch (keytype) {
4340 case CKK_RC4:
4341 case CKK_GENERIC_SECRET:
4342 case CKK_RC5:
4343 case CKK_DES:
4344 case CKK_DES2:
4345 case CKK_DES3:
4346 case CKK_CDMF:
4347 case CKK_AES:
4348 case CKK_BLOWFISH:
4349 if (template->type == CKA_VALUE_LEN) {
4350 return (get_ulong_attr_from_object(
4351 OBJ_SEC_VALUE_LEN(object_p),
4352 template));
4353 } else {
4354 return (get_bigint_attr_from_object(
4355 (biginteger_t *)OBJ_SEC(object_p),
4356 template));
4358 default:
4359 template->ulValueLen = (CK_ULONG)-1;
4360 rv = CKR_ATTRIBUTE_TYPE_INVALID;
4361 break;
4363 break;
4365 default:
4367 * First, get the value of the request attribute defined
4368 * in the list of common key attributes. If the request
4369 * attribute is not found in that list, then get the
4370 * attribute from the list of common attributes.
4372 rv = soft_get_common_key_attrs(object_p, template);
4373 if (rv == CKR_ATTRIBUTE_TYPE_INVALID) {
4374 rv = soft_get_common_attrs(object_p, template,
4375 object_p->object_type);
4377 break;
4380 return (rv);
4385 * Get the value of a requested attribute of a Domain Parameters Object.
4387 * Rule: All the attributes in the domain parameters object can be revealed.
4389 CK_RV
4390 soft_get_domain_parameters_attribute(soft_object_t *object_p,
4391 CK_ATTRIBUTE_PTR template)
4394 CK_RV rv = CKR_OK;
4395 CK_KEY_TYPE keytype = object_p->key_type;
4397 switch (template->type) {
4399 case CKA_KEY_TYPE:
4400 return (get_ulong_attr_from_object(keytype,
4401 template));
4403 case CKA_LOCAL:
4404 return (get_bool_attr_from_object(object_p,
4405 LOCAL_BOOL_ON, template));
4407 case CKA_PRIME:
4408 switch (keytype) {
4409 case CKK_DSA:
4410 return (get_bigint_attr_from_object(
4411 OBJ_DOM_DSA_PRIME(object_p), template));
4413 case CKK_DH:
4414 return (get_bigint_attr_from_object(
4415 OBJ_DOM_DH_PRIME(object_p), template));
4417 case CKK_X9_42_DH:
4418 return (get_bigint_attr_from_object(
4419 OBJ_DOM_DH942_PRIME(object_p), template));
4421 default:
4422 template->ulValueLen = (CK_ULONG)-1;
4423 return (CKR_ATTRIBUTE_TYPE_INVALID);
4426 case CKA_SUBPRIME:
4427 switch (keytype) {
4428 case CKK_DSA:
4429 return (get_bigint_attr_from_object(
4430 OBJ_DOM_DSA_SUBPRIME(object_p), template));
4432 case CKK_X9_42_DH:
4433 return (get_bigint_attr_from_object(
4434 OBJ_DOM_DH942_SUBPRIME(object_p), template));
4436 default:
4437 template->ulValueLen = (CK_ULONG)-1;
4438 return (CKR_ATTRIBUTE_TYPE_INVALID);
4441 case CKA_BASE:
4442 switch (keytype) {
4443 case CKK_DSA:
4444 return (get_bigint_attr_from_object(
4445 OBJ_DOM_DSA_BASE(object_p), template));
4447 case CKK_DH:
4448 return (get_bigint_attr_from_object(
4449 OBJ_DOM_DH_BASE(object_p), template));
4451 case CKK_X9_42_DH:
4452 return (get_bigint_attr_from_object(
4453 OBJ_DOM_DH942_BASE(object_p), template));
4455 default:
4456 template->ulValueLen = (CK_ULONG)-1;
4457 return (CKR_ATTRIBUTE_TYPE_INVALID);
4460 case CKA_PRIME_BITS:
4461 switch (keytype) {
4462 case CKK_DSA:
4463 return (get_ulong_attr_from_object(
4464 OBJ_DOM_DSA_PRIME_BITS(object_p), template));
4466 case CKK_DH:
4467 return (get_ulong_attr_from_object(
4468 OBJ_DOM_DH_PRIME_BITS(object_p), template));
4470 case CKK_X9_42_DH:
4471 return (get_ulong_attr_from_object(
4472 OBJ_DOM_DH942_PRIME_BITS(object_p), template));
4474 default:
4475 template->ulValueLen = (CK_ULONG)-1;
4476 return (CKR_ATTRIBUTE_TYPE_INVALID);
4479 case CKA_SUB_PRIME_BITS:
4480 switch (keytype) {
4481 case CKK_X9_42_DH:
4482 return (get_ulong_attr_from_object(
4483 OBJ_DOM_DH942_SUBPRIME_BITS(object_p), template));
4485 default:
4486 template->ulValueLen = (CK_ULONG)-1;
4487 return (CKR_ATTRIBUTE_TYPE_INVALID);
4490 default:
4492 * Get the value of a common attribute.
4494 rv = soft_get_common_attrs(object_p, template,
4495 object_p->object_type);
4496 break;
4499 return (rv);
4503 * Get certificate attributes from an object.
4504 * return CKR_ATTRIBUTE_TYPE_INVALID if the requested type
4505 * does not exist in the certificate.
4507 CK_RV
4508 soft_get_certificate_attribute(soft_object_t *object_p,
4509 CK_ATTRIBUTE_PTR template)
4511 CK_CERTIFICATE_TYPE certtype = object_p->cert_type;
4512 cert_attr_t src;
4514 switch (template->type) {
4515 case CKA_SUBJECT:
4516 if (certtype == CKC_X_509) {
4517 return (get_cert_attr_from_object(
4518 X509_CERT_SUBJECT(object_p), template));
4520 break;
4521 case CKA_VALUE:
4522 if (certtype == CKC_X_509) {
4523 return (get_cert_attr_from_object(
4524 X509_CERT_VALUE(object_p), template));
4525 } else if (certtype == CKC_X_509_ATTR_CERT) {
4526 return (get_cert_attr_from_object(
4527 X509_ATTR_CERT_VALUE(object_p), template));
4529 break;
4530 case CKA_OWNER:
4531 if (certtype == CKC_X_509_ATTR_CERT) {
4532 return (get_cert_attr_from_object(
4533 X509_ATTR_CERT_OWNER(object_p), template));
4535 break;
4536 case CKA_CERTIFICATE_TYPE:
4537 src.value = (CK_BYTE *)&certtype;
4538 src.length = sizeof (certtype);
4539 return (get_cert_attr_from_object(&src, template));
4540 case CKA_TRUSTED:
4541 return (get_bool_attr_from_object(object_p,
4542 TRUSTED_BOOL_ON, template));
4543 case CKA_ID:
4544 case CKA_ISSUER:
4545 case CKA_SERIAL_NUMBER:
4546 case CKA_AC_ISSUER:
4547 case CKA_ATTR_TYPES:
4548 return (get_extra_attr_from_object(object_p,
4549 template));
4550 default:
4551 return (soft_get_common_attrs(object_p, template,
4552 object_p->object_type));
4556 * If we got this far, then the combination of certificate type
4557 * and requested attribute is invalid.
4559 return (CKR_ATTRIBUTE_TYPE_INVALID);
4562 CK_RV
4563 soft_set_certificate_attribute(soft_object_t *object_p,
4564 CK_ATTRIBUTE_PTR template, boolean_t copy)
4566 CK_CERTIFICATE_TYPE certtype = object_p->cert_type;
4568 switch (template->type) {
4569 case CKA_SUBJECT:
4570 if (certtype == CKC_X_509) {
4571 /* SUBJECT attr cannot be modified. */
4572 return (CKR_ATTRIBUTE_READ_ONLY);
4574 break;
4575 case CKA_OWNER:
4576 if (certtype == CKC_X_509_ATTR_CERT) {
4577 /* OWNER attr cannot be modified. */
4578 return (CKR_ATTRIBUTE_READ_ONLY);
4580 break;
4581 case CKA_VALUE:
4582 /* VALUE attr cannot be modified. */
4583 return (CKR_ATTRIBUTE_READ_ONLY);
4584 case CKA_ID:
4585 case CKA_ISSUER:
4586 if (certtype == CKC_X_509) {
4587 return (set_extra_attr_to_object(object_p,
4588 template->type, template));
4590 break;
4591 case CKA_AC_ISSUER:
4592 case CKA_ATTR_TYPES:
4593 if (certtype == CKC_X_509_ATTR_CERT) {
4594 return (set_extra_attr_to_object(object_p,
4595 template->type, template));
4597 break;
4598 case CKA_SERIAL_NUMBER:
4599 case CKA_LABEL:
4600 return (set_extra_attr_to_object(object_p,
4601 template->type, template));
4602 default:
4603 return (soft_set_common_storage_attribute(
4604 object_p, template, copy));
4608 * If we got this far, then the combination of certificate type
4609 * and requested attribute is invalid.
4611 return (CKR_ATTRIBUTE_TYPE_INVALID);
4615 * Call the appropriate get attribute function according to the class
4616 * of object.
4618 * The caller of this function holds the lock on the object.
4620 CK_RV
4621 soft_get_attribute(soft_object_t *object_p, CK_ATTRIBUTE_PTR template)
4624 CK_RV rv = CKR_OK;
4625 CK_OBJECT_CLASS class = object_p->class;
4627 switch (class) {
4628 case CKO_PUBLIC_KEY:
4629 rv = soft_get_public_key_attribute(object_p, template);
4630 break;
4632 case CKO_PRIVATE_KEY:
4633 rv = soft_get_private_key_attribute(object_p, template);
4634 break;
4636 case CKO_SECRET_KEY:
4637 rv = soft_get_secret_key_attribute(object_p, template);
4638 break;
4640 case CKO_DOMAIN_PARAMETERS:
4641 rv = soft_get_domain_parameters_attribute(object_p, template);
4642 break;
4644 case CKO_CERTIFICATE:
4645 rv = soft_get_certificate_attribute(object_p, template);
4646 break;
4648 default:
4650 * If the specified attribute for the object is invalid
4651 * (the object does not possess such as attribute), then
4652 * the ulValueLen is modified to hold the value -1.
4654 template->ulValueLen = (CK_ULONG)-1;
4655 return (CKR_ATTRIBUTE_TYPE_INVALID);
4658 return (rv);
4662 CK_RV
4663 soft_set_common_storage_attribute(soft_object_t *object_p,
4664 CK_ATTRIBUTE_PTR template, boolean_t copy)
4667 CK_RV rv = CKR_OK;
4669 switch (template->type) {
4671 case CKA_TOKEN:
4672 if (copy) {
4673 if ((*(CK_BBOOL *)template->pValue) == B_TRUE) {
4674 if (!soft_keystore_status(KEYSTORE_INITIALIZED))
4675 return (CKR_DEVICE_REMOVED);
4676 object_p->object_type |= TOKEN_OBJECT;
4678 } else {
4679 rv = CKR_ATTRIBUTE_READ_ONLY;
4682 break;
4684 case CKA_PRIVATE:
4685 if (copy) {
4686 if ((*(CK_BBOOL *)template->pValue) == B_TRUE) {
4687 (void) pthread_mutex_lock(&soft_giant_mutex);
4688 if (!soft_slot.authenticated) {
4690 * Check if this is the special case
4691 * when the PIN is never initialized
4692 * in the keystore. If true, we will
4693 * let it pass here and let it fail
4694 * with CKR_PIN_EXPIRED later on.
4696 if (!soft_slot.userpin_change_needed) {
4697 (void) pthread_mutex_unlock(
4698 &soft_giant_mutex);
4699 return (CKR_USER_NOT_LOGGED_IN);
4702 (void) pthread_mutex_unlock(&soft_giant_mutex);
4703 object_p->object_type |= PRIVATE_OBJECT;
4705 } else {
4706 rv = CKR_ATTRIBUTE_READ_ONLY;
4708 break;
4710 case CKA_MODIFIABLE:
4711 if (copy) {
4712 if ((*(CK_BBOOL *)template->pValue) == TRUE)
4713 object_p->bool_attr_mask &=
4714 ~NOT_MODIFIABLE_BOOL_ON;
4715 else
4716 object_p->bool_attr_mask |=
4717 NOT_MODIFIABLE_BOOL_ON;
4718 } else {
4719 rv = CKR_ATTRIBUTE_READ_ONLY;
4721 break;
4723 case CKA_CLASS:
4724 rv = CKR_ATTRIBUTE_READ_ONLY;
4725 break;
4727 default:
4728 rv = CKR_TEMPLATE_INCONSISTENT;
4731 return (rv);
4735 * Set the value of an attribute that is common to all key objects
4736 * (i.e. public key, private key and secret key).
4738 CK_RV
4739 soft_set_common_key_attribute(soft_object_t *object_p,
4740 CK_ATTRIBUTE_PTR template, boolean_t copy)
4743 switch (template->type) {
4745 case CKA_LABEL:
4747 * Only the LABEL can be modified in the common storage
4748 * object attributes after the object is created.
4750 return (set_extra_attr_to_object(object_p,
4751 CKA_LABEL, template));
4753 case CKA_ID:
4754 return (set_extra_attr_to_object(object_p,
4755 CKA_ID, template));
4757 case CKA_START_DATE:
4758 return (set_extra_attr_to_object(object_p,
4759 CKA_START_DATE, template));
4761 case CKA_END_DATE:
4762 return (set_extra_attr_to_object(object_p,
4763 CKA_END_DATE, template));
4765 case CKA_DERIVE:
4766 return (set_bool_attr_to_object(object_p,
4767 DERIVE_BOOL_ON, template));
4769 case CKA_KEY_TYPE:
4770 case CKA_LOCAL:
4771 case CKA_KEY_GEN_MECHANISM:
4772 return (CKR_ATTRIBUTE_READ_ONLY);
4774 default:
4775 return (soft_set_common_storage_attribute(object_p,
4776 template, copy));
4784 * Set the value of an attribute of a Public Key Object.
4786 * Rule: The attributes marked with footnote number "8" in the PKCS11
4787 * spec may be modified (p.88 in PKCS11 spec.).
4789 CK_RV
4790 soft_set_public_key_attribute(soft_object_t *object_p,
4791 CK_ATTRIBUTE_PTR template, boolean_t copy)
4793 CK_KEY_TYPE keytype = object_p->key_type;
4795 switch (template->type) {
4797 case CKA_SUBJECT:
4798 return (set_extra_attr_to_object(object_p,
4799 CKA_SUBJECT, template));
4801 case CKA_ENCRYPT:
4802 return (set_bool_attr_to_object(object_p,
4803 ENCRYPT_BOOL_ON, template));
4805 case CKA_VERIFY:
4806 return (set_bool_attr_to_object(object_p,
4807 VERIFY_BOOL_ON, template));
4809 case CKA_VERIFY_RECOVER:
4810 return (set_bool_attr_to_object(object_p,
4811 VERIFY_RECOVER_BOOL_ON, template));
4813 case CKA_WRAP:
4814 return (set_bool_attr_to_object(object_p,
4815 WRAP_BOOL_ON, template));
4817 case CKA_MODULUS:
4818 case CKA_MODULUS_BITS:
4819 case CKA_PUBLIC_EXPONENT:
4820 if (keytype == CKK_RSA)
4821 return (CKR_ATTRIBUTE_READ_ONLY);
4822 break;
4824 case CKA_SUBPRIME:
4825 if ((keytype == CKK_DSA) ||
4826 (keytype == CKK_X9_42_DH))
4827 return (CKR_ATTRIBUTE_READ_ONLY);
4828 break;
4830 case CKA_PRIME:
4831 case CKA_BASE:
4832 case CKA_VALUE:
4833 if ((keytype == CKK_DSA) ||
4834 (keytype == CKK_DH) ||
4835 (keytype == CKK_X9_42_DH))
4836 return (CKR_ATTRIBUTE_READ_ONLY);
4837 break;
4839 default:
4841 * Set the value of a common key attribute.
4843 return (soft_set_common_key_attribute(object_p,
4844 template, copy));
4848 * If we got this far, then the combination of key type
4849 * and requested attribute is invalid.
4851 return (CKR_ATTRIBUTE_TYPE_INVALID);
4856 * Set the value of an attribute of a Private Key Object.
4858 * Rule: The attributes marked with footnote number "8" in the PKCS11
4859 * spec may be modified (p.88 in PKCS11 spec.).
4861 CK_RV
4862 soft_set_private_key_attribute(soft_object_t *object_p,
4863 CK_ATTRIBUTE_PTR template, boolean_t copy)
4865 CK_KEY_TYPE keytype = object_p->key_type;
4867 switch (template->type) {
4869 case CKA_SUBJECT:
4870 return (set_extra_attr_to_object(object_p,
4871 CKA_SUBJECT, template));
4873 case CKA_SENSITIVE:
4875 * Cannot set SENSITIVE to FALSE if it is already ON.
4877 if (((*(CK_BBOOL *)template->pValue) == B_FALSE) &&
4878 (object_p->bool_attr_mask & SENSITIVE_BOOL_ON)) {
4879 return (CKR_ATTRIBUTE_READ_ONLY);
4882 if (*(CK_BBOOL *)template->pValue)
4883 object_p->bool_attr_mask |= SENSITIVE_BOOL_ON;
4884 return (CKR_OK);
4886 case CKA_DECRYPT:
4887 return (set_bool_attr_to_object(object_p,
4888 DECRYPT_BOOL_ON, template));
4890 case CKA_SIGN:
4891 return (set_bool_attr_to_object(object_p,
4892 SIGN_BOOL_ON, template));
4894 case CKA_SIGN_RECOVER:
4895 return (set_bool_attr_to_object(object_p,
4896 SIGN_RECOVER_BOOL_ON, template));
4898 case CKA_UNWRAP:
4899 return (set_bool_attr_to_object(object_p,
4900 UNWRAP_BOOL_ON, template));
4902 case CKA_EXTRACTABLE:
4904 * Cannot set EXTRACTABLE to TRUE if it is already OFF.
4906 if ((*(CK_BBOOL *)template->pValue) &&
4907 !(object_p->bool_attr_mask & EXTRACTABLE_BOOL_ON)) {
4908 return (CKR_ATTRIBUTE_READ_ONLY);
4911 if ((*(CK_BBOOL *)template->pValue) == B_FALSE)
4912 object_p->bool_attr_mask &= ~EXTRACTABLE_BOOL_ON;
4913 return (CKR_OK);
4915 case CKA_MODULUS:
4916 case CKA_PUBLIC_EXPONENT:
4917 case CKA_PRIVATE_EXPONENT:
4918 case CKA_PRIME_1:
4919 case CKA_PRIME_2:
4920 case CKA_EXPONENT_1:
4921 case CKA_EXPONENT_2:
4922 case CKA_COEFFICIENT:
4923 if (keytype == CKK_RSA) {
4924 return (CKR_ATTRIBUTE_READ_ONLY);
4926 break;
4928 case CKA_SUBPRIME:
4929 if ((keytype == CKK_DSA) ||
4930 (keytype == CKK_X9_42_DH))
4931 return (CKR_ATTRIBUTE_READ_ONLY);
4932 break;
4934 case CKA_PRIME:
4935 case CKA_BASE:
4936 case CKA_VALUE:
4937 if ((keytype == CKK_DSA) ||
4938 (keytype == CKK_DH) ||
4939 (keytype == CKK_X9_42_DH))
4940 return (CKR_ATTRIBUTE_READ_ONLY);
4941 break;
4943 case CKA_VALUE_BITS:
4944 if (keytype == CKK_DH)
4945 return (CKR_ATTRIBUTE_READ_ONLY);
4946 break;
4948 default:
4950 * Set the value of a common key attribute.
4952 return (soft_set_common_key_attribute(object_p,
4953 template, copy));
4957 * If we got this far, then the combination of key type
4958 * and requested attribute is invalid.
4960 return (CKR_ATTRIBUTE_TYPE_INVALID);
4964 * Set the value of an attribute of a Secret Key Object.
4966 * Rule: The attributes marked with footnote number "8" in the PKCS11
4967 * spec may be modified (p.88 in PKCS11 spec.).
4969 CK_RV
4970 soft_set_secret_key_attribute(soft_object_t *object_p,
4971 CK_ATTRIBUTE_PTR template, boolean_t copy)
4973 CK_KEY_TYPE keytype = object_p->key_type;
4975 switch (template->type) {
4977 case CKA_SENSITIVE:
4979 * Cannot set SENSITIVE to FALSE if it is already ON.
4981 if (((*(CK_BBOOL *)template->pValue) == B_FALSE) &&
4982 (object_p->bool_attr_mask & SENSITIVE_BOOL_ON)) {
4983 return (CKR_ATTRIBUTE_READ_ONLY);
4986 if (*(CK_BBOOL *)template->pValue)
4987 object_p->bool_attr_mask |= SENSITIVE_BOOL_ON;
4988 return (CKR_OK);
4990 case CKA_ENCRYPT:
4991 return (set_bool_attr_to_object(object_p,
4992 ENCRYPT_BOOL_ON, template));
4994 case CKA_DECRYPT:
4995 return (set_bool_attr_to_object(object_p,
4996 DECRYPT_BOOL_ON, template));
4998 case CKA_SIGN:
4999 return (set_bool_attr_to_object(object_p,
5000 SIGN_BOOL_ON, template));
5002 case CKA_VERIFY:
5003 return (set_bool_attr_to_object(object_p,
5004 VERIFY_BOOL_ON, template));
5006 case CKA_WRAP:
5007 return (set_bool_attr_to_object(object_p,
5008 WRAP_BOOL_ON, template));
5010 case CKA_UNWRAP:
5011 return (set_bool_attr_to_object(object_p,
5012 UNWRAP_BOOL_ON, template));
5014 case CKA_EXTRACTABLE:
5016 * Cannot set EXTRACTABLE to TRUE if it is already OFF.
5018 if ((*(CK_BBOOL *)template->pValue) &&
5019 !(object_p->bool_attr_mask & EXTRACTABLE_BOOL_ON)) {
5020 return (CKR_ATTRIBUTE_READ_ONLY);
5023 if ((*(CK_BBOOL *)template->pValue) == B_FALSE)
5024 object_p->bool_attr_mask &= ~EXTRACTABLE_BOOL_ON;
5025 return (CKR_OK);
5027 case CKA_VALUE:
5028 return (CKR_ATTRIBUTE_READ_ONLY);
5030 case CKA_VALUE_LEN:
5031 if ((keytype == CKK_RC4) ||
5032 (keytype == CKK_GENERIC_SECRET) ||
5033 (keytype == CKK_AES) ||
5034 (keytype == CKK_BLOWFISH))
5035 return (CKR_ATTRIBUTE_READ_ONLY);
5036 break;
5038 default:
5040 * Set the value of a common key attribute.
5042 return (soft_set_common_key_attribute(object_p,
5043 template, copy));
5047 * If we got this far, then the combination of key type
5048 * and requested attribute is invalid.
5050 return (CKR_ATTRIBUTE_TYPE_INVALID);
5055 * Call the appropriate set attribute function according to the class
5056 * of object.
5058 * The caller of this function does not hold the lock on the original
5059 * object, since this function is setting the attribute on the new object
5060 * that is being modified.
5062 * Argument copy: TRUE when called by C_CopyObject,
5063 * FALSE when called by C_SetAttributeValue.
5065 CK_RV
5066 soft_set_attribute(soft_object_t *object_p, CK_ATTRIBUTE_PTR template,
5067 boolean_t copy)
5070 CK_RV rv = CKR_OK;
5071 CK_OBJECT_CLASS class = object_p->class;
5073 switch (class) {
5075 case CKO_PUBLIC_KEY:
5076 rv = soft_set_public_key_attribute(object_p, template, copy);
5077 break;
5079 case CKO_PRIVATE_KEY:
5080 rv = soft_set_private_key_attribute(object_p, template, copy);
5081 break;
5083 case CKO_SECRET_KEY:
5084 rv = soft_set_secret_key_attribute(object_p, template, copy);
5085 break;
5087 case CKO_DOMAIN_PARAMETERS:
5088 switch (template->type) {
5089 case CKA_LABEL:
5091 * Only the LABEL can be modified in the common
5092 * storage object attributes after the object is
5093 * created.
5095 return (set_extra_attr_to_object(object_p,
5096 CKA_LABEL, template));
5097 default:
5098 return (CKR_TEMPLATE_INCONSISTENT);
5100 case CKO_CERTIFICATE:
5101 rv = soft_set_certificate_attribute(object_p, template, copy);
5102 break;
5104 default:
5106 * If the template specifies a value of an attribute
5107 * which is incompatible with other existing attributes
5108 * of the object, then fails with return code
5109 * CKR_TEMPLATE_INCONSISTENT.
5111 rv = CKR_TEMPLATE_INCONSISTENT;
5112 break;
5115 return (rv);
5118 CK_RV
5119 soft_get_public_value(soft_object_t *key, CK_ATTRIBUTE_TYPE type,
5120 uchar_t *value, uint32_t *value_len)
5122 uint32_t len = 0;
5123 switch (type) {
5125 /* The following attributes belong to RSA */
5126 case CKA_MODULUS:
5127 len =
5128 ((biginteger_t *)OBJ_PUB_RSA_MOD(key))->big_value_len;
5130 /* This attribute MUST BE set */
5131 if (len == 0 || len > *value_len) {
5132 return (CKR_ATTRIBUTE_VALUE_INVALID);
5134 *value_len = len;
5136 (void) memcpy(value,
5137 ((biginteger_t *)OBJ_PUB_RSA_MOD(key))->big_value,
5138 *value_len);
5140 break;
5142 case CKA_PUBLIC_EXPONENT:
5143 len =
5144 ((biginteger_t *)OBJ_PUB_RSA_PUBEXPO(key))->big_value_len;
5146 /* This attribute MUST BE set */
5147 if (len == 0 || len > *value_len) {
5148 return (CKR_ATTRIBUTE_VALUE_INVALID);
5150 *value_len = len;
5152 (void) memcpy(value,
5153 ((biginteger_t *)OBJ_PUB_RSA_PUBEXPO(key))->big_value,
5154 *value_len);
5156 break;
5158 /* The following attributes belong to DSA and DH */
5159 case CKA_PRIME:
5161 if (key->key_type == CKK_DSA)
5162 len =
5163 ((biginteger_t *)OBJ_PUB_DSA_PRIME(key))->
5164 big_value_len;
5165 else
5166 len =
5167 ((biginteger_t *)OBJ_PUB_DH_PRIME(key))->
5168 big_value_len;
5170 /* This attribute MUST BE set */
5171 if (len == 0 || len > *value_len) {
5172 return (CKR_ATTRIBUTE_VALUE_INVALID);
5174 *value_len = len;
5176 if (key->key_type == CKK_DSA)
5177 (void) memcpy(value,
5178 ((biginteger_t *)OBJ_PUB_DSA_PRIME(key))->big_value,
5179 *value_len);
5180 else
5181 (void) memcpy(value,
5182 ((biginteger_t *)OBJ_PUB_DH_PRIME(key))->big_value,
5183 *value_len);
5185 break;
5187 case CKA_SUBPRIME:
5188 len =
5189 ((biginteger_t *)OBJ_PUB_DSA_SUBPRIME(key))->big_value_len;
5191 /* This attribute MUST BE set */
5192 if (len == 0 || len > *value_len) {
5193 return (CKR_ATTRIBUTE_VALUE_INVALID);
5195 *value_len = len;
5197 (void) memcpy(value,
5198 ((biginteger_t *)OBJ_PUB_DSA_SUBPRIME(key))->big_value,
5199 *value_len);
5201 break;
5203 case CKA_BASE:
5205 if (key->key_type == CKK_DSA)
5206 len =
5207 ((biginteger_t *)OBJ_PUB_DSA_BASE(key))->
5208 big_value_len;
5209 else
5210 len =
5211 ((biginteger_t *)OBJ_PUB_DH_BASE(key))->
5212 big_value_len;
5214 /* This attribute MUST BE set */
5215 if (len == 0 || len > *value_len) {
5216 return (CKR_ATTRIBUTE_VALUE_INVALID);
5218 *value_len = len;
5220 if (key->key_type == CKK_DSA)
5221 (void) memcpy(value,
5222 ((biginteger_t *)OBJ_PUB_DSA_BASE(key))->big_value,
5223 *value_len);
5224 else
5225 (void) memcpy(value,
5226 ((biginteger_t *)OBJ_PUB_DH_BASE(key))->big_value,
5227 *value_len);
5228 break;
5230 case CKA_VALUE:
5232 if (key->key_type == CKK_DSA)
5233 len =
5234 ((biginteger_t *)OBJ_PUB_DSA_VALUE(key))->
5235 big_value_len;
5236 else
5237 len =
5238 ((biginteger_t *)OBJ_PUB_DH_VALUE(key))->
5239 big_value_len;
5241 /* This attribute MUST BE set */
5242 if (len == 0 || len > *value_len) {
5243 return (CKR_ATTRIBUTE_VALUE_INVALID);
5245 *value_len = len;
5247 if (key->key_type == CKK_DSA)
5248 (void) memcpy(value,
5249 ((biginteger_t *)OBJ_PUB_DSA_VALUE(key))->big_value,
5250 *value_len);
5251 else
5252 (void) memcpy(value,
5253 ((biginteger_t *)OBJ_PUB_DH_VALUE(key))->big_value,
5254 *value_len);
5256 break;
5259 return (CKR_OK);
5263 CK_RV
5264 soft_get_private_value(soft_object_t *key, CK_ATTRIBUTE_TYPE type,
5265 uchar_t *value, uint32_t *value_len)
5268 uint32_t len = 0;
5270 switch (type) {
5272 /* The following attributes belong to RSA */
5273 case CKA_MODULUS:
5274 len =
5275 ((biginteger_t *)OBJ_PRI_RSA_MOD(key))->big_value_len;
5277 /* This attribute MUST BE set */
5278 if (len == 0 || len > *value_len) {
5279 return (CKR_ATTRIBUTE_VALUE_INVALID);
5281 *value_len = len;
5283 (void) memcpy(value,
5284 ((biginteger_t *)OBJ_PRI_RSA_MOD(key))->big_value,
5285 *value_len);
5287 break;
5289 case CKA_PRIVATE_EXPONENT:
5290 len =
5291 ((biginteger_t *)OBJ_PRI_RSA_PRIEXPO(key))->big_value_len;
5293 /* This attribute MUST BE set */
5294 if (len == 0 || len > *value_len) {
5295 return (CKR_ATTRIBUTE_VALUE_INVALID);
5297 *value_len = len;
5299 (void) memcpy(value,
5300 ((biginteger_t *)OBJ_PRI_RSA_PRIEXPO(key))->big_value,
5301 *value_len);
5303 break;
5305 case CKA_PRIME_1:
5306 len =
5307 ((biginteger_t *)OBJ_PRI_RSA_PRIME1(key))->big_value_len;
5309 if (len > *value_len) {
5310 return (CKR_ATTRIBUTE_VALUE_INVALID);
5312 *value_len = len;
5314 if (*value_len == 0) {
5315 return (CKR_OK);
5318 (void) memcpy(value,
5319 ((biginteger_t *)OBJ_PRI_RSA_PRIME1(key))->big_value,
5320 *value_len);
5322 break;
5324 case CKA_PRIME_2:
5325 len =
5326 ((biginteger_t *)OBJ_PRI_RSA_PRIME2(key))->big_value_len;
5328 if (len > *value_len) {
5329 return (CKR_ATTRIBUTE_VALUE_INVALID);
5331 *value_len = len;
5333 if (*value_len == 0) {
5334 return (CKR_OK);
5337 (void) memcpy(value,
5338 ((biginteger_t *)OBJ_PRI_RSA_PRIME2(key))->big_value,
5339 *value_len);
5341 break;
5343 case CKA_EXPONENT_1:
5344 len =
5345 ((biginteger_t *)OBJ_PRI_RSA_EXPO1(key))->big_value_len;
5347 if (len > *value_len) {
5348 return (CKR_ATTRIBUTE_VALUE_INVALID);
5350 *value_len = len;
5352 if (*value_len == 0) {
5353 return (CKR_OK);
5356 (void) memcpy(value,
5357 ((biginteger_t *)OBJ_PRI_RSA_EXPO1(key))->big_value,
5358 *value_len);
5360 break;
5362 case CKA_EXPONENT_2:
5363 len =
5364 ((biginteger_t *)OBJ_PRI_RSA_EXPO2(key))->big_value_len;
5366 if (len > *value_len) {
5367 return (CKR_ATTRIBUTE_VALUE_INVALID);
5369 *value_len = len;
5371 if (*value_len == 0) {
5372 return (CKR_OK);
5375 (void) memcpy(value,
5376 ((biginteger_t *)OBJ_PRI_RSA_EXPO2(key))->big_value,
5377 *value_len);
5379 break;
5381 case CKA_COEFFICIENT:
5382 len =
5383 ((biginteger_t *)OBJ_PRI_RSA_COEF(key))->big_value_len;
5385 if (len > *value_len) {
5386 return (CKR_ATTRIBUTE_VALUE_INVALID);
5388 *value_len = len;
5390 if (*value_len == 0) {
5391 return (CKR_OK);
5394 (void) memcpy(value,
5395 ((biginteger_t *)OBJ_PRI_RSA_COEF(key))->big_value,
5396 *value_len);
5398 break;
5400 /* The following attributes belong to DSA and DH */
5401 case CKA_PRIME:
5403 if (key->key_type == CKK_DSA)
5404 len =
5405 ((biginteger_t *)OBJ_PRI_DSA_PRIME(key))->
5406 big_value_len;
5407 else
5408 len =
5409 ((biginteger_t *)OBJ_PRI_DH_PRIME(key))->
5410 big_value_len;
5412 /* This attribute MUST BE set */
5413 if (len == 0 || len > *value_len) {
5414 return (CKR_ATTRIBUTE_VALUE_INVALID);
5416 *value_len = len;
5418 if (key->key_type == CKK_DSA)
5419 (void) memcpy(value,
5420 ((biginteger_t *)OBJ_PRI_DSA_PRIME(key))->big_value,
5421 *value_len);
5422 else
5423 (void) memcpy(value,
5424 ((biginteger_t *)OBJ_PRI_DH_PRIME(key))->big_value,
5425 *value_len);
5427 break;
5429 case CKA_SUBPRIME:
5430 len =
5431 ((biginteger_t *)OBJ_PRI_DSA_SUBPRIME(key))->big_value_len;
5433 /* This attribute MUST BE set */
5434 if (len == 0 || len > *value_len) {
5435 return (CKR_ATTRIBUTE_VALUE_INVALID);
5437 *value_len = len;
5439 (void) memcpy(value,
5440 ((biginteger_t *)OBJ_PRI_DSA_SUBPRIME(key))->big_value,
5441 *value_len);
5443 break;
5445 case CKA_BASE:
5447 if (key->key_type == CKK_DSA)
5448 len =
5449 ((biginteger_t *)OBJ_PRI_DSA_BASE(key))->
5450 big_value_len;
5451 else
5452 len =
5453 ((biginteger_t *)OBJ_PRI_DH_BASE(key))->
5454 big_value_len;
5456 /* This attribute MUST BE set */
5457 if (len == 0 || len > *value_len) {
5458 return (CKR_ATTRIBUTE_VALUE_INVALID);
5460 *value_len = len;
5462 if (key->key_type == CKK_DSA)
5463 (void) memcpy(value,
5464 ((biginteger_t *)OBJ_PRI_DSA_BASE(key))->big_value,
5465 *value_len);
5466 else
5467 (void) memcpy(value,
5468 ((biginteger_t *)OBJ_PRI_DH_BASE(key))->big_value,
5469 *value_len);
5470 break;
5472 case CKA_VALUE:
5474 if (key->key_type == CKK_DSA) {
5475 len =
5476 ((biginteger_t *)OBJ_PRI_DSA_VALUE(key))->
5477 big_value_len;
5478 } else if (key->key_type == CKK_DH) {
5479 len =
5480 ((biginteger_t *)OBJ_PRI_DH_VALUE(key))->
5481 big_value_len;
5482 } else {
5483 len =
5484 ((biginteger_t *)OBJ_PRI_EC_VALUE(key))->
5485 big_value_len;
5488 /* This attribute MUST BE set */
5489 if (len == 0 || len > *value_len) {
5490 return (CKR_ATTRIBUTE_VALUE_INVALID);
5492 *value_len = len;
5494 if (key->key_type == CKK_DSA) {
5495 (void) memcpy(value,
5496 ((biginteger_t *)OBJ_PRI_DSA_VALUE(key))->big_value,
5497 *value_len);
5498 } else if (key->key_type == CKK_DH) {
5499 (void) memcpy(value,
5500 ((biginteger_t *)OBJ_PRI_DH_VALUE(key))->big_value,
5501 *value_len);
5502 } else {
5503 (void) memcpy(value,
5504 ((biginteger_t *)OBJ_PRI_EC_VALUE(key))->big_value,
5505 *value_len);
5508 break;
5511 return (CKR_OK);
5515 static CK_RV
5516 copy_bigint(biginteger_t *new_bigint, biginteger_t *old_bigint)
5518 new_bigint->big_value =
5519 malloc((sizeof (CK_BYTE) * new_bigint->big_value_len));
5521 if (new_bigint->big_value == NULL) {
5522 return (CKR_HOST_MEMORY);
5525 (void) memcpy(new_bigint->big_value, old_bigint->big_value,
5526 (sizeof (CK_BYTE) * new_bigint->big_value_len));
5528 return (CKR_OK);
5531 static void
5532 free_public_key_attr(public_key_obj_t *pbk, CK_KEY_TYPE key_type)
5534 if (pbk == NULL) {
5535 return;
5538 switch (key_type) {
5539 case CKK_RSA:
5540 bigint_attr_cleanup(KEY_PUB_RSA_MOD(pbk));
5541 bigint_attr_cleanup(KEY_PUB_RSA_PUBEXPO(pbk));
5542 break;
5543 case CKK_DSA:
5544 bigint_attr_cleanup(KEY_PUB_DSA_PRIME(pbk));
5545 bigint_attr_cleanup(KEY_PUB_DSA_SUBPRIME(pbk));
5546 bigint_attr_cleanup(KEY_PUB_DSA_BASE(pbk));
5547 bigint_attr_cleanup(KEY_PUB_DSA_VALUE(pbk));
5548 break;
5549 case CKK_DH:
5550 bigint_attr_cleanup(KEY_PUB_DH_PRIME(pbk));
5551 bigint_attr_cleanup(KEY_PUB_DH_BASE(pbk));
5552 bigint_attr_cleanup(KEY_PUB_DH_VALUE(pbk));
5553 break;
5554 case CKK_EC:
5555 bigint_attr_cleanup(KEY_PUB_EC_POINT(pbk));
5556 break;
5557 case CKK_X9_42_DH:
5558 bigint_attr_cleanup(KEY_PUB_DH942_PRIME(pbk));
5559 bigint_attr_cleanup(KEY_PUB_DH942_SUBPRIME(pbk));
5560 bigint_attr_cleanup(KEY_PUB_DH942_BASE(pbk));
5561 bigint_attr_cleanup(KEY_PUB_DH942_VALUE(pbk));
5562 break;
5563 default:
5564 break;
5566 free(pbk);
5569 CK_RV
5570 soft_copy_public_key_attr(public_key_obj_t *old_pub_key_obj_p,
5571 public_key_obj_t **new_pub_key_obj_p, CK_KEY_TYPE key_type)
5574 public_key_obj_t *pbk;
5575 CK_RV rv = CKR_OK;
5577 pbk = calloc(1, sizeof (public_key_obj_t));
5578 if (pbk == NULL) {
5579 return (CKR_HOST_MEMORY);
5582 switch (key_type) {
5583 case CKK_RSA:
5584 (void) memcpy(KEY_PUB_RSA(pbk),
5585 KEY_PUB_RSA(old_pub_key_obj_p),
5586 sizeof (rsa_pub_key_t));
5587 /* copy modulus */
5588 rv = copy_bigint(KEY_PUB_RSA_MOD(pbk),
5589 KEY_PUB_RSA_MOD(old_pub_key_obj_p));
5590 if (rv != CKR_OK) {
5591 free_public_key_attr(pbk, key_type);
5592 return (rv);
5594 /* copy public exponent */
5595 rv = copy_bigint(KEY_PUB_RSA_PUBEXPO(pbk),
5596 KEY_PUB_RSA_PUBEXPO(old_pub_key_obj_p));
5597 if (rv != CKR_OK) {
5598 free_public_key_attr(pbk, key_type);
5599 return (rv);
5601 break;
5602 case CKK_DSA:
5603 (void) memcpy(KEY_PUB_DSA(pbk),
5604 KEY_PUB_DSA(old_pub_key_obj_p),
5605 sizeof (dsa_pub_key_t));
5607 /* copy prime */
5608 rv = copy_bigint(KEY_PUB_DSA_PRIME(pbk),
5609 KEY_PUB_DSA_PRIME(old_pub_key_obj_p));
5610 if (rv != CKR_OK) {
5611 free_public_key_attr(pbk, key_type);
5612 return (rv);
5615 /* copy subprime */
5616 rv = copy_bigint(KEY_PUB_DSA_SUBPRIME(pbk),
5617 KEY_PUB_DSA_SUBPRIME(old_pub_key_obj_p));
5618 if (rv != CKR_OK) {
5619 free_public_key_attr(pbk, key_type);
5620 return (rv);
5623 /* copy base */
5624 rv = copy_bigint(KEY_PUB_DSA_BASE(pbk),
5625 KEY_PUB_DSA_BASE(old_pub_key_obj_p));
5626 if (rv != CKR_OK) {
5627 free_public_key_attr(pbk, key_type);
5628 return (rv);
5631 /* copy value */
5632 rv = copy_bigint(KEY_PUB_DSA_VALUE(pbk),
5633 KEY_PUB_DSA_VALUE(old_pub_key_obj_p));
5634 if (rv != CKR_OK) {
5635 free_public_key_attr(pbk, key_type);
5636 return (rv);
5638 break;
5639 case CKK_DH:
5640 (void) memcpy(KEY_PUB_DH(pbk),
5641 KEY_PUB_DH(old_pub_key_obj_p),
5642 sizeof (dh_pub_key_t));
5644 /* copy prime */
5645 rv = copy_bigint(KEY_PUB_DH_PRIME(pbk),
5646 KEY_PUB_DH_PRIME(old_pub_key_obj_p));
5647 if (rv != CKR_OK) {
5648 free_public_key_attr(pbk, key_type);
5649 return (rv);
5652 /* copy base */
5653 rv = copy_bigint(KEY_PUB_DH_BASE(pbk),
5654 KEY_PUB_DH_BASE(old_pub_key_obj_p));
5655 if (rv != CKR_OK) {
5656 free_public_key_attr(pbk, key_type);
5657 return (rv);
5660 /* copy value */
5661 rv = copy_bigint(KEY_PUB_DH_VALUE(pbk),
5662 KEY_PUB_DH_VALUE(old_pub_key_obj_p));
5663 if (rv != CKR_OK) {
5664 free_public_key_attr(pbk, key_type);
5665 return (rv);
5667 break;
5668 case CKK_EC:
5669 (void) memcpy(KEY_PUB_EC(pbk),
5670 KEY_PUB_EC(old_pub_key_obj_p),
5671 sizeof (ec_pub_key_t));
5673 /* copy point */
5674 rv = copy_bigint(KEY_PUB_EC_POINT(pbk),
5675 KEY_PUB_EC_POINT(old_pub_key_obj_p));
5676 if (rv != CKR_OK) {
5677 free_public_key_attr(pbk, key_type);
5678 return (rv);
5680 break;
5681 case CKK_X9_42_DH:
5682 (void) memcpy(KEY_PUB_DH942(pbk),
5683 KEY_PUB_DH942(old_pub_key_obj_p),
5684 sizeof (dh942_pub_key_t));
5686 /* copy prime */
5687 rv = copy_bigint(KEY_PUB_DH942_PRIME(pbk),
5688 KEY_PUB_DH942_PRIME(old_pub_key_obj_p));
5689 if (rv != CKR_OK) {
5690 free_public_key_attr(pbk, key_type);
5691 return (rv);
5694 /* copy subprime */
5695 rv = copy_bigint(KEY_PUB_DH942_SUBPRIME(pbk),
5696 KEY_PUB_DH942_SUBPRIME(old_pub_key_obj_p));
5697 if (rv != CKR_OK) {
5698 free_public_key_attr(pbk, key_type);
5699 return (rv);
5702 /* copy base */
5703 rv = copy_bigint(KEY_PUB_DH942_BASE(pbk),
5704 KEY_PUB_DH942_BASE(old_pub_key_obj_p));
5705 if (rv != CKR_OK) {
5706 free_public_key_attr(pbk, key_type);
5707 return (rv);
5710 /* copy value */
5711 rv = copy_bigint(KEY_PUB_DH942_VALUE(pbk),
5712 KEY_PUB_DH942_VALUE(old_pub_key_obj_p));
5713 if (rv != CKR_OK) {
5714 free_public_key_attr(pbk, key_type);
5715 return (rv);
5717 break;
5718 default:
5719 break;
5721 *new_pub_key_obj_p = pbk;
5722 return (rv);
5725 static void
5726 free_private_key_attr(private_key_obj_t *pbk, CK_KEY_TYPE key_type)
5728 if (pbk == NULL) {
5729 return;
5732 switch (key_type) {
5733 case CKK_RSA:
5734 bigint_attr_cleanup(KEY_PRI_RSA_MOD(pbk));
5735 bigint_attr_cleanup(KEY_PRI_RSA_PUBEXPO(pbk));
5736 bigint_attr_cleanup(KEY_PRI_RSA_PRIEXPO(pbk));
5737 bigint_attr_cleanup(KEY_PRI_RSA_PRIME1(pbk));
5738 bigint_attr_cleanup(KEY_PRI_RSA_PRIME2(pbk));
5739 bigint_attr_cleanup(KEY_PRI_RSA_EXPO1(pbk));
5740 bigint_attr_cleanup(KEY_PRI_RSA_EXPO2(pbk));
5741 bigint_attr_cleanup(KEY_PRI_RSA_COEF(pbk));
5742 break;
5743 case CKK_DSA:
5744 bigint_attr_cleanup(KEY_PRI_DSA_PRIME(pbk));
5745 bigint_attr_cleanup(KEY_PRI_DSA_SUBPRIME(pbk));
5746 bigint_attr_cleanup(KEY_PRI_DSA_BASE(pbk));
5747 bigint_attr_cleanup(KEY_PRI_DSA_VALUE(pbk));
5748 break;
5749 case CKK_DH:
5750 bigint_attr_cleanup(KEY_PRI_DH_PRIME(pbk));
5751 bigint_attr_cleanup(KEY_PRI_DH_BASE(pbk));
5752 bigint_attr_cleanup(KEY_PRI_DH_VALUE(pbk));
5753 break;
5754 case CKK_EC:
5755 bigint_attr_cleanup(KEY_PRI_EC_VALUE(pbk));
5756 break;
5757 case CKK_X9_42_DH:
5758 bigint_attr_cleanup(KEY_PRI_DH942_PRIME(pbk));
5759 bigint_attr_cleanup(KEY_PRI_DH942_SUBPRIME(pbk));
5760 bigint_attr_cleanup(KEY_PRI_DH942_BASE(pbk));
5761 bigint_attr_cleanup(KEY_PRI_DH942_VALUE(pbk));
5762 break;
5763 default:
5764 break;
5766 free(pbk);
5769 CK_RV
5770 soft_copy_private_key_attr(private_key_obj_t *old_pri_key_obj_p,
5771 private_key_obj_t **new_pri_key_obj_p, CK_KEY_TYPE key_type)
5773 CK_RV rv = CKR_OK;
5774 private_key_obj_t *pbk;
5776 pbk = calloc(1, sizeof (private_key_obj_t));
5777 if (pbk == NULL) {
5778 return (CKR_HOST_MEMORY);
5781 switch (key_type) {
5782 case CKK_RSA:
5783 (void) memcpy(KEY_PRI_RSA(pbk),
5784 KEY_PRI_RSA(old_pri_key_obj_p),
5785 sizeof (rsa_pri_key_t));
5786 /* copy modulus */
5787 rv = copy_bigint(KEY_PRI_RSA_MOD(pbk),
5788 KEY_PRI_RSA_MOD(old_pri_key_obj_p));
5789 if (rv != CKR_OK) {
5790 free_private_key_attr(pbk, key_type);
5791 return (rv);
5793 /* copy public exponent */
5794 rv = copy_bigint(KEY_PRI_RSA_PUBEXPO(pbk),
5795 KEY_PRI_RSA_PUBEXPO(old_pri_key_obj_p));
5796 if (rv != CKR_OK) {
5797 free_private_key_attr(pbk, key_type);
5798 return (rv);
5800 /* copy private exponent */
5801 rv = copy_bigint(KEY_PRI_RSA_PRIEXPO(pbk),
5802 KEY_PRI_RSA_PRIEXPO(old_pri_key_obj_p));
5803 if (rv != CKR_OK) {
5804 free_private_key_attr(pbk, key_type);
5805 return (rv);
5807 /* copy prime_1 */
5808 rv = copy_bigint(KEY_PRI_RSA_PRIME1(pbk),
5809 KEY_PRI_RSA_PRIME1(old_pri_key_obj_p));
5810 if (rv != CKR_OK) {
5811 free_private_key_attr(pbk, key_type);
5812 return (rv);
5814 /* copy prime_2 */
5815 rv = copy_bigint(KEY_PRI_RSA_PRIME2(pbk),
5816 KEY_PRI_RSA_PRIME2(old_pri_key_obj_p));
5817 if (rv != CKR_OK) {
5818 free_private_key_attr(pbk, key_type);
5819 return (rv);
5821 /* copy exponent_1 */
5822 rv = copy_bigint(KEY_PRI_RSA_EXPO1(pbk),
5823 KEY_PRI_RSA_EXPO1(old_pri_key_obj_p));
5824 if (rv != CKR_OK) {
5825 free_private_key_attr(pbk, key_type);
5826 return (rv);
5828 /* copy exponent_2 */
5829 rv = copy_bigint(KEY_PRI_RSA_EXPO2(pbk),
5830 KEY_PRI_RSA_EXPO2(old_pri_key_obj_p));
5831 if (rv != CKR_OK) {
5832 free_private_key_attr(pbk, key_type);
5833 return (rv);
5835 /* copy coefficient */
5836 rv = copy_bigint(KEY_PRI_RSA_COEF(pbk),
5837 KEY_PRI_RSA_COEF(old_pri_key_obj_p));
5838 if (rv != CKR_OK) {
5839 free_private_key_attr(pbk, key_type);
5840 return (rv);
5842 break;
5843 case CKK_DSA:
5844 (void) memcpy(KEY_PRI_DSA(pbk),
5845 KEY_PRI_DSA(old_pri_key_obj_p),
5846 sizeof (dsa_pri_key_t));
5848 /* copy prime */
5849 rv = copy_bigint(KEY_PRI_DSA_PRIME(pbk),
5850 KEY_PRI_DSA_PRIME(old_pri_key_obj_p));
5851 if (rv != CKR_OK) {
5852 free_private_key_attr(pbk, key_type);
5853 return (rv);
5856 /* copy subprime */
5857 rv = copy_bigint(KEY_PRI_DSA_SUBPRIME(pbk),
5858 KEY_PRI_DSA_SUBPRIME(old_pri_key_obj_p));
5859 if (rv != CKR_OK) {
5860 free_private_key_attr(pbk, key_type);
5861 return (rv);
5864 /* copy base */
5865 rv = copy_bigint(KEY_PRI_DSA_BASE(pbk),
5866 KEY_PRI_DSA_BASE(old_pri_key_obj_p));
5867 if (rv != CKR_OK) {
5868 free_private_key_attr(pbk, key_type);
5869 return (rv);
5872 /* copy value */
5873 rv = copy_bigint(KEY_PRI_DSA_VALUE(pbk),
5874 KEY_PRI_DSA_VALUE(old_pri_key_obj_p));
5875 if (rv != CKR_OK) {
5876 free_private_key_attr(pbk, key_type);
5877 return (rv);
5879 break;
5880 case CKK_DH:
5881 (void) memcpy(KEY_PRI_DH(pbk),
5882 KEY_PRI_DH(old_pri_key_obj_p),
5883 sizeof (dh_pri_key_t));
5885 /* copy prime */
5886 rv = copy_bigint(KEY_PRI_DH_PRIME(pbk),
5887 KEY_PRI_DH_PRIME(old_pri_key_obj_p));
5888 if (rv != CKR_OK) {
5889 free_private_key_attr(pbk, key_type);
5890 return (rv);
5893 /* copy base */
5894 rv = copy_bigint(KEY_PRI_DH_BASE(pbk),
5895 KEY_PRI_DH_BASE(old_pri_key_obj_p));
5896 if (rv != CKR_OK) {
5897 free_private_key_attr(pbk, key_type);
5898 return (rv);
5901 /* copy value */
5902 rv = copy_bigint(KEY_PRI_DH_VALUE(pbk),
5903 KEY_PRI_DH_VALUE(old_pri_key_obj_p));
5904 if (rv != CKR_OK) {
5905 free_private_key_attr(pbk, key_type);
5906 return (rv);
5908 break;
5909 case CKK_EC:
5910 (void) memcpy(KEY_PRI_EC(pbk),
5911 KEY_PRI_EC(old_pri_key_obj_p),
5912 sizeof (ec_pri_key_t));
5914 /* copy value */
5915 rv = copy_bigint(KEY_PRI_EC_VALUE(pbk),
5916 KEY_PRI_EC_VALUE(old_pri_key_obj_p));
5917 if (rv != CKR_OK) {
5918 free_private_key_attr(pbk, key_type);
5919 return (rv);
5921 break;
5922 case CKK_X9_42_DH:
5923 (void) memcpy(KEY_PRI_DH942(pbk),
5924 KEY_PRI_DH942(old_pri_key_obj_p),
5925 sizeof (dh942_pri_key_t));
5927 /* copy prime */
5928 rv = copy_bigint(KEY_PRI_DH942_PRIME(pbk),
5929 KEY_PRI_DH942_PRIME(old_pri_key_obj_p));
5930 if (rv != CKR_OK) {
5931 free_private_key_attr(pbk, key_type);
5932 return (rv);
5935 /* copy subprime */
5936 rv = copy_bigint(KEY_PRI_DH942_SUBPRIME(pbk),
5937 KEY_PRI_DH942_SUBPRIME(old_pri_key_obj_p));
5938 if (rv != CKR_OK) {
5939 free_private_key_attr(pbk, key_type);
5940 return (rv);
5943 /* copy base */
5944 rv = copy_bigint(KEY_PRI_DH942_BASE(pbk),
5945 KEY_PRI_DH942_BASE(old_pri_key_obj_p));
5946 if (rv != CKR_OK) {
5947 free_private_key_attr(pbk, key_type);
5948 return (rv);
5951 /* copy value */
5952 rv = copy_bigint(KEY_PRI_DH942_VALUE(pbk),
5953 KEY_PRI_DH942_VALUE(old_pri_key_obj_p));
5954 if (rv != CKR_OK) {
5955 free_private_key_attr(pbk, key_type);
5956 return (rv);
5958 break;
5959 default:
5960 break;
5962 *new_pri_key_obj_p = pbk;
5963 return (rv);
5966 static void
5967 free_domain_attr(domain_obj_t *domain, CK_KEY_TYPE key_type)
5969 if (domain == NULL) {
5970 return;
5973 switch (key_type) {
5974 case CKK_DSA:
5975 bigint_attr_cleanup(KEY_DOM_DSA_PRIME(domain));
5976 bigint_attr_cleanup(KEY_DOM_DSA_SUBPRIME(domain));
5977 bigint_attr_cleanup(KEY_DOM_DSA_BASE(domain));
5978 break;
5979 case CKK_DH:
5980 bigint_attr_cleanup(KEY_DOM_DH_PRIME(domain));
5981 bigint_attr_cleanup(KEY_DOM_DH_BASE(domain));
5982 break;
5983 case CKK_X9_42_DH:
5984 bigint_attr_cleanup(KEY_DOM_DH942_PRIME(domain));
5985 bigint_attr_cleanup(KEY_DOM_DH942_SUBPRIME(domain));
5986 bigint_attr_cleanup(KEY_DOM_DH942_BASE(domain));
5987 break;
5988 default:
5989 break;
5991 free(domain);
5994 CK_RV
5995 soft_copy_domain_attr(domain_obj_t *old_domain_obj_p,
5996 domain_obj_t **new_domain_obj_p, CK_KEY_TYPE key_type)
5998 CK_RV rv = CKR_OK;
5999 domain_obj_t *domain;
6001 domain = calloc(1, sizeof (domain_obj_t));
6002 if (domain == NULL) {
6003 return (CKR_HOST_MEMORY);
6006 switch (key_type) {
6007 case CKK_DSA:
6008 (void) memcpy(KEY_DOM_DSA(domain),
6009 KEY_DOM_DSA(old_domain_obj_p),
6010 sizeof (dsa_dom_key_t));
6012 /* copy prime */
6013 rv = copy_bigint(KEY_DOM_DSA_PRIME(domain),
6014 KEY_DOM_DSA_PRIME(old_domain_obj_p));
6015 if (rv != CKR_OK) {
6016 free_domain_attr(domain, key_type);
6017 return (rv);
6020 /* copy subprime */
6021 rv = copy_bigint(KEY_DOM_DSA_SUBPRIME(domain),
6022 KEY_DOM_DSA_SUBPRIME(old_domain_obj_p));
6023 if (rv != CKR_OK) {
6024 free_domain_attr(domain, key_type);
6025 return (rv);
6028 /* copy base */
6029 rv = copy_bigint(KEY_DOM_DSA_BASE(domain),
6030 KEY_DOM_DSA_BASE(old_domain_obj_p));
6031 if (rv != CKR_OK) {
6032 free_domain_attr(domain, key_type);
6033 return (rv);
6036 break;
6037 case CKK_DH:
6038 (void) memcpy(KEY_DOM_DH(domain),
6039 KEY_DOM_DH(old_domain_obj_p),
6040 sizeof (dh_dom_key_t));
6042 /* copy prime */
6043 rv = copy_bigint(KEY_DOM_DH_PRIME(domain),
6044 KEY_DOM_DH_PRIME(old_domain_obj_p));
6045 if (rv != CKR_OK) {
6046 free_domain_attr(domain, key_type);
6047 return (rv);
6050 /* copy base */
6051 rv = copy_bigint(KEY_DOM_DH_BASE(domain),
6052 KEY_DOM_DH_BASE(old_domain_obj_p));
6053 if (rv != CKR_OK) {
6054 free_domain_attr(domain, key_type);
6055 return (rv);
6058 break;
6059 case CKK_X9_42_DH:
6060 (void) memcpy(KEY_DOM_DH942(domain),
6061 KEY_DOM_DH942(old_domain_obj_p),
6062 sizeof (dh942_dom_key_t));
6064 /* copy prime */
6065 rv = copy_bigint(KEY_DOM_DH942_PRIME(domain),
6066 KEY_DOM_DH942_PRIME(old_domain_obj_p));
6067 if (rv != CKR_OK) {
6068 free_domain_attr(domain, key_type);
6069 return (rv);
6072 /* copy subprime */
6073 rv = copy_bigint(KEY_DOM_DH942_SUBPRIME(domain),
6074 KEY_DOM_DH942_SUBPRIME(old_domain_obj_p));
6075 if (rv != CKR_OK) {
6076 free_domain_attr(domain, key_type);
6077 return (rv);
6080 /* copy base */
6081 rv = copy_bigint(KEY_DOM_DH942_BASE(domain),
6082 KEY_DOM_DH942_BASE(old_domain_obj_p));
6083 if (rv != CKR_OK) {
6084 free_domain_attr(domain, key_type);
6085 return (rv);
6088 break;
6089 default:
6090 break;
6092 *new_domain_obj_p = domain;
6093 return (rv);
6096 CK_RV
6097 soft_copy_secret_key_attr(secret_key_obj_t *old_secret_key_obj_p,
6098 secret_key_obj_t **new_secret_key_obj_p)
6100 secret_key_obj_t *sk;
6102 sk = malloc(sizeof (secret_key_obj_t));
6103 if (sk == NULL) {
6104 return (CKR_HOST_MEMORY);
6106 (void) memcpy(sk, old_secret_key_obj_p, sizeof (secret_key_obj_t));
6108 /* copy the secret key value */
6109 sk->sk_value = malloc(sk->sk_value_len);
6110 if (sk->sk_value == NULL) {
6111 free(sk);
6112 return (CKR_HOST_MEMORY);
6114 (void) memcpy(sk->sk_value, old_secret_key_obj_p->sk_value,
6115 (sizeof (CK_BYTE) * sk->sk_value_len));
6118 * Copy the pre-expanded key schedule.
6120 if (old_secret_key_obj_p->key_sched != NULL &&
6121 old_secret_key_obj_p->keysched_len > 0) {
6122 sk->key_sched = malloc(old_secret_key_obj_p->keysched_len);
6123 if (sk->key_sched == NULL) {
6124 freezero(sk->sk_value, sk->sk_value_len);
6125 free(sk);
6126 return (CKR_HOST_MEMORY);
6128 sk->keysched_len = old_secret_key_obj_p->keysched_len;
6129 (void) memcpy(sk->key_sched, old_secret_key_obj_p->key_sched,
6130 sk->keysched_len);
6133 *new_secret_key_obj_p = sk;
6135 return (CKR_OK);
6139 * If CKA_CLASS not given, guess CKA_CLASS using
6140 * attributes on template .
6142 * Some attributes are specific to an object class. If one or more
6143 * of these attributes are in the template, make a list of classes
6144 * that can have these attributes. This would speed up the search later,
6145 * because we can immediately skip an object if the class of that
6146 * object can not possibly contain one of the attributes.
6149 void
6150 soft_process_find_attr(CK_OBJECT_CLASS *pclasses,
6151 CK_ULONG *num_result_pclasses, CK_ATTRIBUTE_PTR pTemplate,
6152 CK_ULONG ulCount)
6154 ulong_t i;
6155 int j;
6156 boolean_t pub_found = B_FALSE,
6157 priv_found = B_FALSE,
6158 secret_found = B_FALSE,
6159 domain_found = B_FALSE,
6160 hardware_found = B_FALSE,
6161 cert_found = B_FALSE;
6162 int num_pub_key_attrs, num_priv_key_attrs,
6163 num_secret_key_attrs, num_domain_attrs,
6164 num_hardware_attrs, num_cert_attrs;
6165 int num_pclasses = 0;
6167 for (i = 0; i < ulCount; i++) {
6168 if (pTemplate[i].type == CKA_CLASS) {
6170 * don't need to guess the class, it is specified.
6171 * Just record the class, and return.
6173 pclasses[0] =
6174 (*((CK_OBJECT_CLASS *)pTemplate[i].pValue));
6175 *num_result_pclasses = 1;
6176 return;
6180 num_pub_key_attrs =
6181 sizeof (PUB_KEY_ATTRS) / sizeof (CK_ATTRIBUTE_TYPE);
6182 num_priv_key_attrs =
6183 sizeof (PRIV_KEY_ATTRS) / sizeof (CK_ATTRIBUTE_TYPE);
6184 num_secret_key_attrs =
6185 sizeof (SECRET_KEY_ATTRS) / sizeof (CK_ATTRIBUTE_TYPE);
6186 num_domain_attrs =
6187 sizeof (DOMAIN_ATTRS) / sizeof (CK_ATTRIBUTE_TYPE);
6188 num_hardware_attrs =
6189 sizeof (HARDWARE_ATTRS) / sizeof (CK_ATTRIBUTE_TYPE);
6190 num_cert_attrs =
6191 sizeof (CERT_ATTRS) / sizeof (CK_ATTRIBUTE_TYPE);
6194 * Get the list of objects class that might contain
6195 * some attributes.
6197 for (i = 0; i < ulCount; i++) {
6199 * only check if this attribute can belong to public key object
6200 * class if public key object isn't already in the list
6202 if (!pub_found) {
6203 for (j = 0; j < num_pub_key_attrs; j++) {
6204 if (pTemplate[i].type == PUB_KEY_ATTRS[j]) {
6205 pub_found = B_TRUE;
6206 pclasses[num_pclasses++] =
6207 CKO_PUBLIC_KEY;
6208 break;
6213 if (!priv_found) {
6214 for (j = 0; j < num_priv_key_attrs; j++) {
6215 if (pTemplate[i].type == PRIV_KEY_ATTRS[j]) {
6216 priv_found = B_TRUE;
6217 pclasses[num_pclasses++] =
6218 CKO_PRIVATE_KEY;
6219 break;
6224 if (!secret_found) {
6225 for (j = 0; j < num_secret_key_attrs; j++) {
6226 if (pTemplate[i].type == SECRET_KEY_ATTRS[j]) {
6227 secret_found = B_TRUE;
6228 pclasses[num_pclasses++] =
6229 CKO_SECRET_KEY;
6230 break;
6235 if (!domain_found) {
6236 for (j = 0; j < num_domain_attrs; j++) {
6237 if (pTemplate[i].type == DOMAIN_ATTRS[j]) {
6238 domain_found = B_TRUE;
6239 pclasses[num_pclasses++] =
6240 CKO_DOMAIN_PARAMETERS;
6241 break;
6246 if (!hardware_found) {
6247 for (j = 0; j < num_hardware_attrs; j++) {
6248 if (pTemplate[i].type == HARDWARE_ATTRS[j]) {
6249 hardware_found = B_TRUE;
6250 pclasses[num_pclasses++] =
6251 CKO_HW_FEATURE;
6252 break;
6257 if (!cert_found) {
6258 for (j = 0; j < num_cert_attrs; j++) {
6259 if (pTemplate[i].type == CERT_ATTRS[j]) {
6260 cert_found = B_TRUE;
6261 pclasses[num_pclasses++] =
6262 CKO_CERTIFICATE;
6263 break;
6268 *num_result_pclasses = num_pclasses;
6271 boolean_t
6272 soft_find_match_attrs(soft_object_t *obj, CK_OBJECT_CLASS *pclasses,
6273 CK_ULONG num_pclasses, CK_ATTRIBUTE *template, CK_ULONG num_attr)
6275 ulong_t i;
6276 CK_ATTRIBUTE *tmpl_attr, *obj_attr;
6277 cert_attr_t *cert_attr;
6278 uint64_t attr_mask;
6279 biginteger_t *bigint;
6280 boolean_t compare_attr, compare_bigint, compare_boolean;
6281 boolean_t compare_cert_val, compare_cert_type;
6284 * Check if the class of this object match with any
6285 * of object classes that can possibly contain the
6286 * requested attributes.
6288 if (num_pclasses > 0) {
6289 for (i = 0; i < num_pclasses; i++) {
6290 if (obj->class == pclasses[i]) {
6291 break;
6294 if (i == num_pclasses) {
6296 * this object can't possibly contain one or
6297 * more attributes, don't need to check this object
6299 return (B_FALSE);
6303 /* need to examine everything */
6304 for (i = 0; i < num_attr; i++) {
6305 tmpl_attr = &(template[i]);
6306 compare_attr = B_FALSE;
6307 compare_bigint = B_FALSE;
6308 compare_boolean = B_FALSE;
6309 compare_cert_val = B_FALSE;
6310 compare_cert_type = B_FALSE;
6311 switch (tmpl_attr->type) {
6312 /* First, check the most common attributes */
6313 case CKA_CLASS:
6314 if (*((CK_OBJECT_CLASS *)tmpl_attr->pValue) !=
6315 obj->class) {
6316 return (B_FALSE);
6318 break;
6319 case CKA_KEY_TYPE:
6320 if (*((CK_KEY_TYPE *)tmpl_attr->pValue) !=
6321 obj->key_type) {
6322 return (B_FALSE);
6324 break;
6325 case CKA_ENCRYPT:
6326 attr_mask = (obj->bool_attr_mask) & ENCRYPT_BOOL_ON;
6327 compare_boolean = B_TRUE;
6328 break;
6329 case CKA_DECRYPT:
6330 attr_mask = (obj->bool_attr_mask) & DECRYPT_BOOL_ON;
6331 compare_boolean = B_TRUE;
6332 break;
6333 case CKA_WRAP:
6334 attr_mask = (obj->bool_attr_mask) & WRAP_BOOL_ON;
6335 compare_boolean = B_TRUE;
6336 break;
6337 case CKA_UNWRAP:
6338 attr_mask = (obj->bool_attr_mask) & UNWRAP_BOOL_ON;
6339 compare_boolean = B_TRUE;
6340 break;
6341 case CKA_SIGN:
6342 attr_mask = (obj->bool_attr_mask) & SIGN_BOOL_ON;
6343 compare_boolean = B_TRUE;
6344 break;
6345 case CKA_SIGN_RECOVER:
6346 attr_mask = (obj->bool_attr_mask) &
6347 SIGN_RECOVER_BOOL_ON;
6348 compare_boolean = B_TRUE;
6349 break;
6350 case CKA_VERIFY:
6351 attr_mask = (obj->bool_attr_mask) & VERIFY_BOOL_ON;
6352 compare_boolean = B_TRUE;
6353 break;
6354 case CKA_VERIFY_RECOVER:
6355 attr_mask = (obj->bool_attr_mask) &
6356 VERIFY_RECOVER_BOOL_ON;
6357 compare_boolean = B_TRUE;
6358 break;
6359 case CKA_DERIVE:
6360 attr_mask = (obj->bool_attr_mask) & DERIVE_BOOL_ON;
6361 compare_boolean = B_TRUE;
6362 break;
6363 case CKA_LOCAL:
6364 attr_mask = (obj->bool_attr_mask) & LOCAL_BOOL_ON;
6365 compare_boolean = B_TRUE;
6366 break;
6367 case CKA_SENSITIVE:
6368 attr_mask = (obj->bool_attr_mask) & SENSITIVE_BOOL_ON;
6369 compare_boolean = B_TRUE;
6370 break;
6371 case CKA_SECONDARY_AUTH:
6372 attr_mask = (obj->bool_attr_mask) &
6373 SECONDARY_AUTH_BOOL_ON;
6374 compare_boolean = B_TRUE;
6375 break;
6376 case CKA_TRUSTED:
6377 attr_mask = (obj->bool_attr_mask) & TRUSTED_BOOL_ON;
6378 compare_boolean = B_TRUE;
6379 break;
6380 case CKA_EXTRACTABLE:
6381 attr_mask = (obj->bool_attr_mask) &
6382 EXTRACTABLE_BOOL_ON;
6383 compare_boolean = B_TRUE;
6384 break;
6385 case CKA_ALWAYS_SENSITIVE:
6386 attr_mask = (obj->bool_attr_mask) &
6387 ALWAYS_SENSITIVE_BOOL_ON;
6388 compare_boolean = B_TRUE;
6389 break;
6390 case CKA_NEVER_EXTRACTABLE:
6391 attr_mask = (obj->bool_attr_mask) &
6392 NEVER_EXTRACTABLE_BOOL_ON;
6393 compare_boolean = B_TRUE;
6394 break;
6395 case CKA_TOKEN:
6396 attr_mask = (obj->object_type) & TOKEN_OBJECT;
6397 compare_boolean = B_TRUE;
6398 break;
6399 case CKA_PRIVATE:
6400 attr_mask = (obj->object_type) & PRIVATE_OBJECT;
6401 compare_boolean = B_TRUE;
6402 break;
6403 case CKA_MODIFIABLE:
6405 CK_BBOOL bval;
6406 attr_mask = (obj->bool_attr_mask) &
6407 NOT_MODIFIABLE_BOOL_ON;
6409 if (attr_mask) {
6410 bval = FALSE;
6411 } else {
6412 bval = TRUE;
6414 if (bval != *((CK_BBOOL *)tmpl_attr->pValue)) {
6415 return (B_FALSE);
6417 break;
6419 case CKA_OWNER:
6421 * For X.509 attribute certificate object, get its
6422 * CKA_OWNER attribute from the x509_attr_cert_t struct.
6424 if ((obj->class == CKO_CERTIFICATE) &&
6425 (obj->cert_type == CKC_X_509_ATTR_CERT)) {
6426 cert_attr = X509_ATTR_CERT_OWNER(obj);
6427 compare_cert_val = B_TRUE;
6429 break;
6430 case CKA_SUBJECT:
6432 * For X.509 certificate object, get its CKA_SUBJECT
6433 * attribute from the x509_cert_t struct (not from
6434 * the extra_attrlistp).
6436 if ((obj->class == CKO_CERTIFICATE) &&
6437 (obj->cert_type == CKC_X_509)) {
6438 cert_attr = X509_CERT_SUBJECT(obj);
6439 compare_cert_val = B_TRUE;
6440 break;
6442 /*FALLTHRU*/
6443 case CKA_ID:
6444 case CKA_START_DATE:
6445 case CKA_END_DATE:
6446 case CKA_KEY_GEN_MECHANISM:
6447 case CKA_LABEL:
6448 case CKA_ISSUER:
6449 case CKA_SERIAL_NUMBER:
6450 case CKA_AC_ISSUER:
6451 case CKA_ATTR_TYPES:
6452 /* find these attributes from extra_attrlistp */
6453 obj_attr = get_extra_attr(tmpl_attr->type, obj);
6454 compare_attr = B_TRUE;
6455 break;
6456 case CKA_CERTIFICATE_TYPE:
6457 compare_cert_type = B_TRUE;
6458 break;
6459 case CKA_VALUE_LEN:
6460 /* only secret key has this attribute */
6461 if (obj->class == CKO_SECRET_KEY) {
6462 if (*((CK_ULONG *)tmpl_attr->pValue) !=
6463 OBJ_SEC_VALUE_LEN(obj)) {
6464 return (B_FALSE);
6466 } else {
6467 return (B_FALSE);
6469 break;
6470 case CKA_VALUE:
6471 switch (obj->class) {
6472 case CKO_SECRET_KEY:
6474 * secret_key_obj_t is the same as
6475 * biginteger_t
6477 bigint = (biginteger_t *)OBJ_SEC(obj);
6478 compare_bigint = B_TRUE;
6479 break;
6480 case CKO_PRIVATE_KEY:
6481 if (obj->key_type == CKK_DSA) {
6482 bigint = OBJ_PRI_DSA_VALUE(obj);
6483 } else if (obj->key_type == CKK_DH) {
6484 bigint = OBJ_PRI_DH_VALUE(obj);
6485 } else if (obj->key_type == CKK_X9_42_DH) {
6486 bigint = OBJ_PRI_DH942_VALUE(obj);
6487 } else {
6488 return (B_FALSE);
6490 compare_bigint = B_TRUE;
6491 break;
6492 case CKO_PUBLIC_KEY:
6493 if (obj->key_type == CKK_DSA) {
6494 bigint = OBJ_PUB_DSA_VALUE(obj);
6495 } else if (obj->key_type == CKK_DH) {
6496 bigint = OBJ_PUB_DH_VALUE(obj);
6497 } else if (obj->key_type == CKK_X9_42_DH) {
6498 bigint = OBJ_PUB_DH942_VALUE(obj);
6499 } else {
6500 return (B_FALSE);
6502 compare_bigint = B_TRUE;
6503 break;
6504 case CKO_CERTIFICATE:
6505 if (obj->cert_type == CKC_X_509) {
6506 cert_attr = X509_CERT_VALUE(obj);
6507 } else if (obj->cert_type ==
6508 CKC_X_509_ATTR_CERT) {
6509 cert_attr = X509_ATTR_CERT_VALUE(obj);
6511 compare_cert_val = B_TRUE;
6512 break;
6513 default:
6514 return (B_FALSE);
6516 break;
6517 case CKA_MODULUS:
6518 /* only RSA public and private key have this attr */
6519 if (obj->key_type == CKK_RSA) {
6520 if (obj->class == CKO_PUBLIC_KEY) {
6521 bigint = OBJ_PUB_RSA_MOD(obj);
6522 } else if (obj->class == CKO_PRIVATE_KEY) {
6523 bigint = OBJ_PRI_RSA_MOD(obj);
6524 } else {
6525 return (B_FALSE);
6527 compare_bigint = B_TRUE;
6528 } else {
6529 return (B_FALSE);
6531 break;
6532 case CKA_MODULUS_BITS:
6533 /* only RSA public key has this attribute */
6534 if ((obj->key_type == CKK_RSA) &&
6535 (obj->class == CKO_PUBLIC_KEY)) {
6536 CK_ULONG mod_bits = OBJ_PUB_RSA_MOD_BITS(obj);
6537 if (mod_bits !=
6538 *((CK_ULONG *)tmpl_attr->pValue)) {
6539 return (B_FALSE);
6541 } else {
6542 return (B_FALSE);
6544 break;
6545 case CKA_PUBLIC_EXPONENT:
6546 /* only RSA public and private key have this attr */
6547 if (obj->key_type == CKK_RSA) {
6548 if (obj->class == CKO_PUBLIC_KEY) {
6549 bigint = OBJ_PUB_RSA_PUBEXPO(obj);
6550 } else if (obj->class == CKO_PRIVATE_KEY) {
6551 bigint = OBJ_PRI_RSA_PUBEXPO(obj);
6552 } else {
6553 return (B_FALSE);
6555 compare_bigint = B_TRUE;
6556 } else {
6557 return (B_FALSE);
6559 break;
6560 case CKA_PRIVATE_EXPONENT:
6561 /* only RSA private key has this attribute */
6562 if ((obj->key_type == CKK_RSA) &&
6563 (obj->class == CKO_PRIVATE_KEY)) {
6564 bigint = OBJ_PRI_RSA_PRIEXPO(obj);
6565 compare_bigint = B_TRUE;
6566 } else {
6567 return (B_FALSE);
6569 break;
6570 case CKA_PRIME_1:
6571 /* only RSA private key has this attribute */
6572 if ((obj->key_type == CKK_RSA) &&
6573 (obj->class == CKO_PRIVATE_KEY)) {
6574 bigint = OBJ_PRI_RSA_PRIME1(obj);
6575 compare_bigint = B_TRUE;
6576 } else {
6577 return (B_FALSE);
6579 break;
6580 case CKA_PRIME_2:
6581 /* only RSA private key has this attribute */
6582 if ((obj->key_type == CKK_RSA) &&
6583 (obj->class == CKO_PRIVATE_KEY)) {
6584 bigint = OBJ_PRI_RSA_PRIME2(obj);
6585 compare_bigint = B_TRUE;
6586 } else {
6587 return (B_FALSE);
6589 break;
6590 case CKA_EXPONENT_1:
6591 /* only RSA private key has this attribute */
6592 if ((obj->key_type == CKK_RSA) &&
6593 (obj->class == CKO_PRIVATE_KEY)) {
6594 bigint = OBJ_PRI_RSA_EXPO1(obj);
6595 compare_bigint = B_TRUE;
6596 } else {
6597 return (B_FALSE);
6599 break;
6600 case CKA_EXPONENT_2:
6601 /* only RSA private key has this attribute */
6602 if ((obj->key_type == CKK_RSA) &&
6603 (obj->class == CKO_PRIVATE_KEY)) {
6604 bigint = OBJ_PRI_RSA_EXPO2(obj);
6605 compare_bigint = B_TRUE;
6606 } else {
6607 return (B_FALSE);
6609 break;
6610 case CKA_COEFFICIENT:
6611 /* only RSA private key has this attribute */
6612 if ((obj->key_type == CKK_RSA) &&
6613 (obj->class == CKO_PRIVATE_KEY)) {
6614 bigint = OBJ_PRI_RSA_COEF(obj);
6615 compare_bigint = B_TRUE;
6616 } else {
6617 return (B_FALSE);
6619 break;
6620 case CKA_VALUE_BITS:
6621 /* only Diffie-Hellman private key has this attr */
6622 if ((obj->key_type == CKK_DH) &&
6623 (obj->class == CKO_PRIVATE_KEY)) {
6624 CK_ULONG val_bits = OBJ_PRI_DH_VAL_BITS(obj);
6625 if (val_bits !=
6626 *((CK_ULONG *)tmpl_attr->pValue)) {
6627 return (B_FALSE);
6629 } else {
6630 return (B_FALSE);
6632 break;
6633 case CKA_PRIME:
6634 if (obj->class == CKO_PUBLIC_KEY) {
6635 switch (obj->key_type) {
6636 case CKK_DSA:
6637 bigint = OBJ_PUB_DSA_PRIME(obj);
6638 break;
6639 case CKK_DH:
6640 bigint = OBJ_PUB_DH_PRIME(obj);
6641 break;
6642 case CKK_X9_42_DH:
6643 bigint = OBJ_PUB_DH942_PRIME(obj);
6644 break;
6645 default:
6646 return (B_FALSE);
6648 } else if (obj->class == CKO_PRIVATE_KEY) {
6649 switch (obj->key_type) {
6650 case CKK_DSA:
6651 bigint = OBJ_PRI_DSA_PRIME(obj);
6652 break;
6653 case CKK_DH:
6654 bigint = OBJ_PRI_DH_PRIME(obj);
6655 break;
6656 case CKK_X9_42_DH:
6657 bigint = OBJ_PRI_DH942_PRIME(obj);
6658 break;
6659 default:
6660 return (B_FALSE);
6662 } else if (obj->class == CKO_DOMAIN_PARAMETERS) {
6663 switch (obj->key_type) {
6664 case CKK_DSA:
6665 bigint = OBJ_DOM_DSA_PRIME(obj);
6666 break;
6667 case CKK_DH:
6668 bigint = OBJ_DOM_DH_PRIME(obj);
6669 break;
6670 case CKK_X9_42_DH:
6671 bigint = OBJ_DOM_DH942_PRIME(obj);
6672 break;
6673 default:
6674 return (B_FALSE);
6676 } else {
6677 return (B_FALSE);
6679 compare_bigint = B_TRUE;
6680 break;
6681 case CKA_SUBPRIME:
6682 if (obj->class == CKO_PUBLIC_KEY) {
6683 switch (obj->key_type) {
6684 case CKK_DSA:
6685 bigint = OBJ_PUB_DSA_SUBPRIME(obj);
6686 break;
6687 case CKK_X9_42_DH:
6688 bigint = OBJ_PUB_DH942_SUBPRIME(obj);
6689 break;
6690 default:
6691 return (B_FALSE);
6693 } else if (obj->class == CKO_PRIVATE_KEY) {
6694 switch (obj->key_type) {
6695 case CKK_DSA:
6696 bigint = OBJ_PRI_DSA_SUBPRIME(obj);
6697 break;
6698 case CKK_X9_42_DH:
6699 bigint = OBJ_PRI_DH942_SUBPRIME(obj);
6700 break;
6701 default:
6702 return (B_FALSE);
6704 } else if (obj->class == CKO_DOMAIN_PARAMETERS) {
6705 switch (obj->key_type) {
6706 case CKK_DSA:
6707 bigint = OBJ_DOM_DSA_SUBPRIME(obj);
6708 break;
6709 case CKK_X9_42_DH:
6710 bigint = OBJ_DOM_DH942_SUBPRIME(obj);
6711 break;
6712 default:
6713 return (B_FALSE);
6715 } else {
6716 return (B_FALSE);
6718 compare_bigint = B_TRUE;
6719 break;
6720 case CKA_BASE:
6721 if (obj->class == CKO_PUBLIC_KEY) {
6722 switch (obj->key_type) {
6723 case CKK_DSA:
6724 bigint = OBJ_PUB_DSA_BASE(obj);
6725 break;
6726 case CKK_DH:
6727 bigint = OBJ_PUB_DH_BASE(obj);
6728 break;
6729 case CKK_X9_42_DH:
6730 bigint = OBJ_PUB_DH942_BASE(obj);
6731 break;
6732 default:
6733 return (B_FALSE);
6735 } else if (obj->class == CKO_PRIVATE_KEY) {
6736 switch (obj->key_type) {
6737 case CKK_DSA:
6738 bigint = OBJ_PRI_DSA_BASE(obj);
6739 break;
6740 case CKK_DH:
6741 bigint = OBJ_PRI_DH_BASE(obj);
6742 break;
6743 case CKK_X9_42_DH:
6744 bigint = OBJ_PRI_DH942_BASE(obj);
6745 break;
6746 default:
6747 return (B_FALSE);
6749 } else if (obj->class == CKO_DOMAIN_PARAMETERS) {
6750 switch (obj->key_type) {
6751 case CKK_DSA:
6752 bigint = OBJ_DOM_DSA_BASE(obj);
6753 break;
6754 case CKK_DH:
6755 bigint = OBJ_DOM_DH_BASE(obj);
6756 break;
6757 case CKK_X9_42_DH:
6758 bigint = OBJ_DOM_DH942_BASE(obj);
6759 break;
6760 default:
6761 return (B_FALSE);
6763 } else {
6764 return (B_FALSE);
6766 compare_bigint = B_TRUE;
6767 break;
6768 case CKA_PRIME_BITS:
6769 if (obj->class == CKO_DOMAIN_PARAMETERS) {
6770 CK_ULONG prime_bits;
6771 if (obj->key_type == CKK_DSA) {
6772 prime_bits =
6773 OBJ_DOM_DSA_PRIME_BITS(obj);
6774 } else if (obj->key_type == CKK_DH) {
6775 prime_bits =
6776 OBJ_DOM_DH_PRIME_BITS(obj);
6777 } else if (obj->key_type == CKK_X9_42_DH) {
6778 prime_bits =
6779 OBJ_DOM_DH942_PRIME_BITS(obj);
6780 } else {
6781 return (B_FALSE);
6783 if (prime_bits !=
6784 *((CK_ULONG *)tmpl_attr->pValue)) {
6785 return (B_FALSE);
6787 } else {
6788 return (B_FALSE);
6790 break;
6791 case CKA_SUBPRIME_BITS:
6792 if ((obj->class == CKO_DOMAIN_PARAMETERS) &&
6793 (obj->key_type == CKK_X9_42_DH)) {
6794 CK_ULONG subprime_bits =
6795 OBJ_DOM_DH942_SUBPRIME_BITS(obj);
6796 if (subprime_bits !=
6797 *((CK_ULONG *)tmpl_attr->pValue)) {
6798 return (B_FALSE);
6800 } else {
6801 return (B_FALSE);
6803 break;
6804 default:
6806 * any other attributes are currently not supported.
6807 * so, it's not possible for them to be in the
6808 * object
6810 return (B_FALSE);
6812 if (compare_boolean) {
6813 CK_BBOOL bval;
6815 if (attr_mask) {
6816 bval = TRUE;
6817 } else {
6818 bval = FALSE;
6820 if (bval != *((CK_BBOOL *)tmpl_attr->pValue)) {
6821 return (B_FALSE);
6823 } else if (compare_bigint) {
6824 if (bigint == NULL) {
6825 return (B_FALSE);
6827 if (tmpl_attr->ulValueLen != bigint->big_value_len) {
6828 return (B_FALSE);
6830 if (memcmp(tmpl_attr->pValue, bigint->big_value,
6831 tmpl_attr->ulValueLen) != 0) {
6832 return (B_FALSE);
6834 } else if (compare_attr) {
6835 if (obj_attr == NULL) {
6837 * The attribute type is valid, and its value
6838 * has not been initialized in the object. In
6839 * this case, it only matches the template's
6840 * attribute if the template's value length
6841 * is 0.
6843 if (tmpl_attr->ulValueLen != 0)
6844 return (B_FALSE);
6845 } else {
6846 if (tmpl_attr->ulValueLen !=
6847 obj_attr->ulValueLen) {
6848 return (B_FALSE);
6850 if (memcmp(tmpl_attr->pValue, obj_attr->pValue,
6851 tmpl_attr->ulValueLen) != 0) {
6852 return (B_FALSE);
6855 } else if (compare_cert_val) {
6856 if (cert_attr == NULL) {
6857 /* specific attribute not found */
6858 return (B_FALSE);
6860 if (tmpl_attr->ulValueLen != cert_attr->length) {
6861 return (B_FALSE);
6863 if (memcmp(tmpl_attr->pValue, cert_attr->value,
6864 tmpl_attr->ulValueLen) != 0) {
6865 return (B_FALSE);
6867 } else if (compare_cert_type) {
6868 if (memcmp(tmpl_attr->pValue, &(obj->cert_type),
6869 tmpl_attr->ulValueLen) != 0) {
6870 return (B_FALSE);
6874 return (B_TRUE);
6877 CK_ATTRIBUTE_PTR
6878 get_extra_attr(CK_ATTRIBUTE_TYPE type, soft_object_t *obj)
6880 CK_ATTRIBUTE_INFO_PTR tmp;
6882 tmp = obj->extra_attrlistp;
6883 while (tmp != NULL) {
6884 if (tmp->attr.type == type) {
6885 return (&(tmp->attr));
6887 tmp = tmp->next;
6889 /* if get there, the specified attribute is not found */
6890 return (NULL);