Подтвердить что ты не робот

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

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

UPDATE


Хорошо, я попытаюсь кратко описать, что хочу.

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

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

4b9b3361

Ответ 1

Существует много 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. Если вы предпочитаете  низкоуровневый интерфейс для массажа, вы можете использовать hMsg, который будет дополнительно установлен в случае некоторого dwContentType (по крайней мере для CERT_QUERY_CONTENT_PKCS7_SIGNED, CERT_QUERY_CONTENT_PKCS7_UNSIGNED, CERT_QUERY_CONTENT_PKCS7_SIGNED_EMBED).

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

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

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

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

Запоминание инструкции устанавливает поля InfoStruct, если этот файл является файлом системных окон, подпись которого проверена в отношении некоторого файла .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.

Ответ 2

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

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

Ответ 3

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

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