From a57c0a9c24e5cf297016637a478a066afe16ebf4 Mon Sep 17 00:00:00 2001 From: Carl Wallace Date: Thu, 18 Nov 2021 13:06:34 -0500 Subject: [PATCH 1/7] support context specific fields with default values --- der/derive/src/attributes.rs | 36 ++++++++-- der/derive/src/sequence.rs | 9 +-- der/tests/derive.rs | 132 +++++++++++++++++++++++++++++++++++ 3 files changed, 167 insertions(+), 10 deletions(-) diff --git a/der/derive/src/attributes.rs b/der/derive/src/attributes.rs index be0bc4bee..44cd79248 100644 --- a/der/derive/src/attributes.rs +++ b/der/derive/src/attributes.rs @@ -62,6 +62,9 @@ pub(crate) struct FieldAttrs { /// Value of the `#[asn1(context_specific = "...")] attribute if provided. pub context_specific: Option, + /// Indicates if decoding should be deferred + pub defer: Option, + /// Indicates name of function that supplies the default value, which will be used in cases /// where encoding is omitted per DER and to omit the encoding per DER pub default: Option, @@ -85,6 +88,8 @@ impl FieldAttrs { pub fn parse(attrs: &[Attribute], type_attrs: &TypeAttrs) -> Self { let mut asn1_type = None; let mut context_specific = None; + + let mut defer = None; let mut default = None; let mut extensible = None; let mut optional = None; @@ -111,6 +116,12 @@ impl FieldAttrs { abort!(attr.value, "error parsing ASN.1 `default` attribute: {}", e) })); // `extensible` attribute + } else if let Some(defer_attr) = attr.parse_value("defer") { + if defer.is_some() { + panic!("duplicate ASN.1 `defer` attribute"); + } + + defer = Some(defer_attr); } else if let Some(ext) = attr.parse_value("extensible") { if extensible.is_some() { abort!(attr.name, "duplicate ASN.1 `extensible` attribute"); @@ -150,6 +161,7 @@ impl FieldAttrs { Self { asn1_type, context_specific, + defer, default, extensible: extensible.unwrap_or_default(), optional: optional.unwrap_or_default(), @@ -184,7 +196,7 @@ impl FieldAttrs { let context_specific = match self.tag_mode { TagMode::Explicit => { - if self.extensible || self.optional { + if self.extensible || self.optional || self.default.is_some() { quote! { ::der::asn1::ContextSpecific::<#type_params>::decode_explicit( decoder, @@ -210,8 +222,12 @@ impl FieldAttrs { } }; - if self.optional { - quote!(#context_specific.map(|cs| cs.value)) + if self.optional || self.default.is_some() { + if let Some(default) = &self.default { + quote!(#context_specific.map(|cs| cs.value).unwrap_or_else(#default)) + } else { + quote!(#context_specific.map(|cs| cs.value)) + } } else { // TODO(tarcieri): better error handling? quote! { @@ -224,9 +240,17 @@ impl FieldAttrs { } } } else { - self.asn1_type - .map(|ty| ty.decoder()) - .unwrap_or_else(|| quote!(decoder.decode()?)) + if let Some(default) = &self.default { + let type_params = self.asn1_type.map(|ty| ty.type_path()).unwrap_or_default(); + self.asn1_type + .map(|ty| ty.decoder()) + .unwrap_or_else(|| quote!(decoder.decode::>()?.unwrap_or_else(#default))) + } + else { + self.asn1_type + .map(|ty| ty.decoder()) + .unwrap_or_else(|| quote!(decoder.decode()?)) + } } } diff --git a/der/derive/src/sequence.rs b/der/derive/src/sequence.rs index 3dee77b51..3d3a5ff5f 100644 --- a/der/derive/src/sequence.rs +++ b/der/derive/src/sequence.rs @@ -165,10 +165,11 @@ impl SequenceField { let #ident = #decoder.try_into()?; } } - } else if let Some(default) = &self.attrs.default { - quote! { - let #ident = decoder.decode::>()?.unwrap_or_else(#default); - } + } else if self.attrs.context_specific.is_none() && self.attrs.default.is_some() { + let default = &self.attrs.default; + quote! { + let #ident = decoder.decode::>()?.unwrap_or_else(#default); + } } else { quote! { let #ident = #decoder; diff --git a/der/tests/derive.rs b/der/tests/derive.rs index 18105b958..034561ec7 100644 --- a/der/tests/derive.rs +++ b/der/tests/derive.rs @@ -206,6 +206,84 @@ mod sequence { }; use hex_literal::hex; + pub fn default_false_example() -> bool { + false + } + + // Issuing distribution point extension as defined in [RFC 5280 Section 5.2.5] and as identified by the [`PKIX_PE_SUBJECTINFOACCESS`](constant.PKIX_PE_SUBJECTINFOACCESS.html) OID. + // + // ```text + // IssuingDistributionPoint ::= SEQUENCE { + // distributionPoint [0] DistributionPointName OPTIONAL, + // onlyContainsUserCerts [1] BOOLEAN DEFAULT FALSE, + // onlyContainsCACerts [2] BOOLEAN DEFAULT FALSE, + // onlySomeReasons [3] ReasonFlags OPTIONAL, + // indirectCRL [4] BOOLEAN DEFAULT FALSE, + // onlyContainsAttributeCerts [5] BOOLEAN DEFAULT FALSE } + // -- at most one of onlyContainsUserCerts, onlyContainsCACerts, + // -- and onlyContainsAttributeCerts may be set to TRUE. + // ``` + // + // [RFC 5280 Section 5.2.5]: https://datatracker.ietf.org/doc/html/rfc5280#section-5.2.5 + #[derive(Sequence)] + pub struct IssuingDistributionPointExample { + // Omit distributionPoint and only_some_reasons because corresponding structs are not + // available here and are not germane to the example + // distributionPoint [0] DistributionPointName OPTIONAL, + //#[asn1(context_specific="0", optional="true", tag_mode="IMPLICIT")] + //pub distribution_point: Option>, + + /// onlyContainsUserCerts [1] BOOLEAN DEFAULT FALSE, + #[asn1(context_specific="1", default="default_false_example", tag_mode="IMPLICIT")] + pub only_contains_user_certs: bool, + + /// onlyContainsCACerts [2] BOOLEAN DEFAULT FALSE, + #[asn1(context_specific="2", default="default_false_example", tag_mode="IMPLICIT")] + pub only_contains_cacerts: bool, + + // onlySomeReasons [3] ReasonFlags OPTIONAL, + //#[asn1(context_specific="3", optional="true", tag_mode="IMPLICIT")] + //pub only_some_reasons: Option>, + + /// indirectCRL [4] BOOLEAN DEFAULT FALSE, + #[asn1(context_specific="4", default="default_false_example", tag_mode="IMPLICIT")] + pub indirect_crl: bool, + + /// onlyContainsAttributeCerts [5] BOOLEAN DEFAULT FALSE + #[asn1(context_specific="5", default="default_false_example", tag_mode="IMPLICIT")] + pub only_contains_attribute_certs: bool, + } + + // Extension as defined in [RFC 5280 Section 4.1.2.9]. + // + // The ASN.1 definition for Extension objects is below. The extnValue type may be further parsed using a decoder corresponding to the extnID value. + // + // ```text + // Extension ::= SEQUENCE { + // extnID OBJECT IDENTIFIER, + // critical BOOLEAN DEFAULT FALSE, + // extnValue OCTET STRING + // -- contains the DER encoding of an ASN.1 value + // -- corresponding to the extension type identified + // -- by extnID + // } + // ``` + // + // [RFC 5280 Section 4.1.2.9]: https://datatracker.ietf.org/doc/html/rfc5280#section-4.1.2.9 + #[derive(Clone, Debug, Eq, PartialEq, Sequence)] + pub struct ExtensionExample<'a> { + /// extnID OBJECT IDENTIFIER, + pub extn_id: ObjectIdentifier, + + /// critical BOOLEAN DEFAULT FALSE, + #[asn1(default = "default_false_example")] + pub critical: bool, + + /// extnValue OCTET STRING + #[asn1(type = "OCTET STRING")] + pub extn_value: &'a [u8], + } + /// X.509 `AlgorithmIdentifier` #[derive(Copy, Clone, Debug, Eq, PartialEq, Sequence, ValueOrd)] pub struct AlgorithmIdentifier<'a> { @@ -261,6 +339,60 @@ mod sequence { const ALGORITHM_IDENTIFIER_DER: &[u8] = &hex!("30 13 06 07 2a 86 48 ce 3d 02 01 06 08 2a 86 48 ce 3d 03 01 07"); + #[test] + fn idp_test() { + let idp = IssuingDistributionPointExample::from_der(&hex!("30038101FF")).unwrap(); + assert_eq!(idp.only_contains_user_certs, true); + assert_eq!(idp.only_contains_cacerts, false); + assert_eq!(idp.indirect_crl, false); + assert_eq!(idp.only_contains_attribute_certs, false); + + let idp = IssuingDistributionPointExample::from_der(&hex!("30038201FF")).unwrap(); + assert_eq!(idp.only_contains_user_certs, false); + assert_eq!(idp.only_contains_cacerts, true); + assert_eq!(idp.indirect_crl, false); + assert_eq!(idp.only_contains_attribute_certs, false); + + let idp = IssuingDistributionPointExample::from_der(&hex!("30038401FF")).unwrap(); + assert_eq!(idp.only_contains_user_certs, false); + assert_eq!(idp.only_contains_cacerts, false); + assert_eq!(idp.indirect_crl, true); + assert_eq!(idp.only_contains_attribute_certs, false); + + let idp = IssuingDistributionPointExample::from_der(&hex!("30038501FF")).unwrap(); + assert_eq!(idp.only_contains_user_certs, false); + assert_eq!(idp.only_contains_cacerts, false); + assert_eq!(idp.indirect_crl, false); + assert_eq!(idp.only_contains_attribute_certs, true); + } + + // demonstrates default field that is not context specific + #[test] + fn extension_test() { + // 0 15: SEQUENCE { + // 2 3: OBJECT IDENTIFIER basicConstraints (2 5 29 19) + // 7 1: BOOLEAN TRUE + // 10 5: OCTET STRING, encapsulates { + // 12 3: SEQUENCE { + // 14 1: BOOLEAN TRUE + // : } + // : } + // : } + let ext1 = ExtensionExample::from_der(&hex!("300F0603551D130101FF040530030101FF")).unwrap(); + assert_eq!(ext1.critical, true); + + // 0 31: SEQUENCE { + // 2 3: OBJECT IDENTIFIER authorityKeyIdentifier (2 5 29 35) + // 7 24: OCTET STRING, encapsulates { + // 9 22: SEQUENCE { + // 11 20: [0] E4 7D 5F D1 5C 95 86 08 2C 05 AE BE 75 B6 65 A7 D9 5D A8 66 + // : } + // : } + // : } + let ext2 = ExtensionExample::from_der(&hex!("301F0603551D23041830168014E47D5FD15C9586082C05AEBE75B665A7D95DA866")).unwrap(); + assert_eq!(ext2.critical, false); + } + #[test] fn decode() { let algorithm_identifier = From 29b386e435108d92e19777504f7347af70453a53 Mon Sep 17 00:00:00 2001 From: Carl Wallace Date: Thu, 18 Nov 2021 13:08:28 -0500 Subject: [PATCH 2/7] remove defer support --- der/derive/src/attributes.rs | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/der/derive/src/attributes.rs b/der/derive/src/attributes.rs index 44cd79248..1b62d2d77 100644 --- a/der/derive/src/attributes.rs +++ b/der/derive/src/attributes.rs @@ -62,9 +62,6 @@ pub(crate) struct FieldAttrs { /// Value of the `#[asn1(context_specific = "...")] attribute if provided. pub context_specific: Option, - /// Indicates if decoding should be deferred - pub defer: Option, - /// Indicates name of function that supplies the default value, which will be used in cases /// where encoding is omitted per DER and to omit the encoding per DER pub default: Option, @@ -89,7 +86,6 @@ impl FieldAttrs { let mut asn1_type = None; let mut context_specific = None; - let mut defer = None; let mut default = None; let mut extensible = None; let mut optional = None; @@ -116,12 +112,6 @@ impl FieldAttrs { abort!(attr.value, "error parsing ASN.1 `default` attribute: {}", e) })); // `extensible` attribute - } else if let Some(defer_attr) = attr.parse_value("defer") { - if defer.is_some() { - panic!("duplicate ASN.1 `defer` attribute"); - } - - defer = Some(defer_attr); } else if let Some(ext) = attr.parse_value("extensible") { if extensible.is_some() { abort!(attr.name, "duplicate ASN.1 `extensible` attribute"); @@ -161,7 +151,6 @@ impl FieldAttrs { Self { asn1_type, context_specific, - defer, default, extensible: extensible.unwrap_or_default(), optional: optional.unwrap_or_default(), From d61dc70f445b2325af811cb1be21a403958ad8dd Mon Sep 17 00:00:00 2001 From: Carl Wallace Date: Fri, 19 Nov 2021 07:43:49 -0500 Subject: [PATCH 3/7] rustfmt --- der/derive/src/attributes.rs | 9 ++++----- der/derive/src/sequence.rs | 6 +++--- der/tests/derive.rs | 31 ++++++++++++++++++++++++------- 3 files changed, 31 insertions(+), 15 deletions(-) diff --git a/der/derive/src/attributes.rs b/der/derive/src/attributes.rs index 1b62d2d77..a915e7e1b 100644 --- a/der/derive/src/attributes.rs +++ b/der/derive/src/attributes.rs @@ -231,11 +231,10 @@ impl FieldAttrs { } else { if let Some(default) = &self.default { let type_params = self.asn1_type.map(|ty| ty.type_path()).unwrap_or_default(); - self.asn1_type - .map(|ty| ty.decoder()) - .unwrap_or_else(|| quote!(decoder.decode::>()?.unwrap_or_else(#default))) - } - else { + self.asn1_type.map(|ty| ty.decoder()).unwrap_or_else( + || quote!(decoder.decode::>()?.unwrap_or_else(#default)), + ) + } else { self.asn1_type .map(|ty| ty.decoder()) .unwrap_or_else(|| quote!(decoder.decode()?)) diff --git a/der/derive/src/sequence.rs b/der/derive/src/sequence.rs index 3d3a5ff5f..9393b2f5c 100644 --- a/der/derive/src/sequence.rs +++ b/der/derive/src/sequence.rs @@ -167,9 +167,9 @@ impl SequenceField { } } else if self.attrs.context_specific.is_none() && self.attrs.default.is_some() { let default = &self.attrs.default; - quote! { - let #ident = decoder.decode::>()?.unwrap_or_else(#default); - } + quote! { + let #ident = decoder.decode::>()?.unwrap_or_else(#default); + } } else { quote! { let #ident = #decoder; diff --git a/der/tests/derive.rs b/der/tests/derive.rs index 034561ec7..28f647d67 100644 --- a/der/tests/derive.rs +++ b/der/tests/derive.rs @@ -232,25 +232,39 @@ mod sequence { // distributionPoint [0] DistributionPointName OPTIONAL, //#[asn1(context_specific="0", optional="true", tag_mode="IMPLICIT")] //pub distribution_point: Option>, - /// onlyContainsUserCerts [1] BOOLEAN DEFAULT FALSE, - #[asn1(context_specific="1", default="default_false_example", tag_mode="IMPLICIT")] + #[asn1( + context_specific = "1", + default = "default_false_example", + tag_mode = "IMPLICIT" + )] pub only_contains_user_certs: bool, /// onlyContainsCACerts [2] BOOLEAN DEFAULT FALSE, - #[asn1(context_specific="2", default="default_false_example", tag_mode="IMPLICIT")] + #[asn1( + context_specific = "2", + default = "default_false_example", + tag_mode = "IMPLICIT" + )] pub only_contains_cacerts: bool, // onlySomeReasons [3] ReasonFlags OPTIONAL, //#[asn1(context_specific="3", optional="true", tag_mode="IMPLICIT")] //pub only_some_reasons: Option>, - /// indirectCRL [4] BOOLEAN DEFAULT FALSE, - #[asn1(context_specific="4", default="default_false_example", tag_mode="IMPLICIT")] + #[asn1( + context_specific = "4", + default = "default_false_example", + tag_mode = "IMPLICIT" + )] pub indirect_crl: bool, /// onlyContainsAttributeCerts [5] BOOLEAN DEFAULT FALSE - #[asn1(context_specific="5", default="default_false_example", tag_mode="IMPLICIT")] + #[asn1( + context_specific = "5", + default = "default_false_example", + tag_mode = "IMPLICIT" + )] pub only_contains_attribute_certs: bool, } @@ -389,7 +403,10 @@ mod sequence { // : } // : } // : } - let ext2 = ExtensionExample::from_der(&hex!("301F0603551D23041830168014E47D5FD15C9586082C05AEBE75B665A7D95DA866")).unwrap(); + let ext2 = ExtensionExample::from_der(&hex!( + "301F0603551D23041830168014E47D5FD15C9586082C05AEBE75B665A7D95DA866" + )) + .unwrap(); assert_eq!(ext2.critical, false); } From c2f848b7d8ff5dbe91239c31fbf88c2b5e7ef0af Mon Sep 17 00:00:00 2001 From: Carl Wallace Date: Fri, 19 Nov 2021 08:19:50 -0500 Subject: [PATCH 4/7] refactor optional and default variable checks to is_optional check. use hex literal comment feature to place dumpasn1-generated description inline in test cases. --- der/derive/src/attributes.rs | 10 ++++++++-- der/tests/derive.rs | 36 +++++++++++++++--------------------- 2 files changed, 23 insertions(+), 23 deletions(-) diff --git a/der/derive/src/attributes.rs b/der/derive/src/attributes.rs index a915e7e1b..0ecfd688b 100644 --- a/der/derive/src/attributes.rs +++ b/der/derive/src/attributes.rs @@ -81,6 +81,12 @@ pub(crate) struct FieldAttrs { } impl FieldAttrs { + /// is_optional return true when either an optional or default ASN.1 attribute is associated + /// with a field. Default signifies optionality due to omission of default values in DER encodings. + fn is_optional(&self) -> bool { + return self.optional || self.default.is_some(); + } + /// Parse attributes from a struct field or enum variant. pub fn parse(attrs: &[Attribute], type_attrs: &TypeAttrs) -> Self { let mut asn1_type = None; @@ -185,7 +191,7 @@ impl FieldAttrs { let context_specific = match self.tag_mode { TagMode::Explicit => { - if self.extensible || self.optional || self.default.is_some() { + if self.extensible || self.is_optional() { quote! { ::der::asn1::ContextSpecific::<#type_params>::decode_explicit( decoder, @@ -211,7 +217,7 @@ impl FieldAttrs { } }; - if self.optional || self.default.is_some() { + if self.is_optional() { if let Some(default) = &self.default { quote!(#context_specific.map(|cs| cs.value).unwrap_or_else(#default)) } else { diff --git a/der/tests/derive.rs b/der/tests/derive.rs index 28f647d67..0d6686811 100644 --- a/der/tests/derive.rs +++ b/der/tests/derive.rs @@ -383,29 +383,23 @@ mod sequence { // demonstrates default field that is not context specific #[test] fn extension_test() { - // 0 15: SEQUENCE { - // 2 3: OBJECT IDENTIFIER basicConstraints (2 5 29 19) - // 7 1: BOOLEAN TRUE - // 10 5: OCTET STRING, encapsulates { - // 12 3: SEQUENCE { - // 14 1: BOOLEAN TRUE - // : } - // : } - // : } - let ext1 = ExtensionExample::from_der(&hex!("300F0603551D130101FF040530030101FF")).unwrap(); + let ext1 = ExtensionExample::from_der(&hex!(" + 300F // 0 15: SEQUENCE { + 0603551D13 // 2 3: OBJECT IDENTIFIER basicConstraints (2 5 29 19) + 0101FF // 7 1: BOOLEAN TRUE + 0405 // 10 5: OCTET STRING, encapsulates { + 3003 // 12 3: SEQUENCE { + 0101FF // 14 1: BOOLEAN TRUE + ")).unwrap(); assert_eq!(ext1.critical, true); - // 0 31: SEQUENCE { - // 2 3: OBJECT IDENTIFIER authorityKeyIdentifier (2 5 29 35) - // 7 24: OCTET STRING, encapsulates { - // 9 22: SEQUENCE { - // 11 20: [0] E4 7D 5F D1 5C 95 86 08 2C 05 AE BE 75 B6 65 A7 D9 5D A8 66 - // : } - // : } - // : } - let ext2 = ExtensionExample::from_der(&hex!( - "301F0603551D23041830168014E47D5FD15C9586082C05AEBE75B665A7D95DA866" - )) + let ext2 = ExtensionExample::from_der(&hex!(" + 301F // 0 31: SEQUENCE { + 0603551D23 // 2 3: OBJECT IDENTIFIER authorityKeyIdentifier (2 5 29 35) + 0418 // 7 24: OCTET STRING, encapsulates { + 3016 // 9 22: SEQUENCE { + 8014E47D5FD15C9586082C05AEBE75B665A7D95DA866 // 11 20: [0] E4 7D 5F D1 5C 95 86 08 2C 05 AE BE 75 B6 65 A7 D9 5D A8 66 + ")) .unwrap(); assert_eq!(ext2.critical, false); } From 1f039b5e713e0a4699321507531c2079ec7a5cbc Mon Sep 17 00:00:00 2001 From: Carl Wallace Date: Fri, 19 Nov 2021 08:42:44 -0500 Subject: [PATCH 5/7] refactor else block per clippy. rustfmt. --- der/derive/src/attributes.rs | 18 ++++++++---------- der/tests/derive.rs | 7 +++++-- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/der/derive/src/attributes.rs b/der/derive/src/attributes.rs index 0ecfd688b..3bc005732 100644 --- a/der/derive/src/attributes.rs +++ b/der/derive/src/attributes.rs @@ -234,17 +234,15 @@ impl FieldAttrs { })?.value } } + } else if let Some(default) = &self.default { + let type_params = self.asn1_type.map(|ty| ty.type_path()).unwrap_or_default(); + self.asn1_type.map(|ty| ty.decoder()).unwrap_or_else( + || quote!(decoder.decode::>()?.unwrap_or_else(#default)), + ) } else { - if let Some(default) = &self.default { - let type_params = self.asn1_type.map(|ty| ty.type_path()).unwrap_or_default(); - self.asn1_type.map(|ty| ty.decoder()).unwrap_or_else( - || quote!(decoder.decode::>()?.unwrap_or_else(#default)), - ) - } else { - self.asn1_type - .map(|ty| ty.decoder()) - .unwrap_or_else(|| quote!(decoder.decode()?)) - } + self.asn1_type + .map(|ty| ty.decoder()) + .unwrap_or_else(|| quote!(decoder.decode()?)) } } diff --git a/der/tests/derive.rs b/der/tests/derive.rs index 0d6686811..2d6f0a694 100644 --- a/der/tests/derive.rs +++ b/der/tests/derive.rs @@ -383,14 +383,17 @@ mod sequence { // demonstrates default field that is not context specific #[test] fn extension_test() { - let ext1 = ExtensionExample::from_der(&hex!(" + let ext1 = ExtensionExample::from_der(&hex!( + " 300F // 0 15: SEQUENCE { 0603551D13 // 2 3: OBJECT IDENTIFIER basicConstraints (2 5 29 19) 0101FF // 7 1: BOOLEAN TRUE 0405 // 10 5: OCTET STRING, encapsulates { 3003 // 12 3: SEQUENCE { 0101FF // 14 1: BOOLEAN TRUE - ")).unwrap(); + " + )) + .unwrap(); assert_eq!(ext1.critical, true); let ext2 = ExtensionExample::from_der(&hex!(" From e2867bfc5efdcbf198832b6296faf84c11ff3a26 Mon Sep 17 00:00:00 2001 From: Carl Wallace Date: Fri, 19 Nov 2021 08:48:18 -0500 Subject: [PATCH 6/7] remove spurious return --- der/derive/src/attributes.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/der/derive/src/attributes.rs b/der/derive/src/attributes.rs index 3bc005732..cd92e0cb6 100644 --- a/der/derive/src/attributes.rs +++ b/der/derive/src/attributes.rs @@ -84,7 +84,7 @@ impl FieldAttrs { /// is_optional return true when either an optional or default ASN.1 attribute is associated /// with a field. Default signifies optionality due to omission of default values in DER encodings. fn is_optional(&self) -> bool { - return self.optional || self.default.is_some(); + self.optional || self.default.is_some() } /// Parse attributes from a struct field or enum variant. From fe65b1f46f28aa10b10c0a9cf19c590137cb3d15 Mon Sep 17 00:00:00 2001 From: Carl Wallace Date: Fri, 19 Nov 2021 11:26:52 -0500 Subject: [PATCH 7/7] make indentation in test case consistent --- der/tests/derive.rs | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/der/tests/derive.rs b/der/tests/derive.rs index 2d6f0a694..4f3a4c24f 100644 --- a/der/tests/derive.rs +++ b/der/tests/derive.rs @@ -385,24 +385,26 @@ mod sequence { fn extension_test() { let ext1 = ExtensionExample::from_der(&hex!( " - 300F // 0 15: SEQUENCE { - 0603551D13 // 2 3: OBJECT IDENTIFIER basicConstraints (2 5 29 19) - 0101FF // 7 1: BOOLEAN TRUE - 0405 // 10 5: OCTET STRING, encapsulates { - 3003 // 12 3: SEQUENCE { - 0101FF // 14 1: BOOLEAN TRUE - " + 300F // 0 15: SEQUENCE { + 0603551D13 // 2 3: OBJECT IDENTIFIER basicConstraints (2 5 29 19) + 0101FF // 7 1: BOOLEAN TRUE + 0405 // 10 5: OCTET STRING, encapsulates { + 3003 // 12 3: SEQUENCE { + 0101FF // 14 1: BOOLEAN TRUE + " )) .unwrap(); assert_eq!(ext1.critical, true); - let ext2 = ExtensionExample::from_der(&hex!(" - 301F // 0 31: SEQUENCE { - 0603551D23 // 2 3: OBJECT IDENTIFIER authorityKeyIdentifier (2 5 29 35) - 0418 // 7 24: OCTET STRING, encapsulates { - 3016 // 9 22: SEQUENCE { - 8014E47D5FD15C9586082C05AEBE75B665A7D95DA866 // 11 20: [0] E4 7D 5F D1 5C 95 86 08 2C 05 AE BE 75 B6 65 A7 D9 5D A8 66 - ")) + let ext2 = ExtensionExample::from_der(&hex!( + " + 301F // 0 31: SEQUENCE { + 0603551D23 // 2 3: OBJECT IDENTIFIER authorityKeyIdentifier (2 5 29 35) + 0418 // 7 24: OCTET STRING, encapsulates { + 3016 // 9 22: SEQUENCE { + 8014E47D5FD15C9586082C05AEBE75B665A7D95DA866 // 11 20: [0] E4 7D 5F D1 5C 95 86 08 2C 05 AE BE 75 B6 65 A7 D9 5D A8 66 + " + )) .unwrap(); assert_eq!(ext2.critical, false); }