一汁三菜

インターネットのインフラよりな技術の話題、Web周りの技術的な話題、趣味のマラソン、旅行、その他日々の記録をしています。

ntpdateを置き換えようとするtlsdate

ntpに脆弱性が発見されました。NTPのSecurity Noticeのページによれば、軽微な脆弱性がまだ2件残されているそうです。

それに呼応して、Don't update NTP – stop using it - Hanno's blog、「NTPを捨ててtlsdateを使おう」という主張を見かけました。今回の脆弱性の原因はバッファーオーバーフローや実装ミスにあるのでNTPというプロトコル自体が悪い訳では無いのですが、この機会にsecureなプロトコル&ソフトウェアを利用するようにしよう、という主張のようです。今までtlsdateなる物を知らなかったので、はてどんな物なのかと思いソースコードをあさってみました。ソースコードgithubリポジトリがあります。

tlsdateの仕組みはこんな感じです。TLSでは通信路確立時に、まずクライアントがサーバーに対してClientHelloメッセージを送信します。するとサーバからServerHelloメッセージが返ってくるのですが、そのメッセージにはgmt_unix_timeフィールドに現在時刻が含まれているので、これを時刻合わせに用います。このあたりの処理は、tlsdate-helper.cのrun_ssl()に書かれています。肝心の箇所を以下に引用します。

  if (0 != ssl_do_handshake_part (&ssl))
    die("SSL handshake first part failed");

  uint32_t timestamp = ( (uint32_t) ssl.in_msg[6] << 24 )
                     | ( (uint32_t) ssl.in_msg[7] << 16 )
                     | ( (uint32_t) ssl.in_msg[8] <<  8 )
                     | ( (uint32_t) ssl.in_msg[9]       );
  check_timestamp (timestamp);

もちろん単純にServerHelloに入っている時刻をそのまま利用するとパケットの送信遅延によりズレが生じてしまうので、RTTの計測も別途行われています。

なお、ChromeOSでは、既にtlsdateがデフォルトのnetwork time clientとして利用されているようです。