1 /*
2 * CDDL HEADER START
3 *
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.
7 *
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.
12 *
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]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 */
25
26 #include <stdlib.h>
27 #include <string.h>
28 #include <security/cryptoki.h>
29 #include <sys/crypto/common.h>
30 #include <arcfour.h>
31 #include <aes_impl.h>
32 #include <blowfish_impl.h>
33 #include <bignum.h>
34 #include <des_impl.h>
35 #include <rsa_impl.h>
36 #include "softGlobal.h"
37 #include "softObject.h"
38 #include "softSession.h"
39 #include "softKeystore.h"
40 #include "softKeystoreUtil.h"
41 #include "softCrypt.h"
42
43
44 /*
45 * This attribute table is used by the soft_lookup_attr()
46 * to validate the attributes.
47 */
48 CK_ATTRIBUTE_TYPE attr_map[] = {
49 CKA_PRIVATE,
50 CKA_LABEL,
51 CKA_APPLICATION,
52 CKA_OBJECT_ID,
53 CKA_CERTIFICATE_TYPE,
54 CKA_ISSUER,
55 CKA_SERIAL_NUMBER,
56 CKA_AC_ISSUER,
57 CKA_OWNER,
58 CKA_ATTR_TYPES,
59 CKA_SUBJECT,
60 CKA_ID,
61 CKA_SENSITIVE,
62 CKA_START_DATE,
63 CKA_END_DATE,
64 CKA_MODULUS,
65 CKA_MODULUS_BITS,
66 CKA_PUBLIC_EXPONENT,
67 CKA_PRIVATE_EXPONENT,
68 CKA_PRIME_1,
69 CKA_PRIME_2,
70 CKA_EXPONENT_1,
71 CKA_EXPONENT_2,
72 CKA_COEFFICIENT,
73 CKA_PRIME,
74 CKA_SUBPRIME,
75 CKA_BASE,
76 CKA_EXTRACTABLE,
77 CKA_LOCAL,
78 CKA_NEVER_EXTRACTABLE,
79 CKA_ALWAYS_SENSITIVE,
80 CKA_MODIFIABLE,
81 CKA_ECDSA_PARAMS,
82 CKA_EC_PARAMS,
83 CKA_EC_POINT,
84 CKA_SECONDARY_AUTH,
85 CKA_AUTH_PIN_FLAGS,
86 CKA_HW_FEATURE_TYPE,
87 CKA_RESET_ON_INIT,
88 CKA_HAS_RESET
89 };
90
91 /*
92 * attributes that exists only in public key objects
93 * Note: some attributes may also exist in one or two
94 * other object classes, but they are also listed
95 * because not all object have them.
96 */
97 CK_ATTRIBUTE_TYPE PUB_KEY_ATTRS[] =
98 {
99 CKA_SUBJECT,
100 CKA_ENCRYPT,
101 CKA_WRAP,
102 CKA_VERIFY,
103 CKA_VERIFY_RECOVER,
104 CKA_MODULUS,
105 CKA_MODULUS_BITS,
106 CKA_PUBLIC_EXPONENT,
107 CKA_PRIME,
108 CKA_SUBPRIME,
109 CKA_BASE,
110 CKA_TRUSTED,
111 CKA_ECDSA_PARAMS,
112 CKA_EC_PARAMS,
113 CKA_EC_POINT
114 };
115
116 /*
117 * attributes that exists only in private key objects
118 * Note: some attributes may also exist in one or two
119 * other object classes, but they are also listed
120 * because not all object have them.
121 */
122 CK_ATTRIBUTE_TYPE PRIV_KEY_ATTRS[] =
123 {
124 CKA_DECRYPT,
125 CKA_UNWRAP,
126 CKA_SIGN,
127 CKA_SIGN_RECOVER,
128 CKA_MODULUS,
129 CKA_PUBLIC_EXPONENT,
130 CKA_PRIVATE_EXPONENT,
131 CKA_PRIME,
132 CKA_SUBPRIME,
133 CKA_BASE,
134 CKA_PRIME_1,
135 CKA_PRIME_2,
136 CKA_EXPONENT_1,
137 CKA_EXPONENT_2,
138 CKA_COEFFICIENT,
139 CKA_VALUE_BITS,
140 CKA_SUBJECT,
141 CKA_SENSITIVE,
142 CKA_EXTRACTABLE,
143 CKA_NEVER_EXTRACTABLE,
144 CKA_ALWAYS_SENSITIVE,
145 CKA_EC_PARAMS
146 };
147
148 /*
149 * attributes that exists only in secret key objects
150 * Note: some attributes may also exist in one or two
151 * other object classes, but they are also listed
152 * because not all object have them.
153 */
154 CK_ATTRIBUTE_TYPE SECRET_KEY_ATTRS[] =
155 {
156 CKA_VALUE_LEN,
157 CKA_ENCRYPT,
158 CKA_DECRYPT,
159 CKA_WRAP,
160 CKA_UNWRAP,
161 CKA_SIGN,
162 CKA_VERIFY,
163 CKA_SENSITIVE,
164 CKA_EXTRACTABLE,
165 CKA_NEVER_EXTRACTABLE,
166 CKA_ALWAYS_SENSITIVE
167 };
168
169 /*
170 * attributes that exists only in domain parameter objects
171 * Note: some attributes may also exist in one or two
172 * other object classes, but they are also listed
173 * because not all object have them.
174 */
175 CK_ATTRIBUTE_TYPE DOMAIN_ATTRS[] =
176 {
177 CKA_PRIME,
178 CKA_SUBPRIME,
179 CKA_BASE,
180 CKA_PRIME_BITS,
181 CKA_SUBPRIME_BITS,
182 CKA_SUB_PRIME_BITS
183 };
184
185 /*
186 * attributes that exists only in hardware feature objects
187 *
188 */
189 CK_ATTRIBUTE_TYPE HARDWARE_ATTRS[] =
190 {
191 CKA_HW_FEATURE_TYPE,
192 CKA_RESET_ON_INIT,
193 CKA_HAS_RESET
194 };
195
196 /*
197 * attributes that exists only in certificate objects
198 */
199 CK_ATTRIBUTE_TYPE CERT_ATTRS[] =
200 {
201 CKA_CERTIFICATE_TYPE,
202 CKA_TRUSTED,
203 CKA_SUBJECT,
204 CKA_ID,
205 CKA_ISSUER,
206 CKA_AC_ISSUER,
207 CKA_SERIAL_NUMBER,
208 CKA_OWNER,
209 CKA_ATTR_TYPES
210 };
211
212
213 /*
214 * Validate the attribute by using binary search algorithm.
215 */
216 CK_RV
soft_lookup_attr(CK_ATTRIBUTE_TYPE type)217 soft_lookup_attr(CK_ATTRIBUTE_TYPE type)
218 {
219
220 size_t lower, middle, upper;
221
222 lower = 0;
223 upper = (sizeof (attr_map) / sizeof (CK_ATTRIBUTE_TYPE)) - 1;
224
225 while (lower <= upper) {
226 /* Always starts from middle. */
227 middle = (lower + upper) / 2;
228
229 if (type > attr_map[middle]) {
230 /* Adjust the lower bound to upper half. */
231 lower = middle + 1;
232 continue;
233 }
234
235 if (type == attr_map[middle]) {
236 /* Found it. */
237 return (CKR_OK);
238 }
239
240 if (type < attr_map[middle]) {
241 /* Adjust the upper bound to lower half. */
242 upper = middle - 1;
243 continue;
244 }
245 }
246
247 /* Failed to find the matching attribute from the attribute table. */
248 return (CKR_ATTRIBUTE_TYPE_INVALID);
249 }
250
251
252 /*
253 * Validate the attribute by using the following search algorithm:
254 *
255 * 1) Search for the most frequently used attributes first.
256 * 2) If not found, search for the usage-purpose attributes - these
257 * attributes have dense set of values, therefore compiler will
258 * optimize it with a branch table and branch to the appropriate
259 * case.
260 * 3) If still not found, use binary search for the rest of the
261 * attributes in the attr_map[] table.
262 */
263 CK_RV
soft_validate_attr(CK_ATTRIBUTE_PTR template,CK_ULONG ulAttrNum,CK_OBJECT_CLASS * class)264 soft_validate_attr(CK_ATTRIBUTE_PTR template, CK_ULONG ulAttrNum,
265 CK_OBJECT_CLASS *class)
266 {
267
268 CK_ULONG i;
269 CK_RV rv = CKR_OK;
270
271 for (i = 0; i < ulAttrNum; i++) {
272 /* First tier search */
273 switch (template[i].type) {
274 case CKA_CLASS:
275 *class = *((CK_OBJECT_CLASS*)template[i].pValue);
276 break;
277 case CKA_TOKEN:
278 break;
279 case CKA_KEY_TYPE:
280 break;
281 case CKA_VALUE:
282 break;
283 case CKA_VALUE_LEN:
284 break;
285 case CKA_VALUE_BITS:
286 break;
287 default:
288 /* Second tier search */
289 switch (template[i].type) {
290 case CKA_ENCRYPT:
291 break;
292 case CKA_DECRYPT:
293 break;
294 case CKA_WRAP:
295 break;
296 case CKA_UNWRAP:
297 break;
298 case CKA_SIGN:
299 break;
300 case CKA_SIGN_RECOVER:
301 break;
302 case CKA_VERIFY:
303 break;
304 case CKA_VERIFY_RECOVER:
305 break;
306 case CKA_DERIVE:
307 break;
308 default:
309 /* Third tier search */
310 rv = soft_lookup_attr(template[i].type);
311 if (rv != CKR_OK)
312 return (rv);
313 break;
314 }
315 break;
316 }
317 }
318 return (rv);
319 }
320
321 static void
cleanup_cert_attr(cert_attr_t * attr)322 cleanup_cert_attr(cert_attr_t *attr)
323 {
324 if (attr) {
325 if (attr->value) {
326 (void) memset(attr->value, 0, attr->length);
327 free(attr->value);
328 }
329 attr->value = NULL;
330 attr->length = 0;
331 }
332 }
333
334 static CK_RV
copy_cert_attr(cert_attr_t * src_attr,cert_attr_t ** dest_attr)335 copy_cert_attr(cert_attr_t *src_attr, cert_attr_t **dest_attr)
336 {
337 CK_RV rv = CKR_OK;
338
339 if (src_attr == NULL || dest_attr == NULL)
340 return (CKR_HOST_MEMORY);
341
342 if (src_attr->value == NULL)
343 return (CKR_HOST_MEMORY);
344
345 /* free memory if its already allocated */
346 if (*dest_attr != NULL) {
347 if ((*dest_attr)->value != (CK_BYTE *)NULL)
348 free((*dest_attr)->value);
349 } else {
350 *dest_attr = malloc(sizeof (cert_attr_t));
351 if (*dest_attr == NULL)
352 return (CKR_HOST_MEMORY);
353 }
354
355 (*dest_attr)->value = NULL;
356 (*dest_attr)->length = 0;
357
358 if (src_attr->length) {
359 (*dest_attr)->value = malloc(src_attr->length);
360 if ((*dest_attr)->value == NULL) {
361 free(*dest_attr);
362 return (CKR_HOST_MEMORY);
363 }
364
365 (void) memcpy((*dest_attr)->value, src_attr->value,
366 src_attr->length);
367 (*dest_attr)->length = src_attr->length;
368 }
369
370 return (rv);
371 }
372
373 void
soft_cleanup_cert_object(soft_object_t * object_p)374 soft_cleanup_cert_object(soft_object_t *object_p)
375 {
376 CK_CERTIFICATE_TYPE certtype = object_p->cert_type;
377
378 if (object_p->class != CKO_CERTIFICATE ||
379 OBJ_CERT(object_p) == NULL)
380 return;
381
382 if (certtype == CKC_X_509) {
383 if (X509_CERT_SUBJECT(object_p) != NULL) {
384 cleanup_cert_attr(X509_CERT_SUBJECT(object_p));
385 free(X509_CERT_SUBJECT(object_p));
386 X509_CERT_SUBJECT(object_p) = NULL;
387 }
388 if (X509_CERT_VALUE(object_p) != NULL) {
389 cleanup_cert_attr(X509_CERT_VALUE(object_p));
390 free(X509_CERT_VALUE(object_p));
391 X509_CERT_VALUE(object_p) = NULL;
392 }
393 free(OBJ_CERT(object_p));
394 } else if (certtype == CKC_X_509_ATTR_CERT) {
395 if (X509_ATTR_CERT_VALUE(object_p) != NULL) {
396 cleanup_cert_attr(X509_ATTR_CERT_VALUE(object_p));
397 free(X509_ATTR_CERT_VALUE(object_p));
398 X509_ATTR_CERT_VALUE(object_p) = NULL;
399 }
400 if (X509_ATTR_CERT_OWNER(object_p) != NULL) {
401 cleanup_cert_attr(X509_ATTR_CERT_OWNER(object_p));
402 free(X509_ATTR_CERT_OWNER(object_p));
403 X509_ATTR_CERT_OWNER(object_p) = NULL;
404 }
405 free(OBJ_CERT(object_p));
406 }
407 }
408
409 /*
410 * Clean up and release all the storage in the extra attribute list
411 * of an object.
412 */
413 void
soft_cleanup_extra_attr(soft_object_t * object_p)414 soft_cleanup_extra_attr(soft_object_t *object_p)
415 {
416
417 CK_ATTRIBUTE_INFO_PTR extra_attr;
418 CK_ATTRIBUTE_INFO_PTR tmp;
419
420 extra_attr = object_p->extra_attrlistp;
421 while (extra_attr) {
422 tmp = extra_attr->next;
423 if (extra_attr->attr.pValue)
424 /*
425 * All extra attributes in the extra attribute
426 * list have pValue points to the value of the
427 * attribute (with simple byte array type).
428 * Free the storage for the value of the attribute.
429 */
430 free(extra_attr->attr.pValue);
431
432 /* Free the storage for the attribute_info struct. */
433 free(extra_attr);
434 extra_attr = tmp;
435 }
436
437 object_p->extra_attrlistp = NULL;
438 }
439
440
441 /*
442 * Create the attribute_info struct to hold the object's attribute,
443 * and add it to the extra attribute list of an object.
444 */
445 CK_RV
soft_add_extra_attr(CK_ATTRIBUTE_PTR template,soft_object_t * object_p)446 soft_add_extra_attr(CK_ATTRIBUTE_PTR template, soft_object_t *object_p)
447 {
448
449 CK_ATTRIBUTE_INFO_PTR attrp;
450
451 /* Allocate the storage for the attribute_info struct. */
452 attrp = calloc(1, sizeof (attribute_info_t));
453 if (attrp == NULL) {
454 return (CKR_HOST_MEMORY);
455 }
456
457 /* Set up attribute_info struct. */
458 attrp->attr.type = template->type;
459 attrp->attr.ulValueLen = template->ulValueLen;
460
461 if ((template->pValue != NULL) &&
462 (template->ulValueLen > 0)) {
463 /* Allocate storage for the value of the attribute. */
464 attrp->attr.pValue = malloc(template->ulValueLen);
465 if (attrp->attr.pValue == NULL) {
466 free(attrp);
467 return (CKR_HOST_MEMORY);
468 }
469
470 (void) memcpy(attrp->attr.pValue, template->pValue,
471 template->ulValueLen);
472 } else {
473 attrp->attr.pValue = NULL;
474 }
475
476 /* Insert the new attribute in front of extra attribute list. */
477 if (object_p->extra_attrlistp == NULL) {
478 object_p->extra_attrlistp = attrp;
479 attrp->next = NULL;
480 } else {
481 attrp->next = object_p->extra_attrlistp;
482 object_p->extra_attrlistp = attrp;
483 }
484
485 return (CKR_OK);
486 }
487
488 CK_RV
soft_copy_certificate(certificate_obj_t * oldcert,certificate_obj_t ** newcert,CK_CERTIFICATE_TYPE type)489 soft_copy_certificate(certificate_obj_t *oldcert, certificate_obj_t **newcert,
490 CK_CERTIFICATE_TYPE type)
491 {
492 CK_RV rv = CKR_OK;
493 certificate_obj_t *cert;
494 x509_cert_t x509;
495 x509_attr_cert_t x509_attr;
496
497 cert = calloc(1, sizeof (certificate_obj_t));
498 if (cert == NULL) {
499 return (CKR_HOST_MEMORY);
500 }
501
502 if (type == CKC_X_509) {
503 x509 = oldcert->cert_type_u.x509;
504 if (x509.subject)
505 if ((rv = copy_cert_attr(x509.subject,
506 &cert->cert_type_u.x509.subject)))
507 return (rv);
508 if (x509.value)
509 if ((rv = copy_cert_attr(x509.value,
510 &cert->cert_type_u.x509.value)))
511 return (rv);
512 } else if (type == CKC_X_509_ATTR_CERT) {
513 x509_attr = oldcert->cert_type_u.x509_attr;
514 if (x509_attr.owner)
515 if ((rv = copy_cert_attr(x509_attr.owner,
516 &cert->cert_type_u.x509_attr.owner)))
517 return (rv);
518 if (x509_attr.value)
519 if ((rv = copy_cert_attr(x509_attr.value,
520 &cert->cert_type_u.x509_attr.value)))
521 return (rv);
522 } else {
523 /* wrong certificate type */
524 rv = CKR_ATTRIBUTE_TYPE_INVALID;
525 }
526 if (rv == CKR_OK)
527 *newcert = cert;
528 return (rv);
529 }
530
531 /*
532 * Copy the attribute_info struct from the old object to a new attribute_info
533 * struct, and add that new struct to the extra attribute list of the new
534 * object.
535 */
536 CK_RV
soft_copy_extra_attr(CK_ATTRIBUTE_INFO_PTR old_attrp,soft_object_t * object_p)537 soft_copy_extra_attr(CK_ATTRIBUTE_INFO_PTR old_attrp, soft_object_t *object_p)
538 {
539 CK_ATTRIBUTE_INFO_PTR attrp;
540
541 /* Allocate attribute_info struct. */
542 attrp = calloc(1, sizeof (attribute_info_t));
543 if (attrp == NULL) {
544 return (CKR_HOST_MEMORY);
545 }
546
547 attrp->attr.type = old_attrp->attr.type;
548 attrp->attr.ulValueLen = old_attrp->attr.ulValueLen;
549
550 if ((old_attrp->attr.pValue != NULL) &&
551 (old_attrp->attr.ulValueLen > 0)) {
552 attrp->attr.pValue = malloc(old_attrp->attr.ulValueLen);
553 if (attrp->attr.pValue == NULL) {
554 free(attrp);
555 return (CKR_HOST_MEMORY);
556 }
557
558 (void) memcpy(attrp->attr.pValue, old_attrp->attr.pValue,
559 old_attrp->attr.ulValueLen);
560 } else {
561 attrp->attr.pValue = NULL;
562 }
563
564 /* Insert the new attribute in front of extra attribute list */
565 if (object_p->extra_attrlistp == NULL) {
566 object_p->extra_attrlistp = attrp;
567 attrp->next = NULL;
568 } else {
569 attrp->next = object_p->extra_attrlistp;
570 object_p->extra_attrlistp = attrp;
571 }
572
573 return (CKR_OK);
574 }
575
576
577 /*
578 * Get the attribute triple from the extra attribute list in the object
579 * (if the specified attribute type is found), and copy it to a template.
580 * Note the type of the attribute to be copied is specified by the template,
581 * and the storage is pre-allocated for the atrribute value in the template
582 * for doing the copy.
583 */
584 CK_RV
get_extra_attr_from_object(soft_object_t * object_p,CK_ATTRIBUTE_PTR template)585 get_extra_attr_from_object(soft_object_t *object_p, CK_ATTRIBUTE_PTR template)
586 {
587
588 CK_ATTRIBUTE_INFO_PTR extra_attr;
589 CK_ATTRIBUTE_TYPE type = template->type;
590
591 extra_attr = object_p->extra_attrlistp;
592
593 while (extra_attr) {
594 if (type == extra_attr->attr.type) {
595 /* Found it. */
596 break;
597 } else {
598 /* Does not match, try next one. */
599 extra_attr = extra_attr->next;
600 }
601 }
602
603 if (extra_attr == NULL) {
604 /* A valid but un-initialized attribute. */
605 template->ulValueLen = 0;
606 return (CKR_OK);
607 }
608
609 /*
610 * We found the attribute in the extra attribute list.
611 */
612 if (template->pValue == NULL) {
613 template->ulValueLen = extra_attr->attr.ulValueLen;
614 return (CKR_OK);
615 }
616
617 if (template->ulValueLen >= extra_attr->attr.ulValueLen) {
618 /*
619 * The buffer provided by the application is large
620 * enough to hold the value of the attribute.
621 */
622 (void) memcpy(template->pValue, extra_attr->attr.pValue,
623 extra_attr->attr.ulValueLen);
624 template->ulValueLen = extra_attr->attr.ulValueLen;
625 return (CKR_OK);
626 } else {
627 /*
628 * The buffer provided by the application does
629 * not have enough space to hold the value.
630 */
631 template->ulValueLen = (CK_ULONG)-1;
632 return (CKR_BUFFER_TOO_SMALL);
633 }
634 }
635
636
637 /*
638 * Modify the attribute triple in the extra attribute list of the object
639 * if the specified attribute type is found. Otherwise, just add it to
640 * list.
641 */
642 CK_RV
set_extra_attr_to_object(soft_object_t * object_p,CK_ATTRIBUTE_TYPE type,CK_ATTRIBUTE_PTR template)643 set_extra_attr_to_object(soft_object_t *object_p, CK_ATTRIBUTE_TYPE type,
644 CK_ATTRIBUTE_PTR template)
645 {
646
647 CK_ATTRIBUTE_INFO_PTR extra_attr;
648
649 extra_attr = object_p->extra_attrlistp;
650
651 while (extra_attr) {
652 if (type == extra_attr->attr.type) {
653 /* Found it. */
654 break;
655 } else {
656 /* Does not match, try next one. */
657 extra_attr = extra_attr->next;
658 }
659 }
660
661 if (extra_attr == NULL) {
662 /*
663 * This attribute is a new one, go ahead adding it to
664 * the extra attribute list.
665 */
666 return (soft_add_extra_attr(template, object_p));
667 }
668
669 /* We found the attribute in the extra attribute list. */
670 if ((template->pValue != NULL) &&
671 (template->ulValueLen > 0)) {
672 if (template->ulValueLen > extra_attr->attr.ulValueLen) {
673 /* The old buffer is too small to hold the new value. */
674 if (extra_attr->attr.pValue != NULL)
675 /* Free storage for the old attribute value. */
676 free(extra_attr->attr.pValue);
677
678 /* Allocate storage for the new attribute value. */
679 extra_attr->attr.pValue = malloc(template->ulValueLen);
680 if (extra_attr->attr.pValue == NULL) {
681 return (CKR_HOST_MEMORY);
682 }
683 }
684
685 /* Replace the attribute with new value. */
686 extra_attr->attr.ulValueLen = template->ulValueLen;
687 (void) memcpy(extra_attr->attr.pValue, template->pValue,
688 template->ulValueLen);
689 } else {
690 extra_attr->attr.pValue = NULL;
691 }
692
693 return (CKR_OK);
694 }
695
696
697 /*
698 * Copy the big integer attribute value from template to a biginteger_t struct.
699 */
700 CK_RV
get_bigint_attr_from_template(biginteger_t * big,CK_ATTRIBUTE_PTR template)701 get_bigint_attr_from_template(biginteger_t *big, CK_ATTRIBUTE_PTR template)
702 {
703
704 if ((template->pValue != NULL) &&
705 (template->ulValueLen > 0)) {
706 /* Allocate storage for the value of the attribute. */
707 big->big_value = malloc(template->ulValueLen);
708 if (big->big_value == NULL) {
709 return (CKR_HOST_MEMORY);
710 }
711
712 (void) memcpy(big->big_value, template->pValue,
713 template->ulValueLen);
714 big->big_value_len = template->ulValueLen;
715 } else {
716 big->big_value = NULL;
717 big->big_value_len = 0;
718 }
719
720 return (CKR_OK);
721 }
722
723
724 /*
725 * Copy the big integer attribute value from a biginteger_t struct in the
726 * object to a template.
727 */
728 CK_RV
get_bigint_attr_from_object(biginteger_t * big,CK_ATTRIBUTE_PTR template)729 get_bigint_attr_from_object(biginteger_t *big, CK_ATTRIBUTE_PTR template)
730 {
731
732 if (template->pValue == NULL) {
733 template->ulValueLen = big->big_value_len;
734 return (CKR_OK);
735 }
736
737 if (big->big_value == NULL) {
738 template->ulValueLen = 0;
739 return (CKR_OK);
740 }
741
742 if (template->ulValueLen >= big->big_value_len) {
743 /*
744 * The buffer provided by the application is large
745 * enough to hold the value of the attribute.
746 */
747 (void) memcpy(template->pValue, big->big_value,
748 big->big_value_len);
749 template->ulValueLen = big->big_value_len;
750 return (CKR_OK);
751 } else {
752 /*
753 * The buffer provided by the application does
754 * not have enough space to hold the value.
755 */
756 template->ulValueLen = (CK_ULONG)-1;
757 return (CKR_BUFFER_TOO_SMALL);
758 }
759 }
760
761
762 /*
763 * Copy the boolean data type attribute value from an object for the
764 * specified attribute to the template.
765 */
766 CK_RV
get_bool_attr_from_object(soft_object_t * object_p,CK_ULONG bool_flag,CK_ATTRIBUTE_PTR template)767 get_bool_attr_from_object(soft_object_t *object_p, CK_ULONG bool_flag,
768 CK_ATTRIBUTE_PTR template)
769 {
770
771 if (template->pValue == NULL) {
772 template->ulValueLen = sizeof (CK_BBOOL);
773 return (CKR_OK);
774 }
775
776 if (template->ulValueLen >= sizeof (CK_BBOOL)) {
777 /*
778 * The buffer provided by the application is large
779 * enough to hold the value of the attribute.
780 */
781 if (object_p->bool_attr_mask & bool_flag) {
782 *((CK_BBOOL *)template->pValue) = B_TRUE;
783 } else {
784 *((CK_BBOOL *)template->pValue) = B_FALSE;
785 }
786
787 template->ulValueLen = sizeof (CK_BBOOL);
788 return (CKR_OK);
789 } else {
790 /*
791 * The buffer provided by the application does
792 * not have enough space to hold the value.
793 */
794 template->ulValueLen = (CK_ULONG)-1;
795 return (CKR_BUFFER_TOO_SMALL);
796 }
797 }
798
799 /*
800 * Set the boolean data type attribute value in the object.
801 */
802 CK_RV
set_bool_attr_to_object(soft_object_t * object_p,CK_ULONG bool_flag,CK_ATTRIBUTE_PTR template)803 set_bool_attr_to_object(soft_object_t *object_p, CK_ULONG bool_flag,
804 CK_ATTRIBUTE_PTR template)
805 {
806
807 if (*(CK_BBOOL *)template->pValue)
808 object_p->bool_attr_mask |= bool_flag;
809 else
810 object_p->bool_attr_mask &= ~bool_flag;
811
812 return (CKR_OK);
813 }
814
815
816 /*
817 * Copy the CK_ULONG data type attribute value from an object to the
818 * template.
819 */
820 CK_RV
get_ulong_attr_from_object(CK_ULONG value,CK_ATTRIBUTE_PTR template)821 get_ulong_attr_from_object(CK_ULONG value, CK_ATTRIBUTE_PTR template)
822 {
823
824 if (template->pValue == NULL) {
825 template->ulValueLen = sizeof (CK_ULONG);
826 return (CKR_OK);
827 }
828
829 if (template->ulValueLen >= sizeof (CK_ULONG)) {
830 /*
831 * The buffer provided by the application is large
832 * enough to hold the value of the attribute.
833 * It is also assumed to be correctly aligned.
834 */
835 *(CK_ULONG_PTR)template->pValue = value;
836 template->ulValueLen = sizeof (CK_ULONG);
837 return (CKR_OK);
838 } else {
839 /*
840 * The buffer provided by the application does
841 * not have enough space to hold the value.
842 */
843 template->ulValueLen = (CK_ULONG)-1;
844 return (CKR_BUFFER_TOO_SMALL);
845 }
846 }
847
848
849 /*
850 * Copy the CK_ULONG data type attribute value from a template to the
851 * object.
852 */
853 static CK_RV
get_ulong_attr_from_template(CK_ULONG * value,CK_ATTRIBUTE_PTR template)854 get_ulong_attr_from_template(CK_ULONG *value, CK_ATTRIBUTE_PTR template)
855 {
856
857 if (template->ulValueLen < sizeof (CK_ULONG))
858 return (CKR_ATTRIBUTE_VALUE_INVALID);
859
860 if (template->pValue != NULL) {
861 *value = *(CK_ULONG_PTR)template->pValue;
862 } else {
863 *value = 0;
864 }
865
866 return (CKR_OK);
867 }
868
869 /*
870 * Copy the big integer attribute value from source's biginteger_t to
871 * destination's biginteger_t.
872 */
873 void
copy_bigint_attr(biginteger_t * src,biginteger_t * dst)874 copy_bigint_attr(biginteger_t *src, biginteger_t *dst)
875 {
876
877 if ((src->big_value != NULL) &&
878 (src->big_value_len > 0)) {
879 /*
880 * To do the copy, just have dst's big_value points
881 * to src's.
882 */
883 dst->big_value = src->big_value;
884 dst->big_value_len = src->big_value_len;
885
886 /*
887 * After the copy, nullify the src's big_value pointer.
888 * It prevents any double freeing the value.
889 */
890 src->big_value = NULL;
891 src->big_value_len = 0;
892 } else {
893 dst->big_value = NULL;
894 dst->big_value_len = 0;
895 }
896 }
897
898 CK_RV
get_string_from_template(CK_ATTRIBUTE_PTR dest,CK_ATTRIBUTE_PTR src)899 get_string_from_template(CK_ATTRIBUTE_PTR dest, CK_ATTRIBUTE_PTR src)
900 {
901 if ((src->pValue != NULL) &&
902 (src->ulValueLen > 0)) {
903 /* Allocate storage for the value of the attribute. */
904 dest->pValue = malloc(src->ulValueLen);
905 if (dest->pValue == NULL) {
906 return (CKR_HOST_MEMORY);
907 }
908
909 (void) memcpy(dest->pValue, src->pValue,
910 src->ulValueLen);
911 dest->ulValueLen = src->ulValueLen;
912 dest->type = src->type;
913 } else {
914 dest->pValue = NULL;
915 dest->ulValueLen = 0;
916 dest->type = src->type;
917 }
918
919 return (CKR_OK);
920
921 }
922
923 CK_RV
get_cert_attr_from_template(cert_attr_t ** dest,CK_ATTRIBUTE_PTR src)924 get_cert_attr_from_template(cert_attr_t **dest, CK_ATTRIBUTE_PTR src)
925 {
926 if (src->pValue != NULL && src->ulValueLen > 0) {
927 /*
928 * If the attribute was already set, clear out the
929 * existing value and release the memory.
930 */
931 if (*dest != NULL) {
932 if ((*dest)->value != NULL) {
933 (void) memset((*dest)->value, 0,
934 (*dest)->length);
935 free((*dest)->value);
936 }
937 } else {
938 *dest = malloc(sizeof (cert_attr_t));
939 if (*dest == NULL) {
940 return (CKR_HOST_MEMORY);
941 }
942 (void) memset(*dest, 0, sizeof (cert_attr_t));
943 }
944 (*dest)->value = malloc(src->ulValueLen);
945 if ((*dest)->value == NULL) {
946 free(*dest);
947 *dest = NULL;
948 return (CKR_HOST_MEMORY);
949 }
950 (void) memcpy((*dest)->value, src->pValue, src->ulValueLen);
951 (*dest)->length = src->ulValueLen;
952 }
953
954 return (CKR_OK);
955 }
956
957 /*
958 * Copy the certificate attribute information to the template.
959 * If the template attribute is not big enough, set the ulValueLen=-1
960 * and return CKR_BUFFER_TOO_SMALL.
961 */
962 static CK_RV
get_cert_attr_from_object(cert_attr_t * src,CK_ATTRIBUTE_PTR template)963 get_cert_attr_from_object(cert_attr_t *src, CK_ATTRIBUTE_PTR template)
964 {
965 if (template->pValue == NULL) {
966 template->ulValueLen = src->length;
967 return (CKR_OK);
968 } else if (template->ulValueLen >= src->length) {
969 /*
970 * The buffer provided by the application is large
971 * enough to hold the value of the attribute.
972 */
973 (void) memcpy(template->pValue, src->value, src->length);
974 template->ulValueLen = src->length;
975 return (CKR_OK);
976 } else {
977 /*
978 * The buffer provided by the application does
979 * not have enough space to hold the value.
980 */
981 template->ulValueLen = (CK_ULONG)-1;
982 return (CKR_BUFFER_TOO_SMALL);
983 }
984 }
985
986 void
string_attr_cleanup(CK_ATTRIBUTE_PTR template)987 string_attr_cleanup(CK_ATTRIBUTE_PTR template)
988 {
989
990 if (template->pValue) {
991 free(template->pValue);
992 template->pValue = NULL;
993 template->ulValueLen = 0;
994 }
995 }
996
997 /*
998 * Release the storage allocated for object attribute with big integer
999 * value.
1000 */
1001 void
bigint_attr_cleanup(biginteger_t * big)1002 bigint_attr_cleanup(biginteger_t *big)
1003 {
1004
1005 if (big == NULL)
1006 return;
1007
1008 if (big->big_value) {
1009 (void) memset(big->big_value, 0, big->big_value_len);
1010 free(big->big_value);
1011 big->big_value = NULL;
1012 big->big_value_len = 0;
1013 }
1014 }
1015
1016
1017 /*
1018 * Clean up and release all the storage allocated to hold the big integer
1019 * attributes associated with the type (i.e. class) of the object. Also,
1020 * release the storage allocated to the type of the object.
1021 */
1022 void
soft_cleanup_object_bigint_attrs(soft_object_t * object_p)1023 soft_cleanup_object_bigint_attrs(soft_object_t *object_p)
1024 {
1025
1026 CK_OBJECT_CLASS class = object_p->class;
1027 CK_KEY_TYPE keytype = object_p->key_type;
1028
1029
1030 switch (class) {
1031 case CKO_PUBLIC_KEY:
1032 if (OBJ_PUB(object_p)) {
1033 switch (keytype) {
1034 case CKK_RSA:
1035 bigint_attr_cleanup(OBJ_PUB_RSA_MOD(
1036 object_p));
1037 bigint_attr_cleanup(OBJ_PUB_RSA_PUBEXPO(
1038 object_p));
1039 break;
1040
1041 case CKK_DSA:
1042 bigint_attr_cleanup(OBJ_PUB_DSA_PRIME(
1043 object_p));
1044 bigint_attr_cleanup(OBJ_PUB_DSA_SUBPRIME(
1045 object_p));
1046 bigint_attr_cleanup(OBJ_PUB_DSA_BASE(
1047 object_p));
1048 bigint_attr_cleanup(OBJ_PUB_DSA_VALUE(
1049 object_p));
1050 break;
1051
1052 case CKK_DH:
1053 bigint_attr_cleanup(OBJ_PUB_DH_PRIME(
1054 object_p));
1055 bigint_attr_cleanup(OBJ_PUB_DH_BASE(
1056 object_p));
1057 bigint_attr_cleanup(OBJ_PUB_DH_VALUE(
1058 object_p));
1059 break;
1060
1061 case CKK_X9_42_DH:
1062 bigint_attr_cleanup(OBJ_PUB_DH942_PRIME(
1063 object_p));
1064 bigint_attr_cleanup(OBJ_PUB_DH942_BASE(
1065 object_p));
1066 bigint_attr_cleanup(OBJ_PUB_DH942_SUBPRIME(
1067 object_p));
1068 bigint_attr_cleanup(OBJ_PUB_DH942_VALUE(
1069 object_p));
1070 break;
1071 case CKK_EC:
1072 bigint_attr_cleanup(OBJ_PUB_EC_POINT(
1073 object_p));
1074 break;
1075 }
1076
1077 /* Release Public Key Object struct */
1078 free(OBJ_PUB(object_p));
1079 OBJ_PUB(object_p) = NULL;
1080 }
1081 break;
1082
1083 case CKO_PRIVATE_KEY:
1084 if (OBJ_PRI(object_p)) {
1085 switch (keytype) {
1086 case CKK_RSA:
1087 bigint_attr_cleanup(OBJ_PRI_RSA_MOD(
1088 object_p));
1089 bigint_attr_cleanup(OBJ_PRI_RSA_PUBEXPO(
1090 object_p));
1091 bigint_attr_cleanup(OBJ_PRI_RSA_PRIEXPO(
1092 object_p));
1093 bigint_attr_cleanup(OBJ_PRI_RSA_PRIME1(
1094 object_p));
1095 bigint_attr_cleanup(OBJ_PRI_RSA_PRIME2(
1096 object_p));
1097 bigint_attr_cleanup(OBJ_PRI_RSA_EXPO1(
1098 object_p));
1099 bigint_attr_cleanup(OBJ_PRI_RSA_EXPO2(
1100 object_p));
1101 bigint_attr_cleanup(OBJ_PRI_RSA_COEF(
1102 object_p));
1103 break;
1104
1105 case CKK_DSA:
1106 bigint_attr_cleanup(OBJ_PRI_DSA_PRIME(
1107 object_p));
1108 bigint_attr_cleanup(OBJ_PRI_DSA_SUBPRIME(
1109 object_p));
1110 bigint_attr_cleanup(OBJ_PRI_DSA_BASE(
1111 object_p));
1112 bigint_attr_cleanup(OBJ_PRI_DSA_VALUE(
1113 object_p));
1114 break;
1115
1116 case CKK_DH:
1117 bigint_attr_cleanup(OBJ_PRI_DH_PRIME(
1118 object_p));
1119 bigint_attr_cleanup(OBJ_PRI_DH_BASE(
1120 object_p));
1121 bigint_attr_cleanup(OBJ_PRI_DH_VALUE(
1122 object_p));
1123 break;
1124
1125 case CKK_X9_42_DH:
1126 bigint_attr_cleanup(OBJ_PRI_DH942_PRIME(
1127 object_p));
1128 bigint_attr_cleanup(OBJ_PRI_DH942_BASE(
1129 object_p));
1130 bigint_attr_cleanup(OBJ_PRI_DH942_SUBPRIME(
1131 object_p));
1132 bigint_attr_cleanup(OBJ_PRI_DH942_VALUE(
1133 object_p));
1134 break;
1135
1136 case CKK_EC:
1137 bigint_attr_cleanup(OBJ_PRI_EC_VALUE(
1138 object_p));
1139 break;
1140 }
1141
1142 /* Release Private Key Object struct. */
1143 free(OBJ_PRI(object_p));
1144 OBJ_PRI(object_p) = NULL;
1145 }
1146 break;
1147
1148 case CKO_SECRET_KEY:
1149 if (OBJ_SEC(object_p)) {
1150 /* cleanup key data area */
1151 if (OBJ_SEC_VALUE(object_p) != NULL &&
1152 OBJ_SEC_VALUE_LEN(object_p) > 0) {
1153 (void) memset(OBJ_SEC_VALUE(object_p), 0,
1154 OBJ_SEC_VALUE_LEN(object_p));
1155 free(OBJ_SEC_VALUE(object_p));
1156 }
1157 /* cleanup key schedule data area */
1158 if (OBJ_KEY_SCHED(object_p) != NULL &&
1159 OBJ_KEY_SCHED_LEN(object_p) > 0) {
1160 (void) memset(OBJ_KEY_SCHED(object_p), 0,
1161 OBJ_KEY_SCHED_LEN(object_p));
1162 free(OBJ_KEY_SCHED(object_p));
1163 }
1164
1165 /* Release Secret Key Object struct. */
1166 free(OBJ_SEC(object_p));
1167 OBJ_SEC(object_p) = NULL;
1168 }
1169 break;
1170
1171 case CKO_DOMAIN_PARAMETERS:
1172 if (OBJ_DOM(object_p)) {
1173 switch (keytype) {
1174 case CKK_DSA:
1175 bigint_attr_cleanup(OBJ_DOM_DSA_PRIME(
1176 object_p));
1177 bigint_attr_cleanup(OBJ_DOM_DSA_SUBPRIME(
1178 object_p));
1179 bigint_attr_cleanup(OBJ_DOM_DSA_BASE(
1180 object_p));
1181 break;
1182
1183 case CKK_DH:
1184 bigint_attr_cleanup(OBJ_DOM_DH_PRIME(
1185 object_p));
1186 bigint_attr_cleanup(OBJ_DOM_DH_BASE(
1187 object_p));
1188 break;
1189
1190 case CKK_X9_42_DH:
1191 bigint_attr_cleanup(OBJ_DOM_DH942_PRIME(
1192 object_p));
1193 bigint_attr_cleanup(OBJ_DOM_DH942_BASE(
1194 object_p));
1195 bigint_attr_cleanup(OBJ_DOM_DH942_SUBPRIME(
1196 object_p));
1197 break;
1198 }
1199
1200 /* Release Domain Parameters Object struct. */
1201 free(OBJ_DOM(object_p));
1202 OBJ_DOM(object_p) = NULL;
1203 }
1204 break;
1205 }
1206 }
1207
1208
1209 /*
1210 * Parse the common attributes. Return to caller with appropriate return
1211 * value to indicate if the supplied template specifies a valid attribute
1212 * with a valid value.
1213 */
1214 CK_RV
soft_parse_common_attrs(CK_ATTRIBUTE_PTR template,uchar_t * object_type)1215 soft_parse_common_attrs(CK_ATTRIBUTE_PTR template, uchar_t *object_type)
1216 {
1217
1218 CK_RV rv = CKR_OK;
1219
1220 switch (template->type) {
1221 case CKA_CLASS:
1222 break;
1223
1224 /* default boolean attributes */
1225 case CKA_TOKEN:
1226 if ((*(CK_BBOOL *)template->pValue) == B_TRUE) {
1227 if (!soft_keystore_status(KEYSTORE_INITIALIZED))
1228 return (CKR_DEVICE_REMOVED);
1229 *object_type |= TOKEN_OBJECT;
1230 }
1231 break;
1232
1233 case CKA_PRIVATE:
1234 if ((*(CK_BBOOL *)template->pValue) == B_TRUE) {
1235 (void) pthread_mutex_lock(&soft_giant_mutex);
1236 if (!soft_slot.authenticated) {
1237 /*
1238 * Check if this is the special case when
1239 * the PIN is never initialized in the keystore.
1240 * If true, we will let it pass here and let
1241 * it fail with CKR_PIN_EXPIRED later on.
1242 */
1243 if (!soft_slot.userpin_change_needed) {
1244 (void) pthread_mutex_unlock(
1245 &soft_giant_mutex);
1246 return (CKR_USER_NOT_LOGGED_IN);
1247 }
1248 }
1249 (void) pthread_mutex_unlock(&soft_giant_mutex);
1250 *object_type |= PRIVATE_OBJECT;
1251 }
1252 break;
1253
1254 case CKA_LABEL:
1255 break;
1256
1257 default:
1258 rv = CKR_TEMPLATE_INCONSISTENT;
1259 }
1260
1261 return (rv);
1262 }
1263
1264
1265 /*
1266 * Build a Public Key Object.
1267 *
1268 * - Parse the object's template, and when an error is detected such as
1269 * invalid attribute type, invalid attribute value, etc., return
1270 * with appropriate return value.
1271 * - Set up attribute mask field in the object for the supplied common
1272 * attributes that have boolean type.
1273 * - Build the attribute_info struct to hold the value of each supplied
1274 * attribute that has byte array type. Link attribute_info structs
1275 * together to form the extra attribute list of the object.
1276 * - Allocate storage for the Public Key object.
1277 * - Build the Public Key object according to the key type. Allocate
1278 * storage to hold the big integer value for the supplied attributes
1279 * that are required for a certain key type.
1280 *
1281 */
1282 CK_RV
soft_build_public_key_object(CK_ATTRIBUTE_PTR template,CK_ULONG ulAttrNum,soft_object_t * new_object,CK_ULONG mode,CK_KEY_TYPE key_type)1283 soft_build_public_key_object(CK_ATTRIBUTE_PTR template, CK_ULONG ulAttrNum,
1284 soft_object_t *new_object, CK_ULONG mode, CK_KEY_TYPE key_type)
1285 {
1286
1287 ulong_t i;
1288 CK_KEY_TYPE keytype = (CK_KEY_TYPE)~0UL;
1289 uint64_t attr_mask = PUBLIC_KEY_DEFAULT;
1290 CK_RV rv = CKR_OK;
1291 int isLabel = 0;
1292 /* Must set flags */
1293 int isModulus = 0;
1294 int isPubExpo = 0;
1295 int isPrime = 0;
1296 int isSubprime = 0;
1297 int isBase = 0;
1298 int isValue = 0;
1299 int isECParam = 0;
1300 int isECPoint = 0;
1301 /* Must not set flags */
1302 int isModulusBits = 0;
1303 CK_ULONG modulus_bits = 0;
1304
1305 biginteger_t modulus;
1306 biginteger_t pubexpo;
1307 biginteger_t prime;
1308 biginteger_t subprime;
1309 biginteger_t base;
1310 biginteger_t value;
1311 biginteger_t point;
1312 CK_ATTRIBUTE string_tmp;
1313 CK_ATTRIBUTE param_tmp;
1314
1315 public_key_obj_t *pbk;
1316 uchar_t object_type = 0;
1317
1318 CK_ATTRIBUTE defpubexpo = { CKA_PUBLIC_EXPONENT,
1319 (CK_BYTE_PTR)DEFAULT_PUB_EXPO, DEFAULT_PUB_EXPO_Len };
1320
1321 BIGNUM n;
1322
1323 /* prevent bigint_attr_cleanup from freeing invalid attr value */
1324 (void) memset(&modulus, 0x0, sizeof (biginteger_t));
1325 (void) memset(&pubexpo, 0x0, sizeof (biginteger_t));
1326 (void) memset(&prime, 0x0, sizeof (biginteger_t));
1327 (void) memset(&subprime, 0x0, sizeof (biginteger_t));
1328 (void) memset(&base, 0x0, sizeof (biginteger_t));
1329 (void) memset(&value, 0x0, sizeof (biginteger_t));
1330 (void) memset(&point, 0x0, sizeof (biginteger_t));
1331 string_tmp.pValue = NULL;
1332 param_tmp.pValue = NULL;
1333
1334 for (i = 0; i < ulAttrNum; i++) {
1335
1336 /* Public Key Object Attributes */
1337 switch (template[i].type) {
1338
1339 /* common key attributes */
1340 case CKA_KEY_TYPE:
1341 keytype = *((CK_KEY_TYPE*)template[i].pValue);
1342 break;
1343
1344 case CKA_ID:
1345 case CKA_START_DATE:
1346 case CKA_END_DATE:
1347
1348 /* common public key attribute */
1349 case CKA_SUBJECT:
1350 /*
1351 * Allocate storage to hold the attribute
1352 * value with byte array type, and add it to
1353 * the extra attribute list of the object.
1354 */
1355 rv = soft_add_extra_attr(&template[i],
1356 new_object);
1357 if (rv != CKR_OK) {
1358 goto fail_cleanup;
1359 }
1360 break;
1361
1362 /*
1363 * The following key related attribute types must
1364 * not be specified by C_CreateObject, C_GenerateKey(Pair).
1365 */
1366 case CKA_LOCAL:
1367 case CKA_KEY_GEN_MECHANISM:
1368 rv = CKR_TEMPLATE_INCONSISTENT;
1369 goto fail_cleanup;
1370
1371 /* Key related boolean attributes */
1372 case CKA_DERIVE:
1373 if (*(CK_BBOOL *)template[i].pValue)
1374 attr_mask |= DERIVE_BOOL_ON;
1375 break;
1376
1377 case CKA_ENCRYPT:
1378 if (*(CK_BBOOL *)template[i].pValue)
1379 attr_mask |= ENCRYPT_BOOL_ON;
1380 else
1381 attr_mask &= ~ENCRYPT_BOOL_ON;
1382 break;
1383
1384 case CKA_VERIFY:
1385 if (*(CK_BBOOL *)template[i].pValue)
1386 attr_mask |= VERIFY_BOOL_ON;
1387 else
1388 attr_mask &= ~VERIFY_BOOL_ON;
1389 break;
1390
1391 case CKA_VERIFY_RECOVER:
1392 if (*(CK_BBOOL *)template[i].pValue)
1393 attr_mask |= VERIFY_RECOVER_BOOL_ON;
1394 else
1395 attr_mask &= ~VERIFY_RECOVER_BOOL_ON;
1396 break;
1397
1398 case CKA_WRAP:
1399 if (*(CK_BBOOL *)template[i].pValue)
1400 attr_mask |= WRAP_BOOL_ON;
1401 else
1402 attr_mask &= ~WRAP_BOOL_ON;
1403 break;
1404
1405 case CKA_TRUSTED:
1406 if (*(CK_BBOOL *)template[i].pValue)
1407 attr_mask |= TRUSTED_BOOL_ON;
1408 break;
1409
1410 case CKA_MODIFIABLE:
1411 if ((*(CK_BBOOL *)template[i].pValue) == B_FALSE)
1412 attr_mask |= NOT_MODIFIABLE_BOOL_ON;
1413 break;
1414
1415 /*
1416 * The following key related attribute types must
1417 * be specified according to the key type by
1418 * C_CreateObject.
1419 */
1420 case CKA_MODULUS:
1421
1422 isModulus = 1;
1423 /*
1424 * Copyin big integer attribute from template
1425 * to a local variable.
1426 */
1427 rv = get_bigint_attr_from_template(&modulus,
1428 &template[i]);
1429 if (rv != CKR_OK)
1430 goto fail_cleanup;
1431
1432 /*
1433 * Modulus length needs to be between min key length and
1434 * max key length.
1435 */
1436 if ((modulus.big_value_len <
1437 MIN_RSA_KEYLENGTH_IN_BYTES) ||
1438 (modulus.big_value_len >
1439 MAX_RSA_KEYLENGTH_IN_BYTES)) {
1440 rv = CKR_ATTRIBUTE_VALUE_INVALID;
1441 goto fail_cleanup;
1442 }
1443 break;
1444
1445 case CKA_PUBLIC_EXPONENT:
1446 isPubExpo = 1;
1447 rv = get_bigint_attr_from_template(&pubexpo,
1448 &template[i]);
1449 if (rv != CKR_OK)
1450 goto fail_cleanup;
1451 break;
1452
1453 case CKA_PRIME:
1454 isPrime = 1;
1455 rv = get_bigint_attr_from_template(&prime,
1456 &template[i]);
1457 if (rv != CKR_OK)
1458 goto fail_cleanup;
1459 break;
1460
1461 case CKA_SUBPRIME:
1462 isSubprime = 1;
1463 rv = get_bigint_attr_from_template(&subprime,
1464 &template[i]);
1465 if (rv != CKR_OK)
1466 goto fail_cleanup;
1467 break;
1468
1469 case CKA_BASE:
1470 isBase = 1;
1471 rv = get_bigint_attr_from_template(&base,
1472 &template[i]);
1473 if (rv != CKR_OK)
1474 goto fail_cleanup;
1475 break;
1476
1477 case CKA_VALUE:
1478 isValue = 1;
1479 if (mode == SOFT_CREATE_OBJ) {
1480 if ((template[i].ulValueLen == 0) ||
1481 (template[i].pValue == NULL)) {
1482 rv = CKR_ATTRIBUTE_VALUE_INVALID;
1483 goto fail_cleanup;
1484 }
1485 }
1486
1487 rv = get_bigint_attr_from_template(&value,
1488 &template[i]);
1489 if (rv != CKR_OK)
1490 goto fail_cleanup;
1491 break;
1492
1493 case CKA_MODULUS_BITS:
1494 isModulusBits = 1;
1495 rv = get_ulong_attr_from_template(&modulus_bits,
1496 &template[i]);
1497 if (rv != CKR_OK)
1498 goto fail_cleanup;
1499 break;
1500
1501 case CKA_LABEL:
1502 isLabel = 1;
1503 rv = get_string_from_template(&string_tmp,
1504 &template[i]);
1505 if (rv != CKR_OK)
1506 goto fail_cleanup;
1507 break;
1508
1509 case CKA_EC_PARAMS:
1510 isECParam = 1;
1511 rv = get_string_from_template(¶m_tmp, &template[i]);
1512 if (rv != CKR_OK)
1513 goto fail_cleanup;
1514 break;
1515
1516 case CKA_EC_POINT:
1517 isECPoint = 1;
1518 rv = get_bigint_attr_from_template(&point,
1519 &template[i]);
1520 if (rv != CKR_OK)
1521 goto fail_cleanup;
1522 break;
1523
1524 default:
1525 rv = soft_parse_common_attrs(&template[i],
1526 &object_type);
1527 if (rv != CKR_OK)
1528 goto fail_cleanup;
1529 break;
1530 }
1531 } /* For */
1532
1533 /* Allocate storage for Public Key Object. */
1534 pbk = calloc(1, sizeof (public_key_obj_t));
1535 if (pbk == NULL) {
1536 rv = CKR_HOST_MEMORY;
1537 goto fail_cleanup;
1538 }
1539
1540 new_object->object_class_u.public_key = pbk;
1541 new_object->class = CKO_PUBLIC_KEY;
1542
1543 if ((mode == SOFT_CREATE_OBJ) && (keytype == (CK_KEY_TYPE)~0UL)) {
1544 rv = CKR_TEMPLATE_INCOMPLETE;
1545 goto fail_cleanup;
1546 }
1547
1548 if ((mode == SOFT_GEN_KEY) && (keytype == (CK_KEY_TYPE)~0UL)) {
1549 keytype = key_type;
1550 }
1551
1552 if ((mode == SOFT_GEN_KEY) && (keytype != key_type)) {
1553 /*
1554 * The key type specified in the template does not
1555 * match the implied key type based on the mechanism.
1556 */
1557 rv = CKR_TEMPLATE_INCONSISTENT;
1558 goto fail_cleanup;
1559 }
1560
1561 new_object->key_type = keytype;
1562
1563 /* Supported key types of the Public Key Object */
1564 switch (keytype) {
1565
1566 case CKK_RSA:
1567 if (mode == SOFT_CREATE_OBJ) {
1568 if (isModulusBits || isPrime || isSubprime ||
1569 isBase || isValue) {
1570 rv = CKR_TEMPLATE_INCONSISTENT;
1571 goto fail_cleanup;
1572 }
1573
1574 if (isModulus && isPubExpo) {
1575 /*
1576 * Derive modulus_bits attribute from modulus.
1577 * Save modulus_bits integer value to the
1578 * designated place in the public key object.
1579 */
1580 n.malloced = 0;
1581 #ifdef __sparcv9
1582 if (big_init(&n, (int)CHARLEN2BIGNUMLEN(
1583 modulus.big_value_len)) != BIG_OK) {
1584 #else /* !__sparcv9 */
1585 if (big_init(&n, CHARLEN2BIGNUMLEN(
1586 modulus.big_value_len)) != BIG_OK) {
1587 #endif /* __sparcv9 */
1588 rv = CKR_HOST_MEMORY;
1589 big_finish(&n);
1590 goto fail_cleanup;
1591 }
1592 bytestring2bignum(&n, modulus.big_value,
1593 modulus.big_value_len);
1594
1595 modulus_bits = big_bitlength(&n);
1596 KEY_PUB_RSA_MOD_BITS(pbk) = modulus_bits;
1597 big_finish(&n);
1598
1599 /*
1600 * After modulus_bits has been computed,
1601 * it is safe to move modulus and pubexpo
1602 * big integer attribute value to the
1603 * designated place in the public key object.
1604 */
1605 copy_bigint_attr(&modulus,
1606 KEY_PUB_RSA_MOD(pbk));
1607
1608 copy_bigint_attr(&pubexpo,
1609 KEY_PUB_RSA_PUBEXPO(pbk));
1610 } else {
1611 rv = CKR_TEMPLATE_INCOMPLETE;
1612 goto fail_cleanup;
1613 }
1614 } else {
1615 /* mode is SOFT_GEN_KEY */
1616
1617 if (isModulus || isPrime || isSubprime ||
1618 isBase || isValue) {
1619 rv = CKR_TEMPLATE_INCONSISTENT;
1620 goto fail_cleanup;
1621 }
1622
1623
1624 if (isModulusBits) {
1625 /*
1626 * Copy big integer attribute value to the
1627 * designated place in the public key object.
1628 */
1629 KEY_PUB_RSA_MOD_BITS(pbk) = modulus_bits;
1630 } else {
1631 rv = CKR_TEMPLATE_INCOMPLETE;
1632 goto fail_cleanup;
1633 }
1634
1635 /*
1636 * Use PKCS#11 default 0x010001 for public exponent
1637 * if not not specified in attribute template.
1638 */
1639 if (!isPubExpo) {
1640 isPubExpo = 1;
1641 rv = get_bigint_attr_from_template(&pubexpo,
1642 &defpubexpo);
1643 if (rv != CKR_OK)
1644 goto fail_cleanup;
1645 }
1646 /*
1647 * Copy big integer attribute value to the
1648 * designated place in the public key object.
1649 */
1650 copy_bigint_attr(&pubexpo, KEY_PUB_RSA_PUBEXPO(pbk));
1651 }
1652
1653 break;
1654
1655 case CKK_DSA:
1656 if (mode == SOFT_CREATE_OBJ) {
1657 if (isModulusBits || isModulus || isPubExpo) {
1658 rv = CKR_TEMPLATE_INCONSISTENT;
1659 goto fail_cleanup;
1660 }
1661
1662 if (isPrime && isSubprime && isBase && isValue) {
1663 copy_bigint_attr(&value,
1664 KEY_PUB_DSA_VALUE(pbk));
1665 } else {
1666 rv = CKR_TEMPLATE_INCOMPLETE;
1667 goto fail_cleanup;
1668 }
1669 } else {
1670 if (isModulusBits || isModulus || isPubExpo ||
1671 isValue) {
1672 rv = CKR_TEMPLATE_INCONSISTENT;
1673 goto fail_cleanup;
1674 }
1675
1676 if (!(isPrime && isSubprime && isBase)) {
1677 rv = CKR_TEMPLATE_INCOMPLETE;
1678 goto fail_cleanup;
1679 }
1680 }
1681
1682 copy_bigint_attr(&prime, KEY_PUB_DSA_PRIME(pbk));
1683
1684 copy_bigint_attr(&subprime, KEY_PUB_DSA_SUBPRIME(pbk));
1685
1686 copy_bigint_attr(&base, KEY_PUB_DSA_BASE(pbk));
1687
1688 break;
1689
1690 case CKK_DH:
1691 if (mode == SOFT_CREATE_OBJ) {
1692 if (isModulusBits || isModulus || isPubExpo ||
1693 isSubprime) {
1694 rv = CKR_TEMPLATE_INCONSISTENT;
1695 goto fail_cleanup;
1696 }
1697
1698 if (isPrime && isBase && isValue) {
1699 copy_bigint_attr(&value,
1700 KEY_PUB_DH_VALUE(pbk));
1701 } else {
1702 rv = CKR_TEMPLATE_INCOMPLETE;
1703 goto fail_cleanup;
1704 }
1705 } else {
1706 if (isModulusBits || isModulus || isPubExpo ||
1707 isSubprime || isValue) {
1708 rv = CKR_TEMPLATE_INCONSISTENT;
1709 goto fail_cleanup;
1710 }
1711
1712 if (!(isPrime && isBase)) {
1713 rv = CKR_TEMPLATE_INCOMPLETE;
1714 goto fail_cleanup;
1715 }
1716 }
1717
1718 copy_bigint_attr(&prime, KEY_PUB_DH_PRIME(pbk));
1719
1720 copy_bigint_attr(&base, KEY_PUB_DH_BASE(pbk));
1721
1722 break;
1723
1724 case CKK_X9_42_DH:
1725 if (mode == SOFT_CREATE_OBJ) {
1726 if (isModulusBits || isModulus || isPubExpo) {
1727 rv = CKR_TEMPLATE_INCONSISTENT;
1728 goto fail_cleanup;
1729 }
1730
1731 if (isPrime && isSubprime && isBase && isValue) {
1732 copy_bigint_attr(&value,
1733 KEY_PUB_DH942_VALUE(pbk));
1734 } else {
1735 rv = CKR_TEMPLATE_INCOMPLETE;
1736 goto fail_cleanup;
1737 }
1738 } else {
1739 if (isModulusBits || isModulus || isPubExpo ||
1740 isValue) {
1741 rv = CKR_TEMPLATE_INCONSISTENT;
1742 goto fail_cleanup;
1743 }
1744
1745 if (!(isPrime && isSubprime && isBase)) {
1746 rv = CKR_TEMPLATE_INCOMPLETE;
1747 goto fail_cleanup;
1748 }
1749 }
1750
1751 copy_bigint_attr(&prime, KEY_PUB_DH942_PRIME(pbk));
1752
1753 copy_bigint_attr(&base, KEY_PUB_DH942_BASE(pbk));
1754
1755 copy_bigint_attr(&subprime, KEY_PUB_DH942_SUBPRIME(pbk));
1756
1757 break;
1758
1759 case CKK_EC:
1760 if (mode == SOFT_CREATE_OBJ) {
1761 if (isModulusBits || isModulus || isPubExpo ||
1762 isPrime || isSubprime || isBase || isValue) {
1763 rv = CKR_TEMPLATE_INCONSISTENT;
1764 goto fail_cleanup;
1765
1766 } else if (!isECParam || !isECPoint) {
1767 rv = CKR_TEMPLATE_INCOMPLETE;
1768 goto fail_cleanup;
1769 }
1770 } else {
1771 if (isModulusBits || isModulus || isPubExpo ||
1772 isPrime || isSubprime || isBase || isValue) {
1773 rv = CKR_TEMPLATE_INCONSISTENT;
1774 goto fail_cleanup;
1775
1776 } else if (!isECParam) {
1777 rv = CKR_TEMPLATE_INCOMPLETE;
1778 goto fail_cleanup;
1779 }
1780 }
1781
1782 if (isECPoint) {
1783 copy_bigint_attr(&point, KEY_PUB_EC_POINT(pbk));
1784 }
1785 rv = soft_add_extra_attr(¶m_tmp, new_object);
1786 if (rv != CKR_OK)
1787 goto fail_cleanup;
1788 string_attr_cleanup(¶m_tmp);
1789 break;
1790
1791 default:
1792 rv = CKR_TEMPLATE_INCONSISTENT;
1793 goto fail_cleanup;
1794 }
1795
1796 /* Set up object. */
1797 new_object->object_type = object_type;
1798 new_object->bool_attr_mask = attr_mask;
1799 if (isLabel) {
1800 rv = soft_add_extra_attr(&string_tmp, new_object);
1801 if (rv != CKR_OK)
1802 goto fail_cleanup;
1803 string_attr_cleanup(&string_tmp);
1804 }
1805
1806 return (rv);
1807
1808 fail_cleanup:
1809 /*
1810 * cleanup the storage allocated to the local variables.
1811 */
1812 bigint_attr_cleanup(&modulus);
1813 bigint_attr_cleanup(&pubexpo);
1814 bigint_attr_cleanup(&prime);
1815 bigint_attr_cleanup(&subprime);
1816 bigint_attr_cleanup(&base);
1817 bigint_attr_cleanup(&value);
1818 bigint_attr_cleanup(&point);
1819 string_attr_cleanup(&string_tmp);
1820 string_attr_cleanup(¶m_tmp);
1821
1822 /*
1823 * cleanup the storage allocated inside the object itself.
1824 */
1825 soft_cleanup_object(new_object);
1826
1827 return (rv);
1828 }
1829
1830
1831 /*
1832 * Build a Private Key Object.
1833 *
1834 * - Parse the object's template, and when an error is detected such as
1835 * invalid attribute type, invalid attribute value, etc., return
1836 * with appropriate return value.
1837 * - Set up attribute mask field in the object for the supplied common
1838 * attributes that have boolean type.
1839 * - Build the attribute_info struct to hold the value of each supplied
1840 * attribute that has byte array type. Link attribute_info structs
1841 * together to form the extra attribute list of the object.
1842 * - Allocate storage for the Private Key object.
1843 * - Build the Private Key object according to the key type. Allocate
1844 * storage to hold the big integer value for the supplied attributes
1845 * that are required for a certain key type.
1846 *
1847 */
1848 CK_RV
1849 soft_build_private_key_object(CK_ATTRIBUTE_PTR template, CK_ULONG ulAttrNum,
1850 soft_object_t *new_object, CK_ULONG mode, CK_KEY_TYPE key_type)
1851 {
1852 ulong_t i;
1853 CK_KEY_TYPE keytype = (CK_KEY_TYPE)~0UL;
1854 uint64_t attr_mask = PRIVATE_KEY_DEFAULT;
1855 CK_RV rv = CKR_OK;
1856 int isLabel = 0;
1857 int isECParam = 0;
1858 /* Must set flags unless mode == SOFT_UNWRAP_KEY */
1859 int isModulus = 0;
1860 int isPriExpo = 0;
1861 int isPrime = 0;
1862 int isSubprime = 0;
1863 int isBase = 0;
1864 /* Must set flags if mode == SOFT_GEN_KEY */
1865 int isValue = 0;
1866 /* Must not set flags */
1867 int isValueBits = 0;
1868 CK_ULONG value_bits = 0;
1869
1870 /* Private Key RSA optional */
1871 int isPubExpo = 0;
1872 int isPrime1 = 0;
1873 int isPrime2 = 0;
1874 int isExpo1 = 0;
1875 int isExpo2 = 0;
1876 int isCoef = 0;
1877
1878 biginteger_t modulus;
1879 biginteger_t priexpo;
1880 biginteger_t prime;
1881 biginteger_t subprime;
1882 biginteger_t base;
1883 biginteger_t value;
1884
1885 biginteger_t pubexpo;
1886 biginteger_t prime1;
1887 biginteger_t prime2;
1888 biginteger_t expo1;
1889 biginteger_t expo2;
1890 biginteger_t coef;
1891 CK_ATTRIBUTE string_tmp;
1892 CK_ATTRIBUTE param_tmp;
1893 BIGNUM x, q;
1894
1895 private_key_obj_t *pvk;
1896 uchar_t object_type = 0;
1897
1898 /* prevent bigint_attr_cleanup from freeing invalid attr value */
1899 (void) memset(&modulus, 0x0, sizeof (biginteger_t));
1900 (void) memset(&priexpo, 0x0, sizeof (biginteger_t));
1901 (void) memset(&prime, 0x0, sizeof (biginteger_t));
1902 (void) memset(&subprime, 0x0, sizeof (biginteger_t));
1903 (void) memset(&base, 0x0, sizeof (biginteger_t));
1904 (void) memset(&value, 0x0, sizeof (biginteger_t));
1905 (void) memset(&pubexpo, 0x0, sizeof (biginteger_t));
1906 (void) memset(&prime1, 0x0, sizeof (biginteger_t));
1907 (void) memset(&prime2, 0x0, sizeof (biginteger_t));
1908 (void) memset(&expo1, 0x0, sizeof (biginteger_t));
1909 (void) memset(&expo2, 0x0, sizeof (biginteger_t));
1910 (void) memset(&coef, 0x0, sizeof (biginteger_t));
1911 string_tmp.pValue = NULL;
1912 param_tmp.pValue = NULL;
1913 x.malloced = 0;
1914 q.malloced = 0;
1915
1916 for (i = 0; i < ulAttrNum; i++) {
1917
1918 /* Private Key Object Attributes */
1919 switch (template[i].type) {
1920 /* common key attributes */
1921 case CKA_KEY_TYPE:
1922 keytype = *((CK_KEY_TYPE*)template[i].pValue);
1923 break;
1924
1925 case CKA_ID:
1926 case CKA_START_DATE:
1927 case CKA_END_DATE:
1928
1929 /* common private key attribute */
1930 case CKA_SUBJECT:
1931 /*
1932 * Allocate storage to hold the attribute
1933 * value with byte array type, and add it to
1934 * the extra attribute list of the object.
1935 */
1936 rv = soft_add_extra_attr(&template[i],
1937 new_object);
1938 if (rv != CKR_OK) {
1939 goto fail_cleanup;
1940 }
1941 break;
1942
1943 /*
1944 * The following key related attribute types must
1945 * not be specified by C_CreateObject or C_GenerateKey(Pair).
1946 */
1947 case CKA_LOCAL:
1948 case CKA_KEY_GEN_MECHANISM:
1949 case CKA_AUTH_PIN_FLAGS:
1950 case CKA_ALWAYS_SENSITIVE:
1951 case CKA_NEVER_EXTRACTABLE:
1952 rv = CKR_TEMPLATE_INCONSISTENT;
1953 goto fail_cleanup;
1954
1955 /* Key related boolean attributes */
1956 case CKA_DERIVE:
1957 if (*(CK_BBOOL *)template[i].pValue)
1958 attr_mask |= DERIVE_BOOL_ON;
1959 break;
1960
1961 case CKA_SENSITIVE:
1962 if (*(CK_BBOOL *)template[i].pValue)
1963 attr_mask |= SENSITIVE_BOOL_ON;
1964 break;
1965
1966 case CKA_SECONDARY_AUTH:
1967 if (*(CK_BBOOL *)template[i].pValue) {
1968 rv = CKR_ATTRIBUTE_VALUE_INVALID;
1969 goto fail_cleanup;
1970 }
1971 break;
1972
1973 case CKA_DECRYPT:
1974 if (*(CK_BBOOL *)template[i].pValue)
1975 attr_mask |= DECRYPT_BOOL_ON;
1976 else
1977 attr_mask &= ~DECRYPT_BOOL_ON;
1978 break;
1979
1980 case CKA_SIGN:
1981 if (*(CK_BBOOL *)template[i].pValue)
1982 attr_mask |= SIGN_BOOL_ON;
1983 else
1984 attr_mask &= ~SIGN_BOOL_ON;
1985 break;
1986
1987 case CKA_SIGN_RECOVER:
1988 if (*(CK_BBOOL *)template[i].pValue)
1989 attr_mask |= SIGN_RECOVER_BOOL_ON;
1990 else
1991 attr_mask &= ~SIGN_RECOVER_BOOL_ON;
1992 break;
1993
1994 case CKA_UNWRAP:
1995 if (*(CK_BBOOL *)template[i].pValue)
1996 attr_mask |= UNWRAP_BOOL_ON;
1997 else
1998 attr_mask &= ~UNWRAP_BOOL_ON;
1999 break;
2000
2001 case CKA_EXTRACTABLE:
2002 if (*(CK_BBOOL *)template[i].pValue)
2003 attr_mask |= EXTRACTABLE_BOOL_ON;
2004 else
2005 attr_mask &= ~EXTRACTABLE_BOOL_ON;
2006 break;
2007
2008 case CKA_MODIFIABLE:
2009 if ((*(CK_BBOOL *)template[i].pValue) == B_FALSE)
2010 attr_mask |= NOT_MODIFIABLE_BOOL_ON;
2011 break;
2012
2013 /*
2014 * The following key related attribute types must
2015 * be specified according to the key type by
2016 * C_CreateObject.
2017 */
2018 case CKA_MODULUS:
2019
2020 isModulus = 1;
2021 /*
2022 * Copyin big integer attribute from template
2023 * to a local variable.
2024 */
2025 rv = get_bigint_attr_from_template(&modulus,
2026 &template[i]);
2027 if (rv != CKR_OK)
2028 goto fail_cleanup;
2029
2030 /*
2031 * Modulus length needs to be between min key length and
2032 * max key length.
2033 */
2034 if ((modulus.big_value_len <
2035 MIN_RSA_KEYLENGTH_IN_BYTES) ||
2036 (modulus.big_value_len >
2037 MAX_RSA_KEYLENGTH_IN_BYTES)) {
2038 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2039 goto fail_cleanup;
2040 }
2041 break;
2042
2043 case CKA_PUBLIC_EXPONENT:
2044
2045 isPubExpo = 1;
2046 rv = get_bigint_attr_from_template(&pubexpo,
2047 &template[i]);
2048 if (rv != CKR_OK)
2049 goto fail_cleanup;
2050 break;
2051
2052 case CKA_PRIVATE_EXPONENT:
2053
2054 isPriExpo = 1;
2055 rv = get_bigint_attr_from_template(&priexpo,
2056 &template[i]);
2057 if (rv != CKR_OK)
2058 goto fail_cleanup;
2059 break;
2060
2061 case CKA_PRIME_1:
2062 isPrime1 = 1;
2063 rv = get_bigint_attr_from_template(&prime1,
2064 &template[i]);
2065 if (rv != CKR_OK)
2066 goto fail_cleanup;
2067 break;
2068
2069 case CKA_PRIME_2:
2070 isPrime2 = 1;
2071 rv = get_bigint_attr_from_template(&prime2,
2072 &template[i]);
2073 if (rv != CKR_OK)
2074 goto fail_cleanup;
2075 break;
2076
2077 case CKA_EXPONENT_1:
2078 isExpo1 = 1;
2079 rv = get_bigint_attr_from_template(&expo1,
2080 &template[i]);
2081 if (rv != CKR_OK)
2082 goto fail_cleanup;
2083 break;
2084
2085 case CKA_EXPONENT_2:
2086 isExpo2 = 1;
2087 rv = get_bigint_attr_from_template(&expo2,
2088 &template[i]);
2089 if (rv != CKR_OK)
2090 goto fail_cleanup;
2091 break;
2092
2093 case CKA_COEFFICIENT:
2094 isCoef = 1;
2095 rv = get_bigint_attr_from_template(&coef,
2096 &template[i]);
2097 if (rv != CKR_OK)
2098 goto fail_cleanup;
2099 break;
2100
2101 case CKA_PRIME:
2102 isPrime = 1;
2103 rv = get_bigint_attr_from_template(&prime,
2104 &template[i]);
2105 if (rv != CKR_OK)
2106 goto fail_cleanup;
2107 break;
2108
2109 case CKA_SUBPRIME:
2110 isSubprime = 1;
2111 rv = get_bigint_attr_from_template(&subprime,
2112 &template[i]);
2113 if (rv != CKR_OK)
2114 goto fail_cleanup;
2115 break;
2116
2117 case CKA_BASE:
2118 isBase = 1;
2119 rv = get_bigint_attr_from_template(&base,
2120 &template[i]);
2121 if (rv != CKR_OK)
2122 goto fail_cleanup;
2123 break;
2124
2125 case CKA_VALUE:
2126 isValue = 1;
2127 if (mode == SOFT_CREATE_OBJ) {
2128 if ((template[i].ulValueLen == 0) ||
2129 (template[i].pValue == NULL)) {
2130 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2131 goto fail_cleanup;
2132 }
2133 }
2134
2135 rv = get_bigint_attr_from_template(&value,
2136 &template[i]);
2137 if (rv != CKR_OK)
2138 goto fail_cleanup;
2139 break;
2140
2141 case CKA_VALUE_BITS:
2142 isValueBits = 1;
2143 rv = get_ulong_attr_from_template(&value_bits,
2144 &template[i]);
2145 if (rv != CKR_OK)
2146 goto fail_cleanup;
2147 break;
2148
2149 case CKA_LABEL:
2150 isLabel = 1;
2151 rv = get_string_from_template(&string_tmp,
2152 &template[i]);
2153 if (rv != CKR_OK)
2154 goto fail_cleanup;
2155 break;
2156
2157 case CKA_EC_PARAMS:
2158 isECParam = 1;
2159 rv = get_string_from_template(¶m_tmp,
2160 &template[i]);
2161 if (rv != CKR_OK)
2162 goto fail_cleanup;
2163 break;
2164
2165 default:
2166 rv = soft_parse_common_attrs(&template[i],
2167 &object_type);
2168 if (rv != CKR_OK)
2169 goto fail_cleanup;
2170 break;
2171
2172 }
2173 } /* For */
2174
2175 /* Allocate storage for Private Key Object. */
2176 pvk = calloc(1, sizeof (private_key_obj_t));
2177 if (pvk == NULL) {
2178 rv = CKR_HOST_MEMORY;
2179 goto fail_cleanup;
2180 }
2181
2182 new_object->object_class_u.private_key = pvk;
2183 new_object->class = CKO_PRIVATE_KEY;
2184
2185 if ((mode == SOFT_CREATE_OBJ) && (keytype == (CK_KEY_TYPE)~0UL)) {
2186 rv = CKR_TEMPLATE_INCOMPLETE;
2187 goto fail_cleanup;
2188 }
2189
2190 if (mode == SOFT_GEN_KEY) {
2191 /*
2192 * The key type is not specified in the application's
2193 * template, so we use the implied key type based on
2194 * the mechanism.
2195 */
2196 if (keytype == (CK_KEY_TYPE)~0UL) {
2197 keytype = key_type;
2198 }
2199
2200 /* If still unspecified, template is incomplete */
2201 if (keytype == (CK_KEY_TYPE)~0UL) {
2202 rv = CKR_TEMPLATE_INCOMPLETE;
2203 goto fail_cleanup;
2204 }
2205
2206 /*
2207 * The key type specified in the template does not
2208 * match the implied key type based on the mechanism.
2209 */
2210 if (keytype != key_type) {
2211 rv = CKR_TEMPLATE_INCONSISTENT;
2212 goto fail_cleanup;
2213 }
2214 }
2215
2216 if (mode == SOFT_UNWRAP_KEY) {
2217 /*
2218 * Note that, for mode SOFT_UNWRAP_KEY, key type is not
2219 * implied by the mechanism (key_type), so if it is not
2220 * specified from the attribute template (keytype), it is
2221 * incomplete.
2222 */
2223 if (keytype == (CK_KEY_TYPE)~0UL) {
2224 rv = CKR_TEMPLATE_INCOMPLETE;
2225 goto fail_cleanup;
2226 }
2227 }
2228
2229 new_object->key_type = keytype;
2230
2231 /* Supported key types of the Private Key Object */
2232 switch (keytype) {
2233 case CKK_RSA:
2234 if (isPrime || isSubprime || isBase || isValue ||
2235 isValueBits) {
2236 rv = CKR_TEMPLATE_INCONSISTENT;
2237 goto fail_cleanup;
2238 }
2239
2240 if (mode == SOFT_GEN_KEY || mode == SOFT_UNWRAP_KEY) {
2241 if (isModulus || isPubExpo || isPriExpo || isPrime1 ||
2242 isPrime2 || isExpo1 || isExpo2 || isCoef) {
2243 rv = CKR_TEMPLATE_INCONSISTENT;
2244 goto fail_cleanup;
2245 } else
2246 break;
2247 }
2248
2249 if (isModulus && isPriExpo) {
2250 /*
2251 * Copy big integer attribute value to the
2252 * designated place in the Private Key object.
2253 */
2254 copy_bigint_attr(&modulus, KEY_PRI_RSA_MOD(pvk));
2255
2256 copy_bigint_attr(&priexpo, KEY_PRI_RSA_PRIEXPO(pvk));
2257 } else {
2258 rv = CKR_TEMPLATE_INCOMPLETE;
2259 goto fail_cleanup;
2260 }
2261
2262 /* The following attributes are optional. */
2263 if (isPubExpo) {
2264 copy_bigint_attr(&pubexpo, KEY_PRI_RSA_PUBEXPO(pvk));
2265 }
2266
2267 if (isPrime1) {
2268 copy_bigint_attr(&prime1, KEY_PRI_RSA_PRIME1(pvk));
2269 }
2270
2271 if (isPrime2) {
2272 copy_bigint_attr(&prime2, KEY_PRI_RSA_PRIME2(pvk));
2273 }
2274
2275 if (isExpo1) {
2276 copy_bigint_attr(&expo1, KEY_PRI_RSA_EXPO1(pvk));
2277 }
2278
2279 if (isExpo2) {
2280 copy_bigint_attr(&expo2, KEY_PRI_RSA_EXPO2(pvk));
2281 }
2282
2283 if (isCoef) {
2284 copy_bigint_attr(&coef, KEY_PRI_RSA_COEF(pvk));
2285 }
2286 break;
2287
2288 case CKK_DSA:
2289 if (isModulus || isPubExpo || isPriExpo || isPrime1 ||
2290 isPrime2 || isExpo1 || isExpo2 || isCoef ||
2291 isValueBits) {
2292 rv = CKR_TEMPLATE_INCONSISTENT;
2293 goto fail_cleanup;
2294 }
2295
2296 if (mode == SOFT_GEN_KEY || mode == SOFT_UNWRAP_KEY) {
2297 if (isPrime || isSubprime || isBase || isValue) {
2298 rv = CKR_TEMPLATE_INCONSISTENT;
2299 goto fail_cleanup;
2300 } else
2301 break;
2302 }
2303
2304 if (isPrime && isSubprime && isBase && isValue) {
2305 /*
2306 * The private value x must be less than subprime q.
2307 * Size for big_init is in BIG_CHUNK_TYPE words.
2308 */
2309 #ifdef __sparcv9
2310 if (big_init(&x,
2311 (int)CHARLEN2BIGNUMLEN(value.big_value_len))
2312 != BIG_OK) {
2313 #else /* !__sparcv9 */
2314 if (big_init(&x,
2315 CHARLEN2BIGNUMLEN(value.big_value_len))
2316 != BIG_OK) {
2317 #endif /* __sparcv9 */
2318 rv = CKR_HOST_MEMORY;
2319 goto fail_cleanup;
2320 }
2321 #ifdef __sparcv9
2322 if (big_init(&q,
2323 (int)CHARLEN2BIGNUMLEN(subprime.big_value_len))
2324 != BIG_OK) {
2325 #else /* !__sparcv9 */
2326 if (big_init(&q,
2327 CHARLEN2BIGNUMLEN(subprime.big_value_len))
2328 != BIG_OK) {
2329 #endif /* __sparcv9 */
2330 rv = CKR_HOST_MEMORY;
2331 goto fail_cleanup;
2332 }
2333 bytestring2bignum(&x, value.big_value,
2334 value.big_value_len);
2335 bytestring2bignum(&q, subprime.big_value,
2336 subprime.big_value_len);
2337
2338 if (big_cmp_abs(&x, &q) > 0) {
2339 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2340 goto fail_cleanup;
2341 }
2342
2343 copy_bigint_attr(&prime, KEY_PRI_DSA_PRIME(pvk));
2344
2345 copy_bigint_attr(&subprime, KEY_PRI_DSA_SUBPRIME(pvk));
2346
2347 copy_bigint_attr(&base, KEY_PRI_DSA_BASE(pvk));
2348
2349 copy_bigint_attr(&value, KEY_PRI_DSA_VALUE(pvk));
2350 } else {
2351 rv = CKR_TEMPLATE_INCOMPLETE;
2352 goto fail_cleanup;
2353 }
2354 break;
2355
2356 case CKK_DH:
2357 if (isModulus || isPubExpo || isPriExpo || isPrime1 ||
2358 isPrime2 || isExpo1 || isExpo2 || isCoef ||
2359 isSubprime) {
2360 rv = CKR_TEMPLATE_INCONSISTENT;
2361 goto fail_cleanup;
2362 }
2363
2364 /* CKA_VALUE_BITS is for key gen but not unwrap */
2365 if (mode == SOFT_GEN_KEY)
2366 KEY_PRI_DH_VAL_BITS(pvk) = (isValueBits) ?
2367 value_bits : 0;
2368 else if (mode == SOFT_UNWRAP_KEY) {
2369 if (isValueBits) {
2370 rv = CKR_TEMPLATE_INCONSISTENT;
2371 goto fail_cleanup;
2372 }
2373 }
2374
2375 if (mode == SOFT_GEN_KEY || mode == SOFT_UNWRAP_KEY) {
2376 if (isPrime || isBase || isValue) {
2377 rv = CKR_TEMPLATE_INCONSISTENT;
2378 goto fail_cleanup;
2379 } else
2380 break;
2381 }
2382
2383 if (isValueBits) {
2384 rv = CKR_TEMPLATE_INCONSISTENT;
2385 goto fail_cleanup;
2386 }
2387
2388 if (isPrime && isBase && isValue) {
2389 copy_bigint_attr(&prime, KEY_PRI_DH_PRIME(pvk));
2390
2391 copy_bigint_attr(&base, KEY_PRI_DH_BASE(pvk));
2392
2393 copy_bigint_attr(&value, KEY_PRI_DH_VALUE(pvk));
2394 } else {
2395 rv = CKR_TEMPLATE_INCOMPLETE;
2396 goto fail_cleanup;
2397 }
2398 break;
2399
2400 case CKK_X9_42_DH:
2401 if (isModulus || isPubExpo || isPriExpo || isPrime1 ||
2402 isPrime2 || isExpo1 || isExpo2 || isCoef ||
2403 isValueBits) {
2404 rv = CKR_TEMPLATE_INCONSISTENT;
2405 goto fail_cleanup;
2406 }
2407
2408 if (mode == SOFT_GEN_KEY || mode == SOFT_UNWRAP_KEY) {
2409 if (isPrime || isSubprime || isBase || isValue) {
2410 rv = CKR_TEMPLATE_INCONSISTENT;
2411 goto fail_cleanup;
2412 } else
2413 break;
2414 }
2415
2416 if (isPrime && isSubprime && isBase && isValue) {
2417 copy_bigint_attr(&prime, KEY_PRI_DH942_PRIME(pvk));
2418
2419 copy_bigint_attr(&base, KEY_PRI_DH942_BASE(pvk));
2420
2421 copy_bigint_attr(&subprime,
2422 KEY_PRI_DH942_SUBPRIME(pvk));
2423
2424 copy_bigint_attr(&value, KEY_PRI_DH942_VALUE(pvk));
2425 } else {
2426 rv = CKR_TEMPLATE_INCOMPLETE;
2427 goto fail_cleanup;
2428 }
2429 break;
2430
2431 case CKK_EC:
2432 if (isModulus || isPubExpo || isPrime ||
2433 isPrime1 || isPrime2 || isExpo1 || isExpo2 || isCoef ||
2434 isValueBits || isBase) {
2435 rv = CKR_TEMPLATE_INCONSISTENT;
2436 goto fail_cleanup;
2437
2438 } else if (isECParam) {
2439 rv = soft_add_extra_attr(¶m_tmp, new_object);
2440 if (rv != CKR_OK)
2441 goto fail_cleanup;
2442 string_attr_cleanup(¶m_tmp);
2443 }
2444 if (isValue) {
2445 copy_bigint_attr(&value, KEY_PRI_EC_VALUE(pvk));
2446 }
2447 break;
2448
2449 default:
2450 rv = CKR_TEMPLATE_INCONSISTENT;
2451 goto fail_cleanup;
2452 }
2453
2454 /* Set up object. */
2455 new_object->object_type = object_type;
2456 new_object->bool_attr_mask = attr_mask;
2457 if (isLabel) {
2458 rv = soft_add_extra_attr(&string_tmp, new_object);
2459 if (rv != CKR_OK)
2460 goto fail_cleanup;
2461 string_attr_cleanup(&string_tmp);
2462 }
2463 big_finish(&x);
2464 big_finish(&q);
2465
2466 return (rv);
2467
2468 fail_cleanup:
2469 /*
2470 * cleanup the storage allocated to the local variables.
2471 */
2472 bigint_attr_cleanup(&modulus);
2473 bigint_attr_cleanup(&priexpo);
2474 bigint_attr_cleanup(&prime);
2475 bigint_attr_cleanup(&subprime);
2476 bigint_attr_cleanup(&base);
2477 bigint_attr_cleanup(&value);
2478 bigint_attr_cleanup(&pubexpo);
2479 bigint_attr_cleanup(&prime1);
2480 bigint_attr_cleanup(&prime2);
2481 bigint_attr_cleanup(&expo1);
2482 bigint_attr_cleanup(&expo2);
2483 bigint_attr_cleanup(&coef);
2484 string_attr_cleanup(&string_tmp);
2485 string_attr_cleanup(¶m_tmp);
2486 big_finish(&x);
2487 big_finish(&q);
2488
2489 /*
2490 * cleanup the storage allocated inside the object itself.
2491 */
2492 soft_cleanup_object(new_object);
2493
2494 return (rv);
2495 }
2496
2497
2498 /*
2499 * Build a Secret Key Object.
2500 *
2501 * - Parse the object's template, and when an error is detected such as
2502 * invalid attribute type, invalid attribute value, etc., return
2503 * with appropriate return value.
2504 * - Set up attribute mask field in the object for the supplied common
2505 * attributes that have boolean type.
2506 * - Build the attribute_info struct to hold the value of each supplied
2507 * attribute that has byte array type. Link attribute_info structs
2508 * together to form the extra attribute list of the object.
2509 * - Allocate storage for the Secret Key object.
2510 * - Build the Secret Key object. Allocate storage to hold the big integer
2511 * value for the attribute CKA_VALUE that is required for all the key
2512 * types supported by secret key object.
2513 * This function is called internally with mode = SOFT_CREATE_OBJ_INT.
2514 *
2515 */
2516 CK_RV
2517 soft_build_secret_key_object(CK_ATTRIBUTE_PTR template, CK_ULONG ulAttrNum,
2518 soft_object_t *new_object, CK_ULONG mode, CK_ULONG key_len,
2519 CK_KEY_TYPE key_type)
2520 {
2521
2522 ulong_t i;
2523 CK_KEY_TYPE keytype = (CK_KEY_TYPE)~0UL;
2524 uint64_t attr_mask = SECRET_KEY_DEFAULT;
2525 CK_RV rv = CKR_OK;
2526 int isLabel = 0;
2527 /* Must set flags if mode != SOFT_UNWRAP_KEY, else must not set */
2528 int isValue = 0;
2529 /* Must not set flags if mode != SOFT_UNWRAP_KEY, else optional */
2530 int isValueLen = 0;
2531
2532 CK_ATTRIBUTE string_tmp;
2533
2534 secret_key_obj_t *sck;
2535 uchar_t object_type = 0;
2536
2537 string_tmp.pValue = NULL;
2538
2539 /* Allocate storage for Secret Key Object. */
2540 sck = calloc(1, sizeof (secret_key_obj_t));
2541 if (sck == NULL) {
2542 rv = CKR_HOST_MEMORY;
2543 goto fail_cleanup;
2544 }
2545
2546 new_object->object_class_u.secret_key = sck;
2547 new_object->class = CKO_SECRET_KEY;
2548
2549 for (i = 0; i < ulAttrNum; i++) {
2550
2551 /* Secret Key Object Attributes */
2552 switch (template[i].type) {
2553
2554 /* common key attributes */
2555 case CKA_KEY_TYPE:
2556 keytype = *((CK_KEY_TYPE*)template[i].pValue);
2557 break;
2558
2559 case CKA_ID:
2560 case CKA_START_DATE:
2561 case CKA_END_DATE:
2562 /*
2563 * Allocate storage to hold the attribute
2564 * value with byte array type, and add it to
2565 * the extra attribute list of the object.
2566 */
2567 rv = soft_add_extra_attr(&template[i],
2568 new_object);
2569 if (rv != CKR_OK) {
2570 goto fail_cleanup;
2571 }
2572 break;
2573
2574 /*
2575 * The following key related attribute types must
2576 * not be specified by C_CreateObject and C_GenerateKey.
2577 */
2578 case CKA_LOCAL:
2579 case CKA_KEY_GEN_MECHANISM:
2580 case CKA_ALWAYS_SENSITIVE:
2581 case CKA_NEVER_EXTRACTABLE:
2582 rv = CKR_TEMPLATE_INCONSISTENT;
2583 goto fail_cleanup;
2584
2585 /* Key related boolean attributes */
2586 case CKA_DERIVE:
2587 if (*(CK_BBOOL *)template[i].pValue)
2588 attr_mask |= DERIVE_BOOL_ON;
2589 break;
2590
2591 case CKA_SENSITIVE:
2592 if (*(CK_BBOOL *)template[i].pValue)
2593 attr_mask |= SENSITIVE_BOOL_ON;
2594 break;
2595
2596 case CKA_ENCRYPT:
2597 if (*(CK_BBOOL *)template[i].pValue)
2598 attr_mask |= ENCRYPT_BOOL_ON;
2599 else
2600 attr_mask &= ~ENCRYPT_BOOL_ON;
2601 break;
2602
2603 case CKA_DECRYPT:
2604 if (*(CK_BBOOL *)template[i].pValue)
2605 attr_mask |= DECRYPT_BOOL_ON;
2606 else
2607 attr_mask &= ~DECRYPT_BOOL_ON;
2608 break;
2609
2610 case CKA_SIGN:
2611 if (*(CK_BBOOL *)template[i].pValue)
2612 attr_mask |= SIGN_BOOL_ON;
2613 else
2614 attr_mask &= ~SIGN_BOOL_ON;
2615 break;
2616
2617 case CKA_VERIFY:
2618 if (*(CK_BBOOL *)template[i].pValue)
2619 attr_mask |= VERIFY_BOOL_ON;
2620 else
2621 attr_mask &= ~VERIFY_BOOL_ON;
2622 break;
2623
2624 case CKA_WRAP:
2625 if (*(CK_BBOOL *)template[i].pValue)
2626 attr_mask |= WRAP_BOOL_ON;
2627 else
2628 attr_mask &= ~WRAP_BOOL_ON;
2629 break;
2630
2631 case CKA_UNWRAP:
2632 if (*(CK_BBOOL *)template[i].pValue)
2633 attr_mask |= UNWRAP_BOOL_ON;
2634 else
2635 attr_mask &= ~UNWRAP_BOOL_ON;
2636 break;
2637
2638 case CKA_EXTRACTABLE:
2639 if (*(CK_BBOOL *)template[i].pValue)
2640 attr_mask |= EXTRACTABLE_BOOL_ON;
2641 else
2642 attr_mask &= ~EXTRACTABLE_BOOL_ON;
2643 break;
2644
2645 case CKA_MODIFIABLE:
2646 if ((*(CK_BBOOL *)template[i].pValue) == B_FALSE)
2647 attr_mask |= NOT_MODIFIABLE_BOOL_ON;
2648 break;
2649
2650 case CKA_VALUE:
2651 isValue = 1;
2652 if (mode == SOFT_CREATE_OBJ) {
2653 if ((template[i].ulValueLen == 0) ||
2654 (template[i].pValue == NULL)) {
2655 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2656 goto fail_cleanup;
2657 }
2658 }
2659
2660 /*
2661 * Copyin attribute from template
2662 * to a local variable.
2663 */
2664 rv = get_bigint_attr_from_template((biginteger_t *)sck,
2665 &template[i]);
2666 if (rv != CKR_OK)
2667 goto fail_cleanup;
2668 break;
2669
2670 case CKA_VALUE_LEN:
2671 isValueLen = 1;
2672 rv = get_ulong_attr_from_template(&sck->sk_value_len,
2673 &template[i]);
2674 if (rv != CKR_OK)
2675 goto fail_cleanup;
2676 break;
2677
2678 case CKA_LABEL:
2679 isLabel = 1;
2680 rv = get_string_from_template(&string_tmp,
2681 &template[i]);
2682 if (rv != CKR_OK)
2683 goto fail_cleanup;
2684 break;
2685
2686 default:
2687 rv = soft_parse_common_attrs(&template[i],
2688 &object_type);
2689 if (rv != CKR_OK)
2690 goto fail_cleanup;
2691 break;
2692
2693 }
2694 } /* For */
2695
2696 switch (mode) {
2697 case SOFT_CREATE_OBJ:
2698 case SOFT_CREATE_OBJ_INT:
2699 case SOFT_DERIVE_KEY_DH:
2700 /*
2701 * The key type must be specified in the application's
2702 * template. Otherwise, returns error.
2703 */
2704 if (keytype == (CK_KEY_TYPE)~0UL) {
2705 rv = CKR_TEMPLATE_INCOMPLETE;
2706 goto fail_cleanup;
2707 }
2708 break;
2709
2710 case SOFT_GEN_KEY:
2711 if (keytype == (CK_KEY_TYPE)~0UL) {
2712 /*
2713 * The key type is not specified in the application's
2714 * template, so we use the implied key type based on
2715 * the mechanism.
2716 */
2717 keytype = key_type;
2718 } else {
2719 if (keytype != key_type) {
2720 /*
2721 * The key type specified in the template
2722 * does not match the implied key type based
2723 * on the mechanism.
2724 */
2725 rv = CKR_TEMPLATE_INCONSISTENT;
2726 goto fail_cleanup;
2727 }
2728 }
2729
2730 /*
2731 * If a key_len is passed as a parameter, it has to
2732 * match the one found in the template.
2733 */
2734 if (key_len > 0) {
2735 if (isValueLen && sck->sk_value_len != key_len) {
2736 rv = CKR_TEMPLATE_INCONSISTENT;
2737 goto fail_cleanup;
2738 }
2739 isValueLen = 1;
2740 sck->sk_value_len = key_len;
2741 }
2742 break;
2743
2744 case SOFT_UNWRAP_KEY:
2745 /*
2746 * Note that, for mode SOFT_UNWRAP_KEY, key type is not
2747 * implied by the mechanism (key_type), so if it is not
2748 * specified from the attribute template (keytype), it is
2749 * incomplete.
2750 */
2751 if (keytype == (CK_KEY_TYPE)~0UL) {
2752 rv = CKR_TEMPLATE_INCOMPLETE;
2753 goto fail_cleanup;
2754 }
2755 break;
2756
2757 case SOFT_DERIVE_KEY_OTHER:
2758 /*
2759 * For CKM_MD5_KEY_DERIVATION & CKM_SHA1_KEY_DERIVATION, the
2760 * key type is optional.
2761 */
2762 if (keytype == (CK_KEY_TYPE)~0UL) {
2763 keytype = key_type;
2764 }
2765 break;
2766 }
2767
2768 switch (mode) {
2769 case SOFT_CREATE_OBJ:
2770 case SOFT_CREATE_OBJ_INT:
2771 switch (keytype) {
2772 case CKK_RC4:
2773 if (!isValue) {
2774 rv = CKR_TEMPLATE_INCOMPLETE;
2775 goto fail_cleanup;
2776 }
2777 if ((sck->sk_value_len < ARCFOUR_MIN_KEY_BYTES) ||
2778 (sck->sk_value_len > ARCFOUR_MAX_KEY_BYTES)) {
2779 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2780 goto fail_cleanup;
2781 }
2782 break;
2783
2784 case CKK_GENERIC_SECRET:
2785 if (!isValue) {
2786 rv = CKR_TEMPLATE_INCOMPLETE;
2787 goto fail_cleanup;
2788 }
2789 break;
2790
2791 case CKK_AES:
2792 if (!isValue) {
2793 rv = CKR_TEMPLATE_INCOMPLETE;
2794 goto fail_cleanup;
2795 }
2796 if ((sck->sk_value_len != AES_MIN_KEY_BYTES) &&
2797 (sck->sk_value_len != AES_192_KEY_BYTES) &&
2798 (sck->sk_value_len != AES_MAX_KEY_BYTES)) {
2799 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2800 goto fail_cleanup;
2801 }
2802 break;
2803
2804 case CKK_BLOWFISH:
2805 if (!isValue) {
2806 rv = CKR_TEMPLATE_INCOMPLETE;
2807 goto fail_cleanup;
2808 }
2809 if ((sck->sk_value_len < BLOWFISH_MINBYTES) ||
2810 (sck->sk_value_len > BLOWFISH_MAXBYTES)) {
2811 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2812 goto fail_cleanup;
2813 }
2814
2815 break;
2816
2817 case CKK_DES:
2818 if (!isValue) {
2819 rv = CKR_TEMPLATE_INCOMPLETE;
2820 goto fail_cleanup;
2821 }
2822 if (sck->sk_value_len != DES_KEYSIZE) {
2823 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2824 goto fail_cleanup;
2825 }
2826 break;
2827
2828 case CKK_DES2:
2829 if (!isValue) {
2830 rv = CKR_TEMPLATE_INCOMPLETE;
2831 goto fail_cleanup;
2832 }
2833 if (sck->sk_value_len != DES2_KEYSIZE) {
2834 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2835 goto fail_cleanup;
2836 }
2837 break;
2838
2839 case CKK_DES3:
2840 if (!isValue) {
2841 rv = CKR_TEMPLATE_INCOMPLETE;
2842 goto fail_cleanup;
2843 }
2844 if (sck->sk_value_len != DES3_KEYSIZE) {
2845 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2846 goto fail_cleanup;
2847 }
2848 break;
2849
2850 default:
2851 rv = CKR_TEMPLATE_INCONSISTENT;
2852 goto fail_cleanup;
2853 }
2854
2855 if (isValueLen) {
2856 /*
2857 * Templates for internal object creation come from
2858 * applications calls to C_DeriveKey(), for which it
2859 * is OKey to pass a CKA_VALUE_LEN attribute, as
2860 * long as it does not conflict with the length of the
2861 * CKA_VALUE attribute.
2862 */
2863 if ((mode != SOFT_CREATE_OBJ_INT) ||
2864 ((key_len > 0) && sck->sk_value_len != key_len)) {
2865 rv = CKR_TEMPLATE_INCONSISTENT;
2866 goto fail_cleanup;
2867 }
2868 }
2869 break;
2870
2871 case SOFT_GEN_KEY:
2872 /* CKA_VALUE must not be specified */
2873 if (isValue) {
2874 rv = CKR_TEMPLATE_INCONSISTENT;
2875 goto fail_cleanup;
2876 }
2877
2878 switch (keytype) {
2879 /*
2880 * CKA_VALUE_LEN must be specified by C_GenerateKey
2881 * if mech is CKK_RC4, CKK_AES, CKK_GENERIC_SECRET.
2882 */
2883 case CKK_RC4:
2884 if (!isValueLen) {
2885 rv = CKR_TEMPLATE_INCOMPLETE;
2886 goto fail_cleanup;
2887 }
2888 ;
2889 if ((sck->sk_value_len < ARCFOUR_MIN_KEY_BYTES) ||
2890 (sck->sk_value_len > ARCFOUR_MAX_KEY_BYTES)) {
2891 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2892 goto fail_cleanup;
2893 }
2894 break;
2895
2896 case CKK_GENERIC_SECRET:
2897 /* arbitrary key length - no length checking */
2898 if (!isValueLen) {
2899 rv = CKR_TEMPLATE_INCOMPLETE;
2900 goto fail_cleanup;
2901 }
2902 break;
2903
2904 case CKK_AES:
2905 if (!isValueLen) {
2906 rv = CKR_TEMPLATE_INCOMPLETE;
2907 goto fail_cleanup;
2908 }
2909
2910 if ((sck->sk_value_len != AES_MIN_KEY_BYTES) &&
2911 (sck->sk_value_len != AES_192_KEY_BYTES) &&
2912 (sck->sk_value_len != AES_MAX_KEY_BYTES)) {
2913 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2914 goto fail_cleanup;
2915 }
2916
2917 break;
2918
2919 case CKK_BLOWFISH:
2920 if (!isValueLen) {
2921 rv = CKR_TEMPLATE_INCOMPLETE;
2922 goto fail_cleanup;
2923 }
2924 if ((sck->sk_value_len < BLOWFISH_MINBYTES) ||
2925 (sck->sk_value_len > BLOWFISH_MAXBYTES)) {
2926 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2927 goto fail_cleanup;
2928 }
2929
2930 break;
2931
2932 case CKK_DES:
2933 case CKK_DES2:
2934 case CKK_DES3:
2935 /* CKA_VALUE_LEN attribute does not apply to DES<n> */
2936 if (isValueLen) {
2937 rv = CKR_TEMPLATE_INCONSISTENT;
2938 goto fail_cleanup;
2939 }
2940 break;
2941
2942 default:
2943 rv = CKR_TEMPLATE_INCONSISTENT;
2944 goto fail_cleanup;
2945 }
2946 break;
2947
2948 case SOFT_UNWRAP_KEY:
2949 /*
2950 * According to v2.11 of PKCS#11 spec, neither CKA_VALUE nor
2951 * CKA_VALUE_LEN can be be specified; however v2.20 has this
2952 * restriction removed, perhaps because it makes it hard to
2953 * determine variable-length key sizes. This case statement
2954 * complied with v2.20.
2955 */
2956 if (isValue) {
2957 rv = CKR_TEMPLATE_INCONSISTENT;
2958 goto fail_cleanup;
2959 }
2960
2961 switch (keytype) {
2962 /*
2963 * CKA_VALUE_LEN is optional
2964 * if key is CKK_RC4, CKK_AES, CKK_GENERIC_SECRET
2965 * and the unwrapping mech is *_CBC_PAD.
2966 *
2967 * CKA_VALUE_LEN is required
2968 * if key is CKK_RC4, CKK_AES, CKK_GENERIC_SECRET
2969 * and the unwrapping mech is *_ECB or *_CBC.
2970 *
2971 * since mech is not known at this point, CKA_VALUE_LEN is
2972 * treated as optional and the caller needs to enforce it.
2973 */
2974 case CKK_RC4:
2975 if (isValueLen) {
2976 if ((sck->sk_value_len <
2977 ARCFOUR_MIN_KEY_BYTES) ||
2978 (sck->sk_value_len >
2979 ARCFOUR_MAX_KEY_BYTES)) {
2980 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2981 goto fail_cleanup;
2982 }
2983 }
2984 break;
2985
2986 case CKK_GENERIC_SECRET:
2987 /* arbitrary key length - no length checking */
2988 break;
2989
2990 case CKK_AES:
2991 if (isValueLen) {
2992 if ((sck->sk_value_len != AES_MIN_KEY_BYTES) &&
2993 (sck->sk_value_len != AES_192_KEY_BYTES) &&
2994 (sck->sk_value_len != AES_MAX_KEY_BYTES)) {
2995 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2996 goto fail_cleanup;
2997 }
2998 }
2999 break;
3000
3001 case CKK_BLOWFISH:
3002 if (isValueLen &&
3003 ((sck->sk_value_len < BLOWFISH_MINBYTES) ||
3004 (sck->sk_value_len > BLOWFISH_MAXBYTES))) {
3005 rv = CKR_ATTRIBUTE_VALUE_INVALID;
3006 goto fail_cleanup;
3007 }
3008 break;
3009
3010 case CKK_DES:
3011 case CKK_DES2:
3012 case CKK_DES3:
3013 /* CKA_VALUE_LEN attribute does not apply to DES<n> */
3014 if (isValueLen) {
3015 rv = CKR_TEMPLATE_INCONSISTENT;
3016 goto fail_cleanup;
3017 }
3018 break;
3019
3020 default:
3021 rv = CKR_TEMPLATE_INCONSISTENT;
3022 goto fail_cleanup;
3023 }
3024 break;
3025
3026 case SOFT_DERIVE_KEY_DH:
3027 /* CKA_VALUE must not be specified */
3028 if (isValue) {
3029 rv = CKR_TEMPLATE_INCONSISTENT;
3030 goto fail_cleanup;
3031 }
3032
3033 switch (keytype) {
3034 /*
3035 * CKA_VALUE_LEN is optional
3036 * if mech is CKK_RC4, CKK_AES, CKK_GENERIC_SECRET.
3037 */
3038 case CKK_RC4:
3039 if (isValueLen) {
3040 if ((sck->sk_value_len <
3041 ARCFOUR_MIN_KEY_BYTES) ||
3042 (sck->sk_value_len >
3043 ARCFOUR_MAX_KEY_BYTES)) {
3044 rv = CKR_ATTRIBUTE_VALUE_INVALID;
3045 goto fail_cleanup;
3046 }
3047 }
3048 break;
3049
3050 case CKK_GENERIC_SECRET:
3051 /* arbitrary key length - no length checking */
3052 break;
3053
3054 case CKK_AES:
3055 if (isValueLen) {
3056 if ((sck->sk_value_len != AES_MIN_KEY_BYTES) &&
3057 (sck->sk_value_len != AES_192_KEY_BYTES) &&
3058 (sck->sk_value_len != AES_MAX_KEY_BYTES)) {
3059 rv = CKR_ATTRIBUTE_VALUE_INVALID;
3060 goto fail_cleanup;
3061 }
3062 }
3063
3064 break;
3065
3066 case CKK_BLOWFISH:
3067 if (isValueLen &&
3068 ((sck->sk_value_len < BLOWFISH_MINBYTES) ||
3069 (sck->sk_value_len > BLOWFISH_MAXBYTES))) {
3070 rv = CKR_ATTRIBUTE_VALUE_INVALID;
3071 goto fail_cleanup;
3072 }
3073 break;
3074
3075 case CKK_DES:
3076 case CKK_DES2:
3077 case CKK_DES3:
3078 /* CKA_VALUE_LEN attribute does not apply to DES<n> */
3079 if (isValueLen) {
3080 rv = CKR_TEMPLATE_INCONSISTENT;
3081 goto fail_cleanup;
3082 }
3083 break;
3084
3085 default:
3086 rv = CKR_TEMPLATE_INCONSISTENT;
3087 goto fail_cleanup;
3088 }
3089 break;
3090
3091 case SOFT_DERIVE_KEY_OTHER:
3092 /* CKA_VALUE must not be specified */
3093 if (isValue) {
3094 rv = CKR_TEMPLATE_INCONSISTENT;
3095 goto fail_cleanup;
3096 }
3097
3098 switch (keytype) {
3099 /*
3100 * CKA_VALUE_LEN is an optional attribute for
3101 * CKM_SHA1_KEY_DERIVATION and CKM_MD5_KEY_DERIVATION
3102 * if mech is CKK_RC4, CKK_AES, CKK_GENERIC_SECRET.
3103 */
3104 case CKK_RC4:
3105 case CKK_GENERIC_SECRET:
3106 case CKK_AES:
3107 case CKK_BLOWFISH:
3108 /*
3109 * No need to check key length value here, it will be
3110 * validated later in soft_key_derive_check_length().
3111 */
3112 break;
3113
3114 case CKK_DES:
3115 case CKK_DES2:
3116 case CKK_DES3:
3117 /* CKA_VALUE_LEN attribute does not apply to DES<n> */
3118 if (isValueLen) {
3119 rv = CKR_TEMPLATE_INCONSISTENT;
3120 goto fail_cleanup;
3121 }
3122 break;
3123
3124 default:
3125 rv = CKR_TEMPLATE_INCONSISTENT;
3126 goto fail_cleanup;
3127 }
3128 break;
3129 }
3130
3131 /* Set up object. */
3132 new_object->key_type = keytype;
3133 new_object->object_type = object_type;
3134 new_object->bool_attr_mask = attr_mask;
3135 if (isLabel) {
3136 rv = soft_add_extra_attr(&string_tmp, new_object);
3137 if (rv != CKR_OK)
3138 goto fail_cleanup;
3139 string_attr_cleanup(&string_tmp);
3140 }
3141 return (rv);
3142
3143 fail_cleanup:
3144 /*
3145 * cleanup the storage allocated to the local variables.
3146 */
3147 bigint_attr_cleanup((biginteger_t *)sck);
3148 string_attr_cleanup(&string_tmp);
3149
3150 /*
3151 * cleanup the storage allocated inside the object itself.
3152 */
3153 soft_cleanup_object(new_object);
3154
3155 return (rv);
3156 }
3157
3158
3159 /*
3160 * Build a Domain Parameter Object.
3161 *
3162 * - Parse the object's template, and when an error is detected such as
3163 * invalid attribute type, invalid attribute value, etc., return
3164 * with appropriate return value.
3165 * - Allocate storage for the Domain Parameter object.
3166 * - Build the Domain Parameter object according to the key type. Allocate
3167 * storage to hold the big integer value for the supplied attributes
3168 * that are required for a certain key type.
3169 *
3170 */
3171 CK_RV
3172 soft_build_domain_parameters_object(CK_ATTRIBUTE_PTR template,
3173 CK_ULONG ulAttrNum, soft_object_t *new_object)
3174 {
3175
3176 ulong_t i;
3177 CK_KEY_TYPE keytype = (CK_KEY_TYPE)~0UL;
3178 CK_RV rv = CKR_OK;
3179 int isLabel = 0;
3180 /* Must set flags */
3181 int isPrime = 0;
3182 int isSubprime = 0;
3183 int isBase = 0;
3184 /* Must not set flags */
3185 int isPrimeBits = 0;
3186 int isSubPrimeBits = 0;
3187
3188 biginteger_t prime;
3189 biginteger_t subprime;
3190 biginteger_t base;
3191 CK_ATTRIBUTE string_tmp;
3192
3193 domain_obj_t *dom;
3194 uchar_t object_type = 0;
3195
3196 /* prevent bigint_attr_cleanup from freeing invalid attr value */
3197 (void) memset(&prime, 0x0, sizeof (biginteger_t));
3198 (void) memset(&subprime, 0x0, sizeof (biginteger_t));
3199 (void) memset(&base, 0x0, sizeof (biginteger_t));
3200 string_tmp.pValue = NULL;
3201
3202 for (i = 0; i < ulAttrNum; i++) {
3203
3204 /* Domain Parameters Object Attributes */
3205 switch (template[i].type) {
3206
3207 /* common domain parameter attribute */
3208 case CKA_KEY_TYPE:
3209 keytype = *((CK_KEY_TYPE*)template[i].pValue);
3210 break;
3211
3212 /*
3213 * The following common domain parameter attribute
3214 * must not be specified by C_CreateObject.
3215 */
3216 case CKA_LOCAL:
3217 rv = CKR_TEMPLATE_INCONSISTENT;
3218 goto fail_cleanup;
3219
3220 /*
3221 * The following domain parameter attributes must be
3222 * specified according to the key type by
3223 * C_CreateObject.
3224 */
3225 case CKA_PRIME:
3226 isPrime = 1;
3227 /*
3228 * Copyin big integer attribute from template
3229 * to a local variable.
3230 */
3231 rv = get_bigint_attr_from_template(&prime,
3232 &template[i]);
3233 if (rv != CKR_OK)
3234 goto fail_cleanup;
3235 break;
3236
3237 case CKA_SUBPRIME:
3238 isSubprime = 1;
3239 rv = get_bigint_attr_from_template(&subprime,
3240 &template[i]);
3241 if (rv != CKR_OK)
3242 goto fail_cleanup;
3243 break;
3244
3245 case CKA_BASE:
3246 isBase = 1;
3247 rv = get_bigint_attr_from_template(&base,
3248 &template[i]);
3249 if (rv != CKR_OK)
3250 goto fail_cleanup;
3251 break;
3252
3253 case CKA_PRIME_BITS:
3254 isPrimeBits = 1;
3255 break;
3256
3257 case CKA_SUB_PRIME_BITS:
3258 isSubPrimeBits = 1;
3259 break;
3260
3261 case CKA_LABEL:
3262 isLabel = 1;
3263 rv = get_string_from_template(&string_tmp,
3264 &template[i]);
3265 if (rv != CKR_OK)
3266 goto fail_cleanup;
3267 break;
3268
3269 default:
3270 rv = soft_parse_common_attrs(&template[i],
3271 &object_type);
3272 if (rv != CKR_OK)
3273 goto fail_cleanup;
3274 break;
3275
3276 }
3277 } /* For */
3278
3279 /* Allocate storage for Domain Parameters Object. */
3280 dom = calloc(1, sizeof (domain_obj_t));
3281 if (dom == NULL) {
3282 rv = CKR_HOST_MEMORY;
3283 goto fail_cleanup;
3284 }
3285
3286 new_object->object_class_u.domain = dom;
3287 new_object->class = CKO_DOMAIN_PARAMETERS;
3288
3289 if (keytype == (CK_KEY_TYPE)~0UL) {
3290 rv = CKR_TEMPLATE_INCOMPLETE;
3291 goto fail_cleanup;
3292 }
3293
3294 new_object->key_type = keytype;
3295
3296 /* Supported key types of the Domain Parameters Object */
3297 switch (keytype) {
3298 case CKK_DSA:
3299 if (isPrimeBits || isSubPrimeBits) {
3300 rv = CKR_TEMPLATE_INCONSISTENT;
3301 goto fail_cleanup;
3302 }
3303
3304 if (isPrime && isSubprime && isBase) {
3305 /*
3306 * Copy big integer attribute value to the
3307 * designated place in the domain parameter
3308 * object.
3309 */
3310 copy_bigint_attr(&prime, KEY_DOM_DSA_PRIME(dom));
3311
3312 copy_bigint_attr(&subprime, KEY_DOM_DSA_SUBPRIME(dom));
3313
3314 copy_bigint_attr(&base, KEY_DOM_DSA_BASE(dom));
3315 } else {
3316 rv = CKR_TEMPLATE_INCOMPLETE;
3317 goto fail_cleanup;
3318 }
3319 break;
3320
3321 case CKK_DH:
3322 if (isPrimeBits || isSubprime || isSubPrimeBits) {
3323 rv = CKR_TEMPLATE_INCONSISTENT;
3324 goto fail_cleanup;
3325 }
3326
3327 if (isPrime && isBase) {
3328 copy_bigint_attr(&prime, KEY_DOM_DH_PRIME(dom));
3329
3330 copy_bigint_attr(&base, KEY_DOM_DH_BASE(dom));
3331 } else {
3332 rv = CKR_TEMPLATE_INCOMPLETE;
3333 goto fail_cleanup;
3334 }
3335 break;
3336
3337 case CKK_X9_42_DH:
3338 if (isPrimeBits || isSubPrimeBits) {
3339 rv = CKR_TEMPLATE_INCONSISTENT;
3340 goto fail_cleanup;
3341 }
3342
3343 if (isPrime && isSubprime && isBase) {
3344 copy_bigint_attr(&prime, KEY_DOM_DH942_PRIME(dom));
3345
3346 copy_bigint_attr(&base, KEY_DOM_DH942_BASE(dom));
3347
3348 copy_bigint_attr(&subprime,
3349 KEY_DOM_DH942_SUBPRIME(dom));
3350 } else {
3351 rv = CKR_TEMPLATE_INCOMPLETE;
3352 goto fail_cleanup;
3353 }
3354 break;
3355
3356 default:
3357 rv = CKR_TEMPLATE_INCONSISTENT;
3358 goto fail_cleanup;
3359 }
3360
3361 new_object->object_type = object_type;
3362
3363 if (isLabel) {
3364 rv = soft_add_extra_attr(&string_tmp, new_object);
3365 if (rv != CKR_OK)
3366 goto fail_cleanup;
3367 string_attr_cleanup(&string_tmp);
3368 }
3369
3370 return (rv);
3371
3372 fail_cleanup:
3373 /*
3374 * cleanup the storage allocated to the local variables.
3375 */
3376 bigint_attr_cleanup(&prime);
3377 bigint_attr_cleanup(&subprime);
3378 bigint_attr_cleanup(&base);
3379 string_attr_cleanup(&string_tmp);
3380
3381 /*
3382 * cleanup the storage allocated inside the object itself.
3383 */
3384 soft_cleanup_object(new_object);
3385
3386 return (rv);
3387 }
3388
3389 /*
3390 * Build a Certificate Object
3391 *
3392 * - Parse the object's template, and when an error is detected such as
3393 * invalid attribute type, invalid attribute value, etc., return
3394 * with appropriate return value.
3395 * - Allocate storage for the Certificate object
3396 */
3397 static CK_RV
3398 soft_build_certificate_object(CK_ATTRIBUTE_PTR template,
3399 CK_ULONG ulAttrNum, soft_object_t *new_object,
3400 CK_CERTIFICATE_TYPE cert_type)
3401 {
3402 uint64_t attr_mask = 0;
3403 CK_RV rv = CKR_OK;
3404 CK_ULONG i;
3405 int owner_set = 0;
3406 int value_set = 0;
3407 int subject_set = 0;
3408 certificate_obj_t *cert;
3409 /* certificate type defaults to the value given as a parameter */
3410 CK_CERTIFICATE_TYPE certtype = cert_type;
3411 CK_ATTRIBUTE string_tmp;
3412 int isLabel = 0;
3413 uchar_t object_type = 0;
3414
3415 /*
3416 * Look for the certificate type attribute and do some
3417 * sanity checking before creating the structures.
3418 */
3419 for (i = 0; i < ulAttrNum; i++) {
3420 /* Certificate Object Attributes */
3421 switch (template[i].type) {
3422 case CKA_CERTIFICATE_TYPE:
3423 certtype =
3424 *((CK_CERTIFICATE_TYPE*)template[i].pValue);
3425 break;
3426 case CKA_SUBJECT:
3427 subject_set = 1;
3428 break;
3429 case CKA_OWNER:
3430 owner_set = 1;
3431 break;
3432 case CKA_VALUE:
3433 value_set = 1;
3434 break;
3435 }
3436 }
3437
3438 /* The certificate type MUST be specified */
3439 if (certtype != CKC_X_509 && certtype != CKC_X_509_ATTR_CERT)
3440 return (CKR_TEMPLATE_INCOMPLETE);
3441
3442 /*
3443 * For X.509 certs, the CKA_SUBJECT and CKA_VALUE
3444 * must be present at creation time.
3445 */
3446 if (certtype == CKC_X_509 &&
3447 (!subject_set || !value_set))
3448 return (CKR_TEMPLATE_INCOMPLETE);
3449
3450 /*
3451 * For X.509 Attribute certs, the CKA_OWNER and CKA_VALUE
3452 * must be present at creation time.
3453 */
3454 if (certtype == CKC_X_509_ATTR_CERT &&
3455 (!owner_set || !value_set))
3456 return (CKR_TEMPLATE_INCOMPLETE);
3457
3458 string_tmp.pValue = NULL;
3459 cert = calloc(1, sizeof (certificate_obj_t));
3460 if (cert == NULL) {
3461 return (CKR_HOST_MEMORY);
3462 }
3463 cert->certificate_type = certtype;
3464
3465 for (i = 0; i < ulAttrNum; i++) {
3466 /* Certificate Object Attributes */
3467 switch (certtype) {
3468 case CKC_X_509:
3469 switch (template[i].type) {
3470 case CKA_SUBJECT:
3471 rv = get_cert_attr_from_template(
3472 &cert->cert_type_u.x509.subject,
3473 &template[i]);
3474 break;
3475 case CKA_VALUE:
3476 rv = get_cert_attr_from_template(
3477 &cert->cert_type_u.x509.value,
3478 &template[i]);
3479 break;
3480 case CKA_LABEL:
3481 isLabel = 1;
3482 rv = get_string_from_template(
3483 &string_tmp,
3484 &template[i]);
3485 if (rv != CKR_OK)
3486 goto fail_cleanup;
3487 break;
3488 case CKA_ID:
3489 case CKA_ISSUER:
3490 case CKA_SERIAL_NUMBER:
3491 rv = soft_add_extra_attr(&template[i],
3492 new_object);
3493 break;
3494 case CKA_MODIFIABLE:
3495 if ((*(CK_BBOOL *)template[i].pValue) ==
3496 B_FALSE)
3497 attr_mask |=
3498 NOT_MODIFIABLE_BOOL_ON;
3499 break;
3500 case CKA_CERTIFICATE_TYPE:
3501 break;
3502 default:
3503 rv = soft_parse_common_attrs(
3504 &template[i], &object_type);
3505 if (rv != CKR_OK)
3506 goto fail_cleanup;
3507 }
3508 break;
3509 case CKC_X_509_ATTR_CERT:
3510 switch (template[i].type) {
3511 case CKA_OWNER:
3512 rv = get_cert_attr_from_template(
3513 &cert->cert_type_u.x509_attr.owner,
3514 &template[i]);
3515 break;
3516 case CKA_VALUE:
3517 rv = get_cert_attr_from_template(
3518 &cert->cert_type_u.x509_attr.value,
3519 &template[i]);
3520 break;
3521 case CKA_LABEL:
3522 isLabel = 1;
3523 rv = get_string_from_template(
3524 &string_tmp, &template[i]);
3525 if (rv != CKR_OK)
3526 goto fail_cleanup;
3527 break;
3528 case CKA_SERIAL_NUMBER:
3529 case CKA_AC_ISSUER:
3530 case CKA_ATTR_TYPES:
3531 rv = soft_add_extra_attr(&template[i],
3532 new_object);
3533 break;
3534
3535 case CKA_MODIFIABLE:
3536 if ((*(CK_BBOOL *)template[i].pValue) ==
3537 B_FALSE)
3538 attr_mask |=
3539 NOT_MODIFIABLE_BOOL_ON;
3540 break;
3541 case CKA_CERTIFICATE_TYPE:
3542 break;
3543 default:
3544 rv = soft_parse_common_attrs(
3545 &template[i], &object_type);
3546 if (rv != CKR_OK)
3547 goto fail_cleanup;
3548 break;
3549 }
3550 break;
3551 default:
3552 rv = CKR_TEMPLATE_INCOMPLETE;
3553 break;
3554 }
3555 }
3556
3557 if (rv == CKR_OK) {
3558 new_object->object_class_u.certificate = cert;
3559 new_object->class = CKO_CERTIFICATE;
3560 new_object->object_type = object_type;
3561 new_object->cert_type = certtype;
3562 new_object->bool_attr_mask = attr_mask;
3563 if (isLabel) {
3564 rv = soft_add_extra_attr(&string_tmp, new_object);
3565 if (rv != CKR_OK)
3566 goto fail_cleanup;
3567 string_attr_cleanup(&string_tmp);
3568 }
3569 }
3570
3571 fail_cleanup:
3572 if (rv != CKR_OK) {
3573 soft_cleanup_cert_object(new_object);
3574 }
3575 return (rv);
3576 }
3577
3578
3579 /*
3580 * Validate the attribute types in the object's template. Then,
3581 * call the appropriate build function according to the class of
3582 * the object specified in the template.
3583 *
3584 * Note: The following classes of objects are supported:
3585 * - CKO_PUBLIC_KEY
3586 * - CKO_PRIVATE_KEY
3587 * - CKO_SECRET_KEY
3588 * - CKO_DOMAIN_PARAMETERS
3589 * - CKO_CERTIFICATE
3590 *
3591 */
3592 CK_RV
3593 soft_build_object(CK_ATTRIBUTE_PTR template, CK_ULONG ulAttrNum,
3594 soft_object_t *new_object)
3595 {
3596
3597 CK_OBJECT_CLASS class = (CK_OBJECT_CLASS)~0UL;
3598 CK_RV rv = CKR_OK;
3599
3600 if (template == NULL) {
3601 return (CKR_ARGUMENTS_BAD);
3602 }
3603
3604 /* Validate the attribute type in the template. */
3605 rv = soft_validate_attr(template, ulAttrNum, &class);
3606 if (rv != CKR_OK)
3607 return (rv);
3608 /*
3609 * CKA_CLASS is a mandatory attribute for C_CreateObject
3610 */
3611 if (class == (CK_OBJECT_CLASS)~0UL)
3612 return (CKR_TEMPLATE_INCOMPLETE);
3613
3614 /*
3615 * Call the appropriate function based on the supported class
3616 * of the object.
3617 */
3618 switch (class) {
3619 case CKO_PUBLIC_KEY:
3620 rv = soft_build_public_key_object(template, ulAttrNum,
3621 new_object, SOFT_CREATE_OBJ, (CK_KEY_TYPE)~0UL);
3622 break;
3623
3624 case CKO_PRIVATE_KEY:
3625 rv = soft_build_private_key_object(template, ulAttrNum,
3626 new_object, SOFT_CREATE_OBJ, (CK_KEY_TYPE)~0UL);
3627 break;
3628
3629 case CKO_SECRET_KEY:
3630 rv = soft_build_secret_key_object(template, ulAttrNum,
3631 new_object, SOFT_CREATE_OBJ, 0, (CK_KEY_TYPE)~0UL);
3632 break;
3633
3634 case CKO_DOMAIN_PARAMETERS:
3635 rv = soft_build_domain_parameters_object(template, ulAttrNum,
3636 new_object);
3637 break;
3638
3639 case CKO_CERTIFICATE:
3640 rv = soft_build_certificate_object(template, ulAttrNum,
3641 new_object, (CK_CERTIFICATE_TYPE)~0UL);
3642 break;
3643
3644 case CKO_DATA:
3645 case CKO_HW_FEATURE:
3646 case CKO_VENDOR_DEFINED:
3647 default:
3648 return (CKR_ATTRIBUTE_VALUE_INVALID);
3649 }
3650
3651 return (rv);
3652 }
3653
3654 /*
3655 * Validate the attribute types in the object's template. Then,
3656 * call the appropriate build function according to the class of
3657 * the object specified in the template.
3658 *
3659 */
3660 CK_RV
3661 soft_build_key(CK_ATTRIBUTE_PTR template, CK_ULONG ulAttrNum,
3662 soft_object_t *new_object, CK_OBJECT_CLASS class, CK_KEY_TYPE key_type,
3663 CK_ULONG key_len, CK_ULONG mode)
3664 {
3665
3666 CK_RV rv = CKR_OK;
3667 CK_OBJECT_CLASS temp_class = (CK_OBJECT_CLASS)~0UL;
3668
3669 /* Validate the attribute type in the template. */
3670 if ((template != NULL) && (ulAttrNum != 0)) {
3671 rv = soft_validate_attr(template, ulAttrNum, &temp_class);
3672 if (rv != CKR_OK)
3673 return (rv);
3674 }
3675
3676 /*
3677 * If either the class from the parameter list ("class") or
3678 * the class from the template ("temp_class") is not specified,
3679 * try to use the other one.
3680 */
3681 if (temp_class == (CK_OBJECT_CLASS)~0UL) {
3682 temp_class = class;
3683 } else if (class == (CK_OBJECT_CLASS)~0UL) {
3684 class = temp_class;
3685 }
3686
3687 /* If object class is still not specified, template is incomplete. */
3688 if (class == (CK_OBJECT_CLASS)~0UL)
3689 return (CKR_TEMPLATE_INCOMPLETE);
3690
3691 /* Class should match if specified in both parameters and template. */
3692 if (class != temp_class)
3693 return (CKR_TEMPLATE_INCONSISTENT);
3694
3695 /*
3696 * Call the appropriate function based on the supported class
3697 * of the object.
3698 */
3699 switch (class) {
3700 case CKO_PUBLIC_KEY:
3701
3702 /* Unwrapping public keys is not supported. */
3703 if (mode == SOFT_UNWRAP_KEY) {
3704 rv = CKR_ATTRIBUTE_VALUE_INVALID;
3705 break;
3706 }
3707
3708 rv = soft_build_public_key_object(template, ulAttrNum,
3709 new_object, mode, key_type);
3710 break;
3711
3712 case CKO_PRIVATE_KEY:
3713
3714 rv = soft_build_private_key_object(template, ulAttrNum,
3715 new_object, mode, key_type);
3716 break;
3717
3718 case CKO_SECRET_KEY:
3719
3720 rv = soft_build_secret_key_object(template, ulAttrNum,
3721 new_object, mode, key_len, key_type);
3722 break;
3723
3724 case CKO_DOMAIN_PARAMETERS:
3725
3726 /* Unwrapping domain parameters is not supported. */
3727 if (mode == SOFT_UNWRAP_KEY) {
3728 rv = CKR_ATTRIBUTE_VALUE_INVALID;
3729 break;
3730 }
3731
3732 rv = soft_build_domain_parameters_object(template, ulAttrNum,
3733 new_object);
3734 break;
3735
3736 case CKO_DATA:
3737 case CKO_CERTIFICATE:
3738 case CKO_HW_FEATURE:
3739 case CKO_VENDOR_DEFINED:
3740 default:
3741 return (CKR_ATTRIBUTE_VALUE_INVALID);
3742 }
3743
3744 return (rv);
3745 }
3746
3747
3748 /*
3749 * Get the value of a requested attribute that is common to all supported
3750 * classes (i.e. public key, private key, secret key, domain parameters,
3751 * and certificate classes).
3752 */
3753 CK_RV
3754 soft_get_common_attrs(soft_object_t *object_p, CK_ATTRIBUTE_PTR template,
3755 uchar_t object_type)
3756 {
3757
3758 CK_RV rv = CKR_OK;
3759
3760 switch (template->type) {
3761
3762 case CKA_CLASS:
3763 return (get_ulong_attr_from_object(object_p->class,
3764 template));
3765
3766 /* default boolean attributes */
3767 case CKA_TOKEN:
3768 template->ulValueLen = sizeof (CK_BBOOL);
3769 if (template->pValue == NULL) {
3770 return (CKR_OK);
3771 }
3772 if (object_type & TOKEN_OBJECT)
3773 *((CK_BBOOL *)template->pValue) = B_TRUE;
3774 else
3775 *((CK_BBOOL *)template->pValue) = B_FALSE;
3776 break;
3777
3778 case CKA_PRIVATE:
3779
3780 template->ulValueLen = sizeof (CK_BBOOL);
3781 if (template->pValue == NULL) {
3782 return (CKR_OK);
3783 }
3784 if (object_type & PRIVATE_OBJECT)
3785 *((CK_BBOOL *)template->pValue) = B_TRUE;
3786 else
3787 *((CK_BBOOL *)template->pValue) = B_FALSE;
3788 break;
3789
3790 case CKA_MODIFIABLE:
3791 template->ulValueLen = sizeof (CK_BBOOL);
3792 if (template->pValue == NULL) {
3793 return (CKR_OK);
3794 }
3795 if ((object_p->bool_attr_mask) & NOT_MODIFIABLE_BOOL_ON)
3796 *((CK_BBOOL *)template->pValue) = B_FALSE;
3797 else
3798 *((CK_BBOOL *)template->pValue) = B_TRUE;
3799 break;
3800
3801 case CKA_LABEL:
3802 return (get_extra_attr_from_object(object_p,
3803 template));
3804
3805 default:
3806 /*
3807 * The specified attribute for the object is invalid.
3808 * (the object does not possess such an attribute.)
3809 */
3810 template->ulValueLen = (CK_ULONG)-1;
3811 return (CKR_ATTRIBUTE_TYPE_INVALID);
3812 }
3813
3814 return (rv);
3815 }
3816
3817 /*
3818 * Get the value of a requested attribute that is common to all key objects
3819 * (i.e. public key, private key and secret key).
3820 */
3821 CK_RV
3822 soft_get_common_key_attrs(soft_object_t *object_p, CK_ATTRIBUTE_PTR template)
3823 {
3824
3825 switch (template->type) {
3826
3827 case CKA_KEY_TYPE:
3828 return (get_ulong_attr_from_object(object_p->key_type,
3829 template));
3830
3831 case CKA_ID:
3832 case CKA_START_DATE:
3833 case CKA_END_DATE:
3834 /*
3835 * The above extra attributes have byte array type.
3836 */
3837 return (get_extra_attr_from_object(object_p,
3838 template));
3839
3840 /* Key related boolean attributes */
3841 case CKA_LOCAL:
3842 return (get_bool_attr_from_object(object_p,
3843 LOCAL_BOOL_ON, template));
3844
3845 case CKA_DERIVE:
3846 return (get_bool_attr_from_object(object_p,
3847 DERIVE_BOOL_ON, template));
3848
3849 case CKA_KEY_GEN_MECHANISM:
3850 return (get_ulong_attr_from_object(object_p->mechanism,
3851 template));
3852
3853 default:
3854 return (CKR_ATTRIBUTE_TYPE_INVALID);
3855 }
3856 }
3857
3858 /*
3859 * Get the value of a requested attribute of a Public Key Object.
3860 *
3861 * Rule: All the attributes in the public key object can be revealed.
3862 */
3863 CK_RV
3864 soft_get_public_key_attribute(soft_object_t *object_p,
3865 CK_ATTRIBUTE_PTR template)
3866 {
3867
3868 CK_RV rv = CKR_OK;
3869 CK_KEY_TYPE keytype = object_p->key_type;
3870
3871 switch (template->type) {
3872
3873 case CKA_SUBJECT:
3874 case CKA_EC_PARAMS:
3875 /*
3876 * The above extra attributes have byte array type.
3877 */
3878 return (get_extra_attr_from_object(object_p,
3879 template));
3880
3881 /* Key related boolean attributes */
3882 case CKA_ENCRYPT:
3883 return (get_bool_attr_from_object(object_p,
3884 ENCRYPT_BOOL_ON, template));
3885
3886 case CKA_VERIFY:
3887 return (get_bool_attr_from_object(object_p,
3888 VERIFY_BOOL_ON, template));
3889
3890 case CKA_VERIFY_RECOVER:
3891 return (get_bool_attr_from_object(object_p,
3892 VERIFY_RECOVER_BOOL_ON, template));
3893
3894 case CKA_WRAP:
3895 return (get_bool_attr_from_object(object_p,
3896 WRAP_BOOL_ON, template));
3897
3898 case CKA_TRUSTED:
3899 return (get_bool_attr_from_object(object_p,
3900 TRUSTED_BOOL_ON, template));
3901
3902 case CKA_MODULUS:
3903 /*
3904 * This attribute is valid only for RSA public key
3905 * object.
3906 */
3907 if (keytype == CKK_RSA) {
3908 return (get_bigint_attr_from_object(
3909 OBJ_PUB_RSA_MOD(object_p), template));
3910 } else {
3911 template->ulValueLen = (CK_ULONG)-1;
3912 return (CKR_ATTRIBUTE_TYPE_INVALID);
3913 }
3914
3915 case CKA_PUBLIC_EXPONENT:
3916 if (keytype == CKK_RSA) {
3917 return (get_bigint_attr_from_object(
3918 OBJ_PUB_RSA_PUBEXPO(object_p), template));
3919 } else {
3920 template->ulValueLen = (CK_ULONG)-1;
3921 return (CKR_ATTRIBUTE_TYPE_INVALID);
3922 }
3923
3924 case CKA_MODULUS_BITS:
3925 if (keytype == CKK_RSA) {
3926 return (get_ulong_attr_from_object(
3927 OBJ_PUB_RSA_MOD_BITS(object_p), template));
3928 } else {
3929 template->ulValueLen = (CK_ULONG)-1;
3930 return (CKR_ATTRIBUTE_TYPE_INVALID);
3931 }
3932
3933 case CKA_PRIME:
3934 switch (keytype) {
3935 case CKK_DSA:
3936 return (get_bigint_attr_from_object(
3937 OBJ_PUB_DSA_PRIME(object_p), template));
3938
3939 case CKK_DH:
3940 return (get_bigint_attr_from_object(
3941 OBJ_PUB_DH_PRIME(object_p), template));
3942
3943 case CKK_X9_42_DH:
3944 return (get_bigint_attr_from_object(
3945 OBJ_PUB_DH942_PRIME(object_p), template));
3946
3947 default:
3948 template->ulValueLen = (CK_ULONG)-1;
3949 return (CKR_ATTRIBUTE_TYPE_INVALID);
3950 }
3951
3952 case CKA_SUBPRIME:
3953 switch (keytype) {
3954 case CKK_DSA:
3955 return (get_bigint_attr_from_object(
3956 OBJ_PUB_DSA_SUBPRIME(object_p), template));
3957
3958 case CKK_X9_42_DH:
3959 return (get_bigint_attr_from_object(
3960 OBJ_PUB_DH942_SUBPRIME(object_p), template));
3961
3962 default:
3963 template->ulValueLen = (CK_ULONG)-1;
3964 return (CKR_ATTRIBUTE_TYPE_INVALID);
3965 }
3966
3967 case CKA_BASE:
3968 switch (keytype) {
3969 case CKK_DSA:
3970 return (get_bigint_attr_from_object(
3971 OBJ_PUB_DSA_BASE(object_p), template));
3972
3973 case CKK_DH:
3974 return (get_bigint_attr_from_object(
3975 OBJ_PUB_DH_BASE(object_p), template));
3976
3977 case CKK_X9_42_DH:
3978 return (get_bigint_attr_from_object(
3979 OBJ_PUB_DH942_BASE(object_p), template));
3980
3981 default:
3982 template->ulValueLen = (CK_ULONG)-1;
3983 return (CKR_ATTRIBUTE_TYPE_INVALID);
3984 }
3985
3986 case CKA_EC_POINT:
3987 return (get_bigint_attr_from_object(
3988 OBJ_PUB_EC_POINT(object_p), template));
3989
3990 case CKA_VALUE:
3991 switch (keytype) {
3992 case CKK_DSA:
3993 return (get_bigint_attr_from_object(
3994 OBJ_PUB_DSA_VALUE(object_p), template));
3995
3996 case CKK_DH:
3997 return (get_bigint_attr_from_object(
3998 OBJ_PUB_DH_VALUE(object_p), template));
3999
4000 case CKK_X9_42_DH:
4001 return (get_bigint_attr_from_object(
4002 OBJ_PUB_DH942_VALUE(object_p), template));
4003
4004 default:
4005 template->ulValueLen = (CK_ULONG)-1;
4006 return (CKR_ATTRIBUTE_TYPE_INVALID);
4007 }
4008
4009 default:
4010 /*
4011 * First, get the value of the request attribute defined
4012 * in the list of common key attributes. If the request
4013 * attribute is not found in that list, then get the
4014 * attribute from the list of common attributes.
4015 */
4016 rv = soft_get_common_key_attrs(object_p, template);
4017 if (rv == CKR_ATTRIBUTE_TYPE_INVALID) {
4018 rv = soft_get_common_attrs(object_p, template,
4019 object_p->object_type);
4020 }
4021 break;
4022 }
4023
4024 return (rv);
4025 }
4026
4027
4028 /*
4029 * Get the value of a requested attribute of a Private Key Object.
4030 *
4031 * Rule: All the attributes in the private key object can be revealed
4032 * except those marked with footnote number "7" when the object
4033 * has its CKA_SENSITIVE attribute set to TRUE or its
4034 * CKA_EXTRACTABLE attribute set to FALSE (p.88 in PKCS11 spec.).
4035 */
4036 CK_RV
4037 soft_get_private_key_attribute(soft_object_t *object_p,
4038 CK_ATTRIBUTE_PTR template)
4039 {
4040
4041 CK_RV rv = CKR_OK;
4042 CK_KEY_TYPE keytype = object_p->key_type;
4043
4044
4045 /*
4046 * If the following specified attributes for the private key
4047 * object cannot be revealed because the object is sensitive
4048 * or unextractable, then the ulValueLen is set to -1.
4049 */
4050 if ((object_p->bool_attr_mask & SENSITIVE_BOOL_ON) ||
4051 !(object_p->bool_attr_mask & EXTRACTABLE_BOOL_ON)) {
4052
4053 switch (template->type) {
4054 case CKA_PRIVATE_EXPONENT:
4055 case CKA_PRIME_1:
4056 case CKA_PRIME_2:
4057 case CKA_EXPONENT_1:
4058 case CKA_EXPONENT_2:
4059 case CKA_COEFFICIENT:
4060 case CKA_VALUE:
4061 template->ulValueLen = (CK_ULONG)-1;
4062 return (CKR_ATTRIBUTE_SENSITIVE);
4063 }
4064 }
4065
4066 switch (template->type) {
4067
4068 case CKA_SUBJECT:
4069 case CKA_EC_PARAMS:
4070 /*
4071 * The above extra attributes have byte array type.
4072 */
4073 return (get_extra_attr_from_object(object_p,
4074 template));
4075
4076 /* Key related boolean attributes */
4077 case CKA_SENSITIVE:
4078 return (get_bool_attr_from_object(object_p,
4079 SENSITIVE_BOOL_ON, template));
4080
4081 case CKA_SECONDARY_AUTH:
4082 return (get_bool_attr_from_object(object_p,
4083 SECONDARY_AUTH_BOOL_ON, template));
4084
4085 case CKA_DECRYPT:
4086 return (get_bool_attr_from_object(object_p,
4087 DECRYPT_BOOL_ON, template));
4088
4089 case CKA_SIGN:
4090 return (get_bool_attr_from_object(object_p,
4091 SIGN_BOOL_ON, template));
4092
4093 case CKA_SIGN_RECOVER:
4094 return (get_bool_attr_from_object(object_p,
4095 SIGN_RECOVER_BOOL_ON, template));
4096
4097 case CKA_UNWRAP:
4098 return (get_bool_attr_from_object(object_p,
4099 UNWRAP_BOOL_ON, template));
4100
4101 case CKA_EXTRACTABLE:
4102 return (get_bool_attr_from_object(object_p,
4103 EXTRACTABLE_BOOL_ON, template));
4104
4105 case CKA_ALWAYS_SENSITIVE:
4106 return (get_bool_attr_from_object(object_p,
4107 ALWAYS_SENSITIVE_BOOL_ON, template));
4108
4109 case CKA_NEVER_EXTRACTABLE:
4110 return (get_bool_attr_from_object(object_p,
4111 NEVER_EXTRACTABLE_BOOL_ON, template));
4112
4113 case CKA_MODULUS:
4114 if (keytype == CKK_RSA) {
4115 return (get_bigint_attr_from_object(
4116 OBJ_PRI_RSA_MOD(object_p), template));
4117 } else {
4118 template->ulValueLen = (CK_ULONG)-1;
4119 rv = CKR_ATTRIBUTE_TYPE_INVALID;
4120 break;
4121 }
4122
4123 case CKA_PUBLIC_EXPONENT:
4124 if (keytype == CKK_RSA) {
4125 return (get_bigint_attr_from_object(
4126 OBJ_PRI_RSA_PUBEXPO(object_p), template));
4127 } else {
4128 template->ulValueLen = (CK_ULONG)-1;
4129 rv = CKR_ATTRIBUTE_TYPE_INVALID;
4130 break;
4131 }
4132
4133 case CKA_PRIVATE_EXPONENT:
4134 if (keytype == CKK_RSA) {
4135 return (get_bigint_attr_from_object(
4136 OBJ_PRI_RSA_PRIEXPO(object_p), template));
4137 } else {
4138 template->ulValueLen = (CK_ULONG)-1;
4139 rv = CKR_ATTRIBUTE_TYPE_INVALID;
4140 break;
4141 }
4142
4143 case CKA_PRIME_1:
4144 if (keytype == CKK_RSA) {
4145 return (get_bigint_attr_from_object(
4146 OBJ_PRI_RSA_PRIME1(object_p), template));
4147 } else {
4148 template->ulValueLen = (CK_ULONG)-1;
4149 rv = CKR_ATTRIBUTE_TYPE_INVALID;
4150 break;
4151 }
4152
4153 case CKA_PRIME_2:
4154 if (keytype == CKK_RSA) {
4155 return (get_bigint_attr_from_object(
4156 OBJ_PRI_RSA_PRIME2(object_p), template));
4157 } else {
4158 template->ulValueLen = (CK_ULONG)-1;
4159 rv = CKR_ATTRIBUTE_TYPE_INVALID;
4160 break;
4161 }
4162
4163 case CKA_EXPONENT_1:
4164 if (keytype == CKK_RSA) {
4165 return (get_bigint_attr_from_object(
4166 OBJ_PRI_RSA_EXPO1(object_p), template));
4167 } else {
4168 template->ulValueLen = (CK_ULONG)-1;
4169 rv = CKR_ATTRIBUTE_TYPE_INVALID;
4170 break;
4171 }
4172
4173 case CKA_EXPONENT_2:
4174 if (keytype == CKK_RSA) {
4175 return (get_bigint_attr_from_object(
4176 OBJ_PRI_RSA_EXPO2(object_p), template));
4177 } else {
4178 template->ulValueLen = (CK_ULONG)-1;
4179 rv = CKR_ATTRIBUTE_TYPE_INVALID;
4180 break;
4181 }
4182
4183 case CKA_COEFFICIENT:
4184 if (keytype == CKK_RSA) {
4185 return (get_bigint_attr_from_object(
4186 OBJ_PRI_RSA_COEF(object_p), template));
4187 } else {
4188 template->ulValueLen = (CK_ULONG)-1;
4189 rv = CKR_ATTRIBUTE_TYPE_INVALID;
4190 break;
4191 }
4192
4193 case CKA_VALUE_BITS:
4194 if (keytype == CKK_DH) {
4195 return (get_ulong_attr_from_object(
4196 OBJ_PRI_DH_VAL_BITS(object_p), template));
4197 } else {
4198 template->ulValueLen = (CK_ULONG)-1;
4199 rv = CKR_ATTRIBUTE_TYPE_INVALID;
4200 break;
4201 }
4202
4203 case CKA_PRIME:
4204 switch (keytype) {
4205 case CKK_DSA:
4206 return (get_bigint_attr_from_object(
4207 OBJ_PRI_DSA_PRIME(object_p), template));
4208
4209 case CKK_DH:
4210 return (get_bigint_attr_from_object(
4211 OBJ_PRI_DH_PRIME(object_p), template));
4212
4213 case CKK_X9_42_DH:
4214 return (get_bigint_attr_from_object(
4215 OBJ_PRI_DH942_PRIME(object_p), template));
4216
4217 default:
4218 template->ulValueLen = (CK_ULONG)-1;
4219 return (CKR_ATTRIBUTE_TYPE_INVALID);
4220 }
4221
4222 case CKA_SUBPRIME:
4223 switch (keytype) {
4224 case CKK_DSA:
4225 return (get_bigint_attr_from_object(
4226 OBJ_PRI_DSA_SUBPRIME(object_p), template));
4227
4228 case CKK_X9_42_DH:
4229 return (get_bigint_attr_from_object(
4230 OBJ_PRI_DH942_SUBPRIME(object_p), template));
4231
4232 default:
4233 template->ulValueLen = (CK_ULONG)-1;
4234 return (CKR_ATTRIBUTE_TYPE_INVALID);
4235 }
4236
4237 case CKA_BASE:
4238 switch (keytype) {
4239 case CKK_DSA:
4240 return (get_bigint_attr_from_object(
4241 OBJ_PRI_DSA_BASE(object_p), template));
4242
4243 case CKK_DH:
4244 return (get_bigint_attr_from_object(
4245 OBJ_PRI_DH_BASE(object_p), template));
4246
4247 case CKK_X9_42_DH:
4248 return (get_bigint_attr_from_object(
4249 OBJ_PRI_DH942_BASE(object_p), template));
4250
4251 default:
4252 template->ulValueLen = (CK_ULONG)-1;
4253 return (CKR_ATTRIBUTE_TYPE_INVALID);
4254 }
4255
4256 case CKA_VALUE:
4257 switch (keytype) {
4258 case CKK_DSA:
4259 return (get_bigint_attr_from_object(
4260 OBJ_PRI_DSA_VALUE(object_p), template));
4261
4262 case CKK_DH:
4263 return (get_bigint_attr_from_object(
4264 OBJ_PRI_DH_VALUE(object_p), template));
4265
4266 case CKK_X9_42_DH:
4267 return (get_bigint_attr_from_object(
4268 OBJ_PRI_DH942_VALUE(object_p), template));
4269
4270 case CKK_EC:
4271 return (get_bigint_attr_from_object(
4272 OBJ_PRI_EC_VALUE(object_p), template));
4273
4274 default:
4275 template->ulValueLen = (CK_ULONG)-1;
4276 return (CKR_ATTRIBUTE_TYPE_INVALID);
4277 }
4278
4279 default:
4280 /*
4281 * First, get the value of the request attribute defined
4282 * in the list of common key attributes. If the request
4283 * attribute is not found in that list, then get the
4284 * attribute from the list of common attributes.
4285 */
4286 rv = soft_get_common_key_attrs(object_p, template);
4287 if (rv == CKR_ATTRIBUTE_TYPE_INVALID) {
4288 rv = soft_get_common_attrs(object_p, template,
4289 object_p->object_type);
4290 }
4291 break;
4292 }
4293
4294 return (rv);
4295 }
4296
4297
4298 /*
4299 * Get the value of a requested attribute of a Secret Key Object.
4300 *
4301 * Rule: All the attributes in the secret key object can be revealed
4302 * except those marked with footnote number "7" when the object
4303 * has its CKA_SENSITIVE attribute set to TRUE or its
4304 * CKA_EXTRACTABLE attribute set to FALSE (p.88 in PKCS11 spec.).
4305 */
4306 CK_RV
4307 soft_get_secret_key_attribute(soft_object_t *object_p,
4308 CK_ATTRIBUTE_PTR template)
4309 {
4310
4311 CK_RV rv = CKR_OK;
4312 CK_KEY_TYPE keytype = object_p->key_type;
4313
4314 switch (template->type) {
4315
4316 /* Key related boolean attributes */
4317 case CKA_SENSITIVE:
4318 return (get_bool_attr_from_object(object_p,
4319 SENSITIVE_BOOL_ON, template));
4320
4321 case CKA_ENCRYPT:
4322 return (get_bool_attr_from_object(object_p,
4323 ENCRYPT_BOOL_ON, template));
4324
4325 case CKA_DECRYPT:
4326 return (get_bool_attr_from_object(object_p,
4327 DECRYPT_BOOL_ON, template));
4328
4329 case CKA_SIGN:
4330 return (get_bool_attr_from_object(object_p,
4331 SIGN_BOOL_ON, template));
4332
4333 case CKA_VERIFY:
4334 return (get_bool_attr_from_object(object_p,
4335 VERIFY_BOOL_ON, template));
4336
4337 case CKA_WRAP:
4338 return (get_bool_attr_from_object(object_p,
4339 WRAP_BOOL_ON, template));
4340
4341 case CKA_UNWRAP:
4342 return (get_bool_attr_from_object(object_p,
4343 UNWRAP_BOOL_ON, template));
4344
4345 case CKA_EXTRACTABLE:
4346 return (get_bool_attr_from_object(object_p,
4347 EXTRACTABLE_BOOL_ON, template));
4348
4349 case CKA_ALWAYS_SENSITIVE:
4350 return (get_bool_attr_from_object(object_p,
4351 ALWAYS_SENSITIVE_BOOL_ON, template));
4352
4353 case CKA_NEVER_EXTRACTABLE:
4354 return (get_bool_attr_from_object(object_p,
4355 NEVER_EXTRACTABLE_BOOL_ON, template));
4356
4357 case CKA_VALUE:
4358 case CKA_VALUE_LEN:
4359 /*
4360 * If the specified attribute for the secret key object
4361 * cannot be revealed because the object is sensitive
4362 * or unextractable, then the ulValueLen is set to -1.
4363 */
4364 if ((object_p->bool_attr_mask & SENSITIVE_BOOL_ON) ||
4365 !(object_p->bool_attr_mask & EXTRACTABLE_BOOL_ON)) {
4366 template->ulValueLen = (CK_ULONG)-1;
4367 return (CKR_ATTRIBUTE_SENSITIVE);
4368 }
4369
4370 switch (keytype) {
4371 case CKK_RC4:
4372 case CKK_GENERIC_SECRET:
4373 case CKK_RC5:
4374 case CKK_DES:
4375 case CKK_DES2:
4376 case CKK_DES3:
4377 case CKK_CDMF:
4378 case CKK_AES:
4379 case CKK_BLOWFISH:
4380 if (template->type == CKA_VALUE_LEN) {
4381 return (get_ulong_attr_from_object(
4382 OBJ_SEC_VALUE_LEN(object_p),
4383 template));
4384 } else {
4385 return (get_bigint_attr_from_object(
4386 (biginteger_t *)OBJ_SEC(object_p),
4387 template));
4388 }
4389 default:
4390 template->ulValueLen = (CK_ULONG)-1;
4391 rv = CKR_ATTRIBUTE_TYPE_INVALID;
4392 break;
4393 }
4394 break;
4395
4396 default:
4397 /*
4398 * First, get the value of the request attribute defined
4399 * in the list of common key attributes. If the request
4400 * attribute is not found in that list, then get the
4401 * attribute from the list of common attributes.
4402 */
4403 rv = soft_get_common_key_attrs(object_p, template);
4404 if (rv == CKR_ATTRIBUTE_TYPE_INVALID) {
4405 rv = soft_get_common_attrs(object_p, template,
4406 object_p->object_type);
4407 }
4408 break;
4409 }
4410
4411 return (rv);
4412 }
4413
4414
4415 /*
4416 * Get the value of a requested attribute of a Domain Parameters Object.
4417 *
4418 * Rule: All the attributes in the domain parameters object can be revealed.
4419 */
4420 CK_RV
4421 soft_get_domain_parameters_attribute(soft_object_t *object_p,
4422 CK_ATTRIBUTE_PTR template)
4423 {
4424
4425 CK_RV rv = CKR_OK;
4426 CK_KEY_TYPE keytype = object_p->key_type;
4427
4428 switch (template->type) {
4429
4430 case CKA_KEY_TYPE:
4431 return (get_ulong_attr_from_object(keytype,
4432 template));
4433
4434 case CKA_LOCAL:
4435 return (get_bool_attr_from_object(object_p,
4436 LOCAL_BOOL_ON, template));
4437
4438 case CKA_PRIME:
4439 switch (keytype) {
4440 case CKK_DSA:
4441 return (get_bigint_attr_from_object(
4442 OBJ_DOM_DSA_PRIME(object_p), template));
4443
4444 case CKK_DH:
4445 return (get_bigint_attr_from_object(
4446 OBJ_DOM_DH_PRIME(object_p), template));
4447
4448 case CKK_X9_42_DH:
4449 return (get_bigint_attr_from_object(
4450 OBJ_DOM_DH942_PRIME(object_p), template));
4451
4452 default:
4453 template->ulValueLen = (CK_ULONG)-1;
4454 return (CKR_ATTRIBUTE_TYPE_INVALID);
4455 }
4456
4457 case CKA_SUBPRIME:
4458 switch (keytype) {
4459 case CKK_DSA:
4460 return (get_bigint_attr_from_object(
4461 OBJ_DOM_DSA_SUBPRIME(object_p), template));
4462
4463 case CKK_X9_42_DH:
4464 return (get_bigint_attr_from_object(
4465 OBJ_DOM_DH942_SUBPRIME(object_p), template));
4466
4467 default:
4468 template->ulValueLen = (CK_ULONG)-1;
4469 return (CKR_ATTRIBUTE_TYPE_INVALID);
4470 }
4471
4472 case CKA_BASE:
4473 switch (keytype) {
4474 case CKK_DSA:
4475 return (get_bigint_attr_from_object(
4476 OBJ_DOM_DSA_BASE(object_p), template));
4477
4478 case CKK_DH:
4479 return (get_bigint_attr_from_object(
4480 OBJ_DOM_DH_BASE(object_p), template));
4481
4482 case CKK_X9_42_DH:
4483 return (get_bigint_attr_from_object(
4484 OBJ_DOM_DH942_BASE(object_p), template));
4485
4486 default:
4487 template->ulValueLen = (CK_ULONG)-1;
4488 return (CKR_ATTRIBUTE_TYPE_INVALID);
4489 }
4490
4491 case CKA_PRIME_BITS:
4492 switch (keytype) {
4493 case CKK_DSA:
4494 return (get_ulong_attr_from_object(
4495 OBJ_DOM_DSA_PRIME_BITS(object_p), template));
4496
4497 case CKK_DH:
4498 return (get_ulong_attr_from_object(
4499 OBJ_DOM_DH_PRIME_BITS(object_p), template));
4500
4501 case CKK_X9_42_DH:
4502 return (get_ulong_attr_from_object(
4503 OBJ_DOM_DH942_PRIME_BITS(object_p), template));
4504
4505 default:
4506 template->ulValueLen = (CK_ULONG)-1;
4507 return (CKR_ATTRIBUTE_TYPE_INVALID);
4508 }
4509
4510 case CKA_SUB_PRIME_BITS:
4511 switch (keytype) {
4512 case CKK_X9_42_DH:
4513 return (get_ulong_attr_from_object(
4514 OBJ_DOM_DH942_SUBPRIME_BITS(object_p), template));
4515
4516 default:
4517 template->ulValueLen = (CK_ULONG)-1;
4518 return (CKR_ATTRIBUTE_TYPE_INVALID);
4519 }
4520
4521 default:
4522 /*
4523 * Get the value of a common attribute.
4524 */
4525 rv = soft_get_common_attrs(object_p, template,
4526 object_p->object_type);
4527 break;
4528 }
4529
4530 return (rv);
4531 }
4532
4533 /*
4534 * Get certificate attributes from an object.
4535 * return CKR_ATTRIBUTE_TYPE_INVALID if the requested type
4536 * does not exist in the certificate.
4537 */
4538 CK_RV
4539 soft_get_certificate_attribute(soft_object_t *object_p,
4540 CK_ATTRIBUTE_PTR template)
4541 {
4542 CK_CERTIFICATE_TYPE certtype = object_p->cert_type;
4543 cert_attr_t src;
4544
4545 switch (template->type) {
4546 case CKA_SUBJECT:
4547 if (certtype == CKC_X_509) {
4548 return (get_cert_attr_from_object(
4549 X509_CERT_SUBJECT(object_p), template));
4550 }
4551 break;
4552 case CKA_VALUE:
4553 if (certtype == CKC_X_509) {
4554 return (get_cert_attr_from_object(
4555 X509_CERT_VALUE(object_p), template));
4556 } else if (certtype == CKC_X_509_ATTR_CERT) {
4557 return (get_cert_attr_from_object(
4558 X509_ATTR_CERT_VALUE(object_p), template));
4559 }
4560 break;
4561 case CKA_OWNER:
4562 if (certtype == CKC_X_509_ATTR_CERT) {
4563 return (get_cert_attr_from_object(
4564 X509_ATTR_CERT_OWNER(object_p), template));
4565 }
4566 break;
4567 case CKA_CERTIFICATE_TYPE:
4568 src.value = (CK_BYTE *)&certtype;
4569 src.length = sizeof (certtype);
4570 return (get_cert_attr_from_object(&src, template));
4571 break;
4572 case CKA_TRUSTED:
4573 return (get_bool_attr_from_object(object_p,
4574 TRUSTED_BOOL_ON, template));
4575 case CKA_ID:
4576 case CKA_ISSUER:
4577 case CKA_SERIAL_NUMBER:
4578 case CKA_AC_ISSUER:
4579 case CKA_ATTR_TYPES:
4580 return (get_extra_attr_from_object(object_p,
4581 template));
4582 break;
4583 default:
4584 return (soft_get_common_attrs(object_p, template,
4585 object_p->object_type));
4586 break;
4587 }
4588
4589 /*
4590 * If we got this far, then the combination of certificate type
4591 * and requested attribute is invalid.
4592 */
4593 return (CKR_ATTRIBUTE_TYPE_INVALID);
4594 }
4595
4596 CK_RV
4597 soft_set_certificate_attribute(soft_object_t *object_p,
4598 CK_ATTRIBUTE_PTR template, boolean_t copy)
4599 {
4600 CK_CERTIFICATE_TYPE certtype = object_p->cert_type;
4601
4602 switch (template->type) {
4603 case CKA_SUBJECT:
4604 if (certtype == CKC_X_509) {
4605 /* SUBJECT attr cannot be modified. */
4606 return (CKR_ATTRIBUTE_READ_ONLY);
4607 }
4608 break;
4609 case CKA_OWNER:
4610 if (certtype == CKC_X_509_ATTR_CERT) {
4611 /* OWNER attr cannot be modified. */
4612 return (CKR_ATTRIBUTE_READ_ONLY);
4613 }
4614 break;
4615 case CKA_VALUE:
4616 /* VALUE attr cannot be modified. */
4617 return (CKR_ATTRIBUTE_READ_ONLY);
4618 break;
4619 case CKA_ID:
4620 case CKA_ISSUER:
4621 if (certtype == CKC_X_509) {
4622 return (set_extra_attr_to_object(object_p,
4623 template->type, template));
4624 }
4625 break;
4626 case CKA_AC_ISSUER:
4627 case CKA_ATTR_TYPES:
4628 if (certtype == CKC_X_509_ATTR_CERT) {
4629 return (set_extra_attr_to_object(object_p,
4630 template->type, template));
4631 }
4632 break;
4633 case CKA_SERIAL_NUMBER:
4634 case CKA_LABEL:
4635 return (set_extra_attr_to_object(object_p,
4636 template->type, template));
4637 break;
4638 default:
4639 return (soft_set_common_storage_attribute(
4640 object_p, template, copy));
4641 break;
4642 }
4643
4644 /*
4645 * If we got this far, then the combination of certificate type
4646 * and requested attribute is invalid.
4647 */
4648 return (CKR_ATTRIBUTE_TYPE_INVALID);
4649 }
4650
4651 /*
4652 * Call the appropriate get attribute function according to the class
4653 * of object.
4654 *
4655 * The caller of this function holds the lock on the object.
4656 */
4657 CK_RV
4658 soft_get_attribute(soft_object_t *object_p, CK_ATTRIBUTE_PTR template)
4659 {
4660
4661 CK_RV rv = CKR_OK;
4662 CK_OBJECT_CLASS class = object_p->class;
4663
4664 switch (class) {
4665 case CKO_PUBLIC_KEY:
4666 rv = soft_get_public_key_attribute(object_p, template);
4667 break;
4668
4669 case CKO_PRIVATE_KEY:
4670 rv = soft_get_private_key_attribute(object_p, template);
4671 break;
4672
4673 case CKO_SECRET_KEY:
4674 rv = soft_get_secret_key_attribute(object_p, template);
4675 break;
4676
4677 case CKO_DOMAIN_PARAMETERS:
4678 rv = soft_get_domain_parameters_attribute(object_p, template);
4679 break;
4680
4681 case CKO_CERTIFICATE:
4682 rv = soft_get_certificate_attribute(object_p, template);
4683 break;
4684
4685 default:
4686 /*
4687 * If the specified attribute for the object is invalid
4688 * (the object does not possess such as attribute), then
4689 * the ulValueLen is modified to hold the value -1.
4690 */
4691 template->ulValueLen = (CK_ULONG)-1;
4692 return (CKR_ATTRIBUTE_TYPE_INVALID);
4693 }
4694
4695 return (rv);
4696
4697 }
4698
4699 CK_RV
4700 soft_set_common_storage_attribute(soft_object_t *object_p,
4701 CK_ATTRIBUTE_PTR template, boolean_t copy)
4702 {
4703
4704 CK_RV rv = CKR_OK;
4705
4706 switch (template->type) {
4707
4708 case CKA_TOKEN:
4709 if (copy) {
4710 if ((*(CK_BBOOL *)template->pValue) == B_TRUE) {
4711 if (!soft_keystore_status(KEYSTORE_INITIALIZED))
4712 return (CKR_DEVICE_REMOVED);
4713 object_p->object_type |= TOKEN_OBJECT;
4714 }
4715 } else {
4716 rv = CKR_ATTRIBUTE_READ_ONLY;
4717 }
4718
4719 break;
4720
4721 case CKA_PRIVATE:
4722 if (copy) {
4723 if ((*(CK_BBOOL *)template->pValue) == B_TRUE) {
4724 (void) pthread_mutex_lock(&soft_giant_mutex);
4725 if (!soft_slot.authenticated) {
4726 /*
4727 * Check if this is the special case
4728 * when the PIN is never initialized
4729 * in the keystore. If true, we will
4730 * let it pass here and let it fail
4731 * with CKR_PIN_EXPIRED later on.
4732 */
4733 if (!soft_slot.userpin_change_needed) {
4734 (void) pthread_mutex_unlock(
4735 &soft_giant_mutex);
4736 return (CKR_USER_NOT_LOGGED_IN);
4737 }
4738 }
4739 (void) pthread_mutex_unlock(&soft_giant_mutex);
4740 object_p->object_type |= PRIVATE_OBJECT;
4741 }
4742 } else {
4743 rv = CKR_ATTRIBUTE_READ_ONLY;
4744 }
4745 break;
4746
4747 case CKA_MODIFIABLE:
4748 if (copy) {
4749 if ((*(CK_BBOOL *)template->pValue) == TRUE)
4750 object_p->bool_attr_mask &=
4751 ~NOT_MODIFIABLE_BOOL_ON;
4752 else
4753 object_p->bool_attr_mask |=
4754 NOT_MODIFIABLE_BOOL_ON;
4755 } else {
4756 rv = CKR_ATTRIBUTE_READ_ONLY;
4757 }
4758 break;
4759
4760 case CKA_CLASS:
4761 rv = CKR_ATTRIBUTE_READ_ONLY;
4762 break;
4763
4764 default:
4765 rv = CKR_TEMPLATE_INCONSISTENT;
4766 }
4767
4768 return (rv);
4769 }
4770
4771 /*
4772 * Set the value of an attribute that is common to all key objects
4773 * (i.e. public key, private key and secret key).
4774 */
4775 CK_RV
4776 soft_set_common_key_attribute(soft_object_t *object_p,
4777 CK_ATTRIBUTE_PTR template, boolean_t copy)
4778 {
4779
4780 switch (template->type) {
4781
4782 case CKA_LABEL:
4783 /*
4784 * Only the LABEL can be modified in the common storage
4785 * object attributes after the object is created.
4786 */
4787 return (set_extra_attr_to_object(object_p,
4788 CKA_LABEL, template));
4789
4790 case CKA_ID:
4791 return (set_extra_attr_to_object(object_p,
4792 CKA_ID, template));
4793
4794 case CKA_START_DATE:
4795 return (set_extra_attr_to_object(object_p,
4796 CKA_START_DATE, template));
4797
4798 case CKA_END_DATE:
4799 return (set_extra_attr_to_object(object_p,
4800 CKA_END_DATE, template));
4801
4802 case CKA_DERIVE:
4803 return (set_bool_attr_to_object(object_p,
4804 DERIVE_BOOL_ON, template));
4805
4806 case CKA_KEY_TYPE:
4807 case CKA_LOCAL:
4808 case CKA_KEY_GEN_MECHANISM:
4809 return (CKR_ATTRIBUTE_READ_ONLY);
4810
4811 default:
4812 return (soft_set_common_storage_attribute(object_p,
4813 template, copy));
4814
4815 }
4816
4817 }
4818
4819
4820 /*
4821 * Set the value of an attribute of a Public Key Object.
4822 *
4823 * Rule: The attributes marked with footnote number "8" in the PKCS11
4824 * spec may be modified (p.88 in PKCS11 spec.).
4825 */
4826 CK_RV
4827 soft_set_public_key_attribute(soft_object_t *object_p,
4828 CK_ATTRIBUTE_PTR template, boolean_t copy)
4829 {
4830 CK_KEY_TYPE keytype = object_p->key_type;
4831
4832 switch (template->type) {
4833
4834 case CKA_SUBJECT:
4835 return (set_extra_attr_to_object(object_p,
4836 CKA_SUBJECT, template));
4837
4838 case CKA_ENCRYPT:
4839 return (set_bool_attr_to_object(object_p,
4840 ENCRYPT_BOOL_ON, template));
4841
4842 case CKA_VERIFY:
4843 return (set_bool_attr_to_object(object_p,
4844 VERIFY_BOOL_ON, template));
4845
4846 case CKA_VERIFY_RECOVER:
4847 return (set_bool_attr_to_object(object_p,
4848 VERIFY_RECOVER_BOOL_ON, template));
4849
4850 case CKA_WRAP:
4851 return (set_bool_attr_to_object(object_p,
4852 WRAP_BOOL_ON, template));
4853
4854 case CKA_MODULUS:
4855 case CKA_MODULUS_BITS:
4856 case CKA_PUBLIC_EXPONENT:
4857 if (keytype == CKK_RSA)
4858 return (CKR_ATTRIBUTE_READ_ONLY);
4859 break;
4860
4861 case CKA_SUBPRIME:
4862 if ((keytype == CKK_DSA) ||
4863 (keytype == CKK_X9_42_DH))
4864 return (CKR_ATTRIBUTE_READ_ONLY);
4865 break;
4866
4867 case CKA_PRIME:
4868 case CKA_BASE:
4869 case CKA_VALUE:
4870 if ((keytype == CKK_DSA) ||
4871 (keytype == CKK_DH) ||
4872 (keytype == CKK_X9_42_DH))
4873 return (CKR_ATTRIBUTE_READ_ONLY);
4874 break;
4875
4876 default:
4877 /*
4878 * Set the value of a common key attribute.
4879 */
4880 return (soft_set_common_key_attribute(object_p,
4881 template, copy));
4882
4883 }
4884 /*
4885 * If we got this far, then the combination of key type
4886 * and requested attribute is invalid.
4887 */
4888 return (CKR_ATTRIBUTE_TYPE_INVALID);
4889 }
4890
4891
4892 /*
4893 * Set the value of an attribute of a Private Key Object.
4894 *
4895 * Rule: The attributes marked with footnote number "8" in the PKCS11
4896 * spec may be modified (p.88 in PKCS11 spec.).
4897 */
4898 CK_RV
4899 soft_set_private_key_attribute(soft_object_t *object_p,
4900 CK_ATTRIBUTE_PTR template, boolean_t copy)
4901 {
4902 CK_KEY_TYPE keytype = object_p->key_type;
4903
4904 switch (template->type) {
4905
4906 case CKA_SUBJECT:
4907 return (set_extra_attr_to_object(object_p,
4908 CKA_SUBJECT, template));
4909
4910 case CKA_SENSITIVE:
4911 /*
4912 * Cannot set SENSITIVE to FALSE if it is already ON.
4913 */
4914 if (((*(CK_BBOOL *)template->pValue) == B_FALSE) &&
4915 (object_p->bool_attr_mask & SENSITIVE_BOOL_ON)) {
4916 return (CKR_ATTRIBUTE_READ_ONLY);
4917 }
4918
4919 if (*(CK_BBOOL *)template->pValue)
4920 object_p->bool_attr_mask |= SENSITIVE_BOOL_ON;
4921 return (CKR_OK);
4922
4923 case CKA_DECRYPT:
4924 return (set_bool_attr_to_object(object_p,
4925 DECRYPT_BOOL_ON, template));
4926
4927 case CKA_SIGN:
4928 return (set_bool_attr_to_object(object_p,
4929 SIGN_BOOL_ON, template));
4930
4931 case CKA_SIGN_RECOVER:
4932 return (set_bool_attr_to_object(object_p,
4933 SIGN_RECOVER_BOOL_ON, template));
4934
4935 case CKA_UNWRAP:
4936 return (set_bool_attr_to_object(object_p,
4937 UNWRAP_BOOL_ON, template));
4938
4939 case CKA_EXTRACTABLE:
4940 /*
4941 * Cannot set EXTRACTABLE to TRUE if it is already OFF.
4942 */
4943 if ((*(CK_BBOOL *)template->pValue) &&
4944 !(object_p->bool_attr_mask & EXTRACTABLE_BOOL_ON)) {
4945 return (CKR_ATTRIBUTE_READ_ONLY);
4946 }
4947
4948 if ((*(CK_BBOOL *)template->pValue) == B_FALSE)
4949 object_p->bool_attr_mask &= ~EXTRACTABLE_BOOL_ON;
4950 return (CKR_OK);
4951
4952 case CKA_MODULUS:
4953 case CKA_PUBLIC_EXPONENT:
4954 case CKA_PRIVATE_EXPONENT:
4955 case CKA_PRIME_1:
4956 case CKA_PRIME_2:
4957 case CKA_EXPONENT_1:
4958 case CKA_EXPONENT_2:
4959 case CKA_COEFFICIENT:
4960 if (keytype == CKK_RSA) {
4961 return (CKR_ATTRIBUTE_READ_ONLY);
4962 }
4963 break;
4964
4965 case CKA_SUBPRIME:
4966 if ((keytype == CKK_DSA) ||
4967 (keytype == CKK_X9_42_DH))
4968 return (CKR_ATTRIBUTE_READ_ONLY);
4969 break;
4970
4971 case CKA_PRIME:
4972 case CKA_BASE:
4973 case CKA_VALUE:
4974 if ((keytype == CKK_DSA) ||
4975 (keytype == CKK_DH) ||
4976 (keytype == CKK_X9_42_DH))
4977 return (CKR_ATTRIBUTE_READ_ONLY);
4978 break;
4979
4980 case CKA_VALUE_BITS:
4981 if (keytype == CKK_DH)
4982 return (CKR_ATTRIBUTE_READ_ONLY);
4983 break;
4984
4985 default:
4986 /*
4987 * Set the value of a common key attribute.
4988 */
4989 return (soft_set_common_key_attribute(object_p,
4990 template, copy));
4991 }
4992
4993 /*
4994 * If we got this far, then the combination of key type
4995 * and requested attribute is invalid.
4996 */
4997 return (CKR_ATTRIBUTE_TYPE_INVALID);
4998 }
4999
5000 /*
5001 * Set the value of an attribute of a Secret Key Object.
5002 *
5003 * Rule: The attributes marked with footnote number "8" in the PKCS11
5004 * spec may be modified (p.88 in PKCS11 spec.).
5005 */
5006 CK_RV
5007 soft_set_secret_key_attribute(soft_object_t *object_p,
5008 CK_ATTRIBUTE_PTR template, boolean_t copy)
5009 {
5010 CK_KEY_TYPE keytype = object_p->key_type;
5011
5012 switch (template->type) {
5013
5014 case CKA_SENSITIVE:
5015 /*
5016 * Cannot set SENSITIVE to FALSE if it is already ON.
5017 */
5018 if (((*(CK_BBOOL *)template->pValue) == B_FALSE) &&
5019 (object_p->bool_attr_mask & SENSITIVE_BOOL_ON)) {
5020 return (CKR_ATTRIBUTE_READ_ONLY);
5021 }
5022
5023 if (*(CK_BBOOL *)template->pValue)
5024 object_p->bool_attr_mask |= SENSITIVE_BOOL_ON;
5025 return (CKR_OK);
5026
5027 case CKA_ENCRYPT:
5028 return (set_bool_attr_to_object(object_p,
5029 ENCRYPT_BOOL_ON, template));
5030
5031 case CKA_DECRYPT:
5032 return (set_bool_attr_to_object(object_p,
5033 DECRYPT_BOOL_ON, template));
5034
5035 case CKA_SIGN:
5036 return (set_bool_attr_to_object(object_p,
5037 SIGN_BOOL_ON, template));
5038
5039 case CKA_VERIFY:
5040 return (set_bool_attr_to_object(object_p,
5041 VERIFY_BOOL_ON, template));
5042
5043 case CKA_WRAP:
5044 return (set_bool_attr_to_object(object_p,
5045 WRAP_BOOL_ON, template));
5046
5047 case CKA_UNWRAP:
5048 return (set_bool_attr_to_object(object_p,
5049 UNWRAP_BOOL_ON, template));
5050
5051 case CKA_EXTRACTABLE:
5052 /*
5053 * Cannot set EXTRACTABLE to TRUE if it is already OFF.
5054 */
5055 if ((*(CK_BBOOL *)template->pValue) &&
5056 !(object_p->bool_attr_mask & EXTRACTABLE_BOOL_ON)) {
5057 return (CKR_ATTRIBUTE_READ_ONLY);
5058 }
5059
5060 if ((*(CK_BBOOL *)template->pValue) == B_FALSE)
5061 object_p->bool_attr_mask &= ~EXTRACTABLE_BOOL_ON;
5062 return (CKR_OK);
5063
5064 case CKA_VALUE:
5065 return (CKR_ATTRIBUTE_READ_ONLY);
5066
5067 case CKA_VALUE_LEN:
5068 if ((keytype == CKK_RC4) ||
5069 (keytype == CKK_GENERIC_SECRET) ||
5070 (keytype == CKK_AES) ||
5071 (keytype == CKK_BLOWFISH))
5072 return (CKR_ATTRIBUTE_READ_ONLY);
5073 break;
5074
5075 default:
5076 /*
5077 * Set the value of a common key attribute.
5078 */
5079 return (soft_set_common_key_attribute(object_p,
5080 template, copy));
5081
5082 }
5083 /*
5084 * If we got this far, then the combination of key type
5085 * and requested attribute is invalid.
5086 */
5087 return (CKR_ATTRIBUTE_TYPE_INVALID);
5088 }
5089
5090
5091 /*
5092 * Call the appropriate set attribute function according to the class
5093 * of object.
5094 *
5095 * The caller of this function does not hold the lock on the original
5096 * object, since this function is setting the attribute on the new object
5097 * that is being modified.
5098 *
5099 * Argument copy: TRUE when called by C_CopyObject,
5100 * FALSE when called by C_SetAttributeValue.
5101 */
5102 CK_RV
5103 soft_set_attribute(soft_object_t *object_p, CK_ATTRIBUTE_PTR template,
5104 boolean_t copy)
5105 {
5106
5107 CK_RV rv = CKR_OK;
5108 CK_OBJECT_CLASS class = object_p->class;
5109
5110 switch (class) {
5111
5112 case CKO_PUBLIC_KEY:
5113 rv = soft_set_public_key_attribute(object_p, template, copy);
5114 break;
5115
5116 case CKO_PRIVATE_KEY:
5117 rv = soft_set_private_key_attribute(object_p, template, copy);
5118 break;
5119
5120 case CKO_SECRET_KEY:
5121 rv = soft_set_secret_key_attribute(object_p, template, copy);
5122 break;
5123
5124 case CKO_DOMAIN_PARAMETERS:
5125 switch (template->type) {
5126 case CKA_LABEL:
5127 /*
5128 * Only the LABEL can be modified in the common
5129 * storage object attributes after the object is
5130 * created.
5131 */
5132 return (set_extra_attr_to_object(object_p,
5133 CKA_LABEL, template));
5134 default:
5135 return (CKR_TEMPLATE_INCONSISTENT);
5136 }
5137 case CKO_CERTIFICATE:
5138 rv = soft_set_certificate_attribute(object_p, template, copy);
5139 break;
5140
5141 default:
5142 /*
5143 * If the template specifies a value of an attribute
5144 * which is incompatible with other existing attributes
5145 * of the object, then fails with return code
5146 * CKR_TEMPLATE_INCONSISTENT.
5147 */
5148 rv = CKR_TEMPLATE_INCONSISTENT;
5149 break;
5150 }
5151
5152 return (rv);
5153 }
5154
5155 CK_RV
5156 soft_get_public_value(soft_object_t *key, CK_ATTRIBUTE_TYPE type,
5157 uchar_t *value, uint32_t *value_len)
5158 {
5159 uint32_t len = 0;
5160 switch (type) {
5161
5162 /* The following attributes belong to RSA */
5163 case CKA_MODULUS:
5164 #ifdef __sparcv9
5165 len =
5166 /* LINTED */
5167 (uint32_t)
5168 ((biginteger_t *)OBJ_PUB_RSA_MOD(key))->big_value_len;
5169 #else /* !__sparcv9 */
5170 len =
5171 ((biginteger_t *)OBJ_PUB_RSA_MOD(key))->big_value_len;
5172 #endif /* __sparcv9 */
5173
5174 /* This attribute MUST BE set */
5175 if (len == 0 || len > *value_len) {
5176 return (CKR_ATTRIBUTE_VALUE_INVALID);
5177 }
5178 *value_len = len;
5179
5180 (void) memcpy(value,
5181 ((biginteger_t *)OBJ_PUB_RSA_MOD(key))->big_value,
5182 *value_len);
5183
5184 break;
5185
5186 case CKA_PUBLIC_EXPONENT:
5187 #ifdef __sparcv9
5188 len =
5189 /* LINTED */
5190 (uint32_t)
5191 ((biginteger_t *)OBJ_PUB_RSA_PUBEXPO(key))->big_value_len;
5192 #else /* !__sparcv9 */
5193 len =
5194 ((biginteger_t *)OBJ_PUB_RSA_PUBEXPO(key))->big_value_len;
5195 #endif /* __sparcv9 */
5196
5197 /* This attribute MUST BE set */
5198 if (len == 0 || len > *value_len) {
5199 return (CKR_ATTRIBUTE_VALUE_INVALID);
5200 }
5201 *value_len = len;
5202
5203 (void) memcpy(value,
5204 ((biginteger_t *)OBJ_PUB_RSA_PUBEXPO(key))->big_value,
5205 *value_len);
5206
5207 break;
5208
5209 /* The following attributes belong to DSA and DH */
5210 case CKA_PRIME:
5211
5212 if (key->key_type == CKK_DSA)
5213 #ifdef __sparcv9
5214 len =
5215 /* LINTED */
5216 (uint32_t)
5217 ((biginteger_t *)OBJ_PUB_DSA_PRIME(key))->
5218 big_value_len;
5219 #else /* !__sparcv9 */
5220 len =
5221 ((biginteger_t *)OBJ_PUB_DSA_PRIME(key))->
5222 big_value_len;
5223 #endif /* __sparcv9 */
5224 else
5225 #ifdef __sparcv9
5226 len =
5227 /* LINTED */
5228 (uint32_t)
5229 ((biginteger_t *)OBJ_PUB_DH_PRIME(key))->
5230 big_value_len;
5231 #else /* !__sparcv9 */
5232 len =
5233 ((biginteger_t *)OBJ_PUB_DH_PRIME(key))->
5234 big_value_len;
5235 #endif /* __sparcv9 */
5236
5237 /* This attribute MUST BE set */
5238 if (len == 0 || len > *value_len) {
5239 return (CKR_ATTRIBUTE_VALUE_INVALID);
5240 }
5241 *value_len = len;
5242
5243 if (key->key_type == CKK_DSA)
5244 (void) memcpy(value,
5245 ((biginteger_t *)OBJ_PUB_DSA_PRIME(key))->big_value,
5246 *value_len);
5247 else
5248 (void) memcpy(value,
5249 ((biginteger_t *)OBJ_PUB_DH_PRIME(key))->big_value,
5250 *value_len);
5251
5252 break;
5253
5254 case CKA_SUBPRIME:
5255 #ifdef __sparcv9
5256 len =
5257 /* LINTED */
5258 (uint32_t)
5259 ((biginteger_t *)OBJ_PUB_DSA_SUBPRIME(key))->big_value_len;
5260 #else /* !__sparcv9 */
5261 len =
5262 ((biginteger_t *)OBJ_PUB_DSA_SUBPRIME(key))->big_value_len;
5263 #endif /* __sparcv9 */
5264
5265 /* This attribute MUST BE set */
5266 if (len == 0 || len > *value_len) {
5267 return (CKR_ATTRIBUTE_VALUE_INVALID);
5268 }
5269 *value_len = len;
5270
5271 (void) memcpy(value,
5272 ((biginteger_t *)OBJ_PUB_DSA_SUBPRIME(key))->big_value,
5273 *value_len);
5274
5275 break;
5276
5277 case CKA_BASE:
5278
5279 if (key->key_type == CKK_DSA)
5280 #ifdef __sparcv9
5281 len =
5282 /* LINTED */
5283 (uint32_t)
5284 ((biginteger_t *)OBJ_PUB_DSA_BASE(key))->
5285 big_value_len;
5286 #else /* !__sparcv9 */
5287 len =
5288 ((biginteger_t *)OBJ_PUB_DSA_BASE(key))->
5289 big_value_len;
5290 #endif /* __sparcv9 */
5291 else
5292 #ifdef __sparcv9
5293 len =
5294 /* LINTED */
5295 (uint32_t)
5296 ((biginteger_t *)OBJ_PUB_DH_BASE(key))->
5297 big_value_len;
5298 #else /* !__sparcv9 */
5299 len =
5300 ((biginteger_t *)OBJ_PUB_DH_BASE(key))->
5301 big_value_len;
5302 #endif /* __sparcv9 */
5303
5304 /* This attribute MUST BE set */
5305 if (len == 0 || len > *value_len) {
5306 return (CKR_ATTRIBUTE_VALUE_INVALID);
5307 }
5308 *value_len = len;
5309
5310 if (key->key_type == CKK_DSA)
5311 (void) memcpy(value,
5312 ((biginteger_t *)OBJ_PUB_DSA_BASE(key))->big_value,
5313 *value_len);
5314 else
5315 (void) memcpy(value,
5316 ((biginteger_t *)OBJ_PUB_DH_BASE(key))->big_value,
5317 *value_len);
5318 break;
5319
5320 case CKA_VALUE:
5321
5322 if (key->key_type == CKK_DSA)
5323 #ifdef __sparcv9
5324 len =
5325 /* LINTED */
5326 (uint32_t)
5327 ((biginteger_t *)OBJ_PUB_DSA_VALUE(key))->
5328 big_value_len;
5329 #else /* !__sparcv9 */
5330 len =
5331 ((biginteger_t *)OBJ_PUB_DSA_VALUE(key))->
5332 big_value_len;
5333 #endif /* __sparcv9 */
5334 else
5335 #ifdef __sparcv9
5336 len =
5337 /* LINTED */
5338 (uint32_t)
5339 ((biginteger_t *)OBJ_PUB_DH_VALUE(key))->
5340 big_value_len;
5341 #else /* !__sparcv9 */
5342 len =
5343 ((biginteger_t *)OBJ_PUB_DH_VALUE(key))->
5344 big_value_len;
5345 #endif /* __sparcv9 */
5346
5347 /* This attribute MUST BE set */
5348 if (len == 0 || len > *value_len) {
5349 return (CKR_ATTRIBUTE_VALUE_INVALID);
5350 }
5351 *value_len = len;
5352
5353 if (key->key_type == CKK_DSA)
5354 (void) memcpy(value,
5355 ((biginteger_t *)OBJ_PUB_DSA_VALUE(key))->big_value,
5356 *value_len);
5357 else
5358 (void) memcpy(value,
5359 ((biginteger_t *)OBJ_PUB_DH_VALUE(key))->big_value,
5360 *value_len);
5361
5362 break;
5363 }
5364
5365 return (CKR_OK);
5366 }
5367
5368
5369 CK_RV
5370 soft_get_private_value(soft_object_t *key, CK_ATTRIBUTE_TYPE type,
5371 uchar_t *value, uint32_t *value_len)
5372 {
5373
5374 uint32_t len = 0;
5375
5376 switch (type) {
5377
5378 /* The following attributes belong to RSA */
5379 case CKA_MODULUS:
5380 #ifdef __sparcv9
5381 len =
5382 /* LINTED */
5383 (uint32_t)
5384 ((biginteger_t *)OBJ_PRI_RSA_MOD(key))->big_value_len;
5385 #else /* !__sparcv9 */
5386 len =
5387 ((biginteger_t *)OBJ_PRI_RSA_MOD(key))->big_value_len;
5388 #endif /* __sparcv9 */
5389
5390 /* This attribute MUST BE set */
5391 if (len == 0 || len > *value_len) {
5392 return (CKR_ATTRIBUTE_VALUE_INVALID);
5393 }
5394 *value_len = len;
5395
5396 (void) memcpy(value,
5397 ((biginteger_t *)OBJ_PRI_RSA_MOD(key))->big_value,
5398 *value_len);
5399
5400 break;
5401
5402 case CKA_PRIVATE_EXPONENT:
5403 #ifdef __sparcv9
5404 len =
5405 /* LINTED */
5406 (uint32_t)
5407 ((biginteger_t *)OBJ_PRI_RSA_PRIEXPO(key))->big_value_len;
5408 #else /* !__sparcv9 */
5409 len =
5410 ((biginteger_t *)OBJ_PRI_RSA_PRIEXPO(key))->big_value_len;
5411 #endif /* __sparcv9 */
5412
5413 /* This attribute MUST BE set */
5414 if (len == 0 || len > *value_len) {
5415 return (CKR_ATTRIBUTE_VALUE_INVALID);
5416 }
5417 *value_len = len;
5418
5419 (void) memcpy(value,
5420 ((biginteger_t *)OBJ_PRI_RSA_PRIEXPO(key))->big_value,
5421 *value_len);
5422
5423 break;
5424
5425 case CKA_PRIME_1:
5426 #ifdef __sparcv9
5427 len =
5428 /* LINTED */
5429 (uint32_t)
5430 ((biginteger_t *)OBJ_PRI_RSA_PRIME1(key))->big_value_len;
5431 #else /* !__sparcv9 */
5432 len =
5433 ((biginteger_t *)OBJ_PRI_RSA_PRIME1(key))->big_value_len;
5434 #endif /* __sparcv9 */
5435
5436 if (len > *value_len) {
5437 return (CKR_ATTRIBUTE_VALUE_INVALID);
5438 }
5439 *value_len = len;
5440
5441 if (*value_len == 0) {
5442 return (CKR_OK);
5443 }
5444
5445 (void) memcpy(value,
5446 ((biginteger_t *)OBJ_PRI_RSA_PRIME1(key))->big_value,
5447 *value_len);
5448
5449 break;
5450
5451 case CKA_PRIME_2:
5452 #ifdef __sparcv9
5453 len =
5454 /* LINTED */
5455 (uint32_t)
5456 ((biginteger_t *)OBJ_PRI_RSA_PRIME2(key))->big_value_len;
5457 #else /* !__sparcv9 */
5458 len =
5459 ((biginteger_t *)OBJ_PRI_RSA_PRIME2(key))->big_value_len;
5460 #endif /* __sparcv9 */
5461
5462 if (len > *value_len) {
5463 return (CKR_ATTRIBUTE_VALUE_INVALID);
5464 }
5465 *value_len = len;
5466
5467 if (*value_len == 0) {
5468 return (CKR_OK);
5469 }
5470
5471 (void) memcpy(value,
5472 ((biginteger_t *)OBJ_PRI_RSA_PRIME2(key))->big_value,
5473 *value_len);
5474
5475 break;
5476
5477 case CKA_EXPONENT_1:
5478 #ifdef __sparcv9
5479 len =
5480 /* LINTED */
5481 (uint32_t)
5482 ((biginteger_t *)OBJ_PRI_RSA_EXPO1(key))->big_value_len;
5483 #else /* !__sparcv9 */
5484 len =
5485 ((biginteger_t *)OBJ_PRI_RSA_EXPO1(key))->big_value_len;
5486 #endif /* __sparcv9 */
5487
5488 if (len > *value_len) {
5489 return (CKR_ATTRIBUTE_VALUE_INVALID);
5490 }
5491 *value_len = len;
5492
5493 if (*value_len == 0) {
5494 return (CKR_OK);
5495 }
5496
5497 (void) memcpy(value,
5498 ((biginteger_t *)OBJ_PRI_RSA_EXPO1(key))->big_value,
5499 *value_len);
5500
5501 break;
5502
5503 case CKA_EXPONENT_2:
5504 #ifdef __sparcv9
5505 len =
5506 /* LINTED */
5507 (uint32_t)
5508 ((biginteger_t *)OBJ_PRI_RSA_EXPO2(key))->big_value_len;
5509 #else /* !__sparcv9 */
5510 len =
5511 ((biginteger_t *)OBJ_PRI_RSA_EXPO2(key))->big_value_len;
5512 #endif /* __sparcv9 */
5513
5514 if (len > *value_len) {
5515 return (CKR_ATTRIBUTE_VALUE_INVALID);
5516 }
5517 *value_len = len;
5518
5519 if (*value_len == 0) {
5520 return (CKR_OK);
5521 }
5522
5523 (void) memcpy(value,
5524 ((biginteger_t *)OBJ_PRI_RSA_EXPO2(key))->big_value,
5525 *value_len);
5526
5527 break;
5528
5529 case CKA_COEFFICIENT:
5530 #ifdef __sparcv9
5531 len =
5532 /* LINTED */
5533 (uint32_t)
5534 ((biginteger_t *)OBJ_PRI_RSA_COEF(key))->big_value_len;
5535 #else /* !__sparcv9 */
5536 len =
5537 ((biginteger_t *)OBJ_PRI_RSA_COEF(key))->big_value_len;
5538 #endif /* __sparcv9 */
5539
5540 if (len > *value_len) {
5541 return (CKR_ATTRIBUTE_VALUE_INVALID);
5542 }
5543 *value_len = len;
5544
5545 if (*value_len == 0) {
5546 return (CKR_OK);
5547 }
5548
5549 (void) memcpy(value,
5550 ((biginteger_t *)OBJ_PRI_RSA_COEF(key))->big_value,
5551 *value_len);
5552
5553 break;
5554
5555 /* The following attributes belong to DSA and DH */
5556 case CKA_PRIME:
5557
5558 if (key->key_type == CKK_DSA)
5559 #ifdef __sparcv9
5560 len =
5561 /* LINTED */
5562 (uint32_t)
5563 ((biginteger_t *)OBJ_PRI_DSA_PRIME(key))->
5564 big_value_len;
5565 #else /* !__sparcv9 */
5566 len =
5567 ((biginteger_t *)OBJ_PRI_DSA_PRIME(key))->
5568 big_value_len;
5569 #endif /* __sparcv9 */
5570 else
5571 #ifdef __sparcv9
5572 len =
5573 /* LINTED */
5574 (uint32_t)
5575 ((biginteger_t *)OBJ_PRI_DH_PRIME(key))->
5576 big_value_len;
5577 #else /* !__sparcv9 */
5578 len =
5579 ((biginteger_t *)OBJ_PRI_DH_PRIME(key))->
5580 big_value_len;
5581 #endif /* __sparcv9 */
5582
5583 /* This attribute MUST BE set */
5584 if (len == 0 || len > *value_len) {
5585 return (CKR_ATTRIBUTE_VALUE_INVALID);
5586 }
5587 *value_len = len;
5588
5589 if (key->key_type == CKK_DSA)
5590 (void) memcpy(value,
5591 ((biginteger_t *)OBJ_PRI_DSA_PRIME(key))->big_value,
5592 *value_len);
5593 else
5594 (void) memcpy(value,
5595 ((biginteger_t *)OBJ_PRI_DH_PRIME(key))->big_value,
5596 *value_len);
5597
5598 break;
5599
5600 case CKA_SUBPRIME:
5601 #ifdef __sparcv9
5602 len =
5603 /* LINTED */
5604 (uint32_t)
5605 ((biginteger_t *)OBJ_PRI_DSA_SUBPRIME(key))->big_value_len;
5606 #else /* !__sparcv9 */
5607 len =
5608 ((biginteger_t *)OBJ_PRI_DSA_SUBPRIME(key))->big_value_len;
5609 #endif /* __sparcv9 */
5610
5611 /* This attribute MUST BE set */
5612 if (len == 0 || len > *value_len) {
5613 return (CKR_ATTRIBUTE_VALUE_INVALID);
5614 }
5615 *value_len = len;
5616
5617 (void) memcpy(value,
5618 ((biginteger_t *)OBJ_PRI_DSA_SUBPRIME(key))->big_value,
5619 *value_len);
5620
5621 break;
5622
5623 case CKA_BASE:
5624
5625 if (key->key_type == CKK_DSA)
5626 #ifdef __sparcv9
5627 len =
5628 /* LINTED */
5629 (uint32_t)
5630 ((biginteger_t *)OBJ_PRI_DSA_BASE(key))->
5631 big_value_len;
5632 #else /* !__sparcv9 */
5633 len =
5634 ((biginteger_t *)OBJ_PRI_DSA_BASE(key))->
5635 big_value_len;
5636 #endif /* __sparcv9 */
5637 else
5638 #ifdef __sparcv9
5639 len =
5640 /* LINTED */
5641 (uint32_t)
5642 ((biginteger_t *)OBJ_PRI_DH_BASE(key))->
5643 big_value_len;
5644 #else /* !__sparcv9 */
5645 len =
5646 ((biginteger_t *)OBJ_PRI_DH_BASE(key))->
5647 big_value_len;
5648 #endif /* __sparcv9 */
5649
5650 /* This attribute MUST BE set */
5651 if (len == 0 || len > *value_len) {
5652 return (CKR_ATTRIBUTE_VALUE_INVALID);
5653 }
5654 *value_len = len;
5655
5656 if (key->key_type == CKK_DSA)
5657 (void) memcpy(value,
5658 ((biginteger_t *)OBJ_PRI_DSA_BASE(key))->big_value,
5659 *value_len);
5660 else
5661 (void) memcpy(value,
5662 ((biginteger_t *)OBJ_PRI_DH_BASE(key))->big_value,
5663 *value_len);
5664 break;
5665
5666 case CKA_VALUE:
5667
5668 if (key->key_type == CKK_DSA) {
5669 #ifdef __sparcv9
5670 len =
5671 /* LINTED */
5672 (uint32_t)
5673 ((biginteger_t *)OBJ_PRI_DSA_VALUE(key))->
5674 big_value_len;
5675 #else /* !__sparcv9 */
5676 len =
5677 ((biginteger_t *)OBJ_PRI_DSA_VALUE(key))->
5678 big_value_len;
5679 #endif /* __sparcv9 */
5680 } else if (key->key_type == CKK_DH) {
5681 #ifdef __sparcv9
5682 len =
5683 /* LINTED */
5684 (uint32_t)
5685 ((biginteger_t *)OBJ_PRI_DH_VALUE(key))->
5686 big_value_len;
5687 #else /* !__sparcv9 */
5688 len =
5689 ((biginteger_t *)OBJ_PRI_DH_VALUE(key))->
5690 big_value_len;
5691 #endif /* __sparcv9 */
5692 } else {
5693 #ifdef __sparcv9
5694 len =
5695 /* LINTED */
5696 (uint32_t)
5697 ((biginteger_t *)OBJ_PRI_EC_VALUE(key))->
5698 big_value_len;
5699 #else /* !__sparcv9 */
5700 len =
5701 ((biginteger_t *)OBJ_PRI_EC_VALUE(key))->
5702 big_value_len;
5703 #endif /* __sparcv9 */
5704 }
5705
5706 /* This attribute MUST BE set */
5707 if (len == 0 || len > *value_len) {
5708 return (CKR_ATTRIBUTE_VALUE_INVALID);
5709 }
5710 *value_len = len;
5711
5712 if (key->key_type == CKK_DSA) {
5713 (void) memcpy(value,
5714 ((biginteger_t *)OBJ_PRI_DSA_VALUE(key))->big_value,
5715 *value_len);
5716 } else if (key->key_type == CKK_DH) {
5717 (void) memcpy(value,
5718 ((biginteger_t *)OBJ_PRI_DH_VALUE(key))->big_value,
5719 *value_len);
5720 } else {
5721 (void) memcpy(value,
5722 ((biginteger_t *)OBJ_PRI_EC_VALUE(key))->big_value,
5723 *value_len);
5724 }
5725
5726 break;
5727 }
5728
5729 return (CKR_OK);
5730
5731 }
5732
5733 static CK_RV
5734 copy_bigint(biginteger_t *new_bigint, biginteger_t *old_bigint)
5735 {
5736 new_bigint->big_value =
5737 malloc((sizeof (CK_BYTE) * new_bigint->big_value_len));
5738
5739 if (new_bigint->big_value == NULL) {
5740 return (CKR_HOST_MEMORY);
5741 }
5742
5743 (void) memcpy(new_bigint->big_value, old_bigint->big_value,
5744 (sizeof (CK_BYTE) * new_bigint->big_value_len));
5745
5746 return (CKR_OK);
5747 }
5748
5749 static void
5750 free_public_key_attr(public_key_obj_t *pbk, CK_KEY_TYPE key_type)
5751 {
5752 if (pbk == NULL) {
5753 return;
5754 }
5755
5756 switch (key_type) {
5757 case CKK_RSA:
5758 bigint_attr_cleanup(KEY_PUB_RSA_MOD(pbk));
5759 bigint_attr_cleanup(KEY_PUB_RSA_PUBEXPO(pbk));
5760 break;
5761 case CKK_DSA:
5762 bigint_attr_cleanup(KEY_PUB_DSA_PRIME(pbk));
5763 bigint_attr_cleanup(KEY_PUB_DSA_SUBPRIME(pbk));
5764 bigint_attr_cleanup(KEY_PUB_DSA_BASE(pbk));
5765 bigint_attr_cleanup(KEY_PUB_DSA_VALUE(pbk));
5766 break;
5767 case CKK_DH:
5768 bigint_attr_cleanup(KEY_PUB_DH_PRIME(pbk));
5769 bigint_attr_cleanup(KEY_PUB_DH_BASE(pbk));
5770 bigint_attr_cleanup(KEY_PUB_DH_VALUE(pbk));
5771 break;
5772 case CKK_EC:
5773 bigint_attr_cleanup(KEY_PUB_EC_POINT(pbk));
5774 break;
5775 case CKK_X9_42_DH:
5776 bigint_attr_cleanup(KEY_PUB_DH942_PRIME(pbk));
5777 bigint_attr_cleanup(KEY_PUB_DH942_SUBPRIME(pbk));
5778 bigint_attr_cleanup(KEY_PUB_DH942_BASE(pbk));
5779 bigint_attr_cleanup(KEY_PUB_DH942_VALUE(pbk));
5780 break;
5781 default:
5782 break;
5783 }
5784 free(pbk);
5785 }
5786
5787 CK_RV
5788 soft_copy_public_key_attr(public_key_obj_t *old_pub_key_obj_p,
5789 public_key_obj_t **new_pub_key_obj_p, CK_KEY_TYPE key_type)
5790 {
5791
5792 public_key_obj_t *pbk;
5793 CK_RV rv = CKR_OK;
5794
5795 pbk = calloc(1, sizeof (public_key_obj_t));
5796 if (pbk == NULL) {
5797 return (CKR_HOST_MEMORY);
5798 }
5799
5800 switch (key_type) {
5801 case CKK_RSA:
5802 (void) memcpy(KEY_PUB_RSA(pbk),
5803 KEY_PUB_RSA(old_pub_key_obj_p),
5804 sizeof (rsa_pub_key_t));
5805 /* copy modulus */
5806 rv = copy_bigint(KEY_PUB_RSA_MOD(pbk),
5807 KEY_PUB_RSA_MOD(old_pub_key_obj_p));
5808 if (rv != CKR_OK) {
5809 free_public_key_attr(pbk, key_type);
5810 return (rv);
5811 }
5812 /* copy public exponent */
5813 rv = copy_bigint(KEY_PUB_RSA_PUBEXPO(pbk),
5814 KEY_PUB_RSA_PUBEXPO(old_pub_key_obj_p));
5815 if (rv != CKR_OK) {
5816 free_public_key_attr(pbk, key_type);
5817 return (rv);
5818 }
5819 break;
5820 case CKK_DSA:
5821 (void) memcpy(KEY_PUB_DSA(pbk),
5822 KEY_PUB_DSA(old_pub_key_obj_p),
5823 sizeof (dsa_pub_key_t));
5824
5825 /* copy prime */
5826 rv = copy_bigint(KEY_PUB_DSA_PRIME(pbk),
5827 KEY_PUB_DSA_PRIME(old_pub_key_obj_p));
5828 if (rv != CKR_OK) {
5829 free_public_key_attr(pbk, key_type);
5830 return (rv);
5831 }
5832
5833 /* copy subprime */
5834 rv = copy_bigint(KEY_PUB_DSA_SUBPRIME(pbk),
5835 KEY_PUB_DSA_SUBPRIME(old_pub_key_obj_p));
5836 if (rv != CKR_OK) {
5837 free_public_key_attr(pbk, key_type);
5838 return (rv);
5839 }
5840
5841 /* copy base */
5842 rv = copy_bigint(KEY_PUB_DSA_BASE(pbk),
5843 KEY_PUB_DSA_BASE(old_pub_key_obj_p));
5844 if (rv != CKR_OK) {
5845 free_public_key_attr(pbk, key_type);
5846 return (rv);
5847 }
5848
5849 /* copy value */
5850 rv = copy_bigint(KEY_PUB_DSA_VALUE(pbk),
5851 KEY_PUB_DSA_VALUE(old_pub_key_obj_p));
5852 if (rv != CKR_OK) {
5853 free_public_key_attr(pbk, key_type);
5854 return (rv);
5855 }
5856 break;
5857 case CKK_DH:
5858 (void) memcpy(KEY_PUB_DH(pbk),
5859 KEY_PUB_DH(old_pub_key_obj_p),
5860 sizeof (dh_pub_key_t));
5861
5862 /* copy prime */
5863 rv = copy_bigint(KEY_PUB_DH_PRIME(pbk),
5864 KEY_PUB_DH_PRIME(old_pub_key_obj_p));
5865 if (rv != CKR_OK) {
5866 free_public_key_attr(pbk, key_type);
5867 return (rv);
5868 }
5869
5870 /* copy base */
5871 rv = copy_bigint(KEY_PUB_DH_BASE(pbk),
5872 KEY_PUB_DH_BASE(old_pub_key_obj_p));
5873 if (rv != CKR_OK) {
5874 free_public_key_attr(pbk, key_type);
5875 return (rv);
5876 }
5877
5878 /* copy value */
5879 rv = copy_bigint(KEY_PUB_DH_VALUE(pbk),
5880 KEY_PUB_DH_VALUE(old_pub_key_obj_p));
5881 if (rv != CKR_OK) {
5882 free_public_key_attr(pbk, key_type);
5883 return (rv);
5884 }
5885 break;
5886 case CKK_EC:
5887 (void) memcpy(KEY_PUB_EC(pbk),
5888 KEY_PUB_EC(old_pub_key_obj_p),
5889 sizeof (ec_pub_key_t));
5890
5891 /* copy point */
5892 rv = copy_bigint(KEY_PUB_EC_POINT(pbk),
5893 KEY_PUB_EC_POINT(old_pub_key_obj_p));
5894 if (rv != CKR_OK) {
5895 free_public_key_attr(pbk, key_type);
5896 return (rv);
5897 }
5898 break;
5899 case CKK_X9_42_DH:
5900 (void) memcpy(KEY_PUB_DH942(pbk),
5901 KEY_PUB_DH942(old_pub_key_obj_p),
5902 sizeof (dh942_pub_key_t));
5903
5904 /* copy prime */
5905 rv = copy_bigint(KEY_PUB_DH942_PRIME(pbk),
5906 KEY_PUB_DH942_PRIME(old_pub_key_obj_p));
5907 if (rv != CKR_OK) {
5908 free_public_key_attr(pbk, key_type);
5909 return (rv);
5910 }
5911
5912 /* copy subprime */
5913 rv = copy_bigint(KEY_PUB_DH942_SUBPRIME(pbk),
5914 KEY_PUB_DH942_SUBPRIME(old_pub_key_obj_p));
5915 if (rv != CKR_OK) {
5916 free_public_key_attr(pbk, key_type);
5917 return (rv);
5918 }
5919
5920 /* copy base */
5921 rv = copy_bigint(KEY_PUB_DH942_BASE(pbk),
5922 KEY_PUB_DH942_BASE(old_pub_key_obj_p));
5923 if (rv != CKR_OK) {
5924 free_public_key_attr(pbk, key_type);
5925 return (rv);
5926 }
5927
5928 /* copy value */
5929 rv = copy_bigint(KEY_PUB_DH942_VALUE(pbk),
5930 KEY_PUB_DH942_VALUE(old_pub_key_obj_p));
5931 if (rv != CKR_OK) {
5932 free_public_key_attr(pbk, key_type);
5933 return (rv);
5934 }
5935 break;
5936 default:
5937 break;
5938 }
5939 *new_pub_key_obj_p = pbk;
5940 return (rv);
5941 }
5942
5943 static void
5944 free_private_key_attr(private_key_obj_t *pbk, CK_KEY_TYPE key_type)
5945 {
5946 if (pbk == NULL) {
5947 return;
5948 }
5949
5950 switch (key_type) {
5951 case CKK_RSA:
5952 bigint_attr_cleanup(KEY_PRI_RSA_MOD(pbk));
5953 bigint_attr_cleanup(KEY_PRI_RSA_PUBEXPO(pbk));
5954 bigint_attr_cleanup(KEY_PRI_RSA_PRIEXPO(pbk));
5955 bigint_attr_cleanup(KEY_PRI_RSA_PRIME1(pbk));
5956 bigint_attr_cleanup(KEY_PRI_RSA_PRIME2(pbk));
5957 bigint_attr_cleanup(KEY_PRI_RSA_EXPO1(pbk));
5958 bigint_attr_cleanup(KEY_PRI_RSA_EXPO2(pbk));
5959 bigint_attr_cleanup(KEY_PRI_RSA_COEF(pbk));
5960 break;
5961 case CKK_DSA:
5962 bigint_attr_cleanup(KEY_PRI_DSA_PRIME(pbk));
5963 bigint_attr_cleanup(KEY_PRI_DSA_SUBPRIME(pbk));
5964 bigint_attr_cleanup(KEY_PRI_DSA_BASE(pbk));
5965 bigint_attr_cleanup(KEY_PRI_DSA_VALUE(pbk));
5966 break;
5967 case CKK_DH:
5968 bigint_attr_cleanup(KEY_PRI_DH_PRIME(pbk));
5969 bigint_attr_cleanup(KEY_PRI_DH_BASE(pbk));
5970 bigint_attr_cleanup(KEY_PRI_DH_VALUE(pbk));
5971 break;
5972 case CKK_EC:
5973 bigint_attr_cleanup(KEY_PRI_EC_VALUE(pbk));
5974 break;
5975 case CKK_X9_42_DH:
5976 bigint_attr_cleanup(KEY_PRI_DH942_PRIME(pbk));
5977 bigint_attr_cleanup(KEY_PRI_DH942_SUBPRIME(pbk));
5978 bigint_attr_cleanup(KEY_PRI_DH942_BASE(pbk));
5979 bigint_attr_cleanup(KEY_PRI_DH942_VALUE(pbk));
5980 break;
5981 default:
5982 break;
5983 }
5984 free(pbk);
5985 }
5986
5987 CK_RV
5988 soft_copy_private_key_attr(private_key_obj_t *old_pri_key_obj_p,
5989 private_key_obj_t **new_pri_key_obj_p, CK_KEY_TYPE key_type)
5990 {
5991 CK_RV rv = CKR_OK;
5992 private_key_obj_t *pbk;
5993
5994 pbk = calloc(1, sizeof (private_key_obj_t));
5995 if (pbk == NULL) {
5996 return (CKR_HOST_MEMORY);
5997 }
5998
5999 switch (key_type) {
6000 case CKK_RSA:
6001 (void) memcpy(KEY_PRI_RSA(pbk),
6002 KEY_PRI_RSA(old_pri_key_obj_p),
6003 sizeof (rsa_pri_key_t));
6004 /* copy modulus */
6005 rv = copy_bigint(KEY_PRI_RSA_MOD(pbk),
6006 KEY_PRI_RSA_MOD(old_pri_key_obj_p));
6007 if (rv != CKR_OK) {
6008 free_private_key_attr(pbk, key_type);
6009 return (rv);
6010 }
6011 /* copy public exponent */
6012 rv = copy_bigint(KEY_PRI_RSA_PUBEXPO(pbk),
6013 KEY_PRI_RSA_PUBEXPO(old_pri_key_obj_p));
6014 if (rv != CKR_OK) {
6015 free_private_key_attr(pbk, key_type);
6016 return (rv);
6017 }
6018 /* copy private exponent */
6019 rv = copy_bigint(KEY_PRI_RSA_PRIEXPO(pbk),
6020 KEY_PRI_RSA_PRIEXPO(old_pri_key_obj_p));
6021 if (rv != CKR_OK) {
6022 free_private_key_attr(pbk, key_type);
6023 return (rv);
6024 }
6025 /* copy prime_1 */
6026 rv = copy_bigint(KEY_PRI_RSA_PRIME1(pbk),
6027 KEY_PRI_RSA_PRIME1(old_pri_key_obj_p));
6028 if (rv != CKR_OK) {
6029 free_private_key_attr(pbk, key_type);
6030 return (rv);
6031 }
6032 /* copy prime_2 */
6033 rv = copy_bigint(KEY_PRI_RSA_PRIME2(pbk),
6034 KEY_PRI_RSA_PRIME2(old_pri_key_obj_p));
6035 if (rv != CKR_OK) {
6036 free_private_key_attr(pbk, key_type);
6037 return (rv);
6038 }
6039 /* copy exponent_1 */
6040 rv = copy_bigint(KEY_PRI_RSA_EXPO1(pbk),
6041 KEY_PRI_RSA_EXPO1(old_pri_key_obj_p));
6042 if (rv != CKR_OK) {
6043 free_private_key_attr(pbk, key_type);
6044 return (rv);
6045 }
6046 /* copy exponent_2 */
6047 rv = copy_bigint(KEY_PRI_RSA_EXPO2(pbk),
6048 KEY_PRI_RSA_EXPO2(old_pri_key_obj_p));
6049 if (rv != CKR_OK) {
6050 free_private_key_attr(pbk, key_type);
6051 return (rv);
6052 }
6053 /* copy coefficient */
6054 rv = copy_bigint(KEY_PRI_RSA_COEF(pbk),
6055 KEY_PRI_RSA_COEF(old_pri_key_obj_p));
6056 if (rv != CKR_OK) {
6057 free_private_key_attr(pbk, key_type);
6058 return (rv);
6059 }
6060 break;
6061 case CKK_DSA:
6062 (void) memcpy(KEY_PRI_DSA(pbk),
6063 KEY_PRI_DSA(old_pri_key_obj_p),
6064 sizeof (dsa_pri_key_t));
6065
6066 /* copy prime */
6067 rv = copy_bigint(KEY_PRI_DSA_PRIME(pbk),
6068 KEY_PRI_DSA_PRIME(old_pri_key_obj_p));
6069 if (rv != CKR_OK) {
6070 free_private_key_attr(pbk, key_type);
6071 return (rv);
6072 }
6073
6074 /* copy subprime */
6075 rv = copy_bigint(KEY_PRI_DSA_SUBPRIME(pbk),
6076 KEY_PRI_DSA_SUBPRIME(old_pri_key_obj_p));
6077 if (rv != CKR_OK) {
6078 free_private_key_attr(pbk, key_type);
6079 return (rv);
6080 }
6081
6082 /* copy base */
6083 rv = copy_bigint(KEY_PRI_DSA_BASE(pbk),
6084 KEY_PRI_DSA_BASE(old_pri_key_obj_p));
6085 if (rv != CKR_OK) {
6086 free_private_key_attr(pbk, key_type);
6087 return (rv);
6088 }
6089
6090 /* copy value */
6091 rv = copy_bigint(KEY_PRI_DSA_VALUE(pbk),
6092 KEY_PRI_DSA_VALUE(old_pri_key_obj_p));
6093 if (rv != CKR_OK) {
6094 free_private_key_attr(pbk, key_type);
6095 return (rv);
6096 }
6097 break;
6098 case CKK_DH:
6099 (void) memcpy(KEY_PRI_DH(pbk),
6100 KEY_PRI_DH(old_pri_key_obj_p),
6101 sizeof (dh_pri_key_t));
6102
6103 /* copy prime */
6104 rv = copy_bigint(KEY_PRI_DH_PRIME(pbk),
6105 KEY_PRI_DH_PRIME(old_pri_key_obj_p));
6106 if (rv != CKR_OK) {
6107 free_private_key_attr(pbk, key_type);
6108 return (rv);
6109 }
6110
6111 /* copy base */
6112 rv = copy_bigint(KEY_PRI_DH_BASE(pbk),
6113 KEY_PRI_DH_BASE(old_pri_key_obj_p));
6114 if (rv != CKR_OK) {
6115 free_private_key_attr(pbk, key_type);
6116 return (rv);
6117 }
6118
6119 /* copy value */
6120 rv = copy_bigint(KEY_PRI_DH_VALUE(pbk),
6121 KEY_PRI_DH_VALUE(old_pri_key_obj_p));
6122 if (rv != CKR_OK) {
6123 free_private_key_attr(pbk, key_type);
6124 return (rv);
6125 }
6126 break;
6127 case CKK_EC:
6128 (void) memcpy(KEY_PRI_EC(pbk),
6129 KEY_PRI_EC(old_pri_key_obj_p),
6130 sizeof (ec_pri_key_t));
6131
6132 /* copy value */
6133 rv = copy_bigint(KEY_PRI_EC_VALUE(pbk),
6134 KEY_PRI_EC_VALUE(old_pri_key_obj_p));
6135 if (rv != CKR_OK) {
6136 free_private_key_attr(pbk, key_type);
6137 return (rv);
6138 }
6139 break;
6140 case CKK_X9_42_DH:
6141 (void) memcpy(KEY_PRI_DH942(pbk),
6142 KEY_PRI_DH942(old_pri_key_obj_p),
6143 sizeof (dh942_pri_key_t));
6144
6145 /* copy prime */
6146 rv = copy_bigint(KEY_PRI_DH942_PRIME(pbk),
6147 KEY_PRI_DH942_PRIME(old_pri_key_obj_p));
6148 if (rv != CKR_OK) {
6149 free_private_key_attr(pbk, key_type);
6150 return (rv);
6151 }
6152
6153 /* copy subprime */
6154 rv = copy_bigint(KEY_PRI_DH942_SUBPRIME(pbk),
6155 KEY_PRI_DH942_SUBPRIME(old_pri_key_obj_p));
6156 if (rv != CKR_OK) {
6157 free_private_key_attr(pbk, key_type);
6158 return (rv);
6159 }
6160
6161 /* copy base */
6162 rv = copy_bigint(KEY_PRI_DH942_BASE(pbk),
6163 KEY_PRI_DH942_BASE(old_pri_key_obj_p));
6164 if (rv != CKR_OK) {
6165 free_private_key_attr(pbk, key_type);
6166 return (rv);
6167 }
6168
6169 /* copy value */
6170 rv = copy_bigint(KEY_PRI_DH942_VALUE(pbk),
6171 KEY_PRI_DH942_VALUE(old_pri_key_obj_p));
6172 if (rv != CKR_OK) {
6173 free_private_key_attr(pbk, key_type);
6174 return (rv);
6175 }
6176 break;
6177 default:
6178 break;
6179 }
6180 *new_pri_key_obj_p = pbk;
6181 return (rv);
6182 }
6183
6184 static void
6185 free_domain_attr(domain_obj_t *domain, CK_KEY_TYPE key_type)
6186 {
6187 if (domain == NULL) {
6188 return;
6189 }
6190
6191 switch (key_type) {
6192 case CKK_DSA:
6193 bigint_attr_cleanup(KEY_DOM_DSA_PRIME(domain));
6194 bigint_attr_cleanup(KEY_DOM_DSA_SUBPRIME(domain));
6195 bigint_attr_cleanup(KEY_DOM_DSA_BASE(domain));
6196 break;
6197 case CKK_DH:
6198 bigint_attr_cleanup(KEY_DOM_DH_PRIME(domain));
6199 bigint_attr_cleanup(KEY_DOM_DH_BASE(domain));
6200 break;
6201 case CKK_X9_42_DH:
6202 bigint_attr_cleanup(KEY_DOM_DH942_PRIME(domain));
6203 bigint_attr_cleanup(KEY_DOM_DH942_SUBPRIME(domain));
6204 bigint_attr_cleanup(KEY_DOM_DH942_BASE(domain));
6205 break;
6206 default:
6207 break;
6208 }
6209 free(domain);
6210 }
6211
6212 CK_RV
6213 soft_copy_domain_attr(domain_obj_t *old_domain_obj_p,
6214 domain_obj_t **new_domain_obj_p, CK_KEY_TYPE key_type)
6215 {
6216 CK_RV rv = CKR_OK;
6217 domain_obj_t *domain;
6218
6219 domain = calloc(1, sizeof (domain_obj_t));
6220 if (domain == NULL) {
6221 return (CKR_HOST_MEMORY);
6222 }
6223
6224 switch (key_type) {
6225 case CKK_DSA:
6226 (void) memcpy(KEY_DOM_DSA(domain),
6227 KEY_DOM_DSA(old_domain_obj_p),
6228 sizeof (dsa_dom_key_t));
6229
6230 /* copy prime */
6231 rv = copy_bigint(KEY_DOM_DSA_PRIME(domain),
6232 KEY_DOM_DSA_PRIME(old_domain_obj_p));
6233 if (rv != CKR_OK) {
6234 free_domain_attr(domain, key_type);
6235 return (rv);
6236 }
6237
6238 /* copy subprime */
6239 rv = copy_bigint(KEY_DOM_DSA_SUBPRIME(domain),
6240 KEY_DOM_DSA_SUBPRIME(old_domain_obj_p));
6241 if (rv != CKR_OK) {
6242 free_domain_attr(domain, key_type);
6243 return (rv);
6244 }
6245
6246 /* copy base */
6247 rv = copy_bigint(KEY_DOM_DSA_BASE(domain),
6248 KEY_DOM_DSA_BASE(old_domain_obj_p));
6249 if (rv != CKR_OK) {
6250 free_domain_attr(domain, key_type);
6251 return (rv);
6252 }
6253
6254 break;
6255 case CKK_DH:
6256 (void) memcpy(KEY_DOM_DH(domain),
6257 KEY_DOM_DH(old_domain_obj_p),
6258 sizeof (dh_dom_key_t));
6259
6260 /* copy prime */
6261 rv = copy_bigint(KEY_DOM_DH_PRIME(domain),
6262 KEY_DOM_DH_PRIME(old_domain_obj_p));
6263 if (rv != CKR_OK) {
6264 free_domain_attr(domain, key_type);
6265 return (rv);
6266 }
6267
6268 /* copy base */
6269 rv = copy_bigint(KEY_DOM_DH_BASE(domain),
6270 KEY_DOM_DH_BASE(old_domain_obj_p));
6271 if (rv != CKR_OK) {
6272 free_domain_attr(domain, key_type);
6273 return (rv);
6274 }
6275
6276 break;
6277 case CKK_X9_42_DH:
6278 (void) memcpy(KEY_DOM_DH942(domain),
6279 KEY_DOM_DH942(old_domain_obj_p),
6280 sizeof (dh942_dom_key_t));
6281
6282 /* copy prime */
6283 rv = copy_bigint(KEY_DOM_DH942_PRIME(domain),
6284 KEY_DOM_DH942_PRIME(old_domain_obj_p));
6285 if (rv != CKR_OK) {
6286 free_domain_attr(domain, key_type);
6287 return (rv);
6288 }
6289
6290 /* copy subprime */
6291 rv = copy_bigint(KEY_DOM_DH942_SUBPRIME(domain),
6292 KEY_DOM_DH942_SUBPRIME(old_domain_obj_p));
6293 if (rv != CKR_OK) {
6294 free_domain_attr(domain, key_type);
6295 return (rv);
6296 }
6297
6298 /* copy base */
6299 rv = copy_bigint(KEY_DOM_DH942_BASE(domain),
6300 KEY_DOM_DH942_BASE(old_domain_obj_p));
6301 if (rv != CKR_OK) {
6302 free_domain_attr(domain, key_type);
6303 return (rv);
6304 }
6305
6306 break;
6307 default:
6308 break;
6309 }
6310 *new_domain_obj_p = domain;
6311 return (rv);
6312 }
6313
6314 CK_RV
6315 soft_copy_secret_key_attr(secret_key_obj_t *old_secret_key_obj_p,
6316 secret_key_obj_t **new_secret_key_obj_p)
6317 {
6318 secret_key_obj_t *sk;
6319
6320 sk = malloc(sizeof (secret_key_obj_t));
6321 if (sk == NULL) {
6322 return (CKR_HOST_MEMORY);
6323 }
6324 (void) memcpy(sk, old_secret_key_obj_p, sizeof (secret_key_obj_t));
6325
6326 /* copy the secret key value */
6327 sk->sk_value = malloc((sizeof (CK_BYTE) * sk->sk_value_len));
6328 if (sk->sk_value == NULL) {
6329 free(sk);
6330 return (CKR_HOST_MEMORY);
6331 }
6332 (void) memcpy(sk->sk_value, old_secret_key_obj_p->sk_value,
6333 (sizeof (CK_BYTE) * sk->sk_value_len));
6334
6335 /*
6336 * Copy the pre-expanded key schedule.
6337 */
6338 if (old_secret_key_obj_p->key_sched != NULL &&
6339 old_secret_key_obj_p->keysched_len > 0) {
6340 sk->key_sched = malloc(old_secret_key_obj_p->keysched_len);
6341 if (sk->key_sched == NULL) {
6342 free(sk);
6343 return (CKR_HOST_MEMORY);
6344 }
6345 sk->keysched_len = old_secret_key_obj_p->keysched_len;
6346 (void) memcpy(sk->key_sched, old_secret_key_obj_p->key_sched,
6347 sk->keysched_len);
6348 }
6349
6350 *new_secret_key_obj_p = sk;
6351
6352 return (CKR_OK);
6353 }
6354
6355 /*
6356 * If CKA_CLASS not given, guess CKA_CLASS using
6357 * attributes on template .
6358 *
6359 * Some attributes are specific to an object class. If one or more
6360 * of these attributes are in the template, make a list of classes
6361 * that can have these attributes. This would speed up the search later,
6362 * because we can immediately skip an object if the class of that
6363 * object can not possibly contain one of the attributes.
6364 *
6365 */
6366 void
6367 soft_process_find_attr(CK_OBJECT_CLASS *pclasses,
6368 CK_ULONG *num_result_pclasses, CK_ATTRIBUTE_PTR pTemplate,
6369 CK_ULONG ulCount)
6370 {
6371 ulong_t i;
6372 int j;
6373 boolean_t pub_found = B_FALSE,
6374 priv_found = B_FALSE,
6375 secret_found = B_FALSE,
6376 domain_found = B_FALSE,
6377 hardware_found = B_FALSE,
6378 cert_found = B_FALSE;
6379 int num_pub_key_attrs, num_priv_key_attrs,
6380 num_secret_key_attrs, num_domain_attrs,
6381 num_hardware_attrs, num_cert_attrs;
6382 int num_pclasses = 0;
6383
6384 for (i = 0; i < ulCount; i++) {
6385 if (pTemplate[i].type == CKA_CLASS) {
6386 /*
6387 * don't need to guess the class, it is specified.
6388 * Just record the class, and return.
6389 */
6390 pclasses[0] =
6391 (*((CK_OBJECT_CLASS *)pTemplate[i].pValue));
6392 *num_result_pclasses = 1;
6393 return;
6394 }
6395 }
6396
6397 num_pub_key_attrs =
6398 sizeof (PUB_KEY_ATTRS) / sizeof (CK_ATTRIBUTE_TYPE);
6399 num_priv_key_attrs =
6400 sizeof (PRIV_KEY_ATTRS) / sizeof (CK_ATTRIBUTE_TYPE);
6401 num_secret_key_attrs =
6402 sizeof (SECRET_KEY_ATTRS) / sizeof (CK_ATTRIBUTE_TYPE);
6403 num_domain_attrs =
6404 sizeof (DOMAIN_ATTRS) / sizeof (CK_ATTRIBUTE_TYPE);
6405 num_hardware_attrs =
6406 sizeof (HARDWARE_ATTRS) / sizeof (CK_ATTRIBUTE_TYPE);
6407 num_cert_attrs =
6408 sizeof (CERT_ATTRS) / sizeof (CK_ATTRIBUTE_TYPE);
6409
6410 /*
6411 * Get the list of objects class that might contain
6412 * some attributes.
6413 */
6414 for (i = 0; i < ulCount; i++) {
6415 /*
6416 * only check if this attribute can belong to public key object
6417 * class if public key object isn't already in the list
6418 */
6419 if (!pub_found) {
6420 for (j = 0; j < num_pub_key_attrs; j++) {
6421 if (pTemplate[i].type == PUB_KEY_ATTRS[j]) {
6422 pub_found = B_TRUE;
6423 pclasses[num_pclasses++] =
6424 CKO_PUBLIC_KEY;
6425 break;
6426 }
6427 }
6428 }
6429
6430 if (!priv_found) {
6431 for (j = 0; j < num_priv_key_attrs; j++) {
6432 if (pTemplate[i].type == PRIV_KEY_ATTRS[j]) {
6433 priv_found = B_TRUE;
6434 pclasses[num_pclasses++] =
6435 CKO_PRIVATE_KEY;
6436 break;
6437 }
6438 }
6439 }
6440
6441 if (!secret_found) {
6442 for (j = 0; j < num_secret_key_attrs; j++) {
6443 if (pTemplate[i].type == SECRET_KEY_ATTRS[j]) {
6444 secret_found = B_TRUE;
6445 pclasses[num_pclasses++] =
6446 CKO_SECRET_KEY;
6447 break;
6448 }
6449 }
6450 }
6451
6452 if (!domain_found) {
6453 for (j = 0; j < num_domain_attrs; j++) {
6454 if (pTemplate[i].type == DOMAIN_ATTRS[j]) {
6455 domain_found = B_TRUE;
6456 pclasses[num_pclasses++] =
6457 CKO_DOMAIN_PARAMETERS;
6458 break;
6459 }
6460 }
6461 }
6462
6463 if (!hardware_found) {
6464 for (j = 0; j < num_hardware_attrs; j++) {
6465 if (pTemplate[i].type == HARDWARE_ATTRS[j]) {
6466 hardware_found = B_TRUE;
6467 pclasses[num_pclasses++] =
6468 CKO_HW_FEATURE;
6469 break;
6470 }
6471 }
6472 }
6473
6474 if (!cert_found) {
6475 for (j = 0; j < num_cert_attrs; j++) {
6476 if (pTemplate[i].type == CERT_ATTRS[j]) {
6477 cert_found = B_TRUE;
6478 pclasses[num_pclasses++] =
6479 CKO_CERTIFICATE;
6480 break;
6481 }
6482 }
6483 }
6484 }
6485 *num_result_pclasses = num_pclasses;
6486 }
6487
6488 boolean_t
6489 soft_find_match_attrs(soft_object_t *obj, CK_OBJECT_CLASS *pclasses,
6490 CK_ULONG num_pclasses, CK_ATTRIBUTE *template, CK_ULONG num_attr)
6491 {
6492 ulong_t i;
6493 CK_ATTRIBUTE *tmpl_attr, *obj_attr;
6494 cert_attr_t *cert_attr;
6495 uint64_t attr_mask;
6496 biginteger_t *bigint;
6497 boolean_t compare_attr, compare_bigint, compare_boolean;
6498 boolean_t compare_cert_val, compare_cert_type;
6499
6500 /*
6501 * Check if the class of this object match with any
6502 * of object classes that can possibly contain the
6503 * requested attributes.
6504 */
6505 if (num_pclasses > 0) {
6506 for (i = 0; i < num_pclasses; i++) {
6507 if (obj->class == pclasses[i]) {
6508 break;
6509 }
6510 }
6511 if (i == num_pclasses) {
6512 /*
6513 * this object can't possibly contain one or
6514 * more attributes, don't need to check this object
6515 */
6516 return (B_FALSE);
6517 }
6518 }
6519
6520 /* need to examine everything */
6521 for (i = 0; i < num_attr; i++) {
6522 tmpl_attr = &(template[i]);
6523 compare_attr = B_FALSE;
6524 compare_bigint = B_FALSE;
6525 compare_boolean = B_FALSE;
6526 compare_cert_val = B_FALSE;
6527 compare_cert_type = B_FALSE;
6528 switch (tmpl_attr->type) {
6529 /* First, check the most common attributes */
6530 case CKA_CLASS:
6531 if (*((CK_OBJECT_CLASS *)tmpl_attr->pValue) !=
6532 obj->class) {
6533 return (B_FALSE);
6534 }
6535 break;
6536 case CKA_KEY_TYPE:
6537 if (*((CK_KEY_TYPE *)tmpl_attr->pValue) !=
6538 obj->key_type) {
6539 return (B_FALSE);
6540 }
6541 break;
6542 case CKA_ENCRYPT:
6543 attr_mask = (obj->bool_attr_mask) & ENCRYPT_BOOL_ON;
6544 compare_boolean = B_TRUE;
6545 break;
6546 case CKA_DECRYPT:
6547 attr_mask = (obj->bool_attr_mask) & DECRYPT_BOOL_ON;
6548 compare_boolean = B_TRUE;
6549 break;
6550 case CKA_WRAP:
6551 attr_mask = (obj->bool_attr_mask) & WRAP_BOOL_ON;
6552 compare_boolean = B_TRUE;
6553 break;
6554 case CKA_UNWRAP:
6555 attr_mask = (obj->bool_attr_mask) & UNWRAP_BOOL_ON;
6556 compare_boolean = B_TRUE;
6557 break;
6558 case CKA_SIGN:
6559 attr_mask = (obj->bool_attr_mask) & SIGN_BOOL_ON;
6560 compare_boolean = B_TRUE;
6561 break;
6562 case CKA_SIGN_RECOVER:
6563 attr_mask = (obj->bool_attr_mask) &
6564 SIGN_RECOVER_BOOL_ON;
6565 compare_boolean = B_TRUE;
6566 break;
6567 case CKA_VERIFY:
6568 attr_mask = (obj->bool_attr_mask) & VERIFY_BOOL_ON;
6569 compare_boolean = B_TRUE;
6570 break;
6571 case CKA_VERIFY_RECOVER:
6572 attr_mask = (obj->bool_attr_mask) &
6573 VERIFY_RECOVER_BOOL_ON;
6574 compare_boolean = B_TRUE;
6575 break;
6576 case CKA_DERIVE:
6577 attr_mask = (obj->bool_attr_mask) & DERIVE_BOOL_ON;
6578 compare_boolean = B_TRUE;
6579 break;
6580 case CKA_LOCAL:
6581 attr_mask = (obj->bool_attr_mask) & LOCAL_BOOL_ON;
6582 compare_boolean = B_TRUE;
6583 break;
6584 case CKA_SENSITIVE:
6585 attr_mask = (obj->bool_attr_mask) & SENSITIVE_BOOL_ON;
6586 compare_boolean = B_TRUE;
6587 break;
6588 case CKA_SECONDARY_AUTH:
6589 attr_mask = (obj->bool_attr_mask) &
6590 SECONDARY_AUTH_BOOL_ON;
6591 compare_boolean = B_TRUE;
6592 break;
6593 case CKA_TRUSTED:
6594 attr_mask = (obj->bool_attr_mask) & TRUSTED_BOOL_ON;
6595 compare_boolean = B_TRUE;
6596 break;
6597 case CKA_EXTRACTABLE:
6598 attr_mask = (obj->bool_attr_mask) &
6599 EXTRACTABLE_BOOL_ON;
6600 compare_boolean = B_TRUE;
6601 break;
6602 case CKA_ALWAYS_SENSITIVE:
6603 attr_mask = (obj->bool_attr_mask) &
6604 ALWAYS_SENSITIVE_BOOL_ON;
6605 compare_boolean = B_TRUE;
6606 break;
6607 case CKA_NEVER_EXTRACTABLE:
6608 attr_mask = (obj->bool_attr_mask) &
6609 NEVER_EXTRACTABLE_BOOL_ON;
6610 compare_boolean = B_TRUE;
6611 break;
6612 case CKA_TOKEN:
6613 attr_mask = (obj->object_type) & TOKEN_OBJECT;
6614 compare_boolean = B_TRUE;
6615 break;
6616 case CKA_PRIVATE:
6617 attr_mask = (obj->object_type) & PRIVATE_OBJECT;
6618 compare_boolean = B_TRUE;
6619 break;
6620 case CKA_MODIFIABLE:
6621 {
6622 CK_BBOOL bval;
6623 attr_mask = (obj->bool_attr_mask) &
6624 NOT_MODIFIABLE_BOOL_ON;
6625
6626 if (attr_mask) {
6627 bval = FALSE;
6628 } else {
6629 bval = TRUE;
6630 }
6631 if (bval != *((CK_BBOOL *)tmpl_attr->pValue)) {
6632 return (B_FALSE);
6633 }
6634 break;
6635 }
6636 case CKA_OWNER:
6637 /*
6638 * For X.509 attribute certificate object, get its
6639 * CKA_OWNER attribute from the x509_attr_cert_t struct.
6640 */
6641 if ((obj->class == CKO_CERTIFICATE) &&
6642 (obj->cert_type == CKC_X_509_ATTR_CERT)) {
6643 cert_attr = X509_ATTR_CERT_OWNER(obj);
6644 compare_cert_val = B_TRUE;
6645 }
6646 break;
6647 case CKA_SUBJECT:
6648 /*
6649 * For X.509 certificate object, get its CKA_SUBJECT
6650 * attribute from the x509_cert_t struct (not from
6651 * the extra_attrlistp).
6652 */
6653 if ((obj->class == CKO_CERTIFICATE) &&
6654 (obj->cert_type == CKC_X_509)) {
6655 cert_attr = X509_CERT_SUBJECT(obj);
6656 compare_cert_val = B_TRUE;
6657 break;
6658 }
6659 /*FALLTHRU*/
6660 case CKA_ID:
6661 case CKA_START_DATE:
6662 case CKA_END_DATE:
6663 case CKA_KEY_GEN_MECHANISM:
6664 case CKA_LABEL:
6665 case CKA_ISSUER:
6666 case CKA_SERIAL_NUMBER:
6667 case CKA_AC_ISSUER:
6668 case CKA_ATTR_TYPES:
6669 /* find these attributes from extra_attrlistp */
6670 obj_attr = get_extra_attr(tmpl_attr->type, obj);
6671 compare_attr = B_TRUE;
6672 break;
6673 case CKA_CERTIFICATE_TYPE:
6674 compare_cert_type = B_TRUE;
6675 break;
6676 case CKA_VALUE_LEN:
6677 /* only secret key has this attribute */
6678 if (obj->class == CKO_SECRET_KEY) {
6679 if (*((CK_ULONG *)tmpl_attr->pValue) !=
6680 OBJ_SEC_VALUE_LEN(obj)) {
6681 return (B_FALSE);
6682 }
6683 } else {
6684 return (B_FALSE);
6685 }
6686 break;
6687 case CKA_VALUE:
6688 switch (obj->class) {
6689 case CKO_SECRET_KEY:
6690 /*
6691 * secret_key_obj_t is the same as
6692 * biginteger_t
6693 */
6694 bigint = (biginteger_t *)OBJ_SEC(obj);
6695 compare_bigint = B_TRUE;
6696 break;
6697 case CKO_PRIVATE_KEY:
6698 if (obj->key_type == CKK_DSA) {
6699 bigint = OBJ_PRI_DSA_VALUE(obj);
6700 } else if (obj->key_type == CKK_DH) {
6701 bigint = OBJ_PRI_DH_VALUE(obj);
6702 } else if (obj->key_type == CKK_X9_42_DH) {
6703 bigint = OBJ_PRI_DH942_VALUE(obj);
6704 } else {
6705 return (B_FALSE);
6706 }
6707 compare_bigint = B_TRUE;
6708 break;
6709 case CKO_PUBLIC_KEY:
6710 if (obj->key_type == CKK_DSA) {
6711 bigint = OBJ_PUB_DSA_VALUE(obj);
6712 } else if (obj->key_type == CKK_DH) {
6713 bigint = OBJ_PUB_DH_VALUE(obj);
6714 } else if (obj->key_type == CKK_X9_42_DH) {
6715 bigint = OBJ_PUB_DH942_VALUE(obj);
6716 } else {
6717 return (B_FALSE);
6718 }
6719 compare_bigint = B_TRUE;
6720 break;
6721 case CKO_CERTIFICATE:
6722 if (obj->cert_type == CKC_X_509) {
6723 cert_attr = X509_CERT_VALUE(obj);
6724 } else if (obj->cert_type ==
6725 CKC_X_509_ATTR_CERT) {
6726 cert_attr = X509_ATTR_CERT_VALUE(obj);
6727 }
6728 compare_cert_val = B_TRUE;
6729 break;
6730 default:
6731 return (B_FALSE);
6732 }
6733 break;
6734 case CKA_MODULUS:
6735 /* only RSA public and private key have this attr */
6736 if (obj->key_type == CKK_RSA) {
6737 if (obj->class == CKO_PUBLIC_KEY) {
6738 bigint = OBJ_PUB_RSA_MOD(obj);
6739 } else if (obj->class == CKO_PRIVATE_KEY) {
6740 bigint = OBJ_PRI_RSA_MOD(obj);
6741 } else {
6742 return (B_FALSE);
6743 }
6744 compare_bigint = B_TRUE;
6745 } else {
6746 return (B_FALSE);
6747 }
6748 break;
6749 case CKA_MODULUS_BITS:
6750 /* only RSA public key has this attribute */
6751 if ((obj->key_type == CKK_RSA) &&
6752 (obj->class == CKO_PUBLIC_KEY)) {
6753 CK_ULONG mod_bits = OBJ_PUB_RSA_MOD_BITS(obj);
6754 if (mod_bits !=
6755 *((CK_ULONG *)tmpl_attr->pValue)) {
6756 return (B_FALSE);
6757 }
6758 } else {
6759 return (B_FALSE);
6760 }
6761 break;
6762 case CKA_PUBLIC_EXPONENT:
6763 /* only RSA public and private key have this attr */
6764 if (obj->key_type == CKK_RSA) {
6765 if (obj->class == CKO_PUBLIC_KEY) {
6766 bigint = OBJ_PUB_RSA_PUBEXPO(obj);
6767 } else if (obj->class == CKO_PRIVATE_KEY) {
6768 bigint = OBJ_PRI_RSA_PUBEXPO(obj);
6769 } else {
6770 return (B_FALSE);
6771 }
6772 compare_bigint = B_TRUE;
6773 } else {
6774 return (B_FALSE);
6775 }
6776 break;
6777 case CKA_PRIVATE_EXPONENT:
6778 /* only RSA private key has this attribute */
6779 if ((obj->key_type == CKK_RSA) &&
6780 (obj->class == CKO_PRIVATE_KEY)) {
6781 bigint = OBJ_PRI_RSA_PRIEXPO(obj);
6782 compare_bigint = B_TRUE;
6783 } else {
6784 return (B_FALSE);
6785 }
6786 break;
6787 case CKA_PRIME_1:
6788 /* only RSA private key has this attribute */
6789 if ((obj->key_type == CKK_RSA) &&
6790 (obj->class == CKO_PRIVATE_KEY)) {
6791 bigint = OBJ_PRI_RSA_PRIME1(obj);
6792 compare_bigint = B_TRUE;
6793 } else {
6794 return (B_FALSE);
6795 }
6796 break;
6797 case CKA_PRIME_2:
6798 /* only RSA private key has this attribute */
6799 if ((obj->key_type == CKK_RSA) &&
6800 (obj->class == CKO_PRIVATE_KEY)) {
6801 bigint = OBJ_PRI_RSA_PRIME2(obj);
6802 compare_bigint = B_TRUE;
6803 } else {
6804 return (B_FALSE);
6805 }
6806 break;
6807 case CKA_EXPONENT_1:
6808 /* only RSA private key has this attribute */
6809 if ((obj->key_type == CKK_RSA) &&
6810 (obj->class == CKO_PRIVATE_KEY)) {
6811 bigint = OBJ_PRI_RSA_EXPO1(obj);
6812 compare_bigint = B_TRUE;
6813 } else {
6814 return (B_FALSE);
6815 }
6816 break;
6817 case CKA_EXPONENT_2:
6818 /* only RSA private key has this attribute */
6819 if ((obj->key_type == CKK_RSA) &&
6820 (obj->class == CKO_PRIVATE_KEY)) {
6821 bigint = OBJ_PRI_RSA_EXPO2(obj);
6822 compare_bigint = B_TRUE;
6823 } else {
6824 return (B_FALSE);
6825 }
6826 break;
6827 case CKA_COEFFICIENT:
6828 /* only RSA private key has this attribute */
6829 if ((obj->key_type == CKK_RSA) &&
6830 (obj->class == CKO_PRIVATE_KEY)) {
6831 bigint = OBJ_PRI_RSA_COEF(obj);
6832 compare_bigint = B_TRUE;
6833 } else {
6834 return (B_FALSE);
6835 }
6836 break;
6837 case CKA_VALUE_BITS:
6838 /* only Diffie-Hellman private key has this attr */
6839 if ((obj->key_type == CKK_DH) &&
6840 (obj->class == CKO_PRIVATE_KEY)) {
6841 CK_ULONG val_bits = OBJ_PRI_DH_VAL_BITS(obj);
6842 if (val_bits !=
6843 *((CK_ULONG *)tmpl_attr->pValue)) {
6844 return (B_FALSE);
6845 }
6846 } else {
6847 return (B_FALSE);
6848 }
6849 break;
6850 case CKA_PRIME:
6851 if (obj->class == CKO_PUBLIC_KEY) {
6852 switch (obj->key_type) {
6853 case CKK_DSA:
6854 bigint = OBJ_PUB_DSA_PRIME(obj);
6855 break;
6856 case CKK_DH:
6857 bigint = OBJ_PUB_DH_PRIME(obj);
6858 break;
6859 case CKK_X9_42_DH:
6860 bigint = OBJ_PUB_DH942_PRIME(obj);
6861 break;
6862 default:
6863 return (B_FALSE);
6864 }
6865 } else if (obj->class == CKO_PRIVATE_KEY) {
6866 switch (obj->key_type) {
6867 case CKK_DSA:
6868 bigint = OBJ_PRI_DSA_PRIME(obj);
6869 break;
6870 case CKK_DH:
6871 bigint = OBJ_PRI_DH_PRIME(obj);
6872 break;
6873 case CKK_X9_42_DH:
6874 bigint = OBJ_PRI_DH942_PRIME(obj);
6875 break;
6876 default:
6877 return (B_FALSE);
6878 }
6879 } else if (obj->class == CKO_DOMAIN_PARAMETERS) {
6880 switch (obj->key_type) {
6881 case CKK_DSA:
6882 bigint = OBJ_DOM_DSA_PRIME(obj);
6883 break;
6884 case CKK_DH:
6885 bigint = OBJ_DOM_DH_PRIME(obj);
6886 break;
6887 case CKK_X9_42_DH:
6888 bigint = OBJ_DOM_DH942_PRIME(obj);
6889 break;
6890 default:
6891 return (B_FALSE);
6892 }
6893 } else {
6894 return (B_FALSE);
6895 }
6896 compare_bigint = B_TRUE;
6897 break;
6898 case CKA_SUBPRIME:
6899 if (obj->class == CKO_PUBLIC_KEY) {
6900 switch (obj->key_type) {
6901 case CKK_DSA:
6902 bigint = OBJ_PUB_DSA_SUBPRIME(obj);
6903 break;
6904 case CKK_X9_42_DH:
6905 bigint = OBJ_PUB_DH942_SUBPRIME(obj);
6906 break;
6907 default:
6908 return (B_FALSE);
6909 }
6910 } else if (obj->class == CKO_PRIVATE_KEY) {
6911 switch (obj->key_type) {
6912 case CKK_DSA:
6913 bigint = OBJ_PRI_DSA_SUBPRIME(obj);
6914 break;
6915 case CKK_X9_42_DH:
6916 bigint = OBJ_PRI_DH942_SUBPRIME(obj);
6917 break;
6918 default:
6919 return (B_FALSE);
6920 }
6921 } else if (obj->class == CKO_DOMAIN_PARAMETERS) {
6922 switch (obj->key_type) {
6923 case CKK_DSA:
6924 bigint = OBJ_DOM_DSA_SUBPRIME(obj);
6925 break;
6926 case CKK_X9_42_DH:
6927 bigint = OBJ_DOM_DH942_SUBPRIME(obj);
6928 break;
6929 default:
6930 return (B_FALSE);
6931 }
6932 } else {
6933 return (B_FALSE);
6934 }
6935 compare_bigint = B_TRUE;
6936 break;
6937 case CKA_BASE:
6938 if (obj->class == CKO_PUBLIC_KEY) {
6939 switch (obj->key_type) {
6940 case CKK_DSA:
6941 bigint = OBJ_PUB_DSA_BASE(obj);
6942 break;
6943 case CKK_DH:
6944 bigint = OBJ_PUB_DH_BASE(obj);
6945 break;
6946 case CKK_X9_42_DH:
6947 bigint = OBJ_PUB_DH942_BASE(obj);
6948 break;
6949 default:
6950 return (B_FALSE);
6951 }
6952 } else if (obj->class == CKO_PRIVATE_KEY) {
6953 switch (obj->key_type) {
6954 case CKK_DSA:
6955 bigint = OBJ_PRI_DSA_BASE(obj);
6956 break;
6957 case CKK_DH:
6958 bigint = OBJ_PRI_DH_BASE(obj);
6959 break;
6960 case CKK_X9_42_DH:
6961 bigint = OBJ_PRI_DH942_BASE(obj);
6962 break;
6963 default:
6964 return (B_FALSE);
6965 }
6966 } else if (obj->class == CKO_DOMAIN_PARAMETERS) {
6967 switch (obj->key_type) {
6968 case CKK_DSA:
6969 bigint = OBJ_DOM_DSA_BASE(obj);
6970 break;
6971 case CKK_DH:
6972 bigint = OBJ_DOM_DH_BASE(obj);
6973 break;
6974 case CKK_X9_42_DH:
6975 bigint = OBJ_DOM_DH942_BASE(obj);
6976 break;
6977 default:
6978 return (B_FALSE);
6979 }
6980 } else {
6981 return (B_FALSE);
6982 }
6983 compare_bigint = B_TRUE;
6984 break;
6985 case CKA_PRIME_BITS:
6986 if (obj->class == CKO_DOMAIN_PARAMETERS) {
6987 CK_ULONG prime_bits;
6988 if (obj->key_type == CKK_DSA) {
6989 prime_bits =
6990 OBJ_DOM_DSA_PRIME_BITS(obj);
6991 } else if (obj->key_type == CKK_DH) {
6992 prime_bits =
6993 OBJ_DOM_DH_PRIME_BITS(obj);
6994 } else if (obj->key_type == CKK_X9_42_DH) {
6995 prime_bits =
6996 OBJ_DOM_DH942_PRIME_BITS(obj);
6997 } else {
6998 return (B_FALSE);
6999 }
7000 if (prime_bits !=
7001 *((CK_ULONG *)tmpl_attr->pValue)) {
7002 return (B_FALSE);
7003 }
7004 } else {
7005 return (B_FALSE);
7006 }
7007 break;
7008 case CKA_SUBPRIME_BITS:
7009 if ((obj->class == CKO_DOMAIN_PARAMETERS) &&
7010 (obj->key_type == CKK_X9_42_DH)) {
7011 CK_ULONG subprime_bits =
7012 OBJ_DOM_DH942_SUBPRIME_BITS(obj);
7013 if (subprime_bits !=
7014 *((CK_ULONG *)tmpl_attr->pValue)) {
7015 return (B_FALSE);
7016 }
7017 } else {
7018 return (B_FALSE);
7019 }
7020 break;
7021 default:
7022 /*
7023 * any other attributes are currently not supported.
7024 * so, it's not possible for them to be in the
7025 * object
7026 */
7027 return (B_FALSE);
7028 }
7029 if (compare_boolean) {
7030 CK_BBOOL bval;
7031
7032 if (attr_mask) {
7033 bval = TRUE;
7034 } else {
7035 bval = FALSE;
7036 }
7037 if (bval != *((CK_BBOOL *)tmpl_attr->pValue)) {
7038 return (B_FALSE);
7039 }
7040 } else if (compare_bigint) {
7041 if (bigint == NULL) {
7042 return (B_FALSE);
7043 }
7044 if (tmpl_attr->ulValueLen != bigint->big_value_len) {
7045 return (B_FALSE);
7046 }
7047 if (memcmp(tmpl_attr->pValue, bigint->big_value,
7048 tmpl_attr->ulValueLen) != 0) {
7049 return (B_FALSE);
7050 }
7051 } else if (compare_attr) {
7052 if (obj_attr == NULL) {
7053 /*
7054 * The attribute type is valid, and its value
7055 * has not been initialized in the object. In
7056 * this case, it only matches the template's
7057 * attribute if the template's value length
7058 * is 0.
7059 */
7060 if (tmpl_attr->ulValueLen != 0)
7061 return (B_FALSE);
7062 } else {
7063 if (tmpl_attr->ulValueLen !=
7064 obj_attr->ulValueLen) {
7065 return (B_FALSE);
7066 }
7067 if (memcmp(tmpl_attr->pValue, obj_attr->pValue,
7068 tmpl_attr->ulValueLen) != 0) {
7069 return (B_FALSE);
7070 }
7071 }
7072 } else if (compare_cert_val) {
7073 if (cert_attr == NULL) {
7074 /* specific attribute not found */
7075 return (B_FALSE);
7076 }
7077 if (tmpl_attr->ulValueLen != cert_attr->length) {
7078 return (B_FALSE);
7079 }
7080 if (memcmp(tmpl_attr->pValue, cert_attr->value,
7081 tmpl_attr->ulValueLen) != 0) {
7082 return (B_FALSE);
7083 }
7084 } else if (compare_cert_type) {
7085 if (memcmp(tmpl_attr->pValue, &(obj->cert_type),
7086 tmpl_attr->ulValueLen) != 0) {
7087 return (B_FALSE);
7088 }
7089 }
7090 }
7091 return (B_TRUE);
7092 }
7093
7094 CK_ATTRIBUTE_PTR
7095 get_extra_attr(CK_ATTRIBUTE_TYPE type, soft_object_t *obj)
7096 {
7097 CK_ATTRIBUTE_INFO_PTR tmp;
7098
7099 tmp = obj->extra_attrlistp;
7100 while (tmp != NULL) {
7101 if (tmp->attr.type == type) {
7102 return (&(tmp->attr));
7103 }
7104 tmp = tmp->next;
7105 }
7106 /* if get there, the specified attribute is not found */
7107 return (NULL);
7108 }
7109