TsgcUDPServer › Events › OnDTLSVerifyPeer

OnDTLSVerifyPeer Event

Fires during the DTLS handshake so the server can inspect and accept or reject the client certificate.

Syntax

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

Parameters

NameTypeDescription
SenderTObjectThe component that fired the event.
CertificateTIdX509The certificate currently being verified. Read Subject, Issuer, SerialNumber, notBefore, notAfter or FingerprintAsString from it. The object belongs to the DTLS engine, it is valid only for the duration of the call and must not be freed by the handler.
AOkBooleanThe verdict OpenSSL has already reached for this certificate. True when the chain check and the VerifyDepth check passed, False when either of them failed. Return this value to honour it.
ADepthIntegerPosition of Certificate in the chain. The event is fired once per certificate, 0 is the client certificate itself and higher values walk up towards the root.
AErrorIntegerThe OpenSSL verification error code for this certificate (one of the X509_V_ERR_ constants), 0 when no error was detected.

Return Value

True accepts the certificate and lets the handshake continue, False rejects it and terminates the handshake. This is the value that decides the outcome, so return AOk to honour the verdict of OpenSSL, and return False for the certificates the application rejects under its own rules. Returning True unconditionally discards the chain check and the depth check, which is exactly the behaviour the enforcement change removed from the library. When no handler is assigned the library returns AOk, so an application only needs a handler to add rules of its own, not to get correct chain behaviour. (Boolean)

Default Value

—

Remarks

Fired by the DTLS engine during the handshake with a new peer when DTLS is True and DTLSOptions.VerifyCertificate is enabled. Use the event to apply application-specific validation rules on top of the chain validation performed by OpenSSL, for example pinning the expected Common Name, checking a certificate revocation list or logging the certificate fingerprint before allowing the datagram exchange to proceed. The handler must be implemented in a thread-safe manner because it is invoked on the DTLS reader thread before any application payload is delivered.

The chain validation is now genuinely enforced. Previously the result computed by OpenSSL was discarded, so with VerifyCertificate = True any client certificate was accepted, including one issued by an untrusted authority. A certificate whose chain fails to verify now terminates the handshake. VerifyCertificate is False by default, so neither the chain validation nor this event runs until you switch it on. The value returned by the handler is what decides the outcome, and when no handler is assigned the library returns AOk, so an application only needs a handler to add rules of its own, not to get correct chain behaviour.

TsgcRTCPeerConnection is not affected. WebRTC authenticates the other end by the fingerprint carried in the SDP, not by a certificate chain, and leaves VerifyCertificate off. That is the normal WebRTC configuration and it keeps working exactly as before.

Example

function TForm1.oServerDTLSVerifyPeer(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 client 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 only one issuer is accepted
  if Result and (ADepth = 0) then
    Result := Pos('/O=Acme Devices', Certificate.Issuer.OneLine) > 0;
end;

Back to Events