diff options
author | inoguchi <> | 2020-09-09 12:53:42 +0000 |
---|---|---|
committer | inoguchi <> | 2020-09-09 12:53:42 +0000 |
commit | 65d503c40fc92a463c6ab5b70929e16f354e3a5e (patch) | |
tree | d950859713827f501d7c4c029709b0e2fdd05c0c | |
parent | 6917ee449301c0951b71dba3abd88c5a89f7a2c4 (diff) | |
download | openbsd-65d503c40fc92a463c6ab5b70929e16f354e3a5e.tar.gz openbsd-65d503c40fc92a463c6ab5b70929e16f354e3a5e.tar.bz2 openbsd-65d503c40fc92a463c6ab5b70929e16f354e3a5e.zip |
Convert openssl(1) ocsp option handling
input and ok tb@
-rw-r--r-- | src/usr.bin/openssl/ocsp.c | 1168 |
1 files changed, 725 insertions, 443 deletions
diff --git a/src/usr.bin/openssl/ocsp.c b/src/usr.bin/openssl/ocsp.c index 04a719bf40..5e060715f5 100644 --- a/src/usr.bin/openssl/ocsp.c +++ b/src/usr.bin/openssl/ocsp.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ocsp.c,v 1.15 2018/02/07 05:49:36 jsing Exp $ */ | 1 | /* $OpenBSD: ocsp.c,v 1.16 2020/09/09 12:53:42 inoguchi Exp $ */ |
2 | /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL | 2 | /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL |
3 | * project 2000. | 3 | * project 2000. |
4 | */ | 4 | */ |
@@ -102,49 +102,655 @@ static OCSP_RESPONSE *query_responder(BIO * err, BIO * cbio, char *path, | |||
102 | STACK_OF(CONF_VALUE) * headers, | 102 | STACK_OF(CONF_VALUE) * headers, |
103 | OCSP_REQUEST * req, int req_timeout); | 103 | OCSP_REQUEST * req, int req_timeout); |
104 | 104 | ||
105 | static struct { | ||
106 | int accept_count; | ||
107 | int add_nonce; | ||
108 | char *CAfile; | ||
109 | char *CApath; | ||
110 | X509 *cert; | ||
111 | const EVP_MD *cert_id_md; | ||
112 | STACK_OF(CONF_VALUE) * headers; | ||
113 | char *host; | ||
114 | STACK_OF(OCSP_CERTID) * ids; | ||
115 | int ignore_err; | ||
116 | X509 *issuer; | ||
117 | char *keyfile; | ||
118 | long maxage; | ||
119 | int ndays; | ||
120 | int nmin; | ||
121 | int no_usage; | ||
122 | int noverify; | ||
123 | long nsec; | ||
124 | char *outfile; | ||
125 | char *path; | ||
126 | char *port; | ||
127 | char *rca_filename; | ||
128 | char *rcertfile; | ||
129 | OCSP_REQUEST *req; | ||
130 | int req_text; | ||
131 | int req_timeout; | ||
132 | char *reqin; | ||
133 | STACK_OF(OPENSSL_STRING) * reqnames; | ||
134 | char *reqout; | ||
135 | int resp_text; | ||
136 | char *respin; | ||
137 | char *respout; | ||
138 | unsigned long rflags; | ||
139 | char *ridx_filename; | ||
140 | char *rkeyfile; | ||
141 | char *rsignfile; | ||
142 | char *sign_certfile; | ||
143 | unsigned long sign_flags; | ||
144 | char *signfile; | ||
145 | int use_ssl; | ||
146 | char *verify_certfile; | ||
147 | unsigned long verify_flags; | ||
148 | } ocsp_config; | ||
149 | |||
150 | static int | ||
151 | ocsp_opt_cert(char *arg) | ||
152 | { | ||
153 | X509_free(ocsp_config.cert); | ||
154 | ocsp_config.cert = load_cert(bio_err, arg, FORMAT_PEM, NULL, | ||
155 | "certificate"); | ||
156 | if (ocsp_config.cert == NULL) { | ||
157 | ocsp_config.no_usage = 1; | ||
158 | return (1); | ||
159 | } | ||
160 | if (ocsp_config.cert_id_md == NULL) | ||
161 | ocsp_config.cert_id_md = EVP_sha1(); | ||
162 | if (!add_ocsp_cert(&ocsp_config.req, ocsp_config.cert, | ||
163 | ocsp_config.cert_id_md, ocsp_config.issuer, ocsp_config.ids)) { | ||
164 | ocsp_config.no_usage = 1; | ||
165 | return (1); | ||
166 | } | ||
167 | if (!sk_OPENSSL_STRING_push(ocsp_config.reqnames, arg)) { | ||
168 | ocsp_config.no_usage = 1; | ||
169 | return (1); | ||
170 | } | ||
171 | return (0); | ||
172 | } | ||
173 | |||
174 | static int | ||
175 | ocsp_opt_cert_id_md(int argc, char **argv, int *argsused) | ||
176 | { | ||
177 | char *name = argv[0]; | ||
178 | |||
179 | if (*name++ != '-') | ||
180 | return (1); | ||
181 | |||
182 | if ((ocsp_config.cert_id_md = EVP_get_digestbyname(name)) == NULL) | ||
183 | return (1); | ||
184 | |||
185 | *argsused = 1; | ||
186 | return (0); | ||
187 | } | ||
188 | |||
189 | static int | ||
190 | ocsp_opt_header(int argc, char **argv, int *argsused) | ||
191 | { | ||
192 | if (argc < 3 || argv[1] == NULL || argv[2] == NULL) | ||
193 | return (1); | ||
194 | |||
195 | if (!X509V3_add_value(argv[1], argv[2], &ocsp_config.headers)) { | ||
196 | ocsp_config.no_usage = 1; | ||
197 | return (1); | ||
198 | } | ||
199 | |||
200 | *argsused = 3; | ||
201 | return (0); | ||
202 | } | ||
203 | |||
204 | static int | ||
205 | ocsp_opt_host(char *arg) | ||
206 | { | ||
207 | if (ocsp_config.use_ssl != -1) | ||
208 | return (1); | ||
209 | |||
210 | ocsp_config.host = arg; | ||
211 | return (0); | ||
212 | } | ||
213 | |||
214 | static int | ||
215 | ocsp_opt_issuer(char *arg) | ||
216 | { | ||
217 | X509_free(ocsp_config.issuer); | ||
218 | ocsp_config.issuer = load_cert(bio_err, arg, FORMAT_PEM, NULL, | ||
219 | "issuer certificate"); | ||
220 | if (ocsp_config.issuer == NULL) { | ||
221 | ocsp_config.no_usage = 1; | ||
222 | return (1); | ||
223 | } | ||
224 | return (0); | ||
225 | } | ||
226 | |||
227 | static int | ||
228 | ocsp_opt_ndays(char *arg) | ||
229 | { | ||
230 | const char *errstr = NULL; | ||
231 | |||
232 | ocsp_config.ndays = strtonum(arg, 0, INT_MAX, &errstr); | ||
233 | if (errstr != NULL) { | ||
234 | BIO_printf(bio_err, "Illegal update period %s: %s\n", | ||
235 | arg, errstr); | ||
236 | return (1); | ||
237 | } | ||
238 | return (0); | ||
239 | } | ||
240 | |||
241 | static int | ||
242 | ocsp_opt_nmin(char *arg) | ||
243 | { | ||
244 | const char *errstr = NULL; | ||
245 | |||
246 | ocsp_config.nmin = strtonum(arg, 0, INT_MAX, &errstr); | ||
247 | if (errstr != NULL) { | ||
248 | BIO_printf(bio_err, "Illegal update period %s: %s\n", | ||
249 | arg, errstr); | ||
250 | return (1); | ||
251 | } | ||
252 | |||
253 | if (ocsp_config.ndays != -1) | ||
254 | return (1); | ||
255 | |||
256 | ocsp_config.ndays = 0; | ||
257 | return (0); | ||
258 | } | ||
259 | |||
260 | static int | ||
261 | ocsp_opt_nrequest(char *arg) | ||
262 | { | ||
263 | const char *errstr = NULL; | ||
264 | |||
265 | ocsp_config.accept_count = strtonum(arg, 0, INT_MAX, &errstr); | ||
266 | if (errstr != NULL) { | ||
267 | BIO_printf(bio_err, "Illegal accept count %s: %s\n", | ||
268 | arg, errstr); | ||
269 | return (1); | ||
270 | } | ||
271 | return (0); | ||
272 | } | ||
273 | |||
274 | static int | ||
275 | ocsp_opt_port(char *arg) | ||
276 | { | ||
277 | if (ocsp_config.use_ssl != -1) | ||
278 | return (1); | ||
279 | |||
280 | ocsp_config.port = arg; | ||
281 | return (0); | ||
282 | } | ||
283 | |||
284 | static int | ||
285 | ocsp_opt_serial(char *arg) | ||
286 | { | ||
287 | if (ocsp_config.cert_id_md == NULL) | ||
288 | ocsp_config.cert_id_md = EVP_sha1(); | ||
289 | if (!add_ocsp_serial(&ocsp_config.req, arg, ocsp_config.cert_id_md, | ||
290 | ocsp_config.issuer, ocsp_config.ids)) { | ||
291 | ocsp_config.no_usage = 1; | ||
292 | return (1); | ||
293 | } | ||
294 | if (!sk_OPENSSL_STRING_push(ocsp_config.reqnames, arg)) { | ||
295 | ocsp_config.no_usage = 1; | ||
296 | return (1); | ||
297 | } | ||
298 | return (0); | ||
299 | } | ||
300 | |||
301 | static int | ||
302 | ocsp_opt_status_age(char *arg) | ||
303 | { | ||
304 | const char *errstr = NULL; | ||
305 | |||
306 | ocsp_config.maxage = strtonum(arg, 0, LONG_MAX, &errstr); | ||
307 | if (errstr != NULL) { | ||
308 | BIO_printf(bio_err, "Illegal validity age %s: %s\n", | ||
309 | arg, errstr); | ||
310 | return (1); | ||
311 | } | ||
312 | return (0); | ||
313 | } | ||
314 | |||
315 | static int | ||
316 | ocsp_opt_text(void) | ||
317 | { | ||
318 | ocsp_config.req_text = 1; | ||
319 | ocsp_config.resp_text = 1; | ||
320 | return (0); | ||
321 | } | ||
322 | |||
323 | static int | ||
324 | ocsp_opt_timeout(char *arg) | ||
325 | { | ||
326 | const char *errstr = NULL; | ||
327 | |||
328 | ocsp_config.req_timeout = strtonum(arg, 0, INT_MAX, &errstr); | ||
329 | if (errstr != NULL) { | ||
330 | BIO_printf(bio_err, "Illegal timeout value %s: %s\n", | ||
331 | arg, errstr); | ||
332 | return (1); | ||
333 | } | ||
334 | return (0); | ||
335 | } | ||
336 | |||
337 | static int | ||
338 | ocsp_opt_url(char *arg) | ||
339 | { | ||
340 | if (ocsp_config.host == NULL && ocsp_config.port == NULL && | ||
341 | ocsp_config.path == NULL) { | ||
342 | if (!OCSP_parse_url(arg, &ocsp_config.host, &ocsp_config.port, | ||
343 | &ocsp_config.path, &ocsp_config.use_ssl)) { | ||
344 | BIO_printf(bio_err, "Error parsing URL\n"); | ||
345 | return (1); | ||
346 | } | ||
347 | } | ||
348 | return (0); | ||
349 | } | ||
350 | |||
351 | static int | ||
352 | ocsp_opt_vafile(char *arg) | ||
353 | { | ||
354 | ocsp_config.verify_certfile = arg; | ||
355 | ocsp_config.verify_flags |= OCSP_TRUSTOTHER; | ||
356 | return (0); | ||
357 | } | ||
358 | |||
359 | static int | ||
360 | ocsp_opt_validity_period(char *arg) | ||
361 | { | ||
362 | const char *errstr = NULL; | ||
363 | |||
364 | ocsp_config.nsec = strtonum(arg, 0, LONG_MAX, &errstr); | ||
365 | if (errstr != NULL) { | ||
366 | BIO_printf(bio_err, "Illegal validity period %s: %s\n", | ||
367 | arg, errstr); | ||
368 | return (1); | ||
369 | } | ||
370 | return (0); | ||
371 | } | ||
372 | |||
373 | static const struct option ocsp_options[] = { | ||
374 | { | ||
375 | .name = "CA", | ||
376 | .argname = "file", | ||
377 | .desc = "CA certificate corresponding to the revocation information", | ||
378 | .type = OPTION_ARG, | ||
379 | .opt.arg = &ocsp_config.rca_filename, | ||
380 | }, | ||
381 | { | ||
382 | .name = "CAfile", | ||
383 | .argname = "file", | ||
384 | .desc = "Trusted certificates file", | ||
385 | .type = OPTION_ARG, | ||
386 | .opt.arg = &ocsp_config.CAfile, | ||
387 | }, | ||
388 | { | ||
389 | .name = "CApath", | ||
390 | .argname = "directory", | ||
391 | .desc = "Trusted certificates directory", | ||
392 | .type = OPTION_ARG, | ||
393 | .opt.arg = &ocsp_config.CApath, | ||
394 | }, | ||
395 | { | ||
396 | .name = "cert", | ||
397 | .argname = "file", | ||
398 | .desc = "Certificate to check", | ||
399 | .type = OPTION_ARG_FUNC, | ||
400 | .opt.argfunc = ocsp_opt_cert, | ||
401 | }, | ||
402 | { | ||
403 | .name = "header", | ||
404 | .argname = "name value", | ||
405 | .desc = "Add the header name with the value to the request", | ||
406 | .type = OPTION_ARGV_FUNC, | ||
407 | .opt.argvfunc = ocsp_opt_header, | ||
408 | }, | ||
409 | { | ||
410 | .name = "host", | ||
411 | .argname = "hostname:port", | ||
412 | .desc = "Send OCSP request to host on port", | ||
413 | .type = OPTION_ARG_FUNC, | ||
414 | .opt.argfunc = ocsp_opt_host, | ||
415 | }, | ||
416 | { | ||
417 | .name = "ignore_err", | ||
418 | .desc = "Ignore the invalid response", | ||
419 | .type = OPTION_FLAG, | ||
420 | .opt.flag = &ocsp_config.ignore_err, | ||
421 | }, | ||
422 | { | ||
423 | .name = "index", | ||
424 | .argname = "indexfile", | ||
425 | .desc = "Certificate status index file", | ||
426 | .type = OPTION_ARG, | ||
427 | .opt.arg = &ocsp_config.ridx_filename, | ||
428 | }, | ||
429 | { | ||
430 | .name = "issuer", | ||
431 | .argname = "file", | ||
432 | .desc = "Issuer certificate", | ||
433 | .type = OPTION_ARG_FUNC, | ||
434 | .opt.argfunc = ocsp_opt_issuer, | ||
435 | }, | ||
436 | { | ||
437 | .name = "ndays", | ||
438 | .argname = "days", | ||
439 | .desc = "Number of days before next update", | ||
440 | .type = OPTION_ARG_FUNC, | ||
441 | .opt.argfunc = ocsp_opt_ndays, | ||
442 | }, | ||
443 | { | ||
444 | .name = "nmin", | ||
445 | .argname = "minutes", | ||
446 | .desc = "Number of minutes before next update", | ||
447 | .type = OPTION_ARG_FUNC, | ||
448 | .opt.argfunc = ocsp_opt_nmin, | ||
449 | }, | ||
450 | { | ||
451 | .name = "no_cert_checks", | ||
452 | .desc = "Don't do additional checks on signing certificate", | ||
453 | .type = OPTION_UL_VALUE_OR, | ||
454 | .opt.ulvalue = &ocsp_config.verify_flags, | ||
455 | .ulvalue = OCSP_NOCHECKS, | ||
456 | }, | ||
457 | { | ||
458 | .name = "no_cert_verify", | ||
459 | .desc = "Don't check signing certificate", | ||
460 | .type = OPTION_UL_VALUE_OR, | ||
461 | .opt.ulvalue = &ocsp_config.verify_flags, | ||
462 | .ulvalue = OCSP_NOVERIFY, | ||
463 | }, | ||
464 | { | ||
465 | .name = "no_certs", | ||
466 | .desc = "Don't include any certificates in signed request", | ||
467 | .type = OPTION_UL_VALUE_OR, | ||
468 | .opt.ulvalue = &ocsp_config.sign_flags, | ||
469 | .ulvalue = OCSP_NOCERTS, | ||
470 | }, | ||
471 | { | ||
472 | .name = "no_chain", | ||
473 | .desc = "Don't use certificates in the response", | ||
474 | .type = OPTION_UL_VALUE_OR, | ||
475 | .opt.ulvalue = &ocsp_config.verify_flags, | ||
476 | .ulvalue = OCSP_NOCHAIN, | ||
477 | }, | ||
478 | { | ||
479 | .name = "no_explicit", | ||
480 | .desc = "Don't check the explicit trust for OCSP signing", | ||
481 | .type = OPTION_UL_VALUE_OR, | ||
482 | .opt.ulvalue = &ocsp_config.verify_flags, | ||
483 | .ulvalue = OCSP_NOEXPLICIT, | ||
484 | }, | ||
485 | { | ||
486 | .name = "no_intern", | ||
487 | .desc = "Don't search certificates contained in response for signer", | ||
488 | .type = OPTION_UL_VALUE_OR, | ||
489 | .opt.ulvalue = &ocsp_config.verify_flags, | ||
490 | .ulvalue = OCSP_NOINTERN, | ||
491 | }, | ||
492 | { | ||
493 | .name = "no_nonce", | ||
494 | .desc = "Don't add OCSP nonce to request", | ||
495 | .type = OPTION_VALUE, | ||
496 | .opt.value = &ocsp_config.add_nonce, | ||
497 | .value = 0, | ||
498 | }, | ||
499 | { | ||
500 | .name = "no_signature_verify", | ||
501 | .desc = "Don't check signature on response", | ||
502 | .type = OPTION_UL_VALUE_OR, | ||
503 | .opt.ulvalue = &ocsp_config.verify_flags, | ||
504 | .ulvalue = OCSP_NOSIGS, | ||
505 | }, | ||
506 | { | ||
507 | .name = "nonce", | ||
508 | .desc = "Add OCSP nonce to request", | ||
509 | .type = OPTION_VALUE, | ||
510 | .opt.value = &ocsp_config.add_nonce, | ||
511 | .value = 2, | ||
512 | }, | ||
513 | { | ||
514 | .name = "noverify", | ||
515 | .desc = "Don't verify response at all", | ||
516 | .type = OPTION_FLAG, | ||
517 | .opt.flag = &ocsp_config.noverify, | ||
518 | }, | ||
519 | { | ||
520 | .name = "nrequest", | ||
521 | .argname = "number", | ||
522 | .desc = "Number of requests to accept (default unlimited)", | ||
523 | .type = OPTION_ARG_FUNC, | ||
524 | .opt.argfunc = ocsp_opt_nrequest, | ||
525 | }, | ||
526 | { | ||
527 | .name = "out", | ||
528 | .argname = "file", | ||
529 | .desc = "Output filename", | ||
530 | .type = OPTION_ARG, | ||
531 | .opt.arg = &ocsp_config.outfile, | ||
532 | }, | ||
533 | { | ||
534 | .name = "path", | ||
535 | .argname = "path", | ||
536 | .desc = "Path to use in OCSP request", | ||
537 | .type = OPTION_ARG, | ||
538 | .opt.arg = &ocsp_config.path, | ||
539 | }, | ||
540 | { | ||
541 | .name = "port", | ||
542 | .argname = "portnum", | ||
543 | .desc = "Port to run responder on", | ||
544 | .type = OPTION_ARG_FUNC, | ||
545 | .opt.argfunc = ocsp_opt_port, | ||
546 | }, | ||
547 | { | ||
548 | .name = "req_text", | ||
549 | .desc = "Print text form of request", | ||
550 | .type = OPTION_FLAG, | ||
551 | .opt.flag = &ocsp_config.req_text, | ||
552 | }, | ||
553 | { | ||
554 | .name = "reqin", | ||
555 | .argname = "file", | ||
556 | .desc = "Read DER encoded OCSP request from \"file\"", | ||
557 | .type = OPTION_ARG, | ||
558 | .opt.arg = &ocsp_config.reqin, | ||
559 | }, | ||
560 | { | ||
561 | .name = "reqout", | ||
562 | .argname = "file", | ||
563 | .desc = "Write DER encoded OCSP request to \"file\"", | ||
564 | .type = OPTION_ARG, | ||
565 | .opt.arg = &ocsp_config.reqout, | ||
566 | }, | ||
567 | { | ||
568 | .name = "resp_key_id", | ||
569 | .desc = "Identify response by signing certificate key ID", | ||
570 | .type = OPTION_UL_VALUE_OR, | ||
571 | .opt.ulvalue = &ocsp_config.rflags, | ||
572 | .ulvalue = OCSP_RESPID_KEY, | ||
573 | }, | ||
574 | { | ||
575 | .name = "resp_no_certs", | ||
576 | .desc = "Don't include any certificates in response", | ||
577 | .type = OPTION_UL_VALUE_OR, | ||
578 | .opt.ulvalue = &ocsp_config.rflags, | ||
579 | .ulvalue = OCSP_NOCERTS, | ||
580 | }, | ||
581 | { | ||
582 | .name = "resp_text", | ||
583 | .desc = "Print text form of response", | ||
584 | .type = OPTION_FLAG, | ||
585 | .opt.flag = &ocsp_config.resp_text, | ||
586 | }, | ||
587 | { | ||
588 | .name = "respin", | ||
589 | .argname = "file", | ||
590 | .desc = "Read DER encoded OCSP response from \"file\"", | ||
591 | .type = OPTION_ARG, | ||
592 | .opt.arg = &ocsp_config.respin, | ||
593 | }, | ||
594 | { | ||
595 | .name = "respout", | ||
596 | .argname = "file", | ||
597 | .desc = "Write DER encoded OCSP response to \"file\"", | ||
598 | .type = OPTION_ARG, | ||
599 | .opt.arg = &ocsp_config.respout, | ||
600 | }, | ||
601 | { | ||
602 | .name = "rkey", | ||
603 | .argname = "file", | ||
604 | .desc = "Responder key to sign responses with", | ||
605 | .type = OPTION_ARG, | ||
606 | .opt.arg = &ocsp_config.rkeyfile, | ||
607 | }, | ||
608 | { | ||
609 | .name = "rother", | ||
610 | .argname = "file", | ||
611 | .desc = "Other certificates to include in response", | ||
612 | .type = OPTION_ARG, | ||
613 | .opt.arg = &ocsp_config.rcertfile, | ||
614 | }, | ||
615 | { | ||
616 | .name = "rsigner", | ||
617 | .argname = "file", | ||
618 | .desc = "Responder certificate to sign responses with", | ||
619 | .type = OPTION_ARG, | ||
620 | .opt.arg = &ocsp_config.rsignfile, | ||
621 | }, | ||
622 | { | ||
623 | .name = "serial", | ||
624 | .argname = "num", | ||
625 | .desc = "Serial number to check", | ||
626 | .type = OPTION_ARG_FUNC, | ||
627 | .opt.argfunc = ocsp_opt_serial, | ||
628 | }, | ||
629 | { | ||
630 | .name = "sign_other", | ||
631 | .argname = "file", | ||
632 | .desc = "Additional certificates to include in signed request", | ||
633 | .type = OPTION_ARG, | ||
634 | .opt.arg = &ocsp_config.sign_certfile, | ||
635 | }, | ||
636 | { | ||
637 | .name = "signer", | ||
638 | .argname = "file", | ||
639 | .desc = "Certificate to sign OCSP request with", | ||
640 | .type = OPTION_ARG, | ||
641 | .opt.arg = &ocsp_config.signfile, | ||
642 | }, | ||
643 | { | ||
644 | .name = "signkey", | ||
645 | .argname = "file", | ||
646 | .desc = "Private key to sign OCSP request with", | ||
647 | .type = OPTION_ARG, | ||
648 | .opt.arg = &ocsp_config.keyfile, | ||
649 | }, | ||
650 | { | ||
651 | .name = "status_age", | ||
652 | .argname = "age", | ||
653 | .desc = "Maximum status age in seconds", | ||
654 | .type = OPTION_ARG_FUNC, | ||
655 | .opt.argfunc = ocsp_opt_status_age, | ||
656 | }, | ||
657 | { | ||
658 | .name = "text", | ||
659 | .desc = "Print text form of request and response", | ||
660 | .type = OPTION_FUNC, | ||
661 | .opt.func = ocsp_opt_text, | ||
662 | }, | ||
663 | { | ||
664 | .name = "timeout", | ||
665 | .argname = "seconds", | ||
666 | .desc = "Connection timeout to the OCSP responder in seconds", | ||
667 | .type = OPTION_ARG_FUNC, | ||
668 | .opt.argfunc = ocsp_opt_timeout, | ||
669 | }, | ||
670 | { | ||
671 | .name = "trust_other", | ||
672 | .desc = "Don't verify additional certificates", | ||
673 | .type = OPTION_UL_VALUE_OR, | ||
674 | .opt.ulvalue = &ocsp_config.verify_flags, | ||
675 | .ulvalue = OCSP_TRUSTOTHER, | ||
676 | }, | ||
677 | { | ||
678 | .name = "url", | ||
679 | .argname = "responder_url", | ||
680 | .desc = "OCSP responder URL", | ||
681 | .type = OPTION_ARG_FUNC, | ||
682 | .opt.argfunc = ocsp_opt_url, | ||
683 | }, | ||
684 | { | ||
685 | .name = "VAfile", | ||
686 | .argname = "file", | ||
687 | .desc = "Explicitly trusted responder certificates", | ||
688 | .type = OPTION_ARG_FUNC, | ||
689 | .opt.argfunc = ocsp_opt_vafile, | ||
690 | }, | ||
691 | { | ||
692 | .name = "validity_period", | ||
693 | .argname = "n", | ||
694 | .desc = "Maximum validity discrepancy in seconds", | ||
695 | .type = OPTION_ARG_FUNC, | ||
696 | .opt.argfunc = ocsp_opt_validity_period, | ||
697 | }, | ||
698 | { | ||
699 | .name = "verify_other", | ||
700 | .argname = "file", | ||
701 | .desc = "Additional certificates to search for signer", | ||
702 | .type = OPTION_ARG, | ||
703 | .opt.arg = &ocsp_config.verify_certfile, | ||
704 | }, | ||
705 | { | ||
706 | .name = NULL, | ||
707 | .desc = "", | ||
708 | .type = OPTION_ARGV_FUNC, | ||
709 | .opt.argvfunc = ocsp_opt_cert_id_md, | ||
710 | }, | ||
711 | { NULL }, | ||
712 | }; | ||
713 | |||
714 | static void | ||
715 | ocsp_usage(void) | ||
716 | { | ||
717 | fprintf(stderr, "usage: ocsp " | ||
718 | "[-CA file] [-CAfile file] [-CApath directory] [-cert file]\n" | ||
719 | " [-dgst alg] [-header name value] [-host hostname:port]\n" | ||
720 | " [-ignore_err] [-index indexfile] [-issuer file]\n" | ||
721 | " [-ndays days] [-nmin minutes] [-no_cert_checks]\n" | ||
722 | " [-no_cert_verify] [-no_certs] [-no_chain] [-no_explicit]\n" | ||
723 | " [-no_intern] [-no_nonce] [-no_signature_verify] [-nonce]\n" | ||
724 | " [-noverify] [-nrequest number] [-out file] [-path path]\n" | ||
725 | " [-port portnum] [-req_text] [-reqin file] [-reqout file]\n" | ||
726 | " [-resp_key_id] [-resp_no_certs] [-resp_text] [-respin file]\n" | ||
727 | " [-respout file] [-rkey file] [-rother file] [-rsigner file]\n" | ||
728 | " [-serial num] [-sign_other file] [-signer file]\n" | ||
729 | " [-signkey file] [-status_age age] [-text]\n" | ||
730 | " [-timeout seconds] [-trust_other] [-url responder_url]\n" | ||
731 | " [-VAfile file] [-validity_period nsec] [-verify_other file]\n"); | ||
732 | fprintf(stderr, "\n"); | ||
733 | options_usage(ocsp_options); | ||
734 | fprintf(stderr, "\n"); | ||
735 | } | ||
736 | |||
105 | int | 737 | int |
106 | ocsp_main(int argc, char **argv) | 738 | ocsp_main(int argc, char **argv) |
107 | { | 739 | { |
108 | char **args; | ||
109 | char *host = NULL, *port = NULL, *path = NULL; | ||
110 | char *reqin = NULL, *respin = NULL; | ||
111 | char *reqout = NULL, *respout = NULL; | ||
112 | char *signfile = NULL, *keyfile = NULL; | ||
113 | char *rsignfile = NULL, *rkeyfile = NULL; | ||
114 | char *outfile = NULL; | ||
115 | int add_nonce = 1, noverify = 0, use_ssl = -1; | ||
116 | STACK_OF(CONF_VALUE) * headers = NULL; | ||
117 | OCSP_REQUEST *req = NULL; | ||
118 | OCSP_RESPONSE *resp = NULL; | 740 | OCSP_RESPONSE *resp = NULL; |
119 | OCSP_BASICRESP *bs = NULL; | 741 | OCSP_BASICRESP *bs = NULL; |
120 | X509 *issuer = NULL, *cert = NULL; | ||
121 | X509 *signer = NULL, *rsigner = NULL; | 742 | X509 *signer = NULL, *rsigner = NULL; |
122 | EVP_PKEY *key = NULL, *rkey = NULL; | 743 | EVP_PKEY *key = NULL, *rkey = NULL; |
123 | BIO *acbio = NULL, *cbio = NULL; | 744 | BIO *acbio = NULL, *cbio = NULL; |
124 | BIO *derbio = NULL; | 745 | BIO *derbio = NULL; |
125 | BIO *out = NULL; | 746 | BIO *out = NULL; |
126 | int req_timeout = -1; | ||
127 | int req_text = 0, resp_text = 0; | ||
128 | long nsec = MAX_VALIDITY_PERIOD, maxage = -1; | ||
129 | char *CAfile = NULL, *CApath = NULL; | ||
130 | X509_STORE *store = NULL; | 747 | X509_STORE *store = NULL; |
131 | STACK_OF(X509) * sign_other = NULL, *verify_other = NULL, *rother = NULL; | 748 | STACK_OF(X509) * sign_other = NULL, *verify_other = NULL, *rother = NULL; |
132 | char *sign_certfile = NULL, *verify_certfile = NULL, *rcertfile = NULL; | ||
133 | unsigned long sign_flags = 0, verify_flags = 0, rflags = 0; | ||
134 | int ret = 1; | 749 | int ret = 1; |
135 | int accept_count = -1; | ||
136 | int badarg = 0; | 750 | int badarg = 0; |
137 | int i; | 751 | int i; |
138 | int ignore_err = 0; | ||
139 | STACK_OF(OPENSSL_STRING) * reqnames = NULL; | ||
140 | STACK_OF(OCSP_CERTID) * ids = NULL; | ||
141 | X509 *rca_cert = NULL; | 752 | X509 *rca_cert = NULL; |
142 | char *ridx_filename = NULL; | ||
143 | char *rca_filename = NULL; | ||
144 | CA_DB *rdb = NULL; | 753 | CA_DB *rdb = NULL; |
145 | int nmin = 0, ndays = -1; | ||
146 | const EVP_MD *cert_id_md = NULL; | ||
147 | const char *errstr = NULL; | ||
148 | 754 | ||
149 | if (single_execution) { | 755 | if (single_execution) { |
150 | if (pledge("stdio cpath wpath rpath inet dns tty", NULL) == -1) { | 756 | if (pledge("stdio cpath wpath rpath inet dns tty", NULL) == -1) { |
@@ -153,359 +759,36 @@ ocsp_main(int argc, char **argv) | |||
153 | } | 759 | } |
154 | } | 760 | } |
155 | 761 | ||
156 | args = argv + 1; | 762 | memset(&ocsp_config, 0, sizeof(ocsp_config)); |
157 | reqnames = sk_OPENSSL_STRING_new_null(); | 763 | ocsp_config.accept_count = -1; |
158 | ids = sk_OCSP_CERTID_new_null(); | 764 | ocsp_config.add_nonce = 1; |
159 | while (!badarg && *args && *args[0] == '-') { | 765 | if ((ocsp_config.ids = sk_OCSP_CERTID_new_null()) == NULL) |
160 | if (!strcmp(*args, "-out")) { | 766 | goto end; |
161 | if (args[1]) { | 767 | ocsp_config.maxage = -1; |
162 | args++; | 768 | ocsp_config.ndays = -1; |
163 | outfile = *args; | 769 | ocsp_config.nsec = MAX_VALIDITY_PERIOD; |
164 | } else | 770 | ocsp_config.req_timeout = -1; |
165 | badarg = 1; | 771 | if ((ocsp_config.reqnames = sk_OPENSSL_STRING_new_null()) == NULL) |
166 | } else if (!strcmp(*args, "-timeout")) { | 772 | goto end; |
167 | if (args[1]) { | 773 | ocsp_config.use_ssl = -1; |
168 | args++; | 774 | |
169 | req_timeout = strtonum(*args, 0, | 775 | if (options_parse(argc, argv, ocsp_options, NULL, NULL) != 0) { |
170 | INT_MAX, &errstr); | 776 | if (ocsp_config.no_usage) |
171 | if (errstr) { | 777 | goto end; |
172 | BIO_printf(bio_err, | 778 | else |
173 | "Illegal timeout value %s: %s\n", | ||
174 | *args, errstr); | ||
175 | badarg = 1; | ||
176 | } | ||
177 | } else | ||
178 | badarg = 1; | ||
179 | } else if (!strcmp(*args, "-url")) { | ||
180 | if (args[1] && host == NULL && port == NULL && | ||
181 | path == NULL) { | ||
182 | args++; | ||
183 | if (!OCSP_parse_url(*args, &host, &port, &path, &use_ssl)) { | ||
184 | BIO_printf(bio_err, "Error parsing URL\n"); | ||
185 | badarg = 1; | ||
186 | } | ||
187 | } else | ||
188 | badarg = 1; | ||
189 | } else if (!strcmp(*args, "-host")) { | ||
190 | if (args[1] && use_ssl == -1) { | ||
191 | args++; | ||
192 | host = *args; | ||
193 | } else | ||
194 | badarg = 1; | ||
195 | } else if (!strcmp(*args, "-port")) { | ||
196 | if (args[1] && use_ssl == -1) { | ||
197 | args++; | ||
198 | port = *args; | ||
199 | } else | ||
200 | badarg = 1; | ||
201 | } else if (!strcmp(*args, "-header")) { | ||
202 | if (args[1] && args[2]) { | ||
203 | if (!X509V3_add_value(args[1], args[2], &headers)) | ||
204 | goto end; | ||
205 | args += 2; | ||
206 | } else | ||
207 | badarg = 1; | ||
208 | } else if (!strcmp(*args, "-ignore_err")) | ||
209 | ignore_err = 1; | ||
210 | else if (!strcmp(*args, "-noverify")) | ||
211 | noverify = 1; | ||
212 | else if (!strcmp(*args, "-nonce")) | ||
213 | add_nonce = 2; | ||
214 | else if (!strcmp(*args, "-no_nonce")) | ||
215 | add_nonce = 0; | ||
216 | else if (!strcmp(*args, "-resp_no_certs")) | ||
217 | rflags |= OCSP_NOCERTS; | ||
218 | else if (!strcmp(*args, "-resp_key_id")) | ||
219 | rflags |= OCSP_RESPID_KEY; | ||
220 | else if (!strcmp(*args, "-no_certs")) | ||
221 | sign_flags |= OCSP_NOCERTS; | ||
222 | else if (!strcmp(*args, "-no_signature_verify")) | ||
223 | verify_flags |= OCSP_NOSIGS; | ||
224 | else if (!strcmp(*args, "-no_cert_verify")) | ||
225 | verify_flags |= OCSP_NOVERIFY; | ||
226 | else if (!strcmp(*args, "-no_chain")) | ||
227 | verify_flags |= OCSP_NOCHAIN; | ||
228 | else if (!strcmp(*args, "-no_cert_checks")) | ||
229 | verify_flags |= OCSP_NOCHECKS; | ||
230 | else if (!strcmp(*args, "-no_explicit")) | ||
231 | verify_flags |= OCSP_NOEXPLICIT; | ||
232 | else if (!strcmp(*args, "-trust_other")) | ||
233 | verify_flags |= OCSP_TRUSTOTHER; | ||
234 | else if (!strcmp(*args, "-no_intern")) | ||
235 | verify_flags |= OCSP_NOINTERN; | ||
236 | else if (!strcmp(*args, "-text")) { | ||
237 | req_text = 1; | ||
238 | resp_text = 1; | ||
239 | } else if (!strcmp(*args, "-req_text")) | ||
240 | req_text = 1; | ||
241 | else if (!strcmp(*args, "-resp_text")) | ||
242 | resp_text = 1; | ||
243 | else if (!strcmp(*args, "-reqin")) { | ||
244 | if (args[1]) { | ||
245 | args++; | ||
246 | reqin = *args; | ||
247 | } else | ||
248 | badarg = 1; | ||
249 | } else if (!strcmp(*args, "-respin")) { | ||
250 | if (args[1]) { | ||
251 | args++; | ||
252 | respin = *args; | ||
253 | } else | ||
254 | badarg = 1; | ||
255 | } else if (!strcmp(*args, "-signer")) { | ||
256 | if (args[1]) { | ||
257 | args++; | ||
258 | signfile = *args; | ||
259 | } else | ||
260 | badarg = 1; | ||
261 | } else if (!strcmp(*args, "-VAfile")) { | ||
262 | if (args[1]) { | ||
263 | args++; | ||
264 | verify_certfile = *args; | ||
265 | verify_flags |= OCSP_TRUSTOTHER; | ||
266 | } else | ||
267 | badarg = 1; | ||
268 | } else if (!strcmp(*args, "-sign_other")) { | ||
269 | if (args[1]) { | ||
270 | args++; | ||
271 | sign_certfile = *args; | ||
272 | } else | ||
273 | badarg = 1; | ||
274 | } else if (!strcmp(*args, "-verify_other")) { | ||
275 | if (args[1]) { | ||
276 | args++; | ||
277 | verify_certfile = *args; | ||
278 | } else | ||
279 | badarg = 1; | ||
280 | } else if (!strcmp(*args, "-CAfile")) { | ||
281 | if (args[1]) { | ||
282 | args++; | ||
283 | CAfile = *args; | ||
284 | } else | ||
285 | badarg = 1; | ||
286 | } else if (!strcmp(*args, "-CApath")) { | ||
287 | if (args[1]) { | ||
288 | args++; | ||
289 | CApath = *args; | ||
290 | } else | ||
291 | badarg = 1; | ||
292 | } else if (!strcmp(*args, "-validity_period")) { | ||
293 | if (args[1]) { | ||
294 | args++; | ||
295 | nsec = strtonum(*args, 0, LONG_MAX, &errstr); | ||
296 | if (errstr) { | ||
297 | BIO_printf(bio_err, | ||
298 | "Illegal validity period %s: %s\n", | ||
299 | *args, errstr); | ||
300 | badarg = 1; | ||
301 | } | ||
302 | } else | ||
303 | badarg = 1; | ||
304 | } else if (!strcmp(*args, "-status_age")) { | ||
305 | if (args[1]) { | ||
306 | args++; | ||
307 | maxage = strtonum(*args, 0, LONG_MAX, &errstr); | ||
308 | if (errstr) { | ||
309 | BIO_printf(bio_err, | ||
310 | "Illegal validity age %s: %s\n", | ||
311 | *args, errstr); | ||
312 | badarg = 1; | ||
313 | } | ||
314 | } else | ||
315 | badarg = 1; | ||
316 | } else if (!strcmp(*args, "-signkey")) { | ||
317 | if (args[1]) { | ||
318 | args++; | ||
319 | keyfile = *args; | ||
320 | } else | ||
321 | badarg = 1; | ||
322 | } else if (!strcmp(*args, "-reqout")) { | ||
323 | if (args[1]) { | ||
324 | args++; | ||
325 | reqout = *args; | ||
326 | } else | ||
327 | badarg = 1; | ||
328 | } else if (!strcmp(*args, "-respout")) { | ||
329 | if (args[1]) { | ||
330 | args++; | ||
331 | respout = *args; | ||
332 | } else | ||
333 | badarg = 1; | ||
334 | } else if (!strcmp(*args, "-path")) { | ||
335 | if (args[1] && use_ssl == -1) { | ||
336 | args++; | ||
337 | path = *args; | ||
338 | } else | ||
339 | badarg = 1; | ||
340 | } else if (!strcmp(*args, "-issuer")) { | ||
341 | if (args[1]) { | ||
342 | args++; | ||
343 | X509_free(issuer); | ||
344 | issuer = load_cert(bio_err, *args, FORMAT_PEM, | ||
345 | NULL, "issuer certificate"); | ||
346 | if (!issuer) | ||
347 | goto end; | ||
348 | } else | ||
349 | badarg = 1; | ||
350 | } else if (!strcmp(*args, "-cert")) { | ||
351 | if (args[1]) { | ||
352 | args++; | ||
353 | X509_free(cert); | ||
354 | cert = load_cert(bio_err, *args, FORMAT_PEM, | ||
355 | NULL, "certificate"); | ||
356 | if (!cert) | ||
357 | goto end; | ||
358 | if (!cert_id_md) | ||
359 | cert_id_md = EVP_sha1(); | ||
360 | if (!add_ocsp_cert(&req, cert, cert_id_md, issuer, ids)) | ||
361 | goto end; | ||
362 | if (!sk_OPENSSL_STRING_push(reqnames, *args)) | ||
363 | goto end; | ||
364 | } else | ||
365 | badarg = 1; | ||
366 | } else if (!strcmp(*args, "-serial")) { | ||
367 | if (args[1]) { | ||
368 | args++; | ||
369 | if (!cert_id_md) | ||
370 | cert_id_md = EVP_sha1(); | ||
371 | if (!add_ocsp_serial(&req, *args, cert_id_md, issuer, ids)) | ||
372 | goto end; | ||
373 | if (!sk_OPENSSL_STRING_push(reqnames, *args)) | ||
374 | goto end; | ||
375 | } else | ||
376 | badarg = 1; | ||
377 | } else if (!strcmp(*args, "-index")) { | ||
378 | if (args[1]) { | ||
379 | args++; | ||
380 | ridx_filename = *args; | ||
381 | } else | ||
382 | badarg = 1; | ||
383 | } else if (!strcmp(*args, "-CA")) { | ||
384 | if (args[1]) { | ||
385 | args++; | ||
386 | rca_filename = *args; | ||
387 | } else | ||
388 | badarg = 1; | ||
389 | } else if (!strcmp(*args, "-nmin")) { | ||
390 | if (args[1]) { | ||
391 | args++; | ||
392 | nmin = strtonum(*args, 0, INT_MAX, &errstr); | ||
393 | if (errstr) { | ||
394 | BIO_printf(bio_err, | ||
395 | "Illegal update period %s: %s\n", | ||
396 | *args, errstr); | ||
397 | badarg = 1; | ||
398 | } | ||
399 | } | ||
400 | if (ndays == -1) | ||
401 | ndays = 0; | ||
402 | else | ||
403 | badarg = 1; | ||
404 | } else if (!strcmp(*args, "-nrequest")) { | ||
405 | if (args[1]) { | ||
406 | args++; | ||
407 | accept_count = strtonum(*args, 0, INT_MAX, &errstr); | ||
408 | if (errstr) { | ||
409 | BIO_printf(bio_err, | ||
410 | "Illegal accept count %s: %s\n", | ||
411 | *args, errstr); | ||
412 | badarg = 1; | ||
413 | } | ||
414 | } else | ||
415 | badarg = 1; | ||
416 | } else if (!strcmp(*args, "-ndays")) { | ||
417 | if (args[1]) { | ||
418 | args++; | ||
419 | ndays = strtonum(*args, 0, INT_MAX, &errstr); | ||
420 | if (errstr) { | ||
421 | BIO_printf(bio_err, | ||
422 | "Illegal update period %s: %s\n", | ||
423 | *args, errstr); | ||
424 | badarg = 1; | ||
425 | } | ||
426 | } else | ||
427 | badarg = 1; | ||
428 | } else if (!strcmp(*args, "-rsigner")) { | ||
429 | if (args[1]) { | ||
430 | args++; | ||
431 | rsignfile = *args; | ||
432 | } else | ||
433 | badarg = 1; | ||
434 | } else if (!strcmp(*args, "-rkey")) { | ||
435 | if (args[1]) { | ||
436 | args++; | ||
437 | rkeyfile = *args; | ||
438 | } else | ||
439 | badarg = 1; | ||
440 | } else if (!strcmp(*args, "-rother")) { | ||
441 | if (args[1]) { | ||
442 | args++; | ||
443 | rcertfile = *args; | ||
444 | } else | ||
445 | badarg = 1; | ||
446 | } else if ((cert_id_md = EVP_get_digestbyname((*args) + 1)) == NULL) { | ||
447 | badarg = 1; | 779 | badarg = 1; |
448 | } | ||
449 | args++; | ||
450 | } | 780 | } |
451 | 781 | ||
452 | /* Have we anything to do? */ | 782 | /* Have we anything to do? */ |
453 | if (!req && !reqin && !respin && !(port && ridx_filename)) | 783 | if (!ocsp_config.req && !ocsp_config.reqin && !ocsp_config.respin && !(ocsp_config.port && ocsp_config.ridx_filename)) |
454 | badarg = 1; | 784 | badarg = 1; |
455 | 785 | ||
456 | if (badarg) { | 786 | if (badarg) { |
457 | BIO_printf(bio_err, "OCSP utility\n"); | 787 | ocsp_usage(); |
458 | BIO_printf(bio_err, "Usage ocsp [options]\n"); | ||
459 | BIO_printf(bio_err, "where options are\n"); | ||
460 | BIO_printf(bio_err, "-out file output filename\n"); | ||
461 | BIO_printf(bio_err, "-issuer file issuer certificate\n"); | ||
462 | BIO_printf(bio_err, "-cert file certificate to check\n"); | ||
463 | BIO_printf(bio_err, "-serial n serial number to check\n"); | ||
464 | BIO_printf(bio_err, "-signer file certificate to sign OCSP request with\n"); | ||
465 | BIO_printf(bio_err, "-signkey file private key to sign OCSP request with\n"); | ||
466 | BIO_printf(bio_err, "-sign_other file additional certificates to include in signed request\n"); | ||
467 | BIO_printf(bio_err, "-no_certs don't include any certificates in signed request\n"); | ||
468 | BIO_printf(bio_err, "-req_text print text form of request\n"); | ||
469 | BIO_printf(bio_err, "-resp_text print text form of response\n"); | ||
470 | BIO_printf(bio_err, "-text print text form of request and response\n"); | ||
471 | BIO_printf(bio_err, "-reqout file write DER encoded OCSP request to \"file\"\n"); | ||
472 | BIO_printf(bio_err, "-respout file write DER encoded OCSP reponse to \"file\"\n"); | ||
473 | BIO_printf(bio_err, "-reqin file read DER encoded OCSP request from \"file\"\n"); | ||
474 | BIO_printf(bio_err, "-respin file read DER encoded OCSP reponse from \"file\"\n"); | ||
475 | BIO_printf(bio_err, "-nonce add OCSP nonce to request\n"); | ||
476 | BIO_printf(bio_err, "-no_nonce don't add OCSP nonce to request\n"); | ||
477 | BIO_printf(bio_err, "-url URL OCSP responder URL\n"); | ||
478 | BIO_printf(bio_err, "-host host:n send OCSP request to host on port n\n"); | ||
479 | BIO_printf(bio_err, "-path path to use in OCSP request\n"); | ||
480 | BIO_printf(bio_err, "-CApath dir trusted certificates directory\n"); | ||
481 | BIO_printf(bio_err, "-CAfile file trusted certificates file\n"); | ||
482 | BIO_printf(bio_err, "-VAfile file validator certificates file\n"); | ||
483 | BIO_printf(bio_err, "-validity_period n maximum validity discrepancy in seconds\n"); | ||
484 | BIO_printf(bio_err, "-status_age n maximum status age in seconds\n"); | ||
485 | BIO_printf(bio_err, "-noverify don't verify response at all\n"); | ||
486 | BIO_printf(bio_err, "-verify_other file additional certificates to search for signer\n"); | ||
487 | BIO_printf(bio_err, "-trust_other don't verify additional certificates\n"); | ||
488 | BIO_printf(bio_err, "-no_intern don't search certificates contained in response for signer\n"); | ||
489 | BIO_printf(bio_err, "-no_signature_verify don't check signature on response\n"); | ||
490 | BIO_printf(bio_err, "-no_cert_verify don't check signing certificate\n"); | ||
491 | BIO_printf(bio_err, "-no_chain don't chain verify response\n"); | ||
492 | BIO_printf(bio_err, "-no_cert_checks don't do additional checks on signing certificate\n"); | ||
493 | BIO_printf(bio_err, "-port num port to run responder on\n"); | ||
494 | BIO_printf(bio_err, "-index file certificate status index file\n"); | ||
495 | BIO_printf(bio_err, "-CA file CA certificate\n"); | ||
496 | BIO_printf(bio_err, "-rsigner file responder certificate to sign responses with\n"); | ||
497 | BIO_printf(bio_err, "-rkey file responder key to sign responses with\n"); | ||
498 | BIO_printf(bio_err, "-rother file other certificates to include in response\n"); | ||
499 | BIO_printf(bio_err, "-resp_no_certs don't include any certificates in response\n"); | ||
500 | BIO_printf(bio_err, "-nmin n number of minutes before next update\n"); | ||
501 | BIO_printf(bio_err, "-ndays n number of days before next update\n"); | ||
502 | BIO_printf(bio_err, "-resp_key_id identify reponse by signing certificate key ID\n"); | ||
503 | BIO_printf(bio_err, "-nrequest n number of requests to accept (default unlimited)\n"); | ||
504 | BIO_printf(bio_err, "-<dgst alg> use specified digest in the request\n"); | ||
505 | goto end; | 788 | goto end; |
506 | } | 789 | } |
507 | if (outfile) | 790 | if (ocsp_config.outfile) |
508 | out = BIO_new_file(outfile, "w"); | 791 | out = BIO_new_file(ocsp_config.outfile, "w"); |
509 | else | 792 | else |
510 | out = BIO_new_fp(stdout, BIO_NOCLOSE); | 793 | out = BIO_new_fp(stdout, BIO_NOCLOSE); |
511 | 794 | ||
@@ -513,45 +796,45 @@ ocsp_main(int argc, char **argv) | |||
513 | BIO_printf(bio_err, "Error opening output file\n"); | 796 | BIO_printf(bio_err, "Error opening output file\n"); |
514 | goto end; | 797 | goto end; |
515 | } | 798 | } |
516 | if (!req && (add_nonce != 2)) | 799 | if (!ocsp_config.req && (ocsp_config.add_nonce != 2)) |
517 | add_nonce = 0; | 800 | ocsp_config.add_nonce = 0; |
518 | 801 | ||
519 | if (!req && reqin) { | 802 | if (!ocsp_config.req && ocsp_config.reqin) { |
520 | derbio = BIO_new_file(reqin, "rb"); | 803 | derbio = BIO_new_file(ocsp_config.reqin, "rb"); |
521 | if (!derbio) { | 804 | if (!derbio) { |
522 | BIO_printf(bio_err, "Error Opening OCSP request file\n"); | 805 | BIO_printf(bio_err, "Error Opening OCSP request file\n"); |
523 | goto end; | 806 | goto end; |
524 | } | 807 | } |
525 | req = d2i_OCSP_REQUEST_bio(derbio, NULL); | 808 | ocsp_config.req = d2i_OCSP_REQUEST_bio(derbio, NULL); |
526 | BIO_free(derbio); | 809 | BIO_free(derbio); |
527 | if (!req) { | 810 | if (!ocsp_config.req) { |
528 | BIO_printf(bio_err, "Error reading OCSP request\n"); | 811 | BIO_printf(bio_err, "Error reading OCSP request\n"); |
529 | goto end; | 812 | goto end; |
530 | } | 813 | } |
531 | } | 814 | } |
532 | if (!req && port) { | 815 | if (!ocsp_config.req && ocsp_config.port) { |
533 | acbio = init_responder(port); | 816 | acbio = init_responder(ocsp_config.port); |
534 | if (!acbio) | 817 | if (!acbio) |
535 | goto end; | 818 | goto end; |
536 | } | 819 | } |
537 | if (rsignfile && !rdb) { | 820 | if (ocsp_config.rsignfile && !rdb) { |
538 | if (!rkeyfile) | 821 | if (!ocsp_config.rkeyfile) |
539 | rkeyfile = rsignfile; | 822 | ocsp_config.rkeyfile = ocsp_config.rsignfile; |
540 | rsigner = load_cert(bio_err, rsignfile, FORMAT_PEM, | 823 | rsigner = load_cert(bio_err, ocsp_config.rsignfile, FORMAT_PEM, |
541 | NULL, "responder certificate"); | 824 | NULL, "responder certificate"); |
542 | if (!rsigner) { | 825 | if (!rsigner) { |
543 | BIO_printf(bio_err, "Error loading responder certificate\n"); | 826 | BIO_printf(bio_err, "Error loading responder certificate\n"); |
544 | goto end; | 827 | goto end; |
545 | } | 828 | } |
546 | rca_cert = load_cert(bio_err, rca_filename, FORMAT_PEM, | 829 | rca_cert = load_cert(bio_err, ocsp_config.rca_filename, FORMAT_PEM, |
547 | NULL, "CA certificate"); | 830 | NULL, "CA certificate"); |
548 | if (rcertfile) { | 831 | if (ocsp_config.rcertfile) { |
549 | rother = load_certs(bio_err, rcertfile, FORMAT_PEM, | 832 | rother = load_certs(bio_err, ocsp_config.rcertfile, FORMAT_PEM, |
550 | NULL, "responder other certificates"); | 833 | NULL, "responder other certificates"); |
551 | if (!rother) | 834 | if (!rother) |
552 | goto end; | 835 | goto end; |
553 | } | 836 | } |
554 | rkey = load_key(bio_err, rkeyfile, FORMAT_PEM, 0, NULL, | 837 | rkey = load_key(bio_err, ocsp_config.rkeyfile, FORMAT_PEM, 0, NULL, |
555 | "responder private key"); | 838 | "responder private key"); |
556 | if (!rkey) | 839 | if (!rkey) |
557 | goto end; | 840 | goto end; |
@@ -562,80 +845,80 @@ ocsp_main(int argc, char **argv) | |||
562 | redo_accept: | 845 | redo_accept: |
563 | 846 | ||
564 | if (acbio) { | 847 | if (acbio) { |
565 | if (!do_responder(&req, &cbio, acbio, port)) | 848 | if (!do_responder(&ocsp_config.req, &cbio, acbio, ocsp_config.port)) |
566 | goto end; | 849 | goto end; |
567 | if (!req) { | 850 | if (!ocsp_config.req) { |
568 | resp = OCSP_response_create(OCSP_RESPONSE_STATUS_MALFORMEDREQUEST, NULL); | 851 | resp = OCSP_response_create(OCSP_RESPONSE_STATUS_MALFORMEDREQUEST, NULL); |
569 | send_ocsp_response(cbio, resp); | 852 | send_ocsp_response(cbio, resp); |
570 | goto done_resp; | 853 | goto done_resp; |
571 | } | 854 | } |
572 | } | 855 | } |
573 | if (!req && (signfile || reqout || host || add_nonce || ridx_filename)) { | 856 | if (!ocsp_config.req && (ocsp_config.signfile || ocsp_config.reqout || ocsp_config.host || ocsp_config.add_nonce || ocsp_config.ridx_filename)) { |
574 | BIO_printf(bio_err, "Need an OCSP request for this operation!\n"); | 857 | BIO_printf(bio_err, "Need an OCSP request for this operation!\n"); |
575 | goto end; | 858 | goto end; |
576 | } | 859 | } |
577 | if (req && add_nonce) | 860 | if (ocsp_config.req && ocsp_config.add_nonce) |
578 | OCSP_request_add1_nonce(req, NULL, -1); | 861 | OCSP_request_add1_nonce(ocsp_config.req, NULL, -1); |
579 | 862 | ||
580 | if (signfile) { | 863 | if (ocsp_config.signfile) { |
581 | if (!keyfile) | 864 | if (!ocsp_config.keyfile) |
582 | keyfile = signfile; | 865 | ocsp_config.keyfile = ocsp_config.signfile; |
583 | signer = load_cert(bio_err, signfile, FORMAT_PEM, | 866 | signer = load_cert(bio_err, ocsp_config.signfile, FORMAT_PEM, |
584 | NULL, "signer certificate"); | 867 | NULL, "signer certificate"); |
585 | if (!signer) { | 868 | if (!signer) { |
586 | BIO_printf(bio_err, "Error loading signer certificate\n"); | 869 | BIO_printf(bio_err, "Error loading signer certificate\n"); |
587 | goto end; | 870 | goto end; |
588 | } | 871 | } |
589 | if (sign_certfile) { | 872 | if (ocsp_config.sign_certfile) { |
590 | sign_other = load_certs(bio_err, sign_certfile, FORMAT_PEM, | 873 | sign_other = load_certs(bio_err, ocsp_config.sign_certfile, FORMAT_PEM, |
591 | NULL, "signer certificates"); | 874 | NULL, "signer certificates"); |
592 | if (!sign_other) | 875 | if (!sign_other) |
593 | goto end; | 876 | goto end; |
594 | } | 877 | } |
595 | key = load_key(bio_err, keyfile, FORMAT_PEM, 0, NULL, | 878 | key = load_key(bio_err, ocsp_config.keyfile, FORMAT_PEM, 0, NULL, |
596 | "signer private key"); | 879 | "signer private key"); |
597 | if (!key) | 880 | if (!key) |
598 | goto end; | 881 | goto end; |
599 | 882 | ||
600 | if (!OCSP_request_sign(req, signer, key, NULL, sign_other, sign_flags)) { | 883 | if (!OCSP_request_sign(ocsp_config.req, signer, key, NULL, sign_other, ocsp_config.sign_flags)) { |
601 | BIO_printf(bio_err, "Error signing OCSP request\n"); | 884 | BIO_printf(bio_err, "Error signing OCSP request\n"); |
602 | goto end; | 885 | goto end; |
603 | } | 886 | } |
604 | } | 887 | } |
605 | if (req_text && req) | 888 | if (ocsp_config.req_text && ocsp_config.req) |
606 | OCSP_REQUEST_print(out, req, 0); | 889 | OCSP_REQUEST_print(out, ocsp_config.req, 0); |
607 | 890 | ||
608 | if (reqout) { | 891 | if (ocsp_config.reqout) { |
609 | derbio = BIO_new_file(reqout, "wb"); | 892 | derbio = BIO_new_file(ocsp_config.reqout, "wb"); |
610 | if (!derbio) { | 893 | if (!derbio) { |
611 | BIO_printf(bio_err, "Error opening file %s\n", reqout); | 894 | BIO_printf(bio_err, "Error opening file %s\n", ocsp_config.reqout); |
612 | goto end; | 895 | goto end; |
613 | } | 896 | } |
614 | i2d_OCSP_REQUEST_bio(derbio, req); | 897 | i2d_OCSP_REQUEST_bio(derbio, ocsp_config.req); |
615 | BIO_free(derbio); | 898 | BIO_free(derbio); |
616 | } | 899 | } |
617 | if (ridx_filename && (!rkey || !rsigner || !rca_cert)) { | 900 | if (ocsp_config.ridx_filename && (!rkey || !rsigner || !rca_cert)) { |
618 | BIO_printf(bio_err, "Need a responder certificate, key and CA for this operation!\n"); | 901 | BIO_printf(bio_err, "Need a responder certificate, key and CA for this operation!\n"); |
619 | goto end; | 902 | goto end; |
620 | } | 903 | } |
621 | if (ridx_filename && !rdb) { | 904 | if (ocsp_config.ridx_filename && !rdb) { |
622 | rdb = load_index(ridx_filename, NULL); | 905 | rdb = load_index(ocsp_config.ridx_filename, NULL); |
623 | if (!rdb) | 906 | if (!rdb) |
624 | goto end; | 907 | goto end; |
625 | if (!index_index(rdb)) | 908 | if (!index_index(rdb)) |
626 | goto end; | 909 | goto end; |
627 | } | 910 | } |
628 | if (rdb) { | 911 | if (rdb) { |
629 | i = make_ocsp_response(&resp, req, rdb, rca_cert, rsigner, rkey, rother, rflags, nmin, ndays); | 912 | i = make_ocsp_response(&resp, ocsp_config.req, rdb, rca_cert, rsigner, rkey, rother, ocsp_config.rflags, ocsp_config.nmin, ocsp_config.ndays); |
630 | if (cbio) | 913 | if (cbio) |
631 | send_ocsp_response(cbio, resp); | 914 | send_ocsp_response(cbio, resp); |
632 | } else if (host) { | 915 | } else if (ocsp_config.host) { |
633 | resp = process_responder(bio_err, req, host, path ? path : "/", | 916 | resp = process_responder(bio_err, ocsp_config.req, ocsp_config.host, ocsp_config.path ? ocsp_config.path : "/", |
634 | port, use_ssl, headers, req_timeout); | 917 | ocsp_config.port, ocsp_config.use_ssl, ocsp_config.headers, ocsp_config.req_timeout); |
635 | if (!resp) | 918 | if (!resp) |
636 | goto end; | 919 | goto end; |
637 | } else if (respin) { | 920 | } else if (ocsp_config.respin) { |
638 | derbio = BIO_new_file(respin, "rb"); | 921 | derbio = BIO_new_file(ocsp_config.respin, "rb"); |
639 | if (!derbio) { | 922 | if (!derbio) { |
640 | BIO_printf(bio_err, "Error Opening OCSP response file\n"); | 923 | BIO_printf(bio_err, "Error Opening OCSP response file\n"); |
641 | goto end; | 924 | goto end; |
@@ -653,10 +936,10 @@ redo_accept: | |||
653 | 936 | ||
654 | done_resp: | 937 | done_resp: |
655 | 938 | ||
656 | if (respout) { | 939 | if (ocsp_config.respout) { |
657 | derbio = BIO_new_file(respout, "wb"); | 940 | derbio = BIO_new_file(ocsp_config.respout, "wb"); |
658 | if (!derbio) { | 941 | if (!derbio) { |
659 | BIO_printf(bio_err, "Error opening file %s\n", respout); | 942 | BIO_printf(bio_err, "Error opening file %s\n", ocsp_config.respout); |
660 | goto end; | 943 | goto end; |
661 | } | 944 | } |
662 | i2d_OCSP_RESPONSE_bio(derbio, resp); | 945 | i2d_OCSP_RESPONSE_bio(derbio, resp); |
@@ -667,24 +950,24 @@ done_resp: | |||
667 | if (i != OCSP_RESPONSE_STATUS_SUCCESSFUL) { | 950 | if (i != OCSP_RESPONSE_STATUS_SUCCESSFUL) { |
668 | BIO_printf(bio_err, "Responder Error: %s (%d)\n", | 951 | BIO_printf(bio_err, "Responder Error: %s (%d)\n", |
669 | OCSP_response_status_str(i), i); | 952 | OCSP_response_status_str(i), i); |
670 | if (ignore_err) | 953 | if (ocsp_config.ignore_err) |
671 | goto redo_accept; | 954 | goto redo_accept; |
672 | ret = 1; | 955 | ret = 1; |
673 | goto end; | 956 | goto end; |
674 | } | 957 | } |
675 | if (resp_text) | 958 | if (ocsp_config.resp_text) |
676 | OCSP_RESPONSE_print(out, resp, 0); | 959 | OCSP_RESPONSE_print(out, resp, 0); |
677 | 960 | ||
678 | /* If running as responder don't verify our own response */ | 961 | /* If running as responder don't verify our own response */ |
679 | if (cbio) { | 962 | if (cbio) { |
680 | if (accept_count > 0) | 963 | if (ocsp_config.accept_count > 0) |
681 | accept_count--; | 964 | ocsp_config.accept_count--; |
682 | /* Redo if more connections needed */ | 965 | /* Redo if more connections needed */ |
683 | if (accept_count) { | 966 | if (ocsp_config.accept_count) { |
684 | BIO_free_all(cbio); | 967 | BIO_free_all(cbio); |
685 | cbio = NULL; | 968 | cbio = NULL; |
686 | OCSP_REQUEST_free(req); | 969 | OCSP_REQUEST_free(ocsp_config.req); |
687 | req = NULL; | 970 | ocsp_config.req = NULL; |
688 | OCSP_RESPONSE_free(resp); | 971 | OCSP_RESPONSE_free(resp); |
689 | resp = NULL; | 972 | resp = NULL; |
690 | goto redo_accept; | 973 | goto redo_accept; |
@@ -692,11 +975,11 @@ done_resp: | |||
692 | goto end; | 975 | goto end; |
693 | } | 976 | } |
694 | if (!store) | 977 | if (!store) |
695 | store = setup_verify(bio_err, CAfile, CApath); | 978 | store = setup_verify(bio_err, ocsp_config.CAfile, ocsp_config.CApath); |
696 | if (!store) | 979 | if (!store) |
697 | goto end; | 980 | goto end; |
698 | if (verify_certfile) { | 981 | if (ocsp_config.verify_certfile) { |
699 | verify_other = load_certs(bio_err, verify_certfile, FORMAT_PEM, | 982 | verify_other = load_certs(bio_err, ocsp_config.verify_certfile, FORMAT_PEM, |
700 | NULL, "validator certificate"); | 983 | NULL, "validator certificate"); |
701 | if (!verify_other) | 984 | if (!verify_other) |
702 | goto end; | 985 | goto end; |
@@ -707,8 +990,8 @@ done_resp: | |||
707 | BIO_printf(bio_err, "Error parsing response\n"); | 990 | BIO_printf(bio_err, "Error parsing response\n"); |
708 | goto end; | 991 | goto end; |
709 | } | 992 | } |
710 | if (!noverify) { | 993 | if (!ocsp_config.noverify) { |
711 | if (req && ((i = OCSP_check_nonce(req, bs)) <= 0)) { | 994 | if (ocsp_config.req && ((i = OCSP_check_nonce(ocsp_config.req, bs)) <= 0)) { |
712 | if (i == -1) | 995 | if (i == -1) |
713 | BIO_printf(bio_err, "WARNING: no nonce in response\n"); | 996 | BIO_printf(bio_err, "WARNING: no nonce in response\n"); |
714 | else { | 997 | else { |
@@ -716,7 +999,7 @@ done_resp: | |||
716 | goto end; | 999 | goto end; |
717 | } | 1000 | } |
718 | } | 1001 | } |
719 | i = OCSP_basic_verify(bs, verify_other, store, verify_flags); | 1002 | i = OCSP_basic_verify(bs, verify_other, store, ocsp_config.verify_flags); |
720 | if (i < 0) | 1003 | if (i < 0) |
721 | i = OCSP_basic_verify(bs, NULL, store, 0); | 1004 | i = OCSP_basic_verify(bs, NULL, store, 0); |
722 | 1005 | ||
@@ -727,7 +1010,7 @@ done_resp: | |||
727 | BIO_printf(bio_err, "Response verify OK\n"); | 1010 | BIO_printf(bio_err, "Response verify OK\n"); |
728 | 1011 | ||
729 | } | 1012 | } |
730 | if (!print_ocsp_summary(out, bs, req, reqnames, ids, nsec, maxage)) | 1013 | if (!print_ocsp_summary(out, bs, ocsp_config.req, ocsp_config.reqnames, ocsp_config.ids, ocsp_config.nsec, ocsp_config.maxage)) |
731 | goto end; | 1014 | goto end; |
732 | 1015 | ||
733 | ret = 0; | 1016 | ret = 0; |
@@ -738,27 +1021,27 @@ done_resp: | |||
738 | X509_STORE_free(store); | 1021 | X509_STORE_free(store); |
739 | EVP_PKEY_free(key); | 1022 | EVP_PKEY_free(key); |
740 | EVP_PKEY_free(rkey); | 1023 | EVP_PKEY_free(rkey); |
741 | X509_free(issuer); | 1024 | X509_free(ocsp_config.issuer); |
742 | X509_free(cert); | 1025 | X509_free(ocsp_config.cert); |
743 | X509_free(rsigner); | 1026 | X509_free(rsigner); |
744 | X509_free(rca_cert); | 1027 | X509_free(rca_cert); |
745 | free_index(rdb); | 1028 | free_index(rdb); |
746 | BIO_free_all(cbio); | 1029 | BIO_free_all(cbio); |
747 | BIO_free_all(acbio); | 1030 | BIO_free_all(acbio); |
748 | BIO_free(out); | 1031 | BIO_free(out); |
749 | OCSP_REQUEST_free(req); | 1032 | OCSP_REQUEST_free(ocsp_config.req); |
750 | OCSP_RESPONSE_free(resp); | 1033 | OCSP_RESPONSE_free(resp); |
751 | OCSP_BASICRESP_free(bs); | 1034 | OCSP_BASICRESP_free(bs); |
752 | sk_OPENSSL_STRING_free(reqnames); | 1035 | sk_OPENSSL_STRING_free(ocsp_config.reqnames); |
753 | sk_OCSP_CERTID_free(ids); | 1036 | sk_OCSP_CERTID_free(ocsp_config.ids); |
754 | sk_X509_pop_free(sign_other, X509_free); | 1037 | sk_X509_pop_free(sign_other, X509_free); |
755 | sk_X509_pop_free(verify_other, X509_free); | 1038 | sk_X509_pop_free(verify_other, X509_free); |
756 | sk_CONF_VALUE_pop_free(headers, X509V3_conf_free); | 1039 | sk_CONF_VALUE_pop_free(ocsp_config.headers, X509V3_conf_free); |
757 | 1040 | ||
758 | if (use_ssl != -1) { | 1041 | if (ocsp_config.use_ssl != -1) { |
759 | free(host); | 1042 | free(ocsp_config.host); |
760 | free(port); | 1043 | free(ocsp_config.port); |
761 | free(path); | 1044 | free(ocsp_config.path); |
762 | } | 1045 | } |
763 | return (ret); | 1046 | return (ret); |
764 | } | 1047 | } |
@@ -1213,5 +1496,4 @@ process_responder(BIO * err, OCSP_REQUEST * req, | |||
1213 | SSL_CTX_free(ctx); | 1496 | SSL_CTX_free(ctx); |
1214 | return resp; | 1497 | return resp; |
1215 | } | 1498 | } |
1216 | |||
1217 | #endif | 1499 | #endif |