1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58: #ifndef OPENSSL_NO_OCSP
59:
60: #include <stdio.h>
61: #include <string.h>
62: #include "apps.h"
63: #include <openssl/pem.h>
64: #include <openssl/ocsp.h>
65: #include <openssl/err.h>
66: #include <openssl/ssl.h>
67: #include <openssl/bn.h>
68:
69:
70: #define MAX_VALIDITY_PERIOD (5 * 60)
71:
72: static int add_ocsp_cert(OCSP_REQUEST **req, X509 *cert, X509 *issuer,
73: STACK_OF(OCSP_CERTID) *ids);
74: static int add_ocsp_serial(OCSP_REQUEST **req, char *serial, X509 *issuer,
75: STACK_OF(OCSP_CERTID) *ids);
76: static int print_ocsp_summary(BIO *out, OCSP_BASICRESP *bs, OCSP_REQUEST *req,
77: STACK *names, STACK_OF(OCSP_CERTID) *ids,
78: long nsec, long maxage);
79:
80: static int make_ocsp_response(OCSP_RESPONSE **resp, OCSP_REQUEST *req, CA_DB *db,
81: X509 *ca, X509 *rcert, EVP_PKEY *rkey,
82: STACK_OF(X509) *rother, unsigned long flags,
83: int nmin, int ndays);
84:
85: static char **lookup_serial(CA_DB *db, ASN1_INTEGER *ser);
86: static BIO *init_responder(char *port);
87: static int do_responder(OCSP_REQUEST **preq, BIO **pcbio, BIO *acbio, char *port);
88: static int send_ocsp_response(BIO *cbio, OCSP_RESPONSE *resp);
89:
90: #undef PROG
91: #define PROG ocsp_main
92:
93: int MAIN(int, char **);
94:
95: int MAIN(int argc, char **argv)
96: {
97: ENGINE *e = NULL;
98: char **args;
99: char *host = NULL, *port = NULL, *path = "/";
100: char *reqin = NULL, *respin = NULL;
101: char *reqout = NULL, *respout = NULL;
102: char *signfile = NULL, *keyfile = NULL;
103: char *rsignfile = NULL, *rkeyfile = NULL;
104: char *outfile = NULL;
105: int add_nonce = 1, noverify = 0, use_ssl = -1;
106: OCSP_REQUEST *req = NULL;
107: OCSP_RESPONSE *resp = NULL;
108: OCSP_BASICRESP *bs = NULL;
109: X509 *issuer = NULL, *cert = NULL;
110: X509 *signer = NULL, *rsigner = NULL;
111: EVP_PKEY *key = NULL, *rkey = NULL;
112: BIO *acbio = NULL, *cbio = NULL;
113: BIO *derbio = NULL;
114: BIO *out = NULL;
115: int req_text = 0, resp_text = 0;
116: long nsec = MAX_VALIDITY_PERIOD, maxage = -1;
117: char *CAfile = NULL, *CApath = NULL;
118: X509_STORE *store = NULL;
119: SSL_CTX *ctx = NULL;
120: STACK_OF(X509) *sign_other = NULL, *verify_other = NULL, *rother = NULL;
121: char *sign_certfile = NULL, *verify_certfile = NULL, *rcertfile = NULL;
122: unsigned long sign_flags = 0, verify_flags = 0, rflags = 0;
123: int ret = 1;
124: int accept_count = -1;
125: int badarg = 0;
126: int i;
127: int ignore_err = 0;
128: STACK *reqnames = NULL;
129: STACK_OF(OCSP_CERTID) *ids = NULL;
130:
131: X509 *rca_cert = NULL;
132: char *ridx_filename = NULL;
133: char *rca_filename = NULL;
134: CA_DB *rdb = NULL;
135: int nmin = 0, ndays = -1;
136:
137: if (bio_err == NULL) bio_err = BIO_new_fp(stderr, BIO_NOCLOSE);
138:
139: if (!load_config(bio_err, NULL))
140: goto end;
141: SSL_load_error_strings();
142: OpenSSL_add_ssl_algorithms();
143: args = argv + 1;
144: reqnames = sk_new_null();
145: ids = sk_OCSP_CERTID_new_null();
146: while (!badarg && *args && *args[0] == '-')
147: {
148: if (!strcmp(*args, "-out"))
149: {
150: if (args[1])
151: {
152: args++;
153: outfile = *args;
154: }
155: else badarg = 1;
156: }
157: else if (!strcmp(*args, "-url"))
158: {
159: if (args[1])
160: {
161: args++;
162: if (!OCSP_parse_url(*args, &host, &port, &path, &use_ssl))
163: {
164: BIO_printf(bio_err, "Error parsing URL\n");
165: badarg = 1;
166: }
167: }
168: else badarg = 1;
169: }
170: else if (!strcmp(*args, "-host"))
171: {
172: if (args[1])
173: {
174: args++;
175: host = *args;
176: }
177: else badarg = 1;
178: }
179: else if (!strcmp(*args, "-port"))
180: {
181: if (args[1])
182: {
183: args++;
184: port = *args;
185: }
186: else badarg = 1;
187: }
188: else if (!strcmp(*args, "-ignore_err"))
189: ignore_err = 1;
190: else if (!strcmp(*args, "-noverify"))
191: noverify = 1;
192: else if (!strcmp(*args, "-nonce"))
193: add_nonce = 2;
194: else if (!strcmp(*args, "-no_nonce"))
195: add_nonce = 0;
196: else if (!strcmp(*args, "-resp_no_certs"))
197: rflags |= OCSP_NOCERTS;
198: else if (!strcmp(*args, "-resp_key_id"))
199: rflags |= OCSP_RESPID_KEY;
200: else if (!strcmp(*args, "-no_certs"))
201: sign_flags |= OCSP_NOCERTS;
202: else if (!strcmp(*args, "-no_signature_verify"))
203: verify_flags |= OCSP_NOSIGS;
204: else if (!strcmp(*args, "-no_cert_verify"))
205: verify_flags |= OCSP_NOVERIFY;
206: else if (!strcmp(*args, "-no_chain"))
207: verify_flags |= OCSP_NOCHAIN;
208: else if (!strcmp(*args, "-no_cert_checks"))
209: verify_flags |= OCSP_NOCHECKS;
210: else if (!strcmp(*args, "-no_explicit"))
211: verify_flags |= OCSP_NOEXPLICIT;
212: else if (!strcmp(*args, "-trust_other"))
213: verify_flags |= OCSP_TRUSTOTHER;
214: else if (!strcmp(*args, "-no_intern"))
215: verify_flags |= OCSP_NOINTERN;
216: else if (!strcmp(*args, "-text"))
217: {
218: req_text = 1;
219: resp_text = 1;
220: }
221: else if (!strcmp(*args, "-req_text"))
222: req_text = 1;
223: else if (!strcmp(*args, "-resp_text"))
224: resp_text = 1;
225: else if (!strcmp(*args, "-reqin"))
226: {
227: if (args[1])
228: {
229: args++;
230: reqin = *args;
231: }
232: else badarg = 1;
233: }
234: else if (!strcmp(*args, "-respin"))
235: {
236: if (args[1])
237: {
238: args++;
239: respin = *args;
240: }
241: else badarg = 1;
242: }
243: else if (!strcmp(*args, "-signer"))
244: {
245: if (args[1])
246: {
247: args++;
248: signfile = *args;
249: }
250: else badarg = 1;
251: }
252: else if (!strcmp (*args, "-VAfile"))
253: {
254: if (args[1])
255: {
256: args++;
257: verify_certfile = *args;
258: verify_flags |= OCSP_TRUSTOTHER;
259: }
260: else badarg = 1;
261: }
262: else if (!strcmp(*args, "-sign_other"))
263: {
264: if (args[1])
265: {
266: args++;
267: sign_certfile = *args;
268: }
269: else badarg = 1;
270: }
271: else if (!strcmp(*args, "-verify_other"))
272: {
273: if (args[1])
274: {
275: args++;
276: verify_certfile = *args;
277: }
278: else badarg = 1;
279: }
280: else if (!strcmp (*args, "-CAfile"))
281: {
282: if (args[1])
283: {
284: args++;
285: CAfile = *args;
286: }
287: else badarg = 1;
288: }
289: else if (!strcmp (*args, "-CApath"))
290: {
291: if (args[1])
292: {
293: args++;
294: CApath = *args;
295: }
296: else badarg = 1;
297: }
298: else if (!strcmp (*args, "-validity_period"))
299: {
300: if (args[1])
301: {
302: args++;
303: nsec = atol(*args);
304: if (nsec < 0)
305: {
306: BIO_printf(bio_err,
307: "Illegal validity period %s\n",
308: *args);
309: badarg = 1;
310: }
311: }
312: else badarg = 1;
313: }
314: else if (!strcmp (*args, "-status_age"))
315: {
316: if (args[1])
317: {
318: args++;
319: maxage = atol(*args);
320: if (maxage < 0)
321: {
322: BIO_printf(bio_err,
323: "Illegal validity age %s\n",
324: *args);
325: badarg = 1;
326: }
327: }
328: else badarg = 1;
329: }
330: else if (!strcmp(*args, "-signkey"))
331: {
332: if (args[1])
333: {
334: args++;
335: keyfile = *args;
336: }
337: else badarg = 1;
338: }
339: else if (!strcmp(*args, "-reqout"))
340: {
341: if (args[1])
342: {
343: args++;
344: reqout = *args;
345: }
346: else badarg = 1;
347: }
348: else if (!strcmp(*args, "-respout"))
349: {
350: if (args[1])
351: {
352: args++;
353: respout = *args;
354: }
355: else badarg = 1;
356: }
357: else if (!strcmp(*args, "-path"))
358: {
359: if (args[1])
360: {
361: args++;
362: path = *args;
363: }
364: else badarg = 1;
365: }
366: else if (!strcmp(*args, "-issuer"))
367: {
368: if (args[1])
369: {
370: args++;
371: X509_free(issuer);
372: issuer = load_cert(bio_err, *args, FORMAT_PEM,
373: NULL, e, "issuer certificate");
374: if(!issuer) goto end;
375: }
376: else badarg = 1;
377: }
378: else if (!strcmp (*args, "-cert"))
379: {
380: if (args[1])
381: {
382: args++;
383: X509_free(cert);
384: cert = load_cert(bio_err, *args, FORMAT_PEM,
385: NULL, e, "certificate");
386: if(!cert) goto end;
387: if(!add_ocsp_cert(&req, cert, issuer, ids))
388: goto end;
389: if(!sk_push(reqnames, *args))
390: goto end;
391: }
392: else badarg = 1;
393: }
394: else if (!strcmp(*args, "-serial"))
395: {
396: if (args[1])
397: {
398: args++;
399: if(!add_ocsp_serial(&req, *args, issuer, ids))
400: goto end;
401: if(!sk_push(reqnames, *args))
402: goto end;
403: }
404: else badarg = 1;
405: }
406: else if (!strcmp(*args, "-index"))
407: {
408: if (args[1])
409: {
410: args++;
411: ridx_filename = *args;
412: }
413: else badarg = 1;
414: }
415: else if (!strcmp(*args, "-CA"))
416: {
417: if (args[1])
418: {
419: args++;
420: rca_filename = *args;
421: }
422: else badarg = 1;
423: }
424: else if (!strcmp (*args, "-nmin"))
425: {
426: if (args[1])
427: {
428: args++;
429: nmin = atol(*args);
430: if (nmin < 0)
431: {
432: BIO_printf(bio_err,
433: "Illegal update period %s\n",
434: *args);
435: badarg = 1;
436: }
437: }
438: if (ndays == -1)
439: ndays = 0;
440: else badarg = 1;
441: }
442: else if (!strcmp (*args, "-nrequest"))
443: {
444: if (args[1])
445: {
446: args++;
447: accept_count = atol(*args);
448: if (accept_count < 0)
449: {
450: BIO_printf(bio_err,
451: "Illegal accept count %s\n",
452: *args);
453: badarg = 1;
454: }
455: }
456: else badarg = 1;
457: }
458: else if (!strcmp (*args, "-ndays"))
459: {
460: if (args[1])
461: {
462: args++;
463: ndays = atol(*args);
464: if (ndays < 0)
465: {
466: BIO_printf(bio_err,
467: "Illegal update period %s\n",
468: *args);
469: badarg = 1;
470: }
471: }
472: else badarg = 1;
473: }
474: else if (!strcmp(*args, "-rsigner"))
475: {
476: if (args[1])
477: {
478: args++;
479: rsignfile = *args;
480: }
481: else badarg = 1;
482: }
483: else if (!strcmp(*args, "-rkey"))
484: {
485: if (args[1])
486: {
487: args++;
488: rkeyfile = *args;
489: }
490: else badarg = 1;
491: }
492: else if (!strcmp(*args, "-rother"))
493: {
494: if (args[1])
495: {
496: args++;
497: rcertfile = *args;
498: }
499: else badarg = 1;
500: }
501: else badarg = 1;
502: args++;
503: }
504:
505:
506: if (!req && !reqin && !respin && !(port && ridx_filename)) badarg = 1;
507:
508: if (badarg)
509: {
510: BIO_printf (bio_err, "OCSP utility\n");
511: BIO_printf (bio_err, "Usage ocsp [options]\n");
512: BIO_printf (bio_err, "where options are\n");
513: BIO_printf (bio_err, "-out file output filename\n");
514: BIO_printf (bio_err, "-issuer file issuer certificate\n");
515: BIO_printf (bio_err, "-cert file certificate to check\n");
516: BIO_printf (bio_err, "-serial n serial number to check\n");
517: BIO_printf (bio_err, "-signer file certificate to sign OCSP request with\n");
518: BIO_printf (bio_err, "-signkey file private key to sign OCSP request with\n");
519: BIO_printf (bio_err, "-sign_other file additional certificates to include in signed request\n");
520: BIO_printf (bio_err, "-no_certs don't include any certificates in signed request\n");
521: BIO_printf (bio_err, "-req_text print text form of request\n");
522: BIO_printf (bio_err, "-resp_text print text form of response\n");
523: BIO_printf (bio_err, "-text print text form of request and response\n");
524: BIO_printf (bio_err, "-reqout file write DER encoded OCSP request to \"file\"\n");
525: BIO_printf (bio_err, "-respout file write DER encoded OCSP reponse to \"file\"\n");
526: BIO_printf (bio_err, "-reqin file read DER encoded OCSP request from \"file\"\n");
527: BIO_printf (bio_err, "-respin file read DER encoded OCSP reponse from \"file\"\n");
528: BIO_printf (bio_err, "-nonce add OCSP nonce to request\n");
529: BIO_printf (bio_err, "-no_nonce don't add OCSP nonce to request\n");
530: BIO_printf (bio_err, "-url URL OCSP responder URL\n");
531: BIO_printf (bio_err, "-host host:n send OCSP request to host on port n\n");
532: BIO_printf (bio_err, "-path path to use in OCSP request\n");
533: BIO_printf (bio_err, "-CApath dir trusted certificates directory\n");
534: BIO_printf (bio_err, "-CAfile file trusted certificates file\n");
535: BIO_printf (bio_err, "-VAfile file validator certificates file\n");
536: BIO_printf (bio_err, "-validity_period n maximum validity discrepancy in seconds\n");
537: BIO_printf (bio_err, "-status_age n maximum status age in seconds\n");
538: BIO_printf (bio_err, "-noverify don't verify response at all\n");
539: BIO_printf (bio_err, "-verify_other file additional certificates to search for signer\n");
540: BIO_printf (bio_err, "-trust_other don't verify additional certificates\n");
541: BIO_printf (bio_err, "-no_intern don't search certificates contained in response for signer\n");
542: BIO_printf (bio_err, "-no_signature_verify don't check signature on response\n");
543: BIO_printf (bio_err, "-no_cert_verify don't check signing certificate\n");
544: BIO_printf (bio_err, "-no_chain don't chain verify response\n");
545: BIO_printf (bio_err, "-no_cert_checks don't do additional checks on signing certificate\n");
546: BIO_printf (bio_err