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