keyfuncs.pas

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

PAS
1,570
字号

// local time
function GetKeyPropKeyCreationTimeStr(Key: pPGPKey): String;
var
  CreaTime	: PGPTime;
begin
  Result:='';
  if PGPGetKeyDBObjTimeProperty(Key, kPGPKeyProperty_Creation, CreaTime)=0 then begin
    Result:=UnixTimeToLocalTimeStr(PGPGetStdTimeFromPGPTime(CreaTime));
  end;
end;

// local time
function GetKeyPropKeyExpirationTimeStr(Key: pPGPKey): String;
var
  ExpTime	: PGPTime;
  CreaTime	: PGPTime;
begin
  Result:='';
  if (PGPGetKeyDBObjTimeProperty(Key, kPGPKeyProperty_Expiration, ExpTime)=0)
  and (PGPGetKeyDBObjTimeProperty(Key, kPGPKeyProperty_Creation, CreaTime)=0) then begin
    if ExpTime>CreaTime then Result:=UnixTimeToLocalTimeStr(PGPGetStdTimeFromPGPTime(ExpTime));
  end;
end;

function GetKeyPropKeyBits(Key: pPGPKey): String;
var
  Error		: PGPError;
  KeySet	: pPGPKeySet;
  KeyList	: pPGPKeyList;
  KeyIter	: pPGPKeyIter;
  SubKey	: pPGPSubKey;
  KeyAlg	: PGPInt32;
  KeyBits	: PGPInt32;
  SubKeyBits	: PGPInt32;
begin
  Result:='';
  Error:=0;
  KeySet:=nil;
  KeyList:=nil;
  KeyIter:=nil;
  SubKey:=nil;
  if (PGPGetKeyDBObjNumericProperty(Key, kPGPKeyProperty_AlgorithmID, KeyAlg)=0)
  and (PGPGetKeyDBObjNumericProperty(Key, kPGPKeyProperty_Bits, KeyBits)=0)
  and (PGPNewSingletonKeySet(Key, KeySet)=0) then begin
    try
      if PGPOrderKeySet(KeySet, kPGPKeyOrdering_Any, PGPFalse, KeyList)<>0 then Exit;
      try
	if PGPNewKeyIter(KeyList, KeyIter)<>0 then Exit;
	try
	  SubKeyBits:=0;
	  PGPKeyIterSeek(KeyIter, Key);
	  while (PGPKeyIterNextKeyDBObj(KeyIter, kPGPKeyDBObjType_SubKey, SubKey)=0) do begin
	    if not (GetSubKeyPropIsRevoked(SubKey) or GetSubKeyPropIsExpired(SubKey)) then begin
	      Error:=PGPGetKeyDBObjNumericProperty(SubKey, kPGPSubKeyProperty_Bits, SubKeyBits);
	      Break;
	    end;
	  end;
	  if Error=0 then begin
	    if SubKeyBits>0 then
	      Result:=IntToStr(SubKeyBits) + '/' + IntToStr(KeyBits) + ' bits'
	    else Result:=IntToStr(KeyBits) + ' bits';
	  end;
	finally
	  PGPFreeKeyIter(KeyIter);
	end;
      finally
	PGPFreeKeyList(KeyList);
      end;
    finally
      PGPFreeKeySet(KeySet);
    end;
  end;
end;

function GetKeyPropAlg(Key: pPGPKey): TKeyAlgorithm;
var
  KeyAlg	: PGPInt32;
begin
  Result:=KeyAlgorithm_Invalid;
  if PGPGetKeyDBObjNumericProperty(Key, kPGPKeyProperty_AlgorithmID, KeyAlg)=0 then begin
    Result:=TKeyAlgorithm(KeyAlg);
    if (Result=KeyAlgorithm_DSS) and (pos('/', GetKeyPropKeyBits(Key))<>0) then begin
      Result:=KeyAlgorithm_DHDSS;
    end;
  end;
end;

function GetKeyPropLegacy(Key: pPGPKey): Longbool;
var
  KeyVersion	: PGPInt32;
begin
  Result:=true;
  if PGP7X then begin
    if PGPGetKeyDBObjNumericProperty(Key, kPGPKeyProperty_Version, KeyVersion)=0 then begin
      Result:=(KeyVersion<=kPGPKeyVersion_V3);
    end;
  end
  else Result:=(GetKeyPropAlg(Key)=KeyAlgorithm_RSA);
end;

function GetKeyPropTrust(Key: pPGPKey): TTrustLevel;
var
  KeyTrust	: PGPInt32;
begin
  Result:=KeyTrust_Undefined;
  if PGPGetKeyDBObjNumericProperty(Key, kPGPKeyProperty_Trust, KeyTrust)=0 then begin
    Result:=TTrustLevel(KeyTrust);
  end;
end;

function GetKeyPropValidity(Key: pPGPKey): TValidityLevel;
var
  KeyValidity	: PGPInt32;
begin
  Result:=Validity_Unknown;
  if PGPGetKeyDBObjNumericProperty(Key, kPGPKeyProperty_Validity, KeyValidity)=0 then begin
    Result:=TValidityLevel(KeyValidity);
  end;
end;

// UTC/GMT Unix format seconds
function GetKeyPropKeyCreationTime(Key: pPGPKey): Integer;
var
  CreaTime	: PGPTime;
begin
  Result:=0;
  if PGPGetKeyDBObjTimeProperty(Key, kPGPKeyProperty_Creation, CreaTime)=0 then begin
    Result:=PGPGetStdTimeFromPGPTime(CreaTime);
  end;
end;

// UTC/GMT Unix format seconds
function GetKeyPropKeyExpirationTime(Key: pPGPKey): Integer;
var
  ExpTime	: PGPTime;
  CreaTime	: PGPTime;
begin
  Result:=0;
  if (PGPGetKeyDBObjTimeProperty(Key, kPGPKeyProperty_Expiration, ExpTime)=0)
  and (PGPGetKeyDBObjTimeProperty(Key, kPGPKeyProperty_Creation, CreaTime)=0) then begin
    if ExpTime>CreaTime then Result:=PGPGetStdTimeFromPGPTime(ExpTime);
  end;
end;

function GetKeyPropIsSecret(Key: pPGPKey): Longbool;
var
  Prop		: PGPBoolean;
begin
  Result:=false;
  if PGPGetKeyDBObjBooleanProperty(Key, kPGPKeyProperty_IsSecret, Prop)=0 then begin
    Result:=boolean(Prop);
  end;
end;

function GetKeyPropIsAxiomatic(Key: pPGPKey): Longbool;
var
  Prop		: PGPBoolean;
begin
  Result:=false;
  if PGPGetKeyDBObjBooleanProperty(Key, kPGPKeyProperty_IsAxiomatic, Prop)=0 then begin
    Result:=boolean(Prop);
  end;
end;

function GetKeyPropIsRevoked(Key: pPGPKey): Longbool;
var
  Prop		: PGPBoolean;
begin
  Result:=false;
  if PGPGetKeyDBObjBooleanProperty(Key, kPGPKeyProperty_IsRevoked, Prop)=0 then begin
    Result:=boolean(Prop);
  end;
end;

function GetKeyPropIsDisabled(Key: pPGPKey): Longbool;
var
  Prop		: PGPBoolean;
begin
  Result:=false;
  if PGPGetKeyDBObjBooleanProperty(Key, kPGPKeyProperty_IsDisabled, Prop)=0 then begin
    Result:=boolean(Prop);
  end;
end;

function GetKeyPropIsExpired(Key: pPGPKey): Longbool;
var
  Prop		: PGPBoolean;
begin
  Result:=false;
  if PGPGetKeyDBObjBooleanProperty(Key, kPGPKeyProperty_IsExpired, Prop)=0 then begin
    Result:=boolean(Prop);
  end;
end;

function GetKeyPropIsSecretShared(Key: pPGPKey): Longbool;
var
  Prop		: PGPBoolean;
begin
  Result:=false;
  if PGPGetKeyDBObjBooleanProperty(Key, kPGPKeyProperty_IsSecretShared, Prop)=0 then begin
    Result:=boolean(Prop);
  end;
end;

function GetKeyPropCanEncrypt(Key: pPGPKey): Longbool;
var
  Prop		: PGPBoolean;
begin
  Result:=false;
  if PGPGetKeyDBObjBooleanProperty(Key, kPGPKeyProperty_CanEncrypt, Prop)=0 then begin
    Result:=boolean(Prop);
  end;
end;

function GetKeyPropCanDecrypt(Key: pPGPKey): Longbool;
var
  Prop		: PGPBoolean;
begin
  Result:=false;
  if PGPGetKeyDBObjBooleanProperty(Key, kPGPKeyProperty_CanDecrypt, Prop)=0 then begin
    Result:=boolean(Prop);
  end;
end;

function GetKeyPropCanSign(Key: pPGPKey): Longbool;
var
  Prop		: PGPBoolean;
begin
  Result:=false;
  if PGPGetKeyDBObjBooleanProperty(Key, kPGPKeyProperty_CanSign, Prop)=0 then begin
    Result:=boolean(Prop);
  end;
end;

function GetKeyPropCanVerify(Key: pPGPKey): Longbool;
var
  Prop		: PGPBoolean;
begin
  Result:=false;
  if PGPGetKeyDBObjBooleanProperty(Key, kPGPKeyProperty_CanVerify, Prop)=0 then begin
    Result:=boolean(Prop);
  end;
end;

function GetKeyPropHasRevoker(KeySet: pPGPKeySet; Key: pPGPKey; KeyPropsRec: pKeyPropsRec): Longbool;
var
  RevKeyCount	: PGPUInt32;
  RevKeyIndex	: PGPUInt32;
  RevKey	: pPGPKey;
  RevKeyID	: TPGPKeyID7;
  KeyID		: TKeyID;
begin
  Result:=false;
  if (PGPCountRevocationKeys(Key, RevKeyCount)=0) and (RevKeyCount>0) then begin
    Result:=true;
    for RevKeyIndex:=0 to pred(RevKeyCount) do begin
      if PGPGetIndexedRevocationKey(Key, KeySet, RevKeyIndex, RevKey, RevKeyID)=0 then begin
	if PGPGetKeyIDString(RevKeyID, kPGPKeyIDString_Full, KeyID)=0 then begin
	  KeyPropsRec^.kRevKeyIDList.Add(KeyID);
	end;
      end;
    end;
  end;
end;

function GetKeyPropHasARR(KeySet: pPGPKeySet; Key: pPGPKey; KeyPropsRec: pKeyPropsRec): TADKType;
var
  ARKeyCount	: PGPUInt32;
  ARKeyIndex	: PGPUInt32;
  ARKey		: pPGPKey;
  ARKeyID	: TPGPKeyID7;
  ARClass	: PGPByte;
  KeyID		: TKeyID;
begin
  Result:=NoADK;
  ARKey:=nil;
  if (PGPCountAdditionalRecipientRequests(Key, ARKeyCount)=0) and (ARKeyCount>0) then begin
    Result:=SimpleADK;
    for ARKeyIndex:=0 to pred(ARKeyCount) do begin
      if PGPGetIndexedAdditionalRecipientRequestKey(Key, KeySet, ARKeyIndex, ARKey, ARKeyID, ARClass)=0 then begin
	if ARClass>0 then Result:=EnforcedADK;
	if PGPGetKeyIDString(ARKeyID, kPGPKeyIDString_Full, KeyID)=0 then begin
	  KeyPropsRec^.kADKeyIDList.Add(KeyID);
	end;
      end;
    end;
  end;
end;

function GetKeyPropHasSubKey(KeySet: pPGPKeySet; Key: pPGPKey): Longbool;
var
  KeyList	: pPGPKeyList;
  KeyIter	: pPGPKeyIter;
  SubKey	: pPGPSubKey;
begin
  Result:=false;
  if not GetKeyPropLegacy(Key) then begin
    KeyList:=nil;
    KeyIter:=nil;
    if PGPOrderKeySet(KeySet, kPGPKeyOrdering_Any, PGPFalse, KeyList)=0 then begin
      try
	if PGPNewKeyIter(KeyList, KeyIter)=0 then begin
	  try
	    PGPKeyIterSeek(KeyIter, Key);
	    Result:=(PGPKeyIterNextKeyDBObj(KeyIter, kPGPKeyDBObjType_SubKey, SubKey)=0);
	  finally
	    PGPFreeKeyIter(KeyIter);
	  end;
	end;
      finally
	PGPFreeKeyList(KeyList);
      end;
    end;
  end;
end;

function GetKeyPropUserIDs(Key: pPGPKey; KeyPropsRec: pKeyPropsRec; IncludeSignerIDs: Longbool): Integer;
var
  KeySet	: pPGPKeySet;
  KeyList	: pPGPKeyList;
  KeyIter	: pPGPKeyIter;
  UserID	: pPGPUserID;
  UserIDProp	: PGPBoolean;
  UserIDBuf	: TUserID;
  UserIDNum	: PGPInt32;
  IDSize	: PGPSize;
  IDBuffer	: String;
  KeySig	: pPGPSig;
  SignKey	: TPGPKeyID7;
  KeyID		: TKeyID;
begin
  KeySet:=nil;
  KeyList:=nil;
  KeyIter:=nil;
  Result:=PGPNewSingletonKeySet(Key, KeySet);
  if Result<>0 then Exit;
  try
    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);
	if Result<>0 then Exit;
	Result:=PGPKeyIterRewindKeyDBObj(KeyIter, kPGPKeyDBObjType_UserID);
	if Result<>0 then Exit;
	// add UserIDs one by one to UserIDList
	while PGPKeyIterNextKeyDBObj(KeyIter, kPGPKeyDBObjType_UserID, UserID)=0 do begin
	  Result:=PGPGetKeyDBObjBooleanProperty(UserID, kPGPUserIDProperty_IsAttribute, UserIDProp);
	  if Result<>0 then Exit;
	  // check for attributes (picture, f.e.)
	  if not boolean(UserIDProp) then begin
	    // UserID validity
	    Result:=PGPGetKeyDBObjNumericProperty(UserID, kPGPUserIDProperty_Validity, UserIDNum);
	    if Result<>0 then Exit;
	    // UserID string
	    Result:=PGPGetKeyDBObjDataProperty(UserID, kPGPUserIDProperty_Name, @UserIDBuf, SizeOf(TUserID), IDSize);
	    if Result<>0 then Exit;
	    try
	      with KeyPropsRec^ do begin
		if PGP8X then
		  kUserIDList.AddObject(Utf8OrAnsi(UserIDBuf), ptr(UserIDNum))
		else kUserIDList.AddObject(UserIDBuf, ptr(UserIDNum));
		if IncludeSignerIDs then kSignerIDList.Add('');
	      end;
	    except
	      Result:=kPGPError_OutOfMemory;
	      Exit;
	    end;
	  end;
	  IDBuffer:='';
	  if IncludeSignerIDs then begin
	    // add comma separated HexIDs of signing keys to KeyPropsRec.SignerIDList
	    while PGPKeyIterNextKeyDBObj(KeyIter, kPGPKeyDBObjType_Signature, KeySig)=0 do begin
	      Result:=PGPGetKeyIDOfCertifier(KeySig, SignKey);
	      if Result<>0 then Exit;
	      Result:=PGPGetKeyIDString(SignKey, kPGPKeyIDString_Full, KeyID);
	      if Result<>0 then Exit;
	      IDBuffer:=IDBuffer + ',' + KeyID;
	    end;
	    Delete(IDBuffer, 1, 1);
	    try
	      with KeyPropsRec^.kSignerIDList do Strings[pred(Count)]:=IDBuffer;
	    except
	      Result:=kPGPError_OutOfMemory;
	      Exit;
	    end;
	  end;
	end;
      finally
	PGPFreeKeyIter(KeyIter);

⌨️ 快捷键说明

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