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

📄 cpgpdiskuser.cpp

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

		tempUser.Create(newCipher, userName, passphrase, IsReadOnly());
		tempUser.SetIsAdminUser(IsAdminUser());
	}

	Assign(tempUser);
}

void 
CPGPdiskUser::ChangePassphrase(const char *newPassphrase)
{
	pgpAssert(IsAssigned());
	pgpAssertStrValid(newPassphrase);

	if (!IsCipheringEnabled() || !HasSymmetricKey())
		THROW_PGPERROR(kPGPError_BadParams);

	mPCipher->EncryptPassphraseKey(newPassphrase, 
		GetAsUserWithSym()->keyInfo);
}

void 
CPGPdiskUser::Create(
	const CCipherContext&	cipher, 
	const CPGPKey&			pubKey, 
	PGPBoolean				readOnly, 
	PGPBoolean				isLocked)
{
	pgpAssert(cipher.IsInitialized());

	// Encrypt decypted key using the private key of the public key.
	CPGPKey	subKey;
	if (!pubKey.GetKeyForUsage(subKey))
		THROW_PGPERROR(kPGPError_PublicKeyUnimplemented);

	Crypto::CheckBytes		checkBytes;
	CSecureArray<PGPByte>	encryptedKey;
	PGPUInt32				encryptedKeySize;

	EncryptUsingPublicKey(subKey, cipher, encryptedKey, encryptedKeySize, 
		checkBytes);

	// Get key IDs.
	CPGPKeyID	keyID;
	pubKey.GetKeyID(keyID);

	CPGPKeyID	subKeyID;
	subKey.GetKeyID(subKeyID);

	// Import the key.
	ImportRawPublicKey(keyID, subKeyID, encryptedKey.Get(), 
		encryptedKeySize, checkBytes, readOnly, isLocked);
}

void 
CPGPdiskUser::Create(
	const CCipherContext&	cipher, 
	const char				*userName, 
	const char				*passphrase, 
	PGPBoolean				readOnly)
{
	pgpAssertStrValid(userName);
	pgpAssertStrValid(passphrase);

	// Initialize key info structure with session key.
	Crypto::PassphraseKeyInfo	keyInfo;
	cipher.EncryptPassphraseKey(passphrase, keyInfo);

	// Import symmetric key.
	ImportRawSymmetricKey(keyInfo, userName, readOnly);
}

void 
CPGPdiskUser::Import(const void *buf, PGPUInt32 size)
{
	pgpAssertAddrValid(buf, VoidAlign);

	if (size < sizeof(OnDiskUserInfo))
		THROW_PGPERROR(kPGPError_BadParams);

	Clear();

	// First get header.
	mUserBytes.Resize(sizeof(OnDiskUserInfo));
	pgpCopyMemory(buf, mUserBytes.Get(), sizeof(OnDiskUserInfo));

	// Validate header.
	if (GetAsUserInfo()->userMagic != OnDiskUserInfo::kUserMagic)
		THROW_PGPERROR(kPGPClientError_CorruptDiskHeader);

	if (!HasPublicKey() && !HasSymmetricKey())
		THROW_PGPERROR(kPGPClientError_CorruptDiskHeader);

	PGPUInt32	userSize	= GetAsUserInfo()->userSize;

	if (userSize > OnDiskUserInfo::kMaxBytesDiskUser)
		THROW_PGPERROR(kPGPClientError_CorruptDiskHeader);

	// Copy in entire user.
	mUserBytes.Resize(userSize);
	pgpCopyMemory(buf, mUserBytes.Get(), userSize);

	if (HasPublicKey())
	{
		if (GetAsUserWithPub()->encryptedKeyOffset + 
			GetAsUserWithPub()->encryptedKeySize > userSize)
		{
			THROW_PGPERROR(kPGPClientError_CorruptDiskHeader);
		}

		if (GetAsUserWithPub()->encryptedKeyOffset < 
			sizeof(OnDiskUserWithPub))
		{
			// beta header with no subkey ID
			mUserBytes.Resize(sizeof(OnDiskUserWithPub) + 
				GetAsUserWithPub()->encryptedKeySize);

			pgpCopyMemory(
				mUserBytes.Get() + 
					GetAsUserWithPub()->encryptedKeyOffset, 
				mUserBytes.Get() + 
					sizeof(OnDiskUserWithPub), 
				GetAsUserWithPub()->encryptedKeySize);

			GetAsUserWithPub()->encryptedKeyOffset = 
				sizeof(OnDiskUserWithPub);
			GetAsUserInfo()->userSize = 
				GetAsUserWithPub()->encryptedKeyOffset + 
				GetAsUserWithPub()->encryptedKeySize;
			GetAsUserWithPub()->subKeyID = 
				GetAsUserWithPub()->keyID;

			pgpClearMemory(GetAsUserWithPub()->checkBytes.bytes, 
				sizeof(GetAsUserWithPub()->checkBytes.bytes));
		}

		mKeyID = GetAsUserWithPub()->keyID;
		mSubKeyID = GetAsUserWithPub()->subKeyID;
	}

	mIsAssigned = TRUE;
}

void 
CPGPdiskUser::Export(void *buf, PGPUInt32 availSize) const
{
	pgpAssert(IsAssigned());
	pgpAssertAddrValid(buf, VoidAlign);

	if (availSize < GetSizeForExport())
		THROW_PGPERROR(kPGPError_BufferTooSmall);

	pgpCopyMemory(mUserBytes.Get(), buf, GetSizeForExport());
}

void 
CPGPdiskUser::ImportRawSymmetricKey(
	const Crypto::PassphraseKeyInfo&	keyInfo, 
	const char							*userName, 
	PGPBoolean							readOnly)
{
	pgpAssertStrValid(userName);

	Clear();

	// Allocate on disk user bytes.
	PGPUInt32	onDiskSize	= sizeof(OnDiskUserWithSym);

	mUserBytes.Resize(onDiskSize);
	mUserBytes.Wipe();

	// Initialize fields.
	GetAsUserInfo()->userMagic	= OnDiskUserInfo::kUserMagic;
	GetAsUserInfo()->userType	= OnDiskUserInfo::kUserWithSymType;
	GetAsUserInfo()->userSize	= onDiskSize;
	GetAsUserInfo()->readOnly	= readOnly;
	GetAsUserInfo()->locked		= FALSE;

	GetAsUserWithSym()->keyInfo = keyInfo;

	UString::SmartStringCopy(GetAsUserWithSym()->userName, userName, 
		kPGPdiskMaxUserNameSize);

	mIsAssigned = TRUE;
}

void 
CPGPdiskUser::ImportRawPublicKey(
	const PGPKeyID&				keyID, 
	const PGPKeyID&				subKeyID, 
	const PGPByte				*pEncryptedKey, 
	PGPUInt32					lengthEncKey, 
	const Crypto::CheckBytes&	checkBytes, 
	PGPBoolean					readOnly, 
	PGPBoolean					locked)
{
	pgpAssertAddrValid(pEncryptedKey, PGPByte);

	Clear();

	// Allocate on disk user bytes.
	PGPUInt32	onDiskSize	= sizeof(OnDiskUserWithPub) + lengthEncKey;

	mUserBytes.Resize(onDiskSize);
	mUserBytes.Wipe();

	// Initialize fields.
	GetAsUserInfo()->userMagic	= OnDiskUserInfo::kUserMagic;
	GetAsUserInfo()->userType	= OnDiskUserInfo::kUserWithPubType;
	GetAsUserInfo()->userSize	= onDiskSize;
	GetAsUserInfo()->readOnly	= readOnly;
	GetAsUserInfo()->locked		= locked;

	GetAsUserWithPub()->keyID = keyID;
	GetAsUserWithPub()->subKeyID = subKeyID;

	GetAsUserWithPub()->encryptedKeyOffset = sizeof(OnDiskUserWithPub);
	GetAsUserWithPub()->encryptedKeySize = lengthEncKey;
	GetAsUserWithPub()->checkBytes = checkBytes;

	PGPByte	*pData	= mUserBytes.Get() + 
		GetAsUserWithPub()->encryptedKeyOffset;
	pgpCopyMemory(pEncryptedKey, pData, lengthEncKey);

	mKeyID = keyID;
	mSubKeyID = subKeyID;
	mIsAssigned = TRUE;
}

void 
CPGPdiskUser::ImportRawPublicKey(
	const PGPByte				*pKeyID, 
	PGPSize						lengthKeyID, 
	const PGPByte				*pEncryptedKey, 
	PGPSize						lengthEncKey, 
	const Crypto::CheckBytes&	checkBytes, 
 	PGPPublicKeyAlgorithm		pubAlgorithm, 
	PGPBoolean					readOnly, 
	PGPBoolean					locked)
{
	pgpAssertAddrValid(pKeyID, PGPByte);
	pgpAssertAddrValid(pEncryptedKey, PGPByte);

	Clear();

	// This overload means we are being given old-style key ID. Convert it.
	PGPByte	*pRealKeyID	= const_cast<PGPByte *>(pKeyID);
	PGPSize	realLength	= lengthKeyID;

	if ((realLength == 5) || (realLength == 9))
	{
		realLength--;
		pRealKeyID++;
	}

	CPGPKeyID	keyID;
	keyID.SetKeyIDFromBytes(pRealKeyID, realLength, pubAlgorithm);

	ImportRawPublicKey(keyID, keyID, pEncryptedKey, lengthEncKey, 
		checkBytes, readOnly, locked);
}

void 
CPGPdiskUser::Assign(const CPGPdiskUser& user)
{
	if (&user == this)
		return;

	pgpAssert(user.IsAssigned());
	Clear();

	mPContext = user.mPContext;

	CArray<PGPUInt8>	exportedUser(user.GetSizeForExport());
	user.Export(exportedUser.Get(), exportedUser.Size());

	Import(exportedUser.Get(), exportedUser.Size());
}

void 
CPGPdiskUser::Clear()
{
	if (IsAssigned() && IsCipheringEnabled())
		DisableCiphering();

	mUserBytes.Wipe();

	mPGPKeyPresent = FALSE;
	mIsAssigned = FALSE;
}

void 
CPGPdiskUser::Init()
{
	mPContext			= NULL;
	mPCipher			= NULL;
	mCipheringEnabled	= FALSE;
	mIsAssigned			= FALSE;
	mPGPKeyPresent		= FALSE;
}

void 
CPGPdiskUser::SetIsAdminUser(PGPBoolean isAdminUser)
{
	pgpAssert(IsAssigned());
	GetAsUserInfo()->adminUser = isAdminUser;
}

void 
CPGPdiskUser::ImportPublicKey() const
{
	pgpAssert(mIsAssigned);
		
	// Get actual key.
	try
	{
		mPGPKey.FindKeyByKeyID(Context()->PGPKeyDB(), mKeyID);
		mPGPSubKey.FindKeyByKeyID(Context()->PGPKeyDB(), mSubKeyID);
		mPGPKeyPresent = TRUE;
	}
	catch (CComboError&)
	{
		mPGPKeyPresent = FALSE;
	}
}

void 
CPGPdiskUser::VerifyPubKeyCheckBytes(
	const void					*compareMainData, 
	const void					*compareData, 
	const Crypto::CheckBytes&	checkBytes, 
	const CCipherContext&		cipher) const
{
	pgpAssertAddrValid(compareData, VoidAlign);
	pgpAssert(cipher.IsInitialized());

	CArray<PGPUInt8>	encBuf(cipher.GetEncryptSize());
	encBuf.Wipe();

	// if checkbytes are zero, ignore
	if (pgpMemoryEqual(checkBytes.bytes, encBuf.Get(), 
		pgpMin(encBuf.Size(), sizeof(checkBytes.bytes))))
	{
		return;
	}

	cipher.Encrypt(compareData, encBuf.Get());

	if (!pgpMemoryEqual(checkBytes.bytes, encBuf.Get(), 
		pgpMin(encBuf.Size(), sizeof(checkBytes.bytes))))
	{
		// This second try is for 6.5x PGPdisks that compare
		// their checkbytes against the fingerprint of the
		// master key for some odd reason -wjb
		encBuf.Wipe();

		cipher.Encrypt(compareMainData, encBuf.Get());

		if (!pgpMemoryEqual(checkBytes.bytes, encBuf.Get(), 
			pgpMin(encBuf.Size(), sizeof(checkBytes.bytes))))
		{
			THROW_PGPERROR(kPGPClientError_CorruptDiskHeader);
		}
	}
}

void 
CPGPdiskUser::GeneratePubKeyCheckBytes(
	const void				*compareData, 
	const CCipherContext&	cipher, 
	Crypto::CheckBytes&		checkBytes) const
{
	pgpAssertAddrValid(compareData, VoidAlign);
	pgpAssert(cipher.IsInitialized());

	CArray<PGPByte>	encBuf(cipher.GetEncryptSize());
	encBuf.Wipe();

	cipher.Encrypt(compareData, encBuf.Get());
	pgpClearMemory(checkBytes.bytes, sizeof(checkBytes.bytes));

	pgpCopyMemory(encBuf.Get(), checkBytes.bytes, pgpMin(encBuf.Size(), 
		sizeof(checkBytes.bytes)));
}

void 
CPGPdiskUser::DecryptUsingPublicKey(
	const CPGPKey&					pubMainKey,
	const CPGPKey&					pubKey,
	const char						*passphrase,
	int								passkeylen,
	const PGPByte					*pEncryptedData,
	PGPSize							encryptedDataSize,
	const Crypto::PassphraseSalt&	salt, 
	const Crypto::CheckBytes&		checkBytes, 
	CCipherContext&					cipher) const
{
	pgpAssertAddrValid(pEncryptedData, VoidAlign);
	pgpAssert(cipher.IsInitialized());

	// Initialize private key context.
	CPGPPrivateKeyContext	privContext(pubKey, passphrase, passkeylen);

	// Get operation sizes.
	PGPSize	maxDecryptedBufferSize, maxEncryptedBufferSize, maxSignatureSize;

	privContext.GetPrivateKeyOperationSizes(maxDecryptedBufferSize, 
		maxEncryptedBufferSize, maxSignatureSize);

	// Get key properties.
	CArray<PGPByte>	fingerPrint(128);
	PGPSize			fingerPrintSize;

	fingerPrint.Wipe();
		
	pubKey.GetDataProp(kPGPKeyProperty_Fingerprint, fingerPrint.Get(), 
		fingerPrint.Size(), fingerPrintSize);

	// Get Main key properties.
	CArray<PGPByte>	mainFingerPrint(128);
	PGPSize			mainFingerPrintSize;

	mainFingerPrint.Wipe();
		
	pubMainKey.GetDataProp(kPGPKeyProperty_Fingerprint, mainFingerPrint.Get(), 
		mainFingerPrint.Size(), mainFingerPrintSize);

	// Decrypt the session key.
	CSecureArray<PGPByte>	decKeyData;
	PGPUInt32				decryptedDataSize;

	decKeyData.Resize(maxDecryptedBufferSize);

	privContext.PrivateKeyDecrypt(pEncryptedData, encryptedDataSize, 
		decKeyData.Get(), decryptedDataSize);

	// Check the result.
	if (decryptedDataSize > cipher.GetKeySize())
		THROW_PGPERROR(kPGPClientError_CorruptDiskHeader);

	CSecureObject<Crypto::SymmetricKey>	pDecryptedKey;
	pgpCopyMemory(decKeyData.Get(), pDecryptedKey->bytes, decryptedDataSize);

	// Initialize cipher context.
	cipher.AttachSymmetricKey(*pDecryptedKey, salt);

	// Check check bytes.
	VerifyPubKeyCheckBytes(mainFingerPrint.Get(),
		fingerPrint.Get(), checkBytes, cipher);
}

void 
CPGPdiskUser::EncryptUsingPublicKey(
	const CPGPKey&			pubKey, 
	const CCipherContext&	cipher, 
	CSecureArray<PGPByte>&	encryptedKey, 
	PGPUInt32&				encryptedKeySize, 
	Crypto::CheckBytes&		checkBytes) const
{
	// Initialize public key context.
	CPGPPublicKeyContext	pubContext(pubKey);

	// Get operation sizes.
	PGPSize	maxDecryptedBufferSize, maxEncryptedBufferSize, maxSignatureSize;

	pubContext.GetPublicKeyOperationSizes(maxDecryptedBufferSize, 
		maxEncryptedBufferSize, maxSignatureSize);

	// Get fingerprint.
	PGPByte	fingerPrint[128];
	PGPSize	fingerPrintSize;

	pgpClearMemory(fingerPrint, sizeof(fingerPrint));			
		
	pubKey.GetDataProp(kPGPKeyProperty_Fingerprint, fingerPrint, 
		sizeof(fingerPrint), fingerPrintSize);

	// Get session key.
	CSecureObject<Crypto::SymmetricKey>	pDecryptedKey;
	cipher.GetSymmetricKey(*pDecryptedKey);

	// Encrypt the session key.
	pgpAssert(cipher.GetKeySize() < maxDecryptedBufferSize - 10);

	encryptedKey.Resize(maxEncryptedBufferSize);

	pubContext.PublicKeyEncrypt(pDecryptedKey, cipher.GetKeySize(), 
		encryptedKey.Get(), encryptedKeySize);

	// Compute the check bytes.
	GeneratePubKeyCheckBytes(fingerPrint, cipher, checkBytes);
}

⌨️ 快捷键说明

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