什么是签名目录文件成员标记?

时间:2012-10-30 17:47:48

标签: c++ winapi

我正在填写WINTRUST_CATALOG_INFO结构。我已经计算了文件的哈希值并找到了要使用的目录文件。

有一位成员我不知道如何填写:

pcwszMemberTag
    Tag of a member file to be verified.

我在互联网上看到的大多数示例代码似乎都将文件哈希转换为自身的十六进制编码版本,并将其作为成员标记传递。我不知道为什么会这样。

2 个答案:

答案 0 :(得分:5)

它包含文件名的文本引用。此代码可能有助于理解工作流程:

HRESULT Cwvt::VerifyTrust(HANDLE hFile, HWND hWnd, PJAVA_TRUST *ppJavaTrust,
                          LPCWSTR szStatusText,
                          IInternetHostSecurityManager *pHostSecurityManager,
                          LPSTR szFilePath, LPSTR szCatalogFile,
                          CDownload *pdl) 
{
    LPWSTR                   wzFileName = NULL;
    LPWSTR                   wzFilePath = NULL;
    LPWSTR                   wzCatalogFile = NULL;
    GUID                     guidJava = JAVA_POLICY_PROVIDER_DOWNLOAD;
    GUID                     guidCor = COR_POLICY_PROVIDER_DOWNLOAD;
    GUID                     guidAuthenticode = WINTRUST_ACTION_GENERIC_VERIFY_V2;
    GUID                    *pguidActionIDJava = &guidJava;
    GUID                    *pguidActionIDCor = &guidCor;
    WINTRUST_DATA            wintrustData;
    WINTRUST_DATA            wtdAuthenticode;
    WINTRUST_FILE_INFO       fileData;
    JAVA_POLICY_PROVIDER     javaPolicyData;
    WCHAR                    wpath [MAX_PATH];
    PJAVA_TRUST              pbJavaTrust = NULL;
    IServiceProvider        *pServProv = NULL;
    LPCATALOGFILEINFO        pcfi = NULL;
    HRESULT                  hr = S_OK;

    ZEROSTRUCT(wintrustData);
    ZEROSTRUCT(fileData);
    ZEROSTRUCT(javaPolicyData);

    javaPolicyData.cbSize = sizeof(JAVA_POLICY_PROVIDER);
    javaPolicyData.VMBased = FALSE;
    javaPolicyData.fNoBadUI = FALSE;

    javaPolicyData.pwszZone = szStatusText;
    javaPolicyData.pZoneManager = (LPVOID)pHostSecurityManager;


    fileData.cbStruct = sizeof(WINTRUST_FILE_INFO);
    fileData.pcwszFilePath = szStatusText;
    fileData.hFile = hFile;

    wintrustData.cbStruct = sizeof(WINTRUST_DATA);
    wintrustData.pPolicyCallbackData = &javaPolicyData;

    if ( (hWnd == INVALID_HANDLE_VALUE) || IsUIRestricted())
        wintrustData.dwUIChoice = WTD_UI_NONE;
    else
        wintrustData.dwUIChoice = WTD_UI_ALL;

    wintrustData.dwUnionChoice = WTD_CHOICE_FILE;
    wintrustData.pFile = &fileData;

    if (szCatalogFile) {
        ::Ansi2Unicode(szCatalogFile, &wzCatalogFile);
        ::Ansi2Unicode(szFilePath, &wzFilePath);
        wzFileName = PathFindFileNameW(szStatusText);

        if (!m_bHaveWTData) {
            memset(&m_wtCatalogInfo, 0x0, sizeof(m_wtCatalogInfo));
            m_wtCatalogInfo.cbStruct = sizeof(WINTRUST_CATALOG_INFO);
            m_bHaveWTData = TRUE;
        }
        m_wtCatalogInfo.pcwszCatalogFilePath = wzCatalogFile;
        m_wtCatalogInfo.pcwszMemberTag = wzFileName;
        m_wtCatalogInfo.pcwszMemberFilePath = wzFilePath;

        wtdAuthenticode = wintrustData;
        wtdAuthenticode.pCatalog = &m_wtCatalogInfo;
        wtdAuthenticode.dwUnionChoice = WTD_CHOICE_CATALOG;
        wtdAuthenticode.dwStateAction = WTD_STATEACTION_VERIFY;
        wtdAuthenticode.dwUIChoice = WTD_UI_NONE;

        hr = WinVerifyTrust(hWnd, &guidAuthenticode, &wtdAuthenticode);
        if (FAILED(hr)) {
            hr = WinVerifyTrust(hWnd, pguidActionIDCor, &wintrustData);

            if (hr == TRUST_E_PROVIDER_UNKNOWN)
                hr = WinVerifyTrust(hWnd, pguidActionIDJava, &wintrustData);
        }
        else {
            // Clone Java permissions
            pbJavaTrust = pdl->GetCodeDownload()->GetJavaTrust();
            if (!pbJavaTrust) {
                hr = pdl->GetBSC()->QueryInterface(IID_IServiceProvider, (void **)&pServProv);
                if (SUCCEEDED(hr)) {
                    hr = pServProv->QueryService(IID_ICatalogFileInfo, IID_ICatalogFileInfo, (void **)&pcfi);
                    if (SUCCEEDED(hr)) {
                        pcfi->GetJavaTrust((void **)&pbJavaTrust);
                    }
                }
                SAFERELEASE(pServProv);
                SAFERELEASE(pcfi);
                pdl->SetMainCABJavaTrustPermissions(pbJavaTrust);
            }
        }

    }
    else {
        hr =  WinVerifyTrust(hWnd, pguidActionIDCor, &wintrustData);
        if (hr == TRUST_E_PROVIDER_UNKNOWN)
            hr = WinVerifyTrust(hWnd, pguidActionIDJava, &wintrustData);

        if (SUCCEEDED(hr)) {
            pdl->SetMainCABJavaTrustPermissions(javaPolicyData.pbJavaTrust);
        }
    }

    SAFEDELETE(wzCatalogFile);
    SAFEDELETE(wzFilePath);

    // BUGBUG: this works around a wvt bug that returns 0x57 (success) when
    // you hit No to an usigned control
    if (SUCCEEDED(hr) && hr != S_OK) {
        hr = TRUST_E_FAIL;
    }

    if (FAILED(hr)) {
        // display original hr intact to help debugging
//        CodeDownloadDebugOut(DEB_CODEDL, TRUE, ID_CDLDBG_VERIFYTRUST_FAILED, hr);
    } else {
        *ppJavaTrust = javaPolicyData.pbJavaTrust;
    }
    if (hr == TRUST_E_SUBJECT_NOT_TRUSTED && wintrustData.dwUIChoice == WTD_UI_NONE) {
        // if we didn't ask for the UI to be out up there has been no UI
        // work around WVT bvug that it returns us this special error code
        // without putting up UI.

        hr = TRUST_E_FAIL; // this will put up mshtml ui after the fact
                           // that security settings prevented us
    }

    if (FAILED(hr) && (hr != TRUST_E_SUBJECT_NOT_TRUSTED)) {

        // trust system has failed without UI

        // map error to this generic error that will falg our client to put
        // up additional info that this is a trust system error if reqd.
        hr = TRUST_E_FAIL;
    }

    if (hr == TRUST_E_SUBJECT_NOT_TRUSTED) {

        pdl->GetCodeDownload()->SetUserDeclined();
    }


    return hr;
}

HRESULT GetActivePolicy(IInternetHostSecurityManager* pZoneManager, 
                        LPCWSTR pwszZone,
                        DWORD  dwUrlAction,
                        DWORD& dwPolicy)
{
    HRESULT hr = TRUST_E_FAIL;
    HRESULT hr2 = TRUST_E_FAIL;
    DWORD cbPolicy = sizeof(DWORD);

    // Policy are ordered such that high numbers are the most conservative 
    // and the lower numbers are less conservative

    DWORD dwDocumentPolicy = URLPOLICY_ALLOW;
    DWORD dwUrlPolicy = URLPOLICY_ALLOW;

    // We are going for the most conservative so lets set the 
    // value to the least conservative
    dwPolicy = URLPOLICY_ALLOW;

    IInternetSecurityManager* iSM = NULL;

    // Ask the document base for its policy
    if(pZoneManager) { //  Given a IInternetHostSecurityManager
        hr = pZoneManager->ProcessUrlAction(dwUrlAction,
                                            (PBYTE) &dwDocumentPolicy,
                                            cbPolicy,
                                            NULL,
                                            0,
                                            PUAF_NOUI,
                                            0);
    }

    // Get the policy for the URL 
    if(pwszZone) { // Create an IInternetSecurityManager
        hr2 = CoInternetCreateSecurityManager(NULL,
                                              &iSM,
                                              0);
        if(hr2 == S_OK) { // We got the manager so get the policy info
            hr2 = iSM->ProcessUrlAction(pwszZone,
                                        dwUrlAction,
                                        (PBYTE) &dwUrlPolicy,
                                        cbPolicy,
                                        NULL,
                                        0,
                                        PUAF_NOUI,
                                        0);
            iSM->Release();
        }
        else 
            iSM = NULL;
    }

    // if they both failed and we have zones then set it to deny and return an error
    if(FAILED(hr) && FAILED(hr2)) {
        // If we failed because there are on zones then lets QUERY
        // BUGBUG: we should actually try to get the IE30 security policy here.
        if(iSM == NULL && pZoneManager == NULL) {
            dwPolicy = URLPOLICY_QUERY;
            hr = S_OK;
        }
        else {
            dwPolicy = URLPOLICY_DISALLOW;
            hr = TRUST_E_FAIL;
        }
    }
    else {
        if(SUCCEEDED(hr))
            dwPolicy = dwDocumentPolicy;
        if(SUCCEEDED(hr2))
            dwPolicy = dwPolicy > dwUrlPolicy ? dwPolicy : dwUrlPolicy;

        if (dwPolicy == URLPOLICY_DISALLOW)
            hr = TRUST_E_FAIL;
        else
            hr = S_OK;
    }
    return hr;
}

MSDN中可以找到一些其他评论。使用文件散列的十六进制表示作为参考标记是常见用法,但不是强制性的。

答案 1 :(得分:5)

标签存在,因为文件名不可靠。 pcwszMemberTag对应于将成员添加到目录时已设置为pwszReferenceTag的内容(例如,使用CryptCATPutMemberInfo function)。

为了真正符合API应该如何工作,我认为你应该首先获得会员信息,然后才能完全设置WINTRUST_CATALOG_INFO。要确定会员信息,您必须使用CryptCATEnumerateMember function(还有一个CryptCATGetMemberInfo function但你不能使用它 - 鸡和鸡蛋问题 - 你没有标签)并确定你的成员您想以任何方式感兴趣(使用其他CRYPTCATMEMBER structure字段)

使用文件散列的十六进制表示作为参考标记是常见用法(MakeCat可能会这样做,因此它看起来像标准),但我认为它根本不是强制性的 - 另一个是Java的东西回答是没有使用这个约定(另请参阅此链接:RE: CryptCATGetMemberInfo samples与微软的回答。)