Beispiel #1
0
BOOL
GetCatFileFromDriverPath(LPWSTR szFileName, LPWSTR szCatFileName)
{
    GUID VerifyGuid = DRIVER_ACTION_VERIFY;
    HANDLE hFile;
    DWORD dwHash;
    BYTE bHash[100];
    HCATINFO hCatInfo;
    HCATADMIN hActAdmin;
    BOOL bRet = FALSE;
    CATALOG_INFO CatInfo;

    /* attempt to open file */
    hFile = CreateFileW(szFileName, GENERIC_READ,  FILE_SHARE_READ, NULL,  OPEN_EXISTING,  FILE_ATTRIBUTE_NORMAL, NULL);
    if (hFile == INVALID_HANDLE_VALUE)
        return FALSE;

     /* calculate hash from file handle */
     dwHash = sizeof(bHash);
     if (!CryptCATAdminCalcHashFromFileHandle(hFile, &dwHash, bHash, 0))
     {
        CloseHandle(hFile);
        return FALSE;
     }

    /* try open the CAT admin */
    if (!CryptCATAdminAcquireContext(&hActAdmin, &VerifyGuid, 0))
    {
        CloseHandle(hFile);
        return FALSE;
    }

    /* search catalog to find for catalog containing this hash */
    hCatInfo = CryptCATAdminEnumCatalogFromHash(hActAdmin, bHash, dwHash, 0, NULL);
    if (hCatInfo != NULL)
    {
        /* theres a catalog get the filename */
        bRet = CryptCATCatalogInfoFromContext(hCatInfo, &CatInfo, 0);
        if (bRet)
           wcscpy(szCatFileName, CatInfo.wszCatalogFile);
        CryptCATAdminReleaseCatalogContext(hActAdmin, hCatInfo, 0);
    }

    /* perform cleanup */
    CloseHandle(hFile);
    CryptCATAdminReleaseContext(hActAdmin, 0);
    return bRet;
}
Beispiel #2
0
/***********************************************************************
 *      pSetupInstallCatalog  (SETUPAPI.@)
 */
DWORD WINAPI pSetupInstallCatalog( LPCWSTR catalog, LPCWSTR basename, LPWSTR fullname )
{
    HCATADMIN admin;
    HCATINFO cat;

    TRACE ("%s, %s, %p\n", debugstr_w(catalog), debugstr_w(basename), fullname);

    if (!CryptCATAdminAcquireContext(&admin,NULL,0))
        return GetLastError();

    if (!(cat = CryptCATAdminAddCatalog( admin, (PWSTR)catalog, (PWSTR)basename, 0 )))
    {
        DWORD rc = GetLastError();
        CryptCATAdminReleaseContext(admin, 0);
        return rc;
    }
    CryptCATAdminReleaseCatalogContext(admin, cat, 0);
    CryptCATAdminReleaseContext(admin,0);

    if (fullname)
        FIXME("not returning full installed catalog path\n");

    return NO_ERROR;
}
Beispiel #3
0
/***********************************************************************
 *      SetupCopyOEMInfW  (SETUPAPI.@)
 */
BOOL WINAPI SetupCopyOEMInfW( PCWSTR source, PCWSTR location,
                              DWORD media_type, DWORD style, PWSTR dest,
                              DWORD buffer_size, PDWORD required_size, PWSTR *component )
{
    BOOL ret = FALSE;
    WCHAR target[MAX_PATH], catalog_file[MAX_PATH], *p;
    static const WCHAR inf[] = { '\\','i','n','f','\\',0 };
    static const WCHAR wszVersion[] = { 'V','e','r','s','i','o','n',0 };
    static const WCHAR wszCatalogFile[] = { 'C','a','t','a','l','o','g','F','i','l','e',0 };
    DWORD size;
    HINF hinf;

    TRACE("%s, %s, %d, %d, %p, %d, %p, %p\n", debugstr_w(source), debugstr_w(location),
          media_type, style, dest, buffer_size, required_size, component);

    if (!source)
    {
        SetLastError(ERROR_INVALID_PARAMETER);
        return FALSE;
    }

    /* check for a relative path */
    if (!(*source == '\\' || (*source && source[1] == ':')))
    {
        SetLastError(ERROR_FILE_NOT_FOUND);
        return FALSE;
    }

    if (!GetWindowsDirectoryW( target, sizeof(target)/sizeof(WCHAR) )) return FALSE;

    strcatW( target, inf );
    if ((p = strrchrW( source, '\\' )))
        strcatW( target, p + 1 );

    /* does the file exist already? */
    if ((GetFileAttributesW( target ) != INVALID_FILE_ATTRIBUTES) &&
        !(style & SP_COPY_NOOVERWRITE))
    {
        static const WCHAR oem[] = { 'o','e','m',0 };
        unsigned int i;
        LARGE_INTEGER source_file_size;
        HANDLE source_file;

        source_file = CreateFileW( source, FILE_READ_DATA | FILE_READ_ATTRIBUTES,
                                   FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
                                   NULL, OPEN_EXISTING, 0, NULL );
        if (source_file == INVALID_HANDLE_VALUE)
            return FALSE;

        if (!GetFileSizeEx( source_file, &source_file_size ))
        {
            CloseHandle( source_file );
            return FALSE;
        }

        p = strrchrW( target, '\\' ) + 1;
        memcpy( p, oem, sizeof(oem) );
        p += sizeof(oem)/sizeof(oem[0]) - 1;

        /* generate OEMnnn.inf ending */
        for (i = 0; i < OEM_INDEX_LIMIT; i++)
        {
            static const WCHAR format[] = { '%','u','.','i','n','f',0 };
            HANDLE dest_file;
            LARGE_INTEGER dest_file_size;

            wsprintfW( p, format, i );
            dest_file = CreateFileW( target, FILE_READ_DATA | FILE_READ_ATTRIBUTES,
                                     FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
                                     NULL, OPEN_EXISTING, 0, NULL );
            /* if we found a file name that doesn't exist then we're done */
            if (dest_file == INVALID_HANDLE_VALUE)
                break;
            /* now check if the same inf file has already been copied to the inf
             * directory. if so, use that file and don't create a new one */
            if (!GetFileSizeEx( dest_file, &dest_file_size ) ||
                (dest_file_size.QuadPart != source_file_size.QuadPart) ||
                compare_files( source_file, dest_file ))
            {
                CloseHandle( dest_file );
                continue;
            }
            CloseHandle( dest_file );
            break;
        }

        CloseHandle( source_file );
        if (i == OEM_INDEX_LIMIT)
        {
            SetLastError( ERROR_FILENAME_EXCED_RANGE );
            return FALSE;
        }
    }

    hinf = SetupOpenInfFileW( source, NULL, INF_STYLE_WIN4, NULL );
    if (hinf == INVALID_HANDLE_VALUE) return FALSE;

    if (SetupGetLineTextW( NULL, hinf, wszVersion, wszCatalogFile, catalog_file,
                           sizeof(catalog_file)/sizeof(catalog_file[0]), NULL ))
    {
        WCHAR source_cat[MAX_PATH];
        HCATADMIN handle;
        HCATINFO cat;
        GUID msguid = DRIVER_ACTION_VERIFY;

        SetupCloseInfFile( hinf );

        strcpyW( source_cat, source );
        p = strrchrW( source_cat, '\\' );
        if (p) p++;
        else p = source_cat;
        strcpyW( p, catalog_file );

        TRACE("installing catalog file %s\n", debugstr_w( source_cat ));

        if (!CryptCATAdminAcquireContext(&handle, &msguid, 0))
        {
            ERR("Could not acquire security context\n");
            return FALSE;
        }

        if (!(cat = CryptCATAdminAddCatalog(handle, source_cat, catalog_file, 0)))
        {
            ERR("Could not add catalog\n");
            CryptCATAdminReleaseContext(handle, 0);
            return FALSE;
        }

        CryptCATAdminReleaseCatalogContext(handle, cat, 0);
        CryptCATAdminReleaseContext(handle, 0);
    }
    else
        SetupCloseInfFile( hinf );

    if (!(ret = CopyFileW( source, target, (style & SP_COPY_NOOVERWRITE) != 0 )))
        return ret;

    if (style & SP_COPY_DELETESOURCE)
        DeleteFileW( source );

    size = strlenW( target ) + 1;
    if (dest)
    {
        if (buffer_size >= size)
        {
            strcpyW( dest, target );
        }
        else
        {
            SetLastError( ERROR_INSUFFICIENT_BUFFER );
            ret = FALSE;
        }
    }

    if (component) *component = p + 1;
    if (required_size) *required_size = size;
    if (ret) SetLastError(ERROR_SUCCESS);

    return ret;
}
Beispiel #4
0
/***********************************************************************
 *             CryptCATAdminEnumCatalogFromHash (WINTRUST.@)
 */
HCATINFO WINAPI CryptCATAdminEnumCatalogFromHash(HCATADMIN hCatAdmin, BYTE* pbHash,
        DWORD cbHash, DWORD dwFlags,
        HCATINFO* phPrevCatInfo )
{
    static const WCHAR slashW[] = {'\\',0};
    static const WCHAR globW[]  = {'\\','*','.','c','a','t',0};

    struct catadmin *ca = hCatAdmin;
    WIN32_FIND_DATAW data;
    HCATINFO prev = NULL;
    HCRYPTPROV prov;
    DWORD size;
    BOOL ret;

    TRACE("%p %p %d %x %p\n", hCatAdmin, pbHash, cbHash, dwFlags, phPrevCatInfo);

    if (!ca || ca->magic != CATADMIN_MAGIC || !pbHash || cbHash != 20 || dwFlags)
    {
        SetLastError(ERROR_INVALID_PARAMETER);
        return NULL;
    }
    if (phPrevCatInfo) prev = *phPrevCatInfo;

    ret = CryptAcquireContextW(&prov, NULL, MS_DEF_PROV_W, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
    if (!ret) return NULL;

    if (!prev)
    {
        WCHAR *path;

        size = strlenW(ca->path) * sizeof(WCHAR) + sizeof(globW);
        if (!(path = HeapAlloc(GetProcessHeap(), 0, size)))
        {
            CryptReleaseContext(prov, 0);
            SetLastError(ERROR_OUTOFMEMORY);
            return NULL;
        }
        strcpyW(path, ca->path);
        strcatW(path, globW);

        FindClose(ca->find);
        ca->find = FindFirstFileW(path, &data);

        HeapFree(GetProcessHeap(), 0, path);
        if (ca->find == INVALID_HANDLE_VALUE)
        {
            CryptReleaseContext(prov, 0);
            return NULL;
        }
    }
    else if (!FindNextFileW(ca->find, &data))
    {
        CryptCATAdminReleaseCatalogContext(hCatAdmin, prev, 0);
        CryptReleaseContext(prov, 0);
        return NULL;
    }

    while (1)
    {
        WCHAR *filename;
        CRYPTCATMEMBER *member = NULL;
        struct catinfo *ci;
        HANDLE hcat;

        size = (strlenW(ca->path) + strlenW(data.cFileName) + 2) * sizeof(WCHAR);
        if (!(filename = HeapAlloc(GetProcessHeap(), 0, size)))
        {
            SetLastError(ERROR_OUTOFMEMORY);
            return NULL;
        }
        strcpyW(filename, ca->path);
        strcatW(filename, slashW);
        strcatW(filename, data.cFileName);

        hcat = CryptCATOpen(filename, CRYPTCAT_OPEN_EXISTING, prov, 0, 0);
        if (hcat == INVALID_HANDLE_VALUE)
        {
            WARN("couldn't open %s (%u)\n", debugstr_w(filename), GetLastError());
            continue;
        }
        while ((member = CryptCATEnumerateMember(hcat, member)))
        {
            if (member->pIndirectData->Digest.cbData != cbHash)
            {
                WARN("amount of hash bytes differs: %u/%u\n", member->pIndirectData->Digest.cbData, cbHash);
                continue;
            }
            if (!memcmp(member->pIndirectData->Digest.pbData, pbHash, cbHash))
            {
                TRACE("file %s matches\n", debugstr_w(data.cFileName));

                CryptCATClose(hcat);
                CryptReleaseContext(prov, 0);
                if (!phPrevCatInfo)
                {
                    FindClose(ca->find);
                    ca->find = INVALID_HANDLE_VALUE;
                }
                ci = create_catinfo(filename);
                HeapFree(GetProcessHeap(), 0, filename);
                return ci;
            }
        }
        CryptCATClose(hcat);
        HeapFree(GetProcessHeap(), 0, filename);

        if (!FindNextFileW(ca->find, &data))
        {
            FindClose(ca->find);
            ca->find = INVALID_HANDLE_VALUE;
            CryptReleaseContext(prov, 0);
            return NULL;
        }
    }
    return NULL;
}
Beispiel #5
0
BOOL VerifyEmbeddedSignature( LPCWSTR lpFileName )
{
	BOOL bRet = FALSE;
	WINTRUST_DATA wd = { 0 };
	WINTRUST_FILE_INFO wfi = { 0 };
	WINTRUST_CATALOG_INFO wci = { 0 };
	CATALOG_INFO ci = { 0 };

	HCATADMIN hCatAdmin = NULL;
	if ( !CryptCATAdminAcquireContext( &hCatAdmin, NULL, 0 ) )
	{
		return FALSE;
	}

	HANDLE hFile = CreateFileW( lpFileName, GENERIC_READ, FILE_SHARE_READ,
		NULL, OPEN_EXISTING, 0, NULL );
	if ( INVALID_HANDLE_VALUE == hFile )
	{
		CryptCATAdminReleaseContext( hCatAdmin, 0 );
		return FALSE;
	}

	DWORD dwCnt = 100;
	BYTE byHash[100];
	CryptCATAdminCalcHashFromFileHandle( hFile, &dwCnt, byHash, 0 );
	CloseHandle( hFile );

	//LPWSTR pszMemberTag = new WCHAR[dwCnt * 2 + 1];
	//LPWSTR pszMemberTag = (WCHAR *)VirtualAlloc(0, dwCnt * 2 + 1,MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);

	//用静态内存~!
	WCHAR pszMemberTag[260] = {0};
	for ( DWORD dw = 0; dw < dwCnt; ++dw )
	{
		wsprintfW( &pszMemberTag[dw * 2], L"%02X", byHash[dw] );
	}

	HCATINFO hCatInfo = CryptCATAdminEnumCatalogFromHash( hCatAdmin,
		byHash, dwCnt, 0, NULL );
	if ( NULL == hCatInfo )
	{
		wfi.cbStruct       = sizeof( WINTRUST_FILE_INFO );
		wfi.pcwszFilePath  = lpFileName;
		wfi.hFile          = NULL;
		wfi.pgKnownSubject = NULL;

		wd.cbStruct            = sizeof( WINTRUST_DATA );
		wd.dwUnionChoice       = WTD_CHOICE_FILE;
		wd.pFile               = &wfi;
		wd.dwUIChoice          = WTD_UI_NONE;
		wd.fdwRevocationChecks = WTD_REVOKE_NONE;
		wd.dwStateAction       = WTD_STATEACTION_IGNORE;
		wd.dwProvFlags         = WTD_SAFER_FLAG;
		wd.hWVTStateData       = NULL;
		wd.pwszURLReference    = NULL;
	}
	else
	{
		CryptCATCatalogInfoFromContext( hCatInfo, &ci, 0 );
		wci.cbStruct             = sizeof( WINTRUST_CATALOG_INFO );
		wci.pcwszCatalogFilePath = ci.wszCatalogFile;
		wci.pcwszMemberFilePath  = lpFileName;
		wci.pcwszMemberTag       = pszMemberTag;

		wd.cbStruct            = sizeof( WINTRUST_DATA );
		wd.dwUnionChoice       = WTD_CHOICE_CATALOG;
		wd.pCatalog            = &wci;
		wd.dwUIChoice          = WTD_UI_NONE;
		wd.fdwRevocationChecks = WTD_STATEACTION_VERIFY;
		wd.dwProvFlags         = 0;
		wd.hWVTStateData       = NULL;
		wd.pwszURLReference    = NULL;
	}
	GUID action = WINTRUST_ACTION_GENERIC_VERIFY_V2;
	HRESULT hr  = WinVerifyTrust( NULL, &action, &wd );
	bRet        = SUCCEEDED( hr );

	//记得要释放啊,尼玛的不然内存飚的老高了~!!!!
	if (hCatAdmin && hCatInfo)
		 CryptCATAdminReleaseCatalogContext(hCatAdmin,hCatInfo,0);

	if (hCatAdmin)
		CryptCATAdminReleaseContext( hCatAdmin, 0 );

	//delete[] pszMemberTag;
	//VirtualFree(pszMemberTag,dwCnt * 2 + 1,MEM_RESERVE | MEM_COMMIT);

	return bRet;
}