1
0
mirror of https://github.com/veracrypt/VeraCrypt.git synced 2025-11-12 03:18:26 -06:00

Windows: enhancements to the mechanism preserving file timestamps, especially for keyfiles.

This commit is contained in:
Mounir IDRASSI
2019-12-08 22:51:49 +01:00
parent 7f1e21e6a1
commit 5e96a5c44c
8 changed files with 139 additions and 79 deletions

View File

@@ -11238,10 +11238,8 @@ int OpenVolume (OpenVolumeContext *context, const wchar_t *volumePath, Password
else
StringCbCopyW (szCFDevice, sizeof(szCFDevice), szDiskFile);
if (preserveTimestamps)
write = TRUE;
context->HostFileHandle = CreateFile (szCFDevice, GENERIC_READ | (write ? GENERIC_WRITE : 0), FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
context->HostFileHandle = CreateFile (szCFDevice, GENERIC_READ | (write ? GENERIC_WRITE : (!context->IsDevice && preserveTimestamps? FILE_WRITE_ATTRIBUTES : 0)), FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
if (context->HostFileHandle == INVALID_HANDLE_VALUE)
{
@@ -11263,6 +11261,13 @@ int OpenVolume (OpenVolumeContext *context, const wchar_t *volumePath, Password
// Remember the container modification/creation date and time
if (!context->IsDevice && preserveTimestamps)
{
// ensure that Last Access and Last Write timestamps are not modified
FILETIME ftLastAccessTime;
ftLastAccessTime.dwHighDateTime = 0xFFFFFFFF;
ftLastAccessTime.dwLowDateTime = 0xFFFFFFFF;
SetFileTime (context->HostFileHandle, NULL, &ftLastAccessTime, NULL);
if (GetFileTime (context->HostFileHandle, &context->CreationTime, &context->LastAccessTime, &context->LastWriteTime) == 0)
context->TimestampsValid = FALSE;
else

View File

@@ -350,6 +350,19 @@ begin_format:
nStatus = ERR_OS_ERROR;
goto error;
}
else if (volParams->hiddenVol && bPreserveTimestamp)
{
// ensure that Last Access and Last Write timestamps are not modified
ftLastAccessTime.dwHighDateTime = 0xFFFFFFFF;
ftLastAccessTime.dwLowDateTime = 0xFFFFFFFF;
SetFileTime (dev, NULL, &ftLastAccessTime, NULL);
if (GetFileTime ((HANDLE) dev, &ftCreationTime, &ftLastAccessTime, &ftLastWriteTime) == 0)
bTimeStampValid = FALSE;
else
bTimeStampValid = TRUE;
}
DisableFileCompression (dev);
@@ -380,14 +393,6 @@ begin_format:
}
}
if (volParams->hiddenVol && !volParams->bDevice && bPreserveTimestamp)
{
if (GetFileTime ((HANDLE) dev, &ftCreationTime, &ftLastAccessTime, &ftLastWriteTime) == 0)
bTimeStampValid = FALSE;
else
bTimeStampValid = TRUE;
}
if (volParams->hwndDlg && volParams->bGuiMode) KillTimer (volParams->hwndDlg, TIMER_ID_RANDVIEW);
/* Volume header */

View File

@@ -149,50 +149,41 @@ void KeyFileCloneAll (KeyFile *firstKeyFile, KeyFile **outputKeyFile)
static BOOL KeyFileProcess (unsigned __int8 *keyPool, unsigned __int32 keyPoolSize, KeyFile *keyFile)
{
FILE *f;
unsigned __int8 buffer[64 * 1024];
unsigned __int32 crc = 0xffffffff;
unsigned __int32 writePos = 0;
size_t bytesRead, totalRead = 0;
DWORD bytesRead, totalRead = 0;
int status = TRUE;
HANDLE src;
FILETIME ftCreationTime;
FILETIME ftLastWriteTime;
FILETIME ftLastAccessTime;
BOOL bReadStatus = FALSE;
BOOL bTimeStampValid = 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;
SetFileTime (src, NULL, &ftLastAccessTime, NULL);
}
else
{
/* 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;
}
finally_do_arg (HANDLE, src,
while ((bReadStatus = ReadFile (src, buffer, sizeof (buffer), &bytesRead, NULL)) && (bytesRead > 0))
{
if (finally_arg != INVALID_HANDLE_VALUE)
CloseHandle (finally_arg);
});
f = _wfopen (keyFile->FileName, L"rb");
if (f == NULL) return FALSE;
while ((bytesRead = fread (buffer, 1, sizeof (buffer), f)) > 0)
{
size_t i;
if (ferror (f))
{
status = FALSE;
goto close;
}
DWORD i;
for (i = 0; i < bytesRead; i++)
{
@@ -211,7 +202,7 @@ static BOOL KeyFileProcess (unsigned __int8 *keyPool, unsigned __int32 keyPoolSi
}
}
if (ferror (f))
if (!bReadStatus)
{
status = FALSE;
}
@@ -223,13 +214,9 @@ static BOOL KeyFileProcess (unsigned __int8 *keyPool, unsigned __int32 keyPoolSi
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;

View File

@@ -224,6 +224,19 @@ int ChangePwd (const wchar_t *lpszVolume, Password *oldPassword, int old_pkcs5,
if (dev == INVALID_HANDLE_VALUE)
goto error;
else if (!bDevice && bPreserveTimestamp)
{
// ensure that Last Access and Last Write timestamps are not modified
ftLastAccessTime.dwHighDateTime = 0xFFFFFFFF;
ftLastAccessTime.dwLowDateTime = 0xFFFFFFFF;
SetFileTime (dev, NULL, &ftLastAccessTime, NULL);
if (GetFileTime ((HANDLE) dev, &ftCreationTime, &ftLastAccessTime, &ftLastWriteTime) == 0)
bTimeStampValid = FALSE;
else
bTimeStampValid = TRUE;
}
if (bDevice)
{
@@ -313,13 +326,6 @@ int ChangePwd (const wchar_t *lpszVolume, Password *oldPassword, int old_pkcs5,
SetRandomPoolEnrichedByUserStatus (FALSE); /* force the display of the random enriching dialog */
if (!bDevice && bPreserveTimestamp)
{
if (GetFileTime ((HANDLE) dev, &ftCreationTime, &ftLastAccessTime, &ftLastWriteTime) == 0)
bTimeStampValid = FALSE;
else
bTimeStampValid = TRUE;
}
for (volumeType = TC_VOLUME_TYPE_NORMAL; volumeType < TC_VOLUME_TYPE_COUNT; volumeType++)
{