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