仙石浩明の日記

2006年8月15日

stone の SSL 認証 (3)

前々回前回で 説明したように、 stone で 通信相手の SSL 認証を行なうには、 通信相手がクライアントの時 (クライアント認証) は、

-z verify -z CApath=ディレクトリ

という設定で実行し、通信相手がサーバの時 (サーバ認証) は、

-q verify -q CApath=ディレクトリ

という設定で実行する。 「CApath=...」で指定したディレクトリに、 root CA 証明書を「ハッシュ値.数字」という形式のファイル名で 置いておくことにより、 通信相手が提示した証明書を検証することができ、 検証に成功したときのみ通信を許可する、 などのアクセス制限を行なうことができる。

ある root CA が発行した証明書、 あるいはその root CA の子, 孫, ... CA が発行した証明書、 いずれの証明書でも内容を問わず通信を許可して構わないのであれば、 これ以上の設定は不要であるが、 現実問題としては正規の証明書であれば何でも OK というケースは稀だろう。

メジャーな root CA だと、沢山の子 CA を持ち、 それぞれの子がさらに沢山の孫 CA を持っていたりする。 root CA 以外の CA を中間 CA と呼ぶが、 沢山の中間 CA がそれぞれ沢山の証明書を発行しているわけであるから、 その証明書の全てを許可していては、 不特定多数との通信を許可するのと大差ない。

そこで SSL 認証では、証明書を検証するだけでなく、 証明書の内容をも確認することが必要となる。 stone では証明書の識別名が満たすべき条件を正規表現の形で指定することができる。 証明書の識別名とは、例えば次のようなものである:

C=JP
ST=Kanagawa
L=Kawasaki
O=GCD
OU=Hiroaki Sengoku
CN=test
emailAddress=sengoku@gcd.org

これを「/」で区切って一行にした文字列:

/C=JP/ST=Kanagawa/L=Kawasaki/O=GCD/OU=Hiroaki Sengoku/CN=test/emailAddress=sengoku@gcd.org

この一行で表現した識別名が満たすべき正規表現を設定する。 この形式は、 前々回説明したクライアントが 既知の root CA (の子 CA) が発行した証明書を提示した場合の stone の出力例の 中に出てきている:

depth2=/C=JP/ST=Kanagawa/L=Kawasaki/O=GCD/CN=GCD Root CA/emailAddress=root@gcd.org
depth1=/C=JP/ST=Kanagawa/L=Kawasaki/O=GCD/OU=Hiroaki Sengoku/CN=GCD_Sengoku_CA/emailAddress=sengoku@gcd.org
depth0=/C=JP/ST=Kanagawa/L=Kawasaki/O=GCD/OU=Hiroaki Sengoku/CN=test/emailAddress=sengoku@gcd.org

「depth2=」の行が、root CA 「GCD Root CA」の証明書の識別名であり、
「depth1=」の行が、「GCD Root CA」の子CA 「GCD_Sengoku_CA」の証明書の識別名であり、
「depth0=」の行が、「GCD_Sengoku_CA」が発行した証明書の識別名である。
root CA, 子, 孫, 曾孫, ... と、中間CA の階層数が増えて証明書の連鎖が続く場合、 「depth」の数字は大きくなり、 頂点である root CA の「depth」の数字が最も大きくなる。 一方、 サーバないしクライアント自身の証明書は常に「depth0」である。 stone では、depth0 から depth9 まで、扱うことができる。

各識別子 「depth0」~「depth9」が満たすべき正規表現を、
それぞれ 「-z re0=正規表現」~「-z re9=正規表現」(クライアント認証の場合)
あるいは 「-q re0=正規表現」~「-q re9=正規表現」(サーバ認証の場合) で指定する。
stone の設定ファイルの一例を次に示す:

-z key=key.pem
-z cert=cert.pem
-z verify
-z CApath=/usr/local/ssl/certs
-z re2="/CN=GCD Root CA/"
-z re1="/CN=GCD_Sengoku_CA/"
-z re0="/CN=test[0-9]*/"
localhost:25 465/ssl

指定した全ての「re0=正規表現」~「re9=正規表現」が、 それぞれ証明書連鎖の「depth0」~「depth9」とマッチするときに限り、 stone は接続を許可する。

stone 2.3c (近日公開予定) 以降では、 root CA から数えた階層数で「re数字=正規表現」を指定することもできる。 すなわち、root CA を「-1」とし、root CA の子CA が「-2」、 以下順に数字が減っていく。 したがって、上述の設定は以下の設定と等価である:

-z key=key.pem
-z cert=cert.pem
-z verify
-z CApath=/usr/local/ssl/certs
-z re-1="/CN=GCD Root CA/"
-z re-2="/CN=GCD_Sengoku_CA/"
-z re0="/CN=test[0-9]*/"
localhost:25 465/ssl

CA の階層数が 2 (すなわち root CA が depth2) の場合、 「re2=」と「re-1=」、および「re1=」と「re-2=」は、 それぞれ同じ証明書を示す。 両方指定した場合、後者が優先される。 この指定方法を用いると、 中間CA の階層数が一定でなくても、 root CA あるいはその子CA の識別名が満たすべき正規表現を指定することが 可能である。 例えば、

-z re-1="/CN=GCD Root CA/"
-z re0="/CN=test[0-9]*/"

などと指定すると、 中間 CA の階層数にかかわらず、 root CA が「GCD Root CA」であり、 CN が「test[0-9]*」にマッチするような証明書を許可する。

(次回に続く)

Filed under: stone 開発日記 — hiroaki_sengoku @ 08:37

No Comments »

No comments yet.

RSS feed for comments on this post.

Leave a comment