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