TsgcWebSocketClient | SChannel Certificate Revocation

Setting TLSOptions.VerifyCertificate to True establishes that the server certificate chain is trusted and that it names the host being connected to. It says nothing about whether that certificate has been revoked since it was issued.

That gap matters: a stolen private key whose certificate has been revoked but has not yet expired still authenticates successfully, which is precisely the case revocation exists to cover. Revocation is checked only when it is asked for, through TLSOptions.SChannel_Options.Revocation.


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

The status is retrieved while the certificate chain is built, which means the CRL distribution point or OCSP responder named by the certificate is contacted during the handshake. That is why the check is off by default: enabling it adds network traffic to every new connection.

Check

Selects how much of the chain has its revocation status looked up.

scrcDisabled Default. No revocation status is retrieved and none is required.
scrcEndCertificate Only the server certificate is checked. The cheapest option, one lookup per connection.
scrcChainExcludeRoot The server certificate and the intermediate certificates are checked, the root is not. The usual choice, because a self-signed root rarely publishes a CRL for itself.
scrcChain The whole chain including the root.

Timeout

Milliseconds allowed for the whole revocation retrieval, not per URL, so a responder that does not answer cannot stall the handshake. Default 5000. A value of zero leaves the Windows default in force, which can be considerably longer.

CacheOnly

When True, only revocation data Windows has already cached is used and the handshake never goes to the network, so it is never delayed. A cold cache then leaves the status unknown, which IgnoreNoRevocationCheck decides. Default False.

IgnoreRevocationOffline

Decides what happens when the responder could not be reached. Default True, accept the certificate, which is the soft-fail behaviour web browsers use. Set it to False to reject instead. Rejecting is stricter, but it makes every connection depend on the responder being reachable, so a responder outage becomes an outage of your application.

IgnoreNoRevocationCheck

Decides what happens when the certificate publishes no CRL distribution point and no OCSP responder at all, so its status cannot be established. Default True, accept it.

Neither Ignore property ever accepts a certificate that came back confirmed revoked. That outcome is always rejected.

Reported errors

When the connection is refused, the reason reaches the OnSChannelVerifyPeer event as one of:

ecCryptRevoked The certificate has been revoked by its issuer. Always rejected.
ecCryptRevocationOffline The responder could not be reached. Only rejected when IgnoreRevocationOffline is False.
ecCryptNoRevocationCheck The certificate publishes no revocation information. Only rejected when IgnoreNoRevocationCheck is False.

Secure defaults

Setting TLSOptions.Preset to tlspSecureDefaults enables the check as scrcChainExcludeRoot, together with the other hardened defaults, and keeps the two soft-fail settings, so switching it on does not break a connection that used to work. A scope you chose yourself before applying the preset is left untouched.


oClient.TLSOptions.Preset := tlspSecureDefaults;