Skip to main content

rasn_its/ieee1609dot2/
base_types.rs

1extern crate alloc;
2use crate::delegate;
3use crate::ts103097::extension_module::ExtId;
4use bon::Builder;
5use rasn::prelude::*;
6
7/// OID for IEEE 1609.2 Base Types module
8pub const IEEE1609_DOT2_BASE_TYPES_OID: &Oid = Oid::const_new(&[
9    1,    // iso
10    3,    // identified-organization
11    111,  // ieee
12    2,    // standards-association-numbered-series-standards
13    1609, // wave-stds
14    2,    // dot2
15    1,    // base
16    2,    // base-types
17    2,    // major-version-2
18    4,    // minor-version-4
19]);
20
21// ***************************************************************************
22// **                            Integer Types                              **
23// ***************************************************************************
24/// This atomic type is used in the definition of other data structures.
25/// It is for non-negative integers up to 7, i.e., (hex)07.
26#[derive(AsnType, Debug, Clone, Decode, Encode, PartialEq, Eq, Hash, PartialOrd, Ord)]
27#[rasn(delegate, value("0..=7"))]
28pub struct Uint3(pub u8);
29/// This atomic type is used in the definition of other data structures.
30/// It is for non-negative integers up to 255, i.e., (hex)ff.
31pub type Uint8 = u8;
32/// This atomic type is used in the definition of other data structures.
33/// It is for non-negative integers up to 65,535, i.e., (hex)ff ff.
34pub type Uint16 = u16;
35/// This atomic type is used in the definition of other data structures.
36/// It is for non-negative integers up to 4,294,967,295, i.e.,
37/// (hex)ff ff ff ff.
38pub type Uint32 = u32;
39/// This atomic type is used in the definition of other data structures.
40/// It is for non-negative integers up to 18,446,744,073,709,551,615, i.e.,
41/// (hex)ff ff ff ff ff ff ff ff.
42pub type Uint64 = u64;
43
44/// This type is used for clarity of definitions.
45#[derive(AsnType, Debug, Clone, Decode, Encode, PartialEq, Eq, Hash, PartialOrd, Ord)]
46#[rasn(delegate)]
47pub struct SequenceOfUint16(pub SequenceOf<Uint16>);
48
49delegate!(SequenceOf<Uint16>, SequenceOfUint16);
50
51/// This type is used for clarity of definitions.
52#[derive(AsnType, Debug, Clone, Decode, Encode, PartialEq, Eq, Hash, PartialOrd, Ord)]
53#[rasn(delegate)]
54pub struct SequenceOfUint8(pub SequenceOf<Uint8>);
55
56delegate!(SequenceOf<Uint8>, SequenceOfUint8);
57
58// ***************************************************************************
59// **                          OCTET STRING Types                           **
60// ***************************************************************************
61
62/// This is a synonym for ASN.1 OCTET STRING, and is used in the
63/// definition of other data structures.
64#[derive(AsnType, Debug, Clone, Decode, Encode, PartialEq, Eq, Hash, PartialOrd, Ord)]
65#[rasn(delegate)]
66pub struct Opaque(pub OctetString);
67
68delegate!(OctetString, Opaque);
69
70/// A type containing the truncated hash of another data structure.
71///
72/// # Hash Calculation
73/// The `HashedId3` is calculated by:
74/// 1. Computing the hash of the encoded data structure
75/// 2. Taking the low-order three bytes of the hash output
76/// 3. Using the last three bytes of the 32-byte hash when represented in network byte order
77/// 4. Canonicalizing the data structure before hashing if required
78///
79/// # Hash Algorithm Selection
80/// The hash algorithm used for calculating `HashedId3` is context-dependent:
81/// - Each structure including a `HashedId3` field specifies how the hash algorithm
82///   is determined
83/// - See discussion in section 5.3.9 for more details
84///
85/// # Example
86/// Using SHA-256 hash of an empty string:
87/// ```text
88/// SHA-256("") =
89/// e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
90///
91/// Resulting HashedId3 = 52b855
92/// ```
93#[derive(AsnType, Debug, Clone, Decode, Encode, PartialEq, Eq, Hash, PartialOrd, Ord)]
94#[rasn(delegate)]
95pub struct HashedId3(pub FixedOctetString<3usize>);
96
97delegate!(FixedOctetString<3usize>, HashedId3);
98
99/// This type is used for clarity of definitions.
100#[derive(AsnType, Debug, Clone, Decode, Encode, PartialEq, Eq, Hash, PartialOrd, Ord)]
101#[rasn(delegate)]
102pub struct SequenceOfHashedId3(pub SequenceOf<HashedId3>);
103
104delegate!(SequenceOf<HashedId3>, SequenceOfHashedId3);
105
106/// A type containing the truncated hash of another data structure.
107///
108/// # Hash Calculation
109/// The `HashedId8` is calculated by:
110/// 1. Computing the hash of the encoded data structure
111/// 2. Taking the low-order eight bytes of the hash output
112/// 3. Using the last eight bytes of the hash when represented in network byte order
113/// 4. Canonicalizing the data structure before hashing if required
114///
115/// # Hash Algorithm Selection
116/// The hash algorithm used for calculating `HashedId8` is context-dependent:
117/// - Each structure including a `HashedId8` field specifies how the hash algorithm
118///   is determined
119/// - See discussion in section 5.3.9 for more details
120///
121/// # Example
122/// Using SHA-256 hash of an empty string:
123/// ```text
124/// SHA-256("") =
125/// e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
126///
127/// Resulting HashedId8 = a495991b7852b855
128/// ```
129#[derive(AsnType, Debug, Clone, Decode, Encode, PartialEq, Eq, Hash, PartialOrd, Ord)]
130#[rasn(delegate)]
131pub struct HashedId8(pub FixedOctetString<8usize>);
132
133delegate!(FixedOctetString<8usize>, HashedId8);
134
135/// A type containing the truncated hash of another data structure.
136///
137/// # Hash Calculation
138/// The `HashedId10` is calculated by:
139/// 1. Computing the hash of the encoded data structure
140/// 2. Taking the low-order ten bytes of the hash output
141/// 3. Using the last ten bytes of the hash when represented in network byte order
142/// 4. Canonicalizing the data structure before hashing if required
143///
144/// # Hash Algorithm Selection
145/// The hash algorithm used for calculating `HashedId10` is context-dependent:
146/// - Each structure including a `HashedId10` field specifies how the hash algorithm
147///   is determined
148/// - See discussion in section 5.3.9 for more details
149///
150/// # Example
151/// Using SHA-256 hash of an empty string:
152/// ```text
153/// SHA-256("") =
154/// e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
155///
156/// Resulting HashedId10 = 934ca495991b7852b855
157/// ```
158
159#[derive(AsnType, Debug, Clone, Decode, Encode, PartialEq, Eq, Hash, PartialOrd, Ord)]
160#[rasn(delegate)]
161pub struct HashedId10(pub FixedOctetString<10usize>);
162
163delegate!(FixedOctetString<10usize>, HashedId10);
164
165/// A type containing the truncated hash of another data structure.
166///
167/// # Hash Calculation
168/// The `HashedId32` is calculated by:
169/// 1. Computing the hash of the encoded data structure
170/// 2. Taking the low-order 32 bytes of the hash output
171/// 3. Using the last 32 bytes of the hash when represented in network byte order
172/// 4. Canonicalizing the data structure before hashing if required
173///
174/// # Hash Algorithm Selection
175/// The hash algorithm used for calculating `HashedId32` is context-dependent:
176/// - Each structure including a `HashedId32` field specifies how the hash algorithm
177///   is determined
178/// - See discussion in section 5.3.9 for more details
179///
180/// # Example
181/// Using SHA-256 hash of an empty string:
182/// ```text
183/// SHA-256("") =
184/// e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
185///
186/// Resulting HashedId32 =
187/// e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
188/// ```
189
190#[derive(AsnType, Debug, Clone, Decode, Encode, PartialEq, Eq, Hash, PartialOrd, Ord)]
191#[rasn(delegate)]
192pub struct HashedId32(pub FixedOctetString<32usize>);
193
194delegate!(FixedOctetString<32usize>, HashedId32);
195
196/// A type containing the truncated hash of another data structure.
197///
198/// # Hash Calculation
199/// The `HashedId48` is calculated by:
200/// 1. Computing the hash of the encoded data structure
201/// 2. Taking the low-order 48 bytes of the hash output
202/// 3. Using the last 48 bytes of the hash when represented in network byte order
203/// 4. Canonicalizing the data structure before hashing if required
204///
205/// # Hash Algorithm Selection
206/// The hash algorithm used for calculating `HashedId48` is context-dependent:
207/// - Each structure including a `HashedId48` field specifies how the hash algorithm
208///   is determined
209/// - See discussion in section 5.3.9 for more details
210///
211/// # Example
212/// Using SHA-384 hash of an empty string:
213/// ```text
214/// SHA-384("") =
215/// 38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b
216///
217/// Resulting HashedId48 =
218/// 38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b
219/// ```
220#[derive(AsnType, Debug, Clone, Decode, Encode, PartialEq, Eq, Hash, PartialOrd, Ord)]
221#[rasn(delegate)]
222pub struct HashedId48(pub FixedOctetString<48usize>);
223
224delegate!(FixedOctetString<48usize>, HashedId48);
225
226// ***************************************************************************
227// **                           Time Structures                             **
228// ***************************************************************************
229
230/// This type gives the number of (TAI) seconds since 00:00:00 UTC, 1
231/// January, 2004.
232#[derive(AsnType, Debug, Clone, Decode, Encode, PartialEq, Eq, Hash, PartialOrd, Ord)]
233#[rasn(delegate)]
234pub struct Time32(pub Uint32);
235
236delegate!(Uint32, Time32);
237
238/// This data structure is a 64-bit integer giving an estimate of the
239/// number of (TAI) microseconds since 00:00:00 UTC, 1 January, 2004.
240#[derive(AsnType, Debug, Clone, Decode, Encode, PartialEq, Eq, Hash, PartialOrd, Ord)]
241#[rasn(delegate)]
242pub struct Time64(pub Uint64);
243
244delegate!(Uint64, Time64);
245
246/// This type gives the validity period of a certificate.
247/// The start of the validity period is given by `start` and the end is given by `start + duration`.
248#[derive(Builder, AsnType, Debug, Clone, Decode, Encode, PartialEq, Eq, Hash, PartialOrd, Ord)]
249#[rasn(automatic_tags)]
250pub struct ValidityPeriod {
251    pub start: Time32,
252    pub duration: Duration,
253}
254
255/// This structure represents the duration of validity of a certificate.
256/// The Uint16 value is the duration, given in the units denoted by the indicated choice.
257/// A year is considered to be 31,556,952 seconds, which is the average number of seconds in a year.
258///
259/// # Note
260/// Years can be mapped more closely to wall-clock days using the `hours` choice for up to 7 years
261/// and the `sixtyHours` choice for up to 448 years.
262#[derive(AsnType, Debug, Clone, Decode, Encode, PartialEq, Eq, Hash, PartialOrd, Ord)]
263#[rasn(choice, automatic_tags)]
264pub enum Duration {
265    Microseconds(Uint16),
266    Milliseconds(Uint16),
267    Seconds(Uint16),
268    Minutes(Uint16),
269    Hours(Uint16),
270    SixtyHours(Uint16),
271    Years(Uint16),
272}
273
274// ***************************************************************************
275// **                           Location Structures                         **
276// ***************************************************************************
277
278/// Geographic region representation with specified forms.
279///
280/// A certificate is not valid if any part of the region indicated in its scope field
281/// lies outside the region indicated in the scope of its issuer.
282///
283/// # Variants
284/// - `CircularRegion`: Contains a single instance of the `CircularRegion` structure
285/// - `RectangularRegion`: Array of `RectangularRegion` structures containing at least
286///   one entry. Interpreted as a series of rectangles, which may overlap or be
287///   disjoint. The permitted region is any point within any of the rectangles.
288/// - `PolygonalRegion`: Contains a single instance of the `PolygonalRegion` structure
289/// - `IdentifiedRegion`: Array of `IdentifiedRegion` structures containing at least
290///   one entry. The permitted region is any point within any of the identified regions.
291///
292/// # Critical Information Fields
293/// This is a critical information field as defined in 5.2.6:
294///
295/// - An implementation that does not recognize the indicated CHOICE when verifying
296///   a signed SPDU shall indicate that the signed SPDU is invalid (per 4.2.2.3.2)
297///
298/// - For `RectangularRegion`:
299///   - Implementation must support at least eight entries
300///   - If number of entries is not supported, SPDU must be marked invalid
301///
302/// - For `IdentifiedRegion`:
303///   - Implementation must support at least eight entries
304///   - If number of entries is not supported, SPDU must be marked invalid
305#[derive(AsnType, Debug, Clone, Decode, Encode, PartialEq, Eq, Hash, PartialOrd, Ord)]
306#[rasn(choice, automatic_tags)]
307#[non_exhaustive]
308pub enum GeographicRegion {
309    CircularRegion(CircularRegion),
310    RectangularRegion(SequenceOfRectangularRegion),
311    PolygonalRegion(PolygonalRegion),
312    IdentifiedRegion(SequenceOfIdentifiedRegion),
313}
314/// A structure specifying a circle with its center at `center`, radius in meters,
315/// and located tangential to the reference ellipsoid.
316///
317/// The indicated region includes all points on the surface of the reference
318/// ellipsoid whose distance to the center point over the reference ellipsoid
319/// is less than or equal to the radius.
320///
321/// # Note
322/// A point containing an elevation component is considered to be within the
323/// circular region if its horizontal projection onto the reference ellipsoid
324/// lies within the region.
325#[derive(Builder, AsnType, Debug, Clone, Decode, Encode, PartialEq, Eq, Hash, PartialOrd, Ord)]
326#[rasn(automatic_tags)]
327pub struct CircularRegion {
328    pub center: TwoDLocation,
329    pub radius: Uint16,
330}
331/// Specifies a "rectangle" on the surface of the WGS84 ellipsoid where the sides
332/// are given by lines of constant latitude or longitude.
333///
334/// # Points with Elevation
335/// A point which contains an elevation component is considered to be within the
336/// rectangular region if its horizontal projection onto the reference ellipsoid
337/// lies within the region.
338///
339/// # Validity Rules
340/// A RectangularRegion is invalid if:
341/// - The `north_west` value is south of the `south_east` value
342/// - The latitude values in the two points are equal
343/// - The longitude values in the two points are equal
344///
345/// A certificate containing an invalid RectangularRegion is considered invalid.
346///
347/// # Fields
348/// - `north_west`: The north-west corner of the rectangle
349/// - `south_east`: The south-east corner of the rectangle
350#[derive(Builder, AsnType, Debug, Clone, Decode, Encode, PartialEq, Eq, Hash, PartialOrd, Ord)]
351#[rasn(automatic_tags)]
352pub struct RectangularRegion {
353    #[rasn(identifier = "northWest")]
354    pub north_west: TwoDLocation,
355    #[rasn(identifier = "southEast")]
356    pub south_east: TwoDLocation,
357}
358
359/// This type is used for clarity of definitions.
360#[derive(AsnType, Debug, Clone, Decode, Encode, PartialEq, Eq, Hash, PartialOrd, Ord)]
361#[rasn(delegate)]
362pub struct SequenceOfRectangularRegion(pub SequenceOf<RectangularRegion>);
363
364delegate!(SequenceOf<RectangularRegion>, SequenceOfRectangularRegion);
365
366/// Defines a region using a series of distinct geographic points on the surface of
367/// the reference ellipsoid.
368///
369/// The region is specified by:
370/// - Connecting points in their order of appearance via geodesics on the reference ellipsoid
371/// - Completing the polygon by connecting the final point to the first point
372/// - The allowed region is the interior of the polygon and its boundary
373///
374/// # Points with Elevation
375/// A point containing an elevation component is considered within the polygonal
376/// region if its horizontal projection onto the reference ellipsoid lies within
377/// the region.
378///
379/// # Validity Rules
380/// A valid `PolygonalRegion`:
381/// - Must contain at least three points
382/// - Must not have intersecting sides (implied lines making up the polygon)
383///
384/// # Limitations
385/// Does not support enclaves/exclaves (may be addressed in future versions of
386/// the standard).
387///
388/// # Critical Information Fields
389/// This is a critical information field as defined in 5.2.6:
390/// - Implementation must support at least eight `TwoDLocation` entries
391/// - If the number of `TwoDLocation` entries is not supported when verifying
392///   a signed SPDU, the implementation must indicate that the SPDU is invalid
393#[derive(AsnType, Debug, Clone, Decode, Encode, PartialEq, Eq, Hash, PartialOrd, Ord)]
394#[rasn(delegate, size("3.."))]
395pub struct PolygonalRegion(pub SequenceOf<TwoDLocation>);
396
397delegate!(SequenceOf<TwoDLocation>, PolygonalRegion);
398
399/// Defines a region using a series of distinct geographic points on the surface of
400/// the reference ellipsoid.
401///
402/// The region is specified by:
403/// - Connecting points in their order of appearance via geodesics on the reference ellipsoid
404/// - Completing the polygon by connecting the final point to the first point
405/// - The allowed region is the interior of the polygon and its boundary
406///
407/// # Points with Elevation
408/// A point containing an elevation component is considered within the polygonal
409/// region if its horizontal projection onto the reference ellipsoid lies within
410/// the region.
411///
412/// # Validity Rules
413/// A valid `PolygonalRegion`:
414/// - Must contain at least three points
415/// - Must not have intersecting sides (implied lines making up the polygon)
416///
417/// # Limitations
418/// Does not support enclaves/exclaves (may be addressed in future versions of
419/// the standard).
420///
421/// # Critical Information Fields
422/// This is a critical information field as defined in 5.2.6:
423/// - Implementation must support at least eight `TwoDLocation` entries
424/// - If the number of `TwoDLocation` entries is not supported when verifying
425///   a signed SPDU, the implementation must indicate that the SPDU is invalid
426#[derive(Builder, AsnType, Debug, Clone, Decode, Encode, PartialEq, Eq, Hash, PartialOrd, Ord)]
427#[rasn(automatic_tags)]
428pub struct TwoDLocation {
429    pub latitude: Latitude,
430    pub longitude: Longitude,
431}
432/// Indicates the region of validity of a certificate using region identifiers.
433///
434/// A conformant implementation must support at least one of the possible CHOICE values.
435/// The Protocol Implementation Conformance Statement (PICS) in Annex A allows an
436/// implementation to state which `CountryOnly` values it recognizes.
437///
438/// # Variants
439/// - `CountryOnly`: Indicates only a country (or a geographic entity included in
440///   a country list) is given
441/// - `CountryAndRegions`: Indicates one or more top-level regions within a country
442///   (as defined by the region listing associated with that country) is given
443/// - `CountryAndSubregions`: Indicates one or more regions smaller than the
444///   top-level regions within a country (as defined by the region listing
445///   associated with that country) is given
446///
447/// # Critical Information Fields
448/// This is a critical information field as defined in 5.2.6:
449/// - An implementation that does not recognize the indicated CHOICE when verifying
450///   a signed SPDU shall indicate that the SPDU is invalid (per 4.2.2.3.2)
451/// - Invalid in this context means its validity cannot be established
452#[derive(AsnType, Debug, Clone, Decode, Encode, PartialEq, Eq, Hash, PartialOrd, Ord)]
453#[rasn(choice, automatic_tags)]
454#[non_exhaustive]
455pub enum IdentifiedRegion {
456    CountryOnly(UnCountryId),
457    CountryAndRegions(CountryAndRegions),
458    CountryAndSubregions(CountryAndSubregions),
459}
460
461/// This type is used for clarity of definitions.
462#[derive(AsnType, Debug, Clone, Decode, Encode, PartialEq, Eq, Hash, PartialOrd, Ord)]
463#[rasn(delegate)]
464pub struct SequenceOfIdentifiedRegion(pub SequenceOf<IdentifiedRegion>);
465
466delegate!(SequenceOf<IdentifiedRegion>, SequenceOfIdentifiedRegion);
467
468/// Integer representation of country or area identifiers as defined by the United
469/// Nations Statistics Division (October 2013, see normative references in Clause 0).
470///
471/// # Implementation Requirements
472/// A conformant implementation of `IdentifiedRegion` must:
473/// - Recognize at least one value of `UnCountryId` (ability to determine if a
474///   2D location lies inside/outside the identified borders)
475/// - May declare recognized `UnCountryId` values in the Protocol Implementation
476///   Conformance Statement (PICS) in Annex A
477///
478/// # Historical Changes
479/// Since 2013 and before this standard's publication, three changes to the country
480/// code list:
481/// - Added "sub-Saharan Africa" region
482/// - Removed "developed regions"
483/// - Removed "developing regions"
484///
485/// Conformant implementations may recognize these region identifiers.
486///
487/// # Verification Behavior
488/// When verifying geographic information in a signed SPDU against a certificate:
489/// - SDS may indicate SPDU validity even with unrecognized instances if recognized
490///   instances completely contain the relevant geographic information
491/// - Not considered a "critical information field" (ref: 5.2.6) as unrecognized
492///   values are permitted if SPDU validity can be established with recognized values
493///
494/// # Important Note
495/// An unrecognized value in a certificate may still prevent determining the
496/// validity of both the certificate and SPDU.
497#[derive(AsnType, Debug, Clone, Decode, Encode, PartialEq, Eq, Hash, PartialOrd, Ord)]
498#[rasn(delegate)]
499pub struct UnCountryId(pub Uint16);
500
501delegate!(Uint16, UnCountryId);
502
503/// This type is defined only for backwards compatibility.
504#[derive(AsnType, Debug, Clone, Decode, Encode, PartialEq, Eq, Hash, PartialOrd, Ord)]
505#[rasn(delegate)]
506pub struct CountryOnly(pub UnCountryId);
507
508delegate!(UnCountryId, CountryOnly);
509
510/// A type representing country and region information with specific implementation requirements.
511///
512/// # Implementation Requirements
513/// - Must support a `regions` field containing at least eight entries
514/// - Must be able to determine whether a two-dimensional location lies inside or
515///   outside the borders identified by at least:
516///   - One value of `UnCountryId`
517///   - One region within the country indicated by that recognized `UnCountryId` value
518///
519/// # Current Version Requirements
520/// The only way to satisfy the implementation requirements in this version is to:
521/// - Recognize the `UnCountryId` value indicating USA
522/// - Recognize at least one of the FIPS state codes for US states
523///
524/// # Verification Behavior
525/// When verifying geographic information in a signed SPDU against a certificate:
526/// - The SDS may indicate validity even with unrecognized country/region values
527/// - Validity can be determined if recognized values completely contain the relevant
528///   geographic information
529/// - This is not a "critical information field" (ref: 5.2.6) as unrecognized values
530///   are permitted if validity can be established with recognized values
531/// - Note: Unrecognized values in a certificate may still prevent determining
532///   certificate validity and consequently SPDU validity
533///
534/// # Fields
535/// - `countryOnly`: A `UnCountryId` value identifying the country
536/// - `regions`: One or more regions within the country:
537///   - For USA: Uses integer version of 2010 FIPS codes from U.S. Census Bureau
538///   - For other countries: Region meaning is undefined in current version
539///
540/// # PICS Conformance
541/// The Protocol Implementation Conformance Statement (PICS) in Annex A allows
542/// implementations to declare:
543/// - Recognized `UnCountryId` values
544/// - Recognized region values within each country
545#[derive(Builder, AsnType, Debug, Clone, Decode, Encode, PartialEq, Eq, Hash, PartialOrd, Ord)]
546#[rasn(automatic_tags)]
547pub struct CountryAndRegions {
548    #[rasn(identifier = "countryOnly")]
549    pub country_only: UnCountryId,
550    pub regions: SequenceOfUint8,
551}
552
553/// Implementation requirements and behavior specification for country and subregion handling.
554///
555/// # Implementation Requirements
556/// A conformant implementation:
557/// - Must support at least eight entries in the `region_and_subregions` field
558/// - Must recognize at least one country value and one region within that country
559/// - Currently must specifically recognize:
560///   - USA as a `UnCountryId` value
561///   - At least one FIPS state code for US states
562///
563/// The Protocol Implementation Conformance Statement (PICS) in Annex A allows
564/// implementations to declare:
565/// - Recognized `UnCountryId` values
566/// - Recognized region values within each country
567///
568/// # Verification Behavior
569/// When verifying geographic information in a signed SPDU against a certificate:
570/// - SDS may indicate SPDU validity even with unrecognized country or
571///   `region_and_subregions` values if recognized instances completely contain
572///   the relevant geographic information
573/// - Not considered a "critical information field" (ref: 5.2.6) as unrecognized
574///   values are permitted if SPDU validity can be established with recognized values
575///
576/// # Important Note
577/// An unrecognized value in a certificate may prevent determining the validity
578/// of both the certificate and SPDU.
579///
580/// # Fields
581/// - `country`: A `UnCountryId` value identifying the country
582/// - `region_and_subregions`: Identifies one or more subregions within the country
583#[derive(Builder, AsnType, Debug, Clone, Decode, Encode, PartialEq, Eq, Hash, PartialOrd, Ord)]
584#[rasn(automatic_tags)]
585pub struct CountryAndSubregions {
586    #[rasn(identifier = "countryOnly")]
587    pub country_only: UnCountryId,
588    #[rasn(identifier = "regionAndSubregions")]
589    pub region_and_subregions: SequenceOfRegionAndSubregions,
590}
591
592/// Represents regions and subregions within an "enclosing country" context.
593///
594/// # Context
595/// Fields are interpreted within the context of an enclosing country:
596/// - In `CountryAndSubregions`, the enclosing country is specified by the `country` field
597/// - Future uses will specify how the enclosing country is determined
598///
599/// # USA-Specific Implementation
600/// When the enclosing country is the United States of America:
601/// - `region`: Identifies state/equivalent entity using 2010 FIPS codes (U.S. Census Bureau)
602/// - `subregions`: Identifies county/equivalent entity using 2010 FIPS codes
603///
604/// For other countries, the meaning is not defined in this version of the standard.
605///
606/// # Implementation Requirements
607/// A conformant implementation must:
608/// - Recognize at least one region within an enclosing country
609/// - Recognize at least one subregion for the indicated region
610/// - For USA specifically:
611///   - Recognize at least one FIPS state code
612///   - Recognize at least one county code in at least one recognized state
613/// - Support at least eight entries in the `subregions` field
614///
615/// The PICS (Annex A) allows implementations to declare recognized:
616/// - `UnCountryId` values
617/// - Region values within countries
618///
619/// # Verification Behavior
620/// When verifying geographic information in a signed SPDU against a certificate:
621/// - SDS may indicate SPDU validity even with unrecognized subregion values if
622///   recognized instances completely contain the relevant geographic information
623/// - Not considered a "critical information field" (ref: 5.2.6) as unrecognized
624///   values are permitted if SPDU validity can be established with recognized values
625///
626/// # Important Note
627/// An unrecognized value in a certificate may prevent determining the validity
628/// of both the certificate and SPDU.
629///
630/// # Fields
631/// - `region`: Identifies a region within a country
632/// - `subregions`: Identifies one or more subregions within the region
633#[derive(Builder, AsnType, Debug, Clone, Decode, Encode, PartialEq, Eq, Hash, PartialOrd, Ord)]
634#[rasn(automatic_tags)]
635pub struct RegionAndSubregions {
636    pub region: Uint8,
637    pub subregions: SequenceOfUint16,
638}
639
640/// This type is used for clarity of definitions.
641#[derive(AsnType, Debug, Clone, Decode, Encode, PartialEq, Eq, Hash, PartialOrd, Ord)]
642#[rasn(delegate)]
643pub struct SequenceOfRegionAndSubregions(pub SequenceOf<RegionAndSubregions>);
644
645delegate!(
646    SequenceOf<RegionAndSubregions>,
647    SequenceOfRegionAndSubregions
648);
649
650/// A structure containing an estimate of 3D location, with field-specific details
651/// provided in individual field documentation.
652///
653/// # Compatibility Note
654/// The units used in this structure are consistent with SAE J2735 B26 location
655/// data structures, though the encoding is incompatible.
656#[derive(Builder, AsnType, Debug, Clone, Decode, Encode, PartialEq, Eq, Hash, PartialOrd, Ord)]
657#[rasn(automatic_tags)]
658pub struct ThreeDLocation {
659    pub latitude: Latitude,
660    pub longitude: Longitude,
661    pub elevation: Elevation,
662}
663
664/// An INTEGER encoding of latitude estimate with 1/10th microdegree precision,
665/// relative to the World Geodetic System (WGS-84) datum as defined in NIMA
666/// Technical Report TR8350.2.
667///
668/// # Value Range
669/// - Minimum: -900,000,000
670/// - Maximum: 900,000,000
671/// - Special Value: 900,000,001 indicates latitude was not available to sender
672#[derive(AsnType, Debug, Clone, Decode, Encode, PartialEq, Eq, Hash, PartialOrd, Ord)]
673#[rasn(delegate)]
674pub struct Latitude(pub NinetyDegreeInt);
675
676delegate!(NinetyDegreeInt, Latitude);
677
678/// An INTEGER encoding of longitude estimate with 1/10th microdegree precision,
679/// relative to the World Geodetic System (WGS-84) datum as defined in NIMA
680/// Technical Report TR8350.2.
681///
682/// # Value Range
683/// - Minimum: -1,799,999,999
684/// - Maximum: 1,800,000,000
685/// - Special Value: 1,800,000,001 indicates longitude was not available to sender
686#[derive(AsnType, Debug, Clone, Decode, Encode, PartialEq, Eq, Hash, PartialOrd, Ord)]
687#[rasn(delegate)]
688pub struct Longitude(pub OneEightyDegreeInt);
689
690delegate!(OneEightyDegreeInt, Longitude);
691
692/// This structure contains an estimate of the geodetic altitude above
693/// or below the WGS84 ellipsoid. The 16-bit value is interpreted as an
694/// integer number of decimeters representing the height above a minimum
695/// height of -409.5 m, with the maximum height being 6143.9 m.
696#[derive(AsnType, Debug, Clone, Decode, Encode, PartialEq, Eq, Hash, PartialOrd, Ord)]
697#[rasn(delegate)]
698pub struct Elevation(pub Uint16);
699
700delegate!(Uint16, Elevation);
701
702/// The integer in the latitude field is no more than 900,000,000 and
703/// no less than -900,000,000, except that the value 900,000,001 is used to
704/// indicate the latitude was not available to the sender.
705#[derive(AsnType, Debug, Clone, Decode, Encode, PartialEq, Eq, Hash, PartialOrd, Ord)]
706#[rasn(delegate, value("-900000000..=900000001"))]
707pub struct NinetyDegreeInt(i32);
708
709impl NinetyDegreeInt {
710    pub const MIN: i32 = -900_000_000;
711    pub const MAX: i32 = 900_000_000;
712    pub const UNKNOWN: i32 = 900_000_001;
713    pub const fn new(value: i32) -> Option<Self> {
714        if value >= Self::MIN && value <= Self::UNKNOWN {
715            Some(Self(value))
716        } else {
717            None
718        }
719    }
720}
721
722delegate!(i32, NinetyDegreeInt);
723
724/// The known latitudes are from -900,000,000 to +900,000,000 in 0.1
725/// microdegree intervals.
726#[derive(AsnType, Debug, Clone, Decode, Encode, PartialEq, Eq, Hash, PartialOrd, Ord)]
727#[rasn(delegate, value("-900000000..=900000000"))]
728pub struct KnownLatitude(NinetyDegreeInt);
729
730impl KnownLatitude {
731    pub const MIN: i32 = -900_000_000;
732    pub const MAX: i32 = 900_000_000;
733    pub const fn new(value: i32) -> Option<Self> {
734        if value >= Self::MIN && value <= Self::MAX {
735            Some(Self(NinetyDegreeInt(value)))
736        } else {
737            None
738        }
739    }
740}
741
742delegate!(NinetyDegreeInt, KnownLatitude);
743
744/// The value 900,000,001 indicates that the latitude was not
745/// available to the sender.
746#[derive(AsnType, Debug, Clone, Decode, Encode, PartialEq, Eq, Hash, PartialOrd, Ord)]
747#[rasn(delegate, value("900000001"))]
748pub struct UnknownLatitude(NinetyDegreeInt);
749
750impl UnknownLatitude {
751    pub const UNKNOWN: NinetyDegreeInt = NinetyDegreeInt(900_000_001);
752    pub const fn new() -> Self {
753        Self(Self::UNKNOWN)
754    }
755}
756
757impl Default for UnknownLatitude {
758    fn default() -> Self {
759        Self::new()
760    }
761}
762
763delegate!(NinetyDegreeInt, UnknownLatitude);
764
765/// An integer type representing longitude values with named boundary values
766/// and constraints.
767///
768/// # Value Range
769/// - Minimum: -1,799,999,999
770/// - Maximum: 1,800,000,000
771/// - Special Value: 1,800,000,001 (indicates longitude not available to sender)
772#[derive(AsnType, Debug, Clone, Decode, Encode, PartialEq, Eq, Hash, PartialOrd, Ord)]
773#[rasn(delegate, value("-1799999999..=1800000001"))]
774pub struct OneEightyDegreeInt(pub i32);
775
776impl OneEightyDegreeInt {
777    pub const MIN: i32 = -1_799_999_999;
778    pub const MAX: i32 = 1_800_000_000;
779    pub const UNKNOWN: i32 = 1_800_000_001;
780    /// Creates a new OneEightyDegreeInt if the value is within valid range
781    pub const fn new(value: i32) -> Option<Self> {
782        if Self::is_valid(value) {
783            Some(Self(value))
784        } else {
785            None
786        }
787    }
788    /// Creates a new OneEightyDegreeInt with an unknown value
789    pub const fn unknown() -> Self {
790        Self(Self::UNKNOWN)
791    }
792    /// Returns true if this is a valid longitude value (including unknown)
793    pub const fn is_valid(value: i32) -> bool {
794        (value >= Self::MIN && value <= Self::MAX) || value == Self::UNKNOWN
795    }
796    /// Returns true if this represents a known longitude value
797    pub const fn is_known(&self) -> bool {
798        self.0 >= OneEightyDegreeInt::MIN && self.0 <= OneEightyDegreeInt::MAX
799    }
800    /// Returns true if this represents an unknown longitude value
801    pub const fn is_unknown(&self) -> bool {
802        self.0 == Self::UNKNOWN
803    }
804}
805
806delegate!(i32, OneEightyDegreeInt);
807
808/// Represents a known longitude value in 0.1 microdegree intervals.
809///
810/// # Value Range
811/// - Minimum: -1,799,999,999 (-180 degrees)
812/// - Maximum: 1,800,000,000 (180 degrees)
813/// - Precision: 0.1 microdegrees
814#[derive(AsnType, Debug, Clone, Decode, Encode, PartialEq, Eq, Hash, PartialOrd, Ord)]
815#[rasn(delegate, value("-1799999999..=1800000000"))]
816pub struct KnownLongitude(OneEightyDegreeInt);
817
818impl KnownLongitude {
819    pub const MIN: i32 = -1_799_999_999;
820    pub const MAX: i32 = 1_800_000_000;
821    /// Creates a new KnownLongitude if the value is within valid range
822    pub const fn new(value: i32) -> Option<Self> {
823        if value >= Self::MIN && value <= Self::MAX {
824            Some(Self(OneEightyDegreeInt(value)))
825        } else {
826            None
827        }
828    }
829}
830
831delegate!(OneEightyDegreeInt, KnownLongitude);
832
833/// Represents a longitude value that is explicitly unknown/unavailable.
834///
835/// This type can only have the value 1,800,000,001, indicating that the longitude
836/// was not available to the sender.
837#[derive(AsnType, Debug, Clone, Decode, Encode, PartialEq, Eq, Hash, PartialOrd, Ord)]
838#[rasn(delegate, value("1800000001"))]
839pub struct UnknownLongitude(OneEightyDegreeInt);
840
841impl UnknownLongitude {
842    pub const UNKNOWN: OneEightyDegreeInt = OneEightyDegreeInt(1_800_000_001);
843    /// Creates a new UnknownLongitude instance
844    pub const fn new() -> Self {
845        Self(Self::UNKNOWN)
846    }
847}
848impl Default for UnknownLongitude {
849    fn default() -> Self {
850        Self::new()
851    }
852}
853
854delegate!(OneEightyDegreeInt, UnknownLongitude);
855
856// ***************************************************************************
857// **                           Crypto Structures                           **
858// ***************************************************************************
859
860/// Represents a signature for a supported public key algorithm, which may be
861/// contained within `SignedData` or `Certificate`.
862///
863/// # Critical Information Field
864/// This is a critical information field as defined in 5.2.5:
865/// - An implementation that does not recognize the indicated CHOICE when verifying
866///   a signed SPDU shall indicate that the SPDU is invalid (per 4.2.2.3.2)
867/// - Invalid in this context means its validity cannot be established
868///
869/// # Canonicalization
870/// This data structure is subject to canonicalization for operations specified
871/// in 6.1.2. Canonicalization applies to:
872/// - `EcdsaP256Signature` instances
873/// - `EcdsaP384Signature` instances
874#[derive(AsnType, Debug, Clone, Decode, Encode, PartialEq, Eq, Hash, PartialOrd, Ord)]
875#[rasn(choice, automatic_tags)]
876#[non_exhaustive]
877pub enum Signature {
878    EcdsaNistP256(EcdsaP256Signature),
879    EcdsaBrainpoolP256r1(EcdsaP256Signature),
880    #[rasn(extension_addition)]
881    EcdsaBrainpoolP384r1(EcdsaP384Signature),
882    #[rasn(extension_addition)]
883    EcdsaNistP384(EcdsaP384Signature),
884    #[rasn(extension_addition)]
885    Sm2(EcsigP256Signature),
886}
887
888/// Represents an ECDSA signature, generated as specified in 5.3.1.
889///
890/// # Signature Process
891/// - FIPS 186-4: If followed, integer r is represented as an `EccP256CurvePoint`
892///   with `x-only` selection
893/// - SEC 1: If followed, elliptic curve point R is represented as an `EccP256CurvePoint`
894///   with sender's choice of:
895///   - `compressed-y-0`
896///   - `compressed-y-1`
897///   - `uncompressed`
898///
899/// # Canonicalization
900/// This data structure is subject to canonicalization for operations specified in 6.1.2:
901/// - When canonicalized, the `EccP256CurvePoint` in `r_sig` must use `x-only` form
902///
903/// # Technical Details
904/// For signatures with:
905/// - `x-only` form: x-value in `r_sig` is an integer mod n (group order)
906/// - `compressed-y-*` form: x-value in `r_sig` is an integer mod p (field prime)
907///
908/// Converting `compressed-y-*` to `x-only`: theoretically requires checking if x-value
909/// is between n and p, reducing mod n if so. In practice, this check is unnecessary
910/// due to Haase's Theorem (probability ≈ 2^(-128) for 256-bit curves).
911///
912/// # Curve Parameters (hexadecimal)
913/// NIST p256:
914/// - p = FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF
915/// - n = FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551
916///
917/// Brainpool p256:
918/// - p = A9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E5377
919/// - n = A9FB57DBA1EEA9BC3E660A909D838D718C397AA3B561A6F7901E0E82974856A7
920#[derive(Builder, AsnType, Debug, Clone, Decode, Encode, PartialEq, Eq, Hash, PartialOrd, Ord)]
921#[rasn(automatic_tags)]
922pub struct EcdsaP256Signature {
923    #[rasn(identifier = "rSig")]
924    pub r_sig: EccP256CurvePoint,
925    #[rasn(identifier = "sSig")]
926    pub s_sig: FixedOctetString<32>,
927}
928
929/// Represents an ECDSA signature, generated as specified in 5.3.1.
930///
931/// # Signature Process
932/// - FIPS 186-4: If followed, integer r is represented as an `EccP384CurvePoint`
933///   with `x-only` selection
934/// - SEC 1: If followed, elliptic curve point R is represented as an `EccP384CurvePoint`
935///   with sender's choice of:
936///   - `compressed-y-0`
937///   - `compressed-y-1`
938///   - `uncompressed`
939///
940/// # Canonicalization
941/// This data structure is subject to canonicalization for operations specified in 6.1.2:
942/// - When canonicalized, the `EccP384CurvePoint` in `r_sig` must use `x-only` form
943///
944/// # Technical Details
945/// For signatures with:
946/// - `x-only` form: x-value in `r_sig` is an integer mod n (group order)
947/// - `compressed-y-*` form: x-value in `r_sig` is an integer mod p (field prime)
948///
949/// Converting `compressed-y-*` to `x-only`: theoretically requires checking if x-value
950/// is between n and p, reducing mod n if so. In practice, this check is unnecessary
951/// due to Haase's Theorem (probability ≈ 2^(-192) for 384-bit curves).
952///
953/// # Curve Parameters (hexadecimal)
954/// ```text
955/// p = 8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B412B1DA197FB71123\
956///     ACD3A729901D1A71874700133107EC53
957/// n = 8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B31F166E6CAC0425A7\
958///     CF3AB6AF6B7FC3103B883202E9046565
959/// ```
960#[derive(Builder, AsnType, Debug, Clone, Decode, Encode, PartialEq, Eq, Hash, PartialOrd, Ord)]
961#[rasn(automatic_tags)]
962pub struct EcdsaP384Signature {
963    #[rasn(identifier = "rSig")]
964    pub r_sig: EccP384CurvePoint,
965    #[rasn(identifier = "sSig")]
966    pub s_sig: FixedOctetString<48>,
967}
968/// Represents an elliptic curve signature where the component r is constrained
969/// to be an integer. This structure supports SM2 signatures as specified in 5.3.1.3.
970#[derive(Builder, AsnType, Debug, Clone, Decode, Encode, PartialEq, Eq, Hash, PartialOrd, Ord)]
971#[rasn(automatic_tags)]
972pub struct EcsigP256Signature {
973    #[rasn(identifier = "rSig")]
974    pub r_sig: FixedOctetString<32>,
975    #[rasn(identifier = "sSig")]
976    pub s_sig: FixedOctetString<32>,
977}
978/// Specifies a point on an elliptic curve in Weierstrass form defined over a
979/// 256-bit prime number.
980///
981/// # Supported Curves
982/// - NIST p256 (FIPS 186-4)
983/// - Brainpool p256r1 (RFC 5639)
984/// - SM2 curve (GB/T 32918.5-2017)
985///
986/// # Encoding Details
987/// Fields are OCTET STRINGS encoded according to IEEE Std 1363-2000, 5.5.6:
988/// - x-coordinate: Always 32 octets, unsigned integer in network byte order
989/// - y-coordinate: Encoding depends on point representation:
990///   - `XOnly`: y is omitted
991///   - `CompressedY0`: y's least significant bit is 0
992///   - `CompressedY1`: y's least significant bit is 1
993///   - `Uncompressed`: y is explicit 32 octets, unsigned integer in network byte order
994///
995/// # Canonicalization
996/// Subject to canonicalization for operations specified in 6.1.2 when appearing in:
997/// - `HeaderInfo`
998/// - `ToBeSignedCertificate`
999///
1000/// See respective type definitions for specific canonicalization operations.
1001#[derive(AsnType, Debug, Clone, Decode, Encode, PartialEq, Eq, Hash, PartialOrd, Ord)]
1002#[rasn(choice, automatic_tags)]
1003pub enum EccP256CurvePoint {
1004    #[rasn(identifier = "x-only")]
1005    XOnly(FixedOctetString<32>),
1006    Fill(()),
1007    #[rasn(identifier = "compressed-y-0")]
1008    CompressedY0(FixedOctetString<32>),
1009    #[rasn(identifier = "compressed-y-1")]
1010    CompressedY1(FixedOctetString<32>),
1011    #[rasn(identifier = "uncompressedP256")]
1012    Uncompressed(EccP256CurvePointUncompressedP256),
1013}
1014/// Inner type of `EccP256CurvePoint` representing an uncompressed point on the NIST P-256 curve.
1015#[derive(Builder, AsnType, Debug, Clone, Decode, Encode, PartialEq, Eq, Hash, PartialOrd, Ord)]
1016#[rasn(automatic_tags)]
1017pub struct EccP256CurvePointUncompressedP256 {
1018    pub x: FixedOctetString<32>,
1019    pub y: FixedOctetString<32>,
1020}
1021/// Specifies a point on an elliptic curve in Weierstrass form defined over a
1022/// 384-bit prime number.
1023///
1024/// # Supported Curves
1025/// Only supports Brainpool p384r1 as defined in RFC 5639.
1026///
1027/// # Encoding Details
1028/// Fields are OCTET STRINGS encoded according to IEEE Std 1363-2000, 5.5.6:
1029/// - x-coordinate: Always 48 octets, unsigned integer in network byte order
1030/// - y-coordinate: Encoding depends on point representation:
1031///   - `XOnly`: y is omitted
1032///   - `CompressedY0`: y's least significant bit is 0
1033///   - `CompressedY1`: y's least significant bit is 1
1034///   - `Uncompressed`: y is explicit 48 octets, unsigned integer in network byte order
1035///
1036/// # Canonicalization
1037/// Subject to canonicalization for operations specified in 6.1.2 when appearing in:
1038/// - `HeaderInfo`
1039/// - `ToBeSignedCertificate`
1040///
1041/// See respective type definitions for specific canonicalization operations.
1042#[derive(AsnType, Debug, Clone, Decode, Encode, PartialEq, Eq, Hash, PartialOrd, Ord)]
1043#[rasn(choice, automatic_tags)]
1044pub enum EccP384CurvePoint {
1045    #[rasn(identifier = "x-only")]
1046    XOnly(FixedOctetString<48>),
1047    Fill(()),
1048    #[rasn(identifier = "compressed-y-0")]
1049    CompressedY0(FixedOctetString<48>),
1050    #[rasn(identifier = "compressed-y-1")]
1051    CompressedY1(FixedOctetString<48>),
1052    #[rasn(identifier = "uncompressedP384")]
1053    Uncompressed(EccP384CurvePointUncompressedP384),
1054}
1055/// Inner type of `EccP384CurvePoint` representing an uncompressed point on the Brainpool P-384 curve.
1056#[derive(Builder, AsnType, Debug, Clone, Decode, Encode, PartialEq, Eq, Hash, PartialOrd, Ord)]
1057#[rasn(automatic_tags)]
1058pub struct EccP384CurvePointUncompressedP384 {
1059    pub x: FixedOctetString<48>,
1060    pub y: FixedOctetString<48>,
1061}
1062/// Indicates supported symmetric algorithms and their modes of operation.
1063///
1064/// # Supported Algorithms
1065/// - AES-128
1066/// - SM4
1067///
1068/// # Mode of Operation
1069/// Only supports Counter Mode Encryption With Cipher Block Chaining Message
1070/// Authentication Code (CCM).
1071///
1072/// Full implementation details are specified in section 5.3.8.
1073#[derive(AsnType, Debug, Clone, Copy, Decode, Encode, PartialEq, Eq, Hash, PartialOrd, Ord)]
1074#[rasn(enumerated)]
1075#[non_exhaustive]
1076pub enum SymmAlgorithm {
1077    Aes128Ccm = 0,
1078    #[rasn(extension_addition)]
1079    Sm4Ccm = 1,
1080}
1081
1082/// Identifies supported hash algorithms. See section 5.3.3 for implementation details.
1083///
1084/// # Supported Algorithms
1085/// - SHA-256
1086/// - SHA-384
1087/// - SM3
1088///
1089/// # Critical Information Field
1090/// This is a critical information field as defined in 5.2.6:
1091/// - An implementation that does not recognize the enumerated value when verifying
1092///   a signed SPDU shall indicate that the SPDU is invalid (per 4.2.2.3.2)
1093/// - Invalid in this context means its validity cannot be established
1094#[derive(AsnType, Debug, Clone, Copy, Decode, Encode, PartialEq, Eq, Hash, PartialOrd, Ord)]
1095#[rasn(enumerated)]
1096#[non_exhaustive]
1097pub enum HashAlgorithm {
1098    Sha256 = 0,
1099    #[rasn(extension_addition)]
1100    Sha384 = 1,
1101    #[rasn(extension_addition)]
1102    Sm3 = 2,
1103}
1104/// Used to transfer a 16-byte symmetric key encrypted using ECIES as specified in
1105/// IEEE Std 1363a-2004.
1106///
1107/// The symmetric key is input to the key encryption process with no headers,
1108/// encapsulation, or length indication. Encryption and decryption are carried
1109/// out as specified in 5.3.5.1.
1110///
1111/// # Fields
1112/// - `v`: Sender's ephemeral public key (output V from encryption as specified
1113///   in 5.3.5.1)
1114/// - `c`: Encrypted symmetric key (output C from encryption as specified in 5.3.5.1).
1115///   The algorithm is identified by the CHOICE in the following `SymmetricCiphertext`.
1116///   For ECIES, this algorithm must be AES-128.
1117/// - `t`: Authentication tag (output tag from encryption as specified in 5.3.5.1)
1118#[derive(AsnType, Debug, Clone, Decode, Encode, PartialEq, Eq, Hash, PartialOrd, Ord)]
1119#[rasn(automatic_tags)]
1120pub struct EciesP256EncryptedKey {
1121    pub v: EccP256CurvePoint,
1122    pub c: FixedOctetString<16>,
1123    pub t: FixedOctetString<16>,
1124}
1125
1126/// Used to transfer a 16-byte symmetric key encrypted using SM2 encryption as
1127/// specified in 5.3.3.
1128///
1129/// The symmetric key is input to the key encryption process with no headers,
1130/// encapsulation, or length indication. Encryption and decryption are carried
1131/// out as specified in 5.3.5.2.
1132///
1133/// # Fields
1134/// - `v`: Sender's ephemeral public key (output V from encryption as specified
1135///   in 5.3.5.2)
1136/// - `c`: Encrypted symmetric key (output C from encryption as specified in 5.3.5.2).
1137///   The algorithm is identified by the CHOICE in the following `SymmetricCiphertext`.
1138///   For SM2, this algorithm must be SM4.
1139/// - `t`: Authentication tag (output tag from encryption as specified in 5.3.5.2)
1140#[derive(Builder, AsnType, Debug, Clone, Decode, Encode, PartialEq, Eq, Hash, PartialOrd, Ord)]
1141#[rasn(automatic_tags)]
1142pub struct EcencP256EncryptedKey {
1143    pub v: EccP256CurvePoint,
1144    pub c: FixedOctetString<16>,
1145    pub t: FixedOctetString<32>,
1146}
1147/// Contains an encryption key, which may be either public or symmetric.
1148///
1149/// # Canonicalization
1150/// Subject to canonicalization for operations specified in 6.1.2 when appearing in:
1151/// - `HeaderInfo`
1152/// - `ToBeSignedCertificate`
1153///
1154/// Canonicalization applies to the `PublicEncryptionKey`. See respective type
1155/// definitions for specific canonicalization operations.
1156#[derive(AsnType, Debug, Clone, Decode, Encode, PartialEq, Eq, Hash, PartialOrd, Ord)]
1157#[rasn(choice, automatic_tags)]
1158pub enum EncryptionKey {
1159    Public(PublicEncryptionKey),
1160    Symmetric(SymmetricEncryptionKey),
1161}
1162
1163/// Specifies a public encryption key and its associated symmetric algorithm used
1164/// for bulk data encryption when encrypting for that public key.
1165///
1166/// # Canonicalization
1167/// Subject to canonicalization for operations specified in 6.1.2 when appearing in:
1168/// - `HeaderInfo`
1169/// - `ToBeSignedCertificate`
1170///
1171/// Canonicalization applies to the `BasePublicEncryptionKey`. See respective type
1172/// definitions for specific canonicalization operations.
1173#[derive(Builder, AsnType, Debug, Clone, Decode, Encode, PartialEq, Eq, Hash, PartialOrd, Ord)]
1174#[rasn(automatic_tags)]
1175pub struct PublicEncryptionKey {
1176    #[rasn(identifier = "supportedSymmAlg")]
1177    pub supported_symm_alg: SymmAlgorithm,
1178    #[rasn(identifier = "publicKey")]
1179    pub public_key: BasePublicEncryptionKey,
1180}
1181
1182/// This structure specifies the bytes of a public encryption key for
1183/// a particular algorithm. Supported public key encryption algorithms are
1184/// defined in 5.3.5.
1185///
1186/// # Note
1187/// Canonicalization: This data structure is subject to canonicalization
1188/// for the relevant operations specified in 6.1.2 if it appears in a
1189/// HeaderInfo or in a ToBeSignedCertificate. See the definitions of HeaderInfo
1190/// and ToBeSignedCertificate for a specification of the canonicalization
1191/// operations.
1192#[derive(AsnType, Debug, Clone, Decode, Encode, PartialEq, Eq, Hash, PartialOrd, Ord)]
1193#[rasn(choice, automatic_tags)]
1194#[non_exhaustive]
1195pub enum BasePublicEncryptionKey {
1196    EciesNistP256(EccP256CurvePoint),
1197    EciesBrainpoolP256r1(EccP256CurvePoint),
1198    #[rasn(extension_addition)]
1199    EcencSm2(EccP256CurvePoint),
1200}
1201
1202/// Represents a public key and its associated verification algorithm.
1203/// Cryptographic mechanisms are defined in section 5.3.
1204///
1205/// # Validity Rules
1206/// An `EccP256CurvePoint` or `EccP384CurvePoint` within this structure is invalid
1207/// if it indicates the choice `x-only`.
1208///
1209/// # Critical Information Field
1210/// This is a critical information field as defined in 5.2.6:
1211/// - An implementation that does not recognize the indicated CHOICE when verifying
1212///   a signed SPDU shall indicate that the SPDU is invalid (per 4.2.2.3.2)
1213/// - Invalid in this context means its validity cannot be established
1214///
1215/// # Canonicalization
1216/// Subject to canonicalization for operations specified in 6.1.2:
1217/// - Applies to both `EccP256CurvePoint` and `EccP384CurvePoint`
1218/// - Points must be encoded in compressed form (`compressed-y-0` or `compressed-y-1`)
1219#[derive(AsnType, Debug, Clone, Decode, Encode, PartialEq, Eq, Hash, PartialOrd, Ord)]
1220#[rasn(choice, automatic_tags)]
1221#[non_exhaustive]
1222pub enum PublicVerificationKey {
1223    EcdsaNistP256(EccP256CurvePoint),
1224    EcdsaBrainpoolP256r1(EccP256CurvePoint),
1225    #[rasn(extension_addition)]
1226    EcdsaBrainpoolP384r1(EccP384CurvePoint),
1227    #[rasn(extension_addition)]
1228    EcdsaNistP384(EccP384CurvePoint),
1229    #[rasn(extension_addition)]
1230    EcsigSm2(EccP256CurvePoint),
1231}
1232
1233/// Provides key bytes for use with an identified symmetric algorithm.
1234///
1235/// # Supported Algorithms
1236/// - AES-128 in CCM mode
1237/// - SM4 in CCM mode
1238///
1239/// See section 5.3.8 for implementation details.
1240#[derive(AsnType, Debug, Clone, Decode, Encode, PartialEq, Eq, Hash, PartialOrd, Ord)]
1241#[rasn(choice, automatic_tags)]
1242#[non_exhaustive]
1243pub enum SymmetricEncryptionKey {
1244    Aes128Ccm(FixedOctetString<16>),
1245    #[rasn(extension_addition)]
1246    Sm4Ccm(FixedOctetString<16>),
1247}
1248
1249// ***************************************************************************
1250// **                               PSID / ITS-AID                          **
1251// ***************************************************************************
1252
1253/// Represents permissions for a certificate holder regarding activities in a single
1254/// application area, identified by a `Psid`.
1255///
1256/// # Permission Determination
1257/// - The SDEE (not SDS) determines if activities are consistent with PSID and
1258///   ServiceSpecificPermissions
1259/// - SDS provides PSID and SSP information to SDEE for determination
1260/// - See section 5.2.4.3.3 for details
1261///
1262/// # SDEE Specification Requirements
1263/// The SDEE specification must:
1264/// - Specify permitted activities for particular `ServiceSpecificPermissions` values
1265/// - Either:
1266///   - Specify permitted activities when `ServiceSpecificPermissions` is omitted, or
1267///   - State that `ServiceSpecificPermissions` must always be present
1268///
1269/// # Consistency Rules
1270/// ## With Signed SPDU
1271/// Consistency between SSP and signed SPDU is defined by PSID-specific rules
1272/// (out of scope for this standard, see 5.1.1)
1273///
1274/// ## With Issuing Certificate
1275/// When `ssp` field is omitted, entry A is consistent with issuing certificate if
1276/// the certificate contains a `PsidSspRange` P where:
1277/// - P's `psid` field equals A's `psid` field and either:
1278///   - P's `sspRange` field indicates "all"
1279///   - P's `sspRange` field indicates "opaque" and contains an empty OCTET STRING
1280///
1281/// See following subclauses for consistency rules with other `ssp` field forms.
1282#[derive(Builder, AsnType, Debug, Clone, Decode, Encode, PartialEq, Eq, Hash, PartialOrd, Ord)]
1283#[rasn(automatic_tags)]
1284pub struct PsidSsp {
1285    pub psid: Psid,
1286    pub ssp: Option<ServiceSpecificPermissions>,
1287}
1288
1289/// This type is used for clarity of definitions.
1290#[derive(AsnType, Debug, Clone, Decode, Encode, PartialEq, Eq, Hash, PartialOrd, Ord)]
1291#[rasn(delegate)]
1292pub struct SequenceOfPsidSsp(pub SequenceOf<PsidSsp>);
1293
1294delegate!(SequenceOf<PsidSsp>, SequenceOfPsidSsp);
1295
1296/// This type represents the PSID defined in IEEE Std 1609.2.
1297#[derive(AsnType, Debug, Clone, Decode, Encode, PartialEq, Eq, Hash, PartialOrd, Ord)]
1298#[rasn(delegate, value("0.."))]
1299pub struct Psid(pub Integer);
1300
1301delegate!(Integer, Psid);
1302
1303/// This type is used for clarity of definitions.
1304#[derive(AsnType, Debug, Clone, Decode, Encode, PartialEq, Eq, Hash, PartialOrd, Ord)]
1305#[rasn(delegate)]
1306pub struct SequenceOfPsid(pub SequenceOf<Psid>);
1307
1308delegate!(SequenceOf<Psid>, SequenceOfPsid);
1309
1310/// Represents Service Specific Permissions (SSP) relevant to a given entry in
1311/// a `PsidSsp`. The meaning of the SSP is specific to the associated `Psid`.
1312///
1313/// SSPs may be either:
1314/// - PSID-specific octet strings
1315/// - Bitmap-based
1316///
1317/// See Annex C for guidance on choosing SSP forms for application specifiers.
1318///
1319/// # Consistency with Issuing Certificate
1320/// For an `appPermissions` entry A with `opaque` SSP field, A is consistent with
1321/// the issuing certificate if it contains one of:
1322///
1323/// ## Option 1
1324/// A `SubjectPermissions` field indicating "all" and no `PsidSspRange` field
1325/// containing A's `psid` field
1326///
1327/// ## Option 2
1328/// A `PsidSspRange` P where:
1329/// - P's `psid` field equals A's `psid` field and either:
1330///   - P's `sspRange` field indicates "all"
1331///   - P's `sspRange` field indicates "opaque" and contains an OCTET STRING
1332///     identical to A's opaque field
1333///
1334/// See following subclauses for consistency rules with other
1335/// `ServiceSpecificPermissions` types.
1336#[derive(AsnType, Debug, Clone, Decode, Encode, PartialEq, Eq, Hash, PartialOrd, Ord)]
1337#[rasn(choice, automatic_tags)]
1338#[non_exhaustive]
1339pub enum ServiceSpecificPermissions {
1340    Opaque(OctetString),
1341    #[rasn(extension_addition)]
1342    BitmapSsp(BitmapSsp),
1343}
1344
1345/// This structure represents a bitmap representation of a SSP. The
1346/// mapping of the bits of the bitmap to constraints on the signed SPDU is
1347/// PSID-specific.
1348///
1349/// Consistency with issuing certificate: If a certificate has an
1350/// appPermissions entry A for which the ssp field is bitmapSsp, A is
1351/// consistent with the issuing certificate if the certificate contains one
1352/// of the following:
1353///   - (OPTION 1) A SubjectPermissions field indicating the choice all and no PsidSspRange field containing the psid field in A;
1354///   - (OPTION 2) A PsidSspRange P for which the following holds:
1355///     - The psid field in P is equal to the psid field in A and one of the following is true:
1356///       - EITHER The sspRange field in P indicates all
1357///       - OR The sspRange field in P indicates bitmapSspRange and for every bit set to 1 in the sspBitmask in P, the bit in the identical position in the sspValue in A is set equal to the bit in that position in the sspValue in P.
1358///
1359/// # Note
1360/// A BitmapSsp B is consistent with a BitmapSspRange R if for every
1361/// bit set to 1 in the sspBitmask in R, the bit in the identical position in
1362/// B is set equal to the bit in that position in the sspValue in R. For each
1363/// bit set to 0 in the sspBitmask in R, the corresponding bit in the
1364/// identical position in B may be freely set to 0 or 1, i.e., if a bit is
1365/// set to 0 in the sspBitmask in R, the value of corresponding bit in the
1366/// identical position in B has no bearing on whether B and R are consistent.
1367#[derive(AsnType, Debug, Clone, Decode, Encode, PartialEq, Eq, Hash, PartialOrd, Ord)]
1368#[rasn(delegate, size("0..=31"))]
1369pub struct BitmapSsp(pub OctetString);
1370
1371delegate!(OctetString, BitmapSsp);
1372
1373/// Represents the certificate issuing or requesting permissions of the certificate
1374/// holder for a particular set of application permissions.
1375///
1376/// # Fields
1377/// - `psid`: Identifies the application area
1378/// - `ssp_range`: Identifies the SSPs associated with the PSID for which the holder
1379///   may issue or request certificates. If omitted, the holder may issue or request
1380///   certificates for any SSP for that PSID.
1381#[derive(Builder, AsnType, Debug, Clone, Decode, Encode, PartialEq, Eq, Hash, PartialOrd, Ord)]
1382#[rasn(automatic_tags)]
1383pub struct PsidSspRange {
1384    pub psid: Psid,
1385    #[rasn(identifier = "sspRange")]
1386    pub ssp_range: Option<SspRange>,
1387}
1388
1389/// This type is used for clarity of definitions.
1390#[derive(AsnType, Debug, Clone, Decode, Encode, PartialEq, Eq, Hash, PartialOrd, Ord)]
1391#[rasn(delegate)]
1392pub struct SequenceOfPsidSspRange(pub SequenceOf<PsidSspRange>);
1393
1394delegate!(SequenceOf<PsidSspRange>, SequenceOfPsidSspRange);
1395
1396/// Identifies the SSPs associated with a PSID for which the holder may issue or
1397/// request certificates.
1398///
1399/// # Consistency with Issuing Certificate
1400/// ## For Opaque SSP Field
1401/// A `PsidSspRange` A is consistent with the issuing certificate if it contains
1402/// one of:
1403///
1404/// ### Option 1
1405/// A `SubjectPermissions` field indicating "all" and no `PsidSspRange` field
1406/// containing A's `psid` field
1407///
1408/// ### Option 2
1409/// A `PsidSspRange` P where:
1410/// - P's `psid` field equals A's `psid` field and either:
1411///   - P's `sspRange` field indicates "all"
1412///   - Both P and A indicate "opaque", and every OCTET STRING in A's opaque
1413///     matches one in P's opaque
1414///
1415/// ## For All SSP Field
1416/// A `PsidSspRange` A is consistent if the issuing certificate contains either:
1417///
1418/// ### Option 1
1419/// A `SubjectPermissions` field indicating "all" and no `PsidSspRange` field
1420/// containing A's `psid` field
1421///
1422/// ### Option 2
1423/// A `PsidSspRange` P where:
1424/// - P's `psid` field equals A's `psid` field
1425/// - P's `sspRange` field indicates "all"
1426///
1427/// See following subclauses for consistency rules with other `SspRange` types.
1428///
1429/// # Note
1430/// While "all" can be indicated either by omitting `SspRange` in the enclosing
1431/// `PsidSspRange` or explicitly, omission is preferred.
1432#[derive(AsnType, Debug, Clone, Decode, Encode, PartialEq, Eq, Hash, PartialOrd, Ord)]
1433#[rasn(choice, automatic_tags)]
1434#[non_exhaustive]
1435pub enum SspRange {
1436    Opaque(SequenceOf<OctetString>),
1437    All(()),
1438    #[rasn(extension_addition)]
1439    BitmapSspRange(BitmapSspRange),
1440}
1441
1442/// A bitmap representation of a SSP. The `sspValue` indicates permissions and the
1443/// `sspBitmask` contains an octet string used to permit or constrain `sspValue`
1444/// fields in issued certificates. The `sspValue` and `sspBitmask` fields shall be
1445/// of the same length.
1446///
1447/// # Certificate Consistency
1448/// If a certificate has a `PsidSspRange` value P for which the sspRange field is
1449/// bitmapSspRange, P is consistent with the issuing certificate if the issuing
1450/// certificate contains one of:
1451///
1452/// ## Option 1
1453/// A SubjectPermissions field indicating the choice "all" and no PsidSspRange field
1454/// containing the psid field in P
1455///
1456/// ## Option 2
1457/// A PsidSspRange R where:
1458/// - The psid field in R equals the psid field in P and either:
1459///   - The sspRange field in R indicates "all", or
1460///   - The sspRange field in R indicates bitmapSspRange and for every bit set to 1
1461///     in the sspBitmask in R:
1462///     - The corresponding bit in sspBitmask in P is set to 1
1463///     - The corresponding bit in sspValue in P equals the bit in sspValue in R
1464///
1465/// Reference: ETSI TS 103 097
1466
1467#[derive(Builder, AsnType, Debug, Clone, Decode, Encode, PartialEq, Eq, Hash, PartialOrd, Ord)]
1468#[rasn(automatic_tags)]
1469pub struct BitmapSspRange {
1470    #[rasn(size("1..=32"), identifier = "sspValue")]
1471    pub ssp_value: OctetString,
1472    #[rasn(size("1..=32"), identifier = "sspBitmask")]
1473    pub ssp_bitmask: OctetString,
1474}
1475
1476// ***************************************************************************
1477// **                       Certificate Components                          **
1478// ***************************************************************************
1479
1480/// Contains the certificate holder's assurance level, indicating the security of
1481/// both the platform and storage of secret keys, as well as the confidence in
1482/// this assessment.
1483///
1484/// # Bit Field Encoding
1485/// ```text
1486/// Bit number     |  7  |  6  |  5  |  4  |  3  |  2  |  1  |  0  |
1487/// -------------- | --- | --- | --- | --- | --- | --- | --- | --- |
1488/// Interpretation |  A  |  A  |  A  |  R  |  R  |  R  |  C  |  C  |
1489///
1490/// Where:
1491/// - A: Assurance level (bits 7-5)
1492/// - R: Reserved for future use (bits 4-2)
1493/// - C: Confidence level (bits 1-0)
1494/// - Bit 0 is least significant
1495/// ```
1496///
1497/// # Interpretation
1498/// - Higher assurance values indicate more trusted holders (when comparing
1499///   certificates with the same confidence value)
1500/// - Specific assurance level definitions and confidence level encoding are
1501///   outside this standard's scope
1502///
1503/// # Historical Note
1504/// Originally specified in ETSI TS 103 097. Future uses are expected to maintain
1505/// consistency with future versions of that standard.
1506#[derive(AsnType, Debug, Clone, Decode, Encode, PartialEq, Eq, Hash, PartialOrd, Ord)]
1507#[rasn(delegate)]
1508pub struct SubjectAssurance(pub FixedOctetString<1usize>);
1509
1510delegate!(FixedOctetString<1usize>, SubjectAssurance);
1511
1512/// This integer identifies a series of CRLs issued under the authority of a particular CRACA.
1513#[derive(AsnType, Debug, Clone, Decode, Encode, PartialEq, Eq, Hash)]
1514#[rasn(delegate)]
1515pub struct CrlSeries(pub Uint16);
1516
1517delegate!(Uint16, CrlSeries);
1518
1519// *****************************************************************************
1520// **                           Pseudonym Linkage                             **
1521// *****************************************************************************
1522
1523/// This atomic type is used in the definition of other data structures.
1524#[derive(AsnType, Debug, Clone, Decode, Encode, PartialEq, Eq, Hash, PartialOrd, Ord)]
1525#[rasn(delegate)]
1526pub struct IValue(pub Uint16);
1527
1528delegate!(Uint16, IValue);
1529
1530/// This is a UTF-8 string as defined in IETF RFC 3629. The contents are determined by policy.
1531#[derive(AsnType, Debug, Clone, Decode, Encode, PartialEq, Eq, Hash, PartialOrd, Ord)]
1532#[rasn(delegate, size("0..=255"))]
1533pub struct Hostname(pub Utf8String);
1534
1535delegate!(Utf8String, Hostname);
1536
1537/// This is the individual linkage value. See 5.1.3 and 7.3 for details of use.
1538#[derive(AsnType, Debug, Clone, Decode, Encode, PartialEq, Eq, Hash, PartialOrd, Ord)]
1539#[rasn(delegate)]
1540pub struct LinkageValue(pub FixedOctetString<9usize>);
1541
1542delegate!(FixedOctetString<9usize>, LinkageValue);
1543
1544/// This is the group linkage value. See 5.1.3 and 7.3 for details of use.
1545#[derive(Builder, AsnType, Debug, Clone, Decode, Encode, PartialEq, Eq, Hash, PartialOrd, Ord)]
1546#[rasn(automatic_tags)]
1547pub struct GroupLinkageValue {
1548    #[rasn(identifier = "jValue")]
1549    pub j_value: FixedOctetString<4>,
1550    pub value: FixedOctetString<9>,
1551}
1552
1553/// This structure contains a LA Identifier for use in the algorithms specified in 5.1.3.4.
1554#[derive(AsnType, Debug, Clone, Decode, Encode, PartialEq, Eq, Hash, PartialOrd, Ord)]
1555#[rasn(delegate)]
1556pub struct LaId(pub FixedOctetString<2usize>);
1557
1558delegate!(FixedOctetString<2usize>, LaId);
1559
1560/// This type is used for clarity of definitions.
1561#[derive(AsnType, Debug, Clone, Decode, Encode, PartialEq, Eq, Hash, PartialOrd, Ord)]
1562#[rasn(delegate)]
1563pub struct SequenceOfLinkageSeed(pub SequenceOf<LinkageSeed>);
1564
1565delegate!(SequenceOf<LinkageSeed>, SequenceOfLinkageSeed);
1566
1567/// This structure contains a linkage seed value for use in the algorithms specified in 5.1.3.4.
1568#[derive(AsnType, Debug, Clone, Decode, Encode, PartialEq, Eq, Hash, PartialOrd, Ord)]
1569#[rasn(delegate)]
1570pub struct LinkageSeed(pub FixedOctetString<16usize>);
1571
1572delegate!(FixedOctetString<16usize>, LinkageSeed);
1573
1574// ***************************************************************************
1575// **                 Information Object Classes and Sets                   **
1576// ***************************************************************************
1577
1578// Excluding CERT-EXT-TYPE - other types here are defined in ETSI TS 103 097 extension module
1579
1580// /**
1581//  * @brief This structure is the Information Object Class used to contain
1582//  * information about a set of certificate extensions that are associated with
1583//  * each other: an AppExtension, a CertIssueExtension, and a
1584//  * CertRequestExtension.
1585//  */
1586// CERT-EXT-TYPE ::= CLASS {
1587//   &id        ExtId,
1588//   &App,
1589//   &Issue,
1590//   &Req
1591// } WITH SYNTAX {ID &id APP &App ISSUE &Issue REQUEST &Req}
1592
1593// /**
1594//  * @brief This parameterized type represents a (id, content) pair drawn from
1595//  * the set ExtensionTypes, which is constrained to contain objects defined by
1596//  * the class EXT-TYPE.
1597//  */
1598// Extension {EXT-TYPE : ExtensionTypes} ::= SEQUENCE {
1599//   id      EXT-TYPE.&extId({ExtensionTypes}),
1600//   content EXT-TYPE.&ExtContent({ExtensionTypes}{@.id})
1601// }
1602
1603// /**
1604//  * @brief This class defines objects in a form suitable for import into the
1605//  * definition of HeaderInfo.
1606//  */
1607// EXT-TYPE ::= CLASS {
1608//   &extId      ExtId,
1609//   &ExtContent
1610// } WITH SYNTAX {&ExtContent IDENTIFIED BY &extId}
1611
1612// /**
1613//  * @brief This type is used as an identifier for instances of ExtContent
1614//  * within an EXT-TYPE.
1615//  */
1616// ExtId ::= INTEGER(0..255)
1617//
1618
1619/// This structure is the Information Object Class used to contain information about a set of certificate extensions that are associated with each other: an AppExtension, a CertIssueExtension, and a CertRequestExtension.
1620pub trait CertExtType {
1621    const ID: ExtId;
1622    type App: AsnType + Encode + Decode;
1623    type Issue: AsnType
1624        + Encode
1625        + Decode
1626        + core::fmt::Debug
1627        + Clone
1628        + PartialEq
1629        + PartialOrd
1630        + Eq
1631        + Ord
1632        + core::hash::Hash;
1633    type Req: AsnType
1634        + Encode
1635        + Decode
1636        + core::fmt::Debug
1637        + Clone
1638        + PartialEq
1639        + PartialOrd
1640        + Eq
1641        + Ord
1642        + core::hash::Hash;
1643}