Einzelnen Beitrag anzeigen

Benutzerbild von Dalai
Dalai

Registriert seit: 9. Apr 2006
1.680 Beiträge
 
Delphi 5 Professional
 
#4

AW: Digitale Signaturen (Authenticode) von Dateien auslesen

  Alt 16. Feb 2023, 14: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
  Mit Zitat antworten Zitat