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

📄 pgpdiskpublickeyutils.cpp

📁 vc环境下的pgp源码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
	if (derr.IsntError())
	{
		derr = InsertPGPdiskHeaderInList(itemList, 
			(PGPdiskFileHeaderInfo *) pubKeyHdr);
	}

	// Write out the updated headers to the PGPdisk.
	if (derr.IsntError())
	{
		derr = UpdateHeaderItemList(&diskFile, itemList);
	}

	if (gotItemList)
		FreeHeaderItemList(itemList);

	if (gotAllKeys)
		PGPFreeKeySet(allKeys);

	if (diskFile.Opened())
		diskFile.Close();

	return derr;
}


////////////////////////////////////////////
// Public key encryption/decryption routines
////////////////////////////////////////////

// DecryptPublicKey decrypts data using a public/private key pair.

DualErr 
DecryptPublicKey(
	PGPKeyRef			pubKey,
	SecureString		*passphrase,
	const void			*encryptedData,
	PGPSize				encryptedDataSize,
	const CheckBytes	*checkBytes,
	CASTKey				*decryptedKey)
{
	CheckBytes				decryptedCheckBytes;
	DualErr					derr;
	ExpandedCASTKey			*expandedKey;
	PGPBoolean				allocedDataBuf, gotPrivContext;
	PGPByte					*data, fingerPrint[128];
	PGPPrivateKeyContextRef	privContext;
	PGPSize					decryptedDataSize, fingerPrintSize;
	PGPSize					maxDecryptedBufferSize, maxEncryptedBufferSize;
	PGPSize					maxSignatureSize;
	PGPUInt8				*secureBuf;

	SecureMemory	smExpandedKey(sizeof(ExpandedCASTKey));
	SecureMemory	smSecureBuf(kMaxPassphraseLength);
	SecureMemory	*pSmCASTKey;

	allocedDataBuf = gotPrivContext = FALSE;

	pgpAssert(PGPKeyRefIsValid(pubKey));
	pgpAssertAddrValid(passphrase, SecureString);
	pgpAssertAddrValid(encryptedData, VoidAlign);
	pgpAssertAddrValid(checkBytes, checkBytes);
	pgpAssertAddrValid(decryptedKey, CASTKey);

	// Did we get our locked memory?
	derr = smExpandedKey.mInitErr;

	if (derr.IsntError())
	{
		derr = smSecureBuf.mInitErr;
	}

	if (derr.IsntError())
	{
		// Get locked memory pointer.
		expandedKey	= (ExpandedCASTKey *) smExpandedKey.GetPtr();
		secureBuf	= (PGPUInt8 *) smSecureBuf.GetPtr();

		// Get passphrase string.
		passphrase->GetString((LPSTR) secureBuf, kMaxStringSize);

		// Get key context.
		PGPContextRef context = PGPGetKeyContext(pubKey);

		// Initialize private context.
		derr = PGPNewPrivateKeyContext(pubKey, 
			kPGPPublicKeyMessageFormat_PGP, &privContext, 
			PGPOPassphrase(context, (LPCSTR) secureBuf), 
			PGPOLastOption(context));

		gotPrivContext = derr.IsntError();
	}

	// Get operation sizes.
	if (derr.IsntError())
	{		
		derr = PGPGetPrivateKeyOperationSizes(privContext, 
			&maxDecryptedBufferSize, &maxEncryptedBufferSize, 
			&maxSignatureSize);
	}

	// Get key properties.
	if (derr.IsntError())
	{
		pgpClearMemory(fingerPrint, sizeof(fingerPrint));			
			
		derr = PGPGetKeyPropertyBuffer(pubKey, kPGPKeyPropFingerprint,
			sizeof(fingerPrint), fingerPrint, &fingerPrintSize);
	}

	// Get space for buffer.
	if (derr.IsntError())
	{
		try
		{
			pSmCASTKey = new SecureMemory(maxDecryptedBufferSize);
			data = (PGPUInt8 *) pSmCASTKey->GetPtr();
		}
		catch (CMemoryException *ex)
		{
			derr = DualErr(kPGDMinorError_OutOfMemory);
			ex->Delete();
		}

		allocedDataBuf = derr.IsntError();
	}

	// Decrypt the data.
	if (derr.IsntError())
	{
		derr = PGPPrivateKeyDecrypt(privContext, encryptedData,
			encryptedDataSize, data, &decryptedDataSize);
	}

	// Check the result.
	if (derr.IsntError())
	{
		if (decryptedDataSize == sizeof(CASTKey))
		{
			pgpCopyMemory(data, decryptedKey, sizeof(CASTKey));

			// Decrypt the check bytes. We encrypted the first eight bytes of
			// the fingerprint.

			CAST5schedule(expandedKey->keyDWords, decryptedKey->keyBytes);

			CAST5decrypt(&checkBytes->theBytes[0], 
				&decryptedCheckBytes.theBytes[0], expandedKey->keyDWords);

			if (!pgpMemoryEqual(&decryptedCheckBytes, fingerPrint, 
				sizeof(decryptedCheckBytes)))
			{
				// Should never get here.
				derr = DualErr(kPGDMinorError_InvalidParameter);
			}						
		}
		else
		{
			derr = DualErr(kPGDMinorError_InvalidParameter);
		}
	}

	if (gotPrivContext)
		PGPFreePrivateKeyContext(privContext);

	if (allocedDataBuf)
		delete pSmCASTKey;

	return derr;
}

// EncryptPublicKey encrypts data using a public/private key pair.

DualErr 
EncryptPublicKey(
	const CASTKey	*decryptedKey,
	PGPKeyRef		pubKey,
	void			**encryptedData,
	PGPUInt32		*encryptedDataSize,
	CheckBytes		*checkBytes)
{
	DualErr					derr;
	ExpandedCASTKey			*expandedKey;
	PGPBoolean				allocedDataBuf, gotPubContext;
	PGPByte					*data, fingerPrint[128];
	PGPPublicKeyContextRef	pubContext;
	PGPSize					dataSize, fingerPrintSize, maxDecryptedBufferSize;
	PGPSize					maxEncryptedBufferSize, maxSignatureSize;

	SecureMemory	smExpandedKey(sizeof(ExpandedCASTKey));

	allocedDataBuf = gotPubContext = FALSE;

	pgpAssert(PGPKeyRefIsValid(pubKey));
	pgpAssertAddrValid(encryptedData, VoidAlign);
	pgpAssertAddrValid(checkBytes, checkBytes);
	pgpAssertAddrValid(decryptedKey, CASTKey);

	// Did we get our locked memory?
	derr = smExpandedKey.mInitErr;

	if (derr.IsntError())
	{
		// Get locked memory pointer.
		expandedKey = (ExpandedCASTKey *) smExpandedKey.GetPtr();

		// Initialize private GetGlobalPGPContext().
		derr = PGPNewPublicKeyContext(pubKey, 
			kPGPPublicKeyMessageFormat_PGP, &pubContext);

		gotPubContext = derr.IsntError();
	}

	// Get operation sizes.
	if (derr.IsntError())
	{		
		derr = PGPGetPublicKeyOperationSizes(pubContext, 
			&maxDecryptedBufferSize, &maxEncryptedBufferSize, 
			&maxSignatureSize);
	}

	// Get key properties.
	if (derr.IsntError())
	{
		pgpClearMemory(fingerPrint, sizeof(fingerPrint));			
			
		derr = PGPGetKeyPropertyBuffer(pubKey, kPGPKeyPropFingerprint,
			sizeof(fingerPrint), fingerPrint, &fingerPrintSize);
	}

	// Get space for buffer.
	if (derr.IsntError())
	{
		try
		{
			data = new PGPByte[maxEncryptedBufferSize];
		}
		catch (CMemoryException *ex)
		{
			derr = DualErr(kPGDMinorError_OutOfMemory);
			ex->Delete();
		}

		allocedDataBuf = derr.IsntError();
	}

	if (derr.IsntError())
	{
		// Compute the check bytes.
		CAST5schedule(expandedKey->keyDWords, decryptedKey->keyBytes);

		CAST5encrypt(fingerPrint, &checkBytes->theBytes[0], 
			expandedKey->keyDWords);

		// Perform the encryption.
		derr = PGPPublicKeyEncrypt(pubContext, decryptedKey, 
			sizeof(CASTKey), data, &dataSize);
	}

	if (derr.IsntError())
	{
		(* encryptedData) 		= data;
		(* encryptedDataSize)	= dataSize;
	}

	if (gotPubContext)
		PGPFreePublicKeyContext(pubContext);

	if (derr.IsError())
	{
		if (allocedDataBuf)
			delete[] data;
	}

	return derr;
}

// GetDecryptedKeyUsingPublicKey decrypts an encrypted session key using info
// from a public key header.

DualErr 
GetDecryptedKeyUsingPublicKey(
	SecureString			*passphrase, 
	PGPdiskPublicKeyHeader	*pubKeyHdr, 
	CASTKey					*decryptedKey)
{
	DualErr			derr;
	PGPBoolean		gotAllKeys	= FALSE;
	PGPByte			*encryptedKey, *exportedKeyID;
	PGPKeyID		keyID;
	PGPKeyRef		pubKey;
	PGPKeySetRef	allKeys;

	pgpAssertAddrValid(passphrase, SecureString);
	pgpAssertAddrValid(pubKeyHdr, PGPdiskPublicKeyHeader);
	pgpAssertAddrValid(decryptedKey, CASTKey);

	// Load SDK prefs.
	derr = PGPsdkLoadDefaultPrefs(GetGlobalPGPContext());

	// Load default key ring.
	if (derr.IsntError())
	{
		derr = PGPOpenDefaultKeyRings(GetGlobalPGPContext(), 0, &allKeys);
		gotAllKeys = derr.IsntError();
	}

	// Import key ID.
	if (derr.IsntError())
	{
		exportedKeyID = (PGPByte *) pubKeyHdr + pubKeyHdr->keyIDOffset;
		derr = PGPImportKeyID(exportedKeyID, &keyID);
	}

	// Get actual key.
	if (derr.IsntError())
	{
		derr = PGPGetKeyByKeyID(allKeys, &keyID, pubKeyHdr->algorithm, 
			&pubKey);
	}

	// Decrypt the encrypted session key.
	if (derr.IsntError())
	{
		encryptedKey = (PGPByte *) pubKeyHdr + pubKeyHdr->encryptedKeyOffset;

		derr = DecryptPublicKey(pubKey, passphrase, encryptedKey, 
			pubKeyHdr->encryptedKeySize, &pubKeyHdr->checkBytes, 
			decryptedKey);
	}

	if (gotAllKeys)
		PGPFreeKeySet(allKeys);

	return derr;
}

// FindPublicPGPdiskKeyHeader finds a PGPdisk public key header whose private
// key is unlocked by the specified passphrase.

DualErr 
FindPublicPGPdiskKeyHeader(
	LPCSTR					path, 
	SecureString			*passphrase, 
	PGPdiskPublicKeyHeader	**pubKeyHdr)
{
	DualErr				derr;
	PGPBoolean			anyKeysNotInRing, foundKey, gotAllKeys;
	PGPBoolean			gotDiskKeys;
	PGPKeyRef			curKey;
	PGPKeySetRef		allKeys;
	PGPRecipientSpec	*diskRecipKeys;
	PGPUInt8			*secureBuf;
	PGPUInt32			i, numRecipKeys;

	SecureMemory	smSecureBuf(kMaxPassphraseLength);

	anyKeysNotInRing = foundKey = gotAllKeys = gotDiskKeys = FALSE;

	pgpAssertStrValid(path);
	pgpAssertAddrValid(passphrase, SecureString);
	pgpAssertAddrValid(pubKeyHdr, PGPdiskPublicKeyHeader *);

	// Did we get our locked memory?
	derr = smSecureBuf.mInitErr;

	if (derr.IsntError())
	{
		// Get locked memory pointer.
		secureBuf = (PGPUInt8 *) smSecureBuf.GetPtr();

		// Get passphrase string.
		passphrase->GetString((LPSTR) secureBuf, kMaxStringSize);

		// Load SDK prefs.
		derr = PGPsdkLoadDefaultPrefs(GetGlobalPGPContext());
	}

	// Load default key ring.
	if (derr.IsntError())
	{
		derr = PGPOpenDefaultKeyRings(GetGlobalPGPContext(), 0, &allKeys);
		gotAllKeys = derr.IsntError();
	}

	// Get list of keys from PGPdisk.
	if (derr.IsntError())
	{
		derr = GetPGPdiskRecipKeys(path, allKeys, &diskRecipKeys, 
			&numRecipKeys);

		gotDiskKeys = derr.IsntError();
	}

	// Find the key that corresponds to the passphrase.
	if (derr.IsntError())
	{
		// For every recipient spec in the list...
		for (i = 0; i < numRecipKeys; i++)
		{
			// ... if it has an associated key ref...
			if (diskRecipKeys[i].type == kPGPRecipientSpecType_Key)
			{
				PGPBoolean canDecrypt = FALSE;

				curKey = diskRecipKeys[i].u.key;
				PGPGetKeyBoolean(curKey, kPGPKeyPropCanDecrypt, &canDecrypt);

				//... and if the given passphrase unlocks it, we're done.
				if (canDecrypt && PGPPassphraseIsValid(curKey,
					PGPOPassphrase(GetGlobalPGPContext(), (LPCSTR) secureBuf), 
					PGPOLastOption(GetGlobalPGPContext())))
				{
					foundKey = TRUE;
					break;
				}
			}
			else
			{
				anyKeysNotInRing = TRUE;
			}
		}
	}

	// Get header associated with the key if one was found.
	if (derr.IsntError())
	{
		if (foundKey)
		{
			derr = GetHeaderForPublicKey(path, curKey, pubKeyHdr);
		}
		else
		{
			if (anyKeysNotInRing)
				derr = DualErr(kPGDMinorError_IncPassAndKeyNotInRing);
			else
				derr = DualErr(kPGDMinorError_IncorrectPassphrase);
		}
	}

	if (gotDiskKeys)
		FreeRecipientSpecList(diskRecipKeys, numRecipKeys);

	if (gotAllKeys)
		PGPFreeKeySet(allKeys);

	return derr;
}

// CheckIfLockedKeysOnKeyring checks if all the PGPdisk's locked public keys
// are on the local keyring.

DualErr 
CheckIfLockedKeysOnKeyring(LPCSTR path, PGPBoolean *pLockedKeysOnKeyring)
{
	DualErr					derr;
	File					diskFile;
	PGPBoolean				gotAllKeys, gotItemList;
	PGPBoolean				lockedKeysOnKeyring;
	PGPByte					*exportedKeyID;
	PGPdiskFileHeaderItem	*curItem, *itemList;
	PGPKeyID				keyID;
	PGPKeyRef				pubKey;
	PGPKeySetRef			allKeys;

	gotAllKeys = gotItemList = FALSE;
	lockedKeysOnKeyring = TRUE;

	pgpAssertStrValid(path);
	pgpAssertAddrValid(pLockedKeysOnKeyring, PGPBoolean);

	// Open the PGPdisk.
	if (derr.IsntError())
	{
		derr = diskFile.Open(path, kOF_MustExist | kOF_ReadOnly);
	}
	
	// Get list of headers.
	if (derr.IsntError())
	{
		derr = GetHeaderItemList(&diskFile, &itemList);
		gotItemList = derr.IsntError();
	}

	// Search for locked keys.
	if (derr.IsntError())
	{
		curItem = itemList->next;

		// Open default key rings.
		derr = PGPOpenDefaultKeyRings(GetGlobalPGPContext(), 0, &allKeys);
		gotAllKeys = derr.IsntError();
		
		while (derr.IsntError() && IsntNull(curItem))
		{
			if (IsPublicKeyHeader(curItem->hdr))
			{
				PGPdiskPublicKeyHeader *pubKeyHdr;

				pubKeyHdr = (PGPdiskPublicKeyHeader *) curItem->hdr;

				// Is it locked?
				if (pubKeyHdr->locked)
				{
					// Import key ID.
					exportedKeyID = (PGPByte *) pubKeyHdr + 
						pubKeyHdr->keyIDOffset;

					derr = PGPImportKeyID(exportedKeyID, &keyID);

					// Get actual key.
					if (derr.IsntError())
					{
						derr = PGPGetKeyByKeyID(allKeys, &keyID, 
							pubKeyHdr->algorithm, &pubKey);

						// If failed, then bail.
						if (derr.IsError())
						{
							derr = DualErr::NoError;
							lockedKeysOnKeyring = FALSE;
							break;
						}
					}
				}
			}

			curItem = curItem->next;
		}
	}

	(* pLockedKeysOnKeyring) = lockedKeysOnKeyring;

	if (gotAllKeys)
		PGPFreeKeySet(allKeys);

	if (gotItemList)
		FreeHeaderItemList(itemList);

	if (diskFile.Opened())
		diskFile.Close();

	return derr;
}

⌨️ 快捷键说明

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