/* 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; }
/*********************************************************************** * 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); }
/* 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; }
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; }
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); }
/*********************************************************************** * 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; }