OpenSSL - MemoryLeak bei Verwendung eines X509-Zertifikats
Ich muss mich aktuell mit digitaler Signierung herumschlagen. Dazu verwende ich OpenSSL (libeay32.dll). Die verwendeten Header-Übersetzungen habe ich von hier. Jetzt ist mir ein Speicherleck aufgefallen, das sich hartnäckig hält.
Delphi-Quellcode:
Laut Doku dekrementiert X509_free den internen Referenzzähler auf die X509-Struktur und gibt diese bei Erreichen von 0 frei. Leider scheint dem nicht so zu sein, also mache ich wohl irgendetwas falsch. Kommentiere ich den Teil ab d2i_X509 bis X509_free aus, ist das Speicherleck weg, es muss also damit zu tun haben. Hat jemand einen Tipp für mich, die Speicherverwaltung von OpenSSL ist für mich doch recht gewöhnungsbedürftig?
procedure TMyClass.Verfify;
var Certificate: TBytes; CertStr: PPAnsiChar; Cert: PX509; begin //... CertStr := @PAnsiChar(Certificate); Cert := d2i_X509(nil, CertStr, TC_LONG(Length(Certificate))); if Assigned(Cert) then try //Auskommentierter Code finally X509_free(Cert); end; end; |
AW: OpenSSL - MemoryLeak bei Verwendung eines X509-Zertifikats
Ein dezentes *Push* :oops:
|
AW: OpenSSL - MemoryLeak bei Verwendung eines X509-Zertifikats
Ich konnte das Problem jetzt mildern, indem ich die PX509-Variable zu einem privaten Feld gemacht habe und dieses nur befülle, wenn noch nicht zugewiesen. Das Speicherleck besteht zwar weiterhin, aber es entspricht halt nur einmal der Größe der zugrundeliegenden Struktur und nicht einmal je Aufruf. Trotzdem hätte ich das gern ganz weg, bin also weiterhin dankbar für jeden Tipp.
|
AW: OpenSSL - MemoryLeak bei Verwendung eines X509-Zertifikats
Zitat:
Das MM der DLL ist nicht der MM von Delphi. D.h. meldet der Delphi einen Leak, so hat den Speicher Delphi auch reserviert. |
AW: OpenSSL - MemoryLeak bei Verwendung eines X509-Zertifikats
Zum Einen wird es mir bei ReportMemoryLeaksOnShutdown gemeldet, zum Anderen kann ich im Taskmanager sehen, wie der Speicherverbrauch ansteigt.
|
AW: OpenSSL - MemoryLeak bei Verwendung eines X509-Zertifikats
Zitat:
Der Aufrufstack des FastMM zu den reservierenden Aufrufen, gibt dir Hinweise dazu. Zitat:
|
AW: OpenSSL - MemoryLeak bei Verwendung eines X509-Zertifikats
Ich muss mal diesen gut abgehangenen Thread ausgraben, auf den ich durch Google gestoßen bin. Ich habe gerade exakt das gleiche Problem, dass jeder Aufruf von d2i_x509 zu einem kleinen Speicherleck führt. Ziel bei mir ist es letztlich, ein in einem JSON Web Key angegebenes Zertifikat auszulesen und dann später im PEM-Format weiterzunutzen.
Kleiner Code-Auszug aus einem Testprogramm:
Delphi-Quellcode:
Wie ihr seht, passiert hier noch etwas mehr (nämlich die Umwandlung in einen String im PEM-Format - falls jemand weiß, ob das einfacher geht, gerne her damit). Ich bin erstmal froh, dass am Ende das erhoffte Ergebnis rauskommt. :-)
procedure TForm2.ButtonDecodeClick(Sender: TObject);
var byteArray: TBytes; pr: PX509; pubKey: string; bio: PBIO; begin byteArray:=TNetEncoding.Base64.DecodeStringToBytes(MemoKey.Lines.Text); MemoStatus.Lines.Add('base decoded. Length: '+length(byteArray).ToString); if IdSSLOpenSSLHeaders.Load then begin MemoStatus.Lines.Add('openssl loaded.'); pr:=d2i_X509(nil,@@byteArray[0],length(byteArray)); if pr<>nil then begin MemoStatus.Lines.Add('X509 read.'); MemoStatus.Lines.Add('Name: '+X509_NAME_oneline(X509_get_subject_name(pr),nil,0)); MemoStatus.Lines.Add('Public Key Length: '+pr.cert_info.key.public_key.length.ToString); MemoStatus.Lines.Add('Issuer name: '+X509_NAME_oneline(X509_get_issuer_name(pr),nil,0)); bio:=BIO_new(BIO_s_mem); PEM_write_bio_X509(bio,pr); BIO_read(bio,byteArray,BIo.num_write); pubKey:=string(PAnsiChar(@byteArray[0])); MemoPEM.Lines.Text:=pubKey; SetLength(bytePubKey,0); BIO_free(bio); X509_free(pr); end else MemoStatus.Lines.Add('Failed read X509.'); SetLength(byteArray,0); end; end; Aber ich habe nun auch immer das Speicherleck. Ich kann den ganzen Code reduzieren zu
Delphi-Quellcode:
...und bekomme immer noch ein Speicherleck angezeigt.
procedure TForm2.ButtonDecodeClick(Sender: TObject);
var byteArray, p: TBytes; pr: PX509; bytePubKey: TBytes; pubKey: string; bio: PBIO; begin byteArray:=TNetEncoding.Base64.DecodeStringToBytes(MemoKey.Lines.Text); MemoStatus.Lines.Add('base decoded. Length: '+length(byteArray).ToString); if IdSSLOpenSSLHeaders.Load then begin MemoStatus.Lines.Add('openssl loaded.'); pr:=d2i_X509(nil,@@byteArray[0],length(byteArray)); if pr<>nil then X509_free(pr); else MemoStatus.Lines.Add('Failed read X509.'); SetLength(byteArray,0); end; end; Irgendwer vielleicht mittlerweile eine Idee? @DeddyH, hast du das damals gelöst bekommen oder nimmst du das Leck seitdem resigniert in Kauf? |
AW: OpenSSL - MemoryLeak bei Verwendung eines X509-Zertifikats
Hallo,
dein byteArray wird erzeugt, aber nur beim erfolgreichen Load per SetLength freigegeben. |
AW: OpenSSL - MemoryLeak bei Verwendung eines X509-Zertifikats
Zitat:
Leider ist das noch nicht die eigentliche Ursache. Hm. Die Doku von OpenSSL gibt ja an, dass der Pointer auf das Array irgendwie verbogen wird und nachher hinter die übergebenen Byts zeigt. Irgendwie wird es wohl damit zusammenhängen. Man müsste sich also die ursprüngliche Adresse merken und sichergehen, dass man das richtige freigibt. |
AW: OpenSSL - MemoryLeak bei Verwendung eines X509-Zertifikats
Zitat:
Zitat:
Delphi-Quellcode:
Variable in deiner Testfunktion drin. Nutze sie doch!
p: TBytes
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 04:35 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz