Skip to content
Merged
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
85 changes: 70 additions & 15 deletions crates/collaterals/src/certs.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
use crate::{sgx_extensions::sgx_extensions_to_bytes, utils::gen_key};
use crate::{
sgx_extensions::{sgx_extensions_to_bytes, SgxExtensionsBuilder},
utils::gen_key,
};
use anyhow::bail;
use dcap_types::cert::SgxExtensions;
use dcap_types::cert::{
SgxExtensions, SGX_PCK_CERT_CN, SGX_PCK_PLATFORM_CA_CN, SGX_PCK_PROCESSOR_CA_CN,
};
use openssl::{
asn1::{Asn1Integer, Asn1Object, Asn1OctetString, Asn1Time},
bn::BigNum,
Expand All @@ -19,6 +24,17 @@ pub struct RootCa {
pub crl: X509Crl,
}

impl RootCa {
pub fn with_new_crl(&self, revoked_certs: Vec<X509>) -> Result<RootCa, anyhow::Error> {
let crl = gen_crl(&self.cert, &self.key, revoked_certs, None)?;
Ok(RootCa {
cert: self.cert.clone(),
key: self.key.clone(),
crl,
})
}
}

pub fn gen_sgx_intel_root_ca(
root_pkey: &PKey<Private>,
validity: Validity,
Expand Down Expand Up @@ -75,7 +91,7 @@ pub fn gen_root_ca(
&root_key,
root_cert_validity.unwrap_or_else(Validity::long_duration),
)?;
let crl = gen_crl(&root_cert, &root_key, &[], crl_validity)?;
let crl = gen_crl(&root_cert, &root_key, vec![], crl_validity)?;
Ok(RootCa {
cert: root_cert,
key: root_key,
Expand All @@ -86,7 +102,7 @@ pub fn gen_root_ca(
pub fn gen_crl(
issuer_cert: &X509Ref,
issuer_pkey: &PKeyRef<Private>,
revoked_certs: &[X509],
revoked_certs: Vec<X509>,
crl_validity: Option<Validity>,
) -> Result<X509Crl, anyhow::Error> {
let mut crl = X509Crl::new(issuer_cert, None)?;
Expand All @@ -95,7 +111,7 @@ pub fn gen_crl(
crl.set_next_update(&validity.not_after())?;
crl.increment_crl_number()?;
for cert in revoked_certs {
crl.revoke(cert)?;
crl.revoke(&cert)?;
}
crl.sign(issuer_pkey, MessageDigest::sha256())?;
Ok(crl)
Expand All @@ -104,7 +120,7 @@ pub fn gen_crl(
pub fn gen_crl_der(
issuer_cert: &X509Ref,
issuer_pkey: &PKeyRef<Private>,
revoked_certs: &[X509],
revoked_certs: Vec<X509>,
crl_validity: Option<Validity>,
) -> Result<Vec<u8>, anyhow::Error> {
Ok(gen_crl(issuer_cert, issuer_pkey, revoked_certs, crl_validity)?.to_der()?)
Expand Down Expand Up @@ -177,28 +193,33 @@ pub fn gen_tcb_certchain(
})
}

#[derive(Debug, Clone, Copy)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum PckCa {
Processor,
Platform,
}

impl PckCa {
/// Create a PckCa from the CN of the certificate
pub fn from_cn(cn: &str) -> Result<Self, anyhow::Error> {
match cn {
"Intel SGX PCK Processor CA" => Ok(PckCa::Processor),
"Intel SGX PCK Platform CA" => Ok(PckCa::Platform),
_ => bail!("Invalid PCK CA CN: {}", cn),
if cn == SGX_PCK_PROCESSOR_CA_CN {
Ok(PckCa::Processor)
} else if cn == SGX_PCK_PLATFORM_CA_CN {
Ok(PckCa::Platform)
} else {
bail!("Invalid PCK CA CN: {}", cn)
}
}

/// Get the CN of the PckCa
pub fn cn(&self) -> &'static str {
match self {
PckCa::Processor => "Intel SGX PCK Processor CA",
PckCa::Platform => "Intel SGX PCK Platform CA",
PckCa::Processor => SGX_PCK_PROCESSOR_CA_CN,
PckCa::Platform => SGX_PCK_PLATFORM_CA_CN,
}
}

/// Get the type of the PckCa
pub fn ca_type(&self) -> &'static str {
match self {
PckCa::Processor => "processor",
Expand Down Expand Up @@ -277,7 +298,7 @@ pub fn gen_pck_cert(
Asn1Integer::from_bn(BigNum::from_slice(calc_skid(pck_cert_pkey).as_slice())?.as_ref())?
.as_ref(),
)?;
builder.set_subject_name(build_x509_name("Intel SGX PCK Certificate")?.as_ref())?;
builder.set_subject_name(build_x509_name(SGX_PCK_CERT_CN)?.as_ref())?;
builder.set_pubkey(pck_cert_pkey)?;

builder.set_not_before(&validity.not_before())?;
Expand Down Expand Up @@ -326,6 +347,40 @@ pub struct PckCertchain {
pub pck_cert_crl: X509Crl,
}

impl PckCertchain {
/// Generate a new PCK certificate and CRL
/// If `revoked` is true, the `self.pck_cert`` will be revoked in the CRL
pub fn gen_new_pck_cert(&self, revoked: bool) -> PckCertchain {
let pck_cert_key = gen_key();
let pck_cert = gen_pck_cert(
&self.pck_cert_ca,
&self.pck_cert_ca_key,
&pck_cert_key,
&SgxExtensionsBuilder::new().build(),
Validity::new_with_duration(1, 60 * 60 * 24 * 365),
)
.unwrap();
let pck_cert_crl = gen_crl(
&self.pck_cert_ca,
&self.pck_cert_ca_key,
if revoked {
vec![self.pck_cert.clone()]
} else {
vec![]
},
None,
)
.unwrap();
PckCertchain {
pck_cert_ca: self.pck_cert_ca.clone(),
pck_cert_ca_key: self.pck_cert_ca_key.clone(),
pck_cert,
pck_cert_key,
pck_cert_crl,
}
}
}

/// Generate Intel SGX Root CA and PCK Processor/Platform CA and PCK certificates and private keys and CRLs for testing
pub fn gen_pck_certchain(
root_ca: &RootCa,
Expand Down Expand Up @@ -354,7 +409,7 @@ pub fn gen_pck_certchain(
let pck_cert_crl = gen_crl(
&pck_cert_ca,
&pck_cert_ca_key,
&[],
vec![],
pck_cert_ca_crl_validity,
)?;
Ok(PckCertchain {
Expand Down
2 changes: 1 addition & 1 deletion crates/quote-verifier/src/collaterals.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use crate::Result;
* IntelCollateral is a struct that holds the collateral data that is required to verify the
* authenticity of the quote. This includes the TCBInfo, QEIdentity, certificates and CRLs.
*/
#[derive(Clone, Debug)]
#[derive(Clone, Debug, Default)]
pub struct IntelCollateral {
/// TCBInfo in JSON format
/// ref. https://api.portal.trustedservices.intel.com/content/documentation.html#pcs-tcb-info-model-v3
Expand Down
Loading