]> git.saurik.com Git - apple/security.git/blob - SecurityTests/clxutils/certcrl/certcrl.cpp
Security-57031.10.10.tar.gz
[apple/security.git] / SecurityTests / clxutils / certcrl / certcrl.cpp
1 /*
2 * certcrl - generic cert/CRL verifier
3 */
4 #include <security_cdsa_utils/cuFileIo.h>
5 #include <utilLib/common.h>
6 #include <clAppUtils/clutils.h>
7 #include <stdlib.h>
8 #include <stdio.h>
9 #include <string.h>
10 #include <Security/cssm.h>
11 #include <clAppUtils/BlobList.h>
12 #include <clAppUtils/certVerify.h>
13 #include "script.h"
14
15 static void usage(char **argv)
16 {
17 printf("Usage: %s [options]\n", argv[0]);
18 printf("Options:\n");
19 printf(" -c certFileName [...]\n");
20 printf(" -C rootCertFileName [...]\n");
21 printf(" -r crlFileName [...]\n");
22 printf(" -d certDbName\n");
23 printf(" -D crlDlDbName\n");
24 printf(" -s (use system anchor certs)\n");
25 printf(" -g (use Trust Settings)\n");
26 printf(" -i (implicit anchors)\n");
27 printf(" -l=loopCount (default = 1)\n");
28 printf(" -f (leaf cert is a CA)\n");
29 printf(" -w(rite CRLs to dlDbName)\n");
30 printf("Policy options:\n");
31 printf(" -y ssl|smime|swuSign|codeSign|pkgSign|resourceSign|iChat|pkinitServer|\n"
32 " pkinitClient|IPSec\n");
33 printf(" -h sslHostName (implies SSL policy; default is basic)\n");
34 printf(" -t SSL client side (implies SSL policy, default is server side)\n");
35 printf(" -E senderEmail (implies SMIME policy unless iChat is specified)\n");
36 printf("Revocation options:\n");
37 printf(" -R revocationPolicy (crl|ocsp|both|none); default = none\n");
38 printf(" -a (allow certs unverified by CRL or OCSP)\n");
39 printf(" -A (require CRL verification if present in cert\n");
40 printf(" -4 (require CRL verification for all certs)\n");
41 printf(" -Q (require OCSP if present in cert)\n");
42 printf(" -5 (require OCSP verification for all certs)\n");
43 printf(" -u responderURI\n");
44 printf(" -U responderCert\n");
45 printf(" -H (OCSP cache disable)\n");
46 printf(" -W (network OCSP disable)\n");
47 printf(" -o generate OCSP nonce\n");
48 printf(" -O require nonce in OCSP response\n");
49 printf("Misc. options:\n");
50 printf(" -n (no network fetch of CRLs)\n");
51 printf(" -N (no network fetch of certs)\n");
52 printf(" -k keyUsage (In HEX starting with 0x)\n");
53 printf(" -T verifyTime (in CSSM_TIMESTRING format, like 20041217154316)\n");
54 printf(" -e=expectedError (default is CSSM_OK)\n");
55 printf(" -S scriptFile\n");
56 printf(" -p (print script variable names)\n");
57 printf(" -P (pause after each script test)\n");
58 printf(" -v (verbose)\n");
59 printf(" -q (quiet)\n");
60 printf(" -L (silent)\n");
61 exit(1);
62 }
63
64
65
66 /* add files named by successive items in argv to blobList, up until the
67 * next '-' arg */
68 static void gatherFiles(
69 BlobList &blobList,
70 char **argv,
71 int argc,
72 int &currArg)
73 {
74 if((currArg == argc) || (argv[currArg][0] == '-')) {
75 /* need at least one file name */
76 usage(argv);
77 }
78 while(currArg<argc) {
79 char *argp = argv[currArg];
80 if(argp[0] == '-') {
81 /* done with this file list */
82 currArg--;
83 return;
84 }
85 int rtn = blobList.addFile(argv[currArg]);
86 if(rtn) {
87 exit(1);
88 }
89 currArg++;
90 }
91 /* out of args */
92 return;
93 }
94
95 int main(int argc, char **argv)
96 {
97 BlobList certs;
98 BlobList roots;
99 BlobList crls;
100 int rtn;
101 CSSM_DL_HANDLE dlHand;
102 int loop;
103 int arg;
104 char *argp;
105 CSSM_DL_DB_HANDLE_PTR crlDbHandPtr = NULL;
106 CSSM_DL_DB_LIST dlDbList;
107 CSSM_DL_DB_HANDLE dlDbHandles[2];
108 CSSM_RETURN crtn;
109 CSSM_RETURN silent = CSSM_FALSE;
110 CSSM_BOOL scriptPause = CSSM_FALSE;
111
112 CertVerifyArgs vfyArgs;
113 memset(&vfyArgs, 0, sizeof(vfyArgs));
114
115 vfyArgs.version = CERT_VFY_ARGS_VERS;
116 vfyArgs.certs = &certs;
117 vfyArgs.roots = &roots;
118 vfyArgs.crls = &crls;
119
120 /* for historical reasons the defaults for these are true */
121 vfyArgs.crlNetFetchEnable = CSSM_TRUE;
122 vfyArgs.certNetFetchEnable = CSSM_TRUE;
123
124 /* user-specd variables */
125 int loops = 1;
126 const char *crlDbName = NULL;
127 const char *certDbName = NULL;
128 char *scriptFile = NULL;
129
130 if(argc < 2) {
131 usage(argv);
132 }
133 for(arg=1; arg<argc; arg++) {
134 argp = argv[arg];
135 if(argp[0] != '-') {
136 usage(argv);
137 }
138 switch(argp[1]) {
139 case 'l':
140 loops = atoi(&argp[3]);
141 break;
142 case 'r':
143 arg++;
144 gatherFiles(crls, argv, argc, arg);
145 break;
146 case 'c':
147 arg++;
148 gatherFiles(certs, argv, argc, arg);
149 break;
150 case 'C':
151 arg++;
152 gatherFiles(roots, argv, argc, arg);
153 break;
154 case 'v':
155 vfyArgs.verbose = CSSM_TRUE;
156 break;
157 case 'q':
158 vfyArgs.quiet = CSSM_TRUE;
159 break;
160 case 's':
161 vfyArgs.useSystemAnchors = CSSM_TRUE;
162 break;
163 case 'g':
164 vfyArgs.useTrustSettings = CSSM_TRUE;
165 break;
166 case 'i':
167 vfyArgs.implicitAnchors = CSSM_TRUE;
168 break;
169 case 'a':
170 vfyArgs.allowUnverified = CSSM_TRUE;
171 break;
172 case 'e':
173 vfyArgs.expectedErrStr = &argp[3];
174 break;
175 case 'n':
176 vfyArgs.crlNetFetchEnable = CSSM_FALSE;
177 break;
178 case 'N':
179 vfyArgs.certNetFetchEnable = CSSM_FALSE;
180 break;
181 case 'f':
182 vfyArgs.leafCertIsCA = CSSM_TRUE;
183 break;
184 case 'd':
185 arg++;
186 if(arg == argc) {
187 usage(argv);
188 }
189 certDbName = argv[arg];
190 break;
191 case 'D':
192 arg++;
193 if(arg == argc) {
194 usage(argv);
195 }
196 crlDbName = argv[arg];
197 break;
198 case 'S':
199 arg++;
200 if(arg == argc) {
201 usage(argv);
202 }
203 scriptFile = argv[arg];
204 break;
205 case 'h':
206 arg++;
207 if(arg == argc) {
208 usage(argv);
209 }
210 vfyArgs.sslHost= argv[arg];
211 vfyArgs.vfyPolicy = CVP_SSL;
212 break;
213 case 'E':
214 arg++;
215 if(arg == argc) {
216 usage(argv);
217 }
218 if(vfyArgs.vfyPolicy == CVP_Basic) {
219 /* user hasn't specified; now default to SMIME - still
220 * can override (e.g., for iChat) */
221 vfyArgs.vfyPolicy = CVP_SMIME;
222 }
223 vfyArgs.senderEmail = argv[arg];
224 break;
225 case 'k':
226 arg++;
227 if(arg == argc) {
228 usage(argv);
229 }
230 vfyArgs.intendedKeyUse = hexToBin(argv[arg]);
231 break;
232 case 't':
233 vfyArgs.sslClient = CSSM_TRUE;
234 vfyArgs.vfyPolicy = CVP_SSL;
235 break;
236 case 'y':
237 arg++;
238 if(arg == argc) {
239 usage(argv);
240 }
241 argp = argv[arg];
242 if(parsePolicyString(argp, &vfyArgs.vfyPolicy)) {
243 printf("Bogus policyValue (%s)\n", argp);
244 printPolicyStrings();
245 exit(1);
246 }
247 break;
248 case 'R':
249 arg++;
250 if(arg == argc) {
251 usage(argv);
252 }
253 argp = argv[arg];
254 if(!strcmp(argp, "none")) {
255 vfyArgs.revokePolicy = CRP_None;
256 }
257 else if(!strcmp(argp, "crl")) {
258 vfyArgs.revokePolicy = CRP_CRL;
259 }
260 else if(!strcmp(argp, "ocsp")) {
261 vfyArgs.revokePolicy = CRP_OCSP;
262 }
263 else if(!strcmp(argp, "both")) {
264 vfyArgs.revokePolicy = CRP_CRL_OCSP;
265 }
266 else {
267 usage(argv);
268 }
269 break;
270 case 'u':
271 arg++;
272 if(arg == argc) {
273 usage(argv);
274 }
275 vfyArgs.responderURI = argv[arg];
276 /* no implied policy yet - could be CRP_OCSP or CRP_CRL_OCSP */
277 break;
278 case 'U':
279 if(readFile(argv[arg], (unsigned char **)vfyArgs.responderCert,
280 &vfyArgs.responderCertLen)) {
281 printf("***Error reading responderCert from %s. Aborting.\n",
282 argv[arg]);
283 exit(1);
284 }
285 /* no implied policy yet - could be CRP_OCSP or CRP_CRL_OCSP */
286 break;
287 case 'H':
288 vfyArgs.disableCache = CSSM_TRUE;
289 break;
290 case 'W':
291 vfyArgs.disableOcspNet = CSSM_TRUE;
292 break;
293 case 'Q':
294 vfyArgs.requireOcspIfPresent = CSSM_TRUE;
295 break;
296 case '5':
297 vfyArgs.requireOcspForAll = CSSM_TRUE;
298 break;
299 case 'o':
300 vfyArgs.generateOcspNonce = CSSM_TRUE;
301 break;
302 case 'O':
303 vfyArgs.requireOcspRespNonce = CSSM_TRUE;
304 break;
305 case 'A':
306 vfyArgs.requireCrlIfPresent = CSSM_TRUE;
307 break;
308 case '4':
309 vfyArgs.requireCrlForAll = CSSM_TRUE;
310 break;
311 case 'T':
312 arg++;
313 if(arg == argc) {
314 usage(argv);
315 }
316 vfyArgs.vfyTime = argv[arg];
317 break;
318 case 'p':
319 printScriptVars();
320 exit(0);
321 case 'P':
322 scriptPause = CSSM_TRUE;
323 break;
324 case 'L':
325 silent = CSSM_TRUE; // inhibits start banner
326 vfyArgs.quiet = CSSM_TRUE; // inhibits stdout from certVerify
327 break;
328 default:
329 usage(argv);
330 }
331 }
332
333 if((vfyArgs.responderCert != NULL) || (vfyArgs.responderURI != NULL)) {
334 switch(vfyArgs.revokePolicy) {
335 case CRP_None:
336 vfyArgs.revokePolicy = CRP_OCSP;
337 break;
338 case CRP_OCSP:
339 case CRP_CRL_OCSP:
340 break;
341 case CRP_CRL:
342 printf("*** OCSP options (responderURI, responderCert) only valid "
343 "with OCSP policy\n");
344 usage(argv);
345 }
346 }
347
348 vfyArgs.clHand = clStartup();
349 if(vfyArgs.clHand == CSSM_INVALID_HANDLE) {
350 return 1;
351 }
352 vfyArgs.tpHand = tpStartup();
353 if(vfyArgs.tpHand == CSSM_INVALID_HANDLE) {
354 return 1;
355 }
356 vfyArgs.cspHand = cspStartup();
357 if(vfyArgs.cspHand == CSSM_INVALID_HANDLE) {
358 return 1;
359 }
360 dlHand = dlStartup();
361 if(dlHand == CSSM_INVALID_HANDLE) {
362 return 1;
363 }
364
365 if(!silent) {
366 testStartBanner("certcrl", argc, argv);
367 }
368
369 if(scriptFile) {
370 ScriptVars vars;
371 vars.allowUnverified = vfyArgs.allowUnverified;
372 vars.requireCrlIfPresent = vfyArgs.requireCrlIfPresent;
373 vars.requireOcspIfPresent = vfyArgs.requireOcspIfPresent;
374 vars.crlNetFetchEnable = vfyArgs.crlNetFetchEnable;
375 vars.certNetFetchEnable = vfyArgs.certNetFetchEnable;
376 vars.useSystemAnchors = vfyArgs.useSystemAnchors;
377 vars.useTrustSettings = vfyArgs.useTrustSettings;
378 vars.leafCertIsCA = vfyArgs.leafCertIsCA;
379 vars.cacheDisable = vfyArgs.disableCache;
380 vars.ocspNetFetchDisable = vfyArgs.disableOcspNet;
381 vars.requireCrlForAll = vfyArgs.requireCrlForAll;
382 vars.requireOcspForAll = vfyArgs.requireOcspForAll;
383 return runScript(scriptFile, vfyArgs.tpHand, vfyArgs.clHand,
384 vfyArgs.cspHand, dlHand,
385 &vars, vfyArgs.quiet, vfyArgs.verbose, scriptPause);
386 }
387
388 /* open DlDbs if enabled */
389 dlDbList.NumHandles = 0;
390 dlDbList.DLDBHandle = &dlDbHandles[0];
391 dlDbList.DLDBHandle[0].DLHandle = dlHand;
392 dlDbList.DLDBHandle[1].DLHandle = dlHand;
393 if(certDbName != NULL) {
394 crtn = CSSM_DL_DbOpen(dlHand,
395 certDbName,
396 NULL, // DbLocation
397 CSSM_DB_ACCESS_READ,
398 NULL, // CSSM_ACCESS_CREDENTIALS *AccessCred
399 NULL, // void *OpenParameters
400 &dlDbList.DLDBHandle[0].DBHandle);
401 if(crtn) {
402 printError("CSSM_DL_DbOpen", crtn);
403 printf("***Error opening DB %s. Aborting.\n", certDbName);
404 return 1;
405 }
406 dlDbList.NumHandles++;
407 vfyArgs.dlDbList = &dlDbList;
408 }
409 if(crlDbName != NULL) {
410 vfyArgs.crlDlDb = &dlDbList.DLDBHandle[dlDbList.NumHandles];
411 crtn = CSSM_DL_DbOpen(dlHand,
412 crlDbName,
413 NULL, // DbLocation
414 CSSM_DB_ACCESS_READ | CSSM_DB_ACCESS_WRITE,
415 NULL, // CSSM_ACCESS_CREDENTIALS *AccessCred
416 NULL, // void *OpenParameters
417 &crlDbHandPtr->DBHandle);
418 if(crtn) {
419 printError("CSSM_DL_DbOpen", crtn);
420 printf("***Error opening DB %s. Aborting.\n", crlDbName);
421 return 1;
422 }
423 dlDbList.NumHandles++;
424 vfyArgs.dlDbList = &dlDbList;
425 }
426 for(loop=0; loop<loops; loop++) {
427 rtn = certVerify(&vfyArgs);
428 if(rtn) {
429 break;
430 }
431
432 if(loops != 1) {
433 fpurge(stdin);
434 printf("CR to continue, q to quit: ");
435 char c = getchar();
436 if(c == 'q') {
437 break;
438 }
439 }
440 }
441 return rtn;
442 }
443