OpenConnect がトークンに必要な PKCS#11 URI はどれか
OpenConnect が求めるのは、トークンの証明書と鍵を名指す PKCS#11 URI であり、書き出した PEM ではない。登録に一致するオブジェクトを見つけて引用符で囲む。
正しい鍵をすでに保持しているスマートカードでも、その上のどのオブジェクトを使うのかを伝える必要がある。OpenConnect はその状況でコピーした .key ファイルを求めず、証明書を名指す PKCS#11 URI を求める。自動検索で作業を終えられないときは、隣にある秘密鍵も名指す。厄介なのは、構文的に正しい URI だけでは何も証明できないことだ。カードが開く気のあるオブジェクトではなく、ゲートウェイがすでに信頼する登録を名指す必要がある。
書き出した鍵の代わりにクライアントが求めるもの
-c オプションは通常ファイルパスを受け取るが、値が PKCS#11 URI として解釈されると、OpenConnect はディスク上のファイルではなくトークン内のオブジェクトへの参照として扱う。-k オプションも秘密鍵について同じように振る舞う。何も書き出されず、鍵がカードの提供する保護を離れることはない。クライアントがあなたに求めるのは、トークンモジュール、証明書ストア、ゲートウェイの登録が一致する名前だ。
ほとんどの試みが止まるのはこの最後の制約だ。URI が完全に整っていても、ゲートウェイが拒否する証明書を選ぶことがある。有効性と適合性は別の問いだからだ。やる価値のある確認は登録記録との照合であり、たまたま開いた最初のオブジェクトを探すことではない。
二つの URI、二つの異なる仕事
証明書の URI は、どの身元を主張しているかに答える。公開鍵とサブジェクト行が、VPN 管理者が発行したアカウントまたはデバイスのプロファイルと一致する証明書オブジェクトを指す。同じ証明書は通常、隣に保存された秘密鍵オブジェクトとともに届き、TLS ハンドシェイクが実際に必要とするのはその組だ。
鍵の URI は、OpenConnect が推測できないときに、対応する秘密材料がどこにあるかに答える。-c だけを設定した場合、クライアントは証明書の属性から鍵の検索を組み立てる。-k を指定すると、推測が明示的なオブジェクト参照に置き換わる。トークンの PIN は三つ目の無関係な入力であり、操作のためにカードを解錠するだけで、オブジェクトを特定することはない。
openconnect --protocol=anyconnect \
-c 'pkcs11:model=PKCS%2315%20emulated;manufacturer=piv_II;serial=1a2b3c4d;id=%01' \
vpn.example.net
引用符で囲まれたその文字列の中身はすべてデータだ。セミコロンは URI の属性を区切り、パーセントエスケープはそのままでは解析を壊す文字を符号化する。だから引数全体がシェルを無傷で通過しなければならない。
登録に一致する URI を見つける
GnuTLS には p11tool が付属し、現在のユーザーが p11-kit を通じて実際に到達できるものを一覧する。まず p11tool --list-tokens で始め、次に対象のトークン上の証明書オブジェクトを一覧する。オブジェクトが PIN の後でしか現れない場合は --login を加え、最初に現れたものを選ぶのではなく、サブジェクトと発行者を登録記録と照合する。
トークンがまったく現れないなら、問題は OpenConnect より下にある。p11-kit にそのミドルウェア用のモジュールが登録されていないか、モジュールが別のアカウントに登録されている。システム全体の登録は /etc/pkcs11/modules の下にあり、ユーザーごとのディレクトリにもシステムのコピーに触れずに同じものを置ける。モジュールファイルのプロバイダーパスが、リーダーのソフトウェアが実際にインストールしたライブラリを指しているか確認する。
一覧から URI をコピーするときは、囲みの引用符を残す。引用符のないセミコロンは最初の属性で引数を切り、クライアントは見つからないオブジェクトを報告する。
自動の鍵検索が諦めるとき
OpenConnect は証明書の URI から鍵の検索を導けるが、実行する厳密な照合はバージョンに依存し、オブジェクト種別とラベルの扱いは時間とともに変わってきた。動くまで URI を短くせよという助言は古い回避策を述べており、要件ではない。導かれた検索が失敗したら、証明書の URI を曖昧なものに書き換えるのではなく、-k で鍵を明示的に名指す。
クライアントを責める前に、鍵が存在し p11tool --list-keys で見えることを確認する。次に、そのオブジェクトが署名や復号に使えると印されているかを確かめる。属性を誤って生成された鍵は、URI がどれほど正しくてもハンドシェイクを完了できないので、OpenVPN プロファイルのシリアル化された pkcs11-id 値を OpenConnect のオプションに移植してはいけない。同じカードと話していても、二つのクライアントは異なる識別子形式を使う。
URI が解決し PIN が受け入れられても認証が失敗するなら、URI の調整をやめる。次の失敗はトークンより上流にあるので、ゲートウェイ自身のエラーを読む。
URI の問題にしか見えない失敗
別のプロトコルを話すゲートウェイは、URI が正しくても誤っていても同じように失敗する。OpenConnect が旧来の vpnc クライアントを置き換えたのには理由があり、カード対応は互換性のないゲートウェイプロトコルを互換にはしない。オブジェクトの属性にもう一時間費やす前に、サーバーが期待するプロトコルと認証の構成を確認する。
サーバー身元の検証も別の層だ。クライアントはゲートウェイ証明書を自身の信頼ストアに対して検証し、その確認はカードがすでに自分の役割を終えた後に走る。リーダーの権限と停止した pcscd サービスは同じ外見の症状、読めないトークンを生むが、修正はずっと簡単だ。
オブジェクトから外へ向かって作業する。p11tool がトークンを見るか、証明書と鍵を見るか、OpenConnect が URI を受け入れるか、そして最後にゲートウェイが身元を受け入れるかを問う。各段階には独自のエラーメッセージがあり、どれも次の段階より安く試せる。