Compare commits
2 Commits
97f9a57e08
...
1b6241f92b
Author | SHA1 | Date |
---|---|---|
Ryan Heywood | 1b6241f92b | |
Ryan Heywood | c4882f2d21 |
|
@ -533,6 +533,7 @@ dependencies = [
|
||||||
"keyfork-frame",
|
"keyfork-frame",
|
||||||
"keyfork-slip10-test-data",
|
"keyfork-slip10-test-data",
|
||||||
"keyforkd",
|
"keyforkd",
|
||||||
|
"keyforkd-client",
|
||||||
"tempdir",
|
"tempdir",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
"tokio",
|
"tokio",
|
||||||
|
@ -617,6 +618,20 @@ dependencies = [
|
||||||
"tracing-subscriber",
|
"tracing-subscriber",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "keyforkd-client"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"bincode",
|
||||||
|
"keyfork-derive-util",
|
||||||
|
"keyfork-frame",
|
||||||
|
"keyfork-slip10-test-data",
|
||||||
|
"keyforkd",
|
||||||
|
"tempdir",
|
||||||
|
"thiserror",
|
||||||
|
"tokio",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lazy_static"
|
name = "lazy_static"
|
||||||
version = "1.4.0"
|
version = "1.4.0"
|
||||||
|
@ -1072,18 +1087,18 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "thiserror"
|
name = "thiserror"
|
||||||
version = "1.0.48"
|
version = "1.0.49"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9d6d7a740b8a666a7e828dd00da9c0dc290dff53154ea77ac109281de90589b7"
|
checksum = "1177e8c6d7ede7afde3585fd2513e611227efd6481bd78d2e82ba1ce16557ed4"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"thiserror-impl",
|
"thiserror-impl",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "thiserror-impl"
|
name = "thiserror-impl"
|
||||||
version = "1.0.48"
|
version = "1.0.49"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "49922ecae66cc8a249b77e68d1d0623c1b2c514f0060c27cdc68bd62a1219d35"
|
checksum = "10712f02019e9288794769fba95cd6847df9874d49d871d062172f9dd41bc4cc"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
|
|
@ -11,5 +11,6 @@ members = [
|
||||||
"keyfork-mnemonic-util",
|
"keyfork-mnemonic-util",
|
||||||
"keyfork-slip10-test-data",
|
"keyfork-slip10-test-data",
|
||||||
"keyforkd",
|
"keyforkd",
|
||||||
|
"keyforkd-client",
|
||||||
"smex",
|
"smex",
|
||||||
]
|
]
|
||||||
|
|
|
@ -10,6 +10,7 @@ bincode = { version = "1.3.3", default-features = false }
|
||||||
clap = { version = "4.4.2", default-features = false, features = ["std", "usage", "help", "derive"] }
|
clap = { version = "4.4.2", default-features = false, features = ["std", "usage", "help", "derive"] }
|
||||||
keyfork-derive-util = { version = "0.1.0", path = "../keyfork-derive-util" }
|
keyfork-derive-util = { version = "0.1.0", path = "../keyfork-derive-util" }
|
||||||
keyfork-frame = { version = "0.1.0", path = "../keyfork-frame", default-features = false }
|
keyfork-frame = { version = "0.1.0", path = "../keyfork-frame", default-features = false }
|
||||||
|
keyforkd-client = { version = "0.1.0", path = "../keyforkd-client" }
|
||||||
thiserror = "1.0.48"
|
thiserror = "1.0.48"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
use crate::client::Client;
|
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
use keyfork_derive_util::{request::*, DerivationPath};
|
use keyfork_derive_util::{
|
||||||
|
request::{DerivationAlgorithm, DerivationRequest, DerivationResponse},
|
||||||
|
DerivationPath,
|
||||||
|
};
|
||||||
|
use keyforkd_client::{Client, Result};
|
||||||
|
|
||||||
#[derive(Parser, Clone, Debug)]
|
#[derive(Parser, Clone, Debug)]
|
||||||
pub struct Command {
|
pub struct Command {
|
||||||
|
@ -12,7 +15,7 @@ pub struct Command {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Command {
|
impl Command {
|
||||||
pub fn handle(&self) -> super::Result<DerivationResponse> {
|
pub fn handle(&self) -> Result<DerivationResponse> {
|
||||||
let mut client = Client::discover_socket()?;
|
let mut client = Client::discover_socket()?;
|
||||||
let request = DerivationRequest::new(self.algorithm.clone(), &self.path);
|
let request = DerivationRequest::new(self.algorithm.clone(), &self.path);
|
||||||
client.request(&request)
|
client.request(&request)
|
||||||
|
|
|
@ -1,25 +0,0 @@
|
||||||
use crate::Result;
|
|
||||||
use keyfork_derive_util::request::*;
|
|
||||||
use keyfork_frame::*;
|
|
||||||
use std::os::unix::net::UnixStream;
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct Client {
|
|
||||||
socket: UnixStream,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Client {
|
|
||||||
pub fn new(socket: UnixStream) -> Self {
|
|
||||||
Self { socket }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn discover_socket() -> Result<Self> {
|
|
||||||
super::socket::get_socket().map(|socket| Self { socket })
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn request(&mut self, req: &DerivationRequest) -> Result<DerivationResponse> {
|
|
||||||
try_encode_to(&bincode::serialize(&req)?, &mut self.socket)?;
|
|
||||||
let resp = try_decode_from(&mut self.socket)?;
|
|
||||||
bincode::deserialize(&resp).map_err(From::from)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,11 +1,4 @@
|
||||||
use keyfork_frame::{DecodeError, EncodeError};
|
|
||||||
use std::path::PathBuf;
|
|
||||||
|
|
||||||
pub mod cli;
|
pub mod cli;
|
||||||
pub mod client;
|
|
||||||
pub mod socket;
|
|
||||||
|
|
||||||
pub use client::Client;
|
|
||||||
|
|
||||||
#[derive(Debug, thiserror::Error)]
|
#[derive(Debug, thiserror::Error)]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
|
@ -15,23 +8,8 @@ pub enum Error {
|
||||||
#[error("The given path was incorrectly formatted: {0}")]
|
#[error("The given path was incorrectly formatted: {0}")]
|
||||||
ArgsFormat(#[from] keyfork_derive_util::path::Error),
|
ArgsFormat(#[from] keyfork_derive_util::path::Error),
|
||||||
|
|
||||||
#[error("Neither KEYFORK_SOCKET_PATH nor XDG_RUNTIME_DIR were set")]
|
#[error("Unable to perform key derivation request: {0}")]
|
||||||
EnvVarsNotFound,
|
KeyforkdClient(#[from] keyforkd_client::Error),
|
||||||
|
|
||||||
#[error("Socket was unable to connect to {1}: {0}")]
|
|
||||||
Connect(std::io::Error, PathBuf),
|
|
||||||
|
|
||||||
#[error("Could not write to or from the socket: {0}")]
|
|
||||||
Io(#[from] std::io::Error),
|
|
||||||
|
|
||||||
#[error("Could not perform bincode transformation: {0}")]
|
|
||||||
Bincode(#[from] Box<bincode::ErrorKind>),
|
|
||||||
|
|
||||||
#[error("Could not perform frame transformation: {0}")]
|
|
||||||
FrameEnc(#[from] EncodeError),
|
|
||||||
|
|
||||||
#[error("Could not perform frame transformation: {0}")]
|
|
||||||
FrameDec(#[from] DecodeError),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type Result<T, E = Error> = std::result::Result<T, E>;
|
pub type Result<T, E = Error> = std::result::Result<T, E>;
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
|
|
||||||
#[cfg(test)]
|
#[allow(clippy::wildcard_imports)]
|
||||||
mod tests;
|
|
||||||
|
|
||||||
use keyfork_derive_key::*;
|
use keyfork_derive_key::*;
|
||||||
|
|
||||||
fn main() -> Result<()> {
|
fn main() -> Result<()> {
|
||||||
|
|
|
@ -1,24 +0,0 @@
|
||||||
use super::Error;
|
|
||||||
use std::{collections::HashMap, os::unix::net::UnixStream, path::PathBuf};
|
|
||||||
|
|
||||||
pub fn get_socket() -> Result<UnixStream, Error> {
|
|
||||||
let socket_vars = std::env::vars()
|
|
||||||
.filter(|(key, _)| ["XDG_RUNTIME_DIR", "KEYFORKD_SOCKET_PATH"].contains(&key.as_str()))
|
|
||||||
.collect::<HashMap<String, String>>();
|
|
||||||
let mut socket_path: PathBuf;
|
|
||||||
#[allow(clippy::single_match_else)]
|
|
||||||
match socket_vars.get("KEYFORKD_SOCKET_PATH") {
|
|
||||||
Some(occupied) => {
|
|
||||||
socket_path = PathBuf::from(occupied);
|
|
||||||
}
|
|
||||||
None => {
|
|
||||||
socket_path = PathBuf::from(
|
|
||||||
socket_vars
|
|
||||||
.get("XDG_RUNTIME_DIR")
|
|
||||||
.ok_or(Error::EnvVarsNotFound)?,
|
|
||||||
);
|
|
||||||
socket_path.extend(["keyforkd", "keyforkd.sock"]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
UnixStream::connect(&socket_path).map_err(|e| Error::Connect(e, socket_path))
|
|
||||||
}
|
|
|
@ -35,7 +35,7 @@ pub trait PublicKey: Sized {
|
||||||
let hash = Sha256::new().chain_update(self.to_bytes()).finalize();
|
let hash = Sha256::new().chain_update(self.to_bytes()).finalize();
|
||||||
let hash = Ripemd160::new().chain_update(hash).finalize();
|
let hash = Ripemd160::new().chain_update(hash).finalize();
|
||||||
// Note: Safety assured by type returned from Ripemd160
|
// Note: Safety assured by type returned from Ripemd160
|
||||||
hash[..4].try_into().unwrap()
|
hash[..4].try_into().expect("Ripemd160 returned too little data")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,8 +73,9 @@ impl PublicKey for k256::PublicKey {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
fn to_bytes(&self) -> PublicKeyBytes {
|
fn to_bytes(&self) -> PublicKeyBytes {
|
||||||
// Note: Safety assured by type returned from EncodedPoint
|
let mut result = [0u8; 33];
|
||||||
self.to_encoded_point(true).as_bytes().try_into().unwrap()
|
result[..].copy_from_slice(self.to_encoded_point(true).as_bytes());
|
||||||
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
fn derive_child(&self, other: PrivateKeyBytes) -> Result<Self, Self::Err> {
|
fn derive_child(&self, other: PrivateKeyBytes) -> Result<Self, Self::Err> {
|
||||||
|
|
|
@ -37,7 +37,7 @@ fn ensure_offline() {
|
||||||
.expect("Unable to decode UTF-8 filepath")
|
.expect("Unable to decode UTF-8 filepath")
|
||||||
.split('/')
|
.split('/')
|
||||||
.last()
|
.last()
|
||||||
.unwrap()
|
.expect("No data in file path")
|
||||||
== "lo"
|
== "lo"
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
#[allow(clippy::wildcard_imports)]
|
||||||
use keyfork_mnemonic_from_seed::*;
|
use keyfork_mnemonic_from_seed::*;
|
||||||
|
|
||||||
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
|
|
@ -25,6 +25,7 @@ const ED25519_512: &str = "fffcf9f6f3f0edeae7e4e1dedbd8d5d2cfccc9c6c3c0bdbab7b4b
|
||||||
9f9c999693908d8a8784817e7b7875726f6c696663605d5a5754514e4b484542";
|
9f9c999693908d8a8784817e7b7875726f6c696663605d5a5754514e4b484542";
|
||||||
|
|
||||||
// Note: This should never error.
|
// Note: This should never error.
|
||||||
|
#[allow(clippy::too_many_lines)]
|
||||||
pub fn test_data() -> Result<HashMap<String, Vec<TestData>>, Box<dyn std::error::Error>> {
|
pub fn test_data() -> Result<HashMap<String, Vec<TestData>>, Box<dyn std::error::Error>> {
|
||||||
// Format:
|
// Format:
|
||||||
let mut map = HashMap::new();
|
let mut map = HashMap::new();
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#![allow(clippy::module_name_repetitions)]
|
||||||
|
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
|
|
||||||
mod cli;
|
mod cli;
|
||||||
|
@ -5,5 +7,5 @@ mod cli;
|
||||||
fn main() {
|
fn main() {
|
||||||
let opts = cli::Keyfork::parse();
|
let opts = cli::Keyfork::parse();
|
||||||
|
|
||||||
opts.command.handle(&opts).unwrap();
|
opts.command.handle(&opts).expect("Unable to handle command");
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
[package]
|
||||||
|
name = "keyforkd-client"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
bincode = "1.3.3"
|
||||||
|
keyfork-derive-util = { version = "0.1.0", path = "../keyfork-derive-util" }
|
||||||
|
keyfork-frame = { version = "0.1.0", path = "../keyfork-frame" }
|
||||||
|
thiserror = "1.0.49"
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
keyfork-slip10-test-data = { path = "../keyfork-slip10-test-data" }
|
||||||
|
keyforkd = { path = "../keyforkd" }
|
||||||
|
tempdir = "0.3.7"
|
||||||
|
tokio = { version = "1.32.0", features = ["rt", "sync", "rt-multi-thread"] }
|
|
@ -0,0 +1,73 @@
|
||||||
|
use std::{collections::HashMap, os::unix::net::UnixStream, path::PathBuf};
|
||||||
|
|
||||||
|
use keyfork_derive_util::request::{DerivationRequest, DerivationResponse};
|
||||||
|
use keyfork_frame::{try_decode_from, try_encode_to, DecodeError, EncodeError};
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests;
|
||||||
|
|
||||||
|
#[derive(Debug, thiserror::Error)]
|
||||||
|
pub enum Error {
|
||||||
|
#[error("Neither KEYFORK_SOCKET_PATH nor XDG_RUNTIME_DIR were set")]
|
||||||
|
EnvVarsNotFound,
|
||||||
|
|
||||||
|
#[error("Socket was unable to connect to {1}: {0}")]
|
||||||
|
Connect(std::io::Error, PathBuf),
|
||||||
|
|
||||||
|
#[error("Could not write to or from the socket: {0}")]
|
||||||
|
Io(#[from] std::io::Error),
|
||||||
|
|
||||||
|
#[error("Could not perform bincode transformation: {0}")]
|
||||||
|
Bincode(#[from] Box<bincode::ErrorKind>),
|
||||||
|
|
||||||
|
#[error("Could not perform frame transformation: {0}")]
|
||||||
|
FrameEnc(#[from] EncodeError),
|
||||||
|
|
||||||
|
#[error("Could not perform frame transformation: {0}")]
|
||||||
|
FrameDec(#[from] DecodeError),
|
||||||
|
}
|
||||||
|
|
||||||
|
pub type Result<T, E = Error> = std::result::Result<T, E>;
|
||||||
|
|
||||||
|
pub fn get_socket() -> Result<UnixStream, Error> {
|
||||||
|
let socket_vars = std::env::vars()
|
||||||
|
.filter(|(key, _)| ["XDG_RUNTIME_DIR", "KEYFORKD_SOCKET_PATH"].contains(&key.as_str()))
|
||||||
|
.collect::<HashMap<String, String>>();
|
||||||
|
let mut socket_path: PathBuf;
|
||||||
|
#[allow(clippy::single_match_else)]
|
||||||
|
match socket_vars.get("KEYFORKD_SOCKET_PATH") {
|
||||||
|
Some(occupied) => {
|
||||||
|
socket_path = PathBuf::from(occupied);
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
socket_path = PathBuf::from(
|
||||||
|
socket_vars
|
||||||
|
.get("XDG_RUNTIME_DIR")
|
||||||
|
.ok_or(Error::EnvVarsNotFound)?,
|
||||||
|
);
|
||||||
|
socket_path.extend(["keyforkd", "keyforkd.sock"]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
UnixStream::connect(&socket_path).map_err(|e| Error::Connect(e, socket_path))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct Client {
|
||||||
|
socket: UnixStream,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Client {
|
||||||
|
pub fn new(socket: UnixStream) -> Self {
|
||||||
|
Self { socket }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn discover_socket() -> Result<Self> {
|
||||||
|
get_socket().map(|socket| Self { socket })
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn request(&mut self, req: &DerivationRequest) -> Result<DerivationResponse> {
|
||||||
|
try_encode_to(&bincode::serialize(&req)?, &mut self.socket)?;
|
||||||
|
let resp = try_decode_from(&mut self.socket)?;
|
||||||
|
bincode::deserialize(&resp).map_err(From::from)
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
use crate::client::Client;
|
use crate::Client;
|
||||||
use keyfork_derive_util::{request::*, DerivationPath};
|
use keyfork_derive_util::{request::*, DerivationPath};
|
||||||
use keyfork_slip10_test_data::test_data;
|
use keyfork_slip10_test_data::test_data;
|
||||||
use std::sync::mpsc::channel;
|
use std::sync::mpsc::channel;
|
||||||
|
@ -13,6 +13,7 @@ fn secp256k1() {
|
||||||
.remove(&"secp256k1".to_string())
|
.remove(&"secp256k1".to_string())
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
|
// todo: move to tokio::sync channels to avoid using multi thread tokio
|
||||||
let rt = Builder::new_multi_thread().enable_io().build().unwrap();
|
let rt = Builder::new_multi_thread().enable_io().build().unwrap();
|
||||||
let tempdir = TempDir::new("keyfork-seed").unwrap();
|
let tempdir = TempDir::new("keyfork-seed").unwrap();
|
||||||
for (i, per_seed) in tests.into_iter().enumerate() {
|
for (i, per_seed) in tests.into_iter().enumerate() {
|
|
@ -1,7 +1,7 @@
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
#[derive(Debug, Clone, Error)]
|
#[derive(Debug, Clone, Error)]
|
||||||
pub enum KeyforkdError {
|
pub enum Keyforkd {
|
||||||
#[error("Neither KEYFORKD_SOCKET_PATH nor XDG_RUNTIME_DIR were set, nowhere to mount socket")]
|
#[error("Neither KEYFORKD_SOCKET_PATH nor XDG_RUNTIME_DIR were set, nowhere to mount socket")]
|
||||||
NoSocketPath,
|
NoSocketPath,
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,7 @@ pub mod error;
|
||||||
pub mod middleware;
|
pub mod middleware;
|
||||||
pub mod server;
|
pub mod server;
|
||||||
pub mod service;
|
pub mod service;
|
||||||
pub use error::KeyforkdError;
|
pub use error::Keyforkd as KeyforkdError;
|
||||||
pub use server::UnixServer;
|
pub use server::UnixServer;
|
||||||
pub use service::Keyforkd;
|
pub use service::Keyforkd;
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,12 @@ impl<'a, Request> BincodeLayer<'a, Request> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a, Request> Default for BincodeLayer<'a, Request> {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self::new()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<'a, S: 'a, Request> Layer<S> for BincodeLayer<'a, Request> {
|
impl<'a, S: 'a, Request> Layer<S> for BincodeLayer<'a, Request> {
|
||||||
type Service = BincodeService<S, Request>;
|
type Service = BincodeService<S, Request>;
|
||||||
|
|
||||||
|
@ -137,7 +143,7 @@ mod tests {
|
||||||
async fn can_serde_responses() {
|
async fn can_serde_responses() {
|
||||||
let content = serialize(&Test::new()).unwrap();
|
let content = serialize(&Test::new()).unwrap();
|
||||||
let mut service = ServiceBuilder::new()
|
let mut service = ServiceBuilder::new()
|
||||||
.layer(BincodeLayer::<Test>::new())
|
.layer(BincodeLayer::<Test>::default())
|
||||||
.service(App);
|
.service(App);
|
||||||
let result = service
|
let result = service
|
||||||
.ready()
|
.ready()
|
||||||
|
|
Loading…
Reference in New Issue