📄 pgpdiskpublickeyutils.cpp
字号:
}
return derr;
}
// GetHeaderForPublicKey returns a copy of the PGPdisk header that
// corresponds to the given public key.
DualErr
GetHeaderForPublicKey(
LPCSTR path,
PGPKeyRef curKey,
PGPdiskPublicKeyHeader **pubKeyHdr)
{
File diskFile;
DualErr derr;
PGPBoolean gotItemList;
PGPdiskFileHeaderItem *itemList, *keyItem;
pgpAssertStrValid(path);
pgpAssert(PGPKeyRefIsValid(curKey));
// Open the PGPdisk.
derr = diskFile.Open(path, kOF_MustExist | kOF_ReadOnly);
// Get list of headers.
if (derr.IsntError())
{
derr = GetHeaderItemList(&diskFile, &itemList);
gotItemList = derr.IsntError();
}
// Look for associated header.
if (derr.IsntError())
{
derr = FindPublicKeyInHeaderList(&diskFile, curKey, itemList,
&keyItem);
}
// Copy the header.
if (derr.IsntError())
{
derr = CopyHeader(keyItem->hdr, (PGPdiskFileHeaderInfo **) pubKeyHdr);
}
if (gotItemList)
FreeHeaderItemList(itemList);
if (diskFile.Opened())
diskFile.Close();
return derr;
}
// CreatePublicKeyHeader creates and returns a new PGPdisk public key header
// using the specified information.
DualErr
CreatePublicKeyHeader(
PGPKeyRef pubKey,
const CASTKey *decryptedKey,
PGPBoolean locked,
PGPBoolean readOnly,
PGPdiskPublicKeyHeader **outPubKeyHdr)
{
DualErr derr;
CheckBytes checkBytes;
PGPBoolean gotEncryptedKey = FALSE;
PGPByte *data, exportedKeyID[kPGPMaxExportedKeyIDSize];
PGPKeyID keyID;
PGPInt32 alg;
PGPPublicKeyAlgorithm algorithm;
PGPdiskPublicKeyHeader *pubKeyHdr;
PGPSize exportedKeyIDSize;
PGPUInt32 encryptedKeySize, headerSize;
void *encryptedKey = NULL;
encryptedKeySize = 0;
pgpAssert(PGPKeyRefIsValid(pubKey));
pgpAssertAddrValid(decryptedKey, CASTKey);
pgpAssertAddrValid(outPubKeyHdr, PGPdiskPublicKeyHeader *);
// Encrypt decypted key using the private key of the public key.
derr = EncryptPublicKey(decryptedKey, pubKey, &encryptedKey,
&encryptedKeySize, &checkBytes);
gotEncryptedKey = derr.IsntError();
// Get key ID.
if (derr.IsntError())
{
derr = PGPGetKeyIDFromKey(pubKey, &keyID);
}
// Get exported key ID.
if (derr.IsntError())
{
derr = PGPExportKeyID(&keyID, exportedKeyID, &exportedKeyIDSize);
}
// Get key algorithm.
if (derr.IsntError())
{
derr = PGPGetKeyNumber(pubKey, kPGPKeyPropAlgID, &alg);
}
// Allocate header.
if (derr.IsntError())
{
algorithm = (PGPPublicKeyAlgorithm) alg;
headerSize = sizeof(PGPdiskPublicKeyHeader) + exportedKeyIDSize +
encryptedKeySize;
try
{
pubKeyHdr = (PGPdiskPublicKeyHeader *) new PGPUInt8[headerSize];
}
catch (CMemoryException *ex)
{
derr = DualErr(kPGDMinorError_OutOfMemory);
ex->Delete();
}
}
// Initialize header fields.
if (derr.IsntError())
{
pgpClearMemory(pubKeyHdr, sizeof(PGPdiskPublicKeyHeader));
strncpy(pubKeyHdr->headerInfo.headerMagic, kPGPdiskHeaderMagic, 4);
strncpy(pubKeyHdr->headerInfo.headerType,
kPGPdiskPublicKeyHeaderType, 4);
pubKeyHdr->headerInfo.headerSize = headerSize;
pubKeyHdr->majorVersion = kPGPdiskPublicKeyHeaderMajorVersion;
pubKeyHdr->minorVersion = kPGPdiskPublicKeyHeaderMinorVersion;
pubKeyHdr->readOnly = readOnly;
pubKeyHdr->locked = locked;
pubKeyHdr->keyIDSize = exportedKeyIDSize;
pubKeyHdr->encryptedKeySize = encryptedKeySize;
pubKeyHdr->checkBytes = checkBytes;
pubKeyHdr->algorithm = algorithm;
data = (PGPByte *) pubKeyHdr + sizeof(PGPdiskPublicKeyHeader);
pgpCopyMemory(exportedKeyID, data, exportedKeyIDSize);
pubKeyHdr->keyIDOffset = data - (PGPByte *) pubKeyHdr;
data += exportedKeyIDSize;
pgpCopyMemory(encryptedKey, data, encryptedKeySize);
pubKeyHdr->encryptedKeyOffset = data - (PGPByte *) pubKeyHdr;
(* outPubKeyHdr) = pubKeyHdr;
}
if (gotEncryptedKey)
delete[] (PGPUInt8 *) encryptedKey;
return derr;
}
// ArePGPdiskPassesWiped returns TRUE if this PGPdisk has had its passes
// wiped, FALSE otherwise.
PGPBoolean
ArePGPdiskPassesWiped(LPCSTR path)
{
DualErr derr;
File diskFile;
PGPBoolean arePassesWiped, masterInUse, readHeader;
PGPdiskFileHeader *mainHeader;
arePassesWiped = readHeader = FALSE;
pgpAssertStrValid(path);
// Read main header.
derr = ReadPGPdiskFileMainHeader(path, &mainHeader);
readHeader = derr.IsntError();
// If master passphrase not in use and ID matches, then we're wiped.
if (derr.IsntError())
{
masterInUse = (mainHeader->masterPassphrase.inUse ? TRUE : FALSE);
if (!masterInUse)
{
arePassesWiped = (strcmp((LPCSTR)
&mainHeader->masterPassphrase.checkBytes.theBytes,
kPGPdiskPassesWipedId) == 0);
}
}
if (readHeader)
FreePGPdiskFileHeader((PGPdiskFileHeaderInfo *) mainHeader);
if (derr.IsError())
return FALSE;
else
return arePassesWiped;
}
// ShowReadOnlyListOfPublicKeys displays the recipient dialog containing a
// read-only list of all the public keys on the specified PGPdisk.
DualErr
ShowReadOnlyListOfPublicKeys(LPCSTR path)
{
DualErr derr;
PGPBoolean gotAllKeys, gotExistingKeys, gotNewKeys;
PGPBoolean gotOptionsList;
PGPKeySetRef allKeys, newKeySet;
PGPOptionListRef recipientOptions;
PGPRecipientSpec *existingKeys;
PGPUInt32 numExistKeys;
gotAllKeys = gotExistingKeys = gotNewKeys = gotOptionsList = FALSE;
// Open default key rings.
derr = PGPOpenDefaultKeyRings(GetGlobalPGPContext(), 0, &allKeys);
gotAllKeys = derr.IsntError();
// Retrieve already existing keys from the PGPdisk.
if (derr.IsntError())
{
derr = GetPGPdiskRecipKeys(path, allKeys, &existingKeys,
&numExistKeys);
gotExistingKeys = derr.IsntError();
}
// Make each key read-only in the dialog.
if (derr.IsntError())
{
PGPUInt32 i;
for (i = 0; i < numExistKeys; i++)
{
existingKeys[i].locked = TRUE;
}
}
// Build option list for the recipient dialog.
if (derr.IsntError())
{
PGPOptionListRef defRecipOption;
defRecipOption = PGPOUIDefaultRecipients(GetGlobalPGPContext(),
numExistKeys, existingKeys);
derr = PGPBuildOptionList(GetGlobalPGPContext(), &recipientOptions,
defRecipOption, PGPOLastOption(GetGlobalPGPContext()));
gotOptionsList = derr.IsntError();
}
// Show the recipient dialog.
if (derr.IsntError())
{
derr = PGPRecipientDialog(GetGlobalPGPContext(), allKeys, TRUE,
&newKeySet, recipientOptions,
PGPOLastOption(GetGlobalPGPContext()));
gotNewKeys = derr.IsntError();
}
if (gotNewKeys)
PGPFreeKeySet(newKeySet);
if (gotOptionsList)
PGPFreeOptionList(recipientOptions);
if (gotExistingKeys)
FreeRecipientSpecList(existingKeys, numExistKeys);
if (gotAllKeys)
PGPFreeKeySet(allKeys);
return derr;
}
// WipeMasterAndAlternatePasses wipes all the master and alternate
// passphrases on a PGPdisk, but leaves the public key passphrases alone.
DualErr
WipeMasterAndAlternatePasses(LPCSTR path)
{
DualErr derr;
File diskFile;
PGPBoolean readHeader = FALSE;
PGPdiskFileHeader *mainHeader;
pgpAssertStrValid(path);
// Read main header.
derr = ReadPGPdiskFileMainHeader(path, &mainHeader);
readHeader = derr.IsntError();
// Wipe master and alternate passes.
if (derr.IsntError())
{
PGPUInt32 i;
pgpClearMemory(&mainHeader->masterPassphrase,
sizeof(mainHeader->masterPassphrase));
pgpClearMemory(mainHeader->otherPassphrases,
sizeof(mainHeader->otherPassphrases));
mainHeader->masterPassphrase.inUse = FALSE;
for (i = 0; i < kMaxAlternatePassphrases; i++)
{
mainHeader->otherPassphrases[i].inUse = FALSE;
}
strcpy((LPSTR) &mainHeader->masterPassphrase.checkBytes.theBytes,
kPGPdiskPassesWipedId);
derr = WritePGPdiskFileMainHeader(path, mainHeader);
}
if (readHeader)
FreePGPdiskFileHeader((PGPdiskFileHeaderInfo *) mainHeader);
return derr;
}
///////////////////////
// ADK utility routines
///////////////////////
// IsTherePGPdiskADK returns TRUE if a PGPdisk ADK exists, FALSE otherwise.
DualErr
IsTherePGPdiskADK(PGPBoolean *isThereADK)
{
DualErr derr;
pgpAssertAddrValid(isThereADK, PGPBoolean);
(* isThereADK) = FALSE;
#if PGP_BUSINESS_SECURITY
PGPBoolean openedAdminPrefs = FALSE;
PGPPrefRef adminPrefsRef;
// Open admin prefs file.
if (derr.IsntError())
{
derr = PGPclOpenAdminPrefs(PGPGetContextMemoryMgr(
GetGlobalPGPContext()), &adminPrefsRef, TRUE);
openedAdminPrefs = derr.IsntError();
}
// Uses ADK?
if (derr.IsntError())
{
derr = PGPGetPrefBoolean(adminPrefsRef, kPGPPrefUsePGPdiskADK,
isThereADK);
}
if (openedAdminPrefs)
PGPclCloseAdminPrefs(adminPrefsRef, FALSE);
#endif // PGP_BUSINESS_SECURITY
return derr;
}
// GetADKKey gets the PGPdisk ADK key.
DualErr
GetADKKey(PGPKeySetRef allKeys, PGPKeyRef *ADKKey)
{
DualErr derr;
PGPBoolean gotIDData, openedAdminPrefs;
PGPKeyID keyID;
PGPPrefRef adminPrefsRef;
PGPPublicKeyAlgorithm algorithm;
PGPSize dataLength;
PGPUInt32 tempAlg;
void *data;
gotIDData = openedAdminPrefs = FALSE;
pgpAssert(PGP_BUSINESS_SECURITY);
pgpAssert(PGPKeySetRefIsValid(allKeys));
pgpAssertAddrValid(ADKKey, PGPKeyRef);
// Open admin prefs file.
derr = PGPclOpenAdminPrefs(PGPGetContextMemoryMgr(
GetGlobalPGPContext()), &adminPrefsRef, TRUE);
openedAdminPrefs = derr.IsntError();
// Get ADK algorithm.
if (derr.IsntError())
{
derr = PGPGetPrefNumber(adminPrefsRef,
kPGPPrefPGPdiskADKPublicKeyAlgorithm, &tempAlg);
}
// Get ADK algorithm.
if (derr.IsntError())
{
algorithm = (PGPPublicKeyAlgorithm) tempAlg;
derr = PGPGetPrefData(adminPrefsRef, kPGPPrefPGPdiskADKKeyID,
&dataLength, &data);
gotIDData = derr.IsntError();
}
// Get ADK key ID.
if (derr.IsntError())
{
derr = PGPImportKeyID(data, &keyID);
}
// Get ADK key.
if (derr.IsntError())
{
derr = PGPGetKeyByKeyID(allKeys, &keyID, algorithm, ADKKey);
}
if (gotIDData)
PGPFreeData(data);
if (openedAdminPrefs)
PGPclCloseAdminPrefs(adminPrefsRef, FALSE);
return derr;
}
// GetADKUserID gets the user ID of the current PGPdisk ADK.
DualErr
GetADKUserID(PGPKeySetRef allKeys, LPSTR userID, PGPUInt32 sizeUserID)
{
DualErr derr;
PGPKeyRef ADKKey;
pgpAssert(PGP_BUSINESS_SECURITY);
pgpAssert(PGPKeySetRefIsValid(allKeys));
pgpAssertAddrValid(userID, char);
// Get ADK key.
derr = GetADKKey(allKeys, &ADKKey);
// Get user ID string.
if (derr.IsntError())
{
PGPSize usedLength;
derr = PGPGetPrimaryUserIDNameBuffer(ADKKey, sizeUserID, userID,
&usedLength);
}
return derr;
}
// AddADKToPGPdisk adds an existing ADK to a PGPdisk.
DualErr
AddADKToPGPdisk(LPCSTR path, SecureString *masterPassphrase)
{
CASTKey *decryptedKey;
DualErr derr;
File diskFile;
PGPBoolean gotAllKeys, gotItemList;
PGPdiskFileHeaderItem *itemList;
PGPdiskPublicKeyHeader *pubKeyHdr;
PGPdiskFileHeader *mainHeader;
PGPKeyRef ADKKey;
PGPKeySetRef allKeys;
SecureMemory smDecryptedKey(sizeof(CASTKey));
gotAllKeys = gotItemList = FALSE;
pgpAssertStrValid(path);
// Did we get our locked memory?
derr = smDecryptedKey.mInitErr;
// Set the locked memory pointer.
if (derr.IsntError())
{
decryptedKey = (CASTKey *) smDecryptedKey.GetPtr();
}
// Load default key ring.
if (derr.IsntError())
{
derr = PGPOpenDefaultKeyRings(GetGlobalPGPContext(), 0, &allKeys);
gotAllKeys = derr.IsntError();
}
// Get ADK key.
if (derr.IsntError())
{
derr = GetADKKey(allKeys, &ADKKey);
}
// Open the PGPdisk.
if (derr.IsntError())
{
derr = diskFile.Open(path, kOF_MustExist);
}
// Get list of headers.
if (derr.IsntError())
{
derr = GetHeaderItemList(&diskFile, &itemList);
gotItemList = derr.IsntError();
}
if (derr.IsntError())
{
// Get main header pointer.
mainHeader = (PGPdiskFileHeader *) itemList->hdr;
// Decrypt the master key
derr = DecryptPassphraseKey(&mainHeader->masterPassphrase,
&mainHeader->salt, masterPassphrase, decryptedKey);
}
// Create a new header for it.
if (derr.IsntError())
{
derr = CreatePublicKeyHeader(ADKKey, decryptedKey, TRUE, TRUE,
&pubKeyHdr);
}
// Insert the new header after the main header.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -