keyfiles.c
来自「使用visual studio 2005 开发的开源文件、磁盘加密软件。这是6.」· C语言 代码 · 共 661 行 · 第 1/2 页
C
661 行
/*
Copyright (c) 2005 TrueCrypt Foundation. All rights reserved.
Governed by the TrueCrypt License 2.6 the full text of which is contained
in the file License.txt included in TrueCrypt binary and source code
distribution packages.
*/
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include "Tcdefs.h"
#include "Keyfiles.h"
#include "Crc.h"
#include <io.h>
#include "Dlgcode.h"
#include "Language.h"
#include "SecurityToken.h"
#include "Common/resource.h"
#include "Platform/ForEach.h"
using namespace TrueCrypt;
#define stat _stat
#define S_IFDIR _S_IFDIR
#define snprintf _snprintf
KeyFile *KeyFileAdd (KeyFile *firstKeyFile, KeyFile *keyFile)
{
KeyFile *kf = firstKeyFile;
if (firstKeyFile != NULL)
{
while (kf->Next)
kf = kf->Next;
kf->Next = keyFile;
}
else
firstKeyFile = keyFile;
keyFile->Next = NULL;
return firstKeyFile;
}
// Returns first keyfile, NULL if last keyfile was removed
static KeyFile *KeyFileRemove (KeyFile *firstKeyFile, KeyFile *keyFile)
{
KeyFile *prevkf = NULL, *kf = firstKeyFile;
if (firstKeyFile == NULL) return NULL;
do
{
if (kf == keyFile)
{
if (prevkf == NULL)
firstKeyFile = kf->Next;
else
prevkf->Next = kf->Next;
burn (keyFile, sizeof(*keyFile)); // wipe
free (keyFile);
break;
}
prevkf = kf;
}
while (kf = kf->Next);
return firstKeyFile;
}
void KeyFileRemoveAll (KeyFile **firstKeyFile)
{
KeyFile *kf = *firstKeyFile;
while (kf != NULL)
{
KeyFile *d = kf;
kf = kf->Next;
burn (d, sizeof(*d)); // wipe
free (d);
}
*firstKeyFile = NULL;
}
KeyFile *KeyFileClone (KeyFile *keyFile)
{
KeyFile *clone;
if (keyFile == NULL) return NULL;
clone = (KeyFile *) malloc (sizeof (KeyFile));
strcpy (clone->FileName, keyFile->FileName);
clone->Next = NULL;
return clone;
}
KeyFile *KeyFileCloneAll (KeyFile *firstKeyFile)
{
KeyFile *cloneFirstKeyFile = KeyFileClone (firstKeyFile);
KeyFile *kf;
if (firstKeyFile == NULL) return NULL;
kf = firstKeyFile->Next;
while (kf != NULL)
{
KeyFileAdd (cloneFirstKeyFile, KeyFileClone (kf));
kf = kf->Next;
}
return cloneFirstKeyFile;
}
static BOOL KeyFileProcess (unsigned __int8 *keyPool, KeyFile *keyFile)
{
FILE *f;
unsigned __int8 buffer[64 * 1024];
unsigned __int32 crc = 0xffffffff;
int writePos = 0;
size_t bytesRead, totalRead = 0;
int status = TRUE;
HANDLE src;
FILETIME ftCreationTime;
FILETIME ftLastWriteTime;
FILETIME ftLastAccessTime;
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,
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;
else
Warning ("GETFILETIME_FAILED_KEYFILE");
}
f = fopen (keyFile->FileName, "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;
}
for (i = 0; i < bytesRead; i++)
{
crc = UPDC32 (buffer[i], crc);
keyPool[writePos++] += (unsigned __int8) (crc >> 24);
keyPool[writePos++] += (unsigned __int8) (crc >> 16);
keyPool[writePos++] += (unsigned __int8) (crc >> 8);
keyPool[writePos++] += (unsigned __int8) crc;
if (writePos >= KEYFILE_POOL_SIZE)
writePos = 0;
if (++totalRead >= KEYFILE_MAX_READ_LEN)
goto close;
}
}
if (ferror (f))
{
status = FALSE;
}
else if (totalRead == 0)
{
status = FALSE;
SetLastError (ERROR_HANDLE_EOF);
}
close:
DWORD err = GetLastError();
fclose (f);
if (bTimeStampValid && !IsFileOnReadOnlyFilesystem (keyFile->FileName))
{
// Restore the keyfile timestamp
if (!SetFileTime (src, &ftCreationTime, &ftLastAccessTime, &ftLastWriteTime))
Warning ("SETFILETIME_FAILED_KEYFILE");
CloseHandle (src);
}
SetLastError (err);
return status;
}
BOOL KeyFilesApply (Password *password, KeyFile *firstKeyFile)
{
BOOL status = TRUE;
KeyFile kfSubStruct;
KeyFile *kf;
KeyFile *kfSub = &kfSubStruct;
static unsigned __int8 keyPool [KEYFILE_POOL_SIZE];
size_t i;
struct stat statStruct;
char searchPath [TC_MAX_PATH*2];
struct _finddata_t fBuf;
intptr_t searchHandle;
if (firstKeyFile == NULL) return TRUE;
VirtualLock (keyPool, sizeof (keyPool));
memset (keyPool, 0, sizeof (keyPool));
for (kf = firstKeyFile; kf != NULL; kf = kf->Next)
{
// Determine whether it's a security token path
try
{
if (SecurityToken::IsKeyfilePathValid (SingleStringToWide (kf->FileName)))
{
// Apply security token keyfile
vector <byte> keyfileData;
SecurityToken::GetKeyfileData (SecurityTokenKeyfile (SingleStringToWide (kf->FileName)), keyfileData);
if (keyfileData.empty())
{
SetLastError (ERROR_HANDLE_EOF);
handleWin32Error (MainDlg);
Error ("ERR_PROCESS_KEYFILE");
status = FALSE;
continue;
}
unsigned __int32 crc = 0xffffffff;
int writePos = 0;
size_t totalRead = 0;
for (size_t i = 0; i < keyfileData.size(); i++)
{
crc = UPDC32 (keyfileData[i], crc);
keyPool[writePos++] += (unsigned __int8) (crc >> 24);
keyPool[writePos++] += (unsigned __int8) (crc >> 16);
keyPool[writePos++] += (unsigned __int8) (crc >> 8);
keyPool[writePos++] += (unsigned __int8) crc;
if (writePos >= KEYFILE_POOL_SIZE)
writePos = 0;
if (++totalRead >= KEYFILE_MAX_READ_LEN)
break;
}
burn (&keyfileData.front(), keyfileData.size());
continue;
}
}
catch (Exception &e)
{
e.Show (NULL);
return FALSE;
}
// Determine whether it's a path or a file
if (stat (kf->FileName, &statStruct) != 0)
{
handleWin32Error (MainDlg);
Error ("ERR_PROCESS_KEYFILE");
status = FALSE;
continue;
}
if (statStruct.st_mode & S_IFDIR) // If it's a directory
{
/* Find and process all keyfiles in the directory */
snprintf (searchPath, sizeof (searchPath), "%s\\*.*", kf->FileName);
if ((searchHandle = _findfirst (searchPath, &fBuf)) == -1)
{
handleWin32Error (MainDlg);
Error ("ERR_PROCESS_KEYFILE_PATH");
status = FALSE;
continue;
}
do
{
snprintf (kfSub->FileName, sizeof(kfSub->FileName), "%s%c%s", kf->FileName,
'\\',
fBuf.name
);
// Determine whether it's a path or a file
if (stat (kfSub->FileName, &statStruct) != 0)
{
handleWin32Error (MainDlg);
Error ("ERR_PROCESS_KEYFILE");
status = FALSE;
continue;
}
else if (statStruct.st_mode & S_IFDIR) // If it's a directory
{
// Prevent recursive folder scanning
continue;
}
// Apply keyfile to the pool
if (!KeyFileProcess (keyPool, kfSub))
{
handleWin32Error (MainDlg);
Error ("ERR_PROCESS_KEYFILE");
status = FALSE;
}
} while (_findnext (searchHandle, &fBuf) != -1);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?