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

📄 pgpdisk.cpp

📁 vc环境下的pgp源码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
// InitPGPdiskFileHeader initializes a brand new PGPdisk file header.

DualErr 
PGPdisk::InitPGPdiskFileHeader(
	PGPdiskFileHeader			*fileHeader, 
	PGPUInt64					blocksDisk, 
	PGPdiskEncryptionAlgorithm	algorithm, 
	SecureString				*passphrase, 
	PGPUInt8					drive)
{
	DualErr derr;

	pgpAssertAddrValid(fileHeader, PGPdiskFileHeader);
	pgpAssertAddrValid(passphrase, SecureString);

	pgpAssert(algorithm != kInvalidEncryptionAlgorithm);

	pgpAssert(blocksDisk > 0);
	pgpAssert(blocksDisk < 0xFFFFFFFF);	// header doesn't do 64-bit yet

	// Initialize the default fields of the header.
	pgpClearMemory(fileHeader, sizeof(PGPdiskFileHeader));	

	strncpy(fileHeader->headerInfo.headerMagic, kPGPdiskHeaderMagic, 4);
	strncpy(fileHeader->headerInfo.headerType, kPGPdiskPrimaryHeaderType, 4);
	fileHeader->headerInfo.headerSize = sizeof(PGPdiskFileHeader);

	fileHeader->majorVersion	= kPGPdiskPrimaryHeaderMajorVersion;
	fileHeader->minorVersion	= kPGPdiskPrimaryHeaderMinorVersion;

	fileHeader->algorithm = algorithm;

	fileHeader->numHeaderBlocks	= kPGPdiskReservedHeaderBlocks;
	fileHeader->numDataBlocks	= (PGPUInt32) blocksDisk;

	fileHeader->numFileBlocks = kPGPdiskReservedHeaderBlocks + 
		fileHeader->numDataBlocks + kPGPdiskAlternateHeaderBlocks;

	fileHeader->drive			= drive;
	fileHeader->mountedFlag		= FALSE;
	fileHeader->uniqueSessionId	= kInvalidSessionId;

	// Initialize the header with a new session key.
	derr = InitHeaderWithNewSessionKey(fileHeader, algorithm, passphrase);

	if (derr.IsntError())
	{
		// Update the CRC.
		UpdatePGPdiskFileHeaderCRC((PGPdiskFileHeaderInfo *) fileHeader);
	}

	return derr;
}

// FirstTimeEncryptDiskFile wipes the non-FAT blocks and encrypts all of the
// non-header blocks in a new, open PGPdisk.

DualErr 
PGPdisk::FirstTimeEncryptDiskFile(
	PGPdiskFileHeader	*fileHeader, 
	SecureString		*passphrase)
{
	CASTKey			*decryptedKey;
	CipherContext	*pContext		= NULL;
	DualErr			derr;
	PGPBoolean		createdWriteBuffer	= FALSE;
	PGPUInt8		*dataBuf;
	PGPUInt32		blocksBuf;

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

	pgpAssert(Opened());
	pgpAssertAddrValid(fileHeader, PGPdiskFileHeader);
	pgpAssertAddrValid(passphrase, SecureString);

	// Make sure we got 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>
		
		// Decrypt the encrypted key.
		derr = DecryptPassphraseKey(&fileHeader->masterPassphrase, 
			&fileHeader->salt, passphrase, decryptedKey);
	}

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

		// Get the memory for our data buffer.
		derr = CreateReasonableWriteBuffer(fileHeader->numDataBlocks, 
			&dataBuf, &blocksBuf);

		createdWriteBuffer = derr.IsntError();
	}

	// Format the PGPdisk.
	if (derr.IsntError() && !HasUserCanceled())
	{
		PGPUInt32	blocksThisTime, endBlock, startBlock;
		PGPUInt32	totalWrites, writesDone, writesPerUpdate;

		// Calculate the starting and ending blocks.
		startBlock	= fileHeader->numHeaderBlocks;
		endBlock	= startBlock + fileHeader->numDataBlocks;

		// Calculate information used for progress bar updates.
		totalWrites = (PGPUInt32) 
			CeilDiv(endBlock - startBlock, blocksBuf);

		writesDone = 0;
		writesPerUpdate = (PGPUInt32) CeilDiv(totalWrites, 100);

		// Encrypt the PGPdisk.
		for (PGPUInt32 i = startBlock; i < endBlock; i += blocksBuf)
		{
			blocksThisTime = min(blocksBuf, endBlock - i);

			// Encrypt the blocks and output them.
			if (derr.IsntError())
			{
				pgpClearMemory(dataBuf, blocksThisTime*kDefaultBlockSize);

				pContext->CipherBlocks(i - fileHeader->numHeaderBlocks, 
					blocksThisTime, dataBuf, dataBuf, kCipherOp_Encrypt);

				derr = File::Write(dataBuf, i*kDefaultBlockSize, 
					blocksThisTime*kDefaultBlockSize);
			}

			// Update the progress dialog.
			if (derr.IsntError())
			{
				if (writesDone++ % writesPerUpdate == 0)
					SetProgressBarPos(writesDone*100/totalWrites);
			}

			if (derr.IsError() || HasUserCanceled())
			{
				break;
			}
		}
	}

	// If the user cancelled the creation, fail but don't be noisy.
	if (HasUserCanceled())
		derr = DualErr(kPGDMinorError_FailSilently);

	if (createdWriteBuffer)
		FreeByteBuffer(dataBuf);

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

	return derr;
}

// FirstTimeWriteHeaderDiskFile clears the reserved headers blocks and writes
// out the header to the specified PGPdisk.

DualErr 
PGPdisk::FirstTimeWriteHeaderDiskFile(PGPdiskFileHeader* fileHeader)
{
	DualErr		derr;
	PGPUInt8	blanks[kDefaultBlockSize];
	PGPUInt32	i;

	pgpAssertAddrValid(fileHeader, PGPdiskFileHeader);
	pgpAssert(Opened());

	pgpClearMemory(blanks, kDefaultBlockSize);

	// Clear the main header blocks.
	for (i = 0; i < fileHeader->numHeaderBlocks; i++)
	{
		derr = File::Write(blanks, i*kDefaultBlockSize, 
			kDefaultBlockSize);

		if (derr.IsError())
			break;
	}

	// Clear the alternate header blocks.
	if (derr.IsntError())
	{
		PGPUInt32 altStart;

		altStart = fileHeader->numHeaderBlocks + fileHeader->numDataBlocks;

		for (i=0; i<kPGPdiskAlternateHeaderBlocks; i++)
		{
			derr = File::Write(blanks, (altStart+i)*kDefaultBlockSize, 
				kDefaultBlockSize);

			if (derr.IsError())
				break;
		}
	}

	// Write out the header.
	if (derr.IsntError())
	{
		derr = WritePGPdiskFileMainHeader(this, fileHeader);
	}

	return derr;
}

// GetOldSessionKey extracts the old session key from a PGPdisk.

DualErr 
PGPdisk::GetOldSessionKey(
	LPCSTR				path, 
	PGPdiskFileHeader	*fileHeader, 
	SecureString		*passphrase, 
	CASTKey				*oldSessionKey)
{
	DualErr derr;

	pgpAssertStrValid(path);
	pgpAssertAddrValid(fileHeader, PGPdiskFileHeader);
	pgpAssertAddrValid(passphrase, SecureString);
	pgpAssertAddrValid(oldSessionKey, CASTKey);
	pgpAssert(Opened());

	// Must close file first.
	derr = Close();

	if (derr.IsntError())
	{
		if (ArePGPdiskPassesWiped(path))
		{
			PGPBoolean				gotPubKeyHdr	= FALSE;
			PGPdiskPublicKeyHeader	*pubKeyHdr;

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

			if (derr.IsntError())
			{
				// Get decrypted key.
				derr = GetDecryptedKeyUsingPublicKey(passphrase, pubKeyHdr, 
					oldSessionKey);
			}

			if (gotPubKeyHdr)
				FreePGPdiskFileHeader((PGPdiskFileHeaderInfo *) pubKeyHdr);
		}
		else
		{
			// Get old session key from master passphrase.
			derr = DecryptPassphraseKey(GetPassphraseKeyPtr(fileHeader, 
				kMasterPassphraseIndex), &fileHeader->salt, passphrase, 
				oldSessionKey);
		}
	}

	if (derr.IsntError())
	{
		derr = Open(path, kOF_MustExist);
	}

	return derr;
}

// ConvertBlocks converts the specified blocks in the PGPdisk to the new
// session key.

DualErr 
PGPdisk::ConvertBlocks(
	PGPdiskFileHeader		*fileHeader, 
	PGPdiskCASTConvertInfo	*pCCI, 
	const CASTKey			*oldSessionKey, 
	const PassphraseSalt	*oldSalt, 
	const CASTKey			*newSessionKey, 
	const PassphraseSalt	*newSalt, 
	PGPUInt32				startingBlock, 
	PGPUInt32				numBlocks)
{
	CipherContext	*pNewContext, *pOldContext;
	DualErr			derr;
	PGPBoolean		createdWriteBuffer	= FALSE;
	PGPUInt8		*dataBuf;

	SecureMemory	smNewContext(sizeof(CipherContext));
	SecureMemory	smOldContext(sizeof(CipherContext));

	pNewContext = pOldContext = NULL;

	pgpAssert(Opened());
	pgpAssertAddrValid(fileHeader, PGPdiskFileHeader);
	pgpAssertAddrValid(pCCI, PGPdiskCASTConvertInfo);
	pgpAssertAddrValid(oldSessionKey, CASTKey);
	pgpAssertAddrValid(newSessionKey, CASTKey);

	// Make sure we got our locked memory.
	derr = smNewContext.mInitErr;

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

	if (derr.IsntError())
	{
		// Initialize the pointers to our locked memory.
		pNewContext		= new (smNewContext.GetPtr()) CipherContext;
		pOldContext		= new (smOldContext.GetPtr()) CipherContext;

		// Initialize the cipher contexts.
		pNewContext->InitContext(kCASTEncryptionAlgorithm, 
			newSessionKey->keyBytes, newSalt->saltBytes);

		pOldContext->InitContext(kBrokenCASTEncryptionAlgorithm, 
			oldSessionKey->keyBytes, oldSalt->saltBytes);

		// Get the memory for our data buffer.
		derr = GetByteBuffer(kNumBlocksToConvertAtATime * kDefaultBlockSize, 
			&dataBuf);

		createdWriteBuffer = derr.IsntError();
	}

	// Convert the blocks.
	if (derr.IsntError() && !HasUserCanceled())
	{
		PGPUInt32	blocksBuf, blocksThisTime, endBlock, startBlock;
		PGPUInt32	totalWrites, writesDone, writesPerUpdate;

		blocksBuf = kNumBlocksToConvertAtATime;

		// Calculate the starting and ending blocks.
		startBlock	= startingBlock;
		endBlock	= startBlock + numBlocks;

		// Calculate information used for progress bar updates.
		totalWrites = (PGPUInt32) 
			CeilDiv(endBlock - startBlock, blocksBuf);

		writesDone = 0;
		writesPerUpdate = (PGPUInt32) CeilDiv(totalWrites, 100);

		// Encrypt the PGPdisk.
		for (PGPUInt32 i = startBlock; i < endBlock; i += blocksBuf)
		{
			blocksThisTime = min(blocksBuf, endBlock - i);

			// Read the blocks.
			derr = File::Read(dataBuf, i*kDefaultBlockSize, 
				blocksThisTime*kDefaultBlockSize);

			if (derr.IsntError())
			{
				// Decrypt the blocks.
				pOldContext->CipherBlocks(i - fileHeader->numHeaderBlocks, 
					blocksThisTime, dataBuf, dataBuf, kCipherOp_Decrypt);

				// Encrypt the blocks.
				pNewContext->CipherBlocks(i - fileHeader->numHeaderBlocks, 
					blocksThisTime, dataBuf, dataBuf, kCipherOp_Encrypt);

				// Write the blocks.
				derr = File::Write(dataBuf, i*kDefaultBlockSize, 
					blocksThisTime*kDefaultBlockSize);
			}

			// Write the updated block counter.
			if (derr.IsntError())
			{
				pCCI->lastConvertedBlock = i + blocksThisTime - 1;

				derr = File::Write((PGPUInt8 *) pCCI, kOffsetToCCIStruct, 
					sizeof(PGPdiskCASTConvertInfo));
			}

			// Update the progress dialog.
			if (derr.IsntError())
			{
				if (writesDone++ % writesPerUpdate == 0)
					SetProgressBarPos(writesDone*100/totalWrites);
			}

			if (derr.IsError() || HasUserCanceled())
			{
				break;
			}
		}
	}

	// If the user cancelled the creation, fail but don't be noisy.
	if (HasUserCanceled())
		derr = DualErr(kPGDMinorError_FailSilently);

	if (createdWriteBuffer)
		FreeByteBuffer(dataBuf);

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

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

	return derr;
}

⌨️ 快捷键说明

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