8322 nl: misleading-indentation
[unleashed/tickless.git] / usr / src / lib / pkcs11 / pkcs11_softtoken / common / softAttributeUtil.c
blobd6e77c80165893b0dda9ca370f4b29deb94fa3a3
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.
27 #include <stdlib.h>
28 #include <string.h>
29 #include <security/cryptoki.h>
30 #include <sys/crypto/common.h>
31 #include <arcfour.h>
32 #include <aes_impl.h>
33 #include <blowfish_impl.h>
34 #include <bignum.h>
35 #include <des_impl.h>
36 #include <rsa_impl.h>
37 #include "softGlobal.h"
38 #include "softObject.h"
39 #include "softSession.h"
40 #include "softKeystore.h"
41 #include "softKeystoreUtil.h"
42 #include "softCrypt.h"
46 * This attribute table is used by the soft_lookup_attr()
47 * to validate the attributes.
49 CK_ATTRIBUTE_TYPE attr_map[] = {
50 CKA_PRIVATE,
51 CKA_LABEL,
52 CKA_APPLICATION,
53 CKA_OBJECT_ID,
54 CKA_CERTIFICATE_TYPE,
55 CKA_ISSUER,
56 CKA_SERIAL_NUMBER,
57 CKA_AC_ISSUER,
58 CKA_OWNER,
59 CKA_ATTR_TYPES,
60 CKA_SUBJECT,
61 CKA_ID,
62 CKA_SENSITIVE,
63 CKA_START_DATE,
64 CKA_END_DATE,
65 CKA_MODULUS,
66 CKA_MODULUS_BITS,
67 CKA_PUBLIC_EXPONENT,
68 CKA_PRIVATE_EXPONENT,
69 CKA_PRIME_1,
70 CKA_PRIME_2,
71 CKA_EXPONENT_1,
72 CKA_EXPONENT_2,
73 CKA_COEFFICIENT,
74 CKA_PRIME,
75 CKA_SUBPRIME,
76 CKA_BASE,
77 CKA_EXTRACTABLE,
78 CKA_LOCAL,
79 CKA_NEVER_EXTRACTABLE,
80 CKA_ALWAYS_SENSITIVE,
81 CKA_MODIFIABLE,
82 CKA_ECDSA_PARAMS,
83 CKA_EC_PARAMS,
84 CKA_EC_POINT,
85 CKA_SECONDARY_AUTH,
86 CKA_AUTH_PIN_FLAGS,
87 CKA_HW_FEATURE_TYPE,
88 CKA_RESET_ON_INIT,
89 CKA_HAS_RESET
93 * attributes that exists only in public key objects
94 * Note: some attributes may also exist in one or two
95 * other object classes, but they are also listed
96 * because not all object have them.
98 CK_ATTRIBUTE_TYPE PUB_KEY_ATTRS[] =
100 CKA_SUBJECT,
101 CKA_ENCRYPT,
102 CKA_WRAP,
103 CKA_VERIFY,
104 CKA_VERIFY_RECOVER,
105 CKA_MODULUS,
106 CKA_MODULUS_BITS,
107 CKA_PUBLIC_EXPONENT,
108 CKA_PRIME,
109 CKA_SUBPRIME,
110 CKA_BASE,
111 CKA_TRUSTED,
112 CKA_ECDSA_PARAMS,
113 CKA_EC_PARAMS,
114 CKA_EC_POINT
118 * attributes that exists only in private key objects
119 * Note: some attributes may also exist in one or two
120 * other object classes, but they are also listed
121 * because not all object have them.
123 CK_ATTRIBUTE_TYPE PRIV_KEY_ATTRS[] =
125 CKA_DECRYPT,
126 CKA_UNWRAP,
127 CKA_SIGN,
128 CKA_SIGN_RECOVER,
129 CKA_MODULUS,
130 CKA_PUBLIC_EXPONENT,
131 CKA_PRIVATE_EXPONENT,
132 CKA_PRIME,
133 CKA_SUBPRIME,
134 CKA_BASE,
135 CKA_PRIME_1,
136 CKA_PRIME_2,
137 CKA_EXPONENT_1,
138 CKA_EXPONENT_2,
139 CKA_COEFFICIENT,
140 CKA_VALUE_BITS,
141 CKA_SUBJECT,
142 CKA_SENSITIVE,
143 CKA_EXTRACTABLE,
144 CKA_NEVER_EXTRACTABLE,
145 CKA_ALWAYS_SENSITIVE,
146 CKA_EC_PARAMS
150 * attributes that exists only in secret key objects
151 * Note: some attributes may also exist in one or two
152 * other object classes, but they are also listed
153 * because not all object have them.
155 CK_ATTRIBUTE_TYPE SECRET_KEY_ATTRS[] =
157 CKA_VALUE_LEN,
158 CKA_ENCRYPT,
159 CKA_DECRYPT,
160 CKA_WRAP,
161 CKA_UNWRAP,
162 CKA_SIGN,
163 CKA_VERIFY,
164 CKA_SENSITIVE,
165 CKA_EXTRACTABLE,
166 CKA_NEVER_EXTRACTABLE,
167 CKA_ALWAYS_SENSITIVE
171 * attributes that exists only in domain parameter objects
172 * Note: some attributes may also exist in one or two
173 * other object classes, but they are also listed
174 * because not all object have them.
176 CK_ATTRIBUTE_TYPE DOMAIN_ATTRS[] =
178 CKA_PRIME,
179 CKA_SUBPRIME,
180 CKA_BASE,
181 CKA_PRIME_BITS,
182 CKA_SUBPRIME_BITS,
183 CKA_SUB_PRIME_BITS
187 * attributes that exists only in hardware feature objects
190 CK_ATTRIBUTE_TYPE HARDWARE_ATTRS[] =
192 CKA_HW_FEATURE_TYPE,
193 CKA_RESET_ON_INIT,
194 CKA_HAS_RESET
198 * attributes that exists only in certificate objects
200 CK_ATTRIBUTE_TYPE CERT_ATTRS[] =
202 CKA_CERTIFICATE_TYPE,
203 CKA_TRUSTED,
204 CKA_SUBJECT,
205 CKA_ID,
206 CKA_ISSUER,
207 CKA_AC_ISSUER,
208 CKA_SERIAL_NUMBER,
209 CKA_OWNER,
210 CKA_ATTR_TYPES
215 * Validate the attribute by using binary search algorithm.
217 CK_RV
218 soft_lookup_attr(CK_ATTRIBUTE_TYPE type)
221 size_t lower, middle, upper;
223 lower = 0;
224 upper = (sizeof (attr_map) / sizeof (CK_ATTRIBUTE_TYPE)) - 1;
226 while (lower <= upper) {
227 /* Always starts from middle. */
228 middle = (lower + upper) / 2;
230 if (type > attr_map[middle]) {
231 /* Adjust the lower bound to upper half. */
232 lower = middle + 1;
233 continue;
236 if (type == attr_map[middle]) {
237 /* Found it. */
238 return (CKR_OK);
241 if (type < attr_map[middle]) {
242 /* Adjust the upper bound to lower half. */
243 upper = middle - 1;
244 continue;
248 /* Failed to find the matching attribute from the attribute table. */
249 return (CKR_ATTRIBUTE_TYPE_INVALID);
254 * Validate the attribute by using the following search algorithm:
256 * 1) Search for the most frequently used attributes first.
257 * 2) If not found, search for the usage-purpose attributes - these
258 * attributes have dense set of values, therefore compiler will
259 * optimize it with a branch table and branch to the appropriate
260 * case.
261 * 3) If still not found, use binary search for the rest of the
262 * attributes in the attr_map[] table.
264 CK_RV
265 soft_validate_attr(CK_ATTRIBUTE_PTR template, CK_ULONG ulAttrNum,
266 CK_OBJECT_CLASS *class)
269 CK_ULONG i;
270 CK_RV rv = CKR_OK;
272 for (i = 0; i < ulAttrNum; i++) {
273 /* First tier search */
274 switch (template[i].type) {
275 case CKA_CLASS:
276 *class = *((CK_OBJECT_CLASS*)template[i].pValue);
277 break;
278 case CKA_TOKEN:
279 break;
280 case CKA_KEY_TYPE:
281 break;
282 case CKA_VALUE:
283 break;
284 case CKA_VALUE_LEN:
285 break;
286 case CKA_VALUE_BITS:
287 break;
288 default:
289 /* Second tier search */
290 switch (template[i].type) {
291 case CKA_ENCRYPT:
292 break;
293 case CKA_DECRYPT:
294 break;
295 case CKA_WRAP:
296 break;
297 case CKA_UNWRAP:
298 break;
299 case CKA_SIGN:
300 break;
301 case CKA_SIGN_RECOVER:
302 break;
303 case CKA_VERIFY:
304 break;
305 case CKA_VERIFY_RECOVER:
306 break;
307 case CKA_DERIVE:
308 break;
309 default:
310 /* Third tier search */
311 rv = soft_lookup_attr(template[i].type);
312 if (rv != CKR_OK)
313 return (rv);
314 break;
316 break;
319 return (rv);
322 static void
323 cleanup_cert_attr(cert_attr_t *attr)
325 if (attr) {
326 if (attr->value) {
327 (void) memset(attr->value, 0, attr->length);
328 free(attr->value);
330 attr->value = NULL;
331 attr->length = 0;
335 static CK_RV
336 copy_cert_attr(cert_attr_t *src_attr, cert_attr_t **dest_attr)
338 CK_RV rv = CKR_OK;
340 if (src_attr == NULL || dest_attr == NULL)
341 return (CKR_HOST_MEMORY);
343 if (src_attr->value == NULL)
344 return (CKR_HOST_MEMORY);
346 /* free memory if its already allocated */
347 if (*dest_attr != NULL) {
348 if ((*dest_attr)->value != (CK_BYTE *)NULL)
349 free((*dest_attr)->value);
350 } else {
351 *dest_attr = malloc(sizeof (cert_attr_t));
352 if (*dest_attr == NULL)
353 return (CKR_HOST_MEMORY);
356 (*dest_attr)->value = NULL;
357 (*dest_attr)->length = 0;
359 if (src_attr->length) {
360 (*dest_attr)->value = malloc(src_attr->length);
361 if ((*dest_attr)->value == NULL) {
362 free(*dest_attr);
363 return (CKR_HOST_MEMORY);
366 (void) memcpy((*dest_attr)->value, src_attr->value,
367 src_attr->length);
368 (*dest_attr)->length = src_attr->length;
371 return (rv);
374 void
375 soft_cleanup_cert_object(soft_object_t *object_p)
377 CK_CERTIFICATE_TYPE certtype = object_p->cert_type;
379 if (object_p->class != CKO_CERTIFICATE ||
380 OBJ_CERT(object_p) == NULL)
381 return;
383 if (certtype == CKC_X_509) {
384 if (X509_CERT_SUBJECT(object_p) != NULL) {
385 cleanup_cert_attr(X509_CERT_SUBJECT(object_p));
386 free(X509_CERT_SUBJECT(object_p));
387 X509_CERT_SUBJECT(object_p) = NULL;
389 if (X509_CERT_VALUE(object_p) != NULL) {
390 cleanup_cert_attr(X509_CERT_VALUE(object_p));
391 free(X509_CERT_VALUE(object_p));
392 X509_CERT_VALUE(object_p) = NULL;
394 free(OBJ_CERT(object_p));
395 } else if (certtype == CKC_X_509_ATTR_CERT) {
396 if (X509_ATTR_CERT_VALUE(object_p) != NULL) {
397 cleanup_cert_attr(X509_ATTR_CERT_VALUE(object_p));
398 free(X509_ATTR_CERT_VALUE(object_p));
399 X509_ATTR_CERT_VALUE(object_p) = NULL;
401 if (X509_ATTR_CERT_OWNER(object_p) != NULL) {
402 cleanup_cert_attr(X509_ATTR_CERT_OWNER(object_p));
403 free(X509_ATTR_CERT_OWNER(object_p));
404 X509_ATTR_CERT_OWNER(object_p) = NULL;
406 free(OBJ_CERT(object_p));
411 * Clean up and release all the storage in the extra attribute list
412 * of an object.
414 void
415 soft_cleanup_extra_attr(soft_object_t *object_p)
418 CK_ATTRIBUTE_INFO_PTR extra_attr;
419 CK_ATTRIBUTE_INFO_PTR tmp;
421 extra_attr = object_p->extra_attrlistp;
422 while (extra_attr) {
423 tmp = extra_attr->next;
424 if (extra_attr->attr.pValue)
426 * All extra attributes in the extra attribute
427 * list have pValue points to the value of the
428 * attribute (with simple byte array type).
429 * Free the storage for the value of the attribute.
431 free(extra_attr->attr.pValue);
433 /* Free the storage for the attribute_info struct. */
434 free(extra_attr);
435 extra_attr = tmp;
438 object_p->extra_attrlistp = NULL;
443 * Create the attribute_info struct to hold the object's attribute,
444 * and add it to the extra attribute list of an object.
446 CK_RV
447 soft_add_extra_attr(CK_ATTRIBUTE_PTR template, soft_object_t *object_p)
450 CK_ATTRIBUTE_INFO_PTR attrp;
452 /* Allocate the storage for the attribute_info struct. */
453 attrp = calloc(1, sizeof (attribute_info_t));
454 if (attrp == NULL) {
455 return (CKR_HOST_MEMORY);
458 /* Set up attribute_info struct. */
459 attrp->attr.type = template->type;
460 attrp->attr.ulValueLen = template->ulValueLen;
462 if ((template->pValue != NULL) &&
463 (template->ulValueLen > 0)) {
464 /* Allocate storage for the value of the attribute. */
465 attrp->attr.pValue = malloc(template->ulValueLen);
466 if (attrp->attr.pValue == NULL) {
467 free(attrp);
468 return (CKR_HOST_MEMORY);
471 (void) memcpy(attrp->attr.pValue, template->pValue,
472 template->ulValueLen);
473 } else {
474 attrp->attr.pValue = NULL;
477 /* Insert the new attribute in front of extra attribute list. */
478 if (object_p->extra_attrlistp == NULL) {
479 object_p->extra_attrlistp = attrp;
480 attrp->next = NULL;
481 } else {
482 attrp->next = object_p->extra_attrlistp;
483 object_p->extra_attrlistp = attrp;
486 return (CKR_OK);
489 CK_RV
490 soft_copy_certificate(certificate_obj_t *oldcert, certificate_obj_t **newcert,
491 CK_CERTIFICATE_TYPE type)
493 CK_RV rv = CKR_OK;
494 certificate_obj_t *cert;
495 x509_cert_t x509;
496 x509_attr_cert_t x509_attr;
498 cert = calloc(1, sizeof (certificate_obj_t));
499 if (cert == NULL) {
500 return (CKR_HOST_MEMORY);
503 if (type == CKC_X_509) {
504 x509 = oldcert->cert_type_u.x509;
505 if (x509.subject)
506 if ((rv = copy_cert_attr(x509.subject,
507 &cert->cert_type_u.x509.subject)))
508 return (rv);
509 if (x509.value)
510 if ((rv = copy_cert_attr(x509.value,
511 &cert->cert_type_u.x509.value)))
512 return (rv);
513 } else if (type == CKC_X_509_ATTR_CERT) {
514 x509_attr = oldcert->cert_type_u.x509_attr;
515 if (x509_attr.owner)
516 if ((rv = copy_cert_attr(x509_attr.owner,
517 &cert->cert_type_u.x509_attr.owner)))
518 return (rv);
519 if (x509_attr.value)
520 if ((rv = copy_cert_attr(x509_attr.value,
521 &cert->cert_type_u.x509_attr.value)))
522 return (rv);
523 } else {
524 /* wrong certificate type */
525 rv = CKR_ATTRIBUTE_TYPE_INVALID;
527 if (rv == CKR_OK)
528 *newcert = cert;
529 return (rv);
533 * Copy the attribute_info struct from the old object to a new attribute_info
534 * struct, and add that new struct to the extra attribute list of the new
535 * object.
537 CK_RV
538 soft_copy_extra_attr(CK_ATTRIBUTE_INFO_PTR old_attrp, soft_object_t *object_p)
540 CK_ATTRIBUTE_INFO_PTR attrp;
542 /* Allocate attribute_info struct. */
543 attrp = calloc(1, sizeof (attribute_info_t));
544 if (attrp == NULL) {
545 return (CKR_HOST_MEMORY);
548 attrp->attr.type = old_attrp->attr.type;
549 attrp->attr.ulValueLen = old_attrp->attr.ulValueLen;
551 if ((old_attrp->attr.pValue != NULL) &&
552 (old_attrp->attr.ulValueLen > 0)) {
553 attrp->attr.pValue = malloc(old_attrp->attr.ulValueLen);
554 if (attrp->attr.pValue == NULL) {
555 free(attrp);
556 return (CKR_HOST_MEMORY);
559 (void) memcpy(attrp->attr.pValue, old_attrp->attr.pValue,
560 old_attrp->attr.ulValueLen);
561 } else {
562 attrp->attr.pValue = NULL;
565 /* Insert the new attribute in front of extra attribute list */
566 if (object_p->extra_attrlistp == NULL) {
567 object_p->extra_attrlistp = attrp;
568 attrp->next = NULL;
569 } else {
570 attrp->next = object_p->extra_attrlistp;
571 object_p->extra_attrlistp = attrp;
574 return (CKR_OK);
579 * Get the attribute triple from the extra attribute list in the object
580 * (if the specified attribute type is found), and copy it to a template.
581 * Note the type of the attribute to be copied is specified by the template,
582 * and the storage is pre-allocated for the atrribute value in the template
583 * for doing the copy.
585 CK_RV
586 get_extra_attr_from_object(soft_object_t *object_p, CK_ATTRIBUTE_PTR template)
589 CK_ATTRIBUTE_INFO_PTR extra_attr;
590 CK_ATTRIBUTE_TYPE type = template->type;
592 extra_attr = object_p->extra_attrlistp;
594 while (extra_attr) {
595 if (type == extra_attr->attr.type) {
596 /* Found it. */
597 break;
598 } else {
599 /* Does not match, try next one. */
600 extra_attr = extra_attr->next;
604 if (extra_attr == NULL) {
605 /* A valid but un-initialized attribute. */
606 template->ulValueLen = 0;
607 return (CKR_OK);
611 * We found the attribute in the extra attribute list.
613 if (template->pValue == NULL) {
614 template->ulValueLen = extra_attr->attr.ulValueLen;
615 return (CKR_OK);
618 if (template->ulValueLen >= extra_attr->attr.ulValueLen) {
620 * The buffer provided by the application is large
621 * enough to hold the value of the attribute.
623 (void) memcpy(template->pValue, extra_attr->attr.pValue,
624 extra_attr->attr.ulValueLen);
625 template->ulValueLen = extra_attr->attr.ulValueLen;
626 return (CKR_OK);
627 } else {
629 * The buffer provided by the application does
630 * not have enough space to hold the value.
632 template->ulValueLen = (CK_ULONG)-1;
633 return (CKR_BUFFER_TOO_SMALL);
639 * Modify the attribute triple in the extra attribute list of the object
640 * if the specified attribute type is found. Otherwise, just add it to
641 * list.
643 CK_RV
644 set_extra_attr_to_object(soft_object_t *object_p, CK_ATTRIBUTE_TYPE type,
645 CK_ATTRIBUTE_PTR template)
648 CK_ATTRIBUTE_INFO_PTR extra_attr;
650 extra_attr = object_p->extra_attrlistp;
652 while (extra_attr) {
653 if (type == extra_attr->attr.type) {
654 /* Found it. */
655 break;
656 } else {
657 /* Does not match, try next one. */
658 extra_attr = extra_attr->next;
662 if (extra_attr == NULL) {
664 * This attribute is a new one, go ahead adding it to
665 * the extra attribute list.
667 return (soft_add_extra_attr(template, object_p));
670 /* We found the attribute in the extra attribute list. */
671 if ((template->pValue != NULL) &&
672 (template->ulValueLen > 0)) {
673 if (template->ulValueLen > extra_attr->attr.ulValueLen) {
674 /* The old buffer is too small to hold the new value. */
675 if (extra_attr->attr.pValue != NULL)
676 /* Free storage for the old attribute value. */
677 free(extra_attr->attr.pValue);
679 /* Allocate storage for the new attribute value. */
680 extra_attr->attr.pValue = malloc(template->ulValueLen);
681 if (extra_attr->attr.pValue == NULL) {
682 return (CKR_HOST_MEMORY);
686 /* Replace the attribute with new value. */
687 extra_attr->attr.ulValueLen = template->ulValueLen;
688 (void) memcpy(extra_attr->attr.pValue, template->pValue,
689 template->ulValueLen);
690 } else {
691 extra_attr->attr.pValue = NULL;
694 return (CKR_OK);
699 * Copy the big integer attribute value from template to a biginteger_t struct.
701 CK_RV
702 get_bigint_attr_from_template(biginteger_t *big, CK_ATTRIBUTE_PTR template)
705 if ((template->pValue != NULL) &&
706 (template->ulValueLen > 0)) {
707 /* Allocate storage for the value of the attribute. */
708 big->big_value = malloc(template->ulValueLen);
709 if (big->big_value == NULL) {
710 return (CKR_HOST_MEMORY);
713 (void) memcpy(big->big_value, template->pValue,
714 template->ulValueLen);
715 big->big_value_len = template->ulValueLen;
716 } else {
717 big->big_value = NULL;
718 big->big_value_len = 0;
721 return (CKR_OK);
726 * Copy the big integer attribute value from a biginteger_t struct in the
727 * object to a template.
729 CK_RV
730 get_bigint_attr_from_object(biginteger_t *big, CK_ATTRIBUTE_PTR template)
733 if (template->pValue == NULL) {
734 template->ulValueLen = big->big_value_len;
735 return (CKR_OK);
738 if (big->big_value == NULL) {
739 template->ulValueLen = 0;
740 return (CKR_OK);
743 if (template->ulValueLen >= big->big_value_len) {
745 * The buffer provided by the application is large
746 * enough to hold the value of the attribute.
748 (void) memcpy(template->pValue, big->big_value,
749 big->big_value_len);
750 template->ulValueLen = big->big_value_len;
751 return (CKR_OK);
752 } else {
754 * The buffer provided by the application does
755 * not have enough space to hold the value.
757 template->ulValueLen = (CK_ULONG)-1;
758 return (CKR_BUFFER_TOO_SMALL);
764 * Copy the boolean data type attribute value from an object for the
765 * specified attribute to the template.
767 CK_RV
768 get_bool_attr_from_object(soft_object_t *object_p, CK_ULONG bool_flag,
769 CK_ATTRIBUTE_PTR template)
772 if (template->pValue == NULL) {
773 template->ulValueLen = sizeof (CK_BBOOL);
774 return (CKR_OK);
777 if (template->ulValueLen >= sizeof (CK_BBOOL)) {
779 * The buffer provided by the application is large
780 * enough to hold the value of the attribute.
782 if (object_p->bool_attr_mask & bool_flag) {
783 *((CK_BBOOL *)template->pValue) = B_TRUE;
784 } else {
785 *((CK_BBOOL *)template->pValue) = B_FALSE;
788 template->ulValueLen = sizeof (CK_BBOOL);
789 return (CKR_OK);
790 } else {
792 * The buffer provided by the application does
793 * not have enough space to hold the value.
795 template->ulValueLen = (CK_ULONG)-1;
796 return (CKR_BUFFER_TOO_SMALL);
801 * Set the boolean data type attribute value in the object.
803 CK_RV
804 set_bool_attr_to_object(soft_object_t *object_p, CK_ULONG bool_flag,
805 CK_ATTRIBUTE_PTR template)
808 if (*(CK_BBOOL *)template->pValue)
809 object_p->bool_attr_mask |= bool_flag;
810 else
811 object_p->bool_attr_mask &= ~bool_flag;
813 return (CKR_OK);
818 * Copy the CK_ULONG data type attribute value from an object to the
819 * template.
821 CK_RV
822 get_ulong_attr_from_object(CK_ULONG value, CK_ATTRIBUTE_PTR template)
825 if (template->pValue == NULL) {
826 template->ulValueLen = sizeof (CK_ULONG);
827 return (CKR_OK);
830 if (template->ulValueLen >= sizeof (CK_ULONG)) {
832 * The buffer provided by the application is large
833 * enough to hold the value of the attribute.
834 * It is also assumed to be correctly aligned.
836 *(CK_ULONG_PTR)template->pValue = value;
837 template->ulValueLen = sizeof (CK_ULONG);
838 return (CKR_OK);
839 } else {
841 * The buffer provided by the application does
842 * not have enough space to hold the value.
844 template->ulValueLen = (CK_ULONG)-1;
845 return (CKR_BUFFER_TOO_SMALL);
851 * Copy the CK_ULONG data type attribute value from a template to the
852 * object.
854 static CK_RV
855 get_ulong_attr_from_template(CK_ULONG *value, CK_ATTRIBUTE_PTR template)
858 if (template->ulValueLen < sizeof (CK_ULONG))
859 return (CKR_ATTRIBUTE_VALUE_INVALID);
861 if (template->pValue != NULL) {
862 *value = *(CK_ULONG_PTR)template->pValue;
863 } else {
864 *value = 0;
867 return (CKR_OK);
871 * Copy the big integer attribute value from source's biginteger_t to
872 * destination's biginteger_t.
874 void
875 copy_bigint_attr(biginteger_t *src, biginteger_t *dst)
878 if ((src->big_value != NULL) &&
879 (src->big_value_len > 0)) {
881 * To do the copy, just have dst's big_value points
882 * to src's.
884 dst->big_value = src->big_value;
885 dst->big_value_len = src->big_value_len;
888 * After the copy, nullify the src's big_value pointer.
889 * It prevents any double freeing the value.
891 src->big_value = NULL;
892 src->big_value_len = 0;
893 } else {
894 dst->big_value = NULL;
895 dst->big_value_len = 0;
899 CK_RV
900 get_string_from_template(CK_ATTRIBUTE_PTR dest, CK_ATTRIBUTE_PTR src)
902 if ((src->pValue != NULL) &&
903 (src->ulValueLen > 0)) {
904 /* Allocate storage for the value of the attribute. */
905 dest->pValue = malloc(src->ulValueLen);
906 if (dest->pValue == NULL) {
907 return (CKR_HOST_MEMORY);
910 (void) memcpy(dest->pValue, src->pValue,
911 src->ulValueLen);
912 dest->ulValueLen = src->ulValueLen;
913 dest->type = src->type;
914 } else {
915 dest->pValue = NULL;
916 dest->ulValueLen = 0;
917 dest->type = src->type;
920 return (CKR_OK);
924 CK_RV
925 get_cert_attr_from_template(cert_attr_t **dest, CK_ATTRIBUTE_PTR src)
927 if (src->pValue != NULL && src->ulValueLen > 0) {
929 * If the attribute was already set, clear out the
930 * existing value and release the memory.
932 if (*dest != NULL) {
933 if ((*dest)->value != NULL) {
934 (void) memset((*dest)->value, 0,
935 (*dest)->length);
936 free((*dest)->value);
938 } else {
939 *dest = malloc(sizeof (cert_attr_t));
940 if (*dest == NULL) {
941 return (CKR_HOST_MEMORY);
943 (void) memset(*dest, 0, sizeof (cert_attr_t));
945 (*dest)->value = malloc(src->ulValueLen);
946 if ((*dest)->value == NULL) {
947 free(*dest);
948 *dest = NULL;
949 return (CKR_HOST_MEMORY);
951 (void) memcpy((*dest)->value, src->pValue, src->ulValueLen);
952 (*dest)->length = src->ulValueLen;
955 return (CKR_OK);
959 * Copy the certificate attribute information to the template.
960 * If the template attribute is not big enough, set the ulValueLen=-1
961 * and return CKR_BUFFER_TOO_SMALL.
963 static CK_RV
964 get_cert_attr_from_object(cert_attr_t *src, CK_ATTRIBUTE_PTR template)
966 if (template->pValue == NULL) {
967 template->ulValueLen = src->length;
968 return (CKR_OK);
969 } else if (template->ulValueLen >= src->length) {
971 * The buffer provided by the application is large
972 * enough to hold the value of the attribute.
974 (void) memcpy(template->pValue, src->value, src->length);
975 template->ulValueLen = src->length;
976 return (CKR_OK);
977 } else {
979 * The buffer provided by the application does
980 * not have enough space to hold the value.
982 template->ulValueLen = (CK_ULONG)-1;
983 return (CKR_BUFFER_TOO_SMALL);
987 void
988 string_attr_cleanup(CK_ATTRIBUTE_PTR template)
991 if (template->pValue) {
992 free(template->pValue);
993 template->pValue = NULL;
994 template->ulValueLen = 0;
999 * Release the storage allocated for object attribute with big integer
1000 * value.
1002 void
1003 bigint_attr_cleanup(biginteger_t *big)
1006 if (big == NULL)
1007 return;
1009 if (big->big_value) {
1010 (void) memset(big->big_value, 0, big->big_value_len);
1011 free(big->big_value);
1012 big->big_value = NULL;
1013 big->big_value_len = 0;
1019 * Clean up and release all the storage allocated to hold the big integer
1020 * attributes associated with the type (i.e. class) of the object. Also,
1021 * release the storage allocated to the type of the object.
1023 void
1024 soft_cleanup_object_bigint_attrs(soft_object_t *object_p)
1027 CK_OBJECT_CLASS class = object_p->class;
1028 CK_KEY_TYPE keytype = object_p->key_type;
1031 switch (class) {
1032 case CKO_PUBLIC_KEY:
1033 if (OBJ_PUB(object_p)) {
1034 switch (keytype) {
1035 case CKK_RSA:
1036 bigint_attr_cleanup(OBJ_PUB_RSA_MOD(
1037 object_p));
1038 bigint_attr_cleanup(OBJ_PUB_RSA_PUBEXPO(
1039 object_p));
1040 break;
1042 case CKK_DSA:
1043 bigint_attr_cleanup(OBJ_PUB_DSA_PRIME(
1044 object_p));
1045 bigint_attr_cleanup(OBJ_PUB_DSA_SUBPRIME(
1046 object_p));
1047 bigint_attr_cleanup(OBJ_PUB_DSA_BASE(
1048 object_p));
1049 bigint_attr_cleanup(OBJ_PUB_DSA_VALUE(
1050 object_p));
1051 break;
1053 case CKK_DH:
1054 bigint_attr_cleanup(OBJ_PUB_DH_PRIME(
1055 object_p));
1056 bigint_attr_cleanup(OBJ_PUB_DH_BASE(
1057 object_p));
1058 bigint_attr_cleanup(OBJ_PUB_DH_VALUE(
1059 object_p));
1060 break;
1062 case CKK_X9_42_DH:
1063 bigint_attr_cleanup(OBJ_PUB_DH942_PRIME(
1064 object_p));
1065 bigint_attr_cleanup(OBJ_PUB_DH942_BASE(
1066 object_p));
1067 bigint_attr_cleanup(OBJ_PUB_DH942_SUBPRIME(
1068 object_p));
1069 bigint_attr_cleanup(OBJ_PUB_DH942_VALUE(
1070 object_p));
1071 break;
1072 case CKK_EC:
1073 bigint_attr_cleanup(OBJ_PUB_EC_POINT(
1074 object_p));
1075 break;
1078 /* Release Public Key Object struct */
1079 free(OBJ_PUB(object_p));
1080 OBJ_PUB(object_p) = NULL;
1082 break;
1084 case CKO_PRIVATE_KEY:
1085 if (OBJ_PRI(object_p)) {
1086 switch (keytype) {
1087 case CKK_RSA:
1088 bigint_attr_cleanup(OBJ_PRI_RSA_MOD(
1089 object_p));
1090 bigint_attr_cleanup(OBJ_PRI_RSA_PUBEXPO(
1091 object_p));
1092 bigint_attr_cleanup(OBJ_PRI_RSA_PRIEXPO(
1093 object_p));
1094 bigint_attr_cleanup(OBJ_PRI_RSA_PRIME1(
1095 object_p));
1096 bigint_attr_cleanup(OBJ_PRI_RSA_PRIME2(
1097 object_p));
1098 bigint_attr_cleanup(OBJ_PRI_RSA_EXPO1(
1099 object_p));
1100 bigint_attr_cleanup(OBJ_PRI_RSA_EXPO2(
1101 object_p));
1102 bigint_attr_cleanup(OBJ_PRI_RSA_COEF(
1103 object_p));
1104 break;
1106 case CKK_DSA:
1107 bigint_attr_cleanup(OBJ_PRI_DSA_PRIME(
1108 object_p));
1109 bigint_attr_cleanup(OBJ_PRI_DSA_SUBPRIME(
1110 object_p));
1111 bigint_attr_cleanup(OBJ_PRI_DSA_BASE(
1112 object_p));
1113 bigint_attr_cleanup(OBJ_PRI_DSA_VALUE(
1114 object_p));
1115 break;
1117 case CKK_DH:
1118 bigint_attr_cleanup(OBJ_PRI_DH_PRIME(
1119 object_p));
1120 bigint_attr_cleanup(OBJ_PRI_DH_BASE(
1121 object_p));
1122 bigint_attr_cleanup(OBJ_PRI_DH_VALUE(
1123 object_p));
1124 break;
1126 case CKK_X9_42_DH:
1127 bigint_attr_cleanup(OBJ_PRI_DH942_PRIME(
1128 object_p));
1129 bigint_attr_cleanup(OBJ_PRI_DH942_BASE(
1130 object_p));
1131 bigint_attr_cleanup(OBJ_PRI_DH942_SUBPRIME(
1132 object_p));
1133 bigint_attr_cleanup(OBJ_PRI_DH942_VALUE(
1134 object_p));
1135 break;
1137 case CKK_EC:
1138 bigint_attr_cleanup(OBJ_PRI_EC_VALUE(
1139 object_p));
1140 break;
1143 /* Release Private Key Object struct. */
1144 free(OBJ_PRI(object_p));
1145 OBJ_PRI(object_p) = NULL;
1147 break;
1149 case CKO_SECRET_KEY:
1150 if (OBJ_SEC(object_p)) {
1151 /* cleanup key data area */
1152 if (OBJ_SEC_VALUE(object_p) != NULL &&
1153 OBJ_SEC_VALUE_LEN(object_p) > 0) {
1154 (void) memset(OBJ_SEC_VALUE(object_p), 0,
1155 OBJ_SEC_VALUE_LEN(object_p));
1156 free(OBJ_SEC_VALUE(object_p));
1158 /* cleanup key schedule data area */
1159 if (OBJ_KEY_SCHED(object_p) != NULL &&
1160 OBJ_KEY_SCHED_LEN(object_p) > 0) {
1161 (void) memset(OBJ_KEY_SCHED(object_p), 0,
1162 OBJ_KEY_SCHED_LEN(object_p));
1163 free(OBJ_KEY_SCHED(object_p));
1166 /* Release Secret Key Object struct. */
1167 free(OBJ_SEC(object_p));
1168 OBJ_SEC(object_p) = NULL;
1170 break;
1172 case CKO_DOMAIN_PARAMETERS:
1173 if (OBJ_DOM(object_p)) {
1174 switch (keytype) {
1175 case CKK_DSA:
1176 bigint_attr_cleanup(OBJ_DOM_DSA_PRIME(
1177 object_p));
1178 bigint_attr_cleanup(OBJ_DOM_DSA_SUBPRIME(
1179 object_p));
1180 bigint_attr_cleanup(OBJ_DOM_DSA_BASE(
1181 object_p));
1182 break;
1184 case CKK_DH:
1185 bigint_attr_cleanup(OBJ_DOM_DH_PRIME(
1186 object_p));
1187 bigint_attr_cleanup(OBJ_DOM_DH_BASE(
1188 object_p));
1189 break;
1191 case CKK_X9_42_DH:
1192 bigint_attr_cleanup(OBJ_DOM_DH942_PRIME(
1193 object_p));
1194 bigint_attr_cleanup(OBJ_DOM_DH942_BASE(
1195 object_p));
1196 bigint_attr_cleanup(OBJ_DOM_DH942_SUBPRIME(
1197 object_p));
1198 break;
1201 /* Release Domain Parameters Object struct. */
1202 free(OBJ_DOM(object_p));
1203 OBJ_DOM(object_p) = NULL;
1205 break;
1211 * Parse the common attributes. Return to caller with appropriate return
1212 * value to indicate if the supplied template specifies a valid attribute
1213 * with a valid value.
1215 CK_RV
1216 soft_parse_common_attrs(CK_ATTRIBUTE_PTR template, uchar_t *object_type)
1219 CK_RV rv = CKR_OK;
1221 switch (template->type) {
1222 case CKA_CLASS:
1223 break;
1225 /* default boolean attributes */
1226 case CKA_TOKEN:
1227 if ((*(CK_BBOOL *)template->pValue) == B_TRUE) {
1228 if (!soft_keystore_status(KEYSTORE_INITIALIZED))
1229 return (CKR_DEVICE_REMOVED);
1230 *object_type |= TOKEN_OBJECT;
1232 break;
1234 case CKA_PRIVATE:
1235 if ((*(CK_BBOOL *)template->pValue) == B_TRUE) {
1236 (void) pthread_mutex_lock(&soft_giant_mutex);
1237 if (!soft_slot.authenticated) {
1239 * Check if this is the special case when
1240 * the PIN is never initialized in the keystore.
1241 * If true, we will let it pass here and let
1242 * it fail with CKR_PIN_EXPIRED later on.
1244 if (!soft_slot.userpin_change_needed) {
1245 (void) pthread_mutex_unlock(
1246 &soft_giant_mutex);
1247 return (CKR_USER_NOT_LOGGED_IN);
1250 (void) pthread_mutex_unlock(&soft_giant_mutex);
1251 *object_type |= PRIVATE_OBJECT;
1253 break;
1255 case CKA_LABEL:
1256 break;
1258 default:
1259 rv = CKR_TEMPLATE_INCONSISTENT;
1262 return (rv);
1267 * Build a Public Key Object.
1269 * - Parse the object's template, and when an error is detected such as
1270 * invalid attribute type, invalid attribute value, etc., return
1271 * with appropriate return value.
1272 * - Set up attribute mask field in the object for the supplied common
1273 * attributes that have boolean type.
1274 * - Build the attribute_info struct to hold the value of each supplied
1275 * attribute that has byte array type. Link attribute_info structs
1276 * together to form the extra attribute list of the object.
1277 * - Allocate storage for the Public Key object.
1278 * - Build the Public Key object according to the key type. Allocate
1279 * storage to hold the big integer value for the supplied attributes
1280 * that are required for a certain key type.
1283 CK_RV
1284 soft_build_public_key_object(CK_ATTRIBUTE_PTR template, CK_ULONG ulAttrNum,
1285 soft_object_t *new_object, CK_ULONG mode, CK_KEY_TYPE key_type)
1288 ulong_t i;
1289 CK_KEY_TYPE keytype = (CK_KEY_TYPE)~0UL;
1290 uint64_t attr_mask = PUBLIC_KEY_DEFAULT;
1291 CK_RV rv = CKR_OK;
1292 int isLabel = 0;
1293 /* Must set flags */
1294 int isModulus = 0;
1295 int isPubExpo = 0;
1296 int isPrime = 0;
1297 int isSubprime = 0;
1298 int isBase = 0;
1299 int isValue = 0;
1300 int isECParam = 0;
1301 int isECPoint = 0;
1302 /* Must not set flags */
1303 int isModulusBits = 0;
1304 CK_ULONG modulus_bits = 0;
1306 biginteger_t modulus;
1307 biginteger_t pubexpo;
1308 biginteger_t prime;
1309 biginteger_t subprime;
1310 biginteger_t base;
1311 biginteger_t value;
1312 biginteger_t point;
1313 CK_ATTRIBUTE string_tmp;
1314 CK_ATTRIBUTE param_tmp;
1316 public_key_obj_t *pbk;
1317 uchar_t object_type = 0;
1319 CK_ATTRIBUTE defpubexpo = { CKA_PUBLIC_EXPONENT,
1320 (CK_BYTE_PTR)DEFAULT_PUB_EXPO, DEFAULT_PUB_EXPO_Len };
1322 BIGNUM n;
1324 /* prevent bigint_attr_cleanup from freeing invalid attr value */
1325 (void) memset(&modulus, 0x0, sizeof (biginteger_t));
1326 (void) memset(&pubexpo, 0x0, sizeof (biginteger_t));
1327 (void) memset(&prime, 0x0, sizeof (biginteger_t));
1328 (void) memset(&subprime, 0x0, sizeof (biginteger_t));
1329 (void) memset(&base, 0x0, sizeof (biginteger_t));
1330 (void) memset(&value, 0x0, sizeof (biginteger_t));
1331 (void) memset(&point, 0x0, sizeof (biginteger_t));
1332 string_tmp.pValue = NULL;
1333 param_tmp.pValue = NULL;
1335 for (i = 0; i < ulAttrNum; i++) {
1337 /* Public Key Object Attributes */
1338 switch (template[i].type) {
1340 /* common key attributes */
1341 case CKA_KEY_TYPE:
1342 keytype = *((CK_KEY_TYPE*)template[i].pValue);
1343 break;
1345 case CKA_ID:
1346 case CKA_START_DATE:
1347 case CKA_END_DATE:
1349 /* common public key attribute */
1350 case CKA_SUBJECT:
1352 * Allocate storage to hold the attribute
1353 * value with byte array type, and add it to
1354 * the extra attribute list of the object.
1356 rv = soft_add_extra_attr(&template[i],
1357 new_object);
1358 if (rv != CKR_OK) {
1359 goto fail_cleanup;
1361 break;
1364 * The following key related attribute types must
1365 * not be specified by C_CreateObject, C_GenerateKey(Pair).
1367 case CKA_LOCAL:
1368 case CKA_KEY_GEN_MECHANISM:
1369 rv = CKR_TEMPLATE_INCONSISTENT;
1370 goto fail_cleanup;
1372 /* Key related boolean attributes */
1373 case CKA_DERIVE:
1374 if (*(CK_BBOOL *)template[i].pValue)
1375 attr_mask |= DERIVE_BOOL_ON;
1376 break;
1378 case CKA_ENCRYPT:
1379 if (*(CK_BBOOL *)template[i].pValue)
1380 attr_mask |= ENCRYPT_BOOL_ON;
1381 else
1382 attr_mask &= ~ENCRYPT_BOOL_ON;
1383 break;
1385 case CKA_VERIFY:
1386 if (*(CK_BBOOL *)template[i].pValue)
1387 attr_mask |= VERIFY_BOOL_ON;
1388 else
1389 attr_mask &= ~VERIFY_BOOL_ON;
1390 break;
1392 case CKA_VERIFY_RECOVER:
1393 if (*(CK_BBOOL *)template[i].pValue)
1394 attr_mask |= VERIFY_RECOVER_BOOL_ON;
1395 else
1396 attr_mask &= ~VERIFY_RECOVER_BOOL_ON;
1397 break;
1399 case CKA_WRAP:
1400 if (*(CK_BBOOL *)template[i].pValue)
1401 attr_mask |= WRAP_BOOL_ON;
1402 else
1403 attr_mask &= ~WRAP_BOOL_ON;
1404 break;
1406 case CKA_TRUSTED:
1407 if (*(CK_BBOOL *)template[i].pValue)
1408 attr_mask |= TRUSTED_BOOL_ON;
1409 break;
1411 case CKA_MODIFIABLE:
1412 if ((*(CK_BBOOL *)template[i].pValue) == B_FALSE)
1413 attr_mask |= NOT_MODIFIABLE_BOOL_ON;
1414 break;
1417 * The following key related attribute types must
1418 * be specified according to the key type by
1419 * C_CreateObject.
1421 case CKA_MODULUS:
1423 isModulus = 1;
1425 * Copyin big integer attribute from template
1426 * to a local variable.
1428 rv = get_bigint_attr_from_template(&modulus,
1429 &template[i]);
1430 if (rv != CKR_OK)
1431 goto fail_cleanup;
1434 * Modulus length needs to be between min key length and
1435 * max key length.
1437 if ((modulus.big_value_len <
1438 MIN_RSA_KEYLENGTH_IN_BYTES) ||
1439 (modulus.big_value_len >
1440 MAX_RSA_KEYLENGTH_IN_BYTES)) {
1441 rv = CKR_ATTRIBUTE_VALUE_INVALID;
1442 goto fail_cleanup;
1444 break;
1446 case CKA_PUBLIC_EXPONENT:
1447 isPubExpo = 1;
1448 rv = get_bigint_attr_from_template(&pubexpo,
1449 &template[i]);
1450 if (rv != CKR_OK)
1451 goto fail_cleanup;
1452 break;
1454 case CKA_PRIME:
1455 isPrime = 1;
1456 rv = get_bigint_attr_from_template(&prime,
1457 &template[i]);
1458 if (rv != CKR_OK)
1459 goto fail_cleanup;
1460 break;
1462 case CKA_SUBPRIME:
1463 isSubprime = 1;
1464 rv = get_bigint_attr_from_template(&subprime,
1465 &template[i]);
1466 if (rv != CKR_OK)
1467 goto fail_cleanup;
1468 break;
1470 case CKA_BASE:
1471 isBase = 1;
1472 rv = get_bigint_attr_from_template(&base,
1473 &template[i]);
1474 if (rv != CKR_OK)
1475 goto fail_cleanup;
1476 break;
1478 case CKA_VALUE:
1479 isValue = 1;
1480 if (mode == SOFT_CREATE_OBJ) {
1481 if ((template[i].ulValueLen == 0) ||
1482 (template[i].pValue == NULL)) {
1483 rv = CKR_ATTRIBUTE_VALUE_INVALID;
1484 goto fail_cleanup;
1488 rv = get_bigint_attr_from_template(&value,
1489 &template[i]);
1490 if (rv != CKR_OK)
1491 goto fail_cleanup;
1492 break;
1494 case CKA_MODULUS_BITS:
1495 isModulusBits = 1;
1496 rv = get_ulong_attr_from_template(&modulus_bits,
1497 &template[i]);
1498 if (rv != CKR_OK)
1499 goto fail_cleanup;
1500 break;
1502 case CKA_LABEL:
1503 isLabel = 1;
1504 rv = get_string_from_template(&string_tmp,
1505 &template[i]);
1506 if (rv != CKR_OK)
1507 goto fail_cleanup;
1508 break;
1510 case CKA_EC_PARAMS:
1511 isECParam = 1;
1512 rv = get_string_from_template(&param_tmp, &template[i]);
1513 if (rv != CKR_OK)
1514 goto fail_cleanup;
1515 break;
1517 case CKA_EC_POINT:
1518 isECPoint = 1;
1519 rv = get_bigint_attr_from_template(&point,
1520 &template[i]);
1521 if (rv != CKR_OK)
1522 goto fail_cleanup;
1523 break;
1525 default:
1526 rv = soft_parse_common_attrs(&template[i],
1527 &object_type);
1528 if (rv != CKR_OK)
1529 goto fail_cleanup;
1530 break;
1532 } /* For */
1534 /* Allocate storage for Public Key Object. */
1535 pbk = calloc(1, sizeof (public_key_obj_t));
1536 if (pbk == NULL) {
1537 rv = CKR_HOST_MEMORY;
1538 goto fail_cleanup;
1541 new_object->object_class_u.public_key = pbk;
1542 new_object->class = CKO_PUBLIC_KEY;
1544 if ((mode == SOFT_CREATE_OBJ) && (keytype == (CK_KEY_TYPE)~0UL)) {
1545 rv = CKR_TEMPLATE_INCOMPLETE;
1546 goto fail_cleanup;
1549 if ((mode == SOFT_GEN_KEY) && (keytype == (CK_KEY_TYPE)~0UL)) {
1550 keytype = key_type;
1553 if ((mode == SOFT_GEN_KEY) && (keytype != key_type)) {
1555 * The key type specified in the template does not
1556 * match the implied key type based on the mechanism.
1558 rv = CKR_TEMPLATE_INCONSISTENT;
1559 goto fail_cleanup;
1562 new_object->key_type = keytype;
1564 /* Supported key types of the Public Key Object */
1565 switch (keytype) {
1567 case CKK_RSA:
1568 if (mode == SOFT_CREATE_OBJ) {
1569 if (isModulusBits || isPrime || isSubprime ||
1570 isBase || isValue) {
1571 rv = CKR_TEMPLATE_INCONSISTENT;
1572 goto fail_cleanup;
1575 if (isModulus && isPubExpo) {
1577 * Derive modulus_bits attribute from modulus.
1578 * Save modulus_bits integer value to the
1579 * designated place in the public key object.
1581 n.malloced = 0;
1582 #ifdef __sparcv9
1583 if (big_init(&n, (int)CHARLEN2BIGNUMLEN(
1584 modulus.big_value_len)) != BIG_OK) {
1585 #else /* !__sparcv9 */
1586 if (big_init(&n, CHARLEN2BIGNUMLEN(
1587 modulus.big_value_len)) != BIG_OK) {
1588 #endif /* __sparcv9 */
1589 rv = CKR_HOST_MEMORY;
1590 big_finish(&n);
1591 goto fail_cleanup;
1593 bytestring2bignum(&n, modulus.big_value,
1594 modulus.big_value_len);
1596 modulus_bits = big_bitlength(&n);
1597 KEY_PUB_RSA_MOD_BITS(pbk) = modulus_bits;
1598 big_finish(&n);
1601 * After modulus_bits has been computed,
1602 * it is safe to move modulus and pubexpo
1603 * big integer attribute value to the
1604 * designated place in the public key object.
1606 copy_bigint_attr(&modulus,
1607 KEY_PUB_RSA_MOD(pbk));
1609 copy_bigint_attr(&pubexpo,
1610 KEY_PUB_RSA_PUBEXPO(pbk));
1611 } else {
1612 rv = CKR_TEMPLATE_INCOMPLETE;
1613 goto fail_cleanup;
1615 } else {
1616 /* mode is SOFT_GEN_KEY */
1618 if (isModulus || isPrime || isSubprime ||
1619 isBase || isValue) {
1620 rv = CKR_TEMPLATE_INCONSISTENT;
1621 goto fail_cleanup;
1625 if (isModulusBits) {
1627 * Copy big integer attribute value to the
1628 * designated place in the public key object.
1630 KEY_PUB_RSA_MOD_BITS(pbk) = modulus_bits;
1631 } else {
1632 rv = CKR_TEMPLATE_INCOMPLETE;
1633 goto fail_cleanup;
1637 * Use PKCS#11 default 0x010001 for public exponent
1638 * if not not specified in attribute template.
1640 if (!isPubExpo) {
1641 isPubExpo = 1;
1642 rv = get_bigint_attr_from_template(&pubexpo,
1643 &defpubexpo);
1644 if (rv != CKR_OK)
1645 goto fail_cleanup;
1648 * Copy big integer attribute value to the
1649 * designated place in the public key object.
1651 copy_bigint_attr(&pubexpo, KEY_PUB_RSA_PUBEXPO(pbk));
1654 break;
1656 case CKK_DSA:
1657 if (mode == SOFT_CREATE_OBJ) {
1658 if (isModulusBits || isModulus || isPubExpo) {
1659 rv = CKR_TEMPLATE_INCONSISTENT;
1660 goto fail_cleanup;
1663 if (isPrime && isSubprime && isBase && isValue) {
1664 copy_bigint_attr(&value,
1665 KEY_PUB_DSA_VALUE(pbk));
1666 } else {
1667 rv = CKR_TEMPLATE_INCOMPLETE;
1668 goto fail_cleanup;
1670 } else {
1671 if (isModulusBits || isModulus || isPubExpo ||
1672 isValue) {
1673 rv = CKR_TEMPLATE_INCONSISTENT;
1674 goto fail_cleanup;
1677 if (!(isPrime && isSubprime && isBase)) {
1678 rv = CKR_TEMPLATE_INCOMPLETE;
1679 goto fail_cleanup;
1683 copy_bigint_attr(&prime, KEY_PUB_DSA_PRIME(pbk));
1685 copy_bigint_attr(&subprime, KEY_PUB_DSA_SUBPRIME(pbk));
1687 copy_bigint_attr(&base, KEY_PUB_DSA_BASE(pbk));
1689 break;
1691 case CKK_DH:
1692 if (mode == SOFT_CREATE_OBJ) {
1693 if (isModulusBits || isModulus || isPubExpo ||
1694 isSubprime) {
1695 rv = CKR_TEMPLATE_INCONSISTENT;
1696 goto fail_cleanup;
1699 if (isPrime && isBase && isValue) {
1700 copy_bigint_attr(&value,
1701 KEY_PUB_DH_VALUE(pbk));
1702 } else {
1703 rv = CKR_TEMPLATE_INCOMPLETE;
1704 goto fail_cleanup;
1706 } else {
1707 if (isModulusBits || isModulus || isPubExpo ||
1708 isSubprime || isValue) {
1709 rv = CKR_TEMPLATE_INCONSISTENT;
1710 goto fail_cleanup;
1713 if (!(isPrime && isBase)) {
1714 rv = CKR_TEMPLATE_INCOMPLETE;
1715 goto fail_cleanup;
1719 copy_bigint_attr(&prime, KEY_PUB_DH_PRIME(pbk));
1721 copy_bigint_attr(&base, KEY_PUB_DH_BASE(pbk));
1723 break;
1725 case CKK_X9_42_DH:
1726 if (mode == SOFT_CREATE_OBJ) {
1727 if (isModulusBits || isModulus || isPubExpo) {
1728 rv = CKR_TEMPLATE_INCONSISTENT;
1729 goto fail_cleanup;
1732 if (isPrime && isSubprime && isBase && isValue) {
1733 copy_bigint_attr(&value,
1734 KEY_PUB_DH942_VALUE(pbk));
1735 } else {
1736 rv = CKR_TEMPLATE_INCOMPLETE;
1737 goto fail_cleanup;
1739 } else {
1740 if (isModulusBits || isModulus || isPubExpo ||
1741 isValue) {
1742 rv = CKR_TEMPLATE_INCONSISTENT;
1743 goto fail_cleanup;
1746 if (!(isPrime && isSubprime && isBase)) {
1747 rv = CKR_TEMPLATE_INCOMPLETE;
1748 goto fail_cleanup;
1752 copy_bigint_attr(&prime, KEY_PUB_DH942_PRIME(pbk));
1754 copy_bigint_attr(&base, KEY_PUB_DH942_BASE(pbk));
1756 copy_bigint_attr(&subprime, KEY_PUB_DH942_SUBPRIME(pbk));
1758 break;
1760 case CKK_EC:
1761 if (mode == SOFT_CREATE_OBJ) {
1762 if (isModulusBits || isModulus || isPubExpo ||
1763 isPrime || isSubprime || isBase || isValue) {
1764 rv = CKR_TEMPLATE_INCONSISTENT;
1765 goto fail_cleanup;
1767 } else if (!isECParam || !isECPoint) {
1768 rv = CKR_TEMPLATE_INCOMPLETE;
1769 goto fail_cleanup;
1771 } else {
1772 if (isModulusBits || isModulus || isPubExpo ||
1773 isPrime || isSubprime || isBase || isValue) {
1774 rv = CKR_TEMPLATE_INCONSISTENT;
1775 goto fail_cleanup;
1777 } else if (!isECParam) {
1778 rv = CKR_TEMPLATE_INCOMPLETE;
1779 goto fail_cleanup;
1783 if (isECPoint) {
1784 copy_bigint_attr(&point, KEY_PUB_EC_POINT(pbk));
1786 rv = soft_add_extra_attr(&param_tmp, new_object);
1787 if (rv != CKR_OK)
1788 goto fail_cleanup;
1789 string_attr_cleanup(&param_tmp);
1790 break;
1792 default:
1793 rv = CKR_TEMPLATE_INCONSISTENT;
1794 goto fail_cleanup;
1797 /* Set up object. */
1798 new_object->object_type = object_type;
1799 new_object->bool_attr_mask = attr_mask;
1800 if (isLabel) {
1801 rv = soft_add_extra_attr(&string_tmp, new_object);
1802 if (rv != CKR_OK)
1803 goto fail_cleanup;
1804 string_attr_cleanup(&string_tmp);
1807 return (rv);
1809 fail_cleanup:
1811 * cleanup the storage allocated to the local variables.
1813 bigint_attr_cleanup(&modulus);
1814 bigint_attr_cleanup(&pubexpo);
1815 bigint_attr_cleanup(&prime);
1816 bigint_attr_cleanup(&subprime);
1817 bigint_attr_cleanup(&base);
1818 bigint_attr_cleanup(&value);
1819 bigint_attr_cleanup(&point);
1820 string_attr_cleanup(&string_tmp);
1821 string_attr_cleanup(&param_tmp);
1824 * cleanup the storage allocated inside the object itself.
1826 soft_cleanup_object(new_object);
1828 return (rv);
1833 * Build a Private Key Object.
1835 * - Parse the object's template, and when an error is detected such as
1836 * invalid attribute type, invalid attribute value, etc., return
1837 * with appropriate return value.
1838 * - Set up attribute mask field in the object for the supplied common
1839 * attributes that have boolean type.
1840 * - Build the attribute_info struct to hold the value of each supplied
1841 * attribute that has byte array type. Link attribute_info structs
1842 * together to form the extra attribute list of the object.
1843 * - Allocate storage for the Private Key object.
1844 * - Build the Private Key object according to the key type. Allocate
1845 * storage to hold the big integer value for the supplied attributes
1846 * that are required for a certain key type.
1849 CK_RV
1850 soft_build_private_key_object(CK_ATTRIBUTE_PTR template, CK_ULONG ulAttrNum,
1851 soft_object_t *new_object, CK_ULONG mode, CK_KEY_TYPE key_type)
1853 ulong_t i;
1854 CK_KEY_TYPE keytype = (CK_KEY_TYPE)~0UL;
1855 uint64_t attr_mask = PRIVATE_KEY_DEFAULT;
1856 CK_RV rv = CKR_OK;
1857 int isLabel = 0;
1858 int isECParam = 0;
1859 /* Must set flags unless mode == SOFT_UNWRAP_KEY */
1860 int isModulus = 0;
1861 int isPriExpo = 0;
1862 int isPrime = 0;
1863 int isSubprime = 0;
1864 int isBase = 0;
1865 /* Must set flags if mode == SOFT_GEN_KEY */
1866 int isValue = 0;
1867 /* Must not set flags */
1868 int isValueBits = 0;
1869 CK_ULONG value_bits = 0;
1871 /* Private Key RSA optional */
1872 int isPubExpo = 0;
1873 int isPrime1 = 0;
1874 int isPrime2 = 0;
1875 int isExpo1 = 0;
1876 int isExpo2 = 0;
1877 int isCoef = 0;
1879 biginteger_t modulus;
1880 biginteger_t priexpo;
1881 biginteger_t prime;
1882 biginteger_t subprime;
1883 biginteger_t base;
1884 biginteger_t value;
1886 biginteger_t pubexpo;
1887 biginteger_t prime1;
1888 biginteger_t prime2;
1889 biginteger_t expo1;
1890 biginteger_t expo2;
1891 biginteger_t coef;
1892 CK_ATTRIBUTE string_tmp;
1893 CK_ATTRIBUTE param_tmp;
1894 BIGNUM x, q;
1896 private_key_obj_t *pvk;
1897 uchar_t object_type = 0;
1899 /* prevent bigint_attr_cleanup from freeing invalid attr value */
1900 (void) memset(&modulus, 0x0, sizeof (biginteger_t));
1901 (void) memset(&priexpo, 0x0, sizeof (biginteger_t));
1902 (void) memset(&prime, 0x0, sizeof (biginteger_t));
1903 (void) memset(&subprime, 0x0, sizeof (biginteger_t));
1904 (void) memset(&base, 0x0, sizeof (biginteger_t));
1905 (void) memset(&value, 0x0, sizeof (biginteger_t));
1906 (void) memset(&pubexpo, 0x0, sizeof (biginteger_t));
1907 (void) memset(&prime1, 0x0, sizeof (biginteger_t));
1908 (void) memset(&prime2, 0x0, sizeof (biginteger_t));
1909 (void) memset(&expo1, 0x0, sizeof (biginteger_t));
1910 (void) memset(&expo2, 0x0, sizeof (biginteger_t));
1911 (void) memset(&coef, 0x0, sizeof (biginteger_t));
1912 string_tmp.pValue = NULL;
1913 param_tmp.pValue = NULL;
1914 x.malloced = 0;
1915 q.malloced = 0;
1917 for (i = 0; i < ulAttrNum; i++) {
1919 /* Private Key Object Attributes */
1920 switch (template[i].type) {
1921 /* common key attributes */
1922 case CKA_KEY_TYPE:
1923 keytype = *((CK_KEY_TYPE*)template[i].pValue);
1924 break;
1926 case CKA_ID:
1927 case CKA_START_DATE:
1928 case CKA_END_DATE:
1930 /* common private key attribute */
1931 case CKA_SUBJECT:
1933 * Allocate storage to hold the attribute
1934 * value with byte array type, and add it to
1935 * the extra attribute list of the object.
1937 rv = soft_add_extra_attr(&template[i],
1938 new_object);
1939 if (rv != CKR_OK) {
1940 goto fail_cleanup;
1942 break;
1945 * The following key related attribute types must
1946 * not be specified by C_CreateObject or C_GenerateKey(Pair).
1948 case CKA_LOCAL:
1949 case CKA_KEY_GEN_MECHANISM:
1950 case CKA_AUTH_PIN_FLAGS:
1951 case CKA_ALWAYS_SENSITIVE:
1952 case CKA_NEVER_EXTRACTABLE:
1953 rv = CKR_TEMPLATE_INCONSISTENT;
1954 goto fail_cleanup;
1956 /* Key related boolean attributes */
1957 case CKA_DERIVE:
1958 if (*(CK_BBOOL *)template[i].pValue)
1959 attr_mask |= DERIVE_BOOL_ON;
1960 break;
1962 case CKA_SENSITIVE:
1963 if (*(CK_BBOOL *)template[i].pValue)
1964 attr_mask |= SENSITIVE_BOOL_ON;
1965 break;
1967 case CKA_SECONDARY_AUTH:
1968 if (*(CK_BBOOL *)template[i].pValue) {
1969 rv = CKR_ATTRIBUTE_VALUE_INVALID;
1970 goto fail_cleanup;
1972 break;
1974 case CKA_DECRYPT:
1975 if (*(CK_BBOOL *)template[i].pValue)
1976 attr_mask |= DECRYPT_BOOL_ON;
1977 else
1978 attr_mask &= ~DECRYPT_BOOL_ON;
1979 break;
1981 case CKA_SIGN:
1982 if (*(CK_BBOOL *)template[i].pValue)
1983 attr_mask |= SIGN_BOOL_ON;
1984 else
1985 attr_mask &= ~SIGN_BOOL_ON;
1986 break;
1988 case CKA_SIGN_RECOVER:
1989 if (*(CK_BBOOL *)template[i].pValue)
1990 attr_mask |= SIGN_RECOVER_BOOL_ON;
1991 else
1992 attr_mask &= ~SIGN_RECOVER_BOOL_ON;
1993 break;
1995 case CKA_UNWRAP:
1996 if (*(CK_BBOOL *)template[i].pValue)
1997 attr_mask |= UNWRAP_BOOL_ON;
1998 else
1999 attr_mask &= ~UNWRAP_BOOL_ON;
2000 break;
2002 case CKA_EXTRACTABLE:
2003 if (*(CK_BBOOL *)template[i].pValue)
2004 attr_mask |= EXTRACTABLE_BOOL_ON;
2005 else
2006 attr_mask &= ~EXTRACTABLE_BOOL_ON;
2007 break;
2009 case CKA_MODIFIABLE:
2010 if ((*(CK_BBOOL *)template[i].pValue) == B_FALSE)
2011 attr_mask |= NOT_MODIFIABLE_BOOL_ON;
2012 break;
2015 * The following key related attribute types must
2016 * be specified according to the key type by
2017 * C_CreateObject.
2019 case CKA_MODULUS:
2021 isModulus = 1;
2023 * Copyin big integer attribute from template
2024 * to a local variable.
2026 rv = get_bigint_attr_from_template(&modulus,
2027 &template[i]);
2028 if (rv != CKR_OK)
2029 goto fail_cleanup;
2032 * Modulus length needs to be between min key length and
2033 * max key length.
2035 if ((modulus.big_value_len <
2036 MIN_RSA_KEYLENGTH_IN_BYTES) ||
2037 (modulus.big_value_len >
2038 MAX_RSA_KEYLENGTH_IN_BYTES)) {
2039 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2040 goto fail_cleanup;
2042 break;
2044 case CKA_PUBLIC_EXPONENT:
2046 isPubExpo = 1;
2047 rv = get_bigint_attr_from_template(&pubexpo,
2048 &template[i]);
2049 if (rv != CKR_OK)
2050 goto fail_cleanup;
2051 break;
2053 case CKA_PRIVATE_EXPONENT:
2055 isPriExpo = 1;
2056 rv = get_bigint_attr_from_template(&priexpo,
2057 &template[i]);
2058 if (rv != CKR_OK)
2059 goto fail_cleanup;
2060 break;
2062 case CKA_PRIME_1:
2063 isPrime1 = 1;
2064 rv = get_bigint_attr_from_template(&prime1,
2065 &template[i]);
2066 if (rv != CKR_OK)
2067 goto fail_cleanup;
2068 break;
2070 case CKA_PRIME_2:
2071 isPrime2 = 1;
2072 rv = get_bigint_attr_from_template(&prime2,
2073 &template[i]);
2074 if (rv != CKR_OK)
2075 goto fail_cleanup;
2076 break;
2078 case CKA_EXPONENT_1:
2079 isExpo1 = 1;
2080 rv = get_bigint_attr_from_template(&expo1,
2081 &template[i]);
2082 if (rv != CKR_OK)
2083 goto fail_cleanup;
2084 break;
2086 case CKA_EXPONENT_2:
2087 isExpo2 = 1;
2088 rv = get_bigint_attr_from_template(&expo2,
2089 &template[i]);
2090 if (rv != CKR_OK)
2091 goto fail_cleanup;
2092 break;
2094 case CKA_COEFFICIENT:
2095 isCoef = 1;
2096 rv = get_bigint_attr_from_template(&coef,
2097 &template[i]);
2098 if (rv != CKR_OK)
2099 goto fail_cleanup;
2100 break;
2102 case CKA_PRIME:
2103 isPrime = 1;
2104 rv = get_bigint_attr_from_template(&prime,
2105 &template[i]);
2106 if (rv != CKR_OK)
2107 goto fail_cleanup;
2108 break;
2110 case CKA_SUBPRIME:
2111 isSubprime = 1;
2112 rv = get_bigint_attr_from_template(&subprime,
2113 &template[i]);
2114 if (rv != CKR_OK)
2115 goto fail_cleanup;
2116 break;
2118 case CKA_BASE:
2119 isBase = 1;
2120 rv = get_bigint_attr_from_template(&base,
2121 &template[i]);
2122 if (rv != CKR_OK)
2123 goto fail_cleanup;
2124 break;
2126 case CKA_VALUE:
2127 isValue = 1;
2128 if (mode == SOFT_CREATE_OBJ) {
2129 if ((template[i].ulValueLen == 0) ||
2130 (template[i].pValue == NULL)) {
2131 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2132 goto fail_cleanup;
2136 rv = get_bigint_attr_from_template(&value,
2137 &template[i]);
2138 if (rv != CKR_OK)
2139 goto fail_cleanup;
2140 break;
2142 case CKA_VALUE_BITS:
2143 isValueBits = 1;
2144 rv = get_ulong_attr_from_template(&value_bits,
2145 &template[i]);
2146 if (rv != CKR_OK)
2147 goto fail_cleanup;
2148 break;
2150 case CKA_LABEL:
2151 isLabel = 1;
2152 rv = get_string_from_template(&string_tmp,
2153 &template[i]);
2154 if (rv != CKR_OK)
2155 goto fail_cleanup;
2156 break;
2158 case CKA_EC_PARAMS:
2159 isECParam = 1;
2160 rv = get_string_from_template(&param_tmp,
2161 &template[i]);
2162 if (rv != CKR_OK)
2163 goto fail_cleanup;
2164 break;
2166 default:
2167 rv = soft_parse_common_attrs(&template[i],
2168 &object_type);
2169 if (rv != CKR_OK)
2170 goto fail_cleanup;
2171 break;
2174 } /* For */
2176 /* Allocate storage for Private Key Object. */
2177 pvk = calloc(1, sizeof (private_key_obj_t));
2178 if (pvk == NULL) {
2179 rv = CKR_HOST_MEMORY;
2180 goto fail_cleanup;
2183 new_object->object_class_u.private_key = pvk;
2184 new_object->class = CKO_PRIVATE_KEY;
2186 if ((mode == SOFT_CREATE_OBJ) && (keytype == (CK_KEY_TYPE)~0UL)) {
2187 rv = CKR_TEMPLATE_INCOMPLETE;
2188 goto fail_cleanup;
2191 if (mode == SOFT_GEN_KEY) {
2193 * The key type is not specified in the application's
2194 * template, so we use the implied key type based on
2195 * the mechanism.
2197 if (keytype == (CK_KEY_TYPE)~0UL) {
2198 keytype = key_type;
2201 /* If still unspecified, template is incomplete */
2202 if (keytype == (CK_KEY_TYPE)~0UL) {
2203 rv = CKR_TEMPLATE_INCOMPLETE;
2204 goto fail_cleanup;
2208 * The key type specified in the template does not
2209 * match the implied key type based on the mechanism.
2211 if (keytype != key_type) {
2212 rv = CKR_TEMPLATE_INCONSISTENT;
2213 goto fail_cleanup;
2217 if (mode == SOFT_UNWRAP_KEY) {
2219 * Note that, for mode SOFT_UNWRAP_KEY, key type is not
2220 * implied by the mechanism (key_type), so if it is not
2221 * specified from the attribute template (keytype), it is
2222 * incomplete.
2224 if (keytype == (CK_KEY_TYPE)~0UL) {
2225 rv = CKR_TEMPLATE_INCOMPLETE;
2226 goto fail_cleanup;
2230 new_object->key_type = keytype;
2232 /* Supported key types of the Private Key Object */
2233 switch (keytype) {
2234 case CKK_RSA:
2235 if (isPrime || isSubprime || isBase || isValue ||
2236 isValueBits) {
2237 rv = CKR_TEMPLATE_INCONSISTENT;
2238 goto fail_cleanup;
2241 if (mode == SOFT_GEN_KEY || mode == SOFT_UNWRAP_KEY) {
2242 if (isModulus || isPubExpo || isPriExpo || isPrime1 ||
2243 isPrime2 || isExpo1 || isExpo2 || isCoef) {
2244 rv = CKR_TEMPLATE_INCONSISTENT;
2245 goto fail_cleanup;
2246 } else
2247 break;
2250 if (isModulus && isPriExpo) {
2252 * Copy big integer attribute value to the
2253 * designated place in the Private Key object.
2255 copy_bigint_attr(&modulus, KEY_PRI_RSA_MOD(pvk));
2257 copy_bigint_attr(&priexpo, KEY_PRI_RSA_PRIEXPO(pvk));
2258 } else {
2259 rv = CKR_TEMPLATE_INCOMPLETE;
2260 goto fail_cleanup;
2263 /* The following attributes are optional. */
2264 if (isPubExpo) {
2265 copy_bigint_attr(&pubexpo, KEY_PRI_RSA_PUBEXPO(pvk));
2268 if (isPrime1) {
2269 copy_bigint_attr(&prime1, KEY_PRI_RSA_PRIME1(pvk));
2272 if (isPrime2) {
2273 copy_bigint_attr(&prime2, KEY_PRI_RSA_PRIME2(pvk));
2276 if (isExpo1) {
2277 copy_bigint_attr(&expo1, KEY_PRI_RSA_EXPO1(pvk));
2280 if (isExpo2) {
2281 copy_bigint_attr(&expo2, KEY_PRI_RSA_EXPO2(pvk));
2284 if (isCoef) {
2285 copy_bigint_attr(&coef, KEY_PRI_RSA_COEF(pvk));
2287 break;
2289 case CKK_DSA:
2290 if (isModulus || isPubExpo || isPriExpo || isPrime1 ||
2291 isPrime2 || isExpo1 || isExpo2 || isCoef ||
2292 isValueBits) {
2293 rv = CKR_TEMPLATE_INCONSISTENT;
2294 goto fail_cleanup;
2297 if (mode == SOFT_GEN_KEY || mode == SOFT_UNWRAP_KEY) {
2298 if (isPrime || isSubprime || isBase || isValue) {
2299 rv = CKR_TEMPLATE_INCONSISTENT;
2300 goto fail_cleanup;
2301 } else
2302 break;
2305 if (isPrime && isSubprime && isBase && isValue) {
2307 * The private value x must be less than subprime q.
2308 * Size for big_init is in BIG_CHUNK_TYPE words.
2310 #ifdef __sparcv9
2311 if (big_init(&x,
2312 (int)CHARLEN2BIGNUMLEN(value.big_value_len))
2313 != BIG_OK) {
2314 #else /* !__sparcv9 */
2315 if (big_init(&x,
2316 CHARLEN2BIGNUMLEN(value.big_value_len))
2317 != BIG_OK) {
2318 #endif /* __sparcv9 */
2319 rv = CKR_HOST_MEMORY;
2320 goto fail_cleanup;
2322 #ifdef __sparcv9
2323 if (big_init(&q,
2324 (int)CHARLEN2BIGNUMLEN(subprime.big_value_len))
2325 != BIG_OK) {
2326 #else /* !__sparcv9 */
2327 if (big_init(&q,
2328 CHARLEN2BIGNUMLEN(subprime.big_value_len))
2329 != BIG_OK) {
2330 #endif /* __sparcv9 */
2331 rv = CKR_HOST_MEMORY;
2332 goto fail_cleanup;
2334 bytestring2bignum(&x, value.big_value,
2335 value.big_value_len);
2336 bytestring2bignum(&q, subprime.big_value,
2337 subprime.big_value_len);
2339 if (big_cmp_abs(&x, &q) > 0) {
2340 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2341 goto fail_cleanup;
2344 copy_bigint_attr(&prime, KEY_PRI_DSA_PRIME(pvk));
2346 copy_bigint_attr(&subprime, KEY_PRI_DSA_SUBPRIME(pvk));
2348 copy_bigint_attr(&base, KEY_PRI_DSA_BASE(pvk));
2350 copy_bigint_attr(&value, KEY_PRI_DSA_VALUE(pvk));
2351 } else {
2352 rv = CKR_TEMPLATE_INCOMPLETE;
2353 goto fail_cleanup;
2355 break;
2357 case CKK_DH:
2358 if (isModulus || isPubExpo || isPriExpo || isPrime1 ||
2359 isPrime2 || isExpo1 || isExpo2 || isCoef ||
2360 isSubprime) {
2361 rv = CKR_TEMPLATE_INCONSISTENT;
2362 goto fail_cleanup;
2365 /* CKA_VALUE_BITS is for key gen but not unwrap */
2366 if (mode == SOFT_GEN_KEY)
2367 KEY_PRI_DH_VAL_BITS(pvk) = (isValueBits) ?
2368 value_bits : 0;
2369 else if (mode == SOFT_UNWRAP_KEY) {
2370 if (isValueBits) {
2371 rv = CKR_TEMPLATE_INCONSISTENT;
2372 goto fail_cleanup;
2376 if (mode == SOFT_GEN_KEY || mode == SOFT_UNWRAP_KEY) {
2377 if (isPrime || isBase || isValue) {
2378 rv = CKR_TEMPLATE_INCONSISTENT;
2379 goto fail_cleanup;
2380 } else
2381 break;
2384 if (isValueBits) {
2385 rv = CKR_TEMPLATE_INCONSISTENT;
2386 goto fail_cleanup;
2389 if (isPrime && isBase && isValue) {
2390 copy_bigint_attr(&prime, KEY_PRI_DH_PRIME(pvk));
2392 copy_bigint_attr(&base, KEY_PRI_DH_BASE(pvk));
2394 copy_bigint_attr(&value, KEY_PRI_DH_VALUE(pvk));
2395 } else {
2396 rv = CKR_TEMPLATE_INCOMPLETE;
2397 goto fail_cleanup;
2399 break;
2401 case CKK_X9_42_DH:
2402 if (isModulus || isPubExpo || isPriExpo || isPrime1 ||
2403 isPrime2 || isExpo1 || isExpo2 || isCoef ||
2404 isValueBits) {
2405 rv = CKR_TEMPLATE_INCONSISTENT;
2406 goto fail_cleanup;
2409 if (mode == SOFT_GEN_KEY || mode == SOFT_UNWRAP_KEY) {
2410 if (isPrime || isSubprime || isBase || isValue) {
2411 rv = CKR_TEMPLATE_INCONSISTENT;
2412 goto fail_cleanup;
2413 } else
2414 break;
2417 if (isPrime && isSubprime && isBase && isValue) {
2418 copy_bigint_attr(&prime, KEY_PRI_DH942_PRIME(pvk));
2420 copy_bigint_attr(&base, KEY_PRI_DH942_BASE(pvk));
2422 copy_bigint_attr(&subprime,
2423 KEY_PRI_DH942_SUBPRIME(pvk));
2425 copy_bigint_attr(&value, KEY_PRI_DH942_VALUE(pvk));
2426 } else {
2427 rv = CKR_TEMPLATE_INCOMPLETE;
2428 goto fail_cleanup;
2430 break;
2432 case CKK_EC:
2433 if (isModulus || isPubExpo || isPrime ||
2434 isPrime1 || isPrime2 || isExpo1 || isExpo2 || isCoef ||
2435 isValueBits || isBase) {
2436 rv = CKR_TEMPLATE_INCONSISTENT;
2437 goto fail_cleanup;
2439 } else if (isECParam) {
2440 rv = soft_add_extra_attr(&param_tmp, new_object);
2441 if (rv != CKR_OK)
2442 goto fail_cleanup;
2443 string_attr_cleanup(&param_tmp);
2445 if (isValue) {
2446 copy_bigint_attr(&value, KEY_PRI_EC_VALUE(pvk));
2448 break;
2450 default:
2451 rv = CKR_TEMPLATE_INCONSISTENT;
2452 goto fail_cleanup;
2455 /* Set up object. */
2456 new_object->object_type = object_type;
2457 new_object->bool_attr_mask = attr_mask;
2458 if (isLabel) {
2459 rv = soft_add_extra_attr(&string_tmp, new_object);
2460 if (rv != CKR_OK)
2461 goto fail_cleanup;
2462 string_attr_cleanup(&string_tmp);
2464 big_finish(&x);
2465 big_finish(&q);
2467 return (rv);
2469 fail_cleanup:
2471 * cleanup the storage allocated to the local variables.
2473 bigint_attr_cleanup(&modulus);
2474 bigint_attr_cleanup(&priexpo);
2475 bigint_attr_cleanup(&prime);
2476 bigint_attr_cleanup(&subprime);
2477 bigint_attr_cleanup(&base);
2478 bigint_attr_cleanup(&value);
2479 bigint_attr_cleanup(&pubexpo);
2480 bigint_attr_cleanup(&prime1);
2481 bigint_attr_cleanup(&prime2);
2482 bigint_attr_cleanup(&expo1);
2483 bigint_attr_cleanup(&expo2);
2484 bigint_attr_cleanup(&coef);
2485 string_attr_cleanup(&string_tmp);
2486 string_attr_cleanup(&param_tmp);
2487 big_finish(&x);
2488 big_finish(&q);
2491 * cleanup the storage allocated inside the object itself.
2493 soft_cleanup_object(new_object);
2495 return (rv);
2500 * Build a Secret Key Object.
2502 * - Parse the object's template, and when an error is detected such as
2503 * invalid attribute type, invalid attribute value, etc., return
2504 * with appropriate return value.
2505 * - Set up attribute mask field in the object for the supplied common
2506 * attributes that have boolean type.
2507 * - Build the attribute_info struct to hold the value of each supplied
2508 * attribute that has byte array type. Link attribute_info structs
2509 * together to form the extra attribute list of the object.
2510 * - Allocate storage for the Secret Key object.
2511 * - Build the Secret Key object. Allocate storage to hold the big integer
2512 * value for the attribute CKA_VALUE that is required for all the key
2513 * types supported by secret key object.
2514 * This function is called internally with mode = SOFT_CREATE_OBJ_INT.
2517 CK_RV
2518 soft_build_secret_key_object(CK_ATTRIBUTE_PTR template, CK_ULONG ulAttrNum,
2519 soft_object_t *new_object, CK_ULONG mode, CK_ULONG key_len,
2520 CK_KEY_TYPE key_type)
2523 ulong_t i;
2524 CK_KEY_TYPE keytype = (CK_KEY_TYPE)~0UL;
2525 uint64_t attr_mask = SECRET_KEY_DEFAULT;
2526 CK_RV rv = CKR_OK;
2527 int isLabel = 0;
2528 /* Must set flags if mode != SOFT_UNWRAP_KEY, else must not set */
2529 int isValue = 0;
2530 /* Must not set flags if mode != SOFT_UNWRAP_KEY, else optional */
2531 int isValueLen = 0;
2533 CK_ATTRIBUTE string_tmp;
2535 secret_key_obj_t *sck;
2536 uchar_t object_type = 0;
2538 string_tmp.pValue = NULL;
2540 /* Allocate storage for Secret Key Object. */
2541 sck = calloc(1, sizeof (secret_key_obj_t));
2542 if (sck == NULL) {
2543 rv = CKR_HOST_MEMORY;
2544 goto fail_cleanup;
2547 new_object->object_class_u.secret_key = sck;
2548 new_object->class = CKO_SECRET_KEY;
2550 for (i = 0; i < ulAttrNum; i++) {
2552 /* Secret Key Object Attributes */
2553 switch (template[i].type) {
2555 /* common key attributes */
2556 case CKA_KEY_TYPE:
2557 keytype = *((CK_KEY_TYPE*)template[i].pValue);
2558 break;
2560 case CKA_ID:
2561 case CKA_START_DATE:
2562 case CKA_END_DATE:
2564 * Allocate storage to hold the attribute
2565 * value with byte array type, and add it to
2566 * the extra attribute list of the object.
2568 rv = soft_add_extra_attr(&template[i],
2569 new_object);
2570 if (rv != CKR_OK) {
2571 goto fail_cleanup;
2573 break;
2576 * The following key related attribute types must
2577 * not be specified by C_CreateObject and C_GenerateKey.
2579 case CKA_LOCAL:
2580 case CKA_KEY_GEN_MECHANISM:
2581 case CKA_ALWAYS_SENSITIVE:
2582 case CKA_NEVER_EXTRACTABLE:
2583 rv = CKR_TEMPLATE_INCONSISTENT;
2584 goto fail_cleanup;
2586 /* Key related boolean attributes */
2587 case CKA_DERIVE:
2588 if (*(CK_BBOOL *)template[i].pValue)
2589 attr_mask |= DERIVE_BOOL_ON;
2590 break;
2592 case CKA_SENSITIVE:
2593 if (*(CK_BBOOL *)template[i].pValue)
2594 attr_mask |= SENSITIVE_BOOL_ON;
2595 break;
2597 case CKA_ENCRYPT:
2598 if (*(CK_BBOOL *)template[i].pValue)
2599 attr_mask |= ENCRYPT_BOOL_ON;
2600 else
2601 attr_mask &= ~ENCRYPT_BOOL_ON;
2602 break;
2604 case CKA_DECRYPT:
2605 if (*(CK_BBOOL *)template[i].pValue)
2606 attr_mask |= DECRYPT_BOOL_ON;
2607 else
2608 attr_mask &= ~DECRYPT_BOOL_ON;
2609 break;
2611 case CKA_SIGN:
2612 if (*(CK_BBOOL *)template[i].pValue)
2613 attr_mask |= SIGN_BOOL_ON;
2614 else
2615 attr_mask &= ~SIGN_BOOL_ON;
2616 break;
2618 case CKA_VERIFY:
2619 if (*(CK_BBOOL *)template[i].pValue)
2620 attr_mask |= VERIFY_BOOL_ON;
2621 else
2622 attr_mask &= ~VERIFY_BOOL_ON;
2623 break;
2625 case CKA_WRAP:
2626 if (*(CK_BBOOL *)template[i].pValue)
2627 attr_mask |= WRAP_BOOL_ON;
2628 else
2629 attr_mask &= ~WRAP_BOOL_ON;
2630 break;
2632 case CKA_UNWRAP:
2633 if (*(CK_BBOOL *)template[i].pValue)
2634 attr_mask |= UNWRAP_BOOL_ON;
2635 else
2636 attr_mask &= ~UNWRAP_BOOL_ON;
2637 break;
2639 case CKA_EXTRACTABLE:
2640 if (*(CK_BBOOL *)template[i].pValue)
2641 attr_mask |= EXTRACTABLE_BOOL_ON;
2642 else
2643 attr_mask &= ~EXTRACTABLE_BOOL_ON;
2644 break;
2646 case CKA_MODIFIABLE:
2647 if ((*(CK_BBOOL *)template[i].pValue) == B_FALSE)
2648 attr_mask |= NOT_MODIFIABLE_BOOL_ON;
2649 break;
2651 case CKA_VALUE:
2652 isValue = 1;
2653 if (mode == SOFT_CREATE_OBJ) {
2654 if ((template[i].ulValueLen == 0) ||
2655 (template[i].pValue == NULL)) {
2656 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2657 goto fail_cleanup;
2662 * Copyin attribute from template
2663 * to a local variable.
2665 rv = get_bigint_attr_from_template((biginteger_t *)sck,
2666 &template[i]);
2667 if (rv != CKR_OK)
2668 goto fail_cleanup;
2669 break;
2671 case CKA_VALUE_LEN:
2672 isValueLen = 1;
2673 rv = get_ulong_attr_from_template(&sck->sk_value_len,
2674 &template[i]);
2675 if (rv != CKR_OK)
2676 goto fail_cleanup;
2677 break;
2679 case CKA_LABEL:
2680 isLabel = 1;
2681 rv = get_string_from_template(&string_tmp,
2682 &template[i]);
2683 if (rv != CKR_OK)
2684 goto fail_cleanup;
2685 break;
2687 default:
2688 rv = soft_parse_common_attrs(&template[i],
2689 &object_type);
2690 if (rv != CKR_OK)
2691 goto fail_cleanup;
2692 break;
2695 } /* For */
2697 switch (mode) {
2698 case SOFT_CREATE_OBJ:
2699 case SOFT_CREATE_OBJ_INT:
2700 case SOFT_DERIVE_KEY_DH:
2702 * The key type must be specified in the application's
2703 * template. Otherwise, returns error.
2705 if (keytype == (CK_KEY_TYPE)~0UL) {
2706 rv = CKR_TEMPLATE_INCOMPLETE;
2707 goto fail_cleanup;
2709 break;
2711 case SOFT_GEN_KEY:
2712 if (keytype == (CK_KEY_TYPE)~0UL) {
2714 * The key type is not specified in the application's
2715 * template, so we use the implied key type based on
2716 * the mechanism.
2718 keytype = key_type;
2719 } else {
2720 if (keytype != key_type) {
2722 * The key type specified in the template
2723 * does not match the implied key type based
2724 * on the mechanism.
2726 rv = CKR_TEMPLATE_INCONSISTENT;
2727 goto fail_cleanup;
2732 * If a key_len is passed as a parameter, it has to
2733 * match the one found in the template.
2735 if (key_len > 0) {
2736 if (isValueLen && sck->sk_value_len != key_len) {
2737 rv = CKR_TEMPLATE_INCONSISTENT;
2738 goto fail_cleanup;
2740 isValueLen = 1;
2741 sck->sk_value_len = key_len;
2743 break;
2745 case SOFT_UNWRAP_KEY:
2747 * Note that, for mode SOFT_UNWRAP_KEY, key type is not
2748 * implied by the mechanism (key_type), so if it is not
2749 * specified from the attribute template (keytype), it is
2750 * incomplete.
2752 if (keytype == (CK_KEY_TYPE)~0UL) {
2753 rv = CKR_TEMPLATE_INCOMPLETE;
2754 goto fail_cleanup;
2756 break;
2758 case SOFT_DERIVE_KEY_OTHER:
2760 * For CKM_MD5_KEY_DERIVATION & CKM_SHA1_KEY_DERIVATION, the
2761 * key type is optional.
2763 if (keytype == (CK_KEY_TYPE)~0UL) {
2764 keytype = key_type;
2766 break;
2769 switch (mode) {
2770 case SOFT_CREATE_OBJ:
2771 case SOFT_CREATE_OBJ_INT:
2772 switch (keytype) {
2773 case CKK_RC4:
2774 if (!isValue) {
2775 rv = CKR_TEMPLATE_INCOMPLETE;
2776 goto fail_cleanup;
2778 if ((sck->sk_value_len < ARCFOUR_MIN_KEY_BYTES) ||
2779 (sck->sk_value_len > ARCFOUR_MAX_KEY_BYTES)) {
2780 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2781 goto fail_cleanup;
2783 break;
2785 case CKK_GENERIC_SECRET:
2786 if (!isValue) {
2787 rv = CKR_TEMPLATE_INCOMPLETE;
2788 goto fail_cleanup;
2790 break;
2792 case CKK_AES:
2793 if (!isValue) {
2794 rv = CKR_TEMPLATE_INCOMPLETE;
2795 goto fail_cleanup;
2797 if ((sck->sk_value_len != AES_MIN_KEY_BYTES) &&
2798 (sck->sk_value_len != AES_192_KEY_BYTES) &&
2799 (sck->sk_value_len != AES_MAX_KEY_BYTES)) {
2800 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2801 goto fail_cleanup;
2803 break;
2805 case CKK_BLOWFISH:
2806 if (!isValue) {
2807 rv = CKR_TEMPLATE_INCOMPLETE;
2808 goto fail_cleanup;
2810 if ((sck->sk_value_len < BLOWFISH_MINBYTES) ||
2811 (sck->sk_value_len > BLOWFISH_MAXBYTES)) {
2812 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2813 goto fail_cleanup;
2816 break;
2818 case CKK_DES:
2819 if (!isValue) {
2820 rv = CKR_TEMPLATE_INCOMPLETE;
2821 goto fail_cleanup;
2823 if (sck->sk_value_len != DES_KEYSIZE) {
2824 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2825 goto fail_cleanup;
2827 break;
2829 case CKK_DES2:
2830 if (!isValue) {
2831 rv = CKR_TEMPLATE_INCOMPLETE;
2832 goto fail_cleanup;
2834 if (sck->sk_value_len != DES2_KEYSIZE) {
2835 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2836 goto fail_cleanup;
2838 break;
2840 case CKK_DES3:
2841 if (!isValue) {
2842 rv = CKR_TEMPLATE_INCOMPLETE;
2843 goto fail_cleanup;
2845 if (sck->sk_value_len != DES3_KEYSIZE) {
2846 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2847 goto fail_cleanup;
2849 break;
2851 default:
2852 rv = CKR_TEMPLATE_INCONSISTENT;
2853 goto fail_cleanup;
2856 if (isValueLen) {
2858 * Templates for internal object creation come from
2859 * applications calls to C_DeriveKey(), for which it
2860 * is OKey to pass a CKA_VALUE_LEN attribute, as
2861 * long as it does not conflict with the length of the
2862 * CKA_VALUE attribute.
2864 if ((mode != SOFT_CREATE_OBJ_INT) ||
2865 ((key_len > 0) && sck->sk_value_len != key_len)) {
2866 rv = CKR_TEMPLATE_INCONSISTENT;
2867 goto fail_cleanup;
2870 break;
2872 case SOFT_GEN_KEY:
2873 /* CKA_VALUE must not be specified */
2874 if (isValue) {
2875 rv = CKR_TEMPLATE_INCONSISTENT;
2876 goto fail_cleanup;
2879 switch (keytype) {
2881 * CKA_VALUE_LEN must be specified by C_GenerateKey
2882 * if mech is CKK_RC4, CKK_AES, CKK_GENERIC_SECRET.
2884 case CKK_RC4:
2885 if (!isValueLen) {
2886 rv = CKR_TEMPLATE_INCOMPLETE;
2887 goto fail_cleanup;
2890 if ((sck->sk_value_len < ARCFOUR_MIN_KEY_BYTES) ||
2891 (sck->sk_value_len > ARCFOUR_MAX_KEY_BYTES)) {
2892 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2893 goto fail_cleanup;
2895 break;
2897 case CKK_GENERIC_SECRET:
2898 /* arbitrary key length - no length checking */
2899 if (!isValueLen) {
2900 rv = CKR_TEMPLATE_INCOMPLETE;
2901 goto fail_cleanup;
2903 break;
2905 case CKK_AES:
2906 if (!isValueLen) {
2907 rv = CKR_TEMPLATE_INCOMPLETE;
2908 goto fail_cleanup;
2911 if ((sck->sk_value_len != AES_MIN_KEY_BYTES) &&
2912 (sck->sk_value_len != AES_192_KEY_BYTES) &&
2913 (sck->sk_value_len != AES_MAX_KEY_BYTES)) {
2914 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2915 goto fail_cleanup;
2918 break;
2920 case CKK_BLOWFISH:
2921 if (!isValueLen) {
2922 rv = CKR_TEMPLATE_INCOMPLETE;
2923 goto fail_cleanup;
2925 if ((sck->sk_value_len < BLOWFISH_MINBYTES) ||
2926 (sck->sk_value_len > BLOWFISH_MAXBYTES)) {
2927 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2928 goto fail_cleanup;
2931 break;
2933 case CKK_DES:
2934 case CKK_DES2:
2935 case CKK_DES3:
2936 /* CKA_VALUE_LEN attribute does not apply to DES<n> */
2937 if (isValueLen) {
2938 rv = CKR_TEMPLATE_INCONSISTENT;
2939 goto fail_cleanup;
2941 break;
2943 default:
2944 rv = CKR_TEMPLATE_INCONSISTENT;
2945 goto fail_cleanup;
2947 break;
2949 case SOFT_UNWRAP_KEY:
2951 * According to v2.11 of PKCS#11 spec, neither CKA_VALUE nor
2952 * CKA_VALUE_LEN can be be specified; however v2.20 has this
2953 * restriction removed, perhaps because it makes it hard to
2954 * determine variable-length key sizes. This case statement
2955 * complied with v2.20.
2957 if (isValue) {
2958 rv = CKR_TEMPLATE_INCONSISTENT;
2959 goto fail_cleanup;
2962 switch (keytype) {
2964 * CKA_VALUE_LEN is optional
2965 * if key is CKK_RC4, CKK_AES, CKK_GENERIC_SECRET
2966 * and the unwrapping mech is *_CBC_PAD.
2968 * CKA_VALUE_LEN is required
2969 * if key is CKK_RC4, CKK_AES, CKK_GENERIC_SECRET
2970 * and the unwrapping mech is *_ECB or *_CBC.
2972 * since mech is not known at this point, CKA_VALUE_LEN is
2973 * treated as optional and the caller needs to enforce it.
2975 case CKK_RC4:
2976 if (isValueLen) {
2977 if ((sck->sk_value_len <
2978 ARCFOUR_MIN_KEY_BYTES) ||
2979 (sck->sk_value_len >
2980 ARCFOUR_MAX_KEY_BYTES)) {
2981 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2982 goto fail_cleanup;
2985 break;
2987 case CKK_GENERIC_SECRET:
2988 /* arbitrary key length - no length checking */
2989 break;
2991 case CKK_AES:
2992 if (isValueLen) {
2993 if ((sck->sk_value_len != AES_MIN_KEY_BYTES) &&
2994 (sck->sk_value_len != AES_192_KEY_BYTES) &&
2995 (sck->sk_value_len != AES_MAX_KEY_BYTES)) {
2996 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2997 goto fail_cleanup;
3000 break;
3002 case CKK_BLOWFISH:
3003 if (isValueLen &&
3004 ((sck->sk_value_len < BLOWFISH_MINBYTES) ||
3005 (sck->sk_value_len > BLOWFISH_MAXBYTES))) {
3006 rv = CKR_ATTRIBUTE_VALUE_INVALID;
3007 goto fail_cleanup;
3009 break;
3011 case CKK_DES:
3012 case CKK_DES2:
3013 case CKK_DES3:
3014 /* CKA_VALUE_LEN attribute does not apply to DES<n> */
3015 if (isValueLen) {
3016 rv = CKR_TEMPLATE_INCONSISTENT;
3017 goto fail_cleanup;
3019 break;
3021 default:
3022 rv = CKR_TEMPLATE_INCONSISTENT;
3023 goto fail_cleanup;
3025 break;
3027 case SOFT_DERIVE_KEY_DH:
3028 /* CKA_VALUE must not be specified */
3029 if (isValue) {
3030 rv = CKR_TEMPLATE_INCONSISTENT;
3031 goto fail_cleanup;
3034 switch (keytype) {
3036 * CKA_VALUE_LEN is optional
3037 * if mech is CKK_RC4, CKK_AES, CKK_GENERIC_SECRET.
3039 case CKK_RC4:
3040 if (isValueLen) {
3041 if ((sck->sk_value_len <
3042 ARCFOUR_MIN_KEY_BYTES) ||
3043 (sck->sk_value_len >
3044 ARCFOUR_MAX_KEY_BYTES)) {
3045 rv = CKR_ATTRIBUTE_VALUE_INVALID;
3046 goto fail_cleanup;
3049 break;
3051 case CKK_GENERIC_SECRET:
3052 /* arbitrary key length - no length checking */
3053 break;
3055 case CKK_AES:
3056 if (isValueLen) {
3057 if ((sck->sk_value_len != AES_MIN_KEY_BYTES) &&
3058 (sck->sk_value_len != AES_192_KEY_BYTES) &&
3059 (sck->sk_value_len != AES_MAX_KEY_BYTES)) {
3060 rv = CKR_ATTRIBUTE_VALUE_INVALID;
3061 goto fail_cleanup;
3065 break;
3067 case CKK_BLOWFISH:
3068 if (isValueLen &&
3069 ((sck->sk_value_len < BLOWFISH_MINBYTES) ||
3070 (sck->sk_value_len > BLOWFISH_MAXBYTES))) {
3071 rv = CKR_ATTRIBUTE_VALUE_INVALID;
3072 goto fail_cleanup;
3074 break;
3076 case CKK_DES:
3077 case CKK_DES2:
3078 case CKK_DES3:
3079 /* CKA_VALUE_LEN attribute does not apply to DES<n> */
3080 if (isValueLen) {
3081 rv = CKR_TEMPLATE_INCONSISTENT;
3082 goto fail_cleanup;
3084 break;
3086 default:
3087 rv = CKR_TEMPLATE_INCONSISTENT;
3088 goto fail_cleanup;
3090 break;
3092 case SOFT_DERIVE_KEY_OTHER:
3093 /* CKA_VALUE must not be specified */
3094 if (isValue) {
3095 rv = CKR_TEMPLATE_INCONSISTENT;
3096 goto fail_cleanup;
3099 switch (keytype) {
3101 * CKA_VALUE_LEN is an optional attribute for
3102 * CKM_SHA1_KEY_DERIVATION and CKM_MD5_KEY_DERIVATION
3103 * if mech is CKK_RC4, CKK_AES, CKK_GENERIC_SECRET.
3105 case CKK_RC4:
3106 case CKK_GENERIC_SECRET:
3107 case CKK_AES:
3108 case CKK_BLOWFISH:
3110 * No need to check key length value here, it will be
3111 * validated later in soft_key_derive_check_length().
3113 break;
3115 case CKK_DES:
3116 case CKK_DES2:
3117 case CKK_DES3:
3118 /* CKA_VALUE_LEN attribute does not apply to DES<n> */
3119 if (isValueLen) {
3120 rv = CKR_TEMPLATE_INCONSISTENT;
3121 goto fail_cleanup;
3123 break;
3125 default:
3126 rv = CKR_TEMPLATE_INCONSISTENT;
3127 goto fail_cleanup;
3129 break;
3132 /* Set up object. */
3133 new_object->key_type = keytype;
3134 new_object->object_type = object_type;
3135 new_object->bool_attr_mask = attr_mask;
3136 if (isLabel) {
3137 rv = soft_add_extra_attr(&string_tmp, new_object);
3138 if (rv != CKR_OK)
3139 goto fail_cleanup;
3140 string_attr_cleanup(&string_tmp);
3142 return (rv);
3144 fail_cleanup:
3146 * cleanup the storage allocated to the local variables.
3148 bigint_attr_cleanup((biginteger_t *)sck);
3149 string_attr_cleanup(&string_tmp);
3152 * cleanup the storage allocated inside the object itself.
3154 soft_cleanup_object(new_object);
3156 return (rv);
3161 * Build a Domain Parameter Object.
3163 * - Parse the object's template, and when an error is detected such as
3164 * invalid attribute type, invalid attribute value, etc., return
3165 * with appropriate return value.
3166 * - Allocate storage for the Domain Parameter object.
3167 * - Build the Domain Parameter object according to the key type. Allocate
3168 * storage to hold the big integer value for the supplied attributes
3169 * that are required for a certain key type.
3172 CK_RV
3173 soft_build_domain_parameters_object(CK_ATTRIBUTE_PTR template,
3174 CK_ULONG ulAttrNum, soft_object_t *new_object)
3177 ulong_t i;
3178 CK_KEY_TYPE keytype = (CK_KEY_TYPE)~0UL;
3179 CK_RV rv = CKR_OK;
3180 int isLabel = 0;
3181 /* Must set flags */
3182 int isPrime = 0;
3183 int isSubprime = 0;
3184 int isBase = 0;
3185 /* Must not set flags */
3186 int isPrimeBits = 0;
3187 int isSubPrimeBits = 0;
3189 biginteger_t prime;
3190 biginteger_t subprime;
3191 biginteger_t base;
3192 CK_ATTRIBUTE string_tmp;
3194 domain_obj_t *dom;
3195 uchar_t object_type = 0;
3197 /* prevent bigint_attr_cleanup from freeing invalid attr value */
3198 (void) memset(&prime, 0x0, sizeof (biginteger_t));
3199 (void) memset(&subprime, 0x0, sizeof (biginteger_t));
3200 (void) memset(&base, 0x0, sizeof (biginteger_t));
3201 string_tmp.pValue = NULL;
3203 for (i = 0; i < ulAttrNum; i++) {
3205 /* Domain Parameters Object Attributes */
3206 switch (template[i].type) {
3208 /* common domain parameter attribute */
3209 case CKA_KEY_TYPE:
3210 keytype = *((CK_KEY_TYPE*)template[i].pValue);
3211 break;
3214 * The following common domain parameter attribute
3215 * must not be specified by C_CreateObject.
3217 case CKA_LOCAL:
3218 rv = CKR_TEMPLATE_INCONSISTENT;
3219 goto fail_cleanup;
3222 * The following domain parameter attributes must be
3223 * specified according to the key type by
3224 * C_CreateObject.
3226 case CKA_PRIME:
3227 isPrime = 1;
3229 * Copyin big integer attribute from template
3230 * to a local variable.
3232 rv = get_bigint_attr_from_template(&prime,
3233 &template[i]);
3234 if (rv != CKR_OK)
3235 goto fail_cleanup;
3236 break;
3238 case CKA_SUBPRIME:
3239 isSubprime = 1;
3240 rv = get_bigint_attr_from_template(&subprime,
3241 &template[i]);
3242 if (rv != CKR_OK)
3243 goto fail_cleanup;
3244 break;
3246 case CKA_BASE:
3247 isBase = 1;
3248 rv = get_bigint_attr_from_template(&base,
3249 &template[i]);
3250 if (rv != CKR_OK)
3251 goto fail_cleanup;
3252 break;
3254 case CKA_PRIME_BITS:
3255 isPrimeBits = 1;
3256 break;
3258 case CKA_SUB_PRIME_BITS:
3259 isSubPrimeBits = 1;
3260 break;
3262 case CKA_LABEL:
3263 isLabel = 1;
3264 rv = get_string_from_template(&string_tmp,
3265 &template[i]);
3266 if (rv != CKR_OK)
3267 goto fail_cleanup;
3268 break;
3270 default:
3271 rv = soft_parse_common_attrs(&template[i],
3272 &object_type);
3273 if (rv != CKR_OK)
3274 goto fail_cleanup;
3275 break;
3278 } /* For */
3280 /* Allocate storage for Domain Parameters Object. */
3281 dom = calloc(1, sizeof (domain_obj_t));
3282 if (dom == NULL) {
3283 rv = CKR_HOST_MEMORY;
3284 goto fail_cleanup;
3287 new_object->object_class_u.domain = dom;
3288 new_object->class = CKO_DOMAIN_PARAMETERS;
3290 if (keytype == (CK_KEY_TYPE)~0UL) {
3291 rv = CKR_TEMPLATE_INCOMPLETE;
3292 goto fail_cleanup;
3295 new_object->key_type = keytype;
3297 /* Supported key types of the Domain Parameters Object */
3298 switch (keytype) {
3299 case CKK_DSA:
3300 if (isPrimeBits || isSubPrimeBits) {
3301 rv = CKR_TEMPLATE_INCONSISTENT;
3302 goto fail_cleanup;
3305 if (isPrime && isSubprime && isBase) {
3307 * Copy big integer attribute value to the
3308 * designated place in the domain parameter
3309 * object.
3311 copy_bigint_attr(&prime, KEY_DOM_DSA_PRIME(dom));
3313 copy_bigint_attr(&subprime, KEY_DOM_DSA_SUBPRIME(dom));
3315 copy_bigint_attr(&base, KEY_DOM_DSA_BASE(dom));
3316 } else {
3317 rv = CKR_TEMPLATE_INCOMPLETE;
3318 goto fail_cleanup;
3320 break;
3322 case CKK_DH:
3323 if (isPrimeBits || isSubprime || isSubPrimeBits) {
3324 rv = CKR_TEMPLATE_INCONSISTENT;
3325 goto fail_cleanup;
3328 if (isPrime && isBase) {
3329 copy_bigint_attr(&prime, KEY_DOM_DH_PRIME(dom));
3331 copy_bigint_attr(&base, KEY_DOM_DH_BASE(dom));
3332 } else {
3333 rv = CKR_TEMPLATE_INCOMPLETE;
3334 goto fail_cleanup;
3336 break;
3338 case CKK_X9_42_DH:
3339 if (isPrimeBits || isSubPrimeBits) {
3340 rv = CKR_TEMPLATE_INCONSISTENT;
3341 goto fail_cleanup;
3344 if (isPrime && isSubprime && isBase) {
3345 copy_bigint_attr(&prime, KEY_DOM_DH942_PRIME(dom));
3347 copy_bigint_attr(&base, KEY_DOM_DH942_BASE(dom));
3349 copy_bigint_attr(&subprime,
3350 KEY_DOM_DH942_SUBPRIME(dom));
3351 } else {
3352 rv = CKR_TEMPLATE_INCOMPLETE;
3353 goto fail_cleanup;
3355 break;
3357 default:
3358 rv = CKR_TEMPLATE_INCONSISTENT;
3359 goto fail_cleanup;
3362 new_object->object_type = object_type;
3364 if (isLabel) {
3365 rv = soft_add_extra_attr(&string_tmp, new_object);
3366 if (rv != CKR_OK)
3367 goto fail_cleanup;
3368 string_attr_cleanup(&string_tmp);
3371 return (rv);
3373 fail_cleanup:
3375 * cleanup the storage allocated to the local variables.
3377 bigint_attr_cleanup(&prime);
3378 bigint_attr_cleanup(&subprime);
3379 bigint_attr_cleanup(&base);
3380 string_attr_cleanup(&string_tmp);
3383 * cleanup the storage allocated inside the object itself.
3385 soft_cleanup_object(new_object);
3387 return (rv);
3391 * Build a Certificate Object
3393 * - Parse the object's template, and when an error is detected such as
3394 * invalid attribute type, invalid attribute value, etc., return
3395 * with appropriate return value.
3396 * - Allocate storage for the Certificate object
3398 static CK_RV
3399 soft_build_certificate_object(CK_ATTRIBUTE_PTR template,
3400 CK_ULONG ulAttrNum, soft_object_t *new_object,
3401 CK_CERTIFICATE_TYPE cert_type)
3403 uint64_t attr_mask = 0;
3404 CK_RV rv = CKR_OK;
3405 CK_ULONG i;
3406 int owner_set = 0;
3407 int value_set = 0;
3408 int subject_set = 0;
3409 certificate_obj_t *cert;
3410 /* certificate type defaults to the value given as a parameter */
3411 CK_CERTIFICATE_TYPE certtype = cert_type;
3412 CK_ATTRIBUTE string_tmp;
3413 int isLabel = 0;
3414 uchar_t object_type = 0;
3417 * Look for the certificate type attribute and do some
3418 * sanity checking before creating the structures.
3420 for (i = 0; i < ulAttrNum; i++) {
3421 /* Certificate Object Attributes */
3422 switch (template[i].type) {
3423 case CKA_CERTIFICATE_TYPE:
3424 certtype =
3425 *((CK_CERTIFICATE_TYPE*)template[i].pValue);
3426 break;
3427 case CKA_SUBJECT:
3428 subject_set = 1;
3429 break;
3430 case CKA_OWNER:
3431 owner_set = 1;
3432 break;
3433 case CKA_VALUE:
3434 value_set = 1;
3435 break;
3439 /* The certificate type MUST be specified */
3440 if (certtype != CKC_X_509 && certtype != CKC_X_509_ATTR_CERT)
3441 return (CKR_TEMPLATE_INCOMPLETE);
3444 * For X.509 certs, the CKA_SUBJECT and CKA_VALUE
3445 * must be present at creation time.
3447 if (certtype == CKC_X_509 &&
3448 (!subject_set || !value_set))
3449 return (CKR_TEMPLATE_INCOMPLETE);
3452 * For X.509 Attribute certs, the CKA_OWNER and CKA_VALUE
3453 * must be present at creation time.
3455 if (certtype == CKC_X_509_ATTR_CERT &&
3456 (!owner_set || !value_set))
3457 return (CKR_TEMPLATE_INCOMPLETE);
3459 string_tmp.pValue = NULL;
3460 cert = calloc(1, sizeof (certificate_obj_t));
3461 if (cert == NULL) {
3462 return (CKR_HOST_MEMORY);
3464 cert->certificate_type = certtype;
3466 for (i = 0; i < ulAttrNum; i++) {
3467 /* Certificate Object Attributes */
3468 switch (certtype) {
3469 case CKC_X_509:
3470 switch (template[i].type) {
3471 case CKA_SUBJECT:
3472 rv = get_cert_attr_from_template(
3473 &cert->cert_type_u.x509.subject,
3474 &template[i]);
3475 break;
3476 case CKA_VALUE:
3477 rv = get_cert_attr_from_template(
3478 &cert->cert_type_u.x509.value,
3479 &template[i]);
3480 break;
3481 case CKA_LABEL:
3482 isLabel = 1;
3483 rv = get_string_from_template(
3484 &string_tmp,
3485 &template[i]);
3486 if (rv != CKR_OK)
3487 goto fail_cleanup;
3488 break;
3489 case CKA_ID:
3490 case CKA_ISSUER:
3491 case CKA_SERIAL_NUMBER:
3492 rv = soft_add_extra_attr(&template[i],
3493 new_object);
3494 break;
3495 case CKA_MODIFIABLE:
3496 if ((*(CK_BBOOL *)template[i].pValue) ==
3497 B_FALSE)
3498 attr_mask |=
3499 NOT_MODIFIABLE_BOOL_ON;
3500 break;
3501 case CKA_CERTIFICATE_TYPE:
3502 break;
3503 default:
3504 rv = soft_parse_common_attrs(
3505 &template[i], &object_type);
3506 if (rv != CKR_OK)
3507 goto fail_cleanup;
3509 break;
3510 case CKC_X_509_ATTR_CERT:
3511 switch (template[i].type) {
3512 case CKA_OWNER:
3513 rv = get_cert_attr_from_template(
3514 &cert->cert_type_u.x509_attr.owner,
3515 &template[i]);
3516 break;
3517 case CKA_VALUE:
3518 rv = get_cert_attr_from_template(
3519 &cert->cert_type_u.x509_attr.value,
3520 &template[i]);
3521 break;
3522 case CKA_LABEL:
3523 isLabel = 1;
3524 rv = get_string_from_template(
3525 &string_tmp, &template[i]);
3526 if (rv != CKR_OK)
3527 goto fail_cleanup;
3528 break;
3529 case CKA_SERIAL_NUMBER:
3530 case CKA_AC_ISSUER:
3531 case CKA_ATTR_TYPES:
3532 rv = soft_add_extra_attr(&template[i],
3533 new_object);
3534 break;
3536 case CKA_MODIFIABLE:
3537 if ((*(CK_BBOOL *)template[i].pValue) ==
3538 B_FALSE)
3539 attr_mask |=
3540 NOT_MODIFIABLE_BOOL_ON;
3541 break;
3542 case CKA_CERTIFICATE_TYPE:
3543 break;
3544 default:
3545 rv = soft_parse_common_attrs(
3546 &template[i], &object_type);
3547 if (rv != CKR_OK)
3548 goto fail_cleanup;
3549 break;
3551 break;
3552 default:
3553 rv = CKR_TEMPLATE_INCOMPLETE;
3554 break;
3558 if (rv == CKR_OK) {
3559 new_object->object_class_u.certificate = cert;
3560 new_object->class = CKO_CERTIFICATE;
3561 new_object->object_type = object_type;
3562 new_object->cert_type = certtype;
3563 new_object->bool_attr_mask = attr_mask;
3564 if (isLabel) {
3565 rv = soft_add_extra_attr(&string_tmp, new_object);
3566 if (rv != CKR_OK)
3567 goto fail_cleanup;
3568 string_attr_cleanup(&string_tmp);
3572 fail_cleanup:
3573 if (rv != CKR_OK) {
3574 soft_cleanup_cert_object(new_object);
3576 return (rv);
3581 * Validate the attribute types in the object's template. Then,
3582 * call the appropriate build function according to the class of
3583 * the object specified in the template.
3585 * Note: The following classes of objects are supported:
3586 * - CKO_PUBLIC_KEY
3587 * - CKO_PRIVATE_KEY
3588 * - CKO_SECRET_KEY
3589 * - CKO_DOMAIN_PARAMETERS
3590 * - CKO_CERTIFICATE
3593 CK_RV
3594 soft_build_object(CK_ATTRIBUTE_PTR template, CK_ULONG ulAttrNum,
3595 soft_object_t *new_object)
3598 CK_OBJECT_CLASS class = (CK_OBJECT_CLASS)~0UL;
3599 CK_RV rv = CKR_OK;
3601 if (template == NULL) {
3602 return (CKR_ARGUMENTS_BAD);
3605 /* Validate the attribute type in the template. */
3606 rv = soft_validate_attr(template, ulAttrNum, &class);
3607 if (rv != CKR_OK)
3608 return (rv);
3610 * CKA_CLASS is a mandatory attribute for C_CreateObject
3612 if (class == (CK_OBJECT_CLASS)~0UL)
3613 return (CKR_TEMPLATE_INCOMPLETE);
3616 * Call the appropriate function based on the supported class
3617 * of the object.
3619 switch (class) {
3620 case CKO_PUBLIC_KEY:
3621 rv = soft_build_public_key_object(template, ulAttrNum,
3622 new_object, SOFT_CREATE_OBJ, (CK_KEY_TYPE)~0UL);
3623 break;
3625 case CKO_PRIVATE_KEY:
3626 rv = soft_build_private_key_object(template, ulAttrNum,
3627 new_object, SOFT_CREATE_OBJ, (CK_KEY_TYPE)~0UL);
3628 break;
3630 case CKO_SECRET_KEY:
3631 rv = soft_build_secret_key_object(template, ulAttrNum,
3632 new_object, SOFT_CREATE_OBJ, 0, (CK_KEY_TYPE)~0UL);
3633 break;
3635 case CKO_DOMAIN_PARAMETERS:
3636 rv = soft_build_domain_parameters_object(template, ulAttrNum,
3637 new_object);
3638 break;
3640 case CKO_CERTIFICATE:
3641 rv = soft_build_certificate_object(template, ulAttrNum,
3642 new_object, (CK_CERTIFICATE_TYPE)~0UL);
3643 break;
3645 case CKO_DATA:
3646 case CKO_HW_FEATURE:
3647 case CKO_VENDOR_DEFINED:
3648 default:
3649 return (CKR_ATTRIBUTE_VALUE_INVALID);
3652 return (rv);
3656 * Validate the attribute types in the object's template. Then,
3657 * call the appropriate build function according to the class of
3658 * the object specified in the template.
3661 CK_RV
3662 soft_build_key(CK_ATTRIBUTE_PTR template, CK_ULONG ulAttrNum,
3663 soft_object_t *new_object, CK_OBJECT_CLASS class, CK_KEY_TYPE key_type,
3664 CK_ULONG key_len, CK_ULONG mode)
3667 CK_RV rv = CKR_OK;
3668 CK_OBJECT_CLASS temp_class = (CK_OBJECT_CLASS)~0UL;
3670 /* Validate the attribute type in the template. */
3671 if ((template != NULL) && (ulAttrNum != 0)) {
3672 rv = soft_validate_attr(template, ulAttrNum, &temp_class);
3673 if (rv != CKR_OK)
3674 return (rv);
3678 * If either the class from the parameter list ("class") or
3679 * the class from the template ("temp_class") is not specified,
3680 * try to use the other one.
3682 if (temp_class == (CK_OBJECT_CLASS)~0UL) {
3683 temp_class = class;
3684 } else if (class == (CK_OBJECT_CLASS)~0UL) {
3685 class = temp_class;
3688 /* If object class is still not specified, template is incomplete. */
3689 if (class == (CK_OBJECT_CLASS)~0UL)
3690 return (CKR_TEMPLATE_INCOMPLETE);
3692 /* Class should match if specified in both parameters and template. */
3693 if (class != temp_class)
3694 return (CKR_TEMPLATE_INCONSISTENT);
3697 * Call the appropriate function based on the supported class
3698 * of the object.
3700 switch (class) {
3701 case CKO_PUBLIC_KEY:
3703 /* Unwrapping public keys is not supported. */
3704 if (mode == SOFT_UNWRAP_KEY) {
3705 rv = CKR_ATTRIBUTE_VALUE_INVALID;
3706 break;
3709 rv = soft_build_public_key_object(template, ulAttrNum,
3710 new_object, mode, key_type);
3711 break;
3713 case CKO_PRIVATE_KEY:
3715 rv = soft_build_private_key_object(template, ulAttrNum,
3716 new_object, mode, key_type);
3717 break;
3719 case CKO_SECRET_KEY:
3721 rv = soft_build_secret_key_object(template, ulAttrNum,
3722 new_object, mode, key_len, key_type);
3723 break;
3725 case CKO_DOMAIN_PARAMETERS:
3727 /* Unwrapping domain parameters is not supported. */
3728 if (mode == SOFT_UNWRAP_KEY) {
3729 rv = CKR_ATTRIBUTE_VALUE_INVALID;
3730 break;
3733 rv = soft_build_domain_parameters_object(template, ulAttrNum,
3734 new_object);
3735 break;
3737 case CKO_DATA:
3738 case CKO_CERTIFICATE:
3739 case CKO_HW_FEATURE:
3740 case CKO_VENDOR_DEFINED:
3741 default:
3742 return (CKR_ATTRIBUTE_VALUE_INVALID);
3745 return (rv);
3750 * Get the value of a requested attribute that is common to all supported
3751 * classes (i.e. public key, private key, secret key, domain parameters,
3752 * and certificate classes).
3754 CK_RV
3755 soft_get_common_attrs(soft_object_t *object_p, CK_ATTRIBUTE_PTR template,
3756 uchar_t object_type)
3759 CK_RV rv = CKR_OK;
3761 switch (template->type) {
3763 case CKA_CLASS:
3764 return (get_ulong_attr_from_object(object_p->class,
3765 template));
3767 /* default boolean attributes */
3768 case CKA_TOKEN:
3769 template->ulValueLen = sizeof (CK_BBOOL);
3770 if (template->pValue == NULL) {
3771 return (CKR_OK);
3773 if (object_type & TOKEN_OBJECT)
3774 *((CK_BBOOL *)template->pValue) = B_TRUE;
3775 else
3776 *((CK_BBOOL *)template->pValue) = B_FALSE;
3777 break;
3779 case CKA_PRIVATE:
3781 template->ulValueLen = sizeof (CK_BBOOL);
3782 if (template->pValue == NULL) {
3783 return (CKR_OK);
3785 if (object_type & PRIVATE_OBJECT)
3786 *((CK_BBOOL *)template->pValue) = B_TRUE;
3787 else
3788 *((CK_BBOOL *)template->pValue) = B_FALSE;
3789 break;
3791 case CKA_MODIFIABLE:
3792 template->ulValueLen = sizeof (CK_BBOOL);
3793 if (template->pValue == NULL) {
3794 return (CKR_OK);
3796 if ((object_p->bool_attr_mask) & NOT_MODIFIABLE_BOOL_ON)
3797 *((CK_BBOOL *)template->pValue) = B_FALSE;
3798 else
3799 *((CK_BBOOL *)template->pValue) = B_TRUE;
3800 break;
3802 case CKA_LABEL:
3803 return (get_extra_attr_from_object(object_p,
3804 template));
3806 default:
3808 * The specified attribute for the object is invalid.
3809 * (the object does not possess such an attribute.)
3811 template->ulValueLen = (CK_ULONG)-1;
3812 return (CKR_ATTRIBUTE_TYPE_INVALID);
3815 return (rv);
3819 * Get the value of a requested attribute that is common to all key objects
3820 * (i.e. public key, private key and secret key).
3822 CK_RV
3823 soft_get_common_key_attrs(soft_object_t *object_p, CK_ATTRIBUTE_PTR template)
3826 switch (template->type) {
3828 case CKA_KEY_TYPE:
3829 return (get_ulong_attr_from_object(object_p->key_type,
3830 template));
3832 case CKA_ID:
3833 case CKA_START_DATE:
3834 case CKA_END_DATE:
3836 * The above extra attributes have byte array type.
3838 return (get_extra_attr_from_object(object_p,
3839 template));
3841 /* Key related boolean attributes */
3842 case CKA_LOCAL:
3843 return (get_bool_attr_from_object(object_p,
3844 LOCAL_BOOL_ON, template));
3846 case CKA_DERIVE:
3847 return (get_bool_attr_from_object(object_p,
3848 DERIVE_BOOL_ON, template));
3850 case CKA_KEY_GEN_MECHANISM:
3851 return (get_ulong_attr_from_object(object_p->mechanism,
3852 template));
3854 default:
3855 return (CKR_ATTRIBUTE_TYPE_INVALID);
3860 * Get the value of a requested attribute of a Public Key Object.
3862 * Rule: All the attributes in the public key object can be revealed.
3864 CK_RV
3865 soft_get_public_key_attribute(soft_object_t *object_p,
3866 CK_ATTRIBUTE_PTR template)
3869 CK_RV rv = CKR_OK;
3870 CK_KEY_TYPE keytype = object_p->key_type;
3872 switch (template->type) {
3874 case CKA_SUBJECT:
3875 case CKA_EC_PARAMS:
3877 * The above extra attributes have byte array type.
3879 return (get_extra_attr_from_object(object_p,
3880 template));
3882 /* Key related boolean attributes */
3883 case CKA_ENCRYPT:
3884 return (get_bool_attr_from_object(object_p,
3885 ENCRYPT_BOOL_ON, template));
3887 case CKA_VERIFY:
3888 return (get_bool_attr_from_object(object_p,
3889 VERIFY_BOOL_ON, template));
3891 case CKA_VERIFY_RECOVER:
3892 return (get_bool_attr_from_object(object_p,
3893 VERIFY_RECOVER_BOOL_ON, template));
3895 case CKA_WRAP:
3896 return (get_bool_attr_from_object(object_p,
3897 WRAP_BOOL_ON, template));
3899 case CKA_TRUSTED:
3900 return (get_bool_attr_from_object(object_p,
3901 TRUSTED_BOOL_ON, template));
3903 case CKA_MODULUS:
3905 * This attribute is valid only for RSA public key
3906 * object.
3908 if (keytype == CKK_RSA) {
3909 return (get_bigint_attr_from_object(
3910 OBJ_PUB_RSA_MOD(object_p), template));
3911 } else {
3912 template->ulValueLen = (CK_ULONG)-1;
3913 return (CKR_ATTRIBUTE_TYPE_INVALID);
3916 case CKA_PUBLIC_EXPONENT:
3917 if (keytype == CKK_RSA) {
3918 return (get_bigint_attr_from_object(
3919 OBJ_PUB_RSA_PUBEXPO(object_p), template));
3920 } else {
3921 template->ulValueLen = (CK_ULONG)-1;
3922 return (CKR_ATTRIBUTE_TYPE_INVALID);
3925 case CKA_MODULUS_BITS:
3926 if (keytype == CKK_RSA) {
3927 return (get_ulong_attr_from_object(
3928 OBJ_PUB_RSA_MOD_BITS(object_p), template));
3929 } else {
3930 template->ulValueLen = (CK_ULONG)-1;
3931 return (CKR_ATTRIBUTE_TYPE_INVALID);
3934 case CKA_PRIME:
3935 switch (keytype) {
3936 case CKK_DSA:
3937 return (get_bigint_attr_from_object(
3938 OBJ_PUB_DSA_PRIME(object_p), template));
3940 case CKK_DH:
3941 return (get_bigint_attr_from_object(
3942 OBJ_PUB_DH_PRIME(object_p), template));
3944 case CKK_X9_42_DH:
3945 return (get_bigint_attr_from_object(
3946 OBJ_PUB_DH942_PRIME(object_p), template));
3948 default:
3949 template->ulValueLen = (CK_ULONG)-1;
3950 return (CKR_ATTRIBUTE_TYPE_INVALID);
3953 case CKA_SUBPRIME:
3954 switch (keytype) {
3955 case CKK_DSA:
3956 return (get_bigint_attr_from_object(
3957 OBJ_PUB_DSA_SUBPRIME(object_p), template));
3959 case CKK_X9_42_DH:
3960 return (get_bigint_attr_from_object(
3961 OBJ_PUB_DH942_SUBPRIME(object_p), template));
3963 default:
3964 template->ulValueLen = (CK_ULONG)-1;
3965 return (CKR_ATTRIBUTE_TYPE_INVALID);
3968 case CKA_BASE:
3969 switch (keytype) {
3970 case CKK_DSA:
3971 return (get_bigint_attr_from_object(
3972 OBJ_PUB_DSA_BASE(object_p), template));
3974 case CKK_DH:
3975 return (get_bigint_attr_from_object(
3976 OBJ_PUB_DH_BASE(object_p), template));
3978 case CKK_X9_42_DH:
3979 return (get_bigint_attr_from_object(
3980 OBJ_PUB_DH942_BASE(object_p), template));
3982 default:
3983 template->ulValueLen = (CK_ULONG)-1;
3984 return (CKR_ATTRIBUTE_TYPE_INVALID);
3987 case CKA_EC_POINT:
3988 return (get_bigint_attr_from_object(
3989 OBJ_PUB_EC_POINT(object_p), template));
3991 case CKA_VALUE:
3992 switch (keytype) {
3993 case CKK_DSA:
3994 return (get_bigint_attr_from_object(
3995 OBJ_PUB_DSA_VALUE(object_p), template));
3997 case CKK_DH:
3998 return (get_bigint_attr_from_object(
3999 OBJ_PUB_DH_VALUE(object_p), template));
4001 case CKK_X9_42_DH:
4002 return (get_bigint_attr_from_object(
4003 OBJ_PUB_DH942_VALUE(object_p), template));
4005 default:
4006 template->ulValueLen = (CK_ULONG)-1;
4007 return (CKR_ATTRIBUTE_TYPE_INVALID);
4010 default:
4012 * First, get the value of the request attribute defined
4013 * in the list of common key attributes. If the request
4014 * attribute is not found in that list, then get the
4015 * attribute from the list of common attributes.
4017 rv = soft_get_common_key_attrs(object_p, template);
4018 if (rv == CKR_ATTRIBUTE_TYPE_INVALID) {
4019 rv = soft_get_common_attrs(object_p, template,
4020 object_p->object_type);
4022 break;
4025 return (rv);
4030 * Get the value of a requested attribute of a Private Key Object.
4032 * Rule: All the attributes in the private key object can be revealed
4033 * except those marked with footnote number "7" when the object
4034 * has its CKA_SENSITIVE attribute set to TRUE or its
4035 * CKA_EXTRACTABLE attribute set to FALSE (p.88 in PKCS11 spec.).
4037 CK_RV
4038 soft_get_private_key_attribute(soft_object_t *object_p,
4039 CK_ATTRIBUTE_PTR template)
4042 CK_RV rv = CKR_OK;
4043 CK_KEY_TYPE keytype = object_p->key_type;
4047 * If the following specified attributes for the private key
4048 * object cannot be revealed because the object is sensitive
4049 * or unextractable, then the ulValueLen is set to -1.
4051 if ((object_p->bool_attr_mask & SENSITIVE_BOOL_ON) ||
4052 !(object_p->bool_attr_mask & EXTRACTABLE_BOOL_ON)) {
4054 switch (template->type) {
4055 case CKA_PRIVATE_EXPONENT:
4056 case CKA_PRIME_1:
4057 case CKA_PRIME_2:
4058 case CKA_EXPONENT_1:
4059 case CKA_EXPONENT_2:
4060 case CKA_COEFFICIENT:
4061 case CKA_VALUE:
4062 template->ulValueLen = (CK_ULONG)-1;
4063 return (CKR_ATTRIBUTE_SENSITIVE);
4067 switch (template->type) {
4069 case CKA_SUBJECT:
4070 case CKA_EC_PARAMS:
4072 * The above extra attributes have byte array type.
4074 return (get_extra_attr_from_object(object_p,
4075 template));
4077 /* Key related boolean attributes */
4078 case CKA_SENSITIVE:
4079 return (get_bool_attr_from_object(object_p,
4080 SENSITIVE_BOOL_ON, template));
4082 case CKA_SECONDARY_AUTH:
4083 return (get_bool_attr_from_object(object_p,
4084 SECONDARY_AUTH_BOOL_ON, template));
4086 case CKA_DECRYPT:
4087 return (get_bool_attr_from_object(object_p,
4088 DECRYPT_BOOL_ON, template));
4090 case CKA_SIGN:
4091 return (get_bool_attr_from_object(object_p,
4092 SIGN_BOOL_ON, template));
4094 case CKA_SIGN_RECOVER:
4095 return (get_bool_attr_from_object(object_p,
4096 SIGN_RECOVER_BOOL_ON, template));
4098 case CKA_UNWRAP:
4099 return (get_bool_attr_from_object(object_p,
4100 UNWRAP_BOOL_ON, template));
4102 case CKA_EXTRACTABLE:
4103 return (get_bool_attr_from_object(object_p,
4104 EXTRACTABLE_BOOL_ON, template));
4106 case CKA_ALWAYS_SENSITIVE:
4107 return (get_bool_attr_from_object(object_p,
4108 ALWAYS_SENSITIVE_BOOL_ON, template));
4110 case CKA_NEVER_EXTRACTABLE:
4111 return (get_bool_attr_from_object(object_p,
4112 NEVER_EXTRACTABLE_BOOL_ON, template));
4114 case CKA_MODULUS:
4115 if (keytype == CKK_RSA) {
4116 return (get_bigint_attr_from_object(
4117 OBJ_PRI_RSA_MOD(object_p), template));
4118 } else {
4119 template->ulValueLen = (CK_ULONG)-1;
4120 rv = CKR_ATTRIBUTE_TYPE_INVALID;
4121 break;
4124 case CKA_PUBLIC_EXPONENT:
4125 if (keytype == CKK_RSA) {
4126 return (get_bigint_attr_from_object(
4127 OBJ_PRI_RSA_PUBEXPO(object_p), template));
4128 } else {
4129 template->ulValueLen = (CK_ULONG)-1;
4130 rv = CKR_ATTRIBUTE_TYPE_INVALID;
4131 break;
4134 case CKA_PRIVATE_EXPONENT:
4135 if (keytype == CKK_RSA) {
4136 return (get_bigint_attr_from_object(
4137 OBJ_PRI_RSA_PRIEXPO(object_p), template));
4138 } else {
4139 template->ulValueLen = (CK_ULONG)-1;
4140 rv = CKR_ATTRIBUTE_TYPE_INVALID;
4141 break;
4144 case CKA_PRIME_1:
4145 if (keytype == CKK_RSA) {
4146 return (get_bigint_attr_from_object(
4147 OBJ_PRI_RSA_PRIME1(object_p), template));
4148 } else {
4149 template->ulValueLen = (CK_ULONG)-1;
4150 rv = CKR_ATTRIBUTE_TYPE_INVALID;
4151 break;
4154 case CKA_PRIME_2:
4155 if (keytype == CKK_RSA) {
4156 return (get_bigint_attr_from_object(
4157 OBJ_PRI_RSA_PRIME2(object_p), template));
4158 } else {
4159 template->ulValueLen = (CK_ULONG)-1;
4160 rv = CKR_ATTRIBUTE_TYPE_INVALID;
4161 break;
4164 case CKA_EXPONENT_1:
4165 if (keytype == CKK_RSA) {
4166 return (get_bigint_attr_from_object(
4167 OBJ_PRI_RSA_EXPO1(object_p), template));
4168 } else {
4169 template->ulValueLen = (CK_ULONG)-1;
4170 rv = CKR_ATTRIBUTE_TYPE_INVALID;
4171 break;
4174 case CKA_EXPONENT_2:
4175 if (keytype == CKK_RSA) {
4176 return (get_bigint_attr_from_object(
4177 OBJ_PRI_RSA_EXPO2(object_p), template));
4178 } else {
4179 template->ulValueLen = (CK_ULONG)-1;
4180 rv = CKR_ATTRIBUTE_TYPE_INVALID;
4181 break;
4184 case CKA_COEFFICIENT:
4185 if (keytype == CKK_RSA) {
4186 return (get_bigint_attr_from_object(
4187 OBJ_PRI_RSA_COEF(object_p), template));
4188 } else {
4189 template->ulValueLen = (CK_ULONG)-1;
4190 rv = CKR_ATTRIBUTE_TYPE_INVALID;
4191 break;
4194 case CKA_VALUE_BITS:
4195 if (keytype == CKK_DH) {
4196 return (get_ulong_attr_from_object(
4197 OBJ_PRI_DH_VAL_BITS(object_p), template));
4198 } else {
4199 template->ulValueLen = (CK_ULONG)-1;
4200 rv = CKR_ATTRIBUTE_TYPE_INVALID;
4201 break;
4204 case CKA_PRIME:
4205 switch (keytype) {
4206 case CKK_DSA:
4207 return (get_bigint_attr_from_object(
4208 OBJ_PRI_DSA_PRIME(object_p), template));
4210 case CKK_DH:
4211 return (get_bigint_attr_from_object(
4212 OBJ_PRI_DH_PRIME(object_p), template));
4214 case CKK_X9_42_DH:
4215 return (get_bigint_attr_from_object(
4216 OBJ_PRI_DH942_PRIME(object_p), template));
4218 default:
4219 template->ulValueLen = (CK_ULONG)-1;
4220 return (CKR_ATTRIBUTE_TYPE_INVALID);
4223 case CKA_SUBPRIME:
4224 switch (keytype) {
4225 case CKK_DSA:
4226 return (get_bigint_attr_from_object(
4227 OBJ_PRI_DSA_SUBPRIME(object_p), template));
4229 case CKK_X9_42_DH:
4230 return (get_bigint_attr_from_object(
4231 OBJ_PRI_DH942_SUBPRIME(object_p), template));
4233 default:
4234 template->ulValueLen = (CK_ULONG)-1;
4235 return (CKR_ATTRIBUTE_TYPE_INVALID);
4238 case CKA_BASE:
4239 switch (keytype) {
4240 case CKK_DSA:
4241 return (get_bigint_attr_from_object(
4242 OBJ_PRI_DSA_BASE(object_p), template));
4244 case CKK_DH:
4245 return (get_bigint_attr_from_object(
4246 OBJ_PRI_DH_BASE(object_p), template));
4248 case CKK_X9_42_DH:
4249 return (get_bigint_attr_from_object(
4250 OBJ_PRI_DH942_BASE(object_p), template));
4252 default:
4253 template->ulValueLen = (CK_ULONG)-1;
4254 return (CKR_ATTRIBUTE_TYPE_INVALID);
4257 case CKA_VALUE:
4258 switch (keytype) {
4259 case CKK_DSA:
4260 return (get_bigint_attr_from_object(
4261 OBJ_PRI_DSA_VALUE(object_p), template));
4263 case CKK_DH:
4264 return (get_bigint_attr_from_object(
4265 OBJ_PRI_DH_VALUE(object_p), template));
4267 case CKK_X9_42_DH:
4268 return (get_bigint_attr_from_object(
4269 OBJ_PRI_DH942_VALUE(object_p), template));
4271 case CKK_EC:
4272 return (get_bigint_attr_from_object(
4273 OBJ_PRI_EC_VALUE(object_p), template));
4275 default:
4276 template->ulValueLen = (CK_ULONG)-1;
4277 return (CKR_ATTRIBUTE_TYPE_INVALID);
4280 default:
4282 * First, get the value of the request attribute defined
4283 * in the list of common key attributes. If the request
4284 * attribute is not found in that list, then get the
4285 * attribute from the list of common attributes.
4287 rv = soft_get_common_key_attrs(object_p, template);
4288 if (rv == CKR_ATTRIBUTE_TYPE_INVALID) {
4289 rv = soft_get_common_attrs(object_p, template,
4290 object_p->object_type);
4292 break;
4295 return (rv);
4300 * Get the value of a requested attribute of a Secret Key Object.
4302 * Rule: All the attributes in the secret key object can be revealed
4303 * except those marked with footnote number "7" when the object
4304 * has its CKA_SENSITIVE attribute set to TRUE or its
4305 * CKA_EXTRACTABLE attribute set to FALSE (p.88 in PKCS11 spec.).
4307 CK_RV
4308 soft_get_secret_key_attribute(soft_object_t *object_p,
4309 CK_ATTRIBUTE_PTR template)
4312 CK_RV rv = CKR_OK;
4313 CK_KEY_TYPE keytype = object_p->key_type;
4315 switch (template->type) {
4317 /* Key related boolean attributes */
4318 case CKA_SENSITIVE:
4319 return (get_bool_attr_from_object(object_p,
4320 SENSITIVE_BOOL_ON, template));
4322 case CKA_ENCRYPT:
4323 return (get_bool_attr_from_object(object_p,
4324 ENCRYPT_BOOL_ON, template));
4326 case CKA_DECRYPT:
4327 return (get_bool_attr_from_object(object_p,
4328 DECRYPT_BOOL_ON, template));
4330 case CKA_SIGN:
4331 return (get_bool_attr_from_object(object_p,
4332 SIGN_BOOL_ON, template));
4334 case CKA_VERIFY:
4335 return (get_bool_attr_from_object(object_p,
4336 VERIFY_BOOL_ON, template));
4338 case CKA_WRAP:
4339 return (get_bool_attr_from_object(object_p,
4340 WRAP_BOOL_ON, template));
4342 case CKA_UNWRAP:
4343 return (get_bool_attr_from_object(object_p,
4344 UNWRAP_BOOL_ON, template));
4346 case CKA_EXTRACTABLE:
4347 return (get_bool_attr_from_object(object_p,
4348 EXTRACTABLE_BOOL_ON, template));
4350 case CKA_ALWAYS_SENSITIVE:
4351 return (get_bool_attr_from_object(object_p,
4352 ALWAYS_SENSITIVE_BOOL_ON, template));
4354 case CKA_NEVER_EXTRACTABLE:
4355 return (get_bool_attr_from_object(object_p,
4356 NEVER_EXTRACTABLE_BOOL_ON, template));
4358 case CKA_VALUE:
4359 case CKA_VALUE_LEN:
4361 * If the specified attribute for the secret key object
4362 * cannot be revealed because the object is sensitive
4363 * or unextractable, then the ulValueLen is set to -1.
4365 if ((object_p->bool_attr_mask & SENSITIVE_BOOL_ON) ||
4366 !(object_p->bool_attr_mask & EXTRACTABLE_BOOL_ON)) {
4367 template->ulValueLen = (CK_ULONG)-1;
4368 return (CKR_ATTRIBUTE_SENSITIVE);
4371 switch (keytype) {
4372 case CKK_RC4:
4373 case CKK_GENERIC_SECRET:
4374 case CKK_RC5:
4375 case CKK_DES:
4376 case CKK_DES2:
4377 case CKK_DES3:
4378 case CKK_CDMF:
4379 case CKK_AES:
4380 case CKK_BLOWFISH:
4381 if (template->type == CKA_VALUE_LEN) {
4382 return (get_ulong_attr_from_object(
4383 OBJ_SEC_VALUE_LEN(object_p),
4384 template));
4385 } else {
4386 return (get_bigint_attr_from_object(
4387 (biginteger_t *)OBJ_SEC(object_p),
4388 template));
4390 default:
4391 template->ulValueLen = (CK_ULONG)-1;
4392 rv = CKR_ATTRIBUTE_TYPE_INVALID;
4393 break;
4395 break;
4397 default:
4399 * First, get the value of the request attribute defined
4400 * in the list of common key attributes. If the request
4401 * attribute is not found in that list, then get the
4402 * attribute from the list of common attributes.
4404 rv = soft_get_common_key_attrs(object_p, template);
4405 if (rv == CKR_ATTRIBUTE_TYPE_INVALID) {
4406 rv = soft_get_common_attrs(object_p, template,
4407 object_p->object_type);
4409 break;
4412 return (rv);
4417 * Get the value of a requested attribute of a Domain Parameters Object.
4419 * Rule: All the attributes in the domain parameters object can be revealed.
4421 CK_RV
4422 soft_get_domain_parameters_attribute(soft_object_t *object_p,
4423 CK_ATTRIBUTE_PTR template)
4426 CK_RV rv = CKR_OK;
4427 CK_KEY_TYPE keytype = object_p->key_type;
4429 switch (template->type) {
4431 case CKA_KEY_TYPE:
4432 return (get_ulong_attr_from_object(keytype,
4433 template));
4435 case CKA_LOCAL:
4436 return (get_bool_attr_from_object(object_p,
4437 LOCAL_BOOL_ON, template));
4439 case CKA_PRIME:
4440 switch (keytype) {
4441 case CKK_DSA:
4442 return (get_bigint_attr_from_object(
4443 OBJ_DOM_DSA_PRIME(object_p), template));
4445 case CKK_DH:
4446 return (get_bigint_attr_from_object(
4447 OBJ_DOM_DH_PRIME(object_p), template));
4449 case CKK_X9_42_DH:
4450 return (get_bigint_attr_from_object(
4451 OBJ_DOM_DH942_PRIME(object_p), template));
4453 default:
4454 template->ulValueLen = (CK_ULONG)-1;
4455 return (CKR_ATTRIBUTE_TYPE_INVALID);
4458 case CKA_SUBPRIME:
4459 switch (keytype) {
4460 case CKK_DSA:
4461 return (get_bigint_attr_from_object(
4462 OBJ_DOM_DSA_SUBPRIME(object_p), template));
4464 case CKK_X9_42_DH:
4465 return (get_bigint_attr_from_object(
4466 OBJ_DOM_DH942_SUBPRIME(object_p), template));
4468 default:
4469 template->ulValueLen = (CK_ULONG)-1;
4470 return (CKR_ATTRIBUTE_TYPE_INVALID);
4473 case CKA_BASE:
4474 switch (keytype) {
4475 case CKK_DSA:
4476 return (get_bigint_attr_from_object(
4477 OBJ_DOM_DSA_BASE(object_p), template));
4479 case CKK_DH:
4480 return (get_bigint_attr_from_object(
4481 OBJ_DOM_DH_BASE(object_p), template));
4483 case CKK_X9_42_DH:
4484 return (get_bigint_attr_from_object(
4485 OBJ_DOM_DH942_BASE(object_p), template));
4487 default:
4488 template->ulValueLen = (CK_ULONG)-1;
4489 return (CKR_ATTRIBUTE_TYPE_INVALID);
4492 case CKA_PRIME_BITS:
4493 switch (keytype) {
4494 case CKK_DSA:
4495 return (get_ulong_attr_from_object(
4496 OBJ_DOM_DSA_PRIME_BITS(object_p), template));
4498 case CKK_DH:
4499 return (get_ulong_attr_from_object(
4500 OBJ_DOM_DH_PRIME_BITS(object_p), template));
4502 case CKK_X9_42_DH:
4503 return (get_ulong_attr_from_object(
4504 OBJ_DOM_DH942_PRIME_BITS(object_p), template));
4506 default:
4507 template->ulValueLen = (CK_ULONG)-1;
4508 return (CKR_ATTRIBUTE_TYPE_INVALID);
4511 case CKA_SUB_PRIME_BITS:
4512 switch (keytype) {
4513 case CKK_X9_42_DH:
4514 return (get_ulong_attr_from_object(
4515 OBJ_DOM_DH942_SUBPRIME_BITS(object_p), template));
4517 default:
4518 template->ulValueLen = (CK_ULONG)-1;
4519 return (CKR_ATTRIBUTE_TYPE_INVALID);
4522 default:
4524 * Get the value of a common attribute.
4526 rv = soft_get_common_attrs(object_p, template,
4527 object_p->object_type);
4528 break;
4531 return (rv);
4535 * Get certificate attributes from an object.
4536 * return CKR_ATTRIBUTE_TYPE_INVALID if the requested type
4537 * does not exist in the certificate.
4539 CK_RV
4540 soft_get_certificate_attribute(soft_object_t *object_p,
4541 CK_ATTRIBUTE_PTR template)
4543 CK_CERTIFICATE_TYPE certtype = object_p->cert_type;
4544 cert_attr_t src;
4546 switch (template->type) {
4547 case CKA_SUBJECT:
4548 if (certtype == CKC_X_509) {
4549 return (get_cert_attr_from_object(
4550 X509_CERT_SUBJECT(object_p), template));
4552 break;
4553 case CKA_VALUE:
4554 if (certtype == CKC_X_509) {
4555 return (get_cert_attr_from_object(
4556 X509_CERT_VALUE(object_p), template));
4557 } else if (certtype == CKC_X_509_ATTR_CERT) {
4558 return (get_cert_attr_from_object(
4559 X509_ATTR_CERT_VALUE(object_p), template));
4561 break;
4562 case CKA_OWNER:
4563 if (certtype == CKC_X_509_ATTR_CERT) {
4564 return (get_cert_attr_from_object(
4565 X509_ATTR_CERT_OWNER(object_p), template));
4567 break;
4568 case CKA_CERTIFICATE_TYPE:
4569 src.value = (CK_BYTE *)&certtype;
4570 src.length = sizeof (certtype);
4571 return (get_cert_attr_from_object(&src, template));
4572 case CKA_TRUSTED:
4573 return (get_bool_attr_from_object(object_p,
4574 TRUSTED_BOOL_ON, template));
4575 case CKA_ID:
4576 case CKA_ISSUER:
4577 case CKA_SERIAL_NUMBER:
4578 case CKA_AC_ISSUER:
4579 case CKA_ATTR_TYPES:
4580 return (get_extra_attr_from_object(object_p,
4581 template));
4582 default:
4583 return (soft_get_common_attrs(object_p, template,
4584 object_p->object_type));
4588 * If we got this far, then the combination of certificate type
4589 * and requested attribute is invalid.
4591 return (CKR_ATTRIBUTE_TYPE_INVALID);
4594 CK_RV
4595 soft_set_certificate_attribute(soft_object_t *object_p,
4596 CK_ATTRIBUTE_PTR template, boolean_t copy)
4598 CK_CERTIFICATE_TYPE certtype = object_p->cert_type;
4600 switch (template->type) {
4601 case CKA_SUBJECT:
4602 if (certtype == CKC_X_509) {
4603 /* SUBJECT attr cannot be modified. */
4604 return (CKR_ATTRIBUTE_READ_ONLY);
4606 break;
4607 case CKA_OWNER:
4608 if (certtype == CKC_X_509_ATTR_CERT) {
4609 /* OWNER attr cannot be modified. */
4610 return (CKR_ATTRIBUTE_READ_ONLY);
4612 break;
4613 case CKA_VALUE:
4614 /* VALUE attr cannot be modified. */
4615 return (CKR_ATTRIBUTE_READ_ONLY);
4616 case CKA_ID:
4617 case CKA_ISSUER:
4618 if (certtype == CKC_X_509) {
4619 return (set_extra_attr_to_object(object_p,
4620 template->type, template));
4622 break;
4623 case CKA_AC_ISSUER:
4624 case CKA_ATTR_TYPES:
4625 if (certtype == CKC_X_509_ATTR_CERT) {
4626 return (set_extra_attr_to_object(object_p,
4627 template->type, template));
4629 break;
4630 case CKA_SERIAL_NUMBER:
4631 case CKA_LABEL:
4632 return (set_extra_attr_to_object(object_p,
4633 template->type, template));
4634 default:
4635 return (soft_set_common_storage_attribute(
4636 object_p, template, copy));
4640 * If we got this far, then the combination of certificate type
4641 * and requested attribute is invalid.
4643 return (CKR_ATTRIBUTE_TYPE_INVALID);
4647 * Call the appropriate get attribute function according to the class
4648 * of object.
4650 * The caller of this function holds the lock on the object.
4652 CK_RV
4653 soft_get_attribute(soft_object_t *object_p, CK_ATTRIBUTE_PTR template)
4656 CK_RV rv = CKR_OK;
4657 CK_OBJECT_CLASS class = object_p->class;
4659 switch (class) {
4660 case CKO_PUBLIC_KEY:
4661 rv = soft_get_public_key_attribute(object_p, template);
4662 break;
4664 case CKO_PRIVATE_KEY:
4665 rv = soft_get_private_key_attribute(object_p, template);
4666 break;
4668 case CKO_SECRET_KEY:
4669 rv = soft_get_secret_key_attribute(object_p, template);
4670 break;
4672 case CKO_DOMAIN_PARAMETERS:
4673 rv = soft_get_domain_parameters_attribute(object_p, template);
4674 break;
4676 case CKO_CERTIFICATE:
4677 rv = soft_get_certificate_attribute(object_p, template);
4678 break;
4680 default:
4682 * If the specified attribute for the object is invalid
4683 * (the object does not possess such as attribute), then
4684 * the ulValueLen is modified to hold the value -1.
4686 template->ulValueLen = (CK_ULONG)-1;
4687 return (CKR_ATTRIBUTE_TYPE_INVALID);
4690 return (rv);
4694 CK_RV
4695 soft_set_common_storage_attribute(soft_object_t *object_p,
4696 CK_ATTRIBUTE_PTR template, boolean_t copy)
4699 CK_RV rv = CKR_OK;
4701 switch (template->type) {
4703 case CKA_TOKEN:
4704 if (copy) {
4705 if ((*(CK_BBOOL *)template->pValue) == B_TRUE) {
4706 if (!soft_keystore_status(KEYSTORE_INITIALIZED))
4707 return (CKR_DEVICE_REMOVED);
4708 object_p->object_type |= TOKEN_OBJECT;
4710 } else {
4711 rv = CKR_ATTRIBUTE_READ_ONLY;
4714 break;
4716 case CKA_PRIVATE:
4717 if (copy) {
4718 if ((*(CK_BBOOL *)template->pValue) == B_TRUE) {
4719 (void) pthread_mutex_lock(&soft_giant_mutex);
4720 if (!soft_slot.authenticated) {
4722 * Check if this is the special case
4723 * when the PIN is never initialized
4724 * in the keystore. If true, we will
4725 * let it pass here and let it fail
4726 * with CKR_PIN_EXPIRED later on.
4728 if (!soft_slot.userpin_change_needed) {
4729 (void) pthread_mutex_unlock(
4730 &soft_giant_mutex);
4731 return (CKR_USER_NOT_LOGGED_IN);
4734 (void) pthread_mutex_unlock(&soft_giant_mutex);
4735 object_p->object_type |= PRIVATE_OBJECT;
4737 } else {
4738 rv = CKR_ATTRIBUTE_READ_ONLY;
4740 break;
4742 case CKA_MODIFIABLE:
4743 if (copy) {
4744 if ((*(CK_BBOOL *)template->pValue) == TRUE)
4745 object_p->bool_attr_mask &=
4746 ~NOT_MODIFIABLE_BOOL_ON;
4747 else
4748 object_p->bool_attr_mask |=
4749 NOT_MODIFIABLE_BOOL_ON;
4750 } else {
4751 rv = CKR_ATTRIBUTE_READ_ONLY;
4753 break;
4755 case CKA_CLASS:
4756 rv = CKR_ATTRIBUTE_READ_ONLY;
4757 break;
4759 default:
4760 rv = CKR_TEMPLATE_INCONSISTENT;
4763 return (rv);
4767 * Set the value of an attribute that is common to all key objects
4768 * (i.e. public key, private key and secret key).
4770 CK_RV
4771 soft_set_common_key_attribute(soft_object_t *object_p,
4772 CK_ATTRIBUTE_PTR template, boolean_t copy)
4775 switch (template->type) {
4777 case CKA_LABEL:
4779 * Only the LABEL can be modified in the common storage
4780 * object attributes after the object is created.
4782 return (set_extra_attr_to_object(object_p,
4783 CKA_LABEL, template));
4785 case CKA_ID:
4786 return (set_extra_attr_to_object(object_p,
4787 CKA_ID, template));
4789 case CKA_START_DATE:
4790 return (set_extra_attr_to_object(object_p,
4791 CKA_START_DATE, template));
4793 case CKA_END_DATE:
4794 return (set_extra_attr_to_object(object_p,
4795 CKA_END_DATE, template));
4797 case CKA_DERIVE:
4798 return (set_bool_attr_to_object(object_p,
4799 DERIVE_BOOL_ON, template));
4801 case CKA_KEY_TYPE:
4802 case CKA_LOCAL:
4803 case CKA_KEY_GEN_MECHANISM:
4804 return (CKR_ATTRIBUTE_READ_ONLY);
4806 default:
4807 return (soft_set_common_storage_attribute(object_p,
4808 template, copy));
4816 * Set the value of an attribute of a Public Key Object.
4818 * Rule: The attributes marked with footnote number "8" in the PKCS11
4819 * spec may be modified (p.88 in PKCS11 spec.).
4821 CK_RV
4822 soft_set_public_key_attribute(soft_object_t *object_p,
4823 CK_ATTRIBUTE_PTR template, boolean_t copy)
4825 CK_KEY_TYPE keytype = object_p->key_type;
4827 switch (template->type) {
4829 case CKA_SUBJECT:
4830 return (set_extra_attr_to_object(object_p,
4831 CKA_SUBJECT, template));
4833 case CKA_ENCRYPT:
4834 return (set_bool_attr_to_object(object_p,
4835 ENCRYPT_BOOL_ON, template));
4837 case CKA_VERIFY:
4838 return (set_bool_attr_to_object(object_p,
4839 VERIFY_BOOL_ON, template));
4841 case CKA_VERIFY_RECOVER:
4842 return (set_bool_attr_to_object(object_p,
4843 VERIFY_RECOVER_BOOL_ON, template));
4845 case CKA_WRAP:
4846 return (set_bool_attr_to_object(object_p,
4847 WRAP_BOOL_ON, template));
4849 case CKA_MODULUS:
4850 case CKA_MODULUS_BITS:
4851 case CKA_PUBLIC_EXPONENT:
4852 if (keytype == CKK_RSA)
4853 return (CKR_ATTRIBUTE_READ_ONLY);
4854 break;
4856 case CKA_SUBPRIME:
4857 if ((keytype == CKK_DSA) ||
4858 (keytype == CKK_X9_42_DH))
4859 return (CKR_ATTRIBUTE_READ_ONLY);
4860 break;
4862 case CKA_PRIME:
4863 case CKA_BASE:
4864 case CKA_VALUE:
4865 if ((keytype == CKK_DSA) ||
4866 (keytype == CKK_DH) ||
4867 (keytype == CKK_X9_42_DH))
4868 return (CKR_ATTRIBUTE_READ_ONLY);
4869 break;
4871 default:
4873 * Set the value of a common key attribute.
4875 return (soft_set_common_key_attribute(object_p,
4876 template, copy));
4880 * If we got this far, then the combination of key type
4881 * and requested attribute is invalid.
4883 return (CKR_ATTRIBUTE_TYPE_INVALID);
4888 * Set the value of an attribute of a Private Key Object.
4890 * Rule: The attributes marked with footnote number "8" in the PKCS11
4891 * spec may be modified (p.88 in PKCS11 spec.).
4893 CK_RV
4894 soft_set_private_key_attribute(soft_object_t *object_p,
4895 CK_ATTRIBUTE_PTR template, boolean_t copy)
4897 CK_KEY_TYPE keytype = object_p->key_type;
4899 switch (template->type) {
4901 case CKA_SUBJECT:
4902 return (set_extra_attr_to_object(object_p,
4903 CKA_SUBJECT, template));
4905 case CKA_SENSITIVE:
4907 * Cannot set SENSITIVE to FALSE if it is already ON.
4909 if (((*(CK_BBOOL *)template->pValue) == B_FALSE) &&
4910 (object_p->bool_attr_mask & SENSITIVE_BOOL_ON)) {
4911 return (CKR_ATTRIBUTE_READ_ONLY);
4914 if (*(CK_BBOOL *)template->pValue)
4915 object_p->bool_attr_mask |= SENSITIVE_BOOL_ON;
4916 return (CKR_OK);
4918 case CKA_DECRYPT:
4919 return (set_bool_attr_to_object(object_p,
4920 DECRYPT_BOOL_ON, template));
4922 case CKA_SIGN:
4923 return (set_bool_attr_to_object(object_p,
4924 SIGN_BOOL_ON, template));
4926 case CKA_SIGN_RECOVER:
4927 return (set_bool_attr_to_object(object_p,
4928 SIGN_RECOVER_BOOL_ON, template));
4930 case CKA_UNWRAP:
4931 return (set_bool_attr_to_object(object_p,
4932 UNWRAP_BOOL_ON, template));
4934 case CKA_EXTRACTABLE:
4936 * Cannot set EXTRACTABLE to TRUE if it is already OFF.
4938 if ((*(CK_BBOOL *)template->pValue) &&
4939 !(object_p->bool_attr_mask & EXTRACTABLE_BOOL_ON)) {
4940 return (CKR_ATTRIBUTE_READ_ONLY);
4943 if ((*(CK_BBOOL *)template->pValue) == B_FALSE)
4944 object_p->bool_attr_mask &= ~EXTRACTABLE_BOOL_ON;
4945 return (CKR_OK);
4947 case CKA_MODULUS:
4948 case CKA_PUBLIC_EXPONENT:
4949 case CKA_PRIVATE_EXPONENT:
4950 case CKA_PRIME_1:
4951 case CKA_PRIME_2:
4952 case CKA_EXPONENT_1:
4953 case CKA_EXPONENT_2:
4954 case CKA_COEFFICIENT:
4955 if (keytype == CKK_RSA) {
4956 return (CKR_ATTRIBUTE_READ_ONLY);
4958 break;
4960 case CKA_SUBPRIME:
4961 if ((keytype == CKK_DSA) ||
4962 (keytype == CKK_X9_42_DH))
4963 return (CKR_ATTRIBUTE_READ_ONLY);
4964 break;
4966 case CKA_PRIME:
4967 case CKA_BASE:
4968 case CKA_VALUE:
4969 if ((keytype == CKK_DSA) ||
4970 (keytype == CKK_DH) ||
4971 (keytype == CKK_X9_42_DH))
4972 return (CKR_ATTRIBUTE_READ_ONLY);
4973 break;
4975 case CKA_VALUE_BITS:
4976 if (keytype == CKK_DH)
4977 return (CKR_ATTRIBUTE_READ_ONLY);
4978 break;
4980 default:
4982 * Set the value of a common key attribute.
4984 return (soft_set_common_key_attribute(object_p,
4985 template, copy));
4989 * If we got this far, then the combination of key type
4990 * and requested attribute is invalid.
4992 return (CKR_ATTRIBUTE_TYPE_INVALID);
4996 * Set the value of an attribute of a Secret Key Object.
4998 * Rule: The attributes marked with footnote number "8" in the PKCS11
4999 * spec may be modified (p.88 in PKCS11 spec.).
5001 CK_RV
5002 soft_set_secret_key_attribute(soft_object_t *object_p,
5003 CK_ATTRIBUTE_PTR template, boolean_t copy)
5005 CK_KEY_TYPE keytype = object_p->key_type;
5007 switch (template->type) {
5009 case CKA_SENSITIVE:
5011 * Cannot set SENSITIVE to FALSE if it is already ON.
5013 if (((*(CK_BBOOL *)template->pValue) == B_FALSE) &&
5014 (object_p->bool_attr_mask & SENSITIVE_BOOL_ON)) {
5015 return (CKR_ATTRIBUTE_READ_ONLY);
5018 if (*(CK_BBOOL *)template->pValue)
5019 object_p->bool_attr_mask |= SENSITIVE_BOOL_ON;
5020 return (CKR_OK);
5022 case CKA_ENCRYPT:
5023 return (set_bool_attr_to_object(object_p,
5024 ENCRYPT_BOOL_ON, template));
5026 case CKA_DECRYPT:
5027 return (set_bool_attr_to_object(object_p,
5028 DECRYPT_BOOL_ON, template));
5030 case CKA_SIGN:
5031 return (set_bool_attr_to_object(object_p,
5032 SIGN_BOOL_ON, template));
5034 case CKA_VERIFY:
5035 return (set_bool_attr_to_object(object_p,
5036 VERIFY_BOOL_ON, template));
5038 case CKA_WRAP:
5039 return (set_bool_attr_to_object(object_p,
5040 WRAP_BOOL_ON, template));
5042 case CKA_UNWRAP:
5043 return (set_bool_attr_to_object(object_p,
5044 UNWRAP_BOOL_ON, template));
5046 case CKA_EXTRACTABLE:
5048 * Cannot set EXTRACTABLE to TRUE if it is already OFF.
5050 if ((*(CK_BBOOL *)template->pValue) &&
5051 !(object_p->bool_attr_mask & EXTRACTABLE_BOOL_ON)) {
5052 return (CKR_ATTRIBUTE_READ_ONLY);
5055 if ((*(CK_BBOOL *)template->pValue) == B_FALSE)
5056 object_p->bool_attr_mask &= ~EXTRACTABLE_BOOL_ON;
5057 return (CKR_OK);
5059 case CKA_VALUE:
5060 return (CKR_ATTRIBUTE_READ_ONLY);
5062 case CKA_VALUE_LEN:
5063 if ((keytype == CKK_RC4) ||
5064 (keytype == CKK_GENERIC_SECRET) ||
5065 (keytype == CKK_AES) ||
5066 (keytype == CKK_BLOWFISH))
5067 return (CKR_ATTRIBUTE_READ_ONLY);
5068 break;
5070 default:
5072 * Set the value of a common key attribute.
5074 return (soft_set_common_key_attribute(object_p,
5075 template, copy));
5079 * If we got this far, then the combination of key type
5080 * and requested attribute is invalid.
5082 return (CKR_ATTRIBUTE_TYPE_INVALID);
5087 * Call the appropriate set attribute function according to the class
5088 * of object.
5090 * The caller of this function does not hold the lock on the original
5091 * object, since this function is setting the attribute on the new object
5092 * that is being modified.
5094 * Argument copy: TRUE when called by C_CopyObject,
5095 * FALSE when called by C_SetAttributeValue.
5097 CK_RV
5098 soft_set_attribute(soft_object_t *object_p, CK_ATTRIBUTE_PTR template,
5099 boolean_t copy)
5102 CK_RV rv = CKR_OK;
5103 CK_OBJECT_CLASS class = object_p->class;
5105 switch (class) {
5107 case CKO_PUBLIC_KEY:
5108 rv = soft_set_public_key_attribute(object_p, template, copy);
5109 break;
5111 case CKO_PRIVATE_KEY:
5112 rv = soft_set_private_key_attribute(object_p, template, copy);
5113 break;
5115 case CKO_SECRET_KEY:
5116 rv = soft_set_secret_key_attribute(object_p, template, copy);
5117 break;
5119 case CKO_DOMAIN_PARAMETERS:
5120 switch (template->type) {
5121 case CKA_LABEL:
5123 * Only the LABEL can be modified in the common
5124 * storage object attributes after the object is
5125 * created.
5127 return (set_extra_attr_to_object(object_p,
5128 CKA_LABEL, template));
5129 default:
5130 return (CKR_TEMPLATE_INCONSISTENT);
5132 case CKO_CERTIFICATE:
5133 rv = soft_set_certificate_attribute(object_p, template, copy);
5134 break;
5136 default:
5138 * If the template specifies a value of an attribute
5139 * which is incompatible with other existing attributes
5140 * of the object, then fails with return code
5141 * CKR_TEMPLATE_INCONSISTENT.
5143 rv = CKR_TEMPLATE_INCONSISTENT;
5144 break;
5147 return (rv);
5150 CK_RV
5151 soft_get_public_value(soft_object_t *key, CK_ATTRIBUTE_TYPE type,
5152 uchar_t *value, uint32_t *value_len)
5154 uint32_t len = 0;
5155 switch (type) {
5157 /* The following attributes belong to RSA */
5158 case CKA_MODULUS:
5159 #ifdef __sparcv9
5160 len =
5161 /* LINTED */
5162 (uint32_t)
5163 ((biginteger_t *)OBJ_PUB_RSA_MOD(key))->big_value_len;
5164 #else /* !__sparcv9 */
5165 len =
5166 ((biginteger_t *)OBJ_PUB_RSA_MOD(key))->big_value_len;
5167 #endif /* __sparcv9 */
5169 /* This attribute MUST BE set */
5170 if (len == 0 || len > *value_len) {
5171 return (CKR_ATTRIBUTE_VALUE_INVALID);
5173 *value_len = len;
5175 (void) memcpy(value,
5176 ((biginteger_t *)OBJ_PUB_RSA_MOD(key))->big_value,
5177 *value_len);
5179 break;
5181 case CKA_PUBLIC_EXPONENT:
5182 #ifdef __sparcv9
5183 len =
5184 /* LINTED */
5185 (uint32_t)
5186 ((biginteger_t *)OBJ_PUB_RSA_PUBEXPO(key))->big_value_len;
5187 #else /* !__sparcv9 */
5188 len =
5189 ((biginteger_t *)OBJ_PUB_RSA_PUBEXPO(key))->big_value_len;
5190 #endif /* __sparcv9 */
5192 /* This attribute MUST BE set */
5193 if (len == 0 || len > *value_len) {
5194 return (CKR_ATTRIBUTE_VALUE_INVALID);
5196 *value_len = len;
5198 (void) memcpy(value,
5199 ((biginteger_t *)OBJ_PUB_RSA_PUBEXPO(key))->big_value,
5200 *value_len);
5202 break;
5204 /* The following attributes belong to DSA and DH */
5205 case CKA_PRIME:
5207 if (key->key_type == CKK_DSA)
5208 #ifdef __sparcv9
5209 len =
5210 /* LINTED */
5211 (uint32_t)
5212 ((biginteger_t *)OBJ_PUB_DSA_PRIME(key))->
5213 big_value_len;
5214 #else /* !__sparcv9 */
5215 len =
5216 ((biginteger_t *)OBJ_PUB_DSA_PRIME(key))->
5217 big_value_len;
5218 #endif /* __sparcv9 */
5219 else
5220 #ifdef __sparcv9
5221 len =
5222 /* LINTED */
5223 (uint32_t)
5224 ((biginteger_t *)OBJ_PUB_DH_PRIME(key))->
5225 big_value_len;
5226 #else /* !__sparcv9 */
5227 len =
5228 ((biginteger_t *)OBJ_PUB_DH_PRIME(key))->
5229 big_value_len;
5230 #endif /* __sparcv9 */
5232 /* This attribute MUST BE set */
5233 if (len == 0 || len > *value_len) {
5234 return (CKR_ATTRIBUTE_VALUE_INVALID);
5236 *value_len = len;
5238 if (key->key_type == CKK_DSA)
5239 (void) memcpy(value,
5240 ((biginteger_t *)OBJ_PUB_DSA_PRIME(key))->big_value,
5241 *value_len);
5242 else
5243 (void) memcpy(value,
5244 ((biginteger_t *)OBJ_PUB_DH_PRIME(key))->big_value,
5245 *value_len);
5247 break;
5249 case CKA_SUBPRIME:
5250 #ifdef __sparcv9
5251 len =
5252 /* LINTED */
5253 (uint32_t)
5254 ((biginteger_t *)OBJ_PUB_DSA_SUBPRIME(key))->big_value_len;
5255 #else /* !__sparcv9 */
5256 len =
5257 ((biginteger_t *)OBJ_PUB_DSA_SUBPRIME(key))->big_value_len;
5258 #endif /* __sparcv9 */
5260 /* This attribute MUST BE set */
5261 if (len == 0 || len > *value_len) {
5262 return (CKR_ATTRIBUTE_VALUE_INVALID);
5264 *value_len = len;
5266 (void) memcpy(value,
5267 ((biginteger_t *)OBJ_PUB_DSA_SUBPRIME(key))->big_value,
5268 *value_len);
5270 break;
5272 case CKA_BASE:
5274 if (key->key_type == CKK_DSA)
5275 #ifdef __sparcv9
5276 len =
5277 /* LINTED */
5278 (uint32_t)
5279 ((biginteger_t *)OBJ_PUB_DSA_BASE(key))->
5280 big_value_len;
5281 #else /* !__sparcv9 */
5282 len =
5283 ((biginteger_t *)OBJ_PUB_DSA_BASE(key))->
5284 big_value_len;
5285 #endif /* __sparcv9 */
5286 else
5287 #ifdef __sparcv9
5288 len =
5289 /* LINTED */
5290 (uint32_t)
5291 ((biginteger_t *)OBJ_PUB_DH_BASE(key))->
5292 big_value_len;
5293 #else /* !__sparcv9 */
5294 len =
5295 ((biginteger_t *)OBJ_PUB_DH_BASE(key))->
5296 big_value_len;
5297 #endif /* __sparcv9 */
5299 /* This attribute MUST BE set */
5300 if (len == 0 || len > *value_len) {
5301 return (CKR_ATTRIBUTE_VALUE_INVALID);
5303 *value_len = len;
5305 if (key->key_type == CKK_DSA)
5306 (void) memcpy(value,
5307 ((biginteger_t *)OBJ_PUB_DSA_BASE(key))->big_value,
5308 *value_len);
5309 else
5310 (void) memcpy(value,
5311 ((biginteger_t *)OBJ_PUB_DH_BASE(key))->big_value,
5312 *value_len);
5313 break;
5315 case CKA_VALUE:
5317 if (key->key_type == CKK_DSA)
5318 #ifdef __sparcv9
5319 len =
5320 /* LINTED */
5321 (uint32_t)
5322 ((biginteger_t *)OBJ_PUB_DSA_VALUE(key))->
5323 big_value_len;
5324 #else /* !__sparcv9 */
5325 len =
5326 ((biginteger_t *)OBJ_PUB_DSA_VALUE(key))->
5327 big_value_len;
5328 #endif /* __sparcv9 */
5329 else
5330 #ifdef __sparcv9
5331 len =
5332 /* LINTED */
5333 (uint32_t)
5334 ((biginteger_t *)OBJ_PUB_DH_VALUE(key))->
5335 big_value_len;
5336 #else /* !__sparcv9 */
5337 len =
5338 ((biginteger_t *)OBJ_PUB_DH_VALUE(key))->
5339 big_value_len;
5340 #endif /* __sparcv9 */
5342 /* This attribute MUST BE set */
5343 if (len == 0 || len > *value_len) {
5344 return (CKR_ATTRIBUTE_VALUE_INVALID);
5346 *value_len = len;
5348 if (key->key_type == CKK_DSA)
5349 (void) memcpy(value,
5350 ((biginteger_t *)OBJ_PUB_DSA_VALUE(key))->big_value,
5351 *value_len);
5352 else
5353 (void) memcpy(value,
5354 ((biginteger_t *)OBJ_PUB_DH_VALUE(key))->big_value,
5355 *value_len);
5357 break;
5360 return (CKR_OK);
5364 CK_RV
5365 soft_get_private_value(soft_object_t *key, CK_ATTRIBUTE_TYPE type,
5366 uchar_t *value, uint32_t *value_len)
5369 uint32_t len = 0;
5371 switch (type) {
5373 /* The following attributes belong to RSA */
5374 case CKA_MODULUS:
5375 #ifdef __sparcv9
5376 len =
5377 /* LINTED */
5378 (uint32_t)
5379 ((biginteger_t *)OBJ_PRI_RSA_MOD(key))->big_value_len;
5380 #else /* !__sparcv9 */
5381 len =
5382 ((biginteger_t *)OBJ_PRI_RSA_MOD(key))->big_value_len;
5383 #endif /* __sparcv9 */
5385 /* This attribute MUST BE set */
5386 if (len == 0 || len > *value_len) {
5387 return (CKR_ATTRIBUTE_VALUE_INVALID);
5389 *value_len = len;
5391 (void) memcpy(value,
5392 ((biginteger_t *)OBJ_PRI_RSA_MOD(key))->big_value,
5393 *value_len);
5395 break;
5397 case CKA_PRIVATE_EXPONENT:
5398 #ifdef __sparcv9
5399 len =
5400 /* LINTED */
5401 (uint32_t)
5402 ((biginteger_t *)OBJ_PRI_RSA_PRIEXPO(key))->big_value_len;
5403 #else /* !__sparcv9 */
5404 len =
5405 ((biginteger_t *)OBJ_PRI_RSA_PRIEXPO(key))->big_value_len;
5406 #endif /* __sparcv9 */
5408 /* This attribute MUST BE set */
5409 if (len == 0 || len > *value_len) {
5410 return (CKR_ATTRIBUTE_VALUE_INVALID);
5412 *value_len = len;
5414 (void) memcpy(value,
5415 ((biginteger_t *)OBJ_PRI_RSA_PRIEXPO(key))->big_value,
5416 *value_len);
5418 break;
5420 case CKA_PRIME_1:
5421 #ifdef __sparcv9
5422 len =
5423 /* LINTED */
5424 (uint32_t)
5425 ((biginteger_t *)OBJ_PRI_RSA_PRIME1(key))->big_value_len;
5426 #else /* !__sparcv9 */
5427 len =
5428 ((biginteger_t *)OBJ_PRI_RSA_PRIME1(key))->big_value_len;
5429 #endif /* __sparcv9 */
5431 if (len > *value_len) {
5432 return (CKR_ATTRIBUTE_VALUE_INVALID);
5434 *value_len = len;
5436 if (*value_len == 0) {
5437 return (CKR_OK);
5440 (void) memcpy(value,
5441 ((biginteger_t *)OBJ_PRI_RSA_PRIME1(key))->big_value,
5442 *value_len);
5444 break;
5446 case CKA_PRIME_2:
5447 #ifdef __sparcv9
5448 len =
5449 /* LINTED */
5450 (uint32_t)
5451 ((biginteger_t *)OBJ_PRI_RSA_PRIME2(key))->big_value_len;
5452 #else /* !__sparcv9 */
5453 len =
5454 ((biginteger_t *)OBJ_PRI_RSA_PRIME2(key))->big_value_len;
5455 #endif /* __sparcv9 */
5457 if (len > *value_len) {
5458 return (CKR_ATTRIBUTE_VALUE_INVALID);
5460 *value_len = len;
5462 if (*value_len == 0) {
5463 return (CKR_OK);
5466 (void) memcpy(value,
5467 ((biginteger_t *)OBJ_PRI_RSA_PRIME2(key))->big_value,
5468 *value_len);
5470 break;
5472 case CKA_EXPONENT_1:
5473 #ifdef __sparcv9
5474 len =
5475 /* LINTED */
5476 (uint32_t)
5477 ((biginteger_t *)OBJ_PRI_RSA_EXPO1(key))->big_value_len;
5478 #else /* !__sparcv9 */
5479 len =
5480 ((biginteger_t *)OBJ_PRI_RSA_EXPO1(key))->big_value_len;
5481 #endif /* __sparcv9 */
5483 if (len > *value_len) {
5484 return (CKR_ATTRIBUTE_VALUE_INVALID);
5486 *value_len = len;
5488 if (*value_len == 0) {
5489 return (CKR_OK);
5492 (void) memcpy(value,
5493 ((biginteger_t *)OBJ_PRI_RSA_EXPO1(key))->big_value,
5494 *value_len);
5496 break;
5498 case CKA_EXPONENT_2:
5499 #ifdef __sparcv9
5500 len =
5501 /* LINTED */
5502 (uint32_t)
5503 ((biginteger_t *)OBJ_PRI_RSA_EXPO2(key))->big_value_len;
5504 #else /* !__sparcv9 */
5505 len =
5506 ((biginteger_t *)OBJ_PRI_RSA_EXPO2(key))->big_value_len;
5507 #endif /* __sparcv9 */
5509 if (len > *value_len) {
5510 return (CKR_ATTRIBUTE_VALUE_INVALID);
5512 *value_len = len;
5514 if (*value_len == 0) {
5515 return (CKR_OK);
5518 (void) memcpy(value,
5519 ((biginteger_t *)OBJ_PRI_RSA_EXPO2(key))->big_value,
5520 *value_len);
5522 break;
5524 case CKA_COEFFICIENT:
5525 #ifdef __sparcv9
5526 len =
5527 /* LINTED */
5528 (uint32_t)
5529 ((biginteger_t *)OBJ_PRI_RSA_COEF(key))->big_value_len;
5530 #else /* !__sparcv9 */
5531 len =
5532 ((biginteger_t *)OBJ_PRI_RSA_COEF(key))->big_value_len;
5533 #endif /* __sparcv9 */
5535 if (len > *value_len) {
5536 return (CKR_ATTRIBUTE_VALUE_INVALID);
5538 *value_len = len;
5540 if (*value_len == 0) {
5541 return (CKR_OK);
5544 (void) memcpy(value,
5545 ((biginteger_t *)OBJ_PRI_RSA_COEF(key))->big_value,
5546 *value_len);
5548 break;
5550 /* The following attributes belong to DSA and DH */
5551 case CKA_PRIME:
5553 if (key->key_type == CKK_DSA)
5554 #ifdef __sparcv9
5555 len =
5556 /* LINTED */
5557 (uint32_t)
5558 ((biginteger_t *)OBJ_PRI_DSA_PRIME(key))->
5559 big_value_len;
5560 #else /* !__sparcv9 */
5561 len =
5562 ((biginteger_t *)OBJ_PRI_DSA_PRIME(key))->
5563 big_value_len;
5564 #endif /* __sparcv9 */
5565 else
5566 #ifdef __sparcv9
5567 len =
5568 /* LINTED */
5569 (uint32_t)
5570 ((biginteger_t *)OBJ_PRI_DH_PRIME(key))->
5571 big_value_len;
5572 #else /* !__sparcv9 */
5573 len =
5574 ((biginteger_t *)OBJ_PRI_DH_PRIME(key))->
5575 big_value_len;
5576 #endif /* __sparcv9 */
5578 /* This attribute MUST BE set */
5579 if (len == 0 || len > *value_len) {
5580 return (CKR_ATTRIBUTE_VALUE_INVALID);
5582 *value_len = len;
5584 if (key->key_type == CKK_DSA)
5585 (void) memcpy(value,
5586 ((biginteger_t *)OBJ_PRI_DSA_PRIME(key))->big_value,
5587 *value_len);
5588 else
5589 (void) memcpy(value,
5590 ((biginteger_t *)OBJ_PRI_DH_PRIME(key))->big_value,
5591 *value_len);
5593 break;
5595 case CKA_SUBPRIME:
5596 #ifdef __sparcv9
5597 len =
5598 /* LINTED */
5599 (uint32_t)
5600 ((biginteger_t *)OBJ_PRI_DSA_SUBPRIME(key))->big_value_len;
5601 #else /* !__sparcv9 */
5602 len =
5603 ((biginteger_t *)OBJ_PRI_DSA_SUBPRIME(key))->big_value_len;
5604 #endif /* __sparcv9 */
5606 /* This attribute MUST BE set */
5607 if (len == 0 || len > *value_len) {
5608 return (CKR_ATTRIBUTE_VALUE_INVALID);
5610 *value_len = len;
5612 (void) memcpy(value,
5613 ((biginteger_t *)OBJ_PRI_DSA_SUBPRIME(key))->big_value,
5614 *value_len);
5616 break;
5618 case CKA_BASE:
5620 if (key->key_type == CKK_DSA)
5621 #ifdef __sparcv9
5622 len =
5623 /* LINTED */
5624 (uint32_t)
5625 ((biginteger_t *)OBJ_PRI_DSA_BASE(key))->
5626 big_value_len;
5627 #else /* !__sparcv9 */
5628 len =
5629 ((biginteger_t *)OBJ_PRI_DSA_BASE(key))->
5630 big_value_len;
5631 #endif /* __sparcv9 */
5632 else
5633 #ifdef __sparcv9
5634 len =
5635 /* LINTED */
5636 (uint32_t)
5637 ((biginteger_t *)OBJ_PRI_DH_BASE(key))->
5638 big_value_len;
5639 #else /* !__sparcv9 */
5640 len =
5641 ((biginteger_t *)OBJ_PRI_DH_BASE(key))->
5642 big_value_len;
5643 #endif /* __sparcv9 */
5645 /* This attribute MUST BE set */
5646 if (len == 0 || len > *value_len) {
5647 return (CKR_ATTRIBUTE_VALUE_INVALID);
5649 *value_len = len;
5651 if (key->key_type == CKK_DSA)
5652 (void) memcpy(value,
5653 ((biginteger_t *)OBJ_PRI_DSA_BASE(key))->big_value,
5654 *value_len);
5655 else
5656 (void) memcpy(value,
5657 ((biginteger_t *)OBJ_PRI_DH_BASE(key))->big_value,
5658 *value_len);
5659 break;
5661 case CKA_VALUE:
5663 if (key->key_type == CKK_DSA) {
5664 #ifdef __sparcv9
5665 len =
5666 /* LINTED */
5667 (uint32_t)
5668 ((biginteger_t *)OBJ_PRI_DSA_VALUE(key))->
5669 big_value_len;
5670 #else /* !__sparcv9 */
5671 len =
5672 ((biginteger_t *)OBJ_PRI_DSA_VALUE(key))->
5673 big_value_len;
5674 #endif /* __sparcv9 */
5675 } else if (key->key_type == CKK_DH) {
5676 #ifdef __sparcv9
5677 len =
5678 /* LINTED */
5679 (uint32_t)
5680 ((biginteger_t *)OBJ_PRI_DH_VALUE(key))->
5681 big_value_len;
5682 #else /* !__sparcv9 */
5683 len =
5684 ((biginteger_t *)OBJ_PRI_DH_VALUE(key))->
5685 big_value_len;
5686 #endif /* __sparcv9 */
5687 } else {
5688 #ifdef __sparcv9
5689 len =
5690 /* LINTED */
5691 (uint32_t)
5692 ((biginteger_t *)OBJ_PRI_EC_VALUE(key))->
5693 big_value_len;
5694 #else /* !__sparcv9 */
5695 len =
5696 ((biginteger_t *)OBJ_PRI_EC_VALUE(key))->
5697 big_value_len;
5698 #endif /* __sparcv9 */
5701 /* This attribute MUST BE set */
5702 if (len == 0 || len > *value_len) {
5703 return (CKR_ATTRIBUTE_VALUE_INVALID);
5705 *value_len = len;
5707 if (key->key_type == CKK_DSA) {
5708 (void) memcpy(value,
5709 ((biginteger_t *)OBJ_PRI_DSA_VALUE(key))->big_value,
5710 *value_len);
5711 } else if (key->key_type == CKK_DH) {
5712 (void) memcpy(value,
5713 ((biginteger_t *)OBJ_PRI_DH_VALUE(key))->big_value,
5714 *value_len);
5715 } else {
5716 (void) memcpy(value,
5717 ((biginteger_t *)OBJ_PRI_EC_VALUE(key))->big_value,
5718 *value_len);
5721 break;
5724 return (CKR_OK);
5728 static CK_RV
5729 copy_bigint(biginteger_t *new_bigint, biginteger_t *old_bigint)
5731 new_bigint->big_value =
5732 malloc((sizeof (CK_BYTE) * new_bigint->big_value_len));
5734 if (new_bigint->big_value == NULL) {
5735 return (CKR_HOST_MEMORY);
5738 (void) memcpy(new_bigint->big_value, old_bigint->big_value,
5739 (sizeof (CK_BYTE) * new_bigint->big_value_len));
5741 return (CKR_OK);
5744 static void
5745 free_public_key_attr(public_key_obj_t *pbk, CK_KEY_TYPE key_type)
5747 if (pbk == NULL) {
5748 return;
5751 switch (key_type) {
5752 case CKK_RSA:
5753 bigint_attr_cleanup(KEY_PUB_RSA_MOD(pbk));
5754 bigint_attr_cleanup(KEY_PUB_RSA_PUBEXPO(pbk));
5755 break;
5756 case CKK_DSA:
5757 bigint_attr_cleanup(KEY_PUB_DSA_PRIME(pbk));
5758 bigint_attr_cleanup(KEY_PUB_DSA_SUBPRIME(pbk));
5759 bigint_attr_cleanup(KEY_PUB_DSA_BASE(pbk));
5760 bigint_attr_cleanup(KEY_PUB_DSA_VALUE(pbk));
5761 break;
5762 case CKK_DH:
5763 bigint_attr_cleanup(KEY_PUB_DH_PRIME(pbk));
5764 bigint_attr_cleanup(KEY_PUB_DH_BASE(pbk));
5765 bigint_attr_cleanup(KEY_PUB_DH_VALUE(pbk));
5766 break;
5767 case CKK_EC:
5768 bigint_attr_cleanup(KEY_PUB_EC_POINT(pbk));
5769 break;
5770 case CKK_X9_42_DH:
5771 bigint_attr_cleanup(KEY_PUB_DH942_PRIME(pbk));
5772 bigint_attr_cleanup(KEY_PUB_DH942_SUBPRIME(pbk));
5773 bigint_attr_cleanup(KEY_PUB_DH942_BASE(pbk));
5774 bigint_attr_cleanup(KEY_PUB_DH942_VALUE(pbk));
5775 break;
5776 default:
5777 break;
5779 free(pbk);
5782 CK_RV
5783 soft_copy_public_key_attr(public_key_obj_t *old_pub_key_obj_p,
5784 public_key_obj_t **new_pub_key_obj_p, CK_KEY_TYPE key_type)
5787 public_key_obj_t *pbk;
5788 CK_RV rv = CKR_OK;
5790 pbk = calloc(1, sizeof (public_key_obj_t));
5791 if (pbk == NULL) {
5792 return (CKR_HOST_MEMORY);
5795 switch (key_type) {
5796 case CKK_RSA:
5797 (void) memcpy(KEY_PUB_RSA(pbk),
5798 KEY_PUB_RSA(old_pub_key_obj_p),
5799 sizeof (rsa_pub_key_t));
5800 /* copy modulus */
5801 rv = copy_bigint(KEY_PUB_RSA_MOD(pbk),
5802 KEY_PUB_RSA_MOD(old_pub_key_obj_p));
5803 if (rv != CKR_OK) {
5804 free_public_key_attr(pbk, key_type);
5805 return (rv);
5807 /* copy public exponent */
5808 rv = copy_bigint(KEY_PUB_RSA_PUBEXPO(pbk),
5809 KEY_PUB_RSA_PUBEXPO(old_pub_key_obj_p));
5810 if (rv != CKR_OK) {
5811 free_public_key_attr(pbk, key_type);
5812 return (rv);
5814 break;
5815 case CKK_DSA:
5816 (void) memcpy(KEY_PUB_DSA(pbk),
5817 KEY_PUB_DSA(old_pub_key_obj_p),
5818 sizeof (dsa_pub_key_t));
5820 /* copy prime */
5821 rv = copy_bigint(KEY_PUB_DSA_PRIME(pbk),
5822 KEY_PUB_DSA_PRIME(old_pub_key_obj_p));
5823 if (rv != CKR_OK) {
5824 free_public_key_attr(pbk, key_type);
5825 return (rv);
5828 /* copy subprime */
5829 rv = copy_bigint(KEY_PUB_DSA_SUBPRIME(pbk),
5830 KEY_PUB_DSA_SUBPRIME(old_pub_key_obj_p));
5831 if (rv != CKR_OK) {
5832 free_public_key_attr(pbk, key_type);
5833 return (rv);
5836 /* copy base */
5837 rv = copy_bigint(KEY_PUB_DSA_BASE(pbk),
5838 KEY_PUB_DSA_BASE(old_pub_key_obj_p));
5839 if (rv != CKR_OK) {
5840 free_public_key_attr(pbk, key_type);
5841 return (rv);
5844 /* copy value */
5845 rv = copy_bigint(KEY_PUB_DSA_VALUE(pbk),
5846 KEY_PUB_DSA_VALUE(old_pub_key_obj_p));
5847 if (rv != CKR_OK) {
5848 free_public_key_attr(pbk, key_type);
5849 return (rv);
5851 break;
5852 case CKK_DH:
5853 (void) memcpy(KEY_PUB_DH(pbk),
5854 KEY_PUB_DH(old_pub_key_obj_p),
5855 sizeof (dh_pub_key_t));
5857 /* copy prime */
5858 rv = copy_bigint(KEY_PUB_DH_PRIME(pbk),
5859 KEY_PUB_DH_PRIME(old_pub_key_obj_p));
5860 if (rv != CKR_OK) {
5861 free_public_key_attr(pbk, key_type);
5862 return (rv);
5865 /* copy base */
5866 rv = copy_bigint(KEY_PUB_DH_BASE(pbk),
5867 KEY_PUB_DH_BASE(old_pub_key_obj_p));
5868 if (rv != CKR_OK) {
5869 free_public_key_attr(pbk, key_type);
5870 return (rv);
5873 /* copy value */
5874 rv = copy_bigint(KEY_PUB_DH_VALUE(pbk),
5875 KEY_PUB_DH_VALUE(old_pub_key_obj_p));
5876 if (rv != CKR_OK) {
5877 free_public_key_attr(pbk, key_type);
5878 return (rv);
5880 break;
5881 case CKK_EC:
5882 (void) memcpy(KEY_PUB_EC(pbk),
5883 KEY_PUB_EC(old_pub_key_obj_p),
5884 sizeof (ec_pub_key_t));
5886 /* copy point */
5887 rv = copy_bigint(KEY_PUB_EC_POINT(pbk),
5888 KEY_PUB_EC_POINT(old_pub_key_obj_p));
5889 if (rv != CKR_OK) {
5890 free_public_key_attr(pbk, key_type);
5891 return (rv);
5893 break;
5894 case CKK_X9_42_DH:
5895 (void) memcpy(KEY_PUB_DH942(pbk),
5896 KEY_PUB_DH942(old_pub_key_obj_p),
5897 sizeof (dh942_pub_key_t));
5899 /* copy prime */
5900 rv = copy_bigint(KEY_PUB_DH942_PRIME(pbk),
5901 KEY_PUB_DH942_PRIME(old_pub_key_obj_p));
5902 if (rv != CKR_OK) {
5903 free_public_key_attr(pbk, key_type);
5904 return (rv);
5907 /* copy subprime */
5908 rv = copy_bigint(KEY_PUB_DH942_SUBPRIME(pbk),
5909 KEY_PUB_DH942_SUBPRIME(old_pub_key_obj_p));
5910 if (rv != CKR_OK) {
5911 free_public_key_attr(pbk, key_type);
5912 return (rv);
5915 /* copy base */
5916 rv = copy_bigint(KEY_PUB_DH942_BASE(pbk),
5917 KEY_PUB_DH942_BASE(old_pub_key_obj_p));
5918 if (rv != CKR_OK) {
5919 free_public_key_attr(pbk, key_type);
5920 return (rv);
5923 /* copy value */
5924 rv = copy_bigint(KEY_PUB_DH942_VALUE(pbk),
5925 KEY_PUB_DH942_VALUE(old_pub_key_obj_p));
5926 if (rv != CKR_OK) {
5927 free_public_key_attr(pbk, key_type);
5928 return (rv);
5930 break;
5931 default:
5932 break;
5934 *new_pub_key_obj_p = pbk;
5935 return (rv);
5938 static void
5939 free_private_key_attr(private_key_obj_t *pbk, CK_KEY_TYPE key_type)
5941 if (pbk == NULL) {
5942 return;
5945 switch (key_type) {
5946 case CKK_RSA:
5947 bigint_attr_cleanup(KEY_PRI_RSA_MOD(pbk));
5948 bigint_attr_cleanup(KEY_PRI_RSA_PUBEXPO(pbk));
5949 bigint_attr_cleanup(KEY_PRI_RSA_PRIEXPO(pbk));
5950 bigint_attr_cleanup(KEY_PRI_RSA_PRIME1(pbk));
5951 bigint_attr_cleanup(KEY_PRI_RSA_PRIME2(pbk));
5952 bigint_attr_cleanup(KEY_PRI_RSA_EXPO1(pbk));
5953 bigint_attr_cleanup(KEY_PRI_RSA_EXPO2(pbk));
5954 bigint_attr_cleanup(KEY_PRI_RSA_COEF(pbk));
5955 break;
5956 case CKK_DSA:
5957 bigint_attr_cleanup(KEY_PRI_DSA_PRIME(pbk));
5958 bigint_attr_cleanup(KEY_PRI_DSA_SUBPRIME(pbk));
5959 bigint_attr_cleanup(KEY_PRI_DSA_BASE(pbk));
5960 bigint_attr_cleanup(KEY_PRI_DSA_VALUE(pbk));
5961 break;
5962 case CKK_DH:
5963 bigint_attr_cleanup(KEY_PRI_DH_PRIME(pbk));
5964 bigint_attr_cleanup(KEY_PRI_DH_BASE(pbk));
5965 bigint_attr_cleanup(KEY_PRI_DH_VALUE(pbk));
5966 break;
5967 case CKK_EC:
5968 bigint_attr_cleanup(KEY_PRI_EC_VALUE(pbk));
5969 break;
5970 case CKK_X9_42_DH:
5971 bigint_attr_cleanup(KEY_PRI_DH942_PRIME(pbk));
5972 bigint_attr_cleanup(KEY_PRI_DH942_SUBPRIME(pbk));
5973 bigint_attr_cleanup(KEY_PRI_DH942_BASE(pbk));
5974 bigint_attr_cleanup(KEY_PRI_DH942_VALUE(pbk));
5975 break;
5976 default:
5977 break;
5979 free(pbk);
5982 CK_RV
5983 soft_copy_private_key_attr(private_key_obj_t *old_pri_key_obj_p,
5984 private_key_obj_t **new_pri_key_obj_p, CK_KEY_TYPE key_type)
5986 CK_RV rv = CKR_OK;
5987 private_key_obj_t *pbk;
5989 pbk = calloc(1, sizeof (private_key_obj_t));
5990 if (pbk == NULL) {
5991 return (CKR_HOST_MEMORY);
5994 switch (key_type) {
5995 case CKK_RSA:
5996 (void) memcpy(KEY_PRI_RSA(pbk),
5997 KEY_PRI_RSA(old_pri_key_obj_p),
5998 sizeof (rsa_pri_key_t));
5999 /* copy modulus */
6000 rv = copy_bigint(KEY_PRI_RSA_MOD(pbk),
6001 KEY_PRI_RSA_MOD(old_pri_key_obj_p));
6002 if (rv != CKR_OK) {
6003 free_private_key_attr(pbk, key_type);
6004 return (rv);
6006 /* copy public exponent */
6007 rv = copy_bigint(KEY_PRI_RSA_PUBEXPO(pbk),
6008 KEY_PRI_RSA_PUBEXPO(old_pri_key_obj_p));
6009 if (rv != CKR_OK) {
6010 free_private_key_attr(pbk, key_type);
6011 return (rv);
6013 /* copy private exponent */
6014 rv = copy_bigint(KEY_PRI_RSA_PRIEXPO(pbk),
6015 KEY_PRI_RSA_PRIEXPO(old_pri_key_obj_p));
6016 if (rv != CKR_OK) {
6017 free_private_key_attr(pbk, key_type);
6018 return (rv);
6020 /* copy prime_1 */
6021 rv = copy_bigint(KEY_PRI_RSA_PRIME1(pbk),
6022 KEY_PRI_RSA_PRIME1(old_pri_key_obj_p));
6023 if (rv != CKR_OK) {
6024 free_private_key_attr(pbk, key_type);
6025 return (rv);
6027 /* copy prime_2 */
6028 rv = copy_bigint(KEY_PRI_RSA_PRIME2(pbk),
6029 KEY_PRI_RSA_PRIME2(old_pri_key_obj_p));
6030 if (rv != CKR_OK) {
6031 free_private_key_attr(pbk, key_type);
6032 return (rv);
6034 /* copy exponent_1 */
6035 rv = copy_bigint(KEY_PRI_RSA_EXPO1(pbk),
6036 KEY_PRI_RSA_EXPO1(old_pri_key_obj_p));
6037 if (rv != CKR_OK) {
6038 free_private_key_attr(pbk, key_type);
6039 return (rv);
6041 /* copy exponent_2 */
6042 rv = copy_bigint(KEY_PRI_RSA_EXPO2(pbk),
6043 KEY_PRI_RSA_EXPO2(old_pri_key_obj_p));
6044 if (rv != CKR_OK) {
6045 free_private_key_attr(pbk, key_type);
6046 return (rv);
6048 /* copy coefficient */
6049 rv = copy_bigint(KEY_PRI_RSA_COEF(pbk),
6050 KEY_PRI_RSA_COEF(old_pri_key_obj_p));
6051 if (rv != CKR_OK) {
6052 free_private_key_attr(pbk, key_type);
6053 return (rv);
6055 break;
6056 case CKK_DSA:
6057 (void) memcpy(KEY_PRI_DSA(pbk),
6058 KEY_PRI_DSA(old_pri_key_obj_p),
6059 sizeof (dsa_pri_key_t));
6061 /* copy prime */
6062 rv = copy_bigint(KEY_PRI_DSA_PRIME(pbk),
6063 KEY_PRI_DSA_PRIME(old_pri_key_obj_p));
6064 if (rv != CKR_OK) {
6065 free_private_key_attr(pbk, key_type);
6066 return (rv);
6069 /* copy subprime */
6070 rv = copy_bigint(KEY_PRI_DSA_SUBPRIME(pbk),
6071 KEY_PRI_DSA_SUBPRIME(old_pri_key_obj_p));
6072 if (rv != CKR_OK) {
6073 free_private_key_attr(pbk, key_type);
6074 return (rv);
6077 /* copy base */
6078 rv = copy_bigint(KEY_PRI_DSA_BASE(pbk),
6079 KEY_PRI_DSA_BASE(old_pri_key_obj_p));
6080 if (rv != CKR_OK) {
6081 free_private_key_attr(pbk, key_type);
6082 return (rv);
6085 /* copy value */
6086 rv = copy_bigint(KEY_PRI_DSA_VALUE(pbk),
6087 KEY_PRI_DSA_VALUE(old_pri_key_obj_p));
6088 if (rv != CKR_OK) {
6089 free_private_key_attr(pbk, key_type);
6090 return (rv);
6092 break;
6093 case CKK_DH:
6094 (void) memcpy(KEY_PRI_DH(pbk),
6095 KEY_PRI_DH(old_pri_key_obj_p),
6096 sizeof (dh_pri_key_t));
6098 /* copy prime */
6099 rv = copy_bigint(KEY_PRI_DH_PRIME(pbk),
6100 KEY_PRI_DH_PRIME(old_pri_key_obj_p));
6101 if (rv != CKR_OK) {
6102 free_private_key_attr(pbk, key_type);
6103 return (rv);
6106 /* copy base */
6107 rv = copy_bigint(KEY_PRI_DH_BASE(pbk),
6108 KEY_PRI_DH_BASE(old_pri_key_obj_p));
6109 if (rv != CKR_OK) {
6110 free_private_key_attr(pbk, key_type);
6111 return (rv);
6114 /* copy value */
6115 rv = copy_bigint(KEY_PRI_DH_VALUE(pbk),
6116 KEY_PRI_DH_VALUE(old_pri_key_obj_p));
6117 if (rv != CKR_OK) {
6118 free_private_key_attr(pbk, key_type);
6119 return (rv);
6121 break;
6122 case CKK_EC:
6123 (void) memcpy(KEY_PRI_EC(pbk),
6124 KEY_PRI_EC(old_pri_key_obj_p),
6125 sizeof (ec_pri_key_t));
6127 /* copy value */
6128 rv = copy_bigint(KEY_PRI_EC_VALUE(pbk),
6129 KEY_PRI_EC_VALUE(old_pri_key_obj_p));
6130 if (rv != CKR_OK) {
6131 free_private_key_attr(pbk, key_type);
6132 return (rv);
6134 break;
6135 case CKK_X9_42_DH:
6136 (void) memcpy(KEY_PRI_DH942(pbk),
6137 KEY_PRI_DH942(old_pri_key_obj_p),
6138 sizeof (dh942_pri_key_t));
6140 /* copy prime */
6141 rv = copy_bigint(KEY_PRI_DH942_PRIME(pbk),
6142 KEY_PRI_DH942_PRIME(old_pri_key_obj_p));
6143 if (rv != CKR_OK) {
6144 free_private_key_attr(pbk, key_type);
6145 return (rv);
6148 /* copy subprime */
6149 rv = copy_bigint(KEY_PRI_DH942_SUBPRIME(pbk),
6150 KEY_PRI_DH942_SUBPRIME(old_pri_key_obj_p));
6151 if (rv != CKR_OK) {
6152 free_private_key_attr(pbk, key_type);
6153 return (rv);
6156 /* copy base */
6157 rv = copy_bigint(KEY_PRI_DH942_BASE(pbk),
6158 KEY_PRI_DH942_BASE(old_pri_key_obj_p));
6159 if (rv != CKR_OK) {
6160 free_private_key_attr(pbk, key_type);
6161 return (rv);
6164 /* copy value */
6165 rv = copy_bigint(KEY_PRI_DH942_VALUE(pbk),
6166 KEY_PRI_DH942_VALUE(old_pri_key_obj_p));
6167 if (rv != CKR_OK) {
6168 free_private_key_attr(pbk, key_type);
6169 return (rv);
6171 break;
6172 default:
6173 break;
6175 *new_pri_key_obj_p = pbk;
6176 return (rv);
6179 static void
6180 free_domain_attr(domain_obj_t *domain, CK_KEY_TYPE key_type)
6182 if (domain == NULL) {
6183 return;
6186 switch (key_type) {
6187 case CKK_DSA:
6188 bigint_attr_cleanup(KEY_DOM_DSA_PRIME(domain));
6189 bigint_attr_cleanup(KEY_DOM_DSA_SUBPRIME(domain));
6190 bigint_attr_cleanup(KEY_DOM_DSA_BASE(domain));
6191 break;
6192 case CKK_DH:
6193 bigint_attr_cleanup(KEY_DOM_DH_PRIME(domain));
6194 bigint_attr_cleanup(KEY_DOM_DH_BASE(domain));
6195 break;
6196 case CKK_X9_42_DH:
6197 bigint_attr_cleanup(KEY_DOM_DH942_PRIME(domain));
6198 bigint_attr_cleanup(KEY_DOM_DH942_SUBPRIME(domain));
6199 bigint_attr_cleanup(KEY_DOM_DH942_BASE(domain));
6200 break;
6201 default:
6202 break;
6204 free(domain);
6207 CK_RV
6208 soft_copy_domain_attr(domain_obj_t *old_domain_obj_p,
6209 domain_obj_t **new_domain_obj_p, CK_KEY_TYPE key_type)
6211 CK_RV rv = CKR_OK;
6212 domain_obj_t *domain;
6214 domain = calloc(1, sizeof (domain_obj_t));
6215 if (domain == NULL) {
6216 return (CKR_HOST_MEMORY);
6219 switch (key_type) {
6220 case CKK_DSA:
6221 (void) memcpy(KEY_DOM_DSA(domain),
6222 KEY_DOM_DSA(old_domain_obj_p),
6223 sizeof (dsa_dom_key_t));
6225 /* copy prime */
6226 rv = copy_bigint(KEY_DOM_DSA_PRIME(domain),
6227 KEY_DOM_DSA_PRIME(old_domain_obj_p));
6228 if (rv != CKR_OK) {
6229 free_domain_attr(domain, key_type);
6230 return (rv);
6233 /* copy subprime */
6234 rv = copy_bigint(KEY_DOM_DSA_SUBPRIME(domain),
6235 KEY_DOM_DSA_SUBPRIME(old_domain_obj_p));
6236 if (rv != CKR_OK) {
6237 free_domain_attr(domain, key_type);
6238 return (rv);
6241 /* copy base */
6242 rv = copy_bigint(KEY_DOM_DSA_BASE(domain),
6243 KEY_DOM_DSA_BASE(old_domain_obj_p));
6244 if (rv != CKR_OK) {
6245 free_domain_attr(domain, key_type);
6246 return (rv);
6249 break;
6250 case CKK_DH:
6251 (void) memcpy(KEY_DOM_DH(domain),
6252 KEY_DOM_DH(old_domain_obj_p),
6253 sizeof (dh_dom_key_t));
6255 /* copy prime */
6256 rv = copy_bigint(KEY_DOM_DH_PRIME(domain),
6257 KEY_DOM_DH_PRIME(old_domain_obj_p));
6258 if (rv != CKR_OK) {
6259 free_domain_attr(domain, key_type);
6260 return (rv);
6263 /* copy base */
6264 rv = copy_bigint(KEY_DOM_DH_BASE(domain),
6265 KEY_DOM_DH_BASE(old_domain_obj_p));
6266 if (rv != CKR_OK) {
6267 free_domain_attr(domain, key_type);
6268 return (rv);
6271 break;
6272 case CKK_X9_42_DH:
6273 (void) memcpy(KEY_DOM_DH942(domain),
6274 KEY_DOM_DH942(old_domain_obj_p),
6275 sizeof (dh942_dom_key_t));
6277 /* copy prime */
6278 rv = copy_bigint(KEY_DOM_DH942_PRIME(domain),
6279 KEY_DOM_DH942_PRIME(old_domain_obj_p));
6280 if (rv != CKR_OK) {
6281 free_domain_attr(domain, key_type);
6282 return (rv);
6285 /* copy subprime */
6286 rv = copy_bigint(KEY_DOM_DH942_SUBPRIME(domain),
6287 KEY_DOM_DH942_SUBPRIME(old_domain_obj_p));
6288 if (rv != CKR_OK) {
6289 free_domain_attr(domain, key_type);
6290 return (rv);
6293 /* copy base */
6294 rv = copy_bigint(KEY_DOM_DH942_BASE(domain),
6295 KEY_DOM_DH942_BASE(old_domain_obj_p));
6296 if (rv != CKR_OK) {
6297 free_domain_attr(domain, key_type);
6298 return (rv);
6301 break;
6302 default:
6303 break;
6305 *new_domain_obj_p = domain;
6306 return (rv);
6309 CK_RV
6310 soft_copy_secret_key_attr(secret_key_obj_t *old_secret_key_obj_p,
6311 secret_key_obj_t **new_secret_key_obj_p)
6313 secret_key_obj_t *sk;
6315 sk = malloc(sizeof (secret_key_obj_t));
6316 if (sk == NULL) {
6317 return (CKR_HOST_MEMORY);
6319 (void) memcpy(sk, old_secret_key_obj_p, sizeof (secret_key_obj_t));
6321 /* copy the secret key value */
6322 sk->sk_value = malloc((sizeof (CK_BYTE) * sk->sk_value_len));
6323 if (sk->sk_value == NULL) {
6324 free(sk);
6325 return (CKR_HOST_MEMORY);
6327 (void) memcpy(sk->sk_value, old_secret_key_obj_p->sk_value,
6328 (sizeof (CK_BYTE) * sk->sk_value_len));
6331 * Copy the pre-expanded key schedule.
6333 if (old_secret_key_obj_p->key_sched != NULL &&
6334 old_secret_key_obj_p->keysched_len > 0) {
6335 sk->key_sched = malloc(old_secret_key_obj_p->keysched_len);
6336 if (sk->key_sched == NULL) {
6337 free(sk);
6338 return (CKR_HOST_MEMORY);
6340 sk->keysched_len = old_secret_key_obj_p->keysched_len;
6341 (void) memcpy(sk->key_sched, old_secret_key_obj_p->key_sched,
6342 sk->keysched_len);
6345 *new_secret_key_obj_p = sk;
6347 return (CKR_OK);
6351 * If CKA_CLASS not given, guess CKA_CLASS using
6352 * attributes on template .
6354 * Some attributes are specific to an object class. If one or more
6355 * of these attributes are in the template, make a list of classes
6356 * that can have these attributes. This would speed up the search later,
6357 * because we can immediately skip an object if the class of that
6358 * object can not possibly contain one of the attributes.
6361 void
6362 soft_process_find_attr(CK_OBJECT_CLASS *pclasses,
6363 CK_ULONG *num_result_pclasses, CK_ATTRIBUTE_PTR pTemplate,
6364 CK_ULONG ulCount)
6366 ulong_t i;
6367 int j;
6368 boolean_t pub_found = B_FALSE,
6369 priv_found = B_FALSE,
6370 secret_found = B_FALSE,
6371 domain_found = B_FALSE,
6372 hardware_found = B_FALSE,
6373 cert_found = B_FALSE;
6374 int num_pub_key_attrs, num_priv_key_attrs,
6375 num_secret_key_attrs, num_domain_attrs,
6376 num_hardware_attrs, num_cert_attrs;
6377 int num_pclasses = 0;
6379 for (i = 0; i < ulCount; i++) {
6380 if (pTemplate[i].type == CKA_CLASS) {
6382 * don't need to guess the class, it is specified.
6383 * Just record the class, and return.
6385 pclasses[0] =
6386 (*((CK_OBJECT_CLASS *)pTemplate[i].pValue));
6387 *num_result_pclasses = 1;
6388 return;
6392 num_pub_key_attrs =
6393 sizeof (PUB_KEY_ATTRS) / sizeof (CK_ATTRIBUTE_TYPE);
6394 num_priv_key_attrs =
6395 sizeof (PRIV_KEY_ATTRS) / sizeof (CK_ATTRIBUTE_TYPE);
6396 num_secret_key_attrs =
6397 sizeof (SECRET_KEY_ATTRS) / sizeof (CK_ATTRIBUTE_TYPE);
6398 num_domain_attrs =
6399 sizeof (DOMAIN_ATTRS) / sizeof (CK_ATTRIBUTE_TYPE);
6400 num_hardware_attrs =
6401 sizeof (HARDWARE_ATTRS) / sizeof (CK_ATTRIBUTE_TYPE);
6402 num_cert_attrs =
6403 sizeof (CERT_ATTRS) / sizeof (CK_ATTRIBUTE_TYPE);
6406 * Get the list of objects class that might contain
6407 * some attributes.
6409 for (i = 0; i < ulCount; i++) {
6411 * only check if this attribute can belong to public key object
6412 * class if public key object isn't already in the list
6414 if (!pub_found) {
6415 for (j = 0; j < num_pub_key_attrs; j++) {
6416 if (pTemplate[i].type == PUB_KEY_ATTRS[j]) {
6417 pub_found = B_TRUE;
6418 pclasses[num_pclasses++] =
6419 CKO_PUBLIC_KEY;
6420 break;
6425 if (!priv_found) {
6426 for (j = 0; j < num_priv_key_attrs; j++) {
6427 if (pTemplate[i].type == PRIV_KEY_ATTRS[j]) {
6428 priv_found = B_TRUE;
6429 pclasses[num_pclasses++] =
6430 CKO_PRIVATE_KEY;
6431 break;
6436 if (!secret_found) {
6437 for (j = 0; j < num_secret_key_attrs; j++) {
6438 if (pTemplate[i].type == SECRET_KEY_ATTRS[j]) {
6439 secret_found = B_TRUE;
6440 pclasses[num_pclasses++] =
6441 CKO_SECRET_KEY;
6442 break;
6447 if (!domain_found) {
6448 for (j = 0; j < num_domain_attrs; j++) {
6449 if (pTemplate[i].type == DOMAIN_ATTRS[j]) {
6450 domain_found = B_TRUE;
6451 pclasses[num_pclasses++] =
6452 CKO_DOMAIN_PARAMETERS;
6453 break;
6458 if (!hardware_found) {
6459 for (j = 0; j < num_hardware_attrs; j++) {
6460 if (pTemplate[i].type == HARDWARE_ATTRS[j]) {
6461 hardware_found = B_TRUE;
6462 pclasses[num_pclasses++] =
6463 CKO_HW_FEATURE;
6464 break;
6469 if (!cert_found) {
6470 for (j = 0; j < num_cert_attrs; j++) {
6471 if (pTemplate[i].type == CERT_ATTRS[j]) {
6472 cert_found = B_TRUE;
6473 pclasses[num_pclasses++] =
6474 CKO_CERTIFICATE;
6475 break;
6480 *num_result_pclasses = num_pclasses;
6483 boolean_t
6484 soft_find_match_attrs(soft_object_t *obj, CK_OBJECT_CLASS *pclasses,
6485 CK_ULONG num_pclasses, CK_ATTRIBUTE *template, CK_ULONG num_attr)
6487 ulong_t i;
6488 CK_ATTRIBUTE *tmpl_attr, *obj_attr;
6489 cert_attr_t *cert_attr;
6490 uint64_t attr_mask;
6491 biginteger_t *bigint;
6492 boolean_t compare_attr, compare_bigint, compare_boolean;
6493 boolean_t compare_cert_val, compare_cert_type;
6496 * Check if the class of this object match with any
6497 * of object classes that can possibly contain the
6498 * requested attributes.
6500 if (num_pclasses > 0) {
6501 for (i = 0; i < num_pclasses; i++) {
6502 if (obj->class == pclasses[i]) {
6503 break;
6506 if (i == num_pclasses) {
6508 * this object can't possibly contain one or
6509 * more attributes, don't need to check this object
6511 return (B_FALSE);
6515 /* need to examine everything */
6516 for (i = 0; i < num_attr; i++) {
6517 tmpl_attr = &(template[i]);
6518 compare_attr = B_FALSE;
6519 compare_bigint = B_FALSE;
6520 compare_boolean = B_FALSE;
6521 compare_cert_val = B_FALSE;
6522 compare_cert_type = B_FALSE;
6523 switch (tmpl_attr->type) {
6524 /* First, check the most common attributes */
6525 case CKA_CLASS:
6526 if (*((CK_OBJECT_CLASS *)tmpl_attr->pValue) !=
6527 obj->class) {
6528 return (B_FALSE);
6530 break;
6531 case CKA_KEY_TYPE:
6532 if (*((CK_KEY_TYPE *)tmpl_attr->pValue) !=
6533 obj->key_type) {
6534 return (B_FALSE);
6536 break;
6537 case CKA_ENCRYPT:
6538 attr_mask = (obj->bool_attr_mask) & ENCRYPT_BOOL_ON;
6539 compare_boolean = B_TRUE;
6540 break;
6541 case CKA_DECRYPT:
6542 attr_mask = (obj->bool_attr_mask) & DECRYPT_BOOL_ON;
6543 compare_boolean = B_TRUE;
6544 break;
6545 case CKA_WRAP:
6546 attr_mask = (obj->bool_attr_mask) & WRAP_BOOL_ON;
6547 compare_boolean = B_TRUE;
6548 break;
6549 case CKA_UNWRAP:
6550 attr_mask = (obj->bool_attr_mask) & UNWRAP_BOOL_ON;
6551 compare_boolean = B_TRUE;
6552 break;
6553 case CKA_SIGN:
6554 attr_mask = (obj->bool_attr_mask) & SIGN_BOOL_ON;
6555 compare_boolean = B_TRUE;
6556 break;
6557 case CKA_SIGN_RECOVER:
6558 attr_mask = (obj->bool_attr_mask) &
6559 SIGN_RECOVER_BOOL_ON;
6560 compare_boolean = B_TRUE;
6561 break;
6562 case CKA_VERIFY:
6563 attr_mask = (obj->bool_attr_mask) & VERIFY_BOOL_ON;
6564 compare_boolean = B_TRUE;
6565 break;
6566 case CKA_VERIFY_RECOVER:
6567 attr_mask = (obj->bool_attr_mask) &
6568 VERIFY_RECOVER_BOOL_ON;
6569 compare_boolean = B_TRUE;
6570 break;
6571 case CKA_DERIVE:
6572 attr_mask = (obj->bool_attr_mask) & DERIVE_BOOL_ON;
6573 compare_boolean = B_TRUE;
6574 break;
6575 case CKA_LOCAL:
6576 attr_mask = (obj->bool_attr_mask) & LOCAL_BOOL_ON;
6577 compare_boolean = B_TRUE;
6578 break;
6579 case CKA_SENSITIVE:
6580 attr_mask = (obj->bool_attr_mask) & SENSITIVE_BOOL_ON;
6581 compare_boolean = B_TRUE;
6582 break;
6583 case CKA_SECONDARY_AUTH:
6584 attr_mask = (obj->bool_attr_mask) &
6585 SECONDARY_AUTH_BOOL_ON;
6586 compare_boolean = B_TRUE;
6587 break;
6588 case CKA_TRUSTED:
6589 attr_mask = (obj->bool_attr_mask) & TRUSTED_BOOL_ON;
6590 compare_boolean = B_TRUE;
6591 break;
6592 case CKA_EXTRACTABLE:
6593 attr_mask = (obj->bool_attr_mask) &
6594 EXTRACTABLE_BOOL_ON;
6595 compare_boolean = B_TRUE;
6596 break;
6597 case CKA_ALWAYS_SENSITIVE:
6598 attr_mask = (obj->bool_attr_mask) &
6599 ALWAYS_SENSITIVE_BOOL_ON;
6600 compare_boolean = B_TRUE;
6601 break;
6602 case CKA_NEVER_EXTRACTABLE:
6603 attr_mask = (obj->bool_attr_mask) &
6604 NEVER_EXTRACTABLE_BOOL_ON;
6605 compare_boolean = B_TRUE;
6606 break;
6607 case CKA_TOKEN:
6608 attr_mask = (obj->object_type) & TOKEN_OBJECT;
6609 compare_boolean = B_TRUE;
6610 break;
6611 case CKA_PRIVATE:
6612 attr_mask = (obj->object_type) & PRIVATE_OBJECT;
6613 compare_boolean = B_TRUE;
6614 break;
6615 case CKA_MODIFIABLE:
6617 CK_BBOOL bval;
6618 attr_mask = (obj->bool_attr_mask) &
6619 NOT_MODIFIABLE_BOOL_ON;
6621 if (attr_mask) {
6622 bval = FALSE;
6623 } else {
6624 bval = TRUE;
6626 if (bval != *((CK_BBOOL *)tmpl_attr->pValue)) {
6627 return (B_FALSE);
6629 break;
6631 case CKA_OWNER:
6633 * For X.509 attribute certificate object, get its
6634 * CKA_OWNER attribute from the x509_attr_cert_t struct.
6636 if ((obj->class == CKO_CERTIFICATE) &&
6637 (obj->cert_type == CKC_X_509_ATTR_CERT)) {
6638 cert_attr = X509_ATTR_CERT_OWNER(obj);
6639 compare_cert_val = B_TRUE;
6641 break;
6642 case CKA_SUBJECT:
6644 * For X.509 certificate object, get its CKA_SUBJECT
6645 * attribute from the x509_cert_t struct (not from
6646 * the extra_attrlistp).
6648 if ((obj->class == CKO_CERTIFICATE) &&
6649 (obj->cert_type == CKC_X_509)) {
6650 cert_attr = X509_CERT_SUBJECT(obj);
6651 compare_cert_val = B_TRUE;
6652 break;
6654 /*FALLTHRU*/
6655 case CKA_ID:
6656 case CKA_START_DATE:
6657 case CKA_END_DATE:
6658 case CKA_KEY_GEN_MECHANISM:
6659 case CKA_LABEL:
6660 case CKA_ISSUER:
6661 case CKA_SERIAL_NUMBER:
6662 case CKA_AC_ISSUER:
6663 case CKA_ATTR_TYPES:
6664 /* find these attributes from extra_attrlistp */
6665 obj_attr = get_extra_attr(tmpl_attr->type, obj);
6666 compare_attr = B_TRUE;
6667 break;
6668 case CKA_CERTIFICATE_TYPE:
6669 compare_cert_type = B_TRUE;
6670 break;
6671 case CKA_VALUE_LEN:
6672 /* only secret key has this attribute */
6673 if (obj->class == CKO_SECRET_KEY) {
6674 if (*((CK_ULONG *)tmpl_attr->pValue) !=
6675 OBJ_SEC_VALUE_LEN(obj)) {
6676 return (B_FALSE);
6678 } else {
6679 return (B_FALSE);
6681 break;
6682 case CKA_VALUE:
6683 switch (obj->class) {
6684 case CKO_SECRET_KEY:
6686 * secret_key_obj_t is the same as
6687 * biginteger_t
6689 bigint = (biginteger_t *)OBJ_SEC(obj);
6690 compare_bigint = B_TRUE;
6691 break;
6692 case CKO_PRIVATE_KEY:
6693 if (obj->key_type == CKK_DSA) {
6694 bigint = OBJ_PRI_DSA_VALUE(obj);
6695 } else if (obj->key_type == CKK_DH) {
6696 bigint = OBJ_PRI_DH_VALUE(obj);
6697 } else if (obj->key_type == CKK_X9_42_DH) {
6698 bigint = OBJ_PRI_DH942_VALUE(obj);
6699 } else {
6700 return (B_FALSE);
6702 compare_bigint = B_TRUE;
6703 break;
6704 case CKO_PUBLIC_KEY:
6705 if (obj->key_type == CKK_DSA) {
6706 bigint = OBJ_PUB_DSA_VALUE(obj);
6707 } else if (obj->key_type == CKK_DH) {
6708 bigint = OBJ_PUB_DH_VALUE(obj);
6709 } else if (obj->key_type == CKK_X9_42_DH) {
6710 bigint = OBJ_PUB_DH942_VALUE(obj);
6711 } else {
6712 return (B_FALSE);
6714 compare_bigint = B_TRUE;
6715 break;
6716 case CKO_CERTIFICATE:
6717 if (obj->cert_type == CKC_X_509) {
6718 cert_attr = X509_CERT_VALUE(obj);
6719 } else if (obj->cert_type ==
6720 CKC_X_509_ATTR_CERT) {
6721 cert_attr = X509_ATTR_CERT_VALUE(obj);
6723 compare_cert_val = B_TRUE;
6724 break;
6725 default:
6726 return (B_FALSE);
6728 break;
6729 case CKA_MODULUS:
6730 /* only RSA public and private key have this attr */
6731 if (obj->key_type == CKK_RSA) {
6732 if (obj->class == CKO_PUBLIC_KEY) {
6733 bigint = OBJ_PUB_RSA_MOD(obj);
6734 } else if (obj->class == CKO_PRIVATE_KEY) {
6735 bigint = OBJ_PRI_RSA_MOD(obj);
6736 } else {
6737 return (B_FALSE);
6739 compare_bigint = B_TRUE;
6740 } else {
6741 return (B_FALSE);
6743 break;
6744 case CKA_MODULUS_BITS:
6745 /* only RSA public key has this attribute */
6746 if ((obj->key_type == CKK_RSA) &&
6747 (obj->class == CKO_PUBLIC_KEY)) {
6748 CK_ULONG mod_bits = OBJ_PUB_RSA_MOD_BITS(obj);
6749 if (mod_bits !=
6750 *((CK_ULONG *)tmpl_attr->pValue)) {
6751 return (B_FALSE);
6753 } else {
6754 return (B_FALSE);
6756 break;
6757 case CKA_PUBLIC_EXPONENT:
6758 /* only RSA public and private key have this attr */
6759 if (obj->key_type == CKK_RSA) {
6760 if (obj->class == CKO_PUBLIC_KEY) {
6761 bigint = OBJ_PUB_RSA_PUBEXPO(obj);
6762 } else if (obj->class == CKO_PRIVATE_KEY) {
6763 bigint = OBJ_PRI_RSA_PUBEXPO(obj);
6764 } else {
6765 return (B_FALSE);
6767 compare_bigint = B_TRUE;
6768 } else {
6769 return (B_FALSE);
6771 break;
6772 case CKA_PRIVATE_EXPONENT:
6773 /* only RSA private key has this attribute */
6774 if ((obj->key_type == CKK_RSA) &&
6775 (obj->class == CKO_PRIVATE_KEY)) {
6776 bigint = OBJ_PRI_RSA_PRIEXPO(obj);
6777 compare_bigint = B_TRUE;
6778 } else {
6779 return (B_FALSE);
6781 break;
6782 case CKA_PRIME_1:
6783 /* only RSA private key has this attribute */
6784 if ((obj->key_type == CKK_RSA) &&
6785 (obj->class == CKO_PRIVATE_KEY)) {
6786 bigint = OBJ_PRI_RSA_PRIME1(obj);
6787 compare_bigint = B_TRUE;
6788 } else {
6789 return (B_FALSE);
6791 break;
6792 case CKA_PRIME_2:
6793 /* only RSA private key has this attribute */
6794 if ((obj->key_type == CKK_RSA) &&
6795 (obj->class == CKO_PRIVATE_KEY)) {
6796 bigint = OBJ_PRI_RSA_PRIME2(obj);
6797 compare_bigint = B_TRUE;
6798 } else {
6799 return (B_FALSE);
6801 break;
6802 case CKA_EXPONENT_1:
6803 /* only RSA private key has this attribute */
6804 if ((obj->key_type == CKK_RSA) &&
6805 (obj->class == CKO_PRIVATE_KEY)) {
6806 bigint = OBJ_PRI_RSA_EXPO1(obj);
6807 compare_bigint = B_TRUE;
6808 } else {
6809 return (B_FALSE);
6811 break;
6812 case CKA_EXPONENT_2:
6813 /* only RSA private key has this attribute */
6814 if ((obj->key_type == CKK_RSA) &&
6815 (obj->class == CKO_PRIVATE_KEY)) {
6816 bigint = OBJ_PRI_RSA_EXPO2(obj);
6817 compare_bigint = B_TRUE;
6818 } else {
6819 return (B_FALSE);
6821 break;
6822 case CKA_COEFFICIENT:
6823 /* only RSA private key has this attribute */
6824 if ((obj->key_type == CKK_RSA) &&
6825 (obj->class == CKO_PRIVATE_KEY)) {
6826 bigint = OBJ_PRI_RSA_COEF(obj);
6827 compare_bigint = B_TRUE;
6828 } else {
6829 return (B_FALSE);
6831 break;
6832 case CKA_VALUE_BITS:
6833 /* only Diffie-Hellman private key has this attr */
6834 if ((obj->key_type == CKK_DH) &&
6835 (obj->class == CKO_PRIVATE_KEY)) {
6836 CK_ULONG val_bits = OBJ_PRI_DH_VAL_BITS(obj);
6837 if (val_bits !=
6838 *((CK_ULONG *)tmpl_attr->pValue)) {
6839 return (B_FALSE);
6841 } else {
6842 return (B_FALSE);
6844 break;
6845 case CKA_PRIME:
6846 if (obj->class == CKO_PUBLIC_KEY) {
6847 switch (obj->key_type) {
6848 case CKK_DSA:
6849 bigint = OBJ_PUB_DSA_PRIME(obj);
6850 break;
6851 case CKK_DH:
6852 bigint = OBJ_PUB_DH_PRIME(obj);
6853 break;
6854 case CKK_X9_42_DH:
6855 bigint = OBJ_PUB_DH942_PRIME(obj);
6856 break;
6857 default:
6858 return (B_FALSE);
6860 } else if (obj->class == CKO_PRIVATE_KEY) {
6861 switch (obj->key_type) {
6862 case CKK_DSA:
6863 bigint = OBJ_PRI_DSA_PRIME(obj);
6864 break;
6865 case CKK_DH:
6866 bigint = OBJ_PRI_DH_PRIME(obj);
6867 break;
6868 case CKK_X9_42_DH:
6869 bigint = OBJ_PRI_DH942_PRIME(obj);
6870 break;
6871 default:
6872 return (B_FALSE);
6874 } else if (obj->class == CKO_DOMAIN_PARAMETERS) {
6875 switch (obj->key_type) {
6876 case CKK_DSA:
6877 bigint = OBJ_DOM_DSA_PRIME(obj);
6878 break;
6879 case CKK_DH:
6880 bigint = OBJ_DOM_DH_PRIME(obj);
6881 break;
6882 case CKK_X9_42_DH:
6883 bigint = OBJ_DOM_DH942_PRIME(obj);
6884 break;
6885 default:
6886 return (B_FALSE);
6888 } else {
6889 return (B_FALSE);
6891 compare_bigint = B_TRUE;
6892 break;
6893 case CKA_SUBPRIME:
6894 if (obj->class == CKO_PUBLIC_KEY) {
6895 switch (obj->key_type) {
6896 case CKK_DSA:
6897 bigint = OBJ_PUB_DSA_SUBPRIME(obj);
6898 break;
6899 case CKK_X9_42_DH:
6900 bigint = OBJ_PUB_DH942_SUBPRIME(obj);
6901 break;
6902 default:
6903 return (B_FALSE);
6905 } else if (obj->class == CKO_PRIVATE_KEY) {
6906 switch (obj->key_type) {
6907 case CKK_DSA:
6908 bigint = OBJ_PRI_DSA_SUBPRIME(obj);
6909 break;
6910 case CKK_X9_42_DH:
6911 bigint = OBJ_PRI_DH942_SUBPRIME(obj);
6912 break;
6913 default:
6914 return (B_FALSE);
6916 } else if (obj->class == CKO_DOMAIN_PARAMETERS) {
6917 switch (obj->key_type) {
6918 case CKK_DSA:
6919 bigint = OBJ_DOM_DSA_SUBPRIME(obj);
6920 break;
6921 case CKK_X9_42_DH:
6922 bigint = OBJ_DOM_DH942_SUBPRIME(obj);
6923 break;
6924 default:
6925 return (B_FALSE);
6927 } else {
6928 return (B_FALSE);
6930 compare_bigint = B_TRUE;
6931 break;
6932 case CKA_BASE:
6933 if (obj->class == CKO_PUBLIC_KEY) {
6934 switch (obj->key_type) {
6935 case CKK_DSA:
6936 bigint = OBJ_PUB_DSA_BASE(obj);
6937 break;
6938 case CKK_DH:
6939 bigint = OBJ_PUB_DH_BASE(obj);
6940 break;
6941 case CKK_X9_42_DH:
6942 bigint = OBJ_PUB_DH942_BASE(obj);
6943 break;
6944 default:
6945 return (B_FALSE);
6947 } else if (obj->class == CKO_PRIVATE_KEY) {
6948 switch (obj->key_type) {
6949 case CKK_DSA:
6950 bigint = OBJ_PRI_DSA_BASE(obj);
6951 break;
6952 case CKK_DH:
6953 bigint = OBJ_PRI_DH_BASE(obj);
6954 break;
6955 case CKK_X9_42_DH:
6956 bigint = OBJ_PRI_DH942_BASE(obj);
6957 break;
6958 default:
6959 return (B_FALSE);
6961 } else if (obj->class == CKO_DOMAIN_PARAMETERS) {
6962 switch (obj->key_type) {
6963 case CKK_DSA:
6964 bigint = OBJ_DOM_DSA_BASE(obj);
6965 break;
6966 case CKK_DH:
6967 bigint = OBJ_DOM_DH_BASE(obj);
6968 break;
6969 case CKK_X9_42_DH:
6970 bigint = OBJ_DOM_DH942_BASE(obj);
6971 break;
6972 default:
6973 return (B_FALSE);
6975 } else {
6976 return (B_FALSE);
6978 compare_bigint = B_TRUE;
6979 break;
6980 case CKA_PRIME_BITS:
6981 if (obj->class == CKO_DOMAIN_PARAMETERS) {
6982 CK_ULONG prime_bits;
6983 if (obj->key_type == CKK_DSA) {
6984 prime_bits =
6985 OBJ_DOM_DSA_PRIME_BITS(obj);
6986 } else if (obj->key_type == CKK_DH) {
6987 prime_bits =
6988 OBJ_DOM_DH_PRIME_BITS(obj);
6989 } else if (obj->key_type == CKK_X9_42_DH) {
6990 prime_bits =
6991 OBJ_DOM_DH942_PRIME_BITS(obj);
6992 } else {
6993 return (B_FALSE);
6995 if (prime_bits !=
6996 *((CK_ULONG *)tmpl_attr->pValue)) {
6997 return (B_FALSE);
6999 } else {
7000 return (B_FALSE);
7002 break;
7003 case CKA_SUBPRIME_BITS:
7004 if ((obj->class == CKO_DOMAIN_PARAMETERS) &&
7005 (obj->key_type == CKK_X9_42_DH)) {
7006 CK_ULONG subprime_bits =
7007 OBJ_DOM_DH942_SUBPRIME_BITS(obj);
7008 if (subprime_bits !=
7009 *((CK_ULONG *)tmpl_attr->pValue)) {
7010 return (B_FALSE);
7012 } else {
7013 return (B_FALSE);
7015 break;
7016 default:
7018 * any other attributes are currently not supported.
7019 * so, it's not possible for them to be in the
7020 * object
7022 return (B_FALSE);
7024 if (compare_boolean) {
7025 CK_BBOOL bval;
7027 if (attr_mask) {
7028 bval = TRUE;
7029 } else {
7030 bval = FALSE;
7032 if (bval != *((CK_BBOOL *)tmpl_attr->pValue)) {
7033 return (B_FALSE);
7035 } else if (compare_bigint) {
7036 if (bigint == NULL) {
7037 return (B_FALSE);
7039 if (tmpl_attr->ulValueLen != bigint->big_value_len) {
7040 return (B_FALSE);
7042 if (memcmp(tmpl_attr->pValue, bigint->big_value,
7043 tmpl_attr->ulValueLen) != 0) {
7044 return (B_FALSE);
7046 } else if (compare_attr) {
7047 if (obj_attr == NULL) {
7049 * The attribute type is valid, and its value
7050 * has not been initialized in the object. In
7051 * this case, it only matches the template's
7052 * attribute if the template's value length
7053 * is 0.
7055 if (tmpl_attr->ulValueLen != 0)
7056 return (B_FALSE);
7057 } else {
7058 if (tmpl_attr->ulValueLen !=
7059 obj_attr->ulValueLen) {
7060 return (B_FALSE);
7062 if (memcmp(tmpl_attr->pValue, obj_attr->pValue,
7063 tmpl_attr->ulValueLen) != 0) {
7064 return (B_FALSE);
7067 } else if (compare_cert_val) {
7068 if (cert_attr == NULL) {
7069 /* specific attribute not found */
7070 return (B_FALSE);
7072 if (tmpl_attr->ulValueLen != cert_attr->length) {
7073 return (B_FALSE);
7075 if (memcmp(tmpl_attr->pValue, cert_attr->value,
7076 tmpl_attr->ulValueLen) != 0) {
7077 return (B_FALSE);
7079 } else if (compare_cert_type) {
7080 if (memcmp(tmpl_attr->pValue, &(obj->cert_type),
7081 tmpl_attr->ulValueLen) != 0) {
7082 return (B_FALSE);
7086 return (B_TRUE);
7089 CK_ATTRIBUTE_PTR
7090 get_extra_attr(CK_ATTRIBUTE_TYPE type, soft_object_t *obj)
7092 CK_ATTRIBUTE_INFO_PTR tmp;
7094 tmp = obj->extra_attrlistp;
7095 while (tmp != NULL) {
7096 if (tmp->attr.type == type) {
7097 return (&(tmp->attr));
7099 tmp = tmp->next;
7101 /* if get there, the specified attribute is not found */
7102 return (NULL);