AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Win32/Win64 API (native code) Delphi Digitale Signaturen (Authenticode) von Dateien auslesen
Thema durchsuchen
Ansicht
Themen-Optionen

Digitale Signaturen (Authenticode) von Dateien auslesen

Ein Thema von Dalai · begonnen am 12. Feb 2023 · letzter Beitrag vom 20. Feb 2023
 
Benutzerbild von Dalai
Dalai

Registriert seit: 9. Apr 2006
1.684 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
 


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 12:17 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz