とあるアプリケーションにログインする際に、エラーが出て失敗する問題が発生した。

認証処理を行っているphpのlogには、以下のようなメッセージが吐かれている。

[11-Mar-2015 11:40:08] Got no response code when fetching  https://openid-xxxxx/
[11-Mar-2015 11:40:08] CURL error (60): SSL certificate problem, verify that the CA cert is OK.
Details: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed

このエラーは、アプリケーションのサーバーから、認証をするサーバー(openidを使っていた)に対してのcurlで、SSLの認証の失敗で出ているようだ。

手動でcurlを打った時のログがこれ。

$ curl https://openid-xxxxx/
curl: (60) SSL certificate problem, verify that the CA cert is OK. Details:
error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed
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). The default
bundle is named curl-ca-bundle.crt; 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 name 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.

原因は、SHA-1の証明書をSHA-2へ切り替えた事で、新しい証明書に対応したルート証明書がアプリケーションのサーバーになかったことだ。 (※ 単純なSHA-1からSHA-2の切り替えだけだとルート証明書を変えなくてもいいらしいが…?)

現象としてはちょうど一年くらい前にあった、古いOSにインストールされてたルート証明書の期限が切れた時と同じだ。(原因はちがうけど)

とにかく有効なルート証明書をアプリケーションのサーバーに入れないと解消できない。 自分を含めた古いOSをたいせつに(使う|使わざるを得ない)勢のいつかの期限切れのために、以下に更新方法を残しておく。

debianにはupdate-ca-certificatesというコマンドがあるので、manで内容を確認しつつ使ってみる。

$ man update-ca-certificate 
  1. 使ってる認証局(globalsignとかverisign)のルート証明書を手に入れる。拡張子は.crtに。
  2. /usr/share/ca-certificates以下に、1のxxxx.crt を置く。
  3. /etc/ca-certificates.confに、2のpathを書く
  4. update-ca-certificatesを実行して、更新
$ sudo update-ca-certificates
Updating certificates in /etc/ssl/certs... WARNING: Skipping duplicate certificate cacert.org.pem
WARNING: Skipping duplicate certificate ca-certificates.crt
1 added, 0 removed; done.
Running hooks in /etc/ca-certificates/update.d....done.

無事更新できたら、curlしてerrorが出ない事を確認。

$ curl https://openid-xxxxx/

ちなみに、更新したのにcurlで以下のようなエラーが出ることがある。

curl: (35) error:0D0C50A1:asn1 encoding routines:ASN1_item_verify:unknown message digest algorithm

調べると太古のバグっぽい。[ curl-Bugs-2825989 ] curl refuses sha-2 signed certificates

openssl系のパッケージをupdateすると、解消できた。

$ sudo apt-get install openssl