1 /* Copyright (c) 2012, Jacob Appelbaum. 2 * Copyright (c) 2012, The Tor Project, Inc. 3 * Copyright (c) 2012, Christian Grothoff. */ 4 /* See LICENSE for licensing information */ 5 /* 6 This file contains the license for tlsdate, 7 a free software project to set your system clock securely. 8 9 It also lists the licenses for other components used by tlsdate. 10 11 For more information about tlsdate, see https://github.com/ioerror/tlsdate 12 13 If you got this file as a part of a larger bundle, 14 there may be other license terms that you should be aware of. 15 16 =============================================================================== 17 tlsdate is distributed under this license: 18 19 Copyright (c) 2011-2012, Jacob Appelbaum <jacob (at) appelbaum.net> 20 Copyright (c) 2011-2012, The Tor Project, Inc. 21 22 Redistribution and use in source and binary forms, with or without 23 modification, are permitted provided that the following conditions are 24 met: 25 26 * Redistributions of source code must retain the above copyright 27 notice, this list of conditions and the following disclaimer. 28 29 * Redistributions in binary form must reproduce the above 30 copyright notice, this list of conditions and the following disclaimer 31 in the documentation and/or other materials provided with the 32 distribution. 33 34 * Neither the names of the copyright owners nor the names of its 35 contributors may be used to endorse or promote products derived from 36 this software without specific prior written permission. 37 38 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 39 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 40 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 41 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 42 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 43 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 44 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 45 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 46 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 47 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 48 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 49 =============================================================================== 50 If you got tlsdate as a static binary with OpenSSL included, then you should 51 know: 52 53 "This product includes software developed by the OpenSSL Project for use in 54 the OpenSSL Toolkit (http://www.openssl.org/)" 55 56 =============================================================================== 57 */ 58 59 /** 60 * \file tlsdate-helper.c 61 * \brief Helper program that does the actual work of setting the system clock. 62 **/ 63 64 /* 65 * tlsdate is a tool for setting the system clock by hand or by communication 66 * with the network. It does not set the RTC. It is designed to be as secure as 67 * TLS (RFC 2246) but of course the security of TLS is often reduced to 68 * whichever CA racket you believe is trustworthy. By default, tlsdate trusts 69 * your local CA root store - so any of these companies could assist in a MITM 70 * attack against you and you'd be screwed. 71 72 * This tool is designed to be run by hand or as a system daemon. It must be 73 * run as root or otherwise have the proper caps; it will not be able to set 74 * the system time without running as root or another privileged user. 75 */ 76 77 #include "config.h" 78 #include "src/tlsdate-helper-plan9.h" 79 80 #ifndef USE_POLARSSL 81 #include "src/proxy-bio-plan9.h" 82 #else 83 #include "src/proxy-polarssl.h" 84 #endif 85 86 #include "src/compat/clock-plan9.h" 87 88 #ifndef MAP_ANONYMOUS 89 #define MAP_ANONYMOUS MAP_ANON 90 #endif 91 92 #ifdef USE_POLARSSL 93 #include "polarssl/entropy.h" 94 #include "polarssl/ctr_drbg.h" 95 #include "polarssl/ssl.h" 96 #endif 97 98 static void 99 validate_proxy_scheme(const char *scheme) 100 { 101 if (!strcmp(scheme, "http")) 102 return; 103 if (!strcmp(scheme, "socks4")) 104 return; 105 if (!strcmp(scheme, "socks5")) 106 return; 107 die("invalid proxy scheme\n"); 108 } 109 110 static void 111 validate_proxy_host(const char *host) 112 { 113 const char *kValid = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" 114 "abcdefghijklmnopqrstuvwxyz" 115 "0123456789" 116 ".-"; 117 if (strspn(host, kValid) != strlen(host)) 118 die("invalid char in host\n"); 119 } 120 121 static void 122 validate_proxy_port(const char *port) 123 { 124 while (*port) 125 if (!isdigit(*port++)) 126 die("invalid char in port\n"); 127 } 128 129 static void 130 parse_proxy_uri(char *proxy, char **scheme, char **host, char **port) 131 { 132 /* Expecting a URI, so: <scheme> '://' <host> ':' <port> */ 133 *scheme = proxy; 134 proxy = strstr(proxy, "://"); 135 if (!proxy) 136 die("malformed proxy URI\n"); 137 *proxy = '\0'; /* terminate scheme string */ 138 proxy += strlen("://"); 139 140 *host = proxy; 141 proxy = strchr(proxy, ':'); 142 if (!proxy) 143 die("malformed proxy URI\n"); 144 *proxy++ = '\0'; 145 146 *port = proxy; 147 148 validate_proxy_scheme(*scheme); 149 validate_proxy_host(*host); 150 validate_proxy_port(*port); 151 } 152 153 #ifndef USE_POLARSSL 154 static void 155 setup_proxy(BIO *ssl) 156 { 157 BIO *bio; 158 char *scheme; 159 char *proxy_host; 160 char *proxy_port; 161 162 if (!proxy) 163 return; 164 /* 165 * grab the proxy's host and port out of the URI we have for it. We want the 166 * underlying connect BIO to connect to this, not the target host and port, so 167 * we squirrel away the target host and port in the proxy BIO (as the proxy 168 * target) and swap out the connect BIO's target host and port so it'll 169 * connect to the proxy instead. 170 */ 171 parse_proxy_uri(proxy, &scheme, &proxy_host, &proxy_port); 172 bio = BIO_new_proxy(); 173 BIO_proxy_set_type(bio, scheme); 174 BIO_proxy_set_host(bio, host); 175 BIO_proxy_set_port(bio, atoi(port)); 176 host = proxy_host; 177 port = proxy_port; 178 BIO_push(ssl, bio); 179 } 180 181 static BIO * 182 make_ssl_bio(SSL_CTX *ctx) 183 { 184 BIO *con = NULL; 185 BIO *ssl = NULL; 186 187 if (!(con = BIO_new(BIO_s_connect()))) 188 die("BIO_s_connect failed\n"); 189 if (!(ssl = BIO_new_ssl(ctx, 1))) 190 die("BIO_new_ssl failed\n"); 191 setup_proxy(ssl); 192 BIO_push(ssl, con); 193 return ssl; 194 } 195 196 /** helper function for 'malloc' */ 197 static void * 198 xmalloc (size_t size) 199 { 200 void *ptr; 201 202 if (0 == size) 203 die("xmalloc: zero size\n"); 204 205 ptr = malloc(size); 206 if (NULL == ptr) 207 die("xmalloc: out of memory (allocating %zu bytes)\n", size); 208 209 return ptr; 210 } 211 212 213 /** helper function for 'free' */ 214 static void 215 xfree (void *ptr) 216 { 217 if (NULL == ptr) 218 die("xfree: NULL pointer given as argument\n"); 219 220 free(ptr); 221 } 222 223 void 224 openssl_time_callback (const SSL* ssl, int where, int ret) 225 { 226 if (where == SSL_CB_CONNECT_LOOP && 227 (ssl->state == SSL3_ST_CR_SRVR_HELLO_A || ssl->state == SSL3_ST_CR_SRVR_HELLO_B)) 228 { 229 /* 230 // XXX TODO: If we want to trust the remote system for time, 231 // can we just read that time out of the remote system and if the 232 // cert verifies, decide that the time is reasonable? 233 // Such a process seems to indicate that a once valid cert would be 234 // forever valid - we stopgap that by ensuring it isn't less than 235 // the latest compiled_time and isn't above max_reasonable_time... 236 // XXX TODO: Solve eternal question about the Chicken and the Egg... 237 */ 238 uint32_t compiled_time = RECENT_COMPILE_DATE; 239 uint32_t max_reasonable_time = MAX_REASONABLE_TIME; 240 uint32_t server_time; 241 verb("V: freezing time for x509 verification\n"); 242 memcpy(&server_time, ssl->s3->server_random, sizeof(uint32_t)); 243 if (compiled_time < ntohl(server_time) 244 && 245 ntohl(server_time) < max_reasonable_time) 246 { 247 verb("V: remote peer provided: %d, preferred over compile time: %d\n", 248 ntohl(server_time), compiled_time); 249 verb("V: freezing time with X509_VERIFY_PARAM_set_time\n"); 250 X509_VERIFY_PARAM_set_time(ssl->ctx->cert_store->param, 251 (time_t) ntohl(server_time) + 86400); 252 } else { 253 die("V: the remote server is a false ticker! server: %d compile: %d\n", 254 ntohl(server_time), compiled_time); 255 } 256 } 257 } 258 259 uint32_t 260 get_certificate_keybits (EVP_PKEY *public_key) 261 { 262 /* 263 In theory, we could use check_bitlen_dsa() and check_bitlen_rsa() 264 */ 265 uint32_t key_bits; 266 switch (public_key->type) 267 { 268 case EVP_PKEY_RSA: 269 verb("V: key type: EVP_PKEY_RSA\n"); 270 key_bits = BN_num_bits(public_key->pkey.rsa->n); 271 break; 272 case EVP_PKEY_RSA2: 273 verb("V: key type: EVP_PKEY_RSA2\n"); 274 key_bits = BN_num_bits(public_key->pkey.rsa->n); 275 break; 276 case EVP_PKEY_DSA: 277 verb("V: key type: EVP_PKEY_DSA\n"); 278 key_bits = BN_num_bits(public_key->pkey.dsa->p); 279 break; 280 case EVP_PKEY_DSA1: 281 verb("V: key type: EVP_PKEY_DSA1\n"); 282 key_bits = BN_num_bits(public_key->pkey.dsa->p); 283 break; 284 case EVP_PKEY_DSA2: 285 verb("V: key type: EVP_PKEY_DSA2\n"); 286 key_bits = BN_num_bits(public_key->pkey.dsa->p); 287 break; 288 case EVP_PKEY_DSA3: 289 verb("V: key type: EVP_PKEY_DSA3\n"); 290 key_bits = BN_num_bits(public_key->pkey.dsa->p); 291 break; 292 case EVP_PKEY_DSA4: 293 verb("V: key type: EVP_PKEY_DSA4\n"); 294 key_bits = BN_num_bits(public_key->pkey.dsa->p); 295 break; 296 case EVP_PKEY_DH: 297 verb("V: key type: EVP_PKEY_DH\n"); 298 key_bits = BN_num_bits(public_key->pkey.dh->pub_key); 299 break; 300 case EVP_PKEY_EC: 301 verb("V: key type: EVP_PKEY_EC\n"); 302 key_bits = EVP_PKEY_bits(public_key); 303 break; 304 // Should we also care about EVP_PKEY_HMAC and EVP_PKEY_CMAC? 305 default: 306 key_bits = 0; 307 die ("unknown public key type\n"); 308 break; 309 } 310 verb ("V: keybits: %d\n", key_bits); 311 return key_bits; 312 } 313 314 uint32_t 315 dns_label_count(char *label, char *delim) 316 { 317 char *label_tmp; 318 char *saveptr; 319 char *saveptr_tmp; 320 uint32_t label_count; 321 322 label_tmp = strdup(label); 323 label_count = 0; 324 saveptr = NULL; 325 saveptr_tmp = NULL; 326 saveptr = strtok_r(label_tmp, delim, &saveptr); 327 if (NULL != saveptr) 328 { 329 // Did we find our first label? 330 if (saveptr[0] != delim[0]) 331 { 332 label_count++; 333 verb ("V: label found; total label count: %d\n", label_count); 334 } 335 do 336 { 337 // Find all subsequent labels 338 label_count++; 339 saveptr_tmp = strtok_r(NULL, delim, &saveptr); 340 verb ("V: label found; total label count: %d\n", label_count); 341 } while (NULL != saveptr_tmp); 342 } 343 free(label_tmp); 344 return label_count; 345 } 346 347 // first we split strings on '.' 348 // then we call each split string a 'label' 349 // Do not allow '*' for the top level domain label; eg never allow *.*.com 350 // Do not allow '*' for subsequent subdomains; eg never allow *.foo.example.com 351 // Do allow *.example.com 352 uint32_t 353 check_wildcard_match_rfc2595 (const char *orig_hostname, 354 const char *orig_cert_wild_card) 355 { 356 char *hostname; 357 char *hostname_to_free; 358 char *cert_wild_card; 359 char *cert_wild_card_to_free; 360 char *expected_label; 361 char *wildcard_label; 362 char *delim; 363 char *wildchar; 364 uint32_t ok; 365 uint32_t wildcard_encountered; 366 uint32_t label_count; 367 368 // First we copy the original strings 369 hostname = strdup(orig_hostname); 370 cert_wild_card = strdup(orig_cert_wild_card); 371 hostname_to_free = hostname; 372 cert_wild_card_to_free = cert_wild_card; 373 delim = strdup("."); 374 wildchar = strdup("*"); 375 376 verb ("V: Inspecting '%s' for possible wildcard match against '%s'\n", 377 hostname, cert_wild_card); 378 379 // By default we have not processed any labels 380 label_count = dns_label_count(cert_wild_card, delim); 381 382 // By default we have no match 383 ok = 0; 384 wildcard_encountered = 0; 385 // First - do we have labels? If not, we refuse to even try to match 386 if ((NULL != strpbrk(cert_wild_card, delim)) && 387 (NULL != strpbrk(hostname, delim)) && 388 (label_count <= ((uint32_t)RFC2595_MIN_LABEL_COUNT))) 389 { 390 if (wildchar[0] == cert_wild_card[0]) 391 { 392 verb ("V: Found wildcard in at start of provided certificate name\n"); 393 do 394 { 395 // Skip over the bytes between the first char and until the next label 396 wildcard_label = strtok(cert_wild_card, delim); 397 expected_label = strtok(hostname, delim); 398 if (NULL != wildcard_label && 399 NULL != expected_label && 400 NULL != hostname && 401 NULL != cert_wild_card) 402 { 403 // Now we only consider this wildcard valid if the rest of the 404 // hostnames match verbatim 405 verb ("V: Attempting match of '%s' against '%s'\n", 406 expected_label, wildcard_label); 407 // This is the case where we have a label that begins with wildcard 408 // Furthermore, we only allow this for the first label 409 if (wildcard_label[0] == wildchar[0] && 410 0 == wildcard_encountered && 0 == ok) 411 { 412 verb ("V: Forced match of '%s' against '%s'\n", expected_label, wildcard_label); 413 wildcard_encountered = 1; 414 } else { 415 verb ("V: Attempting match of '%s' against '%s'\n", 416 hostname, cert_wild_card); 417 if (0 == strcasecmp (expected_label, wildcard_label) && 418 label_count >= ((uint32_t)RFC2595_MIN_LABEL_COUNT)) 419 { 420 ok = 1; 421 verb ("V: remaining labels match!\n"); 422 break; 423 } else { 424 ok = 0; 425 verb ("V: remaining labels do not match!\n"); 426 break; 427 } 428 } 429 } else { 430 // We hit this case when we have a mismatched number of labels 431 verb("V: NULL label; no wildcard here\n"); 432 break; 433 } 434 } while (0 != wildcard_encountered && label_count <= RFC2595_MIN_LABEL_COUNT); 435 } else { 436 verb ("V: Not a RFC 2595 wildcard\n"); 437 } 438 } else { 439 verb ("V: Not a valid wildcard certificate\n"); 440 ok = 0; 441 } 442 // Free our copies 443 free(wildchar); 444 free(delim); 445 free(hostname_to_free); 446 free(cert_wild_card_to_free); 447 if (wildcard_encountered & ok && label_count >= RFC2595_MIN_LABEL_COUNT) 448 { 449 verb ("V: wildcard match of %s against %s\n", 450 orig_hostname, orig_cert_wild_card); 451 return (wildcard_encountered & ok); 452 } else { 453 verb ("V: wildcard match failure of %s against %s\n", 454 orig_hostname, orig_cert_wild_card); 455 return 0; 456 } 457 } 458 #endif 459 460 #ifndef USE_POLARSSL 461 /** 462 This extracts the first commonName and checks it against hostname. 463 */ 464 uint32_t 465 check_cn (SSL *ssl, const char *hostname) 466 { 467 int ok = 0; 468 int ret; 469 char *cn_buf; 470 X509 *certificate; 471 X509_NAME *xname; 472 473 // We cast this to cast away g++ complaining about the following: 474 // error: invalid conversion from void* to char* 475 cn_buf = (char *) xmalloc(TLSDATE_HOST_NAME_MAX + 1); 476 477 certificate = SSL_get_peer_certificate(ssl); 478 if (NULL == certificate) 479 { 480 die ("Unable to extract certificate\n"); 481 } 482 483 memset(cn_buf, '\0', (TLSDATE_HOST_NAME_MAX + 1)); 484 xname = X509_get_subject_name(certificate); 485 ret = X509_NAME_get_text_by_NID(xname, NID_commonName, 486 cn_buf, TLSDATE_HOST_NAME_MAX); 487 488 if (-1 == ret || ret != (int) strlen(cn_buf)) 489 { 490 die ("Unable to extract commonName\n"); 491 } 492 if (strcasecmp(cn_buf, hostname)) 493 { 494 verb ("V: commonName mismatch! Expected: %s - received: %s\n", 495 hostname, cn_buf); 496 } else { 497 verb ("V: commonName matched: %s\n", cn_buf); 498 ok = 1; 499 } 500 501 X509_NAME_free(xname); 502 X509_free(certificate); 503 xfree(cn_buf); 504 505 return ok; 506 } 507 508 /** 509 Search for a hostname match in the SubjectAlternativeNames. 510 */ 511 uint32_t 512 check_san (SSL *ssl, const char *hostname) 513 { 514 X509 *cert; 515 int extcount, ok = 0; 516 /* What an OpenSSL mess ... */ 517 if (NULL == (cert = SSL_get_peer_certificate(ssl))) 518 { 519 die ("Getting certificate failed\n"); 520 } 521 522 if ((extcount = X509_get_ext_count(cert)) > 0) 523 { 524 int i; 525 for (i = 0; i < extcount; ++i) 526 { 527 const char *extstr; 528 X509_EXTENSION *ext; 529 ext = X509_get_ext(cert, i); 530 extstr = OBJ_nid2sn(OBJ_obj2nid(X509_EXTENSION_get_object(ext))); 531 532 if (!strcmp(extstr, "subjectAltName")) 533 { 534 535 int j; 536 void *extvalstr; 537 const unsigned char *tmp; 538 539 STACK_OF(CONF_VALUE) *val; 540 CONF_VALUE *nval; 541 #if OPENSSL_VERSION_NUMBER >= 0x10000000L 542 const 543 #endif 544 X509V3_EXT_METHOD *method; 545 546 if (!(method = X509V3_EXT_get(ext))) 547 { 548 break; 549 } 550 551 tmp = ext->value->data; 552 if (method->it) 553 { 554 extvalstr = ASN1_item_d2i(NULL, &tmp, ext->value->length, 555 ASN1_ITEM_ptr(method->it)); 556 } else { 557 extvalstr = method->d2i(NULL, &tmp, ext->value->length); 558 } 559 560 if (!extvalstr) 561 { 562 break; 563 } 564 565 if (method->i2v) 566 { 567 val = method->i2v(method, extvalstr, NULL); 568 for (j = 0; j < sk_CONF_VALUE_num(val); ++j) 569 { 570 nval = sk_CONF_VALUE_value(val, j); 571 if ((!strcasecmp(nval->name, "DNS") && 572 !strcasecmp(nval->value, hostname) ) || 573 (!strcasecmp(nval->name, "iPAddress") && 574 !strcasecmp(nval->value, hostname))) 575 { 576 verb ("V: subjectAltName matched: %s, type: %s\n", nval->value, nval->name); /* We matched this; so it's safe to print */ 577 ok = 1; 578 break; 579 } 580 // Attempt to match subjectAltName DNS names 581 if (!strcasecmp(nval->name, "DNS")) 582 { 583 ok = check_wildcard_match_rfc2595(hostname, nval->value); 584 if (ok) 585 { 586 break; 587 } 588 } 589 verb ("V: subjectAltName found but not matched: %s, type: %s\n", nval->value, nval->name); // XXX: Clean this string! 590 } 591 } 592 } else { 593 verb ("V: found non subjectAltName extension\n"); 594 } 595 if (ok) 596 { 597 break; 598 } 599 } 600 } else { 601 verb ("V: no X509_EXTENSION field(s) found\n"); 602 } 603 X509_free(cert); 604 return ok; 605 } 606 607 uint32_t 608 check_name (SSL *ssl, const char *hostname) 609 { 610 uint32_t ret; 611 ret = check_cn(ssl, hostname); 612 ret += check_san(ssl, hostname); 613 if (0 != ret && 0 < ret) 614 { 615 verb ("V: hostname verification passed\n"); 616 } else { 617 die ("hostname verification failed for host %s!\n", host); 618 } 619 return ret; 620 } 621 #endif 622 623 #ifdef USE_POLARSSL 624 uint32_t 625 verify_signature (ssl_context *ssl, const char *hostname) 626 { 627 int ssl_verify_result; 628 629 ssl_verify_result = ssl_get_verify_result (ssl); 630 if (ssl_verify_result & BADCERT_EXPIRED) 631 { 632 die ("certificate has expired\n"); 633 } 634 if (ssl_verify_result & BADCERT_REVOKED) 635 { 636 die ("certificate has been revoked\n"); 637 } 638 if (ssl_verify_result & BADCERT_CN_MISMATCH) 639 { 640 die ("CN and subject AltName mismatch for certificate\n"); 641 } 642 if (ssl_verify_result & BADCERT_NOT_TRUSTED) 643 { 644 die ("certificate is self-signed or not signed by a trusted CA\n"); 645 } 646 647 if (0 == ssl_verify_result) 648 { 649 verb ("V: verify success\n"); 650 } 651 else 652 { 653 die ("certificate verification error: -0x%04x\n", -ssl_verify_result); 654 } 655 return 0; 656 } 657 #else 658 uint32_t 659 verify_signature (SSL *ssl, const char *hostname) 660 { 661 long ssl_verify_result; 662 X509 *certificate; 663 664 certificate = SSL_get_peer_certificate(ssl); 665 if (NULL == certificate) 666 { 667 die ("Getting certificate failed\n"); 668 } 669 // In theory, we verify that the cert is valid 670 ssl_verify_result = SSL_get_verify_result(ssl); 671 switch (ssl_verify_result) 672 { 673 case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT: 674 case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN: 675 die ("certificate is self signed\n"); 676 case X509_V_OK: 677 verb ("V: certificate verification passed\n"); 678 break; 679 default: 680 die ("certification verification error: %ld\n", 681 ssl_verify_result); 682 } 683 return 0; 684 } 685 #endif 686 687 #ifdef USE_POLARSSL 688 void 689 check_key_length (ssl_context *ssl) 690 { 691 uint32_t key_bits; 692 const x509_cert *certificate; 693 const rsa_context *public_key; 694 char buf[1024]; 695 696 certificate = ssl_get_peer_cert (ssl); 697 if (NULL == certificate) 698 { 699 die ("Getting certificate failed\n"); 700 } 701 702 x509parse_dn_gets(buf, 1024, &certificate->subject); 703 verb ("V: Certificate for subject '%s'\n", buf); 704 705 public_key = &certificate->rsa; 706 if (NULL == public_key) 707 { 708 die ("public key extraction failure\n"); 709 } else { 710 verb ("V: public key is ready for inspection\n"); 711 } 712 key_bits = mpi_msb (&public_key->N); 713 if (MIN_PUB_KEY_LEN >= key_bits) 714 { 715 die ("Unsafe public key size: %d bits\n", key_bits); 716 } else { 717 verb ("V: key length appears safe\n"); 718 } 719 } 720 #else 721 void 722 check_key_length (SSL *ssl) 723 { 724 uint32_t key_bits; 725 X509 *certificate; 726 EVP_PKEY *public_key; 727 certificate = SSL_get_peer_certificate (ssl); 728 if (NULL == certificate) 729 { 730 die ("Getting certificate failed\n"); 731 } 732 public_key = X509_get_pubkey (certificate); 733 if (NULL == public_key) 734 { 735 die ("public key extraction failure\n"); 736 } else { 737 verb ("V: public key is ready for inspection\n"); 738 } 739 740 key_bits = get_certificate_keybits (public_key); 741 if (MIN_PUB_KEY_LEN >= key_bits && public_key->type != EVP_PKEY_EC) 742 { 743 die ("Unsafe public key size: %d bits\n", key_bits); 744 } else { 745 if (public_key->type == EVP_PKEY_EC) 746 if(key_bits >= MIN_ECC_PUB_KEY_LEN 747 && key_bits <= MAX_ECC_PUB_KEY_LEN) 748 { 749 verb ("V: ECC key length appears safe\n"); 750 } else { 751 die ("Unsafe ECC key size: %d bits\n", key_bits); 752 } else { 753 verb ("V: key length appears safe\n"); 754 } 755 } 756 EVP_PKEY_free (public_key); 757 } 758 #endif 759 760 #ifdef USE_POLARSSL 761 void 762 inspect_key (ssl_context *ssl, const char *hostname) 763 { 764 verify_signature (ssl, hostname); 765 766 // ssl_get_verify_result() already checks for CN / subjectAltName match 767 // and reports the mismatch as error. So check_name() is not called 768 } 769 #else 770 void 771 inspect_key (SSL *ssl, const char *hostname) 772 { 773 774 verify_signature (ssl, hostname); 775 check_name (ssl, hostname); 776 } 777 #endif 778 779 #ifdef USE_POLARSSL 780 void 781 check_timestamp (uint32_t server_time) 782 { 783 uint32_t compiled_time = RECENT_COMPILE_DATE; 784 uint32_t max_reasonable_time = MAX_REASONABLE_TIME; 785 if (compiled_time < server_time 786 && 787 server_time < max_reasonable_time) 788 { 789 verb("V: remote peer provided: %d, preferred over compile time: %d\n", 790 server_time, compiled_time); 791 } else { 792 die("V: the remote server is a false ticker! server: %d compile: %d\n", 793 server_time, compiled_time); 794 } 795 } 796 797 static int ssl_do_handshake_part(ssl_context *ssl) 798 { 799 int ret = 0; 800 801 /* Only do steps till ServerHello is received */ 802 while (ssl->state != SSL_SERVER_HELLO) 803 { 804 ret = ssl_handshake_step (ssl); 805 if (0 != ret) 806 { 807 die("SSL handshake failed\n"); 808 } 809 } 810 /* Do ServerHello so we can skim the timestamp */ 811 ret = ssl_handshake_step (ssl); 812 if (0 != ret) 813 { 814 die("SSL handshake failed\n"); 815 } 816 817 return 0; 818 } 819 820 /** 821 * Run SSL handshake and store the resulting time value in the 822 * 'time_map'. 823 * 824 * @param time_map where to store the current time 825 */ 826 static void 827 run_ssl (uint32_t *time_map, int time_is_an_illusion) 828 { 829 entropy_context entropy; 830 ctr_drbg_context ctr_drbg; 831 ssl_context ssl; 832 proxy_polarssl_ctx proxy_ctx; 833 x509_cert cacert; 834 struct stat statbuf; 835 int ret = 0, server_fd = 0; 836 char *pers = "tlsdate-helper"; 837 838 memset (&ssl, 0, sizeof(ssl_context)); 839 memset (&cacert, 0, sizeof(x509_cert)); 840 841 verb("V: Using PolarSSL for SSL\n"); 842 if (ca_racket) 843 { 844 if (-1 == stat (ca_cert_container, &statbuf)) 845 { 846 die("Unable to stat CA certficate container %s\n", ca_cert_container); 847 } 848 else 849 { 850 switch (statbuf.st_mode & S_IFMT) 851 { 852 case S_IFREG: 853 if (0 > x509parse_crtfile(&cacert, ca_cert_container)) 854 fprintf(stderr, "x509parse_crtfile failed\n"); 855 break; 856 case S_IFDIR: 857 if (0 > x509parse_crtpath(&cacert, ca_cert_container)) 858 fprintf(stderr, "x509parse_crtpath failed\n"); 859 break; 860 default: 861 die("Unable to load CA certficate container %s\n", ca_cert_container); 862 } 863 } 864 } 865 866 entropy_init (&entropy); 867 if (0 != ctr_drbg_init (&ctr_drbg, entropy_func, &entropy, 868 (unsigned char *) pers, strlen(pers))) 869 { 870 die("Failed to initialize CTR_DRBG\n"); 871 } 872 873 if (0 != ssl_init (&ssl)) 874 { 875 die("SSL initialization failed\n"); 876 } 877 ssl_set_endpoint (&ssl, SSL_IS_CLIENT); 878 ssl_set_rng (&ssl, ctr_drbg_random, &ctr_drbg); 879 ssl_set_ca_chain (&ssl, &cacert, NULL, hostname_to_verify); 880 if (ca_racket) 881 { 882 // You can do SSL_VERIFY_REQUIRED here, but then the check in 883 // inspect_key() never happens as the ssl_handshake() will fail. 884 ssl_set_authmode (&ssl, SSL_VERIFY_OPTIONAL); 885 } 886 887 if (proxy) 888 { 889 char *scheme; 890 char *proxy_host; 891 char *proxy_port; 892 893 parse_proxy_uri (proxy, &scheme, &proxy_host, &proxy_port); 894 895 verb("V: opening socket to proxy %s:%s\n", proxy_host, proxy_port); 896 if (0 != net_connect (&server_fd, proxy_host, atoi(proxy_port))) 897 { 898 die ("SSL connection failed\n"); 899 } 900 901 proxy_polarssl_init (&proxy_ctx); 902 proxy_polarssl_set_bio (&proxy_ctx, net_recv, &server_fd, net_send, &server_fd); 903 proxy_polarssl_set_host (&proxy_ctx, host); 904 proxy_polarssl_set_port (&proxy_ctx, atoi(port)); 905 proxy_polarssl_set_scheme (&proxy_ctx, scheme); 906 907 ssl_set_bio (&ssl, proxy_polarssl_recv, &proxy_ctx, proxy_polarssl_send, &proxy_ctx); 908 909 verb("V: Handle proxy connection\n"); 910 if (0 == proxy_ctx.f_connect (&proxy_ctx)) 911 die("Proxy connection failed\n"); 912 } 913 else 914 { 915 verb("V: opening socket to %s:%s\n", host, port); 916 if (0 != net_connect (&server_fd, host, atoi(port))) 917 { 918 die ("SSL connection failed\n"); 919 } 920 921 ssl_set_bio (&ssl, net_recv, &server_fd, net_send, &server_fd); 922 } 923 924 verb("V: starting handshake\n"); 925 if (0 != ssl_do_handshake_part (&ssl)) 926 die("SSL handshake first part failed\n"); 927 928 uint32_t timestamp = ( (uint32_t) ssl.in_msg[6] << 24 ) 929 | ( (uint32_t) ssl.in_msg[7] << 16 ) 930 | ( (uint32_t) ssl.in_msg[8] << 8 ) 931 | ( (uint32_t) ssl.in_msg[9] ); 932 check_timestamp (timestamp); 933 934 verb("V: continuing handshake\n"); 935 /* Continue with handshake */ 936 while (0 != (ret = ssl_handshake (&ssl))) 937 { 938 if (POLARSSL_ERR_NET_WANT_READ != ret && 939 POLARSSL_ERR_NET_WANT_WRITE != ret) 940 { 941 die("SSL handshake failed\n"); 942 } 943 } 944 945 // Verify the peer certificate against the CA certs on the local system 946 if (ca_racket) { 947 inspect_key (&ssl, hostname_to_verify); 948 } else { 949 verb ("V: Certificate verification skipped!\n"); 950 } 951 check_key_length (&ssl); 952 953 memcpy (time_map, ×tamp, sizeof(uint32_t)); 954 proxy_polarssl_free (&proxy_ctx); 955 ssl_free (&ssl); 956 x509_free (&cacert); 957 } 958 #else /* USE_POLARSSL */ 959 /** 960 * Run SSL handshake and store the resulting time value in the 961 * 'time_map'. 962 * 963 * @param time_map where to store the current time 964 */ 965 static void 966 run_ssl (uint32_t *time_map, int time_is_an_illusion) 967 { 968 BIO *s_bio; 969 SSL_CTX *ctx; 970 SSL *ssl; 971 struct stat statbuf; 972 973 SSL_load_error_strings(); 974 SSL_library_init(); 975 976 ctx = NULL; 977 if (0 == strcmp("sslv23", protocol)) 978 { 979 verb ("V: using SSLv23_client_method()\n"); 980 ctx = SSL_CTX_new(SSLv23_client_method()); 981 } else if (0 == strcmp("sslv3", protocol)) 982 { 983 verb ("V: using SSLv3_client_method()\n"); 984 ctx = SSL_CTX_new(SSLv3_client_method()); 985 } else if (0 == strcmp("tlsv1", protocol)) 986 { 987 verb ("V: using TLSv1_client_method()\n"); 988 ctx = SSL_CTX_new(TLSv1_client_method()); 989 } else 990 die("Unsupported protocol `%s'\n", protocol); 991 992 if (ctx == NULL) 993 die("OpenSSL failed to support protocol `%s'\n", protocol); 994 995 verb("V: Using OpenSSL for SSL\n"); 996 if (ca_racket) 997 { 998 if (-1 == stat(ca_cert_container, &statbuf)) 999 { 1000 die("Unable to stat CA certficate container %s\n", ca_cert_container); 1001 } else 1002 { 1003 switch (statbuf.st_mode & S_IFMT) 1004 { 1005 case S_IFREG: 1006 if (1 != SSL_CTX_load_verify_locations(ctx, ca_cert_container, NULL)) 1007 fprintf(stderr, "SSL_CTX_load_verify_locations failed\n"); 1008 break; 1009 case S_IFDIR: 1010 if (1 != SSL_CTX_load_verify_locations(ctx, NULL, ca_cert_container)) 1011 fprintf(stderr, "SSL_CTX_load_verify_locations failed\n"); 1012 break; 1013 default: 1014 if (1 != SSL_CTX_load_verify_locations(ctx, NULL, ca_cert_container)) 1015 { 1016 fprintf(stderr, "SSL_CTX_load_verify_locations failed\n"); 1017 die("Unable to load CA certficate container %s\n", ca_cert_container); 1018 } 1019 } 1020 } 1021 } 1022 1023 if (NULL == (s_bio = make_ssl_bio(ctx))) 1024 die ("SSL BIO setup failed\n"); 1025 BIO_get_ssl(s_bio, &ssl); 1026 if (NULL == ssl) 1027 die ("SSL setup failed\n"); 1028 1029 if (time_is_an_illusion) 1030 { 1031 SSL_set_info_callback(ssl, openssl_time_callback); 1032 } 1033 1034 SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY); 1035 verb("V: opening socket to %s:%s\n", host, port); 1036 if ( (1 != BIO_set_conn_hostname(s_bio, host)) || 1037 (1 != BIO_set_conn_port(s_bio, port)) ) 1038 die ("Failed to initialize connection to `%s:%s'\n", host, port); 1039 1040 if (NULL == BIO_new_fp(stdout, BIO_NOCLOSE)) 1041 die ("BIO_new_fp returned error, possibly: %s", strerror(errno)); 1042 1043 // This should run in seccomp 1044 // eg: prctl(PR_SET_SECCOMP, 1); 1045 if (1 != BIO_do_connect(s_bio)) /* XXX TODO: BIO_should_retry() later? */ 1046 die ("SSL connection failed\n"); 1047 if (1 != BIO_do_handshake(s_bio)) 1048 die ("SSL handshake failed\n"); 1049 1050 // Verify the peer certificate against the CA certs on the local system 1051 if (ca_racket) { 1052 inspect_key (ssl, hostname_to_verify); 1053 } else { 1054 verb ("V: Certificate verification skipped!\n"); 1055 } 1056 check_key_length(ssl); 1057 // from /usr/include/openssl/ssl3.h 1058 // ssl->s3->server_random is an unsigned char of 32 bits 1059 memcpy(time_map, ssl->s3->server_random, sizeof (uint32_t)); 1060 SSL_free(ssl); 1061 SSL_CTX_free(ctx); 1062 } 1063 #endif /* USE_POLARSSL */ 1064 /** drop root rights and become 'nobody' */ 1065 1066 int 1067 main(int argc, char **argv) 1068 { 1069 uint32_t *time_map; 1070 struct tlsdate_time start_time, end_time, warp_time; 1071 int status; 1072 pid_t ssl_child; 1073 long long rt_time_ms; 1074 uint32_t server_time_s; 1075 int setclock; 1076 int showtime; 1077 int timewarp; 1078 int leap; 1079 1080 if (argc != 12) 1081 return 1; 1082 host = argv[1]; 1083 hostname_to_verify = argv[1]; 1084 port = argv[2]; 1085 protocol = argv[3]; 1086 ca_cert_container = argv[6]; 1087 ca_racket = (0 != strcmp ("unchecked", argv[4])); 1088 verbose = (0 != strcmp ("quiet", argv[5])); 1089 setclock = (0 == strcmp ("setclock", argv[7])); 1090 showtime = (0 == strcmp ("showtime", argv[8])); 1091 timewarp = (0 == strcmp ("timewarp", argv[9])); 1092 leap = (0 == strcmp ("leapaway", argv[10])); 1093 proxy = (0 == strcmp ("none", argv[11]) ? NULL : argv[11]); 1094 1095 if (timewarp) 1096 { 1097 1098 verb ("V: RECENT_COMPILE_DATE is %lu.%06lu\n", 1099 (unsigned long) CLOCK_SEC(&warp_time), 1100 (unsigned long) CLOCK_USEC(&warp_time)); 1101 1102 if (1 == setclock) { 1103 clock_init_time(&warp_time, RECENT_COMPILE_DATE, 0); 1104 } else { 1105 verb ("V: we'll do the time warp another time - we're not setting clock\n"); 1106 } 1107 } 1108 1109 /* We are not going to set the clock, thus no need to stay root */ 1110 if (0 == setclock && 0 == timewarp) 1111 { 1112 drop_privs_to (UNPRIV_USER, UNPRIV_GROUP, NULL); 1113 } 1114 /* 1115 XXX: KILL ME 1116 // We cast the mmap value to remove this error when compiling with g++: 1117 // src/tlsdate-helper.c: In function int main(int, char**): 1118 // src/tlsdate-helper.c:822:41: error: invalid conversion from void* to uint32_t 1119 time_map = (uint32_t *) mmap (NULL, sizeof (uint32_t), 1120 PROT_READ | PROT_WRITE, 1121 MAP_SHARED | MAP_ANONYMOUS, -1, 0); 1122 if (MAP_FAILED == time_map) 1123 { 1124 fprintf (stderr, "mmap failed: %s\n", 1125 strerror (errno)); 1126 return 1; 1127 } 1128 */ 1129 /* Get the current time from the system clock. */ 1130 if (0 != clock_get_real_time(&start_time)) 1131 { 1132 die ("Failed to read current time of day: %s\n", strerror (errno)); 1133 } 1134 1135 verb ("V: time is currently %lu.%06lu\n", 1136 (unsigned long) CLOCK_SEC(&start_time), 1137 (unsigned long) CLOCK_NSEC(&start_time)); 1138 1139 if (((unsigned long) CLOCK_SEC(&start_time)) < ((unsigned long) CLOCK_SEC(&warp_time))) 1140 { 1141 verb ("V: local clock time is less than RECENT_COMPILE_DATE\n"); 1142 if (timewarp) 1143 { 1144 verb ("V: Attempting to warp local clock into the future\n"); 1145 if (0 != clock_set_real_time(&warp_time)) 1146 { 1147 die ("setting time failed: %s (Attempted to set clock to %lu.%06lu)\n", 1148 strerror (errno), 1149 (unsigned long) CLOCK_SEC(&warp_time), 1150 (unsigned long) CLOCK_SEC(&warp_time)); 1151 } 1152 if (0 != clock_get_real_time(&start_time)) 1153 { 1154 die ("Failed to read current time of day: %s\n", strerror (errno)); 1155 } 1156 verb ("V: time is currently %lu.%06lu\n", 1157 (unsigned long) CLOCK_SEC(&start_time), 1158 (unsigned long) CLOCK_NSEC(&start_time)); 1159 verb ("V: It's just a step to the left...\n"); 1160 } 1161 } else { 1162 verb ("V: time is greater than RECENT_COMPILE_DATE\n"); 1163 } 1164 1165 /* initialize to bogus value, just to be on the safe side */ 1166 *time_map = 0; 1167 1168 /* Run SSL interaction in separate process (and not as 'root') */ 1169 ssl_child = fork (); 1170 if (-1 == ssl_child) 1171 die ("fork failed: %s\n", strerror (errno)); 1172 if (0 == ssl_child) 1173 { 1174 drop_privs_to (UNPRIV_USER, UNPRIV_GROUP, NULL); 1175 run_ssl (time_map, leap); 1176 /* 1177 XXX: should be a pipe close 1178 (void) munmap (time_map, sizeof (uint32_t)); 1179 */ 1180 _exit (0); 1181 } 1182 if (ssl_child != waitpid (ssl_child, &status, 0)) 1183 die ("waitpid failed: %s\n", strerror (errno)); 1184 if (! (WIFEXITED (status) && (0 == WEXITSTATUS (status)) )) 1185 die ("child process failed in SSL handshake\n"); 1186 1187 if (0 != clock_get_real_time(&end_time)) 1188 die ("Failed to read current time of day: %s\n", strerror (errno)); 1189 1190 /* calculate RTT */ 1191 rt_time_ms = (CLOCK_SEC(&end_time) - CLOCK_SEC(&start_time)) * 1000 + (CLOCK_USEC(&end_time) - CLOCK_USEC(&start_time)) / 1000; 1192 if (rt_time_ms < 0) 1193 rt_time_ms = 0; /* non-linear time... */ 1194 #ifdef USE_POLARSSL 1195 server_time_s = *time_map; 1196 #else 1197 server_time_s = ntohl (*time_map); 1198 #endif 1199 /* 1200 XXX: should be a pipe close 1201 munmap (time_map, sizeof (uint32_t)); 1202 */ 1203 verb ("V: server time %u (difference is about %d s) was fetched in %lld ms\n", 1204 (unsigned int) server_time_s, 1205 CLOCK_SEC(&start_time) - server_time_s, 1206 rt_time_ms); 1207 1208 /* warning if the handshake took too long */ 1209 if (rt_time_ms > TLS_RTT_THRESHOLD) { 1210 verb ("V: the TLS handshake took more than %d msecs - consider using a different " \ 1211 "server or run it again\n", TLS_RTT_THRESHOLD); 1212 } 1213 1214 if (showtime) 1215 { 1216 struct tm ltm; 1217 time_t tim = server_time_s; 1218 char buf[256]; 1219 1220 localtime_r(&tim, <m); 1221 if (0 == strftime(buf, sizeof buf, "%a %b %e %H:%M:%S %Z %Y", <m)) 1222 { 1223 die ("strftime returned 0\n"); 1224 } 1225 fprintf(stdout, "%s\n", buf); 1226 } 1227 1228 /* finally, actually set the time */ 1229 if (setclock) 1230 { 1231 struct tlsdate_time server_time; 1232 1233 clock_init_time(&server_time, server_time_s + (rt_time_ms / 2 / 1000), 1234 (rt_time_ms / 2) % 1000); 1235 1236 // We should never receive a time that is before the time we were last 1237 // compiled; we subscribe to the linear theory of time for this program 1238 // and this program alone! 1239 if (CLOCK_SEC(&server_time) >= MAX_REASONABLE_TIME) 1240 die("remote server is a false ticker from the future!\n"); 1241 if (CLOCK_SEC(&server_time) <= RECENT_COMPILE_DATE) 1242 die ("remote server is a false ticker!\n"); 1243 if (0 != clock_set_real_time(&server_time)) 1244 die ("setting time failed: %s (Difference from server is about %d s)\n", 1245 strerror (errno), 1246 CLOCK_SEC(&start_time) - server_time_s); 1247 verb ("V: setting time succeeded\n"); 1248 } 1249 return 0; 1250 } 1251