pgpdecode.pas
来自「用DELPHI实现的 PGP 加密算法」· PAS 代码 · 共 1,048 行 · 第 1/3 页
PAS
1,048 行
end;
finally
FinitDecode;
end;
end;
// OutputHandler errors don't get returned correctly by PGP
if (Result=kPGPError_BadParams) and (FOutputError<>0) then Result:=FOutputError;
end;
function TPGPDecodeCustom.AnalyseBuffer(const DataBuffer: String): Longint;
begin
FPassOption:=AnalyseOnly;
Result:=Decode(DataBuffer, false);
end;
function TPGPDecodeCustom.AnalyseFile(const FileName: String): Longint;
begin
FPassOption:=AnalyseOnly;
Result:=Decode(FileName, true);
end;
function TPGPDecodeCustom.DecodeBuffer(const DataBuffer: String): Longint;
begin
FPassOption:=AnalysePass;
Result:=Decode(DataBuffer, false);
end;
function TPGPDecodeCustom.DecodeFile(const FileName: String): Longint;
begin
FPassOption:=AnalysePass;
Result:=Decode(FileName, true);
end;
function TPGPDecodeCustom.AnalyzeHandler(Event: pPGPEvent): PGPError;
var
SkipSection : Longbool;
begin
Result:=0;
SkipSection:=false;
with Event^.EData.AnalyzeData do begin
case FPassOption of
AnalyseOnly: begin
if Assigned(FOnGetAnalysis) then FOnGetAnalysis(FSectionNumber, TAnalysis(SectionType), SkipSection);
if SectionType<>kPGPAnalyze_Key then Result:=kPGPError_SkipSection; // avoid key data bug
end;
AnalysePass: begin
FRecognized:=(SectionType<>kPGPAnalyze_Unknown);
case SectionType of
kPGPAnalyze_Signed: FClearSigned:=true;
kPGPAnalyze_DetachedSignature: FDetachedSigVerify:=true;
end;
if FDetachedSigVerify or FClearSigned then
Result:=kPGPError_UserAbort
else if SectionType<>kPGPAnalyze_Key then Result:=kPGPError_SkipSection; // avoid key data bug
end;
DecodePass: begin
if Assigned(FOnGetAnalysis) then FOnGetAnalysis(FSectionNumber, TAnalysis(SectionType), SkipSection);
Result:=(ord(SkipSection) and 1)*kPGPError_SkipSection;
end;
end;
end;
end;
function TPGPDecodeCustom.RecipientsHandler(Event: pPGPEvent): PGPError;
var
KeyIDArraySize: PGPSize;
begin
Result:=0;
with Event^.EData.RecipientsData do begin
PGPIncKeySetRefCount(RecipientSet);
FRecipientsData.RecipientSet:=RecipientSet;
FRecipientsData.KeyCount:=KeyCount;
if PGP7X then
KeyIDArraySize:=SizeOf(TPGPKeyID7)*KeyCount
else KeyIDArraySize:=SizeOf(TPGPKeyID6)*KeyCount;
GetMem(FRecipientsData.KeyIDArray, KeyIDArraySize);
if FRecipientsData.KeyIDArray<>nil then Move(KeyIDArray^, FRecipientsData.KeyIDArray^, KeyIDArraySize)
end;
end;
function TPGPDecodeCustom.PassphraseHandler(Event: pPGPEvent): PGPError;
var
Cancel : Longbool;
KeyPropsList : TKeyPropsList;
BadPassphrase : Longbool;
DecryptionKey : pPGPKey;
begin
Result:=0;
Cancel:=false;
FPassphraseBufSize:=MaxUTF8Length;
with Event^.EData.PassphraseData do begin
KeyPropsList:=TKeyPropsList.Create(0, spgpKeyPropFlag_IDComplete);
try
if (FPassphrase=nil) or (FSectionNumber=FPassSection) then begin
FPassSection:=FSectionNumber;
BadPassphrase:=false;
if FPassphrase<>nil then begin
PGPFreeData(FPassphrase);
FPassphrase:=nil;
BadPassphrase:=true;
end;
if Assigned(FOnEnterPassphrase) then begin
if not boolean(IsConventional) then begin
Result:=GetKeySetProps(FContext, KeySet, KeyPropsList, spgpKeyPropFlag_IDComplete,
KeyFilterFlag_CanDecrypt, UserID_Ordering);
if Result=0 then Result:=kPGPError_SecretKeyNotFound;
end;
if Result>=0 then begin
Result:=kPGPError_UserAbort;
FPassphrase:=PGPNewSecureData(PGPGetDefaultMemoryMgr, FPassphraseBufSize, kPGPMemoryMgrFlags_Clear);
if FPassphrase<>nil then begin
FOnEnterPassphrase(FPassphrase, KeyPropsList, boolean(IsConventional), BadPassphrase, Cancel);
if not Cancel then begin
if PGP8X then AnsiToUtf8PChar(FPassphrase, FPassphrase, FPassphraseBufSize);
end
else Exit;
end
else begin
Result:=kPGPError_OutOfMemory;
Exit;
end;
end
else Exit;
end
else begin
if boolean(IsConventional) then
Result:=ConvDecPassphraseDialog(FContext, FPassphrase, FPassDlgPrompt, FParentHandle)
else with FRecipientsData do begin
Result:=DecryptionPassphraseDialog(FContext, RecipientSet, KeyCount, KeyIDArray,
DecryptionKey, FPassphrase, true, FPassDlgPrompt, FParentHandle);
end;
if Result<>0 then Exit;
end;
end
else FPassSection:=FSectionNumber;
finally
KeyPropsList.Free;
end;
end;
Result:=PGPAddJobOptions(Event^.Job, PGPOPassphrase(FContext, FPassphrase), PGPOLastOption(FContext));
end;
function TPGPDecodeCustom.KeyFoundHandler(Event: pPGPEvent): PGPError;
var
KeySetSelected: pPGPKeySet;
begin
Result:=0; // don't cancel decoding whatever happens here
with Event^.EData.KeyFoundData do begin
if PGP7X then begin
try
if FQueryAddKeys then begin
KeySetSelected:=PGPPeekKeyDBRootKeySet(KeysFound);
Result:=GetExclusiveKeySet(KeySetSelected, FKeySetMain, FContext, FIgnoreKnownFlag);
if Result<>0 then Exit;
if FKeyDlgPrompt<>'' then begin
SelectAddKeysToKeyRing(FContext, FtlsContext, PGPPeekKeyDBRootKeySet(KeysFound), FKeySetMain,
FKeyPropsList, PChar(FKeyDlgPrompt),
false, spgpKeyPropFlag_IDFlags,
FParentHandle);
end
else AddKeysToKeyRing(FContext, FKeySetMain, KeysFound, FKeyPropsList, spgpKeyPropFlag_IDFlags);
end;
finally
PGPFreeKeyDB(PGPPeekKeySetKeyDB(KeysFound));
end;
end
else begin
try
if FQueryAddKeys then begin
Result:=GetExclusiveKeySet(KeysFound, FKeySetMain, FContext, FIgnoreKnownFlag);
if Result<>0 then Exit;
if FKeyDlgPrompt<>'' then begin
SelectAddKeysToKeyRing(FContext, FtlsContext, KeysFound, FKeySetMain,
FKeyPropsList, PChar(FKeyDlgPrompt),
false, spgpKeyPropFlag_IDFlags,
FParentHandle);
end
else AddKeysToKeyRing(FContext, FKeySetMain, KeysFound, FKeyPropsList, spgpKeyPropFlag_IDFlags);
end;
finally
PGPFreeKeySet(KeysFound);
end;
end;
end;
end;
// causes trouble when used with FPassThroughClearSigned on clear signed input
function TPGPDecodeCustom.OutputHandler(Event: pPGPEvent): PGPError;
begin
Result:=0;
with Event^.EData.OutputData do begin
if boolean(ForYourEyesOnly) then FEyesOnly:=true;
if FOutputExists then
Result:=SecureMove
else if FFileOutput and not FEyesOnly then begin
if FOutputFileName='' then begin
if SuggestedName<>'' then
FOutputFileName:=ExtractFilePath(FInputFileName) + SuggestedName
else FOutputFileName:=FInputFileName;
end;
if GetOutputFile='' then Result:=kPGPError_CantOpenFile;
end;
if Result=0 then begin
Result:=PGPAddJobOptions(Event^.Job,
PGPOAllocatedOutputBuffer(FContext, FAllocatedOutputBuffer,
$FFFFFFFF, FActualOutputSize),
PGPOLastOption(FContext));
FOutputExists:=true;
end
else FOutputError:=Result;
end;
end;
function TPGPDecodeCustom.SignatureHandler(Event: pPGPEvent): PGPError;
var
IsSigningKey : PGPBoolean;
PGPSignKeyID : TPGPKeyID7;
SignKeyID : TKeyID;
KeysFound : Pointer;
begin
Result:=0; // don't cancel decoding whatever happens here
IsSigningKey:=PGPFalse;
FillChar(FSigPropsRec, SizeOf(TSigPropsRec), 0);
if PGP7X then with Event^.EData.SignatureData.PGPEventSignatureData7, FSigPropsRec do begin
if boolean(Checked)
and (PGPGetKeyDBObjBooleanProperty(SigningKey, kPGPKeyProperty_IsSigningKey, IsSigningKey)=0) then begin
sHexID:=GetKeyPropKeyID(SigningKey);
sUserID:=GetKeyPropUserID(SigningKey);
sCreaTimeNum:=PGPGetStdTimeFromPGPTime(CreationTime);
sCreaTimeStr:=UnixTimeToLocalTimeStr(sCreaTimeNum);
sChecked:=boolean(Checked);
sVerified:=boolean(Verified);
sValidity:=TValidityLevel(KeyValidity);
sRevoked:=boolean(KeyRevoked);
sDisabled:=boolean(KeyDisabled);
sExpired:=boolean(KeyExpired);
sAxiomatic:=GetKeyPropIsAxiomatic(SigningKey);
if PGP8X and (ExpirationPeriod<>0) then begin
sExpTimeNum:=sCreaTimeNum + ExpirationPeriod;
sExpTimeStr:=UnixTimeToLocalTimeStr(sExpTimeNum);
end;
if boolean(IsSigningKey) then begin
sStatus:=TSigStatus(Checked + Verified);
if PGP8X and (sStatus=SIGNED_GOOD) and (ExpirationPeriod<>0) and (sExpTimeNum<SystemTimeToUnixTimeNum) then begin
sStatus:=SIGNED_SIG_EXPIRED;
end;
end
else sStatus:=SIGNED_UNKNOWN_ALG;
end
else begin
Move(SigningKeyID, PGPSignKeyID, SizeOf(TPGPKeyID7));
Result:=PGPGetKeyIDString(PGPSignKeyID, kPGPKeyIDString_Full, SignKeyID);
if Result=0 then begin
sCreaTimeNum:=PGPGetStdTimeFromPGPTime(CreationTime);
sCreaTimeStr:=UnixTimeToLocalTimeStr(sCreaTimeNum);
sHexID:=SignKeyID;
end;
sStatus:=SIGNED_NO_KEY;
if (Result=0) and FGetKeyFromServer then begin
KeysFound:=nil;
Result:=KeyServerDialog(FContext, FtlsContext, FKeySetMain, SignKeyID, pPGPKeyDB(KeysFound), FParentHandle);
if (Result=0) and (KeysFound<>nil) then begin
try
if FKeyDlgPrompt<>'' then begin
SelectAddKeysToKeyRing(FContext, FtlsContext, PGPPeekKeyDBRootKeySet(pPGPKeyDB(KeysFound)), FKeySetMain,
FKeyPropsList, PChar(FKeyDlgPrompt),
false, spgpKeyPropFlag_IDFlags,
FParentHandle);
end;
PGPAddJobOptions(Event^.Job,
PGPOKeySetRef(FContext, PGPPeekKeyDBRootKeySet(pPGPKeyDB(KeysFound))),
PGPOLastOption(FContext));
finally
PGPFreeKeyDB(pPGPKeyDB(KeysFound));
end;
end;
end;
Result:=0;
end;
sDetached:=FDetachedSigVerify;
end
else with Event^.EData.SignatureData.PGPEventSignatureData6, FSigPropsRec do begin
if boolean(Checked)
and (PGPGetKeyDBObjBooleanProperty(SigningKey, kPGPKeyProperty_IsSigningKey, IsSigningKey)=0) then begin
sHexID:=GetKeyPropKeyID(SigningKey);
sUserID:=GetKeyPropUserID(SigningKey);
sCreaTimeNum:=PGPGetStdTimeFromPGPTime(CreationTime);
sCreaTimeStr:=UnixTimeToLocalTimeStr(sCreaTimeNum);
sChecked:=boolean(Checked);
sVerified:=boolean(Verified);
sValidity:=TValidityLevel(KeyValidity);
sRevoked:=boolean(KeyRevoked);
sDisabled:=boolean(KeyDisabled);
sExpired:=boolean(KeyExpired);
sAxiomatic:=GetKeyPropIsAxiomatic(SigningKey);
if boolean(IsSigningKey) then
sStatus:=TSigStatus(Checked + Verified)
else sStatus:=SIGNED_UNKNOWN_ALG;
end
else begin
Move(SigningKeyID, PGPSignKeyID, SizeOf(TPGPKeyID6));
Result:=PGPGetKeyIDString(PGPSignKeyID, kPGPKeyIDString_Full, SignKeyID);
if Result=0 then begin
sCreaTimeNum:=PGPGetStdTimeFromPGPTime(CreationTime);
sCreaTimeStr:=UnixTimeToLocalTimeStr(sCreaTimeNum);
sHexID:=SignKeyID;
end;
sStatus:=SIGNED_NO_KEY;
if (Result=0) and FGetKeyFromServer then begin
KeysFound:=nil;
Result:=KeyServerDialog(FContext, FtlsContext, FKeySetMain, SignKeyID, pPGPKeySet(KeysFound), FParentHandle);
if (Result=0) and (KeysFound<>nil) then begin
try
if FKeyDlgPrompt<>'' then begin
SelectAddKeysToKeyRing(FContext, FtlsContext, pPGPKeySet(KeysFound), FKeySetMain,
FKeyPropsList, PChar(FKeyDlgPrompt),
false, spgpKeyPropFlag_IDFlags,
FParentHandle);
end;
PGPAddJobOptions(Event^.Job,
PGPOKeySetRef(FContext, pPGPKeySet(KeysFound)),
PGPOLastOption(FContext));
finally
PGPFreeKeySet(pPGPKeySet(KeysFound));
end;
end;
end;
Result:=0;
end;
sDetached:=FDetachedSigVerify;
end;
if FShowSigLog then ShowSigInfo;
if Assigned(FOnGetSignature) then FOnGetSignature(SigPropsRec);
end;
function TPGPDecodeCustom.EndLexHandler(Event: pPGPEvent): PGPError;
begin
Result:=0;
with FRecipientsData do begin
if KeyIDArray<>nil then FreeMem(KeyIDArray);
PGPFreeKeySet(RecipientSet);
end;
FillChar(FRecipientsData, SizeOf(TPGPEventRecipientsData), 0);
end;
end.
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?