diff --git a/Cargo.lock b/Cargo.lock index 0dd2bbf1e..0cc732ad0 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", @@ -583,7 +577,7 @@ dependencies = [ "serde", "serde_json", "serde_with", - "sev", + "sev 3.2.0", "sha2", "strum", "tdx-attest-rs", @@ -668,7 +662,7 @@ dependencies = [ "serde", "serde-big-array", "serde_json", - "sev", + "sev 3.2.0", "sha2", "thiserror", "tss-esapi", @@ -688,7 +682,7 @@ dependencies = [ "serde", "serde-big-array", "serde_json", - "sev", + "sev 3.2.0", "sha2", "thiserror", "tss-esapi", @@ -706,7 +700,7 @@ dependencies = [ "clap 4.5.4", "openssl", "serde", - "sev", + "sev 3.2.0", "thiserror", "ureq", ] @@ -721,7 +715,7 @@ dependencies = [ "bincode", "clap 4.5.4", "serde", - "sev", + "sev 3.2.0", "thiserror", "ureq", ] @@ -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" @@ -4042,6 +4006,15 @@ dependencies = [ "cipher", ] +[[package]] +name = "rdrand" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d92195228612ac8eed47adbc2ed0f04e513a4ccb98175b6f2bd04d963b533655" +dependencies = [ + "rand_core", +] + [[package]] name = "redox_syscall" version = "0.2.16" @@ -4168,12 +4141,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 +4184,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 +4206,7 @@ dependencies = [ "serde_json", "serde_urlencoded", "sync_wrapper", - "system-configuration", "tokio", - "tokio-native-tls", "tokio-rustls 0.25.0", "tower-service", "url", @@ -4868,13 +4835,38 @@ dependencies = [ [[package]] name = "sev" -version = "3.1.1" +version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2890179f8ef689340f441ba05f0b268bc14f672ae4b36d629cc2266d0d747ab" +checksum = "35156eab65ff1b63432b5a11a06b770e92120033e2831c7dee064865de5dbbbd" dependencies = [ - "base64 0.21.7", + "base64 0.22.1", "bincode", - "bitfield 0.13.2", + "bitfield 0.15.0", + "bitflags 1.3.2", + "byteorder", + "codicon", + "dirs", + "hex", + "iocuddle", + "lazy_static", + "libc", + "openssl", + "serde", + "serde-big-array", + "serde_bytes", + "static_assertions", + "uuid", +] + +[[package]] +name = "sev" +version = "4.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a97bd0b2e2d937951add10c8512a2dacc6ad29b39e5c5f26565a3e443329857d" +dependencies = [ + "base64 0.22.1", + "bincode", + "bitfield 0.15.0", "bitflags 1.3.2", "byteorder", "codicon", @@ -4884,6 +4876,7 @@ dependencies = [ "lazy_static", "libc", "openssl", + "rdrand", "serde", "serde-big-array", "serde_bytes", @@ -5511,7 +5504,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 +5531,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", @@ -5927,7 +5920,7 @@ dependencies = [ "serde_json", "serde_with", "serial_test", - "sev", + "sev 4.0.0", "sha2", "shadow-rs", "strum", diff --git a/Cargo.toml b/Cargo.toml index 3d7bd6bbc..c440bfbaa 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -36,7 +36,7 @@ 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" +reqwest = { version = "0.12", default-features = false } rstest = "0.18.1" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0.89" @@ -46,7 +46,7 @@ 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" diff --git a/deps/verifier/Cargo.toml b/deps/verifier/Cargo.toml index 8f78b6ff4..bab7561ce 100644 --- a/deps/verifier/Cargo.toml +++ b/deps/verifier/Cargo.toml @@ -28,7 +28,7 @@ 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" @@ -41,9 +41,9 @@ scroll = { version = "0.11.0", default-features = false, features = ["derive"], serde.workspace = true serde_json.workspace = true serde_with = { workspace = true, optional = true } -sev = { version = "3.1.1", features = ["openssl", "snp"], optional = true } +sev = { version = "4.0.0", 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 a1cced4cd..52557b7ce 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 40c09d345..85a4a0849 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 b5e4276b7..eaeecb53c 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 link_bytes_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 = link_bytes_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 3278c9e71..bef0436d2 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,