persistence: pem storage now working

This commit is contained in:
Dave Hrycyszyn
2019-12-12 15:36:18 +00:00
parent 14f0c1afbf
commit 71f06b1efc
6 changed files with 80 additions and 25 deletions
+6 -7
View File
@@ -1,21 +1,20 @@
use crate::banner;
use crate::identity::mixnet;
use crate::persistence::pathfinder::Pathfinder;
use crate::persistence::pemstore::PemStore;
use clap::ArgMatches;
use dirs;
pub fn execute(matches: &ArgMatches) {
println!("{}", banner());
println!("Initialising client...");
let id = matches.value_of("id").unwrap(); // required for now
let os_config_dir = dirs::config_dir().unwrap(); // grabs the OS default config dir
let nym_client_config_dir = os_config_dir.join("nym").join("clients").join(id);
let id = matches.value_of("id").unwrap().to_string(); // required for now
let pathfinder = Pathfinder::new(id);
println!("Writing keypairs to {:?}...", nym_client_config_dir);
println!("Writing keypairs to {:?}...", pathfinder.config_dir);
let mix_keys = mixnet::KeyPair::new();
let pem_store = PemStore::new();
pem_store.write(mix_keys, nym_client_config_dir);
let pem_store = PemStore::new(pathfinder);
pem_store.write(mix_keys);
println!("Client configuration completed.\n\n\n")
}
+2 -5
View File
@@ -1,5 +1,5 @@
use crate::clients::directory;
use crate::clients::directory::presence::{MixNodePresence, Topology};
use crate::clients::directory::presence::Topology;
use crate::clients::directory::requests::presence_topology_get::PresenceTopologyGetRequester;
use crate::clients::directory::DirectoryClient;
use crate::clients::mix::MixClient;
@@ -15,10 +15,7 @@ use tokio::time::{interval_at, Instant};
pub fn execute(matches: &ArgMatches) {
let custom_cfg = matches.value_of("customCfg");
println!(
"Going to start client with custom config of: {:?}",
custom_cfg
);
println!("Starting client with config: {:?}", custom_cfg);
// Grab the network topology from the remote directory server
let topology = get_topology();
+13
View File
@@ -1,6 +1,7 @@
use curve25519_dalek::montgomery::MontgomeryPoint;
use curve25519_dalek::scalar::Scalar;
// This keypair serves as the user's identity within the Mixnet
pub struct KeyPair {
pub private: Scalar,
pub public: MontgomeryPoint,
@@ -12,6 +13,18 @@ impl KeyPair {
KeyPair { private, public }
}
pub fn from_bytes(private_bytes: Vec<u8>, public_bytes: Vec<u8>) -> KeyPair {
let mut bytes = [0; 32];
bytes.copy_from_slice(&private_bytes[..]);
let private = Scalar::from_canonical_bytes(bytes).unwrap();
let mut bytes = [0; 32];
bytes.copy_from_slice(&public_bytes[..]);
let public = MontgomeryPoint(bytes);
KeyPair { private, public }
}
pub fn private_bytes(&self) -> Vec<u8> {
self.private.to_bytes().to_vec()
}
+1
View File
@@ -1 +1,2 @@
pub mod pathfinder;
pub mod pemstore;
+21
View File
@@ -0,0 +1,21 @@
use std::path::PathBuf;
pub struct Pathfinder {
pub config_dir: PathBuf,
pub private_mix_key: PathBuf,
pub public_mix_key: PathBuf,
}
impl Pathfinder {
pub fn new(id: String) -> Pathfinder {
let os_config_dir = dirs::config_dir().unwrap(); // grabs the OS default config dir
let config_dir = os_config_dir.join("nym").join("clients").join(id);
let private_mix_key = config_dir.join("private.pem");
let public_mix_key = config_dir.join("public.pem");
Pathfinder {
config_dir,
private_mix_key,
public_mix_key,
}
}
}
+37 -13
View File
@@ -1,41 +1,65 @@
use crate::identity::mixnet::KeyPair;
use pem::{encode, Pem};
use crate::persistence::pathfinder::Pathfinder;
use pem::{encode, parse, Pem};
use std::fs::File;
use std::io::prelude::*;
use std::path::PathBuf;
pub struct PemStore {}
pub struct PemStore {
config_dir: PathBuf,
private_mix_key: PathBuf,
public_mix_key: PathBuf,
}
impl PemStore {
pub fn new() -> PemStore {
PemStore {}
pub fn new(pathfinder: Pathfinder) -> PemStore {
PemStore {
config_dir: pathfinder.config_dir,
private_mix_key: pathfinder.private_mix_key,
public_mix_key: pathfinder.public_mix_key,
}
}
pub fn write(&self, key_pair: KeyPair, path: PathBuf) {
std::fs::create_dir_all(path.clone()).unwrap();
pub fn read(&self) -> KeyPair {
let private = self.read_file(self.private_mix_key.clone());
let public = self.read_file(self.public_mix_key.clone());
KeyPair::from_bytes(private, public)
}
pub fn read_file(&self, filepath: PathBuf) -> Vec<u8> {
let mut pem_bytes = File::open(filepath).unwrap();
let mut buf = Vec::new();
pem_bytes.read_to_end(&mut buf).unwrap();
let pem = parse(&buf).unwrap();
pem.contents
}
// This should be refactored and made more generic for when we have other kinds of
// KeyPairs that we want to persist (e.g. validator keypairs, or keys for
// signing vs encryption). However, for the moment, it does the job.
pub fn write(&self, key_pair: KeyPair) {
std::fs::create_dir_all(self.config_dir.clone()).unwrap();
self.write_pem_file(
path.clone(),
String::from("private.pem"),
self.private_mix_key.clone(),
key_pair.private_bytes(),
String::from("SPHINX CURVE25519 PRIVATE KEY"),
);
self.write_pem_file(
path.clone(),
String::from("public.pem"),
self.public_mix_key.clone(),
key_pair.public_bytes(),
String::from("SPHINX CURVE25519 PUBLIC KEY"),
);
}
fn write_pem_file(&self, path: PathBuf, filename: String, data: Vec<u8>, tag: String) {
fn write_pem_file(&self, filepath: PathBuf, data: Vec<u8>, tag: String) {
let pem = Pem {
tag,
contents: data,
};
let key = encode(&pem);
let full_path = path.join(filename);
let mut file = File::create(full_path).unwrap();
let mut file = File::create(filepath).unwrap();
file.write_all(key.as_bytes()).unwrap();
}
}