Click here to Skip to main content
15,897,226 members
Articles / Programming Languages / C#

ASN.1 Editor

Rate me:
Please Sign up or sign in to vote.
4.96/5 (105 votes)
30 Jun 2008CPOL2 min read 469.9K   30.6K   102  
An editor to view, analyse and modify ASN.1 DER encoded data
//+-------------------------------------------------------------------------------+
//| Copyright (c) 2003 Liping Dai. All rights reserved.                           |
//| Web: www.lipingshare.com                                                      |
//| Email: lipingshare@yahoo.com                                                  |
//|                                                                               |
//| Copyright and Permission Details:                                             |
//| =================================                                             |
//| Permission is hereby granted, free of charge, to any person obtaining a copy  |
//| of this software and associated documentation files (the "Software"), to deal |
//| in the Software without restriction, including without limitation the rights  |
//| to use, copy, modify, merge, publish, distribute, and/or sell copies of the   |
//| Software, subject to the following conditions:                                |
//|                                                                               |
//| 1. Redistributions of source code must retain the above copyright notice, this|
//| list of conditions and the following disclaimer.                              |
//|                                                                               |
//| 2. Redistributions in binary form must reproduce the above copyright notice,  |
//| this list of conditions and the following disclaimer in the documentation     |
//| and/or other materials provided with the distribution.                        |
//|                                                                               |
//| THE SOFTWARE PRODUCT IS PROVIDED �AS IS� WITHOUT WARRANTY OF ANY KIND,        |
//| EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED         |
//| WARRANTIES OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR        |
//| A PARTICULAR PURPOSE.                                                         |
//+-------------------------------------------------------------------------------+

using System;
using System.IO;

namespace LipingShare.LCLib.Asn1Processor
{
	/// <summary>
	/// ASN.1 encoded data parser.
	/// This a higher level class which unilized Asn1Node class functionality to 
	/// provide functions for ASN.1 encoded files. 
	/// </summary>
	public class Asn1Parser
	{
        private byte[] rawData;
        private Asn1Node rootNode = new Asn1Node();

		/// <summary>
		/// Get/Set parseEncapsulatedData. Reloading data is required after this property is reset.
		/// </summary>
		bool ParseEncapsulatedData 
		{ 
			get
			{
				return rootNode.ParseEncapsulatedData;
			}
			set
			{
				rootNode.ParseEncapsulatedData = value;
			}
		}

        /// <summary>
        /// Constructor.
        /// </summary>
		public Asn1Parser()
		{
		}

        /// <summary>
        /// Get raw ASN.1 encoded data.
        /// </summary>
		public byte[] RawData
		{
			get
			{
				return rawData;
			}
		}

        /// <summary>
        /// Load ASN.1 encoded data from a file.
        /// </summary>
        /// <param name="fileName">File name.</param>
        public void LoadData(string fileName)
        {
            FileStream fs = new FileStream(fileName, FileMode.Open);
            rawData = new byte[fs.Length];
            fs.Read(rawData, 0, (int)fs.Length);
            fs.Close();
            MemoryStream ms = new MemoryStream(rawData);
            LoadData(ms);
        }

		/// <summary>
		/// Load PEM formated file.
		/// </summary>
		/// <param name="fileName">PEM file name.</param>
		public void LoadPemData(string fileName)
		{
			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);
			if (Asn1Util.IsPemFormated(dataStr))
			{
				Stream ms = Asn1Util.PemToStream(dataStr); 
				ms.Position = 0;
				LoadData(ms);
			}
			else
			{
				throw new Exception("It is a invalid PEM file: " + fileName);
			}
		}

        /// <summary>
        /// Load ASN.1 encoded data from Stream.
        /// </summary>
        /// <param name="stream">Stream data.</param>
        public void LoadData(Stream stream)
        {
            stream.Position = 0;
            if (!rootNode.LoadData(stream))
            {
                throw new Exception("Failed to load data.");
            }
            rawData = new byte[stream.Length];
            stream.Position = 0;
            stream.Read(rawData, 0, rawData.Length);
        }

        /// <summary>
        /// Save data into a file.
        /// </summary>
        /// <param name="fileName">File name.</param>
        public void SaveData(string fileName)
        {
            FileStream fs = new FileStream(fileName, FileMode.Create);
            rootNode.SaveData(fs);
            fs.Close();
        }

        /// <summary>
        /// Get root node.
        /// </summary>
        public Asn1Node RootNode
        {
            get
            {
                return rootNode;
            }
        }

        /// <summary>
        /// Get a node by path string.
        /// </summary>
        /// <param name="nodePath">Path string.</param>
        /// <returns>Asn1Node or null.</returns>
        public Asn1Node GetNodeByPath(string nodePath)
        {
            return rootNode.GetDescendantNodeByPath(nodePath);
        }

		/// <summary>
		/// Get a node by OID.
		/// </summary>
		/// <param name="oid">OID string.</param>
		/// <returns>Asn1Node or null.</returns>
		public Asn1Node GetNodeByOid(string oid)
		{
			return Asn1Node.GetDecendantNodeByOid(oid, rootNode);
		}       

        /// <summary>
        /// Generate node text header. This method is used by GetNodeText to put heading.
        /// </summary>
        /// <param name="lineLen">Line length.</param>
        /// <returns>Header string.</returns>
        static public string GetNodeTextHeader(int lineLen)
        {
            string header = String.Format("Offset| Len  |LenByte|\r\n");
            header += "======+======+=======+" + Asn1Util.GenStr(lineLen+10, '=') + "\r\n";
            return header;
        }

        /// <summary>
        /// Generate the root node text description.
        /// </summary>
        /// <returns>Text string.</returns>
        public override string ToString()
        {
            return GetNodeText(rootNode, 100);
        }

        /// <summary>
        /// Generate node text description. It uses GetNodeTextHeader to generate
        /// the heading and Asn1Node.GetText to generate the node text.
        /// </summary>
        /// <param name="node">Target node.</param>
        /// <param name="lineLen">Line length.</param>
        /// <returns>Text string.</returns>
        public static string GetNodeText(Asn1Node node, int lineLen)
        {
            string nodeStr = GetNodeTextHeader(lineLen);
            nodeStr +=node.GetText(node, lineLen);
            return nodeStr;
        }

	}
}


By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
United States United States
Liping Dai has worked in IT industry more than 17 years. He moved to Canada in 1996. After worked in Toronto for 4 years, he relocated to Silicon Valley. He has strong passion in the area of Multi-core/Multi thread programming, Parallel Computing, Image Reorganization, Secure Communication, and Mobile Device development.

Comments and Discussions