xref: /illumos-gate/usr/src/lib/pkcs11/pkcs11_tpm/common/template.c (revision 47e946e784719ae402ace34695f67b0e6e76ae5c)
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