Skip to main content

ComidBuilder

Struct ComidBuilder 

Source
pub struct ComidBuilder { /* private fields */ }
Expand description

Builder for constructing a ComidTag (CoMID).

Accepts a caller-provided tag-id and allows adding any combination of the nine triple types defined by the RFC. At least one triple must be present for build to succeed.

Implementations§

Source§

impl ComidBuilder

Source

pub fn new(tag_id: TagIdChoice) -> Self

Create a new builder with the given tag identifier.

The tag identifier must be globally unique per §5.1.1.1.

Examples found in repository?
examples/build_corim.rs (lines 39-41)
14fn main() {
15    // Define the target environment
16    let env = EnvironmentMap {
17        class: Some(ClassMap {
18            class_id: None,
19            vendor: Some("ACME Corp".into()),
20            model: Some("Turbo Encabulator".into()),
21            layer: Some(0),
22            index: None,
23        }),
24        instance: None,
25        group: None,
26    };
27
28    // Create a measurement with a SHA-384 digest
29    let measurement = MeasurementMap {
30        mkey: Some(MeasuredElement::Text("firmware".into())),
31        mval: MeasurementValuesMap {
32            digests: Some(vec![Digest::new(7, vec![0xAA; 48])]),
33            ..MeasurementValuesMap::default()
34        },
35        authorized_by: None,
36    };
37
38    // Build a CoMID
39    let comid = ComidBuilder::new(TagIdChoice::Text(
40        "example.com/acme/turbo-encabulator".into(),
41    ))
42    .set_tag_version(0)
43    .add_entity(EntityMap {
44        entity_name: "ACME Corp".into(),
45        reg_id: Some("https://acme.example.com".into()),
46        role: vec![COMID_ROLE_TAG_CREATOR],
47    })
48    .add_reference_triple(ReferenceTriple::new(env, vec![measurement]))
49    .build()
50    .expect("failed to build CoMID");
51
52    // Wrap in a CoRIM and encode
53    let bytes = CorimBuilder::new(CorimId::Text("acme/corim/v1".into()))
54        .set_profile(ProfileChoice::Uri(
55            "https://example.com/acme-profile".into(),
56        ))
57        .set_validity(Some(1700000000), 1900000000)
58        .unwrap()
59        .add_comid_tag(comid)
60        .expect("failed to encode CoMID")
61        .build_bytes()
62        .expect("failed to build CoRIM");
63
64    println!("Encoded CoRIM: {} bytes", bytes.len());
65    println!(
66        "Hex: {}",
67        bytes
68            .iter()
69            .map(|b| format!("{:02x}", b))
70            .collect::<String>()
71    );
72}
More examples
Hide additional examples
examples/build_corim_ovl3_tdisp_ndpa.rs (line 94)
68fn main() {
69    use corim::builder::{ComidBuilder, CorimBuilder};
70    use corim::profile::azure::{AzureProfile, AZURE_PROFILE_URI};
71    use corim::profile::MatchContext;
72    use corim::types::common::TagIdChoice;
73    use corim::types::corim::{CorimId, ProfileChoice};
74    use corim::types::measurement::{MeasurementMap, MeasurementValuesMap, SvnChoice};
75    use corim::types::triples::{
76        CesCommonCondition, ConditionalEndorsementSeriesTriple, ConditionalSeriesRecord,
77    };
78    use corim::validate::{
79        apply_endorsement_series_with_profile, decode_and_validate_at, EvidenceClaim,
80    };
81
82    let ces = ConditionalEndorsementSeriesTriple::new(
83        CesCommonCondition {
84            environment: make_env(),
85            claims_list: vec![],
86            authorized_by: None,
87        },
88        vec![ConditionalSeriesRecord::new(
89            vec![uint_svn_selection(20, 1)],
90            vec![make_addition_uptodate()],
91        )],
92    );
93
94    let comid = ComidBuilder::new(TagIdChoice::Text("1.3.6.1.4.1.311.102.5_NDPA".into()))
95        .add_conditional_endorsement_series(ces)
96        .build()
97        .expect("failed to build CoMID");
98
99    let bytes = CorimBuilder::new(CorimId::Text("1.3.6.1.4.1.311.102.5_NDPA_20260705".into()))
100        .set_profile(ProfileChoice::Uri(AZURE_PROFILE_URI.into()))
101        .add_comid_tag(comid)
102        .expect("failed to encode CoMID")
103        .build_bytes()
104        .expect("failed to build CoRIM");
105
106    let (_corim, comids) =
107        decode_and_validate_at(&bytes, 1_800_000_000).expect("decode_and_validate_at failed");
108    let decoded = &comids[0];
109
110    let profile = AzureProfile::new();
111    let evidence = vec![EvidenceClaim {
112        environment: decoded
113            .triples
114            .conditional_endorsement_series
115            .as_ref()
116            .unwrap()[0]
117            .common_condition()
118            .environment
119            .clone(),
120        measurements: vec![MeasurementMap {
121            mkey: Some(corim::types::common::MeasuredElement::Uint(20)),
122            mval: MeasurementValuesMap {
123                svn: Some(SvnChoice::ExactValue(1)),
124                ..MeasurementValuesMap::default()
125            },
126            authorized_by: None,
127        }],
128    }];
129
130    let ces_endorsed = apply_endorsement_series_with_profile(
131        decoded
132            .triples
133            .conditional_endorsement_series
134            .as_deref()
135            .unwrap(),
136        &evidence,
137        Some(&profile),
138        &MatchContext::new(),
139    )
140    .expect("apply_endorsement_series_with_profile failed");
141    let out = write_cbor_file(&bytes);
142    println!("CES endorsed claims: {}", ces_endorsed.len());
143    println!("Saved CBOR: {}", out.display());
144
145    println!("Encoded CoRIM: {} bytes", bytes.len());
146    println!(
147        "Hex: {}",
148        bytes
149            .iter()
150            .map(|b| format!("{:02x}", b))
151            .collect::<String>()
152    );
153}
examples/build_corim_ovl3_tdisp_socmana.rs (line 94)
68fn main() {
69    use corim::builder::{ComidBuilder, CorimBuilder};
70    use corim::profile::azure::{AzureProfile, AZURE_PROFILE_URI};
71    use corim::profile::MatchContext;
72    use corim::types::common::TagIdChoice;
73    use corim::types::corim::{CorimId, ProfileChoice};
74    use corim::types::measurement::{MeasurementMap, MeasurementValuesMap, SvnChoice};
75    use corim::types::triples::{
76        CesCommonCondition, ConditionalEndorsementSeriesTriple, ConditionalSeriesRecord,
77    };
78    use corim::validate::{
79        apply_endorsement_series_with_profile, decode_and_validate_at, EvidenceClaim,
80    };
81
82    let ces = ConditionalEndorsementSeriesTriple::new(
83        CesCommonCondition {
84            environment: make_env(),
85            claims_list: vec![],
86            authorized_by: None,
87        },
88        vec![ConditionalSeriesRecord::new(
89            vec![uint_svn_selection(19, 1)],
90            vec![make_addition_uptodate()],
91        )],
92    );
93
94    let comid = ComidBuilder::new(TagIdChoice::Text("1.3.6.1.4.1.311.102.5_SOCMANA".into()))
95        .add_conditional_endorsement_series(ces)
96        .build()
97        .expect("failed to build CoMID");
98
99    let bytes = CorimBuilder::new(CorimId::Text(
100        "1.3.6.1.4.1.311.102.5_SOCMANA_20260705".into(),
101    ))
102    .set_profile(ProfileChoice::Uri(AZURE_PROFILE_URI.into()))
103    .add_comid_tag(comid)
104    .expect("failed to encode CoMID")
105    .build_bytes()
106    .expect("failed to build CoRIM");
107
108    let (_corim, comids) =
109        decode_and_validate_at(&bytes, 1_800_000_000).expect("decode_and_validate_at failed");
110    let decoded = &comids[0];
111
112    let profile = AzureProfile::new();
113    let evidence = vec![EvidenceClaim {
114        environment: decoded
115            .triples
116            .conditional_endorsement_series
117            .as_ref()
118            .unwrap()[0]
119            .common_condition()
120            .environment
121            .clone(),
122        measurements: vec![MeasurementMap {
123            mkey: Some(corim::types::common::MeasuredElement::Uint(19)),
124            mval: MeasurementValuesMap {
125                svn: Some(SvnChoice::ExactValue(1)),
126                ..MeasurementValuesMap::default()
127            },
128            authorized_by: None,
129        }],
130    }];
131
132    let ces_endorsed = apply_endorsement_series_with_profile(
133        decoded
134            .triples
135            .conditional_endorsement_series
136            .as_deref()
137            .unwrap(),
138        &evidence,
139        Some(&profile),
140        &MatchContext::new(),
141    )
142    .expect("apply_endorsement_series_with_profile failed");
143    let out = write_cbor_file(&bytes);
144    println!("CES endorsed claims: {}", ces_endorsed.len());
145    println!("Saved CBOR: {}", out.display());
146
147    println!("Encoded CoRIM: {} bytes", bytes.len());
148    println!(
149        "Hex: {}",
150        bytes
151            .iter()
152            .map(|b| format!("{:02x}", b))
153            .collect::<String>()
154    );
155}
examples/build_corim_ovl3_tdisp_sfua.rs (line 233)
166fn main() {
167    use corim::builder::{ComidBuilder, CorimBuilder};
168    use corim::profile::azure::{AzureProfile, AZURE_PROFILE_URI};
169    use corim::profile::MatchContext;
170    use corim::types::common::{CryptoKey, TagIdChoice};
171    use corim::types::corim::{CorimId, ProfileChoice};
172    use corim::types::measurement::{MeasurementMap, MeasurementValuesMap, SvnChoice};
173    use corim::types::triples::IdentityTriple;
174    use corim::validate::{
175        apply_endorsement_series_with_profile, decode_and_validate_at, EvidenceClaim,
176    };
177
178    let selection = make_selection_svn(0);
179    let addition = make_addition_uptodate();
180
181    let ces = make_ces(
182        make_env(Some(0), Some(SPDM_CERTIFICATES)),
183        vec![selection.clone()],
184        addition.clone(),
185    );
186
187    let ces2 = make_ces(
188        make_env(Some(1), Some(SPDM_CERTIFICATES)),
189        vec![selection],
190        addition.clone(),
191    );
192
193    let digest_384 = sha384_digest(vec![
194        0x4b, 0x56, 0xcf, 0xa0, 0x7f, 0xae, 0xb2, 0xab, 0x57, 0xde, 0x92, 0x1e, 0x4a, 0x97, 0xd6,
195        0x55, 0x14, 0x4b, 0x54, 0x64, 0x70, 0xeb, 0xaa, 0xab, 0x6f, 0x71, 0xc0, 0xdb, 0x51, 0x8d,
196        0xdf, 0x5b, 0x4a, 0x5f, 0xb2, 0x8f, 0xb2, 0xad, 0x1b, 0x49, 0x34, 0x26, 0x44, 0x24, 0xeb,
197        0x1e, 0x5a, 0x86,
198    ]);
199
200    let ces3_selection = vec![
201        uint_digest_selection(1, digest_384.clone()),
202        uint_digest_selection(8, digest_384),
203        uint_svn_selection(15, 1),
204        uint_svn_selection(16, 1),
205        uint_svn_selection(17, 1),
206        uint_svn_selection(18, 1),
207        uint_raw_value_selection(
208            254,
209            vec![
210                0x72, 0x61, 0x77, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x0a, 0x72, 0x61, 0x77, 0x76, 0x61,
211                0x6c, 0x75, 0x65, 0x0a,
212            ],
213        ),
214    ];
215
216    let ces3 = make_ces(
217        make_env(None, Some(SPDM_MEASUREMENTS)),
218        ces3_selection,
219        addition.clone(),
220    );
221
222    let thumbprint_bytes: [u8; 32] = [
223        0x44, 0xaa, 0x33, 0x6a, 0xf4, 0xcb, 0x14, 0xa8, 0x79, 0x43, 0x2e, 0x53, 0xdd, 0x65, 0x71,
224        0xc7, 0xfa, 0x9b, 0xcc, 0xaf, 0xb7, 0x5f, 0x48, 0x82, 0x59, 0x26, 0x2d, 0x6e, 0xa3, 0xa4,
225        0xd9, 0x1b,
226    ];
227    let thumbprint = sha256_digest(thumbprint_bytes.to_vec());
228    let id_keys = vec![
229        CryptoKey::CertThumbprint(thumbprint.clone()),
230        CryptoKey::CertThumbprint(thumbprint),
231    ];
232
233    let comid = ComidBuilder::new(TagIdChoice::Text("1.3.6.1.4.1.311.102.5_SFUA".into()))
234        .set_tag_version(1)
235        .add_identity_triple(IdentityTriple::new(make_env(None, None), id_keys, None))
236        .add_conditional_endorsement_series(ces)
237        .add_conditional_endorsement_series(ces2)
238        .add_conditional_endorsement_series(ces3)
239        .build()
240        .expect("failed to build CoMID");
241
242    let bytes = CorimBuilder::new(CorimId::Text("1.3.6.1.4.1.311.102.5_SFUA_20260705".into()))
243        .set_profile(ProfileChoice::Uri(AZURE_PROFILE_URI.into()))
244        .add_comid_tag(comid)
245        .expect("failed to encode CoMID")
246        .build_bytes()
247        .expect("failed to build CoRIM");
248
249    let (_corim, comids) =
250        decode_and_validate_at(&bytes, 1_800_000_000).expect("decode_and_validate_at failed");
251    let decoded = &comids[0];
252
253    let profile = AzureProfile::new();
254    let evidence = vec![EvidenceClaim {
255        environment: decoded
256            .triples
257            .conditional_endorsement_series
258            .as_ref()
259            .unwrap()[0]
260            .common_condition()
261            .environment
262            .clone(),
263        measurements: vec![MeasurementMap {
264            mkey: None,
265            mval: MeasurementValuesMap {
266                svn: Some(SvnChoice::ExactValue(0)),
267                ..MeasurementValuesMap::default()
268            },
269            authorized_by: None,
270        }],
271    }];
272
273    let ces_endorsed = apply_endorsement_series_with_profile(
274        decoded
275            .triples
276            .conditional_endorsement_series
277            .as_deref()
278            .unwrap(),
279        &evidence,
280        Some(&profile),
281        &MatchContext::new(),
282    )
283    .expect("apply_endorsement_series_with_profile failed");
284    let out = write_cbor_file(&bytes);
285    println!("CES endorsed claims: {}", ces_endorsed.len());
286    println!("Saved CBOR: {}", out.display());
287
288    println!("Encoded CoRIM: {} bytes", bytes.len());
289    println!(
290        "Hex: {}",
291        bytes
292            .iter()
293            .map(|b| format!("{:02x}", b))
294            .collect::<String>()
295    );
296}

Enable cross-triple link checking at build() time.

When enabled, two anchoring checks run:

  1. Every condition environment in a conditional-endorsement-series, conditional-endorsement, or endorsed triple must structurally equal some reference-triple environment in the same CoMID; otherwise build() returns BuilderError::UnanchoredConditionEnv.
  2. Every condition-side measurement (CES claims_list, CES series condition, or CE stateful-environment-record measurement) must structurally equal some measurement in a reference triple for the same env; otherwise build() returns BuilderError::UnanchoredConditionMeasurement. Endorsement and addition lists are not anchored.

The wire format does not encode either constraint — these are builder-side lints for catching authoring mistakes.

Source

pub fn declare_env( &mut self, label: impl Into<String>, env: EnvironmentMap, ) -> Result<EnvRef, BuilderError>

Declare a named environment in this builder’s catalog.

Returns an EnvRef that can be passed to any add_*_for method on this same builder. The label is for diagnostics only; uniqueness is enforced — a second declare_env with the same label returns BuilderError::DuplicateEnvLabel.

EnvRefs never reach the wire format; build() resolves each ref into an inline EnvironmentMap before encoding.

Source

pub fn add_reference_triple_for( self, env: impl Into<EnvSpec>, measurements: Vec<MeasurementMap>, ) -> Self

Add a reference values triple by env-spec.

env may be an EnvironmentMap (inline) or an EnvRef obtained from declare_env on this same builder. Resolution happens at build time.

Source

pub fn add_endorsed_triple_for( self, env: impl Into<EnvSpec>, endorsement: Vec<MeasurementMap>, ) -> Self

Add an endorsed values triple by env-spec. See add_reference_triple_for.

Source

pub fn add_identity_triple_for( self, env: impl Into<EnvSpec>, keys: Vec<CryptoKey>, conditions: Option<KeyTripleConditions>, ) -> Self

Add an identity triple by env-spec. See add_reference_triple_for.

Source

pub fn add_attest_key_triple_for( self, env: impl Into<EnvSpec>, keys: Vec<CryptoKey>, conditions: Option<KeyTripleConditions>, ) -> Self

Add an attest-key triple by env-spec. See add_reference_triple_for.

Source

pub fn add_dependency_triple_for( self, domain: impl Into<EnvSpec>, trustees: Vec<EnvSpec>, ) -> Self

Add a trust dependency triple by env-spec. Trustees are also env-specs; pass vec![env_a.into(), env_b_ref.into()] to mix inline envs and refs.

Source

pub fn add_membership_triple_for( self, domain: impl Into<EnvSpec>, members: Vec<EnvSpec>, ) -> Self

Add a domain membership triple by env-spec. See add_dependency_triple_for.

Source

pub fn add_coswid_triple_for( self, env: impl Into<EnvSpec>, tag_ids: Vec<TagIdChoice>, ) -> Self

Add a CoMID-CoSWID linking triple by env-spec.

Source

pub fn add_conditional_endorsement_series_for( self, condition_env: impl Into<EnvSpec>, condition_claims_list: Vec<MeasurementMap>, condition_authorized_by: Option<Vec<CryptoKey>>, series: Vec<ConditionalSeriesRecord>, ) -> Self

Add a conditional-endorsement-series triple by env-spec.

The arguments correspond to the fields of CesCommonCondition plus the series list. The condition env may be an EnvironmentMap or an EnvRef; refs are resolved at build time exactly like the other _for methods.

This is the preferred way to construct a CES triple whose condition env is shared with a reference triple — passing the same EnvRef to both add_reference_triple_for and this method guarantees the two envs are byte-for-byte identical on the wire, with no caller-visible clone.

Source

pub fn add_conditional_endorsement_for( self, conditions: Vec<(EnvSpec, Vec<MeasurementMap>)>, endorsements: Vec<EndorsedTriple>, ) -> Self

Add a conditional-endorsement triple by env-spec.

conditions is the [+ stateful-environment-record] list — each entry pairs an env (inline or EnvRef) with its measurement list. endorsements is the [+ endorsed-triple-record] list; those inner envs are not covered by the catalog (use add_endorsed_triple_for when the shared-env intent is across whole endorsed triples instead).

Source

pub fn set_tag_version(self, version: u64) -> Self

Set the tag version (§5.1.1.2). Defaults to 0 if not set.

Examples found in repository?
examples/build_corim.rs (line 42)
14fn main() {
15    // Define the target environment
16    let env = EnvironmentMap {
17        class: Some(ClassMap {
18            class_id: None,
19            vendor: Some("ACME Corp".into()),
20            model: Some("Turbo Encabulator".into()),
21            layer: Some(0),
22            index: None,
23        }),
24        instance: None,
25        group: None,
26    };
27
28    // Create a measurement with a SHA-384 digest
29    let measurement = MeasurementMap {
30        mkey: Some(MeasuredElement::Text("firmware".into())),
31        mval: MeasurementValuesMap {
32            digests: Some(vec![Digest::new(7, vec![0xAA; 48])]),
33            ..MeasurementValuesMap::default()
34        },
35        authorized_by: None,
36    };
37
38    // Build a CoMID
39    let comid = ComidBuilder::new(TagIdChoice::Text(
40        "example.com/acme/turbo-encabulator".into(),
41    ))
42    .set_tag_version(0)
43    .add_entity(EntityMap {
44        entity_name: "ACME Corp".into(),
45        reg_id: Some("https://acme.example.com".into()),
46        role: vec![COMID_ROLE_TAG_CREATOR],
47    })
48    .add_reference_triple(ReferenceTriple::new(env, vec![measurement]))
49    .build()
50    .expect("failed to build CoMID");
51
52    // Wrap in a CoRIM and encode
53    let bytes = CorimBuilder::new(CorimId::Text("acme/corim/v1".into()))
54        .set_profile(ProfileChoice::Uri(
55            "https://example.com/acme-profile".into(),
56        ))
57        .set_validity(Some(1700000000), 1900000000)
58        .unwrap()
59        .add_comid_tag(comid)
60        .expect("failed to encode CoMID")
61        .build_bytes()
62        .expect("failed to build CoRIM");
63
64    println!("Encoded CoRIM: {} bytes", bytes.len());
65    println!(
66        "Hex: {}",
67        bytes
68            .iter()
69            .map(|b| format!("{:02x}", b))
70            .collect::<String>()
71    );
72}
More examples
Hide additional examples
examples/build_corim_ovl3_tdisp_sfua.rs (line 234)
166fn main() {
167    use corim::builder::{ComidBuilder, CorimBuilder};
168    use corim::profile::azure::{AzureProfile, AZURE_PROFILE_URI};
169    use corim::profile::MatchContext;
170    use corim::types::common::{CryptoKey, TagIdChoice};
171    use corim::types::corim::{CorimId, ProfileChoice};
172    use corim::types::measurement::{MeasurementMap, MeasurementValuesMap, SvnChoice};
173    use corim::types::triples::IdentityTriple;
174    use corim::validate::{
175        apply_endorsement_series_with_profile, decode_and_validate_at, EvidenceClaim,
176    };
177
178    let selection = make_selection_svn(0);
179    let addition = make_addition_uptodate();
180
181    let ces = make_ces(
182        make_env(Some(0), Some(SPDM_CERTIFICATES)),
183        vec![selection.clone()],
184        addition.clone(),
185    );
186
187    let ces2 = make_ces(
188        make_env(Some(1), Some(SPDM_CERTIFICATES)),
189        vec![selection],
190        addition.clone(),
191    );
192
193    let digest_384 = sha384_digest(vec![
194        0x4b, 0x56, 0xcf, 0xa0, 0x7f, 0xae, 0xb2, 0xab, 0x57, 0xde, 0x92, 0x1e, 0x4a, 0x97, 0xd6,
195        0x55, 0x14, 0x4b, 0x54, 0x64, 0x70, 0xeb, 0xaa, 0xab, 0x6f, 0x71, 0xc0, 0xdb, 0x51, 0x8d,
196        0xdf, 0x5b, 0x4a, 0x5f, 0xb2, 0x8f, 0xb2, 0xad, 0x1b, 0x49, 0x34, 0x26, 0x44, 0x24, 0xeb,
197        0x1e, 0x5a, 0x86,
198    ]);
199
200    let ces3_selection = vec![
201        uint_digest_selection(1, digest_384.clone()),
202        uint_digest_selection(8, digest_384),
203        uint_svn_selection(15, 1),
204        uint_svn_selection(16, 1),
205        uint_svn_selection(17, 1),
206        uint_svn_selection(18, 1),
207        uint_raw_value_selection(
208            254,
209            vec![
210                0x72, 0x61, 0x77, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x0a, 0x72, 0x61, 0x77, 0x76, 0x61,
211                0x6c, 0x75, 0x65, 0x0a,
212            ],
213        ),
214    ];
215
216    let ces3 = make_ces(
217        make_env(None, Some(SPDM_MEASUREMENTS)),
218        ces3_selection,
219        addition.clone(),
220    );
221
222    let thumbprint_bytes: [u8; 32] = [
223        0x44, 0xaa, 0x33, 0x6a, 0xf4, 0xcb, 0x14, 0xa8, 0x79, 0x43, 0x2e, 0x53, 0xdd, 0x65, 0x71,
224        0xc7, 0xfa, 0x9b, 0xcc, 0xaf, 0xb7, 0x5f, 0x48, 0x82, 0x59, 0x26, 0x2d, 0x6e, 0xa3, 0xa4,
225        0xd9, 0x1b,
226    ];
227    let thumbprint = sha256_digest(thumbprint_bytes.to_vec());
228    let id_keys = vec![
229        CryptoKey::CertThumbprint(thumbprint.clone()),
230        CryptoKey::CertThumbprint(thumbprint),
231    ];
232
233    let comid = ComidBuilder::new(TagIdChoice::Text("1.3.6.1.4.1.311.102.5_SFUA".into()))
234        .set_tag_version(1)
235        .add_identity_triple(IdentityTriple::new(make_env(None, None), id_keys, None))
236        .add_conditional_endorsement_series(ces)
237        .add_conditional_endorsement_series(ces2)
238        .add_conditional_endorsement_series(ces3)
239        .build()
240        .expect("failed to build CoMID");
241
242    let bytes = CorimBuilder::new(CorimId::Text("1.3.6.1.4.1.311.102.5_SFUA_20260705".into()))
243        .set_profile(ProfileChoice::Uri(AZURE_PROFILE_URI.into()))
244        .add_comid_tag(comid)
245        .expect("failed to encode CoMID")
246        .build_bytes()
247        .expect("failed to build CoRIM");
248
249    let (_corim, comids) =
250        decode_and_validate_at(&bytes, 1_800_000_000).expect("decode_and_validate_at failed");
251    let decoded = &comids[0];
252
253    let profile = AzureProfile::new();
254    let evidence = vec![EvidenceClaim {
255        environment: decoded
256            .triples
257            .conditional_endorsement_series
258            .as_ref()
259            .unwrap()[0]
260            .common_condition()
261            .environment
262            .clone(),
263        measurements: vec![MeasurementMap {
264            mkey: None,
265            mval: MeasurementValuesMap {
266                svn: Some(SvnChoice::ExactValue(0)),
267                ..MeasurementValuesMap::default()
268            },
269            authorized_by: None,
270        }],
271    }];
272
273    let ces_endorsed = apply_endorsement_series_with_profile(
274        decoded
275            .triples
276            .conditional_endorsement_series
277            .as_deref()
278            .unwrap(),
279        &evidence,
280        Some(&profile),
281        &MatchContext::new(),
282    )
283    .expect("apply_endorsement_series_with_profile failed");
284    let out = write_cbor_file(&bytes);
285    println!("CES endorsed claims: {}", ces_endorsed.len());
286    println!("Saved CBOR: {}", out.display());
287
288    println!("Encoded CoRIM: {} bytes", bytes.len());
289    println!(
290        "Hex: {}",
291        bytes
292            .iter()
293            .map(|b| format!("{:02x}", b))
294            .collect::<String>()
295    );
296}
Source

pub fn set_language(self, lang: impl Into<String>) -> Self

Set the optional language tag (BCP 47).

Source

pub fn add_entity(self, entity: EntityMap) -> Self

Add an entity (§5.1.2).

Examples found in repository?
examples/build_corim.rs (lines 43-47)
14fn main() {
15    // Define the target environment
16    let env = EnvironmentMap {
17        class: Some(ClassMap {
18            class_id: None,
19            vendor: Some("ACME Corp".into()),
20            model: Some("Turbo Encabulator".into()),
21            layer: Some(0),
22            index: None,
23        }),
24        instance: None,
25        group: None,
26    };
27
28    // Create a measurement with a SHA-384 digest
29    let measurement = MeasurementMap {
30        mkey: Some(MeasuredElement::Text("firmware".into())),
31        mval: MeasurementValuesMap {
32            digests: Some(vec![Digest::new(7, vec![0xAA; 48])]),
33            ..MeasurementValuesMap::default()
34        },
35        authorized_by: None,
36    };
37
38    // Build a CoMID
39    let comid = ComidBuilder::new(TagIdChoice::Text(
40        "example.com/acme/turbo-encabulator".into(),
41    ))
42    .set_tag_version(0)
43    .add_entity(EntityMap {
44        entity_name: "ACME Corp".into(),
45        reg_id: Some("https://acme.example.com".into()),
46        role: vec![COMID_ROLE_TAG_CREATOR],
47    })
48    .add_reference_triple(ReferenceTriple::new(env, vec![measurement]))
49    .build()
50    .expect("failed to build CoMID");
51
52    // Wrap in a CoRIM and encode
53    let bytes = CorimBuilder::new(CorimId::Text("acme/corim/v1".into()))
54        .set_profile(ProfileChoice::Uri(
55            "https://example.com/acme-profile".into(),
56        ))
57        .set_validity(Some(1700000000), 1900000000)
58        .unwrap()
59        .add_comid_tag(comid)
60        .expect("failed to encode CoMID")
61        .build_bytes()
62        .expect("failed to build CoRIM");
63
64    println!("Encoded CoRIM: {} bytes", bytes.len());
65    println!(
66        "Hex: {}",
67        bytes
68            .iter()
69            .map(|b| format!("{:02x}", b))
70            .collect::<String>()
71    );
72}
Source

pub fn add_linked_tag(self, linked_tag: LinkedTagMap) -> Self

Add a linked tag (§5.1.3).

Source

pub fn add_reference_triple(self, triple: ReferenceTriple) -> Self

Add a reference values triple (§5.1.5).

Examples found in repository?
examples/build_corim.rs (line 48)
14fn main() {
15    // Define the target environment
16    let env = EnvironmentMap {
17        class: Some(ClassMap {
18            class_id: None,
19            vendor: Some("ACME Corp".into()),
20            model: Some("Turbo Encabulator".into()),
21            layer: Some(0),
22            index: None,
23        }),
24        instance: None,
25        group: None,
26    };
27
28    // Create a measurement with a SHA-384 digest
29    let measurement = MeasurementMap {
30        mkey: Some(MeasuredElement::Text("firmware".into())),
31        mval: MeasurementValuesMap {
32            digests: Some(vec![Digest::new(7, vec![0xAA; 48])]),
33            ..MeasurementValuesMap::default()
34        },
35        authorized_by: None,
36    };
37
38    // Build a CoMID
39    let comid = ComidBuilder::new(TagIdChoice::Text(
40        "example.com/acme/turbo-encabulator".into(),
41    ))
42    .set_tag_version(0)
43    .add_entity(EntityMap {
44        entity_name: "ACME Corp".into(),
45        reg_id: Some("https://acme.example.com".into()),
46        role: vec![COMID_ROLE_TAG_CREATOR],
47    })
48    .add_reference_triple(ReferenceTriple::new(env, vec![measurement]))
49    .build()
50    .expect("failed to build CoMID");
51
52    // Wrap in a CoRIM and encode
53    let bytes = CorimBuilder::new(CorimId::Text("acme/corim/v1".into()))
54        .set_profile(ProfileChoice::Uri(
55            "https://example.com/acme-profile".into(),
56        ))
57        .set_validity(Some(1700000000), 1900000000)
58        .unwrap()
59        .add_comid_tag(comid)
60        .expect("failed to encode CoMID")
61        .build_bytes()
62        .expect("failed to build CoRIM");
63
64    println!("Encoded CoRIM: {} bytes", bytes.len());
65    println!(
66        "Hex: {}",
67        bytes
68            .iter()
69            .map(|b| format!("{:02x}", b))
70            .collect::<String>()
71    );
72}
Source

pub fn add_endorsed_triple(self, triple: EndorsedTriple) -> Self

Add an endorsed values triple (§5.1.6).

Source

pub fn add_identity_triple(self, triple: IdentityTriple) -> Self

Add a device identity triple (§5.1.9).

Examples found in repository?
examples/build_corim_ovl3_tdisp_sfua.rs (line 235)
166fn main() {
167    use corim::builder::{ComidBuilder, CorimBuilder};
168    use corim::profile::azure::{AzureProfile, AZURE_PROFILE_URI};
169    use corim::profile::MatchContext;
170    use corim::types::common::{CryptoKey, TagIdChoice};
171    use corim::types::corim::{CorimId, ProfileChoice};
172    use corim::types::measurement::{MeasurementMap, MeasurementValuesMap, SvnChoice};
173    use corim::types::triples::IdentityTriple;
174    use corim::validate::{
175        apply_endorsement_series_with_profile, decode_and_validate_at, EvidenceClaim,
176    };
177
178    let selection = make_selection_svn(0);
179    let addition = make_addition_uptodate();
180
181    let ces = make_ces(
182        make_env(Some(0), Some(SPDM_CERTIFICATES)),
183        vec![selection.clone()],
184        addition.clone(),
185    );
186
187    let ces2 = make_ces(
188        make_env(Some(1), Some(SPDM_CERTIFICATES)),
189        vec![selection],
190        addition.clone(),
191    );
192
193    let digest_384 = sha384_digest(vec![
194        0x4b, 0x56, 0xcf, 0xa0, 0x7f, 0xae, 0xb2, 0xab, 0x57, 0xde, 0x92, 0x1e, 0x4a, 0x97, 0xd6,
195        0x55, 0x14, 0x4b, 0x54, 0x64, 0x70, 0xeb, 0xaa, 0xab, 0x6f, 0x71, 0xc0, 0xdb, 0x51, 0x8d,
196        0xdf, 0x5b, 0x4a, 0x5f, 0xb2, 0x8f, 0xb2, 0xad, 0x1b, 0x49, 0x34, 0x26, 0x44, 0x24, 0xeb,
197        0x1e, 0x5a, 0x86,
198    ]);
199
200    let ces3_selection = vec![
201        uint_digest_selection(1, digest_384.clone()),
202        uint_digest_selection(8, digest_384),
203        uint_svn_selection(15, 1),
204        uint_svn_selection(16, 1),
205        uint_svn_selection(17, 1),
206        uint_svn_selection(18, 1),
207        uint_raw_value_selection(
208            254,
209            vec![
210                0x72, 0x61, 0x77, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x0a, 0x72, 0x61, 0x77, 0x76, 0x61,
211                0x6c, 0x75, 0x65, 0x0a,
212            ],
213        ),
214    ];
215
216    let ces3 = make_ces(
217        make_env(None, Some(SPDM_MEASUREMENTS)),
218        ces3_selection,
219        addition.clone(),
220    );
221
222    let thumbprint_bytes: [u8; 32] = [
223        0x44, 0xaa, 0x33, 0x6a, 0xf4, 0xcb, 0x14, 0xa8, 0x79, 0x43, 0x2e, 0x53, 0xdd, 0x65, 0x71,
224        0xc7, 0xfa, 0x9b, 0xcc, 0xaf, 0xb7, 0x5f, 0x48, 0x82, 0x59, 0x26, 0x2d, 0x6e, 0xa3, 0xa4,
225        0xd9, 0x1b,
226    ];
227    let thumbprint = sha256_digest(thumbprint_bytes.to_vec());
228    let id_keys = vec![
229        CryptoKey::CertThumbprint(thumbprint.clone()),
230        CryptoKey::CertThumbprint(thumbprint),
231    ];
232
233    let comid = ComidBuilder::new(TagIdChoice::Text("1.3.6.1.4.1.311.102.5_SFUA".into()))
234        .set_tag_version(1)
235        .add_identity_triple(IdentityTriple::new(make_env(None, None), id_keys, None))
236        .add_conditional_endorsement_series(ces)
237        .add_conditional_endorsement_series(ces2)
238        .add_conditional_endorsement_series(ces3)
239        .build()
240        .expect("failed to build CoMID");
241
242    let bytes = CorimBuilder::new(CorimId::Text("1.3.6.1.4.1.311.102.5_SFUA_20260705".into()))
243        .set_profile(ProfileChoice::Uri(AZURE_PROFILE_URI.into()))
244        .add_comid_tag(comid)
245        .expect("failed to encode CoMID")
246        .build_bytes()
247        .expect("failed to build CoRIM");
248
249    let (_corim, comids) =
250        decode_and_validate_at(&bytes, 1_800_000_000).expect("decode_and_validate_at failed");
251    let decoded = &comids[0];
252
253    let profile = AzureProfile::new();
254    let evidence = vec![EvidenceClaim {
255        environment: decoded
256            .triples
257            .conditional_endorsement_series
258            .as_ref()
259            .unwrap()[0]
260            .common_condition()
261            .environment
262            .clone(),
263        measurements: vec![MeasurementMap {
264            mkey: None,
265            mval: MeasurementValuesMap {
266                svn: Some(SvnChoice::ExactValue(0)),
267                ..MeasurementValuesMap::default()
268            },
269            authorized_by: None,
270        }],
271    }];
272
273    let ces_endorsed = apply_endorsement_series_with_profile(
274        decoded
275            .triples
276            .conditional_endorsement_series
277            .as_deref()
278            .unwrap(),
279        &evidence,
280        Some(&profile),
281        &MatchContext::new(),
282    )
283    .expect("apply_endorsement_series_with_profile failed");
284    let out = write_cbor_file(&bytes);
285    println!("CES endorsed claims: {}", ces_endorsed.len());
286    println!("Saved CBOR: {}", out.display());
287
288    println!("Encoded CoRIM: {} bytes", bytes.len());
289    println!(
290        "Hex: {}",
291        bytes
292            .iter()
293            .map(|b| format!("{:02x}", b))
294            .collect::<String>()
295    );
296}
Source

pub fn add_attest_key_triple(self, triple: AttestKeyTriple) -> Self

Add an attest key triple (§5.1.10).

Source

pub fn add_dependency_triple(self, triple: TrustDependencyTriple) -> Self

Add a trust dependency triple (§5.1.11.2).

Source

pub fn add_membership_triple(self, triple: DomainMembershipTriple) -> Self

Add a domain membership triple (§5.1.11.1).

Source

pub fn add_coswid_triple(self, triple: CoswidTriple) -> Self

Add a CoMID-CoSWID linking triple (§5.1.12).

Source

pub fn add_conditional_endorsement_series( self, triple: ConditionalEndorsementSeriesTriple, ) -> Self

Add a conditional endorsement series triple (§5.1.8).

Examples found in repository?
examples/build_corim_ovl3_tdisp_ndpa.rs (line 95)
68fn main() {
69    use corim::builder::{ComidBuilder, CorimBuilder};
70    use corim::profile::azure::{AzureProfile, AZURE_PROFILE_URI};
71    use corim::profile::MatchContext;
72    use corim::types::common::TagIdChoice;
73    use corim::types::corim::{CorimId, ProfileChoice};
74    use corim::types::measurement::{MeasurementMap, MeasurementValuesMap, SvnChoice};
75    use corim::types::triples::{
76        CesCommonCondition, ConditionalEndorsementSeriesTriple, ConditionalSeriesRecord,
77    };
78    use corim::validate::{
79        apply_endorsement_series_with_profile, decode_and_validate_at, EvidenceClaim,
80    };
81
82    let ces = ConditionalEndorsementSeriesTriple::new(
83        CesCommonCondition {
84            environment: make_env(),
85            claims_list: vec![],
86            authorized_by: None,
87        },
88        vec![ConditionalSeriesRecord::new(
89            vec![uint_svn_selection(20, 1)],
90            vec![make_addition_uptodate()],
91        )],
92    );
93
94    let comid = ComidBuilder::new(TagIdChoice::Text("1.3.6.1.4.1.311.102.5_NDPA".into()))
95        .add_conditional_endorsement_series(ces)
96        .build()
97        .expect("failed to build CoMID");
98
99    let bytes = CorimBuilder::new(CorimId::Text("1.3.6.1.4.1.311.102.5_NDPA_20260705".into()))
100        .set_profile(ProfileChoice::Uri(AZURE_PROFILE_URI.into()))
101        .add_comid_tag(comid)
102        .expect("failed to encode CoMID")
103        .build_bytes()
104        .expect("failed to build CoRIM");
105
106    let (_corim, comids) =
107        decode_and_validate_at(&bytes, 1_800_000_000).expect("decode_and_validate_at failed");
108    let decoded = &comids[0];
109
110    let profile = AzureProfile::new();
111    let evidence = vec![EvidenceClaim {
112        environment: decoded
113            .triples
114            .conditional_endorsement_series
115            .as_ref()
116            .unwrap()[0]
117            .common_condition()
118            .environment
119            .clone(),
120        measurements: vec![MeasurementMap {
121            mkey: Some(corim::types::common::MeasuredElement::Uint(20)),
122            mval: MeasurementValuesMap {
123                svn: Some(SvnChoice::ExactValue(1)),
124                ..MeasurementValuesMap::default()
125            },
126            authorized_by: None,
127        }],
128    }];
129
130    let ces_endorsed = apply_endorsement_series_with_profile(
131        decoded
132            .triples
133            .conditional_endorsement_series
134            .as_deref()
135            .unwrap(),
136        &evidence,
137        Some(&profile),
138        &MatchContext::new(),
139    )
140    .expect("apply_endorsement_series_with_profile failed");
141    let out = write_cbor_file(&bytes);
142    println!("CES endorsed claims: {}", ces_endorsed.len());
143    println!("Saved CBOR: {}", out.display());
144
145    println!("Encoded CoRIM: {} bytes", bytes.len());
146    println!(
147        "Hex: {}",
148        bytes
149            .iter()
150            .map(|b| format!("{:02x}", b))
151            .collect::<String>()
152    );
153}
More examples
Hide additional examples
examples/build_corim_ovl3_tdisp_socmana.rs (line 95)
68fn main() {
69    use corim::builder::{ComidBuilder, CorimBuilder};
70    use corim::profile::azure::{AzureProfile, AZURE_PROFILE_URI};
71    use corim::profile::MatchContext;
72    use corim::types::common::TagIdChoice;
73    use corim::types::corim::{CorimId, ProfileChoice};
74    use corim::types::measurement::{MeasurementMap, MeasurementValuesMap, SvnChoice};
75    use corim::types::triples::{
76        CesCommonCondition, ConditionalEndorsementSeriesTriple, ConditionalSeriesRecord,
77    };
78    use corim::validate::{
79        apply_endorsement_series_with_profile, decode_and_validate_at, EvidenceClaim,
80    };
81
82    let ces = ConditionalEndorsementSeriesTriple::new(
83        CesCommonCondition {
84            environment: make_env(),
85            claims_list: vec![],
86            authorized_by: None,
87        },
88        vec![ConditionalSeriesRecord::new(
89            vec![uint_svn_selection(19, 1)],
90            vec![make_addition_uptodate()],
91        )],
92    );
93
94    let comid = ComidBuilder::new(TagIdChoice::Text("1.3.6.1.4.1.311.102.5_SOCMANA".into()))
95        .add_conditional_endorsement_series(ces)
96        .build()
97        .expect("failed to build CoMID");
98
99    let bytes = CorimBuilder::new(CorimId::Text(
100        "1.3.6.1.4.1.311.102.5_SOCMANA_20260705".into(),
101    ))
102    .set_profile(ProfileChoice::Uri(AZURE_PROFILE_URI.into()))
103    .add_comid_tag(comid)
104    .expect("failed to encode CoMID")
105    .build_bytes()
106    .expect("failed to build CoRIM");
107
108    let (_corim, comids) =
109        decode_and_validate_at(&bytes, 1_800_000_000).expect("decode_and_validate_at failed");
110    let decoded = &comids[0];
111
112    let profile = AzureProfile::new();
113    let evidence = vec![EvidenceClaim {
114        environment: decoded
115            .triples
116            .conditional_endorsement_series
117            .as_ref()
118            .unwrap()[0]
119            .common_condition()
120            .environment
121            .clone(),
122        measurements: vec![MeasurementMap {
123            mkey: Some(corim::types::common::MeasuredElement::Uint(19)),
124            mval: MeasurementValuesMap {
125                svn: Some(SvnChoice::ExactValue(1)),
126                ..MeasurementValuesMap::default()
127            },
128            authorized_by: None,
129        }],
130    }];
131
132    let ces_endorsed = apply_endorsement_series_with_profile(
133        decoded
134            .triples
135            .conditional_endorsement_series
136            .as_deref()
137            .unwrap(),
138        &evidence,
139        Some(&profile),
140        &MatchContext::new(),
141    )
142    .expect("apply_endorsement_series_with_profile failed");
143    let out = write_cbor_file(&bytes);
144    println!("CES endorsed claims: {}", ces_endorsed.len());
145    println!("Saved CBOR: {}", out.display());
146
147    println!("Encoded CoRIM: {} bytes", bytes.len());
148    println!(
149        "Hex: {}",
150        bytes
151            .iter()
152            .map(|b| format!("{:02x}", b))
153            .collect::<String>()
154    );
155}
examples/build_corim_ovl3_tdisp_sfua.rs (line 236)
166fn main() {
167    use corim::builder::{ComidBuilder, CorimBuilder};
168    use corim::profile::azure::{AzureProfile, AZURE_PROFILE_URI};
169    use corim::profile::MatchContext;
170    use corim::types::common::{CryptoKey, TagIdChoice};
171    use corim::types::corim::{CorimId, ProfileChoice};
172    use corim::types::measurement::{MeasurementMap, MeasurementValuesMap, SvnChoice};
173    use corim::types::triples::IdentityTriple;
174    use corim::validate::{
175        apply_endorsement_series_with_profile, decode_and_validate_at, EvidenceClaim,
176    };
177
178    let selection = make_selection_svn(0);
179    let addition = make_addition_uptodate();
180
181    let ces = make_ces(
182        make_env(Some(0), Some(SPDM_CERTIFICATES)),
183        vec![selection.clone()],
184        addition.clone(),
185    );
186
187    let ces2 = make_ces(
188        make_env(Some(1), Some(SPDM_CERTIFICATES)),
189        vec![selection],
190        addition.clone(),
191    );
192
193    let digest_384 = sha384_digest(vec![
194        0x4b, 0x56, 0xcf, 0xa0, 0x7f, 0xae, 0xb2, 0xab, 0x57, 0xde, 0x92, 0x1e, 0x4a, 0x97, 0xd6,
195        0x55, 0x14, 0x4b, 0x54, 0x64, 0x70, 0xeb, 0xaa, 0xab, 0x6f, 0x71, 0xc0, 0xdb, 0x51, 0x8d,
196        0xdf, 0x5b, 0x4a, 0x5f, 0xb2, 0x8f, 0xb2, 0xad, 0x1b, 0x49, 0x34, 0x26, 0x44, 0x24, 0xeb,
197        0x1e, 0x5a, 0x86,
198    ]);
199
200    let ces3_selection = vec![
201        uint_digest_selection(1, digest_384.clone()),
202        uint_digest_selection(8, digest_384),
203        uint_svn_selection(15, 1),
204        uint_svn_selection(16, 1),
205        uint_svn_selection(17, 1),
206        uint_svn_selection(18, 1),
207        uint_raw_value_selection(
208            254,
209            vec![
210                0x72, 0x61, 0x77, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x0a, 0x72, 0x61, 0x77, 0x76, 0x61,
211                0x6c, 0x75, 0x65, 0x0a,
212            ],
213        ),
214    ];
215
216    let ces3 = make_ces(
217        make_env(None, Some(SPDM_MEASUREMENTS)),
218        ces3_selection,
219        addition.clone(),
220    );
221
222    let thumbprint_bytes: [u8; 32] = [
223        0x44, 0xaa, 0x33, 0x6a, 0xf4, 0xcb, 0x14, 0xa8, 0x79, 0x43, 0x2e, 0x53, 0xdd, 0x65, 0x71,
224        0xc7, 0xfa, 0x9b, 0xcc, 0xaf, 0xb7, 0x5f, 0x48, 0x82, 0x59, 0x26, 0x2d, 0x6e, 0xa3, 0xa4,
225        0xd9, 0x1b,
226    ];
227    let thumbprint = sha256_digest(thumbprint_bytes.to_vec());
228    let id_keys = vec![
229        CryptoKey::CertThumbprint(thumbprint.clone()),
230        CryptoKey::CertThumbprint(thumbprint),
231    ];
232
233    let comid = ComidBuilder::new(TagIdChoice::Text("1.3.6.1.4.1.311.102.5_SFUA".into()))
234        .set_tag_version(1)
235        .add_identity_triple(IdentityTriple::new(make_env(None, None), id_keys, None))
236        .add_conditional_endorsement_series(ces)
237        .add_conditional_endorsement_series(ces2)
238        .add_conditional_endorsement_series(ces3)
239        .build()
240        .expect("failed to build CoMID");
241
242    let bytes = CorimBuilder::new(CorimId::Text("1.3.6.1.4.1.311.102.5_SFUA_20260705".into()))
243        .set_profile(ProfileChoice::Uri(AZURE_PROFILE_URI.into()))
244        .add_comid_tag(comid)
245        .expect("failed to encode CoMID")
246        .build_bytes()
247        .expect("failed to build CoRIM");
248
249    let (_corim, comids) =
250        decode_and_validate_at(&bytes, 1_800_000_000).expect("decode_and_validate_at failed");
251    let decoded = &comids[0];
252
253    let profile = AzureProfile::new();
254    let evidence = vec![EvidenceClaim {
255        environment: decoded
256            .triples
257            .conditional_endorsement_series
258            .as_ref()
259            .unwrap()[0]
260            .common_condition()
261            .environment
262            .clone(),
263        measurements: vec![MeasurementMap {
264            mkey: None,
265            mval: MeasurementValuesMap {
266                svn: Some(SvnChoice::ExactValue(0)),
267                ..MeasurementValuesMap::default()
268            },
269            authorized_by: None,
270        }],
271    }];
272
273    let ces_endorsed = apply_endorsement_series_with_profile(
274        decoded
275            .triples
276            .conditional_endorsement_series
277            .as_deref()
278            .unwrap(),
279        &evidence,
280        Some(&profile),
281        &MatchContext::new(),
282    )
283    .expect("apply_endorsement_series_with_profile failed");
284    let out = write_cbor_file(&bytes);
285    println!("CES endorsed claims: {}", ces_endorsed.len());
286    println!("Saved CBOR: {}", out.display());
287
288    println!("Encoded CoRIM: {} bytes", bytes.len());
289    println!(
290        "Hex: {}",
291        bytes
292            .iter()
293            .map(|b| format!("{:02x}", b))
294            .collect::<String>()
295    );
296}
Source

pub fn add_conditional_endorsement( self, triple: ConditionalEndorsementTriple, ) -> Self

Add a conditional endorsement triple (§5.1.7).

Source

pub fn build(self) -> Result<ComidTag, BuilderError>

Build the ComidTag.

Returns an error if no triples have been added, or if any triple contains an empty list where the CDDL requires [+ T].

Examples found in repository?
examples/build_corim.rs (line 49)
14fn main() {
15    // Define the target environment
16    let env = EnvironmentMap {
17        class: Some(ClassMap {
18            class_id: None,
19            vendor: Some("ACME Corp".into()),
20            model: Some("Turbo Encabulator".into()),
21            layer: Some(0),
22            index: None,
23        }),
24        instance: None,
25        group: None,
26    };
27
28    // Create a measurement with a SHA-384 digest
29    let measurement = MeasurementMap {
30        mkey: Some(MeasuredElement::Text("firmware".into())),
31        mval: MeasurementValuesMap {
32            digests: Some(vec![Digest::new(7, vec![0xAA; 48])]),
33            ..MeasurementValuesMap::default()
34        },
35        authorized_by: None,
36    };
37
38    // Build a CoMID
39    let comid = ComidBuilder::new(TagIdChoice::Text(
40        "example.com/acme/turbo-encabulator".into(),
41    ))
42    .set_tag_version(0)
43    .add_entity(EntityMap {
44        entity_name: "ACME Corp".into(),
45        reg_id: Some("https://acme.example.com".into()),
46        role: vec![COMID_ROLE_TAG_CREATOR],
47    })
48    .add_reference_triple(ReferenceTriple::new(env, vec![measurement]))
49    .build()
50    .expect("failed to build CoMID");
51
52    // Wrap in a CoRIM and encode
53    let bytes = CorimBuilder::new(CorimId::Text("acme/corim/v1".into()))
54        .set_profile(ProfileChoice::Uri(
55            "https://example.com/acme-profile".into(),
56        ))
57        .set_validity(Some(1700000000), 1900000000)
58        .unwrap()
59        .add_comid_tag(comid)
60        .expect("failed to encode CoMID")
61        .build_bytes()
62        .expect("failed to build CoRIM");
63
64    println!("Encoded CoRIM: {} bytes", bytes.len());
65    println!(
66        "Hex: {}",
67        bytes
68            .iter()
69            .map(|b| format!("{:02x}", b))
70            .collect::<String>()
71    );
72}
More examples
Hide additional examples
examples/build_corim_ovl3_tdisp_ndpa.rs (line 96)
68fn main() {
69    use corim::builder::{ComidBuilder, CorimBuilder};
70    use corim::profile::azure::{AzureProfile, AZURE_PROFILE_URI};
71    use corim::profile::MatchContext;
72    use corim::types::common::TagIdChoice;
73    use corim::types::corim::{CorimId, ProfileChoice};
74    use corim::types::measurement::{MeasurementMap, MeasurementValuesMap, SvnChoice};
75    use corim::types::triples::{
76        CesCommonCondition, ConditionalEndorsementSeriesTriple, ConditionalSeriesRecord,
77    };
78    use corim::validate::{
79        apply_endorsement_series_with_profile, decode_and_validate_at, EvidenceClaim,
80    };
81
82    let ces = ConditionalEndorsementSeriesTriple::new(
83        CesCommonCondition {
84            environment: make_env(),
85            claims_list: vec![],
86            authorized_by: None,
87        },
88        vec![ConditionalSeriesRecord::new(
89            vec![uint_svn_selection(20, 1)],
90            vec![make_addition_uptodate()],
91        )],
92    );
93
94    let comid = ComidBuilder::new(TagIdChoice::Text("1.3.6.1.4.1.311.102.5_NDPA".into()))
95        .add_conditional_endorsement_series(ces)
96        .build()
97        .expect("failed to build CoMID");
98
99    let bytes = CorimBuilder::new(CorimId::Text("1.3.6.1.4.1.311.102.5_NDPA_20260705".into()))
100        .set_profile(ProfileChoice::Uri(AZURE_PROFILE_URI.into()))
101        .add_comid_tag(comid)
102        .expect("failed to encode CoMID")
103        .build_bytes()
104        .expect("failed to build CoRIM");
105
106    let (_corim, comids) =
107        decode_and_validate_at(&bytes, 1_800_000_000).expect("decode_and_validate_at failed");
108    let decoded = &comids[0];
109
110    let profile = AzureProfile::new();
111    let evidence = vec![EvidenceClaim {
112        environment: decoded
113            .triples
114            .conditional_endorsement_series
115            .as_ref()
116            .unwrap()[0]
117            .common_condition()
118            .environment
119            .clone(),
120        measurements: vec![MeasurementMap {
121            mkey: Some(corim::types::common::MeasuredElement::Uint(20)),
122            mval: MeasurementValuesMap {
123                svn: Some(SvnChoice::ExactValue(1)),
124                ..MeasurementValuesMap::default()
125            },
126            authorized_by: None,
127        }],
128    }];
129
130    let ces_endorsed = apply_endorsement_series_with_profile(
131        decoded
132            .triples
133            .conditional_endorsement_series
134            .as_deref()
135            .unwrap(),
136        &evidence,
137        Some(&profile),
138        &MatchContext::new(),
139    )
140    .expect("apply_endorsement_series_with_profile failed");
141    let out = write_cbor_file(&bytes);
142    println!("CES endorsed claims: {}", ces_endorsed.len());
143    println!("Saved CBOR: {}", out.display());
144
145    println!("Encoded CoRIM: {} bytes", bytes.len());
146    println!(
147        "Hex: {}",
148        bytes
149            .iter()
150            .map(|b| format!("{:02x}", b))
151            .collect::<String>()
152    );
153}
examples/build_corim_ovl3_tdisp_socmana.rs (line 96)
68fn main() {
69    use corim::builder::{ComidBuilder, CorimBuilder};
70    use corim::profile::azure::{AzureProfile, AZURE_PROFILE_URI};
71    use corim::profile::MatchContext;
72    use corim::types::common::TagIdChoice;
73    use corim::types::corim::{CorimId, ProfileChoice};
74    use corim::types::measurement::{MeasurementMap, MeasurementValuesMap, SvnChoice};
75    use corim::types::triples::{
76        CesCommonCondition, ConditionalEndorsementSeriesTriple, ConditionalSeriesRecord,
77    };
78    use corim::validate::{
79        apply_endorsement_series_with_profile, decode_and_validate_at, EvidenceClaim,
80    };
81
82    let ces = ConditionalEndorsementSeriesTriple::new(
83        CesCommonCondition {
84            environment: make_env(),
85            claims_list: vec![],
86            authorized_by: None,
87        },
88        vec![ConditionalSeriesRecord::new(
89            vec![uint_svn_selection(19, 1)],
90            vec![make_addition_uptodate()],
91        )],
92    );
93
94    let comid = ComidBuilder::new(TagIdChoice::Text("1.3.6.1.4.1.311.102.5_SOCMANA".into()))
95        .add_conditional_endorsement_series(ces)
96        .build()
97        .expect("failed to build CoMID");
98
99    let bytes = CorimBuilder::new(CorimId::Text(
100        "1.3.6.1.4.1.311.102.5_SOCMANA_20260705".into(),
101    ))
102    .set_profile(ProfileChoice::Uri(AZURE_PROFILE_URI.into()))
103    .add_comid_tag(comid)
104    .expect("failed to encode CoMID")
105    .build_bytes()
106    .expect("failed to build CoRIM");
107
108    let (_corim, comids) =
109        decode_and_validate_at(&bytes, 1_800_000_000).expect("decode_and_validate_at failed");
110    let decoded = &comids[0];
111
112    let profile = AzureProfile::new();
113    let evidence = vec![EvidenceClaim {
114        environment: decoded
115            .triples
116            .conditional_endorsement_series
117            .as_ref()
118            .unwrap()[0]
119            .common_condition()
120            .environment
121            .clone(),
122        measurements: vec![MeasurementMap {
123            mkey: Some(corim::types::common::MeasuredElement::Uint(19)),
124            mval: MeasurementValuesMap {
125                svn: Some(SvnChoice::ExactValue(1)),
126                ..MeasurementValuesMap::default()
127            },
128            authorized_by: None,
129        }],
130    }];
131
132    let ces_endorsed = apply_endorsement_series_with_profile(
133        decoded
134            .triples
135            .conditional_endorsement_series
136            .as_deref()
137            .unwrap(),
138        &evidence,
139        Some(&profile),
140        &MatchContext::new(),
141    )
142    .expect("apply_endorsement_series_with_profile failed");
143    let out = write_cbor_file(&bytes);
144    println!("CES endorsed claims: {}", ces_endorsed.len());
145    println!("Saved CBOR: {}", out.display());
146
147    println!("Encoded CoRIM: {} bytes", bytes.len());
148    println!(
149        "Hex: {}",
150        bytes
151            .iter()
152            .map(|b| format!("{:02x}", b))
153            .collect::<String>()
154    );
155}
examples/build_corim_ovl3_tdisp_sfua.rs (line 239)
166fn main() {
167    use corim::builder::{ComidBuilder, CorimBuilder};
168    use corim::profile::azure::{AzureProfile, AZURE_PROFILE_URI};
169    use corim::profile::MatchContext;
170    use corim::types::common::{CryptoKey, TagIdChoice};
171    use corim::types::corim::{CorimId, ProfileChoice};
172    use corim::types::measurement::{MeasurementMap, MeasurementValuesMap, SvnChoice};
173    use corim::types::triples::IdentityTriple;
174    use corim::validate::{
175        apply_endorsement_series_with_profile, decode_and_validate_at, EvidenceClaim,
176    };
177
178    let selection = make_selection_svn(0);
179    let addition = make_addition_uptodate();
180
181    let ces = make_ces(
182        make_env(Some(0), Some(SPDM_CERTIFICATES)),
183        vec![selection.clone()],
184        addition.clone(),
185    );
186
187    let ces2 = make_ces(
188        make_env(Some(1), Some(SPDM_CERTIFICATES)),
189        vec![selection],
190        addition.clone(),
191    );
192
193    let digest_384 = sha384_digest(vec![
194        0x4b, 0x56, 0xcf, 0xa0, 0x7f, 0xae, 0xb2, 0xab, 0x57, 0xde, 0x92, 0x1e, 0x4a, 0x97, 0xd6,
195        0x55, 0x14, 0x4b, 0x54, 0x64, 0x70, 0xeb, 0xaa, 0xab, 0x6f, 0x71, 0xc0, 0xdb, 0x51, 0x8d,
196        0xdf, 0x5b, 0x4a, 0x5f, 0xb2, 0x8f, 0xb2, 0xad, 0x1b, 0x49, 0x34, 0x26, 0x44, 0x24, 0xeb,
197        0x1e, 0x5a, 0x86,
198    ]);
199
200    let ces3_selection = vec![
201        uint_digest_selection(1, digest_384.clone()),
202        uint_digest_selection(8, digest_384),
203        uint_svn_selection(15, 1),
204        uint_svn_selection(16, 1),
205        uint_svn_selection(17, 1),
206        uint_svn_selection(18, 1),
207        uint_raw_value_selection(
208            254,
209            vec![
210                0x72, 0x61, 0x77, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x0a, 0x72, 0x61, 0x77, 0x76, 0x61,
211                0x6c, 0x75, 0x65, 0x0a,
212            ],
213        ),
214    ];
215
216    let ces3 = make_ces(
217        make_env(None, Some(SPDM_MEASUREMENTS)),
218        ces3_selection,
219        addition.clone(),
220    );
221
222    let thumbprint_bytes: [u8; 32] = [
223        0x44, 0xaa, 0x33, 0x6a, 0xf4, 0xcb, 0x14, 0xa8, 0x79, 0x43, 0x2e, 0x53, 0xdd, 0x65, 0x71,
224        0xc7, 0xfa, 0x9b, 0xcc, 0xaf, 0xb7, 0x5f, 0x48, 0x82, 0x59, 0x26, 0x2d, 0x6e, 0xa3, 0xa4,
225        0xd9, 0x1b,
226    ];
227    let thumbprint = sha256_digest(thumbprint_bytes.to_vec());
228    let id_keys = vec![
229        CryptoKey::CertThumbprint(thumbprint.clone()),
230        CryptoKey::CertThumbprint(thumbprint),
231    ];
232
233    let comid = ComidBuilder::new(TagIdChoice::Text("1.3.6.1.4.1.311.102.5_SFUA".into()))
234        .set_tag_version(1)
235        .add_identity_triple(IdentityTriple::new(make_env(None, None), id_keys, None))
236        .add_conditional_endorsement_series(ces)
237        .add_conditional_endorsement_series(ces2)
238        .add_conditional_endorsement_series(ces3)
239        .build()
240        .expect("failed to build CoMID");
241
242    let bytes = CorimBuilder::new(CorimId::Text("1.3.6.1.4.1.311.102.5_SFUA_20260705".into()))
243        .set_profile(ProfileChoice::Uri(AZURE_PROFILE_URI.into()))
244        .add_comid_tag(comid)
245        .expect("failed to encode CoMID")
246        .build_bytes()
247        .expect("failed to build CoRIM");
248
249    let (_corim, comids) =
250        decode_and_validate_at(&bytes, 1_800_000_000).expect("decode_and_validate_at failed");
251    let decoded = &comids[0];
252
253    let profile = AzureProfile::new();
254    let evidence = vec![EvidenceClaim {
255        environment: decoded
256            .triples
257            .conditional_endorsement_series
258            .as_ref()
259            .unwrap()[0]
260            .common_condition()
261            .environment
262            .clone(),
263        measurements: vec![MeasurementMap {
264            mkey: None,
265            mval: MeasurementValuesMap {
266                svn: Some(SvnChoice::ExactValue(0)),
267                ..MeasurementValuesMap::default()
268            },
269            authorized_by: None,
270        }],
271    }];
272
273    let ces_endorsed = apply_endorsement_series_with_profile(
274        decoded
275            .triples
276            .conditional_endorsement_series
277            .as_deref()
278            .unwrap(),
279        &evidence,
280        Some(&profile),
281        &MatchContext::new(),
282    )
283    .expect("apply_endorsement_series_with_profile failed");
284    let out = write_cbor_file(&bytes);
285    println!("CES endorsed claims: {}", ces_endorsed.len());
286    println!("Saved CBOR: {}", out.display());
287
288    println!("Encoded CoRIM: {} bytes", bytes.len());
289    println!(
290        "Hex: {}",
291        bytes
292            .iter()
293            .map(|b| format!("{:02x}", b))
294            .collect::<String>()
295    );
296}

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.