Browse Source

Allow check valid public key based on Current Protocol

PascalCoin 5 years ago
parent
commit
90392b2f8e

+ 14 - 14
src/core/UAccounts.pas

@@ -139,10 +139,10 @@ Type
   TAccountComp = Class
   private
   public
-    Class Function IsValidAccountKey(const AAccountInfo: TAccountKey; var errors : String): Boolean;
+    Class Function IsValidAccountKey(const AAccountInfo: TAccountKey; ACurrentProtocol : Word; var errors : String): Boolean;
     Class function IsNullAccountKey(const AAccountInfo : TAccountKey) : Boolean;
     Class function IsValidNewAccountKey(const AAccountInfo : TAccountInfo; const ANewKey : TAccountKey; AProtocolVersion : Integer) : Boolean;
-    Class Function IsValidAccountInfo(const AAccountInfo: TAccountInfo; var errors : String): Boolean;
+    Class Function IsValidAccountInfo(const AAccountInfo: TAccountInfo; ACurrentProtocol : Word; var errors : String): Boolean;
     Class Function IsValidAccountInfoHashLockKey(const AAccountInfo : TAccountInfo; const AKey : TRawBytes) : Boolean;
     Class Function IsValidHashLockKey(const AKey : TRawBytes; out AError : String) : Boolean;
     Class Function CalculateHashLock(const AKey : TRawBytes) : T32Bytes;
@@ -1649,7 +1649,7 @@ begin
   end;
 
   if (AAccount.accountInfo.state in [as_ForSale, as_ForAtomicAccountSwap]) then begin
-    if NOT IsValidAccountKey(AAccount.accountInfo.new_publicKey,errors) then
+    if NOT IsValidAccountKey(AAccount.accountInfo.new_publicKey,ACurrentProtocol,errors) then
       exit;
   end;
 
@@ -1743,7 +1743,7 @@ begin
       Account.account_data.ToHexaString,Account.account_seal.ToHexaString ]);
 end;
 
-class function TAccountComp.IsValidAccountInfo(const AAccountInfo: TAccountInfo; var errors: String): Boolean;
+class function TAccountComp.IsValidAccountInfo(const AAccountInfo: TAccountInfo; ACurrentProtocol : Word; var errors: String): Boolean;
 Var s : String;
 begin
   errors := '';
@@ -1753,38 +1753,38 @@ begin
         Result := false;
       end;
     as_Normal: begin
-        Result := IsValidAccountKey(AAccountInfo.accountKey,errors);
+        Result := IsValidAccountKey(AAccountInfo.accountKey,ACurrentProtocol,errors);
       end;
     as_ForSale: begin
-        Result := IsValidAccountKey(AAccountInfo.accountKey,errors);
+        Result := IsValidAccountKey(AAccountInfo.accountKey,ACurrentProtocol,errors);
         if (Result) And (IsAccountForPrivateSale(AAccountInfo)) then begin
-          if Not IsValidAccountKey(AAccountInfo.new_publicKey,s) then begin
+          if Not IsValidAccountKey(AAccountInfo.new_publicKey,ACurrentProtocol,s) then begin
             Result := False;
             errors := 'Invalid new_publicKey: '+s;
           end;
         end;
       end;
     as_ForAtomicAccountSwap: begin
-        Result := IsValidAccountKey(AAccountInfo.accountKey,errors);
-        if (Result) And (Not IsValidAccountKey(AAccountInfo.new_publicKey,s)) then begin
+        Result := IsValidAccountKey(AAccountInfo.accountKey,ACurrentProtocol,errors);
+        if (Result) And (Not IsValidAccountKey(AAccountInfo.new_publicKey,ACurrentProtocol,s)) then begin
           Result := False;
           errors := 'Invalid AccountSwap.new_publicKey: '+s;
         end;
       end;
     as_ForAtomicCoinSwap: begin
-      Result := IsValidAccountKey(AAccountInfo.accountKey,errors);
+      Result := IsValidAccountKey(AAccountInfo.accountKey,ACurrentProtocol,errors);
     end
   else
     raise Exception.Create('DEVELOP ERROR 20170214-3');
   end;
 end;
 
-class function TAccountComp.IsValidAccountKey(const AAccountInfo: TAccountKey; var errors : String): Boolean;
+class function TAccountComp.IsValidAccountKey(const AAccountInfo: TAccountKey;  ACurrentProtocol : Word; var errors : String): Boolean;
 begin
   errors := '';
   case AAccountInfo.EC_OpenSSL_NID of
     CT_NID_secp256k1,CT_NID_secp384r1,CT_NID_sect283k1,CT_NID_secp521r1 : begin
-      Result := TECPrivateKey.IsValidPublicKey(AAccountInfo,errors);
+      Result := TECPrivateKey.IsValidPublicKey(AAccountInfo,ACurrentProtocol,errors);
     end;
   else
     errors := Format('Invalid AccountKey type:%d (Unknown type) - Length x:%d y:%d',[AAccountInfo.EC_OpenSSL_NID,length(AAccountInfo.x),length(AAccountInfo.y)]);
@@ -3314,7 +3314,7 @@ begin
             FOrderedByName.Add(LBlock.accounts[iacc].name,LBlock.accounts[iacc].account);
           end;
           If checkAll then begin
-            if not TAccountComp.IsValidAccountInfo(LBlock.accounts[iacc].accountInfo,aux_errors) then begin
+            if not TAccountComp.IsValidAccountInfo(LBlock.accounts[iacc].accountInfo,FCurrentProtocol,aux_errors) then begin
               errors := errors + ' > '+aux_errors;
               Exit;
             end;
@@ -4014,7 +4014,7 @@ begin
   Result := False;
   errors := '';
   // Check Account key
-  if Not TAccountComp.IsValidAccountKey(newOperationBlock.account_key,errors) then begin
+  if Not TAccountComp.IsValidAccountKey(newOperationBlock.account_key,newOperationBlock.protocol_version,errors) then begin
     exit;
   end;
   // reward

+ 9 - 5
src/core/UCrypto.pas

@@ -61,8 +61,8 @@ Type
     Property PublicKey : TECDSA_Public read GetPublicKey;
     Function SetPrivateKeyFromHexa(AEC_OpenSSL_NID : Word; const hexa : String) : Boolean;
     Property EC_OpenSSL_NID : Word Read GetEC_OpenSSL_NID;
-    class function IsValidPublicKey(PubKey : TECDSA_Public; var errors : String) : Boolean; overload;
-    class function IsValidPublicKey(PubKey : TECDSA_Public) : Boolean; overload;
+    class function IsValidPublicKey(PubKey : TECDSA_Public; ACurrentProtocol : Word; var errors : String) : Boolean; overload;
+    class function IsValidPublicKey(PubKey : TECDSA_Public; ACurrentProtocol : Word) : Boolean; overload;
     // Exports a Private key in a RAW saving 2 bytes for EC_OpenSSL_NID, 2 bytes for private key length and private key as a RAW
     Function ExportToRaw : TRawBytes;
     // Imports a Private key saved with "ExportToRaw" format
@@ -377,7 +377,7 @@ begin
   End;
 end;
 
-class function TECPrivateKey.IsValidPublicKey(PubKey: TECDSA_Public; var errors : String): Boolean;
+class function TECPrivateKey.IsValidPublicKey(PubKey: TECDSA_Public; ACurrentProtocol : Word; var errors : String): Boolean;
 {$IFDEF Use_OpenSSL}
 Var BNx,BNy : PBIGNUM;
   ECG : PEC_GROUP;
@@ -390,6 +390,7 @@ begin
     errors := 'Invalid NID '+IntToStr(PubKey.EC_OpenSSL_NID);
     Exit(False);
   end;
+  Result := (Length(PubKey.x)<100) And (Length(PubKey.y)<100);
 {$IFDEF Use_OpenSSL}
   BNx := BN_bin2bn(PAnsiChar(PubKey.x),length(PubKey.x),nil);
   if Not Assigned(BNx) then Exit;
@@ -397,6 +398,9 @@ begin
     BNy := BN_bin2bn(PAnsiChar(PubKey.y),length(PubKey.y),nil);
     if Not Assigned(BNy) then Exit;
     try
+      if ACurrentProtocol>=CT_PROTOCOL_5 then begin
+        Exit;
+      end;
       ECG := EC_GROUP_new_by_curve_name(PubKey.EC_OpenSSL_NID);
       if Not Assigned(ECG) then Exit;
       try
@@ -430,10 +434,10 @@ begin
 {$ENDIF}
 end;
 
-class function TECPrivateKey.IsValidPublicKey(PubKey: TECDSA_Public): Boolean;
+class function TECPrivateKey.IsValidPublicKey(PubKey: TECDSA_Public; ACurrentProtocol : Word): Boolean;
 var Ltmp : String;
 begin
-  Result := IsValidPublicKey(PubKey,Ltmp);
+  Result := IsValidPublicKey(PubKey,ACurrentProtocol,Ltmp);
 end;
 
 procedure TECPrivateKey.SetPrivateKeyInfo(const Value: TECPrivateKeyInfo);

+ 1 - 1
src/core/UNetProtocol.pas

@@ -3511,7 +3511,7 @@ Begin
       exit;
     end;
     FClientPublicKey := TAccountComp.RawString2Accountkey(RawAccountKey);
-    If Not TAccountComp.IsValidAccountKey(FClientPublicKey,errors) then begin
+    If Not TAccountComp.IsValidAccountKey(FClientPublicKey,CT_BUILD_PROTOCOL,errors) then begin
       DisconnectInvalidClient(false,'Invalid Public key: '+TNetData.HeaderDataToText(HeaderData)+' errors: '+errors);
       exit;
     end;

+ 7 - 7
src/core/UOpTransaction.pas

@@ -540,7 +540,7 @@ begin
     exit;
   end;
   If (public_key in FData.changes_type) then begin
-    If Not TAccountComp.IsValidAccountKey( FData.new_accountkey, errors ) then begin
+    If Not TAccountComp.IsValidAccountKey( FData.new_accountkey, ProtocolVersion, errors) then begin
       exit;
     end;
   end;
@@ -972,7 +972,7 @@ begin
       exit;
     end;
 
-    If Not (TAccountComp.IsValidAccountKey(FData.new_accountkey,AErrors)) then exit; // BUG 20171511
+    If Not (TAccountComp.IsValidAccountKey(FData.new_accountkey,ProtocolVersion,AErrors)) then exit;
     LBuyAccountNewPubkey := FData.new_accountkey;
     {$endregion}
   end else if // (is auto buy) OR (is transaction that can buy)
@@ -996,14 +996,14 @@ begin
         // the below line was a bug fix that introduced a new bug, and is retained here for
         // V2-V4 consistency
         //------
-        if Not (TAccountComp.IsValidAccountKey(FData.new_accountkey,AErrors)) then exit; // BUG 20171511
+        if Not (TAccountComp.IsValidAccountKey(FData.new_accountkey,ProtocolVersion,AErrors)) then exit;
         //------
       end;
     end;
 
     // Check that stored "new_publicKey" is valid (when not in coin swap)
     if (Not TAccountComp.IsAccountForCoinSwap(LTarget.accountInfo)) and
-       (Not (TAccountComp.IsValidAccountKey(LTarget.accountInfo.new_publicKey,AErrors))) then exit;
+       (Not (TAccountComp.IsValidAccountKey(LTarget.accountInfo.new_publicKey,ProtocolVersion,AErrors))) then exit;
 
     // NOTE: This is a Transaction opereation (not a buy account operation) that
     // has some "added" effects (private sale, swap...)
@@ -1462,7 +1462,7 @@ begin
     errors := 'Account signer is currently locked';
     exit;
   end;
-  If Not TAccountComp.IsValidAccountKey( FData.new_accountkey, errors ) then begin
+  If Not TAccountComp.IsValidAccountKey( FData.new_accountkey,ProtocolVersion,errors) then begin
     exit;
   end;
   // NEW v2 protocol protection: Does not allow to change key for same key
@@ -1770,7 +1770,7 @@ begin
     errors := 'Insuficient funds';
     exit;
   end;
-  if Not TAccountComp.IsValidAccountKey(FData.new_accountkey,errors) then begin
+  if Not TAccountComp.IsValidAccountKey(FData.new_accountkey,ProtocolVersion,errors) then begin
     Exit;
   end;
   Result := AccountTransaction.UpdateAccountInfo(AccountPreviousUpdatedBlock,
@@ -2000,7 +2000,7 @@ begin
       exit;
     end;
     if LIsPrivateSale OR LIsAccountSwap then begin
-      If Not TAccountComp.IsValidAccountKey( FData.new_public_key, errors ) then begin
+      If Not TAccountComp.IsValidAccountKey( FData.new_public_key,ProtocolVersion,errors) then begin
         errors := 'Invalid new public key: '+errors;
         exit;
       end;

+ 3 - 3
src/core/URPC.pas

@@ -375,7 +375,7 @@ begin
     APubKey := TAccountComp.RawString2Accountkey(TCrypto.HexaToRaw(AInputParams.AsString(APrefix+'enc_pubkey','')));
   end;
   // Final confirmation
-  If Not TAccountComp.IsValidAccountKey(APubKey,LErrors_aux) then begin
+  If Not TAccountComp.IsValidAccountKey(APubKey,CT_BUILD_PROTOCOL,LErrors_aux) then begin
     AErrortxt := 'Invalid public key: '+LErrors_aux;
   end else Result := True;
 end;
@@ -3571,7 +3571,7 @@ begin
       ErrorNum:= CT_RPC_ErrNum_InvalidPubKey;
       exit;
     end;
-    if TAccountComp.IsValidAccountKey(account.accountInfo.accountKey,ansistr) then begin
+    if TAccountComp.IsValidAccountKey(account.accountInfo.accountKey,CT_BUILD_PROTOCOL,ansistr) then begin
       jsonresponse.GetAsVariant('result').Value:=TCrypto.ToHexaString(TAccountComp.AccountKey2RawString(account.accountInfo.accountKey));
       Result := True;
     end else begin
@@ -3588,7 +3588,7 @@ begin
       ErrorNum := CT_RPC_ErrNum_InvalidPubKey;
       exit;
     end;
-    if (TAccountComp.IsValidAccountKey(account.accountInfo.accountKey,ansistr)) then begin
+    if (TAccountComp.IsValidAccountKey(account.accountInfo.accountKey,CT_BUILD_PROTOCOL,ansistr)) then begin
       TPascalCoinJSONComp.FillPublicKeyObject(account.accountInfo.accountKey,GetResultObject);
       Result := True;
     end else begin

+ 1 - 1
src/core/UTxMultiOperation.pas

@@ -670,7 +670,7 @@ begin
       exit;
     end;
     If (public_key in chi.Changes_type) then begin
-      If Not TAccountComp.IsValidAccountKey( chi.New_Accountkey, errors ) then begin
+      If Not TAccountComp.IsValidAccountKey( chi.New_Accountkey, ProtocolVersion, errors) then begin
         Exit;
       end;
     end;

+ 1 - 1
src/core/UWallet.pas

@@ -719,7 +719,7 @@ begin
       raise Exception.Create('Invalid public key value (Not hexa or not an imported format)'+#10+errors);
     accountKey := TAccountComp.RawString2Accountkey(raw);
   end;
-  If not TAccountComp.IsValidAccountKey(accountKey,errors) then
+  If not TAccountComp.IsValidAccountKey(accountKey,CT_BUILD_PROTOCOL,errors) then
     raise Exception.Create('This data is not a valid public key'+#10+errors);
   if FKeys.IndexOfAccountKey(accountKey)>=0 then
     raise exception.Create('This key exists on your wallet');

+ 4 - 2
src/gui-classic/UFRMAccountSelect.pas

@@ -161,12 +161,14 @@ procedure TSearchThread.BCExecute;
     errors : String;
     i : Integer;
     LBlocksCount : Integer;
+    LCurrentProtocol : Word;
   begin
     SetLength(FAccounts,0);
     c := 0;
     maxC := FSearchValues.SafeBox.AccountsCount-1;
-    validAccKey := TAccountComp.IsValidAccountKey(FSearchValues.inAccountKey,errors);
+    validAccKey := TAccountComp.IsValidAccountKey(FSearchValues.inAccountKey,CT_BUILD_PROTOCOL,errors);
     LBlocksCount := FSearchValues.SafeBox.BlocksCount;
+    LCurrentProtocol := FSearchValues.SafeBox.CurrentProtocol;
     while (c<=maxC) And (Not Terminated) And (Not FDoStopSearch) do begin
       account := FSearchValues.SafeBox.Account(c);
       isValid := True;
@@ -195,7 +197,7 @@ procedure TSearchThread.BCExecute;
       end;
       If IsValid And (Length(FSearchValues.searchName)>0) then begin
         i := TBaseType.FindIn(FSearchValues.searchName,account.name);
-        IsValid := i>0;
+        IsValid := i>=0;
       end;
       //
       if IsValid then begin

+ 1 - 1
src/gui-classic/UFRMWalletKeys.pas

@@ -426,7 +426,7 @@ begin
     if Length(raw)=0 then raise Exception.Create('Invalid public key value (Not hexa or not an imported format)'+#10+errors);
     account := TAccountComp.RawString2Accountkey(raw);
   end;
-  If not TAccountComp.IsValidAccountKey(account,errors) then raise Exception.Create('This data is not a valid public key'+#10+errors);
+  If not TAccountComp.IsValidAccountKey(account,CT_BUILD_PROTOCOL,errors) then raise Exception.Create('This data is not a valid public key'+#10+errors);
   if WalletKeys.IndexOfAccountKey(account)>=0 then raise exception.Create('This key exists on your wallet');
   s := 'Imported public key '+DateTimeToStr(now);
   if InputQuery('Set a name','Name for this private key:',s) then begin