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