Bug Summary

File:root/firefox-clang/security/nss/lib/pki/pkibase.c
Warning:line 742, 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-10-17-231001-351276-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 PRInt32 refCount = PR_ATOMIC_DECREMENT(&object->refCount)__sync_sub_and_fetch(&object->refCount, 1);
136 PORT_ReleaseAssert(refCount >= 0)((refCount >= 0) ? ((void)0) : PR_Assert("refCount >= 0"
, "/root/firefox-clang/security/nss/lib/pki/pkibase.c", 136))
;
137 if (refCount == 0) {
138 for (i = 0; i < object->numInstances; i++) {
139 nssCryptokiObject_Destroy(object->instances[i]);
140 }
141 nssPKIObject_DestroyLock(object);
142 nssArena_Destroy(object->arena);
143 return PR_TRUE1;
144 }
145 return PR_FALSE0;
146}
147
148NSS_IMPLEMENT nssPKIObject *
149nssPKIObject_AddRef(
150 nssPKIObject *object)
151{
152 PRInt32 refCount = PR_ATOMIC_INCREMENT(&object->refCount)__sync_add_and_fetch(&object->refCount, 1);
153 PORT_ReleaseAssert(refCount > 1)((refCount > 1) ? ((void)0) : PR_Assert("refCount > 1",
"/root/firefox-clang/security/nss/lib/pki/pkibase.c", 153))
;
154 return object;
155}
156
157NSS_IMPLEMENT PRStatus
158nssPKIObject_AddInstance(
159 nssPKIObject *object,
160 nssCryptokiObject *instance)
161{
162 nssCryptokiObject **newInstances = NULL((void*)0);
163
164 nssPKIObject_Lock(object);
165 if (object->numInstances == 0) {
166 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)))))
167 nssCryptokiObject *,((nssCryptokiObject * *)(((PRUint64)(object->numInstances +
1) > 4294967295U / sizeof(nssCryptokiObject *)) ? ((void*
)0) : nss_ZAlloc((object->arena), (PRUint32)(sizeof(nssCryptokiObject
*) * (PRUint64)(object->numInstances + 1)))))
168 object->numInstances + 1)((nssCryptokiObject * *)(((PRUint64)(object->numInstances +
1) > 4294967295U / sizeof(nssCryptokiObject *)) ? ((void*
)0) : nss_ZAlloc((object->arena), (PRUint32)(sizeof(nssCryptokiObject
*) * (PRUint64)(object->numInstances + 1)))))
;
169 } else {
170 PRBool found = PR_FALSE0;
171 PRUint32 i;
172 for (i = 0; i < object->numInstances; i++) {
173 if (nssCryptokiObject_Equal(object->instances[i], instance)) {
174 found = PR_TRUE1;
175 break;
176 }
177 }
178 if (found) {
179 /* The new instance is identical to one in the array, except
180 * perhaps that the label may be different. So replace
181 * the label in the array instance with the label from the
182 * new instance, and discard the new instance.
183 */
184 nss_ZFreeIf(object->instances[i]->label);
185 object->instances[i]->label = instance->label;
186 nssPKIObject_Unlock(object);
187 instance->label = NULL((void*)0);
188 nssCryptokiObject_Destroy(instance);
189 return PR_SUCCESS;
190 }
191 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
)))))
192 nssCryptokiObject *,((nssCryptokiObject * *)(((PRUint64)(object->numInstances +
1) > 4294967295U / sizeof(nssCryptokiObject *)) ? ((void*
)0) : nss_ZRealloc((object->instances), (PRUint32)(sizeof(
nssCryptokiObject *) * (PRUint64)(object->numInstances + 1
)))))
193 object->numInstances + 1)((nssCryptokiObject * *)(((PRUint64)(object->numInstances +
1) > 4294967295U / sizeof(nssCryptokiObject *)) ? ((void*
)0) : nss_ZRealloc((object->instances), (PRUint32)(sizeof(
nssCryptokiObject *) * (PRUint64)(object->numInstances + 1
)))))
;
194 }
195 if (newInstances) {
196 object->instances = newInstances;
197 newInstances[object->numInstances++] = instance;
198 }
199 nssPKIObject_Unlock(object);
200 return (newInstances ? PR_SUCCESS : PR_FAILURE);
201}
202
203NSS_IMPLEMENT PRBool
204nssPKIObject_HasInstance(
205 nssPKIObject *object,
206 nssCryptokiObject *instance)
207{
208 PRUint32 i;
209 PRBool hasIt = PR_FALSE0;
210 ;
211 nssPKIObject_Lock(object);
212 for (i = 0; i < object->numInstances; i++) {
213 if (nssCryptokiObject_Equal(object->instances[i], instance)) {
214 hasIt = PR_TRUE1;
215 break;
216 }
217 }
218 nssPKIObject_Unlock(object);
219 return hasIt;
220}
221
222NSS_IMPLEMENT PRStatus
223nssPKIObject_RemoveInstanceForToken(
224 nssPKIObject *object,
225 NSSToken *token)
226{
227 PRUint32 i;
228 nssCryptokiObject *instanceToRemove = NULL((void*)0);
229 nssPKIObject_Lock(object);
230 if (object->numInstances == 0) {
231 nssPKIObject_Unlock(object);
232 return PR_SUCCESS;
233 }
234 for (i = 0; i < object->numInstances; i++) {
235 if (object->instances[i]->token == token) {
236 instanceToRemove = object->instances[i];
237 object->instances[i] = object->instances[object->numInstances - 1];
238 object->instances[object->numInstances - 1] = NULL((void*)0);
239 break;
240 }
241 }
242 if (--object->numInstances > 0) {
243 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)))))
244 nssCryptokiObject *,((nssCryptokiObject * *)(((PRUint64)(object->numInstances)
> 4294967295U / sizeof(nssCryptokiObject *)) ? ((void*)0)
: nss_ZRealloc((object->instances), (PRUint32)(sizeof(nssCryptokiObject
*) * (PRUint64)(object->numInstances)))))
245 object->numInstances)((nssCryptokiObject * *)(((PRUint64)(object->numInstances)
> 4294967295U / sizeof(nssCryptokiObject *)) ? ((void*)0)
: nss_ZRealloc((object->instances), (PRUint32)(sizeof(nssCryptokiObject
*) * (PRUint64)(object->numInstances)))))
;
246 if (instances) {
247 object->instances = instances;
248 }
249 } else {
250 nss_ZFreeIf(object->instances);
251 }
252 nssCryptokiObject_Destroy(instanceToRemove);
253 nssPKIObject_Unlock(object);
254 return PR_SUCCESS;
255}
256
257/* this needs more thought on what will happen when there are multiple
258 * instances
259 */
260NSS_IMPLEMENT PRStatus
261nssPKIObject_DeleteStoredObject(
262 nssPKIObject *object,
263 NSSCallback *uhh,
264 PRBool isFriendly)
265{
266 PRUint32 i, numNotDestroyed;
267 PRStatus status = PR_SUCCESS;
268 numNotDestroyed = 0;
269 nssPKIObject_Lock(object);
270 for (i = 0; i < object->numInstances; i++) {
271 nssCryptokiObject *instance = object->instances[i];
272 status = nssToken_DeleteStoredObject(instance);
273 object->instances[i] = NULL((void*)0);
274 if (status == PR_SUCCESS) {
275 nssCryptokiObject_Destroy(instance);
276 } else {
277 object->instances[numNotDestroyed++] = instance;
278 }
279 }
280 if (numNotDestroyed == 0) {
281 nss_ZFreeIf(object->instances);
282 object->numInstances = 0;
283 } else {
284 object->numInstances = numNotDestroyed;
285 }
286 nssPKIObject_Unlock(object);
287 return status;
288}
289
290NSS_IMPLEMENT NSSToken **
291nssPKIObject_GetTokens(
292 nssPKIObject *object,
293 PRStatus *statusOpt)
294{
295 NSSToken **tokens = NULL((void*)0);
296 nssPKIObject_Lock(object);
297 if (object->numInstances > 0) {
298 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)))))
;
299 if (tokens) {
300 PRUint32 i;
301 for (i = 0; i < object->numInstances; i++) {
302 tokens[i] = nssToken_AddRef(object->instances[i]->token);
303 }
304 }
305 }
306 nssPKIObject_Unlock(object);
307 if (statusOpt)
308 *statusOpt = PR_SUCCESS; /* until more logic here */
309 return tokens;
310}
311
312NSS_IMPLEMENT NSSUTF8 *
313nssPKIObject_GetNicknameForToken(
314 nssPKIObject *object,
315 NSSToken *tokenOpt)
316{
317 PRUint32 i;
318 NSSUTF8 *nickname = NULL((void*)0);
319 nssPKIObject_Lock(object);
320 for (i = 0; i < object->numInstances; i++) {
321 if ((!tokenOpt && object->instances[i]->label) ||
322 (object->instances[i]->token == tokenOpt)) {
323 /* Must copy, see bug 745548 */
324 nickname = nssUTF8_Duplicate(object->instances[i]->label, NULL((void*)0));
325 break;
326 }
327 }
328 nssPKIObject_Unlock(object);
329 return nickname;
330}
331
332NSS_IMPLEMENT nssCryptokiObject **
333nssPKIObject_GetInstances(
334 nssPKIObject *object)
335{
336 nssCryptokiObject **instances = NULL((void*)0);
337 PRUint32 i;
338
339 nssPKIObject_Lock(object);
340 if (object->numInstances == 0) {
341 nssPKIObject_Unlock(object);
342 return (nssCryptokiObject **)NULL((void*)0);
343 }
344 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)))))
345 object->numInstances + 1)((nssCryptokiObject * *)(((PRUint64)(object->numInstances +
1) > 4294967295U / sizeof(nssCryptokiObject *)) ? ((void*
)0) : nss_ZAlloc((((void*)0)), (PRUint32)(sizeof(nssCryptokiObject
*) * (PRUint64)(object->numInstances + 1)))))
;
346 if (instances) {
347 for (i = 0; i < object->numInstances; i++) {
348 instances[i] = nssCryptokiObject_Clone(object->instances[i]);
349 }
350 }
351 nssPKIObject_Unlock(object);
352 return instances;
353}
354
355NSS_IMPLEMENT void
356nssCertificateArray_Destroy(
357 NSSCertificate **certs)
358{
359 if (certs) {
360 NSSCertificate **certp;
361 for (certp = certs; *certp; certp++) {
362 if ((*certp)->decoding) {
363 CERTCertificate *cc = STAN_GetCERTCertificate(*certp);
364 if (cc) {
365 CERT_DestroyCertificate(cc);
366 }
367 continue;
368 }
369 nssCertificate_Destroy(*certp);
370 }
371 nss_ZFreeIf(certs);
372 }
373}
374
375NSS_IMPLEMENT NSSCertificate **
376nssCertificateArray_Join(
377 NSSCertificate **certs1,
378 NSSCertificate **certs2)
379{
380 if (certs1 && certs2) {
381 NSSCertificate **certs, **cp;
382 PRUint32 count = 0;
383 PRUint32 count1 = 0;
384 cp = certs1;
385 while (*cp++)
386 count1++;
387 count = count1;
388 cp = certs2;
389 while (*cp++)
390 count++;
391 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
)))))
;
392 if (!certs) {
393 nss_ZFreeIf(certs1);
394 nss_ZFreeIf(certs2);
395 return (NSSCertificate **)NULL((void*)0);
396 }
397 for (cp = certs2; *cp; cp++, count1++) {
398 certs[count1] = *cp;
399 }
400 nss_ZFreeIf(certs2);
401 return certs;
402 } else if (certs1) {
403 return certs1;
404 } else {
405 return certs2;
406 }
407}
408
409NSS_IMPLEMENT NSSCertificate *
410nssCertificateArray_FindBestCertificate(
411 NSSCertificate **certs,
412 NSSTime *timeOpt,
413 const NSSUsage *usage,
414 NSSPolicies *policiesOpt)
415{
416 NSSCertificate *bestCert = NULL((void*)0);
417 nssDecodedCert *bestdc = NULL((void*)0);
418 NSSTime *time, sTime;
419 PRBool bestCertMatches = PR_FALSE0;
420 PRBool thisCertMatches;
421 PRBool bestCertIsValidAtTime = PR_FALSE0;
422 PRBool bestCertIsTrusted = PR_FALSE0;
423
424 if (timeOpt) {
425 time = timeOpt;
426 } else {
427 NSSTime_Now(&sTime);
428 time = &sTime;
429 }
430 if (!certs) {
431 return (NSSCertificate *)NULL((void*)0);
432 }
433 for (; *certs; certs++) {
434 nssDecodedCert *dc;
435 NSSCertificate *c = *certs;
436 dc = nssCertificate_GetDecoding(c);
437 if (!dc)
438 continue;
439 thisCertMatches = dc->matchUsage(dc, usage);
440 if (!bestCert) {
441 /* always take the first cert, but remember whether or not
442 * the usage matched
443 */
444 bestCert = nssCertificate_AddRef(c);
445 bestCertMatches = thisCertMatches;
446 bestdc = dc;
447 continue;
448 } else {
449 if (bestCertMatches && !thisCertMatches) {
450 /* if already have a cert for this usage, and if this cert
451 * doesn't have the correct usage, continue
452 */
453 continue;
454 } else if (!bestCertMatches && thisCertMatches) {
455 /* this one does match usage, replace the other */
456 nssCertificate_Destroy(bestCert);
457 bestCert = nssCertificate_AddRef(c);
458 bestCertMatches = thisCertMatches;
459 bestdc = dc;
460 continue;
461 }
462 /* this cert match as well as any cert we've found so far,
463 * defer to time/policies
464 * */
465 }
466 /* time */
467 if (bestCertIsValidAtTime || bestdc->isValidAtTime(bestdc, time)) {
468 /* The current best cert is valid at time */
469 bestCertIsValidAtTime = PR_TRUE1;
470 if (!dc->isValidAtTime(dc, time)) {
471 /* If the new cert isn't valid at time, it's not better */
472 continue;
473 }
474 } else {
475 /* The current best cert is not valid at time */
476 if (dc->isValidAtTime(dc, time)) {
477 /* If the new cert is valid at time, it's better */
478 nssCertificate_Destroy(bestCert);
479 bestCert = nssCertificate_AddRef(c);
480 bestdc = dc;
481 bestCertIsValidAtTime = PR_TRUE1;
482 continue;
483 }
484 }
485 /* Either they are both valid at time, or neither valid.
486 * If only one is trusted for this usage, take it.
487 */
488 if (bestCertIsTrusted || bestdc->isTrustedForUsage(bestdc, usage)) {
489 bestCertIsTrusted = PR_TRUE1;
490 if (!dc->isTrustedForUsage(dc, usage)) {
491 continue;
492 }
493 } else {
494 /* The current best cert is not trusted */
495 if (dc->isTrustedForUsage(dc, usage)) {
496 /* If the new cert is trusted, it's better */
497 nssCertificate_Destroy(bestCert);
498 bestCert = nssCertificate_AddRef(c);
499 bestdc = dc;
500 bestCertIsTrusted = PR_TRUE1;
501 continue;
502 }
503 }
504 /* Otherwise, take the newer one. */
505 if (!bestdc->isNewerThan(bestdc, dc)) {
506 nssCertificate_Destroy(bestCert);
507 bestCert = nssCertificate_AddRef(c);
508 bestdc = dc;
509 continue;
510 }
511 /* policies */
512 /* XXX later -- defer to policies */
513 }
514 return bestCert;
515}
516
517NSS_IMPLEMENT void
518nssCRLArray_Destroy(
519 NSSCRL **crls)
520{
521 if (crls) {
522 NSSCRL **crlp;
523 for (crlp = crls; *crlp; crlp++) {
524 nssCRL_Destroy(*crlp);
525 }
526 nss_ZFreeIf(crls);
527 }
528}
529
530/*
531 * Object collections
532 */
533
534typedef enum {
535 pkiObjectType_Certificate = 0,
536 pkiObjectType_CRL = 1,
537} pkiObjectType;
538
539/* Each object is defined by a set of items that uniquely identify it.
540 * Here are the uid sets:
541 *
542 * NSSCertificate ==> { issuer, serial }
543 */
544#define MAX_ITEMS_FOR_UID2 2
545
546/* pkiObjectCollectionNode
547 *
548 * A node in the collection is the set of unique identifiers for a single
549 * object, along with either the actual object or a proto-object.
550 */
551typedef struct
552{
553 PRCList link;
554 PRBool haveObject;
555 nssPKIObject *object;
556 NSSItem uid[MAX_ITEMS_FOR_UID2];
557} pkiObjectCollectionNode;
558
559/* nssPKIObjectCollection
560 *
561 * The collection is the set of all objects, plus the interfaces needed
562 * to manage the objects.
563 *
564 */
565struct nssPKIObjectCollectionStr {
566 NSSArena *arena;
567 NSSTrustDomain *td;
568 NSSCryptoContext *cc;
569 PRCList head; /* list of pkiObjectCollectionNode's */
570 PRUint32 size;
571 pkiObjectType objectType;
572 void (*destroyObject)(nssPKIObject *o);
573 PRStatus (*getUIDFromObject)(nssPKIObject *o, NSSItem *uid);
574 PRStatus (*getUIDFromInstance)(nssCryptokiObject *co, NSSItem *uid,
575 NSSArena *arena);
576 nssPKIObject *(*createObject)(nssPKIObject *o);
577 nssPKILockType lockType; /* type of lock to use for new proto-objects */
578};
579
580static nssPKIObjectCollection *
581nssPKIObjectCollection_Create(
582 NSSTrustDomain *td,
583 NSSCryptoContext *ccOpt,
584 nssPKILockType lockType)
585{
586 NSSArena *arena;
587 nssPKIObjectCollection *rvCollection = NULL((void*)0);
588 arena = nssArena_Create();
589 if (!arena) {
590 return (nssPKIObjectCollection *)NULL((void*)0);
591 }
592 rvCollection = nss_ZNEW(arena, nssPKIObjectCollection)((nssPKIObjectCollection *)nss_ZAlloc((arena), sizeof(nssPKIObjectCollection
)))
;
593 if (!rvCollection) {
594 goto loser;
595 }
596 PR_INIT_CLIST(&rvCollection->head)do {(&rvCollection->head)->next = (&rvCollection
->head); (&rvCollection->head)->prev = (&rvCollection
->head); } while (0)
;
597 rvCollection->arena = arena;
598 rvCollection->td = td; /* XXX */
599 rvCollection->cc = ccOpt;
600 rvCollection->lockType = lockType;
601 return rvCollection;
602loser:
603 nssArena_Destroy(arena);
604 return (nssPKIObjectCollection *)NULL((void*)0);
605}
606
607NSS_IMPLEMENT void
608nssPKIObjectCollection_Destroy(
609 nssPKIObjectCollection *collection)
610{
611 if (collection) {
612 PRCList *link;
613 pkiObjectCollectionNode *node;
614 /* first destroy any objects in the collection */
615 link = PR_NEXT_LINK(&collection->head)((&collection->head)->next);
616 while (link != &collection->head) {
617 node = (pkiObjectCollectionNode *)link;
618 if (node->haveObject) {
619 (*collection->destroyObject)(node->object);
620 } else {
621 nssPKIObject_Destroy(node->object);
622 }
623 link = PR_NEXT_LINK(link)((link)->next);
624 }
625 /* then destroy it */
626 nssArena_Destroy(collection->arena);
627 }
628}
629
630NSS_IMPLEMENT PRUint32
631nssPKIObjectCollection_Count(
632 nssPKIObjectCollection *collection)
633{
634 return collection->size;
635}
636
637NSS_IMPLEMENT PRStatus
638nssPKIObjectCollection_AddObject(
639 nssPKIObjectCollection *collection,
640 nssPKIObject *object)
641{
642 pkiObjectCollectionNode *node;
643 node = nss_ZNEW(collection->arena, pkiObjectCollectionNode)((pkiObjectCollectionNode *)nss_ZAlloc((collection->arena)
, sizeof(pkiObjectCollectionNode)))
;
644 if (!node) {
645 return PR_FAILURE;
646 }
647 node->haveObject = PR_TRUE1;
648 node->object = nssPKIObject_AddRef(object);
649 (*collection->getUIDFromObject)(object, node->uid);
650 PR_INIT_CLIST(&node->link)do {(&node->link)->next = (&node->link); (&
node->link)->prev = (&node->link); } while (0)
;
651 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)
;
652 collection->size++;
653 return PR_SUCCESS;
654}
655
656static pkiObjectCollectionNode *
657find_instance_in_collection(
658 nssPKIObjectCollection *collection,
659 nssCryptokiObject *instance)
660{
661 PRCList *link;
662 pkiObjectCollectionNode *node;
663 link = PR_NEXT_LINK(&collection->head)((&collection->head)->next);
664 while (link != &collection->head) {
665 node = (pkiObjectCollectionNode *)link;
666 if (nssPKIObject_HasInstance(node->object, instance)) {
667 return node;
668 }
669 link = PR_NEXT_LINK(link)((link)->next);
670 }
671 return (pkiObjectCollectionNode *)NULL((void*)0);
672}
673
674static pkiObjectCollectionNode *
675find_object_in_collection(
676 nssPKIObjectCollection *collection,
677 NSSItem *uid)
678{
679 PRUint32 i;
680 PRStatus status;
681 PRCList *link;
682 pkiObjectCollectionNode *node;
683 link = PR_NEXT_LINK(&collection->head)((&collection->head)->next);
684 while (link != &collection->head) {
685 node = (pkiObjectCollectionNode *)link;
686 for (i = 0; i < MAX_ITEMS_FOR_UID2; i++) {
687 if (!nssItem_Equal(&node->uid[i], &uid[i], &status)) {
688 break;
689 }
690 }
691 if (i == MAX_ITEMS_FOR_UID2) {
692 return node;
693 }
694 link = PR_NEXT_LINK(link)((link)->next);
695 }
696 return (pkiObjectCollectionNode *)NULL((void*)0);
697}
698
699static pkiObjectCollectionNode *
700add_object_instance(
701 nssPKIObjectCollection *collection,
702 nssCryptokiObject *instance,
703 PRBool *foundIt)
704{
705 PRUint32 i;
706 PRStatus status;
707 pkiObjectCollectionNode *node;
708 nssArenaMark *mark = NULL((void*)0);
709 NSSItem uid[MAX_ITEMS_FOR_UID2];
710 nsslibc_memset(uid, 0, sizeof uid);
711 /* The list is traversed twice, first (here) looking to match the
712 * { token, handle } tuple, and if that is not found, below a search
713 * for unique identifier is done. Here, a match means this exact object
714 * instance is already in the collection, and we have nothing to do.
715 */
716 *foundIt = PR_FALSE0;
717 node = find_instance_in_collection(collection, instance);
718 if (node) {
719 /* The collection is assumed to take over the instance. Since we
720 * are not using it, it must be destroyed.
721 */
722 nssCryptokiObject_Destroy(instance);
723 *foundIt = PR_TRUE1;
724 return node;
725 }
726 mark = nssArena_Mark(collection->arena);
727 if (!mark) {
728 goto loser;
729 }
730 status = (*collection->getUIDFromInstance)(instance, uid,
731 collection->arena);
732 if (status != PR_SUCCESS) {
733 goto loser;
734 }
735 /* Search for unique identifier. A match here means the object exists
736 * in the collection, but does not have this instance, so the instance
737 * needs to be added.
738 */
739 node = find_object_in_collection(collection, uid);
740 if (node) {
741 /* This is an object with multiple instances */
742 status = nssPKIObject_AddInstance(node->object, instance);
Value stored to 'status' is never read
743 } else {
744 /* This is a completely new object. Create a node for it. */
745 node = nss_ZNEW(collection->arena, pkiObjectCollectionNode)((pkiObjectCollectionNode *)nss_ZAlloc((collection->arena)
, sizeof(pkiObjectCollectionNode)))
;
746 if (!node) {
747 goto loser;
748 }
749 node->object = nssPKIObject_Create(NULL((void*)0), instance,
750 collection->td, collection->cc,
751 collection->lockType);
752 if (!node->object) {
753 goto loser;
754 }
755 for (i = 0; i < MAX_ITEMS_FOR_UID2; i++) {
756 node->uid[i] = uid[i];
757 }
758 node->haveObject = PR_FALSE0;
759 PR_INIT_CLIST(&node->link)do {(&node->link)->next = (&node->link); (&
node->link)->prev = (&node->link); } while (0)
;
760 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)
;
761 collection->size++;
762 status = PR_SUCCESS;
763 }
764 nssArena_Unmark(collection->arena, mark);
765 return node;
766loser:
767 if (mark) {
768 nssArena_Release(collection->arena, mark);
769 }
770 nssCryptokiObject_Destroy(instance);
771 return (pkiObjectCollectionNode *)NULL((void*)0);
772}
773
774NSS_IMPLEMENT PRStatus
775nssPKIObjectCollection_AddInstances(
776 nssPKIObjectCollection *collection,
777 nssCryptokiObject **instances,
778 PRUint32 numInstances)
779{
780 PRStatus status = PR_SUCCESS;
781 PRUint32 i = 0;
782 PRBool foundIt;
783 pkiObjectCollectionNode *node;
784 if (instances) {
785 while ((!numInstances || i < numInstances) && *instances) {
786 if (status == PR_SUCCESS) {
787 node = add_object_instance(collection, *instances, &foundIt);
788 if (node == NULL((void*)0)) {
789 /* add_object_instance freed the current instance */
790 /* free the remaining instances */
791 status = PR_FAILURE;
792 }
793 } else {
794 nssCryptokiObject_Destroy(*instances);
795 }
796 instances++;
797 i++;
798 }
799 }
800 return status;
801}
802
803static void
804nssPKIObjectCollection_RemoveNode(
805 nssPKIObjectCollection *collection,
806 pkiObjectCollectionNode *node)
807{
808 PR_REMOVE_LINK(&node->link)do {(&node->link)->prev->next = (&node->link
)->next; (&node->link)->next->prev = (&node
->link)->prev; } while (0)
;
809 collection->size--;
810}
811
812static PRStatus
813nssPKIObjectCollection_GetObjects(
814 nssPKIObjectCollection *collection,
815 nssPKIObject **rvObjects,
816 PRUint32 rvSize)
817{
818 PRUint32 i = 0;
819 PRCList *link = PR_NEXT_LINK(&collection->head)((&collection->head)->next);
820 pkiObjectCollectionNode *node;
821 int error = 0;
822 while ((i < rvSize) && (link != &collection->head)) {
823 node = (pkiObjectCollectionNode *)link;
824 if (!node->haveObject) {
825 /* Convert the proto-object to an object */
826 node->object = (*collection->createObject)(node->object);
827 if (!node->object) {
828 link = PR_NEXT_LINK(link)((link)->next);
829 /*remove bogus object from list*/
830 nssPKIObjectCollection_RemoveNode(collection, node);
831 error++;
832 continue;
833 }
834 node->haveObject = PR_TRUE1;
835 }
836 rvObjects[i++] = nssPKIObject_AddRef(node->object);
837 link = PR_NEXT_LINK(link)((link)->next);
838 }
839 if (!error && *rvObjects == NULL((void*)0)) {
840 nss_SetError(NSS_ERROR_NOT_FOUND);
841 }
842 return PR_SUCCESS;
843}
844
845NSS_IMPLEMENT PRStatus
846nssPKIObjectCollection_Traverse(
847 nssPKIObjectCollection *collection,
848 nssPKIObjectCallback *callback)
849{
850 PRCList *link = PR_NEXT_LINK(&collection->head)((&collection->head)->next);
851 pkiObjectCollectionNode *node;
852 while (link != &collection->head) {
853 node = (pkiObjectCollectionNode *)link;
854 if (!node->haveObject) {
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 continue;
861 }
862 node->haveObject = PR_TRUE1;
863 }
864 switch (collection->objectType) {
865 case pkiObjectType_Certificate:
866 (void)(*callback->func.cert)((NSSCertificate *)node->object,
867 callback->arg);
868 break;
869 case pkiObjectType_CRL:
870 (void)(*callback->func.crl)((NSSCRL *)node->object,
871 callback->arg);
872 break;
873 }
874 link = PR_NEXT_LINK(link)((link)->next);
875 }
876 return PR_SUCCESS;
877}
878
879NSS_IMPLEMENT PRStatus
880nssPKIObjectCollection_AddInstanceAsObject(
881 nssPKIObjectCollection *collection,
882 nssCryptokiObject *instance)
883{
884 pkiObjectCollectionNode *node;
885 PRBool foundIt;
886 node = add_object_instance(collection, instance, &foundIt);
887 if (node == NULL((void*)0)) {
888 return PR_FAILURE;
889 }
890 if (!node->haveObject) {
891 nssPKIObject *original = node->object;
892 node->object = (*collection->createObject)(node->object);
893 if (!node->object) {
894 /*remove bogus object from list*/
895 nssPKIObject_Destroy(original);
896 nssPKIObjectCollection_RemoveNode(collection, node);
897 return PR_FAILURE;
898 }
899 node->haveObject = PR_TRUE1;
900 } else if (!foundIt) {
901 /* The instance was added to a pre-existing node. This
902 * function is *only* being used for certificates, and having
903 * multiple instances of certs in 3.X requires updating the
904 * CERTCertificate.
905 * But only do it if it was a new instance!!! If the same instance
906 * is encountered, we set *foundIt to true. Detect that here and
907 * ignore it.
908 */
909 STAN_ForceCERTCertificateUpdate((NSSCertificate *)node->object);
910 }
911 return PR_SUCCESS;
912}
913
914/*
915 * Certificate collections
916 */
917
918static void
919cert_destroyObject(nssPKIObject *o)
920{
921 NSSCertificate *c = (NSSCertificate *)o;
922 if (c->decoding) {
923 CERTCertificate *cc = STAN_GetCERTCertificate(c);
924 if (cc) {
925 CERT_DestroyCertificate(cc);
926 return;
927 } /* else destroy it as NSSCertificate below */
928 }
929 nssCertificate_Destroy(c);
930}
931
932static PRStatus
933cert_getUIDFromObject(nssPKIObject *o, NSSItem *uid)
934{
935 NSSCertificate *c = (NSSCertificate *)o;
936 /* The builtins are still returning decoded serial numbers. Until
937 * this compatibility issue is resolved, use the full DER of the
938 * cert to uniquely identify it.
939 */
940 NSSDER *derCert;
941 derCert = nssCertificate_GetEncoding(c);
942 uid[0].data = NULL((void*)0);
943 uid[0].size = 0;
944 uid[1].data = NULL((void*)0);
945 uid[1].size = 0;
946 if (derCert != NULL((void*)0)) {
947 uid[0] = *derCert;
948 }
949 return PR_SUCCESS;
950}
951
952static PRStatus
953cert_getUIDFromInstance(nssCryptokiObject *instance, NSSItem *uid,
954 NSSArena *arena)
955{
956 /* The builtins are still returning decoded serial numbers. Until
957 * this compatibility issue is resolved, use the full DER of the
958 * cert to uniquely identify it.
959 */
960 uid[1].data = NULL((void*)0);
961 uid[1].size = 0;
962 return nssCryptokiCertificate_GetAttributes(instance,
963 NULL((void*)0), /* XXX sessionOpt */
964 arena, /* arena */
965 NULL((void*)0), /* type */
966 NULL((void*)0), /* id */
967 &uid[0], /* encoding */
968 NULL((void*)0), /* issuer */
969 NULL((void*)0), /* serial */
970 NULL((void*)0)); /* subject */
971}
972
973static nssPKIObject *
974cert_createObject(nssPKIObject *o)
975{
976 NSSCertificate *cert = nssCertificate_Create(o);
977 if (!cert) {
978 return NULL((void*)0);
979 }
980 NSSTrustDomain *td = o->trustDomain;
981 /* nssTrustDomain_AddCertToCache takes ownership of the reference to cert,
982 * so first increase the refcount so it doesn't go away. */
983 nssCertificate_AddRef(cert);
984 NSSCertificate *certInCache = nssTrustDomain_AddCertToCache(td, cert);
985 if (certInCache) {
986 // This code should probably use the certificate returned from the cache,
987 // but currently the merge tests rely on not doing so. Discard it
988 // instead.
989 nssCertificate_Destroy(certInCache);
990 }
991 return (nssPKIObject *)cert;
992}
993
994NSS_IMPLEMENT nssPKIObjectCollection *
995nssCertificateCollection_Create(
996 NSSTrustDomain *td,
997 NSSCertificate **certsOpt)
998{
999 nssPKIObjectCollection *collection;
1000 collection = nssPKIObjectCollection_Create(td, NULL((void*)0), nssPKIMonitor);
1001 if (!collection) {
1002 return NULL((void*)0);
1003 }
1004 collection->objectType = pkiObjectType_Certificate;
1005 collection->destroyObject = cert_destroyObject;
1006 collection->getUIDFromObject = cert_getUIDFromObject;
1007 collection->getUIDFromInstance = cert_getUIDFromInstance;
1008 collection->createObject = cert_createObject;
1009 if (certsOpt) {
1010 for (; *certsOpt; certsOpt++) {
1011 nssPKIObject *object = (nssPKIObject *)(*certsOpt);
1012 (void)nssPKIObjectCollection_AddObject(collection, object);
1013 }
1014 }
1015 return collection;
1016}
1017
1018NSS_IMPLEMENT NSSCertificate **
1019nssPKIObjectCollection_GetCertificates(
1020 nssPKIObjectCollection *collection,
1021 NSSCertificate **rvOpt,
1022 PRUint32 maximumOpt,
1023 NSSArena *arenaOpt)
1024{
1025 PRStatus status;
1026 PRUint32 rvSize;
1027 PRBool allocated = PR_FALSE0;
1028 if (collection->size == 0) {
1029 return (NSSCertificate **)NULL((void*)0);
1030 }
1031 if (maximumOpt == 0) {
1032 rvSize = collection->size;
1033 } else {
1034 rvSize = PR_MIN(collection->size, maximumOpt)((collection->size) < (maximumOpt) ? (collection->size
) : (maximumOpt))
;
1035 }
1036 if (!rvOpt) {
1037 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
)))))
;
1038 if (!rvOpt) {
1039 return (NSSCertificate **)NULL((void*)0);
1040 }
1041 allocated = PR_TRUE1;
1042 }
1043 status = nssPKIObjectCollection_GetObjects(collection,
1044 (nssPKIObject **)rvOpt,
1045 rvSize);
1046 if (status != PR_SUCCESS) {
1047 if (allocated) {
1048 nss_ZFreeIf(rvOpt);
1049 }
1050 return (NSSCertificate **)NULL((void*)0);
1051 }
1052 return rvOpt;
1053}
1054
1055/*
1056 * CRL/KRL collections
1057 */
1058
1059static void
1060crl_destroyObject(nssPKIObject *o)
1061{
1062 NSSCRL *crl = (NSSCRL *)o;
1063 nssCRL_Destroy(crl);
1064}
1065
1066static PRStatus
1067crl_getUIDFromObject(nssPKIObject *o, NSSItem *uid)
1068{
1069 NSSCRL *crl = (NSSCRL *)o;
1070 NSSDER *encoding;
1071 encoding = nssCRL_GetEncoding(crl);
1072 if (!encoding) {
1073 nss_SetError(NSS_ERROR_INVALID_ARGUMENT);
1074 return PR_FALSE0;
1075 }
1076 uid[0] = *encoding;
1077 uid[1].data = NULL((void*)0);
1078 uid[1].size = 0;
1079 return PR_SUCCESS;
1080}
1081
1082static PRStatus
1083crl_getUIDFromInstance(nssCryptokiObject *instance, NSSItem *uid,
1084 NSSArena *arena)
1085{
1086 return nssCryptokiCRL_GetAttributes(instance,
1087 NULL((void*)0), /* XXX sessionOpt */
1088 arena, /* arena */
1089 &uid[0], /* encoding */
1090 NULL((void*)0), /* subject */
1091 NULL((void*)0), /* class */
1092 NULL((void*)0), /* url */
1093 NULL((void*)0)); /* isKRL */
1094}
1095
1096static nssPKIObject *
1097crl_createObject(nssPKIObject *o)
1098{
1099 return (nssPKIObject *)nssCRL_Create(o);
1100}
1101
1102NSS_IMPLEMENT nssPKIObjectCollection *
1103nssCRLCollection_Create(
1104 NSSTrustDomain *td,
1105 NSSCRL **crlsOpt)
1106{
1107 nssPKIObjectCollection *collection;
1108 collection = nssPKIObjectCollection_Create(td, NULL((void*)0), nssPKILock);
1109 if (!collection) {
1110 return NULL((void*)0);
1111 }
1112 collection->objectType = pkiObjectType_CRL;
1113 collection->destroyObject = crl_destroyObject;
1114 collection->getUIDFromObject = crl_getUIDFromObject;
1115 collection->getUIDFromInstance = crl_getUIDFromInstance;
1116 collection->createObject = crl_createObject;
1117 if (crlsOpt) {
1118 for (; *crlsOpt; crlsOpt++) {
1119 nssPKIObject *object = (nssPKIObject *)(*crlsOpt);
1120 (void)nssPKIObjectCollection_AddObject(collection, object);
1121 }
1122 }
1123 return collection;
1124}
1125
1126NSS_IMPLEMENT NSSCRL **
1127nssPKIObjectCollection_GetCRLs(
1128 nssPKIObjectCollection *collection,
1129 NSSCRL **rvOpt,
1130 PRUint32 maximumOpt,
1131 NSSArena *arenaOpt)
1132{
1133 PRStatus status;
1134 PRUint32 rvSize;
1135 PRBool allocated = PR_FALSE0;
1136 if (collection->size == 0) {
1137 return (NSSCRL **)NULL((void*)0);
1138 }
1139 if (maximumOpt == 0) {
1140 rvSize = collection->size;
1141 } else {
1142 rvSize = PR_MIN(collection->size, maximumOpt)((collection->size) < (maximumOpt) ? (collection->size
) : (maximumOpt))
;
1143 }
1144 if (!rvOpt) {
1145 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)))))
;
1146 if (!rvOpt) {
1147 return (NSSCRL **)NULL((void*)0);
1148 }
1149 allocated = PR_TRUE1;
1150 }
1151 status = nssPKIObjectCollection_GetObjects(collection,
1152 (nssPKIObject **)rvOpt,
1153 rvSize);
1154 if (status != PR_SUCCESS) {
1155 if (allocated) {
1156 nss_ZFreeIf(rvOpt);
1157 }
1158 return (NSSCRL **)NULL((void*)0);
1159 }
1160 return rvOpt;
1161}
1162
1163/* how bad would it be to have a static now sitting around, updated whenever
1164 * this was called? would avoid repeated allocs...
1165 */
1166NSS_IMPLEMENT NSSTime *
1167NSSTime_Now(NSSTime *timeOpt)
1168{
1169 return NSSTime_SetPRTime(timeOpt, PR_Now());
1170}
1171
1172NSS_IMPLEMENT NSSTime *
1173NSSTime_SetPRTime(
1174 NSSTime *timeOpt,
1175 PRTime prTime)
1176{
1177 NSSTime *rvTime;
1178 rvTime = (timeOpt) ? timeOpt : nss_ZNEW(NULL, NSSTime)((NSSTime *)nss_ZAlloc((((void*)0)), sizeof(NSSTime)));
1179 if (rvTime) {
1180 rvTime->prTime = prTime;
1181 }
1182 return rvTime;
1183}
1184
1185NSS_IMPLEMENT PRTime
1186NSSTime_GetPRTime(
1187 NSSTime *time)
1188{
1189 return time->prTime;
1190}