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