addbuiltin.c (22456B)
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 * Tool for converting builtin CA certs. 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); /* 002: type integer; len >=3 digits */ 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 { /* opt_Input */ 'i', PR_TRUE, 0, PR_FALSE }, 421 { /* opt_Nickname */ 'n', PR_TRUE, 0, PR_FALSE }, 422 { /* opt_Trust */ 't', PR_TRUE, 0, PR_FALSE }, 423 { /* opt_Distrust */ 'D', PR_FALSE, 0, PR_FALSE }, 424 { /* opt_ExcludeCert */ 'c', PR_FALSE, 0, PR_FALSE }, 425 { /* opt_ExcludeHash */ 'h', PR_FALSE, 0, PR_FALSE }, 426 { /* opt_DistrustCRL */ 'C', PR_FALSE, 0, PR_FALSE }, 427 { /* opt_CRLEntry */ 'e', PR_TRUE, 0, PR_FALSE }, 428 { /* opt_ConvertDate */ '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]; 451 452 rv = SECU_ParseCommandLine(argc, argv, progName, &addbuiltin); 453 454 if (rv != SECSuccess) 455 Usage(progName); 456 457 if (addbuiltin.options[opt_ConvertDate].activated) { 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) 482 ++mutuallyExclusiveOpts; 483 if (addbuiltin.options[opt_Distrust].activated) 484 ++mutuallyExclusiveOpts; 485 if (addbuiltin.options[opt_DistrustCRL].activated) 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) { 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) { 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) { 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) { 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 /* If we're going to read binary data from stdin, we must put stdin 524 ** into O_BINARY mode or else incoming \r\n's will become \n's, 525 ** and latin-1 characters will be altered. 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 /* We must put stdout into O_BINARY mode or else the output will include 541 ** carriage returns. 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) { 555 exit(1); 556 } 557 558 if (addbuiltin.options[opt_Distrust].activated || 559 addbuiltin.options[opt_DistrustCRL].activated) { 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) { 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 /*printheader();*/ 592 593 if (addbuiltin.options[opt_DistrustCRL].activated) { 594 rv = ConvertCRLEntry(&derItem, crlentry, 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 }