pgpdecode.pas
来自「用DELPHI实现的 PGP 加密算法」· PAS 代码 · 共 1,048 行 · 第 1/3 页
PAS
1,048 行
procedure TPGPDecodeCustom.FinitDecode;
begin
if FKeyPropsList.Count<>0 then KeyRings.UpdateKeyRings;
with FRecipientsData do begin
if KeyIDArray<>nil then FreeMem(KeyIDArray);
PGPFreeKeySet(RecipientSet);
end;
if FPassOption=AnalyseOnly then
PGPFreeContext(FContext)
else KeyDlgFree(FContext, FtlsContext, FKeySetMain);
end;
function TPGPDecodeCustom.GetOutputFile: String;
var
FileExtension : String;
begin
if FDetachedSigVerify then begin
if FSignedFileName='' then begin
FSignedFileName:=Trim(FInputFileName);
FileExtension:=LowerCase(ExtractFileExt(FSignedFileName));
if (FileExtension='.sig') or (FileExtension='.asc') then begin
Delete(FSignedFileName, Length(FSignedFileName)-3, 4);
end;
end;
if ((FSignedFileName=FInputFileName) or not FileExists(FSignedFileName))
and Assigned(FOnGetSignedFileName) then begin
FOnGetSignedFileName(FSignedFileName);
end;
Result:=FSignedFileName;
end
else begin
if FOutputFileName='' then begin
FOutputFileName:=Trim(FInputFileName);
FileExtension:=LowerCase(ExtractFileExt(FOutputFileName));
if (FileExtension='.pgp') or (FileExtension='.gpg') or (FileExtension='.asc') then begin
Delete(FOutputFileName, Length(FOutputFileName)-3, 4);
end;
end;
if (FOutputFileName='') or (ExtractFileExt(FOutputFileName)='') or FileExists(FOutputFileName) then begin
if Assigned(FOnGetOutputFileName) then
FOnGetOutputFileName(FOutputFileName)
else FOutputFileName:='';
end;
Result:=FOutputFileName;
end;
end;
function TPGPDecodeCustom.SecureMove: PGPError;
begin
try
Result:=PGPReallocData(PGPGetDefaultMemoryMgr,
pointer(FSecureBuffer),
succ(FSecureBufferSize + FActualOutputSize),
kPGPMemoryMgrFlags_Clear);
if Result=0 then begin
Move(FAllocatedOutputBuffer[0], FSecureBuffer[FSecureBufferSize], FActualOutputSize);
inc(FSecureBufferSize, FActualOutputSize);
end;
finally
PGPFreeData(FAllocatedOutputBuffer);
end;
end;
function TPGPDecodeCustom.ShowSigInfo: PGPError;
var
Status : String;
Source : String;
ID : String;
Validity : String;
Info : String;
begin
Result:=0;
with FSigPropsRec do begin
if sStatus<>SIGNED_NOT then begin
// don't change these (constant) PGP strings, see SigEvent.c
if sStatus=SIGNED_GOOD then
Status:='Good Signature' + #10
else Status:='Bad Signature' + #10;
// these strings may be customized
if FInputFileName<>'' then begin
if FDetachedSigVerify then
Source:=ExtractFileName(FSignedFileName) + #10
else Source:=ExtractFileName(FInputFileName) + #10;
end
else Source:='(...)' + #10;
if (sStatus=SIGNED_NO_KEY) or (sUserID='') then
ID:='(' + sHexID + ')' + #10
else ID:=sUserID + #10;
// don't change these (constant) PGP strings, see SigEvent.c
if sAxiomatic then
Validity:='Implicit Trust' + #10 + sCreaTimeStr
else begin
case sValidity of
Validity_Unknown, Validity_Invalid: Validity:='Invalid Key' + #10 + sCreaTimeStr;
Validity_Marginal: Validity:='Marginal Key' + #10 + sCreaTimeStr;
Validity_Complete: Validity:='Valid Key' + #10 + sCreaTimeStr;
end;
end;
// these strings may be customized
if sUserID='' then
Info:=FLogKeyUnknown
else begin
if sStatus<>SIGNED_UNKNOWN_ALG then begin
if sVerified then begin
if sStatus=SIGNED_SIG_EXPIRED then
Info:=FLogExpSignature
else begin
if sRevoked then Info:=FLogKeyRevoked;
if sDisabled then Info:=FLogKeyDisabled;
if sExpired then Info:=FLogKeyExpired;
end;
end
else Info:=FLogBadSignature;
end
else Info:=FLogUnknownAlg;
end;
if Info<>'' then Info:=' (' + Info + ')';
if not SendPGPlogMsg(FParentHandle, PChar(Status + Source + ID + Validity + Info)) then begin
Result:=kPGPError_FeatureNotAvailable;
end;
end;
end;
end;
function TPGPDecodeCustom.WriteOutputFile(Output: PChar; OutputSize: DWord): PGPError;
var
OutputFile : THandle;
BytesWritten : DWord;
begin
OutputFile:=CreateFile(PChar(FOutputFileName), GENERIC_WRITE, 0, nil, CREATE_ALWAYS,
FILE_ATTRIBUTE_ARCHIVE or FILE_FLAG_WRITE_THROUGH, 0);
if OutputFile<>INVALID_HANDLE_VALUE then begin
try
if not WriteFile(OutputFile, Output[0], OutputSize, BytesWritten, nil)
or (BytesWritten<>OutputSize) then
Result:=kPGPError_WriteFailed
else Result:=kPGPError_NoErr;
finally
CloseHandle(OutputFile);
end;
end
else Result:=kPGPError_CantOpenFile;
end;
function TPGPDecodeCustom.Analyze(const Input: String; FileSpec: pPGPFileSpec): PGPError;
var
OptionList : pPGPOptionList;
begin
OptionList:=nil;
Result:=PGPBuildOptionList(FContext, OptionList,
[
PGPODiscardOutput(FContext, PGPTrue),
PGPOEventHandler(FContext, EventHandler, Self)
]);
if Result<>0 then Exit;
if FileSpec<>nil then begin
Result:=PGPAppendOptionList(OptionList, [PGPOInputFile(FContext, FileSpec)]);
end
else if Input<>'' then begin
Result:=PGPAppendOptionList(OptionList, [PGPOInputBuffer(FContext, @Input[1], Length(Input))]);
end;
if Result<>0 then Exit;
try
Result:=pgpEvents.PGPDecode(FContext, OptionList, PGPOLastOption(FContext));
if Result=kPGPError_UserAbort then Result:=0;
finally
PGPFreeOptionList(OptionList);
end;
end;
function TPGPDecodeCustom.GetOptionList(var OptionList: pPGPOptionList): PGPError;
begin
Result:=PGPBuildOptionList(FContext, OptionList,
[
PGPOKeySetRef(FContext, FKeySetMain),
PGPOSendNullEvents(FContext, FProgressInterval),
PGPOPassThroughKeys(FContext, PGPBoolean(PassThrough_Keys in PassThroughOptions)),
PGPOPassThroughClearSigned(FContext, PGPBoolean(PassThrough_ClearSigned in PassThroughOptions)),
PGPOPassThroughIfUnrecognized(FContext, PGPBoolean(PassThrough_Unrecognized in PassThroughOptions)),
PGPOSendEventIfKeyFound(FContext, PGPTrue),
PGPORecursivelyDecode(FContext, PGPBoolean(FRecursivelyDecode) and 1),
PGPOEventHandler(FContext, EventHandler, Self)
]);
end;
function TPGPDecodeCustom.SetOutputOption(var OptionList: pPGPOptionList): PGPError;
var
FileSpec : pPGPFileSpec;
begin
if FDetachedSigVerify then begin
if GetOutputFile<>'' then begin
FileSpec:=nil;
Result:=PGPNewFileSpecFromFullPath(FContext, PChar(FSignedFileName), FileSpec);
if Result<>0 then Exit;
try
Result:=PGPAppendOptionList(OptionList,
[PGPODetachedSig(FContext, PGPOInputFile(FContext, FileSpec), PGPOLastOption(FContext))]);
finally
PGPFreeFileSpec(FileSpec);
end;
end
else Result:=kPGPError_DetachedSignatureFound;
end
else if FileOutput then begin
if GetOutputFile<>'' then begin
Result:=PGPAppendOptionList(OptionList,
[PGPOAllocatedOutputBuffer(FContext, FAllocatedOutputBuffer, $FFFFFFFF, FActualOutputSize)]);
end
else Result:=kPGPError_CantOpenFile;
end
else begin
Result:=PGPAppendOptionList(OptionList,
[PGPOAllocatedOutputBuffer(FContext, FAllocatedOutputBuffer, $FFFFFFFF, FActualOutputSize)]);
end;
end;
function TPGPDecodeCustom.Decode(Input: String; IsFile: Longbool): Longint;
var
BugFix : Longbool;
OptionList : pPGPOptionList;
FileSpec : pPGPFileSpec;
FileHandle : THandle;
FileSizeHigh : DWord;
Output : PChar;
OutputSize : DWord;
begin
Result:=0;
BugFix:=false;
if IsFile then begin
FInputFileName:=Input;
if not FileExists(FInputFileName) then begin
if Assigned(FOnGetInputFileName) then begin
FOnGetInputFileName(FInputFileName);
if FInputFileName='' then Result:=kPGPError_FileNotFound;
end
else Result:=kPGPError_FileNotFound;
end;
end
else if Input='' then Result:=kPGPError_ItemNotFound;
if Result=0 then begin
FileSpec:=nil;
OptionList:=nil;
Result:=InitDecode;
if Result<>0 then Exit;
try
if IsFile then begin
Result:=PGPNewFileSpecFromFullPath(FContext, PChar(FInputFileName), FileSpec);
if Result<>0 then Exit;
end;
try
Result:=Analyze(Input, FileSpec);
if Result=kPGPError_BadIntegrity then Result:=0; // avoid strange error after kPGPError_SkipSection
if not FRecognized and (Input<>'') and (Input[1]>#127) then begin // avoid strange decoding error
Input:='@' + Input;
BugFix:=true;
Result:=0;
end;
if FPassOption<>AnalyseOnly then begin
if Result<>0 then Exit;
Result:=GetOptionList(OptionList);
if Result<>0 then Exit;
if IsFile then begin
FileHandle:=FileOpen(FInputFileName, fmOpenRead or fmShareDenyNone);
if FileHandle<>INVALID_HANDLE_VALUE then begin
FInputSize:=GetFileSize(FileHandle, @FileSizeHigh);
FileClose(FileHandle);
end
else FInputSize:=$FFFFFFFF;
if (FInputSize=0) or (FInputSize=$FFFFFFFF) or (FileSizeHigh<>0) then begin
Result:=kPGPError_ReadFailed;
Exit;
end;
Result:=PGPAppendOptionList(OptionList, [PGPOInputFile(FContext, FileSpec)]);
end
else begin
FInputSize:=Length(Input);
Result:=PGPAppendOptionList(OptionList, [PGPOInputBuffer(FContext, @Input[1], FInputSize)]);
end;
try
if Result<>0 then Exit;
if FDetachedSigVerify or FClearSigned then begin
Result:=SetOutputOption(OptionList);
if Result<>0 then Exit;
end
else FOutputExists:=false;
FPassOption:=DecodePass;
Result:=pgpEvents.PGPDecode(FContext, OptionList, PGPOLastOption(FContext));
try
if (FPassOption<>AnalyseOnly) and (Result=0) then begin
if not (FDetachedSigVerify or FClearSigned) then begin
Result:=SecureMove;
if Result<>0 then Exit;
FAllocatedOutputBuffer:=FSecureBuffer;
FActualOutputSize:=FSecureBufferSize;
if BugFix and (PassThrough_Unrecognized in PassThroughOptions) then begin // remove leading AT
Output:=FAllocatedOutputBuffer + 1;
OutputSize:=pred(FActualOutputSize);
end
else begin // AT already removed
Output:=FAllocatedOutputBuffer;
OutputSize:=FActualOutputSize;
end;
if FEyesOnly then begin
Result:=TempestViewer(FContext, FParentHandle, Output, OutputSize, true);
ProcessMessages;
Exit;
end;
end
else begin
if BugFix and (PassThrough_Unrecognized in PassThroughOptions) then begin // remove leading AT
Output:=FAllocatedOutputBuffer + 1;
OutputSize:=pred(FActualOutputSize);
end
else begin // AT already removed
Output:=FAllocatedOutputBuffer;
OutputSize:=FActualOutputSize;
end;
end;
if FileOutput then
WriteOutputFile(Output, OutputSize)
else begin
SetLength(FOutputBuffer, OutputSize);
Move(Output[0], FOutputBuffer[1], OutputSize);
end;
end;
except
on EOutOfMemory do Result:=kPGPError_OutOfMemory;
end;
finally
try
PGPFreeOptionList(OptionList);
finally
try
if Assigned(FOnWipePassphrase) then begin
if PGP8X then begin
FPassphraseBufSize:=MaxUTF8Length;
Utf8ToAnsiPChar(FPassphrase, FPassphrase, FPassphraseBufSize);
end;
FOnWipePassphrase(FPassphrase);
end;
finally
PGPFreeData(FAllocatedOutputBuffer);
PGPFreeData(FPassphrase);
FPassphrase:=nil;
end;
end;
end;
end;
finally
PGPFreeFileSpec(FileSpec);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?