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