From a4ce8b110394cf242444a062503d1096b8dbcf03 Mon Sep 17 00:00:00 2001 From: Laura Abbott Date: Thu, 29 Aug 2024 16:30:03 -0400 Subject: [PATCH] Connect over the bootstrap network using sprockets_tls This uses the certificates/keys in the RoT as the basis for TLS sessions --- Cargo.lock | 139 ++++++- Cargo.toml | 1 + sled-agent/Cargo.toml | 1 + sled-agent/src/bootstrap/client.rs | 26 +- sled-agent/src/bootstrap/http_entrypoints.rs | 9 +- sled-agent/src/bootstrap/rack_ops.rs | 18 +- sled-agent/src/bootstrap/rss_handle.rs | 49 ++- sled-agent/src/bootstrap/server.rs | 2 + sled-agent/src/bootstrap/sprockets_server.rs | 26 +- sled-agent/src/config.rs | 6 + sled-agent/src/http_entrypoints.rs | 1 + sled-agent/src/sled_agent.rs | 9 + smf/sled-agent/gimlet-standalone/config.toml | 4 + smf/sled-agent/gimlet/config.toml | 4 + smf/sled-agent/non-gimlet/config.kdl | 368 ++++++++++++++++++ smf/sled-agent/non-gimlet/config.toml | 7 + smf/sled-agent/non-gimlet/root.cert.pem | 14 + .../non-gimlet/sprockets-auth.key-alt.pem | 4 + .../non-gimlet/sprockets-auth.key.pem | 4 + .../non-gimlet/sprockets-chain-alt.pem | 71 ++++ smf/sled-agent/non-gimlet/sprockets-chain.pem | 71 ++++ tools/install_runner_prerequisites.sh | 1 + workspace-hack/Cargo.toml | 22 +- 23 files changed, 804 insertions(+), 53 deletions(-) create mode 100644 smf/sled-agent/non-gimlet/config.kdl create mode 100644 smf/sled-agent/non-gimlet/root.cert.pem create mode 100644 smf/sled-agent/non-gimlet/sprockets-auth.key-alt.pem create mode 100644 smf/sled-agent/non-gimlet/sprockets-auth.key.pem create mode 100644 smf/sled-agent/non-gimlet/sprockets-chain-alt.pem create mode 100644 smf/sled-agent/non-gimlet/sprockets-chain.pem diff --git a/Cargo.lock b/Cargo.lock index ee4572ad0e..a7cff3dc64 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -526,6 +526,21 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "attest-data" +version = "0.3.0" +source = "git+https://github.com/oxidecomputer/dice-util?rev=3cc953c8d0ace2f20cbcf3920b0771d25301960a#3cc953c8d0ace2f20cbcf3920b0771d25301960a" +dependencies = [ + "getrandom", + "hubpack", + "salty", + "serde", + "serde_with", + "sha3", + "static_assertions", + "thiserror", +] + [[package]] name = "atty" version = "0.2.14" @@ -698,7 +713,7 @@ dependencies = [ "bitflags 2.6.0", "cexpr", "clang-sys", - "itertools 0.12.1", + "itertools 0.10.5", "lazy_static", "lazycell", "log", @@ -2191,6 +2206,23 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a7993efb860416547839c115490d4951c6d0f8ec04a3594d9dd99d50ed7ec170" +[[package]] +name = "dice-verifier" +version = "0.2.0" +source = "git+https://github.com/oxidecomputer/dice-util?rev=3cc953c8d0ace2f20cbcf3920b0771d25301960a#3cc953c8d0ace2f20cbcf3920b0771d25301960a" +dependencies = [ + "anyhow", + "attest-data", + "const-oid", + "ed25519-dalek", + "env_logger 0.11.5", + "log", + "p384", + "pem-rfc7468", + "sha3", + "x509-cert", +] + [[package]] name = "diesel" version = "2.2.3" @@ -2618,6 +2650,7 @@ dependencies = [ "rand_core", "serde", "sha2", + "signature", "subtle", "zeroize", ] @@ -2745,6 +2778,15 @@ dependencies = [ "syn 2.0.74", ] +[[package]] +name = "env_filter" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f2c92ceda6ceec50f43169f9ee8424fe2db276791afde7b2cd8bc084cb376ab" +dependencies = [ + "log", +] + [[package]] name = "env_logger" version = "0.9.3" @@ -2769,6 +2811,16 @@ dependencies = [ "termcolor", ] +[[package]] +name = "env_logger" +version = "0.11.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13fa619b91fb2381732789fc5de83b45675e882f66623b7d8cb4f643017018d" +dependencies = [ + "env_filter", + "log", +] + [[package]] name = "equivalent" version = "1.0.1" @@ -4050,7 +4102,7 @@ dependencies = [ "httpdate", "itoa", "pin-project-lite", - "socket2 0.5.7", + "socket2 0.4.10", "tokio", "tower-service", "tracing", @@ -4145,9 +4197,9 @@ dependencies = [ [[package]] name = "hyper-util" -version = "0.1.3" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca38ef113da30126bbff9cd1705f9273e15d45498615d138b0c20279ac7a76aa" +checksum = "cde7055719c54e36e95e8719f95883f22072a48ede39db7fc17a4e1d5281e9b9" dependencies = [ "bytes", "futures-channel", @@ -6921,6 +6973,7 @@ dependencies = [ "slog-error-chain", "slog-term", "smf", + "sprockets-tls", "static_assertions", "strum", "subprocess", @@ -7010,13 +7063,14 @@ dependencies = [ "clap", "clap_builder", "console", - "const-oid", "crossbeam-epoch", "crossbeam-utils", "crypto-common", - "der", + "curve25519-dalek", "digest", "dof", + "ecdsa", + "ed25519-dalek", "either", "elliptic-curve", "ff", @@ -7085,6 +7139,7 @@ dependencies = [ "similar", "slog", "smallvec 1.13.2", + "socket2 0.5.7", "spin 0.9.8", "string_cache", "subtle", @@ -7107,6 +7162,7 @@ dependencies = [ "usdt", "usdt-impl", "uuid", + "x509-cert", "zerocopy 0.7.34", "zeroize", ] @@ -9467,6 +9523,21 @@ dependencies = [ "zeroize", ] +[[package]] +name = "rustls" +version = "0.23.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05cff451f60db80f490f3c182b77c35260baace73209e9cdbbe526bfe3a4d402" +dependencies = [ + "log", + "once_cell", + "ring 0.17.8", + "rustls-pki-types", + "rustls-webpki 0.102.4", + "subtle", + "zeroize", +] + [[package]] name = "rustls-native-certs" version = "0.7.0" @@ -9599,6 +9670,16 @@ dependencies = [ "cipher", ] +[[package]] +name = "salty" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b947325a585e90733e0e9ec097228f40b637cc346f9bd68f84d5c6297d0fcfef" +dependencies = [ + "subtle", + "zeroize", +] + [[package]] name = "samael" version = "0.0.17" @@ -10559,6 +10640,36 @@ dependencies = [ "der", ] +[[package]] +name = "sprockets-tls" +version = "0.1.0" +source = "git+https://github.com/oxidecomputer/sprockets.git?rev=cc13773832df1e38257cdc511adfaad72954bbe1#cc13773832df1e38257cdc511adfaad72954bbe1" +dependencies = [ + "anyhow", + "attest-data", + "camino", + "cfg-if", + "clap", + "dice-verifier", + "ed25519-dalek", + "libipcc", + "pem-rfc7468", + "rustls 0.23.10", + "secrecy", + "serde", + "sha2", + "sha3", + "slog", + "slog-async", + "slog-term", + "thiserror", + "tokio", + "tokio-rustls 0.26.0", + "toml 0.8.19", + "x509-cert", + "zeroize", +] + [[package]] name = "sqlformat" version = "0.2.4" @@ -11333,6 +11444,17 @@ dependencies = [ "tokio", ] +[[package]] +name = "tokio-rustls" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c7bc40d0e5a97695bb96e27995cd3a08538541b0a846f65bba7a359f36700d4" +dependencies = [ + "rustls 0.23.10", + "rustls-pki-types", + "tokio", +] + [[package]] name = "tokio-stream" version = "0.1.15" @@ -11530,7 +11652,6 @@ dependencies = [ "tokio", "tower-layer", "tower-service", - "tracing", ] [[package]] @@ -12949,9 +13070,9 @@ dependencies = [ [[package]] name = "zeroize" -version = "1.7.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" +checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" dependencies = [ "zeroize_derive", ] diff --git a/Cargo.toml b/Cargo.toml index b7b34390e7..628977df22 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -570,6 +570,7 @@ slog-term = "2.9.1" smf = "0.2" socket2 = { version = "0.5", features = ["all"] } sp-sim = { path = "sp-sim" } +sprockets-tls = { git = "https://github.com/oxidecomputer/sprockets.git", rev = "cc13773832df1e38257cdc511adfaad72954bbe1" } sqlformat = "0.2.4" sqlparser = { version = "0.45.0", features = [ "visitor" ] } static_assertions = "1.1.0" diff --git a/sled-agent/Cargo.toml b/sled-agent/Cargo.toml index e0559cb354..c9f9c53146 100644 --- a/sled-agent/Cargo.toml +++ b/sled-agent/Cargo.toml @@ -80,6 +80,7 @@ slog-async.workspace = true slog-dtrace.workspace = true slog-term.workspace = true smf.workspace = true +sprockets-tls.workspace = true strum.workspace = true tar.workspace = true thiserror.workspace = true diff --git a/sled-agent/src/bootstrap/client.rs b/sled-agent/src/bootstrap/client.rs index bfdaf6e6d4..02ca18f449 100644 --- a/sled-agent/src/bootstrap/client.rs +++ b/sled-agent/src/bootstrap/client.rs @@ -12,13 +12,14 @@ use crate::bootstrap::views::Response; use crate::bootstrap::views::ResponseEnvelope; use sled_agent_types::sled::StartSledAgentRequest; use slog::Logger; +use sprockets_tls::client::Client as SprocketsClient; +use sprockets_tls::keys::SprocketsConfig; use std::borrow::Cow; use std::io; use std::net::SocketAddrV6; use thiserror::Error; use tokio::io::AsyncReadExt; use tokio::io::AsyncWriteExt; -use tokio::net::TcpStream; #[derive(Debug, Error)] pub enum Error { @@ -67,12 +68,17 @@ pub enum Error { /// bootstrap agent. pub(crate) struct Client { addr: SocketAddrV6, - _log: Logger, + log: Logger, + sprockets_conf: SprocketsConfig, } impl Client { - pub(crate) fn new(addr: SocketAddrV6, _log: Logger) -> Self { - Self { addr, _log } + pub(crate) fn new( + addr: SocketAddrV6, + sprockets_conf: SprocketsConfig, + log: Logger, + ) -> Self { + Self { addr, sprockets_conf, log } } /// Start sled agent by sending an initialization request determined from @@ -100,10 +106,16 @@ impl Client { // far larger than we ever expect to see. const MAX_RESPONSE_LEN: u32 = 16 << 20; + let log = self.log.new(o!("component" => "SledAgentSprocketsClient")); // Establish connection and sprockets connection (if possible). - let stream = TcpStream::connect(self.addr) - .await - .map_err(|err| Error::Connect { addr: self.addr, err })?; + // The sprockets client loads the associated root certificates at this point. + let stream = SprocketsClient::connect( + self.sprockets_conf.clone(), + self.addr, + log.clone(), + ) + .await + .unwrap(); let mut stream = Box::new(tokio::io::BufStream::new(stream)); diff --git a/sled-agent/src/bootstrap/http_entrypoints.rs b/sled-agent/src/bootstrap/http_entrypoints.rs index 2bd1745f77..1af8ea738e 100644 --- a/sled-agent/src/bootstrap/http_entrypoints.rs +++ b/sled-agent/src/bootstrap/http_entrypoints.rs @@ -29,6 +29,7 @@ use sled_agent_types::rack_ops::RackOperationStatus; use sled_hardware_types::Baseboard; use sled_storage::manager::StorageHandle; use slog::Logger; +use sprockets_tls::keys::SprocketsConfig; use std::net::Ipv6Addr; use tokio::sync::mpsc::error::TrySendError; use tokio::sync::{mpsc, oneshot}; @@ -43,6 +44,7 @@ pub(crate) struct BootstrapServerContext { pub(crate) updates: ConfigUpdates, pub(crate) sled_reset_tx: mpsc::Sender>>, + pub(crate) sprockets: SprocketsConfig, } impl BootstrapServerContext { @@ -52,6 +54,7 @@ impl BootstrapServerContext { ) -> Result { self.rss_access.start_initializing( &self.base_log, + self.sprockets.clone(), self.global_zone_bootstrap_ip, &self.storage_manager, &self.bootstore_node_handle, @@ -116,7 +119,11 @@ impl BootstrapAgentApi for BootstrapAgentImpl { let ctx = rqctx.context(); let id = ctx .rss_access - .start_reset(&ctx.base_log, ctx.global_zone_bootstrap_ip) + .start_reset( + &ctx.base_log, + ctx.sprockets.clone(), + ctx.global_zone_bootstrap_ip, + ) .map_err(|err| HttpError::for_bad_request(None, err.to_string()))?; Ok(HttpResponseOk(id)) } diff --git a/sled-agent/src/bootstrap/rack_ops.rs b/sled-agent/src/bootstrap/rack_ops.rs index cd59aa4849..2be59fd588 100644 --- a/sled-agent/src/bootstrap/rack_ops.rs +++ b/sled-agent/src/bootstrap/rack_ops.rs @@ -13,6 +13,7 @@ use sled_agent_types::rack_init::RackInitializeRequest; use sled_agent_types::rack_ops::{RackOperationStatus, RssStep}; use sled_storage::manager::StorageHandle; use slog::Logger; +use sprockets_tls::keys::SprocketsConfig; use std::mem; use std::net::Ipv6Addr; use std::sync::Arc; @@ -143,6 +144,7 @@ impl RssAccess { pub(crate) fn start_initializing( &self, parent_log: &Logger, + sprockets: SprocketsConfig, global_zone_bootstrap_ip: Ipv6Addr, storage_manager: &StorageHandle, bootstore_node_handle: &bootstore::NodeHandle, @@ -186,6 +188,7 @@ impl RssAccess { tokio::spawn(async move { let result = rack_initialize( &parent_log, + sprockets, global_zone_bootstrap_ip, storage_manager, bootstore_node_handle, @@ -213,6 +216,7 @@ impl RssAccess { pub(super) fn start_reset( &self, parent_log: &Logger, + sprockets: SprocketsConfig, global_zone_bootstrap_ip: Ipv6Addr, ) -> Result { let mut status = self.status.lock().unwrap(); @@ -248,8 +252,12 @@ impl RssAccess { let parent_log = parent_log.clone(); let status = Arc::clone(&self.status); tokio::spawn(async move { - let result = - rack_reset(&parent_log, global_zone_bootstrap_ip).await; + let result = rack_reset( + &parent_log, + sprockets, + global_zone_bootstrap_ip, + ) + .await; let new_status = match result { Ok(()) => { RssStatus::Uninitialized { reset_id: Some(id) } @@ -318,6 +326,7 @@ enum RssStatus { async fn rack_initialize( parent_log: &Logger, + sprockets: SprocketsConfig, global_zone_bootstrap_ip: Ipv6Addr, storage_manager: StorageHandle, bootstore_node_handle: bootstore::NodeHandle, @@ -326,6 +335,7 @@ async fn rack_initialize( ) -> Result<(), SetupServiceError> { RssHandle::run_rss( parent_log, + sprockets, request, global_zone_bootstrap_ip, storage_manager, @@ -337,7 +347,9 @@ async fn rack_initialize( async fn rack_reset( parent_log: &Logger, + sprockets: SprocketsConfig, global_zone_bootstrap_ip: Ipv6Addr, ) -> Result<(), SetupServiceError> { - RssHandle::run_rss_reset(parent_log, global_zone_bootstrap_ip).await + RssHandle::run_rss_reset(parent_log, global_zone_bootstrap_ip, sprockets) + .await } diff --git a/sled-agent/src/bootstrap/rss_handle.rs b/sled-agent/src/bootstrap/rss_handle.rs index 0cf6054ca2..4a7449eea8 100644 --- a/sled-agent/src/bootstrap/rss_handle.rs +++ b/sled-agent/src/bootstrap/rss_handle.rs @@ -19,6 +19,7 @@ use sled_agent_types::rack_ops::RssStep; use sled_agent_types::sled::StartSledAgentRequest; use sled_storage::manager::StorageHandle; use slog::Logger; +use sprockets_tls::keys::SprocketsConfig; use std::net::Ipv6Addr; use std::net::SocketAddrV6; use tokio::sync::mpsc; @@ -46,13 +47,14 @@ impl RssHandle { /// Executes the rack setup service until it has completed pub(super) async fn run_rss( log: &Logger, + sprockets: SprocketsConfig, config: RackInitializeRequest, our_bootstrap_address: Ipv6Addr, storage_manager: StorageHandle, bootstore: bootstore::NodeHandle, step_tx: watch::Sender, ) -> Result<(), SetupServiceError> { - let (tx, rx) = rss_channel(our_bootstrap_address); + let (tx, rx) = rss_channel(our_bootstrap_address, sprockets); let rss = RackSetupService::new( log.new(o!("component" => "RSS")), @@ -71,8 +73,9 @@ impl RssHandle { pub(super) async fn run_rss_reset( log: &Logger, our_bootstrap_address: Ipv6Addr, + sprockets: SprocketsConfig, ) -> Result<(), SetupServiceError> { - let (tx, rx) = rss_channel(our_bootstrap_address); + let (tx, rx) = rss_channel(our_bootstrap_address, sprockets); let rss = RackSetupService::new_reset_rack( log.new(o!("component" => "RSS")), @@ -88,10 +91,12 @@ impl RssHandle { async fn initialize_sled_agent( log: &Logger, bootstrap_addr: SocketAddrV6, + sprockets: SprocketsConfig, request: &StartSledAgentRequest, ) -> Result<(), bootstrap_agent_client::Error> { let client = bootstrap_agent_client::Client::new( bootstrap_addr, + sprockets, log.new(o!("BootstrapAgentClient" => bootstrap_addr.to_string())), ); @@ -122,11 +127,12 @@ async fn initialize_sled_agent( // communication mechanism. fn rss_channel( our_bootstrap_address: Ipv6Addr, + sprockets: SprocketsConfig, ) -> (BootstrapAgentHandle, BootstrapAgentHandleReceiver) { let (tx, rx) = mpsc::channel(32); ( BootstrapAgentHandle { inner: tx, our_bootstrap_address }, - BootstrapAgentHandleReceiver { inner: rx }, + BootstrapAgentHandleReceiver { inner: rx, sprockets }, ) } @@ -197,6 +203,7 @@ impl BootstrapAgentHandle { struct BootstrapAgentHandleReceiver { inner: mpsc::Receiver, + sprockets: SprocketsConfig, } impl BootstrapAgentHandleReceiver { @@ -215,16 +222,25 @@ impl BootstrapAgentHandleReceiver { RequestKind::Init(requests) => { // Convert the vec of requests into a `FuturesUnordered` containing all // of the initialization requests, allowing them to run concurrently. + + let s = self.sprockets.clone(); let mut futs = requests .into_iter() - .map(|(bootstrap_addr, request)| async move { - info!( - log, "Received initialization request from RSS"; - "request" => ?request, - "target_sled" => %bootstrap_addr, - ); - - initialize_sled_agent(log, bootstrap_addr, &request) + .map(|(bootstrap_addr, request)| { + let value = s.clone(); + async move { + info!( + log, "Received initialization request from RSS"; + "request" => ?request, + "target_sled" => %bootstrap_addr, + ); + + initialize_sled_agent( + log, + bootstrap_addr, + value, + &request, + ) .await .map_err(|err| { format!( @@ -233,12 +249,13 @@ impl BootstrapAgentHandleReceiver { ) })?; - info!( - log, "Initialized sled agent"; - "target_sled" => %bootstrap_addr, - ); + info!( + log, "Initialized sled agent"; + "target_sled" => %bootstrap_addr, + ); - Ok(()) + Ok(()) + } }) .collect::>(); diff --git a/sled-agent/src/bootstrap/server.rs b/sled-agent/src/bootstrap/server.rs index 6681f396b4..bee6b52d75 100644 --- a/sled-agent/src/bootstrap/server.rs +++ b/sled-agent/src/bootstrap/server.rs @@ -211,6 +211,7 @@ impl Server { rss_access, updates: config.updates.clone(), sled_reset_tx, + sprockets: config.sprockets.clone(), }; let bootstrap_http_server = start_dropshot_server(bootstrap_context)?; @@ -230,6 +231,7 @@ impl Server { 0, ), sled_init_tx, + config.sprockets.clone(), &base_log, ) .await diff --git a/sled-agent/src/bootstrap/sprockets_server.rs b/sled-agent/src/bootstrap/sprockets_server.rs index 8d92970d54..bb7f10d752 100644 --- a/sled-agent/src/bootstrap/sprockets_server.rs +++ b/sled-agent/src/bootstrap/sprockets_server.rs @@ -12,12 +12,14 @@ use crate::bootstrap::views::ResponseEnvelope; use crate::bootstrap::views::SledAgentResponse; use sled_agent_types::sled::StartSledAgentRequest; use slog::Logger; +use sprockets_tls::keys::SprocketsConfig; +use sprockets_tls::server::Server; +use sprockets_tls::Stream; use std::io; use std::net::SocketAddrV6; use tokio::io::AsyncReadExt; use tokio::io::AsyncWriteExt; use tokio::io::BufStream; -use tokio::net::TcpListener; use tokio::net::TcpStream; use tokio::sync::mpsc; use tokio::sync::oneshot; @@ -28,7 +30,7 @@ type TxRequestsChannel = mpsc::Sender<( )>; pub(super) struct SprocketsServer { - listener: TcpListener, + listener: Server, tx_requests: TxRequestsChannel, log: Logger, } @@ -37,10 +39,15 @@ impl SprocketsServer { pub(super) async fn bind( bind_addr: SocketAddrV6, tx_requests: TxRequestsChannel, + sprockets_conf: SprocketsConfig, base_log: &Logger, ) -> io::Result { - let listener = TcpListener::bind(bind_addr).await?; let log = base_log.new(o!("component" => "SledAgentSprocketsServer")); + + // The root certificates associated with sprockets are loaded at + // server creation time + let listener = + Server::new(sprockets_conf, bind_addr, log.clone()).await.unwrap(); info!(log, "Started listening"; "local_addr" => %bind_addr); Ok(Self { listener, tx_requests, log }) } @@ -48,12 +55,13 @@ impl SprocketsServer { /// Run the sprockets server. /// /// This method should be `tokio::spawn()`'d. It can safely be cancelled - /// to shut it down: its only `.await` point is on - /// `TcpListener::accept()`, which is cancel-safe. Note that cancelling this + /// to shut it down: its only `.await` point is on a sprocket listener, + /// which is cancel-safe. Note that cancelling this /// server does not necessarily cancel any outstanding requests that it has /// already received (and which may still be executing). - pub(super) async fn run(self) { + pub(super) async fn run(mut self) { loop { + // Sprockets actually _uses_ the key here! let (stream, remote_addr) = match self.listener.accept().await { Ok(conn) => conn, Err(err) => { @@ -79,7 +87,7 @@ impl SprocketsServer { } async fn handle_start_sled_agent_request( - stream: TcpStream, + stream: Stream, tx_requests: TxRequestsChannel, log: &Logger, ) -> Result<(), String> { @@ -131,7 +139,7 @@ async fn handle_start_sled_agent_request( } async fn read_request( - stream: &mut Box>, + stream: &mut Box>>, ) -> Result, String> { // Bound to avoid allocating an unreasonable amount of memory from a bogus // length prefix from a client. We authenticate clients via sprockets before @@ -175,7 +183,7 @@ async fn read_request( } async fn write_response( - stream: &mut Box>, + stream: &mut Box>>, response: Result, ) -> Result<(), String> { // Build and serialize response. diff --git a/sled-agent/src/config.rs b/sled-agent/src/config.rs index ac9b61f3bb..60e465745a 100644 --- a/sled-agent/src/config.rs +++ b/sled-agent/src/config.rs @@ -16,6 +16,7 @@ use omicron_common::vlan::VlanID; use serde::Deserialize; use sled_hardware::is_gimlet; use sled_hardware::UnparsedDisk; +use sprockets_tls::keys::SprocketsConfig; #[derive(Clone, Debug, Deserialize)] #[serde(rename_all = "lowercase")] @@ -101,6 +102,11 @@ pub struct Config { /// mode maghemite there. #[serde(default)] pub switch_zone_maghemite_links: Vec, + + /// Settings for sprockets running on the bootstrap network. Includes + /// root certificates and whether to use local certificate chain or + /// one over IPCC + pub sprockets: SprocketsConfig, } #[derive(Debug, thiserror::Error)] diff --git a/sled-agent/src/http_entrypoints.rs b/sled-agent/src/http_entrypoints.rs index a48e616070..2886c1380d 100644 --- a/sled-agent/src/http_entrypoints.rs +++ b/sled-agent/src/http_entrypoints.rs @@ -565,6 +565,7 @@ impl SledAgentApi for SledAgentImpl { crate::sled_agent::sled_add( sa.logger().clone(), + sa.sprockets().clone(), request.sled_id, request.start_request, ) diff --git a/sled-agent/src/sled_agent.rs b/sled-agent/src/sled_agent.rs index e7fcdfc327..b02296ce2d 100644 --- a/sled-agent/src/sled_agent.rs +++ b/sled-agent/src/sled_agent.rs @@ -76,6 +76,7 @@ use sled_hardware_types::Baseboard; use sled_storage::dataset::{CRYPT_DATASET, ZONE_DATASET}; use sled_storage::manager::StorageHandle; use slog::Logger; +use sprockets_tls::keys::SprocketsConfig; use std::collections::BTreeMap; use std::net::{Ipv6Addr, SocketAddrV6}; use std::sync::Arc; @@ -365,6 +366,7 @@ impl SledAgentInner { pub struct SledAgent { inner: Arc, log: Logger, + sprockets: SprocketsConfig, } impl SledAgent { @@ -604,6 +606,7 @@ impl SledAgent { boot_disk_os_writer: BootDiskOsWriter::new(&parent_log), }), log: log.clone(), + sprockets: config.sprockets.clone(), }; sled_agent.inner.probes.run().await; @@ -687,6 +690,10 @@ impl SledAgent { &self.inner.start_request } + pub fn sprockets(&self) -> SprocketsConfig { + self.sprockets.clone() + } + /// Requests firewall rules from Nexus. /// /// Does not retry upon failure. @@ -1328,6 +1335,7 @@ pub enum AddSledError { /// Add a sled to an initialized rack. pub async fn sled_add( log: Logger, + sprockets_config: SprocketsConfig, sled_id: BaseboardId, request: StartSledAgentRequest, ) -> Result<(), AddSledError> { @@ -1387,6 +1395,7 @@ pub async fn sled_add( SocketAddrV6::new(bootstrap_addr, BOOTSTRAP_AGENT_RACK_INIT_PORT, 0, 0); let client = crate::bootstrap::client::Client::new( bootstrap_addr, + sprockets_config, log.new(o!("BootstrapAgentClient" => bootstrap_addr.to_string())), ); diff --git a/smf/sled-agent/gimlet-standalone/config.toml b/smf/sled-agent/gimlet-standalone/config.toml index 4d06895453..620dd17290 100644 --- a/smf/sled-agent/gimlet-standalone/config.toml +++ b/smf/sled-agent/gimlet-standalone/config.toml @@ -51,3 +51,7 @@ level = "info" mode = "file" path = "/dev/stdout" if_exists = "append" + +[sprockets] +resolve = { which = "ipcc" } +roots = ["/usr/share/oxide/idcerts/staging.pem", "/usr/share/oxide/idcerts/production.pem"] diff --git a/smf/sled-agent/gimlet/config.toml b/smf/sled-agent/gimlet/config.toml index 666d55f359..55bfbbbc82 100644 --- a/smf/sled-agent/gimlet/config.toml +++ b/smf/sled-agent/gimlet/config.toml @@ -47,3 +47,7 @@ level = "info" mode = "file" path = "/dev/stdout" if_exists = "append" + +[sprockets] +resolve = { which = "ipcc" } +roots = ["/usr/share/oxide/idcerts/staging.pem", "/usr/share/oxide/idcerts/production.pem"] diff --git a/smf/sled-agent/non-gimlet/config.kdl b/smf/sled-agent/non-gimlet/config.kdl new file mode 100644 index 0000000000..b24fa86870 --- /dev/null +++ b/smf/sled-agent/non-gimlet/config.kdl @@ -0,0 +1,368 @@ +key-pair "test-root-a" { + p384 +} + +entity "test-root-a" { + country-name "US" + organization-name "Oxide Computer Company" + common-name "test-root-a" +} + +certificate "test-root-a" { + issuer-entity "test-root-a" + issuer-key "test-root-a" + + subject-entity "test-root-a" + subject-key "test-root-a" + + digest-algorithm "sha-384" + not-after "9999-12-31T23:59:59Z" + serial-number "00" + + extensions { + subject-key-identifier critical=false + + basic-constraints critical=true ca=true + key-usage critical=true { + key-cert-sign + crl-sign + } + certificate-policies critical=true { + oana-platform-identity + tcg-dice-kp-identity-init + tcg-dice-kp-attest-init + tcg-dice-kp-eca + } + } +} + +key-pair "test-signer-a1" { + p384 +} + +entity "test-signer-a1" { + country-name "US" + organization-name "Oxide Computer Company" + common-name "test-signer-a1" +} + +certificate "test-signer-a1" { + issuer-certificate "test-root-a" + issuer-key "test-root-a" + + subject-entity "test-signer-a1" + subject-key "test-signer-a1" + + digest-algorithm "sha-384" + not-after "9999-12-31T23:59:59Z" + serial-number "01" + + extensions { + subject-key-identifier critical=false + authority-key-identifier critical=false { + key-id + } + + basic-constraints critical=true ca=true + key-usage critical=true { + key-cert-sign + crl-sign + } + certificate-policies critical=true { + oana-platform-identity + tcg-dice-kp-identity-init + tcg-dice-kp-attest-init + tcg-dice-kp-eca + } + } +} + +key-pair "test-signer-a2" { + p384 +} + +entity "test-signer-a2" { + country-name "US" + organization-name "Oxide Computer Company" + common-name "test-platformid-1 Signer Staging A2" +} + +certificate "test-signer-a2" { + issuer-certificate "test-root-a" + issuer-key "test-root-a" + + subject-entity "test-signer-a2" + subject-key "test-signer-a2" + + digest-algorithm "sha-384" + not-after "9999-12-31T23:59:59Z" + serial-number "01" + + extensions { + subject-key-identifier critical=false + authority-key-identifier critical=false { + key-id + } + + basic-constraints critical=true ca=true + key-usage critical=true { + key-cert-sign + crl-sign + } + certificate-policies critical=true { + oana-platform-identity + tcg-dice-kp-identity-init + tcg-dice-kp-attest-init + tcg-dice-kp-eca + } + } +} +/// Device 1 +key-pair "test-platformid-1" { + ed25519 +} + +entity "test-platformid-1" { + country-name "US" + organization-name "Oxide Computer Company" + common-name "PDV2:PPP-PPPPPPP:RRR:SSSSSSSSSS1" +} + +certificate "test-platformid-1" { + issuer-certificate "test-signer-a1" + issuer-key "test-signer-a1" + + subject-entity "test-platformid-1" + subject-key "test-platformid-1" + + digest-algorithm "sha-384" + not-after "9999-12-31T23:59:59Z" + serial-number "02" + + extensions { + subject-key-identifier critical=false + authority-key-identifier critical=false { + key-id + } + + basic-constraints critical=true ca=true + key-usage critical=true { + key-cert-sign + crl-sign + } + certificate-policies critical=true { + oana-platform-identity + tcg-dice-kp-identity-init + tcg-dice-kp-attest-init + tcg-dice-kp-eca + } + } +} + +key-pair "test-deviceid-1" { + ed25519 +} + +entity "test-deviceid-1" { + country-name "US" + organization-name "Oxide Computer Company" + common-name "/C=US/O=Oxide Computer Company/CN=test-deviceid-1" +} + +certificate "test-deviceid-1" { + issuer-certificate "test-platformid-1" + issuer-key "test-platformid-1" + + subject-entity "test-deviceid-1" + subject-key "test-deviceid-1" + + digest-algorithm "sha-512" + not-after "9999-12-31T23:59:59Z" + serial-number "03" + + extensions { + subject-key-identifier critical=false + authority-key-identifier critical=false { + key-id + } + + basic-constraints critical=true ca=true + key-usage critical=true { + key-cert-sign + crl-sign + } + certificate-policies critical=true { + oana-platform-identity + tcg-dice-kp-identity-init + tcg-dice-kp-attest-init + tcg-dice-kp-eca + } + } +} + +key-pair "test-sprockets-auth-1" { + ed25519 +} + +entity "test-sprockets-auth-1" { + country-name "US" + organization-name "Oxide Computer Company" + common-name "/C=US/O=Oxide Computer Company/CN=test-sprockets-auth-1" +} + +certificate "test-sprockets-auth-1" { + issuer-certificate "test-deviceid-1" + issuer-key "test-deviceid-1" + + subject-entity "test-sprockets-auth-1" + subject-key "test-sprockets-auth-1" + + digest-algorithm "sha-512" + not-after "9999-12-31T23:59:59Z" + serial-number "04" + + extensions { + subject-key-identifier critical=false + authority-key-identifier critical=false { + key-id + } + + basic-constraints critical=true ca=false + key-usage critical=true { + digital-signature + non-repudiation + } + certificate-policies critical=true { + oana-platform-identity + tcg-dice-kp-identity-init + tcg-dice-kp-attest-init + tcg-dice-kp-eca + } + } +} + +/// Device 2 + +key-pair "test-platformid-2" { + ed25519 +} + +entity "test-platformid-2" { + country-name "US" + organization-name "Oxide Computer Company" + common-name "PDV2:PPP-PPPPPPP:RRR:SSSSSSSSSS2" +} + +certificate "test-platformid-2" { + issuer-certificate "test-signer-a1" + issuer-key "test-signer-a1" + + subject-entity "test-platformid-2" + subject-key "test-platformid-2" + + digest-algorithm "sha-384" + not-after "9999-12-31T23:59:59Z" + serial-number "05" + + extensions { + subject-key-identifier critical=false + authority-key-identifier critical=false { + key-id + } + + basic-constraints critical=true ca=true + key-usage critical=true { + key-cert-sign + crl-sign + } + certificate-policies critical=true { + oana-platform-identity + tcg-dice-kp-identity-init + tcg-dice-kp-attest-init + tcg-dice-kp-eca + } + } +} + +key-pair "test-deviceid-2" { + ed25519 +} + +entity "test-deviceid-2" { + country-name "US" + organization-name "Oxide Computer Company" + common-name "/C=US/O=Oxide Computer Company/CN=test-deviceid-2" +} + +certificate "test-deviceid-2" { + issuer-certificate "test-platformid-2" + issuer-key "test-platformid-2" + + subject-entity "test-deviceid-2" + subject-key "test-deviceid-2" + + digest-algorithm "sha-512" + not-after "9999-12-31T23:59:59Z" + serial-number "06" + + extensions { + subject-key-identifier critical=false + authority-key-identifier critical=false { + key-id + } + + basic-constraints critical=true ca=true + key-usage critical=true { + key-cert-sign + crl-sign + } + certificate-policies critical=true { + oana-platform-identity + tcg-dice-kp-identity-init + tcg-dice-kp-attest-init + tcg-dice-kp-eca + } + } +} + +key-pair "test-sprockets-auth-2" { + ed25519 +} + +entity "test-sprockets-auth-2" { + country-name "US" + organization-name "Oxide Computer Company" + common-name "/C=US/O=Oxide Computer Company/CN=test-sprockets-auth-2" +} + +certificate "test-sprockets-auth-2" { + issuer-certificate "test-deviceid-2" + issuer-key "test-deviceid-2" + + subject-entity "test-sprockets-auth-2" + subject-key "test-sprockets-auth-2" + + digest-algorithm "sha-512" + not-after "9999-12-31T23:59:59Z" + serial-number "07" + + extensions { + subject-key-identifier critical=false + authority-key-identifier critical=false { + key-id + } + + basic-constraints critical=true ca=false + key-usage critical=true { + digital-signature + non-repudiation + } + certificate-policies critical=true { + oana-platform-identity + tcg-dice-kp-identity-init + tcg-dice-kp-attest-init + tcg-dice-kp-eca + } + } +} + diff --git a/smf/sled-agent/non-gimlet/config.toml b/smf/sled-agent/non-gimlet/config.toml index 77ca52a647..03737cd3c0 100644 --- a/smf/sled-agent/non-gimlet/config.toml +++ b/smf/sled-agent/non-gimlet/config.toml @@ -88,3 +88,10 @@ level = "info" mode = "file" path = "/dev/stdout" if_exists = "append" + +# These are pre-generated keys and roots designed to be used for testing. +# Create your own if you need to test a multi-node system +# See the .kdl file for use with pki-playground for generating +[sprockets] +resolve = { which = "local", priv_key = "/opt/oxide/sled-agent/pkg/sprockets-auth.key.pem", cert_chain = "/opt/oxide/sled-agent/pkg/sprockets-chain.pem" } +roots = ["/opt/oxide/sled-agent/pkg/root.cert.pem"] diff --git a/smf/sled-agent/non-gimlet/root.cert.pem b/smf/sled-agent/non-gimlet/root.cert.pem new file mode 100644 index 0000000000..6b3844fa5c --- /dev/null +++ b/smf/sled-agent/non-gimlet/root.cert.pem @@ -0,0 +1,14 @@ +-----BEGIN CERTIFICATE----- +MIICNTCCAbugAwIBAgIBADAKBggqhkjOPQQDAzBEMQswCQYDVQQGEwJVUzEfMB0G +A1UECgwWT3hpZGUgQ29tcHV0ZXIgQ29tcGFueTEUMBIGA1UEAwwLdGVzdC1yb290 +LWEwIBcNMjQwNjEyMTYzMjM3WhgPOTk5OTEyMzEyMzU5NTlaMEQxCzAJBgNVBAYT +AlVTMR8wHQYDVQQKDBZPeGlkZSBDb21wdXRlciBDb21wYW55MRQwEgYDVQQDDAt0 +ZXN0LXJvb3QtYTB2MBAGByqGSM49AgEGBSuBBAAiA2IABMTVjqvxuneT7jaxw6AJ +qqTY3wKithGZt2PUF1TI1AMhnJtfomYjqkQutd+uLhWW5Kq4KXSfZm3OUdZYODZx +n96zENU/iBwq0c0/+FcZEEGQpoSFU5gFfK2/NeMAI3i8c6N/MH0wHQYDVR0OBBYE +FA32eUa3XQ7AOCxvlhiPSVrs/q76MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/ +BAQDAgEGMDsGA1UdIAEB/wQxMC8wDAYKKwYBBAGDwU8BAzAJBgdngQUFBGQGMAkG +B2eBBQUEZAgwCQYHZ4EFBQRkDDAKBggqhkjOPQQDAwNoADBlAjB8UhO0TeULDm2k +RAnyzd1aVissw+BCZGvRsoVuH/Z7i9Yb/fu4pejwuECKO0D7eJUCMQDafRL3gT55 +NBb2W+z8WGKS8B2JIO/Gonnx4XXPYXDsOXlYyGKPqh+VOCRNT7KcQ30= +-----END CERTIFICATE----- diff --git a/smf/sled-agent/non-gimlet/sprockets-auth.key-alt.pem b/smf/sled-agent/non-gimlet/sprockets-auth.key-alt.pem new file mode 100644 index 0000000000..c7081af378 --- /dev/null +++ b/smf/sled-agent/non-gimlet/sprockets-auth.key-alt.pem @@ -0,0 +1,4 @@ +-----BEGIN PRIVATE KEY----- +MFECAQEwBQYDK2VwBCIEIKUDZEeGHACBfyzsrpIbUq+9ieb/Sjv4SUYYVPSH9AYb +gSEAmVwM+SRtpiGqGYHgHCGN4iGdfZ39ML9WrPIYCtFJLyU= +-----END PRIVATE KEY----- diff --git a/smf/sled-agent/non-gimlet/sprockets-auth.key.pem b/smf/sled-agent/non-gimlet/sprockets-auth.key.pem new file mode 100644 index 0000000000..ef762303f4 --- /dev/null +++ b/smf/sled-agent/non-gimlet/sprockets-auth.key.pem @@ -0,0 +1,4 @@ +-----BEGIN PRIVATE KEY----- +MFECAQEwBQYDK2VwBCIEIP//7ZHeb32TVF+0V21Fk7IU51xMnjOQ/VfCnM4YsoWC +gSEA3YfArFPuOHDoQj3aO5VSyuOIPfbAuEpB93dnYnZlM2U= +-----END PRIVATE KEY----- diff --git a/smf/sled-agent/non-gimlet/sprockets-chain-alt.pem b/smf/sled-agent/non-gimlet/sprockets-chain-alt.pem new file mode 100644 index 0000000000..1daa5eb7fa --- /dev/null +++ b/smf/sled-agent/non-gimlet/sprockets-chain-alt.pem @@ -0,0 +1,71 @@ +-----BEGIN CERTIFICATE----- +MIICNTCCAbugAwIBAgIBADAKBggqhkjOPQQDAzBEMQswCQYDVQQGEwJVUzEfMB0G +A1UECgwWT3hpZGUgQ29tcHV0ZXIgQ29tcGFueTEUMBIGA1UEAwwLdGVzdC1yb290 +LWEwIBcNMjQwNjEyMTYzMjM3WhgPOTk5OTEyMzEyMzU5NTlaMEQxCzAJBgNVBAYT +AlVTMR8wHQYDVQQKDBZPeGlkZSBDb21wdXRlciBDb21wYW55MRQwEgYDVQQDDAt0 +ZXN0LXJvb3QtYTB2MBAGByqGSM49AgEGBSuBBAAiA2IABMTVjqvxuneT7jaxw6AJ +qqTY3wKithGZt2PUF1TI1AMhnJtfomYjqkQutd+uLhWW5Kq4KXSfZm3OUdZYODZx +n96zENU/iBwq0c0/+FcZEEGQpoSFU5gFfK2/NeMAI3i8c6N/MH0wHQYDVR0OBBYE +FA32eUa3XQ7AOCxvlhiPSVrs/q76MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/ +BAQDAgEGMDsGA1UdIAEB/wQxMC8wDAYKKwYBBAGDwU8BAzAJBgdngQUFBGQGMAkG +B2eBBQUEZAgwCQYHZ4EFBQRkDDAKBggqhkjOPQQDAwNoADBlAjB8UhO0TeULDm2k +RAnyzd1aVissw+BCZGvRsoVuH/Z7i9Yb/fu4pejwuECKO0D7eJUCMQDafRL3gT55 +NBb2W+z8WGKS8B2JIO/Gonnx4XXPYXDsOXlYyGKPqh+VOCRNT7KcQ30= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIICWzCCAeGgAwIBAgIBATAKBggqhkjOPQQDAzBEMQswCQYDVQQGEwJVUzEfMB0G +A1UECgwWT3hpZGUgQ29tcHV0ZXIgQ29tcGFueTEUMBIGA1UEAwwLdGVzdC1yb290 +LWEwIBcNMjQwNjEyMTYzMjM3WhgPOTk5OTEyMzEyMzU5NTlaMEcxCzAJBgNVBAYT +AlVTMR8wHQYDVQQKDBZPeGlkZSBDb21wdXRlciBDb21wYW55MRcwFQYDVQQDDA50 +ZXN0LXNpZ25lci1hMTB2MBAGByqGSM49AgEGBSuBBAAiA2IABPvzr9YC1dTt1uax +prUzHywnDNkWITkTfAEyLb39QFMntcflGIMhTIPqGx27kc/HfwC1YyMt9ILHM9tp +BOmrv87r4FU0LFGTtnxusAbOFG9XqVGr/N8U6kbA5dzYDgqo7aOBoTCBnjAdBgNV +HQ4EFgQUCi1ys6RafYnKs4DOu/c/BrvD/1cwHwYDVR0jBBgwFoAUDfZ5RrddDsA4 +LG+WGI9JWuz+rvowDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwOwYD +VR0gAQH/BDEwLzAMBgorBgEEAYPBTwEDMAkGB2eBBQUEZAYwCQYHZ4EFBQRkCDAJ +BgdngQUFBGQMMAoGCCqGSM49BAMDA2gAMGUCMQCrf7KzLwY7vUlW0eYEQQpKfTI3 +NLK9P/KNeLW4/TzTCPOKCqcHVi3hQsVkkZlWOO4CMCB0SzgmFUNMmRv3xBJBhiX6 +Kq9QPbDQqzCIGBFa25n6vPhjtx+6J6nliA75I5RNhw== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIICJDCCAaqgAwIBAgIBBTAKBggqhkjOPQQDAzBHMQswCQYDVQQGEwJVUzEfMB0G +A1UECgwWT3hpZGUgQ29tcHV0ZXIgQ29tcGFueTEXMBUGA1UEAwwOdGVzdC1zaWdu +ZXItYTEwIBcNMjQwNjEyMTYzMjM3WhgPOTk5OTEyMzEyMzU5NTlaMFkxCzAJBgNV +BAYTAlVTMR8wHQYDVQQKDBZPeGlkZSBDb21wdXRlciBDb21wYW55MSkwJwYDVQQD +DCBQRFYyOlBQUC1QUFBQUFBQOlJSUjpTU1NTU1NTU1NTMjAqMAUGAytlcAMhAC6v +VVNb07pjsmCKwVPSF7U0TTJFrnMC9E4PDnHM/7JRo4GhMIGeMB0GA1UdDgQWBBRx +goYgaGVc+T9YqT15DGl3BEMixzAfBgNVHSMEGDAWgBQKLXKzpFp9icqzgM679z8G +u8P/VzAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjA7BgNVHSABAf8E +MTAvMAwGCisGAQQBg8FPAQMwCQYHZ4EFBQRkBjAJBgdngQUFBGQIMAkGB2eBBQUE +ZAwwCgYIKoZIzj0EAwMDaAAwZQIwb520J1OCeaQsqgl2Mn8mmc6HZ4FkvO+7c4EA ++FZPSLKzqz4X6q6XU5iejyaCtsX9AjEAv08JXjmx1fZsamXGD6CCLXpZ62NP7AmI +HVNVrJF9u1ilq6i1IBZLo0hiH9o9pc0Y +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIICFjCCAcigAwIBAgIBBjAFBgMrZXAwWTELMAkGA1UEBhMCVVMxHzAdBgNVBAoM +Fk94aWRlIENvbXB1dGVyIENvbXBhbnkxKTAnBgNVBAMMIFBEVjI6UFBQLVBQUFBQ +UFA6UlJSOlNTU1NTU1NTU1MyMCAXDTI0MDYxMjE2MzIzN1oYDzk5OTkxMjMxMjM1 +OTU5WjBqMQswCQYDVQQGEwJVUzEfMB0GA1UECgwWT3hpZGUgQ29tcHV0ZXIgQ29t +cGFueTE6MDgGA1UEAwwxL0M9VVMvTz1PeGlkZSBDb21wdXRlciBDb21wYW55L0NO +PXRlc3QtZGV2aWNlaWQtMjAqMAUGAytlcAMhAE756gouns/hdjAqi/63hdat3du6 +8oaIKk3IA9+wbZaho4GhMIGeMB0GA1UdDgQWBBSBtoW77Dcr/cJfdX4ENFqnKYcc +iDAfBgNVHSMEGDAWgBRxgoYgaGVc+T9YqT15DGl3BEMixzAPBgNVHRMBAf8EBTAD +AQH/MA4GA1UdDwEB/wQEAwIBBjA7BgNVHSABAf8EMTAvMAwGCisGAQQBg8FPAQMw +CQYHZ4EFBQRkBjAJBgdngQUFBGQIMAkGB2eBBQUEZAwwBQYDK2VwA0EAjM+oIvmZ +o/dLqvHRfNk6pi16L+jvauI5YF1wEU33mtSE0Y6lZe1Fb/Ngd3BjvDSQHOTuqf4Z +50iLHgs3YSAeDg== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIICKjCCAdygAwIBAgIBBzAFBgMrZXAwajELMAkGA1UEBhMCVVMxHzAdBgNVBAoM +Fk94aWRlIENvbXB1dGVyIENvbXBhbnkxOjA4BgNVBAMMMS9DPVVTL089T3hpZGUg +Q29tcHV0ZXIgQ29tcGFueS9DTj10ZXN0LWRldmljZWlkLTIwIBcNMjQwNjEyMTYz +MjM3WhgPOTk5OTEyMzEyMzU5NTlaMHAxCzAJBgNVBAYTAlVTMR8wHQYDVQQKDBZP +eGlkZSBDb21wdXRlciBDb21wYW55MUAwPgYDVQQDDDcvQz1VUy9PPU94aWRlIENv +bXB1dGVyIENvbXBhbnkvQ049dGVzdC1zcHJvY2tldHMtYXV0aC0yMCowBQYDK2Vw +AyEAmVwM+SRtpiGqGYHgHCGN4iGdfZ39ML9WrPIYCtFJLyWjgZ4wgZswHQYDVR0O +BBYEFNgfznrPDccOzgKULsJ7hy99LsuPMB8GA1UdIwQYMBaAFIG2hbvsNyv9wl91 +fgQ0WqcphxyIMAwGA1UdEwEB/wQCMAAwDgYDVR0PAQH/BAQDAgbAMDsGA1UdIAEB +/wQxMC8wDAYKKwYBBAGDwU8BAzAJBgdngQUFBGQGMAkGB2eBBQUEZAgwCQYHZ4EF +BQRkDDAFBgMrZXADQQAo2/htLqYgimB91FhnygEmc2zIFyq63IhKSf/zZVCZBBtX +2w0VqGgy4wQwWQVpfdCj4eaLqrFqgAEsmMrrlIMF +-----END CERTIFICATE----- diff --git a/smf/sled-agent/non-gimlet/sprockets-chain.pem b/smf/sled-agent/non-gimlet/sprockets-chain.pem new file mode 100644 index 0000000000..04a04fd00c --- /dev/null +++ b/smf/sled-agent/non-gimlet/sprockets-chain.pem @@ -0,0 +1,71 @@ +-----BEGIN CERTIFICATE----- +MIICNTCCAbugAwIBAgIBADAKBggqhkjOPQQDAzBEMQswCQYDVQQGEwJVUzEfMB0G +A1UECgwWT3hpZGUgQ29tcHV0ZXIgQ29tcGFueTEUMBIGA1UEAwwLdGVzdC1yb290 +LWEwIBcNMjQwNjEyMTYzMjM3WhgPOTk5OTEyMzEyMzU5NTlaMEQxCzAJBgNVBAYT +AlVTMR8wHQYDVQQKDBZPeGlkZSBDb21wdXRlciBDb21wYW55MRQwEgYDVQQDDAt0 +ZXN0LXJvb3QtYTB2MBAGByqGSM49AgEGBSuBBAAiA2IABMTVjqvxuneT7jaxw6AJ +qqTY3wKithGZt2PUF1TI1AMhnJtfomYjqkQutd+uLhWW5Kq4KXSfZm3OUdZYODZx +n96zENU/iBwq0c0/+FcZEEGQpoSFU5gFfK2/NeMAI3i8c6N/MH0wHQYDVR0OBBYE +FA32eUa3XQ7AOCxvlhiPSVrs/q76MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/ +BAQDAgEGMDsGA1UdIAEB/wQxMC8wDAYKKwYBBAGDwU8BAzAJBgdngQUFBGQGMAkG +B2eBBQUEZAgwCQYHZ4EFBQRkDDAKBggqhkjOPQQDAwNoADBlAjB8UhO0TeULDm2k +RAnyzd1aVissw+BCZGvRsoVuH/Z7i9Yb/fu4pejwuECKO0D7eJUCMQDafRL3gT55 +NBb2W+z8WGKS8B2JIO/Gonnx4XXPYXDsOXlYyGKPqh+VOCRNT7KcQ30= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIICWzCCAeGgAwIBAgIBATAKBggqhkjOPQQDAzBEMQswCQYDVQQGEwJVUzEfMB0G +A1UECgwWT3hpZGUgQ29tcHV0ZXIgQ29tcGFueTEUMBIGA1UEAwwLdGVzdC1yb290 +LWEwIBcNMjQwNjEyMTYzMjM3WhgPOTk5OTEyMzEyMzU5NTlaMEcxCzAJBgNVBAYT +AlVTMR8wHQYDVQQKDBZPeGlkZSBDb21wdXRlciBDb21wYW55MRcwFQYDVQQDDA50 +ZXN0LXNpZ25lci1hMTB2MBAGByqGSM49AgEGBSuBBAAiA2IABPvzr9YC1dTt1uax +prUzHywnDNkWITkTfAEyLb39QFMntcflGIMhTIPqGx27kc/HfwC1YyMt9ILHM9tp +BOmrv87r4FU0LFGTtnxusAbOFG9XqVGr/N8U6kbA5dzYDgqo7aOBoTCBnjAdBgNV +HQ4EFgQUCi1ys6RafYnKs4DOu/c/BrvD/1cwHwYDVR0jBBgwFoAUDfZ5RrddDsA4 +LG+WGI9JWuz+rvowDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwOwYD +VR0gAQH/BDEwLzAMBgorBgEEAYPBTwEDMAkGB2eBBQUEZAYwCQYHZ4EFBQRkCDAJ +BgdngQUFBGQMMAoGCCqGSM49BAMDA2gAMGUCMQCrf7KzLwY7vUlW0eYEQQpKfTI3 +NLK9P/KNeLW4/TzTCPOKCqcHVi3hQsVkkZlWOO4CMCB0SzgmFUNMmRv3xBJBhiX6 +Kq9QPbDQqzCIGBFa25n6vPhjtx+6J6nliA75I5RNhw== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIICJDCCAaqgAwIBAgIBAjAKBggqhkjOPQQDAzBHMQswCQYDVQQGEwJVUzEfMB0G +A1UECgwWT3hpZGUgQ29tcHV0ZXIgQ29tcGFueTEXMBUGA1UEAwwOdGVzdC1zaWdu +ZXItYTEwIBcNMjQwNjEyMTYzMjM3WhgPOTk5OTEyMzEyMzU5NTlaMFkxCzAJBgNV +BAYTAlVTMR8wHQYDVQQKDBZPeGlkZSBDb21wdXRlciBDb21wYW55MSkwJwYDVQQD +DCBQRFYyOlBQUC1QUFBQUFBQOlJSUjpTU1NTU1NTU1NTMTAqMAUGAytlcAMhAEKj +CmIAH2mJrc1ZWRoJ57hMc7Z/iqr7fjP0K4afAGvvo4GhMIGeMB0GA1UdDgQWBBQK +Ma9hbXEgoKx7esWcn2hOVUcV8zAfBgNVHSMEGDAWgBQKLXKzpFp9icqzgM679z8G +u8P/VzAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjA7BgNVHSABAf8E +MTAvMAwGCisGAQQBg8FPAQMwCQYHZ4EFBQRkBjAJBgdngQUFBGQIMAkGB2eBBQUE +ZAwwCgYIKoZIzj0EAwMDaAAwZQIwVCZWAzRlrBUUTEB7KP6AqTEeSt90NEFl3RK0 +dV4mEcu4Hv4G3jYChc8BFc83vxyNAjEAt62G/x2jdVf8SQH8cPcIy6G3dfdqrGju +LoPtsRXrW8c/9zOSSO5l2L9vPX/xiIJJ +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIICFjCCAcigAwIBAgIBAzAFBgMrZXAwWTELMAkGA1UEBhMCVVMxHzAdBgNVBAoM +Fk94aWRlIENvbXB1dGVyIENvbXBhbnkxKTAnBgNVBAMMIFBEVjI6UFBQLVBQUFBQ +UFA6UlJSOlNTU1NTU1NTU1MxMCAXDTI0MDYxMjE2MzIzN1oYDzk5OTkxMjMxMjM1 +OTU5WjBqMQswCQYDVQQGEwJVUzEfMB0GA1UECgwWT3hpZGUgQ29tcHV0ZXIgQ29t +cGFueTE6MDgGA1UEAwwxL0M9VVMvTz1PeGlkZSBDb21wdXRlciBDb21wYW55L0NO +PXRlc3QtZGV2aWNlaWQtMTAqMAUGAytlcAMhAM2dFyuZTc+8Jw7QghR/AzeXBsf/ +ZbSKT7qmD8gPWi2Io4GhMIGeMB0GA1UdDgQWBBQYuL8mjvsFqItN35+vpMthvAO1 +wjAfBgNVHSMEGDAWgBQKMa9hbXEgoKx7esWcn2hOVUcV8zAPBgNVHRMBAf8EBTAD +AQH/MA4GA1UdDwEB/wQEAwIBBjA7BgNVHSABAf8EMTAvMAwGCisGAQQBg8FPAQMw +CQYHZ4EFBQRkBjAJBgdngQUFBGQIMAkGB2eBBQUEZAwwBQYDK2VwA0EA8PWIkypd +mZ0Zh3fx3GLEUbVrF0ZyX+1LJeGWR3OChazCz3SLcfncQeOG8OZjURq5Rby3Phar +GfajBESau9KoCA== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIICKjCCAdygAwIBAgIBBDAFBgMrZXAwajELMAkGA1UEBhMCVVMxHzAdBgNVBAoM +Fk94aWRlIENvbXB1dGVyIENvbXBhbnkxOjA4BgNVBAMMMS9DPVVTL089T3hpZGUg +Q29tcHV0ZXIgQ29tcGFueS9DTj10ZXN0LWRldmljZWlkLTEwIBcNMjQwNjEyMTYz +MjM3WhgPOTk5OTEyMzEyMzU5NTlaMHAxCzAJBgNVBAYTAlVTMR8wHQYDVQQKDBZP +eGlkZSBDb21wdXRlciBDb21wYW55MUAwPgYDVQQDDDcvQz1VUy9PPU94aWRlIENv +bXB1dGVyIENvbXBhbnkvQ049dGVzdC1zcHJvY2tldHMtYXV0aC0xMCowBQYDK2Vw +AyEA3YfArFPuOHDoQj3aO5VSyuOIPfbAuEpB93dnYnZlM2WjgZ4wgZswHQYDVR0O +BBYEFM9T7TDOVi/SVlkO5mayCNQ5uHDiMB8GA1UdIwQYMBaAFBi4vyaO+wWoi03f +n6+ky2G8A7XCMAwGA1UdEwEB/wQCMAAwDgYDVR0PAQH/BAQDAgbAMDsGA1UdIAEB +/wQxMC8wDAYKKwYBBAGDwU8BAzAJBgdngQUFBGQGMAkGB2eBBQUEZAgwCQYHZ4EF +BQRkDDAFBgMrZXADQQC4Zz6tZabSnDVf3dnEIdpnknsVCCncKm0dna1sf0BOrd7p +cXNwDx3GINm0jXaLg/N5srh5z/v+TLj8vXwr/uEP +-----END CERTIFICATE----- diff --git a/tools/install_runner_prerequisites.sh b/tools/install_runner_prerequisites.sh index a53d339b69..120cbc3db8 100755 --- a/tools/install_runner_prerequisites.sh +++ b/tools/install_runner_prerequisites.sh @@ -115,6 +115,7 @@ function install_packages { 'brand/omicron1/tools' 'library/libxmlsec1' 'chrony' + 'oxide/platform-identity-cacerts' # necessary for sprockets ) # Install/update the set of packages. diff --git a/workspace-hack/Cargo.toml b/workspace-hack/Cargo.toml index 4580173e48..0bd19259cf 100644 --- a/workspace-hack/Cargo.toml +++ b/workspace-hack/Cargo.toml @@ -35,12 +35,13 @@ cipher = { version = "0.4.4", default-features = false, features = ["block-paddi clap = { version = "4.5.16", features = ["cargo", "derive", "env", "wrap_help"] } clap_builder = { version = "4.5.15", default-features = false, features = ["cargo", "color", "env", "std", "suggestions", "usage", "wrap_help"] } console = { version = "0.15.8" } -const-oid = { version = "0.9.6", default-features = false, features = ["db", "std"] } crossbeam-epoch = { version = "0.9.18" } crossbeam-utils = { version = "0.8.19" } crypto-common = { version = "0.1.6", default-features = false, features = ["getrandom", "std"] } -der = { version = "0.7.9", default-features = false, features = ["derive", "flagset", "oid", "pem", "std"] } +curve25519-dalek = { version = "4.1.3", features = ["digest", "legacy_compatibility", "rand_core"] } digest = { version = "0.10.7", features = ["mac", "oid", "std"] } +ecdsa = { version = "0.16.9", features = ["pem", "signing", "std", "verifying"] } +ed25519-dalek = { version = "2.1.1", features = ["digest", "pkcs8", "rand_core"] } either = { version = "1.13.0" } elliptic-curve = { version = "0.13.8", features = ["ecdh", "hazmat", "pem", "std"] } ff = { version = "0.13.0", default-features = false, features = ["alloc"] } @@ -63,7 +64,7 @@ hickory-proto = { version = "0.24.1", features = ["text-parsing"] } hmac = { version = "0.12.1", default-features = false, features = ["reset"] } hyper-582f2526e08bb6a0 = { package = "hyper", version = "0.14.30", features = ["full"] } hyper-dff4ba8e3ae991db = { package = "hyper", version = "1.4.1", features = ["client", "http1", "http2", "server"] } -hyper-util = { version = "0.1.3", features = ["client-legacy", "server-auto", "tokio"] } +hyper-util = { version = "0.1.7", features = ["client-legacy", "server-auto"] } indexmap = { version = "2.4.0", features = ["serde"] } inout = { version = "0.1.3", default-features = false, features = ["std"] } itertools-5ef9efb8ec2df382 = { package = "itertools", version = "0.12.1" } @@ -104,6 +105,7 @@ sha2 = { version = "0.10.8", features = ["oid"] } similar = { version = "2.6.0", features = ["bytes", "inline", "unicode"] } slog = { version = "2.7.0", features = ["dynamic-keys", "max_level_trace", "release_max_level_debug", "release_max_level_trace"] } smallvec = { version = "1.13.2", default-features = false, features = ["const_new"] } +socket2 = { version = "0.5.7", default-features = false, features = ["all"] } spin = { version = "0.9.8" } string_cache = { version = "0.8.7" } subtle = { version = "2.5.0" } @@ -122,8 +124,9 @@ unicode-normalization = { version = "0.1.23" } usdt = { version = "0.5.0" } usdt-impl = { version = "0.5.0", default-features = false, features = ["asm", "des"] } uuid = { version = "1.10.0", features = ["serde", "v4"] } +x509-cert = { version = "0.2.5" } zerocopy = { version = "0.7.34", features = ["derive", "simd"] } -zeroize = { version = "1.7.0", features = ["std", "zeroize_derive"] } +zeroize = { version = "1.8.1", features = ["std", "zeroize_derive"] } [build-dependencies] ahash = { version = "0.8.11" } @@ -145,12 +148,13 @@ cipher = { version = "0.4.4", default-features = false, features = ["block-paddi clap = { version = "4.5.16", features = ["cargo", "derive", "env", "wrap_help"] } clap_builder = { version = "4.5.15", default-features = false, features = ["cargo", "color", "env", "std", "suggestions", "usage", "wrap_help"] } console = { version = "0.15.8" } -const-oid = { version = "0.9.6", default-features = false, features = ["db", "std"] } crossbeam-epoch = { version = "0.9.18" } crossbeam-utils = { version = "0.8.19" } crypto-common = { version = "0.1.6", default-features = false, features = ["getrandom", "std"] } -der = { version = "0.7.9", default-features = false, features = ["derive", "flagset", "oid", "pem", "std"] } +curve25519-dalek = { version = "4.1.3", features = ["digest", "legacy_compatibility", "rand_core"] } digest = { version = "0.10.7", features = ["mac", "oid", "std"] } +ecdsa = { version = "0.16.9", features = ["pem", "signing", "std", "verifying"] } +ed25519-dalek = { version = "2.1.1", features = ["digest", "pkcs8", "rand_core"] } either = { version = "1.13.0" } elliptic-curve = { version = "0.13.8", features = ["ecdh", "hazmat", "pem", "std"] } ff = { version = "0.13.0", default-features = false, features = ["alloc"] } @@ -173,7 +177,7 @@ hickory-proto = { version = "0.24.1", features = ["text-parsing"] } hmac = { version = "0.12.1", default-features = false, features = ["reset"] } hyper-582f2526e08bb6a0 = { package = "hyper", version = "0.14.30", features = ["full"] } hyper-dff4ba8e3ae991db = { package = "hyper", version = "1.4.1", features = ["client", "http1", "http2", "server"] } -hyper-util = { version = "0.1.3", features = ["client-legacy", "server-auto", "tokio"] } +hyper-util = { version = "0.1.7", features = ["client-legacy", "server-auto"] } indexmap = { version = "2.4.0", features = ["serde"] } inout = { version = "0.1.3", default-features = false, features = ["std"] } itertools-5ef9efb8ec2df382 = { package = "itertools", version = "0.12.1" } @@ -214,6 +218,7 @@ sha2 = { version = "0.10.8", features = ["oid"] } similar = { version = "2.6.0", features = ["bytes", "inline", "unicode"] } slog = { version = "2.7.0", features = ["dynamic-keys", "max_level_trace", "release_max_level_debug", "release_max_level_trace"] } smallvec = { version = "1.13.2", default-features = false, features = ["const_new"] } +socket2 = { version = "0.5.7", default-features = false, features = ["all"] } spin = { version = "0.9.8" } string_cache = { version = "0.8.7" } subtle = { version = "2.5.0" } @@ -235,8 +240,9 @@ unicode-xid = { version = "0.2.4" } usdt = { version = "0.5.0" } usdt-impl = { version = "0.5.0", default-features = false, features = ["asm", "des"] } uuid = { version = "1.10.0", features = ["serde", "v4"] } +x509-cert = { version = "0.2.5" } zerocopy = { version = "0.7.34", features = ["derive", "simd"] } -zeroize = { version = "1.7.0", features = ["std", "zeroize_derive"] } +zeroize = { version = "1.8.1", features = ["std", "zeroize_derive"] } [target.x86_64-unknown-linux-gnu.dependencies] dof = { version = "0.3.0", default-features = false, features = ["des"] }