Generate or Import a Key pair

This commit is contained in:
Mike Dilger 2022-12-27 21:21:22 +13:00
parent e440475755
commit e327891a52
4 changed files with 177 additions and 3 deletions

View File

@ -14,6 +14,7 @@ use tokio::sync::broadcast::Sender;
use tokio::sync::mpsc::UnboundedReceiver;
use tokio::{select, task};
use tracing::{debug, error, info, warn};
use zeroize::Zeroize;
pub struct Overlord {
to_minions: Sender<BusMessage>,
@ -384,6 +385,49 @@ impl Overlord {
let data: (String, String) = serde_json::from_str(&bus_message.json_payload)?;
Overlord::follow_hexkey(data.0, data.1).await?;
}
"unlock_key" => {
let mut password: String = serde_json::from_str(&bus_message.json_payload)?;
GLOBALS
.signer
.write()
.await
.unlock_encrypted_private_key(&password)?;
password.zeroize();
// Update public key from private key
let public_key = GLOBALS.signer.read().await.public_key().unwrap();
{
let mut settings = GLOBALS.settings.write().await;
settings.public_key = Some(public_key);
settings.save().await?;
}
}
"import_bech32" => {
let (mut import_bech32, mut password): (String, String) =
serde_json::from_str(&bus_message.json_payload)?;
let pk = PrivateKey::try_from_bech32_string(&import_bech32)?;
import_bech32.zeroize();
let epk = pk.export_encrypted(&password)?;
{
let mut signer = GLOBALS.signer.write().await;
signer.load_encrypted_private_key(epk.clone());
signer.unlock_encrypted_private_key(&password)?;
}
password.zeroize();
}
"import_hex" => {
let (mut import_hex, mut password): (String, String) =
serde_json::from_str(&bus_message.json_payload)?;
let pk = PrivateKey::try_from_hex_string(&import_hex)?;
import_hex.zeroize();
let epk = pk.export_encrypted(&password)?;
{
let mut signer = GLOBALS.signer.write().await;
signer.load_encrypted_private_key(epk.clone());
signer.unlock_encrypted_private_key(&password)?;
}
password.zeroize();
}
_ => {}
},
_ => {}

View File

@ -14,6 +14,7 @@ use crate::settings::Settings;
use eframe::{egui, IconData, Theme};
use egui::{ColorImage, Context, ImageData, TextureHandle, TextureOptions};
use nostr_types::{PublicKey, PublicKeyHex};
use zeroize::Zeroize;
pub fn run() -> Result<(), Error> {
let icon_bytes = include_bytes!("../../gossip.png");
@ -67,6 +68,15 @@ struct GossipUi {
follow_bech32_pubkey: String,
follow_hex_pubkey: String,
follow_pubkey_at_relay: String,
password: String,
import_bech32: String,
import_hex: String,
}
impl Drop for GossipUi {
fn drop(&mut self) {
self.password.zeroize();
}
}
impl GossipUi {
@ -122,6 +132,9 @@ impl GossipUi {
follow_bech32_pubkey: "".to_owned(),
follow_hex_pubkey: "".to_owned(),
follow_pubkey_at_relay: "".to_owned(),
password: "".to_owned(),
import_bech32: "".to_owned(),
import_hex: "".to_owned(),
}
}
}

View File

@ -19,6 +19,8 @@ pub(super) fn update(app: &mut GossipUi, ctx: &Context, _frame: &mut eframe::Fra
ui.heading("NOTICE: Gossip doesn't update the filters when you follow someone yet, so you have to restart the client to fetch their events. Will fix soon.");
ui.label("NOTICE: use CTRL-V to paste (middle/right click wont work)");
ui.add_space(10.0);
ui.separator();
ui.add_space(10.0);

View File

@ -1,7 +1,122 @@
use super::GossipUi;
use crate::comms::BusMessage;
use crate::globals::GLOBALS;
use eframe::egui;
use egui::{Context, Ui};
use egui::{Context, TextEdit, Ui};
use nostr_types::{KeySecurity, PublicKeyHex};
use tracing::info;
use zeroize::Zeroize;
pub(super) fn update(_app: &mut GossipUi, _ctx: &Context, _frame: &mut eframe::Frame, ui: &mut Ui) {
ui.heading("Your Identities");
pub(super) fn update(app: &mut GossipUi, _ctx: &Context, _frame: &mut eframe::Frame, ui: &mut Ui) {
ui.add_space(30.0);
ui.label("NOTICE: use CTRL-V to paste (middle/right click wont work)");
ui.add_space(10.0);
ui.separator();
ui.add_space(10.0);
if GLOBALS.signer.blocking_read().is_ready() {
ui.heading("Ready to sign events");
let key_security = GLOBALS.signer.blocking_read().key_security().unwrap();
let public_key = GLOBALS.signer.blocking_read().public_key().unwrap();
ui.label(&*format!(
"Private Key security is {}",
match key_security {
KeySecurity::Weak => "weak",
KeySecurity::Medium => "medium",
}
));
let pkhex: PublicKeyHex = public_key.into();
ui.label(&format!("Public Key: {}", pkhex.0));
} else if GLOBALS.signer.blocking_read().is_loaded() {
ui.heading("Password Needed");
ui.horizontal(|ui| {
ui.label("Password: ");
ui.add(TextEdit::singleline(&mut app.password).password(true));
});
if ui.button("Unlock Private Key").clicked() {
let tx = GLOBALS.to_overlord.clone();
let _ = tx.send(BusMessage {
target: "overlord".to_string(),
kind: "unlock_key".to_string(),
json_payload: serde_json::to_string(&app.password).unwrap(),
});
app.password.zeroize();
app.password = "".to_owned();
}
} else {
ui.heading("Generate a Keypair");
if ui.button("Generate Now").clicked() {
info!("TBD GENERATE");
}
ui.add_space(10.0);
ui.separator();
ui.add_space(10.0);
ui.heading("Import a bech32 private key");
ui.horizontal(|ui| {
ui.label("Enter bech32 private key");
ui.add(
TextEdit::singleline(&mut app.import_bech32)
.hint_text("nsec1...")
.password(true),
);
});
ui.horizontal(|ui| {
ui.label("Enter a password to keep it encrypted under");
ui.add(TextEdit::singleline(&mut app.password).password(true));
});
if ui.button("import").clicked() {
let tx = GLOBALS.to_overlord.clone();
let _ = tx.send(BusMessage {
target: "overlord".to_string(),
kind: "import_bech32".to_string(),
json_payload: serde_json::to_string(&(&app.import_bech32, &app.password)).unwrap(),
});
app.import_bech32.zeroize();
app.import_bech32 = "".to_owned();
app.password.zeroize();
app.password = "".to_owned();
}
ui.add_space(10.0);
ui.separator();
ui.add_space(10.0);
ui.heading("Import a hex private key");
ui.horizontal(|ui| {
ui.label("Enter hex-encoded private key");
ui.add(
TextEdit::singleline(&mut app.import_hex)
.hint_text("0123456789abcdef...")
.password(true),
);
});
ui.horizontal(|ui| {
ui.label("Enter a password to keep it encrypted under");
ui.add(TextEdit::singleline(&mut app.password).password(true));
});
if ui.button("import").clicked() {
let tx = GLOBALS.to_overlord.clone();
let _ = tx.send(BusMessage {
target: "overlord".to_string(),
kind: "import_hex".to_string(),
json_payload: serde_json::to_string(&(&app.import_hex, &app.password)).unwrap(),
});
app.import_hex.zeroize();
app.import_hex = "".to_owned();
app.password.zeroize();
app.password = "".to_owned();
}
}
}