Skip to content

Commit

Permalink
feat: use real RA-TLS for everything
Browse files Browse the repository at this point in the history
* add `tee-ratls-preexec` for creating the vault certificate
* remove the old attestation API

Signed-off-by: Harald Hoyer <[email protected]>
  • Loading branch information
haraldh committed Feb 27, 2024
1 parent 020159b commit 8a6aaa2
Show file tree
Hide file tree
Showing 24 changed files with 835 additions and 1,132 deletions.
402 changes: 221 additions & 181 deletions Cargo.lock

Large diffs are not rendered by default.

11 changes: 8 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ hex.workspace = true
intel-tee-quote-verification-rs.workspace = true
num-integer.workspace = true
num-traits.workspace = true
p256.workspace = true
pgp.workspace = true
pkcs8.workspace = true
rand.workspace = true
Expand All @@ -38,8 +39,10 @@ serde.workspace = true
serde_json.workspace = true
serde_with.workspace = true
sha2.workspace = true
signature.workspace = true
thiserror.workspace = true
tracing.workspace = true
webpki-roots.workspace = true
x509-cert.workspace = true
zeroize.workspace = true

Expand Down Expand Up @@ -86,17 +89,19 @@ mio = "0.8.10"
num-integer = "0.1.46"
num-traits = "0.2.18"
pgp = "0.11"
p256 = "0.13.2"
pkcs8 = { version = "0.10" }
rand = "0.8"
ring = { version = "0.17.8", features = ["std"], default-features = false }
rsa = { version = "0.9.6", features = ["sha2"] }
rsa = { version = "0.9.6", features = ["sha2", "pem"] }
rustls = { version = "0.22" }
rustls-pemfile = "2"
sec1 = { version = "0.7.3", features = ["der"], default-features = false }
serde = { version = "1", features = ["derive", "rc"] }
serde_json = "1"
serde_with = { version = "3.6", features = ["base64", "hex"] }
sha2 = "0.10.8"
signature = "2.2.0"
teepot = { path = "." }
testaso = "0.1.0"
thiserror = "1.0.57"
Expand All @@ -105,6 +110,6 @@ tracing = "0.1"
tracing-actix-web = "0.7"
tracing-log = "0.2"
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
x509 = { version = "0.2", package = "x509-cert", default-features = false }
x509-cert = "0.2.5"
x509-cert = { version = "0.2", features = ["builder", "signature"] }
zeroize = { version = "1.7.0", features = ["serde"] }
webpki-roots = "0.26.1"
21 changes: 21 additions & 0 deletions bin/tee-ratls-preexec/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
[package]
name = "tee-ratls-preexec"
version.workspace = true
edition.workspace = true
authors.workspace = true
license.workspace = true
repository.workspace = true

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
anyhow.workspace = true
clap.workspace = true
rsa.workspace = true
rustls-pemfile.workspace = true
rustls.workspace = true
teepot.workspace = true
tracing-log.workspace = true
tracing-subscriber.workspace = true
tracing.workspace = true
x509-cert.workspace = true
104 changes: 104 additions & 0 deletions bin/tee-ratls-preexec/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright (c) 2024 Matter Labs

//! Pre-exec for binary running in a TEE needing attestation of a secret signing key
#![deny(missing_docs)]
#![deny(clippy::all)]

use anyhow::{Context, Result};
use clap::Parser;
use rsa::pkcs1v15::SigningKey;
use rsa::pkcs8::DecodePrivateKey;
use rsa::sha2::Sha256;
use rsa::RsaPrivateKey;
use std::fs::File;
use std::io::Write;
use std::os::unix::process::CommandExt;
use std::path::PathBuf;
use std::process::Command;
use teepot::server::pki::make_signed_cert;
use tracing::error;
use tracing_log::LogTracer;
use tracing_subscriber::{fmt, prelude::*, EnvFilter, Registry};
use x509_cert::der::asn1::Ia5String;
use x509_cert::der::DecodePem;
use x509_cert::ext::pkix::name::GeneralName;
use x509_cert::Certificate;

#[derive(Parser, Debug)]
#[command(author, version, about, long_about = None)]
struct Args {
/// ca cert file
#[arg(long, env = "CA_CERT_FILE", default_value = "/opt/vault/cacert.pem")]
ca_cert_file: PathBuf,
/// ca key file
#[arg(long, env = "CA_KEY_FILE", default_value = "/opt/vault/cakey.pem")]
ca_key_file: PathBuf,
/// out cert file
#[arg(long, env = "TLS_CERT_FILE", default_value = "/opt/vault/tls/tls.crt")]
tls_cert_file: PathBuf,
/// out key file
#[arg(long, env = "TLS_KEY_FILE", default_value = "/opt/vault/tls/tls.key")]
tls_key_file: PathBuf,
/// DNS names, comma separated
#[arg(long, env = "DNS_NAMES", required = true)]
dns_names: String,
/// program to exec [args...] (required)
#[arg(required = true, allow_hyphen_values = true, last = true)]
cmd_args: Vec<String>,
}

fn main_with_error() -> Result<()> {
LogTracer::init().context("Failed to set logger")?;

let subscriber = Registry::default()
.with(EnvFilter::from_default_env())
.with(fmt::layer().with_writer(std::io::stderr));
tracing::subscriber::set_global_default(subscriber).context("Failed to set logger")?;

let args = Args::parse();

// read `issuer_cert_bytes` from file
let ca_cert = std::fs::read(args.ca_cert_file).context("Failed to read ca_cert")?;

let issuer_cert = Certificate::from_pem(&ca_cert)?;
let issuer_key =
RsaPrivateKey::read_pkcs8_pem_file(args.ca_key_file).context("Failed to read ca_key")?;
let issuer_key_pair = SigningKey::<Sha256>::new(issuer_key);

// TODO: read values from config file or env or args
let dn = "O=system:nodes,CN=system:node";
let mut an = vec![std::net::IpAddr::from(std::net::Ipv4Addr::LOCALHOST).into()];
an.extend(
args.dns_names
.split(',')
.map(|s| GeneralName::DnsName(Ia5String::try_from(s.to_string()).unwrap())),
);

let (_report_data, cert, priv_key) =
make_signed_cert(dn, Some(an), &issuer_cert, &issuer_key_pair)?;

// open args.tls_cert_file and write cert and ca_cert
let mut file = File::create(&args.tls_cert_file).context("Failed to create tls_cert")?;
file.write_all(cert.as_bytes())
.context("Failed to write tls_cert")?;
file.write_all(&ca_cert)
.context("Failed to write tls_cert")?;

std::fs::write(args.tls_key_file, priv_key).context("Failed to write tls_cert")?;

let err = Command::new(&args.cmd_args[0])
.args(&args.cmd_args[1..])
.exec();

Err(err).with_context(|| format!("exec of `{cmd}` failed", cmd = args.cmd_args.join(" ")))
}

fn main() -> Result<()> {
let ret = main_with_error();
if let Err(e) = &ret {
error!("Error: {}", e);
}
ret
}
3 changes: 2 additions & 1 deletion bin/tee-stress-client/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright (c) 2024 Matter Labs

//! Server to handle requests to the Vault TEE
Expand Down Expand Up @@ -45,7 +46,7 @@ async fn main() -> Result<()> {

let args = Arguments::parse();

let (report_data, _cert_chain, _priv_key) = make_self_signed_cert()?;
let (report_data, _cert_chain, _priv_key) = make_self_signed_cert("CN=localhost", None)?;
if let Err(e) = get_quote_and_collateral(Some(args.my_sgx_allowed_tcb_levels), &report_data) {
error!("failed to get quote and collateral: {e:?}");
// don't return for now, we can still serve requests but we won't be able to attest
Expand Down
85 changes: 0 additions & 85 deletions bin/tee-vault-admin/Dockerfile-azure

This file was deleted.

25 changes: 0 additions & 25 deletions bin/tee-vault-admin/src/attestation.rs

This file was deleted.

10 changes: 3 additions & 7 deletions bin/tee-vault-admin/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,28 +1,25 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright (c) 2023 Matter Labs
// Copyright (c) 2023-2024 Matter Labs

//! Server to handle requests to the Vault TEE
#![deny(missing_docs)]
#![deny(clippy::all)]

mod attestation;
mod command;
mod digest;
mod sign;

use actix_web::web::Data;
use actix_web::{web, App, HttpServer};
use anyhow::{Context, Result};
use attestation::get_attestation;
use clap::Parser;
use command::post_command;
use digest::get_digest;
use rustls::ServerConfig;
use sign::post_sign;
use std::net::Ipv6Addr;
use std::sync::Arc;
use teepot::json::http::{SignRequest, VaultCommandRequest, ATTESTATION_URL, DIGEST_URL};
use teepot::json::http::{SignRequest, VaultCommandRequest, DIGEST_URL};
use teepot::server::attestation::{get_quote_and_collateral, VaultAttestationArgs};
use teepot::server::new_json_cfg;
use teepot::server::pki::make_self_signed_cert;
Expand Down Expand Up @@ -65,7 +62,7 @@ async fn main() -> Result<()> {

let args = Arguments::parse();

let (report_data, cert_chain, priv_key) = make_self_signed_cert()?;
let (report_data, cert_chain, priv_key) = make_self_signed_cert("CN=localhost", None)?;

if let Err(e) = get_quote_and_collateral(Some(args.server_sgx_allowed_tcb_levels), &report_data)
{
Expand Down Expand Up @@ -94,7 +91,6 @@ async fn main() -> Result<()> {
.wrap(TracingLogger::default())
.app_data(new_json_cfg())
.app_data(Data::new(server_state.clone()))
.service(web::resource(ATTESTATION_URL).route(web::get().to(get_attestation)))
.service(web::resource(VaultCommandRequest::URL).route(web::post().to(post_command)))
.service(web::resource(SignRequest::URL).route(web::post().to(post_sign)))
.service(web::resource(DIGEST_URL).route(web::get().to(get_digest)))
Expand Down
Loading

0 comments on commit 8a6aaa2

Please sign in to comment.