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