/// <summary>
        /// Assert end of Constructed type of node, i.e. SEQUENCE, SET. Then move to next node.
        /// </summary>
        /// <param name="reader">BerReader instance.</param>
        /// <param name="level">Depth of node in ASN.1 structure.</param>
        /// <param name="type">Type of given node to assert.</param>
        private static void AssertReadEnd(BerReader reader, int level, Asn1Type type)
        {
            Assert.AreEqual(level, reader.Depth, "Depth");
            Assert.AreEqual(Asn1NodeType.ConstructedEnd, reader.CurrentNode.NodeType, "Node Tag");
            Assert.AreEqual(type, reader.CurrentNode.Identifier.Tag, "Tag");
            Assert.AreEqual(0, reader.CurrentNode.Length, "Length");
            Assert.IsTrue(reader.CurrentNode.IsConstructed, "IsConstructed");
            Assert.IsFalse(reader.CurrentNode.NodeType == Asn1NodeType.DocumentEnd, "EndOfDocument");

            reader.Read();
        }
        public void DoesNotTouchStreamBeforeRead()
        {
            // Given
            var memoryStream = new MemoryStream();

            // When
            var berReader = new BerReader(memoryStream);

            // Then
            Assert.AreEqual(0, memoryStream.Position);
        }
        public void DisposeTests()
        {
            // Given
            // Example taken from: http://msdn.microsoft.com/en-us/library/bb540809%28v=vs.85%29.aspx
            const string example = @"
                06 09                                ; OBJECT_ID (9 Bytes)
                |  2b 06 01 04 01 82 37 15  14       ;   1.3.6.1.4.1.311.21.20 
            ";

            var encoded = Helpers.GetExampleBytes(example);

            // Given
            var memoryStream = new MemoryStream(encoded);

            // When
            using (var berReader = new BerReader(memoryStream))
            {
                // Then
                Assert.AreEqual(Asn1NodeType.DocumentStart, berReader.CurrentNode.NodeType);
            }

            bool objectDisposed = false;

            try
            {
                //should throw ObjectDisposedException
                var position = memoryStream.Position;
            }
            catch (ObjectDisposedException)
            {
                objectDisposed = true;
            }

            Assert.IsTrue(objectDisposed);


            // Given
            memoryStream = new MemoryStream(encoded);

            // When
            using (var berReader = new BerReader(memoryStream, true))
            {
                // Then
                Assert.AreEqual(Asn1NodeType.DocumentStart, berReader.CurrentNode.NodeType);
            }

            Assert.IsTrue(memoryStream.Position == 0); //should NOT throw ObjectDisposedException
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Read the value of the given node as list of children in the set.
        /// </summary>
        /// <returns>Value of the given node as list of children in the set.</returns>
        internal override List <Asn1ObjectBase> ReadEncodedValue()
        {
            if (this.RawContent == null)
            {
                throw new ArgumentException("Stream that contains encoded value is null.");
            }

            var content = this.RawContent;

            content.Seek(0, SeekOrigin.Begin);
            var internalReader = new BerReader(content);
            List <Asn1ObjectBase> children;

            internalReader.Read(out children);

            return(children);
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Load ASN.1 object in form of a stream, parse it and display its structure.
        /// </summary>
        /// <param name="asn1Content">ASN.1 object to parse.</param>
        public void LoadContent(Stream asn1Content)
        {
            // clear any existing nodes
            Nodes.Clear();

            // use parser to get the structure
            using (var reader = new BerReader(asn1Content))
            {
                var rootNode = new InternalNode();
                try
                {
                    // read whole object. This may fail if there is no valid ASN.1 object in the stream.
                    rootNode = reader.ReadToEnd(ReadContent);
                }
                catch (Exception ex)
                {
                    // something went wrong when reading file. Possibly it was not an ASN.1 object.
                    Trace.WriteLine(String.Format("Parsing exception: {0}", ex));

                    var safetyNode = new Asn1TreeNode(null, "Invalid ASN.1 structure.");
                    Nodes.Add(safetyNode);
                }

                // reader does not parse encapsulated data. Do it manually.
                foreach (InternalNode internalNode in rootNode.ChildNodes)
                {
                    //  This will enrich list of nodes with additional nodes parsed out of values of Primitive ASN.1 nodes
                    if (EncapsulatedDataParsing)
                    {
                        ParseEncapsulatedData(internalNode);
                    }

                    // build tree from list of ASN.1 nodes
                    var rootTreeNode = new Asn1TreeNode(internalNode);
                    MakeTreeNode(rootTreeNode, internalNode, 1, EncapsulatedDataParsing);
                    Nodes.Add(rootTreeNode);
                }
            }

            // expand tree
            ExpandAll();
            SelectedNode = Nodes[0];
        }
        /// <summary>
        /// Assert Primary type of node. Also read the value of the node and assert with given value. Then move to next node.
        /// </summary>
        /// <param name="reader">BerReader instance.</param>
        /// <param name="level">Depth of node in ASN.1 structure.</param>
        /// <param name="type">Type of given node to assert.</param>
        /// <param name="length">Length of given node to assert.</param>
        /// <param name="value">Value of the node to assert.</param>
        private static void AssertReadPri(BerReader reader, int level, Asn1Type type, int length, object value)
        {
            Assert.AreEqual(level, reader.Depth, "Depth");
            Assert.AreEqual(Asn1NodeType.Primitive, reader.CurrentNode.NodeType, "Node Tag");
            Assert.AreEqual(type, reader.CurrentNode.Identifier.Tag, "Tag");
            Assert.AreEqual(length, reader.CurrentNode.Length, "Length");
            Assert.IsFalse(reader.CurrentNode.IsConstructed, "IsConstructed");
            Assert.IsFalse(reader.CurrentNode.NodeType == Asn1NodeType.DocumentEnd, "EndOfDocument");

            reader.CurrentNode.RawValue = reader.ReadContentAsBuffer();

            switch (reader.CurrentNode.Identifier.Tag)
            {
            case Asn1Type.ObjectIdentifier:
                Assert.AreEqual(value, reader.CurrentNode.ReadContentAsObjectIdentifier());
                break;

            case Asn1Type.PrintableString:
            case Asn1Type.Ia5String:
            case Asn1Type.Utf8String:
                Assert.AreEqual(value, reader.CurrentNode.ReadContentAsString());
                break;

            case Asn1Type.GeneralizedTime:
            case Asn1Type.UtcTime:
                Assert.AreEqual(value, reader.CurrentNode.ReadConventAsDateTimeOffset());
                break;

            case Asn1Type.Integer:
                Assert.AreEqual(value, reader.CurrentNode.ReadContentAsBigInteger());
                break;

            case Asn1Type.Boolean:
                Assert.AreEqual(value, reader.CurrentNode.ReadContentAsBoolean());
                break;

            default:
                Assert.AreEqual(value, reader.CurrentNode.RawValue);
                break;
            }

            reader.Read();
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Method will parse value of given node for existing ASN.1 objects.
        /// </summary>
        /// <param name="innerNode">Node to parse.</param>
        internal static void ParseEncapsulatedData(InternalNode innerNode)
        {
            if (innerNode.NodeType != Asn1NodeType.Primitive)
            {
                return;
            }
            if (innerNode.RawValue == null)
            {
                return;                             // nothing to parse
            }
            // for now, only BIT STRING or OCTET STRING may contain encapsulated data
            if (innerNode.Identifier.Tag != Asn1Type.BitString && innerNode.Identifier.Tag != Asn1Type.OctetString)
            {
                return;
            }


            byte[] dataToParse = innerNode.RawValue;
            if (innerNode.Identifier.Tag == Asn1Type.BitString)
            {
                dataToParse = innerNode.ReadContentAsBitString();
            }

            // Reader will close the stream when it is done parsing
            var memStream = new MemoryStream(dataToParse);

            using (var innerReader = new BerReader(memStream))
            {
                try
                {
                    InternalNode innerRootNode = innerReader.ReadToEnd(true);
                    innerNode.ChildNodes.AddRange(innerRootNode.ChildNodes);
                }
                catch (Exception)
                {
                    // nothing to do. Value of primitive node did not contain valid ASN.1 structure.
                }
            }
        }
Ejemplo n.º 8
0
        /// <summary>
        /// Формирует строка со структурным представлением байтового массива в формате ASN1
        /// </summary>
        /// <param name="baAsn1">Байтовый массив в формате ASN1</param>
        /// <returns>Строка с текстовым представлением байтового массива в формате ASN1</returns>
        public static string PrintFromAsn1(byte[] baAsn1)
        {
            var memoryStream = new MemoryStream(baAsn1);

            using (var berReader = new BerReader(memoryStream))
            {
                //Формируем текстовое представление марканта
                try
                {
                    var    node   = berReader.ReadToEnd().ChildNodes[0];
                    string result = "ASN1:";
                    foreach (var childNode in node.ChildNodes)
                    {
                        result = berReader.PrintStructure(childNode, result, 1, true);
                    }

                    return(result);
                }
                catch (Exception e)
                {
                    throw new Exception("Invalid ASN format", e);
                }
            }
        }
Ejemplo n.º 9
0
        /// <summary>
        /// Печатает ASN.1 структуру
        /// </summary>
        /// <param name="reader">Объект BerReader</param>
        /// <param name="node">Узел дерева</param>
        /// <param name="relativeResult">Предыдущий результат работы данного метода</param>
        /// <param name="depth">Глубина вложенности</param>
        /// <param name="dumpValues">Печатать значения</param>
        /// <returns>Структура ASN.1 представленная в виде строки</returns>
        internal static string PrintStructure(this BerReader reader, InternalNode node, string relativeResult, int depth, bool dumpValues)
        {
            var offsetAndLength = String.Format("({0},{1})",
                                                node.StartPosition.ToString(CultureInfo.InvariantCulture),
                                                node.Length.ToString(CultureInfo.InvariantCulture));

            var structure = String.Format("{0} {1}",
                                          offsetAndLength,
                                          (node.Identifier.Class == Asn1Class.ContextSpecific)
                    ? String.Format("{0} ({1})", node.Identifier.Class, (int)node.Identifier.Tag)
                    : node.Identifier.Tag.ToString());

            if (dumpValues)
            {
                if (node.NodeType == Asn1NodeType.Primitive)
                {
                    string stringValue;
                    node.RawValue = reader.ReadContentAsBuffer(node);

                    switch (node.Identifier.Tag)
                    {
                    case Asn1Type.ObjectIdentifier:
                        stringValue = node.ReadContentAsObjectIdentifier();
                        break;

                    case Asn1Type.PrintableString:
                    case Asn1Type.Ia5String:
                    case Asn1Type.Utf8String:
                        stringValue = node.ReadContentAsString();
                        break;

                    case Asn1Type.GeneralizedTime:
                    case Asn1Type.UtcTime:
                        stringValue = node.ReadConventAsDateTimeOffset().ToString();
                        break;

                    case Asn1Type.Integer:
                        stringValue = node.ReadContentAsBigInteger().ToString();
                        break;

                    case Asn1Type.Boolean:
                        stringValue = node.ReadContentAsBoolean().ToString();
                        break;

                    default:
                        stringValue = node.RawValue.ToHexString();
                        break;
                    }

                    structure = string.Format("{0} : {1}", structure, stringValue);
                }
            }

            for (int i = 0; i < depth; i++)
            {
                structure = "\t" + structure;
            }

            string res = relativeResult + Environment.NewLine + structure;

            var innerdepth = (node.ChildNodes.Count > 0) ? depth + 1 : depth;

            foreach (var innerNode in node.ChildNodes)
            {
                res = reader.PrintStructure(innerNode, res, innerdepth, dumpValues);
            }

            return(res);
        }
Ejemplo n.º 10
0
        /// <summary>
        /// Prints structure of given ASN.1 node. Node should be the result of ReadToEnd method called before.
        /// </summary>
        /// <param name="reader">Extended object</param>
        /// <param name="node">Node to print structure of.</param>
        /// <param name="relativeResult">Relative result of this method. Used when iterating through the structure to build on top of previous results of this method.</param>
        /// <param name="depth">Actual depth of parser.</param>
        /// <param name="dumpValues">Flag indicating if values should be printed out.</param>
        /// <returns>Structure of ASN.1 node as string.</returns>
        internal static string PrintStructure(this BerReader reader, InternalNode node, string relativeResult, int depth, bool dumpValues)
        {
            // print offset in source stream and length of ASN.1 node
            var offsetAndLength = String.Format("({0},{1})",
                                                node.StartPosition.ToString(CultureInfo.InvariantCulture),
                                                node.Length.ToString(CultureInfo.InvariantCulture));

            // append tag name
            var structure = String.Format("{0} {1}",
                                          offsetAndLength,
                                          (node.Identifier.Class == Asn1Class.ContextSpecific)
                    ? String.Format("{0} ({1})", node.Identifier.Class, (int)node.Identifier.Tag)
                    : node.Identifier.Tag.ToString());

            // append value of ASN.1 node
            if (dumpValues)
            {
                if (node.NodeType == Asn1NodeType.Primitive)
                {
                    string stringValue;
                    node.RawValue = reader.ReadContentAsBuffer(node);

                    switch (node.Identifier.Tag)
                    {
                    case Asn1Type.ObjectIdentifier:
                        stringValue = node.ReadContentAsObjectIdentifier();
                        break;

                    case Asn1Type.PrintableString:
                    case Asn1Type.Ia5String:
                    case Asn1Type.Utf8String:
                        stringValue = node.ReadContentAsString();
                        break;

                    case Asn1Type.GeneralizedTime:
                    case Asn1Type.UtcTime:
                        stringValue = node.ReadConventAsDateTimeOffset().ToString();
                        break;

                    case Asn1Type.Integer:
                        stringValue = node.ReadContentAsBigInteger().ToString();
                        break;

                    case Asn1Type.Boolean:
                        stringValue = node.ReadContentAsBoolean().ToString();
                        break;

                    default:
                        stringValue = node.RawValue.ToHexString();
                        break;
                    }

                    structure = string.Format("{0} : {1}", structure, stringValue);
                }
            }

            // apply depth
            for (int i = 0; i < depth; i++)
            {
                structure = "\t" + structure;
            }

            // append new line
            string res = relativeResult + Environment.NewLine + structure;

            // count new depth if node has children
            var innerdepth = (node.ChildNodes.Count > 0) ? depth + 1 : depth;

            // recursively go through children and print structure of them
            foreach (var innerNode in node.ChildNodes)
            {
                res = reader.PrintStructure(innerNode, res, innerdepth, dumpValues);
            }

            // return result
            return(res);
        }