1*9126SWyllys.Ingersoll@Sun.COM /*
2*9126SWyllys.Ingersoll@Sun.COM * The Initial Developer of the Original Code is International
3*9126SWyllys.Ingersoll@Sun.COM * Business Machines Corporation. Portions created by IBM
4*9126SWyllys.Ingersoll@Sun.COM * Corporation are Copyright (C) 2005 International Business
5*9126SWyllys.Ingersoll@Sun.COM * Machines Corporation. All Rights Reserved.
6*9126SWyllys.Ingersoll@Sun.COM *
7*9126SWyllys.Ingersoll@Sun.COM * This program is free software; you can redistribute it and/or modify
8*9126SWyllys.Ingersoll@Sun.COM * it under the terms of the Common Public License as published by
9*9126SWyllys.Ingersoll@Sun.COM * IBM Corporation; either version 1 of the License, or (at your option)
10*9126SWyllys.Ingersoll@Sun.COM * any later version.
11*9126SWyllys.Ingersoll@Sun.COM *
12*9126SWyllys.Ingersoll@Sun.COM * This program is distributed in the hope that it will be useful,
13*9126SWyllys.Ingersoll@Sun.COM * but WITHOUT ANY WARRANTY; without even the implied warranty of
14*9126SWyllys.Ingersoll@Sun.COM * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15*9126SWyllys.Ingersoll@Sun.COM * Common Public License for more details.
16*9126SWyllys.Ingersoll@Sun.COM *
17*9126SWyllys.Ingersoll@Sun.COM * You should have received a copy of the Common Public License
18*9126SWyllys.Ingersoll@Sun.COM * along with this program; if not, a copy can be viewed at
19*9126SWyllys.Ingersoll@Sun.COM * http://www.opensource.org/licenses/cpl1.0.php.
20*9126SWyllys.Ingersoll@Sun.COM */
21*9126SWyllys.Ingersoll@Sun.COM /* (C) COPYRIGHT International Business Machines Corp. 2001, 2002, 2005 */
22*9126SWyllys.Ingersoll@Sun.COM /*
23*9126SWyllys.Ingersoll@Sun.COM * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
24*9126SWyllys.Ingersoll@Sun.COM * Use is subject to license terms.
25*9126SWyllys.Ingersoll@Sun.COM */
26*9126SWyllys.Ingersoll@Sun.COM
27*9126SWyllys.Ingersoll@Sun.COM #include "tpmtok_int.h"
28*9126SWyllys.Ingersoll@Sun.COM
29*9126SWyllys.Ingersoll@Sun.COM static CK_BBOOL true = TRUE, false = FALSE;
30*9126SWyllys.Ingersoll@Sun.COM
31*9126SWyllys.Ingersoll@Sun.COM static CK_RV
key_mgr_get_private_key_type(CK_BYTE * keydata,CK_ULONG keylen,CK_KEY_TYPE * keytype)32*9126SWyllys.Ingersoll@Sun.COM key_mgr_get_private_key_type(
33*9126SWyllys.Ingersoll@Sun.COM CK_BYTE *keydata,
34*9126SWyllys.Ingersoll@Sun.COM CK_ULONG keylen,
35*9126SWyllys.Ingersoll@Sun.COM CK_KEY_TYPE *keytype)
36*9126SWyllys.Ingersoll@Sun.COM {
37*9126SWyllys.Ingersoll@Sun.COM CK_BYTE *alg = NULL;
38*9126SWyllys.Ingersoll@Sun.COM CK_BYTE *priv_key = NULL;
39*9126SWyllys.Ingersoll@Sun.COM CK_ULONG alg_len;
40*9126SWyllys.Ingersoll@Sun.COM CK_RV rc;
41*9126SWyllys.Ingersoll@Sun.COM
42*9126SWyllys.Ingersoll@Sun.COM rc = ber_decode_PrivateKeyInfo(keydata, keylen, &alg,
43*9126SWyllys.Ingersoll@Sun.COM &alg_len, &priv_key);
44*9126SWyllys.Ingersoll@Sun.COM if (rc != CKR_OK) {
45*9126SWyllys.Ingersoll@Sun.COM return (rc);
46*9126SWyllys.Ingersoll@Sun.COM }
47*9126SWyllys.Ingersoll@Sun.COM if (alg_len >= ber_rsaEncryptionLen) {
48*9126SWyllys.Ingersoll@Sun.COM if (memcmp(alg, ber_rsaEncryption,
49*9126SWyllys.Ingersoll@Sun.COM ber_rsaEncryptionLen) == 0) {
50*9126SWyllys.Ingersoll@Sun.COM *keytype = CKK_RSA;
51*9126SWyllys.Ingersoll@Sun.COM return (CKR_OK);
52*9126SWyllys.Ingersoll@Sun.COM }
53*9126SWyllys.Ingersoll@Sun.COM }
54*9126SWyllys.Ingersoll@Sun.COM
55*9126SWyllys.Ingersoll@Sun.COM return (CKR_TEMPLATE_INCOMPLETE);
56*9126SWyllys.Ingersoll@Sun.COM }
57*9126SWyllys.Ingersoll@Sun.COM
58*9126SWyllys.Ingersoll@Sun.COM CK_RV
key_mgr_generate_key_pair(SESSION * sess,CK_MECHANISM * mech,CK_ATTRIBUTE * publ_tmpl,CK_ULONG publ_count,CK_ATTRIBUTE * priv_tmpl,CK_ULONG priv_count,CK_OBJECT_HANDLE * publ_key_handle,CK_OBJECT_HANDLE * priv_key_handle)59*9126SWyllys.Ingersoll@Sun.COM key_mgr_generate_key_pair(SESSION * sess,
60*9126SWyllys.Ingersoll@Sun.COM CK_MECHANISM * mech,
61*9126SWyllys.Ingersoll@Sun.COM CK_ATTRIBUTE * publ_tmpl,
62*9126SWyllys.Ingersoll@Sun.COM CK_ULONG publ_count,
63*9126SWyllys.Ingersoll@Sun.COM CK_ATTRIBUTE * priv_tmpl,
64*9126SWyllys.Ingersoll@Sun.COM CK_ULONG priv_count,
65*9126SWyllys.Ingersoll@Sun.COM CK_OBJECT_HANDLE * publ_key_handle,
66*9126SWyllys.Ingersoll@Sun.COM CK_OBJECT_HANDLE * priv_key_handle)
67*9126SWyllys.Ingersoll@Sun.COM {
68*9126SWyllys.Ingersoll@Sun.COM OBJECT * publ_key_obj = NULL;
69*9126SWyllys.Ingersoll@Sun.COM OBJECT * priv_key_obj = NULL;
70*9126SWyllys.Ingersoll@Sun.COM CK_ATTRIBUTE * attr = NULL;
71*9126SWyllys.Ingersoll@Sun.COM CK_ATTRIBUTE * new_attr = NULL;
72*9126SWyllys.Ingersoll@Sun.COM CK_ULONG i, keyclass, subclass = 0;
73*9126SWyllys.Ingersoll@Sun.COM CK_BBOOL flag;
74*9126SWyllys.Ingersoll@Sun.COM CK_RV rc;
75*9126SWyllys.Ingersoll@Sun.COM
76*9126SWyllys.Ingersoll@Sun.COM if (! sess || ! mech || ! publ_key_handle || ! priv_key_handle) {
77*9126SWyllys.Ingersoll@Sun.COM return (CKR_FUNCTION_FAILED);
78*9126SWyllys.Ingersoll@Sun.COM }
79*9126SWyllys.Ingersoll@Sun.COM if (! publ_tmpl && (publ_count != 0)) {
80*9126SWyllys.Ingersoll@Sun.COM return (CKR_FUNCTION_FAILED);
81*9126SWyllys.Ingersoll@Sun.COM }
82*9126SWyllys.Ingersoll@Sun.COM if (! priv_tmpl && (priv_count != 0)) {
83*9126SWyllys.Ingersoll@Sun.COM return (CKR_FUNCTION_FAILED);
84*9126SWyllys.Ingersoll@Sun.COM }
85*9126SWyllys.Ingersoll@Sun.COM
86*9126SWyllys.Ingersoll@Sun.COM for (i = 0; i < publ_count; i++) {
87*9126SWyllys.Ingersoll@Sun.COM if (publ_tmpl[i].type == CKA_CLASS) {
88*9126SWyllys.Ingersoll@Sun.COM keyclass = *(CK_OBJECT_CLASS *)publ_tmpl[i].pValue;
89*9126SWyllys.Ingersoll@Sun.COM if (keyclass != CKO_PUBLIC_KEY) {
90*9126SWyllys.Ingersoll@Sun.COM return (CKR_TEMPLATE_INCONSISTENT);
91*9126SWyllys.Ingersoll@Sun.COM }
92*9126SWyllys.Ingersoll@Sun.COM }
93*9126SWyllys.Ingersoll@Sun.COM
94*9126SWyllys.Ingersoll@Sun.COM if (publ_tmpl[i].type == CKA_KEY_TYPE)
95*9126SWyllys.Ingersoll@Sun.COM subclass = *(CK_ULONG *)publ_tmpl[i].pValue;
96*9126SWyllys.Ingersoll@Sun.COM }
97*9126SWyllys.Ingersoll@Sun.COM
98*9126SWyllys.Ingersoll@Sun.COM
99*9126SWyllys.Ingersoll@Sun.COM for (i = 0; i < priv_count; i++) {
100*9126SWyllys.Ingersoll@Sun.COM if (priv_tmpl[i].type == CKA_CLASS) {
101*9126SWyllys.Ingersoll@Sun.COM keyclass = *(CK_OBJECT_CLASS *)priv_tmpl[i].pValue;
102*9126SWyllys.Ingersoll@Sun.COM if (keyclass != CKO_PRIVATE_KEY) {
103*9126SWyllys.Ingersoll@Sun.COM return (CKR_TEMPLATE_INCONSISTENT);
104*9126SWyllys.Ingersoll@Sun.COM }
105*9126SWyllys.Ingersoll@Sun.COM }
106*9126SWyllys.Ingersoll@Sun.COM
107*9126SWyllys.Ingersoll@Sun.COM if (priv_tmpl[i].type == CKA_KEY_TYPE) {
108*9126SWyllys.Ingersoll@Sun.COM CK_ULONG temp = *(CK_ULONG *)priv_tmpl[i].pValue;
109*9126SWyllys.Ingersoll@Sun.COM if (temp != subclass) {
110*9126SWyllys.Ingersoll@Sun.COM return (CKR_TEMPLATE_INCONSISTENT);
111*9126SWyllys.Ingersoll@Sun.COM }
112*9126SWyllys.Ingersoll@Sun.COM }
113*9126SWyllys.Ingersoll@Sun.COM }
114*9126SWyllys.Ingersoll@Sun.COM
115*9126SWyllys.Ingersoll@Sun.COM
116*9126SWyllys.Ingersoll@Sun.COM switch (mech->mechanism) {
117*9126SWyllys.Ingersoll@Sun.COM case CKM_RSA_PKCS_KEY_PAIR_GEN:
118*9126SWyllys.Ingersoll@Sun.COM if (subclass != 0 && subclass != CKK_RSA) {
119*9126SWyllys.Ingersoll@Sun.COM return (CKR_TEMPLATE_INCONSISTENT);
120*9126SWyllys.Ingersoll@Sun.COM }
121*9126SWyllys.Ingersoll@Sun.COM
122*9126SWyllys.Ingersoll@Sun.COM subclass = CKK_RSA;
123*9126SWyllys.Ingersoll@Sun.COM break;
124*9126SWyllys.Ingersoll@Sun.COM
125*9126SWyllys.Ingersoll@Sun.COM default:
126*9126SWyllys.Ingersoll@Sun.COM return (CKR_MECHANISM_INVALID);
127*9126SWyllys.Ingersoll@Sun.COM }
128*9126SWyllys.Ingersoll@Sun.COM
129*9126SWyllys.Ingersoll@Sun.COM
130*9126SWyllys.Ingersoll@Sun.COM rc = object_mgr_create_skel(sess,
131*9126SWyllys.Ingersoll@Sun.COM publ_tmpl, publ_count, MODE_KEYGEN,
132*9126SWyllys.Ingersoll@Sun.COM CKO_PUBLIC_KEY, subclass, &publ_key_obj);
133*9126SWyllys.Ingersoll@Sun.COM
134*9126SWyllys.Ingersoll@Sun.COM if (rc != CKR_OK) {
135*9126SWyllys.Ingersoll@Sun.COM goto error;
136*9126SWyllys.Ingersoll@Sun.COM }
137*9126SWyllys.Ingersoll@Sun.COM rc = object_mgr_create_skel(sess,
138*9126SWyllys.Ingersoll@Sun.COM priv_tmpl, priv_count, MODE_KEYGEN,
139*9126SWyllys.Ingersoll@Sun.COM CKO_PRIVATE_KEY, subclass, &priv_key_obj);
140*9126SWyllys.Ingersoll@Sun.COM
141*9126SWyllys.Ingersoll@Sun.COM if (rc != CKR_OK) {
142*9126SWyllys.Ingersoll@Sun.COM goto error;
143*9126SWyllys.Ingersoll@Sun.COM }
144*9126SWyllys.Ingersoll@Sun.COM
145*9126SWyllys.Ingersoll@Sun.COM switch (mech->mechanism) {
146*9126SWyllys.Ingersoll@Sun.COM case CKM_RSA_PKCS_KEY_PAIR_GEN:
147*9126SWyllys.Ingersoll@Sun.COM rc = ckm_rsa_key_pair_gen(
148*9126SWyllys.Ingersoll@Sun.COM sess->hContext,
149*9126SWyllys.Ingersoll@Sun.COM publ_key_obj->template,
150*9126SWyllys.Ingersoll@Sun.COM priv_key_obj->template);
151*9126SWyllys.Ingersoll@Sun.COM break;
152*9126SWyllys.Ingersoll@Sun.COM
153*9126SWyllys.Ingersoll@Sun.COM default:
154*9126SWyllys.Ingersoll@Sun.COM rc = CKR_MECHANISM_INVALID;
155*9126SWyllys.Ingersoll@Sun.COM break;
156*9126SWyllys.Ingersoll@Sun.COM }
157*9126SWyllys.Ingersoll@Sun.COM
158*9126SWyllys.Ingersoll@Sun.COM if (rc != CKR_OK) {
159*9126SWyllys.Ingersoll@Sun.COM goto error;
160*9126SWyllys.Ingersoll@Sun.COM }
161*9126SWyllys.Ingersoll@Sun.COM
162*9126SWyllys.Ingersoll@Sun.COM /*
163*9126SWyllys.Ingersoll@Sun.COM * we can now set CKA_ALWAYS_SENSITIVE and CKA_NEVER_EXTRACTABLE
164*9126SWyllys.Ingersoll@Sun.COM * to their appropriate values. this only applies to CKO_SECRET_KEY
165*9126SWyllys.Ingersoll@Sun.COM * and CKO_PRIVATE_KEY objects
166*9126SWyllys.Ingersoll@Sun.COM */
167*9126SWyllys.Ingersoll@Sun.COM flag = template_attribute_find(priv_key_obj->template,
168*9126SWyllys.Ingersoll@Sun.COM CKA_SENSITIVE, &attr);
169*9126SWyllys.Ingersoll@Sun.COM if (flag == TRUE) {
170*9126SWyllys.Ingersoll@Sun.COM flag = *(CK_BBOOL *)attr->pValue;
171*9126SWyllys.Ingersoll@Sun.COM
172*9126SWyllys.Ingersoll@Sun.COM rc = build_attribute(CKA_ALWAYS_SENSITIVE, &flag,
173*9126SWyllys.Ingersoll@Sun.COM sizeof (CK_BBOOL), &new_attr);
174*9126SWyllys.Ingersoll@Sun.COM if (rc != CKR_OK) {
175*9126SWyllys.Ingersoll@Sun.COM goto error;
176*9126SWyllys.Ingersoll@Sun.COM }
177*9126SWyllys.Ingersoll@Sun.COM (void) template_update_attribute(priv_key_obj->template,
178*9126SWyllys.Ingersoll@Sun.COM new_attr);
179*9126SWyllys.Ingersoll@Sun.COM
180*9126SWyllys.Ingersoll@Sun.COM } else {
181*9126SWyllys.Ingersoll@Sun.COM rc = CKR_FUNCTION_FAILED;
182*9126SWyllys.Ingersoll@Sun.COM goto error;
183*9126SWyllys.Ingersoll@Sun.COM }
184*9126SWyllys.Ingersoll@Sun.COM
185*9126SWyllys.Ingersoll@Sun.COM
186*9126SWyllys.Ingersoll@Sun.COM flag = template_attribute_find(priv_key_obj->template,
187*9126SWyllys.Ingersoll@Sun.COM CKA_EXTRACTABLE, &attr);
188*9126SWyllys.Ingersoll@Sun.COM if (flag == TRUE) {
189*9126SWyllys.Ingersoll@Sun.COM flag = *(CK_BBOOL *)attr->pValue;
190*9126SWyllys.Ingersoll@Sun.COM
191*9126SWyllys.Ingersoll@Sun.COM rc = build_attribute(CKA_NEVER_EXTRACTABLE, &true,
192*9126SWyllys.Ingersoll@Sun.COM sizeof (CK_BBOOL), &new_attr);
193*9126SWyllys.Ingersoll@Sun.COM if (rc != CKR_OK) {
194*9126SWyllys.Ingersoll@Sun.COM goto error;
195*9126SWyllys.Ingersoll@Sun.COM }
196*9126SWyllys.Ingersoll@Sun.COM if (flag == TRUE)
197*9126SWyllys.Ingersoll@Sun.COM *(CK_BBOOL *)new_attr->pValue = false;
198*9126SWyllys.Ingersoll@Sun.COM
199*9126SWyllys.Ingersoll@Sun.COM (void) template_update_attribute(priv_key_obj->template,
200*9126SWyllys.Ingersoll@Sun.COM new_attr);
201*9126SWyllys.Ingersoll@Sun.COM
202*9126SWyllys.Ingersoll@Sun.COM } else {
203*9126SWyllys.Ingersoll@Sun.COM rc = CKR_FUNCTION_FAILED;
204*9126SWyllys.Ingersoll@Sun.COM goto error;
205*9126SWyllys.Ingersoll@Sun.COM }
206*9126SWyllys.Ingersoll@Sun.COM
207*9126SWyllys.Ingersoll@Sun.COM rc = object_mgr_create_final(sess, publ_key_obj, publ_key_handle);
208*9126SWyllys.Ingersoll@Sun.COM if (rc != CKR_OK) {
209*9126SWyllys.Ingersoll@Sun.COM goto error;
210*9126SWyllys.Ingersoll@Sun.COM }
211*9126SWyllys.Ingersoll@Sun.COM rc = object_mgr_create_final(sess, priv_key_obj, priv_key_handle);
212*9126SWyllys.Ingersoll@Sun.COM if (rc != CKR_OK) {
213*9126SWyllys.Ingersoll@Sun.COM (void) object_mgr_destroy_object(sess, *publ_key_handle);
214*9126SWyllys.Ingersoll@Sun.COM publ_key_obj = NULL;
215*9126SWyllys.Ingersoll@Sun.COM goto error;
216*9126SWyllys.Ingersoll@Sun.COM }
217*9126SWyllys.Ingersoll@Sun.COM return (rc);
218*9126SWyllys.Ingersoll@Sun.COM
219*9126SWyllys.Ingersoll@Sun.COM error:
220*9126SWyllys.Ingersoll@Sun.COM if (publ_key_obj)
221*9126SWyllys.Ingersoll@Sun.COM (void) object_free(publ_key_obj);
222*9126SWyllys.Ingersoll@Sun.COM if (priv_key_obj)
223*9126SWyllys.Ingersoll@Sun.COM (void) object_free(priv_key_obj);
224*9126SWyllys.Ingersoll@Sun.COM
225*9126SWyllys.Ingersoll@Sun.COM *publ_key_handle = 0;
226*9126SWyllys.Ingersoll@Sun.COM *priv_key_handle = 0;
227*9126SWyllys.Ingersoll@Sun.COM
228*9126SWyllys.Ingersoll@Sun.COM return (rc);
229*9126SWyllys.Ingersoll@Sun.COM }
230*9126SWyllys.Ingersoll@Sun.COM
231*9126SWyllys.Ingersoll@Sun.COM CK_RV
key_mgr_wrap_key(SESSION * sess,CK_BBOOL length_only,CK_MECHANISM * mech,CK_OBJECT_HANDLE h_wrapping_key,CK_OBJECT_HANDLE h_key,CK_BYTE * wrapped_key,CK_ULONG * wrapped_key_len)232*9126SWyllys.Ingersoll@Sun.COM key_mgr_wrap_key(SESSION * sess,
233*9126SWyllys.Ingersoll@Sun.COM CK_BBOOL length_only,
234*9126SWyllys.Ingersoll@Sun.COM CK_MECHANISM * mech,
235*9126SWyllys.Ingersoll@Sun.COM CK_OBJECT_HANDLE h_wrapping_key,
236*9126SWyllys.Ingersoll@Sun.COM CK_OBJECT_HANDLE h_key,
237*9126SWyllys.Ingersoll@Sun.COM CK_BYTE * wrapped_key,
238*9126SWyllys.Ingersoll@Sun.COM CK_ULONG * wrapped_key_len) {
239*9126SWyllys.Ingersoll@Sun.COM ENCR_DECR_CONTEXT * ctx = NULL;
240*9126SWyllys.Ingersoll@Sun.COM OBJECT * key1_obj = NULL;
241*9126SWyllys.Ingersoll@Sun.COM OBJECT * key2_obj = NULL;
242*9126SWyllys.Ingersoll@Sun.COM CK_ATTRIBUTE * attr = NULL;
243*9126SWyllys.Ingersoll@Sun.COM CK_BYTE * data = NULL;
244*9126SWyllys.Ingersoll@Sun.COM CK_ULONG data_len;
245*9126SWyllys.Ingersoll@Sun.COM CK_OBJECT_CLASS class;
246*9126SWyllys.Ingersoll@Sun.COM CK_KEY_TYPE keytype;
247*9126SWyllys.Ingersoll@Sun.COM CK_BBOOL flag;
248*9126SWyllys.Ingersoll@Sun.COM CK_RV rc;
249*9126SWyllys.Ingersoll@Sun.COM
250*9126SWyllys.Ingersoll@Sun.COM if (! sess || ! wrapped_key_len) {
251*9126SWyllys.Ingersoll@Sun.COM return (CKR_FUNCTION_FAILED);
252*9126SWyllys.Ingersoll@Sun.COM }
253*9126SWyllys.Ingersoll@Sun.COM
254*9126SWyllys.Ingersoll@Sun.COM rc = object_mgr_find_in_map1(sess->hContext, h_wrapping_key, &key1_obj);
255*9126SWyllys.Ingersoll@Sun.COM if (rc != CKR_OK) {
256*9126SWyllys.Ingersoll@Sun.COM return (CKR_WRAPPING_KEY_HANDLE_INVALID);
257*9126SWyllys.Ingersoll@Sun.COM }
258*9126SWyllys.Ingersoll@Sun.COM rc = object_mgr_find_in_map1(sess->hContext, h_key, &key2_obj);
259*9126SWyllys.Ingersoll@Sun.COM if (rc != CKR_OK) {
260*9126SWyllys.Ingersoll@Sun.COM return (CKR_KEY_HANDLE_INVALID);
261*9126SWyllys.Ingersoll@Sun.COM }
262*9126SWyllys.Ingersoll@Sun.COM
263*9126SWyllys.Ingersoll@Sun.COM rc = template_attribute_find(key2_obj->template,
264*9126SWyllys.Ingersoll@Sun.COM CKA_EXTRACTABLE, &attr);
265*9126SWyllys.Ingersoll@Sun.COM if (rc == FALSE) {
266*9126SWyllys.Ingersoll@Sun.COM return (CKR_KEY_NOT_WRAPPABLE);
267*9126SWyllys.Ingersoll@Sun.COM } else {
268*9126SWyllys.Ingersoll@Sun.COM flag = *(CK_BBOOL *)attr->pValue;
269*9126SWyllys.Ingersoll@Sun.COM if (flag == FALSE) {
270*9126SWyllys.Ingersoll@Sun.COM return (CKR_KEY_NOT_WRAPPABLE);
271*9126SWyllys.Ingersoll@Sun.COM }
272*9126SWyllys.Ingersoll@Sun.COM }
273*9126SWyllys.Ingersoll@Sun.COM
274*9126SWyllys.Ingersoll@Sun.COM rc = template_attribute_find(key2_obj->template, CKA_CLASS, &attr);
275*9126SWyllys.Ingersoll@Sun.COM if (rc == FALSE) {
276*9126SWyllys.Ingersoll@Sun.COM return (CKR_KEY_NOT_WRAPPABLE);
277*9126SWyllys.Ingersoll@Sun.COM } else
278*9126SWyllys.Ingersoll@Sun.COM class = *(CK_OBJECT_CLASS *)attr->pValue;
279*9126SWyllys.Ingersoll@Sun.COM
280*9126SWyllys.Ingersoll@Sun.COM switch (mech->mechanism) {
281*9126SWyllys.Ingersoll@Sun.COM case CKM_RSA_PKCS:
282*9126SWyllys.Ingersoll@Sun.COM if (class != CKO_SECRET_KEY) {
283*9126SWyllys.Ingersoll@Sun.COM return (CKR_KEY_NOT_WRAPPABLE);
284*9126SWyllys.Ingersoll@Sun.COM }
285*9126SWyllys.Ingersoll@Sun.COM break;
286*9126SWyllys.Ingersoll@Sun.COM
287*9126SWyllys.Ingersoll@Sun.COM default:
288*9126SWyllys.Ingersoll@Sun.COM return (CKR_KEY_NOT_WRAPPABLE);
289*9126SWyllys.Ingersoll@Sun.COM }
290*9126SWyllys.Ingersoll@Sun.COM
291*9126SWyllys.Ingersoll@Sun.COM rc = template_attribute_find(key2_obj->template,
292*9126SWyllys.Ingersoll@Sun.COM CKA_KEY_TYPE, &attr);
293*9126SWyllys.Ingersoll@Sun.COM if (rc == FALSE)
294*9126SWyllys.Ingersoll@Sun.COM return (CKR_KEY_NOT_WRAPPABLE);
295*9126SWyllys.Ingersoll@Sun.COM else
296*9126SWyllys.Ingersoll@Sun.COM keytype = *(CK_KEY_TYPE *)attr->pValue;
297*9126SWyllys.Ingersoll@Sun.COM
298*9126SWyllys.Ingersoll@Sun.COM switch (keytype) {
299*9126SWyllys.Ingersoll@Sun.COM case CKK_RSA:
300*9126SWyllys.Ingersoll@Sun.COM rc = rsa_priv_wrap_get_data(key2_obj->template, length_only,
301*9126SWyllys.Ingersoll@Sun.COM &data, &data_len);
302*9126SWyllys.Ingersoll@Sun.COM if (rc != CKR_OK) {
303*9126SWyllys.Ingersoll@Sun.COM return (rc);
304*9126SWyllys.Ingersoll@Sun.COM }
305*9126SWyllys.Ingersoll@Sun.COM break;
306*9126SWyllys.Ingersoll@Sun.COM
307*9126SWyllys.Ingersoll@Sun.COM case CKK_GENERIC_SECRET:
308*9126SWyllys.Ingersoll@Sun.COM rc = generic_secret_wrap_get_data(key2_obj->template,
309*9126SWyllys.Ingersoll@Sun.COM length_only, &data, &data_len);
310*9126SWyllys.Ingersoll@Sun.COM if (rc != CKR_OK) {
311*9126SWyllys.Ingersoll@Sun.COM return (rc);
312*9126SWyllys.Ingersoll@Sun.COM }
313*9126SWyllys.Ingersoll@Sun.COM break;
314*9126SWyllys.Ingersoll@Sun.COM default:
315*9126SWyllys.Ingersoll@Sun.COM return (CKR_KEY_NOT_WRAPPABLE);
316*9126SWyllys.Ingersoll@Sun.COM }
317*9126SWyllys.Ingersoll@Sun.COM
318*9126SWyllys.Ingersoll@Sun.COM switch (mech->mechanism) {
319*9126SWyllys.Ingersoll@Sun.COM case CKM_RSA_PKCS:
320*9126SWyllys.Ingersoll@Sun.COM break;
321*9126SWyllys.Ingersoll@Sun.COM
322*9126SWyllys.Ingersoll@Sun.COM default:
323*9126SWyllys.Ingersoll@Sun.COM return (CKR_KEY_NOT_WRAPPABLE);
324*9126SWyllys.Ingersoll@Sun.COM }
325*9126SWyllys.Ingersoll@Sun.COM
326*9126SWyllys.Ingersoll@Sun.COM ctx = (ENCR_DECR_CONTEXT *)malloc(sizeof (ENCR_DECR_CONTEXT));
327*9126SWyllys.Ingersoll@Sun.COM if (! ctx) {
328*9126SWyllys.Ingersoll@Sun.COM return (CKR_HOST_MEMORY);
329*9126SWyllys.Ingersoll@Sun.COM }
330*9126SWyllys.Ingersoll@Sun.COM (void) memset(ctx, 0x0, sizeof (ENCR_DECR_CONTEXT));
331*9126SWyllys.Ingersoll@Sun.COM
332*9126SWyllys.Ingersoll@Sun.COM rc = encr_mgr_init(sess, ctx, OP_WRAP, mech, h_wrapping_key);
333*9126SWyllys.Ingersoll@Sun.COM if (rc != CKR_OK) {
334*9126SWyllys.Ingersoll@Sun.COM return (rc);
335*9126SWyllys.Ingersoll@Sun.COM }
336*9126SWyllys.Ingersoll@Sun.COM rc = encr_mgr_encrypt(sess, length_only,
337*9126SWyllys.Ingersoll@Sun.COM ctx, data, data_len, wrapped_key, wrapped_key_len);
338*9126SWyllys.Ingersoll@Sun.COM
339*9126SWyllys.Ingersoll@Sun.COM if (data != NULL) {
340*9126SWyllys.Ingersoll@Sun.COM free(data);
341*9126SWyllys.Ingersoll@Sun.COM }
342*9126SWyllys.Ingersoll@Sun.COM (void) encr_mgr_cleanup(ctx);
343*9126SWyllys.Ingersoll@Sun.COM free(ctx);
344*9126SWyllys.Ingersoll@Sun.COM
345*9126SWyllys.Ingersoll@Sun.COM return (rc);
346*9126SWyllys.Ingersoll@Sun.COM }
347*9126SWyllys.Ingersoll@Sun.COM
348*9126SWyllys.Ingersoll@Sun.COM CK_RV
key_mgr_unwrap_key(SESSION * sess,CK_MECHANISM * mech,CK_ATTRIBUTE * attributes,CK_ULONG attrib_count,CK_BYTE * wrapped_key,CK_ULONG wrapped_key_len,CK_OBJECT_HANDLE h_unwrapping_key,CK_OBJECT_HANDLE * h_unwrapped_key)349*9126SWyllys.Ingersoll@Sun.COM key_mgr_unwrap_key(SESSION * sess,
350*9126SWyllys.Ingersoll@Sun.COM CK_MECHANISM * mech,
351*9126SWyllys.Ingersoll@Sun.COM CK_ATTRIBUTE * attributes,
352*9126SWyllys.Ingersoll@Sun.COM CK_ULONG attrib_count,
353*9126SWyllys.Ingersoll@Sun.COM CK_BYTE * wrapped_key,
354*9126SWyllys.Ingersoll@Sun.COM CK_ULONG wrapped_key_len,
355*9126SWyllys.Ingersoll@Sun.COM CK_OBJECT_HANDLE h_unwrapping_key,
356*9126SWyllys.Ingersoll@Sun.COM CK_OBJECT_HANDLE * h_unwrapped_key)
357*9126SWyllys.Ingersoll@Sun.COM {
358*9126SWyllys.Ingersoll@Sun.COM ENCR_DECR_CONTEXT * ctx = NULL;
359*9126SWyllys.Ingersoll@Sun.COM OBJECT * key_obj = NULL;
360*9126SWyllys.Ingersoll@Sun.COM CK_BYTE * data = NULL;
361*9126SWyllys.Ingersoll@Sun.COM CK_ULONG data_len;
362*9126SWyllys.Ingersoll@Sun.COM CK_ULONG keyclass, keytype;
363*9126SWyllys.Ingersoll@Sun.COM CK_ULONG i;
364*9126SWyllys.Ingersoll@Sun.COM CK_BBOOL found_class, found_type, fromend;
365*9126SWyllys.Ingersoll@Sun.COM CK_RV rc;
366*9126SWyllys.Ingersoll@Sun.COM
367*9126SWyllys.Ingersoll@Sun.COM
368*9126SWyllys.Ingersoll@Sun.COM if (! sess || ! wrapped_key || ! h_unwrapped_key) {
369*9126SWyllys.Ingersoll@Sun.COM return (CKR_FUNCTION_FAILED);
370*9126SWyllys.Ingersoll@Sun.COM }
371*9126SWyllys.Ingersoll@Sun.COM
372*9126SWyllys.Ingersoll@Sun.COM rc = object_mgr_find_in_map1(sess->hContext, h_unwrapping_key,
373*9126SWyllys.Ingersoll@Sun.COM &key_obj);
374*9126SWyllys.Ingersoll@Sun.COM if (rc != CKR_OK) {
375*9126SWyllys.Ingersoll@Sun.COM return (CKR_WRAPPING_KEY_HANDLE_INVALID);
376*9126SWyllys.Ingersoll@Sun.COM }
377*9126SWyllys.Ingersoll@Sun.COM
378*9126SWyllys.Ingersoll@Sun.COM found_class = FALSE;
379*9126SWyllys.Ingersoll@Sun.COM found_type = FALSE;
380*9126SWyllys.Ingersoll@Sun.COM
381*9126SWyllys.Ingersoll@Sun.COM switch (mech->mechanism) {
382*9126SWyllys.Ingersoll@Sun.COM case CKM_RSA_PKCS:
383*9126SWyllys.Ingersoll@Sun.COM keyclass = CKO_SECRET_KEY;
384*9126SWyllys.Ingersoll@Sun.COM found_class = TRUE;
385*9126SWyllys.Ingersoll@Sun.COM break;
386*9126SWyllys.Ingersoll@Sun.COM }
387*9126SWyllys.Ingersoll@Sun.COM
388*9126SWyllys.Ingersoll@Sun.COM for (i = 0; i < attrib_count; i++) {
389*9126SWyllys.Ingersoll@Sun.COM switch (attributes[i].type) {
390*9126SWyllys.Ingersoll@Sun.COM case CKA_CLASS:
391*9126SWyllys.Ingersoll@Sun.COM keyclass = *(CK_OBJECT_CLASS *)attributes[i].pValue;
392*9126SWyllys.Ingersoll@Sun.COM found_class = TRUE;
393*9126SWyllys.Ingersoll@Sun.COM break;
394*9126SWyllys.Ingersoll@Sun.COM
395*9126SWyllys.Ingersoll@Sun.COM case CKA_KEY_TYPE:
396*9126SWyllys.Ingersoll@Sun.COM keytype = *(CK_KEY_TYPE *)attributes[i].pValue;
397*9126SWyllys.Ingersoll@Sun.COM found_type = TRUE;
398*9126SWyllys.Ingersoll@Sun.COM break;
399*9126SWyllys.Ingersoll@Sun.COM }
400*9126SWyllys.Ingersoll@Sun.COM }
401*9126SWyllys.Ingersoll@Sun.COM
402*9126SWyllys.Ingersoll@Sun.COM if (found_class == FALSE || (found_type == FALSE && keyclass !=
403*9126SWyllys.Ingersoll@Sun.COM CKO_PRIVATE_KEY)) {
404*9126SWyllys.Ingersoll@Sun.COM return (CKR_TEMPLATE_INCOMPLETE);
405*9126SWyllys.Ingersoll@Sun.COM }
406*9126SWyllys.Ingersoll@Sun.COM
407*9126SWyllys.Ingersoll@Sun.COM switch (mech->mechanism) {
408*9126SWyllys.Ingersoll@Sun.COM case CKM_RSA_PKCS:
409*9126SWyllys.Ingersoll@Sun.COM if (keyclass != CKO_SECRET_KEY) {
410*9126SWyllys.Ingersoll@Sun.COM return (CKR_TEMPLATE_INCONSISTENT);
411*9126SWyllys.Ingersoll@Sun.COM }
412*9126SWyllys.Ingersoll@Sun.COM break;
413*9126SWyllys.Ingersoll@Sun.COM default:
414*9126SWyllys.Ingersoll@Sun.COM return (CKR_MECHANISM_INVALID);
415*9126SWyllys.Ingersoll@Sun.COM }
416*9126SWyllys.Ingersoll@Sun.COM
417*9126SWyllys.Ingersoll@Sun.COM
418*9126SWyllys.Ingersoll@Sun.COM ctx = (ENCR_DECR_CONTEXT *)malloc(sizeof (ENCR_DECR_CONTEXT));
419*9126SWyllys.Ingersoll@Sun.COM if (! ctx) {
420*9126SWyllys.Ingersoll@Sun.COM return (CKR_HOST_MEMORY);
421*9126SWyllys.Ingersoll@Sun.COM }
422*9126SWyllys.Ingersoll@Sun.COM (void) memset(ctx, 0x0, sizeof (ENCR_DECR_CONTEXT));
423*9126SWyllys.Ingersoll@Sun.COM
424*9126SWyllys.Ingersoll@Sun.COM rc = decr_mgr_init(sess, ctx, OP_UNWRAP, mech, h_unwrapping_key);
425*9126SWyllys.Ingersoll@Sun.COM if (rc != CKR_OK)
426*9126SWyllys.Ingersoll@Sun.COM return (rc);
427*9126SWyllys.Ingersoll@Sun.COM
428*9126SWyllys.Ingersoll@Sun.COM rc = decr_mgr_decrypt(sess,
429*9126SWyllys.Ingersoll@Sun.COM TRUE, ctx, wrapped_key, wrapped_key_len,
430*9126SWyllys.Ingersoll@Sun.COM data, &data_len);
431*9126SWyllys.Ingersoll@Sun.COM if (rc != CKR_OK) {
432*9126SWyllys.Ingersoll@Sun.COM goto error;
433*9126SWyllys.Ingersoll@Sun.COM }
434*9126SWyllys.Ingersoll@Sun.COM data = (CK_BYTE *)malloc(data_len);
435*9126SWyllys.Ingersoll@Sun.COM if (! data) {
436*9126SWyllys.Ingersoll@Sun.COM rc = CKR_HOST_MEMORY;
437*9126SWyllys.Ingersoll@Sun.COM goto error;
438*9126SWyllys.Ingersoll@Sun.COM }
439*9126SWyllys.Ingersoll@Sun.COM
440*9126SWyllys.Ingersoll@Sun.COM rc = decr_mgr_decrypt(sess,
441*9126SWyllys.Ingersoll@Sun.COM FALSE, ctx, wrapped_key, wrapped_key_len,
442*9126SWyllys.Ingersoll@Sun.COM data, &data_len);
443*9126SWyllys.Ingersoll@Sun.COM
444*9126SWyllys.Ingersoll@Sun.COM (void) decr_mgr_cleanup(ctx);
445*9126SWyllys.Ingersoll@Sun.COM free(ctx);
446*9126SWyllys.Ingersoll@Sun.COM
447*9126SWyllys.Ingersoll@Sun.COM if (rc != CKR_OK) {
448*9126SWyllys.Ingersoll@Sun.COM goto error;
449*9126SWyllys.Ingersoll@Sun.COM }
450*9126SWyllys.Ingersoll@Sun.COM /*
451*9126SWyllys.Ingersoll@Sun.COM * if we use X.509, the data will be padded from the front with zeros.
452*9126SWyllys.Ingersoll@Sun.COM * PKCS #11 specifies that for this mechanism, CK_VALUE is to be read
453*9126SWyllys.Ingersoll@Sun.COM * from the end of the data.
454*9126SWyllys.Ingersoll@Sun.COM *
455*9126SWyllys.Ingersoll@Sun.COM * Note: the PKCS #11 reference implementation gets this wrong.
456*9126SWyllys.Ingersoll@Sun.COM */
457*9126SWyllys.Ingersoll@Sun.COM if (mech->mechanism == CKM_RSA_X_509)
458*9126SWyllys.Ingersoll@Sun.COM fromend = TRUE;
459*9126SWyllys.Ingersoll@Sun.COM else
460*9126SWyllys.Ingersoll@Sun.COM fromend = FALSE;
461*9126SWyllys.Ingersoll@Sun.COM
462*9126SWyllys.Ingersoll@Sun.COM if (keyclass == CKO_PRIVATE_KEY) {
463*9126SWyllys.Ingersoll@Sun.COM rc = key_mgr_get_private_key_type(data, data_len, &keytype);
464*9126SWyllys.Ingersoll@Sun.COM if (rc != CKR_OK) {
465*9126SWyllys.Ingersoll@Sun.COM goto error;
466*9126SWyllys.Ingersoll@Sun.COM }
467*9126SWyllys.Ingersoll@Sun.COM }
468*9126SWyllys.Ingersoll@Sun.COM
469*9126SWyllys.Ingersoll@Sun.COM rc = object_mgr_create_skel(sess,
470*9126SWyllys.Ingersoll@Sun.COM attributes, attrib_count,
471*9126SWyllys.Ingersoll@Sun.COM MODE_UNWRAP, keyclass, keytype,
472*9126SWyllys.Ingersoll@Sun.COM &key_obj);
473*9126SWyllys.Ingersoll@Sun.COM if (rc != CKR_OK) {
474*9126SWyllys.Ingersoll@Sun.COM goto error;
475*9126SWyllys.Ingersoll@Sun.COM }
476*9126SWyllys.Ingersoll@Sun.COM switch (keyclass) {
477*9126SWyllys.Ingersoll@Sun.COM case CKO_SECRET_KEY:
478*9126SWyllys.Ingersoll@Sun.COM rc = secret_key_unwrap(key_obj->template, keytype, data,
479*9126SWyllys.Ingersoll@Sun.COM data_len, fromend);
480*9126SWyllys.Ingersoll@Sun.COM break;
481*9126SWyllys.Ingersoll@Sun.COM
482*9126SWyllys.Ingersoll@Sun.COM case CKO_PRIVATE_KEY:
483*9126SWyllys.Ingersoll@Sun.COM rc = priv_key_unwrap(key_obj->template, keytype,
484*9126SWyllys.Ingersoll@Sun.COM data, data_len);
485*9126SWyllys.Ingersoll@Sun.COM break;
486*9126SWyllys.Ingersoll@Sun.COM
487*9126SWyllys.Ingersoll@Sun.COM default:
488*9126SWyllys.Ingersoll@Sun.COM rc = CKR_WRAPPED_KEY_INVALID;
489*9126SWyllys.Ingersoll@Sun.COM break;
490*9126SWyllys.Ingersoll@Sun.COM }
491*9126SWyllys.Ingersoll@Sun.COM
492*9126SWyllys.Ingersoll@Sun.COM if (rc != CKR_OK) {
493*9126SWyllys.Ingersoll@Sun.COM goto error;
494*9126SWyllys.Ingersoll@Sun.COM }
495*9126SWyllys.Ingersoll@Sun.COM rc = object_mgr_create_final(sess, key_obj, h_unwrapped_key);
496*9126SWyllys.Ingersoll@Sun.COM if (rc != CKR_OK) {
497*9126SWyllys.Ingersoll@Sun.COM goto error;
498*9126SWyllys.Ingersoll@Sun.COM }
499*9126SWyllys.Ingersoll@Sun.COM if (data) free(data);
500*9126SWyllys.Ingersoll@Sun.COM return (rc);
501*9126SWyllys.Ingersoll@Sun.COM
502*9126SWyllys.Ingersoll@Sun.COM error:
503*9126SWyllys.Ingersoll@Sun.COM if (key_obj) (void) object_free(key_obj);
504*9126SWyllys.Ingersoll@Sun.COM if (data) free(data);
505*9126SWyllys.Ingersoll@Sun.COM
506*9126SWyllys.Ingersoll@Sun.COM return (rc);
507*9126SWyllys.Ingersoll@Sun.COM }
508