Bug Summary

File:s/cmd/crlutil/crlgen.c
Warning:line 1063, column 9
Branch condition evaluates to a garbage value

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name crlgen.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 -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/var/lib/jenkins/workspace/nss-scan-build/nss/cmd/crlutil -ffunction-sections -fdata-sections -fcoverage-compilation-dir=/var/lib/jenkins/workspace/nss-scan-build/nss/cmd/crlutil -resource-dir /usr/lib/llvm-18/lib/clang/18 -D HAVE_STRERROR -D LINUX -D linux -D XP_UNIX -D XP_UNIX -D NSPR20 -D DEBUG -U NDEBUG -D _DEFAULT_SOURCE -D _BSD_SOURCE -D _POSIX_SOURCE -D SDB_MEASURE_USE_TEMP_DIR -D _REENTRANT -D DEBUG -U NDEBUG -D _DEFAULT_SOURCE -D _BSD_SOURCE -D _POSIX_SOURCE -D SDB_MEASURE_USE_TEMP_DIR -D _REENTRANT -D NSS_DISABLE_SSE3 -D NSS_NO_INIT_SUPPORT -D USE_UTIL_DIRECTLY -D NO_NSPR_10_SUPPORT -D SSL_DISABLE_DEPRECATED_CIPHER_SUITE_NAMES -I ../../../dist/Linux4.19_x86_64_gcc_glibc_PTH_64_DBG.OBJ/include -I ../../../dist/public/nss -I ../../../dist/private/nss -I ../../../dist/public/seccmd -I ../../../dist/public/dbm -internal-isystem /usr/lib/llvm-18/lib/clang/18/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -std=c99 -ferror-limit 19 -fgnuc-version=4.2.1 -analyzer-output=html -analyzer-config stable-report-filename=true -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/scan-build-2024-05-18-082241-28900-1 -x c crlgen.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/*
6** crlgen.c
7**
8** utility for managing certificates revocation lists generation
9**
10*/
11
12#include <stdio.h>
13#include <math.h>
14
15#include "nspr.h"
16#include "plgetopt.h"
17#include "nss.h"
18#include "secutil.h"
19#include "cert.h"
20#include "certi.h"
21#include "certdb.h"
22#include "pk11func.h"
23#include "crlgen.h"
24
25/* Destroys extHandle and data. data was create on heap.
26 * extHandle creaded by CERT_StartCRLEntryExtensions. entry
27 * was allocated on arena.*/
28static void
29destroyEntryData(CRLGENEntryData *data)
30{
31 if (!data)
32 return;
33 PORT_Assert(data->entry)((data->entry)?((void)0):PR_Assert("data->entry","crlgen.c"
,33))
;
34 if (data->extHandle)
35 CERT_FinishExtensions(data->extHandle);
36 PORT_FreePORT_Free_Util(data);
37}
38
39/* Prints error messages along with line number */
40void
41crlgen_PrintError(int line, char *msg, ...)
42{
43 va_list args;
44
45 va_start(args, msg)__builtin_va_start(args, msg);
46
47 fprintf(stderrstderr, "crlgen: (line: %d) ", line);
48 vfprintf(stderrstderr, msg, args);
49
50 va_end(args)__builtin_va_end(args);
51}
52/* Finds CRLGENEntryData in hashtable according PRUint64 value
53 * - certId : cert serial number*/
54static CRLGENEntryData *
55crlgen_FindEntry(CRLGENGeneratorData *crlGenData, SECItem *certId)
56{
57 if (!crlGenData->entryDataHashTable || !certId)
58 return NULL((void*)0);
59 return (CRLGENEntryData *)
60 PL_HashTableLookup(crlGenData->entryDataHashTable,
61 certId);
62}
63
64/* Removes CRLGENEntryData from hashtable according to certId
65 * - certId : cert serial number*/
66static SECStatus
67crlgen_RmEntry(CRLGENGeneratorData *crlGenData, SECItem *certId)
68{
69 CRLGENEntryData *data = NULL((void*)0);
70 SECStatus rv = SECSuccess;
71
72 if (!crlGenData->entryDataHashTable) {
73 return SECSuccess;
74 }
75
76 data = crlgen_FindEntry(crlGenData, certId);
77 if (!data) {
78 return SECSuccess;
79 }
80
81 if (!PL_HashTableRemove(crlGenData->entryDataHashTable, certId)) {
82 rv = SECFailure;
83 }
84
85 destroyEntryData(data);
86 return rv;
87}
88
89/* Stores CRLGENEntryData in hashtable according to certId
90 * - certId : cert serial number*/
91static CRLGENEntryData *
92crlgen_PlaceAnEntry(CRLGENGeneratorData *crlGenData,
93 CERTCrlEntry *entry, SECItem *certId)
94{
95 CRLGENEntryData *newData = NULL((void*)0);
96
97 PORT_Assert(crlGenData && crlGenData->entryDataHashTable &&((crlGenData && crlGenData->entryDataHashTable &&
entry)?((void)0):PR_Assert("crlGenData && crlGenData->entryDataHashTable && entry"
,"crlgen.c",98))
98 entry)((crlGenData && crlGenData->entryDataHashTable &&
entry)?((void)0):PR_Assert("crlGenData && crlGenData->entryDataHashTable && entry"
,"crlgen.c",98))
;
99 if (!crlGenData || !crlGenData->entryDataHashTable || !entry) {
100 PORT_SetErrorPORT_SetError_Util(SEC_ERROR_INVALID_ARGS);
101 return NULL((void*)0);
102 }
103
104 newData = PORT_ZNew(CRLGENEntryData)(CRLGENEntryData *)PORT_ZAlloc_Util(sizeof(CRLGENEntryData));
105 if (!newData) {
106 return NULL((void*)0);
107 }
108 newData->entry = entry;
109 newData->certId = certId;
110 if (!PL_HashTableAdd(crlGenData->entryDataHashTable,
111 newData->certId, newData)) {
112 crlgen_PrintError(crlGenData->parsedLineNum,
113 "Can not add entryData structure\n");
114 return NULL((void*)0);
115 }
116 return newData;
117}
118
119/* Use this structure to keep pointer when commiting entries extensions */
120struct commitData {
121 int pos;
122 CERTCrlEntry **entries;
123};
124
125/* HT PL_HashTableEnumerateEntries callback. Sorts hashtable entries of the
126 * table he. Returns value through arg parameter*/
127static PRIntn PR_CALLBACK
128crlgen_CommitEntryData(PLHashEntry *he, PRIntn i, void *arg)
129{
130 CRLGENEntryData *data = NULL((void*)0);
131
132 PORT_Assert(he)((he)?((void)0):PR_Assert("he","crlgen.c",132));
133 if (!he) {
134 return HT_ENUMERATE_NEXT0;
135 }
136 data = (CRLGENEntryData *)he->value;
137
138 PORT_Assert(data)((data)?((void)0):PR_Assert("data","crlgen.c",138));
139 PORT_Assert(arg)((arg)?((void)0):PR_Assert("arg","crlgen.c",139));
140
141 if (data) {
142 struct commitData *dt = (struct commitData *)arg;
143 dt->entries[dt->pos++] = data->entry;
144 destroyEntryData(data);
145 }
146 return HT_ENUMERATE_NEXT0;
147}
148
149/* Copy char * datainto allocated in arena SECItem */
150static SECStatus
151crlgen_SetString(PLArenaPool *arena, const char *dataIn, SECItem *value)
152{
153 SECItem item;
154
155 PORT_Assert(arena && dataIn)((arena && dataIn)?((void)0):PR_Assert("arena && dataIn"
,"crlgen.c",155))
;
156 if (!arena || !dataIn) {
157 PORT_SetErrorPORT_SetError_Util(SEC_ERROR_INVALID_ARGS);
158 return SECFailure;
159 }
160
161 item.data = (void *)dataIn;
162 item.len = PORT_Strlen(dataIn)strlen(dataIn);
163
164 return SECITEM_CopyItemSECITEM_CopyItem_Util(arena, value, &item);
165}
166
167/* Creates CERTGeneralName from parsed data for the Authority Key Extension */
168static CERTGeneralName *
169crlgen_GetGeneralName(PLArenaPool *arena, CRLGENGeneratorData *crlGenData,
170 const char *data)
171{
172 CERTGeneralName *namesList = NULL((void*)0);
173 CERTGeneralName *current;
174 CERTGeneralName *tail = NULL((void*)0);
175 SECStatus rv = SECSuccess;
176 const char *nextChunk = NULL((void*)0);
177 const char *currData = NULL((void*)0);
178 int intValue;
179 char buffer[512];
180 void *mark;
181
182 if (!data)
183 return NULL((void*)0);
184 PORT_Assert(arena)((arena)?((void)0):PR_Assert("arena","crlgen.c",184));
185 if (!arena) {
186 PORT_SetErrorPORT_SetError_Util(SEC_ERROR_INVALID_ARGS);
187 return NULL((void*)0);
188 }
189
190 mark = PORT_ArenaMarkPORT_ArenaMark_Util(arena);
191
192 nextChunk = data;
193 currData = data;
194 do {
195 int nameLen = 0;
196 char name[128];
197 const char *sepPrt = NULL((void*)0);
198 nextChunk = PORT_Strchrstrchr(currData, '|');
199 if (!nextChunk)
200 nextChunk = data + strlen(data);
201 sepPrt = PORT_Strchrstrchr(currData, ':');
202 if (sepPrt == NULL((void*)0) || sepPrt >= nextChunk) {
203 *buffer = '\0';
204 sepPrt = nextChunk;
205 } else {
206 PORT_Memcpymemcpy(buffer, sepPrt + 1,
207 (nextChunk - sepPrt - 1));
208 buffer[nextChunk - sepPrt - 1] = '\0';
209 }
210 nameLen = PR_MIN(sepPrt - currData, sizeof(name) - 1)((sepPrt - currData)<(sizeof(name) - 1)?(sepPrt - currData
):(sizeof(name) - 1))
;
211 PORT_Memcpymemcpy(name, currData, nameLen);
212 name[nameLen] = '\0';
213 currData = nextChunk + 1;
214
215 if (!PORT_Strcmpstrcmp(name, "otherName"))
216 intValue = certOtherName;
217 else if (!PORT_Strcmpstrcmp(name, "rfc822Name"))
218 intValue = certRFC822Name;
219 else if (!PORT_Strcmpstrcmp(name, "dnsName"))
220 intValue = certDNSName;
221 else if (!PORT_Strcmpstrcmp(name, "x400Address"))
222 intValue = certX400Address;
223 else if (!PORT_Strcmpstrcmp(name, "directoryName"))
224 intValue = certDirectoryName;
225 else if (!PORT_Strcmpstrcmp(name, "ediPartyName"))
226 intValue = certEDIPartyName;
227 else if (!PORT_Strcmpstrcmp(name, "URI"))
228 intValue = certURI;
229 else if (!PORT_Strcmpstrcmp(name, "ipAddress"))
230 intValue = certIPAddress;
231 else if (!PORT_Strcmpstrcmp(name, "registerID"))
232 intValue = certRegisterID;
233 else
234 intValue = -1;
235
236 if (intValue >= certOtherName && intValue <= certRegisterID) {
237 if (namesList == NULL((void*)0)) {
238 namesList = current = tail = PORT_ArenaZNew(arena,(CERTGeneralName *)PORT_ArenaZAlloc_Util(arena, sizeof(CERTGeneralName
))
239 CERTGeneralName)(CERTGeneralName *)PORT_ArenaZAlloc_Util(arena, sizeof(CERTGeneralName
))
;
240 } else {
241 current = PORT_ArenaZNew(arena, CERTGeneralName)(CERTGeneralName *)PORT_ArenaZAlloc_Util(arena, sizeof(CERTGeneralName
))
;
242 }
243 if (current == NULL((void*)0)) {
244 rv = SECFailure;
245 break;
246 }
247 } else {
248 PORT_SetErrorPORT_SetError_Util(SEC_ERROR_INVALID_ARGS);
249 break;
250 }
251 current->type = intValue;
252 switch (current->type) {
253 case certURI:
254 case certDNSName:
255 case certRFC822Name:
256 current->name.other.data = PORT_ArenaAllocPORT_ArenaAlloc_Util(arena, strlen(buffer));
257 if (current->name.other.data == NULL((void*)0)) {
258 rv = SECFailure;
259 break;
260 }
261 PORT_Memcpymemcpy(current->name.other.data, buffer,
262 current->name.other.len = strlen(buffer));
263 break;
264
265 case certEDIPartyName:
266 case certIPAddress:
267 case certOtherName:
268 case certRegisterID:
269 case certX400Address: {
270
271 current->name.other.data = PORT_ArenaAllocPORT_ArenaAlloc_Util(arena, strlen(buffer) + 2);
272 if (current->name.other.data == NULL((void*)0)) {
273 rv = SECFailure;
274 break;
275 }
276
277 PORT_Memcpymemcpy(current->name.other.data + 2, buffer, strlen(buffer));
278 /* This may not be accurate for all cases.For now, use this tag type */
279 current->name.other.data[0] = (char)(((current->type - 1) & 0x1f) | 0x80);
280 current->name.other.data[1] = (char)strlen(buffer);
281 current->name.other.len = strlen(buffer) + 2;
282 break;
283 }
284
285 case certDirectoryName: {
286 CERTName *directoryName = NULL((void*)0);
287
288 directoryName = CERT_AsciiToName(buffer);
289 if (!directoryName) {
290 rv = SECFailure;
291 break;
292 }
293
294 rv = CERT_CopyName(arena, &current->name.directoryName, directoryName);
295 CERT_DestroyName(directoryName);
296
297 break;
298 }
299 }
300 if (rv != SECSuccess)
301 break;
302 current->l.next = &(namesList->l);
303 current->l.prev = &(tail->l);
304 tail->l.next = &(current->l);
305 tail = current;
306
307 } while (nextChunk != data + strlen(data));
308
309 if (rv != SECSuccess) {
310 PORT_ArenaReleasePORT_ArenaRelease_Util(arena, mark);
311 namesList = NULL((void*)0);
312 }
313 return (namesList);
314}
315
316/* Creates CERTGeneralName from parsed data for the Authority Key Extension */
317static CERTGeneralName *
318crlgen_DistinguishedName(PLArenaPool *arena, CRLGENGeneratorData *crlGenData,
319 const char *data)
320{
321 CERTName *directoryName = NULL((void*)0);
322 CERTGeneralName *current;
323 SECStatus rv = SECFailure;
324 void *mark;
325
326 if (!data)
327 return NULL((void*)0);
328 PORT_Assert(arena)((arena)?((void)0):PR_Assert("arena","crlgen.c",328));
329 if (!arena) {
330 PORT_SetErrorPORT_SetError_Util(SEC_ERROR_INVALID_ARGS);
331 return NULL((void*)0);
332 }
333
334 mark = PORT_ArenaMarkPORT_ArenaMark_Util(arena);
335
336 current = PORT_ArenaZNew(arena, CERTGeneralName)(CERTGeneralName *)PORT_ArenaZAlloc_Util(arena, sizeof(CERTGeneralName
))
;
337 if (current == NULL((void*)0)) {
338 goto loser;
339 }
340 current->type = certDirectoryName;
341 current->l.next = &current->l;
342 current->l.prev = &current->l;
343
344 directoryName = CERT_AsciiToName((char *)data);
345 if (!directoryName) {
346 goto loser;
347 }
348
349 rv = CERT_CopyName(arena, &current->name.directoryName, directoryName);
350 CERT_DestroyName(directoryName);
351
352loser:
353 if (rv != SECSuccess) {
354 PORT_SetErrorPORT_SetError_Util(rv);
355 PORT_ArenaReleasePORT_ArenaRelease_Util(arena, mark);
356 current = NULL((void*)0);
357 }
358 return (current);
359}
360
361/* Adding Authority Key ID extension to extension handle. */
362static SECStatus
363crlgen_AddAuthKeyID(CRLGENGeneratorData *crlGenData,
364 const char **dataArr)
365{
366 void *extHandle = NULL((void*)0);
367 CERTAuthKeyID *authKeyID = NULL((void*)0);
368 PLArenaPool *arena = NULL((void*)0);
369 SECStatus rv = SECSuccess;
370
371 PORT_Assert(dataArr && crlGenData)((dataArr && crlGenData)?((void)0):PR_Assert("dataArr && crlGenData"
,"crlgen.c",371))
;
372 if (!crlGenData || !dataArr) {
373 return SECFailure;
374 }
375
376 extHandle = crlGenData->crlExtHandle;
377
378 if (!dataArr[0] || !dataArr[1] || !dataArr[2]) {
379 PORT_SetErrorPORT_SetError_Util(SEC_ERROR_INVALID_ARGS);
380 crlgen_PrintError(crlGenData->parsedLineNum,
381 "insufficient number of parameters.\n");
382 return SECFailure;
383 }
384
385 arena = PORT_NewArenaPORT_NewArena_Util(DER_DEFAULT_CHUNKSIZE(2048));
386 if (!arena) {
387 return SECFailure;
388 }
389
390 authKeyID = PORT_ArenaZNew(arena, CERTAuthKeyID)(CERTAuthKeyID *)PORT_ArenaZAlloc_Util(arena, sizeof(CERTAuthKeyID
))
;
391 if (authKeyID == NULL((void*)0)) {
392 rv = SECFailure;
393 goto loser;
394 }
395
396 if (dataArr[3] == NULL((void*)0)) {
397 rv = crlgen_SetString(arena, dataArr[2], &authKeyID->keyID);
398 if (rv != SECSuccess)
399 goto loser;
400 } else {
401 rv = crlgen_SetString(arena, dataArr[3],
402 &authKeyID->authCertSerialNumber);
403 if (rv != SECSuccess)
404 goto loser;
405
406 authKeyID->authCertIssuer =
407 crlgen_DistinguishedName(arena, crlGenData, dataArr[2]);
408 if (authKeyID->authCertIssuer == NULL((void*)0) && SECFailure == PORT_GetErrorPORT_GetError_Util()) {
409 crlgen_PrintError(crlGenData->parsedLineNum, "syntax error.\n");
410 rv = SECFailure;
411 goto loser;
412 }
413 }
414
415 rv =
416 SECU_EncodeAndAddExtensionValue(arena, extHandle, authKeyID,
417 (*dataArr[1] == '1') ? PR_TRUE1 : PR_FALSE0,
418 SEC_OID_X509_AUTH_KEY_ID,
419 (EXTEN_EXT_VALUE_ENCODER)CERT_EncodeAuthKeyID);
420loser:
421 if (arena)
422 PORT_FreeArenaPORT_FreeArena_Util(arena, PR_FALSE0);
423 return rv;
424}
425
426/* Creates and add Subject Alternative Names extension */
427static SECStatus
428crlgen_AddIssuerAltNames(CRLGENGeneratorData *crlGenData,
429 const char **dataArr)
430{
431 CERTGeneralName *nameList = NULL((void*)0);
432 PLArenaPool *arena = NULL((void*)0);
433 void *extHandle = NULL((void*)0);
434 SECStatus rv = SECSuccess;
435
436 PORT_Assert(dataArr && crlGenData)((dataArr && crlGenData)?((void)0):PR_Assert("dataArr && crlGenData"
,"crlgen.c",436))
;
437 if (!crlGenData || !dataArr) {
438 return SECFailure;
439 }
440
441 if (!dataArr || !dataArr[0] || !dataArr[1] || !dataArr[2]) {
442 PORT_SetErrorPORT_SetError_Util(SEC_ERROR_INVALID_ARGS);
443 crlgen_PrintError(crlGenData->parsedLineNum,
444 "insufficient number of arguments.\n");
445 return SECFailure;
446 }
447
448 PORT_Assert(dataArr && crlGenData)((dataArr && crlGenData)?((void)0):PR_Assert("dataArr && crlGenData"
,"crlgen.c",448))
;
449 if (!crlGenData || !dataArr) {
450 return SECFailure;
451 }
452
453 extHandle = crlGenData->crlExtHandle;
454
455 if (!dataArr[0] || !dataArr[1] || !dataArr[2]) {
456 PORT_SetErrorPORT_SetError_Util(SEC_ERROR_INVALID_ARGS);
457 crlgen_PrintError(crlGenData->parsedLineNum,
458 "insufficient number of parameters.\n");
459 return SECFailure;
460 }
461
462 arena = PORT_NewArenaPORT_NewArena_Util(DER_DEFAULT_CHUNKSIZE(2048));
463 if (!arena) {
464 return SECFailure;
465 }
466
467 nameList = crlgen_GetGeneralName(arena, crlGenData, dataArr[2]);
468 if (nameList == NULL((void*)0)) {
469 crlgen_PrintError(crlGenData->parsedLineNum, "syntax error.\n");
470 rv = SECFailure;
471 goto loser;
472 }
473
474 rv =
475 SECU_EncodeAndAddExtensionValue(arena, extHandle, nameList,
476 (*dataArr[1] == '1') ? PR_TRUE1 : PR_FALSE0,
477 SEC_OID_X509_ISSUER_ALT_NAME,
478 (EXTEN_EXT_VALUE_ENCODER)CERT_EncodeAltNameExtension);
479loser:
480 if (arena)
481 PORT_FreeArenaPORT_FreeArena_Util(arena, PR_FALSE0);
482 return rv;
483}
484
485/* Creates and adds CRLNumber extension to extension handle.
486 * Since, this is CRL extension, extension handle is the one
487 * related to CRL extensions */
488static SECStatus
489crlgen_AddCrlNumber(CRLGENGeneratorData *crlGenData, const char **dataArr)
490{
491 PLArenaPool *arena = NULL((void*)0);
492 SECItem encodedItem;
493 void *dummy;
494 SECStatus rv = SECFailure;
495 int code = 0;
496
497 PORT_Assert(dataArr && crlGenData)((dataArr && crlGenData)?((void)0):PR_Assert("dataArr && crlGenData"
,"crlgen.c",497))
;
498 if (!crlGenData || !dataArr) {
499 goto loser;
500 }
501
502 if (!dataArr[0] || !dataArr[1] || !dataArr[2]) {
503 PORT_SetErrorPORT_SetError_Util(SEC_ERROR_INVALID_ARGS);
504 crlgen_PrintError(crlGenData->parsedLineNum,
505 "insufficient number of arguments.\n");
506 goto loser;
507 }
508
509 arena = PORT_NewArenaPORT_NewArena_Util(DER_DEFAULT_CHUNKSIZE(2048));
510 if (arena == NULL((void*)0)) {
511 goto loser;
512 }
513
514 code = atoi(dataArr[2]);
515 if (code == 0 && *dataArr[2] != '0') {
516 PORT_SetErrorPORT_SetError_Util(SEC_ERROR_INVALID_ARGS);
517 goto loser;
518 }
519
520 dummy = SEC_ASN1EncodeIntegerSEC_ASN1EncodeInteger_Util(arena, &encodedItem, code);
521 if (!dummy) {
522 rv = SECFailure;
523 goto loser;
524 }
525
526 rv = CERT_AddExtension(crlGenData->crlExtHandle, SEC_OID_X509_CRL_NUMBER,
527 &encodedItem,
528 (*dataArr[1] == '1') ? PR_TRUE1 : PR_FALSE0,
529 PR_TRUE1);
530
531loser:
532 if (arena)
533 PORT_FreeArenaPORT_FreeArena_Util(arena, PR_FALSE0);
534 return rv;
535}
536
537/* Creates Cert Revocation Reason code extension. Encodes it and
538 * returns as SECItem structure */
539static SECItem *
540crlgen_CreateReasonCode(PLArenaPool *arena, const char **dataArr,
541 int *extCode)
542{
543 SECItem *encodedItem;
544 void *dummy;
545 void *mark = NULL((void*)0);
546 int code = 0;
547
548 PORT_Assert(arena && dataArr)((arena && dataArr)?((void)0):PR_Assert("arena && dataArr"
,"crlgen.c",548))
;
549 if (!arena || !dataArr) {
550 goto loser;
551 }
552
553 mark = PORT_ArenaMarkPORT_ArenaMark_Util(arena);
554
555 encodedItem = PORT_ArenaZNew(arena, SECItem)(SECItem *)PORT_ArenaZAlloc_Util(arena, sizeof(SECItem));
556 if (encodedItem == NULL((void*)0)) {
557 goto loser;
558 }
559
560 if (dataArr[2] == NULL((void*)0)) {
561 PORT_SetErrorPORT_SetError_Util(SEC_ERROR_INVALID_ARGS);
562 goto loser;
563 }
564
565 code = atoi(dataArr[2]);
566 /* aACompromise(10) is the last possible of the values
567 * for the Reason Core Extension */
568 if ((code == 0 && *dataArr[2] != '0') || code > 10) {
569
570 PORT_SetErrorPORT_SetError_Util(SEC_ERROR_INVALID_ARGS);
571 goto loser;
572 }
573
574 dummy = SEC_ASN1EncodeIntegerSEC_ASN1EncodeInteger_Util(arena, encodedItem, code);
575 if (!dummy) {
576 goto loser;
577 }
578
579 *extCode = SEC_OID_X509_REASON_CODE;
580 return encodedItem;
581
582loser:
583 if (mark) {
584 PORT_ArenaReleasePORT_ArenaRelease_Util(arena, mark);
585 }
586 return NULL((void*)0);
587}
588
589/* Creates Cert Invalidity Date extension. Encodes it and
590 * returns as SECItem structure */
591static SECItem *
592crlgen_CreateInvalidityDate(PLArenaPool *arena, const char **dataArr,
593 int *extCode)
594{
595 SECItem *encodedItem;
596 int length = 0;
597 void *mark = NULL((void*)0);
598
599 PORT_Assert(arena && dataArr)((arena && dataArr)?((void)0):PR_Assert("arena && dataArr"
,"crlgen.c",599))
;
600 if (!arena || !dataArr) {
601 goto loser;
602 }
603
604 mark = PORT_ArenaMarkPORT_ArenaMark_Util(arena);
605
606 encodedItem = PORT_ArenaZNew(arena, SECItem)(SECItem *)PORT_ArenaZAlloc_Util(arena, sizeof(SECItem));
607 if (encodedItem == NULL((void*)0)) {
608 goto loser;
609 }
610
611 length = PORT_Strlen(dataArr[2])strlen(dataArr[2]);
612
613 encodedItem->type = siGeneralizedTime;
614 encodedItem->data = PORT_ArenaAllocPORT_ArenaAlloc_Util(arena, length);
615 if (!encodedItem->data) {
616 goto loser;
617 }
618
619 PORT_Memcpymemcpy(encodedItem->data, dataArr[2], (encodedItem->len = length) * sizeof(char));
620
621 *extCode = SEC_OID_X509_INVALID_DATE;
622 return encodedItem;
623
624loser:
625 if (mark) {
626 PORT_ArenaReleasePORT_ArenaRelease_Util(arena, mark);
627 }
628 return NULL((void*)0);
629}
630
631/* Creates(by calling extCreator function) and adds extension to a set
632 * of already added certs. Uses values of rangeFrom and rangeTo from
633 * CRLGENCrlGenCtl structure for identifying the inclusive set of certs */
634static SECStatus
635crlgen_AddEntryExtension(CRLGENGeneratorData *crlGenData,
636 const char **dataArr, char *extName,
637 SECItem *(*extCreator)(PLArenaPool *arena,
638 const char **dataArr,
639 int *extCode))
640{
641 PRUint64 i = 0;
642 SECStatus rv = SECFailure;
643 int extCode = 0;
644 PRUint64 lastRange;
645 SECItem *ext = NULL((void*)0);
646 PLArenaPool *arena = NULL((void*)0);
647
648 PORT_Assert(crlGenData && dataArr)((crlGenData && dataArr)?((void)0):PR_Assert("crlGenData && dataArr"
,"crlgen.c",648))
;
649 if (!crlGenData || !dataArr) {
650 goto loser;
651 }
652
653 if (!dataArr[0] || !dataArr[1]) {
654 PORT_SetErrorPORT_SetError_Util(SEC_ERROR_INVALID_ARGS);
655 crlgen_PrintError(crlGenData->parsedLineNum,
656 "insufficient number of arguments.\n");
657 }
658
659 lastRange = crlGenData->rangeTo - crlGenData->rangeFrom + 1;
660
661 arena = PORT_NewArenaPORT_NewArena_Util(DER_DEFAULT_CHUNKSIZE(2048));
662 if (arena == NULL((void*)0)) {
663 goto loser;
664 }
665
666 ext = extCreator(arena, dataArr, &extCode);
667 if (ext == NULL((void*)0)) {
668 crlgen_PrintError(crlGenData->parsedLineNum,
669 "got error while creating extension: %s\n",
670 extName);
671 goto loser;
672 }
673
674 for (i = 0; i < lastRange; i++) {
675 CRLGENEntryData *extData = NULL((void*)0);
676 void *extHandle = NULL((void*)0);
677 SECItem *certIdItem =
678 SEC_ASN1EncodeIntegerSEC_ASN1EncodeInteger_Util(arena, NULL((void*)0),
679 crlGenData->rangeFrom + i);
680 if (!certIdItem) {
681 rv = SECFailure;
682 goto loser;
683 }
684
685 extData = crlgen_FindEntry(crlGenData, certIdItem);
686 if (!extData) {
687 crlgen_PrintError(crlGenData->parsedLineNum,
688 "can not add extension: crl entry "
689 "(serial number: %d) is not in the list yet.\n",
690 crlGenData->rangeFrom + i);
691 continue;
692 }
693
694 extHandle = extData->extHandle;
695 if (extHandle == NULL((void*)0)) {
696 extHandle = extData->extHandle =
697 CERT_StartCRLEntryExtensions(&crlGenData->signCrl->crl,
698 (CERTCrlEntry *)extData->entry);
699 }
700 rv = CERT_AddExtension(extHandle, extCode, ext,
701 (*dataArr[1] == '1') ? PR_TRUE1 : PR_FALSE0,
702 PR_TRUE1);
703 if (rv == SECFailure) {
704 goto loser;
705 }
706 }
707
708loser:
709 if (arena)
710 PORT_FreeArenaPORT_FreeArena_Util(arena, PR_FALSE0);
711 return rv;
712}
713
714/* Commits all added entries and their's extensions into CRL. */
715SECStatus
716CRLGEN_CommitExtensionsAndEntries(CRLGENGeneratorData *crlGenData)
717{
718 int size = 0;
719 CERTCrl *crl;
720 PLArenaPool *arena;
721 SECStatus rv = SECSuccess;
722 void *mark;
723
724 PORT_Assert(crlGenData && crlGenData->signCrl && crlGenData->signCrl->arena)((crlGenData && crlGenData->signCrl && crlGenData
->signCrl->arena)?((void)0):PR_Assert("crlGenData && crlGenData->signCrl && crlGenData->signCrl->arena"
,"crlgen.c",724))
;
725 if (!crlGenData || !crlGenData->signCrl || !crlGenData->signCrl->arena) {
726 PORT_SetErrorPORT_SetError_Util(SEC_ERROR_INVALID_ARGS);
727 return SECFailure;
728 }
729
730 arena = crlGenData->signCrl->arena;
731 crl = &crlGenData->signCrl->crl;
732
733 mark = PORT_ArenaMarkPORT_ArenaMark_Util(arena);
734
735 if (crlGenData->crlExtHandle)
736 CERT_FinishExtensions(crlGenData->crlExtHandle);
737
738 size = crlGenData->entryDataHashTable->nentries;
739 crl->entries = NULL((void*)0);
740 if (size) {
741 crl->entries = PORT_ArenaZNewArray(arena, CERTCrlEntry *, size + 1)(CERTCrlEntry * *)PORT_ArenaZAlloc_Util(arena, sizeof(CERTCrlEntry
*) * (size + 1))
;
742 if (!crl->entries) {
743 rv = SECFailure;
744 } else {
745 struct commitData dt;
746 dt.entries = crl->entries;
747 dt.pos = 0;
748 PL_HashTableEnumerateEntries(crlGenData->entryDataHashTable,
749 &crlgen_CommitEntryData, &dt);
750 /* Last should be NULL */
751 crl->entries[size] = NULL((void*)0);
752 }
753 }
754
755 if (rv != SECSuccess)
756 PORT_ArenaReleasePORT_ArenaRelease_Util(arena, mark);
757 return rv;
758}
759
760/* Initializes extHandle with data from extensions array */
761static SECStatus
762crlgen_InitExtensionHandle(void *extHandle,
763 CERTCertExtension **extensions)
764{
765 CERTCertExtension *extension = NULL((void*)0);
766
767 if (!extensions)
768 return SECSuccess;
769
770 PORT_Assert(extHandle != NULL)((extHandle != ((void*)0))?((void)0):PR_Assert("extHandle != NULL"
,"crlgen.c",770))
;
771 if (!extHandle) {
772 return SECFailure;
773 }
774
775 extension = *extensions;
776 while (extension) {
777 SECOidTag oidTag = SECOID_FindOIDTagSECOID_FindOIDTag_Util(&extension->id);
778 /* shell we skip unknown extensions? */
779 CERT_AddExtension(extHandle, oidTag, &extension->value,
780 (extension->critical.len != 0) ? PR_TRUE1 : PR_FALSE0,
781 PR_FALSE0);
782 extension = *(++extensions);
783 }
784 return SECSuccess;
785}
786
787/* Used for initialization of extension handles for crl and certs
788 * extensions from existing CRL data then modifying existing CRL.*/
789SECStatus
790CRLGEN_ExtHandleInit(CRLGENGeneratorData *crlGenData)
791{
792 CERTCrl *crl = NULL((void*)0);
793 PRUint64 maxSN = 0;
794
795 PORT_Assert(crlGenData && crlGenData->signCrl &&((crlGenData && crlGenData->signCrl && crlGenData
->entryDataHashTable)?((void)0):PR_Assert("crlGenData && crlGenData->signCrl && crlGenData->entryDataHashTable"
,"crlgen.c",796))
796 crlGenData->entryDataHashTable)((crlGenData && crlGenData->signCrl && crlGenData
->entryDataHashTable)?((void)0):PR_Assert("crlGenData && crlGenData->signCrl && crlGenData->entryDataHashTable"
,"crlgen.c",796))
;
797 if (!crlGenData || !crlGenData->signCrl ||
798 !crlGenData->entryDataHashTable) {
799 PORT_SetErrorPORT_SetError_Util(SEC_ERROR_INVALID_ARGS);
800 return SECFailure;
801 }
802
803 crl = &crlGenData->signCrl->crl;
804 crlGenData->crlExtHandle = CERT_StartCRLExtensions(crl);
805 crlgen_InitExtensionHandle(crlGenData->crlExtHandle,
806 crl->extensions);
807 crl->extensions = NULL((void*)0);
808
809 if (crl->entries) {
810 CERTCrlEntry **entry = crl->entries;
811 while (*entry) {
812 PRUint64 sn = DER_GetIntegerDER_GetInteger_Util(&(*entry)->serialNumber);
813 CRLGENEntryData *extData =
814 crlgen_PlaceAnEntry(crlGenData, *entry, &(*entry)->serialNumber);
815 if ((*entry)->extensions) {
816 extData->extHandle =
817 CERT_StartCRLEntryExtensions(&crlGenData->signCrl->crl,
818 (CERTCrlEntry *)extData->entry);
819 if (crlgen_InitExtensionHandle(extData->extHandle,
820 (*entry)->extensions) == SECFailure)
821 return SECFailure;
822 }
823 (*entry)->extensions = NULL((void*)0);
824 entry++;
825 maxSN = PR_MAX(maxSN, sn)((maxSN)>(sn)?(maxSN):(sn));
826 }
827 }
828
829 crlGenData->rangeFrom = crlGenData->rangeTo = maxSN + 1;
830 return SECSuccess;
831}
832
833/*****************************************************************************
834 * Parser trigger functions start here
835 */
836
837/* Sets new internal range value for add/rm certs.*/
838static SECStatus
839crlgen_SetNewRangeField(CRLGENGeneratorData *crlGenData, char *value)
840{
841 long rangeFrom = 0, rangeTo = 0;
842 char *dashPos = NULL((void*)0);
843
844 PORT_Assert(crlGenData)((crlGenData)?((void)0):PR_Assert("crlGenData","crlgen.c",844
))
;
845 if (!crlGenData) {
846 PORT_SetErrorPORT_SetError_Util(SEC_ERROR_INVALID_ARGS);
847 return SECFailure;
848 }
849
850 if (value == NULL((void*)0)) {
851 PORT_SetErrorPORT_SetError_Util(SEC_ERROR_INVALID_ARGS);
852 crlgen_PrintError(crlGenData->parsedLineNum,
853 "insufficient number of arguments.\n");
854 return SECFailure;
855 }
856
857 if ((dashPos = strchr(value, '-')) != NULL((void*)0)) {
858 char *rangeToS, *rangeFromS = value;
859 *dashPos = '\0';
860 rangeFrom = atoi(rangeFromS);
861 *dashPos = '-';
862
863 rangeToS = (char *)(dashPos + 1);
864 rangeTo = atol(rangeToS);
865 } else {
866 rangeFrom = atol(value);
867 rangeTo = rangeFrom;
868 }
869
870 if (rangeFrom < 1 || rangeTo < rangeFrom) {
871 PORT_SetErrorPORT_SetError_Util(SEC_ERROR_INVALID_ARGS);
872 crlgen_PrintError(crlGenData->parsedLineNum,
873 "bad cert id range: %s.\n", value);
874 return SECFailure;
875 }
876
877 crlGenData->rangeFrom = rangeFrom;
878 crlGenData->rangeTo = rangeTo;
879
880 return SECSuccess;
881}
882
883/* Changes issuer subject field in CRL. By default this data is taken from
884 * issuer cert subject field.Not yet implemented */
885static SECStatus
886crlgen_SetIssuerField(CRLGENGeneratorData *crlGenData, char *value)
887{
888 crlgen_PrintError(crlGenData->parsedLineNum,
889 "Can not change CRL issuer field.\n");
890 return SECFailure;
891}
892
893/* Encode and sets CRL thisUpdate and nextUpdate time fields*/
894static SECStatus
895crlgen_SetTimeField(CRLGENGeneratorData *crlGenData, char *value,
896 PRBool setThisUpdate)
897{
898 CERTSignedCrl *signCrl;
899 PLArenaPool *arena;
900 CERTCrl *crl;
901 int length = 0;
902 SECItem *timeDest = NULL((void*)0);
903
904 PORT_Assert(crlGenData && crlGenData->signCrl &&((crlGenData && crlGenData->signCrl && crlGenData
->signCrl->arena)?((void)0):PR_Assert("crlGenData && crlGenData->signCrl && crlGenData->signCrl->arena"
,"crlgen.c",905))
905 crlGenData->signCrl->arena)((crlGenData && crlGenData->signCrl && crlGenData
->signCrl->arena)?((void)0):PR_Assert("crlGenData && crlGenData->signCrl && crlGenData->signCrl->arena"
,"crlgen.c",905))
;
906 if (!crlGenData || !crlGenData->signCrl || !crlGenData->signCrl->arena) {
907 PORT_SetErrorPORT_SetError_Util(SEC_ERROR_INVALID_ARGS);
908 return SECFailure;
909 }
910
911 signCrl = crlGenData->signCrl;
912 arena = signCrl->arena;
913 crl = &signCrl->crl;
914
915 if (value == NULL((void*)0)) {
916 PORT_SetErrorPORT_SetError_Util(SEC_ERROR_INVALID_ARGS);
917 crlgen_PrintError(crlGenData->parsedLineNum,
918 "insufficient number of arguments.\n");
919 return SECFailure;
920 }
921 length = PORT_Strlen(value)strlen(value);
922
923 if (setThisUpdate == PR_TRUE1) {
924 timeDest = &crl->lastUpdate;
925 } else {
926 timeDest = &crl->nextUpdate;
927 }
928
929 timeDest->type = siGeneralizedTime;
930 timeDest->data = PORT_ArenaAllocPORT_ArenaAlloc_Util(arena, length);
931 if (!timeDest->data) {
932 return SECFailure;
933 }
934 PORT_Memcpymemcpy(timeDest->data, value, length);
935 timeDest->len = length;
936
937 return SECSuccess;
938}
939
940/* Adds new extension into CRL or added cert handles */
941static SECStatus
942crlgen_AddExtension(CRLGENGeneratorData *crlGenData, const char **extData)
943{
944 PORT_Assert(crlGenData && crlGenData->crlExtHandle)((crlGenData && crlGenData->crlExtHandle)?((void)0
):PR_Assert("crlGenData && crlGenData->crlExtHandle"
,"crlgen.c",944))
;
945 if (!crlGenData || !crlGenData->crlExtHandle) {
946 PORT_SetErrorPORT_SetError_Util(SEC_ERROR_INVALID_ARGS);
947 return SECFailure;
948 }
949
950 if (extData == NULL((void*)0) || *extData == NULL((void*)0)) {
951 PORT_SetErrorPORT_SetError_Util(SEC_ERROR_INVALID_ARGS);
952 crlgen_PrintError(crlGenData->parsedLineNum,
953 "insufficient number of arguments.\n");
954 return SECFailure;
955 }
956 if (!PORT_Strcmpstrcmp(*extData, "authKeyId"))
957 return crlgen_AddAuthKeyID(crlGenData, extData);
958 else if (!PORT_Strcmpstrcmp(*extData, "issuerAltNames"))
959 return crlgen_AddIssuerAltNames(crlGenData, extData);
960 else if (!PORT_Strcmpstrcmp(*extData, "crlNumber"))
961 return crlgen_AddCrlNumber(crlGenData, extData);
962 else if (!PORT_Strcmpstrcmp(*extData, "reasonCode"))
963 return crlgen_AddEntryExtension(crlGenData, extData, "reasonCode",
964 crlgen_CreateReasonCode);
965 else if (!PORT_Strcmpstrcmp(*extData, "invalidityDate"))
966 return crlgen_AddEntryExtension(crlGenData, extData, "invalidityDate",
967 crlgen_CreateInvalidityDate);
968 else {
969 PORT_SetErrorPORT_SetError_Util(SEC_ERROR_INVALID_ARGS);
970 crlgen_PrintError(crlGenData->parsedLineNum,
971 "insufficient number of arguments.\n");
972 return SECFailure;
973 }
974}
975
976/* Created CRLGENEntryData for cert with serial number certId and
977 * adds it to entryDataHashTable. certId can be a single cert serial
978 * number or an inclusive rage of certs */
979static SECStatus
980crlgen_AddCert(CRLGENGeneratorData *crlGenData,
981 char *certId, char *revocationDate)
982{
983 CERTSignedCrl *signCrl;
984 SECItem *certIdItem;
985 PLArenaPool *arena;
986 PRUint64 rangeFrom = 0, rangeTo = 0, i = 0;
987 int timeValLength = -1;
988 SECStatus rv = SECFailure;
989 void *mark;
6
'mark' declared without an initial value
990
991 PORT_Assert(crlGenData && crlGenData->signCrl &&((crlGenData && crlGenData->signCrl && crlGenData
->signCrl->arena)?((void)0):PR_Assert("crlGenData && crlGenData->signCrl && crlGenData->signCrl->arena"
,"crlgen.c",992))
7
Assuming field 'signCrl' is non-null
8
Assuming field 'arena' is non-null
9
'?' condition is true
992 crlGenData->signCrl->arena)((crlGenData && crlGenData->signCrl && crlGenData
->signCrl->arena)?((void)0):PR_Assert("crlGenData && crlGenData->signCrl && crlGenData->signCrl->arena"
,"crlgen.c",992))
;
993 if (!crlGenData
9.1
'crlGenData' is non-null
|| !crlGenData->signCrl
9.2
Field 'signCrl' is non-null
|| !crlGenData->signCrl->arena
9.3
Field 'arena' is non-null
) {
10
Taking false branch
994 PORT_SetErrorPORT_SetError_Util(SEC_ERROR_INVALID_ARGS);
995 return SECFailure;
996 }
997
998 signCrl = crlGenData->signCrl;
999 arena = signCrl->arena;
1000
1001 if (!certId || !revocationDate) {
11
Assuming 'certId' is non-null
12
Assuming 'revocationDate' is non-null
13
Taking false branch
1002 PORT_SetErrorPORT_SetError_Util(SEC_ERROR_INVALID_ARGS);
1003 crlgen_PrintError(crlGenData->parsedLineNum,
1004 "insufficient number of arguments.\n");
1005 return SECFailure;
1006 }
1007
1008 timeValLength = strlen(revocationDate);
1009
1010 if (crlgen_SetNewRangeField(crlGenData, certId) == SECFailure &&
1011 certId) {
1012 return SECFailure;
1013 }
1014 rangeFrom = crlGenData->rangeFrom;
1015 rangeTo = crlGenData->rangeTo;
1016
1017 for (i = 0; i < rangeTo - rangeFrom + 1; i++) {
14
Assuming the condition is false
15
Loop condition is false. Execution continues on line 1061
1018 CERTCrlEntry *entry;
1019 mark = PORT_ArenaMarkPORT_ArenaMark_Util(arena);
1020 entry = PORT_ArenaZNew(arena, CERTCrlEntry)(CERTCrlEntry *)PORT_ArenaZAlloc_Util(arena, sizeof(CERTCrlEntry
))
;
1021 if (entry == NULL((void*)0)) {
1022 goto loser;
1023 }
1024
1025 certIdItem = SEC_ASN1EncodeIntegerSEC_ASN1EncodeInteger_Util(arena, &entry->serialNumber,
1026 rangeFrom + i);
1027 if (!certIdItem) {
1028 goto loser;
1029 }
1030
1031 if (crlgen_FindEntry(crlGenData, certIdItem)) {
1032 crlgen_PrintError(crlGenData->parsedLineNum,
1033 "entry already exists. Use \"range\" "
1034 "and \"rmcert\" before adding a new one with the "
1035 "same serial number %ld\n",
1036 rangeFrom + i);
1037 goto loser;
1038 }
1039
1040 entry->serialNumber.type = siBuffer;
1041
1042 entry->revocationDate.type = siGeneralizedTime;
1043
1044 entry->revocationDate.data =
1045 PORT_ArenaAllocPORT_ArenaAlloc_Util(arena, timeValLength);
1046 if (entry->revocationDate.data == NULL((void*)0)) {
1047 goto loser;
1048 }
1049
1050 PORT_Memcpymemcpy(entry->revocationDate.data, revocationDate,
1051 timeValLength * sizeof(char));
1052 entry->revocationDate.len = timeValLength;
1053
1054 entry->extensions = NULL((void*)0);
1055 if (!crlgen_PlaceAnEntry(crlGenData, entry, certIdItem)) {
1056 goto loser;
1057 }
1058 mark = NULL((void*)0);
1059 }
1060
1061 rv = SECSuccess;
1062loser:
1063 if (mark) {
16
Branch condition evaluates to a garbage value
1064 PORT_ArenaReleasePORT_ArenaRelease_Util(arena, mark);
1065 }
1066 return rv;
1067}
1068
1069/* Removes certs from entryDataHashTable which have certId serial number.
1070 * certId can have value of a range of certs */
1071static SECStatus
1072crlgen_RmCert(CRLGENGeneratorData *crlGenData, char *certId)
1073{
1074 PRUint64 i = 0;
1075
1076 PORT_Assert(crlGenData && certId)((crlGenData && certId)?((void)0):PR_Assert("crlGenData && certId"
,"crlgen.c",1076))
;
1077 if (!crlGenData || !certId) {
1078 PORT_SetErrorPORT_SetError_Util(SEC_ERROR_INVALID_ARGS);
1079 return SECFailure;
1080 }
1081
1082 if (crlgen_SetNewRangeField(crlGenData, certId) == SECFailure &&
1083 certId) {
1084 return SECFailure;
1085 }
1086
1087 for (i = 0; i < crlGenData->rangeTo - crlGenData->rangeFrom + 1; i++) {
1088 SECItem *certIdItem = SEC_ASN1EncodeIntegerSEC_ASN1EncodeInteger_Util(NULL((void*)0), NULL((void*)0),
1089 crlGenData->rangeFrom + i);
1090 if (certIdItem) {
1091 CRLGENEntryData *extData =
1092 crlgen_FindEntry(crlGenData, certIdItem);
1093 if (!extData) {
1094 printf("Cert with id %s is not in the list\n", certId);
1095 } else {
1096 crlgen_RmEntry(crlGenData, certIdItem);
1097 }
1098 SECITEM_FreeItemSECITEM_FreeItem_Util(certIdItem, PR_TRUE1);
1099 }
1100 }
1101
1102 return SECSuccess;
1103}
1104
1105/*************************************************************************
1106 * Lex Parser Helper functions are used to store parsed information
1107 * in context related structures. Context(or state) is identified base on
1108 * a type of a instruction parser currently is going through. New context
1109 * is identified by first token in a line. It can be addcert context,
1110 * addext context, etc. */
1111
1112/* Updates CRL field depending on current context */
1113static SECStatus
1114crlgen_updateCrlFn_field(CRLGENGeneratorData *crlGenData, void *str)
1115{
1116 CRLGENCrlField *fieldStr = (CRLGENCrlField *)str;
1117
1118 PORT_Assert(crlGenData)((crlGenData)?((void)0):PR_Assert("crlGenData","crlgen.c",1118
))
;
1119 if (!crlGenData) {
1120 PORT_SetErrorPORT_SetError_Util(SEC_ERROR_INVALID_ARGS);
1121 return SECFailure;
1122 }
1123
1124 switch (crlGenData->contextId) {
1125 case CRLGEN_ISSUER_CONTEXT1:
1126 crlgen_SetIssuerField(crlGenData, fieldStr->value);
1127 break;
1128 case CRLGEN_UPDATE_CONTEXT2:
1129 return crlgen_SetTimeField(crlGenData, fieldStr->value, PR_TRUE1);
1130 break;
1131 case CRLGEN_NEXT_UPDATE_CONTEXT3:
1132 return crlgen_SetTimeField(crlGenData, fieldStr->value, PR_FALSE0);
1133 break;
1134 case CRLGEN_CHANGE_RANGE_CONTEXT7:
1135 return crlgen_SetNewRangeField(crlGenData, fieldStr->value);
1136 break;
1137 default:
1138 crlgen_PrintError(crlGenData->parsedLineNum,
1139 "syntax error (unknow token type: %d)\n",
1140 crlGenData->contextId);
1141 PORT_SetErrorPORT_SetError_Util(SEC_ERROR_INVALID_ARGS);
1142 return SECFailure;
1143 }
1144 return SECSuccess;
1145}
1146
1147/* Sets parsed data for CRL field update into temporary structure */
1148static SECStatus
1149crlgen_setNextDataFn_field(CRLGENGeneratorData *crlGenData, void *str,
1150 void *data, unsigned short dtype)
1151{
1152 CRLGENCrlField *fieldStr = (CRLGENCrlField *)str;
1153
1154 PORT_Assert(crlGenData)((crlGenData)?((void)0):PR_Assert("crlGenData","crlgen.c",1154
))
;
1155 if (!crlGenData) {
1156 PORT_SetErrorPORT_SetError_Util(SEC_ERROR_INVALID_ARGS);
1157 return SECFailure;
1158 }
1159
1160 switch (crlGenData->contextId) {
1161 case CRLGEN_CHANGE_RANGE_CONTEXT7:
1162 if (dtype != CRLGEN_TYPE_DIGIT2 && dtype != CRLGEN_TYPE_DIGIT_RANGE3) {
1163 crlgen_PrintError(crlGenData->parsedLineNum,
1164 "range value should have "
1165 "numeric or numeric range values.\n");
1166 return SECFailure;
1167 }
1168 break;
1169 case CRLGEN_NEXT_UPDATE_CONTEXT3:
1170 case CRLGEN_UPDATE_CONTEXT2:
1171 if (dtype != CRLGEN_TYPE_ZDATE1) {
1172 crlgen_PrintError(crlGenData->parsedLineNum,
1173 "bad formated date. Should be "
1174 "YYYYMMDDHHMMSSZ.\n");
1175 return SECFailure;
1176 }
1177 break;
1178 default:
1179 PORT_SetErrorPORT_SetError_Util(SEC_ERROR_INVALID_ARGS);
1180 crlgen_PrintError(crlGenData->parsedLineNum,
1181 "syntax error (unknow token type: %d).\n",
1182 crlGenData->contextId, data);
1183 return SECFailure;
1184 }
1185 fieldStr->value = PORT_StrdupPORT_Strdup_Util(data);
1186 if (!fieldStr->value) {
1187 return SECFailure;
1188 }
1189 return SECSuccess;
1190}
1191
1192/* Triggers cert entries update depending on current context */
1193static SECStatus
1194crlgen_updateCrlFn_cert(CRLGENGeneratorData *crlGenData, void *str)
1195{
1196 CRLGENCertEntry *certStr = (CRLGENCertEntry *)str;
1197
1198 PORT_Assert(crlGenData)((crlGenData)?((void)0):PR_Assert("crlGenData","crlgen.c",1198
))
;
1
Assuming 'crlGenData' is non-null
2
'?' condition is true
1199 if (!crlGenData
2.1
'crlGenData' is non-null
) {
3
Taking false branch
1200 PORT_SetErrorPORT_SetError_Util(SEC_ERROR_INVALID_ARGS);
1201 return SECFailure;
1202 }
1203
1204 switch (crlGenData->contextId) {
4
Control jumps to 'case 6:' at line 1205
1205 case CRLGEN_ADD_CERT_CONTEXT6:
1206 return crlgen_AddCert(crlGenData, certStr->certId,
5
Calling 'crlgen_AddCert'
1207 certStr->revocationTime);
1208 case CRLGEN_RM_CERT_CONTEXT8:
1209 return crlgen_RmCert(crlGenData, certStr->certId);
1210 default:
1211 PORT_SetErrorPORT_SetError_Util(SEC_ERROR_INVALID_ARGS);
1212 crlgen_PrintError(crlGenData->parsedLineNum,
1213 "syntax error (unknow token type: %d).\n",
1214 crlGenData->contextId);
1215 return SECFailure;
1216 }
1217}
1218
1219/* Sets parsed data for CRL entries update into temporary structure */
1220static SECStatus
1221crlgen_setNextDataFn_cert(CRLGENGeneratorData *crlGenData, void *str,
1222 void *data, unsigned short dtype)
1223{
1224 CRLGENCertEntry *certStr = (CRLGENCertEntry *)str;
1225
1226 PORT_Assert(crlGenData)((crlGenData)?((void)0):PR_Assert("crlGenData","crlgen.c",1226
))
;
1227 if (!crlGenData) {
1228 PORT_SetErrorPORT_SetError_Util(SEC_ERROR_INVALID_ARGS);
1229 return SECFailure;
1230 }
1231
1232 switch (dtype) {
1233 case CRLGEN_TYPE_DIGIT2:
1234 case CRLGEN_TYPE_DIGIT_RANGE3:
1235 certStr->certId = PORT_StrdupPORT_Strdup_Util(data);
1236 if (!certStr->certId) {
1237 return SECFailure;
1238 }
1239 break;
1240 case CRLGEN_TYPE_DATE0:
1241 case CRLGEN_TYPE_ZDATE1:
1242 certStr->revocationTime = PORT_StrdupPORT_Strdup_Util(data);
1243 if (!certStr->revocationTime) {
1244 return SECFailure;
1245 }
1246 break;
1247 default:
1248 PORT_SetErrorPORT_SetError_Util(SEC_ERROR_INVALID_ARGS);
1249 crlgen_PrintError(crlGenData->parsedLineNum,
1250 "syntax error (unknow token type: %d).\n",
1251 crlGenData->contextId);
1252 return SECFailure;
1253 }
1254 return SECSuccess;
1255}
1256
1257/* Triggers cert entries/crl extension update */
1258static SECStatus
1259crlgen_updateCrlFn_extension(CRLGENGeneratorData *crlGenData, void *str)
1260{
1261 CRLGENExtensionEntry *extStr = (CRLGENExtensionEntry *)str;
1262
1263 return crlgen_AddExtension(crlGenData, (const char **)extStr->extData);
1264}
1265
1266/* Defines maximum number of fields extension may have */
1267#define MAX_EXT_DATA_LENGTH10 10
1268
1269/* Sets parsed extension data for CRL entries/CRL extensions update
1270 * into temporary structure */
1271static SECStatus
1272crlgen_setNextDataFn_extension(CRLGENGeneratorData *crlGenData, void *str,
1273 void *data, unsigned short dtype)
1274{
1275 CRLGENExtensionEntry *extStr = (CRLGENExtensionEntry *)str;
1276
1277 PORT_Assert(crlGenData)((crlGenData)?((void)0):PR_Assert("crlGenData","crlgen.c",1277
))
;
1278 if (!crlGenData) {
1279 PORT_SetErrorPORT_SetError_Util(SEC_ERROR_INVALID_ARGS);
1280 return SECFailure;
1281 }
1282
1283 if (extStr->extData == NULL((void*)0)) {
1284 extStr->extData = PORT_ZNewArray(char *, MAX_EXT_DATA_LENGTH)(char * *)PORT_ZAlloc_Util(sizeof(char *) * (10));
1285 if (!extStr->extData) {
1286 return SECFailure;
1287 }
1288 }
1289 if (extStr->nextUpdatedData >= MAX_EXT_DATA_LENGTH10) {
1290 PORT_SetErrorPORT_SetError_Util(SEC_ERROR_INVALID_ARGS);
1291 crlgen_PrintError(crlGenData->parsedLineNum,
1292 "number of fields in extension "
1293 "exceeded maximum allowed data length: %d.\n",
1294 MAX_EXT_DATA_LENGTH10);
1295 return SECFailure;
1296 }
1297 extStr->extData[extStr->nextUpdatedData] = PORT_StrdupPORT_Strdup_Util(data);
1298 if (!extStr->extData[extStr->nextUpdatedData]) {
1299 return SECFailure;
1300 }
1301 extStr->nextUpdatedData += 1;
1302
1303 return SECSuccess;
1304}
1305
1306/****************************************************************************************
1307 * Top level functions are triggered directly by parser.
1308 */
1309
1310/*
1311 * crl generation script parser recreates a temporary data staructure
1312 * for each line it is going through. This function cleans temp structure.
1313 */
1314void
1315crlgen_destroyTempData(CRLGENGeneratorData *crlGenData)
1316{
1317 if (crlGenData->contextId != CRLGEN_UNKNOWN_CONTEXT0) {
1318 switch (crlGenData->contextId) {
1319 case CRLGEN_ISSUER_CONTEXT1:
1320 case CRLGEN_UPDATE_CONTEXT2:
1321 case CRLGEN_NEXT_UPDATE_CONTEXT3:
1322 case CRLGEN_CHANGE_RANGE_CONTEXT7:
1323 if (crlGenData->crlField->value)
1324 PORT_FreePORT_Free_Util(crlGenData->crlField->value);
1325 PORT_FreePORT_Free_Util(crlGenData->crlField);
1326 break;
1327 case CRLGEN_ADD_CERT_CONTEXT6:
1328 case CRLGEN_RM_CERT_CONTEXT8:
1329 if (crlGenData->certEntry->certId)
1330 PORT_FreePORT_Free_Util(crlGenData->certEntry->certId);
1331 if (crlGenData->certEntry->revocationTime)
1332 PORT_FreePORT_Free_Util(crlGenData->certEntry->revocationTime);
1333 PORT_FreePORT_Free_Util(crlGenData->certEntry);
1334 break;
1335 case CRLGEN_ADD_EXTENSION_CONTEXT4:
1336 if (crlGenData->extensionEntry->extData) {
1337 int i = 0;
1338 for (; i < crlGenData->extensionEntry->nextUpdatedData; i++)
1339 PORT_FreePORT_Free_Util(*(crlGenData->extensionEntry->extData + i));
1340 PORT_FreePORT_Free_Util(crlGenData->extensionEntry->extData);
1341 }
1342 PORT_FreePORT_Free_Util(crlGenData->extensionEntry);
1343 break;
1344 }
1345 crlGenData->contextId = CRLGEN_UNKNOWN_CONTEXT0;
1346 }
1347}
1348
1349SECStatus
1350crlgen_updateCrl(CRLGENGeneratorData *crlGenData)
1351{
1352 SECStatus rv = SECSuccess;
1353
1354 PORT_Assert(crlGenData)((crlGenData)?((void)0):PR_Assert("crlGenData","crlgen.c",1354
))
;
1355 if (!crlGenData) {
1356 PORT_SetErrorPORT_SetError_Util(SEC_ERROR_INVALID_ARGS);
1357 return SECFailure;
1358 }
1359
1360 switch (crlGenData->contextId) {
1361 case CRLGEN_ISSUER_CONTEXT1:
1362 case CRLGEN_UPDATE_CONTEXT2:
1363 case CRLGEN_NEXT_UPDATE_CONTEXT3:
1364 case CRLGEN_CHANGE_RANGE_CONTEXT7:
1365 rv = crlGenData->crlField->updateCrlFn(crlGenData, crlGenData->crlField);
1366 break;
1367 case CRLGEN_RM_CERT_CONTEXT8:
1368 case CRLGEN_ADD_CERT_CONTEXT6:
1369 rv = crlGenData->certEntry->updateCrlFn(crlGenData, crlGenData->certEntry);
1370 break;
1371 case CRLGEN_ADD_EXTENSION_CONTEXT4:
1372 rv = crlGenData->extensionEntry->updateCrlFn(crlGenData, crlGenData->extensionEntry);
1373 break;
1374 case CRLGEN_UNKNOWN_CONTEXT0:
1375 break;
1376 default:
1377 crlgen_PrintError(crlGenData->parsedLineNum,
1378 "unknown lang context type code: %d.\n",
1379 crlGenData->contextId);
1380 PORT_Assert(0)((0)?((void)0):PR_Assert("0","crlgen.c",1380));
1381 return SECFailure;
1382 }
1383 /* Clrean structures after crl update */
1384 crlgen_destroyTempData(crlGenData);
1385
1386 crlGenData->parsedLineNum += 1;
1387
1388 return rv;
1389}
1390
1391SECStatus
1392crlgen_setNextData(CRLGENGeneratorData *crlGenData, void *data,
1393 unsigned short dtype)
1394{
1395 SECStatus rv = SECSuccess;
1396
1397 PORT_Assert(crlGenData)((crlGenData)?((void)0):PR_Assert("crlGenData","crlgen.c",1397
))
;
1398 if (!crlGenData) {
1399 PORT_SetErrorPORT_SetError_Util(SEC_ERROR_INVALID_ARGS);
1400 return SECFailure;
1401 }
1402
1403 switch (crlGenData->contextId) {
1404 case CRLGEN_ISSUER_CONTEXT1:
1405 case CRLGEN_UPDATE_CONTEXT2:
1406 case CRLGEN_NEXT_UPDATE_CONTEXT3:
1407 case CRLGEN_CHANGE_RANGE_CONTEXT7:
1408 rv = crlGenData->crlField->setNextDataFn(crlGenData, crlGenData->crlField,
1409 data, dtype);
1410 break;
1411 case CRLGEN_ADD_CERT_CONTEXT6:
1412 case CRLGEN_RM_CERT_CONTEXT8:
1413 rv = crlGenData->certEntry->setNextDataFn(crlGenData, crlGenData->certEntry,
1414 data, dtype);
1415 break;
1416 case CRLGEN_ADD_EXTENSION_CONTEXT4:
1417 rv =
1418 crlGenData->extensionEntry->setNextDataFn(crlGenData, crlGenData->extensionEntry, data, dtype);
1419 break;
1420 case CRLGEN_UNKNOWN_CONTEXT0:
1421 break;
1422 default:
1423 crlgen_PrintError(crlGenData->parsedLineNum,
1424 "unknown context type: %d.\n",
1425 crlGenData->contextId);
1426 PORT_Assert(0)((0)?((void)0):PR_Assert("0","crlgen.c",1426));
1427 return SECFailure;
1428 }
1429 return rv;
1430}
1431
1432SECStatus
1433crlgen_createNewLangStruct(CRLGENGeneratorData *crlGenData,
1434 unsigned structType)
1435{
1436 PORT_Assert(crlGenData &&((crlGenData && crlGenData->contextId == 0)?((void
)0):PR_Assert("crlGenData && crlGenData->contextId == CRLGEN_UNKNOWN_CONTEXT"
,"crlgen.c",1437))
1437 crlGenData->contextId == CRLGEN_UNKNOWN_CONTEXT)((crlGenData && crlGenData->contextId == 0)?((void
)0):PR_Assert("crlGenData && crlGenData->contextId == CRLGEN_UNKNOWN_CONTEXT"
,"crlgen.c",1437))
;
1438 if (!crlGenData ||
1439 crlGenData->contextId != CRLGEN_UNKNOWN_CONTEXT0) {
1440 PORT_SetErrorPORT_SetError_Util(SEC_ERROR_INVALID_ARGS);
1441 return SECFailure;
1442 }
1443
1444 switch (structType) {
1445 case CRLGEN_ISSUER_CONTEXT1:
1446 case CRLGEN_UPDATE_CONTEXT2:
1447 case CRLGEN_NEXT_UPDATE_CONTEXT3:
1448 case CRLGEN_CHANGE_RANGE_CONTEXT7:
1449 crlGenData->crlField = PORT_New(CRLGENCrlField)(CRLGENCrlField *)PORT_Alloc_Util(sizeof(CRLGENCrlField));
1450 if (!crlGenData->crlField) {
1451 return SECFailure;
1452 }
1453 crlGenData->contextId = structType;
1454 crlGenData->crlField->value = NULL((void*)0);
1455 crlGenData->crlField->updateCrlFn = &crlgen_updateCrlFn_field;
1456 crlGenData->crlField->setNextDataFn = &crlgen_setNextDataFn_field;
1457 break;
1458 case CRLGEN_RM_CERT_CONTEXT8:
1459 case CRLGEN_ADD_CERT_CONTEXT6:
1460 crlGenData->certEntry = PORT_New(CRLGENCertEntry)(CRLGENCertEntry *)PORT_Alloc_Util(sizeof(CRLGENCertEntry));
1461 if (!crlGenData->certEntry) {
1462 return SECFailure;
1463 }
1464 crlGenData->contextId = structType;
1465 crlGenData->certEntry->certId = 0;
1466 crlGenData->certEntry->revocationTime = NULL((void*)0);
1467 crlGenData->certEntry->updateCrlFn = &crlgen_updateCrlFn_cert;
1468 crlGenData->certEntry->setNextDataFn = &crlgen_setNextDataFn_cert;
1469 break;
1470 case CRLGEN_ADD_EXTENSION_CONTEXT4:
1471 crlGenData->extensionEntry = PORT_New(CRLGENExtensionEntry)(CRLGENExtensionEntry *)PORT_Alloc_Util(sizeof(CRLGENExtensionEntry
))
;
1472 if (!crlGenData->extensionEntry) {
1473 return SECFailure;
1474 }
1475 crlGenData->contextId = structType;
1476 crlGenData->extensionEntry->extData = NULL((void*)0);
1477 crlGenData->extensionEntry->nextUpdatedData = 0;
1478 crlGenData->extensionEntry->updateCrlFn =
1479 &crlgen_updateCrlFn_extension;
1480 crlGenData->extensionEntry->setNextDataFn =
1481 &crlgen_setNextDataFn_extension;
1482 break;
1483 case CRLGEN_UNKNOWN_CONTEXT0:
1484 break;
1485 default:
1486 crlgen_PrintError(crlGenData->parsedLineNum,
1487 "unknown context type: %d.\n", structType);
1488 PORT_Assert(0)((0)?((void)0):PR_Assert("0","crlgen.c",1488));
1489 return SECFailure;
1490 }
1491 return SECSuccess;
1492}
1493
1494/* Parser initialization function */
1495CRLGENGeneratorData *
1496CRLGEN_InitCrlGeneration(CERTSignedCrl *signCrl, PRFileDesc *src)
1497{
1498 CRLGENGeneratorData *crlGenData = NULL((void*)0);
1499
1500 PORT_Assert(signCrl && src)((signCrl && src)?((void)0):PR_Assert("signCrl && src"
,"crlgen.c",1500))
;
1501 if (!signCrl || !src) {
1502 PORT_SetErrorPORT_SetError_Util(SEC_ERROR_INVALID_ARGS);
1503 return NULL((void*)0);
1504 }
1505
1506 crlGenData = PORT_ZNew(CRLGENGeneratorData)(CRLGENGeneratorData *)PORT_ZAlloc_Util(sizeof(CRLGENGeneratorData
))
;
1507 if (!crlGenData) {
1508 return NULL((void*)0);
1509 }
1510
1511 crlGenData->entryDataHashTable =
1512 PL_NewHashTable(0, SECITEM_Hash, SECITEM_HashCompare,
1513 PL_CompareValues, NULL((void*)0), NULL((void*)0));
1514 if (!crlGenData->entryDataHashTable) {
1515 PORT_FreePORT_Free_Util(crlGenData);
1516 return NULL((void*)0);
1517 }
1518
1519 crlGenData->src = src;
1520 crlGenData->parsedLineNum = 1;
1521 crlGenData->contextId = CRLGEN_UNKNOWN_CONTEXT0;
1522 crlGenData->signCrl = signCrl;
1523 crlGenData->rangeFrom = 0;
1524 crlGenData->rangeTo = 0;
1525 crlGenData->crlExtHandle = NULL((void*)0);
1526
1527 PORT_SetErrorPORT_SetError_Util(0);
1528
1529 return crlGenData;
1530}
1531
1532void
1533CRLGEN_FinalizeCrlGeneration(CRLGENGeneratorData *crlGenData)
1534{
1535 if (!crlGenData)
1536 return;
1537 if (crlGenData->src)
1538 PR_Close(crlGenData->src);
1539 PL_HashTableDestroy(crlGenData->entryDataHashTable);
1540 PORT_FreePORT_Free_Util(crlGenData);
1541}