opensslによるサーバー証明書失効リスト (CRL) 確認
以前 d:id:i_k_b:20090714:1247565189 で書いた情報に不足があったため補足。
openssl s_client サブコマンドは SSL 上で SMTP や POP、 HTTP を通すためのクライアントコマンドで、その際にサーバー証明書の検証が実施される。単純には下記コマンドで server.com の port ポートに接続して対話待ちに入る。
$ openssl s_client -connect server.com:port
HTTP を話しているならこれに以下を入力することでトップページのサイズや更新日などを取得でき(詳しくは HTTP プロトコルを参照)、あわせてサーバー証明書の検証がなされる。
HEAD / HTTP/1.0<改行> <改行>
ただし、この状態では PKI の信頼の基点となるルート証明機関 (CA: Certificate Authority) の証明書を参照しないため検証に失敗する。
CA 証明書を参照させるには -CApath オプション、あるいは -CAfile オプションを使う。規定では /usr/lib/ssl/certs/ ディレクトリーに有名どころの CA 証明書が配置されている。これを参照して、たとえば twitter.com のサーバー証明書を検証してみる。
$ openssl s_client -connect twitter.com:443 -CApath /usr/lib/ssl/certs << EOF > HEAD / HTTP/1.0 > > EOF
少々長くなるが、上記コマンドを実行すると以下の応答が返ってくる。
CONNECTED(00000003) depth=1 /C=US/O=Equifax Secure Inc./CN=Equifax Secure Global eBusiness CA-1 verify return:1 depth=0 /C=US/O=twitter.com/OU=GT09721236/OU=See www.rapidssl.com/resources/cps (c)09/OU=Domain Control Validated - RapidSSL(R)/CN=twitter.com verify return:1 --- Certificate chain 0 s:/C=US/O=twitter.com/OU=GT09721236/OU=See www.rapidssl.com/resources/cps (c)09/OU=Domain Control Validated - RapidSSL(R)/CN=twitter.com i:/C=US/O=Equifax Secure Inc./CN=Equifax Secure Global eBusiness CA-1 --- Server certificate -----BEGIN CERTIFICATE----- MIIDQzCCAqygAwIBAgIDC7XxMA0GCSqGSIb3DQEBBQUAMFoxCzAJBgNVBAYTAlVT MRwwGgYDVQQKExNFcXVpZmF4IFNlY3VyZSBJbmMuMS0wKwYDVQQDEyRFcXVpZmF4 IFNlY3VyZSBHbG9iYWwgZUJ1c2luZXNzIENBLTEwHhcNMDkwNTI2MTkzNDQ4WhcN MTAwNTI4MTY1ODEzWjCBsjELMAkGA1UEBhMCVVMxFDASBgNVBAoTC3R3aXR0ZXIu Y29tMRMwEQYDVQQLEwpHVDA5NzIxMjM2MTEwLwYDVQQLEyhTZWUgd3d3LnJhcGlk c3NsLmNvbS9yZXNvdXJjZXMvY3BzIChjKTA5MS8wLQYDVQQLEyZEb21haW4gQ29u dHJvbCBWYWxpZGF0ZWQgLSBSYXBpZFNTTChSKTEUMBIGA1UEAxMLdHdpdHRlci5j b20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAObNJ9AKUT3V3ls5J3Cxvs5R OqQO7h+DZ2aBppy2GZFPWza3rhnRk/PBIvasRx82aKL7rAFtVyXggivp32XVZwCy io74Br+cdVV7SgMwMhZgpUKsQTBwQ3InKuuczNyd9qdMF9t/TIf+HpfEXmHTxHIn fJYv8OT5zfE0Fl9iACjTAgMBAAGjgb0wgbowDgYDVR0PAQH/BAQDAgTwMB0GA1Ud DgQWBBQrGm3fNiHRrszg4IuqhAFAK6bWBzA7BgNVHR8ENDAyMDCgLqAshipodHRw Oi8vY3JsLmdlb3RydXN0LmNvbS9jcmxzL2dsb2JhbGNhMS5jcmwwHwYDVR0jBBgw FoAUvqigdHJQa0S3ySPY+6j/s1draGwwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsG AQUFBwMCMAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQEFBQADgYEAebTa/jX//SrR Gt8kccVQvohpKnegZC1HFSfgWfqSOEPjnQQQa7D65znFciw/fD4JS6vbphk5ZeXv jzyk27jdEvJ+02qwr22L2PpgJIndmyNeaBphp72PB604S82j29hfbfzmZy6LIiT8 DHwb3GjhBKhGy1+NLYyWV6T0UaQcLSk= -----END CERTIFICATE----- subject=/C=US/O=twitter.com/OU=GT09721236/OU=See www.rapidssl.com/resources/cps (c)09/OU=Domain Control Validated - RapidSSL(R)/CN=twitter.com issuer=/C=US/O=Equifax Secure Inc./CN=Equifax Secure Global eBusiness CA-1 --- No client certificate CA names sent --- SSL handshake has read 1403 bytes and written 316 bytes --- New, TLSv1/SSLv3, Cipher is DHE-RSA-AES256-SHA Server public key is 1024 bit Compression: NONE Expansion: NONE SSL-Session: Protocol : TLSv1 Cipher : DHE-RSA-AES256-SHA Session-ID: E04B582CC4E49B97EBB48D4EB32E53CFE435066E7BA34564FF22A0E852A910EF Session-ID-ctx: Master-Key: 6FA1F87C58175103277AB134E94C48F84B420B988683B578B73F580D582469104D4F775E8D2EF3280F2FB0CC3EDAB45B Key-Arg : None Start Time: 1263290066 Timeout : 300 (sec) Verify return code: 0 (ok) --- DONE
末尾行近くの "Verify return code: 0 (ok)" が、証明書が (ただしく) 検証できたというしるしである。
この時点でサーバー証明書について確認された事項は以下のとおりである。
- サブジェクト名
- 有効期間
- 証明書チェイン (信頼するルート CA 証明書までたどれる証明書であること)
サーバー証明書を厳密に確認するには、これに加えて「失効されていないこと」も見なければならない。サーバー証明書の失効とは、証明書を発行した機関が情報漏えいやハッキングその他の理由で発行済みの証明書を無効にすることで、 CRL (Certificate Revocation List) の公開という方法で失効が伝えられる。この証明書失効確認を追加するオプションが -crl_check および -crl_check_all である。 -crl_check は末端の証明書の失効確認を、 _all は証明書チェイン上の証明書すべての失効を確認するオプションである。
さて、先のコマンドに -crl_check_all オプションを追加して実行してみよう。
$ openssl s_client -connect twitter.com:443 -CApath /usr/lib/ssl/certs \ > -crl_check_all << EOF > HEAD / HTTP/1.0 > > EOF CONNECTED(00000003) (snip) Verify return code: 3 (unable to get certificate CRL)
-
- -
残念ながら失敗する。エラーコードが示すとおり、証明書失効リストが取得できないことが原因である。
ここで先の twitter.com の証明書に何が書かれているか見てみよう。
$ cat << EOF > twitter.pem > -----BEGIN CERTIFICATE----- > MIIDQzCCAqygAwIBAgIDC7XxMA0GCSqGSIb3DQEBBQUAMFoxCzAJBgNVBAYTAlVT > MRwwGgYDVQQKExNFcXVpZmF4IFNlY3VyZSBJbmMuMS0wKwYDVQQDEyRFcXVpZmF4 > IFNlY3VyZSBHbG9iYWwgZUJ1c2luZXNzIENBLTEwHhcNMDkwNTI2MTkzNDQ4WhcN > MTAwNTI4MTY1ODEzWjCBsjELMAkGA1UEBhMCVVMxFDASBgNVBAoTC3R3aXR0ZXIu > Y29tMRMwEQYDVQQLEwpHVDA5NzIxMjM2MTEwLwYDVQQLEyhTZWUgd3d3LnJhcGlk > c3NsLmNvbS9yZXNvdXJjZXMvY3BzIChjKTA5MS8wLQYDVQQLEyZEb21haW4gQ29u > dHJvbCBWYWxpZGF0ZWQgLSBSYXBpZFNTTChSKTEUMBIGA1UEAxMLdHdpdHRlci5j > b20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAObNJ9AKUT3V3ls5J3Cxvs5R > OqQO7h+DZ2aBppy2GZFPWza3rhnRk/PBIvasRx82aKL7rAFtVyXggivp32XVZwCy > io74Br+cdVV7SgMwMhZgpUKsQTBwQ3InKuuczNyd9qdMF9t/TIf+HpfEXmHTxHIn > fJYv8OT5zfE0Fl9iACjTAgMBAAGjgb0wgbowDgYDVR0PAQH/BAQDAgTwMB0GA1Ud > DgQWBBQrGm3fNiHRrszg4IuqhAFAK6bWBzA7BgNVHR8ENDAyMDCgLqAshipodHRw > Oi8vY3JsLmdlb3RydXN0LmNvbS9jcmxzL2dsb2JhbGNhMS5jcmwwHwYDVR0jBBgw > FoAUvqigdHJQa0S3ySPY+6j/s1draGwwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsG > AQUFBwMCMAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQEFBQADgYEAebTa/jX//SrR > Gt8kccVQvohpKnegZC1HFSfgWfqSOEPjnQQQa7D65znFciw/fD4JS6vbphk5ZeXv > jzyk27jdEvJ+02qwr22L2PpgJIndmyNeaBphp72PB604S82j29hfbfzmZy6LIiT8 > DHwb3GjhBKhGy1+NLYyWV6T0UaQcLSk= > -----END CERTIFICATE----- > EOF $ openssl x509 -noout -text -in twitter.pem Certificate: Data: Version: 3 (0x2) Serial Number: 767473 (0xbb5f1) Signature Algorithm: sha1WithRSAEncryption Issuer: C=US, O=Equifax Secure Inc., CN=Equifax Secure Global eBusiness CA-1 Validity Not Before: May 26 19:34:48 2009 GMT Not After : May 28 16:58:13 2010 GMT Subject: C=US, O=twitter.com, OU=GT09721236, OU=See www.rapidssl.com/resources/cps (c)09, OU=Domain Control Validated - RapidSSL(R), CN=twitter.com Subject Public Key Info: Public Key Algorithm: rsaEncryption RSA Public Key: (1024 bit) Modulus (1024 bit): 00:e6:cd:27:d0:0a:51:3d:d5:de:5b:39:27:70:b1: be:ce:51:3a:a4:0e:ee:1f:83:67:66:81:a6:9c:b6: 19:91:4f:5b:36:b7:ae:19:d1:93:f3:c1:22:f6:ac: 47:1f:36:68:a2:fb:ac:01:6d:57:25:e0:82:2b:e9: df:65:d5:67:00:b2:8a:8e:f8:06:bf:9c:75:55:7b: 4a:03:30:32:16:60:a5:42:ac:41:30:70:43:72:27: 2a:eb:9c:cc:dc:9d:f6:a7:4c:17:db:7f:4c:87:fe: 1e:97:c4:5e:61:d3:c4:72:27:7c:96:2f:f0:e4:f9: cd:f1:34:16:5f:62:00:28:d3 Exponent: 65537 (0x10001) X509v3 extensions: X509v3 Key Usage: critical Digital Signature, Non Repudiation, Key Encipherment, Data Encipherment X509v3 Subject Key Identifier: 2B:1A:6D:DF:36:21:D1:AE:CC:E0:E0:8B:AA:84:01:40:2B:A6:D6:07 X509v3 CRL Distribution Points: URI:http://crl.geotrust.com/crls/globalca1.crl X509v3 Authority Key Identifier: keyid:BE:A8:A0:74:72:50:6B:44:B7:C9:23:D8:FB:A8:FF:B3:57:6B:68:6C X509v3 Extended Key Usage: TLS Web Server Authentication, TLS Web Client Authentication X509v3 Basic Constraints: critical CA:FALSE Signature Algorithm: sha1WithRSAEncryption 79:b4:da:fe:35:ff:fd:2a:d1:1a:df:24:71:c5:50:be:88:69: 2a:77:a0:64:2d:47:15:27:e0:59:fa:92:38:43:e3:9d:04:10: 6b:b0:fa:e7:39:c5:72:2c:3f:7c:3e:09:4b:ab:db:a6:19:39: 65:e5:ef:8f:3c:a4:db:b8:dd:12:f2:7e:d3:6a:b0:af:6d:8b: d8:fa:60:24:89:dd:9b:23:5e:68:1a:61:a7:bd:8f:07:ad:38: 4b:cd:a3:db:d8:5f:6d:fc:e6:67:2e:8b:22:24:fc:0c:7c:1b: dc:68:e1:04:a8:46:cb:5f:8d:2d:8c:96:57:a4:f4:51:a4:1c: 2d:29
サーバー証明書失効リストは以下で配布されていることがわかる。
X509v3 CRL Distribution Points: URI:http://crl.geotrust.com/crls/globalca1.crl
これを保存し、失効リストストアを作成する。
$ mkdir crl $ pushd crl $ curl -O http://crl.geotrust.com/crls/globalca1.crl $ c_rehash . $ popd
openssl s_client サブコマンドの -CApath は : 区切りでディレクトリーを複数指定できるので、今作成した失効リストストアを追加して検証してみよう。
$ openssl s_client -connect twitter.com:443 \ > -CApath /usr/lib/ssl/certs:`pwd`/crl \ > -crl_check_all << EOF > HEAD / HTTP/1.0 > > EOF CONNECTED(00000003) (snip) Verify return code: 0 (ok)
-
- -
たしかに失効リストを使っての検証も通過した。