/// <summary>
 /// Decodes the object by PER.
 /// </summary>
 /// <param name="buffer">A buffer that contains a PER encoding result.</param>
 /// <param name="aligned">Indicating whether the PER decoding is aligned.</param>
 /// <remarks>Length is included.</remarks>
 protected override void ValuePerDecode(IAsn1DecodingBuffer buffer, bool aligned = true)
 {
     ByteArrayValue = Asn1StandardProcedure.PerDecodeArray <byte>(buffer,
                                                                  decodingBuffer =>
     {
         Asn1Integer ai = new Asn1Integer(null, 0, 15);
         ai.PerDecode(buffer);
         if (Constraint == null || Constraint.PermittedCharSet == null)
         {
             if (ai.Value == 0)
             {
                 return((byte)' ');
             }
             else if (ai.Value >= 1 && ai.Value <= 10)
             {
                 return((byte)((byte)'0' + ai.Value - 1));
             }
             else
             {
                 throw new Asn1DecodingUnexpectedData(ExceptionMessages.DecodingUnexpectedData +
                                                      "Only 0~9 and SPACE are allowed in NumericString.");
             }
         }
         else
         {
             int index = (int)ai.Value;
             return((byte)CharSetInArray[(int)ai.Value]);
         }
     },
                                                                  Constraint != null && Constraint.HasMinSize ? Constraint.MinSize : (long?)null, Constraint != null && Constraint.HasMaxSize ? Constraint.MaxSize : (long?)null,
                                                                  true);
 }
        //BER encoding/decoding are implemented in base class Asn1ByteString.

        #region PER

        /// <summary>
        /// Encodes the content of the object by PER.
        /// </summary>
        /// <param name="buffer">A buffer to which the encoding result will be written.</param>
        /// <remarks>Length is included.</remarks>
        protected override void ValuePerEncode(IAsn1PerEncodingBuffer buffer)
        {
            Asn1StandardProcedure.PerEncodeArray(buffer, Value.ToCharArray(),
                                                 (encodingBuffer, b) =>
            {
                int val;
                if (Constraint == null || Constraint.PermittedCharSet == null)
                {
                    if (b == ' ')     //SPACE->0000, '0'->0001, ..., '9'->1010
                    {
                        val = 0;
                    }
                    else
                    {
                        val = 1 + b - '0';
                    }
                }
                else
                {
                    for (val = 0; val != CharSetInArray.Length && b != CharSetInArray[val]; val++)
                    {
                    }
                }
                Asn1Integer ai = new Asn1Integer(val, 0, 15);
                ai.PerEncode(buffer);
            }
                                                 , Constraint != null && Constraint.HasMinSize ? Constraint.MinSize : (long?)null, Constraint != null && Constraint.HasMaxSize ? Constraint.MaxSize : (long?)null,
                                                 true);
        }
 /// <summary>
 /// Decodes the object by PER.
 /// </summary>
 /// <param name="buffer">A buffer that contains a PER encoding result.</param>
 /// <param name="aligned">Indicating whether the PER decoding is aligned.</param>
 /// <remarks>Length is included.</remarks>
 protected override void ValuePerDecode(IAsn1DecodingBuffer buffer, bool aligned = true)
 {
     if (Constraint != null && Constraint.HasMinSize && Constraint.HasMinSize &&
         Constraint.MinSize == Constraint.MaxSize && Constraint.MinSize <= 2)    //Ref. X.691:16.6
     {
         long   minSize    = Constraint.MinSize;
         bool[] bitResult  = buffer.ReadBits((int)(8 * minSize));
         byte[] byteResult = new byte[(int)minSize];
         //Convert bool array to byte array
         int byteIndex = 0, bitIndex = 0;
         foreach (bool b in bitResult)
         {
             if (b)
             {
                 byteResult[byteIndex] |= (byte)(1 << (7 - bitIndex));
             }
             bitIndex++;
             if (bitIndex == 8)
             {
                 bitIndex = 0;
                 byteIndex++;
             }
         }
         ByteArrayValue = byteResult;
     }
     else
     {
         ByteArrayValue = Asn1StandardProcedure.PerDecodeArray(buffer,
                                                               decodingBuffer => decodingBuffer.ReadByte(),
                                                               Constraint != null && Constraint.HasMinSize ? Constraint.MinSize : (long?)null, Constraint != null && Constraint.HasMaxSize ? Constraint.MaxSize : (long?)null);
     }
 }
        //BER encoding/decoding are implemented in base class Asn1ByteString.

        /// <summary>
        /// Encodes the content of the object by PER.
        /// </summary>
        /// <param name="buffer">A buffer to which the encoding result will be written.</param>
        /// <remarks>Length is included.</remarks>
        protected override void ValuePerEncode(IAsn1PerEncodingBuffer buffer)
        {
            if (Constraint != null && Constraint.HasMinSize && Constraint.HasMinSize &&
                Constraint.MinSize == Constraint.MaxSize && Constraint.MinSize <= 2)    //Ref. X.691:16.6
            {
                buffer.WriteBits(ByteArrayValue, 0, ByteArrayValue.Length * 8);
            }
            else
            {
                Asn1StandardProcedure.PerEncodeArray(buffer, ByteArrayValue,
                                                     (encodingBuffer, b) => { encodingBuffer.WriteByte(b); }
                                                     , Constraint != null && Constraint.HasMinSize ? Constraint.MinSize : (long?)null, Constraint != null && Constraint.HasMaxSize ? Constraint.MaxSize : (long?)null);
            }
        }
Esempio n. 5
0
        private void DecryptAsResponse(byte[] key)
        {
            var encryptType = (EncryptionType)Response.enc_part.etype.Value;
            int keyUsage    = (int)KeyUsageNumber.AS_REP_ENCRYPTEDPART;

            if (encryptType == EncryptionType.RC4_HMAC)
            {
                keyUsage = (int)KeyUsageNumber.TGS_REP_encrypted_part;
            }

            var encPartRawData = KerberosUtility.Decrypt(
                encryptType,
                key,
                Response.enc_part.cipher.ByteArrayValue,
                keyUsage);
            Asn1DecodingBuffer buf = new Asn1DecodingBuffer(encPartRawData);
            Asn1Tag            tag = null;

            Asn1StandardProcedure.TagBerDecode(buf, out tag);
            //Some implementations unconditionally send an encrypted EncTGSRepPart in the field
            //regardless of whether the reply is an AS-REP or a TGS-REP.([RFC4120] Section 5.4.2)
            if (tag.TagValue == 25)  //EncAsRepPart
            {
                EncPart = new EncASRepPart();
            }
            else if (tag.TagValue == 26) //EncTgsRepPart
            {
                EncPart = new EncTGSRepPart();
            }
            else
            {
                throw new Exception("Unknown tag number");
            }
            EncPart.BerDecode(new Asn1DecodingBuffer(encPartRawData));
            KerberosUtility.OnDumpMessage("KRB5:AS-REP(enc-part)",
                                          "Encrypted part of AS-REP",
                                          KerberosUtility.DumpLevel.PartialMessage,
                                          encPartRawData);
        }