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