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

📄 pgpdisk.cpp

📁 vc环境下的pgp源码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
//////////////////////////////////////////////////////////////////////////////
// PGPdisk.cpp
//
// Class PGPdisk definition.
//////////////////////////////////////////////////////////////////////////////

// $Id: PGPdisk.cpp,v 1.9 1999/02/26 04:09:57 nryan Exp $

// Copyright (C) 1998 by Network Associates, Inc.
// All rights reserved.

#include "StdAfx.h"
#include <new.h>

#include "Required.h"

#include "pgpUtilities.h"

#include "CommonStrings.h"
#include "GlobalPGPContext.h"
#include "PGPdiskFileFormat.h"
#include "PGPdiskHighLevelUtils.h"
#include "PGPdiskLowLevelUtils.h"
#include "PGPdiskPublicKeyUtils.h"
#include "SecureMemory.h"
#include "UtilityFunctions.h"
#include "Win32Utils.h"

#include "CipherContext.h"
#include "SHA.h"

#include "Globals.h"
#include "PGPdisk.h"


////////////
// Constants
////////////

const PGPUInt32 kNumBlocksToConvertAtATime = 128;

const PGPUInt32 kOffsetToCCIStruct = kDefaultBlockSize - 
	sizeof(PGPdiskCASTConvertInfo);


////////////////////////////////////////
// Class PGPdisk public member functions
////////////////////////////////////////

// The (LPCSTR, PGPUInt8) overloaded constructor attaches a drive and a
// pathname for an already mounted PGPdisk.

PGPdisk::PGPdisk(LPCSTR path, PGPUInt8 drive, PGPUInt64 sessionId)
	 : VolFile(path, drive)
{
	mProgressBarHwnd	= NULL;
	mPCancelFlag		= NULL;

	mInitErr = VolFile::mInitErr;

	// Read the session ID.
	if (mInitErr.IsntError())
	{
		if (IsntNull(path))
		{
			pgpAssert(sessionId != kInvalidSessionId);
			mUniqueSessionId = sessionId;
		}
	}
}

// BestGuessComparePaths uses a number of methods to determine if the
// specified file is the same as the current mounted PGPdisk.

PGPBoolean 
PGPdisk::BestGuessComparePaths(LPCSTR path)
{
	File		testFile;
	CString		csPath, PGPdiskBareName, testBareName;
	DualErr		derr;
	PGPBoolean	failedTest	= FALSE;
	PGPUInt32	i, indexLastPGPdiskPathSlash, indexLastTestFilePathSlash;
	PGPUInt32	numPGPdiskPathElems, numTestFilePathElems;
	CString		diskPath;
	CString		checkPath;

	pgpAssert(Mounted());

	// First try the easy case.
	if (ComparePaths(path))
		return TRUE;

	// Convert paths to canonical form.
	if (VerifyAndCanonicalizePath(path, &csPath).IsError())
		csPath = path;

	// See if the number of path elements in each path is the same.
	numPGPdiskPathElems = 0;

	for (i=0; i<strlen(diskPath); i++)
	{
		if ((diskPath.GetAt(i) == '\\') ||
			(diskPath.GetAt(i) == '/'))
		{
			indexLastPGPdiskPathSlash = i;
			numPGPdiskPathElems++;
		}
	}

	numTestFilePathElems = 0;

	for (i=0; i<strlen(checkPath); i++)
	{
		if ((checkPath.GetAt(i) == '\\') ||
			(checkPath.GetAt(i) == '/'))
		{
			indexLastTestFilePathSlash = i;
			numTestFilePathElems++;
		}
	}

	if (numPGPdiskPathElems != numTestFilePathElems)
		failedTest = TRUE;

	// Compare the file names.
	if (_stricmp(diskPath.Mid(indexLastPGPdiskPathSlash + 1), 
		checkPath.Mid(indexLastTestFilePathSlash + 1)) != 0)
	{
		failedTest = TRUE;
	}

	// Check if the test file is in use (which must be the case with any
	// mounted PGPdisk.

	if (derr.IsntError() && !failedTest)
	{
		if (!App->IsFileInUse(checkPath))
			failedTest = TRUE;
	}

	// Finally return false if there was an error.
	if (derr.IsError())
	{
		failedTest = TRUE;
	}

	return !failedTest;
}

// GetUniqueSessionId returns the unique session ID for the PGPdisk.

PGPUInt64 
PGPdisk::GetUniqueSessionId()
{
	pgpAssert(Mounted());

	return mUniqueSessionId;
}

// ReadInUniqueSessionId reads in the unique session ID from the PGPdisk.

void 
PGPdisk::ReadInUniqueSessionId(LPCSTR path)
{
	mUniqueSessionId = GetPGPdiskUniqueSessionId(path);
}

// MakeUniqueSessionId makes a unique session ID for the PGPdisk.

DualErr 
PGPdisk::MakeUniqueSessionId(LPCSTR path)
{
	FILETIME	fileTime;
	PGPUInt64	tenthMsSince1601;

	GetSystemTimeAsFileTime(&fileTime);

	tenthMsSince1601 = MakeQWord(fileTime.dwLowDateTime, 
		fileTime.dwHighDateTime);

	return SetPGPdiskUniqueSessionId(path, tenthMsSince1601);
}

// Mount asks the driver to mount the PGPdisk specified by 'path' with the
// specified password.

DualErr 
PGPdisk::Mount(
	LPCSTR			path, 
	SecureString	*passphrase, 
	PGPUInt8		drive, 
	PGPBoolean		mountReadOnly)
{
	AD_Mount			MNT;
	CASTKey				*decryptedKey;
	CipherContext		*pContext			= NULL;
	DualErr				derr;
	const PassphraseKey *userInfo;
	PGPBoolean			readOnlyDueToADK	= FALSE;
	PGPBoolean			readHeader			= FALSE;
	PGPdiskFileHeader	*fileHeader;
	PGPUInt16			index;

	SecureMemory	smDecryptedKey(sizeof(CASTKey));
	SecureMemory	smContext(sizeof(CipherContext));

	pgpAssertStrValid(path);
	pgpAssertAddrValid(passphrase, SecureString);

	pgpAssert(Unmounted());
	pgpAssert(!Opened());
	
	// Did we get our locked memory?
	derr = smDecryptedKey.mInitErr;

	if (derr.IsntError())
	{
		derr = smContext.mInitErr;
	}

	if (derr.IsntError())
	{
		// Initialize the pointers to our locked memory.
		decryptedKey	= (CASTKey *) smDecryptedKey.GetPtr();
		pContext		= new (smContext.GetPtr()) CipherContext;	// <new.h>

		// Set and get the session ID and the drive letter preference.
		if (!mountReadOnly)
		{
			MakeUniqueSessionId(path);
			SetDriveLetterPref(path, drive);
		}

		ReadInUniqueSessionId(path);
	}

	// Read the header.
	if (derr.IsntError())
	{
		derr = ReadPGPdiskFileMainHeader(path, &fileHeader);
		readHeader = derr.IsntError();
	}

	if (derr.IsntError())
	{
		// Look for corresponding normal passphrase key.
		derr = FindMatchingPassphrase(fileHeader, passphrase, &index);

		if (derr.IsntError())
		{
			// Get a pointer to the passphrase info.
			userInfo = GetPassphraseKeyPtr(fileHeader, index);

			// Force read-only if the key is read-only.
			if (userInfo->readOnly)
				mountReadOnly = TRUE;

			// Decrypt the encrypted key.
			derr = DecryptPassphraseKey(userInfo, &fileHeader->salt, 
				passphrase, decryptedKey);
		}
		else
		{
			PGPBoolean				gotPubKeyHdr	= FALSE;
			PGPdiskPublicKeyHeader	*pubKeyHdr;

			// Look for corresponding public key header.
			derr = FindPublicPGPdiskKeyHeader(path, passphrase, &pubKeyHdr);
			gotPubKeyHdr = derr.IsntError();

			if (derr.IsntError())
			{
				// Force read-only if the key is read-only.
				if (pubKeyHdr->readOnly)
				{
					if (!mountReadOnly)
						readOnlyDueToADK = TRUE;

					mountReadOnly = TRUE;
				}

				// Get decrypted key.
				derr = GetDecryptedKeyUsingPublicKey(passphrase, pubKeyHdr, 
					decryptedKey);
			}

			if (gotPubKeyHdr)
				FreePGPdiskFileHeader((PGPdiskFileHeaderInfo *) pubKeyHdr);
		}
	}

	if (derr.IsntError())
	{
		// Initialize the cipher context.
		pContext->InitContext(fileHeader->algorithm, decryptedKey->keyBytes, 
			fileHeader->salt.saltBytes);

		// If NTFS perform checks.
		if (IsPGPdiskNTFS(path, pContext))
		{
			if (IsWin95CompatibleMachine())
			{
				derr = DualErr(kPGDMinorError_TriedNTFSOnWin95);
			}
			else if (mountReadOnly)
			{
				if (readOnlyDueToADK)
					mountReadOnly = FALSE;
				else
					derr = DualErr(kPGDMinorError_TriedReadOnlyNTFS);
			}
		}
	}

	if (derr.IsntError())
	{
		// Prepare the mount request packet; base classes will do the rest.
		MNT.pContext = pContext;

		// Call the request down.
		derr = VolFile::Mount(path, drive, mountReadOnly, &MNT);
	}

	if (readHeader)
		FreePGPdiskFileHeader((PGPdiskFileHeaderInfo *) fileHeader);

	if (IsntNull(pContext))
		pContext->~CipherContext();

	return derr;
}

// Unmount asks the driver to unmount us.

DualErr 
PGPdisk::Unmount(PGPBoolean isThisEmergency)
{
	DualErr derr;

	pgpAssert(Mounted());

	// Call the request down.
	derr = VolFile::Unmount(isThisEmergency);

	return derr;
}

// CreatePGPdisk creates a new PGPdisk at the location specified by 'path'
// and with the desired free space specified in 'blocksData'.

DualErr 
PGPdisk::CreatePGPdisk(
	LPCSTR						path, 
	PGPUInt64					blocksDisk, 
	PGPdiskEncryptionAlgorithm	algorithm, 
	SecureString				*passphrase, 
	PGPUInt8					drive)
{
	DualErr				derr;
	PGPdiskFileHeader	*fileHeader;
	SecureMemory		smFileHeader(sizeof(PGPdiskFileHeader));

	pgpAssertAddrValid(passphrase, SecureString);
	pgpAssertStrValid(path);

	pgpAssert(algorithm != kInvalidEncryptionAlgorithm);
	pgpAssert(blocksDisk > 0);

	// Did we get our locked memory?
	derr = smFileHeader.mInitErr;

	if (derr.IsntError())
	{
		// Get a pointer to the locked memory.
		fileHeader = (PGPdiskFileHeader *) smFileHeader.GetPtr();

		// Create the file.
		DeleteFile(path);
		derr = Open(path, kOF_Trunc);
	}

	// Set its length.
	if (derr.IsntError())
	{
		PGPUInt64 blocksLength;

		blocksLength = kPGPdiskReservedHeaderBlocks + blocksDisk + 
			kPGPdiskAlternateHeaderBlocks;

		derr = SetLength(blocksLength*kDefaultBlockSize);
	}

	if (derr.IsntError())
	{
		// Initialize the PGPdisk file header.
		InitPGPdiskFileHeader(fileHeader, blocksDisk, algorithm, passphrase, 
			drive);
	}

	// Encrypt the disk.
	if (derr.IsntError())
	{
		derr = FirstTimeEncryptDiskFile(fileHeader, passphrase);
	}

	// Write the header out to the PGPdisk file. Need to do this
	if (derr.IsntError())
	{
		derr = FirstTimeWriteHeaderDiskFile(fileHeader);
	}

	// Close the file.
	if (Opened())
		Close();

	// Cleanup in case of error.
	if (derr.IsError())
	{
		DeleteFile(path);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -