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

Side by Side Diff: mozilla/security/nss/lib/dev/devutil.c

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

Powered by Google App Engine
This is Rietveld 408576698