blob: d054454b2080f0fdd0b8987dd02aa7515bb7c87a [file] [log] [blame]
// Copyright 2020 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
use anyhow::Error;
/// Tracks the set of certificates that are needed to secure a Router
pub trait SecurityContext: Send + Sync + std::fmt::Debug {
/// The node certificate
fn node_cert(&self) -> &str;
/// The node private key
fn node_private_key(&self) -> &str;
/// The root cert for this Overnet mesh
fn root_cert(&self) -> &str;
}
pub(crate) async fn quiche_config_from_security_context(
sec_ctx: &dyn SecurityContext,
) -> Result<quiche::Config, Error> {
let node_cert = sec_ctx.node_cert().to_string();
let node_private_key = sec_ctx.node_private_key().to_string();
let root_cert = sec_ctx.root_cert().to_string();
let mut config = quiche::Config::new(quiche::PROTOCOL_VERSION)?;
config.load_cert_chain_from_pem_file(&node_cert)?;
config.load_priv_key_from_pem_file(&node_private_key)?;
config.load_verify_locations_from_file(&root_cert)?;
config.verify_peer(false);
Ok(config)
}
/// SecurityContext implementation that just lists files to read for the various pieces.
#[derive(Debug)]
pub struct SimpleSecurityContext {
/// The node certificate
pub node_cert: &'static str,
/// The node private key
pub node_private_key: &'static str,
/// The root cert for this Overnet mesh
pub root_cert: &'static str,
}
impl SecurityContext for SimpleSecurityContext {
fn node_cert(&self) -> &str {
self.node_cert
}
fn node_private_key(&self) -> &str {
self.node_private_key
}
fn root_cert(&self) -> &str {
self.root_cert
}
}
/// SecurityContext implementation that just lists files to read for the various pieces.
#[derive(Debug)]
pub struct StringSecurityContext {
/// The node certificate
pub node_cert: String,
/// The node private key
pub node_private_key: String,
/// The root cert for this Overnet mesh
pub root_cert: String,
}
impl SecurityContext for StringSecurityContext {
fn node_cert(&self) -> &str {
&self.node_cert
}
fn node_private_key(&self) -> &str {
&self.node_private_key
}
fn root_cert(&self) -> &str {
&self.root_cert
}
}
/// SecurityContext builder that takes static data and turns it into temporary files
#[cfg(not(target_os = "fuchsia"))]
pub struct MemoryBuffers {
/// The node certificate
pub node_cert: &'static [u8],
/// The node private key
pub node_private_key: &'static [u8],
/// The root cert for this Overnet mesh
pub root_cert: &'static [u8],
}
#[cfg(not(target_os = "fuchsia"))]
impl MemoryBuffers {
/// Turn these buffers into a SecurityContext
pub fn into_security_context(self) -> Result<impl SecurityContext, Error> {
use std::io::Write;
#[derive(Debug)]
struct SecCtx {
node_cert: tempfile::NamedTempFile,
node_private_key: tempfile::NamedTempFile,
root_cert: tempfile::NamedTempFile,
}
impl SecurityContext for SecCtx {
fn node_cert(&self) -> &str {
self.node_cert.path().to_str().unwrap()
}
fn node_private_key(&self) -> &str {
self.node_private_key.path().to_str().unwrap()
}
fn root_cert(&self) -> &str {
self.root_cert.path().to_str().unwrap()
}
}
let load = |contents| -> Result<_, Error> {
let mut f = tempfile::NamedTempFile::new()?;
f.write_all(contents)?;
Ok(f)
};
Ok(SecCtx {
node_cert: load(self.node_cert)?,
node_private_key: load(self.node_private_key)?,
root_cert: load(self.root_cert)?,
})
}
}