|
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 * Pretty-print some well-known BER or DER encoded data (e.g. certificates, |
|
7 * keys, pkcs7) |
|
8 */ |
|
9 |
|
10 #include "secutil.h" |
|
11 |
|
12 #if defined(__sun) && !defined(SVR4) |
|
13 extern int fprintf(FILE *, char *, ...); |
|
14 #endif |
|
15 |
|
16 #include "plgetopt.h" |
|
17 |
|
18 #include "pk11func.h" |
|
19 #include "nspr.h" |
|
20 #include "nss.h" |
|
21 |
|
22 static void Usage(char *progName) |
|
23 { |
|
24 fprintf(stderr, |
|
25 "Usage: %s [-t type] [-a] [-i input] [-o output] [-w] [-u]\n", |
|
26 progName); |
|
27 fprintf(stderr, "Pretty prints a file containing ASN.1 data in DER or ascii format.\n"); |
|
28 fprintf(stderr, "%-14s Specify input and display type: %s (sk),\n", |
|
29 "-t type", SEC_CT_PRIVATE_KEY); |
|
30 fprintf(stderr, "%-14s %s (pk), %s (c), %s (cr),\n", "", SEC_CT_PUBLIC_KEY, |
|
31 SEC_CT_CERTIFICATE, SEC_CT_CERTIFICATE_REQUEST); |
|
32 fprintf(stderr, "%-14s %s (ci), %s (p7), %s or %s (n).\n", "", SEC_CT_CERTIFICATE_ID, |
|
33 SEC_CT_PKCS7, SEC_CT_CRL, SEC_CT_NAME); |
|
34 fprintf(stderr, "%-14s (Use either the long type name or the shortcut.)\n", "", SEC_CT_CERTIFICATE_ID, |
|
35 SEC_CT_PKCS7, SEC_CT_CRL, SEC_CT_NAME); |
|
36 fprintf(stderr, "%-14s Input is in ascii encoded form (RFC1113)\n", |
|
37 "-a"); |
|
38 fprintf(stderr, "%-14s Define an input file to use (default is stdin)\n", |
|
39 "-i input"); |
|
40 fprintf(stderr, "%-14s Define an output file to use (default is stdout)\n", |
|
41 "-o output"); |
|
42 fprintf(stderr, "%-14s Don't wrap long output lines\n", |
|
43 "-w"); |
|
44 fprintf(stderr, "%-14s Use UTF-8 (default is to show non-ascii as .)\n", |
|
45 "-u"); |
|
46 exit(-1); |
|
47 } |
|
48 |
|
49 int main(int argc, char **argv) |
|
50 { |
|
51 int rv, ascii; |
|
52 char *progName; |
|
53 FILE *outFile; |
|
54 PRFileDesc *inFile; |
|
55 SECItem der, data; |
|
56 char *typeTag; |
|
57 PLOptState *optstate; |
|
58 PRBool wrap = PR_TRUE; |
|
59 |
|
60 progName = strrchr(argv[0], '/'); |
|
61 progName = progName ? progName+1 : argv[0]; |
|
62 |
|
63 ascii = 0; |
|
64 inFile = 0; |
|
65 outFile = 0; |
|
66 typeTag = 0; |
|
67 optstate = PL_CreateOptState(argc, argv, "at:i:o:uw"); |
|
68 while ( PL_GetNextOpt(optstate) == PL_OPT_OK ) { |
|
69 switch (optstate->option) { |
|
70 case '?': |
|
71 Usage(progName); |
|
72 break; |
|
73 |
|
74 case 'a': |
|
75 ascii = 1; |
|
76 break; |
|
77 |
|
78 case 'i': |
|
79 inFile = PR_Open(optstate->value, PR_RDONLY, 0); |
|
80 if (!inFile) { |
|
81 fprintf(stderr, "%s: unable to open \"%s\" for reading\n", |
|
82 progName, optstate->value); |
|
83 return -1; |
|
84 } |
|
85 break; |
|
86 |
|
87 case 'o': |
|
88 outFile = fopen(optstate->value, "w"); |
|
89 if (!outFile) { |
|
90 fprintf(stderr, "%s: unable to open \"%s\" for writing\n", |
|
91 progName, optstate->value); |
|
92 return -1; |
|
93 } |
|
94 break; |
|
95 |
|
96 case 't': |
|
97 typeTag = strdup(optstate->value); |
|
98 break; |
|
99 |
|
100 case 'u': |
|
101 SECU_EnableUtf8Display(PR_TRUE); |
|
102 break; |
|
103 |
|
104 case 'w': |
|
105 wrap = PR_FALSE; |
|
106 break; |
|
107 } |
|
108 } |
|
109 PL_DestroyOptState(optstate); |
|
110 if (!typeTag) Usage(progName); |
|
111 |
|
112 if (!inFile) inFile = PR_STDIN; |
|
113 if (!outFile) outFile = stdout; |
|
114 |
|
115 PR_Init(PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1); |
|
116 rv = NSS_NoDB_Init(NULL); |
|
117 if (rv != SECSuccess) { |
|
118 fprintf(stderr, "%s: NSS_NoDB_Init failed (%s)\n", |
|
119 progName, SECU_Strerror(PORT_GetError())); |
|
120 exit(1); |
|
121 } |
|
122 SECU_RegisterDynamicOids(); |
|
123 |
|
124 rv = SECU_ReadDERFromFile(&der, inFile, ascii, PR_FALSE); |
|
125 if (rv != SECSuccess) { |
|
126 fprintf(stderr, "%s: SECU_ReadDERFromFile failed\n", progName); |
|
127 exit(1); |
|
128 } |
|
129 |
|
130 /* Data is untyped, using the specified type */ |
|
131 data.data = der.data; |
|
132 data.len = der.len; |
|
133 |
|
134 SECU_EnableWrap(wrap); |
|
135 |
|
136 /* Pretty print it */ |
|
137 if (PORT_Strcmp(typeTag, SEC_CT_CERTIFICATE) == 0 || |
|
138 PORT_Strcmp(typeTag, "c") == 0) { |
|
139 rv = SECU_PrintSignedData(outFile, &data, "Certificate", 0, |
|
140 SECU_PrintCertificate); |
|
141 } else if (PORT_Strcmp(typeTag, SEC_CT_CERTIFICATE_ID) == 0 || |
|
142 PORT_Strcmp(typeTag, "ci") == 0) { |
|
143 rv = SECU_PrintSignedContent(outFile, &data, 0, 0, |
|
144 SECU_PrintDumpDerIssuerAndSerial); |
|
145 } else if (PORT_Strcmp(typeTag, SEC_CT_CERTIFICATE_REQUEST) == 0 || |
|
146 PORT_Strcmp(typeTag, "cr") == 0) { |
|
147 rv = SECU_PrintSignedData(outFile, &data, "Certificate Request", 0, |
|
148 SECU_PrintCertificateRequest); |
|
149 } else if (PORT_Strcmp(typeTag, SEC_CT_CRL) == 0) { |
|
150 rv = SECU_PrintSignedData (outFile, &data, "CRL", 0, SECU_PrintCrl); |
|
151 #ifdef HAVE_EPV_TEMPLATE |
|
152 } else if (PORT_Strcmp(typeTag, SEC_CT_PRIVATE_KEY) == 0 || |
|
153 PORT_Strcmp(typeTag, "sk") == 0) { |
|
154 rv = SECU_PrintPrivateKey(outFile, &data, "Private Key", 0); |
|
155 #endif |
|
156 } else if (PORT_Strcmp(typeTag, SEC_CT_PUBLIC_KEY) == 0 || |
|
157 PORT_Strcmp (typeTag, "pk") == 0) { |
|
158 rv = SECU_PrintSubjectPublicKeyInfo(outFile, &data, "Public Key", 0); |
|
159 } else if (PORT_Strcmp(typeTag, SEC_CT_PKCS7) == 0 || |
|
160 PORT_Strcmp (typeTag, "p7") == 0) { |
|
161 rv = SECU_PrintPKCS7ContentInfo(outFile, &data, |
|
162 "PKCS #7 Content Info", 0); |
|
163 } else if (PORT_Strcmp(typeTag, SEC_CT_NAME) == 0 || |
|
164 PORT_Strcmp (typeTag, "n") == 0) { |
|
165 rv = SECU_PrintDERName(outFile, &data, "Name", 0); |
|
166 } else { |
|
167 fprintf(stderr, "%s: don't know how to print out '%s' files\n", |
|
168 progName, typeTag); |
|
169 SECU_PrintAny(outFile, &data, "File contains", 0); |
|
170 return -1; |
|
171 } |
|
172 |
|
173 if (inFile != PR_STDIN) |
|
174 PR_Close(inFile); |
|
175 PORT_Free(der.data); |
|
176 if (rv) { |
|
177 fprintf(stderr, "%s: problem converting data (%s)\n", |
|
178 progName, SECU_Strerror(PORT_GetError())); |
|
179 } |
|
180 if (NSS_Shutdown() != SECSuccess) { |
|
181 fprintf(stderr, "%s: NSS_Shutdown failed (%s)\n", |
|
182 progName, SECU_Strerror(PORT_GetError())); |
|
183 rv = SECFailure; |
|
184 } |
|
185 PR_Cleanup(); |
|
186 return rv; |
|
187 } |