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 addbuiltin.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/addbuiltin -ffunction-sections -fdata-sections -fcoverage-compilation-dir=/var/lib/jenkins/workspace/nss-scan-build/nss/cmd/addbuiltin -resource-dir /usr/lib/llvm-18/lib/clang/18 -D HAVE_STRERROR -D LINUX -D linux -D XP_UNIX -D XP_UNIX -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 -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 addbuiltin.c
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | #include "nssrenam.h" |
10 | #include "nss.h" |
11 | #include "cert.h" |
12 | #include "certdb.h" |
13 | #include "secutil.h" |
14 | #include "pk11func.h" |
15 | |
16 | #if defined(WIN32) |
17 | #include <fcntl.h> |
18 | #include <io.h> |
19 | #endif |
20 | |
21 | void |
22 | dumpbytes(unsigned char *buf, int len) |
23 | { |
24 | int i; |
25 | for (i = 0; i < len; i++) { |
26 | if ((i != 0) && ((i & 0xf) == 0)) { |
27 | printf("\n"); |
28 | } |
29 | printf("\\%03o", buf[i]); |
30 | } |
31 | printf("\n"); |
32 | } |
33 | |
34 | int |
35 | hasPositiveTrust(unsigned int trust) |
36 | { |
37 | if (trust & CERTDB_TRUSTED) { |
38 | if (trust & CERTDB_TRUSTED_CA) { |
39 | return PR_TRUE; |
40 | } else { |
41 | return PR_FALSE; |
42 | } |
43 | } else { |
44 | if (trust & CERTDB_TRUSTED_CA) { |
45 | return PR_TRUE; |
46 | } else if (trust & CERTDB_VALID_CA) { |
47 | return PR_TRUE; |
48 | } else if (trust & CERTDB_TERMINAL_RECORD) { |
49 | return PR_FALSE; |
50 | } else { |
51 | return PR_FALSE; |
52 | } |
53 | } |
54 | return PR_FALSE; |
55 | } |
56 | |
57 | char * |
58 | getTrustString(unsigned int trust) |
59 | { |
60 | if (trust & CERTDB_TRUSTED) { |
61 | if (trust & CERTDB_TRUSTED_CA) { |
62 | return "CKT_NSS_TRUSTED_DELEGATOR"; |
63 | } else { |
64 | return "CKT_NSS_TRUSTED"; |
65 | } |
66 | } else { |
67 | if (trust & CERTDB_TRUSTED_CA) { |
68 | return "CKT_NSS_TRUSTED_DELEGATOR"; |
69 | } else if (trust & CERTDB_VALID_CA) { |
70 | return "CKT_NSS_VALID_DELEGATOR"; |
71 | } else if (trust & CERTDB_TERMINAL_RECORD) { |
72 | return "CKT_NSS_NOT_TRUSTED"; |
73 | } else { |
74 | return "CKT_NSS_MUST_VERIFY_TRUST"; |
75 | } |
76 | } |
77 | } |
78 | |
79 | static const SEC_ASN1Template serialTemplate[] = { |
80 | { SEC_ASN1_INTEGER, offsetof(CERTCertificate, serialNumber) }, |
81 | { 0 } |
82 | }; |
83 | |
84 | void |
85 | print_crl_info(CERTName *name, SECItem *serial) |
86 | { |
87 | PRBool saveWrapeState = SECU_GetWrapEnabled(); |
88 | SECU_EnableWrap(PR_FALSE); |
89 | |
90 | SECU_PrintNameQuotesOptional(stdout, name, "# Issuer", 0, PR_FALSE); |
91 | printf("\n"); |
92 | |
93 | SECU_PrintInteger(stdout, serial, "# Serial Number", 0); |
94 | |
95 | SECU_EnableWrap(saveWrapeState); |
96 | } |
97 | |
98 | static SECStatus |
99 | ConvertCRLEntry(SECItem *sdder, PRInt32 crlentry, char *nickname) |
100 | { |
101 | int rv; |
102 | PLArenaPool *arena = NULL; |
103 | CERTSignedCrl *newCrl = NULL; |
104 | CERTCrlEntry *entry; |
105 | |
106 | CERTName *name = NULL; |
107 | SECItem *derName = NULL; |
108 | SECItem *serial = NULL; |
109 | |
110 | rv = SEC_ERROR_NO_MEMORY; |
111 | arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); |
112 | if (!arena) |
113 | return rv; |
114 | |
115 | newCrl = CERT_DecodeDERCrlWithFlags(arena, sdder, SEC_CRL_TYPE, |
116 | CRL_DECODE_DEFAULT_OPTIONS); |
117 | if (!newCrl) |
118 | return SECFailure; |
119 | |
120 | name = &newCrl->crl.name; |
121 | derName = &newCrl->crl.derName; |
122 | |
123 | if (newCrl->crl.entries != NULL) { |
124 | PRInt32 iv = 0; |
125 | while ((entry = newCrl->crl.entries[iv++]) != NULL) { |
126 | if (crlentry == iv) { |
127 | serial = &entry->serialNumber; |
128 | break; |
129 | } |
130 | } |
131 | } |
132 | |
133 | if (!name || !derName || !serial) |
134 | return SECFailure; |
135 | |
136 | printf("\n# Distrust \"%s\"\n", nickname); |
137 | print_crl_info(name, serial); |
138 | |
139 | printf("CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST\n"); |
140 | printf("CKA_TOKEN CK_BBOOL CK_TRUE\n"); |
141 | printf("CKA_PRIVATE CK_BBOOL CK_FALSE\n"); |
142 | printf("CKA_MODIFIABLE CK_BBOOL CK_FALSE\n"); |
143 | printf("CKA_LABEL UTF8 \"%s\"\n", nickname); |
144 | |
145 | printf("CKA_ISSUER MULTILINE_OCTAL\n"); |
146 | dumpbytes(derName->data, derName->len); |
147 | printf("END\n"); |
148 | printf("CKA_SERIAL_NUMBER MULTILINE_OCTAL\n"); |
149 | printf("\\002\\%03o", serial->len); |
150 | dumpbytes(serial->data, serial->len); |
151 | printf("END\n"); |
152 | |
153 | printf("CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_NOT_TRUSTED\n"); |
154 | printf("CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_NOT_TRUSTED\n"); |
155 | printf("CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_NOT_TRUSTED\n"); |
156 | printf("CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE\n"); |
157 | |
158 | PORT_FreeArena(arena, PR_FALSE); |
159 | return rv; |
160 | } |
161 | |
162 | void |
163 | print_info(SECItem *sdder, CERTCertificate *c) |
164 | { |
165 | PRBool saveWrapeState = SECU_GetWrapEnabled(); |
166 | SECU_EnableWrap(PR_FALSE); |
167 | |
168 | SECU_PrintNameQuotesOptional(stdout, &c->issuer, "# Issuer", 0, PR_FALSE); |
169 | printf("\n"); |
170 | |
171 | SECU_PrintInteger(stdout, &c->serialNumber, "# Serial Number", 0); |
172 | |
173 | SECU_PrintNameQuotesOptional(stdout, &c->subject, "# Subject", 0, PR_FALSE); |
174 | printf("\n"); |
175 | |
176 | SECU_PrintTimeChoice(stdout, &c->validity.notBefore, "# Not Valid Before", 0); |
177 | SECU_PrintTimeChoice(stdout, &c->validity.notAfter, "# Not Valid After ", 0); |
178 | |
179 | SECU_PrintFingerprints(stdout, sdder, "# Fingerprint", 0); |
180 | |
181 | SECU_EnableWrap(saveWrapeState); |
182 | } |
183 | |
184 | static SECStatus |
185 | ConvertCertificate(SECItem *sdder, char *nickname, CERTCertTrust *trust, |
186 | PRBool excludeCert, PRBool excludeHash) |
187 | { |
188 | SECStatus rv = SECSuccess; |
189 | CERTCertificate *cert; |
190 | unsigned char sha1_hash[SHA1_LENGTH]; |
191 | unsigned char md5_hash[MD5_LENGTH]; |
192 | SECItem *serial = NULL; |
193 | PRBool step_up = PR_FALSE; |
194 | const char *trust_info; |
195 | |
196 | cert = CERT_DecodeDERCertificate(sdder, PR_FALSE, nickname); |
197 | if (!cert) { |
198 | return SECFailure; |
199 | } |
200 | serial = SEC_ASN1EncodeItem(NULL, NULL, cert, serialTemplate); |
201 | if (!serial) { |
202 | return SECFailure; |
203 | } |
204 | |
205 | if (!excludeCert) { |
206 | printf("\n#\n# Certificate \"%s\"\n#\n", nickname); |
207 | print_info(sdder, cert); |
208 | printf("CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE\n"); |
209 | printf("CKA_TOKEN CK_BBOOL CK_TRUE\n"); |
210 | printf("CKA_PRIVATE CK_BBOOL CK_FALSE\n"); |
211 | printf("CKA_MODIFIABLE CK_BBOOL CK_FALSE\n"); |
212 | printf("CKA_LABEL UTF8 \"%s\"\n", nickname); |
213 | printf("CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509\n"); |
214 | printf("CKA_SUBJECT MULTILINE_OCTAL\n"); |
215 | dumpbytes(cert->derSubject.data, cert->derSubject.len); |
216 | printf("END\n"); |
217 | printf("CKA_ID UTF8 \"0\"\n"); |
218 | printf("CKA_ISSUER MULTILINE_OCTAL\n"); |
219 | dumpbytes(cert->derIssuer.data, cert->derIssuer.len); |
220 | printf("END\n"); |
221 | printf("CKA_SERIAL_NUMBER MULTILINE_OCTAL\n"); |
222 | dumpbytes(serial->data, serial->len); |
223 | printf("END\n"); |
224 | printf("CKA_VALUE MULTILINE_OCTAL\n"); |
225 | dumpbytes(sdder->data, sdder->len); |
226 | printf("END\n"); |
227 | if (hasPositiveTrust(trust->sslFlags) || |
228 | hasPositiveTrust(trust->emailFlags) || |
229 | hasPositiveTrust(trust->objectSigningFlags)) { |
230 | printf("CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE\n"); |
231 | } |
232 | printf("CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE\n"); |
233 | printf("CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE\n"); |
234 | } |
235 | |
236 | if ((trust->sslFlags | trust->emailFlags | trust->objectSigningFlags) == |
237 | CERTDB_TERMINAL_RECORD) |
238 | trust_info = "Distrust"; |
239 | else |
240 | trust_info = "Trust for"; |
241 | |
242 | printf("\n# %s \"%s\"\n", trust_info, nickname); |
243 | print_info(sdder, cert); |
244 | |
245 | printf("CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST\n"); |
246 | printf("CKA_TOKEN CK_BBOOL CK_TRUE\n"); |
247 | printf("CKA_PRIVATE CK_BBOOL CK_FALSE\n"); |
248 | printf("CKA_MODIFIABLE CK_BBOOL CK_FALSE\n"); |
249 | printf("CKA_LABEL UTF8 \"%s\"\n", nickname); |
250 | |
251 | if (!excludeHash) { |
252 | PK11_HashBuf(SEC_OID_SHA1, sha1_hash, sdder->data, sdder->len); |
253 | printf("CKA_CERT_SHA1_HASH MULTILINE_OCTAL\n"); |
254 | dumpbytes(sha1_hash, SHA1_LENGTH); |
255 | printf("END\n"); |
256 | PK11_HashBuf(SEC_OID_MD5, md5_hash, sdder->data, sdder->len); |
257 | printf("CKA_CERT_MD5_HASH MULTILINE_OCTAL\n"); |
258 | dumpbytes(md5_hash, MD5_LENGTH); |
259 | printf("END\n"); |
260 | } |
261 | |
262 | printf("CKA_ISSUER MULTILINE_OCTAL\n"); |
263 | dumpbytes(cert->derIssuer.data, cert->derIssuer.len); |
264 | printf("END\n"); |
265 | printf("CKA_SERIAL_NUMBER MULTILINE_OCTAL\n"); |
266 | dumpbytes(serial->data, serial->len); |
267 | printf("END\n"); |
268 | |
269 | printf("CKA_TRUST_SERVER_AUTH CK_TRUST %s\n", |
270 | getTrustString(trust->sslFlags)); |
271 | printf("CKA_TRUST_EMAIL_PROTECTION CK_TRUST %s\n", |
272 | getTrustString(trust->emailFlags)); |
273 | printf("CKA_TRUST_CODE_SIGNING CK_TRUST %s\n", |
274 | getTrustString(trust->objectSigningFlags)); |
275 | #ifdef notdef |
276 | printf("CKA_TRUST_CLIENT_AUTH CK_TRUST CKT_NSS_TRUSTED\n"); |
277 | printf("CKA_TRUST_DIGITAL_SIGNATURE CK_TRUST CKT_NSS_TRUSTED_DELEGATOR\n"); |
278 | printf("CKA_TRUST_NON_REPUDIATION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR\n"); |
279 | printf("CKA_TRUST_KEY_ENCIPHERMENT CK_TRUST CKT_NSS_TRUSTED_DELEGATOR\n"); |
280 | printf("CKA_TRUST_DATA_ENCIPHERMENT CK_TRUST CKT_NSS_TRUSTED_DELEGATOR\n"); |
281 | printf("CKA_TRUST_KEY_AGREEMENT CK_TRUST CKT_NSS_TRUSTED_DELEGATOR\n"); |
282 | printf("CKA_TRUST_KEY_CERT_SIGN CK_TRUST CKT_NSS_TRUSTED_DELEGATOR\n"); |
283 | #endif |
284 | |
285 | step_up = (trust->sslFlags & CERTDB_GOVT_APPROVED_CA); |
286 | printf("CKA_TRUST_STEP_UP_APPROVED CK_BBOOL %s\n", |
287 | step_up ? "CK_TRUE" : "CK_FALSE"); |
288 | |
289 | PORT_Free(sdder->data); |
290 | return (rv); |
291 | } |
292 | |
293 | void |
294 | printheader() |
295 | { |
296 | printf("# \n" |
297 | "# This Source Code Form is subject to the terms of the Mozilla Public\n" |
298 | "# License, v. 2.0. If a copy of the MPL was not distributed with this\n" |
299 | "# file, You can obtain one at http://mozilla.org/MPL/2.0/.\n" |
300 | "#\n" |
301 | "# certdata.txt\n" |
302 | "#\n" |
303 | "# This file contains the object definitions for the certs and other\n" |
304 | "# information \"built into\" NSS.\n" |
305 | "#\n" |
306 | "# Object definitions:\n" |
307 | "#\n" |
308 | "# Certificates\n" |
309 | "#\n" |
310 | "# -- Attribute -- -- type -- -- value --\n" |
311 | "# CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE\n" |
312 | "# CKA_TOKEN CK_BBOOL CK_TRUE\n" |
313 | "# CKA_PRIVATE CK_BBOOL CK_FALSE\n" |
314 | "# CKA_MODIFIABLE CK_BBOOL CK_FALSE\n" |
315 | "# CKA_LABEL UTF8 (varies)\n" |
316 | "# CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509\n" |
317 | "# CKA_SUBJECT DER+base64 (varies)\n" |
318 | "# CKA_ID byte array (varies)\n" |
319 | "# CKA_ISSUER DER+base64 (varies)\n" |
320 | "# CKA_SERIAL_NUMBER DER+base64 (varies)\n" |
321 | "# CKA_VALUE DER+base64 (varies)\n" |
322 | "# CKA_NSS_EMAIL ASCII7 (unused here)\n" |
323 | "# CKA_NSS_SERVER_DISTRUST_AFTER DER+base64 (varies)\n" |
324 | "# CKA_NSS_EMAIL_DISTRUST_AFTER DER+base64 (varies)\n" |
325 | "#\n" |
326 | "# Trust\n" |
327 | "#\n" |
328 | "# -- Attribute -- -- type -- -- value --\n" |
329 | "# CKA_CLASS CK_OBJECT_CLASS CKO_TRUST\n" |
330 | "# CKA_TOKEN CK_BBOOL CK_TRUE\n" |
331 | "# CKA_PRIVATE CK_BBOOL CK_FALSE\n" |
332 | "# CKA_MODIFIABLE CK_BBOOL CK_FALSE\n" |
333 | "# CKA_LABEL UTF8 (varies)\n" |
334 | "# CKA_ISSUER DER+base64 (varies)\n" |
335 | "# CKA_SERIAL_NUMBER DER+base64 (varies)\n" |
336 | "# CKA_CERT_HASH binary+base64 (varies)\n" |
337 | "# CKA_EXPIRES CK_DATE (not used here)\n" |
338 | "# CKA_TRUST_DIGITAL_SIGNATURE CK_TRUST (varies)\n" |
339 | "# CKA_TRUST_NON_REPUDIATION CK_TRUST (varies)\n" |
340 | "# CKA_TRUST_KEY_ENCIPHERMENT CK_TRUST (varies)\n" |
341 | "# CKA_TRUST_DATA_ENCIPHERMENT CK_TRUST (varies)\n" |
342 | "# CKA_TRUST_KEY_AGREEMENT CK_TRUST (varies)\n" |
343 | "# CKA_TRUST_KEY_CERT_SIGN CK_TRUST (varies)\n" |
344 | "# CKA_TRUST_CRL_SIGN CK_TRUST (varies)\n" |
345 | "# CKA_TRUST_SERVER_AUTH CK_TRUST (varies)\n" |
346 | "# CKA_TRUST_CLIENT_AUTH CK_TRUST (varies)\n" |
347 | "# CKA_TRUST_CODE_SIGNING CK_TRUST (varies)\n" |
348 | "# CKA_TRUST_EMAIL_PROTECTION CK_TRUST (varies)\n" |
349 | "# CKA_TRUST_IPSEC_END_SYSTEM CK_TRUST (varies)\n" |
350 | "# CKA_TRUST_IPSEC_TUNNEL CK_TRUST (varies)\n" |
351 | "# CKA_TRUST_IPSEC_USER CK_TRUST (varies)\n" |
352 | "# CKA_TRUST_TIME_STAMPING CK_TRUST (varies)\n" |
353 | "# (other trust attributes can be defined)\n" |
354 | "#\n" |
355 | "\n" |
356 | "#\n" |
357 | "# The object to tell NSS that this is a root list and we don't\n" |
358 | "# have to go looking for others.\n" |
359 | "#\n" |
360 | "BEGINDATA\n" |
361 | "CKA_CLASS CK_OBJECT_CLASS CKO_NSS_BUILTIN_ROOT_LIST\n" |
362 | "CKA_TOKEN CK_BBOOL CK_TRUE\n" |
363 | "CKA_PRIVATE CK_BBOOL CK_FALSE\n" |
364 | "CKA_MODIFIABLE CK_BBOOL CK_FALSE\n" |
365 | "CKA_LABEL UTF8 \"Mozilla Builtin Roots\"\n"); |
366 | } |
367 | |
368 | static void |
369 | Usage(char *progName) |
370 | { |
371 | fprintf(stderr, "%s -t trust -n nickname [-i certfile] [-c] [-h]\n", progName); |
372 | fprintf(stderr, |
373 | "\tRead a der-encoded cert from certfile or stdin, and output\n" |
374 | "\tit to stdout in a format suitable for the builtin root module.\n" |
375 | "\tExample: %s -n MyCA -t \"C,C,C\" -i myca.der >> certdata.txt\n", |
376 | progName); |
377 | fprintf(stderr, "%s -D -n label [-i certfile]\n", progName); |
378 | fprintf(stderr, |
379 | "\tRead a der-encoded cert from certfile or stdin, and output\n" |
380 | "\ta distrust record.\n" |
381 | "\t(-D is equivalent to -t p,p,p -c -h)\n"); |
382 | fprintf(stderr, "%s -C -e crl-entry-number -n label [-i crlfile]\n", progName); |
383 | fprintf(stderr, |
384 | "\tRead a CRL from crlfile or stdin, and output\n" |
385 | "\ta distrust record (issuer+serial).\n" |
386 | "\t(-C implies -c -h)\n"); |
387 | fprintf(stderr, "%-15s trust flags (cCTpPuw).\n", "-t trust"); |
388 | fprintf(stderr, "%-15s nickname to assign to builtin cert, or\n", |
389 | "-n nickname"); |
390 | fprintf(stderr, "%-15s a label for the distrust record.\n", ""); |
391 | fprintf(stderr, "%-15s exclude the certificate (only add a trust record)\n", "-c"); |
392 | fprintf(stderr, "%-15s exclude hash from trust record\n", "-h"); |
393 | fprintf(stderr, "%-15s (useful to distrust any matching issuer/serial)\n", ""); |
394 | fprintf(stderr, "%-15s (not allowed when adding positive trust)\n", ""); |
395 | fprintf(stderr, "%-15s a CRL entry number, as shown by \"crlutil -S\"\n", "-e"); |
396 | fprintf(stderr, "%-15s input file to read (default stdin)\n", "-i file"); |
397 | fprintf(stderr, "%-15s (pipe through atob if the cert is b64-encoded)\n", ""); |
398 | fprintf(stderr, "%-15s convert a timestamp to DER, and output.\n", "-d timestamp"); |
399 | fprintf(stderr, "%-15s useful to fill server and email distrust fields\n", ""); |
400 | fprintf(stderr, "%-15s Example: %s -d 1561939200\n", "", progName); |
401 | fprintf(stderr, "%-15s NOTE: The informed timestamp are interpreted as seconds\n", ""); |
402 | fprintf(stderr, "%-15s since unix epoch.\n", ""); |
403 | fprintf(stderr, "%-15s TIP: date -d \"2019-07-01 00:00:00 UTC\" +%%s\n", ""); |
404 | exit(-1); |
405 | } |
406 | |
407 | enum { |
408 | opt_Input = 0, |
409 | opt_Nickname, |
410 | opt_Trust, |
411 | opt_Distrust, |
412 | opt_ExcludeCert, |
413 | opt_ExcludeHash, |
414 | opt_DistrustCRL, |
415 | opt_CRLEntry, |
416 | opt_ConvertDate |
417 | }; |
418 | |
419 | static secuCommandFlag addbuiltin_options[] = { |
420 | { 'i', PR_TRUE, 0, PR_FALSE }, |
421 | { 'n', PR_TRUE, 0, PR_FALSE }, |
422 | { 't', PR_TRUE, 0, PR_FALSE }, |
423 | { 'D', PR_FALSE, 0, PR_FALSE }, |
424 | { 'c', PR_FALSE, 0, PR_FALSE }, |
425 | { 'h', PR_FALSE, 0, PR_FALSE }, |
426 | { 'C', PR_FALSE, 0, PR_FALSE }, |
427 | { 'e', PR_TRUE, 0, PR_FALSE }, |
428 | { 'd', PR_TRUE, 0, PR_FALSE }, |
429 | }; |
430 | |
431 | int |
432 | main(int argc, char **argv) |
433 | { |
434 | SECStatus rv; |
435 | char *nickname = NULL; |
436 | char *trusts = NULL; |
437 | char *progName; |
438 | PRFileDesc *infile; |
439 | CERTCertTrust trust = { 0 }; |
440 | SECItem derItem = { 0 }; |
441 | PRInt32 crlentry = 0; |
442 | PRInt32 mutuallyExclusiveOpts = 0; |
443 | PRBool decodeTrust = PR_FALSE; |
444 | |
445 | secuCommand addbuiltin = { 0 }; |
446 | addbuiltin.numOptions = sizeof(addbuiltin_options) / sizeof(secuCommandFlag); |
447 | addbuiltin.options = addbuiltin_options; |
448 | |
449 | progName = strrchr(argv[0], '/'); |
450 | progName = progName ? progName + 1 : argv[0]; |
| 1 | Assuming 'progName' is non-null | |
|
| |
451 | |
452 | rv = SECU_ParseCommandLine(argc, argv, progName, &addbuiltin); |
453 | |
454 | if (rv != SECSuccess) |
| 3 | | Assuming 'rv' is equal to SECSuccess | |
|
| |
455 | Usage(progName); |
456 | |
457 | if (addbuiltin.options[opt_ConvertDate].activated) { |
| 5 | | Assuming field 'activated' is 0 | |
|
| |
458 | char *endPtr; |
459 | PRTime distrustTimestamp = strtol(addbuiltin.options[opt_ConvertDate].arg, &endPtr, 0) * PR_USEC_PER_SEC; |
460 | if (*endPtr != '\0' && distrustTimestamp > 0) { |
461 | Usage(progName); |
462 | exit(1); |
463 | } |
464 | SECItem encTime; |
465 | DER_EncodeTimeChoice(NULL, &encTime, distrustTimestamp); |
466 | SECU_PrintTimeChoice(stdout, &encTime, "The timestamp represents this date", 0); |
467 | printf("Locate the entry of the desired certificate in certdata.txt\n" |
468 | "Erase the CKA_NSS_[SERVER|EMAIL]_DISTRUST_AFTER CK_BBOOL CK_FALSE\n" |
469 | "And override with the following respective entry:\n\n"); |
470 | SECU_PrintTimeChoice(stdout, &encTime, "# For Server Distrust After", 0); |
471 | printf("CKA_NSS_SERVER_DISTRUST_AFTER MULTILINE_OCTAL\n"); |
472 | dumpbytes(encTime.data, encTime.len); |
473 | printf("END\n"); |
474 | SECU_PrintTimeChoice(stdout, &encTime, "# For Email Distrust After", 0); |
475 | printf("CKA_NSS_EMAIL_DISTRUST_AFTER MULTILINE_OCTAL\n"); |
476 | dumpbytes(encTime.data, encTime.len); |
477 | printf("END\n"); |
478 | exit(0); |
479 | } |
480 | |
481 | if (addbuiltin.options[opt_Trust].activated) |
| 7 | | Assuming field 'activated' is 0 | |
|
| |
482 | ++mutuallyExclusiveOpts; |
483 | if (addbuiltin.options[opt_Distrust].activated) |
| 9 | | Assuming field 'activated' is 0 | |
|
| |
484 | ++mutuallyExclusiveOpts; |
485 | if (addbuiltin.options[opt_DistrustCRL].activated) |
| 11 | | Assuming field 'activated' is not equal to 0 | |
|
| |
486 | ++mutuallyExclusiveOpts; |
487 | |
488 | if (mutuallyExclusiveOpts != 1) { |
| |
489 | fprintf(stderr, "%s: you must specify exactly one of -t or -D or -C\n", |
490 | progName); |
491 | Usage(progName); |
492 | } |
493 | |
494 | if (addbuiltin.options[opt_DistrustCRL].activated) { |
| |
495 | if (!addbuiltin.options[opt_CRLEntry].activated) { |
| 15 | | Assuming field 'activated' is not equal to 0 | |
|
| |
496 | fprintf(stderr, "%s: you must specify the CRL entry number.\n", |
497 | progName); |
498 | Usage(progName); |
499 | } else { |
500 | crlentry = atoi(addbuiltin.options[opt_CRLEntry].arg); |
501 | if (crlentry < 1) { |
| 17 | | Assuming 'crlentry' is >= 1 | |
|
| |
502 | fprintf(stderr, "%s: The CRL entry number must be > 0.\n", |
503 | progName); |
504 | Usage(progName); |
505 | } |
506 | } |
507 | } |
508 | |
509 | if (!addbuiltin.options[opt_Nickname].activated) { |
| 19 | | Assuming field 'activated' is not equal to 0 | |
|
| |
510 | fprintf(stderr, "%s: you must specify parameter -n (a nickname or a label).\n", |
511 | progName); |
512 | Usage(progName); |
513 | } |
514 | |
515 | if (addbuiltin.options[opt_Input].activated) { |
| 21 | | Assuming field 'activated' is 0 | |
|
| |
516 | infile = PR_Open(addbuiltin.options[opt_Input].arg, PR_RDONLY, 00660); |
517 | if (!infile) { |
518 | fprintf(stderr, "%s: failed to open input file.\n", progName); |
519 | exit(1); |
520 | } |
521 | } else { |
522 | #if defined(WIN32) |
523 | |
524 | |
525 | |
526 | |
527 | |
528 | int smrv = _setmode(_fileno(stdin), _O_BINARY); |
529 | if (smrv == -1) { |
530 | fprintf(stderr, |
531 | "%s: Cannot change stdin to binary mode. Use -i option instead.\n", |
532 | progName); |
533 | exit(1); |
534 | } |
535 | #endif |
536 | infile = PR_STDIN; |
537 | } |
538 | |
539 | #if defined(WIN32) |
540 | |
541 | |
542 | |
543 | { |
544 | int smrv = _setmode(_fileno(stdout), _O_BINARY); |
545 | if (smrv == -1) { |
546 | fprintf(stderr, "%s: Cannot change stdout to binary mode.\n", progName); |
547 | exit(1); |
548 | } |
549 | } |
550 | #endif |
551 | |
552 | nickname = strdup(addbuiltin.options[opt_Nickname].arg); |
| |
553 | |
554 | if (NSS_NoDB_Init(NULL) != SECSuccess) { |
| 24 | | Assuming the condition is false | |
|
555 | exit(1); |
556 | } |
557 | |
558 | if (addbuiltin.options[opt_Distrust].activated || |
| 25 | | Assuming field 'activated' is 0 | |
|
| |
559 | addbuiltin.options[opt_DistrustCRL].activated) { |
| 26 | | Assuming field 'activated' is 0 | |
|
560 | addbuiltin.options[opt_ExcludeCert].activated = PR_TRUE; |
561 | addbuiltin.options[opt_ExcludeHash].activated = PR_TRUE; |
562 | } |
563 | |
564 | if (addbuiltin.options[opt_Distrust].activated) { |
| |
565 | trusts = strdup("p,p,p"); |
566 | decodeTrust = PR_TRUE; |
567 | } else if (addbuiltin.options[opt_Trust].activated) { |
| 29 | | Assuming field 'activated' is 0 | |
|
| |
568 | trusts = strdup(addbuiltin.options[opt_Trust].arg); |
569 | decodeTrust = PR_TRUE; |
570 | } |
571 | |
572 | if (decodeTrust) { |
573 | rv = CERT_DecodeTrustString(&trust, trusts); |
574 | if (rv) { |
575 | fprintf(stderr, "%s: incorrectly formatted trust string.\n", progName); |
576 | Usage(progName); |
577 | } |
578 | } |
579 | |
580 | if (addbuiltin.options[opt_Trust].activated && |
581 | addbuiltin.options[opt_ExcludeHash].activated) { |
582 | if ((trust.sslFlags | trust.emailFlags | trust.objectSigningFlags) != |
583 | CERTDB_TERMINAL_RECORD) { |
584 | fprintf(stderr, "%s: Excluding the hash only allowed with distrust.\n", progName); |
585 | Usage(progName); |
586 | } |
587 | } |
588 | |
589 | SECU_FileToItem(&derItem, infile); |
590 | |
591 | |
592 | |
593 | if (addbuiltin.options[opt_DistrustCRL].activated) { |
| 31 | | Assuming field 'activated' is not equal to 0 | |
|
| |
594 | rv = ConvertCRLEntry(&derItem, crlentry, nickname); |
| 33 | | Potential leak of memory pointed to by 'nickname' |
|
595 | } else { |
596 | rv = ConvertCertificate(&derItem, nickname, &trust, |
597 | addbuiltin.options[opt_ExcludeCert].activated, |
598 | addbuiltin.options[opt_ExcludeHash].activated); |
599 | if (rv) { |
600 | fprintf(stderr, "%s: failed to convert certificate.\n", progName); |
601 | exit(1); |
602 | } |
603 | } |
604 | |
605 | if (NSS_Shutdown() != SECSuccess) { |
606 | exit(1); |
607 | } |
608 | |
609 | return (SECSuccess); |
610 | } |