From 976bb3767b2840919f3bc6a819f32118086f2617 Mon Sep 17 00:00:00 2001 From: Mounir IDRASSI Date: Tue, 14 Apr 2026 18:43:07 +0900 Subject: [PATCH] Windows: Fix MSI traveler disk creation with WHQL-signed drivers Make MSI-installed VeraCrypt use the IDRIX-signed COMReg package as the source for traveler files, matching the EXE installer flow. COMReg now packages the x64 traveler payload, so traveler creation no longer has to copy the installed x64 driver from appDir\veracrypt.sys and verify it against a Microsoft WHQL certificate fingerprint. Keep Microsoft WHQL certificate verification only for the loose portable driver fallback, where driver files cannot be signed with the IDRIX code signing certificate. The normal VerifyModuleSignature path now remains IDRIX-only. Also validate that an MSI COMReg package actually contains the required x64 traveler files before reporting success, avoiding partial traveler directories when the package payload is incomplete. --- src/COMReg/COMReg.cpp | 8 +++- src/Common/Dlgcode.c | 57 +++++++++++++++++++++------ src/Common/Dlgcode.h | 1 + src/Mount/Mount.c | 92 +++++++++++-------------------------------- 4 files changed, 76 insertions(+), 82 deletions(-) diff --git a/src/COMReg/COMReg.cpp b/src/COMReg/COMReg.cpp index 9582b413..426f38b8 100644 --- a/src/COMReg/COMReg.cpp +++ b/src/COMReg/COMReg.cpp @@ -21,8 +21,12 @@ int APIENTRY _tWinMain(HINSTANCE hInstance, if (s) s[1] = 0; - /* Create self-extracting package */ - MakeSelfExtractingPackage (NULL, SetupFilesDir, TRUE); + /* + * Create a self-extracting package containing the traveler files. + * The MSI traveler creation path verifies this IDRIX-signed package + * instead of verifying individual WHQL-signed driver files. + */ + MakeSelfExtractingPackage (NULL, SetupFilesDir, FALSE); } return 0; diff --git a/src/Common/Dlgcode.c b/src/Common/Dlgcode.c index 0842c94f..b51f1bf1 100644 --- a/src/Common/Dlgcode.c +++ b/src/Common/Dlgcode.c @@ -314,15 +314,41 @@ static unsigned char gpbSha512CodeSignCertFingerprint[64] = { 0xF1, 0x08, 0xF3, 0xA8 }; -static unsigned char gpbSha512MSCodeSignCertFingerprint[64] = { - 0x17, 0x8C, 0x1B, 0x37, 0x70, 0xBF, 0x8B, 0xDF, 0x84, 0x55, 0xC5, 0x18, - 0x13, 0x64, 0xE9, 0x65, 0x6D, 0x67, 0xCA, 0x0C, 0xD6, 0x3B, 0x9E, 0x7B, - 0x9B, 0x6A, 0x63, 0xD6, 0x19, 0xAE, 0xD7, 0xBA, 0xBE, 0x5C, 0xCB, 0xD1, - 0x07, 0x89, 0x07, 0xFB, 0x12, 0xC0, 0x2C, 0x94, 0x86, 0xEB, 0x67, 0x0B, - 0x9C, 0x97, 0xEB, 0x20, 0x38, 0x13, 0x9C, 0x0F, 0x56, 0x93, 0x1B, 0x19, - 0x6F, 0x8F, 0x6A, 0x39 +/* + * SHA-512 hashes of the DER-encoded Authenticode leaf certificates used by + * Microsoft WHQL signing for the current VeraCrypt driver files. These are + * accepted only by VerifyModuleSignatureAllowingMicrosoftWHQL(), which is used + * for loose portable driver files that cannot be signed by the IDRIX + * certificate. + */ +static unsigned char gpbSha512MSWHQLCertFingerprints[][64] = { + /* + * SHA-1 thumbprint 3847B761C2846DB72F61149176D09F9BB2D43E8A, + * observed on the latest WHQL signing certificate. + */ + { + 0x29, 0x85, 0xDC, 0xD4, 0x85, 0xBF, 0x3C, 0x48, 0xA6, 0x08, 0x13, 0x8E, + 0x53, 0xE6, 0x7A, 0x98, 0x7F, 0xE8, 0x1D, 0x9C, 0xE8, 0x37, 0xDF, 0xE0, + 0xCD, 0x68, 0xF9, 0x97, 0x11, 0x14, 0xF7, 0xEF, 0x69, 0xF7, 0x53, 0x24, + 0x82, 0x0E, 0x8D, 0x49, 0x37, 0xFA, 0xFD, 0xC5, 0x48, 0x76, 0xF0, 0xC0, + 0x5D, 0xF1, 0xCA, 0xAC, 0x7C, 0xC4, 0x5E, 0xC0, 0x93, 0x0C, 0x8E, 0x64, + 0x7C, 0x57, 0xFE, 0xEB + } }; +static BOOL IsKnownMSWHQLCertFingerprint (const unsigned char hashVal[64]) +{ + size_t i; + + for (i = 0; i < sizeof (gpbSha512MSWHQLCertFingerprints) / sizeof (gpbSha512MSWHQLCertFingerprints[0]); ++i) + { + if (0 == memcmp (hashVal, gpbSha512MSWHQLCertFingerprints[i], 64)) + return TRUE; + } + + return FALSE; +} + /* Windows dialog class */ #define WINDOWS_DIALOG_CLASS L"#32770" @@ -944,7 +970,7 @@ cleanup: } #endif -BOOL VerifyModuleSignature (const wchar_t* path) +static BOOL VerifyModuleSignatureInternal (const wchar_t* path, BOOL bAllowMicrosoftWHQL) { #if defined(NDEBUG) && !defined (VC_SKIP_OS_DRIVER_REQ_CHECK) BOOL bResult = FALSE; @@ -995,9 +1021,8 @@ BOOL VerifyModuleSignature (const wchar_t* path) BYTE hashVal[64]; sha512 (hashVal, pProviderCert->pCert->pbCertEncoded, pProviderCert->pCert->cbCertEncoded); - if ( (0 == memcmp (hashVal, gpbSha512CodeSignCertFingerprint, 64)) - || (0 == memcmp (hashVal, gpbSha512MSCodeSignCertFingerprint, 64)) - ) + if ((0 == memcmp (hashVal, gpbSha512CodeSignCertFingerprint, 64)) + || (bAllowMicrosoftWHQL && IsKnownMSWHQLCertFingerprint (hashVal))) { bResult = TRUE; } @@ -1016,6 +1041,16 @@ BOOL VerifyModuleSignature (const wchar_t* path) #endif } +BOOL VerifyModuleSignature (const wchar_t* path) +{ + return VerifyModuleSignatureInternal (path, FALSE); +} + +BOOL VerifyModuleSignatureAllowingMicrosoftWHQL (const wchar_t* path) +{ + return VerifyModuleSignatureInternal (path, TRUE); +} + DWORD handleWin32Error (HWND hwndDlg, const char* srcPos) { #if !defined(VC_COMREG) && !defined(VCSDK_DLL) diff --git a/src/Common/Dlgcode.h b/src/Common/Dlgcode.h index 6fded2f3..d7b2693c 100644 --- a/src/Common/Dlgcode.h +++ b/src/Common/Dlgcode.h @@ -594,6 +594,7 @@ BOOL DeleteDirectory (const wchar_t* szDirName); BOOL IsThreadInSecureDesktop(DWORD dwThreadID); INT_PTR SecureDesktopDialogBoxParam (HINSTANCE, LPCWSTR, HWND, DLGPROC, LPARAM); BOOL VerifyModuleSignature (const wchar_t* path); +BOOL VerifyModuleSignatureAllowingMicrosoftWHQL (const wchar_t* path); void GetInstallationPath (HWND hwndDlg, wchar_t* szInstallPath, DWORD cchSize, BOOL* pbInstallPathDetermined); BOOL GetSetupconfigLocation (wchar_t* path, DWORD cchSize); BOOL BufferHasPattern (const unsigned char* buffer, size_t bufferLen, const void* pattern, size_t patternLen); diff --git a/src/Mount/Mount.c b/src/Mount/Mount.c index a032e214..cf003208 100644 --- a/src/Mount/Mount.c +++ b/src/Mount/Mount.c @@ -4941,7 +4941,7 @@ BOOL CALLBACK TravelerDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lPa // Driver StringCbPrintfW (srcPath, sizeof(srcPath), L"%s\\veracrypt.sys", appDir); StringCbPrintfW (dstPath, sizeof(dstPath), L"%s\\VeraCrypt\\veracrypt.sys", dstDir); - if (!VerifyModuleSignature (srcPath)) + if (!VerifyModuleSignatureAllowingMicrosoftWHQL (srcPath)) { Error ("DIST_PACKAGE_CORRUPTED", hwndDlg); goto stop; @@ -4955,7 +4955,7 @@ BOOL CALLBACK TravelerDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lPa // Driver x64 StringCbPrintfW (srcPath, sizeof(srcPath), L"%s\\veracrypt-x64.sys", appDir); StringCbPrintfW (dstPath, sizeof(dstPath), L"%s\\VeraCrypt\\veracrypt-x64.sys", dstDir); - if (!VerifyModuleSignature (srcPath)) + if (!VerifyModuleSignatureAllowingMicrosoftWHQL (srcPath)) { Error ("DIST_PACKAGE_CORRUPTED", hwndDlg); goto stop; @@ -4969,7 +4969,7 @@ BOOL CALLBACK TravelerDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lPa // Driver ARM64 StringCbPrintfW(srcPath, sizeof(srcPath), L"%s\\veracrypt-arm64.sys", appDir); StringCbPrintfW(dstPath, sizeof(dstPath), L"%s\\VeraCrypt\\veracrypt-arm64.sys", dstDir); - if (!VerifyModuleSignature(srcPath)) + if (!VerifyModuleSignatureAllowingMicrosoftWHQL(srcPath)) { Error("DIST_PACKAGE_CORRUPTED", hwndDlg); goto stop; @@ -4983,19 +4983,23 @@ BOOL CALLBACK TravelerDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lPa else { int fileNo = 0; - BOOL bMsiX64Case = FALSE; - // get file from the Setup binary after checking its signature and its version + BOOL bMsiPackage = FALSE; + BOOL bCopiedX64App = FALSE; + BOOL bCopiedX64Driver = FALSE; + BOOL bCopiedX64Wizard = FALSE; + BOOL bCopiedX64Expander = FALSE; + // Get files from the IDRIX-signed setup or COMReg package after checking its signature and integrity. StringCbPrintfW (srcPath, sizeof(srcPath), L"%s\\VeraCrypt COMReg.exe", appDir); // MSI installation case if (FileExists(srcPath)) { - bMsiX64Case = TRUE; + bMsiPackage = TRUE; } else StringCbPrintfW (srcPath, sizeof(srcPath), L"%s\\VeraCrypt Setup.exe", appDir); // EXE installation case FreeAllFileBuffers (); - if (!VerifyPackageIntegrity (srcPath) || !SelfExtractInMemory (srcPath, TRUE) || (!bMsiX64Case && (Decompressed_Files_Count != NBR_COMPRESSED_FILES))) + if (!VerifyPackageIntegrity (srcPath) || !SelfExtractInMemory (srcPath, TRUE) || (!bMsiPackage && (Decompressed_Files_Count != NBR_COMPRESSED_FILES))) { MessageBoxW (hwndDlg, GetString ("DIST_PACKAGE_CORRUPTED"), lpszTitle, MB_ICONEXCLAMATION); goto stop; @@ -5071,71 +5075,21 @@ BOOL CALLBACK TravelerDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lPa MessageBoxW (hwndDlg, szTmp, lpszTitle, MB_ICONERROR | MB_SETFOREGROUND | MB_TOPMOST); goto stop; } + + if (wcscmp (fileName, L"VeraCrypt-x64.exe") == 0) + bCopiedX64App = TRUE; + else if (wcscmp (fileName, L"veracrypt-x64.sys") == 0) + bCopiedX64Driver = TRUE; + else if (wcscmp (fileName, L"VeraCrypt Format-x64.exe") == 0) + bCopiedX64Wizard = TRUE; + else if (wcscmp (fileName, L"VeraCryptExpander-x64.exe") == 0) + bCopiedX64Expander = TRUE; } - if (bMsiX64Case) + if (bMsiPackage && (!bCopiedX64App || !bCopiedX64Driver || (copyWizard && !bCopiedX64Wizard) || (copyExpander && !bCopiedX64Expander))) { - // Main app - StringCbPrintfW (srcPath, sizeof(srcPath), L"%s\\VeraCrypt.exe", appDir); - StringCbPrintfW (dstPath, sizeof(dstPath), L"%s\\VeraCrypt\\VeraCrypt-x64.exe", dstDir); - if (!VerifyModuleSignature (srcPath)) - { - Error ("DIST_PACKAGE_CORRUPTED", hwndDlg); - goto stop; - } - else if (!TCCopyFile (srcPath, dstPath)) - { - handleWin32Error (hwndDlg, SRC_POS); - goto stop; - } - - // Wizard - if (copyWizard) - { - StringCbPrintfW (srcPath, sizeof(srcPath), L"%s\\VeraCrypt Format.exe", appDir); - StringCbPrintfW (dstPath, sizeof(dstPath), L"%s\\VeraCrypt\\VeraCrypt Format-x64.exe", dstDir); - if (!VerifyModuleSignature (srcPath)) - { - Error ("DIST_PACKAGE_CORRUPTED", hwndDlg); - goto stop; - } - else if (!TCCopyFile (srcPath, dstPath)) - { - handleWin32Error (hwndDlg, SRC_POS); - goto stop; - } - } - - // Expander - if (copyExpander) - { - StringCbPrintfW (srcPath, sizeof(srcPath), L"%s\\VeraCryptExpander.exe", appDir); - StringCbPrintfW (dstPath, sizeof(dstPath), L"%s\\VeraCrypt\\VeraCryptExpander-x64.exe", dstDir); - if (!VerifyModuleSignature (srcPath)) - { - Error ("DIST_PACKAGE_CORRUPTED", hwndDlg); - goto stop; - } - else if (!TCCopyFile (srcPath, dstPath)) - { - handleWin32Error (hwndDlg, SRC_POS); - goto stop; - } - } - - // Driver - StringCbPrintfW (srcPath, sizeof(srcPath), L"%s\\veracrypt.sys", appDir); - StringCbPrintfW (dstPath, sizeof(dstPath), L"%s\\VeraCrypt\\veracrypt-x64.sys", dstDir); - if (!VerifyModuleSignature (srcPath)) - { - Error ("DIST_PACKAGE_CORRUPTED", hwndDlg); - goto stop; - } - else if (!TCCopyFile (srcPath, dstPath)) - { - handleWin32Error (hwndDlg, SRC_POS); - goto stop; - } + MessageBoxW (hwndDlg, GetString ("DIST_PACKAGE_CORRUPTED"), lpszTitle, MB_ICONEXCLAMATION); + goto stop; } }