TsgcUDPCLient › Events › 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 引擎,仅在本次调用期间有效,处理程序不得释放它。
AOkBooleanOpenSSL 已经对该证书作出的判定结果。证书链检查和 VerifyDepth 检查均通过时为 True,其中任一项失败时为 False。返回该值即表示采纳这一判定。
ADepthIntegerCertificate 在证书链中的位置。该事件对每个证书触发一次,0 表示对端证书本身,值越大表示越接近根证书。
AErrorInteger该证书的 OpenSSL 验证错误代码(X509_V_ERR_ 常量之一),未检测到错误时为 0。

返回值

返回 True 表示接受该证书并让握手继续,返回 False 表示拒绝该证书并终止握手。决定最终结果的正是这个返回值,因此若要采纳 OpenSSL 的判定,请返回 AOk;对于应用程序按自身规则拒绝的证书,请返回 False。无条件返回 True 会丢弃证书链检查和深度检查,而这正是本次强制执行改动从库中移除的行为。未指定处理程序时,库会返回 AOk,因此应用程序只有在需要添加自己的规则时才需要处理程序,而不是为了获得正确的证书链行为。(Boolean)

默认值

—

备注

当 DTLS 为 True 且 DTLSOptions.VerifyCertificate 启用时,DTLS 引擎在握手期间触发此事件。使用此事件应用特定于应用程序的验证规则(例如,固定预期的通用名称、检查自定义证书存储或记录证书指纹),以补充 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;

返回事件