Potential TECPrivateKey leak in UWallet.pas

Started by Skybuck, January 27, 2022, 01:29:11 PM

Previous topic - Next topic

Skybuck

Line 335 in UWallet.pas:

See *** for problem spots.

LtmpECPrivKey : TECPrivateKey conditionally destroyed see ***

Only destroyed on exception see ***

procedure TWalletKeys.GeneratePrivateKeysFromPassword;
Var i : Integer;
P : PWalletKey;
raw : TRawBytes;
isOk : Boolean;
LtmpECPrivKey : TECPrivateKey;
begin
  FIsValidPassword := false;
  isOk := true;
  for i := 0 to FSearchableKeys.Count - 1 do begin
    P := FSearchableKeys;
    FreeAndNil(P^.PrivateKey);
  end;
  // try to unencrypt
  for i := 0 to FSearchableKeys.Count - 1 do begin
    P := FSearchableKeys;
    if P^.HasPrivateKey then begin
      isOk := TPCEncryption.DoPascalCoinAESDecrypt(P^.CryptedKey, TEncoding.ASCII.GetBytes(FWalletPassword), raw );
      If isOk then begin
        LtmpECPrivKey := TECPrivateKey.Create;  // *** CREATED ***
        try
          LtmpECPrivKey.SetPrivateKeyFromHexa(P^.AccountKey.EC_OpenSSL_NID,TEncoding.ASCII.GetString(raw));
          if not TAccountComp.EqualAccountKeys(LtmpECPrivKey.PublicKey,P^.AccountKey) then begin
            TLog.NewLog(lterror,ClassName,Format('Private key and public key does not match! %s <> %s',
              [TAccountComp.AccountPublicKeyExport(LtmpECPrivKey.PublicKey),
               TAccountComp.AccountPublicKeyExport(P^.AccountKey)]));
            LtmpECPrivKey.Free; // *** CONDITIONALLY DESTROYED ***
            isOk := False;
          end else P^.PrivateKey := LtmpECPrivKey;
        except
          on E: Exception do begin
            LtmpECPrivKey.Free; // *** ONLY DESTROYED ON EXCEPTION ***
            isOk := false;
            TLog.NewLog(lterror,ClassName,Format('Fatal error when generating EC private key %d/%d: %s',[i+1,FSearchableKeys.Count,E.Message]));
          end;
        end;
      end;
    end;
  end;
  FIsValidPassword := isOk;
end;