GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: usr.bin/openssl/ocsp.c Lines: 436 713 61.2 %
Date: 2017-11-13 Branches: 235 498 47.2 %

Line Branch Exec Source
1
/* $OpenBSD: ocsp.c,v 1.12 2017/01/21 09:29:09 deraadt Exp $ */
2
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3
 * project 2000.
4
 */
5
/* ====================================================================
6
 * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
7
 *
8
 * Redistribution and use in source and binary forms, with or without
9
 * modification, are permitted provided that the following conditions
10
 * are met:
11
 *
12
 * 1. Redistributions of source code must retain the above copyright
13
 *    notice, this list of conditions and the following disclaimer.
14
 *
15
 * 2. Redistributions in binary form must reproduce the above copyright
16
 *    notice, this list of conditions and the following disclaimer in
17
 *    the documentation and/or other materials provided with the
18
 *    distribution.
19
 *
20
 * 3. All advertising materials mentioning features or use of this
21
 *    software must display the following acknowledgment:
22
 *    "This product includes software developed by the OpenSSL Project
23
 *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24
 *
25
 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26
 *    endorse or promote products derived from this software without
27
 *    prior written permission. For written permission, please contact
28
 *    licensing@OpenSSL.org.
29
 *
30
 * 5. Products derived from this software may not be called "OpenSSL"
31
 *    nor may "OpenSSL" appear in their names without prior written
32
 *    permission of the OpenSSL Project.
33
 *
34
 * 6. Redistributions of any form whatsoever must retain the following
35
 *    acknowledgment:
36
 *    "This product includes software developed by the OpenSSL Project
37
 *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38
 *
39
 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
43
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50
 * OF THE POSSIBILITY OF SUCH DAMAGE.
51
 * ====================================================================
52
 *
53
 * This product includes cryptographic software written by Eric Young
54
 * (eay@cryptsoft.com).  This product includes software written by Tim
55
 * Hudson (tjh@cryptsoft.com).
56
 *
57
 */
58
#ifndef OPENSSL_NO_OCSP
59
60
#include <sys/types.h>
61
62
#include <stdio.h>
63
#include <stdlib.h>
64
#include <limits.h>
65
#include <string.h>
66
#include <poll.h>
67
#include <time.h>
68
69
/* Needs to be included before the openssl headers! */
70
#include "apps.h"
71
72
#include <openssl/bn.h>
73
#include <openssl/crypto.h>
74
#include <openssl/err.h>
75
#include <openssl/evp.h>
76
#include <openssl/ssl.h>
77
#include <openssl/x509v3.h>
78
79
/* Maximum leeway in validity period: default 5 minutes */
80
#define MAX_VALIDITY_PERIOD	(5 * 60)
81
82
static int
83
add_ocsp_cert(OCSP_REQUEST ** req, X509 * cert, const EVP_MD * cert_id_md, X509 * issuer,
84
    STACK_OF(OCSP_CERTID) * ids);
85
static int add_ocsp_serial(OCSP_REQUEST ** req, char *serial, const EVP_MD * cert_id_md, X509 * issuer,
86
    STACK_OF(OCSP_CERTID) * ids);
87
static int print_ocsp_summary(BIO * out, OCSP_BASICRESP * bs, OCSP_REQUEST * req,
88
    STACK_OF(OPENSSL_STRING) * names,
89
    STACK_OF(OCSP_CERTID) * ids, long nsec,
90
    long maxage);
91
92
static int make_ocsp_response(OCSP_RESPONSE ** resp, OCSP_REQUEST * req, CA_DB * db,
93
    X509 * ca, X509 * rcert, EVP_PKEY * rkey,
94
    STACK_OF(X509) * rother, unsigned long flags,
95
    int nmin, int ndays);
96
97
static char **lookup_serial(CA_DB * db, ASN1_INTEGER * ser);
98
static BIO *init_responder(char *port);
99
static int do_responder(OCSP_REQUEST ** preq, BIO ** pcbio, BIO * acbio, char *port);
100
static int send_ocsp_response(BIO * cbio, OCSP_RESPONSE * resp);
101
static OCSP_RESPONSE *query_responder(BIO * err, BIO * cbio, char *path,
102
    STACK_OF(CONF_VALUE) * headers,
103
    OCSP_REQUEST * req, int req_timeout);
104
105
int
106
ocsp_main(int argc, char **argv)
107
{
108
	char **args;
109
40
	char *host = NULL, *port = NULL, *path = "/";
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
20
	int add_nonce = 1, noverify = 0, use_ssl = -1;
116
20
	STACK_OF(CONF_VALUE) * headers = NULL;
117
20
	OCSP_REQUEST *req = NULL;
118
20
	OCSP_RESPONSE *resp = NULL;
119
	OCSP_BASICRESP *bs = NULL;
120
	X509 *issuer = NULL, *cert = NULL;
121
	X509 *signer = NULL, *rsigner = NULL;
122
	EVP_PKEY *key = NULL, *rkey = NULL;
123
20
	BIO *acbio = NULL, *cbio = NULL;
124
	BIO *derbio = NULL;
125
	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;
131
	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;
135
	int accept_count = -1;
136
	int badarg = 0;
137
	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;
142
	char *ridx_filename = NULL;
143
	char *rca_filename = NULL;
144
	CA_DB *rdb = NULL;
145
	int nmin = 0, ndays = -1;
146
	const EVP_MD *cert_id_md = NULL;
147
20
	const char *errstr = NULL;
148
149
20
	if (single_execution) {
150
20
		if (pledge("stdio cpath wpath rpath inet dns tty flock", NULL) == -1) {
151
			perror("pledge");
152
			exit(1);
153
		}
154
	}
155
156
20
	args = argv + 1;
157
20
	reqnames = sk_OPENSSL_STRING_new_null();
158
20
	ids = sk_OCSP_CERTID_new_null();
159

504
	while (!badarg && *args && *args[0] == '-') {
160
112
		if (!strcmp(*args, "-out")) {
161
			if (args[1]) {
162
				args++;
163
				outfile = *args;
164
			} else
165
				badarg = 1;
166
112
		} else if (!strcmp(*args, "-timeout")) {
167
			if (args[1]) {
168
				args++;
169
				req_timeout = strtonum(*args, 0,
170
				    INT_MAX, &errstr);
171
				if (errstr) {
172
					BIO_printf(bio_err,
173
					    "Illegal timeout value %s: %s\n",
174
					    *args, errstr);
175
					badarg = 1;
176
				}
177
			} else
178
				badarg = 1;
179
112
		} else if (!strcmp(*args, "-url")) {
180
4
			if (args[1]) {
181
4
				args++;
182
4
				if (!OCSP_parse_url(*args, &host, &port, &path, &use_ssl)) {
183
					BIO_printf(bio_err, "Error parsing URL\n");
184
					badarg = 1;
185
				}
186
			} else
187
				badarg = 1;
188
108
		} else if (!strcmp(*args, "-host")) {
189
			if (args[1]) {
190
				args++;
191
				host = *args;
192
			} else
193
				badarg = 1;
194
108
		} else if (!strcmp(*args, "-port")) {
195
4
			if (args[1]) {
196
4
				args++;
197
4
				port = *args;
198
4
			} else
199
				badarg = 1;
200
104
		} else if (!strcmp(*args, "-header")) {
201
			if (args[1] && args[2]) {
202
				if (!X509V3_add_value(args[1], args[2], &headers))
203
					goto end;
204
				args += 2;
205
			} else
206
				badarg = 1;
207
104
		} else if (!strcmp(*args, "-ignore_err"))
208
			ignore_err = 1;
209
104
		else if (!strcmp(*args, "-noverify"))
210
			noverify = 1;
211
104
		else if (!strcmp(*args, "-nonce"))
212
			add_nonce = 2;
213
104
		else if (!strcmp(*args, "-no_nonce"))
214
			add_nonce = 0;
215
104
		else if (!strcmp(*args, "-resp_no_certs"))
216
			rflags |= OCSP_NOCERTS;
217
104
		else if (!strcmp(*args, "-resp_key_id"))
218
			rflags |= OCSP_RESPID_KEY;
219
104
		else if (!strcmp(*args, "-no_certs"))
220
			sign_flags |= OCSP_NOCERTS;
221
104
		else if (!strcmp(*args, "-no_signature_verify"))
222
			verify_flags |= OCSP_NOSIGS;
223
104
		else if (!strcmp(*args, "-no_cert_verify"))
224
			verify_flags |= OCSP_NOVERIFY;
225
104
		else if (!strcmp(*args, "-no_chain"))
226
			verify_flags |= OCSP_NOCHAIN;
227
104
		else if (!strcmp(*args, "-no_cert_checks"))
228
			verify_flags |= OCSP_NOCHECKS;
229
104
		else if (!strcmp(*args, "-no_explicit"))
230
			verify_flags |= OCSP_NOEXPLICIT;
231
104
		else if (!strcmp(*args, "-trust_other"))
232
			verify_flags |= OCSP_TRUSTOTHER;
233
104
		else if (!strcmp(*args, "-no_intern"))
234
			verify_flags |= OCSP_NOINTERN;
235
104
		else if (!strcmp(*args, "-text")) {
236
			req_text = 1;
237
			resp_text = 1;
238
104
		} else if (!strcmp(*args, "-req_text"))
239
			req_text = 1;
240
100
		else if (!strcmp(*args, "-resp_text"))
241
4
			resp_text = 1;
242
96
		else if (!strcmp(*args, "-reqin")) {
243
4
			if (args[1]) {
244
4
				args++;
245
4
				reqin = *args;
246
4
			} else
247
				badarg = 1;
248
92
		} else if (!strcmp(*args, "-respin")) {
249
			if (args[1]) {
250
				args++;
251
				respin = *args;
252
			} else
253
				badarg = 1;
254
92
		} else if (!strcmp(*args, "-signer")) {
255
			if (args[1]) {
256
				args++;
257
				signfile = *args;
258
			} else
259
				badarg = 1;
260
92
		} else if (!strcmp(*args, "-VAfile")) {
261
			if (args[1]) {
262
				args++;
263
				verify_certfile = *args;
264
				verify_flags |= OCSP_TRUSTOTHER;
265
			} else
266
				badarg = 1;
267
92
		} else if (!strcmp(*args, "-sign_other")) {
268
			if (args[1]) {
269
				args++;
270
				sign_certfile = *args;
271
			} else
272
				badarg = 1;
273
92
		} else if (!strcmp(*args, "-verify_other")) {
274
			if (args[1]) {
275
				args++;
276
				verify_certfile = *args;
277
			} else
278
				badarg = 1;
279
92
		} else if (!strcmp(*args, "-CAfile")) {
280
16
			if (args[1]) {
281
16
				args++;
282
16
				CAfile = *args;
283
16
			} else
284
				badarg = 1;
285
76
		} else if (!strcmp(*args, "-CApath")) {
286
			if (args[1]) {
287
				args++;
288
				CApath = *args;
289
			} else
290
				badarg = 1;
291
76
		} else if (!strcmp(*args, "-validity_period")) {
292
			if (args[1]) {
293
				args++;
294
				nsec = strtonum(*args, 0, LONG_MAX, &errstr);
295
				if (errstr) {
296
					BIO_printf(bio_err,
297
					    "Illegal validity period %s: %s\n",
298
					    *args, errstr);
299
					badarg = 1;
300
				}
301
			} else
302
				badarg = 1;
303
76
		} else if (!strcmp(*args, "-status_age")) {
304
			if (args[1]) {
305
				args++;
306
				maxage = strtonum(*args, 0, LONG_MAX, &errstr);
307
				if (errstr) {
308
					BIO_printf(bio_err,
309
					    "Illegal validity age %s: %s\n",
310
					    *args, errstr);
311
					badarg = 1;
312
				}
313
			} else
314
				badarg = 1;
315
76
		} else if (!strcmp(*args, "-signkey")) {
316
			if (args[1]) {
317
				args++;
318
				keyfile = *args;
319
			} else
320
				badarg = 1;
321
76
		} else if (!strcmp(*args, "-reqout")) {
322
4
			if (args[1]) {
323
4
				args++;
324
4
				reqout = *args;
325
4
			} else
326
				badarg = 1;
327
72
		} else if (!strcmp(*args, "-respout")) {
328
8
			if (args[1]) {
329
8
				args++;
330
8
				respout = *args;
331
8
			} else
332
				badarg = 1;
333
64
		} else if (!strcmp(*args, "-path")) {
334
			if (args[1]) {
335
				args++;
336
				path = *args;
337
			} else
338
				badarg = 1;
339
64
		} else if (!strcmp(*args, "-issuer")) {
340
8
			if (args[1]) {
341
8
				args++;
342
8
				X509_free(issuer);
343
8
				issuer = load_cert(bio_err, *args, FORMAT_PEM,
344
				    NULL, "issuer certificate");
345
8
				if (!issuer)
346
					goto end;
347
			} else
348
				badarg = 1;
349
56
		} else if (!strcmp(*args, "-cert")) {
350
16
			if (args[1]) {
351
16
				args++;
352
16
				X509_free(cert);
353
16
				cert = load_cert(bio_err, *args, FORMAT_PEM,
354
				    NULL, "certificate");
355
16
				if (!cert)
356
					goto end;
357
16
				if (!cert_id_md)
358
8
					cert_id_md = EVP_sha1();
359
16
				if (!add_ocsp_cert(&req, cert, cert_id_md, issuer, ids))
360
					goto end;
361
16
				if (!sk_OPENSSL_STRING_push(reqnames, *args))
362
					goto end;
363
			} else
364
				badarg = 1;
365
40
		} else if (!strcmp(*args, "-serial")) {
366
			if (args[1]) {
367
				args++;
368
				if (!cert_id_md)
369
					cert_id_md = EVP_sha1();
370
				if (!add_ocsp_serial(&req, *args, cert_id_md, issuer, ids))
371
					goto end;
372
				if (!sk_OPENSSL_STRING_push(reqnames, *args))
373
					goto end;
374
			} else
375
				badarg = 1;
376
40
		} else if (!strcmp(*args, "-index")) {
377
8
			if (args[1]) {
378
8
				args++;
379
8
				ridx_filename = *args;
380
8
			} else
381
				badarg = 1;
382
32
		} else if (!strcmp(*args, "-CA")) {
383
8
			if (args[1]) {
384
8
				args++;
385
8
				rca_filename = *args;
386
8
			} else
387
				badarg = 1;
388
24
		} else if (!strcmp(*args, "-nmin")) {
389
			if (args[1]) {
390
				args++;
391
				nmin = strtonum(*args, 0, INT_MAX, &errstr);
392
				if (errstr) {
393
					BIO_printf(bio_err,
394
					    "Illegal update period %s: %s\n",
395
					    *args, errstr);
396
					badarg = 1;
397
				}
398
			}
399
			if (ndays == -1)
400
				ndays = 0;
401
			else
402
				badarg = 1;
403
24
		} else if (!strcmp(*args, "-nrequest")) {
404
4
			if (args[1]) {
405
4
				args++;
406
4
				accept_count = strtonum(*args, 0, INT_MAX, &errstr);
407
4
				if (errstr) {
408
					BIO_printf(bio_err,
409
					    "Illegal accept count %s: %s\n",
410
					    *args, errstr);
411
					badarg = 1;
412
				}
413
			} else
414
				badarg = 1;
415
20
		} else if (!strcmp(*args, "-ndays")) {
416
			if (args[1]) {
417
				args++;
418
				ndays = strtonum(*args, 0, INT_MAX, &errstr);
419
				if (errstr) {
420
					BIO_printf(bio_err,
421
					    "Illegal update period %s: %s\n",
422
					    *args, errstr);
423
					badarg = 1;
424
				}
425
			} else
426
				badarg = 1;
427
20
		} else if (!strcmp(*args, "-rsigner")) {
428
8
			if (args[1]) {
429
8
				args++;
430
8
				rsignfile = *args;
431
8
			} else
432
				badarg = 1;
433
12
		} else if (!strcmp(*args, "-rkey")) {
434
8
			if (args[1]) {
435
8
				args++;
436
8
				rkeyfile = *args;
437
8
			} else
438
				badarg = 1;
439
4
		} else if (!strcmp(*args, "-rother")) {
440
			if (args[1]) {
441
				args++;
442
				rcertfile = *args;
443
			} else
444
				badarg = 1;
445
4
		} else if ((cert_id_md = EVP_get_digestbyname((*args) + 1)) == NULL) {
446
			badarg = 1;
447
4
		}
448
112
		args++;
449
	}
450
451
	/* Have we anything to do? */
452

28
	if (!req && !reqin && !respin && !(port && ridx_filename))
453
4
		badarg = 1;
454
455
20
	if (badarg) {
456
4
		BIO_printf(bio_err, "OCSP utility\n");
457
4
		BIO_printf(bio_err, "Usage ocsp [options]\n");
458
4
		BIO_printf(bio_err, "where options are\n");
459
4
		BIO_printf(bio_err, "-out file          output filename\n");
460
4
		BIO_printf(bio_err, "-issuer file       issuer certificate\n");
461
4
		BIO_printf(bio_err, "-cert file         certificate to check\n");
462
4
		BIO_printf(bio_err, "-serial n          serial number to check\n");
463
4
		BIO_printf(bio_err, "-signer file       certificate to sign OCSP request with\n");
464
4
		BIO_printf(bio_err, "-signkey file      private key to sign OCSP request with\n");
465
4
		BIO_printf(bio_err, "-sign_other file   additional certificates to include in signed request\n");
466
4
		BIO_printf(bio_err, "-no_certs          don't include any certificates in signed request\n");
467
4
		BIO_printf(bio_err, "-req_text          print text form of request\n");
468
4
		BIO_printf(bio_err, "-resp_text         print text form of response\n");
469
4
		BIO_printf(bio_err, "-text              print text form of request and response\n");
470
4
		BIO_printf(bio_err, "-reqout file       write DER encoded OCSP request to \"file\"\n");
471
4
		BIO_printf(bio_err, "-respout file      write DER encoded OCSP reponse to \"file\"\n");
472
4
		BIO_printf(bio_err, "-reqin file        read DER encoded OCSP request from \"file\"\n");
473
4
		BIO_printf(bio_err, "-respin file       read DER encoded OCSP reponse from \"file\"\n");
474
4
		BIO_printf(bio_err, "-nonce             add OCSP nonce to request\n");
475
4
		BIO_printf(bio_err, "-no_nonce          don't add OCSP nonce to request\n");
476
4
		BIO_printf(bio_err, "-url URL           OCSP responder URL\n");
477
4
		BIO_printf(bio_err, "-host host:n       send OCSP request to host on port n\n");
478
4
		BIO_printf(bio_err, "-path              path to use in OCSP request\n");
479
4
		BIO_printf(bio_err, "-CApath dir        trusted certificates directory\n");
480
4
		BIO_printf(bio_err, "-CAfile file       trusted certificates file\n");
481
4
		BIO_printf(bio_err, "-VAfile file       validator certificates file\n");
482
4
		BIO_printf(bio_err, "-validity_period n maximum validity discrepancy in seconds\n");
483
4
		BIO_printf(bio_err, "-status_age n      maximum status age in seconds\n");
484
4
		BIO_printf(bio_err, "-noverify          don't verify response at all\n");
485
4
		BIO_printf(bio_err, "-verify_other file additional certificates to search for signer\n");
486
4
		BIO_printf(bio_err, "-trust_other       don't verify additional certificates\n");
487
4
		BIO_printf(bio_err, "-no_intern         don't search certificates contained in response for signer\n");
488
4
		BIO_printf(bio_err, "-no_signature_verify don't check signature on response\n");
489
4
		BIO_printf(bio_err, "-no_cert_verify    don't check signing certificate\n");
490
4
		BIO_printf(bio_err, "-no_chain          don't chain verify response\n");
491
4
		BIO_printf(bio_err, "-no_cert_checks    don't do additional checks on signing certificate\n");
492
4
		BIO_printf(bio_err, "-port num		 port to run responder on\n");
493
4
		BIO_printf(bio_err, "-index file	 certificate status index file\n");
494
4
		BIO_printf(bio_err, "-CA file		 CA certificate\n");
495
4
		BIO_printf(bio_err, "-rsigner file	 responder certificate to sign responses with\n");
496
4
		BIO_printf(bio_err, "-rkey file	 responder key to sign responses with\n");
497
4
		BIO_printf(bio_err, "-rother file	 other certificates to include in response\n");
498
4
		BIO_printf(bio_err, "-resp_no_certs     don't include any certificates in response\n");
499
4
		BIO_printf(bio_err, "-nmin n		 number of minutes before next update\n");
500
4
		BIO_printf(bio_err, "-ndays n		 number of days before next update\n");
501
4
		BIO_printf(bio_err, "-resp_key_id       identify reponse by signing certificate key ID\n");
502
4
		BIO_printf(bio_err, "-nrequest n        number of requests to accept (default unlimited)\n");
503
4
		BIO_printf(bio_err, "-<dgst alg>     use specified digest in the request\n");
504
4
		goto end;
505
	}
506
16
	if (outfile)
507
		out = BIO_new_file(outfile, "w");
508
	else
509
16
		out = BIO_new_fp(stdout, BIO_NOCLOSE);
510
511
16
	if (!out) {
512
		BIO_printf(bio_err, "Error opening output file\n");
513
		goto end;
514
	}
515
16
	if (!req && (add_nonce != 2))
516
8
		add_nonce = 0;
517
518
16
	if (!req && reqin) {
519
4
		derbio = BIO_new_file(reqin, "rb");
520
4
		if (!derbio) {
521
			BIO_printf(bio_err, "Error Opening OCSP request file\n");
522
			goto end;
523
		}
524
4
		req = d2i_OCSP_REQUEST_bio(derbio, NULL);
525
4
		BIO_free(derbio);
526
4
		if (!req) {
527
			BIO_printf(bio_err, "Error reading OCSP request\n");
528
			goto end;
529
		}
530
	}
531
16
	if (!req && port) {
532
4
		acbio = init_responder(port);
533
4
		if (!acbio)
534
			goto end;
535
	}
536
16
	if (rsignfile && !rdb) {
537
8
		if (!rkeyfile)
538
			rkeyfile = rsignfile;
539
8
		rsigner = load_cert(bio_err, rsignfile, FORMAT_PEM,
540
		    NULL, "responder certificate");
541
8
		if (!rsigner) {
542
			BIO_printf(bio_err, "Error loading responder certificate\n");
543
			goto end;
544
		}
545
8
		rca_cert = load_cert(bio_err, rca_filename, FORMAT_PEM,
546
		    NULL, "CA certificate");
547
8
		if (rcertfile) {
548
			rother = load_certs(bio_err, rcertfile, FORMAT_PEM,
549
			    NULL, "responder other certificates");
550
			if (!rother)
551
				goto end;
552
		}
553
8
		rkey = load_key(bio_err, rkeyfile, FORMAT_PEM, 0, NULL,
554
		    "responder private key");
555
8
		if (!rkey)
556
			goto end;
557
	}
558
32
	if (acbio)
559
4
		BIO_printf(bio_err, "Waiting for OCSP client connections...\n");
560
561
redo_accept:
562
563
16
	if (acbio) {
564
4
		if (!do_responder(&req, &cbio, acbio, port))
565
			goto end;
566
4
		if (!req) {
567
			resp = OCSP_response_create(OCSP_RESPONSE_STATUS_MALFORMEDREQUEST, NULL);
568
			send_ocsp_response(cbio, resp);
569
			goto done_resp;
570
		}
571
	}
572

16
	if (!req && (signfile || reqout || host || add_nonce || ridx_filename)) {
573
		BIO_printf(bio_err, "Need an OCSP request for this operation!\n");
574
		goto end;
575
	}
576
16
	if (req && add_nonce)
577
8
		OCSP_request_add1_nonce(req, NULL, -1);
578
579
16
	if (signfile) {
580
		if (!keyfile)
581
			keyfile = signfile;
582
		signer = load_cert(bio_err, signfile, FORMAT_PEM,
583
		    NULL, "signer certificate");
584
		if (!signer) {
585
			BIO_printf(bio_err, "Error loading signer certificate\n");
586
			goto end;
587
		}
588
		if (sign_certfile) {
589
			sign_other = load_certs(bio_err, sign_certfile, FORMAT_PEM,
590
			    NULL, "signer certificates");
591
			if (!sign_other)
592
				goto end;
593
		}
594
		key = load_key(bio_err, keyfile, FORMAT_PEM, 0, NULL,
595
		    "signer private key");
596
		if (!key)
597
			goto end;
598
599
		if (!OCSP_request_sign(req, signer, key, NULL, sign_other, sign_flags)) {
600
			BIO_printf(bio_err, "Error signing OCSP request\n");
601
			goto end;
602
		}
603
	}
604
16
	if (req_text && req)
605
4
		OCSP_REQUEST_print(out, req, 0);
606
607
16
	if (reqout) {
608
4
		derbio = BIO_new_file(reqout, "wb");
609
4
		if (!derbio) {
610
			BIO_printf(bio_err, "Error opening file %s\n", reqout);
611
			goto end;
612
		}
613
4
		i2d_OCSP_REQUEST_bio(derbio, req);
614
4
		BIO_free(derbio);
615
4
	}
616

24
	if (ridx_filename && (!rkey || !rsigner || !rca_cert)) {
617
		BIO_printf(bio_err, "Need a responder certificate, key and CA for this operation!\n");
618
		goto end;
619
	}
620
16
	if (ridx_filename && !rdb) {
621
8
		rdb = load_index(ridx_filename, NULL);
622
8
		if (!rdb)
623
			goto end;
624
8
		if (!index_index(rdb))
625
			goto end;
626
	}
627
16
	if (rdb) {
628
8
		i = make_ocsp_response(&resp, req, rdb, rca_cert, rsigner, rkey, rother, rflags, nmin, ndays);
629
8
		if (cbio)
630
4
			send_ocsp_response(cbio, resp);
631
8
	} else if (host) {
632
8
		resp = process_responder(bio_err, req, host, path,
633
4
		    port, use_ssl, headers, req_timeout);
634
4
		if (!resp)
635
			goto end;
636
4
	} else if (respin) {
637
		derbio = BIO_new_file(respin, "rb");
638
		if (!derbio) {
639
			BIO_printf(bio_err, "Error Opening OCSP response file\n");
640
			goto end;
641
		}
642
		resp = d2i_OCSP_RESPONSE_bio(derbio, NULL);
643
		BIO_free(derbio);
644
		if (!resp) {
645
			BIO_printf(bio_err, "Error reading OCSP response\n");
646
			goto end;
647
		}
648
	} else {
649
		ret = 0;
650
4
		goto end;
651
	}
652
653
done_resp:
654
655
12
	if (respout) {
656
8
		derbio = BIO_new_file(respout, "wb");
657
8
		if (!derbio) {
658
			BIO_printf(bio_err, "Error opening file %s\n", respout);
659
			goto end;
660
		}
661
8
		i2d_OCSP_RESPONSE_bio(derbio, resp);
662
8
		BIO_free(derbio);
663
8
	}
664
12
	i = OCSP_response_status(resp);
665
666
12
	if (i != OCSP_RESPONSE_STATUS_SUCCESSFUL) {
667
		BIO_printf(bio_err, "Responder Error: %s (%d)\n",
668
		    OCSP_response_status_str(i), i);
669
		if (ignore_err)
670
			goto redo_accept;
671
		ret = 1;
672
		goto end;
673
	}
674
12
	if (resp_text)
675
8
		OCSP_RESPONSE_print(out, resp, 0);
676
677
	/* If running as responder don't verify our own response */
678
12
	if (cbio) {
679
4
		if (accept_count > 0)
680
4
			accept_count--;
681
		/* Redo if more connections needed */
682
4
		if (accept_count) {
683
			BIO_free_all(cbio);
684
			cbio = NULL;
685
			OCSP_REQUEST_free(req);
686
			req = NULL;
687
			OCSP_RESPONSE_free(resp);
688
			resp = NULL;
689
			goto redo_accept;
690
		}
691
		goto end;
692
	}
693
8
	if (!store)
694
8
		store = setup_verify(bio_err, CAfile, CApath);
695
8
	if (!store)
696
		goto end;
697
8
	if (verify_certfile) {
698
		verify_other = load_certs(bio_err, verify_certfile, FORMAT_PEM,
699
		    NULL, "validator certificate");
700
		if (!verify_other)
701
			goto end;
702
	}
703
8
	bs = OCSP_response_get1_basic(resp);
704
705
8
	if (!bs) {
706
		BIO_printf(bio_err, "Error parsing response\n");
707
		goto end;
708
	}
709
8
	if (!noverify) {
710

16
		if (req && ((i = OCSP_check_nonce(req, bs)) <= 0)) {
711
			if (i == -1)
712
				BIO_printf(bio_err, "WARNING: no nonce in response\n");
713
			else {
714
				BIO_printf(bio_err, "Nonce Verify error\n");
715
				goto end;
716
			}
717
		}
718
8
		i = OCSP_basic_verify(bs, verify_other, store, verify_flags);
719
8
		if (i < 0)
720
			i = OCSP_basic_verify(bs, NULL, store, 0);
721
722
8
		if (i <= 0) {
723
			BIO_printf(bio_err, "Response Verify Failure\n");
724
			ERR_print_errors(bio_err);
725
		} else
726
8
			BIO_printf(bio_err, "Response verify OK\n");
727
728
	}
729
8
	if (!print_ocsp_summary(out, bs, req, reqnames, ids, nsec, maxage))
730
		goto end;
731
732
8
	ret = 0;
733
734
end:
735
20
	ERR_print_errors(bio_err);
736
20
	X509_free(signer);
737
20
	X509_STORE_free(store);
738
20
	EVP_PKEY_free(key);
739
20
	EVP_PKEY_free(rkey);
740
20
	X509_free(issuer);
741
20
	X509_free(cert);
742
20
	X509_free(rsigner);
743
20
	X509_free(rca_cert);
744
20
	free_index(rdb);
745
20
	BIO_free_all(cbio);
746
20
	BIO_free_all(acbio);
747
20
	BIO_free(out);
748
20
	OCSP_REQUEST_free(req);
749
20
	OCSP_RESPONSE_free(resp);
750
20
	OCSP_BASICRESP_free(bs);
751
20
	sk_OPENSSL_STRING_free(reqnames);
752
20
	sk_OCSP_CERTID_free(ids);
753
20
	sk_X509_pop_free(sign_other, X509_free);
754
20
	sk_X509_pop_free(verify_other, X509_free);
755
20
	sk_CONF_VALUE_pop_free(headers, X509V3_conf_free);
756
757
20
	if (use_ssl != -1) {
758
4
		free(host);
759
4
		free(port);
760
4
		free(path);
761
4
	}
762
20
	return (ret);
763
20
}
764
765
static int
766
add_ocsp_cert(OCSP_REQUEST ** req, X509 * cert, const EVP_MD * cert_id_md, X509 * issuer,
767
    STACK_OF(OCSP_CERTID) * ids)
768
{
769
	OCSP_CERTID *id;
770
32
	if (!issuer) {
771
		BIO_printf(bio_err, "No issuer certificate specified\n");
772
		return 0;
773
	}
774
16
	if (!*req)
775
8
		*req = OCSP_REQUEST_new();
776
16
	if (!*req)
777
		goto err;
778
16
	id = OCSP_cert_to_id(cert_id_md, cert, issuer);
779

32
	if (!id || !sk_OCSP_CERTID_push(ids, id))
780
		goto err;
781
16
	if (!OCSP_request_add0_id(*req, id))
782
		goto err;
783
16
	return 1;
784
785
err:
786
	BIO_printf(bio_err, "Error Creating OCSP request\n");
787
	return 0;
788
16
}
789
790
static int
791
add_ocsp_serial(OCSP_REQUEST ** req, char *serial, const EVP_MD * cert_id_md, X509 * issuer,
792
    STACK_OF(OCSP_CERTID) * ids)
793
{
794
	OCSP_CERTID *id;
795
	X509_NAME *iname;
796
	ASN1_BIT_STRING *ikey;
797
	ASN1_INTEGER *sno;
798
	if (!issuer) {
799
		BIO_printf(bio_err, "No issuer certificate specified\n");
800
		return 0;
801
	}
802
	if (!*req)
803
		*req = OCSP_REQUEST_new();
804
	if (!*req)
805
		goto err;
806
	iname = X509_get_subject_name(issuer);
807
	ikey = X509_get0_pubkey_bitstr(issuer);
808
	sno = s2i_ASN1_INTEGER(NULL, serial);
809
	if (!sno) {
810
		BIO_printf(bio_err, "Error converting serial number %s\n", serial);
811
		return 0;
812
	}
813
	id = OCSP_cert_id_new(cert_id_md, iname, ikey, sno);
814
	ASN1_INTEGER_free(sno);
815
	if (!id || !sk_OCSP_CERTID_push(ids, id))
816
		goto err;
817
	if (!OCSP_request_add0_id(*req, id))
818
		goto err;
819
	return 1;
820
821
err:
822
	BIO_printf(bio_err, "Error Creating OCSP request\n");
823
	return 0;
824
}
825
826
static int
827
print_ocsp_summary(BIO * out, OCSP_BASICRESP * bs, OCSP_REQUEST * req,
828
    STACK_OF(OPENSSL_STRING) * names,
829
    STACK_OF(OCSP_CERTID) * ids, long nsec,
830
    long maxage)
831
{
832
	OCSP_CERTID *id;
833
	char *name;
834
	int i;
835
836
16
	int status, reason;
837
838
8
	ASN1_GENERALIZEDTIME *rev, *thisupd, *nextupd;
839
840

20
	if (!bs || !req || !sk_OPENSSL_STRING_num(names) || !sk_OCSP_CERTID_num(ids))
841
4
		return 1;
842
843
24
	for (i = 0; i < sk_OCSP_CERTID_num(ids); i++) {
844
8
		id = sk_OCSP_CERTID_value(ids, i);
845
8
		name = sk_OPENSSL_STRING_value(names, i);
846
8
		BIO_printf(out, "%s: ", name);
847
848
8
		if (!OCSP_resp_find_status(bs, id, &status, &reason,
849
			&rev, &thisupd, &nextupd)) {
850
			BIO_puts(out, "ERROR: No Status found.\n");
851
			continue;
852
		}
853
		/*
854
		 * Check validity: if invalid write to output BIO so we know
855
		 * which response this refers to.
856
		 */
857
8
		if (!OCSP_check_validity(thisupd, nextupd, nsec, maxage)) {
858
			BIO_puts(out, "WARNING: Status times invalid.\n");
859
			ERR_print_errors(out);
860
		}
861
8
		BIO_printf(out, "%s\n", OCSP_cert_status_str(status));
862
863
8
		BIO_puts(out, "\tThis Update: ");
864
8
		ASN1_GENERALIZEDTIME_print(out, thisupd);
865
8
		BIO_puts(out, "\n");
866
867
8
		if (nextupd) {
868
			BIO_puts(out, "\tNext Update: ");
869
			ASN1_GENERALIZEDTIME_print(out, nextupd);
870
			BIO_puts(out, "\n");
871
		}
872
8
		if (status != V_OCSP_CERTSTATUS_REVOKED)
873
			continue;
874
875
4
		if (reason != -1)
876
			BIO_printf(out, "\tReason: %s\n",
877
			    OCSP_crl_reason_str(reason));
878
879
4
		BIO_puts(out, "\tRevocation Time: ");
880
4
		ASN1_GENERALIZEDTIME_print(out, rev);
881
4
		BIO_puts(out, "\n");
882
4
	}
883
884
4
	return 1;
885
8
}
886
887
888
static int
889
make_ocsp_response(OCSP_RESPONSE ** resp, OCSP_REQUEST * req, CA_DB * db,
890
    X509 * ca, X509 * rcert, EVP_PKEY * rkey,
891
    STACK_OF(X509) * rother, unsigned long flags,
892
    int nmin, int ndays)
893
{
894
	ASN1_TIME *thisupd = NULL, *nextupd = NULL;
895
	OCSP_CERTID *cid, *ca_id = NULL;
896
	OCSP_BASICRESP *bs = NULL;
897
	int i, id_count, ret = 1;
898
899
16
	id_count = OCSP_request_onereq_count(req);
900
901
8
	if (id_count <= 0) {
902
		*resp = OCSP_response_create(OCSP_RESPONSE_STATUS_MALFORMEDREQUEST, NULL);
903
		goto end;
904
	}
905
8
	bs = OCSP_BASICRESP_new();
906
8
	thisupd = X509_gmtime_adj(NULL, 0);
907
8
	if (ndays != -1)
908
		nextupd = X509_gmtime_adj(NULL, nmin * 60 + ndays * 3600 * 24);
909
910
	/* Examine each certificate id in the request */
911
48
	for (i = 0; i < id_count; i++) {
912
		OCSP_ONEREQ *one;
913
16
		ASN1_INTEGER *serial;
914
		char **inf;
915
16
		ASN1_OBJECT *cert_id_md_oid;
916
		const EVP_MD *cert_id_md;
917
16
		one = OCSP_request_onereq_get0(req, i);
918
16
		cid = OCSP_onereq_get0_id(one);
919
920
16
		OCSP_id_get0_info(NULL, &cert_id_md_oid, NULL, NULL, cid);
921
922
16
		cert_id_md = EVP_get_digestbyobj(cert_id_md_oid);
923
16
		if (!cert_id_md) {
924
			*resp = OCSP_response_create(OCSP_RESPONSE_STATUS_INTERNALERROR,
925
			    NULL);
926
			goto end;
927
		}
928
16
		if (ca_id)
929
8
			OCSP_CERTID_free(ca_id);
930
16
		ca_id = OCSP_cert_to_id(cert_id_md, NULL, ca);
931
932
		/* Is this request about our CA? */
933
16
		if (OCSP_id_issuer_cmp(ca_id, cid)) {
934
			OCSP_basic_add1_status(bs, cid,
935
			    V_OCSP_CERTSTATUS_UNKNOWN,
936
			    0, NULL,
937
			    thisupd, nextupd);
938
			continue;
939
		}
940
16
		OCSP_id_get0_info(NULL, NULL, NULL, &serial, cid);
941
16
		inf = lookup_serial(db, serial);
942
16
		if (!inf)
943
			OCSP_basic_add1_status(bs, cid,
944
			    V_OCSP_CERTSTATUS_UNKNOWN,
945
			    0, NULL,
946
			    thisupd, nextupd);
947
16
		else if (inf[DB_type][0] == DB_TYPE_VAL)
948
8
			OCSP_basic_add1_status(bs, cid,
949
			    V_OCSP_CERTSTATUS_GOOD,
950
			    0, NULL,
951
			    thisupd, nextupd);
952
8
		else if (inf[DB_type][0] == DB_TYPE_REV) {
953
8
			ASN1_OBJECT *inst = NULL;
954
8
			ASN1_TIME *revtm = NULL;
955
8
			ASN1_GENERALIZEDTIME *invtm = NULL;
956
			OCSP_SINGLERESP *single;
957
8
			int reason = -1;
958
8
			unpack_revinfo(&revtm, &reason, &inst, &invtm, inf[DB_rev_date]);
959
8
			single = OCSP_basic_add1_status(bs, cid,
960
			    V_OCSP_CERTSTATUS_REVOKED,
961
8
			    reason, revtm,
962
			    thisupd, nextupd);
963
8
			if (invtm)
964
				OCSP_SINGLERESP_add1_ext_i2d(single, NID_invalidity_date, invtm, 0, 0);
965
8
			else if (inst)
966
				OCSP_SINGLERESP_add1_ext_i2d(single, NID_hold_instruction_code, inst, 0, 0);
967
8
			ASN1_OBJECT_free(inst);
968
8
			ASN1_TIME_free(revtm);
969
8
			ASN1_GENERALIZEDTIME_free(invtm);
970
8
		}
971

48
	}
972
973
8
	OCSP_copy_nonce(bs, req);
974
975
8
	OCSP_basic_sign(bs, rcert, rkey, NULL, rother, flags);
976
977
8
	*resp = OCSP_response_create(OCSP_RESPONSE_STATUS_SUCCESSFUL, bs);
978
979
end:
980
8
	ASN1_TIME_free(thisupd);
981
8
	ASN1_TIME_free(nextupd);
982
8
	OCSP_CERTID_free(ca_id);
983
8
	OCSP_BASICRESP_free(bs);
984
8
	return ret;
985
986
8
}
987
988
static char **
989
lookup_serial(CA_DB * db, ASN1_INTEGER * ser)
990
{
991
	int i;
992
	BIGNUM *bn = NULL;
993
32
	char *itmp, *row[DB_NUMBER], **rrow;
994
224
	for (i = 0; i < DB_NUMBER; i++)
995
96
		row[i] = NULL;
996
16
	bn = ASN1_INTEGER_to_BN(ser, NULL);
997
16
	OPENSSL_assert(bn);	/* FIXME: should report an error at this
998
				 * point and abort */
999
16
	if (BN_is_zero(bn))
1000
		itmp = strdup("00");
1001
	else
1002
16
		itmp = BN_bn2hex(bn);
1003
16
	row[DB_serial] = itmp;
1004
16
	BN_free(bn);
1005
16
	rrow = TXT_DB_get_by_index(db->db, DB_serial, row);
1006
16
	free(itmp);
1007
16
	return rrow;
1008
16
}
1009
1010
/* Quick and dirty OCSP server: read in and parse input request */
1011
1012
static BIO *
1013
init_responder(char *port)
1014
{
1015
	BIO *acbio = NULL, *bufbio = NULL;
1016
8
	bufbio = BIO_new(BIO_f_buffer());
1017
4
	if (!bufbio)
1018
		goto err;
1019
4
	acbio = BIO_new_accept(port);
1020
4
	if (!acbio)
1021
		goto err;
1022
4
	BIO_set_accept_bios(acbio, bufbio);
1023
	bufbio = NULL;
1024
1025
4
	if (BIO_do_accept(acbio) <= 0) {
1026
		BIO_printf(bio_err, "Error setting up accept BIO\n");
1027
		ERR_print_errors(bio_err);
1028
		goto err;
1029
	}
1030
4
	return acbio;
1031
1032
err:
1033
	BIO_free_all(acbio);
1034
	BIO_free(bufbio);
1035
	return NULL;
1036
4
}
1037
1038
static int
1039
do_responder(OCSP_REQUEST ** preq, BIO ** pcbio, BIO * acbio, char *port)
1040
{
1041
	int have_post = 0, len;
1042
	OCSP_REQUEST *req = NULL;
1043
8
	char inbuf[1024];
1044
	BIO *cbio = NULL;
1045
1046
4
	if (BIO_do_accept(acbio) <= 0) {
1047
		BIO_printf(bio_err, "Error accepting connection\n");
1048
		ERR_print_errors(bio_err);
1049
		return 0;
1050
	}
1051
4
	cbio = BIO_pop(acbio);
1052
4
	*pcbio = cbio;
1053
1054
16
	for (;;) {
1055
16
		len = BIO_gets(cbio, inbuf, sizeof inbuf);
1056
16
		if (len <= 0)
1057
			return 1;
1058
		/* Look for "POST" signalling start of query */
1059
16
		if (!have_post) {
1060
4
			if (strncmp(inbuf, "POST", 4)) {
1061
				BIO_printf(bio_err, "Invalid request\n");
1062
				return 1;
1063
			}
1064
			have_post = 1;
1065
4
		}
1066
		/* Look for end of headers */
1067

28
		if ((inbuf[0] == '\r') || (inbuf[0] == '\n'))
1068
			break;
1069
	}
1070
1071
	/* Try to read OCSP request */
1072
1073
4
	req = d2i_OCSP_REQUEST_bio(cbio, NULL);
1074
1075
4
	if (!req) {
1076
		BIO_printf(bio_err, "Error parsing OCSP request\n");
1077
		ERR_print_errors(bio_err);
1078
	}
1079
4
	*preq = req;
1080
1081
4
	return 1;
1082
1083
4
}
1084
1085
static int
1086
send_ocsp_response(BIO * cbio, OCSP_RESPONSE * resp)
1087
{
1088
	static const char http_resp[] =
1089
	"HTTP/1.0 200 OK\r\nContent-type: application/ocsp-response\r\n"
1090
	"Content-Length: %d\r\n\r\n";
1091
8
	if (!cbio)
1092
		return 0;
1093
4
	BIO_printf(cbio, http_resp, i2d_OCSP_RESPONSE(resp, NULL));
1094
4
	i2d_OCSP_RESPONSE_bio(cbio, resp);
1095
4
	(void) BIO_flush(cbio);
1096
4
	return 1;
1097
4
}
1098
1099
static OCSP_RESPONSE *
1100
query_responder(BIO * err, BIO * cbio, char *path,
1101
    STACK_OF(CONF_VALUE) * headers,
1102
    OCSP_REQUEST * req, int req_timeout)
1103
{
1104
8
	int fd;
1105
	int rv;
1106
	int i;
1107
	OCSP_REQ_CTX *ctx = NULL;
1108
4
	OCSP_RESPONSE *rsp = NULL;
1109
4
	struct pollfd pfd[1];
1110
1111
4
	if (req_timeout != -1)
1112
		BIO_set_nbio(cbio, 1);
1113
1114
4
	rv = BIO_do_connect(cbio);
1115
1116

4
	if ((rv <= 0) && ((req_timeout == -1) || !BIO_should_retry(cbio))) {
1117
		BIO_puts(err, "Error connecting BIO\n");
1118
		return NULL;
1119
	}
1120
4
	if (BIO_get_fd(cbio, &fd) < 0) {
1121
		BIO_puts(err, "Can't get connection fd\n");
1122
		goto err;
1123
	}
1124
4
	if (req_timeout != -1 && rv <= 0) {
1125
		pfd[0].fd = fd;
1126
		pfd[0].events = POLLOUT;
1127
		rv = poll(pfd, 1, req_timeout * 1000);
1128
		if (rv == 0) {
1129
			BIO_puts(err, "Timeout on connect\n");
1130
			return NULL;
1131
		}
1132
		if (rv == -1) {
1133
			BIO_puts(err, "Poll error\n");
1134
			return NULL;
1135
		}
1136
	}
1137
4
	ctx = OCSP_sendreq_new(cbio, path, NULL, -1);
1138
4
	if (!ctx)
1139
		return NULL;
1140
1141
8
	for (i = 0; i < sk_CONF_VALUE_num(headers); i++) {
1142
		CONF_VALUE *hdr = sk_CONF_VALUE_value(headers, i);
1143
		if (!OCSP_REQ_CTX_add1_header(ctx, hdr->name, hdr->value))
1144
			goto err;
1145
	}
1146
1147
4
	if (!OCSP_REQ_CTX_set1_req(ctx, req))
1148
		goto err;
1149
1150
4
	for (;;) {
1151
4
		rv = OCSP_sendreq_nbio(&rsp, ctx);
1152
4
		if (rv != -1)
1153
			break;
1154
		if (req_timeout == -1)
1155
			continue;
1156
		pfd[0].fd = fd;
1157
		if (BIO_should_read(cbio))
1158
			pfd[0].events = POLLIN;
1159
		else if (BIO_should_write(cbio))
1160
			pfd[0].events = POLLOUT;
1161
		else {
1162
			BIO_puts(err, "Unexpected retry condition\n");
1163
			goto err;
1164
		}
1165
		rv = poll(pfd, 1, req_timeout * 1000);
1166
		if (rv == 0) {
1167
			BIO_puts(err, "Timeout on request\n");
1168
			break;
1169
		}
1170
		if (rv == -1 || (pfd[0].revents & (POLLERR|POLLNVAL))) {
1171
			BIO_puts(err, "Poll error\n");
1172
			break;
1173
		}
1174
	}
1175
err:
1176
4
	if (ctx)
1177
4
		OCSP_REQ_CTX_free(ctx);
1178
1179
4
	return rsp;
1180
4
}
1181
1182
OCSP_RESPONSE *
1183
process_responder(BIO * err, OCSP_REQUEST * req,
1184
    char *host, char *path, char *port, int use_ssl,
1185
    STACK_OF(CONF_VALUE) * headers,
1186
    int req_timeout)
1187
{
1188
	BIO *cbio = NULL;
1189
	SSL_CTX *ctx = NULL;
1190
	OCSP_RESPONSE *resp = NULL;
1191
8
	cbio = BIO_new_connect(host);
1192
4
	if (!cbio) {
1193
		BIO_printf(err, "Error creating connect BIO\n");
1194
		goto end;
1195
	}
1196
4
	if (port)
1197
4
		BIO_set_conn_port(cbio, port);
1198
4
	if (use_ssl == 1) {
1199
		BIO *sbio;
1200
		ctx = SSL_CTX_new(SSLv23_client_method());
1201
		if (ctx == NULL) {
1202
			BIO_printf(err, "Error creating SSL context.\n");
1203
			goto end;
1204
		}
1205
		SSL_CTX_set_mode(ctx, SSL_MODE_AUTO_RETRY);
1206
		sbio = BIO_new_ssl(ctx, 1);
1207
		cbio = BIO_push(sbio, cbio);
1208
	}
1209
4
	resp = query_responder(err, cbio, path, headers, req, req_timeout);
1210
4
	if (!resp)
1211
		BIO_printf(bio_err, "Error querying OCSP responder\n");
1212
end:
1213
4
	if (cbio)
1214
4
		BIO_free_all(cbio);
1215
4
	if (ctx)
1216
		SSL_CTX_free(ctx);
1217
4
	return resp;
1218
4
}
1219
1220
#endif