Esempio n. 1
0
        /*
         * Parse a string into a DN. The input is expected to use
         * RFC 4514 format. Name elements that are provided as
         * character strings will be mapped to ASN.1 PrintableString
         * values (if they are compatible with that string type)
         * or UTF8String values (otherwise).
         *
         * On parse error, an AsnException is thrown.
         */
        public static X500Name Parse(string str)
        {
            int  n   = str.Length;
            int  p   = 0;
            bool acc = false;
            List <List <DNPart> > dn = new List <List <DNPart> >();

            while (p < n)
            {
                /*
                 * Find the next unescaped '+' or ',' sign.
                 */
                bool lcwb = false;
                int  q;
                for (q = p; q < n; q++)
                {
                    if (lcwb)
                    {
                        lcwb = false;
                        continue;
                    }
                    switch (str[q])
                    {
                    case ',':
                    case '+':
                        goto found;

                    case '\\':
                        lcwb = true;
                        break;
                    }
                }
found:

                /*
                 * Parse DN element.
                 */
                DNPart dnp = DNPart.Parse(str.Substring(p, q - p));
                if (acc)
                {
                    dn[dn.Count - 1].Add(dnp);
                }
                else
                {
                    List <DNPart> r = new List <DNPart>();
                    r.Add(dnp);
                    dn.Add(r);
                }

                p   = q + 1;
                acc = q < n && str[q] == '+';
            }

            dn.Reverse();
            return(new X500Name(dn));
        }
Esempio n. 2
0
        /*
         * Generic parsing. If 'strictStrings' is true, then the following
         * rules are enforced:
         * -- Every SET in the sequence of RDN must have size 1.
         * -- Every name element is decoded as a string (by tag).
         *
         * If 'strictStrings' is false, then multiple elements may appear
         * in each SET, and values needs not be decodable as string (values
         * with a known OID must still be decodable).
         *
         * This constructor checks that within a single RDN, no two
         * attributes may have the same type.
         *
         * On decoding error, an AsnException is thrown.
         */
        public X500Name(AsnElt aDN, bool strictStrings)
        {
            /*
             * Note: the SEQUENCE tag MUST be present, since the
             * ASN.1 definition of Name starts with a CHOICE; thus,
             * any tag override would have to be explicit, not
             * implicit.
             */
            aDN.CheckConstructed();
            aDN.CheckTag(AsnElt.SEQUENCE);
            List <List <DNPart> > r = new List <List <DNPart> >();

            foreach (AsnElt aRDN in aDN.Sub)
            {
                aRDN.CheckConstructed();
                aRDN.CheckTag(AsnElt.SET);
                aRDN.CheckNumSubMin(1);
                int n = aRDN.Sub.Length;
                if (n != 1 && strictStrings)
                {
                    throw new AsnException(String.Format(
                                               "several ({0}) values in RDN", n));
                }
                List <DNPart> r2 = new List <DNPart>();
                r.Add(r2);
                for (int i = 0; i < n; i++)
                {
                    AsnElt aTV = aRDN.Sub[i];
                    aTV.CheckConstructed();
                    aTV.CheckTag(AsnElt.SEQUENCE);
                    aTV.CheckNumSub(2);
                    AsnElt aOID = aTV.GetSub(0);
                    aOID.CheckTag(AsnElt.OBJECT_IDENTIFIER);
                    AsnElt aVal = aTV.GetSub(1);
                    string nt   = aOID.GetOID();
                    DNPart dnp  = new DNPart(nt, aVal);
                    if (strictStrings && !dnp.IsString)
                    {
                        throw new AsnException(
                                  "RDN is not a string");
                    }
                    r2.Add(dnp);
                }
            }
            Init(r);
        }
Esempio n. 3
0
        void Init(List <List <DNPart> > dn)
        {
            int           n = dn.Count;
            List <DNPart> r = new List <DNPart>();

            PartsGen_ = new DNPart[n][];
            for (int i = 0; i < n; i++)
            {
                IDictionary <string, DNPart> dd =
                    new SortedDictionary <string, DNPart>(
                        StringComparer.Ordinal);
                foreach (DNPart dnp in dn[i])
                {
                    string nt = dnp.OID;
                    if (dd.ContainsKey(nt))
                    {
                        throw new AsnException(string.Format(
                                                   "multiple values of type {0}"
                                                   + " in RDN", nt));
                    }
                    dd[nt] = dnp;
                }
                PartsGen_[i] = new DNPart[dd.Count];
                int j = 0;
                foreach (DNPart p in dd.Values)
                {
                    PartsGen_[i][j++] = p;
                    r.Add(p);
                }
            }
            Parts_ = r.ToArray();

            uint hc = 0;

            foreach (DNPart dnp in r)
            {
                hc = ((hc << 7) | (hc >> 25)) + (uint)dnp.GetHashCode();
            }
            hashCode = (int)hc;
        }
Esempio n. 4
0
 public bool Equals(DNPart dnp)
 {
     if (dnp == null)
     {
         return(false);
     }
     if (OID != dnp.OID)
     {
         return(false);
     }
     if (IsString)
     {
         return(dnp.IsString &&
                normValue == dnp.normValue);
     }
     else if (dnp.IsString)
     {
         return(false);
     }
     else
     {
         return(Eq(encodedValue, dnp.encodedValue));
     }
 }