/// <summary> /// Create a new instance of FieldMetaData with a given MemberInfo. /// </summary> /// <param name="outRef">Indicates the reference of the out object that hold this constraint.</param> /// <param name="info"></param> /// <remarks> /// AttachedTag, Constraint will be set automatically by reflection. /// </remarks> protected Asn1ConstraintedFieldMetadata(Asn1Object outRef, MemberInfo info) { OutReference = outRef; MemberInfo = info; //Get AttachedTag AttachedTag = null; var attrs = MemberInfo.GetCustomAttributes(typeof(Asn1Tag), true); if (attrs.Length != 0) { //Only the first tag is valid. Asn1Tag tag = attrs[0] as Asn1Tag; if (tag.TagType != Asn1TagType.Context && tag.TagType != Asn1TagType.Application) { throw new Asn1UserDefinedTypeInconsistent(ExceptionMessages.UserDefinedTypeInconsistent + " Only Context-Specific tag and Application tag are allowed."); } AttachedTag = tag; } //Get Constraint Constraint = GetConstraints(); }
/// <summary> /// Encodes a tag to the buffer. /// </summary> /// <param name="buffer"></param> /// <param name="tag"></param> /// <returns>The length of the encoding result.</returns> /// <remarks>Override this method in a user-defined class only if the procedure is not applicable in some special scenarios.</remarks> protected virtual int TagBerEncode(IAsn1BerEncodingBuffer buffer, Asn1Tag tag) { return Asn1StandardProcedure.TagBerEncode(buffer, tag); }
/// <summary> /// Decodes a tag from the buffer. /// </summary> /// <param name="buffer"></param> /// <param name="tag"></param> /// <returns>The number of the bytes consumed in the buffer to decode the tag.</returns> /// <remarks>Override this method in a user-defined class only if the procedure is not applicable in some special scenarios.</remarks> protected virtual int TagBerDecode(IAsn1DecodingBuffer buffer, out Asn1Tag tag) { return Asn1StandardProcedure.TagBerDecode(buffer, out tag); }
/// <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> /// Decodes a tag from the buffer. /// </summary> /// <param name="buffer"></param> /// <param name="tag"></param> /// <returns>The number of the bytes consumed in the buffer to decode the tag.</returns> public static int TagBerDecode(IAsn1DecodingBuffer buffer, out Asn1Tag tag) { byte prefix = buffer.ReadByte(); int firstTwoBits = (prefix >> 6); Asn1TagType tagType = Asn1TagType.Private; long tagValue; switch (firstTwoBits) { case 0: { tagType = Asn1TagType.Universal; } break; case 1: { tagType = Asn1TagType.Application; } break; case 2: { tagType = Asn1TagType.Context; } break; case 3: { throw new NotImplementedException(ExceptionMessages.Unreachable); }; } tagValue = prefix & ((byte)(1 << 5) - 1); if (tagValue <= 30) { tag = new Asn1Tag(tagType, tagValue); if ((prefix & (1 << 5)) != 0) { tag.EncodingWay = EncodingWay.Constructed; } else { tag.EncodingWay = EncodingWay.Primitive; } return 1; } else { 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 allLen = 0; Asn1Tag contextTag; switch (SelectedChoice) { case 0: allLen += field0.BerEncodeWithoutUnisersalTag(buffer); contextTag = new Asn1Tag(Asn1TagType.Context, 0) { EncodingWay = EncodingWay.Primitive }; allLen += TagBerEncode(buffer, contextTag); break; case 1: allLen += field1.BerEncodeWithoutUnisersalTag(buffer); contextTag = new Asn1Tag(Asn1TagType.Context, 3) { EncodingWay = EncodingWay.Constructed }; allLen += TagBerEncode(buffer, contextTag); break; case 2: allLen += field2.BerEncodeWithoutUnisersalTag(buffer); contextTag = new Asn1Tag(Asn1TagType.Context, 9) { EncodingWay = EncodingWay.Primitive }; allLen += TagBerEncode(buffer, contextTag); break; case 3: allLen += field3.BerEncodeWithoutUnisersalTag(buffer); contextTag = new Asn1Tag(Asn1TagType.Context, 10) { EncodingWay = EncodingWay.Primitive }; allLen += TagBerEncode(buffer, contextTag); break; case 4: allLen += field4.BerEncodeWithoutUnisersalTag(buffer); contextTag = new Asn1Tag(Asn1TagType.Context, 11) { EncodingWay = EncodingWay.Primitive }; allLen += TagBerEncode(buffer, contextTag); break; default: throw new Asn1ConstraintsNotSatisfied(ExceptionMessages.InvalidChoiceIndex + " AuthenticationChoice"); } return allLen; }