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

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

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

Powered by Google App Engine
This is Rietveld 408576698