/// <summary>
        ///     Compares the RDN to the rdn passed.  Note: If an there exist any
        ///     mulivalues in one RDN they must all be present in the other.
        /// </summary>
        /// <param name="rdn">
        ///     the RDN to compare to
        ///     @throws IllegalArgumentException if the application compares a name
        ///     with an OID.
        /// </param>
        public bool Equals(Rdn rdn)
        {
            if (_values.Count != rdn._values.Count)
            {
                return(false);
            }

            for (var i = 0; i < _values.Count; i++)
            {
                // verify that the current value and type exists in the other list
                var j = 0;

                var valuesEqual     = _values[i].EqualsOrdinalCI(rdn._values[j]);
                var isEqualAttrType = EqualAttrType(_types[i], rdn._types[j]);

                while (j < _values.Count && (!valuesEqual || !isEqualAttrType))
                {
                    j++;
                }

                // couldn't find first value
                if (j >= rdn._values.Count)
                {
                    return(false);
                }
            }

            return(true);
        }
Exemple #2
0
        /// <summary>
        ///     Constructs a new DN based on the specified string representation of a
        ///     distinguished name. The syntax of the DN must conform to that specified
        ///     in RFC 2253.
        /// </summary>
        /// <param name="dnString">
        ///     a string representation of the distinguished name.
        /// </param>
        /// <exception>
        ///     IllegalArgumentException  if the the value of the dnString
        ///     parameter does not adhere to the syntax described in
        ///     RFC 2253.
        /// </exception>
        public Dn(string dnString)
        {
            /* the empty string is a valid DN */
            if (dnString.Length == 0)
            {
                return;
            }

            var tokenBuf           = new char[dnString.Length];
            var trailingSpaceCount = 0;
            var attrType           = string.Empty;
            var attrValue          = string.Empty;
            var rawValue           = string.Empty;
            var hexDigitCount      = 0;
            var currRdn            = new Rdn();

            // indicates whether an OID number has a first digit of ZERO

            var tokenIndex = 0;
            var currIndex  = 0;
            var valueStart = 0;
            var state      = LookForRdnAttrType;
            var lastIndex  = dnString.Length - 1;

            while (currIndex <= lastIndex)
            {
                var  currChar = dnString[currIndex];
                char nextChar;
                switch (state)
                {
                case LookForRdnAttrType:
                    while (currChar == ' ' && currIndex < lastIndex)
                    {
                        currChar = dnString[++currIndex];
                    }

                    if (IsAlpha(currChar))
                    {
                        if (dnString.Substring(currIndex).StartsWith("oid.") ||
                            dnString.Substring(currIndex).StartsWith("OID."))
                        {
                            // form is "oid.###.##.###... or OID.###.##.###...
                            currIndex += 4;     // skip oid. prefix and get to actual oid
                            if (currIndex > lastIndex)
                            {
                                throw new ArgumentException(dnString);
                            }

                            currChar = dnString[currIndex];
                            if (IsDigit(currChar))
                            {
                                tokenBuf[tokenIndex++] = currChar;
                                state = OidAttrType;
                            }
                            else
                            {
                                throw new ArgumentException(dnString);
                            }
                        }
                        else
                        {
                            tokenBuf[tokenIndex++] = currChar;
                            state = AlphaAttrType;
                        }
                    }
                    else if (IsDigit(currChar))
                    {
                        --currIndex;
                        state = OidAttrType;
                    }
                    else if (CharUnicodeInfo.GetUnicodeCategory(currChar) != UnicodeCategory.SpaceSeparator)
                    {
                        throw new ArgumentException(dnString);
                    }

                    break;

                case AlphaAttrType:
                    if (IsAlpha(currChar) || IsDigit(currChar) || currChar == '-')
                    {
                        tokenBuf[tokenIndex++] = currChar;
                    }
                    else
                    {
                        // skip any spaces
                        while (currChar == ' ' && currIndex < lastIndex)
                        {
                            currChar = dnString[++currIndex];
                        }

                        if (currChar == '=')
                        {
                            attrType   = new string(tokenBuf, 0, tokenIndex);
                            tokenIndex = 0;
                            state      = LookForRdnValue;
                        }
                        else
                        {
                            throw new ArgumentException(dnString);
                        }
                    }

                    break;

                case OidAttrType:
                    if (!IsDigit(currChar))
                    {
                        throw new ArgumentException(dnString);
                    }

                    var firstDigitZero = currChar == '0' ? true : false;
                    tokenBuf[tokenIndex++] = currChar;
                    currChar = dnString[++currIndex];

                    if (IsDigit(currChar) && firstDigitZero || currChar == '.' && firstDigitZero)
                    {
                        throw new ArgumentException(dnString);
                    }

                    // consume all numbers.
                    while (IsDigit(currChar) && currIndex < lastIndex)
                    {
                        tokenBuf[tokenIndex++] = currChar;
                        currChar = dnString[++currIndex];
                    }

                    if (currChar == '.')
                    {
                        tokenBuf[tokenIndex++] = currChar;

                        // The state remains at OID_ATTR_TYPE
                    }
                    else
                    {
                        // skip any spaces
                        while (currChar == ' ' && currIndex < lastIndex)
                        {
                            currChar = dnString[++currIndex];
                        }

                        if (currChar == '=')
                        {
                            attrType   = new string(tokenBuf, 0, tokenIndex);
                            tokenIndex = 0;
                            state      = LookForRdnValue;
                        }
                        else
                        {
                            throw new ArgumentException(dnString);
                        }
                    }

                    break;

                case LookForRdnValue:
                    while (currChar == ' ')
                    {
                        if (currIndex < lastIndex)
                        {
                            currChar = dnString[++currIndex];
                        }
                        else
                        {
                            throw new ArgumentException(dnString);
                        }
                    }

                    if (currChar == '"')
                    {
                        state      = QuotedRdnValue;
                        valueStart = currIndex;
                    }
                    else if (currChar == '#')
                    {
                        hexDigitCount          = 0;
                        tokenBuf[tokenIndex++] = currChar;
                        valueStart             = currIndex;
                        state = HexRdnValue;
                    }
                    else
                    {
                        valueStart = currIndex;

                        // check this character again in the UNQUOTED_RDN_VALUE state
                        currIndex--;
                        state = UnquotedRdnValue;
                    }

                    break;

                case UnquotedRdnValue:
                    if (currChar == '\\')
                    {
                        if (!(currIndex < lastIndex))
                        {
                            throw new ArgumentException(dnString);
                        }

                        currChar = dnString[++currIndex];
                        if (IsHexDigit(currChar))
                        {
                            if (!(currIndex < lastIndex))
                            {
                                throw new ArgumentException(dnString);
                            }

                            nextChar = dnString[++currIndex];
                            if (IsHexDigit(nextChar))
                            {
                                tokenBuf[tokenIndex++] = HexToChar(currChar, nextChar);
                                trailingSpaceCount     = 0;
                            }
                            else
                            {
                                throw new ArgumentException(dnString);
                            }
                        }
                        else if (NeedsEscape(currChar) || currChar == '#' || currChar == '=' || currChar == ' ')
                        {
                            tokenBuf[tokenIndex++] = currChar;
                            trailingSpaceCount     = 0;
                        }
                        else
                        {
                            throw new ArgumentException(dnString);
                        }
                    }
                    else if (currChar == ' ')
                    {
                        trailingSpaceCount++;
                        tokenBuf[tokenIndex++] = currChar;
                    }
                    else if (currChar == ',' || currChar == ';' || currChar == '+')
                    {
                        attrValue = new string(tokenBuf, 0, tokenIndex - trailingSpaceCount);
                        rawValue  = dnString.Substring(valueStart, currIndex - trailingSpaceCount - valueStart);

                        currRdn.Add(attrType, attrValue, rawValue);
                        if (currChar != '+')
                        {
                            _rdnList.Add(currRdn);
                            currRdn = new Rdn();
                        }

                        trailingSpaceCount = 0;
                        tokenIndex         = 0;
                        state = LookForRdnAttrType;
                    }
                    else if (NeedsEscape(currChar))
                    {
                        throw new ArgumentException(dnString);
                    }
                    else
                    {
                        trailingSpaceCount     = 0;
                        tokenBuf[tokenIndex++] = currChar;
                    }

                    break;     // end UNQUOTED RDN VALUE

                case QuotedRdnValue:
                    if (currChar == '"')
                    {
                        rawValue = dnString.Substring(valueStart, currIndex + 1 - valueStart);
                        if (currIndex < lastIndex)
                        {
                            currChar = dnString[++currIndex];
                        }

                        // skip any spaces
                        while (currChar == ' ' && currIndex < lastIndex)
                        {
                            currChar = dnString[++currIndex];
                        }

                        if (currChar == ',' || currChar == ';' || currChar == '+' || currIndex == lastIndex)
                        {
                            attrValue = new string(tokenBuf, 0, tokenIndex);

                            currRdn.Add(attrType, attrValue, rawValue);
                            if (currChar != '+')
                            {
                                _rdnList.Add(currRdn);
                                currRdn = new Rdn();
                            }

                            trailingSpaceCount = 0;
                            tokenIndex         = 0;
                            state = LookForRdnAttrType;
                        }
                        else
                        {
                            throw new ArgumentException(dnString);
                        }
                    }
                    else if (currChar == '\\')
                    {
                        currChar = dnString[++currIndex];
                        if (IsHexDigit(currChar))
                        {
                            nextChar = dnString[++currIndex];
                            if (IsHexDigit(nextChar))
                            {
                                tokenBuf[tokenIndex++] = HexToChar(currChar, nextChar);
                                trailingSpaceCount     = 0;
                            }
                            else
                            {
                                throw new ArgumentException(dnString);
                            }
                        }
                        else if (NeedsEscape(currChar) || currChar == '#' || currChar == '=' || currChar == ' ')
                        {
                            tokenBuf[tokenIndex++] = currChar;
                            trailingSpaceCount     = 0;
                        }
                        else
                        {
                            throw new ArgumentException(dnString);
                        }
                    }
                    else
                    {
                        tokenBuf[tokenIndex++] = currChar;
                    }

                    break;     // end QUOTED RDN VALUE

                case HexRdnValue:
                    if (!IsHexDigit(currChar) || currIndex > lastIndex)
                    {
                        // check for odd number of hex digits
                        if (hexDigitCount % 2 != 0 || hexDigitCount == 0)
                        {
                            throw new ArgumentException(dnString);
                        }

                        rawValue = dnString.Substring(valueStart, currIndex - valueStart);

                        // skip any spaces
                        while (currChar == ' ' && currIndex < lastIndex)
                        {
                            currChar = dnString[++currIndex];
                        }

                        if (currChar == ',' || currChar == ';' || currChar == '+' || currIndex == lastIndex)
                        {
                            attrValue = new string(tokenBuf, 0, tokenIndex);

                            // added by cameron
                            currRdn.Add(attrType, attrValue, rawValue);
                            if (currChar != '+')
                            {
                                _rdnList.Add(currRdn);
                                currRdn = new Rdn();
                            }

                            tokenIndex = 0;
                            state      = LookForRdnAttrType;
                        }
                        else
                        {
                            throw new ArgumentException(dnString);
                        }
                    }
                    else
                    {
                        tokenBuf[tokenIndex++] = currChar;
                        hexDigitCount++;
                    }

                    break;     // end HEX RDN VALUE
                } // end switch

                currIndex++;
            } // end while

            // check ending state
            if (state == UnquotedRdnValue || state == HexRdnValue && hexDigitCount % 2 == 0 && hexDigitCount != 0)
            {
                attrValue = new string(tokenBuf, 0, tokenIndex - trailingSpaceCount);
                rawValue  = dnString.Substring(valueStart, currIndex - trailingSpaceCount - valueStart);
                currRdn.Add(attrType, attrValue, rawValue);
                _rdnList.Add(currRdn);
            }
            else if (state == LookForRdnValue)
            {
                // empty value is valid
                attrValue = string.Empty;
                rawValue  = dnString.Substring(valueStart);
                currRdn.Add(attrType, attrValue, rawValue);
                _rdnList.Add(currRdn);
            }
            else
            {
                throw new ArgumentException(dnString);
            }
        } // end DN constructor (string dn)
Exemple #3
0
 /// <summary> Adds the RDN to the end of the current DN.</summary>
 /// <param name="rdn">
 ///     an RDN to be added.
 /// </param>
 public void AddRdnToBack(Rdn rdn)
 {
     _rdnList.Add(rdn);
 }
Exemple #4
0
 /// <summary> Adds the RDN to the beginning of the current DN.</summary>
 /// <param name="rdn">
 ///     an RDN to be added.
 /// </param>
 public void AddRdnToFront(Rdn rdn)
 {
     _rdnList.Insert(0, rdn);
 }
Exemple #5
0
 /// <summary> Adds the RDN to the beginning of the current DN.</summary>
 /// <param name="rdn">
 ///     an RDN to be added.
 /// </param>
 public void AddRdn(Rdn rdn)
 {
     _rdnList.Insert(0, rdn);
 }