xref: /onnv-gate/usr/src/lib/pkcs11/pkcs11_kms/common/kmsAttributeUtil.c (revision 12720:3db6e0082404)
1*12720SWyllys.Ingersoll@Sun.COM /*
2*12720SWyllys.Ingersoll@Sun.COM  * CDDL HEADER START
3*12720SWyllys.Ingersoll@Sun.COM  *
4*12720SWyllys.Ingersoll@Sun.COM  * The contents of this file are subject to the terms of the
5*12720SWyllys.Ingersoll@Sun.COM  * Common Development and Distribution License (the "License").
6*12720SWyllys.Ingersoll@Sun.COM  * You may not use this file except in compliance with the License.
7*12720SWyllys.Ingersoll@Sun.COM  *
8*12720SWyllys.Ingersoll@Sun.COM  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*12720SWyllys.Ingersoll@Sun.COM  * or http://www.opensolaris.org/os/licensing.
10*12720SWyllys.Ingersoll@Sun.COM  * See the License for the specific language governing permissions
11*12720SWyllys.Ingersoll@Sun.COM  * and limitations under the License.
12*12720SWyllys.Ingersoll@Sun.COM  *
13*12720SWyllys.Ingersoll@Sun.COM  * When distributing Covered Code, include this CDDL HEADER in each
14*12720SWyllys.Ingersoll@Sun.COM  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*12720SWyllys.Ingersoll@Sun.COM  * If applicable, add the following below this CDDL HEADER, with the
16*12720SWyllys.Ingersoll@Sun.COM  * fields enclosed by brackets "[]" replaced with your own identifying
17*12720SWyllys.Ingersoll@Sun.COM  * information: Portions Copyright [yyyy] [name of copyright owner]
18*12720SWyllys.Ingersoll@Sun.COM  *
19*12720SWyllys.Ingersoll@Sun.COM  * CDDL HEADER END
20*12720SWyllys.Ingersoll@Sun.COM  *
21*12720SWyllys.Ingersoll@Sun.COM  * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
22*12720SWyllys.Ingersoll@Sun.COM  */
23*12720SWyllys.Ingersoll@Sun.COM #include <stdlib.h>
24*12720SWyllys.Ingersoll@Sun.COM #include <string.h>
25*12720SWyllys.Ingersoll@Sun.COM #include <security/cryptoki.h>
26*12720SWyllys.Ingersoll@Sun.COM #include <sys/crypto/common.h>
27*12720SWyllys.Ingersoll@Sun.COM #include <aes_impl.h>
28*12720SWyllys.Ingersoll@Sun.COM #include "kmsGlobal.h"
29*12720SWyllys.Ingersoll@Sun.COM #include "kmsObject.h"
30*12720SWyllys.Ingersoll@Sun.COM #include "kmsSession.h"
31*12720SWyllys.Ingersoll@Sun.COM #include "kmsSlot.h"
32*12720SWyllys.Ingersoll@Sun.COM 
33*12720SWyllys.Ingersoll@Sun.COM /*
34*12720SWyllys.Ingersoll@Sun.COM  * This attribute table is used by the kms_lookup_attr()
35*12720SWyllys.Ingersoll@Sun.COM  * to validate the attributes.
36*12720SWyllys.Ingersoll@Sun.COM  */
37*12720SWyllys.Ingersoll@Sun.COM CK_ATTRIBUTE_TYPE attr_map[] = {
38*12720SWyllys.Ingersoll@Sun.COM 	CKA_PRIVATE,
39*12720SWyllys.Ingersoll@Sun.COM 	CKA_LABEL,
40*12720SWyllys.Ingersoll@Sun.COM 	CKA_APPLICATION,
41*12720SWyllys.Ingersoll@Sun.COM 	CKA_OBJECT_ID,
42*12720SWyllys.Ingersoll@Sun.COM 	CKA_CERTIFICATE_TYPE,
43*12720SWyllys.Ingersoll@Sun.COM 	CKA_ISSUER,
44*12720SWyllys.Ingersoll@Sun.COM 	CKA_SERIAL_NUMBER,
45*12720SWyllys.Ingersoll@Sun.COM 	CKA_AC_ISSUER,
46*12720SWyllys.Ingersoll@Sun.COM 	CKA_OWNER,
47*12720SWyllys.Ingersoll@Sun.COM 	CKA_ATTR_TYPES,
48*12720SWyllys.Ingersoll@Sun.COM 	CKA_SUBJECT,
49*12720SWyllys.Ingersoll@Sun.COM 	CKA_ID,
50*12720SWyllys.Ingersoll@Sun.COM 	CKA_SENSITIVE,
51*12720SWyllys.Ingersoll@Sun.COM 	CKA_START_DATE,
52*12720SWyllys.Ingersoll@Sun.COM 	CKA_END_DATE,
53*12720SWyllys.Ingersoll@Sun.COM 	CKA_MODULUS,
54*12720SWyllys.Ingersoll@Sun.COM 	CKA_MODULUS_BITS,
55*12720SWyllys.Ingersoll@Sun.COM 	CKA_PUBLIC_EXPONENT,
56*12720SWyllys.Ingersoll@Sun.COM 	CKA_PRIVATE_EXPONENT,
57*12720SWyllys.Ingersoll@Sun.COM 	CKA_PRIME_1,
58*12720SWyllys.Ingersoll@Sun.COM 	CKA_PRIME_2,
59*12720SWyllys.Ingersoll@Sun.COM 	CKA_EXPONENT_1,
60*12720SWyllys.Ingersoll@Sun.COM 	CKA_EXPONENT_2,
61*12720SWyllys.Ingersoll@Sun.COM 	CKA_COEFFICIENT,
62*12720SWyllys.Ingersoll@Sun.COM 	CKA_PRIME,
63*12720SWyllys.Ingersoll@Sun.COM 	CKA_SUBPRIME,
64*12720SWyllys.Ingersoll@Sun.COM 	CKA_BASE,
65*12720SWyllys.Ingersoll@Sun.COM 	CKA_EXTRACTABLE,
66*12720SWyllys.Ingersoll@Sun.COM 	CKA_LOCAL,
67*12720SWyllys.Ingersoll@Sun.COM 	CKA_NEVER_EXTRACTABLE,
68*12720SWyllys.Ingersoll@Sun.COM 	CKA_ALWAYS_SENSITIVE,
69*12720SWyllys.Ingersoll@Sun.COM 	CKA_MODIFIABLE,
70*12720SWyllys.Ingersoll@Sun.COM 	CKA_ECDSA_PARAMS,
71*12720SWyllys.Ingersoll@Sun.COM 	CKA_EC_POINT,
72*12720SWyllys.Ingersoll@Sun.COM 	CKA_SECONDARY_AUTH,
73*12720SWyllys.Ingersoll@Sun.COM 	CKA_AUTH_PIN_FLAGS,
74*12720SWyllys.Ingersoll@Sun.COM 	CKA_HW_FEATURE_TYPE,
75*12720SWyllys.Ingersoll@Sun.COM 	CKA_RESET_ON_INIT,
76*12720SWyllys.Ingersoll@Sun.COM 	CKA_HAS_RESET
77*12720SWyllys.Ingersoll@Sun.COM };
78*12720SWyllys.Ingersoll@Sun.COM 
79*12720SWyllys.Ingersoll@Sun.COM /*
80*12720SWyllys.Ingersoll@Sun.COM  * attributes that exists only in secret key objects
81*12720SWyllys.Ingersoll@Sun.COM  * Note: some attributes may also exist in one or two
82*12720SWyllys.Ingersoll@Sun.COM  *       other object classes, but they are also listed
83*12720SWyllys.Ingersoll@Sun.COM  *       because not all object have them.
84*12720SWyllys.Ingersoll@Sun.COM  */
85*12720SWyllys.Ingersoll@Sun.COM CK_ATTRIBUTE_TYPE SECRET_KEY_ATTRS[] =
86*12720SWyllys.Ingersoll@Sun.COM {
87*12720SWyllys.Ingersoll@Sun.COM 	CKA_VALUE_LEN,
88*12720SWyllys.Ingersoll@Sun.COM 	CKA_ENCRYPT,
89*12720SWyllys.Ingersoll@Sun.COM 	CKA_DECRYPT,
90*12720SWyllys.Ingersoll@Sun.COM 	CKA_WRAP,
91*12720SWyllys.Ingersoll@Sun.COM 	CKA_UNWRAP,
92*12720SWyllys.Ingersoll@Sun.COM 	CKA_SIGN,
93*12720SWyllys.Ingersoll@Sun.COM 	CKA_VERIFY,
94*12720SWyllys.Ingersoll@Sun.COM 	CKA_SENSITIVE,
95*12720SWyllys.Ingersoll@Sun.COM 	CKA_EXTRACTABLE,
96*12720SWyllys.Ingersoll@Sun.COM 	CKA_NEVER_EXTRACTABLE,
97*12720SWyllys.Ingersoll@Sun.COM 	CKA_ALWAYS_SENSITIVE
98*12720SWyllys.Ingersoll@Sun.COM };
99*12720SWyllys.Ingersoll@Sun.COM 
100*12720SWyllys.Ingersoll@Sun.COM /*
101*12720SWyllys.Ingersoll@Sun.COM  * Validate the attribute by using binary search algorithm.
102*12720SWyllys.Ingersoll@Sun.COM  */
103*12720SWyllys.Ingersoll@Sun.COM CK_RV
kms_lookup_attr(CK_ATTRIBUTE_TYPE type)104*12720SWyllys.Ingersoll@Sun.COM kms_lookup_attr(CK_ATTRIBUTE_TYPE type)
105*12720SWyllys.Ingersoll@Sun.COM {
106*12720SWyllys.Ingersoll@Sun.COM 	size_t lower, middle, upper;
107*12720SWyllys.Ingersoll@Sun.COM 
108*12720SWyllys.Ingersoll@Sun.COM 	lower = 0;
109*12720SWyllys.Ingersoll@Sun.COM 	upper = (sizeof (attr_map) / sizeof (CK_ATTRIBUTE_TYPE)) - 1;
110*12720SWyllys.Ingersoll@Sun.COM 
111*12720SWyllys.Ingersoll@Sun.COM 	while (lower <= upper) {
112*12720SWyllys.Ingersoll@Sun.COM 		/* Always starts from middle. */
113*12720SWyllys.Ingersoll@Sun.COM 		middle = (lower + upper) / 2;
114*12720SWyllys.Ingersoll@Sun.COM 
115*12720SWyllys.Ingersoll@Sun.COM 		if (type > attr_map[middle]) {
116*12720SWyllys.Ingersoll@Sun.COM 			/* Adjust the lower bound to upper half. */
117*12720SWyllys.Ingersoll@Sun.COM 			lower = middle + 1;
118*12720SWyllys.Ingersoll@Sun.COM 			continue;
119*12720SWyllys.Ingersoll@Sun.COM 		}
120*12720SWyllys.Ingersoll@Sun.COM 
121*12720SWyllys.Ingersoll@Sun.COM 		if (type == attr_map[middle]) {
122*12720SWyllys.Ingersoll@Sun.COM 			/* Found it. */
123*12720SWyllys.Ingersoll@Sun.COM 			return (CKR_OK);
124*12720SWyllys.Ingersoll@Sun.COM 		}
125*12720SWyllys.Ingersoll@Sun.COM 
126*12720SWyllys.Ingersoll@Sun.COM 		if (type < attr_map[middle]) {
127*12720SWyllys.Ingersoll@Sun.COM 			/* Adjust the upper bound to lower half. */
128*12720SWyllys.Ingersoll@Sun.COM 			upper = middle - 1;
129*12720SWyllys.Ingersoll@Sun.COM 			continue;
130*12720SWyllys.Ingersoll@Sun.COM 		}
131*12720SWyllys.Ingersoll@Sun.COM 	}
132*12720SWyllys.Ingersoll@Sun.COM 
133*12720SWyllys.Ingersoll@Sun.COM 	/* Failed to find the matching attribute from the attribute table. */
134*12720SWyllys.Ingersoll@Sun.COM 	return (CKR_ATTRIBUTE_TYPE_INVALID);
135*12720SWyllys.Ingersoll@Sun.COM }
136*12720SWyllys.Ingersoll@Sun.COM 
137*12720SWyllys.Ingersoll@Sun.COM 
138*12720SWyllys.Ingersoll@Sun.COM /*
139*12720SWyllys.Ingersoll@Sun.COM  * Validate the attribute by using the following search algorithm:
140*12720SWyllys.Ingersoll@Sun.COM  *
141*12720SWyllys.Ingersoll@Sun.COM  * 1) Search for the most frequently used attributes first.
142*12720SWyllys.Ingersoll@Sun.COM  * 2) If not found, search for the usage-purpose attributes - these
143*12720SWyllys.Ingersoll@Sun.COM  *    attributes have dense set of values, therefore compiler will
144*12720SWyllys.Ingersoll@Sun.COM  *    optimize it with a branch table and branch to the appropriate
145*12720SWyllys.Ingersoll@Sun.COM  *    case.
146*12720SWyllys.Ingersoll@Sun.COM  * 3) If still not found, use binary search for the rest of the
147*12720SWyllys.Ingersoll@Sun.COM  *    attributes in the attr_map[] table.
148*12720SWyllys.Ingersoll@Sun.COM  */
149*12720SWyllys.Ingersoll@Sun.COM CK_RV
kms_validate_attr(CK_ATTRIBUTE_PTR template,CK_ULONG ulAttrNum,CK_OBJECT_CLASS * class)150*12720SWyllys.Ingersoll@Sun.COM kms_validate_attr(CK_ATTRIBUTE_PTR template, CK_ULONG ulAttrNum,
151*12720SWyllys.Ingersoll@Sun.COM 	CK_OBJECT_CLASS *class)
152*12720SWyllys.Ingersoll@Sun.COM {
153*12720SWyllys.Ingersoll@Sun.COM 
154*12720SWyllys.Ingersoll@Sun.COM 	CK_ULONG i;
155*12720SWyllys.Ingersoll@Sun.COM 	CK_RV rv = CKR_OK;
156*12720SWyllys.Ingersoll@Sun.COM 
157*12720SWyllys.Ingersoll@Sun.COM 	for (i = 0; i < ulAttrNum; i++) {
158*12720SWyllys.Ingersoll@Sun.COM 		/* First tier search */
159*12720SWyllys.Ingersoll@Sun.COM 		switch (template[i].type) {
160*12720SWyllys.Ingersoll@Sun.COM 		case CKA_CLASS:
161*12720SWyllys.Ingersoll@Sun.COM 			*class = *((CK_OBJECT_CLASS*)template[i].pValue);
162*12720SWyllys.Ingersoll@Sun.COM 			break;
163*12720SWyllys.Ingersoll@Sun.COM 		case CKA_TOKEN:
164*12720SWyllys.Ingersoll@Sun.COM 			break;
165*12720SWyllys.Ingersoll@Sun.COM 		case CKA_KEY_TYPE:
166*12720SWyllys.Ingersoll@Sun.COM 			break;
167*12720SWyllys.Ingersoll@Sun.COM 		case CKA_VALUE:
168*12720SWyllys.Ingersoll@Sun.COM 			break;
169*12720SWyllys.Ingersoll@Sun.COM 		case CKA_VALUE_LEN:
170*12720SWyllys.Ingersoll@Sun.COM 			break;
171*12720SWyllys.Ingersoll@Sun.COM 		case CKA_VALUE_BITS:
172*12720SWyllys.Ingersoll@Sun.COM 			break;
173*12720SWyllys.Ingersoll@Sun.COM 		default:
174*12720SWyllys.Ingersoll@Sun.COM 			/* Second tier search */
175*12720SWyllys.Ingersoll@Sun.COM 			switch (template[i].type) {
176*12720SWyllys.Ingersoll@Sun.COM 			case CKA_ENCRYPT:
177*12720SWyllys.Ingersoll@Sun.COM 				break;
178*12720SWyllys.Ingersoll@Sun.COM 			case CKA_DECRYPT:
179*12720SWyllys.Ingersoll@Sun.COM 				break;
180*12720SWyllys.Ingersoll@Sun.COM 			case CKA_WRAP:
181*12720SWyllys.Ingersoll@Sun.COM 				break;
182*12720SWyllys.Ingersoll@Sun.COM 			case CKA_UNWRAP:
183*12720SWyllys.Ingersoll@Sun.COM 				break;
184*12720SWyllys.Ingersoll@Sun.COM 			case CKA_SIGN:
185*12720SWyllys.Ingersoll@Sun.COM 				break;
186*12720SWyllys.Ingersoll@Sun.COM 			case CKA_SIGN_RECOVER:
187*12720SWyllys.Ingersoll@Sun.COM 				break;
188*12720SWyllys.Ingersoll@Sun.COM 			case CKA_VERIFY:
189*12720SWyllys.Ingersoll@Sun.COM 				break;
190*12720SWyllys.Ingersoll@Sun.COM 			case CKA_VERIFY_RECOVER:
191*12720SWyllys.Ingersoll@Sun.COM 				break;
192*12720SWyllys.Ingersoll@Sun.COM 			case CKA_DERIVE:
193*12720SWyllys.Ingersoll@Sun.COM 				break;
194*12720SWyllys.Ingersoll@Sun.COM 			default:
195*12720SWyllys.Ingersoll@Sun.COM 				/* Third tier search */
196*12720SWyllys.Ingersoll@Sun.COM 				rv = kms_lookup_attr(template[i].type);
197*12720SWyllys.Ingersoll@Sun.COM 				if (rv != CKR_OK)
198*12720SWyllys.Ingersoll@Sun.COM 					return (rv);
199*12720SWyllys.Ingersoll@Sun.COM 				break;
200*12720SWyllys.Ingersoll@Sun.COM 			}
201*12720SWyllys.Ingersoll@Sun.COM 			break;
202*12720SWyllys.Ingersoll@Sun.COM 		}
203*12720SWyllys.Ingersoll@Sun.COM 	}
204*12720SWyllys.Ingersoll@Sun.COM 	return (rv);
205*12720SWyllys.Ingersoll@Sun.COM }
206*12720SWyllys.Ingersoll@Sun.COM 
207*12720SWyllys.Ingersoll@Sun.COM 
208*12720SWyllys.Ingersoll@Sun.COM /*
209*12720SWyllys.Ingersoll@Sun.COM  * Clean up and release all the storage in the extra attribute list
210*12720SWyllys.Ingersoll@Sun.COM  * of an object.
211*12720SWyllys.Ingersoll@Sun.COM  */
212*12720SWyllys.Ingersoll@Sun.COM void
kms_cleanup_extra_attr(kms_object_t * object_p)213*12720SWyllys.Ingersoll@Sun.COM kms_cleanup_extra_attr(kms_object_t *object_p)
214*12720SWyllys.Ingersoll@Sun.COM {
215*12720SWyllys.Ingersoll@Sun.COM 
216*12720SWyllys.Ingersoll@Sun.COM 	CK_ATTRIBUTE_INFO_PTR extra_attr;
217*12720SWyllys.Ingersoll@Sun.COM 	CK_ATTRIBUTE_INFO_PTR tmp;
218*12720SWyllys.Ingersoll@Sun.COM 
219*12720SWyllys.Ingersoll@Sun.COM 	if (object_p == NULL)
220*12720SWyllys.Ingersoll@Sun.COM 		return;
221*12720SWyllys.Ingersoll@Sun.COM 
222*12720SWyllys.Ingersoll@Sun.COM 	extra_attr = object_p->extra_attrlistp;
223*12720SWyllys.Ingersoll@Sun.COM 	while (extra_attr) {
224*12720SWyllys.Ingersoll@Sun.COM 		tmp = extra_attr->next;
225*12720SWyllys.Ingersoll@Sun.COM 		if (extra_attr->attr.pValue)
226*12720SWyllys.Ingersoll@Sun.COM 			/*
227*12720SWyllys.Ingersoll@Sun.COM 			 * All extra attributes in the extra attribute
228*12720SWyllys.Ingersoll@Sun.COM 			 * list have pValue points to the value of the
229*12720SWyllys.Ingersoll@Sun.COM 			 * attribute (with simple byte array type).
230*12720SWyllys.Ingersoll@Sun.COM 			 * Free the storage for the value of the attribute.
231*12720SWyllys.Ingersoll@Sun.COM 			 */
232*12720SWyllys.Ingersoll@Sun.COM 			free(extra_attr->attr.pValue);
233*12720SWyllys.Ingersoll@Sun.COM 
234*12720SWyllys.Ingersoll@Sun.COM 		/* Free the storage for the attribute_info struct. */
235*12720SWyllys.Ingersoll@Sun.COM 		free(extra_attr);
236*12720SWyllys.Ingersoll@Sun.COM 		extra_attr = tmp;
237*12720SWyllys.Ingersoll@Sun.COM 	}
238*12720SWyllys.Ingersoll@Sun.COM 
239*12720SWyllys.Ingersoll@Sun.COM 	object_p->extra_attrlistp = NULL;
240*12720SWyllys.Ingersoll@Sun.COM }
241*12720SWyllys.Ingersoll@Sun.COM 
242*12720SWyllys.Ingersoll@Sun.COM /*
243*12720SWyllys.Ingersoll@Sun.COM  * Create the attribute_info struct to hold the object's attribute,
244*12720SWyllys.Ingersoll@Sun.COM  * and add it to the extra attribute list of an object.
245*12720SWyllys.Ingersoll@Sun.COM  */
246*12720SWyllys.Ingersoll@Sun.COM CK_RV
kms_add_extra_attr(CK_ATTRIBUTE_PTR template,kms_object_t * object_p)247*12720SWyllys.Ingersoll@Sun.COM kms_add_extra_attr(CK_ATTRIBUTE_PTR template, kms_object_t *object_p)
248*12720SWyllys.Ingersoll@Sun.COM {
249*12720SWyllys.Ingersoll@Sun.COM 
250*12720SWyllys.Ingersoll@Sun.COM 	CK_ATTRIBUTE_INFO_PTR attrp;
251*12720SWyllys.Ingersoll@Sun.COM 
252*12720SWyllys.Ingersoll@Sun.COM 	/* Allocate the storage for the attribute_info struct. */
253*12720SWyllys.Ingersoll@Sun.COM 	attrp = calloc(1, sizeof (attribute_info_t));
254*12720SWyllys.Ingersoll@Sun.COM 	if (attrp == NULL) {
255*12720SWyllys.Ingersoll@Sun.COM 		return (CKR_HOST_MEMORY);
256*12720SWyllys.Ingersoll@Sun.COM 	}
257*12720SWyllys.Ingersoll@Sun.COM 
258*12720SWyllys.Ingersoll@Sun.COM 	/* Set up attribute_info struct. */
259*12720SWyllys.Ingersoll@Sun.COM 	attrp->attr.type = template->type;
260*12720SWyllys.Ingersoll@Sun.COM 	attrp->attr.ulValueLen = template->ulValueLen;
261*12720SWyllys.Ingersoll@Sun.COM 
262*12720SWyllys.Ingersoll@Sun.COM 	if ((template->pValue != NULL) &&
263*12720SWyllys.Ingersoll@Sun.COM 	    (template->ulValueLen > 0)) {
264*12720SWyllys.Ingersoll@Sun.COM 		/* Allocate storage for the value of the attribute. */
265*12720SWyllys.Ingersoll@Sun.COM 		attrp->attr.pValue = malloc(template->ulValueLen);
266*12720SWyllys.Ingersoll@Sun.COM 		if (attrp->attr.pValue == NULL) {
267*12720SWyllys.Ingersoll@Sun.COM 			free(attrp);
268*12720SWyllys.Ingersoll@Sun.COM 			return (CKR_HOST_MEMORY);
269*12720SWyllys.Ingersoll@Sun.COM 		}
270*12720SWyllys.Ingersoll@Sun.COM 
271*12720SWyllys.Ingersoll@Sun.COM 		(void) memcpy(attrp->attr.pValue, template->pValue,
272*12720SWyllys.Ingersoll@Sun.COM 		    template->ulValueLen);
273*12720SWyllys.Ingersoll@Sun.COM 	} else {
274*12720SWyllys.Ingersoll@Sun.COM 		attrp->attr.pValue = NULL;
275*12720SWyllys.Ingersoll@Sun.COM 	}
276*12720SWyllys.Ingersoll@Sun.COM 
277*12720SWyllys.Ingersoll@Sun.COM 	/* Insert the new attribute in front of extra attribute list. */
278*12720SWyllys.Ingersoll@Sun.COM 	if (object_p->extra_attrlistp == NULL) {
279*12720SWyllys.Ingersoll@Sun.COM 		object_p->extra_attrlistp = attrp;
280*12720SWyllys.Ingersoll@Sun.COM 		attrp->next = NULL;
281*12720SWyllys.Ingersoll@Sun.COM 	} else {
282*12720SWyllys.Ingersoll@Sun.COM 		attrp->next = object_p->extra_attrlistp;
283*12720SWyllys.Ingersoll@Sun.COM 		object_p->extra_attrlistp = attrp;
284*12720SWyllys.Ingersoll@Sun.COM 	}
285*12720SWyllys.Ingersoll@Sun.COM 
286*12720SWyllys.Ingersoll@Sun.COM 	return (CKR_OK);
287*12720SWyllys.Ingersoll@Sun.COM }
288*12720SWyllys.Ingersoll@Sun.COM 
289*12720SWyllys.Ingersoll@Sun.COM /*
290*12720SWyllys.Ingersoll@Sun.COM  * Copy the attribute_info struct from the old object to a new attribute_info
291*12720SWyllys.Ingersoll@Sun.COM  * struct, and add that new struct to the extra attribute list of the new
292*12720SWyllys.Ingersoll@Sun.COM  * object.
293*12720SWyllys.Ingersoll@Sun.COM  */
294*12720SWyllys.Ingersoll@Sun.COM CK_RV
kms_copy_extra_attr(CK_ATTRIBUTE_INFO_PTR old_attrp,kms_object_t * object_p)295*12720SWyllys.Ingersoll@Sun.COM kms_copy_extra_attr(CK_ATTRIBUTE_INFO_PTR old_attrp,
296*12720SWyllys.Ingersoll@Sun.COM     kms_object_t *object_p)
297*12720SWyllys.Ingersoll@Sun.COM {
298*12720SWyllys.Ingersoll@Sun.COM 	CK_ATTRIBUTE_INFO_PTR attrp;
299*12720SWyllys.Ingersoll@Sun.COM 
300*12720SWyllys.Ingersoll@Sun.COM 	/* Allocate attribute_info struct. */
301*12720SWyllys.Ingersoll@Sun.COM 	attrp = calloc(1, sizeof (attribute_info_t));
302*12720SWyllys.Ingersoll@Sun.COM 	if (attrp == NULL) {
303*12720SWyllys.Ingersoll@Sun.COM 		return (CKR_HOST_MEMORY);
304*12720SWyllys.Ingersoll@Sun.COM 	}
305*12720SWyllys.Ingersoll@Sun.COM 
306*12720SWyllys.Ingersoll@Sun.COM 	attrp->attr.type = old_attrp->attr.type;
307*12720SWyllys.Ingersoll@Sun.COM 	attrp->attr.ulValueLen = old_attrp->attr.ulValueLen;
308*12720SWyllys.Ingersoll@Sun.COM 
309*12720SWyllys.Ingersoll@Sun.COM 	if ((old_attrp->attr.pValue != NULL) &&
310*12720SWyllys.Ingersoll@Sun.COM 	    (old_attrp->attr.ulValueLen > 0)) {
311*12720SWyllys.Ingersoll@Sun.COM 		attrp->attr.pValue = malloc(old_attrp->attr.ulValueLen);
312*12720SWyllys.Ingersoll@Sun.COM 		if (attrp->attr.pValue == NULL) {
313*12720SWyllys.Ingersoll@Sun.COM 			free(attrp);
314*12720SWyllys.Ingersoll@Sun.COM 			return (CKR_HOST_MEMORY);
315*12720SWyllys.Ingersoll@Sun.COM 		}
316*12720SWyllys.Ingersoll@Sun.COM 
317*12720SWyllys.Ingersoll@Sun.COM 		(void) memcpy(attrp->attr.pValue, old_attrp->attr.pValue,
318*12720SWyllys.Ingersoll@Sun.COM 		    old_attrp->attr.ulValueLen);
319*12720SWyllys.Ingersoll@Sun.COM 	} else {
320*12720SWyllys.Ingersoll@Sun.COM 		attrp->attr.pValue = NULL;
321*12720SWyllys.Ingersoll@Sun.COM 	}
322*12720SWyllys.Ingersoll@Sun.COM 
323*12720SWyllys.Ingersoll@Sun.COM 	/* Insert the new attribute in front of extra attribute list */
324*12720SWyllys.Ingersoll@Sun.COM 	if (object_p->extra_attrlistp == NULL) {
325*12720SWyllys.Ingersoll@Sun.COM 		object_p->extra_attrlistp = attrp;
326*12720SWyllys.Ingersoll@Sun.COM 		attrp->next = NULL;
327*12720SWyllys.Ingersoll@Sun.COM 	} else {
328*12720SWyllys.Ingersoll@Sun.COM 		attrp->next = object_p->extra_attrlistp;
329*12720SWyllys.Ingersoll@Sun.COM 		object_p->extra_attrlistp = attrp;
330*12720SWyllys.Ingersoll@Sun.COM 	}
331*12720SWyllys.Ingersoll@Sun.COM 
332*12720SWyllys.Ingersoll@Sun.COM 	return (CKR_OK);
333*12720SWyllys.Ingersoll@Sun.COM }
334*12720SWyllys.Ingersoll@Sun.COM 
335*12720SWyllys.Ingersoll@Sun.COM /*
336*12720SWyllys.Ingersoll@Sun.COM  * Get the attribute triple from the extra attribute list in the object
337*12720SWyllys.Ingersoll@Sun.COM  * (if the specified attribute type is found), and copy it to a template.
338*12720SWyllys.Ingersoll@Sun.COM  * Note the type of the attribute to be copied is specified by the template,
339*12720SWyllys.Ingersoll@Sun.COM  * and the storage is pre-allocated for the atrribute value in the template
340*12720SWyllys.Ingersoll@Sun.COM  * for doing the copy.
341*12720SWyllys.Ingersoll@Sun.COM  */
342*12720SWyllys.Ingersoll@Sun.COM CK_RV
get_extra_attr_from_object(kms_object_t * object_p,CK_ATTRIBUTE_PTR template)343*12720SWyllys.Ingersoll@Sun.COM get_extra_attr_from_object(kms_object_t *object_p, CK_ATTRIBUTE_PTR template)
344*12720SWyllys.Ingersoll@Sun.COM {
345*12720SWyllys.Ingersoll@Sun.COM 	CK_ATTRIBUTE_INFO_PTR extra_attr;
346*12720SWyllys.Ingersoll@Sun.COM 	CK_ATTRIBUTE_TYPE type = template->type;
347*12720SWyllys.Ingersoll@Sun.COM 
348*12720SWyllys.Ingersoll@Sun.COM 	extra_attr = object_p->extra_attrlistp;
349*12720SWyllys.Ingersoll@Sun.COM 
350*12720SWyllys.Ingersoll@Sun.COM 	while (extra_attr) {
351*12720SWyllys.Ingersoll@Sun.COM 		if (type == extra_attr->attr.type) {
352*12720SWyllys.Ingersoll@Sun.COM 			/* Found it. */
353*12720SWyllys.Ingersoll@Sun.COM 			break;
354*12720SWyllys.Ingersoll@Sun.COM 		} else {
355*12720SWyllys.Ingersoll@Sun.COM 			/* Does not match, try next one. */
356*12720SWyllys.Ingersoll@Sun.COM 			extra_attr = extra_attr->next;
357*12720SWyllys.Ingersoll@Sun.COM 		}
358*12720SWyllys.Ingersoll@Sun.COM 	}
359*12720SWyllys.Ingersoll@Sun.COM 
360*12720SWyllys.Ingersoll@Sun.COM 	if (extra_attr == NULL) {
361*12720SWyllys.Ingersoll@Sun.COM 		/* A valid but un-initialized attribute. */
362*12720SWyllys.Ingersoll@Sun.COM 		template->ulValueLen = 0;
363*12720SWyllys.Ingersoll@Sun.COM 		return (CKR_OK);
364*12720SWyllys.Ingersoll@Sun.COM 	}
365*12720SWyllys.Ingersoll@Sun.COM 
366*12720SWyllys.Ingersoll@Sun.COM 	/*
367*12720SWyllys.Ingersoll@Sun.COM 	 * We found the attribute in the extra attribute list.
368*12720SWyllys.Ingersoll@Sun.COM 	 */
369*12720SWyllys.Ingersoll@Sun.COM 	if (template->pValue == NULL) {
370*12720SWyllys.Ingersoll@Sun.COM 		template->ulValueLen = extra_attr->attr.ulValueLen;
371*12720SWyllys.Ingersoll@Sun.COM 		return (CKR_OK);
372*12720SWyllys.Ingersoll@Sun.COM 	}
373*12720SWyllys.Ingersoll@Sun.COM 
374*12720SWyllys.Ingersoll@Sun.COM 	if (template->ulValueLen >= extra_attr->attr.ulValueLen) {
375*12720SWyllys.Ingersoll@Sun.COM 		/*
376*12720SWyllys.Ingersoll@Sun.COM 		 * The buffer provided by the application is large
377*12720SWyllys.Ingersoll@Sun.COM 		 * enough to hold the value of the attribute.
378*12720SWyllys.Ingersoll@Sun.COM 		 */
379*12720SWyllys.Ingersoll@Sun.COM 		(void) memcpy(template->pValue, extra_attr->attr.pValue,
380*12720SWyllys.Ingersoll@Sun.COM 		    extra_attr->attr.ulValueLen);
381*12720SWyllys.Ingersoll@Sun.COM 		template->ulValueLen = extra_attr->attr.ulValueLen;
382*12720SWyllys.Ingersoll@Sun.COM 		return (CKR_OK);
383*12720SWyllys.Ingersoll@Sun.COM 	} else {
384*12720SWyllys.Ingersoll@Sun.COM 		/*
385*12720SWyllys.Ingersoll@Sun.COM 		 * The buffer provided by the application does
386*12720SWyllys.Ingersoll@Sun.COM 		 * not have enough space to hold the value.
387*12720SWyllys.Ingersoll@Sun.COM 		 */
388*12720SWyllys.Ingersoll@Sun.COM 		template->ulValueLen = (CK_ULONG)-1;
389*12720SWyllys.Ingersoll@Sun.COM 		return (CKR_BUFFER_TOO_SMALL);
390*12720SWyllys.Ingersoll@Sun.COM 	}
391*12720SWyllys.Ingersoll@Sun.COM }
392*12720SWyllys.Ingersoll@Sun.COM 
393*12720SWyllys.Ingersoll@Sun.COM /*
394*12720SWyllys.Ingersoll@Sun.COM  * Modify the attribute triple in the extra attribute list of the object
395*12720SWyllys.Ingersoll@Sun.COM  * if the specified attribute type is found. Otherwise, just add it to
396*12720SWyllys.Ingersoll@Sun.COM  * list.
397*12720SWyllys.Ingersoll@Sun.COM  */
398*12720SWyllys.Ingersoll@Sun.COM CK_RV
set_extra_attr_to_object(kms_object_t * object_p,CK_ATTRIBUTE_TYPE type,CK_ATTRIBUTE_PTR template)399*12720SWyllys.Ingersoll@Sun.COM set_extra_attr_to_object(kms_object_t *object_p, CK_ATTRIBUTE_TYPE type,
400*12720SWyllys.Ingersoll@Sun.COM 	CK_ATTRIBUTE_PTR template)
401*12720SWyllys.Ingersoll@Sun.COM {
402*12720SWyllys.Ingersoll@Sun.COM 	CK_ATTRIBUTE_INFO_PTR extra_attr;
403*12720SWyllys.Ingersoll@Sun.COM 
404*12720SWyllys.Ingersoll@Sun.COM 	extra_attr = object_p->extra_attrlistp;
405*12720SWyllys.Ingersoll@Sun.COM 
406*12720SWyllys.Ingersoll@Sun.COM 	while (extra_attr) {
407*12720SWyllys.Ingersoll@Sun.COM 		if (type == extra_attr->attr.type) {
408*12720SWyllys.Ingersoll@Sun.COM 			/* Found it. */
409*12720SWyllys.Ingersoll@Sun.COM 			break;
410*12720SWyllys.Ingersoll@Sun.COM 		} else {
411*12720SWyllys.Ingersoll@Sun.COM 			/* Does not match, try next one. */
412*12720SWyllys.Ingersoll@Sun.COM 			extra_attr = extra_attr->next;
413*12720SWyllys.Ingersoll@Sun.COM 		}
414*12720SWyllys.Ingersoll@Sun.COM 	}
415*12720SWyllys.Ingersoll@Sun.COM 
416*12720SWyllys.Ingersoll@Sun.COM 	if (extra_attr == NULL) {
417*12720SWyllys.Ingersoll@Sun.COM 		/*
418*12720SWyllys.Ingersoll@Sun.COM 		 * This attribute is a new one, go ahead adding it to
419*12720SWyllys.Ingersoll@Sun.COM 		 * the extra attribute list.
420*12720SWyllys.Ingersoll@Sun.COM 		 */
421*12720SWyllys.Ingersoll@Sun.COM 		return (kms_add_extra_attr(template, object_p));
422*12720SWyllys.Ingersoll@Sun.COM 	}
423*12720SWyllys.Ingersoll@Sun.COM 
424*12720SWyllys.Ingersoll@Sun.COM 	/* We found the attribute in the extra attribute list. */
425*12720SWyllys.Ingersoll@Sun.COM 	if ((template->pValue != NULL) &&
426*12720SWyllys.Ingersoll@Sun.COM 	    (template->ulValueLen > 0)) {
427*12720SWyllys.Ingersoll@Sun.COM 		if (template->ulValueLen > extra_attr->attr.ulValueLen) {
428*12720SWyllys.Ingersoll@Sun.COM 			/* The old buffer is too small to hold the new value. */
429*12720SWyllys.Ingersoll@Sun.COM 			if (extra_attr->attr.pValue != NULL)
430*12720SWyllys.Ingersoll@Sun.COM 				/* Free storage for the old attribute value. */
431*12720SWyllys.Ingersoll@Sun.COM 				free(extra_attr->attr.pValue);
432*12720SWyllys.Ingersoll@Sun.COM 
433*12720SWyllys.Ingersoll@Sun.COM 			/* Allocate storage for the new attribute value. */
434*12720SWyllys.Ingersoll@Sun.COM 			extra_attr->attr.pValue = malloc(template->ulValueLen);
435*12720SWyllys.Ingersoll@Sun.COM 			if (extra_attr->attr.pValue == NULL) {
436*12720SWyllys.Ingersoll@Sun.COM 				return (CKR_HOST_MEMORY);
437*12720SWyllys.Ingersoll@Sun.COM 			}
438*12720SWyllys.Ingersoll@Sun.COM 		}
439*12720SWyllys.Ingersoll@Sun.COM 
440*12720SWyllys.Ingersoll@Sun.COM 		/* Replace the attribute with new value. */
441*12720SWyllys.Ingersoll@Sun.COM 		extra_attr->attr.ulValueLen = template->ulValueLen;
442*12720SWyllys.Ingersoll@Sun.COM 		(void) memcpy(extra_attr->attr.pValue, template->pValue,
443*12720SWyllys.Ingersoll@Sun.COM 		    template->ulValueLen);
444*12720SWyllys.Ingersoll@Sun.COM 	} else {
445*12720SWyllys.Ingersoll@Sun.COM 		extra_attr->attr.pValue = NULL;
446*12720SWyllys.Ingersoll@Sun.COM 	}
447*12720SWyllys.Ingersoll@Sun.COM 
448*12720SWyllys.Ingersoll@Sun.COM 	return (CKR_OK);
449*12720SWyllys.Ingersoll@Sun.COM }
450*12720SWyllys.Ingersoll@Sun.COM 
451*12720SWyllys.Ingersoll@Sun.COM /*
452*12720SWyllys.Ingersoll@Sun.COM  * Copy the boolean data type attribute value from an object for the
453*12720SWyllys.Ingersoll@Sun.COM  * specified attribute to the template.
454*12720SWyllys.Ingersoll@Sun.COM  */
455*12720SWyllys.Ingersoll@Sun.COM CK_RV
get_bool_attr_from_object(kms_object_t * object_p,CK_ULONG bool_flag,CK_ATTRIBUTE_PTR template)456*12720SWyllys.Ingersoll@Sun.COM get_bool_attr_from_object(kms_object_t *object_p, CK_ULONG bool_flag,
457*12720SWyllys.Ingersoll@Sun.COM 	CK_ATTRIBUTE_PTR template)
458*12720SWyllys.Ingersoll@Sun.COM {
459*12720SWyllys.Ingersoll@Sun.COM 
460*12720SWyllys.Ingersoll@Sun.COM 	if (template->pValue == NULL) {
461*12720SWyllys.Ingersoll@Sun.COM 		template->ulValueLen = sizeof (CK_BBOOL);
462*12720SWyllys.Ingersoll@Sun.COM 		return (CKR_OK);
463*12720SWyllys.Ingersoll@Sun.COM 	}
464*12720SWyllys.Ingersoll@Sun.COM 
465*12720SWyllys.Ingersoll@Sun.COM 	if (template->ulValueLen >= sizeof (CK_BBOOL)) {
466*12720SWyllys.Ingersoll@Sun.COM 		/*
467*12720SWyllys.Ingersoll@Sun.COM 		 * The buffer provided by the application is large
468*12720SWyllys.Ingersoll@Sun.COM 		 * enough to hold the value of the attribute.
469*12720SWyllys.Ingersoll@Sun.COM 		 */
470*12720SWyllys.Ingersoll@Sun.COM 		if (object_p->bool_attr_mask & bool_flag) {
471*12720SWyllys.Ingersoll@Sun.COM 			*((CK_BBOOL *)template->pValue) = B_TRUE;
472*12720SWyllys.Ingersoll@Sun.COM 		} else {
473*12720SWyllys.Ingersoll@Sun.COM 			*((CK_BBOOL *)template->pValue) = B_FALSE;
474*12720SWyllys.Ingersoll@Sun.COM 		}
475*12720SWyllys.Ingersoll@Sun.COM 
476*12720SWyllys.Ingersoll@Sun.COM 		template->ulValueLen = sizeof (CK_BBOOL);
477*12720SWyllys.Ingersoll@Sun.COM 		return (CKR_OK);
478*12720SWyllys.Ingersoll@Sun.COM 	} else {
479*12720SWyllys.Ingersoll@Sun.COM 		/*
480*12720SWyllys.Ingersoll@Sun.COM 		 * The buffer provided by the application does
481*12720SWyllys.Ingersoll@Sun.COM 		 * not have enough space to hold the value.
482*12720SWyllys.Ingersoll@Sun.COM 		 */
483*12720SWyllys.Ingersoll@Sun.COM 		template->ulValueLen = (CK_ULONG)-1;
484*12720SWyllys.Ingersoll@Sun.COM 		return (CKR_BUFFER_TOO_SMALL);
485*12720SWyllys.Ingersoll@Sun.COM 	}
486*12720SWyllys.Ingersoll@Sun.COM }
487*12720SWyllys.Ingersoll@Sun.COM 
488*12720SWyllys.Ingersoll@Sun.COM /*
489*12720SWyllys.Ingersoll@Sun.COM  * Set the boolean data type attribute value in the object.
490*12720SWyllys.Ingersoll@Sun.COM  */
491*12720SWyllys.Ingersoll@Sun.COM CK_RV
set_bool_attr_to_object(kms_object_t * object_p,CK_ULONG bool_flag,CK_ATTRIBUTE_PTR template)492*12720SWyllys.Ingersoll@Sun.COM set_bool_attr_to_object(kms_object_t *object_p, CK_ULONG bool_flag,
493*12720SWyllys.Ingersoll@Sun.COM 	CK_ATTRIBUTE_PTR template)
494*12720SWyllys.Ingersoll@Sun.COM {
495*12720SWyllys.Ingersoll@Sun.COM 
496*12720SWyllys.Ingersoll@Sun.COM 	if (*(CK_BBOOL *)template->pValue)
497*12720SWyllys.Ingersoll@Sun.COM 		object_p->bool_attr_mask |= bool_flag;
498*12720SWyllys.Ingersoll@Sun.COM 	else
499*12720SWyllys.Ingersoll@Sun.COM 		object_p->bool_attr_mask &= ~bool_flag;
500*12720SWyllys.Ingersoll@Sun.COM 
501*12720SWyllys.Ingersoll@Sun.COM 	return (CKR_OK);
502*12720SWyllys.Ingersoll@Sun.COM }
503*12720SWyllys.Ingersoll@Sun.COM 
504*12720SWyllys.Ingersoll@Sun.COM 
505*12720SWyllys.Ingersoll@Sun.COM /*
506*12720SWyllys.Ingersoll@Sun.COM  * Copy the CK_ULONG data type attribute value from an object to the
507*12720SWyllys.Ingersoll@Sun.COM  * template.
508*12720SWyllys.Ingersoll@Sun.COM  */
509*12720SWyllys.Ingersoll@Sun.COM CK_RV
get_ulong_attr_from_object(CK_ULONG value,CK_ATTRIBUTE_PTR template)510*12720SWyllys.Ingersoll@Sun.COM get_ulong_attr_from_object(CK_ULONG value, CK_ATTRIBUTE_PTR template)
511*12720SWyllys.Ingersoll@Sun.COM {
512*12720SWyllys.Ingersoll@Sun.COM 
513*12720SWyllys.Ingersoll@Sun.COM 	if (template->pValue == NULL) {
514*12720SWyllys.Ingersoll@Sun.COM 		template->ulValueLen = sizeof (CK_ULONG);
515*12720SWyllys.Ingersoll@Sun.COM 		return (CKR_OK);
516*12720SWyllys.Ingersoll@Sun.COM 	}
517*12720SWyllys.Ingersoll@Sun.COM 
518*12720SWyllys.Ingersoll@Sun.COM 	if (template->ulValueLen >= sizeof (CK_ULONG)) {
519*12720SWyllys.Ingersoll@Sun.COM 		/*
520*12720SWyllys.Ingersoll@Sun.COM 		 * The buffer provided by the application is large
521*12720SWyllys.Ingersoll@Sun.COM 		 * enough to hold the value of the attribute.
522*12720SWyllys.Ingersoll@Sun.COM 		 */
523*12720SWyllys.Ingersoll@Sun.COM 		*(CK_ULONG_PTR)template->pValue = value;
524*12720SWyllys.Ingersoll@Sun.COM 		template->ulValueLen = sizeof (CK_ULONG);
525*12720SWyllys.Ingersoll@Sun.COM 		return (CKR_OK);
526*12720SWyllys.Ingersoll@Sun.COM 	} else {
527*12720SWyllys.Ingersoll@Sun.COM 		/*
528*12720SWyllys.Ingersoll@Sun.COM 		 * The buffer provided by the application does
529*12720SWyllys.Ingersoll@Sun.COM 		 * not have enough space to hold the value.
530*12720SWyllys.Ingersoll@Sun.COM 		 */
531*12720SWyllys.Ingersoll@Sun.COM 		template->ulValueLen = (CK_ULONG)-1;
532*12720SWyllys.Ingersoll@Sun.COM 		return (CKR_BUFFER_TOO_SMALL);
533*12720SWyllys.Ingersoll@Sun.COM 	}
534*12720SWyllys.Ingersoll@Sun.COM }
535*12720SWyllys.Ingersoll@Sun.COM 
536*12720SWyllys.Ingersoll@Sun.COM CK_RV
get_string_from_template(CK_ATTRIBUTE_PTR dest,CK_ATTRIBUTE_PTR src)537*12720SWyllys.Ingersoll@Sun.COM get_string_from_template(CK_ATTRIBUTE_PTR dest, CK_ATTRIBUTE_PTR src)
538*12720SWyllys.Ingersoll@Sun.COM {
539*12720SWyllys.Ingersoll@Sun.COM 	if ((src->pValue != NULL) &&
540*12720SWyllys.Ingersoll@Sun.COM 	    (src->ulValueLen > 0)) {
541*12720SWyllys.Ingersoll@Sun.COM 		/* Allocate storage for the value of the attribute. */
542*12720SWyllys.Ingersoll@Sun.COM 		dest->pValue = malloc(src->ulValueLen);
543*12720SWyllys.Ingersoll@Sun.COM 		if (dest->pValue == NULL) {
544*12720SWyllys.Ingersoll@Sun.COM 			return (CKR_HOST_MEMORY);
545*12720SWyllys.Ingersoll@Sun.COM 		}
546*12720SWyllys.Ingersoll@Sun.COM 
547*12720SWyllys.Ingersoll@Sun.COM 		(void) memcpy(dest->pValue, src->pValue,
548*12720SWyllys.Ingersoll@Sun.COM 		    src->ulValueLen);
549*12720SWyllys.Ingersoll@Sun.COM 		dest->ulValueLen = src->ulValueLen;
550*12720SWyllys.Ingersoll@Sun.COM 		dest->type = src->type;
551*12720SWyllys.Ingersoll@Sun.COM 	} else {
552*12720SWyllys.Ingersoll@Sun.COM 		dest->pValue = NULL;
553*12720SWyllys.Ingersoll@Sun.COM 		dest->ulValueLen = 0;
554*12720SWyllys.Ingersoll@Sun.COM 		dest->type = src->type;
555*12720SWyllys.Ingersoll@Sun.COM 	}
556*12720SWyllys.Ingersoll@Sun.COM 
557*12720SWyllys.Ingersoll@Sun.COM 	return (CKR_OK);
558*12720SWyllys.Ingersoll@Sun.COM 
559*12720SWyllys.Ingersoll@Sun.COM }
560*12720SWyllys.Ingersoll@Sun.COM 
561*12720SWyllys.Ingersoll@Sun.COM void
string_attr_cleanup(CK_ATTRIBUTE_PTR template)562*12720SWyllys.Ingersoll@Sun.COM string_attr_cleanup(CK_ATTRIBUTE_PTR template)
563*12720SWyllys.Ingersoll@Sun.COM {
564*12720SWyllys.Ingersoll@Sun.COM 
565*12720SWyllys.Ingersoll@Sun.COM 	if (template->pValue) {
566*12720SWyllys.Ingersoll@Sun.COM 		free(template->pValue);
567*12720SWyllys.Ingersoll@Sun.COM 		template->pValue = NULL;
568*12720SWyllys.Ingersoll@Sun.COM 		template->ulValueLen = 0;
569*12720SWyllys.Ingersoll@Sun.COM 	}
570*12720SWyllys.Ingersoll@Sun.COM }
571*12720SWyllys.Ingersoll@Sun.COM 
572*12720SWyllys.Ingersoll@Sun.COM /*
573*12720SWyllys.Ingersoll@Sun.COM  * Parse the common attributes. Return to caller with appropriate return
574*12720SWyllys.Ingersoll@Sun.COM  * value to indicate if the supplied template specifies a valid attribute
575*12720SWyllys.Ingersoll@Sun.COM  * with a valid value.
576*12720SWyllys.Ingersoll@Sun.COM  */
577*12720SWyllys.Ingersoll@Sun.COM static CK_RV
kms_parse_common_attrs(CK_ATTRIBUTE_PTR template,uint64_t * attr_mask_p)578*12720SWyllys.Ingersoll@Sun.COM kms_parse_common_attrs(CK_ATTRIBUTE_PTR template, uint64_t *attr_mask_p)
579*12720SWyllys.Ingersoll@Sun.COM {
580*12720SWyllys.Ingersoll@Sun.COM 	CK_RV rv = CKR_OK;
581*12720SWyllys.Ingersoll@Sun.COM 	kms_slot_t *pslot = get_slotinfo();
582*12720SWyllys.Ingersoll@Sun.COM 
583*12720SWyllys.Ingersoll@Sun.COM 	switch (template->type) {
584*12720SWyllys.Ingersoll@Sun.COM 	case CKA_CLASS:
585*12720SWyllys.Ingersoll@Sun.COM 		break;
586*12720SWyllys.Ingersoll@Sun.COM 	case CKA_TOKEN:
587*12720SWyllys.Ingersoll@Sun.COM 		if ((*(CK_BBOOL *)template->pValue) == TRUE)
588*12720SWyllys.Ingersoll@Sun.COM 			*attr_mask_p |= TOKEN_BOOL_ON;
589*12720SWyllys.Ingersoll@Sun.COM 		break;
590*12720SWyllys.Ingersoll@Sun.COM 
591*12720SWyllys.Ingersoll@Sun.COM 	case CKA_PRIVATE:
592*12720SWyllys.Ingersoll@Sun.COM 		if ((*(CK_BBOOL *)template->pValue) == TRUE) {
593*12720SWyllys.Ingersoll@Sun.COM 			/*
594*12720SWyllys.Ingersoll@Sun.COM 			 * Cannot create a private object if the token
595*12720SWyllys.Ingersoll@Sun.COM 			 * has a keystore and the user isn't logged in.
596*12720SWyllys.Ingersoll@Sun.COM 			 */
597*12720SWyllys.Ingersoll@Sun.COM 			if (pslot->sl_state != CKU_USER) {
598*12720SWyllys.Ingersoll@Sun.COM 				rv = CKR_ATTRIBUTE_VALUE_INVALID;
599*12720SWyllys.Ingersoll@Sun.COM 			} else {
600*12720SWyllys.Ingersoll@Sun.COM 				*attr_mask_p |= PRIVATE_BOOL_ON;
601*12720SWyllys.Ingersoll@Sun.COM 			}
602*12720SWyllys.Ingersoll@Sun.COM 		}
603*12720SWyllys.Ingersoll@Sun.COM 		break;
604*12720SWyllys.Ingersoll@Sun.COM 
605*12720SWyllys.Ingersoll@Sun.COM 	case CKA_MODIFIABLE:
606*12720SWyllys.Ingersoll@Sun.COM 		if ((*(CK_BBOOL *)template->pValue) == FALSE) {
607*12720SWyllys.Ingersoll@Sun.COM 			*attr_mask_p &= ~MODIFIABLE_BOOL_ON;
608*12720SWyllys.Ingersoll@Sun.COM 		}
609*12720SWyllys.Ingersoll@Sun.COM 		break;
610*12720SWyllys.Ingersoll@Sun.COM 
611*12720SWyllys.Ingersoll@Sun.COM 	case CKA_LABEL:
612*12720SWyllys.Ingersoll@Sun.COM 		break;
613*12720SWyllys.Ingersoll@Sun.COM 
614*12720SWyllys.Ingersoll@Sun.COM 	default:
615*12720SWyllys.Ingersoll@Sun.COM 		rv = CKR_TEMPLATE_INCONSISTENT;
616*12720SWyllys.Ingersoll@Sun.COM 	}
617*12720SWyllys.Ingersoll@Sun.COM 
618*12720SWyllys.Ingersoll@Sun.COM 	return (rv);
619*12720SWyllys.Ingersoll@Sun.COM }
620*12720SWyllys.Ingersoll@Sun.COM 
621*12720SWyllys.Ingersoll@Sun.COM /*
622*12720SWyllys.Ingersoll@Sun.COM  * Build a Secret Key Object.
623*12720SWyllys.Ingersoll@Sun.COM  *
624*12720SWyllys.Ingersoll@Sun.COM  * - Parse the object's template, and when an error is detected such as
625*12720SWyllys.Ingersoll@Sun.COM  *   invalid attribute type, invalid attribute value, etc., return
626*12720SWyllys.Ingersoll@Sun.COM  *   with appropriate return value.
627*12720SWyllys.Ingersoll@Sun.COM  * - Set up attribute mask field in the object for the supplied common
628*12720SWyllys.Ingersoll@Sun.COM  *   attributes that have boolean type.
629*12720SWyllys.Ingersoll@Sun.COM  * - Build the attribute_info struct to hold the value of each supplied
630*12720SWyllys.Ingersoll@Sun.COM  *   attribute that has byte array type. Link attribute_info structs
631*12720SWyllys.Ingersoll@Sun.COM  *   together to form the extra attribute list of the object.
632*12720SWyllys.Ingersoll@Sun.COM  * - Allocate storage for the Secret Key object.
633*12720SWyllys.Ingersoll@Sun.COM  * - Build the Secret Key object. Allocate storage to hold the big integer
634*12720SWyllys.Ingersoll@Sun.COM  *   value for the attribute CKA_VALUE that is required for all the key
635*12720SWyllys.Ingersoll@Sun.COM  *   types supported by secret key object.
636*12720SWyllys.Ingersoll@Sun.COM  *
637*12720SWyllys.Ingersoll@Sun.COM  */
638*12720SWyllys.Ingersoll@Sun.COM CK_RV
kms_build_secret_key_object(CK_ATTRIBUTE_PTR template,CK_ULONG ulAttrNum,kms_object_t * new_object)639*12720SWyllys.Ingersoll@Sun.COM kms_build_secret_key_object(CK_ATTRIBUTE_PTR template,
640*12720SWyllys.Ingersoll@Sun.COM     CK_ULONG ulAttrNum,	kms_object_t *new_object)
641*12720SWyllys.Ingersoll@Sun.COM {
642*12720SWyllys.Ingersoll@Sun.COM 	int		i;
643*12720SWyllys.Ingersoll@Sun.COM 	CK_KEY_TYPE	keytype = (CK_KEY_TYPE)~0UL;
644*12720SWyllys.Ingersoll@Sun.COM 	uint64_t	attr_mask;
645*12720SWyllys.Ingersoll@Sun.COM 	CK_RV 		rv = CKR_OK;
646*12720SWyllys.Ingersoll@Sun.COM 	int		isLabel = 0;
647*12720SWyllys.Ingersoll@Sun.COM 	/* Must not set flags */
648*12720SWyllys.Ingersoll@Sun.COM 	int		isValueLen = 0;
649*12720SWyllys.Ingersoll@Sun.COM 	CK_ATTRIBUTE	string_tmp;
650*12720SWyllys.Ingersoll@Sun.COM 	secret_key_obj_t  *sck;
651*12720SWyllys.Ingersoll@Sun.COM 
652*12720SWyllys.Ingersoll@Sun.COM 	string_tmp.pValue = NULL;
653*12720SWyllys.Ingersoll@Sun.COM 
654*12720SWyllys.Ingersoll@Sun.COM 	/*
655*12720SWyllys.Ingersoll@Sun.COM 	 * If the object was pulled from the KMS, the
656*12720SWyllys.Ingersoll@Sun.COM 	 * attributes are encoded in the object record
657*12720SWyllys.Ingersoll@Sun.COM 	 * before this function is called, we don't
658*12720SWyllys.Ingersoll@Sun.COM 	 * want to overwrite them unless the attribute
659*12720SWyllys.Ingersoll@Sun.COM 	 * template says differently.
660*12720SWyllys.Ingersoll@Sun.COM 	 */
661*12720SWyllys.Ingersoll@Sun.COM 	if (new_object->bool_attr_mask != 0)
662*12720SWyllys.Ingersoll@Sun.COM 		attr_mask = new_object->bool_attr_mask;
663*12720SWyllys.Ingersoll@Sun.COM 	else
664*12720SWyllys.Ingersoll@Sun.COM 		attr_mask = SECRET_KEY_DEFAULT;
665*12720SWyllys.Ingersoll@Sun.COM 
666*12720SWyllys.Ingersoll@Sun.COM 	/* Allocate storage for Secret Key Object. */
667*12720SWyllys.Ingersoll@Sun.COM 	sck = calloc(1, sizeof (secret_key_obj_t));
668*12720SWyllys.Ingersoll@Sun.COM 	if (sck == NULL) {
669*12720SWyllys.Ingersoll@Sun.COM 		rv = CKR_HOST_MEMORY;
670*12720SWyllys.Ingersoll@Sun.COM 		goto fail_cleanup;
671*12720SWyllys.Ingersoll@Sun.COM 	}
672*12720SWyllys.Ingersoll@Sun.COM 
673*12720SWyllys.Ingersoll@Sun.COM 	new_object->object_class_u.secret_key = sck;
674*12720SWyllys.Ingersoll@Sun.COM 	new_object->class = CKO_SECRET_KEY;
675*12720SWyllys.Ingersoll@Sun.COM 
676*12720SWyllys.Ingersoll@Sun.COM 	for (i = 0; i < ulAttrNum; i++) {
677*12720SWyllys.Ingersoll@Sun.COM 
678*12720SWyllys.Ingersoll@Sun.COM 		/* Secret Key Object Attributes */
679*12720SWyllys.Ingersoll@Sun.COM 		switch (template[i].type) {
680*12720SWyllys.Ingersoll@Sun.COM 
681*12720SWyllys.Ingersoll@Sun.COM 		/* common key attributes */
682*12720SWyllys.Ingersoll@Sun.COM 		case CKA_KEY_TYPE:
683*12720SWyllys.Ingersoll@Sun.COM 		keytype = *((CK_KEY_TYPE*)template[i].pValue);
684*12720SWyllys.Ingersoll@Sun.COM 			break;
685*12720SWyllys.Ingersoll@Sun.COM 
686*12720SWyllys.Ingersoll@Sun.COM 		case CKA_ID:
687*12720SWyllys.Ingersoll@Sun.COM 		case CKA_START_DATE:
688*12720SWyllys.Ingersoll@Sun.COM 		case CKA_END_DATE:
689*12720SWyllys.Ingersoll@Sun.COM 			/*
690*12720SWyllys.Ingersoll@Sun.COM 			 * Allocate storage to hold the attribute
691*12720SWyllys.Ingersoll@Sun.COM 			 * value with byte array type, and add it to
692*12720SWyllys.Ingersoll@Sun.COM 			 * the extra attribute list of the object.
693*12720SWyllys.Ingersoll@Sun.COM 			 */
694*12720SWyllys.Ingersoll@Sun.COM 			rv = kms_add_extra_attr(&template[i],
695*12720SWyllys.Ingersoll@Sun.COM 			    new_object);
696*12720SWyllys.Ingersoll@Sun.COM 			if (rv != CKR_OK) {
697*12720SWyllys.Ingersoll@Sun.COM 				goto fail_cleanup;
698*12720SWyllys.Ingersoll@Sun.COM 			}
699*12720SWyllys.Ingersoll@Sun.COM 			break;
700*12720SWyllys.Ingersoll@Sun.COM 
701*12720SWyllys.Ingersoll@Sun.COM 		/*
702*12720SWyllys.Ingersoll@Sun.COM 		 * The following key related attribute types must
703*12720SWyllys.Ingersoll@Sun.COM 		 * not be specified by C_CreateObject.
704*12720SWyllys.Ingersoll@Sun.COM 		 */
705*12720SWyllys.Ingersoll@Sun.COM 		case CKA_LOCAL:
706*12720SWyllys.Ingersoll@Sun.COM 		case CKA_KEY_GEN_MECHANISM:
707*12720SWyllys.Ingersoll@Sun.COM 		case CKA_ALWAYS_SENSITIVE:
708*12720SWyllys.Ingersoll@Sun.COM 		case CKA_NEVER_EXTRACTABLE:
709*12720SWyllys.Ingersoll@Sun.COM 			rv = CKR_TEMPLATE_INCONSISTENT;
710*12720SWyllys.Ingersoll@Sun.COM 			goto fail_cleanup;
711*12720SWyllys.Ingersoll@Sun.COM 
712*12720SWyllys.Ingersoll@Sun.COM 		/* Key related boolean attributes */
713*12720SWyllys.Ingersoll@Sun.COM 		case CKA_DERIVE:
714*12720SWyllys.Ingersoll@Sun.COM 			if (*(CK_BBOOL *)template[i].pValue)
715*12720SWyllys.Ingersoll@Sun.COM 				attr_mask |= DERIVE_BOOL_ON;
716*12720SWyllys.Ingersoll@Sun.COM 			break;
717*12720SWyllys.Ingersoll@Sun.COM 
718*12720SWyllys.Ingersoll@Sun.COM 		case CKA_SENSITIVE:
719*12720SWyllys.Ingersoll@Sun.COM 			if (*(CK_BBOOL *)template[i].pValue)
720*12720SWyllys.Ingersoll@Sun.COM 				attr_mask |= SENSITIVE_BOOL_ON;
721*12720SWyllys.Ingersoll@Sun.COM 			break;
722*12720SWyllys.Ingersoll@Sun.COM 
723*12720SWyllys.Ingersoll@Sun.COM 		case CKA_ENCRYPT:
724*12720SWyllys.Ingersoll@Sun.COM 			if (*(CK_BBOOL *)template[i].pValue)
725*12720SWyllys.Ingersoll@Sun.COM 				attr_mask |= ENCRYPT_BOOL_ON;
726*12720SWyllys.Ingersoll@Sun.COM 			else
727*12720SWyllys.Ingersoll@Sun.COM 				attr_mask &= ~ENCRYPT_BOOL_ON;
728*12720SWyllys.Ingersoll@Sun.COM 			break;
729*12720SWyllys.Ingersoll@Sun.COM 
730*12720SWyllys.Ingersoll@Sun.COM 		case CKA_DECRYPT:
731*12720SWyllys.Ingersoll@Sun.COM 			if (*(CK_BBOOL *)template[i].pValue)
732*12720SWyllys.Ingersoll@Sun.COM 				attr_mask |= DECRYPT_BOOL_ON;
733*12720SWyllys.Ingersoll@Sun.COM 			else
734*12720SWyllys.Ingersoll@Sun.COM 				attr_mask &= ~DECRYPT_BOOL_ON;
735*12720SWyllys.Ingersoll@Sun.COM 			break;
736*12720SWyllys.Ingersoll@Sun.COM 
737*12720SWyllys.Ingersoll@Sun.COM 		case CKA_SIGN:
738*12720SWyllys.Ingersoll@Sun.COM 			if (*(CK_BBOOL *)template[i].pValue)
739*12720SWyllys.Ingersoll@Sun.COM 				attr_mask |= SIGN_BOOL_ON;
740*12720SWyllys.Ingersoll@Sun.COM 			else
741*12720SWyllys.Ingersoll@Sun.COM 				attr_mask &= ~SIGN_BOOL_ON;
742*12720SWyllys.Ingersoll@Sun.COM 			break;
743*12720SWyllys.Ingersoll@Sun.COM 
744*12720SWyllys.Ingersoll@Sun.COM 		case CKA_VERIFY:
745*12720SWyllys.Ingersoll@Sun.COM 			if (*(CK_BBOOL *)template[i].pValue)
746*12720SWyllys.Ingersoll@Sun.COM 				attr_mask |= VERIFY_BOOL_ON;
747*12720SWyllys.Ingersoll@Sun.COM 			else
748*12720SWyllys.Ingersoll@Sun.COM 				attr_mask &= ~VERIFY_BOOL_ON;
749*12720SWyllys.Ingersoll@Sun.COM 			break;
750*12720SWyllys.Ingersoll@Sun.COM 
751*12720SWyllys.Ingersoll@Sun.COM 		case CKA_WRAP:
752*12720SWyllys.Ingersoll@Sun.COM 			if (*(CK_BBOOL *)template[i].pValue)
753*12720SWyllys.Ingersoll@Sun.COM 				attr_mask |= WRAP_BOOL_ON;
754*12720SWyllys.Ingersoll@Sun.COM 			break;
755*12720SWyllys.Ingersoll@Sun.COM 
756*12720SWyllys.Ingersoll@Sun.COM 		case CKA_UNWRAP:
757*12720SWyllys.Ingersoll@Sun.COM 			if (*(CK_BBOOL *)template[i].pValue)
758*12720SWyllys.Ingersoll@Sun.COM 				attr_mask |= UNWRAP_BOOL_ON;
759*12720SWyllys.Ingersoll@Sun.COM 			break;
760*12720SWyllys.Ingersoll@Sun.COM 
761*12720SWyllys.Ingersoll@Sun.COM 		case CKA_EXTRACTABLE:
762*12720SWyllys.Ingersoll@Sun.COM 			if (*(CK_BBOOL *)template[i].pValue)
763*12720SWyllys.Ingersoll@Sun.COM 				attr_mask |= EXTRACTABLE_BOOL_ON;
764*12720SWyllys.Ingersoll@Sun.COM 			else
765*12720SWyllys.Ingersoll@Sun.COM 				attr_mask &= ~EXTRACTABLE_BOOL_ON;
766*12720SWyllys.Ingersoll@Sun.COM 			break;
767*12720SWyllys.Ingersoll@Sun.COM 
768*12720SWyllys.Ingersoll@Sun.COM 		case CKA_VALUE:
769*12720SWyllys.Ingersoll@Sun.COM 			if ((template[i].ulValueLen == 0) ||
770*12720SWyllys.Ingersoll@Sun.COM 			    (template[i].pValue == NULL)) {
771*12720SWyllys.Ingersoll@Sun.COM 				rv = CKR_ATTRIBUTE_VALUE_INVALID;
772*12720SWyllys.Ingersoll@Sun.COM 				goto fail_cleanup;
773*12720SWyllys.Ingersoll@Sun.COM 			}
774*12720SWyllys.Ingersoll@Sun.COM 			/*
775*12720SWyllys.Ingersoll@Sun.COM 			 * Copyin attribute from template
776*12720SWyllys.Ingersoll@Sun.COM 			 * to a local variable.
777*12720SWyllys.Ingersoll@Sun.COM 			 */
778*12720SWyllys.Ingersoll@Sun.COM 			sck->sk_value = malloc(template[i].ulValueLen);
779*12720SWyllys.Ingersoll@Sun.COM 			if (sck->sk_value == NULL) {
780*12720SWyllys.Ingersoll@Sun.COM 				rv = CKR_HOST_MEMORY;
781*12720SWyllys.Ingersoll@Sun.COM 				goto fail_cleanup;
782*12720SWyllys.Ingersoll@Sun.COM 			}
783*12720SWyllys.Ingersoll@Sun.COM 			(void) memcpy(sck->sk_value, template[i].pValue,
784*12720SWyllys.Ingersoll@Sun.COM 			    template[i].ulValueLen);
785*12720SWyllys.Ingersoll@Sun.COM 			sck->sk_value_len = template[i].ulValueLen;
786*12720SWyllys.Ingersoll@Sun.COM 			break;
787*12720SWyllys.Ingersoll@Sun.COM 
788*12720SWyllys.Ingersoll@Sun.COM 		case CKA_VALUE_LEN:
789*12720SWyllys.Ingersoll@Sun.COM 			isValueLen = 1;
790*12720SWyllys.Ingersoll@Sun.COM 			if (template[i].pValue != NULL)
791*12720SWyllys.Ingersoll@Sun.COM 				sck->sk_value_len =
792*12720SWyllys.Ingersoll@Sun.COM 				    *(CK_ULONG_PTR)template[i].pValue;
793*12720SWyllys.Ingersoll@Sun.COM 			else
794*12720SWyllys.Ingersoll@Sun.COM 				sck->sk_value_len = 0;
795*12720SWyllys.Ingersoll@Sun.COM 			break;
796*12720SWyllys.Ingersoll@Sun.COM 
797*12720SWyllys.Ingersoll@Sun.COM 		case CKA_LABEL:
798*12720SWyllys.Ingersoll@Sun.COM 			isLabel = 1;
799*12720SWyllys.Ingersoll@Sun.COM 			rv = get_string_from_template(&string_tmp,
800*12720SWyllys.Ingersoll@Sun.COM 			    &template[i]);
801*12720SWyllys.Ingersoll@Sun.COM 			if (rv != CKR_OK)
802*12720SWyllys.Ingersoll@Sun.COM 				goto fail_cleanup;
803*12720SWyllys.Ingersoll@Sun.COM 			break;
804*12720SWyllys.Ingersoll@Sun.COM 
805*12720SWyllys.Ingersoll@Sun.COM 		default:
806*12720SWyllys.Ingersoll@Sun.COM 			rv = kms_parse_common_attrs(&template[i], &attr_mask);
807*12720SWyllys.Ingersoll@Sun.COM 			if (rv != CKR_OK)
808*12720SWyllys.Ingersoll@Sun.COM 				goto fail_cleanup;
809*12720SWyllys.Ingersoll@Sun.COM 			break;
810*12720SWyllys.Ingersoll@Sun.COM 
811*12720SWyllys.Ingersoll@Sun.COM 		}
812*12720SWyllys.Ingersoll@Sun.COM 	} /* For */
813*12720SWyllys.Ingersoll@Sun.COM 
814*12720SWyllys.Ingersoll@Sun.COM 	if (keytype == (CK_KEY_TYPE)~0UL) {
815*12720SWyllys.Ingersoll@Sun.COM 		rv = CKR_TEMPLATE_INCOMPLETE;
816*12720SWyllys.Ingersoll@Sun.COM 		goto fail_cleanup;
817*12720SWyllys.Ingersoll@Sun.COM 	}
818*12720SWyllys.Ingersoll@Sun.COM 
819*12720SWyllys.Ingersoll@Sun.COM 	new_object->key_type = keytype;
820*12720SWyllys.Ingersoll@Sun.COM 
821*12720SWyllys.Ingersoll@Sun.COM 	/* Supported key types of the Secret Key Object */
822*12720SWyllys.Ingersoll@Sun.COM 	switch (keytype) {
823*12720SWyllys.Ingersoll@Sun.COM 
824*12720SWyllys.Ingersoll@Sun.COM 	case CKK_AES:
825*12720SWyllys.Ingersoll@Sun.COM 		if (!isValueLen) {
826*12720SWyllys.Ingersoll@Sun.COM 			rv = CKR_TEMPLATE_INCOMPLETE;
827*12720SWyllys.Ingersoll@Sun.COM 			goto fail_cleanup;
828*12720SWyllys.Ingersoll@Sun.COM 		}
829*12720SWyllys.Ingersoll@Sun.COM 		if (sck->sk_value_len != AES_MIN_KEY_BYTES &&
830*12720SWyllys.Ingersoll@Sun.COM 		    sck->sk_value_len != AES_192_KEY_BYTES &&
831*12720SWyllys.Ingersoll@Sun.COM 		    sck->sk_value_len != AES_MAX_KEY_BYTES) {
832*12720SWyllys.Ingersoll@Sun.COM 			rv = CKR_ATTRIBUTE_VALUE_INVALID;
833*12720SWyllys.Ingersoll@Sun.COM 			goto fail_cleanup;
834*12720SWyllys.Ingersoll@Sun.COM 		}
835*12720SWyllys.Ingersoll@Sun.COM 		break;
836*12720SWyllys.Ingersoll@Sun.COM 
837*12720SWyllys.Ingersoll@Sun.COM 	case CKK_RC4:
838*12720SWyllys.Ingersoll@Sun.COM 	case CKK_GENERIC_SECRET:
839*12720SWyllys.Ingersoll@Sun.COM 	case CKK_BLOWFISH:
840*12720SWyllys.Ingersoll@Sun.COM 	case CKK_DES:
841*12720SWyllys.Ingersoll@Sun.COM 	case CKK_DES2:
842*12720SWyllys.Ingersoll@Sun.COM 	case CKK_DES3:
843*12720SWyllys.Ingersoll@Sun.COM 	default:
844*12720SWyllys.Ingersoll@Sun.COM 		rv = CKR_TEMPLATE_INCONSISTENT;
845*12720SWyllys.Ingersoll@Sun.COM 		goto fail_cleanup;
846*12720SWyllys.Ingersoll@Sun.COM 	}
847*12720SWyllys.Ingersoll@Sun.COM 
848*12720SWyllys.Ingersoll@Sun.COM 	/* Set up object. */
849*12720SWyllys.Ingersoll@Sun.COM 	new_object->bool_attr_mask = attr_mask;
850*12720SWyllys.Ingersoll@Sun.COM 	if (isLabel) {
851*12720SWyllys.Ingersoll@Sun.COM 		rv = kms_add_extra_attr(&string_tmp, new_object);
852*12720SWyllys.Ingersoll@Sun.COM 		if (rv != CKR_OK)
853*12720SWyllys.Ingersoll@Sun.COM 			goto fail_cleanup;
854*12720SWyllys.Ingersoll@Sun.COM 		string_attr_cleanup(&string_tmp);
855*12720SWyllys.Ingersoll@Sun.COM 	}
856*12720SWyllys.Ingersoll@Sun.COM 
857*12720SWyllys.Ingersoll@Sun.COM 	return (rv);
858*12720SWyllys.Ingersoll@Sun.COM 
859*12720SWyllys.Ingersoll@Sun.COM fail_cleanup:
860*12720SWyllys.Ingersoll@Sun.COM 	/*
861*12720SWyllys.Ingersoll@Sun.COM 	 * cleanup the storage allocated to the local variables.
862*12720SWyllys.Ingersoll@Sun.COM 	 */
863*12720SWyllys.Ingersoll@Sun.COM 	string_attr_cleanup(&string_tmp);
864*12720SWyllys.Ingersoll@Sun.COM 
865*12720SWyllys.Ingersoll@Sun.COM 	/*
866*12720SWyllys.Ingersoll@Sun.COM 	 * cleanup the storage allocated inside the object itself.
867*12720SWyllys.Ingersoll@Sun.COM 	 */
868*12720SWyllys.Ingersoll@Sun.COM 	kms_cleanup_object(new_object);
869*12720SWyllys.Ingersoll@Sun.COM 
870*12720SWyllys.Ingersoll@Sun.COM 	return (rv);
871*12720SWyllys.Ingersoll@Sun.COM }
872*12720SWyllys.Ingersoll@Sun.COM 
873*12720SWyllys.Ingersoll@Sun.COM /*
874*12720SWyllys.Ingersoll@Sun.COM  * Validate the attribute types in the object's template. Then,
875*12720SWyllys.Ingersoll@Sun.COM  * call the appropriate build function according to the class of
876*12720SWyllys.Ingersoll@Sun.COM  * the object specified in the template.
877*12720SWyllys.Ingersoll@Sun.COM  *
878*12720SWyllys.Ingersoll@Sun.COM  * Note: The following classes of objects are supported:
879*12720SWyllys.Ingersoll@Sun.COM  * - CKO_SECRET_KEY
880*12720SWyllys.Ingersoll@Sun.COM  */
881*12720SWyllys.Ingersoll@Sun.COM CK_RV
kms_build_object(CK_ATTRIBUTE_PTR template,CK_ULONG ulAttrNum,kms_object_t * new_object)882*12720SWyllys.Ingersoll@Sun.COM kms_build_object(CK_ATTRIBUTE_PTR template, CK_ULONG ulAttrNum,
883*12720SWyllys.Ingersoll@Sun.COM     kms_object_t *new_object)
884*12720SWyllys.Ingersoll@Sun.COM {
885*12720SWyllys.Ingersoll@Sun.COM 	CK_OBJECT_CLASS class = (CK_OBJECT_CLASS)~0UL;
886*12720SWyllys.Ingersoll@Sun.COM 	CK_RV 		rv = CKR_OK;
887*12720SWyllys.Ingersoll@Sun.COM 
888*12720SWyllys.Ingersoll@Sun.COM 	if (template == NULL) {
889*12720SWyllys.Ingersoll@Sun.COM 		return (CKR_ARGUMENTS_BAD);
890*12720SWyllys.Ingersoll@Sun.COM 	}
891*12720SWyllys.Ingersoll@Sun.COM 
892*12720SWyllys.Ingersoll@Sun.COM 	/* Validate the attribute type in the template. */
893*12720SWyllys.Ingersoll@Sun.COM 	rv = kms_validate_attr(template, ulAttrNum, &class);
894*12720SWyllys.Ingersoll@Sun.COM 	if (rv != CKR_OK)
895*12720SWyllys.Ingersoll@Sun.COM 		return (rv);
896*12720SWyllys.Ingersoll@Sun.COM 
897*12720SWyllys.Ingersoll@Sun.COM 	if (class == (CK_OBJECT_CLASS)~0UL)
898*12720SWyllys.Ingersoll@Sun.COM 		return (CKR_TEMPLATE_INCOMPLETE);
899*12720SWyllys.Ingersoll@Sun.COM 
900*12720SWyllys.Ingersoll@Sun.COM 	/*
901*12720SWyllys.Ingersoll@Sun.COM 	 * Call the appropriate function based on the supported class
902*12720SWyllys.Ingersoll@Sun.COM 	 * of the object.
903*12720SWyllys.Ingersoll@Sun.COM 	 */
904*12720SWyllys.Ingersoll@Sun.COM 	switch (class) {
905*12720SWyllys.Ingersoll@Sun.COM 
906*12720SWyllys.Ingersoll@Sun.COM 	case CKO_SECRET_KEY:
907*12720SWyllys.Ingersoll@Sun.COM 		rv = kms_build_secret_key_object(template, ulAttrNum,
908*12720SWyllys.Ingersoll@Sun.COM 		    new_object);
909*12720SWyllys.Ingersoll@Sun.COM 		break;
910*12720SWyllys.Ingersoll@Sun.COM 
911*12720SWyllys.Ingersoll@Sun.COM 	case CKO_DOMAIN_PARAMETERS:
912*12720SWyllys.Ingersoll@Sun.COM 	case CKO_DATA:
913*12720SWyllys.Ingersoll@Sun.COM 	case CKO_CERTIFICATE:
914*12720SWyllys.Ingersoll@Sun.COM 	case CKO_HW_FEATURE:
915*12720SWyllys.Ingersoll@Sun.COM 	case CKO_VENDOR_DEFINED:
916*12720SWyllys.Ingersoll@Sun.COM 	case CKO_PUBLIC_KEY:
917*12720SWyllys.Ingersoll@Sun.COM 	case CKO_PRIVATE_KEY:
918*12720SWyllys.Ingersoll@Sun.COM 	default:
919*12720SWyllys.Ingersoll@Sun.COM 		return (CKR_ATTRIBUTE_VALUE_INVALID);
920*12720SWyllys.Ingersoll@Sun.COM 	}
921*12720SWyllys.Ingersoll@Sun.COM 
922*12720SWyllys.Ingersoll@Sun.COM 	return (rv);
923*12720SWyllys.Ingersoll@Sun.COM }
924*12720SWyllys.Ingersoll@Sun.COM 
925*12720SWyllys.Ingersoll@Sun.COM 
926*12720SWyllys.Ingersoll@Sun.COM /*
927*12720SWyllys.Ingersoll@Sun.COM  * Get the value of a requested attribute that is common to all supported
928*12720SWyllys.Ingersoll@Sun.COM  * classes (i.e. public key, private key, secret key classes).
929*12720SWyllys.Ingersoll@Sun.COM  */
930*12720SWyllys.Ingersoll@Sun.COM CK_RV
kms_get_common_attrs(kms_object_t * object_p,CK_ATTRIBUTE_PTR template)931*12720SWyllys.Ingersoll@Sun.COM kms_get_common_attrs(kms_object_t *object_p, CK_ATTRIBUTE_PTR template)
932*12720SWyllys.Ingersoll@Sun.COM {
933*12720SWyllys.Ingersoll@Sun.COM 
934*12720SWyllys.Ingersoll@Sun.COM 	CK_RV rv = CKR_OK;
935*12720SWyllys.Ingersoll@Sun.COM 
936*12720SWyllys.Ingersoll@Sun.COM 	switch (template->type) {
937*12720SWyllys.Ingersoll@Sun.COM 
938*12720SWyllys.Ingersoll@Sun.COM 	case CKA_CLASS:
939*12720SWyllys.Ingersoll@Sun.COM 		return (get_ulong_attr_from_object(object_p->class,
940*12720SWyllys.Ingersoll@Sun.COM 		    template));
941*12720SWyllys.Ingersoll@Sun.COM 
942*12720SWyllys.Ingersoll@Sun.COM 	/* default boolean attributes */
943*12720SWyllys.Ingersoll@Sun.COM 	case CKA_TOKEN:
944*12720SWyllys.Ingersoll@Sun.COM 		template->ulValueLen = sizeof (CK_BBOOL);
945*12720SWyllys.Ingersoll@Sun.COM 		if (template->pValue == NULL) {
946*12720SWyllys.Ingersoll@Sun.COM 			return (CKR_OK);
947*12720SWyllys.Ingersoll@Sun.COM 		}
948*12720SWyllys.Ingersoll@Sun.COM 
949*12720SWyllys.Ingersoll@Sun.COM 		*((CK_BBOOL *)template->pValue) = B_FALSE;
950*12720SWyllys.Ingersoll@Sun.COM 		break;
951*12720SWyllys.Ingersoll@Sun.COM 
952*12720SWyllys.Ingersoll@Sun.COM 	case CKA_PRIVATE:
953*12720SWyllys.Ingersoll@Sun.COM 
954*12720SWyllys.Ingersoll@Sun.COM 		template->ulValueLen = sizeof (CK_BBOOL);
955*12720SWyllys.Ingersoll@Sun.COM 		if (template->pValue == NULL) {
956*12720SWyllys.Ingersoll@Sun.COM 			return (CKR_OK);
957*12720SWyllys.Ingersoll@Sun.COM 		}
958*12720SWyllys.Ingersoll@Sun.COM 		if (object_p->bool_attr_mask & PRIVATE_BOOL_ON) {
959*12720SWyllys.Ingersoll@Sun.COM 			*((CK_BBOOL *)template->pValue) = B_TRUE;
960*12720SWyllys.Ingersoll@Sun.COM 		} else {
961*12720SWyllys.Ingersoll@Sun.COM 			*((CK_BBOOL *)template->pValue) = B_FALSE;
962*12720SWyllys.Ingersoll@Sun.COM 		}
963*12720SWyllys.Ingersoll@Sun.COM 		break;
964*12720SWyllys.Ingersoll@Sun.COM 
965*12720SWyllys.Ingersoll@Sun.COM 	case CKA_MODIFIABLE:
966*12720SWyllys.Ingersoll@Sun.COM 		template->ulValueLen = sizeof (CK_BBOOL);
967*12720SWyllys.Ingersoll@Sun.COM 		if (template->pValue == NULL) {
968*12720SWyllys.Ingersoll@Sun.COM 			return (CKR_OK);
969*12720SWyllys.Ingersoll@Sun.COM 		}
970*12720SWyllys.Ingersoll@Sun.COM 		if ((object_p->bool_attr_mask) & MODIFIABLE_BOOL_ON)
971*12720SWyllys.Ingersoll@Sun.COM 			*((CK_BBOOL *)template->pValue) = B_TRUE;
972*12720SWyllys.Ingersoll@Sun.COM 		else
973*12720SWyllys.Ingersoll@Sun.COM 			*((CK_BBOOL *)template->pValue) = B_FALSE;
974*12720SWyllys.Ingersoll@Sun.COM 		break;
975*12720SWyllys.Ingersoll@Sun.COM 
976*12720SWyllys.Ingersoll@Sun.COM 	case CKA_LABEL:
977*12720SWyllys.Ingersoll@Sun.COM 		return (get_extra_attr_from_object(object_p,
978*12720SWyllys.Ingersoll@Sun.COM 		    template));
979*12720SWyllys.Ingersoll@Sun.COM 		break;
980*12720SWyllys.Ingersoll@Sun.COM 
981*12720SWyllys.Ingersoll@Sun.COM 	default:
982*12720SWyllys.Ingersoll@Sun.COM 		/*
983*12720SWyllys.Ingersoll@Sun.COM 		 * The specified attribute for the object is invalid.
984*12720SWyllys.Ingersoll@Sun.COM 		 * (the object does not possess such an attribute.)
985*12720SWyllys.Ingersoll@Sun.COM 		 */
986*12720SWyllys.Ingersoll@Sun.COM 		template->ulValueLen = (CK_ULONG)-1;
987*12720SWyllys.Ingersoll@Sun.COM 		return (CKR_ATTRIBUTE_TYPE_INVALID);
988*12720SWyllys.Ingersoll@Sun.COM 	}
989*12720SWyllys.Ingersoll@Sun.COM 
990*12720SWyllys.Ingersoll@Sun.COM 	return (rv);
991*12720SWyllys.Ingersoll@Sun.COM }
992*12720SWyllys.Ingersoll@Sun.COM 
993*12720SWyllys.Ingersoll@Sun.COM /*
994*12720SWyllys.Ingersoll@Sun.COM  * Get the value of a requested attribute that is common to all key objects
995*12720SWyllys.Ingersoll@Sun.COM  * (i.e. public key, private key and secret key).
996*12720SWyllys.Ingersoll@Sun.COM  */
997*12720SWyllys.Ingersoll@Sun.COM CK_RV
kms_get_common_key_attrs(kms_object_t * object_p,CK_ATTRIBUTE_PTR template)998*12720SWyllys.Ingersoll@Sun.COM kms_get_common_key_attrs(kms_object_t *object_p,
999*12720SWyllys.Ingersoll@Sun.COM     CK_ATTRIBUTE_PTR template)
1000*12720SWyllys.Ingersoll@Sun.COM {
1001*12720SWyllys.Ingersoll@Sun.COM 
1002*12720SWyllys.Ingersoll@Sun.COM 	switch (template->type) {
1003*12720SWyllys.Ingersoll@Sun.COM 
1004*12720SWyllys.Ingersoll@Sun.COM 	case CKA_KEY_TYPE:
1005*12720SWyllys.Ingersoll@Sun.COM 		return (get_ulong_attr_from_object(object_p->key_type,
1006*12720SWyllys.Ingersoll@Sun.COM 		    template));
1007*12720SWyllys.Ingersoll@Sun.COM 
1008*12720SWyllys.Ingersoll@Sun.COM 	case CKA_ID:
1009*12720SWyllys.Ingersoll@Sun.COM 	case CKA_START_DATE:
1010*12720SWyllys.Ingersoll@Sun.COM 	case CKA_END_DATE:
1011*12720SWyllys.Ingersoll@Sun.COM 		/*
1012*12720SWyllys.Ingersoll@Sun.COM 		 * The above extra attributes have byte array type.
1013*12720SWyllys.Ingersoll@Sun.COM 		 */
1014*12720SWyllys.Ingersoll@Sun.COM 		return (get_extra_attr_from_object(object_p,
1015*12720SWyllys.Ingersoll@Sun.COM 		    template));
1016*12720SWyllys.Ingersoll@Sun.COM 
1017*12720SWyllys.Ingersoll@Sun.COM 	/* Key related boolean attributes */
1018*12720SWyllys.Ingersoll@Sun.COM 	case CKA_LOCAL:
1019*12720SWyllys.Ingersoll@Sun.COM 		return (get_bool_attr_from_object(object_p,
1020*12720SWyllys.Ingersoll@Sun.COM 		    LOCAL_BOOL_ON, template));
1021*12720SWyllys.Ingersoll@Sun.COM 
1022*12720SWyllys.Ingersoll@Sun.COM 	case CKA_DERIVE:
1023*12720SWyllys.Ingersoll@Sun.COM 		return (get_bool_attr_from_object(object_p,
1024*12720SWyllys.Ingersoll@Sun.COM 		    DERIVE_BOOL_ON, template));
1025*12720SWyllys.Ingersoll@Sun.COM 
1026*12720SWyllys.Ingersoll@Sun.COM 	case CKA_KEY_GEN_MECHANISM:
1027*12720SWyllys.Ingersoll@Sun.COM 		return (get_ulong_attr_from_object(object_p->mechanism,
1028*12720SWyllys.Ingersoll@Sun.COM 		    template));
1029*12720SWyllys.Ingersoll@Sun.COM 
1030*12720SWyllys.Ingersoll@Sun.COM 	default:
1031*12720SWyllys.Ingersoll@Sun.COM 		return (CKR_ATTRIBUTE_TYPE_INVALID);
1032*12720SWyllys.Ingersoll@Sun.COM 	}
1033*12720SWyllys.Ingersoll@Sun.COM }
1034*12720SWyllys.Ingersoll@Sun.COM 
1035*12720SWyllys.Ingersoll@Sun.COM /*
1036*12720SWyllys.Ingersoll@Sun.COM  * Get the value of a requested attribute of a Secret Key Object.
1037*12720SWyllys.Ingersoll@Sun.COM  *
1038*12720SWyllys.Ingersoll@Sun.COM  * Rule: All the attributes in the secret key object can be revealed
1039*12720SWyllys.Ingersoll@Sun.COM  *       except those marked with footnote number "7" when the object
1040*12720SWyllys.Ingersoll@Sun.COM  *       has its CKA_SENSITIVE attribute set to TRUE or its
1041*12720SWyllys.Ingersoll@Sun.COM  *       CKA_EXTRACTABLE attribute set to FALSE.
1042*12720SWyllys.Ingersoll@Sun.COM  */
1043*12720SWyllys.Ingersoll@Sun.COM CK_RV
kms_get_secret_key_attribute(kms_object_t * object_p,CK_ATTRIBUTE_PTR template)1044*12720SWyllys.Ingersoll@Sun.COM kms_get_secret_key_attribute(kms_object_t *object_p,
1045*12720SWyllys.Ingersoll@Sun.COM     CK_ATTRIBUTE_PTR template)
1046*12720SWyllys.Ingersoll@Sun.COM {
1047*12720SWyllys.Ingersoll@Sun.COM 
1048*12720SWyllys.Ingersoll@Sun.COM 	CK_RV		rv = CKR_OK;
1049*12720SWyllys.Ingersoll@Sun.COM 	CK_KEY_TYPE	keytype = object_p->key_type;
1050*12720SWyllys.Ingersoll@Sun.COM 
1051*12720SWyllys.Ingersoll@Sun.COM 	switch (template->type) {
1052*12720SWyllys.Ingersoll@Sun.COM 
1053*12720SWyllys.Ingersoll@Sun.COM 	/* Key related boolean attributes */
1054*12720SWyllys.Ingersoll@Sun.COM 	case CKA_SENSITIVE:
1055*12720SWyllys.Ingersoll@Sun.COM 		return (get_bool_attr_from_object(object_p,
1056*12720SWyllys.Ingersoll@Sun.COM 		    SENSITIVE_BOOL_ON, template));
1057*12720SWyllys.Ingersoll@Sun.COM 
1058*12720SWyllys.Ingersoll@Sun.COM 	case CKA_ENCRYPT:
1059*12720SWyllys.Ingersoll@Sun.COM 		return (get_bool_attr_from_object(object_p,
1060*12720SWyllys.Ingersoll@Sun.COM 		    ENCRYPT_BOOL_ON, template));
1061*12720SWyllys.Ingersoll@Sun.COM 
1062*12720SWyllys.Ingersoll@Sun.COM 	case CKA_DECRYPT:
1063*12720SWyllys.Ingersoll@Sun.COM 		return (get_bool_attr_from_object(object_p,
1064*12720SWyllys.Ingersoll@Sun.COM 		    DECRYPT_BOOL_ON, template));
1065*12720SWyllys.Ingersoll@Sun.COM 
1066*12720SWyllys.Ingersoll@Sun.COM 	case CKA_SIGN:
1067*12720SWyllys.Ingersoll@Sun.COM 		return (get_bool_attr_from_object(object_p,
1068*12720SWyllys.Ingersoll@Sun.COM 		    SIGN_BOOL_ON, template));
1069*12720SWyllys.Ingersoll@Sun.COM 
1070*12720SWyllys.Ingersoll@Sun.COM 	case CKA_VERIFY:
1071*12720SWyllys.Ingersoll@Sun.COM 		return (get_bool_attr_from_object(object_p,
1072*12720SWyllys.Ingersoll@Sun.COM 		    VERIFY_BOOL_ON, template));
1073*12720SWyllys.Ingersoll@Sun.COM 
1074*12720SWyllys.Ingersoll@Sun.COM 	case CKA_WRAP:
1075*12720SWyllys.Ingersoll@Sun.COM 		return (get_bool_attr_from_object(object_p,
1076*12720SWyllys.Ingersoll@Sun.COM 		    WRAP_BOOL_ON, template));
1077*12720SWyllys.Ingersoll@Sun.COM 
1078*12720SWyllys.Ingersoll@Sun.COM 	case CKA_UNWRAP:
1079*12720SWyllys.Ingersoll@Sun.COM 		return (get_bool_attr_from_object(object_p,
1080*12720SWyllys.Ingersoll@Sun.COM 		    UNWRAP_BOOL_ON, template));
1081*12720SWyllys.Ingersoll@Sun.COM 
1082*12720SWyllys.Ingersoll@Sun.COM 	case CKA_EXTRACTABLE:
1083*12720SWyllys.Ingersoll@Sun.COM 		return (get_bool_attr_from_object(object_p,
1084*12720SWyllys.Ingersoll@Sun.COM 		    EXTRACTABLE_BOOL_ON, template));
1085*12720SWyllys.Ingersoll@Sun.COM 
1086*12720SWyllys.Ingersoll@Sun.COM 	case CKA_ALWAYS_SENSITIVE:
1087*12720SWyllys.Ingersoll@Sun.COM 		return (get_bool_attr_from_object(object_p,
1088*12720SWyllys.Ingersoll@Sun.COM 		    ALWAYS_SENSITIVE_BOOL_ON, template));
1089*12720SWyllys.Ingersoll@Sun.COM 
1090*12720SWyllys.Ingersoll@Sun.COM 	case CKA_NEVER_EXTRACTABLE:
1091*12720SWyllys.Ingersoll@Sun.COM 		return (get_bool_attr_from_object(object_p,
1092*12720SWyllys.Ingersoll@Sun.COM 		    NEVER_EXTRACTABLE_BOOL_ON, template));
1093*12720SWyllys.Ingersoll@Sun.COM 
1094*12720SWyllys.Ingersoll@Sun.COM 	case CKA_VALUE:
1095*12720SWyllys.Ingersoll@Sun.COM 		/*
1096*12720SWyllys.Ingersoll@Sun.COM 		 * If the specified attribute for the secret key object
1097*12720SWyllys.Ingersoll@Sun.COM 		 * cannot be revealed because the object is sensitive
1098*12720SWyllys.Ingersoll@Sun.COM 		 * or unextractable, then the ulValueLen is set to -1.
1099*12720SWyllys.Ingersoll@Sun.COM 		 */
1100*12720SWyllys.Ingersoll@Sun.COM 		if ((object_p->bool_attr_mask & SENSITIVE_BOOL_ON) ||
1101*12720SWyllys.Ingersoll@Sun.COM 		    !(object_p->bool_attr_mask & EXTRACTABLE_BOOL_ON)) {
1102*12720SWyllys.Ingersoll@Sun.COM 			template->ulValueLen = (CK_ULONG)-1;
1103*12720SWyllys.Ingersoll@Sun.COM 			return (CKR_ATTRIBUTE_SENSITIVE);
1104*12720SWyllys.Ingersoll@Sun.COM 		}
1105*12720SWyllys.Ingersoll@Sun.COM 
1106*12720SWyllys.Ingersoll@Sun.COM 		switch (keytype) {
1107*12720SWyllys.Ingersoll@Sun.COM 		case CKK_AES:
1108*12720SWyllys.Ingersoll@Sun.COM 			/*
1109*12720SWyllys.Ingersoll@Sun.COM 			 * Copy secret key object attributes to template.
1110*12720SWyllys.Ingersoll@Sun.COM 			 */
1111*12720SWyllys.Ingersoll@Sun.COM 			if (template->pValue == NULL) {
1112*12720SWyllys.Ingersoll@Sun.COM 				template->ulValueLen =
1113*12720SWyllys.Ingersoll@Sun.COM 				    OBJ_SEC_VALUE_LEN(object_p);
1114*12720SWyllys.Ingersoll@Sun.COM 				return (CKR_OK);
1115*12720SWyllys.Ingersoll@Sun.COM 			}
1116*12720SWyllys.Ingersoll@Sun.COM 
1117*12720SWyllys.Ingersoll@Sun.COM 			if (OBJ_SEC_VALUE(object_p) == NULL) {
1118*12720SWyllys.Ingersoll@Sun.COM 				template->ulValueLen = 0;
1119*12720SWyllys.Ingersoll@Sun.COM 				return (CKR_OK);
1120*12720SWyllys.Ingersoll@Sun.COM 			}
1121*12720SWyllys.Ingersoll@Sun.COM 
1122*12720SWyllys.Ingersoll@Sun.COM 			if (template->ulValueLen >=
1123*12720SWyllys.Ingersoll@Sun.COM 			    OBJ_SEC_VALUE_LEN(object_p)) {
1124*12720SWyllys.Ingersoll@Sun.COM 				(void) memcpy(template->pValue,
1125*12720SWyllys.Ingersoll@Sun.COM 				    OBJ_SEC_VALUE(object_p),
1126*12720SWyllys.Ingersoll@Sun.COM 				    OBJ_SEC_VALUE_LEN(object_p));
1127*12720SWyllys.Ingersoll@Sun.COM 				template->ulValueLen =
1128*12720SWyllys.Ingersoll@Sun.COM 				    OBJ_SEC_VALUE_LEN(object_p);
1129*12720SWyllys.Ingersoll@Sun.COM 				return (CKR_OK);
1130*12720SWyllys.Ingersoll@Sun.COM 			} else {
1131*12720SWyllys.Ingersoll@Sun.COM 				template->ulValueLen = (CK_ULONG)-1;
1132*12720SWyllys.Ingersoll@Sun.COM 				return (CKR_BUFFER_TOO_SMALL);
1133*12720SWyllys.Ingersoll@Sun.COM 			}
1134*12720SWyllys.Ingersoll@Sun.COM 
1135*12720SWyllys.Ingersoll@Sun.COM 		case CKK_RC4:
1136*12720SWyllys.Ingersoll@Sun.COM 		case CKK_GENERIC_SECRET:
1137*12720SWyllys.Ingersoll@Sun.COM 		case CKK_RC5:
1138*12720SWyllys.Ingersoll@Sun.COM 		case CKK_DES:
1139*12720SWyllys.Ingersoll@Sun.COM 		case CKK_DES2:
1140*12720SWyllys.Ingersoll@Sun.COM 		case CKK_DES3:
1141*12720SWyllys.Ingersoll@Sun.COM 		case CKK_CDMF:
1142*12720SWyllys.Ingersoll@Sun.COM 		case CKK_BLOWFISH:
1143*12720SWyllys.Ingersoll@Sun.COM 		default:
1144*12720SWyllys.Ingersoll@Sun.COM 			template->ulValueLen = (CK_ULONG)-1;
1145*12720SWyllys.Ingersoll@Sun.COM 			rv = CKR_ATTRIBUTE_TYPE_INVALID;
1146*12720SWyllys.Ingersoll@Sun.COM 			break;
1147*12720SWyllys.Ingersoll@Sun.COM 		}
1148*12720SWyllys.Ingersoll@Sun.COM 		break;
1149*12720SWyllys.Ingersoll@Sun.COM 
1150*12720SWyllys.Ingersoll@Sun.COM 	case CKA_VALUE_LEN:
1151*12720SWyllys.Ingersoll@Sun.COM 		return (get_ulong_attr_from_object(OBJ_SEC_VALUE_LEN(object_p),
1152*12720SWyllys.Ingersoll@Sun.COM 		    template));
1153*12720SWyllys.Ingersoll@Sun.COM 
1154*12720SWyllys.Ingersoll@Sun.COM 	default:
1155*12720SWyllys.Ingersoll@Sun.COM 		/*
1156*12720SWyllys.Ingersoll@Sun.COM 		 * First, get the value of the request attribute defined
1157*12720SWyllys.Ingersoll@Sun.COM 		 * in the list of common key attributes. If the request
1158*12720SWyllys.Ingersoll@Sun.COM 		 * attribute is not found in that list, then get the
1159*12720SWyllys.Ingersoll@Sun.COM 		 * attribute from the list of common attributes.
1160*12720SWyllys.Ingersoll@Sun.COM 		 */
1161*12720SWyllys.Ingersoll@Sun.COM 		rv = kms_get_common_key_attrs(object_p, template);
1162*12720SWyllys.Ingersoll@Sun.COM 		if (rv == CKR_ATTRIBUTE_TYPE_INVALID) {
1163*12720SWyllys.Ingersoll@Sun.COM 			rv = kms_get_common_attrs(object_p, template);
1164*12720SWyllys.Ingersoll@Sun.COM 		}
1165*12720SWyllys.Ingersoll@Sun.COM 		break;
1166*12720SWyllys.Ingersoll@Sun.COM 	}
1167*12720SWyllys.Ingersoll@Sun.COM 
1168*12720SWyllys.Ingersoll@Sun.COM 	return (rv);
1169*12720SWyllys.Ingersoll@Sun.COM 
1170*12720SWyllys.Ingersoll@Sun.COM }
1171*12720SWyllys.Ingersoll@Sun.COM 
1172*12720SWyllys.Ingersoll@Sun.COM /*
1173*12720SWyllys.Ingersoll@Sun.COM  * Call the appropriate get attribute function according to the class
1174*12720SWyllys.Ingersoll@Sun.COM  * of object.
1175*12720SWyllys.Ingersoll@Sun.COM  *
1176*12720SWyllys.Ingersoll@Sun.COM  * The caller of this function holds the lock on the object.
1177*12720SWyllys.Ingersoll@Sun.COM  */
1178*12720SWyllys.Ingersoll@Sun.COM CK_RV
kms_get_attribute(kms_object_t * object_p,CK_ATTRIBUTE_PTR template)1179*12720SWyllys.Ingersoll@Sun.COM kms_get_attribute(kms_object_t *object_p, CK_ATTRIBUTE_PTR template)
1180*12720SWyllys.Ingersoll@Sun.COM {
1181*12720SWyllys.Ingersoll@Sun.COM 
1182*12720SWyllys.Ingersoll@Sun.COM 	CK_RV		rv = CKR_OK;
1183*12720SWyllys.Ingersoll@Sun.COM 	CK_OBJECT_CLASS class = object_p->class;
1184*12720SWyllys.Ingersoll@Sun.COM 
1185*12720SWyllys.Ingersoll@Sun.COM 	switch (class) {
1186*12720SWyllys.Ingersoll@Sun.COM 	case CKO_SECRET_KEY:
1187*12720SWyllys.Ingersoll@Sun.COM 		rv = kms_get_secret_key_attribute(object_p, template);
1188*12720SWyllys.Ingersoll@Sun.COM 		break;
1189*12720SWyllys.Ingersoll@Sun.COM 
1190*12720SWyllys.Ingersoll@Sun.COM 	case CKO_PRIVATE_KEY:
1191*12720SWyllys.Ingersoll@Sun.COM 	case CKO_PUBLIC_KEY:
1192*12720SWyllys.Ingersoll@Sun.COM 	default:
1193*12720SWyllys.Ingersoll@Sun.COM 		/*
1194*12720SWyllys.Ingersoll@Sun.COM 		 * If the specified attribute for the object is invalid
1195*12720SWyllys.Ingersoll@Sun.COM 		 * (the object does not possess such as attribute), then
1196*12720SWyllys.Ingersoll@Sun.COM 		 * the ulValueLen is modified to hold the value -1.
1197*12720SWyllys.Ingersoll@Sun.COM 		 */
1198*12720SWyllys.Ingersoll@Sun.COM 		template->ulValueLen = (CK_ULONG)-1;
1199*12720SWyllys.Ingersoll@Sun.COM 		return (CKR_ATTRIBUTE_TYPE_INVALID);
1200*12720SWyllys.Ingersoll@Sun.COM 	}
1201*12720SWyllys.Ingersoll@Sun.COM 
1202*12720SWyllys.Ingersoll@Sun.COM 	return (rv);
1203*12720SWyllys.Ingersoll@Sun.COM 
1204*12720SWyllys.Ingersoll@Sun.COM }
1205*12720SWyllys.Ingersoll@Sun.COM 
1206*12720SWyllys.Ingersoll@Sun.COM /*
1207*12720SWyllys.Ingersoll@Sun.COM  * Set the value of an attribute that is common to all key objects
1208*12720SWyllys.Ingersoll@Sun.COM  * (i.e. public key, private key and secret key).
1209*12720SWyllys.Ingersoll@Sun.COM  */
1210*12720SWyllys.Ingersoll@Sun.COM static CK_RV
kms_set_common_key_attribute(kms_object_t * object_p,CK_ATTRIBUTE_PTR template,boolean_t copy)1211*12720SWyllys.Ingersoll@Sun.COM kms_set_common_key_attribute(kms_object_t *object_p,
1212*12720SWyllys.Ingersoll@Sun.COM     CK_ATTRIBUTE_PTR template, boolean_t copy)
1213*12720SWyllys.Ingersoll@Sun.COM {
1214*12720SWyllys.Ingersoll@Sun.COM 
1215*12720SWyllys.Ingersoll@Sun.COM 	kms_slot_t *pslot = get_slotinfo();
1216*12720SWyllys.Ingersoll@Sun.COM 	CK_RV rv = CKR_OK;
1217*12720SWyllys.Ingersoll@Sun.COM 
1218*12720SWyllys.Ingersoll@Sun.COM 	switch (template->type) {
1219*12720SWyllys.Ingersoll@Sun.COM 
1220*12720SWyllys.Ingersoll@Sun.COM 	case CKA_LABEL:
1221*12720SWyllys.Ingersoll@Sun.COM 		/*
1222*12720SWyllys.Ingersoll@Sun.COM 		 * Only the LABEL can be modified in the common storage
1223*12720SWyllys.Ingersoll@Sun.COM 		 * object attributes after the object is created.
1224*12720SWyllys.Ingersoll@Sun.COM 		 */
1225*12720SWyllys.Ingersoll@Sun.COM 		return (set_extra_attr_to_object(object_p,
1226*12720SWyllys.Ingersoll@Sun.COM 		    CKA_LABEL, template));
1227*12720SWyllys.Ingersoll@Sun.COM 
1228*12720SWyllys.Ingersoll@Sun.COM 	case CKA_ID:
1229*12720SWyllys.Ingersoll@Sun.COM 		return (set_extra_attr_to_object(object_p,
1230*12720SWyllys.Ingersoll@Sun.COM 		    CKA_ID, template));
1231*12720SWyllys.Ingersoll@Sun.COM 
1232*12720SWyllys.Ingersoll@Sun.COM 	case CKA_START_DATE:
1233*12720SWyllys.Ingersoll@Sun.COM 		return (set_extra_attr_to_object(object_p,
1234*12720SWyllys.Ingersoll@Sun.COM 		    CKA_START_DATE, template));
1235*12720SWyllys.Ingersoll@Sun.COM 
1236*12720SWyllys.Ingersoll@Sun.COM 	case CKA_END_DATE:
1237*12720SWyllys.Ingersoll@Sun.COM 		return (set_extra_attr_to_object(object_p,
1238*12720SWyllys.Ingersoll@Sun.COM 		    CKA_END_DATE, template));
1239*12720SWyllys.Ingersoll@Sun.COM 
1240*12720SWyllys.Ingersoll@Sun.COM 	case CKA_DERIVE:
1241*12720SWyllys.Ingersoll@Sun.COM 		return (set_bool_attr_to_object(object_p,
1242*12720SWyllys.Ingersoll@Sun.COM 		    DERIVE_BOOL_ON, template));
1243*12720SWyllys.Ingersoll@Sun.COM 
1244*12720SWyllys.Ingersoll@Sun.COM 	case CKA_CLASS:
1245*12720SWyllys.Ingersoll@Sun.COM 	case CKA_KEY_TYPE:
1246*12720SWyllys.Ingersoll@Sun.COM 	case CKA_LOCAL:
1247*12720SWyllys.Ingersoll@Sun.COM 		return (CKR_ATTRIBUTE_READ_ONLY);
1248*12720SWyllys.Ingersoll@Sun.COM 
1249*12720SWyllys.Ingersoll@Sun.COM 	case CKA_PRIVATE:
1250*12720SWyllys.Ingersoll@Sun.COM 		if (!copy) {
1251*12720SWyllys.Ingersoll@Sun.COM 			/* called from C_SetAttributeValue() */
1252*12720SWyllys.Ingersoll@Sun.COM 			return (CKR_ATTRIBUTE_READ_ONLY);
1253*12720SWyllys.Ingersoll@Sun.COM 		}
1254*12720SWyllys.Ingersoll@Sun.COM 
1255*12720SWyllys.Ingersoll@Sun.COM 		/* called from C_CopyObject() */
1256*12720SWyllys.Ingersoll@Sun.COM 		if ((*(CK_BBOOL *)template->pValue) != B_TRUE) {
1257*12720SWyllys.Ingersoll@Sun.COM 			return (CKR_OK);
1258*12720SWyllys.Ingersoll@Sun.COM 		}
1259*12720SWyllys.Ingersoll@Sun.COM 
1260*12720SWyllys.Ingersoll@Sun.COM 		(void) pthread_mutex_lock(&pslot->sl_mutex);
1261*12720SWyllys.Ingersoll@Sun.COM 		/*
1262*12720SWyllys.Ingersoll@Sun.COM 		 * Cannot create a private object if the token
1263*12720SWyllys.Ingersoll@Sun.COM 		 * has a keystore and the user isn't logged in.
1264*12720SWyllys.Ingersoll@Sun.COM 		 */
1265*12720SWyllys.Ingersoll@Sun.COM 		if (pslot->sl_state != CKU_USER) {
1266*12720SWyllys.Ingersoll@Sun.COM 			rv = CKR_USER_NOT_LOGGED_IN;
1267*12720SWyllys.Ingersoll@Sun.COM 		} else {
1268*12720SWyllys.Ingersoll@Sun.COM 			rv = set_bool_attr_to_object(object_p,
1269*12720SWyllys.Ingersoll@Sun.COM 			    PRIVATE_BOOL_ON, template);
1270*12720SWyllys.Ingersoll@Sun.COM 		}
1271*12720SWyllys.Ingersoll@Sun.COM 		(void) pthread_mutex_unlock(&pslot->sl_mutex);
1272*12720SWyllys.Ingersoll@Sun.COM 		return (rv);
1273*12720SWyllys.Ingersoll@Sun.COM 
1274*12720SWyllys.Ingersoll@Sun.COM 	case CKA_MODIFIABLE:
1275*12720SWyllys.Ingersoll@Sun.COM 		if (copy) {
1276*12720SWyllys.Ingersoll@Sun.COM 			rv = set_bool_attr_to_object(object_p,
1277*12720SWyllys.Ingersoll@Sun.COM 			    MODIFIABLE_BOOL_ON, template);
1278*12720SWyllys.Ingersoll@Sun.COM 		} else {
1279*12720SWyllys.Ingersoll@Sun.COM 			rv = CKR_ATTRIBUTE_READ_ONLY;
1280*12720SWyllys.Ingersoll@Sun.COM 		}
1281*12720SWyllys.Ingersoll@Sun.COM 		return (rv);
1282*12720SWyllys.Ingersoll@Sun.COM 
1283*12720SWyllys.Ingersoll@Sun.COM 	default:
1284*12720SWyllys.Ingersoll@Sun.COM 		return (CKR_TEMPLATE_INCONSISTENT);
1285*12720SWyllys.Ingersoll@Sun.COM 	}
1286*12720SWyllys.Ingersoll@Sun.COM 
1287*12720SWyllys.Ingersoll@Sun.COM }
1288*12720SWyllys.Ingersoll@Sun.COM 
1289*12720SWyllys.Ingersoll@Sun.COM /*
1290*12720SWyllys.Ingersoll@Sun.COM  * Set the value of an attribute of a Secret Key Object.
1291*12720SWyllys.Ingersoll@Sun.COM  *
1292*12720SWyllys.Ingersoll@Sun.COM  * Rule: The attributes marked with footnote number "8" in the PKCS11
1293*12720SWyllys.Ingersoll@Sun.COM  *       spec may be modified (p.88 in PKCS11 spec.).
1294*12720SWyllys.Ingersoll@Sun.COM  */
1295*12720SWyllys.Ingersoll@Sun.COM static CK_RV
kms_set_secret_key_attribute(kms_object_t * object_p,CK_ATTRIBUTE_PTR template,boolean_t copy)1296*12720SWyllys.Ingersoll@Sun.COM kms_set_secret_key_attribute(kms_object_t *object_p,
1297*12720SWyllys.Ingersoll@Sun.COM     CK_ATTRIBUTE_PTR template, boolean_t copy)
1298*12720SWyllys.Ingersoll@Sun.COM {
1299*12720SWyllys.Ingersoll@Sun.COM 	CK_KEY_TYPE	keytype = object_p->key_type;
1300*12720SWyllys.Ingersoll@Sun.COM 
1301*12720SWyllys.Ingersoll@Sun.COM 	switch (template->type) {
1302*12720SWyllys.Ingersoll@Sun.COM 
1303*12720SWyllys.Ingersoll@Sun.COM 	case CKA_SENSITIVE:
1304*12720SWyllys.Ingersoll@Sun.COM 		/*
1305*12720SWyllys.Ingersoll@Sun.COM 		 * Cannot set SENSITIVE to FALSE if it is already ON.
1306*12720SWyllys.Ingersoll@Sun.COM 		 */
1307*12720SWyllys.Ingersoll@Sun.COM 		if (((*(CK_BBOOL *)template->pValue) == B_FALSE) &&
1308*12720SWyllys.Ingersoll@Sun.COM 		    (object_p->bool_attr_mask & SENSITIVE_BOOL_ON)) {
1309*12720SWyllys.Ingersoll@Sun.COM 			return (CKR_ATTRIBUTE_READ_ONLY);
1310*12720SWyllys.Ingersoll@Sun.COM 		}
1311*12720SWyllys.Ingersoll@Sun.COM 
1312*12720SWyllys.Ingersoll@Sun.COM 		if (*(CK_BBOOL *)template->pValue)
1313*12720SWyllys.Ingersoll@Sun.COM 			object_p->bool_attr_mask |= SENSITIVE_BOOL_ON;
1314*12720SWyllys.Ingersoll@Sun.COM 		return (CKR_OK);
1315*12720SWyllys.Ingersoll@Sun.COM 
1316*12720SWyllys.Ingersoll@Sun.COM 	case CKA_ENCRYPT:
1317*12720SWyllys.Ingersoll@Sun.COM 		return (set_bool_attr_to_object(object_p,
1318*12720SWyllys.Ingersoll@Sun.COM 		    ENCRYPT_BOOL_ON, template));
1319*12720SWyllys.Ingersoll@Sun.COM 
1320*12720SWyllys.Ingersoll@Sun.COM 	case CKA_DECRYPT:
1321*12720SWyllys.Ingersoll@Sun.COM 		return (set_bool_attr_to_object(object_p,
1322*12720SWyllys.Ingersoll@Sun.COM 		    DECRYPT_BOOL_ON, template));
1323*12720SWyllys.Ingersoll@Sun.COM 
1324*12720SWyllys.Ingersoll@Sun.COM 	case CKA_SIGN:
1325*12720SWyllys.Ingersoll@Sun.COM 		return (set_bool_attr_to_object(object_p,
1326*12720SWyllys.Ingersoll@Sun.COM 		    SIGN_BOOL_ON, template));
1327*12720SWyllys.Ingersoll@Sun.COM 
1328*12720SWyllys.Ingersoll@Sun.COM 	case CKA_VERIFY:
1329*12720SWyllys.Ingersoll@Sun.COM 		return (set_bool_attr_to_object(object_p,
1330*12720SWyllys.Ingersoll@Sun.COM 		    VERIFY_BOOL_ON, template));
1331*12720SWyllys.Ingersoll@Sun.COM 
1332*12720SWyllys.Ingersoll@Sun.COM 	case CKA_WRAP:
1333*12720SWyllys.Ingersoll@Sun.COM 		return (set_bool_attr_to_object(object_p,
1334*12720SWyllys.Ingersoll@Sun.COM 		    WRAP_BOOL_ON, template));
1335*12720SWyllys.Ingersoll@Sun.COM 
1336*12720SWyllys.Ingersoll@Sun.COM 	case CKA_UNWRAP:
1337*12720SWyllys.Ingersoll@Sun.COM 		return (set_bool_attr_to_object(object_p,
1338*12720SWyllys.Ingersoll@Sun.COM 		    UNWRAP_BOOL_ON, template));
1339*12720SWyllys.Ingersoll@Sun.COM 
1340*12720SWyllys.Ingersoll@Sun.COM 	case CKA_EXTRACTABLE:
1341*12720SWyllys.Ingersoll@Sun.COM 		/*
1342*12720SWyllys.Ingersoll@Sun.COM 		 * Cannot set EXTRACTABLE to TRUE if it is already OFF.
1343*12720SWyllys.Ingersoll@Sun.COM 		 */
1344*12720SWyllys.Ingersoll@Sun.COM 		if ((*(CK_BBOOL *)template->pValue) &&
1345*12720SWyllys.Ingersoll@Sun.COM 		    !(object_p->bool_attr_mask & EXTRACTABLE_BOOL_ON)) {
1346*12720SWyllys.Ingersoll@Sun.COM 			return (CKR_ATTRIBUTE_READ_ONLY);
1347*12720SWyllys.Ingersoll@Sun.COM 		}
1348*12720SWyllys.Ingersoll@Sun.COM 
1349*12720SWyllys.Ingersoll@Sun.COM 		if ((*(CK_BBOOL *)template->pValue) == B_FALSE)
1350*12720SWyllys.Ingersoll@Sun.COM 			object_p->bool_attr_mask &= ~EXTRACTABLE_BOOL_ON;
1351*12720SWyllys.Ingersoll@Sun.COM 		return (CKR_OK);
1352*12720SWyllys.Ingersoll@Sun.COM 
1353*12720SWyllys.Ingersoll@Sun.COM 	case CKA_VALUE:
1354*12720SWyllys.Ingersoll@Sun.COM 		return (CKR_ATTRIBUTE_READ_ONLY);
1355*12720SWyllys.Ingersoll@Sun.COM 
1356*12720SWyllys.Ingersoll@Sun.COM 	case CKA_VALUE_LEN:
1357*12720SWyllys.Ingersoll@Sun.COM 		if ((keytype == CKK_RC4) ||
1358*12720SWyllys.Ingersoll@Sun.COM 		    (keytype == CKK_GENERIC_SECRET) ||
1359*12720SWyllys.Ingersoll@Sun.COM 		    (keytype == CKK_AES) ||
1360*12720SWyllys.Ingersoll@Sun.COM 		    (keytype == CKK_BLOWFISH))
1361*12720SWyllys.Ingersoll@Sun.COM 			return (CKR_ATTRIBUTE_READ_ONLY);
1362*12720SWyllys.Ingersoll@Sun.COM 		break;
1363*12720SWyllys.Ingersoll@Sun.COM 
1364*12720SWyllys.Ingersoll@Sun.COM 	default:
1365*12720SWyllys.Ingersoll@Sun.COM 		/*
1366*12720SWyllys.Ingersoll@Sun.COM 		 * Set the value of a common key attribute.
1367*12720SWyllys.Ingersoll@Sun.COM 		 */
1368*12720SWyllys.Ingersoll@Sun.COM 		return (kms_set_common_key_attribute(object_p,
1369*12720SWyllys.Ingersoll@Sun.COM 		    template, copy));
1370*12720SWyllys.Ingersoll@Sun.COM 	}
1371*12720SWyllys.Ingersoll@Sun.COM 
1372*12720SWyllys.Ingersoll@Sun.COM 	/*
1373*12720SWyllys.Ingersoll@Sun.COM 	 * If we got this far, then the combination of key type
1374*12720SWyllys.Ingersoll@Sun.COM 	 * and requested attribute is invalid.
1375*12720SWyllys.Ingersoll@Sun.COM 	 */
1376*12720SWyllys.Ingersoll@Sun.COM 	return (CKR_ATTRIBUTE_TYPE_INVALID);
1377*12720SWyllys.Ingersoll@Sun.COM }
1378*12720SWyllys.Ingersoll@Sun.COM 
1379*12720SWyllys.Ingersoll@Sun.COM /*
1380*12720SWyllys.Ingersoll@Sun.COM  * Call the appropriate set attribute function according to the class
1381*12720SWyllys.Ingersoll@Sun.COM  * of object.
1382*12720SWyllys.Ingersoll@Sun.COM  *
1383*12720SWyllys.Ingersoll@Sun.COM  * The caller of this function does not hold the lock on the original
1384*12720SWyllys.Ingersoll@Sun.COM  * object, since this function is setting the attribute on the new object
1385*12720SWyllys.Ingersoll@Sun.COM  * that is being modified.
1386*12720SWyllys.Ingersoll@Sun.COM  *
1387*12720SWyllys.Ingersoll@Sun.COM  */
1388*12720SWyllys.Ingersoll@Sun.COM CK_RV
kms_set_attribute(kms_object_t * object_p,CK_ATTRIBUTE_PTR template,boolean_t copy)1389*12720SWyllys.Ingersoll@Sun.COM kms_set_attribute(kms_object_t *object_p, CK_ATTRIBUTE_PTR template,
1390*12720SWyllys.Ingersoll@Sun.COM     boolean_t copy)
1391*12720SWyllys.Ingersoll@Sun.COM {
1392*12720SWyllys.Ingersoll@Sun.COM 
1393*12720SWyllys.Ingersoll@Sun.COM 	CK_RV		rv = CKR_OK;
1394*12720SWyllys.Ingersoll@Sun.COM 	CK_OBJECT_CLASS	class = object_p->class;
1395*12720SWyllys.Ingersoll@Sun.COM 
1396*12720SWyllys.Ingersoll@Sun.COM 	switch (class) {
1397*12720SWyllys.Ingersoll@Sun.COM 
1398*12720SWyllys.Ingersoll@Sun.COM 	case CKO_SECRET_KEY:
1399*12720SWyllys.Ingersoll@Sun.COM 		rv = kms_set_secret_key_attribute(object_p, template,
1400*12720SWyllys.Ingersoll@Sun.COM 		    copy);
1401*12720SWyllys.Ingersoll@Sun.COM 		break;
1402*12720SWyllys.Ingersoll@Sun.COM 
1403*12720SWyllys.Ingersoll@Sun.COM 	case CKO_PUBLIC_KEY:
1404*12720SWyllys.Ingersoll@Sun.COM 	case CKO_PRIVATE_KEY:
1405*12720SWyllys.Ingersoll@Sun.COM 	default:
1406*12720SWyllys.Ingersoll@Sun.COM 		/*
1407*12720SWyllys.Ingersoll@Sun.COM 		 * If the template specifies a value of an attribute
1408*12720SWyllys.Ingersoll@Sun.COM 		 * which is incompatible with other existing attributes
1409*12720SWyllys.Ingersoll@Sun.COM 		 * of the object, then fails with return code
1410*12720SWyllys.Ingersoll@Sun.COM 		 * CKR_TEMPLATE_INCONSISTENT.
1411*12720SWyllys.Ingersoll@Sun.COM 		 */
1412*12720SWyllys.Ingersoll@Sun.COM 		rv = CKR_TEMPLATE_INCONSISTENT;
1413*12720SWyllys.Ingersoll@Sun.COM 		break;
1414*12720SWyllys.Ingersoll@Sun.COM 	}
1415*12720SWyllys.Ingersoll@Sun.COM 
1416*12720SWyllys.Ingersoll@Sun.COM 	return (rv);
1417*12720SWyllys.Ingersoll@Sun.COM }
1418*12720SWyllys.Ingersoll@Sun.COM 
1419*12720SWyllys.Ingersoll@Sun.COM CK_RV
kms_copy_secret_key_attr(secret_key_obj_t * old_secret_key_obj_p,secret_key_obj_t ** new_secret_key_obj_p)1420*12720SWyllys.Ingersoll@Sun.COM kms_copy_secret_key_attr(secret_key_obj_t *old_secret_key_obj_p,
1421*12720SWyllys.Ingersoll@Sun.COM     secret_key_obj_t **new_secret_key_obj_p)
1422*12720SWyllys.Ingersoll@Sun.COM {
1423*12720SWyllys.Ingersoll@Sun.COM 	secret_key_obj_t *sk;
1424*12720SWyllys.Ingersoll@Sun.COM 
1425*12720SWyllys.Ingersoll@Sun.COM 	sk = malloc(sizeof (secret_key_obj_t));
1426*12720SWyllys.Ingersoll@Sun.COM 	if (sk == NULL) {
1427*12720SWyllys.Ingersoll@Sun.COM 		return (CKR_HOST_MEMORY);
1428*12720SWyllys.Ingersoll@Sun.COM 	}
1429*12720SWyllys.Ingersoll@Sun.COM 	(void) memcpy(sk, old_secret_key_obj_p, sizeof (secret_key_obj_t));
1430*12720SWyllys.Ingersoll@Sun.COM 
1431*12720SWyllys.Ingersoll@Sun.COM 	/* copy the secret key value */
1432*12720SWyllys.Ingersoll@Sun.COM 	sk->sk_value = malloc((sizeof (CK_BYTE) * sk->sk_value_len));
1433*12720SWyllys.Ingersoll@Sun.COM 	if (sk->sk_value == NULL) {
1434*12720SWyllys.Ingersoll@Sun.COM 		free(sk);
1435*12720SWyllys.Ingersoll@Sun.COM 		return (CKR_HOST_MEMORY);
1436*12720SWyllys.Ingersoll@Sun.COM 	}
1437*12720SWyllys.Ingersoll@Sun.COM 	(void) memcpy(sk->sk_value, old_secret_key_obj_p->sk_value,
1438*12720SWyllys.Ingersoll@Sun.COM 	    (sizeof (CK_BYTE) * sk->sk_value_len));
1439*12720SWyllys.Ingersoll@Sun.COM 
1440*12720SWyllys.Ingersoll@Sun.COM 	*new_secret_key_obj_p = sk;
1441*12720SWyllys.Ingersoll@Sun.COM 
1442*12720SWyllys.Ingersoll@Sun.COM 	return (CKR_OK);
1443*12720SWyllys.Ingersoll@Sun.COM }
1444*12720SWyllys.Ingersoll@Sun.COM 
1445*12720SWyllys.Ingersoll@Sun.COM 
1446*12720SWyllys.Ingersoll@Sun.COM 
1447*12720SWyllys.Ingersoll@Sun.COM /*
1448*12720SWyllys.Ingersoll@Sun.COM  * If CKA_CLASS not given, guess CKA_CLASS using
1449*12720SWyllys.Ingersoll@Sun.COM  * attributes on template.
1450*12720SWyllys.Ingersoll@Sun.COM  *
1451*12720SWyllys.Ingersoll@Sun.COM  * Some attributes are specific to an object class.  If one or more
1452*12720SWyllys.Ingersoll@Sun.COM  * of these attributes are in the template, make a list of classes
1453*12720SWyllys.Ingersoll@Sun.COM  * that can have these attributes.  This would speed up the search later,
1454*12720SWyllys.Ingersoll@Sun.COM  * because we can immediately skip an object if the class of that
1455*12720SWyllys.Ingersoll@Sun.COM  * object can not possibly contain one of the attributes.
1456*12720SWyllys.Ingersoll@Sun.COM  *
1457*12720SWyllys.Ingersoll@Sun.COM  */
1458*12720SWyllys.Ingersoll@Sun.COM void
kms_process_find_attr(CK_OBJECT_CLASS * pclasses,CK_ULONG * num_result_pclasses,CK_ATTRIBUTE_PTR pTemplate,CK_ULONG ulCount)1459*12720SWyllys.Ingersoll@Sun.COM kms_process_find_attr(CK_OBJECT_CLASS *pclasses,
1460*12720SWyllys.Ingersoll@Sun.COM     CK_ULONG *num_result_pclasses, CK_ATTRIBUTE_PTR pTemplate,
1461*12720SWyllys.Ingersoll@Sun.COM     CK_ULONG ulCount)
1462*12720SWyllys.Ingersoll@Sun.COM {
1463*12720SWyllys.Ingersoll@Sun.COM 	ulong_t i;
1464*12720SWyllys.Ingersoll@Sun.COM 	int j;
1465*12720SWyllys.Ingersoll@Sun.COM 	boolean_t secret_found = B_FALSE;
1466*12720SWyllys.Ingersoll@Sun.COM 	int num_secret_key_attrs;
1467*12720SWyllys.Ingersoll@Sun.COM 	int num_pclasses = 0;
1468*12720SWyllys.Ingersoll@Sun.COM 
1469*12720SWyllys.Ingersoll@Sun.COM 	for (i = 0; i < ulCount; i++) {
1470*12720SWyllys.Ingersoll@Sun.COM 		if (pTemplate[i].type == CKA_CLASS) {
1471*12720SWyllys.Ingersoll@Sun.COM 			/*
1472*12720SWyllys.Ingersoll@Sun.COM 			 * don't need to guess the class, it is specified.
1473*12720SWyllys.Ingersoll@Sun.COM 			 * Just record the class, and return.
1474*12720SWyllys.Ingersoll@Sun.COM 			 */
1475*12720SWyllys.Ingersoll@Sun.COM 			pclasses[0] =
1476*12720SWyllys.Ingersoll@Sun.COM 			    (*((CK_OBJECT_CLASS *)pTemplate[i].pValue));
1477*12720SWyllys.Ingersoll@Sun.COM 			*num_result_pclasses = 1;
1478*12720SWyllys.Ingersoll@Sun.COM 			return;
1479*12720SWyllys.Ingersoll@Sun.COM 		}
1480*12720SWyllys.Ingersoll@Sun.COM 	}
1481*12720SWyllys.Ingersoll@Sun.COM 
1482*12720SWyllys.Ingersoll@Sun.COM 	num_secret_key_attrs =
1483*12720SWyllys.Ingersoll@Sun.COM 	    sizeof (SECRET_KEY_ATTRS) / sizeof (CK_ATTRIBUTE_TYPE);
1484*12720SWyllys.Ingersoll@Sun.COM 
1485*12720SWyllys.Ingersoll@Sun.COM 	/*
1486*12720SWyllys.Ingersoll@Sun.COM 	 * Get the list of objects class that might contain
1487*12720SWyllys.Ingersoll@Sun.COM 	 * some attributes.
1488*12720SWyllys.Ingersoll@Sun.COM 	 */
1489*12720SWyllys.Ingersoll@Sun.COM 	for (i = 0; i < ulCount; i++) {
1490*12720SWyllys.Ingersoll@Sun.COM 		if (!secret_found) {
1491*12720SWyllys.Ingersoll@Sun.COM 			for (j = 0; j < num_secret_key_attrs; j++) {
1492*12720SWyllys.Ingersoll@Sun.COM 				if (pTemplate[i].type == SECRET_KEY_ATTRS[j]) {
1493*12720SWyllys.Ingersoll@Sun.COM 					secret_found = B_TRUE;
1494*12720SWyllys.Ingersoll@Sun.COM 					pclasses[num_pclasses++] =
1495*12720SWyllys.Ingersoll@Sun.COM 					    CKO_SECRET_KEY;
1496*12720SWyllys.Ingersoll@Sun.COM 					break;
1497*12720SWyllys.Ingersoll@Sun.COM 				}
1498*12720SWyllys.Ingersoll@Sun.COM 			}
1499*12720SWyllys.Ingersoll@Sun.COM 		}
1500*12720SWyllys.Ingersoll@Sun.COM 	}
1501*12720SWyllys.Ingersoll@Sun.COM 	*num_result_pclasses = num_pclasses;
1502*12720SWyllys.Ingersoll@Sun.COM }
1503*12720SWyllys.Ingersoll@Sun.COM 
1504*12720SWyllys.Ingersoll@Sun.COM 
1505*12720SWyllys.Ingersoll@Sun.COM boolean_t
kms_find_match_attrs(kms_object_t * obj,CK_OBJECT_CLASS * pclasses,CK_ULONG num_pclasses,CK_ATTRIBUTE * template,CK_ULONG num_attr)1506*12720SWyllys.Ingersoll@Sun.COM kms_find_match_attrs(kms_object_t *obj, CK_OBJECT_CLASS *pclasses,
1507*12720SWyllys.Ingersoll@Sun.COM     CK_ULONG num_pclasses, CK_ATTRIBUTE *template, CK_ULONG num_attr)
1508*12720SWyllys.Ingersoll@Sun.COM {
1509*12720SWyllys.Ingersoll@Sun.COM 	ulong_t i;
1510*12720SWyllys.Ingersoll@Sun.COM 	CK_ATTRIBUTE *tmpl_attr, *obj_attr;
1511*12720SWyllys.Ingersoll@Sun.COM 	uint64_t attr_mask;
1512*12720SWyllys.Ingersoll@Sun.COM 	boolean_t compare_attr, compare_boolean;
1513*12720SWyllys.Ingersoll@Sun.COM 
1514*12720SWyllys.Ingersoll@Sun.COM 	/*
1515*12720SWyllys.Ingersoll@Sun.COM 	 * Check if the class of this object match with any
1516*12720SWyllys.Ingersoll@Sun.COM 	 * of object classes that can possibly contain the
1517*12720SWyllys.Ingersoll@Sun.COM 	 * requested attributes.
1518*12720SWyllys.Ingersoll@Sun.COM 	 */
1519*12720SWyllys.Ingersoll@Sun.COM 	if (num_pclasses > 0) {
1520*12720SWyllys.Ingersoll@Sun.COM 		for (i = 0; i < num_pclasses; i++) {
1521*12720SWyllys.Ingersoll@Sun.COM 			if (obj->class == pclasses[i]) {
1522*12720SWyllys.Ingersoll@Sun.COM 				break;
1523*12720SWyllys.Ingersoll@Sun.COM 			}
1524*12720SWyllys.Ingersoll@Sun.COM 		}
1525*12720SWyllys.Ingersoll@Sun.COM 		if (i == num_pclasses) {
1526*12720SWyllys.Ingersoll@Sun.COM 			/*
1527*12720SWyllys.Ingersoll@Sun.COM 			 * this object can't possibly contain one or
1528*12720SWyllys.Ingersoll@Sun.COM 			 * more attributes, don't need to check this object
1529*12720SWyllys.Ingersoll@Sun.COM 			 */
1530*12720SWyllys.Ingersoll@Sun.COM 			return (B_FALSE);
1531*12720SWyllys.Ingersoll@Sun.COM 		}
1532*12720SWyllys.Ingersoll@Sun.COM 	}
1533*12720SWyllys.Ingersoll@Sun.COM 
1534*12720SWyllys.Ingersoll@Sun.COM 	/* need to examine everything */
1535*12720SWyllys.Ingersoll@Sun.COM 	for (i = 0; i < num_attr; i++) {
1536*12720SWyllys.Ingersoll@Sun.COM 		tmpl_attr = &(template[i]);
1537*12720SWyllys.Ingersoll@Sun.COM 		compare_attr = B_FALSE;
1538*12720SWyllys.Ingersoll@Sun.COM 		compare_boolean = B_FALSE;
1539*12720SWyllys.Ingersoll@Sun.COM 		switch (tmpl_attr->type) {
1540*12720SWyllys.Ingersoll@Sun.COM 		/* First, check the most common attributes */
1541*12720SWyllys.Ingersoll@Sun.COM 		case CKA_CLASS:
1542*12720SWyllys.Ingersoll@Sun.COM 			if (*((CK_OBJECT_CLASS *)tmpl_attr->pValue) !=
1543*12720SWyllys.Ingersoll@Sun.COM 			    obj->class) {
1544*12720SWyllys.Ingersoll@Sun.COM 				return (B_FALSE);
1545*12720SWyllys.Ingersoll@Sun.COM 			}
1546*12720SWyllys.Ingersoll@Sun.COM 			break;
1547*12720SWyllys.Ingersoll@Sun.COM 		case CKA_KEY_TYPE:
1548*12720SWyllys.Ingersoll@Sun.COM 			if (*((CK_KEY_TYPE *)tmpl_attr->pValue) !=
1549*12720SWyllys.Ingersoll@Sun.COM 			    obj->key_type) {
1550*12720SWyllys.Ingersoll@Sun.COM 				return (B_FALSE);
1551*12720SWyllys.Ingersoll@Sun.COM 			}
1552*12720SWyllys.Ingersoll@Sun.COM 			break;
1553*12720SWyllys.Ingersoll@Sun.COM 		case CKA_ENCRYPT:
1554*12720SWyllys.Ingersoll@Sun.COM 			attr_mask = (obj->bool_attr_mask) & ENCRYPT_BOOL_ON;
1555*12720SWyllys.Ingersoll@Sun.COM 			compare_boolean = B_TRUE;
1556*12720SWyllys.Ingersoll@Sun.COM 			break;
1557*12720SWyllys.Ingersoll@Sun.COM 		case CKA_DECRYPT:
1558*12720SWyllys.Ingersoll@Sun.COM 			attr_mask = (obj->bool_attr_mask) & DECRYPT_BOOL_ON;
1559*12720SWyllys.Ingersoll@Sun.COM 			compare_boolean = B_TRUE;
1560*12720SWyllys.Ingersoll@Sun.COM 			break;
1561*12720SWyllys.Ingersoll@Sun.COM 		case CKA_WRAP:
1562*12720SWyllys.Ingersoll@Sun.COM 			attr_mask = (obj->bool_attr_mask) & WRAP_BOOL_ON;
1563*12720SWyllys.Ingersoll@Sun.COM 			compare_boolean = B_TRUE;
1564*12720SWyllys.Ingersoll@Sun.COM 			break;
1565*12720SWyllys.Ingersoll@Sun.COM 		case CKA_UNWRAP:
1566*12720SWyllys.Ingersoll@Sun.COM 			attr_mask = (obj->bool_attr_mask) & UNWRAP_BOOL_ON;
1567*12720SWyllys.Ingersoll@Sun.COM 			compare_boolean = B_TRUE;
1568*12720SWyllys.Ingersoll@Sun.COM 			break;
1569*12720SWyllys.Ingersoll@Sun.COM 		case CKA_SIGN:
1570*12720SWyllys.Ingersoll@Sun.COM 			attr_mask = (obj->bool_attr_mask) & SIGN_BOOL_ON;
1571*12720SWyllys.Ingersoll@Sun.COM 			compare_boolean = B_TRUE;
1572*12720SWyllys.Ingersoll@Sun.COM 			break;
1573*12720SWyllys.Ingersoll@Sun.COM 		case CKA_SIGN_RECOVER:
1574*12720SWyllys.Ingersoll@Sun.COM 			attr_mask = (obj->bool_attr_mask) &
1575*12720SWyllys.Ingersoll@Sun.COM 			    SIGN_RECOVER_BOOL_ON;
1576*12720SWyllys.Ingersoll@Sun.COM 			compare_boolean = B_TRUE;
1577*12720SWyllys.Ingersoll@Sun.COM 			break;
1578*12720SWyllys.Ingersoll@Sun.COM 		case CKA_VERIFY:
1579*12720SWyllys.Ingersoll@Sun.COM 			attr_mask = (obj->bool_attr_mask) & VERIFY_BOOL_ON;
1580*12720SWyllys.Ingersoll@Sun.COM 			compare_boolean = B_TRUE;
1581*12720SWyllys.Ingersoll@Sun.COM 			break;
1582*12720SWyllys.Ingersoll@Sun.COM 		case CKA_VERIFY_RECOVER:
1583*12720SWyllys.Ingersoll@Sun.COM 			attr_mask = (obj->bool_attr_mask) &
1584*12720SWyllys.Ingersoll@Sun.COM 			    VERIFY_RECOVER_BOOL_ON;
1585*12720SWyllys.Ingersoll@Sun.COM 			compare_boolean = B_TRUE;
1586*12720SWyllys.Ingersoll@Sun.COM 			break;
1587*12720SWyllys.Ingersoll@Sun.COM 		case CKA_DERIVE:
1588*12720SWyllys.Ingersoll@Sun.COM 			attr_mask = (obj->bool_attr_mask) & DERIVE_BOOL_ON;
1589*12720SWyllys.Ingersoll@Sun.COM 			compare_boolean = B_TRUE;
1590*12720SWyllys.Ingersoll@Sun.COM 			break;
1591*12720SWyllys.Ingersoll@Sun.COM 		case CKA_LOCAL:
1592*12720SWyllys.Ingersoll@Sun.COM 			attr_mask = (obj->bool_attr_mask) & LOCAL_BOOL_ON;
1593*12720SWyllys.Ingersoll@Sun.COM 			compare_boolean = B_TRUE;
1594*12720SWyllys.Ingersoll@Sun.COM 			break;
1595*12720SWyllys.Ingersoll@Sun.COM 		case CKA_SENSITIVE:
1596*12720SWyllys.Ingersoll@Sun.COM 			attr_mask = (obj->bool_attr_mask) & SENSITIVE_BOOL_ON;
1597*12720SWyllys.Ingersoll@Sun.COM 			compare_boolean = B_TRUE;
1598*12720SWyllys.Ingersoll@Sun.COM 			break;
1599*12720SWyllys.Ingersoll@Sun.COM 		case CKA_SECONDARY_AUTH:
1600*12720SWyllys.Ingersoll@Sun.COM 			attr_mask = (obj->bool_attr_mask) &
1601*12720SWyllys.Ingersoll@Sun.COM 			    SECONDARY_AUTH_BOOL_ON;
1602*12720SWyllys.Ingersoll@Sun.COM 			compare_boolean = B_TRUE;
1603*12720SWyllys.Ingersoll@Sun.COM 			break;
1604*12720SWyllys.Ingersoll@Sun.COM 		case CKA_TRUSTED:
1605*12720SWyllys.Ingersoll@Sun.COM 			attr_mask = (obj->bool_attr_mask) & TRUSTED_BOOL_ON;
1606*12720SWyllys.Ingersoll@Sun.COM 			compare_boolean = B_TRUE;
1607*12720SWyllys.Ingersoll@Sun.COM 			break;
1608*12720SWyllys.Ingersoll@Sun.COM 		case CKA_EXTRACTABLE:
1609*12720SWyllys.Ingersoll@Sun.COM 			attr_mask = (obj->bool_attr_mask) &
1610*12720SWyllys.Ingersoll@Sun.COM 			    EXTRACTABLE_BOOL_ON;
1611*12720SWyllys.Ingersoll@Sun.COM 			compare_boolean = B_TRUE;
1612*12720SWyllys.Ingersoll@Sun.COM 			break;
1613*12720SWyllys.Ingersoll@Sun.COM 		case CKA_ALWAYS_SENSITIVE:
1614*12720SWyllys.Ingersoll@Sun.COM 			attr_mask = (obj->bool_attr_mask) &
1615*12720SWyllys.Ingersoll@Sun.COM 			    ALWAYS_SENSITIVE_BOOL_ON;
1616*12720SWyllys.Ingersoll@Sun.COM 			compare_boolean = B_TRUE;
1617*12720SWyllys.Ingersoll@Sun.COM 			break;
1618*12720SWyllys.Ingersoll@Sun.COM 		case CKA_NEVER_EXTRACTABLE:
1619*12720SWyllys.Ingersoll@Sun.COM 			attr_mask = (obj->bool_attr_mask) &
1620*12720SWyllys.Ingersoll@Sun.COM 			    NEVER_EXTRACTABLE_BOOL_ON;
1621*12720SWyllys.Ingersoll@Sun.COM 			compare_boolean = B_TRUE;
1622*12720SWyllys.Ingersoll@Sun.COM 			break;
1623*12720SWyllys.Ingersoll@Sun.COM 		case CKA_TOKEN:
1624*12720SWyllys.Ingersoll@Sun.COM 			attr_mask = (obj->bool_attr_mask) & TOKEN_BOOL_ON;
1625*12720SWyllys.Ingersoll@Sun.COM 			compare_boolean = B_TRUE;
1626*12720SWyllys.Ingersoll@Sun.COM 			break;
1627*12720SWyllys.Ingersoll@Sun.COM 		case CKA_PRIVATE:
1628*12720SWyllys.Ingersoll@Sun.COM 			attr_mask = (obj->bool_attr_mask) & PRIVATE_BOOL_ON;
1629*12720SWyllys.Ingersoll@Sun.COM 			compare_boolean = B_TRUE;
1630*12720SWyllys.Ingersoll@Sun.COM 			break;
1631*12720SWyllys.Ingersoll@Sun.COM 		case CKA_MODIFIABLE:
1632*12720SWyllys.Ingersoll@Sun.COM 			attr_mask = (obj->bool_attr_mask) & MODIFIABLE_BOOL_ON;
1633*12720SWyllys.Ingersoll@Sun.COM 			compare_boolean = B_TRUE;
1634*12720SWyllys.Ingersoll@Sun.COM 			break;
1635*12720SWyllys.Ingersoll@Sun.COM 		case CKA_SUBJECT:
1636*12720SWyllys.Ingersoll@Sun.COM 		case CKA_ID:
1637*12720SWyllys.Ingersoll@Sun.COM 		case CKA_START_DATE:
1638*12720SWyllys.Ingersoll@Sun.COM 		case CKA_END_DATE:
1639*12720SWyllys.Ingersoll@Sun.COM 		case CKA_KEY_GEN_MECHANISM:
1640*12720SWyllys.Ingersoll@Sun.COM 		case CKA_LABEL:
1641*12720SWyllys.Ingersoll@Sun.COM 			/* find these attributes from extra_attrlistp */
1642*12720SWyllys.Ingersoll@Sun.COM 			obj_attr = get_extra_attr(tmpl_attr->type, obj);
1643*12720SWyllys.Ingersoll@Sun.COM 			compare_attr = B_TRUE;
1644*12720SWyllys.Ingersoll@Sun.COM 			break;
1645*12720SWyllys.Ingersoll@Sun.COM 		case CKA_VALUE_LEN:
1646*12720SWyllys.Ingersoll@Sun.COM 			/* only secret key has this attribute */
1647*12720SWyllys.Ingersoll@Sun.COM 			if (obj->class == CKO_SECRET_KEY) {
1648*12720SWyllys.Ingersoll@Sun.COM 				if (*((CK_ULONG *)tmpl_attr->pValue) !=
1649*12720SWyllys.Ingersoll@Sun.COM 				    OBJ_SEC_VALUE_LEN(obj)) {
1650*12720SWyllys.Ingersoll@Sun.COM 					return (B_FALSE);
1651*12720SWyllys.Ingersoll@Sun.COM 				}
1652*12720SWyllys.Ingersoll@Sun.COM 			} else {
1653*12720SWyllys.Ingersoll@Sun.COM 				return (B_FALSE);
1654*12720SWyllys.Ingersoll@Sun.COM 			}
1655*12720SWyllys.Ingersoll@Sun.COM 			break;
1656*12720SWyllys.Ingersoll@Sun.COM 		case CKA_VALUE:
1657*12720SWyllys.Ingersoll@Sun.COM 			switch (obj->class) {
1658*12720SWyllys.Ingersoll@Sun.COM 			case CKO_SECRET_KEY:
1659*12720SWyllys.Ingersoll@Sun.COM 				break;
1660*12720SWyllys.Ingersoll@Sun.COM 			default:
1661*12720SWyllys.Ingersoll@Sun.COM 				return (B_FALSE);
1662*12720SWyllys.Ingersoll@Sun.COM 			}
1663*12720SWyllys.Ingersoll@Sun.COM 			break;
1664*12720SWyllys.Ingersoll@Sun.COM 		case CKA_VALUE_BITS:
1665*12720SWyllys.Ingersoll@Sun.COM 		case CKA_PRIME_BITS:
1666*12720SWyllys.Ingersoll@Sun.COM 		case CKA_SUBPRIME_BITS:
1667*12720SWyllys.Ingersoll@Sun.COM 		default:
1668*12720SWyllys.Ingersoll@Sun.COM 			/*
1669*12720SWyllys.Ingersoll@Sun.COM 			 * any other attributes are currently not supported.
1670*12720SWyllys.Ingersoll@Sun.COM 			 * so, it's not possible for them to be in the
1671*12720SWyllys.Ingersoll@Sun.COM 			 * object
1672*12720SWyllys.Ingersoll@Sun.COM 			 */
1673*12720SWyllys.Ingersoll@Sun.COM 			return (B_FALSE);
1674*12720SWyllys.Ingersoll@Sun.COM 		}
1675*12720SWyllys.Ingersoll@Sun.COM 		if (compare_boolean) {
1676*12720SWyllys.Ingersoll@Sun.COM 			CK_BBOOL bval;
1677*12720SWyllys.Ingersoll@Sun.COM 
1678*12720SWyllys.Ingersoll@Sun.COM 			if (attr_mask) {
1679*12720SWyllys.Ingersoll@Sun.COM 				bval = TRUE;
1680*12720SWyllys.Ingersoll@Sun.COM 			} else {
1681*12720SWyllys.Ingersoll@Sun.COM 				bval = FALSE;
1682*12720SWyllys.Ingersoll@Sun.COM 			}
1683*12720SWyllys.Ingersoll@Sun.COM 			if (bval != *((CK_BBOOL *)tmpl_attr->pValue)) {
1684*12720SWyllys.Ingersoll@Sun.COM 				return (B_FALSE);
1685*12720SWyllys.Ingersoll@Sun.COM 			}
1686*12720SWyllys.Ingersoll@Sun.COM 		} else if (compare_attr) {
1687*12720SWyllys.Ingersoll@Sun.COM 			if (obj_attr == NULL) {
1688*12720SWyllys.Ingersoll@Sun.COM 				/*
1689*12720SWyllys.Ingersoll@Sun.COM 				 * The attribute type is valid, and its value
1690*12720SWyllys.Ingersoll@Sun.COM 				 * has not been initialized in the object. In
1691*12720SWyllys.Ingersoll@Sun.COM 				 * this case, it only matches the template's
1692*12720SWyllys.Ingersoll@Sun.COM 				 * attribute if the template's value length
1693*12720SWyllys.Ingersoll@Sun.COM 				 * is 0.
1694*12720SWyllys.Ingersoll@Sun.COM 				 */
1695*12720SWyllys.Ingersoll@Sun.COM 				if (tmpl_attr->ulValueLen != 0)
1696*12720SWyllys.Ingersoll@Sun.COM 					return (B_FALSE);
1697*12720SWyllys.Ingersoll@Sun.COM 			} else {
1698*12720SWyllys.Ingersoll@Sun.COM 				if (tmpl_attr->ulValueLen !=
1699*12720SWyllys.Ingersoll@Sun.COM 				    obj_attr->ulValueLen) {
1700*12720SWyllys.Ingersoll@Sun.COM 					return (B_FALSE);
1701*12720SWyllys.Ingersoll@Sun.COM 				}
1702*12720SWyllys.Ingersoll@Sun.COM 				if (memcmp(tmpl_attr->pValue, obj_attr->pValue,
1703*12720SWyllys.Ingersoll@Sun.COM 				    tmpl_attr->ulValueLen) != 0) {
1704*12720SWyllys.Ingersoll@Sun.COM 					return (B_FALSE);
1705*12720SWyllys.Ingersoll@Sun.COM 				}
1706*12720SWyllys.Ingersoll@Sun.COM 			}
1707*12720SWyllys.Ingersoll@Sun.COM 		}
1708*12720SWyllys.Ingersoll@Sun.COM 	}
1709*12720SWyllys.Ingersoll@Sun.COM 	return (B_TRUE);
1710*12720SWyllys.Ingersoll@Sun.COM }
1711*12720SWyllys.Ingersoll@Sun.COM 
1712*12720SWyllys.Ingersoll@Sun.COM CK_ATTRIBUTE_PTR
get_extra_attr(CK_ATTRIBUTE_TYPE type,kms_object_t * obj)1713*12720SWyllys.Ingersoll@Sun.COM get_extra_attr(CK_ATTRIBUTE_TYPE type, kms_object_t *obj)
1714*12720SWyllys.Ingersoll@Sun.COM {
1715*12720SWyllys.Ingersoll@Sun.COM 	CK_ATTRIBUTE_INFO_PTR tmp;
1716*12720SWyllys.Ingersoll@Sun.COM 
1717*12720SWyllys.Ingersoll@Sun.COM 	tmp = obj->extra_attrlistp;
1718*12720SWyllys.Ingersoll@Sun.COM 	while (tmp != NULL) {
1719*12720SWyllys.Ingersoll@Sun.COM 		if (tmp->attr.type == type) {
1720*12720SWyllys.Ingersoll@Sun.COM 			return (&(tmp->attr));
1721*12720SWyllys.Ingersoll@Sun.COM 		}
1722*12720SWyllys.Ingersoll@Sun.COM 		tmp = tmp->next;
1723*12720SWyllys.Ingersoll@Sun.COM 	}
1724*12720SWyllys.Ingersoll@Sun.COM 	/* if get there, the specified attribute is not found */
1725*12720SWyllys.Ingersoll@Sun.COM 	return (NULL);
1726*12720SWyllys.Ingersoll@Sun.COM }
1727