Bug Summary

File:root/firefox-clang/security/nss/lib/pki/pkibase.c
Warning:line 791, column 9
Value stored to 'status' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -O2 -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name pkibase.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=all -relaxed-aliasing -ffp-contract=off -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/root/firefox-clang/obj-x86_64-pc-linux-gnu/security/nss/lib/pki/pki_nsspki -fcoverage-compilation-dir=/root/firefox-clang/obj-x86_64-pc-linux-gnu/security/nss/lib/pki/pki_nsspki -resource-dir /usr/lib/llvm-23/lib/clang/23 -include /root/firefox-clang/obj-x86_64-pc-linux-gnu/mozilla-config.h -U _FORTIFY_SOURCE -D _FORTIFY_SOURCE=2 -D DEBUG -D NSS_FIPS_DISABLED -D NSS_NO_INIT_SUPPORT -D NSS_X86_OR_X64 -D NSS_X64 -D NSS_USE_64 -D USE_UTIL_DIRECTLY -D NO_NSPR_10_SUPPORT -D SSL_DISABLE_DEPRECATED_CIPHER_SUITE_NAMES -D LINUX2_1 -D LINUX -D linux -D _DEFAULT_SOURCE -D _BSD_SOURCE -D _POSIX_SOURCE -D SDB_MEASURE_USE_TEMP_DIR -D HAVE_STRERROR -D XP_UNIX -D _REENTRANT -D NSS_DISABLE_DBM -D NSS_DISABLE_LIBPKIX -D NSS_USE_PKCS5_PBKD2_PARAMS2_ONLY -D SOFTOKEN_USE_PKCS5_PBKD2_PARAMS2_ONLY -I /root/firefox-clang/security/nss/lib/pki -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/security/nss/lib/pki/pki_nsspki -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include/nspr -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include/private/nss -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include/nss -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include -D MOZILLA_CLIENT -internal-isystem /usr/lib/llvm-23/lib/clang/23/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -Wno-error=tautological-type-limit-compare -Wno-range-loop-analysis -Wno-error=deprecated-declarations -Wno-error=array-bounds -Wno-error=free-nonheap-object -Wno-error=atomic-alignment -Wno-error=deprecated-builtins -Wno-psabi -Wno-error=builtin-macro-redefined -Wno-unknown-warning-option -Wno-character-conversion -ferror-limit 19 -fstrict-flex-arrays=1 -stack-protector 2 -fstack-clash-protection -ftrivial-auto-var-init=pattern -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -fdiagnostics-absolute-paths -vectorize-loops -vectorize-slp -analyzer-checker optin.performance.Padding -analyzer-output=html -analyzer-config stable-report-filename=true -mllvm -dwarf-linkage-names=Abstract -faddrsig -fdwarf2-cfi-asm -o /tmp/scan-build-2026-09-01-224014-2642839-1 -x c /root/firefox-clang/security/nss/lib/pki/pkibase.c
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 DEV_H
6#include "dev.h"
7#endif /* DEV_H */
8
9#ifndef PKIM_H
10#include "pkim.h"
11#endif /* PKIM_H */
12
13#include "pki3hack.h"
14
15extern const NSSError NSS_ERROR_NOT_FOUND;
16
17NSS_IMPLEMENT void
18nssPKIObject_Lock(nssPKIObject *object)
19{
20 switch (object->lockType) {
21 case nssPKIMonitor:
22 PR_EnterMonitor(object->sync.mlock);
23 break;
24 case nssPKILock:
25 PR_Lock(object->sync.lock);
26 break;
27 default:
28 PORT_Assert(0)((0) ? ((void)0) : PR_Assert("0", "/root/firefox-clang/security/nss/lib/pki/pkibase.c"
, 28))
;
29 }
30}
31
32NSS_IMPLEMENT void
33nssPKIObject_Unlock(nssPKIObject *object)
34{
35 switch (object->lockType) {
36 case nssPKIMonitor:
37 PR_ExitMonitor(object->sync.mlock);
38 break;
39 case nssPKILock:
40 PR_Unlock(object->sync.lock);
41 break;
42 default:
43 PORT_Assert(0)((0) ? ((void)0) : PR_Assert("0", "/root/firefox-clang/security/nss/lib/pki/pkibase.c"
, 43))
;
44 }
45}
46
47NSS_IMPLEMENT PRStatus
48nssPKIObject_NewLock(nssPKIObject *object, nssPKILockType lockType)
49{
50 object->lockType = lockType;
51 switch (lockType) {
52 case nssPKIMonitor:
53 object->sync.mlock = PR_NewMonitor();
54 return (object->sync.mlock ? PR_SUCCESS : PR_FAILURE);
55 case nssPKILock:
56 object->sync.lock = PR_NewLock();
57 return (object->sync.lock ? PR_SUCCESS : PR_FAILURE);
58 default:
59 PORT_Assert(0)((0) ? ((void)0) : PR_Assert("0", "/root/firefox-clang/security/nss/lib/pki/pkibase.c"
, 59))
;
60 return PR_FAILURE;
61 }
62}
63
64NSS_IMPLEMENT void
65nssPKIObject_DestroyLock(nssPKIObject *object)
66{
67 switch (object->lockType) {
68 case nssPKIMonitor:
69 PR_DestroyMonitor(object->sync.mlock);
70 object->sync.mlock = NULL((void*)0);
71 break;
72 case nssPKILock:
73 PR_DestroyLock(object->sync.lock);
74 object->sync.lock = NULL((void*)0);
75 break;
76 default:
77 PORT_Assert(0)((0) ? ((void)0) : PR_Assert("0", "/root/firefox-clang/security/nss/lib/pki/pkibase.c"
, 77))
;
78 }
79}
80
81NSS_IMPLEMENT nssPKIObject *
82nssPKIObject_Create(
83 NSSArena *arenaOpt,
84 nssCryptokiObject *instanceOpt,
85 NSSTrustDomain *td,
86 NSSCryptoContext *cc,
87 nssPKILockType lockType)
88{
89 NSSArena *arena;
90 nssArenaMark *mark = NULL((void*)0);
91 nssPKIObject *object;
92 if (arenaOpt) {
93 arena = arenaOpt;
94 mark = nssArena_Mark(arena);
95 } else {
96 arena = nssArena_Create();
97 if (!arena) {
98 return (nssPKIObject *)NULL((void*)0);
99 }
100 }
101 object = nss_ZNEW(arena, nssPKIObject)((nssPKIObject *)nss_ZAlloc((arena), sizeof(nssPKIObject)));
102 if (!object) {
103 goto loser;
104 }
105 object->arena = arena;
106 object->trustDomain = td; /* XXX */
107 object->cryptoContext = cc;
108 if (PR_SUCCESS != nssPKIObject_NewLock(object, lockType)) {
109 goto loser;
110 }
111 if (instanceOpt) {
112 if (nssPKIObject_AddInstance(object, instanceOpt) != PR_SUCCESS) {
113 goto loser;
114 }
115 }
116 PR_ATOMIC_INCREMENT(&object->refCount)__sync_add_and_fetch(&object->refCount, 1);
117 if (mark) {
118 nssArena_Unmark(arena, mark);
119 }
120 return object;
121loser:
122 if (mark) {
123 nssArena_Release(arena, mark);
124 } else {
125 nssArena_Destroy(arena);
126 }
127 return (nssPKIObject *)NULL((void*)0);
128}
129
130NSS_IMPLEMENT PRBool
131nssPKIObject_Destroy(
132 nssPKIObject *object)
133{
134 PRUint32 i;
135 PR_ASSERT(object->refCount > 0)((object->refCount > 0) ? ((void)0) : PR_Assert("object->refCount > 0"
, "/root/firefox-clang/security/nss/lib/pki/pkibase.c", 135))
;
136 if (PR_ATOMIC_DECREMENT(&object->refCount)__sync_sub_and_fetch(&object->refCount, 1) == 0) {
137 for (i = 0; i < object->numInstances; i++) {
138 nssCryptokiObject_Destroy(object->instances[i]);
139 }
140 nssPKIObject_DestroyLock(object);
141 nssArena_Destroy(object->arena);
142 return PR_TRUE1;
143 }
144 return PR_FALSE0;
145}
146
147NSS_IMPLEMENT nssPKIObject *
148nssPKIObject_AddRef(
149 nssPKIObject *object)
150{
151 PR_ATOMIC_INCREMENT(&object->refCount)__sync_add_and_fetch(&object->refCount, 1);
152 return object;
153}
154
155NSS_IMPLEMENT PRStatus
156nssPKIObject_AddInstance(
157 nssPKIObject *object,
158 nssCryptokiObject *instance)
159{
160 nssCryptokiObject **newInstances = NULL((void*)0);
161
162 nssPKIObject_Lock(object);
163 if (object->numInstances == 0) {
164 newInstances = nss_ZNEWARRAY(object->arena,((nssCryptokiObject * *)(((PRUint64)(object->numInstances +
1) > 4294967295U / sizeof(nssCryptokiObject *)) ? ((void*
)0) : nss_ZAlloc((object->arena), (PRUint32)(sizeof(nssCryptokiObject
*) * (PRUint64)(object->numInstances + 1)))))
165 nssCryptokiObject *,((nssCryptokiObject * *)(((PRUint64)(object->numInstances +
1) > 4294967295U / sizeof(nssCryptokiObject *)) ? ((void*
)0) : nss_ZAlloc((object->arena), (PRUint32)(sizeof(nssCryptokiObject
*) * (PRUint64)(object->numInstances + 1)))))
166 object->numInstances + 1)((nssCryptokiObject * *)(((PRUint64)(object->numInstances +
1) > 4294967295U / sizeof(nssCryptokiObject *)) ? ((void*
)0) : nss_ZAlloc((object->arena), (PRUint32)(sizeof(nssCryptokiObject
*) * (PRUint64)(object->numInstances + 1)))))
;
167 } else {
168 PRBool found = PR_FALSE0;
169 PRUint32 i;
170 for (i = 0; i < object->numInstances; i++) {
171 if (nssCryptokiObject_Equal(object->instances[i], instance)) {
172 found = PR_TRUE1;
173 break;
174 }
175 }
176 if (found) {
177 /* The new instance is identical to one in the array, except
178 * perhaps that the label may be different. So replace
179 * the label in the array instance with the label from the
180 * new instance, and discard the new instance.
181 */
182 nss_ZFreeIf(object->instances[i]->label);
183 object->instances[i]->label = instance->label;
184 nssPKIObject_Unlock(object);
185 instance->label = NULL((void*)0);
186 nssCryptokiObject_Destroy(instance);
187 return PR_SUCCESS;
188 }
189 newInstances = nss_ZREALLOCARRAY(object->instances,((nssCryptokiObject * *)(((PRUint64)(object->numInstances +
1) > 4294967295U / sizeof(nssCryptokiObject *)) ? ((void*
)0) : nss_ZRealloc((object->instances), (PRUint32)(sizeof(
nssCryptokiObject *) * (PRUint64)(object->numInstances + 1
)))))
190 nssCryptokiObject *,((nssCryptokiObject * *)(((PRUint64)(object->numInstances +
1) > 4294967295U / sizeof(nssCryptokiObject *)) ? ((void*
)0) : nss_ZRealloc((object->instances), (PRUint32)(sizeof(
nssCryptokiObject *) * (PRUint64)(object->numInstances + 1
)))))
191 object->numInstances + 1)((nssCryptokiObject * *)(((PRUint64)(object->numInstances +
1) > 4294967295U / sizeof(nssCryptokiObject *)) ? ((void*
)0) : nss_ZRealloc((object->instances), (PRUint32)(sizeof(
nssCryptokiObject *) * (PRUint64)(object->numInstances + 1
)))))
;
192 }
193 if (newInstances) {
194 object->instances = newInstances;
195 newInstances[object->numInstances++] = instance;
196 }
197 nssPKIObject_Unlock(object);
198 return (newInstances ? PR_SUCCESS : PR_FAILURE);
199}
200
201NSS_IMPLEMENT PRBool
202nssPKIObject_HasInstance(
203 nssPKIObject *object,
204 nssCryptokiObject *instance)
205{
206 PRUint32 i;
207 PRBool hasIt = PR_FALSE0;
208 ;
209 nssPKIObject_Lock(object);
210 for (i = 0; i < object->numInstances; i++) {
211 if (nssCryptokiObject_Equal(object->instances[i], instance)) {
212 hasIt = PR_TRUE1;
213 break;
214 }
215 }
216 nssPKIObject_Unlock(object);
217 return hasIt;
218}
219
220NSS_IMPLEMENT PRStatus
221nssPKIObject_RemoveInstanceForToken(
222 nssPKIObject *object,
223 NSSToken *token)
224{
225 PRUint32 i;
226 nssCryptokiObject *instanceToRemove = NULL((void*)0);
227 nssPKIObject_Lock(object);
228 if (object->numInstances == 0) {
229 nssPKIObject_Unlock(object);
230 return PR_SUCCESS;
231 }
232 for (i = 0; i < object->numInstances; i++) {
233 if (object->instances[i]->token == token) {
234 instanceToRemove = object->instances[i];
235 object->instances[i] = object->instances[object->numInstances - 1];
236 object->instances[object->numInstances - 1] = NULL((void*)0);
237 break;
238 }
239 }
240 if (--object->numInstances > 0) {
241 nssCryptokiObject **instances = nss_ZREALLOCARRAY(object->instances,((nssCryptokiObject * *)(((PRUint64)(object->numInstances)
> 4294967295U / sizeof(nssCryptokiObject *)) ? ((void*)0)
: nss_ZRealloc((object->instances), (PRUint32)(sizeof(nssCryptokiObject
*) * (PRUint64)(object->numInstances)))))
242 nssCryptokiObject *,((nssCryptokiObject * *)(((PRUint64)(object->numInstances)
> 4294967295U / sizeof(nssCryptokiObject *)) ? ((void*)0)
: nss_ZRealloc((object->instances), (PRUint32)(sizeof(nssCryptokiObject
*) * (PRUint64)(object->numInstances)))))
243 object->numInstances)((nssCryptokiObject * *)(((PRUint64)(object->numInstances)
> 4294967295U / sizeof(nssCryptokiObject *)) ? ((void*)0)
: nss_ZRealloc((object->instances), (PRUint32)(sizeof(nssCryptokiObject
*) * (PRUint64)(object->numInstances)))))
;
244 if (instances) {
245 object->instances = instances;
246 }
247 } else {
248 nss_ZFreeIf(object->instances);
249 }
250 nssCryptokiObject_Destroy(instanceToRemove);
251 nssPKIObject_Unlock(object);
252 return PR_SUCCESS;
253}
254
255/* this needs more thought on what will happen when there are multiple
256 * instances
257 */
258NSS_IMPLEMENT PRStatus
259nssPKIObject_DeleteStoredObject(
260 nssPKIObject *object,
261 NSSCallback *uhh,
262 PRBool isFriendly)
263{
264 PRUint32 i, numNotDestroyed;
265 PRStatus status = PR_SUCCESS;
266 numNotDestroyed = 0;
267 nssPKIObject_Lock(object);
268 for (i = 0; i < object->numInstances; i++) {
269 nssCryptokiObject *instance = object->instances[i];
270 status = nssToken_DeleteStoredObject(instance);
271 object->instances[i] = NULL((void*)0);
272 if (status == PR_SUCCESS) {
273 nssCryptokiObject_Destroy(instance);
274 } else {
275 object->instances[numNotDestroyed++] = instance;
276 }
277 }
278 if (numNotDestroyed == 0) {
279 nss_ZFreeIf(object->instances);
280 object->numInstances = 0;
281 } else {
282 object->numInstances = numNotDestroyed;
283 }
284 nssPKIObject_Unlock(object);
285 return status;
286}
287
288NSS_IMPLEMENT NSSToken **
289nssPKIObject_GetTokens(
290 nssPKIObject *object,
291 PRStatus *statusOpt)
292{
293 NSSToken **tokens = NULL((void*)0);
294 nssPKIObject_Lock(object);
295 if (object->numInstances > 0) {
296 tokens = nss_ZNEWARRAY(NULL, NSSToken *, object->numInstances + 1)((NSSToken * *)(((PRUint64)(object->numInstances + 1) >
4294967295U / sizeof(NSSToken *)) ? ((void*)0) : nss_ZAlloc(
(((void*)0)), (PRUint32)(sizeof(NSSToken *) * (PRUint64)(object
->numInstances + 1)))))
;
297 if (tokens) {
298 PRUint32 i;
299 for (i = 0; i < object->numInstances; i++) {
300 tokens[i] = nssToken_AddRef(object->instances[i]->token);
301 }
302 }
303 }
304 nssPKIObject_Unlock(object);
305 if (statusOpt)
306 *statusOpt = PR_SUCCESS; /* until more logic here */
307 return tokens;
308}
309
310NSS_IMPLEMENT NSSUTF8 *
311nssPKIObject_GetNicknameForToken(
312 nssPKIObject *object,
313 NSSToken *tokenOpt)
314{
315 PRUint32 i;
316 NSSUTF8 *nickname = NULL((void*)0);
317 nssPKIObject_Lock(object);
318 for (i = 0; i < object->numInstances; i++) {
319 if ((!tokenOpt && object->instances[i]->label) ||
320 (object->instances[i]->token == tokenOpt)) {
321 /* Must copy, see bug 745548 */
322 nickname = nssUTF8_Duplicate(object->instances[i]->label, NULL((void*)0));
323 break;
324 }
325 }
326 nssPKIObject_Unlock(object);
327 return nickname;
328}
329
330NSS_IMPLEMENT nssCryptokiObject **
331nssPKIObject_GetInstances(
332 nssPKIObject *object)
333{
334 nssCryptokiObject **instances = NULL((void*)0);
335 PRUint32 i;
336
337 nssPKIObject_Lock(object);
338 if (object->numInstances == 0) {
339 nssPKIObject_Unlock(object);
340 return (nssCryptokiObject **)NULL((void*)0);
341 }
342 instances = nss_ZNEWARRAY(NULL, nssCryptokiObject *,((nssCryptokiObject * *)(((PRUint64)(object->numInstances +
1) > 4294967295U / sizeof(nssCryptokiObject *)) ? ((void*
)0) : nss_ZAlloc((((void*)0)), (PRUint32)(sizeof(nssCryptokiObject
*) * (PRUint64)(object->numInstances + 1)))))
343 object->numInstances + 1)((nssCryptokiObject * *)(((PRUint64)(object->numInstances +
1) > 4294967295U / sizeof(nssCryptokiObject *)) ? ((void*
)0) : nss_ZAlloc((((void*)0)), (PRUint32)(sizeof(nssCryptokiObject
*) * (PRUint64)(object->numInstances + 1)))))
;
344 if (instances) {
345 for (i = 0; i < object->numInstances; i++) {
346 instances[i] = nssCryptokiObject_Clone(object->instances[i]);
347 }
348 }
349 nssPKIObject_Unlock(object);
350 return instances;
351}
352
353NSS_IMPLEMENT void
354nssCertificateArray_Destroy(
355 NSSCertificate **certs)
356{
357 if (certs) {
358 NSSCertificate **certp;
359 for (certp = certs; *certp; certp++) {
360 if ((*certp)->decoding) {
361 CERTCertificate *cc = STAN_GetCERTCertificate(*certp);
362 if (cc) {
363 CERT_DestroyCertificate(cc);
364 }
365 continue;
366 }
367 nssCertificate_Destroy(*certp);
368 }
369 nss_ZFreeIf(certs);
370 }
371}
372
373NSS_IMPLEMENT void
374NSSCertificateArray_Destroy(
375 NSSCertificate **certs)
376{
377 nssCertificateArray_Destroy(certs);
378}
379
380NSS_IMPLEMENT NSSCertificate **
381nssCertificateArray_Join(
382 NSSCertificate **certs1,
383 NSSCertificate **certs2)
384{
385 if (certs1 && certs2) {
386 NSSCertificate **certs, **cp;
387 PRUint32 count = 0;
388 PRUint32 count1 = 0;
389 cp = certs1;
390 while (*cp++)
391 count1++;
392 count = count1;
393 cp = certs2;
394 while (*cp++)
395 count++;
396 certs = nss_ZREALLOCARRAY(certs1, NSSCertificate *, count + 1)((NSSCertificate * *)(((PRUint64)(count + 1) > 4294967295U
/ sizeof(NSSCertificate *)) ? ((void*)0) : nss_ZRealloc((certs1
), (PRUint32)(sizeof(NSSCertificate *) * (PRUint64)(count + 1
)))))
;
397 if (!certs) {
398 nss_ZFreeIf(certs1);
399 nss_ZFreeIf(certs2);
400 return (NSSCertificate **)NULL((void*)0);
401 }
402 for (cp = certs2; *cp; cp++, count1++) {
403 certs[count1] = *cp;
404 }
405 nss_ZFreeIf(certs2);
406 return certs;
407 } else if (certs1) {
408 return certs1;
409 } else {
410 return certs2;
411 }
412}
413
414NSS_IMPLEMENT NSSCertificate *
415nssCertificateArray_FindBestCertificate(
416 NSSCertificate **certs,
417 NSSTime *timeOpt,
418 const NSSUsage *usage,
419 NSSPolicies *policiesOpt)
420{
421 NSSCertificate *bestCert = NULL((void*)0);
422 nssDecodedCert *bestdc = NULL((void*)0);
423 NSSTime *time, sTime;
424 PRBool bestCertMatches = PR_FALSE0;
425 PRBool thisCertMatches;
426 PRBool bestCertIsValidAtTime = PR_FALSE0;
427 PRBool bestCertIsTrusted = PR_FALSE0;
428
429 if (timeOpt) {
430 time = timeOpt;
431 } else {
432 NSSTime_Now(&sTime);
433 time = &sTime;
434 }
435 if (!certs) {
436 return (NSSCertificate *)NULL((void*)0);
437 }
438 for (; *certs; certs++) {
439 nssDecodedCert *dc;
440 NSSCertificate *c = *certs;
441 dc = nssCertificate_GetDecoding(c);
442 if (!dc)
443 continue;
444 thisCertMatches = dc->matchUsage(dc, usage);
445 if (!bestCert) {
446 /* always take the first cert, but remember whether or not
447 * the usage matched
448 */
449 bestCert = nssCertificate_AddRef(c);
450 bestCertMatches = thisCertMatches;
451 bestdc = dc;
452 continue;
453 } else {
454 if (bestCertMatches && !thisCertMatches) {
455 /* if already have a cert for this usage, and if this cert
456 * doesn't have the correct usage, continue
457 */
458 continue;
459 } else if (!bestCertMatches && thisCertMatches) {
460 /* this one does match usage, replace the other */
461 nssCertificate_Destroy(bestCert);
462 bestCert = nssCertificate_AddRef(c);
463 bestCertMatches = thisCertMatches;
464 bestdc = dc;
465 continue;
466 }
467 /* this cert match as well as any cert we've found so far,
468 * defer to time/policies
469 * */
470 }
471 /* time */
472 if (bestCertIsValidAtTime || bestdc->isValidAtTime(bestdc, time)) {
473 /* The current best cert is valid at time */
474 bestCertIsValidAtTime = PR_TRUE1;
475 if (!dc->isValidAtTime(dc, time)) {
476 /* If the new cert isn't valid at time, it's not better */
477 continue;
478 }
479 } else {
480 /* The current best cert is not valid at time */
481 if (dc->isValidAtTime(dc, time)) {
482 /* If the new cert is valid at time, it's better */
483 nssCertificate_Destroy(bestCert);
484 bestCert = nssCertificate_AddRef(c);
485 bestdc = dc;
486 bestCertIsValidAtTime = PR_TRUE1;
487 continue;
488 }
489 }
490 /* Either they are both valid at time, or neither valid.
491 * If only one is trusted for this usage, take it.
492 */
493 if (bestCertIsTrusted || bestdc->isTrustedForUsage(bestdc, usage)) {
494 bestCertIsTrusted = PR_TRUE1;
495 if (!dc->isTrustedForUsage(dc, usage)) {
496 continue;
497 }
498 } else {
499 /* The current best cert is not trusted */
500 if (dc->isTrustedForUsage(dc, usage)) {
501 /* If the new cert is trusted, it's better */
502 nssCertificate_Destroy(bestCert);
503 bestCert = nssCertificate_AddRef(c);
504 bestdc = dc;
505 bestCertIsTrusted = PR_TRUE1;
506 continue;
507 }
508 }
509 /* Otherwise, take the newer one. */
510 if (!bestdc->isNewerThan(bestdc, dc)) {
511 nssCertificate_Destroy(bestCert);
512 bestCert = nssCertificate_AddRef(c);
513 bestdc = dc;
514 continue;
515 }
516 /* policies */
517 /* XXX later -- defer to policies */
518 }
519 return bestCert;
520}
521
522NSS_IMPLEMENT PRStatus
523nssCertificateArray_Traverse(
524 NSSCertificate **certs,
525 PRStatus (*callback)(NSSCertificate *c, void *arg),
526 void *arg)
527{
528 PRStatus status = PR_SUCCESS;
529 if (certs) {
530 NSSCertificate **certp;
531 for (certp = certs; *certp; certp++) {
532 status = (*callback)(*certp, arg);
533 if (status != PR_SUCCESS) {
534 break;
535 }
536 }
537 }
538 return status;
539}
540
541NSS_IMPLEMENT void
542nssCRLArray_Destroy(
543 NSSCRL **crls)
544{
545 if (crls) {
546 NSSCRL **crlp;
547 for (crlp = crls; *crlp; crlp++) {
548 nssCRL_Destroy(*crlp);
549 }
550 nss_ZFreeIf(crls);
551 }
552}
553
554/*
555 * Object collections
556 */
557
558typedef enum {
559 pkiObjectType_Certificate = 0,
560 pkiObjectType_CRL = 1,
561 pkiObjectType_PrivateKey = 2,
562 pkiObjectType_PublicKey = 3
563} pkiObjectType;
564
565/* Each object is defined by a set of items that uniquely identify it.
566 * Here are the uid sets:
567 *
568 * NSSCertificate ==> { issuer, serial }
569 * NSSPrivateKey
570 * (RSA) ==> { modulus, public exponent }
571 *
572 */
573#define MAX_ITEMS_FOR_UID2 2
574
575/* pkiObjectCollectionNode
576 *
577 * A node in the collection is the set of unique identifiers for a single
578 * object, along with either the actual object or a proto-object.
579 */
580typedef struct
581{
582 PRCList link;
583 PRBool haveObject;
584 nssPKIObject *object;
585 NSSItem uid[MAX_ITEMS_FOR_UID2];
586} pkiObjectCollectionNode;
587
588/* nssPKIObjectCollection
589 *
590 * The collection is the set of all objects, plus the interfaces needed
591 * to manage the objects.
592 *
593 */
594struct nssPKIObjectCollectionStr {
595 NSSArena *arena;
596 NSSTrustDomain *td;
597 NSSCryptoContext *cc;
598 PRCList head; /* list of pkiObjectCollectionNode's */
599 PRUint32 size;
600 pkiObjectType objectType;
601 void (*destroyObject)(nssPKIObject *o);
602 PRStatus (*getUIDFromObject)(nssPKIObject *o, NSSItem *uid);
603 PRStatus (*getUIDFromInstance)(nssCryptokiObject *co, NSSItem *uid,
604 NSSArena *arena);
605 nssPKIObject *(*createObject)(nssPKIObject *o);
606 nssPKILockType lockType; /* type of lock to use for new proto-objects */
607};
608
609static nssPKIObjectCollection *
610nssPKIObjectCollection_Create(
611 NSSTrustDomain *td,
612 NSSCryptoContext *ccOpt,
613 nssPKILockType lockType)
614{
615 NSSArena *arena;
616 nssPKIObjectCollection *rvCollection = NULL((void*)0);
617 arena = nssArena_Create();
618 if (!arena) {
619 return (nssPKIObjectCollection *)NULL((void*)0);
620 }
621 rvCollection = nss_ZNEW(arena, nssPKIObjectCollection)((nssPKIObjectCollection *)nss_ZAlloc((arena), sizeof(nssPKIObjectCollection
)))
;
622 if (!rvCollection) {
623 goto loser;
624 }
625 PR_INIT_CLIST(&rvCollection->head)do {(&rvCollection->head)->next = (&rvCollection
->head); (&rvCollection->head)->prev = (&rvCollection
->head); } while (0)
;
626 rvCollection->arena = arena;
627 rvCollection->td = td; /* XXX */
628 rvCollection->cc = ccOpt;
629 rvCollection->lockType = lockType;
630 return rvCollection;
631loser:
632 nssArena_Destroy(arena);
633 return (nssPKIObjectCollection *)NULL((void*)0);
634}
635
636NSS_IMPLEMENT void
637nssPKIObjectCollection_Destroy(
638 nssPKIObjectCollection *collection)
639{
640 if (collection) {
641 PRCList *link;
642 pkiObjectCollectionNode *node;
643 /* first destroy any objects in the collection */
644 link = PR_NEXT_LINK(&collection->head)((&collection->head)->next);
645 while (link != &collection->head) {
646 node = (pkiObjectCollectionNode *)link;
647 if (node->haveObject) {
648 (*collection->destroyObject)(node->object);
649 } else {
650 nssPKIObject_Destroy(node->object);
651 }
652 link = PR_NEXT_LINK(link)((link)->next);
653 }
654 /* then destroy it */
655 nssArena_Destroy(collection->arena);
656 }
657}
658
659NSS_IMPLEMENT PRUint32
660nssPKIObjectCollection_Count(
661 nssPKIObjectCollection *collection)
662{
663 return collection->size;
664}
665
666NSS_IMPLEMENT PRStatus
667nssPKIObjectCollection_AddObject(
668 nssPKIObjectCollection *collection,
669 nssPKIObject *object)
670{
671 pkiObjectCollectionNode *node;
672 node = nss_ZNEW(collection->arena, pkiObjectCollectionNode)((pkiObjectCollectionNode *)nss_ZAlloc((collection->arena)
, sizeof(pkiObjectCollectionNode)))
;
673 if (!node) {
674 return PR_FAILURE;
675 }
676 node->haveObject = PR_TRUE1;
677 node->object = nssPKIObject_AddRef(object);
678 (*collection->getUIDFromObject)(object, node->uid);
679 PR_INIT_CLIST(&node->link)do {(&node->link)->next = (&node->link); (&
node->link)->prev = (&node->link); } while (0)
;
680 PR_INSERT_BEFORE(&node->link, &collection->head)do {(&node->link)->next = (&collection->head
); (&node->link)->prev = (&collection->head)
->prev; (&collection->head)->prev->next = (&
node->link); (&collection->head)->prev = (&node
->link); } while (0)
;
681 collection->size++;
682 return PR_SUCCESS;
683}
684
685static pkiObjectCollectionNode *
686find_instance_in_collection(
687 nssPKIObjectCollection *collection,
688 nssCryptokiObject *instance)
689{
690 PRCList *link;
691 pkiObjectCollectionNode *node;
692 link = PR_NEXT_LINK(&collection->head)((&collection->head)->next);
693 while (link != &collection->head) {
694 node = (pkiObjectCollectionNode *)link;
695 if (nssPKIObject_HasInstance(node->object, instance)) {
696 return node;
697 }
698 link = PR_NEXT_LINK(link)((link)->next);
699 }
700 return (pkiObjectCollectionNode *)NULL((void*)0);
701}
702
703static pkiObjectCollectionNode *
704find_object_in_collection(
705 nssPKIObjectCollection *collection,
706 NSSItem *uid)
707{
708 PRUint32 i;
709 PRStatus status;
710 PRCList *link;
711 pkiObjectCollectionNode *node;
712 link = PR_NEXT_LINK(&collection->head)((&collection->head)->next);
713 while (link != &collection->head) {
714 node = (pkiObjectCollectionNode *)link;
715 for (i = 0; i < MAX_ITEMS_FOR_UID2; i++) {
716 if (!nssItem_Equal(&node->uid[i], &uid[i], &status)) {
717 break;
718 }
719 }
720 if (i == MAX_ITEMS_FOR_UID2) {
721 return node;
722 }
723 link = PR_NEXT_LINK(link)((link)->next);
724 }
725 return (pkiObjectCollectionNode *)NULL((void*)0);
726}
727
728static pkiObjectCollectionNode *
729add_object_instance(
730 nssPKIObjectCollection *collection,
731 nssCryptokiObject *instance,
732 PRBool *foundIt)
733{
734 PRUint32 i;
735 PRStatus status;
736 pkiObjectCollectionNode *node;
737 nssArenaMark *mark = NULL((void*)0);
738 NSSItem uid[MAX_ITEMS_FOR_UID2];
739 nsslibc_memset(uid, 0, sizeof uid);
740 /* The list is traversed twice, first (here) looking to match the
741 * { token, handle } tuple, and if that is not found, below a search
742 * for unique identifier is done. Here, a match means this exact object
743 * instance is already in the collection, and we have nothing to do.
744 */
745 *foundIt = PR_FALSE0;
746 node = find_instance_in_collection(collection, instance);
747 if (node) {
748 /* The collection is assumed to take over the instance. Since we
749 * are not using it, it must be destroyed.
750 */
751 nssCryptokiObject_Destroy(instance);
752 *foundIt = PR_TRUE1;
753 return node;
754 }
755 mark = nssArena_Mark(collection->arena);
756 if (!mark) {
757 goto loser;
758 }
759 status = (*collection->getUIDFromInstance)(instance, uid,
760 collection->arena);
761 if (status != PR_SUCCESS) {
762 goto loser;
763 }
764 /* Search for unique identifier. A match here means the object exists
765 * in the collection, but does not have this instance, so the instance
766 * needs to be added.
767 */
768 node = find_object_in_collection(collection, uid);
769 if (node) {
770 /* This is an object with multiple instances */
771 status = nssPKIObject_AddInstance(node->object, instance);
772 } else {
773 /* This is a completely new object. Create a node for it. */
774 node = nss_ZNEW(collection->arena, pkiObjectCollectionNode)((pkiObjectCollectionNode *)nss_ZAlloc((collection->arena)
, sizeof(pkiObjectCollectionNode)))
;
775 if (!node) {
776 goto loser;
777 }
778 node->object = nssPKIObject_Create(NULL((void*)0), instance,
779 collection->td, collection->cc,
780 collection->lockType);
781 if (!node->object) {
782 goto loser;
783 }
784 for (i = 0; i < MAX_ITEMS_FOR_UID2; i++) {
785 node->uid[i] = uid[i];
786 }
787 node->haveObject = PR_FALSE0;
788 PR_INIT_CLIST(&node->link)do {(&node->link)->next = (&node->link); (&
node->link)->prev = (&node->link); } while (0)
;
789 PR_INSERT_BEFORE(&node->link, &collection->head)do {(&node->link)->next = (&collection->head
); (&node->link)->prev = (&collection->head)
->prev; (&collection->head)->prev->next = (&
node->link); (&collection->head)->prev = (&node
->link); } while (0)
;
790 collection->size++;
791 status = PR_SUCCESS;
Value stored to 'status' is never read
792 }
793 nssArena_Unmark(collection->arena, mark);
794 return node;
795loser:
796 if (mark) {
797 nssArena_Release(collection->arena, mark);
798 }
799 nssCryptokiObject_Destroy(instance);
800 return (pkiObjectCollectionNode *)NULL((void*)0);
801}
802
803NSS_IMPLEMENT PRStatus
804nssPKIObjectCollection_AddInstances(
805 nssPKIObjectCollection *collection,
806 nssCryptokiObject **instances,
807 PRUint32 numInstances)
808{
809 PRStatus status = PR_SUCCESS;
810 PRUint32 i = 0;
811 PRBool foundIt;
812 pkiObjectCollectionNode *node;
813 if (instances) {
814 while ((!numInstances || i < numInstances) && *instances) {
815 if (status == PR_SUCCESS) {
816 node = add_object_instance(collection, *instances, &foundIt);
817 if (node == NULL((void*)0)) {
818 /* add_object_instance freed the current instance */
819 /* free the remaining instances */
820 status = PR_FAILURE;
821 }
822 } else {
823 nssCryptokiObject_Destroy(*instances);
824 }
825 instances++;
826 i++;
827 }
828 }
829 return status;
830}
831
832static void
833nssPKIObjectCollection_RemoveNode(
834 nssPKIObjectCollection *collection,
835 pkiObjectCollectionNode *node)
836{
837 PR_REMOVE_LINK(&node->link)do {(&node->link)->prev->next = (&node->link
)->next; (&node->link)->next->prev = (&node
->link)->prev; } while (0)
;
838 collection->size--;
839}
840
841static PRStatus
842nssPKIObjectCollection_GetObjects(
843 nssPKIObjectCollection *collection,
844 nssPKIObject **rvObjects,
845 PRUint32 rvSize)
846{
847 PRUint32 i = 0;
848 PRCList *link = PR_NEXT_LINK(&collection->head)((&collection->head)->next);
849 pkiObjectCollectionNode *node;
850 int error = 0;
851 while ((i < rvSize) && (link != &collection->head)) {
852 node = (pkiObjectCollectionNode *)link;
853 if (!node->haveObject) {
854 /* Convert the proto-object to an object */
855 node->object = (*collection->createObject)(node->object);
856 if (!node->object) {
857 link = PR_NEXT_LINK(link)((link)->next);
858 /*remove bogus object from list*/
859 nssPKIObjectCollection_RemoveNode(collection, node);
860 error++;
861 continue;
862 }
863 node->haveObject = PR_TRUE1;
864 }
865 rvObjects[i++] = nssPKIObject_AddRef(node->object);
866 link = PR_NEXT_LINK(link)((link)->next);
867 }
868 if (!error && *rvObjects == NULL((void*)0)) {
869 nss_SetError(NSS_ERROR_NOT_FOUND);
870 }
871 return PR_SUCCESS;
872}
873
874NSS_IMPLEMENT PRStatus
875nssPKIObjectCollection_Traverse(
876 nssPKIObjectCollection *collection,
877 nssPKIObjectCallback *callback)
878{
879 PRCList *link = PR_NEXT_LINK(&collection->head)((&collection->head)->next);
880 pkiObjectCollectionNode *node;
881 while (link != &collection->head) {
882 node = (pkiObjectCollectionNode *)link;
883 if (!node->haveObject) {
884 node->object = (*collection->createObject)(node->object);
885 if (!node->object) {
886 link = PR_NEXT_LINK(link)((link)->next);
887 /*remove bogus object from list*/
888 nssPKIObjectCollection_RemoveNode(collection, node);
889 continue;
890 }
891 node->haveObject = PR_TRUE1;
892 }
893 switch (collection->objectType) {
894 case pkiObjectType_Certificate:
895 (void)(*callback->func.cert)((NSSCertificate *)node->object,
896 callback->arg);
897 break;
898 case pkiObjectType_CRL:
899 (void)(*callback->func.crl)((NSSCRL *)node->object,
900 callback->arg);
901 break;
902 case pkiObjectType_PrivateKey:
903 (void)(*callback->func.pvkey)((NSSPrivateKey *)node->object,
904 callback->arg);
905 break;
906 case pkiObjectType_PublicKey:
907 (void)(*callback->func.pbkey)((NSSPublicKey *)node->object,
908 callback->arg);
909 break;
910 }
911 link = PR_NEXT_LINK(link)((link)->next);
912 }
913 return PR_SUCCESS;
914}
915
916NSS_IMPLEMENT PRStatus
917nssPKIObjectCollection_AddInstanceAsObject(
918 nssPKIObjectCollection *collection,
919 nssCryptokiObject *instance)
920{
921 pkiObjectCollectionNode *node;
922 PRBool foundIt;
923 node = add_object_instance(collection, instance, &foundIt);
924 if (node == NULL((void*)0)) {
925 return PR_FAILURE;
926 }
927 if (!node->haveObject) {
928 nssPKIObject *original = node->object;
929 node->object = (*collection->createObject)(node->object);
930 if (!node->object) {
931 /*remove bogus object from list*/
932 nssPKIObject_Destroy(original);
933 nssPKIObjectCollection_RemoveNode(collection, node);
934 return PR_FAILURE;
935 }
936 node->haveObject = PR_TRUE1;
937 } else if (!foundIt) {
938 /* The instance was added to a pre-existing node. This
939 * function is *only* being used for certificates, and having
940 * multiple instances of certs in 3.X requires updating the
941 * CERTCertificate.
942 * But only do it if it was a new instance!!! If the same instance
943 * is encountered, we set *foundIt to true. Detect that here and
944 * ignore it.
945 */
946 STAN_ForceCERTCertificateUpdate((NSSCertificate *)node->object);
947 }
948 return PR_SUCCESS;
949}
950
951/*
952 * Certificate collections
953 */
954
955static void
956cert_destroyObject(nssPKIObject *o)
957{
958 NSSCertificate *c = (NSSCertificate *)o;
959 if (c->decoding) {
960 CERTCertificate *cc = STAN_GetCERTCertificate(c);
961 if (cc) {
962 CERT_DestroyCertificate(cc);
963 return;
964 } /* else destroy it as NSSCertificate below */
965 }
966 nssCertificate_Destroy(c);
967}
968
969static PRStatus
970cert_getUIDFromObject(nssPKIObject *o, NSSItem *uid)
971{
972 NSSCertificate *c = (NSSCertificate *)o;
973 /* The builtins are still returning decoded serial numbers. Until
974 * this compatibility issue is resolved, use the full DER of the
975 * cert to uniquely identify it.
976 */
977 NSSDER *derCert;
978 derCert = nssCertificate_GetEncoding(c);
979 uid[0].data = NULL((void*)0);
980 uid[0].size = 0;
981 uid[1].data = NULL((void*)0);
982 uid[1].size = 0;
983 if (derCert != NULL((void*)0)) {
984 uid[0] = *derCert;
985 }
986 return PR_SUCCESS;
987}
988
989static PRStatus
990cert_getUIDFromInstance(nssCryptokiObject *instance, NSSItem *uid,
991 NSSArena *arena)
992{
993 /* The builtins are still returning decoded serial numbers. Until
994 * this compatibility issue is resolved, use the full DER of the
995 * cert to uniquely identify it.
996 */
997 uid[1].data = NULL((void*)0);
998 uid[1].size = 0;
999 return nssCryptokiCertificate_GetAttributes(instance,
1000 NULL((void*)0), /* XXX sessionOpt */
1001 arena, /* arena */
1002 NULL((void*)0), /* type */
1003 NULL((void*)0), /* id */
1004 &uid[0], /* encoding */
1005 NULL((void*)0), /* issuer */
1006 NULL((void*)0), /* serial */
1007 NULL((void*)0)); /* subject */
1008}
1009
1010static nssPKIObject *
1011cert_createObject(nssPKIObject *o)
1012{
1013 NSSCertificate *cert = nssCertificate_Create(o);
1014 if (!cert) {
1015 return NULL((void*)0);
1016 }
1017 NSSTrustDomain *td = o->trustDomain;
1018 /* nssTrustDomain_AddCertToCache takes ownership of the reference to cert,
1019 * so first increase the refcount so it doesn't go away. */
1020 nssCertificate_AddRef(cert);
1021 NSSCertificate *certInCache = nssTrustDomain_AddCertToCache(td, cert);
1022 if (certInCache) {
1023 // This code should probably use the certificate returned from the cache,
1024 // but currently the merge tests rely on not doing so. Discard it
1025 // instead.
1026 nssCertificate_Destroy(certInCache);
1027 }
1028 return (nssPKIObject *)cert;
1029}
1030
1031NSS_IMPLEMENT nssPKIObjectCollection *
1032nssCertificateCollection_Create(
1033 NSSTrustDomain *td,
1034 NSSCertificate **certsOpt)
1035{
1036 nssPKIObjectCollection *collection;
1037 collection = nssPKIObjectCollection_Create(td, NULL((void*)0), nssPKIMonitor);
1038 if (!collection) {
1039 return NULL((void*)0);
1040 }
1041 collection->objectType = pkiObjectType_Certificate;
1042 collection->destroyObject = cert_destroyObject;
1043 collection->getUIDFromObject = cert_getUIDFromObject;
1044 collection->getUIDFromInstance = cert_getUIDFromInstance;
1045 collection->createObject = cert_createObject;
1046 if (certsOpt) {
1047 for (; *certsOpt; certsOpt++) {
1048 nssPKIObject *object = (nssPKIObject *)(*certsOpt);
1049 (void)nssPKIObjectCollection_AddObject(collection, object);
1050 }
1051 }
1052 return collection;
1053}
1054
1055NSS_IMPLEMENT NSSCertificate **
1056nssPKIObjectCollection_GetCertificates(
1057 nssPKIObjectCollection *collection,
1058 NSSCertificate **rvOpt,
1059 PRUint32 maximumOpt,
1060 NSSArena *arenaOpt)
1061{
1062 PRStatus status;
1063 PRUint32 rvSize;
1064 PRBool allocated = PR_FALSE0;
1065 if (collection->size == 0) {
1066 return (NSSCertificate **)NULL((void*)0);
1067 }
1068 if (maximumOpt == 0) {
1069 rvSize = collection->size;
1070 } else {
1071 rvSize = PR_MIN(collection->size, maximumOpt)((collection->size) < (maximumOpt) ? (collection->size
) : (maximumOpt))
;
1072 }
1073 if (!rvOpt) {
1074 rvOpt = nss_ZNEWARRAY(arenaOpt, NSSCertificate *, rvSize + 1)((NSSCertificate * *)(((PRUint64)(rvSize + 1) > 4294967295U
/ sizeof(NSSCertificate *)) ? ((void*)0) : nss_ZAlloc((arenaOpt
), (PRUint32)(sizeof(NSSCertificate *) * (PRUint64)(rvSize + 1
)))))
;
1075 if (!rvOpt) {
1076 return (NSSCertificate **)NULL((void*)0);
1077 }
1078 allocated = PR_TRUE1;
1079 }
1080 status = nssPKIObjectCollection_GetObjects(collection,
1081 (nssPKIObject **)rvOpt,
1082 rvSize);
1083 if (status != PR_SUCCESS) {
1084 if (allocated) {
1085 nss_ZFreeIf(rvOpt);
1086 }
1087 return (NSSCertificate **)NULL((void*)0);
1088 }
1089 return rvOpt;
1090}
1091
1092/*
1093 * CRL/KRL collections
1094 */
1095
1096static void
1097crl_destroyObject(nssPKIObject *o)
1098{
1099 NSSCRL *crl = (NSSCRL *)o;
1100 nssCRL_Destroy(crl);
1101}
1102
1103static PRStatus
1104crl_getUIDFromObject(nssPKIObject *o, NSSItem *uid)
1105{
1106 NSSCRL *crl = (NSSCRL *)o;
1107 NSSDER *encoding;
1108 encoding = nssCRL_GetEncoding(crl);
1109 if (!encoding) {
1110 nss_SetError(NSS_ERROR_INVALID_ARGUMENT);
1111 return PR_FALSE0;
1112 }
1113 uid[0] = *encoding;
1114 uid[1].data = NULL((void*)0);
1115 uid[1].size = 0;
1116 return PR_SUCCESS;
1117}
1118
1119static PRStatus
1120crl_getUIDFromInstance(nssCryptokiObject *instance, NSSItem *uid,
1121 NSSArena *arena)
1122{
1123 return nssCryptokiCRL_GetAttributes(instance,
1124 NULL((void*)0), /* XXX sessionOpt */
1125 arena, /* arena */
1126 &uid[0], /* encoding */
1127 NULL((void*)0), /* subject */
1128 NULL((void*)0), /* class */
1129 NULL((void*)0), /* url */
1130 NULL((void*)0)); /* isKRL */
1131}
1132
1133static nssPKIObject *
1134crl_createObject(nssPKIObject *o)
1135{
1136 return (nssPKIObject *)nssCRL_Create(o);
1137}
1138
1139NSS_IMPLEMENT nssPKIObjectCollection *
1140nssCRLCollection_Create(
1141 NSSTrustDomain *td,
1142 NSSCRL **crlsOpt)
1143{
1144 nssPKIObjectCollection *collection;
1145 collection = nssPKIObjectCollection_Create(td, NULL((void*)0), nssPKILock);
1146 if (!collection) {
1147 return NULL((void*)0);
1148 }
1149 collection->objectType = pkiObjectType_CRL;
1150 collection->destroyObject = crl_destroyObject;
1151 collection->getUIDFromObject = crl_getUIDFromObject;
1152 collection->getUIDFromInstance = crl_getUIDFromInstance;
1153 collection->createObject = crl_createObject;
1154 if (crlsOpt) {
1155 for (; *crlsOpt; crlsOpt++) {
1156 nssPKIObject *object = (nssPKIObject *)(*crlsOpt);
1157 (void)nssPKIObjectCollection_AddObject(collection, object);
1158 }
1159 }
1160 return collection;
1161}
1162
1163NSS_IMPLEMENT NSSCRL **
1164nssPKIObjectCollection_GetCRLs(
1165 nssPKIObjectCollection *collection,
1166 NSSCRL **rvOpt,
1167 PRUint32 maximumOpt,
1168 NSSArena *arenaOpt)
1169{
1170 PRStatus status;
1171 PRUint32 rvSize;
1172 PRBool allocated = PR_FALSE0;
1173 if (collection->size == 0) {
1174 return (NSSCRL **)NULL((void*)0);
1175 }
1176 if (maximumOpt == 0) {
1177 rvSize = collection->size;
1178 } else {
1179 rvSize = PR_MIN(collection->size, maximumOpt)((collection->size) < (maximumOpt) ? (collection->size
) : (maximumOpt))
;
1180 }
1181 if (!rvOpt) {
1182 rvOpt = nss_ZNEWARRAY(arenaOpt, NSSCRL *, rvSize + 1)((NSSCRL * *)(((PRUint64)(rvSize + 1) > 4294967295U / sizeof
(NSSCRL *)) ? ((void*)0) : nss_ZAlloc((arenaOpt), (PRUint32)(
sizeof(NSSCRL *) * (PRUint64)(rvSize + 1)))))
;
1183 if (!rvOpt) {
1184 return (NSSCRL **)NULL((void*)0);
1185 }
1186 allocated = PR_TRUE1;
1187 }
1188 status = nssPKIObjectCollection_GetObjects(collection,
1189 (nssPKIObject **)rvOpt,
1190 rvSize);
1191 if (status != PR_SUCCESS) {
1192 if (allocated) {
1193 nss_ZFreeIf(rvOpt);
1194 }
1195 return (NSSCRL **)NULL((void*)0);
1196 }
1197 return rvOpt;
1198}
1199
1200/* how bad would it be to have a static now sitting around, updated whenever
1201 * this was called? would avoid repeated allocs...
1202 */
1203NSS_IMPLEMENT NSSTime *
1204NSSTime_Now(NSSTime *timeOpt)
1205{
1206 return NSSTime_SetPRTime(timeOpt, PR_Now());
1207}
1208
1209NSS_IMPLEMENT NSSTime *
1210NSSTime_SetPRTime(
1211 NSSTime *timeOpt,
1212 PRTime prTime)
1213{
1214 NSSTime *rvTime;
1215 rvTime = (timeOpt) ? timeOpt : nss_ZNEW(NULL, NSSTime)((NSSTime *)nss_ZAlloc((((void*)0)), sizeof(NSSTime)));
1216 if (rvTime) {
1217 rvTime->prTime = prTime;
1218 }
1219 return rvTime;
1220}
1221
1222NSS_IMPLEMENT PRTime
1223NSSTime_GetPRTime(
1224 NSSTime *time)
1225{
1226 return time->prTime;
1227}