nss: import at 3.0.1 beta 1
[mozilla-nss.git] / security / nss / cmd / p7content / p7content.c
blob86ea9f991ae5d4c73012aa0b193dc9c63f03e14f
1 /* ***** BEGIN LICENSE BLOCK *****
2 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 * The contents of this file are subject to the Mozilla Public License Version
5 * 1.1 (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 * http://www.mozilla.org/MPL/
9 * Software distributed under the License is distributed on an "AS IS" basis,
10 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
11 * for the specific language governing rights and limitations under the
12 * License.
14 * The Original Code is the Netscape security libraries.
16 * The Initial Developer of the Original Code is
17 * Netscape Communications Corporation.
18 * Portions created by the Initial Developer are Copyright (C) 1994-2000
19 * the Initial Developer. All Rights Reserved.
21 * Contributor(s):
23 * Alternatively, the contents of this file may be used under the terms of
24 * either the GNU General Public License Version 2 or later (the "GPL"), or
25 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
26 * in which case the provisions of the GPL or the LGPL are applicable instead
27 * of those above. If you wish to allow use of your version of this file only
28 * under the terms of either the GPL or the LGPL, and not to allow others to
29 * use your version of this file under the terms of the MPL, indicate your
30 * decision by deleting the provisions above and replace them with the notice
31 * and other provisions required by the GPL or the LGPL. If you do not delete
32 * the provisions above, a recipient may use your version of this file under
33 * the terms of any one of the MPL, the GPL or the LGPL.
35 * ***** END LICENSE BLOCK ***** */
38 * p7content -- A command to display pkcs7 content.
40 * $Id: p7content.c,v 1.11 2007/01/25 00:52:25 alexei.volkov.bugs%sun.com Exp $
43 #include "nspr.h"
44 #include "secutil.h"
45 #include "plgetopt.h"
46 #include "secpkcs7.h"
47 #include "cert.h"
48 #include "certdb.h"
49 #include "nss.h"
50 #include "pk11pub.h"
52 #if defined(XP_UNIX)
53 #include <unistd.h>
54 #endif
56 #include <stdio.h>
57 #include <string.h>
59 #if (defined(XP_WIN) && !defined(WIN32)) || (defined(__sun) && !defined(SVR4))
60 extern int fwrite(char *, size_t, size_t, FILE*);
61 extern int fprintf(FILE *, char *, ...);
62 #endif
66 static void
67 Usage(char *progName)
69 fprintf(stderr,
70 "Usage: %s [-d dbdir] [-i input] [-o output]\n",
71 progName);
72 fprintf(stderr,
73 "%-20s Key/Cert database directory (default is ~/.netscape)\n",
74 "-d dbdir");
75 fprintf(stderr, "%-20s Define an input file to use (default is stdin)\n",
76 "-i input");
77 fprintf(stderr, "%-20s Define an output file to use (default is stdout)\n",
78 "-o output");
79 exit(-1);
82 static PRBool saw_content;
84 static void
85 PrintBytes(void *arg, const char *buf, unsigned long len)
87 FILE *out;
89 out = arg;
90 fwrite (buf, len, 1, out);
92 saw_content = PR_TRUE;
96 * XXX Someday we may want to do real policy stuff here. This allows
97 * anything to be decrypted, which is okay for a test program but does
98 * not set an example of how a real client with a real policy would
99 * need to do it.
101 static PRBool
102 decryption_allowed(SECAlgorithmID *algid, PK11SymKey *key)
104 return PR_TRUE;
107 char* KeyDbPassword = 0;
110 char* MyPK11PasswordFunc (PK11SlotInfo *slot, PRBool retry, void* arg)
112 char *ret=0;
114 if (retry == PR_TRUE)
115 return NULL;
116 ret = PL_strdup (KeyDbPassword);
117 return ret;
121 DecodeAndPrintFile(FILE *out, PRFileDesc *in, char *progName)
123 SECItem derdata;
124 SEC_PKCS7ContentInfo *cinfo = NULL;
125 SEC_PKCS7DecoderContext *dcx;
127 if (SECU_ReadDERFromFile(&derdata, in, PR_FALSE)) {
128 SECU_PrintError(progName, "error converting der");
129 return -1;
132 fprintf(out,
133 "Content printed between bars (newline added before second bar):");
134 fprintf(out, "\n---------------------------------------------\n");
136 saw_content = PR_FALSE;
137 dcx = SEC_PKCS7DecoderStart(PrintBytes, out, NULL, NULL,
138 NULL, NULL, decryption_allowed);
139 if (dcx != NULL) {
140 #if 0 /* Test that decoder works when data is really streaming in. */
142 unsigned long i;
143 for (i = 0; i < derdata.len; i++)
144 SEC_PKCS7DecoderUpdate(dcx, derdata.data + i, 1);
146 #else
147 SEC_PKCS7DecoderUpdate(dcx, (char *)derdata.data, derdata.len);
148 #endif
149 cinfo = SEC_PKCS7DecoderFinish(dcx);
152 fprintf(out, "\n---------------------------------------------\n");
154 if (cinfo == NULL)
155 return -1;
157 fprintf(out, "Content was%s encrypted.\n",
158 SEC_PKCS7ContentIsEncrypted(cinfo) ? "" : " not");
160 if (SEC_PKCS7ContentIsSigned(cinfo)) {
161 char *signer_cname, *signer_ename;
162 SECItem *signing_time;
164 if (saw_content) {
165 fprintf(out, "Signature is ");
166 PORT_SetError(0);
167 if (SEC_PKCS7VerifySignature(cinfo, certUsageEmailSigner, PR_FALSE))
168 fprintf(out, "valid.\n");
169 else
170 fprintf(out, "invalid (Reason: %s).\n",
171 SECU_Strerror(PORT_GetError()));
172 } else {
173 fprintf(out,
174 "Content is detached; signature cannot be verified.\n");
177 signer_cname = SEC_PKCS7GetSignerCommonName(cinfo);
178 if (signer_cname != NULL) {
179 fprintf(out, "The signer's common name is %s\n", signer_cname);
180 PORT_Free(signer_cname);
181 } else {
182 fprintf(out, "No signer common name.\n");
185 signer_ename = SEC_PKCS7GetSignerEmailAddress(cinfo);
186 if (signer_ename != NULL) {
187 fprintf(out, "The signer's email address is %s\n", signer_ename);
188 PORT_Free(signer_ename);
189 } else {
190 fprintf(out, "No signer email address.\n");
193 signing_time = SEC_PKCS7GetSigningTime(cinfo);
194 if (signing_time != NULL) {
195 SECU_PrintTimeChoice(out, signing_time, "Signing time", 0);
196 } else {
197 fprintf(out, "No signing time included.\n");
199 } else {
200 fprintf(out, "Content was not signed.\n");
203 fprintf(out, "There were%s certs or crls included.\n",
204 SEC_PKCS7ContainsCertsOrCrls(cinfo) ? "" : " no");
206 SEC_PKCS7DestroyContentInfo(cinfo);
207 return 0;
212 * Print the contents of a PKCS7 message, indicating signatures, etc.
216 main(int argc, char **argv)
218 char *progName;
219 FILE *outFile;
220 PRFileDesc *inFile;
221 PLOptState *optstate;
222 PLOptStatus status;
223 SECStatus rv;
225 progName = strrchr(argv[0], '/');
226 progName = progName ? progName+1 : argv[0];
228 inFile = NULL;
229 outFile = NULL;
232 * Parse command line arguments
234 optstate = PL_CreateOptState(argc, argv, "d:i:o:p:");
235 while ((status = PL_GetNextOpt(optstate)) == PL_OPT_OK) {
236 switch (optstate->option) {
237 case 'd':
238 SECU_ConfigDirectory(optstate->value);
239 break;
241 case 'i':
242 inFile = PR_Open(optstate->value, PR_RDONLY, 0);
243 if (!inFile) {
244 fprintf(stderr, "%s: unable to open \"%s\" for reading\n",
245 progName, optstate->value);
246 return -1;
248 break;
250 case 'o':
251 outFile = fopen(optstate->value, "w");
252 if (!outFile) {
253 fprintf(stderr, "%s: unable to open \"%s\" for writing\n",
254 progName, optstate->value);
255 return -1;
257 break;
259 case 'p':
260 KeyDbPassword = strdup (optstate->value);
261 break;
263 default:
264 Usage(progName);
265 break;
268 if (status == PL_OPT_BAD)
269 Usage(progName);
271 if (!inFile) inFile = PR_STDIN;
272 if (!outFile) outFile = stdout;
274 /* Call the initialization routines */
275 PR_Init(PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1);
276 rv = NSS_Init(SECU_ConfigDirectory(NULL));
277 if (rv != SECSuccess) {
278 SECU_PrintPRandOSError(progName);
279 return -1;
282 PK11_SetPasswordFunc (MyPK11PasswordFunc);
284 if (DecodeAndPrintFile(outFile, inFile, progName)) {
285 SECU_PrintError(progName, "problem decoding data");
286 return -1;
289 if (NSS_Shutdown() != SECSuccess) {
290 exit(1);
293 return 0;