TsgcUDPCLient › イベント › OnDTLSVerifyPeer

OnDTLSVerifyPeer イベント

DTLSハンドシェイク中に発火し、アプリケーションがピア証明書を検査して承認または拒否できるようにします。

構文

property OnDTLSVerifyPeer: TsgcUDPDTLSVerifyPeerEvent;
// TsgcUDPDTLSVerifyPeerEvent = function(Sender: TObject; Certificate: TIdX509; AOk: Boolean; ADepth, AError: Integer): Boolean of object

パラメータ

名前タイプ説明
SenderTObjectイベントを発生させたコンポーネント。
CertificateTIdX509現在検証中の証明書。Subject、Issuer、SerialNumber、notBefore、notAfter、FingerprintAsString などを読み取れます。このオブジェクトは DTLS エンジンが所有しており、呼び出しの間だけ有効です。ハンドラーで解放しないでください。
AOkBooleanこの証明書について OpenSSL がすでに下した判定。チェーンのチェックと VerifyDepth のチェックの両方に合格した場合は True、いずれかに失敗した場合は False です。この判定に従うにはこの値をそのまま返してください。
ADepthIntegerチェーン内での Certificate の位置。イベントは証明書ごとに 1 回発生し、0 はピア証明書自身を表し、値が大きくなるほどルートに近づきます。
AErrorIntegerこの証明書に対する OpenSSL の検証エラーコード(X509_V_ERR_ 定数のいずれか)。エラーが検出されなかった場合は 0 です。

戻り値

True を返すと証明書が受け入れられてハンドシェイクが続行され、False を返すと証明書が拒否されてハンドシェイクが終了します。結果を決めるのはこの戻り値です。OpenSSL の判定に従う場合は AOk を返し、アプリケーション独自のルールで拒否する証明書については False を返してください。無条件に True を返すとチェーンのチェックと深さのチェックが無視されますが、これはまさに、適用が強化されたことでライブラリから取り除かれた動作です。ハンドラーが割り当てられていない場合、ライブラリは AOk を返します。したがって、正しいチェーン動作を得るためにハンドラーが必要なわけではなく、独自のルールを追加する場合にのみ必要です。(Boolean)

デフォルト値

—

解説

DTLS が True で DTLSOptions.VerifyCertificate が有効な場合にハンドシェイク中に DTLS エンジンによって発生します。このイベントを使用して、アプリケーション固有の検証ルール (例: 期待される Common Name のピン留め、カスタム証明書ストアの確認、証明書フィンガープリントのログ記録) を OpenSSL によって実行されるチェーン検証に加えて適用します。ハンドラーはデータグラムが受け入れられる前に DTLS リーダースレッドで呼び出されるため、スレッドセーフに実装する必要があります。

チェーン検証は実際に適用されるようになりました。以前は OpenSSL が算出した結果が破棄されていたため、VerifyCertificate = True であっても、信頼されていない認証局が発行した証明書を含め、あらゆる証明書が受け入れられていました。現在はチェーンの検証に失敗した証明書があるとハンドシェイクが終了します。VerifyCertificate のデフォルトは False であるため、有効にするまではチェーン検証もこのイベントも実行されません。結果を決めるのはハンドラーの戻り値であり、ハンドラーが割り当てられていない場合、ライブラリは AOk を返します。したがって、正しいチェーン動作を得るためにハンドラーが必要なわけではなく、独自のルールを追加する場合にのみ必要です。

TsgcRTCPeerConnection は影響を受けません。WebRTC は証明書チェーンではなく SDP に含まれるフィンガープリントで相手側を認証し、VerifyCertificate は無効のままです。これが通常の WebRTC 構成であり、従来とまったく同じように動作します。

使用例

function TForm1.oClientDTLSVerifyPeer(Sender: TObject; Certificate: TIdX509;
  AOk: Boolean; ADepth, AError: Integer): Boolean;
begin
  // start from the verdict OpenSSL already reached
  Result := AOk;
  Memo1.Lines.Add(Format('DTLS peer certificate, depth %d, ok %s, error %d, subject %s',
    [ADepth, BoolToStr(AOk, True), AError, Certificate.Subject.OneLine]));
  // add the rules of the application on top, here the expected name is pinned
  if Result and (ADepth = 0) then
    Result := Pos('/CN=dtls.example.com', Certificate.Subject.OneLine) > 0;
end;

イベントに戻る