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