Skip to content

Commit fdc0e8b

Browse files
committed
Adding method to add reference_triples to CoMIDs
Also added PartialEq, Eq, PartialOrd, Ord to most types. Signed-off-by: Larry Dewey <[email protected]>
1 parent 64aca20 commit fdc0e8b

File tree

8 files changed

+305
-93
lines changed

8 files changed

+305
-93
lines changed

src/comid.rs

Lines changed: 145 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,10 @@
8585
//! All components support optional extensions through [`ExtensionMap`] for future expandability.
8686
8787
use crate::{
88-
generate_tagged, AttestKeyTripleRecord, ConditionalEndorsementSeriesTripleRecord,
88+
core::{RawValueType, TaggedBytes},
89+
generate_tagged,
90+
triples::{EnvironmentMap, MeasuredElementTypeChoice, MeasurementMap, MeasurementValuesMap},
91+
AttestKeyTripleRecord, ConditionalEndorsementSeriesTripleRecord,
8992
ConditionalEndorsementTripleRecord, CoswidTripleRecord, DomainDependencyTripleRecord,
9093
DomainMembershipTripleRecord, EndorsedTripleRecord, ExtensionMap, IdentityTripleRecord,
9194
OneOrMany, ReferenceTripleRecord, Text, Tstr, Uint, Uri, UuidType,
@@ -104,7 +107,7 @@ generate_tagged!((
104107
"A Concise Module Identifier (CoMID) structured tag"
105108
),);
106109
/// A Concise Module Identifier (CoMID) tag structure tagged with CBOR tag 506
107-
#[derive(Debug, Serialize, Deserialize, From, Constructor)]
110+
#[derive(Debug, Serialize, Deserialize, From, Constructor, PartialEq, Eq, PartialOrd, Ord)]
108111
#[repr(C)]
109112
pub struct ConciseMidTag<'a> {
110113
/// Optional language identifier for the tag content
@@ -126,8 +129,141 @@ pub struct ConciseMidTag<'a> {
126129
pub extension: Option<ExtensionMap<'a>>,
127130
}
128131

132+
impl<'a> ConciseMidTag<'a> {
133+
/// Adds a reference value to the CoMID tag's reference triples.
134+
///
135+
/// This method serializes the provided value to CBOR bytes and adds it as a raw measurement value
136+
/// within a reference triple. If a reference triple with the same environment already exists,
137+
/// the measurement is added to that triple. Otherwise, a new reference triple is created.
138+
///
139+
/// # Arguments
140+
///
141+
/// * `environment` - The environment map that describes the context for this reference value
142+
/// * `mkey` - Optional measurement element type that identifies what is being measured
143+
/// * `value` - The value to serialize and store as the reference value
144+
///
145+
/// # Returns
146+
///
147+
/// Returns `Ok(())` if successful, or an `std::io::Error` if serialization fails.
148+
///
149+
/// # Example
150+
///
151+
/// ``` ignore
152+
/// use corim_rs::{
153+
/// comid::{ConciseMidTag, TagIdentityMap, ComidEntityMap, TriplesMap, TagIdTypeChoice},
154+
/// core::{OneOrMore, Text, Tstr},
155+
/// triples::{EnvironmentMap, MeasuredElementTypeChoice},
156+
/// };
157+
///
158+
/// let mut comid = ConciseMidTag {
159+
/// language: None,
160+
/// tag_identity: TagIdentityMap {
161+
/// tag_id: TagIdTypeChoice::Tstr(Tstr::from("example-id")),
162+
/// tag_version: Some(1),
163+
/// },
164+
/// entities: OneOrMore::One(ComidEntityMap {
165+
/// entity_name: Text::from("Example Corp"),
166+
/// reg_id: None,
167+
/// role: OneOrMore::One(corim_rs::comid::ComidRoleTypeChoice::TagCreator),
168+
/// extension: None,
169+
/// }),
170+
/// linked_tags: None,
171+
/// triples: TriplesMap::default(),
172+
/// extension: None,
173+
/// };
174+
///
175+
/// // Add a reference value
176+
/// let env = EnvironmentMap::default();
177+
/// let reference_data = "example reference value";
178+
/// comid.add_reference_value(env, None, &reference_data).expect("Failed to add reference value");
179+
/// ```
180+
///
181+
/// # How It Works
182+
///
183+
/// 1. The value is serialized to CBOR bytes using the `ciborium` library
184+
/// 2. The bytes are wrapped in a `TaggedBytes` structure
185+
/// 3. A `MeasurementMap` is created with the provided measurement key and the raw value
186+
/// 4. The method then updates the CoMID's reference triples based on existing data:
187+
/// - If no reference triples exist, a new one is created
188+
/// - If a reference triple with the matching environment exists, the measurement is added to it
189+
/// - If reference triples exist but none match the environment, a new triple is added
190+
pub fn add_reference_value<T>(
191+
&mut self,
192+
environment: EnvironmentMap<'a>,
193+
mkey: Option<MeasuredElementTypeChoice<'a>>,
194+
value: &T,
195+
) -> Result<(), std::io::Error>
196+
where
197+
T: ?Sized + Serialize,
198+
{
199+
let mut raw_bytes = vec![];
200+
ciborium::into_writer(value, &mut raw_bytes)
201+
.map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e.to_string()))?;
202+
let raw_value = TaggedBytes::new(raw_bytes);
203+
204+
let measurement = MeasurementMap {
205+
mkey,
206+
mval: MeasurementValuesMap {
207+
raw: Some(RawValueType {
208+
raw_value: raw_value.into(),
209+
raw_value_mask: None,
210+
}),
211+
..Default::default()
212+
},
213+
authorized_by: None,
214+
};
215+
216+
match &mut self.triples.reference_triples {
217+
None => {
218+
let new_record = ReferenceTripleRecord {
219+
ref_env: environment,
220+
ref_claims: measurement.into(),
221+
};
222+
self.triples.reference_triples = Some(OneOrMany::One(new_record));
223+
}
224+
Some(OneOrMany::One(record)) => {
225+
if record.ref_env == environment {
226+
match &mut record.ref_claims {
227+
OneOrMany::One(original_claim) => {
228+
record.ref_claims =
229+
OneOrMany::Many(vec![std::mem::take(original_claim), measurement])
230+
}
231+
OneOrMany::Many(claims) => claims.push(measurement),
232+
}
233+
} else {
234+
let new_record: ReferenceTripleRecord<'a> = ReferenceTripleRecord {
235+
ref_env: environment,
236+
ref_claims: measurement.into(),
237+
};
238+
239+
let many = vec![std::mem::take(record), new_record];
240+
self.triples.reference_triples = Some(OneOrMany::Many(many));
241+
}
242+
}
243+
Some(OneOrMany::Many(vec)) => {
244+
if let Some(record) = vec.iter_mut().find(|r| r.ref_env == environment) {
245+
match &mut record.ref_claims {
246+
OneOrMany::One(claim) => {
247+
record.ref_claims =
248+
OneOrMany::Many(vec![std::mem::take(claim), measurement])
249+
}
250+
OneOrMany::Many(claims) => claims.push(measurement),
251+
}
252+
} else {
253+
let new_record = ReferenceTripleRecord {
254+
ref_env: environment,
255+
ref_claims: measurement.into(),
256+
};
257+
vec.push(new_record);
258+
}
259+
}
260+
}
261+
Ok(())
262+
}
263+
}
264+
129265
/// Identification information for a tag
130-
#[derive(Debug, Serialize, Deserialize, From, Constructor)]
266+
#[derive(Debug, Serialize, Deserialize, From, Constructor, PartialEq, Eq, PartialOrd, Ord)]
131267
#[repr(C)]
132268
pub struct TagIdentityMap<'a> {
133269
/// Unique identifier for the tag
@@ -140,7 +276,7 @@ pub struct TagIdentityMap<'a> {
140276
}
141277

142278
/// Represents either a string or UUID tag identifier
143-
#[derive(Debug, Serialize, Deserialize, From, TryFrom)]
279+
#[derive(Debug, Serialize, Deserialize, From, TryFrom, PartialEq, Eq, PartialOrd, Ord)]
144280
#[repr(C)]
145281
pub enum TagIdTypeChoice<'a> {
146282
/// Text string identifier
@@ -156,7 +292,7 @@ impl<'a> From<&'a str> for TagIdTypeChoice<'a> {
156292
}
157293

158294
/// Information about an entity associated with the tag
159-
#[derive(Debug, Serialize, Deserialize, From, Constructor)]
295+
#[derive(Debug, Serialize, Deserialize, From, Constructor, PartialEq, Eq, PartialOrd, Ord)]
160296
#[repr(C)]
161297
pub struct ComidEntityMap<'a> {
162298
/// Name of the entity
@@ -175,7 +311,7 @@ pub struct ComidEntityMap<'a> {
175311
}
176312

177313
/// Role types that can be assigned to entities
178-
#[derive(Debug, Serialize, Deserialize, From, TryFrom)]
314+
#[derive(Debug, Serialize, Deserialize, From, TryFrom, PartialEq, Eq, PartialOrd, Ord)]
179315
#[repr(C)]
180316
pub enum ComidRoleTypeChoice {
181317
/// Entity that created the tag (value: 0)
@@ -187,7 +323,7 @@ pub enum ComidRoleTypeChoice {
187323
}
188324

189325
/// Reference to another tag and its relationship to this one
190-
#[derive(Debug, Serialize, Deserialize, From, Constructor)]
326+
#[derive(Debug, Serialize, Deserialize, From, Constructor, PartialEq, Eq, PartialOrd, Ord)]
191327
#[repr(C)]
192328
pub struct LinkedTagMap<'a> {
193329
/// Identifier of the linked tag
@@ -199,7 +335,7 @@ pub struct LinkedTagMap<'a> {
199335
}
200336

201337
/// Types of relationships between tags
202-
#[derive(Debug, Serialize, Deserialize, From, TryFrom)]
338+
#[derive(Debug, Serialize, Deserialize, From, TryFrom, PartialEq, Eq, PartialOrd, Ord)]
203339
#[repr(C)]
204340
pub enum TagRelTypeChoice {
205341
/// This tag supplements the linked tag by providing additional information
@@ -211,7 +347,7 @@ pub enum TagRelTypeChoice {
211347
}
212348

213349
/// Collection of different types of triples describing the module characteristics
214-
#[derive(Default, Debug, Serialize, Deserialize, From)]
350+
#[derive(Default, Debug, Serialize, Deserialize, From, PartialEq, Eq, PartialOrd, Ord)]
215351
#[repr(C)]
216352
pub struct TriplesMap<'a> {
217353
/// Optional reference triples that link to external references

src/core.rs

Lines changed: 32 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -66,11 +66,6 @@ pub type Int = i32;
6666
/// Integer is an alias for Int type
6767
pub type Integer = Int;
6868

69-
pub enum StrWrapper<'a, T> {
70-
Tstr(Tstr<'a>),
71-
Other(T),
72-
}
73-
7469
/// ExtensionMap represents the possible types that can be used in extensions
7570
#[derive(Debug, Serialize, Deserialize, Ord, PartialOrd, Eq, PartialEq, From, TryFrom)]
7671
pub enum ExtensionMap<'a> {
@@ -91,7 +86,20 @@ pub enum ExtensionMap<'a> {
9186
}
9287

9388
/// UUID type representing a 16-byte unique identifier
94-
#[derive(Default, Debug, Serialize, Deserialize, From, AsRef, AsMut, Constructor)]
89+
#[derive(
90+
Default,
91+
Debug,
92+
Serialize,
93+
Deserialize,
94+
From,
95+
AsRef,
96+
AsMut,
97+
Constructor,
98+
PartialEq,
99+
Eq,
100+
PartialOrd,
101+
Ord,
102+
)]
95103
pub struct UuidType {
96104
#[serde(flatten)]
97105
pub field: [u8; 16],
@@ -107,7 +115,7 @@ impl TryFrom<&[u8]> for UuidType {
107115
}
108116

109117
/// UEID type representing a 33-byte Unique Entity Identifier
110-
#[derive(Debug, Serialize, Deserialize, From, Constructor)]
118+
#[derive(Debug, Serialize, Deserialize, From, Constructor, PartialEq, Eq, PartialOrd, Ord)]
111119
pub struct UeidType {
112120
#[serde(flatten)]
113121
pub field: FixedBytes<33>,
@@ -134,7 +142,7 @@ generate_tagged!(
134142

135143
/// Represents a value that can be either text or bytes
136144
#[repr(C)]
137-
#[derive(Debug, Serialize, Deserialize, From, TryFrom)]
145+
#[derive(Debug, Serialize, Deserialize, From, TryFrom, PartialEq, Eq, PartialOrd, Ord)]
138146
pub enum TextOrBytes<'a> {
139147
/// UTF-8 string value
140148
Text(Text<'a>),
@@ -144,7 +152,7 @@ pub enum TextOrBytes<'a> {
144152

145153
/// Represents a value that can be either text or fixed-size bytes
146154
#[repr(C)]
147-
#[derive(Debug, Serialize, Deserialize, From, TryFrom)]
155+
#[derive(Debug, Serialize, Deserialize, From, TryFrom, PartialEq, Eq, PartialOrd, Ord)]
148156
pub enum TextOrBytesSized<'a, const N: usize> {
149157
/// UTF-8 string value
150158
Text(Text<'a>),
@@ -154,7 +162,7 @@ pub enum TextOrBytesSized<'a, const N: usize> {
154162

155163
/// Represents a hash entry with algorithm ID and hash value
156164
#[repr(C)]
157-
#[derive(Debug, Serialize, Deserialize, From, Constructor)]
165+
#[derive(Debug, Serialize, Deserialize, From, Constructor, PartialEq, Eq, PartialOrd, Ord)]
158166
pub struct HashEntry {
159167
/// Algorithm identifier for the hash
160168
#[serde(rename = "hash-alg-id")]
@@ -205,7 +213,7 @@ pub enum OneOrMany<T> {
205213
}
206214

207215
/// Represents an attribute value that can be either text or integer, single or multiple
208-
#[derive(Debug, Clone, PartialEq, Eq, Ord, PartialOrd, Serialize, Deserialize, From, TryFrom)]
216+
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize, From, TryFrom)]
209217
#[serde(untagged)]
210218
#[repr(C)]
211219
pub enum AttributeValue<'a> {
@@ -214,7 +222,9 @@ pub enum AttributeValue<'a> {
214222
}
215223

216224
/// Represents global attributes with optional language tag and arbitrary attributes
217-
#[derive(Default, Debug, Clone, Serialize, Deserialize, From, Constructor)]
225+
#[derive(
226+
Default, Debug, Clone, Serialize, Deserialize, From, Constructor, PartialEq, Eq, PartialOrd, Ord,
227+
)]
218228
#[repr(C)]
219229
pub struct GlobalAttributes<'a> {
220230
/// Optional language tag (ex. en_US)
@@ -273,7 +283,7 @@ pub enum CotlMapRegistry {
273283

274284
/// Represents a digest value with its algorithm identifier
275285
#[repr(C)]
276-
#[derive(Debug, Serialize, Deserialize, From, Constructor)]
286+
#[derive(Debug, Serialize, Deserialize, From, Constructor, PartialEq, Eq, PartialOrd, Ord)]
277287
pub struct Digest<'a> {
278288
/// Algorithm identifier for the digest
279289
pub alg: AlgLabel<'a>,
@@ -283,7 +293,7 @@ pub struct Digest<'a> {
283293

284294
/// Represents either a COSE key set or a single COSE key
285295
#[repr(C)]
286-
#[derive(Debug, Serialize, Deserialize, From, TryFrom)]
296+
#[derive(Debug, Serialize, Deserialize, From, TryFrom, PartialEq, Eq, PartialOrd, Ord)]
287297
pub enum CoseKeySetOrKey<'a> {
288298
/// A set of COSE keys
289299
KeySet(OneOrMany<CoseKey<'a>>),
@@ -292,7 +302,7 @@ pub enum CoseKeySetOrKey<'a> {
292302
}
293303

294304
/// Represents a COSE key structure as defined in RFC 8152
295-
#[derive(Debug, Serialize, Deserialize, From, Constructor)]
305+
#[derive(Debug, Serialize, Deserialize, From, Constructor, PartialEq, Eq, PartialOrd, Ord)]
296306
#[repr(C)]
297307
pub struct CoseKey<'a> {
298308
/// Key type identifier (kty)
@@ -316,15 +326,17 @@ pub struct CoseKey<'a> {
316326
pub extension: Option<ExtensionMap<'a>>,
317327
}
318328

319-
#[derive(Default, Debug, Serialize, Deserialize, From, Constructor)]
329+
#[derive(
330+
Default, Debug, Serialize, Deserialize, From, Constructor, PartialEq, Eq, PartialOrd, Ord,
331+
)]
320332
#[repr(C)]
321333
/// Raw value data structure with associated mask
322334
pub struct MaskedRawValue {
323335
pub value: Bytes,
324336
pub mask: Bytes,
325337
}
326338

327-
#[derive(Debug, Serialize, Deserialize, From, Constructor)]
339+
#[derive(Debug, Serialize, Deserialize, From, Constructor, PartialEq, Eq, PartialOrd, Ord)]
328340
#[repr(C)]
329341
/// Container for raw values with optional masking
330342
pub struct RawValueType {
@@ -335,7 +347,7 @@ pub struct RawValueType {
335347
/// Type alias for raw value masks
336348
pub type RawValueMaskType = Bytes;
337349

338-
#[derive(Debug, Serialize, Deserialize, From)]
350+
#[derive(Debug, Serialize, Deserialize, From, PartialEq, Eq, PartialOrd, Ord)]
339351
/// Represents different types of raw values
340352
pub enum RawValueTypeChoice {
341353
TaggedBytes(TaggedBytes),
@@ -344,7 +356,7 @@ pub enum RawValueTypeChoice {
344356

345357
/// Version scheme enumeration as defined in the specification
346358
#[repr(C)]
347-
#[derive(Debug, Serialize, Deserialize, From, TryFrom)]
359+
#[derive(Debug, Serialize, Deserialize, From, TryFrom, PartialEq, Eq, PartialOrd, Ord)]
348360
pub enum VersionScheme {
349361
/// Multi-part numeric version (e.g., 1.2.3)
350362
Multipartnumeric = 1,
@@ -392,7 +404,7 @@ pub enum VersionScheme {
392404
/// let alg = CoseAlgorithm::ES256; // ECDSA with SHA-256
393405
/// let hash_alg = CoseAlgorithm::Sha256; // SHA-256 hash function
394406
/// ```
395-
#[derive(Debug, Clone, PartialEq, Eq, Ord, PartialOrd, Serialize, Deserialize)]
407+
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
396408
#[repr(i64)]
397409
pub enum CoseAlgorithm {
398410
/// Reserved for private use (-65536)

0 commit comments

Comments
 (0)