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