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

Side by Side Diff: nss/lib/dev/devutil.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 #ifndef DEVM_H 5 #ifndef DEVM_H
6 #include "devm.h" 6 #include "devm.h"
7 #endif /* DEVM_H */ 7 #endif /* DEVM_H */
8 8
9 #ifndef CKHELPER_H 9 #ifndef CKHELPER_H
10 #include "ckhelper.h" 10 #include "ckhelper.h"
11 #endif /* CKHELPER_H */ 11 #endif /* CKHELPER_H */
12 12
13 NSS_IMPLEMENT nssCryptokiObject * 13 NSS_IMPLEMENT nssCryptokiObject *
14 nssCryptokiObject_Create ( 14 nssCryptokiObject_Create(
15 NSSToken *t, 15 NSSToken *t,
16 nssSession *session, 16 nssSession *session,
17 CK_OBJECT_HANDLE h 17 CK_OBJECT_HANDLE h)
18 )
19 { 18 {
20 PRStatus status; 19 PRStatus status;
21 NSSSlot *slot; 20 NSSSlot *slot;
22 nssCryptokiObject *object; 21 nssCryptokiObject *object;
23 CK_BBOOL *isTokenObject; 22 CK_BBOOL *isTokenObject;
24 CK_ATTRIBUTE cert_template[] = { 23 CK_ATTRIBUTE cert_template[] = {
25 » { CKA_TOKEN, NULL, 0 }, 24 { CKA_TOKEN, NULL, 0 },
26 » { CKA_LABEL, NULL, 0 } 25 { CKA_LABEL, NULL, 0 }
27 }; 26 };
28 slot = nssToken_GetSlot(t); 27 slot = nssToken_GetSlot(t);
29 status = nssCKObject_GetAttributes(h, cert_template, 2, 28 status = nssCKObject_GetAttributes(h, cert_template, 2,
30 NULL, session, slot); 29 NULL, session, slot);
31 nssSlot_Destroy(slot); 30 nssSlot_Destroy(slot);
32 if (status != PR_SUCCESS) { 31 if (status != PR_SUCCESS) {
33 » /* a failure here indicates a device error */ 32 /* a failure here indicates a device error */
34 » return (nssCryptokiObject *)NULL; 33 return (nssCryptokiObject *)NULL;
35 } 34 }
36 object = nss_ZNEW(NULL, nssCryptokiObject); 35 object = nss_ZNEW(NULL, nssCryptokiObject);
37 if (!object) { 36 if (!object) {
38 » return (nssCryptokiObject *)NULL; 37 return (nssCryptokiObject *)NULL;
39 } 38 }
40 object->handle = h; 39 object->handle = h;
41 object->token = nssToken_AddRef(t); 40 object->token = nssToken_AddRef(t);
42 isTokenObject = (CK_BBOOL *)cert_template[0].pValue; 41 isTokenObject = (CK_BBOOL *)cert_template[0].pValue;
43 object->isTokenObject = *isTokenObject; 42 object->isTokenObject = *isTokenObject;
44 nss_ZFreeIf(isTokenObject); 43 nss_ZFreeIf(isTokenObject);
45 NSS_CK_ATTRIBUTE_TO_UTF8(&cert_template[1], object->label); 44 NSS_CK_ATTRIBUTE_TO_UTF8(&cert_template[1], object->label);
46 return object; 45 return object;
47 } 46 }
48 47
49 NSS_IMPLEMENT void 48 NSS_IMPLEMENT void
50 nssCryptokiObject_Destroy ( 49 nssCryptokiObject_Destroy(
51 nssCryptokiObject *object 50 nssCryptokiObject *object)
52 )
53 { 51 {
54 if (object) { 52 if (object) {
55 » nssToken_Destroy(object->token); 53 nssToken_Destroy(object->token);
56 » nss_ZFreeIf(object->label); 54 nss_ZFreeIf(object->label);
57 » nss_ZFreeIf(object); 55 nss_ZFreeIf(object);
58 } 56 }
59 } 57 }
60 58
61 NSS_IMPLEMENT nssCryptokiObject * 59 NSS_IMPLEMENT nssCryptokiObject *
62 nssCryptokiObject_Clone ( 60 nssCryptokiObject_Clone(
63 nssCryptokiObject *object 61 nssCryptokiObject *object)
64 )
65 { 62 {
66 nssCryptokiObject *rvObject; 63 nssCryptokiObject *rvObject;
67 rvObject = nss_ZNEW(NULL, nssCryptokiObject); 64 rvObject = nss_ZNEW(NULL, nssCryptokiObject);
68 if (rvObject) { 65 if (rvObject) {
69 » rvObject->handle = object->handle; 66 rvObject->handle = object->handle;
70 » rvObject->token = nssToken_AddRef(object->token); 67 rvObject->token = nssToken_AddRef(object->token);
71 » rvObject->isTokenObject = object->isTokenObject; 68 rvObject->isTokenObject = object->isTokenObject;
72 » if (object->label) { 69 if (object->label) {
73 » rvObject->label = nssUTF8_Duplicate(object->label, NULL); 70 rvObject->label = nssUTF8_Duplicate(object->label, NULL);
74 » } 71 }
75 } 72 }
76 return rvObject; 73 return rvObject;
77 } 74 }
78 75
79 NSS_EXTERN PRBool 76 NSS_EXTERN PRBool
80 nssCryptokiObject_Equal ( 77 nssCryptokiObject_Equal(
81 nssCryptokiObject *o1, 78 nssCryptokiObject *o1,
82 nssCryptokiObject *o2 79 nssCryptokiObject *o2)
83 )
84 { 80 {
85 return (o1->token == o2->token && o1->handle == o2->handle); 81 return (o1->token == o2->token && o1->handle == o2->handle);
86 } 82 }
87 83
88 NSS_IMPLEMENT PRUint32 84 NSS_IMPLEMENT PRUint32
89 nssPKCS11String_Length(CK_CHAR *pkcs11Str, PRUint32 bufLen) 85 nssPKCS11String_Length(CK_CHAR *pkcs11Str, PRUint32 bufLen)
90 { 86 {
91 PRInt32 i; 87 PRInt32 i;
92 for (i = bufLen - 1; i>=0; ) { 88 for (i = bufLen - 1; i >= 0;) {
93 » if (pkcs11Str[i] != ' ' && pkcs11Str[i] != '\0') break; 89 if (pkcs11Str[i] != ' ' && pkcs11Str[i] != '\0')
94 » --i; 90 break;
91 --i;
95 } 92 }
96 return (PRUint32)(i + 1); 93 return (PRUint32)(i + 1);
97 } 94 }
98 95
99 /* 96 /*
100 * Slot arrays 97 * Slot arrays
101 */ 98 */
102 99
103 NSS_IMPLEMENT NSSSlot ** 100 NSS_IMPLEMENT NSSSlot **
104 nssSlotArray_Clone ( 101 nssSlotArray_Clone(
105 NSSSlot **slots 102 NSSSlot **slots)
106 )
107 { 103 {
108 NSSSlot **rvSlots = NULL; 104 NSSSlot **rvSlots = NULL;
109 NSSSlot **sp = slots; 105 NSSSlot **sp = slots;
110 PRUint32 count = 0; 106 PRUint32 count = 0;
111 while (sp && *sp) count++; 107 while (sp && *sp)
108 count++;
112 if (count > 0) { 109 if (count > 0) {
113 » rvSlots = nss_ZNEWARRAY(NULL, NSSSlot *, count + 1); 110 rvSlots = nss_ZNEWARRAY(NULL, NSSSlot *, count + 1);
114 » if (rvSlots) { 111 if (rvSlots) {
115 » for (sp = slots, count = 0; *sp; sp++) { 112 for (sp = slots, count = 0; *sp; sp++) {
116 » » rvSlots[count++] = nssSlot_AddRef(*sp); 113 rvSlots[count++] = nssSlot_AddRef(*sp);
117 » } 114 }
118 » } 115 }
119 } 116 }
120 return rvSlots; 117 return rvSlots;
121 } 118 }
122 119
123 NSS_IMPLEMENT void 120 NSS_IMPLEMENT void
124 nssSlotArray_Destroy ( 121 nssSlotArray_Destroy(
125 NSSSlot **slots 122 NSSSlot **slots)
126 )
127 { 123 {
128 if (slots) { 124 if (slots) {
129 » NSSSlot **slotp; 125 NSSSlot **slotp;
130 » for (slotp = slots; *slotp; slotp++) { 126 for (slotp = slots; *slotp; slotp++) {
131 » nssSlot_Destroy(*slotp); 127 nssSlot_Destroy(*slotp);
132 » } 128 }
133 » nss_ZFreeIf(slots); 129 nss_ZFreeIf(slots);
134 } 130 }
135 } 131 }
136 132
137 NSS_IMPLEMENT void 133 NSS_IMPLEMENT void
138 NSSSlotArray_Destroy ( 134 NSSSlotArray_Destroy(
139 NSSSlot **slots 135 NSSSlot **slots)
140 )
141 { 136 {
142 nssSlotArray_Destroy(slots); 137 nssSlotArray_Destroy(slots);
143 } 138 }
144 139
145 NSS_IMPLEMENT void 140 NSS_IMPLEMENT void
146 nssTokenArray_Destroy ( 141 nssTokenArray_Destroy(
147 NSSToken **tokens 142 NSSToken **tokens)
148 )
149 { 143 {
150 if (tokens) { 144 if (tokens) {
151 » NSSToken **tokenp; 145 NSSToken **tokenp;
152 » for (tokenp = tokens; *tokenp; tokenp++) { 146 for (tokenp = tokens; *tokenp; tokenp++) {
153 » nssToken_Destroy(*tokenp); 147 nssToken_Destroy(*tokenp);
154 » } 148 }
155 » nss_ZFreeIf(tokens); 149 nss_ZFreeIf(tokens);
156 } 150 }
157 } 151 }
158 152
159 NSS_IMPLEMENT void 153 NSS_IMPLEMENT void
160 NSSTokenArray_Destroy ( 154 NSSTokenArray_Destroy(
161 NSSToken **tokens 155 NSSToken **tokens)
162 )
163 { 156 {
164 nssTokenArray_Destroy(tokens); 157 nssTokenArray_Destroy(tokens);
165 } 158 }
166 159
167 NSS_IMPLEMENT void 160 NSS_IMPLEMENT void
168 nssCryptokiObjectArray_Destroy ( 161 nssCryptokiObjectArray_Destroy(
169 nssCryptokiObject **objects 162 nssCryptokiObject **objects)
170 )
171 { 163 {
172 if (objects) { 164 if (objects) {
173 » nssCryptokiObject **op; 165 nssCryptokiObject **op;
174 » for (op = objects; *op; op++) { 166 for (op = objects; *op; op++) {
175 » nssCryptokiObject_Destroy(*op); 167 nssCryptokiObject_Destroy(*op);
176 » } 168 }
177 » nss_ZFreeIf(objects); 169 nss_ZFreeIf(objects);
178 } 170 }
179 } 171 }
180 172
181 /* object cache for token */ 173 /* object cache for token */
182 174
183 typedef struct 175 typedef struct
184 { 176 {
185 NSSArena *arena; 177 NSSArena *arena;
186 nssCryptokiObject *object; 178 nssCryptokiObject *object;
187 CK_ATTRIBUTE_PTR attributes; 179 CK_ATTRIBUTE_PTR attributes;
188 CK_ULONG numAttributes; 180 CK_ULONG numAttributes;
189 } 181 } nssCryptokiObjectAndAttributes;
190 nssCryptokiObjectAndAttributes;
191 182
192 enum { 183 enum {
193 cachedCerts = 0, 184 cachedCerts = 0,
194 cachedTrust = 1, 185 cachedTrust = 1,
195 cachedCRLs = 2 186 cachedCRLs = 2
196 } cachedObjectType; 187 } cachedObjectType;
197 188
198 struct nssTokenObjectCacheStr 189 struct nssTokenObjectCacheStr {
199 { 190 NSSToken *token;
200 NSSToken *token; 191 PZLock *lock;
201 PZLock *lock; 192 PRBool loggedIn;
202 PRBool loggedIn; 193 PRBool doObjectType[3];
203 PRBool doObjectType[3]; 194 PRBool searchedObjectType[3];
204 PRBool searchedObjectType[3]; 195 nssCryptokiObjectAndAttributes **objects[3];
205 nssCryptokiObjectAndAttributes **objects[3];
206 }; 196 };
207 197
208 NSS_IMPLEMENT nssTokenObjectCache * 198 NSS_IMPLEMENT nssTokenObjectCache *
209 nssTokenObjectCache_Create ( 199 nssTokenObjectCache_Create(
210 NSSToken *token, 200 NSSToken *token,
211 PRBool cacheCerts, 201 PRBool cacheCerts,
212 PRBool cacheTrust, 202 PRBool cacheTrust,
213 PRBool cacheCRLs 203 PRBool cacheCRLs)
214 )
215 { 204 {
216 nssTokenObjectCache *rvCache; 205 nssTokenObjectCache *rvCache;
217 rvCache = nss_ZNEW(NULL, nssTokenObjectCache); 206 rvCache = nss_ZNEW(NULL, nssTokenObjectCache);
218 if (!rvCache) { 207 if (!rvCache) {
219 » goto loser; 208 goto loser;
220 } 209 }
221 rvCache->lock = PZ_NewLock(nssILockOther); /* XXX */ 210 rvCache->lock = PZ_NewLock(nssILockOther); /* XXX */
222 if (!rvCache->lock) { 211 if (!rvCache->lock) {
223 » goto loser; 212 goto loser;
224 } 213 }
225 rvCache->doObjectType[cachedCerts] = cacheCerts; 214 rvCache->doObjectType[cachedCerts] = cacheCerts;
226 rvCache->doObjectType[cachedTrust] = cacheTrust; 215 rvCache->doObjectType[cachedTrust] = cacheTrust;
227 rvCache->doObjectType[cachedCRLs] = cacheCRLs; 216 rvCache->doObjectType[cachedCRLs] = cacheCRLs;
228 rvCache->token = token; /* cache goes away with token */ 217 rvCache->token = token; /* cache goes away with token */
229 return rvCache; 218 return rvCache;
230 loser: 219 loser:
231 nssTokenObjectCache_Destroy(rvCache); 220 nssTokenObjectCache_Destroy(rvCache);
232 return (nssTokenObjectCache *)NULL; 221 return (nssTokenObjectCache *)NULL;
233 } 222 }
234 223
235 static void 224 static void
236 clear_cache ( 225 clear_cache(
237 nssTokenObjectCache *cache 226 nssTokenObjectCache *cache)
238 )
239 { 227 {
240 nssCryptokiObjectAndAttributes **oa; 228 nssCryptokiObjectAndAttributes **oa;
241 PRUint32 objectType; 229 PRUint32 objectType;
242 for (objectType = cachedCerts; objectType <= cachedCRLs; objectType++) { 230 for (objectType = cachedCerts; objectType <= cachedCRLs; objectType++) {
243 » cache->searchedObjectType[objectType] = PR_FALSE; 231 cache->searchedObjectType[objectType] = PR_FALSE;
244 » if (!cache->objects[objectType]) { 232 if (!cache->objects[objectType]) {
245 » continue; 233 continue;
246 » } 234 }
247 » for (oa = cache->objects[objectType]; *oa; oa++) { 235 for (oa = cache->objects[objectType]; *oa; oa++) {
248 » /* prevent the token from being destroyed */ 236 /* prevent the token from being destroyed */
249 » (*oa)->object->token = NULL; 237 (*oa)->object->token = NULL;
250 » nssCryptokiObject_Destroy((*oa)->object); 238 nssCryptokiObject_Destroy((*oa)->object);
251 » nssArena_Destroy((*oa)->arena); 239 nssArena_Destroy((*oa)->arena);
252 » } 240 }
253 » nss_ZFreeIf(cache->objects[objectType]); 241 nss_ZFreeIf(cache->objects[objectType]);
254 » cache->objects[objectType] = NULL; 242 cache->objects[objectType] = NULL;
255 } 243 }
256 } 244 }
257 245
258 NSS_IMPLEMENT void 246 NSS_IMPLEMENT void
259 nssTokenObjectCache_Clear ( 247 nssTokenObjectCache_Clear(
260 nssTokenObjectCache *cache 248 nssTokenObjectCache *cache)
261 )
262 { 249 {
263 if (cache) { 250 if (cache) {
264 » PZ_Lock(cache->lock); 251 PZ_Lock(cache->lock);
265 » clear_cache(cache); 252 clear_cache(cache);
266 » PZ_Unlock(cache->lock); 253 PZ_Unlock(cache->lock);
267 } 254 }
268 } 255 }
269 256
270 NSS_IMPLEMENT void 257 NSS_IMPLEMENT void
271 nssTokenObjectCache_Destroy ( 258 nssTokenObjectCache_Destroy(
272 nssTokenObjectCache *cache 259 nssTokenObjectCache *cache)
273 )
274 { 260 {
275 if (cache) { 261 if (cache) {
276 » clear_cache(cache); 262 clear_cache(cache);
277 » if (cache->lock) { 263 if (cache->lock) {
278 » PZ_DestroyLock(cache->lock); 264 PZ_DestroyLock(cache->lock);
279 » } 265 }
280 » nss_ZFreeIf(cache); 266 nss_ZFreeIf(cache);
281 } 267 }
282 } 268 }
283 269
284 NSS_IMPLEMENT PRBool 270 NSS_IMPLEMENT PRBool
285 nssTokenObjectCache_HaveObjectClass ( 271 nssTokenObjectCache_HaveObjectClass(
286 nssTokenObjectCache *cache, 272 nssTokenObjectCache *cache,
287 CK_OBJECT_CLASS objclass 273 CK_OBJECT_CLASS objclass)
288 )
289 { 274 {
290 PRBool haveIt; 275 PRBool haveIt;
291 PZ_Lock(cache->lock); 276 PZ_Lock(cache->lock);
292 switch (objclass) { 277 switch (objclass) {
293 case CKO_CERTIFICATE: haveIt = cache->doObjectType[cachedCerts]; break; 278 case CKO_CERTIFICATE:
294 case CKO_NETSCAPE_TRUST: haveIt = cache->doObjectType[cachedTrust]; break; 279 haveIt = cache->doObjectType[cachedCerts];
295 case CKO_NETSCAPE_CRL: haveIt = cache->doObjectType[cachedCRLs]; break; 280 break;
296 default: haveIt = PR_FALSE; 281 case CKO_NETSCAPE_TRUST:
282 haveIt = cache->doObjectType[cachedTrust];
283 break;
284 case CKO_NETSCAPE_CRL:
285 haveIt = cache->doObjectType[cachedCRLs];
286 break;
287 default:
288 haveIt = PR_FALSE;
297 } 289 }
298 PZ_Unlock(cache->lock); 290 PZ_Unlock(cache->lock);
299 return haveIt; 291 return haveIt;
300 } 292 }
301 293
302 static nssCryptokiObjectAndAttributes ** 294 static nssCryptokiObjectAndAttributes **
303 create_object_array ( 295 create_object_array(
304 nssCryptokiObject **objects, 296 nssCryptokiObject **objects,
305 PRBool *doObjects, 297 PRBool *doObjects,
306 PRUint32 *numObjects, 298 PRUint32 *numObjects,
307 PRStatus *status 299 PRStatus *status)
308 )
309 { 300 {
310 nssCryptokiObjectAndAttributes **rvOandA = NULL; 301 nssCryptokiObjectAndAttributes **rvOandA = NULL;
311 *numObjects = 0; 302 *numObjects = 0;
312 /* There are no objects for this type */ 303 /* There are no objects for this type */
313 if (!objects || !*objects) { 304 if (!objects || !*objects) {
314 » *status = PR_SUCCESS; 305 *status = PR_SUCCESS;
315 » return rvOandA; 306 return rvOandA;
316 } 307 }
317 while (*objects++) (*numObjects)++; 308 while (*objects++)
309 (*numObjects)++;
318 if (*numObjects >= MAX_LOCAL_CACHE_OBJECTS) { 310 if (*numObjects >= MAX_LOCAL_CACHE_OBJECTS) {
319 » /* Hit the maximum allowed, so don't use a cache (there are 311 /* Hit the maximum allowed, so don't use a cache (there are
320 » * too many objects to make caching worthwhile, presumably, if 312 * too many objects to make caching worthwhile, presumably, if
321 » * the token can handle that many objects, it can handle searching. 313 * the token can handle that many objects, it can handle searching.
322 » */ 314 */
323 » *doObjects = PR_FALSE; 315 *doObjects = PR_FALSE;
324 » *status = PR_FAILURE; 316 *status = PR_FAILURE;
325 » *numObjects = 0; 317 *numObjects = 0;
326 } else { 318 } else {
327 » rvOandA = nss_ZNEWARRAY(NULL, 319 rvOandA = nss_ZNEWARRAY(NULL,
328 » nssCryptokiObjectAndAttributes *, 320 nssCryptokiObjectAndAttributes *,
329 » *numObjects + 1); 321 *numObjects + 1);
330 » *status = rvOandA ? PR_SUCCESS : PR_FAILURE; 322 *status = rvOandA ? PR_SUCCESS : PR_FAILURE;
331 } 323 }
332 return rvOandA; 324 return rvOandA;
333 } 325 }
334 326
335 static nssCryptokiObjectAndAttributes * 327 static nssCryptokiObjectAndAttributes *
336 create_object ( 328 create_object(
337 nssCryptokiObject *object, 329 nssCryptokiObject *object,
338 const CK_ATTRIBUTE_TYPE *types, 330 const CK_ATTRIBUTE_TYPE *types,
339 PRUint32 numTypes, 331 PRUint32 numTypes,
340 PRStatus *status 332 PRStatus *status)
341 )
342 { 333 {
343 PRUint32 j; 334 PRUint32 j;
344 NSSArena *arena = NULL; 335 NSSArena *arena = NULL;
345 NSSSlot *slot = NULL; 336 NSSSlot *slot = NULL;
346 nssSession *session = NULL; 337 nssSession *session = NULL;
347 nssCryptokiObjectAndAttributes *rvCachedObject = NULL; 338 nssCryptokiObjectAndAttributes *rvCachedObject = NULL;
348 339
349 slot = nssToken_GetSlot(object->token); 340 slot = nssToken_GetSlot(object->token);
350 if (!slot) { 341 if (!slot) {
351 nss_SetError(NSS_ERROR_INVALID_POINTER); 342 nss_SetError(NSS_ERROR_INVALID_POINTER);
352 goto loser; 343 goto loser;
353 } 344 }
354 session = nssToken_GetDefaultSession(object->token); 345 session = nssToken_GetDefaultSession(object->token);
355 if (!session) { 346 if (!session) {
356 nss_SetError(NSS_ERROR_INVALID_POINTER); 347 nss_SetError(NSS_ERROR_INVALID_POINTER);
357 goto loser; 348 goto loser;
358 } 349 }
359 arena = nssArena_Create(); 350 arena = nssArena_Create();
360 if (!arena) { 351 if (!arena) {
361 » goto loser; 352 goto loser;
362 } 353 }
363 rvCachedObject = nss_ZNEW(arena, nssCryptokiObjectAndAttributes); 354 rvCachedObject = nss_ZNEW(arena, nssCryptokiObjectAndAttributes);
364 if (!rvCachedObject) { 355 if (!rvCachedObject) {
365 » goto loser; 356 goto loser;
366 } 357 }
367 rvCachedObject->arena = arena; 358 rvCachedObject->arena = arena;
368 /* The cache is tied to the token, and therefore the objects 359 /* The cache is tied to the token, and therefore the objects
369 * in it should not hold references to the token. 360 * in it should not hold references to the token.
370 */ 361 */
371 nssToken_Destroy(object->token); 362 nssToken_Destroy(object->token);
372 rvCachedObject->object = object; 363 rvCachedObject->object = object;
373 rvCachedObject->attributes = nss_ZNEWARRAY(arena, CK_ATTRIBUTE, numTypes); 364 rvCachedObject->attributes = nss_ZNEWARRAY(arena, CK_ATTRIBUTE, numTypes);
374 if (!rvCachedObject->attributes) { 365 if (!rvCachedObject->attributes) {
375 » goto loser; 366 goto loser;
376 } 367 }
377 for (j=0; j<numTypes; j++) { 368 for (j = 0; j < numTypes; j++) {
378 » rvCachedObject->attributes[j].type = types[j]; 369 rvCachedObject->attributes[j].type = types[j];
379 } 370 }
380 *status = nssCKObject_GetAttributes(object->handle, 371 *status = nssCKObject_GetAttributes(object->handle,
381 rvCachedObject->attributes, 372 rvCachedObject->attributes,
382 numTypes, 373 numTypes,
383 arena, 374 arena,
384 session, 375 session,
385 slot); 376 slot);
386 if (*status != PR_SUCCESS) { 377 if (*status != PR_SUCCESS) {
387 » goto loser; 378 goto loser;
388 } 379 }
389 rvCachedObject->numAttributes = numTypes; 380 rvCachedObject->numAttributes = numTypes;
390 *status = PR_SUCCESS; 381 *status = PR_SUCCESS;
391 nssSlot_Destroy(slot); 382 nssSlot_Destroy(slot);
392 383
393 return rvCachedObject; 384 return rvCachedObject;
394 loser: 385 loser:
395 *status = PR_FAILURE; 386 *status = PR_FAILURE;
396 if (slot) { 387 if (slot) {
397 » nssSlot_Destroy(slot); 388 nssSlot_Destroy(slot);
398 } 389 }
399 if (arena) 390 if (arena)
400 » nssArena_Destroy(arena); 391 nssArena_Destroy(arena);
401 return (nssCryptokiObjectAndAttributes *)NULL; 392 return (nssCryptokiObjectAndAttributes *)NULL;
402 } 393 }
403 394
404 /* 395 /*
405 * 396 *
406 * State diagram for cache: 397 * State diagram for cache:
407 * 398 *
408 * token !present token removed 399 * token !present token removed
409 * +-------------------------+<----------------------+ 400 * +-------------------------+<----------------------+
410 * | ^ | 401 * | ^ |
411 * v | | 402 * v | |
412 * +----------+ slot friendly | token present +----------+ 403 * +----------+ slot friendly | token present +----------+
413 * | cache | -----------------> % ---------------> | cache | 404 * | cache | -----------------> % ---------------> | cache |
414 * | unloaded | | loaded | 405 * | unloaded | | loaded |
415 * +----------+ +----------+ 406 * +----------+ +----------+
416 * ^ | ^ | 407 * ^ | ^ |
417 * | | slot !friendly slot logged in | | 408 * | | slot !friendly slot logged in | |
418 * | +-----------------------> % ----------------------+ | 409 * | +-----------------------> % ----------------------+ |
419 * | | | 410 * | | |
420 * | slot logged out v slot !friendly | 411 * | slot logged out v slot !friendly |
421 * +-----------------------------+<--------------------------+ 412 * +-----------------------------+<--------------------------+
422 * 413 *
423 */ 414 */
424 415
425 /* This function must not be called with cache->lock locked. */ 416 /* This function must not be called with cache->lock locked. */
426 static PRBool 417 static PRBool
427 token_is_present ( 418 token_is_present(
428 nssTokenObjectCache *cache 419 nssTokenObjectCache *cache)
429 )
430 { 420 {
431 NSSSlot *slot = nssToken_GetSlot(cache->token); 421 NSSSlot *slot = nssToken_GetSlot(cache->token);
432 PRBool tokenPresent = nssSlot_IsTokenPresent(slot); 422 PRBool tokenPresent = nssSlot_IsTokenPresent(slot);
433 nssSlot_Destroy(slot); 423 nssSlot_Destroy(slot);
434 return tokenPresent; 424 return tokenPresent;
435 } 425 }
436 426
437 static PRBool 427 static PRBool
438 search_for_objects ( 428 search_for_objects(
439 nssTokenObjectCache *cache 429 nssTokenObjectCache *cache)
440 )
441 { 430 {
442 PRBool doSearch = PR_FALSE; 431 PRBool doSearch = PR_FALSE;
443 NSSSlot *slot = nssToken_GetSlot(cache->token); 432 NSSSlot *slot = nssToken_GetSlot(cache->token);
444 /* Handle non-friendly slots (slots which require login for objects) */ 433 /* Handle non-friendly slots (slots which require login for objects) */
445 if (!nssSlot_IsFriendly(slot)) { 434 if (!nssSlot_IsFriendly(slot)) {
446 » if (nssSlot_IsLoggedIn(slot)) { 435 if (nssSlot_IsLoggedIn(slot)) {
447 » /* Either no state change, or went from !logged in -> logged in */ 436 /* Either no state change, or went from !logged in -> logged in */
448 » cache->loggedIn = PR_TRUE; 437 cache->loggedIn = PR_TRUE;
449 » doSearch = PR_TRUE; 438 doSearch = PR_TRUE;
450 » } else { 439 } else {
451 » if (cache->loggedIn) { 440 if (cache->loggedIn) {
452 » » /* went from logged in -> !logged in, destroy cached objects */ 441 /* went from logged in -> !logged in, destroy cached objects */
453 » » clear_cache(cache); 442 clear_cache(cache);
454 » » cache->loggedIn = PR_FALSE; 443 cache->loggedIn = PR_FALSE;
455 » } /* else no state change, still not logged in, so exit */ 444 } /* else no state change, still not logged in, so exit */
456 » } 445 }
457 } else { 446 } else {
458 » /* slot is friendly, thus always available for search */ 447 /* slot is friendly, thus always available for search */
459 » doSearch = PR_TRUE; 448 doSearch = PR_TRUE;
460 } 449 }
461 nssSlot_Destroy(slot); 450 nssSlot_Destroy(slot);
462 return doSearch; 451 return doSearch;
463 } 452 }
464 453
465 static nssCryptokiObjectAndAttributes * 454 static nssCryptokiObjectAndAttributes *
466 create_cert ( 455 create_cert(
467 nssCryptokiObject *object, 456 nssCryptokiObject *object,
468 PRStatus *status 457 PRStatus *status)
469 )
470 { 458 {
471 static const CK_ATTRIBUTE_TYPE certAttr[] = { 459 static const CK_ATTRIBUTE_TYPE certAttr[] = {
472 » CKA_CLASS, 460 CKA_CLASS,
473 » CKA_TOKEN, 461 CKA_TOKEN,
474 » CKA_LABEL, 462 CKA_LABEL,
475 » CKA_CERTIFICATE_TYPE, 463 CKA_CERTIFICATE_TYPE,
476 » CKA_ID, 464 CKA_ID,
477 » CKA_VALUE, 465 CKA_VALUE,
478 » CKA_ISSUER, 466 CKA_ISSUER,
479 » CKA_SERIAL_NUMBER, 467 CKA_SERIAL_NUMBER,
480 » CKA_SUBJECT, 468 CKA_SUBJECT,
481 » CKA_NETSCAPE_EMAIL 469 CKA_NETSCAPE_EMAIL
482 }; 470 };
483 static const PRUint32 numCertAttr = sizeof(certAttr) / sizeof(certAttr[0]); 471 static const PRUint32 numCertAttr = sizeof(certAttr) / sizeof(certAttr[0]);
484 return create_object(object, certAttr, numCertAttr, status); 472 return create_object(object, certAttr, numCertAttr, status);
485 } 473 }
486 474
487 static nssCryptokiObjectAndAttributes * 475 static nssCryptokiObjectAndAttributes *
488 create_trust ( 476 create_trust(
489 nssCryptokiObject *object, 477 nssCryptokiObject *object,
490 PRStatus *status 478 PRStatus *status)
491 )
492 { 479 {
493 static const CK_ATTRIBUTE_TYPE trustAttr[] = { 480 static const CK_ATTRIBUTE_TYPE trustAttr[] = {
494 » CKA_CLASS, 481 CKA_CLASS,
495 » CKA_TOKEN, 482 CKA_TOKEN,
496 » CKA_LABEL, 483 CKA_LABEL,
497 » CKA_CERT_SHA1_HASH, 484 CKA_CERT_SHA1_HASH,
498 » CKA_CERT_MD5_HASH, 485 CKA_CERT_MD5_HASH,
499 » CKA_ISSUER, 486 CKA_ISSUER,
500 » CKA_SUBJECT, 487 CKA_SUBJECT,
501 » CKA_TRUST_SERVER_AUTH, 488 CKA_TRUST_SERVER_AUTH,
502 » CKA_TRUST_CLIENT_AUTH, 489 CKA_TRUST_CLIENT_AUTH,
503 » CKA_TRUST_EMAIL_PROTECTION, 490 CKA_TRUST_EMAIL_PROTECTION,
504 » CKA_TRUST_CODE_SIGNING 491 CKA_TRUST_CODE_SIGNING
505 }; 492 };
506 static const PRUint32 numTrustAttr = sizeof(trustAttr) / sizeof(trustAttr[0] ); 493 static const PRUint32 numTrustAttr = sizeof(trustAttr) / sizeof(trustAttr[0] );
507 return create_object(object, trustAttr, numTrustAttr, status); 494 return create_object(object, trustAttr, numTrustAttr, status);
508 } 495 }
509 496
510 static nssCryptokiObjectAndAttributes * 497 static nssCryptokiObjectAndAttributes *
511 create_crl ( 498 create_crl(
512 nssCryptokiObject *object, 499 nssCryptokiObject *object,
513 PRStatus *status 500 PRStatus *status)
514 )
515 { 501 {
516 static const CK_ATTRIBUTE_TYPE crlAttr[] = { 502 static const CK_ATTRIBUTE_TYPE crlAttr[] = {
517 » CKA_CLASS, 503 CKA_CLASS,
518 » CKA_TOKEN, 504 CKA_TOKEN,
519 » CKA_LABEL, 505 CKA_LABEL,
520 » CKA_VALUE, 506 CKA_VALUE,
521 » CKA_SUBJECT, 507 CKA_SUBJECT,
522 » CKA_NETSCAPE_KRL, 508 CKA_NETSCAPE_KRL,
523 » CKA_NETSCAPE_URL 509 CKA_NETSCAPE_URL
524 }; 510 };
525 static const PRUint32 numCRLAttr = sizeof(crlAttr) / sizeof(crlAttr[0]); 511 static const PRUint32 numCRLAttr = sizeof(crlAttr) / sizeof(crlAttr[0]);
526 return create_object(object, crlAttr, numCRLAttr, status); 512 return create_object(object, crlAttr, numCRLAttr, status);
527 } 513 }
528 514
529 /* Dispatch to the create function for the object type */ 515 /* Dispatch to the create function for the object type */
530 static nssCryptokiObjectAndAttributes * 516 static nssCryptokiObjectAndAttributes *
531 create_object_of_type ( 517 create_object_of_type(
532 nssCryptokiObject *object, 518 nssCryptokiObject *object,
533 PRUint32 objectType, 519 PRUint32 objectType,
534 PRStatus *status 520 PRStatus *status)
535 )
536 { 521 {
537 if (objectType == cachedCerts) { 522 if (objectType == cachedCerts) {
538 » return create_cert(object, status); 523 return create_cert(object, status);
539 } 524 }
540 if (objectType == cachedTrust) { 525 if (objectType == cachedTrust) {
541 » return create_trust(object, status); 526 return create_trust(object, status);
542 } 527 }
543 if (objectType == cachedCRLs) { 528 if (objectType == cachedCRLs) {
544 » return create_crl(object, status); 529 return create_crl(object, status);
545 } 530 }
546 return (nssCryptokiObjectAndAttributes *)NULL; 531 return (nssCryptokiObjectAndAttributes *)NULL;
547 } 532 }
548 533
549 static PRStatus 534 static PRStatus
550 get_token_objects_for_cache ( 535 get_token_objects_for_cache(
551 nssTokenObjectCache *cache, 536 nssTokenObjectCache *cache,
552 PRUint32 objectType, 537 PRUint32 objectType,
553 CK_OBJECT_CLASS objclass 538 CK_OBJECT_CLASS objclass)
554 )
555 { 539 {
556 PRStatus status; 540 PRStatus status;
557 nssCryptokiObject **objects; 541 nssCryptokiObject **objects;
558 PRBool *doIt = &cache->doObjectType[objectType]; 542 PRBool *doIt = &cache->doObjectType[objectType];
559 PRUint32 i, numObjects; 543 PRUint32 i, numObjects;
560 544
561 if (!search_for_objects(cache) || 545 if (!search_for_objects(cache) ||
562 cache->searchedObjectType[objectType] || 546 cache->searchedObjectType[objectType] ||
563 !cache->doObjectType[objectType]) 547 !cache->doObjectType[objectType]) {
564 { 548 /* Either there was a state change that prevents a search
565 » /* Either there was a state change that prevents a search 549 * (token logged out), or the search was already done,
566 » * (token logged out), or the search was already done, 550 * or objects of this type are not being cached.
567 » * or objects of this type are not being cached. 551 */
568 » */ 552 return PR_SUCCESS;
569 » return PR_SUCCESS;
570 } 553 }
571 objects = nssToken_FindObjects(cache->token, NULL, objclass, 554 objects = nssToken_FindObjects(cache->token, NULL, objclass,
572 nssTokenSearchType_TokenForced, 555 nssTokenSearchType_TokenForced,
573 MAX_LOCAL_CACHE_OBJECTS, &status); 556 MAX_LOCAL_CACHE_OBJECTS, &status);
574 if (status != PR_SUCCESS) { 557 if (status != PR_SUCCESS) {
575 » return status; 558 return status;
576 } 559 }
577 cache->objects[objectType] = create_object_array(objects, 560 cache->objects[objectType] = create_object_array(objects,
578 doIt, 561 doIt,
579 &numObjects, 562 &numObjects,
580 &status); 563 &status);
581 if (status != PR_SUCCESS) { 564 if (status != PR_SUCCESS) {
582 » nss_ZFreeIf(objects); 565 nss_ZFreeIf(objects);
583 » return status; 566 return status;
584 } 567 }
585 for (i=0; i<numObjects; i++) { 568 for (i = 0; i < numObjects; i++) {
586 » cache->objects[objectType][i] = create_object_of_type(objects[i], 569 cache->objects[objectType][i] = create_object_of_type(objects[i],
587 » objectType, 570 objectType,
588 » &status); 571 &status);
589 » if (status != PR_SUCCESS) { 572 if (status != PR_SUCCESS) {
590 » break; 573 break;
591 » } 574 }
592 } 575 }
593 if (status == PR_SUCCESS) { 576 if (status == PR_SUCCESS) {
594 » nss_ZFreeIf(objects); 577 nss_ZFreeIf(objects);
595 } else { 578 } else {
596 » PRUint32 j; 579 PRUint32 j;
597 » for (j=0; j<i; j++) { 580 for (j = 0; j < i; j++) {
598 » /* sigh */ 581 /* sigh */
599 » nssToken_AddRef(cache->objects[objectType][j]->object->token); 582 nssToken_AddRef(cache->objects[objectType][j]->object->token);
600 » nssArena_Destroy(cache->objects[objectType][j]->arena); 583 nssArena_Destroy(cache->objects[objectType][j]->arena);
601 » } 584 }
602 » nss_ZFreeIf(cache->objects[objectType]); 585 nss_ZFreeIf(cache->objects[objectType]);
603 » cache->objects[objectType] = NULL; 586 cache->objects[objectType] = NULL;
604 » nssCryptokiObjectArray_Destroy(objects); 587 nssCryptokiObjectArray_Destroy(objects);
605 } 588 }
606 cache->searchedObjectType[objectType] = PR_TRUE; 589 cache->searchedObjectType[objectType] = PR_TRUE;
607 return status; 590 return status;
608 } 591 }
609 592
610 static CK_ATTRIBUTE_PTR 593 static CK_ATTRIBUTE_PTR
611 find_attribute_in_object ( 594 find_attribute_in_object(
612 nssCryptokiObjectAndAttributes *obj, 595 nssCryptokiObjectAndAttributes *obj,
613 CK_ATTRIBUTE_TYPE attrType 596 CK_ATTRIBUTE_TYPE attrType)
614 )
615 { 597 {
616 PRUint32 j; 598 PRUint32 j;
617 for (j=0; j<obj->numAttributes; j++) { 599 for (j = 0; j < obj->numAttributes; j++) {
618 » if (attrType == obj->attributes[j].type) { 600 if (attrType == obj->attributes[j].type) {
619 » return &obj->attributes[j]; 601 return &obj->attributes[j];
620 » } 602 }
621 } 603 }
622 return (CK_ATTRIBUTE_PTR)NULL; 604 return (CK_ATTRIBUTE_PTR)NULL;
623 } 605 }
624 606
625 /* Find all objects in the array that match the supplied template */ 607 /* Find all objects in the array that match the supplied template */
626 static nssCryptokiObject ** 608 static nssCryptokiObject **
627 find_objects_in_array ( 609 find_objects_in_array(
628 nssCryptokiObjectAndAttributes **objArray, 610 nssCryptokiObjectAndAttributes **objArray,
629 CK_ATTRIBUTE_PTR ot, 611 CK_ATTRIBUTE_PTR ot,
630 CK_ULONG otlen, 612 CK_ULONG otlen,
631 PRUint32 maximumOpt 613 PRUint32 maximumOpt)
632 )
633 { 614 {
634 PRIntn oi = 0; 615 PRIntn oi = 0;
635 PRUint32 i; 616 PRUint32 i;
636 NSSArena *arena; 617 NSSArena *arena;
637 PRUint32 size = 8; 618 PRUint32 size = 8;
638 PRUint32 numMatches = 0; 619 PRUint32 numMatches = 0;
639 nssCryptokiObject **objects = NULL; 620 nssCryptokiObject **objects = NULL;
640 nssCryptokiObjectAndAttributes **matches = NULL; 621 nssCryptokiObjectAndAttributes **matches = NULL;
641 CK_ATTRIBUTE_PTR attr; 622 CK_ATTRIBUTE_PTR attr;
642 623
643 if (!objArray) { 624 if (!objArray) {
644 » return (nssCryptokiObject **)NULL; 625 return (nssCryptokiObject **)NULL;
645 } 626 }
646 arena = nssArena_Create(); 627 arena = nssArena_Create();
647 if (!arena) { 628 if (!arena) {
648 » return (nssCryptokiObject **)NULL; 629 return (nssCryptokiObject **)NULL;
649 } 630 }
650 matches = nss_ZNEWARRAY(arena, nssCryptokiObjectAndAttributes *, size); 631 matches = nss_ZNEWARRAY(arena, nssCryptokiObjectAndAttributes *, size);
651 if (!matches) { 632 if (!matches) {
652 » goto loser; 633 goto loser;
653 } 634 }
654 if (maximumOpt == 0) maximumOpt = ~0; 635 if (maximumOpt == 0)
636 maximumOpt = ~0;
655 /* loop over the cached objects */ 637 /* loop over the cached objects */
656 for (; *objArray && numMatches < maximumOpt; objArray++) { 638 for (; *objArray && numMatches < maximumOpt; objArray++) {
657 » nssCryptokiObjectAndAttributes *obj = *objArray; 639 nssCryptokiObjectAndAttributes *obj = *objArray;
658 » /* loop over the test template */ 640 /* loop over the test template */
659 » for (i=0; i<otlen; i++) { 641 for (i = 0; i < otlen; i++) {
660 » /* see if the object has the attribute */ 642 /* see if the object has the attribute */
661 » attr = find_attribute_in_object(obj, ot[i].type); 643 attr = find_attribute_in_object(obj, ot[i].type);
662 » if (!attr) { 644 if (!attr) {
663 » » /* nope, match failed */ 645 /* nope, match failed */
664 » » break; 646 break;
665 » } 647 }
666 » /* compare the attribute against the test value */ 648 /* compare the attribute against the test value */
667 » if (ot[i].ulValueLen != attr->ulValueLen || 649 if (ot[i].ulValueLen != attr->ulValueLen ||
668 » !nsslibc_memequal(ot[i].pValue, 650 !nsslibc_memequal(ot[i].pValue,
669 » attr->pValue, 651 attr->pValue,
670 » attr->ulValueLen, NULL)) 652 attr->ulValueLen, NULL)) {
671 » { 653 /* nope, match failed */
672 » » /* nope, match failed */ 654 break;
673 » » break; 655 }
674 » } 656 }
675 » } 657 if (i == otlen) {
676 » if (i == otlen) { 658 /* all of the attributes in the test template were found
677 » /* all of the attributes in the test template were found 659 * in the object's template, and they all matched
678 » * in the object's template, and they all matched 660 */
679 » */ 661 matches[numMatches++] = obj;
680 » matches[numMatches++] = obj; 662 if (numMatches == size) {
681 » if (numMatches == size) { 663 size *= 2;
682 » » size *= 2; 664 matches = nss_ZREALLOCARRAY(matches,
683 » » matches = nss_ZREALLOCARRAY(matches, 665 nssCryptokiObjectAndAttributes *,
684 » » nssCryptokiObjectAndAttributes *, 666 size);
685 » » size); 667 if (!matches) {
686 » » if (!matches) { 668 goto loser;
687 » » goto loser; 669 }
688 » » } 670 }
689 » } 671 }
690 » }
691 } 672 }
692 if (numMatches > 0) { 673 if (numMatches > 0) {
693 » objects = nss_ZNEWARRAY(NULL, nssCryptokiObject *, numMatches + 1); 674 objects = nss_ZNEWARRAY(NULL, nssCryptokiObject *, numMatches + 1);
694 » if (!objects) { 675 if (!objects) {
695 » goto loser; 676 goto loser;
696 » } 677 }
697 » for (oi=0; oi<(PRIntn)numMatches; oi++) { 678 for (oi = 0; oi < (PRIntn)numMatches; oi++) {
698 » objects[oi] = nssCryptokiObject_Clone(matches[oi]->object); 679 objects[oi] = nssCryptokiObject_Clone(matches[oi]->object);
699 » if (!objects[oi]) { 680 if (!objects[oi]) {
700 » » goto loser; 681 goto loser;
701 » } 682 }
702 » } 683 }
703 } 684 }
704 nssArena_Destroy(arena); 685 nssArena_Destroy(arena);
705 return objects; 686 return objects;
706 loser: 687 loser:
707 nssCryptokiObjectArray_Destroy(objects); 688 nssCryptokiObjectArray_Destroy(objects);
708 nssArena_Destroy(arena); 689 nssArena_Destroy(arena);
709 return (nssCryptokiObject **)NULL; 690 return (nssCryptokiObject **)NULL;
710 } 691 }
711 692
712 NSS_IMPLEMENT nssCryptokiObject ** 693 NSS_IMPLEMENT nssCryptokiObject **
713 nssTokenObjectCache_FindObjectsByTemplate ( 694 nssTokenObjectCache_FindObjectsByTemplate(
714 nssTokenObjectCache *cache, 695 nssTokenObjectCache *cache,
715 CK_OBJECT_CLASS objclass, 696 CK_OBJECT_CLASS objclass,
716 CK_ATTRIBUTE_PTR otemplate, 697 CK_ATTRIBUTE_PTR otemplate,
717 CK_ULONG otlen, 698 CK_ULONG otlen,
718 PRUint32 maximumOpt, 699 PRUint32 maximumOpt,
719 PRStatus *statusOpt 700 PRStatus *statusOpt)
720 )
721 { 701 {
722 PRStatus status = PR_FAILURE; 702 PRStatus status = PR_FAILURE;
723 nssCryptokiObject **rvObjects = NULL; 703 nssCryptokiObject **rvObjects = NULL;
724 PRUint32 objectType; 704 PRUint32 objectType;
725 if (!token_is_present(cache)) { 705 if (!token_is_present(cache)) {
726 » status = PR_SUCCESS; 706 status = PR_SUCCESS;
727 » goto finish; 707 goto finish;
728 } 708 }
729 switch (objclass) { 709 switch (objclass) {
730 case CKO_CERTIFICATE: objectType = cachedCerts; break; 710 case CKO_CERTIFICATE:
731 case CKO_NETSCAPE_TRUST: objectType = cachedTrust; break; 711 objectType = cachedCerts;
732 case CKO_NETSCAPE_CRL: objectType = cachedCRLs; break; 712 break;
733 default: goto finish; 713 case CKO_NETSCAPE_TRUST:
714 objectType = cachedTrust;
715 break;
716 case CKO_NETSCAPE_CRL:
717 objectType = cachedCRLs;
718 break;
719 default:
720 goto finish;
734 } 721 }
735 PZ_Lock(cache->lock); 722 PZ_Lock(cache->lock);
736 if (cache->doObjectType[objectType]) { 723 if (cache->doObjectType[objectType]) {
737 » status = get_token_objects_for_cache(cache, objectType, objclass); 724 status = get_token_objects_for_cache(cache, objectType, objclass);
738 » if (status == PR_SUCCESS) { 725 if (status == PR_SUCCESS) {
739 » rvObjects = find_objects_in_array(cache->objects[objectType], 726 rvObjects = find_objects_in_array(cache->objects[objectType],
740 » otemplate, otlen, maximumOpt); 727 otemplate, otlen, maximumOpt);
741 » } 728 }
742 } 729 }
743 PZ_Unlock(cache->lock); 730 PZ_Unlock(cache->lock);
744 finish: 731 finish:
745 if (statusOpt) { 732 if (statusOpt) {
746 » *statusOpt = status; 733 *statusOpt = status;
747 } 734 }
748 return rvObjects; 735 return rvObjects;
749 } 736 }
750 737
751 static PRBool 738 static PRBool
752 cache_available_for_object_type ( 739 cache_available_for_object_type(
753 nssTokenObjectCache *cache, 740 nssTokenObjectCache *cache,
754 PRUint32 objectType 741 PRUint32 objectType)
755 )
756 { 742 {
757 if (!cache->doObjectType[objectType]) { 743 if (!cache->doObjectType[objectType]) {
758 » /* not caching this object kind */ 744 /* not caching this object kind */
759 » return PR_FALSE; 745 return PR_FALSE;
760 } 746 }
761 if (!cache->searchedObjectType[objectType]) { 747 if (!cache->searchedObjectType[objectType]) {
762 » /* objects are not cached yet */ 748 /* objects are not cached yet */
763 » return PR_FALSE; 749 return PR_FALSE;
764 } 750 }
765 if (!search_for_objects(cache)) { 751 if (!search_for_objects(cache)) {
766 » /* not logged in */ 752 /* not logged in */
767 » return PR_FALSE; 753 return PR_FALSE;
768 } 754 }
769 return PR_TRUE; 755 return PR_TRUE;
770 } 756 }
771 757
772 NSS_IMPLEMENT PRStatus 758 NSS_IMPLEMENT PRStatus
773 nssTokenObjectCache_GetObjectAttributes ( 759 nssTokenObjectCache_GetObjectAttributes(
774 nssTokenObjectCache *cache, 760 nssTokenObjectCache *cache,
775 NSSArena *arenaOpt, 761 NSSArena *arenaOpt,
776 nssCryptokiObject *object, 762 nssCryptokiObject *object,
777 CK_OBJECT_CLASS objclass, 763 CK_OBJECT_CLASS objclass,
778 CK_ATTRIBUTE_PTR atemplate, 764 CK_ATTRIBUTE_PTR atemplate,
779 CK_ULONG atlen 765 CK_ULONG atlen)
780 )
781 { 766 {
782 PRUint32 i, j; 767 PRUint32 i, j;
783 NSSArena *arena = NULL; 768 NSSArena *arena = NULL;
784 nssArenaMark *mark = NULL; 769 nssArenaMark *mark = NULL;
785 nssCryptokiObjectAndAttributes *cachedOA = NULL; 770 nssCryptokiObjectAndAttributes *cachedOA = NULL;
786 nssCryptokiObjectAndAttributes **oa = NULL; 771 nssCryptokiObjectAndAttributes **oa = NULL;
787 PRUint32 objectType; 772 PRUint32 objectType;
788 if (!token_is_present(cache)) { 773 if (!token_is_present(cache)) {
789 » return PR_FAILURE; 774 return PR_FAILURE;
790 } 775 }
791 PZ_Lock(cache->lock); 776 PZ_Lock(cache->lock);
792 switch (objclass) { 777 switch (objclass) {
793 case CKO_CERTIFICATE: objectType = cachedCerts; break; 778 case CKO_CERTIFICATE:
794 case CKO_NETSCAPE_TRUST: objectType = cachedTrust; break; 779 objectType = cachedCerts;
795 case CKO_NETSCAPE_CRL: objectType = cachedCRLs; break; 780 break;
796 default: goto loser; 781 case CKO_NETSCAPE_TRUST:
782 objectType = cachedTrust;
783 break;
784 case CKO_NETSCAPE_CRL:
785 objectType = cachedCRLs;
786 break;
787 default:
788 goto loser;
797 } 789 }
798 if (!cache_available_for_object_type(cache, objectType)) { 790 if (!cache_available_for_object_type(cache, objectType)) {
799 » goto loser; 791 goto loser;
800 } 792 }
801 oa = cache->objects[objectType]; 793 oa = cache->objects[objectType];
802 if (!oa) { 794 if (!oa) {
803 » goto loser; 795 goto loser;
804 } 796 }
805 for (; *oa; oa++) { 797 for (; *oa; oa++) {
806 » if (nssCryptokiObject_Equal((*oa)->object, object)) { 798 if (nssCryptokiObject_Equal((*oa)->object, object)) {
807 » cachedOA = *oa; 799 cachedOA = *oa;
808 » break; 800 break;
809 » } 801 }
810 } 802 }
811 if (!cachedOA) { 803 if (!cachedOA) {
812 » goto loser; /* don't have this object */ 804 goto loser; /* don't have this object */
813 } 805 }
814 if (arenaOpt) { 806 if (arenaOpt) {
815 » arena = arenaOpt; 807 arena = arenaOpt;
816 » mark = nssArena_Mark(arena); 808 mark = nssArena_Mark(arena);
817 } 809 }
818 for (i=0; i<atlen; i++) { 810 for (i = 0; i < atlen; i++) {
819 » for (j=0; j<cachedOA->numAttributes; j++) { 811 for (j = 0; j < cachedOA->numAttributes; j++) {
820 » if (atemplate[i].type == cachedOA->attributes[j].type) { 812 if (atemplate[i].type == cachedOA->attributes[j].type) {
821 » » CK_ATTRIBUTE_PTR attr = &cachedOA->attributes[j]; 813 CK_ATTRIBUTE_PTR attr = &cachedOA->attributes[j];
822 » » if (cachedOA->attributes[j].ulValueLen == 0 || 814 if (cachedOA->attributes[j].ulValueLen == 0 ||
823 » » cachedOA->attributes[j].ulValueLen == (CK_ULONG)-1) 815 cachedOA->attributes[j].ulValueLen == (CK_ULONG)-1) {
824 » » { 816 break; /* invalid attribute */
825 » » break; /* invalid attribute */ 817 }
826 » » } 818 if (atemplate[i].ulValueLen > 0) {
827 » » if (atemplate[i].ulValueLen > 0) { 819 if (atemplate[i].pValue == NULL ||
828 » » if (atemplate[i].pValue == NULL || 820 atemplate[i].ulValueLen < attr->ulValueLen) {
829 » » atemplate[i].ulValueLen < attr->ulValueLen) 821 goto loser;
830 » » { 822 }
831 » » » goto loser; 823 } else {
832 » » } 824 atemplate[i].pValue = nss_ZAlloc(arena, attr->ulValueLen);
833 » » } else { 825 if (!atemplate[i].pValue) {
834 » » atemplate[i].pValue = nss_ZAlloc(arena, attr->ulValueLen); 826 goto loser;
835 » » if (!atemplate[i].pValue) { 827 }
836 » » » goto loser; 828 }
837 » » } 829 nsslibc_memcpy(atemplate[i].pValue,
838 » » } 830 attr->pValue, attr->ulValueLen);
839 » » nsslibc_memcpy(atemplate[i].pValue, 831 atemplate[i].ulValueLen = attr->ulValueLen;
840 » » attr->pValue, attr->ulValueLen); 832 break;
841 » » atemplate[i].ulValueLen = attr->ulValueLen; 833 }
842 » » break; 834 }
843 » } 835 if (j == cachedOA->numAttributes) {
844 » } 836 atemplate[i].ulValueLen = (CK_ULONG)-1;
845 » if (j == cachedOA->numAttributes) { 837 }
846 » atemplate[i].ulValueLen = (CK_ULONG)-1;
847 » }
848 } 838 }
849 PZ_Unlock(cache->lock); 839 PZ_Unlock(cache->lock);
850 if (mark) { 840 if (mark) {
851 » nssArena_Unmark(arena, mark); 841 nssArena_Unmark(arena, mark);
852 } 842 }
853 return PR_SUCCESS; 843 return PR_SUCCESS;
854 loser: 844 loser:
855 PZ_Unlock(cache->lock); 845 PZ_Unlock(cache->lock);
856 if (mark) { 846 if (mark) {
857 » nssArena_Release(arena, mark); 847 nssArena_Release(arena, mark);
858 } 848 }
859 return PR_FAILURE; 849 return PR_FAILURE;
860 } 850 }
861 851
862 NSS_IMPLEMENT PRStatus 852 NSS_IMPLEMENT PRStatus
863 nssTokenObjectCache_ImportObject ( 853 nssTokenObjectCache_ImportObject(
864 nssTokenObjectCache *cache, 854 nssTokenObjectCache *cache,
865 nssCryptokiObject *object, 855 nssCryptokiObject *object,
866 CK_OBJECT_CLASS objclass, 856 CK_OBJECT_CLASS objclass,
867 CK_ATTRIBUTE_PTR ot, 857 CK_ATTRIBUTE_PTR ot,
868 CK_ULONG otlen 858 CK_ULONG otlen)
869 )
870 { 859 {
871 PRStatus status = PR_SUCCESS; 860 PRStatus status = PR_SUCCESS;
872 PRUint32 count; 861 PRUint32 count;
873 nssCryptokiObjectAndAttributes **oa, ***otype; 862 nssCryptokiObjectAndAttributes **oa, ***otype;
874 PRUint32 objectType; 863 PRUint32 objectType;
875 PRBool haveIt = PR_FALSE; 864 PRBool haveIt = PR_FALSE;
876 865
877 if (!token_is_present(cache)) { 866 if (!token_is_present(cache)) {
878 » return PR_SUCCESS; /* cache not active, ignored */ 867 return PR_SUCCESS; /* cache not active, ignored */
879 } 868 }
880 PZ_Lock(cache->lock); 869 PZ_Lock(cache->lock);
881 switch (objclass) { 870 switch (objclass) {
882 case CKO_CERTIFICATE: objectType = cachedCerts; break; 871 case CKO_CERTIFICATE:
883 case CKO_NETSCAPE_TRUST: objectType = cachedTrust; break; 872 objectType = cachedCerts;
884 case CKO_NETSCAPE_CRL: objectType = cachedCRLs; break; 873 break;
885 default: 874 case CKO_NETSCAPE_TRUST:
886 » PZ_Unlock(cache->lock); 875 objectType = cachedTrust;
887 » return PR_SUCCESS; /* don't need to import it here */ 876 break;
877 case CKO_NETSCAPE_CRL:
878 objectType = cachedCRLs;
879 break;
880 default:
881 PZ_Unlock(cache->lock);
882 return PR_SUCCESS; /* don't need to import it here */
888 } 883 }
889 if (!cache_available_for_object_type(cache, objectType)) { 884 if (!cache_available_for_object_type(cache, objectType)) {
890 » PZ_Unlock(cache->lock); 885 PZ_Unlock(cache->lock);
891 » return PR_SUCCESS; /* cache not active, ignored */ 886 return PR_SUCCESS; /* cache not active, ignored */
892 } 887 }
893 count = 0; 888 count = 0;
894 otype = &cache->objects[objectType]; /* index into array of types */ 889 otype = &cache->objects[objectType]; /* index into array of types */
895 oa = *otype; /* the array of objects for this type */ 890 oa = *otype; /* the array of objects for this type * /
896 while (oa && *oa) { 891 while (oa && *oa) {
897 » if (nssCryptokiObject_Equal((*oa)->object, object)) { 892 if (nssCryptokiObject_Equal((*oa)->object, object)) {
898 » haveIt = PR_TRUE; 893 haveIt = PR_TRUE;
899 » break; 894 break;
900 » } 895 }
901 » count++; 896 count++;
902 » oa++; 897 oa++;
903 } 898 }
904 if (haveIt) { 899 if (haveIt) {
905 » /* Destroy the old entry */ 900 /* Destroy the old entry */
906 » (*oa)->object->token = NULL; 901 (*oa)->object->token = NULL;
907 » nssCryptokiObject_Destroy((*oa)->object); 902 nssCryptokiObject_Destroy((*oa)->object);
908 » nssArena_Destroy((*oa)->arena); 903 nssArena_Destroy((*oa)->arena);
909 } else { 904 } else {
910 » /* Create space for a new entry */ 905 /* Create space for a new entry */
911 » if (count > 0) { 906 if (count > 0) {
912 » *otype = nss_ZREALLOCARRAY(*otype, 907 *otype = nss_ZREALLOCARRAY(*otype,
913 » nssCryptokiObjectAndAttributes *, 908 nssCryptokiObjectAndAttributes *,
914 » count + 2); 909 count + 2);
915 » } else { 910 } else {
916 » *otype = nss_ZNEWARRAY(NULL, nssCryptokiObjectAndAttributes *, 2); 911 *otype = nss_ZNEWARRAY(NULL, nssCryptokiObjectAndAttributes *, 2);
917 » } 912 }
918 } 913 }
919 if (*otype) { 914 if (*otype) {
920 » nssCryptokiObject *copyObject = nssCryptokiObject_Clone(object); 915 nssCryptokiObject *copyObject = nssCryptokiObject_Clone(object);
921 » (*otype)[count] = create_object_of_type(copyObject, objectType, 916 (*otype)[count] = create_object_of_type(copyObject, objectType,
922 » &status); 917 &status);
923 } else { 918 } else {
924 » status = PR_FAILURE; 919 status = PR_FAILURE;
925 } 920 }
926 PZ_Unlock(cache->lock); 921 PZ_Unlock(cache->lock);
927 return status; 922 return status;
928 } 923 }
929 924
930 NSS_IMPLEMENT void 925 NSS_IMPLEMENT void
931 nssTokenObjectCache_RemoveObject ( 926 nssTokenObjectCache_RemoveObject(
932 nssTokenObjectCache *cache, 927 nssTokenObjectCache *cache,
933 nssCryptokiObject *object 928 nssCryptokiObject *object)
934 )
935 { 929 {
936 PRUint32 oType; 930 PRUint32 oType;
937 nssCryptokiObjectAndAttributes **oa, **swp = NULL; 931 nssCryptokiObjectAndAttributes **oa, **swp = NULL;
938 if (!token_is_present(cache)) { 932 if (!token_is_present(cache)) {
939 » return; 933 return;
940 } 934 }
941 PZ_Lock(cache->lock); 935 PZ_Lock(cache->lock);
942 for (oType=0; oType<3; oType++) { 936 for (oType = 0; oType < 3; oType++) {
943 » if (!cache_available_for_object_type(cache, oType) || 937 if (!cache_available_for_object_type(cache, oType) ||
944 » !cache->objects[oType]) 938 !cache->objects[oType]) {
945 » { 939 continue;
946 » continue; 940 }
947 » } 941 for (oa = cache->objects[oType]; *oa; oa++) {
948 » for (oa = cache->objects[oType]; *oa; oa++) { 942 if (nssCryptokiObject_Equal((*oa)->object, object)) {
949 » if (nssCryptokiObject_Equal((*oa)->object, object)) { 943 swp = oa; /* the entry to remove */
950 » » swp = oa; /* the entry to remove */ 944 while (oa[1])
951 » » while (oa[1]) oa++; /* go to the tail */ 945 oa++; /* go to the tail */
952 » » (*swp)->object->token = NULL; 946 (*swp)->object->token = NULL;
953 » » nssCryptokiObject_Destroy((*swp)->object); 947 nssCryptokiObject_Destroy((*swp)->object);
954 » » nssArena_Destroy((*swp)->arena); /* destroy it */ 948 nssArena_Destroy((*swp)->arena); /* destroy it */
955 » » *swp = *oa; /* swap the last with the removed */ 949 *swp = *oa; /* swap the last with the remov ed */
956 » » *oa = NULL; /* null-terminate the array */ 950 *oa = NULL; /* null-terminate the array */
957 » » break; 951 break;
958 » } 952 }
959 » } 953 }
960 » if (swp) { 954 if (swp) {
961 » break; 955 break;
962 » } 956 }
963 } 957 }
964 if ((oType <3) && 958 if ((oType < 3) &&
965 » » cache->objects[oType] && cache->objects[oType][0] == NULL) { 959 cache->objects[oType] && cache->objects[oType][0] == NULL) {
966 » nss_ZFreeIf(cache->objects[oType]); /* no entries remaining */ 960 nss_ZFreeIf(cache->objects[oType]); /* no entries remaining */
967 » cache->objects[oType] = NULL; 961 cache->objects[oType] = NULL;
968 } 962 }
969 PZ_Unlock(cache->lock); 963 PZ_Unlock(cache->lock);
970 } 964 }
971 965
972 /* These two hash algorithms are presently sufficient. 966 /* These two hash algorithms are presently sufficient.
973 ** They are used for fingerprints of certs which are stored as the 967 ** They are used for fingerprints of certs which are stored as the
974 ** CKA_CERT_SHA1_HASH and CKA_CERT_MD5_HASH attributes. 968 ** CKA_CERT_SHA1_HASH and CKA_CERT_MD5_HASH attributes.
975 ** We don't need to add SHAxxx to these now. 969 ** We don't need to add SHAxxx to these now.
976 */ 970 */
977 /* XXX of course this doesn't belong here */ 971 /* XXX of course this doesn't belong here */
978 NSS_IMPLEMENT NSSAlgorithmAndParameters * 972 NSS_IMPLEMENT NSSAlgorithmAndParameters *
979 NSSAlgorithmAndParameters_CreateSHA1Digest ( 973 NSSAlgorithmAndParameters_CreateSHA1Digest(
980 NSSArena *arenaOpt 974 NSSArena *arenaOpt)
981 )
982 { 975 {
983 NSSAlgorithmAndParameters *rvAP = NULL; 976 NSSAlgorithmAndParameters *rvAP = NULL;
984 rvAP = nss_ZNEW(arenaOpt, NSSAlgorithmAndParameters); 977 rvAP = nss_ZNEW(arenaOpt, NSSAlgorithmAndParameters);
985 if (rvAP) { 978 if (rvAP) {
986 » rvAP->mechanism.mechanism = CKM_SHA_1; 979 rvAP->mechanism.mechanism = CKM_SHA_1;
987 » rvAP->mechanism.pParameter = NULL; 980 rvAP->mechanism.pParameter = NULL;
988 » rvAP->mechanism.ulParameterLen = 0; 981 rvAP->mechanism.ulParameterLen = 0;
989 } 982 }
990 return rvAP; 983 return rvAP;
991 } 984 }
992 985
993 NSS_IMPLEMENT NSSAlgorithmAndParameters * 986 NSS_IMPLEMENT NSSAlgorithmAndParameters *
994 NSSAlgorithmAndParameters_CreateMD5Digest ( 987 NSSAlgorithmAndParameters_CreateMD5Digest(
995 NSSArena *arenaOpt 988 NSSArena *arenaOpt)
996 )
997 { 989 {
998 NSSAlgorithmAndParameters *rvAP = NULL; 990 NSSAlgorithmAndParameters *rvAP = NULL;
999 rvAP = nss_ZNEW(arenaOpt, NSSAlgorithmAndParameters); 991 rvAP = nss_ZNEW(arenaOpt, NSSAlgorithmAndParameters);
1000 if (rvAP) { 992 if (rvAP) {
1001 » rvAP->mechanism.mechanism = CKM_MD5; 993 rvAP->mechanism.mechanism = CKM_MD5;
1002 » rvAP->mechanism.pParameter = NULL; 994 rvAP->mechanism.pParameter = NULL;
1003 » rvAP->mechanism.ulParameterLen = 0; 995 rvAP->mechanism.ulParameterLen = 0;
1004 } 996 }
1005 return rvAP; 997 return rvAP;
1006 } 998 }
1007
OLDNEW
« no previous file with comments | « nss/lib/dev/devtoken.c ('k') | nss/lib/dev/nssdev.h » ('j') | nss/lib/util/secoid.c » ('J')

Powered by Google App Engine
This is Rietveld 408576698