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 #include "pkcs11.h" | 5 #include "pkcs11.h" |
6 | 6 |
7 #ifndef DEVM_H | 7 #ifndef DEVM_H |
8 #include "devm.h" | 8 #include "devm.h" |
9 #endif /* DEVM_H */ | 9 #endif /* DEVM_H */ |
10 | 10 |
11 #ifndef CKHELPER_H | 11 #ifndef CKHELPER_H |
12 #include "ckhelper.h" | 12 #include "ckhelper.h" |
13 #endif /* CKHELPER_H */ | 13 #endif /* CKHELPER_H */ |
14 | 14 |
15 #include "pk11func.h" | 15 #include "pk11func.h" |
16 #include "dev3hack.h" | 16 #include "dev3hack.h" |
17 #include "secerr.h" | 17 #include "secerr.h" |
18 | 18 |
19 extern const NSSError NSS_ERROR_NOT_FOUND; | 19 extern const NSSError NSS_ERROR_NOT_FOUND; |
20 extern const NSSError NSS_ERROR_INVALID_ARGUMENT; | 20 extern const NSSError NSS_ERROR_INVALID_ARGUMENT; |
21 extern const NSSError NSS_ERROR_PKCS11; | 21 extern const NSSError NSS_ERROR_PKCS11; |
22 | 22 |
23 /* The number of object handles to grab during each call to C_FindObjects */ | 23 /* The number of object handles to grab during each call to C_FindObjects */ |
24 #define OBJECT_STACK_SIZE 16 | 24 #define OBJECT_STACK_SIZE 16 |
25 | 25 |
26 NSS_IMPLEMENT PRStatus | 26 NSS_IMPLEMENT PRStatus |
27 nssToken_Destroy ( | 27 nssToken_Destroy( |
28 NSSToken *tok | 28 NSSToken *tok) |
29 ) | |
30 { | 29 { |
31 if (tok) { | 30 if (tok) { |
32 » if (PR_ATOMIC_DECREMENT(&tok->base.refCount) == 0) { | 31 if (PR_ATOMIC_DECREMENT(&tok->base.refCount) == 0) { |
33 » PZ_DestroyLock(tok->base.lock); | 32 PZ_DestroyLock(tok->base.lock); |
34 » nssTokenObjectCache_Destroy(tok->cache); | 33 nssTokenObjectCache_Destroy(tok->cache); |
35 » /* The token holds the first/last reference to the slot. | 34 /* The token holds the first/last reference to the slot. |
36 » * When the token is actually destroyed, that ref must go too. | 35 * When the token is actually destroyed, that ref must go too. |
37 » */ | 36 */ |
38 » (void)nssSlot_Destroy(tok->slot); | 37 (void)nssSlot_Destroy(tok->slot); |
39 » return nssArena_Destroy(tok->base.arena); | 38 return nssArena_Destroy(tok->base.arena); |
40 » } | 39 } |
41 } | 40 } |
42 return PR_SUCCESS; | 41 return PR_SUCCESS; |
43 } | 42 } |
44 | 43 |
45 NSS_IMPLEMENT void | 44 NSS_IMPLEMENT void |
46 nssToken_Remove ( | 45 nssToken_Remove( |
47 NSSToken *tok | 46 NSSToken *tok) |
48 ) | |
49 { | 47 { |
50 nssTokenObjectCache_Clear(tok->cache); | 48 nssTokenObjectCache_Clear(tok->cache); |
51 } | 49 } |
52 | 50 |
53 NSS_IMPLEMENT void | 51 NSS_IMPLEMENT void |
54 NSSToken_Destroy ( | 52 NSSToken_Destroy( |
55 NSSToken *tok | 53 NSSToken *tok) |
56 ) | |
57 { | 54 { |
58 (void)nssToken_Destroy(tok); | 55 (void)nssToken_Destroy(tok); |
59 } | 56 } |
60 | 57 |
61 NSS_IMPLEMENT NSSToken * | 58 NSS_IMPLEMENT NSSToken * |
62 nssToken_AddRef ( | 59 nssToken_AddRef( |
63 NSSToken *tok | 60 NSSToken *tok) |
64 ) | |
65 { | 61 { |
66 PR_ATOMIC_INCREMENT(&tok->base.refCount); | 62 PR_ATOMIC_INCREMENT(&tok->base.refCount); |
67 return tok; | 63 return tok; |
68 } | 64 } |
69 | 65 |
70 NSS_IMPLEMENT NSSSlot * | 66 NSS_IMPLEMENT NSSSlot * |
71 nssToken_GetSlot ( | 67 nssToken_GetSlot( |
72 NSSToken *tok | 68 NSSToken *tok) |
73 ) | |
74 { | 69 { |
75 return nssSlot_AddRef(tok->slot); | 70 return nssSlot_AddRef(tok->slot); |
76 } | 71 } |
77 | 72 |
78 NSS_IMPLEMENT void * | 73 NSS_IMPLEMENT void * |
79 nssToken_GetCryptokiEPV ( | 74 nssToken_GetCryptokiEPV( |
80 NSSToken *token | 75 NSSToken *token) |
81 ) | |
82 { | 76 { |
83 return nssSlot_GetCryptokiEPV(token->slot); | 77 return nssSlot_GetCryptokiEPV(token->slot); |
84 } | 78 } |
85 | 79 |
86 NSS_IMPLEMENT nssSession * | 80 NSS_IMPLEMENT nssSession * |
87 nssToken_GetDefaultSession ( | 81 nssToken_GetDefaultSession( |
88 NSSToken *token | 82 NSSToken *token) |
89 ) | |
90 { | 83 { |
91 return token->defaultSession; | 84 return token->defaultSession; |
92 } | 85 } |
93 | 86 |
94 NSS_IMPLEMENT NSSUTF8 * | 87 NSS_IMPLEMENT NSSUTF8 * |
95 nssToken_GetName ( | 88 nssToken_GetName( |
96 NSSToken *tok | 89 NSSToken *tok) |
97 ) | |
98 { | 90 { |
99 if (tok == NULL) { | 91 if (tok == NULL) { |
100 » return ""; | 92 return ""; |
101 } | 93 } |
102 if (tok->base.name[0] == 0) { | 94 if (tok->base.name[0] == 0) { |
103 » (void) nssSlot_IsTokenPresent(tok->slot); | 95 (void)nssSlot_IsTokenPresent(tok->slot); |
104 } | 96 } |
105 return tok->base.name; | 97 return tok->base.name; |
106 } | 98 } |
107 | 99 |
108 NSS_IMPLEMENT NSSUTF8 * | 100 NSS_IMPLEMENT NSSUTF8 * |
109 NSSToken_GetName ( | 101 NSSToken_GetName( |
110 NSSToken *token | 102 NSSToken *token) |
111 ) | |
112 { | 103 { |
113 return nssToken_GetName(token); | 104 return nssToken_GetName(token); |
114 } | 105 } |
115 | 106 |
116 NSS_IMPLEMENT PRBool | 107 NSS_IMPLEMENT PRBool |
117 nssToken_IsLoginRequired ( | 108 nssToken_IsLoginRequired( |
118 NSSToken *token | 109 NSSToken *token) |
119 ) | |
120 { | 110 { |
121 return (token->ckFlags & CKF_LOGIN_REQUIRED); | 111 return (token->ckFlags & CKF_LOGIN_REQUIRED); |
122 } | 112 } |
123 | 113 |
124 NSS_IMPLEMENT PRBool | 114 NSS_IMPLEMENT PRBool |
125 nssToken_NeedsPINInitialization ( | 115 nssToken_NeedsPINInitialization( |
126 NSSToken *token | 116 NSSToken *token) |
127 ) | |
128 { | 117 { |
129 return (!(token->ckFlags & CKF_USER_PIN_INITIALIZED)); | 118 return (!(token->ckFlags & CKF_USER_PIN_INITIALIZED)); |
130 } | 119 } |
131 | 120 |
132 NSS_IMPLEMENT PRStatus | 121 NSS_IMPLEMENT PRStatus |
133 nssToken_DeleteStoredObject ( | 122 nssToken_DeleteStoredObject( |
134 nssCryptokiObject *instance | 123 nssCryptokiObject *instance) |
135 ) | |
136 { | 124 { |
137 CK_RV ckrv; | 125 CK_RV ckrv; |
138 PRStatus status; | 126 PRStatus status; |
139 PRBool createdSession = PR_FALSE; | 127 PRBool createdSession = PR_FALSE; |
140 NSSToken *token = instance->token; | 128 NSSToken *token = instance->token; |
141 nssSession *session = NULL; | 129 nssSession *session = NULL; |
142 void *epv = nssToken_GetCryptokiEPV(instance->token); | 130 void *epv = nssToken_GetCryptokiEPV(instance->token); |
143 if (token->cache) { | 131 if (token->cache) { |
144 » nssTokenObjectCache_RemoveObject(token->cache, instance); | 132 nssTokenObjectCache_RemoveObject(token->cache, instance); |
145 } | 133 } |
146 if (instance->isTokenObject) { | 134 if (instance->isTokenObject) { |
147 if (token->defaultSession && | 135 if (token->defaultSession && |
148 nssSession_IsReadWrite(token->defaultSession)) { | 136 nssSession_IsReadWrite(token->defaultSession)) { |
149 » session = token->defaultSession; | 137 session = token->defaultSession; |
150 } else { | 138 } else { |
151 » session = nssSlot_CreateSession(token->slot, NULL, PR_TRUE); | 139 session = nssSlot_CreateSession(token->slot, NULL, PR_TRUE); |
152 » createdSession = PR_TRUE; | 140 createdSession = PR_TRUE; |
153 } | 141 } |
154 } | 142 } |
155 if (session == NULL) { | 143 if (session == NULL) { |
156 » return PR_FAILURE; | 144 return PR_FAILURE; |
157 } | 145 } |
158 nssSession_EnterMonitor(session); | 146 nssSession_EnterMonitor(session); |
159 ckrv = CKAPI(epv)->C_DestroyObject(session->handle, instance->handle); | 147 ckrv = CKAPI(epv)->C_DestroyObject(session->handle, instance->handle); |
160 nssSession_ExitMonitor(session); | 148 nssSession_ExitMonitor(session); |
161 if (createdSession) { | 149 if (createdSession) { |
162 » nssSession_Destroy(session); | 150 nssSession_Destroy(session); |
163 } | 151 } |
164 status = PR_SUCCESS; | 152 status = PR_SUCCESS; |
165 if (ckrv != CKR_OK) { | 153 if (ckrv != CKR_OK) { |
166 » status = PR_FAILURE; | 154 status = PR_FAILURE; |
167 » /* use the error stack to pass the PKCS #11 error out */ | 155 /* use the error stack to pass the PKCS #11 error out */ |
168 » nss_SetError(ckrv); | 156 nss_SetError(ckrv); |
169 » nss_SetError(NSS_ERROR_PKCS11); | 157 nss_SetError(NSS_ERROR_PKCS11); |
170 } | 158 } |
171 return status; | 159 return status; |
172 } | 160 } |
173 | 161 |
174 static nssCryptokiObject * | 162 static nssCryptokiObject * |
175 import_object ( | 163 import_object( |
176 NSSToken *tok, | 164 NSSToken *tok, |
177 nssSession *sessionOpt, | 165 nssSession *sessionOpt, |
178 CK_ATTRIBUTE_PTR objectTemplate, | 166 CK_ATTRIBUTE_PTR objectTemplate, |
179 CK_ULONG otsize | 167 CK_ULONG otsize) |
180 ) | |
181 { | 168 { |
182 nssSession *session = NULL; | 169 nssSession *session = NULL; |
183 PRBool createdSession = PR_FALSE; | 170 PRBool createdSession = PR_FALSE; |
184 nssCryptokiObject *object = NULL; | 171 nssCryptokiObject *object = NULL; |
185 CK_OBJECT_HANDLE handle; | 172 CK_OBJECT_HANDLE handle; |
186 CK_RV ckrv; | 173 CK_RV ckrv; |
187 void *epv = nssToken_GetCryptokiEPV(tok); | 174 void *epv = nssToken_GetCryptokiEPV(tok); |
188 if (nssCKObject_IsTokenObjectTemplate(objectTemplate, otsize)) { | 175 if (nssCKObject_IsTokenObjectTemplate(objectTemplate, otsize)) { |
189 » if (sessionOpt) { | 176 if (sessionOpt) { |
190 » if (!nssSession_IsReadWrite(sessionOpt)) { | 177 if (!nssSession_IsReadWrite(sessionOpt)) { |
191 » » nss_SetError(NSS_ERROR_INVALID_ARGUMENT); | 178 nss_SetError(NSS_ERROR_INVALID_ARGUMENT); |
192 » » return NULL; | 179 return NULL; |
193 » } | 180 } |
194 » session = sessionOpt; | 181 session = sessionOpt; |
195 » } else if (tok->defaultSession && | 182 } else if (tok->defaultSession && |
196 » nssSession_IsReadWrite(tok->defaultSession)) { | 183 nssSession_IsReadWrite(tok->defaultSession)) { |
197 » session = tok->defaultSession; | 184 session = tok->defaultSession; |
198 » } else { | 185 } else { |
199 » session = nssSlot_CreateSession(tok->slot, NULL, PR_TRUE); | 186 session = nssSlot_CreateSession(tok->slot, NULL, PR_TRUE); |
200 » createdSession = PR_TRUE; | 187 createdSession = PR_TRUE; |
201 » } | 188 } |
202 } else { | 189 } else { |
203 » session = (sessionOpt) ? sessionOpt : tok->defaultSession; | 190 session = (sessionOpt) ? sessionOpt : tok->defaultSession; |
204 } | 191 } |
205 if (session == NULL) { | 192 if (session == NULL) { |
206 » nss_SetError(NSS_ERROR_INVALID_ARGUMENT); | 193 nss_SetError(NSS_ERROR_INVALID_ARGUMENT); |
207 » return NULL; | 194 return NULL; |
208 } | 195 } |
209 nssSession_EnterMonitor(session); | 196 nssSession_EnterMonitor(session); |
210 ckrv = CKAPI(epv)->C_CreateObject(session->handle, | 197 ckrv = CKAPI(epv)->C_CreateObject(session->handle, |
211 objectTemplate, otsize, | 198 objectTemplate, otsize, |
212 &handle); | 199 &handle); |
213 nssSession_ExitMonitor(session); | 200 nssSession_ExitMonitor(session); |
214 if (ckrv == CKR_OK) { | 201 if (ckrv == CKR_OK) { |
215 » object = nssCryptokiObject_Create(tok, session, handle); | 202 object = nssCryptokiObject_Create(tok, session, handle); |
216 } else { | 203 } else { |
217 » nss_SetError(ckrv); | 204 nss_SetError(ckrv); |
218 » nss_SetError(NSS_ERROR_PKCS11); | 205 nss_SetError(NSS_ERROR_PKCS11); |
219 } | 206 } |
220 if (createdSession) { | 207 if (createdSession) { |
221 » nssSession_Destroy(session); | 208 nssSession_Destroy(session); |
222 } | 209 } |
223 return object; | 210 return object; |
224 } | 211 } |
225 | 212 |
226 static nssCryptokiObject ** | 213 static nssCryptokiObject ** |
227 create_objects_from_handles ( | 214 create_objects_from_handles( |
228 NSSToken *tok, | 215 NSSToken *tok, |
229 nssSession *session, | 216 nssSession *session, |
230 CK_OBJECT_HANDLE *handles, | 217 CK_OBJECT_HANDLE *handles, |
231 PRUint32 numH | 218 PRUint32 numH) |
232 ) | |
233 { | 219 { |
234 nssCryptokiObject **objects; | 220 nssCryptokiObject **objects; |
235 objects = nss_ZNEWARRAY(NULL, nssCryptokiObject *, numH + 1); | 221 objects = nss_ZNEWARRAY(NULL, nssCryptokiObject *, numH + 1); |
236 if (objects) { | 222 if (objects) { |
237 » PRInt32 i; | 223 PRInt32 i; |
238 » for (i=0; i<(PRInt32)numH; i++) { | 224 for (i = 0; i < (PRInt32)numH; i++) { |
239 » objects[i] = nssCryptokiObject_Create(tok, session, handles[i]); | 225 objects[i] = nssCryptokiObject_Create(tok, session, handles[i]); |
240 » if (!objects[i]) { | 226 if (!objects[i]) { |
241 » » for (--i; i>0; --i) { | 227 for (--i; i > 0; --i) { |
242 » » nssCryptokiObject_Destroy(objects[i]); | 228 nssCryptokiObject_Destroy(objects[i]); |
243 » » } | 229 } |
244 » » nss_ZFreeIf(objects); | 230 nss_ZFreeIf(objects); |
245 » » objects = NULL; | 231 objects = NULL; |
246 » » break; | 232 break; |
247 » } | 233 } |
248 » } | 234 } |
249 } | 235 } |
250 return objects; | 236 return objects; |
251 } | 237 } |
252 | 238 |
253 static nssCryptokiObject ** | 239 static nssCryptokiObject ** |
254 find_objects ( | 240 find_objects( |
255 NSSToken *tok, | 241 NSSToken *tok, |
256 nssSession *sessionOpt, | 242 nssSession *sessionOpt, |
257 CK_ATTRIBUTE_PTR obj_template, | 243 CK_ATTRIBUTE_PTR obj_template, |
258 CK_ULONG otsize, | 244 CK_ULONG otsize, |
259 PRUint32 maximumOpt, | 245 PRUint32 maximumOpt, |
260 PRStatus *statusOpt | 246 PRStatus *statusOpt) |
261 ) | |
262 { | 247 { |
263 CK_RV ckrv = CKR_OK; | 248 CK_RV ckrv = CKR_OK; |
264 CK_ULONG count; | 249 CK_ULONG count; |
265 CK_OBJECT_HANDLE *objectHandles = NULL; | 250 CK_OBJECT_HANDLE *objectHandles = NULL; |
266 CK_OBJECT_HANDLE staticObjects[OBJECT_STACK_SIZE]; | 251 CK_OBJECT_HANDLE staticObjects[OBJECT_STACK_SIZE]; |
267 PRUint32 arraySize, numHandles; | 252 PRUint32 arraySize, numHandles; |
268 void *epv = nssToken_GetCryptokiEPV(tok); | 253 void *epv = nssToken_GetCryptokiEPV(tok); |
269 nssCryptokiObject **objects; | 254 nssCryptokiObject **objects; |
270 nssSession *session = (sessionOpt) ? sessionOpt : tok->defaultSession; | 255 nssSession *session = (sessionOpt) ? sessionOpt : tok->defaultSession; |
271 | 256 |
272 /* Don't ask the module to use an invalid session handle. */ | 257 /* Don't ask the module to use an invalid session handle. */ |
273 if (!session || session->handle == CK_INVALID_SESSION) { | 258 if (!session || session->handle == CK_INVALID_SESSION) { |
274 » ckrv = CKR_SESSION_HANDLE_INVALID; | 259 ckrv = CKR_SESSION_HANDLE_INVALID; |
275 » goto loser; | 260 goto loser; |
276 } | 261 } |
277 | 262 |
278 /* the arena is only for the array of object handles */ | 263 /* the arena is only for the array of object handles */ |
279 if (maximumOpt > 0) { | 264 if (maximumOpt > 0) { |
280 » arraySize = maximumOpt; | 265 arraySize = maximumOpt; |
281 } else { | 266 } else { |
282 » arraySize = OBJECT_STACK_SIZE; | 267 arraySize = OBJECT_STACK_SIZE; |
283 } | 268 } |
284 numHandles = 0; | 269 numHandles = 0; |
285 if (arraySize <= OBJECT_STACK_SIZE) { | 270 if (arraySize <= OBJECT_STACK_SIZE) { |
286 » objectHandles = staticObjects; | 271 objectHandles = staticObjects; |
287 } else { | 272 } else { |
288 » objectHandles = nss_ZNEWARRAY(NULL, CK_OBJECT_HANDLE, arraySize); | 273 objectHandles = nss_ZNEWARRAY(NULL, CK_OBJECT_HANDLE, arraySize); |
289 } | 274 } |
290 if (!objectHandles) { | 275 if (!objectHandles) { |
291 » ckrv = CKR_HOST_MEMORY; | 276 ckrv = CKR_HOST_MEMORY; |
292 » goto loser; | 277 goto loser; |
293 } | 278 } |
294 nssSession_EnterMonitor(session); /* ==== session lock === */ | 279 nssSession_EnterMonitor(session); /* ==== session lock === */ |
295 /* Initialize the find with the template */ | 280 /* Initialize the find with the template */ |
296 ckrv = CKAPI(epv)->C_FindObjectsInit(session->handle, | 281 ckrv = CKAPI(epv)->C_FindObjectsInit(session->handle, |
297 obj_template, otsize); | 282 obj_template, otsize); |
298 if (ckrv != CKR_OK) { | 283 if (ckrv != CKR_OK) { |
299 » nssSession_ExitMonitor(session); | 284 nssSession_ExitMonitor(session); |
300 » goto loser; | 285 goto loser; |
301 } | 286 } |
302 while (PR_TRUE) { | 287 while (PR_TRUE) { |
303 » /* Issue the find for up to arraySize - numHandles objects */ | 288 /* Issue the find for up to arraySize - numHandles objects */ |
304 » ckrv = CKAPI(epv)->C_FindObjects(session->handle, | 289 ckrv = CKAPI(epv)->C_FindObjects(session->handle, |
305 » objectHandles + numHandles, | 290 objectHandles + numHandles, |
306 » arraySize - numHandles, | 291 arraySize - numHandles, |
307 » &count); | 292 &count); |
308 » if (ckrv != CKR_OK) { | 293 if (ckrv != CKR_OK) { |
309 » nssSession_ExitMonitor(session); | 294 nssSession_ExitMonitor(session); |
310 » goto loser; | 295 goto loser; |
311 » } | 296 } |
312 » /* bump the number of found objects */ | 297 /* bump the number of found objects */ |
313 » numHandles += count; | 298 numHandles += count; |
314 » if (maximumOpt > 0 || numHandles < arraySize) { | 299 if (maximumOpt > 0 || numHandles < arraySize) { |
315 » /* When a maximum is provided, the search is done all at once, | 300 /* When a maximum is provided, the search is done all at once, |
316 » * so the search is finished. If the number returned was less | 301 * so the search is finished. If the number returned was less |
317 » * than the number sought, the search is finished. | 302 * than the number sought, the search is finished. |
318 » */ | 303 */ |
319 » break; | 304 break; |
320 » } | 305 } |
321 » /* the array is filled, double it and continue */ | 306 /* the array is filled, double it and continue */ |
322 » arraySize *= 2; | 307 arraySize *= 2; |
323 » if (objectHandles == staticObjects) { | 308 if (objectHandles == staticObjects) { |
324 » objectHandles = nss_ZNEWARRAY(NULL,CK_OBJECT_HANDLE, arraySize); | 309 objectHandles = nss_ZNEWARRAY(NULL, CK_OBJECT_HANDLE, arraySize); |
325 » if (objectHandles) { | 310 if (objectHandles) { |
326 » » PORT_Memcpy(objectHandles, staticObjects, | 311 PORT_Memcpy(objectHandles, staticObjects, |
327 » » » OBJECT_STACK_SIZE * sizeof(objectHandles[1])); | 312 OBJECT_STACK_SIZE * sizeof(objectHandles[1])); |
328 » } | 313 } |
329 » } else { | 314 } else { |
330 » objectHandles = nss_ZREALLOCARRAY(objectHandles, | 315 objectHandles = nss_ZREALLOCARRAY(objectHandles, |
331 » CK_OBJECT_HANDLE, | 316 CK_OBJECT_HANDLE, |
332 » arraySize); | 317 arraySize); |
333 » } | 318 } |
334 » if (!objectHandles) { | 319 if (!objectHandles) { |
335 » nssSession_ExitMonitor(session); | 320 nssSession_ExitMonitor(session); |
336 » ckrv = CKR_HOST_MEMORY; | 321 ckrv = CKR_HOST_MEMORY; |
337 » goto loser; | 322 goto loser; |
338 » } | 323 } |
339 } | 324 } |
340 ckrv = CKAPI(epv)->C_FindObjectsFinal(session->handle); | 325 ckrv = CKAPI(epv)->C_FindObjectsFinal(session->handle); |
341 nssSession_ExitMonitor(session); /* ==== end session lock === */ | 326 nssSession_ExitMonitor(session); /* ==== end session lock === */ |
342 if (ckrv != CKR_OK) { | 327 if (ckrv != CKR_OK) { |
343 » goto loser; | 328 goto loser; |
344 } | 329 } |
345 if (numHandles > 0) { | 330 if (numHandles > 0) { |
346 » objects = create_objects_from_handles(tok, session, | 331 objects = create_objects_from_handles(tok, session, |
347 » objectHandles, numHandles); | 332 objectHandles, numHandles); |
348 } else { | 333 } else { |
349 » nss_SetError(NSS_ERROR_NOT_FOUND); | 334 nss_SetError(NSS_ERROR_NOT_FOUND); |
350 » objects = NULL; | 335 objects = NULL; |
351 } | 336 } |
352 if (objectHandles && objectHandles != staticObjects) { | 337 if (objectHandles && objectHandles != staticObjects) { |
353 » nss_ZFreeIf(objectHandles); | 338 nss_ZFreeIf(objectHandles); |
354 } | 339 } |
355 if (statusOpt) *statusOpt = PR_SUCCESS; | 340 if (statusOpt) |
| 341 *statusOpt = PR_SUCCESS; |
356 return objects; | 342 return objects; |
357 loser: | 343 loser: |
358 if (objectHandles && objectHandles != staticObjects) { | 344 if (objectHandles && objectHandles != staticObjects) { |
359 » nss_ZFreeIf(objectHandles); | 345 nss_ZFreeIf(objectHandles); |
360 } | 346 } |
361 /* | 347 /* |
362 * These errors should be treated the same as if the objects just weren't | 348 * These errors should be treated the same as if the objects just weren't |
363 * found.. | 349 * found.. |
364 */ | 350 */ |
365 if ((ckrv == CKR_ATTRIBUTE_TYPE_INVALID) || | 351 if ((ckrv == CKR_ATTRIBUTE_TYPE_INVALID) || |
366 » (ckrv == CKR_ATTRIBUTE_VALUE_INVALID) || | 352 (ckrv == CKR_ATTRIBUTE_VALUE_INVALID) || |
367 » (ckrv == CKR_DATA_INVALID) || | 353 (ckrv == CKR_DATA_INVALID) || |
368 » (ckrv == CKR_DATA_LEN_RANGE) || | 354 (ckrv == CKR_DATA_LEN_RANGE) || |
369 » (ckrv == CKR_FUNCTION_NOT_SUPPORTED) || | 355 (ckrv == CKR_FUNCTION_NOT_SUPPORTED) || |
370 » (ckrv == CKR_TEMPLATE_INCOMPLETE) || | 356 (ckrv == CKR_TEMPLATE_INCOMPLETE) || |
371 » (ckrv == CKR_TEMPLATE_INCONSISTENT)) { | 357 (ckrv == CKR_TEMPLATE_INCONSISTENT)) { |
372 | 358 |
373 » nss_SetError(NSS_ERROR_NOT_FOUND); | 359 nss_SetError(NSS_ERROR_NOT_FOUND); |
374 » if (statusOpt) *statusOpt = PR_SUCCESS; | 360 if (statusOpt) |
| 361 *statusOpt = PR_SUCCESS; |
375 } else { | 362 } else { |
376 » nss_SetError(ckrv); | 363 nss_SetError(ckrv); |
377 » nss_SetError(NSS_ERROR_PKCS11); | 364 nss_SetError(NSS_ERROR_PKCS11); |
378 » if (statusOpt) *statusOpt = PR_FAILURE; | 365 if (statusOpt) |
| 366 *statusOpt = PR_FAILURE; |
379 } | 367 } |
380 return (nssCryptokiObject **)NULL; | 368 return (nssCryptokiObject **)NULL; |
381 } | 369 } |
382 | 370 |
383 static nssCryptokiObject ** | 371 static nssCryptokiObject ** |
384 find_objects_by_template ( | 372 find_objects_by_template( |
385 NSSToken *token, | 373 NSSToken *token, |
386 nssSession *sessionOpt, | 374 nssSession *sessionOpt, |
387 CK_ATTRIBUTE_PTR obj_template, | 375 CK_ATTRIBUTE_PTR obj_template, |
388 CK_ULONG otsize, | 376 CK_ULONG otsize, |
389 PRUint32 maximumOpt, | 377 PRUint32 maximumOpt, |
390 PRStatus *statusOpt | 378 PRStatus *statusOpt) |
391 ) | |
392 { | 379 { |
393 CK_OBJECT_CLASS objclass = (CK_OBJECT_CLASS)-1; | 380 CK_OBJECT_CLASS objclass = (CK_OBJECT_CLASS)-1; |
394 nssCryptokiObject **objects = NULL; | 381 nssCryptokiObject **objects = NULL; |
395 PRUint32 i; | 382 PRUint32 i; |
396 | 383 |
397 if (!token) { | 384 if (!token) { |
398 » PORT_SetError(SEC_ERROR_NO_TOKEN); | 385 PORT_SetError(SEC_ERROR_NO_TOKEN); |
399 » if (statusOpt) | 386 if (statusOpt) |
400 » *statusOpt = PR_FAILURE; | 387 *statusOpt = PR_FAILURE; |
401 » return NULL; | 388 return NULL; |
402 } | 389 } |
403 for (i=0; i<otsize; i++) { | 390 for (i = 0; i < otsize; i++) { |
404 » if (obj_template[i].type == CKA_CLASS) { | 391 if (obj_template[i].type == CKA_CLASS) { |
405 » objclass = *(CK_OBJECT_CLASS *)obj_template[i].pValue; | 392 objclass = *(CK_OBJECT_CLASS *)obj_template[i].pValue; |
406 » break; | 393 break; |
407 » } | 394 } |
408 } | 395 } |
409 PR_ASSERT(i < otsize); | 396 PR_ASSERT(i < otsize); |
410 if (i == otsize) { | 397 if (i == otsize) { |
411 » PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); | 398 PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); |
412 » if (statusOpt) *statusOpt = PR_FAILURE; | 399 if (statusOpt) |
413 » return NULL; | 400 *statusOpt = PR_FAILURE; |
| 401 return NULL; |
414 } | 402 } |
415 /* If these objects are being cached, try looking there first */ | 403 /* If these objects are being cached, try looking there first */ |
416 if (token->cache && | 404 if (token->cache && |
417 nssTokenObjectCache_HaveObjectClass(token->cache, objclass)) | 405 nssTokenObjectCache_HaveObjectClass(token->cache, objclass)) { |
418 { | 406 PRStatus status; |
419 » PRStatus status; | 407 objects = nssTokenObjectCache_FindObjectsByTemplate(token->cache, |
420 » objects = nssTokenObjectCache_FindObjectsByTemplate(token->cache, | 408 objclass, |
421 » objclass, | 409 obj_template, |
422 » obj_template, | 410 otsize, |
423 » otsize, | 411 maximumOpt, |
424 » maximumOpt, | 412 &status); |
425 » &status); | 413 if (status == PR_SUCCESS) { |
426 » if (status == PR_SUCCESS) { | 414 if (statusOpt) |
427 » if (statusOpt) *statusOpt = status; | 415 *statusOpt = status; |
428 » return objects; | 416 return objects; |
429 » } | 417 } |
430 } | 418 } |
431 /* Either they are not cached, or cache failed; look on token. */ | 419 /* Either they are not cached, or cache failed; look on token. */ |
432 objects = find_objects(token, sessionOpt, | 420 objects = find_objects(token, sessionOpt, |
433 obj_template, otsize, | 421 obj_template, otsize, |
434 maximumOpt, statusOpt); | 422 maximumOpt, statusOpt); |
435 return objects; | 423 return objects; |
436 } | 424 } |
437 | 425 |
438 extern const NSSError NSS_ERROR_INVALID_CERTIFICATE; | 426 extern const NSSError NSS_ERROR_INVALID_CERTIFICATE; |
439 | 427 |
440 NSS_IMPLEMENT nssCryptokiObject * | 428 NSS_IMPLEMENT nssCryptokiObject * |
441 nssToken_ImportCertificate ( | 429 nssToken_ImportCertificate( |
442 NSSToken *tok, | 430 NSSToken *tok, |
443 nssSession *sessionOpt, | 431 nssSession *sessionOpt, |
444 NSSCertificateType certType, | 432 NSSCertificateType certType, |
445 NSSItem *id, | 433 NSSItem *id, |
446 const NSSUTF8 *nickname, | 434 const NSSUTF8 *nickname, |
447 NSSDER *encoding, | 435 NSSDER *encoding, |
448 NSSDER *issuer, | 436 NSSDER *issuer, |
449 NSSDER *subject, | 437 NSSDER *subject, |
450 NSSDER *serial, | 438 NSSDER *serial, |
451 NSSASCII7 *email, | 439 NSSASCII7 *email, |
452 PRBool asTokenObject | 440 PRBool asTokenObject) |
453 ) | |
454 { | 441 { |
455 PRStatus status; | 442 PRStatus status; |
456 CK_CERTIFICATE_TYPE cert_type; | 443 CK_CERTIFICATE_TYPE cert_type; |
457 CK_ATTRIBUTE_PTR attr; | 444 CK_ATTRIBUTE_PTR attr; |
458 CK_ATTRIBUTE cert_tmpl[10]; | 445 CK_ATTRIBUTE cert_tmpl[10]; |
459 CK_ULONG ctsize; | 446 CK_ULONG ctsize; |
460 nssTokenSearchType searchType; | 447 nssTokenSearchType searchType; |
461 nssCryptokiObject *rvObject = NULL; | 448 nssCryptokiObject *rvObject = NULL; |
462 | 449 |
463 if (!tok) { | 450 if (!tok) { |
464 » PORT_SetError(SEC_ERROR_NO_TOKEN); | 451 PORT_SetError(SEC_ERROR_NO_TOKEN); |
465 » return NULL; | 452 return NULL; |
466 } | 453 } |
467 if (certType == NSSCertificateType_PKIX) { | 454 if (certType == NSSCertificateType_PKIX) { |
468 » cert_type = CKC_X_509; | 455 cert_type = CKC_X_509; |
469 } else { | 456 } else { |
470 » return (nssCryptokiObject *)NULL; | 457 return (nssCryptokiObject *)NULL; |
471 } | 458 } |
472 NSS_CK_TEMPLATE_START(cert_tmpl, attr, ctsize); | 459 NSS_CK_TEMPLATE_START(cert_tmpl, attr, ctsize); |
473 if (asTokenObject) { | 460 if (asTokenObject) { |
474 » NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true); | 461 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true); |
475 » searchType = nssTokenSearchType_TokenOnly; | 462 searchType = nssTokenSearchType_TokenOnly; |
476 } else { | 463 } else { |
477 » NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_false); | 464 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_false); |
478 » searchType = nssTokenSearchType_SessionOnly; | 465 searchType = nssTokenSearchType_SessionOnly; |
479 } | 466 } |
480 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_CLASS, &g_ck_class_cert); | 467 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_CLASS, &g_ck_class_cert); |
481 NSS_CK_SET_ATTRIBUTE_VAR( attr, CKA_CERTIFICATE_TYPE, cert_type); | 468 NSS_CK_SET_ATTRIBUTE_VAR(attr, CKA_CERTIFICATE_TYPE, cert_type); |
482 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_ID, id); | 469 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_ID, id); |
483 NSS_CK_SET_ATTRIBUTE_UTF8(attr, CKA_LABEL, nickname); | 470 NSS_CK_SET_ATTRIBUTE_UTF8(attr, CKA_LABEL, nickname); |
484 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_VALUE, encoding); | 471 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_VALUE, encoding); |
485 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_ISSUER, issuer); | 472 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_ISSUER, issuer); |
486 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_SUBJECT, subject); | 473 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_SUBJECT, subject); |
487 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_SERIAL_NUMBER, serial); | 474 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_SERIAL_NUMBER, serial); |
488 if (email) { | 475 if (email) { |
489 » NSS_CK_SET_ATTRIBUTE_UTF8(attr, CKA_NSS_EMAIL, email); | 476 NSS_CK_SET_ATTRIBUTE_UTF8(attr, CKA_NSS_EMAIL, email); |
490 } | 477 } |
491 NSS_CK_TEMPLATE_FINISH(cert_tmpl, attr, ctsize); | 478 NSS_CK_TEMPLATE_FINISH(cert_tmpl, attr, ctsize); |
492 /* see if the cert is already there */ | 479 /* see if the cert is already there */ |
493 rvObject = nssToken_FindCertificateByIssuerAndSerialNumber(tok, | 480 rvObject = nssToken_FindCertificateByIssuerAndSerialNumber(tok, |
494 sessionOpt, | 481 sessionOpt, |
495 issuer, | 482 issuer, |
496 serial, | 483 serial, |
497 searchType, | 484 searchType, |
498 NULL); | 485 NULL); |
499 if (rvObject) { | 486 if (rvObject) { |
500 » NSSItem existingDER; | 487 NSSItem existingDER; |
501 » NSSSlot *slot = nssToken_GetSlot(tok); | 488 NSSSlot *slot = nssToken_GetSlot(tok); |
502 » nssSession *session = nssSlot_CreateSession(slot, NULL, PR_TRUE); | 489 nssSession *session = nssSlot_CreateSession(slot, NULL, PR_TRUE); |
503 » if (!session) { | 490 if (!session) { |
504 » nssCryptokiObject_Destroy(rvObject); | 491 nssCryptokiObject_Destroy(rvObject); |
505 » nssSlot_Destroy(slot); | 492 nssSlot_Destroy(slot); |
506 » return (nssCryptokiObject *)NULL; | 493 return (nssCryptokiObject *)NULL; |
507 » } | 494 } |
508 » /* Reject any attempt to import a new cert that has the same | 495 /* Reject any attempt to import a new cert that has the same |
509 » * issuer/serial as an existing cert, but does not have the | 496 * issuer/serial as an existing cert, but does not have the |
510 » * same encoding | 497 * same encoding |
511 » */ | 498 */ |
512 » NSS_CK_TEMPLATE_START(cert_tmpl, attr, ctsize); | 499 NSS_CK_TEMPLATE_START(cert_tmpl, attr, ctsize); |
513 » NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_VALUE); | 500 NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_VALUE); |
514 » NSS_CK_TEMPLATE_FINISH(cert_tmpl, attr, ctsize); | 501 NSS_CK_TEMPLATE_FINISH(cert_tmpl, attr, ctsize); |
515 » status = nssCKObject_GetAttributes(rvObject->handle, | 502 status = nssCKObject_GetAttributes(rvObject->handle, |
516 » cert_tmpl, ctsize, NULL, | 503 cert_tmpl, ctsize, NULL, |
517 » session, slot); | 504 session, slot); |
518 » NSS_CK_ATTRIBUTE_TO_ITEM(cert_tmpl, &existingDER); | 505 NSS_CK_ATTRIBUTE_TO_ITEM(cert_tmpl, &existingDER); |
519 » if (status == PR_SUCCESS) { | 506 if (status == PR_SUCCESS) { |
520 » if (!nssItem_Equal(encoding, &existingDER, NULL)) { | 507 if (!nssItem_Equal(encoding, &existingDER, NULL)) { |
521 » » nss_SetError(NSS_ERROR_INVALID_CERTIFICATE); | 508 nss_SetError(NSS_ERROR_INVALID_CERTIFICATE); |
522 » » status = PR_FAILURE; | 509 status = PR_FAILURE; |
523 » } | 510 } |
524 » nss_ZFreeIf(existingDER.data); | 511 nss_ZFreeIf(existingDER.data); |
525 » } | 512 } |
526 » if (status == PR_FAILURE) { | 513 if (status == PR_FAILURE) { |
527 » nssCryptokiObject_Destroy(rvObject); | 514 nssCryptokiObject_Destroy(rvObject); |
528 » nssSession_Destroy(session); | 515 nssSession_Destroy(session); |
529 » nssSlot_Destroy(slot); | 516 nssSlot_Destroy(slot); |
530 » return (nssCryptokiObject *)NULL; | 517 return (nssCryptokiObject *)NULL; |
531 » } | 518 } |
532 » /* according to PKCS#11, label, ID, issuer, and serial number | 519 /* according to PKCS#11, label, ID, issuer, and serial number |
533 » * may change after the object has been created. For PKIX, the | 520 * may change after the object has been created. For PKIX, the |
534 » * last two attributes can't change, so for now we'll only worry | 521 * last two attributes can't change, so for now we'll only worry |
535 » * about the first two. | 522 * about the first two. |
536 » */ | 523 */ |
537 » NSS_CK_TEMPLATE_START(cert_tmpl, attr, ctsize); | 524 NSS_CK_TEMPLATE_START(cert_tmpl, attr, ctsize); |
538 » NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_ID, id); | 525 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_ID, id); |
539 » NSS_CK_SET_ATTRIBUTE_UTF8(attr, CKA_LABEL, nickname); | 526 NSS_CK_SET_ATTRIBUTE_UTF8(attr, CKA_LABEL, nickname); |
540 » NSS_CK_TEMPLATE_FINISH(cert_tmpl, attr, ctsize); | 527 NSS_CK_TEMPLATE_FINISH(cert_tmpl, attr, ctsize); |
541 » /* reset the mutable attributes on the token */ | 528 /* reset the mutable attributes on the token */ |
542 » nssCKObject_SetAttributes(rvObject->handle, | 529 nssCKObject_SetAttributes(rvObject->handle, |
543 » cert_tmpl, ctsize, | 530 cert_tmpl, ctsize, |
544 » session, slot); | 531 session, slot); |
545 » if (!rvObject->label && nickname) { | 532 if (!rvObject->label && nickname) { |
546 » rvObject->label = nssUTF8_Duplicate(nickname, NULL); | 533 rvObject->label = nssUTF8_Duplicate(nickname, NULL); |
547 » } | 534 } |
548 » nssSession_Destroy(session); | 535 nssSession_Destroy(session); |
549 » nssSlot_Destroy(slot); | 536 nssSlot_Destroy(slot); |
550 } else { | 537 } else { |
551 » /* Import the certificate onto the token */ | 538 /* Import the certificate onto the token */ |
552 » rvObject = import_object(tok, sessionOpt, cert_tmpl, ctsize); | 539 rvObject = import_object(tok, sessionOpt, cert_tmpl, ctsize); |
553 } | 540 } |
554 if (rvObject && tok->cache) { | 541 if (rvObject && tok->cache) { |
555 » /* The cache will overwrite the attributes if the object already | 542 /* The cache will overwrite the attributes if the object already |
556 » * exists. | 543 * exists. |
557 » */ | 544 */ |
558 » nssTokenObjectCache_ImportObject(tok->cache, rvObject, | 545 nssTokenObjectCache_ImportObject(tok->cache, rvObject, |
559 » CKO_CERTIFICATE, | 546 CKO_CERTIFICATE, |
560 » cert_tmpl, ctsize); | 547 cert_tmpl, ctsize); |
561 } | 548 } |
562 return rvObject; | 549 return rvObject; |
563 } | 550 } |
564 | 551 |
565 /* traverse all objects of the given class - this should only happen | 552 /* traverse all objects of the given class - this should only happen |
566 * if the token has been marked as "traversable" | 553 * if the token has been marked as "traversable" |
567 */ | 554 */ |
568 NSS_IMPLEMENT nssCryptokiObject ** | 555 NSS_IMPLEMENT nssCryptokiObject ** |
569 nssToken_FindObjects ( | 556 nssToken_FindObjects( |
570 NSSToken *token, | 557 NSSToken *token, |
571 nssSession *sessionOpt, | 558 nssSession *sessionOpt, |
572 CK_OBJECT_CLASS objclass, | 559 CK_OBJECT_CLASS objclass, |
573 nssTokenSearchType searchType, | 560 nssTokenSearchType searchType, |
574 PRUint32 maximumOpt, | 561 PRUint32 maximumOpt, |
575 PRStatus *statusOpt | 562 PRStatus *statusOpt) |
576 ) | |
577 { | 563 { |
578 CK_ATTRIBUTE_PTR attr; | 564 CK_ATTRIBUTE_PTR attr; |
579 CK_ATTRIBUTE obj_template[2]; | 565 CK_ATTRIBUTE obj_template[2]; |
580 CK_ULONG obj_size; | 566 CK_ULONG obj_size; |
581 nssCryptokiObject **objects; | 567 nssCryptokiObject **objects; |
582 NSS_CK_TEMPLATE_START(obj_template, attr, obj_size); | 568 NSS_CK_TEMPLATE_START(obj_template, attr, obj_size); |
583 /* Set the search to token/session only if provided */ | 569 /* Set the search to token/session only if provided */ |
584 if (searchType == nssTokenSearchType_SessionOnly) { | 570 if (searchType == nssTokenSearchType_SessionOnly) { |
585 » NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_false); | 571 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_false); |
586 } else if (searchType == nssTokenSearchType_TokenOnly || | 572 } else if (searchType == nssTokenSearchType_TokenOnly || |
587 searchType == nssTokenSearchType_TokenForced) { | 573 searchType == nssTokenSearchType_TokenForced) { |
588 » NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true); | 574 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true); |
589 } | 575 } |
590 NSS_CK_SET_ATTRIBUTE_VAR( attr, CKA_CLASS, objclass); | 576 NSS_CK_SET_ATTRIBUTE_VAR(attr, CKA_CLASS, objclass); |
591 NSS_CK_TEMPLATE_FINISH(obj_template, attr, obj_size); | 577 NSS_CK_TEMPLATE_FINISH(obj_template, attr, obj_size); |
592 | 578 |
593 if (searchType == nssTokenSearchType_TokenForced) { | 579 if (searchType == nssTokenSearchType_TokenForced) { |
594 » objects = find_objects(token, sessionOpt, | 580 objects = find_objects(token, sessionOpt, |
595 » obj_template, obj_size, | 581 obj_template, obj_size, |
596 » maximumOpt, statusOpt); | 582 maximumOpt, statusOpt); |
597 } else { | 583 } else { |
598 » objects = find_objects_by_template(token, sessionOpt, | 584 objects = find_objects_by_template(token, sessionOpt, |
599 » obj_template, obj_size, | 585 obj_template, obj_size, |
600 » maximumOpt, statusOpt); | 586 maximumOpt, statusOpt); |
601 } | 587 } |
602 return objects; | 588 return objects; |
603 } | 589 } |
604 | 590 |
605 NSS_IMPLEMENT nssCryptokiObject ** | 591 NSS_IMPLEMENT nssCryptokiObject ** |
606 nssToken_FindCertificatesBySubject ( | 592 nssToken_FindCertificatesBySubject( |
607 NSSToken *token, | 593 NSSToken *token, |
608 nssSession *sessionOpt, | 594 nssSession *sessionOpt, |
609 NSSDER *subject, | 595 NSSDER *subject, |
610 nssTokenSearchType searchType, | 596 nssTokenSearchType searchType, |
611 PRUint32 maximumOpt, | 597 PRUint32 maximumOpt, |
612 PRStatus *statusOpt | 598 PRStatus *statusOpt) |
613 ) | |
614 { | 599 { |
615 CK_ATTRIBUTE_PTR attr; | 600 CK_ATTRIBUTE_PTR attr; |
616 CK_ATTRIBUTE subj_template[3]; | 601 CK_ATTRIBUTE subj_template[3]; |
617 CK_ULONG stsize; | 602 CK_ULONG stsize; |
618 nssCryptokiObject **objects; | 603 nssCryptokiObject **objects; |
619 NSS_CK_TEMPLATE_START(subj_template, attr, stsize); | 604 NSS_CK_TEMPLATE_START(subj_template, attr, stsize); |
620 /* Set the search to token/session only if provided */ | 605 /* Set the search to token/session only if provided */ |
621 if (searchType == nssTokenSearchType_SessionOnly) { | 606 if (searchType == nssTokenSearchType_SessionOnly) { |
622 » NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_false); | 607 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_false); |
623 } else if (searchType == nssTokenSearchType_TokenOnly) { | 608 } else if (searchType == nssTokenSearchType_TokenOnly) { |
624 » NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true); | 609 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true); |
625 } | 610 } |
626 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_CLASS, &g_ck_class_cert); | 611 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_CLASS, &g_ck_class_cert); |
627 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_SUBJECT, subject); | 612 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_SUBJECT, subject); |
628 NSS_CK_TEMPLATE_FINISH(subj_template, attr, stsize); | 613 NSS_CK_TEMPLATE_FINISH(subj_template, attr, stsize); |
629 /* now locate the token certs matching this template */ | 614 /* now locate the token certs matching this template */ |
630 objects = find_objects_by_template(token, sessionOpt, | 615 objects = find_objects_by_template(token, sessionOpt, |
631 subj_template, stsize, | 616 subj_template, stsize, |
632 maximumOpt, statusOpt); | 617 maximumOpt, statusOpt); |
633 return objects; | 618 return objects; |
634 } | 619 } |
635 | 620 |
636 NSS_IMPLEMENT nssCryptokiObject ** | 621 NSS_IMPLEMENT nssCryptokiObject ** |
637 nssToken_FindCertificatesByNickname ( | 622 nssToken_FindCertificatesByNickname( |
638 NSSToken *token, | 623 NSSToken *token, |
639 nssSession *sessionOpt, | 624 nssSession *sessionOpt, |
640 const NSSUTF8 *name, | 625 const NSSUTF8 *name, |
641 nssTokenSearchType searchType, | 626 nssTokenSearchType searchType, |
642 PRUint32 maximumOpt, | 627 PRUint32 maximumOpt, |
643 PRStatus *statusOpt | 628 PRStatus *statusOpt) |
644 ) | |
645 { | 629 { |
646 CK_ATTRIBUTE_PTR attr; | 630 CK_ATTRIBUTE_PTR attr; |
647 CK_ATTRIBUTE nick_template[3]; | 631 CK_ATTRIBUTE nick_template[3]; |
648 CK_ULONG ntsize; | 632 CK_ULONG ntsize; |
649 nssCryptokiObject **objects; | 633 nssCryptokiObject **objects; |
650 NSS_CK_TEMPLATE_START(nick_template, attr, ntsize); | 634 NSS_CK_TEMPLATE_START(nick_template, attr, ntsize); |
651 NSS_CK_SET_ATTRIBUTE_UTF8(attr, CKA_LABEL, name); | 635 NSS_CK_SET_ATTRIBUTE_UTF8(attr, CKA_LABEL, name); |
652 /* Set the search to token/session only if provided */ | 636 /* Set the search to token/session only if provided */ |
653 if (searchType == nssTokenSearchType_SessionOnly) { | 637 if (searchType == nssTokenSearchType_SessionOnly) { |
654 » NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_false); | 638 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_false); |
655 } else if (searchType == nssTokenSearchType_TokenOnly) { | 639 } else if (searchType == nssTokenSearchType_TokenOnly) { |
656 » NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true); | 640 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true); |
657 } | 641 } |
658 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_CLASS, &g_ck_class_cert); | 642 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_CLASS, &g_ck_class_cert); |
659 NSS_CK_TEMPLATE_FINISH(nick_template, attr, ntsize); | 643 NSS_CK_TEMPLATE_FINISH(nick_template, attr, ntsize); |
660 /* now locate the token certs matching this template */ | 644 /* now locate the token certs matching this template */ |
661 objects = find_objects_by_template(token, sessionOpt, | 645 objects = find_objects_by_template(token, sessionOpt, |
662 nick_template, ntsize, | 646 nick_template, ntsize, |
663 maximumOpt, statusOpt); | 647 maximumOpt, statusOpt); |
664 if (!objects) { | 648 if (!objects) { |
665 » /* This is to workaround the fact that PKCS#11 doesn't specify | 649 /* This is to workaround the fact that PKCS#11 doesn't specify |
666 » * whether the '\0' should be included. XXX Is that still true? | 650 * whether the '\0' should be included. XXX Is that still true? |
667 » * im - this is not needed by the current softoken. However, I'm | 651 * im - this is not needed by the current softoken. However, I'm |
668 » * leaving it in until I have surveyed more tokens to see if it needed. | 652 * leaving it in until I have surveyed more tokens to see if it needed. |
669 » * well, its needed by the builtin token... | 653 * well, its needed by the builtin token... |
670 » */ | 654 */ |
671 » nick_template[0].ulValueLen++; | 655 nick_template[0].ulValueLen++; |
672 » objects = find_objects_by_template(token, sessionOpt, | 656 objects = find_objects_by_template(token, sessionOpt, |
673 » nick_template, ntsize, | 657 nick_template, ntsize, |
674 » maximumOpt, statusOpt); | 658 maximumOpt, statusOpt); |
675 } | 659 } |
676 return objects; | 660 return objects; |
677 } | 661 } |
678 | 662 |
679 /* XXX | 663 /* XXX |
680 * This function *does not* use the token object cache, because not even | 664 * This function *does not* use the token object cache, because not even |
681 * the softoken will return a value for CKA_NSS_EMAIL from a call | 665 * the softoken will return a value for CKA_NSS_EMAIL from a call |
682 * to GetAttributes. The softoken does allow searches with that attribute, | 666 * to GetAttributes. The softoken does allow searches with that attribute, |
683 * it just won't return a value for it. | 667 * it just won't return a value for it. |
684 */ | 668 */ |
685 NSS_IMPLEMENT nssCryptokiObject ** | 669 NSS_IMPLEMENT nssCryptokiObject ** |
686 nssToken_FindCertificatesByEmail ( | 670 nssToken_FindCertificatesByEmail( |
687 NSSToken *token, | 671 NSSToken *token, |
688 nssSession *sessionOpt, | 672 nssSession *sessionOpt, |
689 NSSASCII7 *email, | 673 NSSASCII7 *email, |
690 nssTokenSearchType searchType, | 674 nssTokenSearchType searchType, |
691 PRUint32 maximumOpt, | 675 PRUint32 maximumOpt, |
692 PRStatus *statusOpt | 676 PRStatus *statusOpt) |
693 ) | |
694 { | 677 { |
695 CK_ATTRIBUTE_PTR attr; | 678 CK_ATTRIBUTE_PTR attr; |
696 CK_ATTRIBUTE email_template[3]; | 679 CK_ATTRIBUTE email_template[3]; |
697 CK_ULONG etsize; | 680 CK_ULONG etsize; |
698 nssCryptokiObject **objects; | 681 nssCryptokiObject **objects; |
699 NSS_CK_TEMPLATE_START(email_template, attr, etsize); | 682 NSS_CK_TEMPLATE_START(email_template, attr, etsize); |
700 NSS_CK_SET_ATTRIBUTE_UTF8(attr, CKA_NSS_EMAIL, email); | 683 NSS_CK_SET_ATTRIBUTE_UTF8(attr, CKA_NSS_EMAIL, email); |
701 /* Set the search to token/session only if provided */ | 684 /* Set the search to token/session only if provided */ |
702 if (searchType == nssTokenSearchType_SessionOnly) { | 685 if (searchType == nssTokenSearchType_SessionOnly) { |
703 » NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_false); | 686 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_false); |
704 } else if (searchType == nssTokenSearchType_TokenOnly) { | 687 } else if (searchType == nssTokenSearchType_TokenOnly) { |
705 » NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true); | 688 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true); |
706 } | 689 } |
707 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_CLASS, &g_ck_class_cert); | 690 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_CLASS, &g_ck_class_cert); |
708 NSS_CK_TEMPLATE_FINISH(email_template, attr, etsize); | 691 NSS_CK_TEMPLATE_FINISH(email_template, attr, etsize); |
709 /* now locate the token certs matching this template */ | 692 /* now locate the token certs matching this template */ |
710 objects = find_objects(token, sessionOpt, | 693 objects = find_objects(token, sessionOpt, |
711 email_template, etsize, | 694 email_template, etsize, |
712 maximumOpt, statusOpt); | 695 maximumOpt, statusOpt); |
713 if (!objects) { | 696 if (!objects) { |
714 » /* This is to workaround the fact that PKCS#11 doesn't specify | 697 /* This is to workaround the fact that PKCS#11 doesn't specify |
715 » * whether the '\0' should be included. XXX Is that still true? | 698 * whether the '\0' should be included. XXX Is that still true? |
716 » * im - this is not needed by the current softoken. However, I'm | 699 * im - this is not needed by the current softoken. However, I'm |
717 » * leaving it in until I have surveyed more tokens to see if it needed. | 700 * leaving it in until I have surveyed more tokens to see if it needed. |
718 » * well, its needed by the builtin token... | 701 * well, its needed by the builtin token... |
719 » */ | 702 */ |
720 » email_template[0].ulValueLen++; | 703 email_template[0].ulValueLen++; |
721 » objects = find_objects(token, sessionOpt, | 704 objects = find_objects(token, sessionOpt, |
722 » email_template, etsize, | 705 email_template, etsize, |
723 » maximumOpt, statusOpt); | 706 maximumOpt, statusOpt); |
724 } | 707 } |
725 return objects; | 708 return objects; |
726 } | 709 } |
727 | 710 |
728 NSS_IMPLEMENT nssCryptokiObject ** | 711 NSS_IMPLEMENT nssCryptokiObject ** |
729 nssToken_FindCertificatesByID ( | 712 nssToken_FindCertificatesByID( |
730 NSSToken *token, | 713 NSSToken *token, |
731 nssSession *sessionOpt, | 714 nssSession *sessionOpt, |
732 NSSItem *id, | 715 NSSItem *id, |
733 nssTokenSearchType searchType, | 716 nssTokenSearchType searchType, |
734 PRUint32 maximumOpt, | 717 PRUint32 maximumOpt, |
735 PRStatus *statusOpt | 718 PRStatus *statusOpt) |
736 ) | |
737 { | 719 { |
738 CK_ATTRIBUTE_PTR attr; | 720 CK_ATTRIBUTE_PTR attr; |
739 CK_ATTRIBUTE id_template[3]; | 721 CK_ATTRIBUTE id_template[3]; |
740 CK_ULONG idtsize; | 722 CK_ULONG idtsize; |
741 nssCryptokiObject **objects; | 723 nssCryptokiObject **objects; |
742 NSS_CK_TEMPLATE_START(id_template, attr, idtsize); | 724 NSS_CK_TEMPLATE_START(id_template, attr, idtsize); |
743 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_ID, id); | 725 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_ID, id); |
744 /* Set the search to token/session only if provided */ | 726 /* Set the search to token/session only if provided */ |
745 if (searchType == nssTokenSearchType_SessionOnly) { | 727 if (searchType == nssTokenSearchType_SessionOnly) { |
746 » NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_false); | 728 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_false); |
747 } else if (searchType == nssTokenSearchType_TokenOnly) { | 729 } else if (searchType == nssTokenSearchType_TokenOnly) { |
748 » NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true); | 730 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true); |
749 } | 731 } |
750 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_CLASS, &g_ck_class_cert); | 732 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_CLASS, &g_ck_class_cert); |
751 NSS_CK_TEMPLATE_FINISH(id_template, attr, idtsize); | 733 NSS_CK_TEMPLATE_FINISH(id_template, attr, idtsize); |
752 /* now locate the token certs matching this template */ | 734 /* now locate the token certs matching this template */ |
753 objects = find_objects_by_template(token, sessionOpt, | 735 objects = find_objects_by_template(token, sessionOpt, |
754 id_template, idtsize, | 736 id_template, idtsize, |
755 maximumOpt, statusOpt); | 737 maximumOpt, statusOpt); |
756 return objects; | 738 return objects; |
757 } | 739 } |
758 | 740 |
759 /* | 741 /* |
760 * decode the serial item and return our result. | 742 * decode the serial item and return our result. |
761 * NOTE serialDecode's data is really stored in serial. Don't free it. | 743 * NOTE serialDecode's data is really stored in serial. Don't free it. |
762 */ | 744 */ |
763 static PRStatus | 745 static PRStatus |
764 nssToken_decodeSerialItem(NSSItem *serial, NSSItem *serialDecode) | 746 nssToken_decodeSerialItem(NSSItem *serial, NSSItem *serialDecode) |
765 { | 747 { |
766 unsigned char *data = (unsigned char *)serial->data; | 748 unsigned char *data = (unsigned char *)serial->data; |
767 int data_left, data_len, index; | 749 int data_left, data_len, index; |
768 | 750 |
769 if ((serial->size >= 3) && (data[0] == 0x2)) { | 751 if ((serial->size >= 3) && (data[0] == 0x2)) { |
770 » /* remove the der encoding of the serial number before generating the | 752 /* remove the der encoding of the serial number before generating the |
771 » * key.. */ | 753 * key.. */ |
772 » data_left = serial->size-2; | 754 data_left = serial->size - 2; |
773 » data_len = data[1]; | 755 data_len = data[1]; |
774 » index = 2; | 756 index = 2; |
775 | 757 |
776 » /* extended length ? (not very likely for a serial number) */ | 758 /* extended length ? (not very likely for a serial number) */ |
777 » if (data_len & 0x80) { | 759 if (data_len & 0x80) { |
778 » int len_count = data_len & 0x7f; | 760 int len_count = data_len & 0x7f; |
779 | 761 |
780 » data_len = 0; | 762 data_len = 0; |
781 » data_left -= len_count; | 763 data_left -= len_count; |
782 » if (data_left > 0) { | 764 if (data_left > 0) { |
783 » » while (len_count --) { | 765 while (len_count--) { |
784 » » data_len = (data_len << 8) | data[index++]; | 766 data_len = (data_len << 8) | data[index++]; |
785 » » } | 767 } |
786 » } | 768 } |
787 » } | 769 } |
788 » /* XXX leaving any leading zeros on the serial number for backwards | 770 /* XXX leaving any leading zeros on the serial number for backwards |
789 » * compatibility | 771 * compatibility |
790 » */ | 772 */ |
791 » /* not a valid der, must be just an unlucky serial number value */ | 773 /* not a valid der, must be just an unlucky serial number value */ |
792 » if (data_len == data_left) { | 774 if (data_len == data_left) { |
793 » serialDecode->size = data_len; | 775 serialDecode->size = data_len; |
794 » serialDecode->data = &data[index]; | 776 serialDecode->data = &data[index]; |
795 » return PR_SUCCESS; | 777 return PR_SUCCESS; |
796 » } | 778 } |
797 } | 779 } |
798 return PR_FAILURE; | 780 return PR_FAILURE; |
799 } | 781 } |
800 | 782 |
801 NSS_IMPLEMENT nssCryptokiObject * | 783 NSS_IMPLEMENT nssCryptokiObject * |
802 nssToken_FindCertificateByIssuerAndSerialNumber ( | 784 nssToken_FindCertificateByIssuerAndSerialNumber( |
803 NSSToken *token, | 785 NSSToken *token, |
804 nssSession *sessionOpt, | 786 nssSession *sessionOpt, |
805 NSSDER *issuer, | 787 NSSDER *issuer, |
806 NSSDER *serial, | 788 NSSDER *serial, |
807 nssTokenSearchType searchType, | 789 nssTokenSearchType searchType, |
808 PRStatus *statusOpt | 790 PRStatus *statusOpt) |
809 ) | |
810 { | 791 { |
811 CK_ATTRIBUTE_PTR attr; | 792 CK_ATTRIBUTE_PTR attr; |
812 CK_ATTRIBUTE_PTR serialAttr; | 793 CK_ATTRIBUTE_PTR serialAttr; |
813 CK_ATTRIBUTE cert_template[4]; | 794 CK_ATTRIBUTE cert_template[4]; |
814 CK_ULONG ctsize; | 795 CK_ULONG ctsize; |
815 nssCryptokiObject **objects; | 796 nssCryptokiObject **objects; |
816 nssCryptokiObject *rvObject = NULL; | 797 nssCryptokiObject *rvObject = NULL; |
817 NSS_CK_TEMPLATE_START(cert_template, attr, ctsize); | 798 NSS_CK_TEMPLATE_START(cert_template, attr, ctsize); |
818 | 799 |
819 if (!token) { | 800 if (!token) { |
820 » PORT_SetError(SEC_ERROR_NO_TOKEN); | 801 PORT_SetError(SEC_ERROR_NO_TOKEN); |
821 » if (statusOpt) | 802 if (statusOpt) |
822 » *statusOpt = PR_FAILURE; | 803 *statusOpt = PR_FAILURE; |
823 » return NULL; | 804 return NULL; |
824 } | 805 } |
825 /* Set the search to token/session only if provided */ | 806 /* Set the search to token/session only if provided */ |
826 if (searchType == nssTokenSearchType_SessionOnly) { | 807 if (searchType == nssTokenSearchType_SessionOnly) { |
827 » NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_false); | 808 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_false); |
828 } else if ((searchType == nssTokenSearchType_TokenOnly) || | 809 } else if ((searchType == nssTokenSearchType_TokenOnly) || |
829 (searchType == nssTokenSearchType_TokenForced)) { | 810 (searchType == nssTokenSearchType_TokenForced)) { |
830 » NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true); | 811 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true); |
831 } | 812 } |
832 /* Set the unique id */ | 813 /* Set the unique id */ |
833 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_CLASS, &g_ck_class_cert); | 814 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_CLASS, &g_ck_class_cert); |
834 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_ISSUER, issuer); | 815 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_ISSUER, issuer); |
835 serialAttr = attr; | 816 serialAttr = attr; |
836 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_SERIAL_NUMBER, serial); | 817 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_SERIAL_NUMBER, serial); |
837 NSS_CK_TEMPLATE_FINISH(cert_template, attr, ctsize); | 818 NSS_CK_TEMPLATE_FINISH(cert_template, attr, ctsize); |
838 /* get the object handle */ | 819 /* get the object handle */ |
839 if (searchType == nssTokenSearchType_TokenForced) { | 820 if (searchType == nssTokenSearchType_TokenForced) { |
840 » objects = find_objects(token, sessionOpt, | 821 objects = find_objects(token, sessionOpt, |
841 » cert_template, ctsize, | 822 cert_template, ctsize, |
842 » 1, statusOpt); | 823 1, statusOpt); |
843 } else { | 824 } else { |
844 » objects = find_objects_by_template(token, sessionOpt, | 825 objects = find_objects_by_template(token, sessionOpt, |
845 cert_template, ctsize, | 826 cert_template, ctsize, |
846 1, statusOpt); | 827 1, statusOpt); |
847 } | 828 } |
848 if (objects) { | 829 if (objects) { |
849 » rvObject = objects[0]; | 830 rvObject = objects[0]; |
850 » nss_ZFreeIf(objects); | 831 nss_ZFreeIf(objects); |
851 } | 832 } |
852 | 833 |
853 /* | 834 /* |
854 * NSS used to incorrectly store serial numbers in their decoded form. | 835 * NSS used to incorrectly store serial numbers in their decoded form. |
855 * because of this old tokens have decoded serial numbers. | 836 * because of this old tokens have decoded serial numbers. |
856 */ | 837 */ |
857 if (!objects) { | 838 if (!objects) { |
858 » NSSItem serialDecode; | 839 NSSItem serialDecode; |
859 » PRStatus status; | 840 PRStatus status; |
860 | 841 |
861 » status = nssToken_decodeSerialItem(serial, &serialDecode); | 842 status = nssToken_decodeSerialItem(serial, &serialDecode); |
862 » if (status != PR_SUCCESS) { | 843 if (status != PR_SUCCESS) { |
863 » return NULL; | 844 return NULL; |
864 » } | 845 } |
865 » NSS_CK_SET_ATTRIBUTE_ITEM(serialAttr,CKA_SERIAL_NUMBER,&serialDecode); | 846 NSS_CK_SET_ATTRIBUTE_ITEM(serialAttr, CKA_SERIAL_NUMBER, &serialDecode); |
866 » if (searchType == nssTokenSearchType_TokenForced) { | 847 if (searchType == nssTokenSearchType_TokenForced) { |
867 » objects = find_objects(token, sessionOpt, | 848 objects = find_objects(token, sessionOpt, |
868 » cert_template, ctsize, | 849 cert_template, ctsize, |
869 » 1, statusOpt); | 850 1, statusOpt); |
870 » } else { | 851 } else { |
871 » objects = find_objects_by_template(token, sessionOpt, | 852 objects = find_objects_by_template(token, sessionOpt, |
872 cert_template, ctsize, | 853 cert_template, ctsize, |
873 1, statusOpt); | 854 1, statusOpt); |
874 » } | 855 } |
875 » if (objects) { | 856 if (objects) { |
876 » rvObject = objects[0]; | 857 rvObject = objects[0]; |
877 » nss_ZFreeIf(objects); | 858 nss_ZFreeIf(objects); |
878 » } | 859 } |
879 } | 860 } |
880 return rvObject; | 861 return rvObject; |
881 } | 862 } |
882 | 863 |
883 NSS_IMPLEMENT nssCryptokiObject * | 864 NSS_IMPLEMENT nssCryptokiObject * |
884 nssToken_FindCertificateByEncodedCertificate ( | 865 nssToken_FindCertificateByEncodedCertificate( |
885 NSSToken *token, | 866 NSSToken *token, |
886 nssSession *sessionOpt, | 867 nssSession *sessionOpt, |
887 NSSBER *encodedCertificate, | 868 NSSBER *encodedCertificate, |
888 nssTokenSearchType searchType, | 869 nssTokenSearchType searchType, |
889 PRStatus *statusOpt | 870 PRStatus *statusOpt) |
890 ) | |
891 { | 871 { |
892 CK_ATTRIBUTE_PTR attr; | 872 CK_ATTRIBUTE_PTR attr; |
893 CK_ATTRIBUTE cert_template[3]; | 873 CK_ATTRIBUTE cert_template[3]; |
894 CK_ULONG ctsize; | 874 CK_ULONG ctsize; |
895 nssCryptokiObject **objects; | 875 nssCryptokiObject **objects; |
896 nssCryptokiObject *rvObject = NULL; | 876 nssCryptokiObject *rvObject = NULL; |
897 NSS_CK_TEMPLATE_START(cert_template, attr, ctsize); | 877 NSS_CK_TEMPLATE_START(cert_template, attr, ctsize); |
898 /* Set the search to token/session only if provided */ | 878 /* Set the search to token/session only if provided */ |
899 if (searchType == nssTokenSearchType_SessionOnly) { | 879 if (searchType == nssTokenSearchType_SessionOnly) { |
900 » NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_false); | 880 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_false); |
901 } else if (searchType == nssTokenSearchType_TokenOnly) { | 881 } else if (searchType == nssTokenSearchType_TokenOnly) { |
902 » NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true); | 882 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true); |
903 } | 883 } |
904 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_CLASS, &g_ck_class_cert); | 884 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_CLASS, &g_ck_class_cert); |
905 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_VALUE, encodedCertificate); | 885 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_VALUE, encodedCertificate); |
906 NSS_CK_TEMPLATE_FINISH(cert_template, attr, ctsize); | 886 NSS_CK_TEMPLATE_FINISH(cert_template, attr, ctsize); |
907 /* get the object handle */ | 887 /* get the object handle */ |
908 objects = find_objects_by_template(token, sessionOpt, | 888 objects = find_objects_by_template(token, sessionOpt, |
909 cert_template, ctsize, | 889 cert_template, ctsize, |
910 1, statusOpt); | 890 1, statusOpt); |
911 if (objects) { | 891 if (objects) { |
912 » rvObject = objects[0]; | 892 rvObject = objects[0]; |
913 » nss_ZFreeIf(objects); | 893 nss_ZFreeIf(objects); |
914 } | 894 } |
915 return rvObject; | 895 return rvObject; |
916 } | 896 } |
917 | 897 |
918 NSS_IMPLEMENT nssCryptokiObject ** | 898 NSS_IMPLEMENT nssCryptokiObject ** |
919 nssToken_FindPrivateKeys ( | 899 nssToken_FindPrivateKeys( |
920 NSSToken *token, | 900 NSSToken *token, |
921 nssSession *sessionOpt, | 901 nssSession *sessionOpt, |
922 nssTokenSearchType searchType, | 902 nssTokenSearchType searchType, |
923 PRUint32 maximumOpt, | 903 PRUint32 maximumOpt, |
924 PRStatus *statusOpt | 904 PRStatus *statusOpt) |
925 ) | |
926 { | 905 { |
927 CK_ATTRIBUTE_PTR attr; | 906 CK_ATTRIBUTE_PTR attr; |
928 CK_ATTRIBUTE key_template[2]; | 907 CK_ATTRIBUTE key_template[2]; |
929 CK_ULONG ktsize; | 908 CK_ULONG ktsize; |
930 nssCryptokiObject **objects; | 909 nssCryptokiObject **objects; |
931 | 910 |
932 NSS_CK_TEMPLATE_START(key_template, attr, ktsize); | 911 NSS_CK_TEMPLATE_START(key_template, attr, ktsize); |
933 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_CLASS, &g_ck_class_privkey); | 912 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_CLASS, &g_ck_class_privkey); |
934 if (searchType == nssTokenSearchType_SessionOnly) { | 913 if (searchType == nssTokenSearchType_SessionOnly) { |
935 » NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_false); | 914 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_false); |
936 } else if (searchType == nssTokenSearchType_TokenOnly) { | 915 } else if (searchType == nssTokenSearchType_TokenOnly) { |
937 » NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true); | 916 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true); |
938 } | 917 } |
939 NSS_CK_TEMPLATE_FINISH(key_template, attr, ktsize); | 918 NSS_CK_TEMPLATE_FINISH(key_template, attr, ktsize); |
940 | 919 |
941 objects = find_objects_by_template(token, sessionOpt, | 920 objects = find_objects_by_template(token, sessionOpt, |
942 key_template, ktsize, | 921 key_template, ktsize, |
943 maximumOpt, statusOpt); | 922 maximumOpt, statusOpt); |
944 return objects; | 923 return objects; |
945 } | 924 } |
946 | 925 |
947 /* XXX ?there are no session cert objects, so only search token objects */ | 926 /* XXX ?there are no session cert objects, so only search token objects */ |
948 NSS_IMPLEMENT nssCryptokiObject * | 927 NSS_IMPLEMENT nssCryptokiObject * |
949 nssToken_FindPrivateKeyByID ( | 928 nssToken_FindPrivateKeyByID( |
950 NSSToken *token, | 929 NSSToken *token, |
951 nssSession *sessionOpt, | 930 nssSession *sessionOpt, |
952 NSSItem *keyID | 931 NSSItem *keyID) |
953 ) | |
954 { | 932 { |
955 CK_ATTRIBUTE_PTR attr; | 933 CK_ATTRIBUTE_PTR attr; |
956 CK_ATTRIBUTE key_template[3]; | 934 CK_ATTRIBUTE key_template[3]; |
957 CK_ULONG ktsize; | 935 CK_ULONG ktsize; |
958 nssCryptokiObject **objects; | 936 nssCryptokiObject **objects; |
959 nssCryptokiObject *rvKey = NULL; | 937 nssCryptokiObject *rvKey = NULL; |
960 | 938 |
961 NSS_CK_TEMPLATE_START(key_template, attr, ktsize); | 939 NSS_CK_TEMPLATE_START(key_template, attr, ktsize); |
962 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_CLASS, &g_ck_class_privkey); | 940 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_CLASS, &g_ck_class_privkey); |
963 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true); | 941 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true); |
964 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_ID, keyID); | 942 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_ID, keyID); |
965 NSS_CK_TEMPLATE_FINISH(key_template, attr, ktsize); | 943 NSS_CK_TEMPLATE_FINISH(key_template, attr, ktsize); |
966 | 944 |
967 objects = find_objects_by_template(token, sessionOpt, | 945 objects = find_objects_by_template(token, sessionOpt, |
968 key_template, ktsize, | 946 key_template, ktsize, |
969 1, NULL); | 947 1, NULL); |
970 if (objects) { | 948 if (objects) { |
971 » rvKey = objects[0]; | 949 rvKey = objects[0]; |
972 » nss_ZFreeIf(objects); | 950 nss_ZFreeIf(objects); |
973 } | 951 } |
974 return rvKey; | 952 return rvKey; |
975 } | 953 } |
976 | 954 |
977 /* XXX ?there are no session cert objects, so only search token objects */ | 955 /* XXX ?there are no session cert objects, so only search token objects */ |
978 NSS_IMPLEMENT nssCryptokiObject * | 956 NSS_IMPLEMENT nssCryptokiObject * |
979 nssToken_FindPublicKeyByID ( | 957 nssToken_FindPublicKeyByID( |
980 NSSToken *token, | 958 NSSToken *token, |
981 nssSession *sessionOpt, | 959 nssSession *sessionOpt, |
982 NSSItem *keyID | 960 NSSItem *keyID) |
983 ) | |
984 { | 961 { |
985 CK_ATTRIBUTE_PTR attr; | 962 CK_ATTRIBUTE_PTR attr; |
986 CK_ATTRIBUTE key_template[3]; | 963 CK_ATTRIBUTE key_template[3]; |
987 CK_ULONG ktsize; | 964 CK_ULONG ktsize; |
988 nssCryptokiObject **objects; | 965 nssCryptokiObject **objects; |
989 nssCryptokiObject *rvKey = NULL; | 966 nssCryptokiObject *rvKey = NULL; |
990 | 967 |
991 NSS_CK_TEMPLATE_START(key_template, attr, ktsize); | 968 NSS_CK_TEMPLATE_START(key_template, attr, ktsize); |
992 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_CLASS, &g_ck_class_pubkey); | 969 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_CLASS, &g_ck_class_pubkey); |
993 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true); | 970 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true); |
994 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_ID, keyID); | 971 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_ID, keyID); |
995 NSS_CK_TEMPLATE_FINISH(key_template, attr, ktsize); | 972 NSS_CK_TEMPLATE_FINISH(key_template, attr, ktsize); |
996 | 973 |
997 objects = find_objects_by_template(token, sessionOpt, | 974 objects = find_objects_by_template(token, sessionOpt, |
998 key_template, ktsize, | 975 key_template, ktsize, |
999 1, NULL); | 976 1, NULL); |
1000 if (objects) { | 977 if (objects) { |
1001 » rvKey = objects[0]; | 978 rvKey = objects[0]; |
1002 » nss_ZFreeIf(objects); | 979 nss_ZFreeIf(objects); |
1003 } | 980 } |
1004 return rvKey; | 981 return rvKey; |
1005 } | 982 } |
1006 | 983 |
1007 static void | 984 static void |
1008 sha1_hash(NSSItem *input, NSSItem *output) | 985 sha1_hash(NSSItem *input, NSSItem *output) |
1009 { | 986 { |
1010 NSSAlgorithmAndParameters *ap; | 987 NSSAlgorithmAndParameters *ap; |
1011 PK11SlotInfo *internal = PK11_GetInternalSlot(); | 988 PK11SlotInfo *internal = PK11_GetInternalSlot(); |
1012 NSSToken *token = PK11Slot_GetNSSToken(internal); | 989 NSSToken *token = PK11Slot_GetNSSToken(internal); |
1013 ap = NSSAlgorithmAndParameters_CreateSHA1Digest(NULL); | 990 ap = NSSAlgorithmAndParameters_CreateSHA1Digest(NULL); |
1014 (void)nssToken_Digest(token, NULL, ap, input, output, NULL); | 991 (void)nssToken_Digest(token, NULL, ap, input, output, NULL); |
1015 PK11_FreeSlot(token->pk11slot); | 992 PK11_FreeSlot(token->pk11slot); |
1016 nss_ZFreeIf(ap); | 993 nss_ZFreeIf(ap); |
1017 } | 994 } |
1018 | 995 |
1019 static void | 996 static void |
1020 md5_hash(NSSItem *input, NSSItem *output) | 997 md5_hash(NSSItem *input, NSSItem *output) |
1021 { | 998 { |
1022 NSSAlgorithmAndParameters *ap; | 999 NSSAlgorithmAndParameters *ap; |
1023 PK11SlotInfo *internal = PK11_GetInternalSlot(); | 1000 PK11SlotInfo *internal = PK11_GetInternalSlot(); |
1024 NSSToken *token = PK11Slot_GetNSSToken(internal); | 1001 NSSToken *token = PK11Slot_GetNSSToken(internal); |
1025 ap = NSSAlgorithmAndParameters_CreateMD5Digest(NULL); | 1002 ap = NSSAlgorithmAndParameters_CreateMD5Digest(NULL); |
1026 (void)nssToken_Digest(token, NULL, ap, input, output, NULL); | 1003 (void)nssToken_Digest(token, NULL, ap, input, output, NULL); |
1027 PK11_FreeSlot(token->pk11slot); | 1004 PK11_FreeSlot(token->pk11slot); |
1028 nss_ZFreeIf(ap); | 1005 nss_ZFreeIf(ap); |
1029 } | 1006 } |
1030 | 1007 |
1031 static CK_TRUST | 1008 static CK_TRUST |
1032 get_ck_trust ( | 1009 get_ck_trust( |
1033 nssTrustLevel nssTrust | 1010 nssTrustLevel nssTrust) |
1034 ) | |
1035 { | 1011 { |
1036 CK_TRUST t; | 1012 CK_TRUST t; |
1037 switch (nssTrust) { | 1013 switch (nssTrust) { |
1038 case nssTrustLevel_NotTrusted: t = CKT_NSS_NOT_TRUSTED; break; | 1014 case nssTrustLevel_NotTrusted: |
1039 case nssTrustLevel_TrustedDelegator: t = CKT_NSS_TRUSTED_DELEGATOR; | 1015 t = CKT_NSS_NOT_TRUSTED; |
1040 » break; | 1016 break; |
1041 case nssTrustLevel_ValidDelegator: t = CKT_NSS_VALID_DELEGATOR; break; | 1017 case nssTrustLevel_TrustedDelegator: |
1042 case nssTrustLevel_Trusted: t = CKT_NSS_TRUSTED; break; | 1018 t = CKT_NSS_TRUSTED_DELEGATOR; |
1043 case nssTrustLevel_MustVerify: t = CKT_NSS_MUST_VERIFY_TRUST; break; | 1019 break; |
1044 case nssTrustLevel_Unknown: | 1020 case nssTrustLevel_ValidDelegator: |
1045 default: t = CKT_NSS_TRUST_UNKNOWN; break; | 1021 t = CKT_NSS_VALID_DELEGATOR; |
| 1022 break; |
| 1023 case nssTrustLevel_Trusted: |
| 1024 t = CKT_NSS_TRUSTED; |
| 1025 break; |
| 1026 case nssTrustLevel_MustVerify: |
| 1027 t = CKT_NSS_MUST_VERIFY_TRUST; |
| 1028 break; |
| 1029 case nssTrustLevel_Unknown: |
| 1030 default: |
| 1031 t = CKT_NSS_TRUST_UNKNOWN; |
| 1032 break; |
1046 } | 1033 } |
1047 return t; | 1034 return t; |
1048 } | 1035 } |
1049 | 1036 |
1050 NSS_IMPLEMENT nssCryptokiObject * | 1037 NSS_IMPLEMENT nssCryptokiObject * |
1051 nssToken_ImportTrust ( | 1038 nssToken_ImportTrust( |
1052 NSSToken *tok, | 1039 NSSToken *tok, |
1053 nssSession *sessionOpt, | 1040 nssSession *sessionOpt, |
1054 NSSDER *certEncoding, | 1041 NSSDER *certEncoding, |
1055 NSSDER *certIssuer, | 1042 NSSDER *certIssuer, |
1056 NSSDER *certSerial, | 1043 NSSDER *certSerial, |
1057 nssTrustLevel serverAuth, | 1044 nssTrustLevel serverAuth, |
1058 nssTrustLevel clientAuth, | 1045 nssTrustLevel clientAuth, |
1059 nssTrustLevel codeSigning, | 1046 nssTrustLevel codeSigning, |
1060 nssTrustLevel emailProtection, | 1047 nssTrustLevel emailProtection, |
1061 PRBool stepUpApproved, | 1048 PRBool stepUpApproved, |
1062 PRBool asTokenObject | 1049 PRBool asTokenObject) |
1063 ) | |
1064 { | 1050 { |
1065 nssCryptokiObject *object; | 1051 nssCryptokiObject *object; |
1066 CK_OBJECT_CLASS tobjc = CKO_NSS_TRUST; | 1052 CK_OBJECT_CLASS tobjc = CKO_NSS_TRUST; |
1067 CK_TRUST ckSA, ckCA, ckCS, ckEP; | 1053 CK_TRUST ckSA, ckCA, ckCS, ckEP; |
1068 CK_ATTRIBUTE_PTR attr; | 1054 CK_ATTRIBUTE_PTR attr; |
1069 CK_ATTRIBUTE trust_tmpl[11]; | 1055 CK_ATTRIBUTE trust_tmpl[11]; |
1070 CK_ULONG tsize; | 1056 CK_ULONG tsize; |
1071 PRUint8 sha1[20]; /* this is cheating... */ | 1057 PRUint8 sha1[20]; /* this is cheating... */ |
1072 PRUint8 md5[16]; | 1058 PRUint8 md5[16]; |
1073 NSSItem sha1_result, md5_result; | 1059 NSSItem sha1_result, md5_result; |
1074 sha1_result.data = sha1; sha1_result.size = sizeof sha1; | 1060 sha1_result.data = sha1; |
1075 md5_result.data = md5; md5_result.size = sizeof md5; | 1061 sha1_result.size = sizeof sha1; |
| 1062 md5_result.data = md5; |
| 1063 md5_result.size = sizeof md5; |
1076 sha1_hash(certEncoding, &sha1_result); | 1064 sha1_hash(certEncoding, &sha1_result); |
1077 md5_hash(certEncoding, &md5_result); | 1065 md5_hash(certEncoding, &md5_result); |
1078 ckSA = get_ck_trust(serverAuth); | 1066 ckSA = get_ck_trust(serverAuth); |
1079 ckCA = get_ck_trust(clientAuth); | 1067 ckCA = get_ck_trust(clientAuth); |
1080 ckCS = get_ck_trust(codeSigning); | 1068 ckCS = get_ck_trust(codeSigning); |
1081 ckEP = get_ck_trust(emailProtection); | 1069 ckEP = get_ck_trust(emailProtection); |
1082 NSS_CK_TEMPLATE_START(trust_tmpl, attr, tsize); | 1070 NSS_CK_TEMPLATE_START(trust_tmpl, attr, tsize); |
1083 if (asTokenObject) { | 1071 if (asTokenObject) { |
1084 » NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true); | 1072 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true); |
1085 } else { | 1073 } else { |
1086 » NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_false); | 1074 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_false); |
1087 } | 1075 } |
1088 NSS_CK_SET_ATTRIBUTE_VAR( attr, CKA_CLASS, tobjc); | 1076 NSS_CK_SET_ATTRIBUTE_VAR(attr, CKA_CLASS, tobjc); |
1089 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_ISSUER, certIssuer); | 1077 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_ISSUER, certIssuer); |
1090 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_SERIAL_NUMBER, certSerial); | 1078 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_SERIAL_NUMBER, certSerial); |
1091 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_CERT_SHA1_HASH, &sha1_result); | 1079 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_CERT_SHA1_HASH, &sha1_result); |
1092 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_CERT_MD5_HASH, &md5_result); | 1080 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_CERT_MD5_HASH, &md5_result); |
1093 /* now set the trust values */ | 1081 /* now set the trust values */ |
1094 NSS_CK_SET_ATTRIBUTE_VAR(attr, CKA_TRUST_SERVER_AUTH, ckSA); | 1082 NSS_CK_SET_ATTRIBUTE_VAR(attr, CKA_TRUST_SERVER_AUTH, ckSA); |
1095 NSS_CK_SET_ATTRIBUTE_VAR(attr, CKA_TRUST_CLIENT_AUTH, ckCA); | 1083 NSS_CK_SET_ATTRIBUTE_VAR(attr, CKA_TRUST_CLIENT_AUTH, ckCA); |
1096 NSS_CK_SET_ATTRIBUTE_VAR(attr, CKA_TRUST_CODE_SIGNING, ckCS); | 1084 NSS_CK_SET_ATTRIBUTE_VAR(attr, CKA_TRUST_CODE_SIGNING, ckCS); |
1097 NSS_CK_SET_ATTRIBUTE_VAR(attr, CKA_TRUST_EMAIL_PROTECTION, ckEP); | 1085 NSS_CK_SET_ATTRIBUTE_VAR(attr, CKA_TRUST_EMAIL_PROTECTION, ckEP); |
1098 if (stepUpApproved) { | 1086 if (stepUpApproved) { |
1099 » NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TRUST_STEP_UP_APPROVED, | 1087 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TRUST_STEP_UP_APPROVED, |
1100 » &g_ck_true); | 1088 &g_ck_true); |
1101 } else { | 1089 } else { |
1102 » NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TRUST_STEP_UP_APPROVED, | 1090 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TRUST_STEP_UP_APPROVED, |
1103 » &g_ck_false); | 1091 &g_ck_false); |
1104 } | 1092 } |
1105 NSS_CK_TEMPLATE_FINISH(trust_tmpl, attr, tsize); | 1093 NSS_CK_TEMPLATE_FINISH(trust_tmpl, attr, tsize); |
1106 /* import the trust object onto the token */ | 1094 /* import the trust object onto the token */ |
1107 object = import_object(tok, sessionOpt, trust_tmpl, tsize); | 1095 object = import_object(tok, sessionOpt, trust_tmpl, tsize); |
1108 if (object && tok->cache) { | 1096 if (object && tok->cache) { |
1109 » nssTokenObjectCache_ImportObject(tok->cache, object, tobjc, | 1097 nssTokenObjectCache_ImportObject(tok->cache, object, tobjc, |
1110 » trust_tmpl, tsize); | 1098 trust_tmpl, tsize); |
1111 } | 1099 } |
1112 return object; | 1100 return object; |
1113 } | 1101 } |
1114 | 1102 |
1115 NSS_IMPLEMENT nssCryptokiObject * | 1103 NSS_IMPLEMENT nssCryptokiObject * |
1116 nssToken_FindTrustForCertificate ( | 1104 nssToken_FindTrustForCertificate( |
1117 NSSToken *token, | 1105 NSSToken *token, |
1118 nssSession *sessionOpt, | 1106 nssSession *sessionOpt, |
1119 NSSDER *certEncoding, | 1107 NSSDER *certEncoding, |
1120 NSSDER *certIssuer, | 1108 NSSDER *certIssuer, |
1121 NSSDER *certSerial, | 1109 NSSDER *certSerial, |
1122 nssTokenSearchType searchType | 1110 nssTokenSearchType searchType) |
1123 ) | |
1124 { | 1111 { |
1125 CK_OBJECT_CLASS tobjc = CKO_NSS_TRUST; | 1112 CK_OBJECT_CLASS tobjc = CKO_NSS_TRUST; |
1126 CK_ATTRIBUTE_PTR attr; | 1113 CK_ATTRIBUTE_PTR attr; |
1127 CK_ATTRIBUTE tobj_template[5]; | 1114 CK_ATTRIBUTE tobj_template[5]; |
1128 CK_ULONG tobj_size; | 1115 CK_ULONG tobj_size; |
1129 nssSession *session = sessionOpt ? sessionOpt : token->defaultSession; | 1116 nssSession *session = sessionOpt ? sessionOpt : token->defaultSession; |
1130 nssCryptokiObject *object = NULL, **objects; | 1117 nssCryptokiObject *object = NULL, **objects; |
1131 | 1118 |
1132 /* Don't ask the module to use an invalid session handle. */ | 1119 /* Don't ask the module to use an invalid session handle. */ |
1133 if (!session || session->handle == CK_INVALID_SESSION) { | 1120 if (!session || session->handle == CK_INVALID_SESSION) { |
1134 » PORT_SetError(SEC_ERROR_NO_TOKEN); | 1121 PORT_SetError(SEC_ERROR_NO_TOKEN); |
1135 » return object; | 1122 return object; |
1136 } | 1123 } |
1137 | 1124 |
1138 NSS_CK_TEMPLATE_START(tobj_template, attr, tobj_size); | 1125 NSS_CK_TEMPLATE_START(tobj_template, attr, tobj_size); |
1139 if (searchType == nssTokenSearchType_TokenOnly) { | 1126 if (searchType == nssTokenSearchType_TokenOnly) { |
1140 » NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true); | 1127 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true); |
1141 } | 1128 } |
1142 NSS_CK_SET_ATTRIBUTE_VAR( attr, CKA_CLASS, tobjc); | 1129 NSS_CK_SET_ATTRIBUTE_VAR(attr, CKA_CLASS, tobjc); |
1143 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_ISSUER, certIssuer); | 1130 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_ISSUER, certIssuer); |
1144 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_SERIAL_NUMBER , certSerial); | 1131 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_SERIAL_NUMBER, certSerial); |
1145 NSS_CK_TEMPLATE_FINISH(tobj_template, attr, tobj_size); | 1132 NSS_CK_TEMPLATE_FINISH(tobj_template, attr, tobj_size); |
1146 objects = find_objects_by_template(token, session, | 1133 objects = find_objects_by_template(token, session, |
1147 tobj_template, tobj_size, | 1134 tobj_template, tobj_size, |
1148 1, NULL); | 1135 1, NULL); |
1149 if (objects) { | 1136 if (objects) { |
1150 » object = objects[0]; | 1137 object = objects[0]; |
1151 » nss_ZFreeIf(objects); | 1138 nss_ZFreeIf(objects); |
1152 } | 1139 } |
1153 return object; | 1140 return object; |
1154 } | 1141 } |
1155 | 1142 |
1156 NSS_IMPLEMENT nssCryptokiObject * | 1143 NSS_IMPLEMENT nssCryptokiObject * |
1157 nssToken_ImportCRL ( | 1144 nssToken_ImportCRL( |
1158 NSSToken *token, | 1145 NSSToken *token, |
1159 nssSession *sessionOpt, | 1146 nssSession *sessionOpt, |
1160 NSSDER *subject, | 1147 NSSDER *subject, |
1161 NSSDER *encoding, | 1148 NSSDER *encoding, |
1162 PRBool isKRL, | 1149 PRBool isKRL, |
1163 NSSUTF8 *url, | 1150 NSSUTF8 *url, |
1164 PRBool asTokenObject | 1151 PRBool asTokenObject) |
1165 ) | |
1166 { | 1152 { |
1167 nssCryptokiObject *object; | 1153 nssCryptokiObject *object; |
1168 CK_OBJECT_CLASS crlobjc = CKO_NSS_CRL; | 1154 CK_OBJECT_CLASS crlobjc = CKO_NSS_CRL; |
1169 CK_ATTRIBUTE_PTR attr; | 1155 CK_ATTRIBUTE_PTR attr; |
1170 CK_ATTRIBUTE crl_tmpl[6]; | 1156 CK_ATTRIBUTE crl_tmpl[6]; |
1171 CK_ULONG crlsize; | 1157 CK_ULONG crlsize; |
1172 | 1158 |
1173 NSS_CK_TEMPLATE_START(crl_tmpl, attr, crlsize); | 1159 NSS_CK_TEMPLATE_START(crl_tmpl, attr, crlsize); |
1174 if (asTokenObject) { | 1160 if (asTokenObject) { |
1175 » NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true); | 1161 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true); |
1176 } else { | 1162 } else { |
1177 » NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_false); | 1163 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_false); |
1178 } | 1164 } |
1179 NSS_CK_SET_ATTRIBUTE_VAR( attr, CKA_CLASS, crlobjc); | 1165 NSS_CK_SET_ATTRIBUTE_VAR(attr, CKA_CLASS, crlobjc); |
1180 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_SUBJECT, subject); | 1166 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_SUBJECT, subject); |
1181 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_VALUE, encoding); | 1167 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_VALUE, encoding); |
1182 NSS_CK_SET_ATTRIBUTE_UTF8(attr, CKA_NSS_URL, url); | 1168 NSS_CK_SET_ATTRIBUTE_UTF8(attr, CKA_NSS_URL, url); |
1183 if (isKRL) { | 1169 if (isKRL) { |
1184 » NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_NSS_KRL, &g_ck_true); | 1170 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_NSS_KRL, &g_ck_true); |
1185 } else { | 1171 } else { |
1186 » NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_NSS_KRL, &g_ck_false); | 1172 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_NSS_KRL, &g_ck_false); |
1187 } | 1173 } |
1188 NSS_CK_TEMPLATE_FINISH(crl_tmpl, attr, crlsize); | 1174 NSS_CK_TEMPLATE_FINISH(crl_tmpl, attr, crlsize); |
1189 | 1175 |
1190 /* import the crl object onto the token */ | 1176 /* import the crl object onto the token */ |
1191 object = import_object(token, sessionOpt, crl_tmpl, crlsize); | 1177 object = import_object(token, sessionOpt, crl_tmpl, crlsize); |
1192 if (object && token->cache) { | 1178 if (object && token->cache) { |
1193 » nssTokenObjectCache_ImportObject(token->cache, object, crlobjc, | 1179 nssTokenObjectCache_ImportObject(token->cache, object, crlobjc, |
1194 » crl_tmpl, crlsize); | 1180 crl_tmpl, crlsize); |
1195 } | 1181 } |
1196 return object; | 1182 return object; |
1197 } | 1183 } |
1198 | 1184 |
1199 NSS_IMPLEMENT nssCryptokiObject ** | 1185 NSS_IMPLEMENT nssCryptokiObject ** |
1200 nssToken_FindCRLsBySubject ( | 1186 nssToken_FindCRLsBySubject( |
1201 NSSToken *token, | 1187 NSSToken *token, |
1202 nssSession *sessionOpt, | 1188 nssSession *sessionOpt, |
1203 NSSDER *subject, | 1189 NSSDER *subject, |
1204 nssTokenSearchType searchType, | 1190 nssTokenSearchType searchType, |
1205 PRUint32 maximumOpt, | 1191 PRUint32 maximumOpt, |
1206 PRStatus *statusOpt | 1192 PRStatus *statusOpt) |
1207 ) | |
1208 { | 1193 { |
1209 CK_OBJECT_CLASS crlobjc = CKO_NSS_CRL; | 1194 CK_OBJECT_CLASS crlobjc = CKO_NSS_CRL; |
1210 CK_ATTRIBUTE_PTR attr; | 1195 CK_ATTRIBUTE_PTR attr; |
1211 CK_ATTRIBUTE crlobj_template[3]; | 1196 CK_ATTRIBUTE crlobj_template[3]; |
1212 CK_ULONG crlobj_size; | 1197 CK_ULONG crlobj_size; |
1213 nssCryptokiObject **objects = NULL; | 1198 nssCryptokiObject **objects = NULL; |
1214 nssSession *session = sessionOpt ? sessionOpt : token->defaultSession; | 1199 nssSession *session = sessionOpt ? sessionOpt : token->defaultSession; |
1215 | 1200 |
1216 /* Don't ask the module to use an invalid session handle. */ | 1201 /* Don't ask the module to use an invalid session handle. */ |
1217 if (!session || session->handle == CK_INVALID_SESSION) { | 1202 if (!session || session->handle == CK_INVALID_SESSION) { |
1218 » PORT_SetError(SEC_ERROR_NO_TOKEN); | 1203 PORT_SetError(SEC_ERROR_NO_TOKEN); |
1219 » return objects; | 1204 return objects; |
1220 } | 1205 } |
1221 | 1206 |
1222 NSS_CK_TEMPLATE_START(crlobj_template, attr, crlobj_size); | 1207 NSS_CK_TEMPLATE_START(crlobj_template, attr, crlobj_size); |
1223 if (searchType == nssTokenSearchType_SessionOnly) { | 1208 if (searchType == nssTokenSearchType_SessionOnly) { |
1224 » NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_false); | 1209 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_false); |
1225 } else if (searchType == nssTokenSearchType_TokenOnly || | 1210 } else if (searchType == nssTokenSearchType_TokenOnly || |
1226 searchType == nssTokenSearchType_TokenForced) { | 1211 searchType == nssTokenSearchType_TokenForced) { |
1227 » NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true); | 1212 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true); |
1228 } | 1213 } |
1229 NSS_CK_SET_ATTRIBUTE_VAR( attr, CKA_CLASS, crlobjc); | 1214 NSS_CK_SET_ATTRIBUTE_VAR(attr, CKA_CLASS, crlobjc); |
1230 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_SUBJECT, subject); | 1215 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_SUBJECT, subject); |
1231 NSS_CK_TEMPLATE_FINISH(crlobj_template, attr, crlobj_size); | 1216 NSS_CK_TEMPLATE_FINISH(crlobj_template, attr, crlobj_size); |
1232 | 1217 |
1233 objects = find_objects_by_template(token, session, | 1218 objects = find_objects_by_template(token, session, |
1234 crlobj_template, crlobj_size, | 1219 crlobj_template, crlobj_size, |
1235 maximumOpt, statusOpt); | 1220 maximumOpt, statusOpt); |
1236 return objects; | 1221 return objects; |
1237 } | 1222 } |
1238 | 1223 |
1239 NSS_IMPLEMENT PRStatus | 1224 NSS_IMPLEMENT PRStatus |
1240 nssToken_GetCachedObjectAttributes ( | 1225 nssToken_GetCachedObjectAttributes( |
1241 NSSToken *token, | 1226 NSSToken *token, |
1242 NSSArena *arenaOpt, | 1227 NSSArena *arenaOpt, |
1243 nssCryptokiObject *object, | 1228 nssCryptokiObject *object, |
1244 CK_OBJECT_CLASS objclass, | 1229 CK_OBJECT_CLASS objclass, |
1245 CK_ATTRIBUTE_PTR atemplate, | 1230 CK_ATTRIBUTE_PTR atemplate, |
1246 CK_ULONG atlen | 1231 CK_ULONG atlen) |
1247 ) | |
1248 { | 1232 { |
1249 if (!token->cache) { | 1233 if (!token->cache) { |
1250 » return PR_FAILURE; | 1234 return PR_FAILURE; |
1251 } | 1235 } |
1252 return nssTokenObjectCache_GetObjectAttributes(token->cache, arenaOpt, | 1236 return nssTokenObjectCache_GetObjectAttributes(token->cache, arenaOpt, |
1253 object, objclass, | 1237 object, objclass, |
1254 atemplate, atlen); | 1238 atemplate, atlen); |
1255 } | 1239 } |
1256 | 1240 |
1257 NSS_IMPLEMENT NSSItem * | 1241 NSS_IMPLEMENT NSSItem * |
1258 nssToken_Digest ( | 1242 nssToken_Digest( |
1259 NSSToken *tok, | 1243 NSSToken *tok, |
1260 nssSession *sessionOpt, | 1244 nssSession *sessionOpt, |
1261 NSSAlgorithmAndParameters *ap, | 1245 NSSAlgorithmAndParameters *ap, |
1262 NSSItem *data, | 1246 NSSItem *data, |
1263 NSSItem *rvOpt, | 1247 NSSItem *rvOpt, |
1264 NSSArena *arenaOpt | 1248 NSSArena *arenaOpt) |
1265 ) | |
1266 { | 1249 { |
1267 CK_RV ckrv; | 1250 CK_RV ckrv; |
1268 CK_ULONG digestLen; | 1251 CK_ULONG digestLen; |
1269 CK_BYTE_PTR digest; | 1252 CK_BYTE_PTR digest; |
1270 NSSItem *rvItem = NULL; | 1253 NSSItem *rvItem = NULL; |
1271 void *epv = nssToken_GetCryptokiEPV(tok); | 1254 void *epv = nssToken_GetCryptokiEPV(tok); |
1272 nssSession *session = (sessionOpt) ? sessionOpt : tok->defaultSession; | 1255 nssSession *session = (sessionOpt) ? sessionOpt : tok->defaultSession; |
1273 | 1256 |
1274 /* Don't ask the module to use an invalid session handle. */ | 1257 /* Don't ask the module to use an invalid session handle. */ |
1275 if (!session || session->handle == CK_INVALID_SESSION) { | 1258 if (!session || session->handle == CK_INVALID_SESSION) { |
1276 » PORT_SetError(SEC_ERROR_NO_TOKEN); | 1259 PORT_SetError(SEC_ERROR_NO_TOKEN); |
1277 » return rvItem; | 1260 return rvItem; |
1278 } | 1261 } |
1279 | 1262 |
1280 nssSession_EnterMonitor(session); | 1263 nssSession_EnterMonitor(session); |
1281 ckrv = CKAPI(epv)->C_DigestInit(session->handle, &ap->mechanism); | 1264 ckrv = CKAPI(epv)->C_DigestInit(session->handle, &ap->mechanism); |
1282 if (ckrv != CKR_OK) { | 1265 if (ckrv != CKR_OK) { |
1283 » nssSession_ExitMonitor(session); | 1266 nssSession_ExitMonitor(session); |
1284 » return NULL; | 1267 return NULL; |
1285 } | 1268 } |
1286 #if 0 | 1269 #if 0 |
1287 /* XXX the standard says this should work, but it doesn't */ | 1270 /* XXX the standard says this should work, but it doesn't */ |
1288 ckrv = CKAPI(epv)->C_Digest(session->handle, NULL, 0, NULL, &digestLen); | 1271 ckrv = CKAPI(epv)->C_Digest(session->handle, NULL, 0, NULL, &digestLen); |
1289 if (ckrv != CKR_OK) { | 1272 if (ckrv != CKR_OK) { |
1290 nssSession_ExitMonitor(session); | 1273 nssSession_ExitMonitor(session); |
1291 return NULL; | 1274 return NULL; |
1292 } | 1275 } |
1293 #endif | 1276 #endif |
1294 digestLen = 0; /* XXX for now */ | 1277 digestLen = 0; /* XXX for now */ |
1295 digest = NULL; | 1278 digest = NULL; |
1296 if (rvOpt) { | 1279 if (rvOpt) { |
1297 » if (rvOpt->size > 0 && rvOpt->size < digestLen) { | 1280 if (rvOpt->size > 0 && rvOpt->size < digestLen) { |
1298 » nssSession_ExitMonitor(session); | 1281 nssSession_ExitMonitor(session); |
1299 » /* the error should be bad args */ | 1282 /* the error should be bad args */ |
1300 » return NULL; | 1283 return NULL; |
1301 » } | 1284 } |
1302 » if (rvOpt->data) { | 1285 if (rvOpt->data) { |
1303 » digest = rvOpt->data; | 1286 digest = rvOpt->data; |
1304 » } | 1287 } |
1305 » digestLen = rvOpt->size; | 1288 digestLen = rvOpt->size; |
1306 } | 1289 } |
1307 if (!digest) { | 1290 if (!digest) { |
1308 » digest = (CK_BYTE_PTR)nss_ZAlloc(arenaOpt, digestLen); | 1291 digest = (CK_BYTE_PTR)nss_ZAlloc(arenaOpt, digestLen); |
1309 » if (!digest) { | 1292 if (!digest) { |
1310 » nssSession_ExitMonitor(session); | 1293 nssSession_ExitMonitor(session); |
1311 » return NULL; | 1294 return NULL; |
1312 » } | 1295 } |
1313 } | 1296 } |
1314 ckrv = CKAPI(epv)->C_Digest(session->handle, | 1297 ckrv = CKAPI(epv)->C_Digest(session->handle, |
1315 (CK_BYTE_PTR)data->data, | 1298 (CK_BYTE_PTR)data->data, |
1316 (CK_ULONG)data->size, | 1299 (CK_ULONG)data->size, |
1317 (CK_BYTE_PTR)digest, | 1300 (CK_BYTE_PTR)digest, |
1318 &digestLen); | 1301 &digestLen); |
1319 nssSession_ExitMonitor(session); | 1302 nssSession_ExitMonitor(session); |
1320 if (ckrv != CKR_OK) { | 1303 if (ckrv != CKR_OK) { |
1321 » nss_ZFreeIf(digest); | 1304 nss_ZFreeIf(digest); |
1322 » return NULL; | 1305 return NULL; |
1323 } | 1306 } |
1324 if (!rvOpt) { | 1307 if (!rvOpt) { |
1325 » rvItem = nssItem_Create(arenaOpt, NULL, digestLen, (void *)digest); | 1308 rvItem = nssItem_Create(arenaOpt, NULL, digestLen, (void *)digest); |
1326 } | 1309 } |
1327 return rvItem; | 1310 return rvItem; |
1328 } | 1311 } |
1329 | 1312 |
1330 NSS_IMPLEMENT PRStatus | 1313 NSS_IMPLEMENT PRStatus |
1331 nssToken_BeginDigest ( | 1314 nssToken_BeginDigest( |
1332 NSSToken *tok, | 1315 NSSToken *tok, |
1333 nssSession *sessionOpt, | 1316 nssSession *sessionOpt, |
1334 NSSAlgorithmAndParameters *ap | 1317 NSSAlgorithmAndParameters *ap) |
1335 ) | |
1336 { | 1318 { |
1337 CK_RV ckrv; | 1319 CK_RV ckrv; |
1338 void *epv = nssToken_GetCryptokiEPV(tok); | 1320 void *epv = nssToken_GetCryptokiEPV(tok); |
1339 nssSession *session = (sessionOpt) ? sessionOpt : tok->defaultSession; | 1321 nssSession *session = (sessionOpt) ? sessionOpt : tok->defaultSession; |
1340 | 1322 |
1341 /* Don't ask the module to use an invalid session handle. */ | 1323 /* Don't ask the module to use an invalid session handle. */ |
1342 if (!session || session->handle == CK_INVALID_SESSION) { | 1324 if (!session || session->handle == CK_INVALID_SESSION) { |
1343 » PORT_SetError(SEC_ERROR_NO_TOKEN); | 1325 PORT_SetError(SEC_ERROR_NO_TOKEN); |
1344 » return PR_FAILURE; | 1326 return PR_FAILURE; |
1345 } | 1327 } |
1346 | 1328 |
1347 nssSession_EnterMonitor(session); | 1329 nssSession_EnterMonitor(session); |
1348 ckrv = CKAPI(epv)->C_DigestInit(session->handle, &ap->mechanism); | 1330 ckrv = CKAPI(epv)->C_DigestInit(session->handle, &ap->mechanism); |
1349 nssSession_ExitMonitor(session); | 1331 nssSession_ExitMonitor(session); |
1350 return (ckrv == CKR_OK) ? PR_SUCCESS : PR_FAILURE; | 1332 return (ckrv == CKR_OK) ? PR_SUCCESS : PR_FAILURE; |
1351 } | 1333 } |
1352 | 1334 |
1353 NSS_IMPLEMENT PRStatus | 1335 NSS_IMPLEMENT PRStatus |
1354 nssToken_ContinueDigest ( | 1336 nssToken_ContinueDigest( |
1355 NSSToken *tok, | 1337 NSSToken *tok, |
1356 nssSession *sessionOpt, | 1338 nssSession *sessionOpt, |
1357 NSSItem *item | 1339 NSSItem *item) |
1358 ) | |
1359 { | 1340 { |
1360 CK_RV ckrv; | 1341 CK_RV ckrv; |
1361 void *epv = nssToken_GetCryptokiEPV(tok); | 1342 void *epv = nssToken_GetCryptokiEPV(tok); |
1362 nssSession *session = (sessionOpt) ? sessionOpt : tok->defaultSession; | 1343 nssSession *session = (sessionOpt) ? sessionOpt : tok->defaultSession; |
1363 | 1344 |
1364 /* Don't ask the module to use an invalid session handle. */ | 1345 /* Don't ask the module to use an invalid session handle. */ |
1365 if (!session || session->handle == CK_INVALID_SESSION) { | 1346 if (!session || session->handle == CK_INVALID_SESSION) { |
1366 » PORT_SetError(SEC_ERROR_NO_TOKEN); | 1347 PORT_SetError(SEC_ERROR_NO_TOKEN); |
1367 » return PR_FAILURE; | 1348 return PR_FAILURE; |
1368 } | 1349 } |
1369 | 1350 |
1370 nssSession_EnterMonitor(session); | 1351 nssSession_EnterMonitor(session); |
1371 ckrv = CKAPI(epv)->C_DigestUpdate(session->handle, | 1352 ckrv = CKAPI(epv)->C_DigestUpdate(session->handle, |
1372 (CK_BYTE_PTR)item->data, | 1353 (CK_BYTE_PTR)item->data, |
1373 (CK_ULONG)item->size); | 1354 (CK_ULONG)item->size); |
1374 nssSession_ExitMonitor(session); | 1355 nssSession_ExitMonitor(session); |
1375 return (ckrv == CKR_OK) ? PR_SUCCESS : PR_FAILURE; | 1356 return (ckrv == CKR_OK) ? PR_SUCCESS : PR_FAILURE; |
1376 } | 1357 } |
1377 | 1358 |
1378 NSS_IMPLEMENT NSSItem * | 1359 NSS_IMPLEMENT NSSItem * |
1379 nssToken_FinishDigest ( | 1360 nssToken_FinishDigest( |
1380 NSSToken *tok, | 1361 NSSToken *tok, |
1381 nssSession *sessionOpt, | 1362 nssSession *sessionOpt, |
1382 NSSItem *rvOpt, | 1363 NSSItem *rvOpt, |
1383 NSSArena *arenaOpt | 1364 NSSArena *arenaOpt) |
1384 ) | |
1385 { | 1365 { |
1386 CK_RV ckrv; | 1366 CK_RV ckrv; |
1387 CK_ULONG digestLen; | 1367 CK_ULONG digestLen; |
1388 CK_BYTE_PTR digest; | 1368 CK_BYTE_PTR digest; |
1389 NSSItem *rvItem = NULL; | 1369 NSSItem *rvItem = NULL; |
1390 void *epv = nssToken_GetCryptokiEPV(tok); | 1370 void *epv = nssToken_GetCryptokiEPV(tok); |
1391 nssSession *session = (sessionOpt) ? sessionOpt : tok->defaultSession; | 1371 nssSession *session = (sessionOpt) ? sessionOpt : tok->defaultSession; |
1392 | 1372 |
1393 /* Don't ask the module to use an invalid session handle. */ | 1373 /* Don't ask the module to use an invalid session handle. */ |
1394 if (!session || session->handle == CK_INVALID_SESSION) { | 1374 if (!session || session->handle == CK_INVALID_SESSION) { |
1395 » PORT_SetError(SEC_ERROR_NO_TOKEN); | 1375 PORT_SetError(SEC_ERROR_NO_TOKEN); |
1396 » return NULL; | 1376 return NULL; |
1397 } | 1377 } |
1398 | 1378 |
1399 nssSession_EnterMonitor(session); | 1379 nssSession_EnterMonitor(session); |
1400 ckrv = CKAPI(epv)->C_DigestFinal(session->handle, NULL, &digestLen); | 1380 ckrv = CKAPI(epv)->C_DigestFinal(session->handle, NULL, &digestLen); |
1401 if (ckrv != CKR_OK || digestLen == 0) { | 1381 if (ckrv != CKR_OK || digestLen == 0) { |
1402 » nssSession_ExitMonitor(session); | 1382 nssSession_ExitMonitor(session); |
1403 » return NULL; | 1383 return NULL; |
1404 } | 1384 } |
1405 digest = NULL; | 1385 digest = NULL; |
1406 if (rvOpt) { | 1386 if (rvOpt) { |
1407 » if (rvOpt->size > 0 && rvOpt->size < digestLen) { | 1387 if (rvOpt->size > 0 && rvOpt->size < digestLen) { |
1408 » nssSession_ExitMonitor(session); | 1388 nssSession_ExitMonitor(session); |
1409 » /* the error should be bad args */ | 1389 /* the error should be bad args */ |
1410 » return NULL; | 1390 return NULL; |
1411 » } | 1391 } |
1412 » if (rvOpt->data) { | 1392 if (rvOpt->data) { |
1413 » digest = rvOpt->data; | 1393 digest = rvOpt->data; |
1414 » } | 1394 } |
1415 » digestLen = rvOpt->size; | 1395 digestLen = rvOpt->size; |
1416 } | 1396 } |
1417 if (!digest) { | 1397 if (!digest) { |
1418 » digest = (CK_BYTE_PTR)nss_ZAlloc(arenaOpt, digestLen); | 1398 digest = (CK_BYTE_PTR)nss_ZAlloc(arenaOpt, digestLen); |
1419 » if (!digest) { | 1399 if (!digest) { |
1420 » nssSession_ExitMonitor(session); | 1400 nssSession_ExitMonitor(session); |
1421 » return NULL; | 1401 return NULL; |
1422 » } | 1402 } |
1423 } | 1403 } |
1424 ckrv = CKAPI(epv)->C_DigestFinal(session->handle, digest, &digestLen); | 1404 ckrv = CKAPI(epv)->C_DigestFinal(session->handle, digest, &digestLen); |
1425 nssSession_ExitMonitor(session); | 1405 nssSession_ExitMonitor(session); |
1426 if (ckrv != CKR_OK) { | 1406 if (ckrv != CKR_OK) { |
1427 » nss_ZFreeIf(digest); | 1407 nss_ZFreeIf(digest); |
1428 » return NULL; | 1408 return NULL; |
1429 } | 1409 } |
1430 if (!rvOpt) { | 1410 if (!rvOpt) { |
1431 » rvItem = nssItem_Create(arenaOpt, NULL, digestLen, (void *)digest); | 1411 rvItem = nssItem_Create(arenaOpt, NULL, digestLen, (void *)digest); |
1432 } | 1412 } |
1433 return rvItem; | 1413 return rvItem; |
1434 } | 1414 } |
1435 | 1415 |
1436 NSS_IMPLEMENT PRBool | 1416 NSS_IMPLEMENT PRBool |
1437 nssToken_IsPresent ( | 1417 nssToken_IsPresent( |
1438 NSSToken *token | 1418 NSSToken *token) |
1439 ) | |
1440 { | 1419 { |
1441 return nssSlot_IsTokenPresent(token->slot); | 1420 return nssSlot_IsTokenPresent(token->slot); |
1442 } | 1421 } |
1443 | 1422 |
1444 /* Sigh. The methods to find objects declared above cause problems with | 1423 /* Sigh. The methods to find objects declared above cause problems with |
1445 * the low-level object cache in the softoken -- the objects are found in | 1424 * the low-level object cache in the softoken -- the objects are found in |
1446 * toto, then one wave of GetAttributes is done, then another. Having a | 1425 * toto, then one wave of GetAttributes is done, then another. Having a |
1447 * large number of objects causes the cache to be thrashed, as the objects | 1426 * large number of objects causes the cache to be thrashed, as the objects |
1448 * are gone before there's any chance to ask for their attributes. | 1427 * are gone before there's any chance to ask for their attributes. |
1449 * So, for now, bringing back traversal methods for certs. This way all of | 1428 * So, for now, bringing back traversal methods for certs. This way all of |
1450 * the cert's attributes can be grabbed immediately after finding it, | 1429 * the cert's attributes can be grabbed immediately after finding it, |
1451 * increasing the likelihood that the cache takes care of it. | 1430 * increasing the likelihood that the cache takes care of it. |
1452 */ | 1431 */ |
1453 NSS_IMPLEMENT PRStatus | 1432 NSS_IMPLEMENT PRStatus |
1454 nssToken_TraverseCertificates ( | 1433 nssToken_TraverseCertificates( |
1455 NSSToken *token, | 1434 NSSToken *token, |
1456 nssSession *sessionOpt, | 1435 nssSession *sessionOpt, |
1457 nssTokenSearchType searchType, | 1436 nssTokenSearchType searchType, |
1458 PRStatus (* callback)(nssCryptokiObject *instance, void *arg), | 1437 PRStatus (*callback)(nssCryptokiObject *instance, void *arg), |
1459 void *arg | 1438 void *arg) |
1460 ) | |
1461 { | 1439 { |
1462 CK_RV ckrv; | 1440 CK_RV ckrv; |
1463 CK_ULONG count; | 1441 CK_ULONG count; |
1464 CK_OBJECT_HANDLE *objectHandles; | 1442 CK_OBJECT_HANDLE *objectHandles; |
1465 CK_ATTRIBUTE_PTR attr; | 1443 CK_ATTRIBUTE_PTR attr; |
1466 CK_ATTRIBUTE cert_template[2]; | 1444 CK_ATTRIBUTE cert_template[2]; |
1467 CK_ULONG ctsize; | 1445 CK_ULONG ctsize; |
1468 NSSArena *arena; | 1446 NSSArena *arena; |
1469 PRUint32 arraySize, numHandles; | 1447 PRUint32 arraySize, numHandles; |
1470 nssCryptokiObject **objects; | 1448 nssCryptokiObject **objects; |
1471 void *epv = nssToken_GetCryptokiEPV(token); | 1449 void *epv = nssToken_GetCryptokiEPV(token); |
1472 nssSession *session = (sessionOpt) ? sessionOpt : token->defaultSession; | 1450 nssSession *session = (sessionOpt) ? sessionOpt : token->defaultSession; |
1473 | 1451 |
1474 /* Don't ask the module to use an invalid session handle. */ | 1452 /* Don't ask the module to use an invalid session handle. */ |
1475 if (!session || session->handle == CK_INVALID_SESSION) { | 1453 if (!session || session->handle == CK_INVALID_SESSION) { |
1476 » PORT_SetError(SEC_ERROR_NO_TOKEN); | 1454 PORT_SetError(SEC_ERROR_NO_TOKEN); |
1477 » return PR_FAILURE; | 1455 return PR_FAILURE; |
1478 } | 1456 } |
1479 | 1457 |
1480 /* template for all certs */ | 1458 /* template for all certs */ |
1481 NSS_CK_TEMPLATE_START(cert_template, attr, ctsize); | 1459 NSS_CK_TEMPLATE_START(cert_template, attr, ctsize); |
1482 if (searchType == nssTokenSearchType_SessionOnly) { | 1460 if (searchType == nssTokenSearchType_SessionOnly) { |
1483 » NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_false); | 1461 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_false); |
1484 } else if (searchType == nssTokenSearchType_TokenOnly || | 1462 } else if (searchType == nssTokenSearchType_TokenOnly || |
1485 searchType == nssTokenSearchType_TokenForced) { | 1463 searchType == nssTokenSearchType_TokenForced) { |
1486 » NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true); | 1464 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true); |
1487 } | 1465 } |
1488 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_CLASS, &g_ck_class_cert); | 1466 NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_CLASS, &g_ck_class_cert); |
1489 NSS_CK_TEMPLATE_FINISH(cert_template, attr, ctsize); | 1467 NSS_CK_TEMPLATE_FINISH(cert_template, attr, ctsize); |
1490 | 1468 |
1491 /* the arena is only for the array of object handles */ | 1469 /* the arena is only for the array of object handles */ |
1492 arena = nssArena_Create(); | 1470 arena = nssArena_Create(); |
1493 if (!arena) { | 1471 if (!arena) { |
1494 » return PR_FAILURE; | 1472 return PR_FAILURE; |
1495 } | 1473 } |
1496 arraySize = OBJECT_STACK_SIZE; | 1474 arraySize = OBJECT_STACK_SIZE; |
1497 numHandles = 0; | 1475 numHandles = 0; |
1498 objectHandles = nss_ZNEWARRAY(arena, CK_OBJECT_HANDLE, arraySize); | 1476 objectHandles = nss_ZNEWARRAY(arena, CK_OBJECT_HANDLE, arraySize); |
1499 if (!objectHandles) { | 1477 if (!objectHandles) { |
1500 » goto loser; | 1478 goto loser; |
1501 } | 1479 } |
1502 nssSession_EnterMonitor(session); /* ==== session lock === */ | 1480 nssSession_EnterMonitor(session); /* ==== session lock === */ |
1503 /* Initialize the find with the template */ | 1481 /* Initialize the find with the template */ |
1504 ckrv = CKAPI(epv)->C_FindObjectsInit(session->handle, | 1482 ckrv = CKAPI(epv)->C_FindObjectsInit(session->handle, |
1505 cert_template, ctsize); | 1483 cert_template, ctsize); |
1506 if (ckrv != CKR_OK) { | 1484 if (ckrv != CKR_OK) { |
1507 » nssSession_ExitMonitor(session); | 1485 nssSession_ExitMonitor(session); |
1508 » goto loser; | 1486 goto loser; |
1509 } | 1487 } |
1510 while (PR_TRUE) { | 1488 while (PR_TRUE) { |
1511 » /* Issue the find for up to arraySize - numHandles objects */ | 1489 /* Issue the find for up to arraySize - numHandles objects */ |
1512 » ckrv = CKAPI(epv)->C_FindObjects(session->handle, | 1490 ckrv = CKAPI(epv)->C_FindObjects(session->handle, |
1513 » objectHandles + numHandles, | 1491 objectHandles + numHandles, |
1514 » arraySize - numHandles, | 1492 arraySize - numHandles, |
1515 » &count); | 1493 &count); |
1516 » if (ckrv != CKR_OK) { | 1494 if (ckrv != CKR_OK) { |
1517 » nssSession_ExitMonitor(session); | 1495 nssSession_ExitMonitor(session); |
1518 » goto loser; | 1496 goto loser; |
1519 » } | 1497 } |
1520 » /* bump the number of found objects */ | 1498 /* bump the number of found objects */ |
1521 » numHandles += count; | 1499 numHandles += count; |
1522 » if (numHandles < arraySize) { | 1500 if (numHandles < arraySize) { |
1523 » break; | 1501 break; |
1524 » } | 1502 } |
1525 » /* the array is filled, double it and continue */ | 1503 /* the array is filled, double it and continue */ |
1526 » arraySize *= 2; | 1504 arraySize *= 2; |
1527 » objectHandles = nss_ZREALLOCARRAY(objectHandles, | 1505 objectHandles = nss_ZREALLOCARRAY(objectHandles, |
1528 » CK_OBJECT_HANDLE, | 1506 CK_OBJECT_HANDLE, |
1529 » arraySize); | 1507 arraySize); |
1530 » if (!objectHandles) { | 1508 if (!objectHandles) { |
1531 » nssSession_ExitMonitor(session); | 1509 nssSession_ExitMonitor(session); |
1532 » goto loser; | 1510 goto loser; |
1533 » } | 1511 } |
1534 } | 1512 } |
1535 ckrv = CKAPI(epv)->C_FindObjectsFinal(session->handle); | 1513 ckrv = CKAPI(epv)->C_FindObjectsFinal(session->handle); |
1536 nssSession_ExitMonitor(session); /* ==== end session lock === */ | 1514 nssSession_ExitMonitor(session); /* ==== end session lock === */ |
1537 if (ckrv != CKR_OK) { | 1515 if (ckrv != CKR_OK) { |
1538 » goto loser; | 1516 goto loser; |
1539 } | 1517 } |
1540 if (numHandles > 0) { | 1518 if (numHandles > 0) { |
1541 » objects = create_objects_from_handles(token, session, | 1519 objects = create_objects_from_handles(token, session, |
1542 » objectHandles, numHandles); | 1520 objectHandles, numHandles); |
1543 » if (objects) { | 1521 if (objects) { |
1544 » nssCryptokiObject **op; | 1522 nssCryptokiObject **op; |
1545 » for (op = objects; *op; op++) { | 1523 for (op = objects; *op; op++) { |
1546 » » (void)(*callback)(*op, arg); | 1524 (void)(*callback)(*op, arg); |
1547 » } | 1525 } |
1548 » nss_ZFreeIf(objects); | 1526 nss_ZFreeIf(objects); |
1549 » } | 1527 } |
1550 } | 1528 } |
1551 nssArena_Destroy(arena); | 1529 nssArena_Destroy(arena); |
1552 return PR_SUCCESS; | 1530 return PR_SUCCESS; |
1553 loser: | 1531 loser: |
1554 nssArena_Destroy(arena); | 1532 nssArena_Destroy(arena); |
1555 return PR_FAILURE; | 1533 return PR_FAILURE; |
1556 } | 1534 } |
1557 | 1535 |
1558 NSS_IMPLEMENT PRBool | 1536 NSS_IMPLEMENT PRBool |
1559 nssToken_IsPrivateKeyAvailable ( | 1537 nssToken_IsPrivateKeyAvailable( |
1560 NSSToken *token, | 1538 NSSToken *token, |
1561 NSSCertificate *c, | 1539 NSSCertificate *c, |
1562 nssCryptokiObject *instance | 1540 nssCryptokiObject *instance) |
1563 ) | |
1564 { | 1541 { |
1565 CK_OBJECT_CLASS theClass; | 1542 CK_OBJECT_CLASS theClass; |
1566 | 1543 |
1567 if (token == NULL) return PR_FALSE; | 1544 if (token == NULL) |
1568 if (c == NULL) return PR_FALSE; | 1545 return PR_FALSE; |
| 1546 if (c == NULL) |
| 1547 return PR_FALSE; |
1569 | 1548 |
1570 theClass = CKO_PRIVATE_KEY; | 1549 theClass = CKO_PRIVATE_KEY; |
1571 if (!nssSlot_IsLoggedIn(token->slot)) { | 1550 if (!nssSlot_IsLoggedIn(token->slot)) { |
1572 » theClass = CKO_PUBLIC_KEY; | 1551 theClass = CKO_PUBLIC_KEY; |
1573 } | 1552 } |
1574 if (PK11_MatchItem(token->pk11slot, instance->handle, theClass) | 1553 if (PK11_MatchItem(token->pk11slot, instance->handle, theClass) != |
1575 » » » » » » != CK_INVALID_HANDLE) { | 1554 CK_INVALID_HANDLE) { |
1576 » return PR_TRUE; | 1555 return PR_TRUE; |
1577 } | 1556 } |
1578 return PR_FALSE; | 1557 return PR_FALSE; |
1579 } | 1558 } |
OLD | NEW |