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//
301CK_RV
302template_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//
342CK_RV
343template_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//
420CK_BBOOL
421template_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//
451void
452template_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
469CK_RV
470template_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//
540CK_RV
541template_check_required_base_attributes(TEMPLATE * tmpl,
542CK_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//
556CK_BBOOL
557template_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//
593CK_RV
594template_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//
629CK_RV
630template_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
705CK_RV
706template_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
833CK_RV
834template_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
851CK_BBOOL
852template_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
883CK_ULONG
884template_get_count(TEMPLATE *tmpl)
885{
886	if (tmpl == NULL)
887		return (0);
888	return (dlist_length(tmpl->attribute_list));
889}
890
891CK_ULONG
892template_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
911CK_ULONG
912template_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 */
953CK_BBOOL
954template_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
990CK_RV
991template_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 */
1028CK_RV
1029template_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
1080CK_RV
1081template_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
1109CK_RV
1110template_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
1171CK_RV
1172template_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
1196CK_RV
1197template_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