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