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-19/lib/clang/19 -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/Linux6.12_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-19/lib/clang/19/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-01-06-222215-268153-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 | } |