1 /*
2  * unbound-anchor.c - update the root anchor if necessary.
3  *
4  * Copyright (c) 2010, NLnet Labs. All rights reserved.
5  *
6  * This software is open source.
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  * Redistributions of source code must retain the above copyright notice,
13  * this list of conditions and the following disclaimer.
14  *
15  * Redistributions in binary form must reproduce the above copyright notice,
16  * this list of conditions and the following disclaimer in the documentation
17  * and/or other materials provided with the distribution.
18  *
19  * Neither the name of the NLNET LABS nor the names of its contributors may
20  * be used to endorse or promote products derived from this software without
21  * specific prior written permission.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
26  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
27  * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
29  * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
30  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
31  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
32  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34  */
35 
36 /**
37  * \file
38  *
39  * This file checks to see that the current 5011 keys work to prime the
40  * current root anchor.  If not a certificate is used to update the anchor,
41  * with RFC7958 https xml fetch.
42  *
43  * This is a concept solution for distribution of the DNSSEC root
44  * trust anchor.  It is a small tool, called "unbound-anchor", that
45  * runs before the main validator starts.  I.e. in the init script:
46  * unbound-anchor; unbound.  Thus it is meant to run at system boot time.
47  *
48  * Management-Abstract:
49  *    * first run: fill root.key file with hardcoded DS record.
50  *    * mostly: use RFC5011 tracking, quick . DNSKEY UDP query.
51  *    * failover: use RFC7958 builtin certificate, do https and update.
52  * Special considerations:
53  *    * 30-days RFC5011 timer saves a lot of https traffic.
54  *    * DNSKEY probe must be NOERROR, saves a lot of https traffic.
55  *    * fail if clock before sign date of the root, if cert expired.
56  *    * if the root goes back to unsigned, deals with it.
57  *
58  * It has hardcoded the root DS anchors and the ICANN CA root certificate.
59  * It allows with options to override those.  It also takes root-hints (it
60  * has to do a DNS resolve), and also has hardcoded defaults for those.
61  *
62  * Once it starts, just before the validator starts, it quickly checks if
63  * the root anchor file needs to be updated.  First it tries to use
64  * RFC5011-tracking of the root key.  If that fails (and for 30-days since
65  * last successful probe), then it attempts to update using the
66  * certificate.  So most of the time, the RFC5011 tracking will work fine,
67  * and within a couple milliseconds, the main daemon can start.  It will
68  * have only probed the . DNSKEY, not done expensive https transfers on the
69  * root infrastructure.
70  *
71  * If there is no root key in the root.key file, it bootstraps the
72  * RFC5011-tracking with its builtin DS anchors; if that fails it
73  * bootstraps the RFC5011-tracking using the certificate.  (again to avoid
74  * https, and it is also faster).
75  *
76  * It uses the XML file by converting it to DS records and writing that to the
77  * key file.  Unbound can detect that the 'special comments' are gone, and
78  * the file contains a list of normal DNSKEY/DS records, and uses that to
79  * bootstrap 5011 (the KSK is made VALID).
80  *
81  * The certificate RFC7958 update is done by fetching root-anchors.xml and
82  * root-anchors.p7s via SSL.  The HTTPS certificate can be logged but is
83  * not validated (https for channel security; the security comes from the
84  * certificate).  The 'data.iana.org' domain name A and AAAA are resolved
85  * without DNSSEC.  It tries a random IP until the transfer succeeds.  It
86  * then checks the p7s signature.
87  *
88  * On any failure, it leaves the root key file untouched.  The main
89  * validator has to cope with it, it cannot fix things (So a failure does
90  * not go 'without DNSSEC', no downgrade).  If it used its builtin stuff or
91  * did the https, it exits with an exit code, so that this can trigger the
92  * init script to log the event and potentially alert the operator that can
93  * do a manual check.
94  *
95  * The date is also checked.  Before 2010-07-15 is a failure (root not
96  * signed yet; avoids attacks on system clock).  The
97  * last-successful-RFC5011-probe (if available) has to be more than 30 days
98  * in the past (otherwise, RFC5011 should have worked).  This keeps
99  * unnecessary https traffic down.  If the main certificate is expired, it
100  * fails.
101  *
102  * The dates on the keys in the xml are checked (uses the libexpat xml
103  * parser), only the valid ones are used to re-enstate RFC5011 tracking.
104  * If 0 keys are valid, the zone has gone to insecure (a special marker is
105  * written in the keyfile that tells the main validator daemon the zone is
106  * insecure).
107  *
108  * Only the root ICANN CA is shipped, not the intermediate ones.  The
109  * intermediate CAs are included in the p7s file that was downloaded.  (the
110  * root cert is valid to 2028 and the intermediate to 2014, today).
111  *
112  * Obviously, the tool also has options so the operator can provide a new
113  * keyfile, a new certificate and new URLs, and fresh root hints.  By
114  * default it logs nothing on failure and success; it 'just works'.
115  *
116  */
117 
118 #include <err.h>
119 #include <libgen.h>
120 #include <unistd.h>
121 
122 #include "config.h"
123 #include "libunbound/unbound.h"
124 #include "sldns/rrdef.h"
125 #include "sldns/parseutil.h"
126 #include <expat.h>
127 #ifndef HAVE_EXPAT_H
128 #error "need libexpat to parse root-anchors.xml file."
129 #endif
130 #ifdef HAVE_GETOPT_H
131 #include <getopt.h>
132 #endif
133 #ifdef HAVE_OPENSSL_SSL_H
134 #include <openssl/ssl.h>
135 #endif
136 #ifdef HAVE_OPENSSL_ERR_H
137 #include <openssl/err.h>
138 #endif
139 #ifdef HAVE_OPENSSL_RAND_H
140 #include <openssl/rand.h>
141 #endif
142 #include <openssl/x509.h>
143 #include <openssl/x509v3.h>
144 #include <openssl/pem.h>
145 
146 /** name of server in URL to fetch HTTPS from */
147 #define URLNAME "data.iana.org"
148 /** path on HTTPS server to xml file */
149 #define XMLNAME "root-anchors/root-anchors.xml"
150 /** path on HTTPS server to p7s file */
151 #define P7SNAME "root-anchors/root-anchors.p7s"
152 /** name of the signer of the certificate */
153 #define P7SIGNER "dnssec@iana.org"
154 /** port number for https access */
155 #define HTTPS_PORT 443
156 
157 #ifdef USE_WINSOCK
158 /* sneakily reuse the wsa_strerror function, on windows */
159 char* wsa_strerror(int err);
160 #endif
161 
162 static const char ICANN_UPDATE_CA[] =
163 	/* The ICANN CA fetched at 24 Sep 2010.  Valid to 2028 */
164 	"-----BEGIN CERTIFICATE-----\n"
165 	"MIIDdzCCAl+gAwIBAgIBATANBgkqhkiG9w0BAQsFADBdMQ4wDAYDVQQKEwVJQ0FO\n"
166 	"TjEmMCQGA1UECxMdSUNBTk4gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxFjAUBgNV\n"
167 	"BAMTDUlDQU5OIFJvb3QgQ0ExCzAJBgNVBAYTAlVTMB4XDTA5MTIyMzA0MTkxMloX\n"
168 	"DTI5MTIxODA0MTkxMlowXTEOMAwGA1UEChMFSUNBTk4xJjAkBgNVBAsTHUlDQU5O\n"
169 	"IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MRYwFAYDVQQDEw1JQ0FOTiBSb290IENB\n"
170 	"MQswCQYDVQQGEwJVUzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKDb\n"
171 	"cLhPNNqc1NB+u+oVvOnJESofYS9qub0/PXagmgr37pNublVThIzyLPGCJ8gPms9S\n"
172 	"G1TaKNIsMI7d+5IgMy3WyPEOECGIcfqEIktdR1YWfJufXcMReZwU4v/AdKzdOdfg\n"
173 	"ONiwc6r70duEr1IiqPbVm5T05l1e6D+HkAvHGnf1LtOPGs4CHQdpIUcy2kauAEy2\n"
174 	"paKcOcHASvbTHK7TbbvHGPB+7faAztABLoneErruEcumetcNfPMIjXKdv1V1E3C7\n"
175 	"MSJKy+jAqqQJqjZoQGB0necZgUMiUv7JK1IPQRM2CXJllcyJrm9WFxY0c1KjBO29\n"
176 	"iIKK69fcglKcBuFShUECAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8B\n"
177 	"Af8EBAMCAf4wHQYDVR0OBBYEFLpS6UmDJIZSL8eZzfyNa2kITcBQMA0GCSqGSIb3\n"
178 	"DQEBCwUAA4IBAQAP8emCogqHny2UYFqywEuhLys7R9UKmYY4suzGO4nkbgfPFMfH\n"
179 	"6M+Zj6owwxlwueZt1j/IaCayoKU3QsrYYoDRolpILh+FPwx7wseUEV8ZKpWsoDoD\n"
180 	"2JFbLg2cfB8u/OlE4RYmcxxFSmXBg0yQ8/IoQt/bxOcEEhhiQ168H2yE5rxJMt9h\n"
181 	"15nu5JBSewrCkYqYYmaxyOC3WrVGfHZxVI7MpIFcGdvSb2a1uyuua8l0BKgk3ujF\n"
182 	"0/wsHNeP22qNyVO+XVBzrM8fk8BSUFuiT/6tZTYXRtEt5aKQZgXbKU5dUF3jT9qg\n"
183 	"j/Br5BZw3X/zd325TvnswzMC1+ljLzHnQGGk\n"
184 	"-----END CERTIFICATE-----\n";
185 
186 static const char DS_TRUST_ANCHOR[] =
187 	/* The anchors must start on a new line with ". IN DS and end with \n"[;]
188 	 * because the makedist script greps on the source here */
189 	/* anchor 20326 is from 2017 */
190 ". IN DS 20326 8 2 E06D44B80B8F1D39A95C0B0D7C65D08458E880409BBC683457104237C7F8EC8D\n"
191 	/* anchor 38696 is from 2024 */
192 ". IN DS 38696 8 2 683D2D0ACB8C9B712A1948B27F741219298D0A450D612C483AF444A4C0FB2B16\n";
193 
194 /** verbosity for this application */
195 static int verb = 0;
196 
197 /** list of IP addresses */
198 struct ip_list {
199 	/** next in list */
200 	struct ip_list* next;
201 	/** length of addr */
202 	socklen_t len;
203 	/** address ready to connect to */
204 	struct sockaddr_storage addr;
205 	/** has the address been used */
206 	int used;
207 };
208 
209 /** Give unbound-anchor usage, and exit (1). */
210 static void
usage(void)211 usage(void)
212 {
213 	printf("Usage:	unbound-anchor [opts]\n");
214 	printf("	Setup or update root anchor. "
215 		"Most options have defaults.\n");
216 	printf("	Run this program before you start the validator.\n");
217 	printf("\n");
218 	printf("	The anchor and cert have default builtin content\n");
219 	printf("	if the file does not exist or is empty.\n");
220 	printf("\n");
221 	printf("-a file		root key file, default %s\n", ROOT_ANCHOR_FILE);
222 	printf("		The key is input and output for this tool.\n");
223 	printf("-c file		cert file, default %s\n", ROOT_CERT_FILE);
224 	printf("-l		list builtin key and cert on stdout\n");
225 	printf("-u name		server in https url, default %s\n", URLNAME);
226 	printf("-S		do not use SNI for the https connection\n");
227 	printf("-x path		pathname to xml in url, default %s\n", XMLNAME);
228 	printf("-s path		pathname to p7s in url, default %s\n", P7SNAME);
229 	printf("-n name		signer's subject emailAddress, default %s\n", P7SIGNER);
230 	printf("-b address	source address to bind to\n");
231 	printf("-4		work using IPv4 only\n");
232 	printf("-6		work using IPv6 only\n");
233 	printf("-f resolv.conf	use given resolv.conf\n");
234 	printf("-r root.hints	use given root.hints\n"
235 		"		builtin root hints are used by default\n");
236 	printf("-R		fallback from -f to root query on error\n");
237 	printf("-v		more verbose\n");
238 	printf("-C conf		debug, read config\n");
239 	printf("-P port		use port for https connect, default 443\n");
240 	printf("-F 		debug, force update with cert\n");
241 	printf("-h		show this usage help\n");
242 	printf("Version %s\n", PACKAGE_VERSION);
243 	printf("BSD licensed, see LICENSE in source package for details.\n");
244 	printf("Report bugs to %s\n", PACKAGE_BUGREPORT);
245 	exit(1);
246 }
247 
248 /** return the built in root update certificate */
249 static const char*
get_builtin_cert(void)250 get_builtin_cert(void)
251 {
252 	return ICANN_UPDATE_CA;
253 }
254 
255 /** return the built in root DS trust anchor */
256 static const char*
get_builtin_ds(void)257 get_builtin_ds(void)
258 {
259 	return DS_TRUST_ANCHOR;
260 }
261 
262 /** print hex data */
263 static void
print_data(const char * msg,const char * data,size_t len)264 print_data(const char* msg, const char* data, size_t len)
265 {
266 	size_t i;
267 	printf("%s: ", msg);
268 	for(i=0; i<len; i++) {
269 		printf(" %2.2x", (unsigned char)data[i]);
270 	}
271 	printf("\n");
272 }
273 
274 /** print ub context creation error and exit */
275 static void
ub_ctx_error_exit(struct ub_ctx * ctx,const char * str,const char * str2)276 ub_ctx_error_exit(struct ub_ctx* ctx, const char* str, const char* str2)
277 {
278 	ub_ctx_delete(ctx);
279 	if(str && str2 && verb) printf("%s: %s\n", str, str2);
280 	if(verb) printf("error: could not create unbound resolver context\n");
281 	exit(0);
282 }
283 
284 /**
285  * Create a new unbound context with the commandline settings applied
286  */
287 static struct ub_ctx*
create_unbound_context(const char * res_conf,const char * root_hints,const char * debugconf,const char * srcaddr,int ip4only,int ip6only)288 create_unbound_context(const char* res_conf, const char* root_hints,
289 	const char* debugconf, const char* srcaddr, int ip4only, int ip6only)
290 {
291 	int r;
292 	struct ub_ctx* ctx = ub_ctx_create();
293 	if(!ctx) {
294 		if(verb) printf("out of memory\n");
295 		exit(0);
296 	}
297 	/* do not waste time and network traffic to fetch extra nameservers */
298 	r = ub_ctx_set_option(ctx, "target-fetch-policy:", "0 0 0 0 0");
299 	if(r && verb) printf("ctx targetfetchpolicy: %s\n", ub_strerror(r));
300 	/* read config file first, so its settings can be overridden */
301 	if(debugconf) {
302 		r = ub_ctx_config(ctx, debugconf);
303 		if(r) ub_ctx_error_exit(ctx, debugconf, ub_strerror(r));
304 	}
305 	if(res_conf) {
306 		r = ub_ctx_resolvconf(ctx, res_conf);
307 		if(r) ub_ctx_error_exit(ctx, res_conf, ub_strerror(r));
308 	}
309 	if(root_hints) {
310 		r = ub_ctx_set_option(ctx, "root-hints:", root_hints);
311 		if(r) ub_ctx_error_exit(ctx, root_hints, ub_strerror(r));
312 	}
313 	if(srcaddr) {
314 		r = ub_ctx_set_option(ctx, "outgoing-interface:", srcaddr);
315 		if(r) ub_ctx_error_exit(ctx, srcaddr, ub_strerror(r));
316 	}
317 	if(ip4only) {
318 		r = ub_ctx_set_option(ctx, "do-ip6:", "no");
319 		if(r) ub_ctx_error_exit(ctx, "ip4only", ub_strerror(r));
320 	}
321 	if(ip6only) {
322 		r = ub_ctx_set_option(ctx, "do-ip4:", "no");
323 		if(r) ub_ctx_error_exit(ctx, "ip6only", ub_strerror(r));
324 	}
325 	return ctx;
326 }
327 
328 /** printout certificate in detail */
329 static void
verb_cert(const char * msg,X509 * x)330 verb_cert(const char* msg, X509* x)
331 {
332 	if(verb == 0 || verb == 1) return;
333 	if(verb == 2) {
334 		if(msg) printf("%s\n", msg);
335 		X509_print_ex_fp(stdout, x, 0, (unsigned long)-1
336 			^(X509_FLAG_NO_SUBJECT
337 			|X509_FLAG_NO_ISSUER|X509_FLAG_NO_VALIDITY));
338 		return;
339 	}
340 	if(msg) printf("%s\n", msg);
341 	X509_print_fp(stdout, x);
342 }
343 
344 /** printout certificates in detail */
345 static void
verb_certs(const char * msg,STACK_OF (X509)* sk)346 verb_certs(const char* msg, STACK_OF(X509)* sk)
347 {
348 	int i, num = sk_X509_num(sk);
349 	if(verb == 0 || verb == 1) return;
350 	for(i=0; i<num; i++) {
351 		printf("%s (%d/%d)\n", msg, i, num);
352 		verb_cert(NULL, sk_X509_value(sk, i));
353 	}
354 }
355 
356 /** read certificates from a PEM bio */
STACK_OF(X509)357 static STACK_OF(X509)*
358 read_cert_bio(BIO* bio)
359 {
360 	STACK_OF(X509) *sk = sk_X509_new_null();
361 	if(!sk) {
362 		if(verb) printf("out of memory\n");
363 		exit(0);
364 	}
365 	while(!BIO_eof(bio)) {
366 		X509* x = PEM_read_bio_X509(bio, NULL, NULL, NULL);
367 		if(x == NULL) {
368 			if(verb) {
369 				printf("failed to read X509\n");
370 			 	ERR_print_errors_fp(stdout);
371 			}
372 			continue;
373 		}
374 		if(!sk_X509_push(sk, x)) {
375 			if(verb) printf("out of memory\n");
376 			exit(0);
377 		}
378 	}
379 	return sk;
380 }
381 
382 /* read the certificate file */
STACK_OF(X509)383 static STACK_OF(X509)*
384 read_cert_file(const char* file)
385 {
386 	STACK_OF(X509)* sk;
387 	FILE* in;
388 	int content = 0;
389 	char buf[128];
390 	if(file == NULL || strcmp(file, "") == 0) {
391 		return NULL;
392 	}
393 	sk = sk_X509_new_null();
394 	if(!sk) {
395 		if(verb) printf("out of memory\n");
396 		exit(0);
397 	}
398 	in = fopen(file, "r");
399 	if(!in) {
400 		if(verb) printf("%s: %s\n", file, strerror(errno));
401 #ifndef S_SPLINT_S
402 		sk_X509_pop_free(sk, X509_free);
403 #endif
404 		return NULL;
405 	}
406 	while(!feof(in)) {
407 		X509* x = PEM_read_X509(in, NULL, NULL, NULL);
408 		if(x == NULL) {
409 			if(verb) {
410 				printf("failed to read X509 file\n");
411 			 	ERR_print_errors_fp(stdout);
412 			}
413 			continue;
414 		}
415 		if(!sk_X509_push(sk, x)) {
416 			if(verb) printf("out of memory\n");
417 			fclose(in);
418 			exit(0);
419 		}
420 		content = 1;
421 		/* read away newline after --END CERT-- */
422 		if(!fgets(buf, (int)sizeof(buf), in))
423 			break;
424 	}
425 	fclose(in);
426 	if(!content) {
427 		if(verb) printf("%s is empty\n", file);
428 #ifndef S_SPLINT_S
429 		sk_X509_pop_free(sk, X509_free);
430 #endif
431 		return NULL;
432 	}
433 	return sk;
434 }
435 
436 /** read certificates from the builtin certificate */
STACK_OF(X509)437 static STACK_OF(X509)*
438 read_builtin_cert(void)
439 {
440 	const char* builtin_cert = get_builtin_cert();
441 	STACK_OF(X509)* sk;
442 	BIO *bio;
443 	char* d = strdup(builtin_cert); /* to avoid const warnings in the
444 		changed prototype of BIO_new_mem_buf */
445 	if(!d) {
446 		if(verb) printf("out of memory\n");
447 		exit(0);
448 	}
449 	bio = BIO_new_mem_buf(d, (int)strlen(d));
450 	if(!bio) {
451 		if(verb) printf("out of memory\n");
452 		exit(0);
453 	}
454 	sk = read_cert_bio(bio);
455 	if(!sk) {
456 		if(verb) printf("internal error, out of memory\n");
457 		exit(0);
458 	}
459 	BIO_free(bio);
460 	free(d);
461 	return sk;
462 }
463 
464 /** read update cert file or use builtin */
STACK_OF(X509)465 static STACK_OF(X509)*
466 read_cert_or_builtin(const char* file)
467 {
468 	STACK_OF(X509) *sk = read_cert_file(file);
469 	if(!sk) {
470 		if(verb) printf("using builtin certificate\n");
471 		sk = read_builtin_cert();
472 	}
473 	if(verb) printf("have %d trusted certificates\n", sk_X509_num(sk));
474 	verb_certs("trusted certificates", sk);
475 	return sk;
476 }
477 
478 static void
do_list_builtin(void)479 do_list_builtin(void)
480 {
481 	const char* builtin_cert = get_builtin_cert();
482 	const char* builtin_ds = get_builtin_ds();
483 	printf("%s\n", builtin_ds);
484 	printf("%s\n", builtin_cert);
485 	exit(0);
486 }
487 
488 /** printout IP address with message */
489 static void
verb_addr(const char * msg,struct ip_list * ip)490 verb_addr(const char* msg, struct ip_list* ip)
491 {
492 	if(verb) {
493 		char out[100];
494 		void* a = &((struct sockaddr_in*)&ip->addr)->sin_addr;
495 		if(ip->len != (socklen_t)sizeof(struct sockaddr_in))
496 			a = &((struct sockaddr_in6*)&ip->addr)->sin6_addr;
497 
498 		if(inet_ntop((int)((struct sockaddr_in*)&ip->addr)->sin_family,
499 			a, out, (socklen_t)sizeof(out))==0)
500 			printf("%s (inet_ntop error)\n", msg);
501 		else printf("%s %s\n", msg, out);
502 	}
503 }
504 
505 /** free ip_list */
506 static void
ip_list_free(struct ip_list * p)507 ip_list_free(struct ip_list* p)
508 {
509 	struct ip_list* np;
510 	while(p) {
511 		np = p->next;
512 		free(p);
513 		p = np;
514 	}
515 }
516 
517 /** create ip_list entry for a RR record */
518 static struct ip_list*
RR_to_ip(int tp,char * data,int len,int port)519 RR_to_ip(int tp, char* data, int len, int port)
520 {
521 	struct ip_list* ip = (struct ip_list*)calloc(1, sizeof(*ip));
522 	uint16_t p = (uint16_t)port;
523 	if(tp == LDNS_RR_TYPE_A) {
524 		struct sockaddr_in* sa = (struct sockaddr_in*)&ip->addr;
525 		ip->len = (socklen_t)sizeof(*sa);
526 		sa->sin_family = AF_INET;
527 		sa->sin_port = (in_port_t)htons(p);
528 		if(len != (int)sizeof(sa->sin_addr)) {
529 			if(verb) printf("skipped badly formatted A\n");
530 			free(ip);
531 			return NULL;
532 		}
533 		memmove(&sa->sin_addr, data, sizeof(sa->sin_addr));
534 
535 	} else if(tp == LDNS_RR_TYPE_AAAA) {
536 		struct sockaddr_in6* sa = (struct sockaddr_in6*)&ip->addr;
537 		ip->len = (socklen_t)sizeof(*sa);
538 		sa->sin6_family = AF_INET6;
539 		sa->sin6_port = (in_port_t)htons(p);
540 		if(len != (int)sizeof(sa->sin6_addr)) {
541 			if(verb) printf("skipped badly formatted AAAA\n");
542 			free(ip);
543 			return NULL;
544 		}
545 		memmove(&sa->sin6_addr, data, sizeof(sa->sin6_addr));
546 	} else {
547 		if(verb) printf("internal error: bad type in RRtoip\n");
548 		free(ip);
549 		return NULL;
550 	}
551 	verb_addr("resolved server address", ip);
552 	return ip;
553 }
554 
555 /** Resolve name, type, class and add addresses to iplist */
556 static void
resolve_host_ip(struct ub_ctx * ctx,const char * host,int port,int tp,int cl,struct ip_list ** head)557 resolve_host_ip(struct ub_ctx* ctx, const char* host, int port, int tp, int cl,
558 	struct ip_list** head)
559 {
560 	struct ub_result* res = NULL;
561 	int r;
562 	int i;
563 
564 	r = ub_resolve(ctx, host, tp, cl, &res);
565 	if(r) {
566 		if(verb) printf("error: resolve %s %s: %s\n", host,
567 			(tp==LDNS_RR_TYPE_A)?"A":"AAAA", ub_strerror(r));
568 		return;
569 	}
570 	if(!res) {
571 		if(verb) printf("out of memory\n");
572 		ub_ctx_delete(ctx);
573 		exit(0);
574 	}
575 	if(!res->havedata || res->rcode || !res->data) {
576 		if(verb) printf("resolve %s %s: no result\n", host,
577 			(tp==LDNS_RR_TYPE_A)?"A":"AAAA");
578 		return;
579 	}
580 	for(i = 0; res->data[i]; i++) {
581 		struct ip_list* ip = RR_to_ip(tp, res->data[i], res->len[i],
582 			port);
583 		if(!ip) continue;
584 		ip->next = *head;
585 		*head = ip;
586 	}
587 	ub_resolve_free(res);
588 }
589 
590 /** parse a text IP address into a sockaddr */
591 static struct ip_list*
parse_ip_addr(const char * str,int port)592 parse_ip_addr(const char* str, int port)
593 {
594 	socklen_t len = 0;
595 	union {
596 		struct sockaddr_in6 a6;
597 		struct sockaddr_in a;
598 	} addr;
599 	struct ip_list* ip;
600 	uint16_t p = (uint16_t)port;
601 	memset(&addr, 0, sizeof(addr));
602 
603 	if(inet_pton(AF_INET6, str, &addr.a6.sin6_addr) > 0) {
604 		/* it is an IPv6 */
605 		addr.a6.sin6_family = AF_INET6;
606 		addr.a6.sin6_port = (in_port_t)htons(p);
607 		len = (socklen_t)sizeof(addr.a6);
608 	}
609 	if(inet_pton(AF_INET, str, &addr.a.sin_addr) > 0) {
610 		/* it is an IPv4 */
611 		addr.a.sin_family = AF_INET;
612 		addr.a.sin_port = (in_port_t)htons(p);
613 		len = (socklen_t)sizeof(struct sockaddr_in);
614 	}
615 	if(!len) return NULL;
616 	ip = (struct ip_list*)calloc(1, sizeof(*ip));
617 	if(!ip) {
618 		if(verb) printf("out of memory\n");
619 		exit(0);
620 	}
621 	ip->len = len;
622 	memmove(&ip->addr, &addr, len);
623 	if(verb) printf("server address is %s\n", str);
624 	return ip;
625 }
626 
627 /**
628  * Resolve a domain name (even though the resolver is down and there is
629  * no trust anchor).  Without DNSSEC validation.
630  * @param host: the name to resolve.
631  * 	If this name is an IP4 or IP6 address this address is returned.
632  * @param port: the port number used for the returned IP structs.
633  * @param res_conf: resolv.conf (if any).
634  * @param root_hints: root hints (if any).
635  * @param debugconf: unbound.conf for debugging options.
636  * @param srcaddr: source address option (if any).
637  * @param ip4only: use only ip4 for resolve and only lookup A
638  * @param ip6only: use only ip6 for resolve and only lookup AAAA
639  * 	default is to lookup A and AAAA using ip4 and ip6.
640  * @return list of IP addresses.
641  */
642 static struct ip_list*
resolve_name(const char * host,int port,const char * res_conf,const char * root_hints,const char * debugconf,const char * srcaddr,int ip4only,int ip6only)643 resolve_name(const char* host, int port, const char* res_conf,
644 	const char* root_hints, const char* debugconf,
645 	const char* srcaddr, int ip4only, int ip6only)
646 {
647 	struct ub_ctx* ctx;
648 	struct ip_list* list = NULL;
649 	/* first see if name is an IP address itself */
650 	if( (list=parse_ip_addr(host, port)) ) {
651 		return list;
652 	}
653 
654 	/* create resolver context */
655 	ctx = create_unbound_context(res_conf, root_hints, debugconf,
656         	srcaddr, ip4only, ip6only);
657 
658 	/* try resolution of A */
659 	if(!ip6only) {
660 		resolve_host_ip(ctx, host, port, LDNS_RR_TYPE_A,
661 			LDNS_RR_CLASS_IN, &list);
662 	}
663 
664 	/* try resolution of AAAA */
665 	if(!ip4only) {
666 		resolve_host_ip(ctx, host, port, LDNS_RR_TYPE_AAAA,
667 			LDNS_RR_CLASS_IN, &list);
668 	}
669 
670 	ub_ctx_delete(ctx);
671 	if(!list) {
672 		if(verb) printf("%s has no IP addresses I can use\n", host);
673 		exit(0);
674 	}
675 	return list;
676 }
677 
678 /** clear used flags */
679 static void
wipe_ip_usage(struct ip_list * p)680 wipe_ip_usage(struct ip_list* p)
681 {
682 	while(p) {
683 		p->used = 0;
684 		p = p->next;
685 	}
686 }
687 
688 /** count unused IPs */
689 static int
count_unused(struct ip_list * p)690 count_unused(struct ip_list* p)
691 {
692 	int num = 0;
693 	while(p) {
694 		if(!p->used) num++;
695 		p = p->next;
696 	}
697 	return num;
698 }
699 
700 /** pick random unused element from IP list */
701 static struct ip_list*
pick_random_ip(struct ip_list * list)702 pick_random_ip(struct ip_list* list)
703 {
704 	struct ip_list* p = list;
705 	int num = count_unused(list);
706 	int sel;
707 	if(num == 0) return NULL;
708 	/* not perfect, but random enough */
709 	sel = (int)arc4random_uniform((uint32_t)num);
710 	/* skip over unused elements that we did not select */
711 	while(sel > 0 && p) {
712 		if(!p->used) sel--;
713 		p = p->next;
714 	}
715 	/* find the next unused element */
716 	while(p && p->used)
717 		p = p->next;
718 	if(!p) return NULL; /* robustness */
719 	return p;
720 }
721 
722 /** close the fd */
723 static void
fd_close(int fd)724 fd_close(int fd)
725 {
726 #ifndef USE_WINSOCK
727 	close(fd);
728 #else
729 	closesocket(fd);
730 #endif
731 }
732 
733 /** printout socket errno */
734 static void
print_sock_err(const char * msg)735 print_sock_err(const char* msg)
736 {
737 #ifndef USE_WINSOCK
738 	if(verb) printf("%s: %s\n", msg, strerror(errno));
739 #else
740 	if(verb) printf("%s: %s\n", msg, wsa_strerror(WSAGetLastError()));
741 #endif
742 }
743 
744 /** connect to IP address */
745 static int
connect_to_ip(struct ip_list * ip,struct ip_list * src)746 connect_to_ip(struct ip_list* ip, struct ip_list* src)
747 {
748 	int fd;
749 	verb_addr("connect to", ip);
750 	fd = socket(ip->len==(socklen_t)sizeof(struct sockaddr_in)?
751 		AF_INET:AF_INET6, SOCK_STREAM, 0);
752 	if(fd == -1) {
753 		print_sock_err("socket");
754 		return -1;
755 	}
756 	if(src && bind(fd, (struct sockaddr*)&src->addr, src->len) < 0) {
757 		print_sock_err("bind");
758 		fd_close(fd);
759 		return -1;
760 	}
761 	if(connect(fd, (struct sockaddr*)&ip->addr, ip->len) < 0) {
762 		print_sock_err("connect");
763 		fd_close(fd);
764 		return -1;
765 	}
766 	return fd;
767 }
768 
769 /** create SSL context */
770 static SSL_CTX*
setup_sslctx(void)771 setup_sslctx(void)
772 {
773 	SSL_CTX* sslctx = SSL_CTX_new(SSLv23_client_method());
774 	if(!sslctx) {
775 		if(verb) printf("SSL_CTX_new error\n");
776 		return NULL;
777 	}
778 	return sslctx;
779 }
780 
781 /** initiate TLS on a connection */
782 static SSL*
TLS_initiate(SSL_CTX * sslctx,int fd,const char * urlname,int use_sni)783 TLS_initiate(SSL_CTX* sslctx, int fd, const char* urlname, int use_sni)
784 {
785 	X509* x;
786 	int r;
787 	SSL* ssl = SSL_new(sslctx);
788 	if(!ssl) {
789 		if(verb) printf("SSL_new error\n");
790 		return NULL;
791 	}
792 	SSL_set_connect_state(ssl);
793 	(void)SSL_set_mode(ssl, (long)SSL_MODE_AUTO_RETRY);
794 	if(!SSL_set_fd(ssl, fd)) {
795 		if(verb) printf("SSL_set_fd error\n");
796 		SSL_free(ssl);
797 		return NULL;
798 	}
799 	if(use_sni) {
800 		(void)SSL_set_tlsext_host_name(ssl, urlname);
801 	}
802 	while(1) {
803 		ERR_clear_error();
804 		if( (r=SSL_do_handshake(ssl)) == 1)
805 			break;
806 		r = SSL_get_error(ssl, r);
807 		if(r != SSL_ERROR_WANT_READ && r != SSL_ERROR_WANT_WRITE) {
808 			if(verb) printf("SSL handshake failed\n");
809 			SSL_free(ssl);
810 			return NULL;
811 		}
812 		/* wants to be called again */
813 	}
814 #ifdef HAVE_SSL_GET1_PEER_CERTIFICATE
815 	x = SSL_get1_peer_certificate(ssl);
816 #else
817 	x = SSL_get_peer_certificate(ssl);
818 #endif
819 	if(!x) {
820 		if(verb) printf("Server presented no peer certificate\n");
821 		SSL_free(ssl);
822 		return NULL;
823 	}
824 	verb_cert("server SSL certificate", x);
825 	X509_free(x);
826 	return ssl;
827 }
828 
829 /** perform neat TLS shutdown */
830 static void
TLS_shutdown(int fd,SSL * ssl,SSL_CTX * sslctx)831 TLS_shutdown(int fd, SSL* ssl, SSL_CTX* sslctx)
832 {
833 	/* shutdown the SSL connection nicely */
834 	if(SSL_shutdown(ssl) == 0) {
835 		SSL_shutdown(ssl);
836 	}
837 	SSL_free(ssl);
838 	SSL_CTX_free(sslctx);
839 	fd_close(fd);
840 }
841 
842 /** write a line over SSL */
843 static int
write_ssl_line(SSL * ssl,const char * str,const char * sec)844 write_ssl_line(SSL* ssl, const char* str, const char* sec)
845 {
846 	char buf[1024];
847 	size_t l;
848 	if(sec) {
849 		snprintf(buf, sizeof(buf), str, sec);
850 	} else {
851 		snprintf(buf, sizeof(buf), "%s", str);
852 	}
853 	l = strlen(buf);
854 	if(l+2 >= sizeof(buf)) {
855 		if(verb) printf("line too long\n");
856 		return 0;
857 	}
858 	if(verb >= 2) printf("SSL_write: %s\n", buf);
859 	buf[l] = '\r';
860 	buf[l+1] = '\n';
861 	buf[l+2] = 0;
862 	/* add \r\n */
863 	if(SSL_write(ssl, buf, (int)strlen(buf)) <= 0) {
864 		if(verb) printf("could not SSL_write %s", str);
865 		return 0;
866 	}
867 	return 1;
868 }
869 
870 /** process header line, check rcode and keeping track of size */
871 static int
process_one_header(char * buf,size_t * clen,int * chunked)872 process_one_header(char* buf, size_t* clen, int* chunked)
873 {
874 	if(verb>=2) printf("header: '%s'\n", buf);
875 	if(strncasecmp(buf, "HTTP/1.1 ", 9) == 0) {
876 		/* check returncode */
877 		if(buf[9] != '2') {
878 			if(verb) printf("bad status %s\n", buf+9);
879 			return 0;
880 		}
881 	} else if(strncasecmp(buf, "Content-Length: ", 16) == 0) {
882 		if(!*chunked)
883 			*clen = (size_t)atoi(buf+16);
884 	} else if(strncasecmp(buf, "Transfer-Encoding: chunked", 19+7) == 0) {
885 		*clen = 0;
886 		*chunked = 1;
887 	}
888 	return 1;
889 }
890 
891 /**
892  * Read one line from SSL
893  * zero terminates.
894  * skips "\r\n" (but not copied to buf).
895  * @param ssl: the SSL connection to read from (blocking).
896  * @param buf: buffer to return line in.
897  * @param len: size of the buffer.
898  * @return 0 on error, 1 on success.
899  */
900 static int
read_ssl_line(SSL * ssl,char * buf,size_t len)901 read_ssl_line(SSL* ssl, char* buf, size_t len)
902 {
903 	size_t n = 0;
904 	int r;
905 	int endnl = 0;
906 	while(1) {
907 		if(n >= len) {
908 			if(verb) printf("line too long\n");
909 			return 0;
910 		}
911 		if((r = SSL_read(ssl, buf+n, 1)) <= 0) {
912 			if(SSL_get_error(ssl, r) == SSL_ERROR_ZERO_RETURN) {
913 				/* EOF */
914 				break;
915 			}
916 			if(verb) printf("could not SSL_read\n");
917 			return 0;
918 		}
919 		if(endnl && buf[n] == '\n') {
920 			break;
921 		} else if(endnl) {
922 			/* bad data */
923 			if(verb) printf("error: stray linefeeds\n");
924 			return 0;
925 		} else if(buf[n] == '\r') {
926 			/* skip \r, and also \n on the wire */
927 			endnl = 1;
928 			continue;
929 		} else if(buf[n] == '\n') {
930 			/* skip the \n, we are done */
931 			break;
932 		} else n++;
933 	}
934 	buf[n] = 0;
935 	return 1;
936 }
937 
938 /** read http headers and process them */
939 static size_t
read_http_headers(SSL * ssl,size_t * clen)940 read_http_headers(SSL* ssl, size_t* clen)
941 {
942 	char buf[1024];
943 	int chunked = 0;
944 	*clen = 0;
945 	while(read_ssl_line(ssl, buf, sizeof(buf))) {
946 		if(buf[0] == 0)
947 			return 1;
948 		if(!process_one_header(buf, clen, &chunked))
949 			return 0;
950 	}
951 	return 0;
952 }
953 
954 /** read a data chunk */
955 static char*
read_data_chunk(SSL * ssl,size_t len)956 read_data_chunk(SSL* ssl, size_t len)
957 {
958 	size_t got = 0;
959 	int r;
960 	char* data;
961 	if((unsigned)len >= (unsigned)0xfffffff0)
962 		return NULL; /* to protect against integer overflow in malloc*/
963 	data = malloc(len+1);
964 	if(!data) {
965 		if(verb) printf("out of memory\n");
966 		return NULL;
967 	}
968 	while(got < len) {
969 		if((r = SSL_read(ssl, data+got, (int)(len-got))) <= 0) {
970 			if(SSL_get_error(ssl, r) == SSL_ERROR_ZERO_RETURN) {
971 				/* EOF */
972 				if(verb) printf("could not SSL_read: unexpected EOF\n");
973 				free(data);
974 				return NULL;
975 			}
976 			if(verb) printf("could not SSL_read\n");
977 			free(data);
978 			return NULL;
979 		}
980 		if(verb >= 2) printf("at %d/%d\n", (int)got, (int)len);
981 		got += r;
982 	}
983 	if(verb>=2) printf("read %d data\n", (int)len);
984 	data[len] = 0;
985 	return data;
986 }
987 
988 /** parse chunk header */
989 static int
parse_chunk_header(char * buf,size_t * result)990 parse_chunk_header(char* buf, size_t* result)
991 {
992 	char* e = NULL;
993 	size_t v = (size_t)strtol(buf, &e, 16);
994 	if(e == buf)
995 		return 0;
996 	*result = v;
997 	return 1;
998 }
999 
1000 /** read chunked data from connection */
1001 static BIO*
do_chunked_read(SSL * ssl)1002 do_chunked_read(SSL* ssl)
1003 {
1004 	char buf[1024];
1005 	size_t len;
1006 	char* body;
1007 	BIO* mem = BIO_new(BIO_s_mem());
1008 	if(verb>=3) printf("do_chunked_read\n");
1009 	if(!mem) {
1010 		if(verb) printf("out of memory\n");
1011 		return NULL;
1012 	}
1013 	while(read_ssl_line(ssl, buf, sizeof(buf))) {
1014 		/* read the chunked start line */
1015 		if(verb>=2) printf("chunk header: %s\n", buf);
1016 		if(!parse_chunk_header(buf, &len)) {
1017 			BIO_free(mem);
1018 			if(verb>=3) printf("could not parse chunk header\n");
1019 			return NULL;
1020 		}
1021 		if(verb>=2) printf("chunk len: %d\n", (int)len);
1022 		/* are we done? */
1023 		if(len == 0) {
1024 			char z = 0;
1025 			/* skip end-of-chunk-trailer lines,
1026 			 * until the empty line after that */
1027 			do {
1028 				if(!read_ssl_line(ssl, buf, sizeof(buf))) {
1029 					BIO_free(mem);
1030 					return NULL;
1031 				}
1032 			} while (strlen(buf) > 0);
1033 			/* end of chunks, zero terminate it */
1034 			if(BIO_write(mem, &z, 1) <= 0) {
1035 				if(verb) printf("out of memory\n");
1036 				BIO_free(mem);
1037 				return NULL;
1038 			}
1039 			return mem;
1040 		}
1041 		/* read the chunked body */
1042 		body = read_data_chunk(ssl, len);
1043 		if(!body) {
1044 			BIO_free(mem);
1045 			return NULL;
1046 		}
1047 		if(BIO_write(mem, body, (int)len) <= 0) {
1048 			if(verb) printf("out of memory\n");
1049 			free(body);
1050 			BIO_free(mem);
1051 			return NULL;
1052 		}
1053 		free(body);
1054 		/* skip empty line after data chunk */
1055 		if(!read_ssl_line(ssl, buf, sizeof(buf))) {
1056 			BIO_free(mem);
1057 			return NULL;
1058 		}
1059 	}
1060 	BIO_free(mem);
1061 	return NULL;
1062 }
1063 
1064 /** start HTTP1.1 transaction on SSL */
1065 static int
write_http_get(SSL * ssl,const char * pathname,const char * urlname)1066 write_http_get(SSL* ssl, const char* pathname, const char* urlname)
1067 {
1068 	if(write_ssl_line(ssl, "GET /%s HTTP/1.1", pathname) &&
1069 	   write_ssl_line(ssl, "Host: %s", urlname) &&
1070 	   write_ssl_line(ssl, "User-Agent: unbound-anchor/%s",
1071 	   	PACKAGE_VERSION) &&
1072 	   /* We do not really do multiple queries per connection,
1073 	    * but this header setting is also not needed.
1074 	    * write_ssl_line(ssl, "Connection: close", NULL) &&*/
1075 	   write_ssl_line(ssl, "", NULL)) {
1076 		return 1;
1077 	}
1078 	return 0;
1079 }
1080 
1081 /** read chunked data and zero terminate; len is without zero */
1082 static char*
read_chunked_zero_terminate(SSL * ssl,size_t * len)1083 read_chunked_zero_terminate(SSL* ssl, size_t* len)
1084 {
1085 	/* do the chunked version */
1086 	BIO* tmp = do_chunked_read(ssl);
1087 	char* data, *d = NULL;
1088 	size_t l;
1089 	if(!tmp) {
1090 		if(verb) printf("could not read from https\n");
1091 		return NULL;
1092 	}
1093 	l = (size_t)BIO_get_mem_data(tmp, &d);
1094 	if(verb>=2) printf("chunked data is %d\n", (int)l);
1095 	if(l == 0 || d == NULL) {
1096 		if(verb) printf("out of memory\n");
1097 		return NULL;
1098 	}
1099 	*len = l-1;
1100 	data = (char*)malloc(l);
1101 	if(data == NULL) {
1102 		if(verb) printf("out of memory\n");
1103 		return NULL;
1104 	}
1105 	memcpy(data, d, l);
1106 	BIO_free(tmp);
1107 	return data;
1108 }
1109 
1110 /** read HTTP result from SSL */
1111 static BIO*
read_http_result(SSL * ssl)1112 read_http_result(SSL* ssl)
1113 {
1114 	size_t len = 0;
1115 	char* data;
1116 	BIO* m;
1117 	if(!read_http_headers(ssl, &len)) {
1118 		return NULL;
1119 	}
1120 	if(len == 0) {
1121 		data = read_chunked_zero_terminate(ssl, &len);
1122 	} else {
1123 		data = read_data_chunk(ssl, len);
1124 	}
1125 	if(!data) return NULL;
1126 	if(verb >= 4) print_data("read data", data, len);
1127 	m = BIO_new(BIO_s_mem());
1128 	if(!m) {
1129 		if(verb) printf("out of memory\n");
1130 		free(data);
1131 		exit(0);
1132 	}
1133 	BIO_write(m, data, (int)len);
1134 	free(data);
1135 	return m;
1136 }
1137 
1138 /** https to an IP addr, return BIO with pathname or NULL */
1139 static BIO*
https_to_ip(struct ip_list * ip,const char * pathname,const char * urlname,struct ip_list * src,int use_sni)1140 https_to_ip(struct ip_list* ip, const char* pathname, const char* urlname,
1141 	struct ip_list* src, int use_sni)
1142 {
1143 	int fd;
1144 	SSL* ssl;
1145 	BIO* bio;
1146 	SSL_CTX* sslctx = setup_sslctx();
1147 	if(!sslctx) {
1148 		return NULL;
1149 	}
1150 	fd = connect_to_ip(ip, src);
1151 	if(fd == -1) {
1152 		SSL_CTX_free(sslctx);
1153 		return NULL;
1154 	}
1155 	ssl = TLS_initiate(sslctx, fd, urlname, use_sni);
1156 	if(!ssl) {
1157 		SSL_CTX_free(sslctx);
1158 		fd_close(fd);
1159 		return NULL;
1160 	}
1161 	if(!write_http_get(ssl, pathname, urlname)) {
1162 		if(verb) printf("could not write to server\n");
1163 		SSL_free(ssl);
1164 		SSL_CTX_free(sslctx);
1165 		fd_close(fd);
1166 		return NULL;
1167 	}
1168 	bio = read_http_result(ssl);
1169 	TLS_shutdown(fd, ssl, sslctx);
1170 	return bio;
1171 }
1172 
1173 /**
1174  * Do a HTTPS, HTTP1.1 over TLS, to fetch a file
1175  * @param ip_list: list of IP addresses to use to fetch from.
1176  * @param pathname: pathname of file on server to GET.
1177  * @param urlname: name to pass as the virtual host for this request.
1178  * @param src: if nonNULL, source address to bind to.
1179  * @param use_sni: if SNI will be used.
1180  * @return a memory BIO with the file in it.
1181  */
1182 static BIO*
https(struct ip_list * ip_list,const char * pathname,const char * urlname,struct ip_list * src,int use_sni)1183 https(struct ip_list* ip_list, const char* pathname, const char* urlname,
1184 	struct ip_list* src, int use_sni)
1185 {
1186 	struct ip_list* ip;
1187 	BIO* bio = NULL;
1188 	/* try random address first, and work through the list */
1189 	wipe_ip_usage(ip_list);
1190 	while( (ip = pick_random_ip(ip_list)) ) {
1191 		ip->used = 1;
1192 		bio = https_to_ip(ip, pathname, urlname, src, use_sni);
1193 		if(bio) break;
1194 	}
1195 	if(!bio) {
1196 		if(verb) printf("could not fetch %s\n", pathname);
1197 		exit(0);
1198 	} else {
1199 		if(verb) printf("fetched %s (%d bytes)\n",
1200 			pathname, (int)BIO_ctrl_pending(bio));
1201 	}
1202 	return bio;
1203 }
1204 
1205 /** XML parse private data during the parse */
1206 struct xml_data {
1207 	/** the parser, reference */
1208 	XML_Parser parser;
1209 	/** the current tag; malloced; or NULL outside of tags */
1210 	char* tag;
1211 	/** current date to use during the parse */
1212 	time_t date;
1213 	/** number of keys usefully read in */
1214 	int num_keys;
1215 	/** the compiled anchors as DS records */
1216 	BIO* ds;
1217 
1218 	/** do we want to use this anchor? */
1219 	int use_key;
1220 	/** the current anchor: Zone */
1221 	BIO* czone;
1222 	/** the current anchor: KeyTag */
1223 	BIO* ctag;
1224 	/** the current anchor: Algorithm */
1225 	BIO* calgo;
1226 	/** the current anchor: DigestType */
1227 	BIO* cdigtype;
1228 	/** the current anchor: Digest*/
1229 	BIO* cdigest;
1230 };
1231 
1232 /** The BIO for the tag */
1233 static BIO*
xml_selectbio(struct xml_data * data,const char * tag)1234 xml_selectbio(struct xml_data* data, const char* tag)
1235 {
1236 	BIO* b = NULL;
1237 	if(strcasecmp(tag, "KeyTag") == 0)
1238 		b = data->ctag;
1239 	else if(strcasecmp(tag, "Algorithm") == 0)
1240 		b = data->calgo;
1241 	else if(strcasecmp(tag, "DigestType") == 0)
1242 		b = data->cdigtype;
1243 	else if(strcasecmp(tag, "Digest") == 0)
1244 		b = data->cdigest;
1245 	return b;
1246 }
1247 
1248 /**
1249  * XML handle character data, the data inside an element.
1250  * @param userData: xml_data structure
1251  * @param s: the character data.  May not all be in one callback.
1252  * 	NOT zero terminated.
1253  * @param len: length of this part of the data.
1254  */
1255 static void
xml_charhandle(void * userData,const XML_Char * s,int len)1256 xml_charhandle(void *userData, const XML_Char *s, int len)
1257 {
1258 	struct xml_data* data = (struct xml_data*)userData;
1259 	BIO* b = NULL;
1260 	/* skip characters outside of elements */
1261 	if(!data->tag)
1262 		return;
1263 	if(verb>=4) {
1264 		int i;
1265 		printf("%s%s charhandle: '",
1266 			data->use_key?"use ":"",
1267 			data->tag?data->tag:"none");
1268 		for(i=0; i<len; i++)
1269 			printf("%c", s[i]);
1270 		printf("'\n");
1271 	}
1272 	if(strcasecmp(data->tag, "Zone") == 0) {
1273 		if(BIO_write(data->czone, s, len) < 0) {
1274 			if(verb) printf("out of memory in BIO_write\n");
1275 			exit(0);
1276 		}
1277 		return;
1278 	}
1279 	/* only store if key is used */
1280 	if(!data->use_key)
1281 		return;
1282 	b = xml_selectbio(data, data->tag);
1283 	if(b) {
1284 		if(BIO_write(b, s, len) < 0) {
1285 			if(verb) printf("out of memory in BIO_write\n");
1286 			exit(0);
1287 		}
1288 	}
1289 }
1290 
1291 /**
1292  * XML fetch value of particular attribute(by name) or NULL if not present.
1293  * @param atts: attribute array (from xml_startelem).
1294  * @param name: name of attribute to look for.
1295  * @return the value or NULL. (ptr into atts).
1296  */
1297 static const XML_Char*
find_att(const XML_Char ** atts,const XML_Char * name)1298 find_att(const XML_Char **atts, const XML_Char* name)
1299 {
1300 	int i;
1301 	for(i=0; atts[i]; i+=2) {
1302 		if(strcasecmp(atts[i], name) == 0)
1303 			return atts[i+1];
1304 	}
1305 	return NULL;
1306 }
1307 
1308 /**
1309  * XML convert DateTime element to time_t.
1310  * [-]CCYY-MM-DDThh:mm:ss[Z|(+|-)hh:mm]
1311  * (with optional .ssssss fractional seconds)
1312  * @param str: the string
1313  * @return a time_t representation or 0 on failure.
1314  */
1315 static time_t
xml_convertdate(const char * str)1316 xml_convertdate(const char* str)
1317 {
1318 	time_t t = 0;
1319 	struct tm tm;
1320 	const char* s;
1321 	/* for this application, ignore minus in front;
1322 	 * only positive dates are expected */
1323 	s = str;
1324 	if(s[0] == '-') s++;
1325 	memset(&tm, 0, sizeof(tm));
1326 	/* parse initial content of the string (lots of whitespace allowed) */
1327 	s = strptime(s, "%t%Y%t-%t%m%t-%t%d%tT%t%H%t:%t%M%t:%t%S%t", &tm);
1328 	if(!s) {
1329 		if(verb) printf("xml_convertdate parse failure %s\n", str);
1330 		return 0;
1331 	}
1332 	/* parse remainder of date string */
1333 	if(*s == '.') {
1334 		/* optional '.' and fractional seconds */
1335 		int frac = 0, n = 0;
1336 		if(sscanf(s+1, "%d%n", &frac, &n) < 1) {
1337 			if(verb) printf("xml_convertdate f failure %s\n", str);
1338 			return 0;
1339 		}
1340 		/* fraction is not used, time_t has second accuracy */
1341 		s++;
1342 		s+=n;
1343 	}
1344 	if(*s == 'Z' || *s == 'z') {
1345 		/* nothing to do for this */
1346 		s++;
1347 	} else if(*s == '+' || *s == '-') {
1348 		/* optional timezone spec: Z or +hh:mm or -hh:mm */
1349 		int hr = 0, mn = 0, n = 0;
1350 		if(sscanf(s+1, "%d:%d%n", &hr, &mn, &n) < 2) {
1351 			if(verb) printf("xml_convertdate tz failure %s\n", str);
1352 			return 0;
1353 		}
1354 		if(*s == '+') {
1355 			tm.tm_hour += hr;
1356 			tm.tm_min += mn;
1357 		} else {
1358 			tm.tm_hour -= hr;
1359 			tm.tm_min -= mn;
1360 		}
1361 		s++;
1362 		s += n;
1363 	}
1364 	if(*s != 0) {
1365 		/* not ended properly */
1366 		/* but ignore, (lenient) */
1367 	}
1368 
1369 	t = sldns_mktime_from_utc(&tm);
1370 	if(t == (time_t)-1) {
1371 		if(verb) printf("xml_convertdate mktime failure\n");
1372 		return 0;
1373 	}
1374 	return t;
1375 }
1376 
1377 /**
1378  * XML handle the KeyDigest start tag, check validity periods.
1379  */
1380 static void
handle_keydigest(struct xml_data * data,const XML_Char ** atts)1381 handle_keydigest(struct xml_data* data, const XML_Char **atts)
1382 {
1383 	data->use_key = 0;
1384 	if(find_att(atts, "validFrom")) {
1385 		time_t from = xml_convertdate(find_att(atts, "validFrom"));
1386 		if(from == 0) {
1387 			if(verb) printf("error: xml cannot be parsed\n");
1388 			exit(0);
1389 		}
1390 		if(data->date < from)
1391 			return;
1392 	}
1393 	if(find_att(atts, "validUntil")) {
1394 		time_t until = xml_convertdate(find_att(atts, "validUntil"));
1395 		if(until == 0) {
1396 			if(verb) printf("error: xml cannot be parsed\n");
1397 			exit(0);
1398 		}
1399 		if(data->date > until)
1400 			return;
1401 	}
1402 	/* yes we want to use this key */
1403 	data->use_key = 1;
1404 	(void)BIO_reset(data->ctag);
1405 	(void)BIO_reset(data->calgo);
1406 	(void)BIO_reset(data->cdigtype);
1407 	(void)BIO_reset(data->cdigest);
1408 }
1409 
1410 /** See if XML element equals the zone name */
1411 static int
xml_is_zone_name(BIO * zone,const char * name)1412 xml_is_zone_name(BIO* zone, const char* name)
1413 {
1414 	char buf[1024];
1415 	char* z = NULL;
1416 	long zlen;
1417 	(void)BIO_seek(zone, 0);
1418 	zlen = BIO_get_mem_data(zone, &z);
1419 	if(!zlen || !z) return 0;
1420 	/* zero terminate */
1421 	if(zlen >= (long)sizeof(buf)) return 0;
1422 	memmove(buf, z, (size_t)zlen);
1423 	buf[zlen] = 0;
1424 	/* compare */
1425 	return (strncasecmp(buf, name, strlen(name)) == 0);
1426 }
1427 
1428 /**
1429  * XML start of element. This callback is called whenever an XML tag starts.
1430  * XML_Char is UTF8.
1431  * @param userData: the xml_data structure.
1432  * @param name: the tag that starts.
1433  * @param atts: array of strings, pairs of attr = value, ends with NULL.
1434  * 	i.e. att[0]="att[1]" att[2]="att[3]" att[4]isNull
1435  */
1436 static void
xml_startelem(void * userData,const XML_Char * name,const XML_Char ** atts)1437 xml_startelem(void *userData, const XML_Char *name, const XML_Char **atts)
1438 {
1439 	struct xml_data* data = (struct xml_data*)userData;
1440 	BIO* b;
1441 	if(verb>=4) printf("xml tag start '%s'\n", name);
1442 	free(data->tag);
1443 	data->tag = strdup(name);
1444 	if(!data->tag) {
1445 		if(verb) printf("out of memory\n");
1446 		exit(0);
1447 	}
1448 	if(verb>=4) {
1449 		int i;
1450 		for(i=0; atts[i]; i+=2) {
1451 			printf("  %s='%s'\n", atts[i], atts[i+1]);
1452 		}
1453 	}
1454 	/* handle attributes to particular types */
1455 	if(strcasecmp(name, "KeyDigest") == 0) {
1456 		handle_keydigest(data, atts);
1457 		return;
1458 	} else if(strcasecmp(name, "Zone") == 0) {
1459 		(void)BIO_reset(data->czone);
1460 		return;
1461 	}
1462 
1463 	/* for other types we prepare to pick up the data */
1464 	if(!data->use_key)
1465 		return;
1466 	b = xml_selectbio(data, data->tag);
1467 	if(b) {
1468 		/* empty it */
1469 		(void)BIO_reset(b);
1470 	}
1471 }
1472 
1473 /** Append str to bio */
1474 static void
xml_append_str(BIO * b,const char * s)1475 xml_append_str(BIO* b, const char* s)
1476 {
1477 	if(BIO_write(b, s, (int)strlen(s)) < 0) {
1478 		if(verb) printf("out of memory in BIO_write\n");
1479 		exit(0);
1480 	}
1481 }
1482 
1483 /** Append bio to bio */
1484 static void
xml_append_bio(BIO * b,BIO * a)1485 xml_append_bio(BIO* b, BIO* a)
1486 {
1487 	char* z = NULL;
1488 	long i, len;
1489 	(void)BIO_seek(a, 0);
1490 	len = BIO_get_mem_data(a, &z);
1491 	if(!len || !z) {
1492 		if(verb) printf("out of memory in BIO_write\n");
1493 		exit(0);
1494 	}
1495 	/* remove newlines in the data here */
1496 	for(i=0; i<len; i++) {
1497 		if(z[i] == '\r' || z[i] == '\n')
1498 			z[i] = ' ';
1499 	}
1500 	/* write to BIO */
1501 	if(BIO_write(b, z, len) < 0) {
1502 		if(verb) printf("out of memory in BIO_write\n");
1503 		exit(0);
1504 	}
1505 }
1506 
1507 /** write the parsed xml-DS to the DS list */
1508 static void
xml_append_ds(struct xml_data * data)1509 xml_append_ds(struct xml_data* data)
1510 {
1511 	/* write DS to accumulated DS */
1512 	xml_append_str(data->ds, ". IN DS ");
1513 	xml_append_bio(data->ds, data->ctag);
1514 	xml_append_str(data->ds, " ");
1515 	xml_append_bio(data->ds, data->calgo);
1516 	xml_append_str(data->ds, " ");
1517 	xml_append_bio(data->ds, data->cdigtype);
1518 	xml_append_str(data->ds, " ");
1519 	xml_append_bio(data->ds, data->cdigest);
1520 	xml_append_str(data->ds, "\n");
1521 	data->num_keys++;
1522 }
1523 
1524 /**
1525  * XML end of element. This callback is called whenever an XML tag ends.
1526  * XML_Char is UTF8.
1527  * @param userData: the xml_data structure
1528  * @param name: the tag that ends.
1529  */
1530 static void
xml_endelem(void * userData,const XML_Char * name)1531 xml_endelem(void *userData, const XML_Char *name)
1532 {
1533 	struct xml_data* data = (struct xml_data*)userData;
1534 	if(verb>=4) printf("xml tag end   '%s'\n", name);
1535 	free(data->tag);
1536 	data->tag = NULL;
1537 	if(strcasecmp(name, "KeyDigest") == 0) {
1538 		if(data->use_key)
1539 			xml_append_ds(data);
1540 		data->use_key = 0;
1541 	} else if(strcasecmp(name, "Zone") == 0) {
1542 		if(!xml_is_zone_name(data->czone, ".")) {
1543 			if(verb) printf("xml not for the right zone\n");
1544 			exit(0);
1545 		}
1546 	}
1547 }
1548 
1549 /* Stop the parser when an entity declaration is encountered. For safety. */
1550 static void
xml_entitydeclhandler(void * userData,const XML_Char * ATTR_UNUSED (entityName),int ATTR_UNUSED (is_parameter_entity),const XML_Char * ATTR_UNUSED (value),int ATTR_UNUSED (value_length),const XML_Char * ATTR_UNUSED (base),const XML_Char * ATTR_UNUSED (systemId),const XML_Char * ATTR_UNUSED (publicId),const XML_Char * ATTR_UNUSED (notationName))1551 xml_entitydeclhandler(void *userData,
1552 	const XML_Char *ATTR_UNUSED(entityName),
1553 	int ATTR_UNUSED(is_parameter_entity),
1554 	const XML_Char *ATTR_UNUSED(value), int ATTR_UNUSED(value_length),
1555 	const XML_Char *ATTR_UNUSED(base),
1556 	const XML_Char *ATTR_UNUSED(systemId),
1557 	const XML_Char *ATTR_UNUSED(publicId),
1558 	const XML_Char *ATTR_UNUSED(notationName))
1559 {
1560 #if HAVE_DECL_XML_STOPPARSER
1561 	(void)XML_StopParser((XML_Parser)userData, XML_FALSE);
1562 #else
1563 	(void)userData;
1564 #endif
1565 }
1566 
1567 /**
1568  * XML parser setup of the callbacks for the tags
1569  */
1570 static void
xml_parse_setup(XML_Parser parser,struct xml_data * data,time_t now)1571 xml_parse_setup(XML_Parser parser, struct xml_data* data, time_t now)
1572 {
1573 	char buf[1024];
1574 	memset(data, 0, sizeof(*data));
1575 	XML_SetUserData(parser, data);
1576 	data->parser = parser;
1577 	data->date = now;
1578 	data->ds = BIO_new(BIO_s_mem());
1579 	data->ctag = BIO_new(BIO_s_mem());
1580 	data->czone = BIO_new(BIO_s_mem());
1581 	data->calgo = BIO_new(BIO_s_mem());
1582 	data->cdigtype = BIO_new(BIO_s_mem());
1583 	data->cdigest = BIO_new(BIO_s_mem());
1584 	if(!data->ds || !data->ctag || !data->calgo || !data->czone ||
1585 		!data->cdigtype || !data->cdigest) {
1586 		if(verb) printf("out of memory\n");
1587 		exit(0);
1588 	}
1589 	snprintf(buf, sizeof(buf), "; created by unbound-anchor on %s",
1590 		ctime(&now));
1591 	if(BIO_write(data->ds, buf, (int)strlen(buf)) < 0) {
1592 		if(verb) printf("out of memory\n");
1593 		exit(0);
1594 	}
1595 	XML_SetEntityDeclHandler(parser, xml_entitydeclhandler);
1596 	XML_SetElementHandler(parser, xml_startelem, xml_endelem);
1597 	XML_SetCharacterDataHandler(parser, xml_charhandle);
1598 }
1599 
1600 /**
1601  * Perform XML parsing of the root-anchors file
1602  * Its format description can be found in RFC 7958.
1603  * It uses libexpat.
1604  * @param xml: BIO with xml data.
1605  * @param now: the current time for checking DS validity periods.
1606  * @return memoryBIO with the DS data in zone format.
1607  * 	or NULL if the zone is insecure.
1608  * 	(It exit()s on error)
1609  */
1610 static BIO*
xml_parse(BIO * xml,time_t now)1611 xml_parse(BIO* xml, time_t now)
1612 {
1613 	char* pp;
1614 	int len;
1615 	XML_Parser parser;
1616 	struct xml_data data;
1617 
1618 	parser = XML_ParserCreate(NULL);
1619 	if(!parser) {
1620 		if(verb) printf("could not XML_ParserCreate\n");
1621 		exit(0);
1622 	}
1623 
1624 	/* setup callbacks */
1625 	xml_parse_setup(parser, &data, now);
1626 
1627 	/* parse it */
1628 	(void)BIO_seek(xml, 0);
1629 	len = (int)BIO_get_mem_data(xml, &pp);
1630 	if(!len || !pp) {
1631 		if(verb) printf("out of memory\n");
1632 		exit(0);
1633 	}
1634 	if(!XML_Parse(parser, pp, len, 1 /*isfinal*/ )) {
1635 		const char *e = XML_ErrorString(XML_GetErrorCode(parser));
1636 		if(verb) printf("XML_Parse failure %s\n", e?e:"");
1637 		exit(0);
1638 	}
1639 
1640 	/* parsed */
1641 	if(verb) printf("XML was parsed successfully, %d keys\n",
1642 			data.num_keys);
1643 	free(data.tag);
1644 	XML_ParserFree(parser);
1645 
1646 	if(verb >= 4) {
1647 		(void)BIO_seek(data.ds, 0);
1648 		len = BIO_get_mem_data(data.ds, &pp);
1649 		printf("got DS bio %d: '", len);
1650 		if(!fwrite(pp, (size_t)len, 1, stdout))
1651 			/* compilers do not allow us to ignore fwrite .. */
1652 			fprintf(stderr, "error writing to stdout\n");
1653 		printf("'\n");
1654 	}
1655 	BIO_free(data.czone);
1656 	BIO_free(data.ctag);
1657 	BIO_free(data.calgo);
1658 	BIO_free(data.cdigtype);
1659 	BIO_free(data.cdigest);
1660 
1661 	if(data.num_keys == 0) {
1662 		/* the root zone seems to have gone insecure */
1663 		BIO_free(data.ds);
1664 		return NULL;
1665 	} else {
1666 		return data.ds;
1667 	}
1668 }
1669 
1670 /* get key usage out of its extension, returns 0 if no key_usage extension */
1671 static unsigned long
get_usage_of_ex(X509 * cert)1672 get_usage_of_ex(X509* cert)
1673 {
1674 	unsigned long val = 0;
1675 	ASN1_BIT_STRING* s;
1676 	if((s=X509_get_ext_d2i(cert, NID_key_usage, NULL, NULL))) {
1677 		if(s->length > 0) {
1678 			val = s->data[0];
1679 			if(s->length > 1)
1680 				val |= s->data[1] << 8;
1681 		}
1682 		ASN1_BIT_STRING_free(s);
1683 	}
1684 	return val;
1685 }
1686 
1687 /** get valid signers from the list of signers in the signature */
STACK_OF(X509)1688 static STACK_OF(X509)*
1689 get_valid_signers(PKCS7* p7, const char* p7signer)
1690 {
1691 	int i;
1692 	STACK_OF(X509)* validsigners = sk_X509_new_null();
1693 	STACK_OF(X509)* signers = PKCS7_get0_signers(p7, NULL, 0);
1694 	unsigned long usage = 0;
1695 	if(!validsigners) {
1696 		if(verb) printf("out of memory\n");
1697 		sk_X509_free(signers);
1698 		return NULL;
1699 	}
1700 	if(!signers) {
1701 		if(verb) printf("no signers in pkcs7 signature\n");
1702 		sk_X509_free(validsigners);
1703 		return NULL;
1704 	}
1705 	for(i=0; i<sk_X509_num(signers); i++) {
1706 		X509_NAME* nm = X509_get_subject_name(
1707 			sk_X509_value(signers, i));
1708 		char buf[1024];
1709 		if(!nm) {
1710 			if(verb) printf("signer %d: cert has no subject name\n", i);
1711 			continue;
1712 		}
1713 		if(verb && nm) {
1714 			char* nmline = X509_NAME_oneline(nm, buf,
1715 				(int)sizeof(buf));
1716 			printf("signer %d: Subject: %s\n", i,
1717 				nmline?nmline:"no subject");
1718 			if(verb >= 3 && X509_NAME_get_text_by_NID(nm,
1719 				NID_commonName, buf, (int)sizeof(buf)))
1720 				printf("commonName: %s\n", buf);
1721 			if(verb >= 3 && X509_NAME_get_text_by_NID(nm,
1722 				NID_pkcs9_emailAddress, buf, (int)sizeof(buf)))
1723 				printf("emailAddress: %s\n", buf);
1724 		}
1725 		if(verb) {
1726 			int ku_loc = X509_get_ext_by_NID(
1727 				sk_X509_value(signers, i), NID_key_usage, -1);
1728 			if(verb >= 3 && ku_loc >= 0) {
1729 				X509_EXTENSION *ex = X509_get_ext(
1730 					sk_X509_value(signers, i), ku_loc);
1731 				if(ex) {
1732 					printf("keyUsage: ");
1733 					X509V3_EXT_print_fp(stdout, ex, 0, 0);
1734 					printf("\n");
1735 				}
1736 			}
1737 		}
1738 		if(!p7signer || strcmp(p7signer, "")==0) {
1739 			/* there is no name to check, return all records */
1740 			if(verb) printf("did not check commonName of signer\n");
1741 		} else {
1742 			if(!X509_NAME_get_text_by_NID(nm,
1743 				NID_pkcs9_emailAddress,
1744 				buf, (int)sizeof(buf))) {
1745 				if(verb) printf("removed cert with no name\n");
1746 				continue; /* no name, no use */
1747 			}
1748 			if(strcmp(buf, p7signer) != 0) {
1749 				if(verb) printf("removed cert with wrong name\n");
1750 				continue; /* wrong name, skip it */
1751 			}
1752 		}
1753 
1754 		/* check that the key usage allows digital signatures
1755 		 * (the p7s) */
1756 		usage = get_usage_of_ex(sk_X509_value(signers, i));
1757 		if(!(usage & KU_DIGITAL_SIGNATURE)) {
1758 			if(verb) printf("removed cert with no key usage Digital Signature allowed\n");
1759 			continue;
1760 		}
1761 
1762 		/* we like this cert, add it to our list of valid
1763 		 * signers certificates */
1764 		sk_X509_push(validsigners, sk_X509_value(signers, i));
1765 	}
1766 	sk_X509_free(signers);
1767 	return validsigners;
1768 }
1769 
1770 /** verify a PKCS7 signature, false on failure */
1771 static int
verify_p7sig(BIO * data,BIO * p7s,STACK_OF (X509)* trust,const char * p7signer)1772 verify_p7sig(BIO* data, BIO* p7s, STACK_OF(X509)* trust, const char* p7signer)
1773 {
1774 	PKCS7* p7;
1775 	X509_STORE *store = X509_STORE_new();
1776 	STACK_OF(X509)* validsigners;
1777 	int secure = 0;
1778 	int i;
1779 #ifdef X509_V_FLAG_CHECK_SS_SIGNATURE
1780 	X509_VERIFY_PARAM* param = X509_VERIFY_PARAM_new();
1781 	if(!param) {
1782 		if(verb) printf("out of memory\n");
1783 		X509_STORE_free(store);
1784 		return 0;
1785 	}
1786 	/* do the selfcheck on the root certificate; it checks that the
1787 	 * input is valid */
1788 	X509_VERIFY_PARAM_set_flags(param, X509_V_FLAG_CHECK_SS_SIGNATURE);
1789 	if(store) X509_STORE_set1_param(store, param);
1790 #endif
1791 	if(!store) {
1792 		if(verb) printf("out of memory\n");
1793 #ifdef X509_V_FLAG_CHECK_SS_SIGNATURE
1794 		X509_VERIFY_PARAM_free(param);
1795 #endif
1796 		return 0;
1797 	}
1798 #ifdef X509_V_FLAG_CHECK_SS_SIGNATURE
1799 	X509_VERIFY_PARAM_free(param);
1800 #endif
1801 
1802 	(void)BIO_seek(p7s, 0);
1803 	(void)BIO_seek(data, 0);
1804 
1805 	/* convert p7s to p7 (the signature) */
1806 	p7 = d2i_PKCS7_bio(p7s, NULL);
1807 	if(!p7) {
1808 		if(verb) printf("could not parse p7s signature file\n");
1809 		X509_STORE_free(store);
1810 		return 0;
1811 	}
1812 	if(verb >= 2) printf("parsed the PKCS7 signature\n");
1813 
1814 	/* convert trust to trusted certificate store */
1815 	for(i=0; i<sk_X509_num(trust); i++) {
1816 		if(!X509_STORE_add_cert(store, sk_X509_value(trust, i))) {
1817 			if(verb) printf("failed X509_STORE_add_cert\n");
1818 			X509_STORE_free(store);
1819 			PKCS7_free(p7);
1820 			return 0;
1821 		}
1822 	}
1823 	if(verb >= 2) printf("setup the X509_STORE\n");
1824 
1825 	/* check what is in the Subject name of the certificates,
1826 	 * and build a stack that contains only the right certificates */
1827 	validsigners = get_valid_signers(p7, p7signer);
1828 	if(!validsigners) {
1829 			X509_STORE_free(store);
1830 			PKCS7_free(p7);
1831 			return 0;
1832 	}
1833 	if(PKCS7_verify(p7, validsigners, store, data, NULL, PKCS7_NOINTERN) == 1) {
1834 		secure = 1;
1835 		if(verb) printf("the PKCS7 signature verified\n");
1836 	} else {
1837 		if(verb) {
1838 			ERR_print_errors_fp(stdout);
1839 		}
1840 	}
1841 
1842 	sk_X509_free(validsigners);
1843 	X509_STORE_free(store);
1844 	PKCS7_free(p7);
1845 	return secure;
1846 }
1847 
1848 /** open a temp file */
1849 static FILE*
tempfile_open(char * tempf,size_t tempflen,const char * fname,const char * mode)1850 tempfile_open(char* tempf, size_t tempflen, const char* fname, const char* mode)
1851 {
1852 	snprintf(tempf, tempflen, "%s~", fname);
1853 	return fopen(tempf, mode);
1854 }
1855 
1856 /** close an open temp file and replace the original with it */
1857 static void
tempfile_close(FILE * fd,const char * tempf,const char * fname)1858 tempfile_close(FILE* fd, const char* tempf, const char* fname)
1859 {
1860 	fflush(fd);
1861 #ifdef HAVE_FSYNC
1862 	fsync(fileno(fd));
1863 #else
1864 	FlushFileBuffers((HANDLE)_get_osfhandle(_fileno(fd)));
1865 #endif
1866 	if(fclose(fd) != 0) {
1867 		printf("could not complete write: %s: %s\n",
1868 			tempf, strerror(errno));
1869 		unlink(tempf);
1870 		return;
1871 	}
1872 	/* success; overwrite actual file */
1873 #ifdef USE_WINSOCK
1874 	(void)unlink(fname); /* windows does not replace file with rename() */
1875 #endif
1876 	if(rename(tempf, fname) < 0) {
1877 		printf("rename(%s to %s): %s", tempf, fname, strerror(errno));
1878 	}
1879 }
1880 
1881 /** write unsigned root anchor file, a 5011 revoked tp */
1882 static void
write_unsigned_root(const char * root_anchor_file)1883 write_unsigned_root(const char* root_anchor_file)
1884 {
1885 	FILE* out;
1886 	time_t now = time(NULL);
1887 	char tempf[2048];
1888 	out = tempfile_open(tempf, sizeof(tempf), root_anchor_file, "w");
1889 	if(!out) {
1890 		if(verb) printf("%s: %s\n", tempf, strerror(errno));
1891 		return;
1892 	}
1893 	if(fprintf(out, "; autotrust trust anchor file\n"
1894 		";;REVOKED\n"
1895 		";;id: . 1\n"
1896 		"; This file was written by unbound-anchor on %s"
1897 		"; It indicates that the root does not use DNSSEC\n"
1898 		"; to restart DNSSEC overwrite this file with a\n"
1899 		"; valid trustanchor or (empty-it and run unbound-anchor)\n"
1900 		, ctime(&now)) < 0) {
1901 		if(verb) printf("failed to write 'unsigned' to %s\n",
1902 			root_anchor_file);
1903 		if(verb && errno != 0) printf("%s\n", strerror(errno));
1904 	}
1905 	tempfile_close(out, tempf, root_anchor_file);
1906 }
1907 
1908 /** write root anchor file */
1909 static void
write_root_anchor(const char * root_anchor_file,BIO * ds)1910 write_root_anchor(const char* root_anchor_file, BIO* ds)
1911 {
1912 	char* pp = NULL;
1913 	int len;
1914 	FILE* out;
1915 	char tempf[2048];
1916 	(void)BIO_seek(ds, 0);
1917 	len = BIO_get_mem_data(ds, &pp);
1918 	if(!len || !pp) {
1919 		if(verb) printf("out of memory\n");
1920 		return;
1921 	}
1922 	out = tempfile_open(tempf, sizeof(tempf), root_anchor_file, "w");
1923 	if(!out) {
1924 		if(verb) printf("%s: %s\n", tempf, strerror(errno));
1925 		return;
1926 	}
1927 	if(fwrite(pp, (size_t)len, 1, out) != 1) {
1928 		if(verb) printf("failed to write all data to %s\n",
1929 			tempf);
1930 		if(verb && errno != 0) printf("%s\n", strerror(errno));
1931 	}
1932 	tempfile_close(out, tempf, root_anchor_file);
1933 }
1934 
1935 /** Perform the verification and update of the trustanchor file */
1936 static void
verify_and_update_anchor(const char * root_anchor_file,BIO * xml,BIO * p7s,STACK_OF (X509)* cert,const char * p7signer)1937 verify_and_update_anchor(const char* root_anchor_file, BIO* xml, BIO* p7s,
1938 	STACK_OF(X509)* cert, const char* p7signer)
1939 {
1940 	BIO* ds;
1941 
1942 	/* verify xml file */
1943 	if(!verify_p7sig(xml, p7s, cert, p7signer)) {
1944 		printf("the PKCS7 signature failed\n");
1945 		exit(0);
1946 	}
1947 
1948 	/* parse the xml file into DS records */
1949 	ds = xml_parse(xml, time(NULL));
1950 	if(!ds) {
1951 		/* the root zone is unsigned now */
1952 		write_unsigned_root(root_anchor_file);
1953 	} else {
1954 		/* reinstate 5011 tracking */
1955 		write_root_anchor(root_anchor_file, ds);
1956 	}
1957 	BIO_free(ds);
1958 }
1959 
1960 #ifdef USE_WINSOCK
do_wsa_cleanup(void)1961 static void do_wsa_cleanup(void) { WSACleanup(); }
1962 #endif
1963 
1964 /** perform actual certupdate work */
1965 static int
do_certupdate(const char * root_anchor_file,const char * root_cert_file,const char * urlname,const char * xmlname,const char * p7sname,const char * p7signer,const char * res_conf,const char * root_hints,const char * debugconf,const char * srcaddr,int ip4only,int ip6only,int port,int use_sni)1966 do_certupdate(const char* root_anchor_file, const char* root_cert_file,
1967 	const char* urlname, const char* xmlname, const char* p7sname,
1968 	const char* p7signer, const char* res_conf, const char* root_hints,
1969 	const char* debugconf, const char* srcaddr, int ip4only, int ip6only,
1970 	int port, int use_sni)
1971 
1972 {
1973 	STACK_OF(X509)* cert;
1974 	BIO *xml, *p7s;
1975 	struct ip_list* ip_list = NULL;
1976 	struct ip_list* src = NULL;
1977 
1978 	/* read pem file or provide builtin */
1979 	cert = read_cert_or_builtin(root_cert_file);
1980 
1981 	/* lookup A, AAAA for the urlname (or parse urlname if IP address) */
1982 	ip_list = resolve_name(urlname, port, res_conf, root_hints, debugconf,
1983 	        srcaddr, ip4only, ip6only);
1984 
1985 	if(srcaddr && !(src = parse_ip_addr(srcaddr, 0))) {
1986 		if(verb) printf("cannot parse source address: %s\n", srcaddr);
1987 		exit(0);
1988 	}
1989 
1990 #ifdef USE_WINSOCK
1991 	if(1) { /* libunbound finished, startup WSA for the https connection */
1992 		WSADATA wsa_data;
1993 		int r;
1994 		if((r = WSAStartup(MAKEWORD(2,2), &wsa_data)) != 0) {
1995 			if(verb) printf("WSAStartup failed: %s\n",
1996 				wsa_strerror(r));
1997 			exit(0);
1998 		}
1999 		atexit(&do_wsa_cleanup);
2000 	}
2001 #endif
2002 
2003 	/* fetch the necessary files over HTTPS */
2004 	xml = https(ip_list, xmlname, urlname, src, use_sni);
2005 	p7s = https(ip_list, p7sname, urlname, src, use_sni);
2006 
2007 	/* verify and update the root anchor */
2008 	verify_and_update_anchor(root_anchor_file, xml, p7s, cert, p7signer);
2009 	if(verb) printf("success: the anchor has been updated "
2010 			"using the cert\n");
2011 
2012 	BIO_free(xml);
2013 	BIO_free(p7s);
2014 #ifndef S_SPLINT_S
2015 	sk_X509_pop_free(cert, X509_free);
2016 #endif
2017 	ip_list_free(ip_list);
2018 	return 1;
2019 }
2020 
2021 /**
2022  * Try to read the root RFC5011 autotrust anchor file,
2023  * @param file: filename.
2024  * @return:
2025  * 	0 if does not exist or empty
2026  * 	1 if trust-point-revoked-5011
2027  * 	2 if it is OK.
2028  */
2029 static int
try_read_anchor(const char * file)2030 try_read_anchor(const char* file)
2031 {
2032 	int empty = 1;
2033 	char line[10240];
2034 	char* p;
2035 	FILE* in = fopen(file, "r");
2036 	if(!in) {
2037 		/* only if the file does not exist, can we fix it */
2038 		if(errno != ENOENT) {
2039 			if(verb) printf("%s: %s\n", file, strerror(errno));
2040 			if(verb) printf("error: cannot access the file\n");
2041 			exit(0);
2042 		}
2043 		if(verb) printf("%s does not exist\n", file);
2044 		return 0;
2045 	}
2046 	while(fgets(line, (int)sizeof(line), in)) {
2047 		line[sizeof(line)-1] = 0;
2048 		if(strncmp(line, ";;REVOKED", 9) == 0) {
2049 			fclose(in);
2050 			if(verb) printf("%s : the trust point is revoked\n"
2051 				"and the zone is considered unsigned.\n"
2052 				"if you wish to re-enable, delete the file\n",
2053 				file);
2054 			return 1;
2055 		}
2056 		p=line;
2057 		while(*p == ' ' || *p == '\t')
2058 			p++;
2059 		if(p[0]==0 || p[0]=='\n' || p[0]==';') continue;
2060 		/* this line is a line of content */
2061 		empty = 0;
2062 	}
2063 	fclose(in);
2064 	if(empty) {
2065 		if(verb) printf("%s is empty\n", file);
2066 		return 0;
2067 	}
2068 	if(verb) printf("%s has content\n", file);
2069 	return 2;
2070 }
2071 
2072 /** Write the builtin root anchor to a file */
2073 static void
write_builtin_anchor(const char * file)2074 write_builtin_anchor(const char* file)
2075 {
2076 	char tempf[2048];
2077 	const char* builtin_root_anchor = get_builtin_ds();
2078 	FILE* out = tempfile_open(tempf, sizeof(tempf), file, "w");
2079 	if(!out) {
2080 		printf("could not write builtin anchor, to file %s: %s\n",
2081 			tempf, strerror(errno));
2082 		return;
2083 	}
2084 	if(!fwrite(builtin_root_anchor, strlen(builtin_root_anchor), 1, out)) {
2085 		printf("could not complete write builtin anchor, to file %s: %s\n",
2086 			tempf, strerror(errno));
2087 	}
2088 	tempfile_close(out, tempf, file);
2089 }
2090 
2091 /**
2092  * Check the root anchor file.
2093  * If does not exist, provide builtin and write file.
2094  * If empty, provide builtin and write file.
2095  * If trust-point-revoked-5011 file: make the program exit.
2096  * @param root_anchor_file: filename of the root anchor.
2097  * @param used_builtin: set to 1 if the builtin is written.
2098  * @return 0 if trustpoint is insecure, 1 on success.  Exit on failure.
2099  */
2100 static int
provide_builtin(const char * root_anchor_file,int * used_builtin)2101 provide_builtin(const char* root_anchor_file, int* used_builtin)
2102 {
2103 	/* try to read it */
2104 	switch(try_read_anchor(root_anchor_file))
2105 	{
2106 		case 0: /* no exist or empty */
2107 			write_builtin_anchor(root_anchor_file);
2108 			*used_builtin = 1;
2109 			break;
2110 		case 1: /* revoked tp */
2111 			return 0;
2112 		case 2: /* it is fine */
2113 		default:
2114 			break;
2115 	}
2116 	return 1;
2117 }
2118 
2119 /**
2120  * add an autotrust anchor for the root to the context
2121  */
2122 static void
add_5011_probe_root(struct ub_ctx * ctx,const char * root_anchor_file)2123 add_5011_probe_root(struct ub_ctx* ctx, const char* root_anchor_file)
2124 {
2125 	int r;
2126 	r = ub_ctx_set_option(ctx, "auto-trust-anchor-file:", root_anchor_file);
2127 	if(r) {
2128 		if(verb) printf("add 5011 probe to ctx: %s\n", ub_strerror(r));
2129 		ub_ctx_delete(ctx);
2130 		exit(0);
2131 	}
2132 }
2133 
2134 /**
2135  * Prime the root key and return the result.  Exit on error.
2136  * @param ctx: the unbound context to perform the priming with.
2137  * @return: the result of the prime, on error it exit()s.
2138  */
2139 static struct ub_result*
prime_root_key(struct ub_ctx * ctx)2140 prime_root_key(struct ub_ctx* ctx)
2141 {
2142 	struct ub_result* res = NULL;
2143 	int r;
2144 	r = ub_resolve(ctx, ".", LDNS_RR_TYPE_DNSKEY, LDNS_RR_CLASS_IN, &res);
2145 	if(r) {
2146 		if(verb) printf("resolve DNSKEY: %s\n", ub_strerror(r));
2147 		ub_ctx_delete(ctx);
2148 		exit(0);
2149 	}
2150 	if(!res) {
2151 		if(verb) printf("out of memory\n");
2152 		ub_ctx_delete(ctx);
2153 		exit(0);
2154 	}
2155 	return res;
2156 }
2157 
2158 /** see if ADDPEND keys exist in autotrust file (if possible) */
2159 static int
read_if_pending_keys(const char * file)2160 read_if_pending_keys(const char* file)
2161 {
2162 	FILE* in = fopen(file, "r");
2163 	char line[8192];
2164 	if(!in) {
2165 		if(verb>=2) printf("%s: %s\n", file, strerror(errno));
2166 		return 0;
2167 	}
2168 	while(fgets(line, (int)sizeof(line), in)) {
2169 		if(line[0]==';') continue;
2170 		if(strstr(line, "[ ADDPEND ]")) {
2171 			fclose(in);
2172 			if(verb) printf("RFC5011-state has ADDPEND keys\n");
2173 			return 1;
2174 		}
2175 	}
2176 	fclose(in);
2177 	return 0;
2178 }
2179 
2180 /** read last successful probe time from autotrust file (if possible) */
2181 static int32_t
read_last_success_time(const char * file)2182 read_last_success_time(const char* file)
2183 {
2184 	FILE* in = fopen(file, "r");
2185 	char line[1024];
2186 	if(!in) {
2187 		if(verb) printf("%s: %s\n", file, strerror(errno));
2188 		return 0;
2189 	}
2190 	while(fgets(line, (int)sizeof(line), in)) {
2191 		if(strncmp(line, ";;last_success: ", 16) == 0) {
2192 			char* e;
2193 			time_t x = (unsigned int)strtol(line+16, &e, 10);
2194 			fclose(in);
2195 			if(line+16 == e) {
2196 				if(verb) printf("failed to parse "
2197 					"last_success probe time\n");
2198 				return 0;
2199 			}
2200 			if(verb) printf("last successful probe: %s", ctime(&x));
2201 			return (int32_t)x;
2202 		}
2203 	}
2204 	fclose(in);
2205 	if(verb) printf("no last_success probe time in anchor file\n");
2206 	return 0;
2207 }
2208 
2209 /**
2210  * Read autotrust 5011 probe file and see if the date
2211  * compared to the current date allows a certupdate.
2212  * If the last successful probe was recent then 5011 cannot be behind,
2213  * and the failure cannot be solved with a certupdate.
2214  * The debugconf is to validation-override the date for testing.
2215  * @param root_anchor_file: filename of root key
2216  * @return true if certupdate is ok.
2217  */
2218 static int
probe_date_allows_certupdate(const char * root_anchor_file)2219 probe_date_allows_certupdate(const char* root_anchor_file)
2220 {
2221 	int has_pending_keys = read_if_pending_keys(root_anchor_file);
2222 	int32_t last_success = read_last_success_time(root_anchor_file);
2223 	int32_t now = (int32_t)time(NULL);
2224 	int32_t leeway = 30 * 24 * 3600; /* 30 days leeway */
2225 	/* if the date is before 2010-07-15:00.00.00 then the root has not
2226 	 * been signed yet, and thus we refuse to take action. */
2227 	if(time(NULL) < xml_convertdate("2010-07-15T00:00:00")) {
2228 		if(verb) printf("the date is before the root was first signed,"
2229 			" please correct the clock\n");
2230 		return 0;
2231 	}
2232 	if(last_success == 0)
2233 		return 1; /* no probe time */
2234 	if(has_pending_keys)
2235 		return 1; /* key in ADDPEND state, a previous probe has
2236 		inserted that, and it was present in all recent probes,
2237 		but it has not become active.  The 30 day timer may not have
2238 		expired, but we know(for sure) there is a rollover going on.
2239 		If we only managed to pickup the new key on its last day
2240 		of announcement (for example) this can happen. */
2241 	if(now - last_success < 0) {
2242 		if(verb) printf("the last successful probe is in the future,"
2243 			" clock was modified\n");
2244 		return 0;
2245 	}
2246 	if(now - last_success >= leeway) {
2247 		if(verb) printf("the last successful probe was more than 30 "
2248 			"days ago\n");
2249 		return 1;
2250 	}
2251 	if(verb) printf("the last successful probe is recent\n");
2252 	return 0;
2253 }
2254 
2255 static struct ub_result *
fetch_root_key(const char * root_anchor_file,const char * res_conf,const char * root_hints,const char * debugconf,const char * srcaddr,int ip4only,int ip6only)2256 fetch_root_key(const char* root_anchor_file, const char* res_conf,
2257 	const char* root_hints, const char* debugconf, const char* srcaddr,
2258 	int ip4only, int ip6only)
2259 {
2260 	struct ub_ctx* ctx;
2261 	struct ub_result* dnskey;
2262 
2263 	ctx = create_unbound_context(res_conf, root_hints, debugconf,
2264 		srcaddr, ip4only, ip6only);
2265 	add_5011_probe_root(ctx, root_anchor_file);
2266 	dnskey = prime_root_key(ctx);
2267 	ub_ctx_delete(ctx);
2268 	return dnskey;
2269 }
2270 
2271 /** perform the unbound-anchor work */
2272 static int
do_root_update_work(const char * root_anchor_file,const char * root_cert_file,const char * urlname,const char * xmlname,const char * p7sname,const char * p7signer,const char * res_conf,const char * root_hints,const char * debugconf,const char * srcaddr,int ip4only,int ip6only,int force,int res_conf_fallback,int port,int use_sni)2273 do_root_update_work(const char* root_anchor_file, const char* root_cert_file,
2274 	const char* urlname, const char* xmlname, const char* p7sname,
2275 	const char* p7signer, const char* res_conf, const char* root_hints,
2276 	const char* debugconf, const char* srcaddr, int ip4only, int ip6only,
2277 	int force, int res_conf_fallback, int port, int use_sni)
2278 {
2279 	struct ub_result* dnskey;
2280 	int used_builtin = 0;
2281 	int rcode;
2282 
2283 	/* see if builtin rootanchor needs to be provided, or if
2284 	 * rootanchor is 'revoked-trust-point' */
2285 	if(!provide_builtin(root_anchor_file, &used_builtin))
2286 		return 0;
2287 
2288 	/* make unbound context with 5011-probe for root anchor,
2289 	 * and probe . DNSKEY */
2290 	dnskey = fetch_root_key(root_anchor_file, res_conf,
2291 		root_hints, debugconf, srcaddr, ip4only, ip6only);
2292 	rcode = dnskey->rcode;
2293 
2294 	if (res_conf_fallback && res_conf && !dnskey->secure) {
2295 		if (verb) printf("%s failed, retrying direct\n", res_conf);
2296 		ub_resolve_free(dnskey);
2297 		/* try direct query without res_conf */
2298 		dnskey = fetch_root_key(root_anchor_file, NULL,
2299 			root_hints, debugconf, srcaddr, ip4only, ip6only);
2300 		if (rcode != 0 && dnskey->rcode == 0) {
2301 			res_conf = NULL;
2302 			rcode = 0;
2303 		}
2304 	}
2305 
2306 	/* if secure: exit */
2307 	if(dnskey->secure && !force) {
2308 		if(verb) printf("success: the anchor is ok\n");
2309 		ub_resolve_free(dnskey);
2310 		return used_builtin;
2311 	}
2312 	if(force && verb) printf("debug cert update forced\n");
2313 	ub_resolve_free(dnskey);
2314 
2315 	/* if not (and NOERROR): check date and do certupdate */
2316 	if((rcode == 0 &&
2317 		probe_date_allows_certupdate(root_anchor_file)) || force) {
2318 		if(do_certupdate(root_anchor_file, root_cert_file, urlname,
2319 			xmlname, p7sname, p7signer, res_conf, root_hints,
2320 			debugconf, srcaddr, ip4only, ip6only, port, use_sni))
2321 			return 1;
2322 		return used_builtin;
2323 	}
2324 	if(verb) printf("fail: the anchor is NOT ok and could not be fixed\n");
2325 	return used_builtin;
2326 }
2327 
2328 /** getopt global, in case header files fail to declare it. */
2329 extern int optind;
2330 /** getopt global, in case header files fail to declare it. */
2331 extern char* optarg;
2332 
2333 /** Main routine for unbound-anchor */
main(int argc,char * argv[])2334 int main(int argc, char* argv[])
2335 {
2336 	int c;
2337 	const char* root_anchor_file = ROOT_ANCHOR_FILE;
2338 	const char* root_cert_file = ROOT_CERT_FILE;
2339 	const char* urlname = URLNAME;
2340 	const char* xmlname = XMLNAME;
2341 	const char* p7sname = P7SNAME;
2342 	const char* p7signer = P7SIGNER;
2343 	const char* res_conf = NULL;
2344 	const char* root_hints = NULL;
2345 	const char* debugconf = NULL;
2346 	const char* srcaddr = NULL;
2347 	char* root_anchor_temppath;
2348 	char* s;
2349 	int dolist=0, ip4only=0, ip6only=0, force=0, port = HTTPS_PORT;
2350 	int res_conf_fallback = 0;
2351 	int use_sni = 1;
2352 	/* parse the options */
2353 	while( (c=getopt(argc, argv, "46C:FRSP:a:b:c:f:hln:r:s:u:vx:")) != -1) {
2354 		switch(c) {
2355 		case 'l':
2356 			dolist = 1;
2357 			break;
2358 		case '4':
2359 			ip4only = 1;
2360 			break;
2361 		case '6':
2362 			ip6only = 1;
2363 			break;
2364 		case 'a':
2365 			root_anchor_file = optarg;
2366 			break;
2367 		case 'b':
2368 			srcaddr = optarg;
2369 			break;
2370 		case 'c':
2371 			root_cert_file = optarg;
2372 			break;
2373 		case 'u':
2374 			urlname = optarg;
2375 			break;
2376 		case 'S':
2377 			use_sni = 0;
2378 			break;
2379 		case 'x':
2380 			xmlname = optarg;
2381 			break;
2382 		case 's':
2383 			p7sname = optarg;
2384 			break;
2385 		case 'n':
2386 			p7signer = optarg;
2387 			break;
2388 		case 'f':
2389 			res_conf = optarg;
2390 			break;
2391 		case 'r':
2392 			root_hints = optarg;
2393 			break;
2394 		case 'R':
2395 			res_conf_fallback = 1;
2396 			break;
2397 		case 'C':
2398 			debugconf = optarg;
2399 			break;
2400 		case 'F':
2401 			force = 1;
2402 			break;
2403 		case 'P':
2404 			port = atoi(optarg);
2405 			break;
2406 		case 'v':
2407 			verb++;
2408 			break;
2409 		case '?':
2410 		case 'h':
2411 		default:
2412 			usage();
2413 		}
2414 	}
2415 	argc -= optind;
2416 	/* argv += optind; not using further arguments */
2417 	if(argc != 0)
2418 		usage();
2419 
2420 #ifdef HAVE_ERR_LOAD_CRYPTO_STRINGS
2421 	ERR_load_crypto_strings();
2422 #endif
2423 #if OPENSSL_VERSION_NUMBER < 0x10100000 || !defined(HAVE_OPENSSL_INIT_SSL)
2424 	ERR_load_SSL_strings();
2425 #endif
2426 #if OPENSSL_VERSION_NUMBER < 0x10100000 || !defined(HAVE_OPENSSL_INIT_CRYPTO)
2427 #  ifndef S_SPLINT_S
2428 	OpenSSL_add_all_algorithms();
2429 #  endif
2430 #else
2431 	OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_CIPHERS
2432 		| OPENSSL_INIT_ADD_ALL_DIGESTS
2433 		| OPENSSL_INIT_LOAD_CRYPTO_STRINGS, NULL);
2434 #endif
2435 #if OPENSSL_VERSION_NUMBER < 0x10100000 || !defined(HAVE_OPENSSL_INIT_SSL)
2436 	(void)SSL_library_init();
2437 #else
2438 	(void)OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS, NULL);
2439 #endif
2440 
2441 	if(dolist) do_list_builtin();
2442 
2443 	s = strdup(root_anchor_file);
2444 	if (s == NULL ||
2445 	    asprintf(&root_anchor_temppath, "%s", dirname(s)) == -1) {
2446 		if(verb) printf("out of memory\n");
2447 		exit(0);
2448 	}
2449 	if (unveil(root_anchor_temppath, "rwc") == -1)
2450 		err(1, "unveil %s", root_anchor_temppath);
2451 	free(root_anchor_temppath);
2452 	free(s);
2453 	if (unveil(root_cert_file, "r") == -1)
2454 		err(1, "unveil %s", root_cert_file);
2455 	if (res_conf != NULL && unveil(res_conf, "r") == -1)
2456 		err(1, "unveil %s", res_conf);
2457 	if (root_hints != NULL && unveil(root_hints, "r") == -1)
2458 		err(1, "unveil %s", root_hints);
2459 	if (debugconf != NULL && unveil(debugconf, "r") == -1)
2460 		err(1, "unveil %s", debugconf);
2461 
2462 	if (pledge("stdio rpath wpath cpath inet dns", NULL) == -1)
2463 		err(1, "pledge");
2464 
2465 	return do_root_update_work(root_anchor_file, root_cert_file, urlname,
2466 		xmlname, p7sname, p7signer, res_conf, root_hints, debugconf,
2467 		srcaddr, ip4only, ip6only, force, res_conf_fallback, port, use_sni);
2468 }
2469