Post by Ole JansenFalls Du Dich low level mit dem Thema auseinandersetzen
<https://www.disi.unige.it/person/FerranteM/delphiopenssl/libeay32.pas>
<https://www.disi.unige.it/person/FerranteM/delphiopenssl/OpenSSLUtils.pas>
Evtl. kannst Du analog dazu einen p12 reader ableiten?
<https://stackoverflow.com/questions/6371775/how-to-load-a-pkcs12-file-in-openssl-programmatically>
So, ich hab's jetzt endlich ohne externe Programme und DLLs geschafft.
Ich bin vor allem daran gescheitert, dass ich beim "Übersetzen" der
Windows API-Funktion PFXImportCertStore das stdcall; vergessen habe. Und
dann noch den CRYPT_DATA_BLOB falsch befüllt.
Der jetzt funktionierende Code schaut eigentlich recht einfach aus
(GetDataBlob ruft CryptBinaryToStringA auf, das in wcrypt2.pas drinnen
ist, das laut Disclaimer auf http://delphi-jedi.org/ gefunden werden kann)
function PFXImportCertStore(pPFX : PCRYPT_DATA_BLOB;
szPassword : LPCWSTR;
dwFlags : DWORD): HCERTSTORE; stdcall;
function CryptBinaryToStringA(pbBinary: pointer; cbBinary: dword;
dwFlags: dword;
pszString: PAnsiChar; var pcchString: dword): boolean; stdcall;
{$IFDEF UNICODE}
function CryptBinaryToString; external crypt32 name 'CryptBinaryToStringW';
{$ELSE}
function CryptBinaryToString; external crypt32 name 'CryptBinaryToStringA';
{$ENDIF}
function CryptBinaryToStringA; external crypt32 name 'CryptBinaryToStringA';
function CryptBinaryToStringW; external crypt32 name 'CryptBinaryToStringW';
function PFXImportCertStore; external 'crypt32.dll' name
'PFXImportCertStore';
function GetDataBlobText(AData: DATA_BLOB; Art: DWORD): AnsiString;
var size: Cardinal;
begin
CryptBinaryToStringA(AData.pbData, AData.cbData, Art, nil, size);
SetLength(Result, size-1);
CryptBinaryToStringA(AData.pbData, AData.cbData, Art,
PAnsiChar(Result), size);
end;
function PKCS12Seriennummer(ADateiname, APassphrase: String): String;
var store: HCERTSTORE;
ms: TMemoryStream;
cryptBlob: CRYPT_DATA_BLOB;
context: PCCERT_CONTEXT;
ci: PCERT_INFO;
SerialNo: String;
i: Integer;
gle: DWORD;
begin
Result := '';
if not FileExists(ADateiname) then EXIT;
ms := TMemoryStream.Create;
try
ms.LoadFromFile(ADateiname);
cryptBlob.cbData := ms.Size;
cryptBlob.pbData := ms.Memory;
store := PFXImportCertStore(@cryptblob, PChar(APassphrase),
CRYPT_USER_KEYSET or PKCS12_NO_PERSIST_KEY);
try
if store=nil then
begin
gle := GetLastError;
ShowMyMessage(IntToHex(gle, 8), mtError);
EXIT;
end;
context := CertEnumCertificatesInStore(store, nil);
while context<>nil do
begin
ci := context.pCertInfo;
SerialNo := GetDataBlobText(ci.SerialNumber, CRYPT_STRING_HEX);
for i := Length(SerialNo) downto 1 do // Byteorder passt auch
nicht zusammen.
if not (SerialNo[i] in ['0'..'9','A'..'F']) then
Delete(SerialNo, i,1);
ShowMyMessage(GetDataBlobText(ci.Issuer,CRYPT_STRING_HEXASCII)+#13#10+serialno{+#13#10+GetDataBlobText(context,
CRYPT_STRING_BASE64)});
context := CertEnumCertificatesInStore(store, context);
end;
finally
CertCloseStore(store,0);
end;
finally
ms.Free;
end;
end;