diff --git a/catalyst-gateway-crates/c509-certificate/src/extensions/alt_name.rs b/catalyst-gateway-crates/c509-certificate/src/extensions/alt_name.rs index ba99a48ac4..c07c883cb0 100644 --- a/catalyst-gateway-crates/c509-certificate/src/extensions/alt_name.rs +++ b/catalyst-gateway-crates/c509-certificate/src/extensions/alt_name.rs @@ -4,8 +4,8 @@ use oid::ObjectIdentifier; use super::is_critical; -/// Define the GeneralNamesRegistry enum -/// Section 9.9 https://datatracker.ietf.org/doc/draft-ietf-cose-cbor-encoded-cert/09/ +// Define the GeneralNamesRegistry enum +// Section 9.9 https://datatracker.ietf.org/doc/draft-ietf-cose-cbor-encoded-cert/09/ #[allow(unused)] #[derive(Debug, PartialEq, Clone)] enum GeneralNamesRegistry { @@ -21,6 +21,7 @@ enum GeneralNamesRegistry { RegisteredID = 8, // ~oid } +// GeneralNamesRegistryType enum defines a type used in GeneralNamesRegistry #[allow(unused)] #[derive(Clone)] pub(crate) enum GeneralNamesRegistryType { @@ -28,11 +29,13 @@ pub(crate) enum GeneralNamesRegistryType { Bytes(Vec), Oid(String), OidAndBytes(Vec), + Eid(Eid), } +// Type othername mention in Section 3.3 +// Struct of OtherNameType 'otherName + hardwareModuleName' is used in a form +// of [ ~oid, bytes ] which, contain the pair ( hwType, hwSerialNum ) #[derive(Clone)] -// When 'otherName + hardwareModuleName' is used, then [ ~oid, bytes ] is -// used to contain the pair ( hwType, hwSerialNum ) pub(crate) struct OtherNameType { hw_type: String, hw_serial_num: Vec, @@ -41,7 +44,6 @@ pub(crate) struct OtherNameType { impl CborEncoder for Vec { fn encode(&self, encoder: &mut Encoder<&mut Vec>) { let _unused = encoder.array(self.len() as u64); - for item in self { let oid = match ObjectIdentifier::try_from(item.hw_type.as_str()) { Ok(oid) => oid, @@ -54,6 +56,46 @@ impl CborEncoder for Vec { } } +// BundleProtocolURISchemeTypes enum defines the type of URI scheme +// URI Scheme can be found in Section 9.7 +// https://datatracker.ietf.org/doc/rfc9171/ +// +// DTN scheme syntax +// dtn-uri = "dtn:" ("none" / dtn-hier-part) +// dtn-hier-part = "//" node-name name-delim demux ; a path-rootless +// node-name = reg-name +// name-delim = "/" +// demux = *VCHAR +// Note that - *VCHAR consists of zero or more visible characters +// Example dtn://node1/service1/data + +// IPN scheme syntax +// ipn-uri = "ipn:" ipn-hier-part +// ipn-hier-part = node-nbr nbr-delim service-nbr ; a path-rootless +// node-nbr = 1*DIGIT +// nbr-delim = "." +// service-nbr = 1*DIGIT +// Note that 1*DIGIT consists of one or more digits +#[allow(unused)] +#[derive(Clone)] +pub(crate) enum BundleProtocolURISchemeTypes { + Dtn = 1, + Ipn = 2, +} + +// EID structure define in https://datatracker.ietf.org/doc/rfc9171/ +#[derive(Clone)] +pub(crate) struct Eid { + uri_code: BundleProtocolURISchemeTypes, + ssp: String, +} + +impl CborEncoder for Eid { + fn encode(&self, encoder: &mut Encoder<&mut Vec>) { + let _unused = encoder.u8(self.uri_code.clone() as u8); + let _unused = encoder.str(&self.ssp); + } +} // Define the GeneralName struct #[derive(Clone)] pub(crate) struct GeneralName { @@ -68,6 +110,7 @@ impl CborEncoder for GeneralNamesRegistryType { GeneralNamesRegistryType::Bytes(b) => self.encode_bytes(encoder, b), GeneralNamesRegistryType::Oid(s) => self.encode_oid(encoder, s), GeneralNamesRegistryType::OidAndBytes(b) => b.encode(encoder), + GeneralNamesRegistryType::Eid(e) => e.encode(encoder), } } } @@ -78,8 +121,8 @@ impl GeneralName { } } -#[allow(unused)] // Implement the encode_alt_name function +#[allow(unused)] fn encode_alt_name(b: Vec, critical: bool, encoder: &mut Encoder<&mut Vec>) { // If subjectAltName contains exactly one dNSName, the array and the int // are omitted and extensionValue is the dNSName encoded as a CBOR text string. @@ -125,7 +168,7 @@ mod tests { // 3, [-1, [h'2B06010401B01F0A01', h'01020304']] // 03 82 20 82 49 2B 06 01 04 01 B0 1F 0A 01 44 01 02 03 04 #[test] - fn test() { + fn test_encode_general_name_hw_module_name() { let mut buffer = Vec::new(); let mut encoder = Encoder::new(&mut buffer); let general_name = GeneralName { @@ -138,4 +181,20 @@ mod tests { encode_alt_name(vec![general_name], false, &mut encoder); assert_eq!(hex::encode(buffer), "822081492b06010401b01f0a014401020304"); } + + #[test] + fn test_encode_general_name_eid() { + let mut buffer = Vec::new(); + let mut encoder = Encoder::new(&mut buffer); + let general_name = GeneralName { + gn_name: GeneralNamesRegistry::OtherNameBundleEID, + gn_value: GeneralNamesRegistryType::Eid(Eid { + uri_code: BundleProtocolURISchemeTypes::Dtn, + ssp: "dtn://node1/service1/data".to_string(), + }), + }; + encode_alt_name(vec![general_name], false, &mut encoder); + // FIXME - recheck this + assert_eq!(hex::encode(buffer), "822201781964746e3a2f2f6e6f6465312f73657276696365312f64617461"); + } }