//+-------------------------------------------------------------------------------+ //| 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; using System.Collections.Specialized; namespace LipingShare.LCLib.Asn1Processor { /// /// Summary description for OID. /// This class is used to encode and decode OID strings. /// internal class Oid { /// /// Retrieve OID name by OID string. /// /// source OID string. /// OID name. public string GetOidName(string inOidStr) { if (oidDictionary == null) //Initialize oidDictionary: { oidDictionary = new StringDictionary(); // string oidStr = ""; // string oidDesc = ""; // bool loadOidError = false; // int dbCounter = 0; } return oidDictionary[inOidStr]; } /// /// Encode OID string to byte array. /// /// source string. /// encoded array. public byte[] Encode(string oidStr) { MemoryStream ms = new MemoryStream(); Encode(ms, oidStr); ms.Position = 0; byte[] retval = new byte[ms.Length]; ms.Read(retval, 0, retval.Length); ms.Close(); return retval; } /// /// Decode OID byte array to OID string. /// /// source byte array. /// result OID string. public string Decode(byte[] data) { MemoryStream ms = new MemoryStream(data); ms.Position = 0; string retval = Decode(ms); ms.Close(); return retval; } /// /// Encode OID string and put result into /// /// output stream. /// source OID string. public virtual void Encode(Stream bt, string oidStr) //TODO { string[] oidList = oidStr.Split('.'); if (oidList.Length < 2) throw new Exception("Invalid OID string."); ulong[] values = new ulong[oidList.Length]; for (int i = 0; i < oidList.Length; i++) { values[i] = Convert.ToUInt64(oidList[i]); } bt.WriteByte((byte)(values[0] * 40 + values[1])); for (int i = 2; i < values.Length; i++) EncodeValue(bt, values[i]); } /// /// Decode OID and return OID string. /// /// source stream. /// result OID string. public virtual string Decode(Stream bt) { string retval = ""; byte b; ulong v = 0; b = (byte)bt.ReadByte(); retval += Convert.ToString(b / 40); retval += "." + Convert.ToString(b % 40); while (bt.Position < bt.Length) { try { DecodeValue(bt, ref v); retval += "." + v.ToString(); } catch (Exception e) { throw new Exception("Failed to decode OID value: " + e.Message); } } return retval; } /// /// OID dictionary. /// private static StringDictionary oidDictionary = null; /// /// Default constructor /// public Oid() { } /// /// Encode single OID value. /// /// output stream. /// source value. 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)); } /// /// Decode single OID value. /// /// source stream. /// output value /// OID value bytes. protected int DecodeValue(Stream bt, ref ulong v) { byte b; int i = 0; v = 0; while (true) { b = (byte)bt.ReadByte(); i++; v <<= 7; v += (ulong)(b & 0x7f); if ((b & 0x80) == 0) return i; } } } }