sd: remove 'ssd' driver support
[unleashed/tickless.git] / usr / src / lib / pkcs11 / pkcs11_softtoken / common / softAttributeUtil.c
blob33a99ee0d0fef04b49fdbc3bf214cba9cf4b5756
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 free(extra_attr->attr.pValue);
426 /* Free the storage for the attribute_info struct. */
427 free(extra_attr);
428 extra_attr = tmp;
431 object_p->extra_attrlistp = NULL;
436 * Create the attribute_info struct to hold the object's attribute,
437 * and add it to the extra attribute list of an object.
439 CK_RV
440 soft_add_extra_attr(CK_ATTRIBUTE_PTR template, soft_object_t *object_p)
443 CK_ATTRIBUTE_INFO_PTR attrp;
445 /* Allocate the storage for the attribute_info struct. */
446 attrp = calloc(1, sizeof (attribute_info_t));
447 if (attrp == NULL) {
448 return (CKR_HOST_MEMORY);
451 /* Set up attribute_info struct. */
452 attrp->attr.type = template->type;
453 attrp->attr.ulValueLen = template->ulValueLen;
455 if ((template->pValue != NULL) &&
456 (template->ulValueLen > 0)) {
457 /* Allocate storage for the value of the attribute. */
458 attrp->attr.pValue = malloc(template->ulValueLen);
459 if (attrp->attr.pValue == NULL) {
460 free(attrp);
461 return (CKR_HOST_MEMORY);
464 (void) memcpy(attrp->attr.pValue, template->pValue,
465 template->ulValueLen);
466 } else {
467 attrp->attr.pValue = NULL;
470 /* Insert the new attribute in front of extra attribute list. */
471 if (object_p->extra_attrlistp == NULL) {
472 object_p->extra_attrlistp = attrp;
473 attrp->next = NULL;
474 } else {
475 attrp->next = object_p->extra_attrlistp;
476 object_p->extra_attrlistp = attrp;
479 return (CKR_OK);
482 CK_RV
483 soft_copy_certificate(certificate_obj_t *oldcert, certificate_obj_t **newcert,
484 CK_CERTIFICATE_TYPE type)
486 CK_RV rv = CKR_OK;
487 certificate_obj_t *cert;
488 x509_cert_t x509;
489 x509_attr_cert_t x509_attr;
491 cert = calloc(1, sizeof (certificate_obj_t));
492 if (cert == NULL) {
493 return (CKR_HOST_MEMORY);
496 if (type == CKC_X_509) {
497 x509 = oldcert->cert_type_u.x509;
498 if (x509.subject)
499 if ((rv = copy_cert_attr(x509.subject,
500 &cert->cert_type_u.x509.subject)))
501 return (rv);
502 if (x509.value)
503 if ((rv = copy_cert_attr(x509.value,
504 &cert->cert_type_u.x509.value)))
505 return (rv);
506 } else if (type == CKC_X_509_ATTR_CERT) {
507 x509_attr = oldcert->cert_type_u.x509_attr;
508 if (x509_attr.owner)
509 if ((rv = copy_cert_attr(x509_attr.owner,
510 &cert->cert_type_u.x509_attr.owner)))
511 return (rv);
512 if (x509_attr.value)
513 if ((rv = copy_cert_attr(x509_attr.value,
514 &cert->cert_type_u.x509_attr.value)))
515 return (rv);
516 } else {
517 /* wrong certificate type */
518 rv = CKR_ATTRIBUTE_TYPE_INVALID;
520 if (rv == CKR_OK)
521 *newcert = cert;
522 return (rv);
526 * Copy the attribute_info struct from the old object to a new attribute_info
527 * struct, and add that new struct to the extra attribute list of the new
528 * object.
530 CK_RV
531 soft_copy_extra_attr(CK_ATTRIBUTE_INFO_PTR old_attrp, soft_object_t *object_p)
533 CK_ATTRIBUTE_INFO_PTR attrp;
535 /* Allocate attribute_info struct. */
536 attrp = calloc(1, sizeof (attribute_info_t));
537 if (attrp == NULL) {
538 return (CKR_HOST_MEMORY);
541 attrp->attr.type = old_attrp->attr.type;
542 attrp->attr.ulValueLen = old_attrp->attr.ulValueLen;
544 if ((old_attrp->attr.pValue != NULL) &&
545 (old_attrp->attr.ulValueLen > 0)) {
546 attrp->attr.pValue = malloc(old_attrp->attr.ulValueLen);
547 if (attrp->attr.pValue == NULL) {
548 free(attrp);
549 return (CKR_HOST_MEMORY);
552 (void) memcpy(attrp->attr.pValue, old_attrp->attr.pValue,
553 old_attrp->attr.ulValueLen);
554 } else {
555 attrp->attr.pValue = NULL;
558 /* Insert the new attribute in front of extra attribute list */
559 if (object_p->extra_attrlistp == NULL) {
560 object_p->extra_attrlistp = attrp;
561 attrp->next = NULL;
562 } else {
563 attrp->next = object_p->extra_attrlistp;
564 object_p->extra_attrlistp = attrp;
567 return (CKR_OK);
572 * Get the attribute triple from the extra attribute list in the object
573 * (if the specified attribute type is found), and copy it to a template.
574 * Note the type of the attribute to be copied is specified by the template,
575 * and the storage is pre-allocated for the atrribute value in the template
576 * for doing the copy.
578 CK_RV
579 get_extra_attr_from_object(soft_object_t *object_p, CK_ATTRIBUTE_PTR template)
582 CK_ATTRIBUTE_INFO_PTR extra_attr;
583 CK_ATTRIBUTE_TYPE type = template->type;
585 extra_attr = object_p->extra_attrlistp;
587 while (extra_attr) {
588 if (type == extra_attr->attr.type) {
589 /* Found it. */
590 break;
591 } else {
592 /* Does not match, try next one. */
593 extra_attr = extra_attr->next;
597 if (extra_attr == NULL) {
598 /* A valid but un-initialized attribute. */
599 template->ulValueLen = 0;
600 return (CKR_OK);
604 * We found the attribute in the extra attribute list.
606 if (template->pValue == NULL) {
607 template->ulValueLen = extra_attr->attr.ulValueLen;
608 return (CKR_OK);
611 if (template->ulValueLen >= extra_attr->attr.ulValueLen) {
613 * The buffer provided by the application is large
614 * enough to hold the value of the attribute.
616 (void) memcpy(template->pValue, extra_attr->attr.pValue,
617 extra_attr->attr.ulValueLen);
618 template->ulValueLen = extra_attr->attr.ulValueLen;
619 return (CKR_OK);
620 } else {
622 * The buffer provided by the application does
623 * not have enough space to hold the value.
625 template->ulValueLen = (CK_ULONG)-1;
626 return (CKR_BUFFER_TOO_SMALL);
632 * Modify the attribute triple in the extra attribute list of the object
633 * if the specified attribute type is found. Otherwise, just add it to
634 * list.
636 CK_RV
637 set_extra_attr_to_object(soft_object_t *object_p, CK_ATTRIBUTE_TYPE type,
638 CK_ATTRIBUTE_PTR template)
641 CK_ATTRIBUTE_INFO_PTR extra_attr;
643 extra_attr = object_p->extra_attrlistp;
645 while (extra_attr) {
646 if (type == extra_attr->attr.type) {
647 /* Found it. */
648 break;
649 } else {
650 /* Does not match, try next one. */
651 extra_attr = extra_attr->next;
655 if (extra_attr == NULL) {
657 * This attribute is a new one, go ahead adding it to
658 * the extra attribute list.
660 return (soft_add_extra_attr(template, object_p));
663 /* We found the attribute in the extra attribute list. */
664 if ((template->pValue != NULL) &&
665 (template->ulValueLen > 0)) {
666 if (template->ulValueLen > extra_attr->attr.ulValueLen) {
667 /* The old buffer is too small to hold the new value. */
668 free(extra_attr->attr.pValue);
670 /* Allocate storage for the new attribute value. */
671 extra_attr->attr.pValue = malloc(template->ulValueLen);
672 if (extra_attr->attr.pValue == NULL) {
673 return (CKR_HOST_MEMORY);
677 /* Replace the attribute with new value. */
678 extra_attr->attr.ulValueLen = template->ulValueLen;
679 (void) memcpy(extra_attr->attr.pValue, template->pValue,
680 template->ulValueLen);
681 } else {
682 extra_attr->attr.pValue = NULL;
685 return (CKR_OK);
690 * Copy the big integer attribute value from template to a biginteger_t struct.
692 CK_RV
693 get_bigint_attr_from_template(biginteger_t *big, CK_ATTRIBUTE_PTR template)
696 if ((template->pValue != NULL) &&
697 (template->ulValueLen > 0)) {
698 /* Allocate storage for the value of the attribute. */
699 big->big_value = malloc(template->ulValueLen);
700 if (big->big_value == NULL) {
701 return (CKR_HOST_MEMORY);
704 (void) memcpy(big->big_value, template->pValue,
705 template->ulValueLen);
706 big->big_value_len = template->ulValueLen;
707 } else {
708 big->big_value = NULL;
709 big->big_value_len = 0;
712 return (CKR_OK);
717 * Copy the big integer attribute value from a biginteger_t struct in the
718 * object to a template.
720 CK_RV
721 get_bigint_attr_from_object(biginteger_t *big, CK_ATTRIBUTE_PTR template)
724 if (template->pValue == NULL) {
725 template->ulValueLen = big->big_value_len;
726 return (CKR_OK);
729 if (big->big_value == NULL) {
730 template->ulValueLen = 0;
731 return (CKR_OK);
734 if (template->ulValueLen >= big->big_value_len) {
736 * The buffer provided by the application is large
737 * enough to hold the value of the attribute.
739 (void) memcpy(template->pValue, big->big_value,
740 big->big_value_len);
741 template->ulValueLen = big->big_value_len;
742 return (CKR_OK);
743 } else {
745 * The buffer provided by the application does
746 * not have enough space to hold the value.
748 template->ulValueLen = (CK_ULONG)-1;
749 return (CKR_BUFFER_TOO_SMALL);
755 * Copy the boolean data type attribute value from an object for the
756 * specified attribute to the template.
758 CK_RV
759 get_bool_attr_from_object(soft_object_t *object_p, CK_ULONG bool_flag,
760 CK_ATTRIBUTE_PTR template)
763 if (template->pValue == NULL) {
764 template->ulValueLen = sizeof (CK_BBOOL);
765 return (CKR_OK);
768 if (template->ulValueLen >= sizeof (CK_BBOOL)) {
770 * The buffer provided by the application is large
771 * enough to hold the value of the attribute.
773 if (object_p->bool_attr_mask & bool_flag) {
774 *((CK_BBOOL *)template->pValue) = B_TRUE;
775 } else {
776 *((CK_BBOOL *)template->pValue) = B_FALSE;
779 template->ulValueLen = sizeof (CK_BBOOL);
780 return (CKR_OK);
781 } else {
783 * The buffer provided by the application does
784 * not have enough space to hold the value.
786 template->ulValueLen = (CK_ULONG)-1;
787 return (CKR_BUFFER_TOO_SMALL);
792 * Set the boolean data type attribute value in the object.
794 CK_RV
795 set_bool_attr_to_object(soft_object_t *object_p, CK_ULONG bool_flag,
796 CK_ATTRIBUTE_PTR template)
799 if (*(CK_BBOOL *)template->pValue)
800 object_p->bool_attr_mask |= bool_flag;
801 else
802 object_p->bool_attr_mask &= ~bool_flag;
804 return (CKR_OK);
809 * Copy the CK_ULONG data type attribute value from an object to the
810 * template.
812 CK_RV
813 get_ulong_attr_from_object(CK_ULONG value, CK_ATTRIBUTE_PTR template)
816 if (template->pValue == NULL) {
817 template->ulValueLen = sizeof (CK_ULONG);
818 return (CKR_OK);
821 if (template->ulValueLen >= sizeof (CK_ULONG)) {
823 * The buffer provided by the application is large
824 * enough to hold the value of the attribute.
825 * It is also assumed to be correctly aligned.
827 *(CK_ULONG_PTR)template->pValue = value;
828 template->ulValueLen = sizeof (CK_ULONG);
829 return (CKR_OK);
830 } else {
832 * The buffer provided by the application does
833 * not have enough space to hold the value.
835 template->ulValueLen = (CK_ULONG)-1;
836 return (CKR_BUFFER_TOO_SMALL);
842 * Copy the CK_ULONG data type attribute value from a template to the
843 * object.
845 static CK_RV
846 get_ulong_attr_from_template(CK_ULONG *value, CK_ATTRIBUTE_PTR template)
849 if (template->ulValueLen < sizeof (CK_ULONG))
850 return (CKR_ATTRIBUTE_VALUE_INVALID);
852 if (template->pValue != NULL) {
853 *value = *(CK_ULONG_PTR)template->pValue;
854 } else {
855 *value = 0;
858 return (CKR_OK);
862 * Copy the big integer attribute value from source's biginteger_t to
863 * destination's biginteger_t.
865 void
866 copy_bigint_attr(biginteger_t *src, biginteger_t *dst)
869 if ((src->big_value != NULL) &&
870 (src->big_value_len > 0)) {
872 * To do the copy, just have dst's big_value points
873 * to src's.
875 dst->big_value = src->big_value;
876 dst->big_value_len = src->big_value_len;
879 * After the copy, nullify the src's big_value pointer.
880 * It prevents any double freeing the value.
882 src->big_value = NULL;
883 src->big_value_len = 0;
884 } else {
885 dst->big_value = NULL;
886 dst->big_value_len = 0;
890 CK_RV
891 get_string_from_template(CK_ATTRIBUTE_PTR dest, CK_ATTRIBUTE_PTR src)
893 if ((src->pValue != NULL) &&
894 (src->ulValueLen > 0)) {
895 /* Allocate storage for the value of the attribute. */
896 dest->pValue = malloc(src->ulValueLen);
897 if (dest->pValue == NULL) {
898 return (CKR_HOST_MEMORY);
901 (void) memcpy(dest->pValue, src->pValue,
902 src->ulValueLen);
903 dest->ulValueLen = src->ulValueLen;
904 dest->type = src->type;
905 } else {
906 dest->pValue = NULL;
907 dest->ulValueLen = 0;
908 dest->type = src->type;
911 return (CKR_OK);
915 CK_RV
916 get_cert_attr_from_template(cert_attr_t **dest, CK_ATTRIBUTE_PTR src)
918 if (src->pValue != NULL && src->ulValueLen > 0) {
920 * If the attribute was already set, clear out the
921 * existing value and release the memory.
923 if (*dest != NULL) {
924 if ((*dest)->value != NULL) {
925 (void) memset((*dest)->value, 0,
926 (*dest)->length);
927 free((*dest)->value);
929 } else {
930 *dest = malloc(sizeof (cert_attr_t));
931 if (*dest == NULL) {
932 return (CKR_HOST_MEMORY);
934 (void) memset(*dest, 0, sizeof (cert_attr_t));
936 (*dest)->value = malloc(src->ulValueLen);
937 if ((*dest)->value == NULL) {
938 free(*dest);
939 *dest = NULL;
940 return (CKR_HOST_MEMORY);
942 (void) memcpy((*dest)->value, src->pValue, src->ulValueLen);
943 (*dest)->length = src->ulValueLen;
946 return (CKR_OK);
950 * Copy the certificate attribute information to the template.
951 * If the template attribute is not big enough, set the ulValueLen=-1
952 * and return CKR_BUFFER_TOO_SMALL.
954 static CK_RV
955 get_cert_attr_from_object(cert_attr_t *src, CK_ATTRIBUTE_PTR template)
957 if (template->pValue == NULL) {
958 template->ulValueLen = src->length;
959 return (CKR_OK);
960 } else if (template->ulValueLen >= src->length) {
962 * The buffer provided by the application is large
963 * enough to hold the value of the attribute.
965 (void) memcpy(template->pValue, src->value, src->length);
966 template->ulValueLen = src->length;
967 return (CKR_OK);
968 } else {
970 * The buffer provided by the application does
971 * not have enough space to hold the value.
973 template->ulValueLen = (CK_ULONG)-1;
974 return (CKR_BUFFER_TOO_SMALL);
978 void
979 string_attr_cleanup(CK_ATTRIBUTE_PTR template)
982 if (template->pValue) {
983 free(template->pValue);
984 template->pValue = NULL;
985 template->ulValueLen = 0;
990 * Release the storage allocated for object attribute with big integer
991 * value.
993 void
994 bigint_attr_cleanup(biginteger_t *big)
997 if (big == NULL)
998 return;
1000 if (big->big_value) {
1001 (void) memset(big->big_value, 0, big->big_value_len);
1002 free(big->big_value);
1003 big->big_value = NULL;
1004 big->big_value_len = 0;
1010 * Clean up and release all the storage allocated to hold the big integer
1011 * attributes associated with the type (i.e. class) of the object. Also,
1012 * release the storage allocated to the type of the object.
1014 void
1015 soft_cleanup_object_bigint_attrs(soft_object_t *object_p)
1018 CK_OBJECT_CLASS class = object_p->class;
1019 CK_KEY_TYPE keytype = object_p->key_type;
1022 switch (class) {
1023 case CKO_PUBLIC_KEY:
1024 if (OBJ_PUB(object_p)) {
1025 switch (keytype) {
1026 case CKK_RSA:
1027 bigint_attr_cleanup(OBJ_PUB_RSA_MOD(
1028 object_p));
1029 bigint_attr_cleanup(OBJ_PUB_RSA_PUBEXPO(
1030 object_p));
1031 break;
1033 case CKK_DSA:
1034 bigint_attr_cleanup(OBJ_PUB_DSA_PRIME(
1035 object_p));
1036 bigint_attr_cleanup(OBJ_PUB_DSA_SUBPRIME(
1037 object_p));
1038 bigint_attr_cleanup(OBJ_PUB_DSA_BASE(
1039 object_p));
1040 bigint_attr_cleanup(OBJ_PUB_DSA_VALUE(
1041 object_p));
1042 break;
1044 case CKK_DH:
1045 bigint_attr_cleanup(OBJ_PUB_DH_PRIME(
1046 object_p));
1047 bigint_attr_cleanup(OBJ_PUB_DH_BASE(
1048 object_p));
1049 bigint_attr_cleanup(OBJ_PUB_DH_VALUE(
1050 object_p));
1051 break;
1053 case CKK_X9_42_DH:
1054 bigint_attr_cleanup(OBJ_PUB_DH942_PRIME(
1055 object_p));
1056 bigint_attr_cleanup(OBJ_PUB_DH942_BASE(
1057 object_p));
1058 bigint_attr_cleanup(OBJ_PUB_DH942_SUBPRIME(
1059 object_p));
1060 bigint_attr_cleanup(OBJ_PUB_DH942_VALUE(
1061 object_p));
1062 break;
1063 case CKK_EC:
1064 bigint_attr_cleanup(OBJ_PUB_EC_POINT(
1065 object_p));
1066 break;
1069 /* Release Public Key Object struct */
1070 free(OBJ_PUB(object_p));
1071 OBJ_PUB(object_p) = NULL;
1073 break;
1075 case CKO_PRIVATE_KEY:
1076 if (OBJ_PRI(object_p)) {
1077 switch (keytype) {
1078 case CKK_RSA:
1079 bigint_attr_cleanup(OBJ_PRI_RSA_MOD(
1080 object_p));
1081 bigint_attr_cleanup(OBJ_PRI_RSA_PUBEXPO(
1082 object_p));
1083 bigint_attr_cleanup(OBJ_PRI_RSA_PRIEXPO(
1084 object_p));
1085 bigint_attr_cleanup(OBJ_PRI_RSA_PRIME1(
1086 object_p));
1087 bigint_attr_cleanup(OBJ_PRI_RSA_PRIME2(
1088 object_p));
1089 bigint_attr_cleanup(OBJ_PRI_RSA_EXPO1(
1090 object_p));
1091 bigint_attr_cleanup(OBJ_PRI_RSA_EXPO2(
1092 object_p));
1093 bigint_attr_cleanup(OBJ_PRI_RSA_COEF(
1094 object_p));
1095 break;
1097 case CKK_DSA:
1098 bigint_attr_cleanup(OBJ_PRI_DSA_PRIME(
1099 object_p));
1100 bigint_attr_cleanup(OBJ_PRI_DSA_SUBPRIME(
1101 object_p));
1102 bigint_attr_cleanup(OBJ_PRI_DSA_BASE(
1103 object_p));
1104 bigint_attr_cleanup(OBJ_PRI_DSA_VALUE(
1105 object_p));
1106 break;
1108 case CKK_DH:
1109 bigint_attr_cleanup(OBJ_PRI_DH_PRIME(
1110 object_p));
1111 bigint_attr_cleanup(OBJ_PRI_DH_BASE(
1112 object_p));
1113 bigint_attr_cleanup(OBJ_PRI_DH_VALUE(
1114 object_p));
1115 break;
1117 case CKK_X9_42_DH:
1118 bigint_attr_cleanup(OBJ_PRI_DH942_PRIME(
1119 object_p));
1120 bigint_attr_cleanup(OBJ_PRI_DH942_BASE(
1121 object_p));
1122 bigint_attr_cleanup(OBJ_PRI_DH942_SUBPRIME(
1123 object_p));
1124 bigint_attr_cleanup(OBJ_PRI_DH942_VALUE(
1125 object_p));
1126 break;
1128 case CKK_EC:
1129 bigint_attr_cleanup(OBJ_PRI_EC_VALUE(
1130 object_p));
1131 break;
1134 /* Release Private Key Object struct. */
1135 free(OBJ_PRI(object_p));
1136 OBJ_PRI(object_p) = NULL;
1138 break;
1140 case CKO_SECRET_KEY:
1141 if (OBJ_SEC(object_p)) {
1142 /* cleanup key data area */
1143 if (OBJ_SEC_VALUE(object_p) != NULL &&
1144 OBJ_SEC_VALUE_LEN(object_p) > 0) {
1145 (void) memset(OBJ_SEC_VALUE(object_p), 0,
1146 OBJ_SEC_VALUE_LEN(object_p));
1147 free(OBJ_SEC_VALUE(object_p));
1149 /* cleanup key schedule data area */
1150 if (OBJ_KEY_SCHED(object_p) != NULL &&
1151 OBJ_KEY_SCHED_LEN(object_p) > 0) {
1152 (void) memset(OBJ_KEY_SCHED(object_p), 0,
1153 OBJ_KEY_SCHED_LEN(object_p));
1154 free(OBJ_KEY_SCHED(object_p));
1157 /* Release Secret Key Object struct. */
1158 free(OBJ_SEC(object_p));
1159 OBJ_SEC(object_p) = NULL;
1161 break;
1163 case CKO_DOMAIN_PARAMETERS:
1164 if (OBJ_DOM(object_p)) {
1165 switch (keytype) {
1166 case CKK_DSA:
1167 bigint_attr_cleanup(OBJ_DOM_DSA_PRIME(
1168 object_p));
1169 bigint_attr_cleanup(OBJ_DOM_DSA_SUBPRIME(
1170 object_p));
1171 bigint_attr_cleanup(OBJ_DOM_DSA_BASE(
1172 object_p));
1173 break;
1175 case CKK_DH:
1176 bigint_attr_cleanup(OBJ_DOM_DH_PRIME(
1177 object_p));
1178 bigint_attr_cleanup(OBJ_DOM_DH_BASE(
1179 object_p));
1180 break;
1182 case CKK_X9_42_DH:
1183 bigint_attr_cleanup(OBJ_DOM_DH942_PRIME(
1184 object_p));
1185 bigint_attr_cleanup(OBJ_DOM_DH942_BASE(
1186 object_p));
1187 bigint_attr_cleanup(OBJ_DOM_DH942_SUBPRIME(
1188 object_p));
1189 break;
1192 /* Release Domain Parameters Object struct. */
1193 free(OBJ_DOM(object_p));
1194 OBJ_DOM(object_p) = NULL;
1196 break;
1202 * Parse the common attributes. Return to caller with appropriate return
1203 * value to indicate if the supplied template specifies a valid attribute
1204 * with a valid value.
1206 CK_RV
1207 soft_parse_common_attrs(CK_ATTRIBUTE_PTR template, uchar_t *object_type)
1210 CK_RV rv = CKR_OK;
1212 switch (template->type) {
1213 case CKA_CLASS:
1214 break;
1216 /* default boolean attributes */
1217 case CKA_TOKEN:
1218 if ((*(CK_BBOOL *)template->pValue) == B_TRUE) {
1219 if (!soft_keystore_status(KEYSTORE_INITIALIZED))
1220 return (CKR_DEVICE_REMOVED);
1221 *object_type |= TOKEN_OBJECT;
1223 break;
1225 case CKA_PRIVATE:
1226 if ((*(CK_BBOOL *)template->pValue) == B_TRUE) {
1227 (void) pthread_mutex_lock(&soft_giant_mutex);
1228 if (!soft_slot.authenticated) {
1230 * Check if this is the special case when
1231 * the PIN is never initialized in the keystore.
1232 * If true, we will let it pass here and let
1233 * it fail with CKR_PIN_EXPIRED later on.
1235 if (!soft_slot.userpin_change_needed) {
1236 (void) pthread_mutex_unlock(
1237 &soft_giant_mutex);
1238 return (CKR_USER_NOT_LOGGED_IN);
1241 (void) pthread_mutex_unlock(&soft_giant_mutex);
1242 *object_type |= PRIVATE_OBJECT;
1244 break;
1246 case CKA_LABEL:
1247 break;
1249 default:
1250 rv = CKR_TEMPLATE_INCONSISTENT;
1253 return (rv);
1258 * Build a Public Key Object.
1260 * - Parse the object's template, and when an error is detected such as
1261 * invalid attribute type, invalid attribute value, etc., return
1262 * with appropriate return value.
1263 * - Set up attribute mask field in the object for the supplied common
1264 * attributes that have boolean type.
1265 * - Build the attribute_info struct to hold the value of each supplied
1266 * attribute that has byte array type. Link attribute_info structs
1267 * together to form the extra attribute list of the object.
1268 * - Allocate storage for the Public Key object.
1269 * - Build the Public Key object according to the key type. Allocate
1270 * storage to hold the big integer value for the supplied attributes
1271 * that are required for a certain key type.
1274 CK_RV
1275 soft_build_public_key_object(CK_ATTRIBUTE_PTR template, CK_ULONG ulAttrNum,
1276 soft_object_t *new_object, CK_ULONG mode, CK_KEY_TYPE key_type)
1279 ulong_t i;
1280 CK_KEY_TYPE keytype = (CK_KEY_TYPE)~0UL;
1281 uint64_t attr_mask = PUBLIC_KEY_DEFAULT;
1282 CK_RV rv = CKR_OK;
1283 int isLabel = 0;
1284 /* Must set flags */
1285 int isModulus = 0;
1286 int isPubExpo = 0;
1287 int isPrime = 0;
1288 int isSubprime = 0;
1289 int isBase = 0;
1290 int isValue = 0;
1291 int isECParam = 0;
1292 int isECPoint = 0;
1293 /* Must not set flags */
1294 int isModulusBits = 0;
1295 CK_ULONG modulus_bits = 0;
1297 biginteger_t modulus;
1298 biginteger_t pubexpo;
1299 biginteger_t prime;
1300 biginteger_t subprime;
1301 biginteger_t base;
1302 biginteger_t value;
1303 biginteger_t point;
1304 CK_ATTRIBUTE string_tmp;
1305 CK_ATTRIBUTE param_tmp;
1307 public_key_obj_t *pbk;
1308 uchar_t object_type = 0;
1310 CK_ATTRIBUTE defpubexpo = { CKA_PUBLIC_EXPONENT,
1311 (CK_BYTE_PTR)DEFAULT_PUB_EXPO, DEFAULT_PUB_EXPO_Len };
1313 BIGNUM n;
1315 /* prevent bigint_attr_cleanup from freeing invalid attr value */
1316 (void) memset(&modulus, 0x0, sizeof (biginteger_t));
1317 (void) memset(&pubexpo, 0x0, sizeof (biginteger_t));
1318 (void) memset(&prime, 0x0, sizeof (biginteger_t));
1319 (void) memset(&subprime, 0x0, sizeof (biginteger_t));
1320 (void) memset(&base, 0x0, sizeof (biginteger_t));
1321 (void) memset(&value, 0x0, sizeof (biginteger_t));
1322 (void) memset(&point, 0x0, sizeof (biginteger_t));
1323 string_tmp.pValue = NULL;
1324 param_tmp.pValue = NULL;
1326 for (i = 0; i < ulAttrNum; i++) {
1328 /* Public Key Object Attributes */
1329 switch (template[i].type) {
1331 /* common key attributes */
1332 case CKA_KEY_TYPE:
1333 keytype = *((CK_KEY_TYPE*)template[i].pValue);
1334 break;
1336 case CKA_ID:
1337 case CKA_START_DATE:
1338 case CKA_END_DATE:
1340 /* common public key attribute */
1341 case CKA_SUBJECT:
1343 * Allocate storage to hold the attribute
1344 * value with byte array type, and add it to
1345 * the extra attribute list of the object.
1347 rv = soft_add_extra_attr(&template[i],
1348 new_object);
1349 if (rv != CKR_OK) {
1350 goto fail_cleanup;
1352 break;
1355 * The following key related attribute types must
1356 * not be specified by C_CreateObject, C_GenerateKey(Pair).
1358 case CKA_LOCAL:
1359 case CKA_KEY_GEN_MECHANISM:
1360 rv = CKR_TEMPLATE_INCONSISTENT;
1361 goto fail_cleanup;
1363 /* Key related boolean attributes */
1364 case CKA_DERIVE:
1365 if (*(CK_BBOOL *)template[i].pValue)
1366 attr_mask |= DERIVE_BOOL_ON;
1367 break;
1369 case CKA_ENCRYPT:
1370 if (*(CK_BBOOL *)template[i].pValue)
1371 attr_mask |= ENCRYPT_BOOL_ON;
1372 else
1373 attr_mask &= ~ENCRYPT_BOOL_ON;
1374 break;
1376 case CKA_VERIFY:
1377 if (*(CK_BBOOL *)template[i].pValue)
1378 attr_mask |= VERIFY_BOOL_ON;
1379 else
1380 attr_mask &= ~VERIFY_BOOL_ON;
1381 break;
1383 case CKA_VERIFY_RECOVER:
1384 if (*(CK_BBOOL *)template[i].pValue)
1385 attr_mask |= VERIFY_RECOVER_BOOL_ON;
1386 else
1387 attr_mask &= ~VERIFY_RECOVER_BOOL_ON;
1388 break;
1390 case CKA_WRAP:
1391 if (*(CK_BBOOL *)template[i].pValue)
1392 attr_mask |= WRAP_BOOL_ON;
1393 else
1394 attr_mask &= ~WRAP_BOOL_ON;
1395 break;
1397 case CKA_TRUSTED:
1398 if (*(CK_BBOOL *)template[i].pValue)
1399 attr_mask |= TRUSTED_BOOL_ON;
1400 break;
1402 case CKA_MODIFIABLE:
1403 if ((*(CK_BBOOL *)template[i].pValue) == B_FALSE)
1404 attr_mask |= NOT_MODIFIABLE_BOOL_ON;
1405 break;
1408 * The following key related attribute types must
1409 * be specified according to the key type by
1410 * C_CreateObject.
1412 case CKA_MODULUS:
1414 isModulus = 1;
1416 * Copyin big integer attribute from template
1417 * to a local variable.
1419 rv = get_bigint_attr_from_template(&modulus,
1420 &template[i]);
1421 if (rv != CKR_OK)
1422 goto fail_cleanup;
1425 * Modulus length needs to be between min key length and
1426 * max key length.
1428 if ((modulus.big_value_len <
1429 MIN_RSA_KEYLENGTH_IN_BYTES) ||
1430 (modulus.big_value_len >
1431 MAX_RSA_KEYLENGTH_IN_BYTES)) {
1432 rv = CKR_ATTRIBUTE_VALUE_INVALID;
1433 goto fail_cleanup;
1435 break;
1437 case CKA_PUBLIC_EXPONENT:
1438 isPubExpo = 1;
1439 rv = get_bigint_attr_from_template(&pubexpo,
1440 &template[i]);
1441 if (rv != CKR_OK)
1442 goto fail_cleanup;
1443 break;
1445 case CKA_PRIME:
1446 isPrime = 1;
1447 rv = get_bigint_attr_from_template(&prime,
1448 &template[i]);
1449 if (rv != CKR_OK)
1450 goto fail_cleanup;
1451 break;
1453 case CKA_SUBPRIME:
1454 isSubprime = 1;
1455 rv = get_bigint_attr_from_template(&subprime,
1456 &template[i]);
1457 if (rv != CKR_OK)
1458 goto fail_cleanup;
1459 break;
1461 case CKA_BASE:
1462 isBase = 1;
1463 rv = get_bigint_attr_from_template(&base,
1464 &template[i]);
1465 if (rv != CKR_OK)
1466 goto fail_cleanup;
1467 break;
1469 case CKA_VALUE:
1470 isValue = 1;
1471 if (mode == SOFT_CREATE_OBJ) {
1472 if ((template[i].ulValueLen == 0) ||
1473 (template[i].pValue == NULL)) {
1474 rv = CKR_ATTRIBUTE_VALUE_INVALID;
1475 goto fail_cleanup;
1479 rv = get_bigint_attr_from_template(&value,
1480 &template[i]);
1481 if (rv != CKR_OK)
1482 goto fail_cleanup;
1483 break;
1485 case CKA_MODULUS_BITS:
1486 isModulusBits = 1;
1487 rv = get_ulong_attr_from_template(&modulus_bits,
1488 &template[i]);
1489 if (rv != CKR_OK)
1490 goto fail_cleanup;
1491 break;
1493 case CKA_LABEL:
1494 isLabel = 1;
1495 rv = get_string_from_template(&string_tmp,
1496 &template[i]);
1497 if (rv != CKR_OK)
1498 goto fail_cleanup;
1499 break;
1501 case CKA_EC_PARAMS:
1502 isECParam = 1;
1503 rv = get_string_from_template(&param_tmp, &template[i]);
1504 if (rv != CKR_OK)
1505 goto fail_cleanup;
1506 break;
1508 case CKA_EC_POINT:
1509 isECPoint = 1;
1510 rv = get_bigint_attr_from_template(&point,
1511 &template[i]);
1512 if (rv != CKR_OK)
1513 goto fail_cleanup;
1514 break;
1516 default:
1517 rv = soft_parse_common_attrs(&template[i],
1518 &object_type);
1519 if (rv != CKR_OK)
1520 goto fail_cleanup;
1521 break;
1523 } /* For */
1525 /* Allocate storage for Public Key Object. */
1526 pbk = calloc(1, sizeof (public_key_obj_t));
1527 if (pbk == NULL) {
1528 rv = CKR_HOST_MEMORY;
1529 goto fail_cleanup;
1532 new_object->object_class_u.public_key = pbk;
1533 new_object->class = CKO_PUBLIC_KEY;
1535 if ((mode == SOFT_CREATE_OBJ) && (keytype == (CK_KEY_TYPE)~0UL)) {
1536 rv = CKR_TEMPLATE_INCOMPLETE;
1537 goto fail_cleanup;
1540 if ((mode == SOFT_GEN_KEY) && (keytype == (CK_KEY_TYPE)~0UL)) {
1541 keytype = key_type;
1544 if ((mode == SOFT_GEN_KEY) && (keytype != key_type)) {
1546 * The key type specified in the template does not
1547 * match the implied key type based on the mechanism.
1549 rv = CKR_TEMPLATE_INCONSISTENT;
1550 goto fail_cleanup;
1553 new_object->key_type = keytype;
1555 /* Supported key types of the Public Key Object */
1556 switch (keytype) {
1558 case CKK_RSA:
1559 if (mode == SOFT_CREATE_OBJ) {
1560 if (isModulusBits || isPrime || isSubprime ||
1561 isBase || isValue) {
1562 rv = CKR_TEMPLATE_INCONSISTENT;
1563 goto fail_cleanup;
1566 if (isModulus && isPubExpo) {
1568 * Derive modulus_bits attribute from modulus.
1569 * Save modulus_bits integer value to the
1570 * designated place in the public key object.
1572 n.malloced = 0;
1573 #ifdef __sparcv9
1574 if (big_init(&n, (int)CHARLEN2BIGNUMLEN(
1575 modulus.big_value_len)) != BIG_OK) {
1576 #else /* !__sparcv9 */
1577 if (big_init(&n, CHARLEN2BIGNUMLEN(
1578 modulus.big_value_len)) != BIG_OK) {
1579 #endif /* __sparcv9 */
1580 rv = CKR_HOST_MEMORY;
1581 big_finish(&n);
1582 goto fail_cleanup;
1584 bytestring2bignum(&n, modulus.big_value,
1585 modulus.big_value_len);
1587 modulus_bits = big_bitlength(&n);
1588 KEY_PUB_RSA_MOD_BITS(pbk) = modulus_bits;
1589 big_finish(&n);
1592 * After modulus_bits has been computed,
1593 * it is safe to move modulus and pubexpo
1594 * big integer attribute value to the
1595 * designated place in the public key object.
1597 copy_bigint_attr(&modulus,
1598 KEY_PUB_RSA_MOD(pbk));
1600 copy_bigint_attr(&pubexpo,
1601 KEY_PUB_RSA_PUBEXPO(pbk));
1602 } else {
1603 rv = CKR_TEMPLATE_INCOMPLETE;
1604 goto fail_cleanup;
1606 } else {
1607 /* mode is SOFT_GEN_KEY */
1609 if (isModulus || isPrime || isSubprime ||
1610 isBase || isValue) {
1611 rv = CKR_TEMPLATE_INCONSISTENT;
1612 goto fail_cleanup;
1616 if (isModulusBits) {
1618 * Copy big integer attribute value to the
1619 * designated place in the public key object.
1621 KEY_PUB_RSA_MOD_BITS(pbk) = modulus_bits;
1622 } else {
1623 rv = CKR_TEMPLATE_INCOMPLETE;
1624 goto fail_cleanup;
1628 * Use PKCS#11 default 0x010001 for public exponent
1629 * if not not specified in attribute template.
1631 if (!isPubExpo) {
1632 isPubExpo = 1;
1633 rv = get_bigint_attr_from_template(&pubexpo,
1634 &defpubexpo);
1635 if (rv != CKR_OK)
1636 goto fail_cleanup;
1639 * Copy big integer attribute value to the
1640 * designated place in the public key object.
1642 copy_bigint_attr(&pubexpo, KEY_PUB_RSA_PUBEXPO(pbk));
1645 break;
1647 case CKK_DSA:
1648 if (mode == SOFT_CREATE_OBJ) {
1649 if (isModulusBits || isModulus || isPubExpo) {
1650 rv = CKR_TEMPLATE_INCONSISTENT;
1651 goto fail_cleanup;
1654 if (isPrime && isSubprime && isBase && isValue) {
1655 copy_bigint_attr(&value,
1656 KEY_PUB_DSA_VALUE(pbk));
1657 } else {
1658 rv = CKR_TEMPLATE_INCOMPLETE;
1659 goto fail_cleanup;
1661 } else {
1662 if (isModulusBits || isModulus || isPubExpo ||
1663 isValue) {
1664 rv = CKR_TEMPLATE_INCONSISTENT;
1665 goto fail_cleanup;
1668 if (!(isPrime && isSubprime && isBase)) {
1669 rv = CKR_TEMPLATE_INCOMPLETE;
1670 goto fail_cleanup;
1674 copy_bigint_attr(&prime, KEY_PUB_DSA_PRIME(pbk));
1676 copy_bigint_attr(&subprime, KEY_PUB_DSA_SUBPRIME(pbk));
1678 copy_bigint_attr(&base, KEY_PUB_DSA_BASE(pbk));
1680 break;
1682 case CKK_DH:
1683 if (mode == SOFT_CREATE_OBJ) {
1684 if (isModulusBits || isModulus || isPubExpo ||
1685 isSubprime) {
1686 rv = CKR_TEMPLATE_INCONSISTENT;
1687 goto fail_cleanup;
1690 if (isPrime && isBase && isValue) {
1691 copy_bigint_attr(&value,
1692 KEY_PUB_DH_VALUE(pbk));
1693 } else {
1694 rv = CKR_TEMPLATE_INCOMPLETE;
1695 goto fail_cleanup;
1697 } else {
1698 if (isModulusBits || isModulus || isPubExpo ||
1699 isSubprime || isValue) {
1700 rv = CKR_TEMPLATE_INCONSISTENT;
1701 goto fail_cleanup;
1704 if (!(isPrime && isBase)) {
1705 rv = CKR_TEMPLATE_INCOMPLETE;
1706 goto fail_cleanup;
1710 copy_bigint_attr(&prime, KEY_PUB_DH_PRIME(pbk));
1712 copy_bigint_attr(&base, KEY_PUB_DH_BASE(pbk));
1714 break;
1716 case CKK_X9_42_DH:
1717 if (mode == SOFT_CREATE_OBJ) {
1718 if (isModulusBits || isModulus || isPubExpo) {
1719 rv = CKR_TEMPLATE_INCONSISTENT;
1720 goto fail_cleanup;
1723 if (isPrime && isSubprime && isBase && isValue) {
1724 copy_bigint_attr(&value,
1725 KEY_PUB_DH942_VALUE(pbk));
1726 } else {
1727 rv = CKR_TEMPLATE_INCOMPLETE;
1728 goto fail_cleanup;
1730 } else {
1731 if (isModulusBits || isModulus || isPubExpo ||
1732 isValue) {
1733 rv = CKR_TEMPLATE_INCONSISTENT;
1734 goto fail_cleanup;
1737 if (!(isPrime && isSubprime && isBase)) {
1738 rv = CKR_TEMPLATE_INCOMPLETE;
1739 goto fail_cleanup;
1743 copy_bigint_attr(&prime, KEY_PUB_DH942_PRIME(pbk));
1745 copy_bigint_attr(&base, KEY_PUB_DH942_BASE(pbk));
1747 copy_bigint_attr(&subprime, KEY_PUB_DH942_SUBPRIME(pbk));
1749 break;
1751 case CKK_EC:
1752 if (mode == SOFT_CREATE_OBJ) {
1753 if (isModulusBits || isModulus || isPubExpo ||
1754 isPrime || isSubprime || isBase || isValue) {
1755 rv = CKR_TEMPLATE_INCONSISTENT;
1756 goto fail_cleanup;
1758 } else if (!isECParam || !isECPoint) {
1759 rv = CKR_TEMPLATE_INCOMPLETE;
1760 goto fail_cleanup;
1762 } else {
1763 if (isModulusBits || isModulus || isPubExpo ||
1764 isPrime || isSubprime || isBase || isValue) {
1765 rv = CKR_TEMPLATE_INCONSISTENT;
1766 goto fail_cleanup;
1768 } else if (!isECParam) {
1769 rv = CKR_TEMPLATE_INCOMPLETE;
1770 goto fail_cleanup;
1774 if (isECPoint) {
1775 copy_bigint_attr(&point, KEY_PUB_EC_POINT(pbk));
1777 rv = soft_add_extra_attr(&param_tmp, new_object);
1778 if (rv != CKR_OK)
1779 goto fail_cleanup;
1780 string_attr_cleanup(&param_tmp);
1781 break;
1783 default:
1784 rv = CKR_TEMPLATE_INCONSISTENT;
1785 goto fail_cleanup;
1788 /* Set up object. */
1789 new_object->object_type = object_type;
1790 new_object->bool_attr_mask = attr_mask;
1791 if (isLabel) {
1792 rv = soft_add_extra_attr(&string_tmp, new_object);
1793 if (rv != CKR_OK)
1794 goto fail_cleanup;
1795 string_attr_cleanup(&string_tmp);
1798 return (rv);
1800 fail_cleanup:
1802 * cleanup the storage allocated to the local variables.
1804 bigint_attr_cleanup(&modulus);
1805 bigint_attr_cleanup(&pubexpo);
1806 bigint_attr_cleanup(&prime);
1807 bigint_attr_cleanup(&subprime);
1808 bigint_attr_cleanup(&base);
1809 bigint_attr_cleanup(&value);
1810 bigint_attr_cleanup(&point);
1811 string_attr_cleanup(&string_tmp);
1812 string_attr_cleanup(&param_tmp);
1815 * cleanup the storage allocated inside the object itself.
1817 soft_cleanup_object(new_object);
1819 return (rv);
1824 * Build a Private Key Object.
1826 * - Parse the object's template, and when an error is detected such as
1827 * invalid attribute type, invalid attribute value, etc., return
1828 * with appropriate return value.
1829 * - Set up attribute mask field in the object for the supplied common
1830 * attributes that have boolean type.
1831 * - Build the attribute_info struct to hold the value of each supplied
1832 * attribute that has byte array type. Link attribute_info structs
1833 * together to form the extra attribute list of the object.
1834 * - Allocate storage for the Private Key object.
1835 * - Build the Private Key object according to the key type. Allocate
1836 * storage to hold the big integer value for the supplied attributes
1837 * that are required for a certain key type.
1840 CK_RV
1841 soft_build_private_key_object(CK_ATTRIBUTE_PTR template, CK_ULONG ulAttrNum,
1842 soft_object_t *new_object, CK_ULONG mode, CK_KEY_TYPE key_type)
1844 ulong_t i;
1845 CK_KEY_TYPE keytype = (CK_KEY_TYPE)~0UL;
1846 uint64_t attr_mask = PRIVATE_KEY_DEFAULT;
1847 CK_RV rv = CKR_OK;
1848 int isLabel = 0;
1849 int isECParam = 0;
1850 /* Must set flags unless mode == SOFT_UNWRAP_KEY */
1851 int isModulus = 0;
1852 int isPriExpo = 0;
1853 int isPrime = 0;
1854 int isSubprime = 0;
1855 int isBase = 0;
1856 /* Must set flags if mode == SOFT_GEN_KEY */
1857 int isValue = 0;
1858 /* Must not set flags */
1859 int isValueBits = 0;
1860 CK_ULONG value_bits = 0;
1862 /* Private Key RSA optional */
1863 int isPubExpo = 0;
1864 int isPrime1 = 0;
1865 int isPrime2 = 0;
1866 int isExpo1 = 0;
1867 int isExpo2 = 0;
1868 int isCoef = 0;
1870 biginteger_t modulus;
1871 biginteger_t priexpo;
1872 biginteger_t prime;
1873 biginteger_t subprime;
1874 biginteger_t base;
1875 biginteger_t value;
1877 biginteger_t pubexpo;
1878 biginteger_t prime1;
1879 biginteger_t prime2;
1880 biginteger_t expo1;
1881 biginteger_t expo2;
1882 biginteger_t coef;
1883 CK_ATTRIBUTE string_tmp;
1884 CK_ATTRIBUTE param_tmp;
1885 BIGNUM x, q;
1887 private_key_obj_t *pvk;
1888 uchar_t object_type = 0;
1890 /* prevent bigint_attr_cleanup from freeing invalid attr value */
1891 (void) memset(&modulus, 0x0, sizeof (biginteger_t));
1892 (void) memset(&priexpo, 0x0, sizeof (biginteger_t));
1893 (void) memset(&prime, 0x0, sizeof (biginteger_t));
1894 (void) memset(&subprime, 0x0, sizeof (biginteger_t));
1895 (void) memset(&base, 0x0, sizeof (biginteger_t));
1896 (void) memset(&value, 0x0, sizeof (biginteger_t));
1897 (void) memset(&pubexpo, 0x0, sizeof (biginteger_t));
1898 (void) memset(&prime1, 0x0, sizeof (biginteger_t));
1899 (void) memset(&prime2, 0x0, sizeof (biginteger_t));
1900 (void) memset(&expo1, 0x0, sizeof (biginteger_t));
1901 (void) memset(&expo2, 0x0, sizeof (biginteger_t));
1902 (void) memset(&coef, 0x0, sizeof (biginteger_t));
1903 string_tmp.pValue = NULL;
1904 param_tmp.pValue = NULL;
1905 x.malloced = 0;
1906 q.malloced = 0;
1908 for (i = 0; i < ulAttrNum; i++) {
1910 /* Private Key Object Attributes */
1911 switch (template[i].type) {
1912 /* common key attributes */
1913 case CKA_KEY_TYPE:
1914 keytype = *((CK_KEY_TYPE*)template[i].pValue);
1915 break;
1917 case CKA_ID:
1918 case CKA_START_DATE:
1919 case CKA_END_DATE:
1921 /* common private key attribute */
1922 case CKA_SUBJECT:
1924 * Allocate storage to hold the attribute
1925 * value with byte array type, and add it to
1926 * the extra attribute list of the object.
1928 rv = soft_add_extra_attr(&template[i],
1929 new_object);
1930 if (rv != CKR_OK) {
1931 goto fail_cleanup;
1933 break;
1936 * The following key related attribute types must
1937 * not be specified by C_CreateObject or C_GenerateKey(Pair).
1939 case CKA_LOCAL:
1940 case CKA_KEY_GEN_MECHANISM:
1941 case CKA_AUTH_PIN_FLAGS:
1942 case CKA_ALWAYS_SENSITIVE:
1943 case CKA_NEVER_EXTRACTABLE:
1944 rv = CKR_TEMPLATE_INCONSISTENT;
1945 goto fail_cleanup;
1947 /* Key related boolean attributes */
1948 case CKA_DERIVE:
1949 if (*(CK_BBOOL *)template[i].pValue)
1950 attr_mask |= DERIVE_BOOL_ON;
1951 break;
1953 case CKA_SENSITIVE:
1954 if (*(CK_BBOOL *)template[i].pValue)
1955 attr_mask |= SENSITIVE_BOOL_ON;
1956 break;
1958 case CKA_SECONDARY_AUTH:
1959 if (*(CK_BBOOL *)template[i].pValue) {
1960 rv = CKR_ATTRIBUTE_VALUE_INVALID;
1961 goto fail_cleanup;
1963 break;
1965 case CKA_DECRYPT:
1966 if (*(CK_BBOOL *)template[i].pValue)
1967 attr_mask |= DECRYPT_BOOL_ON;
1968 else
1969 attr_mask &= ~DECRYPT_BOOL_ON;
1970 break;
1972 case CKA_SIGN:
1973 if (*(CK_BBOOL *)template[i].pValue)
1974 attr_mask |= SIGN_BOOL_ON;
1975 else
1976 attr_mask &= ~SIGN_BOOL_ON;
1977 break;
1979 case CKA_SIGN_RECOVER:
1980 if (*(CK_BBOOL *)template[i].pValue)
1981 attr_mask |= SIGN_RECOVER_BOOL_ON;
1982 else
1983 attr_mask &= ~SIGN_RECOVER_BOOL_ON;
1984 break;
1986 case CKA_UNWRAP:
1987 if (*(CK_BBOOL *)template[i].pValue)
1988 attr_mask |= UNWRAP_BOOL_ON;
1989 else
1990 attr_mask &= ~UNWRAP_BOOL_ON;
1991 break;
1993 case CKA_EXTRACTABLE:
1994 if (*(CK_BBOOL *)template[i].pValue)
1995 attr_mask |= EXTRACTABLE_BOOL_ON;
1996 else
1997 attr_mask &= ~EXTRACTABLE_BOOL_ON;
1998 break;
2000 case CKA_MODIFIABLE:
2001 if ((*(CK_BBOOL *)template[i].pValue) == B_FALSE)
2002 attr_mask |= NOT_MODIFIABLE_BOOL_ON;
2003 break;
2006 * The following key related attribute types must
2007 * be specified according to the key type by
2008 * C_CreateObject.
2010 case CKA_MODULUS:
2012 isModulus = 1;
2014 * Copyin big integer attribute from template
2015 * to a local variable.
2017 rv = get_bigint_attr_from_template(&modulus,
2018 &template[i]);
2019 if (rv != CKR_OK)
2020 goto fail_cleanup;
2023 * Modulus length needs to be between min key length and
2024 * max key length.
2026 if ((modulus.big_value_len <
2027 MIN_RSA_KEYLENGTH_IN_BYTES) ||
2028 (modulus.big_value_len >
2029 MAX_RSA_KEYLENGTH_IN_BYTES)) {
2030 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2031 goto fail_cleanup;
2033 break;
2035 case CKA_PUBLIC_EXPONENT:
2037 isPubExpo = 1;
2038 rv = get_bigint_attr_from_template(&pubexpo,
2039 &template[i]);
2040 if (rv != CKR_OK)
2041 goto fail_cleanup;
2042 break;
2044 case CKA_PRIVATE_EXPONENT:
2046 isPriExpo = 1;
2047 rv = get_bigint_attr_from_template(&priexpo,
2048 &template[i]);
2049 if (rv != CKR_OK)
2050 goto fail_cleanup;
2051 break;
2053 case CKA_PRIME_1:
2054 isPrime1 = 1;
2055 rv = get_bigint_attr_from_template(&prime1,
2056 &template[i]);
2057 if (rv != CKR_OK)
2058 goto fail_cleanup;
2059 break;
2061 case CKA_PRIME_2:
2062 isPrime2 = 1;
2063 rv = get_bigint_attr_from_template(&prime2,
2064 &template[i]);
2065 if (rv != CKR_OK)
2066 goto fail_cleanup;
2067 break;
2069 case CKA_EXPONENT_1:
2070 isExpo1 = 1;
2071 rv = get_bigint_attr_from_template(&expo1,
2072 &template[i]);
2073 if (rv != CKR_OK)
2074 goto fail_cleanup;
2075 break;
2077 case CKA_EXPONENT_2:
2078 isExpo2 = 1;
2079 rv = get_bigint_attr_from_template(&expo2,
2080 &template[i]);
2081 if (rv != CKR_OK)
2082 goto fail_cleanup;
2083 break;
2085 case CKA_COEFFICIENT:
2086 isCoef = 1;
2087 rv = get_bigint_attr_from_template(&coef,
2088 &template[i]);
2089 if (rv != CKR_OK)
2090 goto fail_cleanup;
2091 break;
2093 case CKA_PRIME:
2094 isPrime = 1;
2095 rv = get_bigint_attr_from_template(&prime,
2096 &template[i]);
2097 if (rv != CKR_OK)
2098 goto fail_cleanup;
2099 break;
2101 case CKA_SUBPRIME:
2102 isSubprime = 1;
2103 rv = get_bigint_attr_from_template(&subprime,
2104 &template[i]);
2105 if (rv != CKR_OK)
2106 goto fail_cleanup;
2107 break;
2109 case CKA_BASE:
2110 isBase = 1;
2111 rv = get_bigint_attr_from_template(&base,
2112 &template[i]);
2113 if (rv != CKR_OK)
2114 goto fail_cleanup;
2115 break;
2117 case CKA_VALUE:
2118 isValue = 1;
2119 if (mode == SOFT_CREATE_OBJ) {
2120 if ((template[i].ulValueLen == 0) ||
2121 (template[i].pValue == NULL)) {
2122 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2123 goto fail_cleanup;
2127 rv = get_bigint_attr_from_template(&value,
2128 &template[i]);
2129 if (rv != CKR_OK)
2130 goto fail_cleanup;
2131 break;
2133 case CKA_VALUE_BITS:
2134 isValueBits = 1;
2135 rv = get_ulong_attr_from_template(&value_bits,
2136 &template[i]);
2137 if (rv != CKR_OK)
2138 goto fail_cleanup;
2139 break;
2141 case CKA_LABEL:
2142 isLabel = 1;
2143 rv = get_string_from_template(&string_tmp,
2144 &template[i]);
2145 if (rv != CKR_OK)
2146 goto fail_cleanup;
2147 break;
2149 case CKA_EC_PARAMS:
2150 isECParam = 1;
2151 rv = get_string_from_template(&param_tmp,
2152 &template[i]);
2153 if (rv != CKR_OK)
2154 goto fail_cleanup;
2155 break;
2157 default:
2158 rv = soft_parse_common_attrs(&template[i],
2159 &object_type);
2160 if (rv != CKR_OK)
2161 goto fail_cleanup;
2162 break;
2165 } /* For */
2167 /* Allocate storage for Private Key Object. */
2168 pvk = calloc(1, sizeof (private_key_obj_t));
2169 if (pvk == NULL) {
2170 rv = CKR_HOST_MEMORY;
2171 goto fail_cleanup;
2174 new_object->object_class_u.private_key = pvk;
2175 new_object->class = CKO_PRIVATE_KEY;
2177 if ((mode == SOFT_CREATE_OBJ) && (keytype == (CK_KEY_TYPE)~0UL)) {
2178 rv = CKR_TEMPLATE_INCOMPLETE;
2179 goto fail_cleanup;
2182 if (mode == SOFT_GEN_KEY) {
2184 * The key type is not specified in the application's
2185 * template, so we use the implied key type based on
2186 * the mechanism.
2188 if (keytype == (CK_KEY_TYPE)~0UL) {
2189 keytype = key_type;
2192 /* If still unspecified, template is incomplete */
2193 if (keytype == (CK_KEY_TYPE)~0UL) {
2194 rv = CKR_TEMPLATE_INCOMPLETE;
2195 goto fail_cleanup;
2199 * The key type specified in the template does not
2200 * match the implied key type based on the mechanism.
2202 if (keytype != key_type) {
2203 rv = CKR_TEMPLATE_INCONSISTENT;
2204 goto fail_cleanup;
2208 if (mode == SOFT_UNWRAP_KEY) {
2210 * Note that, for mode SOFT_UNWRAP_KEY, key type is not
2211 * implied by the mechanism (key_type), so if it is not
2212 * specified from the attribute template (keytype), it is
2213 * incomplete.
2215 if (keytype == (CK_KEY_TYPE)~0UL) {
2216 rv = CKR_TEMPLATE_INCOMPLETE;
2217 goto fail_cleanup;
2221 new_object->key_type = keytype;
2223 /* Supported key types of the Private Key Object */
2224 switch (keytype) {
2225 case CKK_RSA:
2226 if (isPrime || isSubprime || isBase || isValue ||
2227 isValueBits) {
2228 rv = CKR_TEMPLATE_INCONSISTENT;
2229 goto fail_cleanup;
2232 if (mode == SOFT_GEN_KEY || mode == SOFT_UNWRAP_KEY) {
2233 if (isModulus || isPubExpo || isPriExpo || isPrime1 ||
2234 isPrime2 || isExpo1 || isExpo2 || isCoef) {
2235 rv = CKR_TEMPLATE_INCONSISTENT;
2236 goto fail_cleanup;
2237 } else
2238 break;
2241 if (isModulus && isPriExpo) {
2243 * Copy big integer attribute value to the
2244 * designated place in the Private Key object.
2246 copy_bigint_attr(&modulus, KEY_PRI_RSA_MOD(pvk));
2248 copy_bigint_attr(&priexpo, KEY_PRI_RSA_PRIEXPO(pvk));
2249 } else {
2250 rv = CKR_TEMPLATE_INCOMPLETE;
2251 goto fail_cleanup;
2254 /* The following attributes are optional. */
2255 if (isPubExpo) {
2256 copy_bigint_attr(&pubexpo, KEY_PRI_RSA_PUBEXPO(pvk));
2259 if (isPrime1) {
2260 copy_bigint_attr(&prime1, KEY_PRI_RSA_PRIME1(pvk));
2263 if (isPrime2) {
2264 copy_bigint_attr(&prime2, KEY_PRI_RSA_PRIME2(pvk));
2267 if (isExpo1) {
2268 copy_bigint_attr(&expo1, KEY_PRI_RSA_EXPO1(pvk));
2271 if (isExpo2) {
2272 copy_bigint_attr(&expo2, KEY_PRI_RSA_EXPO2(pvk));
2275 if (isCoef) {
2276 copy_bigint_attr(&coef, KEY_PRI_RSA_COEF(pvk));
2278 break;
2280 case CKK_DSA:
2281 if (isModulus || isPubExpo || isPriExpo || isPrime1 ||
2282 isPrime2 || isExpo1 || isExpo2 || isCoef ||
2283 isValueBits) {
2284 rv = CKR_TEMPLATE_INCONSISTENT;
2285 goto fail_cleanup;
2288 if (mode == SOFT_GEN_KEY || mode == SOFT_UNWRAP_KEY) {
2289 if (isPrime || isSubprime || isBase || isValue) {
2290 rv = CKR_TEMPLATE_INCONSISTENT;
2291 goto fail_cleanup;
2292 } else
2293 break;
2296 if (isPrime && isSubprime && isBase && isValue) {
2298 * The private value x must be less than subprime q.
2299 * Size for big_init is in BIG_CHUNK_TYPE words.
2301 #ifdef __sparcv9
2302 if (big_init(&x,
2303 (int)CHARLEN2BIGNUMLEN(value.big_value_len))
2304 != BIG_OK) {
2305 #else /* !__sparcv9 */
2306 if (big_init(&x,
2307 CHARLEN2BIGNUMLEN(value.big_value_len))
2308 != BIG_OK) {
2309 #endif /* __sparcv9 */
2310 rv = CKR_HOST_MEMORY;
2311 goto fail_cleanup;
2313 #ifdef __sparcv9
2314 if (big_init(&q,
2315 (int)CHARLEN2BIGNUMLEN(subprime.big_value_len))
2316 != BIG_OK) {
2317 #else /* !__sparcv9 */
2318 if (big_init(&q,
2319 CHARLEN2BIGNUMLEN(subprime.big_value_len))
2320 != BIG_OK) {
2321 #endif /* __sparcv9 */
2322 rv = CKR_HOST_MEMORY;
2323 goto fail_cleanup;
2325 bytestring2bignum(&x, value.big_value,
2326 value.big_value_len);
2327 bytestring2bignum(&q, subprime.big_value,
2328 subprime.big_value_len);
2330 if (big_cmp_abs(&x, &q) > 0) {
2331 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2332 goto fail_cleanup;
2335 copy_bigint_attr(&prime, KEY_PRI_DSA_PRIME(pvk));
2337 copy_bigint_attr(&subprime, KEY_PRI_DSA_SUBPRIME(pvk));
2339 copy_bigint_attr(&base, KEY_PRI_DSA_BASE(pvk));
2341 copy_bigint_attr(&value, KEY_PRI_DSA_VALUE(pvk));
2342 } else {
2343 rv = CKR_TEMPLATE_INCOMPLETE;
2344 goto fail_cleanup;
2346 break;
2348 case CKK_DH:
2349 if (isModulus || isPubExpo || isPriExpo || isPrime1 ||
2350 isPrime2 || isExpo1 || isExpo2 || isCoef ||
2351 isSubprime) {
2352 rv = CKR_TEMPLATE_INCONSISTENT;
2353 goto fail_cleanup;
2356 /* CKA_VALUE_BITS is for key gen but not unwrap */
2357 if (mode == SOFT_GEN_KEY)
2358 KEY_PRI_DH_VAL_BITS(pvk) = (isValueBits) ?
2359 value_bits : 0;
2360 else if (mode == SOFT_UNWRAP_KEY) {
2361 if (isValueBits) {
2362 rv = CKR_TEMPLATE_INCONSISTENT;
2363 goto fail_cleanup;
2367 if (mode == SOFT_GEN_KEY || mode == SOFT_UNWRAP_KEY) {
2368 if (isPrime || isBase || isValue) {
2369 rv = CKR_TEMPLATE_INCONSISTENT;
2370 goto fail_cleanup;
2371 } else
2372 break;
2375 if (isValueBits) {
2376 rv = CKR_TEMPLATE_INCONSISTENT;
2377 goto fail_cleanup;
2380 if (isPrime && isBase && isValue) {
2381 copy_bigint_attr(&prime, KEY_PRI_DH_PRIME(pvk));
2383 copy_bigint_attr(&base, KEY_PRI_DH_BASE(pvk));
2385 copy_bigint_attr(&value, KEY_PRI_DH_VALUE(pvk));
2386 } else {
2387 rv = CKR_TEMPLATE_INCOMPLETE;
2388 goto fail_cleanup;
2390 break;
2392 case CKK_X9_42_DH:
2393 if (isModulus || isPubExpo || isPriExpo || isPrime1 ||
2394 isPrime2 || isExpo1 || isExpo2 || isCoef ||
2395 isValueBits) {
2396 rv = CKR_TEMPLATE_INCONSISTENT;
2397 goto fail_cleanup;
2400 if (mode == SOFT_GEN_KEY || mode == SOFT_UNWRAP_KEY) {
2401 if (isPrime || isSubprime || isBase || isValue) {
2402 rv = CKR_TEMPLATE_INCONSISTENT;
2403 goto fail_cleanup;
2404 } else
2405 break;
2408 if (isPrime && isSubprime && isBase && isValue) {
2409 copy_bigint_attr(&prime, KEY_PRI_DH942_PRIME(pvk));
2411 copy_bigint_attr(&base, KEY_PRI_DH942_BASE(pvk));
2413 copy_bigint_attr(&subprime,
2414 KEY_PRI_DH942_SUBPRIME(pvk));
2416 copy_bigint_attr(&value, KEY_PRI_DH942_VALUE(pvk));
2417 } else {
2418 rv = CKR_TEMPLATE_INCOMPLETE;
2419 goto fail_cleanup;
2421 break;
2423 case CKK_EC:
2424 if (isModulus || isPubExpo || isPrime ||
2425 isPrime1 || isPrime2 || isExpo1 || isExpo2 || isCoef ||
2426 isValueBits || isBase) {
2427 rv = CKR_TEMPLATE_INCONSISTENT;
2428 goto fail_cleanup;
2430 } else if (isECParam) {
2431 rv = soft_add_extra_attr(&param_tmp, new_object);
2432 if (rv != CKR_OK)
2433 goto fail_cleanup;
2434 string_attr_cleanup(&param_tmp);
2436 if (isValue) {
2437 copy_bigint_attr(&value, KEY_PRI_EC_VALUE(pvk));
2439 break;
2441 default:
2442 rv = CKR_TEMPLATE_INCONSISTENT;
2443 goto fail_cleanup;
2446 /* Set up object. */
2447 new_object->object_type = object_type;
2448 new_object->bool_attr_mask = attr_mask;
2449 if (isLabel) {
2450 rv = soft_add_extra_attr(&string_tmp, new_object);
2451 if (rv != CKR_OK)
2452 goto fail_cleanup;
2453 string_attr_cleanup(&string_tmp);
2455 big_finish(&x);
2456 big_finish(&q);
2458 return (rv);
2460 fail_cleanup:
2462 * cleanup the storage allocated to the local variables.
2464 bigint_attr_cleanup(&modulus);
2465 bigint_attr_cleanup(&priexpo);
2466 bigint_attr_cleanup(&prime);
2467 bigint_attr_cleanup(&subprime);
2468 bigint_attr_cleanup(&base);
2469 bigint_attr_cleanup(&value);
2470 bigint_attr_cleanup(&pubexpo);
2471 bigint_attr_cleanup(&prime1);
2472 bigint_attr_cleanup(&prime2);
2473 bigint_attr_cleanup(&expo1);
2474 bigint_attr_cleanup(&expo2);
2475 bigint_attr_cleanup(&coef);
2476 string_attr_cleanup(&string_tmp);
2477 string_attr_cleanup(&param_tmp);
2478 big_finish(&x);
2479 big_finish(&q);
2482 * cleanup the storage allocated inside the object itself.
2484 soft_cleanup_object(new_object);
2486 return (rv);
2491 * Build a Secret Key Object.
2493 * - Parse the object's template, and when an error is detected such as
2494 * invalid attribute type, invalid attribute value, etc., return
2495 * with appropriate return value.
2496 * - Set up attribute mask field in the object for the supplied common
2497 * attributes that have boolean type.
2498 * - Build the attribute_info struct to hold the value of each supplied
2499 * attribute that has byte array type. Link attribute_info structs
2500 * together to form the extra attribute list of the object.
2501 * - Allocate storage for the Secret Key object.
2502 * - Build the Secret Key object. Allocate storage to hold the big integer
2503 * value for the attribute CKA_VALUE that is required for all the key
2504 * types supported by secret key object.
2505 * This function is called internally with mode = SOFT_CREATE_OBJ_INT.
2508 CK_RV
2509 soft_build_secret_key_object(CK_ATTRIBUTE_PTR template, CK_ULONG ulAttrNum,
2510 soft_object_t *new_object, CK_ULONG mode, CK_ULONG key_len,
2511 CK_KEY_TYPE key_type)
2514 ulong_t i;
2515 CK_KEY_TYPE keytype = (CK_KEY_TYPE)~0UL;
2516 uint64_t attr_mask = SECRET_KEY_DEFAULT;
2517 CK_RV rv = CKR_OK;
2518 int isLabel = 0;
2519 /* Must set flags if mode != SOFT_UNWRAP_KEY, else must not set */
2520 int isValue = 0;
2521 /* Must not set flags if mode != SOFT_UNWRAP_KEY, else optional */
2522 int isValueLen = 0;
2524 CK_ATTRIBUTE string_tmp;
2526 secret_key_obj_t *sck;
2527 uchar_t object_type = 0;
2529 string_tmp.pValue = NULL;
2531 /* Allocate storage for Secret Key Object. */
2532 sck = calloc(1, sizeof (secret_key_obj_t));
2533 if (sck == NULL) {
2534 rv = CKR_HOST_MEMORY;
2535 goto fail_cleanup;
2538 new_object->object_class_u.secret_key = sck;
2539 new_object->class = CKO_SECRET_KEY;
2541 for (i = 0; i < ulAttrNum; i++) {
2543 /* Secret Key Object Attributes */
2544 switch (template[i].type) {
2546 /* common key attributes */
2547 case CKA_KEY_TYPE:
2548 keytype = *((CK_KEY_TYPE*)template[i].pValue);
2549 break;
2551 case CKA_ID:
2552 case CKA_START_DATE:
2553 case CKA_END_DATE:
2555 * Allocate storage to hold the attribute
2556 * value with byte array type, and add it to
2557 * the extra attribute list of the object.
2559 rv = soft_add_extra_attr(&template[i],
2560 new_object);
2561 if (rv != CKR_OK) {
2562 goto fail_cleanup;
2564 break;
2567 * The following key related attribute types must
2568 * not be specified by C_CreateObject and C_GenerateKey.
2570 case CKA_LOCAL:
2571 case CKA_KEY_GEN_MECHANISM:
2572 case CKA_ALWAYS_SENSITIVE:
2573 case CKA_NEVER_EXTRACTABLE:
2574 rv = CKR_TEMPLATE_INCONSISTENT;
2575 goto fail_cleanup;
2577 /* Key related boolean attributes */
2578 case CKA_DERIVE:
2579 if (*(CK_BBOOL *)template[i].pValue)
2580 attr_mask |= DERIVE_BOOL_ON;
2581 break;
2583 case CKA_SENSITIVE:
2584 if (*(CK_BBOOL *)template[i].pValue)
2585 attr_mask |= SENSITIVE_BOOL_ON;
2586 break;
2588 case CKA_ENCRYPT:
2589 if (*(CK_BBOOL *)template[i].pValue)
2590 attr_mask |= ENCRYPT_BOOL_ON;
2591 else
2592 attr_mask &= ~ENCRYPT_BOOL_ON;
2593 break;
2595 case CKA_DECRYPT:
2596 if (*(CK_BBOOL *)template[i].pValue)
2597 attr_mask |= DECRYPT_BOOL_ON;
2598 else
2599 attr_mask &= ~DECRYPT_BOOL_ON;
2600 break;
2602 case CKA_SIGN:
2603 if (*(CK_BBOOL *)template[i].pValue)
2604 attr_mask |= SIGN_BOOL_ON;
2605 else
2606 attr_mask &= ~SIGN_BOOL_ON;
2607 break;
2609 case CKA_VERIFY:
2610 if (*(CK_BBOOL *)template[i].pValue)
2611 attr_mask |= VERIFY_BOOL_ON;
2612 else
2613 attr_mask &= ~VERIFY_BOOL_ON;
2614 break;
2616 case CKA_WRAP:
2617 if (*(CK_BBOOL *)template[i].pValue)
2618 attr_mask |= WRAP_BOOL_ON;
2619 else
2620 attr_mask &= ~WRAP_BOOL_ON;
2621 break;
2623 case CKA_UNWRAP:
2624 if (*(CK_BBOOL *)template[i].pValue)
2625 attr_mask |= UNWRAP_BOOL_ON;
2626 else
2627 attr_mask &= ~UNWRAP_BOOL_ON;
2628 break;
2630 case CKA_EXTRACTABLE:
2631 if (*(CK_BBOOL *)template[i].pValue)
2632 attr_mask |= EXTRACTABLE_BOOL_ON;
2633 else
2634 attr_mask &= ~EXTRACTABLE_BOOL_ON;
2635 break;
2637 case CKA_MODIFIABLE:
2638 if ((*(CK_BBOOL *)template[i].pValue) == B_FALSE)
2639 attr_mask |= NOT_MODIFIABLE_BOOL_ON;
2640 break;
2642 case CKA_VALUE:
2643 isValue = 1;
2644 if (mode == SOFT_CREATE_OBJ) {
2645 if ((template[i].ulValueLen == 0) ||
2646 (template[i].pValue == NULL)) {
2647 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2648 goto fail_cleanup;
2653 * Copyin attribute from template
2654 * to a local variable.
2656 rv = get_bigint_attr_from_template((biginteger_t *)sck,
2657 &template[i]);
2658 if (rv != CKR_OK)
2659 goto fail_cleanup;
2660 break;
2662 case CKA_VALUE_LEN:
2663 isValueLen = 1;
2664 rv = get_ulong_attr_from_template(&sck->sk_value_len,
2665 &template[i]);
2666 if (rv != CKR_OK)
2667 goto fail_cleanup;
2668 break;
2670 case CKA_LABEL:
2671 isLabel = 1;
2672 rv = get_string_from_template(&string_tmp,
2673 &template[i]);
2674 if (rv != CKR_OK)
2675 goto fail_cleanup;
2676 break;
2678 default:
2679 rv = soft_parse_common_attrs(&template[i],
2680 &object_type);
2681 if (rv != CKR_OK)
2682 goto fail_cleanup;
2683 break;
2686 } /* For */
2688 switch (mode) {
2689 case SOFT_CREATE_OBJ:
2690 case SOFT_CREATE_OBJ_INT:
2691 case SOFT_DERIVE_KEY_DH:
2693 * The key type must be specified in the application's
2694 * template. Otherwise, returns error.
2696 if (keytype == (CK_KEY_TYPE)~0UL) {
2697 rv = CKR_TEMPLATE_INCOMPLETE;
2698 goto fail_cleanup;
2700 break;
2702 case SOFT_GEN_KEY:
2703 if (keytype == (CK_KEY_TYPE)~0UL) {
2705 * The key type is not specified in the application's
2706 * template, so we use the implied key type based on
2707 * the mechanism.
2709 keytype = key_type;
2710 } else {
2711 if (keytype != key_type) {
2713 * The key type specified in the template
2714 * does not match the implied key type based
2715 * on the mechanism.
2717 rv = CKR_TEMPLATE_INCONSISTENT;
2718 goto fail_cleanup;
2723 * If a key_len is passed as a parameter, it has to
2724 * match the one found in the template.
2726 if (key_len > 0) {
2727 if (isValueLen && sck->sk_value_len != key_len) {
2728 rv = CKR_TEMPLATE_INCONSISTENT;
2729 goto fail_cleanup;
2731 isValueLen = 1;
2732 sck->sk_value_len = key_len;
2734 break;
2736 case SOFT_UNWRAP_KEY:
2738 * Note that, for mode SOFT_UNWRAP_KEY, key type is not
2739 * implied by the mechanism (key_type), so if it is not
2740 * specified from the attribute template (keytype), it is
2741 * incomplete.
2743 if (keytype == (CK_KEY_TYPE)~0UL) {
2744 rv = CKR_TEMPLATE_INCOMPLETE;
2745 goto fail_cleanup;
2747 break;
2749 case SOFT_DERIVE_KEY_OTHER:
2751 * For CKM_MD5_KEY_DERIVATION & CKM_SHA1_KEY_DERIVATION, the
2752 * key type is optional.
2754 if (keytype == (CK_KEY_TYPE)~0UL) {
2755 keytype = key_type;
2757 break;
2760 switch (mode) {
2761 case SOFT_CREATE_OBJ:
2762 case SOFT_CREATE_OBJ_INT:
2763 switch (keytype) {
2764 case CKK_RC4:
2765 if (!isValue) {
2766 rv = CKR_TEMPLATE_INCOMPLETE;
2767 goto fail_cleanup;
2769 if ((sck->sk_value_len < ARCFOUR_MIN_KEY_BYTES) ||
2770 (sck->sk_value_len > ARCFOUR_MAX_KEY_BYTES)) {
2771 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2772 goto fail_cleanup;
2774 break;
2776 case CKK_GENERIC_SECRET:
2777 if (!isValue) {
2778 rv = CKR_TEMPLATE_INCOMPLETE;
2779 goto fail_cleanup;
2781 break;
2783 case CKK_AES:
2784 if (!isValue) {
2785 rv = CKR_TEMPLATE_INCOMPLETE;
2786 goto fail_cleanup;
2788 if ((sck->sk_value_len != AES_MIN_KEY_BYTES) &&
2789 (sck->sk_value_len != AES_192_KEY_BYTES) &&
2790 (sck->sk_value_len != AES_MAX_KEY_BYTES)) {
2791 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2792 goto fail_cleanup;
2794 break;
2796 case CKK_BLOWFISH:
2797 if (!isValue) {
2798 rv = CKR_TEMPLATE_INCOMPLETE;
2799 goto fail_cleanup;
2801 if ((sck->sk_value_len < BLOWFISH_MINBYTES) ||
2802 (sck->sk_value_len > BLOWFISH_MAXBYTES)) {
2803 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2804 goto fail_cleanup;
2807 break;
2809 case CKK_DES:
2810 if (!isValue) {
2811 rv = CKR_TEMPLATE_INCOMPLETE;
2812 goto fail_cleanup;
2814 if (sck->sk_value_len != DES_KEYSIZE) {
2815 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2816 goto fail_cleanup;
2818 break;
2820 case CKK_DES2:
2821 if (!isValue) {
2822 rv = CKR_TEMPLATE_INCOMPLETE;
2823 goto fail_cleanup;
2825 if (sck->sk_value_len != DES2_KEYSIZE) {
2826 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2827 goto fail_cleanup;
2829 break;
2831 case CKK_DES3:
2832 if (!isValue) {
2833 rv = CKR_TEMPLATE_INCOMPLETE;
2834 goto fail_cleanup;
2836 if (sck->sk_value_len != DES3_KEYSIZE) {
2837 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2838 goto fail_cleanup;
2840 break;
2842 default:
2843 rv = CKR_TEMPLATE_INCONSISTENT;
2844 goto fail_cleanup;
2847 if (isValueLen) {
2849 * Templates for internal object creation come from
2850 * applications calls to C_DeriveKey(), for which it
2851 * is OKey to pass a CKA_VALUE_LEN attribute, as
2852 * long as it does not conflict with the length of the
2853 * CKA_VALUE attribute.
2855 if ((mode != SOFT_CREATE_OBJ_INT) ||
2856 ((key_len > 0) && sck->sk_value_len != key_len)) {
2857 rv = CKR_TEMPLATE_INCONSISTENT;
2858 goto fail_cleanup;
2861 break;
2863 case SOFT_GEN_KEY:
2864 /* CKA_VALUE must not be specified */
2865 if (isValue) {
2866 rv = CKR_TEMPLATE_INCONSISTENT;
2867 goto fail_cleanup;
2870 switch (keytype) {
2872 * CKA_VALUE_LEN must be specified by C_GenerateKey
2873 * if mech is CKK_RC4, CKK_AES, CKK_GENERIC_SECRET.
2875 case CKK_RC4:
2876 if (!isValueLen) {
2877 rv = CKR_TEMPLATE_INCOMPLETE;
2878 goto fail_cleanup;
2881 if ((sck->sk_value_len < ARCFOUR_MIN_KEY_BYTES) ||
2882 (sck->sk_value_len > ARCFOUR_MAX_KEY_BYTES)) {
2883 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2884 goto fail_cleanup;
2886 break;
2888 case CKK_GENERIC_SECRET:
2889 /* arbitrary key length - no length checking */
2890 if (!isValueLen) {
2891 rv = CKR_TEMPLATE_INCOMPLETE;
2892 goto fail_cleanup;
2894 break;
2896 case CKK_AES:
2897 if (!isValueLen) {
2898 rv = CKR_TEMPLATE_INCOMPLETE;
2899 goto fail_cleanup;
2902 if ((sck->sk_value_len != AES_MIN_KEY_BYTES) &&
2903 (sck->sk_value_len != AES_192_KEY_BYTES) &&
2904 (sck->sk_value_len != AES_MAX_KEY_BYTES)) {
2905 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2906 goto fail_cleanup;
2909 break;
2911 case CKK_BLOWFISH:
2912 if (!isValueLen) {
2913 rv = CKR_TEMPLATE_INCOMPLETE;
2914 goto fail_cleanup;
2916 if ((sck->sk_value_len < BLOWFISH_MINBYTES) ||
2917 (sck->sk_value_len > BLOWFISH_MAXBYTES)) {
2918 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2919 goto fail_cleanup;
2922 break;
2924 case CKK_DES:
2925 case CKK_DES2:
2926 case CKK_DES3:
2927 /* CKA_VALUE_LEN attribute does not apply to DES<n> */
2928 if (isValueLen) {
2929 rv = CKR_TEMPLATE_INCONSISTENT;
2930 goto fail_cleanup;
2932 break;
2934 default:
2935 rv = CKR_TEMPLATE_INCONSISTENT;
2936 goto fail_cleanup;
2938 break;
2940 case SOFT_UNWRAP_KEY:
2942 * According to v2.11 of PKCS#11 spec, neither CKA_VALUE nor
2943 * CKA_VALUE_LEN can be be specified; however v2.20 has this
2944 * restriction removed, perhaps because it makes it hard to
2945 * determine variable-length key sizes. This case statement
2946 * complied with v2.20.
2948 if (isValue) {
2949 rv = CKR_TEMPLATE_INCONSISTENT;
2950 goto fail_cleanup;
2953 switch (keytype) {
2955 * CKA_VALUE_LEN is optional
2956 * if key is CKK_RC4, CKK_AES, CKK_GENERIC_SECRET
2957 * and the unwrapping mech is *_CBC_PAD.
2959 * CKA_VALUE_LEN is required
2960 * if key is CKK_RC4, CKK_AES, CKK_GENERIC_SECRET
2961 * and the unwrapping mech is *_ECB or *_CBC.
2963 * since mech is not known at this point, CKA_VALUE_LEN is
2964 * treated as optional and the caller needs to enforce it.
2966 case CKK_RC4:
2967 if (isValueLen) {
2968 if ((sck->sk_value_len <
2969 ARCFOUR_MIN_KEY_BYTES) ||
2970 (sck->sk_value_len >
2971 ARCFOUR_MAX_KEY_BYTES)) {
2972 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2973 goto fail_cleanup;
2976 break;
2978 case CKK_GENERIC_SECRET:
2979 /* arbitrary key length - no length checking */
2980 break;
2982 case CKK_AES:
2983 if (isValueLen) {
2984 if ((sck->sk_value_len != AES_MIN_KEY_BYTES) &&
2985 (sck->sk_value_len != AES_192_KEY_BYTES) &&
2986 (sck->sk_value_len != AES_MAX_KEY_BYTES)) {
2987 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2988 goto fail_cleanup;
2991 break;
2993 case CKK_BLOWFISH:
2994 if (isValueLen &&
2995 ((sck->sk_value_len < BLOWFISH_MINBYTES) ||
2996 (sck->sk_value_len > BLOWFISH_MAXBYTES))) {
2997 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2998 goto fail_cleanup;
3000 break;
3002 case CKK_DES:
3003 case CKK_DES2:
3004 case CKK_DES3:
3005 /* CKA_VALUE_LEN attribute does not apply to DES<n> */
3006 if (isValueLen) {
3007 rv = CKR_TEMPLATE_INCONSISTENT;
3008 goto fail_cleanup;
3010 break;
3012 default:
3013 rv = CKR_TEMPLATE_INCONSISTENT;
3014 goto fail_cleanup;
3016 break;
3018 case SOFT_DERIVE_KEY_DH:
3019 /* CKA_VALUE must not be specified */
3020 if (isValue) {
3021 rv = CKR_TEMPLATE_INCONSISTENT;
3022 goto fail_cleanup;
3025 switch (keytype) {
3027 * CKA_VALUE_LEN is optional
3028 * if mech is CKK_RC4, CKK_AES, CKK_GENERIC_SECRET.
3030 case CKK_RC4:
3031 if (isValueLen) {
3032 if ((sck->sk_value_len <
3033 ARCFOUR_MIN_KEY_BYTES) ||
3034 (sck->sk_value_len >
3035 ARCFOUR_MAX_KEY_BYTES)) {
3036 rv = CKR_ATTRIBUTE_VALUE_INVALID;
3037 goto fail_cleanup;
3040 break;
3042 case CKK_GENERIC_SECRET:
3043 /* arbitrary key length - no length checking */
3044 break;
3046 case CKK_AES:
3047 if (isValueLen) {
3048 if ((sck->sk_value_len != AES_MIN_KEY_BYTES) &&
3049 (sck->sk_value_len != AES_192_KEY_BYTES) &&
3050 (sck->sk_value_len != AES_MAX_KEY_BYTES)) {
3051 rv = CKR_ATTRIBUTE_VALUE_INVALID;
3052 goto fail_cleanup;
3056 break;
3058 case CKK_BLOWFISH:
3059 if (isValueLen &&
3060 ((sck->sk_value_len < BLOWFISH_MINBYTES) ||
3061 (sck->sk_value_len > BLOWFISH_MAXBYTES))) {
3062 rv = CKR_ATTRIBUTE_VALUE_INVALID;
3063 goto fail_cleanup;
3065 break;
3067 case CKK_DES:
3068 case CKK_DES2:
3069 case CKK_DES3:
3070 /* CKA_VALUE_LEN attribute does not apply to DES<n> */
3071 if (isValueLen) {
3072 rv = CKR_TEMPLATE_INCONSISTENT;
3073 goto fail_cleanup;
3075 break;
3077 default:
3078 rv = CKR_TEMPLATE_INCONSISTENT;
3079 goto fail_cleanup;
3081 break;
3083 case SOFT_DERIVE_KEY_OTHER:
3084 /* CKA_VALUE must not be specified */
3085 if (isValue) {
3086 rv = CKR_TEMPLATE_INCONSISTENT;
3087 goto fail_cleanup;
3090 switch (keytype) {
3092 * CKA_VALUE_LEN is an optional attribute for
3093 * CKM_SHA1_KEY_DERIVATION and CKM_MD5_KEY_DERIVATION
3094 * if mech is CKK_RC4, CKK_AES, CKK_GENERIC_SECRET.
3096 case CKK_RC4:
3097 case CKK_GENERIC_SECRET:
3098 case CKK_AES:
3099 case CKK_BLOWFISH:
3101 * No need to check key length value here, it will be
3102 * validated later in soft_key_derive_check_length().
3104 break;
3106 case CKK_DES:
3107 case CKK_DES2:
3108 case CKK_DES3:
3109 /* CKA_VALUE_LEN attribute does not apply to DES<n> */
3110 if (isValueLen) {
3111 rv = CKR_TEMPLATE_INCONSISTENT;
3112 goto fail_cleanup;
3114 break;
3116 default:
3117 rv = CKR_TEMPLATE_INCONSISTENT;
3118 goto fail_cleanup;
3120 break;
3123 /* Set up object. */
3124 new_object->key_type = keytype;
3125 new_object->object_type = object_type;
3126 new_object->bool_attr_mask = attr_mask;
3127 if (isLabel) {
3128 rv = soft_add_extra_attr(&string_tmp, new_object);
3129 if (rv != CKR_OK)
3130 goto fail_cleanup;
3131 string_attr_cleanup(&string_tmp);
3133 return (rv);
3135 fail_cleanup:
3137 * cleanup the storage allocated to the local variables.
3139 bigint_attr_cleanup((biginteger_t *)sck);
3140 string_attr_cleanup(&string_tmp);
3143 * cleanup the storage allocated inside the object itself.
3145 soft_cleanup_object(new_object);
3147 return (rv);
3152 * Build a Domain Parameter Object.
3154 * - Parse the object's template, and when an error is detected such as
3155 * invalid attribute type, invalid attribute value, etc., return
3156 * with appropriate return value.
3157 * - Allocate storage for the Domain Parameter object.
3158 * - Build the Domain Parameter object according to the key type. Allocate
3159 * storage to hold the big integer value for the supplied attributes
3160 * that are required for a certain key type.
3163 CK_RV
3164 soft_build_domain_parameters_object(CK_ATTRIBUTE_PTR template,
3165 CK_ULONG ulAttrNum, soft_object_t *new_object)
3168 ulong_t i;
3169 CK_KEY_TYPE keytype = (CK_KEY_TYPE)~0UL;
3170 CK_RV rv = CKR_OK;
3171 int isLabel = 0;
3172 /* Must set flags */
3173 int isPrime = 0;
3174 int isSubprime = 0;
3175 int isBase = 0;
3176 /* Must not set flags */
3177 int isPrimeBits = 0;
3178 int isSubPrimeBits = 0;
3180 biginteger_t prime;
3181 biginteger_t subprime;
3182 biginteger_t base;
3183 CK_ATTRIBUTE string_tmp;
3185 domain_obj_t *dom;
3186 uchar_t object_type = 0;
3188 /* prevent bigint_attr_cleanup from freeing invalid attr value */
3189 (void) memset(&prime, 0x0, sizeof (biginteger_t));
3190 (void) memset(&subprime, 0x0, sizeof (biginteger_t));
3191 (void) memset(&base, 0x0, sizeof (biginteger_t));
3192 string_tmp.pValue = NULL;
3194 for (i = 0; i < ulAttrNum; i++) {
3196 /* Domain Parameters Object Attributes */
3197 switch (template[i].type) {
3199 /* common domain parameter attribute */
3200 case CKA_KEY_TYPE:
3201 keytype = *((CK_KEY_TYPE*)template[i].pValue);
3202 break;
3205 * The following common domain parameter attribute
3206 * must not be specified by C_CreateObject.
3208 case CKA_LOCAL:
3209 rv = CKR_TEMPLATE_INCONSISTENT;
3210 goto fail_cleanup;
3213 * The following domain parameter attributes must be
3214 * specified according to the key type by
3215 * C_CreateObject.
3217 case CKA_PRIME:
3218 isPrime = 1;
3220 * Copyin big integer attribute from template
3221 * to a local variable.
3223 rv = get_bigint_attr_from_template(&prime,
3224 &template[i]);
3225 if (rv != CKR_OK)
3226 goto fail_cleanup;
3227 break;
3229 case CKA_SUBPRIME:
3230 isSubprime = 1;
3231 rv = get_bigint_attr_from_template(&subprime,
3232 &template[i]);
3233 if (rv != CKR_OK)
3234 goto fail_cleanup;
3235 break;
3237 case CKA_BASE:
3238 isBase = 1;
3239 rv = get_bigint_attr_from_template(&base,
3240 &template[i]);
3241 if (rv != CKR_OK)
3242 goto fail_cleanup;
3243 break;
3245 case CKA_PRIME_BITS:
3246 isPrimeBits = 1;
3247 break;
3249 case CKA_SUB_PRIME_BITS:
3250 isSubPrimeBits = 1;
3251 break;
3253 case CKA_LABEL:
3254 isLabel = 1;
3255 rv = get_string_from_template(&string_tmp,
3256 &template[i]);
3257 if (rv != CKR_OK)
3258 goto fail_cleanup;
3259 break;
3261 default:
3262 rv = soft_parse_common_attrs(&template[i],
3263 &object_type);
3264 if (rv != CKR_OK)
3265 goto fail_cleanup;
3266 break;
3269 } /* For */
3271 /* Allocate storage for Domain Parameters Object. */
3272 dom = calloc(1, sizeof (domain_obj_t));
3273 if (dom == NULL) {
3274 rv = CKR_HOST_MEMORY;
3275 goto fail_cleanup;
3278 new_object->object_class_u.domain = dom;
3279 new_object->class = CKO_DOMAIN_PARAMETERS;
3281 if (keytype == (CK_KEY_TYPE)~0UL) {
3282 rv = CKR_TEMPLATE_INCOMPLETE;
3283 goto fail_cleanup;
3286 new_object->key_type = keytype;
3288 /* Supported key types of the Domain Parameters Object */
3289 switch (keytype) {
3290 case CKK_DSA:
3291 if (isPrimeBits || isSubPrimeBits) {
3292 rv = CKR_TEMPLATE_INCONSISTENT;
3293 goto fail_cleanup;
3296 if (isPrime && isSubprime && isBase) {
3298 * Copy big integer attribute value to the
3299 * designated place in the domain parameter
3300 * object.
3302 copy_bigint_attr(&prime, KEY_DOM_DSA_PRIME(dom));
3304 copy_bigint_attr(&subprime, KEY_DOM_DSA_SUBPRIME(dom));
3306 copy_bigint_attr(&base, KEY_DOM_DSA_BASE(dom));
3307 } else {
3308 rv = CKR_TEMPLATE_INCOMPLETE;
3309 goto fail_cleanup;
3311 break;
3313 case CKK_DH:
3314 if (isPrimeBits || isSubprime || isSubPrimeBits) {
3315 rv = CKR_TEMPLATE_INCONSISTENT;
3316 goto fail_cleanup;
3319 if (isPrime && isBase) {
3320 copy_bigint_attr(&prime, KEY_DOM_DH_PRIME(dom));
3322 copy_bigint_attr(&base, KEY_DOM_DH_BASE(dom));
3323 } else {
3324 rv = CKR_TEMPLATE_INCOMPLETE;
3325 goto fail_cleanup;
3327 break;
3329 case CKK_X9_42_DH:
3330 if (isPrimeBits || isSubPrimeBits) {
3331 rv = CKR_TEMPLATE_INCONSISTENT;
3332 goto fail_cleanup;
3335 if (isPrime && isSubprime && isBase) {
3336 copy_bigint_attr(&prime, KEY_DOM_DH942_PRIME(dom));
3338 copy_bigint_attr(&base, KEY_DOM_DH942_BASE(dom));
3340 copy_bigint_attr(&subprime,
3341 KEY_DOM_DH942_SUBPRIME(dom));
3342 } else {
3343 rv = CKR_TEMPLATE_INCOMPLETE;
3344 goto fail_cleanup;
3346 break;
3348 default:
3349 rv = CKR_TEMPLATE_INCONSISTENT;
3350 goto fail_cleanup;
3353 new_object->object_type = object_type;
3355 if (isLabel) {
3356 rv = soft_add_extra_attr(&string_tmp, new_object);
3357 if (rv != CKR_OK)
3358 goto fail_cleanup;
3359 string_attr_cleanup(&string_tmp);
3362 return (rv);
3364 fail_cleanup:
3366 * cleanup the storage allocated to the local variables.
3368 bigint_attr_cleanup(&prime);
3369 bigint_attr_cleanup(&subprime);
3370 bigint_attr_cleanup(&base);
3371 string_attr_cleanup(&string_tmp);
3374 * cleanup the storage allocated inside the object itself.
3376 soft_cleanup_object(new_object);
3378 return (rv);
3382 * Build a Certificate Object
3384 * - Parse the object's template, and when an error is detected such as
3385 * invalid attribute type, invalid attribute value, etc., return
3386 * with appropriate return value.
3387 * - Allocate storage for the Certificate object
3389 static CK_RV
3390 soft_build_certificate_object(CK_ATTRIBUTE_PTR template,
3391 CK_ULONG ulAttrNum, soft_object_t *new_object,
3392 CK_CERTIFICATE_TYPE cert_type)
3394 uint64_t attr_mask = 0;
3395 CK_RV rv = CKR_OK;
3396 CK_ULONG i;
3397 int owner_set = 0;
3398 int value_set = 0;
3399 int subject_set = 0;
3400 certificate_obj_t *cert;
3401 /* certificate type defaults to the value given as a parameter */
3402 CK_CERTIFICATE_TYPE certtype = cert_type;
3403 CK_ATTRIBUTE string_tmp;
3404 int isLabel = 0;
3405 uchar_t object_type = 0;
3408 * Look for the certificate type attribute and do some
3409 * sanity checking before creating the structures.
3411 for (i = 0; i < ulAttrNum; i++) {
3412 /* Certificate Object Attributes */
3413 switch (template[i].type) {
3414 case CKA_CERTIFICATE_TYPE:
3415 certtype =
3416 *((CK_CERTIFICATE_TYPE*)template[i].pValue);
3417 break;
3418 case CKA_SUBJECT:
3419 subject_set = 1;
3420 break;
3421 case CKA_OWNER:
3422 owner_set = 1;
3423 break;
3424 case CKA_VALUE:
3425 value_set = 1;
3426 break;
3430 /* The certificate type MUST be specified */
3431 if (certtype != CKC_X_509 && certtype != CKC_X_509_ATTR_CERT)
3432 return (CKR_TEMPLATE_INCOMPLETE);
3435 * For X.509 certs, the CKA_SUBJECT and CKA_VALUE
3436 * must be present at creation time.
3438 if (certtype == CKC_X_509 &&
3439 (!subject_set || !value_set))
3440 return (CKR_TEMPLATE_INCOMPLETE);
3443 * For X.509 Attribute certs, the CKA_OWNER and CKA_VALUE
3444 * must be present at creation time.
3446 if (certtype == CKC_X_509_ATTR_CERT &&
3447 (!owner_set || !value_set))
3448 return (CKR_TEMPLATE_INCOMPLETE);
3450 string_tmp.pValue = NULL;
3451 cert = calloc(1, sizeof (certificate_obj_t));
3452 if (cert == NULL) {
3453 return (CKR_HOST_MEMORY);
3455 cert->certificate_type = certtype;
3457 for (i = 0; i < ulAttrNum; i++) {
3458 /* Certificate Object Attributes */
3459 switch (certtype) {
3460 case CKC_X_509:
3461 switch (template[i].type) {
3462 case CKA_SUBJECT:
3463 rv = get_cert_attr_from_template(
3464 &cert->cert_type_u.x509.subject,
3465 &template[i]);
3466 break;
3467 case CKA_VALUE:
3468 rv = get_cert_attr_from_template(
3469 &cert->cert_type_u.x509.value,
3470 &template[i]);
3471 break;
3472 case CKA_LABEL:
3473 isLabel = 1;
3474 rv = get_string_from_template(
3475 &string_tmp,
3476 &template[i]);
3477 if (rv != CKR_OK)
3478 goto fail_cleanup;
3479 break;
3480 case CKA_ID:
3481 case CKA_ISSUER:
3482 case CKA_SERIAL_NUMBER:
3483 rv = soft_add_extra_attr(&template[i],
3484 new_object);
3485 break;
3486 case CKA_MODIFIABLE:
3487 if ((*(CK_BBOOL *)template[i].pValue) ==
3488 B_FALSE)
3489 attr_mask |=
3490 NOT_MODIFIABLE_BOOL_ON;
3491 break;
3492 case CKA_CERTIFICATE_TYPE:
3493 break;
3494 default:
3495 rv = soft_parse_common_attrs(
3496 &template[i], &object_type);
3497 if (rv != CKR_OK)
3498 goto fail_cleanup;
3500 break;
3501 case CKC_X_509_ATTR_CERT:
3502 switch (template[i].type) {
3503 case CKA_OWNER:
3504 rv = get_cert_attr_from_template(
3505 &cert->cert_type_u.x509_attr.owner,
3506 &template[i]);
3507 break;
3508 case CKA_VALUE:
3509 rv = get_cert_attr_from_template(
3510 &cert->cert_type_u.x509_attr.value,
3511 &template[i]);
3512 break;
3513 case CKA_LABEL:
3514 isLabel = 1;
3515 rv = get_string_from_template(
3516 &string_tmp, &template[i]);
3517 if (rv != CKR_OK)
3518 goto fail_cleanup;
3519 break;
3520 case CKA_SERIAL_NUMBER:
3521 case CKA_AC_ISSUER:
3522 case CKA_ATTR_TYPES:
3523 rv = soft_add_extra_attr(&template[i],
3524 new_object);
3525 break;
3527 case CKA_MODIFIABLE:
3528 if ((*(CK_BBOOL *)template[i].pValue) ==
3529 B_FALSE)
3530 attr_mask |=
3531 NOT_MODIFIABLE_BOOL_ON;
3532 break;
3533 case CKA_CERTIFICATE_TYPE:
3534 break;
3535 default:
3536 rv = soft_parse_common_attrs(
3537 &template[i], &object_type);
3538 if (rv != CKR_OK)
3539 goto fail_cleanup;
3540 break;
3542 break;
3543 default:
3544 rv = CKR_TEMPLATE_INCOMPLETE;
3545 break;
3549 if (rv == CKR_OK) {
3550 new_object->object_class_u.certificate = cert;
3551 new_object->class = CKO_CERTIFICATE;
3552 new_object->object_type = object_type;
3553 new_object->cert_type = certtype;
3554 new_object->bool_attr_mask = attr_mask;
3555 if (isLabel) {
3556 rv = soft_add_extra_attr(&string_tmp, new_object);
3557 if (rv != CKR_OK)
3558 goto fail_cleanup;
3559 string_attr_cleanup(&string_tmp);
3563 fail_cleanup:
3564 if (rv != CKR_OK) {
3565 soft_cleanup_cert_object(new_object);
3567 return (rv);
3572 * Validate the attribute types in the object's template. Then,
3573 * call the appropriate build function according to the class of
3574 * the object specified in the template.
3576 * Note: The following classes of objects are supported:
3577 * - CKO_PUBLIC_KEY
3578 * - CKO_PRIVATE_KEY
3579 * - CKO_SECRET_KEY
3580 * - CKO_DOMAIN_PARAMETERS
3581 * - CKO_CERTIFICATE
3584 CK_RV
3585 soft_build_object(CK_ATTRIBUTE_PTR template, CK_ULONG ulAttrNum,
3586 soft_object_t *new_object)
3589 CK_OBJECT_CLASS class = (CK_OBJECT_CLASS)~0UL;
3590 CK_RV rv = CKR_OK;
3592 if (template == NULL) {
3593 return (CKR_ARGUMENTS_BAD);
3596 /* Validate the attribute type in the template. */
3597 rv = soft_validate_attr(template, ulAttrNum, &class);
3598 if (rv != CKR_OK)
3599 return (rv);
3601 * CKA_CLASS is a mandatory attribute for C_CreateObject
3603 if (class == (CK_OBJECT_CLASS)~0UL)
3604 return (CKR_TEMPLATE_INCOMPLETE);
3607 * Call the appropriate function based on the supported class
3608 * of the object.
3610 switch (class) {
3611 case CKO_PUBLIC_KEY:
3612 rv = soft_build_public_key_object(template, ulAttrNum,
3613 new_object, SOFT_CREATE_OBJ, (CK_KEY_TYPE)~0UL);
3614 break;
3616 case CKO_PRIVATE_KEY:
3617 rv = soft_build_private_key_object(template, ulAttrNum,
3618 new_object, SOFT_CREATE_OBJ, (CK_KEY_TYPE)~0UL);
3619 break;
3621 case CKO_SECRET_KEY:
3622 rv = soft_build_secret_key_object(template, ulAttrNum,
3623 new_object, SOFT_CREATE_OBJ, 0, (CK_KEY_TYPE)~0UL);
3624 break;
3626 case CKO_DOMAIN_PARAMETERS:
3627 rv = soft_build_domain_parameters_object(template, ulAttrNum,
3628 new_object);
3629 break;
3631 case CKO_CERTIFICATE:
3632 rv = soft_build_certificate_object(template, ulAttrNum,
3633 new_object, (CK_CERTIFICATE_TYPE)~0UL);
3634 break;
3636 case CKO_DATA:
3637 case CKO_HW_FEATURE:
3638 case CKO_VENDOR_DEFINED:
3639 default:
3640 return (CKR_ATTRIBUTE_VALUE_INVALID);
3643 return (rv);
3647 * Validate the attribute types in the object's template. Then,
3648 * call the appropriate build function according to the class of
3649 * the object specified in the template.
3652 CK_RV
3653 soft_build_key(CK_ATTRIBUTE_PTR template, CK_ULONG ulAttrNum,
3654 soft_object_t *new_object, CK_OBJECT_CLASS class, CK_KEY_TYPE key_type,
3655 CK_ULONG key_len, CK_ULONG mode)
3658 CK_RV rv = CKR_OK;
3659 CK_OBJECT_CLASS temp_class = (CK_OBJECT_CLASS)~0UL;
3661 /* Validate the attribute type in the template. */
3662 if ((template != NULL) && (ulAttrNum != 0)) {
3663 rv = soft_validate_attr(template, ulAttrNum, &temp_class);
3664 if (rv != CKR_OK)
3665 return (rv);
3669 * If either the class from the parameter list ("class") or
3670 * the class from the template ("temp_class") is not specified,
3671 * try to use the other one.
3673 if (temp_class == (CK_OBJECT_CLASS)~0UL) {
3674 temp_class = class;
3675 } else if (class == (CK_OBJECT_CLASS)~0UL) {
3676 class = temp_class;
3679 /* If object class is still not specified, template is incomplete. */
3680 if (class == (CK_OBJECT_CLASS)~0UL)
3681 return (CKR_TEMPLATE_INCOMPLETE);
3683 /* Class should match if specified in both parameters and template. */
3684 if (class != temp_class)
3685 return (CKR_TEMPLATE_INCONSISTENT);
3688 * Call the appropriate function based on the supported class
3689 * of the object.
3691 switch (class) {
3692 case CKO_PUBLIC_KEY:
3694 /* Unwrapping public keys is not supported. */
3695 if (mode == SOFT_UNWRAP_KEY) {
3696 rv = CKR_ATTRIBUTE_VALUE_INVALID;
3697 break;
3700 rv = soft_build_public_key_object(template, ulAttrNum,
3701 new_object, mode, key_type);
3702 break;
3704 case CKO_PRIVATE_KEY:
3706 rv = soft_build_private_key_object(template, ulAttrNum,
3707 new_object, mode, key_type);
3708 break;
3710 case CKO_SECRET_KEY:
3712 rv = soft_build_secret_key_object(template, ulAttrNum,
3713 new_object, mode, key_len, key_type);
3714 break;
3716 case CKO_DOMAIN_PARAMETERS:
3718 /* Unwrapping domain parameters is not supported. */
3719 if (mode == SOFT_UNWRAP_KEY) {
3720 rv = CKR_ATTRIBUTE_VALUE_INVALID;
3721 break;
3724 rv = soft_build_domain_parameters_object(template, ulAttrNum,
3725 new_object);
3726 break;
3728 case CKO_DATA:
3729 case CKO_CERTIFICATE:
3730 case CKO_HW_FEATURE:
3731 case CKO_VENDOR_DEFINED:
3732 default:
3733 return (CKR_ATTRIBUTE_VALUE_INVALID);
3736 return (rv);
3741 * Get the value of a requested attribute that is common to all supported
3742 * classes (i.e. public key, private key, secret key, domain parameters,
3743 * and certificate classes).
3745 CK_RV
3746 soft_get_common_attrs(soft_object_t *object_p, CK_ATTRIBUTE_PTR template,
3747 uchar_t object_type)
3750 CK_RV rv = CKR_OK;
3752 switch (template->type) {
3754 case CKA_CLASS:
3755 return (get_ulong_attr_from_object(object_p->class,
3756 template));
3758 /* default boolean attributes */
3759 case CKA_TOKEN:
3760 template->ulValueLen = sizeof (CK_BBOOL);
3761 if (template->pValue == NULL) {
3762 return (CKR_OK);
3764 if (object_type & TOKEN_OBJECT)
3765 *((CK_BBOOL *)template->pValue) = B_TRUE;
3766 else
3767 *((CK_BBOOL *)template->pValue) = B_FALSE;
3768 break;
3770 case CKA_PRIVATE:
3772 template->ulValueLen = sizeof (CK_BBOOL);
3773 if (template->pValue == NULL) {
3774 return (CKR_OK);
3776 if (object_type & PRIVATE_OBJECT)
3777 *((CK_BBOOL *)template->pValue) = B_TRUE;
3778 else
3779 *((CK_BBOOL *)template->pValue) = B_FALSE;
3780 break;
3782 case CKA_MODIFIABLE:
3783 template->ulValueLen = sizeof (CK_BBOOL);
3784 if (template->pValue == NULL) {
3785 return (CKR_OK);
3787 if ((object_p->bool_attr_mask) & NOT_MODIFIABLE_BOOL_ON)
3788 *((CK_BBOOL *)template->pValue) = B_FALSE;
3789 else
3790 *((CK_BBOOL *)template->pValue) = B_TRUE;
3791 break;
3793 case CKA_LABEL:
3794 return (get_extra_attr_from_object(object_p,
3795 template));
3797 default:
3799 * The specified attribute for the object is invalid.
3800 * (the object does not possess such an attribute.)
3802 template->ulValueLen = (CK_ULONG)-1;
3803 return (CKR_ATTRIBUTE_TYPE_INVALID);
3806 return (rv);
3810 * Get the value of a requested attribute that is common to all key objects
3811 * (i.e. public key, private key and secret key).
3813 CK_RV
3814 soft_get_common_key_attrs(soft_object_t *object_p, CK_ATTRIBUTE_PTR template)
3817 switch (template->type) {
3819 case CKA_KEY_TYPE:
3820 return (get_ulong_attr_from_object(object_p->key_type,
3821 template));
3823 case CKA_ID:
3824 case CKA_START_DATE:
3825 case CKA_END_DATE:
3827 * The above extra attributes have byte array type.
3829 return (get_extra_attr_from_object(object_p,
3830 template));
3832 /* Key related boolean attributes */
3833 case CKA_LOCAL:
3834 return (get_bool_attr_from_object(object_p,
3835 LOCAL_BOOL_ON, template));
3837 case CKA_DERIVE:
3838 return (get_bool_attr_from_object(object_p,
3839 DERIVE_BOOL_ON, template));
3841 case CKA_KEY_GEN_MECHANISM:
3842 return (get_ulong_attr_from_object(object_p->mechanism,
3843 template));
3845 default:
3846 return (CKR_ATTRIBUTE_TYPE_INVALID);
3851 * Get the value of a requested attribute of a Public Key Object.
3853 * Rule: All the attributes in the public key object can be revealed.
3855 CK_RV
3856 soft_get_public_key_attribute(soft_object_t *object_p,
3857 CK_ATTRIBUTE_PTR template)
3860 CK_RV rv = CKR_OK;
3861 CK_KEY_TYPE keytype = object_p->key_type;
3863 switch (template->type) {
3865 case CKA_SUBJECT:
3866 case CKA_EC_PARAMS:
3868 * The above extra attributes have byte array type.
3870 return (get_extra_attr_from_object(object_p,
3871 template));
3873 /* Key related boolean attributes */
3874 case CKA_ENCRYPT:
3875 return (get_bool_attr_from_object(object_p,
3876 ENCRYPT_BOOL_ON, template));
3878 case CKA_VERIFY:
3879 return (get_bool_attr_from_object(object_p,
3880 VERIFY_BOOL_ON, template));
3882 case CKA_VERIFY_RECOVER:
3883 return (get_bool_attr_from_object(object_p,
3884 VERIFY_RECOVER_BOOL_ON, template));
3886 case CKA_WRAP:
3887 return (get_bool_attr_from_object(object_p,
3888 WRAP_BOOL_ON, template));
3890 case CKA_TRUSTED:
3891 return (get_bool_attr_from_object(object_p,
3892 TRUSTED_BOOL_ON, template));
3894 case CKA_MODULUS:
3896 * This attribute is valid only for RSA public key
3897 * object.
3899 if (keytype == CKK_RSA) {
3900 return (get_bigint_attr_from_object(
3901 OBJ_PUB_RSA_MOD(object_p), template));
3902 } else {
3903 template->ulValueLen = (CK_ULONG)-1;
3904 return (CKR_ATTRIBUTE_TYPE_INVALID);
3907 case CKA_PUBLIC_EXPONENT:
3908 if (keytype == CKK_RSA) {
3909 return (get_bigint_attr_from_object(
3910 OBJ_PUB_RSA_PUBEXPO(object_p), template));
3911 } else {
3912 template->ulValueLen = (CK_ULONG)-1;
3913 return (CKR_ATTRIBUTE_TYPE_INVALID);
3916 case CKA_MODULUS_BITS:
3917 if (keytype == CKK_RSA) {
3918 return (get_ulong_attr_from_object(
3919 OBJ_PUB_RSA_MOD_BITS(object_p), template));
3920 } else {
3921 template->ulValueLen = (CK_ULONG)-1;
3922 return (CKR_ATTRIBUTE_TYPE_INVALID);
3925 case CKA_PRIME:
3926 switch (keytype) {
3927 case CKK_DSA:
3928 return (get_bigint_attr_from_object(
3929 OBJ_PUB_DSA_PRIME(object_p), template));
3931 case CKK_DH:
3932 return (get_bigint_attr_from_object(
3933 OBJ_PUB_DH_PRIME(object_p), template));
3935 case CKK_X9_42_DH:
3936 return (get_bigint_attr_from_object(
3937 OBJ_PUB_DH942_PRIME(object_p), template));
3939 default:
3940 template->ulValueLen = (CK_ULONG)-1;
3941 return (CKR_ATTRIBUTE_TYPE_INVALID);
3944 case CKA_SUBPRIME:
3945 switch (keytype) {
3946 case CKK_DSA:
3947 return (get_bigint_attr_from_object(
3948 OBJ_PUB_DSA_SUBPRIME(object_p), template));
3950 case CKK_X9_42_DH:
3951 return (get_bigint_attr_from_object(
3952 OBJ_PUB_DH942_SUBPRIME(object_p), template));
3954 default:
3955 template->ulValueLen = (CK_ULONG)-1;
3956 return (CKR_ATTRIBUTE_TYPE_INVALID);
3959 case CKA_BASE:
3960 switch (keytype) {
3961 case CKK_DSA:
3962 return (get_bigint_attr_from_object(
3963 OBJ_PUB_DSA_BASE(object_p), template));
3965 case CKK_DH:
3966 return (get_bigint_attr_from_object(
3967 OBJ_PUB_DH_BASE(object_p), template));
3969 case CKK_X9_42_DH:
3970 return (get_bigint_attr_from_object(
3971 OBJ_PUB_DH942_BASE(object_p), template));
3973 default:
3974 template->ulValueLen = (CK_ULONG)-1;
3975 return (CKR_ATTRIBUTE_TYPE_INVALID);
3978 case CKA_EC_POINT:
3979 return (get_bigint_attr_from_object(
3980 OBJ_PUB_EC_POINT(object_p), template));
3982 case CKA_VALUE:
3983 switch (keytype) {
3984 case CKK_DSA:
3985 return (get_bigint_attr_from_object(
3986 OBJ_PUB_DSA_VALUE(object_p), template));
3988 case CKK_DH:
3989 return (get_bigint_attr_from_object(
3990 OBJ_PUB_DH_VALUE(object_p), template));
3992 case CKK_X9_42_DH:
3993 return (get_bigint_attr_from_object(
3994 OBJ_PUB_DH942_VALUE(object_p), template));
3996 default:
3997 template->ulValueLen = (CK_ULONG)-1;
3998 return (CKR_ATTRIBUTE_TYPE_INVALID);
4001 default:
4003 * First, get the value of the request attribute defined
4004 * in the list of common key attributes. If the request
4005 * attribute is not found in that list, then get the
4006 * attribute from the list of common attributes.
4008 rv = soft_get_common_key_attrs(object_p, template);
4009 if (rv == CKR_ATTRIBUTE_TYPE_INVALID) {
4010 rv = soft_get_common_attrs(object_p, template,
4011 object_p->object_type);
4013 break;
4016 return (rv);
4021 * Get the value of a requested attribute of a Private Key Object.
4023 * Rule: All the attributes in the private key object can be revealed
4024 * except those marked with footnote number "7" when the object
4025 * has its CKA_SENSITIVE attribute set to TRUE or its
4026 * CKA_EXTRACTABLE attribute set to FALSE (p.88 in PKCS11 spec.).
4028 CK_RV
4029 soft_get_private_key_attribute(soft_object_t *object_p,
4030 CK_ATTRIBUTE_PTR template)
4033 CK_RV rv = CKR_OK;
4034 CK_KEY_TYPE keytype = object_p->key_type;
4038 * If the following specified attributes for the private key
4039 * object cannot be revealed because the object is sensitive
4040 * or unextractable, then the ulValueLen is set to -1.
4042 if ((object_p->bool_attr_mask & SENSITIVE_BOOL_ON) ||
4043 !(object_p->bool_attr_mask & EXTRACTABLE_BOOL_ON)) {
4045 switch (template->type) {
4046 case CKA_PRIVATE_EXPONENT:
4047 case CKA_PRIME_1:
4048 case CKA_PRIME_2:
4049 case CKA_EXPONENT_1:
4050 case CKA_EXPONENT_2:
4051 case CKA_COEFFICIENT:
4052 case CKA_VALUE:
4053 template->ulValueLen = (CK_ULONG)-1;
4054 return (CKR_ATTRIBUTE_SENSITIVE);
4058 switch (template->type) {
4060 case CKA_SUBJECT:
4061 case CKA_EC_PARAMS:
4063 * The above extra attributes have byte array type.
4065 return (get_extra_attr_from_object(object_p,
4066 template));
4068 /* Key related boolean attributes */
4069 case CKA_SENSITIVE:
4070 return (get_bool_attr_from_object(object_p,
4071 SENSITIVE_BOOL_ON, template));
4073 case CKA_SECONDARY_AUTH:
4074 return (get_bool_attr_from_object(object_p,
4075 SECONDARY_AUTH_BOOL_ON, template));
4077 case CKA_DECRYPT:
4078 return (get_bool_attr_from_object(object_p,
4079 DECRYPT_BOOL_ON, template));
4081 case CKA_SIGN:
4082 return (get_bool_attr_from_object(object_p,
4083 SIGN_BOOL_ON, template));
4085 case CKA_SIGN_RECOVER:
4086 return (get_bool_attr_from_object(object_p,
4087 SIGN_RECOVER_BOOL_ON, template));
4089 case CKA_UNWRAP:
4090 return (get_bool_attr_from_object(object_p,
4091 UNWRAP_BOOL_ON, template));
4093 case CKA_EXTRACTABLE:
4094 return (get_bool_attr_from_object(object_p,
4095 EXTRACTABLE_BOOL_ON, template));
4097 case CKA_ALWAYS_SENSITIVE:
4098 return (get_bool_attr_from_object(object_p,
4099 ALWAYS_SENSITIVE_BOOL_ON, template));
4101 case CKA_NEVER_EXTRACTABLE:
4102 return (get_bool_attr_from_object(object_p,
4103 NEVER_EXTRACTABLE_BOOL_ON, template));
4105 case CKA_MODULUS:
4106 if (keytype == CKK_RSA) {
4107 return (get_bigint_attr_from_object(
4108 OBJ_PRI_RSA_MOD(object_p), template));
4109 } else {
4110 template->ulValueLen = (CK_ULONG)-1;
4111 rv = CKR_ATTRIBUTE_TYPE_INVALID;
4112 break;
4115 case CKA_PUBLIC_EXPONENT:
4116 if (keytype == CKK_RSA) {
4117 return (get_bigint_attr_from_object(
4118 OBJ_PRI_RSA_PUBEXPO(object_p), template));
4119 } else {
4120 template->ulValueLen = (CK_ULONG)-1;
4121 rv = CKR_ATTRIBUTE_TYPE_INVALID;
4122 break;
4125 case CKA_PRIVATE_EXPONENT:
4126 if (keytype == CKK_RSA) {
4127 return (get_bigint_attr_from_object(
4128 OBJ_PRI_RSA_PRIEXPO(object_p), template));
4129 } else {
4130 template->ulValueLen = (CK_ULONG)-1;
4131 rv = CKR_ATTRIBUTE_TYPE_INVALID;
4132 break;
4135 case CKA_PRIME_1:
4136 if (keytype == CKK_RSA) {
4137 return (get_bigint_attr_from_object(
4138 OBJ_PRI_RSA_PRIME1(object_p), template));
4139 } else {
4140 template->ulValueLen = (CK_ULONG)-1;
4141 rv = CKR_ATTRIBUTE_TYPE_INVALID;
4142 break;
4145 case CKA_PRIME_2:
4146 if (keytype == CKK_RSA) {
4147 return (get_bigint_attr_from_object(
4148 OBJ_PRI_RSA_PRIME2(object_p), template));
4149 } else {
4150 template->ulValueLen = (CK_ULONG)-1;
4151 rv = CKR_ATTRIBUTE_TYPE_INVALID;
4152 break;
4155 case CKA_EXPONENT_1:
4156 if (keytype == CKK_RSA) {
4157 return (get_bigint_attr_from_object(
4158 OBJ_PRI_RSA_EXPO1(object_p), template));
4159 } else {
4160 template->ulValueLen = (CK_ULONG)-1;
4161 rv = CKR_ATTRIBUTE_TYPE_INVALID;
4162 break;
4165 case CKA_EXPONENT_2:
4166 if (keytype == CKK_RSA) {
4167 return (get_bigint_attr_from_object(
4168 OBJ_PRI_RSA_EXPO2(object_p), template));
4169 } else {
4170 template->ulValueLen = (CK_ULONG)-1;
4171 rv = CKR_ATTRIBUTE_TYPE_INVALID;
4172 break;
4175 case CKA_COEFFICIENT:
4176 if (keytype == CKK_RSA) {
4177 return (get_bigint_attr_from_object(
4178 OBJ_PRI_RSA_COEF(object_p), template));
4179 } else {
4180 template->ulValueLen = (CK_ULONG)-1;
4181 rv = CKR_ATTRIBUTE_TYPE_INVALID;
4182 break;
4185 case CKA_VALUE_BITS:
4186 if (keytype == CKK_DH) {
4187 return (get_ulong_attr_from_object(
4188 OBJ_PRI_DH_VAL_BITS(object_p), template));
4189 } else {
4190 template->ulValueLen = (CK_ULONG)-1;
4191 rv = CKR_ATTRIBUTE_TYPE_INVALID;
4192 break;
4195 case CKA_PRIME:
4196 switch (keytype) {
4197 case CKK_DSA:
4198 return (get_bigint_attr_from_object(
4199 OBJ_PRI_DSA_PRIME(object_p), template));
4201 case CKK_DH:
4202 return (get_bigint_attr_from_object(
4203 OBJ_PRI_DH_PRIME(object_p), template));
4205 case CKK_X9_42_DH:
4206 return (get_bigint_attr_from_object(
4207 OBJ_PRI_DH942_PRIME(object_p), template));
4209 default:
4210 template->ulValueLen = (CK_ULONG)-1;
4211 return (CKR_ATTRIBUTE_TYPE_INVALID);
4214 case CKA_SUBPRIME:
4215 switch (keytype) {
4216 case CKK_DSA:
4217 return (get_bigint_attr_from_object(
4218 OBJ_PRI_DSA_SUBPRIME(object_p), template));
4220 case CKK_X9_42_DH:
4221 return (get_bigint_attr_from_object(
4222 OBJ_PRI_DH942_SUBPRIME(object_p), template));
4224 default:
4225 template->ulValueLen = (CK_ULONG)-1;
4226 return (CKR_ATTRIBUTE_TYPE_INVALID);
4229 case CKA_BASE:
4230 switch (keytype) {
4231 case CKK_DSA:
4232 return (get_bigint_attr_from_object(
4233 OBJ_PRI_DSA_BASE(object_p), template));
4235 case CKK_DH:
4236 return (get_bigint_attr_from_object(
4237 OBJ_PRI_DH_BASE(object_p), template));
4239 case CKK_X9_42_DH:
4240 return (get_bigint_attr_from_object(
4241 OBJ_PRI_DH942_BASE(object_p), template));
4243 default:
4244 template->ulValueLen = (CK_ULONG)-1;
4245 return (CKR_ATTRIBUTE_TYPE_INVALID);
4248 case CKA_VALUE:
4249 switch (keytype) {
4250 case CKK_DSA:
4251 return (get_bigint_attr_from_object(
4252 OBJ_PRI_DSA_VALUE(object_p), template));
4254 case CKK_DH:
4255 return (get_bigint_attr_from_object(
4256 OBJ_PRI_DH_VALUE(object_p), template));
4258 case CKK_X9_42_DH:
4259 return (get_bigint_attr_from_object(
4260 OBJ_PRI_DH942_VALUE(object_p), template));
4262 case CKK_EC:
4263 return (get_bigint_attr_from_object(
4264 OBJ_PRI_EC_VALUE(object_p), template));
4266 default:
4267 template->ulValueLen = (CK_ULONG)-1;
4268 return (CKR_ATTRIBUTE_TYPE_INVALID);
4271 default:
4273 * First, get the value of the request attribute defined
4274 * in the list of common key attributes. If the request
4275 * attribute is not found in that list, then get the
4276 * attribute from the list of common attributes.
4278 rv = soft_get_common_key_attrs(object_p, template);
4279 if (rv == CKR_ATTRIBUTE_TYPE_INVALID) {
4280 rv = soft_get_common_attrs(object_p, template,
4281 object_p->object_type);
4283 break;
4286 return (rv);
4291 * Get the value of a requested attribute of a Secret Key Object.
4293 * Rule: All the attributes in the secret key object can be revealed
4294 * except those marked with footnote number "7" when the object
4295 * has its CKA_SENSITIVE attribute set to TRUE or its
4296 * CKA_EXTRACTABLE attribute set to FALSE (p.88 in PKCS11 spec.).
4298 CK_RV
4299 soft_get_secret_key_attribute(soft_object_t *object_p,
4300 CK_ATTRIBUTE_PTR template)
4303 CK_RV rv = CKR_OK;
4304 CK_KEY_TYPE keytype = object_p->key_type;
4306 switch (template->type) {
4308 /* Key related boolean attributes */
4309 case CKA_SENSITIVE:
4310 return (get_bool_attr_from_object(object_p,
4311 SENSITIVE_BOOL_ON, template));
4313 case CKA_ENCRYPT:
4314 return (get_bool_attr_from_object(object_p,
4315 ENCRYPT_BOOL_ON, template));
4317 case CKA_DECRYPT:
4318 return (get_bool_attr_from_object(object_p,
4319 DECRYPT_BOOL_ON, template));
4321 case CKA_SIGN:
4322 return (get_bool_attr_from_object(object_p,
4323 SIGN_BOOL_ON, template));
4325 case CKA_VERIFY:
4326 return (get_bool_attr_from_object(object_p,
4327 VERIFY_BOOL_ON, template));
4329 case CKA_WRAP:
4330 return (get_bool_attr_from_object(object_p,
4331 WRAP_BOOL_ON, template));
4333 case CKA_UNWRAP:
4334 return (get_bool_attr_from_object(object_p,
4335 UNWRAP_BOOL_ON, template));
4337 case CKA_EXTRACTABLE:
4338 return (get_bool_attr_from_object(object_p,
4339 EXTRACTABLE_BOOL_ON, template));
4341 case CKA_ALWAYS_SENSITIVE:
4342 return (get_bool_attr_from_object(object_p,
4343 ALWAYS_SENSITIVE_BOOL_ON, template));
4345 case CKA_NEVER_EXTRACTABLE:
4346 return (get_bool_attr_from_object(object_p,
4347 NEVER_EXTRACTABLE_BOOL_ON, template));
4349 case CKA_VALUE:
4350 case CKA_VALUE_LEN:
4352 * If the specified attribute for the secret key object
4353 * cannot be revealed because the object is sensitive
4354 * or unextractable, then the ulValueLen is set to -1.
4356 if ((object_p->bool_attr_mask & SENSITIVE_BOOL_ON) ||
4357 !(object_p->bool_attr_mask & EXTRACTABLE_BOOL_ON)) {
4358 template->ulValueLen = (CK_ULONG)-1;
4359 return (CKR_ATTRIBUTE_SENSITIVE);
4362 switch (keytype) {
4363 case CKK_RC4:
4364 case CKK_GENERIC_SECRET:
4365 case CKK_RC5:
4366 case CKK_DES:
4367 case CKK_DES2:
4368 case CKK_DES3:
4369 case CKK_CDMF:
4370 case CKK_AES:
4371 case CKK_BLOWFISH:
4372 if (template->type == CKA_VALUE_LEN) {
4373 return (get_ulong_attr_from_object(
4374 OBJ_SEC_VALUE_LEN(object_p),
4375 template));
4376 } else {
4377 return (get_bigint_attr_from_object(
4378 (biginteger_t *)OBJ_SEC(object_p),
4379 template));
4381 default:
4382 template->ulValueLen = (CK_ULONG)-1;
4383 rv = CKR_ATTRIBUTE_TYPE_INVALID;
4384 break;
4386 break;
4388 default:
4390 * First, get the value of the request attribute defined
4391 * in the list of common key attributes. If the request
4392 * attribute is not found in that list, then get the
4393 * attribute from the list of common attributes.
4395 rv = soft_get_common_key_attrs(object_p, template);
4396 if (rv == CKR_ATTRIBUTE_TYPE_INVALID) {
4397 rv = soft_get_common_attrs(object_p, template,
4398 object_p->object_type);
4400 break;
4403 return (rv);
4408 * Get the value of a requested attribute of a Domain Parameters Object.
4410 * Rule: All the attributes in the domain parameters object can be revealed.
4412 CK_RV
4413 soft_get_domain_parameters_attribute(soft_object_t *object_p,
4414 CK_ATTRIBUTE_PTR template)
4417 CK_RV rv = CKR_OK;
4418 CK_KEY_TYPE keytype = object_p->key_type;
4420 switch (template->type) {
4422 case CKA_KEY_TYPE:
4423 return (get_ulong_attr_from_object(keytype,
4424 template));
4426 case CKA_LOCAL:
4427 return (get_bool_attr_from_object(object_p,
4428 LOCAL_BOOL_ON, template));
4430 case CKA_PRIME:
4431 switch (keytype) {
4432 case CKK_DSA:
4433 return (get_bigint_attr_from_object(
4434 OBJ_DOM_DSA_PRIME(object_p), template));
4436 case CKK_DH:
4437 return (get_bigint_attr_from_object(
4438 OBJ_DOM_DH_PRIME(object_p), template));
4440 case CKK_X9_42_DH:
4441 return (get_bigint_attr_from_object(
4442 OBJ_DOM_DH942_PRIME(object_p), template));
4444 default:
4445 template->ulValueLen = (CK_ULONG)-1;
4446 return (CKR_ATTRIBUTE_TYPE_INVALID);
4449 case CKA_SUBPRIME:
4450 switch (keytype) {
4451 case CKK_DSA:
4452 return (get_bigint_attr_from_object(
4453 OBJ_DOM_DSA_SUBPRIME(object_p), template));
4455 case CKK_X9_42_DH:
4456 return (get_bigint_attr_from_object(
4457 OBJ_DOM_DH942_SUBPRIME(object_p), template));
4459 default:
4460 template->ulValueLen = (CK_ULONG)-1;
4461 return (CKR_ATTRIBUTE_TYPE_INVALID);
4464 case CKA_BASE:
4465 switch (keytype) {
4466 case CKK_DSA:
4467 return (get_bigint_attr_from_object(
4468 OBJ_DOM_DSA_BASE(object_p), template));
4470 case CKK_DH:
4471 return (get_bigint_attr_from_object(
4472 OBJ_DOM_DH_BASE(object_p), template));
4474 case CKK_X9_42_DH:
4475 return (get_bigint_attr_from_object(
4476 OBJ_DOM_DH942_BASE(object_p), template));
4478 default:
4479 template->ulValueLen = (CK_ULONG)-1;
4480 return (CKR_ATTRIBUTE_TYPE_INVALID);
4483 case CKA_PRIME_BITS:
4484 switch (keytype) {
4485 case CKK_DSA:
4486 return (get_ulong_attr_from_object(
4487 OBJ_DOM_DSA_PRIME_BITS(object_p), template));
4489 case CKK_DH:
4490 return (get_ulong_attr_from_object(
4491 OBJ_DOM_DH_PRIME_BITS(object_p), template));
4493 case CKK_X9_42_DH:
4494 return (get_ulong_attr_from_object(
4495 OBJ_DOM_DH942_PRIME_BITS(object_p), template));
4497 default:
4498 template->ulValueLen = (CK_ULONG)-1;
4499 return (CKR_ATTRIBUTE_TYPE_INVALID);
4502 case CKA_SUB_PRIME_BITS:
4503 switch (keytype) {
4504 case CKK_X9_42_DH:
4505 return (get_ulong_attr_from_object(
4506 OBJ_DOM_DH942_SUBPRIME_BITS(object_p), template));
4508 default:
4509 template->ulValueLen = (CK_ULONG)-1;
4510 return (CKR_ATTRIBUTE_TYPE_INVALID);
4513 default:
4515 * Get the value of a common attribute.
4517 rv = soft_get_common_attrs(object_p, template,
4518 object_p->object_type);
4519 break;
4522 return (rv);
4526 * Get certificate attributes from an object.
4527 * return CKR_ATTRIBUTE_TYPE_INVALID if the requested type
4528 * does not exist in the certificate.
4530 CK_RV
4531 soft_get_certificate_attribute(soft_object_t *object_p,
4532 CK_ATTRIBUTE_PTR template)
4534 CK_CERTIFICATE_TYPE certtype = object_p->cert_type;
4535 cert_attr_t src;
4537 switch (template->type) {
4538 case CKA_SUBJECT:
4539 if (certtype == CKC_X_509) {
4540 return (get_cert_attr_from_object(
4541 X509_CERT_SUBJECT(object_p), template));
4543 break;
4544 case CKA_VALUE:
4545 if (certtype == CKC_X_509) {
4546 return (get_cert_attr_from_object(
4547 X509_CERT_VALUE(object_p), template));
4548 } else if (certtype == CKC_X_509_ATTR_CERT) {
4549 return (get_cert_attr_from_object(
4550 X509_ATTR_CERT_VALUE(object_p), template));
4552 break;
4553 case CKA_OWNER:
4554 if (certtype == CKC_X_509_ATTR_CERT) {
4555 return (get_cert_attr_from_object(
4556 X509_ATTR_CERT_OWNER(object_p), template));
4558 break;
4559 case CKA_CERTIFICATE_TYPE:
4560 src.value = (CK_BYTE *)&certtype;
4561 src.length = sizeof (certtype);
4562 return (get_cert_attr_from_object(&src, template));
4563 case CKA_TRUSTED:
4564 return (get_bool_attr_from_object(object_p,
4565 TRUSTED_BOOL_ON, template));
4566 case CKA_ID:
4567 case CKA_ISSUER:
4568 case CKA_SERIAL_NUMBER:
4569 case CKA_AC_ISSUER:
4570 case CKA_ATTR_TYPES:
4571 return (get_extra_attr_from_object(object_p,
4572 template));
4573 default:
4574 return (soft_get_common_attrs(object_p, template,
4575 object_p->object_type));
4579 * If we got this far, then the combination of certificate type
4580 * and requested attribute is invalid.
4582 return (CKR_ATTRIBUTE_TYPE_INVALID);
4585 CK_RV
4586 soft_set_certificate_attribute(soft_object_t *object_p,
4587 CK_ATTRIBUTE_PTR template, boolean_t copy)
4589 CK_CERTIFICATE_TYPE certtype = object_p->cert_type;
4591 switch (template->type) {
4592 case CKA_SUBJECT:
4593 if (certtype == CKC_X_509) {
4594 /* SUBJECT attr cannot be modified. */
4595 return (CKR_ATTRIBUTE_READ_ONLY);
4597 break;
4598 case CKA_OWNER:
4599 if (certtype == CKC_X_509_ATTR_CERT) {
4600 /* OWNER attr cannot be modified. */
4601 return (CKR_ATTRIBUTE_READ_ONLY);
4603 break;
4604 case CKA_VALUE:
4605 /* VALUE attr cannot be modified. */
4606 return (CKR_ATTRIBUTE_READ_ONLY);
4607 case CKA_ID:
4608 case CKA_ISSUER:
4609 if (certtype == CKC_X_509) {
4610 return (set_extra_attr_to_object(object_p,
4611 template->type, template));
4613 break;
4614 case CKA_AC_ISSUER:
4615 case CKA_ATTR_TYPES:
4616 if (certtype == CKC_X_509_ATTR_CERT) {
4617 return (set_extra_attr_to_object(object_p,
4618 template->type, template));
4620 break;
4621 case CKA_SERIAL_NUMBER:
4622 case CKA_LABEL:
4623 return (set_extra_attr_to_object(object_p,
4624 template->type, template));
4625 default:
4626 return (soft_set_common_storage_attribute(
4627 object_p, template, copy));
4631 * If we got this far, then the combination of certificate type
4632 * and requested attribute is invalid.
4634 return (CKR_ATTRIBUTE_TYPE_INVALID);
4638 * Call the appropriate get attribute function according to the class
4639 * of object.
4641 * The caller of this function holds the lock on the object.
4643 CK_RV
4644 soft_get_attribute(soft_object_t *object_p, CK_ATTRIBUTE_PTR template)
4647 CK_RV rv = CKR_OK;
4648 CK_OBJECT_CLASS class = object_p->class;
4650 switch (class) {
4651 case CKO_PUBLIC_KEY:
4652 rv = soft_get_public_key_attribute(object_p, template);
4653 break;
4655 case CKO_PRIVATE_KEY:
4656 rv = soft_get_private_key_attribute(object_p, template);
4657 break;
4659 case CKO_SECRET_KEY:
4660 rv = soft_get_secret_key_attribute(object_p, template);
4661 break;
4663 case CKO_DOMAIN_PARAMETERS:
4664 rv = soft_get_domain_parameters_attribute(object_p, template);
4665 break;
4667 case CKO_CERTIFICATE:
4668 rv = soft_get_certificate_attribute(object_p, template);
4669 break;
4671 default:
4673 * If the specified attribute for the object is invalid
4674 * (the object does not possess such as attribute), then
4675 * the ulValueLen is modified to hold the value -1.
4677 template->ulValueLen = (CK_ULONG)-1;
4678 return (CKR_ATTRIBUTE_TYPE_INVALID);
4681 return (rv);
4685 CK_RV
4686 soft_set_common_storage_attribute(soft_object_t *object_p,
4687 CK_ATTRIBUTE_PTR template, boolean_t copy)
4690 CK_RV rv = CKR_OK;
4692 switch (template->type) {
4694 case CKA_TOKEN:
4695 if (copy) {
4696 if ((*(CK_BBOOL *)template->pValue) == B_TRUE) {
4697 if (!soft_keystore_status(KEYSTORE_INITIALIZED))
4698 return (CKR_DEVICE_REMOVED);
4699 object_p->object_type |= TOKEN_OBJECT;
4701 } else {
4702 rv = CKR_ATTRIBUTE_READ_ONLY;
4705 break;
4707 case CKA_PRIVATE:
4708 if (copy) {
4709 if ((*(CK_BBOOL *)template->pValue) == B_TRUE) {
4710 (void) pthread_mutex_lock(&soft_giant_mutex);
4711 if (!soft_slot.authenticated) {
4713 * Check if this is the special case
4714 * when the PIN is never initialized
4715 * in the keystore. If true, we will
4716 * let it pass here and let it fail
4717 * with CKR_PIN_EXPIRED later on.
4719 if (!soft_slot.userpin_change_needed) {
4720 (void) pthread_mutex_unlock(
4721 &soft_giant_mutex);
4722 return (CKR_USER_NOT_LOGGED_IN);
4725 (void) pthread_mutex_unlock(&soft_giant_mutex);
4726 object_p->object_type |= PRIVATE_OBJECT;
4728 } else {
4729 rv = CKR_ATTRIBUTE_READ_ONLY;
4731 break;
4733 case CKA_MODIFIABLE:
4734 if (copy) {
4735 if ((*(CK_BBOOL *)template->pValue) == TRUE)
4736 object_p->bool_attr_mask &=
4737 ~NOT_MODIFIABLE_BOOL_ON;
4738 else
4739 object_p->bool_attr_mask |=
4740 NOT_MODIFIABLE_BOOL_ON;
4741 } else {
4742 rv = CKR_ATTRIBUTE_READ_ONLY;
4744 break;
4746 case CKA_CLASS:
4747 rv = CKR_ATTRIBUTE_READ_ONLY;
4748 break;
4750 default:
4751 rv = CKR_TEMPLATE_INCONSISTENT;
4754 return (rv);
4758 * Set the value of an attribute that is common to all key objects
4759 * (i.e. public key, private key and secret key).
4761 CK_RV
4762 soft_set_common_key_attribute(soft_object_t *object_p,
4763 CK_ATTRIBUTE_PTR template, boolean_t copy)
4766 switch (template->type) {
4768 case CKA_LABEL:
4770 * Only the LABEL can be modified in the common storage
4771 * object attributes after the object is created.
4773 return (set_extra_attr_to_object(object_p,
4774 CKA_LABEL, template));
4776 case CKA_ID:
4777 return (set_extra_attr_to_object(object_p,
4778 CKA_ID, template));
4780 case CKA_START_DATE:
4781 return (set_extra_attr_to_object(object_p,
4782 CKA_START_DATE, template));
4784 case CKA_END_DATE:
4785 return (set_extra_attr_to_object(object_p,
4786 CKA_END_DATE, template));
4788 case CKA_DERIVE:
4789 return (set_bool_attr_to_object(object_p,
4790 DERIVE_BOOL_ON, template));
4792 case CKA_KEY_TYPE:
4793 case CKA_LOCAL:
4794 case CKA_KEY_GEN_MECHANISM:
4795 return (CKR_ATTRIBUTE_READ_ONLY);
4797 default:
4798 return (soft_set_common_storage_attribute(object_p,
4799 template, copy));
4807 * Set the value of an attribute of a Public Key Object.
4809 * Rule: The attributes marked with footnote number "8" in the PKCS11
4810 * spec may be modified (p.88 in PKCS11 spec.).
4812 CK_RV
4813 soft_set_public_key_attribute(soft_object_t *object_p,
4814 CK_ATTRIBUTE_PTR template, boolean_t copy)
4816 CK_KEY_TYPE keytype = object_p->key_type;
4818 switch (template->type) {
4820 case CKA_SUBJECT:
4821 return (set_extra_attr_to_object(object_p,
4822 CKA_SUBJECT, template));
4824 case CKA_ENCRYPT:
4825 return (set_bool_attr_to_object(object_p,
4826 ENCRYPT_BOOL_ON, template));
4828 case CKA_VERIFY:
4829 return (set_bool_attr_to_object(object_p,
4830 VERIFY_BOOL_ON, template));
4832 case CKA_VERIFY_RECOVER:
4833 return (set_bool_attr_to_object(object_p,
4834 VERIFY_RECOVER_BOOL_ON, template));
4836 case CKA_WRAP:
4837 return (set_bool_attr_to_object(object_p,
4838 WRAP_BOOL_ON, template));
4840 case CKA_MODULUS:
4841 case CKA_MODULUS_BITS:
4842 case CKA_PUBLIC_EXPONENT:
4843 if (keytype == CKK_RSA)
4844 return (CKR_ATTRIBUTE_READ_ONLY);
4845 break;
4847 case CKA_SUBPRIME:
4848 if ((keytype == CKK_DSA) ||
4849 (keytype == CKK_X9_42_DH))
4850 return (CKR_ATTRIBUTE_READ_ONLY);
4851 break;
4853 case CKA_PRIME:
4854 case CKA_BASE:
4855 case CKA_VALUE:
4856 if ((keytype == CKK_DSA) ||
4857 (keytype == CKK_DH) ||
4858 (keytype == CKK_X9_42_DH))
4859 return (CKR_ATTRIBUTE_READ_ONLY);
4860 break;
4862 default:
4864 * Set the value of a common key attribute.
4866 return (soft_set_common_key_attribute(object_p,
4867 template, copy));
4871 * If we got this far, then the combination of key type
4872 * and requested attribute is invalid.
4874 return (CKR_ATTRIBUTE_TYPE_INVALID);
4879 * Set the value of an attribute of a Private Key Object.
4881 * Rule: The attributes marked with footnote number "8" in the PKCS11
4882 * spec may be modified (p.88 in PKCS11 spec.).
4884 CK_RV
4885 soft_set_private_key_attribute(soft_object_t *object_p,
4886 CK_ATTRIBUTE_PTR template, boolean_t copy)
4888 CK_KEY_TYPE keytype = object_p->key_type;
4890 switch (template->type) {
4892 case CKA_SUBJECT:
4893 return (set_extra_attr_to_object(object_p,
4894 CKA_SUBJECT, template));
4896 case CKA_SENSITIVE:
4898 * Cannot set SENSITIVE to FALSE if it is already ON.
4900 if (((*(CK_BBOOL *)template->pValue) == B_FALSE) &&
4901 (object_p->bool_attr_mask & SENSITIVE_BOOL_ON)) {
4902 return (CKR_ATTRIBUTE_READ_ONLY);
4905 if (*(CK_BBOOL *)template->pValue)
4906 object_p->bool_attr_mask |= SENSITIVE_BOOL_ON;
4907 return (CKR_OK);
4909 case CKA_DECRYPT:
4910 return (set_bool_attr_to_object(object_p,
4911 DECRYPT_BOOL_ON, template));
4913 case CKA_SIGN:
4914 return (set_bool_attr_to_object(object_p,
4915 SIGN_BOOL_ON, template));
4917 case CKA_SIGN_RECOVER:
4918 return (set_bool_attr_to_object(object_p,
4919 SIGN_RECOVER_BOOL_ON, template));
4921 case CKA_UNWRAP:
4922 return (set_bool_attr_to_object(object_p,
4923 UNWRAP_BOOL_ON, template));
4925 case CKA_EXTRACTABLE:
4927 * Cannot set EXTRACTABLE to TRUE if it is already OFF.
4929 if ((*(CK_BBOOL *)template->pValue) &&
4930 !(object_p->bool_attr_mask & EXTRACTABLE_BOOL_ON)) {
4931 return (CKR_ATTRIBUTE_READ_ONLY);
4934 if ((*(CK_BBOOL *)template->pValue) == B_FALSE)
4935 object_p->bool_attr_mask &= ~EXTRACTABLE_BOOL_ON;
4936 return (CKR_OK);
4938 case CKA_MODULUS:
4939 case CKA_PUBLIC_EXPONENT:
4940 case CKA_PRIVATE_EXPONENT:
4941 case CKA_PRIME_1:
4942 case CKA_PRIME_2:
4943 case CKA_EXPONENT_1:
4944 case CKA_EXPONENT_2:
4945 case CKA_COEFFICIENT:
4946 if (keytype == CKK_RSA) {
4947 return (CKR_ATTRIBUTE_READ_ONLY);
4949 break;
4951 case CKA_SUBPRIME:
4952 if ((keytype == CKK_DSA) ||
4953 (keytype == CKK_X9_42_DH))
4954 return (CKR_ATTRIBUTE_READ_ONLY);
4955 break;
4957 case CKA_PRIME:
4958 case CKA_BASE:
4959 case CKA_VALUE:
4960 if ((keytype == CKK_DSA) ||
4961 (keytype == CKK_DH) ||
4962 (keytype == CKK_X9_42_DH))
4963 return (CKR_ATTRIBUTE_READ_ONLY);
4964 break;
4966 case CKA_VALUE_BITS:
4967 if (keytype == CKK_DH)
4968 return (CKR_ATTRIBUTE_READ_ONLY);
4969 break;
4971 default:
4973 * Set the value of a common key attribute.
4975 return (soft_set_common_key_attribute(object_p,
4976 template, copy));
4980 * If we got this far, then the combination of key type
4981 * and requested attribute is invalid.
4983 return (CKR_ATTRIBUTE_TYPE_INVALID);
4987 * Set the value of an attribute of a Secret Key Object.
4989 * Rule: The attributes marked with footnote number "8" in the PKCS11
4990 * spec may be modified (p.88 in PKCS11 spec.).
4992 CK_RV
4993 soft_set_secret_key_attribute(soft_object_t *object_p,
4994 CK_ATTRIBUTE_PTR template, boolean_t copy)
4996 CK_KEY_TYPE keytype = object_p->key_type;
4998 switch (template->type) {
5000 case CKA_SENSITIVE:
5002 * Cannot set SENSITIVE to FALSE if it is already ON.
5004 if (((*(CK_BBOOL *)template->pValue) == B_FALSE) &&
5005 (object_p->bool_attr_mask & SENSITIVE_BOOL_ON)) {
5006 return (CKR_ATTRIBUTE_READ_ONLY);
5009 if (*(CK_BBOOL *)template->pValue)
5010 object_p->bool_attr_mask |= SENSITIVE_BOOL_ON;
5011 return (CKR_OK);
5013 case CKA_ENCRYPT:
5014 return (set_bool_attr_to_object(object_p,
5015 ENCRYPT_BOOL_ON, template));
5017 case CKA_DECRYPT:
5018 return (set_bool_attr_to_object(object_p,
5019 DECRYPT_BOOL_ON, template));
5021 case CKA_SIGN:
5022 return (set_bool_attr_to_object(object_p,
5023 SIGN_BOOL_ON, template));
5025 case CKA_VERIFY:
5026 return (set_bool_attr_to_object(object_p,
5027 VERIFY_BOOL_ON, template));
5029 case CKA_WRAP:
5030 return (set_bool_attr_to_object(object_p,
5031 WRAP_BOOL_ON, template));
5033 case CKA_UNWRAP:
5034 return (set_bool_attr_to_object(object_p,
5035 UNWRAP_BOOL_ON, template));
5037 case CKA_EXTRACTABLE:
5039 * Cannot set EXTRACTABLE to TRUE if it is already OFF.
5041 if ((*(CK_BBOOL *)template->pValue) &&
5042 !(object_p->bool_attr_mask & EXTRACTABLE_BOOL_ON)) {
5043 return (CKR_ATTRIBUTE_READ_ONLY);
5046 if ((*(CK_BBOOL *)template->pValue) == B_FALSE)
5047 object_p->bool_attr_mask &= ~EXTRACTABLE_BOOL_ON;
5048 return (CKR_OK);
5050 case CKA_VALUE:
5051 return (CKR_ATTRIBUTE_READ_ONLY);
5053 case CKA_VALUE_LEN:
5054 if ((keytype == CKK_RC4) ||
5055 (keytype == CKK_GENERIC_SECRET) ||
5056 (keytype == CKK_AES) ||
5057 (keytype == CKK_BLOWFISH))
5058 return (CKR_ATTRIBUTE_READ_ONLY);
5059 break;
5061 default:
5063 * Set the value of a common key attribute.
5065 return (soft_set_common_key_attribute(object_p,
5066 template, copy));
5070 * If we got this far, then the combination of key type
5071 * and requested attribute is invalid.
5073 return (CKR_ATTRIBUTE_TYPE_INVALID);
5078 * Call the appropriate set attribute function according to the class
5079 * of object.
5081 * The caller of this function does not hold the lock on the original
5082 * object, since this function is setting the attribute on the new object
5083 * that is being modified.
5085 * Argument copy: TRUE when called by C_CopyObject,
5086 * FALSE when called by C_SetAttributeValue.
5088 CK_RV
5089 soft_set_attribute(soft_object_t *object_p, CK_ATTRIBUTE_PTR template,
5090 boolean_t copy)
5093 CK_RV rv = CKR_OK;
5094 CK_OBJECT_CLASS class = object_p->class;
5096 switch (class) {
5098 case CKO_PUBLIC_KEY:
5099 rv = soft_set_public_key_attribute(object_p, template, copy);
5100 break;
5102 case CKO_PRIVATE_KEY:
5103 rv = soft_set_private_key_attribute(object_p, template, copy);
5104 break;
5106 case CKO_SECRET_KEY:
5107 rv = soft_set_secret_key_attribute(object_p, template, copy);
5108 break;
5110 case CKO_DOMAIN_PARAMETERS:
5111 switch (template->type) {
5112 case CKA_LABEL:
5114 * Only the LABEL can be modified in the common
5115 * storage object attributes after the object is
5116 * created.
5118 return (set_extra_attr_to_object(object_p,
5119 CKA_LABEL, template));
5120 default:
5121 return (CKR_TEMPLATE_INCONSISTENT);
5123 case CKO_CERTIFICATE:
5124 rv = soft_set_certificate_attribute(object_p, template, copy);
5125 break;
5127 default:
5129 * If the template specifies a value of an attribute
5130 * which is incompatible with other existing attributes
5131 * of the object, then fails with return code
5132 * CKR_TEMPLATE_INCONSISTENT.
5134 rv = CKR_TEMPLATE_INCONSISTENT;
5135 break;
5138 return (rv);
5141 CK_RV
5142 soft_get_public_value(soft_object_t *key, CK_ATTRIBUTE_TYPE type,
5143 uchar_t *value, uint32_t *value_len)
5145 uint32_t len = 0;
5146 switch (type) {
5148 /* The following attributes belong to RSA */
5149 case CKA_MODULUS:
5150 #ifdef __sparcv9
5151 len =
5152 /* LINTED */
5153 (uint32_t)
5154 ((biginteger_t *)OBJ_PUB_RSA_MOD(key))->big_value_len;
5155 #else /* !__sparcv9 */
5156 len =
5157 ((biginteger_t *)OBJ_PUB_RSA_MOD(key))->big_value_len;
5158 #endif /* __sparcv9 */
5160 /* This attribute MUST BE set */
5161 if (len == 0 || len > *value_len) {
5162 return (CKR_ATTRIBUTE_VALUE_INVALID);
5164 *value_len = len;
5166 (void) memcpy(value,
5167 ((biginteger_t *)OBJ_PUB_RSA_MOD(key))->big_value,
5168 *value_len);
5170 break;
5172 case CKA_PUBLIC_EXPONENT:
5173 #ifdef __sparcv9
5174 len =
5175 /* LINTED */
5176 (uint32_t)
5177 ((biginteger_t *)OBJ_PUB_RSA_PUBEXPO(key))->big_value_len;
5178 #else /* !__sparcv9 */
5179 len =
5180 ((biginteger_t *)OBJ_PUB_RSA_PUBEXPO(key))->big_value_len;
5181 #endif /* __sparcv9 */
5183 /* This attribute MUST BE set */
5184 if (len == 0 || len > *value_len) {
5185 return (CKR_ATTRIBUTE_VALUE_INVALID);
5187 *value_len = len;
5189 (void) memcpy(value,
5190 ((biginteger_t *)OBJ_PUB_RSA_PUBEXPO(key))->big_value,
5191 *value_len);
5193 break;
5195 /* The following attributes belong to DSA and DH */
5196 case CKA_PRIME:
5198 if (key->key_type == CKK_DSA)
5199 #ifdef __sparcv9
5200 len =
5201 /* LINTED */
5202 (uint32_t)
5203 ((biginteger_t *)OBJ_PUB_DSA_PRIME(key))->
5204 big_value_len;
5205 #else /* !__sparcv9 */
5206 len =
5207 ((biginteger_t *)OBJ_PUB_DSA_PRIME(key))->
5208 big_value_len;
5209 #endif /* __sparcv9 */
5210 else
5211 #ifdef __sparcv9
5212 len =
5213 /* LINTED */
5214 (uint32_t)
5215 ((biginteger_t *)OBJ_PUB_DH_PRIME(key))->
5216 big_value_len;
5217 #else /* !__sparcv9 */
5218 len =
5219 ((biginteger_t *)OBJ_PUB_DH_PRIME(key))->
5220 big_value_len;
5221 #endif /* __sparcv9 */
5223 /* This attribute MUST BE set */
5224 if (len == 0 || len > *value_len) {
5225 return (CKR_ATTRIBUTE_VALUE_INVALID);
5227 *value_len = len;
5229 if (key->key_type == CKK_DSA)
5230 (void) memcpy(value,
5231 ((biginteger_t *)OBJ_PUB_DSA_PRIME(key))->big_value,
5232 *value_len);
5233 else
5234 (void) memcpy(value,
5235 ((biginteger_t *)OBJ_PUB_DH_PRIME(key))->big_value,
5236 *value_len);
5238 break;
5240 case CKA_SUBPRIME:
5241 #ifdef __sparcv9
5242 len =
5243 /* LINTED */
5244 (uint32_t)
5245 ((biginteger_t *)OBJ_PUB_DSA_SUBPRIME(key))->big_value_len;
5246 #else /* !__sparcv9 */
5247 len =
5248 ((biginteger_t *)OBJ_PUB_DSA_SUBPRIME(key))->big_value_len;
5249 #endif /* __sparcv9 */
5251 /* This attribute MUST BE set */
5252 if (len == 0 || len > *value_len) {
5253 return (CKR_ATTRIBUTE_VALUE_INVALID);
5255 *value_len = len;
5257 (void) memcpy(value,
5258 ((biginteger_t *)OBJ_PUB_DSA_SUBPRIME(key))->big_value,
5259 *value_len);
5261 break;
5263 case CKA_BASE:
5265 if (key->key_type == CKK_DSA)
5266 #ifdef __sparcv9
5267 len =
5268 /* LINTED */
5269 (uint32_t)
5270 ((biginteger_t *)OBJ_PUB_DSA_BASE(key))->
5271 big_value_len;
5272 #else /* !__sparcv9 */
5273 len =
5274 ((biginteger_t *)OBJ_PUB_DSA_BASE(key))->
5275 big_value_len;
5276 #endif /* __sparcv9 */
5277 else
5278 #ifdef __sparcv9
5279 len =
5280 /* LINTED */
5281 (uint32_t)
5282 ((biginteger_t *)OBJ_PUB_DH_BASE(key))->
5283 big_value_len;
5284 #else /* !__sparcv9 */
5285 len =
5286 ((biginteger_t *)OBJ_PUB_DH_BASE(key))->
5287 big_value_len;
5288 #endif /* __sparcv9 */
5290 /* This attribute MUST BE set */
5291 if (len == 0 || len > *value_len) {
5292 return (CKR_ATTRIBUTE_VALUE_INVALID);
5294 *value_len = len;
5296 if (key->key_type == CKK_DSA)
5297 (void) memcpy(value,
5298 ((biginteger_t *)OBJ_PUB_DSA_BASE(key))->big_value,
5299 *value_len);
5300 else
5301 (void) memcpy(value,
5302 ((biginteger_t *)OBJ_PUB_DH_BASE(key))->big_value,
5303 *value_len);
5304 break;
5306 case CKA_VALUE:
5308 if (key->key_type == CKK_DSA)
5309 #ifdef __sparcv9
5310 len =
5311 /* LINTED */
5312 (uint32_t)
5313 ((biginteger_t *)OBJ_PUB_DSA_VALUE(key))->
5314 big_value_len;
5315 #else /* !__sparcv9 */
5316 len =
5317 ((biginteger_t *)OBJ_PUB_DSA_VALUE(key))->
5318 big_value_len;
5319 #endif /* __sparcv9 */
5320 else
5321 #ifdef __sparcv9
5322 len =
5323 /* LINTED */
5324 (uint32_t)
5325 ((biginteger_t *)OBJ_PUB_DH_VALUE(key))->
5326 big_value_len;
5327 #else /* !__sparcv9 */
5328 len =
5329 ((biginteger_t *)OBJ_PUB_DH_VALUE(key))->
5330 big_value_len;
5331 #endif /* __sparcv9 */
5333 /* This attribute MUST BE set */
5334 if (len == 0 || len > *value_len) {
5335 return (CKR_ATTRIBUTE_VALUE_INVALID);
5337 *value_len = len;
5339 if (key->key_type == CKK_DSA)
5340 (void) memcpy(value,
5341 ((biginteger_t *)OBJ_PUB_DSA_VALUE(key))->big_value,
5342 *value_len);
5343 else
5344 (void) memcpy(value,
5345 ((biginteger_t *)OBJ_PUB_DH_VALUE(key))->big_value,
5346 *value_len);
5348 break;
5351 return (CKR_OK);
5355 CK_RV
5356 soft_get_private_value(soft_object_t *key, CK_ATTRIBUTE_TYPE type,
5357 uchar_t *value, uint32_t *value_len)
5360 uint32_t len = 0;
5362 switch (type) {
5364 /* The following attributes belong to RSA */
5365 case CKA_MODULUS:
5366 #ifdef __sparcv9
5367 len =
5368 /* LINTED */
5369 (uint32_t)
5370 ((biginteger_t *)OBJ_PRI_RSA_MOD(key))->big_value_len;
5371 #else /* !__sparcv9 */
5372 len =
5373 ((biginteger_t *)OBJ_PRI_RSA_MOD(key))->big_value_len;
5374 #endif /* __sparcv9 */
5376 /* This attribute MUST BE set */
5377 if (len == 0 || len > *value_len) {
5378 return (CKR_ATTRIBUTE_VALUE_INVALID);
5380 *value_len = len;
5382 (void) memcpy(value,
5383 ((biginteger_t *)OBJ_PRI_RSA_MOD(key))->big_value,
5384 *value_len);
5386 break;
5388 case CKA_PRIVATE_EXPONENT:
5389 #ifdef __sparcv9
5390 len =
5391 /* LINTED */
5392 (uint32_t)
5393 ((biginteger_t *)OBJ_PRI_RSA_PRIEXPO(key))->big_value_len;
5394 #else /* !__sparcv9 */
5395 len =
5396 ((biginteger_t *)OBJ_PRI_RSA_PRIEXPO(key))->big_value_len;
5397 #endif /* __sparcv9 */
5399 /* This attribute MUST BE set */
5400 if (len == 0 || len > *value_len) {
5401 return (CKR_ATTRIBUTE_VALUE_INVALID);
5403 *value_len = len;
5405 (void) memcpy(value,
5406 ((biginteger_t *)OBJ_PRI_RSA_PRIEXPO(key))->big_value,
5407 *value_len);
5409 break;
5411 case CKA_PRIME_1:
5412 #ifdef __sparcv9
5413 len =
5414 /* LINTED */
5415 (uint32_t)
5416 ((biginteger_t *)OBJ_PRI_RSA_PRIME1(key))->big_value_len;
5417 #else /* !__sparcv9 */
5418 len =
5419 ((biginteger_t *)OBJ_PRI_RSA_PRIME1(key))->big_value_len;
5420 #endif /* __sparcv9 */
5422 if (len > *value_len) {
5423 return (CKR_ATTRIBUTE_VALUE_INVALID);
5425 *value_len = len;
5427 if (*value_len == 0) {
5428 return (CKR_OK);
5431 (void) memcpy(value,
5432 ((biginteger_t *)OBJ_PRI_RSA_PRIME1(key))->big_value,
5433 *value_len);
5435 break;
5437 case CKA_PRIME_2:
5438 #ifdef __sparcv9
5439 len =
5440 /* LINTED */
5441 (uint32_t)
5442 ((biginteger_t *)OBJ_PRI_RSA_PRIME2(key))->big_value_len;
5443 #else /* !__sparcv9 */
5444 len =
5445 ((biginteger_t *)OBJ_PRI_RSA_PRIME2(key))->big_value_len;
5446 #endif /* __sparcv9 */
5448 if (len > *value_len) {
5449 return (CKR_ATTRIBUTE_VALUE_INVALID);
5451 *value_len = len;
5453 if (*value_len == 0) {
5454 return (CKR_OK);
5457 (void) memcpy(value,
5458 ((biginteger_t *)OBJ_PRI_RSA_PRIME2(key))->big_value,
5459 *value_len);
5461 break;
5463 case CKA_EXPONENT_1:
5464 #ifdef __sparcv9
5465 len =
5466 /* LINTED */
5467 (uint32_t)
5468 ((biginteger_t *)OBJ_PRI_RSA_EXPO1(key))->big_value_len;
5469 #else /* !__sparcv9 */
5470 len =
5471 ((biginteger_t *)OBJ_PRI_RSA_EXPO1(key))->big_value_len;
5472 #endif /* __sparcv9 */
5474 if (len > *value_len) {
5475 return (CKR_ATTRIBUTE_VALUE_INVALID);
5477 *value_len = len;
5479 if (*value_len == 0) {
5480 return (CKR_OK);
5483 (void) memcpy(value,
5484 ((biginteger_t *)OBJ_PRI_RSA_EXPO1(key))->big_value,
5485 *value_len);
5487 break;
5489 case CKA_EXPONENT_2:
5490 #ifdef __sparcv9
5491 len =
5492 /* LINTED */
5493 (uint32_t)
5494 ((biginteger_t *)OBJ_PRI_RSA_EXPO2(key))->big_value_len;
5495 #else /* !__sparcv9 */
5496 len =
5497 ((biginteger_t *)OBJ_PRI_RSA_EXPO2(key))->big_value_len;
5498 #endif /* __sparcv9 */
5500 if (len > *value_len) {
5501 return (CKR_ATTRIBUTE_VALUE_INVALID);
5503 *value_len = len;
5505 if (*value_len == 0) {
5506 return (CKR_OK);
5509 (void) memcpy(value,
5510 ((biginteger_t *)OBJ_PRI_RSA_EXPO2(key))->big_value,
5511 *value_len);
5513 break;
5515 case CKA_COEFFICIENT:
5516 #ifdef __sparcv9
5517 len =
5518 /* LINTED */
5519 (uint32_t)
5520 ((biginteger_t *)OBJ_PRI_RSA_COEF(key))->big_value_len;
5521 #else /* !__sparcv9 */
5522 len =
5523 ((biginteger_t *)OBJ_PRI_RSA_COEF(key))->big_value_len;
5524 #endif /* __sparcv9 */
5526 if (len > *value_len) {
5527 return (CKR_ATTRIBUTE_VALUE_INVALID);
5529 *value_len = len;
5531 if (*value_len == 0) {
5532 return (CKR_OK);
5535 (void) memcpy(value,
5536 ((biginteger_t *)OBJ_PRI_RSA_COEF(key))->big_value,
5537 *value_len);
5539 break;
5541 /* The following attributes belong to DSA and DH */
5542 case CKA_PRIME:
5544 if (key->key_type == CKK_DSA)
5545 #ifdef __sparcv9
5546 len =
5547 /* LINTED */
5548 (uint32_t)
5549 ((biginteger_t *)OBJ_PRI_DSA_PRIME(key))->
5550 big_value_len;
5551 #else /* !__sparcv9 */
5552 len =
5553 ((biginteger_t *)OBJ_PRI_DSA_PRIME(key))->
5554 big_value_len;
5555 #endif /* __sparcv9 */
5556 else
5557 #ifdef __sparcv9
5558 len =
5559 /* LINTED */
5560 (uint32_t)
5561 ((biginteger_t *)OBJ_PRI_DH_PRIME(key))->
5562 big_value_len;
5563 #else /* !__sparcv9 */
5564 len =
5565 ((biginteger_t *)OBJ_PRI_DH_PRIME(key))->
5566 big_value_len;
5567 #endif /* __sparcv9 */
5569 /* This attribute MUST BE set */
5570 if (len == 0 || len > *value_len) {
5571 return (CKR_ATTRIBUTE_VALUE_INVALID);
5573 *value_len = len;
5575 if (key->key_type == CKK_DSA)
5576 (void) memcpy(value,
5577 ((biginteger_t *)OBJ_PRI_DSA_PRIME(key))->big_value,
5578 *value_len);
5579 else
5580 (void) memcpy(value,
5581 ((biginteger_t *)OBJ_PRI_DH_PRIME(key))->big_value,
5582 *value_len);
5584 break;
5586 case CKA_SUBPRIME:
5587 #ifdef __sparcv9
5588 len =
5589 /* LINTED */
5590 (uint32_t)
5591 ((biginteger_t *)OBJ_PRI_DSA_SUBPRIME(key))->big_value_len;
5592 #else /* !__sparcv9 */
5593 len =
5594 ((biginteger_t *)OBJ_PRI_DSA_SUBPRIME(key))->big_value_len;
5595 #endif /* __sparcv9 */
5597 /* This attribute MUST BE set */
5598 if (len == 0 || len > *value_len) {
5599 return (CKR_ATTRIBUTE_VALUE_INVALID);
5601 *value_len = len;
5603 (void) memcpy(value,
5604 ((biginteger_t *)OBJ_PRI_DSA_SUBPRIME(key))->big_value,
5605 *value_len);
5607 break;
5609 case CKA_BASE:
5611 if (key->key_type == CKK_DSA)
5612 #ifdef __sparcv9
5613 len =
5614 /* LINTED */
5615 (uint32_t)
5616 ((biginteger_t *)OBJ_PRI_DSA_BASE(key))->
5617 big_value_len;
5618 #else /* !__sparcv9 */
5619 len =
5620 ((biginteger_t *)OBJ_PRI_DSA_BASE(key))->
5621 big_value_len;
5622 #endif /* __sparcv9 */
5623 else
5624 #ifdef __sparcv9
5625 len =
5626 /* LINTED */
5627 (uint32_t)
5628 ((biginteger_t *)OBJ_PRI_DH_BASE(key))->
5629 big_value_len;
5630 #else /* !__sparcv9 */
5631 len =
5632 ((biginteger_t *)OBJ_PRI_DH_BASE(key))->
5633 big_value_len;
5634 #endif /* __sparcv9 */
5636 /* This attribute MUST BE set */
5637 if (len == 0 || len > *value_len) {
5638 return (CKR_ATTRIBUTE_VALUE_INVALID);
5640 *value_len = len;
5642 if (key->key_type == CKK_DSA)
5643 (void) memcpy(value,
5644 ((biginteger_t *)OBJ_PRI_DSA_BASE(key))->big_value,
5645 *value_len);
5646 else
5647 (void) memcpy(value,
5648 ((biginteger_t *)OBJ_PRI_DH_BASE(key))->big_value,
5649 *value_len);
5650 break;
5652 case CKA_VALUE:
5654 if (key->key_type == CKK_DSA) {
5655 #ifdef __sparcv9
5656 len =
5657 /* LINTED */
5658 (uint32_t)
5659 ((biginteger_t *)OBJ_PRI_DSA_VALUE(key))->
5660 big_value_len;
5661 #else /* !__sparcv9 */
5662 len =
5663 ((biginteger_t *)OBJ_PRI_DSA_VALUE(key))->
5664 big_value_len;
5665 #endif /* __sparcv9 */
5666 } else if (key->key_type == CKK_DH) {
5667 #ifdef __sparcv9
5668 len =
5669 /* LINTED */
5670 (uint32_t)
5671 ((biginteger_t *)OBJ_PRI_DH_VALUE(key))->
5672 big_value_len;
5673 #else /* !__sparcv9 */
5674 len =
5675 ((biginteger_t *)OBJ_PRI_DH_VALUE(key))->
5676 big_value_len;
5677 #endif /* __sparcv9 */
5678 } else {
5679 #ifdef __sparcv9
5680 len =
5681 /* LINTED */
5682 (uint32_t)
5683 ((biginteger_t *)OBJ_PRI_EC_VALUE(key))->
5684 big_value_len;
5685 #else /* !__sparcv9 */
5686 len =
5687 ((biginteger_t *)OBJ_PRI_EC_VALUE(key))->
5688 big_value_len;
5689 #endif /* __sparcv9 */
5692 /* This attribute MUST BE set */
5693 if (len == 0 || len > *value_len) {
5694 return (CKR_ATTRIBUTE_VALUE_INVALID);
5696 *value_len = len;
5698 if (key->key_type == CKK_DSA) {
5699 (void) memcpy(value,
5700 ((biginteger_t *)OBJ_PRI_DSA_VALUE(key))->big_value,
5701 *value_len);
5702 } else if (key->key_type == CKK_DH) {
5703 (void) memcpy(value,
5704 ((biginteger_t *)OBJ_PRI_DH_VALUE(key))->big_value,
5705 *value_len);
5706 } else {
5707 (void) memcpy(value,
5708 ((biginteger_t *)OBJ_PRI_EC_VALUE(key))->big_value,
5709 *value_len);
5712 break;
5715 return (CKR_OK);
5719 static CK_RV
5720 copy_bigint(biginteger_t *new_bigint, biginteger_t *old_bigint)
5722 new_bigint->big_value =
5723 malloc((sizeof (CK_BYTE) * new_bigint->big_value_len));
5725 if (new_bigint->big_value == NULL) {
5726 return (CKR_HOST_MEMORY);
5729 (void) memcpy(new_bigint->big_value, old_bigint->big_value,
5730 (sizeof (CK_BYTE) * new_bigint->big_value_len));
5732 return (CKR_OK);
5735 static void
5736 free_public_key_attr(public_key_obj_t *pbk, CK_KEY_TYPE key_type)
5738 if (pbk == NULL) {
5739 return;
5742 switch (key_type) {
5743 case CKK_RSA:
5744 bigint_attr_cleanup(KEY_PUB_RSA_MOD(pbk));
5745 bigint_attr_cleanup(KEY_PUB_RSA_PUBEXPO(pbk));
5746 break;
5747 case CKK_DSA:
5748 bigint_attr_cleanup(KEY_PUB_DSA_PRIME(pbk));
5749 bigint_attr_cleanup(KEY_PUB_DSA_SUBPRIME(pbk));
5750 bigint_attr_cleanup(KEY_PUB_DSA_BASE(pbk));
5751 bigint_attr_cleanup(KEY_PUB_DSA_VALUE(pbk));
5752 break;
5753 case CKK_DH:
5754 bigint_attr_cleanup(KEY_PUB_DH_PRIME(pbk));
5755 bigint_attr_cleanup(KEY_PUB_DH_BASE(pbk));
5756 bigint_attr_cleanup(KEY_PUB_DH_VALUE(pbk));
5757 break;
5758 case CKK_EC:
5759 bigint_attr_cleanup(KEY_PUB_EC_POINT(pbk));
5760 break;
5761 case CKK_X9_42_DH:
5762 bigint_attr_cleanup(KEY_PUB_DH942_PRIME(pbk));
5763 bigint_attr_cleanup(KEY_PUB_DH942_SUBPRIME(pbk));
5764 bigint_attr_cleanup(KEY_PUB_DH942_BASE(pbk));
5765 bigint_attr_cleanup(KEY_PUB_DH942_VALUE(pbk));
5766 break;
5767 default:
5768 break;
5770 free(pbk);
5773 CK_RV
5774 soft_copy_public_key_attr(public_key_obj_t *old_pub_key_obj_p,
5775 public_key_obj_t **new_pub_key_obj_p, CK_KEY_TYPE key_type)
5778 public_key_obj_t *pbk;
5779 CK_RV rv = CKR_OK;
5781 pbk = calloc(1, sizeof (public_key_obj_t));
5782 if (pbk == NULL) {
5783 return (CKR_HOST_MEMORY);
5786 switch (key_type) {
5787 case CKK_RSA:
5788 (void) memcpy(KEY_PUB_RSA(pbk),
5789 KEY_PUB_RSA(old_pub_key_obj_p),
5790 sizeof (rsa_pub_key_t));
5791 /* copy modulus */
5792 rv = copy_bigint(KEY_PUB_RSA_MOD(pbk),
5793 KEY_PUB_RSA_MOD(old_pub_key_obj_p));
5794 if (rv != CKR_OK) {
5795 free_public_key_attr(pbk, key_type);
5796 return (rv);
5798 /* copy public exponent */
5799 rv = copy_bigint(KEY_PUB_RSA_PUBEXPO(pbk),
5800 KEY_PUB_RSA_PUBEXPO(old_pub_key_obj_p));
5801 if (rv != CKR_OK) {
5802 free_public_key_attr(pbk, key_type);
5803 return (rv);
5805 break;
5806 case CKK_DSA:
5807 (void) memcpy(KEY_PUB_DSA(pbk),
5808 KEY_PUB_DSA(old_pub_key_obj_p),
5809 sizeof (dsa_pub_key_t));
5811 /* copy prime */
5812 rv = copy_bigint(KEY_PUB_DSA_PRIME(pbk),
5813 KEY_PUB_DSA_PRIME(old_pub_key_obj_p));
5814 if (rv != CKR_OK) {
5815 free_public_key_attr(pbk, key_type);
5816 return (rv);
5819 /* copy subprime */
5820 rv = copy_bigint(KEY_PUB_DSA_SUBPRIME(pbk),
5821 KEY_PUB_DSA_SUBPRIME(old_pub_key_obj_p));
5822 if (rv != CKR_OK) {
5823 free_public_key_attr(pbk, key_type);
5824 return (rv);
5827 /* copy base */
5828 rv = copy_bigint(KEY_PUB_DSA_BASE(pbk),
5829 KEY_PUB_DSA_BASE(old_pub_key_obj_p));
5830 if (rv != CKR_OK) {
5831 free_public_key_attr(pbk, key_type);
5832 return (rv);
5835 /* copy value */
5836 rv = copy_bigint(KEY_PUB_DSA_VALUE(pbk),
5837 KEY_PUB_DSA_VALUE(old_pub_key_obj_p));
5838 if (rv != CKR_OK) {
5839 free_public_key_attr(pbk, key_type);
5840 return (rv);
5842 break;
5843 case CKK_DH:
5844 (void) memcpy(KEY_PUB_DH(pbk),
5845 KEY_PUB_DH(old_pub_key_obj_p),
5846 sizeof (dh_pub_key_t));
5848 /* copy prime */
5849 rv = copy_bigint(KEY_PUB_DH_PRIME(pbk),
5850 KEY_PUB_DH_PRIME(old_pub_key_obj_p));
5851 if (rv != CKR_OK) {
5852 free_public_key_attr(pbk, key_type);
5853 return (rv);
5856 /* copy base */
5857 rv = copy_bigint(KEY_PUB_DH_BASE(pbk),
5858 KEY_PUB_DH_BASE(old_pub_key_obj_p));
5859 if (rv != CKR_OK) {
5860 free_public_key_attr(pbk, key_type);
5861 return (rv);
5864 /* copy value */
5865 rv = copy_bigint(KEY_PUB_DH_VALUE(pbk),
5866 KEY_PUB_DH_VALUE(old_pub_key_obj_p));
5867 if (rv != CKR_OK) {
5868 free_public_key_attr(pbk, key_type);
5869 return (rv);
5871 break;
5872 case CKK_EC:
5873 (void) memcpy(KEY_PUB_EC(pbk),
5874 KEY_PUB_EC(old_pub_key_obj_p),
5875 sizeof (ec_pub_key_t));
5877 /* copy point */
5878 rv = copy_bigint(KEY_PUB_EC_POINT(pbk),
5879 KEY_PUB_EC_POINT(old_pub_key_obj_p));
5880 if (rv != CKR_OK) {
5881 free_public_key_attr(pbk, key_type);
5882 return (rv);
5884 break;
5885 case CKK_X9_42_DH:
5886 (void) memcpy(KEY_PUB_DH942(pbk),
5887 KEY_PUB_DH942(old_pub_key_obj_p),
5888 sizeof (dh942_pub_key_t));
5890 /* copy prime */
5891 rv = copy_bigint(KEY_PUB_DH942_PRIME(pbk),
5892 KEY_PUB_DH942_PRIME(old_pub_key_obj_p));
5893 if (rv != CKR_OK) {
5894 free_public_key_attr(pbk, key_type);
5895 return (rv);
5898 /* copy subprime */
5899 rv = copy_bigint(KEY_PUB_DH942_SUBPRIME(pbk),
5900 KEY_PUB_DH942_SUBPRIME(old_pub_key_obj_p));
5901 if (rv != CKR_OK) {
5902 free_public_key_attr(pbk, key_type);
5903 return (rv);
5906 /* copy base */
5907 rv = copy_bigint(KEY_PUB_DH942_BASE(pbk),
5908 KEY_PUB_DH942_BASE(old_pub_key_obj_p));
5909 if (rv != CKR_OK) {
5910 free_public_key_attr(pbk, key_type);
5911 return (rv);
5914 /* copy value */
5915 rv = copy_bigint(KEY_PUB_DH942_VALUE(pbk),
5916 KEY_PUB_DH942_VALUE(old_pub_key_obj_p));
5917 if (rv != CKR_OK) {
5918 free_public_key_attr(pbk, key_type);
5919 return (rv);
5921 break;
5922 default:
5923 break;
5925 *new_pub_key_obj_p = pbk;
5926 return (rv);
5929 static void
5930 free_private_key_attr(private_key_obj_t *pbk, CK_KEY_TYPE key_type)
5932 if (pbk == NULL) {
5933 return;
5936 switch (key_type) {
5937 case CKK_RSA:
5938 bigint_attr_cleanup(KEY_PRI_RSA_MOD(pbk));
5939 bigint_attr_cleanup(KEY_PRI_RSA_PUBEXPO(pbk));
5940 bigint_attr_cleanup(KEY_PRI_RSA_PRIEXPO(pbk));
5941 bigint_attr_cleanup(KEY_PRI_RSA_PRIME1(pbk));
5942 bigint_attr_cleanup(KEY_PRI_RSA_PRIME2(pbk));
5943 bigint_attr_cleanup(KEY_PRI_RSA_EXPO1(pbk));
5944 bigint_attr_cleanup(KEY_PRI_RSA_EXPO2(pbk));
5945 bigint_attr_cleanup(KEY_PRI_RSA_COEF(pbk));
5946 break;
5947 case CKK_DSA:
5948 bigint_attr_cleanup(KEY_PRI_DSA_PRIME(pbk));
5949 bigint_attr_cleanup(KEY_PRI_DSA_SUBPRIME(pbk));
5950 bigint_attr_cleanup(KEY_PRI_DSA_BASE(pbk));
5951 bigint_attr_cleanup(KEY_PRI_DSA_VALUE(pbk));
5952 break;
5953 case CKK_DH:
5954 bigint_attr_cleanup(KEY_PRI_DH_PRIME(pbk));
5955 bigint_attr_cleanup(KEY_PRI_DH_BASE(pbk));
5956 bigint_attr_cleanup(KEY_PRI_DH_VALUE(pbk));
5957 break;
5958 case CKK_EC:
5959 bigint_attr_cleanup(KEY_PRI_EC_VALUE(pbk));
5960 break;
5961 case CKK_X9_42_DH:
5962 bigint_attr_cleanup(KEY_PRI_DH942_PRIME(pbk));
5963 bigint_attr_cleanup(KEY_PRI_DH942_SUBPRIME(pbk));
5964 bigint_attr_cleanup(KEY_PRI_DH942_BASE(pbk));
5965 bigint_attr_cleanup(KEY_PRI_DH942_VALUE(pbk));
5966 break;
5967 default:
5968 break;
5970 free(pbk);
5973 CK_RV
5974 soft_copy_private_key_attr(private_key_obj_t *old_pri_key_obj_p,
5975 private_key_obj_t **new_pri_key_obj_p, CK_KEY_TYPE key_type)
5977 CK_RV rv = CKR_OK;
5978 private_key_obj_t *pbk;
5980 pbk = calloc(1, sizeof (private_key_obj_t));
5981 if (pbk == NULL) {
5982 return (CKR_HOST_MEMORY);
5985 switch (key_type) {
5986 case CKK_RSA:
5987 (void) memcpy(KEY_PRI_RSA(pbk),
5988 KEY_PRI_RSA(old_pri_key_obj_p),
5989 sizeof (rsa_pri_key_t));
5990 /* copy modulus */
5991 rv = copy_bigint(KEY_PRI_RSA_MOD(pbk),
5992 KEY_PRI_RSA_MOD(old_pri_key_obj_p));
5993 if (rv != CKR_OK) {
5994 free_private_key_attr(pbk, key_type);
5995 return (rv);
5997 /* copy public exponent */
5998 rv = copy_bigint(KEY_PRI_RSA_PUBEXPO(pbk),
5999 KEY_PRI_RSA_PUBEXPO(old_pri_key_obj_p));
6000 if (rv != CKR_OK) {
6001 free_private_key_attr(pbk, key_type);
6002 return (rv);
6004 /* copy private exponent */
6005 rv = copy_bigint(KEY_PRI_RSA_PRIEXPO(pbk),
6006 KEY_PRI_RSA_PRIEXPO(old_pri_key_obj_p));
6007 if (rv != CKR_OK) {
6008 free_private_key_attr(pbk, key_type);
6009 return (rv);
6011 /* copy prime_1 */
6012 rv = copy_bigint(KEY_PRI_RSA_PRIME1(pbk),
6013 KEY_PRI_RSA_PRIME1(old_pri_key_obj_p));
6014 if (rv != CKR_OK) {
6015 free_private_key_attr(pbk, key_type);
6016 return (rv);
6018 /* copy prime_2 */
6019 rv = copy_bigint(KEY_PRI_RSA_PRIME2(pbk),
6020 KEY_PRI_RSA_PRIME2(old_pri_key_obj_p));
6021 if (rv != CKR_OK) {
6022 free_private_key_attr(pbk, key_type);
6023 return (rv);
6025 /* copy exponent_1 */
6026 rv = copy_bigint(KEY_PRI_RSA_EXPO1(pbk),
6027 KEY_PRI_RSA_EXPO1(old_pri_key_obj_p));
6028 if (rv != CKR_OK) {
6029 free_private_key_attr(pbk, key_type);
6030 return (rv);
6032 /* copy exponent_2 */
6033 rv = copy_bigint(KEY_PRI_RSA_EXPO2(pbk),
6034 KEY_PRI_RSA_EXPO2(old_pri_key_obj_p));
6035 if (rv != CKR_OK) {
6036 free_private_key_attr(pbk, key_type);
6037 return (rv);
6039 /* copy coefficient */
6040 rv = copy_bigint(KEY_PRI_RSA_COEF(pbk),
6041 KEY_PRI_RSA_COEF(old_pri_key_obj_p));
6042 if (rv != CKR_OK) {
6043 free_private_key_attr(pbk, key_type);
6044 return (rv);
6046 break;
6047 case CKK_DSA:
6048 (void) memcpy(KEY_PRI_DSA(pbk),
6049 KEY_PRI_DSA(old_pri_key_obj_p),
6050 sizeof (dsa_pri_key_t));
6052 /* copy prime */
6053 rv = copy_bigint(KEY_PRI_DSA_PRIME(pbk),
6054 KEY_PRI_DSA_PRIME(old_pri_key_obj_p));
6055 if (rv != CKR_OK) {
6056 free_private_key_attr(pbk, key_type);
6057 return (rv);
6060 /* copy subprime */
6061 rv = copy_bigint(KEY_PRI_DSA_SUBPRIME(pbk),
6062 KEY_PRI_DSA_SUBPRIME(old_pri_key_obj_p));
6063 if (rv != CKR_OK) {
6064 free_private_key_attr(pbk, key_type);
6065 return (rv);
6068 /* copy base */
6069 rv = copy_bigint(KEY_PRI_DSA_BASE(pbk),
6070 KEY_PRI_DSA_BASE(old_pri_key_obj_p));
6071 if (rv != CKR_OK) {
6072 free_private_key_attr(pbk, key_type);
6073 return (rv);
6076 /* copy value */
6077 rv = copy_bigint(KEY_PRI_DSA_VALUE(pbk),
6078 KEY_PRI_DSA_VALUE(old_pri_key_obj_p));
6079 if (rv != CKR_OK) {
6080 free_private_key_attr(pbk, key_type);
6081 return (rv);
6083 break;
6084 case CKK_DH:
6085 (void) memcpy(KEY_PRI_DH(pbk),
6086 KEY_PRI_DH(old_pri_key_obj_p),
6087 sizeof (dh_pri_key_t));
6089 /* copy prime */
6090 rv = copy_bigint(KEY_PRI_DH_PRIME(pbk),
6091 KEY_PRI_DH_PRIME(old_pri_key_obj_p));
6092 if (rv != CKR_OK) {
6093 free_private_key_attr(pbk, key_type);
6094 return (rv);
6097 /* copy base */
6098 rv = copy_bigint(KEY_PRI_DH_BASE(pbk),
6099 KEY_PRI_DH_BASE(old_pri_key_obj_p));
6100 if (rv != CKR_OK) {
6101 free_private_key_attr(pbk, key_type);
6102 return (rv);
6105 /* copy value */
6106 rv = copy_bigint(KEY_PRI_DH_VALUE(pbk),
6107 KEY_PRI_DH_VALUE(old_pri_key_obj_p));
6108 if (rv != CKR_OK) {
6109 free_private_key_attr(pbk, key_type);
6110 return (rv);
6112 break;
6113 case CKK_EC:
6114 (void) memcpy(KEY_PRI_EC(pbk),
6115 KEY_PRI_EC(old_pri_key_obj_p),
6116 sizeof (ec_pri_key_t));
6118 /* copy value */
6119 rv = copy_bigint(KEY_PRI_EC_VALUE(pbk),
6120 KEY_PRI_EC_VALUE(old_pri_key_obj_p));
6121 if (rv != CKR_OK) {
6122 free_private_key_attr(pbk, key_type);
6123 return (rv);
6125 break;
6126 case CKK_X9_42_DH:
6127 (void) memcpy(KEY_PRI_DH942(pbk),
6128 KEY_PRI_DH942(old_pri_key_obj_p),
6129 sizeof (dh942_pri_key_t));
6131 /* copy prime */
6132 rv = copy_bigint(KEY_PRI_DH942_PRIME(pbk),
6133 KEY_PRI_DH942_PRIME(old_pri_key_obj_p));
6134 if (rv != CKR_OK) {
6135 free_private_key_attr(pbk, key_type);
6136 return (rv);
6139 /* copy subprime */
6140 rv = copy_bigint(KEY_PRI_DH942_SUBPRIME(pbk),
6141 KEY_PRI_DH942_SUBPRIME(old_pri_key_obj_p));
6142 if (rv != CKR_OK) {
6143 free_private_key_attr(pbk, key_type);
6144 return (rv);
6147 /* copy base */
6148 rv = copy_bigint(KEY_PRI_DH942_BASE(pbk),
6149 KEY_PRI_DH942_BASE(old_pri_key_obj_p));
6150 if (rv != CKR_OK) {
6151 free_private_key_attr(pbk, key_type);
6152 return (rv);
6155 /* copy value */
6156 rv = copy_bigint(KEY_PRI_DH942_VALUE(pbk),
6157 KEY_PRI_DH942_VALUE(old_pri_key_obj_p));
6158 if (rv != CKR_OK) {
6159 free_private_key_attr(pbk, key_type);
6160 return (rv);
6162 break;
6163 default:
6164 break;
6166 *new_pri_key_obj_p = pbk;
6167 return (rv);
6170 static void
6171 free_domain_attr(domain_obj_t *domain, CK_KEY_TYPE key_type)
6173 if (domain == NULL) {
6174 return;
6177 switch (key_type) {
6178 case CKK_DSA:
6179 bigint_attr_cleanup(KEY_DOM_DSA_PRIME(domain));
6180 bigint_attr_cleanup(KEY_DOM_DSA_SUBPRIME(domain));
6181 bigint_attr_cleanup(KEY_DOM_DSA_BASE(domain));
6182 break;
6183 case CKK_DH:
6184 bigint_attr_cleanup(KEY_DOM_DH_PRIME(domain));
6185 bigint_attr_cleanup(KEY_DOM_DH_BASE(domain));
6186 break;
6187 case CKK_X9_42_DH:
6188 bigint_attr_cleanup(KEY_DOM_DH942_PRIME(domain));
6189 bigint_attr_cleanup(KEY_DOM_DH942_SUBPRIME(domain));
6190 bigint_attr_cleanup(KEY_DOM_DH942_BASE(domain));
6191 break;
6192 default:
6193 break;
6195 free(domain);
6198 CK_RV
6199 soft_copy_domain_attr(domain_obj_t *old_domain_obj_p,
6200 domain_obj_t **new_domain_obj_p, CK_KEY_TYPE key_type)
6202 CK_RV rv = CKR_OK;
6203 domain_obj_t *domain;
6205 domain = calloc(1, sizeof (domain_obj_t));
6206 if (domain == NULL) {
6207 return (CKR_HOST_MEMORY);
6210 switch (key_type) {
6211 case CKK_DSA:
6212 (void) memcpy(KEY_DOM_DSA(domain),
6213 KEY_DOM_DSA(old_domain_obj_p),
6214 sizeof (dsa_dom_key_t));
6216 /* copy prime */
6217 rv = copy_bigint(KEY_DOM_DSA_PRIME(domain),
6218 KEY_DOM_DSA_PRIME(old_domain_obj_p));
6219 if (rv != CKR_OK) {
6220 free_domain_attr(domain, key_type);
6221 return (rv);
6224 /* copy subprime */
6225 rv = copy_bigint(KEY_DOM_DSA_SUBPRIME(domain),
6226 KEY_DOM_DSA_SUBPRIME(old_domain_obj_p));
6227 if (rv != CKR_OK) {
6228 free_domain_attr(domain, key_type);
6229 return (rv);
6232 /* copy base */
6233 rv = copy_bigint(KEY_DOM_DSA_BASE(domain),
6234 KEY_DOM_DSA_BASE(old_domain_obj_p));
6235 if (rv != CKR_OK) {
6236 free_domain_attr(domain, key_type);
6237 return (rv);
6240 break;
6241 case CKK_DH:
6242 (void) memcpy(KEY_DOM_DH(domain),
6243 KEY_DOM_DH(old_domain_obj_p),
6244 sizeof (dh_dom_key_t));
6246 /* copy prime */
6247 rv = copy_bigint(KEY_DOM_DH_PRIME(domain),
6248 KEY_DOM_DH_PRIME(old_domain_obj_p));
6249 if (rv != CKR_OK) {
6250 free_domain_attr(domain, key_type);
6251 return (rv);
6254 /* copy base */
6255 rv = copy_bigint(KEY_DOM_DH_BASE(domain),
6256 KEY_DOM_DH_BASE(old_domain_obj_p));
6257 if (rv != CKR_OK) {
6258 free_domain_attr(domain, key_type);
6259 return (rv);
6262 break;
6263 case CKK_X9_42_DH:
6264 (void) memcpy(KEY_DOM_DH942(domain),
6265 KEY_DOM_DH942(old_domain_obj_p),
6266 sizeof (dh942_dom_key_t));
6268 /* copy prime */
6269 rv = copy_bigint(KEY_DOM_DH942_PRIME(domain),
6270 KEY_DOM_DH942_PRIME(old_domain_obj_p));
6271 if (rv != CKR_OK) {
6272 free_domain_attr(domain, key_type);
6273 return (rv);
6276 /* copy subprime */
6277 rv = copy_bigint(KEY_DOM_DH942_SUBPRIME(domain),
6278 KEY_DOM_DH942_SUBPRIME(old_domain_obj_p));
6279 if (rv != CKR_OK) {
6280 free_domain_attr(domain, key_type);
6281 return (rv);
6284 /* copy base */
6285 rv = copy_bigint(KEY_DOM_DH942_BASE(domain),
6286 KEY_DOM_DH942_BASE(old_domain_obj_p));
6287 if (rv != CKR_OK) {
6288 free_domain_attr(domain, key_type);
6289 return (rv);
6292 break;
6293 default:
6294 break;
6296 *new_domain_obj_p = domain;
6297 return (rv);
6300 CK_RV
6301 soft_copy_secret_key_attr(secret_key_obj_t *old_secret_key_obj_p,
6302 secret_key_obj_t **new_secret_key_obj_p)
6304 secret_key_obj_t *sk;
6306 sk = malloc(sizeof (secret_key_obj_t));
6307 if (sk == NULL) {
6308 return (CKR_HOST_MEMORY);
6310 (void) memcpy(sk, old_secret_key_obj_p, sizeof (secret_key_obj_t));
6312 /* copy the secret key value */
6313 sk->sk_value = malloc((sizeof (CK_BYTE) * sk->sk_value_len));
6314 if (sk->sk_value == NULL) {
6315 free(sk);
6316 return (CKR_HOST_MEMORY);
6318 (void) memcpy(sk->sk_value, old_secret_key_obj_p->sk_value,
6319 (sizeof (CK_BYTE) * sk->sk_value_len));
6322 * Copy the pre-expanded key schedule.
6324 if (old_secret_key_obj_p->key_sched != NULL &&
6325 old_secret_key_obj_p->keysched_len > 0) {
6326 sk->key_sched = malloc(old_secret_key_obj_p->keysched_len);
6327 if (sk->key_sched == NULL) {
6328 free(sk);
6329 return (CKR_HOST_MEMORY);
6331 sk->keysched_len = old_secret_key_obj_p->keysched_len;
6332 (void) memcpy(sk->key_sched, old_secret_key_obj_p->key_sched,
6333 sk->keysched_len);
6336 *new_secret_key_obj_p = sk;
6338 return (CKR_OK);
6342 * If CKA_CLASS not given, guess CKA_CLASS using
6343 * attributes on template .
6345 * Some attributes are specific to an object class. If one or more
6346 * of these attributes are in the template, make a list of classes
6347 * that can have these attributes. This would speed up the search later,
6348 * because we can immediately skip an object if the class of that
6349 * object can not possibly contain one of the attributes.
6352 void
6353 soft_process_find_attr(CK_OBJECT_CLASS *pclasses,
6354 CK_ULONG *num_result_pclasses, CK_ATTRIBUTE_PTR pTemplate,
6355 CK_ULONG ulCount)
6357 ulong_t i;
6358 int j;
6359 boolean_t pub_found = B_FALSE,
6360 priv_found = B_FALSE,
6361 secret_found = B_FALSE,
6362 domain_found = B_FALSE,
6363 hardware_found = B_FALSE,
6364 cert_found = B_FALSE;
6365 int num_pub_key_attrs, num_priv_key_attrs,
6366 num_secret_key_attrs, num_domain_attrs,
6367 num_hardware_attrs, num_cert_attrs;
6368 int num_pclasses = 0;
6370 for (i = 0; i < ulCount; i++) {
6371 if (pTemplate[i].type == CKA_CLASS) {
6373 * don't need to guess the class, it is specified.
6374 * Just record the class, and return.
6376 pclasses[0] =
6377 (*((CK_OBJECT_CLASS *)pTemplate[i].pValue));
6378 *num_result_pclasses = 1;
6379 return;
6383 num_pub_key_attrs =
6384 sizeof (PUB_KEY_ATTRS) / sizeof (CK_ATTRIBUTE_TYPE);
6385 num_priv_key_attrs =
6386 sizeof (PRIV_KEY_ATTRS) / sizeof (CK_ATTRIBUTE_TYPE);
6387 num_secret_key_attrs =
6388 sizeof (SECRET_KEY_ATTRS) / sizeof (CK_ATTRIBUTE_TYPE);
6389 num_domain_attrs =
6390 sizeof (DOMAIN_ATTRS) / sizeof (CK_ATTRIBUTE_TYPE);
6391 num_hardware_attrs =
6392 sizeof (HARDWARE_ATTRS) / sizeof (CK_ATTRIBUTE_TYPE);
6393 num_cert_attrs =
6394 sizeof (CERT_ATTRS) / sizeof (CK_ATTRIBUTE_TYPE);
6397 * Get the list of objects class that might contain
6398 * some attributes.
6400 for (i = 0; i < ulCount; i++) {
6402 * only check if this attribute can belong to public key object
6403 * class if public key object isn't already in the list
6405 if (!pub_found) {
6406 for (j = 0; j < num_pub_key_attrs; j++) {
6407 if (pTemplate[i].type == PUB_KEY_ATTRS[j]) {
6408 pub_found = B_TRUE;
6409 pclasses[num_pclasses++] =
6410 CKO_PUBLIC_KEY;
6411 break;
6416 if (!priv_found) {
6417 for (j = 0; j < num_priv_key_attrs; j++) {
6418 if (pTemplate[i].type == PRIV_KEY_ATTRS[j]) {
6419 priv_found = B_TRUE;
6420 pclasses[num_pclasses++] =
6421 CKO_PRIVATE_KEY;
6422 break;
6427 if (!secret_found) {
6428 for (j = 0; j < num_secret_key_attrs; j++) {
6429 if (pTemplate[i].type == SECRET_KEY_ATTRS[j]) {
6430 secret_found = B_TRUE;
6431 pclasses[num_pclasses++] =
6432 CKO_SECRET_KEY;
6433 break;
6438 if (!domain_found) {
6439 for (j = 0; j < num_domain_attrs; j++) {
6440 if (pTemplate[i].type == DOMAIN_ATTRS[j]) {
6441 domain_found = B_TRUE;
6442 pclasses[num_pclasses++] =
6443 CKO_DOMAIN_PARAMETERS;
6444 break;
6449 if (!hardware_found) {
6450 for (j = 0; j < num_hardware_attrs; j++) {
6451 if (pTemplate[i].type == HARDWARE_ATTRS[j]) {
6452 hardware_found = B_TRUE;
6453 pclasses[num_pclasses++] =
6454 CKO_HW_FEATURE;
6455 break;
6460 if (!cert_found) {
6461 for (j = 0; j < num_cert_attrs; j++) {
6462 if (pTemplate[i].type == CERT_ATTRS[j]) {
6463 cert_found = B_TRUE;
6464 pclasses[num_pclasses++] =
6465 CKO_CERTIFICATE;
6466 break;
6471 *num_result_pclasses = num_pclasses;
6474 boolean_t
6475 soft_find_match_attrs(soft_object_t *obj, CK_OBJECT_CLASS *pclasses,
6476 CK_ULONG num_pclasses, CK_ATTRIBUTE *template, CK_ULONG num_attr)
6478 ulong_t i;
6479 CK_ATTRIBUTE *tmpl_attr, *obj_attr;
6480 cert_attr_t *cert_attr;
6481 uint64_t attr_mask;
6482 biginteger_t *bigint;
6483 boolean_t compare_attr, compare_bigint, compare_boolean;
6484 boolean_t compare_cert_val, compare_cert_type;
6487 * Check if the class of this object match with any
6488 * of object classes that can possibly contain the
6489 * requested attributes.
6491 if (num_pclasses > 0) {
6492 for (i = 0; i < num_pclasses; i++) {
6493 if (obj->class == pclasses[i]) {
6494 break;
6497 if (i == num_pclasses) {
6499 * this object can't possibly contain one or
6500 * more attributes, don't need to check this object
6502 return (B_FALSE);
6506 /* need to examine everything */
6507 for (i = 0; i < num_attr; i++) {
6508 tmpl_attr = &(template[i]);
6509 compare_attr = B_FALSE;
6510 compare_bigint = B_FALSE;
6511 compare_boolean = B_FALSE;
6512 compare_cert_val = B_FALSE;
6513 compare_cert_type = B_FALSE;
6514 switch (tmpl_attr->type) {
6515 /* First, check the most common attributes */
6516 case CKA_CLASS:
6517 if (*((CK_OBJECT_CLASS *)tmpl_attr->pValue) !=
6518 obj->class) {
6519 return (B_FALSE);
6521 break;
6522 case CKA_KEY_TYPE:
6523 if (*((CK_KEY_TYPE *)tmpl_attr->pValue) !=
6524 obj->key_type) {
6525 return (B_FALSE);
6527 break;
6528 case CKA_ENCRYPT:
6529 attr_mask = (obj->bool_attr_mask) & ENCRYPT_BOOL_ON;
6530 compare_boolean = B_TRUE;
6531 break;
6532 case CKA_DECRYPT:
6533 attr_mask = (obj->bool_attr_mask) & DECRYPT_BOOL_ON;
6534 compare_boolean = B_TRUE;
6535 break;
6536 case CKA_WRAP:
6537 attr_mask = (obj->bool_attr_mask) & WRAP_BOOL_ON;
6538 compare_boolean = B_TRUE;
6539 break;
6540 case CKA_UNWRAP:
6541 attr_mask = (obj->bool_attr_mask) & UNWRAP_BOOL_ON;
6542 compare_boolean = B_TRUE;
6543 break;
6544 case CKA_SIGN:
6545 attr_mask = (obj->bool_attr_mask) & SIGN_BOOL_ON;
6546 compare_boolean = B_TRUE;
6547 break;
6548 case CKA_SIGN_RECOVER:
6549 attr_mask = (obj->bool_attr_mask) &
6550 SIGN_RECOVER_BOOL_ON;
6551 compare_boolean = B_TRUE;
6552 break;
6553 case CKA_VERIFY:
6554 attr_mask = (obj->bool_attr_mask) & VERIFY_BOOL_ON;
6555 compare_boolean = B_TRUE;
6556 break;
6557 case CKA_VERIFY_RECOVER:
6558 attr_mask = (obj->bool_attr_mask) &
6559 VERIFY_RECOVER_BOOL_ON;
6560 compare_boolean = B_TRUE;
6561 break;
6562 case CKA_DERIVE:
6563 attr_mask = (obj->bool_attr_mask) & DERIVE_BOOL_ON;
6564 compare_boolean = B_TRUE;
6565 break;
6566 case CKA_LOCAL:
6567 attr_mask = (obj->bool_attr_mask) & LOCAL_BOOL_ON;
6568 compare_boolean = B_TRUE;
6569 break;
6570 case CKA_SENSITIVE:
6571 attr_mask = (obj->bool_attr_mask) & SENSITIVE_BOOL_ON;
6572 compare_boolean = B_TRUE;
6573 break;
6574 case CKA_SECONDARY_AUTH:
6575 attr_mask = (obj->bool_attr_mask) &
6576 SECONDARY_AUTH_BOOL_ON;
6577 compare_boolean = B_TRUE;
6578 break;
6579 case CKA_TRUSTED:
6580 attr_mask = (obj->bool_attr_mask) & TRUSTED_BOOL_ON;
6581 compare_boolean = B_TRUE;
6582 break;
6583 case CKA_EXTRACTABLE:
6584 attr_mask = (obj->bool_attr_mask) &
6585 EXTRACTABLE_BOOL_ON;
6586 compare_boolean = B_TRUE;
6587 break;
6588 case CKA_ALWAYS_SENSITIVE:
6589 attr_mask = (obj->bool_attr_mask) &
6590 ALWAYS_SENSITIVE_BOOL_ON;
6591 compare_boolean = B_TRUE;
6592 break;
6593 case CKA_NEVER_EXTRACTABLE:
6594 attr_mask = (obj->bool_attr_mask) &
6595 NEVER_EXTRACTABLE_BOOL_ON;
6596 compare_boolean = B_TRUE;
6597 break;
6598 case CKA_TOKEN:
6599 attr_mask = (obj->object_type) & TOKEN_OBJECT;
6600 compare_boolean = B_TRUE;
6601 break;
6602 case CKA_PRIVATE:
6603 attr_mask = (obj->object_type) & PRIVATE_OBJECT;
6604 compare_boolean = B_TRUE;
6605 break;
6606 case CKA_MODIFIABLE:
6608 CK_BBOOL bval;
6609 attr_mask = (obj->bool_attr_mask) &
6610 NOT_MODIFIABLE_BOOL_ON;
6612 if (attr_mask) {
6613 bval = FALSE;
6614 } else {
6615 bval = TRUE;
6617 if (bval != *((CK_BBOOL *)tmpl_attr->pValue)) {
6618 return (B_FALSE);
6620 break;
6622 case CKA_OWNER:
6624 * For X.509 attribute certificate object, get its
6625 * CKA_OWNER attribute from the x509_attr_cert_t struct.
6627 if ((obj->class == CKO_CERTIFICATE) &&
6628 (obj->cert_type == CKC_X_509_ATTR_CERT)) {
6629 cert_attr = X509_ATTR_CERT_OWNER(obj);
6630 compare_cert_val = B_TRUE;
6632 break;
6633 case CKA_SUBJECT:
6635 * For X.509 certificate object, get its CKA_SUBJECT
6636 * attribute from the x509_cert_t struct (not from
6637 * the extra_attrlistp).
6639 if ((obj->class == CKO_CERTIFICATE) &&
6640 (obj->cert_type == CKC_X_509)) {
6641 cert_attr = X509_CERT_SUBJECT(obj);
6642 compare_cert_val = B_TRUE;
6643 break;
6645 /*FALLTHRU*/
6646 case CKA_ID:
6647 case CKA_START_DATE:
6648 case CKA_END_DATE:
6649 case CKA_KEY_GEN_MECHANISM:
6650 case CKA_LABEL:
6651 case CKA_ISSUER:
6652 case CKA_SERIAL_NUMBER:
6653 case CKA_AC_ISSUER:
6654 case CKA_ATTR_TYPES:
6655 /* find these attributes from extra_attrlistp */
6656 obj_attr = get_extra_attr(tmpl_attr->type, obj);
6657 compare_attr = B_TRUE;
6658 break;
6659 case CKA_CERTIFICATE_TYPE:
6660 compare_cert_type = B_TRUE;
6661 break;
6662 case CKA_VALUE_LEN:
6663 /* only secret key has this attribute */
6664 if (obj->class == CKO_SECRET_KEY) {
6665 if (*((CK_ULONG *)tmpl_attr->pValue) !=
6666 OBJ_SEC_VALUE_LEN(obj)) {
6667 return (B_FALSE);
6669 } else {
6670 return (B_FALSE);
6672 break;
6673 case CKA_VALUE:
6674 switch (obj->class) {
6675 case CKO_SECRET_KEY:
6677 * secret_key_obj_t is the same as
6678 * biginteger_t
6680 bigint = (biginteger_t *)OBJ_SEC(obj);
6681 compare_bigint = B_TRUE;
6682 break;
6683 case CKO_PRIVATE_KEY:
6684 if (obj->key_type == CKK_DSA) {
6685 bigint = OBJ_PRI_DSA_VALUE(obj);
6686 } else if (obj->key_type == CKK_DH) {
6687 bigint = OBJ_PRI_DH_VALUE(obj);
6688 } else if (obj->key_type == CKK_X9_42_DH) {
6689 bigint = OBJ_PRI_DH942_VALUE(obj);
6690 } else {
6691 return (B_FALSE);
6693 compare_bigint = B_TRUE;
6694 break;
6695 case CKO_PUBLIC_KEY:
6696 if (obj->key_type == CKK_DSA) {
6697 bigint = OBJ_PUB_DSA_VALUE(obj);
6698 } else if (obj->key_type == CKK_DH) {
6699 bigint = OBJ_PUB_DH_VALUE(obj);
6700 } else if (obj->key_type == CKK_X9_42_DH) {
6701 bigint = OBJ_PUB_DH942_VALUE(obj);
6702 } else {
6703 return (B_FALSE);
6705 compare_bigint = B_TRUE;
6706 break;
6707 case CKO_CERTIFICATE:
6708 if (obj->cert_type == CKC_X_509) {
6709 cert_attr = X509_CERT_VALUE(obj);
6710 } else if (obj->cert_type ==
6711 CKC_X_509_ATTR_CERT) {
6712 cert_attr = X509_ATTR_CERT_VALUE(obj);
6714 compare_cert_val = B_TRUE;
6715 break;
6716 default:
6717 return (B_FALSE);
6719 break;
6720 case CKA_MODULUS:
6721 /* only RSA public and private key have this attr */
6722 if (obj->key_type == CKK_RSA) {
6723 if (obj->class == CKO_PUBLIC_KEY) {
6724 bigint = OBJ_PUB_RSA_MOD(obj);
6725 } else if (obj->class == CKO_PRIVATE_KEY) {
6726 bigint = OBJ_PRI_RSA_MOD(obj);
6727 } else {
6728 return (B_FALSE);
6730 compare_bigint = B_TRUE;
6731 } else {
6732 return (B_FALSE);
6734 break;
6735 case CKA_MODULUS_BITS:
6736 /* only RSA public key has this attribute */
6737 if ((obj->key_type == CKK_RSA) &&
6738 (obj->class == CKO_PUBLIC_KEY)) {
6739 CK_ULONG mod_bits = OBJ_PUB_RSA_MOD_BITS(obj);
6740 if (mod_bits !=
6741 *((CK_ULONG *)tmpl_attr->pValue)) {
6742 return (B_FALSE);
6744 } else {
6745 return (B_FALSE);
6747 break;
6748 case CKA_PUBLIC_EXPONENT:
6749 /* only RSA public and private key have this attr */
6750 if (obj->key_type == CKK_RSA) {
6751 if (obj->class == CKO_PUBLIC_KEY) {
6752 bigint = OBJ_PUB_RSA_PUBEXPO(obj);
6753 } else if (obj->class == CKO_PRIVATE_KEY) {
6754 bigint = OBJ_PRI_RSA_PUBEXPO(obj);
6755 } else {
6756 return (B_FALSE);
6758 compare_bigint = B_TRUE;
6759 } else {
6760 return (B_FALSE);
6762 break;
6763 case CKA_PRIVATE_EXPONENT:
6764 /* only RSA private key has this attribute */
6765 if ((obj->key_type == CKK_RSA) &&
6766 (obj->class == CKO_PRIVATE_KEY)) {
6767 bigint = OBJ_PRI_RSA_PRIEXPO(obj);
6768 compare_bigint = B_TRUE;
6769 } else {
6770 return (B_FALSE);
6772 break;
6773 case CKA_PRIME_1:
6774 /* only RSA private key has this attribute */
6775 if ((obj->key_type == CKK_RSA) &&
6776 (obj->class == CKO_PRIVATE_KEY)) {
6777 bigint = OBJ_PRI_RSA_PRIME1(obj);
6778 compare_bigint = B_TRUE;
6779 } else {
6780 return (B_FALSE);
6782 break;
6783 case CKA_PRIME_2:
6784 /* only RSA private key has this attribute */
6785 if ((obj->key_type == CKK_RSA) &&
6786 (obj->class == CKO_PRIVATE_KEY)) {
6787 bigint = OBJ_PRI_RSA_PRIME2(obj);
6788 compare_bigint = B_TRUE;
6789 } else {
6790 return (B_FALSE);
6792 break;
6793 case CKA_EXPONENT_1:
6794 /* only RSA private key has this attribute */
6795 if ((obj->key_type == CKK_RSA) &&
6796 (obj->class == CKO_PRIVATE_KEY)) {
6797 bigint = OBJ_PRI_RSA_EXPO1(obj);
6798 compare_bigint = B_TRUE;
6799 } else {
6800 return (B_FALSE);
6802 break;
6803 case CKA_EXPONENT_2:
6804 /* only RSA private key has this attribute */
6805 if ((obj->key_type == CKK_RSA) &&
6806 (obj->class == CKO_PRIVATE_KEY)) {
6807 bigint = OBJ_PRI_RSA_EXPO2(obj);
6808 compare_bigint = B_TRUE;
6809 } else {
6810 return (B_FALSE);
6812 break;
6813 case CKA_COEFFICIENT:
6814 /* only RSA private key has this attribute */
6815 if ((obj->key_type == CKK_RSA) &&
6816 (obj->class == CKO_PRIVATE_KEY)) {
6817 bigint = OBJ_PRI_RSA_COEF(obj);
6818 compare_bigint = B_TRUE;
6819 } else {
6820 return (B_FALSE);
6822 break;
6823 case CKA_VALUE_BITS:
6824 /* only Diffie-Hellman private key has this attr */
6825 if ((obj->key_type == CKK_DH) &&
6826 (obj->class == CKO_PRIVATE_KEY)) {
6827 CK_ULONG val_bits = OBJ_PRI_DH_VAL_BITS(obj);
6828 if (val_bits !=
6829 *((CK_ULONG *)tmpl_attr->pValue)) {
6830 return (B_FALSE);
6832 } else {
6833 return (B_FALSE);
6835 break;
6836 case CKA_PRIME:
6837 if (obj->class == CKO_PUBLIC_KEY) {
6838 switch (obj->key_type) {
6839 case CKK_DSA:
6840 bigint = OBJ_PUB_DSA_PRIME(obj);
6841 break;
6842 case CKK_DH:
6843 bigint = OBJ_PUB_DH_PRIME(obj);
6844 break;
6845 case CKK_X9_42_DH:
6846 bigint = OBJ_PUB_DH942_PRIME(obj);
6847 break;
6848 default:
6849 return (B_FALSE);
6851 } else if (obj->class == CKO_PRIVATE_KEY) {
6852 switch (obj->key_type) {
6853 case CKK_DSA:
6854 bigint = OBJ_PRI_DSA_PRIME(obj);
6855 break;
6856 case CKK_DH:
6857 bigint = OBJ_PRI_DH_PRIME(obj);
6858 break;
6859 case CKK_X9_42_DH:
6860 bigint = OBJ_PRI_DH942_PRIME(obj);
6861 break;
6862 default:
6863 return (B_FALSE);
6865 } else if (obj->class == CKO_DOMAIN_PARAMETERS) {
6866 switch (obj->key_type) {
6867 case CKK_DSA:
6868 bigint = OBJ_DOM_DSA_PRIME(obj);
6869 break;
6870 case CKK_DH:
6871 bigint = OBJ_DOM_DH_PRIME(obj);
6872 break;
6873 case CKK_X9_42_DH:
6874 bigint = OBJ_DOM_DH942_PRIME(obj);
6875 break;
6876 default:
6877 return (B_FALSE);
6879 } else {
6880 return (B_FALSE);
6882 compare_bigint = B_TRUE;
6883 break;
6884 case CKA_SUBPRIME:
6885 if (obj->class == CKO_PUBLIC_KEY) {
6886 switch (obj->key_type) {
6887 case CKK_DSA:
6888 bigint = OBJ_PUB_DSA_SUBPRIME(obj);
6889 break;
6890 case CKK_X9_42_DH:
6891 bigint = OBJ_PUB_DH942_SUBPRIME(obj);
6892 break;
6893 default:
6894 return (B_FALSE);
6896 } else if (obj->class == CKO_PRIVATE_KEY) {
6897 switch (obj->key_type) {
6898 case CKK_DSA:
6899 bigint = OBJ_PRI_DSA_SUBPRIME(obj);
6900 break;
6901 case CKK_X9_42_DH:
6902 bigint = OBJ_PRI_DH942_SUBPRIME(obj);
6903 break;
6904 default:
6905 return (B_FALSE);
6907 } else if (obj->class == CKO_DOMAIN_PARAMETERS) {
6908 switch (obj->key_type) {
6909 case CKK_DSA:
6910 bigint = OBJ_DOM_DSA_SUBPRIME(obj);
6911 break;
6912 case CKK_X9_42_DH:
6913 bigint = OBJ_DOM_DH942_SUBPRIME(obj);
6914 break;
6915 default:
6916 return (B_FALSE);
6918 } else {
6919 return (B_FALSE);
6921 compare_bigint = B_TRUE;
6922 break;
6923 case CKA_BASE:
6924 if (obj->class == CKO_PUBLIC_KEY) {
6925 switch (obj->key_type) {
6926 case CKK_DSA:
6927 bigint = OBJ_PUB_DSA_BASE(obj);
6928 break;
6929 case CKK_DH:
6930 bigint = OBJ_PUB_DH_BASE(obj);
6931 break;
6932 case CKK_X9_42_DH:
6933 bigint = OBJ_PUB_DH942_BASE(obj);
6934 break;
6935 default:
6936 return (B_FALSE);
6938 } else if (obj->class == CKO_PRIVATE_KEY) {
6939 switch (obj->key_type) {
6940 case CKK_DSA:
6941 bigint = OBJ_PRI_DSA_BASE(obj);
6942 break;
6943 case CKK_DH:
6944 bigint = OBJ_PRI_DH_BASE(obj);
6945 break;
6946 case CKK_X9_42_DH:
6947 bigint = OBJ_PRI_DH942_BASE(obj);
6948 break;
6949 default:
6950 return (B_FALSE);
6952 } else if (obj->class == CKO_DOMAIN_PARAMETERS) {
6953 switch (obj->key_type) {
6954 case CKK_DSA:
6955 bigint = OBJ_DOM_DSA_BASE(obj);
6956 break;
6957 case CKK_DH:
6958 bigint = OBJ_DOM_DH_BASE(obj);
6959 break;
6960 case CKK_X9_42_DH:
6961 bigint = OBJ_DOM_DH942_BASE(obj);
6962 break;
6963 default:
6964 return (B_FALSE);
6966 } else {
6967 return (B_FALSE);
6969 compare_bigint = B_TRUE;
6970 break;
6971 case CKA_PRIME_BITS:
6972 if (obj->class == CKO_DOMAIN_PARAMETERS) {
6973 CK_ULONG prime_bits;
6974 if (obj->key_type == CKK_DSA) {
6975 prime_bits =
6976 OBJ_DOM_DSA_PRIME_BITS(obj);
6977 } else if (obj->key_type == CKK_DH) {
6978 prime_bits =
6979 OBJ_DOM_DH_PRIME_BITS(obj);
6980 } else if (obj->key_type == CKK_X9_42_DH) {
6981 prime_bits =
6982 OBJ_DOM_DH942_PRIME_BITS(obj);
6983 } else {
6984 return (B_FALSE);
6986 if (prime_bits !=
6987 *((CK_ULONG *)tmpl_attr->pValue)) {
6988 return (B_FALSE);
6990 } else {
6991 return (B_FALSE);
6993 break;
6994 case CKA_SUBPRIME_BITS:
6995 if ((obj->class == CKO_DOMAIN_PARAMETERS) &&
6996 (obj->key_type == CKK_X9_42_DH)) {
6997 CK_ULONG subprime_bits =
6998 OBJ_DOM_DH942_SUBPRIME_BITS(obj);
6999 if (subprime_bits !=
7000 *((CK_ULONG *)tmpl_attr->pValue)) {
7001 return (B_FALSE);
7003 } else {
7004 return (B_FALSE);
7006 break;
7007 default:
7009 * any other attributes are currently not supported.
7010 * so, it's not possible for them to be in the
7011 * object
7013 return (B_FALSE);
7015 if (compare_boolean) {
7016 CK_BBOOL bval;
7018 if (attr_mask) {
7019 bval = TRUE;
7020 } else {
7021 bval = FALSE;
7023 if (bval != *((CK_BBOOL *)tmpl_attr->pValue)) {
7024 return (B_FALSE);
7026 } else if (compare_bigint) {
7027 if (bigint == NULL) {
7028 return (B_FALSE);
7030 if (tmpl_attr->ulValueLen != bigint->big_value_len) {
7031 return (B_FALSE);
7033 if (memcmp(tmpl_attr->pValue, bigint->big_value,
7034 tmpl_attr->ulValueLen) != 0) {
7035 return (B_FALSE);
7037 } else if (compare_attr) {
7038 if (obj_attr == NULL) {
7040 * The attribute type is valid, and its value
7041 * has not been initialized in the object. In
7042 * this case, it only matches the template's
7043 * attribute if the template's value length
7044 * is 0.
7046 if (tmpl_attr->ulValueLen != 0)
7047 return (B_FALSE);
7048 } else {
7049 if (tmpl_attr->ulValueLen !=
7050 obj_attr->ulValueLen) {
7051 return (B_FALSE);
7053 if (memcmp(tmpl_attr->pValue, obj_attr->pValue,
7054 tmpl_attr->ulValueLen) != 0) {
7055 return (B_FALSE);
7058 } else if (compare_cert_val) {
7059 if (cert_attr == NULL) {
7060 /* specific attribute not found */
7061 return (B_FALSE);
7063 if (tmpl_attr->ulValueLen != cert_attr->length) {
7064 return (B_FALSE);
7066 if (memcmp(tmpl_attr->pValue, cert_attr->value,
7067 tmpl_attr->ulValueLen) != 0) {
7068 return (B_FALSE);
7070 } else if (compare_cert_type) {
7071 if (memcmp(tmpl_attr->pValue, &(obj->cert_type),
7072 tmpl_attr->ulValueLen) != 0) {
7073 return (B_FALSE);
7077 return (B_TRUE);
7080 CK_ATTRIBUTE_PTR
7081 get_extra_attr(CK_ATTRIBUTE_TYPE type, soft_object_t *obj)
7083 CK_ATTRIBUTE_INFO_PTR tmp;
7085 tmp = obj->extra_attrlistp;
7086 while (tmp != NULL) {
7087 if (tmp->attr.type == type) {
7088 return (&(tmp->attr));
7090 tmp = tmp->next;
7092 /* if get there, the specified attribute is not found */
7093 return (NULL);