diff options
Diffstat (limited to 'crypto/src/pkix/PkixNameConstraintValidator.cs')
-rw-r--r-- | crypto/src/pkix/PkixNameConstraintValidator.cs | 206 |
1 files changed, 101 insertions, 105 deletions
diff --git a/crypto/src/pkix/PkixNameConstraintValidator.cs b/crypto/src/pkix/PkixNameConstraintValidator.cs index f4ae73925..4d5af28ea 100644 --- a/crypto/src/pkix/PkixNameConstraintValidator.cs +++ b/crypto/src/pkix/PkixNameConstraintValidator.cs @@ -2,6 +2,8 @@ using System; using System.Collections; using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.X500; +using Org.BouncyCastle.Asn1.X500.Style; using Org.BouncyCastle.Asn1.X509; using Org.BouncyCastle.Utilities; using Org.BouncyCastle.Utilities.Collections; @@ -10,6 +12,10 @@ namespace Org.BouncyCastle.Pkix { public class PkixNameConstraintValidator { + // TODO Implement X500Name and styles + //private static readonly DerObjectIdentifier SerialNumberOid = Rfc4519Style.SerialNumber; + private static readonly DerObjectIdentifier SerialNumberOid = new DerObjectIdentifier("2.5.4.5"); + private ISet excludedSubtreesDN = new HashSet(); private ISet excludedSubtreesDNS = new HashSet(); @@ -38,19 +44,32 @@ namespace Org.BouncyCastle.Pkix Asn1Sequence dns, Asn1Sequence subtree) { - if (subtree.Count < 1) - { + if (subtree.Count < 1 || subtree.Count > dns.Count) return false; - } - if (subtree.Count > dns.Count) + for (int j = 0; j < subtree.Count; ++j) { - return false; - } + // both subtree and dns are a ASN.1 Name and the elements are a RDN + Rdn subtreeRdn = Rdn.GetInstance(subtree[j]); + Rdn dnsRdn = Rdn.GetInstance(dns[j]); - for (int j = subtree.Count - 1; j >= 0; j--) - { - if (!(subtree[j].Equals(dns[j]))) + // check if types and values of all naming attributes are matching, other types which are not restricted are allowed, see https://tools.ietf.org/html/rfc5280#section-7.1 + + // Two relative distinguished names + // RDN1 and RDN2 match if they have the same number of naming attributes + // and for each naming attribute in RDN1 there is a matching naming attribute in RDN2. + // NOTE: this is checking the attributes in the same order, which might be not necessary, if this is a problem also IETFUtils.rDNAreEqual mus tbe changed. + // use new RFC 5280 comparison, NOTE: this is now different from with RFC 3280, where only binary comparison is used + // obey RFC 5280 7.1 + // special treatment of serialNumber for GSMA SGP.22 RSP specification + if (subtreeRdn.Count == 1 && dnsRdn.Count == 1 + && subtreeRdn.GetFirst().GetType().Equals(SerialNumberOid) + && dnsRdn.GetFirst().GetType().Equals(SerialNumberOid)) + { + if (!Platform.StartsWith(dnsRdn.GetFirst().Value.ToString(), subtreeRdn.GetFirst().Value.ToString())) + return false; + } + else if (!IetfUtilities.RdnAreEqual(subtreeRdn, dnsRdn)) { return false; } @@ -202,7 +221,7 @@ namespace Org.BouncyCastle.Pkix ISet intersect = new HashSet(); for (IEnumerator it = emails.GetEnumerator(); it.MoveNext(); ) { - String email = ExtractNameAsString(((GeneralSubtree)it.Current) + string email = ExtractNameAsString(((GeneralSubtree)it.Current) .Base); if (permitted == null) @@ -217,7 +236,7 @@ namespace Org.BouncyCastle.Pkix IEnumerator it2 = permitted.GetEnumerator(); while (it2.MoveNext()) { - String _permitted = (String)it2.Current; + string _permitted = (string)it2.Current; intersectEmail(email, _permitted, intersect); } @@ -226,7 +245,7 @@ namespace Org.BouncyCastle.Pkix return intersect; } - private ISet UnionEmail(ISet excluded, String email) + private ISet UnionEmail(ISet excluded, string email) { if (excluded.IsEmpty) { @@ -244,9 +263,9 @@ namespace Org.BouncyCastle.Pkix IEnumerator it = excluded.GetEnumerator(); while (it.MoveNext()) { - String _excluded = (String)it.Current; + string _excluded = (string)it.Current; - unionEmail(_excluded, email, union); + UnionEmail(_excluded, email, union); } return union; @@ -476,7 +495,7 @@ namespace Org.BouncyCastle.Pkix return new byte[][] { min1, max1, min2, max2 }; } - private void CheckPermittedEmail(ISet permitted, String email) + private void CheckPermittedEmail(ISet permitted, string email) //throws PkixNameConstraintValidatorException { if (permitted == null) @@ -488,7 +507,7 @@ namespace Org.BouncyCastle.Pkix while (it.MoveNext()) { - String str = ((String)it.Current); + string str = ((string)it.Current); if (EmailIsConstrained(email, str)) { @@ -505,7 +524,7 @@ namespace Org.BouncyCastle.Pkix "Subject email address is not from a permitted subtree."); } - private void CheckExcludedEmail(ISet excluded, String email) + private void CheckExcludedEmail(ISet excluded, string email) //throws PkixNameConstraintValidatorException { if (excluded.IsEmpty) @@ -517,7 +536,7 @@ namespace Org.BouncyCastle.Pkix while (it.MoveNext()) { - String str = (String)it.Current; + string str = (string)it.Current; if (EmailIsConstrained(email, str)) { @@ -574,7 +593,7 @@ namespace Org.BouncyCastle.Pkix * @throws PkixNameConstraintValidatorException * if the IP is excluded. */ - private void checkExcludedIP(ISet excluded, byte[] ip) + private void CheckExcludedIP(ISet excluded, byte[] ip) //throws PkixNameConstraintValidatorException { if (excluded.IsEmpty) @@ -632,9 +651,9 @@ namespace Org.BouncyCastle.Pkix return Org.BouncyCastle.Utilities.Arrays.AreEqual(permittedSubnetAddress, ipSubnetAddress); } - private bool EmailIsConstrained(String email, String constraint) + private bool EmailIsConstrained(string email, string constraint) { - String sub = email.Substring(email.IndexOf('@') + 1); + string sub = email.Substring(email.IndexOf('@') + 1); // a particular mailbox if (constraint.IndexOf('@') != -1) { @@ -659,28 +678,27 @@ namespace Org.BouncyCastle.Pkix return false; } - private bool WithinDomain(String testDomain, String domain) + private bool WithinDomain(string testDomain, string domain) { - String tempDomain = 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, '.'); + + 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].Equals("")) + if (testDomainParts[i + d].Length < 1) { return false; } @@ -693,55 +711,33 @@ namespace Org.BouncyCastle.Pkix return true; } - private void CheckPermittedDNS(ISet permitted, String dns) - //throws PkixNameConstraintValidatorException + private void CheckPermittedDns(ISet permitted, string dns) + //throws PkixNameConstraintValidatorException { - if (permitted == null) - { + if (null == permitted) return; - } - - IEnumerator it = permitted.GetEnumerator(); - while (it.MoveNext()) + foreach (string str in permitted) { - String str = ((String)it.Current); - - // is sub domain - if (WithinDomain(dns, str) - || Platform.ToUpperInvariant(dns).Equals(Platform.ToUpperInvariant(str))) - { + // is sub domain or the same + if (WithinDomain(dns, str) || Platform.EqualsIgnoreCase(dns, str)) return; - } } + if (dns.Length == 0 && permitted.Count == 0) - { return; - } - throw new PkixNameConstraintValidatorException( - "DNS is not from a permitted subtree."); + + throw new PkixNameConstraintValidatorException("DNS is not from a permitted subtree."); } - private void checkExcludedDNS(ISet excluded, String dns) - // throws PkixNameConstraintValidatorException + private void CheckExcludedDns(ISet excluded, string dns) + //throws PkixNameConstraintValidatorException { - if (excluded.IsEmpty) - { - return; - } - - IEnumerator it = excluded.GetEnumerator(); - - while (it.MoveNext()) + foreach (string str in excluded) { - String str = ((String)it.Current); - // is sub domain or the same if (WithinDomain(dns, str) || Platform.EqualsIgnoreCase(dns, str)) - { - throw new PkixNameConstraintValidatorException( - "DNS is from an excluded subtree."); - } + throw new PkixNameConstraintValidatorException("DNS is from an excluded subtree."); } } @@ -754,12 +750,12 @@ namespace Org.BouncyCastle.Pkix * @param email2 Email address constraint 2. * @param union The union. */ - private void unionEmail(String email1, String email2, ISet 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); + string _sub = email1.Substring(email1.IndexOf('@') + 1); // both are a particular mailbox if (email2.IndexOf('@') != -1) { @@ -805,7 +801,7 @@ namespace Org.BouncyCastle.Pkix { if (email2.IndexOf('@') != -1) { - String _sub = email2.Substring(email1.IndexOf('@') + 1); + string _sub = email2.Substring(email1.IndexOf('@') + 1); if (WithinDomain(_sub, email1)) { union.Add(email1); @@ -851,7 +847,7 @@ namespace Org.BouncyCastle.Pkix { if (email2.IndexOf('@') != -1) { - String _sub = email2.Substring(email1.IndexOf('@') + 1); + string _sub = email2.Substring(email1.IndexOf('@') + 1); if (Platform.EqualsIgnoreCase(_sub, email1)) { union.Add(email1); @@ -891,12 +887,12 @@ namespace Org.BouncyCastle.Pkix } } - private void unionURI(String email1, String email2, ISet union) + private void unionURI(string email1, string email2, ISet union) { // email1 is a particular address if (email1.IndexOf('@') != -1) { - String _sub = email1.Substring(email1.IndexOf('@') + 1); + string _sub = email1.Substring(email1.IndexOf('@') + 1); // both are a particular mailbox if (email2.IndexOf('@') != -1) { @@ -943,7 +939,7 @@ namespace Org.BouncyCastle.Pkix { if (email2.IndexOf('@') != -1) { - String _sub = email2.Substring(email1.IndexOf('@') + 1); + string _sub = email2.Substring(email1.IndexOf('@') + 1); if (WithinDomain(_sub, email1)) { union.Add(email1); @@ -989,7 +985,7 @@ namespace Org.BouncyCastle.Pkix { if (email2.IndexOf('@') != -1) { - String _sub = email2.Substring(email1.IndexOf('@') + 1); + string _sub = email2.Substring(email1.IndexOf('@') + 1); if (Platform.EqualsIgnoreCase(_sub, email1)) { union.Add(email1); @@ -1034,7 +1030,7 @@ namespace Org.BouncyCastle.Pkix ISet intersect = new HashSet(); for (IEnumerator it = dnss.GetEnumerator(); it.MoveNext(); ) { - String dns = ExtractNameAsString(((GeneralSubtree)it.Current) + string dns = ExtractNameAsString(((GeneralSubtree)it.Current) .Base); if (permitted == null) { @@ -1048,7 +1044,7 @@ namespace Org.BouncyCastle.Pkix IEnumerator _iter = permitted.GetEnumerator(); while (_iter.MoveNext()) { - String _permitted = (String)_iter.Current; + string _permitted = (string)_iter.Current; if (WithinDomain(_permitted, dns)) { @@ -1065,7 +1061,7 @@ namespace Org.BouncyCastle.Pkix return intersect; } - protected ISet unionDNS(ISet excluded, String dns) + protected ISet unionDNS(ISet excluded, string dns) { if (excluded.IsEmpty) { @@ -1084,7 +1080,7 @@ namespace Org.BouncyCastle.Pkix IEnumerator _iter = excluded.GetEnumerator(); while (_iter.MoveNext()) { - String _permitted = (String)_iter.Current; + string _permitted = (string)_iter.Current; if (WithinDomain(_permitted, dns)) { @@ -1113,12 +1109,12 @@ namespace Org.BouncyCastle.Pkix * @param email2 Email address constraint 2. * @param intersect The intersection. */ - private void intersectEmail(String email1, String email2, ISet intersect) + private void intersectEmail(string email1, string email2, ISet intersect) { // email1 is a particular address if (email1.IndexOf('@') != -1) { - String _sub = email1.Substring(email1.IndexOf('@') + 1); + string _sub = email1.Substring(email1.IndexOf('@') + 1); // both are a particular mailbox if (email2.IndexOf('@') != -1) { @@ -1149,7 +1145,7 @@ namespace Org.BouncyCastle.Pkix { if (email2.IndexOf('@') != -1) { - String _sub = email2.Substring(email1.IndexOf('@') + 1); + string _sub = email2.Substring(email1.IndexOf('@') + 1); if (WithinDomain(_sub, email1)) { intersect.Add(email2); @@ -1180,7 +1176,7 @@ namespace Org.BouncyCastle.Pkix { if (email2.IndexOf('@') != -1) { - String _sub = email2.Substring(email2.IndexOf('@') + 1); + string _sub = email2.Substring(email2.IndexOf('@') + 1); if (Platform.EqualsIgnoreCase(_sub, email1)) { intersect.Add(email2); @@ -1205,7 +1201,7 @@ namespace Org.BouncyCastle.Pkix } } - private void checkExcludedURI(ISet excluded, String uri) + private void checkExcludedURI(ISet excluded, string uri) // throws PkixNameConstraintValidatorException { if (excluded.IsEmpty) @@ -1217,7 +1213,7 @@ namespace Org.BouncyCastle.Pkix while (it.MoveNext()) { - String str = ((String)it.Current); + string str = ((string)it.Current); if (IsUriConstrained(uri, str)) { @@ -1232,7 +1228,7 @@ namespace Org.BouncyCastle.Pkix ISet intersect = new HashSet(); for (IEnumerator it = uris.GetEnumerator(); it.MoveNext(); ) { - String uri = ExtractNameAsString(((GeneralSubtree)it.Current) + string uri = ExtractNameAsString(((GeneralSubtree)it.Current) .Base); if (permitted == null) { @@ -1246,7 +1242,7 @@ namespace Org.BouncyCastle.Pkix IEnumerator _iter = permitted.GetEnumerator(); while (_iter.MoveNext()) { - String _permitted = (String)_iter.Current; + string _permitted = (string)_iter.Current; intersectURI(_permitted, uri, intersect); } } @@ -1254,7 +1250,7 @@ namespace Org.BouncyCastle.Pkix return intersect; } - private ISet unionURI(ISet excluded, String uri) + private ISet unionURI(ISet excluded, string uri) { if (excluded.IsEmpty) { @@ -1273,7 +1269,7 @@ namespace Org.BouncyCastle.Pkix IEnumerator _iter = excluded.GetEnumerator(); while (_iter.MoveNext()) { - String _excluded = (String)_iter.Current; + string _excluded = (string)_iter.Current; unionURI(_excluded, uri, union); } @@ -1282,12 +1278,12 @@ namespace Org.BouncyCastle.Pkix } } - private void intersectURI(String email1, String email2, ISet intersect) + private void intersectURI(string email1, string email2, ISet intersect) { // email1 is a particular address if (email1.IndexOf('@') != -1) { - String _sub = email1.Substring(email1.IndexOf('@') + 1); + string _sub = email1.Substring(email1.IndexOf('@') + 1); // both are a particular mailbox if (email2.IndexOf('@') != -1) { @@ -1318,7 +1314,7 @@ namespace Org.BouncyCastle.Pkix { if (email2.IndexOf('@') != -1) { - String _sub = email2.Substring(email1.IndexOf('@') + 1); + string _sub = email2.Substring(email1.IndexOf('@') + 1); if (WithinDomain(_sub, email1)) { intersect.Add(email2); @@ -1349,7 +1345,7 @@ namespace Org.BouncyCastle.Pkix { if (email2.IndexOf('@') != -1) { - String _sub = email2.Substring(email2.IndexOf('@') + 1); + string _sub = email2.Substring(email2.IndexOf('@') + 1); if (Platform.EqualsIgnoreCase(_sub, email1)) { intersect.Add(email2); @@ -1374,7 +1370,7 @@ namespace Org.BouncyCastle.Pkix } } - private void CheckPermittedURI(ISet permitted, String uri) + private void CheckPermittedURI(ISet permitted, string uri) // throws PkixNameConstraintValidatorException { if (permitted == null) @@ -1386,7 +1382,7 @@ namespace Org.BouncyCastle.Pkix while (it.MoveNext()) { - String str = ((String)it.Current); + string str = ((string)it.Current); if (IsUriConstrained(uri, str)) { @@ -1401,9 +1397,9 @@ namespace Org.BouncyCastle.Pkix "URI is not from a permitted subtree."); } - private bool IsUriConstrained(String uri, String constraint) + private bool IsUriConstrained(string uri, string constraint) { - String host = ExtractHostFromURL(uri); + string host = ExtractHostFromURL(uri); // a host if (!Platform.StartsWith(constraint, ".")) { @@ -1422,11 +1418,11 @@ namespace Org.BouncyCastle.Pkix return false; } - private static String ExtractHostFromURL(String url) + private static string ExtractHostFromURL(string url) { // see RFC 1738 // remove ':' after protocol, e.g. http: - String sub = url.Substring(url.IndexOf(':') + 1); + string sub = url.Substring(url.IndexOf(':') + 1); // extract host from Common Internet Scheme Syntax, e.g. http:// int idxOfSlashes = Platform.IndexOf(sub, "//"); if (idxOfSlashes != -1) @@ -1466,7 +1462,7 @@ namespace Org.BouncyCastle.Pkix ExtractNameAsString(name)); break; case 2: - CheckPermittedDNS(permittedSubtreesDNS, DerIA5String.GetInstance( + CheckPermittedDns(permittedSubtreesDNS, DerIA5String.GetInstance( name.Name).GetString()); break; case 4: @@ -1501,7 +1497,7 @@ namespace Org.BouncyCastle.Pkix CheckExcludedEmail(excludedSubtreesEmail, ExtractNameAsString(name)); break; case 2: - checkExcludedDNS(excludedSubtreesDNS, DerIA5String.GetInstance( + CheckExcludedDns(excludedSubtreesDNS, DerIA5String.GetInstance( name.Name).GetString()); break; case 4: @@ -1514,7 +1510,7 @@ namespace Org.BouncyCastle.Pkix case 7: byte[] ip = Asn1OctetString.GetInstance(name.Name).GetOctets(); - checkExcludedIP(excludedSubtreesIP, ip); + CheckExcludedIP(excludedSubtreesIP, ip); break; } } @@ -1575,7 +1571,7 @@ namespace Org.BouncyCastle.Pkix } } - private String ExtractNameAsString(GeneralName name) + private string ExtractNameAsString(GeneralName name) { return DerIA5String.GetInstance(name.Name).GetString(); } @@ -1840,9 +1836,9 @@ namespace Org.BouncyCastle.Pkix * @param ip The IP with subnet mask. * @return The stringified IP address. */ - private String StringifyIP(byte[] ip) + private string StringifyIP(byte[] ip) { - String temp = ""; + string temp = ""; for (int i = 0; i < ip.Length / 2; i++) { //temp += Integer.toString(ip[i] & 0x00FF) + "."; @@ -1859,9 +1855,9 @@ namespace Org.BouncyCastle.Pkix return temp; } - private String StringifyIPCollection(ISet ips) + private string StringifyIPCollection(ISet ips) { - String temp = ""; + string temp = ""; temp += "["; for (IEnumerator it = ips.GetEnumerator(); it.MoveNext(); ) { @@ -1876,9 +1872,9 @@ namespace Org.BouncyCastle.Pkix return temp; } - public override String ToString() + public override string ToString() { - String temp = ""; + string temp = ""; temp += "permitted:\n"; if (permittedSubtreesDN != null) |