public static long GetTotalByteCount(Asn1Tag node) { if (node.Constructed) { return(Asn1.EncodeHeader(node).Length + node.Sum(subTag => GetTotalByteCount(subTag))); } else { return(Asn1.EncodeHeader(node).Length + node.Data.Length); } }
protected internal void ToShortText(ConsoleTable output, int indentLevel) { output.AddRow( StartByte.ToString(), (IndefiniteLength) ? "inf" : Asn1.GetTotalByteCount(this).ToString(), Constructed ? "cons" : "prim", Identifier.ToString(), string.Concat(string.Empty.PadLeft(indentLevel * 2, ' '), ShortDescription), DataText ); if (Constructed) { foreach (Asn1Tag subTag in SubTags) { subTag.ToShortText(output, indentLevel + 1); } } }
/// <summary> /// Parse data in a (BitString) node if it's valid ASN.1 and add read nodes as sub nodes to this node. /// </summary> /// <param name="node">Node to read data from.</param> /// <returns>True if valid ASN.1 was read, false if not.</returns> private static bool ReadSubAsn1(Asn1Tag node, int dataOffset) { try { using (MemoryStream ms = new MemoryStream(node.Data, dataOffset, node.Data.Length - 1)) { Asn1Tag subTag = Asn1.Decode(ms); subTag.ToShortText(); // To validate, if it fails with exception, it's not added node.AddSubTag(subTag); return(true); } } catch (Exception ex) // TODO: narrow this down { Console.WriteLine("Exception: " + ex.Message); return(false); } }
/// <summary> /// Read an ASN.1 tag identifier from a stream (as specified in X.690) /// </summary> /// <param name="stream">Stream to read from</param> /// <param name="tagClass">Tag class of the tag</param> /// <param name="constructed">Indicates if the tag is constructed = true (or primitive = false)</param> /// <returns></returns> private static int ReadIdentifier(Stream stream, out Asn1.Class tagClass, out bool constructed, out int fullIdentifier, out bool forceMultiByteIdentifier) { int identifier; int b = stream.ReadByte(); if (b < 0) throw new IOException("Unexpected end of ASN.1 data while reading identifier."); // 8 7 | 6 | 5 4 3 2 1 // Class |P/C| Tag number tagClass = (Asn1.Class)(b >> 6); constructed = (b & 0x20) != 0; fullIdentifier = 0; if ((b & 0x1f) != 0x1f) { // Single byte identifier identifier = b & 0x1f; fullIdentifier = b; forceMultiByteIdentifier = false; } else { // Multi byte identifier identifier = 0; fullIdentifier |= b; // juse to be sure we force encoding this to multiple bytes to maintain the structue as much as we can forceMultiByteIdentifier = true; do { b = stream.ReadByte(); if (b < 0) throw new IOException("Unexpected end of ASN.1 data while reading multi byte identifier."); identifier <<= 7; // also happens first time, but that's ok, it's still 0 identifier |= b & 0x7F; fullIdentifier <<= 8; fullIdentifier |= b; if (identifier == 0) throw new IOException("Invalid ASN.1 identifier (0 while reading constructed identifier)."); } while ((b & 0x80) != 0); } return identifier; }