1 /* 2 * Common Public License Version 0.5 3 * 4 * THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF 5 * THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, 6 * REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES 7 * RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 8 * 9 * 1. DEFINITIONS 10 * 11 * "Contribution" means: 12 * a) in the case of the initial Contributor, the 13 * initial code and documentation distributed under 14 * this Agreement, and 15 * 16 * b) in the case of each subsequent Contributor: 17 * i) changes to the Program, and 18 * ii) additions to the Program; 19 * 20 * where such changes and/or additions to the Program 21 * originate from and are distributed by that 22 * particular Contributor. A Contribution 'originates' 23 * from a Contributor if it was added to the Program 24 * by such Contributor itself or anyone acting on such 25 * Contributor's behalf. Contributions do not include 26 * additions to the Program which: (i) are separate 27 * modules of software distributed in conjunction with 28 * the Program under their own license agreement, and 29 * (ii) are not derivative works of the Program. 30 * 31 * 32 * "Contributor" means any person or entity that distributes 33 * the Program. 34 * 35 * "Licensed Patents " mean patent claims licensable by a 36 * Contributor which are necessarily infringed by the use or 37 * sale of its Contribution alone or when combined with the 38 * Program. 39 * 40 * "Program" means the Contributions distributed in 41 * accordance with this Agreement. 42 * 43 * "Recipient" means anyone who receives the Program under 44 * this Agreement, including all Contributors. 45 * 46 * 2. GRANT OF RIGHTS 47 * 48 * a) Subject to the terms of this Agreement, each 49 * Contributor hereby grants Recipient a 50 * no - exclusive, worldwide, royalt - free copyright 51 * license to reproduce, prepare derivative works of, 52 * publicly display, publicly perform, distribute and 53 * sublicense the Contribution of such Contributor, if 54 * any, and such derivative works, in source code and 55 * object code form. 56 * 57 * b) Subject to the terms of this Agreement, each 58 * Contributor hereby grants Recipient a 59 * no - exclusive, worldwide, royalt - free patent 60 * license under Licensed Patents to make, use, sell, 61 * offer to sell, import and otherwise transfer the 62 * Contribution of such Contributor, if any, in source 63 * code and object code form. This patent license 64 * shall apply to the combination of the Contribution 65 * and the Program if, at the time the Contribution is 66 * added by the Contributor, such addition of the 67 * Contribution causes such combination to be covered 68 * by the Licensed Patents. The patent license shall 69 * not apply to any other combinations which include 70 * the Contribution. No hardware per se is licensed 71 * hereunder. 72 * 73 * c) Recipient understands that although each 74 * Contributor grants the licenses to its 75 * Contributions set forth herein, no assurances are 76 * provided by any Contributor that the Program does 77 * not infringe the patent or other intellectual 78 * property rights of any other entity. Each 79 * Contributor disclaims any liability to Recipient 80 * for claims brought by any other entity based on 81 * infringement of intellectual property rights or 82 * otherwise. As a condition to exercising the rights 83 * and licenses granted hereunder, each Recipient 84 * hereby assumes sole responsibility to secure any 85 * other intellectual property rights needed, if any. 86 * 87 * For example, if a third party patent license is 88 * required to allow Recipient to distribute the 89 * Program, it is Recipient's responsibility to 90 * acquire that license before distributing the 91 * Program. 92 * 93 * d) Each Contributor represents that to its 94 * knowledge it has sufficient copyright rights in its 95 * Contribution, if any, to grant the copyright 96 * license set forth in this Agreement. 97 * 98 * 3. REQUIREMENTS 99 * 100 * A Contributor may choose to distribute the Program in 101 * object code form under its own license agreement, provided 102 * that: 103 * a) it complies with the terms and conditions of 104 * this Agreement; and 105 * 106 * b) its license agreement: 107 * i) effectively disclaims on behalf of all 108 * Contributors all warranties and conditions, express 109 * and implied, including warranties or conditions of 110 * title and no - infringement, and implied warranties 111 * or conditions of merchantability and fitness for a 112 * particular purpose; 113 * 114 * ii) effectively excludes on behalf of all 115 * Contributors all liability for damages, including 116 * direct, indirect, special, incidental and 117 * consequential damages, such as lost profits; 118 * 119 * iii) states that any provisions which differ from 120 * this Agreement are offered by that Contributor 121 * alone and not by any other party; and 122 * 123 * iv) states that source code for the Program is 124 * available from such Contributor, and informs 125 * licensees how to obtain it in a reasonable manner 126 * on or through a medium customarily used for 127 * software exchange. 128 * 129 * When the Program is made available in source code form: 130 * a) it must be made available under this Agreement; 131 * and 132 * b) a copy of this Agreement must be included with 133 * each copy of the Program. 134 * 135 * Contributors may not remove or alter any copyright notices 136 * contained within the Program. 137 * 138 * Each Contributor must identify itself as the originator of 139 * its Contribution, if any, in a manner that reasonably 140 * allows subsequent Recipients to identify the originator of 141 * the Contribution. 142 * 143 * 144 * 4. COMMERCIAL DISTRIBUTION 145 * 146 * Commercial distributors of software may accept certain 147 * responsibilities with respect to end users, business 148 * partners and the like. While this license is intended to 149 * facilitate the commercial use of the Program, the 150 * Contributor who includes the Program in a commercial 151 * product offering should do so in a manner which does not 152 * create potential liability for other Contributors. 153 * Therefore, if a Contributor includes the Program in a 154 * commercial product offering, such Contributor ("Commercial 155 * Contributor") hereby agrees to defend and indemnify every 156 * other Contributor ("Indemnified Contributor") against any 157 * losses, damages and costs (collectively "Losses") arising 158 * from claims, lawsuits and other legal actions brought by a 159 * third party against the Indemnified Contributor to the 160 * extent caused by the acts or omissions of such Commercial 161 * Contributor in connection with its distribution of the 162 * Program in a commercial product offering. The obligations 163 * in this section do not apply to any claims or Losses 164 * relating to any actual or alleged intellectual property 165 * infringement. In order to qualify, an Indemnified 166 * Contributor must: a) promptly notify the Commercial 167 * Contributor in writing of such claim, and b) allow the 168 * Commercial Contributor to control, and cooperate with the 169 * Commercial Contributor in, the defense and any related 170 * settlement negotiations. The Indemnified Contributor may 171 * participate in any such claim at its own expense. 172 * 173 * 174 * For example, a Contributor might include the Program in a 175 * commercial product offering, Product X. That Contributor 176 * is then a Commercial Contributor. If that Commercial 177 * Contributor then makes performance claims, or offers 178 * warranties related to Product X, those performance claims 179 * and warranties are such Commercial Contributor's 180 * responsibility alone. Under this section, the Commercial 181 * Contributor would have to defend claims against the other 182 * Contributors related to those performance claims and 183 * warranties, and if a court requires any other Contributor 184 * to pay any damages as a result, the Commercial Contributor 185 * must pay those damages. 186 * 187 * 188 * 5. NO WARRANTY 189 * 190 * EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE 191 * PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT 192 * WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR 193 * IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR 194 * CONDITIONS OF TITLE, NO - INFRINGEMENT, MERCHANTABILITY OR 195 * FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely 196 * responsible for determining the appropriateness of using 197 * and distributing the Program and assumes all risks 198 * associated with its exercise of rights under this 199 * Agreement, including but not limited to the risks and 200 * costs of program errors, compliance with applicable laws, 201 * damage to or loss of data, programs or equipment, and 202 * unavailability or interruption of operations. 203 * 204 * 6. DISCLAIMER OF LIABILITY 205 * EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER 206 * RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY 207 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, 208 * OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION 209 * LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF 210 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 211 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 212 * OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE 213 * OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE 214 * POSSIBILITY OF SUCH DAMAGES. 215 * 216 * 7. GENERAL 217 * 218 * If any provision of this Agreement is invalid or 219 * unenforceable under applicable law, it shall not affect 220 * the validity or enforceability of the remainder of the 221 * terms of this Agreement, and without further action by the 222 * parties hereto, such provision shall be reformed to the 223 * minimum extent necessary to make such provision valid and 224 * enforceable. 225 * 226 * 227 * If Recipient institutes patent litigation against a 228 * Contributor with respect to a patent applicable to 229 * software (including a cros - claim or counterclaim in a 230 * lawsuit), then any patent licenses granted by that 231 * Contributor to such Recipient under this Agreement shall 232 * terminate as of the date such litigation is filed. In 233 * addition, If Recipient institutes patent litigation 234 * against any entity (including a cros - claim or 235 * counterclaim in a lawsuit) alleging that the Program 236 * itself (excluding combinations of the Program with other 237 * software or hardware) infringes such Recipient's 238 * patent(s), then such Recipient's rights granted under 239 * Section 2(b) shall terminate as of the date such 240 * litigation is filed. 241 * 242 * All Recipient's rights under this Agreement shall 243 * terminate if it fails to comply with any of the material 244 * terms or conditions of this Agreement and does not cure 245 * such failure in a reasonable period of time after becoming 246 * aware of such noncompliance. If all Recipient's rights 247 * under this Agreement terminate, Recipient agrees to cease 248 * use and distribution of the Program as soon as reasonably 249 * practicable. However, Recipient's obligations under this 250 * Agreement and any licenses granted by Recipient relating 251 * to the Program shall continue and survive. 252 * 253 * Everyone is permitted to copy and distribute copies of 254 * this Agreement, but in order to avoid inconsistency the 255 * Agreement is copyrighted and may only be modified in the 256 * following manner. The Agreement Steward reserves the right 257 * to publish new versions (including revisions) of this 258 * Agreement from time to time. No one other than the 259 * Agreement Steward has the right to modify this Agreement. 260 * 261 * IBM is the initial Agreement Steward. IBM may assign the 262 * responsibility to serve as the Agreement Steward to a 263 * suitable separate entity. Each new version of the 264 * Agreement will be given a distinguishing version number. 265 * The Program (including Contributions) may always be 266 * distributed subject to the version of the Agreement under 267 * which it was received. In addition, after a new version of 268 * the Agreement is published, Contributor may elect to 269 * distribute the Program (including its Contributions) under 270 * the new version. Except as expressly stated in Sections 271 * 2(a) and 2(b) above, Recipient receives no rights or 272 * licenses to the intellectual property of any Contributor 273 * under this Agreement, whether expressly, by implication, 274 * estoppel or otherwise. All rights in the Program not 275 * expressly granted under this Agreement are reserved. 276 * 277 * 278 * This Agreement is governed by the laws of the State of New 279 * York and the intellectual property laws of the United 280 * States of America. No party to this Agreement will bring a 281 * legal action under this Agreement more than one year after 282 * the cause of action arose. Each party waives its rights to 283 * a jury trial in any resulting litigation. 284 * 285 * 286 * 287 * (C) COPYRIGHT International Business Machines Corp. 2001, 2002 288 */ 289 /* 290 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 291 * Use is subject to license terms. 292 */ 293 294 #include "tpmtok_int.h" 295 296 // template_add_attributes() 297 // 298 // blindly add the given attributes to the template. do no sanity checking 299 // at this point. sanity checking will occur later. 300 // 301 CK_RV 302 template_add_attributes(TEMPLATE * tmpl, 303 CK_ATTRIBUTE * pTemplate, 304 CK_ULONG ulCount) 305 { 306 CK_ATTRIBUTE * attr = NULL; 307 CK_RV rc; 308 unsigned int i; 309 310 for (i = 0; i < ulCount; i++) { 311 if (! is_attribute_defined(pTemplate[i].type)) { 312 return (CKR_ATTRIBUTE_TYPE_INVALID); 313 } 314 attr = (CK_ATTRIBUTE *)malloc(sizeof (CK_ATTRIBUTE) + 315 pTemplate[i].ulValueLen); 316 if (! attr) { 317 return (CKR_HOST_MEMORY); 318 } 319 attr->type = pTemplate[i].type; 320 attr->ulValueLen = pTemplate[i].ulValueLen; 321 322 if (attr->ulValueLen != 0) { 323 attr->pValue = (CK_BYTE *)attr + sizeof (CK_ATTRIBUTE); 324 (void) memcpy(attr->pValue, pTemplate[i].pValue, 325 attr->ulValueLen); 326 } else 327 attr->pValue = NULL; 328 329 rc = template_update_attribute(tmpl, attr); 330 if (rc != CKR_OK) { 331 free(attr); 332 return (rc); 333 } 334 } 335 336 return (CKR_OK); 337 } 338 339 340 // template_add_default_attributes() 341 // 342 CK_RV 343 template_add_default_attributes(TEMPLATE * tmpl, 344 CK_ULONG class, 345 CK_ULONG subclass, 346 CK_ULONG mode) 347 { 348 CK_RV rc; 349 350 // first add the default common attributes 351 // 352 rc = template_set_default_common_attributes(tmpl); 353 if (rc != CKR_OK) { 354 return (rc); 355 } 356 // set the template class - specific default attributes 357 // 358 switch (class) { 359 case CKO_DATA: 360 return (data_object_set_default_attributes(tmpl, mode)); 361 case CKO_CERTIFICATE: 362 if (subclass == CKC_X_509) 363 return (cert_x509_set_default_attributes(tmpl, mode)); 364 else 365 return (CKR_OK); 366 case CKO_PUBLIC_KEY: 367 switch (subclass) { 368 case CKK_RSA: 369 return (rsa_publ_set_default_attributes( 370 tmpl, mode)); 371 default: 372 return (CKR_ATTRIBUTE_VALUE_INVALID); 373 } 374 375 case CKO_PRIVATE_KEY: 376 switch (subclass) { 377 case CKK_RSA: 378 return (rsa_priv_set_default_attributes( 379 tmpl, mode)); 380 default: 381 return (CKR_ATTRIBUTE_VALUE_INVALID); 382 } 383 384 case CKO_SECRET_KEY: 385 switch (subclass) { 386 case CKK_GENERIC_SECRET: 387 return (generic_secret_set_default_attributes( 388 tmpl, mode)); 389 default: 390 return (CKR_ATTRIBUTE_VALUE_INVALID); 391 } 392 393 case CKO_HW_FEATURE: 394 switch (subclass) { 395 case CKH_CLOCK: 396 return (clock_set_default_attributes( 397 tmpl)); 398 case CKH_MONOTONIC_COUNTER: 399 return (counter_set_default_attributes( 400 tmpl)); 401 default: 402 return (CKR_ATTRIBUTE_VALUE_INVALID); 403 } 404 405 case CKO_DOMAIN_PARAMETERS: 406 switch (subclass) { 407 default: 408 return (CKR_ATTRIBUTE_VALUE_INVALID); 409 } 410 411 default: 412 return (CKR_ATTRIBUTE_VALUE_INVALID); 413 } 414 } 415 416 // template_attribute_find() 417 // 418 // find the attribute in the list and return (its value 419 // 420 CK_BBOOL 421 template_attribute_find(TEMPLATE * tmpl, 422 CK_ATTRIBUTE_TYPE type, 423 CK_ATTRIBUTE ** attr) 424 { 425 DL_NODE * node = NULL; 426 CK_ATTRIBUTE * a = NULL; 427 428 if (! tmpl || ! attr) 429 return (FALSE); 430 node = tmpl->attribute_list; 431 432 while (node != NULL) { 433 a = (CK_ATTRIBUTE *)node->data; 434 435 if (type == a->type) { 436 *attr = a; 437 return (TRUE); 438 } 439 440 node = node->next; 441 } 442 443 *attr = NULL; 444 return (FALSE); 445 } 446 447 // template_attribute_find_multiple() 448 // 449 // find the attributes in the list and return (their values 450 // 451 void 452 template_attribute_find_multiple(TEMPLATE * tmpl, 453 ATTRIBUTE_PARSE_LIST * parselist, 454 CK_ULONG plcount) 455 { 456 CK_ATTRIBUTE * attr = NULL; 457 CK_ULONG i; 458 459 for (i = 0; i < plcount; i++) { 460 parselist[i].found = template_attribute_find( 461 tmpl, parselist[i].type, &attr); 462 463 if (parselist[i].found && parselist[i].ptr != NULL) 464 (void) memcpy(parselist[i].ptr, attr->pValue, 465 parselist[i].len); 466 } 467 } 468 469 CK_RV 470 template_check_required_attributes(TEMPLATE * tmpl, 471 CK_ULONG class, 472 CK_ULONG subclass, 473 CK_ULONG mode) 474 { 475 if (class == CKO_DATA) 476 return (data_object_check_required_attributes( 477 tmpl, mode)); 478 else if (class == CKO_CERTIFICATE) { 479 if (subclass == CKC_X_509) 480 return (cert_x509_check_required_attributes( 481 tmpl, mode)); 482 else 483 return (cert_vendor_check_required_attributes( 484 tmpl, mode)); 485 } else if (class == CKO_PUBLIC_KEY) { 486 switch (subclass) { 487 case CKK_RSA: 488 return (rsa_publ_check_required_attributes( 489 tmpl, mode)); 490 default: 491 return (CKR_ATTRIBUTE_VALUE_INVALID); 492 } 493 } else if (class == CKO_PRIVATE_KEY) { 494 switch (subclass) { 495 case CKK_RSA: 496 return (rsa_priv_check_required_attributes( 497 tmpl, mode)); 498 default: 499 return (CKR_ATTRIBUTE_VALUE_INVALID); 500 } 501 } else if (class == CKO_SECRET_KEY) { 502 switch (subclass) { 503 case CKK_GENERIC_SECRET: 504 return ( 505 generic_secret_check_required_attributes( 506 tmpl, mode)); 507 default: 508 return (CKR_ATTRIBUTE_VALUE_INVALID); 509 } 510 } else if (class == CKO_HW_FEATURE) { 511 512 switch (subclass) { 513 case CKH_CLOCK: 514 return ( 515 clock_check_required_attributes( 516 tmpl, mode)); 517 case CKH_MONOTONIC_COUNTER: 518 return ( 519 counter_check_required_attributes( 520 tmpl, mode)); 521 default: 522 return (CKR_ATTRIBUTE_VALUE_INVALID); 523 } 524 } else if (class == CKO_DOMAIN_PARAMETERS) { 525 switch (subclass) { 526 default: 527 return (CKR_ATTRIBUTE_VALUE_INVALID); 528 } 529 } 530 return (CKR_ATTRIBUTE_VALUE_INVALID); 531 } 532 533 534 // template_check_required_base_attributes() 535 // 536 // check to make sure that attributes required by Cryptoki are 537 // present. does not check to see if the attribute makes sense 538 // for the particular object (that is done in the 'validate' routines) 539 // 540 CK_RV 541 template_check_required_base_attributes(TEMPLATE * tmpl, 542 CK_ULONG mode) 543 { 544 CK_ATTRIBUTE * attr; 545 CK_BBOOL found; 546 547 found = template_attribute_find(tmpl, CKA_CLASS, &attr); 548 if (mode == MODE_CREATE && found == FALSE) 549 return (CKR_TEMPLATE_INCOMPLETE); 550 return (CKR_OK); 551 } 552 553 554 // template_compare() 555 // 556 CK_BBOOL 557 template_compare(CK_ATTRIBUTE * t1, 558 CK_ULONG ulCount, 559 TEMPLATE * t2) { 560 CK_ATTRIBUTE * attr1 = NULL; 561 CK_ATTRIBUTE * attr2 = NULL; 562 CK_ULONG i; 563 CK_RV rc; 564 565 if (! t1 || ! t2) 566 return (FALSE); 567 attr1 = t1; 568 569 for (i = 0; i < ulCount; i++) { 570 rc = template_attribute_find(t2, attr1->type, &attr2); 571 if (rc == FALSE) 572 return (FALSE); 573 if (attr1->ulValueLen != attr2->ulValueLen) 574 return (FALSE); 575 if (memcmp(attr1->pValue, attr2->pValue, attr1->ulValueLen) 576 != 0) 577 return (FALSE); 578 attr1++; 579 } 580 581 return (TRUE); 582 } 583 584 // template_copy() 585 // 586 // This doesn't copy the template items verbatim. The new template is in 587 // the reverse order of the old one. This should not have any effect. 588 // 589 // This is very similar to template_merge(). template_merge() can also 590 // be used to copy a list (of unique attributes) but is slower because for 591 // each attribute, it must search through the list. 592 // 593 CK_RV 594 template_copy(TEMPLATE *dest, TEMPLATE *src) { 595 DL_NODE *node; 596 597 if (! dest || ! src) { 598 return (CKR_FUNCTION_FAILED); 599 } 600 node = src->attribute_list; 601 602 while (node) { 603 CK_ATTRIBUTE *attr = (CK_ATTRIBUTE *)node->data; 604 CK_ATTRIBUTE *new_attr = NULL; 605 CK_ULONG len; 606 607 len = sizeof (CK_ATTRIBUTE) + attr->ulValueLen; 608 609 new_attr = (CK_ATTRIBUTE *)malloc(len); 610 if (! new_attr) { 611 return (CKR_HOST_MEMORY); 612 } 613 (void) memcpy(new_attr, attr, len); 614 615 new_attr->pValue = (CK_BYTE *)new_attr + sizeof (CK_ATTRIBUTE); 616 617 dest->attribute_list = dlist_add_as_first(dest->attribute_list, 618 new_attr); 619 620 node = node->next; 621 } 622 623 return (CKR_OK); 624 } 625 626 627 // template_flatten() - this still gets used when saving token objects to disk 628 // 629 CK_RV 630 template_flatten(TEMPLATE * tmpl, 631 CK_BYTE * dest) 632 { 633 DL_NODE * node = NULL; 634 CK_BYTE * ptr = NULL; 635 CK_ULONG_32 long_len; 636 CK_ATTRIBUTE_32 *attr_32 = NULL; 637 CK_ULONG Val; 638 CK_ULONG_32 Val_32; 639 CK_ULONG * pVal; 640 long_len = sizeof (CK_ULONG); 641 642 if (! tmpl || ! dest) { 643 return (CKR_FUNCTION_FAILED); 644 } 645 ptr = dest; 646 node = tmpl->attribute_list; 647 while (node) { 648 CK_ATTRIBUTE *attr = (CK_ATTRIBUTE *)node->data; 649 650 if (long_len == 4) { 651 (void) memcpy(ptr, attr, sizeof (CK_ATTRIBUTE) + 652 attr->ulValueLen); 653 ptr += sizeof (CK_ATTRIBUTE) + attr->ulValueLen; 654 } else { 655 attr_32 = malloc(sizeof (CK_ATTRIBUTE_32)); 656 if (! attr_32) { 657 return (CKR_HOST_MEMORY); 658 } 659 attr_32->type = attr->type; 660 attr_32->pValue = 0x00; 661 if ((attr->type == CKA_CLASS || 662 attr->type == CKA_KEY_TYPE || 663 attr->type == CKA_MODULUS_BITS || 664 attr->type == CKA_VALUE_BITS || 665 attr->type == CKA_CERTIFICATE_TYPE || 666 attr->type == CKA_VALUE_LEN) && 667 attr->ulValueLen != 0) { 668 669 attr_32->ulValueLen = sizeof (CK_ULONG_32); 670 671 (void) memcpy(ptr, attr_32, 672 sizeof (CK_ATTRIBUTE_32)); 673 ptr += sizeof (CK_ATTRIBUTE_32); 674 675 pVal = (CK_ULONG *)attr->pValue; 676 Val = *pVal; 677 Val_32 = (CK_ULONG_32)Val; 678 (void) memcpy(ptr, &Val_32, 679 sizeof (CK_ULONG_32)); 680 ptr += sizeof (CK_ULONG_32); 681 } else { 682 attr_32->ulValueLen = attr->ulValueLen; 683 (void) memcpy(ptr, attr_32, 684 sizeof (CK_ATTRIBUTE_32)); 685 ptr += sizeof (CK_ATTRIBUTE_32); 686 if (attr->ulValueLen != 0) { 687 (void) memcpy(ptr, attr->pValue, 688 attr->ulValueLen); 689 ptr += attr->ulValueLen; 690 } 691 } 692 } 693 694 695 696 node = node->next; 697 } 698 699 if (attr_32) 700 free(attr_32); 701 702 return (CKR_OK); 703 } 704 705 CK_RV 706 template_unflatten(TEMPLATE ** new_tmpl, 707 CK_BYTE * buf, 708 CK_ULONG count) 709 { 710 TEMPLATE * tmpl = NULL; 711 CK_ATTRIBUTE * a2 = NULL; 712 CK_BYTE *ptr = NULL; 713 CK_ULONG i, len; 714 CK_RV rc; 715 CK_ULONG_32 long_len = sizeof (CK_ULONG); 716 CK_ULONG_32 attr_ulong_32; 717 CK_ULONG attr_ulong; 718 CK_ATTRIBUTE * a1_64 = NULL; 719 CK_ATTRIBUTE_32 * a1 = NULL; 720 721 if (! new_tmpl || ! buf) { 722 return (CKR_FUNCTION_FAILED); 723 } 724 tmpl = (TEMPLATE *)malloc(sizeof (TEMPLATE)); 725 if (! tmpl) { 726 return (CKR_HOST_MEMORY); 727 } 728 (void) memset(tmpl, 0x0, sizeof (TEMPLATE)); 729 730 ptr = buf; 731 for (i = 0; i < count; i++) { 732 if (long_len == 4) { 733 void *aptr = ptr; 734 a1_64 = (CK_ATTRIBUTE *)aptr; 735 736 len = sizeof (CK_ATTRIBUTE) + a1_64->ulValueLen; 737 a2 = (CK_ATTRIBUTE *)malloc(len); 738 if (! a2) { 739 (void) template_free(tmpl); 740 return (CKR_HOST_MEMORY); 741 } 742 743 (void) memcpy(a2, a1_64, len); 744 } else { 745 void *aptr = ptr; 746 a1 = (CK_ATTRIBUTE_32 *)aptr; 747 748 if ((a1->type == CKA_CLASS || 749 a1->type == CKA_KEY_TYPE || 750 a1->type == CKA_MODULUS_BITS || 751 a1->type == CKA_VALUE_BITS || 752 a1->type == CKA_CERTIFICATE_TYPE || 753 a1->type == CKA_VALUE_LEN) && 754 a1->ulValueLen != 0) { 755 len = sizeof (CK_ATTRIBUTE) + sizeof (CK_ULONG); 756 } else { 757 len = sizeof (CK_ATTRIBUTE) + a1->ulValueLen; 758 } 759 760 a2 = (CK_ATTRIBUTE *)malloc(len); 761 if (! a2) { 762 return (CKR_HOST_MEMORY); 763 } 764 a2->type = a1->type; 765 766 if ((a1->type == CKA_CLASS || 767 a1->type == CKA_KEY_TYPE || 768 a1->type == CKA_MODULUS_BITS || 769 a1->type == CKA_VALUE_BITS || 770 a1->type == CKA_CERTIFICATE_TYPE || 771 a1->type == CKA_VALUE_LEN) && 772 a1->ulValueLen != 0) { 773 a2->ulValueLen = sizeof (CK_ULONG); 774 { 775 CK_ULONG_32 *p32; 776 CK_BYTE *pb2; 777 void *aptr = a1; 778 void *bptr; 779 780 pb2 = (CK_BYTE *)aptr; 781 pb2 += sizeof (CK_ATTRIBUTE_32); 782 bptr = pb2; 783 p32 = (CK_ULONG_32 *)bptr; 784 attr_ulong_32 = *p32; 785 } 786 787 attr_ulong = attr_ulong_32; 788 789 { 790 CK_BYTE *pb2; 791 pb2 = (CK_BYTE *)a2; 792 pb2 += sizeof (CK_ATTRIBUTE); 793 (void) memcpy(pb2, 794 (CK_BYTE *)&attr_ulong, 795 sizeof (CK_ULONG)); 796 } 797 } else { 798 CK_BYTE *pb2, *pb; 799 800 a2->ulValueLen = a1->ulValueLen; 801 pb2 = (CK_BYTE *)a2; 802 pb2 += sizeof (CK_ATTRIBUTE); 803 pb = (CK_BYTE *)a1; 804 pb += sizeof (CK_ATTRIBUTE_32); 805 (void) memcpy(pb2, pb, a1->ulValueLen); 806 } 807 } 808 809 810 if (a2->ulValueLen != 0) 811 a2->pValue = (CK_BYTE *)a2 + sizeof (CK_ATTRIBUTE); 812 else 813 a2->pValue = NULL; 814 815 rc = template_update_attribute(tmpl, a2); 816 if (rc != CKR_OK) { 817 free(a2); 818 (void) template_free(tmpl); 819 return (rc); 820 } 821 if (long_len == 4) 822 ptr += len; 823 else 824 ptr += sizeof (CK_ATTRIBUTE_32) + a1->ulValueLen; 825 826 827 } 828 829 *new_tmpl = tmpl; 830 return (CKR_OK); 831 } 832 833 CK_RV 834 template_free(TEMPLATE *tmpl) { 835 if (! tmpl) 836 return (CKR_OK); 837 while (tmpl->attribute_list) { 838 CK_ATTRIBUTE *attr = (CK_ATTRIBUTE *)tmpl->attribute_list->data; 839 840 if (attr) 841 free(attr); 842 843 tmpl->attribute_list = dlist_remove_node(tmpl->attribute_list, 844 tmpl->attribute_list); 845 } 846 847 free(tmpl); 848 return (CKR_OK); 849 } 850 851 CK_BBOOL 852 template_get_class(TEMPLATE * tmpl, 853 CK_ULONG * class, 854 CK_ULONG * subclass) 855 { 856 DL_NODE * node; 857 CK_BBOOL found; 858 859 if (! tmpl || ! class || ! subclass) 860 return (FALSE); 861 node = tmpl->attribute_list; 862 863 while (node) { 864 CK_ATTRIBUTE *attr = (CK_ATTRIBUTE *)node->data; 865 866 if (attr->type == CKA_CLASS) { 867 *class = *(CK_OBJECT_CLASS *)attr->pValue; 868 found = TRUE; 869 } 870 871 if (attr->type == CKA_CERTIFICATE_TYPE) 872 *subclass = *(CK_CERTIFICATE_TYPE *)attr->pValue; 873 874 if (attr->type == CKA_KEY_TYPE) 875 *subclass = *(CK_KEY_TYPE *)attr->pValue; 876 877 node = node->next; 878 } 879 880 return (found); 881 } 882 883 CK_ULONG 884 template_get_count(TEMPLATE *tmpl) 885 { 886 if (tmpl == NULL) 887 return (0); 888 return (dlist_length(tmpl->attribute_list)); 889 } 890 891 CK_ULONG 892 template_get_size(TEMPLATE *tmpl) 893 { 894 DL_NODE * node; 895 CK_ULONG size = 0; 896 897 if (tmpl == NULL) 898 return (0); 899 node = tmpl->attribute_list; 900 while (node) { 901 CK_ATTRIBUTE *attr = (CK_ATTRIBUTE *)node->data; 902 903 size += sizeof (CK_ATTRIBUTE) + attr->ulValueLen; 904 905 node = node->next; 906 } 907 908 return (size); 909 } 910 911 CK_ULONG 912 template_get_compressed_size(TEMPLATE *tmpl) 913 { 914 DL_NODE * node; 915 CK_ULONG size = 0; 916 917 if (tmpl == NULL) 918 return (0); 919 node = tmpl->attribute_list; 920 while (node) { 921 CK_ATTRIBUTE *attr = (CK_ATTRIBUTE *)node->data; 922 923 size += sizeof (CK_ATTRIBUTE_32); 924 if ((attr->type == CKA_CLASS || 925 attr->type == CKA_KEY_TYPE || 926 attr->type == CKA_MODULUS_BITS || 927 attr->type == CKA_VALUE_BITS || 928 attr->type == CKA_CERTIFICATE_TYPE || 929 attr->type == CKA_VALUE_LEN) && 930 attr->ulValueLen != 0) { 931 size += sizeof (CK_ULONG_32); 932 } else { 933 size += attr->ulValueLen; 934 } 935 936 node = node->next; 937 } 938 939 return (size); 940 } 941 942 /* 943 * template_is_okay_to_reveal_attribute() 944 * 945 * determines whether the specified CK_ATTRIBUTE_TYPE is allowed to 946 * be leave the card in the clear. note: the specified template doesn't need 947 * to actually posess an attribute of type 'type'. The template is 948 * provided mainly to determine the object class and subclass 949 * 950 * this routine is called by C_GetAttributeValue which exports the attributes 951 * in the clear. this routine is NOT called when wrapping a key. 952 */ 953 CK_BBOOL 954 template_check_exportability(TEMPLATE *tmpl, CK_ATTRIBUTE_TYPE type) 955 { 956 CK_ATTRIBUTE * attr = NULL; 957 CK_ULONG class; 958 CK_ULONG subclass; 959 CK_BBOOL val; 960 961 if (! tmpl) 962 return (FALSE); 963 (void) template_get_class(tmpl, &class, &subclass); 964 965 if (class != CKO_PRIVATE_KEY && class != CKO_SECRET_KEY) 966 return (TRUE); 967 val = template_attribute_find(tmpl, CKA_SENSITIVE, &attr); 968 if (val) { 969 val = *(CK_BBOOL *)attr->pValue; 970 if (val == FALSE) 971 return (TRUE); 972 } else { 973 return (FALSE); 974 } 975 976 if (class == CKO_PRIVATE_KEY) { 977 switch (subclass) { 978 case CKK_RSA: 979 return (rsa_priv_check_exportability(type)); 980 default: 981 return (CKR_ATTRIBUTE_VALUE_INVALID); 982 } 983 } else if (class == CKO_SECRET_KEY) { 984 return (secret_key_check_exportability(type)); 985 } 986 987 return (CKR_ATTRIBUTE_VALUE_INVALID); 988 } 989 990 CK_RV 991 template_merge(TEMPLATE *dest, TEMPLATE **src) 992 { 993 DL_NODE *node; 994 CK_RV rc; 995 996 if (! dest || ! src) { 997 return (CKR_FUNCTION_FAILED); 998 } 999 node = (*src)->attribute_list; 1000 1001 while (node) { 1002 CK_ATTRIBUTE *attr = (CK_ATTRIBUTE *)node->data; 1003 1004 rc = template_update_attribute(dest, attr); 1005 if (rc != CKR_OK) { 1006 return (rc); 1007 } 1008 node->data = NULL; 1009 node = node->next; 1010 } 1011 1012 (void) template_free(*src); 1013 *src = NULL; 1014 1015 return (CKR_OK); 1016 } 1017 1018 /* 1019 * template_set_default_common_attributes() 1020 * 1021 * Set the default attributes common to all objects: 1022 * 1023 * CKA_TOKEN : FALSE 1024 * CKA_PRIVATE : TRUE -- Cryptoki leaves this up to the token to decide 1025 * CKA_MODIFIABLE : TRUE 1026 * CKA_LABEL : empty string 1027 */ 1028 CK_RV 1029 template_set_default_common_attributes(TEMPLATE *tmpl) 1030 { 1031 CK_ATTRIBUTE * token_attr; 1032 CK_ATTRIBUTE * priv_attr; 1033 CK_ATTRIBUTE * mod_attr; 1034 CK_ATTRIBUTE * label_attr; 1035 1036 token_attr = (CK_ATTRIBUTE *)malloc(sizeof (CK_ATTRIBUTE) + 1037 sizeof (CK_BBOOL)); 1038 priv_attr = (CK_ATTRIBUTE *)malloc(sizeof (CK_ATTRIBUTE) + 1039 sizeof (CK_BBOOL)); 1040 mod_attr = (CK_ATTRIBUTE *)malloc(sizeof (CK_ATTRIBUTE) + 1041 sizeof (CK_BBOOL)); 1042 label_attr = (CK_ATTRIBUTE *)malloc(sizeof (CK_ATTRIBUTE) + 0); 1043 1044 if (! token_attr || ! priv_attr || ! mod_attr || ! label_attr) { 1045 if (token_attr) free(token_attr); 1046 if (priv_attr) free(priv_attr); 1047 if (mod_attr) free(mod_attr); 1048 if (label_attr) free(label_attr); 1049 1050 return (CKR_HOST_MEMORY); 1051 } 1052 1053 token_attr->type = CKA_TOKEN; 1054 token_attr->ulValueLen = sizeof (CK_BBOOL); 1055 token_attr->pValue = (CK_BYTE *)token_attr + sizeof (CK_ATTRIBUTE); 1056 *(CK_BBOOL *)token_attr->pValue = FALSE; 1057 1058 priv_attr->type = CKA_PRIVATE; 1059 priv_attr->ulValueLen = sizeof (CK_BBOOL); 1060 priv_attr->pValue = (CK_BYTE *)priv_attr + sizeof (CK_ATTRIBUTE); 1061 *(CK_BBOOL *)priv_attr->pValue = FALSE; 1062 1063 mod_attr->type = CKA_MODIFIABLE; 1064 mod_attr->ulValueLen = sizeof (CK_BBOOL); 1065 mod_attr->pValue = (CK_BYTE *)mod_attr + sizeof (CK_ATTRIBUTE); 1066 *(CK_BBOOL *)mod_attr->pValue = TRUE; 1067 1068 label_attr->type = CKA_LABEL; 1069 label_attr->ulValueLen = 0; // empty string 1070 label_attr->pValue = NULL; 1071 1072 (void) template_update_attribute(tmpl, token_attr); 1073 (void) template_update_attribute(tmpl, priv_attr); 1074 (void) template_update_attribute(tmpl, mod_attr); 1075 (void) template_update_attribute(tmpl, label_attr); 1076 1077 return (CKR_OK); 1078 } 1079 1080 CK_RV 1081 template_update_attribute(TEMPLATE *tmpl, CK_ATTRIBUTE *new_attr) { 1082 DL_NODE * node = NULL; 1083 CK_ATTRIBUTE * attr = NULL; 1084 1085 if (! tmpl || ! new_attr) { 1086 return (CKR_FUNCTION_FAILED); 1087 } 1088 node = tmpl->attribute_list; 1089 1090 while (node != NULL) { 1091 attr = (CK_ATTRIBUTE *)node->data; 1092 1093 if (new_attr->type == attr->type) { 1094 free(attr); 1095 tmpl->attribute_list = dlist_remove_node( 1096 tmpl->attribute_list, node); 1097 break; 1098 } 1099 1100 node = node->next; 1101 } 1102 1103 tmpl->attribute_list = dlist_add_as_first( 1104 tmpl->attribute_list, new_attr); 1105 1106 return (CKR_OK); 1107 } 1108 1109 CK_RV 1110 template_validate_attribute(TEMPLATE * tmpl, 1111 CK_ATTRIBUTE * attr, 1112 CK_ULONG class, 1113 CK_ULONG subclass, 1114 CK_ULONG mode) 1115 { 1116 if (class == CKO_DATA) 1117 return (data_object_validate_attribute(tmpl, attr, mode)); 1118 else if (class == CKO_CERTIFICATE) { 1119 if (subclass == CKC_X_509) 1120 return (cert_x509_validate_attribute(tmpl, attr, mode)); 1121 else 1122 return (cert_vendor_validate_attribute(tmpl, 1123 attr, mode)); 1124 } else if (class == CKO_PUBLIC_KEY) { 1125 1126 switch (subclass) { 1127 case CKK_RSA: 1128 return (rsa_publ_validate_attribute(tmpl, 1129 attr, mode)); 1130 default: 1131 return (CKR_ATTRIBUTE_VALUE_INVALID); 1132 } 1133 } else if (class == CKO_PRIVATE_KEY) { 1134 1135 switch (subclass) { 1136 case CKK_RSA: 1137 return (rsa_priv_validate_attribute(tmpl, 1138 attr, mode)); 1139 default: 1140 return (CKR_ATTRIBUTE_VALUE_INVALID); 1141 } 1142 } else if (class == CKO_SECRET_KEY) { 1143 switch (subclass) { 1144 case CKK_GENERIC_SECRET: 1145 return (generic_secret_validate_attribute(tmpl, 1146 attr, mode)); 1147 default: 1148 return (CKR_ATTRIBUTE_VALUE_INVALID); 1149 } 1150 } else if (class == CKO_HW_FEATURE) { 1151 1152 switch (subclass) { 1153 case CKH_CLOCK: 1154 return (clock_validate_attribute(tmpl, 1155 attr, mode)); 1156 case CKH_MONOTONIC_COUNTER: 1157 return (counter_validate_attribute(tmpl, 1158 attr, mode)); 1159 default: 1160 return (CKR_ATTRIBUTE_VALUE_INVALID); 1161 } 1162 } else if (class == CKO_DOMAIN_PARAMETERS) { 1163 switch (subclass) { 1164 default: 1165 return (CKR_ATTRIBUTE_VALUE_INVALID); 1166 } 1167 } 1168 return (CKR_ATTRIBUTE_VALUE_INVALID); 1169 } 1170 1171 CK_RV 1172 template_validate_attributes(TEMPLATE * tmpl, 1173 CK_ULONG class, 1174 CK_ULONG subclass, 1175 CK_ULONG mode) 1176 { 1177 DL_NODE *node; 1178 CK_RV rc = CKR_OK; 1179 1180 node = tmpl->attribute_list; 1181 1182 while (node) { 1183 CK_ATTRIBUTE *attr = (CK_ATTRIBUTE *)node->data; 1184 1185 rc = template_validate_attribute(tmpl, attr, class, 1186 subclass, mode); 1187 if (rc != CKR_OK) { 1188 return (rc); 1189 } 1190 node = node->next; 1191 } 1192 1193 return (CKR_OK); 1194 } 1195 1196 CK_RV 1197 template_validate_base_attribute(TEMPLATE * tmpl, 1198 CK_ATTRIBUTE * attr, 1199 CK_ULONG mode) 1200 { 1201 if (! tmpl || ! attr) { 1202 return (CKR_FUNCTION_FAILED); 1203 } 1204 switch (attr->type) { 1205 case CKA_CLASS: 1206 if ((mode & (MODE_CREATE | MODE_DERIVE | 1207 MODE_KEYGEN | MODE_UNWRAP)) != 0) 1208 return (CKR_OK); 1209 break; 1210 1211 case CKA_TOKEN: 1212 if ((mode & (MODE_CREATE | MODE_COPY | 1213 MODE_DERIVE | MODE_KEYGEN | MODE_UNWRAP)) != 0) 1214 return (CKR_OK); 1215 break; 1216 1217 case CKA_PRIVATE: 1218 if ((mode & (MODE_CREATE | MODE_COPY | 1219 MODE_DERIVE | MODE_KEYGEN | MODE_UNWRAP)) != 0) 1220 return (CKR_OK); 1221 break; 1222 1223 case CKA_LABEL: 1224 return (CKR_OK); 1225 case CKA_MODIFIABLE: 1226 if ((mode & (MODE_CREATE | MODE_COPY | 1227 MODE_DERIVE | MODE_KEYGEN | MODE_UNWRAP)) != 0) 1228 return (CKR_OK); 1229 break; 1230 1231 default: 1232 return (CKR_TEMPLATE_INCONSISTENT); 1233 } 1234 1235 return (CKR_ATTRIBUTE_READ_ONLY); 1236 } 1237