TsgcWebSocketClient | SChannel Certificate Revocation

TLSOptions.VerifyCertificateをTrueに設定すると、サーバー証明書チェーンが信頼できること、および接続先のホスト名が証明書に記載されていることが確認されます。しかし、その証明書が発行後に失効させられたかどうかについては何も分かりません。

このギャップは重要です。証明書が失効しているものの、まだ有効期限が切れていない盗まれた秘密鍵は、依然として認証に成功します。これはまさに失効の仕組みが対象とするケースです。失効の確認は、TLSOptions.SChannel_Options.Revocationを通じて明示的に要求した場合にのみ行われます。


oClient.TLS := True;
oClient.TLSOptions.IOHandler := iohSChannel;
oClient.TLSOptions.VerifyCertificate := True;
oClient.TLSOptions.SChannel_Options.Revocation.Check := scrcChainExcludeRoot;

失効状態は証明書チェーンの構築中に取得されます。つまり、証明書に指定されたCRL配布ポイントまたはOCSPレスポンダーには、ハンドシェイク中にアクセスが行われます。チェックがデフォルトで無効になっているのはこのためです。有効にすると、新しい接続ごとにネットワークトラフィックが追加されます。

Check

チェーンのどの範囲まで失効状態を照会するかを選択します。

scrcDisabled デフォルト。失効状態は取得されず、必須でもありません。
scrcEndCertificate サーバー証明書のみをチェックします。最も負荷の低いオプションで、接続ごとに1回の照会で済みます。
scrcChainExcludeRoot サーバー証明書と中間証明書をチェックし、ルート証明書はチェックしません。自己署名のルート証明書が自身のCRLを公開することはほとんどないため、通常はこれを選択します。
scrcChain ルート証明書を含むチェーン全体。

Timeout

失効情報の取得全体に許可されるミリ秒数です。URLごとではないため、応答しないレスポンダーがハンドシェイクを停滞させることはありません。デフォルトは5000です。値をゼロにするとWindowsのデフォルトが適用され、これはかなり長くなる場合があります。

CacheOnly

Trueの場合、Windowsが既にキャッシュしている失効データのみが使用され、ハンドシェイクがネットワークにアクセスすることはないため、遅延が発生することもありません。ただしキャッシュが空の場合は状態が不明のままとなり、その扱いはIgnoreNoRevocationCheckが決定します。デフォルトはFalseです。

IgnoreRevocationOffline

レスポンダーに到達できなかった場合の動作を決定します。デフォルトはTrueで、証明書を受け入れます。これはWebブラウザーが採用しているソフトフェイルの動作です。代わりに拒否するにはFalseに設定します。拒否する方が厳格ですが、すべての接続がレスポンダーへの到達可能性に依存することになるため、レスポンダーの障害がアプリケーションの障害になります。

IgnoreNoRevocationCheck

証明書がCRL配布ポイントもOCSPレスポンダーもまったく公開しておらず、その状態を確定できない場合の動作を決定します。デフォルトはTrueで、受け入れます。

どちらのIgnoreプロパティも、失効が確認された証明書を受け入れることはありません。この結果は常に拒否されます。

報告されるエラー

接続が拒否された場合、その理由はOnSChannelVerifyPeerイベントに次のいずれかとして通知されます:

ecCryptRevoked 証明書が発行者によって失効させられています。常に拒否されます。
ecCryptRevocationOffline レスポンダーに到達できませんでした。IgnoreRevocationOfflineがFalseの場合にのみ拒否されます。
ecCryptNoRevocationCheck 証明書が失効情報を公開していません。IgnoreNoRevocationCheckがFalseの場合にのみ拒否されます。

安全なデフォルト

TLSOptions.PresettlspSecureDefaultsに設定すると、他の強化されたデフォルト設定とともに、チェックがscrcChainExcludeRootとして有効になります。2つのソフトフェイル設定はそのまま維持されるため、これを有効にしても、それまで機能していた接続が動作しなくなることはありません。プリセットを適用する前に自分で選択した範囲は変更されません。


oClient.TLSOptions.Preset := tlspSecureDefaults;