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}

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 selection-side measurement (CES claims_list, CES series selection, 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 domain 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 CesCondition 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}
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).

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: DomainDependencyTriple) -> Self

Add a domain 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).

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}

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.