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, &timestamp, 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, &ltm);
1395      if (0 == strftime(buf, sizeof buf, "%a %b %e %H:%M:%S %Z %Y", &ltm))
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