Windows Vista での PKI に関する問題のトラブルシューティング
適用対象: Windows Server 2008,Windows Vista
CAPI2 診断は、Windows Vista® および Windows Server® 2008 の機能です。この機能を使用すると、管理者は、証明書チェーンの検証、証明書ストアの操作、および署名の確認についての詳細な情報を収集することにより、PKI に関する問題をトラブルシューティングすることができます。CAPI2 診断によって、PKI に関するほとんどの問題の根本的な原因を簡単に特定できます。また CAPI2 診断を使用すると、問題の診断にかかる時間を短縮し、トラブルシューティングの手順を改善することができます。このドキュメントでは、CAPI2 診断について説明します。また、一般的な PKI エラーのシナリオでトラブルシューティングする場合の CAPI2 診断の使用方法についても説明します。
このガイドの内容
CAPI2 の概要
公開キー基盤 (PKI) は、暗号化、ソフトウェア、処理、およびサービスを組み合わせたもので、これを利用することにより、組織の通信とビジネス トランザクションを保護できます。X.509 証明書を使用すると、ユーザー、デバイス、組織を識別できます。また、署名済みの電子メール、コード署名、セキュリティで保護された Web の閲覧などによる安全なアプリケーションを使用することができます。
CryptoAPI (CAPI) は、Windows での暗号化と X.509 証明書をサポートする主要な API です。CAPI1 は、暗号化関数、暗号化解除関数およびハッシュ関数などによって、基本的な暗号化コンポーネントをサポートします。CAPI2 は、証明書チェーンの検証、証明書ストア、および署名の確認などによって、PKI と X.509 証明書をサポートします。Cryptography API: Next Generation (CNG) は、Windows Vista の新しいアプリケーション プログラミング インターフェイス (API) のセットであり、既存の CAPI1 に替わるものです。ただし、CAPI1 も引き続きサポートされます。このドキュメントでは、CAPI2 を使用した PKI エラーのトラブルシューティングについて詳細に説明します。CNG と CAPI1 は対象としていません。
アプリケーションは CAPI2 を呼び出して、次のようなさまざまなタスクを実行します。
-
証明書チェーンの構築と検証
-
ユーザーごとおよびコンピュータごとの証明書ストアの管理
-
メッセージに対する暗号化/暗号化解除、エンコード/デコード、署名/検証
バックグラウンド
PKI に関する問題は、一般的な PKI 対応アプリケーションではトラブルシューティングすることが難しいものです。ほとんどのアプリケーションでは、エラーの詳細な情報が表示されません。たとえば、ネットワーク関連の多くのエラーに対して、CAPI2 は "オフラインの失効" というエラーをアプリケーションに返します。アプリケーションではこれをエラー メッセージとして表示します。ユーザーは、報告される PKI に関するエラーの一般的な意味は確認できますが、問題をどのように解決すればよいかは判断できません。API 署名は、エラー コードと文字列を返すように設計されています。API は公開されているものであるため、既存のアプリケーションを中断させずに、より詳細な情報を返すように API の機能を拡張することはできません。また、一部のエラーは、通常の操作で検出しようとするとパフォーマンスが著しく低下するため、ポスト プロセスで処理するほうが適しています。
以上のような状況により、CAPI2 には、PKI のトラブルシューティングのためのより優れた診断機能の実装が求められていました。Windows Vista の CAPI2 診断では、証明書の検証、ネットワークの取得、失効、およびその他の低レベルな API の結果やエラーに関する詳細な情報をログに記録できます。この拡張された機能により、PKI に関する問題の根本的な原因を簡単に特定できます。
PKI に関連する一般的なエラーについては、特定のパターンで情報がログに記録されます。このドキュメントでは、CAPI2 診断の概要を示し、ログを解釈するのに役立つ方法について説明します。また、エラー シナリオに対応した、ログのパターンについても説明します。ここで説明されている情報を利用すると、PKI に関する問題を診断でき、開発者は、PKI に関する一般的な問題をトラブルシューティングするためのツールを作成できます。
証明書パス検証
証明書パス検証のプロセスを理解することは、CAPI2 を使用する PKI 対応アプリケーションをトラブルシューティングする場合の基本要件です。図 1 に示すような証明書チェーンを考えてみます。ルート CA は下位 CA 証明書を発行します。これに対し、下位 CA はエンド エンティティ証明書を発行します。ルート CA と下位 CA は、証明書失効リスト (CRL) を個別に発行します。CRL には、署名 CA によって失効にしたすべての証明書のシリアル番号が含まれています。
証明書パス検証の最初の段階では、証明書パスの検出が行われます。これは、エンド エンティティ証明書に対して発行されている CA 証明書を検索し、信頼されたルート証明書までの証明書パスを構築するプロセスです。中間 CA 証明書は、アプリケーション プロトコルの一部として含まれている場合も、グループ ポリシーまたは機関情報アクセス (AIA) 拡張機能で指定された URL を使用して取得される場合もあります。パスが構築されると、パス内のすべての証明書は、さまざまなパラメータ (名前、時刻、署名、失効状態、その他の制約など) に照らし合わせて、その有効性が検証されます。
証明書パス検証の詳細については、http://go.microsoft.com/fwlink/?LinkId=27081 (英語の可能性あり) を参照してください。
Windows Vista の CAPI2 診断
CAPI2 診断は Windows Vista の機能であり、イベント ログとイベント ビューアを利用し、CAPI2 の API セットに基づく PKI アプリケーションに対して、より優れたログ記録機能とトラブルシューティング機能を提供します。Windows Vista のイベント レポートおよびイベント トレース システムでは、体系化されたイベントを発行する機能、ログ ファイルの照会機能、およびイベントへのサブスクライブ機能を実現するための、アプリケーション、コンポーネント、ドライバを使用できます。このシステムは、イベント ログシステムとイベント トレース フレームワークを統合したものです。イベント ログシステムによって、アプリケーションでイベントの構造化や分類を行うために必要な機能が提供されます。これにより、管理者は、イベントを簡単に整理したり表示することができます。イベントは XML 形式でログに記録され、イベント ビューアで表示できます。診断情報を XML でログに記録することにより、自動トラブルシューティング ツールを簡単に作成できます。イベント ビューアでは、イベントを表示するためのユーザー インターフェイスが提供され、パラメータ (ソース、レベル、キーワードなど) に基づいてイベントをフィルタ処理できます。
Windows Vista のイベント レポートおよびイベント トレース システムの詳細については、http://go.microsoft.com/fwlink/?LinkId=82279 (英語の可能性あり) を参照してください。
CAPI2 診断を使用するにあたって
CAPI2 イベントは、Microsoft-Windows-CAPI2 チャネルを経由してイベント ログに記録されます。イベントは、証明書パス検証プロセスの一部である、共通の Crypto API に基づいています。
CAPI2 ログの有効化と保存
次に示す手順は、ログ記録を有効化する方法、ログの保存および消去方法、ログのサイズを増やす方法について説明しています。管理者が実行する必要がある手順を次に示します。
CAPI2 ログをイベント ビューア UI から有効化し、保存する-
イベント ビューアを開きます。 イベント ビューアを開くには、[スタート] ボタン、[コントロール パネル] の順にクリックし、[管理ツール]、[イベント ビューア] の順にダブルクリックします。
-
[ユーザー アカウント制御] ダイアログ ボックスが表示された場合、このボックスに希望する動作が表示されていることを確認し、[継続] をクリックします。
-
コンソール ウィンドウで、[イベント ビューア]、[アプリケーションとサービス ログ]、[Microsoft]、[Windows]、および [CAPI2] の順に展開します。
-
これで、次の操作を実行できます。
-
CAPI2 のログ記録を有効化するには、[Operational] を右クリックし、[ログの有効化] を選択します。
-
ログをファイルへ保存するには、[Operational] を右クリックし、[イベントに名前を付けて保存] を選択します。ログ ファイルは .evtx 形式 (イベント ビューアで開くことができます) または .xml 形式で保存できます。
-
CAPI2 のログ記録を無効化するには、[Operational] を右クリックし、[ログの無効化] を選択します。
-
ログにデータが存在する場合は、問題を再現する前にログを消去することをお勧めします。これにより、保存されたログから、問題のあるシナリオに関係するデータだけを収集できます。ログを消去するには、[Operational] を右クリックし、[ログの消去] オプションを選択します。
-
イベント ログの既定のサイズは 1 MB です。CAPI2 診断ではログのサイズがすぐに大きくなるため、関連するイベントを取得するために、ログ サイズを少なくとも 4 MB に増やすことをお勧めします。ログ サイズを増やすには、[Operational] を右クリックし、[プロパティ] をクリックします。ログのプロパティで、最大ログ サイズを増やします。
-
CAPI2 のログ記録を有効化するには、[Operational] を右クリックし、[ログの有効化] を選択します。
wevtutil.exe ツールを使用して、ログ記録を有効化し、ログを保存することもできます。このツールは、Windows Vista で使用できます。
wevtutil.exe を使用して、CAPI2 のログを有効化し保存するには-
管理者としてコマンド プロンプトを開きます。これを行うには、[スタート] ボタン、[すべてのプログラム]、[アクセサリ] の順にクリックします。
-
[コマンド プロンプト] を右クリックして [管理者として実行] をクリックします。
-
[ユーザー アカウント制御] ダイアログ ボックスが表示された場合、このボックスに希望する動作が表示されていることを確認し、[継続] をクリックします。
-
コマンド プロンプトで、次のコマンドを実行します。
-
ログ記録を有効化する場合 : wevtutil.exe sl Microsoft-Windows-CAPI2/Operational /e:true
-
ログをファイルに保存する場合 : wevtutil.exe epl Microsoft-Windows-CAPI2/Operational filename.evtx
-
ログ記録を無効化する場合 : wevtutil.exe sl Microsoft-Windows-CAPI2/Operational /e:false
-
ログを消去する場合 : wevtutil.exe cl Microsoft-Windows-CAPI2/Operational
-
ログ サイズを増やす場合 : wevtutil sl Microsoft-Windows-CAPI2/Operational /ms:<バイト単位のログ サイズ>
-
ログ記録を有効化する場合 : wevtutil.exe sl Microsoft-Windows-CAPI2/Operational /e:true
このツールで使用できるすべてのオプションを表示するには、wevtutil -? を実行します。
注 |
|---|
| イベント ログはパフォーマンスに影響を与える可能性があるため、問題をトラブルシューティングする場合にのみログ記録を有効にしてください。 |
イベントの概要
CAPI2 診断では、イベントは、特定のタスクの実行に対応してログに記録されます。一部のイベントは、タスクを実行するために呼び出された特定の API に対応します。自動トラブルシューティング アプリケーションの作成者および知識のある開発者は、API に対応したイベントの情報と MSDN に掲載されているデータ構造のドキュメントを相互参照することができます。イベントは、最上位のイベントとその下に入れ子になる子イベントで編成されます。これらの子イベントは、タスク内部のステップに対応しており、実行された操作および最上位のイベントの一環として参照されたオブジェクトに関する詳細な情報を含んでいます。
たとえば、証明書パス検証では、次の表に示すイベントが関連します。
証明書パス検証のイベント
| イベント | 説明 |
|---|---|
|
CertGetCertificateChain |
証明書チェーンの構築結果を表示します。 |
|
CertVerifyRevocation |
失効確認の結果を示します。 |
|
CryptRetrieveObjectByUrlWire |
ネットワークを経由した CRL または OCSP 応答などのオブジェクトの取得に関する詳細をログに記録します。 |
|
CertRejectedRevocationInfo |
Windows が無効な失効情報を取得した場合の詳細なエラー情報を格納します。 |
|
X509Objects |
証明書パス検証の一環として処理されたすべてのオブジェクトの詳細を格納します。 |
子イベントは最上位のイベントで数回繰り返されるステップを表すため、子イベントは上で説明したような方法で編成されます。たとえば、証明書チェーン内の複数の異なる証明書に関する失効を確認する場合、"CertVerifyRevocation" は、1 つの "CertGetCertificateChain" イベント内で複数回呼び出されます。
ログに記録されるさまざまなイベントの一覧、およびその説明については、「付録 A」を参照してください。
これらの API の詳細については、http://go.microsoft.com/fwlink/?LinkId=82278 (英語の可能性あり) を参照してください。
CAPI2 では、イベント データの UserData セクションのイベントに関する詳細な情報をログに記録します。この情報は、イベント ビューアの [詳細] タブで確認できます。重要な拡張エラー情報を返す API の場合、CAPI2 では、イベントのエラー コードと説明をイベント データの一部として結果フィールドにあるログに記録します。また CAPI2 では、DWORD 値を表す値属性を持ったフラグ、および設定されている個々のフラグの意味を表すブール属性のリストもログに記録されます。たとえば、次のようになります。
<ErrorStatus value="1000040" CERT_TRUST_REVOCATION_STATUS_UNKNOWN="true" CERT_TRUST_IS_OFFLINE_REVOCATION="true" />
PKI オブジェクトの記録
PKI オブジェクト (証明書、CRL、オンライン証明書状態プロトコル (OCSP) 応答など) の詳細な情報は、トラブルシューティングに重要です。CAPI2 では、証明書や他の PKI オブジェクトのほとんどの関連情報を、X509Objects イベントに XML 形式で記録します。
"X509Objects" イベントに記録される証明書のエントリの例を、次に示します。
<Certificate fileRef="B18D64DA254B2E51F533193E36FF10E91A9198FC.cer" subjectName="ContosoRoot"> <Subject> <CN>ContosoRoot</CN> </Subject> <SubjectKeyID computed="true" hash="24CD7CB5D99A6734139189D3828DD11069397CF6" /> <Issuer> <CN>ContosoRoot</CN> </Issuer> <SerialNumber>49BAC183C61F688F4F237F306950C6A3</SerialNumber> <NotBefore>2005-01-01T00:00:00Z</NotBefore> <NotAfter>2008-12-31T00:00:00Z</NotAfter> </Certificate>
fileRef 属性には、オブジェクトの SHA1 ハッシュのファイル名が含まれます。ファイル名の後には、適切な拡張子 (.cer, .crl, or .bin) が付加されます。
X.509 オブジェクトは、単一の最上位のイベント内であっても、複数回参照される場合があります。たとえば、エンド エンティティ証明書は、"CertGetCertificateChain"、"CertVerifyRevocation"、および "CryptAIAUrlRetrievalWire" イベントで参照されます。CAPI2 では、オブジェクトの参照を、fileRef 属性と後続の名前 (証明書の場合は subjectName、CRL や OCSP 応答の場合は issuerName) を使用してログに記録します。
<Certificate fileRef="" subjectName=""> <CertificateRevocationList fileRef="" subjectName=""> <OCSPResponse fileRef="" subjectName="">
上の例は、次のように参照されます。
<Certificate fileRef="B18D64DA254B2E51F533193E36FF10E91A9198FC.cer" subjectName="ContosoRoot">
相関関係のあるイベント
ほとんどのイベントには、さまざまな形式の開始と停止があります。CAPI2 では、イベント ログに設定されたシステム情報のみを使用して、空の開始イベントをログに記録し、イベントの開始を示します。入力パラメータ、出力、およびその他の状態情報を含む完全な情報は、停止イベントに記録されます。停止イベントですべての情報をまとめるため、別のイベントを検索する回数が減少します。
本来、イベントは階層構造になっています。最上位の API の一部として呼び出される内部関数に対応した、関連するすべてのイベントは、最上位の API に対応する開始イベントと停止イベントの間で入れ子になります。ログでは、このようなすべての関連イベント (同じ証明書パス検証シーケンスに含まれるすべてのイベントなど) は、共通の相関関係のあるタスクの識別子によってグループ化されます。シーケンス内の各イベントにはシーケンス番号が関連付けられています。この番号によって、シーケンス内のイベントの順番を識別できます。
たとえば、証明書チェーン内にあるすべての証明書 (ルート証明書は除く) に対する失効状態の確認が含まれている証明書パス検証を考えてみます。追加の失効情報はネットワークから取得します。いずれかの失効の確認が失敗した場合、ログに含まれる、入れ子になったイベントのシーケンスは次のようになります。
CertGetCertificateChainStart
-
CertVerifyRevocationStart
-
CryptRetrieveObjectByUrlWireStart
-
CryptRetrieveObjectByUrlWire
-
CryptRetrieveObjectByUrlWireStart
-
CertVerifyRevocation
-
CertVerifyRevocationStart
-
CryptRetrieveObjectByUrlWireStart
-
CryptRetrieveObjectByUrlWire
-
CertRejectedRevocationInfo
-
CryptRetrieveObjectByUrlWireStart
-
CertVerifyRevocation
CertGetCertificateChain
CertVerifyCertifcateChainPolicy
X509Objects
各イベントでは、相関関係のあるタスクの識別子は同じになりますが、シーケンス番号は順序に応じて増加していきます。最初のイベントのフィールドは次のようになります。
<CorrelationAuxInfo TaskId="{B679BF8C-B26E-401A-A35F-342C7753B6BA}" SeqNumber="9" />
ログ モード
CAPI2 診断では、エラー レベルやキーワードなどのイベント ビューアの機能を活用して、ログ内のデータをフィルタ処理します。たとえば、パス検証に関連したエラーを確認する場合、"Error" (レベル 2) といったイベント レベルと "chain building"、"chain validation" および "revocation" などのキーワードでフィルタ処理できます。イベントは、API の結果がエラーであるとレベル 2 とマークされ、成功であるとレベル 4 とマークされます。
既定のログ モードでは、レベル 2 と 4 のイベントだけがログに記録されます。この場合、最上位のイベントについて成功したイベントとエラーのイベントが、子のエラー イベントと共に記録されます。子イベントに対応する追加の情報を含んだ、さらに詳細なログが必要な場合は、詳細ログ モードを有効にします。詳細モードでは、詳細レベル 5 のイベントがログで使用できます。たとえば詳細モードでは、バイナリ X.509 オブジェクトへのリンクを使用できます。X.509 オブジェクトは、%USERPROFILE%/AppData/LocalLow/Microsoft/X509Objects でファイル システムにキャッシュされます。
これは次のようにログに記録されます。
<X509Objects> <Base path="F:\Users\abby\AppData\LocalLow\Microsoft\X509Objects”/>
詳細モードは、格納操作やキャッシュ操作など、失敗がほとんどない操作で役立ちます。また、コンテキストを他のイベントへ渡すときにも役立ちます。操作が失敗すると、レベル 2 のエラー イベントがログに記録されます。これは、既定のログ モードで使用できます。
詳細モードを有効化するには-
[スタート] ボタン、[検索の開始] の順にクリックし、「ファイル名を指定して実行」と入力して、Enter キーを押します。
-
[ファイル名を指定して実行] で、「regedit」と入力し、[OK] をクリックします。
-
[ユーザー アカウント制御] ダイアログ ボックスが表示された場合、このボックスに希望する動作が表示されていることを確認し、[継続] をクリックします。
-
次のレジストリ キーに移動します。HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\crypt32
-
DWORD (32 ビット) 値 DiagLevel を追加し、値 0x00000005 を設定します。
-
QWORD (64 ビット) 値 DiagMatchAnyMask を追加し、値 0x00ffffff を設定します。
プライバシー
ここでは、CAPI2 診断での個人を特定できる情報 (PII) の処理方法について説明します。PII とは、個人の識別または個人への連絡で使用される情報のことです。管理者は、CAPI2 診断での PII の処理方法に注意し、法律または企業のプライバシー ガイドラインに適切に準拠しているかどうかを確認する必要があります。
イベント ビューアでログに記録されるイベント データに加え、CAPI2 イベント ログに記録される情報には、ユーザー、システム、アプリケーションが使用する証明書についてのデータも含まれています。診断用にログに記録される、PII と同様なデータには次のものがあります。
-
サブジェクトおよび証明書の発行者の X.500 識別名を備えた証明書に含まれている情報。アプリケーションに応じて、次の情報が含まれます。
-
電子メール アドレス (署名済みの電子メールを確認する場合)
-
ファイル名 (ファイルの署名を確認する場合)
-
参照した Web サイトの URL (Secure Sockets Layer (SSL) プロトコルでの証明書パス検証の一環として)
-
電子メール アドレス (署名済みの電子メールを確認する場合)
-
証明書パス検証の一環としてアクセスされる URL。証明書失効リストや中間証明書の場所が含まれています。
-
IP アドレス (ネットワークのダウンロードで接続されるプロキシ サーバーの URL など)。
Microsoft-Windows-CAPI2 チャネルでのログ記録は、既定では有効になっていません。ログ記録の有効化と無効化は、ローカル管理者だけが実行できます。またログは、管理者だけが読み取れます。管理者は、ログをファイルに保存したり、ログを Microsoft プレミア サポートなどの専門の担当者に送付して分析を依頼することができます。
CAPI2 診断およびイベント ビューアによる PII の収集の詳細については、http://go.microsoft.com/fwlink/?LinkID=34493 を参照してください。
一般的な問題のトラブルシューティング
ログ記録を有効化し、シナリオを再現し、ログを収集したら、次の手順ではイベント ログのデータを解釈して、問題の根本的な原因を特定します。ここでは、CAPI2 診断のイベントを、PKI に関する一般的な問題のトラブルシューティングで役立てる方法について説明します。問題となる各シナリオでは、シナリオを構成する状況、およびイベント ビューアの Microsoft-Windows-CAPI2\Operational パスに記録されているイベントについて確認します。次の操作を実行することにより、問題のトラブルシューティングの方法を学習します。
-
関連するイベントの特定と関連付け
-
最上位のエラー イベントに基づいたエラーの分類
-
入れ子になったイベントを使用した、エラーの原因の絞り込み
-
詳細なイベント データによる、エラーの根本的な原因の特定
CAPI2 では、構造化された XML 形式で情報をログに記録します。この形式は、自動トラブルシューティング ツールを使用可能にするために設計されたものです。XML ドキュメントの要素を処理するための言語である XPATH は、CAPI2 診断 のイベント ログに含まれる情報を照会する場合に便利です。XPATH はノードを照合する場合に使用できます。たとえば、ノードが特定のパターンに一致するかどうかを確認する場合などです。特定のシナリオに対応したログ内のデータには、特定のパターンがあります。たとえば、プロキシを介してネットワークの取得が発生する場合、プロキシ リストがログに記録されます。この場合、XPATH を使用して、プロキシ リストの存在を示すパターンにノードが一致するかどうかを確認できます。これらのパターンは、XPATH 式を使用して記述できます。この式が評価されると、その結果は、式に一致するノードのセット、または文字列、数値、ブール値などの値になります。
XPATH の詳細については、http://go.microsoft.com/fwlink/?LinkId=82280 (英語の可能性あり) を参照してください。
ここで扱う問題は次のとおりです。
-
SSL を経由した HTTP セッションの確立時における認証の失敗
-
スマート カードを使用したログオンの失敗
-
署名済みの電子メールを確認する場合の Microsoft Outlook での証明書の警告
SSL を経由した HTTP セッションの確立時における認証の失敗
シナリオ
Internet Explorer で Web サイトのアドレス (https://www.contoso.com など) を入力し、https を経由して Web サイトに接続します。証明書のエラー "この Web サイトで提示されたセキュリティ証明書は、信頼された証明機関から発行されたものではありません" が発生したため、Internet Explorer でのナビゲーションがブロックされます。
Web サイトへの接続を続行する場合、アドレス バーの右に証明書のエラーが示されます。
証明書パスの検出の一環として、証明書パスを構築するために、発行されている CA 証明書を検索する必要があります。これらの証明書は、クライアントのキャッシュまたは証明書ストアから取得できます。サーバーは、クライアントに対して追加の情報を提供できます。このための方法の一例として、SSL があります。SSL ネゴシエーションでは、サーバーはクライアントに対して、独自の証明書と中間証明書を提供します。クライアントはこれらの証明書を使用して、証明書パスを構築できます。
このシナリオの状況は次のとおりです。
-
サーバー証明書の証明書パスの構築に必要な中間証明書は、クライアントのキャッシュまたは証明書ストアに存在しません。
-
SSL ネゴシエーションの一環として、エンド エンティティのサーバー証明書だけがクライアントに提供されます。有効な中間証明書がサーバーのローカル コンピュータのローカル証明書ストアに存在しないため、中間証明書は SSL ネゴシエーションの一環として提供されません。
-
中間証明書がローカルで使用できず、アプリケーションによって提供されないため、CAPI2 ではエンド エンティティ証明書の AIA 拡張機能を使用して、ネットワークから中間証明書を取得します。
-
証明書が、AIA 拡張機能で指定されたネットワークの場所に存在しません。その結果、ネットワークの取得が失敗します。
-
中間証明書を取得できないため、信頼されたルート CA までの証明書パスを構築できません。
診断
次の図は、このシナリオで記録されているイベントを示しています。
-
トラブルシューティングを開始するには、"CertGetCertificateChain" エラー イベント (タスク カテゴリ "チェーンの作成" のイベントなど) を確認します。"CertGetCertificateChain" API によって報告されるエラーは通常、アプリケーションに報告されるエラーです。イベント データに含まれるプロセス名を使用すると、特定のエラー イベントを簡単に絞り込むことができます。この場合、アプリケーションが Internet Explorer であることがわかっているので、対応するプロセス名 "iexplore.exe" をイベントの照会で使用できます。同じ "CorrelationAuxInfo" の TaskId を持つ、関連するすべてのイベントを確認します。この ID を使用すると、原因の特定につながるイベントを絞り込むことができます。
-
エラーを分類するには、"CertGetCertificateChain" イベントに記録されている状態フラグを確認します。エラー状態から、パス検証が失敗した理由を特定できます。不完全なチェ-ン エラーを検出するには、フラグ "CERT_TRUST_IS_PARTIAL_CHAIN" を照会します。証明書パスの検出プロセスでは、発行者証明書が、証明書ストアおよびアプリケーションによって提供された証明書から検索されます。イベント データの AdditionalStore フィールド (図 6) に、アプリケーションによって提供された追加の証明書が含まれています。
-
この例では、アプリケーションによって CAPI2 に提供されるのはエンド エンティティ証明書だけです。CAPI2 では、AIA 拡張機能を使用して発行者証明書のダウンロードを試行します。このタスクは、"CertAIAUrlRetrievalWire" イベント (図 7) によって表され、"CertGetCertificateChain" の下で入れ子になります。発行者証明書のネットワークの取得に関する問題を特定するには、失敗の Result 値 (0 以外の値) を含んだ "CertAIAUrlRetrievalWire" を照会します。
-
ネットワークの取得では、"CryptRetrieveObjectByUrlWire" イベント (図 8) が "CertAIAUrlRetrievalWire." の下で入れ子になります。"HTTPResponseHeadersInfo" の "AdditionalInfo" に "404 Not Found" エラーがある場合、オブジェクトがその場所に存在しないことを表しています。この例では、オブジェクトが終了証明書の AIA 拡張機能で指定した場所に存在しないということになります。この情報は、このイベントの "AuxInfo" 要素にある "httpStatusCode" 属性から照会できます。
その他の HTTP エラーを診断する場合も、HTTP 状態コードの情報を同様に使用できます。このようなシナリオについては、このドキュメントの「HTTP エラー」で説明しています。
スマート カードを使用したログオンの失敗
シナリオ
スマート カードを使用して、コンピュータへのログオンを試行します。ただし、スマート カードによるログオンは成功しません。発生したエラーを調査します。
スマート カードを使用してログオンするとき、相互認証が実行されます。ドメイン コントローラでは、スマート カード上の証明書を確認して、クライアントを認証します。クライアントでは、ドメイン コントローラ証明書のチェーンを構築し、証明書を検証して、ドメイン コントローラを認証します。
このシナリオの状況は次のとおりです。
-
ドメイン コントローラ証明書の失効を確認するための CRL が、クライアントのキャッシュまたは証明書ストアで利用可能になっていません。
-
CRL が、ドメイン コントローラのエンド エンティティ証明書内にある CRL 配布ポイントで指定されている場所に存在しません。
-
エンド エンティティ証明書の失効確認が失敗します。その結果、ドメイン コントローラ証明書の証明書パス検証が失敗します。スマート カードによるログオンが機能しないため、ユーザー名とパスワードを使用してコンピュータにログオンする必要があります。
エラー メッセージは、エラーがドメイン コントローラ証明書に関連していることを示しています。この証明書パス検証はクライアントで行われます。したがって、問題を診断するためにクライアントで CAPI2 診断のログ記録を有効化し、失敗を再現します。
診断
このシナリオでは、次のイベントがログに記録されます。
-
プロセス名 lsass.exe を含んだ "CertGetCertificateChain" エラー イベントを検索し、相関関係のあるすべてのイベントを特定します。
-
"CertGetCertificateChain" エラー イベントのエラー状態フラグを照会します。有効な失効情報が取得できない場合、エラー状態フラグ "CERT_TRUST_IS_OFFLINE_REVOCATION" および "CERT_TRUST_REVOCATION_STATUS_UNKNOWN" が設定されます。チェーンの要素を調べ、いずれかの要素にこのフラグがある場合は、そのチェーンの要素に対する失効確認が失敗していることを表しています。エラーが発生したチェーンの要素について、失効確認が失敗したサブジェクト名や証明書のハッシュなど、さらに詳細な情報を確認できます。
-
失効確認に対応して、イベント "CertVerifyRevocation" が "CertGetCertificateChain" の下で入れ子になります。失効確認が失敗すると、"CertVerifyRevocation" イベントはエラーを報告します。このエラーの根本的な原因を特定するには、"CertVerifyRevocation" の下で入れ子になっているイベントを調べます。
-
失効確認の実行中、ネットワークの取得が行われると、必ず "CryptRetrieveObjectByUrlWire" エラー イベントが "CertVerifyRevocation" の下で入れ子になります。前のシナリオと同様に、HTTP 状態コードの情報を使用して、エラーの根本的な原因を検出できます。HTTP エラー コード "404" は、オブジェクトが見つからないことを示しています。
同様の手順で、他のネットワークの失敗をトラブルシューティングすることができます。最上位のイベントを使用すると、オフラインの失効エラーおよび "CryptRetrieveObjectByUrlWire" エラー イベントを確認し、根本的な原因を特定できます。
署名済みの電子メールを確認する場合の Microsoft Outlook での証明書の警告
シナリオ
署名済みの電子メールを Microsoft Outlook 2007 で開きます。メッセージが表示された後にデジタル署名のアイコンをクリックすると、次の警告が示されます。
このシナリオの状況は次のとおりです。
-
署名証明書の失効を確認するための CRL が、クライアントのキャッシュまたは証明書ストアで利用可能になっていません。
-
クライアント コンピュータがネットワークから切断されているため、CRL を、署名証明書で指定されている CDP からダウンロードできません。
-
CRL をダウンロードできないため、"オフラインの失効" エラーとなり、Outlook のユーザー インターフェイスには "署名証明を確認する際に必要な証明書取り消し一覧がないか期限が切れています" というエラー メッセージが表示されます。
診断
このシナリオでは、次のイベントがログに記録されます。
-
"チェーンの作成" に対応するエラー イベントを探し、相関関係のあるすべてのイベントを特定します。検索の対象を特定のエラー イベントに絞り込むには、プロセス名 (この場合は "outlook.exe") を使用します。
-
証明書の失効確認が失敗するため、証明書パス検証も失敗します。前のシナリオと同様に、"CertGetCertificateChain" イベントのフラグを照会することにより、失効確認の失敗を絞り込みます。対応する "CertVerifyRevocation" エラー イベントの下で入れ子になっているイベントを調べます。
-
"CertRejectedRevocationInfo" エラー イベントに記録された操作を調べます。このシナリオでは、操作 "Call_IsNetworkAlive" がログに記録されています。エラーは、コンピュータがネットワークから切断されており、証明書を確認するための失効情報を取得できないことを表しています。
"CertRejectedRevocationInfo" イベントは、失効情報 (CRL または OCSP 応答) の検証の失敗に関連するさまざまなエラーを診断する場合に役立ちます。このようなエラーが発生した場合、"CertRejectedRevocationInfo" エラー イベント内の対応する操作名を照会することによって、エラーの根本的な原因を特定できます。他の診断手順も同様です。この種類のエラーに関するさまざまなエラー シナリオの詳細、およびそのトラブルシューティングの方法については、このドキュメントの「エラー シナリオ」で説明しています。
これらの例は、CAPI2 診断では、情報を提供することによってさまざまなアプリケーション エラーを診断し、エラーの根本的な原因を特定できることを示しています。
イベント ログの特定のイベントを表示する場合は、イベント ビューアを使用して、手動でログをフィルタ処理できます。「付録 D」では、イベント ビューアを使用したフィルタ処理の例について説明します。ログを XML ファイルに保存する場合は、コードを使用して XPATH クエリを作成し、ログのデータを照会できます。サンプルのクエリについては、「付録 B」を参照してください。「付録 C」では、エラーの根本的な原因を特定するための XPATH クエリの使用方法を、C# コードのサンプルを使用して説明します。
エラー シナリオ
ここでは、さまざまなエラー シナリオについて説明します。また CAPI2 診断 のイベント ログに記録された情報に基づいてこれらのエラーをトラブルシューティングする手順についても説明します。
パスの検証エラー
CAPI2 では、証明書パス検証のエラーを "CertGetCertificateChain" エラー イベントに記録します。この種類のエラーを診断する場合は、"CertGetCertificateChain" エラー イベントの "CertificateChain" 要素にある ErrorStatus フラグを照会します。次の表は、一般的な証明書パス検証のエラーの一覧です。
パスの検証エラー
| ErrorStatus フラグ | 説明 |
|---|---|
|
CERT_TRUST_IS_NOT_TIME_VALID |
エンド エンティティ証明書またはチェーン内にあるいずれかの証明書の有効期限が切れています。証明書の詳細および有効期限は、"X509Objects" イベントに記録されています。 |
|
CERT_TRUST_IS_NOT_SIGNATURE_VALID |
エンド エンティティ証明書またはチェーン内にあるいずれかの証明書の署名を確認できません。 |
|
CERT_TRUST_IS_REVOKED |
エンド エンティティ証明書またはチェーン内にあるいずれかの証明書が失効しています。失効の理由は、イベント データで確認できます。 |
|
CERT_TRUST_IS_NOT_VALID_FOR_USAGE |
証明書が、その拡張キー使用法 (EKU) とは異なる目的で使用されています。EKU およびアプリケーションの使用情報は、"CertGetCertificateChain" エラー イベントから取得できます。 |
|
CERT_TRUST_IS_UNTRUSTED_ROOT |
証明書チェーンはルート CA まで構築されますが、コンピュータ上の信頼されたルート CA ストアに、ルート CA 証明書がありません。 |
|
CERT_TRUST_IS_CYCLIC |
証明書チェーンが循環しています。たとえば、チェーン内にあるいずれかの証明書が、元の証明書が既に証明している CA によって発行されています。 |
|
CERT_TRUST_IS_REVOCATION_UNKNOWN |
エンド エンティティ証明書または証明書チェーン内にあるいずれかの証明書の失効状態が不明です。失効確認の失敗の詳細については、このドキュメントの「失効確認の失敗エラー」を参照してください。 |
|
CERT_TRUST_IS_OFFLINE_REVOCATION |
エンド エンティティ証明書または証明書チェーン内にあるいずれかの証明書の失効状態が、オフラインになっているか、最新の状態ではありません。これは、ネットワークの問題が原因になっている場合があります。失効確認の失敗の詳細については、このドキュメントの「失効確認の失敗エラー」を参照してください。 |
|
CERT_TRUST_IS_PARTIAL_CHAIN |
証明書チェーンが完全ではありません。証明書パスの検出が失敗すると、不完全な証明書が生成されます。詳細については、このドキュメントの「証明書パスの検出エラー」を参照してください。 |
パスの検証エラーには、不完全なチェ-ンや、さまざまな問題 (ネットワーク障害、無効なオブジェクト、正しくない構成など) が原因である失効確認の失敗などがあります。以下のセクションでは、これらのエラー シナリオについて説明します。特に、上記以外の問題が根本的な原因となっているエラー シナリオを扱います。
ネットワークの取得エラー
PKI に関する問題の多くは、ネットワーク障害が原因と考えられます。たとえば、ネットワークの取得エラーは、CRL、OCSP 応答、AIA 拡張機能を使用した発行者証明書など、異なる種類のオブジェクトを取得する場合に発生することがあります。したがって、ネットワーク ダウンロードが失敗すると、失効確認や証明書パスの検出が失敗します。ネットワーク エラーのシナリオは、さらに次のように分類されます。
HTTP エラー
ここでは、発生する可能性のある HTTP エラーの種類とその説明を示します。次のようなエラーがあります。
オブジェクトが見つからない
証明書の CDP 拡張機能で指定した場所に CRL が存在しない場合、CRL のダウンロードは失敗します。同様に、AIA 拡張機能で指定した場所に証明書が存在しない場合、発行者証明書のダウンロードは失敗します。オブジェクトが見つからないと、HTTP 状態コード "404" が返されます。この状態コードは、"CryptRetrieveObjectByUrlWire" イベントの httpStatusCode フィールドで確認できます。httpStatusCode を使用して、同様な HTTP のシナリオを診断できます。それらのシナリオの一部を、以下のサブセクションで説明します。
アクセス拒否
サーバー上のオブジェクトに対するアクセスが拒否された場合、HTTP 応答の状態 "401" が返されます。このエラーを確認するには、"CryptRetrieveObjectByUrlWire" エラー イベントの操作 "HTTP_STATUS_DENIED" を照会します。サーバーの URL が同じエラーイベントに記録されます。このエラーは、サーバー側の認証エラーを示しています。
Web サーバーで許可されていないメソッド
サーバーの情報を要求するための HTTP メソッドがサーバーで許可されていない場合、このエラーを示す HTTP 状態コード "405" が返されます。このエラーを照会する場合は、"CryptRetrieveObjectByUrlWire" イベントで、値 "405" を持つ httpStatusCode フィールドを検索します。このシナリオの例として、CAPI2 が OCSP 応答を要求する場合が考えられます。CAPI2 では、最初に GET メソッドを試行し、GET メソッドが失敗すると、POST メソッドを使用します。サーバーで POST メソッドがサポートされていない場合は、"HTTP 405" エラーが返されます。
プロキシの認証が必要
HTTP 状態コードを使用して特定できるもう一つのシナリオとして、プロキシの認証エラーのシナリオがあります。これは、"アクセス拒否" エラーと類似しています。相違点は、Web リソースへのアクセスで使用されるプロキシ サーバーで認証エラーが発生するという点です。またプロキシ サーバーは、HTTP 状態コード "407" を返します。このエラーを確認するには、"CryptRetrieveObjectByUrlWire" イベントの操作名 "HTTP_STATUS_PROXY_AUTH_REQ" を照会します。このエラー シナリオは、特定の構成でのみ発生します。たとえば、プロキシが統合 Windows 認証をサポートしていない場合、またはユーザーやコンピュータにプロキシを経由したインターネットへのアクセス許可が与えられていない場合などです。詳細については、http://go.microsoft.com/fwlink/?LinkId=82288 (英語の可能性あり) を参照してください。
その他の HTTP エラー
その他の HTTP エラーも、"CryptRetrieveObjectByUrlWire" イベントの HTTP 状態コードを確認することで特定できます。詳細については、http://go.microsoft.com/fwlink/?LinkId=82289 (英語の可能性あり) を参照してください。
タイムアウト エラー
Web サーバーに対してオブジェクトの取得を要求する場合は、必ずタイムアウト期間がネットワークの取得に関連付けられていることに注意してください。既定のタイムアウトは 15 秒ですが、この値はグループ ポリシーを使用して構成したり、アプリケーションで指定することができます。タイムアウト期間内にオブジェクトを取得できなかった場合、"NetworkRetrievalTimeout" 操作が "CryptRetrieveObjectByUrlWire" イベントに記録されます。
オブジェクトが大きすぎる
タイムアウトが発生するシナリオとして、ダウンロードするオブジェクトが大きく、タイムアウト期間内にダウンロードが完了しない状況が考えられます。CAPI2 ではバックグラウンド スレッドを自動的に開始して、オブジェクトを取得します。タイムアウト期間内に取得が完了しない場合、元のフォアグラウンド スレッドは "NetworkRetrievalTimeout" エラーで終了しますが、ダウンロードはバックグラウンド スレッドで完了します。ダウンロードが完了すると、"CryptRetrieveObjectByUrlWire" イベントに操作 "PendingNetworkRetrievalComplete" が記録されます。このイベントには、取得したオブジェクトも記録されます。
たとえば、スマート カードによるログオンのシナリオを考えてみます。CRL のダウンロードがタイムアウトし、ログオンが失敗したとします。その後しばらくしてから再度ログオンすると、ログオンは成功します。これは、CRL のダウンロードがバックグラウンドで完了したためです。
イベント ログからこのエラーを診断するには
-
"NetworkRetrievalTimeout" 操作が記録されている "CryptRetrieveObjectByUrlWire" エラー イベントを検索します。
-
このエラー イベントの URL 要素から、ダウンロードがタイムアウトした URL を特定します。
-
ログを調べ、同じ URL 要素の値を持ち、"PendingNetworkRetrievalComplete" 操作が記録されている、別の "CryptRetrieveObjectByUrlWire" イベントを探します。このイベントは、バックグラウンド スレッドに対応するもので、パス検証を行ったフォアグラウンド スレッドとは異なる "CorrelationAuxInfo" の TaskId を持っています。
-
Result 値 "0" は、バックグラウンド スレッドが正常に完了したことを表しています。
注 |
|---|
| バックグラウンド スレッドがダウンロードを完了する前に呼び出しプロセスが終了すると、"PendingNetworkRetrievalComplete" を含んだエラー イベントは記録されません。 |
要求タイムアウト
サーバーに対して行ったオブジェクトの取得の要求がタイムアウトする、別のシナリオを次に示します。
-
サーバーがオンラインではなく、要求に対する応答を返さない
-
DNS サーバーがタイムアウトする
-
プロキシが応答しない
-
自動プロキシ検出の速度が遅く、タイムアウトする
これらのシナリオでは、"CryptRetrieveObjectByUrlWire" エラー イベントの "NetworkRetrievalTimeout" 操作がログに記録され、タイムアウト期間が経過したことを示します。ただし、バックグラウンド スレッドによるオブジェクトの取得も成功しません。"PendingNetworkRetrievalComplete" 操作を含むイベントでは、基になっているネットワーク コンポーネントによって報告されるエラーがログに記録されます。たとえば、HTTP サーバーへの接続が確立できない場合、操作 "Call_WinHttpSendRequest" がエラー値 "2EFD" でログに記録されます。この値は、エラー メッセージ定数 "ERROR_WINHTTP_CANNOT_CONNECT" の 16 進数値です。
このエラーを診断するには、「オブジェクトが大きすぎる」の診断手順と同様の手順を実行します。この手順と異なる点は、"PendingNetworkRetrievalComplete" を含んだエラー イベントでは Result 要素の値が 0 以外になる点です。根本的な原因を特定するには、基となる API エラー を参照する操作 (上の例の "Call_WinHttpSendRequest" など) を照会します。また、"Call_" で始まる操作がログに記録されている場合、その操作が参照する、基となる API の呼び出しが失敗していることに注意してください。たとえば、"Call_WinHttpSendRequest" は、"WinHttpSendRequest" の呼び出しが失敗していることを示しており、この API によって返されるエラー コードもログに記録されています。
タイムアウト期間の増加
バックグラウンドでの取得が成功する前にタイムアウトが確認された場合、オブジェクトが大きいか、ネットワーク接続の速度が遅いためにタイムアウトが発生したことを表しています。この問題に対処するために、ネットワークの取得に関する既定のタイムアウト期間を増やすことができます。オブジェクトのサイズと帯域幅を把握している場合、そのオブジェクトのダウンロードに必要な時間を予測できます。オブジェクトのサイズには、"CryptRetrieveObjectByUrlWire" イベント データの "HTTPResponseHeadersInfo" 要素にある "Content-Length" ヘッダー フィールドの値を利用できます。
取得タイムアウト期間を増やす手順を次に示します。
取得タイムアウト期間を増やすには-
[スタート] ボタン、[検索の開始] の順にクリックし、「mmc」と入力して、Enter キーを押します。
-
[ユーザー アカウント制御] ダイアログ ボックスが表示された場合、このボックスに希望する動作が表示されていることを確認し、[継続] をクリックします。
-
[ファイル] メニューの [スナップインの追加と削除] をクリックします。
-
[スナップインの追加と削除] で次の操作を行います。
-
ローカル コンピュータのグループ ポリシー オブジェクトを編集している場合は、[ローカル グループ ポリシー エディタ]、[追加] の順にクリックし、[完了] をクリックします。
-
ドメインのグループ ポリシー オブジェクトを編集している場合は、[グループ ポリシー管理コンソール]、[追加] の順にクリックし、[完了] をクリックします。コンソール ツリーで、編集する [既定のドメイン ポリシー] グループ ポリシー オブジェクト (GPO) が含まれているフォレストおよびドメインの [グループ ポリシー オブジェクト] をダブルクリックします。[既定のドメイン ポリシー] GPO を右クリックし、[編集] をクリックします。
-
目的のスナップインをコンソールに追加し終えたら、[OK] をクリックします。
-
ローカル コンピュータのグループ ポリシー オブジェクトを編集している場合は、[ローカル グループ ポリシー エディタ]、[追加] の順にクリックし、[完了] をクリックします。
-
コンソール ツリーで、前の手順で選択した項目に応じて、[ローカル セキュリティ ポリシー] または [既定のドメイン ポリシー] を展開します。[コンピュータの構成]、[Windows の設定]、[セキュリティの設定] の順に展開し、[公開キーのポリシー] をクリックして、[証明書パス検証の設定] を選択します。
-
[ネットワークの取得] タブをクリックします。
-
[既定の取得タイムアウトの設定] セクションの [既定の URL 取得タイムアウト (秒)] オプションを選択します。
-
必要なタイムアウトの値を入力します。
-
[適用] をクリックして、新しい設定を適用します。
プロキシ サーバーを経由した接続の失敗
プロキシ サーバーを経由してネットワークに接続する場合、プロキシ サーバーが適切に構成されている必要があります。プロキシ サーバーが正しく指定されていないと、ネットワークを経由した失効情報の取得は失敗します。このシナリオは、"CryptRetrieveObjectByUrlWire" イベントに記録されているデータを調べることで確認できます。プロキシが使用されている場合、このイベントには操作 "ProxyListAndBypass" が含まれており、その後にプロキシ リストが記録されます。プロキシがローカルで構成されていない場合は、操作 "NoProxy" が含まれます。
プロキシ サーバーが適切でない場合は、操作 "BadProxy" が "CryptRetrieveObjectByUrlWire" イベント データに記録されます。その後に、エラーを説明するシステム エラー メッセージが記録されます。たとえば、プロキシ サーバーの DNS 名が解決できないため DNS がエラーを報告すると、操作 "Call_WinHttpSendRequest" がエラー コード "2EE7" で記録されます。このエラー コードは、エラー定数 "ERROR_WINHTTP_NAME_NOT_RESOLVED" の 16 進数値です。プロキシ サーバーへの接続が確立できない場合は、操作 "Call_WinHttpSendRequest" がエラー コード "2EFD" で記録されます。このエラー コードは、エラー定数 "ERROR_WINHTTP_CANNOT_CONNECT" の 16 進数値です。
ネットワーク接続がプロキシ サーバーを経由して行われる場合は、必ずプロキシ サーバーとバイパス サイトのリストがログに含まれます。このリストは、操作要素 "ProxyListAndBypassList" の "CryptRetrieveObjectByUrlWire" イベントに記録されます。この操作要素のパラメータ属性によって、プロキシ サーバーとバイパス サイトのリストが示されます。通常 "BadProxy" は、プロキシ リストの最初のプロキシに問題があることを表しています。
LDAP エラー
ライトウェイト ディレクトリ アクセス プロトコル (LDAP) を使用してオブジェクトを取得する場合、一部のエラーは、他のネットワークの取得に関するシナリオと類似したものになります。ただし、LDAP 固有の追加のエラーもいくつかあります。
LDAP URL が検出されると、CAPI2 では最初に URL を解析して各種のコンポーネントを識別します。これに失敗した場合、"CrackLdapUrl" が "CryptRetrieveObjectByUrl" エラー イベントに記録されます。
エラーは、LDAP 接続プロセスのさまざまな段階で発生します。CAPI2 では各種の LDAP API を呼び出して、接続を確立し、オブジェクトをダウンロードします。失敗した API に応じて、エラー イベントが操作名と共に記録されます。この操作名には、"Call_" で始まる API の名前が含まれています。LDAP API によって返されたエラー コードも記録されます。このエラー コードによって、問題の根本的な原因を特定できます。失敗した LDAP API の種類によっては、操作 "Call_ldap_connect"、"Call_ldap_bind" または "Call_ldap_search" がログに含まれる場合があります。
その他のネットワークの取得エラー
ここでは、その他のネットワークの取得エラーについて説明します。次のエラーがあります。
オブジェクトの内容の取得の失敗
オブジェクトをネットワークから取得する場合、CryptQueryObject 関数が呼び出され、オブジェクトの内容に関する情報が取得されます。これに失敗すると、CAPI2 では "CryptRetrieveObjectByUrlWire" エラー イベントを、操作 "Call_CryptQueryObject" およびこの失敗に関する拡張エラー情報と共にログに記録します。たとえば、CRL が破損しており、デコードできない場合は、このエラーがログに記録されます。OCSP 応答のデコードは、この手順とは異なる手順で処理されることに注意してください。詳細については、このドキュメントの「OCSP 応答のデコードの失敗」を参照してください。
サーバーへの接続の失敗
このエラー シナリオは、サーバーに接続できなかったことを表し、次のような問題が原因で発生します。
-
サーバーがオンラインではない
-
指定した URL が間違っている
-
URL が誤まった IP アドレスを指している
"CryptRetrieveObjectByUrl" API は WinHttpSendRequest API を呼び出して、CRL の要求を HTTP サーバーに送信します。このシナリオでは、サーバーへの接続が確立できず、WinHttpSendRequest がエラー "ERROR_WINHTTP_CANNOT_CONNECT" で失敗します。このエラーは、"CryptRetrieveObjectByUrlWire" イベントに "Call_WinHttpSendRequest" という操作要素として記録され、エラー値が "2EFD" になります。この値は、エラー メッセージ定数 "ERROR_WINHTTP_CANNOT_CONNECT" の 16 進数値です。
サポートされていないプロトコル
オブジェクトを取得するとき、URL に指定したプロトコルがサポートされていないと、エラー "System cannot find the file specified" が "CryptRetrieveObjectByUrlWire" イベントに記録されます。このエラーは、"CryptRetrieveObjectByUrlWire" エラー イベントで値 2 の結果を検索することにより、照会できます。たとえば、CryptoAPI ではネットワークの取得で FTP プロトコルをサポートしません。CDP または AIA 拡張機能に FTP URL が含まれている場合は、ネットワークの取得が失敗します。
ネットワークの取得の繰り返しの失敗
CAPI2 では、オフライン応答の繰り返しを目的とした、サーバーへの頻繁なアクセスが防止されます。進行中のバックオフを使用する場合、次のバックオフでサーバーへアクセスするタイミングの前に要求が発生すると、ネットワークの取得の繰り返しは禁止されます。このシナリオでは、操作 "CanRetrieveFromNetwork" を含んだ "CertRejectedRevocationInfo" エラー イベントがログに記録されます。サーバーへアクセスする次のタイミングは、"EarliestOnlineTime" パラメータの下に示されます。
要約すると、ネットワークのエラーをトラブルシューティングする場合は、エラーの原因である、基になっているコンポーネント (ネットワーク、プロキシの設定、Web サーバー、LDAP など) を修正します。
失効確認の失敗
ここでは、失効確認の失敗を診断する方法について説明します。失効確認の失敗には、さまざまな原因があります。主な原因としては、有効な失効情報を取得できなかったこと、または CDP や OCSP AIA 拡張機能が証明書にないため、失効情報を利用できないことが挙げられます。"CertGetCertificateChain" イベントに含まれている "ErrorStatus" フラグが "CERT_TRUST_REVOCATION_STATUS_UNKNOWN" である場合、失効確認の失敗を示しています。
失効確認の失敗のほとんどは、有効な失効情報を取得できなかったことが原因です。この場合、追加の "ErrorStatus" フラグ (値 "CERT_TRUST_IS_OFFLINE_REVOCATION") が設定され、チェーン内にあるいずれかの証明書の失効状態がオフラインであるか、最新ではないことを示します。このような状況は、失効情報を取得できなかった場合、または失効情報を取得できたが有効なものではなかった場合に発生します。
失効確認の結果は、"CertVerifyRevocation" イベントに記録されます。根本的な原因を特定するには、"CertRejectedRevocationInfo" および "CryptRetrieveObjectByUrlWire" イベントを調べます。これらのイベントは、"CertVerifyRevocation" イベントの下で入れ子になっています。
失効情報の取得の失敗
ネットワークの取得の失敗には、さまざまな原因があります。それらの原因については、このドキュメントの「ネットワークの取得エラー」を参照してください。
無効な失効情報
有効期限切れの CRL
現在の日付が、CRL の nextUpdate フィールドの日付よりも後の日付である場合、CRL の有効期限が切れています。このシナリオは、"CertRejectedRevocationInfo" イベントの操作 "CheckTimeValidity" で示されます。このイベントには、CRL や OCSP 応答などの失効情報が拒否された理由、および失効確認が失敗した証明書に関する詳細が含まれています。またこのイベントには、失効情報の拒否に失敗した操作や、失効情報の拒否の原因となった操作も記録されます。
CRL の nextUpdate フィールドの日付は、イベント ログで確認できます。対応する "X509Objects" イベントで、対応する "CertRejectedRevocationInfo" イベントに記録されている fileref と同じ fileref を持つ "CertificateRevocationList" 要素を検索します。この要素には、CRL の有効期間に関する情報が含まれており、 thisUpdate および nextUpdate フィールドで示されます。このエラーを修正するには、有効期限内にある CRL をサーバーで公開します。
「ネットワークの取得の繰り返しの失敗」で説明したように、CAPI2 では、進行中のバックオフを使用したサーバーへの頻繁なアクセスが防止されます。サーバーが有効期限切れの CRL を使用して応答を繰り返し、バックオフごとにサーバーへアクセスするタイミングの前に新しい要求が発生すると、操作 "CanCheckServerForUpdatedCrl" がログに記録されます。サーバーへアクセスする次のタイミングは、"EarliestOnlineTime" パラメータの下に示されます。
CRL の署名が無効
CRL の署名を確認できない場合、操作名 "IsCrlSignatureValid" を含む "CertRejectedRevocationInfo" エラー イベントがログに記録されます。発生したエラーに対応するエラー コードおよび CRL の場所も記録されます。この問題を解決するには、サーバーの CRL を有効な署名の CRL に置き換える必要があります。
OCSP 応答を検証できない
OCSP 応答の検証の一環として、OCSP 応答の署名が確認されます。ただしこの署名の確認に失敗すると、結果として、失効確認も失敗します。この場合、操作 "IsResponseSignatureValid" が "CertRejectedRevocationInfo" エラー イベントに記録されます。また CAPI2 では、OCSP 応答が基本署名付きの応答ではない場合、OCSP 応答の検証に失敗します。応答にオブジェクト識別子 (OID) が含まれていない場合、操作要素 "IsMissingResponseOID" を含んだ "CertRejectedRevocationInfo" エラー イベントがログに記録されます。応答にオブジェクト識別子は含まれていても、基本署名付きの OCSP 応答のオブジェクト識別子とは異なる場合は、操作 "IsUnsupportedResponseOID" がログに記録されます。
承認されていない OCSP 署名者
OCSP 応答には署名が必要であり、OCSP 署名者の証明書には OCSP 署名 EKU が含まれている必要があります。この EKU がないと、エラーが発生します。このエラーは、"CertRejectedRevocationInfo" イベントの操作 "GetOCSPSignerCertificate" で示されます。OCSP 署名者の証明書の内容でその他のエラーが発生した場合も、同じ操作がログに記録されます。このようなエラーには、次のものがあります。
-
期間が無効な証明書
-
CDP 拡張機能または OCSP URL は含まれていても "Revocation_No_Check" 拡張機能が含まれていない証明書
これらのエラーの場合、CAPI2 では、OCSP 署名者の証明書に関する情報もログに記録されます。
OCSP 応答のデコードの失敗
OCSP 応答は、必要な情報を取得するために再帰的にデコードする必要があるデータ構造で構成されています。OCSP 応答のデコードに失敗すると、CAPI2 では "CertRejectedRevocationInfo" イベント エラーをログに記録します。CAPI2 がこのイベントをログに記録するとき、デコードに失敗したステップに応じて、操作 "Call_CryptDecodeObject_OCSP_RESPONSE"、"Call_CryptDecodeObject_OCSP_BASIC_SIGNED_RESPONSE"、または "Call_CryptDecodeObject_OCSP_BASIC_RESPONSE" が記録されます。
CRL または OCSP 応答に、サポートされていない重要な拡張機能が含まれている
CRL または OCSP 応答に、サポートされていない重要な拡張機能が含まれていると、CAPI2 では失効の確認に失敗します。この場合、CAPI2 では次の情報をログに記録します。
-
エラーが CRL で発生した場合、操作 "IsCrlCriticalExtensionSupported" を含んだ "CertRejectedRevocationInfo" エラー イベント
-
サポートされていない重要な拡張機能が OCSP 応答に含まれている場合、操作 "IsResponseCriticalExtensionSupported"
OCSP 応答の状態が失敗を示す
OCSP 応答は、優先的な要求の処理状態を示す "responseStatus" フィールドで構成されています。処理が成功すると、応答の状態 "successful" で示されます。
エラーが発生すると、OCSP の "responseStatus" は次のいずれかの値になります。
-
MalformedRequest
-
InternalError
-
TryLater
-
SigRequired
-
Unauthorized
"responseStatus" が "successful" ではない場合、操作名 "CheckResponseStatus" を含んだ "CertRejectedRevocationInfo" イベントがログに記録されます。OCSP 応答の状態を照会するには、対応する "X509Objects" イベントを調べます。"OCSPResponse" の状態要素には、応答の状態が含まれています。
状態値、および状態値が設定されるシナリオの詳細については、インターネット技術標準化委員会の Web サイト (英語) の RFC 2560 を参照してください。
その他のエラー
証明書に失効情報が含まれていない
ルート CA 証明書以外の証明書では、CDP が必要です。これは、失効情報を検索するためのポインタが CDP によって提供されるためです。CDP がない場合は、OCSP のダウンロード場所が AIA 拡張機能で使用可能になっている必要があります。これらのポインタが両方とも無い場合、CAPI2 には、CA が実際に失効情報を公開したという決定的な証拠がありません。その結果、失効確認が失敗し、"revocation unknown" というエラー状態になります。この場合、CAPI2 では、操作 "GetCrlOrOcspUrls" と拡張エラー "Cannot find object or property" を含んだ "CertRejectedRevocationInfo" エラー イベントをログに記録します。
この問題をトラブルシューティングするには、エラーの原因となる証明書をイベント ログで調べます。この証明書がルート CA 証明書ではない場合、証明書を発行している、対応する CA の再構成が必要になります。また、問題となっている証明書を、正しい CDP を使用して再発行する必要があります。問題となるのがルート CA 証明書である場合は、ルート CA 証明書に対する失効確認を要求しているアプリケーションがベスト プラクティスではないことを表しています。
CAPI2 では、原因に応じてパーティション分割された CRL をサポートしていません。証明書の CDP が、原因に応じてパーティション分割された CRL を参照している場合、CAPI2 で処理を行うときに、この特定の CDP の場所は無視されます。他に使用可能な CDP がない場合は、証明書に CDP 情報が含まれていないシナリオと同じエラー シナリオとなります。
ベスト プラクティスについては、http://go.microsoft.com/fwlink/?LinkId=25612 (英語の可能性あり) を参照してください。
CRL の IDP がサブジェクト証明書に対して有効でない
発行する配布ポイント (IDP) 拡張機能が CRL に含まれている場合、CAPI2 では、その IDP が、失効確認の対象となるサブジェクト証明書に対して有効であるかどうかを確認します。この確認に失敗し、IDP がサブジェクト証明書に対して有効ではない場合、CAPI2 では "Call_CertIsValidCRLForCertificate" 操作を含んだ "CertRejectedRevocationInfo" エラー イベントをログに記録します。たとえば、CRL の IDP がサブジェクト証明書の CDP に一致しない場合に、このエラーが記録されます。
証明書パスの検出エラー
発行者証明書の取得が原因となるサーバー構成エラー
証明書パスの検出の一環として、中間証明書が証明書ストアまたはキャッシュから取得されるか、あるいはアプリケーション プロトコルから取得されます。たとえば SSL の場合、サーバー認証証明書と共に中間証明書が、ハンドシェイクの一部としてクライアントに送信されます。発行者証明書がローカルで使用できない、またはアプリケーション プロトコルの一部として提供されていない場合は、エンド エンティティ証明書の AIA 拡張機能を使用して、発行者証明書がネットワークから取得されます。CAPI2 では、発行者証明書のダウンロードを "CertAIAUrlRetrievalWire" イベントに記録します。ネットワークの取得はパフォーマンスに影響を与えるため、このような AIA による取得は回避することをお勧めします。
SSL の場合、イベント ログに "CertAIAUrlRetrievalWire" イベントが記録されているときは、サーバーが正しく構成されていないことを示しています。ログからさらに詳細な情報を取得して、欠落しているまたは有効期限が切れている証明書を特定できます。管理者はグループ ポリシーを使用して、中間 CA 証明書をクライアントに展開できますが、通常、中間 CA 証明書はクライアントにローカルでインストールされません。ネットワークの取得を防ぐには、すべてのサーバーが適切な中間 CA 証明書を使用して正しく構成されている必要があります。サーバー証明書の証明書チェーンに含まれている有効な中間証明書は、サーバーのローカル コンピュータの中間 CA ストアに追加されます。有効な中間証明書を追加したら、サーバー証明書のバインドを再確立します。これにより、中間証明書がハンドシェイクの一部として確実に渡されるようになります。
詳細については、http://go.microsoft.com/fwlink/?LinkId=82290 の記事 834438 を参照してください。
発行者証明書の取得に失敗
発行者証明書を取得できない場合、エンド エンティティ証明書から信頼されたルート証明書までのチェーンを構築できません。このため、信頼されたルート機関までの証明書チェーンを構築できないといった、不完全なチェ-ン エラーが発生します。不完全なチェ-ン エラーでは、エラー状態フラグ "CERT_TRUST_IS_PARTIAL_CHAIN" が設定されます。
発行者証明書の取得の失敗には、さまざまな原因があります。発行者証明書のネットワークの取得が失敗する場合のさまざまな原因については、このドキュメントの「ネットワークの取得エラー」を参照してください。
また、発行者証明書の取得の一環として実行される URL の最大数には制限があります。同様に、AIA を使用して取得される証明書の数にも制限があります。これらの制限は、発行者証明書の取得で費やされる時間を制限するために設定されています。これらの制限を超えると、不完全なチェ-ン エラーが発生します。また、発行者証明書は取得できても適切にデコードできない場合も、不完全なチェ-ン エラーが発生します。
トラブルシューティングを自動化する場合の一般的な考慮事項
ログのデータを取り出し、エラーの根本的な原因を特定するための手順の概要を次に示します。
手順 1 : 相関関係のあるイベントを特定し、それらをグループにまとめる
-
ログに含まれる一意の各 "CorrelationAuxInfo" TaskId を検索し、記録します。
-
各 TaskId を調べ、同じ TaskId を持つイベントを確認して、1 つのセットにグループ化します。
相関関係のあるイベントの各セットに対して、次の手順を実行します。
手順 2 : エラーを分類する
この手順では、最上位のエラー イベントに基づいてエラー シナリオを分類します。
-
エラーのある "CertGetCertificateChain" イベントを検索します。"CertGetCertificateChain" エラー イベントがある場合は、"ErrorStatus" フラグを使用してエラー シナリオを特定します。
-
フラグ "CERT_TRUST_REVOCATION_STATUS_UNKNOWN" が設定されている場合、失効確認の失敗が原因でパス検証が失敗しています。通常、失効確認の失敗は取得エラーが原因となり、このことを示すために追加のフラグが設定されます。追加のフラグが設定されていない場合は、他の理由 (サポートされていない Reasons フィールドが CDP にあるなど) による失効確認の失敗が発生したことを表しています。
-
フラグ "CERT_TRUST_IS_REVOCATION_OFFLINE" も設定されている場合、失効確認時の取得エラーが原因でパス検証が失敗しています。これは、失効情報を取得できなかったか、または失効情報を取得できたが無効な情報であったことを示します。
-
フラグ "CERT_TRUST_IS_UNTRUSTED_ROOT" が設定されている場合、証明書チェーンはルート CA まで構築されましたが、信頼されたルート CA ストアにルート CA 証明書が存在していません。
-
フラグ "CERT_TRUST_IS_PARTIAL_CHAIN" が設定されている場合、信頼されたルートまでの完全な証明書チェーンが作成されていません。これは、発行者証明書が見つからず、AIA を使用した発行者証明書の取得が失敗した場合に発生します。
-
その他のフラグが設定されている場合は、フラグに応じた特定のパス検証のエラーが発生しています。このドキュメントの「パスの検証エラー」を参照してください。ここでは、一般的なパス検証のエラー シナリオおよび対応する "ErrorStatus" フラグについて説明しています。
-
フラグ "CERT_TRUST_REVOCATION_STATUS_UNKNOWN" が設定されている場合、失効確認の失敗が原因でパス検証が失敗しています。通常、失効確認の失敗は取得エラーが原因となり、このことを示すために追加のフラグが設定されます。追加のフラグが設定されていない場合は、他の理由 (サポートされていない Reasons フィールドが CDP にあるなど) による失効確認の失敗が発生したことを表しています。
-
エラーのある "CryptAcquireCertificatePrivateKey" イベントを検索します。このイベントは、証明書の秘密キーの取得に関連するエラーを示しています。
-
エラーのある "CertOpenStore" イベントを検索します。このイベントは、証明書ストアの操作に関連するエラーを示しています。
-
その他のエラーを検索します。
"CertGetCertificateChain" イベントのエラー状態フラグを使用すると、エラーの状況を確認し、エラーの根本的な原因を絞り込むことができます。エラーの根本的な原因を検出するには、パス検証の一環として呼び出された他の API を調べます。ただし、インスタンスによってはこれらの API が直接呼び出されるため、相関関係のあるイベントのセットに "CertGetCertificateChain" イベントが存在しない場合があります。その場合は、これらの API に基づいたイベントを使用して、エラーの原因を直接調べます。このようなエラー イベントは、このドキュメントの「エラー シナリオ」で説明した、その他のイベントのいずれかになります。
手順 3 : エラーの根本的な原因を特定する
手順 2 では、特定のシナリオについて、それぞれのエラーの状況を確認し、検索の対象となる根本的な原因に関するエラーの数を絞り込みました。手順 3 では、この根本的な原因を特定します。この手順は、イベント ログの特定の操作または状態コードを調べることによって実行します。さまざまなシナリオに関する操作および状態コードについては、「エラー シナリオ」で説明しています。エラーの分類に基づいて、特定のイベントにおけるこれらの操作名と状態コードを検索します。たとえば、失効に関するエラーの場合は "CertRejectedRevocationInfo" エラー イベントを調べ、ネットワークの取得に関するエラーの場合は "CryptRetrieveObjectByUrlWire" エラー イベントを調べます。
この手順のアルゴリズムに対応したフローチャートを次の図に示します。
トラブルシューティングのプロセスを自動化する場合、上で説明した手順に従ってログを照会するコードを作成します。「付録 C」 のコード サンプルを参照してください。ここでは、トラブルシューティングのプロセスをエラーの診断に適用する方法が説明されています。「付録 B」には、このコード サンプルで使用されているクエリに類似した、さまざまなエラー シナリオに対応する XPATH クエリをいくつか紹介しています。
まとめ
CAPI2 診断では、証明書に関連するさまざまな操作 (証明書パス検証や署名の確認など) のための、詳細な情報を収集できます。この情報は、PKI 対応アプリケーションで PKI に関する問題をトラブルシューティングする場合に重要な情報となります。このドキュメントに記載されたシナリオやクエリに関する情報を使用すると、ログのデータを解釈し、イベント ログを検索して特定のパターンを確認し、問題の根本的な原因を特定することができます。CAPI2 診断は、PKI のトラブルシューティングを向上させる方法を提供します。また CAPI2 診断を使用することにより、一般的な問題をトラブルシューティングする場合にかかる時間を減らすことができます。
フィードバック
CAPI2 診断に関する質問やフィードバックがありましたら、microsoft.public.security.crypto ニュースグループに投稿してください。
付録
ここでは、次の内容について説明します。
-
付録 A : CAPI2 診断のイベント ログに含まれるイベント
-
付録 B : サンプルの XPATH クエリ
-
付録 C : パターンを特定するためのコード サンプル
-
付録 D : イベント ビューアを使用したフィルタ処理
-
付録 E : Windows の証明書関連ツール
付録 A : CAPI2 診断のイベント ログに含まれるイベント
次の表では、CAPI2 診断のログに記録される最上位のイベントについて説明します。
CAPI2 診断 : 最上位のイベント
| イベント名 | タスク | 説明 |
|---|---|---|
|
CertGetCertificateChain |
チェーンの作成 |
証明書パス検証の結果が示されます。 |
|
CertVerifyRevocation |
失効の確認 |
1 つまたは複数の証明書に対する失効確認の結果が示されます。ほとんどの場合、このイベントは "CertGetCertificateChain" の下で入れ子になり、アプリケーションが "CertVerifyRevocation" API を直接呼び出した場合にのみ、最上位のイベントとしてトリガされます。 |
|
CertVerifyCertificateChainPolicy |
チェーン ポリシーの確認 |
Windows で事前に定義されているポリシーに従って証明書チェーンを評価する、アプリケーションの結果が示されます。 |
|
CertOpenStore |
ストアを開く |
証明書ストアを開いた結果が示されます。 |
|
CryptRetrieveObjectByUrlWire |
オブジェクトをネットワークから取得 |
ネットワーク ダウンロードの結果が示されます。 |
|
CryptRetrieveObjectByUrlCache |
オブジェクトをキャッシュから取得 |
オブジェクトをディスク キャッシュから取得した結果が示されます。 |
|
CryptAcquireCertificatePrivateKey |
証明書の秘密キーの取得 |
証明書の秘密キーの取得を試行した結果が示されます。 |
|
WinVerifyTrust |
信頼の確認 |
"WinVerifyTrust" を使用した署名の確認の結果、および証明書チェーンの検証の結果が示されます。署名済みのコードが検証に失敗した理由も含まれています。 |
|
CryptCATAdminEnumCatalogFromHash |
ファイルのセキュリティ カタログの検索 |
カタログ検索の情報が含まれています。署名の確認の一環として、ファイルのハッシュが取得され、カタログ内で検索されます。その後で、カタログの署名が確認されます。このイベントでは、ファイルのハッシュ、カタログ ファイルのパス、およびターゲット ファイルのパスがログに記録されます。ファイルのハッシュは、このイベントおよび対応する "WinVerifyTrust" イベント間のリンクとして使用できます。 |
次の表では、CAPI2 診断 のログに記録される最上位のイベントの下で入れ子になる、下位のイベントについて説明します。
CAPI2 診断ログ : 下位のイベント
| イベント名 | タスク | 説明 |
|---|---|---|
|
CertAIAUrlRetrievalWire |
発行者証明書をネットワークから取得 |
発行者証明書をネットワークから取得した結果が示されます。 |
|
CertAIAUrlRetrievalCache |
発行者証明書をキャッシュから取得 |
発行者証明書をキャッシュから取得した結果が示されます。 |
|
CertAutoRootUrlRetrievalWire |
サード パーティのルート証明書をネットワークから取得 |
ルートの自動更新の一環として行った、サード パーティのルート証明書のダウンロード結果が示されます。 |
|
CertAutoRootUrlRetrievalCache |
サード パーティのルート証明書をキャッシュから取得 |
サード パーティのルート証明書をキャッシュから取得した結果が示されます。 |
|
CertCrossCertUrlRetrievalWire |
クロス証明書をネットワークから取得 |
クロス証明書のダウンロード結果が示されます。 |
|
CertCrossCertUrlRetrievalCache |
クロス証明書をキャッシュから取得 |
クロス証明書をキャッシュから取得した結果が示されます。 |
|
CertRejectAIAUrlRetrieval |
発行者証明書の取得の禁止 |
発行者証明書の取得が禁止された理由が含まれています。この理由は、URL の最大数を超過した場合の理由と類似している場合があります。 |
|
CertRejectedRevocationInfo |
失効情報の拒否 |
特定の CRL や OCSP 応答が拒否された理由が含まれています。このイベントは、CRL や OCSP がキャッシュ、ストア、またはネットワークから取得されたかどうかも示します。このイベントは、"CertVerifyRevocation" イベントの下で入れ子になります。 |
|
X509Objects |
X509 オブジェクト |
操作で使用された証明書オブジェクトの詳細が含まれています。X.509 オブジェクトの内容 (証明書、CRL、OCSP 応答など) は、このイベントの一部としてログに記録されます。 |
付録 B : サンプルの XPATH クエリ
XPATH を使用して、イベント ログ内の情報を照会し、問題をトラブルシューティングすることができます。イベント ログのデータを XML ファイル形式で保存すると、次の XPATH を使用して、ログに含まれる特定の情報を確認できます。
次の表に、このドキュメントの「一般的な問題のトラブルシューティング」で説明しているタスク、および対応する XPATH 式の一覧を示します。
XPATH クエリ : 一般的な問題のトラブルシューティング
| タスク | XPATH 式 |
|---|---|
|
チェーンの作成エラー イベントの検索 |
|
|
特定のアプリケーション (Internet Explorer など) に関連付けられているチェーンの作成エラー イベントの検索 |
|
|
特定のタスク ID を使用したすべてのイベントの検索 |
|
|
チェーンの要素に関連するエラー状態フラグの照会 |
|
次の表に、このドキュメントの「パスの検証エラー」で説明しているエラー、および対応する XPATH 式の一覧を示します。
XPATH クエリ : パスの検証エラー
| エラー | XPATH 式 |
|---|---|
|
証明書または証明書チェーン内にあるいずれかの証明書の有効期限切れ |
その他のパスの検証エラーについては、上の式の ErrorStatus フラグの値を、対応する値に置き換えてください。 |
次の表に、このドキュメントの「ネットワークの取得エラー」で説明しているエラー、および対応する XPATH 式の一覧を示します。
XPATH クエリ : ネットワークの取得エラー
| エラー | XPATH 式 |
|---|---|
|
HTTP 404 エラー |
その他の HTTP エラーについては、404 を、対応する状態コードに置き換えてください。 |
|
タイムアウト エラー |
オブジェクトが大きすぎる場合は、バックグラウンド スレッドのイベントを調べてください。
サーバーが使用できない場合は、WinHttpSendRequest の呼び出しが失敗しています。
|
|
プロキシを経由した接続に失敗 |
誤まったプロキシを特定するには、次のクエリを使用します。
|
|
LDAP エラー |
LDAP API の呼び出しの失敗を照会
|
|
エラー |
XPATH 式 |
|
HTTP 404 エラー |
その他の HTTP エラーについては、"404" を対応する状態コードに置き換えてください。 |
|
タイムアウト エラー |
オブジェクトが大きすぎる場合は、バックグラウンド スレッドのイベントを調べてください。
サーバーが使用できない場合は、WinHttpSendRequest の呼び出しが失敗しています。
|
|
プロキシを経由した接続に失敗 |
誤まったプロキシを特定するには、次のクエリを使用します。
|
|
LDAP エラー |
LDAP API の呼び出しの失敗を照会
|
次の表に、このドキュメントの「失効確認の失敗エラー」で説明しているエラー、および対応する XPATH 式の一覧を示します。
XPATH クエリ : 失効確認の失敗
| エラー | XPATH 式 |
|---|---|
|
有効期限切れの CRL |
|
|
CRL の署名を確認できない |
|
|
OCSP 応答を検証できない |
OCSP 応答の署名を検証できない場合は、次のクエリを使用します。
OCSP 応答のデコードに失敗した場合は、次のクエリを使用します。
|
|
承認されていない OCSP 署名者 |
|
|
OCSP 応答のデコードに失敗 |
|
|
CRL または OCSP 応答に、サポートされていない重要な拡張機能が含まれている |
|
|
OCSP 応答の状態が失敗を示す |
|
付録 C : パターンを特定するためのコード サンプル
このコード サンプルでは、「スマート カードを使用したログオンの失敗」で示したシナリオで発生するエラーの根本的な原因を検出する方法について説明します。このコードは、「トラブルシューティングを自動化する場合の一般的な考慮事項」で概要を説明したプロセスの実装も示しています。このコード サンプルを拡張して、さらに多くのエラー シナリオに対応することもできます。このサンプルを実行するには、CAPI2 診断 のイベント ログに含まれるイベントを XML ファイルに保存します。サンプルを実行するとき、この XML ファイルの名前をコマンド ライン引数として指定します。
このサンプル コードの主な関数は次のとおりです。
-
IdentifyPattern : エラー パターンを特定するための開始点です。相関関係のあるイベントの特定のシーケンスを対象とします。
-
ClassifyError : "CertGetCertificateChain" の "ErrorStatus" に基づく、パス検証のエラーに関する最上位の分類です。
-
CheckHTTPErrorPattern : HTTP エラーが原因となる取得エラーの分類を確認します。"CheckProxyErrorPattern" や "CheckTimeoutErrorPattern" なども同様な関数です。
-
ヘルパー関数 : その他の関数は、イベント ログから特定の情報を照会するためのヘルパー関数です。
Using System;
using System.IO;
using System.Xml;
using System.Xml.XPath;
using System.Collections;
using System.Text;
namespace CAPIDiagPatternIdentifier
{
class PatternIdentifier {
// エラーの状況に関する最上位の分類
const int OTHER_ERROR = 0;
const int REVOCATION_FAILURE = 1;
const int RETRIEVAL_ERROR = 2;
const int SIGNATURE_INVALID = 3;
const int UNTRUSTED_ROOT = 4;
const int PARTIAL_CHAIN = 5;
const int REVOKED = 6;
const string filePath = ".\\";
//ログの名前空間
const string logns = "http://schemas.microsoft.com/win/2004/08/events/event";
// エラー クエリとメッセージ文字列をここに定義します
// これは、ログ内の特定のパターンの検索で使用されます
const string err404qry = "//ns:CryptRetrieveObjectByUrlWire[ns:AuxInfo[@httpStatusCode='404']]";
const string err404msg = "CRL が CDP の URL にありません :";
private XmlDocument doc;
private XPathNavigator xpath;
private XmlNamespaceManager nsmanager;
public PatternIdentifier(string[] args) {
// XmlDocument オブジェクトを作成します
doc = new XmlDocument();
// コマンド ラインで指定したログを開きます
FileStream fs = new FileStream(args[0], FileMode.Open);
// ログを XML DOM に読み込みます
doc.Load(fs);
xpath = doc.CreateNavigator();
nsmanager = new XmlNamespaceManager(xpath.NameTable);
nsmanager.AddNamespace("ns", logns); }
public String GetTaskId(XmlNode eventNode) {
String TaskId = null;
XPathNavigator navigator = eventNode.CreateNavigator();
XPathNodeIterator itr = navigator.Select("@TaskId");
if (itr.MoveNext()) {
TaskId = itr.Current.Value;
}
return TaskId;
}
private String GetProcessName(XPathNavigator currentNode) {
String processName = null;
XPathNodeIterator itr = currentNode.Select("//@ProcessName");
if (itr.MoveNext()) {
processName = itr.Current.Value;
}
return processName ;
}
// すべてのネットワーク エラーを確認する共通の関数
private bool CheckNetworkRetrievalPattern(XPathNavigator currentNode, String evtQuery, String errString) {
XPathExpression evtqry = xpath.Compile(evtQuery);
evtqry.SetContext(nsmanager);
if (currentNode.Matches(evtqry) && (currentNode is IHasXmlNode)) {
XmlNode node = ((IHasXmlNode)currentNode).GetNode();
string URL = (node.SelectSingleNode("ns:URL", nsmanager)).InnerXml;
System.Console.WriteLine("ネットワークの取得に失敗しました。 "+ errString + URL);
return true;
} return false;
}
// HTTP エラーを確認します
private bool CheckHTTPErrorPattern(XPathNavigator currentNode) {
if (CheckNetworkRetrievalPattern(currentNode, err404qry, err404msg)) return true;
// ここにその他の HTTP エラーを追加します
return false;
}
private bool isInArray(ArrayList al, string val) {
for (int i = 0; i < al.Count; ++i) {
if (val == (string)al[i]) {
return true;
}
}
return false;
}
public void IdentifyPattern(XPathNodeIterator eventNodes, string TaskId) {
if (eventNodes.Count > 0) {
while (eventNodes.MoveNext()) {
String fileRef = null;
String subjectName = null;
String processName = null ;
int errorType = 0;
// エラーがあるチェーンの要素を調べます XPathExpression
errQuery = xpath.Compile("//ns:CertGetCertificateChain[ns:Result[@value!='0']]");
errQuery.SetContext(nsmanager);
if (eventNodes.Current.Matches(errQuery)) {
// チェーンの要素にエラーがあることが判明しました
// 要素とエラーに関するデータをさらに取得します
errorType = ClassifyError(eventNodes, ref fileRef, ref subjectName, ref processName);
}
// 次に、このエラーの原因を特定します。
switch (errorType) {
case RETRIEVAL_ERROR:
{
while (eventNodes.MoveNext()) {
if (CheckHTTPErrorPattern(eventNodes.Current)) break;
//ここで、その他のネットワーク エラーを確認します
}
break;
}
//分類ごとにさらにケースを追加します
case OTHER_ERROR:
{
//上のケースでは、その他のエラーに対応していません。
break;
}
}
}
eventNodes = null;
}
}
//エラーの状況に関する最上位の分類 (アルゴリズムの手順 2)
//特定のエラーの状況に対応したチェーンの要素を検索します
private int ClassifyError(XPathNodeIterator eventNodes, ref String fileRef, ref String subjectName, ref String processName) {
processName = GetProcessName(eventNodes.Current);
System.Console.WriteLine("エラーの原因となるアプリケーション :" + processName);
XPathNodeIterator chainElement = eventNodes.Current.SelectDescendants("ChainElement", logns, false);
while (chainElement.MoveNext()) {
XPathExpression statusQuery1 =
xpath.Compile("//ns:ChainElement[ns:TrustStatus[ns:ErrorStatus[@CERT_TRUST_REVOCATION_STATUS_UNKNOWN]]]");
XPathExpression statusQuery2 = xpath.Compile("//ns:ChainElement[ns:TrustStatus[ns:ErrorStatus[@CERT_TRUST_IS_OFFLINE_REVOCATION]]]");
XPathExpression statusQuery3 = xpath.Compile("//ns:ChainElement[ns:TrustStatus[ns:ErrorStatus[@CERT_TRUST_IS_NOT_SIGNATURE_VALID]]]");
XPathExpression statusQuery4 = xpath.Compile("//ns:ChainElement[ns:TrustStatus[ns:ErrorStatus[@CERT_TRUST_IS_UNTRUSTED_ROOT]]]");
XPathExpression statusQuery5 = xpath.Compile("//ns:ChainElement[ns:TrustStatus[ns:ErrorStatus[@CERT_TRUST_IS_PARTIAL_CHAIN]]]");
XPathExpression statusQuery6 = xpath.Compile("//ns:ChainElement[ns:TrustStatus[ns:ErrorStatus[@CERT_TRUST_IS_REVOKED]]]");
statusQuery1.SetContext(nsmanager);
statusQuery2.SetContext(nsmanager);
statusQuery3.SetContext(nsmanager);
statusQuery4.SetContext(nsmanager);
statusQuery5.SetContext(nsmanager);
statusQuery6.SetContext(nsmanager);
chainElement.Current.MoveToChild("Certificate", logns);
fileRef = chainElement.Current.GetAttribute("fileRef", "");
subjectName = chainElement.Current.GetAttribute("subjectName", "");
chainElement.Current.MoveToParent();
if (chainElement.Current.Matches(statusQuery5)) {
System.Console.WriteLine("パスの検証が次のサブジェクト名の証明書で失敗しました :" + subjectName + " (" + fileRef + ") 完全な証明書チェーンを構築できなかったためです");
return PARTIAL_CHAIN;
}
else if (chainElement.Current.Matches(statusQuery4)) {
System.Console.WriteLine("パスの検証が次のサブジェクト名の証明書で失敗しました :" + subjectName + " (" + fileRef + ") 信頼されたルートまでチェーンが作成されていないためです");
return UNTRUSTED_ROOT;
}
else if (chainElement.Current.Matches(statusQuery3)) {
System.Console.WriteLine("パスの検証が次のサブジェクト名の証明書で失敗しました :" + subjectName + " (" + fileRef + ") 署名を確認できなかったためです");
return SIGNATURE_INVALID;
}
else if (chainElement.Current.Matches(statusQuery2)) {
System.Console.WriteLine("失効確認が次のサブジェクト名の証明書で失敗しました :"+ subjectName + " (" + fileRef + ") 失効サーバーがオフラインであるためです");
return RETRIEVAL_ERROR;
}
else if (chainElement.Current.Matches(statusQuery1)) {
System.Console.WriteLine("サブジェクト名 :" + subjectName + " (" + fileRef + ") の証明書の失効状態を確認できませんでした");
return REVOCATION_FAILURE;
}
else if (chainElement.Current.Matches(statusQuery6)) {
System.Console.WriteLine("証明書が失効しています");
return REVOKED;
}
}
return OTHER_ERROR;
}
//XML イベント ログ ファイルはプログラムのコマンド ライン引数です
static void Main(string[] args) {
PatternIdentifier mainProg = new PatternIdentifier(args);
XmlNode root = mainProg.doc.DocumentElement;
//すべてのエラー イベントの TaskId を確認します
XmlNodeList errEvents = root.SelectNodes("//ns:Event[ns:System/ns:Level=2]//ns:CorrelationAuxInfo",mainProg.nsmanager);
ArrayList tasks = new ArrayList();
foreach (XmlNode errEvent in errEvents) {
string taskId = null;
taskId = mainProg.GetTaskId(errEvent);
if (!mainProg.isInArray(tasks, taskId)) {
tasks.Add(taskId);
}
}
//各 TaskId を調べ、同じ TaskId を持つすべてのイベントを関連付け、相関関係のあるイベントのセットに含まれているエラー パターンを特定します。
for (int i = 0; i < tasks.Count; ++i) {
string TaskId = (string)tasks[i];
XPathExpression eventQuery = mainProg.xpath.Compile("//ns:CorrelationAuxInfo[@TaskId='" + TaskId + "']/parent::*");
eventQuery.SetContext(mainProg.nsmanager);
XPathNodeIterator eventNodes = mainProg.xpath.Select(eventQuery);
mainProg.IdentifyPattern(eventNodes,TaskId);
}
System.Console.Read();
}
}
}
付録 D : イベント ビューアを使用したフィルタ処理
イベント ビューアのフィルタを使用してクエリを手動で作成し、特定のイベントを表示できます。
イベント ビューアのフィルタを使用してクエリを手動で作成するには-
イベント ビューアを開きます。 イベント ビューアを開くには、[スタート] ボタン、[コントロール パネル] の順にクリックし、[管理ツール]、[イベント ビューア] の順にダブルクリックします。
-
[ユーザー アカウント制御] ダイアログ ボックスが表示された場合、このボックスに希望する動作が表示されていることを確認し、[継続] をクリックします。
-
コンソール ウィンドウで、[イベント ビューア]、[アプリケーションとサービス ログ]、[Microsoft]、[Windows]、および [CAPI2] の順に展開します。
-
[Operational] を右クリックし、[現在のログをフィルタ] を選択します。
-
[XML] タブを選択し、[手動でクエリを編集する] チェック ボックスをオンにします。
-
ログをフィルタ処理するには、対応するクエリをテキスト ボックスに入力します。
-
"iexplore.exe" というプロセス名を持つすべての "CertGetCertificateChain" エラー イベントを検索するには、次のクエリをテキスト ボックスに入力します。
<QueryList> <Query Id="0" Path="Microsoft-Windows-CAPI2/Operational"> <Select Path="Microsoft-Windows-CAPI2/Operational">Event[System[(Level=2)] and UserData[CertGetCertificateChain[EventAuxInfo[@ProcessName='iexplore.exe']]]]</Select> </Query> </QueryList>
-
特定の "CertGetCertificateChain" エラー イベントに対応する、相関関係のあるすべてのイベントを特定する場合は、イベント ビューアのフィルタで次のクエリを使用できます (この {taskid} とは、"CertGetCertificateChain" エラー イベントのタスク ID です)。
<QueryList> <Query Id="0" Path="Microsoft-Windows-CAPI2/Operational"> <Select Path="Microsoft-Windows-CAPI2/Operational">*[*[*[CorrelationAuxInfo[@TaskId='{taskid}']]]]</Select> </Query> </QueryList>
-
"iexplore.exe" というプロセス名を持つすべての "CertGetCertificateChain" エラー イベントを検索するには、次のクエリをテキスト ボックスに入力します。
付録 E : Windows の証明書関連ツール
CAPI2 診断は、Windows Vista で使用できます。Windows の以前のバージョンで問題のトラブルシューティングに使用できる、既存の診断ツールがあります。CryptoAPI Monitor (CAPIMON) は、管理者がアプリケーションでの CryptoAPI の呼び出しとその結果を監視できるツールです。CAPIMON は、エラーを適切に報告しない既存のアプリケーションをトラブルシューティングするために作成されました。このトラブルシューティングでは、アプリケーションのエラー報告やログに依存せずに、特定の API の入力と出力を取得します。CAPIMON は、Windows の以前のバージョンで使用できるトラブルシューティング ツールで、アプリケーションのエラー報告では失敗の原因が示されない場合に適しています。CAPIMON をダウンロードするには、http://go.microsoft.com/fwlink/?LinkId=82293 (英語の可能性あり) を参照してください。
証明書、キーの組、および証明書チェーンを検証するには、コマンド ライン ユーティリティ certutil.exe を使用できます。Certutil は、証明書サービスの構成や構成情報の表示を行う場合に役立ちます。Certutil の詳細については、http://go.microsoft.com/fwlink/?LinkId=82294 (英語の可能性あり) を参照してください。
詳細情報
さらに詳しい情報については、以下のドキュメントを参照してください。
-
RFC: "Internet Public Key Infrastructure Certificate and Certificate Revocation List (CRL) Profile"
-
RFC: "X.509 Internet Public Key Infrastructure Online Certificate Status Protocol – OCSP"
-
証明書の失効と状態の確認についてのトラブルシューティングに関するページ (英語の可能性あり)
-
Microsoft Windows Server 2003 の公開キー基盤を実装する際のベスト プラクティスに関するページ (英語の可能性あり)
-
Windows Vista プライバシーに関する声明のハイライト
-
暗号化関数に関するページ (英語の可能性あり)
-
Windows Vista でのサポート費用の削減に関するページ (英語の可能性あり)
-
XPATH での Infosets の対応に関するページ (英語の可能性あり)

注