@@ -548,4 +548,78 @@ public void testUpdateSkipsInvalidVersionKeystores() throws Exception {
548548 assertTrue ("Error should mention no keystore found" ,
549549 err .toString ().contains ("No keystore found" ));
550550 }
551+
552+ @ Test
553+ public void testUpdateRejectsTamperedAddressKeystore () throws Exception {
554+ File dir = tempFolder .newFolder ("keystore-tampered" );
555+ String password = "test123456" ;
556+
557+ // Create a real keystore, then tamper with the address field to simulate
558+ // a spoofed keystore that claims a different address than its encrypted key.
559+ SignInterface keyPair = SignUtils .getGeneratedRandomSign (
560+ SecureRandom .getInstance ("NativePRNG" ), true );
561+ String fileName = WalletUtils .generateWalletFile (password , keyPair , dir , true );
562+ File keystoreFile = new File (dir , fileName );
563+
564+ String realAddress = Credentials .create (keyPair ).getAddress ();
565+ String spoofedAddress = "TSpoofedAddressXXXXXXXXXXXXXXXXXXXX" ;
566+
567+ com .fasterxml .jackson .databind .ObjectMapper mapper =
568+ new com .fasterxml .jackson .databind .ObjectMapper ()
569+ .configure (com .fasterxml .jackson .databind .DeserializationFeature
570+ .FAIL_ON_UNKNOWN_PROPERTIES , false );
571+ org .tron .keystore .WalletFile wf = mapper .readValue (keystoreFile ,
572+ org .tron .keystore .WalletFile .class );
573+ wf .setAddress (spoofedAddress );
574+ mapper .writeValue (keystoreFile , wf );
575+
576+ File pwFile = tempFolder .newFile ("pw-tampered.txt" );
577+ Files .write (pwFile .toPath (),
578+ (password + "\n newpass789" ).getBytes (StandardCharsets .UTF_8 ));
579+
580+ StringWriter err = new StringWriter ();
581+ CommandLine cmd = new CommandLine (new Toolkit ());
582+ cmd .setErr (new PrintWriter (err ));
583+ int exitCode = cmd .execute ("keystore" , "update" , spoofedAddress ,
584+ "--keystore-dir" , dir .getAbsolutePath (),
585+ "--password-file" , pwFile .getAbsolutePath ());
586+
587+ assertEquals ("Should fail decryption on tampered address" , 1 , exitCode );
588+ assertTrue ("Error should mention address mismatch, got: " + err .toString (),
589+ err .toString ().contains ("address mismatch" ));
590+ }
591+
592+ @ Test
593+ public void testUpdatePreservesCorrectDerivedAddress () throws Exception {
594+ // After update, the keystore's address field should be the derived address,
595+ // not carried over from the original JSON (defense-in-depth against any
596+ // residual spoofed address that somehow passed decryption).
597+ File dir = tempFolder .newFolder ("keystore-derived" );
598+ String oldPassword = "oldpass123" ;
599+ String newPassword = "newpass456" ;
600+
601+ SignInterface keyPair = SignUtils .getGeneratedRandomSign (
602+ SecureRandom .getInstance ("NativePRNG" ), true );
603+ String fileName = WalletUtils .generateWalletFile (oldPassword , keyPair , dir , true );
604+ String originalAddress = Credentials .create (keyPair ).getAddress ();
605+
606+ File pwFile = tempFolder .newFile ("pw-derived.txt" );
607+ Files .write (pwFile .toPath (),
608+ (oldPassword + "\n " + newPassword ).getBytes (StandardCharsets .UTF_8 ));
609+
610+ CommandLine cmd = new CommandLine (new Toolkit ());
611+ int exitCode = cmd .execute ("keystore" , "update" , originalAddress ,
612+ "--keystore-dir" , dir .getAbsolutePath (),
613+ "--password-file" , pwFile .getAbsolutePath ());
614+
615+ assertEquals (0 , exitCode );
616+
617+ // Verify updated file has the derived address
618+ com .fasterxml .jackson .databind .ObjectMapper mapper =
619+ new com .fasterxml .jackson .databind .ObjectMapper ();
620+ org .tron .keystore .WalletFile wf = mapper .readValue (new File (dir , fileName ),
621+ org .tron .keystore .WalletFile .class );
622+ assertEquals ("Updated keystore address must match derived address" ,
623+ originalAddress , wf .getAddress ());
624+ }
551625}
0 commit comments