⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 keyfiles.c

📁 使用visual studio 2005 开发的开源文件、磁盘加密软件。这是6.1a版。加密自己资料的好工具。也是学习的优秀范本。结成了众多加密算法。
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
 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 + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -