Compare commits
No commits in common. "278e5c84fdaf719632fb7291e1321cd55a9f8d7c" and "12095495326ab637999674fb684a5c73e52eb974" have entirely different histories.
278e5c84fd
...
1209549532
|
@ -1023,9 +1023,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ed25519-dalek"
|
name = "ed25519-dalek"
|
||||||
version = "2.1.1"
|
version = "2.1.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4a3daa8e81a3963a60642bcc1f90a670680bd4a77535faa384e9d1c79d620871"
|
checksum = "1f628eaec48bfd21b865dc2950cfa014450c01d2fa2b69a86c2fd5844ec523c0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"curve25519-dalek",
|
"curve25519-dalek",
|
||||||
"ed25519",
|
"ed25519",
|
||||||
|
@ -1663,8 +1663,6 @@ dependencies = [
|
||||||
"ecdsa",
|
"ecdsa",
|
||||||
"elliptic-curve",
|
"elliptic-curve",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"sha2",
|
|
||||||
"signature",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1886,14 +1884,14 @@ name = "keyforkd-client"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bincode",
|
"bincode",
|
||||||
"ed25519-dalek",
|
|
||||||
"k256",
|
|
||||||
"keyfork-derive-util",
|
"keyfork-derive-util",
|
||||||
"keyfork-frame",
|
"keyfork-frame",
|
||||||
"keyfork-slip10-test-data",
|
"keyfork-slip10-test-data",
|
||||||
"keyforkd",
|
"keyforkd",
|
||||||
"keyforkd-models",
|
"keyforkd-models",
|
||||||
|
"tempfile",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
|
"tokio",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
|
@ -8,8 +8,8 @@ license = "MIT"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["ed25519", "secp256k1"]
|
default = ["ed25519", "secp256k1"]
|
||||||
ed25519 = ["keyfork-derive-util/ed25519", "ed25519-dalek"]
|
ed25519 = ["keyfork-derive-util/ed25519"]
|
||||||
secp256k1 = ["keyfork-derive-util/secp256k1", "k256"]
|
secp256k1 = ["keyfork-derive-util/secp256k1"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
keyfork-derive-util = { version = "0.1.0", path = "../../derive/keyfork-derive-util", default-features = false }
|
keyfork-derive-util = { version = "0.1.0", path = "../../derive/keyfork-derive-util", default-features = false }
|
||||||
|
@ -17,9 +17,9 @@ keyfork-frame = { version = "0.1.0", path = "../../util/keyfork-frame" }
|
||||||
keyforkd-models = { version = "0.1.0", path = "../keyforkd-models" }
|
keyforkd-models = { version = "0.1.0", path = "../keyforkd-models" }
|
||||||
bincode = "1.3.3"
|
bincode = "1.3.3"
|
||||||
thiserror = "1.0.49"
|
thiserror = "1.0.49"
|
||||||
k256 = { version = "0.13.3", optional = true }
|
|
||||||
ed25519-dalek = { version = "2.1.1", optional = true }
|
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
keyfork-slip10-test-data = { path = "../../util/keyfork-slip10-test-data" }
|
keyfork-slip10-test-data = { path = "../../util/keyfork-slip10-test-data" }
|
||||||
keyforkd = { path = "../keyforkd" }
|
keyforkd = { path = "../keyforkd" }
|
||||||
|
tempfile = "3.9.0"
|
||||||
|
tokio = { version = "1.32.0", features = ["rt", "sync", "rt-multi-thread"] }
|
||||||
|
|
|
@ -1,48 +1,6 @@
|
||||||
//! # The Keyforkd Client
|
//! A client for Keyforkd.
|
||||||
//!
|
|
||||||
//! Keyfork allows securing the master key and highest-level derivation keys by having derivation
|
|
||||||
//! requests performed against a server, "Keyforkd" or the "Keyfork Server". The server is operated
|
|
||||||
//! on a UNIX socket with messages sent using the Keyfork Frame format.
|
|
||||||
//!
|
|
||||||
//! Programs using the Keyfork Client should ensure they are built against a compatible version of
|
|
||||||
//! the Keyfork Server. For versions prior to `1.0.0`, all versions within a "minor" version (i.e.,
|
|
||||||
//! `0.5.x`) will be compatible, but `0.5.x` will not be compatible with `0.6.x`. For versions
|
|
||||||
//! after `1.0.0`, all versions within a "major" version (i.e., `1.0.0`) will be compatible, but
|
|
||||||
//! `1.x.y` will not be compatible with `2.0.0`.
|
|
||||||
//!
|
|
||||||
//! Presently, the Keyfork server only supports the following requests:
|
|
||||||
//!
|
|
||||||
//! * Derive Key
|
|
||||||
//!
|
|
||||||
//! ## Extended Private Keys
|
|
||||||
//!
|
|
||||||
//! Keyfork doesn't need to be continuously called once a key has been derived. Once an Extended
|
|
||||||
//! Private Key (often shortened to "XPrv") has been created, further derivations can be performed.
|
|
||||||
//! The tests for this library ensure that all levels of Keyfork derivation beyond the required two
|
|
||||||
//! will be derived similarly between the server and the client.
|
|
||||||
//!
|
|
||||||
//! # Examples
|
|
||||||
//! ```rust
|
|
||||||
//! use std::str::FromStr;
|
|
||||||
//!
|
|
||||||
//! use keyforkd_client::Client;
|
|
||||||
//! use keyfork_derive_util::DerivationPath;
|
|
||||||
//! # use keyfork_derive_util::private_key::TestPrivateKey as PrivateKey;
|
|
||||||
//! // use k256::SecretKey as PrivateKey;
|
|
||||||
//! // use ed25519_dalek::SigningKey as PrivateKey;
|
|
||||||
//!
|
|
||||||
//! # let seed = b"funky accordion noises";
|
|
||||||
//! # keyforkd::test_util::run_test(seed, |socket_path| {
|
|
||||||
//! # std::env::set_var("KEYFORKD_SOCKET_PATH", socket_path);
|
|
||||||
//! let derivation_path = DerivationPath::from_str("m/44'/0'").unwrap();
|
|
||||||
//! let mut client = Client::discover_socket().unwrap();
|
|
||||||
//! let xprv = client.request_xprv::<PrivateKey>(&derivation_path).unwrap();
|
|
||||||
//! # keyforkd::test_util::Infallible::Ok(())
|
|
||||||
//! # }).unwrap();
|
|
||||||
//! ```
|
|
||||||
|
|
||||||
pub use std::os::unix::net::UnixStream;
|
use std::{collections::HashMap, os::unix::net::UnixStream, path::PathBuf};
|
||||||
use std::{collections::HashMap, path::PathBuf};
|
|
||||||
|
|
||||||
use keyfork_derive_util::{
|
use keyfork_derive_util::{
|
||||||
request::{AsAlgorithm, DerivationRequest},
|
request::{AsAlgorithm, DerivationRequest},
|
||||||
|
@ -132,22 +90,7 @@ pub struct Client {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Client {
|
impl Client {
|
||||||
/// Create a new client from a given already-connected [`UnixStream`]. This function is
|
/// Create a new client from a given already-connected [`UnixStream`].
|
||||||
/// provided in case a specific UnixStream has to be used; otherwise,
|
|
||||||
/// [`Client::discover_socket`] should be preferred.
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
/// ```rust
|
|
||||||
/// use keyforkd_client::{Client, get_socket};
|
|
||||||
///
|
|
||||||
/// # let seed = b"funky accordion noises";
|
|
||||||
/// # keyforkd::test_util::run_test(seed, |socket_path| {
|
|
||||||
/// # std::env::set_var("KEYFORKD_SOCKET_PATH", socket_path);
|
|
||||||
/// let mut socket = get_socket().unwrap();
|
|
||||||
/// let mut client = Client::new(socket);
|
|
||||||
/// # keyforkd::test_util::Infallible::Ok(())
|
|
||||||
/// # }).unwrap();
|
|
||||||
/// ```
|
|
||||||
pub fn new(socket: UnixStream) -> Self {
|
pub fn new(socket: UnixStream) -> Self {
|
||||||
Self { socket }
|
Self { socket }
|
||||||
}
|
}
|
||||||
|
@ -157,18 +100,6 @@ impl Client {
|
||||||
/// # Errors
|
/// # Errors
|
||||||
/// An error may be returned if the required environment variables were not set or if the
|
/// An error may be returned if the required environment variables were not set or if the
|
||||||
/// socket could not be connected to.
|
/// socket could not be connected to.
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
/// ```rust
|
|
||||||
/// use keyforkd_client::Client;
|
|
||||||
///
|
|
||||||
/// # let seed = b"funky accordion noises";
|
|
||||||
/// # keyforkd::test_util::run_test(seed, |socket_path| {
|
|
||||||
/// # std::env::set_var("KEYFORKD_SOCKET_PATH", socket_path);
|
|
||||||
/// let mut client = Client::discover_socket().unwrap();
|
|
||||||
/// # keyforkd::test_util::Infallible::Ok(())
|
|
||||||
/// # }).unwrap();
|
|
||||||
/// ```
|
|
||||||
pub fn discover_socket() -> Result<Self> {
|
pub fn discover_socket() -> Result<Self> {
|
||||||
get_socket().map(|socket| Self { socket })
|
get_socket().map(|socket| Self { socket })
|
||||||
}
|
}
|
||||||
|
@ -181,26 +112,6 @@ impl Client {
|
||||||
/// * Bincode could not serialize the request or deserialize the response.
|
/// * Bincode could not serialize the request or deserialize the response.
|
||||||
/// * An error occurred in Keyforkd.
|
/// * An error occurred in Keyforkd.
|
||||||
/// * Keyforkd returned invalid data.
|
/// * Keyforkd returned invalid data.
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
/// ```rust
|
|
||||||
/// use std::str::FromStr;
|
|
||||||
///
|
|
||||||
/// use keyforkd_client::Client;
|
|
||||||
/// use keyfork_derive_util::DerivationPath;
|
|
||||||
/// # use keyfork_derive_util::private_key::TestPrivateKey as PrivateKey;
|
|
||||||
/// // use k256::SecretKey as PrivateKey;
|
|
||||||
/// // use ed25519_dalek::SigningKey as PrivateKey;
|
|
||||||
///
|
|
||||||
/// # let seed = b"funky accordion noises";
|
|
||||||
/// # keyforkd::test_util::run_test(seed, |socket_path| {
|
|
||||||
/// # std::env::set_var("KEYFORKD_SOCKET_PATH", socket_path);
|
|
||||||
/// let derivation_path = DerivationPath::from_str("m/44'/0'").unwrap();
|
|
||||||
/// let mut client = Client::discover_socket().unwrap();
|
|
||||||
/// let xprv = client.request_xprv::<PrivateKey>(&derivation_path).unwrap();
|
|
||||||
/// # keyforkd::test_util::Infallible::Ok(())
|
|
||||||
/// # }).unwrap();
|
|
||||||
/// ```
|
|
||||||
pub fn request_xprv<K>(&mut self, path: &DerivationPath) -> Result<ExtendedPrivateKey<K>>
|
pub fn request_xprv<K>(&mut self, path: &DerivationPath) -> Result<ExtendedPrivateKey<K>>
|
||||||
where
|
where
|
||||||
K: PrivateKey + Clone + AsAlgorithm,
|
K: PrivateKey + Clone + AsAlgorithm,
|
||||||
|
@ -232,7 +143,6 @@ impl Client {
|
||||||
/// * Reading or writing from or to the socket encountered an error.
|
/// * Reading or writing from or to the socket encountered an error.
|
||||||
/// * Bincode could not serialize the request or deserialize the response.
|
/// * Bincode could not serialize the request or deserialize the response.
|
||||||
/// * An error occurred in Keyforkd.
|
/// * An error occurred in Keyforkd.
|
||||||
#[doc(hidden)]
|
|
||||||
pub fn request(&mut self, req: &Request) -> Result<Response> {
|
pub fn request(&mut self, req: &Request) -> Result<Response> {
|
||||||
try_encode_to(&bincode::serialize(&req)?, &mut self.socket)?;
|
try_encode_to(&bincode::serialize(&req)?, &mut self.socket)?;
|
||||||
let resp = try_decode_from(&mut self.socket)?;
|
let resp = try_decode_from(&mut self.socket)?;
|
||||||
|
|
|
@ -1,14 +1,11 @@
|
||||||
use crate::Client;
|
use crate::Client;
|
||||||
|
use keyforkd::test_util::{run_test, Infallible};
|
||||||
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 keyforkd::test_util::{run_test, Infallible};
|
|
||||||
use std::{os::unix::net::UnixStream, str::FromStr};
|
use std::{os::unix::net::UnixStream, str::FromStr};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[cfg(feature = "secp256k1")]
|
|
||||||
fn secp256k1_test_suite() {
|
fn secp256k1_test_suite() {
|
||||||
use k256::SecretKey;
|
|
||||||
|
|
||||||
let tests = test_data()
|
let tests = test_data()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.remove(&"secp256k1".to_string())
|
.remove(&"secp256k1".to_string())
|
||||||
|
@ -16,38 +13,14 @@ fn secp256k1_test_suite() {
|
||||||
|
|
||||||
for seed_test in tests {
|
for seed_test in tests {
|
||||||
let seed = seed_test.seed;
|
let seed = seed_test.seed;
|
||||||
run_test(&seed, move |socket_path| -> Result<(), Box<dyn std::error::Error + Send>> {
|
run_test(&seed, move |socket_path| {
|
||||||
for test in seed_test.tests {
|
for test in seed_test.tests {
|
||||||
let socket = UnixStream::connect(&socket_path).unwrap();
|
let socket = UnixStream::connect(&socket_path).unwrap();
|
||||||
let mut client = Client::new(socket);
|
let mut client = Client::new(socket);
|
||||||
let chain = DerivationPath::from_str(test.chain).unwrap();
|
let chain = DerivationPath::from_str(test.chain).unwrap();
|
||||||
let chain_len = chain.len();
|
if chain.len() < 2 {
|
||||||
if chain_len < 2 {
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// Consistency check: ensure the server and the client can each derive the same
|
|
||||||
// key using an XPrv, for all but the last XPrv, which is verified after this
|
|
||||||
for i in 2..chain_len {
|
|
||||||
// FIXME: Keyfork will only allow one request per session
|
|
||||||
let socket = UnixStream::connect(&socket_path).unwrap();
|
|
||||||
let mut client = Client::new(socket);
|
|
||||||
let path = DerivationPath::from_str(test.chain).unwrap();
|
|
||||||
let left_path = path.inner()[..i]
|
|
||||||
.iter()
|
|
||||||
.fold(DerivationPath::default(), |p, i| p.chain_push(i.clone()));
|
|
||||||
let right_path = path.inner()[i..]
|
|
||||||
.iter()
|
|
||||||
.fold(DerivationPath::default(), |p, i| p.chain_push(i.clone()));
|
|
||||||
let xprv = dbg!(client.request_xprv::<SecretKey>(&left_path)).unwrap();
|
|
||||||
let derived_xprv = xprv.derive_path(&right_path).unwrap();
|
|
||||||
let socket = UnixStream::connect(&socket_path).unwrap();
|
|
||||||
let mut client = Client::new(socket);
|
|
||||||
let keyforkd_xprv = client.request_xprv::<SecretKey>(&path).unwrap();
|
|
||||||
assert_eq!(
|
|
||||||
derived_xprv, keyforkd_xprv,
|
|
||||||
"{left_path} + {right_path} != {path}"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
let req = DerivationRequest::new(
|
let req = DerivationRequest::new(
|
||||||
DerivationAlgorithm::Secp256k1,
|
DerivationAlgorithm::Secp256k1,
|
||||||
&DerivationPath::from_str(test.chain).unwrap(),
|
&DerivationPath::from_str(test.chain).unwrap(),
|
||||||
|
@ -56,18 +29,17 @@ fn secp256k1_test_suite() {
|
||||||
DerivationResponse::try_from(client.request(&req.into()).unwrap()).unwrap();
|
DerivationResponse::try_from(client.request(&req.into()).unwrap()).unwrap();
|
||||||
assert_eq!(&response.data, test.private_key.as_slice());
|
assert_eq!(&response.data, test.private_key.as_slice());
|
||||||
}
|
}
|
||||||
Ok(())
|
Infallible::Ok(())
|
||||||
})
|
}).unwrap();
|
||||||
.unwrap();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[cfg(feature = "ed25519")]
|
|
||||||
fn ed25519_test_suite() {
|
fn ed25519_test_suite() {
|
||||||
use ed25519_dalek::SigningKey;
|
let tests = test_data()
|
||||||
|
.unwrap()
|
||||||
let tests = test_data().unwrap().remove(&"ed25519".to_string()).unwrap();
|
.remove(&"ed25519".to_string())
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
for seed_test in tests {
|
for seed_test in tests {
|
||||||
let seed = seed_test.seed;
|
let seed = seed_test.seed;
|
||||||
|
@ -76,28 +48,9 @@ fn ed25519_test_suite() {
|
||||||
let socket = UnixStream::connect(&socket_path).unwrap();
|
let socket = UnixStream::connect(&socket_path).unwrap();
|
||||||
let mut client = Client::new(socket);
|
let mut client = Client::new(socket);
|
||||||
let chain = DerivationPath::from_str(test.chain).unwrap();
|
let chain = DerivationPath::from_str(test.chain).unwrap();
|
||||||
let chain_len = chain.len();
|
if chain.len() < 2 {
|
||||||
if chain_len < 2 {
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
for i in 2..chain_len {
|
|
||||||
// Consistency check: ensure the server and the client can each derive the same
|
|
||||||
// key using an XPrv, for all but the last XPrv, which is verified after this
|
|
||||||
let path = DerivationPath::from_str(test.chain).unwrap();
|
|
||||||
let left_path = path.inner()[..i]
|
|
||||||
.iter()
|
|
||||||
.fold(DerivationPath::default(), |p, i| p.chain_push(i.clone()));
|
|
||||||
let right_path = path.inner()[i..]
|
|
||||||
.iter()
|
|
||||||
.fold(DerivationPath::default(), |p, i| p.chain_push(i.clone()));
|
|
||||||
let xprv = dbg!(client.request_xprv::<SigningKey>(&left_path)).unwrap();
|
|
||||||
let derived_xprv = xprv.derive_path(&right_path).unwrap();
|
|
||||||
let keyforkd_xprv = client.request_xprv::<SigningKey>(&path).unwrap();
|
|
||||||
assert_eq!(
|
|
||||||
derived_xprv, keyforkd_xprv,
|
|
||||||
"{left_path} + {right_path} != {path}"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
let req = DerivationRequest::new(
|
let req = DerivationRequest::new(
|
||||||
DerivationAlgorithm::Ed25519,
|
DerivationAlgorithm::Ed25519,
|
||||||
&DerivationPath::from_str(test.chain).unwrap(),
|
&DerivationPath::from_str(test.chain).unwrap(),
|
||||||
|
@ -107,7 +60,6 @@ fn ed25519_test_suite() {
|
||||||
assert_eq!(&response.data, test.private_key.as_slice());
|
assert_eq!(&response.data, test.private_key.as_slice());
|
||||||
}
|
}
|
||||||
Infallible::Ok(())
|
Infallible::Ok(())
|
||||||
})
|
}).unwrap();
|
||||||
.unwrap();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,6 @@
|
||||||
//! A UNIX socket server to run a Tower Service.
|
//! A UNIX socket server to run a Tower Service.
|
||||||
|
|
||||||
use keyfork_frame::{
|
use keyfork_frame::asyncext::{try_decode_from, try_encode_to};
|
||||||
asyncext::{try_decode_from, try_encode_to},
|
|
||||||
DecodeError, EncodeError,
|
|
||||||
};
|
|
||||||
use std::{
|
use std::{
|
||||||
io::Error,
|
io::Error,
|
||||||
path::{Path, PathBuf},
|
path::{Path, PathBuf},
|
||||||
|
@ -20,34 +17,6 @@ pub struct UnixServer {
|
||||||
listener: UnixListener,
|
listener: UnixListener,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This feels like a hack, but this is a convenient way to use the same method to quickly verify
|
|
||||||
/// something across two different error types.
|
|
||||||
trait IsDisconnect {
|
|
||||||
fn is_disconnect(&self) -> bool;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl IsDisconnect for DecodeError {
|
|
||||||
fn is_disconnect(&self) -> bool {
|
|
||||||
if let Self::Io(e) = self {
|
|
||||||
if let std::io::ErrorKind::UnexpectedEof = e.kind() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl IsDisconnect for EncodeError {
|
|
||||||
fn is_disconnect(&self) -> bool {
|
|
||||||
if let Self::Io(e) = self {
|
|
||||||
if let std::io::ErrorKind::UnexpectedEof = e.kind() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl UnixServer {
|
impl UnixServer {
|
||||||
/// Bind a socket to the given `address` and create a [`UnixServer`]. This function also creates a ctrl_c handler to automatically clean up the socket file.
|
/// Bind a socket to the given `address` and create a [`UnixServer`]. This function also creates a ctrl_c handler to automatically clean up the socket file.
|
||||||
///
|
///
|
||||||
|
@ -99,19 +68,9 @@ impl UnixServer {
|
||||||
#[cfg(feature = "tracing")]
|
#[cfg(feature = "tracing")]
|
||||||
debug!("new socket connected");
|
debug!("new socket connected");
|
||||||
tokio::spawn(async move {
|
tokio::spawn(async move {
|
||||||
let mut has_processed_request = false;
|
|
||||||
// Process requests until an error occurs or a client disconnects
|
|
||||||
loop {
|
|
||||||
let bytes = match try_decode_from(&mut socket).await {
|
let bytes = match try_decode_from(&mut socket).await {
|
||||||
Ok(bytes) => bytes,
|
Ok(bytes) => bytes,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
if e.is_disconnect() {
|
|
||||||
#[cfg(feature = "tracing")]
|
|
||||||
if !has_processed_request {
|
|
||||||
debug!("client disconnected before sending any response");
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#[cfg(feature = "tracing")]
|
#[cfg(feature = "tracing")]
|
||||||
debug!(%e, "Error reading DerivationPath from socket");
|
debug!(%e, "Error reading DerivationPath from socket");
|
||||||
let content = e.to_string().bytes().collect::<Vec<_>>();
|
let content = e.to_string().bytes().collect::<Vec<_>>();
|
||||||
|
@ -148,37 +107,17 @@ impl UnixServer {
|
||||||
let result = try_encode_to(&content[..], &mut socket).await;
|
let result = try_encode_to(&content[..], &mut socket).await;
|
||||||
#[cfg(feature = "tracing")]
|
#[cfg(feature = "tracing")]
|
||||||
if let Err(error) = result {
|
if let Err(error) = result {
|
||||||
if error.is_disconnect() {
|
|
||||||
#[cfg(feature = "tracing")]
|
|
||||||
if has_processed_request {
|
|
||||||
debug!("client disconnected while sending error frame");
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
debug!(%error, "Error sending error to client");
|
debug!(%error, "Error sending error to client");
|
||||||
}
|
}
|
||||||
has_processed_request = true;
|
return;
|
||||||
// The error has been successfully sent, the client may perform
|
|
||||||
// another request.
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.into();
|
.into();
|
||||||
|
|
||||||
if let Err(e) = try_encode_to(&response[..], &mut socket).await {
|
if let Err(e) = try_encode_to(&response[..], &mut socket).await {
|
||||||
if e.is_disconnect() {
|
|
||||||
#[cfg(feature = "tracing")]
|
|
||||||
if has_processed_request {
|
|
||||||
debug!("client disconnected while sending success frame");
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#[cfg(feature = "tracing")]
|
#[cfg(feature = "tracing")]
|
||||||
debug!(%e, "Error sending response to client");
|
debug!(%e, "Error sending response to client");
|
||||||
}
|
}
|
||||||
|
|
||||||
has_processed_request = true;
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -96,7 +96,7 @@ mod as_private_key {
|
||||||
/// Extended private keys derived using BIP-0032.
|
/// Extended private keys derived using BIP-0032.
|
||||||
///
|
///
|
||||||
/// Generic over types implementing [`PrivateKey`].
|
/// Generic over types implementing [`PrivateKey`].
|
||||||
#[derive(Clone, Serialize, Deserialize, PartialEq, Eq)]
|
#[derive(Clone, Serialize, Deserialize)]
|
||||||
pub struct ExtendedPrivateKey<K: PrivateKey + Clone> {
|
pub struct ExtendedPrivateKey<K: PrivateKey + Clone> {
|
||||||
/// The internal private key data.
|
/// The internal private key data.
|
||||||
#[serde(with = "serde_with")]
|
#[serde(with = "serde_with")]
|
||||||
|
|
|
@ -51,11 +51,6 @@ impl DerivationPath {
|
||||||
self.path.push(index);
|
self.path.push(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return the inner path.
|
|
||||||
pub fn inner(&self) -> &Vec<DerivationIndex> {
|
|
||||||
&self.path
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Append an index to the path, returning self to allow chaining method calls.
|
/// Append an index to the path, returning self to allow chaining method calls.
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
|
|
|
@ -7,15 +7,14 @@ license = "AGPL-3.0-only"
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["openpgp", "openpgp-card", "qrcode", "bin"]
|
default = ["openpgp", "openpgp-card", "qrcode", "sequoia-openpgp/crypto-nettle", "keyfork-qrcode/decode-backend-rqrr"]
|
||||||
bin = ["sequoia-openpgp/crypto-nettle", "keyfork-qrcode/decode-backend-rqrr"]
|
|
||||||
openpgp = ["sequoia-openpgp", "anyhow"]
|
openpgp = ["sequoia-openpgp", "anyhow"]
|
||||||
openpgp-card = ["openpgp-card-sequoia", "card-backend-pcsc", "card-backend", "dep:openpgp-card"]
|
openpgp-card = ["openpgp-card-sequoia", "card-backend-pcsc", "card-backend", "dep:openpgp-card"]
|
||||||
qrcode = ["keyfork-qrcode"]
|
qrcode = ["keyfork-qrcode"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
keyfork-prompt = { version = "0.1.0", path = "../util/keyfork-prompt", default-features = false, features = ["mnemonic"] }
|
keyfork-prompt = { version = "0.1.0", path = "../util/keyfork-prompt", default-features = false, features = ["mnemonic"] }
|
||||||
keyfork-qrcode = { version = "0.1.0", path = "../qrcode/keyfork-qrcode", optional = true, default-features = false }
|
keyfork-qrcode = { version = "0.1.0", path = "../qrcode/keyfork-qrcode", optional = true }
|
||||||
smex = { version = "0.1.0", path = "../util/smex" }
|
smex = { version = "0.1.0", path = "../util/smex" }
|
||||||
|
|
||||||
sharks = "0.5.0"
|
sharks = "0.5.0"
|
||||||
|
|
|
@ -30,8 +30,8 @@ keyfork-derive-util = { version = "0.1.0", path = "../derive/keyfork-derive-util
|
||||||
keyfork-entropy = { version = "0.1.0", path = "../util/keyfork-entropy" }
|
keyfork-entropy = { version = "0.1.0", path = "../util/keyfork-entropy" }
|
||||||
keyfork-mnemonic-util = { version = "0.1.0", path = "../util/keyfork-mnemonic-util" }
|
keyfork-mnemonic-util = { version = "0.1.0", path = "../util/keyfork-mnemonic-util" }
|
||||||
keyfork-prompt = { version = "0.1.0", path = "../util/keyfork-prompt" }
|
keyfork-prompt = { version = "0.1.0", path = "../util/keyfork-prompt" }
|
||||||
keyfork-qrcode = { version = "0.1.0", path = "../qrcode/keyfork-qrcode", default-features = false }
|
keyfork-qrcode = { version = "0.1.0", path = "../qrcode/keyfork-qrcode" }
|
||||||
keyfork-shard = { version = "0.1.0", path = "../keyfork-shard", default-features = false, features = ["openpgp", "openpgp-card", "qrcode"] }
|
keyfork-shard = { version = "0.1.0", path = "../keyfork-shard" }
|
||||||
smex = { version = "0.1.0", path = "../util/smex" }
|
smex = { version = "0.1.0", path = "../util/smex" }
|
||||||
|
|
||||||
clap = { version = "4.4.2", features = ["derive", "env", "wrap_help"] }
|
clap = { version = "4.4.2", features = ["derive", "env", "wrap_help"] }
|
||||||
|
|
Loading…
Reference in New Issue