pgpkeygenerate.pas

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

PAS
659
字号
			KeyFilterFlag_CanSign or KeyFilterFlag_V4, Any_Ordering)=1 then begin
	  KeyPropsRec:=pKeyPropsRec(KeyPropsList.Strings[0])^;
	end
	else begin
	  Result:=kPGPError_SecretKeyNotFound;
	  Exit;
	end;
      end;
      FPassphrase:=PGPNewSecureData(PGPGetDefaultMemoryMgr, PassBufSize, kPGPMemoryMgrFlags_Clear);
      if FPassphrase<>nil then begin
	repeat
	  FOnEnterPassphrase(FPassphrase, KeyPropsRec, FMinPassLen, FMinPassQual, Cancel);
	  PassLength:=StrLen(FPassphrase);
	  if PGP8X and not Cancel then AnsiToUtf8PChar(FPassphrase, FPassphrase, PassBufSize);
	until Cancel or ((PassLength>=FMinPassLen) and (PGPEstimatePassphraseQuality(FPassphrase)>=FMinPassQual));
	if Cancel then Result:=kPGPError_UserAbort;
      end
      else Result:=kPGPError_OutOfMemory;
    finally
      KeyPropsList.Free;
    end;
  end
  else begin
    if OfMasterKey then begin
      Result:=GetKeySetByAnyIDs(FContext, FKeySetMain, FMasterKeyHexID, KeySetFound);
      if Result<>0 then Exit;
      try
	Result:=KeyPassphraseDialog(FContext, KeySetFound, FPassphrase, FPassDlgPrompt, FParentHandle);
      finally
	PGPFreeKeySet(KeySetFound);
      end;
    end
    else begin
      Result:=ConfirmationPassphraseDialog(FContext, FPassphrase, FMinPassLen, FMinPassQual, true,
					   FPassDlgPrompt, FParentHandle);
    end;
  end;
end;

function TPGPKeysGenerateCustom.GetEntropy(IncludeSubKey: Longbool): PGPError;
var
  OptionList	: pPGPOptionList;
  EntropyNeeded	: PGPUInt32;
  ParamOption	: pPGPoptionList;
begin
  OptionList:=nil;
  Result:=PGPBuildOptionList(FContext, OptionList,
    [
      PGPOKeyGenParams(FContext, PGPPublicKeyAlgorithm(FPubKeyAlgorithm), FKeySize),
      PGPOKeyGenFast(FContext, PGPBoolean(FFastGenerate) and 1)
    ]);
  if Result<>0 then Exit;
  try
    EntropyNeeded:=PGPGetKeyEntropyNeeded(FContext, OptionList, PGPOLastOption(FContext));
  finally
    PGPFreeOptionList(OptionList);
  end;
  if IncludeSubKey then begin
    OptionList:=nil;
    if FPubKeyAlgorithm<>KeyAlgorithm_RSA then
      ParamOption:=PGPOKeyGenParams(FContext, PGPPublicKeyAlgorithm(KeyAlgorithm_DH), FSubKeySize)
    else ParamOption:=PGPOKeyGenParams(FContext, PGPPublicKeyAlgorithm(KeyAlgorithm_RSA), FSubKeySize);
    try
      Result:=PGPBuildOptionList(FContext, OptionList,
	[ParamOption, PGPOKeyGenFast(FContext, PGPBoolean(FFastGenerate) and 1)]);
    finally
      PGPFreeOptionList(ParamOption);
    end;
    if Result<>0 then Exit;
    try
      EntropyNeeded:=EntropyNeeded + PGPGetKeyEntropyNeeded(FContext, OptionList, PGPOLastOption(FContext));
    finally
      PGPFreeOptionList(OptionList);
    end;
  end;
  if FFailNoEntropy and (EntropyNeeded>PGPGlobalRandomPoolGetEntropy) then begin
    Result:=kPGPError_OutOfEntropy;
    Exit;
  end;
  // PGP 8 returns kPGPError_OutOfEntropy if we don't call CollectRandomDataDialog() in any case
  Result:=CollectRandomDataDialog(FContext, EntropyNeeded, FParentHandle);
end;

function GetPGPCipherAlgorithm(CipherAlgorithm: TCipherAlgorithm): PGPCipherAlgorithm;
begin
  Result:=PGPCipherAlgorithm(
    ord(CipherAlgorithm) +
    ord(CipherAlgorithm>CipherAlgorithm_CAST5) * ord(pred(kPGPCipherAlgorithm_AES128-kPGPCipherAlgorithm_CAST5))
  );
end;

function TPGPKeysGenerateCustom.KeyGenerate(IncludeSubKey: Longbool): PGPError;
var
  OptionList	: pPGPOptionList;
  CipherAlgs	: TPGPCipherAlgorithms;
  CipherIndex	: Longint;
  UsageOption	: pPGPOptionList;
  UserIDUtf8	: UTF8String;
  NewKey	: pPGPKey;
begin
  OptionList:=nil;
  if FCipherAlgorithmList[0]=CipherAlgorithm_None then begin
    case FCipherAlgorithm of
      CipherAlgorithm_None: begin
	case FPubKeyAlgorithm of
	  KeyAlgorithm_RSA: FCipherAlgorithm:=CipherAlgorithm_IDEA;
	  KeyAlgorithm_DSS: FCipherAlgorithm:=CipherAlgorithm_CAST5;
	end;
      end;
    end;
    CipherAlgs[0]:=GetPGPCipherAlgorithm(FCipherAlgorithm);
    CipherIndex:=1;
  end
  else begin
    CipherIndex:=0;
    while FCipherAlgorithmList[CipherIndex]<>CipherAlgorithm_None do begin
      CipherAlgs[CipherIndex]:=GetPGPCipherAlgorithm(FCipherAlgorithmList[CipherIndex]);
      inc(CipherIndex);
    end;
  end;
  if PGP7X and not FLegacyKey then
    UsageOption:=PGPOKeyFlags(FContext, kPGPKeyPropertyFlags_UsageSign)
  else UsageOption:=PGPONullOption(FContext);
  if PGP8X then
    UserIDUtf8:=AnsiToUtf8(FUserID)
  else UserIDUtf8:=FUserID;
  try
    Result:=PGPBuildOptionList(FContext, OptionList,
      [
	PGPOKeySetRef(FContext, FKeySetMain),
	PGPOPassphrase(FContext, FPassphrase),
	PGPOKeyGenName(FContext, PChar(UserIDUtf8), Length(UserIDUtf8)),
	PGPOKeyGenParams(FContext, PGPPublicKeyAlgorithm(FPubKeyAlgorithm), FKeySize),
	PGPOPreferredAlgorithms(FContext, CipherAlgs, CipherIndex),
	PGPOKeyGenFast(FContext, PGPBoolean(FFastGenerate) and 1),
	PGPOExpiration(FContext, FExpires),
	UsageOption,
	PGPOEventHandler(FContext, EventHandler, Self)
      ]);
  finally
    PGPFreeOptionList(UsageOption);
  end;
  if Result<>0 then Exit;
  try
    Result:=PGPGenerateKey(FContext, NewKey, OptionList, PGPOLastOption(FContext));
    if Result<>0 then Exit;
    if not IncludeSubKey then begin
      Result:=KeyRings.UpdateKeyRings;
      if Result<>0 then Exit;
    end;
    FNewKeyHexID:=GetKeyPropKeyID(NewKey);
  finally
    PGPFreeOptionList(OptionList);
  end;
end;

function TPGPKeysGenerateCustom.SubKeyGenerate(ForOldMasterKey: Longbool): PGPError;
var
  OptionList	: pPGPOptionList;
  MasterKey	: pPGPKey;
  UsageOption	: pPGPOptionList;
  NewSubKey	: pPGPKey;
begin
  OptionList:=nil;
  Result:=GetKeyByHexID(FKeySetMain, FMasterKeyHexID, MasterKey);
  if Result<>0 then Exit;
  if PGP7X and not FLegacyKey then
    UsageOption:=PGPOKeyFlags(FContext, kPGPKeyPropertyFlags_UsageEncrypt)
  else UsageOption:=PGPONullOption(FContext);
  try
    Result:=PGPBuildOptionList(FContext, OptionList,
      [
	PGPOKeyGenMasterKey(FContext, MasterKey),
	PGPOPassphrase(FContext, FPassphrase),
	PGPOKeyGenParams(FContext, PGPPublicKeyAlgorithm(FPubKeyAlgorithm), FSubKeySize),
	PGPOKeyGenFast(FContext, PGPBoolean(FFastGenerate) and 1),
	PGPOExpiration(FContext, FExpires),
	UsageOption,
	PGPOEventHandler(FContext, EventHandler, Self)
      ]);
  finally
    PGPFreeOptionList(UsageOption);
  end;
  if Result<>0 then Exit;
  try
    Result:=PGPGenerateSubKey(FContext, NewSubKey, OptionList, PGPOLastOption(FContext));
    if Result<>0 then Exit;
    Result:=KeyRings.UpdateKeyRings;
    if Result<>0 then Exit;
    if ForOldMasterKey then FUserID:=GetKeyPropUserID(MasterKey);
    FNewSubKeyHexID:=GetSubKeyPropKeyID(NewSubKey);
  finally
    PGPFreeOptionList(OptionList);
  end;
end;

procedure TPGPKeysGenerateCustom.SetCipherAlgPrefs(const CipherAlgList: Array of TCipherAlgorithm);
var
  CipherCount	: Longint;
  CipherIndex	: Longint;
begin
  CipherCount:=succ(high(CipherAlgList));
  if CipherCount>high(TCipherCount) then CipherCount:=high(TCipherCount);
  for CipherIndex:=0 to pred(CipherCount) do FCipherAlgorithmList[CipherIndex]:=CipherAlgList[CipherIndex];
  FCipherAlgorithmList[CipherCount]:=CipherAlgorithm_None;
end;

function TPGPKeysGenerateCustom.DHDSSKeyGenerate: Longint;
begin
  Result:=0;
  Result:=InitKeyGen;
  if Result<>0 then Exit;
  try
    Result:=GetUserNameAddress;
    if Result<>0 then Exit;
    if FKeySize>1024 then FKeySize:=1024;
    FPubKeyAlgorithm:=KeyAlgorithm_DSS;
    FUserID:=GetUserID;
    Result:=GetPassphrase(false);
    if Result<>0 then Exit;
    Result:=GetEntropy(true);
    if Result<>0 then Exit;
    Result:=KeyGenerate(true);
    if Result<>0 then Exit;
    FPubKeyAlgorithm:=KeyAlgorithm_DH;
    FMasterKeyHexID:=FNewKeyHexID;
    Result:=SubKeyGenerate(false);
    if Result=0 then FNewHexID:=FNewKeyHexID;
  finally
    FinitKeyGen(Result);
  end;
end;

function TPGPKeysGenerateCustom.DHSubKeyGenerate: Longint;
begin
  Result:=0;
  Result:=InitKeyGen;
  if Result<>0 then Exit;
  try
    Result:=GetMasterKeyHexID;
    if Result<>0 then Exit;
    FPubKeyAlgorithm:=KeyAlgorithm_DH;
    Result:=GetPassphrase(true);
    if Result<>0 then Exit;
    Result:=GetEntropy(false);
    if Result<>0 then Exit;
    Result:=SubKeyGenerate(true);
    if Result=0 then FNewHexID:=FNewSubKeyHexID;
  finally
    FinitKeyGen(Result);
  end;
end;

function TPGPKeysGenerateCustom.DSAKeyGenerate: Longint;
begin
  Result:=0;
  Result:=InitKeyGen;
  if Result<>0 then Exit;
  try
    Result:=GetUserNameAddress;
    if Result<>0 then Exit;
    if FKeySize>1024 then FKeySize:=1024;
    FPubKeyAlgorithm:=KeyAlgorithm_DSS;
    FUserID:=GetUserID;
    Result:=GetPassphrase(false);
    if Result<>0 then Exit;
    Result:=GetEntropy(false);
    if Result<>0 then Exit;
    Result:=KeyGenerate(false);
    if Result=0 then FNewHexID:=FNewKeyHexID;
  finally
    FinitKeyGen(Result);
  end;
end;

function TPGPKeysGenerateCustom.RSASubKeyGenerate: Longint;
begin
  Result:=0;
  Result:=InitKeyGen;
  if Result<>0 then Exit;
  try
    Result:=GetMasterKeyHexID;
    if Result<>0 then Exit;
    FPubKeyAlgorithm:=KeyAlgorithm_RSA;
    Result:=GetPassphrase(true);
    if Result<>0 then Exit;
    Result:=GetEntropy(false);
    if Result<>0 then Exit;
    Result:=SubKeyGenerate(true);
    if Result=0 then FNewHexID:=FNewSubKeyHexID;
  finally
    FinitKeyGen(Result);
  end;
end;

function TPGPKeysGenerateCustom.RSAKeyGenerate(Legacy: Longbool): Longint;
begin
  if Legacy or PGP7X then begin
    Result:=0;
    Result:=InitKeyGen;
    if Result<>0 then Exit;
    try
      Result:=GetUserNameAddress;
      if Result<>0 then Exit;
      FPubKeyAlgorithm:=KeyAlgorithm_RSA;
      FUserID:=GetUserID;
      FLegacyKey:=Legacy;
      Result:=GetPassphrase(false);
      if Result<>0 then Exit;
      Result:=GetEntropy(not Legacy);
      if Result<>0 then Exit;
      Result:=KeyGenerate(not Legacy);
      if Result<>0 then Exit;
      if not Legacy then begin
	FPubKeyAlgorithm:=KeyAlgorithm_RSA;
	FMasterKeyHexID:=FNewKeyHexID;
	Result:=SubKeyGenerate(false);
      end;
      if Result=0 then FNewHexID:=FNewKeyHexID;
    finally
      FinitKeyGen(Result);
    end;
  end
  else Result:=kPGPError_UnknownKeyVersion;
end;

end.

⌨️ 快捷键说明

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