cert dir_name cmp: fix empty name
This commit is contained in:
parent
8cedbd5165
commit
7782d939f3
@ -353,6 +353,30 @@ impl<'a> GeneralName<'a> {
|
|||||||
// Self IP address is not NULL
|
// Self IP address is not NULL
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
(Self::DirectoryName(self_name), Self::DirectoryName(other_name)) => {
|
||||||
|
if self_name.relative_distinguished_name.len() == 0 {
|
||||||
|
true // Empty set is always a subset of other set
|
||||||
|
} else if other_name.relative_distinguished_name.len() == 0 {
|
||||||
|
false // If self is not empty, other is empty, other is a subset
|
||||||
|
} else if self_name.relative_distinguished_name.len()
|
||||||
|
< other_name.relative_distinguished_name.len() {
|
||||||
|
false
|
||||||
|
} else {
|
||||||
|
// For each RDN in other, if self has the same RDN
|
||||||
|
// then self is within the subtree of other
|
||||||
|
// Special case: therecould be no RDN in other
|
||||||
|
// In this case other_name is empty
|
||||||
|
// it should be handled in prior
|
||||||
|
for other_rdn in other_name.relative_distinguished_name.iter() {
|
||||||
|
if self_name.relative_distinguished_name.iter().find(
|
||||||
|
|&self_rdn| self_rdn == other_rdn
|
||||||
|
).is_none() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
_ => false // Heterogeneity, in terms of GeneralName variant
|
_ => false // Heterogeneity, in terms of GeneralName variant
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -370,10 +394,12 @@ impl<'a> GeneralName<'a> {
|
|||||||
match (self, other) {
|
match (self, other) {
|
||||||
(Self::URI(self_uri), Self::URI(other_uri)) => {
|
(Self::URI(self_uri), Self::URI(other_uri)) => {
|
||||||
self_uri.ends_with(other_uri)
|
self_uri.ends_with(other_uri)
|
||||||
}
|
},
|
||||||
(Self::RFC822Name(..), Self::RFC822Name(..))
|
(Self::RFC822Name(self_rfc_822), Self::RFC822Name(other_rfc_822)) => {
|
||||||
| (Self::DNSName(..), Self::DNSName(..)) => {
|
self_rfc_822.ends_with(other_rfc_822)
|
||||||
self.is_subset_of(other)
|
},
|
||||||
|
(Self::DNSName(self_dns), Self::DNSName(other_dns)) => {
|
||||||
|
self_dns.ends_with(other_dns)
|
||||||
},
|
},
|
||||||
|
|
||||||
(Self::IPAddress(san_ip), Self::IPAddress(cidr_network)) => {
|
(Self::IPAddress(san_ip), Self::IPAddress(cidr_network)) => {
|
||||||
@ -418,6 +444,10 @@ impl<'a> GeneralName<'a> {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
(Self::DirectoryName(self_dir_name), Self::DirectoryName(other_dir_name)) => {
|
||||||
|
self_dir_name.belongs_to(other_dir_name)
|
||||||
|
},
|
||||||
|
|
||||||
// Unsupported variant/heterogeneous comparison
|
// Unsupported variant/heterogeneous comparison
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
@ -455,9 +485,10 @@ pub struct Name<'a> {
|
|||||||
|
|
||||||
impl<'a> Name<'a> {
|
impl<'a> Name<'a> {
|
||||||
pub fn belongs_to(&self, other: &Self) -> bool {
|
pub fn belongs_to(&self, other: &Self) -> bool {
|
||||||
if self.relative_distinguished_name.len()
|
if other.relative_distinguished_name.len() == 0 {
|
||||||
< other.relative_distinguished_name.len()
|
true // Wildcard
|
||||||
{
|
} else if self.relative_distinguished_name.len()
|
||||||
|
< other.relative_distinguished_name.len() {
|
||||||
false
|
false
|
||||||
} else {
|
} else {
|
||||||
// For each RDN in other, self must have the same RDN
|
// For each RDN in other, self must have the same RDN
|
||||||
@ -475,6 +506,8 @@ impl<'a> Name<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> PartialEq for Name<'a> {
|
impl<'a> PartialEq for Name<'a> {
|
||||||
|
// Equivalent operator
|
||||||
|
// It should treat permutated name as equivalent
|
||||||
fn eq(&self, other: &Self) -> bool {
|
fn eq(&self, other: &Self) -> bool {
|
||||||
for self_name in self.relative_distinguished_name.iter() {
|
for self_name in self.relative_distinguished_name.iter() {
|
||||||
if other.relative_distinguished_name.iter().find(
|
if other.relative_distinguished_name.iter().find(
|
||||||
@ -483,6 +516,13 @@ impl<'a> PartialEq for Name<'a> {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for other_name in other.relative_distinguished_name.iter() {
|
||||||
|
if self.relative_distinguished_name.iter().find(
|
||||||
|
|&att_type_val| att_type_val == other_name
|
||||||
|
).is_none() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1226,6 +1266,8 @@ fn get_subtree_intersection<'a>(
|
|||||||
let mut has_other_ipv4_address_tree = false;
|
let mut has_other_ipv4_address_tree = false;
|
||||||
let mut has_self_ipv6_address_tree = false;
|
let mut has_self_ipv6_address_tree = false;
|
||||||
let mut has_other_ipv6_address_tree = false;
|
let mut has_other_ipv6_address_tree = false;
|
||||||
|
let mut has_self_directory_name = false;
|
||||||
|
let mut has_other_directory_name = false;
|
||||||
|
|
||||||
for general_name in state_subtree.iter() {
|
for general_name in state_subtree.iter() {
|
||||||
match general_name {
|
match general_name {
|
||||||
@ -1240,6 +1282,7 @@ fn get_subtree_intersection<'a>(
|
|||||||
has_self_ipv6_address_tree = true;
|
has_self_ipv6_address_tree = true;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
GeneralName::DirectoryName(..) => has_self_directory_name = true,
|
||||||
// Other general_name variants should not appear in this subtree
|
// Other general_name variants should not appear in this subtree
|
||||||
_ => {},
|
_ => {},
|
||||||
}
|
}
|
||||||
@ -1258,6 +1301,7 @@ fn get_subtree_intersection<'a>(
|
|||||||
has_other_ipv6_address_tree = true;
|
has_other_ipv6_address_tree = true;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
GeneralName::DirectoryName(..) => has_other_directory_name = true,
|
||||||
// Other general_name variants should not appear in this subtree
|
// Other general_name variants should not appear in this subtree
|
||||||
_ => {},
|
_ => {},
|
||||||
}
|
}
|
||||||
@ -1291,6 +1335,11 @@ fn get_subtree_intersection<'a>(
|
|||||||
preserved_subtrees.push((*general_name).clone());
|
preserved_subtrees.push((*general_name).clone());
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
GeneralName::DirectoryName(..) => {
|
||||||
|
if !has_other_directory_name {
|
||||||
|
preserved_subtrees.push((*general_name).clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
// Other general_name variants should not appear in this subtree
|
// Other general_name variants should not appear in this subtree
|
||||||
_ => {},
|
_ => {},
|
||||||
}
|
}
|
||||||
@ -1321,6 +1370,11 @@ fn get_subtree_intersection<'a>(
|
|||||||
preserved_subtrees.push((*general_name).clone());
|
preserved_subtrees.push((*general_name).clone());
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
GeneralName::DirectoryName(..) => {
|
||||||
|
if !has_self_directory_name {
|
||||||
|
preserved_subtrees.push((*general_name).clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
// Other general_name variants should not appear in this subtree
|
// Other general_name variants should not appear in this subtree
|
||||||
_ => {},
|
_ => {},
|
||||||
}
|
}
|
||||||
@ -1379,6 +1433,7 @@ fn get_subtree_intersection<'a>(
|
|||||||
|
|
||||||
// If neither are subset of the other, the intersection shall be none
|
// If neither are subset of the other, the intersection shall be none
|
||||||
// Should both names be homogeneous, it should imply an all-blocking name
|
// Should both names be homogeneous, it should imply an all-blocking name
|
||||||
|
else {
|
||||||
match (self_name, other_name) {
|
match (self_name, other_name) {
|
||||||
(GeneralName::URI(self_uri), GeneralName::URI(other_uri)) => {
|
(GeneralName::URI(self_uri), GeneralName::URI(other_uri)) => {
|
||||||
preserved_subtrees.push(
|
preserved_subtrees.push(
|
||||||
@ -1400,12 +1455,20 @@ fn get_subtree_intersection<'a>(
|
|||||||
GeneralName::IPAddress(&[])
|
GeneralName::IPAddress(&[])
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
|
(GeneralName::DirectoryName(..), GeneralName::DirectoryName(..)) => {
|
||||||
|
preserved_subtrees.push(
|
||||||
|
GeneralName::DirectoryName(Name {
|
||||||
|
relative_distinguished_name: Vec::new()
|
||||||
|
})
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
// Heterogeneous general name variants
|
// Heterogeneous general name variants
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 4. Perform union operation
|
// 4. Perform union operation
|
||||||
// Again recall that general names are hierarchical
|
// Again recall that general names are hierarchical
|
||||||
@ -1459,8 +1522,15 @@ pub fn get_subtree_union<'a>(
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
|
|
||||||
use alloc::vec::Vec;
|
use alloc::vec::Vec;
|
||||||
use super::*;
|
use super::*;
|
||||||
|
use crate::parse::parse_asn1_der_name;
|
||||||
|
|
||||||
|
// Helper to init logger if necessary
|
||||||
|
fn init() {
|
||||||
|
simple_logger::SimpleLogger::new().init();
|
||||||
|
}
|
||||||
|
|
||||||
const DNS_EXAMPLE_COM: GeneralName = GeneralName::DNSName(
|
const DNS_EXAMPLE_COM: GeneralName = GeneralName::DNSName(
|
||||||
b"example.com"
|
b"example.com"
|
||||||
@ -1475,11 +1545,6 @@ mod test {
|
|||||||
b""
|
b""
|
||||||
);
|
);
|
||||||
|
|
||||||
// Helper to init logger if necessary
|
|
||||||
fn init() {
|
|
||||||
simple_logger::SimpleLogger::new().init();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Behaviour of IP intersection/union operation
|
* Behaviour of IP intersection/union operation
|
||||||
*/
|
*/
|
||||||
@ -1491,51 +1556,76 @@ mod test {
|
|||||||
const CIDR_IPv4_2: GeneralName = GeneralName::IPAddress(
|
const CIDR_IPv4_2: GeneralName = GeneralName::IPAddress(
|
||||||
&[192, 168, 0, 1, 255, 255, 255, 128]
|
&[192, 168, 0, 1, 255, 255, 255, 128]
|
||||||
);
|
);
|
||||||
|
|
||||||
// 192.168.0.1/31
|
// 192.168.0.1/31
|
||||||
const CIDR_IPv4_3: GeneralName = GeneralName::IPAddress(
|
const CIDR_IPv4_3: GeneralName = GeneralName::IPAddress(
|
||||||
&[192, 168, 0, 1, 255, 255, 255, 254]
|
&[192, 168, 0, 1, 255, 255, 255, 254]
|
||||||
);
|
);
|
||||||
|
// 192.72.0.1/24
|
||||||
const CIDR_IPv4_4: GeneralName = GeneralName::IPAddress(
|
const CIDR_IPv4_4: GeneralName = GeneralName::IPAddress(
|
||||||
&[192, 72, 0, 1, 255, 255, 255, 0]
|
&[192, 72, 0, 1, 255, 255, 255, 0]
|
||||||
);
|
);
|
||||||
|
// Wildcard
|
||||||
const CIDR_IPv4_NONE: GeneralName = GeneralName::IPAddress(
|
const CIDR_IPv4_NONE: GeneralName = GeneralName::IPAddress(
|
||||||
&[]
|
&[]
|
||||||
);
|
);
|
||||||
|
// 192.72.0.0/24
|
||||||
const CIDR_IPv4_5: GeneralName = GeneralName::IPAddress(
|
const CIDR_IPv4_5: GeneralName = GeneralName::IPAddress(
|
||||||
&[192, 72, 0, 0, 255, 255, 255, 0]
|
&[192, 72, 0, 0, 255, 255, 255, 0]
|
||||||
);
|
);
|
||||||
|
// 192.200.103.0/24
|
||||||
const CIDR_IPv4_6: GeneralName = GeneralName::IPAddress(
|
const CIDR_IPv4_6: GeneralName = GeneralName::IPAddress(
|
||||||
&[192, 200, 103, 0, 255, 255, 255, 0]
|
&[192, 200, 103, 0, 255, 255, 255, 0]
|
||||||
);
|
);
|
||||||
|
// 192.200.100.0/22
|
||||||
const CIDR_IPv4_7: GeneralName = GeneralName::IPAddress(
|
const CIDR_IPv4_7: GeneralName = GeneralName::IPAddress(
|
||||||
&[192, 200, 100, 0, 255, 255, 252, 0]
|
&[192, 200, 100, 0, 255, 255, 252, 0]
|
||||||
);
|
);
|
||||||
|
// 200.200.100.0/24
|
||||||
const CIDR_IPv4_8: GeneralName = GeneralName::IPAddress(
|
const CIDR_IPv4_8: GeneralName = GeneralName::IPAddress(
|
||||||
&[200, 200, 100, 0, 255, 255, 255, 0]
|
&[200, 200, 100, 0, 255, 255, 255, 0]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// 2001:0db8:ac10:fe01::/64
|
||||||
const CIDR_IPv6_1: GeneralName = GeneralName::IPAddress(
|
const CIDR_IPv6_1: GeneralName = GeneralName::IPAddress(
|
||||||
&[0x20, 0x01, 0x0D, 0xB8, 0xAC, 0x10, 0xFE, 0x01,
|
&[0x20, 0x01, 0x0D, 0xB8, 0xAC, 0x10, 0xFE, 0x01,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]
|
||||||
);
|
);
|
||||||
|
// 2001:0db8:ac10:fe01:1224::/80
|
||||||
const CIDR_IPv6_2: GeneralName = GeneralName::IPAddress(
|
const CIDR_IPv6_2: GeneralName = GeneralName::IPAddress(
|
||||||
&[0x20, 0x01, 0x0D, 0xB8, 0xAC, 0x10, 0xFE, 0x01,
|
&[0x20, 0x01, 0x0D, 0xB8, 0xAC, 0x10, 0xFE, 0x01,
|
||||||
0x12, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x12, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||||
0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]
|
0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]
|
||||||
);
|
);
|
||||||
|
// 2001:0db8:ac10:ac01::/64
|
||||||
const CIDR_IPv6_3: GeneralName = GeneralName::IPAddress(
|
const CIDR_IPv6_3: GeneralName = GeneralName::IPAddress(
|
||||||
&[0x20, 0x01, 0x0D, 0xB8, 0xAC, 0x10, 0xAC, 0x01,
|
&[0x20, 0x01, 0x0D, 0xB8, 0xAC, 0x10, 0xAC, 0x01,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]
|
||||||
);
|
);
|
||||||
|
// URI
|
||||||
|
const URI_HOST_SPECIFIC: GeneralName = GeneralName::URI(
|
||||||
|
b"host.example.com"
|
||||||
|
);
|
||||||
|
const URI_HOST_ONLY: GeneralName = GeneralName::URI(
|
||||||
|
b".example.com"
|
||||||
|
);
|
||||||
|
const URI_DOMAIN_WIDE: GeneralName = GeneralName::URI(
|
||||||
|
b"example.com"
|
||||||
|
);
|
||||||
|
// X400, not supported
|
||||||
|
const X400_ROOT: GeneralName = GeneralName::X400Address(
|
||||||
|
b"root@example.com"
|
||||||
|
);
|
||||||
|
const X400_HOST: GeneralName = GeneralName::X400Address(
|
||||||
|
b"example.com"
|
||||||
|
);
|
||||||
|
const X400_DOMAIN_WIDE: GeneralName = GeneralName::X400Address(
|
||||||
|
b".example.com"
|
||||||
|
);
|
||||||
|
|
||||||
macro_rules! test_set_intersection {
|
macro_rules! test_set_intersection {
|
||||||
($($($left_item: expr)*, $($right_item: expr)*, $($expected_item: expr)*);*) => {
|
($($($left_item: expr)*, $($right_item: expr)*, $($expected_item: expr)*);*) => {
|
||||||
@ -1610,7 +1700,8 @@ mod test {
|
|||||||
// Intersection between DNS set and unspecified set
|
// Intersection between DNS set and unspecified set
|
||||||
DNS_EXAMPLE_COM DNS_FOO_EXAMPLE, , DNS_EXAMPLE_COM;
|
DNS_EXAMPLE_COM DNS_FOO_EXAMPLE, , DNS_EXAMPLE_COM;
|
||||||
, DNS_EXAMPLE_COM DNS_FOO_EXAMPLE, DNS_EXAMPLE_COM;
|
, DNS_EXAMPLE_COM DNS_FOO_EXAMPLE, DNS_EXAMPLE_COM;
|
||||||
// Intersection between subset and superset
|
|
||||||
|
// Intersection between subnet and supernet
|
||||||
CIDR_IPv4_1, CIDR_IPv4_2 CIDR_IPv4_3, CIDR_IPv4_2;
|
CIDR_IPv4_1, CIDR_IPv4_2 CIDR_IPv4_3, CIDR_IPv4_2;
|
||||||
CIDR_IPv4_1 CIDR_IPv4_2, CIDR_IPv4_3, CIDR_IPv4_3;
|
CIDR_IPv4_1 CIDR_IPv4_2, CIDR_IPv4_3, CIDR_IPv4_3;
|
||||||
CIDR_IPv4_2 CIDR_IPv4_3, CIDR_IPv4_1, CIDR_IPv4_2;
|
CIDR_IPv4_2 CIDR_IPv4_3, CIDR_IPv4_1, CIDR_IPv4_2;
|
||||||
@ -1629,7 +1720,14 @@ mod test {
|
|||||||
// Adding a disjoint IPv6 on state subtrees should not alter intersection result
|
// Adding a disjoint IPv6 on state subtrees should not alter intersection result
|
||||||
CIDR_IPv6_1 CIDR_IPv4_7 CIDR_IPv6_3, CIDR_IPv6_2 CIDR_IPv4_6, CIDR_IPv6_2 CIDR_IPv4_6;
|
CIDR_IPv6_1 CIDR_IPv4_7 CIDR_IPv6_3, CIDR_IPv6_2 CIDR_IPv4_6, CIDR_IPv6_2 CIDR_IPv4_6;
|
||||||
// Heterogeneous disjoint intersection, effectively self union
|
// Heterogeneous disjoint intersection, effectively self union
|
||||||
CIDR_IPv6_1 CIDR_IPv6_2, CIDR_IPv4_7 CIDR_IPv4_6, CIDR_IPv6_1 CIDR_IPv4_7
|
CIDR_IPv6_1 CIDR_IPv6_2, CIDR_IPv4_7 CIDR_IPv4_6, CIDR_IPv6_1 CIDR_IPv4_7;
|
||||||
|
|
||||||
|
// Intersection between heterogeneous variants
|
||||||
|
DNS_FOO_EXAMPLE, CIDR_IPv6_1, DNS_FOO_EXAMPLE CIDR_IPv6_1;
|
||||||
|
DNS_FOO_EXAMPLE CIDR_IPv6_2, CIDR_IPv6_1 DNS_EXAMPLE_NET, DNS_EMPTY CIDR_IPv6_2;
|
||||||
|
|
||||||
|
// Intersection with variants that do not support such operation
|
||||||
|
X400_ROOT DNS_FOO_EXAMPLE CIDR_IPv6_2, CIDR_IPv6_1 DNS_EXAMPLE_NET, DNS_EMPTY CIDR_IPv6_2
|
||||||
);
|
);
|
||||||
|
|
||||||
test_set_union!(
|
test_set_union!(
|
||||||
@ -1645,7 +1743,8 @@ mod test {
|
|||||||
// Union between DNS set and unspecified set
|
// Union between DNS set and unspecified set
|
||||||
DNS_EXAMPLE_COM DNS_FOO_EXAMPLE, , DNS_EXAMPLE_COM;
|
DNS_EXAMPLE_COM DNS_FOO_EXAMPLE, , DNS_EXAMPLE_COM;
|
||||||
, DNS_EXAMPLE_COM DNS_FOO_EXAMPLE, DNS_EXAMPLE_COM;
|
, DNS_EXAMPLE_COM DNS_FOO_EXAMPLE, DNS_EXAMPLE_COM;
|
||||||
// Union between subset and superset
|
|
||||||
|
// Union between subnet and supernet
|
||||||
CIDR_IPv4_1, CIDR_IPv4_2 CIDR_IPv4_3, CIDR_IPv4_1;
|
CIDR_IPv4_1, CIDR_IPv4_2 CIDR_IPv4_3, CIDR_IPv4_1;
|
||||||
CIDR_IPv4_1 CIDR_IPv4_3, CIDR_IPv4_2, CIDR_IPv4_1;
|
CIDR_IPv4_1 CIDR_IPv4_3, CIDR_IPv4_2, CIDR_IPv4_1;
|
||||||
CIDR_IPv4_2 CIDR_IPv4_3, CIDR_IPv4_1, CIDR_IPv4_1;
|
CIDR_IPv4_2 CIDR_IPv4_3, CIDR_IPv4_1, CIDR_IPv4_1;
|
||||||
@ -1661,6 +1760,127 @@ mod test {
|
|||||||
// Adding a disjoint IPv6 on state subtrees should mean appending the disjoin subtree
|
// Adding a disjoint IPv6 on state subtrees should mean appending the disjoin subtree
|
||||||
CIDR_IPv6_1 CIDR_IPv6_3 CIDR_IPv4_7, CIDR_IPv6_2 CIDR_IPv4_6, CIDR_IPv6_1 CIDR_IPv6_3 CIDR_IPv4_7;
|
CIDR_IPv6_1 CIDR_IPv6_3 CIDR_IPv4_7, CIDR_IPv6_2 CIDR_IPv4_6, CIDR_IPv6_1 CIDR_IPv6_3 CIDR_IPv4_7;
|
||||||
// Heterogeneous disjoint union, effectively self union
|
// Heterogeneous disjoint union, effectively self union
|
||||||
CIDR_IPv6_1 CIDR_IPv6_2, CIDR_IPv4_7 CIDR_IPv4_6, CIDR_IPv6_1 CIDR_IPv4_7
|
CIDR_IPv6_1 CIDR_IPv6_2, CIDR_IPv4_7 CIDR_IPv4_6, CIDR_IPv6_1 CIDR_IPv4_7;
|
||||||
|
|
||||||
|
// Union between heterogeneous variants
|
||||||
|
DNS_FOO_EXAMPLE, CIDR_IPv6_1, DNS_FOO_EXAMPLE CIDR_IPv6_1;
|
||||||
|
DNS_FOO_EXAMPLE CIDR_IPv6_2, CIDR_IPv6_1 DNS_EXAMPLE_NET, DNS_FOO_EXAMPLE CIDR_IPv6_1 DNS_EXAMPLE_NET;
|
||||||
|
|
||||||
|
// Intersection with variants that do not support such operation
|
||||||
|
X400_ROOT DNS_FOO_EXAMPLE CIDR_IPv6_2, CIDR_IPv6_1 DNS_EXAMPLE_NET, X400_ROOT DNS_FOO_EXAMPLE CIDR_IPv6_1 DNS_EXAMPLE_NET
|
||||||
);
|
);
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_directory_name_operations() {
|
||||||
|
// Less specific directory name
|
||||||
|
let broad_name = parse_asn1_der_name(
|
||||||
|
&[0x30, 0x22, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
|
||||||
|
0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a,
|
||||||
|
0x13, 0x0a, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x43, 0x41]
|
||||||
|
).unwrap().1;
|
||||||
|
|
||||||
|
// More specific directory name
|
||||||
|
let specific_name = parse_asn1_der_name(
|
||||||
|
&[0x30, 0x2e, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
|
||||||
|
0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a,
|
||||||
|
0x13, 0x0a, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x43, 0x41,
|
||||||
|
0x31, 0x0a, 0x30, 0x08, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x01, 0x70]
|
||||||
|
).unwrap().1;
|
||||||
|
|
||||||
|
// Disjoint name
|
||||||
|
let disjoint_name = parse_asn1_der_name(
|
||||||
|
&[0x30, 0x22, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
|
||||||
|
0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a,
|
||||||
|
0x13, 0x0a, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x43, 0x42]
|
||||||
|
).unwrap().1;
|
||||||
|
|
||||||
|
// Permutated name
|
||||||
|
let permutated_name = parse_asn1_der_name(
|
||||||
|
&[0x30, 0x22, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a,
|
||||||
|
0x13, 0x0a, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x43, 0x41,
|
||||||
|
0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
|
||||||
|
0x02, 0x55, 0x53]
|
||||||
|
).unwrap().1;
|
||||||
|
|
||||||
|
// Empty name
|
||||||
|
let empty_name = Name {
|
||||||
|
relative_distinguished_name: Vec::new()
|
||||||
|
};
|
||||||
|
|
||||||
|
assert!(specific_name.belongs_to(&broad_name));
|
||||||
|
assert!(!disjoint_name.belongs_to(&broad_name));
|
||||||
|
assert!(!disjoint_name.belongs_to(&specific_name));
|
||||||
|
assert!(specific_name != broad_name);
|
||||||
|
assert!(broad_name != specific_name);
|
||||||
|
assert!(broad_name == permutated_name);
|
||||||
|
|
||||||
|
let mut state_subtrees: Vec<GeneralName> = Vec::new();
|
||||||
|
let mut cert_subtrees: Vec<GeneralName> = Vec::new();
|
||||||
|
let mut expected_subtrees: Vec<GeneralName> = Vec::new();
|
||||||
|
|
||||||
|
let broad_general_name = GeneralName::DirectoryName(broad_name);
|
||||||
|
let specific_general_name = GeneralName::DirectoryName(specific_name);
|
||||||
|
let disjoint_general_name = GeneralName::DirectoryName(disjoint_name);
|
||||||
|
let permutated_general_name = GeneralName::DirectoryName(permutated_name);
|
||||||
|
let empty_general_name = GeneralName::DirectoryName(empty_name);
|
||||||
|
|
||||||
|
assert!(specific_general_name.is_subset_of(&broad_general_name));
|
||||||
|
assert!(!broad_general_name.is_subset_of(&specific_general_name));
|
||||||
|
assert!(specific_general_name != broad_general_name);
|
||||||
|
|
||||||
|
assert!(empty_general_name.is_subset_of(&specific_general_name));
|
||||||
|
assert!(!specific_general_name.is_subset_of(&empty_general_name));
|
||||||
|
|
||||||
|
state_subtrees.push(broad_general_name.clone());
|
||||||
|
cert_subtrees.push(specific_general_name.clone());
|
||||||
|
expected_subtrees.push(specific_general_name.clone());
|
||||||
|
get_subtree_intersection(&mut state_subtrees, &cert_subtrees);
|
||||||
|
assert_eq!(state_subtrees, expected_subtrees);
|
||||||
|
|
||||||
|
state_subtrees.clear();
|
||||||
|
cert_subtrees.clear();
|
||||||
|
expected_subtrees.clear();
|
||||||
|
state_subtrees.push(broad_general_name.clone());
|
||||||
|
cert_subtrees.push(specific_general_name.clone());
|
||||||
|
expected_subtrees.push(broad_general_name.clone());
|
||||||
|
get_subtree_union(&mut state_subtrees, &cert_subtrees);
|
||||||
|
assert_eq!(state_subtrees, expected_subtrees);
|
||||||
|
|
||||||
|
// Behaviour with empty name
|
||||||
|
state_subtrees.clear();
|
||||||
|
cert_subtrees.clear();
|
||||||
|
expected_subtrees.clear();
|
||||||
|
state_subtrees.push(empty_general_name.clone());
|
||||||
|
cert_subtrees.push(specific_general_name.clone());
|
||||||
|
expected_subtrees.push(empty_general_name.clone());
|
||||||
|
get_subtree_intersection(&mut state_subtrees, &cert_subtrees);
|
||||||
|
assert_eq!(state_subtrees, expected_subtrees);
|
||||||
|
|
||||||
|
state_subtrees.clear();
|
||||||
|
cert_subtrees.clear();
|
||||||
|
expected_subtrees.clear();
|
||||||
|
state_subtrees.push(empty_general_name.clone());
|
||||||
|
cert_subtrees.push(specific_general_name.clone());
|
||||||
|
expected_subtrees.push(specific_general_name.clone());
|
||||||
|
get_subtree_union(&mut state_subtrees, &cert_subtrees);
|
||||||
|
assert_eq!(state_subtrees, expected_subtrees);
|
||||||
|
|
||||||
|
state_subtrees.clear();
|
||||||
|
cert_subtrees.clear();
|
||||||
|
expected_subtrees.clear();
|
||||||
|
state_subtrees.push(specific_general_name.clone());
|
||||||
|
cert_subtrees.push(empty_general_name.clone());
|
||||||
|
expected_subtrees.push(empty_general_name.clone());
|
||||||
|
get_subtree_intersection(&mut state_subtrees, &cert_subtrees);
|
||||||
|
assert_eq!(state_subtrees, expected_subtrees);
|
||||||
|
|
||||||
|
state_subtrees.clear();
|
||||||
|
cert_subtrees.clear();
|
||||||
|
expected_subtrees.clear();
|
||||||
|
state_subtrees.push(specific_general_name.clone());
|
||||||
|
cert_subtrees.push(empty_general_name.clone());
|
||||||
|
expected_subtrees.push(specific_general_name.clone());
|
||||||
|
get_subtree_union(&mut state_subtrees, &cert_subtrees);
|
||||||
|
assert_eq!(state_subtrees, expected_subtrees);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user