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