Registriert seit: 9. Apr 2006
1.682 Beiträge
Delphi 5 Professional
|
AW: Digitale Signaturen (Authenticode) von Dateien auslesen
16. Feb 2023, 15:52
Danke, nach längerm Rumprobieren konnte ich mithilfe dieser Beschreibung meinen Code funktionierend bekommen. Es können nun alle Signaturen gelesen werden.
Leider ist das Ergebnis weiterhin inkonsistent, d.h. ich erhalte nicht immer dasselbe Ergebnis nach Neuaufbau der TSignatureContainerList (ist eine TObjectList von TSignatureContainer). Beeinflusst wird das Ergebnis auch durch Aufrufe von OutputDebugString
- vor allem solche, die FFileName ausgeben. Aber auch nur mit dem Standard-Speichermanager von Delphi 5. Nutze ich stattdessen FastMM, ist das Ergebnis konsistent und die Calls von OutputDebugString
spielen keine Rolle.
Durch die Debug-Ausgaben konnte ich ermitteln, dass das erste CompareMem
fehlschlägt. Daher habe ich den Verdacht, dass die Zeigerschieberei irgendetwas kaputtmacht. Zugriffsverletzungen habe ich aber keine, soweit ich sehen kann.
Nachfolgend die komplette Funktion:
Delphi-Quellcode:
procedure TSignatureContainer.FindAllEmbeddedSignatures(const ASignerInfo: PCMSG_SIGNER_INFO; const ACertStore: HCERTSTORE; const AMaxSize: DWORD);
function BigEndianToLittleEndian(const A: Word): Word;
begin
Result:= Word(((A AND $FF00) shr 8) OR ((A AND $00FF) shl 8));
end;
function _8ByteAlign(const offset, base: NativeUInt): NativeUInt;
begin
Result:= ((offset + base + 7) AND $FFFFFFF8) - (base AND $FFFFFFF8);
end;
const
SG_ProtoCoded: array[0..1] of Byte = ($30, $82);
SG_SignedData: array[0..8] of Byte = ($2a, $86, $48, $86, $f7, $0d, $01, $07, $02);
var i: integer;
{ Nested signatures }
LUnauthAttr: PCRYPT_ATTRIBUTE;
LNestedMsg: HCRYPTMSG;
LNestedSignerInfo: PCMSG_SIGNER_INFO;
LNestedSignerInfoSize: DWORD;
LNestedMsgCertStore: HCERTSTORE;
LpbCurrData, LpbNextData: PByte;
LcbCurrData: DWORD;
Lret: BOOL;
LMaxAddress: PByte;
begin
LUnauthAttr:= ASignerInfo.UnauthAttrs.rgAttr;
AddSignatureFromSignerInfo(ASignerInfo, ACertStore);
LMaxAddress:= PByte(ASignerInfo);
Inc(LMaxAddress, AMaxSize);
// FFileName: WideString;
OutputDebugString(PChar(String(FFileName)));
for i:= 1 to ASignerInfo.UnauthAttrs.cAttr do begin
if AnsiString(LUnauthAttr.pszObjId) = szOID_NESTED_SIGNATURE then begin
FNestedSignature:= True;
LpbCurrData:= LUnauthAttr.rgValue.pbData;
while (NativeUInt(LpbCurrData) > NativeUInt(ASignerInfo)) AND
(NativeUInt(LpbCurrData) < NativeUInt(LMaxAddress)) do begin
// OutputDebugString('Loop');
if NOT CompareMem(Pointer(NativeUInt(LpbCurrData) + 0), @SG_ProtoCoded, SizeOf(SG_ProtoCoded)) then
Break;
// OutputDebugString('Loop2');
if NOT CompareMem(Pointer(NativeUInt(LpbCurrData) + 6), @SG_SignedData, SizeOf(SG_SignedData)) then
Break;
LNestedMsg:= CryptMsgOpenToDecode(X509_OR_PKCS7_ENCODING, 0, 0, 0, nil, nil);
if NOT Assigned(LNestedMsg) then
Exit;
try
// LcbCurrData:= Swap(PWord(NativeUInt(LpbCurrData)+2)^) + 4;
LcbCurrData:= BigEndianToLittleEndian(PWord(NativeUInt(LpbCurrData)+2)^) + 4;
LpbNextData:= LpbCurrData;
Inc(LpbNextData, _8ByteAlign(LcbCurrData, ULONG_PTR(LpbCurrData)));
Lret:= CryptMsgUpdate(LNestedMsg, LpbCurrData, LcbCurrData, True);
LpbCurrData:= LpbNextData;
if NOT Lret then
Continue;
if NOT CryptMsgGetParam(LNestedMsg, CMSG_SIGNER_INFO_PARAM, 0, nil, LNestedSignerInfoSize) then
Exit;
GetMem(LNestedSignerInfo, LNestedSignerInfoSize);
try
if NOT CryptMsgGetParam(LNestedMsg, CMSG_SIGNER_INFO_PARAM, 0, LNestedSignerInfo, LNestedSignerInfoSize) then
Exit;
LNestedMsgCertStore:= CertOpenStore(CERT_STORE_PROV_MSG, X509_OR_PKCS7_ENCODING, 0, 0, LNestedMsg);
try
AddSignatureFromSignerInfo(LNestedSignerInfo, LNestedMsgCertStore);
finally
CertCloseStore(LNestedMsgCertStore, 0);
end;
finally
FreeMem(LNestedSignerInfo);
end;
finally
CryptMsgClose(LNestedMsg);
end;
end;
Break;
end;
Inc(LUnauthAttr);
end;
end;
Grüße
Dalai
|