pgpdecode.pas

来自「用DELPHI实现的 PGP 加密算法」· PAS 代码 · 共 1,048 行 · 第 1/3 页

PAS
1,048
字号
{$J+,Z4}
unit PGPDecode;

{------------------------------------------------------------------------------}
{                                                                              }
{                 This unit is partly based on Steve Heller's                  }
{         SPGP sources available from http://www.oz.net/~srheller/spgp/        }
{                                                                              }
{                Portions created by Michael in der Wiesche are                }
{              Copyright (C) 2001-2003 by Michael in der Wiesche               }
{                                                                              }
{------------------------------------------------------------------------------}

interface

uses
  Windows,
  Classes,
  SysUtils,
  KeyPropTypes,
  UTF8,
  pgpBase,
  pgpErrors,
  pgpPubTypes,
  pgpUtilities,
  pgpOptionList,
  pgpMemoryMgr,
  pgpEvents,
  pgpKeys,
  pgpTLS,
  pgpSC,
  KeyFuncs,
  PGPDialogs;

type
  TSigStatus = (
    SIGNED_NOT,
    SIGNED_BAD,
    SIGNED_GOOD,
    SIGNED_NO_KEY,
    SIGNED_UNKNOWN_ALG,
    SIGNED_SIG_EXPIRED
  );
  TSigPropsRec = Record
    sStatus: TSigStatus;
    sHexID: String;
    sUserID: String;
    sCreaTimeStr: String;
    sCreaTimeNum: DWord;
    sChecked: Longbool;
    sVerified: Longbool;
    sValidity: TValidityLevel;
    sRevoked: Longbool;
    sDisabled: Longbool;
    sExpired: Longbool;
    sDetached: Longbool;
    sAxiomatic: Longbool;
    sExpTimeNum: Longint;
    sExpTimeStr: String;
  end;
  TAnalysis = (
    ENCRYPTED,
    SIGNED,
    DETACHED_SIGNATURE,
    KEY,
    UNKNOWN,
    X509_CERTIFICATE
  );
  TPassThroughOption = (
    PassThrough_Keys,
    PassThrough_ClearSigned,
    PassThrough_Unrecognized
  );
  TPassOption = (
    AnalyseOnly,
    AnalysePass,
    DecodePass
  );
  TPassThroughOptions = Set of TPassThroughOption;
  TOnGetAnalysis = procedure(SectionNumber: Longint; SectionType: TAnalysis; var SkipSection: Longbool) of Object;
  TOnGetInputFileName = procedure(var SuggestedName: String) of Object;
  TOnGetOutputFileName = procedure(var SuggestedName: String) of Object;
  TOnGetSignedFileName = procedure(var SuggestedName: String) of Object;
  TOnEnterPassphrase = procedure(const Passphrase: PChar;
				 const DecryptionKeyList: TKeyPropsList;
				 Conventional, BadPassphrase: Longbool;
				 var Cancel: Longbool) of Object;
  TOnGetSignature = procedure(const SigProps: TSigPropsRec) of Object;
  TOnShowProgress = procedure(BytesProcessed, BytesTotal: Longint) of Object;
  TOnWipePassphrase = procedure(const Passphrase: PChar) of Object;
  TPGPDecodeCustom = class(TComponent)
  private
    // internal
    FContext: pPGPContext;
    FKeySetMain: pPGPKeySet;
    FtlsContext: pPGPTLSContext;
    FAllocatedOutputBuffer: PChar;
    FActualOutputSize: PGPSize;
    FPassphraseBufSize: Cardinal;
    FInputSize: PGPSize;
    FInputFileName: String;
    FOutputBuffer: String;
    FClearSigned: Longbool;
    FDetachedSigVerify: Longbool;
    FEyesOnly: Longbool;
    FOutputExists: Longbool;
    FRecognized: Longbool;
    FOutputError: PGPError;
    FPassOption: TPassOption;
    FPassphrase: PChar;
    FPassSection: PGPUInt32;
    FRecipientsData: TPGPEventRecipientsData;
    FSectionNumber: PGPUInt32;
    FSecureBuffer: PChar;
    FSecureBufferSize: PGPSize;
    // properties
    FFileOutput: Longbool;
    FGetKeyFromServer: Longbool;
    FIgnoreKnownFlag: Longint;
    FLogBadSignature: String;
    FLogExpSignature: String;
    FLogKeyDisabled: String;
    FLogKeyExpired: String;
    FLogKeyRevoked: String;
    FLogKeyUnknown: String;
    FLogUnknownAlg: String;
    FParentHandle: THandle;
    FPassThroughOptions: TPassThroughOptions;
    FProgressInterval: Cardinal;
    FQueryAddKeys: Longbool;
    FRecursivelyDecode: Longbool;
    FShowSigLog: Longbool;
    FKeyDlgPrompt: String;
    FPassDlgPrompt: String;
    FOutputFileName: String;
    FSignedFileName: String;
    FKeyPropsList: TKeyPropsList;
    FSigPropsRec: TSigPropsRec;
    // events
    FOnGetAnalysis: TOnGetAnalysis;
    FOnGetInputFileName: TOnGetInputFileName;
    FOnGetOutputFileName: TOnGetOutputFileName;
    FOnGetSignedFileName: TOnGetSignedFileName;
    FOnEnterPassphrase: TOnEnterPassphrase;
    FOnGetSignature: TOnGetSignature;
    FOnShowProgress: TOnShowProgress;
    FOnWipePassphrase: TOnWipePassphrase;
    procedure SetRecursive(Value: Longbool);
    function  InitDecode: PGPError;
    procedure FinitDecode;
    function  GetOutputFile: String;
    function  SecureMove: PGPError;
    function  ShowSigInfo: PGPError;
    function  WriteOutputFile(Output: PChar; OutputSize: DWord): PGPError;
    function  Analyze(const Input: String; FileSpec: pPGPFileSpec): PGPError;
    function  GetOptionList(var OptionList: pPGPOptionList): PGPError;
    function  SetOutputOption(var OptionList: pPGPOptionList): PGPError;
    function  Decode(Input: String; IsFile: Longbool): Longint;
    function  AnalyzeHandler(Event: pPGPEvent): PGPError;
    function  RecipientsHandler(Event: pPGPEvent): PGPError;
    function  PassphraseHandler(Event: pPGPEvent): PGPError;
    function  KeyFoundHandler(Event: pPGPEvent): PGPError;
    function  OutputHandler(Event: pPGPEvent): PGPError;
    function  SignatureHandler(Event: pPGPEvent): PGPError;
    function  EndLexHandler(Event: pPGPEvent): PGPError;
  protected
    property OutputBuffer: String
      read FOutputBuffer;
    property DetachedSignature: Longbool
      read FDetachedSigVerify;
    property IgnoreKnownFlag: Longint
      write FIgnoreKnownFlag;
    property SigPropsRec: TSigPropsRec
      read FSigPropsRec;
    property KeyPropsList: TKeyPropsList
      read FKeyPropsList;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
    function AnalyseBuffer(const DataBuffer: String): Longint; virtual;
    function AnalyseFile(const FileName: String): Longint; virtual;
    function DecodeBuffer(const DataBuffer: String): Longint; virtual;
    function DecodeFile(const FileName: String): Longint; virtual;
    property ParentHandle: THandle
      read FParentHandle
      write FParentHandle;
  published
    property FileOutput: Longbool
      read FFileOutput
      write FFileOutput;
    property GetKeyFromServer: Longbool
      read FGetKeyFromServer
      write FGetKeyFromServer;
    property LogBadSignature: String
      read FLogBadSignature
      write FLogBadSignature;
    property LogExpSignature: String
      read FLogExpSignature
      write FLogExpSignature;
    property LogKeyDisabled: String
      read FLogKeyDisabled
      write FLogKeyDisabled;
    property LogKeyExpired: String
      read FLogKeyExpired
      write FLogKeyExpired;
    property LogKeyRevoked: String
      read FLogKeyRevoked
      write FLogKeyRevoked;
    property LogKeyUnknown: String
      read FLogKeyUnknown
      write FLogKeyUnknown;
    property LogUnknownAlg: String
      read FLogUnknownAlg
      write FLogUnknownAlg;
    property PassThroughOptions: TPassThroughOptions
      read FPassThroughOptions
      write FPassThroughOptions;
    property ProgressInterval: Cardinal
      read FProgressInterval
      write FProgressInterval;
    property RecursivelyDecode: Longbool
      read FRecursivelyDecode
      write SetRecursive;
    property QueryAddKeys: Longbool
      read FQueryAddKeys
      write FQueryAddKeys;
    property ShowSigLog: Longbool
      read FShowSigLog
      write FShowSigLog;
    property KeyDlgPrompt: String
      read FKeyDlgPrompt
      write FKeyDlgPrompt;
    property PassDlgPrompt: String
      read FPassDlgPrompt
      write FPassDlgPrompt;
    property OutputFileName: String
      read FOutputFileName
      write FOutputFileName;
    property SignedFileName: String
      read FSignedFileName
      write FSignedFileName;
    property OnGetAnalysis: TOnGetAnalysis
      read FOnGetAnalysis
      write FOnGetAnalysis;
    property OnGetInputFileName: TOnGetInputFileName
      read FOnGetInputFileName
      write FOnGetInputFileName;
    property OnGetSignedFileName: TOnGetSignedFileName
      read FOnGetSignedFileName
      write FOnGetSignedFileName;
    property OnGetOutputFileName: TOnGetOutputFileName
      read FOnGetOutputFileName
      write FOnGetOutputFileName;
    property OnEnterPassphrase: TOnEnterPassphrase
      read FOnEnterPassphrase
      write FOnEnterPassphrase;
    property OnGetSignature: TOnGetSignature
      read FOnGetSignature
      write FOnGetSignature;
    property OnShowProgress: TOnShowProgress
      read FOnShowProgress
      write FOnShowProgress;
    property OnWipePassphrase: TOnWipePassphrase
      read FOnWipePassphrase
      write FOnWipePassphrase;
  end;

implementation

function EventHandler(Context: pPGPContext; Event: pPGPEvent; UserValue: PGPUserValue): PGPError; cdecl;
begin
  Result:=0;
  with TPGPDecodeCustom(UserValue) do begin
    case Event^.EType of
      kPGPEvent_NullEvent:		if (FPassOption=DecodePass)
      					and not (FDetachedSigVerify or FClearSigned) then begin
					  if TMethod(FOnShowProgress).Code<>nil then begin
					    // BytesTotal always stays 0 => use FInputSize
					    with Event^.EData.NullData do FOnShowProgress(BytesWritten, FInputSize);
					  end;
					  ProcessMessages;
					end;
      kPGPEvent_InitialEvent:		;
      kPGPEvent_FinalEvent:		;
      kPGPEvent_ErrorEvent:	  	Result:=Event^.EData.ErrorData.Error;
      kPGPEvent_WarningEvent:		;
      kPGPEvent_PassphraseEvent:        Result:=PassphraseHandler(Event);
      kPGPEvent_AnalyzeEvent:		Result:=AnalyzeHandler(Event);
      kPGPEvent_RecipientsEvent:  	if FPassOption=DecodePass then Result:=RecipientsHandler(Event);
      kPGPEvent_KeyFoundEvent:          if FPassOption=DecodePass then Result:=KeyFoundHandler(Event);
      kPGPEvent_OutputEvent:		if FPassOption=DecodePass then OutputHandler(Event);
      kPGPEvent_SignatureEvent:         if FPassOption=DecodePass then Result:=SignatureHandler(Event);
      kPGPEvent_BeginLexEvent:	  	FSectionNumber:=succ(Event^.EData.BeginLexData.SectionNumber);
      kPGPEvent_EndLexEvent:      	Result:=EndLexHandler(Event);
      kPGPEvent_DetachedSignatureEvent:	;
      kPGPEvent_DecryptionEvent:	;
    end;
  end;
end;

constructor TPGPDecodeCustom.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  FKeyPropsList:=TKeyPropsList.Create(0, spgpKeyPropFlag_IDFlags);
  FLogBadSignature:='bad signature';
  FLogExpSignature:='expired signature';
  FLogKeyDisabled:='disabled key';
  FLogKeyExpired:='expired key';
  FLogKeyRevoked:='revoked key';
  FLogKeyUnknown:='unknown key';
  FProgressInterval:=1000;
end;

destructor TPGPDecodeCustom.Destroy;
begin
  FKeyPropsList.Free;
  inherited Destroy;
end;

procedure TPGPDecodeCustom.SetRecursive(Value: Longbool);
begin
  if Value<>FRecursivelyDecode then FRecursivelyDecode:=Value;
  if FRecursivelyDecode then Include(FPassThroughOptions, PassThrough_ClearSigned);
end;

function TPGPDecodeCustom.InitDecode: PGPError;
begin
  FSectionNumber:=0;
  FOutputError:=0;
  FOutputBuffer:='';
  FSecureBufferSize:=0;
  FSecureBuffer:=nil;
  FActualOutputSize:=0;
  FAllocatedOutputBuffer:=nil;
  FDetachedSigVerify:=false;
  FClearSigned:=false;
  FRecognized:=false;
  FEyesOnly:=false;
  FKeyPropsList.Clear;
  FPassSection:=0;
  FPassphrase:=nil;
  FillChar(FSigPropsRec, SizeOf(TSigPropsRec), 0);
  FillChar(FRecipientsData, SizeOf(TPGPEventRecipientsData), 0);
  if FPassOption=AnalyseOnly then begin
    FContext:=nil;
    Result:=PGPNewContext(kPGPsdkAPIVersion, FContext);
  end
  else Result:=KeyDlgInit(FContext, FtlsContext, FKeySetMain);
end;

⌨️ 快捷键说明

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