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) { //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; }