"Fossies" - the Fresh Open Source Software Archive

Member "nss-3.55/nss/cmd/addbuiltin/addbuiltin.c" (24 Jul 2020, 22446 Bytes) of package /linux/misc/nss-3.55.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "addbuiltin.c" see the Fossies "Dox" file reference documentation.

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