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