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

📄 cpgpdiskheaders.cpp

📁 PGP8.0源码 请认真阅读您的文件包然后写出其具体功能
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/*____________________________________________________________________________
		Copyright (C) 2002 PGP Corporation
        All rights reserved.

        $Id: CPGPdiskHeaders.cpp,v 1.20 2002/11/21 18:42:55 wjb Exp $
____________________________________________________________________________*/

#include "pgpClassesConfig.h"
#include "pgpBuild.h"

#include "CArray.h"
#include "CFile.h"
#include "CString.h"
#include "UMath.h"
#include "UString.h"

#include "pgpClientErrors.h"

#include "CCipherContext.h"
#include "CCRC32.h"
#include "UCommonStrings.h"

#include "CPGPGlobalRandomPool.h"
#include "CPGPKey.h"

#include "CPGPdiskContext.h"
#include "CPGPdiskHeaders.h"
#include "CPGPdiskUser.h"
#include "CPGPdiskUserSet.h"
#include "PGPdiskOldFormat.h"

_USING_PGP

_UNNAMED_BEGIN

// Types

// Align to 1.
#if PGP_WIN32
#pragma pack(push, 1)
#endif

struct OnDiskHeaderInfo
{
	enum
	{
		kReservedHeaderBlocks	= 4, 
		kMaxBlocksHeader		= 128		// arbitrary
	};

#if defined(_M_IX86)
	enum 
	{
		kHeaderMagic	= 'dPGP',	// backwards since little-endian

		kMainType		= 'NIAM', 
		kUserType		= 'RESU', 
		kOldPubKeyType	= 'YEKP', 
	};
#endif	// _M_IX86

	PGPUInt32	headerMagic;	// Always OnDiskHeaderInfo::kHeaderMagic
	PGPUInt32	headerType;		// One of the HeaderType enums
	PGPUInt32	headerSize;		// Total size of this header, in bytes

	PGPUInt32	headerCRC;			// CRC of this header
	PGPUInt64	nextHeaderOffset;	// Offset to next header from file start
									// 0 = no additional headers
	PGPUInt32	reserved[2];
};

struct OnDiskMainHeader
{
	enum
	{
		kMajorVersion		= 6, 
		kMinorVersion		= 0, 

		kCompatMajorVersion		= 1, 
		kPreSubKeyMajorVersion	= 5, 
		kMaxSizeRoot			= 256, 
	};

	OnDiskHeaderInfo	hdrInfo;

	PGPUInt8	majorVersion;
	PGPUInt8	minorVersion;
	PGPUInt16	reserved;

	PGPUInt64	numFileBlocks;			// Size of the file, in blocks
	PGPUInt64	numHeaderBlocks;		// Size of leading header data
	PGPUInt64	numDataBlocks;			// Size of encrypted data

	PGPdiskEncryptionAlgorithm	algorithm;
	Crypto::PassphraseSalt		salt;

	PGPUInt32	isBeingReEncrypted 	: 1;	// is disk being reencrypted?
	PGPUInt32	isWiped				: 1;	// users wiped?
	PGPUInt32	usesCustomTimeout	: 1;	// custom timeout?
	PGPUInt32	unused				: 29;

	PGPUInt32	customTimeout;				// custom unmount timeout
	PGPUInt64	numBlocksReEncrypted;		// number of blocks reencrypted

	char		defaultRoot[kMaxSizeRoot];	// Preferred mount point
};

struct OnDiskUserHeader
{
	OnDiskHeaderInfo	hdrInfo;

	PGPUInt32	notExported		: 1;
	PGPUInt32	unused			: 31;

	PGPUInt32	exportedUserOffset;
	PGPUInt32	exportedUserSize;

	PGPUInt32	reserved[4];

	// Exported PGPdisk user structure goes here...
};

// Restore alignment.
#if PGP_WIN32
#pragma pack(pop)
#endif

_UNNAMED_END

_PGP_BEGIN

// Class CPGPdiskHeader

class CPGPdiskHeader : public CListableObject<CPGPdiskHeader>
{
	NOT_COPYABLE(CPGPdiskHeader);

public:
	CPGPdiskHeader(const CPGPdiskContext *pContext);
	virtual ~CPGPdiskHeader() { }

	const CPGPdiskContext *	Context() const {return mPContext;}

	OnDiskHeaderInfo *	GetAsHeaderInfo() const 
	{
		return reinterpret_cast<OnDiskHeaderInfo *>(mHeaderBytes.Get());
	}
	
	PGPUInt32&	HeaderMagic() const 
	{
		return GetAsHeaderInfo()->headerMagic;
	}

	PGPUInt32&	HeaderType() const 
	{
		return GetAsHeaderInfo()->headerType;
	}

	PGPUInt32&	HeaderSize() const 
	{
		return GetAsHeaderInfo()->headerSize;
	}

	PGPUInt32&	HeaderCRC() const 
	{
		return GetAsHeaderInfo()->headerCRC;
	}

	PGPUInt64&	NextHeaderOffset() const 
	{
		return GetAsHeaderInfo()->nextHeaderOffset;
	}

	PGPBoolean	IsMainType() const
	{
		return (HeaderType() == OnDiskHeaderInfo::kMainType);
	}

	PGPBoolean	IsUserType() const
	{
		return (HeaderType() == OnDiskHeaderInfo::kUserType);
	}

	PGPBoolean	IsOldPubKeyType() const
	{
		return (HeaderType() == OnDiskHeaderInfo::kOldPubKeyType);
	}

	void		UpdateCRC() 
	{
		HeaderCRC() = ComputeCRC();
	}

	virtual void	ReadAtOffset(const CFile& diskFile, PGPUInt64 offset);
	virtual void	WriteAtOffset(CFile& diskFile, PGPUInt64 offset);

	virtual void	Assign(const CPGPdiskHeader *pHeader);

protected:
	const CPGPdiskContext	*mPContext;
	CArray<PGPByte>			mHeaderBytes;

	PGPUInt32		ComputeCRC();

	void			ValidateHeaderSize();
	virtual void	CanonicalizeHeader();
};


// Class CPGPdiskMainHeader

class CPGPdiskMainHeader : public CPGPdiskHeader
{
public:
	CPGPdiskMainHeader(const CPGPdiskContext *pContext);
	~CPGPdiskMainHeader();

	OnDiskMainHeader *	GetAsMainHeader() const
	{
		return reinterpret_cast<OnDiskMainHeader *>(mHeaderBytes.Get());
	}

	PGPBoolean	IsOldHeaderAvailable() const
	{
		return mIsOldHeaderAvailable;
	}

	const PGPdiskOldFormat::MainHeader *	GetOldHeader() const
	{
		return mOldHeader;
	}

	PGPUInt8&	MajorVersion() const 
	{
		return GetAsMainHeader()->majorVersion;
	}

	PGPUInt8&	MinorVersion() const 
	{
		return GetAsMainHeader()->minorVersion;
	}

	PGPUInt64&	NumFileBlocks() const 
	{
		return GetAsMainHeader()->numFileBlocks;
	}

	PGPUInt64&	NumHeaderBlocks() const 
	{
		return GetAsMainHeader()->numHeaderBlocks;
	}

	PGPUInt64&	NumDataBlocks() const 
	{
		return GetAsMainHeader()->numDataBlocks;
	}

	PGPdiskEncryptionAlgorithm&	Algorithm() const
	{
		return GetAsMainHeader()->algorithm;
	}

	Crypto::PassphraseSalt&		Salt() const
	{
		return GetAsMainHeader()->salt;
	}

	PGPBoolean	GetIsBeingReEncrypted() const 
	{
		return GetAsMainHeader()->isBeingReEncrypted;
	}

	PGPBoolean	GetIsWiped() const 
	{
		return GetAsMainHeader()->isWiped;
	}

	PGPBoolean	GetUsesCustomTimeout() const 
	{
		return GetAsMainHeader()->usesCustomTimeout;
	}
	
	const char *	DefaultRoot() const 
	{
		return GetAsMainHeader()->defaultRoot;
	}

	PGPUInt32&	CustomTimeout() const 
	{
		return GetAsMainHeader()->customTimeout;
	}

	PGPUInt64&	NumBlocksReEncrypted() const 
	{
		return GetAsMainHeader()->numBlocksReEncrypted;
	}

	void	SetIsBeingReEncrypted(PGPBoolean isBeingReEncrypted) 
	{
		GetAsMainHeader()->isBeingReEncrypted = isBeingReEncrypted;
	}

	void	SetIsWiped(PGPBoolean isWiped) 
	{
		GetAsMainHeader()->isWiped = isWiped;
	}

	void	SetUsesCustomTimeout(PGPBoolean usesCustom) const 
	{
		GetAsMainHeader()->usesCustomTimeout = usesCustom;
	}

	void	SetDefaultRoot(const char *defaultRoot)
	{
		pgpAssertStrValid(defaultRoot);

		UString::SmartStringCopy(GetAsMainHeader()->defaultRoot, 
			defaultRoot, OnDiskMainHeader::kMaxSizeRoot);
	}

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

private:
	PGPBoolean						mIsOldHeaderAvailable;
	PGPdiskOldFormat::MainHeader	*mOldHeader;

	void	ConvertOldVersion();
	void	CanonicalizeHeader();

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


// Class CPGPdiskUserHeader

class CPGPdiskUserHeader : public CPGPdiskHeader
{
public:
	CPGPdiskUserHeader(const CPGPdiskContext *pContext);
	~CPGPdiskUserHeader() { }

	OnDiskUserHeader *	GetAsUserHeader() const
	{
		return reinterpret_cast<OnDiskUserHeader *>(mHeaderBytes.Get());
	}

	PGPUInt32&	ExportedUserOffset() const
	{
		return GetAsUserHeader()->exportedUserOffset;
	}

	PGPUInt32&	ExportedUserSize() const
	{
		return GetAsUserHeader()->exportedUserSize;
	}

	PGPBoolean	GetIsNotExported() const 
	{
		return GetAsUserHeader()->notExported;
	}

	void	SetIsNotExported(PGPBoolean isNotExported) 
	{
		GetAsUserHeader()->notExported = isNotExported;
	}
	
	void	GetUser(CPGPdiskUser& user);

	void	Create(const CPGPdiskUser& user);
	void	CreateFromOldKeyInfo(
		const PGPdiskOldCrypto::PassphraseKeyInfo *pOldKeyInfo, 
		PGPBoolean isAdmin = FALSE);

private:
	void	ConvertFromOldPubKeyHeader();
	void	CanonicalizeHeader();
};

_PGP_END

// Class CPGPdiskHeader member functions

CPGPdiskHeader::CPGPdiskHeader(const CPGPdiskContext *pContext) : 
	mPContext(pContext)
{
	  pgpAssertAddrValid(pContext, CPGPdiskContext);
}

void 
CPGPdiskHeader::ReadAtOffset(const CFile& diskFile, PGPUInt64 offset)
{
	pgpAssert(diskFile.IsOpened());

	// Read in at least one block.
	pgpAssert(sizeof(OnDiskHeaderInfo) <= kPGPdiskBlockSize);

	mHeaderBytes.Resize(kPGPdiskBlockSize);
	diskFile.Read(mHeaderBytes.Get(), offset, kPGPdiskBlockSize);

	// Validate size.
	ValidateHeaderSize();

	// Read in rest of header if necessary.
	if (HeaderSize() > kPGPdiskBlockSize)
	{
		mHeaderBytes.Resize(HeaderSize());
		diskFile.Read(mHeaderBytes.Get(), offset, HeaderSize());
	}

	// Make sure everything is kosher.
	CanonicalizeHeader();
}

void 
CPGPdiskHeader::WriteAtOffset(CFile& diskFile, PGPUInt64 offset)
{
	pgpAssert(diskFile.IsOpened());

	// Update header CRC.
	UpdateCRC();

	// Write it out.
	diskFile.Write(mHeaderBytes.Get(), offset, HeaderSize());

	// Clear bytes up to block boundary.
	if (HeaderSize()%kPGPdiskBlockSize > 0)
	{
		CArray<PGPUInt8>	blanks(kPGPdiskBlockSize);
		blanks.Wipe();

		diskFile.Write(blanks.Get(), offset + HeaderSize(), 
			kPGPdiskBlockSize - (HeaderSize()%kPGPdiskBlockSize));
	}
}

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

	mHeaderBytes.Resize(pHeader->HeaderSize());

	pgpCopyMemory(pHeader->mHeaderBytes.Get(), mHeaderBytes.Get(), 
		pHeader->HeaderSize());

	// Make sure everything is kosher.
	CanonicalizeHeader();
}

PGPUInt32 
CPGPdiskHeader::ComputeCRC()
{
	CCRC32	theCrc;

	// Always set CRC value to zero before computing.
	PGPUInt32	oldCRC = HeaderCRC();
	HeaderCRC() = 0;

	theCrc.Init();

	theCrc.Continue(reinterpret_cast<const PGPUInt32 *>(mHeaderBytes.Get()), 
		HeaderSize() / sizeof(PGPUInt32));

	HeaderCRC() = oldCRC;

	return theCrc.GetCRC();
}

void 
CPGPdiskHeader::ValidateHeaderSize()
{
	if ((HeaderSize() < sizeof(OnDiskHeaderInfo)) || 
		(HeaderSize() > OnDiskHeaderInfo::kMaxBlocksHeader * 
		kPGPdiskBlockSize))
	{
		THROW_PGPERROR(kPGPClientError_CorruptDiskHeader);
	}
}

void 
CPGPdiskHeader::CanonicalizeHeader()
{
	if (HeaderMagic() != OnDiskHeaderInfo::kHeaderMagic)
		THROW_PGPERROR(kPGPClientError_CorruptDiskHeader);

	if (HeaderCRC() != ComputeCRC())
		THROW_PGPERROR(kPGPClientError_CorruptDiskHeader);

	ValidateHeaderSize();
}

⌨️ 快捷键说明

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