keyfuncs.pas

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

PAS
1,570
字号
    if Result<>0 then Exit;
    if FilterFlags and KeyFilterMask_Algorithm<>0 then begin
      if FilterFlags and KeyFilterFlag_DHDSS<>0 then begin
	Result:=PGPNewKeyDBObjNumericFilter(Context, kPGPKeyProperty_AlgorithmID,
					    kPGPPublicKeyAlgorithm_DSA, kPGPMatchEqual, KeyAlgFilter);
      end else if FilterFlags and KeyFilterFlag_RSA<>0 then begin
	Result:=PGPNewKeyDBObjNumericFilter(Context, kPGPKeyProperty_AlgorithmID,
					    kPGPPublicKeyAlgorithm_RSA, kPGPMatchEqual, KeyAlgFilter);
      end else if FilterFlags and KeyFilterFlag_V4<>0 then begin
	if PGP7X then begin
	  Result:=PGPNewKeyDBObjNumericFilter(Context, kPGPKeyProperty_Version,
					      kPGPKeyVersion_V4, kPGPMatchEqual, KeyAlgFilter);
	end
	else begin
	  Result:=PGPNewKeyDBObjNumericFilter(Context, kPGPKeyProperty_AlgorithmID,
					      kPGPPublicKeyAlgorithm_DSA, kPGPMatchEqual, KeyAlgFilter);
	end;
      end else if FilterFlags and KeyFilterFlag_V3<>0 then begin
	if PGP7X then begin
	  Result:=PGPNewKeyDBObjNumericFilter(Context, kPGPKeyProperty_Version,
					      kPGPKeyVersion_V3, kPGPMatchLessOrEqual, KeyAlgFilter);
	end
	else begin
	  Result:=PGPNewKeyDBObjNumericFilter(Context, kPGPKeyProperty_AlgorithmID,
					      kPGPPublicKeyAlgorithm_RSA, kPGPMatchEqual, KeyAlgFilter);
	end;
      end;
    end;
    if Result<>0 then Exit;
    if (KeyBoolFilter<>nil) and (KeyAlgFilter<>nil) then
      Result:=PGPIntersectFilters(KeyBoolFilter, KeyAlgFilter, KeyFilter)
    else if KeyBoolFilter<>nil then
      KeyFilter:=KeyBoolFilter
    else if KeyAlgFilter<>nil then
      KeyFilter:=KeyAlgFilter;
  finally
    if Result<>0 then begin
      if KeyBoolFilter<>nil then PGPFreeFilter(KeyBoolFilter);
      if KeyAlgFilter<>nil then PGPFreeFilter(KeyAlgFilter);
    end;
  end;
end;

function GetKeyFilterByAnyID(Context: pPGPContext; const AnyID: String;
			     IncludeSubKeys: Longbool; var KeyFilter: pPGPFilter): PGPError;
var
  PGPKeyID	: TPGPKeyID7;
  KeyIDFilter	: pPGPFilter;
  SubKeyIDFilter: pPGPFilter;
  UTF8Filter	: pPGPFilter;
  AnsiFilter	: pPGPFilter;
  UTF8ID	: UTF8String;
begin
  Result:=0;
  KeyFilter:=nil;
  if IsHexID(AnyID) then begin
    KeyIDFilter:=nil;
    SubKeyIDFilter:=nil;
    try
      Result:=PGPGetKeyIDFromString(PChar(AnyID), kPGPPublicKeyAlgorithm_Invalid, PGPKeyID);
      if Result<>0 then Exit;
      Result:=PGPNewKeyDBObjDataFilter(Context, kPGPKeyProperty_KeyID, @PGPKeyID,
				       SizeOf(TPGPKeyID7), kPGPMatchEqual, KeyIDFilter);
      if Result<>0 then Exit;
      if IncludeSubKeys then begin
	Result:=PGPNewKeyDBObjDataFilter(Context, kPGPSubKeyProperty_KeyID, @PGPKeyID,
					 SizeOf(TPGPKeyID7), kPGPMatchEqual, SubKeyIDFilter);
	if Result<>0 then Exit;
	Result:=PGPUnionFilters(KeyIDFilter, SubKeyIDFilter, KeyFilter);
      end
      else KeyFilter:=KeyIDFilter;
    finally
      if Result<>0 then begin
	if KeyIDFilter<>nil then PGPFreeFilter(KeyIDFilter);
	if SubKeyIDFilter<>nil then PGPFreeFilter(SubKeyIDFilter);
      end;
    end;
  end
  else begin
    UTF8Filter:=nil;
    AnsiFilter:=nil;
    try
      Result:=PGPNewKeyDBObjDataFilter(Context, kPGPUserIDProperty_Name, PChar(AnyID),
				       Length(AnyID), kPGPMatchSubString, AnsiFilter);
      if Result<>0 then Exit;
      if PGP8X then begin
	UTF8ID:=AnsiToUtf8(AnyID);
	Result:=PGPNewKeyDBObjDataFilter(Context, kPGPUserIDProperty_Name, PChar(UTF8ID),
					 Length(UTF8ID), kPGPMatchSubString, UTF8Filter);
	if Result<>0 then Exit;
	Result:=PGPUnionFilters(UTF8Filter, AnsiFilter, KeyFilter);
      end
      else KeyFilter:=AnsiFilter;
    finally
      if Result<>0 then begin
	if UTF8Filter<>nil then PGPFreeFilter(UTF8Filter);
	if AnsiFilter<>nil then PGPFreeFilter(AnsiFilter);
      end;
    end;
  end;
end;

function GetKeySetByAnyIDs(Context: pPGPContext;
			   KeySetMain: pPGPKeySet;
			   const KeyIDCommaText: String;
			   var KeySetFound: pPGPKeySet): PGPError;
var
  KeyDataList	: TStringList;
  KeyIndex	: PGPUInt32;
  KeyString	: String;
  KeyFilter	: pPGPFilter;
  KeySetFiltered: pPGPKeySet;
  KeyCount	: PGPUInt32;
begin
  KeySetFound:=nil;
  if KeyIDCommaText<>'' then begin
    KeyDataList:=TStringList.Create;
    KeyFilter:=nil;
    KeySetFiltered:=nil;
    try
      KeyDataList.CommaText:=KeyIDCommaText;
      if PGP7X then
	Result:=PGPNewEmptyKeySet(PGPPeekKeySetKeyDB(KeySetMain), KeySetFound)
      else Result:=PGPNewKeySet(Context, KeySetFound);
      if Result<>0 then Exit;
      for KeyIndex:=0 to pred(KeyDataList.Count) do begin
	KeyString:=Trim(KeyDataList[KeyIndex]);
	if KeyString<>'' then begin
	  Result:=GetKeyFilterByAnyID(Context, KeyString, false, KeyFilter);
	  if Result<>0 then Exit;
	  try
	    Result:=PGPFilterKeySet(KeySetMain, KeyFilter, KeySetFiltered);
	    if Result<>0 then Exit;
	    try
	      Result:=PGPCountKeys(KeySetFiltered, KeyCount);
	      if Result<>0 then Exit;
	      if KeyCount<>0 then begin
		Result:=PGPAddKeys(KeySetFiltered, KeySetFound);
		if Result<>0 then Exit;
	      end
	      else begin
		Result:=kPGPError_ItemNotFound;
		PGPFreeKeySet(KeySetFound);
		KeySetFound:=nil;
		Exit;
	      end;
	    finally
	      PGPFreeKeySet(KeySetFiltered);
	    end;
	  finally
	    PGPFreeFilter(KeyFilter);
	  end;
	end;
      end;
    finally
      KeyDataList.Free;
    end;
  end
  else Result:=kPGPError_ItemNotFound;
end;

function GetExclusiveKeySet(var KeySetToCheck: pPGPKeySet; KeySetMain: pPGPKeySet;
			    Context: pPGPContext; IgnoreKnownFlag: Integer): PGPError;
var
  KeyListToCheck: pPGPKeyList;
  KeyIterToCheck: pPGPKeyIter;
  KeyToCheck	: pPGPKey;
  KeyIDToCheck	: TKeyID;
  UserIDToCheck	: TUserID;
  KeyCount	: PGPUInt32;
  IDSize	: PGPSize;
  UserIDFound	: pPGPUserID;
  UserIDProp	: PGPBoolean;
  KeyFilter	: pPGPFilter;
  KeySetFound	: pPGPKeySet;
  KeySetToRemove: pPGPKeySet;
begin
  KeyToCheck:=nil;
  KeyListToCheck:=nil;
  KeyIterToCheck:=nil;
  try
    if PGP7X then
      Result:=PGPNewKeyIterFromKeySet(KeySetToCheck, KeyIterToCheck)
    else begin
      Result:=PGPOrderKeySet(KeySetToCheck, kPGPKeyOrdering_UserID, PGPFalse, KeyListToCheck);
      if Result<>0 then Exit;
      Result:=PGPNewKeyIter(KeyListToCheck, KeyIterToCheck);
    end;
    if Result<>0 then Exit;
    try
      if (IgnoreKnownFlag and IgnoreFlag_ByHexID)<>0 then begin
	while PGPKeyIterNextKeyDBObj(KeyIterToCheck, kPGPKeyDBObjType_Key, KeyToCheck)=0 do begin
	  KeyFilter:=nil;
	  KeySetFound:=nil;
	  KeySetToRemove:=nil;
	  try
	    if (PGPGetKeyDBObjDataProperty(KeyToCheck, kPGPKeyProperty_KeyID,
					   @KeyIDToCheck, kPGPMaxKeyIDStringSize, IDSize)=0)
	    and (PGPNewKeyDBObjDataFilter(Context, kPGPKeyProperty_KeyID, @KeyIDToCheck,
					  IDSize, kPGPMatchEqual, KeyFilter)=0)
	    and (PGPFilterKeySet(KeySetMain, KeyFilter, KeySetFound)=0)
	    and (PGPCountKeys(KeySetFound, KeyCount)=0) and (KeyCount<>0)
	    and (PGPNewSingletonKeySet(KeyToCheck, KeySetToRemove)=0) then begin
	      PGPRemoveKeys(KeySetToRemove, KeySetToCheck);
	    end;
	  finally
	    PGPFreeFilter(KeyFilter);
	    PGPFreeKeySet(KeySetFound);
	    PGPFreeKeySet(KeySetToRemove);
	  end;
	end;
	PGPKeyIterRewindKeyDBObj(KeyIterToCheck, kPGPKeyDBObjType_Key);
      end;
      if (PGPCountKeys(KeySetToCheck, KeyCount)=0) and (KeyCount=0) then Exit;
      if (IgnoreKnownFlag and IgnoreFlag_ByUserID)<>0 then begin
	while (PGPKeyIterNextKeyDBObj(KeyIterToCheck, kPGPKeyDBObjType_Key, KeyToCheck)=0)
	and (PGPKeyIterRewindKeyDBObj(KeyIterToCheck, kPGPKeyDBObjType_UserID)=0) do begin
	  while (PGPKeyIterNextKeyDBObj(KeyIterToCheck, kPGPKeyDBObjType_UserID, UserIDFound)=0)
	  and (PGPGetKeyDBObjBooleanProperty(UserIDFound, kPGPUserIDProperty_IsAttribute, UserIDProp)=0)
	  and not boolean(UserIDProp) do begin
	    KeyFilter:=nil;
	    KeySetFound:=nil;
	    KeySetToRemove:=nil;
	    try
	      if (PGPGetKeyDBObjDataProperty(UserIDFound, kPGPUserIDProperty_Name,
					     @UserIDToCheck, SizeOf(TUserID), IDSize)=0)
	      and (PGPNewKeyDBObjDataFilter(Context, kPGPUserIDProperty_Name, @UserIDToCheck,
					    IDSize, kPGPMatchEqual, KeyFilter)=0)
	      and (PGPFilterKeySet(KeySetMain, KeyFilter, KeySetFound)=0)
	      and (PGPCountKeys(KeySetFound, KeyCount)=0) and (KeyCount<>0)
	      and (PGPNewSingletonKeySet(KeyToCheck, KeySetToRemove)=0) then begin
		PGPRemoveKeys(KeySetToRemove, KeySetToCheck);
		Break;
	      end;
	    finally
	      PGPFreeFilter(KeyFilter);
	      PGPFreeKeySet(KeySetFound);
	      PGPFreeKeySet(KeySetToRemove);
	    end;
	  end;
	  if (PGPCountKeys(KeySetToCheck, KeyCount)=0) and (KeyCount=0) then Break;
	end;
      end;
    finally
      PGPFreeKeyIter(KeyIterToCheck);
    end;
  finally
    PGPFreeKeyList(KeyListToCheck);
  end;
end;

function GetFingerprintString(const Fingerprint: TFingerprint; FPSize: PGPSize): String; assembler;
asm	// EAX=@Fingerprint, EDX=FPSize, ECX=@Result
  JMP	@BEGIN
  @HEXCHARS:
  DB	'0123456789ABCDEF';
  @BEGIN:
  PUSH	EBX
  PUSH	EDI
  PUSH	ESI
  PUSH	EBP
  MOV	ESI,EAX
  MOV	EDI,ECX
  MOV	EAX,EDX
  MOV	EBX,EDX
  SHL	EAX,1
  SHR	EBX,1
  MOV	EBP,EBX
  ADD	EAX,EBX
  INC	EBP
  PUSH	EDX
  PUSH	EAX
  CALL	SYSTEM.@NEWANSISTRING
  MOV	[EDI],EAX
  MOV	EDI,EAX
  POP	EBX
  POP	ECX
  SUB	EBX,2
  DEC	ECX
  @LOOP:
  MOVZX	EAX,BYTE PTR[ESI + ECX]
  MOV	EDX,EAX
  AND	EAX,0Fh
  SHR	EDX,4
  MOV	AH,BYTE PTR[@HEXCHARS + EAX]
  MOV	AL,BYTE PTR[@HEXCHARS + EDX]
  MOV	[EDI + EBX],AX
  MOVZX	EAX,BYTE PTR[ESI + ECX - 1]
  MOV	EDX,EAX
  AND	EAX,0Fh
  SHR	EDX,4
  MOV	AH,BYTE PTR[@HEXCHARS + EAX]
  MOV	AL,BYTE PTR[@HEXCHARS + EDX]
  MOV	[EDI + EBX - 2],AX
  CMP	EBP,ECX
  JE	@MIDDLE
  SUB	EBX,5
  SUB	ECX,2
  JS	@END
  MOV	BYTE PTR[EDI + EBX + 2],' '
  JMP	@LOOP
  @MIDDLE:
  SUB	EBX,6
  SUB	ECX,2
  MOV	WORD PTR[EDI + EBX + 2],'  '
  JMP	@LOOP
  @END:
  POP	EBP
  POP	ESI
  POP	EDI
  POP	EBX
end;

function SystemTimeToUnixTimeNum: Integer;
var SystemTime: TSystemTime;
begin
  GetSystemTime(SystemTime);
  Result:=SystemTimeToUnixTime(SystemTime);
end;

function UnixTimeToLocalTimeStr(UnixSeconds: Integer): String;
begin
  Result:=FormatDateTime('ddd, dd mmm yyyy, tt', UnixTimeToLocalTime(UnixSeconds));
end;

function GetSubKeyPropKeyID(SubKey: pPGPKey): String;
var
  PGPKeyID	: TPGPKeyID7;
  KeyID		: TKeyID;
begin
  Result:='';
  if (PGPGetKeyIDFromSubKey(SubKey, PGPKeyID)=0)
  and (PGPGetKeyIDString(PGPKeyID, kPGPKeyIDString_Full, KeyID)=0) then begin
    Result:=KeyID;
  end;
end;

function GetSubKeyPropIsRevoked(SubKey: pPGPKey): Longbool;
var
  Prop		: PGPBoolean;
begin
  Result:=false;
  if PGPGetKeyDBObjBooleanProperty(SubKey, kPGPSubKeyProperty_IsRevoked, Prop)=0 then begin
    Result:=boolean(Prop);
  end;
end;

function GetSubKeyPropIsExpired(SubKey: pPGPKey): Longbool;
var
  Prop		: PGPBoolean;
begin
  Result:=false;
  if PGPGetKeyDBObjBooleanProperty(SubKey, kPGPSubKeyProperty_IsExpired, Prop)=0 then begin
    Result:=boolean(Prop);
  end;
end;

function GetKeyPropKeyID(Key: pPGPKey): String;
var
  PGPKeyID	: TPGPKeyID7;
  KeyID		: TKeyID;
begin
  Result:='';
  if (PGPGetKeyIDFromKey(Key, PGPKeyID)=0)
  and (PGPGetKeyIDString(PGPKeyID, kPGPKeyIDString_Full, KeyID)=0) then begin
    Result:=KeyID;
  end;
end;

function GetKeyPropUserID(Key: pPGPKey): String;
var
  UserIDBuf	: TUserID;
  IDSize	: PGPSize;
begin
  Result:='';
  if PGPGetPrimaryUserIDNameBuffer(Key, @UserIDBuf, SizeOf(TUserID), IDSize)=0 then begin
    if PGP8X then
      Result:=Utf8OrAnsi(UserIDBuf)
    else Result:=UserIDBuf;
  end;
end;

function GetKeyPropFingerprint(Key: pPGPKey): String;
var
  Fingerprint	: TFingerprint;
  FPSize	: PGPSize;
begin
  Result:='';
  if (PGPGetKeyDBObjDataProperty(Key, kPGPKeyProperty_Fingerprint, @Fingerprint, kPGPmaxFingerprintSize, FPSize)=0)
  and (FPSize<>0) then begin
    Result:=GetFingerprintString(Fingerprint, FPSize);
  end;
end;

⌨️ 快捷键说明

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