/// <summary>
 /// Initializes a new instance of the <see cref="Asn1TagInfo"/> struct.
 /// </summary>
 /// <param name="asn1Tag">The asn1 tag.</param>
 /// <param name="constructType">Type of the construct.</param>
 public Asn1TagInfo(Asn1Tag asn1Tag, ConstructType constructType)
 {
     this.Asn1ClassType = Asn1Class.Universal;
     this.Asn1ConstructType = constructType;
     this.Asn1SnmpTagType = Asn1SnmpTag.NotSnmpData;
     this.Asn1TagType = asn1Tag;
 }
 /// <summary>
 /// Initializes a new instance of the <see cref="Asn1TagInfo"/> struct.
 /// </summary>
 /// <param name="asn1Tag">The asn1 tag.</param>
 /// <param name="constructType">Type of the construct.</param>
 /// <param name="asn1Class">The asn1 class.</param>
 public Asn1TagInfo(Asn1Tag asn1Tag, ConstructType constructType, Asn1Class asn1Class)
 {
     this.Asn1ClassType = asn1Class;
     this.Asn1ConstructType = constructType;
     this.Asn1SnmpTagType = Asn1SnmpTag.NotSnmpData;
     this.Asn1TagType = asn1Tag;
 }
 /// <summary>
 /// Initializes a new instance of the <see cref="Asn1TagInfo"/> struct.
 /// </summary>
 /// <param name="asn1SnmpTag">The asn1 SNMP tag.</param>
 /// <param name="constructType">Type of the construct.</param>
 public Asn1TagInfo(Asn1SnmpTag asn1SnmpTag, ConstructType constructType)
 {
     this.Asn1ClassType = Asn1Class.Application;
     this.Asn1ConstructType = constructType;
     this.Asn1SnmpTagType = asn1SnmpTag;
     this.Asn1TagType = Asn1Tag.NotAsn1Data;
 }
Exemple #4
0
 /// <summary>
 /// Initializes a new instance of the <see cref="Asn1TagInfo"/> struct.
 /// </summary>
 /// <param name="asn1SnmpTag">The asn1 SNMP tag.</param>
 /// <param name="constructType">Type of the construct.</param>
 public Asn1TagInfo(Asn1SnmpTag asn1SnmpTag, ConstructType constructType)
 {
     Asn1ClassType     = Asn1Class.Application;
     Asn1ConstructType = constructType;
     Asn1SnmpTagType   = asn1SnmpTag;
     Asn1TagType       = Asn1Tag.NotAsn1Data;
 }
Exemple #5
0
 /// <summary>
 /// Initializes a new instance of the <see cref="Asn1Object{T}"/> class.
 /// </summary>
 /// <param name="asn1Class">Class of given Asn.1 object.</param>
 /// <param name="constructed">Constructed/Primitive bit of identifier octet.</param>
 /// <param name="asn1Tag">Tag number or type of Asn.1 object.</param>
 /// <param name="content">Raw content to be decoded.</param>
 protected Asn1Object(Asn1Class asn1Class, bool constructed, int asn1Tag, SubStream content)
     : base(asn1Class, constructed, asn1Tag)
 {
     this.RawContent = content;
     this.RawContent.Seek(this.RawContent.Length, SeekOrigin.Current);
     this.toBeParsed = true;
 }
Exemple #6
0
 /// <summary>
 /// Initializes a new instance of the <see cref="Asn1TagInfo"/> struct.
 /// </summary>
 /// <param name="asn1Tag">The asn1 tag.</param>
 /// <param name="constructType">Type of the construct.</param>
 public Asn1TagInfo(Asn1Tag asn1Tag, ConstructType constructType)
 {
     Asn1ClassType     = Asn1Class.Universal;
     Asn1ConstructType = constructType;
     Asn1SnmpTagType   = Asn1SnmpTag.NotSnmpData;
     Asn1TagType       = asn1Tag;
 }
Exemple #7
0
 /// <summary>
 /// Initializes a new instance of the <see cref="Asn1TagInfo"/> struct.
 /// </summary>
 /// <param name="asn1Tag">The asn1 tag.</param>
 /// <param name="constructType">Type of the construct.</param>
 /// <param name="asn1Class">The asn1 class.</param>
 public Asn1TagInfo(Asn1Tag asn1Tag, ConstructType constructType, Asn1Class asn1Class)
 {
     Asn1ClassType     = asn1Class;
     Asn1ConstructType = constructType;
     Asn1SnmpTagType   = Asn1SnmpTag.NotSnmpData;
     Asn1TagType       = asn1Tag;
 }
Exemple #8
0
        /// <summary>
        /// Writes Identifier octet of ASN.1 object.
        /// </summary>
        /// <param name="asn1Class">Class of given Asn.1 object.</param>
        /// <param name="tagNumber">Tag number or type of Asn.1 object.</param>
        /// <param name="constructed">Constructed/Primitive bit of identifier octet.</param>
        /// <returns>Encoded identifier octet of ASN.1 object.</returns>
        internal static byte[] WriteTag(Asn1Class asn1Class, int tagNumber, bool constructed = false)
        {
            byte[] tagOctets = null;
            var    classPart = (int)asn1Class;
            var    typePart  = tagNumber & 0x1F; // clear bits 8 to 6

            int tag = classPart;

            if (constructed)
            {
                tag = tag | 0x20;
            }

            if (asn1Class == Asn1Class.ContextSpecific && tagNumber > 30)
            {
                tag = tag + 31; // in long form bits 1-5 have value of 1 and tag number is encoded in the following octets

                var tagValueOctets = new List <byte>();
                tagValueOctets.Add((byte)tag);
                DerWriterUtils.SevenBitEncode(tagNumber, tagValueOctets);

                tagOctets = tagValueOctets.ToArray();
            }
            else
            {
                tag       = tag + typePart;
                tagOctets = new byte[1] {
                    (byte)tag
                };
            }

            return(tagOctets);
        }
Exemple #9
0
        /// <summary>
        /// Reads one node as ASN.1 object.
        /// </summary>
        /// <typeparam name="T">Type of objects to parse. Basically it has to be Asn1BaseObject</typeparam>
        /// <param name="foundObject">Parsed ASN.1 Object.</param>
        /// <returns>Itself.</returns>
        public BerReader ReadOne <T>(out T foundObject)
            where T : Asn1ObjectBase
        {
            var nodeStartOffset = this.inputStream.Position;

            // get first byte - Identifier octet
            var firstByte = this.inputStream.ReadByte();

            // break the cycle when stream ends
            if (firstByte == -1)
            {
                // TODO: return or throw?
                // end of stream
                foundObject = null;
                return(this);
            }

            // parse type of ASN.1 node
            Asn1Class asn1Class   = ReadAsn1Class(firstByte);
            var       constructed = (firstByte & 32) == 32;

            // if first byte is not enough to get ASN1 tag, we will read more from input stream
            int tag = ReadAsn1Tag(firstByte, this.inputStream);

            // read length - Length octet(s) as many as needed
            long length = this.ReadLength();
            long substreamLength;

            // TODO: not sure if it's correct. Need to stop parsing because length of node greater than stream length
            if (length > this.inputStream.Length)
            {
                substreamLength = 0;
                foundObject     = null;
                return(this);
            }

            substreamLength = length;
            if (length == -1)
            {
                substreamLength = this.inputStream.Length;
            }

            // read content - Value octets
            var contentStream = new SubStream(this.inputStream, substreamLength);

            // make an instance of exact ASN.1 object
            foundObject = MakeInstanceOfAsn1Object <T>(nodeStartOffset, asn1Class, constructed, tag, contentStream);

            return(this);
        }
Exemple #10
0
 /// <summary>
 /// Initializes a new instance of the <see cref="Asn1TagInfo"/> struct.
 /// </summary>
 /// <param name="asn1Class">The asn1 class.</param>
 /// <param name="constructType">Type of the construct.</param>
 /// <param name="tagType">Type of the tag.</param>
 internal Asn1TagInfo(int asn1Class, int constructType, int tagType)
 {
     Asn1ClassType     = (Asn1Class)asn1Class;
     Asn1ConstructType = (ConstructType)constructType;
     if (Asn1ClassType == Asn1Class.Application)
     {
         Asn1SnmpTagType = (Asn1SnmpTag)tagType;
         Asn1TagType     = Asn1Tag.NotAsn1Data;
     }
     else
     {
         Asn1TagType     = (Asn1Tag)tagType;
         Asn1SnmpTagType = Asn1SnmpTag.NotSnmpData;
     }
 }
Exemple #11
0
        /// <summary>
        /// Writes Identifier octet of ASN.1 object.
        /// </summary>
        /// <param name="asn1Class">Class of given Asn.1 object.</param>
        /// <param name="tagNumber">Tag number or type of Asn.1 object.</param>
        /// <param name="constructed">Constructed/Primitive bit of identifier octet.</param>
        /// <returns>Encoded identifier octet of ASN.1 object.</returns>
        internal static byte WriteTag(Asn1Class asn1Class, int tagNumber, bool constructed = false)
        {
            // TODO: support tag number > 30
            if (asn1Class == Asn1Class.ContextSpecific && tagNumber > 30)
            {
                throw new NotSupportedException("Currently only tag numbers 0-30 are supported.");
            }

            var classPart = (int)asn1Class;
            var typePart  = tagNumber & 0x1F; // clear bits 8 to 6

            int tag = classPart + typePart;

            if (constructed)
            {
                tag = tag | 0x20;
            }

            return((byte)tag);
        }
Exemple #12
0
 /// <summary>
 /// Encodes the type of the class construct.
 /// </summary>
 /// <param name="data">The data.</param>
 /// <param name="offset">The offset.</param>
 /// <param name="asn1Class">The asn1 class.</param>
 /// <param name="constructType">Type of the construct.</param>
 /// <param name="tag">The tag.</param>
 /// <returns>new offset value in int</returns>
 public static int EncodeClassConstructType(this byte[] data, int offset, Asn1Class asn1Class, ConstructType constructType, byte tag)
 {
     data[offset] = (byte)(((byte)asn1Class << 6) | ((byte)constructType << 5) | tag);
     return(offset + 1);
 }
Exemple #13
0
 /// <summary>
 /// Encodes the type of the class construct.
 /// </summary>
 /// <param name="data">The data.</param>
 /// <param name="offset">The offset.</param>
 /// <param name="asn1Class">The asn1 class.</param>
 /// <param name="constructType">Type of the construct.</param>
 /// <param name="tag">The tag.</param>
 /// <returns>new offset value in int</returns>
 public static int EncodeClassConstructType(this byte[] data, int offset, Asn1Class asn1Class, ConstructType constructType, byte tag)
 {
     data[offset] = (byte)(((byte)asn1Class << 6) | ((byte)constructType << 5) | tag);
     return offset + 1;
 }
 /// <summary>
 /// Initializes a new instance of the <see cref="Asn1Sequence"/> class.
 /// </summary>
 /// <param name="asn1Class">Class of given Asn.1 object.</param>
 /// <param name="content">Content to be encoded.</param>
 public Asn1Sequence(Asn1Class asn1Class, List <Asn1ObjectBase> content)
     : base(asn1Class, true, (int)Asn1Type.Sequence, content)
 {
 }
Exemple #15
0
 /// <summary>
 /// Initializes a new instance of the <see cref="Asn1Set"/> class.
 /// Preferably used when reading SET.
 /// The encoding of a set value shall be constructed.
 /// </summary>
 /// <param name="asn1Class">Class of given Asn.1 object.</param>
 /// <param name="content">BER encoded value in a Stream.</param>
 /// <param name="constructed">Flag if type is constructed or primitive.</param>
 internal Asn1Set(Asn1Class asn1Class, SubStream content, bool constructed)
     : base(asn1Class, constructed, (int)Asn1Type.Set, content)
 {
 }
Exemple #16
0
 /// <summary>
 /// Initializes a new instance of the <see cref="Asn1Set"/> class.
 /// Preferably used when encoding SET.
 /// The encoding of a set value shall be constructed.
 /// </summary>
 /// <param name="asn1Class">Class of given Asn.1 object.</param>
 /// <param name="content">Content to be encoded.</param>
 /// <param name="constructed">Flag if type is constructed or primitive.</param>
 public Asn1Set(Asn1Class asn1Class, List <Asn1ObjectBase> content, bool constructed = true)
     : base(asn1Class, constructed, (int)Asn1Type.Set, content)
 {
 }
Exemple #17
0
 public Asn1TypeAttribute(Asn1Tag asn1Tag, ConstructType constructType, Asn1Class asn1Class)
 {
     this.tagInfo = new Asn1TagInfo(asn1Tag, constructType, asn1Class);
 }
Exemple #18
0
 /// <summary>
 /// Initializes a new instance of the <see cref="Asn1Object{T}"/> class.
 /// </summary>
 /// <param name="asn1Class">Class of given Asn.1 object.</param>
 /// <param name="constructed">Constructed/Primitive bit of identifier octet.</param>
 /// <param name="asn1Tag">Tag number or type of Asn.1 object.</param>
 /// <param name="content">Content to be encoded.</param>
 protected Asn1Object(Asn1Class asn1Class, bool constructed, int asn1Tag, T content)
     : base(asn1Class, constructed, asn1Tag)
 {
     this.content    = content;
     this.toBeParsed = false;
 }
 public Asn1TypeAttribute(Asn1Tag asn1Tag, ConstructType constructType, Asn1Class asn1Class)
 {
     this.tagInfo = new Asn1TagInfo(asn1Tag, constructType, asn1Class);
 }
 /// <summary>
 /// Initializes a new instance of the <see cref="Asn1Object{T}"/> class.
 /// </summary>
 /// <param name="asn1Class">Class of given Asn.1 object.</param>
 /// <param name="constructed">Constructed/Primitive bit of identifier octet.</param>
 /// <param name="asn1Tag">Tag number or type of Asn.1 object.</param>
 /// <param name="content">Content to be encoded.</param>
 protected Asn1Object(Asn1Class asn1Class, bool constructed, int asn1Tag, T content)
     : base(asn1Class, constructed, asn1Tag)
 {
     this.Content = content;
 }
Exemple #21
0
 /// <summary>
 /// Initializes a new instance of the <see cref="Asn1Sequence"/> class.
 /// Preferably used when reading SEQUENCE.
 /// The encoding of a sequence value shall be constructed.
 /// </summary>
 /// <param name="asn1Class">Class of given Asn.1 object.</param>
 /// <param name="content">BER encoded value in a Stream.</param>
 /// <param name="constructed">Flag if type is constructed or primitive.</param>
 public Asn1Sequence(Asn1Class asn1Class, SubStream content, bool constructed)
     : base(asn1Class, constructed, (int)Asn1Type.Sequence, content)
 {
 }
Exemple #22
0
 /// <summary>
 /// Initializes a new instance of the <see cref="Asn1ObjectBase"/> class.
 /// </summary>
 /// <param name="asn1Class">Class of given Asn.1 object.</param>
 /// <param name="constructed">Constructed/Primitive bit of identifier octet.</param>
 /// <param name="asn1Tag">Tag number or type of Asn.1 object.</param>
 protected Asn1ObjectBase(Asn1Class asn1Class, bool constructed, int asn1Tag)
 {
     this.Asn1Class   = asn1Class;
     this.Constructed = constructed;
     this.Asn1Tag     = asn1Tag;
 }
Exemple #23
0
        private static T MakeInstanceOfAsn1Object <T>(long nodeStartOffset, Asn1Class asn1Class, bool constructed, int tag, SubStream content)
            where T : Asn1ObjectBase
        {
            T foundObject;
            Asn1ObjectBase shouldBeType = null;

            if (asn1Class == Asn1Class.ContextSpecific)
            {
                shouldBeType = new Asn1ContextSpecific(constructed, tag, content);
            }
            else
            {
                switch ((Asn1Type)tag)
                {
                case Asn1Type.Eoc:
                    shouldBeType = new Asn1Eoc();
                    break;

                case Asn1Type.Boolean:
                    shouldBeType = new Asn1Boolean(content, constructed);
                    break;

                case Asn1Type.Integer:
                    shouldBeType = new Asn1Integer(content, constructed);
                    break;

                case Asn1Type.BitString:
                    shouldBeType = new Asn1BitString(content, constructed);
                    break;

                case Asn1Type.OctetString:
                    shouldBeType = new Asn1OctetString(content, constructed);
                    break;

                case Asn1Type.Null:
                    shouldBeType = new Asn1Null(constructed);
                    break;

                case Asn1Type.ObjectIdentifier:
                    shouldBeType = new Asn1ObjectIdentifier(content, constructed);
                    break;

                case Asn1Type.Real:
                    shouldBeType = new Asn1Real(content, constructed);
                    break;

                case Asn1Type.Enumerated:
                    shouldBeType = new Asn1Enumerated(content, constructed);
                    break;

                case Asn1Type.Utf8String:
                    shouldBeType = new Asn1Utf8String(content, constructed);
                    break;

                case Asn1Type.RelativeOid:
                    shouldBeType = new Asn1RelativeOid(content, constructed);
                    break;

                case Asn1Type.Sequence:
                    shouldBeType = new Asn1Sequence(asn1Class, content, constructed);
                    break;

                case Asn1Type.Set:
                    shouldBeType = new Asn1Set(asn1Class, content, constructed);
                    break;

                case Asn1Type.NumericString:
                    shouldBeType = new Asn1NumericString(content, constructed);
                    break;

                case Asn1Type.PrintableString:
                    shouldBeType = new Asn1PrintableString(content, constructed);
                    break;

                case Asn1Type.T61String:
                    shouldBeType = new Asn1T61String(content, constructed);
                    break;

                case Asn1Type.Ia5String:
                    shouldBeType = new Asn1Ia5String(content, constructed);
                    break;

                case Asn1Type.UtcTime:
                    shouldBeType = new Asn1UtcTime(content, constructed);
                    break;

                case Asn1Type.GeneralizedTime:
                    shouldBeType = new Asn1GeneralizedTime(content, constructed);
                    break;

                case Asn1Type.GraphicString:
                    shouldBeType = new Asn1GraphicString(content, constructed);
                    break;

                case Asn1Type.GeneralString:
                    shouldBeType = new Asn1GeneralString(content, constructed);
                    break;

                case Asn1Type.UniversalString:
                    shouldBeType = new Asn1UniversalString(content, constructed);
                    break;

                case Asn1Type.BmpString:
                    shouldBeType = new Asn1BmpString(content, constructed);
                    break;

                case Asn1Type.ObjectDescriptor:
                case Asn1Type.External:
                case Asn1Type.EmbeddedPdv:
                case Asn1Type.VideotexString:
                case Asn1Type.VisibleString:
                case Asn1Type.CharacterString:
                case Asn1Type.LongForm:
                default:
                    throw new NotSupportedException($"ASN.1 tag {tag} is unsupported.");
                }
            }

            foundObject = shouldBeType as T;

            // sanity check
            if (foundObject == null)
            {
                throw new FormatException(FormattableString.Invariant($"ASN.1 node at offset {nodeStartOffset} is of type {shouldBeType.GetType()} but expected type was {typeof(T)}"));
            }

            return(foundObject);
        }
Exemple #24
0
 /// <summary>
 /// Initializes a new instance of the <see cref="Asn1TagInfo"/> struct.
 /// </summary>
 /// <param name="asn1Class">The asn1 class.</param>
 /// <param name="constructType">Type of the construct.</param>
 /// <param name="tagType">Type of the tag.</param>
 internal Asn1TagInfo(int asn1Class, int constructType, int tagType)
 {
     this.Asn1ClassType = (Asn1Class)asn1Class;
     this.Asn1ConstructType = (ConstructType)constructType;
     if (this.Asn1ClassType == Asn1Class.Application)
     {
         this.Asn1SnmpTagType = (Asn1SnmpTag)tagType;
         this.Asn1TagType = Asn1Tag.NotAsn1Data;
     }
     else
     {
         this.Asn1TagType = (Asn1Tag)tagType;
         this.Asn1SnmpTagType = Asn1SnmpTag.NotSnmpData;
     }
 }