dmake: do not set MAKEFLAGS=k
[unleashed/tickless.git] / usr / src / lib / pkcs11 / pkcs11_softtoken / common / softAttributeUtil.c
blobb753f0f7f8eaded3f99a54c4e2a1559fe3d9e991
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 if (big_init(&n, CHARLEN2BIGNUMLEN(
1574 modulus.big_value_len)) != BIG_OK) {
1575 rv = CKR_HOST_MEMORY;
1576 big_finish(&n);
1577 goto fail_cleanup;
1579 bytestring2bignum(&n, modulus.big_value,
1580 modulus.big_value_len);
1582 modulus_bits = big_bitlength(&n);
1583 KEY_PUB_RSA_MOD_BITS(pbk) = modulus_bits;
1584 big_finish(&n);
1587 * After modulus_bits has been computed,
1588 * it is safe to move modulus and pubexpo
1589 * big integer attribute value to the
1590 * designated place in the public key object.
1592 copy_bigint_attr(&modulus,
1593 KEY_PUB_RSA_MOD(pbk));
1595 copy_bigint_attr(&pubexpo,
1596 KEY_PUB_RSA_PUBEXPO(pbk));
1597 } else {
1598 rv = CKR_TEMPLATE_INCOMPLETE;
1599 goto fail_cleanup;
1601 } else {
1602 /* mode is SOFT_GEN_KEY */
1604 if (isModulus || isPrime || isSubprime ||
1605 isBase || isValue) {
1606 rv = CKR_TEMPLATE_INCONSISTENT;
1607 goto fail_cleanup;
1611 if (isModulusBits) {
1613 * Copy big integer attribute value to the
1614 * designated place in the public key object.
1616 KEY_PUB_RSA_MOD_BITS(pbk) = modulus_bits;
1617 } else {
1618 rv = CKR_TEMPLATE_INCOMPLETE;
1619 goto fail_cleanup;
1623 * Use PKCS#11 default 0x010001 for public exponent
1624 * if not not specified in attribute template.
1626 if (!isPubExpo) {
1627 isPubExpo = 1;
1628 rv = get_bigint_attr_from_template(&pubexpo,
1629 &defpubexpo);
1630 if (rv != CKR_OK)
1631 goto fail_cleanup;
1634 * Copy big integer attribute value to the
1635 * designated place in the public key object.
1637 copy_bigint_attr(&pubexpo, KEY_PUB_RSA_PUBEXPO(pbk));
1640 break;
1642 case CKK_DSA:
1643 if (mode == SOFT_CREATE_OBJ) {
1644 if (isModulusBits || isModulus || isPubExpo) {
1645 rv = CKR_TEMPLATE_INCONSISTENT;
1646 goto fail_cleanup;
1649 if (isPrime && isSubprime && isBase && isValue) {
1650 copy_bigint_attr(&value,
1651 KEY_PUB_DSA_VALUE(pbk));
1652 } else {
1653 rv = CKR_TEMPLATE_INCOMPLETE;
1654 goto fail_cleanup;
1656 } else {
1657 if (isModulusBits || isModulus || isPubExpo ||
1658 isValue) {
1659 rv = CKR_TEMPLATE_INCONSISTENT;
1660 goto fail_cleanup;
1663 if (!(isPrime && isSubprime && isBase)) {
1664 rv = CKR_TEMPLATE_INCOMPLETE;
1665 goto fail_cleanup;
1669 copy_bigint_attr(&prime, KEY_PUB_DSA_PRIME(pbk));
1671 copy_bigint_attr(&subprime, KEY_PUB_DSA_SUBPRIME(pbk));
1673 copy_bigint_attr(&base, KEY_PUB_DSA_BASE(pbk));
1675 break;
1677 case CKK_DH:
1678 if (mode == SOFT_CREATE_OBJ) {
1679 if (isModulusBits || isModulus || isPubExpo ||
1680 isSubprime) {
1681 rv = CKR_TEMPLATE_INCONSISTENT;
1682 goto fail_cleanup;
1685 if (isPrime && isBase && isValue) {
1686 copy_bigint_attr(&value,
1687 KEY_PUB_DH_VALUE(pbk));
1688 } else {
1689 rv = CKR_TEMPLATE_INCOMPLETE;
1690 goto fail_cleanup;
1692 } else {
1693 if (isModulusBits || isModulus || isPubExpo ||
1694 isSubprime || isValue) {
1695 rv = CKR_TEMPLATE_INCONSISTENT;
1696 goto fail_cleanup;
1699 if (!(isPrime && isBase)) {
1700 rv = CKR_TEMPLATE_INCOMPLETE;
1701 goto fail_cleanup;
1705 copy_bigint_attr(&prime, KEY_PUB_DH_PRIME(pbk));
1707 copy_bigint_attr(&base, KEY_PUB_DH_BASE(pbk));
1709 break;
1711 case CKK_X9_42_DH:
1712 if (mode == SOFT_CREATE_OBJ) {
1713 if (isModulusBits || isModulus || isPubExpo) {
1714 rv = CKR_TEMPLATE_INCONSISTENT;
1715 goto fail_cleanup;
1718 if (isPrime && isSubprime && isBase && isValue) {
1719 copy_bigint_attr(&value,
1720 KEY_PUB_DH942_VALUE(pbk));
1721 } else {
1722 rv = CKR_TEMPLATE_INCOMPLETE;
1723 goto fail_cleanup;
1725 } else {
1726 if (isModulusBits || isModulus || isPubExpo ||
1727 isValue) {
1728 rv = CKR_TEMPLATE_INCONSISTENT;
1729 goto fail_cleanup;
1732 if (!(isPrime && isSubprime && isBase)) {
1733 rv = CKR_TEMPLATE_INCOMPLETE;
1734 goto fail_cleanup;
1738 copy_bigint_attr(&prime, KEY_PUB_DH942_PRIME(pbk));
1740 copy_bigint_attr(&base, KEY_PUB_DH942_BASE(pbk));
1742 copy_bigint_attr(&subprime, KEY_PUB_DH942_SUBPRIME(pbk));
1744 break;
1746 case CKK_EC:
1747 if (mode == SOFT_CREATE_OBJ) {
1748 if (isModulusBits || isModulus || isPubExpo ||
1749 isPrime || isSubprime || isBase || isValue) {
1750 rv = CKR_TEMPLATE_INCONSISTENT;
1751 goto fail_cleanup;
1753 } else if (!isECParam || !isECPoint) {
1754 rv = CKR_TEMPLATE_INCOMPLETE;
1755 goto fail_cleanup;
1757 } else {
1758 if (isModulusBits || isModulus || isPubExpo ||
1759 isPrime || isSubprime || isBase || isValue) {
1760 rv = CKR_TEMPLATE_INCONSISTENT;
1761 goto fail_cleanup;
1763 } else if (!isECParam) {
1764 rv = CKR_TEMPLATE_INCOMPLETE;
1765 goto fail_cleanup;
1769 if (isECPoint) {
1770 copy_bigint_attr(&point, KEY_PUB_EC_POINT(pbk));
1772 rv = soft_add_extra_attr(&param_tmp, new_object);
1773 if (rv != CKR_OK)
1774 goto fail_cleanup;
1775 string_attr_cleanup(&param_tmp);
1776 break;
1778 default:
1779 rv = CKR_TEMPLATE_INCONSISTENT;
1780 goto fail_cleanup;
1783 /* Set up object. */
1784 new_object->object_type = object_type;
1785 new_object->bool_attr_mask = attr_mask;
1786 if (isLabel) {
1787 rv = soft_add_extra_attr(&string_tmp, new_object);
1788 if (rv != CKR_OK)
1789 goto fail_cleanup;
1790 string_attr_cleanup(&string_tmp);
1793 return (rv);
1795 fail_cleanup:
1797 * cleanup the storage allocated to the local variables.
1799 bigint_attr_cleanup(&modulus);
1800 bigint_attr_cleanup(&pubexpo);
1801 bigint_attr_cleanup(&prime);
1802 bigint_attr_cleanup(&subprime);
1803 bigint_attr_cleanup(&base);
1804 bigint_attr_cleanup(&value);
1805 bigint_attr_cleanup(&point);
1806 string_attr_cleanup(&string_tmp);
1807 string_attr_cleanup(&param_tmp);
1810 * cleanup the storage allocated inside the object itself.
1812 soft_cleanup_object(new_object);
1814 return (rv);
1819 * Build a Private Key Object.
1821 * - Parse the object's template, and when an error is detected such as
1822 * invalid attribute type, invalid attribute value, etc., return
1823 * with appropriate return value.
1824 * - Set up attribute mask field in the object for the supplied common
1825 * attributes that have boolean type.
1826 * - Build the attribute_info struct to hold the value of each supplied
1827 * attribute that has byte array type. Link attribute_info structs
1828 * together to form the extra attribute list of the object.
1829 * - Allocate storage for the Private Key object.
1830 * - Build the Private Key object according to the key type. Allocate
1831 * storage to hold the big integer value for the supplied attributes
1832 * that are required for a certain key type.
1835 CK_RV
1836 soft_build_private_key_object(CK_ATTRIBUTE_PTR template, CK_ULONG ulAttrNum,
1837 soft_object_t *new_object, CK_ULONG mode, CK_KEY_TYPE key_type)
1839 ulong_t i;
1840 CK_KEY_TYPE keytype = (CK_KEY_TYPE)~0UL;
1841 uint64_t attr_mask = PRIVATE_KEY_DEFAULT;
1842 CK_RV rv = CKR_OK;
1843 int isLabel = 0;
1844 int isECParam = 0;
1845 /* Must set flags unless mode == SOFT_UNWRAP_KEY */
1846 int isModulus = 0;
1847 int isPriExpo = 0;
1848 int isPrime = 0;
1849 int isSubprime = 0;
1850 int isBase = 0;
1851 /* Must set flags if mode == SOFT_GEN_KEY */
1852 int isValue = 0;
1853 /* Must not set flags */
1854 int isValueBits = 0;
1855 CK_ULONG value_bits = 0;
1857 /* Private Key RSA optional */
1858 int isPubExpo = 0;
1859 int isPrime1 = 0;
1860 int isPrime2 = 0;
1861 int isExpo1 = 0;
1862 int isExpo2 = 0;
1863 int isCoef = 0;
1865 biginteger_t modulus;
1866 biginteger_t priexpo;
1867 biginteger_t prime;
1868 biginteger_t subprime;
1869 biginteger_t base;
1870 biginteger_t value;
1872 biginteger_t pubexpo;
1873 biginteger_t prime1;
1874 biginteger_t prime2;
1875 biginteger_t expo1;
1876 biginteger_t expo2;
1877 biginteger_t coef;
1878 CK_ATTRIBUTE string_tmp;
1879 CK_ATTRIBUTE param_tmp;
1880 BIGNUM x, q;
1882 private_key_obj_t *pvk;
1883 uchar_t object_type = 0;
1885 /* prevent bigint_attr_cleanup from freeing invalid attr value */
1886 (void) memset(&modulus, 0x0, sizeof (biginteger_t));
1887 (void) memset(&priexpo, 0x0, sizeof (biginteger_t));
1888 (void) memset(&prime, 0x0, sizeof (biginteger_t));
1889 (void) memset(&subprime, 0x0, sizeof (biginteger_t));
1890 (void) memset(&base, 0x0, sizeof (biginteger_t));
1891 (void) memset(&value, 0x0, sizeof (biginteger_t));
1892 (void) memset(&pubexpo, 0x0, sizeof (biginteger_t));
1893 (void) memset(&prime1, 0x0, sizeof (biginteger_t));
1894 (void) memset(&prime2, 0x0, sizeof (biginteger_t));
1895 (void) memset(&expo1, 0x0, sizeof (biginteger_t));
1896 (void) memset(&expo2, 0x0, sizeof (biginteger_t));
1897 (void) memset(&coef, 0x0, sizeof (biginteger_t));
1898 string_tmp.pValue = NULL;
1899 param_tmp.pValue = NULL;
1900 x.malloced = 0;
1901 q.malloced = 0;
1903 for (i = 0; i < ulAttrNum; i++) {
1905 /* Private Key Object Attributes */
1906 switch (template[i].type) {
1907 /* common key attributes */
1908 case CKA_KEY_TYPE:
1909 keytype = *((CK_KEY_TYPE*)template[i].pValue);
1910 break;
1912 case CKA_ID:
1913 case CKA_START_DATE:
1914 case CKA_END_DATE:
1916 /* common private key attribute */
1917 case CKA_SUBJECT:
1919 * Allocate storage to hold the attribute
1920 * value with byte array type, and add it to
1921 * the extra attribute list of the object.
1923 rv = soft_add_extra_attr(&template[i],
1924 new_object);
1925 if (rv != CKR_OK) {
1926 goto fail_cleanup;
1928 break;
1931 * The following key related attribute types must
1932 * not be specified by C_CreateObject or C_GenerateKey(Pair).
1934 case CKA_LOCAL:
1935 case CKA_KEY_GEN_MECHANISM:
1936 case CKA_AUTH_PIN_FLAGS:
1937 case CKA_ALWAYS_SENSITIVE:
1938 case CKA_NEVER_EXTRACTABLE:
1939 rv = CKR_TEMPLATE_INCONSISTENT;
1940 goto fail_cleanup;
1942 /* Key related boolean attributes */
1943 case CKA_DERIVE:
1944 if (*(CK_BBOOL *)template[i].pValue)
1945 attr_mask |= DERIVE_BOOL_ON;
1946 break;
1948 case CKA_SENSITIVE:
1949 if (*(CK_BBOOL *)template[i].pValue)
1950 attr_mask |= SENSITIVE_BOOL_ON;
1951 break;
1953 case CKA_SECONDARY_AUTH:
1954 if (*(CK_BBOOL *)template[i].pValue) {
1955 rv = CKR_ATTRIBUTE_VALUE_INVALID;
1956 goto fail_cleanup;
1958 break;
1960 case CKA_DECRYPT:
1961 if (*(CK_BBOOL *)template[i].pValue)
1962 attr_mask |= DECRYPT_BOOL_ON;
1963 else
1964 attr_mask &= ~DECRYPT_BOOL_ON;
1965 break;
1967 case CKA_SIGN:
1968 if (*(CK_BBOOL *)template[i].pValue)
1969 attr_mask |= SIGN_BOOL_ON;
1970 else
1971 attr_mask &= ~SIGN_BOOL_ON;
1972 break;
1974 case CKA_SIGN_RECOVER:
1975 if (*(CK_BBOOL *)template[i].pValue)
1976 attr_mask |= SIGN_RECOVER_BOOL_ON;
1977 else
1978 attr_mask &= ~SIGN_RECOVER_BOOL_ON;
1979 break;
1981 case CKA_UNWRAP:
1982 if (*(CK_BBOOL *)template[i].pValue)
1983 attr_mask |= UNWRAP_BOOL_ON;
1984 else
1985 attr_mask &= ~UNWRAP_BOOL_ON;
1986 break;
1988 case CKA_EXTRACTABLE:
1989 if (*(CK_BBOOL *)template[i].pValue)
1990 attr_mask |= EXTRACTABLE_BOOL_ON;
1991 else
1992 attr_mask &= ~EXTRACTABLE_BOOL_ON;
1993 break;
1995 case CKA_MODIFIABLE:
1996 if ((*(CK_BBOOL *)template[i].pValue) == B_FALSE)
1997 attr_mask |= NOT_MODIFIABLE_BOOL_ON;
1998 break;
2001 * The following key related attribute types must
2002 * be specified according to the key type by
2003 * C_CreateObject.
2005 case CKA_MODULUS:
2007 isModulus = 1;
2009 * Copyin big integer attribute from template
2010 * to a local variable.
2012 rv = get_bigint_attr_from_template(&modulus,
2013 &template[i]);
2014 if (rv != CKR_OK)
2015 goto fail_cleanup;
2018 * Modulus length needs to be between min key length and
2019 * max key length.
2021 if ((modulus.big_value_len <
2022 MIN_RSA_KEYLENGTH_IN_BYTES) ||
2023 (modulus.big_value_len >
2024 MAX_RSA_KEYLENGTH_IN_BYTES)) {
2025 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2026 goto fail_cleanup;
2028 break;
2030 case CKA_PUBLIC_EXPONENT:
2032 isPubExpo = 1;
2033 rv = get_bigint_attr_from_template(&pubexpo,
2034 &template[i]);
2035 if (rv != CKR_OK)
2036 goto fail_cleanup;
2037 break;
2039 case CKA_PRIVATE_EXPONENT:
2041 isPriExpo = 1;
2042 rv = get_bigint_attr_from_template(&priexpo,
2043 &template[i]);
2044 if (rv != CKR_OK)
2045 goto fail_cleanup;
2046 break;
2048 case CKA_PRIME_1:
2049 isPrime1 = 1;
2050 rv = get_bigint_attr_from_template(&prime1,
2051 &template[i]);
2052 if (rv != CKR_OK)
2053 goto fail_cleanup;
2054 break;
2056 case CKA_PRIME_2:
2057 isPrime2 = 1;
2058 rv = get_bigint_attr_from_template(&prime2,
2059 &template[i]);
2060 if (rv != CKR_OK)
2061 goto fail_cleanup;
2062 break;
2064 case CKA_EXPONENT_1:
2065 isExpo1 = 1;
2066 rv = get_bigint_attr_from_template(&expo1,
2067 &template[i]);
2068 if (rv != CKR_OK)
2069 goto fail_cleanup;
2070 break;
2072 case CKA_EXPONENT_2:
2073 isExpo2 = 1;
2074 rv = get_bigint_attr_from_template(&expo2,
2075 &template[i]);
2076 if (rv != CKR_OK)
2077 goto fail_cleanup;
2078 break;
2080 case CKA_COEFFICIENT:
2081 isCoef = 1;
2082 rv = get_bigint_attr_from_template(&coef,
2083 &template[i]);
2084 if (rv != CKR_OK)
2085 goto fail_cleanup;
2086 break;
2088 case CKA_PRIME:
2089 isPrime = 1;
2090 rv = get_bigint_attr_from_template(&prime,
2091 &template[i]);
2092 if (rv != CKR_OK)
2093 goto fail_cleanup;
2094 break;
2096 case CKA_SUBPRIME:
2097 isSubprime = 1;
2098 rv = get_bigint_attr_from_template(&subprime,
2099 &template[i]);
2100 if (rv != CKR_OK)
2101 goto fail_cleanup;
2102 break;
2104 case CKA_BASE:
2105 isBase = 1;
2106 rv = get_bigint_attr_from_template(&base,
2107 &template[i]);
2108 if (rv != CKR_OK)
2109 goto fail_cleanup;
2110 break;
2112 case CKA_VALUE:
2113 isValue = 1;
2114 if (mode == SOFT_CREATE_OBJ) {
2115 if ((template[i].ulValueLen == 0) ||
2116 (template[i].pValue == NULL)) {
2117 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2118 goto fail_cleanup;
2122 rv = get_bigint_attr_from_template(&value,
2123 &template[i]);
2124 if (rv != CKR_OK)
2125 goto fail_cleanup;
2126 break;
2128 case CKA_VALUE_BITS:
2129 isValueBits = 1;
2130 rv = get_ulong_attr_from_template(&value_bits,
2131 &template[i]);
2132 if (rv != CKR_OK)
2133 goto fail_cleanup;
2134 break;
2136 case CKA_LABEL:
2137 isLabel = 1;
2138 rv = get_string_from_template(&string_tmp,
2139 &template[i]);
2140 if (rv != CKR_OK)
2141 goto fail_cleanup;
2142 break;
2144 case CKA_EC_PARAMS:
2145 isECParam = 1;
2146 rv = get_string_from_template(&param_tmp,
2147 &template[i]);
2148 if (rv != CKR_OK)
2149 goto fail_cleanup;
2150 break;
2152 default:
2153 rv = soft_parse_common_attrs(&template[i],
2154 &object_type);
2155 if (rv != CKR_OK)
2156 goto fail_cleanup;
2157 break;
2160 } /* For */
2162 /* Allocate storage for Private Key Object. */
2163 pvk = calloc(1, sizeof (private_key_obj_t));
2164 if (pvk == NULL) {
2165 rv = CKR_HOST_MEMORY;
2166 goto fail_cleanup;
2169 new_object->object_class_u.private_key = pvk;
2170 new_object->class = CKO_PRIVATE_KEY;
2172 if ((mode == SOFT_CREATE_OBJ) && (keytype == (CK_KEY_TYPE)~0UL)) {
2173 rv = CKR_TEMPLATE_INCOMPLETE;
2174 goto fail_cleanup;
2177 if (mode == SOFT_GEN_KEY) {
2179 * The key type is not specified in the application's
2180 * template, so we use the implied key type based on
2181 * the mechanism.
2183 if (keytype == (CK_KEY_TYPE)~0UL) {
2184 keytype = key_type;
2187 /* If still unspecified, template is incomplete */
2188 if (keytype == (CK_KEY_TYPE)~0UL) {
2189 rv = CKR_TEMPLATE_INCOMPLETE;
2190 goto fail_cleanup;
2194 * The key type specified in the template does not
2195 * match the implied key type based on the mechanism.
2197 if (keytype != key_type) {
2198 rv = CKR_TEMPLATE_INCONSISTENT;
2199 goto fail_cleanup;
2203 if (mode == SOFT_UNWRAP_KEY) {
2205 * Note that, for mode SOFT_UNWRAP_KEY, key type is not
2206 * implied by the mechanism (key_type), so if it is not
2207 * specified from the attribute template (keytype), it is
2208 * incomplete.
2210 if (keytype == (CK_KEY_TYPE)~0UL) {
2211 rv = CKR_TEMPLATE_INCOMPLETE;
2212 goto fail_cleanup;
2216 new_object->key_type = keytype;
2218 /* Supported key types of the Private Key Object */
2219 switch (keytype) {
2220 case CKK_RSA:
2221 if (isPrime || isSubprime || isBase || isValue ||
2222 isValueBits) {
2223 rv = CKR_TEMPLATE_INCONSISTENT;
2224 goto fail_cleanup;
2227 if (mode == SOFT_GEN_KEY || mode == SOFT_UNWRAP_KEY) {
2228 if (isModulus || isPubExpo || isPriExpo || isPrime1 ||
2229 isPrime2 || isExpo1 || isExpo2 || isCoef) {
2230 rv = CKR_TEMPLATE_INCONSISTENT;
2231 goto fail_cleanup;
2232 } else
2233 break;
2236 if (isModulus && isPriExpo) {
2238 * Copy big integer attribute value to the
2239 * designated place in the Private Key object.
2241 copy_bigint_attr(&modulus, KEY_PRI_RSA_MOD(pvk));
2243 copy_bigint_attr(&priexpo, KEY_PRI_RSA_PRIEXPO(pvk));
2244 } else {
2245 rv = CKR_TEMPLATE_INCOMPLETE;
2246 goto fail_cleanup;
2249 /* The following attributes are optional. */
2250 if (isPubExpo) {
2251 copy_bigint_attr(&pubexpo, KEY_PRI_RSA_PUBEXPO(pvk));
2254 if (isPrime1) {
2255 copy_bigint_attr(&prime1, KEY_PRI_RSA_PRIME1(pvk));
2258 if (isPrime2) {
2259 copy_bigint_attr(&prime2, KEY_PRI_RSA_PRIME2(pvk));
2262 if (isExpo1) {
2263 copy_bigint_attr(&expo1, KEY_PRI_RSA_EXPO1(pvk));
2266 if (isExpo2) {
2267 copy_bigint_attr(&expo2, KEY_PRI_RSA_EXPO2(pvk));
2270 if (isCoef) {
2271 copy_bigint_attr(&coef, KEY_PRI_RSA_COEF(pvk));
2273 break;
2275 case CKK_DSA:
2276 if (isModulus || isPubExpo || isPriExpo || isPrime1 ||
2277 isPrime2 || isExpo1 || isExpo2 || isCoef ||
2278 isValueBits) {
2279 rv = CKR_TEMPLATE_INCONSISTENT;
2280 goto fail_cleanup;
2283 if (mode == SOFT_GEN_KEY || mode == SOFT_UNWRAP_KEY) {
2284 if (isPrime || isSubprime || isBase || isValue) {
2285 rv = CKR_TEMPLATE_INCONSISTENT;
2286 goto fail_cleanup;
2287 } else
2288 break;
2291 if (isPrime && isSubprime && isBase && isValue) {
2293 * The private value x must be less than subprime q.
2294 * Size for big_init is in BIG_CHUNK_TYPE words.
2296 if (big_init(&x,
2297 CHARLEN2BIGNUMLEN(value.big_value_len))
2298 != BIG_OK) {
2299 rv = CKR_HOST_MEMORY;
2300 goto fail_cleanup;
2302 if (big_init(&q,
2303 CHARLEN2BIGNUMLEN(subprime.big_value_len))
2304 != BIG_OK) {
2305 rv = CKR_HOST_MEMORY;
2306 goto fail_cleanup;
2308 bytestring2bignum(&x, value.big_value,
2309 value.big_value_len);
2310 bytestring2bignum(&q, subprime.big_value,
2311 subprime.big_value_len);
2313 if (big_cmp_abs(&x, &q) > 0) {
2314 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2315 goto fail_cleanup;
2318 copy_bigint_attr(&prime, KEY_PRI_DSA_PRIME(pvk));
2320 copy_bigint_attr(&subprime, KEY_PRI_DSA_SUBPRIME(pvk));
2322 copy_bigint_attr(&base, KEY_PRI_DSA_BASE(pvk));
2324 copy_bigint_attr(&value, KEY_PRI_DSA_VALUE(pvk));
2325 } else {
2326 rv = CKR_TEMPLATE_INCOMPLETE;
2327 goto fail_cleanup;
2329 break;
2331 case CKK_DH:
2332 if (isModulus || isPubExpo || isPriExpo || isPrime1 ||
2333 isPrime2 || isExpo1 || isExpo2 || isCoef ||
2334 isSubprime) {
2335 rv = CKR_TEMPLATE_INCONSISTENT;
2336 goto fail_cleanup;
2339 /* CKA_VALUE_BITS is for key gen but not unwrap */
2340 if (mode == SOFT_GEN_KEY)
2341 KEY_PRI_DH_VAL_BITS(pvk) = (isValueBits) ?
2342 value_bits : 0;
2343 else if (mode == SOFT_UNWRAP_KEY) {
2344 if (isValueBits) {
2345 rv = CKR_TEMPLATE_INCONSISTENT;
2346 goto fail_cleanup;
2350 if (mode == SOFT_GEN_KEY || mode == SOFT_UNWRAP_KEY) {
2351 if (isPrime || isBase || isValue) {
2352 rv = CKR_TEMPLATE_INCONSISTENT;
2353 goto fail_cleanup;
2354 } else
2355 break;
2358 if (isValueBits) {
2359 rv = CKR_TEMPLATE_INCONSISTENT;
2360 goto fail_cleanup;
2363 if (isPrime && isBase && isValue) {
2364 copy_bigint_attr(&prime, KEY_PRI_DH_PRIME(pvk));
2366 copy_bigint_attr(&base, KEY_PRI_DH_BASE(pvk));
2368 copy_bigint_attr(&value, KEY_PRI_DH_VALUE(pvk));
2369 } else {
2370 rv = CKR_TEMPLATE_INCOMPLETE;
2371 goto fail_cleanup;
2373 break;
2375 case CKK_X9_42_DH:
2376 if (isModulus || isPubExpo || isPriExpo || isPrime1 ||
2377 isPrime2 || isExpo1 || isExpo2 || isCoef ||
2378 isValueBits) {
2379 rv = CKR_TEMPLATE_INCONSISTENT;
2380 goto fail_cleanup;
2383 if (mode == SOFT_GEN_KEY || mode == SOFT_UNWRAP_KEY) {
2384 if (isPrime || isSubprime || isBase || isValue) {
2385 rv = CKR_TEMPLATE_INCONSISTENT;
2386 goto fail_cleanup;
2387 } else
2388 break;
2391 if (isPrime && isSubprime && isBase && isValue) {
2392 copy_bigint_attr(&prime, KEY_PRI_DH942_PRIME(pvk));
2394 copy_bigint_attr(&base, KEY_PRI_DH942_BASE(pvk));
2396 copy_bigint_attr(&subprime,
2397 KEY_PRI_DH942_SUBPRIME(pvk));
2399 copy_bigint_attr(&value, KEY_PRI_DH942_VALUE(pvk));
2400 } else {
2401 rv = CKR_TEMPLATE_INCOMPLETE;
2402 goto fail_cleanup;
2404 break;
2406 case CKK_EC:
2407 if (isModulus || isPubExpo || isPrime ||
2408 isPrime1 || isPrime2 || isExpo1 || isExpo2 || isCoef ||
2409 isValueBits || isBase) {
2410 rv = CKR_TEMPLATE_INCONSISTENT;
2411 goto fail_cleanup;
2413 } else if (isECParam) {
2414 rv = soft_add_extra_attr(&param_tmp, new_object);
2415 if (rv != CKR_OK)
2416 goto fail_cleanup;
2417 string_attr_cleanup(&param_tmp);
2419 if (isValue) {
2420 copy_bigint_attr(&value, KEY_PRI_EC_VALUE(pvk));
2422 break;
2424 default:
2425 rv = CKR_TEMPLATE_INCONSISTENT;
2426 goto fail_cleanup;
2429 /* Set up object. */
2430 new_object->object_type = object_type;
2431 new_object->bool_attr_mask = attr_mask;
2432 if (isLabel) {
2433 rv = soft_add_extra_attr(&string_tmp, new_object);
2434 if (rv != CKR_OK)
2435 goto fail_cleanup;
2436 string_attr_cleanup(&string_tmp);
2438 big_finish(&x);
2439 big_finish(&q);
2441 return (rv);
2443 fail_cleanup:
2445 * cleanup the storage allocated to the local variables.
2447 bigint_attr_cleanup(&modulus);
2448 bigint_attr_cleanup(&priexpo);
2449 bigint_attr_cleanup(&prime);
2450 bigint_attr_cleanup(&subprime);
2451 bigint_attr_cleanup(&base);
2452 bigint_attr_cleanup(&value);
2453 bigint_attr_cleanup(&pubexpo);
2454 bigint_attr_cleanup(&prime1);
2455 bigint_attr_cleanup(&prime2);
2456 bigint_attr_cleanup(&expo1);
2457 bigint_attr_cleanup(&expo2);
2458 bigint_attr_cleanup(&coef);
2459 string_attr_cleanup(&string_tmp);
2460 string_attr_cleanup(&param_tmp);
2461 big_finish(&x);
2462 big_finish(&q);
2465 * cleanup the storage allocated inside the object itself.
2467 soft_cleanup_object(new_object);
2469 return (rv);
2474 * Build a Secret Key Object.
2476 * - Parse the object's template, and when an error is detected such as
2477 * invalid attribute type, invalid attribute value, etc., return
2478 * with appropriate return value.
2479 * - Set up attribute mask field in the object for the supplied common
2480 * attributes that have boolean type.
2481 * - Build the attribute_info struct to hold the value of each supplied
2482 * attribute that has byte array type. Link attribute_info structs
2483 * together to form the extra attribute list of the object.
2484 * - Allocate storage for the Secret Key object.
2485 * - Build the Secret Key object. Allocate storage to hold the big integer
2486 * value for the attribute CKA_VALUE that is required for all the key
2487 * types supported by secret key object.
2488 * This function is called internally with mode = SOFT_CREATE_OBJ_INT.
2491 CK_RV
2492 soft_build_secret_key_object(CK_ATTRIBUTE_PTR template, CK_ULONG ulAttrNum,
2493 soft_object_t *new_object, CK_ULONG mode, CK_ULONG key_len,
2494 CK_KEY_TYPE key_type)
2497 ulong_t i;
2498 CK_KEY_TYPE keytype = (CK_KEY_TYPE)~0UL;
2499 uint64_t attr_mask = SECRET_KEY_DEFAULT;
2500 CK_RV rv = CKR_OK;
2501 int isLabel = 0;
2502 /* Must set flags if mode != SOFT_UNWRAP_KEY, else must not set */
2503 int isValue = 0;
2504 /* Must not set flags if mode != SOFT_UNWRAP_KEY, else optional */
2505 int isValueLen = 0;
2507 CK_ATTRIBUTE string_tmp;
2509 secret_key_obj_t *sck;
2510 uchar_t object_type = 0;
2512 string_tmp.pValue = NULL;
2514 /* Allocate storage for Secret Key Object. */
2515 sck = calloc(1, sizeof (secret_key_obj_t));
2516 if (sck == NULL) {
2517 rv = CKR_HOST_MEMORY;
2518 goto fail_cleanup;
2521 new_object->object_class_u.secret_key = sck;
2522 new_object->class = CKO_SECRET_KEY;
2524 for (i = 0; i < ulAttrNum; i++) {
2526 /* Secret Key Object Attributes */
2527 switch (template[i].type) {
2529 /* common key attributes */
2530 case CKA_KEY_TYPE:
2531 keytype = *((CK_KEY_TYPE*)template[i].pValue);
2532 break;
2534 case CKA_ID:
2535 case CKA_START_DATE:
2536 case CKA_END_DATE:
2538 * Allocate storage to hold the attribute
2539 * value with byte array type, and add it to
2540 * the extra attribute list of the object.
2542 rv = soft_add_extra_attr(&template[i],
2543 new_object);
2544 if (rv != CKR_OK) {
2545 goto fail_cleanup;
2547 break;
2550 * The following key related attribute types must
2551 * not be specified by C_CreateObject and C_GenerateKey.
2553 case CKA_LOCAL:
2554 case CKA_KEY_GEN_MECHANISM:
2555 case CKA_ALWAYS_SENSITIVE:
2556 case CKA_NEVER_EXTRACTABLE:
2557 rv = CKR_TEMPLATE_INCONSISTENT;
2558 goto fail_cleanup;
2560 /* Key related boolean attributes */
2561 case CKA_DERIVE:
2562 if (*(CK_BBOOL *)template[i].pValue)
2563 attr_mask |= DERIVE_BOOL_ON;
2564 break;
2566 case CKA_SENSITIVE:
2567 if (*(CK_BBOOL *)template[i].pValue)
2568 attr_mask |= SENSITIVE_BOOL_ON;
2569 break;
2571 case CKA_ENCRYPT:
2572 if (*(CK_BBOOL *)template[i].pValue)
2573 attr_mask |= ENCRYPT_BOOL_ON;
2574 else
2575 attr_mask &= ~ENCRYPT_BOOL_ON;
2576 break;
2578 case CKA_DECRYPT:
2579 if (*(CK_BBOOL *)template[i].pValue)
2580 attr_mask |= DECRYPT_BOOL_ON;
2581 else
2582 attr_mask &= ~DECRYPT_BOOL_ON;
2583 break;
2585 case CKA_SIGN:
2586 if (*(CK_BBOOL *)template[i].pValue)
2587 attr_mask |= SIGN_BOOL_ON;
2588 else
2589 attr_mask &= ~SIGN_BOOL_ON;
2590 break;
2592 case CKA_VERIFY:
2593 if (*(CK_BBOOL *)template[i].pValue)
2594 attr_mask |= VERIFY_BOOL_ON;
2595 else
2596 attr_mask &= ~VERIFY_BOOL_ON;
2597 break;
2599 case CKA_WRAP:
2600 if (*(CK_BBOOL *)template[i].pValue)
2601 attr_mask |= WRAP_BOOL_ON;
2602 else
2603 attr_mask &= ~WRAP_BOOL_ON;
2604 break;
2606 case CKA_UNWRAP:
2607 if (*(CK_BBOOL *)template[i].pValue)
2608 attr_mask |= UNWRAP_BOOL_ON;
2609 else
2610 attr_mask &= ~UNWRAP_BOOL_ON;
2611 break;
2613 case CKA_EXTRACTABLE:
2614 if (*(CK_BBOOL *)template[i].pValue)
2615 attr_mask |= EXTRACTABLE_BOOL_ON;
2616 else
2617 attr_mask &= ~EXTRACTABLE_BOOL_ON;
2618 break;
2620 case CKA_MODIFIABLE:
2621 if ((*(CK_BBOOL *)template[i].pValue) == B_FALSE)
2622 attr_mask |= NOT_MODIFIABLE_BOOL_ON;
2623 break;
2625 case CKA_VALUE:
2626 isValue = 1;
2627 if (mode == SOFT_CREATE_OBJ) {
2628 if ((template[i].ulValueLen == 0) ||
2629 (template[i].pValue == NULL)) {
2630 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2631 goto fail_cleanup;
2636 * Copyin attribute from template
2637 * to a local variable.
2639 rv = get_bigint_attr_from_template((biginteger_t *)sck,
2640 &template[i]);
2641 if (rv != CKR_OK)
2642 goto fail_cleanup;
2643 break;
2645 case CKA_VALUE_LEN:
2646 isValueLen = 1;
2647 rv = get_ulong_attr_from_template(&sck->sk_value_len,
2648 &template[i]);
2649 if (rv != CKR_OK)
2650 goto fail_cleanup;
2651 break;
2653 case CKA_LABEL:
2654 isLabel = 1;
2655 rv = get_string_from_template(&string_tmp,
2656 &template[i]);
2657 if (rv != CKR_OK)
2658 goto fail_cleanup;
2659 break;
2661 default:
2662 rv = soft_parse_common_attrs(&template[i],
2663 &object_type);
2664 if (rv != CKR_OK)
2665 goto fail_cleanup;
2666 break;
2669 } /* For */
2671 switch (mode) {
2672 case SOFT_CREATE_OBJ:
2673 case SOFT_CREATE_OBJ_INT:
2674 case SOFT_DERIVE_KEY_DH:
2676 * The key type must be specified in the application's
2677 * template. Otherwise, returns error.
2679 if (keytype == (CK_KEY_TYPE)~0UL) {
2680 rv = CKR_TEMPLATE_INCOMPLETE;
2681 goto fail_cleanup;
2683 break;
2685 case SOFT_GEN_KEY:
2686 if (keytype == (CK_KEY_TYPE)~0UL) {
2688 * The key type is not specified in the application's
2689 * template, so we use the implied key type based on
2690 * the mechanism.
2692 keytype = key_type;
2693 } else {
2694 if (keytype != key_type) {
2696 * The key type specified in the template
2697 * does not match the implied key type based
2698 * on the mechanism.
2700 rv = CKR_TEMPLATE_INCONSISTENT;
2701 goto fail_cleanup;
2706 * If a key_len is passed as a parameter, it has to
2707 * match the one found in the template.
2709 if (key_len > 0) {
2710 if (isValueLen && sck->sk_value_len != key_len) {
2711 rv = CKR_TEMPLATE_INCONSISTENT;
2712 goto fail_cleanup;
2714 isValueLen = 1;
2715 sck->sk_value_len = key_len;
2717 break;
2719 case SOFT_UNWRAP_KEY:
2721 * Note that, for mode SOFT_UNWRAP_KEY, key type is not
2722 * implied by the mechanism (key_type), so if it is not
2723 * specified from the attribute template (keytype), it is
2724 * incomplete.
2726 if (keytype == (CK_KEY_TYPE)~0UL) {
2727 rv = CKR_TEMPLATE_INCOMPLETE;
2728 goto fail_cleanup;
2730 break;
2732 case SOFT_DERIVE_KEY_OTHER:
2734 * For CKM_MD5_KEY_DERIVATION & CKM_SHA1_KEY_DERIVATION, the
2735 * key type is optional.
2737 if (keytype == (CK_KEY_TYPE)~0UL) {
2738 keytype = key_type;
2740 break;
2743 switch (mode) {
2744 case SOFT_CREATE_OBJ:
2745 case SOFT_CREATE_OBJ_INT:
2746 switch (keytype) {
2747 case CKK_RC4:
2748 if (!isValue) {
2749 rv = CKR_TEMPLATE_INCOMPLETE;
2750 goto fail_cleanup;
2752 if ((sck->sk_value_len < ARCFOUR_MIN_KEY_BYTES) ||
2753 (sck->sk_value_len > ARCFOUR_MAX_KEY_BYTES)) {
2754 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2755 goto fail_cleanup;
2757 break;
2759 case CKK_GENERIC_SECRET:
2760 if (!isValue) {
2761 rv = CKR_TEMPLATE_INCOMPLETE;
2762 goto fail_cleanup;
2764 break;
2766 case CKK_AES:
2767 if (!isValue) {
2768 rv = CKR_TEMPLATE_INCOMPLETE;
2769 goto fail_cleanup;
2771 if ((sck->sk_value_len != AES_MIN_KEY_BYTES) &&
2772 (sck->sk_value_len != AES_192_KEY_BYTES) &&
2773 (sck->sk_value_len != AES_MAX_KEY_BYTES)) {
2774 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2775 goto fail_cleanup;
2777 break;
2779 case CKK_BLOWFISH:
2780 if (!isValue) {
2781 rv = CKR_TEMPLATE_INCOMPLETE;
2782 goto fail_cleanup;
2784 if ((sck->sk_value_len < BLOWFISH_MINBYTES) ||
2785 (sck->sk_value_len > BLOWFISH_MAXBYTES)) {
2786 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2787 goto fail_cleanup;
2790 break;
2792 case CKK_DES:
2793 if (!isValue) {
2794 rv = CKR_TEMPLATE_INCOMPLETE;
2795 goto fail_cleanup;
2797 if (sck->sk_value_len != DES_KEYSIZE) {
2798 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2799 goto fail_cleanup;
2801 break;
2803 case CKK_DES2:
2804 if (!isValue) {
2805 rv = CKR_TEMPLATE_INCOMPLETE;
2806 goto fail_cleanup;
2808 if (sck->sk_value_len != DES2_KEYSIZE) {
2809 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2810 goto fail_cleanup;
2812 break;
2814 case CKK_DES3:
2815 if (!isValue) {
2816 rv = CKR_TEMPLATE_INCOMPLETE;
2817 goto fail_cleanup;
2819 if (sck->sk_value_len != DES3_KEYSIZE) {
2820 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2821 goto fail_cleanup;
2823 break;
2825 default:
2826 rv = CKR_TEMPLATE_INCONSISTENT;
2827 goto fail_cleanup;
2830 if (isValueLen) {
2832 * Templates for internal object creation come from
2833 * applications calls to C_DeriveKey(), for which it
2834 * is OKey to pass a CKA_VALUE_LEN attribute, as
2835 * long as it does not conflict with the length of the
2836 * CKA_VALUE attribute.
2838 if ((mode != SOFT_CREATE_OBJ_INT) ||
2839 ((key_len > 0) && sck->sk_value_len != key_len)) {
2840 rv = CKR_TEMPLATE_INCONSISTENT;
2841 goto fail_cleanup;
2844 break;
2846 case SOFT_GEN_KEY:
2847 /* CKA_VALUE must not be specified */
2848 if (isValue) {
2849 rv = CKR_TEMPLATE_INCONSISTENT;
2850 goto fail_cleanup;
2853 switch (keytype) {
2855 * CKA_VALUE_LEN must be specified by C_GenerateKey
2856 * if mech is CKK_RC4, CKK_AES, CKK_GENERIC_SECRET.
2858 case CKK_RC4:
2859 if (!isValueLen) {
2860 rv = CKR_TEMPLATE_INCOMPLETE;
2861 goto fail_cleanup;
2864 if ((sck->sk_value_len < ARCFOUR_MIN_KEY_BYTES) ||
2865 (sck->sk_value_len > ARCFOUR_MAX_KEY_BYTES)) {
2866 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2867 goto fail_cleanup;
2869 break;
2871 case CKK_GENERIC_SECRET:
2872 /* arbitrary key length - no length checking */
2873 if (!isValueLen) {
2874 rv = CKR_TEMPLATE_INCOMPLETE;
2875 goto fail_cleanup;
2877 break;
2879 case CKK_AES:
2880 if (!isValueLen) {
2881 rv = CKR_TEMPLATE_INCOMPLETE;
2882 goto fail_cleanup;
2885 if ((sck->sk_value_len != AES_MIN_KEY_BYTES) &&
2886 (sck->sk_value_len != AES_192_KEY_BYTES) &&
2887 (sck->sk_value_len != AES_MAX_KEY_BYTES)) {
2888 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2889 goto fail_cleanup;
2892 break;
2894 case CKK_BLOWFISH:
2895 if (!isValueLen) {
2896 rv = CKR_TEMPLATE_INCOMPLETE;
2897 goto fail_cleanup;
2899 if ((sck->sk_value_len < BLOWFISH_MINBYTES) ||
2900 (sck->sk_value_len > BLOWFISH_MAXBYTES)) {
2901 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2902 goto fail_cleanup;
2905 break;
2907 case CKK_DES:
2908 case CKK_DES2:
2909 case CKK_DES3:
2910 /* CKA_VALUE_LEN attribute does not apply to DES<n> */
2911 if (isValueLen) {
2912 rv = CKR_TEMPLATE_INCONSISTENT;
2913 goto fail_cleanup;
2915 break;
2917 default:
2918 rv = CKR_TEMPLATE_INCONSISTENT;
2919 goto fail_cleanup;
2921 break;
2923 case SOFT_UNWRAP_KEY:
2925 * According to v2.11 of PKCS#11 spec, neither CKA_VALUE nor
2926 * CKA_VALUE_LEN can be be specified; however v2.20 has this
2927 * restriction removed, perhaps because it makes it hard to
2928 * determine variable-length key sizes. This case statement
2929 * complied with v2.20.
2931 if (isValue) {
2932 rv = CKR_TEMPLATE_INCONSISTENT;
2933 goto fail_cleanup;
2936 switch (keytype) {
2938 * CKA_VALUE_LEN is optional
2939 * if key is CKK_RC4, CKK_AES, CKK_GENERIC_SECRET
2940 * and the unwrapping mech is *_CBC_PAD.
2942 * CKA_VALUE_LEN is required
2943 * if key is CKK_RC4, CKK_AES, CKK_GENERIC_SECRET
2944 * and the unwrapping mech is *_ECB or *_CBC.
2946 * since mech is not known at this point, CKA_VALUE_LEN is
2947 * treated as optional and the caller needs to enforce it.
2949 case CKK_RC4:
2950 if (isValueLen) {
2951 if ((sck->sk_value_len <
2952 ARCFOUR_MIN_KEY_BYTES) ||
2953 (sck->sk_value_len >
2954 ARCFOUR_MAX_KEY_BYTES)) {
2955 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2956 goto fail_cleanup;
2959 break;
2961 case CKK_GENERIC_SECRET:
2962 /* arbitrary key length - no length checking */
2963 break;
2965 case CKK_AES:
2966 if (isValueLen) {
2967 if ((sck->sk_value_len != AES_MIN_KEY_BYTES) &&
2968 (sck->sk_value_len != AES_192_KEY_BYTES) &&
2969 (sck->sk_value_len != AES_MAX_KEY_BYTES)) {
2970 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2971 goto fail_cleanup;
2974 break;
2976 case CKK_BLOWFISH:
2977 if (isValueLen &&
2978 ((sck->sk_value_len < BLOWFISH_MINBYTES) ||
2979 (sck->sk_value_len > BLOWFISH_MAXBYTES))) {
2980 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2981 goto fail_cleanup;
2983 break;
2985 case CKK_DES:
2986 case CKK_DES2:
2987 case CKK_DES3:
2988 /* CKA_VALUE_LEN attribute does not apply to DES<n> */
2989 if (isValueLen) {
2990 rv = CKR_TEMPLATE_INCONSISTENT;
2991 goto fail_cleanup;
2993 break;
2995 default:
2996 rv = CKR_TEMPLATE_INCONSISTENT;
2997 goto fail_cleanup;
2999 break;
3001 case SOFT_DERIVE_KEY_DH:
3002 /* CKA_VALUE must not be specified */
3003 if (isValue) {
3004 rv = CKR_TEMPLATE_INCONSISTENT;
3005 goto fail_cleanup;
3008 switch (keytype) {
3010 * CKA_VALUE_LEN is optional
3011 * if mech is CKK_RC4, CKK_AES, CKK_GENERIC_SECRET.
3013 case CKK_RC4:
3014 if (isValueLen) {
3015 if ((sck->sk_value_len <
3016 ARCFOUR_MIN_KEY_BYTES) ||
3017 (sck->sk_value_len >
3018 ARCFOUR_MAX_KEY_BYTES)) {
3019 rv = CKR_ATTRIBUTE_VALUE_INVALID;
3020 goto fail_cleanup;
3023 break;
3025 case CKK_GENERIC_SECRET:
3026 /* arbitrary key length - no length checking */
3027 break;
3029 case CKK_AES:
3030 if (isValueLen) {
3031 if ((sck->sk_value_len != AES_MIN_KEY_BYTES) &&
3032 (sck->sk_value_len != AES_192_KEY_BYTES) &&
3033 (sck->sk_value_len != AES_MAX_KEY_BYTES)) {
3034 rv = CKR_ATTRIBUTE_VALUE_INVALID;
3035 goto fail_cleanup;
3039 break;
3041 case CKK_BLOWFISH:
3042 if (isValueLen &&
3043 ((sck->sk_value_len < BLOWFISH_MINBYTES) ||
3044 (sck->sk_value_len > BLOWFISH_MAXBYTES))) {
3045 rv = CKR_ATTRIBUTE_VALUE_INVALID;
3046 goto fail_cleanup;
3048 break;
3050 case CKK_DES:
3051 case CKK_DES2:
3052 case CKK_DES3:
3053 /* CKA_VALUE_LEN attribute does not apply to DES<n> */
3054 if (isValueLen) {
3055 rv = CKR_TEMPLATE_INCONSISTENT;
3056 goto fail_cleanup;
3058 break;
3060 default:
3061 rv = CKR_TEMPLATE_INCONSISTENT;
3062 goto fail_cleanup;
3064 break;
3066 case SOFT_DERIVE_KEY_OTHER:
3067 /* CKA_VALUE must not be specified */
3068 if (isValue) {
3069 rv = CKR_TEMPLATE_INCONSISTENT;
3070 goto fail_cleanup;
3073 switch (keytype) {
3075 * CKA_VALUE_LEN is an optional attribute for
3076 * CKM_SHA1_KEY_DERIVATION and CKM_MD5_KEY_DERIVATION
3077 * if mech is CKK_RC4, CKK_AES, CKK_GENERIC_SECRET.
3079 case CKK_RC4:
3080 case CKK_GENERIC_SECRET:
3081 case CKK_AES:
3082 case CKK_BLOWFISH:
3084 * No need to check key length value here, it will be
3085 * validated later in soft_key_derive_check_length().
3087 break;
3089 case CKK_DES:
3090 case CKK_DES2:
3091 case CKK_DES3:
3092 /* CKA_VALUE_LEN attribute does not apply to DES<n> */
3093 if (isValueLen) {
3094 rv = CKR_TEMPLATE_INCONSISTENT;
3095 goto fail_cleanup;
3097 break;
3099 default:
3100 rv = CKR_TEMPLATE_INCONSISTENT;
3101 goto fail_cleanup;
3103 break;
3106 /* Set up object. */
3107 new_object->key_type = keytype;
3108 new_object->object_type = object_type;
3109 new_object->bool_attr_mask = attr_mask;
3110 if (isLabel) {
3111 rv = soft_add_extra_attr(&string_tmp, new_object);
3112 if (rv != CKR_OK)
3113 goto fail_cleanup;
3114 string_attr_cleanup(&string_tmp);
3116 return (rv);
3118 fail_cleanup:
3120 * cleanup the storage allocated to the local variables.
3122 bigint_attr_cleanup((biginteger_t *)sck);
3123 string_attr_cleanup(&string_tmp);
3126 * cleanup the storage allocated inside the object itself.
3128 soft_cleanup_object(new_object);
3130 return (rv);
3135 * Build a Domain Parameter Object.
3137 * - Parse the object's template, and when an error is detected such as
3138 * invalid attribute type, invalid attribute value, etc., return
3139 * with appropriate return value.
3140 * - Allocate storage for the Domain Parameter object.
3141 * - Build the Domain Parameter object according to the key type. Allocate
3142 * storage to hold the big integer value for the supplied attributes
3143 * that are required for a certain key type.
3146 CK_RV
3147 soft_build_domain_parameters_object(CK_ATTRIBUTE_PTR template,
3148 CK_ULONG ulAttrNum, soft_object_t *new_object)
3151 ulong_t i;
3152 CK_KEY_TYPE keytype = (CK_KEY_TYPE)~0UL;
3153 CK_RV rv = CKR_OK;
3154 int isLabel = 0;
3155 /* Must set flags */
3156 int isPrime = 0;
3157 int isSubprime = 0;
3158 int isBase = 0;
3159 /* Must not set flags */
3160 int isPrimeBits = 0;
3161 int isSubPrimeBits = 0;
3163 biginteger_t prime;
3164 biginteger_t subprime;
3165 biginteger_t base;
3166 CK_ATTRIBUTE string_tmp;
3168 domain_obj_t *dom;
3169 uchar_t object_type = 0;
3171 /* prevent bigint_attr_cleanup from freeing invalid attr value */
3172 (void) memset(&prime, 0x0, sizeof (biginteger_t));
3173 (void) memset(&subprime, 0x0, sizeof (biginteger_t));
3174 (void) memset(&base, 0x0, sizeof (biginteger_t));
3175 string_tmp.pValue = NULL;
3177 for (i = 0; i < ulAttrNum; i++) {
3179 /* Domain Parameters Object Attributes */
3180 switch (template[i].type) {
3182 /* common domain parameter attribute */
3183 case CKA_KEY_TYPE:
3184 keytype = *((CK_KEY_TYPE*)template[i].pValue);
3185 break;
3188 * The following common domain parameter attribute
3189 * must not be specified by C_CreateObject.
3191 case CKA_LOCAL:
3192 rv = CKR_TEMPLATE_INCONSISTENT;
3193 goto fail_cleanup;
3196 * The following domain parameter attributes must be
3197 * specified according to the key type by
3198 * C_CreateObject.
3200 case CKA_PRIME:
3201 isPrime = 1;
3203 * Copyin big integer attribute from template
3204 * to a local variable.
3206 rv = get_bigint_attr_from_template(&prime,
3207 &template[i]);
3208 if (rv != CKR_OK)
3209 goto fail_cleanup;
3210 break;
3212 case CKA_SUBPRIME:
3213 isSubprime = 1;
3214 rv = get_bigint_attr_from_template(&subprime,
3215 &template[i]);
3216 if (rv != CKR_OK)
3217 goto fail_cleanup;
3218 break;
3220 case CKA_BASE:
3221 isBase = 1;
3222 rv = get_bigint_attr_from_template(&base,
3223 &template[i]);
3224 if (rv != CKR_OK)
3225 goto fail_cleanup;
3226 break;
3228 case CKA_PRIME_BITS:
3229 isPrimeBits = 1;
3230 break;
3232 case CKA_SUB_PRIME_BITS:
3233 isSubPrimeBits = 1;
3234 break;
3236 case CKA_LABEL:
3237 isLabel = 1;
3238 rv = get_string_from_template(&string_tmp,
3239 &template[i]);
3240 if (rv != CKR_OK)
3241 goto fail_cleanup;
3242 break;
3244 default:
3245 rv = soft_parse_common_attrs(&template[i],
3246 &object_type);
3247 if (rv != CKR_OK)
3248 goto fail_cleanup;
3249 break;
3252 } /* For */
3254 /* Allocate storage for Domain Parameters Object. */
3255 dom = calloc(1, sizeof (domain_obj_t));
3256 if (dom == NULL) {
3257 rv = CKR_HOST_MEMORY;
3258 goto fail_cleanup;
3261 new_object->object_class_u.domain = dom;
3262 new_object->class = CKO_DOMAIN_PARAMETERS;
3264 if (keytype == (CK_KEY_TYPE)~0UL) {
3265 rv = CKR_TEMPLATE_INCOMPLETE;
3266 goto fail_cleanup;
3269 new_object->key_type = keytype;
3271 /* Supported key types of the Domain Parameters Object */
3272 switch (keytype) {
3273 case CKK_DSA:
3274 if (isPrimeBits || isSubPrimeBits) {
3275 rv = CKR_TEMPLATE_INCONSISTENT;
3276 goto fail_cleanup;
3279 if (isPrime && isSubprime && isBase) {
3281 * Copy big integer attribute value to the
3282 * designated place in the domain parameter
3283 * object.
3285 copy_bigint_attr(&prime, KEY_DOM_DSA_PRIME(dom));
3287 copy_bigint_attr(&subprime, KEY_DOM_DSA_SUBPRIME(dom));
3289 copy_bigint_attr(&base, KEY_DOM_DSA_BASE(dom));
3290 } else {
3291 rv = CKR_TEMPLATE_INCOMPLETE;
3292 goto fail_cleanup;
3294 break;
3296 case CKK_DH:
3297 if (isPrimeBits || isSubprime || isSubPrimeBits) {
3298 rv = CKR_TEMPLATE_INCONSISTENT;
3299 goto fail_cleanup;
3302 if (isPrime && isBase) {
3303 copy_bigint_attr(&prime, KEY_DOM_DH_PRIME(dom));
3305 copy_bigint_attr(&base, KEY_DOM_DH_BASE(dom));
3306 } else {
3307 rv = CKR_TEMPLATE_INCOMPLETE;
3308 goto fail_cleanup;
3310 break;
3312 case CKK_X9_42_DH:
3313 if (isPrimeBits || isSubPrimeBits) {
3314 rv = CKR_TEMPLATE_INCONSISTENT;
3315 goto fail_cleanup;
3318 if (isPrime && isSubprime && isBase) {
3319 copy_bigint_attr(&prime, KEY_DOM_DH942_PRIME(dom));
3321 copy_bigint_attr(&base, KEY_DOM_DH942_BASE(dom));
3323 copy_bigint_attr(&subprime,
3324 KEY_DOM_DH942_SUBPRIME(dom));
3325 } else {
3326 rv = CKR_TEMPLATE_INCOMPLETE;
3327 goto fail_cleanup;
3329 break;
3331 default:
3332 rv = CKR_TEMPLATE_INCONSISTENT;
3333 goto fail_cleanup;
3336 new_object->object_type = object_type;
3338 if (isLabel) {
3339 rv = soft_add_extra_attr(&string_tmp, new_object);
3340 if (rv != CKR_OK)
3341 goto fail_cleanup;
3342 string_attr_cleanup(&string_tmp);
3345 return (rv);
3347 fail_cleanup:
3349 * cleanup the storage allocated to the local variables.
3351 bigint_attr_cleanup(&prime);
3352 bigint_attr_cleanup(&subprime);
3353 bigint_attr_cleanup(&base);
3354 string_attr_cleanup(&string_tmp);
3357 * cleanup the storage allocated inside the object itself.
3359 soft_cleanup_object(new_object);
3361 return (rv);
3365 * Build a Certificate Object
3367 * - Parse the object's template, and when an error is detected such as
3368 * invalid attribute type, invalid attribute value, etc., return
3369 * with appropriate return value.
3370 * - Allocate storage for the Certificate object
3372 static CK_RV
3373 soft_build_certificate_object(CK_ATTRIBUTE_PTR template,
3374 CK_ULONG ulAttrNum, soft_object_t *new_object,
3375 CK_CERTIFICATE_TYPE cert_type)
3377 uint64_t attr_mask = 0;
3378 CK_RV rv = CKR_OK;
3379 CK_ULONG i;
3380 int owner_set = 0;
3381 int value_set = 0;
3382 int subject_set = 0;
3383 certificate_obj_t *cert;
3384 /* certificate type defaults to the value given as a parameter */
3385 CK_CERTIFICATE_TYPE certtype = cert_type;
3386 CK_ATTRIBUTE string_tmp;
3387 int isLabel = 0;
3388 uchar_t object_type = 0;
3391 * Look for the certificate type attribute and do some
3392 * sanity checking before creating the structures.
3394 for (i = 0; i < ulAttrNum; i++) {
3395 /* Certificate Object Attributes */
3396 switch (template[i].type) {
3397 case CKA_CERTIFICATE_TYPE:
3398 certtype =
3399 *((CK_CERTIFICATE_TYPE*)template[i].pValue);
3400 break;
3401 case CKA_SUBJECT:
3402 subject_set = 1;
3403 break;
3404 case CKA_OWNER:
3405 owner_set = 1;
3406 break;
3407 case CKA_VALUE:
3408 value_set = 1;
3409 break;
3413 /* The certificate type MUST be specified */
3414 if (certtype != CKC_X_509 && certtype != CKC_X_509_ATTR_CERT)
3415 return (CKR_TEMPLATE_INCOMPLETE);
3418 * For X.509 certs, the CKA_SUBJECT and CKA_VALUE
3419 * must be present at creation time.
3421 if (certtype == CKC_X_509 &&
3422 (!subject_set || !value_set))
3423 return (CKR_TEMPLATE_INCOMPLETE);
3426 * For X.509 Attribute certs, the CKA_OWNER and CKA_VALUE
3427 * must be present at creation time.
3429 if (certtype == CKC_X_509_ATTR_CERT &&
3430 (!owner_set || !value_set))
3431 return (CKR_TEMPLATE_INCOMPLETE);
3433 string_tmp.pValue = NULL;
3434 cert = calloc(1, sizeof (certificate_obj_t));
3435 if (cert == NULL) {
3436 return (CKR_HOST_MEMORY);
3438 cert->certificate_type = certtype;
3440 for (i = 0; i < ulAttrNum; i++) {
3441 /* Certificate Object Attributes */
3442 switch (certtype) {
3443 case CKC_X_509:
3444 switch (template[i].type) {
3445 case CKA_SUBJECT:
3446 rv = get_cert_attr_from_template(
3447 &cert->cert_type_u.x509.subject,
3448 &template[i]);
3449 break;
3450 case CKA_VALUE:
3451 rv = get_cert_attr_from_template(
3452 &cert->cert_type_u.x509.value,
3453 &template[i]);
3454 break;
3455 case CKA_LABEL:
3456 isLabel = 1;
3457 rv = get_string_from_template(
3458 &string_tmp,
3459 &template[i]);
3460 if (rv != CKR_OK)
3461 goto fail_cleanup;
3462 break;
3463 case CKA_ID:
3464 case CKA_ISSUER:
3465 case CKA_SERIAL_NUMBER:
3466 rv = soft_add_extra_attr(&template[i],
3467 new_object);
3468 break;
3469 case CKA_MODIFIABLE:
3470 if ((*(CK_BBOOL *)template[i].pValue) ==
3471 B_FALSE)
3472 attr_mask |=
3473 NOT_MODIFIABLE_BOOL_ON;
3474 break;
3475 case CKA_CERTIFICATE_TYPE:
3476 break;
3477 default:
3478 rv = soft_parse_common_attrs(
3479 &template[i], &object_type);
3480 if (rv != CKR_OK)
3481 goto fail_cleanup;
3483 break;
3484 case CKC_X_509_ATTR_CERT:
3485 switch (template[i].type) {
3486 case CKA_OWNER:
3487 rv = get_cert_attr_from_template(
3488 &cert->cert_type_u.x509_attr.owner,
3489 &template[i]);
3490 break;
3491 case CKA_VALUE:
3492 rv = get_cert_attr_from_template(
3493 &cert->cert_type_u.x509_attr.value,
3494 &template[i]);
3495 break;
3496 case CKA_LABEL:
3497 isLabel = 1;
3498 rv = get_string_from_template(
3499 &string_tmp, &template[i]);
3500 if (rv != CKR_OK)
3501 goto fail_cleanup;
3502 break;
3503 case CKA_SERIAL_NUMBER:
3504 case CKA_AC_ISSUER:
3505 case CKA_ATTR_TYPES:
3506 rv = soft_add_extra_attr(&template[i],
3507 new_object);
3508 break;
3510 case CKA_MODIFIABLE:
3511 if ((*(CK_BBOOL *)template[i].pValue) ==
3512 B_FALSE)
3513 attr_mask |=
3514 NOT_MODIFIABLE_BOOL_ON;
3515 break;
3516 case CKA_CERTIFICATE_TYPE:
3517 break;
3518 default:
3519 rv = soft_parse_common_attrs(
3520 &template[i], &object_type);
3521 if (rv != CKR_OK)
3522 goto fail_cleanup;
3523 break;
3525 break;
3526 default:
3527 rv = CKR_TEMPLATE_INCOMPLETE;
3528 break;
3532 if (rv == CKR_OK) {
3533 new_object->object_class_u.certificate = cert;
3534 new_object->class = CKO_CERTIFICATE;
3535 new_object->object_type = object_type;
3536 new_object->cert_type = certtype;
3537 new_object->bool_attr_mask = attr_mask;
3538 if (isLabel) {
3539 rv = soft_add_extra_attr(&string_tmp, new_object);
3540 if (rv != CKR_OK)
3541 goto fail_cleanup;
3542 string_attr_cleanup(&string_tmp);
3546 fail_cleanup:
3547 if (rv != CKR_OK) {
3548 soft_cleanup_cert_object(new_object);
3550 return (rv);
3555 * Validate the attribute types in the object's template. Then,
3556 * call the appropriate build function according to the class of
3557 * the object specified in the template.
3559 * Note: The following classes of objects are supported:
3560 * - CKO_PUBLIC_KEY
3561 * - CKO_PRIVATE_KEY
3562 * - CKO_SECRET_KEY
3563 * - CKO_DOMAIN_PARAMETERS
3564 * - CKO_CERTIFICATE
3567 CK_RV
3568 soft_build_object(CK_ATTRIBUTE_PTR template, CK_ULONG ulAttrNum,
3569 soft_object_t *new_object)
3572 CK_OBJECT_CLASS class = (CK_OBJECT_CLASS)~0UL;
3573 CK_RV rv = CKR_OK;
3575 if (template == NULL) {
3576 return (CKR_ARGUMENTS_BAD);
3579 /* Validate the attribute type in the template. */
3580 rv = soft_validate_attr(template, ulAttrNum, &class);
3581 if (rv != CKR_OK)
3582 return (rv);
3584 * CKA_CLASS is a mandatory attribute for C_CreateObject
3586 if (class == (CK_OBJECT_CLASS)~0UL)
3587 return (CKR_TEMPLATE_INCOMPLETE);
3590 * Call the appropriate function based on the supported class
3591 * of the object.
3593 switch (class) {
3594 case CKO_PUBLIC_KEY:
3595 rv = soft_build_public_key_object(template, ulAttrNum,
3596 new_object, SOFT_CREATE_OBJ, (CK_KEY_TYPE)~0UL);
3597 break;
3599 case CKO_PRIVATE_KEY:
3600 rv = soft_build_private_key_object(template, ulAttrNum,
3601 new_object, SOFT_CREATE_OBJ, (CK_KEY_TYPE)~0UL);
3602 break;
3604 case CKO_SECRET_KEY:
3605 rv = soft_build_secret_key_object(template, ulAttrNum,
3606 new_object, SOFT_CREATE_OBJ, 0, (CK_KEY_TYPE)~0UL);
3607 break;
3609 case CKO_DOMAIN_PARAMETERS:
3610 rv = soft_build_domain_parameters_object(template, ulAttrNum,
3611 new_object);
3612 break;
3614 case CKO_CERTIFICATE:
3615 rv = soft_build_certificate_object(template, ulAttrNum,
3616 new_object, (CK_CERTIFICATE_TYPE)~0UL);
3617 break;
3619 case CKO_DATA:
3620 case CKO_HW_FEATURE:
3621 case CKO_VENDOR_DEFINED:
3622 default:
3623 return (CKR_ATTRIBUTE_VALUE_INVALID);
3626 return (rv);
3630 * Validate the attribute types in the object's template. Then,
3631 * call the appropriate build function according to the class of
3632 * the object specified in the template.
3635 CK_RV
3636 soft_build_key(CK_ATTRIBUTE_PTR template, CK_ULONG ulAttrNum,
3637 soft_object_t *new_object, CK_OBJECT_CLASS class, CK_KEY_TYPE key_type,
3638 CK_ULONG key_len, CK_ULONG mode)
3641 CK_RV rv = CKR_OK;
3642 CK_OBJECT_CLASS temp_class = (CK_OBJECT_CLASS)~0UL;
3644 /* Validate the attribute type in the template. */
3645 if ((template != NULL) && (ulAttrNum != 0)) {
3646 rv = soft_validate_attr(template, ulAttrNum, &temp_class);
3647 if (rv != CKR_OK)
3648 return (rv);
3652 * If either the class from the parameter list ("class") or
3653 * the class from the template ("temp_class") is not specified,
3654 * try to use the other one.
3656 if (temp_class == (CK_OBJECT_CLASS)~0UL) {
3657 temp_class = class;
3658 } else if (class == (CK_OBJECT_CLASS)~0UL) {
3659 class = temp_class;
3662 /* If object class is still not specified, template is incomplete. */
3663 if (class == (CK_OBJECT_CLASS)~0UL)
3664 return (CKR_TEMPLATE_INCOMPLETE);
3666 /* Class should match if specified in both parameters and template. */
3667 if (class != temp_class)
3668 return (CKR_TEMPLATE_INCONSISTENT);
3671 * Call the appropriate function based on the supported class
3672 * of the object.
3674 switch (class) {
3675 case CKO_PUBLIC_KEY:
3677 /* Unwrapping public keys is not supported. */
3678 if (mode == SOFT_UNWRAP_KEY) {
3679 rv = CKR_ATTRIBUTE_VALUE_INVALID;
3680 break;
3683 rv = soft_build_public_key_object(template, ulAttrNum,
3684 new_object, mode, key_type);
3685 break;
3687 case CKO_PRIVATE_KEY:
3689 rv = soft_build_private_key_object(template, ulAttrNum,
3690 new_object, mode, key_type);
3691 break;
3693 case CKO_SECRET_KEY:
3695 rv = soft_build_secret_key_object(template, ulAttrNum,
3696 new_object, mode, key_len, key_type);
3697 break;
3699 case CKO_DOMAIN_PARAMETERS:
3701 /* Unwrapping domain parameters is not supported. */
3702 if (mode == SOFT_UNWRAP_KEY) {
3703 rv = CKR_ATTRIBUTE_VALUE_INVALID;
3704 break;
3707 rv = soft_build_domain_parameters_object(template, ulAttrNum,
3708 new_object);
3709 break;
3711 case CKO_DATA:
3712 case CKO_CERTIFICATE:
3713 case CKO_HW_FEATURE:
3714 case CKO_VENDOR_DEFINED:
3715 default:
3716 return (CKR_ATTRIBUTE_VALUE_INVALID);
3719 return (rv);
3724 * Get the value of a requested attribute that is common to all supported
3725 * classes (i.e. public key, private key, secret key, domain parameters,
3726 * and certificate classes).
3728 CK_RV
3729 soft_get_common_attrs(soft_object_t *object_p, CK_ATTRIBUTE_PTR template,
3730 uchar_t object_type)
3733 CK_RV rv = CKR_OK;
3735 switch (template->type) {
3737 case CKA_CLASS:
3738 return (get_ulong_attr_from_object(object_p->class,
3739 template));
3741 /* default boolean attributes */
3742 case CKA_TOKEN:
3743 template->ulValueLen = sizeof (CK_BBOOL);
3744 if (template->pValue == NULL) {
3745 return (CKR_OK);
3747 if (object_type & TOKEN_OBJECT)
3748 *((CK_BBOOL *)template->pValue) = B_TRUE;
3749 else
3750 *((CK_BBOOL *)template->pValue) = B_FALSE;
3751 break;
3753 case CKA_PRIVATE:
3755 template->ulValueLen = sizeof (CK_BBOOL);
3756 if (template->pValue == NULL) {
3757 return (CKR_OK);
3759 if (object_type & PRIVATE_OBJECT)
3760 *((CK_BBOOL *)template->pValue) = B_TRUE;
3761 else
3762 *((CK_BBOOL *)template->pValue) = B_FALSE;
3763 break;
3765 case CKA_MODIFIABLE:
3766 template->ulValueLen = sizeof (CK_BBOOL);
3767 if (template->pValue == NULL) {
3768 return (CKR_OK);
3770 if ((object_p->bool_attr_mask) & NOT_MODIFIABLE_BOOL_ON)
3771 *((CK_BBOOL *)template->pValue) = B_FALSE;
3772 else
3773 *((CK_BBOOL *)template->pValue) = B_TRUE;
3774 break;
3776 case CKA_LABEL:
3777 return (get_extra_attr_from_object(object_p,
3778 template));
3780 default:
3782 * The specified attribute for the object is invalid.
3783 * (the object does not possess such an attribute.)
3785 template->ulValueLen = (CK_ULONG)-1;
3786 return (CKR_ATTRIBUTE_TYPE_INVALID);
3789 return (rv);
3793 * Get the value of a requested attribute that is common to all key objects
3794 * (i.e. public key, private key and secret key).
3796 CK_RV
3797 soft_get_common_key_attrs(soft_object_t *object_p, CK_ATTRIBUTE_PTR template)
3800 switch (template->type) {
3802 case CKA_KEY_TYPE:
3803 return (get_ulong_attr_from_object(object_p->key_type,
3804 template));
3806 case CKA_ID:
3807 case CKA_START_DATE:
3808 case CKA_END_DATE:
3810 * The above extra attributes have byte array type.
3812 return (get_extra_attr_from_object(object_p,
3813 template));
3815 /* Key related boolean attributes */
3816 case CKA_LOCAL:
3817 return (get_bool_attr_from_object(object_p,
3818 LOCAL_BOOL_ON, template));
3820 case CKA_DERIVE:
3821 return (get_bool_attr_from_object(object_p,
3822 DERIVE_BOOL_ON, template));
3824 case CKA_KEY_GEN_MECHANISM:
3825 return (get_ulong_attr_from_object(object_p->mechanism,
3826 template));
3828 default:
3829 return (CKR_ATTRIBUTE_TYPE_INVALID);
3834 * Get the value of a requested attribute of a Public Key Object.
3836 * Rule: All the attributes in the public key object can be revealed.
3838 CK_RV
3839 soft_get_public_key_attribute(soft_object_t *object_p,
3840 CK_ATTRIBUTE_PTR template)
3843 CK_RV rv = CKR_OK;
3844 CK_KEY_TYPE keytype = object_p->key_type;
3846 switch (template->type) {
3848 case CKA_SUBJECT:
3849 case CKA_EC_PARAMS:
3851 * The above extra attributes have byte array type.
3853 return (get_extra_attr_from_object(object_p,
3854 template));
3856 /* Key related boolean attributes */
3857 case CKA_ENCRYPT:
3858 return (get_bool_attr_from_object(object_p,
3859 ENCRYPT_BOOL_ON, template));
3861 case CKA_VERIFY:
3862 return (get_bool_attr_from_object(object_p,
3863 VERIFY_BOOL_ON, template));
3865 case CKA_VERIFY_RECOVER:
3866 return (get_bool_attr_from_object(object_p,
3867 VERIFY_RECOVER_BOOL_ON, template));
3869 case CKA_WRAP:
3870 return (get_bool_attr_from_object(object_p,
3871 WRAP_BOOL_ON, template));
3873 case CKA_TRUSTED:
3874 return (get_bool_attr_from_object(object_p,
3875 TRUSTED_BOOL_ON, template));
3877 case CKA_MODULUS:
3879 * This attribute is valid only for RSA public key
3880 * object.
3882 if (keytype == CKK_RSA) {
3883 return (get_bigint_attr_from_object(
3884 OBJ_PUB_RSA_MOD(object_p), template));
3885 } else {
3886 template->ulValueLen = (CK_ULONG)-1;
3887 return (CKR_ATTRIBUTE_TYPE_INVALID);
3890 case CKA_PUBLIC_EXPONENT:
3891 if (keytype == CKK_RSA) {
3892 return (get_bigint_attr_from_object(
3893 OBJ_PUB_RSA_PUBEXPO(object_p), template));
3894 } else {
3895 template->ulValueLen = (CK_ULONG)-1;
3896 return (CKR_ATTRIBUTE_TYPE_INVALID);
3899 case CKA_MODULUS_BITS:
3900 if (keytype == CKK_RSA) {
3901 return (get_ulong_attr_from_object(
3902 OBJ_PUB_RSA_MOD_BITS(object_p), template));
3903 } else {
3904 template->ulValueLen = (CK_ULONG)-1;
3905 return (CKR_ATTRIBUTE_TYPE_INVALID);
3908 case CKA_PRIME:
3909 switch (keytype) {
3910 case CKK_DSA:
3911 return (get_bigint_attr_from_object(
3912 OBJ_PUB_DSA_PRIME(object_p), template));
3914 case CKK_DH:
3915 return (get_bigint_attr_from_object(
3916 OBJ_PUB_DH_PRIME(object_p), template));
3918 case CKK_X9_42_DH:
3919 return (get_bigint_attr_from_object(
3920 OBJ_PUB_DH942_PRIME(object_p), template));
3922 default:
3923 template->ulValueLen = (CK_ULONG)-1;
3924 return (CKR_ATTRIBUTE_TYPE_INVALID);
3927 case CKA_SUBPRIME:
3928 switch (keytype) {
3929 case CKK_DSA:
3930 return (get_bigint_attr_from_object(
3931 OBJ_PUB_DSA_SUBPRIME(object_p), template));
3933 case CKK_X9_42_DH:
3934 return (get_bigint_attr_from_object(
3935 OBJ_PUB_DH942_SUBPRIME(object_p), template));
3937 default:
3938 template->ulValueLen = (CK_ULONG)-1;
3939 return (CKR_ATTRIBUTE_TYPE_INVALID);
3942 case CKA_BASE:
3943 switch (keytype) {
3944 case CKK_DSA:
3945 return (get_bigint_attr_from_object(
3946 OBJ_PUB_DSA_BASE(object_p), template));
3948 case CKK_DH:
3949 return (get_bigint_attr_from_object(
3950 OBJ_PUB_DH_BASE(object_p), template));
3952 case CKK_X9_42_DH:
3953 return (get_bigint_attr_from_object(
3954 OBJ_PUB_DH942_BASE(object_p), template));
3956 default:
3957 template->ulValueLen = (CK_ULONG)-1;
3958 return (CKR_ATTRIBUTE_TYPE_INVALID);
3961 case CKA_EC_POINT:
3962 return (get_bigint_attr_from_object(
3963 OBJ_PUB_EC_POINT(object_p), template));
3965 case CKA_VALUE:
3966 switch (keytype) {
3967 case CKK_DSA:
3968 return (get_bigint_attr_from_object(
3969 OBJ_PUB_DSA_VALUE(object_p), template));
3971 case CKK_DH:
3972 return (get_bigint_attr_from_object(
3973 OBJ_PUB_DH_VALUE(object_p), template));
3975 case CKK_X9_42_DH:
3976 return (get_bigint_attr_from_object(
3977 OBJ_PUB_DH942_VALUE(object_p), template));
3979 default:
3980 template->ulValueLen = (CK_ULONG)-1;
3981 return (CKR_ATTRIBUTE_TYPE_INVALID);
3984 default:
3986 * First, get the value of the request attribute defined
3987 * in the list of common key attributes. If the request
3988 * attribute is not found in that list, then get the
3989 * attribute from the list of common attributes.
3991 rv = soft_get_common_key_attrs(object_p, template);
3992 if (rv == CKR_ATTRIBUTE_TYPE_INVALID) {
3993 rv = soft_get_common_attrs(object_p, template,
3994 object_p->object_type);
3996 break;
3999 return (rv);
4004 * Get the value of a requested attribute of a Private Key Object.
4006 * Rule: All the attributes in the private key object can be revealed
4007 * except those marked with footnote number "7" when the object
4008 * has its CKA_SENSITIVE attribute set to TRUE or its
4009 * CKA_EXTRACTABLE attribute set to FALSE (p.88 in PKCS11 spec.).
4011 CK_RV
4012 soft_get_private_key_attribute(soft_object_t *object_p,
4013 CK_ATTRIBUTE_PTR template)
4016 CK_RV rv = CKR_OK;
4017 CK_KEY_TYPE keytype = object_p->key_type;
4021 * If the following specified attributes for the private key
4022 * object cannot be revealed because the object is sensitive
4023 * or unextractable, then the ulValueLen is set to -1.
4025 if ((object_p->bool_attr_mask & SENSITIVE_BOOL_ON) ||
4026 !(object_p->bool_attr_mask & EXTRACTABLE_BOOL_ON)) {
4028 switch (template->type) {
4029 case CKA_PRIVATE_EXPONENT:
4030 case CKA_PRIME_1:
4031 case CKA_PRIME_2:
4032 case CKA_EXPONENT_1:
4033 case CKA_EXPONENT_2:
4034 case CKA_COEFFICIENT:
4035 case CKA_VALUE:
4036 template->ulValueLen = (CK_ULONG)-1;
4037 return (CKR_ATTRIBUTE_SENSITIVE);
4041 switch (template->type) {
4043 case CKA_SUBJECT:
4044 case CKA_EC_PARAMS:
4046 * The above extra attributes have byte array type.
4048 return (get_extra_attr_from_object(object_p,
4049 template));
4051 /* Key related boolean attributes */
4052 case CKA_SENSITIVE:
4053 return (get_bool_attr_from_object(object_p,
4054 SENSITIVE_BOOL_ON, template));
4056 case CKA_SECONDARY_AUTH:
4057 return (get_bool_attr_from_object(object_p,
4058 SECONDARY_AUTH_BOOL_ON, template));
4060 case CKA_DECRYPT:
4061 return (get_bool_attr_from_object(object_p,
4062 DECRYPT_BOOL_ON, template));
4064 case CKA_SIGN:
4065 return (get_bool_attr_from_object(object_p,
4066 SIGN_BOOL_ON, template));
4068 case CKA_SIGN_RECOVER:
4069 return (get_bool_attr_from_object(object_p,
4070 SIGN_RECOVER_BOOL_ON, template));
4072 case CKA_UNWRAP:
4073 return (get_bool_attr_from_object(object_p,
4074 UNWRAP_BOOL_ON, template));
4076 case CKA_EXTRACTABLE:
4077 return (get_bool_attr_from_object(object_p,
4078 EXTRACTABLE_BOOL_ON, template));
4080 case CKA_ALWAYS_SENSITIVE:
4081 return (get_bool_attr_from_object(object_p,
4082 ALWAYS_SENSITIVE_BOOL_ON, template));
4084 case CKA_NEVER_EXTRACTABLE:
4085 return (get_bool_attr_from_object(object_p,
4086 NEVER_EXTRACTABLE_BOOL_ON, template));
4088 case CKA_MODULUS:
4089 if (keytype == CKK_RSA) {
4090 return (get_bigint_attr_from_object(
4091 OBJ_PRI_RSA_MOD(object_p), template));
4092 } else {
4093 template->ulValueLen = (CK_ULONG)-1;
4094 rv = CKR_ATTRIBUTE_TYPE_INVALID;
4095 break;
4098 case CKA_PUBLIC_EXPONENT:
4099 if (keytype == CKK_RSA) {
4100 return (get_bigint_attr_from_object(
4101 OBJ_PRI_RSA_PUBEXPO(object_p), template));
4102 } else {
4103 template->ulValueLen = (CK_ULONG)-1;
4104 rv = CKR_ATTRIBUTE_TYPE_INVALID;
4105 break;
4108 case CKA_PRIVATE_EXPONENT:
4109 if (keytype == CKK_RSA) {
4110 return (get_bigint_attr_from_object(
4111 OBJ_PRI_RSA_PRIEXPO(object_p), template));
4112 } else {
4113 template->ulValueLen = (CK_ULONG)-1;
4114 rv = CKR_ATTRIBUTE_TYPE_INVALID;
4115 break;
4118 case CKA_PRIME_1:
4119 if (keytype == CKK_RSA) {
4120 return (get_bigint_attr_from_object(
4121 OBJ_PRI_RSA_PRIME1(object_p), template));
4122 } else {
4123 template->ulValueLen = (CK_ULONG)-1;
4124 rv = CKR_ATTRIBUTE_TYPE_INVALID;
4125 break;
4128 case CKA_PRIME_2:
4129 if (keytype == CKK_RSA) {
4130 return (get_bigint_attr_from_object(
4131 OBJ_PRI_RSA_PRIME2(object_p), template));
4132 } else {
4133 template->ulValueLen = (CK_ULONG)-1;
4134 rv = CKR_ATTRIBUTE_TYPE_INVALID;
4135 break;
4138 case CKA_EXPONENT_1:
4139 if (keytype == CKK_RSA) {
4140 return (get_bigint_attr_from_object(
4141 OBJ_PRI_RSA_EXPO1(object_p), template));
4142 } else {
4143 template->ulValueLen = (CK_ULONG)-1;
4144 rv = CKR_ATTRIBUTE_TYPE_INVALID;
4145 break;
4148 case CKA_EXPONENT_2:
4149 if (keytype == CKK_RSA) {
4150 return (get_bigint_attr_from_object(
4151 OBJ_PRI_RSA_EXPO2(object_p), template));
4152 } else {
4153 template->ulValueLen = (CK_ULONG)-1;
4154 rv = CKR_ATTRIBUTE_TYPE_INVALID;
4155 break;
4158 case CKA_COEFFICIENT:
4159 if (keytype == CKK_RSA) {
4160 return (get_bigint_attr_from_object(
4161 OBJ_PRI_RSA_COEF(object_p), template));
4162 } else {
4163 template->ulValueLen = (CK_ULONG)-1;
4164 rv = CKR_ATTRIBUTE_TYPE_INVALID;
4165 break;
4168 case CKA_VALUE_BITS:
4169 if (keytype == CKK_DH) {
4170 return (get_ulong_attr_from_object(
4171 OBJ_PRI_DH_VAL_BITS(object_p), template));
4172 } else {
4173 template->ulValueLen = (CK_ULONG)-1;
4174 rv = CKR_ATTRIBUTE_TYPE_INVALID;
4175 break;
4178 case CKA_PRIME:
4179 switch (keytype) {
4180 case CKK_DSA:
4181 return (get_bigint_attr_from_object(
4182 OBJ_PRI_DSA_PRIME(object_p), template));
4184 case CKK_DH:
4185 return (get_bigint_attr_from_object(
4186 OBJ_PRI_DH_PRIME(object_p), template));
4188 case CKK_X9_42_DH:
4189 return (get_bigint_attr_from_object(
4190 OBJ_PRI_DH942_PRIME(object_p), template));
4192 default:
4193 template->ulValueLen = (CK_ULONG)-1;
4194 return (CKR_ATTRIBUTE_TYPE_INVALID);
4197 case CKA_SUBPRIME:
4198 switch (keytype) {
4199 case CKK_DSA:
4200 return (get_bigint_attr_from_object(
4201 OBJ_PRI_DSA_SUBPRIME(object_p), template));
4203 case CKK_X9_42_DH:
4204 return (get_bigint_attr_from_object(
4205 OBJ_PRI_DH942_SUBPRIME(object_p), template));
4207 default:
4208 template->ulValueLen = (CK_ULONG)-1;
4209 return (CKR_ATTRIBUTE_TYPE_INVALID);
4212 case CKA_BASE:
4213 switch (keytype) {
4214 case CKK_DSA:
4215 return (get_bigint_attr_from_object(
4216 OBJ_PRI_DSA_BASE(object_p), template));
4218 case CKK_DH:
4219 return (get_bigint_attr_from_object(
4220 OBJ_PRI_DH_BASE(object_p), template));
4222 case CKK_X9_42_DH:
4223 return (get_bigint_attr_from_object(
4224 OBJ_PRI_DH942_BASE(object_p), template));
4226 default:
4227 template->ulValueLen = (CK_ULONG)-1;
4228 return (CKR_ATTRIBUTE_TYPE_INVALID);
4231 case CKA_VALUE:
4232 switch (keytype) {
4233 case CKK_DSA:
4234 return (get_bigint_attr_from_object(
4235 OBJ_PRI_DSA_VALUE(object_p), template));
4237 case CKK_DH:
4238 return (get_bigint_attr_from_object(
4239 OBJ_PRI_DH_VALUE(object_p), template));
4241 case CKK_X9_42_DH:
4242 return (get_bigint_attr_from_object(
4243 OBJ_PRI_DH942_VALUE(object_p), template));
4245 case CKK_EC:
4246 return (get_bigint_attr_from_object(
4247 OBJ_PRI_EC_VALUE(object_p), template));
4249 default:
4250 template->ulValueLen = (CK_ULONG)-1;
4251 return (CKR_ATTRIBUTE_TYPE_INVALID);
4254 default:
4256 * First, get the value of the request attribute defined
4257 * in the list of common key attributes. If the request
4258 * attribute is not found in that list, then get the
4259 * attribute from the list of common attributes.
4261 rv = soft_get_common_key_attrs(object_p, template);
4262 if (rv == CKR_ATTRIBUTE_TYPE_INVALID) {
4263 rv = soft_get_common_attrs(object_p, template,
4264 object_p->object_type);
4266 break;
4269 return (rv);
4274 * Get the value of a requested attribute of a Secret Key Object.
4276 * Rule: All the attributes in the secret key object can be revealed
4277 * except those marked with footnote number "7" when the object
4278 * has its CKA_SENSITIVE attribute set to TRUE or its
4279 * CKA_EXTRACTABLE attribute set to FALSE (p.88 in PKCS11 spec.).
4281 CK_RV
4282 soft_get_secret_key_attribute(soft_object_t *object_p,
4283 CK_ATTRIBUTE_PTR template)
4286 CK_RV rv = CKR_OK;
4287 CK_KEY_TYPE keytype = object_p->key_type;
4289 switch (template->type) {
4291 /* Key related boolean attributes */
4292 case CKA_SENSITIVE:
4293 return (get_bool_attr_from_object(object_p,
4294 SENSITIVE_BOOL_ON, template));
4296 case CKA_ENCRYPT:
4297 return (get_bool_attr_from_object(object_p,
4298 ENCRYPT_BOOL_ON, template));
4300 case CKA_DECRYPT:
4301 return (get_bool_attr_from_object(object_p,
4302 DECRYPT_BOOL_ON, template));
4304 case CKA_SIGN:
4305 return (get_bool_attr_from_object(object_p,
4306 SIGN_BOOL_ON, template));
4308 case CKA_VERIFY:
4309 return (get_bool_attr_from_object(object_p,
4310 VERIFY_BOOL_ON, template));
4312 case CKA_WRAP:
4313 return (get_bool_attr_from_object(object_p,
4314 WRAP_BOOL_ON, template));
4316 case CKA_UNWRAP:
4317 return (get_bool_attr_from_object(object_p,
4318 UNWRAP_BOOL_ON, template));
4320 case CKA_EXTRACTABLE:
4321 return (get_bool_attr_from_object(object_p,
4322 EXTRACTABLE_BOOL_ON, template));
4324 case CKA_ALWAYS_SENSITIVE:
4325 return (get_bool_attr_from_object(object_p,
4326 ALWAYS_SENSITIVE_BOOL_ON, template));
4328 case CKA_NEVER_EXTRACTABLE:
4329 return (get_bool_attr_from_object(object_p,
4330 NEVER_EXTRACTABLE_BOOL_ON, template));
4332 case CKA_VALUE:
4333 case CKA_VALUE_LEN:
4335 * If the specified attribute for the secret key object
4336 * cannot be revealed because the object is sensitive
4337 * or unextractable, then the ulValueLen is set to -1.
4339 if ((object_p->bool_attr_mask & SENSITIVE_BOOL_ON) ||
4340 !(object_p->bool_attr_mask & EXTRACTABLE_BOOL_ON)) {
4341 template->ulValueLen = (CK_ULONG)-1;
4342 return (CKR_ATTRIBUTE_SENSITIVE);
4345 switch (keytype) {
4346 case CKK_RC4:
4347 case CKK_GENERIC_SECRET:
4348 case CKK_RC5:
4349 case CKK_DES:
4350 case CKK_DES2:
4351 case CKK_DES3:
4352 case CKK_CDMF:
4353 case CKK_AES:
4354 case CKK_BLOWFISH:
4355 if (template->type == CKA_VALUE_LEN) {
4356 return (get_ulong_attr_from_object(
4357 OBJ_SEC_VALUE_LEN(object_p),
4358 template));
4359 } else {
4360 return (get_bigint_attr_from_object(
4361 (biginteger_t *)OBJ_SEC(object_p),
4362 template));
4364 default:
4365 template->ulValueLen = (CK_ULONG)-1;
4366 rv = CKR_ATTRIBUTE_TYPE_INVALID;
4367 break;
4369 break;
4371 default:
4373 * First, get the value of the request attribute defined
4374 * in the list of common key attributes. If the request
4375 * attribute is not found in that list, then get the
4376 * attribute from the list of common attributes.
4378 rv = soft_get_common_key_attrs(object_p, template);
4379 if (rv == CKR_ATTRIBUTE_TYPE_INVALID) {
4380 rv = soft_get_common_attrs(object_p, template,
4381 object_p->object_type);
4383 break;
4386 return (rv);
4391 * Get the value of a requested attribute of a Domain Parameters Object.
4393 * Rule: All the attributes in the domain parameters object can be revealed.
4395 CK_RV
4396 soft_get_domain_parameters_attribute(soft_object_t *object_p,
4397 CK_ATTRIBUTE_PTR template)
4400 CK_RV rv = CKR_OK;
4401 CK_KEY_TYPE keytype = object_p->key_type;
4403 switch (template->type) {
4405 case CKA_KEY_TYPE:
4406 return (get_ulong_attr_from_object(keytype,
4407 template));
4409 case CKA_LOCAL:
4410 return (get_bool_attr_from_object(object_p,
4411 LOCAL_BOOL_ON, template));
4413 case CKA_PRIME:
4414 switch (keytype) {
4415 case CKK_DSA:
4416 return (get_bigint_attr_from_object(
4417 OBJ_DOM_DSA_PRIME(object_p), template));
4419 case CKK_DH:
4420 return (get_bigint_attr_from_object(
4421 OBJ_DOM_DH_PRIME(object_p), template));
4423 case CKK_X9_42_DH:
4424 return (get_bigint_attr_from_object(
4425 OBJ_DOM_DH942_PRIME(object_p), template));
4427 default:
4428 template->ulValueLen = (CK_ULONG)-1;
4429 return (CKR_ATTRIBUTE_TYPE_INVALID);
4432 case CKA_SUBPRIME:
4433 switch (keytype) {
4434 case CKK_DSA:
4435 return (get_bigint_attr_from_object(
4436 OBJ_DOM_DSA_SUBPRIME(object_p), template));
4438 case CKK_X9_42_DH:
4439 return (get_bigint_attr_from_object(
4440 OBJ_DOM_DH942_SUBPRIME(object_p), template));
4442 default:
4443 template->ulValueLen = (CK_ULONG)-1;
4444 return (CKR_ATTRIBUTE_TYPE_INVALID);
4447 case CKA_BASE:
4448 switch (keytype) {
4449 case CKK_DSA:
4450 return (get_bigint_attr_from_object(
4451 OBJ_DOM_DSA_BASE(object_p), template));
4453 case CKK_DH:
4454 return (get_bigint_attr_from_object(
4455 OBJ_DOM_DH_BASE(object_p), template));
4457 case CKK_X9_42_DH:
4458 return (get_bigint_attr_from_object(
4459 OBJ_DOM_DH942_BASE(object_p), template));
4461 default:
4462 template->ulValueLen = (CK_ULONG)-1;
4463 return (CKR_ATTRIBUTE_TYPE_INVALID);
4466 case CKA_PRIME_BITS:
4467 switch (keytype) {
4468 case CKK_DSA:
4469 return (get_ulong_attr_from_object(
4470 OBJ_DOM_DSA_PRIME_BITS(object_p), template));
4472 case CKK_DH:
4473 return (get_ulong_attr_from_object(
4474 OBJ_DOM_DH_PRIME_BITS(object_p), template));
4476 case CKK_X9_42_DH:
4477 return (get_ulong_attr_from_object(
4478 OBJ_DOM_DH942_PRIME_BITS(object_p), template));
4480 default:
4481 template->ulValueLen = (CK_ULONG)-1;
4482 return (CKR_ATTRIBUTE_TYPE_INVALID);
4485 case CKA_SUB_PRIME_BITS:
4486 switch (keytype) {
4487 case CKK_X9_42_DH:
4488 return (get_ulong_attr_from_object(
4489 OBJ_DOM_DH942_SUBPRIME_BITS(object_p), template));
4491 default:
4492 template->ulValueLen = (CK_ULONG)-1;
4493 return (CKR_ATTRIBUTE_TYPE_INVALID);
4496 default:
4498 * Get the value of a common attribute.
4500 rv = soft_get_common_attrs(object_p, template,
4501 object_p->object_type);
4502 break;
4505 return (rv);
4509 * Get certificate attributes from an object.
4510 * return CKR_ATTRIBUTE_TYPE_INVALID if the requested type
4511 * does not exist in the certificate.
4513 CK_RV
4514 soft_get_certificate_attribute(soft_object_t *object_p,
4515 CK_ATTRIBUTE_PTR template)
4517 CK_CERTIFICATE_TYPE certtype = object_p->cert_type;
4518 cert_attr_t src;
4520 switch (template->type) {
4521 case CKA_SUBJECT:
4522 if (certtype == CKC_X_509) {
4523 return (get_cert_attr_from_object(
4524 X509_CERT_SUBJECT(object_p), template));
4526 break;
4527 case CKA_VALUE:
4528 if (certtype == CKC_X_509) {
4529 return (get_cert_attr_from_object(
4530 X509_CERT_VALUE(object_p), template));
4531 } else if (certtype == CKC_X_509_ATTR_CERT) {
4532 return (get_cert_attr_from_object(
4533 X509_ATTR_CERT_VALUE(object_p), template));
4535 break;
4536 case CKA_OWNER:
4537 if (certtype == CKC_X_509_ATTR_CERT) {
4538 return (get_cert_attr_from_object(
4539 X509_ATTR_CERT_OWNER(object_p), template));
4541 break;
4542 case CKA_CERTIFICATE_TYPE:
4543 src.value = (CK_BYTE *)&certtype;
4544 src.length = sizeof (certtype);
4545 return (get_cert_attr_from_object(&src, template));
4546 case CKA_TRUSTED:
4547 return (get_bool_attr_from_object(object_p,
4548 TRUSTED_BOOL_ON, template));
4549 case CKA_ID:
4550 case CKA_ISSUER:
4551 case CKA_SERIAL_NUMBER:
4552 case CKA_AC_ISSUER:
4553 case CKA_ATTR_TYPES:
4554 return (get_extra_attr_from_object(object_p,
4555 template));
4556 default:
4557 return (soft_get_common_attrs(object_p, template,
4558 object_p->object_type));
4562 * If we got this far, then the combination of certificate type
4563 * and requested attribute is invalid.
4565 return (CKR_ATTRIBUTE_TYPE_INVALID);
4568 CK_RV
4569 soft_set_certificate_attribute(soft_object_t *object_p,
4570 CK_ATTRIBUTE_PTR template, boolean_t copy)
4572 CK_CERTIFICATE_TYPE certtype = object_p->cert_type;
4574 switch (template->type) {
4575 case CKA_SUBJECT:
4576 if (certtype == CKC_X_509) {
4577 /* SUBJECT attr cannot be modified. */
4578 return (CKR_ATTRIBUTE_READ_ONLY);
4580 break;
4581 case CKA_OWNER:
4582 if (certtype == CKC_X_509_ATTR_CERT) {
4583 /* OWNER attr cannot be modified. */
4584 return (CKR_ATTRIBUTE_READ_ONLY);
4586 break;
4587 case CKA_VALUE:
4588 /* VALUE attr cannot be modified. */
4589 return (CKR_ATTRIBUTE_READ_ONLY);
4590 case CKA_ID:
4591 case CKA_ISSUER:
4592 if (certtype == CKC_X_509) {
4593 return (set_extra_attr_to_object(object_p,
4594 template->type, template));
4596 break;
4597 case CKA_AC_ISSUER:
4598 case CKA_ATTR_TYPES:
4599 if (certtype == CKC_X_509_ATTR_CERT) {
4600 return (set_extra_attr_to_object(object_p,
4601 template->type, template));
4603 break;
4604 case CKA_SERIAL_NUMBER:
4605 case CKA_LABEL:
4606 return (set_extra_attr_to_object(object_p,
4607 template->type, template));
4608 default:
4609 return (soft_set_common_storage_attribute(
4610 object_p, template, copy));
4614 * If we got this far, then the combination of certificate type
4615 * and requested attribute is invalid.
4617 return (CKR_ATTRIBUTE_TYPE_INVALID);
4621 * Call the appropriate get attribute function according to the class
4622 * of object.
4624 * The caller of this function holds the lock on the object.
4626 CK_RV
4627 soft_get_attribute(soft_object_t *object_p, CK_ATTRIBUTE_PTR template)
4630 CK_RV rv = CKR_OK;
4631 CK_OBJECT_CLASS class = object_p->class;
4633 switch (class) {
4634 case CKO_PUBLIC_KEY:
4635 rv = soft_get_public_key_attribute(object_p, template);
4636 break;
4638 case CKO_PRIVATE_KEY:
4639 rv = soft_get_private_key_attribute(object_p, template);
4640 break;
4642 case CKO_SECRET_KEY:
4643 rv = soft_get_secret_key_attribute(object_p, template);
4644 break;
4646 case CKO_DOMAIN_PARAMETERS:
4647 rv = soft_get_domain_parameters_attribute(object_p, template);
4648 break;
4650 case CKO_CERTIFICATE:
4651 rv = soft_get_certificate_attribute(object_p, template);
4652 break;
4654 default:
4656 * If the specified attribute for the object is invalid
4657 * (the object does not possess such as attribute), then
4658 * the ulValueLen is modified to hold the value -1.
4660 template->ulValueLen = (CK_ULONG)-1;
4661 return (CKR_ATTRIBUTE_TYPE_INVALID);
4664 return (rv);
4668 CK_RV
4669 soft_set_common_storage_attribute(soft_object_t *object_p,
4670 CK_ATTRIBUTE_PTR template, boolean_t copy)
4673 CK_RV rv = CKR_OK;
4675 switch (template->type) {
4677 case CKA_TOKEN:
4678 if (copy) {
4679 if ((*(CK_BBOOL *)template->pValue) == B_TRUE) {
4680 if (!soft_keystore_status(KEYSTORE_INITIALIZED))
4681 return (CKR_DEVICE_REMOVED);
4682 object_p->object_type |= TOKEN_OBJECT;
4684 } else {
4685 rv = CKR_ATTRIBUTE_READ_ONLY;
4688 break;
4690 case CKA_PRIVATE:
4691 if (copy) {
4692 if ((*(CK_BBOOL *)template->pValue) == B_TRUE) {
4693 (void) pthread_mutex_lock(&soft_giant_mutex);
4694 if (!soft_slot.authenticated) {
4696 * Check if this is the special case
4697 * when the PIN is never initialized
4698 * in the keystore. If true, we will
4699 * let it pass here and let it fail
4700 * with CKR_PIN_EXPIRED later on.
4702 if (!soft_slot.userpin_change_needed) {
4703 (void) pthread_mutex_unlock(
4704 &soft_giant_mutex);
4705 return (CKR_USER_NOT_LOGGED_IN);
4708 (void) pthread_mutex_unlock(&soft_giant_mutex);
4709 object_p->object_type |= PRIVATE_OBJECT;
4711 } else {
4712 rv = CKR_ATTRIBUTE_READ_ONLY;
4714 break;
4716 case CKA_MODIFIABLE:
4717 if (copy) {
4718 if ((*(CK_BBOOL *)template->pValue) == TRUE)
4719 object_p->bool_attr_mask &=
4720 ~NOT_MODIFIABLE_BOOL_ON;
4721 else
4722 object_p->bool_attr_mask |=
4723 NOT_MODIFIABLE_BOOL_ON;
4724 } else {
4725 rv = CKR_ATTRIBUTE_READ_ONLY;
4727 break;
4729 case CKA_CLASS:
4730 rv = CKR_ATTRIBUTE_READ_ONLY;
4731 break;
4733 default:
4734 rv = CKR_TEMPLATE_INCONSISTENT;
4737 return (rv);
4741 * Set the value of an attribute that is common to all key objects
4742 * (i.e. public key, private key and secret key).
4744 CK_RV
4745 soft_set_common_key_attribute(soft_object_t *object_p,
4746 CK_ATTRIBUTE_PTR template, boolean_t copy)
4749 switch (template->type) {
4751 case CKA_LABEL:
4753 * Only the LABEL can be modified in the common storage
4754 * object attributes after the object is created.
4756 return (set_extra_attr_to_object(object_p,
4757 CKA_LABEL, template));
4759 case CKA_ID:
4760 return (set_extra_attr_to_object(object_p,
4761 CKA_ID, template));
4763 case CKA_START_DATE:
4764 return (set_extra_attr_to_object(object_p,
4765 CKA_START_DATE, template));
4767 case CKA_END_DATE:
4768 return (set_extra_attr_to_object(object_p,
4769 CKA_END_DATE, template));
4771 case CKA_DERIVE:
4772 return (set_bool_attr_to_object(object_p,
4773 DERIVE_BOOL_ON, template));
4775 case CKA_KEY_TYPE:
4776 case CKA_LOCAL:
4777 case CKA_KEY_GEN_MECHANISM:
4778 return (CKR_ATTRIBUTE_READ_ONLY);
4780 default:
4781 return (soft_set_common_storage_attribute(object_p,
4782 template, copy));
4790 * Set the value of an attribute of a Public Key Object.
4792 * Rule: The attributes marked with footnote number "8" in the PKCS11
4793 * spec may be modified (p.88 in PKCS11 spec.).
4795 CK_RV
4796 soft_set_public_key_attribute(soft_object_t *object_p,
4797 CK_ATTRIBUTE_PTR template, boolean_t copy)
4799 CK_KEY_TYPE keytype = object_p->key_type;
4801 switch (template->type) {
4803 case CKA_SUBJECT:
4804 return (set_extra_attr_to_object(object_p,
4805 CKA_SUBJECT, template));
4807 case CKA_ENCRYPT:
4808 return (set_bool_attr_to_object(object_p,
4809 ENCRYPT_BOOL_ON, template));
4811 case CKA_VERIFY:
4812 return (set_bool_attr_to_object(object_p,
4813 VERIFY_BOOL_ON, template));
4815 case CKA_VERIFY_RECOVER:
4816 return (set_bool_attr_to_object(object_p,
4817 VERIFY_RECOVER_BOOL_ON, template));
4819 case CKA_WRAP:
4820 return (set_bool_attr_to_object(object_p,
4821 WRAP_BOOL_ON, template));
4823 case CKA_MODULUS:
4824 case CKA_MODULUS_BITS:
4825 case CKA_PUBLIC_EXPONENT:
4826 if (keytype == CKK_RSA)
4827 return (CKR_ATTRIBUTE_READ_ONLY);
4828 break;
4830 case CKA_SUBPRIME:
4831 if ((keytype == CKK_DSA) ||
4832 (keytype == CKK_X9_42_DH))
4833 return (CKR_ATTRIBUTE_READ_ONLY);
4834 break;
4836 case CKA_PRIME:
4837 case CKA_BASE:
4838 case CKA_VALUE:
4839 if ((keytype == CKK_DSA) ||
4840 (keytype == CKK_DH) ||
4841 (keytype == CKK_X9_42_DH))
4842 return (CKR_ATTRIBUTE_READ_ONLY);
4843 break;
4845 default:
4847 * Set the value of a common key attribute.
4849 return (soft_set_common_key_attribute(object_p,
4850 template, copy));
4854 * If we got this far, then the combination of key type
4855 * and requested attribute is invalid.
4857 return (CKR_ATTRIBUTE_TYPE_INVALID);
4862 * Set the value of an attribute of a Private Key Object.
4864 * Rule: The attributes marked with footnote number "8" in the PKCS11
4865 * spec may be modified (p.88 in PKCS11 spec.).
4867 CK_RV
4868 soft_set_private_key_attribute(soft_object_t *object_p,
4869 CK_ATTRIBUTE_PTR template, boolean_t copy)
4871 CK_KEY_TYPE keytype = object_p->key_type;
4873 switch (template->type) {
4875 case CKA_SUBJECT:
4876 return (set_extra_attr_to_object(object_p,
4877 CKA_SUBJECT, template));
4879 case CKA_SENSITIVE:
4881 * Cannot set SENSITIVE to FALSE if it is already ON.
4883 if (((*(CK_BBOOL *)template->pValue) == B_FALSE) &&
4884 (object_p->bool_attr_mask & SENSITIVE_BOOL_ON)) {
4885 return (CKR_ATTRIBUTE_READ_ONLY);
4888 if (*(CK_BBOOL *)template->pValue)
4889 object_p->bool_attr_mask |= SENSITIVE_BOOL_ON;
4890 return (CKR_OK);
4892 case CKA_DECRYPT:
4893 return (set_bool_attr_to_object(object_p,
4894 DECRYPT_BOOL_ON, template));
4896 case CKA_SIGN:
4897 return (set_bool_attr_to_object(object_p,
4898 SIGN_BOOL_ON, template));
4900 case CKA_SIGN_RECOVER:
4901 return (set_bool_attr_to_object(object_p,
4902 SIGN_RECOVER_BOOL_ON, template));
4904 case CKA_UNWRAP:
4905 return (set_bool_attr_to_object(object_p,
4906 UNWRAP_BOOL_ON, template));
4908 case CKA_EXTRACTABLE:
4910 * Cannot set EXTRACTABLE to TRUE if it is already OFF.
4912 if ((*(CK_BBOOL *)template->pValue) &&
4913 !(object_p->bool_attr_mask & EXTRACTABLE_BOOL_ON)) {
4914 return (CKR_ATTRIBUTE_READ_ONLY);
4917 if ((*(CK_BBOOL *)template->pValue) == B_FALSE)
4918 object_p->bool_attr_mask &= ~EXTRACTABLE_BOOL_ON;
4919 return (CKR_OK);
4921 case CKA_MODULUS:
4922 case CKA_PUBLIC_EXPONENT:
4923 case CKA_PRIVATE_EXPONENT:
4924 case CKA_PRIME_1:
4925 case CKA_PRIME_2:
4926 case CKA_EXPONENT_1:
4927 case CKA_EXPONENT_2:
4928 case CKA_COEFFICIENT:
4929 if (keytype == CKK_RSA) {
4930 return (CKR_ATTRIBUTE_READ_ONLY);
4932 break;
4934 case CKA_SUBPRIME:
4935 if ((keytype == CKK_DSA) ||
4936 (keytype == CKK_X9_42_DH))
4937 return (CKR_ATTRIBUTE_READ_ONLY);
4938 break;
4940 case CKA_PRIME:
4941 case CKA_BASE:
4942 case CKA_VALUE:
4943 if ((keytype == CKK_DSA) ||
4944 (keytype == CKK_DH) ||
4945 (keytype == CKK_X9_42_DH))
4946 return (CKR_ATTRIBUTE_READ_ONLY);
4947 break;
4949 case CKA_VALUE_BITS:
4950 if (keytype == CKK_DH)
4951 return (CKR_ATTRIBUTE_READ_ONLY);
4952 break;
4954 default:
4956 * Set the value of a common key attribute.
4958 return (soft_set_common_key_attribute(object_p,
4959 template, copy));
4963 * If we got this far, then the combination of key type
4964 * and requested attribute is invalid.
4966 return (CKR_ATTRIBUTE_TYPE_INVALID);
4970 * Set the value of an attribute of a Secret Key Object.
4972 * Rule: The attributes marked with footnote number "8" in the PKCS11
4973 * spec may be modified (p.88 in PKCS11 spec.).
4975 CK_RV
4976 soft_set_secret_key_attribute(soft_object_t *object_p,
4977 CK_ATTRIBUTE_PTR template, boolean_t copy)
4979 CK_KEY_TYPE keytype = object_p->key_type;
4981 switch (template->type) {
4983 case CKA_SENSITIVE:
4985 * Cannot set SENSITIVE to FALSE if it is already ON.
4987 if (((*(CK_BBOOL *)template->pValue) == B_FALSE) &&
4988 (object_p->bool_attr_mask & SENSITIVE_BOOL_ON)) {
4989 return (CKR_ATTRIBUTE_READ_ONLY);
4992 if (*(CK_BBOOL *)template->pValue)
4993 object_p->bool_attr_mask |= SENSITIVE_BOOL_ON;
4994 return (CKR_OK);
4996 case CKA_ENCRYPT:
4997 return (set_bool_attr_to_object(object_p,
4998 ENCRYPT_BOOL_ON, template));
5000 case CKA_DECRYPT:
5001 return (set_bool_attr_to_object(object_p,
5002 DECRYPT_BOOL_ON, template));
5004 case CKA_SIGN:
5005 return (set_bool_attr_to_object(object_p,
5006 SIGN_BOOL_ON, template));
5008 case CKA_VERIFY:
5009 return (set_bool_attr_to_object(object_p,
5010 VERIFY_BOOL_ON, template));
5012 case CKA_WRAP:
5013 return (set_bool_attr_to_object(object_p,
5014 WRAP_BOOL_ON, template));
5016 case CKA_UNWRAP:
5017 return (set_bool_attr_to_object(object_p,
5018 UNWRAP_BOOL_ON, template));
5020 case CKA_EXTRACTABLE:
5022 * Cannot set EXTRACTABLE to TRUE if it is already OFF.
5024 if ((*(CK_BBOOL *)template->pValue) &&
5025 !(object_p->bool_attr_mask & EXTRACTABLE_BOOL_ON)) {
5026 return (CKR_ATTRIBUTE_READ_ONLY);
5029 if ((*(CK_BBOOL *)template->pValue) == B_FALSE)
5030 object_p->bool_attr_mask &= ~EXTRACTABLE_BOOL_ON;
5031 return (CKR_OK);
5033 case CKA_VALUE:
5034 return (CKR_ATTRIBUTE_READ_ONLY);
5036 case CKA_VALUE_LEN:
5037 if ((keytype == CKK_RC4) ||
5038 (keytype == CKK_GENERIC_SECRET) ||
5039 (keytype == CKK_AES) ||
5040 (keytype == CKK_BLOWFISH))
5041 return (CKR_ATTRIBUTE_READ_ONLY);
5042 break;
5044 default:
5046 * Set the value of a common key attribute.
5048 return (soft_set_common_key_attribute(object_p,
5049 template, copy));
5053 * If we got this far, then the combination of key type
5054 * and requested attribute is invalid.
5056 return (CKR_ATTRIBUTE_TYPE_INVALID);
5061 * Call the appropriate set attribute function according to the class
5062 * of object.
5064 * The caller of this function does not hold the lock on the original
5065 * object, since this function is setting the attribute on the new object
5066 * that is being modified.
5068 * Argument copy: TRUE when called by C_CopyObject,
5069 * FALSE when called by C_SetAttributeValue.
5071 CK_RV
5072 soft_set_attribute(soft_object_t *object_p, CK_ATTRIBUTE_PTR template,
5073 boolean_t copy)
5076 CK_RV rv = CKR_OK;
5077 CK_OBJECT_CLASS class = object_p->class;
5079 switch (class) {
5081 case CKO_PUBLIC_KEY:
5082 rv = soft_set_public_key_attribute(object_p, template, copy);
5083 break;
5085 case CKO_PRIVATE_KEY:
5086 rv = soft_set_private_key_attribute(object_p, template, copy);
5087 break;
5089 case CKO_SECRET_KEY:
5090 rv = soft_set_secret_key_attribute(object_p, template, copy);
5091 break;
5093 case CKO_DOMAIN_PARAMETERS:
5094 switch (template->type) {
5095 case CKA_LABEL:
5097 * Only the LABEL can be modified in the common
5098 * storage object attributes after the object is
5099 * created.
5101 return (set_extra_attr_to_object(object_p,
5102 CKA_LABEL, template));
5103 default:
5104 return (CKR_TEMPLATE_INCONSISTENT);
5106 case CKO_CERTIFICATE:
5107 rv = soft_set_certificate_attribute(object_p, template, copy);
5108 break;
5110 default:
5112 * If the template specifies a value of an attribute
5113 * which is incompatible with other existing attributes
5114 * of the object, then fails with return code
5115 * CKR_TEMPLATE_INCONSISTENT.
5117 rv = CKR_TEMPLATE_INCONSISTENT;
5118 break;
5121 return (rv);
5124 CK_RV
5125 soft_get_public_value(soft_object_t *key, CK_ATTRIBUTE_TYPE type,
5126 uchar_t *value, uint32_t *value_len)
5128 uint32_t len = 0;
5129 switch (type) {
5131 /* The following attributes belong to RSA */
5132 case CKA_MODULUS:
5133 len =
5134 ((biginteger_t *)OBJ_PUB_RSA_MOD(key))->big_value_len;
5136 /* This attribute MUST BE set */
5137 if (len == 0 || len > *value_len) {
5138 return (CKR_ATTRIBUTE_VALUE_INVALID);
5140 *value_len = len;
5142 (void) memcpy(value,
5143 ((biginteger_t *)OBJ_PUB_RSA_MOD(key))->big_value,
5144 *value_len);
5146 break;
5148 case CKA_PUBLIC_EXPONENT:
5149 len =
5150 ((biginteger_t *)OBJ_PUB_RSA_PUBEXPO(key))->big_value_len;
5152 /* This attribute MUST BE set */
5153 if (len == 0 || len > *value_len) {
5154 return (CKR_ATTRIBUTE_VALUE_INVALID);
5156 *value_len = len;
5158 (void) memcpy(value,
5159 ((biginteger_t *)OBJ_PUB_RSA_PUBEXPO(key))->big_value,
5160 *value_len);
5162 break;
5164 /* The following attributes belong to DSA and DH */
5165 case CKA_PRIME:
5167 if (key->key_type == CKK_DSA)
5168 len =
5169 ((biginteger_t *)OBJ_PUB_DSA_PRIME(key))->
5170 big_value_len;
5171 else
5172 len =
5173 ((biginteger_t *)OBJ_PUB_DH_PRIME(key))->
5174 big_value_len;
5176 /* This attribute MUST BE set */
5177 if (len == 0 || len > *value_len) {
5178 return (CKR_ATTRIBUTE_VALUE_INVALID);
5180 *value_len = len;
5182 if (key->key_type == CKK_DSA)
5183 (void) memcpy(value,
5184 ((biginteger_t *)OBJ_PUB_DSA_PRIME(key))->big_value,
5185 *value_len);
5186 else
5187 (void) memcpy(value,
5188 ((biginteger_t *)OBJ_PUB_DH_PRIME(key))->big_value,
5189 *value_len);
5191 break;
5193 case CKA_SUBPRIME:
5194 len =
5195 ((biginteger_t *)OBJ_PUB_DSA_SUBPRIME(key))->big_value_len;
5197 /* This attribute MUST BE set */
5198 if (len == 0 || len > *value_len) {
5199 return (CKR_ATTRIBUTE_VALUE_INVALID);
5201 *value_len = len;
5203 (void) memcpy(value,
5204 ((biginteger_t *)OBJ_PUB_DSA_SUBPRIME(key))->big_value,
5205 *value_len);
5207 break;
5209 case CKA_BASE:
5211 if (key->key_type == CKK_DSA)
5212 len =
5213 ((biginteger_t *)OBJ_PUB_DSA_BASE(key))->
5214 big_value_len;
5215 else
5216 len =
5217 ((biginteger_t *)OBJ_PUB_DH_BASE(key))->
5218 big_value_len;
5220 /* This attribute MUST BE set */
5221 if (len == 0 || len > *value_len) {
5222 return (CKR_ATTRIBUTE_VALUE_INVALID);
5224 *value_len = len;
5226 if (key->key_type == CKK_DSA)
5227 (void) memcpy(value,
5228 ((biginteger_t *)OBJ_PUB_DSA_BASE(key))->big_value,
5229 *value_len);
5230 else
5231 (void) memcpy(value,
5232 ((biginteger_t *)OBJ_PUB_DH_BASE(key))->big_value,
5233 *value_len);
5234 break;
5236 case CKA_VALUE:
5238 if (key->key_type == CKK_DSA)
5239 len =
5240 ((biginteger_t *)OBJ_PUB_DSA_VALUE(key))->
5241 big_value_len;
5242 else
5243 len =
5244 ((biginteger_t *)OBJ_PUB_DH_VALUE(key))->
5245 big_value_len;
5247 /* This attribute MUST BE set */
5248 if (len == 0 || len > *value_len) {
5249 return (CKR_ATTRIBUTE_VALUE_INVALID);
5251 *value_len = len;
5253 if (key->key_type == CKK_DSA)
5254 (void) memcpy(value,
5255 ((biginteger_t *)OBJ_PUB_DSA_VALUE(key))->big_value,
5256 *value_len);
5257 else
5258 (void) memcpy(value,
5259 ((biginteger_t *)OBJ_PUB_DH_VALUE(key))->big_value,
5260 *value_len);
5262 break;
5265 return (CKR_OK);
5269 CK_RV
5270 soft_get_private_value(soft_object_t *key, CK_ATTRIBUTE_TYPE type,
5271 uchar_t *value, uint32_t *value_len)
5274 uint32_t len = 0;
5276 switch (type) {
5278 /* The following attributes belong to RSA */
5279 case CKA_MODULUS:
5280 len =
5281 ((biginteger_t *)OBJ_PRI_RSA_MOD(key))->big_value_len;
5283 /* This attribute MUST BE set */
5284 if (len == 0 || len > *value_len) {
5285 return (CKR_ATTRIBUTE_VALUE_INVALID);
5287 *value_len = len;
5289 (void) memcpy(value,
5290 ((biginteger_t *)OBJ_PRI_RSA_MOD(key))->big_value,
5291 *value_len);
5293 break;
5295 case CKA_PRIVATE_EXPONENT:
5296 len =
5297 ((biginteger_t *)OBJ_PRI_RSA_PRIEXPO(key))->big_value_len;
5299 /* This attribute MUST BE set */
5300 if (len == 0 || len > *value_len) {
5301 return (CKR_ATTRIBUTE_VALUE_INVALID);
5303 *value_len = len;
5305 (void) memcpy(value,
5306 ((biginteger_t *)OBJ_PRI_RSA_PRIEXPO(key))->big_value,
5307 *value_len);
5309 break;
5311 case CKA_PRIME_1:
5312 len =
5313 ((biginteger_t *)OBJ_PRI_RSA_PRIME1(key))->big_value_len;
5315 if (len > *value_len) {
5316 return (CKR_ATTRIBUTE_VALUE_INVALID);
5318 *value_len = len;
5320 if (*value_len == 0) {
5321 return (CKR_OK);
5324 (void) memcpy(value,
5325 ((biginteger_t *)OBJ_PRI_RSA_PRIME1(key))->big_value,
5326 *value_len);
5328 break;
5330 case CKA_PRIME_2:
5331 len =
5332 ((biginteger_t *)OBJ_PRI_RSA_PRIME2(key))->big_value_len;
5334 if (len > *value_len) {
5335 return (CKR_ATTRIBUTE_VALUE_INVALID);
5337 *value_len = len;
5339 if (*value_len == 0) {
5340 return (CKR_OK);
5343 (void) memcpy(value,
5344 ((biginteger_t *)OBJ_PRI_RSA_PRIME2(key))->big_value,
5345 *value_len);
5347 break;
5349 case CKA_EXPONENT_1:
5350 len =
5351 ((biginteger_t *)OBJ_PRI_RSA_EXPO1(key))->big_value_len;
5353 if (len > *value_len) {
5354 return (CKR_ATTRIBUTE_VALUE_INVALID);
5356 *value_len = len;
5358 if (*value_len == 0) {
5359 return (CKR_OK);
5362 (void) memcpy(value,
5363 ((biginteger_t *)OBJ_PRI_RSA_EXPO1(key))->big_value,
5364 *value_len);
5366 break;
5368 case CKA_EXPONENT_2:
5369 len =
5370 ((biginteger_t *)OBJ_PRI_RSA_EXPO2(key))->big_value_len;
5372 if (len > *value_len) {
5373 return (CKR_ATTRIBUTE_VALUE_INVALID);
5375 *value_len = len;
5377 if (*value_len == 0) {
5378 return (CKR_OK);
5381 (void) memcpy(value,
5382 ((biginteger_t *)OBJ_PRI_RSA_EXPO2(key))->big_value,
5383 *value_len);
5385 break;
5387 case CKA_COEFFICIENT:
5388 len =
5389 ((biginteger_t *)OBJ_PRI_RSA_COEF(key))->big_value_len;
5391 if (len > *value_len) {
5392 return (CKR_ATTRIBUTE_VALUE_INVALID);
5394 *value_len = len;
5396 if (*value_len == 0) {
5397 return (CKR_OK);
5400 (void) memcpy(value,
5401 ((biginteger_t *)OBJ_PRI_RSA_COEF(key))->big_value,
5402 *value_len);
5404 break;
5406 /* The following attributes belong to DSA and DH */
5407 case CKA_PRIME:
5409 if (key->key_type == CKK_DSA)
5410 len =
5411 ((biginteger_t *)OBJ_PRI_DSA_PRIME(key))->
5412 big_value_len;
5413 else
5414 len =
5415 ((biginteger_t *)OBJ_PRI_DH_PRIME(key))->
5416 big_value_len;
5418 /* This attribute MUST BE set */
5419 if (len == 0 || len > *value_len) {
5420 return (CKR_ATTRIBUTE_VALUE_INVALID);
5422 *value_len = len;
5424 if (key->key_type == CKK_DSA)
5425 (void) memcpy(value,
5426 ((biginteger_t *)OBJ_PRI_DSA_PRIME(key))->big_value,
5427 *value_len);
5428 else
5429 (void) memcpy(value,
5430 ((biginteger_t *)OBJ_PRI_DH_PRIME(key))->big_value,
5431 *value_len);
5433 break;
5435 case CKA_SUBPRIME:
5436 len =
5437 ((biginteger_t *)OBJ_PRI_DSA_SUBPRIME(key))->big_value_len;
5439 /* This attribute MUST BE set */
5440 if (len == 0 || len > *value_len) {
5441 return (CKR_ATTRIBUTE_VALUE_INVALID);
5443 *value_len = len;
5445 (void) memcpy(value,
5446 ((biginteger_t *)OBJ_PRI_DSA_SUBPRIME(key))->big_value,
5447 *value_len);
5449 break;
5451 case CKA_BASE:
5453 if (key->key_type == CKK_DSA)
5454 len =
5455 ((biginteger_t *)OBJ_PRI_DSA_BASE(key))->
5456 big_value_len;
5457 else
5458 len =
5459 ((biginteger_t *)OBJ_PRI_DH_BASE(key))->
5460 big_value_len;
5462 /* This attribute MUST BE set */
5463 if (len == 0 || len > *value_len) {
5464 return (CKR_ATTRIBUTE_VALUE_INVALID);
5466 *value_len = len;
5468 if (key->key_type == CKK_DSA)
5469 (void) memcpy(value,
5470 ((biginteger_t *)OBJ_PRI_DSA_BASE(key))->big_value,
5471 *value_len);
5472 else
5473 (void) memcpy(value,
5474 ((biginteger_t *)OBJ_PRI_DH_BASE(key))->big_value,
5475 *value_len);
5476 break;
5478 case CKA_VALUE:
5480 if (key->key_type == CKK_DSA) {
5481 len =
5482 ((biginteger_t *)OBJ_PRI_DSA_VALUE(key))->
5483 big_value_len;
5484 } else if (key->key_type == CKK_DH) {
5485 len =
5486 ((biginteger_t *)OBJ_PRI_DH_VALUE(key))->
5487 big_value_len;
5488 } else {
5489 len =
5490 ((biginteger_t *)OBJ_PRI_EC_VALUE(key))->
5491 big_value_len;
5494 /* This attribute MUST BE set */
5495 if (len == 0 || len > *value_len) {
5496 return (CKR_ATTRIBUTE_VALUE_INVALID);
5498 *value_len = len;
5500 if (key->key_type == CKK_DSA) {
5501 (void) memcpy(value,
5502 ((biginteger_t *)OBJ_PRI_DSA_VALUE(key))->big_value,
5503 *value_len);
5504 } else if (key->key_type == CKK_DH) {
5505 (void) memcpy(value,
5506 ((biginteger_t *)OBJ_PRI_DH_VALUE(key))->big_value,
5507 *value_len);
5508 } else {
5509 (void) memcpy(value,
5510 ((biginteger_t *)OBJ_PRI_EC_VALUE(key))->big_value,
5511 *value_len);
5514 break;
5517 return (CKR_OK);
5521 static CK_RV
5522 copy_bigint(biginteger_t *new_bigint, biginteger_t *old_bigint)
5524 new_bigint->big_value =
5525 malloc((sizeof (CK_BYTE) * new_bigint->big_value_len));
5527 if (new_bigint->big_value == NULL) {
5528 return (CKR_HOST_MEMORY);
5531 (void) memcpy(new_bigint->big_value, old_bigint->big_value,
5532 (sizeof (CK_BYTE) * new_bigint->big_value_len));
5534 return (CKR_OK);
5537 static void
5538 free_public_key_attr(public_key_obj_t *pbk, CK_KEY_TYPE key_type)
5540 if (pbk == NULL) {
5541 return;
5544 switch (key_type) {
5545 case CKK_RSA:
5546 bigint_attr_cleanup(KEY_PUB_RSA_MOD(pbk));
5547 bigint_attr_cleanup(KEY_PUB_RSA_PUBEXPO(pbk));
5548 break;
5549 case CKK_DSA:
5550 bigint_attr_cleanup(KEY_PUB_DSA_PRIME(pbk));
5551 bigint_attr_cleanup(KEY_PUB_DSA_SUBPRIME(pbk));
5552 bigint_attr_cleanup(KEY_PUB_DSA_BASE(pbk));
5553 bigint_attr_cleanup(KEY_PUB_DSA_VALUE(pbk));
5554 break;
5555 case CKK_DH:
5556 bigint_attr_cleanup(KEY_PUB_DH_PRIME(pbk));
5557 bigint_attr_cleanup(KEY_PUB_DH_BASE(pbk));
5558 bigint_attr_cleanup(KEY_PUB_DH_VALUE(pbk));
5559 break;
5560 case CKK_EC:
5561 bigint_attr_cleanup(KEY_PUB_EC_POINT(pbk));
5562 break;
5563 case CKK_X9_42_DH:
5564 bigint_attr_cleanup(KEY_PUB_DH942_PRIME(pbk));
5565 bigint_attr_cleanup(KEY_PUB_DH942_SUBPRIME(pbk));
5566 bigint_attr_cleanup(KEY_PUB_DH942_BASE(pbk));
5567 bigint_attr_cleanup(KEY_PUB_DH942_VALUE(pbk));
5568 break;
5569 default:
5570 break;
5572 free(pbk);
5575 CK_RV
5576 soft_copy_public_key_attr(public_key_obj_t *old_pub_key_obj_p,
5577 public_key_obj_t **new_pub_key_obj_p, CK_KEY_TYPE key_type)
5580 public_key_obj_t *pbk;
5581 CK_RV rv = CKR_OK;
5583 pbk = calloc(1, sizeof (public_key_obj_t));
5584 if (pbk == NULL) {
5585 return (CKR_HOST_MEMORY);
5588 switch (key_type) {
5589 case CKK_RSA:
5590 (void) memcpy(KEY_PUB_RSA(pbk),
5591 KEY_PUB_RSA(old_pub_key_obj_p),
5592 sizeof (rsa_pub_key_t));
5593 /* copy modulus */
5594 rv = copy_bigint(KEY_PUB_RSA_MOD(pbk),
5595 KEY_PUB_RSA_MOD(old_pub_key_obj_p));
5596 if (rv != CKR_OK) {
5597 free_public_key_attr(pbk, key_type);
5598 return (rv);
5600 /* copy public exponent */
5601 rv = copy_bigint(KEY_PUB_RSA_PUBEXPO(pbk),
5602 KEY_PUB_RSA_PUBEXPO(old_pub_key_obj_p));
5603 if (rv != CKR_OK) {
5604 free_public_key_attr(pbk, key_type);
5605 return (rv);
5607 break;
5608 case CKK_DSA:
5609 (void) memcpy(KEY_PUB_DSA(pbk),
5610 KEY_PUB_DSA(old_pub_key_obj_p),
5611 sizeof (dsa_pub_key_t));
5613 /* copy prime */
5614 rv = copy_bigint(KEY_PUB_DSA_PRIME(pbk),
5615 KEY_PUB_DSA_PRIME(old_pub_key_obj_p));
5616 if (rv != CKR_OK) {
5617 free_public_key_attr(pbk, key_type);
5618 return (rv);
5621 /* copy subprime */
5622 rv = copy_bigint(KEY_PUB_DSA_SUBPRIME(pbk),
5623 KEY_PUB_DSA_SUBPRIME(old_pub_key_obj_p));
5624 if (rv != CKR_OK) {
5625 free_public_key_attr(pbk, key_type);
5626 return (rv);
5629 /* copy base */
5630 rv = copy_bigint(KEY_PUB_DSA_BASE(pbk),
5631 KEY_PUB_DSA_BASE(old_pub_key_obj_p));
5632 if (rv != CKR_OK) {
5633 free_public_key_attr(pbk, key_type);
5634 return (rv);
5637 /* copy value */
5638 rv = copy_bigint(KEY_PUB_DSA_VALUE(pbk),
5639 KEY_PUB_DSA_VALUE(old_pub_key_obj_p));
5640 if (rv != CKR_OK) {
5641 free_public_key_attr(pbk, key_type);
5642 return (rv);
5644 break;
5645 case CKK_DH:
5646 (void) memcpy(KEY_PUB_DH(pbk),
5647 KEY_PUB_DH(old_pub_key_obj_p),
5648 sizeof (dh_pub_key_t));
5650 /* copy prime */
5651 rv = copy_bigint(KEY_PUB_DH_PRIME(pbk),
5652 KEY_PUB_DH_PRIME(old_pub_key_obj_p));
5653 if (rv != CKR_OK) {
5654 free_public_key_attr(pbk, key_type);
5655 return (rv);
5658 /* copy base */
5659 rv = copy_bigint(KEY_PUB_DH_BASE(pbk),
5660 KEY_PUB_DH_BASE(old_pub_key_obj_p));
5661 if (rv != CKR_OK) {
5662 free_public_key_attr(pbk, key_type);
5663 return (rv);
5666 /* copy value */
5667 rv = copy_bigint(KEY_PUB_DH_VALUE(pbk),
5668 KEY_PUB_DH_VALUE(old_pub_key_obj_p));
5669 if (rv != CKR_OK) {
5670 free_public_key_attr(pbk, key_type);
5671 return (rv);
5673 break;
5674 case CKK_EC:
5675 (void) memcpy(KEY_PUB_EC(pbk),
5676 KEY_PUB_EC(old_pub_key_obj_p),
5677 sizeof (ec_pub_key_t));
5679 /* copy point */
5680 rv = copy_bigint(KEY_PUB_EC_POINT(pbk),
5681 KEY_PUB_EC_POINT(old_pub_key_obj_p));
5682 if (rv != CKR_OK) {
5683 free_public_key_attr(pbk, key_type);
5684 return (rv);
5686 break;
5687 case CKK_X9_42_DH:
5688 (void) memcpy(KEY_PUB_DH942(pbk),
5689 KEY_PUB_DH942(old_pub_key_obj_p),
5690 sizeof (dh942_pub_key_t));
5692 /* copy prime */
5693 rv = copy_bigint(KEY_PUB_DH942_PRIME(pbk),
5694 KEY_PUB_DH942_PRIME(old_pub_key_obj_p));
5695 if (rv != CKR_OK) {
5696 free_public_key_attr(pbk, key_type);
5697 return (rv);
5700 /* copy subprime */
5701 rv = copy_bigint(KEY_PUB_DH942_SUBPRIME(pbk),
5702 KEY_PUB_DH942_SUBPRIME(old_pub_key_obj_p));
5703 if (rv != CKR_OK) {
5704 free_public_key_attr(pbk, key_type);
5705 return (rv);
5708 /* copy base */
5709 rv = copy_bigint(KEY_PUB_DH942_BASE(pbk),
5710 KEY_PUB_DH942_BASE(old_pub_key_obj_p));
5711 if (rv != CKR_OK) {
5712 free_public_key_attr(pbk, key_type);
5713 return (rv);
5716 /* copy value */
5717 rv = copy_bigint(KEY_PUB_DH942_VALUE(pbk),
5718 KEY_PUB_DH942_VALUE(old_pub_key_obj_p));
5719 if (rv != CKR_OK) {
5720 free_public_key_attr(pbk, key_type);
5721 return (rv);
5723 break;
5724 default:
5725 break;
5727 *new_pub_key_obj_p = pbk;
5728 return (rv);
5731 static void
5732 free_private_key_attr(private_key_obj_t *pbk, CK_KEY_TYPE key_type)
5734 if (pbk == NULL) {
5735 return;
5738 switch (key_type) {
5739 case CKK_RSA:
5740 bigint_attr_cleanup(KEY_PRI_RSA_MOD(pbk));
5741 bigint_attr_cleanup(KEY_PRI_RSA_PUBEXPO(pbk));
5742 bigint_attr_cleanup(KEY_PRI_RSA_PRIEXPO(pbk));
5743 bigint_attr_cleanup(KEY_PRI_RSA_PRIME1(pbk));
5744 bigint_attr_cleanup(KEY_PRI_RSA_PRIME2(pbk));
5745 bigint_attr_cleanup(KEY_PRI_RSA_EXPO1(pbk));
5746 bigint_attr_cleanup(KEY_PRI_RSA_EXPO2(pbk));
5747 bigint_attr_cleanup(KEY_PRI_RSA_COEF(pbk));
5748 break;
5749 case CKK_DSA:
5750 bigint_attr_cleanup(KEY_PRI_DSA_PRIME(pbk));
5751 bigint_attr_cleanup(KEY_PRI_DSA_SUBPRIME(pbk));
5752 bigint_attr_cleanup(KEY_PRI_DSA_BASE(pbk));
5753 bigint_attr_cleanup(KEY_PRI_DSA_VALUE(pbk));
5754 break;
5755 case CKK_DH:
5756 bigint_attr_cleanup(KEY_PRI_DH_PRIME(pbk));
5757 bigint_attr_cleanup(KEY_PRI_DH_BASE(pbk));
5758 bigint_attr_cleanup(KEY_PRI_DH_VALUE(pbk));
5759 break;
5760 case CKK_EC:
5761 bigint_attr_cleanup(KEY_PRI_EC_VALUE(pbk));
5762 break;
5763 case CKK_X9_42_DH:
5764 bigint_attr_cleanup(KEY_PRI_DH942_PRIME(pbk));
5765 bigint_attr_cleanup(KEY_PRI_DH942_SUBPRIME(pbk));
5766 bigint_attr_cleanup(KEY_PRI_DH942_BASE(pbk));
5767 bigint_attr_cleanup(KEY_PRI_DH942_VALUE(pbk));
5768 break;
5769 default:
5770 break;
5772 free(pbk);
5775 CK_RV
5776 soft_copy_private_key_attr(private_key_obj_t *old_pri_key_obj_p,
5777 private_key_obj_t **new_pri_key_obj_p, CK_KEY_TYPE key_type)
5779 CK_RV rv = CKR_OK;
5780 private_key_obj_t *pbk;
5782 pbk = calloc(1, sizeof (private_key_obj_t));
5783 if (pbk == NULL) {
5784 return (CKR_HOST_MEMORY);
5787 switch (key_type) {
5788 case CKK_RSA:
5789 (void) memcpy(KEY_PRI_RSA(pbk),
5790 KEY_PRI_RSA(old_pri_key_obj_p),
5791 sizeof (rsa_pri_key_t));
5792 /* copy modulus */
5793 rv = copy_bigint(KEY_PRI_RSA_MOD(pbk),
5794 KEY_PRI_RSA_MOD(old_pri_key_obj_p));
5795 if (rv != CKR_OK) {
5796 free_private_key_attr(pbk, key_type);
5797 return (rv);
5799 /* copy public exponent */
5800 rv = copy_bigint(KEY_PRI_RSA_PUBEXPO(pbk),
5801 KEY_PRI_RSA_PUBEXPO(old_pri_key_obj_p));
5802 if (rv != CKR_OK) {
5803 free_private_key_attr(pbk, key_type);
5804 return (rv);
5806 /* copy private exponent */
5807 rv = copy_bigint(KEY_PRI_RSA_PRIEXPO(pbk),
5808 KEY_PRI_RSA_PRIEXPO(old_pri_key_obj_p));
5809 if (rv != CKR_OK) {
5810 free_private_key_attr(pbk, key_type);
5811 return (rv);
5813 /* copy prime_1 */
5814 rv = copy_bigint(KEY_PRI_RSA_PRIME1(pbk),
5815 KEY_PRI_RSA_PRIME1(old_pri_key_obj_p));
5816 if (rv != CKR_OK) {
5817 free_private_key_attr(pbk, key_type);
5818 return (rv);
5820 /* copy prime_2 */
5821 rv = copy_bigint(KEY_PRI_RSA_PRIME2(pbk),
5822 KEY_PRI_RSA_PRIME2(old_pri_key_obj_p));
5823 if (rv != CKR_OK) {
5824 free_private_key_attr(pbk, key_type);
5825 return (rv);
5827 /* copy exponent_1 */
5828 rv = copy_bigint(KEY_PRI_RSA_EXPO1(pbk),
5829 KEY_PRI_RSA_EXPO1(old_pri_key_obj_p));
5830 if (rv != CKR_OK) {
5831 free_private_key_attr(pbk, key_type);
5832 return (rv);
5834 /* copy exponent_2 */
5835 rv = copy_bigint(KEY_PRI_RSA_EXPO2(pbk),
5836 KEY_PRI_RSA_EXPO2(old_pri_key_obj_p));
5837 if (rv != CKR_OK) {
5838 free_private_key_attr(pbk, key_type);
5839 return (rv);
5841 /* copy coefficient */
5842 rv = copy_bigint(KEY_PRI_RSA_COEF(pbk),
5843 KEY_PRI_RSA_COEF(old_pri_key_obj_p));
5844 if (rv != CKR_OK) {
5845 free_private_key_attr(pbk, key_type);
5846 return (rv);
5848 break;
5849 case CKK_DSA:
5850 (void) memcpy(KEY_PRI_DSA(pbk),
5851 KEY_PRI_DSA(old_pri_key_obj_p),
5852 sizeof (dsa_pri_key_t));
5854 /* copy prime */
5855 rv = copy_bigint(KEY_PRI_DSA_PRIME(pbk),
5856 KEY_PRI_DSA_PRIME(old_pri_key_obj_p));
5857 if (rv != CKR_OK) {
5858 free_private_key_attr(pbk, key_type);
5859 return (rv);
5862 /* copy subprime */
5863 rv = copy_bigint(KEY_PRI_DSA_SUBPRIME(pbk),
5864 KEY_PRI_DSA_SUBPRIME(old_pri_key_obj_p));
5865 if (rv != CKR_OK) {
5866 free_private_key_attr(pbk, key_type);
5867 return (rv);
5870 /* copy base */
5871 rv = copy_bigint(KEY_PRI_DSA_BASE(pbk),
5872 KEY_PRI_DSA_BASE(old_pri_key_obj_p));
5873 if (rv != CKR_OK) {
5874 free_private_key_attr(pbk, key_type);
5875 return (rv);
5878 /* copy value */
5879 rv = copy_bigint(KEY_PRI_DSA_VALUE(pbk),
5880 KEY_PRI_DSA_VALUE(old_pri_key_obj_p));
5881 if (rv != CKR_OK) {
5882 free_private_key_attr(pbk, key_type);
5883 return (rv);
5885 break;
5886 case CKK_DH:
5887 (void) memcpy(KEY_PRI_DH(pbk),
5888 KEY_PRI_DH(old_pri_key_obj_p),
5889 sizeof (dh_pri_key_t));
5891 /* copy prime */
5892 rv = copy_bigint(KEY_PRI_DH_PRIME(pbk),
5893 KEY_PRI_DH_PRIME(old_pri_key_obj_p));
5894 if (rv != CKR_OK) {
5895 free_private_key_attr(pbk, key_type);
5896 return (rv);
5899 /* copy base */
5900 rv = copy_bigint(KEY_PRI_DH_BASE(pbk),
5901 KEY_PRI_DH_BASE(old_pri_key_obj_p));
5902 if (rv != CKR_OK) {
5903 free_private_key_attr(pbk, key_type);
5904 return (rv);
5907 /* copy value */
5908 rv = copy_bigint(KEY_PRI_DH_VALUE(pbk),
5909 KEY_PRI_DH_VALUE(old_pri_key_obj_p));
5910 if (rv != CKR_OK) {
5911 free_private_key_attr(pbk, key_type);
5912 return (rv);
5914 break;
5915 case CKK_EC:
5916 (void) memcpy(KEY_PRI_EC(pbk),
5917 KEY_PRI_EC(old_pri_key_obj_p),
5918 sizeof (ec_pri_key_t));
5920 /* copy value */
5921 rv = copy_bigint(KEY_PRI_EC_VALUE(pbk),
5922 KEY_PRI_EC_VALUE(old_pri_key_obj_p));
5923 if (rv != CKR_OK) {
5924 free_private_key_attr(pbk, key_type);
5925 return (rv);
5927 break;
5928 case CKK_X9_42_DH:
5929 (void) memcpy(KEY_PRI_DH942(pbk),
5930 KEY_PRI_DH942(old_pri_key_obj_p),
5931 sizeof (dh942_pri_key_t));
5933 /* copy prime */
5934 rv = copy_bigint(KEY_PRI_DH942_PRIME(pbk),
5935 KEY_PRI_DH942_PRIME(old_pri_key_obj_p));
5936 if (rv != CKR_OK) {
5937 free_private_key_attr(pbk, key_type);
5938 return (rv);
5941 /* copy subprime */
5942 rv = copy_bigint(KEY_PRI_DH942_SUBPRIME(pbk),
5943 KEY_PRI_DH942_SUBPRIME(old_pri_key_obj_p));
5944 if (rv != CKR_OK) {
5945 free_private_key_attr(pbk, key_type);
5946 return (rv);
5949 /* copy base */
5950 rv = copy_bigint(KEY_PRI_DH942_BASE(pbk),
5951 KEY_PRI_DH942_BASE(old_pri_key_obj_p));
5952 if (rv != CKR_OK) {
5953 free_private_key_attr(pbk, key_type);
5954 return (rv);
5957 /* copy value */
5958 rv = copy_bigint(KEY_PRI_DH942_VALUE(pbk),
5959 KEY_PRI_DH942_VALUE(old_pri_key_obj_p));
5960 if (rv != CKR_OK) {
5961 free_private_key_attr(pbk, key_type);
5962 return (rv);
5964 break;
5965 default:
5966 break;
5968 *new_pri_key_obj_p = pbk;
5969 return (rv);
5972 static void
5973 free_domain_attr(domain_obj_t *domain, CK_KEY_TYPE key_type)
5975 if (domain == NULL) {
5976 return;
5979 switch (key_type) {
5980 case CKK_DSA:
5981 bigint_attr_cleanup(KEY_DOM_DSA_PRIME(domain));
5982 bigint_attr_cleanup(KEY_DOM_DSA_SUBPRIME(domain));
5983 bigint_attr_cleanup(KEY_DOM_DSA_BASE(domain));
5984 break;
5985 case CKK_DH:
5986 bigint_attr_cleanup(KEY_DOM_DH_PRIME(domain));
5987 bigint_attr_cleanup(KEY_DOM_DH_BASE(domain));
5988 break;
5989 case CKK_X9_42_DH:
5990 bigint_attr_cleanup(KEY_DOM_DH942_PRIME(domain));
5991 bigint_attr_cleanup(KEY_DOM_DH942_SUBPRIME(domain));
5992 bigint_attr_cleanup(KEY_DOM_DH942_BASE(domain));
5993 break;
5994 default:
5995 break;
5997 free(domain);
6000 CK_RV
6001 soft_copy_domain_attr(domain_obj_t *old_domain_obj_p,
6002 domain_obj_t **new_domain_obj_p, CK_KEY_TYPE key_type)
6004 CK_RV rv = CKR_OK;
6005 domain_obj_t *domain;
6007 domain = calloc(1, sizeof (domain_obj_t));
6008 if (domain == NULL) {
6009 return (CKR_HOST_MEMORY);
6012 switch (key_type) {
6013 case CKK_DSA:
6014 (void) memcpy(KEY_DOM_DSA(domain),
6015 KEY_DOM_DSA(old_domain_obj_p),
6016 sizeof (dsa_dom_key_t));
6018 /* copy prime */
6019 rv = copy_bigint(KEY_DOM_DSA_PRIME(domain),
6020 KEY_DOM_DSA_PRIME(old_domain_obj_p));
6021 if (rv != CKR_OK) {
6022 free_domain_attr(domain, key_type);
6023 return (rv);
6026 /* copy subprime */
6027 rv = copy_bigint(KEY_DOM_DSA_SUBPRIME(domain),
6028 KEY_DOM_DSA_SUBPRIME(old_domain_obj_p));
6029 if (rv != CKR_OK) {
6030 free_domain_attr(domain, key_type);
6031 return (rv);
6034 /* copy base */
6035 rv = copy_bigint(KEY_DOM_DSA_BASE(domain),
6036 KEY_DOM_DSA_BASE(old_domain_obj_p));
6037 if (rv != CKR_OK) {
6038 free_domain_attr(domain, key_type);
6039 return (rv);
6042 break;
6043 case CKK_DH:
6044 (void) memcpy(KEY_DOM_DH(domain),
6045 KEY_DOM_DH(old_domain_obj_p),
6046 sizeof (dh_dom_key_t));
6048 /* copy prime */
6049 rv = copy_bigint(KEY_DOM_DH_PRIME(domain),
6050 KEY_DOM_DH_PRIME(old_domain_obj_p));
6051 if (rv != CKR_OK) {
6052 free_domain_attr(domain, key_type);
6053 return (rv);
6056 /* copy base */
6057 rv = copy_bigint(KEY_DOM_DH_BASE(domain),
6058 KEY_DOM_DH_BASE(old_domain_obj_p));
6059 if (rv != CKR_OK) {
6060 free_domain_attr(domain, key_type);
6061 return (rv);
6064 break;
6065 case CKK_X9_42_DH:
6066 (void) memcpy(KEY_DOM_DH942(domain),
6067 KEY_DOM_DH942(old_domain_obj_p),
6068 sizeof (dh942_dom_key_t));
6070 /* copy prime */
6071 rv = copy_bigint(KEY_DOM_DH942_PRIME(domain),
6072 KEY_DOM_DH942_PRIME(old_domain_obj_p));
6073 if (rv != CKR_OK) {
6074 free_domain_attr(domain, key_type);
6075 return (rv);
6078 /* copy subprime */
6079 rv = copy_bigint(KEY_DOM_DH942_SUBPRIME(domain),
6080 KEY_DOM_DH942_SUBPRIME(old_domain_obj_p));
6081 if (rv != CKR_OK) {
6082 free_domain_attr(domain, key_type);
6083 return (rv);
6086 /* copy base */
6087 rv = copy_bigint(KEY_DOM_DH942_BASE(domain),
6088 KEY_DOM_DH942_BASE(old_domain_obj_p));
6089 if (rv != CKR_OK) {
6090 free_domain_attr(domain, key_type);
6091 return (rv);
6094 break;
6095 default:
6096 break;
6098 *new_domain_obj_p = domain;
6099 return (rv);
6102 CK_RV
6103 soft_copy_secret_key_attr(secret_key_obj_t *old_secret_key_obj_p,
6104 secret_key_obj_t **new_secret_key_obj_p)
6106 secret_key_obj_t *sk;
6108 sk = malloc(sizeof (secret_key_obj_t));
6109 if (sk == NULL) {
6110 return (CKR_HOST_MEMORY);
6112 (void) memcpy(sk, old_secret_key_obj_p, sizeof (secret_key_obj_t));
6114 /* copy the secret key value */
6115 sk->sk_value = malloc((sizeof (CK_BYTE) * sk->sk_value_len));
6116 if (sk->sk_value == NULL) {
6117 free(sk);
6118 return (CKR_HOST_MEMORY);
6120 (void) memcpy(sk->sk_value, old_secret_key_obj_p->sk_value,
6121 (sizeof (CK_BYTE) * sk->sk_value_len));
6124 * Copy the pre-expanded key schedule.
6126 if (old_secret_key_obj_p->key_sched != NULL &&
6127 old_secret_key_obj_p->keysched_len > 0) {
6128 sk->key_sched = malloc(old_secret_key_obj_p->keysched_len);
6129 if (sk->key_sched == NULL) {
6130 free(sk);
6131 return (CKR_HOST_MEMORY);
6133 sk->keysched_len = old_secret_key_obj_p->keysched_len;
6134 (void) memcpy(sk->key_sched, old_secret_key_obj_p->key_sched,
6135 sk->keysched_len);
6138 *new_secret_key_obj_p = sk;
6140 return (CKR_OK);
6144 * If CKA_CLASS not given, guess CKA_CLASS using
6145 * attributes on template .
6147 * Some attributes are specific to an object class. If one or more
6148 * of these attributes are in the template, make a list of classes
6149 * that can have these attributes. This would speed up the search later,
6150 * because we can immediately skip an object if the class of that
6151 * object can not possibly contain one of the attributes.
6154 void
6155 soft_process_find_attr(CK_OBJECT_CLASS *pclasses,
6156 CK_ULONG *num_result_pclasses, CK_ATTRIBUTE_PTR pTemplate,
6157 CK_ULONG ulCount)
6159 ulong_t i;
6160 int j;
6161 boolean_t pub_found = B_FALSE,
6162 priv_found = B_FALSE,
6163 secret_found = B_FALSE,
6164 domain_found = B_FALSE,
6165 hardware_found = B_FALSE,
6166 cert_found = B_FALSE;
6167 int num_pub_key_attrs, num_priv_key_attrs,
6168 num_secret_key_attrs, num_domain_attrs,
6169 num_hardware_attrs, num_cert_attrs;
6170 int num_pclasses = 0;
6172 for (i = 0; i < ulCount; i++) {
6173 if (pTemplate[i].type == CKA_CLASS) {
6175 * don't need to guess the class, it is specified.
6176 * Just record the class, and return.
6178 pclasses[0] =
6179 (*((CK_OBJECT_CLASS *)pTemplate[i].pValue));
6180 *num_result_pclasses = 1;
6181 return;
6185 num_pub_key_attrs =
6186 sizeof (PUB_KEY_ATTRS) / sizeof (CK_ATTRIBUTE_TYPE);
6187 num_priv_key_attrs =
6188 sizeof (PRIV_KEY_ATTRS) / sizeof (CK_ATTRIBUTE_TYPE);
6189 num_secret_key_attrs =
6190 sizeof (SECRET_KEY_ATTRS) / sizeof (CK_ATTRIBUTE_TYPE);
6191 num_domain_attrs =
6192 sizeof (DOMAIN_ATTRS) / sizeof (CK_ATTRIBUTE_TYPE);
6193 num_hardware_attrs =
6194 sizeof (HARDWARE_ATTRS) / sizeof (CK_ATTRIBUTE_TYPE);
6195 num_cert_attrs =
6196 sizeof (CERT_ATTRS) / sizeof (CK_ATTRIBUTE_TYPE);
6199 * Get the list of objects class that might contain
6200 * some attributes.
6202 for (i = 0; i < ulCount; i++) {
6204 * only check if this attribute can belong to public key object
6205 * class if public key object isn't already in the list
6207 if (!pub_found) {
6208 for (j = 0; j < num_pub_key_attrs; j++) {
6209 if (pTemplate[i].type == PUB_KEY_ATTRS[j]) {
6210 pub_found = B_TRUE;
6211 pclasses[num_pclasses++] =
6212 CKO_PUBLIC_KEY;
6213 break;
6218 if (!priv_found) {
6219 for (j = 0; j < num_priv_key_attrs; j++) {
6220 if (pTemplate[i].type == PRIV_KEY_ATTRS[j]) {
6221 priv_found = B_TRUE;
6222 pclasses[num_pclasses++] =
6223 CKO_PRIVATE_KEY;
6224 break;
6229 if (!secret_found) {
6230 for (j = 0; j < num_secret_key_attrs; j++) {
6231 if (pTemplate[i].type == SECRET_KEY_ATTRS[j]) {
6232 secret_found = B_TRUE;
6233 pclasses[num_pclasses++] =
6234 CKO_SECRET_KEY;
6235 break;
6240 if (!domain_found) {
6241 for (j = 0; j < num_domain_attrs; j++) {
6242 if (pTemplate[i].type == DOMAIN_ATTRS[j]) {
6243 domain_found = B_TRUE;
6244 pclasses[num_pclasses++] =
6245 CKO_DOMAIN_PARAMETERS;
6246 break;
6251 if (!hardware_found) {
6252 for (j = 0; j < num_hardware_attrs; j++) {
6253 if (pTemplate[i].type == HARDWARE_ATTRS[j]) {
6254 hardware_found = B_TRUE;
6255 pclasses[num_pclasses++] =
6256 CKO_HW_FEATURE;
6257 break;
6262 if (!cert_found) {
6263 for (j = 0; j < num_cert_attrs; j++) {
6264 if (pTemplate[i].type == CERT_ATTRS[j]) {
6265 cert_found = B_TRUE;
6266 pclasses[num_pclasses++] =
6267 CKO_CERTIFICATE;
6268 break;
6273 *num_result_pclasses = num_pclasses;
6276 boolean_t
6277 soft_find_match_attrs(soft_object_t *obj, CK_OBJECT_CLASS *pclasses,
6278 CK_ULONG num_pclasses, CK_ATTRIBUTE *template, CK_ULONG num_attr)
6280 ulong_t i;
6281 CK_ATTRIBUTE *tmpl_attr, *obj_attr;
6282 cert_attr_t *cert_attr;
6283 uint64_t attr_mask;
6284 biginteger_t *bigint;
6285 boolean_t compare_attr, compare_bigint, compare_boolean;
6286 boolean_t compare_cert_val, compare_cert_type;
6289 * Check if the class of this object match with any
6290 * of object classes that can possibly contain the
6291 * requested attributes.
6293 if (num_pclasses > 0) {
6294 for (i = 0; i < num_pclasses; i++) {
6295 if (obj->class == pclasses[i]) {
6296 break;
6299 if (i == num_pclasses) {
6301 * this object can't possibly contain one or
6302 * more attributes, don't need to check this object
6304 return (B_FALSE);
6308 /* need to examine everything */
6309 for (i = 0; i < num_attr; i++) {
6310 tmpl_attr = &(template[i]);
6311 compare_attr = B_FALSE;
6312 compare_bigint = B_FALSE;
6313 compare_boolean = B_FALSE;
6314 compare_cert_val = B_FALSE;
6315 compare_cert_type = B_FALSE;
6316 switch (tmpl_attr->type) {
6317 /* First, check the most common attributes */
6318 case CKA_CLASS:
6319 if (*((CK_OBJECT_CLASS *)tmpl_attr->pValue) !=
6320 obj->class) {
6321 return (B_FALSE);
6323 break;
6324 case CKA_KEY_TYPE:
6325 if (*((CK_KEY_TYPE *)tmpl_attr->pValue) !=
6326 obj->key_type) {
6327 return (B_FALSE);
6329 break;
6330 case CKA_ENCRYPT:
6331 attr_mask = (obj->bool_attr_mask) & ENCRYPT_BOOL_ON;
6332 compare_boolean = B_TRUE;
6333 break;
6334 case CKA_DECRYPT:
6335 attr_mask = (obj->bool_attr_mask) & DECRYPT_BOOL_ON;
6336 compare_boolean = B_TRUE;
6337 break;
6338 case CKA_WRAP:
6339 attr_mask = (obj->bool_attr_mask) & WRAP_BOOL_ON;
6340 compare_boolean = B_TRUE;
6341 break;
6342 case CKA_UNWRAP:
6343 attr_mask = (obj->bool_attr_mask) & UNWRAP_BOOL_ON;
6344 compare_boolean = B_TRUE;
6345 break;
6346 case CKA_SIGN:
6347 attr_mask = (obj->bool_attr_mask) & SIGN_BOOL_ON;
6348 compare_boolean = B_TRUE;
6349 break;
6350 case CKA_SIGN_RECOVER:
6351 attr_mask = (obj->bool_attr_mask) &
6352 SIGN_RECOVER_BOOL_ON;
6353 compare_boolean = B_TRUE;
6354 break;
6355 case CKA_VERIFY:
6356 attr_mask = (obj->bool_attr_mask) & VERIFY_BOOL_ON;
6357 compare_boolean = B_TRUE;
6358 break;
6359 case CKA_VERIFY_RECOVER:
6360 attr_mask = (obj->bool_attr_mask) &
6361 VERIFY_RECOVER_BOOL_ON;
6362 compare_boolean = B_TRUE;
6363 break;
6364 case CKA_DERIVE:
6365 attr_mask = (obj->bool_attr_mask) & DERIVE_BOOL_ON;
6366 compare_boolean = B_TRUE;
6367 break;
6368 case CKA_LOCAL:
6369 attr_mask = (obj->bool_attr_mask) & LOCAL_BOOL_ON;
6370 compare_boolean = B_TRUE;
6371 break;
6372 case CKA_SENSITIVE:
6373 attr_mask = (obj->bool_attr_mask) & SENSITIVE_BOOL_ON;
6374 compare_boolean = B_TRUE;
6375 break;
6376 case CKA_SECONDARY_AUTH:
6377 attr_mask = (obj->bool_attr_mask) &
6378 SECONDARY_AUTH_BOOL_ON;
6379 compare_boolean = B_TRUE;
6380 break;
6381 case CKA_TRUSTED:
6382 attr_mask = (obj->bool_attr_mask) & TRUSTED_BOOL_ON;
6383 compare_boolean = B_TRUE;
6384 break;
6385 case CKA_EXTRACTABLE:
6386 attr_mask = (obj->bool_attr_mask) &
6387 EXTRACTABLE_BOOL_ON;
6388 compare_boolean = B_TRUE;
6389 break;
6390 case CKA_ALWAYS_SENSITIVE:
6391 attr_mask = (obj->bool_attr_mask) &
6392 ALWAYS_SENSITIVE_BOOL_ON;
6393 compare_boolean = B_TRUE;
6394 break;
6395 case CKA_NEVER_EXTRACTABLE:
6396 attr_mask = (obj->bool_attr_mask) &
6397 NEVER_EXTRACTABLE_BOOL_ON;
6398 compare_boolean = B_TRUE;
6399 break;
6400 case CKA_TOKEN:
6401 attr_mask = (obj->object_type) & TOKEN_OBJECT;
6402 compare_boolean = B_TRUE;
6403 break;
6404 case CKA_PRIVATE:
6405 attr_mask = (obj->object_type) & PRIVATE_OBJECT;
6406 compare_boolean = B_TRUE;
6407 break;
6408 case CKA_MODIFIABLE:
6410 CK_BBOOL bval;
6411 attr_mask = (obj->bool_attr_mask) &
6412 NOT_MODIFIABLE_BOOL_ON;
6414 if (attr_mask) {
6415 bval = FALSE;
6416 } else {
6417 bval = TRUE;
6419 if (bval != *((CK_BBOOL *)tmpl_attr->pValue)) {
6420 return (B_FALSE);
6422 break;
6424 case CKA_OWNER:
6426 * For X.509 attribute certificate object, get its
6427 * CKA_OWNER attribute from the x509_attr_cert_t struct.
6429 if ((obj->class == CKO_CERTIFICATE) &&
6430 (obj->cert_type == CKC_X_509_ATTR_CERT)) {
6431 cert_attr = X509_ATTR_CERT_OWNER(obj);
6432 compare_cert_val = B_TRUE;
6434 break;
6435 case CKA_SUBJECT:
6437 * For X.509 certificate object, get its CKA_SUBJECT
6438 * attribute from the x509_cert_t struct (not from
6439 * the extra_attrlistp).
6441 if ((obj->class == CKO_CERTIFICATE) &&
6442 (obj->cert_type == CKC_X_509)) {
6443 cert_attr = X509_CERT_SUBJECT(obj);
6444 compare_cert_val = B_TRUE;
6445 break;
6447 /*FALLTHRU*/
6448 case CKA_ID:
6449 case CKA_START_DATE:
6450 case CKA_END_DATE:
6451 case CKA_KEY_GEN_MECHANISM:
6452 case CKA_LABEL:
6453 case CKA_ISSUER:
6454 case CKA_SERIAL_NUMBER:
6455 case CKA_AC_ISSUER:
6456 case CKA_ATTR_TYPES:
6457 /* find these attributes from extra_attrlistp */
6458 obj_attr = get_extra_attr(tmpl_attr->type, obj);
6459 compare_attr = B_TRUE;
6460 break;
6461 case CKA_CERTIFICATE_TYPE:
6462 compare_cert_type = B_TRUE;
6463 break;
6464 case CKA_VALUE_LEN:
6465 /* only secret key has this attribute */
6466 if (obj->class == CKO_SECRET_KEY) {
6467 if (*((CK_ULONG *)tmpl_attr->pValue) !=
6468 OBJ_SEC_VALUE_LEN(obj)) {
6469 return (B_FALSE);
6471 } else {
6472 return (B_FALSE);
6474 break;
6475 case CKA_VALUE:
6476 switch (obj->class) {
6477 case CKO_SECRET_KEY:
6479 * secret_key_obj_t is the same as
6480 * biginteger_t
6482 bigint = (biginteger_t *)OBJ_SEC(obj);
6483 compare_bigint = B_TRUE;
6484 break;
6485 case CKO_PRIVATE_KEY:
6486 if (obj->key_type == CKK_DSA) {
6487 bigint = OBJ_PRI_DSA_VALUE(obj);
6488 } else if (obj->key_type == CKK_DH) {
6489 bigint = OBJ_PRI_DH_VALUE(obj);
6490 } else if (obj->key_type == CKK_X9_42_DH) {
6491 bigint = OBJ_PRI_DH942_VALUE(obj);
6492 } else {
6493 return (B_FALSE);
6495 compare_bigint = B_TRUE;
6496 break;
6497 case CKO_PUBLIC_KEY:
6498 if (obj->key_type == CKK_DSA) {
6499 bigint = OBJ_PUB_DSA_VALUE(obj);
6500 } else if (obj->key_type == CKK_DH) {
6501 bigint = OBJ_PUB_DH_VALUE(obj);
6502 } else if (obj->key_type == CKK_X9_42_DH) {
6503 bigint = OBJ_PUB_DH942_VALUE(obj);
6504 } else {
6505 return (B_FALSE);
6507 compare_bigint = B_TRUE;
6508 break;
6509 case CKO_CERTIFICATE:
6510 if (obj->cert_type == CKC_X_509) {
6511 cert_attr = X509_CERT_VALUE(obj);
6512 } else if (obj->cert_type ==
6513 CKC_X_509_ATTR_CERT) {
6514 cert_attr = X509_ATTR_CERT_VALUE(obj);
6516 compare_cert_val = B_TRUE;
6517 break;
6518 default:
6519 return (B_FALSE);
6521 break;
6522 case CKA_MODULUS:
6523 /* only RSA public and private key have this attr */
6524 if (obj->key_type == CKK_RSA) {
6525 if (obj->class == CKO_PUBLIC_KEY) {
6526 bigint = OBJ_PUB_RSA_MOD(obj);
6527 } else if (obj->class == CKO_PRIVATE_KEY) {
6528 bigint = OBJ_PRI_RSA_MOD(obj);
6529 } else {
6530 return (B_FALSE);
6532 compare_bigint = B_TRUE;
6533 } else {
6534 return (B_FALSE);
6536 break;
6537 case CKA_MODULUS_BITS:
6538 /* only RSA public key has this attribute */
6539 if ((obj->key_type == CKK_RSA) &&
6540 (obj->class == CKO_PUBLIC_KEY)) {
6541 CK_ULONG mod_bits = OBJ_PUB_RSA_MOD_BITS(obj);
6542 if (mod_bits !=
6543 *((CK_ULONG *)tmpl_attr->pValue)) {
6544 return (B_FALSE);
6546 } else {
6547 return (B_FALSE);
6549 break;
6550 case CKA_PUBLIC_EXPONENT:
6551 /* only RSA public and private key have this attr */
6552 if (obj->key_type == CKK_RSA) {
6553 if (obj->class == CKO_PUBLIC_KEY) {
6554 bigint = OBJ_PUB_RSA_PUBEXPO(obj);
6555 } else if (obj->class == CKO_PRIVATE_KEY) {
6556 bigint = OBJ_PRI_RSA_PUBEXPO(obj);
6557 } else {
6558 return (B_FALSE);
6560 compare_bigint = B_TRUE;
6561 } else {
6562 return (B_FALSE);
6564 break;
6565 case CKA_PRIVATE_EXPONENT:
6566 /* only RSA private key has this attribute */
6567 if ((obj->key_type == CKK_RSA) &&
6568 (obj->class == CKO_PRIVATE_KEY)) {
6569 bigint = OBJ_PRI_RSA_PRIEXPO(obj);
6570 compare_bigint = B_TRUE;
6571 } else {
6572 return (B_FALSE);
6574 break;
6575 case CKA_PRIME_1:
6576 /* only RSA private key has this attribute */
6577 if ((obj->key_type == CKK_RSA) &&
6578 (obj->class == CKO_PRIVATE_KEY)) {
6579 bigint = OBJ_PRI_RSA_PRIME1(obj);
6580 compare_bigint = B_TRUE;
6581 } else {
6582 return (B_FALSE);
6584 break;
6585 case CKA_PRIME_2:
6586 /* only RSA private key has this attribute */
6587 if ((obj->key_type == CKK_RSA) &&
6588 (obj->class == CKO_PRIVATE_KEY)) {
6589 bigint = OBJ_PRI_RSA_PRIME2(obj);
6590 compare_bigint = B_TRUE;
6591 } else {
6592 return (B_FALSE);
6594 break;
6595 case CKA_EXPONENT_1:
6596 /* only RSA private key has this attribute */
6597 if ((obj->key_type == CKK_RSA) &&
6598 (obj->class == CKO_PRIVATE_KEY)) {
6599 bigint = OBJ_PRI_RSA_EXPO1(obj);
6600 compare_bigint = B_TRUE;
6601 } else {
6602 return (B_FALSE);
6604 break;
6605 case CKA_EXPONENT_2:
6606 /* only RSA private key has this attribute */
6607 if ((obj->key_type == CKK_RSA) &&
6608 (obj->class == CKO_PRIVATE_KEY)) {
6609 bigint = OBJ_PRI_RSA_EXPO2(obj);
6610 compare_bigint = B_TRUE;
6611 } else {
6612 return (B_FALSE);
6614 break;
6615 case CKA_COEFFICIENT:
6616 /* only RSA private key has this attribute */
6617 if ((obj->key_type == CKK_RSA) &&
6618 (obj->class == CKO_PRIVATE_KEY)) {
6619 bigint = OBJ_PRI_RSA_COEF(obj);
6620 compare_bigint = B_TRUE;
6621 } else {
6622 return (B_FALSE);
6624 break;
6625 case CKA_VALUE_BITS:
6626 /* only Diffie-Hellman private key has this attr */
6627 if ((obj->key_type == CKK_DH) &&
6628 (obj->class == CKO_PRIVATE_KEY)) {
6629 CK_ULONG val_bits = OBJ_PRI_DH_VAL_BITS(obj);
6630 if (val_bits !=
6631 *((CK_ULONG *)tmpl_attr->pValue)) {
6632 return (B_FALSE);
6634 } else {
6635 return (B_FALSE);
6637 break;
6638 case CKA_PRIME:
6639 if (obj->class == CKO_PUBLIC_KEY) {
6640 switch (obj->key_type) {
6641 case CKK_DSA:
6642 bigint = OBJ_PUB_DSA_PRIME(obj);
6643 break;
6644 case CKK_DH:
6645 bigint = OBJ_PUB_DH_PRIME(obj);
6646 break;
6647 case CKK_X9_42_DH:
6648 bigint = OBJ_PUB_DH942_PRIME(obj);
6649 break;
6650 default:
6651 return (B_FALSE);
6653 } else if (obj->class == CKO_PRIVATE_KEY) {
6654 switch (obj->key_type) {
6655 case CKK_DSA:
6656 bigint = OBJ_PRI_DSA_PRIME(obj);
6657 break;
6658 case CKK_DH:
6659 bigint = OBJ_PRI_DH_PRIME(obj);
6660 break;
6661 case CKK_X9_42_DH:
6662 bigint = OBJ_PRI_DH942_PRIME(obj);
6663 break;
6664 default:
6665 return (B_FALSE);
6667 } else if (obj->class == CKO_DOMAIN_PARAMETERS) {
6668 switch (obj->key_type) {
6669 case CKK_DSA:
6670 bigint = OBJ_DOM_DSA_PRIME(obj);
6671 break;
6672 case CKK_DH:
6673 bigint = OBJ_DOM_DH_PRIME(obj);
6674 break;
6675 case CKK_X9_42_DH:
6676 bigint = OBJ_DOM_DH942_PRIME(obj);
6677 break;
6678 default:
6679 return (B_FALSE);
6681 } else {
6682 return (B_FALSE);
6684 compare_bigint = B_TRUE;
6685 break;
6686 case CKA_SUBPRIME:
6687 if (obj->class == CKO_PUBLIC_KEY) {
6688 switch (obj->key_type) {
6689 case CKK_DSA:
6690 bigint = OBJ_PUB_DSA_SUBPRIME(obj);
6691 break;
6692 case CKK_X9_42_DH:
6693 bigint = OBJ_PUB_DH942_SUBPRIME(obj);
6694 break;
6695 default:
6696 return (B_FALSE);
6698 } else if (obj->class == CKO_PRIVATE_KEY) {
6699 switch (obj->key_type) {
6700 case CKK_DSA:
6701 bigint = OBJ_PRI_DSA_SUBPRIME(obj);
6702 break;
6703 case CKK_X9_42_DH:
6704 bigint = OBJ_PRI_DH942_SUBPRIME(obj);
6705 break;
6706 default:
6707 return (B_FALSE);
6709 } else if (obj->class == CKO_DOMAIN_PARAMETERS) {
6710 switch (obj->key_type) {
6711 case CKK_DSA:
6712 bigint = OBJ_DOM_DSA_SUBPRIME(obj);
6713 break;
6714 case CKK_X9_42_DH:
6715 bigint = OBJ_DOM_DH942_SUBPRIME(obj);
6716 break;
6717 default:
6718 return (B_FALSE);
6720 } else {
6721 return (B_FALSE);
6723 compare_bigint = B_TRUE;
6724 break;
6725 case CKA_BASE:
6726 if (obj->class == CKO_PUBLIC_KEY) {
6727 switch (obj->key_type) {
6728 case CKK_DSA:
6729 bigint = OBJ_PUB_DSA_BASE(obj);
6730 break;
6731 case CKK_DH:
6732 bigint = OBJ_PUB_DH_BASE(obj);
6733 break;
6734 case CKK_X9_42_DH:
6735 bigint = OBJ_PUB_DH942_BASE(obj);
6736 break;
6737 default:
6738 return (B_FALSE);
6740 } else if (obj->class == CKO_PRIVATE_KEY) {
6741 switch (obj->key_type) {
6742 case CKK_DSA:
6743 bigint = OBJ_PRI_DSA_BASE(obj);
6744 break;
6745 case CKK_DH:
6746 bigint = OBJ_PRI_DH_BASE(obj);
6747 break;
6748 case CKK_X9_42_DH:
6749 bigint = OBJ_PRI_DH942_BASE(obj);
6750 break;
6751 default:
6752 return (B_FALSE);
6754 } else if (obj->class == CKO_DOMAIN_PARAMETERS) {
6755 switch (obj->key_type) {
6756 case CKK_DSA:
6757 bigint = OBJ_DOM_DSA_BASE(obj);
6758 break;
6759 case CKK_DH:
6760 bigint = OBJ_DOM_DH_BASE(obj);
6761 break;
6762 case CKK_X9_42_DH:
6763 bigint = OBJ_DOM_DH942_BASE(obj);
6764 break;
6765 default:
6766 return (B_FALSE);
6768 } else {
6769 return (B_FALSE);
6771 compare_bigint = B_TRUE;
6772 break;
6773 case CKA_PRIME_BITS:
6774 if (obj->class == CKO_DOMAIN_PARAMETERS) {
6775 CK_ULONG prime_bits;
6776 if (obj->key_type == CKK_DSA) {
6777 prime_bits =
6778 OBJ_DOM_DSA_PRIME_BITS(obj);
6779 } else if (obj->key_type == CKK_DH) {
6780 prime_bits =
6781 OBJ_DOM_DH_PRIME_BITS(obj);
6782 } else if (obj->key_type == CKK_X9_42_DH) {
6783 prime_bits =
6784 OBJ_DOM_DH942_PRIME_BITS(obj);
6785 } else {
6786 return (B_FALSE);
6788 if (prime_bits !=
6789 *((CK_ULONG *)tmpl_attr->pValue)) {
6790 return (B_FALSE);
6792 } else {
6793 return (B_FALSE);
6795 break;
6796 case CKA_SUBPRIME_BITS:
6797 if ((obj->class == CKO_DOMAIN_PARAMETERS) &&
6798 (obj->key_type == CKK_X9_42_DH)) {
6799 CK_ULONG subprime_bits =
6800 OBJ_DOM_DH942_SUBPRIME_BITS(obj);
6801 if (subprime_bits !=
6802 *((CK_ULONG *)tmpl_attr->pValue)) {
6803 return (B_FALSE);
6805 } else {
6806 return (B_FALSE);
6808 break;
6809 default:
6811 * any other attributes are currently not supported.
6812 * so, it's not possible for them to be in the
6813 * object
6815 return (B_FALSE);
6817 if (compare_boolean) {
6818 CK_BBOOL bval;
6820 if (attr_mask) {
6821 bval = TRUE;
6822 } else {
6823 bval = FALSE;
6825 if (bval != *((CK_BBOOL *)tmpl_attr->pValue)) {
6826 return (B_FALSE);
6828 } else if (compare_bigint) {
6829 if (bigint == NULL) {
6830 return (B_FALSE);
6832 if (tmpl_attr->ulValueLen != bigint->big_value_len) {
6833 return (B_FALSE);
6835 if (memcmp(tmpl_attr->pValue, bigint->big_value,
6836 tmpl_attr->ulValueLen) != 0) {
6837 return (B_FALSE);
6839 } else if (compare_attr) {
6840 if (obj_attr == NULL) {
6842 * The attribute type is valid, and its value
6843 * has not been initialized in the object. In
6844 * this case, it only matches the template's
6845 * attribute if the template's value length
6846 * is 0.
6848 if (tmpl_attr->ulValueLen != 0)
6849 return (B_FALSE);
6850 } else {
6851 if (tmpl_attr->ulValueLen !=
6852 obj_attr->ulValueLen) {
6853 return (B_FALSE);
6855 if (memcmp(tmpl_attr->pValue, obj_attr->pValue,
6856 tmpl_attr->ulValueLen) != 0) {
6857 return (B_FALSE);
6860 } else if (compare_cert_val) {
6861 if (cert_attr == NULL) {
6862 /* specific attribute not found */
6863 return (B_FALSE);
6865 if (tmpl_attr->ulValueLen != cert_attr->length) {
6866 return (B_FALSE);
6868 if (memcmp(tmpl_attr->pValue, cert_attr->value,
6869 tmpl_attr->ulValueLen) != 0) {
6870 return (B_FALSE);
6872 } else if (compare_cert_type) {
6873 if (memcmp(tmpl_attr->pValue, &(obj->cert_type),
6874 tmpl_attr->ulValueLen) != 0) {
6875 return (B_FALSE);
6879 return (B_TRUE);
6882 CK_ATTRIBUTE_PTR
6883 get_extra_attr(CK_ATTRIBUTE_TYPE type, soft_object_t *obj)
6885 CK_ATTRIBUTE_INFO_PTR tmp;
6887 tmp = obj->extra_attrlistp;
6888 while (tmp != NULL) {
6889 if (tmp->attr.type == type) {
6890 return (&(tmp->attr));
6892 tmp = tmp->next;
6894 /* if get there, the specified attribute is not found */
6895 return (NULL);