]> git.saurik.com Git - apple/security.git/blob - SecurityTests/clxutils/crlTool/crlTool.cpp
Security-57031.1.35.tar.gz
[apple/security.git] / SecurityTests / clxutils / crlTool / crlTool.cpp
1 /*
2 * crlTool.cpp
3 */
4
5 #include <stdlib.h>
6 #include <strings.h>
7 #include <stdio.h>
8 #include <unistd.h>
9 #include <security_cdsa_utils/cuFileIo.h>
10 #include <utilLib/common.h>
11 #include <clAppUtils/clutils.h>
12 #include <clAppUtils/CertParser.h>
13 #include <Security/Security.h>
14 #include "crlNetwork.h"
15 #include <security_cdsa_utils/cuPrintCert.h>
16 #define LOOPS_DEF 100
17
18 static void usage(char **argv)
19 {
20 printf("usage: %s [options]\n", argv[0]);
21 printf("Options:\n");
22 printf(" -c certFile -- obtain CRL via net from this cert\n");
23 printf(" -C crlFile -- CRL from this file\n");
24 printf(" -p -- parse the CRL\n");
25 printf(" -o outFile -- write the fetched CRL to this file\n");
26 printf(" -v -- verbose CRL dump\n");
27 /* etc. */
28 exit(1);
29 }
30
31 static int fetchCrlViaGeneralNames(
32 const CE_GeneralNames *names,
33 unsigned char **crl, // mallocd and RETURNED
34 size_t *crlLen) // RETURNED
35 {
36 CSSM_DATA crlData = {0, NULL};
37 CSSM_RETURN crtn;
38
39 for(unsigned nameDex=0; nameDex<names->numNames; nameDex++) {
40 CE_GeneralName *name = &names->generalName[nameDex];
41 switch(name->nameType) {
42 case GNT_URI:
43 if(name->name.Length < 5) {
44 continue;
45 }
46 if(strncmp((char *)name->name.Data, "ldap:", 5) &&
47 strncmp((char *)name->name.Data, "http:", 5) &&
48 strncmp((char *)name->name.Data, "https:", 6)) {
49 /* eventually handle other schemes here */
50 continue;
51 }
52
53 /* OK, we can do this */
54 crtn = crlNetFetch(&name->name, LT_Crl, &crlData);
55 if(crtn) {
56 printf("...net fetch error\n");
57 return 1;
58 }
59 *crl = crlData.Data;
60 *crlLen = crlData.Length;
61 return 0;
62
63 default:
64 printf("fetchCrlViaGeneralNames: unknown"
65 "nameType (%u)", (unsigned)name->nameType);
66 break;
67 }
68 }
69 printf("...GNT_URI name not found in GeneralNames\n");
70 return 1;
71 }
72
73 static int fetchCrl(
74 CertParser &cert,
75 unsigned char **crl, // mallocd and RETURNED
76 size_t *crlLen) // RETURNED
77 {
78 CE_CRLDistPointsSyntax *dps = (CE_CRLDistPointsSyntax *)
79 cert.extensionForOid(CSSMOID_CrlDistributionPoints);
80
81 *crl = NULL;
82 *crlLen = 0;
83 if(dps == NULL) {
84 /* not an error, just indicate NULL return */
85 printf("***No CrlDistributionPoints in this cert.\n");
86 return 0;
87 }
88 for(unsigned dex=0; dex<dps->numDistPoints; dex++) {
89
90 CE_CRLDistributionPoint *dp = &dps->distPoints[dex];
91 if(dp->distPointName == NULL) {
92 continue;
93 }
94 switch(dp->distPointName->nameType) {
95 case CE_CDNT_NameRelativeToCrlIssuer:
96 printf("...CE_CDNT_NameRelativeToCrlIssuer not implemented\n");
97 break;
98
99 case CE_CDNT_FullName:
100 {
101 CE_GeneralNames *names = dp->distPointName->dpn.fullName;
102 int rtn = fetchCrlViaGeneralNames(names, crl, crlLen);
103 if(rtn == 0) {
104 return 0;
105 }
106 /* else try again if there's another name */
107 break;
108 } /* CE_CDNT_FullName */
109
110 default:
111 /* not yet */
112 printf("unknown distPointName->nameType (%u)\n",
113 (unsigned)dp->distPointName->nameType);
114 break;
115 } /* switch distPointName->nameType */
116 } /* for each distPoints */
117 printf("...CrlDistributionPoints found, but nothing we can use.\n");
118 return 0;
119 }
120
121 int main(int argc, char **argv)
122 {
123 char *certFile = NULL;
124 char *crlFile = NULL;
125 unsigned char *certData;
126 unsigned certDataLen;
127 bool doParse = false;
128 char *outFile = NULL;
129 CSSM_BOOL verbose = CSSM_FALSE;
130 unsigned char *crl = NULL;
131 size_t crlLen = 0;
132 int rtn = -1;
133
134 if(argc < 2) {
135 usage(argv);
136 }
137
138 extern char *optarg;
139 int arg;
140 while ((arg = getopt(argc, argv, "c:C:po:vh")) != -1) {
141 switch (arg) {
142 case 'c':
143 certFile = optarg;
144 break;
145 case 'C':
146 crlFile = optarg;
147 break;
148 case 'p':
149 doParse = true;
150 break;
151 case 'o':
152 outFile = optarg;
153 break;
154 case 'v':
155 verbose = CSSM_TRUE;
156 break;
157 case 'h':
158 usage(argv);
159 }
160 }
161 if(optind != argc) {
162 usage(argv);
163 }
164 if((certFile != NULL) && (crlFile != NULL)) {
165 printf("***crlFile and certFile are mutually exclusive.\n");
166 usage(argv);
167 }
168 if((certFile == NULL) && (crlFile == NULL)) {
169 printf("***Must specify either certFile or crlFile\n");
170 usage(argv);
171 }
172
173 CSSM_RETURN crtn;
174 CSSM_CL_HANDLE clHand = clStartup();
175 CertParser parser(clHand);
176
177 if(crlFile) {
178 unsigned len;
179 if(readFile(crlFile, &crl, &len)) {
180 printf("***Error reading %s. Aborting.\n", crlFile);
181 exit(1);
182 }
183 crlLen = len;
184 }
185 if(certFile) {
186 if(readFile(certFile, &certData, &certDataLen)) {
187 printf("***Error reading %s. Aborting.\n", certFile);
188 exit(1);
189 }
190 CSSM_DATA cdata = {certDataLen, certData};
191 crtn = parser.initWithData(cdata);
192 if(crtn) {
193 printf("Error parsing cert %s. Aborting.\n", certFile);
194 exit(1);
195 }
196 rtn = fetchCrl(parser, &crl, &crlLen);
197 if(rtn) {
198 printf("***aborting.\n");
199 exit(1);
200 }
201 }
202
203 if(doParse) {
204 if(crl == NULL) {
205 printf("...parse specified but no CRL found.\n");
206 }
207 else {
208 if(certFile != NULL) {
209 printf("============== CRL for cert %s ==============\n", certFile);
210 }
211 printCrl(crl, crlLen, verbose);
212 if(certFile != NULL) {
213 printf("============== end of CRL ==============\n");
214 }
215 }
216 }
217 if(outFile) {
218 if(crl == NULL) {
219 printf("...outFile specified but no CRL found.\n");
220 }
221 else {
222 if(writeFile(outFile, crl, crlLen)) {
223 printf("***Error writing CRL to %s.\n", outFile);
224 rtn = 1;
225 }
226 else {
227 printf("...wrote %u bytes to %s\n", (unsigned)crlLen, outFile);
228 }
229 }
230 }
231 return rtn;
232 }