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