keyfuncs.pas
来自「用DELPHI实现的 PGP 加密算法」· PAS 代码 · 共 1,570 行 · 第 1/4 页
PAS
1,570 行
{$J+,Z4}
unit KeyFuncs;
{------------------------------------------------------------------------------}
{ }
{ This unit is partly based on Steve Heller's spgpKeyUtil.pas from his }
{ 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,
TimeUtils,
KeyPropTypes,
UTF8,
pgpBase,
pgpErrors,
pgpPubTypes,
pgpUtilities,
pgpOptionList,
pgpGroups,
pgpKeys,
pgpCl;
type
TKeyRings = Class
private
InitCount: Longint;
RingKeyDB: pPGPKeyDB;
RingKeySet: pPGPKeySet;
RingContext: pPGPContext;
public
PubringFile: String;
SecringFile: String;
GroupsFile: String;
function UpdateKeyRings: PGPError;
function SetKeyRings(const Pubring, Secring: String): Longbool;
function InitKeyRings(var Context: pPGPContext; var KeySetMain: pPGPKeySet): PGPError;
procedure FreeKeyRings;
end;
{ "public" functions }
function IsHexID(const ToCheck: String): Longbool;
function KeyRemove(KeyIDCommaText: PChar): Integer;
function KeyEnable(HexKeyID: PChar): Integer;
function KeyDisable(HexKeyID: PChar): Integer;
function KeyRevoke(HexKeyID, Passphrase: PChar): Integer;
function ChangePassphrase(HexKeyID, OldPassphrase, NewPassphrase: PChar): Integer;
// properties, key & user IDs for all keys matching the specified KeyIDCommaText
// if KeyIDCommaText='' then all keys will be checked
// - returns number of keys found or error
function FindKeyProps(const KeyIDCommaText: String;
var KeyPropsList: TKeyPropsList;
PropertyFlags, FilterFlags: DWord;
KeyOrder: TPGPKeyOrdering): Integer;
{ "private" functions }
function SystemTimeToUnixTimeNum: Integer;
function UnixTimeToLocalTimeStr(UnixSeconds: Integer): String;
function GetSubKeyPropKeyID(SubKey: pPGPKey): String;
function GetKeyPropKeyID(Key: pPGPKey): String;
function GetKeyPropUserID(Key: pPGPKey): String;
function GetKeyPropAlg(Key: pPGPKey): TKeyAlgorithm;
function GetKeyPropLegacy(Key: pPGPKey): Longbool;
function GetKeyPropIsAxiomatic(Key: pPGPKey): Longbool;
function GetKeyFromKeySet(KeySet: pPGPKeySet; var Key: pPGPKey): PGPError;
function GetKeyByHexID(KeySet: pPGPKeySet; const HexID: String; var Key: pPGPKey): PGPError;
function GetKeyFilter(Context: pPGPContext; FilterFlags: DWord; var KeyFilter: pPGPFilter): PGPError;
function GetKeyFilterByAnyID(Context: pPGPContext; const AnyID: String;
IncludeSubKeys: Longbool; var KeyFilter: pPGPFilter): PGPError;
function GetKeySetByAnyIDs(Context: pPGPContext;
KeySetMain: pPGPKeySet;
const KeyIDCommaText: String;
var KeySetFound: pPGPKeySet): PGPError;
function GetExclusiveKeySet(var KeySetToCheck: pPGPKeySet; KeySetMain: pPGPKeySet;
Context: pPGPContext; IgnoreKnownFlag: Integer): PGPError;
function GetKeySetProps(Context: pPGPContext; KeySet: pPGPKeySet;
var KeyPropsList: TKeyPropsList;
PropertyFlags, FilterFlags: DWord;
KeyOrder: TPGPKeyOrdering): Integer; // - returns number of keys found or error
function AddKeysToKeyRing(Context: pPGPContext; KeySetMain: pPGPKeySet;
KeysToImport: Pointer; var KeyPropsList: TKeyPropsList;
PropertyFlags: DWord): Integer; // - returns number of keys added or error
function GetHexIDByAnyID(Context: pPGPContext; KeySetMain: pPGPKeySet;
const AnyID: String; var HexID: String): Integer; // - returns number of keys found or error
function PassphraseIsValid(Context: pPGPContext; KeySetMain: pPGPKeySet; AnyID, Passphrase: PChar): Longbool;
const KeyRings: TKeyRings = nil;
implementation
uses PrefFuncs;
function IsHexID(const ToCheck: String): Longbool; assembler;
asm // EAX=@ToCheck
OR EAX,EAX
JE @FALSE
MOV ECX,[EAX-04h]
CMP ECX,LongHexIDLen
JE @START
CMP ECX,ShortHexIDLen
JNE @FALSE
@START:
MOV DX,[EAX]
AND DX,0DFFFh
CMP DX,'X0'
JNE @FALSE
SUB ECX,2
ADD EAX,2
@LOOP:
DEC ECX
JS @TRUE
MOV DL,[EAX+ECX]
CMP DL,'0'
JB @FALSE
CMP DL,'9'
JBE @LOOP
AND DL,0DFh
CMP DL,'A'
JB @FALSE
CMP DL,'F'
JBE @LOOP
@FALSE:
XOR EAX,EAX
RET
@TRUE:
MOV EAX,1
end;
function KeyRemove(KeyIDCommaText: PChar): Integer;
var
Context : pPGPContext;
KeySetMain : pPGPKeySet;
KeySetFound : pPGPKeySet;
KeyCount : PGPUInt32;
begin
KeySetFound:=nil;
Result:=KeyRings.InitKeyRings(Context, KeySetMain);
if Result<>0 then Exit;
try
Result:=GetKeySetByAnyIDs(Context, KeySetMain, KeyIDCommaText, KeySetFound);
if Result<>0 then Exit;
try
Result:=PGPCountKeys(KeySetFound, KeyCount);
if Result<>0 then Exit;
if KeyCount<>0 then begin
Result:=PGPRemoveKeys(KeySetFound, KeySetMain);
if Result<>0 then Exit;
end;
finally
PGPFreeKeySet(KeySetFound);
end;
Result:=KeyRings.UpdateKeyRings;
finally
KeyRings.FreeKeyRings;
end;
end;
function KeyEnable(HexKeyID: PChar): Integer;
var
Context : pPGPContext;
KeySetMain : pPGPKeySet;
Key : pPGPKey;
begin
Result:=KeyRings.InitKeyRings(Context, KeySetMain);
if Result<>0 then Exit;
try
Result:=GetKeyByHexID(KeySetMain, HexKeyID, Key);
if Result<>0 then Exit;
Result:=PGPEnableKey(Key);
if Result<>0 then Exit;
Result:=KeyRings.UpdateKeyRings;
finally
KeyRings.FreeKeyRings;
end;
end;
function KeyDisable(HexKeyID: PChar): Integer;
var
Context : pPGPContext;
KeySetMain : pPGPKeySet;
Key : pPGPKey;
begin
Result:=KeyRings.InitKeyRings(Context, KeySetMain);
if Result<>0 then Exit;
try
Result:=GetKeyByHexID(KeySetMain, HexKeyID, Key);
if Result<>0 then Exit;
Result:=PGPDisableKey(Key);
if Result<>0 then Exit;
Result:=KeyRings.UpdateKeyRings;
finally
KeyRings.FreeKeyRings;
end;
end;
function KeyRevoke(HexKeyID, Passphrase: PChar): Integer;
var
Context : pPGPContext;
KeySetMain : pPGPKeySet;
Key : pPGPKey;
begin
Result:=KeyRings.InitKeyRings(Context, KeySetMain);
if Result<>0 then Exit;
try
Result:=GetKeyByHexID(KeySetMain, HexKeyID, Key);
if Result<>0 then Exit;
Result:=PGPRevokeKey(Key, PGPOPassphrase(Context, Passphrase), PGPOLastOption(Context));
if Result<>0 then Exit;
Result:=KeyRings.UpdateKeyRings;
finally
KeyRings.FreeKeyRings;
end;
end;
function ChangePassphrase(HexKeyID, OldPassphrase, NewPassphrase: PChar): Integer;
var
Context : pPGPContext;
KeySetMain : pPGPKeySet;
OptionList : pPGPOptionList;
Key : pPGPKey;
KeyList : pPGPKeyList;
KeyIter : pPGPKeyIter;
SubKey : pPGPSubKey;
begin
Result:=KeyRings.InitKeyRings(Context, KeySetMain);
if Result<>0 then Exit;
OptionList:=nil;
try
Result:=PGPBuildOptionList(Context, OptionList,
[
PGPOPassphrase(Context, OldPassphrase),
PGPOPassphrase(Context, NewPassphrase)
]);
if Result<>0 then Exit;
try
Result:=GetKeyByHexID(KeySetMain, HexKeyID, Key);
if Result<>0 then Exit;
Result:=PGPChangePassphrase(Key, OptionList, PGPOLastOption(Context));
if Result<>0 then Exit;
if not GetKeyPropLegacy(Key) then begin
KeyList:=nil;
KeyIter:=nil;
Result:=PGPOrderKeySet(KeySetMain, kPGPKeyOrdering_Any, PGPFalse, KeyList);
if Result<>0 then Exit;
try
Result:=PGPNewKeyIter(KeyList, KeyIter);
if Result<>0 then Exit;
try
PGPKeyIterSeek(KeyIter, Key);
while PGPKeyIterNextKeyDBObj(KeyIter, kPGPKeyDBObjType_SubKey, SubKey)=0 do begin
Result:=PGPChangeSubKeyPassphrase(SubKey, OptionList, PGPOLastOption(Context));
if Result<>0 then Exit;
end;
finally
PGPFreeKeyIter(KeyIter);
end;
finally
PGPFreeKeyList(KeyList);
end;
end;
Result:=KeyRings.UpdateKeyRings;
finally
PGPFreeOptionList(OptionList);
end;
finally
KeyRings.FreeKeyRings;
end;
end;
function FindKeyProps(const KeyIDCommaText: String;
var KeyPropsList: TKeyPropsList;
PropertyFlags, FilterFlags: DWord;
KeyOrder: TPGPKeyOrdering): Integer;
var
Context : pPGPContext;
KeySetMain : pPGPKeySet;
KeySetFound : pPGPKeySet;
KeyFilter : pPGPFilter;
KeySetFiltered: pPGPKeySet;
KeyCount : PGPUInt32;
begin
KeySetFound:=nil;
KeyFilter:=nil;
KeySetFiltered:=nil;
Result:=KeyRings.InitKeyRings(Context, KeySetMain);
if Result<>0 then Exit;
try
if KeyIDCommaText='' then
KeySetFound:=KeySetMain // all keys on key rings
else Result:=GetKeySetByAnyIDs(Context, KeySetMain, KeyIDCommaText, KeySetFound); // key(s) matching KeyData
if Result<>0 then Exit;
try
if PropertyFlags<>0 then begin
Result:=GetKeySetProps(Context, KeySetFound,
KeyPropsList, PropertyFlags,
FilterFlags, KeyOrder);
end
else begin
if FilterFlags<>KeyFilterFlag_AllKeys then begin
Result:=GetKeyFilter(Context, FilterFlags, KeyFilter);
try
if Result<>0 then Exit;
Result:=PGPFilterKeySet(KeySetFound, KeyFilter, KeySetFiltered);
finally
PGPFreeFilter(KeyFilter);
end;
end
else KeySetFiltered:=KeySetFound;
if Result<>0 then Exit;
try
Result:=PGPCountKeys(KeySetFiltered, KeyCount);
if Result=0 then Result:=KeyCount;
finally
if KeySetFiltered<>KeySetFound then PGPFreeKeySet(KeySetFiltered);
end;
end;
finally
if KeySetFound<>KeySetMain then PGPFreeKeySet(KeySetFound);
end;
finally
KeyRings.FreeKeyRings;
end;
end;
function GetKeyFromKeySet(KeySet: pPGPKeySet; var Key: pPGPKey): PGPError;
var
KeyList : pPGPKeyList;
KeyIter : pPGPKeyIter;
begin
Key:=nil;
KeyList:=nil;
KeyIter:=nil;
Result:=PGPOrderKeySet(KeySet, kPGPKeyOrdering_UserID, PGPFalse, KeyList);
if Result<>0 then Exit;
try
Result:=PGPNewKeyIter(KeyList, KeyIter);
if Result<>0 then Exit;
try
Result:=PGPKeyIterNextKeyDBObj(KeyIter, kPGPKeyDBObjType_Key, Key);
finally
PGPFreeKeyIter(KeyIter);
end;
finally
PGPFreeKeyList(KeyList);
end;
end;
function GetKeyByHexID(KeySet: pPGPKeySet; const HexID: String; var Key: pPGPKey): PGPError;
var
PGPKeyID : TPGPKeyID7;
begin
Key:=nil;
Result:=PGPGetKeyIDFromString(PChar(HexID), kPGPPublicKeyAlgorithm_Invalid, PGPKeyID);
if Result=0 then Result:=PGPGetKeyByKeyID(KeySet, PGPKeyID, kPGPPublicKeyAlgorithm_Invalid, Key);
end;
function GetKeyFilter(Context: pPGPContext; FilterFlags: DWord; var KeyFilter: pPGPFilter): PGPError;
var
KeyBoolFilter : pPGPFilter;
KeyAlgFilter : pPGPFilter;
begin
Result:=0;
KeyFilter:=nil;
KeyBoolFilter:=nil;
KeyAlgFilter:=nil;
try
if FilterFlags and KeyFilterMask_Boolean<>0 then begin
if FilterFlags and KeyFilterFlag_CanEncrypt<>0 then begin
Result:=PGPNewKeyDBObjBooleanFilter(Context, kPGPKeyProperty_CanEncrypt, PGPTrue, KeyBoolFilter);
end
else if FilterFlags and KeyFilterFlag_CanDecrypt<>0 then begin
Result:=PGPNewKeyDBObjBooleanFilter(Context, kPGPKeyProperty_CanDecrypt, PGPTrue, KeyBoolFilter);
end
else if FilterFlags and KeyFilterFlag_CanSign<>0 then begin
Result:=PGPNewKeyDBObjBooleanFilter(Context, kPGPKeyProperty_CanSign, PGPTrue, KeyBoolFilter);
end
else if FilterFlags and KeyFilterFlag_CanVerify<>0 then begin
Result:=PGPNewKeyDBObjBooleanFilter(Context, kPGPKeyProperty_CanVerify, PGPTrue, KeyBoolFilter);
end
else if FilterFlags and KeyFilterFlag_Enabled<>0 then begin
Result:=PGPNewKeyDBObjBooleanFilter(Context, kPGPKeyProperty_IsDisabled, PGPFalse, KeyBoolFilter);
end
else if FilterFlags and KeyFilterFlag_Disabled<>0 then begin
Result:=PGPNewKeyDBObjBooleanFilter(Context, kPGPKeyProperty_IsDisabled, PGPTrue, KeyBoolFilter);
end;
end;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?