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

📄 pgpdisk.cpp

📁 vc环境下的pgp源码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
	}

	MessageBeep(MB_OK);

	return derr;
}

// ConvertPGPdisk attempts to re-encrypt a broken CAST PGPdisk using the
// correct implementation of CAST.

DualErr 
PGPdisk::ConvertPGPdisk(LPCSTR path, SecureString *passphrase)
{
	DualErr					derr;
	CASTKey					*newSessionKey;
	PGPBoolean				conversionRestarting, readHeader;
	PGPdiskCASTConvertInfo	CCI;
	PGPdiskFileHeader		*fileHeader;

	SecureMemory	smFileHeader(sizeof(PGPdiskFileHeader));
	SecureMemory	smNewSessionKey(sizeof(CASTKey));

	conversionRestarting = readHeader = FALSE;

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

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

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

	if (derr.IsntError())
	{
		// Set up secure pointers.
		fileHeader		= (PGPdiskFileHeader *) smFileHeader.GetPtr();
		newSessionKey	= (CASTKey *) smNewSessionKey.GetPtr();

		// Open the PGPdisk.
		derr = Open(path, kOF_MustExist);
	}

	// Read in main header.
	if (derr.IsntError())
	{
		derr = ReadPGPdiskFileMainHeader(this, &fileHeader);
		readHeader = derr.IsntError();
	}

	if (derr.IsntError())
	{
		// Are we restarting an already begun conversion?
		conversionRestarting = (fileHeader->majorVersion == 
			kPGPdiskConvertInProgressMajorVersion);

		if (conversionRestarting)
		{
			// Read CCI struct.
			derr = File::Read((PGPUInt8 *) &CCI, kOffsetToCCIStruct, 
				sizeof(CCI));

			// Verify the stored conversion information.
			if (derr.IsntError())
			{
				if (strncmp(CCI.convertInfoMagic, kPGPdiskBadCASTInfoMagic, 
					4) != 0)
				{
					derr = DualErr(kPGDMinorError_BadHeaderMagic);
				}
			}

			// Retrieve the new session key.
			if (derr.IsntError())
			{
				derr = DecryptPassphraseKey(GetPassphraseKeyPtr(fileHeader, 
					kMasterPassphraseIndex), &fileHeader->salt, passphrase, 
					newSessionKey);
			}
		}
		else
		{
			// Prepare the main header for conversion.
			fileHeader->majorVersion = 
				kPGPdiskConvertInProgressMajorVersion;

			// Clear alternate passphrases.
			pgpClearMemory(fileHeader->otherPassphrases, 
				sizeof(fileHeader->otherPassphrases));

			// Prepare conversion info structure.
			strncpy(CCI.convertInfoMagic, kPGPdiskBadCASTInfoMagic, 4);

			CCI.lastConvertedBlock = fileHeader->numHeaderBlocks - 1;
			CCI.oldSalt = fileHeader->salt;

			// Retrieve and save the old session key.
			derr = GetOldSessionKey(path, fileHeader, passphrase, 
				&CCI.oldSessionKey);

			// Put a new session key in the header.
			if (derr.IsntError())
			{	
				derr = InitHeaderWithNewSessionKey(fileHeader, 
					kCASTEncryptionAlgorithm, passphrase);
			}

			// Retrieve the new session key from the header.
			if (derr.IsntError())
			{
				derr = DecryptPassphraseKey(GetPassphraseKeyPtr(fileHeader, 
					kMasterPassphraseIndex), &fileHeader->salt, passphrase, 
					newSessionKey);
			}

			// Update main header.
			if (derr.IsntError())
			{
				derr = WritePGPdiskFileMainHeader(this, fileHeader);
			}

			if (derr.IsntError())
			{
				// Remove other headers (non-fatal).
				NukeAllNonADKHeaders(this, newSessionKey);

				// Write out CCI.
				derr = File::Write((PGPUInt8 *) &CCI, kOffsetToCCIStruct, 
					sizeof(CCI));
			}

			// Read in main header again.
			if (derr.IsntError())
			{
				FreePGPdiskFileHeader((PGPdiskFileHeaderInfo *) fileHeader);

				derr = ReadPGPdiskFileMainHeader(this, &fileHeader);
				readHeader = derr.IsntError();
			}
		}
	}

	// Convert all non-converted blocks.
	if (derr.IsntError())
	{		
		PGPUInt32 numBlocks;

		numBlocks = fileHeader->numDataBlocks - 
			(CCI.lastConvertedBlock - fileHeader->numHeaderBlocks + 1);

		derr = ConvertBlocks(fileHeader, &CCI, &CCI.oldSessionKey, 
			&CCI.oldSalt, newSessionKey, &fileHeader->salt, 
			CCI.lastConvertedBlock + 1, numBlocks);
	}

	// Mark the PGPdisk as finished with the conversion process.
	if (derr.IsntError())
	{
		fileHeader->majorVersion = kPGPdiskPrimaryHeaderMajorVersion;
		fileHeader->minorVersion = kPGPdiskPrimaryHeaderMinorVersion;

		fileHeader->algorithm = kCASTEncryptionAlgorithm;

		derr = WritePGPdiskFileMainHeader(this, fileHeader);
	}

	if (derr.IsntError())
	{
		MessageBeep(MB_OK);
	}

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

	if (Opened())
		Close();

	return derr;
}

// HighLevelFormatPGPdisk displays the format dialog. Failing that, it
// formats using our own algorithm.

DualErr 
PGPdisk::HighLevelFormatPGPdisk()
{
	DualErr derr;

	pgpAssert(Mounted());

	// Display the format dialog.
	derr = App->ShowWindowsFormatDialog(GetDrive());

	// If failed, warn user and format using our own algorithm if we can.
	if (derr.IsError())
	{
		ReportError(kPGDMajorError_WindowsFormatFailed, derr);
		derr = Format();

		// Set the volume label.
		if (derr.IsntError())
		{
			SetVolumeLabel(kPGPdiskDefaultVolLabel);
		}
	}

	return derr;
}

// SetProgressBarInfo is called to specify the window handle of a progress
// bar slider control to be used during disk creation, and also to specify
// a pointer to a shared boolean that will be polled to determine if the user
// has canceled the operation.

void 
PGPdisk::SetProgressBarInfo(HWND hWnd, PGPBoolean *pCancelFlag)
{
	pgpAssertAddrValid(pCancelFlag, PGPBoolean);

	mProgressBarHwnd = hWnd;
	mPCancelFlag = pCancelFlag;

	SetProgressBarRange(0, 100);
	SetProgressBarPos(0);
}


/////////////////////////////////////////
// Class PGPdisk private member functions
/////////////////////////////////////////

// HasUserCanceled checks the shared cancel variable to determine if the user
// has canceled the request.

PGPBoolean 
PGPdisk::HasUserCanceled()
{
	if (mProgressBarHwnd && mPCancelFlag)
	{
		pgpAssertAddrValid(mPCancelFlag, PGPBoolean);
		
		return (* mPCancelFlag);
	}
	else
	{
		return FALSE;
	}
}

// SetProgressBarPos sets the position of the disk creation progress bar.

void 
PGPdisk::SetProgressBarPos(PGPUInt32 nPos)
{
	if (mProgressBarHwnd)
		PostMessage(mProgressBarHwnd, PBM_SETPOS, nPos, 0);
}

// SetProgressBarRange sets the range of the disk creation progress bar.

void 
PGPdisk::SetProgressBarRange(PGPUInt32 nMin, PGPUInt32 nMax)
{
	if (mProgressBarHwnd)
	{
		PostMessage(mProgressBarHwnd, PBM_SETRANGE, 0, 
			MAKELPARAM(nMin, nMax));
	}
}

// IsNTFSPGPdisk checks if the PGPdisk is NTFS formatted.

PGPBoolean  
PGPdisk::IsPGPdiskNTFS(LPCSTR path, CipherContext *pContext)
{
	DualErr		derr;
	PGPBoolean	isNTFS = FALSE;
	PGPUInt8	*bootBlock;

	pgpAssertStrValid(path);
	pgpAssertAddrValid(pContext, CipherContext);

	try
	{
		bootBlock = new PGPUInt8[kDefaultBlockSize];

		// Open the PGPdisk.
		derr = Open(path, kOF_MustExist | kOF_ReadOnly);

		// Read on the boot block.
		if (derr.IsntError())
		{
			derr = File::Read(bootBlock, 
				kPGPdiskReservedHeaderBlocks*kDefaultBlockSize, 
				kDefaultBlockSize);
		}

		if (derr.IsntError())
		{
			// Decrypt it.
			pContext->CipherBlocks(0, 1, bootBlock, bootBlock, 
				kCipherOp_Decrypt);

			// Is it NTFS?
			isNTFS = (strncmp((LPCSTR) &bootBlock[3], "NTFS", 4) == 0);
		}

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

		delete[] bootBlock;
	}
	catch (CMemoryException *ex)
	{
		derr = DualErr(kPGDMinorError_OutOfMemory);
		ex->Delete();

		if (Opened())
			Close();
	}

	return isNTFS;
}

// InitHeaderWithNewSessionKey initializes the header with a new session
// key generated from the specified master passphrase and random data.

DualErr 
PGPdisk::InitHeaderWithNewSessionKey(
	PGPdiskFileHeader			*fileHeader, 
	PGPdiskEncryptionAlgorithm	algorithm, 
	SecureString				*passphrase)
{
	DualErr				derr;
	EncryptedCASTKey	*key;
	ExpandedCASTKey		*expandedKey;
	PGPUInt8			*secureBuf;
	PGPUInt32			i, index;

	SecureMemory	smKey(sizeof(EncryptedCASTKey));
	SecureMemory	smExpandedKey(sizeof(ExpandedCASTKey));
	SecureMemory	smSecureBuf(kMaxPassphraseLength);

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

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

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

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

	if (derr.IsntError())
	{
		// Initialize the pointers to our locked memory.
		key			= (EncryptedCASTKey *) smKey.GetPtr();
		expandedKey	= (ExpandedCASTKey *) smExpandedKey.GetPtr();
		secureBuf	= (PGPUInt8 *) smSecureBuf.GetPtr();

		// Initialize the salt with random data.
		PGPContextGetRandomBytes(GetGlobalPGPContext(), 
			fileHeader->salt.saltBytes, sizeof(fileHeader->salt));
		
		// Initialize the master passphrase with random data.
		PGPContextGetRandomBytes(GetGlobalPGPContext(), 
			fileHeader->masterPassphrase.encryptedKey.keyBytes, 
			sizeof(fileHeader->masterPassphrase.encryptedKey));
		
		// Hash, salt, and schedule the passphrase. Ask for the unexpanded
		// key since we will need it later.

		derr = HashSaltAndSchedule(passphrase, expandedKey, 
			&fileHeader->salt, &fileHeader->masterPassphrase.hashReps, key);
	}

	if (derr.IsntError())
	{
		// Encrypt the random key twice
		for (i = 0; i < 2; i++)
		{
			CAST5encrypt(
				&fileHeader->masterPassphrase.encryptedKey.keyBytes[0], 
				&fileHeader->masterPassphrase.encryptedKey.keyBytes[0], 
				expandedKey->keyDWords);

			CAST5encrypt(
				&fileHeader->masterPassphrase.encryptedKey.keyBytes[8],
				&fileHeader->masterPassphrase.encryptedKey.keyBytes[8],
				expandedKey->keyDWords);
		}

		// Encrypt the key itself for checkbytes purposes.
		CAST5encrypt(key->keyBytes, key->keyBytes, expandedKey->keyDWords);

		for (index = 0; 
			index < sizeof(fileHeader->masterPassphrase.checkBytes); 
			index++)
		{
			fileHeader->masterPassphrase.checkBytes.theBytes[index] = 
				key->keyBytes[index];
		}

		// Must mark as in use.
		fileHeader->masterPassphrase.inUse = TRUE;
	}

	return derr;
}

⌨️ 快捷键说明

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