From 72c4e2c09e07bcfcf4c1af8011b0569420318a70 Mon Sep 17 00:00:00 2001 From: Taylor Thomas Date: Fri, 16 Dec 2022 16:16:54 -0700 Subject: [PATCH] fix(server): Adds default host keys and signing keys to keychain This automatically adds the keys from signing-keys.toml to the keychain and adds the auto-generated host key to the keychain as well. Fixes #356 Signed-off-by: Taylor Thomas --- bin/server.rs | 35 ++++++++++++++++++++++++++++------- 1 file changed, 28 insertions(+), 7 deletions(-) diff --git a/bin/server.rs b/bin/server.rs index 08cc2d01..4b17ea2f 100644 --- a/bin/server.rs +++ b/bin/server.rs @@ -1,6 +1,7 @@ -use std::net::SocketAddr; use std::path::PathBuf; +use std::{net::SocketAddr, path::Path}; +use bindle::signature::KeyRingSaver; use clap::Parser; use tracing::{debug, info, warn}; @@ -8,7 +9,7 @@ use bindle::{ invoice::signature::{KeyRing, SignatureRole}, provider, search, server::{server, TlsConfig}, - signature::{KeyRingLoader, SecretKeyFile}, + signature::{KeyEntry, KeyRingLoader, SecretKeyFile}, SecretKeyEntry, }; @@ -173,7 +174,6 @@ async fn main() -> anyhow::Result<()> { .join("bindle") }); - // TODO: Should we ensure a keyring? let keyring_file: PathBuf = config .keyring_file .unwrap_or_else(|| default_config_dir().join("keyring.toml")); @@ -184,7 +184,7 @@ async fn main() -> anyhow::Result<()> { // a keyring does not exist. // // All other cases are considered errors worthy of failing. - let keyring: KeyRing = match tokio::fs::metadata(&keyring_file).await { + let mut keyring: KeyRing = match tokio::fs::metadata(&keyring_file).await { Ok(md) if md.is_file() => keyring_file.load().await?, Ok(_) => { anyhow::bail!("Expected {} to be a regular file", keyring_file.display()); @@ -207,7 +207,7 @@ async fn main() -> anyhow::Result<()> { } None => { debug!("No signing key file set, attempting to load from default"); - ensure_signing_keys().await? + ensure_signing_keys(&mut keyring, &keyring_file).await? } }; @@ -236,6 +236,15 @@ async fn main() -> anyhow::Result<()> { ) })?; + // If there are any keys we use for signing, we should trust them in our keychain + keyring.key.extend( + secret_store + .key + .iter() + .map(|sk| KeyEntry::try_from(sk.clone())) + .collect::, _>>()?, + ); + tracing::log::info!( "Starting server at {}, and serving bindles from {}", addr.to_string(), @@ -405,7 +414,11 @@ async fn ensure_config_dir() -> anyhow::Result { Ok(dir) } -async fn ensure_signing_keys() -> anyhow::Result { +/// Makes sure signing keys exist for the host. If it generates a key, it will add it to the current keyring and save it to the path +async fn ensure_signing_keys( + keyring: &mut KeyRing, + keyring_path: &Path, +) -> anyhow::Result { let base = ensure_config_dir().await?; let signing_keyfile = base.join("signing-keys.toml"); @@ -421,7 +434,7 @@ async fn ensure_signing_keys() -> anyhow::Result { signing_keyfile.display() ); let key = SecretKeyEntry::new("Default host key", vec![SignatureRole::Host]); - default_keyfile.key.push(key); + default_keyfile.key.push(key.clone()); default_keyfile .save_file(&signing_keyfile) .await @@ -432,6 +445,14 @@ async fn ensure_signing_keys() -> anyhow::Result { e ) })?; + keyring.add_entry(key.try_into()?); + keyring_path.save(keyring).await.map_err(|e| { + anyhow::anyhow!( + "Unable to save newly created key to keyring {}: {}", + keyring_path.display(), + e + ) + })?; Ok(signing_keyfile) } Err(e) => Err(anyhow::anyhow!(