Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(284)

Side by Side Diff: nss/lib/dev/devtoken.c

Issue 1843333003: Update NSPR to 4.12 and NSS to 3.23 on iOS (Closed) Base URL: https://chromium.googlesource.com/chromium/deps/nss.git@master
Patch Set: Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 }
OLDNEW
« no previous file with comments | « nss/lib/dev/devtm.h ('k') | nss/lib/dev/devutil.c » ('j') | nss/lib/util/secoid.c » ('J')

Powered by Google App Engine
This is Rietveld 408576698