OLD | NEW |
1 /* This Source Code Form is subject to the terms of the Mozilla Public | 1 /* This Source Code Form is subject to the terms of the Mozilla Public |
2 * License, v. 2.0. If a copy of the MPL was not distributed with this | 2 * License, v. 2.0. If a copy of the MPL was not distributed with this |
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ | 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
4 /* | 4 /* |
5 * This file implements the Symkey wrapper and the PKCS context | 5 * This file implements the Symkey wrapper and the PKCS context |
6 * Interfaces. | 6 * Interfaces. |
7 */ | 7 */ |
8 | 8 |
9 #include "seccomon.h" | 9 #include "seccomon.h" |
10 #include "secmod.h" | 10 #include "secmod.h" |
11 #include "nssilock.h" | 11 #include "nssilock.h" |
12 #include "secmodi.h" | 12 #include "secmodi.h" |
13 #include "secmodti.h" | 13 #include "secmodti.h" |
14 #include "pkcs11.h" | 14 #include "pkcs11.h" |
15 #include "pk11func.h" | 15 #include "pk11func.h" |
16 #include "secitem.h" | 16 #include "secitem.h" |
17 #include "secoid.h" | 17 #include "secoid.h" |
18 #include "secerr.h" | 18 #include "secerr.h" |
19 #include "hasht.h" | 19 #include "hasht.h" |
20 | 20 |
21 static void | 21 static void pk11_EnterKeyMonitor(PK11SymKey *symKey) { |
22 pk11_EnterKeyMonitor(PK11SymKey *symKey) { | 22 if (!symKey->sessionOwner || !(symKey->slot->isThreadSafe)) |
23 if (!symKey->sessionOwner || !(symKey->slot->isThreadSafe))· | 23 PK11_EnterSlotMonitor(symKey->slot); |
24 » PK11_EnterSlotMonitor(symKey->slot); | 24 } |
25 } | 25 |
26 | 26 static void pk11_ExitKeyMonitor(PK11SymKey *symKey) { |
27 static void | 27 if (!symKey->sessionOwner || !(symKey->slot->isThreadSafe)) |
28 pk11_ExitKeyMonitor(PK11SymKey *symKey) { | 28 PK11_ExitSlotMonitor(symKey->slot); |
29 if (!symKey->sessionOwner || !(symKey->slot->isThreadSafe)) | |
30 » PK11_ExitSlotMonitor(symKey->slot); | |
31 } | 29 } |
32 | 30 |
33 /* | 31 /* |
34 * pk11_getKeyFromList returns a symKey that has a session (if needSession | 32 * pk11_getKeyFromList returns a symKey that has a session (if needSession |
35 * was specified), or explicitly does not have a session (if needSession | 33 * was specified), or explicitly does not have a session (if needSession |
36 * was not specified). | 34 * was not specified). |
37 */ | 35 */ |
38 static PK11SymKey * | 36 static PK11SymKey *pk11_getKeyFromList(PK11SlotInfo *slot, PRBool needSession) { |
39 pk11_getKeyFromList(PK11SlotInfo *slot, PRBool needSession) { | 37 PK11SymKey *symKey = NULL; |
40 PK11SymKey *symKey = NULL; | 38 |
41 | 39 PZ_Lock(slot->freeListLock); |
42 PZ_Lock(slot->freeListLock); | 40 /* own session list are symkeys with sessions that the symkey owns. |
43 /* own session list are symkeys with sessions that the symkey owns. | 41 * 'most' symkeys will own their own session. */ |
44 * 'most' symkeys will own their own session. */ | 42 if (needSession) { |
45 if (needSession) { | 43 if (slot->freeSymKeysWithSessionHead) { |
46 » if (slot->freeSymKeysWithSessionHead) { | 44 symKey = slot->freeSymKeysWithSessionHead; |
47 » symKey = slot->freeSymKeysWithSessionHead; | 45 slot->freeSymKeysWithSessionHead = symKey->next; |
48 » slot->freeSymKeysWithSessionHead = symKey->next; | 46 slot->keyCount--; |
49 » slot->keyCount--; | 47 } |
50 » } | 48 } |
51 } | 49 /* if we don't need a symkey with its own session, or we couldn't find |
52 /* if we don't need a symkey with its own session, or we couldn't find | 50 * one on the owner list, get one from the non-owner free list. */ |
53 * one on the owner list, get one from the non-owner free list. */ | 51 if (!symKey) { |
54 if (!symKey) { | 52 if (slot->freeSymKeysHead) { |
55 » if (slot->freeSymKeysHead) { | 53 symKey = slot->freeSymKeysHead; |
56 » symKey = slot->freeSymKeysHead; | 54 slot->freeSymKeysHead = symKey->next; |
57 » slot->freeSymKeysHead = symKey->next; | 55 slot->keyCount--; |
58 » slot->keyCount--; | 56 } |
59 » } | 57 } |
60 } | 58 PZ_Unlock(slot->freeListLock); |
61 PZ_Unlock(slot->freeListLock); | 59 if (symKey) { |
62 if (symKey) { | |
63 » symKey->next = NULL; | |
64 » if (!needSession) { | |
65 » return symKey; | |
66 » } | |
67 » /* if we are getting an owner key, make sure we have a valid session. | |
68 * session could be invalid if the token has been removed or because | |
69 * we got it from the non-owner free list */ | |
70 » if ((symKey->series != slot->series) ||· | |
71 » » » (symKey->session == CK_INVALID_SESSION)) { | |
72 » symKey->session = pk11_GetNewSession(slot, &symKey->sessionOwner); | |
73 » } | |
74 » PORT_Assert(symKey->session != CK_INVALID_SESSION); | |
75 » if (symKey->session != CK_INVALID_SESSION) | |
76 » return symKey; | |
77 » PK11_FreeSymKey(symKey); | |
78 » /* if we are here, we need a session, but couldn't get one, it's· | |
79 » * unlikely we pk11_GetNewSession will succeed if we call it a second | |
80 » * time. */ | |
81 » return NULL; | |
82 } | |
83 | |
84 symKey = PORT_New(PK11SymKey); | |
85 if (symKey == NULL) { | |
86 » return NULL; | |
87 } | |
88 | |
89 symKey->next = NULL; | 60 symKey->next = NULL; |
90 if (needSession) { | 61 if (!needSession) { |
91 » symKey->session = pk11_GetNewSession(slot,&symKey->sessionOwner); | 62 return symKey; |
92 » PORT_Assert(symKey->session != CK_INVALID_SESSION); | 63 } |
93 if (symKey->session == CK_INVALID_SESSION) { | 64 /* if we are getting an owner key, make sure we have a valid session. |
94 » PK11_FreeSymKey(symKey); | 65 * session could be invalid if the token has been removed or because |
95 » symKey = NULL; | 66 * we got it from the non-owner free list */ |
96 » } | 67 if ((symKey->series != slot->series) || |
97 } else { | 68 (symKey->session == CK_INVALID_SESSION)) { |
98 » symKey->session = CK_INVALID_SESSION; | 69 symKey->session = pk11_GetNewSession(slot, &symKey->sessionOwner); |
99 } | 70 } |
100 return symKey; | 71 PORT_Assert(symKey->session != CK_INVALID_SESSION); |
| 72 if (symKey->session != CK_INVALID_SESSION) return symKey; |
| 73 PK11_FreeSymKey(symKey); |
| 74 /* if we are here, we need a session, but couldn't get one, it's |
| 75 * unlikely we pk11_GetNewSession will succeed if we call it a second |
| 76 * time. */ |
| 77 return NULL; |
| 78 } |
| 79 |
| 80 symKey = PORT_New(PK11SymKey); |
| 81 if (symKey == NULL) { |
| 82 return NULL; |
| 83 } |
| 84 |
| 85 symKey->next = NULL; |
| 86 if (needSession) { |
| 87 symKey->session = pk11_GetNewSession(slot, &symKey->sessionOwner); |
| 88 PORT_Assert(symKey->session != CK_INVALID_SESSION); |
| 89 if (symKey->session == CK_INVALID_SESSION) { |
| 90 PK11_FreeSymKey(symKey); |
| 91 symKey = NULL; |
| 92 } |
| 93 } else { |
| 94 symKey->session = CK_INVALID_SESSION; |
| 95 } |
| 96 return symKey; |
101 } | 97 } |
102 | 98 |
103 /* Caller MUST hold slot->freeListLock (or ref count == 0?) !! */ | 99 /* Caller MUST hold slot->freeListLock (or ref count == 0?) !! */ |
104 void | 100 void PK11_CleanKeyList(PK11SlotInfo *slot) { |
105 PK11_CleanKeyList(PK11SlotInfo *slot) | 101 PK11SymKey *symKey = NULL; |
106 { | 102 |
107 PK11SymKey *symKey = NULL; | 103 while (slot->freeSymKeysWithSessionHead) { |
108 | 104 symKey = slot->freeSymKeysWithSessionHead; |
109 while (slot->freeSymKeysWithSessionHead) { | 105 slot->freeSymKeysWithSessionHead = symKey->next; |
110 » symKey = slot->freeSymKeysWithSessionHead; | 106 pk11_CloseSession(slot, symKey->session, symKey->sessionOwner); |
111 » slot->freeSymKeysWithSessionHead = symKey->next; | 107 PORT_Free(symKey); |
112 » pk11_CloseSession(slot, symKey->session, symKey->sessionOwner); | 108 } |
113 » PORT_Free(symKey); | 109 while (slot->freeSymKeysHead) { |
114 } | 110 symKey = slot->freeSymKeysHead; |
115 while (slot->freeSymKeysHead) { | 111 slot->freeSymKeysHead = symKey->next; |
116 » symKey = slot->freeSymKeysHead; | 112 pk11_CloseSession(slot, symKey->session, symKey->sessionOwner); |
117 » slot->freeSymKeysHead = symKey->next; | 113 PORT_Free(symKey); |
118 » pk11_CloseSession(slot, symKey->session, symKey->sessionOwner); | 114 } |
119 » PORT_Free(symKey); | 115 return; |
120 } | |
121 return; | |
122 } | 116 } |
123 | 117 |
124 /* | 118 /* |
125 * create a symetric key: | 119 * create a symetric key: |
126 * Slot is the slot to create the key in. | 120 * Slot is the slot to create the key in. |
127 * type is the mechanism type | 121 * type is the mechanism type |
128 * owner is does this symKey structure own it's object handle (rare | 122 * owner is does this symKey structure own it's object handle (rare |
129 * that this is false). | 123 * that this is false). |
130 * needSession means the returned symKey will return with a valid session | 124 * needSession means the returned symKey will return with a valid session |
131 * allocated already. | 125 * allocated already. |
132 */ | 126 */ |
133 static PK11SymKey * | 127 static PK11SymKey *pk11_CreateSymKey(PK11SlotInfo *slot, CK_MECHANISM_TYPE type, |
134 pk11_CreateSymKey(PK11SlotInfo *slot, CK_MECHANISM_TYPE type,· | 128 PRBool owner, PRBool needSession, |
135 » » PRBool owner, PRBool needSession, void *wincx) | 129 void *wincx) { |
136 { | 130 |
137 | 131 PK11SymKey *symKey = pk11_getKeyFromList(slot, needSession); |
138 PK11SymKey *symKey = pk11_getKeyFromList(slot, needSession); | 132 |
139 | 133 if (symKey == NULL) { |
140 if (symKey == NULL) { | 134 return NULL; |
141 » return NULL; | 135 } |
142 } | 136 /* if needSession was specified, make sure we have a valid session. |
143 /* if needSession was specified, make sure we have a valid session. | 137 * callers which specify needSession as false should do their own |
144 * callers which specify needSession as false should do their own | 138 * check of the session before returning the symKey */ |
145 * check of the session before returning the symKey */ | 139 if (needSession && symKey->session == CK_INVALID_SESSION) { |
146 if (needSession && symKey->session == CK_INVALID_SESSION) { | 140 PK11_FreeSymKey(symKey); |
147 » PK11_FreeSymKey(symKey); | 141 PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); |
148 » PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); | 142 return NULL; |
149 » return NULL; | 143 } |
150 } | 144 |
151 | 145 symKey->type = type; |
152 symKey->type = type; | 146 symKey->data.type = siBuffer; |
153 symKey->data.type = siBuffer; | 147 symKey->data.data = NULL; |
154 symKey->data.data = NULL; | 148 symKey->data.len = 0; |
155 symKey->data.len = 0; | 149 symKey->owner = owner; |
156 symKey->owner = owner; | 150 symKey->objectID = CK_INVALID_HANDLE; |
157 symKey->objectID = CK_INVALID_HANDLE; | 151 symKey->slot = slot; |
158 symKey->slot = slot; | 152 symKey->series = slot->series; |
159 symKey->series = slot->series; | 153 symKey->cx = wincx; |
160 symKey->cx = wincx; | 154 symKey->size = 0; |
161 symKey->size = 0; | 155 symKey->refCount = 1; |
162 symKey->refCount = 1; | 156 symKey->origin = PK11_OriginNULL; |
163 symKey->origin = PK11_OriginNULL; | 157 symKey->parent = NULL; |
| 158 symKey->freeFunc = NULL; |
| 159 symKey->userData = NULL; |
| 160 PK11_ReferenceSlot(slot); |
| 161 return symKey; |
| 162 } |
| 163 |
| 164 /* |
| 165 * destroy a symetric key |
| 166 */ |
| 167 void PK11_FreeSymKey(PK11SymKey *symKey) { |
| 168 PK11SlotInfo *slot; |
| 169 PRBool freeit = PR_TRUE; |
| 170 |
| 171 if (PR_ATOMIC_DECREMENT(&symKey->refCount) == 0) { |
| 172 PK11SymKey *parent = symKey->parent; |
| 173 |
164 symKey->parent = NULL; | 174 symKey->parent = NULL; |
165 symKey->freeFunc = NULL; | 175 if ((symKey->owner) && symKey->objectID != CK_INVALID_HANDLE) { |
166 symKey->userData = NULL; | 176 pk11_EnterKeyMonitor(symKey); |
167 PK11_ReferenceSlot(slot); | 177 (void)PK11_GETTAB(symKey->slot) |
168 return symKey; | 178 ->C_DestroyObject(symKey->session, symKey->objectID); |
169 } | 179 pk11_ExitKeyMonitor(symKey); |
170 | 180 } |
171 /* | 181 if (symKey->data.data) { |
172 * destroy a symetric key | 182 PORT_Memset(symKey->data.data, 0, symKey->data.len); |
173 */ | 183 PORT_Free(symKey->data.data); |
174 void | 184 } |
175 PK11_FreeSymKey(PK11SymKey *symKey) | |
176 { | |
177 PK11SlotInfo *slot; | |
178 PRBool freeit = PR_TRUE; | |
179 | |
180 if (PR_ATOMIC_DECREMENT(&symKey->refCount) == 0) { | |
181 » PK11SymKey *parent = symKey->parent; | |
182 | |
183 » symKey->parent = NULL; | |
184 » if ((symKey->owner) && symKey->objectID != CK_INVALID_HANDLE) { | |
185 » pk11_EnterKeyMonitor(symKey); | |
186 » (void) PK11_GETTAB(symKey->slot)-> | |
187 » » C_DestroyObject(symKey->session, symKey->objectID); | |
188 » pk11_ExitKeyMonitor(symKey); | |
189 » } | |
190 » if (symKey->data.data) { | |
191 » PORT_Memset(symKey->data.data, 0, symKey->data.len); | |
192 » PORT_Free(symKey->data.data); | |
193 » } | |
194 » /* free any existing data */ | |
195 » if (symKey->userData && symKey->freeFunc) { | |
196 » (*symKey->freeFunc)(symKey->userData); | |
197 » } | |
198 slot = symKey->slot; | |
199 PZ_Lock(slot->freeListLock); | |
200 » if (slot->keyCount < slot->maxKeyCount) { | |
201 » /*· | |
202 * freeSymkeysWithSessionHead contain a list of reusable | |
203 » * SymKey structures with valid sessions. | |
204 » * sessionOwner must be true. | |
205 * session must be valid. | |
206 * freeSymKeysHead contain a list of SymKey structures without | |
207 * valid session. | |
208 * session must be CK_INVALID_SESSION. | |
209 » * though sessionOwner is false, callers should not depend on | |
210 » * this fact. | |
211 » */ | |
212 » if (symKey->sessionOwner) { | |
213 » » PORT_Assert (symKey->session != CK_INVALID_SESSION); | |
214 » » symKey->next = slot->freeSymKeysWithSessionHead; | |
215 » » slot->freeSymKeysWithSessionHead = symKey; | |
216 » } else { | |
217 » » symKey->session = CK_INVALID_SESSION; | |
218 » » symKey->next = slot->freeSymKeysHead; | |
219 » » slot->freeSymKeysHead = symKey; | |
220 » } | |
221 » slot->keyCount++; | |
222 » symKey->slot = NULL; | |
223 » freeit = PR_FALSE; | |
224 } | |
225 » PZ_Unlock(slot->freeListLock); | |
226 if (freeit) { | |
227 » pk11_CloseSession(symKey->slot, symKey->session, | |
228 » » » » » » » symKey->sessionOwner); | |
229 » PORT_Free(symKey); | |
230 » } | |
231 » PK11_FreeSlot(slot); | |
232 | |
233 » if (parent) { | |
234 » PK11_FreeSymKey(parent); | |
235 » } | |
236 } | |
237 } | |
238 | |
239 PK11SymKey * | |
240 PK11_ReferenceSymKey(PK11SymKey *symKey) | |
241 { | |
242 PR_ATOMIC_INCREMENT(&symKey->refCount); | |
243 return symKey; | |
244 } | |
245 | |
246 /* | |
247 * Accessors | |
248 */ | |
249 CK_MECHANISM_TYPE | |
250 PK11_GetMechanism(PK11SymKey *symKey) | |
251 { | |
252 return symKey->type; | |
253 } | |
254 | |
255 /* | |
256 * return the slot associated with a symetric key | |
257 */ | |
258 PK11SlotInfo * | |
259 PK11_GetSlotFromKey(PK11SymKey *symKey) | |
260 { | |
261 return PK11_ReferenceSlot(symKey->slot); | |
262 } | |
263 | |
264 CK_KEY_TYPE PK11_GetSymKeyType(PK11SymKey *symKey) | |
265 { | |
266 return PK11_GetKeyType(symKey->type,symKey->size); | |
267 } | |
268 | |
269 PK11SymKey * | |
270 PK11_GetNextSymKey(PK11SymKey *symKey) | |
271 { | |
272 return symKey ? symKey->next : NULL; | |
273 } | |
274 | |
275 char * | |
276 PK11_GetSymKeyNickname(PK11SymKey *symKey) | |
277 { | |
278 return PK11_GetObjectNickname(symKey->slot,symKey->objectID); | |
279 } | |
280 | |
281 SECStatus | |
282 PK11_SetSymKeyNickname(PK11SymKey *symKey, const char *nickname) | |
283 { | |
284 return PK11_SetObjectNickname(symKey->slot,symKey->objectID,nickname); | |
285 } | |
286 | |
287 void * | |
288 PK11_GetSymKeyUserData(PK11SymKey *symKey) | |
289 { | |
290 return symKey->userData; | |
291 } | |
292 | |
293 void | |
294 PK11_SetSymKeyUserData(PK11SymKey *symKey, void *userData,· | |
295 PK11FreeDataFunc freeFunc) | |
296 { | |
297 /* free any existing data */ | 185 /* free any existing data */ |
298 if (symKey->userData && symKey->freeFunc) { | 186 if (symKey->userData && symKey->freeFunc) { |
299 » (*symKey->freeFunc)(symKey->userData); | 187 (*symKey->freeFunc)(symKey->userData); |
300 } | 188 } |
301 symKey->userData = userData; | 189 slot = symKey->slot; |
302 symKey->freeFunc = freeFunc; | 190 PZ_Lock(slot->freeListLock); |
303 return; | 191 if (slot->keyCount < slot->maxKeyCount) { |
| 192 /* |
| 193 * freeSymkeysWithSessionHead contain a list of reusable |
| 194 * SymKey structures with valid sessions. |
| 195 * sessionOwner must be true. |
| 196 * session must be valid. |
| 197 * freeSymKeysHead contain a list of SymKey structures without |
| 198 * valid session. |
| 199 * session must be CK_INVALID_SESSION. |
| 200 * though sessionOwner is false, callers should not depend on |
| 201 * this fact. |
| 202 */ |
| 203 if (symKey->sessionOwner) { |
| 204 PORT_Assert(symKey->session != CK_INVALID_SESSION); |
| 205 symKey->next = slot->freeSymKeysWithSessionHead; |
| 206 slot->freeSymKeysWithSessionHead = symKey; |
| 207 } else { |
| 208 symKey->session = CK_INVALID_SESSION; |
| 209 symKey->next = slot->freeSymKeysHead; |
| 210 slot->freeSymKeysHead = symKey; |
| 211 } |
| 212 slot->keyCount++; |
| 213 symKey->slot = NULL; |
| 214 freeit = PR_FALSE; |
| 215 } |
| 216 PZ_Unlock(slot->freeListLock); |
| 217 if (freeit) { |
| 218 pk11_CloseSession(symKey->slot, symKey->session, symKey->sessionOwner); |
| 219 PORT_Free(symKey); |
| 220 } |
| 221 PK11_FreeSlot(slot); |
| 222 |
| 223 if (parent) { |
| 224 PK11_FreeSymKey(parent); |
| 225 } |
| 226 } |
| 227 } |
| 228 |
| 229 PK11SymKey *PK11_ReferenceSymKey(PK11SymKey *symKey) { |
| 230 PR_ATOMIC_INCREMENT(&symKey->refCount); |
| 231 return symKey; |
| 232 } |
| 233 |
| 234 /* |
| 235 * Accessors |
| 236 */ |
| 237 CK_MECHANISM_TYPE |
| 238 PK11_GetMechanism(PK11SymKey *symKey) { return symKey->type; } |
| 239 |
| 240 /* |
| 241 * return the slot associated with a symetric key |
| 242 */ |
| 243 PK11SlotInfo *PK11_GetSlotFromKey(PK11SymKey *symKey) { |
| 244 return PK11_ReferenceSlot(symKey->slot); |
| 245 } |
| 246 |
| 247 CK_KEY_TYPE PK11_GetSymKeyType(PK11SymKey *symKey) { |
| 248 return PK11_GetKeyType(symKey->type, symKey->size); |
| 249 } |
| 250 |
| 251 PK11SymKey *PK11_GetNextSymKey(PK11SymKey *symKey) { |
| 252 return symKey ? symKey->next : NULL; |
| 253 } |
| 254 |
| 255 char *PK11_GetSymKeyNickname(PK11SymKey *symKey) { |
| 256 return PK11_GetObjectNickname(symKey->slot, symKey->objectID); |
| 257 } |
| 258 |
| 259 SECStatus PK11_SetSymKeyNickname(PK11SymKey *symKey, const char *nickname) { |
| 260 return PK11_SetObjectNickname(symKey->slot, symKey->objectID, nickname); |
| 261 } |
| 262 |
| 263 void *PK11_GetSymKeyUserData(PK11SymKey *symKey) { return symKey->userData; } |
| 264 |
| 265 void PK11_SetSymKeyUserData(PK11SymKey *symKey, void *userData, |
| 266 PK11FreeDataFunc freeFunc) { |
| 267 /* free any existing data */ |
| 268 if (symKey->userData && symKey->freeFunc) { |
| 269 (*symKey->freeFunc)(symKey->userData); |
| 270 } |
| 271 symKey->userData = userData; |
| 272 symKey->freeFunc = freeFunc; |
| 273 return; |
304 } | 274 } |
305 | 275 |
306 /* | 276 /* |
307 * turn key handle into an appropriate key object | 277 * turn key handle into an appropriate key object |
308 */ | 278 */ |
309 PK11SymKey * | 279 PK11SymKey *PK11_SymKeyFromHandle(PK11SlotInfo *slot, PK11SymKey *parent, |
310 PK11_SymKeyFromHandle(PK11SlotInfo *slot, PK11SymKey *parent, PK11Origin origin, | 280 PK11Origin origin, CK_MECHANISM_TYPE type, |
311 CK_MECHANISM_TYPE type, CK_OBJECT_HANDLE keyID, PRBool owner, void *wincx) | 281 CK_OBJECT_HANDLE keyID, PRBool owner, |
312 { | 282 void *wincx) { |
313 PK11SymKey *symKey; | 283 PK11SymKey *symKey; |
314 PRBool needSession = !(owner && parent); | 284 PRBool needSession = !(owner && parent); |
315 | 285 |
316 if (keyID == CK_INVALID_HANDLE) { | 286 if (keyID == CK_INVALID_HANDLE) { |
317 » return NULL; | 287 return NULL; |
318 } | 288 } |
319 | 289 |
320 symKey = pk11_CreateSymKey(slot, type, owner, needSession, wincx); | 290 symKey = pk11_CreateSymKey(slot, type, owner, needSession, wincx); |
321 if (symKey == NULL) { | 291 if (symKey == NULL) { |
322 » return NULL; | 292 return NULL; |
323 } | 293 } |
324 | 294 |
325 symKey->objectID = keyID; | 295 symKey->objectID = keyID; |
326 symKey->origin = origin; | 296 symKey->origin = origin; |
327 | 297 |
328 /* adopt the parent's session */ | 298 /* adopt the parent's session */ |
329 /* This is only used by SSL. What we really want here is a session | 299 /* This is only used by SSL. What we really want here is a session |
330 * structure with a ref count so the session goes away only after all the | 300 * structure with a ref count so the session goes away only after all the |
331 * keys do. */ | 301 * keys do. */ |
332 if (!needSession) { | 302 if (!needSession) { |
333 » symKey->sessionOwner = PR_FALSE; | 303 symKey->sessionOwner = PR_FALSE; |
334 » symKey->session = parent->session; | 304 symKey->session = parent->session; |
335 » symKey->parent = PK11_ReferenceSymKey(parent); | 305 symKey->parent = PK11_ReferenceSymKey(parent); |
336 /* This is the only case where pk11_CreateSymKey does not explicitly | 306 /* This is the only case where pk11_CreateSymKey does not explicitly |
337 » * check symKey->session. We need to assert here to make sure. | 307 * check symKey->session. We need to assert here to make sure. |
338 » * the session isn't invalid. */ | 308 * the session isn't invalid. */ |
339 » PORT_Assert(parent->session != CK_INVALID_SESSION); | 309 PORT_Assert(parent->session != CK_INVALID_SESSION); |
340 » if (parent->session == CK_INVALID_SESSION) { | 310 if (parent->session == CK_INVALID_SESSION) { |
341 » PK11_FreeSymKey(symKey); | 311 PK11_FreeSymKey(symKey); |
342 » PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); | 312 PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); |
343 » return NULL; | 313 return NULL; |
344 » } | 314 } |
345 } | 315 } |
346 | 316 |
347 return symKey; | 317 return symKey; |
348 } | 318 } |
349 | 319 |
350 /* | 320 /* |
351 * turn key handle into an appropriate key object | 321 * turn key handle into an appropriate key object |
352 */ | 322 */ |
353 PK11SymKey * | 323 PK11SymKey *PK11_GetWrapKey(PK11SlotInfo *slot, int wrap, |
354 PK11_GetWrapKey(PK11SlotInfo *slot, int wrap, CK_MECHANISM_TYPE type, | 324 CK_MECHANISM_TYPE type, int series, void *wincx) { |
355 » » » » » » int series, void *wincx) | 325 PK11SymKey *symKey = NULL; |
356 { | 326 |
357 PK11SymKey *symKey = NULL; | 327 if (slot->series != series) return NULL; |
358 | 328 if (slot->refKeys[wrap] == CK_INVALID_HANDLE) return NULL; |
359 if (slot->series != series) return NULL; | 329 if (type == CKM_INVALID_MECHANISM) type = slot->wrapMechanism; |
360 if (slot->refKeys[wrap] == CK_INVALID_HANDLE) return NULL; | 330 |
361 if (type == CKM_INVALID_MECHANISM) type = slot->wrapMechanism; | 331 symKey = |
362 | 332 PK11_SymKeyFromHandle(slot, NULL, PK11_OriginDerive, slot->wrapMechanism, |
363 symKey = PK11_SymKeyFromHandle(slot, NULL, PK11_OriginDerive, | 333 slot->refKeys[wrap], PR_FALSE, wincx); |
364 » » slot->wrapMechanism, slot->refKeys[wrap], PR_FALSE, wincx); | 334 return symKey; |
365 return symKey; | |
366 } | 335 } |
367 | 336 |
368 /* | 337 /* |
369 * This function is not thread-safe because it sets wrapKey->sessionOwner | 338 * This function is not thread-safe because it sets wrapKey->sessionOwner |
370 * without using a lock or atomic routine. It can only be called when | 339 * without using a lock or atomic routine. It can only be called when |
371 * only one thread has a reference to wrapKey. | 340 * only one thread has a reference to wrapKey. |
372 */ | 341 */ |
373 void | 342 void PK11_SetWrapKey(PK11SlotInfo *slot, int wrap, PK11SymKey *wrapKey) { |
374 PK11_SetWrapKey(PK11SlotInfo *slot, int wrap, PK11SymKey *wrapKey) | 343 /* save the handle and mechanism for the wrapping key */ |
375 { | 344 /* mark the key and session as not owned by us to they don't get freed |
376 /* save the handle and mechanism for the wrapping key */ | 345 * when the key goes way... that lets us reuse the key later */ |
377 /* mark the key and session as not owned by us to they don't get freed | 346 slot->refKeys[wrap] = wrapKey->objectID; |
378 * when the key goes way... that lets us reuse the key later */ | 347 wrapKey->owner = PR_FALSE; |
379 slot->refKeys[wrap] = wrapKey->objectID; | 348 wrapKey->sessionOwner = PR_FALSE; |
380 wrapKey->owner = PR_FALSE; | 349 slot->wrapMechanism = wrapKey->type; |
381 wrapKey->sessionOwner = PR_FALSE; | 350 } |
382 slot->wrapMechanism = wrapKey->type; | |
383 } | |
384 | |
385 | 351 |
386 /* | 352 /* |
387 * figure out if a key is still valid or if it is stale. | 353 * figure out if a key is still valid or if it is stale. |
388 */ | 354 */ |
389 PRBool | 355 PRBool PK11_VerifyKeyOK(PK11SymKey *key) { |
390 PK11_VerifyKeyOK(PK11SymKey *key) { | 356 if (!PK11_IsPresent(key->slot)) { |
391 if (!PK11_IsPresent(key->slot)) { | 357 return PR_FALSE; |
392 » return PR_FALSE; | 358 } |
393 } | 359 return (PRBool)(key->series == key->slot->series); |
394 return (PRBool)(key->series == key->slot->series); | 360 } |
395 } | 361 |
396 | 362 static PK11SymKey *pk11_ImportSymKeyWithTempl(PK11SlotInfo *slot, |
397 static PK11SymKey * | 363 CK_MECHANISM_TYPE type, |
398 pk11_ImportSymKeyWithTempl(PK11SlotInfo *slot, CK_MECHANISM_TYPE type, | 364 PK11Origin origin, PRBool isToken, |
399 PK11Origin origin, PRBool isToken, CK_ATTRIBUTE *keyTemplate, | 365 CK_ATTRIBUTE *keyTemplate, |
400 » » unsigned int templateCount, SECItem *key, void *wincx) | 366 unsigned int templateCount, |
401 { | 367 SECItem *key, void *wincx) { |
402 PK11SymKey * symKey; | 368 PK11SymKey *symKey; |
403 SECStatus» rv; | 369 SECStatus rv; |
404 | 370 |
405 symKey = pk11_CreateSymKey(slot, type, !isToken, PR_TRUE, wincx); | 371 symKey = pk11_CreateSymKey(slot, type, !isToken, PR_TRUE, wincx); |
406 if (symKey == NULL) { | 372 if (symKey == NULL) { |
407 » return NULL; | 373 return NULL; |
408 } | 374 } |
409 | 375 |
410 symKey->size = key->len; | 376 symKey->size = key->len; |
411 | 377 |
412 PK11_SETATTRS(&keyTemplate[templateCount], CKA_VALUE, key->data, key->len); | 378 PK11_SETATTRS(&keyTemplate[templateCount], CKA_VALUE, key->data, key->len); |
413 templateCount++; | 379 templateCount++; |
414 | 380 |
415 if (SECITEM_CopyItem(NULL,&symKey->data,key) != SECSuccess) { | 381 if (SECITEM_CopyItem(NULL, &symKey->data, key) != SECSuccess) { |
416 » PK11_FreeSymKey(symKey); | 382 PK11_FreeSymKey(symKey); |
417 » return NULL; | 383 return NULL; |
418 } | 384 } |
419 | 385 |
420 symKey->origin = origin; | 386 symKey->origin = origin; |
421 | 387 |
422 /* import the keys */ | 388 /* import the keys */ |
423 rv = PK11_CreateNewObject(slot, symKey->session, keyTemplate, | 389 rv = PK11_CreateNewObject(slot, symKey->session, keyTemplate, templateCount, |
424 » » » templateCount, isToken, &symKey->objectID); | 390 isToken, &symKey->objectID); |
425 if ( rv != SECSuccess) { | 391 if (rv != SECSuccess) { |
426 » PK11_FreeSymKey(symKey); | 392 PK11_FreeSymKey(symKey); |
427 » return NULL; | 393 return NULL; |
428 } | 394 } |
429 | 395 |
430 return symKey; | 396 return symKey; |
431 } | 397 } |
432 | 398 |
433 /* | 399 /* |
434 * turn key bits into an appropriate key object | 400 * turn key bits into an appropriate key object |
435 */ | 401 */ |
436 PK11SymKey * | 402 PK11SymKey *PK11_ImportSymKey(PK11SlotInfo *slot, CK_MECHANISM_TYPE type, |
437 PK11_ImportSymKey(PK11SlotInfo *slot, CK_MECHANISM_TYPE type, | 403 PK11Origin origin, CK_ATTRIBUTE_TYPE operation, |
438 PK11Origin origin, CK_ATTRIBUTE_TYPE operation, SECItem *key,void *wincx) | 404 SECItem *key, void *wincx) { |
439 { | 405 PK11SymKey *symKey; |
440 PK11SymKey * symKey; | 406 unsigned int templateCount = 0; |
441 unsigned int templateCount = 0; | 407 CK_OBJECT_CLASS keyClass = CKO_SECRET_KEY; |
442 CK_OBJECT_CLASS keyClass » = CKO_SECRET_KEY; | 408 CK_KEY_TYPE keyType = CKK_GENERIC_SECRET; |
443 CK_KEY_TYPE keyType » = CKK_GENERIC_SECRET; | 409 CK_BBOOL cktrue = CK_TRUE; /* sigh */ |
444 CK_BBOOL cktrue » = CK_TRUE; /* sigh */ | 410 CK_ATTRIBUTE keyTemplate[5]; |
445 CK_ATTRIBUTE keyTemplate[5]; | 411 CK_ATTRIBUTE *attrs = keyTemplate; |
446 CK_ATTRIBUTE * attrs » = keyTemplate; | 412 |
447 | 413 PK11_SETATTRS(attrs, CKA_CLASS, &keyClass, sizeof(keyClass)); |
448 PK11_SETATTRS(attrs, CKA_CLASS, &keyClass, sizeof(keyClass) ); attrs++; | 414 attrs++; |
449 PK11_SETATTRS(attrs, CKA_KEY_TYPE, &keyType, sizeof(keyType) ); attrs++; | 415 PK11_SETATTRS(attrs, CKA_KEY_TYPE, &keyType, sizeof(keyType)); |
450 PK11_SETATTRS(attrs, operation, &cktrue, 1); attrs++; | 416 attrs++; |
451 templateCount = attrs - keyTemplate; | 417 PK11_SETATTRS(attrs, operation, &cktrue, 1); |
452 PR_ASSERT(templateCount+1 <= sizeof(keyTemplate)/sizeof(CK_ATTRIBUTE)); | 418 attrs++; |
453 | 419 templateCount = attrs - keyTemplate; |
454 keyType = PK11_GetKeyType(type,key->len); | 420 PR_ASSERT(templateCount + 1 <= sizeof(keyTemplate) / sizeof(CK_ATTRIBUTE)); |
455 symKey = pk11_ImportSymKeyWithTempl(slot, type, origin, PR_FALSE, | 421 |
456 » » » » keyTemplate, templateCount, key, wincx); | 422 keyType = PK11_GetKeyType(type, key->len); |
457 return symKey; | 423 symKey = pk11_ImportSymKeyWithTempl(slot, type, origin, PR_FALSE, keyTemplate, |
458 } | 424 templateCount, key, wincx); |
459 | 425 return symKey; |
| 426 } |
460 | 427 |
461 /* | 428 /* |
462 * turn key bits into an appropriate key object | 429 * turn key bits into an appropriate key object |
463 */ | 430 */ |
464 PK11SymKey * | 431 PK11SymKey *PK11_ImportSymKeyWithFlags(PK11SlotInfo *slot, |
465 PK11_ImportSymKeyWithFlags(PK11SlotInfo *slot, CK_MECHANISM_TYPE type, | 432 CK_MECHANISM_TYPE type, |
466 PK11Origin origin, CK_ATTRIBUTE_TYPE operation, SECItem *key, | 433 PK11Origin origin, |
467 CK_FLAGS flags, PRBool isPerm, void *wincx) | 434 CK_ATTRIBUTE_TYPE operation, |
468 { | 435 SECItem *key, CK_FLAGS flags, |
469 PK11SymKey * symKey; | 436 PRBool isPerm, void *wincx) { |
470 unsigned int templateCount = 0; | 437 PK11SymKey *symKey; |
471 CK_OBJECT_CLASS keyClass » = CKO_SECRET_KEY; | 438 unsigned int templateCount = 0; |
472 CK_KEY_TYPE keyType » = CKK_GENERIC_SECRET; | 439 CK_OBJECT_CLASS keyClass = CKO_SECRET_KEY; |
473 CK_BBOOL cktrue » = CK_TRUE; /* sigh */ | 440 CK_KEY_TYPE keyType = CKK_GENERIC_SECRET; |
474 CK_ATTRIBUTE keyTemplate[MAX_TEMPL_ATTRS]; | 441 CK_BBOOL cktrue = CK_TRUE; /* sigh */ |
475 CK_ATTRIBUTE * attrs » = keyTemplate; | 442 CK_ATTRIBUTE keyTemplate[MAX_TEMPL_ATTRS]; |
476 | 443 CK_ATTRIBUTE *attrs = keyTemplate; |
477 PK11_SETATTRS(attrs, CKA_CLASS, &keyClass, sizeof(keyClass) ); attrs++; | 444 |
478 PK11_SETATTRS(attrs, CKA_KEY_TYPE, &keyType, sizeof(keyType) ); attrs++; | 445 PK11_SETATTRS(attrs, CKA_CLASS, &keyClass, sizeof(keyClass)); |
479 if (isPerm) { | 446 attrs++; |
480 » PK11_SETATTRS(attrs, CKA_TOKEN, &cktrue, sizeof(cktrue) ); attrs++; | 447 PK11_SETATTRS(attrs, CKA_KEY_TYPE, &keyType, sizeof(keyType)); |
481 » /* sigh some tokens think CKA_PRIVATE = false is a reasonable· | 448 attrs++; |
482 » * default for secret keys */ | 449 if (isPerm) { |
483 » PK11_SETATTRS(attrs, CKA_PRIVATE, &cktrue, sizeof(cktrue) ); attrs++; | 450 PK11_SETATTRS(attrs, CKA_TOKEN, &cktrue, sizeof(cktrue)); |
484 } | 451 attrs++; |
485 attrs += pk11_OpFlagsToAttributes(flags, attrs, &cktrue); | 452 /* sigh some tokens think CKA_PRIVATE = false is a reasonable |
486 if ((operation != CKA_FLAGS_ONLY) && | 453 * default for secret keys */ |
487 » !pk11_FindAttrInTemplate(keyTemplate, attrs-keyTemplate, operation)) { | 454 PK11_SETATTRS(attrs, CKA_PRIVATE, &cktrue, sizeof(cktrue)); |
488 PK11_SETATTRS(attrs, operation, &cktrue, sizeof(cktrue)); attrs++; | 455 attrs++; |
489 } | 456 } |
490 templateCount = attrs - keyTemplate; | 457 attrs += pk11_OpFlagsToAttributes(flags, attrs, &cktrue); |
491 PR_ASSERT(templateCount+1 <= sizeof(keyTemplate)/sizeof(CK_ATTRIBUTE)); | 458 if ((operation != CKA_FLAGS_ONLY) && |
492 | 459 !pk11_FindAttrInTemplate(keyTemplate, attrs - keyTemplate, operation)) { |
493 keyType = PK11_GetKeyType(type,key->len); | 460 PK11_SETATTRS(attrs, operation, &cktrue, sizeof(cktrue)); |
494 symKey = pk11_ImportSymKeyWithTempl(slot, type, origin, isPerm, | 461 attrs++; |
495 » » » » keyTemplate, templateCount, key, wincx); | 462 } |
496 if (symKey && isPerm) { | 463 templateCount = attrs - keyTemplate; |
497 » symKey->owner = PR_FALSE; | 464 PR_ASSERT(templateCount + 1 <= sizeof(keyTemplate) / sizeof(CK_ATTRIBUTE)); |
498 } | 465 |
499 return symKey; | 466 keyType = PK11_GetKeyType(type, key->len); |
500 } | 467 symKey = pk11_ImportSymKeyWithTempl(slot, type, origin, isPerm, keyTemplate, |
501 | 468 templateCount, key, wincx); |
502 | 469 if (symKey && isPerm) { |
503 PK11SymKey * | 470 symKey->owner = PR_FALSE; |
504 PK11_FindFixedKey(PK11SlotInfo *slot, CK_MECHANISM_TYPE type, SECItem *keyID, | 471 } |
505 » » » » » » » » void *wincx) | 472 return symKey; |
506 { | 473 } |
507 CK_ATTRIBUTE findTemp[4]; | 474 |
508 CK_ATTRIBUTE *attrs; | 475 PK11SymKey *PK11_FindFixedKey(PK11SlotInfo *slot, CK_MECHANISM_TYPE type, |
509 CK_BBOOL ckTrue = CK_TRUE; | 476 SECItem *keyID, void *wincx) { |
510 CK_OBJECT_CLASS keyclass = CKO_SECRET_KEY; | 477 CK_ATTRIBUTE findTemp[4]; |
511 int tsize = 0; | 478 CK_ATTRIBUTE *attrs; |
512 CK_OBJECT_HANDLE key_id; | 479 CK_BBOOL ckTrue = CK_TRUE; |
513 | 480 CK_OBJECT_CLASS keyclass = CKO_SECRET_KEY; |
514 attrs = findTemp; | 481 int tsize = 0; |
515 PK11_SETATTRS(attrs, CKA_CLASS, &keyclass, sizeof(keyclass)); attrs++; | 482 CK_OBJECT_HANDLE key_id; |
516 PK11_SETATTRS(attrs, CKA_TOKEN, &ckTrue, sizeof(ckTrue)); attrs++; | 483 |
517 if (keyID) { | 484 attrs = findTemp; |
518 PK11_SETATTRS(attrs, CKA_ID, keyID->data, keyID->len); attrs++; | 485 PK11_SETATTRS(attrs, CKA_CLASS, &keyclass, sizeof(keyclass)); |
519 } | 486 attrs++; |
520 tsize = attrs - findTemp; | 487 PK11_SETATTRS(attrs, CKA_TOKEN, &ckTrue, sizeof(ckTrue)); |
521 PORT_Assert(tsize <= sizeof(findTemp)/sizeof(CK_ATTRIBUTE)); | 488 attrs++; |
522 | 489 if (keyID) { |
523 key_id = pk11_FindObjectByTemplate(slot,findTemp,tsize); | 490 PK11_SETATTRS(attrs, CKA_ID, keyID->data, keyID->len); |
524 if (key_id == CK_INVALID_HANDLE) { | 491 attrs++; |
525 » return NULL; | 492 } |
526 } | 493 tsize = attrs - findTemp; |
527 return PK11_SymKeyFromHandle(slot, NULL, PK11_OriginDerive, type, key_id, | 494 PORT_Assert(tsize <= sizeof(findTemp) / sizeof(CK_ATTRIBUTE)); |
528 » » » » » » PR_FALSE, wincx); | 495 |
529 } | 496 key_id = pk11_FindObjectByTemplate(slot, findTemp, tsize); |
530 | 497 if (key_id == CK_INVALID_HANDLE) { |
531 PK11SymKey * | 498 return NULL; |
532 PK11_ListFixedKeysInSlot(PK11SlotInfo *slot, char *nickname, void *wincx) | 499 } |
533 { | 500 return PK11_SymKeyFromHandle(slot, NULL, PK11_OriginDerive, type, key_id, |
534 CK_ATTRIBUTE findTemp[4]; | 501 PR_FALSE, wincx); |
535 CK_ATTRIBUTE *attrs; | 502 } |
536 CK_BBOOL ckTrue = CK_TRUE; | 503 |
537 CK_OBJECT_CLASS keyclass = CKO_SECRET_KEY; | 504 PK11SymKey *PK11_ListFixedKeysInSlot(PK11SlotInfo *slot, char *nickname, |
538 int tsize = 0; | 505 void *wincx) { |
539 int objCount = 0; | 506 CK_ATTRIBUTE findTemp[4]; |
540 CK_OBJECT_HANDLE *key_ids; | 507 CK_ATTRIBUTE *attrs; |
541 PK11SymKey *nextKey = NULL; | 508 CK_BBOOL ckTrue = CK_TRUE; |
542 PK11SymKey *topKey = NULL; | 509 CK_OBJECT_CLASS keyclass = CKO_SECRET_KEY; |
543 int i,len; | 510 int tsize = 0; |
544 | 511 int objCount = 0; |
545 attrs = findTemp; | 512 CK_OBJECT_HANDLE *key_ids; |
546 PK11_SETATTRS(attrs, CKA_CLASS, &keyclass, sizeof(keyclass)); attrs++; | 513 PK11SymKey *nextKey = NULL; |
547 PK11_SETATTRS(attrs, CKA_TOKEN, &ckTrue, sizeof(ckTrue)); attrs++; | 514 PK11SymKey *topKey = NULL; |
548 if (nickname) { | 515 int i, len; |
549 » len = PORT_Strlen(nickname); | 516 |
550 » PK11_SETATTRS(attrs, CKA_LABEL, nickname, len); attrs++; | 517 attrs = findTemp; |
551 } | 518 PK11_SETATTRS(attrs, CKA_CLASS, &keyclass, sizeof(keyclass)); |
552 tsize = attrs - findTemp; | 519 attrs++; |
553 PORT_Assert(tsize <= sizeof(findTemp)/sizeof(CK_ATTRIBUTE)); | 520 PK11_SETATTRS(attrs, CKA_TOKEN, &ckTrue, sizeof(ckTrue)); |
554 | 521 attrs++; |
555 key_ids = pk11_FindObjectsByTemplate(slot,findTemp,tsize,&objCount); | 522 if (nickname) { |
556 if (key_ids == NULL) { | 523 len = PORT_Strlen(nickname); |
557 » return NULL; | 524 PK11_SETATTRS(attrs, CKA_LABEL, nickname, len); |
558 } | 525 attrs++; |
559 | 526 } |
560 for (i=0; i < objCount ; i++) { | 527 tsize = attrs - findTemp; |
561 » SECItem typeData; | 528 PORT_Assert(tsize <= sizeof(findTemp) / sizeof(CK_ATTRIBUTE)); |
562 » CK_KEY_TYPE type = CKK_GENERIC_SECRET; | 529 |
563 SECStatus rv = PK11_ReadAttribute(slot, key_ids[i], | 530 key_ids = pk11_FindObjectsByTemplate(slot, findTemp, tsize, &objCount); |
564 » » » » » » CKA_KEY_TYPE, NULL, &typeData); | 531 if (key_ids == NULL) { |
565 » if (rv == SECSuccess) { | 532 return NULL; |
566 » if (typeData.len == sizeof(CK_KEY_TYPE)) { | 533 } |
567 » » type = *(CK_KEY_TYPE *)typeData.data; | 534 |
568 » } | 535 for (i = 0; i < objCount; i++) { |
569 » PORT_Free(typeData.data); | 536 SECItem typeData; |
570 » } | 537 CK_KEY_TYPE type = CKK_GENERIC_SECRET; |
571 » nextKey = PK11_SymKeyFromHandle(slot, NULL, PK11_OriginDerive,· | 538 SECStatus rv = |
572 » » PK11_GetKeyMechanism(type), key_ids[i], PR_FALSE, wincx); | 539 PK11_ReadAttribute(slot, key_ids[i], CKA_KEY_TYPE, NULL, &typeData); |
573 » if (nextKey) { | 540 if (rv == SECSuccess) { |
574 » nextKey->next = topKey; | 541 if (typeData.len == sizeof(CK_KEY_TYPE)) { |
575 » topKey = nextKey; | 542 type = *(CK_KEY_TYPE *)typeData.data; |
576 » } | 543 } |
577 } | 544 PORT_Free(typeData.data); |
578 PORT_Free(key_ids); | 545 } |
579 return topKey; | 546 nextKey = PK11_SymKeyFromHandle(slot, NULL, PK11_OriginDerive, |
580 } | 547 PK11_GetKeyMechanism(type), key_ids[i], |
581 | 548 PR_FALSE, wincx); |
582 void * | 549 if (nextKey) { |
583 PK11_GetWindow(PK11SymKey *key) | 550 nextKey->next = topKey; |
584 { | 551 topKey = nextKey; |
585 return key->cx; | 552 } |
586 } | 553 } |
587 ···· | 554 PORT_Free(key_ids); |
| 555 return topKey; |
| 556 } |
| 557 |
| 558 void *PK11_GetWindow(PK11SymKey *key) { return key->cx; } |
588 | 559 |
589 /* | 560 /* |
590 * extract a symetric key value. NOTE: if the key is sensitive, we will | 561 * extract a symetric key value. NOTE: if the key is sensitive, we will |
591 * not be able to do this operation. This function is used to move | 562 * not be able to do this operation. This function is used to move |
592 * keys from one token to another */ | 563 * keys from one token to another */ |
593 SECStatus | 564 SECStatus PK11_ExtractKeyValue(PK11SymKey *symKey) { |
594 PK11_ExtractKeyValue(PK11SymKey *symKey) | 565 SECStatus rv; |
595 { | 566 |
596 SECStatus rv; | 567 if (symKey->data.data != NULL) { |
597 | 568 if (symKey->size == 0) { |
598 if (symKey->data.data != NULL) { | 569 symKey->size = symKey->data.len; |
599 » if (symKey->size == 0) { | 570 } |
600 » symKey->size = symKey->data.len; | |
601 » } | |
602 » return SECSuccess; | |
603 } | |
604 | |
605 if (symKey->slot == NULL) { | |
606 » PORT_SetError( SEC_ERROR_INVALID_KEY ); | |
607 » return SECFailure; | |
608 } | |
609 | |
610 rv = PK11_ReadAttribute(symKey->slot,symKey->objectID,CKA_VALUE,NULL, | |
611 » » » » &symKey->data); | |
612 if (rv == SECSuccess) { | |
613 » symKey->size = symKey->data.len; | |
614 } | |
615 return rv; | |
616 } | |
617 | |
618 SECStatus | |
619 PK11_DeleteTokenSymKey(PK11SymKey *symKey) | |
620 { | |
621 if (!PK11_IsPermObject(symKey->slot, symKey->objectID)) { | |
622 » return SECFailure; | |
623 } | |
624 PK11_DestroyTokenObject(symKey->slot,symKey->objectID); | |
625 symKey->objectID = CK_INVALID_HANDLE; | |
626 return SECSuccess; | 571 return SECSuccess; |
627 } | 572 } |
628 | 573 |
629 SECItem * | 574 if (symKey->slot == NULL) { |
630 PK11_GetKeyData(PK11SymKey *symKey) | 575 PORT_SetError(SEC_ERROR_INVALID_KEY); |
631 { | 576 return SECFailure; |
632 return &symKey->data; | 577 } |
633 } | 578 |
| 579 rv = PK11_ReadAttribute(symKey->slot, symKey->objectID, CKA_VALUE, NULL, |
| 580 &symKey->data); |
| 581 if (rv == SECSuccess) { |
| 582 symKey->size = symKey->data.len; |
| 583 } |
| 584 return rv; |
| 585 } |
| 586 |
| 587 SECStatus PK11_DeleteTokenSymKey(PK11SymKey *symKey) { |
| 588 if (!PK11_IsPermObject(symKey->slot, symKey->objectID)) { |
| 589 return SECFailure; |
| 590 } |
| 591 PK11_DestroyTokenObject(symKey->slot, symKey->objectID); |
| 592 symKey->objectID = CK_INVALID_HANDLE; |
| 593 return SECSuccess; |
| 594 } |
| 595 |
| 596 SECItem *PK11_GetKeyData(PK11SymKey *symKey) { return &symKey->data; } |
634 | 597 |
635 /* This symbol is exported for backward compatibility. */ | 598 /* This symbol is exported for backward compatibility. */ |
636 SECItem * | 599 SECItem *__PK11_GetKeyData(PK11SymKey *symKey) { |
637 __PK11_GetKeyData(PK11SymKey *symKey) | 600 return PK11_GetKeyData(symKey); |
638 { | 601 } |
639 return PK11_GetKeyData(symKey); | |
640 } | |
641 | |
642 | 602 |
643 /* | 603 /* |
644 * PKCS #11 key Types with predefined length | 604 * PKCS #11 key Types with predefined length |
645 */ | 605 */ |
646 unsigned int | 606 unsigned int pk11_GetPredefinedKeyLength(CK_KEY_TYPE keyType) { |
647 pk11_GetPredefinedKeyLength(CK_KEY_TYPE keyType) | 607 int length = 0; |
648 { | 608 switch (keyType) { |
649 int length = 0; | 609 case CKK_DES: |
650 switch (keyType) { | 610 length = 8; |
651 case CKK_DES: length = 8; break; | 611 break; |
652 case CKK_DES2: length = 16; break; | 612 case CKK_DES2: |
653 case CKK_DES3: length = 24; break; | 613 length = 16; |
654 case CKK_SKIPJACK: length = 10; break; | 614 break; |
655 case CKK_BATON: length = 20; break; | 615 case CKK_DES3: |
656 case CKK_JUNIPER: length = 20; break; | 616 length = 24; |
657 default: break; | 617 break; |
658 } | 618 case CKK_SKIPJACK: |
659 return length; | 619 length = 10; |
| 620 break; |
| 621 case CKK_BATON: |
| 622 length = 20; |
| 623 break; |
| 624 case CKK_JUNIPER: |
| 625 length = 20; |
| 626 break; |
| 627 default: |
| 628 break; |
| 629 } |
| 630 return length; |
660 } | 631 } |
661 | 632 |
662 /* return the keylength if possible. '0' if not */ | 633 /* return the keylength if possible. '0' if not */ |
663 unsigned int | 634 unsigned int PK11_GetKeyLength(PK11SymKey *key) { |
664 PK11_GetKeyLength(PK11SymKey *key) | 635 CK_KEY_TYPE keyType; |
665 { | 636 |
666 CK_KEY_TYPE keyType; | 637 if (key->size != 0) return key->size; |
667 | 638 |
668 if (key->size != 0) return key->size; | 639 /* First try to figure out the key length from its type */ |
669 | 640 keyType = PK11_ReadULongAttribute(key->slot, key->objectID, CKA_KEY_TYPE); |
670 /* First try to figure out the key length from its type */ | 641 key->size = pk11_GetPredefinedKeyLength(keyType); |
671 keyType = PK11_ReadULongAttribute(key->slot,key->objectID,CKA_KEY_TYPE); | 642 if ((keyType == CKK_GENERIC_SECRET) && |
672 key->size = pk11_GetPredefinedKeyLength(keyType); | 643 (key->type == CKM_SSL3_PRE_MASTER_KEY_GEN)) { |
673 if ((keyType == CKK_GENERIC_SECRET) && | 644 key->size = 48; |
674 » (key->type == CKM_SSL3_PRE_MASTER_KEY_GEN)) { | 645 } |
675 » key->size=48; | 646 |
676 } | 647 if (key->size != 0) return key->size; |
677 | 648 |
678 if( key->size != 0 ) return key->size; | 649 if (key->data.data == NULL) { |
679 | 650 PK11_ExtractKeyValue(key); |
680 if (key->data.data == NULL) { | 651 } |
681 » PK11_ExtractKeyValue(key); | 652 /* key is probably secret. Look up its length */ |
682 } | 653 /* this is new PKCS #11 version 2.0 functionality. */ |
683 /* key is probably secret. Look up its length */ | 654 if (key->size == 0) { |
684 /* this is new PKCS #11 version 2.0 functionality. */ | 655 CK_ULONG keyLength; |
685 if (key->size == 0) { | 656 |
686 » CK_ULONG keyLength; | 657 keyLength = |
687 | 658 PK11_ReadULongAttribute(key->slot, key->objectID, CKA_VALUE_LEN); |
688 » keyLength = PK11_ReadULongAttribute(key->slot,key->objectID,CKA_VALUE_LE
N); | 659 if (keyLength != CK_UNAVAILABLE_INFORMATION) { |
689 » if (keyLength != CK_UNAVAILABLE_INFORMATION) { | 660 key->size = (unsigned int)keyLength; |
690 » key->size = (unsigned int)keyLength; | 661 } |
691 » } | 662 } |
692 } | 663 |
693 | 664 return key->size; |
694 return key->size; | |
695 } | 665 } |
696 | 666 |
697 /* return the strength of a key. This is different from length in that | 667 /* return the strength of a key. This is different from length in that |
698 * 1) it returns the size in bits, and 2) it returns only the secret portions | 668 * 1) it returns the size in bits, and 2) it returns only the secret portions |
699 * of the key minus any checksums or parity. | 669 * of the key minus any checksums or parity. |
700 */ | 670 */ |
701 unsigned int | 671 unsigned int PK11_GetKeyStrength(PK11SymKey *key, SECAlgorithmID *algid) { |
702 PK11_GetKeyStrength(PK11SymKey *key, SECAlgorithmID *algid) | 672 int size = 0; |
703 { | 673 CK_MECHANISM_TYPE mechanism = CKM_INVALID_MECHANISM; /* RC2 only */ |
704 int size=0; | 674 SECItem *param = NULL; /* RC2 only */ |
705 CK_MECHANISM_TYPE mechanism= CKM_INVALID_MECHANISM; /* RC2 only */ | 675 CK_RC2_CBC_PARAMS *rc2_params = NULL; /* RC2 ONLY */ |
706 SECItem *param = NULL; /* RC2 only */ | 676 unsigned int effectiveBits = 0; /* RC2 ONLY */ |
707 CK_RC2_CBC_PARAMS *rc2_params = NULL; /* RC2 ONLY */ | 677 |
708 unsigned int effectiveBits = 0; /* RC2 ONLY */ | 678 switch (PK11_GetKeyType(key->type, 0)) { |
709 | 679 case CKK_CDMF: |
710 switch (PK11_GetKeyType(key->type,0)) { | 680 return 40; |
711 case CKK_CDMF: | 681 case CKK_DES: |
712 » return 40; | 682 return 56; |
713 case CKK_DES: | 683 case CKK_DES3: |
714 » return 56; | 684 case CKK_DES2: |
715 case CKK_DES3: | 685 size = PK11_GetKeyLength(key); |
716 case CKK_DES2: | 686 if (size == 16) { |
717 » size = PK11_GetKeyLength(key); | 687 /* double des */ |
718 » if (size == 16) { | 688 return 112; /* 16*7 */ |
719 » /* double des */ | 689 } |
720 » return 112; /* 16*7 */ | 690 return 168; |
721 » } | |
722 » return 168; | |
723 /* | 691 /* |
724 * RC2 has is different than other ciphers in that it allows the user | 692 * RC2 has is different than other ciphers in that it allows the user |
725 * to deprecating keysize while still requiring all the bits for the | 693 * to deprecating keysize while still requiring all the bits for the |
726 * original key. The info | 694 * original key. The info |
727 * on what the effective key strength is in the parameter for the key. | 695 * on what the effective key strength is in the parameter for the key. |
728 * In S/MIME this parameter is stored in the DER encoded algid. In Our | 696 * In S/MIME this parameter is stored in the DER encoded algid. In Our |
729 * other uses of RC2, effectiveBits == keyBits, so this code functions | 697 * other uses of RC2, effectiveBits == keyBits, so this code functions |
730 * correctly without an algid. | 698 * correctly without an algid. |
731 */ | 699 */ |
732 case CKK_RC2: | 700 case CKK_RC2: |
733 » /* if no algid was provided, fall through to default */ | 701 /* if no algid was provided, fall through to default */ |
734 if (!algid) { | 702 if (!algid) { |
735 » break;· | 703 break; |
736 » } | 704 } |
737 » /* verify that the algid is for RC2 */ | 705 /* verify that the algid is for RC2 */ |
738 » mechanism = PK11_AlgtagToMechanism(SECOID_GetAlgorithmTag(algid)); | 706 mechanism = PK11_AlgtagToMechanism(SECOID_GetAlgorithmTag(algid)); |
739 » if ((mechanism != CKM_RC2_CBC) && (mechanism != CKM_RC2_ECB)) { | 707 if ((mechanism != CKM_RC2_CBC) && (mechanism != CKM_RC2_ECB)) { |
740 » break; | 708 break; |
741 » } | 709 } |
742 | 710 |
743 » /* now get effective bits from the algorithm ID. */ | 711 /* now get effective bits from the algorithm ID. */ |
744 » param = PK11_ParamFromAlgid(algid); | 712 param = PK11_ParamFromAlgid(algid); |
745 » /* if we couldn't get memory just use key length */ | 713 /* if we couldn't get memory just use key length */ |
746 » if (param == NULL) { | 714 if (param == NULL) { |
747 » break; | 715 break; |
748 » } | 716 } |
749 | 717 |
750 » rc2_params = (CK_RC2_CBC_PARAMS *) param->data; | 718 rc2_params = (CK_RC2_CBC_PARAMS *)param->data; |
751 » /* paranoia... shouldn't happen */ | 719 /* paranoia... shouldn't happen */ |
752 » PORT_Assert(param->data != NULL); | 720 PORT_Assert(param->data != NULL); |
753 » if (param->data == NULL) { | 721 if (param->data == NULL) { |
754 » SECITEM_FreeItem(param,PR_TRUE); | 722 SECITEM_FreeItem(param, PR_TRUE); |
755 » break; | 723 break; |
756 » } | 724 } |
757 » effectiveBits = (unsigned int)rc2_params->ulEffectiveBits; | 725 effectiveBits = (unsigned int)rc2_params->ulEffectiveBits; |
758 » SECITEM_FreeItem(param,PR_TRUE); | 726 SECITEM_FreeItem(param, PR_TRUE); |
759 » param = NULL; rc2_params=NULL; /* paranoia */ | 727 param = NULL; |
760 | 728 rc2_params = NULL; /* paranoia */ |
761 » /* we have effective bits, is and allocated memory is free, now | 729 |
762 » * we need to return the smaller of effective bits and keysize */ | 730 /* we have effective bits, is and allocated memory is free, now |
763 » size = PK11_GetKeyLength(key); | 731 * we need to return the smaller of effective bits and keysize */ |
764 » if ((unsigned int)size*8 > effectiveBits) { | 732 size = PK11_GetKeyLength(key); |
765 » return effectiveBits; | 733 if ((unsigned int)size * 8 > effectiveBits) { |
766 » } | 734 return effectiveBits; |
767 | 735 } |
768 » return size*8; /* the actual key is smaller, the strength can't be | 736 |
769 » » » * greater than the actual key size */ | 737 return size * 8; /* the actual key is smaller, the strength can't be |
770 »······· | 738 * greater than the actual key size */ |
| 739 |
771 default: | 740 default: |
772 » break; | 741 break; |
773 } | 742 } |
774 return PK11_GetKeyLength(key) * 8; | 743 return PK11_GetKeyLength(key) * 8; |
775 } | 744 } |
776 | 745 |
777 /* | 746 /* |
778 * The next three utilities are to deal with the fact that a given operation | 747 * The next three utilities are to deal with the fact that a given operation |
779 * may be a multi-slot affair. This creates a new key object that is copied | 748 * may be a multi-slot affair. This creates a new key object that is copied |
780 * into the new slot. | 749 * into the new slot. |
781 */ | 750 */ |
782 PK11SymKey * | 751 PK11SymKey *pk11_CopyToSlotPerm(PK11SlotInfo *slot, CK_MECHANISM_TYPE type, |
783 pk11_CopyToSlotPerm(PK11SlotInfo *slot,CK_MECHANISM_TYPE type,· | 752 CK_ATTRIBUTE_TYPE operation, CK_FLAGS flags, |
784 » » CK_ATTRIBUTE_TYPE operation, CK_FLAGS flags,· | 753 PRBool isPerm, PK11SymKey *symKey) { |
785 » » PRBool isPerm, PK11SymKey *symKey) | 754 SECStatus rv; |
786 { | 755 PK11SymKey *newKey = NULL; |
787 SECStatus rv; | 756 |
788 PK11SymKey *newKey = NULL; | 757 /* Extract the raw key data if possible */ |
789 | 758 if (symKey->data.data == NULL) { |
790 /* Extract the raw key data if possible */ | 759 rv = PK11_ExtractKeyValue(symKey); |
791 if (symKey->data.data == NULL) { | 760 /* KEY is sensitive, we're try key exchanging it. */ |
792 » rv = PK11_ExtractKeyValue(symKey); | 761 if (rv != SECSuccess) { |
793 » /* KEY is sensitive, we're try key exchanging it. */ | 762 return pk11_KeyExchange(slot, type, operation, flags, isPerm, symKey); |
794 » if (rv != SECSuccess) { | 763 } |
795 » return pk11_KeyExchange(slot, type, operation, | 764 } |
796 » » » » » » flags, isPerm, symKey); | 765 |
797 » } | 766 newKey = PK11_ImportSymKeyWithFlags(slot, type, symKey->origin, operation, |
798 } | 767 &symKey->data, flags, isPerm, symKey->cx); |
799 | 768 if (newKey == NULL) { |
800 newKey = PK11_ImportSymKeyWithFlags(slot, type, symKey->origin, | 769 newKey = pk11_KeyExchange(slot, type, operation, flags, isPerm, symKey); |
801 » operation, &symKey->data, flags, isPerm, symKey->cx); | 770 } |
802 if (newKey == NULL) { | 771 return newKey; |
803 » newKey = pk11_KeyExchange(slot, type, operation, flags, isPerm, symKey); | 772 } |
804 } | 773 |
805 return newKey; | 774 PK11SymKey *pk11_CopyToSlot(PK11SlotInfo *slot, CK_MECHANISM_TYPE type, |
806 } | 775 CK_ATTRIBUTE_TYPE operation, PK11SymKey *symKey) { |
807 | 776 return pk11_CopyToSlotPerm(slot, type, operation, 0, PR_FALSE, symKey); |
808 PK11SymKey * | |
809 pk11_CopyToSlot(PK11SlotInfo *slot,CK_MECHANISM_TYPE type, | |
810 » CK_ATTRIBUTE_TYPE operation, PK11SymKey *symKey) | |
811 { | |
812 return pk11_CopyToSlotPerm(slot, type, operation, 0, PR_FALSE, symKey); | |
813 } | 777 } |
814 | 778 |
815 /* | 779 /* |
816 * Make sure the slot we are in is the correct slot for the operation | 780 * Make sure the slot we are in is the correct slot for the operation |
817 * by verifying that it supports all of the specified mechanism types. | 781 * by verifying that it supports all of the specified mechanism types. |
818 */ | 782 */ |
819 PK11SymKey * | 783 PK11SymKey *pk11_ForceSlotMultiple(PK11SymKey *symKey, CK_MECHANISM_TYPE *type, |
820 pk11_ForceSlotMultiple(PK11SymKey *symKey, CK_MECHANISM_TYPE *type, | 784 int mechCount, CK_ATTRIBUTE_TYPE operation) { |
821 » » » int mechCount, CK_ATTRIBUTE_TYPE operation) | 785 PK11SlotInfo *slot = symKey->slot; |
822 { | 786 PK11SymKey *newKey = NULL; |
823 PK11SlotInfo *slot = symKey->slot; | 787 PRBool needToCopy = PR_FALSE; |
824 PK11SymKey *newKey = NULL; | 788 int i; |
825 PRBool needToCopy = PR_FALSE; | 789 |
826 int i; | 790 if (slot == NULL) { |
827 | 791 needToCopy = PR_TRUE; |
| 792 } else { |
| 793 i = 0; |
| 794 while ((i < mechCount) && (needToCopy == PR_FALSE)) { |
| 795 if (!PK11_DoesMechanism(slot, type[i])) { |
| 796 needToCopy = PR_TRUE; |
| 797 } |
| 798 i++; |
| 799 } |
| 800 } |
| 801 |
| 802 if (needToCopy == PR_TRUE) { |
| 803 slot = PK11_GetBestSlotMultiple(type, mechCount, symKey->cx); |
828 if (slot == NULL) { | 804 if (slot == NULL) { |
829 » needToCopy = PR_TRUE; | 805 PORT_SetError(SEC_ERROR_NO_MODULE); |
| 806 return NULL; |
| 807 } |
| 808 newKey = pk11_CopyToSlot(slot, type[0], operation, symKey); |
| 809 PK11_FreeSlot(slot); |
| 810 } |
| 811 return newKey; |
| 812 } |
| 813 |
| 814 /* |
| 815 * Make sure the slot we are in is the correct slot for the operation |
| 816 */ |
| 817 PK11SymKey *pk11_ForceSlot(PK11SymKey *symKey, CK_MECHANISM_TYPE type, |
| 818 CK_ATTRIBUTE_TYPE operation) { |
| 819 return pk11_ForceSlotMultiple(symKey, &type, 1, operation); |
| 820 } |
| 821 |
| 822 PK11SymKey *PK11_MoveSymKey(PK11SlotInfo *slot, CK_ATTRIBUTE_TYPE operation, |
| 823 CK_FLAGS flags, PRBool perm, PK11SymKey *symKey) { |
| 824 if (symKey->slot == slot) { |
| 825 if (perm) { |
| 826 return PK11_ConvertSessionSymKeyToTokenSymKey(symKey, symKey->cx); |
830 } else { | 827 } else { |
831 » i = 0; | 828 return PK11_ReferenceSymKey(symKey); |
832 » while ((i < mechCount) && (needToCopy == PR_FALSE)) { | 829 } |
833 » if (!PK11_DoesMechanism(slot,type[i])) { | 830 } |
834 » » needToCopy = PR_TRUE; | 831 |
835 » } | 832 return pk11_CopyToSlotPerm(slot, symKey->type, operation, flags, perm, |
836 » i++; | 833 symKey); |
837 » } | 834 } |
838 } | 835 |
839 | 836 /* |
840 if (needToCopy == PR_TRUE) { | 837 * Use the token to generate a key. |
841 » slot = PK11_GetBestSlotMultiple(type,mechCount,symKey->cx); | 838 * |
842 » if (slot == NULL) { | 839 * keySize must be 'zero' for fixed key length algorithms. A nonzero |
843 » PORT_SetError( SEC_ERROR_NO_MODULE ); | 840 * keySize causes the CKA_VALUE_LEN attribute to be added to the template |
844 » return NULL; | 841 * for the key. Most PKCS #11 modules fail if you specify the CKA_VALUE_LEN |
845 » } | |
846 » newKey = pk11_CopyToSlot(slot, type[0], operation, symKey); | |
847 » PK11_FreeSlot(slot); | |
848 } | |
849 return newKey; | |
850 } | |
851 | |
852 /* | |
853 * Make sure the slot we are in is the correct slot for the operation | |
854 */ | |
855 PK11SymKey * | |
856 pk11_ForceSlot(PK11SymKey *symKey,CK_MECHANISM_TYPE type, | |
857 » » » » » » CK_ATTRIBUTE_TYPE operation) | |
858 { | |
859 return pk11_ForceSlotMultiple(symKey, &type, 1, operation); | |
860 } | |
861 | |
862 PK11SymKey * | |
863 PK11_MoveSymKey(PK11SlotInfo *slot, CK_ATTRIBUTE_TYPE operation,· | |
864 » » » CK_FLAGS flags, PRBool perm, PK11SymKey *symKey) | |
865 { | |
866 if (symKey->slot == slot) { | |
867 » if (perm) { | |
868 » return PK11_ConvertSessionSymKeyToTokenSymKey(symKey,symKey->cx); | |
869 » } else { | |
870 » return PK11_ReferenceSymKey(symKey); | |
871 » } | |
872 } | |
873 ···· | |
874 return pk11_CopyToSlotPerm(slot, symKey->type,· | |
875 » » » » » operation, flags, perm, symKey); | |
876 } | |
877 | |
878 /* | |
879 * Use the token to generate a key.· | |
880 *· | |
881 * keySize must be 'zero' for fixed key length algorithms. A nonzero· | |
882 * keySize causes the CKA_VALUE_LEN attribute to be added to the template· | |
883 * for the key. Most PKCS #11 modules fail if you specify the CKA_VALUE_LEN· | |
884 * attribute for keys with fixed length. The exception is DES2. If you | 842 * attribute for keys with fixed length. The exception is DES2. If you |
885 * select a CKM_DES3_CBC mechanism, this code will not add the CKA_VALUE_LEN | 843 * select a CKM_DES3_CBC mechanism, this code will not add the CKA_VALUE_LEN |
886 * parameter and use the key size to determine which underlying DES keygen | 844 * parameter and use the key size to determine which underlying DES keygen |
887 * function to use (CKM_DES2_KEY_GEN or CKM_DES3_KEY_GEN). | 845 * function to use (CKM_DES2_KEY_GEN or CKM_DES3_KEY_GEN). |
888 * | 846 * |
889 * keyType must be -1 for most algorithms. Some PBE algorthims cannot | 847 * keyType must be -1 for most algorithms. Some PBE algorthims cannot |
890 * determine the correct key type from the mechanism or the parameters, | 848 * determine the correct key type from the mechanism or the parameters, |
891 * so key type must be specified. Other PKCS #11 mechanisms may do so in | 849 * so key type must be specified. Other PKCS #11 mechanisms may do so in |
892 * the future. Currently there is no need to export this publically. | 850 * the future. Currently there is no need to export this publically. |
893 * Keep it private until there is a need in case we need to expand the | 851 * Keep it private until there is a need in case we need to expand the |
894 * keygen parameters again... | 852 * keygen parameters again... |
895 * | 853 * |
896 * CK_FLAGS flags: key operation flags | 854 * CK_FLAGS flags: key operation flags |
897 * PK11AttrFlags attrFlags: PK11_ATTR_XXX key attribute flags | 855 * PK11AttrFlags attrFlags: PK11_ATTR_XXX key attribute flags |
898 */ | 856 */ |
899 PK11SymKey * | 857 PK11SymKey *pk11_TokenKeyGenWithFlagsAndKeyType( |
900 pk11_TokenKeyGenWithFlagsAndKeyType(PK11SlotInfo *slot, CK_MECHANISM_TYPE type, | 858 PK11SlotInfo *slot, CK_MECHANISM_TYPE type, SECItem *param, |
901 SECItem *param, CK_KEY_TYPE keyType, int keySize, SECItem *keyid, | 859 CK_KEY_TYPE keyType, int keySize, SECItem *keyid, CK_FLAGS opFlags, |
902 CK_FLAGS opFlags, PK11AttrFlags attrFlags, void *wincx) | 860 PK11AttrFlags attrFlags, void *wincx) { |
903 { | 861 PK11SymKey *symKey; |
904 PK11SymKey *symKey; | 862 CK_ATTRIBUTE genTemplate[MAX_TEMPL_ATTRS]; |
905 CK_ATTRIBUTE genTemplate[MAX_TEMPL_ATTRS]; | 863 CK_ATTRIBUTE *attrs = genTemplate; |
906 CK_ATTRIBUTE *attrs = genTemplate; | 864 int count = sizeof(genTemplate) / sizeof(genTemplate[0]); |
907 int count = sizeof(genTemplate)/sizeof(genTemplate[0]); | 865 CK_MECHANISM_TYPE keyGenType; |
908 CK_MECHANISM_TYPE keyGenType; | 866 CK_BBOOL cktrue = CK_TRUE; |
909 CK_BBOOL cktrue = CK_TRUE; | 867 CK_BBOOL ckfalse = CK_FALSE; |
910 CK_BBOOL ckfalse = CK_FALSE; | 868 CK_ULONG ck_key_size; /* only used for variable-length keys */ |
911 CK_ULONG ck_key_size; /* only used for variable-length keys */ | 869 |
912 | 870 if (pk11_BadAttrFlags(attrFlags)) { |
913 if (pk11_BadAttrFlags(attrFlags)) { | 871 PORT_SetError(SEC_ERROR_INVALID_ARGS); |
914 » PORT_SetError( SEC_ERROR_INVALID_ARGS ); | 872 return NULL; |
915 » return NULL; | 873 } |
916 } | 874 |
917 | 875 if ((keySize != 0) && (type != CKM_DES3_CBC) && (type != CKM_DES3_CBC_PAD) && |
918 if ((keySize != 0) && (type != CKM_DES3_CBC) && | 876 (type != CKM_DES3_ECB)) { |
919 » » (type !=CKM_DES3_CBC_PAD) && (type != CKM_DES3_ECB)) { | 877 ck_key_size = keySize; /* Convert to PK11 type */ |
920 ck_key_size = keySize; /* Convert to PK11 type */ | 878 |
921 | 879 PK11_SETATTRS(attrs, CKA_VALUE_LEN, &ck_key_size, sizeof(ck_key_size)); |
922 PK11_SETATTRS(attrs, CKA_VALUE_LEN, &ck_key_size, sizeof(ck_key_size));· | 880 attrs++; |
923 » » » » » » » attrs++; | 881 } |
924 } | 882 |
925 | 883 if (keyType != -1) { |
926 if (keyType != -1) { | 884 PK11_SETATTRS(attrs, CKA_KEY_TYPE, &keyType, sizeof(CK_KEY_TYPE)); |
927 PK11_SETATTRS(attrs, CKA_KEY_TYPE, &keyType, sizeof(CK_KEY_TYPE));· | 885 attrs++; |
928 » » » » » » » attrs++; | 886 } |
929 } | 887 |
930 | 888 /* Include key id value if provided */ |
931 /* Include key id value if provided */ | 889 if (keyid) { |
932 if (keyid) { | 890 PK11_SETATTRS(attrs, CKA_ID, keyid->data, keyid->len); |
933 PK11_SETATTRS(attrs, CKA_ID, keyid->data, keyid->len); attrs++; | 891 attrs++; |
934 } | 892 } |
935 | 893 |
936 attrs += pk11_AttrFlagsToAttributes(attrFlags, attrs, &cktrue, &ckfalse); | 894 attrs += pk11_AttrFlagsToAttributes(attrFlags, attrs, &cktrue, &ckfalse); |
937 attrs += pk11_OpFlagsToAttributes(opFlags, attrs, &cktrue); | 895 attrs += pk11_OpFlagsToAttributes(opFlags, attrs, &cktrue); |
938 | 896 |
939 count = attrs - genTemplate; | 897 count = attrs - genTemplate; |
940 PR_ASSERT(count <= sizeof(genTemplate)/sizeof(CK_ATTRIBUTE)); | 898 PR_ASSERT(count <= sizeof(genTemplate) / sizeof(CK_ATTRIBUTE)); |
941 | 899 |
942 keyGenType = PK11_GetKeyGenWithSize(type, keySize); | 900 keyGenType = PK11_GetKeyGenWithSize(type, keySize); |
943 if (keyGenType == CKM_FAKE_RANDOM) { | 901 if (keyGenType == CKM_FAKE_RANDOM) { |
944 PORT_SetError( SEC_ERROR_NO_MODULE ); | 902 PORT_SetError(SEC_ERROR_NO_MODULE); |
945 return NULL; | 903 return NULL; |
946 } | 904 } |
947 symKey = PK11_KeyGenWithTemplate(slot, type, keyGenType, | 905 symKey = PK11_KeyGenWithTemplate(slot, type, keyGenType, param, genTemplate, |
948 param, genTemplate, count, wincx); | 906 count, wincx); |
949 if (symKey != NULL) { | 907 if (symKey != NULL) { |
950 symKey->size = keySize; | 908 symKey->size = keySize; |
951 } | 909 } |
952 return symKey; | 910 return symKey; |
953 } | 911 } |
954 | 912 |
955 /* | 913 /* |
956 * Use the token to generate a key. - Public | 914 * Use the token to generate a key. - Public |
957 * | 915 * |
958 * keySize must be 'zero' for fixed key length algorithms. A nonzero | 916 * keySize must be 'zero' for fixed key length algorithms. A nonzero |
959 * keySize causes the CKA_VALUE_LEN attribute to be added to the template | 917 * keySize causes the CKA_VALUE_LEN attribute to be added to the template |
960 * for the key. Most PKCS #11 modules fail if you specify the CKA_VALUE_LEN | 918 * for the key. Most PKCS #11 modules fail if you specify the CKA_VALUE_LEN |
961 * attribute for keys with fixed length. The exception is DES2. If you | 919 * attribute for keys with fixed length. The exception is DES2. If you |
962 * select a CKM_DES3_CBC mechanism, this code will not add the CKA_VALUE_LEN | 920 * select a CKM_DES3_CBC mechanism, this code will not add the CKA_VALUE_LEN |
963 * parameter and use the key size to determine which underlying DES keygen | 921 * parameter and use the key size to determine which underlying DES keygen |
964 * function to use (CKM_DES2_KEY_GEN or CKM_DES3_KEY_GEN). | 922 * function to use (CKM_DES2_KEY_GEN or CKM_DES3_KEY_GEN). |
965 * | 923 * |
966 * CK_FLAGS flags: key operation flags | 924 * CK_FLAGS flags: key operation flags |
967 * PK11AttrFlags attrFlags: PK11_ATTR_XXX key attribute flags | 925 * PK11AttrFlags attrFlags: PK11_ATTR_XXX key attribute flags |
968 */ | 926 */ |
969 PK11SymKey * | 927 PK11SymKey *PK11_TokenKeyGenWithFlags(PK11SlotInfo *slot, |
970 PK11_TokenKeyGenWithFlags(PK11SlotInfo *slot, CK_MECHANISM_TYPE type, | 928 CK_MECHANISM_TYPE type, SECItem *param, |
971 SECItem *param, int keySize, SECItem *keyid, CK_FLAGS opFlags, | 929 int keySize, SECItem *keyid, |
972 PK11AttrFlags attrFlags, void *wincx) | 930 CK_FLAGS opFlags, PK11AttrFlags attrFlags, |
973 { | 931 void *wincx) { |
974 return pk11_TokenKeyGenWithFlagsAndKeyType(slot, type, param, -1, keySize,· | 932 return pk11_TokenKeyGenWithFlagsAndKeyType(slot, type, param, -1, keySize, |
975 » keyid, opFlags, attrFlags, wincx); | 933 keyid, opFlags, attrFlags, wincx); |
976 } | 934 } |
977 | 935 |
978 /* | 936 /* |
979 * Use the token to generate a key. keySize must be 'zero' for fixed key | 937 * Use the token to generate a key. keySize must be 'zero' for fixed key |
980 * length algorithms. A nonzero keySize causes the CKA_VALUE_LEN attribute | 938 * length algorithms. A nonzero keySize causes the CKA_VALUE_LEN attribute |
981 * to be added to the template for the key. PKCS #11 modules fail if you | 939 * to be added to the template for the key. PKCS #11 modules fail if you |
982 * specify the CKA_VALUE_LEN attribute for keys with fixed length. | 940 * specify the CKA_VALUE_LEN attribute for keys with fixed length. |
983 * NOTE: this means to generate a DES2 key from this interface you must | 941 * NOTE: this means to generate a DES2 key from this interface you must |
984 * specify CKM_DES2_KEY_GEN as the mechanism directly; specifying | 942 * specify CKM_DES2_KEY_GEN as the mechanism directly; specifying |
985 * CKM_DES3_CBC as the mechanism and 16 as keySize currently doesn't work. | 943 * CKM_DES3_CBC as the mechanism and 16 as keySize currently doesn't work. |
986 */ | 944 */ |
987 PK11SymKey * | 945 PK11SymKey *PK11_TokenKeyGen(PK11SlotInfo *slot, CK_MECHANISM_TYPE type, |
988 PK11_TokenKeyGen(PK11SlotInfo *slot, CK_MECHANISM_TYPE type, SECItem *param, | 946 SECItem *param, int keySize, SECItem *keyid, |
989 int keySize, SECItem *keyid, PRBool isToken, void *wincx) | 947 PRBool isToken, void *wincx) { |
990 { | 948 PK11SymKey *symKey; |
991 PK11SymKey *symKey; | 949 PRBool weird = PR_FALSE; /* hack for fortezza */ |
992 PRBool weird = PR_FALSE; /* hack for fortezza */ | 950 CK_FLAGS opFlags = CKF_SIGN; |
993 CK_FLAGS opFlags = CKF_SIGN; | 951 PK11AttrFlags attrFlags = 0; |
994 PK11AttrFlags attrFlags = 0; | 952 |
995 | 953 if ((keySize == -1) && (type == CKM_SKIPJACK_CBC64)) { |
996 if ((keySize == -1) && (type == CKM_SKIPJACK_CBC64)) { | 954 weird = PR_TRUE; |
997 » weird = PR_TRUE; | 955 keySize = 0; |
998 » keySize = 0; | 956 } |
999 } | 957 |
1000 | 958 opFlags |= weird ? CKF_DECRYPT : CKF_ENCRYPT; |
1001 opFlags |= weird ? CKF_DECRYPT : CKF_ENCRYPT; | 959 |
1002 | 960 if (isToken) { |
1003 if (isToken) { | 961 attrFlags |= (PK11_ATTR_TOKEN | PK11_ATTR_PRIVATE); |
1004 » attrFlags |= (PK11_ATTR_TOKEN | PK11_ATTR_PRIVATE); | 962 } |
1005 } | 963 |
1006 | 964 symKey = pk11_TokenKeyGenWithFlagsAndKeyType( |
1007 symKey = pk11_TokenKeyGenWithFlagsAndKeyType(slot, type, param, | 965 slot, type, param, -1, keySize, keyid, opFlags, attrFlags, wincx); |
1008 » » » -1, keySize, keyid, opFlags, attrFlags, wincx); | 966 if (symKey && weird) { |
1009 if (symKey && weird) { | 967 PK11_SetFortezzaHack(symKey); |
1010 » PK11_SetFortezzaHack(symKey); | 968 } |
1011 } | 969 |
1012 | 970 return symKey; |
1013 return symKey; | 971 } |
1014 } | 972 |
1015 | 973 PK11SymKey *PK11_KeyGen(PK11SlotInfo *slot, CK_MECHANISM_TYPE type, |
1016 PK11SymKey * | 974 SECItem *param, int keySize, void *wincx) { |
1017 PK11_KeyGen(PK11SlotInfo *slot, CK_MECHANISM_TYPE type, SECItem *param, | 975 return PK11_TokenKeyGen(slot, type, param, keySize, 0, PR_FALSE, wincx); |
1018 » » » » » » int keySize, void *wincx) | 976 } |
1019 { | 977 |
1020 return PK11_TokenKeyGen(slot, type, param, keySize, 0, PR_FALSE, wincx); | 978 PK11SymKey *PK11_KeyGenWithTemplate(PK11SlotInfo *slot, CK_MECHANISM_TYPE type, |
1021 } | 979 CK_MECHANISM_TYPE keyGenType, |
1022 | 980 SECItem *param, CK_ATTRIBUTE *attrs, |
1023 PK11SymKey * | 981 unsigned int attrsCount, void *wincx) { |
1024 PK11_KeyGenWithTemplate(PK11SlotInfo *slot, CK_MECHANISM_TYPE type, | 982 PK11SymKey *symKey; |
1025 CK_MECHANISM_TYPE keyGenType, | 983 CK_SESSION_HANDLE session; |
1026 SECItem *param, CK_ATTRIBUTE * attrs, | 984 CK_MECHANISM mechanism; |
1027 unsigned int attrsCount, void *wincx) | 985 CK_RV crv; |
1028 { | 986 PRBool isToken = CK_FALSE; |
1029 PK11SymKey *symKey; | 987 CK_ULONG keySize = 0; |
1030 CK_SESSION_HANDLE session; | 988 unsigned i; |
1031 CK_MECHANISM mechanism; | 989 |
1032 CK_RV crv; | 990 /* Extract the template's CKA_VALUE_LEN into keySize and CKA_TOKEN into |
1033 PRBool isToken = CK_FALSE; | 991 isToken. */ |
1034 CK_ULONG keySize = 0; | 992 for (i = 0; i < attrsCount; ++i) { |
1035 unsigned i; | 993 switch (attrs[i].type) { |
1036 | 994 case CKA_VALUE_LEN: |
1037 /* Extract the template's CKA_VALUE_LEN into keySize and CKA_TOKEN into | 995 if (attrs[i].pValue == NULL || |
1038 isToken. */ | 996 attrs[i].ulValueLen != sizeof(CK_ULONG)) { |
1039 for (i = 0; i < attrsCount; ++i) { | 997 PORT_SetError(PK11_MapError(CKR_TEMPLATE_INCONSISTENT)); |
1040 switch (attrs[i].type) { | 998 return NULL; |
1041 case CKA_VALUE_LEN: | |
1042 if (attrs[i].pValue == NULL || | |
1043 attrs[i].ulValueLen != sizeof(CK_ULONG)) { | |
1044 PORT_SetError(PK11_MapError(CKR_TEMPLATE_INCONSISTENT)); | |
1045 return NULL; | |
1046 } | |
1047 keySize = * (CK_ULONG *) attrs[i].pValue; | |
1048 break; | |
1049 case CKA_TOKEN: | |
1050 if (attrs[i].pValue == NULL ||· | |
1051 attrs[i].ulValueLen != sizeof(CK_BBOOL)) { | |
1052 PORT_SetError(PK11_MapError(CKR_TEMPLATE_INCONSISTENT)); | |
1053 return NULL; | |
1054 } | |
1055 isToken = (*(CK_BBOOL*)attrs[i].pValue) ? PR_TRUE : PR_FALSE; | |
1056 break; | |
1057 } | 999 } |
1058 } | 1000 keySize = *(CK_ULONG *)attrs[i].pValue; |
1059 | 1001 break; |
1060 /* find a slot to generate the key into */ | 1002 case CKA_TOKEN: |
1061 /* Only do slot management if this is not a token key */ | 1003 if (attrs[i].pValue == NULL || |
1062 if (!isToken && (slot == NULL || !PK11_DoesMechanism(slot,type))) { | 1004 attrs[i].ulValueLen != sizeof(CK_BBOOL)) { |
1063 PK11SlotInfo *bestSlot = PK11_GetBestSlot(type,wincx); | 1005 PORT_SetError(PK11_MapError(CKR_TEMPLATE_INCONSISTENT)); |
1064 if (bestSlot == NULL) { | 1006 return NULL; |
1065 PORT_SetError( SEC_ERROR_NO_MODULE ); | |
1066 return NULL; | |
1067 } | 1007 } |
1068 symKey = pk11_CreateSymKey(bestSlot, type, !isToken, PR_TRUE, wincx); | 1008 isToken = (*(CK_BBOOL *)attrs[i].pValue) ? PR_TRUE : PR_FALSE; |
1069 PK11_FreeSlot(bestSlot); | 1009 break; |
1070 } else { | 1010 } |
1071 symKey = pk11_CreateSymKey(slot, type, !isToken, PR_TRUE, wincx); | 1011 } |
1072 } | 1012 |
1073 if (symKey == NULL) return NULL; | 1013 /* find a slot to generate the key into */ |
1074 | 1014 /* Only do slot management if this is not a token key */ |
1075 symKey->size = keySize; | 1015 if (!isToken && (slot == NULL || !PK11_DoesMechanism(slot, type))) { |
1076 symKey->origin = PK11_OriginGenerated; | 1016 PK11SlotInfo *bestSlot = PK11_GetBestSlot(type, wincx); |
1077 | 1017 if (bestSlot == NULL) { |
1078 /* Set the parameters for the key gen if provided */ | 1018 PORT_SetError(SEC_ERROR_NO_MODULE); |
1079 mechanism.mechanism = keyGenType; | 1019 return NULL; |
1080 mechanism.pParameter = NULL; | 1020 } |
1081 mechanism.ulParameterLen = 0; | 1021 symKey = pk11_CreateSymKey(bestSlot, type, !isToken, PR_TRUE, wincx); |
1082 if (param) { | 1022 PK11_FreeSlot(bestSlot); |
1083 mechanism.pParameter = param->data; | 1023 } else { |
1084 mechanism.ulParameterLen = param->len; | 1024 symKey = pk11_CreateSymKey(slot, type, !isToken, PR_TRUE, wincx); |
1085 } | 1025 } |
1086 | 1026 if (symKey == NULL) return NULL; |
1087 /* Get session and perform locking */ | 1027 |
1088 if (isToken) { | 1028 symKey->size = keySize; |
1089 PK11_Authenticate(symKey->slot,PR_TRUE,wincx); | 1029 symKey->origin = PK11_OriginGenerated; |
1090 /* Should always be original slot */ | 1030 |
1091 session = PK11_GetRWSession(symKey->slot);·· | 1031 /* Set the parameters for the key gen if provided */ |
1092 symKey->owner = PR_FALSE; | 1032 mechanism.mechanism = keyGenType; |
1093 } else { | 1033 mechanism.pParameter = NULL; |
1094 session = symKey->session; | 1034 mechanism.ulParameterLen = 0; |
1095 if (session != CK_INVALID_SESSION) | 1035 if (param) { |
1096 pk11_EnterKeyMonitor(symKey); | 1036 mechanism.pParameter = param->data; |
1097 } | 1037 mechanism.ulParameterLen = param->len; |
1098 if (session == CK_INVALID_SESSION) { | 1038 } |
1099 PK11_FreeSymKey(symKey); | 1039 |
1100 PORT_SetError(SEC_ERROR_BAD_DATA); | 1040 /* Get session and perform locking */ |
1101 return NULL; | 1041 if (isToken) { |
1102 } | 1042 PK11_Authenticate(symKey->slot, PR_TRUE, wincx); |
1103 | 1043 /* Should always be original slot */ |
1104 crv = PK11_GETTAB(symKey->slot)->C_GenerateKey(session, | 1044 session = PK11_GetRWSession(symKey->slot); |
1105 » » » &mechanism, attrs, attrsCount, &symKey->objectID); | 1045 symKey->owner = PR_FALSE; |
1106 | 1046 } else { |
1107 /* Release lock and session */ | 1047 session = symKey->session; |
1108 if (isToken) { | 1048 if (session != CK_INVALID_SESSION) pk11_EnterKeyMonitor(symKey); |
1109 PK11_RestoreROSession(symKey->slot, session); | 1049 } |
1110 } else { | 1050 if (session == CK_INVALID_SESSION) { |
1111 pk11_ExitKeyMonitor(symKey); | 1051 PK11_FreeSymKey(symKey); |
1112 } | 1052 PORT_SetError(SEC_ERROR_BAD_DATA); |
1113 | 1053 return NULL; |
1114 if (crv != CKR_OK) { | 1054 } |
1115 PK11_FreeSymKey(symKey); | 1055 |
1116 PORT_SetError( PK11_MapError(crv) ); | 1056 crv = PK11_GETTAB(symKey->slot)->C_GenerateKey(session, &mechanism, attrs, |
1117 return NULL; | 1057 attrsCount, &symKey->objectID); |
1118 } | 1058 |
1119 | 1059 /* Release lock and session */ |
1120 return symKey; | 1060 if (isToken) { |
1121 } | 1061 PK11_RestoreROSession(symKey->slot, session); |
1122 | 1062 } else { |
| 1063 pk11_ExitKeyMonitor(symKey); |
| 1064 } |
| 1065 |
| 1066 if (crv != CKR_OK) { |
| 1067 PK11_FreeSymKey(symKey); |
| 1068 PORT_SetError(PK11_MapError(crv)); |
| 1069 return NULL; |
| 1070 } |
| 1071 |
| 1072 return symKey; |
| 1073 } |
1123 | 1074 |
1124 /* --- */ | 1075 /* --- */ |
1125 PK11SymKey * | 1076 PK11SymKey *PK11_GenDES3TokenKey(PK11SlotInfo *slot, SECItem *keyid, void *cx) { |
1126 PK11_GenDES3TokenKey(PK11SlotInfo *slot, SECItem *keyid, void *cx) | |
1127 { | |
1128 return PK11_TokenKeyGen(slot, CKM_DES3_CBC, 0, 0, keyid, PR_TRUE, cx); | 1077 return PK11_TokenKeyGen(slot, CKM_DES3_CBC, 0, 0, keyid, PR_TRUE, cx); |
1129 } | 1078 } |
1130 | 1079 |
1131 PK11SymKey* | 1080 PK11SymKey *PK11_ConvertSessionSymKeyToTokenSymKey(PK11SymKey *symk, |
1132 PK11_ConvertSessionSymKeyToTokenSymKey(PK11SymKey *symk, void *wincx) | 1081 void *wincx) { |
1133 { | 1082 PK11SlotInfo *slot = symk->slot; |
1134 PK11SlotInfo* slot = symk->slot; | 1083 CK_ATTRIBUTE template[1]; |
1135 CK_ATTRIBUTE template[1]; | 1084 CK_ATTRIBUTE *attrs = template; |
1136 CK_ATTRIBUTE *attrs = template; | 1085 CK_BBOOL cktrue = CK_TRUE; |
1137 CK_BBOOL cktrue = CK_TRUE; | 1086 CK_RV crv; |
1138 CK_RV crv; | 1087 CK_OBJECT_HANDLE newKeyID; |
1139 CK_OBJECT_HANDLE newKeyID; | 1088 CK_SESSION_HANDLE rwsession; |
1140 CK_SESSION_HANDLE rwsession; | 1089 |
1141 | 1090 PK11_SETATTRS(attrs, CKA_TOKEN, &cktrue, sizeof(cktrue)); |
1142 PK11_SETATTRS(attrs, CKA_TOKEN, &cktrue, sizeof(cktrue)); attrs++; | 1091 attrs++; |
1143 | 1092 |
1144 PK11_Authenticate(slot, PR_TRUE, wincx); | 1093 PK11_Authenticate(slot, PR_TRUE, wincx); |
1145 rwsession = PK11_GetRWSession(slot); | 1094 rwsession = PK11_GetRWSession(slot); |
1146 if (rwsession == CK_INVALID_SESSION) { | 1095 if (rwsession == CK_INVALID_SESSION) { |
1147 » PORT_SetError(SEC_ERROR_BAD_DATA); | 1096 PORT_SetError(SEC_ERROR_BAD_DATA); |
1148 » return NULL; | 1097 return NULL; |
1149 } | 1098 } |
1150 crv = PK11_GETTAB(slot)->C_CopyObject(rwsession, symk->objectID, | 1099 crv = PK11_GETTAB(slot) |
1151 template, 1, &newKeyID); | 1100 ->C_CopyObject(rwsession, symk->objectID, template, 1, &newKeyID); |
1152 PK11_RestoreROSession(slot, rwsession); | 1101 PK11_RestoreROSession(slot, rwsession); |
1153 | 1102 |
1154 if (crv != CKR_OK) { | 1103 if (crv != CKR_OK) { |
1155 PORT_SetError( PK11_MapError(crv) ); | 1104 PORT_SetError(PK11_MapError(crv)); |
1156 return NULL; | 1105 return NULL; |
1157 } | 1106 } |
1158 | 1107 |
1159 return PK11_SymKeyFromHandle(slot, NULL /*parent*/, symk->origin, | 1108 return PK11_SymKeyFromHandle(slot, NULL /*parent*/, symk->origin, symk->type, |
1160 symk->type, newKeyID, PR_FALSE /*owner*/, NULL /*wincx*/); | 1109 newKeyID, PR_FALSE /*owner*/, NULL /*wincx*/); |
1161 } | 1110 } |
1162 | 1111 |
1163 /* | 1112 /* |
1164 * This function does a straight public key wrap (which only RSA can do). | 1113 * This function does a straight public key wrap (which only RSA can do). |
1165 * Use PK11_PubGenKey and PK11_WrapSymKey to implement the FORTEZZA and | 1114 * Use PK11_PubGenKey and PK11_WrapSymKey to implement the FORTEZZA and |
1166 * Diffie-Hellman Ciphers. */ | 1115 * Diffie-Hellman Ciphers. */ |
1167 SECStatus | 1116 SECStatus PK11_PubWrapSymKey(CK_MECHANISM_TYPE type, SECKEYPublicKey *pubKey, |
1168 PK11_PubWrapSymKey(CK_MECHANISM_TYPE type, SECKEYPublicKey *pubKey, | 1117 PK11SymKey *symKey, SECItem *wrappedKey) { |
1169 » » » » PK11SymKey *symKey, SECItem *wrappedKey) | 1118 PK11SlotInfo *slot; |
1170 { | 1119 CK_ULONG len = wrappedKey->len; |
1171 PK11SlotInfo *slot; | 1120 PK11SymKey *newKey = NULL; |
1172 CK_ULONG len = wrappedKey->len; | 1121 CK_OBJECT_HANDLE id; |
1173 PK11SymKey *newKey = NULL; | 1122 CK_MECHANISM mechanism; |
1174 CK_OBJECT_HANDLE id; | 1123 PRBool owner = PR_TRUE; |
1175 CK_MECHANISM mechanism; | 1124 CK_SESSION_HANDLE session; |
1176 PRBool owner = PR_TRUE; | 1125 CK_RV crv; |
1177 CK_SESSION_HANDLE session; | 1126 |
1178 CK_RV crv; | 1127 if (symKey == NULL) { |
1179 | 1128 PORT_SetError(SEC_ERROR_INVALID_ARGS); |
1180 if (symKey == NULL) { | 1129 return SECFailure; |
1181 » PORT_SetError( SEC_ERROR_INVALID_ARGS ); | 1130 } |
1182 » return SECFailure; | 1131 |
1183 } | 1132 /* if this slot doesn't support the mechanism, go to a slot that does */ |
1184 | 1133 newKey = pk11_ForceSlot(symKey, type, CKA_ENCRYPT); |
1185 /* if this slot doesn't support the mechanism, go to a slot that does */ | 1134 if (newKey != NULL) { |
1186 newKey = pk11_ForceSlot(symKey,type,CKA_ENCRYPT); | 1135 symKey = newKey; |
1187 if (newKey != NULL) { | 1136 } |
1188 » symKey = newKey; | 1137 |
1189 } | 1138 if (symKey->slot == NULL) { |
1190 | 1139 PORT_SetError(SEC_ERROR_NO_MODULE); |
1191 if (symKey->slot == NULL) { | 1140 return SECFailure; |
1192 » PORT_SetError( SEC_ERROR_NO_MODULE ); | 1141 } |
1193 » return SECFailure; | 1142 |
1194 } | 1143 slot = symKey->slot; |
1195 | 1144 mechanism.mechanism = pk11_mapWrapKeyType(pubKey->keyType); |
1196 slot = symKey->slot; | 1145 mechanism.pParameter = NULL; |
1197 mechanism.mechanism = pk11_mapWrapKeyType(pubKey->keyType); | 1146 mechanism.ulParameterLen = 0; |
| 1147 |
| 1148 id = PK11_ImportPublicKey(slot, pubKey, PR_FALSE); |
| 1149 if (id == CK_INVALID_HANDLE) { |
| 1150 if (newKey) { |
| 1151 PK11_FreeSymKey(newKey); |
| 1152 } |
| 1153 return SECFailure; /* Error code has been set. */ |
| 1154 } |
| 1155 |
| 1156 session = pk11_GetNewSession(slot, &owner); |
| 1157 if (!owner || !(slot->isThreadSafe)) PK11_EnterSlotMonitor(slot); |
| 1158 crv = PK11_GETTAB(slot)->C_WrapKey(session, &mechanism, id, symKey->objectID, |
| 1159 wrappedKey->data, &len); |
| 1160 if (!owner || !(slot->isThreadSafe)) PK11_ExitSlotMonitor(slot); |
| 1161 pk11_CloseSession(slot, session, owner); |
| 1162 if (newKey) { |
| 1163 PK11_FreeSymKey(newKey); |
| 1164 } |
| 1165 |
| 1166 if (crv != CKR_OK) { |
| 1167 PORT_SetError(PK11_MapError(crv)); |
| 1168 return SECFailure; |
| 1169 } |
| 1170 wrappedKey->len = len; |
| 1171 return SECSuccess; |
| 1172 } |
| 1173 |
| 1174 /* |
| 1175 * this little function uses the Encrypt function to wrap a key, just in |
| 1176 * case we have problems with the wrap implementation for a token. |
| 1177 */ |
| 1178 static SECStatus pk11_HandWrap(PK11SymKey *wrappingKey, SECItem *param, |
| 1179 CK_MECHANISM_TYPE type, SECItem *inKey, |
| 1180 SECItem *outKey) { |
| 1181 PK11SlotInfo *slot; |
| 1182 CK_ULONG len; |
| 1183 SECItem *data; |
| 1184 CK_MECHANISM mech; |
| 1185 PRBool owner = PR_TRUE; |
| 1186 CK_SESSION_HANDLE session; |
| 1187 CK_RV crv; |
| 1188 |
| 1189 slot = wrappingKey->slot; |
| 1190 /* use NULL IV's for wrapping */ |
| 1191 mech.mechanism = type; |
| 1192 if (param) { |
| 1193 mech.pParameter = param->data; |
| 1194 mech.ulParameterLen = param->len; |
| 1195 } else { |
| 1196 mech.pParameter = NULL; |
| 1197 mech.ulParameterLen = 0; |
| 1198 } |
| 1199 session = pk11_GetNewSession(slot, &owner); |
| 1200 if (!owner || !(slot->isThreadSafe)) PK11_EnterSlotMonitor(slot); |
| 1201 crv = PK11_GETTAB(slot)->C_EncryptInit(session, &mech, wrappingKey->objectID); |
| 1202 if (crv != CKR_OK) { |
| 1203 if (!owner || !(slot->isThreadSafe)) PK11_ExitSlotMonitor(slot); |
| 1204 pk11_CloseSession(slot, session, owner); |
| 1205 PORT_SetError(PK11_MapError(crv)); |
| 1206 return SECFailure; |
| 1207 } |
| 1208 |
| 1209 /* keys are almost always aligned, but if we get this far, |
| 1210 * we've gone above and beyond anyway... */ |
| 1211 data = PK11_BlockData(inKey, PK11_GetBlockSize(type, param)); |
| 1212 if (data == NULL) { |
| 1213 if (!owner || !(slot->isThreadSafe)) PK11_ExitSlotMonitor(slot); |
| 1214 pk11_CloseSession(slot, session, owner); |
| 1215 PORT_SetError(SEC_ERROR_NO_MEMORY); |
| 1216 return SECFailure; |
| 1217 } |
| 1218 len = outKey->len; |
| 1219 crv = PK11_GETTAB(slot) |
| 1220 ->C_Encrypt(session, data->data, data->len, outKey->data, &len); |
| 1221 if (!owner || !(slot->isThreadSafe)) PK11_ExitSlotMonitor(slot); |
| 1222 pk11_CloseSession(slot, session, owner); |
| 1223 SECITEM_FreeItem(data, PR_TRUE); |
| 1224 outKey->len = len; |
| 1225 if (crv != CKR_OK) { |
| 1226 PORT_SetError(PK11_MapError(crv)); |
| 1227 return SECFailure; |
| 1228 } |
| 1229 return SECSuccess; |
| 1230 } |
| 1231 |
| 1232 /* |
| 1233 * This function does a symetric based wrap. |
| 1234 */ |
| 1235 SECStatus PK11_WrapSymKey(CK_MECHANISM_TYPE type, SECItem *param, |
| 1236 PK11SymKey *wrappingKey, PK11SymKey *symKey, |
| 1237 SECItem *wrappedKey) { |
| 1238 PK11SlotInfo *slot; |
| 1239 CK_ULONG len = wrappedKey->len; |
| 1240 PK11SymKey *newKey = NULL; |
| 1241 SECItem *param_save = NULL; |
| 1242 CK_MECHANISM mechanism; |
| 1243 PRBool owner = PR_TRUE; |
| 1244 CK_SESSION_HANDLE session; |
| 1245 CK_RV crv; |
| 1246 SECStatus rv; |
| 1247 |
| 1248 /* if this slot doesn't support the mechanism, go to a slot that does */ |
| 1249 /* Force symKey and wrappingKey into the same slot */ |
| 1250 if ((wrappingKey->slot == NULL) || (symKey->slot != wrappingKey->slot)) { |
| 1251 /* first try copying the wrapping Key to the symKey slot */ |
| 1252 if (symKey->slot && PK11_DoesMechanism(symKey->slot, type)) { |
| 1253 newKey = pk11_CopyToSlot(symKey->slot, type, CKA_WRAP, wrappingKey); |
| 1254 } |
| 1255 /* Nope, try it the other way */ |
| 1256 if (newKey == NULL) { |
| 1257 if (wrappingKey->slot) { |
| 1258 newKey = pk11_CopyToSlot(wrappingKey->slot, symKey->type, CKA_ENCRYPT, |
| 1259 symKey); |
| 1260 } |
| 1261 /* just not playing... one last thing, can we get symKey's data? |
| 1262 * If it's possible, we it should already be in the |
| 1263 * symKey->data.data pointer because pk11_CopyToSlot would have |
| 1264 * tried to put it there. */ |
| 1265 if (newKey == NULL) { |
| 1266 /* Can't get symKey's data: Game Over */ |
| 1267 if (symKey->data.data == NULL) { |
| 1268 PORT_SetError(SEC_ERROR_NO_MODULE); |
| 1269 return SECFailure; |
| 1270 } |
| 1271 if (param == NULL) { |
| 1272 param_save = param = PK11_ParamFromIV(type, NULL); |
| 1273 } |
| 1274 rv = pk11_HandWrap(wrappingKey, param, type, &symKey->data, wrappedKey); |
| 1275 if (param_save) SECITEM_FreeItem(param_save, PR_TRUE); |
| 1276 return rv; |
| 1277 } |
| 1278 /* we successfully moved the sym Key */ |
| 1279 symKey = newKey; |
| 1280 } else { |
| 1281 /* we successfully moved the wrapping Key */ |
| 1282 wrappingKey = newKey; |
| 1283 } |
| 1284 } |
| 1285 |
| 1286 /* at this point both keys are in the same token */ |
| 1287 slot = wrappingKey->slot; |
| 1288 mechanism.mechanism = type; |
| 1289 /* use NULL IV's for wrapping */ |
| 1290 if (param == NULL) { |
| 1291 param_save = param = PK11_ParamFromIV(type, NULL); |
| 1292 } |
| 1293 if (param) { |
| 1294 mechanism.pParameter = param->data; |
| 1295 mechanism.ulParameterLen = param->len; |
| 1296 } else { |
1198 mechanism.pParameter = NULL; | 1297 mechanism.pParameter = NULL; |
1199 mechanism.ulParameterLen = 0; | 1298 mechanism.ulParameterLen = 0; |
1200 | 1299 } |
1201 id = PK11_ImportPublicKey(slot,pubKey,PR_FALSE); | 1300 |
1202 if (id == CK_INVALID_HANDLE) { | 1301 len = wrappedKey->len; |
1203 » if (newKey) { | 1302 |
1204 » PK11_FreeSymKey(newKey); | 1303 session = pk11_GetNewSession(slot, &owner); |
1205 » } | 1304 if (!owner || !(slot->isThreadSafe)) PK11_EnterSlotMonitor(slot); |
1206 » return SECFailure; /* Error code has been set. */ | 1305 crv = PK11_GETTAB(slot)->C_WrapKey(session, &mechanism, wrappingKey->objectID, |
1207 } | 1306 symKey->objectID, wrappedKey->data, &len); |
1208 | 1307 if (!owner || !(slot->isThreadSafe)) PK11_ExitSlotMonitor(slot); |
1209 session = pk11_GetNewSession(slot,&owner); | 1308 pk11_CloseSession(slot, session, owner); |
1210 if (!owner || !(slot->isThreadSafe)) PK11_EnterSlotMonitor(slot); | 1309 rv = SECSuccess; |
1211 crv = PK11_GETTAB(slot)->C_WrapKey(session,&mechanism, | 1310 if (crv != CKR_OK) { |
1212 » » id,symKey->objectID,wrappedKey->data,&len); | 1311 /* can't wrap it? try hand wrapping it... */ |
1213 if (!owner || !(slot->isThreadSafe)) PK11_ExitSlotMonitor(slot); | 1312 do { |
1214 pk11_CloseSession(slot,session,owner); | 1313 if (symKey->data.data == NULL) { |
1215 if (newKey) { | 1314 rv = PK11_ExtractKeyValue(symKey); |
1216 » PK11_FreeSymKey(newKey); | 1315 if (rv != SECSuccess) break; |
1217 } | 1316 } |
1218 | 1317 rv = pk11_HandWrap(wrappingKey, param, type, &symKey->data, wrappedKey); |
1219 if (crv != CKR_OK) { | 1318 } while (PR_FALSE); |
1220 » PORT_SetError( PK11_MapError(crv) ); | 1319 } else { |
1221 » return SECFailure; | |
1222 } | |
1223 wrappedKey->len = len; | 1320 wrappedKey->len = len; |
1224 return SECSuccess; | 1321 } |
1225 }· | 1322 if (newKey) PK11_FreeSymKey(newKey); |
1226 | 1323 if (param_save) SECITEM_FreeItem(param_save, PR_TRUE); |
1227 /* | 1324 return rv; |
1228 * this little function uses the Encrypt function to wrap a key, just in | 1325 } |
1229 * case we have problems with the wrap implementation for a token. | 1326 |
1230 */ | 1327 /* |
1231 static SECStatus | 1328 * This Generates a new key based on a symetricKey |
1232 pk11_HandWrap(PK11SymKey *wrappingKey, SECItem *param, CK_MECHANISM_TYPE type, | 1329 */ |
1233 » » » SECItem *inKey, SECItem *outKey) | 1330 PK11SymKey *PK11_Derive(PK11SymKey *baseKey, CK_MECHANISM_TYPE derive, |
1234 { | 1331 SECItem *param, CK_MECHANISM_TYPE target, |
1235 PK11SlotInfo *slot; | 1332 CK_ATTRIBUTE_TYPE operation, int keySize) { |
1236 CK_ULONG len; | 1333 return PK11_DeriveWithTemplate(baseKey, derive, param, target, operation, |
1237 SECItem *data; | 1334 keySize, NULL, 0, PR_FALSE); |
1238 CK_MECHANISM mech; | 1335 } |
1239 PRBool owner = PR_TRUE; | 1336 |
1240 CK_SESSION_HANDLE session; | 1337 PK11SymKey *PK11_DeriveWithFlags(PK11SymKey *baseKey, CK_MECHANISM_TYPE derive, |
1241 CK_RV crv; | 1338 SECItem *param, CK_MECHANISM_TYPE target, |
1242 | 1339 CK_ATTRIBUTE_TYPE operation, int keySize, |
1243 slot = wrappingKey->slot; | 1340 CK_FLAGS flags) { |
1244 /* use NULL IV's for wrapping */ | 1341 CK_BBOOL ckTrue = CK_TRUE; |
1245 mech.mechanism = type; | 1342 CK_ATTRIBUTE keyTemplate[MAX_TEMPL_ATTRS]; |
1246 if (param) { | 1343 unsigned int templateCount; |
1247 » mech.pParameter = param->data; | 1344 |
1248 » mech.ulParameterLen = param->len; | 1345 templateCount = pk11_OpFlagsToAttributes(flags, keyTemplate, &ckTrue); |
| 1346 return PK11_DeriveWithTemplate(baseKey, derive, param, target, operation, |
| 1347 keySize, keyTemplate, templateCount, PR_FALSE); |
| 1348 } |
| 1349 |
| 1350 PK11SymKey *PK11_DeriveWithFlagsPerm(PK11SymKey *baseKey, |
| 1351 CK_MECHANISM_TYPE derive, SECItem *param, |
| 1352 CK_MECHANISM_TYPE target, |
| 1353 CK_ATTRIBUTE_TYPE operation, int keySize, |
| 1354 CK_FLAGS flags, PRBool isPerm) { |
| 1355 CK_BBOOL cktrue = CK_TRUE; |
| 1356 CK_ATTRIBUTE keyTemplate[MAX_TEMPL_ATTRS]; |
| 1357 CK_ATTRIBUTE *attrs; |
| 1358 unsigned int templateCount = 0; |
| 1359 |
| 1360 attrs = keyTemplate; |
| 1361 if (isPerm) { |
| 1362 PK11_SETATTRS(attrs, CKA_TOKEN, &cktrue, sizeof(CK_BBOOL)); |
| 1363 attrs++; |
| 1364 } |
| 1365 templateCount = attrs - keyTemplate; |
| 1366 templateCount += pk11_OpFlagsToAttributes(flags, attrs, &cktrue); |
| 1367 return PK11_DeriveWithTemplate(baseKey, derive, param, target, operation, |
| 1368 keySize, keyTemplate, templateCount, isPerm); |
| 1369 } |
| 1370 |
| 1371 PK11SymKey *PK11_DeriveWithTemplate(PK11SymKey *baseKey, |
| 1372 CK_MECHANISM_TYPE derive, SECItem *param, |
| 1373 CK_MECHANISM_TYPE target, |
| 1374 CK_ATTRIBUTE_TYPE operation, int keySize, |
| 1375 CK_ATTRIBUTE *userAttr, |
| 1376 unsigned int numAttrs, PRBool isPerm) { |
| 1377 PK11SlotInfo *slot = baseKey->slot; |
| 1378 PK11SymKey *symKey; |
| 1379 PK11SymKey *newBaseKey = NULL; |
| 1380 CK_BBOOL cktrue = CK_TRUE; |
| 1381 CK_OBJECT_CLASS keyClass = CKO_SECRET_KEY; |
| 1382 CK_KEY_TYPE keyType = CKK_GENERIC_SECRET; |
| 1383 CK_ULONG valueLen = 0; |
| 1384 CK_MECHANISM mechanism; |
| 1385 CK_RV crv; |
| 1386 #define MAX_ADD_ATTRS 4 |
| 1387 CK_ATTRIBUTE keyTemplate[MAX_TEMPL_ATTRS + MAX_ADD_ATTRS]; |
| 1388 #undef MAX_ADD_ATTRS |
| 1389 CK_ATTRIBUTE *attrs = keyTemplate; |
| 1390 CK_SESSION_HANDLE session; |
| 1391 unsigned int templateCount; |
| 1392 |
| 1393 if (numAttrs > MAX_TEMPL_ATTRS) { |
| 1394 PORT_SetError(SEC_ERROR_INVALID_ARGS); |
| 1395 return NULL; |
| 1396 } |
| 1397 |
| 1398 /* first copy caller attributes in. */ |
| 1399 for (templateCount = 0; templateCount < numAttrs; ++templateCount) { |
| 1400 *attrs++ = *userAttr++; |
| 1401 } |
| 1402 |
| 1403 /* We only add the following attributes to the template if the caller |
| 1404 ** didn't already supply them. |
| 1405 */ |
| 1406 if (!pk11_FindAttrInTemplate(keyTemplate, numAttrs, CKA_CLASS)) { |
| 1407 PK11_SETATTRS(attrs, CKA_CLASS, &keyClass, sizeof keyClass); |
| 1408 attrs++; |
| 1409 } |
| 1410 if (!pk11_FindAttrInTemplate(keyTemplate, numAttrs, CKA_KEY_TYPE)) { |
| 1411 keyType = PK11_GetKeyType(target, keySize); |
| 1412 PK11_SETATTRS(attrs, CKA_KEY_TYPE, &keyType, sizeof keyType); |
| 1413 attrs++; |
| 1414 } |
| 1415 if (keySize > 0 && |
| 1416 !pk11_FindAttrInTemplate(keyTemplate, numAttrs, CKA_VALUE_LEN)) { |
| 1417 valueLen = (CK_ULONG)keySize; |
| 1418 PK11_SETATTRS(attrs, CKA_VALUE_LEN, &valueLen, sizeof valueLen); |
| 1419 attrs++; |
| 1420 } |
| 1421 if ((operation != CKA_FLAGS_ONLY) && |
| 1422 !pk11_FindAttrInTemplate(keyTemplate, numAttrs, operation)) { |
| 1423 PK11_SETATTRS(attrs, operation, &cktrue, sizeof cktrue); |
| 1424 attrs++; |
| 1425 } |
| 1426 |
| 1427 templateCount = attrs - keyTemplate; |
| 1428 PR_ASSERT(templateCount <= sizeof(keyTemplate) / sizeof(CK_ATTRIBUTE)); |
| 1429 |
| 1430 /* move the key to a slot that can do the function */ |
| 1431 if (!PK11_DoesMechanism(slot, derive)) { |
| 1432 /* get a new base key & slot */ |
| 1433 PK11SlotInfo *newSlot = PK11_GetBestSlot(derive, baseKey->cx); |
| 1434 |
| 1435 if (newSlot == NULL) return NULL; |
| 1436 |
| 1437 newBaseKey = pk11_CopyToSlot(newSlot, derive, CKA_DERIVE, baseKey); |
| 1438 PK11_FreeSlot(newSlot); |
| 1439 if (newBaseKey == NULL) return NULL; |
| 1440 baseKey = newBaseKey; |
| 1441 slot = baseKey->slot; |
| 1442 } |
| 1443 |
| 1444 /* get our key Structure */ |
| 1445 symKey = pk11_CreateSymKey(slot, target, !isPerm, PR_TRUE, baseKey->cx); |
| 1446 if (symKey == NULL) { |
| 1447 return NULL; |
| 1448 } |
| 1449 |
| 1450 symKey->size = keySize; |
| 1451 |
| 1452 mechanism.mechanism = derive; |
| 1453 if (param) { |
| 1454 mechanism.pParameter = param->data; |
| 1455 mechanism.ulParameterLen = param->len; |
| 1456 } else { |
| 1457 mechanism.pParameter = NULL; |
| 1458 mechanism.ulParameterLen = 0; |
| 1459 } |
| 1460 symKey->origin = PK11_OriginDerive; |
| 1461 |
| 1462 if (isPerm) { |
| 1463 session = PK11_GetRWSession(slot); |
| 1464 } else { |
| 1465 pk11_EnterKeyMonitor(symKey); |
| 1466 session = symKey->session; |
| 1467 } |
| 1468 if (session == CK_INVALID_SESSION) { |
| 1469 if (!isPerm) pk11_ExitKeyMonitor(symKey); |
| 1470 crv = CKR_SESSION_HANDLE_INVALID; |
| 1471 } else { |
| 1472 crv = PK11_GETTAB(slot)->C_DeriveKey(session, &mechanism, baseKey->objectID, |
| 1473 keyTemplate, templateCount, |
| 1474 &symKey->objectID); |
| 1475 if (isPerm) { |
| 1476 PK11_RestoreROSession(slot, session); |
1249 } else { | 1477 } else { |
1250 » mech.pParameter = NULL; | 1478 pk11_ExitKeyMonitor(symKey); |
1251 » mech.ulParameterLen = 0; | 1479 } |
1252 } | 1480 } |
1253 session = pk11_GetNewSession(slot,&owner); | 1481 if (newBaseKey) PK11_FreeSymKey(newBaseKey); |
1254 if (!owner || !(slot->isThreadSafe)) PK11_EnterSlotMonitor(slot); | 1482 if (crv != CKR_OK) { |
1255 crv = PK11_GETTAB(slot)->C_EncryptInit(session,&mech, | 1483 PK11_FreeSymKey(symKey); |
1256 » » » » » » » wrappingKey->objectID); | 1484 return NULL; |
1257 if (crv != CKR_OK) { | 1485 } |
1258 if (!owner || !(slot->isThreadSafe)) PK11_ExitSlotMonitor(slot); | 1486 return symKey; |
1259 pk11_CloseSession(slot,session,owner); | |
1260 » PORT_SetError( PK11_MapError(crv) ); | |
1261 » return SECFailure; | |
1262 } | |
1263 | |
1264 /* keys are almost always aligned, but if we get this far, | |
1265 * we've gone above and beyond anyway... */ | |
1266 data = PK11_BlockData(inKey,PK11_GetBlockSize(type,param)); | |
1267 if (data == NULL) { | |
1268 if (!owner || !(slot->isThreadSafe)) PK11_ExitSlotMonitor(slot); | |
1269 pk11_CloseSession(slot,session,owner); | |
1270 » PORT_SetError(SEC_ERROR_NO_MEMORY); | |
1271 » return SECFailure; | |
1272 } | |
1273 len = outKey->len; | |
1274 crv = PK11_GETTAB(slot)->C_Encrypt(session,data->data,data->len, | |
1275 » » » » » » » outKey->data, &len); | |
1276 if (!owner || !(slot->isThreadSafe)) PK11_ExitSlotMonitor(slot); | |
1277 pk11_CloseSession(slot,session,owner); | |
1278 SECITEM_FreeItem(data,PR_TRUE); | |
1279 outKey->len = len; | |
1280 if (crv != CKR_OK) { | |
1281 » PORT_SetError( PK11_MapError(crv) ); | |
1282 » return SECFailure; | |
1283 } | |
1284 return SECSuccess; | |
1285 } | |
1286 | |
1287 /* | |
1288 * This function does a symetric based wrap. | |
1289 */ | |
1290 SECStatus | |
1291 PK11_WrapSymKey(CK_MECHANISM_TYPE type, SECItem *param,· | |
1292 » PK11SymKey *wrappingKey, PK11SymKey *symKey, SECItem *wrappedKey) | |
1293 { | |
1294 PK11SlotInfo *slot; | |
1295 CK_ULONG len = wrappedKey->len; | |
1296 PK11SymKey *newKey = NULL; | |
1297 SECItem *param_save = NULL; | |
1298 CK_MECHANISM mechanism; | |
1299 PRBool owner = PR_TRUE; | |
1300 CK_SESSION_HANDLE session; | |
1301 CK_RV crv; | |
1302 SECStatus rv; | |
1303 | |
1304 /* if this slot doesn't support the mechanism, go to a slot that does */ | |
1305 /* Force symKey and wrappingKey into the same slot */ | |
1306 if ((wrappingKey->slot == NULL) || (symKey->slot != wrappingKey->slot)) { | |
1307 » /* first try copying the wrapping Key to the symKey slot */ | |
1308 » if (symKey->slot && PK11_DoesMechanism(symKey->slot,type)) { | |
1309 » newKey = pk11_CopyToSlot(symKey->slot,type,CKA_WRAP,wrappingKey); | |
1310 » } | |
1311 » /* Nope, try it the other way */ | |
1312 » if (newKey == NULL) { | |
1313 » if (wrappingKey->slot) { | |
1314 » newKey = pk11_CopyToSlot(wrappingKey->slot, | |
1315 » » » » » symKey->type, CKA_ENCRYPT, symKey); | |
1316 » } | |
1317 » /* just not playing... one last thing, can we get symKey's data? | |
1318 » * If it's possible, we it should already be in the· | |
1319 » * symKey->data.data pointer because pk11_CopyToSlot would have | |
1320 » * tried to put it there. */ | |
1321 » if (newKey == NULL) { | |
1322 » » /* Can't get symKey's data: Game Over */ | |
1323 » » if (symKey->data.data == NULL) { | |
1324 » » PORT_SetError( SEC_ERROR_NO_MODULE ); | |
1325 » » return SECFailure; | |
1326 » » } | |
1327 » » if (param == NULL) { | |
1328 » » param_save = param = PK11_ParamFromIV(type,NULL); | |
1329 » » } | |
1330 » » rv = pk11_HandWrap(wrappingKey, param, type, | |
1331 » » » » » » &symKey->data,wrappedKey); | |
1332 » » if (param_save) SECITEM_FreeItem(param_save,PR_TRUE); | |
1333 » » return rv; | |
1334 » } | |
1335 » /* we successfully moved the sym Key */ | |
1336 » symKey = newKey; | |
1337 » } else { | |
1338 » /* we successfully moved the wrapping Key */ | |
1339 » wrappingKey = newKey; | |
1340 » } | |
1341 } | |
1342 | |
1343 /* at this point both keys are in the same token */ | |
1344 slot = wrappingKey->slot; | |
1345 mechanism.mechanism = type; | |
1346 /* use NULL IV's for wrapping */ | |
1347 if (param == NULL) { | |
1348 » param_save = param = PK11_ParamFromIV(type,NULL); | |
1349 } | |
1350 if (param) { | |
1351 » mechanism.pParameter = param->data; | |
1352 » mechanism.ulParameterLen = param->len; | |
1353 } else { | |
1354 » mechanism.pParameter = NULL; | |
1355 » mechanism.ulParameterLen = 0; | |
1356 } | |
1357 | |
1358 len = wrappedKey->len; | |
1359 | |
1360 session = pk11_GetNewSession(slot,&owner); | |
1361 if (!owner || !(slot->isThreadSafe)) PK11_EnterSlotMonitor(slot); | |
1362 crv = PK11_GETTAB(slot)->C_WrapKey(session, &mechanism, | |
1363 » » wrappingKey->objectID, symKey->objectID,· | |
1364 » » » » » » wrappedKey->data, &len); | |
1365 if (!owner || !(slot->isThreadSafe)) PK11_ExitSlotMonitor(slot); | |
1366 pk11_CloseSession(slot,session,owner); | |
1367 rv = SECSuccess; | |
1368 if (crv != CKR_OK) { | |
1369 » /* can't wrap it? try hand wrapping it... */ | |
1370 » do { | |
1371 » if (symKey->data.data == NULL) { | |
1372 » » rv = PK11_ExtractKeyValue(symKey); | |
1373 » » if (rv != SECSuccess) break; | |
1374 » } | |
1375 » rv = pk11_HandWrap(wrappingKey, param, type, &symKey->data, | |
1376 » » » » » » » » wrappedKey); | |
1377 » } while (PR_FALSE); | |
1378 } else { | |
1379 wrappedKey->len = len; | |
1380 } | |
1381 if (newKey) PK11_FreeSymKey(newKey); | |
1382 if (param_save) SECITEM_FreeItem(param_save,PR_TRUE); | |
1383 return rv; | |
1384 }· | |
1385 | |
1386 /* | |
1387 * This Generates a new key based on a symetricKey | |
1388 */ | |
1389 PK11SymKey * | |
1390 PK11_Derive( PK11SymKey *baseKey, CK_MECHANISM_TYPE derive, SECItem *param,· | |
1391 CK_MECHANISM_TYPE target, CK_ATTRIBUTE_TYPE operation, | |
1392 » int keySize) | |
1393 { | |
1394 return PK11_DeriveWithTemplate(baseKey, derive, param, target, operation,· | |
1395 » » » » keySize, NULL, 0, PR_FALSE); | |
1396 } | |
1397 | |
1398 | |
1399 PK11SymKey * | |
1400 PK11_DeriveWithFlags( PK11SymKey *baseKey, CK_MECHANISM_TYPE derive,· | |
1401 » SECItem *param, CK_MECHANISM_TYPE target, CK_ATTRIBUTE_TYPE operation,· | |
1402 » int keySize, CK_FLAGS flags) | |
1403 { | |
1404 CK_BBOOL ckTrue» = CK_TRUE;· | |
1405 CK_ATTRIBUTE keyTemplate[MAX_TEMPL_ATTRS]; | |
1406 unsigned int templateCount; | |
1407 | |
1408 templateCount = pk11_OpFlagsToAttributes(flags, keyTemplate, &ckTrue); | |
1409 return PK11_DeriveWithTemplate(baseKey, derive, param, target, operation,· | |
1410 » » keySize, keyTemplate, templateCount, PR_FALSE); | |
1411 } | |
1412 | |
1413 PK11SymKey * | |
1414 PK11_DeriveWithFlagsPerm( PK11SymKey *baseKey, CK_MECHANISM_TYPE derive,· | |
1415 » SECItem *param, CK_MECHANISM_TYPE target, CK_ATTRIBUTE_TYPE operation,· | |
1416 » int keySize, CK_FLAGS flags, PRBool isPerm) | |
1417 { | |
1418 CK_BBOOL cktrue» = CK_TRUE;· | |
1419 CK_ATTRIBUTE keyTemplate[MAX_TEMPL_ATTRS]; | |
1420 CK_ATTRIBUTE *attrs; | |
1421 unsigned int templateCount = 0; | |
1422 | |
1423 attrs = keyTemplate; | |
1424 if (isPerm) { | |
1425 PK11_SETATTRS(attrs, CKA_TOKEN, &cktrue, sizeof(CK_BBOOL)); attrs++; | |
1426 } | |
1427 templateCount = attrs - keyTemplate; | |
1428 templateCount += pk11_OpFlagsToAttributes(flags, attrs, &cktrue); | |
1429 return PK11_DeriveWithTemplate(baseKey, derive, param, target, operation,· | |
1430 » » » » keySize, keyTemplate, templateCount, isPerm); | |
1431 } | |
1432 | |
1433 PK11SymKey * | |
1434 PK11_DeriveWithTemplate( PK11SymKey *baseKey, CK_MECHANISM_TYPE derive,· | |
1435 » SECItem *param, CK_MECHANISM_TYPE target, CK_ATTRIBUTE_TYPE operation,· | |
1436 » int keySize, CK_ATTRIBUTE *userAttr, unsigned int numAttrs, | |
1437 » » » » » » » PRBool isPerm) | |
1438 { | |
1439 PK11SlotInfo * slot» = baseKey->slot; | |
1440 PK11SymKey * symKey; | |
1441 PK11SymKey * newBaseKey» = NULL; | |
1442 CK_BBOOL cktrue» = CK_TRUE;· | |
1443 CK_OBJECT_CLASS keyClass» = CKO_SECRET_KEY; | |
1444 CK_KEY_TYPE keyType» = CKK_GENERIC_SECRET; | |
1445 CK_ULONG valueLen» = 0; | |
1446 CK_MECHANISM mechanism;· | |
1447 CK_RV crv; | |
1448 #define MAX_ADD_ATTRS 4 | |
1449 CK_ATTRIBUTE keyTemplate[MAX_TEMPL_ATTRS + MAX_ADD_ATTRS]; | |
1450 #undef MAX_ADD_ATTRS | |
1451 CK_ATTRIBUTE * attrs» = keyTemplate; | |
1452 CK_SESSION_HANDLE session; | |
1453 unsigned int templateCount; | |
1454 | |
1455 if (numAttrs > MAX_TEMPL_ATTRS) { | |
1456 » PORT_SetError(SEC_ERROR_INVALID_ARGS); | |
1457 » return NULL; | |
1458 } | |
1459 | |
1460 /* first copy caller attributes in. */ | |
1461 for (templateCount = 0; templateCount < numAttrs; ++templateCount) { | |
1462 » *attrs++ = *userAttr++; | |
1463 } | |
1464 | |
1465 /* We only add the following attributes to the template if the caller | |
1466 ** didn't already supply them. | |
1467 */ | |
1468 if (!pk11_FindAttrInTemplate(keyTemplate, numAttrs, CKA_CLASS)) { | |
1469 » PK11_SETATTRS(attrs, CKA_CLASS, &keyClass, sizeof keyClass);· | |
1470 » attrs++; | |
1471 } | |
1472 if (!pk11_FindAttrInTemplate(keyTemplate, numAttrs, CKA_KEY_TYPE)) { | |
1473 » keyType = PK11_GetKeyType(target, keySize); | |
1474 » PK11_SETATTRS(attrs, CKA_KEY_TYPE, &keyType, sizeof keyType );· | |
1475 » attrs++; | |
1476 } | |
1477 if (keySize > 0 && | |
1478 » !pk11_FindAttrInTemplate(keyTemplate, numAttrs, CKA_VALUE_LEN)) { | |
1479 » valueLen = (CK_ULONG)keySize; | |
1480 » PK11_SETATTRS(attrs, CKA_VALUE_LEN, &valueLen, sizeof valueLen);· | |
1481 » attrs++; | |
1482 } | |
1483 if ((operation != CKA_FLAGS_ONLY) && | |
1484 » !pk11_FindAttrInTemplate(keyTemplate, numAttrs, operation)) { | |
1485 » PK11_SETATTRS(attrs, operation, &cktrue, sizeof cktrue); attrs++; | |
1486 } | |
1487 | |
1488 templateCount = attrs - keyTemplate; | |
1489 PR_ASSERT(templateCount <= sizeof(keyTemplate)/sizeof(CK_ATTRIBUTE)); | |
1490 | |
1491 /* move the key to a slot that can do the function */ | |
1492 if (!PK11_DoesMechanism(slot,derive)) { | |
1493 » /* get a new base key & slot */ | |
1494 » PK11SlotInfo *newSlot = PK11_GetBestSlot(derive, baseKey->cx); | |
1495 | |
1496 » if (newSlot == NULL) return NULL; | |
1497 | |
1498 newBaseKey = pk11_CopyToSlot (newSlot, derive, CKA_DERIVE,· | |
1499 » » » » baseKey); | |
1500 » PK11_FreeSlot(newSlot); | |
1501 » if (newBaseKey == NULL)· | |
1502 » return NULL;»······· | |
1503 » baseKey = newBaseKey; | |
1504 » slot = baseKey->slot; | |
1505 } | |
1506 | |
1507 | |
1508 /* get our key Structure */ | |
1509 symKey = pk11_CreateSymKey(slot, target, !isPerm, PR_TRUE, baseKey->cx); | |
1510 if (symKey == NULL) { | |
1511 » return NULL; | |
1512 } | |
1513 | |
1514 symKey->size = keySize; | |
1515 | |
1516 mechanism.mechanism = derive; | |
1517 if (param) { | |
1518 » mechanism.pParameter = param->data; | |
1519 » mechanism.ulParameterLen = param->len; | |
1520 } else { | |
1521 » mechanism.pParameter = NULL; | |
1522 » mechanism.ulParameterLen = 0; | |
1523 } | |
1524 symKey->origin=PK11_OriginDerive; | |
1525 | |
1526 if (isPerm) { | |
1527 » session = PK11_GetRWSession(slot); | |
1528 } else { | |
1529 pk11_EnterKeyMonitor(symKey); | |
1530 » session = symKey->session; | |
1531 } | |
1532 if (session == CK_INVALID_SESSION) { | |
1533 » if (!isPerm) | |
1534 » pk11_ExitKeyMonitor(symKey); | |
1535 » crv = CKR_SESSION_HANDLE_INVALID; | |
1536 } else { | |
1537 » crv = PK11_GETTAB(slot)->C_DeriveKey(session, &mechanism, | |
1538 » baseKey->objectID, keyTemplate, templateCount, &symKey->objectID); | |
1539 » if (isPerm) { | |
1540 » PK11_RestoreROSession(slot, session); | |
1541 » } else { | |
1542 » pk11_ExitKeyMonitor(symKey); | |
1543 » } | |
1544 } | |
1545 if (newBaseKey)· | |
1546 » PK11_FreeSymKey(newBaseKey); | |
1547 if (crv != CKR_OK) { | |
1548 » PK11_FreeSymKey(symKey); | |
1549 » return NULL; | |
1550 } | |
1551 return symKey; | |
1552 } | 1487 } |
1553 | 1488 |
1554 /* Create a new key by concatenating base and data | 1489 /* Create a new key by concatenating base and data |
1555 */ | 1490 */ |
1556 static PK11SymKey *pk11_ConcatenateBaseAndData(PK11SymKey *base, | 1491 static PK11SymKey *pk11_ConcatenateBaseAndData(PK11SymKey *base, CK_BYTE *data, |
1557 » CK_BYTE *data, CK_ULONG dataLen, CK_MECHANISM_TYPE target, | 1492 CK_ULONG dataLen, |
1558 » CK_ATTRIBUTE_TYPE operation) | 1493 CK_MECHANISM_TYPE target, |
1559 { | 1494 CK_ATTRIBUTE_TYPE operation) { |
1560 CK_KEY_DERIVATION_STRING_DATA mechParams; | 1495 CK_KEY_DERIVATION_STRING_DATA mechParams; |
1561 SECItem param; | 1496 SECItem param; |
1562 | 1497 |
1563 if (base == NULL) { | 1498 if (base == NULL) { |
1564 » PORT_SetError( SEC_ERROR_INVALID_ARGS ); | 1499 PORT_SetError(SEC_ERROR_INVALID_ARGS); |
1565 » return NULL; | 1500 return NULL; |
1566 } | 1501 } |
1567 | 1502 |
1568 mechParams.pData = data; | 1503 mechParams.pData = data; |
1569 mechParams.ulLen = dataLen; | 1504 mechParams.ulLen = dataLen; |
1570 param.data = (unsigned char *)&mechParams; | 1505 param.data = (unsigned char *)&mechParams; |
1571 param.len = sizeof(CK_KEY_DERIVATION_STRING_DATA); | 1506 param.len = sizeof(CK_KEY_DERIVATION_STRING_DATA); |
1572 | 1507 |
1573 return PK11_Derive(base, CKM_CONCATENATE_BASE_AND_DATA, | 1508 return PK11_Derive(base, CKM_CONCATENATE_BASE_AND_DATA, ¶m, target, |
1574 » » » » ¶m, target, operation, 0); | 1509 operation, 0); |
1575 } | 1510 } |
1576 | 1511 |
1577 /* Create a new key by concatenating base and key | 1512 /* Create a new key by concatenating base and key |
1578 */ | 1513 */ |
1579 static PK11SymKey *pk11_ConcatenateBaseAndKey(PK11SymKey *base, | 1514 static PK11SymKey *pk11_ConcatenateBaseAndKey(PK11SymKey *base, PK11SymKey *key, |
1580 » » » PK11SymKey *key, CK_MECHANISM_TYPE target, | 1515 CK_MECHANISM_TYPE target, |
1581 » » » CK_ATTRIBUTE_TYPE operation, CK_ULONG keySize) | 1516 CK_ATTRIBUTE_TYPE operation, |
1582 { | 1517 CK_ULONG keySize) { |
1583 SECItem param; | 1518 SECItem param; |
1584 | 1519 |
1585 if ((base == NULL) || (key == NULL)) { | 1520 if ((base == NULL) || (key == NULL)) { |
1586 » PORT_SetError( SEC_ERROR_INVALID_ARGS ); | 1521 PORT_SetError(SEC_ERROR_INVALID_ARGS); |
1587 » return NULL; | 1522 return NULL; |
1588 } | 1523 } |
1589 | 1524 |
1590 param.data = (unsigned char *)&(key->objectID); | 1525 param.data = (unsigned char *)&(key->objectID); |
1591 param.len = sizeof(CK_OBJECT_HANDLE); | 1526 param.len = sizeof(CK_OBJECT_HANDLE); |
1592 | 1527 |
1593 return PK11_Derive(base, CKM_CONCATENATE_BASE_AND_KEY, | 1528 return PK11_Derive(base, CKM_CONCATENATE_BASE_AND_KEY, ¶m, target, |
1594 » » » » ¶m, target, operation, keySize); | 1529 operation, keySize); |
1595 } | 1530 } |
1596 | 1531 |
1597 /* Create a new key whose value is the hash of tobehashed. | 1532 /* Create a new key whose value is the hash of tobehashed. |
1598 * type is the mechanism for the derived key. | 1533 * type is the mechanism for the derived key. |
1599 */ | 1534 */ |
1600 static PK11SymKey *pk11_HashKeyDerivation(PK11SymKey *toBeHashed, | 1535 static PK11SymKey *pk11_HashKeyDerivation(PK11SymKey *toBeHashed, |
1601 » CK_MECHANISM_TYPE hashMechanism, CK_MECHANISM_TYPE target, | 1536 CK_MECHANISM_TYPE hashMechanism, |
1602 » CK_ATTRIBUTE_TYPE operation, CK_ULONG keySize) | 1537 CK_MECHANISM_TYPE target, |
1603 { | 1538 CK_ATTRIBUTE_TYPE operation, |
1604 return PK11_Derive(toBeHashed, hashMechanism, NULL, target, operation, keySi
ze); | 1539 CK_ULONG keySize) { |
| 1540 return PK11_Derive(toBeHashed, hashMechanism, NULL, target, operation, |
| 1541 keySize); |
1605 } | 1542 } |
1606 | 1543 |
1607 /* This function implements the ANSI X9.63 key derivation function | 1544 /* This function implements the ANSI X9.63 key derivation function |
1608 */ | 1545 */ |
1609 static PK11SymKey *pk11_ANSIX963Derive(PK11SymKey *sharedSecret, | 1546 static PK11SymKey *pk11_ANSIX963Derive(PK11SymKey *sharedSecret, |
1610 » » CK_EC_KDF_TYPE kdf, SECItem *sharedData, | 1547 CK_EC_KDF_TYPE kdf, SECItem *sharedData, |
1611 » » CK_MECHANISM_TYPE target, CK_ATTRIBUTE_TYPE operation, | 1548 CK_MECHANISM_TYPE target, |
1612 » » CK_ULONG keySize) | 1549 CK_ATTRIBUTE_TYPE operation, |
1613 { | 1550 CK_ULONG keySize) { |
1614 CK_KEY_TYPE keyType; | 1551 CK_KEY_TYPE keyType; |
1615 CK_MECHANISM_TYPE hashMechanism, mechanismArray[4]; | 1552 CK_MECHANISM_TYPE hashMechanism, mechanismArray[4]; |
1616 CK_ULONG derivedKeySize, HashLen, counter, maxCounter, bufferLen; | 1553 CK_ULONG derivedKeySize, HashLen, counter, maxCounter, bufferLen; |
1617 CK_ULONG SharedInfoLen; | 1554 CK_ULONG SharedInfoLen; |
1618 CK_BYTE *buffer = NULL; | 1555 CK_BYTE *buffer = NULL; |
1619 PK11SymKey *toBeHashed, *hashOutput; | 1556 PK11SymKey *toBeHashed, *hashOutput; |
1620 PK11SymKey *newSharedSecret = NULL; | 1557 PK11SymKey *newSharedSecret = NULL; |
1621 PK11SymKey *oldIntermediateResult, *intermediateResult = NULL; | 1558 PK11SymKey *oldIntermediateResult, *intermediateResult = NULL; |
1622 | 1559 |
1623 if (sharedSecret == NULL) { | 1560 if (sharedSecret == NULL) { |
1624 » PORT_SetError( SEC_ERROR_INVALID_ARGS ); | 1561 PORT_SetError(SEC_ERROR_INVALID_ARGS); |
1625 » return NULL; | 1562 return NULL; |
1626 } | 1563 } |
1627 | 1564 |
1628 switch (kdf) { | 1565 switch (kdf) { |
1629 case CKD_SHA1_KDF: | 1566 case CKD_SHA1_KDF: |
1630 » HashLen = SHA1_LENGTH; | 1567 HashLen = SHA1_LENGTH; |
1631 » hashMechanism = CKM_SHA1_KEY_DERIVATION; | 1568 hashMechanism = CKM_SHA1_KEY_DERIVATION; |
1632 » break; | 1569 break; |
1633 case CKD_SHA224_KDF: | 1570 case CKD_SHA224_KDF: |
1634 » HashLen = SHA224_LENGTH; | 1571 HashLen = SHA224_LENGTH; |
1635 » hashMechanism = CKM_SHA224_KEY_DERIVATION; | 1572 hashMechanism = CKM_SHA224_KEY_DERIVATION; |
1636 » break; | 1573 break; |
1637 case CKD_SHA256_KDF: | 1574 case CKD_SHA256_KDF: |
1638 » HashLen = SHA256_LENGTH; | 1575 HashLen = SHA256_LENGTH; |
1639 » hashMechanism = CKM_SHA256_KEY_DERIVATION; | 1576 hashMechanism = CKM_SHA256_KEY_DERIVATION; |
1640 » break; | 1577 break; |
1641 case CKD_SHA384_KDF: | 1578 case CKD_SHA384_KDF: |
1642 » HashLen = SHA384_LENGTH; | 1579 HashLen = SHA384_LENGTH; |
1643 » hashMechanism = CKM_SHA384_KEY_DERIVATION; | 1580 hashMechanism = CKM_SHA384_KEY_DERIVATION; |
1644 » break; | 1581 break; |
1645 case CKD_SHA512_KDF: | 1582 case CKD_SHA512_KDF: |
1646 » HashLen = SHA512_LENGTH; | 1583 HashLen = SHA512_LENGTH; |
1647 » hashMechanism = CKM_SHA512_KEY_DERIVATION; | 1584 hashMechanism = CKM_SHA512_KEY_DERIVATION; |
1648 » break; | 1585 break; |
1649 default: | 1586 default: |
1650 » PORT_SetError( SEC_ERROR_INVALID_ARGS ); | 1587 PORT_SetError(SEC_ERROR_INVALID_ARGS); |
1651 » return NULL; | 1588 return NULL; |
1652 } | 1589 } |
1653 | 1590 |
1654 derivedKeySize = keySize; | 1591 derivedKeySize = keySize; |
| 1592 if (derivedKeySize == 0) { |
| 1593 keyType = PK11_GetKeyType(target, keySize); |
| 1594 derivedKeySize = pk11_GetPredefinedKeyLength(keyType); |
1655 if (derivedKeySize == 0) { | 1595 if (derivedKeySize == 0) { |
1656 » keyType = PK11_GetKeyType(target,keySize); | 1596 derivedKeySize = HashLen; |
1657 » derivedKeySize = pk11_GetPredefinedKeyLength(keyType); | 1597 } |
1658 » if (derivedKeySize == 0) { | 1598 } |
1659 » derivedKeySize = HashLen; | 1599 |
1660 » } | 1600 /* Check that key_len isn't too long. The maximum key length could be |
1661 } | 1601 * greatly increased if the code below did not limit the 4-byte counter |
1662 | 1602 * to a maximum value of 255. */ |
1663 /* Check that key_len isn't too long. The maximum key length could be | 1603 if (derivedKeySize > 254 * HashLen) { |
1664 * greatly increased if the code below did not limit the 4-byte counter | 1604 PORT_SetError(SEC_ERROR_INVALID_ARGS); |
1665 * to a maximum value of 255. */ | 1605 return NULL; |
1666 if (derivedKeySize > 254 * HashLen) { | 1606 } |
1667 » PORT_SetError( SEC_ERROR_INVALID_ARGS ); | 1607 |
1668 » return NULL; | 1608 maxCounter = derivedKeySize / HashLen; |
1669 } | 1609 if (derivedKeySize > maxCounter * HashLen) maxCounter++; |
1670 | 1610 |
1671 maxCounter = derivedKeySize / HashLen; | 1611 if ((sharedData == NULL) || (sharedData->data == NULL)) |
1672 if (derivedKeySize > maxCounter * HashLen) | 1612 SharedInfoLen = 0; |
1673 » maxCounter++; | 1613 else |
1674 | 1614 SharedInfoLen = sharedData->len; |
1675 if ((sharedData == NULL) || (sharedData->data == NULL)) | 1615 |
1676 » SharedInfoLen = 0; | 1616 bufferLen = SharedInfoLen + 4; |
1677 else | 1617 |
1678 » SharedInfoLen = sharedData->len; | 1618 /* Populate buffer with Counter || sharedData |
1679 | 1619 * where Counter is 0x00000001. */ |
1680 bufferLen = SharedInfoLen + 4; | 1620 buffer = (unsigned char *)PORT_Alloc(bufferLen); |
1681 ···· | 1621 if (buffer == NULL) { |
1682 /* Populate buffer with Counter || sharedData | 1622 PORT_SetError(SEC_ERROR_NO_MEMORY); |
1683 * where Counter is 0x00000001. */ | 1623 return NULL; |
1684 buffer = (unsigned char *)PORT_Alloc(bufferLen); | 1624 } |
1685 if (buffer == NULL) { | 1625 |
1686 » PORT_SetError(SEC_ERROR_NO_MEMORY); | 1626 buffer[0] = 0; |
1687 » return NULL; | 1627 buffer[1] = 0; |
1688 } | 1628 buffer[2] = 0; |
1689 | 1629 buffer[3] = 1; |
1690 buffer[0] = 0; | 1630 if (SharedInfoLen > 0) { |
1691 buffer[1] = 0; | 1631 PORT_Memcpy(&buffer[4], sharedData->data, SharedInfoLen); |
1692 buffer[2] = 0; | 1632 } |
1693 buffer[3] = 1; | 1633 |
1694 if (SharedInfoLen > 0) { | 1634 /* Look for a slot that supports the mechanisms needed |
1695 » PORT_Memcpy(&buffer[4], sharedData->data, SharedInfoLen); | 1635 * to implement the ANSI X9.63 KDF as well as the |
1696 } | 1636 * target mechanism. |
1697 | 1637 */ |
1698 /* Look for a slot that supports the mechanisms needed | 1638 mechanismArray[0] = CKM_CONCATENATE_BASE_AND_DATA; |
1699 * to implement the ANSI X9.63 KDF as well as the | 1639 mechanismArray[1] = hashMechanism; |
1700 * target mechanism. | 1640 mechanismArray[2] = CKM_CONCATENATE_BASE_AND_KEY; |
1701 */ | 1641 mechanismArray[3] = target; |
1702 mechanismArray[0] = CKM_CONCATENATE_BASE_AND_DATA; | 1642 |
1703 mechanismArray[1] = hashMechanism; | 1643 newSharedSecret = |
1704 mechanismArray[2] = CKM_CONCATENATE_BASE_AND_KEY; | 1644 pk11_ForceSlotMultiple(sharedSecret, mechanismArray, 4, operation); |
1705 mechanismArray[3] = target; | 1645 if (newSharedSecret != NULL) { |
1706 | 1646 sharedSecret = newSharedSecret; |
1707 newSharedSecret = pk11_ForceSlotMultiple(sharedSecret, | 1647 } |
1708 » » » » » mechanismArray, 4, operation); | 1648 |
1709 if (newSharedSecret != NULL) { | 1649 for (counter = 1; counter <= maxCounter; counter++) { |
1710 » sharedSecret = newSharedSecret; | 1650 /* Concatenate shared_secret and buffer */ |
1711 } | 1651 toBeHashed = pk11_ConcatenateBaseAndData(sharedSecret, buffer, bufferLen, |
1712 | 1652 hashMechanism, operation); |
1713 for(counter=1; counter <= maxCounter; counter++) { | 1653 if (toBeHashed == NULL) { |
1714 » /* Concatenate shared_secret and buffer */ | 1654 goto loser; |
1715 » toBeHashed = pk11_ConcatenateBaseAndData(sharedSecret, buffer, | 1655 } |
1716 » » » » » bufferLen, hashMechanism, operation); | 1656 |
1717 » if (toBeHashed == NULL) { | 1657 /* Hash value */ |
1718 » goto loser; | 1658 if (maxCounter == 1) { |
1719 » } | 1659 /* In this case the length of the key to be derived is |
1720 | 1660 * less than or equal to the length of the hash output. |
1721 » /* Hash value */ | 1661 * So, the output of the hash operation will be the |
1722 » if (maxCounter == 1) { | 1662 * dervied key. */ |
1723 » /* In this case the length of the key to be derived is | 1663 hashOutput = pk11_HashKeyDerivation(toBeHashed, hashMechanism, target, |
1724 » * less than or equal to the length of the hash output. | 1664 operation, keySize); |
1725 » * So, the output of the hash operation will be the | 1665 } else { |
1726 » * dervied key. */ | 1666 /* In this case, the output of the hash operation will be |
1727 » hashOutput = pk11_HashKeyDerivation(toBeHashed, hashMechanism, | 1667 * concatenated with other data to create the derived key. */ |
1728 » » » » » » target, operation, keySize); | 1668 hashOutput = |
1729 » } else { | 1669 pk11_HashKeyDerivation(toBeHashed, hashMechanism, |
1730 » /* In this case, the output of the hash operation will be | 1670 CKM_CONCATENATE_BASE_AND_KEY, operation, 0); |
1731 » * concatenated with other data to create the derived key. */ | 1671 } |
1732 » hashOutput = pk11_HashKeyDerivation(toBeHashed, hashMechanism, | 1672 PK11_FreeSymKey(toBeHashed); |
1733 » » » » CKM_CONCATENATE_BASE_AND_KEY, operation, 0); | 1673 if (hashOutput == NULL) { |
1734 » } | 1674 goto loser; |
1735 » PK11_FreeSymKey(toBeHashed); | 1675 } |
1736 » if (hashOutput == NULL) { | 1676 |
1737 » goto loser; | 1677 /* Append result to intermediate result, if necessary */ |
1738 » } | 1678 oldIntermediateResult = intermediateResult; |
1739 | 1679 |
1740 » /* Append result to intermediate result, if necessary */ | 1680 if (oldIntermediateResult == NULL) { |
1741 » oldIntermediateResult = intermediateResult; | 1681 intermediateResult = hashOutput; |
1742 | 1682 } else { |
1743 » if (oldIntermediateResult == NULL) { | 1683 if (counter == maxCounter) { |
1744 » intermediateResult = hashOutput; | 1684 /* This is the final concatenation, and so the output |
1745 » } else { | 1685 * will be the derived key. */ |
1746 » if (counter == maxCounter) { | 1686 intermediateResult = pk11_ConcatenateBaseAndKey( |
1747 » » /* This is the final concatenation, and so the output | 1687 oldIntermediateResult, hashOutput, target, operation, keySize); |
1748 » » * will be the derived key. */ | 1688 } else { |
1749 » » intermediateResult = | 1689 /* The output of this concatenation will be concatenated |
1750 » » pk11_ConcatenateBaseAndKey(oldIntermediateResult, | 1690 * with other data to create the derived key. */ |
1751 » » » » hashOutput, target, operation, keySize); | 1691 intermediateResult = pk11_ConcatenateBaseAndKey( |
1752 » } else { | 1692 oldIntermediateResult, hashOutput, CKM_CONCATENATE_BASE_AND_KEY, |
1753 » » /* The output of this concatenation will be concatenated | 1693 operation, 0); |
1754 » » * with other data to create the derived key. */ | 1694 } |
1755 » » intermediateResult = | 1695 |
1756 » » pk11_ConcatenateBaseAndKey(oldIntermediateResult, | 1696 PK11_FreeSymKey(hashOutput); |
1757 » » » » hashOutput, CKM_CONCATENATE_BASE_AND_KEY, | 1697 PK11_FreeSymKey(oldIntermediateResult); |
1758 » » » » operation, 0); | 1698 if (intermediateResult == NULL) { |
1759 » } | 1699 goto loser; |
1760 | 1700 } |
1761 » PK11_FreeSymKey(hashOutput); | 1701 } |
1762 » PK11_FreeSymKey(oldIntermediateResult); | 1702 |
1763 » if (intermediateResult == NULL) { | 1703 /* Increment counter (assumes maxCounter < 255) */ |
1764 » » goto loser; | 1704 buffer[3]++; |
1765 » } | 1705 } |
1766 » } | 1706 |
1767 | 1707 PORT_ZFree(buffer, bufferLen); |
1768 » /* Increment counter (assumes maxCounter < 255) */ | 1708 if (newSharedSecret != NULL) PK11_FreeSymKey(newSharedSecret); |
1769 » buffer[3]++; | 1709 return intermediateResult; |
1770 } | |
1771 | |
1772 PORT_ZFree(buffer, bufferLen); | |
1773 if (newSharedSecret != NULL) | |
1774 » PK11_FreeSymKey(newSharedSecret); | |
1775 return intermediateResult; | |
1776 | 1710 |
1777 loser: | 1711 loser: |
1778 if (buffer != NULL) | 1712 if (buffer != NULL) PORT_ZFree(buffer, bufferLen); |
1779 » PORT_ZFree(buffer, bufferLen); | 1713 if (newSharedSecret != NULL) PK11_FreeSymKey(newSharedSecret); |
1780 if (newSharedSecret != NULL) | 1714 if (intermediateResult != NULL) PK11_FreeSymKey(intermediateResult); |
1781 » PK11_FreeSymKey(newSharedSecret); | 1715 return NULL; |
1782 if (intermediateResult != NULL) | |
1783 » PK11_FreeSymKey(intermediateResult); | |
1784 return NULL; | |
1785 } | 1716 } |
1786 | 1717 |
1787 /* | 1718 /* |
1788 * This Generates a wrapping key based on a privateKey, publicKey, and two | 1719 * This Generates a wrapping key based on a privateKey, publicKey, and two |
1789 * random numbers. For Mail usage RandomB should be NULL. In the Sender's | 1720 * random numbers. For Mail usage RandomB should be NULL. In the Sender's |
1790 * case RandomA is generate, outherwize it is passed. | 1721 * case RandomA is generate, outherwize it is passed. |
1791 */ | 1722 */ |
1792 static unsigned char *rb_email = NULL; | 1723 static unsigned char *rb_email = NULL; |
1793 | 1724 |
1794 PK11SymKey * | 1725 PK11SymKey *PK11_PubDerive(SECKEYPrivateKey *privKey, SECKEYPublicKey *pubKey, |
1795 PK11_PubDerive(SECKEYPrivateKey *privKey, SECKEYPublicKey *pubKey,· | 1726 PRBool isSender, SECItem *randomA, SECItem *randomB, |
1796 PRBool isSender, SECItem *randomA, SECItem *randomB,· | 1727 CK_MECHANISM_TYPE derive, CK_MECHANISM_TYPE target, |
1797 CK_MECHANISM_TYPE derive, CK_MECHANISM_TYPE target, | 1728 CK_ATTRIBUTE_TYPE operation, int keySize, |
1798 » » » CK_ATTRIBUTE_TYPE operation, int keySize,void *wincx) | 1729 void *wincx) { |
1799 { | 1730 PK11SlotInfo *slot = privKey->pkcs11Slot; |
1800 PK11SlotInfo *slot = privKey->pkcs11Slot; | 1731 CK_MECHANISM mechanism; |
1801 CK_MECHANISM mechanism; | 1732 PK11SymKey *symKey; |
1802 PK11SymKey *symKey; | 1733 CK_RV crv; |
1803 CK_RV crv; | 1734 |
1804 | 1735 if (rb_email == NULL) { |
1805 | 1736 rb_email = PORT_ZAlloc(128); |
1806 if (rb_email == NULL) { | 1737 if (rb_email == NULL) { |
1807 » rb_email = PORT_ZAlloc(128); | 1738 return NULL; |
1808 » if (rb_email == NULL) { | 1739 } |
1809 » return NULL; | 1740 rb_email[127] = 1; |
1810 » } | 1741 } |
1811 » rb_email[127] = 1; | 1742 |
1812 } | 1743 /* get our key Structure */ |
1813 | 1744 symKey = pk11_CreateSymKey(slot, target, PR_TRUE, PR_TRUE, wincx); |
1814 /* get our key Structure */ | 1745 if (symKey == NULL) { |
1815 symKey = pk11_CreateSymKey(slot, target, PR_TRUE, PR_TRUE, wincx); | 1746 return NULL; |
1816 if (symKey == NULL) { | 1747 } |
1817 » return NULL; | 1748 |
1818 } | 1749 symKey->origin = PK11_OriginDerive; |
1819 | 1750 |
1820 symKey->origin = PK11_OriginDerive; | 1751 switch (privKey->keyType) { |
1821 | |
1822 switch (privKey->keyType) { | |
1823 case rsaKey: | 1752 case rsaKey: |
1824 case nullKey: | 1753 case nullKey: |
1825 » PORT_SetError(SEC_ERROR_BAD_KEY); | 1754 PORT_SetError(SEC_ERROR_BAD_KEY); |
1826 » break; | 1755 break; |
1827 case dsaKey: | 1756 case dsaKey: |
1828 case keaKey: | 1757 case keaKey: |
1829 case fortezzaKey: | 1758 case fortezzaKey: { |
1830 { | 1759 CK_KEA_DERIVE_PARAMS param; |
1831 CK_KEA_DERIVE_PARAMS param; | 1760 param.isSender = (CK_BBOOL)isSender; |
1832 param.isSender = (CK_BBOOL) isSender; | 1761 param.ulRandomLen = randomA->len; |
1833 param.ulRandomLen = randomA->len; | 1762 param.pRandomA = randomA->data; |
1834 param.pRandomA = randomA->data; | 1763 param.pRandomB = rb_email; |
1835 param.pRandomB = rb_email; | 1764 if (randomB) param.pRandomB = randomB->data; |
1836 if (randomB) | 1765 if (pubKey->keyType == fortezzaKey) { |
1837 param.pRandomB = randomB->data; | 1766 param.ulPublicDataLen = pubKey->u.fortezza.KEAKey.len; |
1838 if (pubKey->keyType == fortezzaKey) { | 1767 param.pPublicData = pubKey->u.fortezza.KEAKey.data; |
1839 param.ulPublicDataLen = pubKey->u.fortezza.KEAKey.len; | 1768 } else { |
1840 param.pPublicData = pubKey->u.fortezza.KEAKey.data; | 1769 /* assert type == keaKey */ |
1841 } else { | 1770 /* XXX change to match key key types */ |
1842 /* assert type == keaKey */ | 1771 param.ulPublicDataLen = pubKey->u.fortezza.KEAKey.len; |
1843 /* XXX change to match key key types */ | 1772 param.pPublicData = pubKey->u.fortezza.KEAKey.data; |
1844 param.ulPublicDataLen = pubKey->u.fortezza.KEAKey.len; | 1773 } |
1845 param.pPublicData = pubKey->u.fortezza.KEAKey.data; | 1774 |
1846 } | 1775 mechanism.mechanism = derive; |
1847 | 1776 mechanism.pParameter = ¶m; |
1848 mechanism.mechanism = derive; | 1777 mechanism.ulParameterLen = sizeof(param); |
1849 mechanism.pParameter = ¶m; | 1778 |
1850 mechanism.ulParameterLen = sizeof(param); | 1779 /* get a new symKey structure */ |
1851 | 1780 pk11_EnterKeyMonitor(symKey); |
1852 /* get a new symKey structure */ | 1781 crv = PK11_GETTAB(slot)->C_DeriveKey(symKey->session, &mechanism, |
1853 pk11_EnterKeyMonitor(symKey); | 1782 privKey->pkcs11ID, NULL, 0, |
1854 crv=PK11_GETTAB(slot)->C_DeriveKey(symKey->session, &mechanism, | 1783 &symKey->objectID); |
1855 privKey->pkcs11ID, NULL, 0, &symKey->objectID); | 1784 pk11_ExitKeyMonitor(symKey); |
1856 pk11_ExitKeyMonitor(symKey); | 1785 if (crv == CKR_OK) return symKey; |
1857 if (crv == CKR_OK) return symKey; | 1786 PORT_SetError(PK11_MapError(crv)); |
1858 PORT_SetError( PK11_MapError(crv) ); | 1787 } break; |
1859 } | 1788 case dhKey: { |
1860 break; | 1789 CK_BBOOL cktrue = CK_TRUE; |
1861 case dhKey: | 1790 CK_OBJECT_CLASS keyClass = CKO_SECRET_KEY; |
1862 { | 1791 CK_KEY_TYPE keyType = CKK_GENERIC_SECRET; |
1863 CK_BBOOL cktrue = CK_TRUE; | 1792 CK_ULONG key_size = 0; |
1864 CK_OBJECT_CLASS keyClass = CKO_SECRET_KEY; | 1793 CK_ATTRIBUTE keyTemplate[4]; |
1865 CK_KEY_TYPE keyType = CKK_GENERIC_SECRET; | 1794 int templateCount; |
1866 CK_ULONG key_size = 0; | 1795 CK_ATTRIBUTE *attrs = keyTemplate; |
1867 CK_ATTRIBUTE keyTemplate[4]; | 1796 |
1868 int templateCount; | 1797 if (pubKey->keyType != dhKey) { |
1869 CK_ATTRIBUTE *attrs = keyTemplate; | 1798 PORT_SetError(SEC_ERROR_BAD_KEY); |
1870 | 1799 break; |
1871 if (pubKey->keyType != dhKey) { | 1800 } |
1872 PORT_SetError(SEC_ERROR_BAD_KEY); | 1801 |
1873 break; | 1802 PK11_SETATTRS(attrs, CKA_CLASS, &keyClass, sizeof(keyClass)); |
1874 } | 1803 attrs++; |
1875 | 1804 PK11_SETATTRS(attrs, CKA_KEY_TYPE, &keyType, sizeof(keyType)); |
1876 PK11_SETATTRS(attrs, CKA_CLASS, &keyClass, sizeof(keyClass)); | 1805 attrs++; |
1877 attrs++; | 1806 PK11_SETATTRS(attrs, operation, &cktrue, 1); |
1878 PK11_SETATTRS(attrs, CKA_KEY_TYPE, &keyType, sizeof(keyType)); | 1807 attrs++; |
1879 attrs++; | 1808 PK11_SETATTRS(attrs, CKA_VALUE_LEN, &key_size, sizeof(key_size)); |
1880 PK11_SETATTRS(attrs, operation, &cktrue, 1); attrs++; | 1809 attrs++; |
1881 PK11_SETATTRS(attrs, CKA_VALUE_LEN, &key_size, sizeof(key_size));· | 1810 templateCount = attrs - keyTemplate; |
1882 attrs++; | 1811 PR_ASSERT(templateCount <= sizeof(keyTemplate) / sizeof(CK_ATTRIBUTE)); |
1883 templateCount = attrs - keyTemplate; | 1812 |
1884 PR_ASSERT(templateCount <= sizeof(keyTemplate)/sizeof(CK_ATTRIBUTE))
; | 1813 keyType = PK11_GetKeyType(target, keySize); |
1885 | 1814 key_size = keySize; |
1886 keyType = PK11_GetKeyType(target,keySize); | 1815 symKey->size = keySize; |
1887 key_size = keySize; | 1816 if (key_size == 0) templateCount--; |
1888 symKey->size = keySize; | 1817 |
1889 if (key_size == 0) templateCount--; | 1818 mechanism.mechanism = derive; |
1890 | 1819 |
1891 mechanism.mechanism = derive; | 1820 /* we can undefine these when we define diffie-helman keys */ |
1892 | 1821 |
1893 /* we can undefine these when we define diffie-helman keys */ | 1822 mechanism.pParameter = pubKey->u.dh.publicValue.data; |
1894 | 1823 mechanism.ulParameterLen = pubKey->u.dh.publicValue.len; |
1895 mechanism.pParameter = pubKey->u.dh.publicValue.data;· | 1824 |
1896 mechanism.ulParameterLen = pubKey->u.dh.publicValue.len; | 1825 pk11_EnterKeyMonitor(symKey); |
1897 ················ | 1826 crv = PK11_GETTAB(slot)->C_DeriveKey(symKey->session, &mechanism, |
1898 pk11_EnterKeyMonitor(symKey); | 1827 privKey->pkcs11ID, keyTemplate, |
1899 crv = PK11_GETTAB(slot)->C_DeriveKey(symKey->session, &mechanism, | 1828 templateCount, &symKey->objectID); |
1900 privKey->pkcs11ID, keyTemplate, templateCount, &symKey->objectID); | 1829 pk11_ExitKeyMonitor(symKey); |
1901 pk11_ExitKeyMonitor(symKey); | 1830 if (crv == CKR_OK) return symKey; |
1902 if (crv == CKR_OK) return symKey; | 1831 PORT_SetError(PK11_MapError(crv)); |
1903 PORT_SetError( PK11_MapError(crv) ); | 1832 } break; |
1904 } | 1833 case ecKey: { |
1905 break; | 1834 CK_BBOOL cktrue = CK_TRUE; |
1906 case ecKey: | 1835 CK_OBJECT_CLASS keyClass = CKO_SECRET_KEY; |
1907 { | 1836 CK_KEY_TYPE keyType = CKK_GENERIC_SECRET; |
1908 CK_BBOOL cktrue = CK_TRUE; | 1837 CK_ULONG key_size = 0; |
1909 CK_OBJECT_CLASS keyClass = CKO_SECRET_KEY; | 1838 CK_ATTRIBUTE keyTemplate[4]; |
1910 CK_KEY_TYPE keyType = CKK_GENERIC_SECRET; | 1839 int templateCount; |
1911 CK_ULONG key_size = 0; | 1840 CK_ATTRIBUTE *attrs = keyTemplate; |
1912 CK_ATTRIBUTE keyTemplate[4]; | 1841 CK_ECDH1_DERIVE_PARAMS *mechParams = NULL; |
1913 int templateCount; | 1842 |
1914 CK_ATTRIBUTE *attrs = keyTemplate; | 1843 if (pubKey->keyType != ecKey) { |
1915 CK_ECDH1_DERIVE_PARAMS *mechParams = NULL; | 1844 PORT_SetError(SEC_ERROR_BAD_KEY); |
1916 | 1845 break; |
1917 if (pubKey->keyType != ecKey) { | 1846 } |
1918 PORT_SetError(SEC_ERROR_BAD_KEY); | 1847 |
1919 break; | 1848 PK11_SETATTRS(attrs, CKA_CLASS, &keyClass, sizeof(keyClass)); |
1920 } | 1849 attrs++; |
1921 | 1850 PK11_SETATTRS(attrs, CKA_KEY_TYPE, &keyType, sizeof(keyType)); |
1922 PK11_SETATTRS(attrs, CKA_CLASS, &keyClass, sizeof(keyClass)); | 1851 attrs++; |
1923 attrs++; | 1852 PK11_SETATTRS(attrs, operation, &cktrue, 1); |
1924 PK11_SETATTRS(attrs, CKA_KEY_TYPE, &keyType, sizeof(keyType)); | 1853 attrs++; |
1925 attrs++; | 1854 PK11_SETATTRS(attrs, CKA_VALUE_LEN, &key_size, sizeof(key_size)); |
1926 PK11_SETATTRS(attrs, operation, &cktrue, 1); attrs++; | 1855 attrs++; |
1927 PK11_SETATTRS(attrs, CKA_VALUE_LEN, &key_size, sizeof(key_size));· | 1856 templateCount = attrs - keyTemplate; |
1928 attrs++; | 1857 PR_ASSERT(templateCount <= sizeof(keyTemplate) / sizeof(CK_ATTRIBUTE)); |
1929 templateCount = attrs - keyTemplate; | 1858 |
1930 PR_ASSERT(templateCount <= sizeof(keyTemplate)/sizeof(CK_ATTRIBUTE))
; | 1859 keyType = PK11_GetKeyType(target, keySize); |
1931 | 1860 key_size = keySize; |
1932 keyType = PK11_GetKeyType(target,keySize); | 1861 if (key_size == 0) { |
1933 key_size = keySize; | 1862 if ((key_size = pk11_GetPredefinedKeyLength(keyType))) { |
1934 if (key_size == 0) { | 1863 templateCount--; |
1935 if ((key_size = pk11_GetPredefinedKeyLength(keyType))) { | 1864 } else { |
1936 templateCount --; | 1865 /* sigh, some tokens can't figure this out and require |
1937 } else { | 1866 * CKA_VALUE_LEN to be set */ |
1938 /* sigh, some tokens can't figure this out and require | 1867 key_size = SHA1_LENGTH; |
1939 * CKA_VALUE_LEN to be set */ | 1868 } |
1940 key_size = SHA1_LENGTH; | 1869 } |
1941 } | 1870 symKey->size = key_size; |
1942 } | 1871 |
1943 symKey->size = key_size; | 1872 mechParams = PORT_ZNew(CK_ECDH1_DERIVE_PARAMS); |
1944 | 1873 mechParams->kdf = CKD_SHA1_KDF; |
1945 mechParams = PORT_ZNew(CK_ECDH1_DERIVE_PARAMS);· | 1874 mechParams->ulSharedDataLen = 0; |
1946 mechParams->kdf = CKD_SHA1_KDF; | 1875 mechParams->pSharedData = NULL; |
1947 mechParams->ulSharedDataLen = 0; | 1876 mechParams->ulPublicDataLen = pubKey->u.ec.publicValue.len; |
1948 mechParams->pSharedData = NULL; | 1877 mechParams->pPublicData = pubKey->u.ec.publicValue.data; |
1949 mechParams->ulPublicDataLen = pubKey->u.ec.publicValue.len; | 1878 |
1950 mechParams->pPublicData = pubKey->u.ec.publicValue.data; | 1879 mechanism.mechanism = derive; |
1951 | 1880 mechanism.pParameter = mechParams; |
1952 mechanism.mechanism = derive; | 1881 mechanism.ulParameterLen = sizeof(CK_ECDH1_DERIVE_PARAMS); |
1953 mechanism.pParameter = mechParams; | 1882 |
1954 mechanism.ulParameterLen = sizeof(CK_ECDH1_DERIVE_PARAMS); | 1883 pk11_EnterKeyMonitor(symKey); |
1955 | 1884 crv = PK11_GETTAB(slot)->C_DeriveKey(symKey->session, &mechanism, |
1956 pk11_EnterKeyMonitor(symKey); | 1885 privKey->pkcs11ID, keyTemplate, |
1957 crv = PK11_GETTAB(slot)->C_DeriveKey(symKey->session,· | 1886 templateCount, &symKey->objectID); |
1958 &mechanism, privKey->pkcs11ID, keyTemplate,· | 1887 pk11_ExitKeyMonitor(symKey); |
1959 templateCount, &symKey->objectID); | 1888 |
1960 pk11_ExitKeyMonitor(symKey); | 1889 /* old PKCS #11 spec was ambiguous on what needed to be passed, |
1961 | 1890 * try this again with and encoded public key */ |
1962 /* old PKCS #11 spec was ambiguous on what needed to be passed, | 1891 if (crv != CKR_OK) { |
1963 * try this again with and encoded public key */ | 1892 SECItem *pubValue = |
1964 if (crv != CKR_OK) { | 1893 SEC_ASN1EncodeItem(NULL, NULL, &pubKey->u.ec.publicValue, |
1965 SECItem *pubValue = SEC_ASN1EncodeItem(NULL, NULL, | 1894 SEC_ASN1_GET(SEC_OctetStringTemplate)); |
1966 &pubKey->u.ec.publicValue, | 1895 if (pubValue == NULL) { |
1967 SEC_ASN1_GET(SEC_OctetStringTemplate)); | 1896 PORT_ZFree(mechParams, sizeof(CK_ECDH1_DERIVE_PARAMS)); |
1968 if (pubValue == NULL) { | 1897 break; |
1969 PORT_ZFree(mechParams, sizeof(CK_ECDH1_DERIVE_PARAMS)); | 1898 } |
1970 break; | 1899 mechParams->ulPublicDataLen = pubValue->len; |
1971 } | 1900 mechParams->pPublicData = pubValue->data; |
1972 mechParams->ulPublicDataLen = pubValue->len; | 1901 |
1973 mechParams->pPublicData = pubValue->data; | 1902 pk11_EnterKeyMonitor(symKey); |
1974 | 1903 crv = PK11_GETTAB(slot)->C_DeriveKey(symKey->session, &mechanism, |
1975 pk11_EnterKeyMonitor(symKey); | 1904 privKey->pkcs11ID, keyTemplate, |
1976 crv = PK11_GETTAB(slot)->C_DeriveKey(symKey->session,· | 1905 templateCount, &symKey->objectID); |
1977 &mechanism, privKey->pkcs11ID, keyTemplate,· | 1906 pk11_ExitKeyMonitor(symKey); |
1978 templateCount, &symKey->objectID); | 1907 |
1979 pk11_ExitKeyMonitor(symKey); | 1908 SECITEM_FreeItem(pubValue, PR_TRUE); |
1980 | 1909 } |
1981 SECITEM_FreeItem(pubValue,PR_TRUE); | 1910 |
1982 } | 1911 PORT_ZFree(mechParams, sizeof(CK_ECDH1_DERIVE_PARAMS)); |
1983 | 1912 |
1984 PORT_ZFree(mechParams, sizeof(CK_ECDH1_DERIVE_PARAMS)); | 1913 if (crv == CKR_OK) return symKey; |
1985 | 1914 PORT_SetError(PK11_MapError(crv)); |
1986 if (crv == CKR_OK) return symKey; | 1915 } |
1987 PORT_SetError( PK11_MapError(crv) ); | 1916 } |
1988 } | 1917 |
1989 } | 1918 PK11_FreeSymKey(symKey); |
1990 | 1919 return NULL; |
1991 PK11_FreeSymKey(symKey); | |
1992 return NULL; | |
1993 } | 1920 } |
1994 | 1921 |
1995 /* Returns the size of the public key, or 0 if there | 1922 /* Returns the size of the public key, or 0 if there |
1996 * is an error. */ | 1923 * is an error. */ |
1997 static CK_ULONG | 1924 static CK_ULONG pk11_ECPubKeySize(SECItem *publicValue) { |
1998 pk11_ECPubKeySize(SECItem *publicValue) | 1925 if (publicValue->data[0] == 0x04) { |
1999 { | 1926 /* key encoded in uncompressed form */ |
2000 if (publicValue->data[0] == 0x04) { | 1927 return ((publicValue->len - 1) / 2); |
2001 » /* key encoded in uncompressed form */ | 1928 } else if ((publicValue->data[0] == 0x02) || (publicValue->data[0] == 0x03)) { |
2002 » return((publicValue->len - 1)/2); | 1929 /* key encoded in compressed form */ |
2003 } else if ( (publicValue->data[0] == 0x02) || | 1930 return (publicValue->len - 1); |
2004 » » (publicValue->data[0] == 0x03)) { | 1931 } |
2005 » /* key encoded in compressed form */ | 1932 /* key encoding not recognized */ |
2006 » return(publicValue->len - 1); | 1933 return (0); |
2007 } | 1934 } |
2008 /* key encoding not recognized */ | 1935 |
2009 return(0); | 1936 static PK11SymKey *pk11_PubDeriveECKeyWithKDF( |
2010 } | 1937 SECKEYPrivateKey *privKey, SECKEYPublicKey *pubKey, PRBool isSender, |
2011 | 1938 SECItem *randomA, SECItem *randomB, CK_MECHANISM_TYPE derive, |
2012 static PK11SymKey * | 1939 CK_MECHANISM_TYPE target, CK_ATTRIBUTE_TYPE operation, int keySize, |
2013 pk11_PubDeriveECKeyWithKDF( | 1940 CK_ULONG kdf, SECItem *sharedData, void *wincx) { |
2014 » » SECKEYPrivateKey *privKey, SECKEYPublicKey *pubKey, | 1941 PK11SlotInfo *slot = privKey->pkcs11Slot; |
2015 » » PRBool isSender, SECItem *randomA, SECItem *randomB, | 1942 PK11SymKey *symKey; |
2016 » » CK_MECHANISM_TYPE derive, CK_MECHANISM_TYPE target, | 1943 PK11SymKey *SharedSecret; |
2017 » » CK_ATTRIBUTE_TYPE operation, int keySize, | 1944 CK_MECHANISM mechanism; |
2018 » » CK_ULONG kdf, SECItem *sharedData, void *wincx) | 1945 CK_RV crv; |
2019 { | 1946 CK_BBOOL cktrue = CK_TRUE; |
2020 PK11SlotInfo *slot = privKey->pkcs11Slot; | 1947 CK_OBJECT_CLASS keyClass = CKO_SECRET_KEY; |
2021 PK11SymKey *symKey; | 1948 CK_KEY_TYPE keyType = CKK_GENERIC_SECRET; |
2022 PK11SymKey *SharedSecret; | 1949 CK_ULONG key_size = 0; |
2023 CK_MECHANISM mechanism; | 1950 CK_ATTRIBUTE keyTemplate[4]; |
2024 CK_RV crv; | 1951 int templateCount; |
2025 CK_BBOOL cktrue = CK_TRUE; | 1952 CK_ATTRIBUTE *attrs = keyTemplate; |
2026 CK_OBJECT_CLASS keyClass = CKO_SECRET_KEY; | 1953 CK_ECDH1_DERIVE_PARAMS *mechParams = NULL; |
2027 CK_KEY_TYPE keyType = CKK_GENERIC_SECRET; | 1954 |
2028 CK_ULONG key_size = 0; | 1955 if (pubKey->keyType != ecKey) { |
2029 CK_ATTRIBUTE keyTemplate[4]; | 1956 PORT_SetError(SEC_ERROR_BAD_KEY); |
2030 int templateCount; | 1957 return NULL; |
2031 CK_ATTRIBUTE *attrs = keyTemplate; | 1958 } |
2032 CK_ECDH1_DERIVE_PARAMS *mechParams = NULL; | 1959 if ((kdf != CKD_NULL) && (kdf != CKD_SHA1_KDF) && (kdf != CKD_SHA224_KDF) && |
2033 | 1960 (kdf != CKD_SHA256_KDF) && (kdf != CKD_SHA384_KDF) && |
2034 if (pubKey->keyType != ecKey) { | 1961 (kdf != CKD_SHA512_KDF)) { |
2035 » PORT_SetError(SEC_ERROR_BAD_KEY); | 1962 PORT_SetError(SEC_ERROR_INVALID_ALGORITHM); |
2036 » return NULL; | 1963 return NULL; |
2037 } | 1964 } |
2038 if ((kdf != CKD_NULL) && (kdf != CKD_SHA1_KDF) && | 1965 |
2039 » (kdf != CKD_SHA224_KDF) && (kdf != CKD_SHA256_KDF) && | 1966 /* get our key Structure */ |
2040 » (kdf != CKD_SHA384_KDF) && (kdf != CKD_SHA512_KDF)) { | 1967 symKey = pk11_CreateSymKey(slot, target, PR_TRUE, PR_TRUE, wincx); |
2041 » PORT_SetError(SEC_ERROR_INVALID_ALGORITHM); | 1968 if (symKey == NULL) { |
2042 » return NULL; | 1969 return NULL; |
2043 } | 1970 } |
2044 | 1971 |
2045 /* get our key Structure */ | 1972 symKey->origin = PK11_OriginDerive; |
2046 symKey = pk11_CreateSymKey(slot, target, PR_TRUE, PR_TRUE, wincx); | 1973 |
2047 if (symKey == NULL) { | 1974 PK11_SETATTRS(attrs, CKA_CLASS, &keyClass, sizeof(keyClass)); |
2048 » return NULL; | 1975 attrs++; |
2049 } | 1976 PK11_SETATTRS(attrs, CKA_KEY_TYPE, &keyType, sizeof(keyType)); |
2050 | 1977 attrs++; |
2051 symKey->origin = PK11_OriginDerive; | 1978 PK11_SETATTRS(attrs, operation, &cktrue, 1); |
2052 | 1979 attrs++; |
2053 PK11_SETATTRS(attrs, CKA_CLASS, &keyClass, sizeof(keyClass)); attrs++; | 1980 PK11_SETATTRS(attrs, CKA_VALUE_LEN, &key_size, sizeof(key_size)); |
2054 PK11_SETATTRS(attrs, CKA_KEY_TYPE, &keyType, sizeof(keyType)); attrs++; | 1981 attrs++; |
2055 PK11_SETATTRS(attrs, operation, &cktrue, 1); attrs++; | 1982 templateCount = attrs - keyTemplate; |
2056 PK11_SETATTRS(attrs, CKA_VALUE_LEN, &key_size, sizeof(key_size)); attrs++; | 1983 PR_ASSERT(templateCount <= sizeof(keyTemplate) / sizeof(CK_ATTRIBUTE)); |
2057 templateCount = attrs - keyTemplate; | 1984 |
2058 PR_ASSERT(templateCount <= sizeof(keyTemplate)/sizeof(CK_ATTRIBUTE)); | 1985 keyType = PK11_GetKeyType(target, keySize); |
2059 | 1986 key_size = keySize; |
2060 keyType = PK11_GetKeyType(target,keySize); | 1987 if (key_size == 0) { |
2061 key_size = keySize; | 1988 if ((key_size = pk11_GetPredefinedKeyLength(keyType))) { |
2062 if (key_size == 0) { | 1989 templateCount--; |
2063 » if ((key_size = pk11_GetPredefinedKeyLength(keyType))) { | |
2064 » templateCount --; | |
2065 » } else { | |
2066 » /* sigh, some tokens can't figure this out and require | |
2067 » * CKA_VALUE_LEN to be set */ | |
2068 » switch (kdf) { | |
2069 » case CKD_NULL: | |
2070 » » key_size = pk11_ECPubKeySize(&pubKey->u.ec.publicValue); | |
2071 » » if (key_size == 0) { | |
2072 » » PK11_FreeSymKey(symKey); | |
2073 » » return NULL; | |
2074 » » } | |
2075 » » break; | |
2076 » case CKD_SHA1_KDF: | |
2077 » » key_size = SHA1_LENGTH; | |
2078 » » break; | |
2079 » case CKD_SHA224_KDF: | |
2080 » » key_size = SHA224_LENGTH; | |
2081 » » break; | |
2082 » case CKD_SHA256_KDF: | |
2083 » » key_size = SHA256_LENGTH; | |
2084 » » break; | |
2085 » case CKD_SHA384_KDF: | |
2086 » » key_size = SHA384_LENGTH; | |
2087 » » break; | |
2088 » case CKD_SHA512_KDF: | |
2089 » » key_size = SHA512_LENGTH; | |
2090 » » break; | |
2091 » default: | |
2092 » » PORT_Assert(!"Invalid CKD"); | |
2093 » » PORT_SetError(SEC_ERROR_INVALID_ALGORITHM); | |
2094 » » return NULL; | |
2095 » } | |
2096 » } | |
2097 } | |
2098 symKey->size = key_size; | |
2099 | |
2100 mechParams = PORT_ZNew(CK_ECDH1_DERIVE_PARAMS); | |
2101 if (!mechParams) { | |
2102 » PK11_FreeSymKey(symKey); | |
2103 » return NULL; | |
2104 } | |
2105 mechParams->kdf = kdf; | |
2106 if (sharedData == NULL) { | |
2107 » mechParams->ulSharedDataLen = 0; | |
2108 » mechParams->pSharedData = NULL; | |
2109 } else { | 1990 } else { |
2110 » mechParams->ulSharedDataLen = sharedData->len; | 1991 /* sigh, some tokens can't figure this out and require |
2111 » mechParams->pSharedData = sharedData->data; | 1992 * CKA_VALUE_LEN to be set */ |
2112 } | 1993 switch (kdf) { |
2113 mechParams->ulPublicDataLen = pubKey->u.ec.publicValue.len; | 1994 case CKD_NULL: |
2114 mechParams->pPublicData = pubKey->u.ec.publicValue.data; | 1995 key_size = pk11_ECPubKeySize(&pubKey->u.ec.publicValue); |
2115 | 1996 if (key_size == 0) { |
2116 mechanism.mechanism = derive; | 1997 PK11_FreeSymKey(symKey); |
2117 mechanism.pParameter = mechParams; | 1998 return NULL; |
2118 mechanism.ulParameterLen = sizeof(CK_ECDH1_DERIVE_PARAMS); | 1999 } |
| 2000 break; |
| 2001 case CKD_SHA1_KDF: |
| 2002 key_size = SHA1_LENGTH; |
| 2003 break; |
| 2004 case CKD_SHA224_KDF: |
| 2005 key_size = SHA224_LENGTH; |
| 2006 break; |
| 2007 case CKD_SHA256_KDF: |
| 2008 key_size = SHA256_LENGTH; |
| 2009 break; |
| 2010 case CKD_SHA384_KDF: |
| 2011 key_size = SHA384_LENGTH; |
| 2012 break; |
| 2013 case CKD_SHA512_KDF: |
| 2014 key_size = SHA512_LENGTH; |
| 2015 break; |
| 2016 default: |
| 2017 PORT_Assert(!"Invalid CKD"); |
| 2018 PORT_SetError(SEC_ERROR_INVALID_ALGORITHM); |
| 2019 return NULL; |
| 2020 } |
| 2021 } |
| 2022 } |
| 2023 symKey->size = key_size; |
| 2024 |
| 2025 mechParams = PORT_ZNew(CK_ECDH1_DERIVE_PARAMS); |
| 2026 if (!mechParams) { |
| 2027 PK11_FreeSymKey(symKey); |
| 2028 return NULL; |
| 2029 } |
| 2030 mechParams->kdf = kdf; |
| 2031 if (sharedData == NULL) { |
| 2032 mechParams->ulSharedDataLen = 0; |
| 2033 mechParams->pSharedData = NULL; |
| 2034 } else { |
| 2035 mechParams->ulSharedDataLen = sharedData->len; |
| 2036 mechParams->pSharedData = sharedData->data; |
| 2037 } |
| 2038 mechParams->ulPublicDataLen = pubKey->u.ec.publicValue.len; |
| 2039 mechParams->pPublicData = pubKey->u.ec.publicValue.data; |
| 2040 |
| 2041 mechanism.mechanism = derive; |
| 2042 mechanism.pParameter = mechParams; |
| 2043 mechanism.ulParameterLen = sizeof(CK_ECDH1_DERIVE_PARAMS); |
| 2044 |
| 2045 pk11_EnterKeyMonitor(symKey); |
| 2046 crv = PK11_GETTAB(slot)->C_DeriveKey(symKey->session, &mechanism, |
| 2047 privKey->pkcs11ID, keyTemplate, |
| 2048 templateCount, &symKey->objectID); |
| 2049 pk11_ExitKeyMonitor(symKey); |
| 2050 |
| 2051 /* old PKCS #11 spec was ambiguous on what needed to be passed, |
| 2052 * try this again with an encoded public key */ |
| 2053 if (crv != CKR_OK) { |
| 2054 SECItem *pubValue = |
| 2055 SEC_ASN1EncodeItem(NULL, NULL, &pubKey->u.ec.publicValue, |
| 2056 SEC_ASN1_GET(SEC_OctetStringTemplate)); |
| 2057 if (pubValue == NULL) { |
| 2058 goto loser; |
| 2059 } |
| 2060 mechParams->ulPublicDataLen = pubValue->len; |
| 2061 mechParams->pPublicData = pubValue->data; |
2119 | 2062 |
2120 pk11_EnterKeyMonitor(symKey); | 2063 pk11_EnterKeyMonitor(symKey); |
2121 crv = PK11_GETTAB(slot)->C_DeriveKey(symKey->session, &mechanism,· | 2064 crv = PK11_GETTAB(slot)->C_DeriveKey(symKey->session, &mechanism, |
2122 » privKey->pkcs11ID, keyTemplate, templateCount, &symKey->objectID); | 2065 privKey->pkcs11ID, keyTemplate, |
| 2066 templateCount, &symKey->objectID); |
2123 pk11_ExitKeyMonitor(symKey); | 2067 pk11_ExitKeyMonitor(symKey); |
2124 | 2068 |
2125 /* old PKCS #11 spec was ambiguous on what needed to be passed, | 2069 if ((crv != CKR_OK) && (kdf != CKD_NULL)) { |
2126 * try this again with an encoded public key */ | 2070 /* Some PKCS #11 libraries cannot perform the key derivation |
2127 if (crv != CKR_OK) { | 2071 * function. So, try calling C_DeriveKey with CKD_NULL and then |
2128 » SECItem *pubValue = SEC_ASN1EncodeItem(NULL, NULL, | 2072 * performing the KDF separately. |
2129 » » &pubKey->u.ec.publicValue, | 2073 */ |
2130 » » SEC_ASN1_GET(SEC_OctetStringTemplate)); | 2074 CK_ULONG derivedKeySize = key_size; |
2131 » if (pubValue == NULL) { | 2075 |
2132 » goto loser; | 2076 keyType = CKK_GENERIC_SECRET; |
2133 » } | 2077 key_size = pk11_ECPubKeySize(&pubKey->u.ec.publicValue); |
2134 » mechParams->ulPublicDataLen = pubValue->len; | 2078 if (key_size == 0) { |
2135 » mechParams->pPublicData = pubValue->data; | 2079 SECITEM_FreeItem(pubValue, PR_TRUE); |
2136 | 2080 goto loser; |
2137 » pk11_EnterKeyMonitor(symKey); | 2081 } |
2138 » crv = PK11_GETTAB(slot)->C_DeriveKey(symKey->session,· | 2082 SharedSecret = symKey; |
2139 » &mechanism, privKey->pkcs11ID, keyTemplate,· | 2083 SharedSecret->size = key_size; |
2140 » templateCount, &symKey->objectID); | 2084 |
2141 » pk11_ExitKeyMonitor(symKey); | 2085 mechParams->kdf = CKD_NULL; |
2142 | 2086 mechParams->ulSharedDataLen = 0; |
2143 » if ((crv != CKR_OK) && (kdf != CKD_NULL)) { | 2087 mechParams->pSharedData = NULL; |
2144 » /* Some PKCS #11 libraries cannot perform the key derivation | 2088 mechParams->ulPublicDataLen = pubKey->u.ec.publicValue.len; |
2145 » * function. So, try calling C_DeriveKey with CKD_NULL and then | 2089 mechParams->pPublicData = pubKey->u.ec.publicValue.data; |
2146 » * performing the KDF separately. | 2090 |
2147 » */ | 2091 pk11_EnterKeyMonitor(SharedSecret); |
2148 » CK_ULONG derivedKeySize = key_size; | 2092 crv = PK11_GETTAB(slot)->C_DeriveKey( |
2149 | 2093 SharedSecret->session, &mechanism, privKey->pkcs11ID, keyTemplate, |
2150 » keyType = CKK_GENERIC_SECRET; | 2094 templateCount, &SharedSecret->objectID); |
2151 » key_size = pk11_ECPubKeySize(&pubKey->u.ec.publicValue); | 2095 pk11_ExitKeyMonitor(SharedSecret); |
2152 » if (key_size == 0) { | 2096 |
2153 » » SECITEM_FreeItem(pubValue,PR_TRUE); | 2097 if (crv != CKR_OK) { |
2154 » » goto loser; | 2098 /* old PKCS #11 spec was ambiguous on what needed to be passed, |
2155 » } | 2099 * try this one final time with an encoded public key */ |
2156 » SharedSecret = symKey; | 2100 mechParams->ulPublicDataLen = pubValue->len; |
2157 » SharedSecret->size = key_size; | 2101 mechParams->pPublicData = pubValue->data; |
2158 | 2102 |
2159 » mechParams->kdf = CKD_NULL; | 2103 pk11_EnterKeyMonitor(SharedSecret); |
2160 » mechParams->ulSharedDataLen = 0; | 2104 crv = PK11_GETTAB(slot)->C_DeriveKey( |
2161 » mechParams->pSharedData = NULL; | 2105 SharedSecret->session, &mechanism, privKey->pkcs11ID, keyTemplate, |
2162 » mechParams->ulPublicDataLen = pubKey->u.ec.publicValue.len; | 2106 templateCount, &SharedSecret->objectID); |
2163 » mechParams->pPublicData = pubKey->u.ec.publicValue.data; | 2107 pk11_ExitKeyMonitor(SharedSecret); |
2164 | 2108 } |
2165 » pk11_EnterKeyMonitor(SharedSecret); | 2109 |
2166 » crv = PK11_GETTAB(slot)->C_DeriveKey(SharedSecret->session, | 2110 /* Perform KDF. */ |
2167 » » » &mechanism, privKey->pkcs11ID, keyTemplate, | 2111 if (crv == CKR_OK) { |
2168 » » » templateCount, &SharedSecret->objectID); | 2112 symKey = pk11_ANSIX963Derive(SharedSecret, kdf, sharedData, target, |
2169 » pk11_ExitKeyMonitor(SharedSecret); | 2113 operation, derivedKeySize); |
2170 | 2114 PK11_FreeSymKey(SharedSecret); |
2171 » if (crv != CKR_OK) { | 2115 if (symKey == NULL) { |
2172 » » /* old PKCS #11 spec was ambiguous on what needed to be passed, | 2116 SECITEM_FreeItem(pubValue, PR_TRUE); |
2173 » » * try this one final time with an encoded public key */ | 2117 PORT_ZFree(mechParams, sizeof(CK_ECDH1_DERIVE_PARAMS)); |
2174 » » mechParams->ulPublicDataLen = pubValue->len; | 2118 return NULL; |
2175 » » mechParams->pPublicData = pubValue->data; | 2119 } |
2176 | 2120 } |
2177 » » pk11_EnterKeyMonitor(SharedSecret); | 2121 } |
2178 » » crv = PK11_GETTAB(slot)->C_DeriveKey(SharedSecret->session, | 2122 SECITEM_FreeItem(pubValue, PR_TRUE); |
2179 » » » » &mechanism, privKey->pkcs11ID, keyTemplate, | 2123 } |
2180 » » » » templateCount, &SharedSecret->objectID); | |
2181 » » pk11_ExitKeyMonitor(SharedSecret); | |
2182 » } | |
2183 | |
2184 » /* Perform KDF. */ | |
2185 » if (crv == CKR_OK) { | |
2186 » » symKey = pk11_ANSIX963Derive(SharedSecret, kdf, | |
2187 » » » » » sharedData, target, operation, | |
2188 » » » » » derivedKeySize); | |
2189 » » PK11_FreeSymKey(SharedSecret); | |
2190 » » if (symKey == NULL) { | |
2191 » » » SECITEM_FreeItem(pubValue,PR_TRUE); | |
2192 » » » PORT_ZFree(mechParams, sizeof(CK_ECDH1_DERIVE_PARAMS)); | |
2193 » » » return NULL; | |
2194 » » } | |
2195 » } | |
2196 » } | |
2197 » SECITEM_FreeItem(pubValue,PR_TRUE); | |
2198 } | |
2199 | 2124 |
2200 loser: | 2125 loser: |
2201 PORT_ZFree(mechParams, sizeof(CK_ECDH1_DERIVE_PARAMS)); | 2126 PORT_ZFree(mechParams, sizeof(CK_ECDH1_DERIVE_PARAMS)); |
2202 | 2127 |
2203 if (crv != CKR_OK) { | 2128 if (crv != CKR_OK) { |
2204 » PK11_FreeSymKey(symKey); | 2129 PK11_FreeSymKey(symKey); |
2205 » symKey = NULL; | 2130 symKey = NULL; |
2206 » PORT_SetError( PK11_MapError(crv) ); | 2131 PORT_SetError(PK11_MapError(crv)); |
2207 } | 2132 } |
2208 return symKey; | 2133 return symKey; |
2209 } | 2134 } |
2210 | 2135 |
2211 PK11SymKey * | 2136 PK11SymKey *PK11_PubDeriveWithKDF( |
2212 PK11_PubDeriveWithKDF(SECKEYPrivateKey *privKey, SECKEYPublicKey *pubKey, | 2137 SECKEYPrivateKey *privKey, SECKEYPublicKey *pubKey, PRBool isSender, |
2213 » » PRBool isSender, SECItem *randomA, SECItem *randomB, | 2138 SECItem *randomA, SECItem *randomB, CK_MECHANISM_TYPE derive, |
2214 » » CK_MECHANISM_TYPE derive, CK_MECHANISM_TYPE target, | 2139 CK_MECHANISM_TYPE target, CK_ATTRIBUTE_TYPE operation, int keySize, |
2215 » » CK_ATTRIBUTE_TYPE operation, int keySize, | 2140 CK_ULONG kdf, SECItem *sharedData, void *wincx) { |
2216 » » CK_ULONG kdf, SECItem *sharedData, void *wincx) | 2141 |
2217 { | 2142 switch (privKey->keyType) { |
2218 | |
2219 switch (privKey->keyType) { | |
2220 case rsaKey: | 2143 case rsaKey: |
2221 case nullKey: | 2144 case nullKey: |
2222 case dsaKey: | 2145 case dsaKey: |
2223 case keaKey: | 2146 case keaKey: |
2224 case fortezzaKey: | 2147 case fortezzaKey: |
2225 case dhKey: | 2148 case dhKey: |
2226 » return PK11_PubDerive(privKey, pubKey, isSender, randomA, randomB, | 2149 return PK11_PubDerive(privKey, pubKey, isSender, randomA, randomB, derive, |
2227 » » derive, target, operation, keySize, wincx); | 2150 target, operation, keySize, wincx); |
2228 case ecKey: | 2151 case ecKey: |
2229 » return pk11_PubDeriveECKeyWithKDF( privKey, pubKey, isSender,· | 2152 return pk11_PubDeriveECKeyWithKDF(privKey, pubKey, isSender, randomA, |
2230 » » randomA, randomB, derive, target, operation, keySize,· | 2153 randomB, derive, target, operation, |
2231 » » kdf, sharedData, wincx); | 2154 keySize, kdf, sharedData, wincx); |
2232 default: | 2155 default: |
2233 PORT_SetError(SEC_ERROR_BAD_KEY); | 2156 PORT_SetError(SEC_ERROR_BAD_KEY); |
2234 break; | 2157 break; |
2235 } | 2158 } |
2236 | 2159 |
2237 return NULL; | 2160 return NULL; |
2238 } | 2161 } |
2239 | 2162 |
2240 /* | 2163 /* |
2241 * this little function uses the Decrypt function to unwrap a key, just in | 2164 * this little function uses the Decrypt function to unwrap a key, just in |
2242 * case we are having problem with unwrap. NOTE: The key size may | 2165 * case we are having problem with unwrap. NOTE: The key size may |
2243 * not be preserved properly for some algorithms! | 2166 * not be preserved properly for some algorithms! |
2244 */ | 2167 */ |
2245 static PK11SymKey * | 2168 static PK11SymKey *pk11_HandUnwrap(PK11SlotInfo *slot, |
2246 pk11_HandUnwrap(PK11SlotInfo *slot, CK_OBJECT_HANDLE wrappingKey, | 2169 CK_OBJECT_HANDLE wrappingKey, |
2247 CK_MECHANISM *mech, SECItem *inKey, CK_MECHANISM_TYPE target,· | 2170 CK_MECHANISM *mech, SECItem *inKey, |
2248 » » CK_ATTRIBUTE *keyTemplate, unsigned int templateCount, | 2171 CK_MECHANISM_TYPE target, |
2249 » » int key_size, void * wincx, CK_RV *crvp, PRBool isPerm) | 2172 CK_ATTRIBUTE *keyTemplate, |
2250 { | 2173 unsigned int templateCount, int key_size, |
2251 CK_ULONG len; | 2174 void *wincx, CK_RV *crvp, PRBool isPerm) { |
2252 SECItem outKey; | 2175 CK_ULONG len; |
2253 PK11SymKey *symKey; | 2176 SECItem outKey; |
2254 CK_RV crv; | 2177 PK11SymKey *symKey; |
2255 PRBool owner = PR_TRUE; | 2178 CK_RV crv; |
2256 CK_SESSION_HANDLE session; | 2179 PRBool owner = PR_TRUE; |
2257 | 2180 CK_SESSION_HANDLE session; |
2258 /* remove any VALUE_LEN parameters */ | 2181 |
2259 if (keyTemplate[templateCount-1].type == CKA_VALUE_LEN) { | 2182 /* remove any VALUE_LEN parameters */ |
2260 templateCount--; | 2183 if (keyTemplate[templateCount - 1].type == CKA_VALUE_LEN) { |
2261 } | 2184 templateCount--; |
2262 | 2185 } |
2263 /* keys are almost always aligned, but if we get this far, | 2186 |
2264 * we've gone above and beyond anyway... */ | 2187 /* keys are almost always aligned, but if we get this far, |
2265 outKey.data = (unsigned char*)PORT_Alloc(inKey->len); | 2188 * we've gone above and beyond anyway... */ |
2266 if (outKey.data == NULL) { | 2189 outKey.data = (unsigned char *)PORT_Alloc(inKey->len); |
2267 » PORT_SetError( SEC_ERROR_NO_MEMORY ); | 2190 if (outKey.data == NULL) { |
2268 » if (crvp) *crvp = CKR_HOST_MEMORY; | 2191 PORT_SetError(SEC_ERROR_NO_MEMORY); |
2269 » return NULL; | 2192 if (crvp) *crvp = CKR_HOST_MEMORY; |
2270 } | 2193 return NULL; |
2271 len = inKey->len; | 2194 } |
2272 | 2195 len = inKey->len; |
2273 /* use NULL IV's for wrapping */ | 2196 |
2274 session = pk11_GetNewSession(slot,&owner); | 2197 /* use NULL IV's for wrapping */ |
2275 if (!owner || !(slot->isThreadSafe)) PK11_EnterSlotMonitor(slot); | 2198 session = pk11_GetNewSession(slot, &owner); |
2276 crv = PK11_GETTAB(slot)->C_DecryptInit(session,mech,wrappingKey); | 2199 if (!owner || !(slot->isThreadSafe)) PK11_EnterSlotMonitor(slot); |
2277 if (crv != CKR_OK) { | 2200 crv = PK11_GETTAB(slot)->C_DecryptInit(session, mech, wrappingKey); |
2278 » if (!owner || !(slot->isThreadSafe)) PK11_ExitSlotMonitor(slot); | 2201 if (crv != CKR_OK) { |
2279 » pk11_CloseSession(slot,session,owner); | |
2280 » PORT_Free(outKey.data); | |
2281 » PORT_SetError( PK11_MapError(crv) ); | |
2282 » if (crvp) *crvp =crv; | |
2283 » return NULL; | |
2284 } | |
2285 crv = PK11_GETTAB(slot)->C_Decrypt(session,inKey->data,inKey->len, | |
2286 » » » » » » » outKey.data, &len); | |
2287 if (!owner || !(slot->isThreadSafe)) PK11_ExitSlotMonitor(slot); | 2202 if (!owner || !(slot->isThreadSafe)) PK11_ExitSlotMonitor(slot); |
2288 pk11_CloseSession(slot,session,owner); | 2203 pk11_CloseSession(slot, session, owner); |
2289 if (crv != CKR_OK) { | |
2290 » PORT_Free(outKey.data); | |
2291 » PORT_SetError( PK11_MapError(crv) ); | |
2292 » if (crvp) *crvp =crv; | |
2293 » return NULL; | |
2294 } | |
2295 | |
2296 outKey.len = (key_size == 0) ? len : key_size; | |
2297 outKey.type = siBuffer; | |
2298 | |
2299 if (PK11_DoesMechanism(slot,target)) { | |
2300 » symKey = pk11_ImportSymKeyWithTempl(slot, target, PK11_OriginUnwrap,· | |
2301 » isPerm, keyTemplate,· | |
2302 » » » » » templateCount, &outKey, wincx); | |
2303 } else { | |
2304 » slot = PK11_GetBestSlot(target,wincx); | |
2305 » if (slot == NULL) { | |
2306 » PORT_SetError( SEC_ERROR_NO_MODULE ); | |
2307 » PORT_Free(outKey.data); | |
2308 » if (crvp) *crvp = CKR_DEVICE_ERROR;· | |
2309 » return NULL; | |
2310 » } | |
2311 » symKey = pk11_ImportSymKeyWithTempl(slot, target, PK11_OriginUnwrap,· | |
2312 » isPerm, keyTemplate, | |
2313 » » » » » templateCount, &outKey, wincx); | |
2314 » PK11_FreeSlot(slot); | |
2315 } | |
2316 PORT_Free(outKey.data); | 2204 PORT_Free(outKey.data); |
2317 | 2205 PORT_SetError(PK11_MapError(crv)); |
2318 if (crvp) *crvp = symKey? CKR_OK : CKR_DEVICE_ERROR;· | 2206 if (crvp) *crvp = crv; |
2319 return symKey; | 2207 return NULL; |
| 2208 } |
| 2209 crv = PK11_GETTAB(slot) |
| 2210 ->C_Decrypt(session, inKey->data, inKey->len, outKey.data, &len); |
| 2211 if (!owner || !(slot->isThreadSafe)) PK11_ExitSlotMonitor(slot); |
| 2212 pk11_CloseSession(slot, session, owner); |
| 2213 if (crv != CKR_OK) { |
| 2214 PORT_Free(outKey.data); |
| 2215 PORT_SetError(PK11_MapError(crv)); |
| 2216 if (crvp) *crvp = crv; |
| 2217 return NULL; |
| 2218 } |
| 2219 |
| 2220 outKey.len = (key_size == 0) ? len : key_size; |
| 2221 outKey.type = siBuffer; |
| 2222 |
| 2223 if (PK11_DoesMechanism(slot, target)) { |
| 2224 symKey = |
| 2225 pk11_ImportSymKeyWithTempl(slot, target, PK11_OriginUnwrap, isPerm, |
| 2226 keyTemplate, templateCount, &outKey, wincx); |
| 2227 } else { |
| 2228 slot = PK11_GetBestSlot(target, wincx); |
| 2229 if (slot == NULL) { |
| 2230 PORT_SetError(SEC_ERROR_NO_MODULE); |
| 2231 PORT_Free(outKey.data); |
| 2232 if (crvp) *crvp = CKR_DEVICE_ERROR; |
| 2233 return NULL; |
| 2234 } |
| 2235 symKey = |
| 2236 pk11_ImportSymKeyWithTempl(slot, target, PK11_OriginUnwrap, isPerm, |
| 2237 keyTemplate, templateCount, &outKey, wincx); |
| 2238 PK11_FreeSlot(slot); |
| 2239 } |
| 2240 PORT_Free(outKey.data); |
| 2241 |
| 2242 if (crvp) *crvp = symKey ? CKR_OK : CKR_DEVICE_ERROR; |
| 2243 return symKey; |
2320 } | 2244 } |
2321 | 2245 |
2322 /* | 2246 /* |
2323 * The wrap/unwrap function is pretty much the same for private and | 2247 * The wrap/unwrap function is pretty much the same for private and |
2324 * public keys. It's just getting the Object ID and slot right. This is | 2248 * public keys. It's just getting the Object ID and slot right. This is |
2325 * the combined unwrap function. | 2249 * the combined unwrap function. |
2326 */ | 2250 */ |
2327 static PK11SymKey * | 2251 static PK11SymKey *pk11_AnyUnwrapKey( |
2328 pk11_AnyUnwrapKey(PK11SlotInfo *slot, CK_OBJECT_HANDLE wrappingKey, | 2252 PK11SlotInfo *slot, CK_OBJECT_HANDLE wrappingKey, |
2329 CK_MECHANISM_TYPE wrapType, SECItem *param, SECItem *wrappedKey, | 2253 CK_MECHANISM_TYPE wrapType, SECItem *param, SECItem *wrappedKey, |
2330 CK_MECHANISM_TYPE target, CK_ATTRIBUTE_TYPE operation, int keySize, | 2254 CK_MECHANISM_TYPE target, CK_ATTRIBUTE_TYPE operation, int keySize, |
2331 void *wincx, CK_ATTRIBUTE *userAttr, unsigned int numAttrs, PRBool isPerm) | 2255 void *wincx, CK_ATTRIBUTE *userAttr, unsigned int numAttrs, PRBool isPerm) { |
2332 { | 2256 PK11SymKey *symKey; |
2333 PK11SymKey * symKey; | 2257 SECItem *param_free = NULL; |
2334 SECItem * param_free» = NULL; | 2258 CK_BBOOL cktrue = CK_TRUE; |
2335 CK_BBOOL cktrue» = CK_TRUE;· | 2259 CK_OBJECT_CLASS keyClass = CKO_SECRET_KEY; |
2336 CK_OBJECT_CLASS keyClass» = CKO_SECRET_KEY; | 2260 CK_KEY_TYPE keyType = CKK_GENERIC_SECRET; |
2337 CK_KEY_TYPE keyType» = CKK_GENERIC_SECRET; | 2261 CK_ULONG valueLen = 0; |
2338 CK_ULONG valueLen» = 0; | 2262 CK_MECHANISM mechanism; |
2339 CK_MECHANISM mechanism; | 2263 CK_SESSION_HANDLE rwsession; |
2340 CK_SESSION_HANDLE rwsession; | 2264 CK_RV crv; |
2341 CK_RV crv; | 2265 CK_MECHANISM_INFO mechanism_info; |
2342 CK_MECHANISM_INFO mechanism_info; | |
2343 #define MAX_ADD_ATTRS 4 | 2266 #define MAX_ADD_ATTRS 4 |
2344 CK_ATTRIBUTE keyTemplate[MAX_TEMPL_ATTRS + MAX_ADD_ATTRS]; | 2267 CK_ATTRIBUTE keyTemplate[MAX_TEMPL_ATTRS + MAX_ADD_ATTRS]; |
2345 #undef MAX_ADD_ATTRS | 2268 #undef MAX_ADD_ATTRS |
2346 CK_ATTRIBUTE * attrs» = keyTemplate; | 2269 CK_ATTRIBUTE *attrs = keyTemplate; |
2347 unsigned int templateCount; | 2270 unsigned int templateCount; |
2348 | 2271 |
2349 if (numAttrs > MAX_TEMPL_ATTRS) { | 2272 if (numAttrs > MAX_TEMPL_ATTRS) { |
2350 » PORT_SetError(SEC_ERROR_INVALID_ARGS); | 2273 PORT_SetError(SEC_ERROR_INVALID_ARGS); |
2351 » return NULL; | 2274 return NULL; |
2352 } | 2275 } |
2353 | 2276 |
2354 /* first copy caller attributes in. */ | 2277 /* first copy caller attributes in. */ |
2355 for (templateCount = 0; templateCount < numAttrs; ++templateCount) { | 2278 for (templateCount = 0; templateCount < numAttrs; ++templateCount) { |
2356 » *attrs++ = *userAttr++; | 2279 *attrs++ = *userAttr++; |
2357 } | 2280 } |
2358 | 2281 |
2359 /* We only add the following attributes to the template if the caller | 2282 /* We only add the following attributes to the template if the caller |
2360 ** didn't already supply them. | 2283 ** didn't already supply them. |
2361 */ | 2284 */ |
2362 if (!pk11_FindAttrInTemplate(keyTemplate, numAttrs, CKA_CLASS)) { | 2285 if (!pk11_FindAttrInTemplate(keyTemplate, numAttrs, CKA_CLASS)) { |
2363 » PK11_SETATTRS(attrs, CKA_CLASS, &keyClass, sizeof keyClass);· | 2286 PK11_SETATTRS(attrs, CKA_CLASS, &keyClass, sizeof keyClass); |
2364 » attrs++; | 2287 attrs++; |
2365 } | 2288 } |
2366 if (!pk11_FindAttrInTemplate(keyTemplate, numAttrs, CKA_KEY_TYPE)) { | 2289 if (!pk11_FindAttrInTemplate(keyTemplate, numAttrs, CKA_KEY_TYPE)) { |
2367 » keyType = PK11_GetKeyType(target, keySize); | 2290 keyType = PK11_GetKeyType(target, keySize); |
2368 » PK11_SETATTRS(attrs, CKA_KEY_TYPE, &keyType, sizeof keyType );· | 2291 PK11_SETATTRS(attrs, CKA_KEY_TYPE, &keyType, sizeof keyType); |
2369 » attrs++; | 2292 attrs++; |
2370 } | 2293 } |
2371 if ((operation != CKA_FLAGS_ONLY) && | 2294 if ((operation != CKA_FLAGS_ONLY) && |
2372 » !pk11_FindAttrInTemplate(keyTemplate, numAttrs, operation)) { | 2295 !pk11_FindAttrInTemplate(keyTemplate, numAttrs, operation)) { |
2373 » PK11_SETATTRS(attrs, operation, &cktrue, 1); attrs++; | 2296 PK11_SETATTRS(attrs, operation, &cktrue, 1); |
2374 } | 2297 attrs++; |
2375 | 2298 } |
| 2299 |
| 2300 /* |
| 2301 * must be last in case we need to use this template to import the key |
| 2302 */ |
| 2303 if (keySize > 0 && |
| 2304 !pk11_FindAttrInTemplate(keyTemplate, numAttrs, CKA_VALUE_LEN)) { |
| 2305 valueLen = (CK_ULONG)keySize; |
| 2306 PK11_SETATTRS(attrs, CKA_VALUE_LEN, &valueLen, sizeof valueLen); |
| 2307 attrs++; |
| 2308 } |
| 2309 |
| 2310 templateCount = attrs - keyTemplate; |
| 2311 PR_ASSERT(templateCount <= sizeof(keyTemplate) / sizeof(CK_ATTRIBUTE)); |
| 2312 |
| 2313 /* find out if we can do wrap directly. Because the RSA case if *very* |
| 2314 * common, cache the results for it. */ |
| 2315 if ((wrapType == CKM_RSA_PKCS) && (slot->hasRSAInfo)) { |
| 2316 mechanism_info.flags = slot->RSAInfoFlags; |
| 2317 } else { |
| 2318 if (!slot->isThreadSafe) PK11_EnterSlotMonitor(slot); |
| 2319 crv = PK11_GETTAB(slot) |
| 2320 ->C_GetMechanismInfo(slot->slotID, wrapType, &mechanism_info); |
| 2321 if (!slot->isThreadSafe) PK11_ExitSlotMonitor(slot); |
| 2322 if (crv != CKR_OK) { |
| 2323 mechanism_info.flags = 0; |
| 2324 } |
| 2325 if (wrapType == CKM_RSA_PKCS) { |
| 2326 slot->RSAInfoFlags = mechanism_info.flags; |
| 2327 slot->hasRSAInfo = PR_TRUE; |
| 2328 } |
| 2329 } |
| 2330 |
| 2331 /* initialize the mechanism structure */ |
| 2332 mechanism.mechanism = wrapType; |
| 2333 /* use NULL IV's for wrapping */ |
| 2334 if (param == NULL) param = param_free = PK11_ParamFromIV(wrapType, NULL); |
| 2335 if (param) { |
| 2336 mechanism.pParameter = param->data; |
| 2337 mechanism.ulParameterLen = param->len; |
| 2338 } else { |
| 2339 mechanism.pParameter = NULL; |
| 2340 mechanism.ulParameterLen = 0; |
| 2341 } |
| 2342 |
| 2343 if ((mechanism_info.flags & CKF_DECRYPT) && |
| 2344 !PK11_DoesMechanism(slot, target)) { |
| 2345 symKey = pk11_HandUnwrap(slot, wrappingKey, &mechanism, wrappedKey, target, |
| 2346 keyTemplate, templateCount, keySize, wincx, &crv, |
| 2347 isPerm); |
| 2348 if (symKey) { |
| 2349 if (param_free) SECITEM_FreeItem(param_free, PR_TRUE); |
| 2350 return symKey; |
| 2351 } |
2376 /* | 2352 /* |
2377 * must be last in case we need to use this template to import the key | 2353 * if the RSA OP simply failed, don't try to unwrap again |
| 2354 * with this module. |
2378 */ | 2355 */ |
2379 if (keySize > 0 && | 2356 if (crv == CKR_DEVICE_ERROR) { |
2380 » !pk11_FindAttrInTemplate(keyTemplate, numAttrs, CKA_VALUE_LEN)) { | 2357 if (param_free) SECITEM_FreeItem(param_free, PR_TRUE); |
2381 » valueLen = (CK_ULONG)keySize; | 2358 return NULL; |
2382 » PK11_SETATTRS(attrs, CKA_VALUE_LEN, &valueLen, sizeof valueLen);· | 2359 } |
2383 » attrs++; | 2360 /* fall through, maybe they incorrectly set CKF_DECRYPT */ |
2384 } | 2361 } |
2385 | 2362 |
2386 templateCount = attrs - keyTemplate; | 2363 /* get our key Structure */ |
2387 PR_ASSERT(templateCount <= sizeof(keyTemplate)/sizeof(CK_ATTRIBUTE)); | 2364 symKey = pk11_CreateSymKey(slot, target, !isPerm, PR_TRUE, wincx); |
2388 | 2365 if (symKey == NULL) { |
2389 | 2366 if (param_free) SECITEM_FreeItem(param_free, PR_TRUE); |
2390 /* find out if we can do wrap directly. Because the RSA case if *very* | 2367 return NULL; |
2391 * common, cache the results for it. */ | 2368 } |
2392 if ((wrapType == CKM_RSA_PKCS) && (slot->hasRSAInfo)) { | 2369 |
2393 » mechanism_info.flags = slot->RSAInfoFlags; | 2370 symKey->size = keySize; |
2394 } else { | 2371 symKey->origin = PK11_OriginUnwrap; |
2395 » if (!slot->isThreadSafe) PK11_EnterSlotMonitor(slot); | 2372 |
2396 » crv = PK11_GETTAB(slot)->C_GetMechanismInfo(slot->slotID,wrapType, | 2373 if (isPerm) { |
2397 » » » » &mechanism_info); | 2374 rwsession = PK11_GetRWSession(slot); |
2398 » if (!slot->isThreadSafe) PK11_ExitSlotMonitor(slot); | 2375 } else { |
2399 » if (crv != CKR_OK) { | 2376 pk11_EnterKeyMonitor(symKey); |
2400 » mechanism_info.flags = 0; | 2377 rwsession = symKey->session; |
2401 » } | 2378 } |
2402 if (wrapType == CKM_RSA_PKCS) { | 2379 PORT_Assert(rwsession != CK_INVALID_SESSION); |
2403 » slot->RSAInfoFlags = mechanism_info.flags; | 2380 if (rwsession == CK_INVALID_SESSION) |
2404 » slot->hasRSAInfo = PR_TRUE; | 2381 crv = CKR_SESSION_HANDLE_INVALID; |
2405 » } | 2382 else |
2406 } | 2383 crv = PK11_GETTAB(slot)->C_UnwrapKey( |
2407 | 2384 rwsession, &mechanism, wrappingKey, wrappedKey->data, wrappedKey->len, |
2408 /* initialize the mechanism structure */ | 2385 keyTemplate, templateCount, &symKey->objectID); |
2409 mechanism.mechanism = wrapType; | 2386 if (isPerm) { |
2410 /* use NULL IV's for wrapping */ | 2387 if (rwsession != CK_INVALID_SESSION) PK11_RestoreROSession(slot, rwsession); |
2411 if (param == NULL)· | 2388 } else { |
2412 » param = param_free = PK11_ParamFromIV(wrapType,NULL); | 2389 pk11_ExitKeyMonitor(symKey); |
2413 if (param) { | 2390 } |
2414 » mechanism.pParameter = param->data; | 2391 if (param_free) SECITEM_FreeItem(param_free, PR_TRUE); |
2415 » mechanism.ulParameterLen = param->len; | 2392 if (crv != CKR_OK) { |
2416 } else { | 2393 PK11_FreeSymKey(symKey); |
2417 » mechanism.pParameter = NULL; | 2394 symKey = NULL; |
2418 » mechanism.ulParameterLen = 0; | 2395 if (crv != CKR_DEVICE_ERROR) { |
2419 } | 2396 /* try hand Unwrapping */ |
2420 | 2397 symKey = pk11_HandUnwrap(slot, wrappingKey, &mechanism, wrappedKey, |
2421 if ((mechanism_info.flags & CKF_DECRYPT)·· | 2398 target, keyTemplate, templateCount, keySize, |
2422 » » » » && !PK11_DoesMechanism(slot,target)) { | 2399 wincx, NULL, isPerm); |
2423 » symKey = pk11_HandUnwrap(slot, wrappingKey, &mechanism, wrappedKey,· | 2400 } |
2424 » target, keyTemplate, templateCount, keySize,· | 2401 } |
2425 » » » » wincx, &crv, isPerm); | 2402 |
2426 » if (symKey) { | 2403 return symKey; |
2427 » if (param_free) SECITEM_FreeItem(param_free,PR_TRUE); | |
2428 » return symKey; | |
2429 » } | |
2430 » /* | |
2431 » * if the RSA OP simply failed, don't try to unwrap again· | |
2432 » * with this module. | |
2433 » */ | |
2434 » if (crv == CKR_DEVICE_ERROR){ | |
2435 » if (param_free) SECITEM_FreeItem(param_free,PR_TRUE); | |
2436 » return NULL; | |
2437 » } | |
2438 » /* fall through, maybe they incorrectly set CKF_DECRYPT */ | |
2439 } | |
2440 | |
2441 /* get our key Structure */ | |
2442 symKey = pk11_CreateSymKey(slot, target, !isPerm, PR_TRUE, wincx); | |
2443 if (symKey == NULL) { | |
2444 » if (param_free) SECITEM_FreeItem(param_free,PR_TRUE); | |
2445 » return NULL; | |
2446 } | |
2447 | |
2448 symKey->size = keySize; | |
2449 symKey->origin = PK11_OriginUnwrap; | |
2450 | |
2451 if (isPerm) { | |
2452 » rwsession = PK11_GetRWSession(slot); | |
2453 } else { | |
2454 pk11_EnterKeyMonitor(symKey); | |
2455 » rwsession = symKey->session; | |
2456 } | |
2457 PORT_Assert(rwsession != CK_INVALID_SESSION); | |
2458 if (rwsession == CK_INVALID_SESSION)· | |
2459 » crv = CKR_SESSION_HANDLE_INVALID; | |
2460 else | |
2461 » crv = PK11_GETTAB(slot)->C_UnwrapKey(rwsession,&mechanism,wrappingKey, | |
2462 » » wrappedKey->data, wrappedKey->len, keyTemplate, templateCount,· | |
2463 » » » » » » » &symKey->objectID); | |
2464 if (isPerm) { | |
2465 » if (rwsession != CK_INVALID_SESSION) | |
2466 » PK11_RestoreROSession(slot, rwsession); | |
2467 } else { | |
2468 pk11_ExitKeyMonitor(symKey); | |
2469 } | |
2470 if (param_free) SECITEM_FreeItem(param_free,PR_TRUE); | |
2471 if (crv != CKR_OK) { | |
2472 » PK11_FreeSymKey(symKey); | |
2473 » symKey = NULL; | |
2474 » if (crv != CKR_DEVICE_ERROR) { | |
2475 » /* try hand Unwrapping */ | |
2476 » symKey = pk11_HandUnwrap(slot, wrappingKey, &mechanism, wrappedKey,· | |
2477 » » » » target, keyTemplate, templateCount, | |
2478 » » » » keySize, wincx, NULL, isPerm); | |
2479 » } | |
2480 } | |
2481 | |
2482 return symKey; | |
2483 } | 2404 } |
2484 | 2405 |
2485 /* use a symetric key to unwrap another symetric key */ | 2406 /* use a symetric key to unwrap another symetric key */ |
2486 PK11SymKey * | 2407 PK11SymKey *PK11_UnwrapSymKey(PK11SymKey *wrappingKey, |
2487 PK11_UnwrapSymKey( PK11SymKey *wrappingKey, CK_MECHANISM_TYPE wrapType, | 2408 CK_MECHANISM_TYPE wrapType, SECItem *param, |
2488 SECItem *param, SECItem *wrappedKey,· | 2409 SECItem *wrappedKey, CK_MECHANISM_TYPE target, |
2489 » » CK_MECHANISM_TYPE target, CK_ATTRIBUTE_TYPE operation,· | 2410 CK_ATTRIBUTE_TYPE operation, int keySize) { |
2490 » » int keySize) | 2411 return pk11_AnyUnwrapKey(wrappingKey->slot, wrappingKey->objectID, wrapType, |
2491 { | 2412 param, wrappedKey, target, operation, keySize, |
2492 return pk11_AnyUnwrapKey(wrappingKey->slot, wrappingKey->objectID, | 2413 wrappingKey->cx, NULL, 0, PR_FALSE); |
2493 » » wrapType, param, wrappedKey, target, operation, keySize,· | |
2494 » » wrappingKey->cx, NULL, 0, PR_FALSE); | |
2495 } | 2414 } |
2496 | 2415 |
2497 /* use a symetric key to unwrap another symetric key */ | 2416 /* use a symetric key to unwrap another symetric key */ |
2498 PK11SymKey * | 2417 PK11SymKey *PK11_UnwrapSymKeyWithFlags(PK11SymKey *wrappingKey, |
2499 PK11_UnwrapSymKeyWithFlags(PK11SymKey *wrappingKey, CK_MECHANISM_TYPE wrapType, | 2418 CK_MECHANISM_TYPE wrapType, |
2500 SECItem *param, SECItem *wrappedKey,· | 2419 SECItem *param, SECItem *wrappedKey, |
2501 » » CK_MECHANISM_TYPE target, CK_ATTRIBUTE_TYPE operation, | 2420 CK_MECHANISM_TYPE target, |
2502 » » int keySize, CK_FLAGS flags) | 2421 CK_ATTRIBUTE_TYPE operation, int keySize, |
2503 { | 2422 CK_FLAGS flags) { |
2504 CK_BBOOL ckTrue» = CK_TRUE;· | 2423 CK_BBOOL ckTrue = CK_TRUE; |
2505 CK_ATTRIBUTE keyTemplate[MAX_TEMPL_ATTRS]; | 2424 CK_ATTRIBUTE keyTemplate[MAX_TEMPL_ATTRS]; |
2506 unsigned int templateCount; | 2425 unsigned int templateCount; |
2507 | 2426 |
2508 templateCount = pk11_OpFlagsToAttributes(flags, keyTemplate, &ckTrue); | 2427 templateCount = pk11_OpFlagsToAttributes(flags, keyTemplate, &ckTrue); |
2509 return pk11_AnyUnwrapKey(wrappingKey->slot, wrappingKey->objectID, | 2428 return pk11_AnyUnwrapKey(wrappingKey->slot, wrappingKey->objectID, wrapType, |
2510 » » wrapType, param, wrappedKey, target, operation, keySize,· | 2429 param, wrappedKey, target, operation, keySize, |
2511 » » wrappingKey->cx, keyTemplate, templateCount, PR_FALSE); | 2430 wrappingKey->cx, keyTemplate, templateCount, |
2512 } | 2431 PR_FALSE); |
2513 | 2432 } |
2514 PK11SymKey * | 2433 |
2515 PK11_UnwrapSymKeyWithFlagsPerm(PK11SymKey *wrappingKey, | 2434 PK11SymKey *PK11_UnwrapSymKeyWithFlagsPerm( |
2516 » » CK_MECHANISM_TYPE wrapType, | 2435 PK11SymKey *wrappingKey, CK_MECHANISM_TYPE wrapType, SECItem *param, |
2517 SECItem *param, SECItem *wrappedKey, | 2436 SECItem *wrappedKey, CK_MECHANISM_TYPE target, CK_ATTRIBUTE_TYPE operation, |
2518 » » CK_MECHANISM_TYPE target, CK_ATTRIBUTE_TYPE operation,· | 2437 int keySize, CK_FLAGS flags, PRBool isPerm) { |
2519 » » int keySize, CK_FLAGS flags, PRBool isPerm) | 2438 CK_BBOOL cktrue = CK_TRUE; |
2520 { | 2439 CK_ATTRIBUTE keyTemplate[MAX_TEMPL_ATTRS]; |
2521 CK_BBOOL cktrue» = CK_TRUE;· | 2440 CK_ATTRIBUTE *attrs; |
2522 CK_ATTRIBUTE keyTemplate[MAX_TEMPL_ATTRS]; | 2441 unsigned int templateCount; |
2523 CK_ATTRIBUTE *attrs; | 2442 |
2524 unsigned int templateCount; | 2443 attrs = keyTemplate; |
2525 | 2444 if (isPerm) { |
2526 attrs = keyTemplate; | 2445 PK11_SETATTRS(attrs, CKA_TOKEN, &cktrue, sizeof(CK_BBOOL)); |
2527 if (isPerm) { | 2446 attrs++; |
2528 PK11_SETATTRS(attrs, CKA_TOKEN, &cktrue, sizeof(CK_BBOOL)); attrs++; | 2447 } |
2529 } | 2448 templateCount = attrs - keyTemplate; |
2530 templateCount = attrs-keyTemplate; | 2449 templateCount += pk11_OpFlagsToAttributes(flags, attrs, &cktrue); |
2531 templateCount += pk11_OpFlagsToAttributes(flags, attrs, &cktrue); | 2450 |
2532 | 2451 return pk11_AnyUnwrapKey(wrappingKey->slot, wrappingKey->objectID, wrapType, |
2533 return pk11_AnyUnwrapKey(wrappingKey->slot, wrappingKey->objectID, | 2452 param, wrappedKey, target, operation, keySize, |
2534 » » wrapType, param, wrappedKey, target, operation, keySize,· | 2453 wrappingKey->cx, keyTemplate, templateCount, isPerm); |
2535 » » wrappingKey->cx, keyTemplate, templateCount, isPerm); | 2454 } |
2536 } | |
2537 | |
2538 | 2455 |
2539 /* unwrap a symetric key with a private key. */ | 2456 /* unwrap a symetric key with a private key. */ |
2540 PK11SymKey * | 2457 PK11SymKey *PK11_PubUnwrapSymKey(SECKEYPrivateKey *wrappingKey, |
2541 PK11_PubUnwrapSymKey(SECKEYPrivateKey *wrappingKey, SECItem *wrappedKey, | 2458 SECItem *wrappedKey, CK_MECHANISM_TYPE target, |
2542 » CK_MECHANISM_TYPE target, CK_ATTRIBUTE_TYPE operation, int keySize) | 2459 CK_ATTRIBUTE_TYPE operation, int keySize) { |
2543 { | 2460 CK_MECHANISM_TYPE wrapType = pk11_mapWrapKeyType(wrappingKey->keyType); |
2544 CK_MECHANISM_TYPE wrapType = pk11_mapWrapKeyType(wrappingKey->keyType); | 2461 PK11SlotInfo *slot = wrappingKey->pkcs11Slot; |
2545 PK11SlotInfo *slot = wrappingKey->pkcs11Slot; | 2462 |
2546 | 2463 if (SECKEY_HAS_ATTRIBUTE_SET(wrappingKey, CKA_PRIVATE)) { |
2547 if (SECKEY_HAS_ATTRIBUTE_SET(wrappingKey,CKA_PRIVATE)) { | 2464 PK11_HandlePasswordCheck(slot, wrappingKey->wincx); |
2548 » PK11_HandlePasswordCheck(slot,wrappingKey->wincx); | 2465 } |
2549 } | 2466 |
2550 ···· | 2467 return pk11_AnyUnwrapKey(slot, wrappingKey->pkcs11ID, wrapType, NULL, |
2551 return pk11_AnyUnwrapKey(slot, wrappingKey->pkcs11ID, | 2468 wrappedKey, target, operation, keySize, |
2552 » wrapType, NULL, wrappedKey, target, operation, keySize,· | 2469 wrappingKey->wincx, NULL, 0, PR_FALSE); |
2553 » wrappingKey->wincx, NULL, 0, PR_FALSE); | |
2554 } | 2470 } |
2555 | 2471 |
2556 /* unwrap a symetric key with a private key. */ | 2472 /* unwrap a symetric key with a private key. */ |
2557 PK11SymKey * | 2473 PK11SymKey *PK11_PubUnwrapSymKeyWithFlags(SECKEYPrivateKey *wrappingKey, |
2558 PK11_PubUnwrapSymKeyWithFlags(SECKEYPrivateKey *wrappingKey,· | 2474 SECItem *wrappedKey, |
2559 » SECItem *wrappedKey, CK_MECHANISM_TYPE target,· | 2475 CK_MECHANISM_TYPE target, |
2560 » CK_ATTRIBUTE_TYPE operation, int keySize, CK_FLAGS flags) | 2476 CK_ATTRIBUTE_TYPE operation, |
2561 { | 2477 int keySize, CK_FLAGS flags) { |
2562 CK_MECHANISM_TYPE wrapType = pk11_mapWrapKeyType(wrappingKey->keyType); | 2478 CK_MECHANISM_TYPE wrapType = pk11_mapWrapKeyType(wrappingKey->keyType); |
2563 CK_BBOOL ckTrue» = CK_TRUE;· | 2479 CK_BBOOL ckTrue = CK_TRUE; |
2564 CK_ATTRIBUTE keyTemplate[MAX_TEMPL_ATTRS]; | 2480 CK_ATTRIBUTE keyTemplate[MAX_TEMPL_ATTRS]; |
2565 unsigned int templateCount; | 2481 unsigned int templateCount; |
2566 PK11SlotInfo *slot = wrappingKey->pkcs11Slot; | 2482 PK11SlotInfo *slot = wrappingKey->pkcs11Slot; |
2567 | 2483 |
2568 templateCount = pk11_OpFlagsToAttributes(flags, keyTemplate, &ckTrue); | 2484 templateCount = pk11_OpFlagsToAttributes(flags, keyTemplate, &ckTrue); |
2569 | 2485 |
2570 if (SECKEY_HAS_ATTRIBUTE_SET(wrappingKey,CKA_PRIVATE)) { | 2486 if (SECKEY_HAS_ATTRIBUTE_SET(wrappingKey, CKA_PRIVATE)) { |
2571 » PK11_HandlePasswordCheck(slot,wrappingKey->wincx); | 2487 PK11_HandlePasswordCheck(slot, wrappingKey->wincx); |
2572 } | 2488 } |
2573 ···· | 2489 |
2574 return pk11_AnyUnwrapKey(slot, wrappingKey->pkcs11ID, | 2490 return pk11_AnyUnwrapKey(slot, wrappingKey->pkcs11ID, wrapType, NULL, |
2575 » wrapType, NULL, wrappedKey, target, operation, keySize,· | 2491 wrappedKey, target, operation, keySize, |
2576 » wrappingKey->wincx, keyTemplate, templateCount, PR_FALSE); | 2492 wrappingKey->wincx, keyTemplate, templateCount, |
2577 } | 2493 PR_FALSE); |
2578 | 2494 } |
2579 PK11SymKey * | 2495 |
2580 PK11_PubUnwrapSymKeyWithFlagsPerm(SECKEYPrivateKey *wrappingKey,· | 2496 PK11SymKey *PK11_PubUnwrapSymKeyWithFlagsPerm(SECKEYPrivateKey *wrappingKey, |
2581 » SECItem *wrappedKey, CK_MECHANISM_TYPE target,· | 2497 SECItem *wrappedKey, |
2582 » CK_ATTRIBUTE_TYPE operation, int keySize, | 2498 CK_MECHANISM_TYPE target, |
2583 » CK_FLAGS flags, PRBool isPerm) | 2499 CK_ATTRIBUTE_TYPE operation, |
2584 { | 2500 int keySize, CK_FLAGS flags, |
2585 CK_MECHANISM_TYPE wrapType = pk11_mapWrapKeyType(wrappingKey->keyType); | 2501 PRBool isPerm) { |
2586 CK_BBOOL cktrue» = CK_TRUE;· | 2502 CK_MECHANISM_TYPE wrapType = pk11_mapWrapKeyType(wrappingKey->keyType); |
2587 CK_ATTRIBUTE keyTemplate[MAX_TEMPL_ATTRS]; | 2503 CK_BBOOL cktrue = CK_TRUE; |
2588 CK_ATTRIBUTE *attrs; | 2504 CK_ATTRIBUTE keyTemplate[MAX_TEMPL_ATTRS]; |
2589 unsigned int templateCount; | 2505 CK_ATTRIBUTE *attrs; |
2590 PK11SlotInfo *slot = wrappingKey->pkcs11Slot; | 2506 unsigned int templateCount; |
2591 | 2507 PK11SlotInfo *slot = wrappingKey->pkcs11Slot; |
2592 attrs = keyTemplate; | 2508 |
2593 if (isPerm) { | 2509 attrs = keyTemplate; |
2594 PK11_SETATTRS(attrs, CKA_TOKEN, &cktrue, sizeof(CK_BBOOL)); attrs++; | 2510 if (isPerm) { |
2595 } | 2511 PK11_SETATTRS(attrs, CKA_TOKEN, &cktrue, sizeof(CK_BBOOL)); |
2596 templateCount = attrs-keyTemplate; | 2512 attrs++; |
2597 | 2513 } |
2598 templateCount += pk11_OpFlagsToAttributes(flags, attrs, &cktrue); | 2514 templateCount = attrs - keyTemplate; |
2599 | 2515 |
2600 if (SECKEY_HAS_ATTRIBUTE_SET(wrappingKey,CKA_PRIVATE)) { | 2516 templateCount += pk11_OpFlagsToAttributes(flags, attrs, &cktrue); |
2601 » PK11_HandlePasswordCheck(slot,wrappingKey->wincx); | 2517 |
2602 } | 2518 if (SECKEY_HAS_ATTRIBUTE_SET(wrappingKey, CKA_PRIVATE)) { |
2603 ···· | 2519 PK11_HandlePasswordCheck(slot, wrappingKey->wincx); |
2604 return pk11_AnyUnwrapKey(slot, wrappingKey->pkcs11ID, | 2520 } |
2605 » wrapType, NULL, wrappedKey, target, operation, keySize,· | 2521 |
2606 » wrappingKey->wincx, keyTemplate, templateCount, isPerm); | 2522 return pk11_AnyUnwrapKey(slot, wrappingKey->pkcs11ID, wrapType, NULL, |
2607 } | 2523 wrappedKey, target, operation, keySize, |
2608 | 2524 wrappingKey->wincx, keyTemplate, templateCount, |
2609 PK11SymKey* | 2525 isPerm); |
2610 PK11_CopySymKeyForSigning(PK11SymKey *originalKey, CK_MECHANISM_TYPE mech) | 2526 } |
2611 { | 2527 |
2612 CK_RV crv; | 2528 PK11SymKey *PK11_CopySymKeyForSigning(PK11SymKey *originalKey, |
2613 CK_ATTRIBUTE setTemplate; | 2529 CK_MECHANISM_TYPE mech) { |
2614 CK_BBOOL ckTrue = CK_TRUE;· | 2530 CK_RV crv; |
2615 PK11SlotInfo *slot = originalKey->slot; | 2531 CK_ATTRIBUTE setTemplate; |
2616 | 2532 CK_BBOOL ckTrue = CK_TRUE; |
2617 /* first just try to set this key up for signing */ | 2533 PK11SlotInfo *slot = originalKey->slot; |
2618 PK11_SETATTRS(&setTemplate, CKA_SIGN, &ckTrue, sizeof(ckTrue)); | 2534 |
2619 pk11_EnterKeyMonitor(originalKey); | 2535 /* first just try to set this key up for signing */ |
2620 crv = PK11_GETTAB(slot)-> C_SetAttributeValue(originalKey->session, | 2536 PK11_SETATTRS(&setTemplate, CKA_SIGN, &ckTrue, sizeof(ckTrue)); |
2621 » » » » originalKey->objectID, &setTemplate, 1); | 2537 pk11_EnterKeyMonitor(originalKey); |
2622 pk11_ExitKeyMonitor(originalKey); | 2538 crv = PK11_GETTAB(slot)->C_SetAttributeValue( |
2623 if (crv == CKR_OK) { | 2539 originalKey->session, originalKey->objectID, &setTemplate, 1); |
2624 » return PK11_ReferenceSymKey(originalKey); | 2540 pk11_ExitKeyMonitor(originalKey); |
2625 } | 2541 if (crv == CKR_OK) { |
2626 | 2542 return PK11_ReferenceSymKey(originalKey); |
2627 /* nope, doesn't like it, use the pk11 copy object command */ | 2543 } |
2628 return pk11_CopyToSlot(slot, mech, CKA_SIGN, originalKey); | 2544 |
2629 } | 2545 /* nope, doesn't like it, use the pk11 copy object command */ |
2630 | 2546 return pk11_CopyToSlot(slot, mech, CKA_SIGN, originalKey); |
2631 void ·· | 2547 } |
2632 PK11_SetFortezzaHack(PK11SymKey *symKey) {· | 2548 |
2633 symKey->origin = PK11_OriginFortezzaHack; | 2549 void PK11_SetFortezzaHack(PK11SymKey *symKey) { |
| 2550 symKey->origin = PK11_OriginFortezzaHack; |
2634 } | 2551 } |
2635 | 2552 |
2636 /* | 2553 /* |
2637 * This is required to allow FORTEZZA_NULL and FORTEZZA_RC4 | 2554 * This is required to allow FORTEZZA_NULL and FORTEZZA_RC4 |
2638 * working. This function simply gets a valid IV for the keys. | 2555 * working. This function simply gets a valid IV for the keys. |
2639 */ | 2556 */ |
2640 SECStatus | 2557 SECStatus PK11_GenerateFortezzaIV(PK11SymKey *symKey, unsigned char *iv, |
2641 PK11_GenerateFortezzaIV(PK11SymKey *symKey,unsigned char *iv,int len) | 2558 int len) { |
2642 { | 2559 CK_MECHANISM mech_info; |
2643 CK_MECHANISM mech_info; | 2560 CK_ULONG count = 0; |
2644 CK_ULONG count = 0; | 2561 CK_RV crv; |
2645 CK_RV crv; | 2562 SECStatus rv = SECFailure; |
2646 SECStatus rv = SECFailure; | 2563 |
2647 | 2564 mech_info.mechanism = CKM_SKIPJACK_CBC64; |
2648 mech_info.mechanism = CKM_SKIPJACK_CBC64; | 2565 mech_info.pParameter = iv; |
2649 mech_info.pParameter = iv; | 2566 mech_info.ulParameterLen = len; |
2650 mech_info.ulParameterLen = len; | 2567 |
2651 | 2568 /* generate the IV for fortezza */ |
2652 /* generate the IV for fortezza */ | 2569 PK11_EnterSlotMonitor(symKey->slot); |
2653 PK11_EnterSlotMonitor(symKey->slot); | 2570 crv = PK11_GETTAB(symKey->slot)->C_EncryptInit(symKey->slot->session, |
2654 crv=PK11_GETTAB(symKey->slot)->C_EncryptInit(symKey->slot->session, | 2571 &mech_info, symKey->objectID); |
2655 » » » » &mech_info, symKey->objectID); | 2572 if (crv == CKR_OK) { |
2656 if (crv == CKR_OK) { | 2573 PK11_GETTAB(symKey->slot) |
2657 » PK11_GETTAB(symKey->slot)->C_EncryptFinal(symKey->slot->session, | 2574 ->C_EncryptFinal(symKey->slot->session, NULL, &count); |
2658 » » » » » » » » NULL, &count); | 2575 rv = SECSuccess; |
2659 » rv = SECSuccess; | 2576 } |
2660 } | 2577 PK11_ExitSlotMonitor(symKey->slot); |
2661 PK11_ExitSlotMonitor(symKey->slot); | 2578 return rv; |
2662 return rv; | |
2663 } | 2579 } |
2664 | 2580 |
2665 CK_OBJECT_HANDLE | 2581 CK_OBJECT_HANDLE |
2666 PK11_GetSymKeyHandle(PK11SymKey *symKey) | 2582 PK11_GetSymKeyHandle(PK11SymKey *symKey) { return symKey->objectID; } |
2667 { | |
2668 return symKey->objectID; | |
2669 } | |
2670 | |
OLD | NEW |