diff options
Diffstat (limited to 'src/identity.rs')
| -rw-r--r-- | src/identity.rs | 71 |
1 files changed, 18 insertions, 53 deletions
diff --git a/src/identity.rs b/src/identity.rs index 93d8739..04b7e6f 100644 --- a/src/identity.rs +++ b/src/identity.rs @@ -3,13 +3,12 @@ //! //! The node ID names the node whatever transport reaches it: a transport address only //! says where it is (`docs/peers.md`, node IDs and addresses). A new key is a new -//! node, so the key is created only when asked to (`--create-node-key`), never because +//! node, so the key is created only when asked to (`--node-key-create`), never because //! a path was mistyped. -use std::io::Write; use std::path::Path; -use anyhow::{Context, Result, bail}; +use anyhow::{Result, bail}; use ed25519_dalek::SigningKey; use tracing::info; @@ -30,25 +29,14 @@ impl NodeKey { /// Reads the key from `path`; with `create`, makes a new one there if the file /// doesn't exist. pub(crate) fn load(path: &Path, create: bool) -> Result<Self> { - let bytes = match std::fs::read(path) { - Ok(bytes) => bytes, - Err(error) if error.kind() == std::io::ErrorKind::NotFound => { - if !create { - bail!( - "The node key file {} doesn't exist; add --create-node-key to create a new node key there (a new key is a new node)", - path.display() - ); - } - let key = Self::create(path)?; - info!(path = %path.display(), node_id = %key.id(), "Created a new node key: this is a new node"); - return Ok(key); - } - Err(error) => { - return Err(error) - .with_context(|| format!("Reading the node key from {}", path.display())); - } - }; - crate::swarm::auth::warn_if_readable_by_others(path, "node key"); + let (bytes, created) = crate::files::key_file( + path, + "node key", + create, + "node-key-create", + "a new key is a new node", + KEY_BYTES, + )?; let Ok(seed) = <[u8; KEY_BYTES]>::try_from(bytes.as_slice()) else { bail!( "The node key in {} has {} bytes; a node key has {KEY_BYTES}", @@ -56,7 +44,11 @@ impl NodeKey { bytes.len() ); }; - Ok(Self::from_seed(seed)) + let key = Self::from_seed(seed); + if created { + info!(path = %path.display(), node_id = %key.id(), "Created a new node key: this is a new node"); + } + Ok(key) } /// A key from its 32 secret bytes: for simulated nodes, which have no key files. @@ -66,26 +58,6 @@ impl NodeKey { } } - /// A new key in a new file at `path` (only its owner may read it). - fn create(path: &Path) -> Result<Self> { - let mut seed = [0u8; KEY_BYTES]; - getrandom::fill(&mut seed).map_err(|error| anyhow::anyhow!("No randomness: {error}"))?; - let mut options = std::fs::OpenOptions::new(); - options.write(true).create_new(true); - #[cfg(unix)] - { - use std::os::unix::fs::OpenOptionsExt; - options.mode(0o600); - } - let written = (|| { - let mut file = options.open(path)?; - file.write_all(&seed)?; - file.sync_all() - })(); - written.with_context(|| format!("Creating the node key file {}", path.display()))?; - Ok(Self::from_seed(seed)) - } - /// This node's ID. pub(crate) fn id(&self) -> String { node_id_of(&self.public()) @@ -129,18 +101,11 @@ pub(crate) fn is_node_id(id: &str) -> bool { #[cfg(test)] mod tests { use super::*; - - fn scratch(name: &str) -> std::path::PathBuf { - let dir = - std::env::temp_dir().join(format!("continuum-identity-{name}-{}", std::process::id())); - let _ = std::fs::remove_dir_all(&dir); - std::fs::create_dir_all(&dir).unwrap(); - dir - } + use crate::files::scratch_dir; #[test] fn created_only_when_asked_and_then_kept() { - let path = scratch("create").join("node.key"); + let path = scratch_dir("identity-create").join("node.key"); assert!(NodeKey::load(&path, false).is_err()); assert!(!path.exists()); @@ -160,7 +125,7 @@ mod tests { #[test] fn a_key_of_the_wrong_size_is_refused() { - let path = scratch("size").join("node.key"); + let path = scratch_dir("identity-size").join("node.key"); std::fs::write(&path, [7u8; 16]).unwrap(); assert!(NodeKey::load(&path, true).is_err()); } |
