Files
nym/common/pemstore/src/lib.rs
T
Jędrzej Stuczyński e5afd54ce0 Feature/node status api (#680)
* Basic storage stub

* New models for new node status api

* Route handling

* Mounting new routes

* Missing selective commit

* Moved network monitor related files to separate package

* Starting to see some sqlx action

* Schema updates

* Log statement upon finished migration

* Removed old diesel related imports

* Converted mixnode cache initialisation into a fairing

* Moved cache related functionalities to separate package

Also defined staging there

* Created run method for validator cache + removed unwrap

* Removed old node-status-api types and left bunch of todo placeholders in their place

* Fixed managing validatorcache

* Status reports are starting to get constructed

* Submitting some dummy results to the database

* Removing duplicate code for generating reports

* Removed statuses older than 48h

* Initial attempt at trying to obtain reports for all active nodes

* Removed duplicates from the full report

* Grabbing uptime history

* Updating historical uptimes of active nodes

* Updated sqlx-data.json

* Removed all placeholder foomp owner values

* Changed Layer serde behaviour for easier usage

* Extended validator api config

* Initial (seems working !) integration with network monitor

* Added database path configuration to config

* Using ValidatorCache in NetworkMonitor

* Flag indicating whether validator cache has been initialised

* Introduced a locla-only route for reward script to perform daily chores

* Flag to save config to a file

* Moved spawning of receiving future to run method rather than new

* Removed arguments that dont make sense to be configured via CLI

* Removed dead code from config file

* More dead code removal

* Added validator API to CI

* Corrected manifest-path arguments

* Constructing network monitor by passing config

* Combined validator API CI with the main CI file

* Using query_as for NodeStatus

* Checking if historical uptimes were already calculated on particular day

* Making id field NOT NULL

* More query_as! action

* Updated sqlx-data.json

* Removed unused chrono feature

* Renamed the migration file

* Changed default validator endpoint to point to local validator

* Removing unnecessary clone

* More appropriate naming

* Removed dead code

* Lock file updates

* Updated network monitor address in contract code

* Don't stage node status api if network monitor is disabled

* cargo fmt

* Updated all license notices to SPDX
2021-07-19 14:02:47 +01:00

109 lines
2.9 KiB
Rust

// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use crate::traits::{PemStorableKey, PemStorableKeyPair};
use pem::{self, Pem};
use std::fs::File;
use std::io::{self, Read, Write};
use std::path::{Path, PathBuf};
pub mod traits;
pub struct KeyPairPath {
private_key_path: PathBuf,
public_key_path: PathBuf,
}
impl KeyPairPath {
pub fn new(private_key_path: PathBuf, public_key_path: PathBuf) -> Self {
KeyPairPath {
private_key_path,
public_key_path,
}
}
}
pub fn load_keypair<T>(paths: &KeyPairPath) -> io::Result<T>
where
T: PemStorableKeyPair,
{
let private = load_key::<T::PrivatePemKey>(&paths.private_key_path)?;
let public = load_key::<T::PublicPemKey>(&paths.public_key_path)?;
Ok(T::from_keys(private, public))
}
pub fn store_keypair<T>(keypair: &T, paths: &KeyPairPath) -> io::Result<()>
where
T: PemStorableKeyPair,
{
store_key(keypair.public_key(), &paths.public_key_path)?;
store_key(keypair.private_key(), &paths.private_key_path)
}
pub fn load_key<T>(path: &Path) -> io::Result<T>
where
T: PemStorableKey,
{
let key_pem = read_pem_file(path)?;
if T::pem_type() != key_pem.tag {
return Err(io::Error::new(
io::ErrorKind::Other,
"unexpected key pem tag",
));
}
let key = match T::from_bytes(&key_pem.contents) {
Ok(key) => key,
Err(err) => return Err(io::Error::new(io::ErrorKind::InvalidData, err.to_string())),
};
Ok(key)
}
pub fn store_key<T>(key: &T, path: &Path) -> io::Result<()>
where
T: PemStorableKey,
{
write_pem_file(path, key.to_bytes(), T::pem_type())
}
fn read_pem_file(filepath: &Path) -> io::Result<Pem> {
let mut pem_bytes = File::open(filepath)?;
let mut buf = Vec::new();
pem_bytes.read_to_end(&mut buf)?;
pem::parse(&buf).map_err(|e| io::Error::new(io::ErrorKind::Other, e))
}
fn write_pem_file(filepath: &Path, data: Vec<u8>, tag: &str) -> io::Result<()> {
// ensure the whole directory structure exists
if let Some(parent_dir) = filepath.parent() {
std::fs::create_dir_all(parent_dir)?;
}
let pem = Pem {
tag: tag.to_string(),
contents: data,
};
let key = pem::encode(&pem);
let mut file = File::create(filepath)?;
file.write_all(key.as_bytes())?;
// note: this is only supported on unix (on different systems, like Windows, it will just
// be ignored)
// TODO: a possible consideration would be to use `permission.set_readonly(true)`,
// which would work on both platforms, but that would leave keys on unix with 0444,
// which I feel is too open.
#[cfg(target_family = "unix")]
{
use std::fs;
use std::os::unix::fs::PermissionsExt;
let mut permissions = file.metadata()?.permissions();
permissions.set_mode(0o600);
fs::set_permissions(filepath, permissions)?;
}
Ok(())
}