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

📄 cpgpdiskheaders.cpp

📁 PGP8.0源码 请认真阅读您的文件包然后写出其具体功能
💻 CPP
📖 第 1 页 / 共 3 页
字号:

// Class CPGPdiskMainHeader member functions

CPGPdiskMainHeader::CPGPdiskMainHeader(const CPGPdiskContext *pContext) : 
	CPGPdiskHeader(pContext), mIsOldHeaderAvailable(FALSE), mOldHeader(NULL)
{
}

CPGPdiskMainHeader::~CPGPdiskMainHeader()
{
	if (IsOldHeaderAvailable())
	{
		delete mOldHeader;
		mOldHeader = NULL;
	}
}

void 
CPGPdiskMainHeader::Create(
	PGPUInt64						headerBlocks, 
	PGPUInt64						dataBlocks, 
	PGPdiskEncryptionAlgorithm		algorithm, 
	const Crypto::PassphraseSalt&	salt, 
	const char *					defaultRoot)
{
	CommonCreate(headerBlocks, dataBlocks, algorithm, salt, defaultRoot);
}

void 
CPGPdiskMainHeader::ConvertOldVersion()
{
	if (MajorVersion() >= OnDiskMainHeader::kPreSubKeyMajorVersion)
		return;

	// Store old header for retrieval by re-encrypters.
	if (IsOldHeaderAvailable())
	{
		delete mOldHeader;
		mOldHeader = NULL;
	}

	mOldHeader = new PGPdiskOldFormat::MainHeader;
	mIsOldHeaderAvailable = TRUE;

	pgpCopyMemory(mHeaderBytes.Get(), mOldHeader, 
		sizeof(PGPdiskOldFormat::MainHeader));

	// Fill in new header structure.
	Crypto::PassphraseSalt	salt;
	pgpClearMemory(&salt.bytes, sizeof(salt.bytes));

	pgpCopyMemory(mOldHeader->salt.bytes, salt.bytes, 
		sizeof(mOldHeader->salt.bytes));

	CString	root;
	root.Format("%c:\\", UString::NumberToLetter(mOldHeader->drive));

	CommonCreate(mOldHeader->numHeaderBlocks, mOldHeader->numDataBlocks, 
		mOldHeader->algorithm, salt, root);

	NextHeaderOffset() = mOldHeader->headerInfo.nextHeaderOffset;
}

void 
CPGPdiskMainHeader::CanonicalizeHeader()
{
	CPGPdiskHeader::CanonicalizeHeader();

	if (!IsMainType())
		THROW_PGPERROR(kPGPClientError_CorruptDiskHeader);

	OnDiskMainHeader	*pHeader	= GetAsMainHeader();

	if (MajorVersion() < OnDiskMainHeader::kCompatMajorVersion)
		THROW_PGPERROR(kPGPClientError_DiskTooOld);

	if (MajorVersion() < OnDiskMainHeader::kMajorVersion)
		ConvertOldVersion();

	if (MajorVersion() > OnDiskMainHeader::kMajorVersion)
		THROW_PGPERROR(kPGPClientError_DiskTooNew);

	if (NumDataBlocks() > NumFileBlocks())
		THROW_PGPERROR(kPGPClientError_CorruptDiskHeader);

	if (NumHeaderBlocks() + NumDataBlocks() > NumFileBlocks())
		THROW_PGPERROR(kPGPClientError_CorruptDiskHeader);
}

void 
CPGPdiskMainHeader::CommonCreate(
	PGPUInt64						headerBlocks, 
	PGPUInt64						dataBlocks, 
	PGPdiskEncryptionAlgorithm		algorithm, 
	const Crypto::PassphraseSalt&	salt, 
	const char						*defaultRoot)
{
	pgpAssertStrValid(defaultRoot);

	// Allocate header.
	mHeaderBytes.Resize(sizeof(OnDiskMainHeader));
	mHeaderBytes.Wipe();

	// Initialize fields.
	HeaderMagic()	= OnDiskHeaderInfo::kHeaderMagic;
	HeaderType()	= OnDiskHeaderInfo::kMainType;
	HeaderSize()	= sizeof(OnDiskMainHeader);

	MajorVersion() = OnDiskMainHeader::kMajorVersion;
	MinorVersion() = OnDiskMainHeader::kMinorVersion;

	Algorithm() = algorithm;

	NumHeaderBlocks()	= headerBlocks;
	NumDataBlocks()		= dataBlocks;
	NumFileBlocks()		= headerBlocks + dataBlocks;

	Salt() = salt;
	SetDefaultRoot(defaultRoot);
}


// Class CPGPdiskUserHeader member functions

CPGPdiskUserHeader::CPGPdiskUserHeader(const CPGPdiskContext *pContext) : 
	CPGPdiskHeader(pContext)
{
}

void 
CPGPdiskUserHeader::GetUser(CPGPdiskUser& user)
{
	user.Import(mHeaderBytes.Get() + ExportedUserOffset(), 
		ExportedUserSize());
}

void 
CPGPdiskUserHeader::Create(const CPGPdiskUser& user)
{
	pgpAssert(user.IsAssigned());

	// Expand header large enough to hold user.
	PGPUInt32	onDiskSize	= sizeof(OnDiskUserHeader) + 
		user.GetSizeForExport();

	mHeaderBytes.Resize(onDiskSize);
	mHeaderBytes.Wipe();

	// Initialize fields.
	HeaderMagic()	= OnDiskHeaderInfo::kHeaderMagic;
	HeaderType()	= OnDiskHeaderInfo::kUserType;
	HeaderSize()	= onDiskSize;

	// Get exported user.
	ExportedUserOffset() = sizeof(OnDiskUserHeader);
	ExportedUserSize() = user.GetSizeForExport();

	user.Export(mHeaderBytes.Get() + ExportedUserOffset(), 
		user.GetSizeForExport());
}

void 
CPGPdiskUserHeader::CreateFromOldKeyInfo(
	const PGPdiskOldCrypto::PassphraseKeyInfo	*pOldKeyInfo,  
	PGPBoolean									isAdmin)
{
	pgpAssertAddrValid(pOldKeyInfo, PGPdiskOldCrypto::PassphraseKeyInfo);

	// Re-encrypt crypto.
	Crypto::PassphraseKeyInfo	keyInfo;
	pgpClearMemory(&keyInfo, sizeof(keyInfo));

	pgpCopyMemory(pOldKeyInfo->encryptedKey.bytes, 
		keyInfo.encryptedKey.bytes, sizeof(pOldKeyInfo->encryptedKey));

	pgpCopyMemory(pOldKeyInfo->checkBytes.bytes, 
		keyInfo.checkBytes.bytes, sizeof(pOldKeyInfo->checkBytes));

	keyInfo.hashReps = pOldKeyInfo->hashReps;

	CPGPdiskUser	user(Context());

	user.ImportRawSymmetricKey(keyInfo, UCommonStrings::Get(
		UCommonStrings::kUnknownUserString), pOldKeyInfo->readOnly);

	if (isAdmin)
		user.SetIsAdminUser(TRUE);

	// Punt to Create();
	Create(user);
}

void 
CPGPdiskUserHeader::ConvertFromOldPubKeyHeader()
{
	PGPdiskOldFormat::PublicKeyHeader	*pOldHeader	= 
		reinterpret_cast<PGPdiskOldFormat::PublicKeyHeader *>(
		mHeaderBytes.Get());

	const PGPByte	*pExportedKeyID	= mHeaderBytes.Get() + 
		pOldHeader->keyIDOffset;
	const PGPByte	*pEncryptedKey	= mHeaderBytes.Get() + 
		pOldHeader->encryptedKeyOffset;

	Crypto::CheckBytes	checkBytes;
	pgpClearMemory(&checkBytes.bytes, sizeof(checkBytes.bytes));

	pgpCopyMemory(pOldHeader->checkBytes.bytes, checkBytes.bytes, 
		sizeof(pOldHeader->checkBytes.bytes));

	CPGPdiskUser	user(Context());

	user.ImportRawPublicKey(pExportedKeyID, pOldHeader->keyIDSize, 
		pEncryptedKey, pOldHeader->encryptedKeySize, checkBytes, 
		pOldHeader->algorithm, pOldHeader->readOnly, pOldHeader->locked);

	// Punt to Create();
	Create(user);
}

void 
CPGPdiskUserHeader::CanonicalizeHeader()
{
	CPGPdiskHeader::CanonicalizeHeader();

	if (IsOldPubKeyType())
		ConvertFromOldPubKeyHeader();

	if (!IsUserType())
		THROW_PGPERROR(kPGPClientError_CorruptDiskHeader);

	if (ExportedUserOffset() + ExportedUserSize() > HeaderSize())
		THROW_PGPERROR(kPGPClientError_CorruptDiskHeader);
}


// Class CPGPdiskHeaders member functions

CPGPdiskHeaders::~CPGPdiskHeaders()
{
	ClearHeaders();
}

PGPBoolean 
CPGPdiskHeaders::HasOldHeaders() const
{
	pgpAssert(HeadersRead());
	return MainHeader()->IsOldHeaderAvailable();
}

PGPUInt64 
CPGPdiskHeaders::NumFileBlocks() const
{
	pgpAssert(HeadersRead());
	return MainHeader()->NumFileBlocks();
}

PGPUInt64 
CPGPdiskHeaders::NumHeaderBlocks() const
{
	pgpAssert(HeadersRead());
	return MainHeader()->NumHeaderBlocks();
}

PGPUInt64 
CPGPdiskHeaders::NumDataBlocks() const
{
	pgpAssert(HeadersRead());
	return MainHeader()->NumDataBlocks();
}

PGPdiskEncryptionAlgorithm 
CPGPdiskHeaders::Algorithm() const
{
	pgpAssert(HeadersRead());
	return MainHeader()->Algorithm();
}

PGPBoolean 
CPGPdiskHeaders::IsBeingReEncrypted() const
{
	pgpAssert(HeadersRead());
	return MainHeader()->GetIsBeingReEncrypted();
}

PGPBoolean 
CPGPdiskHeaders::AreUsersWiped() const
{
	pgpAssert(HeadersRead());
	return MainHeader()->GetIsWiped();
}

PGPBoolean 
CPGPdiskHeaders::UsesCustomTimeout() const
{
	// Could happen if the network cable is unplugged--headers couldn't be read
	// This was reported to happen when PGPdisk is mounted from a network
	// drive, PGPkeys is opened to change passphrase, and then network is
	// disconnected before closing PGPkeys. 
	if(!HeadersRead())
	{
		return FALSE;
	}

	pgpAssert(HeadersRead());

	return MainHeader()->GetUsesCustomTimeout();
}

const char * 
CPGPdiskHeaders::DefaultRoot() const
{
	pgpAssert(HeadersRead());
	return MainHeader()->DefaultRoot();
}

PGPUInt32 
CPGPdiskHeaders::CustomTimeout() const
{
	pgpAssert(HeadersRead());
	return MainHeader()->CustomTimeout();
}

PGPUInt64 
CPGPdiskHeaders::BlocksDisk() const
{
	pgpAssert(HeadersRead());
	return MainHeader()->NumDataBlocks();
}

void 
CPGPdiskHeaders::SetUsesCustomTimeout(PGPBoolean usesCustom)
{
	pgpAssert(HeadersRead());
	MainHeader()->SetUsesCustomTimeout(usesCustom);
}

void 
CPGPdiskHeaders::SetCustomTimeout(PGPUInt32 customTimeout)
{
	pgpAssert(HeadersRead());
	MainHeader()->CustomTimeout() = customTimeout;
}

void 
CPGPdiskHeaders::SetDefaultRoot(const char * root)
{
	pgpAssert(HeadersRead());
	MainHeader()->SetDefaultRoot(root);
}

void 
CPGPdiskHeaders::ExportUserSet(CPGPdiskUserSet& userSet) const
{
	CPGPdiskHeader	*pHeader	= MainHeader();
	userSet.Empty();

	while (IsntNull(pHeader))
	{
		if (pHeader->IsUserType())
		{
			CPGPdiskUserHeader	*pUserHeader	= 
				reinterpret_cast<CPGPdiskUserHeader *>(pHeader);

			if (!pUserHeader->GetIsNotExported())
			{
				CPGPdiskUser	user(Context());
				pUserHeader->GetUser(user);

				userSet.Add(user);
			}
		}

		pHeader = mHeaders.Next(pHeader);
	}
}

void 
CPGPdiskHeaders::ImportUserSet(const CPGPdiskUserSet& userSet)
{
	CPGPdiskUser		*pUser;
	CPGPdiskUserIter	userIter(&userSet);

	if (userSet.Count() == 0)
		THROW_PGPERROR(kPGPError_BadParams);

	NukeAllUserHeaders();

	// First pass: ensure only one user is the admin.
	PGPBoolean	sawAdmin	= FALSE;

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

		if (IsNull(pUser))
			break;

		if (pUser->IsAdminUser())
		{
			if (sawAdmin)
				pUser->SetIsAdminUser(FALSE);

			sawAdmin = TRUE;
		}
	}

	userIter.Rewind();

	// Second pass: create user headers.
	while (TRUE)
	{
		pUser = userIter.Next();

		if (IsNull(pUser))
			break;

		// If no admin was seen on first pass, first user becomes admin.
		if (!sawAdmin)
		{
			pUser->SetIsAdminUser(TRUE);
			sawAdmin = TRUE;
		}

		// Create and add new user header.
		auto_ptr<CPGPdiskUserHeader>	pUserHeader(
			new CPGPdiskUserHeader(Context()));

		pUserHeader->Create(*pUser);
		mHeaders.AddTail(pUserHeader.release());
	}
}

void 
CPGPdiskHeaders::EnableCipheringOnUser(
	CPGPdiskUser&	user, 
	const char		*passphrase,
	int				passkeylen)
{
	pgpAssert(HeadersRead());
	pgpAssert(user.IsAssigned());

	user.EnableCiphering(passphrase, passkeylen, Algorithm(), MainHeader()->Salt());
}

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

	// Remove all symmetric user headers.
	CPGPdiskUserSet	userSet, usersToRemove;
	ExportUserSet(userSet);

	CPGPdiskUserIter	userIter(&userSet);
	CPGPdiskUser		*pUser;
	PGPBoolean			sawPubKey	= FALSE;

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

		if (IsNull(pUser))
			break;

		if (pUser->HasPublicKey())
			sawPubKey = TRUE;

		if (pUser->HasSymmetricKey())
			usersToRemove.Add(*pUser);
	}

	// Only proceed if at least one public key was seen.
	if (!sawPubKey)
		THROW_PGPERROR(kPGPClientError_NeedPubKeyToWipeDisk);

	// Remove and update users.
	userSet.Remove(usersToRemove);
	ImportUserSet(userSet);

	// Mark disk as wiped.
	MainHeader()->SetIsWiped(TRUE);

	// Make sure we write out now and flush.
	WriteHeaders(diskFile);
	diskFile.Flush();
}

void 
CPGPdiskHeaders::BeginReEncryption(
	CFile&						diskFile, 
	const char					*adminPassphrase, 
	PGPdiskEncryptionAlgorithm	newAlgorithm)
{

⌨️ 快捷键说明

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