security/nss/cmd/p7content/p7content.c

Wed, 31 Dec 2014 06:55:50 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:55:50 +0100
changeset 2
7e26c7da4463
permissions
-rw-r--r--

Added tag UPSTREAM_283F7C6 for changeset ca08bd8f51b2

     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/. */
     5 /*
     6  * p7content -- A command to display pkcs7 content.
     7  */
     9 #include "nspr.h"
    10 #include "secutil.h"
    11 #include "plgetopt.h"
    12 #include "secpkcs7.h"
    13 #include "cert.h"
    14 #include "certdb.h"
    15 #include "nss.h"
    16 #include "pk11pub.h"
    18 #if defined(XP_UNIX)
    19 #include <unistd.h>
    20 #endif
    22 #include <stdio.h>
    23 #include <string.h>
    25 #if (defined(XP_WIN) && !defined(WIN32)) || (defined(__sun) && !defined(SVR4))
    26 extern int fwrite(char *, size_t, size_t, FILE*);
    27 extern int fprintf(FILE *, char *, ...);
    28 #endif
    32 static void
    33 Usage(char *progName)
    34 {
    35     fprintf(stderr,
    36 	    "Usage:  %s [-d dbdir] [-i input] [-o output]\n",
    37 	    progName);
    38     fprintf(stderr,
    39 	    "%-20s Key/Cert database directory (default is ~/.netscape)\n",
    40 	    "-d dbdir");
    41     fprintf(stderr, "%-20s Define an input file to use (default is stdin)\n",
    42 	    "-i input");
    43     fprintf(stderr, "%-20s Define an output file to use (default is stdout)\n",
    44 	    "-o output");
    45     exit(-1);
    46 }
    48 static PRBool saw_content;
    49 static secuPWData  pwdata          = { PW_NONE, 0 };
    51 static void
    52 PrintBytes(void *arg, const char *buf, unsigned long len)
    53 {
    54     FILE *out;
    56     out = arg; 
    57     fwrite (buf, len, 1, out);
    59     saw_content = PR_TRUE;
    60 }
    62 /*
    63  * XXX Someday we may want to do real policy stuff here.  This allows
    64  * anything to be decrypted, which is okay for a test program but does
    65  * not set an example of how a real client with a real policy would
    66  * need to do it.
    67  */
    68 static PRBool
    69 decryption_allowed(SECAlgorithmID *algid, PK11SymKey *key)
    70 {
    71     return PR_TRUE;
    72 }
    74 int
    75 DecodeAndPrintFile(FILE *out, PRFileDesc *in, char *progName)
    76 {
    77     SECItem derdata;
    78     SEC_PKCS7ContentInfo *cinfo = NULL;
    79     SEC_PKCS7DecoderContext *dcx;
    81     if (SECU_ReadDERFromFile(&derdata, in, PR_FALSE, PR_FALSE)) {
    82         SECU_PrintError(progName, "error converting der");
    83 	return -1;
    84     }
    86     fprintf(out,
    87 	    "Content printed between bars (newline added before second bar):");
    88     fprintf(out, "\n---------------------------------------------\n");
    90     saw_content = PR_FALSE;
    91     dcx = SEC_PKCS7DecoderStart(PrintBytes, out, NULL, &pwdata,
    92 				NULL, NULL, decryption_allowed);
    93     if (dcx != NULL) {
    94 #if 0	/* Test that decoder works when data is really streaming in. */
    95 	{
    96 	    unsigned long i;
    97 	    for (i = 0; i < derdata.len; i++)
    98 		SEC_PKCS7DecoderUpdate(dcx, derdata.data + i, 1);
    99 	}
   100 #else
   101 	SEC_PKCS7DecoderUpdate(dcx, (char *)derdata.data, derdata.len);
   102 #endif
   103 	cinfo = SEC_PKCS7DecoderFinish(dcx);
   104     }
   106     fprintf(out, "\n---------------------------------------------\n");
   108     if (cinfo == NULL)
   109 	return -1;
   111     fprintf(out, "Content was%s encrypted.\n",
   112 	    SEC_PKCS7ContentIsEncrypted(cinfo) ? "" : " not");
   114     if (SEC_PKCS7ContentIsSigned(cinfo)) {
   115 	char *signer_cname, *signer_ename;
   116 	SECItem *signing_time;
   118 	if (saw_content) {
   119 	    fprintf(out, "Signature is ");
   120 	    PORT_SetError(0);
   121 	    if (SEC_PKCS7VerifySignature(cinfo, certUsageEmailSigner, PR_FALSE))
   122 		fprintf(out, "valid.\n");
   123 	    else
   124 		fprintf(out, "invalid (Reason: %s).\n",
   125 			SECU_Strerror(PORT_GetError()));
   126 	} else {
   127 	    fprintf(out,
   128 		    "Content is detached; signature cannot be verified.\n");
   129 	}
   131 	signer_cname = SEC_PKCS7GetSignerCommonName(cinfo);
   132 	if (signer_cname != NULL) {
   133 	    fprintf(out, "The signer's common name is %s\n", signer_cname);
   134 	    PORT_Free(signer_cname);
   135 	} else {
   136 	    fprintf(out, "No signer common name.\n");
   137 	}
   139 	signer_ename = SEC_PKCS7GetSignerEmailAddress(cinfo);
   140 	if (signer_ename != NULL) {
   141 	    fprintf(out, "The signer's email address is %s\n", signer_ename);
   142 	    PORT_Free(signer_ename);
   143 	} else {
   144 	    fprintf(out, "No signer email address.\n");
   145 	}
   147 	signing_time = SEC_PKCS7GetSigningTime(cinfo);
   148 	if (signing_time != NULL) {
   149 	    SECU_PrintTimeChoice(out, signing_time, "Signing time", 0);
   150 	} else {
   151 	    fprintf(out, "No signing time included.\n");
   152 	}
   153     } else {
   154 	fprintf(out, "Content was not signed.\n");
   155     }
   157     fprintf(out, "There were%s certs or crls included.\n",
   158 	    SEC_PKCS7ContainsCertsOrCrls(cinfo) ? "" : " no");
   160     SEC_PKCS7DestroyContentInfo(cinfo);
   161     return 0;
   162 }
   164 /*
   165  * Print the contents of a PKCS7 message, indicating signatures, etc.
   166  */
   168 int
   169 main(int argc, char **argv)
   170 {
   171     char *progName;
   172     FILE *outFile;
   173     PRFileDesc *inFile;
   174     PLOptState *optstate;
   175     PLOptStatus status;
   176     SECStatus rv;
   178     progName = strrchr(argv[0], '/');
   179     progName = progName ? progName+1 : argv[0];
   181     inFile = NULL;
   182     outFile = NULL;
   184     /*
   185      * Parse command line arguments
   186      */
   187     optstate = PL_CreateOptState(argc, argv, "d:i:o:p:f:");
   188     while ((status = PL_GetNextOpt(optstate)) == PL_OPT_OK) {
   189 	switch (optstate->option) {
   190 	  case 'd':
   191 	    SECU_ConfigDirectory(optstate->value);
   192 	    break;
   194 	  case 'i':
   195 	    inFile = PR_Open(optstate->value, PR_RDONLY, 0);
   196 	    if (!inFile) {
   197 		fprintf(stderr, "%s: unable to open \"%s\" for reading\n",
   198 			progName, optstate->value);
   199 		return -1;
   200 	    }
   201 	    break;
   203 	  case 'o':
   204 	    outFile = fopen(optstate->value, "w");
   205 	    if (!outFile) {
   206 		fprintf(stderr, "%s: unable to open \"%s\" for writing\n",
   207 			progName, optstate->value);
   208 		return -1;
   209 	    }
   210 	    break;
   212 	  case 'p':
   213             pwdata.source = PW_PLAINTEXT;
   214             pwdata.data = PORT_Strdup (optstate->value);
   215             break;
   217           case 'f':
   218             pwdata.source = PW_FROMFILE;
   219             pwdata.data = PORT_Strdup (optstate->value);
   220             break;
   222 	  default:
   223 	    Usage(progName);
   224 	    break;
   225 	}
   226     }
   227     if (status == PL_OPT_BAD)
   228 	Usage(progName);
   230     if (!inFile) inFile = PR_STDIN;
   231     if (!outFile) outFile = stdout;
   233     /* Call the initialization routines */
   234     PR_Init(PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1);
   235     rv = NSS_Init(SECU_ConfigDirectory(NULL));
   236     if (rv != SECSuccess) {
   237 	SECU_PrintPRandOSError(progName);
   238 	return -1;
   239     }
   241     PK11_SetPasswordFunc(SECU_GetModulePassword);
   243     if (DecodeAndPrintFile(outFile, inFile, progName)) {
   244 	SECU_PrintError(progName, "problem decoding data");
   245 	return -1;
   246     }
   248     if (NSS_Shutdown() != SECSuccess) {
   249         exit(1);
   250     }
   252     return 0;
   253 }

mercurial