Прочитать и проверить сертификат из исполняемого файла

Я хочу проверить сертификаты подписанных исполняемых образов (под проверкой я имею в виду, если подпись исходит от MS/Adobe/Oracle и т. Д.). Windows предоставляет API для этой задачи? Как мне это сделать, понятия не имею. Любая помощь будет оценена. Я использую Windows и C++. Я хочу проверить собственные исполняемые образы, а не сборки.NET или файлы jar Java.

ОБНОВИТЬ


Хорошо, я постараюсь описать, что я хочу в ближайшее время.

1) Подтвердить сертификат PE. Подпись действительна или нет. Это должно работать, когда подпись встроена в PE и когда подпись находится в каталоге безопасности. (Я нашел это на форуме sysinternals и работает нормально, поэтому он мне больше не нужен).

2) Сообщите, кто подписал / издал файл. Я знаю, что этого можно достичь с помощью CryptQueryObject (я нашел рабочий пример, хотя он не работает с каталогами безопасности), но не знаю, как использовать его с файлами каталога безопасности.

3 ответа

Решение

Есть много API и подходов, как вы можете получить и проверить подпись исполняемого файла и как вы можете получить другую дополнительную информацию, которая вам нужна. Проблема в том, какой уровень вы выбираете (высокий уровень, как WinVerifyTrust)

Самым простым первым API, который можно использовать для получения контекста криптографии из файла CAT или EXE, является функция CryptQueryObject. Пример кода из KB323809 может дать вам основную идею, как декодировать информацию, что вам нужно. Основное отличие при работе с файлами CAT заключается в том, что вам следует изменить некоторые параметры CryptQueryObject. Я рекомендую вам просто использовать CERT_QUERY_CONTENT_FLAG_ALL а также CERT_QUERY_FORMAT_FLAG_ALL а также CryptQueryObject сделаем все что нужно внутри:

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);

Значение dwContentType устанавливается CryptQueryObject получите базовую информацию о типе файла szFileName, pvContext будет PCCERT_CONTEXT для большинства случаев, которые вам нужны, но это также может быть PCCRL_CONTEXT или же PCCTL_CONTEXT если вы используете.ctl или.crl файл в качестве входных данных. Вы получите hStore заполнены все сертификаты из файла szFileName, Так что в отношении pvContext а также hStore Вы можете просмотреть файл, содержащийся с CryptoAPI. Если вы предпочитаете низкоуровневый массаж API, вы можете использовать hMsg который будет дополнительно установлен в случае некоторых dwContentType (по крайней мере, для CERT_QUERY_CONTENT_PKCS7_SIGNED, CERT_QUERY_CONTENT_PKCS7_UNSIGNED, CERT_QUERY_CONTENT_PKCS7_SIGNED_EMBED).

Чтобы проверить подпись файла, я бы порекомендовал вам использовать CertGetCertificateChain и CertVerifyCertificateChainPolicy, чтобы проверить не только то, что сертификат действителен в целом, но и то, что он (или все его родители) действителен для authenticode (szOID_PKIX_KP_CODE_SIGNING). CertGetCertificateChain может использоваться для различных сценариев отзыва. Вы должны сделать два отдельных звонка с CERT_CHAIN_POLICY_AUTHENTICODE а также CERT_CHAIN_POLICY_AUTHENTICODE_TS чтобы убедиться, что политика цепочки Authenticode и политика цепочки меток времени Authenticode являются действительными.

ОБНОВЛЕНО: я перечитал ваш текущий вопрос (обновленная часть). Ваша текущая проблема заключается в том, как получить подписавшего / издателя файла. Поэтому я отвечаю только на вопрос.

Если вы используете код от sysinternal для проверки подписи, вам нужно просто найти строку

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

Утверждение Sill установить поля InfoStruct в случае, если этот файл является системным файлом Windows, подпись которого проверяется относительно некоторого файла.cat. Поле InfoStruct.wszCatalogFile даст вам имя файла.cat.

Например, на моем Windows 7, если я пытаюсь проверить цифровую подпись C:\Windows\explorer.exe файл.cat, где можно найти его хэш C:\Windows\system32\CatRoot\{F750E6C3-38EE-11D1-85E5-00C04FC295EE}\Package_1_for_KB2515325~31bf3856ad364e35~amd64~~6.1.1.0.cat,

Если вы используете код из KB323809 с описанными выше параметрами CryptQueryObject вы расшифруете SPC_SP_OPUS_INFO_OBJID ("1.3.6.1.4.1.311.2.1.12") атрибута C:\Windows\system32\CatRoot\{F750E6C3-38EE-11D1-85E5-00C04FC295EE}\Package_1_for_KB2515325~31bf3856ad364e35~amd64~~6.1.1.0.cat (см. функцию GetProgAndPublisherInfo) и ты узнаешь

pwszProgramName: "Windows Express Security Catalogs"
pPublisherInfo: NULL
pMoreInfo->dwLinkChoice: SPC_URL_LINK_CHOICE
pMoreInfo->pwszUrl "http://www.microsoft.com"

Таким образом, никакая специальная информация об издателе не включена в файл. Если вы осмотрите подписавшего каталог, вы обнаружите, что:

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

Таким образом, вы должны использовать только подписавшего файла.cat, потому что нет другого подписавшего explorer.exe,

Функция WinVerifyTrust выполняет действие по проверке доверия для указанного объекта. Функция передает запрос поставщику доверия, который поддерживает идентификатор действия, если таковой существует.

Для проверки сертификата используйте функции CertGetCertificateChain и CertVerifyCertificateChainPolicy.

@ Давита Я внимательно прочитал вышеупомянутую проблему и попытался ее решить.

Мое предложение состоит в том, чтобы попробовать CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED вместо CERT_QUERY_CONTENT_FLAG_ALL в третьем параметре CryptQueryObject()

Другие вопросы по тегам