Merge pull request #12 from kedars/feature/txt-fields-dn
Certs: Include support for text fields in Distinguished Names
This commit is contained in:
		
						commit
						d77871e44e
					
				
					 5 changed files with 277 additions and 53 deletions
				
			
		| 
						 | 
					@ -180,13 +180,18 @@ impl<'a> CertConsumer for ASN1Writer<'a> {
 | 
				
			||||||
        self.write_str(0x02, i)
 | 
					        self.write_str(0x02, i)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fn printstr(&mut self, _tag: &str, s: &str) -> Result<(), Error> {
 | 
				
			||||||
 | 
					        // Note: ASN1 has multiple strings, this is PrintableString
 | 
				
			||||||
 | 
					        self.write_str(0x13, s.as_bytes())
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fn utf8str(&mut self, _tag: &str, s: &str) -> Result<(), Error> {
 | 
					    fn utf8str(&mut self, _tag: &str, s: &str) -> Result<(), Error> {
 | 
				
			||||||
        // Note: ASN1 has 3 string, this is UTF8String
 | 
					        // Note: ASN1 has multiple strings, this is UTF8String
 | 
				
			||||||
        self.write_str(0x0c, s.as_bytes())
 | 
					        self.write_str(0x0c, s.as_bytes())
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fn bitstr(&mut self, _tag: &str, truncate: bool, s: &[u8]) -> Result<(), Error> {
 | 
					    fn bitstr(&mut self, _tag: &str, truncate: bool, s: &[u8]) -> Result<(), Error> {
 | 
				
			||||||
        // Note: ASN1 has 3 string, this is BIT String
 | 
					        // Note: ASN1 has multiple strings, this is BIT String
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Strip off the end zeroes
 | 
					        // Strip off the end zeroes
 | 
				
			||||||
        let mut last_byte = s.len() - 1;
 | 
					        let mut last_byte = s.len() - 1;
 | 
				
			||||||
| 
						 | 
					@ -208,7 +213,7 @@ impl<'a> CertConsumer for ASN1Writer<'a> {
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fn ostr(&mut self, _tag: &str, s: &[u8]) -> Result<(), Error> {
 | 
					    fn ostr(&mut self, _tag: &str, s: &[u8]) -> Result<(), Error> {
 | 
				
			||||||
        // Note: ASN1 has 3 string, this is Octet String
 | 
					        // Note: ASN1 has multiple strings, this is Octet String
 | 
				
			||||||
        self.write_str(0x04, s)
 | 
					        self.write_str(0x04, s)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -180,10 +180,10 @@ impl BasicConstraints {
 | 
				
			||||||
        w.start_seq("")?;
 | 
					        w.start_seq("")?;
 | 
				
			||||||
        if self.is_ca {
 | 
					        if self.is_ca {
 | 
				
			||||||
            // Encode CA only if true
 | 
					            // Encode CA only if true
 | 
				
			||||||
            w.bool("CA:", true)?
 | 
					            w.bool("CA:", true)?;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        if self.path.is_some() {
 | 
					        if let Some(len) = self.path {
 | 
				
			||||||
            error!("Path Len is not yet implemented");
 | 
					            w.integer("Path Len Constraint", &[len])?;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        w.end_seq()
 | 
					        w.end_seq()
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					@ -268,6 +268,22 @@ const MAX_DN_ENTRIES: usize = 5;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[derive(FromPrimitive, Copy, Clone)]
 | 
					#[derive(FromPrimitive, Copy, Clone)]
 | 
				
			||||||
enum DnTags {
 | 
					enum DnTags {
 | 
				
			||||||
 | 
					    CommonName = 1,
 | 
				
			||||||
 | 
					    Surname = 2,
 | 
				
			||||||
 | 
					    SerialNum = 3,
 | 
				
			||||||
 | 
					    CountryName = 4,
 | 
				
			||||||
 | 
					    LocalityName = 5,
 | 
				
			||||||
 | 
					    StateName = 6,
 | 
				
			||||||
 | 
					    OrgName = 7,
 | 
				
			||||||
 | 
					    OrgUnitName = 8,
 | 
				
			||||||
 | 
					    Title = 9,
 | 
				
			||||||
 | 
					    Name = 10,
 | 
				
			||||||
 | 
					    GivenName = 11,
 | 
				
			||||||
 | 
					    Intials = 12,
 | 
				
			||||||
 | 
					    GenQalifier = 13,
 | 
				
			||||||
 | 
					    DnQualifier = 14,
 | 
				
			||||||
 | 
					    Pseudonym = 15,
 | 
				
			||||||
 | 
					    DomainComponent = 16,
 | 
				
			||||||
    NodeId = 17,
 | 
					    NodeId = 17,
 | 
				
			||||||
    FirmwareSignId = 18,
 | 
					    FirmwareSignId = 18,
 | 
				
			||||||
    IcaId = 19,
 | 
					    IcaId = 19,
 | 
				
			||||||
| 
						 | 
					@ -276,11 +292,17 @@ enum DnTags {
 | 
				
			||||||
    NocCat = 22,
 | 
					    NocCat = 22,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum DistNameValue {
 | 
				
			||||||
 | 
					    Uint(u64),
 | 
				
			||||||
 | 
					    Utf8Str(Vec<u8>),
 | 
				
			||||||
 | 
					    PrintableStr(Vec<u8>),
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[derive(Default)]
 | 
					#[derive(Default)]
 | 
				
			||||||
struct DistNames {
 | 
					struct DistNames {
 | 
				
			||||||
    // The order in which the DNs arrive is important, as the signing
 | 
					    // The order in which the DNs arrive is important, as the signing
 | 
				
			||||||
    // requires that the ASN1 notation retains the same order
 | 
					    // requires that the ASN1 notation retains the same order
 | 
				
			||||||
    dn: Vec<(u8, u64)>,
 | 
					    dn: Vec<(u8, DistNameValue)>,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl DistNames {
 | 
					impl DistNames {
 | 
				
			||||||
| 
						 | 
					@ -288,10 +310,18 @@ impl DistNames {
 | 
				
			||||||
        self.dn
 | 
					        self.dn
 | 
				
			||||||
            .iter()
 | 
					            .iter()
 | 
				
			||||||
            .find(|(id, _)| *id == match_id as u8)
 | 
					            .find(|(id, _)| *id == match_id as u8)
 | 
				
			||||||
            .map(|(_, value)| *value)
 | 
					            .and_then(|(_, value)| {
 | 
				
			||||||
 | 
					                if let DistNameValue::Uint(u) = *value {
 | 
				
			||||||
 | 
					                    Some(u)
 | 
				
			||||||
 | 
					                } else {
 | 
				
			||||||
 | 
					                    None
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            })
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const PRINTABLE_STR_THRESHOLD: u8 = 0x80;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl<'a> FromTLV<'a> for DistNames {
 | 
					impl<'a> FromTLV<'a> for DistNames {
 | 
				
			||||||
    fn from_tlv(t: &TLVElement<'a>) -> Result<Self, Error> {
 | 
					    fn from_tlv(t: &TLVElement<'a>) -> Result<Self, Error> {
 | 
				
			||||||
        let mut d = Self {
 | 
					        let mut d = Self {
 | 
				
			||||||
| 
						 | 
					@ -300,12 +330,18 @@ impl<'a> FromTLV<'a> for DistNames {
 | 
				
			||||||
        let iter = t.confirm_list()?.enter().ok_or(Error::Invalid)?;
 | 
					        let iter = t.confirm_list()?.enter().ok_or(Error::Invalid)?;
 | 
				
			||||||
        for t in iter {
 | 
					        for t in iter {
 | 
				
			||||||
            if let TagType::Context(tag) = t.get_tag() {
 | 
					            if let TagType::Context(tag) = t.get_tag() {
 | 
				
			||||||
                let value = t.u64().map_err(|e| {
 | 
					                if let Ok(value) = t.u64() {
 | 
				
			||||||
                    // Non-integer DNs not yet supported
 | 
					                    d.dn.push((tag, DistNameValue::Uint(value)));
 | 
				
			||||||
                    error!("This DN is not yet supported{}", tag);
 | 
					                } else if let Ok(value) = t.slice() {
 | 
				
			||||||
                    e
 | 
					                    if tag > PRINTABLE_STR_THRESHOLD {
 | 
				
			||||||
                })?;
 | 
					                        d.dn.push((
 | 
				
			||||||
                d.dn.push((tag, value));
 | 
					                            tag - PRINTABLE_STR_THRESHOLD,
 | 
				
			||||||
 | 
					                            DistNameValue::PrintableStr(value.to_vec()),
 | 
				
			||||||
 | 
					                        ));
 | 
				
			||||||
 | 
					                    } else {
 | 
				
			||||||
 | 
					                        d.dn.push((tag, DistNameValue::Utf8Str(value.to_vec())));
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        Ok(d)
 | 
					        Ok(d)
 | 
				
			||||||
| 
						 | 
					@ -316,7 +352,14 @@ impl ToTLV for DistNames {
 | 
				
			||||||
    fn to_tlv(&self, tw: &mut TLVWriter, tag: TagType) -> Result<(), Error> {
 | 
					    fn to_tlv(&self, tw: &mut TLVWriter, tag: TagType) -> Result<(), Error> {
 | 
				
			||||||
        tw.start_list(tag)?;
 | 
					        tw.start_list(tag)?;
 | 
				
			||||||
        for (name, value) in &self.dn {
 | 
					        for (name, value) in &self.dn {
 | 
				
			||||||
            tw.u64(TagType::Context(*name), *value)?;
 | 
					            match value {
 | 
				
			||||||
 | 
					                DistNameValue::Uint(v) => tw.u64(TagType::Context(*name), *v)?,
 | 
				
			||||||
 | 
					                DistNameValue::Utf8Str(v) => tw.utf8(TagType::Context(*name), v.as_slice())?,
 | 
				
			||||||
 | 
					                DistNameValue::PrintableStr(v) => tw.utf8(
 | 
				
			||||||
 | 
					                    TagType::Context(*name + PRINTABLE_STR_THRESHOLD),
 | 
				
			||||||
 | 
					                    v.as_slice(),
 | 
				
			||||||
 | 
					                )?,
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        tw.end_container()
 | 
					        tw.end_container()
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					@ -324,43 +367,106 @@ impl ToTLV for DistNames {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl DistNames {
 | 
					impl DistNames {
 | 
				
			||||||
    fn encode(&self, tag: &str, w: &mut dyn CertConsumer) -> Result<(), Error> {
 | 
					    fn encode(&self, tag: &str, w: &mut dyn CertConsumer) -> Result<(), Error> {
 | 
				
			||||||
        const OID_MATTER_NODE_ID: [u8; 10] =
 | 
					        const OID_COMMON_NAME: [u8; 3] = [0x55_u8, 0x04, 0x03];
 | 
				
			||||||
            [0x2B, 0x06, 0x01, 0x04, 0x01, 0x82, 0xA2, 0x7C, 0x01, 0x01];
 | 
					        const OID_SURNAME: [u8; 3] = [0x55_u8, 0x04, 0x04];
 | 
				
			||||||
        const OID_MATTER_FW_SIGN_ID: [u8; 10] =
 | 
					        const OID_SERIAL_NUMBER: [u8; 3] = [0x55_u8, 0x04, 0x05];
 | 
				
			||||||
            [0x2B, 0x06, 0x01, 0x04, 0x01, 0x82, 0xA2, 0x7C, 0x01, 0x02];
 | 
					        const OID_COUNTRY_NAME: [u8; 3] = [0x55_u8, 0x04, 0x06];
 | 
				
			||||||
        const OID_MATTER_ICA_ID: [u8; 10] =
 | 
					        const OID_LOCALITY_NAME: [u8; 3] = [0x55_u8, 0x04, 0x07];
 | 
				
			||||||
            [0x2B, 0x06, 0x01, 0x04, 0x01, 0x82, 0xA2, 0x7C, 0x01, 0x03];
 | 
					        const OID_STATE_NAME: [u8; 3] = [0x55_u8, 0x04, 0x08];
 | 
				
			||||||
        const OID_MATTER_ROOT_CA_ID: [u8; 10] =
 | 
					        const OID_ORGANIZATION_NAME: [u8; 3] = [0x55_u8, 0x04, 0x0A];
 | 
				
			||||||
            [0x2B, 0x06, 0x01, 0x04, 0x01, 0x82, 0xA2, 0x7C, 0x01, 0x04];
 | 
					        const OID_ORGANIZATIONAL_UNIT_NAME: [u8; 3] = [0x55_u8, 0x04, 0x0B];
 | 
				
			||||||
        const OID_MATTER_FABRIC_ID: [u8; 10] =
 | 
					        const OID_TITLE: [u8; 3] = [0x55_u8, 0x04, 0x0C];
 | 
				
			||||||
            [0x2B, 0x06, 0x01, 0x04, 0x01, 0x82, 0xA2, 0x7C, 0x01, 0x05];
 | 
					        const OID_NAME: [u8; 3] = [0x55_u8, 0x04, 0x29];
 | 
				
			||||||
        const OID_MATTER_NOC_CAT_ID: [u8; 10] =
 | 
					        const OID_GIVEN_NAME: [u8; 3] = [0x55_u8, 0x04, 0x2A];
 | 
				
			||||||
            [0x2B, 0x06, 0x01, 0x04, 0x01, 0x82, 0xA2, 0x7C, 0x01, 0x06];
 | 
					        const OID_INITIALS: [u8; 3] = [0x55_u8, 0x04, 0x2B];
 | 
				
			||||||
 | 
					        const OID_GENERATION_QUALIFIER: [u8; 3] = [0x55_u8, 0x04, 0x2C];
 | 
				
			||||||
 | 
					        const OID_DN_QUALIFIER: [u8; 3] = [0x55_u8, 0x04, 0x2E];
 | 
				
			||||||
 | 
					        const OID_PSEUDONYM: [u8; 3] = [0x55_u8, 0x04, 0x41];
 | 
				
			||||||
 | 
					        const OID_DOMAIN_COMPONENT: [u8; 10] = [
 | 
				
			||||||
 | 
					            0x09_u8, 0x92, 0x26, 0x89, 0x93, 0xF2, 0x2C, 0x64, 0x01, 0x19,
 | 
				
			||||||
 | 
					        ];
 | 
				
			||||||
 | 
					        const OID_MATTER_NODE_ID: [u8; 10] = [
 | 
				
			||||||
 | 
					            0x2B_u8, 0x06, 0x01, 0x04, 0x01, 0x82, 0xA2, 0x7C, 0x01, 0x01,
 | 
				
			||||||
 | 
					        ];
 | 
				
			||||||
 | 
					        const OID_MATTER_FW_SIGNING_ID: [u8; 10] = [
 | 
				
			||||||
 | 
					            0x2B_u8, 0x06, 0x01, 0x04, 0x01, 0x82, 0xA2, 0x7C, 0x01, 0x02,
 | 
				
			||||||
 | 
					        ];
 | 
				
			||||||
 | 
					        const OID_MATTER_ICAC_ID: [u8; 10] = [
 | 
				
			||||||
 | 
					            0x2B_u8, 0x06, 0x01, 0x04, 0x01, 0x82, 0xA2, 0x7C, 0x01, 0x03,
 | 
				
			||||||
 | 
					        ];
 | 
				
			||||||
 | 
					        const OID_MATTER_RCAC_ID: [u8; 10] = [
 | 
				
			||||||
 | 
					            0x2B_u8, 0x06, 0x01, 0x04, 0x01, 0x82, 0xA2, 0x7C, 0x01, 0x04,
 | 
				
			||||||
 | 
					        ];
 | 
				
			||||||
 | 
					        const OID_MATTER_FABRIC_ID: [u8; 10] = [
 | 
				
			||||||
 | 
					            0x2B_u8, 0x06, 0x01, 0x04, 0x01, 0x82, 0xA2, 0x7C, 0x01, 0x05,
 | 
				
			||||||
 | 
					        ];
 | 
				
			||||||
 | 
					        const OID_MATTER_CASE_AUTH_TAG: [u8; 10] = [
 | 
				
			||||||
 | 
					            0x2B_u8, 0x06, 0x01, 0x04, 0x01, 0x82, 0xA2, 0x7C, 0x01, 0x06,
 | 
				
			||||||
 | 
					        ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let dn_encoding = [
 | 
					        const DN_ENCODING: [(&str, &[u8], Option<IntToStringLen>); 22] = [
 | 
				
			||||||
            ("Chip Node Id:", &OID_MATTER_NODE_ID),
 | 
					            ("Common Name:", &OID_COMMON_NAME, None),
 | 
				
			||||||
            ("Chip Firmware Signing Id:", &OID_MATTER_FW_SIGN_ID),
 | 
					            ("Surname:", &OID_SURNAME, None),
 | 
				
			||||||
            ("Chip ICA Id:", &OID_MATTER_ICA_ID),
 | 
					            ("Serial Number", &OID_SERIAL_NUMBER, None),
 | 
				
			||||||
            ("Chip Root CA Id:", &OID_MATTER_ROOT_CA_ID),
 | 
					            ("Country Name", &OID_COUNTRY_NAME, None),
 | 
				
			||||||
            ("Chip Fabric Id:", &OID_MATTER_FABRIC_ID),
 | 
					            ("Locality name", &OID_LOCALITY_NAME, None),
 | 
				
			||||||
 | 
					            ("State Name", &OID_STATE_NAME, None),
 | 
				
			||||||
 | 
					            ("Org Name", &OID_ORGANIZATION_NAME, None),
 | 
				
			||||||
 | 
					            ("OU Name", &OID_ORGANIZATIONAL_UNIT_NAME, None),
 | 
				
			||||||
 | 
					            ("Title", &OID_TITLE, None),
 | 
				
			||||||
 | 
					            ("Name", &OID_NAME, None),
 | 
				
			||||||
 | 
					            ("Given Name", &OID_GIVEN_NAME, None),
 | 
				
			||||||
 | 
					            ("Initials", &OID_INITIALS, None),
 | 
				
			||||||
 | 
					            ("Gen Qualifier", &OID_GENERATION_QUALIFIER, None),
 | 
				
			||||||
 | 
					            ("DN Qualifier", &OID_DN_QUALIFIER, None),
 | 
				
			||||||
 | 
					            ("Pseudonym", &OID_PSEUDONYM, None),
 | 
				
			||||||
 | 
					            ("Domain Component", &OID_DOMAIN_COMPONENT, None),
 | 
				
			||||||
 | 
					            (
 | 
				
			||||||
 | 
					                "Chip Node Id:",
 | 
				
			||||||
 | 
					                &OID_MATTER_NODE_ID,
 | 
				
			||||||
 | 
					                Some(IntToStringLen::Len16),
 | 
				
			||||||
 | 
					            ),
 | 
				
			||||||
 | 
					            (
 | 
				
			||||||
 | 
					                "Chip Firmware Signing Id:",
 | 
				
			||||||
 | 
					                &OID_MATTER_FW_SIGNING_ID,
 | 
				
			||||||
 | 
					                Some(IntToStringLen::Len16),
 | 
				
			||||||
 | 
					            ),
 | 
				
			||||||
 | 
					            (
 | 
				
			||||||
 | 
					                "Chip ICA Id:",
 | 
				
			||||||
 | 
					                &OID_MATTER_ICAC_ID,
 | 
				
			||||||
 | 
					                Some(IntToStringLen::Len16),
 | 
				
			||||||
 | 
					            ),
 | 
				
			||||||
 | 
					            (
 | 
				
			||||||
 | 
					                "Chip Root CA Id:",
 | 
				
			||||||
 | 
					                &OID_MATTER_RCAC_ID,
 | 
				
			||||||
 | 
					                Some(IntToStringLen::Len16),
 | 
				
			||||||
 | 
					            ),
 | 
				
			||||||
 | 
					            (
 | 
				
			||||||
 | 
					                "Chip Fabric Id:",
 | 
				
			||||||
 | 
					                &OID_MATTER_FABRIC_ID,
 | 
				
			||||||
 | 
					                Some(IntToStringLen::Len16),
 | 
				
			||||||
 | 
					            ),
 | 
				
			||||||
 | 
					            (
 | 
				
			||||||
 | 
					                "Chip NOC CAT Id:",
 | 
				
			||||||
 | 
					                &OID_MATTER_CASE_AUTH_TAG,
 | 
				
			||||||
 | 
					                Some(IntToStringLen::Len8),
 | 
				
			||||||
 | 
					            ),
 | 
				
			||||||
        ];
 | 
					        ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        w.start_seq(tag)?;
 | 
					        w.start_seq(tag)?;
 | 
				
			||||||
        for (id, value) in &self.dn {
 | 
					        for (id, value) in &self.dn {
 | 
				
			||||||
            if let Ok(tag) = num::FromPrimitive::from_u8(*id).ok_or(Error::InvalidData) {
 | 
					            let tag: Option<DnTags> = num::FromPrimitive::from_u8(*id);
 | 
				
			||||||
                if let DnTags::NocCat = tag {
 | 
					            if tag.is_some() {
 | 
				
			||||||
                    w.start_set("")?;
 | 
					                let index = (id - 1) as usize;
 | 
				
			||||||
                    w.start_seq("")?;
 | 
					                if index <= DN_ENCODING.len() {
 | 
				
			||||||
                    w.oid("Chip NOC CAT Id:", &OID_MATTER_NOC_CAT_ID)?;
 | 
					                    let this = &DN_ENCODING[index];
 | 
				
			||||||
                    w.utf8str("", format!("{:08X}", value).as_str())?;
 | 
					                    encode_dn_value(value, this.0, this.1, w, this.2)?;
 | 
				
			||||||
                    w.end_seq()?;
 | 
					 | 
				
			||||||
                    w.end_set()?;
 | 
					 | 
				
			||||||
                } else {
 | 
					                } else {
 | 
				
			||||||
                    let index: usize = (*id as usize) - (DnTags::NodeId as usize);
 | 
					                    // Non Matter DNs are encoded as
 | 
				
			||||||
                    let this = &dn_encoding[index];
 | 
					                    error!("Invalid DN, too high {}", id);
 | 
				
			||||||
                    encode_u64_dn(*value, this.0, this.1, w)?;
 | 
					 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            } else {
 | 
					            } else {
 | 
				
			||||||
 | 
					                // Non Matter DNs are encoded as
 | 
				
			||||||
                error!("Non Matter DNs are not yet supported {}", id);
 | 
					                error!("Non Matter DNs are not yet supported {}", id);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
| 
						 | 
					@ -369,16 +475,42 @@ impl DistNames {
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
fn encode_u64_dn(
 | 
					#[derive(Copy, Clone)]
 | 
				
			||||||
    value: u64,
 | 
					/// Describes the expected string length while encoding an integer as a string
 | 
				
			||||||
 | 
					enum IntToStringLen {
 | 
				
			||||||
 | 
					    Len16,
 | 
				
			||||||
 | 
					    Len8,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn encode_dn_value(
 | 
				
			||||||
 | 
					    value: &DistNameValue,
 | 
				
			||||||
    name: &str,
 | 
					    name: &str,
 | 
				
			||||||
    oid: &[u8],
 | 
					    oid: &[u8],
 | 
				
			||||||
    w: &mut dyn CertConsumer,
 | 
					    w: &mut dyn CertConsumer,
 | 
				
			||||||
 | 
					    // Only applicable for integer values
 | 
				
			||||||
 | 
					    expected_len: Option<IntToStringLen>,
 | 
				
			||||||
) -> Result<(), Error> {
 | 
					) -> Result<(), Error> {
 | 
				
			||||||
    w.start_set("")?;
 | 
					    w.start_set("")?;
 | 
				
			||||||
    w.start_seq("")?;
 | 
					    w.start_seq("")?;
 | 
				
			||||||
    w.oid(name, oid)?;
 | 
					    w.oid(name, oid)?;
 | 
				
			||||||
    w.utf8str("", format!("{:016X}", value).as_str())?;
 | 
					    match value {
 | 
				
			||||||
 | 
					        DistNameValue::Uint(v) => match expected_len {
 | 
				
			||||||
 | 
					            Some(IntToStringLen::Len16) => w.utf8str("", format!("{:016X}", v).as_str())?,
 | 
				
			||||||
 | 
					            Some(IntToStringLen::Len8) => w.utf8str("", format!("{:08X}", v).as_str())?,
 | 
				
			||||||
 | 
					            _ => {
 | 
				
			||||||
 | 
					                error!("Invalid encoding");
 | 
				
			||||||
 | 
					                return Err(Error::Invalid);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        DistNameValue::Utf8Str(v) => {
 | 
				
			||||||
 | 
					            let str = String::from_utf8(v.to_vec())?;
 | 
				
			||||||
 | 
					            w.utf8str("", &str)?;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        DistNameValue::PrintableStr(v) => {
 | 
				
			||||||
 | 
					            let str = String::from_utf8(v.to_vec())?;
 | 
				
			||||||
 | 
					            w.printstr("", &str)?;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    w.end_seq()?;
 | 
					    w.end_seq()?;
 | 
				
			||||||
    w.end_set()
 | 
					    w.end_set()
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -557,6 +689,7 @@ pub trait CertConsumer {
 | 
				
			||||||
    fn start_seq(&mut self, tag: &str) -> Result<(), Error>;
 | 
					    fn start_seq(&mut self, tag: &str) -> Result<(), Error>;
 | 
				
			||||||
    fn end_seq(&mut self) -> Result<(), Error>;
 | 
					    fn end_seq(&mut self) -> Result<(), Error>;
 | 
				
			||||||
    fn integer(&mut self, tag: &str, i: &[u8]) -> Result<(), Error>;
 | 
					    fn integer(&mut self, tag: &str, i: &[u8]) -> Result<(), Error>;
 | 
				
			||||||
 | 
					    fn printstr(&mut self, tag: &str, s: &str) -> Result<(), Error>;
 | 
				
			||||||
    fn utf8str(&mut self, tag: &str, s: &str) -> Result<(), Error>;
 | 
					    fn utf8str(&mut self, tag: &str, s: &str) -> Result<(), Error>;
 | 
				
			||||||
    fn bitstr(&mut self, tag: &str, truncate: bool, s: &[u8]) -> Result<(), Error>;
 | 
					    fn bitstr(&mut self, tag: &str, truncate: bool, s: &[u8]) -> Result<(), Error>;
 | 
				
			||||||
    fn ostr(&mut self, tag: &str, s: &[u8]) -> Result<(), Error>;
 | 
					    fn ostr(&mut self, tag: &str, s: &[u8]) -> Result<(), Error>;
 | 
				
			||||||
| 
						 | 
					@ -589,17 +722,24 @@ mod tests {
 | 
				
			||||||
    fn test_asn1_encode_success() {
 | 
					    fn test_asn1_encode_success() {
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            let mut asn1_buf = [0u8; 1000];
 | 
					            let mut asn1_buf = [0u8; 1000];
 | 
				
			||||||
            let c = Cert::new(&test_vectors::ASN1_INPUT1).unwrap();
 | 
					            let c = Cert::new(&test_vectors::CHIP_CERT_INPUT1).unwrap();
 | 
				
			||||||
            let len = c.as_asn1(&mut asn1_buf).unwrap();
 | 
					            let len = c.as_asn1(&mut asn1_buf).unwrap();
 | 
				
			||||||
            assert_eq!(&test_vectors::ASN1_OUTPUT1, &asn1_buf[..len]);
 | 
					            assert_eq!(&test_vectors::ASN1_OUTPUT1, &asn1_buf[..len]);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            let mut asn1_buf = [0u8; 1000];
 | 
					            let mut asn1_buf = [0u8; 1000];
 | 
				
			||||||
            let c = Cert::new(&test_vectors::ASN1_INPUT2).unwrap();
 | 
					            let c = Cert::new(&test_vectors::CHIP_CERT_INPUT2).unwrap();
 | 
				
			||||||
            let len = c.as_asn1(&mut asn1_buf).unwrap();
 | 
					            let len = c.as_asn1(&mut asn1_buf).unwrap();
 | 
				
			||||||
            assert_eq!(&test_vectors::ASN1_OUTPUT2, &asn1_buf[..len]);
 | 
					            assert_eq!(&test_vectors::ASN1_OUTPUT2, &asn1_buf[..len]);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            let mut asn1_buf = [0u8; 1000];
 | 
				
			||||||
 | 
					            let c = Cert::new(&test_vectors::CHIP_CERT_TXT_IN_DN).unwrap();
 | 
				
			||||||
 | 
					            let len = c.as_asn1(&mut asn1_buf).unwrap();
 | 
				
			||||||
 | 
					            assert_eq!(&test_vectors::ASN1_OUTPUT_TXT_IN_DN, &asn1_buf[..len]);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    #[test]
 | 
					    #[test]
 | 
				
			||||||
| 
						 | 
					@ -759,7 +899,7 @@ mod tests {
 | 
				
			||||||
            0x93, 0xd3, 0x7c, 0x4, 0x0, 0xe4, 0xc7, 0x78, 0xe9, 0x83, 0x5b, 0xc, 0x33, 0x61, 0x5c,
 | 
					            0x93, 0xd3, 0x7c, 0x4, 0x0, 0xe4, 0xc7, 0x78, 0xe9, 0x83, 0x5b, 0xc, 0x33, 0x61, 0x5c,
 | 
				
			||||||
            0x2e, 0x18,
 | 
					            0x2e, 0x18,
 | 
				
			||||||
        ];
 | 
					        ];
 | 
				
			||||||
        pub const ASN1_INPUT1: [u8; 237] = [
 | 
					        pub const CHIP_CERT_INPUT1: [u8; 237] = [
 | 
				
			||||||
            0x15, 0x30, 0x01, 0x01, 0x00, 0x24, 0x02, 0x01, 0x37, 0x03, 0x24, 0x14, 0x00, 0x24,
 | 
					            0x15, 0x30, 0x01, 0x01, 0x00, 0x24, 0x02, 0x01, 0x37, 0x03, 0x24, 0x14, 0x00, 0x24,
 | 
				
			||||||
            0x15, 0x03, 0x18, 0x26, 0x04, 0x80, 0x22, 0x81, 0x27, 0x26, 0x05, 0x80, 0x25, 0x4d,
 | 
					            0x15, 0x03, 0x18, 0x26, 0x04, 0x80, 0x22, 0x81, 0x27, 0x26, 0x05, 0x80, 0x25, 0x4d,
 | 
				
			||||||
            0x3a, 0x37, 0x06, 0x24, 0x13, 0x01, 0x24, 0x15, 0x03, 0x18, 0x24, 0x07, 0x01, 0x24,
 | 
					            0x3a, 0x37, 0x06, 0x24, 0x13, 0x01, 0x24, 0x15, 0x03, 0x18, 0x24, 0x07, 0x01, 0x24,
 | 
				
			||||||
| 
						 | 
					@ -778,7 +918,7 @@ mod tests {
 | 
				
			||||||
            0xaa, 0xab, 0xa0, 0xdb, 0xb4, 0x79, 0x63, 0xfc, 0x02, 0x03, 0x27, 0x25, 0xac, 0x21,
 | 
					            0xaa, 0xab, 0xa0, 0xdb, 0xb4, 0x79, 0x63, 0xfc, 0x02, 0x03, 0x27, 0x25, 0xac, 0x21,
 | 
				
			||||||
            0x6f, 0xef, 0x27, 0xab, 0x0f, 0x90, 0x09, 0x99, 0x05, 0xa8, 0x60, 0xd8, 0x18,
 | 
					            0x6f, 0xef, 0x27, 0xab, 0x0f, 0x90, 0x09, 0x99, 0x05, 0xa8, 0x60, 0xd8, 0x18,
 | 
				
			||||||
        ];
 | 
					        ];
 | 
				
			||||||
        pub const ASN1_INPUT2: [u8; 247] = [
 | 
					        pub const CHIP_CERT_INPUT2: [u8; 247] = [
 | 
				
			||||||
            0x15, 0x30, 0x01, 0x01, 0x01, 0x24, 0x02, 0x01, 0x37, 0x03, 0x24, 0x13, 0x01, 0x24,
 | 
					            0x15, 0x30, 0x01, 0x01, 0x01, 0x24, 0x02, 0x01, 0x37, 0x03, 0x24, 0x13, 0x01, 0x24,
 | 
				
			||||||
            0x15, 0x03, 0x18, 0x26, 0x04, 0x80, 0x22, 0x81, 0x27, 0x26, 0x05, 0x80, 0x25, 0x4d,
 | 
					            0x15, 0x03, 0x18, 0x26, 0x04, 0x80, 0x22, 0x81, 0x27, 0x26, 0x05, 0x80, 0x25, 0x4d,
 | 
				
			||||||
            0x3a, 0x37, 0x06, 0x26, 0x11, 0x69, 0xb6, 0x01, 0x00, 0x24, 0x15, 0x03, 0x18, 0x24,
 | 
					            0x3a, 0x37, 0x06, 0x26, 0x11, 0x69, 0xb6, 0x01, 0x00, 0x24, 0x15, 0x03, 0x18, 0x24,
 | 
				
			||||||
| 
						 | 
					@ -798,6 +938,29 @@ mod tests {
 | 
				
			||||||
            0xf5, 0x6c, 0x1d, 0x65, 0x6c, 0x0f, 0xd1, 0xe8, 0x55, 0x14, 0x5e, 0x27, 0xfd, 0xa4,
 | 
					            0xf5, 0x6c, 0x1d, 0x65, 0x6c, 0x0f, 0xd1, 0xe8, 0x55, 0x14, 0x5e, 0x27, 0xfd, 0xa4,
 | 
				
			||||||
            0xac, 0xf9, 0x93, 0xdb, 0x29, 0x49, 0xaa, 0x71, 0x18,
 | 
					            0xac, 0xf9, 0x93, 0xdb, 0x29, 0x49, 0xaa, 0x71, 0x18,
 | 
				
			||||||
        ];
 | 
					        ];
 | 
				
			||||||
 | 
					        pub const CHIP_CERT_TXT_IN_DN: [u8; 304] = [
 | 
				
			||||||
 | 
					            0x15, 0x30, 0x1, 0x1, 0x1, 0x24, 0x2, 0x1, 0x37, 0x3, 0x2c, 0x84, 0x2, 0x55, 0x53,
 | 
				
			||||||
 | 
					            0x2c, 0x7, 0x6, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2c, 0x1, 0xb, 0x4d, 0x61, 0x74,
 | 
				
			||||||
 | 
					            0x74, 0x65, 0x72, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x27, 0x14, 0x1, 0x0, 0x0, 0x0, 0xfe,
 | 
				
			||||||
 | 
					            0xff, 0xff, 0xff, 0x18, 0x26, 0x4, 0x7f, 0xd2, 0x43, 0x29, 0x26, 0x5, 0x7f, 0x94, 0x5b,
 | 
				
			||||||
 | 
					            0xe5, 0x37, 0x6, 0x2c, 0x84, 0x2, 0x55, 0x53, 0x2c, 0x7, 0x6, 0x47, 0x6f, 0x6f, 0x67,
 | 
				
			||||||
 | 
					            0x6c, 0x65, 0x2c, 0x1, 0xb, 0x4d, 0x61, 0x74, 0x74, 0x65, 0x72, 0x20, 0x52, 0x6f, 0x6f,
 | 
				
			||||||
 | 
					            0x74, 0x27, 0x14, 0x1, 0x0, 0x0, 0x0, 0xfe, 0xff, 0xff, 0xff, 0x18, 0x24, 0x7, 0x1,
 | 
				
			||||||
 | 
					            0x24, 0x8, 0x1, 0x30, 0x9, 0x41, 0x4, 0x5b, 0x37, 0xdf, 0x65, 0x49, 0xc2, 0xd, 0xc8,
 | 
				
			||||||
 | 
					            0xd7, 0x22, 0xa6, 0xb8, 0xac, 0xb6, 0x60, 0xa8, 0xa7, 0x64, 0xce, 0x7b, 0xaf, 0x6c,
 | 
				
			||||||
 | 
					            0x6c, 0x22, 0x4f, 0x7e, 0xe8, 0x43, 0x49, 0x68, 0x4a, 0xd7, 0xd8, 0x9, 0xff, 0x65, 0x0,
 | 
				
			||||||
 | 
					            0x33, 0xd1, 0x52, 0x7d, 0xcf, 0x1f, 0xba, 0xac, 0x6a, 0x9c, 0x3a, 0xd8, 0xb4, 0x1e,
 | 
				
			||||||
 | 
					            0xda, 0xc9, 0x9, 0xf7, 0xb5, 0xc7, 0x60, 0xfd, 0x54, 0x2c, 0x89, 0x23, 0x75, 0x37, 0xa,
 | 
				
			||||||
 | 
					            0x35, 0x1, 0x29, 0x1, 0x24, 0x2, 0x1, 0x18, 0x24, 0x2, 0x60, 0x30, 0x4, 0x14, 0x72,
 | 
				
			||||||
 | 
					            0xc2, 0x1, 0xf7, 0x57, 0x19, 0x13, 0xb3, 0x48, 0xca, 0x0, 0xca, 0x7b, 0x45, 0xf4, 0x77,
 | 
				
			||||||
 | 
					            0x46, 0x68, 0xc9, 0x7e, 0x30, 0x5, 0x14, 0x72, 0xc2, 0x1, 0xf7, 0x57, 0x19, 0x13, 0xb3,
 | 
				
			||||||
 | 
					            0x48, 0xca, 0x0, 0xca, 0x7b, 0x45, 0xf4, 0x77, 0x46, 0x68, 0xc9, 0x7e, 0x18, 0x30, 0xb,
 | 
				
			||||||
 | 
					            0x40, 0x65, 0x16, 0x4b, 0x16, 0x6a, 0xdf, 0xf1, 0x8c, 0x15, 0x61, 0xa, 0x8c, 0xe9,
 | 
				
			||||||
 | 
					            0x1b, 0xd7, 0x3, 0xe9, 0xc1, 0xf6, 0x77, 0xb7, 0x11, 0xce, 0x13, 0x35, 0x5, 0x15, 0x2d,
 | 
				
			||||||
 | 
					            0xf0, 0xda, 0x15, 0x11, 0x16, 0x75, 0xac, 0x55, 0x91, 0xce, 0xe7, 0x86, 0x85, 0x1c,
 | 
				
			||||||
 | 
					            0xdd, 0x9e, 0xfd, 0xad, 0x29, 0x66, 0x74, 0xbe, 0xbc, 0xb2, 0xa3, 0xa3, 0x20, 0x9b,
 | 
				
			||||||
 | 
					            0xcd, 0xe7, 0xb3, 0x9, 0xdb, 0x55, 0x2c, 0x6f, 0x18,
 | 
				
			||||||
 | 
					        ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        pub const ASN1_OUTPUT1: [u8; 388] = [
 | 
					        pub const ASN1_OUTPUT1: [u8; 388] = [
 | 
				
			||||||
            0x30, 0x82, 0x01, 0x80, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x01, 0x00, 0x30, 0x0a,
 | 
					            0x30, 0x82, 0x01, 0x80, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x01, 0x00, 0x30, 0x0a,
 | 
				
			||||||
| 
						 | 
					@ -862,5 +1025,38 @@ mod tests {
 | 
				
			||||||
            0xbf, 0x68, 0x18, 0x59, 0x7f, 0xf7, 0xe8, 0xaf, 0x88, 0x91, 0x1c, 0x72, 0x32, 0xf7,
 | 
					            0xbf, 0x68, 0x18, 0x59, 0x7f, 0xf7, 0xe8, 0xaf, 0x88, 0x91, 0x1c, 0x72, 0x32, 0xf7,
 | 
				
			||||||
            0x52,
 | 
					            0x52,
 | 
				
			||||||
        ];
 | 
					        ];
 | 
				
			||||||
 | 
					        pub const ASN1_OUTPUT_TXT_IN_DN: [u8; 427] = [
 | 
				
			||||||
 | 
					            0x30, 0x82, 0x01, 0xa7, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x01, 0x01, 0x30, 0x0a,
 | 
				
			||||||
 | 
					            0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x30, 0x56, 0x31, 0x0b,
 | 
				
			||||||
 | 
					            0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x0f, 0x30,
 | 
				
			||||||
 | 
					            0x0d, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x06, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65,
 | 
				
			||||||
 | 
					            0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x0b, 0x4d, 0x61, 0x74,
 | 
				
			||||||
 | 
					            0x74, 0x65, 0x72, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x31, 0x20, 0x30, 0x1e, 0x06, 0x0a,
 | 
				
			||||||
 | 
					            0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0xa2, 0x7c, 0x01, 0x04, 0x0c, 0x10, 0x46, 0x46,
 | 
				
			||||||
 | 
					            0x46, 0x46, 0x46, 0x46, 0x46, 0x45, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x31,
 | 
				
			||||||
 | 
					            0x30, 0x1e, 0x17, 0x0d, 0x32, 0x31, 0x31, 0x32, 0x30, 0x38, 0x32, 0x30, 0x33, 0x30,
 | 
				
			||||||
 | 
					            0x35, 0x35, 0x5a, 0x17, 0x0d, 0x32, 0x31, 0x31, 0x32, 0x30, 0x38, 0x32, 0x30, 0x33,
 | 
				
			||||||
 | 
					            0x30, 0x35, 0x35, 0x5a, 0x30, 0x56, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04,
 | 
				
			||||||
 | 
					            0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x0f, 0x30, 0x0d, 0x06, 0x03, 0x55, 0x04, 0x0a,
 | 
				
			||||||
 | 
					            0x0c, 0x06, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03,
 | 
				
			||||||
 | 
					            0x55, 0x04, 0x03, 0x0c, 0x0b, 0x4d, 0x61, 0x74, 0x74, 0x65, 0x72, 0x20, 0x52, 0x6f,
 | 
				
			||||||
 | 
					            0x6f, 0x74, 0x31, 0x20, 0x30, 0x1e, 0x06, 0x0a, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82,
 | 
				
			||||||
 | 
					            0xa2, 0x7c, 0x01, 0x04, 0x0c, 0x10, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x45,
 | 
				
			||||||
 | 
					            0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x31, 0x30, 0x59, 0x30, 0x13, 0x06, 0x07,
 | 
				
			||||||
 | 
					            0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d,
 | 
				
			||||||
 | 
					            0x03, 0x01, 0x07, 0x03, 0x42, 0x00, 0x04, 0x5b, 0x37, 0xdf, 0x65, 0x49, 0xc2, 0x0d,
 | 
				
			||||||
 | 
					            0xc8, 0xd7, 0x22, 0xa6, 0xb8, 0xac, 0xb6, 0x60, 0xa8, 0xa7, 0x64, 0xce, 0x7b, 0xaf,
 | 
				
			||||||
 | 
					            0x6c, 0x6c, 0x22, 0x4f, 0x7e, 0xe8, 0x43, 0x49, 0x68, 0x4a, 0xd7, 0xd8, 0x09, 0xff,
 | 
				
			||||||
 | 
					            0x65, 0x00, 0x33, 0xd1, 0x52, 0x7d, 0xcf, 0x1f, 0xba, 0xac, 0x6a, 0x9c, 0x3a, 0xd8,
 | 
				
			||||||
 | 
					            0xb4, 0x1e, 0xda, 0xc9, 0x09, 0xf7, 0xb5, 0xc7, 0x60, 0xfd, 0x54, 0x2c, 0x89, 0x23,
 | 
				
			||||||
 | 
					            0x75, 0xa3, 0x66, 0x30, 0x64, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01,
 | 
				
			||||||
 | 
					            0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01, 0x30, 0x0e, 0x06,
 | 
				
			||||||
 | 
					            0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30,
 | 
				
			||||||
 | 
					            0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x72, 0xc2, 0x01, 0xf7,
 | 
				
			||||||
 | 
					            0x57, 0x19, 0x13, 0xb3, 0x48, 0xca, 0x00, 0xca, 0x7b, 0x45, 0xf4, 0x77, 0x46, 0x68,
 | 
				
			||||||
 | 
					            0xc9, 0x7e, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80,
 | 
				
			||||||
 | 
					            0x14, 0x72, 0xc2, 0x01, 0xf7, 0x57, 0x19, 0x13, 0xb3, 0x48, 0xca, 0x00, 0xca, 0x7b,
 | 
				
			||||||
 | 
					            0x45, 0xf4, 0x77, 0x46, 0x68, 0xc9, 0x7e,
 | 
				
			||||||
 | 
					        ];
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -61,6 +61,10 @@ impl<'a, 'b> CertConsumer for CertPrinter<'a, 'b> {
 | 
				
			||||||
        let _ = writeln!(self.f, "{} {} {:x?}", SPACE[self.level], tag, i);
 | 
					        let _ = writeln!(self.f, "{} {} {:x?}", SPACE[self.level], tag, i);
 | 
				
			||||||
        Ok(())
 | 
					        Ok(())
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    fn printstr(&mut self, tag: &str, s: &str) -> Result<(), Error> {
 | 
				
			||||||
 | 
					        let _ = writeln!(self.f, "{} {} {:x?}", SPACE[self.level], tag, s);
 | 
				
			||||||
 | 
					        Ok(())
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    fn utf8str(&mut self, tag: &str, s: &str) -> Result<(), Error> {
 | 
					    fn utf8str(&mut self, tag: &str, s: &str) -> Result<(), Error> {
 | 
				
			||||||
        let _ = writeln!(self.f, "{} {} {:x?}", SPACE[self.level], tag, s);
 | 
					        let _ = writeln!(self.f, "{} {} {:x?}", SPACE[self.level], tag, s);
 | 
				
			||||||
        Ok(())
 | 
					        Ok(())
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -15,7 +15,9 @@
 | 
				
			||||||
 *    limitations under the License.
 | 
					 *    limitations under the License.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use std::{array::TryFromSliceError, fmt, sync::PoisonError, time::SystemTimeError};
 | 
					use std::{
 | 
				
			||||||
 | 
					    array::TryFromSliceError, fmt, string::FromUtf8Error, sync::PoisonError, time::SystemTimeError,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use async_channel::{SendError, TryRecvError};
 | 
					use async_channel::{SendError, TryRecvError};
 | 
				
			||||||
use log::error;
 | 
					use log::error;
 | 
				
			||||||
| 
						 | 
					@ -65,6 +67,7 @@ pub enum Error {
 | 
				
			||||||
    TLVNotFound,
 | 
					    TLVNotFound,
 | 
				
			||||||
    TLVTypeMismatch,
 | 
					    TLVTypeMismatch,
 | 
				
			||||||
    TruncatedPacket,
 | 
					    TruncatedPacket,
 | 
				
			||||||
 | 
					    Utf8Fail,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl From<std::io::Error> for Error {
 | 
					impl From<std::io::Error> for Error {
 | 
				
			||||||
| 
						 | 
					@ -115,6 +118,12 @@ impl<T> From<SendError<T>> for Error {
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl From<FromUtf8Error> for Error {
 | 
				
			||||||
 | 
					    fn from(_e: FromUtf8Error) -> Self {
 | 
				
			||||||
 | 
					        Self::Utf8Fail
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl From<TryRecvError> for Error {
 | 
					impl From<TryRecvError> for Error {
 | 
				
			||||||
    fn from(e: TryRecvError) -> Self {
 | 
					    fn from(e: TryRecvError) -> Self {
 | 
				
			||||||
        error!("Error in channel try_recv {}", e);
 | 
					        error!("Error in channel try_recv {}", e);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -47,7 +47,12 @@ fn main() {
 | 
				
			||||||
        .arg(
 | 
					        .arg(
 | 
				
			||||||
            Arg::with_name("cert")
 | 
					            Arg::with_name("cert")
 | 
				
			||||||
                .long("cert")
 | 
					                .long("cert")
 | 
				
			||||||
                .help("The input is a Matter-encoded Certificate"),
 | 
					                .help("Decode a Matter-encoded Certificate"),
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					        .arg(
 | 
				
			||||||
 | 
					            Arg::with_name("as-asn1")
 | 
				
			||||||
 | 
					                .long("as-asn1")
 | 
				
			||||||
 | 
					                .help("Decode a Matter-encoded Certificate and encode as ASN1"),
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
        .arg(Arg::with_name("tlvs").help("List of TLVs").required(true))
 | 
					        .arg(Arg::with_name("tlvs").help("List of TLVs").required(true))
 | 
				
			||||||
        .get_matches();
 | 
					        .get_matches();
 | 
				
			||||||
| 
						 | 
					@ -88,6 +93,11 @@ fn main() {
 | 
				
			||||||
    if m.is_present("cert") {
 | 
					    if m.is_present("cert") {
 | 
				
			||||||
        let cert = cert::Cert::new(&tlv_list[..index]).unwrap();
 | 
					        let cert = cert::Cert::new(&tlv_list[..index]).unwrap();
 | 
				
			||||||
        println!("{}", cert);
 | 
					        println!("{}", cert);
 | 
				
			||||||
 | 
					    } else if m.is_present("as-asn1") {
 | 
				
			||||||
 | 
					        let mut asn1_cert = [0_u8; 1024];
 | 
				
			||||||
 | 
					        let cert = cert::Cert::new(&tlv_list[..index]).unwrap();
 | 
				
			||||||
 | 
					        let len = cert.as_asn1(&mut asn1_cert).unwrap();
 | 
				
			||||||
 | 
					        println!("{:02x?}", &asn1_cert[..len]);
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
        tlv::print_tlv_list(&tlv_list[..index]);
 | 
					        tlv::print_tlv_list(&tlv_list[..index]);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		
		Reference in a new issue