Получение цифровой подписи из mmc.exe в Windows 8

У меня есть приложение, которое пытается проверить подпись mmc.exe (службы). (контекст приложения, я думаю, не имеет значения) Я пытаюсь использовать функцию winapi, которая не работает с
WinVerifyTrust. Я получаю TRUST_E_BAD_DIGEST при попытке подтверждения из каталога и
TRUST_E_NOSIGNATURE при попытке получить информацию из файла. очень важно отметить, что моя функция успешно работает на win7, XP, но не на win8.

это фрагмент кода для функции

CATALOG_INFO InfoStruct = {0};
InfoStruct.cbStruct = sizeof(CATALOG_INFO);

WINTRUST_CATALOG_INFO WintrustCatalogStructure = {0};
WintrustCatalogStructure.cbStruct = sizeof(WINTRUST_CATALOG_INFO);

WINTRUST_FILE_INFO WintrustFileStructure = {0};
WintrustFileStructure.cbStruct = sizeof(WINTRUST_FILE_INFO);

GUID ActionGuid = WINTRUST_ACTION_GENERIC_VERIFY_V2;

//Get a context for signature verification.
HCATADMIN Context = NULL;
if(!::CryptCATAdminAcquireContext(&Context, NULL, 0) ){
return false;
}

//Open file.

cx_handle hFile(::CreateFileW(filename_.c_str(), GENERIC_READ, 7, NULL, OPEN_EXISTING, 0, NULL));
if( INVALID_HANDLE_VALUE == (HANDLE)hFile )
{
CryptCATAdminReleaseContext(Context, 0);
return false;
}

//Get the size we need for our hash.
DWORD HashSize = 0;
::CryptCATAdminCalcHashFromFileHandle(hFile, &HashSize, NULL, 0);
if( HashSize == 0 )
{
//0-sized has means error!
::CryptCATAdminReleaseContext(Context, 0);
return false;
}

//Allocate memory.
buffer hashbuf(HashSize);

//Actually calculate the hash
if( !CryptCATAdminCalcHashFromFileHandle(hFile, &HashSize, hashbuf.data, 0) )
{
CryptCATAdminReleaseContext(Context, 0);
return false;
}

//Convert the hash to a string.
buffer MemberTag(((HashSize * 2) + 1) * sizeof(wchar_t));
for( unsigned int i = 0; i < HashSize; i++ ){
swprintf(&((PWCHAR)MemberTag.data)[i * 2], L"%02X", hashbuf.data[i ]);
}

//Get catalog for our context.
HCATINFO CatalogContext = CryptCATAdminEnumCatalogFromHash(Context, hashbuf, HashSize, 0, NULL);
if ( CatalogContext )
{
//If we couldn't get information
if ( !CryptCATCatalogInfoFromContext(CatalogContext, &InfoStruct, 0) )
{
//Release the context and set the context to null so it gets picked up below.
CryptCATAdminReleaseCatalogContext(Context, CatalogContext, 0);
CatalogContext = NULL;
}
}

//If we have a valid context, we got our info.
//Otherwise, we attempt to verify the internal signature.

WINTRUST_DATA WintrustStructure = {0};
WintrustStructure.cbStruct = sizeof(WINTRUST_DATA);

if( !CatalogContext )
{
load_signature_verification_from_file_info(WintrustFileStructure, WintrustStructure);
}
else
{
load_signature_verification_from_catalog(WintrustStructure, WintrustCatalogStructure, InfoStruct, MemberTag);
}

//Call our verification function.
long verification_res = ::WinVerifyTrust(0, &ActionGuid, &WintrustStructure);

//Check return.
bool is_success = SUCCEEDED(verification_res) ? true : false;

// if failed with CatalogContext, try with FILE_INFO
if(!is_success && CatalogContext && verification_res != TRUST_E_NOSIGNATURE)
{
//warning2(L"Failed verification with Catalog Context: 0x%x %s ; Retrying with FILE_INFO.", verification_res, (const wchar_t*)format_last_error(verification_res));

load_signature_verification_from_file_info(WintrustFileStructure, WintrustStructure);
verification_res = ::WinVerifyTrust(0, &ActionGuid, &WintrustStructure);
is_success = SUCCEEDED(verification_res) ? true : false;
}

if(perr && !is_success && verification_res != TRUST_E_NOSIGNATURE)
{
perr->code = verification_res;
perr->description = format_last_error(verification_res);
}

//Free context.
if( CatalogContext ){
::CryptCATAdminReleaseCatalogContext(Context, CatalogContext, 0);
}

//If we successfully verified, we need to free.
if( is_success )
{
WintrustStructure.dwStateAction = WTD_STATEACTION_CLOSE;
::WinVerifyTrust(0, &ActionGuid, &WintrustStructure);
}

::CryptCATAdminReleaseContext(Context, 0);

return is_success;

Я не думаю, что что-то изменилось в этой функции с win7 на win 8, так что может пойти не так?

ОБНОВИТЬ

Я заметил, что моя функция работает для диспетчера задач на win 8.
но опять же для MMC это не работает.

1

Решение

Похоже, что ваш общий подход правильный и сами функции не изменились. Однако есть небольшие изменения; а именно данные, на которых они работают, изменились. Хеши, хранящиеся для файлов в Windows 8, согласно комментариям к CryptCATAdminCalcHashFromFileHandle, рассчитываются с использованием хэшей SHA-256.

Алгоритм хеширования SHA-256 не поддерживается CryptCATAdminCalcHashFromFileHandle, поэтому необходимо обновить код, чтобы использовать CryptCATAdminAcquireContext2 а также CryptCATAdminCalcHashFromFileHandle2 в Windows 8; первое позволяет вам приобрести HCATADMIN с указанным алгоритмом хеширования, и последний позволяет использовать это HCATADMIN,

(Что интересно, WINTRUST_CATALOG_INFO также указывает это направление с его HCATADMIN hCatAdmin член, задокументированный как «Windows 8 и Windows Server 2012: Поддержка этого члена начинается. «)

2

Другие решения


По вопросам рекламы [email protected]