예제 #1
0
        /// <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);
        }
예제 #2
0
        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");
        }
예제 #3
0
 /// <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));
 }
예제 #4
0
        /// <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();
        }
예제 #5
0
        /// <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);
        }
예제 #6
0
 /// <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("");
     }
 }
예제 #7
0
        /// <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);
        }
예제 #8
0
        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);
        }
예제 #9
0
        /// <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);
        }
예제 #10
0
        /// <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);
        }