Skip to content

Commit a8e7698

Browse files
committed
Port pcs changes
1 parent 52c797d commit a8e7698

File tree

4 files changed

+70
-52
lines changed

4 files changed

+70
-52
lines changed

intel-sgx/dcap-artifact-retrieval/src/provisioning_client/intel.rs

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
//! - <https://download.01.org/intel-sgx/dcap-1.1/linux/docs/Intel_SGX_PCK_Certificate_CRL_Spec-1.1.pdf>
1212
1313
use pcs::{
14-
CpuSvn, EncPpid, PceId, PceIsvsvn, PckCert, PckCerts, PckCrl, QeId, QeIdentitySigned, TcbInfo,
14+
CpuSvn, EncPpid, Fmspc, PceId, PceIsvsvn, PckCert, PckCerts, PckCrl, QeId, QeIdentitySigned, TcbInfo,
1515
Unverified,
1616
};
1717
use percent_encoding::percent_decode;
@@ -331,7 +331,7 @@ impl TcbInfoApi {
331331
impl<'inp> TcbInfoService<'inp> for TcbInfoApi {
332332
fn build_input(
333333
&'inp self,
334-
fmspc: &'inp Vec<u8>,
334+
fmspc: &'inp Fmspc,
335335
) -> <Self as ProvisioningServiceApi<'inp>>::Input {
336336
TcbInfoIn {
337337
api_version: self.api_version.clone(),
@@ -348,7 +348,7 @@ impl<'inp> ProvisioningServiceApi<'inp> for TcbInfoApi {
348348

349349
fn build_request(&self, input: &Self::Input) -> Result<(String, Vec<(String, String)>), Error> {
350350
let api_version = input.api_version as u8;
351-
let fmspc = input.fmspc.to_hex();
351+
let fmspc = input.fmspc.as_bytes().to_hex();
352352
let url = format!(
353353
"https://api.trustedservices.intel.com/sgx/certification/v{}/tcb?fmspc={fmspc}",
354354
api_version
@@ -631,6 +631,8 @@ mod tests {
631631
#[test]
632632
pub fn pck_cached() {
633633
for api_version in [PcsVersion::V3, PcsVersion::V4] {
634+
let root_ca = include_bytes!("../../tests/data/root_SGX_CA_der.cert");
635+
let root_cas = [&root_ca[..]];
634636
let mut intel_builder = IntelProvisioningClientBuilder::new(api_version)
635637
.set_retry_timeout(TIME_RETRY_TIMEOUT);
636638
if api_version == PcsVersion::V3 {
@@ -650,6 +652,7 @@ mod tests {
650652
None,
651653
)
652654
.unwrap();
655+
let pck = pck.verify(&root_cas).unwrap();
653656

654657
// The cache should be populated after initial service call
655658
{
@@ -674,7 +677,7 @@ mod tests {
674677
.to_owned()
675678
};
676679

677-
assert_eq!(pck.fmspc().unwrap(), cached_pck.fmspc().unwrap());
680+
assert_eq!(pck.fmspc().unwrap(), cached_pck.clone().verify(&root_cas).unwrap().fmspc().unwrap());
678681
assert_eq!(pck.ca_chain(), cached_pck.ca_chain());
679682
}
680683

@@ -689,7 +692,7 @@ mod tests {
689692
)
690693
.unwrap();
691694

692-
assert_eq!(pck.fmspc().unwrap(), pck_from_service.fmspc().unwrap());
695+
assert_eq!(pck.fmspc().unwrap(), pck_from_service.clone().verify(&root_cas).unwrap().fmspc().unwrap());
693696
assert_eq!(pck.ca_chain(), pck_from_service.ca_chain());
694697
}
695698
}

intel-sgx/dcap-artifact-retrieval/src/provisioning_client/mod.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use std::time::{Duration, SystemTime};
1414
use lru_cache::LruCache;
1515
use num_enum::TryFromPrimitive;
1616
use pcs::{
17-
CpuSvn, EncPpid, PceId, PceIsvsvn, PckCert, PckCerts, PckCrl, QeId, QeIdentitySigned, TcbInfo,
17+
CpuSvn, EncPpid, Fmspc, PceId, PceIsvsvn, PckCert, PckCerts, PckCrl, QeId, QeIdentitySigned, TcbInfo,
1818
Unverified,
1919
};
2020
#[cfg(feature = "reqwest")]
@@ -218,7 +218,7 @@ pub trait QeIdService<'inp>:
218218
#[derive(Hash)]
219219
pub struct TcbInfoIn<'i> {
220220
pub(crate) api_version: PcsVersion,
221-
pub(crate) fmspc: &'i Vec<u8>,
221+
pub(crate) fmspc: &'i Fmspc,
222222
}
223223

224224
impl WithApiVersion for TcbInfoIn<'_> {
@@ -232,7 +232,7 @@ pub trait TcbInfoService<'inp>:
232232
{
233233
fn build_input(
234234
&'inp self,
235-
fmspc: &'inp Vec<u8>,
235+
fmspc: &'inp Fmspc,
236236
) -> <Self as ProvisioningServiceApi<'inp>>::Input;
237237
}
238238

@@ -524,7 +524,7 @@ pub trait ProvisioningClient {
524524
qe_id: Option<&QeId>,
525525
) -> Result<PckCert<Unverified>, Error>;
526526

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

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

@@ -558,7 +558,7 @@ impl<F: for<'a> Fetcher<'a>> ProvisioningClient for Client<F> {
558558
self.pckcert_service.call_service(&self.fetcher, &input)
559559
}
560560

561-
fn tcbinfo(&self, fmspc: &Vec<u8>) -> Result<TcbInfo, Error> {
561+
fn tcbinfo(&self, fmspc: &Fmspc) -> Result<TcbInfo, Error> {
562562
let input = self.tcbinfo_service.pcs_service().build_input(fmspc);
563563
self.tcbinfo_service.call_service(&self.fetcher, &input)
564564
}

intel-sgx/pcs/src/pckcrt.rs

Lines changed: 21 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ use {
3030
};
3131

3232
use crate::io::{self};
33-
use crate::tcb_info::{TcbData, TcbLevel};
33+
use crate::tcb_info::{Fmspc, TcbData, TcbLevel};
3434
use crate::{CpuSvn, Error, Unverified, VerificationType, Verified};
3535

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

298-
pub fn fmspc(&self) -> Result<Vec<u8>, Error> {
298+
pub fn fmspc(&self) -> Result<Fmspc, Error> {
299299
let pck = self.iter().nth(0).ok_or(Error::NoPckCertData)?;
300300
let sgx_extension = SGXPCKCertificateExtension::try_from(pck).map_err(|e| Error::InvalidPckFormat(e))?;
301301
Ok(sgx_extension.fmspc)
@@ -458,6 +458,16 @@ impl PckCert<Verified> {
458458
let pk = cert.public_key();
459459
pk.ec_public()
460460
}
461+
462+
pub fn ppid(&self) -> Result<Vec<u8>, ASN1Error> {
463+
let extension = self.sgx_extension()?;
464+
Ok(extension.ppid)
465+
}
466+
467+
pub fn fmspc(&self) -> Result<Fmspc, ASN1Error> {
468+
let extension = self.sgx_extension()?;
469+
Ok(extension.fmspc)
470+
}
461471
}
462472

463473
impl<V: VerificationType> PckCert<V> {
@@ -536,11 +546,6 @@ impl<V: VerificationType> PckCert<V> {
536546
Err(Error::InvalidPck("PckCert isn't valid for provided TCB".into()))
537547
}
538548
}
539-
540-
pub fn fmspc(&self) -> Result<Vec<u8>, Error> {
541-
let sgx_extension = self.sgx_extension().map_err(|e| Error::InvalidPckFormat(e))?;
542-
Ok(sgx_extension.fmspc)
543-
}
544549
}
545550

546551
#[derive(Default, Debug)]
@@ -624,12 +629,12 @@ impl BERDecodable for SGXPlatformConfiguration {
624629
}
625630
}
626631

627-
#[derive(Default, Debug)]
632+
#[derive(Debug)]
628633
pub struct SGXPCKCertificateExtension {
629634
pub ppid: Vec<u8>,
630635
pub tcb: PlatformTCB,
631636
pub pceid: u16,
632-
pub fmspc: Vec<u8>,
637+
pub fmspc: Fmspc,
633638
pub sgx_type: SGXType,
634639
pub platform_instance_id: Option<Vec<u8>>,
635640
pub configuration: Option<SGXPlatformConfiguration>,
@@ -679,11 +684,8 @@ impl SGXPCKCertificateExtension {
679684
configuration = Some(reader.next(|reader| SGXPlatformConfiguration::decode_ber(reader))?);
680685
}
681686

682-
if ppid.len() != 16
683-
|| pceid.len() != 2
684-
|| fmspc.len() != 6
685-
|| platform_instance_id.as_ref().map_or(false, |id| id.len() != 16)
686-
{
687+
let fmspc = Fmspc::try_from(&fmspc).map_err(|_| ASN1Error::new(ASN1ErrorKind::Invalid))?;
688+
if ppid.len() != 16 || pceid.len() != 2 || platform_instance_id.as_ref().map_or(false, |id| id.len() != 16) {
687689
return Err(ASN1Error::new(ASN1ErrorKind::Invalid));
688690
}
689691

@@ -921,7 +923,7 @@ mod tests {
921923
assert_eq!(sgx_extension.tcb.tcb_components.0.pcesvn, 9);
922924
assert_eq!(sgx_extension.tcb.cpusvn, [13, 13, 2, 4, 1, 128, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
923925
assert_eq!(sgx_extension.pceid, 0);
924-
assert_eq!(sgx_extension.fmspc, [0, 144, 110, 161, 0, 0]);
926+
assert_eq!(sgx_extension.fmspc, Fmspc::new([0, 144, 110, 161, 0, 0]));
925927
assert_eq!(sgx_extension.sgx_type, SGXType::Standard);
926928
assert!(sgx_extension.platform_instance_id.is_none());
927929
assert!(sgx_extension.configuration.is_none());
@@ -957,7 +959,7 @@ mod tests {
957959
assert_eq!(sgx_extension.tcb.tcb_components.0.pcesvn, 10);
958960
assert_eq!(sgx_extension.tcb.cpusvn, [3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
959961
assert_eq!(sgx_extension.pceid, 0);
960-
assert_eq!(sgx_extension.fmspc, [16, 96, 106, 0, 0, 0]);
962+
assert_eq!(sgx_extension.fmspc, Fmspc::new([16, 96, 106, 0, 0, 0]));
961963
assert_eq!(sgx_extension.sgx_type, SGXType::Scalable);
962964
assert_eq!(
963965
sgx_extension.platform_instance_id.unwrap(),
@@ -998,7 +1000,7 @@ mod tests {
9981000
assert_eq!(sgx_extension.tcb.tcb_components.0.pcesvn, 9);
9991001
assert_eq!(sgx_extension.tcb.cpusvn, [13, 13, 2, 4, 1, 128, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
10001002
assert_eq!(sgx_extension.pceid, 0);
1001-
assert_eq!(sgx_extension.fmspc, [0, 144, 110, 161, 0, 0]);
1003+
assert_eq!(sgx_extension.fmspc, Fmspc::new([0, 144, 110, 161, 0, 0]));
10021004
}
10031005
}
10041006

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

10161018
#[test]
@@ -1041,7 +1043,7 @@ mod tests {
10411043
assert_eq!(sgx_extension.tcb.tcb_components.0.pcesvn, 10);
10421044
assert_eq!(sgx_extension.tcb.cpusvn, [14, 14, 2, 4, 1, 128, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
10431045
assert_eq!(sgx_extension.pceid, 0);
1044-
assert_eq!(sgx_extension.fmspc, [0, 144, 110, 161, 0, 0]);
1046+
assert_eq!(sgx_extension.fmspc, Fmspc::new([0, 144, 110, 161, 0, 0]));
10451047
}
10461048

10471049
#[test]

intel-sgx/pcs/src/tcb_info.rs

Lines changed: 36 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,7 @@ use std::convert::TryFrom;
99
use std::marker::PhantomData;
1010
use std::path::PathBuf;
1111

12-
use base16::DecodeError as Base16DecodeError;
13-
use serde::{Deserialize, Deserializer, Serialize, Serializer};
14-
use serde::de::Error as _;
12+
use serde::{de, Deserialize, Deserializer, Serialize, Serializer};
1513
use serde_json::value::RawValue;
1614
#[cfg(feature = "verify")]
1715
use {
@@ -22,7 +20,7 @@ use {
2220
use crate::pckcrt::TcbComponents;
2321
use crate::{io, Error, TcbStatus, Unverified, VerificationType, Verified};
2422

25-
#[derive(Debug, Clone, PartialEq, Eq)]
23+
#[derive(Debug, Clone, Hash, PartialEq, Eq)]
2624
pub struct Fmspc([u8; 6]);
2725

2826
#[derive(Debug)]
@@ -31,8 +29,8 @@ pub enum FmspcDecodeError {
3129
InvalidFmspcLength,
3230
}
3331

34-
impl From<Base16DecodeError> for FmspcDecodeError {
35-
fn from(_value: Base16DecodeError) -> FmspcDecodeError {
32+
impl From<base16::DecodeError> for FmspcDecodeError {
33+
fn from(_value: base16::DecodeError) -> FmspcDecodeError {
3634
FmspcDecodeError::InvalidHex
3735
}
3836
}
@@ -62,6 +60,14 @@ impl TryFrom<&[u8]> for Fmspc {
6260
}
6361
}
6462

63+
impl TryFrom<&Vec<u8>> for Fmspc {
64+
type Error = FmspcDecodeError;
65+
66+
fn try_from(value: &Vec<u8>) -> Result<Fmspc, FmspcDecodeError> {
67+
Fmspc::try_from(value.as_slice())
68+
}
69+
}
70+
6571
impl TryFrom<&str> for Fmspc {
6672
type Error = FmspcDecodeError;
6773

@@ -71,6 +77,14 @@ impl TryFrom<&str> for Fmspc {
7177
}
7278
}
7379

80+
impl TryFrom<&String> for Fmspc {
81+
type Error = FmspcDecodeError;
82+
83+
fn try_from(value: &String) -> Result<Fmspc, FmspcDecodeError> {
84+
Fmspc::try_from(value.as_str())
85+
}
86+
}
87+
7488
impl ToString for Fmspc {
7589
fn to_string(&self) -> String {
7690
base16::encode_lower(&self.0)
@@ -91,8 +105,8 @@ impl<'de> Deserialize<'de> for Fmspc {
91105
where
92106
D: Deserializer<'de>,
93107
{
94-
let fmspc = <&str>::deserialize(deserializer)?;
95-
Fmspc::try_from(fmspc).map_err(|_| D::Error::custom("Bad fmspc format"))
108+
let fmspc = String::deserialize(deserializer)?;
109+
Fmspc::try_from(&fmspc).map_err(|_| de::Error::custom("Bad fmspc format"))
96110
}
97111
}
98112

@@ -123,7 +137,7 @@ pub struct TcbData<V: VerificationType = Verified> {
123137
version: u16,
124138
issue_date: String,
125139
next_update: String,
126-
fmspc: String,
140+
fmspc: Fmspc,
127141
pce_id: String,
128142
tcb_type: u16,
129143
tcb_evaluation_data_number: u64,
@@ -144,7 +158,7 @@ impl<'de> Deserialize<'de> for TcbData<Unverified> {
144158
version: u16,
145159
issue_date: String,
146160
next_update: String,
147-
fmspc: String,
161+
fmspc: Fmspc,
148162
pce_id: String,
149163
tcb_type: u16,
150164
tcb_evaluation_data_number: u64,
@@ -179,7 +193,7 @@ impl<'de> Deserialize<'de> for TcbData<Unverified> {
179193
}
180194

181195
impl TcbData<Verified> {
182-
pub fn fmspc(&self) -> &str {
196+
pub fn fmspc(&self) -> &Fmspc {
183197
&self.fmspc
184198
}
185199
}
@@ -250,20 +264,19 @@ impl TcbInfo {
250264

251265
pub fn store(&self, output_dir: &str) -> Result<String, Error> {
252266
let data = TcbData::<Unverified>::parse(&self.raw_tcb_info)?;
253-
let filename = Self::create_filename(&data.fmspc);
267+
let filename = Self::create_filename(&data.fmspc.to_string());
254268
io::write_to_file(&self, output_dir, &filename)?;
255269
Ok(filename)
256270
}
257271

258272
pub fn store_if_not_exist(&self, output_dir: &str) -> Result<Option<PathBuf>, Error> {
259273
let data = TcbData::<Unverified>::parse(&self.raw_tcb_info)?;
260-
let filename = Self::create_filename(&data.fmspc);
274+
let filename = Self::create_filename(&data.fmspc.to_string());
261275
io::write_to_file_if_not_exist(&self, output_dir, &filename)
262276
}
263277

264-
pub fn restore(input_dir: &str, fmspc: &[u8]) -> Result<Self, Error> {
265-
let fmspc = &base16::encode_lower(&fmspc);
266-
let filename = TcbInfo::create_filename(fmspc);
278+
pub fn restore(input_dir: &str, fmspc: &Fmspc) -> Result<Self, Error> {
279+
let filename = TcbInfo::create_filename(&fmspc.to_string());
267280
let info: TcbInfo = io::read_from_file(input_dir, &filename)?;
268281
Ok(info)
269282
}
@@ -352,16 +365,16 @@ impl TcbInfo {
352365
#[cfg(test)]
353366
mod tests {
354367
#[cfg(not(target_env = "sgx"))]
355-
use crate::tcb_info::TcbInfo;
368+
use {
369+
crate::tcb_info::{Fmspc, TcbInfo},
370+
std::convert::TryFrom,
371+
};
356372

357373
#[test]
358374
#[cfg(not(target_env = "sgx"))]
359375
fn read_tcb_info() {
360-
let info = TcbInfo::restore(
361-
"./tests/data/",
362-
&base16::decode("00906ea10000".as_bytes()).expect("validated"),
363-
)
364-
.expect("validated");
376+
let info =
377+
TcbInfo::restore("./tests/data/", &Fmspc::try_from("00906ea10000").expect("static fmspc")).expect("validated");
365378
let root_certificate = include_bytes!("../tests/data/root_SGX_CA_der.cert");
366379
let root_certificates = [&root_certificate[..]];
367380
assert!(info.verify(&root_certificates).is_ok());
@@ -370,7 +383,7 @@ mod tests {
370383
#[test]
371384
#[cfg(not(target_env = "sgx"))]
372385
fn read_corrupt_tcb_info() {
373-
let tcb_info = TcbInfo::restore("./tests/data/corrupted", &base16::decode("00906ea10000".as_bytes()).unwrap()).unwrap();
386+
let tcb_info = TcbInfo::restore("./tests/data/corrupted", &Fmspc::try_from("00906ea10000").unwrap()).unwrap();
374387
let root_certificate = include_bytes!("../tests/data/root_SGX_CA_der.cert");
375388
let root_certificates = [&root_certificate[..]];
376389
assert!(tcb_info.verify(&root_certificates).is_err());

0 commit comments

Comments
 (0)