diff --git a/Cargo.lock b/Cargo.lock index ca9cf35d28..9f9bcbfc4c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -40,7 +40,7 @@ dependencies = [ "encoding_rs", "flate2", "futures-core", - "h2 0.3.26", + "h2", "http 0.2.12", "httparse", "httpdate", @@ -490,12 +490,6 @@ dependencies = [ "syn 2.0.60", ] -[[package]] -name = "atomic-waker" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" - [[package]] name = "attestation-agent" version = "0.1.0" @@ -573,7 +567,7 @@ dependencies = [ "csv-rs", "hex", "hyper 0.14.28", - "hyper-tls 0.5.0", + "hyper-tls", "kbs-types", "log", "nix", @@ -894,6 +888,12 @@ version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2d7e60934ceec538daadb9d8432424ed043a904d8e0243f3c6446bce549a46ac" +[[package]] +name = "bitfield" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c821a6e124197eb56d907ccc2188eab1038fb919c914f47976e64dd8dbc855d1" + [[package]] name = "bitflags" version = "1.3.2" @@ -1417,7 +1417,7 @@ dependencies = [ "codicon", "dirs", "hyper 0.14.28", - "hyper-tls 0.5.0", + "hyper-tls", "iocuddle", "libc", "openssl", @@ -2077,25 +2077,6 @@ dependencies = [ "tracing", ] -[[package]] -name = "h2" -version = "0.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa82e28a107a8cc405f0839610bdc9b15f1e25ec7d696aa5cf173edbcb1486ab" -dependencies = [ - "atomic-waker", - "bytes", - "fnv", - "futures-core", - "futures-sink", - "http 1.1.0", - "indexmap 2.2.6", - "slab", - "tokio", - "tokio-util", - "tracing", -] - [[package]] name = "half" version = "2.4.1" @@ -2295,7 +2276,7 @@ dependencies = [ "futures-channel", "futures-core", "futures-util", - "h2 0.3.26", + "h2", "http 0.2.12", "http-body 0.4.6", "httparse", @@ -2318,7 +2299,6 @@ dependencies = [ "bytes", "futures-channel", "futures-util", - "h2 0.4.5", "http 1.1.0", "http-body 1.0.0", "httparse", @@ -2385,22 +2365,6 @@ dependencies = [ "tokio-native-tls", ] -[[package]] -name = "hyper-tls" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" -dependencies = [ - "bytes", - "http-body-util", - "hyper 1.3.1", - "hyper-util", - "native-tls", - "tokio", - "tokio-native-tls", - "tower-service", -] - [[package]] name = "hyper-util" version = "0.1.5" @@ -4168,12 +4132,12 @@ dependencies = [ "encoding_rs", "futures-core", "futures-util", - "h2 0.3.26", + "h2", "http 0.2.12", "http-body 0.4.6", "hyper 0.14.28", "hyper-rustls 0.24.2", - "hyper-tls 0.5.0", + "hyper-tls", "ipnet", "js-sys", "log", @@ -4211,22 +4175,18 @@ dependencies = [ "bytes", "cookie 0.17.0", "cookie_store", - "encoding_rs", "futures-core", "futures-util", - "h2 0.4.5", "http 1.1.0", "http-body 1.0.0", "http-body-util", "hyper 1.3.1", "hyper-rustls 0.26.0", - "hyper-tls 0.6.0", "hyper-util", "ipnet", "js-sys", "log", "mime", - "native-tls", "once_cell", "percent-encoding", "pin-project-lite", @@ -4237,9 +4197,7 @@ dependencies = [ "serde_json", "serde_urlencoded", "sync_wrapper", - "system-configuration", "tokio", - "tokio-native-tls", "tokio-rustls 0.25.0", "tower-service", "url", @@ -4869,12 +4827,10 @@ dependencies = [ [[package]] name = "sev" version = "3.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2890179f8ef689340f441ba05f0b268bc14f672ae4b36d629cc2266d0d747ab" dependencies = [ - "base64 0.21.7", + "base64 0.22.1", "bincode", - "bitfield 0.13.2", + "bitfield 0.15.0", "bitflags 1.3.2", "byteorder", "codicon", @@ -5511,7 +5467,7 @@ dependencies = [ "bytes", "futures-core", "futures-util", - "h2 0.3.26", + "h2", "http 0.2.12", "http-body 0.4.6", "hyper 0.14.28", @@ -5538,7 +5494,7 @@ dependencies = [ "axum", "base64 0.21.7", "bytes", - "h2 0.3.26", + "h2", "http 0.2.12", "http-body 0.4.6", "hyper 0.14.28", diff --git a/Cargo.toml b/Cargo.toml index 3d7bd6bbc9..592cf11172 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -34,9 +34,13 @@ kbs-types = "0.6.0" kms = { git = "https://github.com/confidential-containers/guest-components.git", rev="9bd6f06a9704e01808e91abde130dffb20e632a5", default-features = false } jsonwebtoken = { version = "9", default-features = false } log = "0.4.17" -prost = "0.12" -regorus = { version = "0.1.5", default-features = false, features = ["regex", "base64", "time"] } -reqwest = "0.12" +prost = "0.12.0" +regorus = { version = "0.1.5", default-features = false, features = [ + "regex", + "base64", + "time", +] } +reqwest = { version = "0.12", default-features = false } rstest = "0.18.1" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0.89" @@ -46,7 +50,11 @@ sha2 = "0.10" shadow-rs = "0.19.0" strum = { version = "0.25", features = ["derive"] } thiserror = "1.0" -tokio = { version = "1", features = ["full"] } +tokio = { version = "1", features = ["full"], default-features = false } tempfile = "3.4.0" tonic = "0.11" -tonic-build = "0.11" \ No newline at end of file +tonic-build = "0.11" + +# Will be removed after updates are pulled in upstream +[patch.crates-io] +sev = { version = "3.1.1", path = "/home/larry/git/larrydewey/virtee-sev" } diff --git a/attestation-service/Makefile b/attestation-service/Makefile index 60e285b12f..e5714a44e7 100644 --- a/attestation-service/Makefile +++ b/attestation-service/Makefile @@ -23,7 +23,6 @@ grpc-as: restful-as: cargo build --bin restful-as $(release) --features restful-bin - install: for bin_name in $(BIN_NAMES); do \ install -D -m0755 $(TARGET_DIR)/$$bin_name $(DESTDIR); \ diff --git a/deps/verifier/Cargo.toml b/deps/verifier/Cargo.toml index 8f78b6ff45..84be06b5ba 100644 --- a/deps/verifier/Cargo.toml +++ b/deps/verifier/Cargo.toml @@ -4,31 +4,44 @@ version = "0.1.0" edition = "2021" [features] -default = [ "all-verifier" ] -all-verifier = [ "tdx-verifier", "sgx-verifier", "snp-verifier", "az-snp-vtpm-verifier", "az-tdx-vtpm-verifier", "csv-verifier", "cca-verifier", "se-verifier" ] -tdx-verifier = [ "eventlog-rs", "scroll", "intel-tee-quote-verification-rs" ] -sgx-verifier = [ "scroll", "intel-tee-quote-verification-rs" ] -az-snp-vtpm-verifier = [ "az-snp-vtpm", "sev", "snp-verifier" ] -az-tdx-vtpm-verifier = [ "az-tdx-vtpm", "openssl", "tdx-verifier" ] -snp-verifier = [ "asn1-rs", "openssl", "sev", "x509-parser" ] -csv-verifier = [ "openssl", "csv-rs", "codicon" ] -cca-verifier = [ "ear", "jsonwebtoken", "veraison-apiclient" ] -se-verifier = [ "openssl", "pv", "serde_with", "tokio/sync" ] +default = ["all-verifier"] +all-verifier = [ + "tdx-verifier", + "sgx-verifier", + "snp-verifier", + "az-snp-vtpm-verifier", + "az-tdx-vtpm-verifier", + "csv-verifier", + "cca-verifier", + "se-verifier", +] +tdx-verifier = ["eventlog-rs", "scroll", "intel-tee-quote-verification-rs"] +sgx-verifier = ["scroll", "intel-tee-quote-verification-rs"] +az-snp-vtpm-verifier = ["az-snp-vtpm", "sev", "snp-verifier"] +az-tdx-vtpm-verifier = ["az-tdx-vtpm", "openssl", "tdx-verifier"] +snp-verifier = ["asn1-rs", "openssl", "sev", "x509-parser"] +csv-verifier = ["openssl", "csv-rs", "codicon"] +cca-verifier = ["ear", "jsonwebtoken", "veraison-apiclient"] +se-verifier = ["openssl", "pv", "serde_with", "tokio/sync"] [dependencies] anyhow.workspace = true thiserror.workspace = true asn1-rs = { version = "0.5.1", optional = true } async-trait.workspace = true -az-snp-vtpm = { version = "0.5.3", default-features = false, features = ["verifier"], optional = true } -az-tdx-vtpm = { version = "0.5.3", default-features = false, features = ["verifier"], optional = true } +az-snp-vtpm = { version = "0.5.3", default-features = false, features = [ + "verifier", +], optional = true } +az-tdx-vtpm = { version = "0.5.3", default-features = false, features = [ + "verifier", +], optional = true } base64 = "0.21" bincode = "1.3.3" byteorder = "1" cfg-if = "1.0.0" codicon = { version = "3.0", optional = true } # TODO: change it to "0.1", once released. -csv-rs = { git = "https://github.com/openanolis/csv-rs", rev = "b74aa8c", optional = true } +csv-rs = { version = "=0.1.0", git = "https://github.com/openanolis/csv-rs", rev = "b74aa8c", optional = true } eventlog-rs = { version = "0.1.3", optional = true } hex.workspace = true jsonwebkey = "0.3.5" @@ -37,13 +50,15 @@ kbs-types.workspace = true log.workspace = true openssl = { version = "0.10.55", optional = true } pv = { version = "0.10.0", package = "s390_pv", optional = true } -scroll = { version = "0.11.0", default-features = false, features = ["derive"], optional = true } +scroll = { version = "0.11.0", default-features = false, features = [ + "derive", +], optional = true } serde.workspace = true serde_json.workspace = true serde_with = { workspace = true, optional = true } sev = { version = "3.1.1", features = ["openssl", "snp"], optional = true } sha2.workspace = true -tokio = { workspace = true, optional = true, default-features = false } +tokio = { workspace = true, optional = true } intel-tee-quote-verification-rs = { git = "https://github.com/intel/SGXDataCenterAttestationPrimitives", tag = "DCAP_1.21", optional = true } strum.workspace = true veraison-apiclient = { git = "https://github.com/chendave/rust-apiclient", branch = "token", optional = true } diff --git a/deps/verifier/src/az_snp_vtpm/mod.rs b/deps/verifier/src/az_snp_vtpm/mod.rs index a1cced4cda..52557b7ce5 100644 --- a/deps/verifier/src/az_snp_vtpm/mod.rs +++ b/deps/verifier/src/az_snp_vtpm/mod.rs @@ -4,9 +4,7 @@ // use super::{TeeEvidenceParsedClaim, Verifier}; -use crate::snp::{ - load_milan_cert_chain, parse_tee_evidence, verify_report_signature, VendorCertificates, -}; +use crate::snp::{load_milan_cert_chain, parse_tee_evidence, verify_report_signature}; use crate::{InitDataHash, ReportData}; use anyhow::{bail, Context, Result}; use async_trait::async_trait; @@ -19,6 +17,7 @@ use log::{debug, warn}; use openssl::pkey::PKey; use serde::{Deserialize, Serialize}; use serde_json::Value; +use sev::certs::snp::Chain; use sev::firmware::host::{CertTableEntry, CertType}; use thiserror::Error; @@ -32,7 +31,7 @@ struct Evidence { } pub struct AzSnpVtpm { - vendor_certs: VendorCertificates, + vendor_certs: Chain, } #[derive(Error, Debug)] @@ -54,12 +53,10 @@ pub enum CertError { } impl AzSnpVtpm { - pub fn new() -> Result { - let Result::Ok(vendor_certs) = load_milan_cert_chain() else { - return Err(CertError::LoadMilanCert); - }; - let vendor_certs = vendor_certs.clone(); - Ok(Self { vendor_certs }) + pub fn new() -> Self { + Self { + vendor_certs: load_milan_cert_chain().clone(), + } } } @@ -171,7 +168,7 @@ fn verify_report_data( fn verify_snp_report( snp_report: &AttestationReport, vcek: &Vcek, - vendor_certs: &VendorCertificates, + vendor_certs: &Chain, ) -> Result<(), CertError> { let vcek_data = vcek.0.to_der().context("Failed to get raw VCEK data")?; let cert_chain = [CertTableEntry::new(CertType::VCEK, vcek_data)]; @@ -199,7 +196,7 @@ mod tests { let hcl_report = HclReport::new(REPORT.to_vec()).unwrap(); let snp_report = hcl_report.try_into().unwrap(); let vcek = Vcek::from_pem(include_str!("../../test_data/az-snp-vtpm/vcek.pem")).unwrap(); - let vendor_certs = load_milan_cert_chain().as_ref().unwrap(); + let vendor_certs = load_milan_cert_chain(); verify_snp_report(&snp_report, &vcek, vendor_certs).unwrap(); } @@ -211,7 +208,7 @@ mod tests { let hcl_report = HclReport::new(wrong_report.to_vec()).unwrap(); let snp_report = hcl_report.try_into().unwrap(); let vcek = Vcek::from_pem(include_str!("../../test_data/az-snp-vtpm/vcek.pem")).unwrap(); - let vendor_certs = load_milan_cert_chain().as_ref().unwrap(); + let vendor_certs = load_milan_cert_chain(); assert_eq!( verify_snp_report(&snp_report, &vcek, vendor_certs) .unwrap_err() diff --git a/deps/verifier/src/lib.rs b/deps/verifier/src/lib.rs index 40c09d345a..85a4a08496 100644 --- a/deps/verifier/src/lib.rs +++ b/deps/verifier/src/lib.rs @@ -39,7 +39,7 @@ pub fn to_verifier(tee: &Tee) -> Result> { Tee::AzSnpVtpm => { cfg_if::cfg_if! { if #[cfg(feature = "az-snp-vtpm-verifier")] { - let verifier = az_snp_vtpm::AzSnpVtpm::new()?; + let verifier = az_snp_vtpm::AzSnpVtpm::new(); Ok(Box::new(verifier) as Box) } else { bail!("feature `az-snp-vtpm-verifier` is not enabled for `verifier` crate.") @@ -67,7 +67,7 @@ pub fn to_verifier(tee: &Tee) -> Result> { Tee::Snp => { cfg_if::cfg_if! { if #[cfg(feature = "snp-verifier")] { - let verifier = snp::Snp::new()?; + let verifier = snp::Snp::new(); Ok(Box::new(verifier) as Box) } else { bail!("feature `snp-verifier` is not enabled for `verifier` crate.") diff --git a/deps/verifier/src/snp/mod.rs b/deps/verifier/src/snp/mod.rs index b5e4276b71..eff06868c2 100644 --- a/deps/verifier/src/snp/mod.rs +++ b/deps/verifier/src/snp/mod.rs @@ -15,6 +15,7 @@ use openssl::{ x509::{self, X509}, }; use serde_json::json; +use sev::certs::snp::{ca::Chain as CaChain, Certificate, Chain}; use sev::firmware::guest::AttestationReport; use sev::firmware::host::{CertTableEntry, CertType}; use std::sync::OnceLock; @@ -34,43 +35,43 @@ const LOADER_SPL_OID: Oid<'static> = oid!(1.3.6 .1 .4 .1 .3704 .1 .3 .1); #[derive(Debug)] pub struct Snp { - vendor_certs: VendorCertificates, + vendor_certs: Chain, } -pub(crate) fn load_milan_cert_chain() -> &'static Result { - static MILAN_CERT_CHAIN: OnceLock> = OnceLock::new(); - MILAN_CERT_CHAIN.get_or_init(|| { - let certs = X509::stack_from_pem(include_bytes!("milan_ask_ark_asvk.pem"))?; - if certs.len() != 3 { - bail!("Malformed Milan ASK/ARK/ASVK"); +fn read_certs_from_file() -> Vec { + match X509::stack_from_pem(include_bytes!("milan_ask_ark_asvk.pem")) { + Result::Ok(certs) => { + if certs.len() != 3 { + panic!("Malformed Milan ASK/ARK/ASVK"); + } + return certs; } + Result::Err(err) => panic!("Error reading certificates file: {err}"), + } +} - let vendor_certs = VendorCertificates { - ask: certs[0].clone(), - ark: certs[1].clone(), - asvk: certs[2].clone(), - }; - Ok(vendor_certs) +pub(crate) fn load_milan_cert_chain() -> &'static Chain { + static MILAN_CERT_CHAIN: OnceLock = OnceLock::new(); + MILAN_CERT_CHAIN.get_or_init(|| { + let certs = read_certs_from_file(); + Chain { + ca: CaChain { + ark: Certificate::from(certs[1].clone()), + ask: Certificate::from(certs[0].clone()), + }, + vek: Certificate::from(certs[2].clone()), + } }) } impl Snp { - pub fn new() -> Result { - let Result::Ok(vendor_certs) = load_milan_cert_chain() else { - bail!("Failed to load Milan cert chain"); - }; - let vendor_certs = vendor_certs.clone(); - Ok(Self { vendor_certs }) + pub fn new() -> Self { + Self { + vendor_certs: load_milan_cert_chain().clone(), + } } } -#[derive(Clone, Debug)] -pub(crate) struct VendorCertificates { - ask: X509, - ark: X509, - asvk: X509, -} - #[async_trait] impl Verifier for Snp { async fn evaluate( @@ -165,10 +166,10 @@ fn get_oid_int(cert: &x509_parser::certificate::TbsCertificate, oid: Oid) -> Res pub(crate) fn verify_report_signature( report: &AttestationReport, cert_chain: &[CertTableEntry], - vendor_certs: &VendorCertificates, + vendor_certs: &Chain, ) -> Result<()> { // check cert chain - let VendorCertificates { ask, ark, asvk } = vendor_certs; + let (ask, ark, asvk): (&X509, &X509, &X509) = vendor_certs.into(); // verify VCEK or VLEK cert chain // the key can be either VCEK or VLEK @@ -322,7 +323,7 @@ mod tests { #[test] fn check_milan_certificates() { - let VendorCertificates { ask, ark, asvk } = load_milan_cert_chain().as_ref().unwrap(); + let (ask, ark, asvk) = load_milan_cert_chain().into(); assert_eq!(get_common_name(ark).unwrap(), "ARK-Milan"); assert_eq!(get_common_name(ask).unwrap(), "SEV-Milan"); assert_eq!(get_common_name(asvk).unwrap(), "SEV-VLEK-Milan"); @@ -393,7 +394,7 @@ mod tests { #[test] fn check_vcek_signature_verification() { let cert_table = vec![CertTableEntry::new(CertType::VCEK, VCEK.to_vec())]; - let VendorCertificates { ask, ark, asvk } = load_milan_cert_chain().as_ref().unwrap(); + let (ask, ark, asvk) = load_milan_cert_chain().into(); verify_cert_chain(&cert_table, ask, ark, asvk).unwrap(); } @@ -406,14 +407,14 @@ mod tests { X509::from_der(&vcek).expect("failed to parse der"); let cert_table = vec![CertTableEntry::new(CertType::VCEK, vcek.to_vec())]; - let VendorCertificates { ask, ark, asvk } = load_milan_cert_chain().as_ref().unwrap(); + let (ask, ark, asvk) = load_milan_cert_chain().into(); verify_cert_chain(&cert_table, ask, ark, asvk).unwrap_err(); } #[test] fn check_vlek_signature_verification() { let cert_table = vec![CertTableEntry::new(CertType::VLEK, VLEK.to_vec())]; - let VendorCertificates { ask, ark, asvk } = load_milan_cert_chain().as_ref().unwrap(); + let (ask, ark, asvk) = load_milan_cert_chain().into(); verify_cert_chain(&cert_table, ask, ark, asvk).unwrap(); } @@ -426,14 +427,14 @@ mod tests { X509::from_der(&vlek).expect("failed to parse der"); let cert_table = vec![CertTableEntry::new(CertType::VLEK, vlek.to_vec())]; - let VendorCertificates { ask, ark, asvk } = load_milan_cert_chain().as_ref().unwrap(); + let (ask, ark, asvk) = load_milan_cert_chain().into(); verify_cert_chain(&cert_table, ask, ark, asvk).unwrap_err(); } #[test] fn check_milan_chain_signature_failure() { let cert_table = vec![CertTableEntry::new(CertType::VCEK, VCEK.to_vec())]; - let VendorCertificates { ask, ark, asvk } = load_milan_cert_chain().as_ref().unwrap(); + let (ask, ark, asvk) = load_milan_cert_chain().into(); // toggle ark <=> ask verify_cert_chain(&cert_table, ark, ask, asvk).unwrap_err(); @@ -444,7 +445,7 @@ mod tests { let attestation_report = bincode::deserialize::(VCEK_REPORT.as_slice()).unwrap(); let cert_chain = vec![CertTableEntry::new(CertType::VCEK, VCEK.to_vec())]; - let vendor_certs = load_milan_cert_chain().as_ref().unwrap(); + let vendor_certs = load_milan_cert_chain(); verify_report_signature(&attestation_report, &cert_chain, vendor_certs).unwrap(); } @@ -453,7 +454,7 @@ mod tests { let attestation_report = bincode::deserialize::(VLEK_REPORT.as_slice()).unwrap(); let cert_chain = vec![CertTableEntry::new(CertType::VLEK, VLEK.to_vec())]; - let vendor_certs = load_milan_cert_chain().as_ref().unwrap(); + let vendor_certs = load_milan_cert_chain(); verify_report_signature(&attestation_report, &cert_chain, vendor_certs).unwrap(); } @@ -466,7 +467,7 @@ mod tests { let attestation_report = bincode::deserialize::(&bytes).unwrap(); let cert_chain = vec![CertTableEntry::new(CertType::VCEK, VCEK.to_vec())]; - let vendor_certs = load_milan_cert_chain().as_ref().unwrap(); + let vendor_certs = load_milan_cert_chain(); verify_report_signature(&attestation_report, &cert_chain, vendor_certs).unwrap_err(); } @@ -479,7 +480,7 @@ mod tests { let attestation_report = bincode::deserialize::(&bytes).unwrap(); let cert_chain = vec![CertTableEntry::new(CertType::VLEK, VLEK.to_vec())]; - let vendor_certs = load_milan_cert_chain().as_ref().unwrap(); + let vendor_certs = load_milan_cert_chain(); verify_report_signature(&attestation_report, &cert_chain, vendor_certs).unwrap_err(); } } diff --git a/deps/verifier/src/tdx/eventlog.rs b/deps/verifier/src/tdx/eventlog.rs index 3278c9e71a..bef0436d27 100644 --- a/deps/verifier/src/tdx/eventlog.rs +++ b/deps/verifier/src/tdx/eventlog.rs @@ -124,6 +124,7 @@ impl CcEventLog { /// Defined in TCG PC Client Platform Firmware Profile Specification section /// 'UEFI_PLATFORM_FIRMWARE_BLOB Structure Definition' +#[allow(dead_code)] pub struct ParsedUefiPlatformFirmwareBlob2 { pub desc_len: u8, pub desc: Vec,