VeraCrypt
aboutsummaryrefslogtreecommitdiff
path: root/src/Common/Keyfiles.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/Common/Keyfiles.c')
-rw-r--r--src/Common/Keyfiles.c149
1 files changed, 83 insertions, 66 deletions
diff --git a/src/Common/Keyfiles.c b/src/Common/Keyfiles.c
index 9f756e53..d10daa06 100644
--- a/src/Common/Keyfiles.c
+++ b/src/Common/Keyfiles.c
@@ -23,6 +23,7 @@
#include "Dlgcode.h"
#include "Language.h"
#include "SecurityToken.h"
+#include "EMVToken.h"
#include "Common/resource.h"
#include "Platform/Finally.h"
#include "Platform/ForEach.h"
@@ -147,52 +148,43 @@ void KeyFileCloneAll (KeyFile *firstKeyFile, KeyFile **outputKeyFile)
}
-static BOOL KeyFileProcess (unsigned __int8 *keyPool, KeyFile *keyFile)
+static BOOL KeyFileProcess (unsigned __int8 *keyPool, unsigned __int32 keyPoolSize, KeyFile *keyFile)
{
- FILE *f;
unsigned __int8 buffer[64 * 1024];
unsigned __int32 crc = 0xffffffff;
- int writePos = 0;
- size_t bytesRead, totalRead = 0;
+ unsigned __int32 writePos = 0;
+ DWORD bytesRead, totalRead = 0;
int status = TRUE;
-
HANDLE src;
- FILETIME ftCreationTime;
- FILETIME ftLastWriteTime;
- FILETIME ftLastAccessTime;
-
- BOOL bTimeStampValid = FALSE;
+ BOOL bReadStatus = FALSE;
- /* Remember the last access time of the keyfile. It will be preserved in order to prevent
- an adversary from determining which file may have been used as keyfile. */
src = CreateFile (keyFile->FileName,
- GENERIC_READ | GENERIC_WRITE,
+ GENERIC_READ | FILE_WRITE_ATTRIBUTES,
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
if (src != INVALID_HANDLE_VALUE)
{
- if (GetFileTime ((HANDLE) src, &ftCreationTime, &ftLastAccessTime, &ftLastWriteTime))
- bTimeStampValid = TRUE;
- }
+ /* We tell Windows not to update the Last Access timestamp in order to prevent
+ an adversary from determining which file may have been used as keyfile. */
+ FILETIME ftLastAccessTime;
+ ftLastAccessTime.dwHighDateTime = 0xFFFFFFFF;
+ ftLastAccessTime.dwLowDateTime = 0xFFFFFFFF;
- finally_do_arg (HANDLE, src,
+ SetFileTime (src, NULL, &ftLastAccessTime, NULL);
+ }
+ else
{
- if (finally_arg != INVALID_HANDLE_VALUE)
- CloseHandle (finally_arg);
- });
-
- f = _wfopen (keyFile->FileName, L"rb");
- if (f == NULL) return FALSE;
+ /* try to open without FILE_WRITE_ATTRIBUTES in case we are in a ReadOnly filesystem (e.g. CD) */
+ src = CreateFile (keyFile->FileName,
+ GENERIC_READ,
+ FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
+ if (src == INVALID_HANDLE_VALUE)
+ return FALSE;
+ }
- while ((bytesRead = fread (buffer, 1, sizeof (buffer), f)) > 0)
+ while ((bReadStatus = ReadFile (src, buffer, sizeof (buffer), &bytesRead, NULL)) && (bytesRead > 0))
{
- size_t i;
-
- if (ferror (f))
- {
- status = FALSE;
- goto close;
- }
+ DWORD i;
for (i = 0; i < bytesRead; i++)
{
@@ -203,7 +195,7 @@ static BOOL KeyFileProcess (unsigned __int8 *keyPool, KeyFile *keyFile)
keyPool[writePos++] += (unsigned __int8) (crc >> 8);
keyPool[writePos++] += (unsigned __int8) crc;
- if (writePos >= KEYFILE_POOL_SIZE)
+ if (writePos >= keyPoolSize)
writePos = 0;
if (++totalRead >= KEYFILE_MAX_READ_LEN)
@@ -211,7 +203,7 @@ static BOOL KeyFileProcess (unsigned __int8 *keyPool, KeyFile *keyFile)
}
}
- if (ferror (f))
+ if (!bReadStatus)
{
status = FALSE;
}
@@ -223,13 +215,9 @@ static BOOL KeyFileProcess (unsigned __int8 *keyPool, KeyFile *keyFile)
close:
DWORD err = GetLastError();
- fclose (f);
- if (bTimeStampValid && !IsFileOnReadOnlyFilesystem (keyFile->FileName))
- {
- // Restore the keyfile timestamp
- SetFileTime (src, &ftCreationTime, &ftLastAccessTime, &ftLastWriteTime);
- }
+ CloseHandle (src);
+ burn (buffer, sizeof (buffer));
SetLastError (err);
return status;
@@ -248,6 +236,7 @@ BOOL KeyFilesApply (HWND hwndDlg, Password *password, KeyFile *firstKeyFile, con
wchar_t searchPath [TC_MAX_PATH*2];
struct _wfinddata_t fBuf;
intptr_t searchHandle;
+ unsigned __int32 keyPoolSize = password->Length <= MAX_LEGACY_PASSWORD? KEYFILE_POOL_LEGACY_SIZE : KEYFILE_POOL_SIZE;
HiddenFilesPresentInKeyfilePath = FALSE;
@@ -261,12 +250,12 @@ BOOL KeyFilesApply (HWND hwndDlg, Password *password, KeyFile *firstKeyFile, con
// Determine whether it's a security token path
try
{
- if (SecurityToken::IsKeyfilePathValid (kf->FileName))
+ if (Token::IsKeyfilePathValid (kf->FileName, EMVSupportEnabled? true : false))
{
// Apply security token keyfile
vector <byte> keyfileData;
- SecurityTokenKeyfilePath secPath (kf->FileName);
- SecurityToken::GetKeyfileData (SecurityTokenKeyfile (secPath), keyfileData);
+ TokenKeyfilePath secPath (kf->FileName);
+ Token::getTokenKeyfile (secPath)->GetKeyfileData (keyfileData);
if (keyfileData.empty())
{
@@ -278,7 +267,7 @@ BOOL KeyFilesApply (HWND hwndDlg, Password *password, KeyFile *firstKeyFile, con
}
unsigned __int32 crc = 0xffffffff;
- int writePos = 0;
+ unsigned __int32 writePos = 0;
size_t totalRead = 0;
for (size_t i = 0; i < keyfileData.size(); i++)
@@ -290,7 +279,7 @@ BOOL KeyFilesApply (HWND hwndDlg, Password *password, KeyFile *firstKeyFile, con
keyPool[writePos++] += (unsigned __int8) (crc >> 8);
keyPool[writePos++] += (unsigned __int8) crc;
- if (writePos >= KEYFILE_POOL_SIZE)
+ if (writePos >= keyPoolSize)
writePos = 0;
if (++totalRead >= KEYFILE_MAX_READ_LEN)
@@ -371,7 +360,7 @@ BOOL KeyFilesApply (HWND hwndDlg, Password *password, KeyFile *firstKeyFile, con
++keyfileCount;
// Apply keyfile to the pool
- if (!KeyFileProcess (keyPool, kfSub))
+ if (!KeyFileProcess (keyPool, keyPoolSize, kfSub))
{
handleWin32Error (hwndDlg, SRC_POS);
Error ("ERR_PROCESS_KEYFILE", hwndDlg);
@@ -390,7 +379,7 @@ BOOL KeyFilesApply (HWND hwndDlg, Password *password, KeyFile *firstKeyFile, con
}
}
// Apply keyfile to the pool
- else if (!KeyFileProcess (keyPool, kf))
+ else if (!KeyFileProcess (keyPool, keyPoolSize, kf))
{
handleWin32Error (hwndDlg, SRC_POS);
Error ("ERR_PROCESS_KEYFILE", hwndDlg);
@@ -400,7 +389,7 @@ BOOL KeyFilesApply (HWND hwndDlg, Password *password, KeyFile *firstKeyFile, con
/* Mix the keyfile pool contents into the password */
- for (i = 0; i < sizeof (keyPool); i++)
+ for (i = 0; i < keyPoolSize; i++)
{
if (i < password->Length)
password->Text[i] += keyPool[i];
@@ -408,8 +397,8 @@ BOOL KeyFilesApply (HWND hwndDlg, Password *password, KeyFile *firstKeyFile, con
password->Text[i] = keyPool[i];
}
- if (password->Length < (int)sizeof (keyPool))
- password->Length = sizeof (keyPool);
+ if (password->Length < keyPoolSize)
+ password->Length = keyPoolSize;
burn (keyPool, sizeof (keyPool));
@@ -495,9 +484,23 @@ BOOL CALLBACK KeyFilesDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lPa
SetWindowTextW(GetDlgItem(hwndDlg, IDT_KEYFILES_NOTE), GetString ("KEYFILES_NOTE"));
ToHyperlink (hwndDlg, IDC_LINK_KEYFILES_INFO);
+ ToHyperlink (hwndDlg, IDC_LINK_KEYFILES_EXTENSIONS_WARNING);
}
return 1;
+ case WM_CTLCOLORSTATIC:
+ {
+ if (((HWND)lParam == GetDlgItem(hwndDlg, IDT_KEYFILE_WARNING)) )
+ {
+ // we're about to draw the static
+ // set the text colour in (HDC)wParam
+ SetBkMode((HDC)wParam,TRANSPARENT);
+ SetTextColor((HDC)wParam, RGB(255,0,0));
+ return (BOOL)GetSysColorBrush(COLOR_MENU);
+ }
+ }
+ return 0;
+
case WM_COMMAND:
if (lw == IDC_KEYADD)
@@ -505,11 +508,15 @@ BOOL CALLBACK KeyFilesDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lPa
KeyFile *kf = (KeyFile *) malloc (sizeof (KeyFile));
if (kf)
{
- if (SelectMultipleFiles (hwndDlg, "SELECT_KEYFILE", kf->FileName, sizeof(kf->FileName),bHistory))
+ std::vector<std::wstring> filesList;
+ if (SelectMultipleFiles (hwndDlg, "SELECT_KEYFILE", bHistory, filesList))
{
bool containerFileSkipped = false;
- do
+ for (std::vector<std::wstring>::const_iterator it = filesList.begin();
+ it != filesList.end();
+ ++it)
{
+ StringCbCopyW (kf->FileName, sizeof (kf->FileName), it->c_str());
CorrectFileName (kf->FileName);
if (_wcsicmp (param->VolumeFileName, kf->FileName) == 0)
containerFileSkipped = true;
@@ -519,13 +526,13 @@ BOOL CALLBACK KeyFilesDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lPa
LoadKeyList (hwndDlg, param->FirstKeyFile);
kf = (KeyFile *) malloc (sizeof (KeyFile));
- if (!kf)
- {
- Warning ("ERR_MEM_ALLOC", hwndDlg);
- break;
- }
+ if (!kf)
+ {
+ Warning ("ERR_MEM_ALLOC", hwndDlg);
+ break;
+ }
}
- } while (SelectMultipleFilesNext (kf->FileName, sizeof(kf->FileName)));
+ }
if (containerFileSkipped)
{
@@ -544,7 +551,7 @@ BOOL CALLBACK KeyFilesDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lPa
KeyFile *kf = (KeyFile *) malloc (sizeof (KeyFile));
if (kf)
{
- if (BrowseDirectories (hwndDlg,"SELECT_KEYFILE_PATH", kf->FileName))
+ if (BrowseDirectories (hwndDlg,"SELECT_KEYFILE_PATH", kf->FileName, NULL))
{
param->FirstKeyFile = KeyFileAdd (param->FirstKeyFile, kf);
LoadKeyList (hwndDlg, param->FirstKeyFile);
@@ -563,10 +570,10 @@ BOOL CALLBACK KeyFilesDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lPa
if (lw == IDC_TOKEN_FILES_ADD)
{
- list <SecurityTokenKeyfilePath> selectedTokenKeyfiles;
+ list <TokenKeyfilePath> selectedTokenKeyfiles;
if (DialogBoxParamW (hInst, MAKEINTRESOURCEW (IDD_TOKEN_KEYFILES), hwndDlg, (DLGPROC) SecurityTokenKeyfileDlgProc, (LPARAM) &selectedTokenKeyfiles) == IDOK)
{
- foreach (const SecurityTokenKeyfilePath &keyPath, selectedTokenKeyfiles)
+ foreach (const TokenKeyfilePath &keyPath, selectedTokenKeyfiles)
{
KeyFile *kf = (KeyFile *) malloc (sizeof (KeyFile));
if (kf)
@@ -621,6 +628,12 @@ BOOL CALLBACK KeyFilesDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lPa
return 1;
}
+ if (lw == IDC_LINK_KEYFILES_EXTENSIONS_WARNING)
+ {
+ Applink ("keyfilesextensions");
+ return 1;
+ }
+
if (lw == IDOK)
{
param->EnableKeyFiles = IsButtonChecked (GetDlgItem (hwndDlg, IDC_KEYFILES_ENABLE));
@@ -722,10 +735,14 @@ BOOL KeyfilesPopupMenu (HWND hwndDlg, POINT popupPosition, KeyFilesDlgParam *par
KeyFile *kf = (KeyFile *) malloc (sizeof (KeyFile));
if (kf)
{
- if (SelectMultipleFiles (hwndDlg, "SELECT_KEYFILE", kf->FileName, sizeof(kf->FileName),bHistory))
+ std::vector<std::wstring> filesList;
+ if (SelectMultipleFiles (hwndDlg, "SELECT_KEYFILE", bHistory, filesList))
{
- do
+ for (std::vector<std::wstring>::const_iterator it = filesList.begin();
+ it != filesList.end();
+ ++it)
{
+ StringCbCopyW (kf->FileName, sizeof (kf->FileName), it->c_str());
param->FirstKeyFile = KeyFileAdd (param->FirstKeyFile, kf);
kf = (KeyFile *) malloc (sizeof (KeyFile));
if (!kf)
@@ -733,7 +750,7 @@ BOOL KeyfilesPopupMenu (HWND hwndDlg, POINT popupPosition, KeyFilesDlgParam *par
Warning ("ERR_MEM_ALLOC", hwndDlg);
break;
}
- } while (SelectMultipleFilesNext (kf->FileName, sizeof(kf->FileName)));
+ }
param->EnableKeyFiles = TRUE;
status = TRUE;
@@ -750,7 +767,7 @@ BOOL KeyfilesPopupMenu (HWND hwndDlg, POINT popupPosition, KeyFilesDlgParam *par
KeyFile *kf = (KeyFile *) malloc (sizeof (KeyFile));
if (kf)
{
- if (BrowseDirectories (hwndDlg,"SELECT_KEYFILE_PATH", kf->FileName))
+ if (BrowseDirectories (hwndDlg,"SELECT_KEYFILE_PATH", kf->FileName, NULL))
{
param->FirstKeyFile = KeyFileAdd (param->FirstKeyFile, kf);
param->EnableKeyFiles = TRUE;
@@ -770,10 +787,10 @@ BOOL KeyfilesPopupMenu (HWND hwndDlg, POINT popupPosition, KeyFilesDlgParam *par
case IDM_KEYFILES_POPUP_ADD_TOKEN_FILES:
{
- list <SecurityTokenKeyfilePath> selectedTokenKeyfiles;
+ list <TokenKeyfilePath> selectedTokenKeyfiles;
if (DialogBoxParamW (hInst, MAKEINTRESOURCEW (IDD_TOKEN_KEYFILES), hwndDlg, (DLGPROC) SecurityTokenKeyfileDlgProc, (LPARAM) &selectedTokenKeyfiles) == IDOK)
{
- foreach (const SecurityTokenKeyfilePath &keyPath, selectedTokenKeyfiles)
+ foreach (const TokenKeyfilePath &keyPath, selectedTokenKeyfiles)
{
KeyFile *kf = (KeyFile *) malloc (sizeof (KeyFile));
if (kf)