/// <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); }
/// <summary> /// Calculates length of ASN.1 object /// </summary> /// <param name="value">Content of ASN.1 object.</param> /// <param name="asn1Type">Type of ASN.1 object. In some types there has to be an octet before content bytes.</param> /// <returns>Encoded length of ASN.1 object.</returns> internal static byte[] WriteLength(IEnumerable <byte> value, Asn1Type asn1Type) { var length = value.Count(); if (asn1Type == Asn1Type.BitString) { length++; // count in the unused bits } byte[] lengthOctets = DerWriterUtils.EncodeLength(length); return(lengthOctets); }