Skip to content

Commit 1ad2a64

Browse files
committed
Refactor X.509 encoding library to use the der crate
The der crate-based implementation is significantly less code and follows a more consistent pattern. Since this allows defining types with encoding rules, this will make it much simpler to add structures for ML-DSA structures for Caliptra 2.0. The der crate is part of RustCrypto and is intended to be embedded/no_std friendly.
1 parent 2e02db5 commit 1ad2a64

File tree

7 files changed

+1046
-1849
lines changed

7 files changed

+1046
-1849
lines changed

Cargo.lock

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crypto/src/signer.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,22 @@ pub struct EcdsaSig {
1010
pub s: CryptoBuf,
1111
}
1212

13+
pub const MAX_ENCODED_ECDSA_PUB: usize = 1 + (2 * CryptoBuf::MAX_SIZE);
14+
15+
#[derive(ZeroizeOnDrop)]
16+
pub struct EncodedEcdsaPub(pub ArrayVec<u8, MAX_ENCODED_ECDSA_PUB>);
17+
18+
impl From<&EcdsaPub> for EncodedEcdsaPub {
19+
fn from(value: &EcdsaPub) -> Self {
20+
// PANIC FREE: Size of data is same is 1 + x_max + y_max
21+
let mut encoded = EncodedEcdsaPub(ArrayVec::<u8, MAX_ENCODED_ECDSA_PUB>::new());
22+
encoded.0.push(0x4);
23+
encoded.0.try_extend_from_slice(value.x.bytes()).unwrap();
24+
encoded.0.try_extend_from_slice(value.y.bytes()).unwrap();
25+
encoded
26+
}
27+
}
28+
1329
/// An ECDSA public key
1430
#[derive(ZeroizeOnDrop)]
1531
pub struct EcdsaPub {

dpe/Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,14 +30,15 @@ caliptra-cfi-lib-git = { workspace = true, default-features = false, features =
3030
caliptra-cfi-derive-git.workspace = true
3131
constant_time_eq = "0.3.0"
3232
crypto = {path = "../crypto", default-features = false}
33+
der = { version = "0.7.9", default-features = false, features = ["oid", "derive"] }
3334
platform = {path = "../platform", default-features = false}
3435
ufmt = { git = "https://github.com/korran/ufmt.git", rev = "1d0743c1ffffc68bc05ca8eeb81c166192863f33", features = ["inline"] }
3536
zerocopy.workspace = true
3637
zeroize = { version = "1.6.0", default-features = false, features = ["zeroize_derive"] }
3738
cfg-if = "1.0.0"
3839

3940
[dev-dependencies]
40-
asn1 = "0.13.0"
41+
asn1 = { version = "0.13.0", default-features = false}
4142
caliptra-cfi-lib-git = { workspace = true, features = ["cfi-test"] }
4243
openssl.workspace = true
4344
x509-parser = "0.15.1"

dpe/fuzz/Cargo.lock

Lines changed: 3 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dpe/src/commands/certify_key.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use crate::{
55
dpe_instance::{DpeEnv, DpeInstance, DpeTypes},
66
response::{CertifyKeyResp, DpeErrorCode, Response, ResponseHdr},
77
tci::TciNodeData,
8-
x509::{CertWriter, DirectoryString, MeasurementData, Name},
8+
x509::{CertWriter, MeasurementData, Name},
99
DPE_PROFILE, MAX_CERT_SIZE, MAX_HANDLES,
1010
};
1111
use bitflags::bitflags;
@@ -116,8 +116,8 @@ impl CommandExecution for CertifyKeyCmd {
116116
let truncated_subj_serial = &subj_serial[..64];
117117

118118
let subject_name = Name {
119-
cn: DirectoryString::PrintableString(b"DPE Leaf"),
120-
serial: DirectoryString::PrintableString(truncated_subj_serial),
119+
cn: b"DPE Leaf",
120+
serial: truncated_subj_serial,
121121
};
122122

123123
// Get TCI Nodes
@@ -178,7 +178,7 @@ impl CommandExecution for CertifyKeyCmd {
178178
let cert_validity = env.platform.get_cert_validity()?;
179179
let mut bytes_written = tbs_writer.encode_ecdsa_tbs(
180180
/*serial=*/
181-
&subject_name.serial.bytes()[..20], // Serial number must be truncated to 20 bytes
181+
&subject_name.serial[..20], // Serial number must be truncated to 20 bytes
182182
&issuer_name[..issuer_len],
183183
&subject_name,
184184
&pub_key,
@@ -671,13 +671,13 @@ mod tests {
671671
.unwrap();
672672
let truncated_subj_serial = &subj_serial[..64];
673673
let subject_name = Name {
674-
cn: DirectoryString::PrintableString(b"DPE Leaf"),
675-
serial: DirectoryString::PrintableString(truncated_subj_serial),
674+
cn: b"DPE Leaf",
675+
serial: truncated_subj_serial,
676676
};
677677
let expected_subject_name = format!(
678678
"CN={}, serialNumber={}",
679-
str::from_utf8(subject_name.cn.bytes()).unwrap(),
680-
str::from_utf8(&subject_name.serial.bytes()).unwrap()
679+
str::from_utf8(subject_name.cn).unwrap(),
680+
str::from_utf8(&subject_name.serial).unwrap()
681681
);
682682
let actual_subject_name = cri.subject.to_string_with_registry(oid_registry()).unwrap();
683683
assert_eq!(expected_subject_name, actual_subject_name);

dpe/src/response.rs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,9 @@ Abstract:
55
DPE reponses and serialization.
66
--*/
77
use crate::{
8-
context::ContextHandle, validation::ValidationError, CURRENT_PROFILE_MAJOR_VERSION,
9-
CURRENT_PROFILE_MINOR_VERSION, DPE_PROFILE, MAX_CERT_SIZE, MAX_HANDLES,
8+
context::ContextHandle, validation::ValidationError, x509::X509Error,
9+
CURRENT_PROFILE_MAJOR_VERSION, CURRENT_PROFILE_MINOR_VERSION, DPE_PROFILE, MAX_CERT_SIZE,
10+
MAX_HANDLES,
1011
};
1112
use crypto::CryptoError;
1213
use platform::PlatformError;
@@ -151,6 +152,7 @@ pub enum DpeErrorCode {
151152
Platform(PlatformError) = 0x01000000,
152153
Crypto(CryptoError) = 0x02000000,
153154
Validation(ValidationError) = 0x03000000,
155+
X509(X509Error) = 0x04000000,
154156
}
155157

156158
impl From<PlatformError> for DpeErrorCode {
@@ -165,6 +167,12 @@ impl From<CryptoError> for DpeErrorCode {
165167
}
166168
}
167169

170+
impl From<X509Error> for DpeErrorCode {
171+
fn from(e: X509Error) -> Self {
172+
DpeErrorCode::X509(e)
173+
}
174+
}
175+
168176
impl DpeErrorCode {
169177
/// Get the spec-defined numeric error code. This does not include the
170178
/// extended error information returned from the Platform and Crypto
@@ -181,6 +189,7 @@ impl DpeErrorCode {
181189
DpeErrorCode::Platform(e) => self.discriminant() | e.discriminant() as u32,
182190
DpeErrorCode::Crypto(e) => self.discriminant() | e.discriminant() as u32,
183191
DpeErrorCode::Validation(e) => self.discriminant() | e.discriminant() as u32,
192+
DpeErrorCode::X509(e) => self.discriminant() | e.discriminant() as u32,
184193
_ => self.discriminant(),
185194
}
186195
}
@@ -194,6 +203,7 @@ impl DpeErrorCode {
194203
match self {
195204
DpeErrorCode::Platform(e) => e.get_error_detail(),
196205
DpeErrorCode::Crypto(e) => e.get_error_detail(),
206+
DpeErrorCode::X509(e) => e.get_error_detail(),
197207
_ => None,
198208
}
199209
}

0 commit comments

Comments
 (0)