Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement secure key storage functionality, including updates to Carg… #164

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 11 additions & 7 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ edition = "2021"
description = "A mediator for DIDComm messages"
authors = ["adorsys GmbH Co. KG"]


[workspace]
members = [
"crates/did-utils",
Expand All @@ -14,16 +13,17 @@ members = [
"crates/plugins/did-endpoint",
"crates/plugins/mediator-coordination",
"crates/plugins/oob-messages",
"crates/secure-key-storage", # Added path for the secure_key_storage crate
]


[workspace.dependencies]
did-utils = { path = "./crates/did-utils", version = "0.1.0" }
keystore = { path = "./crates/keystore", version = "0.1.0" }
plugin-api = { path = "./crates/plugin-api", version = "0.1.0" }
did-endpoint = { path = "./crates/plugins/did-endpoint", version = "0.1.0" }
oob-messages = { path = "./crates/plugins/oob-messages", version = "0.1.0" }
mediator-coordination = { path = "./crates/plugins/mediator-coordination", version = "0.1.0" }
secure-key-storage = { path = "./crates/secure-key-storage", version = "0.1.0" } # Added path

# Other common dependencies
serde = "1.0"
Expand All @@ -32,7 +32,7 @@ getrandom = "0.2"
hyper-tls = "0.5.0"
json-patch = "1.0.0"
x25519-dalek = "2.0.0-rc.3"
multibase = "0.8.0" # earlier version due to 'did-utils'
multibase = "0.8.0"
json-canon = "0.1.3"
qrcode = "0.12.0"
image = "0.23"
Expand Down Expand Up @@ -67,10 +67,8 @@ tower-http = "0.4.3"
base64ct = { version = "1.6.0", default-features = false }
zeroize = { version = "1.6.0", default-features = false }


[dependencies]
plugin-api.workspace = true

axum.workspace = true
dotenv-flow.workspace = true
tracing.workspace = true
Expand All @@ -80,21 +78,27 @@ hyper.workspace = true
tokio = { workspace = true, features = ["full"] }
tracing-subscriber = { workspace = true, features = ["json"] }
tower-http = { workspace = true, features = ["catch-panic", "trace"] }
secure-key-storage = { path = "./crates/secure-key-storage" } # Added path

# optional dependencies
chrono = { workspace = true, optional = true }
did-endpoint = { workspace = true, optional = true }
oob-messages = { workspace = true, optional = true }


[features]
default = ["plugin-index", "plugin-did_endpoint", "plugin-oob_messages"]

plugin-index = ["dep:chrono"]
plugin-did_endpoint = ["dep:did-endpoint"]
plugin-oob_messages = ["dep:oob-messages"]


[dev-dependencies]
nix = { version = "0.29.0", features = ["feature"] }
tower = { version = "0.4.13", features = ["util"] }

# Add missing dependencies for `secure_key_storage`
[dependencies.secrecy]
version = "0.9"

[dependencies.serde_derive]
version = "1.0" # Include this only if the `secure_key_storage` crate uses it directly
3 changes: 3 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
pub mod plugins;
pub mod secret_key;
pub mod secure_key;

use axum::Router;
use plugins::handler::PluginContainer;
use secret_key::SecretBox;
use tower_http::{catch_panic::CatchPanicLayer, trace::TraceLayer};

pub fn app() -> (PluginContainer<'static>, Router) {
Expand Down
39 changes: 27 additions & 12 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,27 +1,45 @@
use axum::Server;
use didcomm_mediator::app;
use std::net::SocketAddr;
use secure_key_storage::SecretBox;
use zeroize::Zeroize;
use std::env;
use tracing::info;
use dotenv_flow::dotenv_flow;
use tracing_subscriber::{filter, layer::SubscriberExt, util::SubscriberInitExt};

#[tokio::main]
async fn main() {
// Load dotenv-flow variables
dotenv_flow::dotenv_flow().ok();
dotenv_flow().ok();

// Enable logging
config_tracing();

// Example: securely loading a secret key
let api_key = load_secret_key().await;
info!("Loaded API key.");

// Start server
let port = std::env::var("SERVER_LOCAL_PORT").unwrap_or("3000".to_owned());
let port = env::var("SERVER_LOCAL_PORT").unwrap_or("3000".to_owned());
let addr: SocketAddr = format!("127.0.0.1:{port}").parse().unwrap();

tracing::info!("listening on {addr}");
generic_server_with_graceful_shutdown(addr).await;
info!("listening on {addr}");
generic_server_with_graceful_shutdown(addr, api_key).await;
}

async fn load_secret_key() -> SecretBox<String> {
// Simulate loading a secret key. Replace this with actual key loading.
let secret_key = "supersecretapikey".to_string(); // This should be replaced with actual key retrieval logic
SecretBox::new(secret_key)
}

async fn generic_server_with_graceful_shutdown(addr: SocketAddr) {
async fn generic_server_with_graceful_shutdown(addr: SocketAddr, api_key: SecretBox<String>) {
// Load plugins
let (mut plugin_container, router) = app();

// Use `api_key` securely as needed in your application, for example in your app's router setup.

// Spawn task for server
tokio::spawn(async move {
Server::bind(&addr)
Expand All @@ -32,21 +50,18 @@ async fn generic_server_with_graceful_shutdown(addr: SocketAddr) {

tokio::select! {
_ = tokio::signal::ctrl_c() => {
tracing::info!("shutting down gracefully");
info!("shutting down gracefully");
let _ = plugin_container.unload();
}
};
}

fn config_tracing() {
use tracing::Level;
use tracing_subscriber::{filter, layer::SubscriberExt, util::SubscriberInitExt};

let tracing_layer = tracing_subscriber::fmt::layer();
let filter = filter::Targets::new()
.with_target("hyper::proto", Level::INFO)
.with_target("tower_http::trace", Level::DEBUG)
.with_default(Level::DEBUG);
.with_target("hyper::proto", tracing::Level::INFO)
.with_target("tower_http::trace", tracing::Level::DEBUG)
.with_default(tracing::Level::DEBUG);

tracing_subscriber::registry()
.with(tracing_layer)
Expand Down
43 changes: 43 additions & 0 deletions src/secret_key.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
//! Secure key storage implementation using `SecretBox`
//!
//! This module provides a `SecretBox` wrapper to securely handle secrets,
//! ensuring that they are not exposed, copied, or logged inadvertently.

use secrecy::Secret;
use zeroize::Zeroize;
use core::fmt;

pub struct SecretBox<S: Zeroize> {
inner_secret: Secret<S>,
}

impl<S: Zeroize> SecretBox<S> {
/// Create a new `SecretBox` with the given secret.
pub fn new(secret: S) -> Self {
Self {
inner_secret: Secret::new(secret),
}
}

/// Expose the inner secret for read-only access.
pub fn expose_secret(&self) -> &S {
self.inner_secret.expose_secret()
}

/// Expose the inner secret for mutable access.
pub fn expose_secret_mut(&mut self) -> &mut S {
self.inner_secret.expose_secret_mut()
}
}

impl<S: Zeroize> fmt::Debug for SecretBox<S> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "SecretBox<{}>([REDACTED])", core::any::type_name::<S>())
}
}

impl<S: Zeroize> Drop for SecretBox<S> {
fn drop(&mut self) {
self.inner_secret.zeroize();
}
}
Empty file added src/secure_key/mod.rs
Empty file.
Loading