private string GetHexPrintingStr(Asn1Node startNode, string baseLine, string lStr, int lineLen) { string nodeStr = ""; string iStr = GetIndentStr(startNode); string dataStr = Asn1Util.ToHexString(data); if (dataStr.Length > 0) { if (baseLine.Length + dataStr.Length < lineLen) { nodeStr += baseLine + "'" + dataStr + "'"; } else { nodeStr += baseLine + FormatLineHexString( lStr, iStr.Length, lineLen, dataStr ); } } else { nodeStr += baseLine; } return(nodeStr + "\r\n"); }
private Asn1Node(Asn1Node parentNode, long dataOffset) { Init(); deepness = parentNode.Deepness + 1; this.parentNode = parentNode; this.dataOffset = dataOffset; }
/// <summary> /// Get descendant node by node path. /// </summary> /// <param name="nodePath">relative node path that refer to current node.</param> /// <returns></returns> public Asn1Node GetDescendantNodeByPath(string nodePath) { Asn1Node retval = this; if (nodePath == null) { return(retval); } nodePath = nodePath.TrimEnd().TrimStart(); if (nodePath.Length < 1) { return(retval); } string[] route = nodePath.Split('/'); try { for (int i = 1; i < route.Length; i++) { retval = retval.GetChildNode(Convert.ToInt32(route[i])); } } catch { retval = null; } return(retval); }
/// <summary> /// Get node by OID. /// </summary> /// <param name="oid">OID.</param> /// <param name="startNode">Starting node.</param> /// <returns>Null or Asn1Node.</returns> static public Asn1Node GetDecendantNodeByOid(string oid, Asn1Node startNode) { Asn1Node retval = null; Oid xoid = new Oid(); for (int i = 0; i < startNode.ChildNodeCount; i++) { Asn1Node childNode = startNode.GetChildNode(i); int tmpTag = childNode.tag & Asn1Tag.TAG_MASK; if (tmpTag == Asn1Tag.OBJECT_IDENTIFIER) { if (oid == xoid.Decode(childNode.Data)) { retval = childNode; break; } } retval = GetDecendantNodeByOid(oid, childNode); if (retval != null) { break; } } return(retval); }
/// <summary> /// Recursively set all the node data length. /// </summary> /// <param name="node"></param> /// <returns>node data length.</returns> protected static long ResetBranchDataLength(Asn1Node node) { long retval = 0; long childDataLength = 0; if (node.ChildNodeCount < 1) { if (node.data != null) { childDataLength += node.data.Length; } } else { for (int i = 0; i < node.ChildNodeCount; i++) { childDataLength += ResetBranchDataLength(node.GetChildNode(i)); } } node.dataLength = childDataLength; if (node.tag == Asn1Tag.BIT_STRING) { node.dataLength += BitStringUnusedFiledLength; } ResetDataLengthFieldWidth(node); retval = node.dataLength + TagLength + node.lengthFieldBytes; return(retval); }
/// <summary> /// Insert a node in the children list after the pointed node. /// </summary> /// <param name="xdata">Asn1Node that will be instered in the children list.</param> /// <param name="index">0 based index.</param> /// <returns>New node index.</returns> public int InsertChildAfter(Asn1Node xdata, int index) { int xindex = index + 1; childNodeList.Insert(xindex, xdata); RecalculateTreePar(); return(xindex); }
/// <summary> /// Insert a node in the children list after the pointed node. /// </summary> /// <param name="xdata">Asn1Node</param> /// <param name="indexNode">Index node.</param> /// <returns>New node index.</returns> public int InsertChildAfter(Asn1Node xdata, Asn1Node indexNode) { int index = childNodeList.IndexOf(indexNode) + 1; childNodeList.Insert(index, xdata); RecalculateTreePar(); return(index); }
/// <summary> /// Encode the node data length field and set lengthFieldBytes and dataLength. /// </summary> /// <param name="node">The node needs to be reset.</param> protected static void ResetDataLengthFieldWidth(Asn1Node node) { MemoryStream tempStream = new MemoryStream(); Asn1Util.DERLengthEncode(tempStream, (ulong)node.dataLength); node.lengthFieldBytes = tempStream.Length; tempStream.Close(); }
/// <summary> /// Remove the child from children node list. /// </summary> /// <param name="node">The node needs to be removed.</param> /// <returns></returns> public Asn1Node RemoveChild(Asn1Node node) { Asn1Node retval = null; int i = childNodeList.IndexOf(node); retval = RemoveChild(i); return(retval); }
/// <summary> /// Retrieve child node by index. /// </summary> /// <param name="index">0 based index.</param> /// <returns>0 based index.</returns> public Asn1Node GetChildNode(int index) { Asn1Node retval = null; if (index < ChildNodeCount) { retval = (Asn1Node)childNodeList[index]; } return(retval); }
/// <summary> /// Retrieve all the node count in the node subtree. /// </summary> /// <param name="node">starting node.</param> /// <returns>long integer node count in the node subtree.</returns> public static long GetDescendantNodeCount(Asn1Node node) { long count = 0; count += node.ChildNodeCount; for (int i = 0; i < node.ChildNodeCount; i++) { count += GetDescendantNodeCount(node.GetChildNode(i)); } return(count); }
/// <summary> /// Clone a new Asn1Node by current node. /// </summary> /// <returns>new node.</returns> public Asn1Node Clone() { MemoryStream ms = new MemoryStream(); this.SaveData(ms); ms.Position = 0; Asn1Node node = new Asn1Node(); node.LoadData(ms); return(node); }
private void Init() { childNodeList = new ArrayList(); data = null; dataLength = 0; lengthFieldBytes = 0; unusedBits = 0; tag = Asn1Tag.SEQUENCE | Asn1TagClasses.CONSTRUCTED; childNodeList.Clear(); deepness = 0; parentNode = null; }
/// <summary> /// Generate the node indent string. /// </summary> /// <param name="startNode">The node.</param> /// <returns>Text string.</returns> protected string GetIndentStr(Asn1Node startNode) { string retval = ""; long startLen = 0; if (startNode != null) { startLen = startNode.Deepness; } for (long i = 0; i < deepness - startLen; i++) { retval += " "; } return(retval); }
/// <summary> /// Check if the string is ASN.1 encoded hex string. /// </summary> /// <param name="dataStr">The string.</param> /// <returns>true:Yes, false:No.</returns> public static bool IsAsn1EncodedHexStr(string dataStr) { bool retval = false; try { byte[] data = HexStrToBytes(dataStr); if (data.Length > 0) { Asn1Node node = new Asn1Node(); retval = node.LoadData(data); } } catch { retval = false; } return(retval); }
/// <summary> /// Recursively set all the child parameters, except dataLength. /// dataLength is set by ResetBranchDataLength. /// </summary> /// <param name="xNode">Starting node.</param> /// <param name="subOffset">Starting node offset.</param> protected void ResetChildNodePar(Asn1Node xNode, long subOffset) { int i; if (xNode.tag == Asn1Tag.BIT_STRING) { subOffset++; } Asn1Node tempNode; for (i = 0; i < xNode.ChildNodeCount; i++) { tempNode = xNode.GetChildNode(i); tempNode.parentNode = xNode; tempNode.dataOffset = subOffset; tempNode.deepness = xNode.deepness + 1; tempNode.path = xNode.path + '/' + i.ToString(); subOffset += TagLength + tempNode.lengthFieldBytes; ResetChildNodePar(tempNode, subOffset); subOffset += tempNode.dataLength; } }
/// <summary> /// Remove a child from children node list by index. /// </summary> /// <param name="index">0 based index.</param> /// <returns>The Asn1Node just removed from the list.</returns> public Asn1Node RemoveChild(int index) { Asn1Node retval = null; if (index < (childNodeList.Count - 1)) { retval = (Asn1Node)childNodeList[index + 1]; } childNodeList.RemoveAt(index); if (retval == null) { if (childNodeList.Count > 0) { retval = (Asn1Node)childNodeList[childNodeList.Count - 1]; } else { retval = this; } } RecalculateTreePar(); return(retval); }
/// <summary> /// Add child node at the end of children list. /// </summary> /// <param name="xdata">the node that will be add in.</param> public void AddChild(Asn1Node xdata) { childNodeList.Add(xdata); RecalculateTreePar(); }
/// <summary> /// Decode ASN.1 encoded complex data type Stream data. /// </summary> /// <param name="xdata">Stream data.</param> /// <returns>true:Succeed, false:Failed.</returns> protected bool ListDecode(Stream xdata) { bool retval = false; long originalPosition = xdata.Position; long childNodeMaxLen; try { childNodeMaxLen = xdata.Length - xdata.Position; tag = (byte)xdata.ReadByte(); long start, end, offset; start = xdata.Position; dataLength = Asn1Util.DerLengthDecode(xdata, ref isIndefiniteLength); if (dataLength < 0 || childNodeMaxLen < dataLength) { return(retval); } end = xdata.Position; lengthFieldBytes = end - start; offset = dataOffset + TagLength + lengthFieldBytes; Stream secData; byte[] secByte; if (tag == Asn1Tag.BIT_STRING) { // First byte of BIT_STRING is unused bits. // BIT_STRING data does not include this byte. unusedBits = (byte)xdata.ReadByte(); dataLength--; offset++; } if (dataLength <= 0) { return(retval); // List data length cann't be zero. } secData = new MemoryStream((int)dataLength); secByte = new byte[dataLength]; xdata.Read(secByte, 0, (int)(dataLength)); if (tag == Asn1Tag.BIT_STRING) { dataLength++; } secData.Write(secByte, 0, secByte.Length); secData.Position = 0; while (secData.Position < secData.Length) { Asn1Node node = new Asn1Node(this, offset); node.parseEncapsulatedData = this.parseEncapsulatedData; start = secData.Position; if (!node.InternalLoadData(secData)) { return(retval); } AddChild(node); end = secData.Position; offset += end - start; } retval = true; } finally { if (!retval) { xdata.Position = originalPosition; ClearAll(); } } return(retval); }
public string GetText(Asn1Node startNode, int lineLen) { throw new NotImplementedException(); }
/// <summary> /// Insert a node in the children list before the pointed index. /// </summary> /// <param name="xdata">Asn1Node</param> /// <param name="index">0 based index.</param> /// <returns>New node index.</returns> public int InsertChild(Asn1Node xdata, int index) { childNodeList.Insert(index, xdata); RecalculateTreePar(); return(index); }