public override int BerEncode(IAsn1BerEncodingBuffer buffer, bool explicitTag = true)
        {
            int length = ValueBerEncode(buffer);

            length += LengthBerEncode(buffer, length);
            buffer.WriteByte(101);
            buffer.WriteByte(127);
            return(length + 2);
        }
Example #2
0
        /// <summary>
        /// Encodes the data of this object to the buffer.
        /// </summary>
        /// <param name="buffer">A buffer to which the encoding result will be written.</param>
        /// <returns>The length of the encoding result of the data.</returns>
        /// <remarks>
        /// For the TLV (Tag, Length, Value) triple in the encoding result,
        /// this method provides the functionality of encoding Value.
        /// The encoding for Tag and Length will be done in Asn1Object::BerEncode method.
        /// </remarks>
        protected override int ValueBerEncode(IAsn1BerEncodingBuffer buffer)
        {
            //Encode data
            if (Value == false)
            {
                buffer.WriteByte(0);
            }
            else
            {
                buffer.WriteByte(255);
            }

            return(1);
        }
 /// <summary>
 /// Encodes the data of this object to the buffer.
 /// </summary>
 /// <param name="buffer">A buffer to which the encoding result will be written.</param>
 /// <returns>The length of the encoding result of the data.</returns>
 /// <remarks>
 /// For the TLV (Tag, Length, Value) triple in the encoding result,
 /// this method provides the functionality of encoding Value.
 /// The encoding for Tag and Length will be done in Asn1Object::BerEncode method.
 /// </remarks>
 protected override int ValueBerEncode(IAsn1BerEncodingBuffer buffer)
 {
     //Ref. X.680: 8.6.2.2
     buffer.WriteBytes(ByteArrayValue);
     buffer.WriteByte(unusedBitsInLastByte);
     return(ByteArrayValue.Length + 1);
 }
        /// <summary>
        /// Encodes a length to the buffer.
        /// </summary>
        /// <param name="buffer"></param>
        /// <param name="length">The length to be written to the buffer.</param>
        /// <returns>The length of "the encoded length's encoding result".</returns>
        public static int LengthBerEncode(IAsn1BerEncodingBuffer buffer, int length)
        {
            if (length < 0)
            {
                throw new Asn1InvalidArgument(ExceptionMessages.LengthNegative);
            }
            if (length < 128)
            {
                buffer.WriteByte((byte)length);
                return(1);
            }
            else
            {
                //The encoding result of a length that no less than 128 will be stored in at least two bytes.
                //The first byte:  1xxxxxxx, xxxxxxx is the length of the following encoding result.
                //The next bytes:  the length's encoding result, big endian.
                //Ref. X.690: 8.1.3
                byte[] bytes = BitConverter.GetBytes(length);
                //ensure bytes is big endian
                if (BitConverter.IsLittleEndian)
                {
                    Array.Reverse(bytes);
                }

                //delete the redundant zeros
                int zeroNum = 0;
                for (int i = 0; i < bytes.Length; i++)
                {
                    if (bytes[i] == 0)
                    {
                        zeroNum++;
                    }
                    else
                    {
                        break;
                    }
                }
                //zeroNum won't be equal to bytes.Length since length>=128.

                //Encode data first, then encode length of the data's encoding result since buffer is reversed.
                buffer.WriteBytes(bytes, zeroNum, bytes.Length - zeroNum);
                buffer.WriteByte((byte)((bytes.Length - zeroNum) | (1 << 7)));//set the first bit to 1
                return(1 + bytes.Length - zeroNum);
            }
        }
        /// <summary>
        /// Encodes a tag to the buffer.
        /// </summary>
        /// <param name="buffer"></param>
        /// <param name="tag"></param>
        /// <returns>The length of the encoding result.</returns>
        public static int TagBerEncode(IAsn1BerEncodingBuffer buffer, Asn1Tag tag)
        {
            //Ref. X.690: 8.1.2.2, there are four kinds of tags
            byte prefix = 0;

            switch (tag.TagType)
            {
            case Asn1TagType.Universal:
            {
                prefix = 0;        //00
            } break;

            case Asn1TagType.Application:
            {
                prefix = 1;        //01
            } break;

            case Asn1TagType.Context:
            {
                prefix = 2;        //10
            } break;

            case Asn1TagType.Private:
            {
                prefix = 3;        //11
                //Ref. X.680: G.2.12.4
                throw new Asn1UnreachableExcpetion(ExceptionMessages.Unreachable);
            };
            }
            prefix <<= 6;
            if (tag.EncodingWay == EncodingWay.Constructed)
            {
                prefix |= (1 << 5); //Set the sixth bit to 1 if it is encoded in constructed way. Ref. X.690: 8.1.2.3
            }
            if (tag.TagValue <= 30) //Use one byte to store the encoding result
            //Ref. X.690: 8.1.2.3
            {
                prefix |= (byte)tag.TagValue;
                buffer.WriteByte(prefix);
                return(1);
            }
            else//Use more than one bytes to store.
            {
                //Ref. X.690: 8.1.2.4.3
                throw new NotImplementedException("Case tag > 30 is not implemented. Check X.690: 8.1.2.4.3.");
            }
        }
        /// <summary>
        /// Encodes a length to the buffer.
        /// </summary>
        /// <param name="buffer"></param>
        /// <param name="length">The length to be written to the buffer.</param>
        /// <returns>The length of "the encoded length's encoding result".</returns>
        public static int LengthBerEncode(IAsn1BerEncodingBuffer buffer, int length)
        {
            if (length < 0)
            {
                throw new Asn1InvalidArgument(ExceptionMessages.LengthNegative);
            }
            if (length < 128)
            {
                buffer.WriteByte((byte)length);
                return 1;
            }
            else
            {
                //The encoding result of a length that no less than 128 will be stored in at least two bytes.
                //The first byte:  1xxxxxxx, xxxxxxx is the length of the following encoding result.
                //The next bytes:  the length's encoding result, big endian.
                //Ref. X.690: 8.1.3
                byte[] bytes = BitConverter.GetBytes(length);
                //ensure bytes is big endian
                if (BitConverter.IsLittleEndian)
                {
                    Array.Reverse(bytes);
                }

                //delete the redundant zeros
                int zeroNum = 0;
                for (int i = 0; i < bytes.Length; i++)
                {
                    if (bytes[i] == 0)
                    {
                        zeroNum++;
                    }
                    else
                    {
                        break;
                    }
                }
                //zeroNum won't be equal to bytes.Length since length>=128.

                //Encode data first, then encode length of the data's encoding result since buffer is reversed.
                buffer.WriteBytes(bytes, zeroNum, bytes.Length - zeroNum);
                buffer.WriteByte((byte)((bytes.Length - zeroNum) | (1 << 7)));//set the first bit to 1
                return 1 + bytes.Length - zeroNum;
            }
        }
        /// <summary>
        /// Encodes the data of this object to the buffer.
        /// </summary>
        /// <param name="buffer">A buffer to which the encoding result will be written.</param>
        /// <returns>The length of the encoding result of the data.</returns>
        /// <remarks>
        /// For the TLV (Tag, Length, Value) triple in the encoding result,
        /// this method provides the functionality of encoding Value.
        /// The encoding for Tag and Length will be done in Asn1Object::BerEncode method.
        /// </remarks>
        protected override int ValueBerEncode(IAsn1BerEncodingBuffer buffer)
        {
            //Encode data
            if (Value == false)
            {
                buffer.WriteByte(0);
            }
            else
            {
                buffer.WriteByte(255);
            }

            return 1;
        }
 /// <summary>
 /// Encodes a tag to the buffer.
 /// </summary>
 /// <param name="buffer"></param>
 /// <param name="tag"></param>
 /// <returns>The length of the encoding result.</returns>
 public static int TagBerEncode(IAsn1BerEncodingBuffer buffer, Asn1Tag tag)
 {
     //Ref. X.690: 8.1.2.2, there are four kinds of tags
     byte prefix = 0;
     switch (tag.TagType)
     {
         case Asn1TagType.Universal:
             {
                 prefix = 0;//00
             } break;
         case Asn1TagType.Application:
             {
                 prefix = 1;//01
             } break;
         case Asn1TagType.Context:
             {
                 prefix = 2;//10
             } break;
         case Asn1TagType.Private:
             {
                 prefix = 3;//11
                 //Ref. X.680: G.2.12.4
                 throw new Asn1UnreachableExcpetion(ExceptionMessages.Unreachable);
             };
     }
     prefix <<= 6;
     if (tag.EncodingWay == EncodingWay.Constructed)
     {
         prefix |= (1 << 5);//Set the sixth bit to 1 if it is encoded in constructed way. Ref. X.690: 8.1.2.3
     }
     if (tag.TagValue <= 30)//Use one byte to store the encoding result
     //Ref. X.690: 8.1.2.3
     {
         prefix |= (byte)tag.TagValue;
         buffer.WriteByte(prefix);
         return 1;
     }
     else//Use more than one bytes to store.
     {
         //Ref. X.690: 8.1.2.4.3
         throw new NotImplementedException("Case tag > 30 is not implemented. Check X.690: 8.1.2.4.3.");
     }
 }
 public override int BerEncode(IAsn1BerEncodingBuffer buffer, bool explicitTag = true)
 {
     int length = ValueBerEncode(buffer);
     length += LengthBerEncode(buffer, length);
     buffer.WriteByte(101);
     buffer.WriteByte(127);
     return length + 2;
 }
 /// <summary>
 /// Encodes the data of this object to the buffer.
 /// </summary>
 /// <param name="buffer">A buffer to which the encoding result will be written.</param>
 /// <returns>The length of the encoding result of the data.</returns>
 /// <remarks>
 /// For the TLV (Tag, Length, Value) triple in the encoding result,
 /// this method provides the functionality of encoding Value.
 /// The encoding for Tag and Length will be done in Asn1Object::BerEncode method.
 /// </remarks>
 protected override int ValueBerEncode(IAsn1BerEncodingBuffer buffer)
 {
     //Ref. X.680: 8.6.2.2
     buffer.WriteBytes(ByteArrayValue);
     buffer.WriteByte(unusedBitsInLastByte);
     return ByteArrayValue.Length + 1;
 }