Einzelnen Beitrag anzeigen

christophspaeth

Registriert seit: 7. Mär 2008
73 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#1

Indy/OpenSSL: Komplette Zertifikatskette im Client ermitteln

  Alt 12. Okt 2016, 17:59
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!
Christoph Späth
  Mit Zitat antworten Zitat