Ejemplo n.º 1
0
        public static TlvObject Query(byte[] data, int tag)
        {
            /*
             * Search for the tag.
             */
            TlvConstructed myTag = new TlvConstructed();

            myTag.Value = data;
            return(myTag.Find(tag));
        }
Ejemplo n.º 2
0
        public static TlvObject Query(byte[] data, string path)
        {
            /*
             * Transform the path into its separate tags and validate them.
             */
            List <int> myNumbers = new List <int>();

            foreach (string t in path.Split('/'))
            {
                try
                {
                    myNumbers.Add(Int32.Parse(t, NumberStyles.HexNumber, CultureInfo.InvariantCulture));
                }
                catch
                {
                    throw new ArgumentException(@"Error parsing the BER path", @"path");
                }
            }

            TlvObject myTag = new TlvConstructed();

            myTag.Value = data;

            /*
             * Search recursively for the tag.
             */
            for (int i = 0; i < myNumbers.Count; i++)
            {
                myTag = ((TlvConstructed)myTag).Find(myNumbers[i]);

                if (null == myTag)
                {
                    // The path wasn't found
                    return(null);
                }
            }

            // Return what we found
            return(myTag);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Finds the specified tag.
        /// </summary>
        /// <param name="tag">The tag.</param>
        /// <returns></returns>
        public TlvObject Find(int tag)
        {
            int myIndex = 0;

            TlvObject myTLV = null;

            while (myIndex < Value.Length)
            {
                /*
                 * RETRIEVE THE TAG TYPE
                 * The bit B6 of the leading byte of the tag field shall encode the tag type,
                 * i.e. the type of the data object.
                 *
                 * B6=0 introduces a primitive data object
                 * B6=1 introduces a constructed data object
                 */
                if ((Value[myIndex] & 0x20) == 0x20)
                {
                    myTLV = new TlvConstructed();
                }
                else
                {
                    myTLV = new TlvPrimitive();
                }

                /*
                 * RETRIEVE THE TAG NUMBER
                 *
                 * If the bits B5-B1 of the leading byte are not all set to 1, then may they
                 * shall encode an integer equal to the tag number which therefore lies in the
                 * range from 0 to 30. Then the tag field consists of a single byte.
                 *
                 * Otherwise (B5-B1 set to 1 in the leading byte), the tag field shall
                 * continue on one or more shubsequent bytes.
                 *
                 * The bit B8 of each subsequent byte shall be set to 1, unless it is the
                 * last subsequent byte
                 * The bits B7-B1 of the first subsequent byte shall not be all set to 0
                 * The bits B7-B1 of the first subsequent byte, folowed by the bits B7 to B1
                 * of each further subsequent byte, up to and including the bits B7-B1 of
                 * the last subsequent byte, shall encode an integer equal to the tag
                 * number (thus strictly positive).
                 */

                if (0x1F == (Value[myIndex] & 0x1F))
                {
                    // Set the first byte of the tag number
                    myTLV.Number = Value[myIndex];

                    while (true)
                    {
                        // Move to the next byte
                        myIndex++;

                        // Shift the number over by 8 bits
                        myTLV.Number <<= 8;

                        // Assign the next value to the lower byte
                        myTLV.Number |= Value[myIndex];

                        // If the MSB is clear then this is our last byte
                        if ((Value[myIndex] & 0x80) == 0x00)
                        {
                            break;
                        }
                    }
                }
                else
                {
                    // This is a low-tag number

                    /*
                     * NOTE: When documentation refers to the tag number it also
                     * seems to include the class/type information so we won't trim
                     * it out here.
                     */
                    myTLV.Number = Value[myIndex];
                }

                // Move to the next byte
                myIndex++;

                /*
                 * LENGTH
                 */
                int myLength = 0;

                if (0x80 == (Value[myIndex] & 0x80))
                {
                    // This is a long length
                    int myLengthBytes = Value[myIndex] & 0x7F;

                    for (int i = 0; i < myLengthBytes; i++)
                    {
                        // Move to the next byte
                        myIndex++;

                        // Shift our length over by 8 bits
                        myLength <<= 8;

                        // Copy the value
                        myLength |= Value[myIndex];
                    }
                }
                else
                {
                    // This is a short length (msb is 0 here so we take the whole byte)
                    myLength = Value[myIndex];
                }

                // Move to the next byte
                myIndex++;

                // Is this the tag we're looking for?
                if (myTLV.Number == tag)
                {
                    // Set our tag value
                    myTLV.Value = new byte[myLength];
                    Array.Copy(Value, myIndex, myTLV.Value, 0, myLength);

                    // Finished!
                    return(myTLV);
                }
                else
                {
                    // Move to the next tag
                    myIndex += myLength;
                }
            }

            // Nothing was found
            return(null);
        }