retain the existing wallet encryption when a password change is cancelled

This commit is contained in:
Craig Raw
2026-08-20 08:34:11 +02:00
parent 1e660ad230
commit 194bd70f86
2 changed files with 55 additions and 22 deletions
@@ -170,17 +170,16 @@ public class SettingsDialog extends WalletDialog {
}
}
private void saveWallet(boolean changePassword, boolean suggestChangePassword) {
//Returns true if the wallet save was initiated, and false if it was abandoned without any change to the wallet or its storage
private boolean saveWallet(boolean changePassword, boolean suggestChangePassword) {
WalletForm walletForm = getWalletForm();
ECKey existingPubKey = walletForm.getStorage().getEncryptionPubKey();
PasswordRequirement requirement;
if(existingPubKey == null) {
if(changePassword) {
requirement = PasswordRequirement.UPDATE_CHANGE;
} else {
requirement = PasswordRequirement.UPDATE_NEW;
}
if(changePassword) {
requirement = PasswordRequirement.UPDATE_CHANGE;
} else if(existingPubKey == null) {
requirement = PasswordRequirement.UPDATE_NEW;
} else if(Storage.NO_PASSWORD_KEY.equals(existingPubKey)) {
requirement = PasswordRequirement.UPDATE_EMPTY;
} else {
@@ -213,7 +212,8 @@ public class SettingsDialog extends WalletDialog {
try {
ECKey encryptionPubKey = ECKey.fromPublicOnly(encryptionFullKey);
if(existingPubKey != null && !Storage.NO_PASSWORD_KEY.equals(existingPubKey) && !existingPubKey.equals(encryptionPubKey)) {
//When changing the password, the existing encryption key is retained until the new one is derived, so a different key is expected here
if(!changePassword && existingPubKey != null && !Storage.NO_PASSWORD_KEY.equals(existingPubKey) && !existingPubKey.equals(encryptionPubKey)) {
AppServices.showErrorDialog("Incorrect Password", "The password was incorrect.");
return;
}
@@ -222,14 +222,32 @@ public class SettingsDialog extends WalletDialog {
Wallet masterWallet = walletForm.getWallet().isMasterWallet() ? walletForm.getWallet() : walletForm.getWallet().getMasterWallet();
if(suggestChangePassword && requirement == PasswordRequirement.UPDATE_SET) {
walletForm.getStorage().setEncryptionPubKey(null);
masterWallet.decrypt(key);
for(Wallet childWallet : masterWallet.getChildWallets()) {
if(!childWallet.isNested()) {
childWallet.decrypt(key);
}
}
SparrowTerminal.get().getGuiThread().invokeLater(() -> saveWallet(true, false));
//The next dialog is shown on the gui thread, so hand the existing key over to re-encrypt with rather than clearing it here
Key existingKey = key;
key = null;
SparrowTerminal.get().getGuiThread().invokeLater(() -> {
boolean saving = saveWallet(true, false);
Platform.runLater(() -> {
//If a new password is not provided, re-encrypt with the existing key rather than leaving the wallet decrypted for the session
if(!saving) {
masterWallet.encrypt(existingKey);
for(Wallet childWallet : masterWallet.getChildWallets()) {
if(!childWallet.isNested()) {
childWallet.encrypt(existingKey);
}
}
}
existingKey.clear();
});
});
return;
}
@@ -259,7 +277,11 @@ public class SettingsDialog extends WalletDialog {
keyDerivationService.start();
}
});
return true;
}
return false;
}
public static List<String> splitString(String stringToSplit, int maxLength) {
@@ -956,16 +956,15 @@ public class SettingsController extends WalletFormController implements Initiali
}
}
private void saveWallet(boolean changePassword, boolean suggestChangePassword) {
//Returns true if the wallet save was initiated, and false if it was abandoned without any change to the wallet or its storage
private boolean saveWallet(boolean changePassword, boolean suggestChangePassword) {
ECKey existingPubKey = walletForm.getStorage().getEncryptionPubKey();
WalletPasswordDialog.PasswordRequirement requirement;
if(existingPubKey == null) {
if(changePassword) {
requirement = WalletPasswordDialog.PasswordRequirement.UPDATE_CHANGE;
} else {
requirement = WalletPasswordDialog.PasswordRequirement.UPDATE_NEW;
}
if(changePassword) {
requirement = WalletPasswordDialog.PasswordRequirement.UPDATE_CHANGE;
} else if(existingPubKey == null) {
requirement = WalletPasswordDialog.PasswordRequirement.UPDATE_NEW;
} else if(Storage.NO_PASSWORD_KEY.equals(existingPubKey)) {
requirement = WalletPasswordDialog.PasswordRequirement.UPDATE_EMPTY;
} else {
@@ -977,7 +976,7 @@ public class SettingsController extends WalletFormController implements Initiali
if(optResponse.isPresent() && optResponse.get().equals(ButtonType.CANCEL)) {
revert.setDisable(false);
apply.setDisable(false);
return;
return false;
}
}
@@ -993,7 +992,7 @@ public class SettingsController extends WalletFormController implements Initiali
AppServices.showErrorDialog("Error saving wallet backup", e.getMessage());
revert.setDisable(false);
apply.setDisable(false);
return;
return false;
}
}
@@ -1018,7 +1017,8 @@ public class SettingsController extends WalletFormController implements Initiali
try {
ECKey encryptionPubKey = ECKey.fromPublicOnly(encryptionFullKey);
if(existingPubKey != null && !Storage.NO_PASSWORD_KEY.equals(existingPubKey) && !existingPubKey.equals(encryptionPubKey)) {
//When changing the password, the existing encryption key is retained until the new one is derived, so a different key is expected here
if(!changePassword && existingPubKey != null && !Storage.NO_PASSWORD_KEY.equals(existingPubKey) && !existingPubKey.equals(encryptionPubKey)) {
AppServices.showErrorDialog("Incorrect Password", "The password was incorrect.");
revert.setDisable(false);
apply.setDisable(false);
@@ -1033,14 +1033,22 @@ public class SettingsController extends WalletFormController implements Initiali
walletForm.deleteBackups();
}
walletForm.getStorage().setEncryptionPubKey(null);
masterWallet.decrypt(key);
for(Wallet childWallet : masterWallet.getChildWallets()) {
if(!childWallet.isNested()) {
childWallet.decrypt(key);
}
}
saveWallet(true, false);
//If a new password is not provided, re-encrypt with the existing key rather than leaving the wallet decrypted for the session
if(!saveWallet(true, false)) {
masterWallet.encrypt(key);
for(Wallet childWallet : masterWallet.getChildWallets()) {
if(!childWallet.isNested()) {
childWallet.encrypt(key);
}
}
}
return;
}
@@ -1077,9 +1085,12 @@ public class SettingsController extends WalletFormController implements Initiali
EventManager.get().post(new StorageEvent(walletForm.getWalletId(), TimedEvent.Action.START, "Encrypting wallet..."));
keyDerivationService.start();
}
return true;
} else {
revert.setDisable(false);
apply.setDisable(false);
return false;
}
}