Hallo,
(wie) kann ich bei einem mit
Indy+OpenSSL geschriebenen TLS-Client an das Root-Zertifikat kommen, ohne eine Liste mit erlaubten Root-Zertifikaten bereitzustellen?
Konkreter: Bei mit einem TIdSMTP (=
SMTP-Client) möchte ich die komplette Zertifikatskette vom Server auslesen und zur Anzeige bringen.
Dazu habe ich im OnVerifyPeer Funktionalität, die mir die benötigten Werte ausgibt bzw. in eine Struktur schreibt. Das funktioniert grundsätzlich auch, aber für die root-CA wird das Event nicht ausgelöst. Liegt das an
Indy bzw. OpenSSL oder habe ich nur etwas was falsch konfiguriert?
Beispiel: "mail.example.com" ist signiert von "StartCom Class 2 Primary Intermediate Server CA" ist signiert von "StartCom Certification Authority".
Nun bekomme ich ein Event für das Zertifikat "StartCom Class 2 Primary Intermediate Server CA" mit ADepth = 1 und ein Event für "mail.example.com" mit ADepth=0. Ich bekomme aber kein Event für "StartCom Certification Authority". Die VerifyDepth ist auf 9 gestellt (was wohl auch der default ist) und ich habe keine Datei mit Rootzertifikaten angegeben.
Certificate Info:
Subject: mail.example.com
Issuer: StartCom Class 2 Primary Intermediate Server CA
Certificate Info:
Subject: StartCom Class 2 Primary Intermediate Server CA
Issuer: StartCom Certification Authority
Delphi-Quellcode:
procedure TMyClass.InitTls;
var
SslIoHandler: TIdSSLIOHandlerSocketOpenSSL;
begin
SslIoHandler := TIdSSLIOHandlerSocketOpenSSL.Create(FSMTPClient);
SslIoHandler.SSLOptions.Method := sslvTLSv1;
SslIoHandler.SSLOptions.VerifyMode := [sslvrfPeer];
SslIoHandler.SSLOptions.VerifyDepth := 9; // 9 is default: https://linux.die.net/man/3/ssl_ctx_set_verify_depth
// SslIoHandler.SSLOptions.RootCertFile ; // don't have one
SslIoHandler.OnVerifyPeer := TlsVerifyPeer; // Necessary for certificate verification
FSMTPClient.IOHandler := SslIoHandler; // ownership of SslIoHandler is moved
FSMTPClient.UseTLS := utUseRequireTLS;
end;
function TMyClass.TlsVerifyPeer(Certificate: TIdX509;
AOk: Boolean; ADepth, AError: Integer): Boolean;
begin
// store/output certificate info...
// for now we do not want to continue - present certificates to the user first
result := ADepth > 0; // false for leaf cert; true for (intermediate) CAs
end;
Zweiter Test: Gegen eine Exchange-Server Testinstallation mit "mail.testexchange.mydomain" signiert von "meineWindowsCA" bekomme ich nur das Peer-Zertifikat präsentiert, dafür gleich zwei mal (beide Male mit ADepth = 0; das erste mal mit AError = X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY(20), das zweite mal mit AError = X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE(21)).
schon mal Danke für die Hilfe!