diff --git a/Cargo.lock b/Cargo.lock index a0befe1..6caef01 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -88,9 +88,7 @@ dependencies = [ "exec 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", "serde_cbor 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_yaml 0.8.11 (registry+https://github.com/rust-lang/crates.io-index)", "structopt 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", ] diff --git a/coffer-client/Cargo.toml b/coffer-client/Cargo.toml index a4989f3..e0c56d1 100644 --- a/coffer-client/Cargo.toml +++ b/coffer-client/Cargo.toml @@ -12,8 +12,6 @@ log = "0.4" env_logger="0.7" structopt = "0.3" # Communication -serde = { version = "1.0", features = ["derive"]} -serde_yaml = "0.8" serde_cbor = "0.10.2" # Executing subcommand exec = "0.3.1" diff --git a/coffer-client/src/main.rs b/coffer-client/src/main.rs index cf70e73..ff8b937 100644 --- a/coffer-client/src/main.rs +++ b/coffer-client/src/main.rs @@ -1,9 +1,12 @@ +//! # Coffer client +//! +//! Retrieve a secret shard from a `coffer-server`. Secrets in the shard are set +//! as environment variables for the spawned subcommand `cmd`. + #[allow(unused_imports)] use log::{debug, error, info, trace, warn}; use env_logger; -use structopt::StructOpt; - use std:: { net::TcpStream, error::Error, @@ -12,9 +15,14 @@ use std:: { convert::{TryInto, TryFrom} }; -use coffer_common::certificate::Certificate; -use coffer_common::coffer::{CofferShard, CofferValue}; +use coffer_common::{ + coffer::{CofferShard, CofferValue}, + certificate::Certificate +}; +use structopt::StructOpt; + +/// Client for setting up the environment from coffer server secrets #[derive(StructOpt, Debug)] struct Args { /// Address of the coffer server @@ -75,6 +83,8 @@ fn main() -> Result<(), Box> { Err("Could not spawn sub-command".into()) } +/// Replaces the `coffer-client` process image with +/// the subcommand `cmd` with `args` fn reap_coffer(cmd: &str, args: &[String]) { let mut cmd = exec::Command::new(cmd); diff --git a/coffer-common/src/certificate.rs b/coffer-common/src/certificate.rs index 54e44a7..9431184 100644 --- a/coffer-common/src/certificate.rs +++ b/coffer-common/src/certificate.rs @@ -1,12 +1,20 @@ -//! Common certificate handling and encryption +//! A keypair contianer providing functionality for signing, encryption and +//! decryption +//! +//! # Base libraries +//! The cryptographic operations exposed by this module are based on the +//! [NaCl](http://nacl.cr.yp.to/) fork [libsodium](https://libsodium.org) as +//! exposed by the rust bindings [sodiumoxide](https://crates.io/crates/sodiumoxide). #[allow(unused_imports)] use log::{debug, error, info, trace, warn}; -use std::path::Path; -use std::io::BufReader; -use std::fs::File; -use std::fmt::{Debug, Formatter}; +use std::{ + path::Path, + io::BufReader, + fs::File, + ops::Deref +}; use quick_error::quick_error; @@ -25,22 +33,51 @@ quick_error! { Io(err: std::io::Error) { from() } - SecKey + SecKey { + from(CertificateInner) + } Crypto } } -/// A secure container for certificates +/// A secure container for a keypair /// -/// # Certificate +/// Secure means a best effort approach to: +/// - Prevent swapping memory to disk +/// - Zeroing out memory upon dropping +/// - Prevent other processes and buffer overflows to access the secure memory +/// area /// -/// A certificate consists of a public and a private key in a secure memory -/// area. With a certificate data sealed and opened. +/// These guarantees are currently *not* reliable. If you threat model contains +/// targeted attacks against coffer memory, additional precautions have to be +/// taken. pub struct Certificate { inner: SecKey } +// The SecKeyReadGuard prevents convenience methods for handing out references +// to private/public keys (reference outlives SecKeyReadGuard). Hence below +// macros are shortcut projections that can be used after a read guard is +// created + +// Get the public key +macro_rules! pk { + ($cert:ident) => { + &$cert.inner.read().public_key + }; +} + +// Get the private key +macro_rules! sk { + ($cert:ident) => { + &$cert.inner.read().private_key + }; +} + +// Certificate and its inner SecKey own their +// raw pointer without any thread local behaviour unsafe impl Send for Certificate {} +// After initialization, certificate is read-only unsafe impl Sync for Certificate {} #[derive(Serialize, Deserialize)] @@ -49,13 +86,8 @@ struct CertificateInner { private_key: box_::SecretKey } -impl Debug for CertificateInner { - fn fmt(&self, fmt: &mut Formatter<'_>) -> std::fmt::Result { - write!(fmt, "