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