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@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.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
99 static void
validate_proxy_scheme(const char * scheme)100 validate_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
111 static void
validate_proxy_host(const char * host)112 validate_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
122 static void
validate_proxy_port(const char * port)123 validate_proxy_port(const char *port)
124 {
125 while (*port)
126 if (!isdigit((int)(unsigned char)*port++))
127 die("invalid char in port");
128 }
129
130 static void
parse_proxy_uri(char * proxy,char ** scheme,char ** host,char ** port)131 parse_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
155 static void
setup_proxy(BIO * ssl)156 setup_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
182 static int
write_all_to_ssl(SSL * ssl,const char * string)183 write_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. */
205 static const char *
sanitize_string(const char * s)206 sanitize_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
216 static int
handle_date_line(const char * dateline,uint32_t * result)217 handle_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
300 static int
read_http_date_from_ssl(SSL * ssl,uint32_t * result)301 read_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' */
331 static void *
xmalloc(size_t size)332 xmalloc (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' */
348 static void
xfree(void * ptr)349 xfree (void *ptr)
350 {
351 if (NULL == ptr)
352 die("xfree: NULL pointer given as argument");
353
354 free(ptr);
355 }
356
357 void
openssl_time_callback(const SSL * ssl,int where,int ret)358 openssl_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
391 static const char *
key_type_to_str(int key_type)392 key_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
429 uint32_t
get_certificate_keybits(EVP_PKEY * public_key)430 get_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
451 uint32_t
dns_label_count(char * label,char * delim)452 dns_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
488 uint32_t
check_wildcard_match_rfc2595(const char * orig_hostname,const char * orig_cert_wild_card)489 check_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 */
600 uint32_t
check_cn(SSL * ssl,const char * hostname)601 check_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 */
647 uint32_t
check_san(SSL * ssl,const char * hostname)648 check_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
744 uint32_t
check_name(SSL * ssl,const char * hostname)745 check_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
761 uint32_t
verify_signature(ssl_context * ssl,const char * hostname)762 verify_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
795 uint32_t
verify_signature(SSL * ssl,const char * hostname)796 verify_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
825 void
check_key_length(ssl_context * ssl)826 check_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
858 void
check_key_length(SSL * ssl)859 check_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
898 void
inspect_key(ssl_context * ssl,const char * hostname)899 inspect_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
907 void
inspect_key(SSL * ssl,const char * hostname)908 inspect_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
917 void
check_timestamp(uint32_t server_time)918 check_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
ssl_do_handshake_part(ssl_context * ssl)934 static 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 */
966 static void
run_ssl(uint32_t * time_map,int time_is_an_illusion,int http)967 run_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 */
1108 static void
run_ssl(uint32_t * time_map,int time_is_an_illusion,int http)1109 run_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
1229 int
main(int argc,char ** argv)1230 main(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