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