summary refs log tree commit diff
path: root/crypto/src/pkix/PkixNameConstraintValidator.cs
diff options
context:
space:
mode:
authorPeter Dettman <peter.dettman@bouncycastle.org>2019-06-01 19:11:34 +0700
committerPeter Dettman <peter.dettman@bouncycastle.org>2019-06-01 19:11:34 +0700
commit5cc0a46f4dbaafd9e3104643ec1fa5bf69ac5a6c (patch)
tree0ac8a1bd4557e3682c2fb2cbf889bd992402b1db /crypto/src/pkix/PkixNameConstraintValidator.cs
parentRemove extraneous output (diff)
downloadBouncyCastle.NET-ed25519-5cc0a46f4dbaafd9e3104643ec1fa5bf69ac5a6c.tar.xz
Name constraint validation updates from bc-java
Diffstat (limited to 'crypto/src/pkix/PkixNameConstraintValidator.cs')
-rw-r--r--crypto/src/pkix/PkixNameConstraintValidator.cs206
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)