TsgcUDPCLient › Events › OnDTLSVerifyPeer
Fires during the DTLS handshake so the application can inspect and accept or reject the peer certificate.
property OnDTLSVerifyPeer: TsgcUDPDTLSVerifyPeerEvent;
// TsgcUDPDTLSVerifyPeerEvent = function(Sender: TObject; Certificate: TIdX509; AOk: Boolean; ADepth, AError: Integer): Boolean of object
| Name | Type | Description |
|---|---|---|
Sender | TObject | The component that fired the event. |
Certificate | TIdX509 | The 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. |
AOk | Boolean | The 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. |
ADepth | Integer | Position of Certificate in the chain. The event is fired once per certificate, 0 is the peer certificate itself and higher values walk up towards the root. |
AError | Integer | The OpenSSL verification error code for this certificate (one of the X509_V_ERR_ constants), 0 when no error was detected. |
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)
—
Fired by the DTLS engine during the handshake when DTLS is True and DTLSOptions.VerifyCertificate is enabled. Use the event to apply application-specific validation rules (for example, pinning the expected Common Name, checking a custom certificate store, or logging the certificate fingerprint) on top of the chain validation performed by OpenSSL. The handler must be implemented in a thread-safe manner because it is invoked on the DTLS reader thread before any datagram is accepted.
The chain validation is now genuinely enforced. Previously the result computed by OpenSSL was discarded, so with VerifyCertificate = True any 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.
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;