From 814aff1dec125a36bf33214162b501dbb597abba Mon Sep 17 00:00:00 2001 From: Bertrand Roussel Date: Wed, 16 Oct 2024 14:02:05 -0700 Subject: [PATCH 1/4] Add name_contraints access from X509Ref --- openssl-sys/CHANGELOG.md | 4 ++ openssl-sys/src/handwritten/x509v3.rs | 24 ++++++++++ openssl/CHANGELOG.md | 4 ++ openssl/src/x509/mod.rs | 64 +++++++++++++++++++++++++++ openssl/src/x509/tests.rs | 33 ++++++++++++++ openssl/test/name_constraints.pem | 31 +++++++++++++ 6 files changed, 160 insertions(+) create mode 100644 openssl/test/name_constraints.pem diff --git a/openssl-sys/CHANGELOG.md b/openssl-sys/CHANGELOG.md index 641f0d4b7a..4b08965a84 100644 --- a/openssl-sys/CHANGELOG.md +++ b/openssl-sys/CHANGELOG.md @@ -2,6 +2,10 @@ ## [Unreleased] +### Added + +* Added `NAME_CONSTRAINTS`, `GENERAL_SUBTREE`, `stack_st_GENERAL_SUBTREE` + ## [v0.9.104] - 2024-10-15 ### Added diff --git a/openssl-sys/src/handwritten/x509v3.rs b/openssl-sys/src/handwritten/x509v3.rs index 1a548c0e25..09f5045144 100644 --- a/openssl-sys/src/handwritten/x509v3.rs +++ b/openssl-sys/src/handwritten/x509v3.rs @@ -165,3 +165,27 @@ extern "C" { pub fn X509_check_ip(x: *mut X509, chk: *const c_uchar, chklen: usize, flags: c_uint) -> c_int; pub fn X509_check_ip_asc(x: *mut X509, ipasc: *const c_char, flags: c_uint) -> c_int; } + +#[repr(C)] +pub struct GENERAL_SUBTREE { + pub base: *mut GENERAL_NAME, + pub minimum: *mut ASN1_INTEGER, + pub maximum: *mut ASN1_INTEGER, +} + +extern "C" { + pub fn GENERAL_SUBTREE_new() -> *mut GENERAL_SUBTREE; + pub fn GENERAL_SUBTREE_free(name: *mut GENERAL_SUBTREE); +} + +stack!(stack_st_GENERAL_SUBTREE); + +#[repr(C)] +pub struct NAME_CONSTRAINTS { + pub permitted: *mut stack_st_GENERAL_SUBTREE, + pub excluded: *mut stack_st_GENERAL_SUBTREE, +} + +extern "C" { + pub fn NAME_CONSTRAINTS_free(nc: *mut NAME_CONSTRAINTS); +} \ No newline at end of file diff --git a/openssl/CHANGELOG.md b/openssl/CHANGELOG.md index 259614ceea..85e65d9735 100644 --- a/openssl/CHANGELOG.md +++ b/openssl/CHANGELOG.md @@ -2,6 +2,10 @@ ## [Unreleased] +### Added + +- Added `X509Ref::name_constraints` + ## [v0.10.67] - 2024-10-15 ### Added diff --git a/openssl/src/x509/mod.rs b/openssl/src/x509/mod.rs index 67c86ee3d4..047dc85bf2 100644 --- a/openssl/src/x509/mod.rs +++ b/openssl/src/x509/mod.rs @@ -477,6 +477,22 @@ impl X509Ref { } } + /// Returns this certificate's [`name constraints`] entry, if it exists. + /// + /// [`name constraints`]: https://tools.ietf.org/html/rfc5280#section-4.2.1.10 + #[corresponds(X509_get_ext_d2i)] + pub fn name_constraints(&self) -> Option<&NameConstraintsRef> { + unsafe { + let ext = ffi::X509_get_ext_d2i( + self.as_ptr(), + ffi::NID_name_constraints, + ptr::null_mut(), + ptr::null_mut(), + ); + NameConstraintsRef::from_const_ptr_opt(ext as *mut _) + } + } + /// Retrieves the path length extension from a certificate, if it exists. #[corresponds(X509_get_pathlen)] #[cfg(any(ossl110, boringssl))] @@ -2261,6 +2277,54 @@ impl Stackable for AccessDescription { type StackType = ffi::stack_st_ACCESS_DESCRIPTION; } +foreign_type_and_impl_send_sync! { + type CType = ffi::GENERAL_SUBTREE; + fn drop = ffi::GENERAL_SUBTREE_free; + + /// An `X509` subtree. + pub struct GeneralSubtree; + /// Reference to `GeneralSubtree`. + pub struct GeneralSubtreeRef; +} + +impl Stackable for GeneralSubtree { + type StackType = ffi::stack_st_GENERAL_SUBTREE; +} + +impl GeneralSubtreeRef { + pub fn base(&self) -> &GeneralNameRef { + unsafe { GeneralNameRef::from_ptr((*self.as_ptr()).base) } + } + + pub fn minimum(&self) -> Option<&Asn1IntegerRef> { + unsafe { Asn1IntegerRef::from_const_ptr_opt((*self.as_ptr()).minimum) } + } + + pub fn maximum(&self) -> Option<&Asn1IntegerRef> { + unsafe { Asn1IntegerRef::from_const_ptr_opt((*self.as_ptr()).maximum) } + } +} + +foreign_type_and_impl_send_sync! { + type CType = ffi::NAME_CONSTRAINTS; + fn drop = ffi::NAME_CONSTRAINTS_free; + + /// `NameConstraints` of certificate authority information. + pub struct NameConstraints; + /// Reference to `NameConstraints`. + pub struct NameConstraintsRef; +} + +impl NameConstraintsRef { + pub fn permitted(&self) -> Option<&StackRef> { + unsafe { StackRef::from_const_ptr_opt((*self.as_ptr()).permitted) } + } + + pub fn excluded(&self) -> Option<&StackRef> { + unsafe { StackRef::from_const_ptr_opt((*self.as_ptr()).excluded) } + } +} + foreign_type_and_impl_send_sync! { type CType = ffi::X509_ALGOR; fn drop = ffi::X509_ALGOR_free; diff --git a/openssl/src/x509/tests.rs b/openssl/src/x509/tests.rs index 25c2da0125..24e90690e7 100644 --- a/openssl/src/x509/tests.rs +++ b/openssl/src/x509/tests.rs @@ -265,6 +265,39 @@ fn test_subject_alt_name_iter() { assert!(subject_alt_names_iter.next().is_none()); } +#[test] +fn test_name_constraints() { + let cert = include_bytes!("../../test/name_constraints.pem"); + let cert = X509::from_pem(cert).unwrap(); + + // Access through .name_constraints() + let name_constraints = cert + .name_constraints() + .expect("Name constraints extension should be present"); + + let permitted = name_constraints.permitted().unwrap(); + assert_eq!(permitted.len(), 1); + + let base = permitted[0].base().dnsname().unwrap(); + assert_eq!(base, ".example.com"); + + let minimum = permitted[0].minimum().is_none(); + assert_eq!(minimum, true); + let maximum = permitted[0].maximum().is_none(); + assert_eq!(maximum, true); + + let excluded = name_constraints.excluded().unwrap(); + assert_eq!(excluded.len(), 1); + + let base = excluded[0].base().dnsname().unwrap(); + assert_eq!(base, ".example.net"); + + let minimum = excluded[0].minimum().is_none(); + assert_eq!(minimum, true); + let maximum = excluded[0].maximum().is_none(); + assert_eq!(maximum, true); +} + #[test] fn test_aia_ca_issuer() { // With AIA diff --git a/openssl/test/name_constraints.pem b/openssl/test/name_constraints.pem new file mode 100644 index 0000000000..f2b66764ec --- /dev/null +++ b/openssl/test/name_constraints.pem @@ -0,0 +1,31 @@ +-----BEGIN CERTIFICATE----- +MIIFWjCCA0KgAwIBAgIUOwEq2g8zyCoGLVhxTQ/loZ7M0qwwDQYJKoZIhvcNAQEL +BQAwLDELMAkGA1UEBhMCVVMxEDAOBgNVBAoMB0V4YW1wbGUxCzAJBgNVBAsMAkNB +MB4XDTI0MTAxNjA0NTcyOFoXDTI1MTAxNjA0NTcyOFowLDELMAkGA1UEBhMCVVMx +EDAOBgNVBAoMB0V4YW1wbGUxCzAJBgNVBAsMAkNBMIICIjANBgkqhkiG9w0BAQEF +AAOCAg8AMIICCgKCAgEAoRQKVqSwPHyHQiHxMVCxabVO2W7dNGSP7jvnAR5Yu424 +9vLaY/n347f80w1ad8c1Ecl8m8vrprg7jAXuDoI02ys62J6qE87bqGpfL5oJ5AGD +RDm3x+T63bNvBbU2pSN5F0INXlahaGufE1BqDQlPq3CRDDnXSslTMGruZbcriW/u +IMgvnCGm7WtKejcnWa0vEmOo9KgOnHrpzYqWRJg6FmeT8D4P703HSexL1wNw7e4n +jSmaWrAMQeq8H0srjyMfKItMm1khYN7s4xFHkYARh9ppolXAXwLN56c9ZTunpb+p +Y1yBpYIeOp8NIDvwTfdUyHzr6ZsQ4tHu3XsXi4HMmBqnXxDIIctkwE1zB8nrGF8J +8GEH0hwXInsIG8ib7FIpF3T9zx85FsjK90TPMIG5DoBg3IuYiGU4Jc3tKrQLbrGl +fr25tneqbvndLSsIrRkb5z7JNnLNTv6eCVQGus6MYaOnR/tJAm7htCoImxvuc7+h +4nXIzypjNz1ephlvtad69RZYf1WQMMeVR3uK6T/J6QYVN3VqmU62pRJPuC3J3x/l +nEqJphA51gattgX7WJLb0dKSEEuRZzSmEJcgEnHg3Pyg0ST7Tbbj3hkLYVLD+kOn +VTaI4PDzLNSWnucZ6hcIDJr3rTj4wekkq+MsZ2dOacrzZKlJKWXTQGtdSeTxIesC +AwEAAaN0MHIwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0O +BBYEFGa7OPpxvHJn7JmdrnSvM8Yc1plJMDAGA1UdHgEB/wQmMCSgEDAOggwuZXhh +bXBsZS5jb22hEDAOggwuZXhhbXBsZS5uZXQwDQYJKoZIhvcNAQELBQADggIBAAbd +/7jTjmctPZrCB2//jLQXzPkqtwjK/kIWJ90l2XtlALsykdjawGi7GsbLHWabM0Cm +55iRFsQ+w3DC9+m/2wCL6yG/Pjnj/c3PNb707S4y57o8ALL7YuURso3PGOqYfBY1 +G851MXahFCM3SjxVKlJc6XCfs/XgJ7N0loAYLQSNsYjNk4QiuEsU6r7WtPy0qEzv +ly6u8U8DWQ0EEH3dA9UzUpwHW3sipUzxeKpxzqhaTc8U8+TPS+InEJfWHrGMKwF7 +Db1q7aQA6s8U7uLG45RIIvLBerpdyPsSpcFIlP7DAhllPgTWhtkAAvcddkeIUUcy +YKsjKMrtIX9Jzzo+ddgsIB8C/SRSE310lx2EJoD8gS1zMg4y9zQ/WXLI2ASzsO42 +n4b/O7me1Qd85ku8XgnEPxmLIzpNgfDTPR5z85zeCcejmFEXzXCAwIKhCub9tjjY +9ujbrI1jGGSfCv2YvxwfZgbMMwii5YA8wK9aXqqndV/IZasxDZqJiXhDhzxZMscf +RCOphZL2dzjeiS0iWmlSTr8YQ0jr5kjZc/zl5Z3WEQFWcVzBAjJwcYiiXtIWQBVH +aEdupCi8xLVm5lRZIGL/UupM2Kz8gPPxUJkmKGDS/cceoUmtdXsNrlNUSHiXlWh1 +ZITcIQozA0r0o+aEXoQtc6Tmb/rNnf84Rrfns622 +-----END CERTIFICATE----- From 23b7e35a56b491f49912ca13965df10eb6db08db Mon Sep 17 00:00:00 2001 From: Bertrand Roussel Date: Wed, 16 Oct 2024 15:02:04 -0700 Subject: [PATCH 2/4] Add policy_mappings access from X509Ref --- openssl-sys/CHANGELOG.md | 1 + openssl-sys/src/handwritten/x509v3.rs | 14 ++++++++- openssl/CHANGELOG.md | 1 + openssl/src/x509/mod.rs | 44 +++++++++++++++++++++++++++ openssl/src/x509/tests.rs | 17 +++++++++++ openssl/test/policy_mappings.pem | 16 ++++++++++ 6 files changed, 92 insertions(+), 1 deletion(-) create mode 100644 openssl/test/policy_mappings.pem diff --git a/openssl-sys/CHANGELOG.md b/openssl-sys/CHANGELOG.md index 4b08965a84..7fa7302b06 100644 --- a/openssl-sys/CHANGELOG.md +++ b/openssl-sys/CHANGELOG.md @@ -5,6 +5,7 @@ ### Added * Added `NAME_CONSTRAINTS`, `GENERAL_SUBTREE`, `stack_st_GENERAL_SUBTREE` +* Added `POLICY_MAPPING`, `stack_st_POLICY_MAPPING` ## [v0.9.104] - 2024-10-15 diff --git a/openssl-sys/src/handwritten/x509v3.rs b/openssl-sys/src/handwritten/x509v3.rs index 09f5045144..064d2731b3 100644 --- a/openssl-sys/src/handwritten/x509v3.rs +++ b/openssl-sys/src/handwritten/x509v3.rs @@ -188,4 +188,16 @@ pub struct NAME_CONSTRAINTS { extern "C" { pub fn NAME_CONSTRAINTS_free(nc: *mut NAME_CONSTRAINTS); -} \ No newline at end of file +} + +#[repr(C)] +pub struct POLICY_MAPPING { + pub issuerDomainPolicy: *mut ASN1_OBJECT, + pub subjectDomainPolicy: *mut ASN1_OBJECT, +} + +extern "C" { + pub fn POLICY_MAPPING_free(nc: *mut POLICY_MAPPING); +} + +stack!(stack_st_POLICY_MAPPING); \ No newline at end of file diff --git a/openssl/CHANGELOG.md b/openssl/CHANGELOG.md index 85e65d9735..77074ba657 100644 --- a/openssl/CHANGELOG.md +++ b/openssl/CHANGELOG.md @@ -5,6 +5,7 @@ ### Added - Added `X509Ref::name_constraints` +- Added `X509Ref::policy_mappings` ## [v0.10.67] - 2024-10-15 diff --git a/openssl/src/x509/mod.rs b/openssl/src/x509/mod.rs index 047dc85bf2..02174d4f21 100644 --- a/openssl/src/x509/mod.rs +++ b/openssl/src/x509/mod.rs @@ -493,6 +493,22 @@ impl X509Ref { } } + /// Returns this certificate's [`policy mappings`] entries, if they exist. + /// + /// [`policy mappings`]: https://tools.ietf.org/html/rfc5280#section-4.2.1.5 + #[corresponds(X509_get_ext_d2i)] + pub fn policy_mappings(&self) -> Option> { + unsafe { + let stack = ffi::X509_get_ext_d2i( + self.as_ptr(), + ffi::NID_policy_mappings, + ptr::null_mut(), + ptr::null_mut(), + ); + Stack::from_ptr_opt(stack as *mut _) + } + } + /// Retrieves the path length extension from a certificate, if it exists. #[corresponds(X509_get_pathlen)] #[cfg(any(ossl110, boringssl))] @@ -2325,6 +2341,34 @@ impl NameConstraintsRef { } } +foreign_type_and_impl_send_sync! { + type CType = ffi::POLICY_MAPPING; + fn drop = ffi::POLICY_MAPPING_free; + + /// `PolicyMapping` of certificate authority information. + pub struct PolicyMapping; + /// Reference to `PolicyMapping`. + pub struct PolicyMappingRef; +} + +impl Stackable for PolicyMapping { + type StackType = ffi::stack_st_POLICY_MAPPING; +} + +impl PolicyMappingRef { + pub fn issuer_domain_policy(&self) -> &Asn1ObjectRef { + unsafe { + Asn1ObjectRef::from_ptr((*self.as_ptr()).issuerDomainPolicy) + } + } + + pub fn subject_domain_policy(&self) -> &Asn1ObjectRef { + unsafe { + Asn1ObjectRef::from_ptr((*self.as_ptr()).subjectDomainPolicy) + } + } +} + foreign_type_and_impl_send_sync! { type CType = ffi::X509_ALGOR; fn drop = ffi::X509_ALGOR_free; diff --git a/openssl/src/x509/tests.rs b/openssl/src/x509/tests.rs index 24e90690e7..83734e9b9b 100644 --- a/openssl/src/x509/tests.rs +++ b/openssl/src/x509/tests.rs @@ -298,6 +298,23 @@ fn test_name_constraints() { assert_eq!(maximum, true); } +#[test] +fn test_policy_mappings() { + let cert = include_bytes!("../../test/policy_mappings.pem"); + let cert = X509::from_pem(cert).unwrap(); + + // Access through .policy_mappings() + let policy_mappings = cert + .policy_mappings() + .expect("Policy mappings should be present"); + + assert_eq!(policy_mappings.len(), 1); + let policy = policy_mappings[0].issuer_domain_policy().to_string(); + assert_eq!(policy, "2.16.840.1.101.3.2.1.48.1"); + let policy = policy_mappings[0].subject_domain_policy().to_string(); + assert_eq!(policy, "2.16.840.1.101.3.2.1.48.2"); +} + #[test] fn test_aia_ca_issuer() { // With AIA diff --git a/openssl/test/policy_mappings.pem b/openssl/test/policy_mappings.pem new file mode 100644 index 0000000000..b6b5e5e921 --- /dev/null +++ b/openssl/test/policy_mappings.pem @@ -0,0 +1,16 @@ +-----BEGIN CERTIFICATE----- +MIICfDCCAiOgAwIBAgIKaALI6NVFszY7ADAKBggqhkjOPQQDAjBcMQswCQYDVQQG +EwJVUzEgMB4GA1UECgwXVGVzdCBNQ0EgT3JnYW5pemF0aW9uIDIxHzAdBgNVBAMM +FlRlc3QgSUVFRSAyMDMwLjUgTUNBIDIxCjAIBgNVBAUMATEwIBcNMTkwNDE2MDU0 +MzE4WhgPOTk5OTEyMzEyMzU5NTlaMF4xCzAJBgNVBAYTAlVTMSEwHwYDVQQKDBhU +ZXN0IE1JQ0EgT3JnYW5pemF0aW9uIDIxIDAeBgNVBAMMF1Rlc3QgSUVFRSAyMDMw +LjUgTUlDQSAyMQowCAYDVQQFDAE0MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE +hfu4ivOW15lzRrkguuUpDi4jR82g+p1z/2m0AJmiC4uJ2nY4c/80EDhG9mzuOaW4 +UqJ5xSoyJWqmjDqLi7RdOaOByDCBxTASBgNVHRMBAf8ECDAGAQH/AgEAMBEGA1Ud +DgQKBAhD4TrR7KbbDTATBgNVHSMEDDAKgAhO1GdTUZdzwDAOBgNVHQ8BAf8EBAMC +AQYwUgYDVR0gAQH/BEgwRjAMBgorBQEEAYK+HAEBMAwGCisFAQQBgr4cAQIwDAYK +KwUBBAGCvhwBAzAMBgorBQEEAYK+HAIBMAwGCisFAQQBgr4cAgQwIwYDVR0hBBww +GjAYBgpghkgBZQMCATABBgpghkgBZQMCATACMAoGCCqGSM49BAMCA0cAMEQCIDJn +3s1sy27lQgxYNPImr9nYzsvIlTrEGbZUuBcw7knuAiAGWfpCVFxzE+UujZ8+ylqT +k6IKlu1bUvsNJL0Tv8XV6A== +-----END CERTIFICATE----- From cd0b955aa0d2a04fbf6b3405cffd7ac7ba0743f3 Mon Sep 17 00:00:00 2001 From: Bertrand Roussel Date: Wed, 16 Oct 2024 15:29:57 -0700 Subject: [PATCH 3/4] Fix NAME_CONSTRAINTS content to match openssl struct --- openssl-sys/src/handwritten/x509v3.rs | 4 ++-- openssl/src/x509/mod.rs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/openssl-sys/src/handwritten/x509v3.rs b/openssl-sys/src/handwritten/x509v3.rs index 064d2731b3..fcf02c1f0f 100644 --- a/openssl-sys/src/handwritten/x509v3.rs +++ b/openssl-sys/src/handwritten/x509v3.rs @@ -182,8 +182,8 @@ stack!(stack_st_GENERAL_SUBTREE); #[repr(C)] pub struct NAME_CONSTRAINTS { - pub permitted: *mut stack_st_GENERAL_SUBTREE, - pub excluded: *mut stack_st_GENERAL_SUBTREE, + pub permittedSubtrees: *mut stack_st_GENERAL_SUBTREE, + pub excludedSubtrees: *mut stack_st_GENERAL_SUBTREE, } extern "C" { diff --git a/openssl/src/x509/mod.rs b/openssl/src/x509/mod.rs index 02174d4f21..f9ee9e369e 100644 --- a/openssl/src/x509/mod.rs +++ b/openssl/src/x509/mod.rs @@ -2333,11 +2333,11 @@ foreign_type_and_impl_send_sync! { impl NameConstraintsRef { pub fn permitted(&self) -> Option<&StackRef> { - unsafe { StackRef::from_const_ptr_opt((*self.as_ptr()).permitted) } + unsafe { StackRef::from_const_ptr_opt((*self.as_ptr()).permittedSubtrees) } } pub fn excluded(&self) -> Option<&StackRef> { - unsafe { StackRef::from_const_ptr_opt((*self.as_ptr()).excluded) } + unsafe { StackRef::from_const_ptr_opt((*self.as_ptr()).excludedSubtrees) } } } From 2ed865bbfd16f307caba80fd85ba3e74013aebbf Mon Sep 17 00:00:00 2001 From: Bertrand Roussel Date: Wed, 16 Oct 2024 15:32:59 -0700 Subject: [PATCH 4/4] Fix fmt & clippy issues --- openssl-sys/src/handwritten/x509v3.rs | 2 +- openssl/src/x509/mod.rs | 8 ++------ openssl/src/x509/tests.rs | 8 ++++---- 3 files changed, 7 insertions(+), 11 deletions(-) diff --git a/openssl-sys/src/handwritten/x509v3.rs b/openssl-sys/src/handwritten/x509v3.rs index fcf02c1f0f..df6d98f284 100644 --- a/openssl-sys/src/handwritten/x509v3.rs +++ b/openssl-sys/src/handwritten/x509v3.rs @@ -200,4 +200,4 @@ extern "C" { pub fn POLICY_MAPPING_free(nc: *mut POLICY_MAPPING); } -stack!(stack_st_POLICY_MAPPING); \ No newline at end of file +stack!(stack_st_POLICY_MAPPING); diff --git a/openssl/src/x509/mod.rs b/openssl/src/x509/mod.rs index f9ee9e369e..3cdc30ad4f 100644 --- a/openssl/src/x509/mod.rs +++ b/openssl/src/x509/mod.rs @@ -2357,15 +2357,11 @@ impl Stackable for PolicyMapping { impl PolicyMappingRef { pub fn issuer_domain_policy(&self) -> &Asn1ObjectRef { - unsafe { - Asn1ObjectRef::from_ptr((*self.as_ptr()).issuerDomainPolicy) - } + unsafe { Asn1ObjectRef::from_ptr((*self.as_ptr()).issuerDomainPolicy) } } pub fn subject_domain_policy(&self) -> &Asn1ObjectRef { - unsafe { - Asn1ObjectRef::from_ptr((*self.as_ptr()).subjectDomainPolicy) - } + unsafe { Asn1ObjectRef::from_ptr((*self.as_ptr()).subjectDomainPolicy) } } } diff --git a/openssl/src/x509/tests.rs b/openssl/src/x509/tests.rs index 83734e9b9b..8db2046e2a 100644 --- a/openssl/src/x509/tests.rs +++ b/openssl/src/x509/tests.rs @@ -282,9 +282,9 @@ fn test_name_constraints() { assert_eq!(base, ".example.com"); let minimum = permitted[0].minimum().is_none(); - assert_eq!(minimum, true); + assert!(minimum); let maximum = permitted[0].maximum().is_none(); - assert_eq!(maximum, true); + assert!(maximum); let excluded = name_constraints.excluded().unwrap(); assert_eq!(excluded.len(), 1); @@ -293,9 +293,9 @@ fn test_name_constraints() { assert_eq!(base, ".example.net"); let minimum = excluded[0].minimum().is_none(); - assert_eq!(minimum, true); + assert!(minimum); let maximum = excluded[0].maximum().is_none(); - assert_eq!(maximum, true); + assert!(maximum); } #[test]