Ustawienie SSLOptions.VerifyCertificate na True sprawia, że serwer żąda certyfikatu od każdego przychodzącego klienta i weryfikuje przedstawiony przez niego łańcuch. Ta weryfikacja potwierdza, że łańcuch klienta jest zaufany. Nie mówi natomiast nic o tym, czy certyfikat klienta został unieważniony od chwili jego wystawienia.
Ta luka ma znaczenie wszędzie tam, gdzie certyfikat pełni rolę poświadczenia: laptop zostaje zgubiony albo pracownik odchodzi z firmy, wystawiony mu certyfikat zostaje unieważniony, a mimo to aż do dnia wygaśnięcia nadal otwiera sesję na Twoim serwerze. Stan unieważnienia jest sprawdzany tylko wtedy, gdy zostanie to zażądane, za pomocą SSLOptions.SChannel_Options.Revocation.
Ustawienia unieważniania są odczytywane podczas weryfikacji certyfikatu klienta, więc nie mają żadnego działania, dopóki SSLOptions.VerifyCertificate nie ma wartości True, ponieważ to właśnie ta właściwość sprawia, że serwer w ogóle żąda certyfikatu od klienta. To, czy klient, który nie przedstawia żadnego certyfikatu, zostaje odrzucony, czy przepuszczony, jest odrębną decyzją, podejmowaną przez SSLOptions.VerifyCertificate_Options.FailIfNoCertificate.
oServer.SSL := True;
oServer.SSLOptions.IOHandler := iohSChannel;
oServer.SSLOptions.VerifyCertificate := True;
oServer.SSLOptions.VerifyCertificate_Options.FailIfNoCertificate := True;
oServer.SSLOptions.SChannel_Options.Revocation.Check := scrcChainExcludeRoot;
Stan jest pobierany podczas budowania łańcucha certyfikatów, co oznacza, że punkt dystrybucji CRL lub responder OCSP wskazany przez certyfikat klienta jest odpytywany w trakcie uzgadniania. Dlatego to sprawdzanie jest domyślnie wyłączone: umieszcza ono zapytanie wychodzące na drodze każdego połączenia przyjmowanego przez serwer.
Określa, dla jakiej części łańcucha klienta pobierany jest stan unieważnienia.
| scrcDisabled | Wartość domyślna. Stan unieważnienia nie jest pobierany ani wymagany. |
| scrcEndCertificate | Sprawdzany jest tylko sam certyfikat klienta. Najtańsza opcja, jedno zapytanie na połączenie. |
| scrcChainExcludeRoot | Sprawdzane są certyfikat klienta i certyfikaty pośrednie, które go wystawiły, certyfikat główny nie. Zwykły wybór, ponieważ certyfikat główny urzędu certyfikacji wystawiającego Twoje certyfikaty klienta rzadko publikuje listę CRL dla samego siebie. |
| scrcChain | Cały łańcuch wraz z certyfikatem głównym. |
Liczba milisekund przeznaczona na całe pobranie informacji o unieważnieniu, a nie na pojedynczy adres URL, dzięki czemu responder, który nie odpowiada, nie może zablokować uzgadniania, gdy serwer na niego czeka. Wartość domyślna to 5000. Wartość zero pozostawia w mocy domyślne ustawienie systemu Windows, które może być znacznie dłuższe.
Przy wartości True używane są wyłącznie dane o unieważnieniu, które system Windows ma już w pamięci podręcznej, a uzgadnianie nigdy nie sięga do sieci, więc przychodzące połączenie nigdy nie jest opóźniane przez respondera. Pusta pamięć podręczna pozostawia wówczas stan nieznany, o czym rozstrzyga IgnoreNoRevocationCheck. Wartość domyślna to False.
Rozstrzyga, co się dzieje, gdy nie udało się połączyć z responderem. Wartość domyślna to True, czyli zaakceptowanie certyfikatu klienta, co odpowiada łagodnemu zachowaniu (soft-fail). Ustaw ją na False, aby zamiast tego odrzucać połączenie. Odrzucanie jest bardziej restrykcyjne, ale uzależnia każde nowe połączenie od dostępności respondera z poziomu serwera, więc awaria respondera staje się awarią dla wszystkich Twoich klientów.
Rozstrzyga, co się dzieje, gdy certyfikat klienta nie publikuje ani punktu dystrybucji CRL, ani respondera OCSP, więc jego stanu nie da się ustalić. Wartość domyślna to True, czyli zaakceptowanie go. Certyfikaty wystawione przez wewnętrzny urząd certyfikacji często nie zawierają żadnych informacji o unieważnieniu, dlatego ustaw tę właściwość na False dopiero wtedy, gdy masz pewność, że każdy certyfikat przekazywany klientowi je publikuje.
Żadna z właściwości Ignore nigdy nie akceptuje certyfikatu zwróconego jako potwierdzony jako unieważniony. Taki wynik jest zawsze odrzucany, a uzgadnianie kończy się niepowodzeniem.
Gdy weryfikacja łańcucha odrzuca klienta, przyczyną jest jedna z poniższych:
| ecCryptRevoked | Certyfikat klienta został unieważniony przez wystawcę. Zawsze odrzucany. |
| ecCryptRevocationOffline | Nie udało się połączyć z responderem. Odrzucany tylko wtedy, gdy IgnoreRevocationOffline ma wartość False. |
| ecCryptNoRevocationCheck | Certyfikat klienta nie publikuje żadnych informacji o unieważnieniu. Odrzucany tylko wtedy, gdy IgnoreNoRevocationCheck ma wartość False. |
Ustawienie SSLOptions.Preset na tlspSecureDefaults włącza sprawdzanie jako scrcChainExcludeRoot na serwerze, zgodnie z tym, co ten sam preset stosował już po stronie klienta, i zachowuje oba ustawienia łagodnego niepowodzenia, dzięki czemu klient, który wcześniej był dopuszczany, nadal jest dopuszczany. Zakres wybrany samodzielnie przed zastosowaniem presetu pozostaje nienaruszony.
oServer.SSLOptions.Preset := tlspSecureDefaults;