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, ×tamp, 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, <m);
1453 if (0 == strftime(buf, sizeof buf, "%a %b %e %H:%M:%S %Z %Y", <m))
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