xref: /openbsd-src/usr.sbin/rpki-client/parser.c (revision f1dd7b858388b4a23f4f67a4957ec5ff656ebbe8)
1 /*	$OpenBSD: parser.c,v 1.10 2021/05/11 11:32:51 claudio Exp $ */
2 /*
3  * Copyright (c) 2019 Claudio Jeker <claudio@openbsd.org>
4  * Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv>
5  *
6  * Permission to use, copy, modify, and distribute this software for any
7  * purpose with or without fee is hereby granted, provided that the above
8  * copyright notice and this permission notice appear in all copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17  */
18 
19 #include <sys/queue.h>
20 #include <sys/tree.h>
21 #include <sys/types.h>
22 
23 #include <assert.h>
24 #include <err.h>
25 #include <poll.h>
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #include <limits.h>
30 #include <unistd.h>
31 #include <imsg.h>
32 
33 #include <openssl/asn1.h>
34 #include <openssl/err.h>
35 #include <openssl/evp.h>
36 #include <openssl/x509.h>
37 
38 #include "extern.h"
39 
40 static void	build_chain(const struct auth *, STACK_OF(X509) **);
41 static void	build_crls(const struct auth *, struct crl_tree *,
42 		    STACK_OF(X509_CRL) **);
43 /*
44  * Parse and validate a ROA.
45  * This is standard stuff.
46  * Returns the roa on success, NULL on failure.
47  */
48 static struct roa *
49 proc_parser_roa(struct entity *entp,
50     X509_STORE *store, X509_STORE_CTX *ctx,
51     struct auth_tree *auths, struct crl_tree *crlt)
52 {
53 	struct roa		*roa;
54 	X509			*x509;
55 	int			 c, i;
56 	struct auth		*a;
57 	STACK_OF(X509)		*chain;
58 	STACK_OF(X509_CRL)	*crls;
59 	const ASN1_TIME		*at;
60 	struct tm		 expires_tm;
61 	time_t			 expires;
62 
63 	if ((roa = roa_parse(&x509, entp->file)) == NULL)
64 		return NULL;
65 
66 	a = valid_ski_aki(entp->file, auths, roa->ski, roa->aki);
67 
68 	build_chain(a, &chain);
69 	build_crls(a, crlt, &crls);
70 
71 	assert(x509 != NULL);
72 	if (!X509_STORE_CTX_init(ctx, store, x509, chain))
73 		cryptoerrx("X509_STORE_CTX_init");
74 	X509_STORE_CTX_set_flags(ctx,
75 	    X509_V_FLAG_IGNORE_CRITICAL | X509_V_FLAG_CRL_CHECK);
76 	X509_STORE_CTX_set0_crls(ctx, crls);
77 
78 	if (X509_verify_cert(ctx) <= 0) {
79 		c = X509_STORE_CTX_get_error(ctx);
80 		X509_STORE_CTX_cleanup(ctx);
81 		if (verbose > 0 || c != X509_V_ERR_UNABLE_TO_GET_CRL)
82 			warnx("%s: %s", entp->file,
83 			    X509_verify_cert_error_string(c));
84 		X509_free(x509);
85 		roa_free(roa);
86 		sk_X509_free(chain);
87 		sk_X509_CRL_free(crls);
88 		return NULL;
89 	}
90 	X509_STORE_CTX_cleanup(ctx);
91 
92 	/*
93 	 * Scan the stack of CRLs to figure out the soonest transitive
94 	 * expiry moment
95 	 */
96 	for (i = 0; i < sk_X509_CRL_num(crls); i++) {
97 		X509_CRL *ci = sk_X509_CRL_value(crls, i);
98 
99 		at = X509_CRL_get0_nextUpdate(ci);
100 		if (at == NULL) {
101 			err(1, "X509_CRL_get0_nextUpdate failed");
102 			goto out;
103 		}
104 		memset(&expires_tm, 0, sizeof(expires_tm));
105 		if (ASN1_time_parse(at->data, at->length, &expires_tm,
106 		    V_ASN1_UTCTIME) != V_ASN1_UTCTIME) {
107 			err(1, "ASN1_time_parse failed");
108 			goto out;
109 		}
110 		if ((expires = mktime(&expires_tm)) == -1) {
111 			err(1, "mktime failed");
112 			goto out;
113 		}
114 		if (roa->expires > expires)
115 			roa->expires = expires;
116 	}
117 
118 	/*
119 	 * Scan the stack of CAs to figure out the soonest transitive
120 	 * expiry moment
121 	 */
122 	for (i = 0; i < sk_X509_num(chain); i++) {
123 		X509 *xi = sk_X509_value(chain, i);
124 
125 		at = X509_get0_notAfter(xi);
126 		if (at == NULL) {
127 			err(1, "X509_get0_notafter failed");
128 			goto out;
129 		}
130 		memset(&expires_tm, 0, sizeof(expires_tm));
131 		if (ASN1_time_parse(at->data, at->length, &expires_tm,
132 		    V_ASN1_UTCTIME) != V_ASN1_UTCTIME) {
133 			err(1, "ASN1_time_parse failed");
134 			goto out;
135 		}
136 		if ((expires = mktime(&expires_tm)) == -1) {
137 			err(1, "mktime failed");
138 			goto out;
139 		}
140 		if (roa->expires > expires)
141 			roa->expires = expires;
142 	}
143 
144 	/*
145 	 * If the ROA isn't valid, we accept it anyway and depend upon
146 	 * the code around roa_read() to check the "valid" field itself.
147 	 */
148 
149 	if (valid_roa(entp->file, auths, roa))
150 		roa->valid = 1;
151 
152 out:
153 	sk_X509_free(chain);
154 	sk_X509_CRL_free(crls);
155 	X509_free(x509);
156 
157 	return roa;
158 }
159 
160 /*
161  * Parse and validate a manifest file.
162  * Here we *don't* validate against the list of CRLs, because the
163  * certificate used to sign the manifest may specify a CRL that the root
164  * certificate didn't, and we haven't scanned for it yet.
165  * This chicken-and-egg isn't important, however, because we'll catch
166  * the revocation list by the time we scan for any contained resources
167  * (ROA, CER) and will see it then.
168  * Return the mft on success or NULL on failure.
169  */
170 static struct mft *
171 proc_parser_mft(struct entity *entp, X509_STORE *store, X509_STORE_CTX *ctx,
172 	struct auth_tree *auths, struct crl_tree *crlt)
173 {
174 	struct mft		*mft;
175 	X509			*x509;
176 	int			 c;
177 	struct auth		*a;
178 	STACK_OF(X509)		*chain;
179 
180 	if ((mft = mft_parse(&x509, entp->file)) == NULL)
181 		return NULL;
182 
183 	a = valid_ski_aki(entp->file, auths, mft->ski, mft->aki);
184 	build_chain(a, &chain);
185 
186 	if (!X509_STORE_CTX_init(ctx, store, x509, chain))
187 		cryptoerrx("X509_STORE_CTX_init");
188 
189 	/* CRL checked disabled here because CRL is referenced from mft */
190 	X509_STORE_CTX_set_flags(ctx, X509_V_FLAG_IGNORE_CRITICAL);
191 
192 	if (X509_verify_cert(ctx) <= 0) {
193 		c = X509_STORE_CTX_get_error(ctx);
194 		X509_STORE_CTX_cleanup(ctx);
195 		warnx("%s: %s", entp->file, X509_verify_cert_error_string(c));
196 		mft_free(mft);
197 		X509_free(x509);
198 		sk_X509_free(chain);
199 		return NULL;
200 	}
201 
202 	X509_STORE_CTX_cleanup(ctx);
203 	sk_X509_free(chain);
204 	X509_free(x509);
205 
206 	if (!mft_check(entp->file, mft)) {
207 		mft_free(mft);
208 		return NULL;
209 	}
210 
211 	return mft;
212 }
213 
214 /*
215  * Certificates are from manifests (has a digest and is signed with
216  * another certificate) Parse the certificate, make sure its
217  * signatures are valid (with CRLs), then validate the RPKI content.
218  * This returns a certificate (which must not be freed) or NULL on
219  * parse failure.
220  */
221 static struct cert *
222 proc_parser_cert(const struct entity *entp,
223     X509_STORE *store, X509_STORE_CTX *ctx,
224     struct auth_tree *auths, struct crl_tree *crlt)
225 {
226 	struct cert		*cert;
227 	X509			*x509;
228 	int			 c;
229 	struct auth		*a = NULL, *na;
230 	char			*tal;
231 	STACK_OF(X509)		*chain;
232 	STACK_OF(X509_CRL)	*crls;
233 
234 	assert(!entp->has_pkey);
235 
236 	/* Extract certificate data and X509. */
237 
238 	cert = cert_parse(&x509, entp->file);
239 	if (cert == NULL)
240 		return NULL;
241 
242 	a = valid_ski_aki(entp->file, auths, cert->ski, cert->aki);
243 	build_chain(a, &chain);
244 	build_crls(a, crlt, &crls);
245 
246 	/*
247 	 * Validate certificate chain w/CRLs.
248 	 * Only check the CRLs if specifically asked.
249 	 */
250 
251 	assert(x509 != NULL);
252 	if (!X509_STORE_CTX_init(ctx, store, x509, chain))
253 		cryptoerrx("X509_STORE_CTX_init");
254 
255 	X509_STORE_CTX_set_flags(ctx,
256 	    X509_V_FLAG_IGNORE_CRITICAL | X509_V_FLAG_CRL_CHECK);
257 	X509_STORE_CTX_set0_crls(ctx, crls);
258 
259 	if (X509_verify_cert(ctx) <= 0) {
260 		c = X509_STORE_CTX_get_error(ctx);
261 		warnx("%s: %s", entp->file,
262 		    X509_verify_cert_error_string(c));
263 		X509_STORE_CTX_cleanup(ctx);
264 		cert_free(cert);
265 		sk_X509_free(chain);
266 		sk_X509_CRL_free(crls);
267 		X509_free(x509);
268 		return NULL;
269 	}
270 
271 	X509_STORE_CTX_cleanup(ctx);
272 	sk_X509_free(chain);
273 	sk_X509_CRL_free(crls);
274 
275 	/* Validate the cert to get the parent */
276 	if (!valid_cert(entp->file, auths, cert)) {
277 		X509_free(x509); // needed? XXX
278 		return cert;
279 	}
280 
281 	/*
282 	 * Add validated certs to the RPKI auth tree.
283 	 */
284 
285 	cert->valid = 1;
286 
287 	na = malloc(sizeof(*na));
288 	if (na == NULL)
289 		err(1, NULL);
290 
291 	tal = a->tal;
292 
293 	na->parent = a;
294 	na->cert = cert;
295 	na->tal = tal;
296 	na->fn = strdup(entp->file);
297 	if (na->fn == NULL)
298 		err(1, NULL);
299 
300 	if (RB_INSERT(auth_tree, auths, na) != NULL)
301 		err(1, "auth tree corrupted");
302 
303 	return cert;
304 }
305 
306 
307 /*
308  * Root certificates come from TALs (has a pkey and is self-signed).
309  * Parse the certificate, ensure that it's public key matches the
310  * known public key from the TAL, and then validate the RPKI
311  * content. If valid, we add it as a trusted root (trust anchor) to
312  * "store".
313  *
314  * This returns a certificate (which must not be freed) or NULL on
315  * parse failure.
316  */
317 static struct cert *
318 proc_parser_root_cert(const struct entity *entp,
319     X509_STORE *store, X509_STORE_CTX *ctx,
320     struct auth_tree *auths, struct crl_tree *crlt)
321 {
322 	char			subject[256];
323 	ASN1_TIME		*notBefore, *notAfter;
324 	X509_NAME		*name;
325 	struct cert		*cert;
326 	X509			*x509;
327 	struct auth		*na;
328 	char			*tal;
329 
330 	assert(entp->has_pkey);
331 
332 	/* Extract certificate data and X509. */
333 
334 	cert = ta_parse(&x509, entp->file, entp->pkey, entp->pkeysz);
335 	if (cert == NULL)
336 		return NULL;
337 
338 	if ((name = X509_get_subject_name(x509)) == NULL) {
339 		warnx("%s Unable to get certificate subject", entp->file);
340 		goto badcert;
341 	}
342 	if (X509_NAME_oneline(name, subject, sizeof(subject)) == NULL) {
343 		warnx("%s: Unable to parse certificate subject name",
344 		    entp->file);
345 		goto badcert;
346 	}
347 	if ((notBefore = X509_get_notBefore(x509)) == NULL) {
348 		warnx("%s: certificate has invalid notBefore, subject='%s'",
349 		    entp->file, subject);
350 		goto badcert;
351 	}
352 	if ((notAfter = X509_get_notAfter(x509)) == NULL) {
353 		warnx("%s: certificate has invalid notAfter, subject='%s'",
354 		    entp->file, subject);
355 		goto badcert;
356 	}
357 	if (X509_cmp_current_time(notBefore) != -1) {
358 		warnx("%s: certificate not yet valid, subject='%s'", entp->file,
359 		    subject);
360 		goto badcert;
361 	}
362 	if (X509_cmp_current_time(notAfter) != 1)  {
363 		warnx("%s: certificate has expired, subject='%s'", entp->file,
364 		    subject);
365 		goto badcert;
366 	}
367 	if (!valid_ta(entp->file, auths, cert)) {
368 		warnx("%s: certificate not a valid ta, subject='%s'",
369 		    entp->file, subject);
370 		goto badcert;
371 	}
372 
373 	/*
374 	 * Add valid roots to the RPKI auth tree and as a trusted root
375 	 * for chain validation to the X509_STORE.
376 	 */
377 
378 	cert->valid = 1;
379 
380 	na = malloc(sizeof(*na));
381 	if (na == NULL)
382 		err(1, NULL);
383 
384 	if ((tal = strdup(entp->descr)) == NULL)
385 		err(1, NULL);
386 
387 	na->parent = NULL;
388 	na->cert = cert;
389 	na->tal = tal;
390 	na->fn = strdup(entp->file);
391 	if (na->fn == NULL)
392 		err(1, NULL);
393 
394 	if (RB_INSERT(auth_tree, auths, na) != NULL)
395 		err(1, "auth tree corrupted");
396 
397 	X509_STORE_add_cert(store, x509);
398 
399 	return cert;
400  badcert:
401 	X509_free(x509); // needed? XXX
402 	return cert;
403 }
404 
405 /*
406  * Parse a certificate revocation list
407  * This simply parses the CRL content itself, optionally validating it
408  * within the digest if it comes from a manifest, then adds it to the
409  * store of CRLs.
410  */
411 static void
412 proc_parser_crl(struct entity *entp, X509_STORE *store,
413     X509_STORE_CTX *ctx, struct crl_tree *crlt)
414 {
415 	X509_CRL		*x509_crl;
416 	struct crl		*crl;
417 
418 	if ((x509_crl = crl_parse(entp->file)) != NULL) {
419 		if ((crl = malloc(sizeof(*crl))) == NULL)
420 			err(1, NULL);
421 		if ((crl->aki = x509_crl_get_aki(x509_crl, entp->file)) ==
422 		    NULL)
423 			errx(1, "x509_crl_get_aki failed");
424 		crl->x509_crl = x509_crl;
425 
426 		if (RB_INSERT(crl_tree, crlt, crl) != NULL) {
427 			warnx("%s: duplicate AKI %s", entp->file, crl->aki);
428 			free_crl(crl);
429 		}
430 	}
431 }
432 
433 /*
434  * Parse a ghostbuster record
435  */
436 static void
437 proc_parser_gbr(struct entity *entp, X509_STORE *store,
438     X509_STORE_CTX *ctx, struct auth_tree *auths, struct crl_tree *crlt)
439 {
440 	struct gbr		*gbr;
441 	X509			*x509;
442 	int			 c;
443 	struct auth		*a;
444 	STACK_OF(X509)		*chain;
445 	STACK_OF(X509_CRL)	*crls;
446 
447 	if ((gbr = gbr_parse(&x509, entp->file)) == NULL)
448 		return;
449 
450 	a = valid_ski_aki(entp->file, auths, gbr->ski, gbr->aki);
451 
452 	build_chain(a, &chain);
453 	build_crls(a, crlt, &crls);
454 
455 	assert(x509 != NULL);
456 	if (!X509_STORE_CTX_init(ctx, store, x509, chain))
457 		cryptoerrx("X509_STORE_CTX_init");
458 	X509_STORE_CTX_set_flags(ctx,
459 	    X509_V_FLAG_IGNORE_CRITICAL | X509_V_FLAG_CRL_CHECK);
460 	X509_STORE_CTX_set0_crls(ctx, crls);
461 
462 	if (X509_verify_cert(ctx) <= 0) {
463 		c = X509_STORE_CTX_get_error(ctx);
464 		if (verbose > 0 || c != X509_V_ERR_UNABLE_TO_GET_CRL)
465 			warnx("%s: %s", entp->file,
466 			    X509_verify_cert_error_string(c));
467 	}
468 
469 	X509_STORE_CTX_cleanup(ctx);
470 	sk_X509_free(chain);
471 	sk_X509_CRL_free(crls);
472 	X509_free(x509);
473 	gbr_free(gbr);
474 }
475 
476 /*
477  * Use the parent to walk the tree to the root and build a certificate
478  * chain from cert->x509. Do not include the root node since this node
479  * should already be in the X509_STORE as a trust anchor.
480  */
481 static void
482 build_chain(const struct auth *a, STACK_OF(X509) **chain)
483 {
484 	*chain = NULL;
485 
486 	if (a == NULL)
487 		return;
488 
489 	if ((*chain = sk_X509_new_null()) == NULL)
490 		err(1, "sk_X509_new_null");
491 	for (; a->parent != NULL; a = a->parent) {
492 		assert(a->cert->x509 != NULL);
493 		if (!sk_X509_push(*chain, a->cert->x509))
494 			errx(1, "sk_X509_push");
495 	}
496 }
497 
498 /*
499  * Add the CRL based on the certs SKI value.
500  * No need to insert any other CRL since those were already checked.
501  */
502 static void
503 build_crls(const struct auth *a, struct crl_tree *crlt,
504     STACK_OF(X509_CRL) **crls)
505 {
506 	struct crl	find, *found;
507 
508 	*crls = NULL;
509 
510 	if (a == NULL)
511 		return;
512 
513 	if ((*crls = sk_X509_CRL_new_null()) == NULL)
514 		errx(1, "sk_X509_CRL_new_null");
515 
516 	find.aki = a->cert->ski;
517 	found = RB_FIND(crl_tree, crlt, &find);
518 	if (found && !sk_X509_CRL_push(*crls, found->x509_crl))
519 		err(1, "sk_X509_CRL_push");
520 }
521 
522 /*
523  * Process responsible for parsing and validating content.
524  * All this process does is wait to be told about a file to parse, then
525  * it parses it and makes sure that the data being returned is fully
526  * validated and verified.
527  * The process will exit cleanly only when fd is closed.
528  */
529 void
530 proc_parser(int fd)
531 {
532 	struct tal	*tal;
533 	struct cert	*cert;
534 	struct mft	*mft;
535 	struct roa	*roa;
536 	struct entity	*entp;
537 	struct entityq	 q;
538 	int		 c, rc = 1;
539 	struct msgbuf	 msgq;
540 	struct pollfd	 pfd;
541 	struct ibuf	*b;
542 	X509_STORE	*store;
543 	X509_STORE_CTX	*ctx;
544 	struct auth_tree auths = RB_INITIALIZER(&auths);
545 	struct crl_tree	 crlt = RB_INITIALIZER(&crlt);
546 
547 	ERR_load_crypto_strings();
548 	OpenSSL_add_all_ciphers();
549 	OpenSSL_add_all_digests();
550 
551 	if ((store = X509_STORE_new()) == NULL)
552 		cryptoerrx("X509_STORE_new");
553 	if ((ctx = X509_STORE_CTX_new()) == NULL)
554 		cryptoerrx("X509_STORE_CTX_new");
555 
556 	TAILQ_INIT(&q);
557 
558 	msgbuf_init(&msgq);
559 	msgq.fd = fd;
560 
561 	pfd.fd = fd;
562 
563 	io_socket_nonblocking(pfd.fd);
564 
565 	for (;;) {
566 		pfd.events = POLLIN;
567 		if (msgq.queued)
568 			pfd.events |= POLLOUT;
569 
570 		if (poll(&pfd, 1, INFTIM) == -1)
571 			err(1, "poll");
572 		if ((pfd.revents & (POLLERR|POLLNVAL)))
573 			errx(1, "poll: bad descriptor");
574 
575 		/* If the parent closes, return immediately. */
576 
577 		if ((pfd.revents & POLLHUP))
578 			break;
579 
580 		/*
581 		 * Start with read events.
582 		 * This means that the parent process is sending us
583 		 * something we need to parse.
584 		 * We don't actually parse it til we have space in our
585 		 * outgoing buffer for responding, though.
586 		 */
587 
588 		if ((pfd.revents & POLLIN)) {
589 			io_socket_blocking(fd);
590 			entp = calloc(1, sizeof(struct entity));
591 			if (entp == NULL)
592 				err(1, NULL);
593 			entity_read_req(fd, entp);
594 			TAILQ_INSERT_TAIL(&q, entp, entries);
595 			io_socket_nonblocking(fd);
596 		}
597 
598 		if (pfd.revents & POLLOUT) {
599 			switch (msgbuf_write(&msgq)) {
600 			case 0:
601 				errx(1, "write: connection closed");
602 			case -1:
603 				err(1, "write");
604 			}
605 		}
606 
607 		/*
608 		 * If there's nothing to parse, then stop waiting for
609 		 * the write signal.
610 		 */
611 
612 		if (TAILQ_EMPTY(&q)) {
613 			pfd.events &= ~POLLOUT;
614 			continue;
615 		}
616 
617 		entp = TAILQ_FIRST(&q);
618 		assert(entp != NULL);
619 
620 		if ((b = ibuf_dynamic(256, UINT_MAX)) == NULL)
621 			err(1, NULL);
622 		io_simple_buffer(b, &entp->type, sizeof(entp->type));
623 
624 		switch (entp->type) {
625 		case RTYPE_TAL:
626 			if ((tal = tal_parse(entp->file, entp->descr)) == NULL)
627 				goto out;
628 			tal_buffer(b, tal);
629 			tal_free(tal);
630 			break;
631 		case RTYPE_CER:
632 			if (entp->has_pkey)
633 				cert = proc_parser_root_cert(entp, store, ctx,
634 				    &auths, &crlt);
635 			else
636 				cert = proc_parser_cert(entp, store, ctx,
637 				    &auths, &crlt);
638 			c = (cert != NULL);
639 			io_simple_buffer(b, &c, sizeof(int));
640 			if (cert != NULL)
641 				cert_buffer(b, cert);
642 			/*
643 			 * The parsed certificate data "cert" is now
644 			 * managed in the "auths" table, so don't free
645 			 * it here (see the loop after "out").
646 			 */
647 			break;
648 		case RTYPE_MFT:
649 			mft = proc_parser_mft(entp, store, ctx, &auths, &crlt);
650 			c = (mft != NULL);
651 			io_simple_buffer(b, &c, sizeof(int));
652 			if (mft != NULL)
653 				mft_buffer(b, mft);
654 			mft_free(mft);
655 			break;
656 		case RTYPE_CRL:
657 			proc_parser_crl(entp, store, ctx, &crlt);
658 			break;
659 		case RTYPE_ROA:
660 			roa = proc_parser_roa(entp, store, ctx, &auths, &crlt);
661 			c = (roa != NULL);
662 			io_simple_buffer(b, &c, sizeof(int));
663 			if (roa != NULL)
664 				roa_buffer(b, roa);
665 			roa_free(roa);
666 			break;
667 		case RTYPE_GBR:
668 			proc_parser_gbr(entp, store, ctx, &auths, &crlt);
669 			break;
670 		default:
671 			abort();
672 		}
673 
674 		ibuf_close(&msgq, b);
675 		TAILQ_REMOVE(&q, entp, entries);
676 		entity_free(entp);
677 	}
678 
679 	rc = 0;
680 out:
681 	while ((entp = TAILQ_FIRST(&q)) != NULL) {
682 		TAILQ_REMOVE(&q, entp, entries);
683 		entity_free(entp);
684 	}
685 
686 	/* XXX free auths and crl tree */
687 
688 	X509_STORE_CTX_free(ctx);
689 	X509_STORE_free(store);
690 
691 	msgbuf_clear(&msgq);
692 
693 	exit(rc);
694 }
695