MacにTLS1.3とHTTP/2で通信可能なcurlをインストールした手順

Mac標準のcurlはLibreSSLとリンクしているが、現在手元にインストールされているバージョンだとTLS1.3を指定して通信することはできない。

```
$ /usr/bin/curl --version
curl 7.54.0 (x86_64-apple-darwin18.0) libcurl/7.54.0 LibreSSL/2.6.5 zlib/1.2.11 nghttp2/1.24.1
Protocols: dict file ftp ftps gopher http https imap imaps ldap ldaps pop3 pop3s rtsp smb smbs smtp smtps telnet tftp
Features: AsynchDNS IPv6 Largefile GSS-API Kerberos SPNEGO NTLM NTLM_WB SSL libz HTTP2 UnixSockets HTTPS-proxy

$ /usr/bin/curl https://www.instart.com --tlsv1.3 --http2
curl: (4) LibreSSL was built without TLS 1.3 support
```

TLS1.3に対応しているOpenSSL1.1を使用したcurlをインストールすることで、TLS1.3通信が可能になるのだけど、インストールに苦戦したのでメモしておく。

Macの場合、curlは`brew install curl`または`brew install curl-openssl`でインストールできるが、これでインストールしたcurlはTLS1.3に未対応のOpenSSL1.0系にリンクしてしまう。この時`--tlsv1.3`オプションを指定してもエラーにならないが無視されてしまい、TLS1.2などで接続されてしまう。

OpenSSL 1.1は`brew install openssl`ではなく`brew install openssl@1.1`でインストールできるが、`/usr/local/opt/openssl@1.1`という別ディレクトリーにインストールされることもあり、この後curlをインストールしても1.0の方が使用されてしまう。また、他のbrewでインストールしたライブラリーが1.0系を参照していることもあり、1.0をアンインストールしてもうまくいかなかった。`openssl@1.1`を`1.0`と同一ディレクトリーに上書きできるなら解決しそうな気もするのだけど、できるのだろうか？

仕方ないのでcurlのソースをダウンロードしてビルドするが、下記のように、1.1側を参照させるような環境変数設定をがんばって行っても、なぜか1.0とリンクしてしまう。

```bash
$ export CPPFLAGS="-I/usr/local/opt/openssl@1.1/include"
$ export LDFLAGS="-L/usr/local/opt/openssl@1.1/lib"
$ export PKG_CONFIG_PATH="/usr/local/opt/openssl@1.1/lib/pkgconfig"
$ ./configure --with-nghttp2=/usr/local/opt/nghttp2 --with-brotli --without-darwinssl --with-ssl="/usr/local/opt/openssl@1.1" CPPFLAGS="-I/usr/local/opt/openssl@1.1/include" CFLAGS="-I/usr/local/opt/openssl@1.1/include"
```

config.logを見ると、`checking for OpenSSL headers version`の結果が1.0.2になってしまうことがわかった。バージョン確認がどのように行われているかを調べたところ、`#include <openssl/crypto.h>`して定数OPENSSL_VERSION_NUMBERの値をチェックしている。

ここで、なぜかCPPFLAGSで指定したディレクトリーではなく、`-I/opt/local/include`が追加されており、`-isystem`より`-I`が優先されるため、1.0系が入っている`/opt/local/include/openssl/cypto.h`の方が優先で参照されてしまっていた。

```bash
gcc -E -isystem /usr/local/opt/openssl@1.1/include -I /opt/local/include  -I/usr/local/Cellar/openssl@1.1/1.1.1c/include    conftest.c
```

configureの20703行目あたりでzlibライブラリーの場所を確認するために実行したpkg-configコマンドの戻り値が-Iを使っていることが判明したため、-isystemに置き換えたところ、無事1.1.1cとリンクしてTLS1.3通信が可能になった。

```bash
#      CPPFLAGS="$CPPFLAGS `$PKGCONFIG --cflags-only-I zlib`"
      CPPFLAGS="$CPPFLAGS -isystem /opt/local/include" 
```

```
$ /usr/local/bin/curl --version
curl 7.65.3 (x86_64-apple-darwin18.7.0) libcurl/7.65.3 OpenSSL/1.1.1c zlib/1.2.11 brotli/1.0.7 libidn2/2.2.0 nghttp2/1.39.1 librtmp/2.3
Release-Date: 2019-07-19
Protocols: dict file ftp ftps gopher http https imap imaps ldap ldaps pop3 pop3s rtmp rtsp smb smbs smtp smtps telnet tftp
Features: AsynchDNS brotli HTTP2 HTTPS-proxy IDN IPv6 Largefile libz NTLM NTLM_WB SSL TLS-SRP UnixSockets

$ /usr/local/bin/curl -v https://www.instart.com -o/dev/null --tlsv1.3 --http2
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0*   Trying 159.180.93.29:443...
* TCP_NODELAY set
* Connected to www.instart.com (159.180.93.29) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
*   CAfile: /etc/ssl/cert.pem
  CApath: none
} [5 bytes data]
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
} [512 bytes data]
* TLSv1.3 (IN), TLS handshake, Server hello (2):
{ [122 bytes data]
* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
{ [19 bytes data]
* TLSv1.3 (IN), TLS handshake, Certificate (11):
{ [2820 bytes data]
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
{ [264 bytes data]
* TLSv1.3 (IN), TLS handshake, Finished (20):
{ [52 bytes data]
* TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
} [1 bytes data]
* TLSv1.3 (OUT), TLS handshake, Finished (20):
} [52 bytes data]
* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384
* ALPN, server accepted to use h2
* Server certificate:
*  subject: C=US; ST=California; L=Palo Alto; O=Instart Logic, Inc.; OU=IT Department; CN=*.instart.com
*  start date: Jan 21 00:00:00 2019 GMT
*  expire date: Jan 29 12:00:00 2020 GMT
*  subjectAltName: host "www.instart.com" matched cert's "*.instart.com"
*  issuer: C=US; O=DigiCert Inc; CN=DigiCert SHA2 Secure Server CA
*  SSL certificate verify ok.
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0* Using HTTP2, server supports multi-use
* Connection state changed (HTTP/2 confirmed)
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
} [5 bytes data]
* Using Stream ID: 1 (easy handle 0x7fea5500b600)
} [5 bytes data]
> GET / HTTP/2
> Host: www.instart.com
> User-Agent: curl/7.65.3
> Accept: */*
>
{ [5 bytes data]
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
{ [289 bytes data]
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
{ [273 bytes data]
* old SSL session ID is stale, removing
{ [5 bytes data]
* Connection state changed (MAX_CONCURRENT_STREAMS == 128)!
} [5 bytes data]
  0     0    0     0    0     0      0      0 --:--:--  0:00:01 --:--:--     0< HTTP/2 200
< content-type: text/html; charset=UTF-8
< content-length: 77762
< x-type: default
< accept-ranges: bytes
< x-pingback: https://instart.wpengine.com/xmlrpc.php
< cache-control: max-age=600, must-revalidate
< x-pass-why:
< vary: Accept-Encoding
< vary: Accept-Encoding
< vary: Accept-Encoding,Cookie
< x-cacheable: SHORT
< x-cache-group: normal
< link: <https://instart.wpengine.com/wp-json/>; rel="https://api.w.org/"
< server: nginx
< wpe-backend: apache
< date: Wed, 24 Jul 2019 01:30:21 GMT
< x-cache: HIT: 26
< x-instart-request-id: 5606122923514061747:UXT01-CPVNPPRY16:1563931821:0
<
{ [15820 bytes data]
100 77762  100 77762    0     0  36714      0  0:00:02  0:00:02 --:--:-- 36714
* Connection #0 to host www.instart.com left intact
```

疲れすぎたのでissueを書こうとしたけどKNOWN BUSに似たようなのがあった。
https://curl.haxx.se/docs/knownbugs.html#configure_finding_libs_in_wrong