c ++ - Læs og valider certifikat fra eksekverbar

Indlæg af Hanne Mølgaard Plasc

Problem



Jeg vil validere certifikater for underskrevne eksekverbare billeder (ved validering betyder det, at signaturen kommer fra MS/Adobe/Oracle osv.). Indeholder vinduer api til denne opgave? Hvordan skal jeg gøre det, ingen idé. Enhver hjælp ville blive værdsat.
Jeg bruger Windows og C ++. Jeg vil validere native eksekverbare billeder, ikke .NET-enheder eller Java-jarfiler.


UPDATE





Ok, jeg vil forsøge at beskrive hvad jeg vil have kort tid.


1) Godkend PE certifikat. Er signaturen gyldig eller ej. Det skal fungere, når signaturen er indlejret i PE, og når signaturen er i sikkerhedskatalog. ( Jeg fandt dette på sysinternals forum og fungerer fint, så jeg behøver ikke denne her længere ).


2) Fortæl, hvem der er underskriveren/udgiveren af ​​filen. Jeg ved, at det kan opnås gennem CryptQueryObject (jeg fandt et fungerende eksempel, selvom det ikke fungerer med sikkerhedskataloger), men ved ikke hvordan man bruger det med sikkerhedskatalogfiler.

Bedste reference


Der er mange API'er og fremgangsmåder, hvordan du kan få og verificere signaturen af ​​den eksekverbare, og hvordan du kan få andre yderligere oplysninger, som du har brug for. Problemet er hvilket niveau du vælger (højt niveau som WinVerifyTrust)


Den nemmeste første API, der kan bruges til at få kryptografi sammenhæng fra CAT eller EXE filen er CryptQueryObject funktion. Kodeksemplet fra KB323809 kan få dig den vigtigste ide om, hvordan du afkoder information, hvad du har brug for. Hovedforskellen, hvis du arbejder med CAT-filer, er, at du bør ændre nogle parametre i CryptQueryObject. Jeg anbefaler dig bare for at bruge CERT\_QUERY\_CONTENT\_FLAG\_ALL og CERT\_QUERY\_FORMAT\_FLAG\_ALL og CryptQueryObject vil gøre alt hvad du har brug for internt: [39] [40] [41]


BOOL bIsSuccess;
DWORD dwEncoding, dwContentType, dwFormatType;
HCERTSTORE hStore = NULL;
HCRYPTMSG hMsg = NULL;
PVOID pvContext = NULL;

// fill szFileName
...

// Get message handle and store handle from the signed file.
bIsSuccess = CryptQueryObject (CERT\_QUERY\_OBJECT\_FILE,
                               szFileName,
                               CERT\_QUERY\_CONTENT\_FLAG\_ALL,
                               CERT\_QUERY\_FORMAT\_FLAG\_ALL,
                               0,
                               &dwEncoding,
                               &dwContentType,
                               &dwFormatType,
                               &hStore,
                               &hMsg,
                               &pvContext);


Værdien dwContentType indstillet af CryptQueryObject giver dig basisoplysninger om typen af ​​filen szFileName. pvContext vil være PCCERT\_CONTEXT for de fleste tilfælde, du har brug for, men det kan også være PCCRL\_CONTEXT eller PCCTL\_CONTEXT, hvis du bruger .ctl eller .crl-filen som input. Du vil modtage hStore fyldt med alle certifikater fra filen szFileName. Så med respekt for pvContext og hStore kan du undersøge filen indeholder med CryptoAPI. Hvis du foretrækker det
 API med lavt niveau massager kan du bruge hMsg, som yderligere vil blive fastsat i tilfælde af nogle dwContentType (i det mindste for til CERT\_QUERY\_CONTENT\_PKCS7\_SIGNED, CERT\_QUERY\_CONTENT\_PKCS7\_UNSIGNED, CERT\_QUERY\_CONTENT\_PKCS7\_SIGNED\_EMBED) .


For at bekræfte filens underskrift anbefaler jeg dig at bruge CertGetCertificateChain og CertVerifyCertificateChainPolicy til ikke kun at kontrollere, at certifikatet er generelt gyldigt, men at det (eller alle dets forældre) er gyldigt for authenticode (szOID\_PKIX\_KP\_CODE\_SIGNING). CertGetCertificateChain kan bruges til forskellige tilbagekaldelsesscenarier. Du skal foretage to separate opkald med CERT\_CHAIN\_POLICY\_AUTHENTICODE og CERT\_CHAIN\_POLICY\_AUTHENTICODE\_TS for at bekræfte, at både Authenticode-kædepolitik og Authenticode Time Stamp-kædepolitik er gyldige. [42] [43] [44]


OPDATERET : Jeg læser dit aktuelle spørgsmål (den opdaterede del). Dit nuværende problem er hvordan man får filens underskriver/udgiver . Så jeg svarer kun på spørgsmålet.


Hvis du bruger koden fra sysinternal til signaturverifikationen, skal du bare søge efter linjen [45]


if ( !CryptCATCatalogInfoFromContext(CatalogContext, &InfoStruct, 0) )


Erklæringen sill angiver felterne i InfoStruct i tilfælde af at den fil er system windows fil som underskrift er verificeret med hensyn til nogle .cat fil. Feltet InfoStruct.wszCatalogFile får navnet på .cat-filen. [46]


For eksempel på min Windows 7, hvis jeg forsøger at bekræfte den digitale signatur af C:Windowsexplorer.exe filen, kan den .cat, hvor dens hash findes, C:Windowssystem32CatRoot{F750E6C3-38EE-11D1-85E5-00C04FC295EE}Package\_1\_for\_KB2515325~31bf3856ad364e35~amd64~~6.1.1.0.cat.


Hvis du vil bruge kode fra KB323809 med de ovenfor beskrevne parametre for CryptQueryObject, vil du dekode SPC\_SP\_OPUS\_INFO\_OBJID ('1.3.6.1.4.1.311.2.1.12') attributten til C:Windowssystem32CatRoot{F750E6C3-38EE-11D1-85E5-00C04FC295EE}Package\_1\_for\_KB2515325~31bf3856ad364e35~amd64~~6.1.1.0.cat (se funktion GetProgAndPublisherInfo) og du vil vide [47]


pwszProgramName: "Windows Express Security Catalogs"
pPublisherInfo: NULL
pMoreInfo->dwLinkChoice: SPC\_URL\_LINK\_CHOICE
pMoreInfo->pwszUrl "http://www.microsoft.com"


Så ingen særlige udgiveroplysninger er inkluderet i filen. Hvis du undersøger underskriveren af ​​kataloget, vil du finde ud af at:


The signer of the .cat file: "Microsoft Windows"
The signer signed it with the certificate:
    Serial Number: 0x6115230F00000000000A
    Issuer Name: Microsoft Windows Verification PCA
    Full Issuer Name:
        CN = Microsoft Windows Verification PCA
        O = Microsoft Corporation
        L = Redmond
        S = Washington
        C = US
    Subject Name: Microsoft Windows
    Full Subject Name:
        CN = Microsoft Windows
        OU = MOPR
        O = Microsoft Corporation
        L = Redmond
        S = Washington
        C = US
The Date of TimeStamp : 28.02.2011 21:16:36
TimeStamp Certificate: 
    Serial Number: 0x6103DCF600000000000C
    Issuer Name: Microsoft Time-Stamp PCA
    Subject Name: Microsoft Time-Stamp Service


Så du skal kun bruge underskriveren af ​​.cat-filen, fordi der ikke er nogen anden underskriver af explorer.exe.

Andre referencer 1


WinVerifyTrust-funktionen udfører en tillidskontrolhandling på en bestemt objekt. Funktionen sender forespørgslen til en trust-udbyder, der understøtter handlingsidentifikatoren, hvis en findes. [48]


Ved certificeringskontrol skal du bruge CertGetCertificateChain og CertVerifyCertificateChainPolicy-funktionerne.

Andre referencer 2


@Davita
 Jeg har læst ovenstående problem grundigt og forsøgt at løse det.


Mit forslag er at prøve CERT\_QUERY\_CONTENT\_FLAG\_PKCS7\_SIGNED i stedet for CERT\_QUERY\_CONTENT\_FLAG\_ALL i den tredje parameter af CryptQueryObject()