/// <summary> /// Save node data into Stream. /// </summary> /// <param name="xdata">Stream.</param> /// <returns>true:Succeed; false:failed.</returns> public bool SaveData(Stream xdata) { bool retval = true; long nodeCount = ChildNodeCount; xdata.WriteByte(tag); int tmpLen = Asn1Util.DERLengthEncode(xdata, (ulong)dataLength); if ((tag) == Asn1Tag.BIT_STRING) { xdata.WriteByte(unusedBits); } if (nodeCount == 0) { if (data != null) { xdata.Write(data, 0, data.Length); } } else { Asn1Node tempNode; int i; for (i = 0; i < nodeCount; i++) { tempNode = GetChildNode(i); retval = tempNode.SaveData(xdata); } } return(retval); }
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"); }
/// <summary> /// Encode single OID value. /// </summary> /// <param name="bt">output stream.</param> /// <param name="v">source value.</param> protected void EncodeValue(Stream bt, ulong v) { for (int i = (Asn1Util.BitPrecision(v) - 1) / 7; i > 0; i--) { bt.WriteByte((byte)(0x80 | ((v >> (i * 7)) & 0x7f))); } bt.WriteByte((byte)(v & 0x7f)); }
/// <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> /// Decode ASN.1 encoded node Stream data. /// </summary> /// <param name="xdata">Stream data.</param> /// <returns>true:Succeed, false:Failed.</returns> protected bool GeneralDecode(Stream xdata) { bool retval = false; long nodeMaxLen; nodeMaxLen = xdata.Length - xdata.Position; tag = (byte)xdata.ReadByte(); long start, end; start = xdata.Position; dataLength = Asn1Util.DerLengthDecode(xdata, ref isIndefiniteLength); if (dataLength < 0) { return(retval); // Node data length can not be negative. } end = xdata.Position; lengthFieldBytes = end - start; if (nodeMaxLen < (dataLength + TagLength + lengthFieldBytes)) { return(retval); } if (ParentNode == null || ((ParentNode.tag & Asn1TagClasses.CONSTRUCTED) == 0)) { if ((tag & Asn1Tag.TAG_MASK) <= 0 || (tag & Asn1Tag.TAG_MASK) > 0x1E) { return(retval); } } if (tag == Asn1Tag.BIT_STRING) { // First byte of BIT_STRING is unused bits. // BIT_STRING data does not include this byte. // Fixed by Gustaf Björklund. if (dataLength < 1) { return(retval); // We cannot read less than 1 - 1 bytes. } unusedBits = (byte)xdata.ReadByte(); data = new byte[dataLength - 1]; xdata.Read(data, 0, (int)(dataLength - 1)); } else { data = new byte[dataLength]; xdata.Read(data, 0, (int)(dataLength)); } retval = true; return(retval); }
/// <summary> /// Retrieve PEM file heading. /// </summary> /// <param name="fileName">source file name.</param> /// <returns>heading string.</returns> public static string GetPemFileHeader(string fileName) { try { FileStream fs = new FileStream(fileName, FileMode.Open); byte[] data = new byte[fs.Length]; fs.Read(data, 0, data.Length); fs.Close(); string dataStr = Asn1Util.BytesToString(data); return(GetPemHeader(dataStr)); } catch { return(""); } }
/// <summary> /// Check if a file is PEM formated. /// </summary> /// <param name="fileName">source file name.</param> /// <returns>true:Yes, false:No.</returns> public static bool IsPemFormatedFile(string fileName) { bool retval = false; try { FileStream fs = new FileStream(fileName, System.IO.FileMode.Open); byte[] data = new byte[fs.Length]; fs.Read(data, 0, data.Length); fs.Close(); string dataStr = Asn1Util.BytesToString(data); retval = IsPemFormated(dataStr); } catch { retval = false; } return(retval); }
private string FormatLineHexString(string lStr, int indent, int lineLen, string msg) { string retval = ""; indent += indentStep; int realLen = lineLen - indent; int sLen = indent; int currentp; for (currentp = 0; currentp < msg.Length; currentp += realLen) { if (currentp + realLen > msg.Length) { retval += "\r\n" + lStr + Asn1Util.GenStr(sLen, ' ') + msg.Substring(currentp, msg.Length - currentp); } else { retval += "\r\n" + lStr + Asn1Util.GenStr(sLen, ' ') + msg.Substring(currentp, realLen); } } return(retval); }
/// <summary> /// Retrieve the node description. /// </summary> /// <param name="pureHexMode">true:Return hex string only; /// false:Convert to more readable string depending on the node tag.</param> /// <returns>string</returns> public string GetDataStr(bool pureHexMode) { const int lineLen = 32; string dataStr = ""; if (pureHexMode) { dataStr = Asn1Util.FormatString(Asn1Util.ToHexString(data), lineLen, 2); } else { switch (tag) { case Asn1Tag.BIT_STRING: dataStr = Asn1Util.FormatString(Asn1Util.ToHexString(data), lineLen, 2); break; case Asn1Tag.OBJECT_IDENTIFIER: Oid xoid = new Oid(); dataStr = xoid.Decode(new MemoryStream(data)); break; case Asn1Tag.RELATIVE_OID: RelativeOid roid = new RelativeOid(); dataStr = roid.Decode(new MemoryStream(data)); break; case Asn1Tag.PRINTABLE_STRING: case Asn1Tag.IA5_STRING: case Asn1Tag.UNIVERSAL_STRING: case Asn1Tag.VISIBLE_STRING: case Asn1Tag.NUMERIC_STRING: case Asn1Tag.UTC_TIME: case Asn1Tag.BMPSTRING: case Asn1Tag.GENERAL_STRING: case Asn1Tag.GENERALIZED_TIME: dataStr = Asn1Util.BytesToString(data); break; case Asn1Tag.UTF8_STRING: UTF8Encoding utf8 = new UTF8Encoding(); dataStr = utf8.GetString(data); break; case Asn1Tag.INTEGER: dataStr = Asn1Util.FormatString(Asn1Util.ToHexString(data), lineLen, 2); break; default: if ((tag & Asn1Tag.TAG_MASK) == 6 || // Visible string for certificate Asn1Util.IsAsciiString(Data)) { dataStr = Asn1Util.BytesToString(data); } else { dataStr = Asn1Util.FormatString(Asn1Util.ToHexString(data), lineLen, 2); } break; } ; } return(dataStr); }
/// <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); }