S/MIME
S/MIME の機能を提供するために、Mew は GnuPG version 2に含まれる "gpgsm" を利用します。ただし、GnuPG version 2.0 はサポートしていますが、現時点では version 2.1 はサポートしていません。
以降の説明では、証明書(署名された公開鍵)と秘密鍵は、会社から支給されていると仮定します。それらは PKCS 12 と呼ばれる書式でファイルに格納されています。
構成
- "gpgsm" は、S/MIME を取り扱うプログラムです
- "gpg-agent" は、パスワードをキャッシュするデーモンです
- 'pinentry' は、ユーザにパスワードを尋ねるためのフロントエンドです。Mew は、"mew-pinentry" という独自のプログラムを提供しています。
- "dirmngr" は、CRL をキャッシュするデーモンです
gpgsm --> gpg-agent --> mew-pinentry --> ユーザ | +-----> dirmngr --> CRLサーバ
詳細は、Project Agyptenを参照して下さい。
- "gpgsm" と "gpg-agent" が必須です。両者は、GnuPG 2 のパッケージに含まれています
- "dirmngr" は必須ではありません。これは、別パッケージとなっています。
"dirmngr" は、現時点で私(山本)の環境では上手く動きません。
インストール
GnuPG 2 のパッケージを入手し、インストールして下さい。"gpgsm" と "gpg-agent" がインストールされるはずです。CRL を検査したいなら、"dirmngr" もインストールしましょう。
Mew の "bin" ディテクトリにある "mew-pinentry" もインストールして下さい。
"mew-pinentry" が "gpg-agent" から呼ばれるように、"~/.gnupg/gpg-agent.conf" に以下の行を追加して下さい。
pinentry-program /usr/local/bin/mew-pinentry
秘密鍵を秘密鍵リングに格納する
まず最初に、PKCS 12 のファイルを会社に入手して下さい。それには、証明書と秘密鍵が入っています。これを "keycert.p12" と呼ぶことにしましょう。
次に、"keycert.p12" を PEM 形式に直す必要があります。そのファイルを "keycert.pem" と呼びましょう。
% openssl pkcs12 -in keycert.p12 -out keycert.pem -nodes
そして、"keycert.p12" を暗号化しているパスフレーズを入力します。
次に、秘密鍵を取り出します。"key.p12" ファイルに取り出すことにしましょう。
% openssl pkcs12 -in keycert.pem -export -out key.p12 -nocerts -nodes
ここで、"key.p12" を暗号化するための一時的なパスフレーズを入力します。そして、確認のためにもう一度、一時的なパスフレーズを入力します。
秘密鍵を秘密鍵リングに格納します。
% gpg-agent --daemon gpgsm --call-protect-tool --p12-import --store key.p12
復号化のために、一時的なパスワードを入力します。そして、秘密鍵リングの中で、秘密鍵を暗号化するために、新しいパスフレーズを入力します。確認のために、もう一度、新しいパスフレーズを入力します。
公開鍵を公開鍵リングに格納する
証明書を "keycert.p12" から取り出します。"certs.pem" ファイルに取り出すことにしましょう。
% openssl pkcs12 -in keycert.p12 -out certs.pem -nokeys
ここで、"keycert.p12" を暗号化しているパスフレーズを入力します。
そして、この証明書を公開鍵リングに格納します。
% gpgsm --import certs.pem
ルート CA を信用させる
必要なルート CA の拇印(fingerprint)を "~/.gnupg/trustlist.txt" に格納します。
話は前後しますが、Mew で S/MIME の署名を検証すると、"~/.gnupg/pubring.kbx" に利用した証明書が自動的に登録されます。よって拇印の値は、以下のようにして調べることができます。
% gpgsm -kv Serial number: 7DD9FE07CFA81EB7107967FBA78934C6 Issuer: /OU=VeriSign Trust Network/OU=(c) 1998 VeriSign, Inc. - For authorized use only/OU=Class 3 Public Primary Certification Authority - G2/O=VeriSign , Inc./C=US Subject: /OU=VeriSign Trust Network/OU=(c) 1998 VeriSign, Inc. - For authorized use only/OU=Class 3 Public Primary Certification Authority - G2/O=VeriSign , Inc./C=US validity: 1998-05-18 00:00:00 through 2028-08-01 23:59:59 key type: 1024 bit RSA chain length: none fingerprint: 85:37:1C:A6:E5:50:14:3D:CE:28:03:47:1B:DE:3A:09:E8:F8:77:0F
上記のように、Issuer と Subject が完全に同じであれば、それがルート CA の証明書です。ルート CA の証明書の属性に "key usage" があれば証明書のバージョンは 3、なければ証明書のバージョンは 1 です。
ルート CA の証明書のバージョンが 3 の場合、捺印の値を単に "trustlist.txt" の一行に格納します。ルート CA の証明書のバージョンが 1 の場合、拇印の最後に " S relax" と書く必要があります。
たとえば、上記のルート CA の証明書のバージョンは 1 なので、これを信用するには、以下のような行を "trustlist.txt" に書くことになります。
85:37:1C:A6:E5:50:14:3D:CE:28:03:47:1B:DE:3A:09:E8:F8:77:0F S relax
検証
"gpgsm" と "gpg-agent" がうまく動いているか確かめるために、以下のようにして分離署名を作ってみて下さい。
% gpgsm --detach-sign file > sig
ここで、秘密鍵を暗号化しているパフレーズを入力します。
以下のような警告が表示されるかもしれません。
dirmngr[nnnn]: no CRL available for issuer id NNNNN....
これは、CRL サーバが動いていないか、CRL サーバから CRL ファイルが入手できないためです。
このように "dirmngr" とうまく連動できないなら、とりあえず CRL の検査を無効にしましょう。以下の行を "~/.gnupg/gpgsm.conf" に入れて下さい。
disable-crl-checks
そして、もう一度、以下のコマンドを実行します。
% gpgsm --detach-sign file > sig
ここで、秘密鍵を暗号化しているパフレーズを入力します。
分離署名ができたら、成功です。
分離署名を検証するには、以下のようにします。
% gpgsm --verify sig file
Mew から S/MIME を使う
添付領域のパートに "SS" マーク (S/MIME 署名) を付けるには、'M-s' とタイプします。
添付領域のパートに "SE" マーク (S/MIME 暗号) を付けるには、'M-e' とタイプします。
'C-cC-s'、'C-cC-e'、'C-cC-b' および 'C-cC-r' を(PGP 用ではなく) S/MIME 用に使いたいなら、以下のように設定します。
(setq mew-draft-privacy-method 'smime)
以下の値を 'mew-protect-privacy-always-type' に設定することも可能です。
- smime-signature
- smime-encryption
- smime-signature-encryption
- smie-encryption-signature
たとえば、'C-cC-c' か 'C-cC-m' を押してメッセージを作成する際に、常に S/MIME の署名を付けたいなら、以下のように設定します。
(setq mew-protect-privacy-always t) (setq mew-protect-privacy-always-type 'smime-signature)
gpg-agent
Mew には、パスフレーズをキャッシュする機能があるので、"gpg-agent" をデーモンとして起動しておく必要はないでしょう。ただ、"gpgsm" をコマンドラインから実行し、パスフレーズの入力を省略したいと思うなら、以下のようにして "gpg-agent" を起動して下さい。
% gpg-agent --use-standard-socket --daemon
こうすれば、"gpgsm" をどこで実行しても構いません。("gpgsm" を "gpg-agent" の子プロセスとして起動する必要はありません。)
備考
- 繰り返しになりますが、"dirmngr" は、私の環境ではうまく動作しません。