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

📄 pgpdisklowlevelutils.cpp

📁 vc环境下的pgp源码
💻 CPP
📖 第 1 页 / 共 2 页
字号:

	// Assume always enough room to store main header in beginning.
	if (derr.IsntError())
	{
		PGPBoolean	usedUpReservedBlocks	= FALSE;
		PGPUInt32	blocksCurItem, nextBlock, remainingBlocks;

		curItem = itemList;

		nextBlock = 0;
		remainingBlocks = mainHdr->numHeaderBlocks;

		// Calculate new offsets for each header.
		while (IsntNull(curItem))
		{
			blocksCurItem = (PGPUInt32) CeilDiv(curItem->hdr->headerSize, 
				kDefaultBlockSize);

			nextItem = curItem->next;

			// Any space left at beginning of file?
			if (!usedUpReservedBlocks)
			{
				if (blocksCurItem <= remainingBlocks)
				{
					remainingBlocks -= blocksCurItem;
					nextBlock += blocksCurItem;

					// OK to put at current offset.
					curItem->hdr->nextHeaderOffset = nextBlock * 
						kDefaultBlockSize;
				}
				else
				{
					nextBlock = blockAfterData + blocksCurItem;
					usedUpReservedBlocks = TRUE;

					// Exhausted bytes at beginning of file.
					if (IsntNull(curItem->prev))
					{
						curItem->prev->hdr->nextHeaderOffset = 
							blockAfterData * kDefaultBlockSize;
					}

					curItem->hdr->nextHeaderOffset = nextBlock * 
						kDefaultBlockSize;
				}
			}
			else
			{
				nextBlock += blocksCurItem;

				// Already after end of file.
				curItem->hdr->nextHeaderOffset = 
					nextBlock * kDefaultBlockSize;
			}

			if (IsNull(nextItem))
				curItem->hdr->nextHeaderOffset = 0;

			curItem = nextItem;
		}
	}

	// Write out all the headers.
	if (derr.IsntError())
	{
		PGPUInt64 curOffset;

		curItem = itemList;
		curOffset = 0;

		while (derr.IsntError() && IsntNull(curItem))
		{
			derr = WritePGPdiskFileHeaderAtOffset(diskFile, curOffset, 
				curItem->hdr);

			curOffset = curItem->hdr->nextHeaderOffset;
			curItem = curItem->next;
		}
	}

	// Restore main and alternate header.
	if (derr.IsntError())
	{
		derr = diskFile->GetLength(&length);
	}

	if (derr.IsntError())
	{
		mainHdr->numFileBlocks = (PGPUInt32) (length/kDefaultBlockSize + 
			kPGPdiskAlternateHeaderBlocks);

		derr = diskFile->SetLength(length + kPGPdiskAlternateHeaderBlocks *
			kDefaultBlockSize);
	}

	if (derr.IsntError())
	{
		derr = WritePGPdiskFileMainHeader(diskFile, mainHdr);
	}

	return derr;
}

// ReadPGPdiskFilePrimaryHeader reads in and verifies the primary PGPdisk
// header.

DualErr
ReadPGPdiskFilePrimaryHeader(File *diskFile, PGPdiskFileHeader **fileHeader)
{
	DualErr		derr;
	PGPBoolean	readHeader	= FALSE;
	PGPUInt64	bytesFile;

	pgpAssertAddrValid(diskFile, File);
	pgpAssert(diskFile->Opened());
	pgpAssertAddrValid(fileHeader, PGPdiskFileHeader *);

	derr = ReadPGPdiskFileHeaderAtOffset(diskFile, 0, 
		(PGPdiskFileHeaderInfo **) fileHeader);

	readHeader = derr.IsntError();

	if (derr.IsntError())
	{
		derr = diskFile->GetLength(&bytesFile);
	}

	if (derr.IsntError())
	{
		derr = VerifyPGPdiskFileMainHeader((* fileHeader), bytesFile);
	}

	if (derr.IsError())
	{
		if (readHeader)
			FreePGPdiskFileHeader((PGPdiskFileHeaderInfo *) (* fileHeader));
	}

	return derr;
}

// WritePGPdiskFilePrimaryHeader verifies and writes out the primary PGPdisk
// file header to a PGPdisk file.

DualErr
WritePGPdiskFilePrimaryHeader(
	File					*diskFile, 
	const PGPdiskFileHeader	*fileHeader)
{
	DualErr		derr;
	PGPUInt64	bytesFile;
	
	pgpAssertAddrValid(diskFile, File);
	pgpAssert(diskFile->Opened());
	pgpAssertAddrValid(fileHeader, PGPdiskFileHeader);

	derr = diskFile->GetLength(&bytesFile);

	if (derr.IsntError())
	{
		derr = WritePGPdiskFileHeaderAtOffset(diskFile, 0, 
			(PGPdiskFileHeaderInfo *) fileHeader);
	}

	return derr;
}

// ReadPGPdiskFileAlternateHeader reads in and verifies the alternate PGPdisk
// header.

DualErr
ReadPGPdiskFileAlternateHeader(File *diskFile, PGPdiskFileHeader **fileHeader)
{
	DualErr		derr;
	PGPBoolean	readHeader	= FALSE;
	PGPUInt64	bytesFile;

	pgpAssertAddrValid(diskFile, File);
	pgpAssert(diskFile->Opened());
	pgpAssertAddrValid(fileHeader, PGPdiskFileHeader *);

	derr = diskFile->GetLength(&bytesFile);

	if (derr.IsntError())
	{
		derr = ReadPGPdiskFileHeaderAtOffset(diskFile, 
			bytesFile - kPGPdiskAlternateHeaderSize, 
			(PGPdiskFileHeaderInfo **) fileHeader);

		readHeader = derr.IsntError();
	}

	if (derr.IsError())
	{
		if (readHeader)
			FreePGPdiskFileHeader((PGPdiskFileHeaderInfo *) (* fileHeader));
	}

	return derr;
}

// WritePGPdiskFileAlternateHeader verifies and writes out the alternate
// PGPdisk file header to a PGPdisk file.

DualErr
WritePGPdiskFileAlternateHeader(
	File					*diskFile, 
	const PGPdiskFileHeader	*fileHeader)
{
	DualErr		derr;
	PGPUInt64	bytesFile;
	
	pgpAssertAddrValid(diskFile, File);
	pgpAssert(diskFile->Opened());
	pgpAssertAddrValid(fileHeader, PGPdiskFileHeader);

	derr = diskFile->GetLength(&bytesFile);

	if (derr.IsntError())
	{
		// Alternate header is ALWAYS 'kPGPdiskAlternateHeaderSize' bytes
		// from the end of the file.

		derr = WritePGPdiskFileHeaderAtOffset(diskFile, 
			bytesFile - kPGPdiskAlternateHeaderSize, 
			(PGPdiskFileHeaderInfo *) fileHeader);
	}
	
	return derr;
}

// VerifyPGPdiskFileMainHeader verifies certain fields of the given PGPdisk
// file header for a file of the given size.

DualErr 
VerifyPGPdiskFileMainHeader(
	const PGPdiskFileHeader	*fileHeader,
	PGPUInt64				bytesFile)
{
	pgpAssertAddrValid(fileHeader, PGPdiskFileHeader);
		
	if (strncmp(fileHeader->headerInfo.headerMagic, kPGPdiskHeaderMagic, 4) 
		!= 0)
	{
		return DualErr(kPGDMinorError_BadHeaderMagic);
	}

	if (fileHeader->headerInfo.headerSize > sizeof(PGPdiskFileHeader))
	{
		return DualErr(kPGDMinorError_BadHeaderSize);
	}

	if (fileHeader->headerInfo.headerCRC != 
		ComputePGPdiskFileHeaderCRC((PGPdiskFileHeaderInfo *) fileHeader))
	{
		return DualErr(kPGDMinorError_BadHeaderCRC);
	}

	if (strncmp(fileHeader->headerInfo.headerType, 
		kPGPdiskPrimaryHeaderType, 4) != 0)
	{
		return DualErr(kPGDMinorError_InvalidHeaderType);
	}

	if (fileHeader->majorVersion > kPGPdiskPrimaryHeaderMajorVersion)
	{
		return DualErr(kPGDMinorError_NewerHeaderVersion);
	}

	if ((fileHeader->algorithm != kBrokenCASTEncryptionAlgorithm) && 
		(fileHeader->algorithm != kCASTEncryptionAlgorithm) && 
		(fileHeader->algorithm != kCopyDataEncryptionAlgorithm))
	{
		return DualErr(kPGDMinorError_InvalidAlgorithm);
	}

	if ((PGPUInt64) fileHeader->numFileBlocks*kDefaultBlockSize != bytesFile)
	{
		return DualErr(kPGDMinorError_InvalidTotalFileSize);
	}

	if (fileHeader->numDataBlocks > fileHeader->numFileBlocks)
	{
		return DualErr(kPGDMinorError_InvalidFileDataSize);
	}

	if (fileHeader->numHeaderBlocks + fileHeader->numDataBlocks > 
		fileHeader->numFileBlocks)
	{
		return DualErr(kPGDMinorError_InvalidHeaderBlocks);
	}

	return DualErr::NoError;
}

// ComputePGPdiskFileHeaderCRC computes and returns a checksum over the given
// PGPdisk file header.

CRC32 
ComputePGPdiskFileHeaderCRC(PGPdiskFileHeaderInfo *fileHeader)
{
	CRC32	saveCRCValue;
	CRC32	crc;
	
	pgpAssertAddrValid(fileHeader, PGPdiskFileHeaderInfo);

	// Always set CRC value to zero before computing.
	saveCRCValue = fileHeader->headerCRC;
	
	fileHeader->headerCRC = 0;
	
	crc = ComputeCRC32((const PGPUInt32 *) fileHeader, 
		fileHeader->headerSize / sizeof(PGPUInt32));
	
	fileHeader->headerCRC = saveCRCValue;
	
	return crc;
}

// UpdatePGPdiskFileHeaderCRC stores the checksum of the PGPdisk file header
// in its 'headerCRC' member.

void 
UpdatePGPdiskFileHeaderCRC(PGPdiskFileHeaderInfo *fileHeader)
{
	pgpAssertAddrValid(fileHeader, PGPdiskFileHeaderInfo);

	fileHeader->headerCRC = ComputePGPdiskFileHeaderCRC(fileHeader);
}


/////////////////////////////////////////
// Low-level passphrase utility functions
/////////////////////////////////////////

// FindMatchingPassphrase determines if the specified passphrase is
// legitimate for any of the keys.

DualErr 
FindMatchingPassphrase(
	const PGPdiskFileHeader	*fileHeader, 
	SecureString			*passphrase, 
	PGPUInt16				*index)
{
	DualErr		derr;
	PGPBoolean	foundKey	= FALSE;
	
	pgpAssertAddrValid(fileHeader, PGPdiskFileHeader);
	pgpAssertAddrValid(passphrase, SecureString);
	pgpAssertAddrValid(index, PGPUInt16);

	pgpAssert(kMasterPassphraseIndex == 0);

	for (PGPUInt16 keyIndex = 0; keyIndex <= kMaxAlternatePassphrases; 
		++keyIndex)
	{
		const PassphraseKey *userInfo = NULL;

		userInfo = GetPassphraseKeyPtr(fileHeader, keyIndex);

		if (userInfo->inUse)
		{
			derr = VerifyPassphraseKey(userInfo, &fileHeader->salt, 
				passphrase);

			foundKey = derr.IsntError();

			if (foundKey)
			{
				(* index) = keyIndex;
				break;
			}
		}
	}

	if (!foundKey)
		derr = DualErr(kPGDMinorError_IncorrectPassphrase);

	return derr;
}

// GetPassphraseKeyPtr returns a pointer to the PassphraseKey corresponding to
// the index.

const PassphraseKey * 
GetPassphraseKeyPtr(
	const PGPdiskFileHeader	*fileHeader, 
	PGPUInt16				whichPassphrase)
{
	const PassphraseKey *userInfo = NULL;
	
	// 0 being master, 1...kMaxAlternatePassphrases alternates.
	pgpAssert(whichPassphrase <= kMaxAlternatePassphrases);
		
	if (whichPassphrase == kMasterPassphraseIndex)
		userInfo = &fileHeader->masterPassphrase;
	else
		userInfo = &fileHeader->otherPassphrases[whichPassphrase-1];
			
	return userInfo;
}

// VerifyPassphraseKey verifies that the specified passphrase unlocks the
// specified key.

DualErr 
VerifyPassphraseKey(
	const PassphraseKey		*userInfo, 
	const PassphraseSalt	*salt, 
	SecureString			*passphrase)
{
	DualErr	derr;
	CASTKey	*decryptedKey;

	SecureMemory smDecryptedKey(sizeof(CASTKey));

	pgpAssertAddrValid(userInfo, PassphraseKey);
	pgpAssertAddrValid(passphrase, SecureString);
	pgpAssertAddrValid(salt, PassphraseSalt);
	pgpAssert(userInfo->inUse);

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

	if (derr.IsntError())
	{
		// Set the locked memory pointer.
		decryptedKey = (CASTKey *) smDecryptedKey.GetPtr();

		// Attempt to decypt the key
		derr = DecryptPassphraseKey(userInfo, salt, passphrase,
			decryptedKey);
	}

	return derr;
}

// VerifyFileHeaderPassphrase verifies that a passphrase is valid for the
// specified passphrase index in the specified header.

DualErr
VerifyFileHeaderPassphrase(
	const PGPdiskFileHeader	*fileHeader,
	SecureString			*passphrase,
	PGPUInt16				whichKey)
{
	DualErr				derr;
	const PassphraseKey	*userInfo;
	
	pgpAssertAddrValid(fileHeader, PGPdiskFileHeader);
	pgpAssertAddrValid(passphrase, SecureString);
	
	userInfo = GetPassphraseKeyPtr(fileHeader, whichKey);

	if (!userInfo->inUse)
		derr = DualErr(kPGDMinorError_IncorrectPassphrase);

	if (derr.IsntError())
	{
		derr = VerifyPassphraseKey(userInfo, &fileHeader->salt, passphrase);
	}

	return derr;
}

⌨️ 快捷键说明

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