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