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