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