template.c revision e6fda97ba28fe3b5aaba49c030a73272719c7cba
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;
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			free(attr_32);
693		}
694		node = node->next;
695	}
696
697	return (CKR_OK);
698}
699
700CK_RV
701template_unflatten(TEMPLATE ** new_tmpl,
702	CK_BYTE   * buf,
703	CK_ULONG    count)
704{
705	TEMPLATE	* tmpl = NULL;
706	CK_ATTRIBUTE  * a2   = NULL;
707	CK_BYTE	*ptr  = NULL;
708	CK_ULONG	i, len;
709	CK_RV	   rc;
710	CK_ULONG_32	long_len = sizeof (CK_ULONG);
711	CK_ULONG_32	attr_ulong_32;
712	CK_ULONG	attr_ulong;
713	CK_ATTRIBUTE * a1_64 = NULL;
714	CK_ATTRIBUTE_32 * a1 = NULL;
715
716	if (! new_tmpl || ! buf) {
717		return (CKR_FUNCTION_FAILED);
718	}
719	tmpl = (TEMPLATE *)malloc(sizeof (TEMPLATE));
720	if (! tmpl) {
721		return (CKR_HOST_MEMORY);
722	}
723	(void) memset(tmpl, 0x0, sizeof (TEMPLATE));
724
725	ptr = buf;
726	for (i = 0; i < count; i++) {
727		if (long_len == 4) {
728			void *aptr = ptr;
729			a1_64 = (CK_ATTRIBUTE *)aptr;
730
731			len = sizeof (CK_ATTRIBUTE) + a1_64->ulValueLen;
732			a2 = (CK_ATTRIBUTE *)malloc(len);
733			if (! a2) {
734				(void) template_free(tmpl);
735				return (CKR_HOST_MEMORY);
736			}
737
738			(void) memcpy(a2, a1_64, len);
739		} else {
740			void *aptr = ptr;
741			a1 = (CK_ATTRIBUTE_32 *)aptr;
742
743			if ((a1->type == CKA_CLASS ||
744			    a1->type == CKA_KEY_TYPE ||
745			    a1->type == CKA_MODULUS_BITS ||
746			    a1->type == CKA_VALUE_BITS ||
747			    a1->type == CKA_CERTIFICATE_TYPE ||
748			    a1->type == CKA_VALUE_LEN) &&
749			    a1->ulValueLen != 0) {
750				len = sizeof (CK_ATTRIBUTE) + sizeof (CK_ULONG);
751			} else {
752				len = sizeof (CK_ATTRIBUTE) + a1->ulValueLen;
753			}
754
755			a2 = (CK_ATTRIBUTE *)malloc(len);
756			if (! a2) {
757				return (CKR_HOST_MEMORY);
758			}
759			a2->type = a1->type;
760
761			if ((a1->type == CKA_CLASS ||
762			    a1->type == CKA_KEY_TYPE ||
763			    a1->type == CKA_MODULUS_BITS ||
764			    a1->type == CKA_VALUE_BITS ||
765			    a1->type == CKA_CERTIFICATE_TYPE ||
766			    a1->type == CKA_VALUE_LEN) &&
767			    a1->ulValueLen != 0) {
768				a2->ulValueLen = sizeof (CK_ULONG);
769				{
770					CK_ULONG_32 *p32;
771					CK_BYTE *pb2;
772					void *aptr = a1;
773					void *bptr;
774
775					pb2 = (CK_BYTE *)aptr;
776					pb2 += sizeof (CK_ATTRIBUTE_32);
777					bptr = pb2;
778					p32 = (CK_ULONG_32 *)bptr;
779					attr_ulong_32 = *p32;
780				}
781
782				attr_ulong = attr_ulong_32;
783
784				{
785					CK_BYTE *pb2;
786					pb2 = (CK_BYTE *)a2;
787					pb2 += sizeof (CK_ATTRIBUTE);
788					(void) memcpy(pb2,
789					    (CK_BYTE *)&attr_ulong,
790					    sizeof (CK_ULONG));
791				}
792			} else {
793				CK_BYTE *pb2, *pb;
794
795				a2->ulValueLen = a1->ulValueLen;
796				pb2 = (CK_BYTE *)a2;
797				pb2 += sizeof (CK_ATTRIBUTE);
798				pb = (CK_BYTE *)a1;
799				pb += sizeof (CK_ATTRIBUTE_32);
800				(void) memcpy(pb2, pb, a1->ulValueLen);
801			}
802		}
803
804
805		if (a2->ulValueLen != 0)
806			a2->pValue = (CK_BYTE *)a2 + sizeof (CK_ATTRIBUTE);
807		else
808			a2->pValue = NULL;
809
810		rc = template_update_attribute(tmpl, a2);
811		if (rc != CKR_OK) {
812			free(a2);
813			(void) template_free(tmpl);
814			return (rc);
815		}
816		if (long_len == 4)
817			ptr += len;
818		else
819			ptr += sizeof (CK_ATTRIBUTE_32) + a1->ulValueLen;
820
821
822	}
823
824		*new_tmpl = tmpl;
825	return (CKR_OK);
826}
827
828CK_RV
829template_free(TEMPLATE *tmpl) {
830	if (! tmpl)
831		return (CKR_OK);
832	while (tmpl->attribute_list) {
833		CK_ATTRIBUTE *attr = (CK_ATTRIBUTE *)tmpl->attribute_list->data;
834
835		if (attr)
836			free(attr);
837
838		tmpl->attribute_list = dlist_remove_node(tmpl->attribute_list,
839		tmpl->attribute_list);
840	}
841
842	free(tmpl);
843	return (CKR_OK);
844}
845
846CK_BBOOL
847template_get_class(TEMPLATE  * tmpl,
848	CK_ULONG  * class,
849	CK_ULONG  * subclass)
850{
851	DL_NODE * node;
852	CK_BBOOL  found;
853
854	if (! tmpl || ! class || ! subclass)
855		return (FALSE);
856	node = tmpl->attribute_list;
857
858	while (node) {
859		CK_ATTRIBUTE *attr = (CK_ATTRIBUTE *)node->data;
860
861		if (attr->type == CKA_CLASS) {
862			*class = *(CK_OBJECT_CLASS *)attr->pValue;
863			found = TRUE;
864		}
865
866		if (attr->type == CKA_CERTIFICATE_TYPE)
867			*subclass = *(CK_CERTIFICATE_TYPE *)attr->pValue;
868
869		if (attr->type == CKA_KEY_TYPE)
870			*subclass = *(CK_KEY_TYPE *)attr->pValue;
871
872		node = node->next;
873	}
874
875	return (found);
876}
877
878CK_ULONG
879template_get_count(TEMPLATE *tmpl)
880{
881	if (tmpl == NULL)
882		return (0);
883	return (dlist_length(tmpl->attribute_list));
884}
885
886CK_ULONG
887template_get_size(TEMPLATE *tmpl)
888{
889	DL_NODE   * node;
890	CK_ULONG    size = 0;
891
892	if (tmpl == NULL)
893		return (0);
894	node = tmpl->attribute_list;
895	while (node) {
896		CK_ATTRIBUTE *attr = (CK_ATTRIBUTE *)node->data;
897
898		size += sizeof (CK_ATTRIBUTE) + attr->ulValueLen;
899
900		node = node->next;
901	}
902
903	return (size);
904}
905
906CK_ULONG
907template_get_compressed_size(TEMPLATE *tmpl)
908{
909	DL_NODE   * node;
910	CK_ULONG    size = 0;
911
912	if (tmpl == NULL)
913		return (0);
914	node = tmpl->attribute_list;
915	while (node) {
916		CK_ATTRIBUTE *attr = (CK_ATTRIBUTE *)node->data;
917
918		size += sizeof (CK_ATTRIBUTE_32);
919		if ((attr->type == CKA_CLASS ||
920		    attr->type == CKA_KEY_TYPE ||
921		    attr->type == CKA_MODULUS_BITS ||
922		    attr->type == CKA_VALUE_BITS ||
923		    attr->type == CKA_CERTIFICATE_TYPE ||
924		    attr->type == CKA_VALUE_LEN) &&
925		    attr->ulValueLen != 0) {
926			size += sizeof (CK_ULONG_32);
927		} else {
928			size += attr->ulValueLen;
929		}
930
931		node = node->next;
932	}
933
934	return (size);
935}
936
937/*
938 * template_is_okay_to_reveal_attribute()
939 *
940 * determines whether the specified CK_ATTRIBUTE_TYPE is allowed to
941 * be leave the card in the clear.  note: the specified template doesn't need
942 * to actually posess an attribute of type 'type'.  The template is
943 * provided mainly to determine the object class and subclass
944 *
945 * this routine is called by C_GetAttributeValue which exports the attributes
946 * in the clear.  this routine is NOT called when wrapping a key.
947 */
948CK_BBOOL
949template_check_exportability(TEMPLATE *tmpl, CK_ATTRIBUTE_TYPE type)
950{
951	CK_ATTRIBUTE * attr = NULL;
952	CK_ULONG	class;
953	CK_ULONG	subclass;
954	CK_BBOOL	val;
955
956	if (! tmpl)
957		return (FALSE);
958	(void) template_get_class(tmpl, &class, &subclass);
959
960	if (class != CKO_PRIVATE_KEY && class != CKO_SECRET_KEY)
961		return (TRUE);
962	val = template_attribute_find(tmpl, CKA_SENSITIVE, &attr);
963	if (val) {
964		val = *(CK_BBOOL *)attr->pValue;
965		if (val == FALSE)
966			return (TRUE);
967	} else {
968		return (FALSE);
969	}
970
971	if (class == CKO_PRIVATE_KEY) {
972		switch (subclass) {
973			case CKK_RSA:
974				return (rsa_priv_check_exportability(type));
975			default:
976				return (CKR_ATTRIBUTE_VALUE_INVALID);
977		}
978	} else if (class == CKO_SECRET_KEY) {
979		return (secret_key_check_exportability(type));
980	}
981
982	return (CKR_ATTRIBUTE_VALUE_INVALID);
983}
984
985CK_RV
986template_merge(TEMPLATE *dest, TEMPLATE **src)
987{
988	DL_NODE  *node;
989	CK_RV	rc;
990
991	if (! dest || ! src) {
992		return (CKR_FUNCTION_FAILED);
993	}
994	node = (*src)->attribute_list;
995
996	while (node) {
997		CK_ATTRIBUTE *attr = (CK_ATTRIBUTE *)node->data;
998
999		rc = template_update_attribute(dest, attr);
1000		if (rc != CKR_OK) {
1001			return (rc);
1002		}
1003		node->data = NULL;
1004		node = node->next;
1005	}
1006
1007	(void) template_free(*src);
1008	*src = NULL;
1009
1010	return (CKR_OK);
1011}
1012
1013/*
1014 * template_set_default_common_attributes()
1015 *
1016 * Set the default attributes common to all objects:
1017 *
1018 *    CKA_TOKEN	:  FALSE
1019 *    CKA_PRIVATE    :  TRUE -- Cryptoki leaves this up to the token to decide
1020 *    CKA_MODIFIABLE :  TRUE
1021 *    CKA_LABEL	:  empty string
1022 */
1023CK_RV
1024template_set_default_common_attributes(TEMPLATE *tmpl)
1025{
1026	CK_ATTRIBUTE * token_attr;
1027	CK_ATTRIBUTE * priv_attr;
1028	CK_ATTRIBUTE * mod_attr;
1029	CK_ATTRIBUTE * label_attr;
1030
1031	token_attr = (CK_ATTRIBUTE *)malloc(sizeof (CK_ATTRIBUTE) +
1032	    sizeof (CK_BBOOL));
1033	priv_attr  = (CK_ATTRIBUTE *)malloc(sizeof (CK_ATTRIBUTE) +
1034	    sizeof (CK_BBOOL));
1035	mod_attr   = (CK_ATTRIBUTE *)malloc(sizeof (CK_ATTRIBUTE) +
1036	    sizeof (CK_BBOOL));
1037	label_attr = (CK_ATTRIBUTE *)malloc(sizeof (CK_ATTRIBUTE) + 0);
1038
1039	if (! token_attr || ! priv_attr || ! mod_attr || ! label_attr) {
1040		if (token_attr) free(token_attr);
1041		if (priv_attr)  free(priv_attr);
1042		if (mod_attr)   free(mod_attr);
1043		if (label_attr) free(label_attr);
1044
1045		return (CKR_HOST_MEMORY);
1046	}
1047
1048	token_attr->type	 = CKA_TOKEN;
1049	token_attr->ulValueLen   = sizeof (CK_BBOOL);
1050	token_attr->pValue	= (CK_BYTE *)token_attr + sizeof (CK_ATTRIBUTE);
1051	*(CK_BBOOL *)token_attr->pValue = FALSE;
1052
1053	priv_attr->type	  = CKA_PRIVATE;
1054	priv_attr->ulValueLen    = sizeof (CK_BBOOL);
1055	priv_attr->pValue	= (CK_BYTE *)priv_attr + sizeof (CK_ATTRIBUTE);
1056	*(CK_BBOOL *)priv_attr->pValue = FALSE;
1057
1058	mod_attr->type	   = CKA_MODIFIABLE;
1059	mod_attr->ulValueLen	= sizeof (CK_BBOOL);
1060	mod_attr->pValue	 = (CK_BYTE *)mod_attr + sizeof (CK_ATTRIBUTE);
1061	*(CK_BBOOL *)mod_attr->pValue = TRUE;
1062
1063	label_attr->type	 = CKA_LABEL;
1064	label_attr->ulValueLen   = 0;	 // empty string
1065	label_attr->pValue	= NULL;
1066
1067	(void) template_update_attribute(tmpl, token_attr);
1068	(void) template_update_attribute(tmpl, priv_attr);
1069	(void) template_update_attribute(tmpl, mod_attr);
1070	(void) template_update_attribute(tmpl, label_attr);
1071
1072	return (CKR_OK);
1073}
1074
1075CK_RV
1076template_update_attribute(TEMPLATE *tmpl, CK_ATTRIBUTE *new_attr) {
1077	DL_NODE	* node = NULL;
1078	CK_ATTRIBUTE * attr = NULL;
1079
1080	if (! tmpl || ! new_attr) {
1081		return (CKR_FUNCTION_FAILED);
1082	}
1083	node = tmpl->attribute_list;
1084
1085	while (node != NULL) {
1086		attr = (CK_ATTRIBUTE *)node->data;
1087
1088		if (new_attr->type == attr->type) {
1089			free(attr);
1090			tmpl->attribute_list = dlist_remove_node(
1091			    tmpl->attribute_list, node);
1092			break;
1093		}
1094
1095		node = node->next;
1096	}
1097
1098	tmpl->attribute_list = dlist_add_as_first(
1099	    tmpl->attribute_list, new_attr);
1100
1101	return (CKR_OK);
1102}
1103
1104CK_RV
1105template_validate_attribute(TEMPLATE	* tmpl,
1106	CK_ATTRIBUTE * attr,
1107	CK_ULONG	class,
1108	CK_ULONG	subclass,
1109	CK_ULONG	mode)
1110{
1111	if (class == CKO_DATA)
1112		return (data_object_validate_attribute(tmpl, attr, mode));
1113	else if (class == CKO_CERTIFICATE) {
1114		if (subclass == CKC_X_509)
1115			return (cert_x509_validate_attribute(tmpl, attr, mode));
1116		else
1117			return (cert_vendor_validate_attribute(tmpl,
1118			    attr, mode));
1119	} else if (class == CKO_PUBLIC_KEY) {
1120
1121		switch (subclass) {
1122			case CKK_RSA:
1123				return (rsa_publ_validate_attribute(tmpl,
1124				    attr, mode));
1125			default:
1126				return (CKR_ATTRIBUTE_VALUE_INVALID);
1127		}
1128	} else if (class == CKO_PRIVATE_KEY) {
1129
1130		switch (subclass) {
1131			case CKK_RSA:
1132				return (rsa_priv_validate_attribute(tmpl,
1133				    attr, mode));
1134			default:
1135				return (CKR_ATTRIBUTE_VALUE_INVALID);
1136		}
1137	} else if (class == CKO_SECRET_KEY) {
1138		switch (subclass) {
1139			case CKK_GENERIC_SECRET:
1140				return (generic_secret_validate_attribute(tmpl,
1141				    attr, mode));
1142			default:
1143				return (CKR_ATTRIBUTE_VALUE_INVALID);
1144			}
1145		} else if (class == CKO_HW_FEATURE) {
1146
1147		switch (subclass) {
1148			case CKH_CLOCK:
1149				return (clock_validate_attribute(tmpl,
1150				    attr, mode));
1151			case CKH_MONOTONIC_COUNTER:
1152				return (counter_validate_attribute(tmpl,
1153				    attr, mode));
1154			default:
1155				return (CKR_ATTRIBUTE_VALUE_INVALID);
1156		}
1157	} else if (class == CKO_DOMAIN_PARAMETERS) {
1158		switch (subclass) {
1159			default:
1160				return (CKR_ATTRIBUTE_VALUE_INVALID);
1161		}
1162	}
1163	return (CKR_ATTRIBUTE_VALUE_INVALID);
1164}
1165
1166CK_RV
1167template_validate_attributes(TEMPLATE * tmpl,
1168	CK_ULONG   class,
1169	CK_ULONG   subclass,
1170	CK_ULONG   mode)
1171{
1172	DL_NODE	*node;
1173	CK_RV	rc = CKR_OK;
1174
1175	node = tmpl->attribute_list;
1176
1177	while (node) {
1178		CK_ATTRIBUTE *attr = (CK_ATTRIBUTE *)node->data;
1179
1180		rc = template_validate_attribute(tmpl, attr, class,
1181		    subclass, mode);
1182		if (rc != CKR_OK) {
1183			return (rc);
1184		}
1185		node = node->next;
1186	}
1187
1188	return (CKR_OK);
1189}
1190
1191CK_RV
1192template_validate_base_attribute(TEMPLATE	* tmpl,
1193	CK_ATTRIBUTE  * attr,
1194	CK_ULONG	 mode)
1195{
1196	if (! tmpl || ! attr) {
1197		return (CKR_FUNCTION_FAILED);
1198	}
1199	switch (attr->type) {
1200		case CKA_CLASS:
1201			if ((mode & (MODE_CREATE | MODE_DERIVE |
1202			    MODE_KEYGEN | MODE_UNWRAP)) != 0)
1203				return (CKR_OK);
1204			break;
1205
1206		case CKA_TOKEN:
1207			if ((mode & (MODE_CREATE | MODE_COPY |
1208			    MODE_DERIVE | MODE_KEYGEN | MODE_UNWRAP)) != 0)
1209				return (CKR_OK);
1210			break;
1211
1212		case CKA_PRIVATE:
1213			if ((mode & (MODE_CREATE | MODE_COPY |
1214			    MODE_DERIVE | MODE_KEYGEN | MODE_UNWRAP)) != 0)
1215				return (CKR_OK);
1216			break;
1217
1218		case CKA_LABEL:
1219			return (CKR_OK);
1220		case CKA_MODIFIABLE:
1221			if ((mode & (MODE_CREATE | MODE_COPY |
1222			    MODE_DERIVE | MODE_KEYGEN | MODE_UNWRAP)) != 0)
1223				return (CKR_OK);
1224			break;
1225
1226		default:
1227			return (CKR_TEMPLATE_INCONSISTENT);
1228		}
1229
1230	return (CKR_ATTRIBUTE_READ_ONLY);
1231}
1232