aboutsummaryrefslogtreecommitdiffstats
path: root/src/identity.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/identity.rs')
-rw-r--r--src/identity.rs71
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());
}