diff --git a/rust/c509-certificate/examples/cli/main.rs b/rust/c509-certificate/examples/cli/main.rs index 9ef57c157f..e408ac96a7 100644 --- a/rust/c509-certificate/examples/cli/main.rs +++ b/rust/c509-certificate/examples/cli/main.rs @@ -8,7 +8,7 @@ use std::{ use asn1_rs::{oid, Oid}; use c509_certificate::{ - attributes::Attributes, + attributes::attribute::Attribute, big_uint::UnwrappedBigUint, extensions::Extensions, issuer_sig_algo::IssuerSignatureAlgorithm, @@ -108,7 +108,7 @@ struct C509Json { issuer_signature_algorithm: Option, /// Optional issuer of the certificate, /// if not provided, issuer is the same as subject. - issuer: Option, + issuer: Option>, /// Optional validity not before date, /// if not provided, set to current time. validity_not_before: Option, @@ -116,7 +116,7 @@ struct C509Json { /// if not provided, set to no expire date 9999-12-31T23:59:59+00:00. validity_not_after: Option, /// Attributes of the subject. - subject: Attributes, + subject: Vec, /// Optional subject public key algorithm of the certificate, /// if not provided, set to Ed25519. subject_public_key_algorithm: Option, @@ -184,10 +184,10 @@ fn generate( c509_json .issuer_signature_algorithm .unwrap_or(IssuerSignatureAlgorithm::new(key_type.0.clone(), ED25519.1)), - Some(Name::new(NameValue::Attributes(issuer))), + Some(Name::new(NameValue::Attribute(issuer))), Time::new(not_before), Time::new(not_after), - Name::new(NameValue::Attributes(c509_json.subject)), + Name::new(NameValue::Attribute(c509_json.subject)), c509_json .subject_public_key_algorithm .unwrap_or(SubjectPubKeyAlgorithm::new(key_type.0, key_type.1)), @@ -219,8 +219,8 @@ fn write_to_output_file(output: PathBuf, data: &[u8]) -> anyhow::Result<()> { /// If self-signed is true, issuer is the same as subject. /// Otherwise, issuer must be present. fn determine_issuer( - self_signed: bool, issuer: Option, subject: Attributes, -) -> anyhow::Result { + self_signed: bool, issuer: Option>, subject: Vec, +) -> anyhow::Result> { if self_signed { Ok(subject) } else { @@ -330,9 +330,9 @@ fn decode(file: &PathBuf, output: Option) -> anyhow::Result<()> { } /// Extract a `Attributes` from a `Name`. -fn extract_attributes(name: &Name) -> anyhow::Result { +fn extract_attributes(name: &Name) -> anyhow::Result> { match name.value() { - NameValue::Attributes(attrs) => Ok(attrs.clone()), + NameValue::Attribute(attrs) => Ok(attrs.clone()), _ => Err(anyhow::anyhow!("Expected Attributes")), } } diff --git a/rust/c509-certificate/src/attributes/attribute.rs b/rust/c509-certificate/src/attributes/attribute.rs index 9c85ba4e2b..60da994d00 100644 --- a/rust/c509-certificate/src/attributes/attribute.rs +++ b/rust/c509-certificate/src/attributes/attribute.rs @@ -239,7 +239,8 @@ mod test_attribute { attribute .encode(&mut encoder, &mut ()) .expect("Failed to encode Attribute"); - // Email Address example@example.com: 0x00736578616d706c65406578616d706c652e636f6d + // 1.2.840 .113549 .1 .9 .1 in attribute int = 0x00 + // Email Address example@example.com: 0x736578616d706c65406578616d706c652e636f6d assert_eq!( hex::encode(buffer.clone()), "00736578616d706c65406578616d706c652e636f6d" diff --git a/rust/c509-certificate/src/attributes/mod.rs b/rust/c509-certificate/src/attributes/mod.rs index 6b830f28dd..ef4dd5a8fb 100644 --- a/rust/c509-certificate/src/attributes/mod.rs +++ b/rust/c509-certificate/src/attributes/mod.rs @@ -111,7 +111,7 @@ mod test_attributes { .encode(&mut encoder, &mut ()) .expect("Failed to encode Attributes"); // 1 Attribute (array len 2 (attribute type + value)): 0x82 - // Email Address: 0x00 + // Email Address attribute int: 0x00 // Attribute value (array len 2): 0x82 // example@example.com: 0x736578616d706c65406578616d706c652e636f6d assert_eq!( diff --git a/rust/c509-certificate/src/big_uint.rs b/rust/c509-certificate/src/big_uint.rs index 9a8cfdb644..a6e67ad0a5 100644 --- a/rust/c509-certificate/src/big_uint.rs +++ b/rust/c509-certificate/src/big_uint.rs @@ -77,6 +77,7 @@ mod test_big_uint { b_uint .encode(&mut encoder, &mut ()) .expect("Failed to encode UnwrappedBigUint"); + // 128269 (h'01F50D'): CBOR 0x4301f50d assert_eq!(hex::encode(buffer.clone()), "4301f50d"); let mut decoder = minicbor::Decoder::new(&buffer); @@ -97,6 +98,7 @@ mod test_big_uint { b_uint .encode(&mut encoder, &mut ()) .expect("Failed to encode UnwrappedBigUint"); + // 9112578475118446130 (h'7E7661D7B54E4632'): CBOR 0x487e7661d7b54e4632 assert_eq!(hex::encode(buffer.clone()), "487e7661d7b54e4632"); let mut decoder = minicbor::Decoder::new(&buffer); diff --git a/rust/c509-certificate/src/extensions/extension/mod.rs b/rust/c509-certificate/src/extensions/extension/mod.rs index 8870793604..8fc4ea21cf 100644 --- a/rust/c509-certificate/src/extensions/extension/mod.rs +++ b/rust/c509-certificate/src/extensions/extension/mod.rs @@ -307,7 +307,7 @@ mod test_extension { let mut buffer = Vec::new(); let mut encoder = Encoder::new(&mut buffer); - // Not PEN OID and not in the registry table + // Not in the registry table // Value should be bytes let ext = Extension::new( oid!(2.16.840 .1 .101 .3 .4 .2 .1), diff --git a/rust/c509-certificate/src/general_names/mod.rs b/rust/c509-certificate/src/general_names/mod.rs index 334ed695a4..a36530333e 100644 --- a/rust/c509-certificate/src/general_names/mod.rs +++ b/rust/c509-certificate/src/general_names/mod.rs @@ -116,6 +116,16 @@ mod test_general_names { gns.encode(&mut encoder, &mut ()) .expect("Failed to encode GeneralNames"); // Array of 4 GeneralName (type, value) so 8 items: 0x88 + // Unsigned int 2 for DNSName: 0x02 + // DNSName with "example.com": 0x6b6578616d706c652e636f6d + // OtherNameHardwareModuleName negative 1: 0x20 + // Array of 2 items: 0x82 + // OID 2.16.840 .1 .101 .3 .4 .2 .1: 0x49608648016503040201 + // vec![0x01, 0x02, 0x03, 0x04]: 0x4401020304 + // IPAddress: 0x07 + // IPAddress Value in bytes string 192, 168, 1, 1: 0x44c0a80101 + // RegisteredID: 0x08 + // OID 2.16.840 .1 .101 .3 .4 .2 .1: 0x49608648016503040201 assert_eq!(hex::encode(buffer.clone()), "88026b6578616d706c652e636f6d20824960864801650304020144010203040744c0a801010849608648016503040201"); let mut decoder = Decoder::new(&buffer); diff --git a/rust/c509-certificate/src/helper/decode.rs b/rust/c509-certificate/src/helper/decode.rs index 0b760e130e..d43ef62e5e 100644 --- a/rust/c509-certificate/src/helper/decode.rs +++ b/rust/c509-certificate/src/helper/decode.rs @@ -8,7 +8,7 @@ pub(crate) fn decode_helper<'a, T, C>( ) -> Result where T: minicbor::Decode<'a, C> { T::decode(d, context).map_err(|e| { - decode::Error::message(&format!( + decode::Error::message(format!( "Failed to decode {:?} in {from}: {e}", std::any::type_name::() )) @@ -18,7 +18,7 @@ where T: minicbor::Decode<'a, C> { /// Helper function for decoding bytes. pub(crate) fn decode_bytes(d: &mut Decoder, from: &str) -> Result, decode::Error> { d.bytes().map(<[u8]>::to_vec).map_err(|e| { - decode::Error::message(&format!( + decode::Error::message(format!( "Failed to decode bytes in {from}: {e}" )) @@ -29,12 +29,12 @@ pub(crate) fn decode_bytes(d: &mut Decoder, from: &str) -> Result, decod pub(crate) fn decode_array_len(d: &mut Decoder, from: &str) -> Result { d.array() .map_err(|e| { - decode::Error::message(&format!( + decode::Error::message(format!( "Failed to decode array in {from}: {e}" )) })? - .ok_or(decode::Error::message(&format!( + .ok_or(decode::Error::message(format!( "Failed to decode array in {from}, unexpected indefinite length", ))) } @@ -42,7 +42,7 @@ pub(crate) fn decode_array_len(d: &mut Decoder, from: &str) -> Result Result<(), decode::Error> { d.null().map_err(|e| { - decode::Error::message(&format!( + decode::Error::message(format!( "Failed to decode null in {from}: {e}" )) @@ -54,7 +54,7 @@ pub(crate) fn decode_datatype( d: &mut Decoder, from: &str, ) -> Result { d.datatype().map_err(|e| { - decode::Error::message(&format!( + decode::Error::message(format!( "Failed to decode datatype in {from}: {e}" )) diff --git a/rust/c509-certificate/src/helper/encode.rs b/rust/c509-certificate/src/helper/encode.rs index 0cbfe75287..3184ce0a4c 100644 --- a/rust/c509-certificate/src/helper/encode.rs +++ b/rust/c509-certificate/src/helper/encode.rs @@ -13,7 +13,7 @@ where T: minicbor::Encode { T::encode(value, e, ctx).map_err(|err| { encode::Error::with_message( err, - &format!( + format!( "Failed to encode {:?} in {from}", std::any::type_name::() ), @@ -28,7 +28,7 @@ pub(crate) fn encode_bytes( e: &mut Encoder, from: &str, value: &[u8], ) -> Result<(), encode::Error> { e.bytes(value).map_err(|err| { - encode::Error::with_message(err, &format!("Failed to encode bytes in {from}")) + encode::Error::with_message(err, format!("Failed to encode bytes in {from}")) })?; Ok(()) } @@ -38,7 +38,7 @@ pub(crate) fn encode_null( e: &mut Encoder, from: &str, ) -> Result<(), encode::Error> { e.null().map_err(|err| { - encode::Error::with_message(err, &format!("Failed to encode null in {from}")) + encode::Error::with_message(err, format!("Failed to encode null in {from}")) })?; Ok(()) } @@ -48,7 +48,7 @@ pub(crate) fn encode_array_len( e: &mut Encoder, from: &str, len: u64, ) -> Result<(), encode::Error> { e.array(len).map_err(|err| { - encode::Error::with_message(err, &format!("Failed to encode array in {from}")) + encode::Error::with_message(err, format!("Failed to encode array in {from}")) })?; Ok(()) } diff --git a/rust/c509-certificate/src/lib.rs b/rust/c509-certificate/src/lib.rs index 6678370d65..9fad8b8f0d 100644 --- a/rust/c509-certificate/src/lib.rs +++ b/rust/c509-certificate/src/lib.rs @@ -117,13 +117,13 @@ mod test { use std::str::FromStr; use signing::tests::private_key_str; - use tbs_cert::test_tbs_cert::tbs; + use tbs_cert::test_tbs_cert::tbs_1; use super::*; #[test] fn test_generate_and_verify_signed_c509_cert() { - let tbs_cert = tbs(); + let (tbs_cert, _) = tbs_1(); let private_key = FromStr::from_str(&private_key_str()).expect( "Cannot create diff --git a/rust/c509-certificate/src/name/mod.rs b/rust/c509-certificate/src/name/mod.rs index 8a51f55921..78d1c404e3 100644 --- a/rust/c509-certificate/src/name/mod.rs +++ b/rust/c509-certificate/src/name/mod.rs @@ -4,7 +4,7 @@ //! are UTF-8 encoded and all attributeType should be non-negative. //! //! ```cddl -//! Name = [ * Attributes ] / text / bytes +//! Name = [ * Attribute ] / text / bytes //! Attribute = ( attributeType: int, attributeValue: text ) // //! ( attributeType: ~oid, attributeValue: bytes ) // //! ``` @@ -18,13 +18,10 @@ use regex::Regex; use serde::{Deserialize, Serialize}; use crate::{ - attributes::{ - attribute::{Attribute, AttributeValue}, - Attributes, - }, + attributes::attribute::{Attribute, AttributeValue}, helper::{ - decode::{decode_bytes, decode_datatype, decode_helper}, - encode::{encode_bytes, encode_helper}, + decode::{decode_array_len, decode_bytes, decode_datatype, decode_helper}, + encode::{encode_array_len, encode_bytes, encode_helper}, }, }; /// OID of `CommonName` attribute. @@ -79,8 +76,8 @@ impl Decode<'_, ()> for Name { #[derive(Debug, Clone, PartialEq, Deserialize, Serialize)] #[serde(rename_all = "snake_case")] pub enum NameValue { - /// Attributes. - Attributes(Attributes), + /// Attribute. + Attribute(Vec), /// A text. Text(String), /// bytes. @@ -92,30 +89,34 @@ impl Encode<()> for NameValue { &self, e: &mut Encoder, ctx: &mut (), ) -> Result<(), minicbor::encode::Error> { match self { - NameValue::Attributes(attrs) => { - let attr_first = - attrs - .attributes() - .first() - .ok_or(minicbor::encode::Error::message( - "Cannot get the first Attribute", - ))?; - // If Name contains a single Attribute of type CommonName - if attrs.attributes().len() == 1 - && attr_first.registered_oid().c509_oid().oid() == &COMMON_NAME_OID - { - // Get the value of the attribute - let cn_value = - attr_first - .value() - .first() - .ok_or(minicbor::encode::Error::message( - "Cannot get the first Attribute value", - ))?; - - encode_cn_value(e, cn_value)?; + NameValue::Attribute(attrs) => { + if let Some(attr_first) = attrs.first() { + // If `attrs` contains exactly one attribute of type CommonName + if attrs.len() == 1 + && attr_first.registered_oid().c509_oid().oid() == &COMMON_NAME_OID + { + // Get the value of the attribute + let cn_value = + attr_first + .value() + .first() + .ok_or(minicbor::encode::Error::message( + "Cannot get the first attribute value", + ))?; + + encode_cn_value(e, cn_value)?; + } else { + encode_array_len(e, "Attributes", attrs.len() as u64 * 2)?; + for attribute in attrs { + attribute.encode(e, ctx)?; + } + } } else { - attrs.encode(e, ctx)?; + // If is okay if the attributes is empty + encode_array_len(e, "Attributes", attrs.len() as u64 * 2)?; + for attribute in attrs { + attribute.encode(e, ctx)?; + } } }, NameValue::Text(text) => { @@ -132,7 +133,17 @@ impl Encode<()> for NameValue { impl Decode<'_, ()> for NameValue { fn decode(d: &mut Decoder<'_>, ctx: &mut ()) -> Result { match decode_datatype(d, "Name")? { - minicbor::data::Type::Array => Ok(NameValue::Attributes(Attributes::decode(d, ctx)?)), + minicbor::data::Type::Array => { + let len = decode_array_len(d, "Attributes")?; + let mut attrs = Vec::new(); + + // The attribute type is included in an array, so divide by 2 + for _ in 0..len / 2 { + let attribute = Attribute::decode(d, ctx)?; + attrs.push(attribute); + } + Ok(NameValue::Attribute(attrs)) + }, // If Name is a text string, the attribute is a CommonName minicbor::data::Type::String => { Ok(create_attributes_with_cn(decode_helper(d, "Name", ctx)?)) @@ -289,43 +300,34 @@ fn decode_eui_cn_bytes(bytes: &[u8]) -> Result NameValue { let mut attr = Attribute::new(COMMON_NAME_OID); attr.add_value(AttributeValue::Text(text)); - let mut attrs = Attributes::new(); - attrs.add_attribute(attr); - NameValue::Attributes(attrs) + NameValue::Attribute(vec![attr]) } // ------------------Test---------------------- #[cfg(test)] -pub(crate) mod test_name { +mod test_name { + use std::vec; + use super::*; use crate::attributes::attribute::Attribute; // Test data from https://datatracker.ietf.org/doc/draft-ietf-cose-cbor-encoded-cert/11/ // A.1.1. Example C509 Certificate Encoding - pub(crate) fn name_cn_text() -> (Name, String) { - let mut attr = Attribute::new(oid!(2.5.4 .3)); - attr.add_value(AttributeValue::Text("RFC test CA".to_string())); - let mut attrs = Attributes::new(); - attrs.add_attribute(attr); - - ( - Name::new(NameValue::Attributes(attrs)), - // "RFC test CA" Text string: 6b5246432074657374204341 - "6b5246432074657374204341".to_string(), - ) - } - #[test] fn encode_decode_type_name_cn() { let mut buffer = Vec::new(); let mut encoder = Encoder::new(&mut buffer); - let name = name_cn_text().0; + let mut attr = Attribute::new(oid!(2.5.4 .3)); + attr.add_value(AttributeValue::Text("RFC test CA".to_string())); + + let name = Name::new(NameValue::Attribute(vec![attr])); name.encode(&mut encoder, &mut ()) .expect("Failed to encode Name"); - assert_eq!(hex::encode(buffer.clone()), name_cn_text().1); + // "RFC test CA" text(11): 0x6b5246432074657374204341 + assert_eq!(hex::encode(buffer.clone()), "6b5246432074657374204341"); let mut decoder = Decoder::new(&buffer); let name_decoded = Name::decode(&mut decoder, &mut ()).expect("Failed to decode Name"); @@ -339,10 +341,8 @@ pub(crate) mod test_name { let mut attr = Attribute::new(oid!(2.5.4 .3)); attr.add_value(AttributeValue::Text("000123abcd".to_string())); - let mut attrs = Attributes::new(); - attrs.add_attribute(attr); - let name = Name::new(NameValue::Attributes(attrs)); + let name = Name::new(NameValue::Attribute(vec![attr])); name.encode(&mut encoder, &mut ()) .expect("Failed to encode Name"); @@ -363,10 +363,8 @@ pub(crate) mod test_name { let mut attr = Attribute::new(oid!(2.5.4 .3)); attr.add_value(AttributeValue::Text("000123ABCD".to_string())); - let mut attrs = Attributes::new(); - attrs.add_attribute(attr); - let name = Name::new(NameValue::Attributes(attrs)); + let name = Name::new(NameValue::Attribute(vec![attr])); name.encode(&mut encoder, &mut ()) .expect("Failed to encode Name"); @@ -379,32 +377,21 @@ pub(crate) mod test_name { assert_eq!(name_decoded, name); } - // Test data from https://datatracker.ietf.org/doc/draft-ietf-cose-cbor-encoded-cert/11/ - // A.1. Example RFC 7925 profiled X.509 Certificate - pub(crate) fn name_cn_eui_mac() -> (Name, String) { - let mut attr = Attribute::new(oid!(2.5.4 .3)); - attr.add_value(AttributeValue::Text("01-23-45-FF-FE-67-89-AB".to_string())); - let mut attrs = Attributes::new(); - attrs.add_attribute(attr); - - ( - Name::new(NameValue::Attributes(attrs)), - // Bytes of length 7: 0x47 - // "01-23-45-FF-FE-67-89-AB" special encode: 0x010123456789AB - "47010123456789ab".to_string(), - ) - } - #[test] fn encode_decode_type_name_cn_eui_mac() { let mut buffer = Vec::new(); let mut encoder = Encoder::new(&mut buffer); - let name = name_cn_eui_mac().0; + let mut attr = Attribute::new(oid!(2.5.4 .3)); + attr.add_value(AttributeValue::Text("01-23-45-FF-FE-67-89-AB".to_string())); + + let name = Name::new(NameValue::Attribute(vec![attr])); name.encode(&mut encoder, &mut ()) .expect("Failed to encode Name"); - assert_eq!(hex::encode(buffer.clone()), name_cn_eui_mac().1); + // Bytes of length 7: 0x47 + // "01-23-45-FF-FE-67-89-AB" special encode: 0x010123456789AB + assert_eq!(hex::encode(buffer.clone()), "47010123456789ab"); let mut decoder = Decoder::new(&buffer); let name_decoded = Name::decode(&mut decoder, &mut ()).expect("Failed to decode Name"); @@ -418,9 +405,7 @@ pub(crate) mod test_name { let mut attr = Attribute::new(oid!(2.5.4 .3)); attr.add_value(AttributeValue::Text("01-23-45-ff-fe-67-89-AB".to_string())); - let mut attrs = Attributes::new(); - attrs.add_attribute(attr); - let name = Name::new(NameValue::Attributes(attrs)); + let name = Name::new(NameValue::Attribute(vec![attr])); name.encode(&mut encoder, &mut ()) .expect("Failed to encode Name"); @@ -444,14 +429,13 @@ pub(crate) mod test_name { let mut attr = Attribute::new(oid!(2.5.4 .3)); attr.add_value(AttributeValue::Text("01-23-45-67-89-AB-00-01".to_string())); - let mut attrs = Attributes::new(); - attrs.add_attribute(attr); - let name = Name::new(NameValue::Attributes(attrs)); + let name = Name::new(NameValue::Attribute(vec![attr])); name.encode(&mut encoder, &mut ()) .expect("Failed to encode Name"); + // 01-23-45-67-89-AB-00-01 = h'010123456789AB0001': 0x49010123456789ab0001 assert_eq!(hex::encode(buffer.clone()), "49010123456789ab0001"); let mut decoder = Decoder::new(&buffer); @@ -466,10 +450,8 @@ pub(crate) mod test_name { let mut attr = Attribute::new(oid!(2.5.4 .3)); attr.add_value(AttributeValue::Text("01-23-45-67-89-ab-00-01".to_string())); - let mut attrs = Attributes::new(); - attrs.add_attribute(attr); - let name = Name::new(NameValue::Attributes(attrs)); + let name = Name::new(NameValue::Attribute(vec![attr])); name.encode(&mut encoder, &mut ()) .expect("Failed to encode Name"); @@ -489,8 +471,11 @@ pub(crate) mod test_name { // Test data from https://datatracker.ietf.org/doc/draft-ietf-cose-cbor-encoded-cert/11/ // A.2. Example IEEE 802.1AR profiled X.509 Certificate // Issuer: C=US, ST=CA, O=Example Inc, OU=certification, CN=802.1AR CA - #[allow(clippy::similar_names)] - pub(crate) fn names() -> (Name, String) { + #[test] + fn encode_decode_type_name_attrs() { + let mut buffer = Vec::new(); + let mut encoder = Encoder::new(&mut buffer); + let mut attr1 = Attribute::new(oid!(2.5.4 .6)); attr1.add_value(AttributeValue::Text("US".to_string())); let mut attr2 = Attribute::new(oid!(2.5.4 .8)); @@ -502,34 +487,30 @@ pub(crate) mod test_name { let mut attr5 = Attribute::new(oid!(2.5.4 .3)); attr5.add_value(AttributeValue::Text("802.1AR CA".to_string())); - let mut attrs = Attributes::new(); - attrs.add_attribute(attr1); - attrs.add_attribute(attr2); - attrs.add_attribute(attr3); - attrs.add_attribute(attr4); - attrs.add_attribute(attr5); - - ( - Name::new(NameValue::Attributes(attrs)), - // Array of 10 items [4, "US", 6, "CA", 8, "Example Inc", 9, "certification", 1, "802.1AR CA"] : 0x8a - // attr1: 0x04625553 - // attr2: 0x06624341 - // attr3: 0x086b4578616d706c6520496e63 - // attr4: 0x096d63657274696669636174696f6e - // attr5: 0x016a3830322e314152204341 - "8a0462555306624341086b4578616d706c6520496e63096d63657274696669636174696f6e016a3830322e314152204341".to_string(), - ) + let name = Name::new(NameValue::Attribute(vec![ + attr1, attr2, attr3, attr4, attr5, + ])); + + name.encode(&mut encoder, &mut ()) + .expect("Failed to encode Name"); + assert_eq!(hex::encode(buffer.clone()), "8a0462555306624341086b4578616d706c6520496e63096d63657274696669636174696f6e016a3830322e314152204341"); + + let mut decoder = Decoder::new(&buffer); + let name_decoded = Name::decode(&mut decoder, &mut ()).expect("Failed to decode Name"); + assert_eq!(name_decoded, name); } + #[test] - fn encode_decode_type_name_attrs() { + fn encode_decode_empty_attribute() { let mut buffer = Vec::new(); let mut encoder = Encoder::new(&mut buffer); - let name = names().0; + let name = Name::new(NameValue::Attribute(vec![])); name.encode(&mut encoder, &mut ()) .expect("Failed to encode Name"); - assert_eq!(hex::encode(buffer.clone()), names().1); + + assert_eq!(hex::encode(buffer.clone()), "80"); let mut decoder = Decoder::new(&buffer); let name_decoded = Name::decode(&mut decoder, &mut ()).expect("Failed to decode Name"); diff --git a/rust/c509-certificate/src/oid.rs b/rust/c509-certificate/src/oid.rs index 4f566394cb..52ba8e3778 100644 --- a/rust/c509-certificate/src/oid.rs +++ b/rust/c509-certificate/src/oid.rs @@ -142,6 +142,9 @@ mod test_c509_oid { let oid = C509oid::new(oid!(2.16.840 .1 .101 .3 .4 .2 .1)); oid.encode(&mut encoder, &mut ()) .expect("Failed to encode OID"); + // bytes(9) 0x49 + // 0x60 (for 2.16) + // 0x18, 0x03, 0x60, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01 assert_eq!(hex::encode(buffer.clone()), "49608648016503040201"); let mut decoder = Decoder::new(&buffer); diff --git a/rust/c509-certificate/src/tbs_cert.rs b/rust/c509-certificate/src/tbs_cert.rs index fbaf4d9bd9..c909c53ae1 100644 --- a/rust/c509-certificate/src/tbs_cert.rs +++ b/rust/c509-certificate/src/tbs_cert.rs @@ -197,10 +197,7 @@ pub(crate) mod test_tbs_cert { use super::*; use crate::{ - attributes::{ - attribute::{Attribute, AttributeValue}, - Attributes, - }, + attributes::attribute::{Attribute, AttributeValue}, extensions::{ alt_name::{AlternativeName, GeneralNamesOrText}, extension::{Extension, ExtensionValue}, @@ -210,10 +207,7 @@ pub(crate) mod test_tbs_cert { other_name_hw_module::OtherNameHardwareModuleName, GeneralNames, }, - name::{ - test_name::{name_cn_eui_mac, name_cn_text, names}, - NameValue, - }, + name::NameValue, }; // Mnemonic: match mad promote group rival case @@ -221,81 +215,88 @@ pub(crate) mod test_tbs_cert { // Test reference https://datatracker.ietf.org/doc/draft-ietf-cose-cbor-encoded-cert/11/ // A.1. Example RFC 7925 profiled X.509 Certificate - // - // - // Certificate: - // Data: - // Version: 3 (0x2) - // Serial Number: 128269 (0x1f50d) - // Signature Algorithm: ecdsa-with-SHA256 - // Issuer: CN=RFC test CA - // Validity - // Not Before: Jan 1 00:00:00 2023 GMT - // Not After : Jan 1 00:00:00 2026 GMT - // Subject: CN=01-23-45-FF-FE-67-89-AB - // Subject Public Key Info: - // Public Key Algorithm: id-ecPublicKey - // Public-Key: (256 bit) - // pub: - // 04:b1:21:6a:b9:6e:5b:3b:33:40:f5:bd:f0:2e:69: - // 3f:16:21:3a:04:52:5e:d4:44:50:b1:01:9c:2d:fd: - // 38:38:ab:ac:4e:14:d8:6c:09:83:ed:5e:9e:ef:24: - // 48:c6:86:1c:c4:06:54:71:77:e6:02:60:30:d0:51: - // f7:79:2a:c2:06 - // ASN1 OID: prime256v1 - // NIST CURVE: P-256 - // X509v3 extensions: - // X509v3 Key Usage: - // Digital Signature - // Signature Algorithm: ecdsa-with-SHA256 - // 30:46:02:21:00:d4:32:0b:1d:68:49:e3:09:21:9d:30:03:7e: - // 13:81:66:f2:50:82:47:dd:da:e7:6c:ce:ea:55:05:3c:10:8e: - // 90:02:21:00:d5:51:f6:d6:01:06:f1:ab:b4:84:cf:be:62:56: - // c1:78:e4:ac:33:14:ea:19:19:1e:8b:60:7d:a5:ae:3b:da:16 - // - // 01 - // 43 01 F5 0D - // 6B 52 46 43 20 74 65 73 74 20 43 41 - // 1A 63 B0 CD 00 - // 1A 69 55 B9 00 - // 47 01 01 23 45 67 89 AB - // 01 - // 58 21 02 B1 21 6A B9 6E 5B 3B 33 40 F5 BD F0 2E 69 3F 16 21 3A 04 52 - // 5E D4 44 50 B1 01 9C 2D FD 38 38 AB - // 01 - // 00 - // 58 40 D4 32 0B 1D 68 49 E3 09 21 9D 30 03 7E 13 81 66 F2 50 82 47 DD - // DA E7 6C CE EA 55 05 3C 10 8E 90 D5 51 F6 D6 01 06 F1 AB B4 84 CF BE - // 62 56 C1 78 E4 AC 33 14 EA 19 19 1E 8B 60 7D A5 AE 3B DA 16 - - pub(crate) fn tbs() -> TbsCert { - fn extensions() -> Extensions { - let mut exts = Extensions::new(); - exts.add_extension(Extension::new( - oid!(2.5.29 .15), - ExtensionValue::Int(1), - false, - )); - exts - } + pub(crate) fn tbs_1() -> (TbsCert, String) { + let tbs_certificate = ( + 3, // c509_certificate_type + 128_269, // certificate_serial_number + oid!(1.2.840 .10045 .4 .3 .2), // issuer_signature_algorithm (ecdsa-with-SHA256) + ( + // issuer + oid!(2.5.4 .3), // oid (commonName) + "RFC test CA", // value + false, // critical + ), + 1_672_531_200, // validity_not_before + 1_767_225_600, // validity_not_after + ( + // subject + oid!(2.5.4 .3), // oid (commonName) + "01-23-45-FF-FE-67-89-AB", // value + false, // critical + ), + oid!(1.2.840 .10045 .2 .1), /* subject_public_key_algorithm (id-ecPublicKey + * prime256v1 P-256) */ + PUBKEY, // subject_public_key (modified from the example) + ( + // extensions + oid!(2.5.29 .15), // oid (keyUsage) + 1, // value + false, // critical + ), + ); + + let tbs_certificate_cbor = [ + "03", // c509_certificate_type + "4301f50d", // certificate_serial_number + "00", // issuer_signature_algorithm + "6b5246432074657374204341", // issuer + "1a63b0cd00", // validity_not_before + "1a6955b900", // validity_not_after + "47010123456789ab", // subject + "01", // subject_public_key_algorithm + "4888d0b6b0b37baa46", // subject_public_key + "01", // extensions + ]; + + // Issuer + let mut attr1 = Attribute::new(tbs_certificate.3 .0); + attr1.add_value(AttributeValue::Text(tbs_certificate.3 .1.to_string())); + let issuer = Name::new(NameValue::Attribute(vec![attr1])); + + // Subject + let mut attr2 = Attribute::new(tbs_certificate.6 .0); + attr2.add_value(AttributeValue::Text(tbs_certificate.6 .1.to_string())); + let subject = Name::new(NameValue::Attribute(vec![attr2])); + + // Extensions + let mut extensions = Extensions::new(); + extensions.add_extension(Extension::new( + tbs_certificate.9 .0, + ExtensionValue::Int(tbs_certificate.9 .1), + tbs_certificate.9 .2, + )); + + let data = TbsCert::new( + tbs_certificate.0, + UnwrappedBigUint::new(tbs_certificate.1), + IssuerSignatureAlgorithm::new(tbs_certificate.2, None), + Some(issuer), + Time::new(tbs_certificate.4), + Time::new(tbs_certificate.5), + subject, + SubjectPubKeyAlgorithm::new(tbs_certificate.7, None), + tbs_certificate.8.to_vec(), + extensions, + ); - TbsCert::new( - 1, - UnwrappedBigUint::new(128_269), - IssuerSignatureAlgorithm::new(oid!(1.2.840 .10045 .4 .3 .2), None), - Some(name_cn_text().0), - Time::new(1_672_531_200), - Time::new(1_767_225_600), - name_cn_eui_mac().0, - SubjectPubKeyAlgorithm::new(oid!(1.2.840 .10045 .2 .1), None), - PUBKEY.to_vec(), - extensions(), - ) + let concatenated: String = tbs_certificate_cbor.concat(); + + (data, concatenated) } #[test] - fn encode_decode_tbs_cert() { - let tbs_cert = tbs(); + fn encode_decode_tbs_cert_1() { + let (tbs_cert, tbs_cert_cbor) = tbs_1(); let mut buffer = Vec::new(); let mut encoder = Encoder::new(&mut buffer); @@ -303,21 +304,7 @@ pub(crate) mod test_tbs_cert { .encode(&mut encoder, &mut ()) .expect("Failed to encode TBS Certificate"); - // c509_certificate_type: 0x01 - // certificate_serial_number: 0x4301f50d - // issuer: 0x6b5246432074657374204341 - // validity_not_before: 0x1a63b0cd00 - // validity_not_after: 0x1a6955b900 - // subject: 0x47010123456789ab - // subject_public_key_algorithm: 0x01 - // subject_public_key: 0x4888d0b6b0b37baa46 - // extensions: 0x01 - // issuer_signature_algorithm: 0x00 - - assert_eq!( - hex::encode(buffer.clone()), - "014301f50d6b52464320746573742043411a63b0cd001a6955b90047010123456789ab014888d0b6b0b37baa460100" - ); + assert_eq!(hex::encode(buffer.clone()), tbs_cert_cbor); let mut decoder = Decoder::new(&buffer); let decoded_tbs = @@ -327,168 +314,208 @@ pub(crate) mod test_tbs_cert { // Test reference https://datatracker.ietf.org/doc/draft-ietf-cose-cbor-encoded-cert/11/ // A.2. Example IEEE 802.1AR profiled X.509 Certificate - // - // Certificate: - // Data: - // Version: 3 (0x2) - // Serial Number: 9112578475118446130 (0x7e7661d7b54e4632) - // Signature Algorithm: ecdsa-with-SHA256 - // Issuer: C=US, ST=CA, O=Example Inc, OU=certification, CN=802.1AR CA - // Validity - // Not Before: Jan 31 11:29:16 2019 GMT - // Not After : Dec 31 23:59:59 9999 GMT - // Subject: C=US, ST=CA, L=LA, O=example Inc, OU=IoT/serialNumber=Wt1234 - // Subject Public Key Info: - // Public Key Algorithm: id-ecPublicKey - // Public-Key: (256 bit) - // pub: - // 04:c8:b4:21:f1:1c:25:e4:7e:3a:c5:71:23:bf:2d: - // 9f:dc:49:4f:02:8b:c3:51:cc:80:c0:3f:15:0b:f5: - // 0c:ff:95:8d:75:41:9d:81:a6:a2:45:df:fa:e7:90: - // be:95:cf:75:f6:02:f9:15:26:18:f8:16:a2:b2:3b: - // 56:38:e5:9f:d9 - // ASN1 OID: prime256v1 - // NIST CURVE: P-256 - // X509v3 extensions: - // X509v3 Basic Constraints: - // CA:FALSE - // X509v3 Subject Key Identifier: - // 96:60:0D:87:16:BF:7F:D0:E7:52:D0:AC:76:07:77:AD:66:5D:02:A0 - // X509v3 Authority Key Identifier: - // 68:D1:65:51:F9:51:BF:C8:2A:43:1D:0D:9F:08:BC:2D:20:5B:11:60 - // X509v3 Key Usage: critical - // Digital Signature, Key Encipherment - // X509v3 Subject Alternative Name: - // otherName: - // type-id: 1.3.6.1.5.5.7.8.4 (id-on-hardwareModuleName) - // value: - // hwType: 1.3.6.1.4.1.6175.10.1 - // hwSerialNum: 01:02:03:04 - // Signature Algorithm: ecdsa-with-SHA256 - // Signature Value: - // 30:46:02:21:00:c0:d8:19:96:d2:50:7d:69:3f:3c:48:ea:a5: - // ee:94:91:bd:a6:db:21:40:99:d9:81:17:c6:3b:36:13:74:cd: - // 86:02:21:00:a7:74:98:9f:4c:32:1a:5c:f2:5d:83:2a:4d:33: - // 6a:08:ad:67:df:20:f1:50:64:21:18:8a:0a:de:6d:34:92:36 - // - // 01 48 7E 76 61 D7 B5 4E 46 32 8A 23 62 55 53 06 62 43 41 08 6B 45 78 - // 61 6D 70 6C 65 20 49 6E 63 09 6D 63 65 72 74 69 66 69 63 61 74 69 6F - // 6E 01 6A 38 30 32 2E 31 41 52 20 43 41 1A 5C 52 DC 0C F6 8C 23 62 55 - // 53 06 62 43 41 05 62 4C 41 08 6B 65 78 61 6D 70 6C 65 20 49 6E 63 09 - // 63 49 6F 54 22 66 57 74 31 32 33 34 01 58 21 03 C8 B4 21 F1 1C 25 E4 - // 7E 3A C5 71 23 BF 2D 9F DC 49 4F 02 8B C3 51 CC 80 C0 3F 15 0B F5 0C - // FF 95 8A 04 21 01 54 96 60 0D 87 16 BF 7F D0 E7 52 D0 AC 76 07 77 AD - // 66 5D 02 A0 07 54 68 D1 65 51 F9 51 BF C8 2A 43 1D 0D 9F 08 BC 2D 20 - // 5B 11 60 21 05 03 82 20 82 49 2B 06 01 04 01 B0 1F 0A 01 44 01 02 03 - // 04 00 58 40 C0 D8 19 96 D2 50 7D 69 3F 3C 48 EA A5 EE 94 91 BD A6 DB - // 21 40 99 D9 81 17 C6 3B 36 13 74 CD 86 A7 74 98 9F 4C 32 1A 5C F2 5D - // 83 2A 4D 33 6A 08 AD 67 DF 20 F1 50 64 21 18 8A 0A DE 6D 34 92 36 - - #[test] - #[allow(clippy::similar_names)] - fn tbs_cert2() { - // ---------helper---------- - // C=US, ST=CA, L=LA, O=example Inc, OU=IoT/serialNumber=Wt1234 - fn subject() -> Name { - let mut attr1 = Attribute::new(oid!(2.5.4 .6)); - attr1.add_value(AttributeValue::Text("US".to_string())); - let mut attr2 = Attribute::new(oid!(2.5.4 .8)); - attr2.add_value(AttributeValue::Text("CA".to_string())); - let mut attr3 = Attribute::new(oid!(2.5.4 .7)); - attr3.add_value(AttributeValue::Text("LA".to_string())); - let mut attr4 = Attribute::new(oid!(2.5.4 .10)); - attr4.add_value(AttributeValue::Text("example Inc".to_string())); - let mut attr5 = Attribute::new(oid!(2.5.4 .11)); - attr5.add_value(AttributeValue::Text("IoT".to_string())); - let mut attr6 = Attribute::new(oid!(2.5.4 .5)); - attr6.add_value(AttributeValue::Text("Wt1234".to_string())); - - let mut attrs = Attributes::new(); - attrs.add_attribute(attr1); - attrs.add_attribute(attr2); - attrs.add_attribute(attr3); - attrs.add_attribute(attr4); - attrs.add_attribute(attr5); - attrs.add_attribute(attr6); - - Name::new(NameValue::Attributes(attrs)) - } - - fn extensions() -> Extensions { - let mut exts = Extensions::new(); - exts.add_extension(Extension::new( - oid!(2.5.29 .19), - ExtensionValue::Int(-2), - false, - )); - exts.add_extension(Extension::new( - oid!(2.5.29 .14), - ExtensionValue::Bytes( + #[allow(clippy::too_many_lines)] + fn tbs_2() -> (TbsCert, String) { + let tbs_certificate = ( + 3, // c509_certificate_type + 9_112_578_475_118_446_130, // certificate_serial_number + oid!(1.2.840 .10045 .4 .3 .2), // issuer_signature_algorithm (ecdsa-with-SHA256) + [ + // issuer + ( + oid!(2.5.4 .6), // oid (C: countryName) + "US", // value + false, // critical + ), + ( + oid!(2.5.4 .8), // oid (ST: stateOrProvinceName) + "CA", // value + false, // critical + ), + ( + oid!(2.5.4 .10), // oid (O: organizationName) + "Example Inc", // value + false, // critical + ), + ( + oid!(2.5.4 .11), // oid (OU: organizationalUnitName) + "certification", // value + false, // critical + ), + ( + oid!(2.5.4 .3), // oid (CN: commonName) + "802.1AR CA", // value + false, // critical + ), + ], + 1_548_934_156, // validity_not_before + 253_402_300_799, // validity_not_after + [ + // subject + ( + oid!(2.5.4 .6), // oid (C: countryName) + "US", // value + false, // critical + ), + ( + oid!(2.5.4 .8), // oid (ST: stateOrProvinceName) + "CA", // value + false, // critical + ), + ( + oid!(2.5.4 .7), // oid (L: localityName) + "LA", // value + false, // critical + ), + ( + oid!(2.5.4 .10), // oid (O: organizationName) + "example Inc", // value + false, // critical + ), + ( + oid!(2.5.4 .11), // oid (OU: organizationalUnitName) + "IoT", // value + false, // critical + ), + ( + oid!(2.5.4 .5), // oid (serialNumber) + "Wt1234", // value + false, // critical + ), + ], + oid!(1.2.840 .10045 .2 .1), /* subject_public_key_algorithm (id-ecPublicKey + * prime256v1 P-256) */ + PUBKEY, // subject_public_key (modified from the example) + ( + // extensions + ( + oid!(2.5.29 .19), // oid (basicConstraints) + -2, // value + false, // critical + ), + ( + oid!(2.5.29 .14), // oid (subjectKeyIdentifier) [ 0x96, 0x60, 0x0D, 0x87, 0x16, 0xBF, 0x7F, 0xD0, 0xE7, 0x52, 0xD0, 0xAC, 0x76, 0x07, 0x77, 0xAD, 0x66, 0x5D, 0x02, 0xA0, - ] - .to_vec(), + ], // value + false, // critical ), - false, - )); - exts.add_extension(Extension::new( - oid!(2.5.29 .15), - ExtensionValue::Int(5), - true, + ( + oid!(2.5.29 .15), // oid (keyUsage) + 5, // value + true, // critical + ), + ( + oid!(2.5.29 .17), // oid (subjectAltName) + ( + oid!(1.3.6 .1 .4 .1 .6175 .10 .1), // hwType + [0x01, 0x02, 0x03, 0x04], // hwSerialNum + ), + false, // critical + ), + ), + ); + + let tbs_certificate_cbor = [ + "03", // c509_certificate_type + "487e7661d7b54e4632", // certificate_serial_number + "00", // issuer_signature_algorithm + "8a0462555306624341086b4578616d706c6520496e63096d63657274696669636174696f6e016a3830322e314152204341", // issuer + "1a5c52dc0c", // validity_not_before + "f6", // validity_not_after + "8c046255530662434105624c41086b6578616d706c6520496e630963496f540366577431323334", // subject + "01", // subject_public_key_algorithm + "4888d0b6b0b37baa46", // subject_public_key + "840421015496600d8716bf7fd0e752d0ac760777ad665d02a0210503822082492b06010401b01f0a014401020304", // extensions + ]; + + // Issuer + let mut attributes_1 = Vec::new(); + for i in 0..tbs_certificate.3.len() { + let mut attr = Attribute::new(tbs_certificate.3.get(i).unwrap().0.clone()); + attr.add_value(AttributeValue::Text( + tbs_certificate.3.get(i).unwrap().1.to_string(), )); - let mut gns = GeneralNames::new(); - let hw = OtherNameHardwareModuleName::new(oid!(1.3.6 .1 .4 .1 .6175 .10 .1), vec![ - 0x01, 0x02, 0x03, 0x04, - ]); - gns.add_general_name(GeneralName::new( - GeneralNameTypeRegistry::OtherNameHardwareModuleName, - GeneralNameValue::OtherNameHWModuleName(hw), + attributes_1.push(attr); + } + let issuer = Name::new(NameValue::Attribute(attributes_1)); + + // Subject + let mut attributes_2 = Vec::new(); + for i in 0..tbs_certificate.6.len() { + let mut attr = Attribute::new(tbs_certificate.6.get(i).unwrap().0.clone()); + attr.add_value(AttributeValue::Text( + tbs_certificate.6.get(i).unwrap().1.to_string(), )); + attributes_2.push(attr); + } + let subject = Name::new(NameValue::Attribute(attributes_2)); + + // Extensions + let mut extensions = Extensions::new(); + extensions.add_extension(Extension::new( + tbs_certificate.9 .0 .0, + ExtensionValue::Int(tbs_certificate.9 .0 .1), + tbs_certificate.9 .0 .2, + )); + extensions.add_extension(Extension::new( + tbs_certificate.9 .1 .0, + ExtensionValue::Bytes(tbs_certificate.9 .1 .1.to_vec()), + tbs_certificate.9 .1 .2, + )); + extensions.add_extension(Extension::new( + tbs_certificate.9 .2 .0, + ExtensionValue::Int(tbs_certificate.9 .2 .1), + tbs_certificate.9 .2 .2, + )); + let mut gns = GeneralNames::new(); + let hw = OtherNameHardwareModuleName::new( + tbs_certificate.9 .3 .1 .0, + tbs_certificate.9 .3 .1 .1.to_vec(), + ); + gns.add_general_name(GeneralName::new( + GeneralNameTypeRegistry::OtherNameHardwareModuleName, + GeneralNameValue::OtherNameHWModuleName(hw), + )); + + extensions.add_extension(Extension::new( + tbs_certificate.9 .3 .0, + ExtensionValue::AlternativeName(AlternativeName::new( + GeneralNamesOrText::GeneralNames(gns), + )), + false, + )); + + let data = TbsCert::new( + tbs_certificate.0, + UnwrappedBigUint::new(tbs_certificate.1), + IssuerSignatureAlgorithm::new(tbs_certificate.2, None), + Some(issuer), + Time::new(tbs_certificate.4), + Time::new(tbs_certificate.5), + subject, + SubjectPubKeyAlgorithm::new(tbs_certificate.7, None), + tbs_certificate.8.to_vec(), + extensions, + ); - exts.add_extension(Extension::new( - oid!(2.5.29 .17), - ExtensionValue::AlternativeName(AlternativeName::new( - GeneralNamesOrText::GeneralNames(gns), - )), - false, - )); + let concatenated: String = tbs_certificate_cbor.concat(); - exts - } + (data, concatenated) + } - let tbs_cert = TbsCert::new( - 1, - UnwrappedBigUint::new(9_112_578_475_118_446_130), - IssuerSignatureAlgorithm::new(oid!(1.2.840 .10045 .4 .3 .2), None), - Some(names().0), - Time::new(1_548_934_156), - Time::new(253_402_300_799), - subject(), - SubjectPubKeyAlgorithm::new(oid!(1.2.840 .10045 .2 .1), None), - PUBKEY.to_vec(), - extensions(), - ); + #[test] + fn encode_decode_tbs_cert_2() { + let (tbs_cert, tbs_cert_cbor) = tbs_2(); let mut buffer = Vec::new(); let mut encoder = Encoder::new(&mut buffer); tbs_cert .encode(&mut encoder, &mut ()) .expect("Failed to encode TBS Certificate"); - // c509_certificate_type: 0x01 - // certificate_serial_number: 0x487e7661d7b54e4632 - // issuer: 0x8a0462555306624341086b4578616d706c6520496e63096d63657274696669636174696f6e016a3830322e314152204341 - // validity_not_before: 0x1a5c52dc0c - // validity_not_after: 0xf6 - // subject: 0x8c046255530662434105624c41086b6578616d706c6520496e630963496f540366577431323334 - // subject_public_key_algorithm: 0x01 - // subject_public_key: 0x4888d0b6b0b37baa46 - // extensions: - // 0x840421015496600d8716bf7fd0e752d0ac760777ad665d02a0210503822082492b06010401b01f0a014401020304 - // issuer_signature_algorithm: 0x00 - assert_eq!(hex::encode(buffer.clone()), - "01487e7661d7b54e46328a0462555306624341086b4578616d706c6520496e63096d63657274696669636174696f6e016a3830322e3141522043411a5c52dc0cf68c046255530662434105624c41086b6578616d706c6520496e630963496f540366577431323334014888d0b6b0b37baa46840421015496600d8716bf7fd0e752d0ac760777ad665d02a0210503822082492b06010401b01f0a01440102030400" - ); + assert_eq!(hex::encode(buffer.clone()), tbs_cert_cbor); + let mut decoder = Decoder::new(&buffer); let decoded_tbs = TbsCert::decode(&mut decoder, &mut ()).expect("Failed to decode TBS Certificate"); diff --git a/rust/c509-certificate/src/time.rs b/rust/c509-certificate/src/time.rs index 514687ab23..b3e74a178f 100644 --- a/rust/c509-certificate/src/time.rs +++ b/rust/c509-certificate/src/time.rs @@ -106,6 +106,7 @@ mod test_time { let time = Time::new(1_672_531_200); time.encode(&mut encoder, &mut ()) .expect("Failed to encode Time"); + // 1A 63B0CD00 # unsigned(1672531200) assert_eq!(hex::encode(buffer.clone()), "1a63b0cd00"); let mut decoder = minicbor::Decoder::new(&buffer); diff --git a/rust/cardano-chain-follower/src/metadata/cip509/decode_helper.rs b/rust/cardano-chain-follower/src/metadata/cip509/decode_helper.rs index 366c20b892..a75ac3eaa5 100644 --- a/rust/cardano-chain-follower/src/metadata/cip509/decode_helper.rs +++ b/rust/cardano-chain-follower/src/metadata/cip509/decode_helper.rs @@ -8,7 +8,7 @@ pub(crate) fn decode_helper<'a, T, C>( ) -> Result where T: minicbor::Decode<'a, C> { T::decode(d, context).map_err(|e| { - decode::Error::message(&format!( + decode::Error::message(format!( "Failed to decode {:?} in {from}: {e}", std::any::type_name::() )) @@ -18,7 +18,7 @@ where T: minicbor::Decode<'a, C> { /// Helper function for decoding bytes. pub(crate) fn decode_bytes(d: &mut Decoder, from: &str) -> Result, decode::Error> { d.bytes().map(<[u8]>::to_vec).map_err(|e| { - decode::Error::message(&format!( + decode::Error::message(format!( "Failed to decode bytes in {from}: {e}" )) @@ -29,12 +29,12 @@ pub(crate) fn decode_bytes(d: &mut Decoder, from: &str) -> Result, decod pub(crate) fn decode_array_len(d: &mut Decoder, from: &str) -> Result { d.array() .map_err(|e| { - decode::Error::message(&format!( + decode::Error::message(format!( "Failed to decode array in {from}: {e}" )) })? - .ok_or(decode::Error::message(&format!( + .ok_or(decode::Error::message(format!( "Failed to decode array in {from}, unexpected indefinite length", ))) }