curlとルート証明書

ブラウザではなくcurlでHTTPSのサイトにアクセスしてみよう。
curlを使うと、ブラウザでは見えないような細かい情報が表示される。今回は証明書について確認してみよう。

さて、以下のようにアクセスします。
 curl -v -I https://www.thinqa.net/
すると下記のような結果が表示されます。

# curl -v -I https://www.thinqa.net/
* About to connect() to www.thinqa.net port 443 (#0)
*   Trying 34.193.246.50... connected
* Connected to www.thinqa.net (34.193.246.50) port 443 (#0)
* Initializing NSS with certpath: sql:/etc/pki/nssdb
*   CAfile: /etc/pki/tls/certs/ca-bundle.crt
  CApath: none
* SSL connection using TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
* Server certificate:
* 	subject: CN=www.thinqa.net
* 	start date:  7月 29 21:48:29 2019 GMT
* 	expire date:  7月 30 14:59:59 2020 GMT
* 	common name: www.thinqa.net
* 	issuer: CN=FujiSSL Public Validation Authority - G3,O="SECOM Trust Systems CO.,LTD.",C=JP
> HEAD / HTTP/1.1
> User-Agent: curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.27.1 zlib/1.2.3 libidn/1.18 libssh2/1.4.2
> Host: www.thinqa.net「SECOM Trust Systems CO.,LTD.」
> Accept: */*
> 
< HTTP/1.1 200 OK
HTTP/1.1 200 OK

のようにしてアクセスしてみる。上記から「www.thinqa.net」の証明書は「FujiSSL Public Validation Authority – G3」に署名されており、さらにそれは「SECOM Trust Systems CO.,LTD.」に署名されていることが分かります。
つまりルート証明書は「SECOM Trust Systems CO.,LTD.」となります。
ではこの情報はどこにあるのかというと、上記コマンドにも記載されている/etc/pki/tls/certs/ca-bundle.crt です。ここに様々なルート証明書が記載されています。このルート証明書によって署名された証明書は「信頼できる」としているわけです。

試しに /etc/pki/tls/certs/ca-bundle.crt から「Security Communication RootCA2」を検索し、この証明書情報を削除します。(あとで戻せるよう必ずコピーは忘れずに)
そして再度下記でアクセスすると最初と応答が異なります。
「Peer’s certificate issuer is not recognized: ‘CN=FujiSSL Public Validation Authority – G3,O=”SECOM Trust Systems CO.,LTD.”,C=JP’」
と出ています。つまり「この証明書の署名者(つまり上で削除したSECOMの証明書)知らないよ」と言われて警告が出ています。
これがよくある「信頼できない証明書」と言われる状態です。

# curl -v -I https://www.thinqa.net/
* About to connect() to www.thinqa.net port 443 (#0)
*   Trying 34.193.246.50... connected

* Connected to www.thinqa.net (34.193.246.50) port 443 (#0)
* Initializing NSS with certpath: sql:/etc/pki/nssdb
*   CAfile: /etc/pki/tls/certs/ca-bundle.crt
  CApath: none
* Peer's certificate issuer is not recognized: 'CN=FujiSSL Public Validation Authority - G3,O="SECOM Trust Systems CO.,LTD.",C=JP'
* NSS error -8179
* Closing connection #0
* Peer certificate cannot be authenticated with known CA certificates
curl: (60) Peer certificate cannot be authenticated with known CA certificates
More details here: http://curl.haxx.se/docs/sslcerts.html

curl performs SSL certificate verification by default, using a "bundle"
 of Certificate Authority (CA) public keys (CA certs). If the default
 bundle file isn't adequate, you can specify an alternate file
 using the --cacert option.
If this HTTPS server uses a certificate signed by a CA represented in
 the bundle, the certificate verification probably failed due to a
 problem with the certificate (it might be expired, or the nSecurity Communication RootCA2ame might
 not match the domain name in the URL).
If you'd like to turn off curl's verification of the certificate, use
 the -k (or --insecure) option.

もちろん今は意図的にルート証明書を削除したので、こうなることは分かっています。この状態でもアクセスさせたいときは「-k」オプションを使用することで以下のように証明書のエラーを無視して普通にアクセスします。

# curl -k -v -I https://www.thinqa.net/
* About to connect() to www.thinqa.net port 443 (#0)
*   Trying 34.193.246.50... connected
* Connected to www.thinqa.net (34.193.246.50) port 443 (#0)
* Initializing NSS with certpath: sql:/etc/pki/nssdb
* warning: ignoring value of ssl.verifyhost
* skipping SSL peer certificate verification
* SSL connection using TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
* Server certificate:
* 	subject: CN=www.thinqa.net
* 	start date:  7月 29 21:48:29 2019 GMT
* 	expire date:  7月 30 14:59:59 2020 GMT
* 	common name: www.thinqa.net
* 	issuer: CN=FujiSSL Public Validation Authority - G3,O="SECOM Trust Systems CO.,LTD.",C=JP
> HEAD / HTTP/1.1
> User-Agent: curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.27.1 zlib/1.2.3 libidn/1.18 libssh2/1.4.2
> Host: www.thinqa.net
> Accept: */*
> 
< HTTP/1.1 200 OK