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

📄 cpgpdiskheaders.cpp

📁 PGP8.0源码 请认真阅读您的文件包然后写出其具体功能
💻 CPP
📖 第 1 页 / 共 3 页
字号:
	pgpAssert(HeadersRead());
	pgpAssert(!IsBeingReEncrypted());
	pgpAssert(diskFile.IsOpened());
	pgpAssertStrValid(adminPassphrase);

	// Get set of users on disk.
	CPGPdiskUserSet	userSet;
	ExportUserSet(userSet);

	// Find current admin user and copy it.
	CPGPdiskUserIter	userIter(&userSet);
	CPGPdiskUser		oldAdmin(*userIter.FindAdminUser());

	// Create new session user and salt from random data.
	CCipherContext	newCipher(newAlgorithm);
	GenerateNewKeyAndSalt(newCipher);

	Crypto::PassphraseSalt	newSalt;
	newCipher.GetSalt(newSalt);

	// Convert all users to the new session key.
	userIter.Rewind();

	while (TRUE)
	{
		CPGPdiskUser	*pUser	= userIter.Next();

		if (IsNull(pUser))
			break;

		PGPBoolean	removeUser	= FALSE;

		if (pUser->IsAdminUser())
		{
			// New admin gets converted whether symmetric or not.
			pUser->ChangeCipher(newCipher, adminPassphrase);
		}
		else if (pUser->HasSymmetricKey())
		{
			// Non-admin symmetrics are hopeless, no passphrase.
			removeUser = TRUE;
		}
		else
		{
			// We have a non-admin public key user, attempt a conversion.
			try
			{
				pUser->ChangeCipher(newCipher, adminPassphrase);
			}
			catch (CComboError&)
			{
				if (pUser->IsLocked())
					THROW_PGPERROR(kPGPClientError_DiskReEncryptWithBadADK);

				removeUser = TRUE;
			}
		}

		if (removeUser)
			userSet.Remove(*pUser);
	}

	// Import the converted keys.
	ImportUserSet(userSet);

	// Re-create old admin user header.
	auto_ptr<CPGPdiskUserHeader>	pOldAdmin(
		new CPGPdiskUserHeader(Context()));

	pOldAdmin->Create(oldAdmin);
	pOldAdmin->SetIsNotExported(TRUE);

	// Create new main header.
	auto_ptr<CPGPdiskMainHeader>	pNewMain(
		new CPGPdiskMainHeader(Context()));

	pNewMain->Create(MainHeader()->NumHeaderBlocks(), 
		MainHeader()->NumDataBlocks(), newAlgorithm, newSalt, 
		MainHeader()->DefaultRoot());

	// Add old admin user header and new main header.
	mHeaders.InsertAfter(MainHeader(), pOldAdmin.release());
	mHeaders.AddHead(pNewMain.release());

	// Mark disk as being reencrypted.
	MainHeader()->SetIsBeingReEncrypted(TRUE);

	WriteHeaders(diskFile);
	diskFile.Flush();
}

void 
CPGPdiskHeaders::GetReEncryptionInfo(
	const char		*adminPassphrase, 
	CCipherContext&	oldCipher, 
	CCipherContext&	newCipher, 
	PGPUInt64&		numBlocksReEncrypted) const
{
	pgpAssert(HeadersRead());
	pgpAssert(IsBeingReEncrypted());
	pgpAssertStrValid(adminPassphrase);
	pgpAssert(!oldCipher.IsInitialized());
	pgpAssert(!newCipher.IsInitialized());

	CPGPdiskMainHeader	*pOldMain	= reinterpret_cast<CPGPdiskMainHeader *>(
		mHeaders.Next(MainHeader()));
	CPGPdiskUserHeader	*pOldAdmin	= reinterpret_cast<CPGPdiskUserHeader *>(
		mHeaders.Next(pOldMain));

	// Get old admin user.
	CPGPdiskUser	oldAdminUser(Context());
	pOldAdmin->GetUser(oldAdminUser);

	// Get old cipher context.
	// This is just conventional and the zero ok. -wjb
	oldAdminUser.EnableCiphering(adminPassphrase, 0, pOldMain->Algorithm(), 
		pOldMain->Salt());
	oldAdminUser.GetCipherContext(oldCipher);

	// Get new admin user.
	CPGPdiskUserSet	userSet;
	ExportUserSet(userSet);

	CPGPdiskUserIter	userIter(&userSet);
	CPGPdiskUser		*pNewAdminUser	= userIter.FindAdminUser();

	pgpAssertAddrValid(pNewAdminUser, CPGPdiskUser);

	// Get new cipher context.
	// This is just conventional and the zero ok. -wjb
	pNewAdminUser->EnableCiphering(adminPassphrase, 0,
		MainHeader()->Algorithm(), MainHeader()->Salt());
	pNewAdminUser->GetCipherContext(newCipher);

	// Get next block to reencrypt.
	numBlocksReEncrypted = MainHeader()->NumBlocksReEncrypted();
}

void 
CPGPdiskHeaders::WriteReEncryptionProgress(
	CFile&		diskFile, 
	PGPUInt64	numBlocksReEncrypted)
{
	pgpAssert(HeadersRead());
	pgpAssert(IsBeingReEncrypted());
	pgpAssert(diskFile.IsOpened());

	MainHeader()->NumBlocksReEncrypted() = numBlocksReEncrypted;

	WriteHeaders(diskFile);
	diskFile.Flush();
}

void 
CPGPdiskHeaders::FinishReEncryption(CFile& diskFile)
{
	pgpAssert(HeadersRead());
	pgpAssert(IsBeingReEncrypted());
	pgpAssert(diskFile.IsOpened());

	// Remove old main and admin user headers.
	CPGPdiskMainHeader	*pOldMain	= reinterpret_cast<CPGPdiskMainHeader *>(
		mHeaders.Next(MainHeader()));
	CPGPdiskUserHeader	*pOldAdmin	= reinterpret_cast<CPGPdiskUserHeader *>(
		mHeaders.Next(pOldMain));

	mHeaders.Remove(pOldMain);
	mHeaders.Remove(pOldAdmin);

	delete pOldMain;
	delete pOldAdmin;

	// Update new main header.
	MainHeader()->SetIsBeingReEncrypted(FALSE);

	WriteHeaders(diskFile);
	diskFile.Flush();
}

void 
CPGPdiskHeaders::ReadHeaders(
	const CPGPdiskContext	*pContext, 
	const CFile&			diskFile)
{
	pgpAssertAddrValid(pContext, CPGPdiskContext);
	pgpAssert(diskFile.IsOpened());

	mPContext = pContext;
	ClearHeaders();

	// Read in main header.
	auto_ptr<CPGPdiskMainHeader>	pMainHeader(
		new CPGPdiskMainHeader(pContext));

	pMainHeader->ReadAtOffset(diskFile, 0);
	mHeaders.AddTail(pMainHeader.release());

	// If this is an older PGPdisk, create symmetric user headers from main.
	if (pMainHeader->IsOldHeaderAvailable())
		CreateHeadersFromOldMainHeader(pMainHeader->GetOldHeader());

	// Read in the remaining PGPdisk headers.
	try
	{
		PGPUInt64	curOffset	= MainHeader()->NextHeaderOffset();

		while (curOffset != 0)
		{
			CPGPdiskHeader	genericHeader(pContext);

			// Read in current header.
			genericHeader.ReadAtOffset(diskFile, curOffset);

			// Generate and add header object of appropriate type.
			CopyAndAddTypedHeader(&genericHeader);

			// Determine offset of next header.
			curOffset = genericHeader.NextHeaderOffset();
		}
	}
	catch (CComboError&) { }

	mHeadersRead = TRUE;
}

void 
CPGPdiskHeaders::WriteHeaders(CFile& diskFile)
{
	pgpAssert(HeadersRead());
	pgpAssert(diskFile.IsOpened());

	PGPUInt64	blockAfterData	= MainHeader()->NumHeaderBlocks() + 
		 MainHeader()->NumDataBlocks();
	PGPUInt64	byteAfterData	= blockAfterData * kPGPdiskBlockSize;

	// Set file size to max we will need BEFORE beginning the writes. Headers
	// after the first go at the END of the file.

	CPGPdiskHeader	*pHeader	= mHeaders.Next(MainHeader());
	PGPUInt32		blocksTail	= 0;

	while (IsntNull(pHeader))
	{
		blocksTail += UMath::CeilDiv<PGPUInt32>(pHeader->HeaderSize(), 
			kPGPdiskBlockSize);
		pHeader = mHeaders.Next(pHeader);
	}

	diskFile.SetLength(byteAfterData + blocksTail * kPGPdiskBlockSize);

	// Update file size in main header.
	MainHeader()->NumFileBlocks() = MainHeader()->NumHeaderBlocks() + 
		MainHeader()->NumDataBlocks() + blocksTail;

	// Wipe reserved header blocks.
	CArray<PGPUInt8>	blanks(kPGPdiskBlockSize);
	blanks.Wipe();

	for (PGPUInt32 i = 0; i <  MainHeader()->NumHeaderBlocks(); i++)
	{
		diskFile.Write(blanks.Get(), i * kPGPdiskBlockSize, 
			kPGPdiskBlockSize);
	}

	// Calculate new offsets and write out all headers.
	MainHeader()->NextHeaderOffset() = byteAfterData;
	MainHeader()->WriteAtOffset(diskFile, 0);

	pHeader = mHeaders.Next(MainHeader());

	while (IsntNull(pHeader))
	{
		PGPUInt64	offset		= mHeaders.Prev(pHeader)->NextHeaderOffset();
		PGPUInt64	nextOffset	= offset + UMath::RoundUpToMultiple<
			PGPUInt32>(pHeader->HeaderSize(), kPGPdiskBlockSize);
			
		if (IsNull(mHeaders.Next(pHeader)))
			pHeader->NextHeaderOffset() = 0;
		else
			pHeader->NextHeaderOffset() = nextOffset;

		pHeader->WriteAtOffset(diskFile, offset);
		pHeader = mHeaders.Next(pHeader);
	}
}

void 
CPGPdiskHeaders::ClearHeaders()
{
	mHeaders.EmptyWithDelete();
	mHeadersRead = FALSE;
}

void 
CPGPdiskHeaders::CreateHeaders(
	const CPGPdiskContext		*pContext, 
	const CFile&				diskFile, 
	PGPUInt64					blocksDisk, 
	PGPdiskEncryptionAlgorithm	algorithm, 
	const char					*adminPassphrase, 
	const char					*userName, 
	const char					*defaultRoot, 
	CCipherContext&				cipher)
{
	ClearHeaders();

	CreateHeadersCommon(pContext, diskFile, blocksDisk, algorithm, 
		adminPassphrase, userName, NULL, defaultRoot, cipher);
}

void 
CPGPdiskHeaders::CreateHeaders(
	const CPGPdiskContext		*pContext, 
	const CFile&				diskFile, 
	PGPUInt64					blocksDisk, 
	PGPdiskEncryptionAlgorithm	algorithm, 
	const CPGPKey&				pubKey, 
	const char					*defaultRoot, 
	CCipherContext&				cipher)
{
	ClearHeaders();

	CreateHeadersCommon(pContext, diskFile, blocksDisk, algorithm, NULL, 
		NULL, &pubKey, defaultRoot, cipher);
}

void 
CPGPdiskHeaders::NukeAllUserHeaders()
{
	CPGPdiskHeader	*pHeader	= MainHeader();

	while (IsntNull(pHeader))
	{
		CPGPdiskHeader	*pNextHeader	= mHeaders.Next(pHeader);

		if (pHeader->IsUserType())
		{
			mHeaders.Remove(pHeader);
			delete pHeader;
		}

		pHeader = pNextHeader;
	}
}

void 
CPGPdiskHeaders::CopyAndAddTypedHeader(const CPGPdiskHeader *pHeader)
{
	pgpAssertAddrValid(pHeader, CPGPdiskHeader);

	// Allocate new header object according to type.
	auto_ptr<CPGPdiskHeader>	pNewHeader;

	if (pHeader->IsMainType())
	{
		pNewHeader = auto_ptr<CPGPdiskHeader>(
			new CPGPdiskMainHeader(Context()));
	}
	else if ((pHeader->IsUserType() || pHeader->IsOldPubKeyType()))
	{
		pNewHeader = auto_ptr<CPGPdiskHeader>(
			new CPGPdiskUserHeader(Context()));
	}
	else
	{
		THROW_PGPERROR(kPGPClientError_CorruptDiskHeader);
	}

	pNewHeader->Assign(pHeader);

	// Add the new header to the header list.
	mHeaders.AddTail(pNewHeader.release());
}

void 
CPGPdiskHeaders::CreateHeadersFromOldMainHeader(
	const PGPdiskOldFormat::MainHeader	*pOldHeader)
{
	pgpAssertAddrValid(pOldHeader, PGPdiskOldFormat::MainHeader);

	// For each passphrase, add a new user header.
	for (PGPUInt32 i = 0; 
		i <= PGPdiskOldFormat::MainHeader::kMaxAlternatePassphrases;
		i++)
	{
		const PGPdiskOldCrypto::PassphraseKeyInfo	*pUserInfo	= 
			&pOldHeader->passphrases[i];

		if (pUserInfo->inUse)
		{
			auto_ptr<CPGPdiskUserHeader>	pNewHeader(
				new CPGPdiskUserHeader(Context()));

			PGPBoolean	isAdmin	= (i == 0);
			pNewHeader->CreateFromOldKeyInfo(pUserInfo, isAdmin);

			mHeaders.AddTail(pNewHeader.release());
		}
	}
}

void 
CPGPdiskHeaders::GenerateNewKeyAndSalt(CCipherContext& cipher) const
{
	pgpAssert(cipher.IsInitialized());

	CPGPGlobalRandomPool	randomPool(Context()->PGPContext());
	CSecureArray<PGPUInt8>	keyData(cipher.GetNeededRandomDataSize());
	CSecureArray<PGPUInt8>	mungeData(cipher.GetNeededRandomDataSize());
	Crypto::PassphraseSalt	salt;

	randomPool.GetRandomBytes(keyData.Get(), keyData.Size());
	randomPool.GetRandomBytes(salt.bytes, sizeof(salt.bytes));
	randomPool.GetRandomBytes(mungeData.Get(), mungeData.Size());

	cipher.GenerateNewSymmetricKey(keyData.Get(), mungeData.Get(), 
		keyData.Size(), salt);
}

void 
CPGPdiskHeaders::CreateHeadersCommon(
	const CPGPdiskContext		*pContext, 
	const CFile&				diskFile, 
	PGPUInt64					blocksDisk, 
	PGPdiskEncryptionAlgorithm	algorithm, 
	const char					*adminPass, 
	const char					*userName, 
	const CPGPKey				*pPubKey, 
	const char					*defaultRoot, 
	CCipherContext&				cipher)
{
	pgpAssertAddrValid(pContext, CPGPdiskContext);
	pgpAssert(diskFile.IsOpened());
	pgpAssertStrValid(defaultRoot);

	mPContext = pContext;

	// Create new session user and salt from random data.
	if (!cipher.IsInitialized())
		cipher.Init(algorithm);

	Crypto::PassphraseSalt	salt;

	GenerateNewKeyAndSalt(cipher);
	cipher.GetSalt(salt);

	// Create main header.
	auto_ptr<CPGPdiskMainHeader>	pMainHeader(
		new CPGPdiskMainHeader(Context()));

	pMainHeader->Create(OnDiskHeaderInfo::kReservedHeaderBlocks, blocksDisk, 
		algorithm, salt, defaultRoot);

	// Create admin user header.
	CPGPdiskUser	user(Context());

	if (IsntNull(pPubKey))
		user.Create(cipher, *pPubKey);
	else
		user.Create(cipher, userName, adminPass);

	user.SetIsAdminUser(TRUE);

	auto_ptr<CPGPdiskUserHeader>	pAdminUserHeader(
		new CPGPdiskUserHeader(Context()));

	pAdminUserHeader->Create(user);

	// Add the headers to the disk
	mHeaders.AddHead(pAdminUserHeader.release());
	mHeaders.AddHead(pMainHeader.release());

	if(PGPclEnterprise())
	{
		// Create ADK header if we must.
		if (Context()->IsTherePGPdiskADK())
		{
			CPGPKey	adkKey;
			Context()->GetPGPdiskADKPubKey(adkKey);

			user.Create(cipher, adkKey, FALSE, TRUE);

			auto_ptr<CPGPdiskUserHeader>	pADKeyHeader(
				new CPGPdiskUserHeader(Context()));

			pADKeyHeader->Create(user);
			mHeaders.AddTail(pADKeyHeader.release());
		}
	}

	mHeadersRead = TRUE;
}

⌨️ 快捷键说明

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