Bug Summary

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