Проверить подпись файла как Process Explorer
От: x64 Россия  
Дата: 19.10.08 15:03
Оценка:
Привет.
Нужен быстрый способ проверки цифровой подписи файла на Win32/64. Условия следующие:

1. Высокая скорость работы.
2. Проверка подписи как в самом файле, так и в отдельном .cat-файле.
3. Крайне желательно чтобы не приходилось ходить в инет для проверки.

Есть варианты вот такие: здесь и здесь
Автор: Unmanaged
Дата: 16.11.07
. Недостатки первого способа описаны по второй ссылке внизу, а второй способ настолько тормозной, что ну просто слов нет, и к тому же в инет зачем-то лезет.

Вот в Process Explorer'е и в Autoruns'е есть кнопка Verify, она как раз и делает то, что мне нужно, удовлетворяет всем 3 пунктам. Вопрос — кто-нибудь знает, как они это делают?
Re: Проверить подпись файла как Process Explorer
От: Аноним  
Дата: 19.10.08 15:07
Оценка:
Process Explorer использует именно WinVerifyTrust
Re[2]: Проверить подпись файла как Process Explorer
От: x64 Россия  
Дата: 19.10.08 15:12
Оценка:
А>Process Explorer использует именно WinVerifyTrust

Ну я в общем с этим не спорю, но вопрос — как именно? Хотелось бы подробностей. Может завалялся у кого исходник какой-нибудь старой Process Explorer или Autoruns? Киньте на мыло, плиз.
Проверить подпись файла как Process Explorer
От: Аноним  
Дата: 19.10.08 15:20
Оценка: 18 (2)
#Имя: FAQ.winapi.WinVerifyTrust
>Нужен быстрый способ проверки цифровой подписи файла на Win32/64.

>Вот в Process Explorer'е и в Autoruns'е есть кнопка Verify, она как раз и делает то, что мне нужно, удовлетворяет всем 3 пунктам. Вопрос — кто-нибудь знает, как они это делают?


    bool CheckByCat(const wchar_t *pwFileName)
    {
        HANDLE hCat;
        if (!CryptCATAdminAcquireContext(&hCat, NULL, 0))
            return false;
        
        bool out = false;
        
        
        HANDLE f = CreateFile(
            pwFileName, GENERIC_READ, 
            FILE_SHARE_READ | FILE_SHARE_WRITE, 
            NULL, OPEN_EXISTING, 
            FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, 
            NULL);

    
        if (f != INVALID_HANDLE_VALUE)
        {
            BYTE hash[1024];
            DWORD cb = sizeof(hash);
            if (CryptCATAdminCalcHashFromFileHandle(f, &cb, hash, 0))
            {
                if(CryptCATAdminEnumCatalogFromHash(hCat, hash, cb, 0, 0))
                    out = true;
            }    
        }
        
        CryptCATAdminReleaseContext(hCat, 0);
        ::CloseHandle(f);
        
        return out;
    }    

    bool CheckByWinVerifyTrust(const wchar_t *pwFileName)
    {
        WINTRUST_FILE_INFO wfi={sizeof(WINTRUST_FILE_INFO), 0};
        wfi.pcwszFilePath = pwFileName;
        wfi.hFile = NULL;

        WINTRUST_DATA wtd={sizeof(WINTRUST_DATA),0};
        wtd.dwUIChoice = WTD_UI_NONE;
        wtd.fdwRevocationChecks = WTD_REVOKE_NONE;
        wtd.dwUnionChoice = WTD_CHOICE_FILE;
        wtd.pFile = &wfi;

        GUID g = WINTRUST_ACTION_GENERIC_VERIFY_V2;
        LONG r = WinVerifyTrust(NULL, &g, &wtd);
        return (r==ERROR_SUCCESS);
    }

оно?
winverifytrust
Re[4]: Проверить подпись файла как Process Explorer
От: x64 Россия  
Дата: 19.10.08 15:35
Оценка:
Да, спасибо, оно самое. Вдогонку, не знаешь по случаю как из этой подписи извлечь имя подписавшего? Т.е. например строку типа "Microsoft Windows Component Publisher", "Mozilla Corporation" или "ACD Systems International Inc".
Как из этой подписи извлечь имя подписавшего?
От: xmen  
Дата: 19.10.08 22:23
Оценка: 18 (3)
#Имя: FAQ.winapi. WinVerifyTrust.name
Здравствуйте, x64, Вы писали:

x64>Вдогонку, не знаешь по случаю как из этой подписи извлечь имя подписавшего? Т.е. например строку типа "Microsoft Windows Component Publisher", "Mozilla Corporation" или "ACD Systems International Inc".


Wintrust.CryptCATAdminAcquireContext
kernel32.CreateFileA
Wintrust.CryptCATAdminCalcHashFromFileHandle
kernel32.CloseHandle
Wintrust.CryptCATAdminEnumCatalogFromHash
Wintrust.CryptCATAdminReleaseContext
Wintrust.WinVerifyTrust

WINTRUST_DATA WVTData;
if (WinVerifyTrust(NULL, WINTRUST_ACTION_GENERIC_VERIFY_V2, &WVTData) == NULL)
{
 for (i ...)
 {
   Wintrust.WTHelperProvDataFromStateData
   Wintrust.WTHelperGetProvSignerFromChain
   //CRYPT32.CertNameToStrA - имя в формате LDAP т.е. "C=US, S=Washington, L=Redmond, O=Microsoft Corporation, CN=Microsoft Windows Component Publisher"
   //далее идет разбор строки оставляют только "Microsoft Windows Component Publisher"
 }
 //потом еще раз вызываем
 WinVerifyTrust(NULL, WINTRUST_ACTION_GENERIC_VERIFY_V2, NULL);
}
winverifytrust
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.