LibreSSL の TLS1.3 サポート

# はじめに

[LibreSSL](https://www.libressl.org/) は [OpenBSD プロジェクト](https://www.openbsd.org/) によってメンテナンスされている TLS/SSL 通信用ライブラリです。
2020/4/8 に最新の開発版 (development release) 3.1.0 がリリースされ、このバージョンでクライアント側の TLS1.3 がサポートされました。
<font color="Red">
(追記) 2020/5/31 に最新の開発版 (development release) 3.2.0 がリリースされ、サーバー側の TLS1.3 も有効となりました。
</font>
<font color="Red">
(追記) 2020/8/17 に最新の安定版 (stable release) 3.1.4 がリリースされました。
TLSv1.3 クライアントでの問題が修正されています。
</font>
<strike>(追記) 2020/6/15 に最新の安定版 (stable release) 3.1.3 がリリースされました。
3.1.3 で 2020/5/30 に発生した AddTrust External CA Root の有効期限切れで発覚した問題への対応がなされています。
詳細はこのコミットを参照：[OpenBSD 6.7 errata 010, June 11, 2020 (6.7/010_x509.patch.sig)](https://github.com/libressl-portable/openbsd/commit/379d8eb40afacd377874ca6cadc8fb71926c512c)</strike>
<strike>(追記) 2020/5/20 に最新の安定版 (stable release) 3.1.2 がリリースされました。</strike>
<strike>(追記) 2020/5/7 に最新の安定版 (stable release) 3.1.1 がリリースされました。</strike>
</font>
この記事ではこの最新版の LibreSSL を使って TLS1.3 での通信を確認します。

関連する過去の記事はこちらです。
- [LibreSSL の意義](https://qiita.com/kinichiro/items/3108e950b056963c33ad) 
- [LibreSSL の現在（2018年2月時点）](https://qiita.com/kinichiro/items/c06692d81c175516e3cf)
- [LibreSSL TLS1.3 対応状況（2019年12月時点）](https://qiita.com/kinichiro/items/60b0e284ea6645bc4384)

# ダウンロード

https://ftp.openbsd.org/pub/OpenBSD/LibreSSL/ から libressl-3.1.0.tar.gz をダウンロードします。

```shell-session
$ curl -O https://ftp.openbsd.org/pub/OpenBSD/LibreSSL/libressl-3.1.0.tar.gz
```

同じ所に置いてある public key と signature file もダウンロードして signify でチェックしておきます。

```shell-session
$ curl -O https://ftp.openbsd.org/pub/OpenBSD/LibreSSL/libressl.pub
$ curl -O https://ftp.openbsd.org/pub/OpenBSD/LibreSSL/SHA256.sig
$ signify -C -p libressl.pub -x SHA256.sig libressl-3.1.0.tar.gz
Signature Verified
libressl-3.1.0.tar.gz: OK
$
```

# ビルドとインストール

## unix系システムの場合

ダウンロードした libressl-3.1.0.tar.gz を展開して、展開したディレクトリに移動します。

```shell-session
$ tar zxf libressl-3.1.0.tar.gz
$ cd libressl-3.1.0
```

`configure` を実行してビルドの準備をします。今回はインストール先をホームディレクトリ配下の libressl-3.1.0/ としたいので以下のように `--prefix` オプションで指定しました。

```shell-session
$ ./configure --prefix=$HOME/libressl-3.1.0
checking build system type... x86_64-unknown-openbsd6.6
checking host system type... x86_64-unknown-openbsd6.6
...
config.status: executing depfiles commands
config.status: executing libtool commands
```

make を実行します。

```shell-session
$ make check
Making check in crypto
...
Testsuite summary for libressl 3.1.0
============================================================================
# TOTAL: 76
# PASS:  76
# SKIP:  0
# XFAIL: 0
# FAIL:  0
# XPASS: 0
# ERROR: 0
============================================================================
Making check in man
```

インストールします。

```shell-session
$ make install
```

以上でビルドとインストールが完了しました。

## Windows の場合

Windows の場合 Visual Studio と cmake が必要です。以下は cmake 3.16.5 と Visual Studio 2019 を使った場合の例です。

ダウンロードした libressl-3.1.0.tar.gz を展開してその配下に build というディレクトリを作り、そこに移動します。

```shell-session
C:\work> cd libressl-3.1.0
C:\work\libressl-3.1.0> mkdir build
C:\work\libressl-3.1.0> cd build
```

cmake を実行してビルドの準備をします。以下の例ではインストール先を C:\libressl-3.1.0 としています。またルート証明書 (`cert.pem`) や設定ファイル (`openssl.cnf`) のデフォルトの置き場所を指定するため `-DOPENSSLDIR` オプションを使っています。指定しない場合はデフォルトの置き場所が C:/Windows/libressl/ssl に設定されます。

```shell-session
C:\work\libressl-3.1.0\build> cmake -G "Visual Studio 16 2019" -DCMAKE_INSTALL_PREFIX=C:\libressl-3.1.0 -DOPENSSLDIR=C:\libressl-3.1.0\etc\ssl ..
```

ビルドを実行します。

```shell-session
C:\work\libressl-3.1.0\build> cmake --build .
```

テストを実行します。

```shell-session
C:\work\libressl-3.1.0\build> cmake --build . --target RUN_TESTS
```

上の例ではコマンドラインからビルドもテストも行いましたが、build 配下に作られる `LibreSSL.sln` をダブルクリックして Visual Studio を起動してビルドやテスト実行を行うこともできます。

インストールします。

```shell-session
C:\work\libressl-3.1.0\build> cmake --build . --target INSTALL
```

以上で Windows でのビルドとインストールが完了しました。

# TLS1.3 で通信テスト

インストールした LibreSSL 3.1.0 を使って TLS1.3 での通信をテストしてみます。

コマンドが実行できるようにパスを通しておきます。

```shell-session
$ PATH=$HOME/libressl-3.1.0/bin:$PATH
```

Facebook へのテスト接続例。

```shell-session
$ openssl s_client -connect www.facebook.com:443
CONNECTED(00000003)
depth=2 C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert High Assurance EV Root CA
verify return:1
depth=1 C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert SHA2 High Assurance Server CA
verify return:1
depth=0 C = US, ST = California, L = Menlo Park, O = "Facebook, Inc.", CN = *.facebook.com
verify return:1
write W BLOCK
---
Certificate chain
 0 s:/C=US/ST=California/L=Menlo Park/O=Facebook, Inc./CN=*.facebook.com
   i:/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert SHA2 High Assurance Server CA
 1 s:/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert SHA2 High Assurance Server CA
   i:/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert High Assurance EV Root CA
---
Server certificate
-----BEGIN CERTIFICATE-----
MIIGODCCBSCgAwIBAgIQB44/9grw+eCzj2yyeoJp3DANBgkqhkiG9w0BAQsFADBw
... (略) ...
c+R+hkD5C1QvtmS165/s0ClJFeHQkQbiH+HF/DkVPydCF7hfmH3bJyl2Zb4UMa9u
VA+RiPCb2qVM2m4h
-----END CERTIFICATE-----
subject=/C=US/ST=California/L=Menlo Park/O=Facebook, Inc./CN=*.facebook.com
issuer=/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert SHA2 High Assurance Server CA
---
No client certificate CA names sent
---
SSL handshake has read 3139 bytes and written 343 bytes
---
New, TLSv1/SSLv3, Cipher is AEAD-CHACHA20-POLY1305-SHA256
Server public key is 256 bit
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
    Protocol  : TLSv1.3
    Cipher    : AEAD-CHACHA20-POLY1305-SHA256
    Session-ID:
    Session-ID-ctx:
    Master-Key:
    Start Time: 1586412181
    Timeout   : 7200 (sec)
    Verify return code: 0 (ok)
---
```

Google への接続例。

```shell-session
$ openssl s_client -connect www.google.com:443 -servername www.google.com
CONNECTED(00000003)
depth=2 OU = GlobalSign Root CA - R2, O = GlobalSign, CN = GlobalSign
verify return:1
depth=1 C = US, O = Google Trust Services, CN = GTS CA 1O1
verify return:1
depth=0 C = US, ST = California, L = Mountain View, O = Google LLC, CN = www.google.com
verify return:1
write W BLOCK
---
Certificate chain
 0 s:/C=US/ST=California/L=Mountain View/O=Google LLC/CN=www.google.com
   i:/C=US/O=Google Trust Services/CN=GTS CA 1O1
 1 s:/C=US/O=Google Trust Services/CN=GTS CA 1O1
   i:/OU=GlobalSign Root CA - R2/O=GlobalSign/CN=GlobalSign
---
Server certificate
-----BEGIN CERTIFICATE-----
MIIEvzCCA6egAwIBAgIQY6KU5rvg96MCAAAAAF+YvzANBgkqhkiG9w0BAQsFADBC
... (略) ...
W3JUShEXgvk3gVt61l61pRDwlQo/b8k+OP/i16Cv1GswrXnfHIU7lMrT75vJIK5B
m+3yt3dbfICDE5/NEJKnzPn0gg==
-----END CERTIFICATE-----
subject=/C=US/ST=California/L=Mountain View/O=Google LLC/CN=www.google.com
issuer=/C=US/O=Google Trust Services/CN=GTS CA 1O1
---
No client certificate CA names sent
---
SSL handshake has read 2631 bytes and written 382 bytes
---
New, TLSv1/SSLv3, Cipher is AEAD-AES256-GCM-SHA384
Server public key is 256 bit
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
    Protocol  : TLSv1.3
    Cipher    : AEAD-AES256-GCM-SHA384
    Session-ID:
    Session-ID-ctx:
    Master-Key:
    Start Time: 1586412377
    Timeout   : 7200 (sec)
    Verify return code: 0 (ok)
---
```

以上のように TLS1.3 での接続ができていることを確認できました。

# まとめ

LibreSSL の最新の開発版 3.1.0 を使って TLS1.3 でのクライアント接続を確認しました。現在のところクライアント側のみ TLS1.3 対応されておりサーバー側は未対応ですが、今後対応がなされたらまた確認を行います。

OpenBSD プロジェクトは寄付を募ってます。
メールアドレス指定で日本からでもPayPalでの寄付ができます。
詳しくはこちら： https://www.openbsd.org/donations.html もしくは http://www.openbsdfoundation.org/donations.html