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

📄 cpgpdiskuser.cpp

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

        $Id: CPGPdiskUser.cpp,v 1.16 2002/11/02 19:22:38 wjb Exp $
____________________________________________________________________________*/

#include "pgpClassesConfig.h"

#include "CArray.h"
#include "CSecureObject.h"
#include "CString.h"
#include "UString.h"

#include "pgpClientErrors.h"
#include "CCipherContext.h"
#include "UCommonStrings.h"
#include "CPGPKey.h"

#include "CPGPdiskContext.h"
#include "CPGPdiskUser.h"

_USING_PGP

_PGP_BEGIN

// Types

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

struct OnDiskUserInfo
{
	enum
	{
		kMaxBytesDiskUser	= PFLConstants::kBytesPerKb * 32	// arbitrary
	};

#if defined(_M_IX86)
	enum 
	{
		kUserMagic			= 'RESU', 

		kUserWithSymType	= 'MMYS', 
		kUserWithPubType	= 'YEKP', 
	};
#endif	// _M_IX86

	PGPUInt32	userMagic;
	PGPUInt32	userType;
	PGPUInt32	userSize;

	PGPUInt32	readOnly 	: 1;
	PGPUInt32	locked 		: 1;
	PGPUInt32	adminUser	: 1;
	PGPUInt32	disabled	: 1;
	PGPUInt32	unused		: 28;

	PGPUInt32	reserved[4];
};

struct OnDiskUserWithPub
{
	OnDiskUserInfo	header;
	
	PGPUInt32	encryptedKeyOffset;
	PGPUInt32	encryptedKeySize;

	PGPKeyID			keyID;
	Crypto::CheckBytes	checkBytes;
	PGPKeyID			subKeyID;

	PGPUInt32	reserved[8];

	// Encrypted key here...
};

struct OnDiskUserWithSym
{
	OnDiskUserInfo	header;

	char						userName[kPGPdiskMaxUserNameSize + 1];
	Crypto::PassphraseKeyInfo	keyInfo;
};

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

_PGP_END

// Class CPGPdiskUser member functions

CPGPdiskUser::CPGPdiskUser(const CPGPdiskContext *pContext)
{
	Init();

	pgpAssertAddrValid(pContext, CPGPdiskContext);
	mPContext = pContext;
}

CPGPdiskUser::CPGPdiskUser(const CPGPdiskUser& user)
{
	Init();
	Assign(user);
}

CPGPdiskUser::~CPGPdiskUser()
{
	Clear();
}

CPGPdiskUser& 
CPGPdiskUser::operator=(const CPGPdiskUser& user)
{
	Assign(user);
	return *this;
}

const CPGPdiskContext * 
CPGPdiskUser::Context() const
{
	pgpAssert(IsAssigned());
	return mPContext;
}

PGPBoolean 
CPGPdiskUser::IsEqual(const CPGPdiskUser& user) const
{
	if (this == &user)
		return TRUE;

	// Must both be assigned.
	if (!IsAssigned() || !user.IsAssigned())
		return FALSE;

	// Must be same type and same cipher.
	if (GetAsUserInfo()->userSize != user.GetAsUserInfo()->userSize)
		return FALSE;

	if (HasPublicKey())
	{
		// If public key, compare key IDs.
		return (mKeyID.IsEqual(user.mKeyID));
	}
	else
	{
		// If symmetric key, compare PassphraseKeyInfos and user names.
		CString	userName1, userName2;

		GetUserName(userName1);
		user.GetUserName(userName2);

		if (userName1 != userName2)
			return FALSE;

		return pgpMemoryEqual(&GetAsUserWithSym()->keyInfo, 
			&user.GetAsUserWithSym()->keyInfo, 
			sizeof(Crypto::PassphraseKeyInfo));
	}
}

PGPBoolean 
CPGPdiskUser::IsAssigned() const
{
	return mIsAssigned;
}

PGPBoolean 
CPGPdiskUser::HasPublicKey() const
{
	return (GetAsUserInfo()->userType == OnDiskUserInfo::kUserWithPubType);
}

PGPBoolean 
CPGPdiskUser::HasSymmetricKey() const
{
	return (GetAsUserInfo()->userType == OnDiskUserInfo::kUserWithSymType);
}

PGPBoolean 
CPGPdiskUser::IsReadOnly() const
{
	pgpAssert(IsAssigned());
	return (GetAsUserInfo()->readOnly);
}

PGPBoolean 
CPGPdiskUser::IsLocked() const
{
	pgpAssert(IsAssigned());
	return (GetAsUserInfo()->locked);
}

PGPBoolean 
CPGPdiskUser::IsAdminUser() const
{
	pgpAssert(IsAssigned());
	return (GetAsUserInfo()->adminUser);
}

PGPBoolean 
CPGPdiskUser::IsDisabled() const
{
	pgpAssert(IsAssigned());
	return (GetAsUserInfo()->disabled);
}

PGPBoolean 
CPGPdiskUser::IsCipheringEnabled() const
{
	pgpAssert(IsAssigned());
	return (mCipheringEnabled);
}

PGPBoolean 
CPGPdiskUser::CanSetReadOnly() const
{
	pgpAssert(IsAssigned());
	return TRUE;
}

PGPBoolean 
CPGPdiskUser::CanSetLocked() const
{
	pgpAssert(IsAssigned());
	return HasPublicKey();
}

PGPBoolean 
CPGPdiskUser::CanSetUserName() const
{
	pgpAssert(IsAssigned());
	return HasSymmetricKey();
}

void 
CPGPdiskUser::GetUserName(CString& userName) const
{
	pgpAssert(IsAssigned());

	if (HasPublicKey())
	{
		ImportPublicKey();

		if (mPGPKeyPresent)
		{
			mPGPKey.GetPrimaryUserIDName(userName);
		}
		else
		{
			CString	keyIDStr;
			mKeyID.GetKeyIDString(kPGPKeyIDString_Abbreviated, keyIDStr);

			userName.Format(UCommonStrings::Get(
				UCommonStrings::kUnknownUserWithIDString), keyIDStr.Get());
		}
	}
	else
	{
		userName = GetAsUserWithSym()->userName;
	}
}

PGPUInt32 
CPGPdiskUser::GetSizeForExport() const
{
	pgpAssert(IsAssigned());
	return GetAsUserInfo()->userSize;
}

void 
CPGPdiskUser::GetPGPKeyID(CPGPKeyID& keyID) const
{
	pgpAssert(IsAssigned());

	if (!HasPublicKey())
		THROW_PGPERROR(kPGPError_BadParams);

	keyID = mKeyID;
}

void 
CPGPdiskUser::GetPGPSubKeyID(CPGPKeyID& subKeyID) const
{
	pgpAssert(IsAssigned());

	if (!HasPublicKey())
		THROW_PGPERROR(kPGPError_BadParams);

	subKeyID = mSubKeyID;
}

void 
CPGPdiskUser::GetCipherContext(CCipherContext& context) const
{
	pgpAssert(IsAssigned());
	pgpAssert(IsCipheringEnabled());

	context = *mPCipher;
}

void 
CPGPdiskUser::SetIsReadOnly(PGPBoolean isReadOnly)
{
	pgpAssert(IsAssigned());
	GetAsUserInfo()->readOnly = isReadOnly;
}

void 
CPGPdiskUser::SetIsLocked(PGPBoolean isLocked)
{
	pgpAssert(IsAssigned());

	if (!CanSetLocked())
		THROW_PGPERROR(kPGPError_FeatureNotAvailable);

	GetAsUserInfo()->locked = isLocked;
}

void 
CPGPdiskUser::SetIsDisabled(PGPBoolean isDisabled)
{
	pgpAssert(IsAssigned());
	GetAsUserInfo()->disabled = isDisabled;
}

void 
CPGPdiskUser::SetUserName(const char *userName)
{
	pgpAssert(IsAssigned());

	if (HasPublicKey())
		THROW_PGPERROR(kPGPError_FeatureNotAvailable);

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

void 
CPGPdiskUser::EnableCiphering(
	const char						*passphrase,
	int								passkeylen,
	PGPdiskEncryptionAlgorithm		algorithm, 
	const Crypto::PassphraseSalt&	salt)
{
	pgpAssert(IsAssigned());

	if (IsCipheringEnabled())
		return;

	mPCipher = new CCipherContext(algorithm);

	if (HasPublicKey())
	{
		// Force reload of KeyDB... in case tokens have been inserted,etc
		// Note that because of our notification callback reloads only
		// occur when things have changed, we just tell disk when it
		// can safely update things -wjb
		Context()->ReloadPGPKeyDB();

		// Public key must be present on keyring.
		ImportPublicKey();

		if (!mPGPKeyPresent)
			THROW_PGPERROR(kPGPClientError_BadDiskPassKeyNotInRing);

		// Can we use it for decryption?
		if (!mPGPKey.GetBooleanProp(kPGPKeyProperty_CanDecrypt))
			// Changed error for private part missing from bad pass
			THROW_PGPERROR(kPGPClientError_BadDiskPassKeyNotInRing);

		// Does this passphrase unlock the private key?
		if (!mPGPKey.PassphraseIsValid(passphrase,passkeylen))
			THROW_PGPERROR(kPGPClientError_BadDiskPassphrase);

		// Decrypt the encrypted session key, assigning it to the cipher.
		PGPByte	*pEncryptedKey	= mUserBytes.Get() + 
			GetAsUserWithPub()->encryptedKeyOffset;

		if (mKeyID.IsEqual(mSubKeyID) && 
			(mPGPKey.GetNumericProp(kPGPKeyProperty_Version) > 
			kPGPKeyVersion_V3))
		{
			CPGPKeySet	pgpKeys(Context()->PGPKeyDB());
			CPGPKeyList	keyList(pgpKeys, kPGPKeyOrdering_Any);
			CPGPKeyIter	keyIter(keyList);
			CPGPKey		key;

			PGPBoolean	succeeded	= FALSE;

			while (keyIter.Next(key))
			{
				CPGPKeyID	keyID;
				key.GetKeyID(keyID);

				if (keyID.IsEqual(mKeyID))
				{
					CPGPKey	subKey;

					while (keyIter.NextSubKey(subKey))
					{
						try
						{
							DecryptUsingPublicKey(key, subKey, passphrase, passkeylen,
								pEncryptedKey, 
								GetAsUserWithPub()->encryptedKeySize, salt, 
								GetAsUserWithPub()->checkBytes, *mPCipher);

							mPGPSubKey.Attach(subKey);
							subKey.GetKeyID(mSubKeyID);

							succeeded = TRUE;
							break;
						}
						catch (CComboError&) {}
					}

					break;
				}
			}

			if (!succeeded)
				THROW_PGPERROR(kPGPClientError_BadDiskPassphrase);
		}
		else
		{
			DecryptUsingPublicKey(mPGPSubKey,mPGPSubKey, passphrase, passkeylen, pEncryptedKey, 
				GetAsUserWithPub()->encryptedKeySize, salt, 
				GetAsUserWithPub()->checkBytes, *mPCipher);
		}
	}
	else
	{
		pgpAssertStrValid(passphrase);

		// Decrypt encrypted session key, assigning it to the cipher.
		mPCipher->DecryptPassphraseKey(passphrase, salt, 
			GetAsUserWithSym()->keyInfo);
	}

	mCipheringEnabled = TRUE;
}

void 
CPGPdiskUser::DisableCiphering()
{
	pgpAssert(IsAssigned());

	if (!IsCipheringEnabled())
		return;

	delete mPCipher;
	mPCipher = NULL;

	mCipheringEnabled = FALSE;
}

void 
CPGPdiskUser::ChangeCipher(
	const CCipherContext&	newCipher, 
	const char				*passphrase)
{
	pgpAssert(newCipher.IsKeyAttached());

	CPGPdiskUser	tempUser(Context());

	if (HasPublicKey())
	{
		// Public key must be present for public PGPdisk keys.
		ImportPublicKey();

		if (!mPGPKeyPresent)
			THROW_PGPERROR(kPGPClientError_BadDiskPassKeyNotInRing);

		// Convert ADK users from READ ONLY 65DISKFIX -wjb
		PGPBoolean bReadOnly;

		bReadOnly=IsReadOnly();

		if (Context()->IsTherePGPdiskADK())
		{
			CPGPKey	adkKey;

			Context()->GetPGPdiskADKPubKey(adkKey);
			if(adkKey==mPGPKey)
				bReadOnly=FALSE;
		}
		// End ADK testing

		tempUser.Create(newCipher, mPGPKey, bReadOnly, IsLocked());
		tempUser.SetIsAdminUser(IsAdminUser());
	}
	else

⌨️ 快捷键说明

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