Skip to content

Commit

Permalink
Port pcs changes
Browse files Browse the repository at this point in the history
  • Loading branch information
raoulstrackx authored and mzohreva committed Dec 17, 2024
1 parent b06d1fd commit cb16436
Show file tree
Hide file tree
Showing 5 changed files with 115 additions and 62 deletions.
31 changes: 25 additions & 6 deletions intel-sgx/dcap-artifact-retrieval/src/provisioning_client/intel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@
//! - <https://download.01.org/intel-sgx/dcap-1.1/linux/docs/Intel_SGX_PCK_Certificate_CRL_Spec-1.1.pdf>
use pcs::{
CpuSvn, EncPpid, PceId, PceIsvsvn, PckCert, PckCerts, PckCrl, QeId, QeIdentitySigned, TcbInfo,
Unverified,
CpuSvn, EncPpid, Fmspc, PceId, PceIsvsvn, PckCert, PckCerts, PckCrl, QeId, QeIdentitySigned,
TcbInfo, Unverified,
};
use rustc_serialize::hex::ToHex;
use std::time::Duration;
Expand Down Expand Up @@ -336,7 +336,7 @@ impl TcbInfoApi {
impl<'inp> TcbInfoService<'inp> for TcbInfoApi {
fn build_input(
&'inp self,
fmspc: &'inp Vec<u8>,
fmspc: &'inp Fmspc,
) -> <Self as ProvisioningServiceApi<'inp>>::Input {
TcbInfoIn {
api_version: self.api_version.clone(),
Expand All @@ -353,7 +353,7 @@ impl<'inp> ProvisioningServiceApi<'inp> for TcbInfoApi {

fn build_request(&self, input: &Self::Input) -> Result<(String, Vec<(String, String)>), Error> {
let api_version = input.api_version as u8;
let fmspc = input.fmspc.to_hex();
let fmspc = input.fmspc.as_bytes().to_hex();
let url = format!(
"{}/sgx/certification/v{}/tcb?fmspc={}",
INTEL_BASE_URL, api_version, fmspc,
Expand Down Expand Up @@ -610,6 +610,8 @@ mod tests {
#[test]
pub fn pck_cached() {
for api_version in [PcsVersion::V3, PcsVersion::V4] {
let root_ca = include_bytes!("../../tests/data/root_SGX_CA_der.cert");
let root_cas = [&root_ca[..]];
let mut intel_builder = IntelProvisioningClientBuilder::new(api_version)
.set_retry_timeout(TIME_RETRY_TIMEOUT);
if api_version == PcsVersion::V3 {
Expand All @@ -629,6 +631,7 @@ mod tests {
None,
)
.unwrap();
let pck = pck.verify(&root_cas).unwrap();

// The cache should be populated after initial service call
{
Expand All @@ -653,7 +656,15 @@ mod tests {
.to_owned()
};

assert_eq!(pck.fmspc().unwrap(), cached_pck.fmspc().unwrap());
assert_eq!(
pck.fmspc().unwrap(),
cached_pck
.clone()
.verify(&root_cas)
.unwrap()
.fmspc()
.unwrap()
);
assert_eq!(pck.ca_chain(), cached_pck.ca_chain());
}

Expand All @@ -668,7 +679,15 @@ mod tests {
)
.unwrap();

assert_eq!(pck.fmspc().unwrap(), pck_from_service.fmspc().unwrap());
assert_eq!(
pck.fmspc().unwrap(),
pck_from_service
.clone()
.verify(&root_cas)
.unwrap()
.fmspc()
.unwrap()
);
assert_eq!(pck.ca_chain(), pck_from_service.ca_chain());
}
}
Expand Down
16 changes: 7 additions & 9 deletions intel-sgx/dcap-artifact-retrieval/src/provisioning_client/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ use std::time::{Duration, SystemTime};
use lru_cache::LruCache;
use num_enum::TryFromPrimitive;
use pcs::{
CpuSvn, EncPpid, PceId, PceIsvsvn, PckCert, PckCerts, PckCrl, PckID, QeId, QeIdentitySigned,
TcbInfo, Unverified,
CpuSvn, EncPpid, Fmspc, PceId, PceIsvsvn, PckCert, PckCerts, PckCrl, PckID, QeId,
QeIdentitySigned, TcbInfo, Unverified,
};
#[cfg(feature = "reqwest")]
use reqwest::blocking::{Client as ReqwestClient, Response as ReqwestResponse};
Expand Down Expand Up @@ -224,7 +224,7 @@ pub trait QeIdService<'inp>:
#[derive(Hash)]
pub struct TcbInfoIn<'i> {
pub(crate) api_version: PcsVersion,
pub(crate) fmspc: &'i Vec<u8>,
pub(crate) fmspc: &'i Fmspc,
}

impl WithApiVersion for TcbInfoIn<'_> {
Expand All @@ -236,10 +236,8 @@ impl WithApiVersion for TcbInfoIn<'_> {
pub trait TcbInfoService<'inp>:
ProvisioningServiceApi<'inp, Input = TcbInfoIn<'inp>, Output = TcbInfo>
{
fn build_input(
&'inp self,
fmspc: &'inp Vec<u8>,
) -> <Self as ProvisioningServiceApi<'inp>>::Input;
fn build_input(&'inp self, fmspc: &'inp Fmspc)
-> <Self as ProvisioningServiceApi<'inp>>::Input;
}

pub struct ClientBuilder {
Expand Down Expand Up @@ -530,7 +528,7 @@ pub trait ProvisioningClient {
qe_id: Option<&QeId>,
) -> Result<PckCert<Unverified>, Error>;

fn tcbinfo(&self, fmspc: &Vec<u8>) -> Result<TcbInfo, Error>;
fn tcbinfo(&self, fmspc: &Fmspc) -> Result<TcbInfo, Error>;

fn pckcrl(&self) -> Result<PckCrl, Error>;

Expand Down Expand Up @@ -588,7 +586,7 @@ impl<F: for<'a> Fetcher<'a>> ProvisioningClient for Client<F> {
self.pckcert_service.call_service(&self.fetcher, &input)
}

fn tcbinfo(&self, fmspc: &Vec<u8>) -> Result<TcbInfo, Error> {
fn tcbinfo(&self, fmspc: &Fmspc) -> Result<TcbInfo, Error> {
let input = self.tcbinfo_service.pcs_service().build_input(fmspc);
self.tcbinfo_service.call_service(&self.fetcher, &input)
}
Expand Down
31 changes: 26 additions & 5 deletions intel-sgx/dcap-artifact-retrieval/src/provisioning_client/pccs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ use std::borrow::Cow;
use std::time::Duration;

use pcs::{
CpuSvn, EncPpid, PceId, PceIsvsvn, PckCert, PckCrl, QeId, QeIdentitySigned, TcbInfo, Unverified,
CpuSvn, EncPpid, Fmspc, PceId, PceIsvsvn, PckCert, PckCrl, QeId, QeIdentitySigned, TcbInfo,
Unverified,
};
use rustc_serialize::hex::{FromHex, ToHex};

Expand Down Expand Up @@ -260,7 +261,7 @@ impl TcbInfoApi {
impl<'inp> TcbInfoService<'inp> for TcbInfoApi {
fn build_input(
&'inp self,
fmspc: &'inp Vec<u8>,
fmspc: &'inp Fmspc,
) -> <Self as ProvisioningServiceApi<'inp>>::Input {
TcbInfoIn {
api_version: self.api_version,
Expand All @@ -278,7 +279,7 @@ impl<'inp> ProvisioningServiceApi<'inp> for TcbInfoApi {

fn build_request(&self, input: &Self::Input) -> Result<(String, Vec<(String, String)>), Error> {
let api_version = input.api_version as u8;
let fmspc = input.fmspc.to_hex();
let fmspc = input.fmspc.as_bytes().to_hex();
let url = format!(
"{}/sgx/certification/v{}/tcb?fmspc={}",
self.base_url, api_version, fmspc
Expand Down Expand Up @@ -454,6 +455,8 @@ mod tests {
#[test]
#[ignore = "needs a running PCCS service"] // FIXME
pub fn pck_cached() {
let root_ca = include_bytes!("../../tests/data/root_SGX_CA_der.cert");
let root_cas = [&root_ca[..]];
for api_version in [PcsVersion::V3, PcsVersion::V4] {
let client = make_client(api_version);

Expand All @@ -471,6 +474,8 @@ mod tests {
)
.unwrap();

let pck = pck.verify(&root_cas).unwrap();

// The cache should be populated after initial service call
{
let mut cache = client.pckcert_service.cache.lock().unwrap();
Expand All @@ -494,7 +499,15 @@ mod tests {
.to_owned()
};

assert_eq!(pck.fmspc().unwrap(), cached_pck.fmspc().unwrap());
assert_eq!(
pck.fmspc().unwrap(),
cached_pck
.clone()
.verify(&root_cas)
.unwrap()
.fmspc()
.unwrap()
);
assert_eq!(pck.ca_chain(), cached_pck.ca_chain());
}

Expand All @@ -509,7 +522,15 @@ mod tests {
)
.unwrap();

assert_eq!(pck.fmspc().unwrap(), pck_from_service.fmspc().unwrap());
assert_eq!(
pck.fmspc().unwrap(),
pck_from_service
.clone()
.verify(&root_cas)
.unwrap()
.fmspc()
.unwrap()
);
assert_eq!(pck.ca_chain(), pck_from_service.ca_chain());
}
}
Expand Down
40 changes: 21 additions & 19 deletions intel-sgx/pcs/src/pckcrt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ use {
};

use crate::io::{self};
use crate::tcb_info::{TcbData, TcbLevel};
use crate::tcb_info::{Fmspc, TcbData, TcbLevel};
use crate::{CpuSvn, Error, Unverified, VerificationType, Verified};

/// [`SGXType`] is a rust enum representing the Intel® SGX Type.
Expand Down Expand Up @@ -295,7 +295,7 @@ impl PckCerts {
Ok(pcks)
}

pub fn fmspc(&self) -> Result<Vec<u8>, Error> {
pub fn fmspc(&self) -> Result<Fmspc, Error> {
let pck = self.iter().nth(0).ok_or(Error::NoPckCertData)?;
let sgx_extension = SGXPCKCertificateExtension::try_from(pck).map_err(|e| Error::InvalidPckFormat(e))?;
Ok(sgx_extension.fmspc)
Expand Down Expand Up @@ -458,6 +458,16 @@ impl PckCert<Verified> {
let pk = cert.public_key();
pk.ec_public()
}

pub fn ppid(&self) -> Result<Vec<u8>, ASN1Error> {
let extension = self.sgx_extension()?;
Ok(extension.ppid)
}

pub fn fmspc(&self) -> Result<Fmspc, ASN1Error> {
let extension = self.sgx_extension()?;
Ok(extension.fmspc)
}
}

impl<V: VerificationType> PckCert<V> {
Expand Down Expand Up @@ -536,11 +546,6 @@ impl<V: VerificationType> PckCert<V> {
Err(Error::InvalidPck("PckCert isn't valid for provided TCB".into()))
}
}

pub fn fmspc(&self) -> Result<Vec<u8>, Error> {
let sgx_extension = self.sgx_extension().map_err(|e| Error::InvalidPckFormat(e))?;
Ok(sgx_extension.fmspc)
}
}

#[derive(Default, Debug)]
Expand Down Expand Up @@ -624,12 +629,12 @@ impl BERDecodable for SGXPlatformConfiguration {
}
}

#[derive(Default, Debug)]
#[derive(Debug)]
pub struct SGXPCKCertificateExtension {
pub ppid: Vec<u8>,
pub tcb: PlatformTCB,
pub pceid: u16,
pub fmspc: Vec<u8>,
pub fmspc: Fmspc,
pub sgx_type: SGXType,
pub platform_instance_id: Option<Vec<u8>>,
pub configuration: Option<SGXPlatformConfiguration>,
Expand Down Expand Up @@ -679,11 +684,8 @@ impl SGXPCKCertificateExtension {
configuration = Some(reader.next(|reader| SGXPlatformConfiguration::decode_ber(reader))?);
}

if ppid.len() != 16
|| pceid.len() != 2
|| fmspc.len() != 6
|| platform_instance_id.as_ref().map_or(false, |id| id.len() != 16)
{
let fmspc = Fmspc::try_from(&fmspc).map_err(|_| ASN1Error::new(ASN1ErrorKind::Invalid))?;
if ppid.len() != 16 || pceid.len() != 2 || platform_instance_id.as_ref().map_or(false, |id| id.len() != 16) {
return Err(ASN1Error::new(ASN1ErrorKind::Invalid));
}

Expand Down Expand Up @@ -921,7 +923,7 @@ mod tests {
assert_eq!(sgx_extension.tcb.tcb_components.0.pcesvn, 9);
assert_eq!(sgx_extension.tcb.cpusvn, [13, 13, 2, 4, 1, 128, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
assert_eq!(sgx_extension.pceid, 0);
assert_eq!(sgx_extension.fmspc, [0, 144, 110, 161, 0, 0]);
assert_eq!(sgx_extension.fmspc, Fmspc::new([0, 144, 110, 161, 0, 0]));
assert_eq!(sgx_extension.sgx_type, SGXType::Standard);
assert!(sgx_extension.platform_instance_id.is_none());
assert!(sgx_extension.configuration.is_none());
Expand Down Expand Up @@ -957,7 +959,7 @@ mod tests {
assert_eq!(sgx_extension.tcb.tcb_components.0.pcesvn, 10);
assert_eq!(sgx_extension.tcb.cpusvn, [3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
assert_eq!(sgx_extension.pceid, 0);
assert_eq!(sgx_extension.fmspc, [16, 96, 106, 0, 0, 0]);
assert_eq!(sgx_extension.fmspc, Fmspc::new([16, 96, 106, 0, 0, 0]));
assert_eq!(sgx_extension.sgx_type, SGXType::Scalable);
assert_eq!(
sgx_extension.platform_instance_id.unwrap(),
Expand Down Expand Up @@ -998,7 +1000,7 @@ mod tests {
assert_eq!(sgx_extension.tcb.tcb_components.0.pcesvn, 9);
assert_eq!(sgx_extension.tcb.cpusvn, [13, 13, 2, 4, 1, 128, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
assert_eq!(sgx_extension.pceid, 0);
assert_eq!(sgx_extension.fmspc, [0, 144, 110, 161, 0, 0]);
assert_eq!(sgx_extension.fmspc, Fmspc::new([0, 144, 110, 161, 0, 0]));
}
}

Expand All @@ -1010,7 +1012,7 @@ mod tests {
let pck_chain: Qe3CertDataPckCertChain = sig.certification_data().unwrap();
let pck = PckCert::from_pck_chain(pck_chain.certs.into()).unwrap();
let sgx_extension = pck.sgx_extension().unwrap();
assert_eq!(sgx_extension.fmspc, [0, 144, 110, 161, 0, 0]);
assert_eq!(sgx_extension.fmspc, Fmspc::new([0, 144, 110, 161, 0, 0]));
}

#[test]
Expand Down Expand Up @@ -1041,7 +1043,7 @@ mod tests {
assert_eq!(sgx_extension.tcb.tcb_components.0.pcesvn, 10);
assert_eq!(sgx_extension.tcb.cpusvn, [14, 14, 2, 4, 1, 128, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
assert_eq!(sgx_extension.pceid, 0);
assert_eq!(sgx_extension.fmspc, [0, 144, 110, 161, 0, 0]);
assert_eq!(sgx_extension.fmspc, Fmspc::new([0, 144, 110, 161, 0, 0]));
}

#[test]
Expand Down
Loading

0 comments on commit cb16436

Please sign in to comment.