Change Passphrase, and fix deadlock on exporting

This commit is contained in:
Mike Dilger 2023-02-11 11:32:37 +13:00
parent d5d1f2fee3
commit 20b3a19069
5 changed files with 84 additions and 2 deletions

View File

@ -5,6 +5,7 @@ use nostr_types::{Event, Id, IdHex, Metadata, PublicKey, PublicKeyHex, RelayUrl,
pub enum ToOverlordMessage {
AddRelay(RelayUrl),
AdvertiseRelayList,
ChangePassphrase(String, String),
DeletePub,
DeletePriv(String),
DropRelay(RelayUrl),

View File

@ -447,6 +447,11 @@ impl Overlord {
ToOverlordMessage::AdvertiseRelayList => {
self.advertise_relay_list().await?;
}
ToOverlordMessage::ChangePassphrase(mut old, mut new) => {
GLOBALS.signer.change_passphrase(&old, &new)?;
old.zeroize();
new.zeroize();
}
ToOverlordMessage::DeletePub => {
GLOBALS.signer.clear_public_key();
GLOBALS.signer.save_through_settings().await?;

View File

@ -94,6 +94,26 @@ impl Signer {
}
}
pub fn change_passphrase(&self, old: &str, new: &str) -> Result<(), Error> {
let maybe_encrypted = self.encrypted.read().to_owned();
match maybe_encrypted {
Some(epk) => {
// Test password
let pk = epk.decrypt(old)?;
let epk = pk.export_encrypted(new, DEFAULT_LOG_N)?;
*self.encrypted.write() = Some(epk);
task::spawn(async move {
if let Err(e) = GLOBALS.signer.save_through_settings().await {
tracing::error!("{}", e);
}
*GLOBALS.status_message.write().await = "Passphrase changed.".to_owned()
});
Ok(())
}
_ => Err(Error::NoPrivateKey),
}
}
pub fn generate_private_key(&self, pass: &str) -> Result<(), Error> {
let pk = PrivateKey::generate();
*self.encrypted.write() = Some(pk.export_encrypted(pass, DEFAULT_LOG_N)?);
@ -133,7 +153,8 @@ impl Signer {
}
pub fn export_private_key_bech32(&self, pass: &str) -> Result<String, Error> {
match &*self.encrypted.read() {
let maybe_encrypted = self.encrypted.read().to_owned();
match maybe_encrypted {
Some(epk) => {
// Test password
let mut pk = epk.decrypt(pass)?;
@ -157,7 +178,8 @@ impl Signer {
}
pub fn export_private_key_hex(&self, pass: &str) -> Result<String, Error> {
match &*self.encrypted.read() {
let maybe_encrypted = self.encrypted.read().to_owned();
match maybe_encrypted {
Some(epk) => {
// Test password
let mut pk = epk.decrypt(pass)?;

View File

@ -123,6 +123,7 @@ struct GossipUi {
follow_pubkey_at_relay: String,
password: String,
password2: String,
password3: String,
del_password: String,
new_metadata_fieldname: String,
import_priv: String,
@ -134,6 +135,7 @@ impl Drop for GossipUi {
fn drop(&mut self) {
self.password.zeroize();
self.password2.zeroize();
self.password3.zeroize();
self.del_password.zeroize();
}
}
@ -250,6 +252,7 @@ impl GossipUi {
follow_pubkey_at_relay: "".to_owned(),
password: "".to_owned(),
password2: "".to_owned(),
password3: "".to_owned(),
del_password: "".to_owned(),
new_metadata_fieldname: String::new(),
import_priv: "".to_owned(),

View File

@ -62,6 +62,12 @@ pub(super) fn update(app: &mut GossipUi, ctx: &Context, _frame: &mut eframe::Fra
ui.separator();
ui.add_space(10.0);
offer_change_password(app, ui);
ui.add_space(10.0);
ui.separator();
ui.add_space(10.0);
offer_export_priv_key(app, ui);
ui.add_space(10.0);
@ -211,6 +217,51 @@ fn show_priv_key_detail(_app: &mut GossipUi, ui: &mut Ui) {
}
}
fn offer_change_password(app: &mut GossipUi, ui: &mut Ui) {
ui.heading("Change Passphrase");
ui.horizontal(|ui| {
ui.add_space(10.0);
ui.label("Enter Existing Passphrase: ");
ui.add(TextEdit::singleline(&mut app.password).password(true));
});
ui.horizontal(|ui| {
ui.add_space(10.0);
ui.label("Enter New Passphrase: ");
ui.add(TextEdit::singleline(&mut app.password2).password(true));
});
ui.horizontal(|ui| {
ui.add_space(10.0);
ui.label("Repeat New Passphrase: ");
ui.add(TextEdit::singleline(&mut app.password3).password(true));
});
if ui.button("Change Passphrase").clicked() {
if app.password2 != app.password3 {
*GLOBALS.status_message.blocking_write() = "Passphrases do not match.".to_owned();
app.password2.zeroize();
app.password2 = "".to_owned();
app.password3.zeroize();
app.password3 = "".to_owned();
} else {
let _ = GLOBALS
.to_overlord
.send(ToOverlordMessage::ChangePassphrase(
app.password.clone(),
app.password2.clone(),
));
app.password.zeroize();
app.password = "".to_owned();
app.password2.zeroize();
app.password2 = "".to_owned();
app.password3.zeroize();
app.password3 = "".to_owned();
}
}
}
fn offer_export_priv_key(app: &mut GossipUi, ui: &mut Ui) {
let key_security = GLOBALS.signer.key_security().unwrap();