3

署名チェーンからの証明書が、 Windows によって信頼されていない特定のルート証明書に戻っていることを確認しようとしています (これはアプリのプライベート証明書です)。

これを行う私の現在の試みには、ルートとして必要な特定の証明書のみを信頼するチェーン エンジンを作成することが含まれているため、他のチェーンは生成されません。

HCERTSTORE hPrivateRootStore = CertOpenStore(CERT_STORE_PROV_FILENAME, dwEncoding,
    NULL, CERT_STORE_OPEN_EXISTING_FLAG | CERT_STORE_READONLY_FLAG,
    _T("C:\\Test\\PrivateRoot.cer"));
CERT_CHAIN_ENGINE_CONFIG config;
memset(&config, 0, sizeof(config));
config.cbSize = sizeof(config);
config.hRestrictedTrust = hPrivateRootStore;
config.dwFlags = CERT_CHAIN_CACHE_ONLY_URL_RETRIEVAL | CERT_CHAIN_ENABLE_SHARE_STORE;
HCERTCHAINENGINE hEngine;
CertCreateCertificateChainEngine(&config, &hEngine);
CERT_CHAIN_PARA params;
memset(&params, 0, sizeof(params));
params.cbSize = sizeof(params);
PCCERT_CHAIN_CONTEXT chains = NULL;
if (CertGetCertificateChain(hEngine, pCertContext, NULL, hStore, &params,
    0, NULL, &chains))
   ...

(わかりやすくするためにエラー チェックは省略されています。pCertContextまた、署名付きバイナリ ファイルhStoreからCryptQueryObject署名と関連する証明書を抽出することによってエラー チェックが行われます。)

残念ながら、これはうまくいかないようです。カスタムチェーンエンジンを使用しているにもかかわらず、OSストアを検索しているようで、チェーンが見つからないか、別のルート(OSによって信頼されている)へのチェーンが見つかります。OS の信頼できるストアにプライベート ルート証明書を追加することによってのみ、必要なチェーンを取得できます。

config.hRestrictedOtherドキュメントでは、非 NULL を使用するとシステム ストアが再度読み込まれることが示唆されているため、空のメモリ ストアに設定しようとしましhRestrictedTrustたが、違いはありません。

私が見逃しているもの、またはこれを行うためのより良い方法はありますか?

編集:もう少しコンテキストを提供するために、署名証明書が2つの異なるルートにチェーンバックするドライバー署名証明書に似た何かをしようとしています:OSによって信頼される1つの標準CAルートと1つの内部ルート(これはドライバーも OS によって信頼されますが、私の場合はアプリによってのみ信頼されます)。クロスは、「メイン」チェーンの途中で発生します。すべてが異なる「実際の」CAで署名されているが、内部証明書に連鎖している多数の異なるファイルが潜在的に存在する可能性があります。

4

1 に答える 1

2

私は中途半端な回避策を見つけました。少し醜いですが、ちょっとうまくいきます。基本的なアイデアはChromium のテスト スイートから得ました。Crypt32 にフックをインストールして、システム ストアを開いてチェーンを構築しようとしたときに、代わりに、目的の証明書のみを含むカスタム ストアを取得するようにします。

CertGetCertificateChain良い点は、これが実際の CA 証明書を「通過」し、CA 証明書で停止するのではなく、カスタム証明書までチェーンすることを強制しているように見えることです(これは、信頼されている場合に通常行うことです)。

悪い点は、チェーンを構築して他の CA 証明書を信頼することを止めないように見えることです。チェーンのルートが必要な証明書であることを明示的に確認することで回避できますが、理想的とは言えず、つまずく状況があるかどうかはわかりません。

より良い解決策をまだ探しています。どこかで間違った道を進んでいるという印象を確実に受けています。

よし、新企画。私は今、次のような基本構造で、チェーンを手動で歩いています (私が関心のあるすべての証明書はhStore、署名された .exe から抽出されたものになることがわかっているため):

  • WinVerifyTrust基本的な「改ざんされていないか」認証を行うために使用します。
  • .exe からCryptQueryObject証明書ストアを取得するために使用しますhStore
  • CryptMsgGetParamとを使用しCertFindCertificateInStoreて、 から署名証明書を見つけますhStore
  • 署名証明書から始めて、ループ内でCertFindCertificateInStorewithを使用して潜在的な発行者証明書を見つけます。CERT_FIND_SUBJECT_NAME自己署名証明書に到達するか、目的のルートが見つかるまで戻り続けます (を介して一致を確認しますCertComparePublicKeyInfo)。
  • CertVerifySubjectCertificateContext署名が一致しないと言われたら、特定のブランチを放棄します。

私が試していた以前のアプローチよりもきれいに見えます。考え/コメント/代替案はありますか?

(いくつかの点でより理にかなっているように見えるものは、このような証明書をチェーンしようとする代わりに、[タイムスタンプに似た]追加のカスタム副署名を追加することですが、それを行うことに関する情報や、賛否両論あります。)

于 2011-09-27T02:39:05.953 に答える