From b1bf9f1a666dcc527fb1191b61b7446543eed6b5 Mon Sep 17 00:00:00 2001 From: Peter Dettman Date: Tue, 7 Feb 2023 18:23:55 +0700 Subject: Add outlining, reorder methods --- crypto/src/pkix/PkixNameConstraintValidator.cs | 1641 ++++++++++++------------ 1 file changed, 826 insertions(+), 815 deletions(-) diff --git a/crypto/src/pkix/PkixNameConstraintValidator.cs b/crypto/src/pkix/PkixNameConstraintValidator.cs index 85dac857b..0b9e30f19 100644 --- a/crypto/src/pkix/PkixNameConstraintValidator.cs +++ b/crypto/src/pkix/PkixNameConstraintValidator.cs @@ -94,14 +94,47 @@ namespace Org.BouncyCastle.Pkix return true; } + #region DN + + public void CheckExcludedDN(Asn1Sequence dn) + { + CheckExcludedDN(excludedSubtreesDN, dn); + } + public void CheckPermittedDN(Asn1Sequence dn) { - CheckPermittedDirectory(permittedSubtreesDN, dn); + CheckPermittedDN(permittedSubtreesDN, dn); } - public void CheckExcludedDN(Asn1Sequence dn) + private void CheckExcludedDN(ISet excluded, Asn1Sequence directory) + { + if (IsDNConstrained(excluded, directory)) + { + throw new PkixNameConstraintValidatorException( + "Subject distinguished name is from an excluded subtree"); + } + } + + private void CheckPermittedDN(ISet permitted, Asn1Sequence directory) + { + if (permitted != null + && !(directory.Count == 0 && permitted.Count < 1) + && !IsDNConstrained(permitted, directory)) + { + throw new PkixNameConstraintValidatorException( + "Subject distinguished name is not from a permitted subtree"); + } + } + + private bool IsDNConstrained(ISet constraints, Asn1Sequence directory) { - CheckExcludedDirectory(excludedSubtreesDN, dn); + foreach (var constraint in constraints) + { + if (WithinDNSubtree(directory, constraint)) + return true; + } + + return false; } private ISet IntersectDN(ISet permitted, ISet dns) @@ -168,6 +201,38 @@ namespace Org.BouncyCastle.Pkix return union; } + #endregion + + #region OtherName + + private void CheckExcludedOtherName(ISet excluded, OtherName name) + { + if (IsOtherNameConstrained(excluded, name)) + throw new PkixNameConstraintValidatorException("OtherName is from an excluded subtree."); + } + + private void CheckPermittedOtherName(ISet permitted, OtherName name) + { + if (permitted != null && !IsOtherNameConstrained(permitted, name)) + throw new PkixNameConstraintValidatorException("Subject OtherName is not from a permitted subtree."); + } + + private bool IsOtherNameConstrained(ISet constraints, OtherName otherName) + { + foreach (OtherName constraint in constraints) + { + if (IsOtherNameConstrained(constraint, otherName)) + return true; + } + + return false; + } + + private bool IsOtherNameConstrained(OtherName constraint, OtherName otherName) + { + return constraint.Equals(otherName); + } + private ISet IntersectOtherName(ISet permitted, ISet otherNames) { var intersect = new HashSet(); @@ -207,6 +272,61 @@ namespace Org.BouncyCastle.Pkix return union; } + #endregion + + #region Email + + private void CheckExcludedEmail(ISet excluded, string email) + { + if (IsEmailConstrained(excluded, email)) + throw new PkixNameConstraintValidatorException("Email address is from an excluded subtree."); + } + + private void CheckPermittedEmail(ISet permitted, string email) + { + if (permitted != null + && !(email.Length == 0 && permitted.Count < 1) + && !IsEmailConstrained(permitted, email)) + { + throw new PkixNameConstraintValidatorException( + "Subject email address is not from a permitted subtree."); + } + } + + private bool IsEmailConstrained(ISet constraints, string email) + { + foreach (string constraint in constraints) + { + if (IsEmailConstrained(constraint, email)) + return true; + } + + return false; + } + + private bool IsEmailConstrained(string constraint, string email) + { + string sub = email.Substring(email.IndexOf('@') + 1); + // a particular mailbox + if (constraint.IndexOf('@') != -1) + { + if (string.Equals(email, constraint, StringComparison.OrdinalIgnoreCase)) + return true; + } + // on particular host + else if (constraint[0] != '.') + { + if (string.Equals(sub, constraint, StringComparison.OrdinalIgnoreCase)) + return true; + } + // address in sub domain + else if (WithinDomain(sub, constraint)) + { + return true; + } + return false; + } + private ISet IntersectEmail(ISet permitted, ISet emails) { var intersect = new HashSet(); @@ -232,179 +352,506 @@ namespace Org.BouncyCastle.Pkix return intersect; } - private ISet UnionEmail(ISet excluded, string email) + /** + * The most restricting part from email1 and + * email2 is added to the intersection intersect. + * + * @param email1 Email address constraint 1. + * @param email2 Email address constraint 2. + * @param intersect The intersection. + */ + private void IntersectEmail(string email1, string email2, ISet intersect) { - if (excluded.Count < 1) + // email1 is a particular address + if (email1.IndexOf('@') != -1) { - if (email == null) - return excluded; - - excluded.Add(email); - return excluded; + string _sub = email1.Substring(email1.IndexOf('@') + 1); + // both are a particular mailbox + if (email2.IndexOf('@') != -1) + { + if (Platform.EqualsIgnoreCase(email1, email2)) + { + intersect.Add(email1); + } + } + // email2 specifies a domain + else if (Platform.StartsWith(email2, ".")) + { + if (WithinDomain(_sub, email2)) + { + intersect.Add(email1); + } + } + // email2 specifies a particular host + else + { + if (Platform.EqualsIgnoreCase(_sub, email2)) + { + intersect.Add(email1); + } + } } - - var union = new HashSet(); - foreach (string _excluded in excluded) + // email specifies a domain + else if (Platform.StartsWith(email1, ".")) { - UnionEmail(_excluded, email, union); + if (email2.IndexOf('@') != -1) + { + string _sub = email2.Substring(email1.IndexOf('@') + 1); + if (WithinDomain(_sub, email1)) + { + intersect.Add(email2); + } + } + // email2 specifies a domain + else if (Platform.StartsWith(email2, ".")) + { + if (WithinDomain(email1, email2) || Platform.EqualsIgnoreCase(email1, email2)) + { + intersect.Add(email1); + } + else if (WithinDomain(email2, email1)) + { + intersect.Add(email2); + } + } + else + { + if (WithinDomain(email2, email1)) + { + intersect.Add(email2); + } + } } - return union; - } - - /** - * Returns the intersection of the permitted IP ranges in - * permitted with ip. - * - * @param permitted A Set of permitted IP addresses with - * their subnet mask as byte arrays. - * @param ips The IP address with its subnet mask. - * @return The Set of permitted IP ranges intersected with - * ip. - */ - private ISet IntersectIP(ISet permitted, ISet ips) - { - var intersect = new HashSet(); - foreach (GeneralSubtree subtree in ips) + // email1 specifies a host + else { - byte[] ip = Asn1OctetString.GetInstance(subtree.Base.Name).GetOctets(); - if (permitted == null) + if (email2.IndexOf('@') != -1) { - if (ip != null) + string _sub = email2.Substring(email2.IndexOf('@') + 1); + if (Platform.EqualsIgnoreCase(_sub, email1)) { - intersect.Add(ip); + intersect.Add(email2); + } + } + // email2 specifies a domain + else if (Platform.StartsWith(email2, ".")) + { + if (WithinDomain(email1, email2)) + { + intersect.Add(email1); } } + // email2 specifies a particular host else { - foreach (byte[] _permitted in permitted) + if (Platform.EqualsIgnoreCase(email1, email2)) { - intersect.UnionWith(IntersectIPRange(_permitted, ip)); + intersect.Add(email1); } } } - return intersect; } - /** - * Returns the union of the excluded IP ranges in excluded - * with ip. - * - * @param excluded A Set of excluded IP addresses with their - * subnet mask as byte arrays. - * @param ip The IP address with its subnet mask. - * @return The Set of excluded IP ranges unified with - * ip as byte arrays. - */ - private ISet UnionIP(ISet excluded, byte[] ip) + private ISet UnionEmail(ISet excluded, string email) { if (excluded.Count < 1) { - if (ip == null) + if (email == null) return excluded; - excluded.Add(ip); + excluded.Add(email); return excluded; } - var union = new HashSet(); - foreach (byte[] _excluded in excluded) + var union = new HashSet(); + foreach (string _excluded in excluded) { - union.UnionWith(UnionIPRange(_excluded, ip)); + UnionEmail(_excluded, email, union); } return union; } /** - * Calculates the union if two IP ranges. + * The common part of email1 and email2 is + * added to the union union. If email1 and + * email2 have nothing in common they are added both. * - * @param ipWithSubmask1 The first IP address with its subnet mask. - * @param ipWithSubmask2 The second IP address with its subnet mask. - * @return A Set with the union of both addresses. + * @param email1 Email address constraint 1. + * @param email2 Email address constraint 2. + * @param union The union. */ - private ISet UnionIPRange(byte[] ipWithSubmask1, byte[] ipWithSubmask2) + private void UnionEmail(string email1, string email2, ISet union) { - var set = new HashSet(); - // difficult, adding always all IPs is not wrong - if (Arrays.AreEqual(ipWithSubmask1, ipWithSubmask2)) + // email1 is a particular address + if (email1.IndexOf('@') != -1) { - set.Add(ipWithSubmask1); + string _sub = email1.Substring(email1.IndexOf('@') + 1); + // both are a particular mailbox + if (email2.IndexOf('@') != -1) + { + if (Platform.EqualsIgnoreCase(email1, email2)) + { + union.Add(email1); + } + else + { + union.Add(email1); + union.Add(email2); + } + } + // email2 specifies a domain + else if (Platform.StartsWith(email2, ".")) + { + if (WithinDomain(_sub, email2)) + { + union.Add(email2); + } + else + { + union.Add(email1); + union.Add(email2); + } + } + // email2 specifies a particular host + else + { + if (Platform.EqualsIgnoreCase(_sub, email2)) + { + union.Add(email2); + } + else + { + union.Add(email1); + union.Add(email2); + } + } + } + // email1 specifies a domain + else if (Platform.StartsWith(email1, ".")) + { + if (email2.IndexOf('@') != -1) + { + string _sub = email2.Substring(email1.IndexOf('@') + 1); + if (WithinDomain(_sub, email1)) + { + union.Add(email1); + } + else + { + union.Add(email1); + union.Add(email2); + } + } + // email2 specifies a domain + else if (Platform.StartsWith(email2, ".")) + { + if (WithinDomain(email1, email2) || Platform.EqualsIgnoreCase(email1, email2)) + { + union.Add(email2); + } + else if (WithinDomain(email2, email1)) + { + union.Add(email1); + } + else + { + union.Add(email1); + union.Add(email2); + } + } + else + { + if (WithinDomain(email2, email1)) + { + union.Add(email1); + } + else + { + union.Add(email1); + union.Add(email2); + } + } } + // email specifies a host else { - set.Add(ipWithSubmask1); - set.Add(ipWithSubmask2); + if (email2.IndexOf('@') != -1) + { + string _sub = email2.Substring(email1.IndexOf('@') + 1); + if (Platform.EqualsIgnoreCase(_sub, email1)) + { + union.Add(email1); + } + else + { + union.Add(email1); + union.Add(email2); + } + } + // email2 specifies a domain + else if (Platform.StartsWith(email2, ".")) + { + if (WithinDomain(email1, email2)) + { + union.Add(email2); + } + else + { + union.Add(email1); + union.Add(email2); + } + } + // email2 specifies a particular host + else + { + if (Platform.EqualsIgnoreCase(email1, email2)) + { + union.Add(email1); + } + else + { + union.Add(email1); + union.Add(email2); + } + } } - return set; } + #endregion + + #region IP + /** - * Calculates the interesction if two IP ranges. + * Checks if the IP ip is included in the excluded ISet + * excluded. * - * @param ipWithSubmask1 The first IP address with its subnet mask. - * @param ipWithSubmask2 The second IP address with its subnet mask. - * @return A Set with the single IP address with its subnet - * mask as a byte array or an empty Set. + * @param excluded A Set of excluded IP addresses with their + * subnet mask as byte arrays. + * @param ip The IP address. + * @throws PkixNameConstraintValidatorException + * if the IP is excluded. */ - private ISet IntersectIPRange(byte[] ipWithSubmask1, byte[] ipWithSubmask2) + private void CheckExcludedIP(ISet excluded, byte[] ip) { - if (ipWithSubmask1.Length != ipWithSubmask2.Length) + if (IsIPConstrained(excluded, ip)) + throw new PkixNameConstraintValidatorException("IP is from an excluded subtree."); + } + + /** + * Checks if the IP ip is included in the permitted ISet + * permitted. + * + * @param permitted A Set of permitted IP addresses with + * their subnet mask as byte arrays. + * @param ip The IP address. + * @throws PkixNameConstraintValidatorException + * if the IP is not permitted. + */ + private void CheckPermittedIP(ISet permitted, byte[] ip) + { + if (permitted != null + && !(ip.Length == 0 && permitted.Count < 1) + && !IsIPConstrained(permitted, ip)) { - //Collections.EMPTY_SET; - return new HashSet(); + throw new PkixNameConstraintValidatorException("IP is not from a permitted subtree."); } + } - byte[][] temp = ExtractIPsAndSubnetMasks(ipWithSubmask1, ipWithSubmask2); - byte[] ip1 = temp[0]; - byte[] subnetmask1 = temp[1]; - byte[] ip2 = temp[2]; - byte[] subnetmask2 = temp[3]; - - byte[][] minMax = MinMaxIPs(ip1, subnetmask1, ip2, subnetmask2); - byte[] min; - byte[] max; - max = Min(minMax[1], minMax[3]); - min = Max(minMax[0], minMax[2]); - - // minimum IP address must be bigger than max - if (CompareTo(min, max) == 1) + private bool IsIPConstrained(ISet constraints, byte[] ip) + { + foreach (byte[] constraint in constraints) { - //return Collections.EMPTY_SET; - return new HashSet(); + if (IsIPConstrained(constraint, ip)) + return true; } - // OR keeps all significant bits - byte[] ip = Or(minMax[0], minMax[2]); - byte[] subnetmask = Or(subnetmask1, subnetmask2); - - //return new HashSet( ICollectionsingleton(IpWithSubnetMask(ip, subnetmask)); - var hs = new HashSet(); - hs.Add(IpWithSubnetMask(ip, subnetmask)); - return hs; + return false; } /** - * Concatenates the IP address with its subnet mask. + * Checks if the IP address ip is constrained by + * constraint. * + * @param constraint The constraint. This is an IP address concatenated with + * its subnetmask. * @param ip The IP address. - * @param subnetMask Its subnet mask. - * @return The concatenated IP address with its subnet mask. + * @return true if constrained, false + * otherwise. */ - private byte[] IpWithSubnetMask(byte[] ip, byte[] subnetMask) + private bool IsIPConstrained(byte[] constraint, byte[] ip) { int ipLength = ip.Length; - byte[] temp = new byte[ipLength * 2]; - Array.Copy(ip, 0, temp, 0, ipLength); - Array.Copy(subnetMask, 0, temp, ipLength, ipLength); - return temp; + if (ipLength != (constraint.Length / 2)) + return false; + + byte[] subnetMask = new byte[ipLength]; + Array.Copy(constraint, ipLength, subnetMask, 0, ipLength); + + byte[] permittedSubnetAddress = new byte[ipLength]; + + byte[] ipSubnetAddress = new byte[ipLength]; + + // the resulting IP address by applying the subnet mask + for (int i = 0; i < ipLength; i++) + { + permittedSubnetAddress[i] = (byte)(constraint[i] & subnetMask[i]); + ipSubnetAddress[i] = (byte)(ip[i] & subnetMask[i]); + } + + return Arrays.AreEqual(permittedSubnetAddress, ipSubnetAddress); } /** - * Splits the IP addresses and their subnet mask. + * Returns the intersection of the permitted IP ranges in + * permitted with ip. * - * @param ipWithSubmask1 The first IP address with the subnet mask. - * @param ipWithSubmask2 The second IP address with the subnet mask. - * @return An array with two elements. Each element contains the IP address - * and the subnet mask in this order. + * @param permitted A Set of permitted IP addresses with + * their subnet mask as byte arrays. + * @param ips The IP address with its subnet mask. + * @return The Set of permitted IP ranges intersected with + * ip. + */ + private ISet IntersectIP(ISet permitted, ISet ips) + { + var intersect = new HashSet(); + foreach (GeneralSubtree subtree in ips) + { + byte[] ip = Asn1OctetString.GetInstance(subtree.Base.Name).GetOctets(); + if (permitted == null) + { + if (ip != null) + { + intersect.Add(ip); + } + } + else + { + foreach (byte[] _permitted in permitted) + { + intersect.UnionWith(IntersectIPRange(_permitted, ip)); + } + } + } + return intersect; + } + + /** + * Calculates the interesction if two IP ranges. + * + * @param ipWithSubmask1 The first IP address with its subnet mask. + * @param ipWithSubmask2 The second IP address with its subnet mask. + * @return A Set with the single IP address with its subnet + * mask as a byte array or an empty Set. + */ + private ISet IntersectIPRange(byte[] ipWithSubmask1, byte[] ipWithSubmask2) + { + if (ipWithSubmask1.Length != ipWithSubmask2.Length) + return new HashSet(); + + byte[][] temp = ExtractIPsAndSubnetMasks(ipWithSubmask1, ipWithSubmask2); + byte[] ip1 = temp[0]; + byte[] subnetmask1 = temp[1]; + byte[] ip2 = temp[2]; + byte[] subnetmask2 = temp[3]; + + byte[][] minMax = MinMaxIPs(ip1, subnetmask1, ip2, subnetmask2); + byte[] min; + byte[] max; + max = Min(minMax[1], minMax[3]); + min = Max(minMax[0], minMax[2]); + + // minimum IP address must be bigger than max + if (CompareTo(min, max) == 1) + { + //return Collections.EMPTY_SET; + return new HashSet(); + } + // OR keeps all significant bits + byte[] ip = Or(minMax[0], minMax[2]); + byte[] subnetmask = Or(subnetmask1, subnetmask2); + + //return new HashSet( ICollectionsingleton(IpWithSubnetMask(ip, subnetmask)); + var hs = new HashSet(); + hs.Add(IpWithSubnetMask(ip, subnetmask)); + + return hs; + } + + /** + * Returns the union of the excluded IP ranges in excluded + * with ip. + * + * @param excluded A Set of excluded IP addresses with their + * subnet mask as byte arrays. + * @param ip The IP address with its subnet mask. + * @return The Set of excluded IP ranges unified with + * ip as byte arrays. + */ + private ISet UnionIP(ISet excluded, byte[] ip) + { + if (excluded.Count < 1) + { + if (ip == null) + return excluded; + + excluded.Add(ip); + return excluded; + } + + var union = new HashSet(); + foreach (byte[] _excluded in excluded) + { + union.UnionWith(UnionIPRange(_excluded, ip)); + } + return union; + } + + /** + * Calculates the union if two IP ranges. + * + * @param ipWithSubmask1 The first IP address with its subnet mask. + * @param ipWithSubmask2 The second IP address with its subnet mask. + * @return A Set with the union of both addresses. + */ + private ISet UnionIPRange(byte[] ipWithSubmask1, byte[] ipWithSubmask2) + { + var set = new HashSet(); + // difficult, adding always all IPs is not wrong + if (Arrays.AreEqual(ipWithSubmask1, ipWithSubmask2)) + { + set.Add(ipWithSubmask1); + } + else + { + set.Add(ipWithSubmask1); + set.Add(ipWithSubmask2); + } + return set; + } + + /** + * Concatenates the IP address with its subnet mask. + * + * @param ip The IP address. + * @param subnetMask Its subnet mask. + * @return The concatenated IP address with its subnet mask. + */ + private byte[] IpWithSubnetMask(byte[] ip, byte[] subnetMask) + { + int ipLength = ip.Length; + byte[] temp = new byte[ipLength * 2]; + Array.Copy(ip, 0, temp, 0, ipLength); + Array.Copy(subnetMask, 0, temp, ipLength, ipLength); + return temp; + } + + /** + * Splits the IP addresses and their subnet mask. + * + * @param ipWithSubmask1 The first IP address with the subnet mask. + * @param ipWithSubmask2 The second IP address with the subnet mask. + * @return An array with two elements. Each element contains the IP address + * and the subnet mask in this order. */ private byte[][] ExtractIPsAndSubnetMasks( byte[] ipWithSubmask1, @@ -461,584 +908,110 @@ namespace Org.BouncyCastle.Pkix return new byte[][]{ min1, max1, min2, max2 }; } - private bool IsOtherNameConstrained(OtherName constraint, OtherName otherName) - { - return constraint.Equals(otherName); - } - - private bool IsOtherNameConstrained(ISet constraints, OtherName otherName) - { - foreach (OtherName constraint in constraints) - { - if (IsOtherNameConstrained(constraint, otherName)) - return true; - } - - return false; - } - - private void CheckPermittedOtherName(ISet permitted, OtherName name) - { - if (permitted != null && !IsOtherNameConstrained(permitted, name)) - throw new PkixNameConstraintValidatorException("Subject OtherName is not from a permitted subtree."); - } - - private void CheckExcludedOtherName(ISet excluded, OtherName name) - { - if (IsOtherNameConstrained(excluded, name)) - throw new PkixNameConstraintValidatorException("OtherName is from an excluded subtree."); - } - - private bool IsEmailConstrained(string constraint, string email) - { - string sub = email.Substring(email.IndexOf('@') + 1); - // a particular mailbox - if (constraint.IndexOf('@') != -1) - { - if (string.Equals(email, constraint, StringComparison.OrdinalIgnoreCase)) - return true; - } - // on particular host - else if (constraint[0] != '.') - { - if (string.Equals(sub, constraint, StringComparison.OrdinalIgnoreCase)) - return true; - } - // address in sub domain - else if (WithinDomain(sub, constraint)) - { - return true; - } - return false; - } - - private bool IsEmailConstrained(ISet constraints, string email) - { - foreach (string constraint in constraints) - { - if (IsEmailConstrained(constraint, email)) - return true; - } - - return false; - } - - private void CheckPermittedEmail(ISet permitted, string email) - { - if (permitted != null - && !(email.Length == 0 && permitted.Count < 1) - && !IsEmailConstrained(permitted, email)) - { - throw new PkixNameConstraintValidatorException( - "Subject email address is not from a permitted subtree."); - } - } - - private void CheckExcludedEmail(ISet excluded, string email) - { - if (IsEmailConstrained(excluded, email)) - throw new PkixNameConstraintValidatorException("Email address is from an excluded subtree."); - } - - private bool IsDnsConstrained(string constraint, string dns) - { - return WithinDomain(dns, constraint) || Platform.EqualsIgnoreCase(dns, constraint); - } - - private bool IsDnsConstrained(ISet constraints, string dns) - { - foreach (var constraint in constraints) - { - if (IsDnsConstrained(constraint, dns)) - return true; - } - - return false; - } - - private void CheckPermittedDns(ISet permitted, string dns) + /** + * Returns the maximum IP address. + * + * @param ip1 The first IP address. + * @param ip2 The second IP address. + * @return The maximum IP address. + */ + private static byte[] Max(byte[] ip1, byte[] ip2) { - if (permitted != null - && !(dns.Length == 0 && permitted.Count < 1) - && !IsDnsConstrained(permitted, dns)) + for (int i = 0; i < ip1.Length; i++) { - throw new PkixNameConstraintValidatorException("DNS is not from a permitted subtree."); + if (ip1[i] > ip2[i]) + return ip1; } - } - - private void CheckExcludedDns(ISet excluded, string dns) - { - if (IsDnsConstrained(excluded, dns)) - throw new PkixNameConstraintValidatorException("DNS is from an excluded subtree."); - } - - private bool IsDirectoryConstrained(ISet constraints, Asn1Sequence directory) - { - foreach (var constraint in constraints) - { - if (WithinDNSubtree(directory, constraint)) - return true; - } - - return false; - } - - private void CheckPermittedDirectory(ISet permitted, Asn1Sequence directory) - { - if (permitted != null - && !(directory.Count == 0 && permitted.Count < 1) - && !IsDirectoryConstrained(permitted, directory)) - { - throw new PkixNameConstraintValidatorException( - "Subject distinguished name is not from a permitted subtree"); - } - } - - private void CheckExcludedDirectory(ISet excluded, Asn1Sequence directory) - { - if (IsDirectoryConstrained(excluded, directory)) - { - throw new PkixNameConstraintValidatorException( - "Subject distinguished name is from an excluded subtree"); - } - } - - private bool IsUriConstrained(string constraint, string uri) - { - string host = ExtractHostFromURL(uri); - - if (Platform.StartsWith(constraint, ".")) - { - // in sub domain or domain - return WithinDomain(host, constraint); - } - - // a host - return Platform.EqualsIgnoreCase(host, constraint); - } - - private bool IsUriConstrained(ISet constraints, string uri) - { - foreach (string constraint in constraints) - { - if (IsUriConstrained(constraint, uri)) - return true; - } - - return false; - } - - private void CheckPermittedUri(ISet permitted, string uri) - { - if (permitted != null - && !(uri.Length == 0 && permitted.Count < 1) - && !IsUriConstrained(permitted, uri)) - { - throw new PkixNameConstraintValidatorException("URI is not from a permitted subtree."); - } - } - - private void CheckExcludedUri(ISet excluded, string uri) - { - if (IsUriConstrained(excluded, uri)) - throw new PkixNameConstraintValidatorException("URI is from an excluded subtree."); - } - - /** - * Checks if the IP address ip is constrained by - * constraint. - * - * @param constraint The constraint. This is an IP address concatenated with - * its subnetmask. - * @param ip The IP address. - * @return true if constrained, false - * otherwise. - */ - private bool IsIPConstrained(byte[] constraint, byte[] ip) - { - int ipLength = ip.Length; - if (ipLength != (constraint.Length / 2)) - return false; - - byte[] subnetMask = new byte[ipLength]; - Array.Copy(constraint, ipLength, subnetMask, 0, ipLength); - - byte[] permittedSubnetAddress = new byte[ipLength]; - - byte[] ipSubnetAddress = new byte[ipLength]; - - // the resulting IP address by applying the subnet mask - for (int i = 0; i < ipLength; i++) - { - permittedSubnetAddress[i] = (byte)(constraint[i] & subnetMask[i]); - ipSubnetAddress[i] = (byte)(ip[i] & subnetMask[i]); - } - - return Arrays.AreEqual(permittedSubnetAddress, ipSubnetAddress); - } - - private bool IsIPConstrained(ISet constraints, byte[] ip) - { - foreach (byte[] constraint in constraints) - { - if (IsIPConstrained(constraint, ip)) - return true; - } - - return false; - } - - /** - * Checks if the IP ip is included in the permitted ISet - * permitted. - * - * @param permitted A Set of permitted IP addresses with - * their subnet mask as byte arrays. - * @param ip The IP address. - * @throws PkixNameConstraintValidatorException - * if the IP is not permitted. - */ - private void CheckPermittedIP(ISet permitted, byte[] ip) - { - if (permitted != null - && !(ip.Length == 0 && permitted.Count < 1) - && !IsIPConstrained(permitted, ip)) - { - throw new PkixNameConstraintValidatorException("IP is not from a permitted subtree."); - } - } - - /** - * Checks if the IP ip is included in the excluded ISet - * excluded. - * - * @param excluded A Set of excluded IP addresses with their - * subnet mask as byte arrays. - * @param ip The IP address. - * @throws PkixNameConstraintValidatorException - * if the IP is excluded. - */ - private void CheckExcludedIP(ISet excluded, byte[] ip) - { - if (IsIPConstrained(excluded, ip)) - throw new PkixNameConstraintValidatorException("IP is from an excluded subtree."); - } - - private bool WithinDomain(string testDomain, string domain) - { - string tempDomain = domain; - if (Platform.StartsWith(tempDomain, ".")) - { - tempDomain = tempDomain.Substring(1); - } - - string[] domainParts = tempDomain.Split('.'); // Strings.split(tempDomain, '.'); - string[] testDomainParts = testDomain.Split('.'); // Strings.split(testDomain, '.'); - - // must have at least one subdomain - if (testDomainParts.Length <= domainParts.Length) - return false; - - int d = testDomainParts.Length - domainParts.Length; - for (int i = -1; i < domainParts.Length; i++) - { - if (i == -1) - { - if (testDomainParts[i + d].Length < 1) - { - return false; - } - } - else if (!Platform.EqualsIgnoreCase(testDomainParts[i + d], domainParts[i])) - { - return false; - } - } - return true; + return ip2; } /** - * The common part of email1 and email2 is - * added to the union union. If email1 and - * email2 have nothing in common they are added both. + * Returns the minimum IP address. * - * @param email1 Email address constraint 1. - * @param email2 Email address constraint 2. - * @param union The union. - */ - private void UnionEmail(string email1, string email2, ISet union) - { - // email1 is a particular address - if (email1.IndexOf('@') != -1) - { - string _sub = email1.Substring(email1.IndexOf('@') + 1); - // both are a particular mailbox - if (email2.IndexOf('@') != -1) - { - if (Platform.EqualsIgnoreCase(email1, email2)) - { - union.Add(email1); - } - else - { - union.Add(email1); - union.Add(email2); - } - } - // email2 specifies a domain - else if (Platform.StartsWith(email2, ".")) - { - if (WithinDomain(_sub, email2)) - { - union.Add(email2); - } - else - { - union.Add(email1); - union.Add(email2); - } - } - // email2 specifies a particular host - else - { - if (Platform.EqualsIgnoreCase(_sub, email2)) - { - union.Add(email2); - } - else - { - union.Add(email1); - union.Add(email2); - } - } - } - // email1 specifies a domain - else if (Platform.StartsWith(email1, ".")) - { - if (email2.IndexOf('@') != -1) - { - string _sub = email2.Substring(email1.IndexOf('@') + 1); - if (WithinDomain(_sub, email1)) - { - union.Add(email1); - } - else - { - union.Add(email1); - union.Add(email2); - } - } - // email2 specifies a domain - else if (Platform.StartsWith(email2, ".")) - { - if (WithinDomain(email1, email2) || Platform.EqualsIgnoreCase(email1, email2)) - { - union.Add(email2); - } - else if (WithinDomain(email2, email1)) - { - union.Add(email1); - } - else - { - union.Add(email1); - union.Add(email2); - } - } - else - { - if (WithinDomain(email2, email1)) - { - union.Add(email1); - } - else - { - union.Add(email1); - union.Add(email2); - } - } - } - // email specifies a host - else - { - if (email2.IndexOf('@') != -1) - { - string _sub = email2.Substring(email1.IndexOf('@') + 1); - if (Platform.EqualsIgnoreCase(_sub, email1)) - { - union.Add(email1); - } - else - { - union.Add(email1); - union.Add(email2); - } - } - // email2 specifies a domain - else if (Platform.StartsWith(email2, ".")) - { - if (WithinDomain(email1, email2)) - { - union.Add(email2); - } - else - { - union.Add(email1); - union.Add(email2); - } - } - // email2 specifies a particular host - else - { - if (Platform.EqualsIgnoreCase(email1, email2)) - { - union.Add(email1); - } - else - { - union.Add(email1); - union.Add(email2); - } - } + * @param ip1 The first IP address. + * @param ip2 The second IP address. + * @return The minimum IP address. + */ + private static byte[] Min(byte[] ip1, byte[] ip2) + { + for (int i = 0; i < ip1.Length; i++) + { + if (ip1[i] < ip2[i]) + return ip1; } + return ip2; } - private void UnionUri(string email1, string email2, ISet union) + /** + * Compares IP address ip1 with ip2. If ip1 + * is equal to ip2 0 is returned. If ip1 is bigger 1 is returned, -1 + * otherwise. + * + * @param ip1 The first IP address. + * @param ip2 The second IP address. + * @return 0 if ip1 is equal to ip2, 1 if ip1 is bigger, -1 otherwise. + */ + private static int CompareTo(byte[] ip1, byte[] ip2) { - // email1 is a particular address - if (email1.IndexOf('@') != -1) - { - string _sub = email1.Substring(email1.IndexOf('@') + 1); - // both are a particular mailbox - if (email2.IndexOf('@') != -1) - { - if (Platform.EqualsIgnoreCase(email1, email2)) - { - union.Add(email1); - } - else - { - union.Add(email1); - union.Add(email2); - } - } - // email2 specifies a domain - else if (Platform.StartsWith(email2, ".")) - { - if (WithinDomain(_sub, email2)) - { - union.Add(email2); - } - else - { - union.Add(email1); - union.Add(email2); - } - } - // email2 specifies a particular host - else - { - if (Platform.EqualsIgnoreCase(_sub, email2)) - { - union.Add(email2); - } - else - { - union.Add(email1); - union.Add(email2); + if (Arrays.AreEqual(ip1, ip2)) + return 0; + if (Arrays.AreEqual(Max(ip1, ip2), ip1)) + return 1; + return -1; + } - } - } + /** + * Returns the logical OR of the IP addresses ip1 and + * ip2. + * + * @param ip1 The first IP address. + * @param ip2 The second IP address. + * @return The OR of ip1 and ip2. + */ + private static byte[] Or(byte[] ip1, byte[] ip2) + { + byte[] temp = new byte[ip1.Length]; + for (int i = 0; i < ip1.Length; i++) + { + temp[i] = (byte)(ip1[i] | ip2[i]); } - // email1 specifies a domain - else if (Platform.StartsWith(email1, ".")) + return temp; + } + + #endregion + + #region Dns + + private void CheckExcludedDns(ISet excluded, string dns) + { + if (IsDnsConstrained(excluded, dns)) + throw new PkixNameConstraintValidatorException("DNS is from an excluded subtree."); + } + + private void CheckPermittedDns(ISet permitted, string dns) + { + if (permitted != null + && !(dns.Length == 0 && permitted.Count < 1) + && !IsDnsConstrained(permitted, dns)) { - if (email2.IndexOf('@') != -1) - { - string _sub = email2.Substring(email1.IndexOf('@') + 1); - if (WithinDomain(_sub, email1)) - { - union.Add(email1); - } - else - { - union.Add(email1); - union.Add(email2); - } - } - // email2 specifies a domain - else if (Platform.StartsWith(email2, ".")) - { - if (WithinDomain(email1, email2) || Platform.EqualsIgnoreCase(email1, email2)) - { - union.Add(email2); - } - else if (WithinDomain(email2, email1)) - { - union.Add(email1); - } - else - { - union.Add(email1); - union.Add(email2); - } - } - else - { - if (WithinDomain(email2, email1)) - { - union.Add(email1); - } - else - { - union.Add(email1); - union.Add(email2); - } - } + throw new PkixNameConstraintValidatorException("DNS is not from a permitted subtree."); } - // email specifies a host - else + } + + private bool IsDnsConstrained(ISet constraints, string dns) + { + foreach (var constraint in constraints) { - if (email2.IndexOf('@') != -1) - { - string _sub = email2.Substring(email1.IndexOf('@') + 1); - if (Platform.EqualsIgnoreCase(_sub, email1)) - { - union.Add(email1); - } - else - { - union.Add(email1); - union.Add(email2); - } - } - // email2 specifies a domain - else if (Platform.StartsWith(email2, ".")) - { - if (WithinDomain(email1, email2)) - { - union.Add(email2); - } - else - { - union.Add(email1); - union.Add(email2); - } - } - // email2 specifies a particular host - else - { - if (Platform.EqualsIgnoreCase(email1, email2)) - { - union.Add(email1); - } - else - { - union.Add(email1); - union.Add(email2); - } - } + if (IsDnsConstrained(constraint, dns)) + return true; } + + return false; + } + + private bool IsDnsConstrained(string constraint, string dns) + { + return WithinDomain(dns, constraint) || Platform.EqualsIgnoreCase(dns, constraint); } private ISet IntersectDns(ISet permitted, ISet dnss) @@ -1074,44 +1047,105 @@ namespace Org.BouncyCastle.Pkix private ISet UnionDns(ISet excluded, string dns) { - if (excluded.Count < 1) - { - if (dns == null) - return excluded; + if (excluded.Count < 1) + { + if (dns == null) + return excluded; + + excluded.Add(dns); + return excluded; + } + + var union = new HashSet(); + foreach (string _excluded in excluded) + { + if (WithinDomain(_excluded, dns)) + { + union.Add(dns); + } + else if (WithinDomain(dns, _excluded)) + { + union.Add(_excluded); + } + else + { + union.Add(_excluded); + union.Add(dns); + } + } + return union; + } + + #endregion + + #region Uri + + private void CheckExcludedUri(ISet excluded, string uri) + { + if (IsUriConstrained(excluded, uri)) + throw new PkixNameConstraintValidatorException("URI is from an excluded subtree."); + } + + private void CheckPermittedUri(ISet permitted, string uri) + { + if (permitted != null + && !(uri.Length == 0 && permitted.Count < 1) + && !IsUriConstrained(permitted, uri)) + { + throw new PkixNameConstraintValidatorException("URI is not from a permitted subtree."); + } + } + + private bool IsUriConstrained(ISet constraints, string uri) + { + foreach (string constraint in constraints) + { + if (IsUriConstrained(constraint, uri)) + return true; + } + + return false; + } + + private bool IsUriConstrained(string constraint, string uri) + { + string host = ExtractHostFromURL(uri); - excluded.Add(dns); - return excluded; + if (Platform.StartsWith(constraint, ".")) + { + // in sub domain or domain + return WithinDomain(host, constraint); } - var union = new HashSet(); - foreach (string _excluded in excluded) + // a host + return Platform.EqualsIgnoreCase(host, constraint); + } + + private ISet IntersectUri(ISet permitted, ISet uris) + { + var intersect = new HashSet(); + foreach (GeneralSubtree subtree in uris) { - if (WithinDomain(_excluded, dns)) - { - union.Add(dns); - } - else if (WithinDomain(dns, _excluded)) + string uri = ExtractNameAsString(subtree.Base); + if (permitted == null) { - union.Add(_excluded); + if (uri != null) + { + intersect.Add(uri); + } } else { - union.Add(_excluded); - union.Add(dns); + foreach (string _permitted in permitted) + { + IntersectUri(_permitted, uri, intersect); + } } } - return union; + return intersect; } - /** - * The most restricting part from email1 and - * email2 is added to the intersection intersect. - * - * @param email1 Email address constraint 1. - * @param email2 Email address constraint 2. - * @param intersect The intersection. - */ - private void IntersectEmail(string email1, string email2, ISet intersect) + private void IntersectUri(string email1, string email2, ISet intersect) { // email1 is a particular address if (email1.IndexOf('@') != -1) @@ -1203,30 +1237,6 @@ namespace Org.BouncyCastle.Pkix } } - private ISet IntersectUri(ISet permitted, ISet uris) - { - var intersect = new HashSet(); - foreach (GeneralSubtree subtree in uris) - { - string uri = ExtractNameAsString(subtree.Base); - if (permitted == null) - { - if (uri != null) - { - intersect.Add(uri); - } - } - else - { - foreach (string _permitted in permitted) - { - IntersectUri(_permitted, uri, intersect); - } - } - } - return intersect; - } - private ISet UnionUri(ISet excluded, string uri) { if (excluded.Count < 1) @@ -1246,7 +1256,7 @@ namespace Org.BouncyCastle.Pkix return union; } - private void IntersectUri(string email1, string email2, ISet intersect) + private void UnionUri(string email1, string email2, ISet union) { // email1 is a particular address if (email1.IndexOf('@') != -1) @@ -1257,7 +1267,12 @@ namespace Org.BouncyCastle.Pkix { if (Platform.EqualsIgnoreCase(email1, email2)) { - intersect.Add(email1); + union.Add(email1); + } + else + { + union.Add(email1); + union.Add(email2); } } // email2 specifies a domain @@ -1265,7 +1280,12 @@ namespace Org.BouncyCastle.Pkix { if (WithinDomain(_sub, email2)) { - intersect.Add(email1); + union.Add(email2); + } + else + { + union.Add(email1); + union.Add(email2); } } // email2 specifies a particular host @@ -1273,11 +1293,17 @@ namespace Org.BouncyCastle.Pkix { if (Platform.EqualsIgnoreCase(_sub, email2)) { - intersect.Add(email1); + union.Add(email2); + } + else + { + union.Add(email1); + union.Add(email2); + } } } - // email specifies a domain + // email1 specifies a domain else if (Platform.StartsWith(email1, ".")) { if (email2.IndexOf('@') != -1) @@ -1285,7 +1311,12 @@ namespace Org.BouncyCastle.Pkix string _sub = email2.Substring(email1.IndexOf('@') + 1); if (WithinDomain(_sub, email1)) { - intersect.Add(email2); + union.Add(email1); + } + else + { + union.Add(email1); + union.Add(email2); } } // email2 specifies a domain @@ -1293,30 +1324,45 @@ namespace Org.BouncyCastle.Pkix { if (WithinDomain(email1, email2) || Platform.EqualsIgnoreCase(email1, email2)) { - intersect.Add(email1); + union.Add(email2); } else if (WithinDomain(email2, email1)) { - intersect.Add(email2); + union.Add(email1); + } + else + { + union.Add(email1); + union.Add(email2); } } else { if (WithinDomain(email2, email1)) { - intersect.Add(email2); + union.Add(email1); + } + else + { + union.Add(email1); + union.Add(email2); } } } - // email1 specifies a host + // email specifies a host else { if (email2.IndexOf('@') != -1) { - string _sub = email2.Substring(email2.IndexOf('@') + 1); + string _sub = email2.Substring(email1.IndexOf('@') + 1); if (Platform.EqualsIgnoreCase(_sub, email1)) { - intersect.Add(email2); + union.Add(email1); + } + else + { + union.Add(email1); + union.Add(email2); } } // email2 specifies a domain @@ -1324,7 +1370,12 @@ namespace Org.BouncyCastle.Pkix { if (WithinDomain(email1, email2)) { - intersect.Add(email1); + union.Add(email2); + } + else + { + union.Add(email1); + union.Add(email2); } } // email2 specifies a particular host @@ -1332,7 +1383,12 @@ namespace Org.BouncyCastle.Pkix { if (Platform.EqualsIgnoreCase(email1, email2)) { - intersect.Add(email1); + union.Add(email1); + } + else + { + union.Add(email1); + union.Add(email2); } } } @@ -1365,6 +1421,39 @@ namespace Org.BouncyCastle.Pkix return sub; } + #endregion + + private bool WithinDomain(string testDomain, string domain) + { + string tempDomain = domain; + if (Platform.StartsWith(tempDomain, ".")) + { + tempDomain = tempDomain.Substring(1); + } + + string[] domainParts = tempDomain.Split('.'); // Strings.split(tempDomain, '.'); + string[] testDomainParts = testDomain.Split('.'); // Strings.split(testDomain, '.'); + + // must have at least one subdomain + if (testDomainParts.Length <= domainParts.Length) + return false; + + int d = testDomainParts.Length - domainParts.Length; + for (int i = -1; i < domainParts.Length; i++) + { + if (i == -1) + { + if (testDomainParts[i + d].Length < 1) + return false; + } + else if (!Platform.EqualsIgnoreCase(testDomainParts[i + d], domainParts[i])) + { + return false; + } + } + return true; + } + /// [Obsolete("Use 'CheckPermittedName' instead")] public void checkPermitted(GeneralName name) @@ -1569,84 +1658,6 @@ namespace Org.BouncyCastle.Pkix } } - /** - * Returns the maximum IP address. - * - * @param ip1 The first IP address. - * @param ip2 The second IP address. - * @return The maximum IP address. - */ - private static byte[] Max(byte[] ip1, byte[] ip2) - { - for (int i = 0; i < ip1.Length; i++) - { - if ((ip1[i] & 0xFFFF) > (ip2[i] & 0xFFFF)) - { - return ip1; - } - } - return ip2; - } - - /** - * Returns the minimum IP address. - * - * @param ip1 The first IP address. - * @param ip2 The second IP address. - * @return The minimum IP address. - */ - private static byte[] Min(byte[] ip1, byte[] ip2) - { - for (int i = 0; i < ip1.Length; i++) - { - if ((ip1[i] & 0xFFFF) < (ip2[i] & 0xFFFF)) - { - return ip1; - } - } - return ip2; - } - - /** - * Compares IP address ip1 with ip2. If ip1 - * is equal to ip2 0 is returned. If ip1 is bigger 1 is returned, -1 - * otherwise. - * - * @param ip1 The first IP address. - * @param ip2 The second IP address. - * @return 0 if ip1 is equal to ip2, 1 if ip1 is bigger, -1 otherwise. - */ - private static int CompareTo(byte[] ip1, byte[] ip2) - { - if (Org.BouncyCastle.Utilities.Arrays.AreEqual(ip1, ip2)) - { - return 0; - } - if (Org.BouncyCastle.Utilities.Arrays.AreEqual(Max(ip1, ip2), ip1)) - { - return 1; - } - return -1; - } - - /** - * Returns the logical OR of the IP addresses ip1 and - * ip2. - * - * @param ip1 The first IP address. - * @param ip2 The second IP address. - * @return The OR of ip1 and ip2. - */ - private static byte[] Or(byte[] ip1, byte[] ip2) - { - byte[] temp = new byte[ip1.Length]; - for (int i = 0; i < ip1.Length; i++) - { - temp[i] = (byte)(ip1[i] | ip2[i]); - } - return temp; - } - public override int GetHashCode() { return HashCollection(excludedSubtreesDN) -- cgit 1.4.1