Example #1
0
/* Assumes data->pWintrustData->u.pFile exists.  Sets data->pPDSip->gSubject to
 * the file's subject GUID.
 */
static DWORD SOFTPUB_GetFileSubject(CRYPT_PROVIDER_DATA *data)
{
    DWORD err = ERROR_SUCCESS;

    if (!WVT_ISINSTRUCT(WINTRUST_FILE_INFO,
     data->pWintrustData->u.pFile->cbStruct, pgKnownSubject) ||
     !data->pWintrustData->u.pFile->pgKnownSubject)
    {
        if (!CryptSIPRetrieveSubjectGuid(
         data->pWintrustData->u.pFile->pcwszFilePath,
         data->pWintrustData->u.pFile->hFile,
         &data->u.pPDSip->gSubject))
        {
            LARGE_INTEGER fileSize;
            DWORD sipError = GetLastError();

            /* Special case for empty files: the error is expected to be
             * TRUST_E_SUBJECT_FORM_UNKNOWN, rather than whatever
             * CryptSIPRetrieveSubjectGuid returns.
             */
            if (GetFileSizeEx(data->pWintrustData->u.pFile->hFile, &fileSize)
             && !fileSize.QuadPart)
                err = TRUST_E_SUBJECT_FORM_UNKNOWN;
            else
                err = sipError;
        }
    }
    else
        data->u.pPDSip->gSubject = *data->pWintrustData->u.pFile->pgKnownSubject;
    TRACE("returning %d\n", err);
    return err;
}
Example #2
0
/***********************************************************************
 *              IsCatalogFile
 */
BOOL WINAPI IsCatalogFile(HANDLE hFile, WCHAR *pwszFileName)
{
    static const GUID catGUID = { 0xDE351A43, 0x8E59, 0x11D0, { 0x8C,0x47,0x00,0xC0,0x4F,0xC2,0x95,0xEE }};
    GUID guid;

    TRACE("(%p, %s)\n", hFile, debugstr_w(pwszFileName));

    if (!CryptSIPRetrieveSubjectGuid(pwszFileName, hFile, &guid))
        return FALSE;
    return IsEqualGUID(&guid, &catGUID);
}
Example #3
0
/* Assumes data->pWintrustData->u.pFile exists.  Sets data->pPDSip->gSubject to
 * the file's subject GUID.
 */
static BOOL SOFTPUB_GetFileSubject(CRYPT_PROVIDER_DATA *data)
{
    BOOL ret;

    if (!data->pWintrustData->u.pFile->pgKnownSubject)
    {
        ret = CryptSIPRetrieveSubjectGuid(
         data->pWintrustData->u.pFile->pcwszFilePath,
         data->pWintrustData->u.pFile->hFile,
         &data->u.pPDSip->gSubject);
    }
    else
    {
        data->u.pPDSip->gSubject = *data->pWintrustData->u.pFile->pgKnownSubject;
        ret = TRUE;
    }
    TRACE("returning %d\n", ret);
    return ret;
}
Example #4
0
static DWORD SOFTPUB_LoadCatalogMessage(CRYPT_PROVIDER_DATA *data)
{
    DWORD err;
    HANDLE catalog = INVALID_HANDLE_VALUE;

    if (!data->pWintrustData->u.pCatalog)
    {
        SetLastError(ERROR_INVALID_PARAMETER);
        return FALSE;
    }
    catalog = CreateFileW(data->pWintrustData->u.pCatalog->pcwszCatalogFilePath,
     GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,
     NULL);
    if (catalog == INVALID_HANDLE_VALUE)
        return GetLastError();
    if (!CryptSIPRetrieveSubjectGuid(
     data->pWintrustData->u.pCatalog->pcwszCatalogFilePath, catalog,
     &data->u.pPDSip->gSubject))
    {
        err = GetLastError();
        goto error;
    }
    err = SOFTPUB_GetSIP(data);
    if (err)
        goto error;
    err = SOFTPUB_GetMessageFromFile(data, catalog,
     data->pWintrustData->u.pCatalog->pcwszCatalogFilePath);
    if (err)
        goto error;
    err = SOFTPUB_CreateStoreFromMessage(data);
    if (err)
        goto error;
    err = SOFTPUB_DecodeInnerContent(data);
    /* FIXME: this loads the catalog file, but doesn't validate the member. */
error:
    CloseHandle(catalog);
    return err;
}
Example #5
0
static void test_SIPRetrieveSubjectGUID(void)
{
    BOOL ret;
    GUID subject;
    HANDLE file;
    static const CHAR windir[] = "windir";
    static const CHAR regeditExe[] = "regedit.exe";
    static const GUID nullSubject  = { 0x0, 0x0, 0x0, { 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0 }};
    static const WCHAR deadbeef[]  = { 'c',':','\\','d','e','a','d','b','e','e','f','.','d','b','f',0 };
    /* Couldn't find a name for this GUID, it's the one used for 95% of the files */
    static const GUID unknownGUID = { 0xC689AAB8, 0x8E78, 0x11D0, { 0x8C,0x47,0x00,0xC0,0x4F,0xC2,0x95,0xEE }};
    static const GUID cabGUID = { 0xc689aaba, 0x8e78, 0x11d0, {0x8c,0x47,0x00,0xc0,0x4f,0xc2,0x95,0xee }};
    static CHAR  regeditPath[MAX_PATH];
    static WCHAR regeditPathW[MAX_PATH];
    static CHAR path[MAX_PATH];
    static CHAR tempfile[MAX_PATH];
    static WCHAR tempfileW[MAX_PATH];
    DWORD written;

    /* NULL check */
    SetLastError(0xdeadbeef);
    ret = CryptSIPRetrieveSubjectGuid(NULL, NULL, NULL);
    ok ( !ret, "Expected CryptSIPRetrieveSubjectGuid to fail\n");
    ok (GetLastError() == ERROR_INVALID_PARAMETER,
        "Expected ERROR_INVALID_PARAMETER, got %d.\n", GetLastError());

    /* Test with a nonexistent file (hopefully) */
    SetLastError(0xdeadbeef);
    /* Set subject to something other than zeros */
    memset(&subject, 1, sizeof(GUID));
    ret = CryptSIPRetrieveSubjectGuid(deadbeef, NULL, &subject);
    ok ( !ret, "Expected CryptSIPRetrieveSubjectGuid to fail\n");
    ok (GetLastError() == ERROR_FILE_NOT_FOUND ||
        GetLastError() == ERROR_PATH_NOT_FOUND,
        "Expected ERROR_FILE_NOT_FOUND or ERROR_PATH_NOT_FOUND, got %d.\n",
        GetLastError());
    ok ( !memcmp(&subject, &nullSubject, sizeof(GUID)),
        "Expected a NULL GUID for c:\\deadbeef.dbf, not %s\n", wine_dbgstr_guid(&subject));

    /* Now with an executable that should exist
     *
     * Use A-functions where possible as that should be available on all platforms
     */
    ret = GetEnvironmentVariableA(windir, regeditPath, MAX_PATH);
    ok (ret > 0, "expected GEVA(windir) to succeed, last error %d\n", GetLastError());
    strcat(regeditPath, "\\");
    strcat(regeditPath, regeditExe);
    MultiByteToWideChar( CP_ACP, 0, regeditPath,
                         strlen(regeditPath)+1, regeditPathW,
                         sizeof(regeditPathW)/sizeof(regeditPathW[0]) );

    SetLastError(0xdeadbeef);
    memset(&subject, 1, sizeof(GUID));
    ret = CryptSIPRetrieveSubjectGuid(regeditPathW, NULL, &subject);
    ok ( ret, "Expected CryptSIPRetrieveSubjectGuid to succeed\n");
    ok ( !memcmp(&subject, &unknownGUID, sizeof(GUID)),
        "Expected (%s), got (%s).\n", wine_dbgstr_guid(&unknownGUID), wine_dbgstr_guid(&subject));

    /* The same thing but now with a handle instead of a filename */
    file = CreateFileA(regeditPath, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
    SetLastError(0xdeadbeef);
    memset(&subject, 1, sizeof(GUID));
    ret = CryptSIPRetrieveSubjectGuid(NULL, file, &subject);
    ok ( ret, "Expected CryptSIPRetrieveSubjectGuid to succeed\n");
    ok ( !memcmp(&subject, &unknownGUID, sizeof(GUID)),
        "Expected (%s), got (%s).\n", wine_dbgstr_guid(&unknownGUID), wine_dbgstr_guid(&subject));
    CloseHandle(file);

    /* And both */
    file = CreateFileA(regeditPath, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
    SetLastError(0xdeadbeef);
    memset(&subject, 1, sizeof(GUID));
    ret = CryptSIPRetrieveSubjectGuid(regeditPathW, file, &subject);
    ok ( ret, "Expected CryptSIPRetrieveSubjectGuid to succeed\n");
    ok ( !memcmp(&subject, &unknownGUID, sizeof(GUID)),
        "Expected (%s), got (%s).\n", wine_dbgstr_guid(&unknownGUID), wine_dbgstr_guid(&subject));
    CloseHandle(file);

    /* Now with an empty file */
    GetTempPathA(sizeof(path), path);
    GetTempFileNameA(path, "sip", 0 , tempfile);
    MultiByteToWideChar( CP_ACP, 0, tempfile,
                         strlen(tempfile)+1, tempfileW,
                         sizeof(tempfileW)/sizeof(tempfileW[0]) );

    SetLastError(0xdeadbeef);
    memset(&subject, 1, sizeof(GUID));
    ret = CryptSIPRetrieveSubjectGuid(tempfileW, NULL, &subject);
    ok ( !ret, "Expected CryptSIPRetrieveSubjectGuid to fail\n");
    ok ( GetLastError() == ERROR_FILE_INVALID ||
         GetLastError() == ERROR_INVALID_PARAMETER /* Vista */ ||
         GetLastError() == ERROR_SUCCESS /* most Win98 */ ||
         GetLastError() == TRUST_E_SUBJECT_FORM_UNKNOWN /* some Win98 */,
        "Expected ERROR_FILE_INVALID, ERROR_INVALID_PARAMETER, ERROR_SUCCESS or TRUST_E_SUBJECT_FORM_UNKNOWN, got 0x%08x\n", GetLastError());
    ok ( !memcmp(&subject, &nullSubject, sizeof(GUID)),
        "Expected a NULL GUID for empty file %s, not %s\n", tempfile, wine_dbgstr_guid(&subject));

    /* Use a file with a size of 3 (at least < 4) */
    file = CreateFileA(tempfile, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
    WriteFile(file, "123", 3, &written, NULL);
    CloseHandle(file);

    SetLastError(0xdeadbeef);
    memset(&subject, 1, sizeof(GUID));
    ret = CryptSIPRetrieveSubjectGuid(tempfileW, NULL, &subject);
    ok ( !ret, "Expected CryptSIPRetrieveSubjectGuid to fail\n");
    ok ( GetLastError() == ERROR_INVALID_PARAMETER ||
         GetLastError() == ERROR_SUCCESS /* most Win98 */ ||
         GetLastError() == TRUST_E_SUBJECT_FORM_UNKNOWN /* some Win98 */,
        "Expected ERROR_INVALID_PARAMETER, ERROR_SUCCESS or TRUST_E_SUBJECT_FORM_UNKNOWN, got 0x%08x\n", GetLastError());
    ok ( !memcmp(&subject, &nullSubject, sizeof(GUID)),
        "Expected a NULL GUID for empty file %s, not %s\n", tempfile, wine_dbgstr_guid(&subject));

    /* And now >= 4 */
    file = CreateFileA(tempfile, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
    WriteFile(file, "1234", 4, &written, NULL);
    CloseHandle(file);

    SetLastError(0xdeadbeef);
    memset(&subject, 1, sizeof(GUID));
    ret = CryptSIPRetrieveSubjectGuid(tempfileW, NULL, &subject);
    ok ( !ret, "Expected CryptSIPRetrieveSubjectGuid to fail\n");
    ok ( GetLastError() == TRUST_E_SUBJECT_FORM_UNKNOWN ||
         GetLastError() == ERROR_SUCCESS /* Win98 */,
        "Expected TRUST_E_SUBJECT_FORM_UNKNOWN or ERROR_SUCCESS, got 0x%08x\n", GetLastError());
    ok ( !memcmp(&subject, &nullSubject, sizeof(GUID)),
        "Expected a NULL GUID for empty file %s, not %s\n", tempfile, wine_dbgstr_guid(&subject));

    /* Clean up */
    DeleteFileA(tempfile);

    /* Create a file with just the .cab header 'MSCF' */
    SetLastError(0xdeadbeef);
    file = CreateFileA(tempfile, GENERIC_WRITE, 0, NULL, CREATE_NEW, 0, NULL);
    ok(file != INVALID_HANDLE_VALUE, "failed with %u\n", GetLastError());
    WriteFile(file, cabFileData, 4, &written, NULL);
    CloseHandle(file);

    SetLastError(0xdeadbeef);
    memset(&subject, 1, sizeof(GUID));
    ret = CryptSIPRetrieveSubjectGuid(tempfileW, NULL, &subject);
    ok( ret, "CryptSIPRetrieveSubjectGuid failed: %d (0x%08x)\n",
            GetLastError(), GetLastError() );
    ok ( !memcmp(&subject, &cabGUID, sizeof(GUID)),
        "Expected GUID %s for cabinet file, not %s\n", wine_dbgstr_guid(&cabGUID), wine_dbgstr_guid(&subject));

    /* Clean up */
    DeleteFileA(tempfile);

    /* Create a .cab file */
    SetLastError(0xdeadbeef);
    file = CreateFileA(tempfile, GENERIC_WRITE, 0, NULL, CREATE_NEW, 0, NULL);
    ok(file != INVALID_HANDLE_VALUE, "failed with %u\n", GetLastError());
    WriteFile(file, cabFileData, sizeof(cabFileData), &written, NULL);
    CloseHandle(file);

    SetLastError(0xdeadbeef);
    memset(&subject, 1, sizeof(GUID));
    ret = CryptSIPRetrieveSubjectGuid(tempfileW, NULL, &subject);
    ok( ret, "CryptSIPRetrieveSubjectGuid failed: %d (0x%08x)\n",
            GetLastError(), GetLastError() );
    ok ( !memcmp(&subject, &cabGUID, sizeof(GUID)),
        "Expected GUID %s for cabinet file, not %s\n", wine_dbgstr_guid(&cabGUID), wine_dbgstr_guid(&subject));

    /* Clean up */
    DeleteFileA(tempfile);
}
Example #6
0
File: crypt.c Project: dvdhoo/wine
/***********************************************************************
 *      CryptCATOpen  (WINTRUST.@)
 */
HANDLE WINAPI CryptCATOpen(LPWSTR pwszFileName, DWORD fdwOpenFlags, HCRYPTPROV hProv,
                           DWORD dwPublicVersion, DWORD dwEncodingType)
{
    HANDLE file, hmsg;
    BYTE *buffer = NULL;
    DWORD size, flags = OPEN_EXISTING;
    struct cryptcat *cc;

    TRACE("%s, %x, %lx, %x, %x\n", debugstr_w(pwszFileName), fdwOpenFlags,
          hProv, dwPublicVersion, dwEncodingType);

    if (!pwszFileName)
    {
        SetLastError(ERROR_INVALID_PARAMETER);
        return INVALID_HANDLE_VALUE;
    }

    if (!dwEncodingType)  dwEncodingType  = X509_ASN_ENCODING | PKCS_7_ASN_ENCODING;

    if (fdwOpenFlags & CRYPTCAT_OPEN_ALWAYS)    flags |= OPEN_ALWAYS;
    if (fdwOpenFlags & CRYPTCAT_OPEN_CREATENEW) flags |= CREATE_NEW;

    file = CreateFileW(pwszFileName, GENERIC_READ, FILE_SHARE_READ, NULL, flags, 0, NULL);
    if (file == INVALID_HANDLE_VALUE) return INVALID_HANDLE_VALUE;

    size = GetFileSize(file, NULL);
    if (!(buffer = HeapAlloc(GetProcessHeap(), 0, size)))
    {
        CloseHandle(file);
        SetLastError(ERROR_OUTOFMEMORY);
        return INVALID_HANDLE_VALUE;
    }
    if (!(hmsg = CryptMsgOpenToDecode(dwEncodingType, 0, 0, hProv, NULL, NULL)))
    {
        CloseHandle(file);
        HeapFree(GetProcessHeap(), 0, buffer);
        return INVALID_HANDLE_VALUE;
    }
    if (!ReadFile(file, buffer, size, &size, NULL) || !CryptMsgUpdate(hmsg, buffer, size, TRUE))
    {
        CloseHandle(file);
        HeapFree(GetProcessHeap(), 0, buffer);
        CryptMsgClose(hmsg);
        return INVALID_HANDLE_VALUE;
    }
    HeapFree(GetProcessHeap(), 0, buffer);
    CloseHandle(file);

    size = sizeof(DWORD);
    if (!(cc = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*cc))))
    {
        CryptMsgClose(hmsg);
        SetLastError(ERROR_OUTOFMEMORY);
        return INVALID_HANDLE_VALUE;
    }

    cc->msg = hmsg;
    cc->encoding = dwEncodingType;
    if (CryptMsgGetParam(hmsg, CMSG_ATTR_CERT_COUNT_PARAM, 0, &cc->attr_count, &size))
    {
        DWORD i, sum = 0;
        BYTE *p;

        for (i = 0; i < cc->attr_count; i++)
        {
            if (!CryptMsgGetParam(hmsg, CMSG_ATTR_CERT_PARAM, i, NULL, &size))
            {
                CryptMsgClose(hmsg);
                return INVALID_HANDLE_VALUE;
            }
            sum += size;
        }
        if (!(cc->attr = HeapAlloc(GetProcessHeap(), 0, sizeof(*cc->attr) * cc->attr_count + sum)))
        {
            CryptMsgClose(hmsg);
            SetLastError(ERROR_OUTOFMEMORY);
            return INVALID_HANDLE_VALUE;
        }
        p = (BYTE *)(cc->attr + cc->attr_count);
        for (i = 0; i < cc->attr_count; i++)
        {
            if (!CryptMsgGetParam(hmsg, CMSG_ATTR_CERT_PARAM, i, NULL, &size))
            {
                CryptMsgClose(hmsg);
                HeapFree(GetProcessHeap(), 0, cc->attr);
                return INVALID_HANDLE_VALUE;
            }
            if (!CryptMsgGetParam(hmsg, CMSG_ATTR_CERT_PARAM, i, p, &size))
            {
                CryptMsgClose(hmsg);
                HeapFree(GetProcessHeap(), 0, cc->attr);
                return INVALID_HANDLE_VALUE;
            }
            p += size;
        }
        cc->inner = decode_inner_content(hmsg, dwEncodingType, &cc->inner_len);
        if (!cc->inner || !CryptSIPRetrieveSubjectGuid(pwszFileName, NULL, &cc->subject))
        {
            CryptMsgClose(hmsg);
            HeapFree(GetProcessHeap(), 0, cc->attr);
            HeapFree(GetProcessHeap(), 0, cc->inner);
            HeapFree(GetProcessHeap(), 0, cc);
            return INVALID_HANDLE_VALUE;
        }
        cc->magic = CRYPTCAT_MAGIC;
        return cc;
    }
    return INVALID_HANDLE_VALUE;
}