TsgcUDPCLient › 이벤트 › OnDTLSVerifyPeer
DTLS 핸드셰이크 중에 발생하므로 애플리케이션이 피어 인증서를 검사하고 수락하거나 거부할 수 있습니다.
property OnDTLSVerifyPeer: TsgcUDPDTLSVerifyPeerEvent;
// TsgcUDPDTLSVerifyPeerEvent = function(Sender: TObject; Certificate: TIdX509; AOk: Boolean; ADepth, AError: Integer): Boolean of object
| Name | Type | 설명 |
|---|---|---|
Sender | TObject | 이벤트를 발생시킨 컴포넌트. |
Certificate | TIdX509 | 현재 검증 중인 인증서. Subject, Issuer, SerialNumber, notBefore, notAfter 또는 FingerprintAsString을 읽을 수 있습니다. 이 객체는 DTLS 엔진이 소유하며 호출이 진행되는 동안에만 유효하므로 핸들러에서 해제해서는 안 됩니다. |
AOk | Boolean | OpenSSL이 이 인증서에 대해 이미 내린 판정입니다. 체인 검사와 VerifyDepth 검사를 모두 통과하면 True, 둘 중 하나라도 실패하면 False입니다. 이 판정을 그대로 따르려면 이 값을 반환하십시오. |
ADepth | Integer | 체인에서 Certificate의 위치입니다. 이벤트는 인증서마다 한 번씩 발생하며, 0은 피어 인증서 자체이고 값이 커질수록 루트 쪽으로 올라갑니다. |
AError | Integer | 이 인증서에 대한 OpenSSL 검증 오류 코드(X509_V_ERR_ 상수 중 하나)이며, 오류가 감지되지 않으면 0입니다. |
True를 반환하면 인증서를 수락하고 핸드셰이크를 계속 진행하며, False를 반환하면 인증서를 거부하고 핸드셰이크를 종료합니다. 결과를 결정하는 것은 바로 이 반환 값이므로, OpenSSL의 판정을 그대로 따르려면 AOk를 반환하고, 애플리케이션 자체 규칙에 따라 거부할 인증서에는 False를 반환하십시오. 무조건 True를 반환하면 체인 검사와 깊이 검사가 무시되는데, 이는 이번 적용 변경으로 라이브러리에서 제거된 바로 그 동작입니다. 핸들러를 지정하지 않으면 라이브러리가 AOk를 반환하므로, 올바른 체인 동작을 얻기 위해서가 아니라 자체 규칙을 추가하려는 경우에만 핸들러가 필요합니다. (Boolean)
—
DTLS가 True이고 DTLSOptions.VerifyCertificate가 활성화된 경우 핸드셰이크 동안 DTLS 엔진에 의해 발생합니다. OpenSSL이 수행하는 체인 검증에 더하여, 애플리케이션별 검증 규칙(예: 예상 Common Name 고정, 사용자 지정 인증서 저장소 확인, 인증서 지문 로깅)을 적용하려면 이 이벤트를 사용하십시오. 데이터그램이 수락되기 전에 DTLS reader 스레드에서 호출되므로 핸들러는 스레드 안전한 방식으로 구현해야 합니다.
이제 체인 검증이 실제로 적용됩니다. 이전에는 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;