いつものように Thunderbird でメールをチェックしようとしたら、SSL 証明書の有効期限が切れているとの警告が出た。メールサーバには imapd-uw を使って SSL 経由で接続している。自分で運用して自分でしか使っていないサーバなので、使っている証明書は、認証局 (CA) も自前の、いわゆるオレオレ証明書というものだ。
imapd で使う証明書を自己証明書にしても良いのだが、認証局の運用の仕組みを知りたかったので、自前サーバ上で OpenSSL による認証局を立ち上げ、imapd で使う証明書に署名をする形にしている。認証局の証明書は自己証明書で有効期限は10年とし、imapd の証明書の有効期限は 1 年としている。
自己認証局で、署名をする機会などそうそうあるものではなく、openssl を実行することは実際のところ、年に1度になっている。当然のように前にやったことなど忘れてしまっているので、今回もそうであるが、期限が切れてから慌てることになる。とはいえ、期限を短くすれば面倒なだけであるし、期限を3年とかにしたら、思い出すのが不可能になってしまうかもしれないので、1年に1度の混乱は我慢することにしている。
作業のメモは当然作るわけだが、理解しないまま作業した結果がたまたまうまくいったとか (しかも試行錯誤をしたうえで)、当時は普通だったけど今では時代遅れになっているとか、実行環境が変わって昔のやり方ではできないとか、以前はなかった要因が今回は増えているとかあって、作業の見直しはいつでも必要になる。
完全に理解した上で正しい記録を残すのが望ましいが、そうもいってられないので、せめて、後からの検証に耐えうるように、実際の作業の内容と結果、確認したことと、未確認なことが判別できるような記述を心がけたいと思う。
今回の証明書の更新では、有効期限が切れた証明書の失効手続きを行う、という作業が必要になった。更新は今回が初めてではないはずだが、1年前の作業を調べてみると、その時は CA を作り直している。何か思うところがあって、やり直したのだろうが、そこのところはメモしていなかった。我ながら困ったものである。たぶんそれまでの CA の運営方法が間違っていると判断したのだろう。今回は、CA はそのままで、imapd 用の証明書の更新のみを行うことにする。
はじめに証明書の失効手続きを行う。期限切れの証明書と、新たに更新する証明書は、特に理由がない限りその識別名 (DN) は同じにすると思う。私もそうする。ところが、 CA で署名する際に、DN が同じだと署名に失敗してしまう。有効な証明書は DN 1つに付き1つしか存在できないらしい。当然といえば当然かもしれない。ただ、期限切れの証明書と失効した証明書は別物というのは注意が必要なのかもしれない。また、OpenSSL の署名時のエラーメッセージも適切でないと思う。’failed to update database’ では失敗の原因を誤解するではないか。
証明書の失効手続きが初めての時は、crlnumber というファイルがおそらく存在しない。そのときは、あらかじめ次のように crlnumber というファイルを作成しておかなければならない。このファイル名は openssl.conf の crlnumber で定義されていて、サンプルでは $dir/crlnumber となっている。たぶん、ファイルの中身は失効した証明書の個数を表しているのだろう。
$ echo "00" > crlnumber
crlnumber ができたら、証明書の失効手続きをおこなう。失効手続きは CA.sh でサポートされていないようなので、openssl コマンドを直接実行しなければならない。また、失効させる証明書の現物が必要である。通常の環境であれば index.txt に CA が署名した DN とシリアル番号の一覧がある (行頭が V となっているのが現在有効な証明書) ので、ここで失効させたいシリアル番号を確認しておく。例えばシリアル番号 01 の証明書を失効させたい場合、newcerts/01.pem というように過去に署名した証明書の控えが保存されているはずなので、このファイルを指定して次のように失効手続きを行う。
$ openssl ca -revoke newcerts/01.pem
Using configuration from /etc/openssl/openssl.cnf
Enter pass phrase for /home/moriko/Config/CA/private/cakey.pem:
Revoking Certificate 01.
Data Base Updated
失効すると、index.txt の該当箇所には R (Revoked) の印がつけられる(他の情報も記録される)。crlnumber の中の数字がインクリメントされる。
また、次のようにして失効した証明書のリストを更新する。imap-uw で失効した証明書を調べてくれるのかどうかは知らない。
$ openssl ca -gencrl -out crl.pem
これで新しい証明書を作成する準備ができたので、CA.sh を使って新しいリクエストを作成する。この手順はよく知られている。ただし、CA.sh を使った場合、作成される鍵 (newkey.pem) にはパスフレーズが要求されてしまう。これが都合が悪い場合は後述するように、後からパスフレーズを不要にした鍵に変換すれば良い。CA.pl だと -newreq-nodes オプションで、はじめからパスフレーズ不要の鍵とすることができる、らしい。
$ ./CA.sh -newreq
Generating a 1024 bit RSA private key
(略)
writing new private key to 'newkey.pem'
Enter PEM pass phrase:(パスフレーズの入力)
Verifying - Enter PEM pass phrase:(パスフレーズの入力)
(略)