Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor X.509 encoding library to use the der crate #351

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
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
4 changes: 2 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 16 additions & 0 deletions crypto/src/signer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,22 @@ pub struct EcdsaSig {
pub s: CryptoBuf,
}

pub const MAX_ENCODED_ECDSA_PUB: usize = 1 + (2 * CryptoBuf::MAX_SIZE);

#[derive(ZeroizeOnDrop)]
pub struct EncodedEcdsaPub(pub ArrayVec<u8, MAX_ENCODED_ECDSA_PUB>);

impl From<&EcdsaPub> for EncodedEcdsaPub {
fn from(value: &EcdsaPub) -> Self {
// PANIC FREE: Size of data is same is 1 + x_max + y_max
let mut encoded = EncodedEcdsaPub(ArrayVec::<u8, MAX_ENCODED_ECDSA_PUB>::new());
encoded.0.push(0x4);
encoded.0.try_extend_from_slice(value.x.bytes()).unwrap();
encoded.0.try_extend_from_slice(value.y.bytes()).unwrap();
encoded
}
}

/// An ECDSA public key
#[derive(ZeroizeOnDrop)]
pub struct EcdsaPub {
Expand Down
4 changes: 2 additions & 2 deletions dpe/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,20 +30,20 @@ caliptra-cfi-lib-git = { workspace = true, default-features = false, features =
caliptra-cfi-derive-git.workspace = true
constant_time_eq = "0.3.0"
crypto = {path = "../crypto", default-features = false}
der = { version = "0.7.9", default-features = false, features = ["derive"] }
platform = {path = "../platform", default-features = false}
ufmt = { git = "https://github.com/korran/ufmt.git", rev = "1d0743c1ffffc68bc05ca8eeb81c166192863f33", features = ["inline"] }
zerocopy.workspace = true
zeroize = { version = "1.6.0", default-features = false, features = ["zeroize_derive"] }
cfg-if = "1.0.0"

[dev-dependencies]
asn1 = "0.13.0"
asn1 = { version = "0.13.0", default-features = false}
caliptra-cfi-lib-git = { workspace = true, features = ["cfi-test"] }
openssl.workspace = true
x509-parser = "0.15.1"
crypto = {path = "../crypto", features = ["deterministic_rand", "openssl"]}
platform = {path = "../platform", default-features = false, features = ["openssl"]}
cms = "0.2.2"
der = "0.7.8"
spki = "0.7.2"
rand = "0.8.5"
5 changes: 3 additions & 2 deletions dpe/fuzz/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 8 additions & 8 deletions dpe/src/commands/certify_key.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use crate::{
dpe_instance::{DpeEnv, DpeInstance, DpeTypes},
response::{CertifyKeyResp, DpeErrorCode, Response, ResponseHdr},
tci::TciNodeData,
x509::{CertWriter, DirectoryString, MeasurementData, Name},
x509::{CertWriter, MeasurementData, Name},
DPE_PROFILE, MAX_CERT_SIZE, MAX_HANDLES,
};
use bitflags::bitflags;
Expand Down Expand Up @@ -116,8 +116,8 @@ impl CommandExecution for CertifyKeyCmd {
let truncated_subj_serial = &subj_serial[..64];

let subject_name = Name {
cn: DirectoryString::PrintableString(b"DPE Leaf"),
serial: DirectoryString::PrintableString(truncated_subj_serial),
cn: b"DPE Leaf",
serial: truncated_subj_serial,
};

// Get TCI Nodes
Expand Down Expand Up @@ -178,7 +178,7 @@ impl CommandExecution for CertifyKeyCmd {
let cert_validity = env.platform.get_cert_validity()?;
let mut bytes_written = tbs_writer.encode_ecdsa_tbs(
/*serial=*/
&subject_name.serial.bytes()[..20], // Serial number must be truncated to 20 bytes
&subject_name.serial[..20], // Serial number must be truncated to 20 bytes
&issuer_name[..issuer_len],
&subject_name,
&pub_key,
Expand Down Expand Up @@ -671,13 +671,13 @@ mod tests {
.unwrap();
let truncated_subj_serial = &subj_serial[..64];
let subject_name = Name {
cn: DirectoryString::PrintableString(b"DPE Leaf"),
serial: DirectoryString::PrintableString(truncated_subj_serial),
cn: b"DPE Leaf",
serial: truncated_subj_serial,
};
let expected_subject_name = format!(
"CN={}, serialNumber={}",
str::from_utf8(subject_name.cn.bytes()).unwrap(),
str::from_utf8(&subject_name.serial.bytes()).unwrap()
str::from_utf8(subject_name.cn).unwrap(),
str::from_utf8(&subject_name.serial).unwrap()
);
let actual_subject_name = cri.subject.to_string_with_registry(oid_registry()).unwrap();
assert_eq!(expected_subject_name, actual_subject_name);
Expand Down
1 change: 1 addition & 0 deletions dpe/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ pub mod validation;
use core::mem::size_of;
#[cfg(not(feature = "disable_internal_info"))]
use response::GetProfileResp;
mod oid;
pub mod tci;
pub mod x509;

Expand Down
71 changes: 71 additions & 0 deletions dpe/src/oid.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
use crate::{DpeProfile, DPE_PROFILE};

pub const ECDSA_OID: &'static [u8] = match DPE_PROFILE {
// ECDSA with SHA256
DpeProfile::P256Sha256 => &[0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x03, 0x02],
// ECDSA with SHA384
DpeProfile::P384Sha384 => &[0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x03, 0x03],
};

pub const EC_PUB_OID: &'static [u8] = &[0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x02, 0x01];

pub const CURVE_OID: &'static [u8] = match DPE_PROFILE {
// P256
DpeProfile::P256Sha256 => &[0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x01, 0x07],
// P384
DpeProfile::P384Sha384 => &[0x2B, 0x81, 0x04, 0x00, 0x22],
};

pub const HASH_OID: &'static [u8] = match DPE_PROFILE {
// SHA256
DpeProfile::P256Sha256 => &[0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01],
// SHA384
DpeProfile::P384Sha384 => &[0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02],
};

pub const RDN_COMMON_NAME_OID: &'static [u8] = &[0x55, 0x04, 0x03];
pub const RDN_SERIALNUMBER_OID: &'static [u8] = &[0x55, 0x04, 0x05];

// tcg-dice-MultiTcbInfo 2.23.133.5.4.5
pub const MULTI_TCBINFO_OID: &'static [u8] = &[0x67, 0x81, 0x05, 0x05, 0x04, 0x05];

// tcg-dice-Ueid 2.23.133.5.4.4
pub const UEID_OID: &'static [u8] = &[0x67, 0x81, 0x05, 0x05, 0x04, 0x04];

// tcg-dice-kp-eca 2.23.133.5.4.100.12
pub const ECA_OID: &'static [u8] = &[0x67, 0x81, 0x05, 0x05, 0x04, 0x64, 0x0C];

// tcg-dice-kp-attestLoc 2.23.133.5.4.100.9
pub const ATTEST_LOC_OID: &'static [u8] = &[0x67, 0x81, 0x05, 0x05, 0x04, 0x64, 0x09];

// RFC 5280 2.5.29.19
pub const BASIC_CONSTRAINTS_OID: &'static [u8] = &[0x55, 0x1D, 0x13];

// RFC 5280 2.5.29.15
pub const KEY_USAGE_OID: &'static [u8] = &[0x55, 0x1D, 0x0F];

// RFC 5280 2.5.29.37
pub const EXTENDED_KEY_USAGE_OID: &'static [u8] = &[0x55, 0x1D, 0x25];

// RFC 5280 2.5.29.14
pub const SUBJECT_KEY_IDENTIFIER_OID: &'static [u8] = &[0x55, 0x1D, 0x0E];

// RFC 5280 2.5.29.35
pub const AUTHORITY_KEY_IDENTIFIER_OID: &'static [u8] = &[0x55, 0x1D, 0x23];

// RFC 5280 2.5.29.17
pub const SUBJECT_ALTERNATIVE_NAME_OID: &'static [u8] = &[0x55, 0x1D, 0x11];

// RFC 5652 1.2.840.113549.1.7.2
#[cfg(not(feature = "disable_csr"))]
pub const ID_SIGNED_DATA_OID: &'static [u8] =
&[0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x02];

// RFC 5652 1.2.840.113549.1.7.1
#[cfg(not(feature = "disable_csr"))]
pub const ID_DATA_OID: &'static [u8] = &[0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x01];

// RFC 2985 1.2.840.113549.1.9.14
#[cfg(not(feature = "disable_csr"))]
pub const EXTENSION_REQUEST_OID: &'static [u8] =
&[0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x09, 0x0E];
14 changes: 12 additions & 2 deletions dpe/src/response.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@ Abstract:
DPE reponses and serialization.
--*/
use crate::{
context::ContextHandle, validation::ValidationError, CURRENT_PROFILE_MAJOR_VERSION,
CURRENT_PROFILE_MINOR_VERSION, DPE_PROFILE, MAX_CERT_SIZE, MAX_HANDLES,
context::ContextHandle, validation::ValidationError, x509::X509Error,
CURRENT_PROFILE_MAJOR_VERSION, CURRENT_PROFILE_MINOR_VERSION, DPE_PROFILE, MAX_CERT_SIZE,
MAX_HANDLES,
};
use crypto::CryptoError;
use platform::PlatformError;
Expand Down Expand Up @@ -151,6 +152,7 @@ pub enum DpeErrorCode {
Platform(PlatformError) = 0x01000000,
Crypto(CryptoError) = 0x02000000,
Validation(ValidationError) = 0x03000000,
X509(X509Error) = 0x04000000,
}

impl From<PlatformError> for DpeErrorCode {
Expand All @@ -165,6 +167,12 @@ impl From<CryptoError> for DpeErrorCode {
}
}

impl From<X509Error> for DpeErrorCode {
fn from(e: X509Error) -> Self {
DpeErrorCode::X509(e)
}
}

impl DpeErrorCode {
/// Get the spec-defined numeric error code. This does not include the
/// extended error information returned from the Platform and Crypto
Expand All @@ -181,6 +189,7 @@ impl DpeErrorCode {
DpeErrorCode::Platform(e) => self.discriminant() | e.discriminant() as u32,
DpeErrorCode::Crypto(e) => self.discriminant() | e.discriminant() as u32,
DpeErrorCode::Validation(e) => self.discriminant() | e.discriminant() as u32,
DpeErrorCode::X509(e) => self.discriminant() | e.discriminant() as u32,
_ => self.discriminant(),
}
}
Expand All @@ -194,6 +203,7 @@ impl DpeErrorCode {
match self {
DpeErrorCode::Platform(e) => e.get_error_detail(),
DpeErrorCode::Crypto(e) => e.get_error_detail(),
DpeErrorCode::X509(e) => e.get_error_detail(),
_ => None,
}
}
Expand Down
Loading