Skip to content
Draft
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
2 changes: 1 addition & 1 deletion intel-sgx/dcap-artifact-retrieval/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ enum Origin {
Pccs,
}

fn str_deserialize(s: &str) -> value::StrDeserializer<value::Error> {
fn str_deserialize(s: &str) -> value::StrDeserializer<'_, value::Error> {
s.into_deserializer()
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ use super::{
PckCrlIn, PckCrlService, PcsVersion, ProvisioningServiceApi, QeIdIn, QeIdService, StatusCode,
TcbEvaluationDataNumbersIn, TcbEvaluationDataNumbersService, TcbInfoIn, TcbInfoService, WithApiVersion,
};
use crate::Error;
use crate::{Error, UpdateType};

pub(crate) const INTEL_BASE_URL: &'static str = "https://api.trustedservices.intel.com";
const SUBSCRIPTION_KEY_HEADER: &'static str = "Ocp-Apim-Subscription-Key";
Expand Down Expand Up @@ -348,11 +348,13 @@ impl<'inp> TcbInfoService<'inp> for TcbInfoApi {
&'inp self,
fmspc: &'inp Fmspc,
tcb_evaluation_data_number: Option<u16>,
update_type: Option<UpdateType>,
) -> <Self as ProvisioningServiceApi<'inp>>::Input {
TcbInfoIn {
api_version: self.api_version.clone(),
fmspc,
tcb_evaluation_data_number,
update_type: update_type.unwrap_or(UpdateType::Early),
}
}
}
Expand Down Expand Up @@ -435,10 +437,11 @@ impl QeIdApi {
}

impl<'inp> QeIdService<'inp> for QeIdApi {
fn build_input(&'inp self, tcb_evaluation_data_number: Option<u16>) -> <Self as ProvisioningServiceApi<'inp>>::Input {
fn build_input(&'inp self, tcb_evaluation_data_number: Option<u16>, update_type: Option<UpdateType>) -> <Self as ProvisioningServiceApi<'inp>>::Input {
QeIdIn {
api_version: self.api_version.clone(),
tcb_evaluation_data_number,
update_type: update_type.unwrap_or(UpdateType::Early),
}
}
}
Expand All @@ -458,8 +461,8 @@ impl<'inp> ProvisioningServiceApi<'inp> for QeIdApi {
)
} else {
format!(
"{}/sgx/certification/v{}/qe/identity?update=early",
INTEL_BASE_URL, api_version,
"{}/sgx/certification/v{}/qe/identity?update={}",
INTEL_BASE_URL, api_version, input.update_type.as_str(),
)
};
Ok((url, Vec::new()))
Expand Down Expand Up @@ -930,7 +933,7 @@ mod tests {
let input = client
.tcbinfo_service
.pcs_service()
.build_input(&fmspc, None);
.build_input(&fmspc, None, None);
input.hash(&mut hasher);

cache
Expand Down Expand Up @@ -1072,7 +1075,7 @@ mod tests {

let (cached_qeid, _) = {
let mut hasher = DefaultHasher::new();
let input = client.qeid_service.pcs_service().build_input(None);
let input = client.qeid_service.pcs_service().build_input(None, None);
input.hash(&mut hasher);

cache
Expand Down
25 changes: 21 additions & 4 deletions intel-sgx/dcap-artifact-retrieval/src/provisioning_client/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -206,10 +206,26 @@ pub trait PckCrlService<'inp>:
fn build_input(&'inp self, ca: DcapArtifactIssuer) -> <Self as ProvisioningServiceApi<'inp>>::Input;
}

#[derive(Copy, Clone, PartialEq, Eq, Hash)]
pub enum UpdateType {
Early,
Standard,
}

impl UpdateType {
pub const fn as_str(&self) -> &str {
match self {
Self::Early => "early",
Self::Standard => "standard",
}
}
}

#[derive(Hash)]
pub struct QeIdIn {
pub api_version: PcsVersion,
pub tcb_evaluation_data_number: Option<u16>,
pub update_type: UpdateType,
}

impl WithApiVersion for QeIdIn {
Expand All @@ -221,14 +237,15 @@ impl WithApiVersion for QeIdIn {
pub trait QeIdService<'inp>:
ProvisioningServiceApi<'inp, Input = QeIdIn, Output = QeIdentitySigned>
{
fn build_input(&'inp self, tcb_evaluation_data_number: Option<u16>) -> <Self as ProvisioningServiceApi<'inp>>::Input;
fn build_input(&'inp self, tcb_evaluation_data_number: Option<u16>, update_type: Option<UpdateType>) -> <Self as ProvisioningServiceApi<'inp>>::Input;
}

#[derive(Hash)]
pub struct TcbInfoIn<'i> {
pub(crate) api_version: PcsVersion,
pub(crate) fmspc: &'i Fmspc,
pub(crate) tcb_evaluation_data_number: Option<u16>,
pub(crate) update_type: UpdateType,
}

impl WithApiVersion for TcbInfoIn<'_> {
Expand All @@ -240,7 +257,7 @@ impl WithApiVersion for TcbInfoIn<'_> {
pub trait TcbInfoService<'inp>:
ProvisioningServiceApi<'inp, Input = TcbInfoIn<'inp>, Output = TcbInfo>
{
fn build_input(&'inp self, fmspc: &'inp Fmspc, tcb_evaluation_data_number: Option<u16>)
fn build_input(&'inp self, fmspc: &'inp Fmspc, tcb_evaluation_data_number: Option<u16>, update_type: Option<UpdateType>)
-> <Self as ProvisioningServiceApi<'inp>>::Input;
}

Expand Down Expand Up @@ -649,7 +666,7 @@ impl<F: for<'a> Fetcher<'a>> ProvisioningClient for Client<F> {
}

fn tcbinfo(&self, fmspc: &Fmspc, tcb_evaluation_data_number: Option<u16>) -> Result<TcbInfo, Error> {
let input = self.tcbinfo_service.pcs_service().build_input(fmspc, tcb_evaluation_data_number);
let input = self.tcbinfo_service.pcs_service().build_input(fmspc, tcb_evaluation_data_number, None);
self.tcbinfo_service.call_service(&self.fetcher, &input)
}

Expand All @@ -659,7 +676,7 @@ impl<F: for<'a> Fetcher<'a>> ProvisioningClient for Client<F> {
}

fn qe_identity(&self, tcb_evaluation_data_number: Option<u16>) -> Result<QeIdentitySigned, Error> {
let input = self.qeid_service.pcs_service().build_input(tcb_evaluation_data_number);
let input = self.qeid_service.pcs_service().build_input(tcb_evaluation_data_number, None);
self.qeid_service.call_service(&self.fetcher, &input)
}

Expand Down
52 changes: 45 additions & 7 deletions intel-sgx/dcap-artifact-retrieval/src/provisioning_client/pccs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ use super::{
ProvisioningServiceApi, QeIdIn, QeIdService, StatusCode, TcbInfoIn, TcbInfoService,
};
use super::intel::TcbEvaluationDataNumbersApi;
use crate::Error;
use crate::{Error, UpdateType};

pub struct PccsProvisioningClientBuilder {
base_url: Cow<'static, str>,
Expand Down Expand Up @@ -273,11 +273,13 @@ impl<'inp> TcbInfoService<'inp> for TcbInfoApi {
&'inp self,
fmspc: &'inp Fmspc,
tcb_evaluation_data_number: Option<u16>,
update_type: Option<UpdateType>,
) -> <Self as ProvisioningServiceApi<'inp>>::Input {
TcbInfoIn {
api_version: self.api_version,
fmspc,
tcb_evaluation_data_number,
update_type: update_type.unwrap_or(UpdateType::Early),
}
}
}
Expand Down Expand Up @@ -360,10 +362,11 @@ impl QeIdApi {
}

impl<'inp> QeIdService<'inp> for QeIdApi {
fn build_input(&'inp self, tcb_evaluation_data_number: Option<u16>) -> <Self as ProvisioningServiceApi<'inp>>::Input {
fn build_input(&'inp self, tcb_evaluation_data_number: Option<u16>, update_type: Option<UpdateType>) -> <Self as ProvisioningServiceApi<'inp>>::Input {
QeIdIn {
api_version: self.api_version,
tcb_evaluation_data_number,
update_type: update_type.unwrap_or(UpdateType::Early),
}
}
}
Expand All @@ -384,8 +387,8 @@ impl<'inp> ProvisioningServiceApi<'inp> for QeIdApi {
)
} else {
format!(
"{}/sgx/certification/v{}/qe/identity?update=early",
self.base_url, api_version,
"{}/sgx/certification/v{}/qe/identity?update={}",
self.base_url, api_version, input.update_type.as_str(),
)
};
Ok((url, Vec::new()))
Expand Down Expand Up @@ -439,11 +442,12 @@ mod tests {
};

use super::Client;
use super::Error;
use crate::provisioning_client::{
test_helpers, DcapArtifactIssuer, PccsProvisioningClientBuilder, PcsVersion,
ProvisioningClient,
};
use crate::{reqwest_client_insecure_tls, ReqwestClient};
use crate::{reqwest_client_insecure_tls, ReqwestClient, UpdateType};

const PCKID_TEST_FILE: &str = "./tests/data/pckid_retrieval.csv";
const OUTPUT_TEST_DIR: &str = "./tests/data/";
Expand All @@ -467,6 +471,22 @@ mod tests {
.build(reqwest_client_insecure_tls())
}

fn get_qe_id_standard_tcb_evaluation_num(client: &Client<ReqwestClient>, root_cas: &[&[u8]]) -> Result<u64, Error> {
let input = client.qeid_service.pcs_service().build_input(None, Some(UpdateType::Standard));
let qe_id = client.qeid_service
.call_service(&client.fetcher, &input)?
.verify(root_cas, EnclaveIdentity::QE)?;
Ok(qe_id.tcb_evaluation_data_number())
}

fn get_tcb_info_standard_tcb_evaluation_num(client: &Client<ReqwestClient>, fmspc: &Fmspc, root_cas: &[&[u8]]) -> Result<u64, Error> {
let input = client.tcbinfo_service.pcs_service().build_input(fmspc, None, Some(UpdateType::Standard));
let tcb_info = client.tcbinfo_service
.call_service(&client.fetcher, &input)?
.verify(root_cas, Platform::SGX, 2)?;
Ok(tcb_info.tcb_evaluation_data_number())
}

#[test]
pub fn pck() {
for api_version in [PcsVersion::V3, PcsVersion::V4] {
Expand Down Expand Up @@ -635,6 +655,8 @@ mod tests {

#[test]
pub fn tcb_info_with_evaluation_data_number() {
let root_ca = include_bytes!("../../tests/data/root_SGX_CA_der.cert");
let root_cas = [&root_ca[..]];
let client = make_client(PcsVersion::V4);
for pckid in PckID::parse_file(&PathBuf::from(PCKID_TEST_FILE).as_path())
.unwrap()
Expand All @@ -652,8 +674,15 @@ mod tests {
.unwrap()
.evaluation_data_numbers()
.unwrap();
let standard_eval_num = get_tcb_info_standard_tcb_evaluation_num(&client, &fmspc, &root_cas).unwrap();

for number in evaluation_data_numbers.numbers() {
// API query with update="standard" will return TCB info with TCB Evaluation Data Number M.
// If the inputted TCB Evaluation Data Number is < M, Intel PCS will return a 410 Gone response.
// And PCCS currently return 404 Not Found since PCCS not yet has logic for handling 410 Gone responses.
if (number.number() as u64) < standard_eval_num {
continue;
}
assert!(client
.tcbinfo(&fmspc, Some(number.number()))
.and_then(|tcb| { Ok(tcb.store(OUTPUT_TEST_DIR).unwrap()) })
Expand Down Expand Up @@ -686,7 +715,7 @@ mod tests {
let input = client
.tcbinfo_service
.pcs_service()
.build_input(&fmspc, None);
.build_input(&fmspc, None, None);
input.hash(&mut hasher);

cache
Expand Down Expand Up @@ -783,7 +812,7 @@ mod tests {

let (cached_qeid, _) = {
let mut hasher = DefaultHasher::new();
let input = client.qeid_service.pcs_service().build_input(None);
let input = client.qeid_service.pcs_service().build_input(None, None);
input.hash(&mut hasher);

cache
Expand Down Expand Up @@ -817,7 +846,16 @@ mod tests {
let fmspc = Fmspc::try_from("90806f000000").unwrap();
let eval_numbers: TcbEvaluationDataNumbers =
eval_numbers.verify(&root_cas, Platform::SGX).unwrap();

let standard_eval_num = get_qe_id_standard_tcb_evaluation_num(&client, &root_cas).unwrap();

for number in eval_numbers.numbers().map(|n| n.number()) {
// API query with update="standard" will return QE Identity with TCB Evaluation Data Number M.
// If the inputted TCB Evaluation Data Number is < M, Intel PCS will return a 410 Gone response.
// And PCCS currently return 404 Not Found since PCCS not yet has logic for handling 410 Gone responses.
if (number as u64) < standard_eval_num {
continue;
}
let qe_id = client
.qe_identity(Some(number))
.unwrap()
Expand Down