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