Skip to content
Merged
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
385 changes: 233 additions & 152 deletions Cargo.lock

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -724,7 +724,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 = "6d31fa63217c6a51061dc4afa1ebe175a0021981" }
sprockets-tls = { git = "https://github.com/oxidecomputer/sprockets.git", rev = "7da1f0b5dcd3d631da18b43ba78a84b1a2b425ee" }
sqlformat = "0.3.5"
sqlparser = { version = "0.45.0", features = [ "visitor" ] }
static_assertions = "1.1.0"
Expand Down
43 changes: 26 additions & 17 deletions sled-agent/src/bootstrap/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ use crate::bootstrap::views::Response;
use crate::bootstrap::views::ResponseEnvelope;
use sled_agent_types::sled::StartSledAgentRequest;
use slog::Logger;
use slog_error_chain::SlogInlineError;
use sprockets_tls::client::Client as SprocketsClient;
use sprockets_tls::keys::SprocketsConfig;
use std::borrow::Cow;
Expand All @@ -21,34 +22,38 @@ use thiserror::Error;
use tokio::io::AsyncReadExt;
use tokio::io::AsyncWriteExt;

#[derive(Debug, Error)]
#[derive(Debug, Error, SlogInlineError)]
pub enum Error {
#[error("Could not connect to {addr}: {err}")]
Connect { addr: SocketAddrV6, err: sprockets_tls::Error },
#[error("Could not connect to {addr}")]
Connect {
addr: SocketAddrV6,
#[source]
err: sprockets_tls::Error,
},

#[error("Failed serializing request: {0}")]
Serialize(serde_json::Error),
#[error("Failed serializing request")]
Serialize(#[source] serde_json::Error),

#[error("Failed writing request length prefix: {0}")]
WriteLengthPrefix(io::Error),
#[error("Failed writing request length prefix")]
WriteLengthPrefix(#[source] io::Error),

#[error("Failed writing request: {0}")]
WriteRequest(io::Error),
#[error("Failed writing request")]
WriteRequest(#[source] io::Error),

#[error("Failed flushing request: {0}")]
FlushRequest(io::Error),
#[error("Failed flushing request")]
FlushRequest(#[source] io::Error),

#[error("Failed reading response length prefix: {0}")]
ReadLengthPrefix(io::Error),
#[error("Failed reading response length prefix")]
ReadLengthPrefix(#[source] io::Error),

#[error("Received bogus response length: {0}")]
BadResponseLength(u32),

#[error("Failed reading response: {0}")]
ReadResponse(io::Error),
#[error("Failed reading response")]
ReadResponse(#[source] io::Error),

#[error("Failed deserializing response: {0}")]
Deserialize(serde_json::Error),
#[error("Failed deserializing response")]
Deserialize(#[source] serde_json::Error),

#[error("Unsupported version: {0}")]
UnsupportedVersion(u32),
Expand Down Expand Up @@ -111,9 +116,13 @@ impl Client {
let log = self.log.new(o!("component" => "SledAgentSprocketsClient"));
// Establish connection and sprockets connection (if possible).
// The sprockets client loads the associated root certificates at this point.
//
// TODO: Use a real corpus
let corpus = vec![];
let stream = SprocketsClient::connect(
self.sprockets_conf.clone(),
self.addr,
corpus,
log.clone(),
)
.await
Expand Down
25 changes: 18 additions & 7 deletions sled-agent/src/bootstrap/sprockets_server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,22 +59,33 @@ impl SprocketsServer {
/// 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(mut self) {
pub(super) async fn run(self) {
loop {
// Sprockets actually _uses_ the key here!
let (stream, remote_addr) = match self.listener.accept().await {
Ok(conn) => conn,
// TODO: Once we have a corpus, use it.
// Will we ever have one at RSS time?
Comment on lines +65 to +66
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe we should because the expectation is that sleds have gotten a mupdate but we should review this

let corpus = vec![];
let acceptor = match self.listener.accept(corpus).await {
Ok(acceptor) => acceptor,
Err(err) => {
error!(self.log, "accept() failed"; "err" => #%err);
error!(self.log, "accept() failed"; &err);
continue;
}
};

let log = self.log.new(o!("remote_addr" => remote_addr));
info!(log, "Accepted connection");

let log = self.log.new(o!("remote_addr" => acceptor.addr()));
info!(log, "TCP connection accepted");
let tx_requests = self.tx_requests.clone();
tokio::spawn(async move {
let stream = match acceptor.handshake().await {
Ok((stream, _)) => stream,
Err(err) => {
error!(log, "Sprockets handshake failed"; &err);
return;
}
};
info!(log, "Sprockets handshake completed");

match handle_start_sled_agent_request(stream, tx_requests, &log)
.await
{
Expand Down
5 changes: 3 additions & 2 deletions sled-agent/src/sled_agent.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ use sled_hardware::{HardwareManager, MemoryReservations, underlay};
use sled_hardware_types::Baseboard;
use sled_hardware_types::underlay::BootstrapInterface;
use slog::Logger;
use slog_error_chain::InlineErrorChain;
use slog_error_chain::{InlineErrorChain, SlogInlineError};
use sprockets_tls::keys::SprocketsConfig;
use std::collections::BTreeMap;
use std::net::{Ipv6Addr, SocketAddrV6};
Expand Down Expand Up @@ -1187,7 +1187,7 @@ impl SledAgent {
}
}

#[derive(From, thiserror::Error, Debug)]
#[derive(From, thiserror::Error, Debug, SlogInlineError)]
pub enum AddSledError {
#[error("Failed to learn bootstrap ip for {sled_id}")]
BootstrapAgentClient {
Expand All @@ -1202,6 +1202,7 @@ pub enum AddSledError {
#[error("Failed to initialize {sled_id}: {err}")]
BootstrapTcpClient {
sled_id: Baseboard,
#[source]
err: crate::bootstrap::client::Error,
},
}
Expand Down
1 change: 1 addition & 0 deletions smf/sled-agent/gimlet-standalone/config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -76,4 +76,5 @@ if_exists = "append"

[sprockets]
resolve = { which = "ipcc" }
attest = { which = "ipcc" }
roots = ["/usr/share/oxide/idcerts/staging.pem", "/usr/share/oxide/idcerts/production.pem"]
1 change: 1 addition & 0 deletions smf/sled-agent/gimlet/config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -72,4 +72,5 @@ if_exists = "append"

[sprockets]
resolve = { which = "ipcc" }
attest = { which = "ipcc" }
roots = ["/usr/share/oxide/idcerts/staging.pem", "/usr/share/oxide/idcerts/production.pem"]
151 changes: 107 additions & 44 deletions smf/sled-agent/non-gimlet/config.kdl
Original file line number Diff line number Diff line change
Expand Up @@ -77,46 +77,6 @@ certificate "test-signer-a1" {
}
}

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
Expand Down Expand Up @@ -166,7 +126,7 @@ key-pair "test-deviceid-1" {
entity "test-deviceid-1" {
country-name "US"
organization-name "Oxide Computer Company"
common-name "/C=US/O=Oxide Computer Company/CN=test-deviceid-1"
common-name "test-deviceid-1"
}

certificate "test-deviceid-1" {
Expand Down Expand Up @@ -207,7 +167,7 @@ key-pair "test-sprockets-auth-1" {
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"
common-name "test-sprockets-auth-1"
}

certificate "test-sprockets-auth-1" {
Expand Down Expand Up @@ -241,6 +201,58 @@ certificate "test-sprockets-auth-1" {
}
}

// TODO: sprockets reverses this cert chain before passing it to rustls
certificate-list "test-sprockets-auth-1" \
"test-signer-a1" \
"test-platformid-1" \
"test-deviceid-1" \
"test-sprockets-auth-1"

key-pair "test-alias-1" {
ed25519
}

entity "test-alias-1" {
country-name "US"
organization-name "Oxide Computer Company"
common-name "alias"
}

certificate "test-alias-1" {
issuer-certificate "test-deviceid-1"
issuer-key "test-deviceid-1"

subject-entity "test-alias-1"
subject-key "test-alias-1"

not-after "9999-12-31T23:59:59Z"
serial-number "00"

extensions {
basic-constraints critical=true ca=false
key-usage critical=true {
digital-signature
}
certificate-policies critical=true {
tcg-dice-kp-attest-init
}
dice-tcb-info critical=true {
fwid-list {
fwid {
digest-algorithm "sha3-256"
digest "72fa8f8ea84a42251031366002cbb36281d0131f78cd680436116a720cdd9de5"
}
}
}
}
}

certificate-list "test-alias-1" \
"test-alias-1" \
"test-deviceid-1" \
"test-platformid-1" \
"test-signer-a1"

/// Device 2

key-pair "test-platformid-2" {
Expand Down Expand Up @@ -291,7 +303,7 @@ key-pair "test-deviceid-2" {
entity "test-deviceid-2" {
country-name "US"
organization-name "Oxide Computer Company"
common-name "/C=US/O=Oxide Computer Company/CN=test-deviceid-2"
common-name "test-deviceid-2"
}

certificate "test-deviceid-2" {
Expand Down Expand Up @@ -332,7 +344,7 @@ key-pair "test-sprockets-auth-2" {
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"
common-name "test-sprockets-auth-2"
}

certificate "test-sprockets-auth-2" {
Expand Down Expand Up @@ -366,3 +378,54 @@ certificate "test-sprockets-auth-2" {
}
}

// TODO: sprockets reverses this cert chain before passing it to rustls
certificate-list "test-sprockets-auth-2" \
"test-signer-a1" \
"test-platformid-2" \
"test-deviceid-2" \
"test-sprockets-auth-2"

key-pair "test-alias-2" {
ed25519
}

entity "test-alias-2" {
country-name "US"
organization-name "Oxide Computer Company"
common-name "alias"
}

certificate "test-alias-2" {
issuer-certificate "test-deviceid-2"
issuer-key "test-deviceid-2"

subject-entity "test-alias-2"
subject-key "test-alias-2"

not-after "9999-12-31T23:59:59Z"
serial-number "00"

extensions {
basic-constraints critical=true ca=false
key-usage critical=true {
digital-signature
}
certificate-policies critical=true {
tcg-dice-kp-attest-init
}
dice-tcb-info critical=true {
fwid-list {
fwid {
digest-algorithm "sha3-256"
digest "72fa8f8ea84a42251031366002cbb36281d0131f78cd680436116a720cdd9de5"
}
}
}
}
}

certificate-list "test-alias-2" \
"test-alias-2" \
"test-deviceid-2" \
"test-platformid-2" \
"test-signer-a1"
1 change: 1 addition & 0 deletions smf/sled-agent/non-gimlet/config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -121,4 +121,5 @@ if_exists = "append"
# 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" }
attest = { which = "local", priv_key = "/opt/oxide/sled-agent/pkg/sprockets-attest.key.pem", cert_chain = "/opt/oxide/sled-agent/pkg/sprockets-attest-chain.pem", log = "/opt/oxide/sled-agent/pkg/sprockets-log.bin" }
roots = ["/opt/oxide/sled-agent/pkg/root.cert.pem"]
18 changes: 9 additions & 9 deletions smf/sled-agent/non-gimlet/root.cert.pem
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
-----BEGIN CERTIFICATE-----
MIICNTCCAbugAwIBAgIBADAKBggqhkjOPQQDAzBEMQswCQYDVQQGEwJVUzEfMB0G
MIICNjCCAbugAwIBAgIBADAKBggqhkjOPQQDAzBEMQswCQYDVQQGEwJVUzEfMB0G
A1UECgwWT3hpZGUgQ29tcHV0ZXIgQ29tcGFueTEUMBIGA1UEAwwLdGVzdC1yb290
LWEwIBcNMjQwNjEyMTYzMjM3WhgPOTk5OTEyMzEyMzU5NTlaMEQxCzAJBgNVBAYT
LWEwIBcNMjUwNzE3MjM1MjAyWhgPOTk5OTEyMzEyMzU5NTlaMEQxCzAJBgNVBAYT
AlVTMR8wHQYDVQQKDBZPeGlkZSBDb21wdXRlciBDb21wYW55MRQwEgYDVQQDDAt0
ZXN0LXJvb3QtYTB2MBAGByqGSM49AgEGBSuBBAAiA2IABMTVjqvxuneT7jaxw6AJ
qqTY3wKithGZt2PUF1TI1AMhnJtfomYjqkQutd+uLhWW5Kq4KXSfZm3OUdZYODZx
n96zENU/iBwq0c0/+FcZEEGQpoSFU5gFfK2/NeMAI3i8c6N/MH0wHQYDVR0OBBYE
FA32eUa3XQ7AOCxvlhiPSVrs/q76MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/
ZXN0LXJvb3QtYTB2MBAGByqGSM49AgEGBSuBBAAiA2IABFsoJvbvOh6jULakcq5J
syiG+X7hmTiDVFw5wbRp5x+hM0OV1URU6gF1fvHMnx3TS6r2VhUcRn6jvje958Kf
FoQW02GTwuMw2zXzXl4X/LTQWjpIqmr0/YBeLEzIRUTiiKN/MH0wHQYDVR0OBBYE
FK4mUY+okoRWTHZvwbpMqqYj1zQxMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/
BAQDAgEGMDsGA1UdIAEB/wQxMC8wDAYKKwYBBAGDwU8BAzAJBgdngQUFBGQGMAkG
B2eBBQUEZAgwCQYHZ4EFBQRkDDAKBggqhkjOPQQDAwNoADBlAjB8UhO0TeULDm2k
RAnyzd1aVissw+BCZGvRsoVuH/Z7i9Yb/fu4pejwuECKO0D7eJUCMQDafRL3gT55
NBb2W+z8WGKS8B2JIO/Gonnx4XXPYXDsOXlYyGKPqh+VOCRNT7KcQ30=
B2eBBQUEZAgwCQYHZ4EFBQRkDDAKBggqhkjOPQQDAwNpADBmAjEAhDlimZx4MQoR
TtLN1P1sQimopsxXOYgF3a2MkTHIxKuPAwG8KOYUbN/pQ8z2sljUAjEAtjH7Fp1a
IlVT6bbRJX1wXkF6Z13VWcgjGJ7q6GSfw6Ef5/SthSGRJ59EU0WNXrRy
-----END CERTIFICATE-----
Loading
Loading