📄 cpgpdiskuser.cpp
字号:
/*____________________________________________________________________________
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 + -