コード例 #1
0
        // Note that unlike the C++ & Java implementation this returns unescaped data.
        private void Parse(string value, List <List <RFC2253.RDNPair> > reject, List <List <RFC2253.RDNPair> > accept)
        {
            // As with the Java implementation, the DN that comes from the X500DistinguishedName does not necessarily
            // match the user's input form. Therefore we need to normalize the data to match the C# forms.
            List <RFC2253.RDNEntry> l = RFC2253.Parse(value);

            for (int i = 0; i < l.Count; ++i)
            {
                List <RFC2253.RDNPair> dn = l[i].Rdn;
                for (int j = 0; j < dn.Count; ++j)
                {
                    RFC2253.RDNPair pair = dn[j];
                    // Normalize the RDN key.
                    if (pair.Key == "emailAddress")
                    {
                        pair.Key = "E";
                    }
                    else if (pair.Key == "ST")
                    {
                        pair.Key = "S";
                    }
                    // Unescape the value.
                    pair.Value = RFC2253.Unescape(pair.Value);
                    dn[j]      = pair;
                }
                if (l[i].Negate)
                {
                    reject.Add(l[i].Rdn);
                }
                else
                {
                    accept.Add(l[i].Rdn);
                }
            }
        }
コード例 #2
0
        internal bool Verify(SslConnectionInfo info, string desc)
        {
            List <List <List <RFC2253.RDNPair> > > reject = new List <List <List <RFC2253.RDNPair> > >(),
                                                   accept = new List <List <List <RFC2253.RDNPair> > >();

            if (_rejectAll.Count != 0)
            {
                reject.Add(_rejectAll);
            }
            if (info.Incoming)
            {
                if (_rejectAllServer.Count != 0)
                {
                    reject.Add(_rejectAllServer);
                }
                if (info.AdapterName !.Length > 0)
                {
                    if (_rejectServer.TryGetValue(info.AdapterName, out List <List <RFC2253.RDNPair> >?p))
                    {
                        reject.Add(p);
                    }
                }
            }
            else
            {
                if (_rejectClient.Count != 0)
                {
                    reject.Add(_rejectClient);
                }
            }

            if (_acceptAll.Count != 0)
            {
                accept.Add(_acceptAll);
            }
            if (info.Incoming)
            {
                if (_acceptAllServer.Count != 0)
                {
                    accept.Add(_acceptAllServer);
                }
                if (info.AdapterName !.Length > 0)
                {
                    if (_acceptServer.TryGetValue(info.AdapterName, out List <List <RFC2253.RDNPair> >?p))
                    {
                        accept.Add(p);
                    }
                }
            }
            else
            {
                if (_acceptClient.Count != 0)
                {
                    accept.Add(_acceptClient);
                }
            }

            //
            // If there is nothing to match against, then we accept the cert.
            //
            if (reject.Count == 0 && accept.Count == 0)
            {
                return(true);
            }

            //
            // If there is no certificate then we match false.
            //
            if (info.Certs != null && info.Certs.Length > 0)
            {
                X500DistinguishedName subjectDN = info.Certs[0].SubjectName;
                string subjectName = subjectDN.Name;
                Debug.Assert(subjectName != null);
                try
                {
                    //
                    // Decompose the subject DN into the RDNs.
                    //
                    if (_traceLevel > 0)
                    {
                        if (info.Incoming)
                        {
                            _communicator.Logger.Trace("Security", "trust manager evaluating client:\n" +
                                                       "subject = " + subjectName + "\n" + "adapter = " + info.AdapterName + "\n" + desc);
                        }
                        else
                        {
                            _communicator.Logger.Trace("Security", "trust manager evaluating server:\n" +
                                                       "subject = " + subjectName + "\n" + desc);
                        }
                    }

                    List <RFC2253.RDNPair> dn = RFC2253.ParseStrict(subjectName);

                    //
                    // Unescape the DN. Note that this isn't done in
                    // the parser in order to keep the various RFC2253
                    // implementations as close as possible.
                    //
                    for (int i = 0; i < dn.Count; ++i)
                    {
                        RFC2253.RDNPair p = dn[i];
                        p.Value = RFC2253.Unescape(p.Value);
                        dn[i]   = p;
                    }

                    //
                    // Fail if we match anything in the reject set.
                    //
                    foreach (List <List <RFC2253.RDNPair> > matchSet in reject)
                    {
                        if (_traceLevel > 0)
                        {
                            var s = new StringBuilder("trust manager rejecting PDNs:\n");
                            Stringify(matchSet, s);
                            _communicator.Logger.Trace("Security", s.ToString());
                        }
                        if (Match(matchSet, dn))
                        {
                            return(false);
                        }
                    }

                    //
                    // Succeed if we match anything in the accept set.
                    //
                    foreach (List <List <RFC2253.RDNPair> > matchSet in accept)
                    {
                        if (_traceLevel > 0)
                        {
                            var s = new StringBuilder("trust manager accepting PDNs:\n");
                            Stringify(matchSet, s);
                            _communicator.Logger.Trace("Security", s.ToString());
                        }
                        if (Match(matchSet, dn))
                        {
                            return(true);
                        }
                    }
                }
                catch (FormatException e)
                {
                    _communicator.Logger.Warning(
                        $"unable to parse certificate DN `{subjectName}'\nreason: {e.Message}");
                }

                //
                // At this point we accept the connection if there are no explicit accept rules.
                //
                return(accept.Count == 0);
            }

            return(false);
        }