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