/// <summary> /// Decode AS Request from bytes /// </summary> /// <param name="buffer">the byte array to be decoded</param> /// <exception cref="System.ArgumentNullException">thrown when input buffer is null</exception> public override void FromBytes(byte[] buffer) { if (buffer == null) { throw new ArgumentNullException("buffer"); } Asn1DecodingBuffer decodeBuffer = new Asn1DecodingBuffer(buffer); Request.BerDecode(decodeBuffer); }
/// <summary> /// Decode the Krb Error from bytes /// </summary> /// <param name="buffer">The byte array to be decoded.</param> /// <exception cref="System.ArgumentNullException">thrown when input buffer is null</exception> public override void FromBytes(byte[] buffer) { if (null == buffer) { throw new ArgumentNullException("buffer"); } KerberosUtility.OnDumpMessage("KRB5:KrbMessage", "Kerberos Message", KerberosUtility.DumpLevel.WholeMessage, buffer); // Decode Krb Error Asn1DecodingBuffer decodeBuffer = new Asn1DecodingBuffer(buffer); this.KrbError.BerDecode(decodeBuffer); ErrorCode = (KRB_ERROR_CODE)KrbError.error_code.Value; }
/// <summary> /// Decode TGS Response from bytes /// </summary> /// <param name="buffer">byte array to be decoded</param> /// <exception cref="System.ArgumentNullException">thrown when input buffer is null</exception> public override void FromBytes(byte[] buffer) { if (null == buffer) { throw new ArgumentNullException("buffer"); } KerberosUtility.OnDumpMessage("KRB5:KrbMessage", "Kerberos Message", KerberosUtility.DumpLevel.WholeMessage, buffer); // Decode TGS Response Asn1DecodingBuffer decodeBuffer = new Asn1DecodingBuffer(buffer); Response.BerDecode(decodeBuffer); }
/// <summary> /// Decodes an LDAP v3 packet. /// </summary> /// <param name="messageBytes">The message bytes that contains the packet data.</param> /// <param name="context">The context that contains decode-related information.</param> /// <returns>Decoded LDAP v3 packet.</returns> internal override AdtsLdapPacket ParseAdtsLdapPacket(byte[] messageBytes, AdtsLdapContext context) { LDAPMessage message = new LDAPMessage(); Asn1DecodingBuffer decodeBuffer = new Asn1DecodingBuffer(messageBytes); message.BerDecode(decodeBuffer); Type innerMessageType = message.protocolOp.GetData().GetType(); AdtsLdapPacket packet = CreatePacketFromType(innerMessageType); context.MessageId = (long)message.messageID.Value; packet.messageId = (long)message.messageID.Value; packet.ldapMessagev3 = message; return packet; }
/// <summary> /// Decrypt the KRB-PRIV /// </summary> /// <param name="subkey">the subkey used to decrypt</param> public void DecryptKrbPriv(EncryptionKey subkey) { byte[] priv = KerberosUtility.Decrypt( (EncryptionType)subkey.keytype.Value, subkey.keyvalue.ByteArrayValue, krb_priv.enc_part.cipher.ByteArrayValue, (int)KeyUsageNumber.KRB_PRIV_EncPart); Asn1DecodingBuffer decodeBuffer = new Asn1DecodingBuffer(priv); priv_enc_part.BerDecode(decodeBuffer); }
/// <summary> /// Decode Kpassword Response from bytes /// </summary> /// <param name="buffer">the byte array to be decoded</param> /// <exception cref="System.ArgumentNullException">thrown when input buffer is null</exception> public override void FromBytes(byte[] buffer) { if (null == buffer) { throw new ArgumentNullException("buffer"); } //Calculate the length of the message and the length of AP response data byte[] msgLengthBytes = ArrayUtility.SubArray<byte>(buffer, 0, sizeof(ushort)); Array.Reverse(msgLengthBytes); ushort msgLength = BitConverter.ToUInt16(msgLengthBytes, 0); byte[] apLengthBytes = ArrayUtility.SubArray<byte>(buffer, 2 * sizeof(ushort), sizeof(ushort)); Array.Reverse(apLengthBytes); ushort apLength = BitConverter.ToUInt16(apLengthBytes, 0); //Decode the ap response and the krb-priv message byte[] apBytes = ArrayUtility.SubArray<byte>(buffer, 3 * sizeof(ushort), apLength); Asn1DecodingBuffer apBuffer = new Asn1DecodingBuffer(apBytes); this.ap_rep.Response.BerDecode(apBuffer); byte[] privBytes = ArrayUtility.SubArray<byte>(buffer, 3 * sizeof(ushort) + apLength); Asn1DecodingBuffer privBuffer = new Asn1DecodingBuffer(privBytes); this.krb_priv.BerDecode(privBuffer); }
/// <summary> /// [TD Reference 3.2.5.3.4] /// Decode MCS Connect Response PDU with GCC Conference Create Response /// </summary> /// <param name="data">data to be parsed</param> /// <returns>decoded MCS Connect Response PDU with GCC Conference Create Response PDU</returns> public StackPacket DecodeMcsConnectResponsePDU(byte[] data) { // initialize int currentIndex = 0; Server_MCS_Connect_Response_Pdu_with_GCC_Conference_Create_Response pdu = new Server_MCS_Connect_Response_Pdu_with_GCC_Conference_Create_Response(); // McsConnectResponse: TpktHeader pdu.tpktHeader = ParseTpktHeader(data, ref currentIndex); // McsConnectResponse: X224 pdu.x224Data = ParseX224Data(data, ref currentIndex); // T125 Data: decode McsConnectResponse int t125DataLength = data.Length - currentIndex; if (t125DataLength <= 0) { throw new FormatException(ConstValue.ERROR_MESSAGE_DATA_INDEX_OUT_OF_RANGE); } byte[] t125Data = new byte[t125DataLength]; Array.Copy(data, currentIndex, t125Data, 0, t125Data.Length); Connect_Response mcsConnectResponse = new Connect_Response(); Asn1DecodingBuffer decodeBuffer = new Asn1DecodingBuffer(t125Data); mcsConnectResponse.BerDecode(decodeBuffer); // McsConnectResponse:result pdu.mcsCrsp.result = (int)mcsConnectResponse.result.Value; byte[] userData = mcsConnectResponse.userData.ByteArrayValue; // T125 Data: decode McsConnectResponse's user data Asn1DecodingBuffer connectDataBuffer = new Asn1DecodingBuffer(userData); ConnectData connectData = new ConnectData(); connectData.PerDecode(connectDataBuffer); // T125 Data: get Gcc data int gccDataLength = userData.Length - ConstValue.GCC_DATA_OFFSET; if (gccDataLength <= 0) { throw new FormatException(ConstValue.ERROR_MESSAGE_DATA_INDEX_OUT_OF_RANGE); } byte[] gccData = new byte[gccDataLength]; Array.Copy(userData, ConstValue.GCC_DATA_OFFSET, gccData, 0, gccData.Length); // T125 Data: decode Gcc user data ConnectGCCPDU gccPdu = new ConnectGCCPDU(); Asn1DecodingBuffer gccPduBuffer = new Asn1DecodingBuffer(gccData); gccPdu.PerDecode(gccPduBuffer); // McsConnectResponse: H221Key ConferenceCreateResponse conferenceResponse = (ConferenceCreateResponse)gccPdu.GetData(); H221NonStandardIdentifier identifier = (H221NonStandardIdentifier)conferenceResponse.userData.Elements[0].key.GetData(); pdu.mcsCrsp.gccPdu.H221Key = Encoding.ASCII.GetString(identifier.ByteArrayValue); // McsConnectResponse: ccrResult pdu.mcsCrsp.gccPdu.ccrResult = (int)conferenceResponse.result.Value; // McsConnectResponse: nodeID pdu.mcsCrsp.gccPdu.nodeID = (int)conferenceResponse.nodeID.Value; // McsConnectResponse: tag pdu.mcsCrsp.gccPdu.tag = (int)conferenceResponse.tag.Value; // T125 Data: get Gcc user data byte[] gccUserData = conferenceResponse.userData.Elements[0].value.ByteArrayValue; // Reset current index currentIndex = 0; while (currentIndex < gccUserData.Length) { // Peek data type int tempIndex = currentIndex; TS_UD_HEADER_type_Values type = (TS_UD_HEADER_type_Values)ParseUInt16(gccUserData, ref tempIndex, false); // Parse data by type switch (type) { case TS_UD_HEADER_type_Values.SC_CORE: pdu.mcsCrsp.gccPdu.serverCoreData = ParseTsUdScCore(gccUserData, ref currentIndex); break; case TS_UD_HEADER_type_Values.SC_NET: pdu.mcsCrsp.gccPdu.serverNetworkData = ParseTsUdScNet(gccUserData, ref currentIndex); break; case TS_UD_HEADER_type_Values.SC_SECURITY: pdu.mcsCrsp.gccPdu.serverSecurityData = ParseTsUdScSec1(gccUserData, ref currentIndex); break; case TS_UD_HEADER_type_Values.SC_MCS_MSGCHANNEL: pdu.mcsCrsp.gccPdu.serverMessageChannelData = ParseTsUdScMSGChannel(gccUserData, ref currentIndex); break; case TS_UD_HEADER_type_Values.SC_MULTITRANSPORT: pdu.mcsCrsp.gccPdu.serverMultitransportChannelData = ParseTsUdScMultiTransport(gccUserData, ref currentIndex); break; default: throw new FormatException(ConstValue.ERROR_MESSAGE_ENUM_UNRECOGNIZED); } } // Check if data length exceeded expectation VerifyDataLength(gccUserData.Length, currentIndex, ConstValue.ERROR_MESSAGE_DATA_LENGTH_EXCEEDED); return pdu; }
/// <summary> /// Parse MCS Domain PDU /// (parser index is updated according to parsed length) /// </summary> /// <param name="data">data to be parsed</param> /// <param name="currentIndex">current parser index</param> /// <returns>MCS Domain PDU</returns> private DomainMCSPDU ParseMcsDomainPdu(byte[] data, ref int currentIndex) { // initialize decode buffer byte[] temp = GetBytes(data, ref currentIndex, (data.Length - currentIndex)); Asn1DecodingBuffer buffer = new Asn1DecodingBuffer(temp); // decode DomainMCSPDU domainPdu = new DomainMCSPDU(); domainPdu.PerDecode(buffer); return domainPdu; }
/// <summary> /// Decode MCS Connect Initial PDU with GCC Conference Create Initial /// </summary> /// <param name="data">data to be parsed</param> /// <returns>Decoded MCS Connect Initial PDU with GCC Conference Create Initial</returns> public StackPacket DecodeMcsConnectInitialPDU(byte[] data) { // initialize int currentIndex = 0; Client_MCS_Connect_Initial_Pdu_with_GCC_Conference_Create_Request pdu = new Client_MCS_Connect_Initial_Pdu_with_GCC_Conference_Create_Request(); // McsConnectResponse: TpktHeader pdu.tpktHeader = ParseTpktHeader(data, ref currentIndex); // McsConnectResponse: X224 pdu.x224Data = ParseX224Data(data, ref currentIndex); // T125 Data: decode McsConnectResponse int t125DataLength = data.Length - currentIndex; if (t125DataLength <= 0) { throw new FormatException(ConstValue.ERROR_MESSAGE_DATA_INDEX_OUT_OF_RANGE); } byte[] t125Data = new byte[t125DataLength]; Array.Copy(data, currentIndex, t125Data, 0, t125Data.Length); Connect_Initial mcsConnectInitial = new Connect_Initial(); Asn1DecodingBuffer decodeBuffer = new Asn1DecodingBuffer(t125Data); mcsConnectInitial.BerDecode(decodeBuffer); // McsConnectResponse:result pdu.mcsCi.targetParameters.maxChannelIds = (long)mcsConnectInitial.targetParameters.maxChannelIds.Value; pdu.mcsCi.targetParameters.maxHeight = (long)mcsConnectInitial.targetParameters.maxHeight.Value; pdu.mcsCi.targetParameters.maxMcsPduSize = (long)mcsConnectInitial.targetParameters.maxMCSPDUsize.Value; pdu.mcsCi.targetParameters.maxTokenIds = (long)mcsConnectInitial.targetParameters.maxTokenIds.Value; pdu.mcsCi.targetParameters.maxUserIds = (long)mcsConnectInitial.targetParameters.maxUserIds.Value; pdu.mcsCi.targetParameters.minThroughput = (long)mcsConnectInitial.targetParameters.minThroughput.Value; pdu.mcsCi.targetParameters.numPriorities = (long)mcsConnectInitial.targetParameters.numPriorities.Value; pdu.mcsCi.targetParameters.protocolVersion = (long)mcsConnectInitial.targetParameters.protocolVersion.Value; pdu.mcsCi.minimumParameters.maxChannelIds = (long)mcsConnectInitial.minimumParameters.maxChannelIds.Value; pdu.mcsCi.minimumParameters.maxHeight = (long)mcsConnectInitial.minimumParameters.maxHeight.Value; pdu.mcsCi.minimumParameters.maxMcsPduSize = (long)mcsConnectInitial.minimumParameters.maxMCSPDUsize.Value; pdu.mcsCi.minimumParameters.maxTokenIds = (long)mcsConnectInitial.minimumParameters.maxTokenIds.Value; pdu.mcsCi.minimumParameters.maxUserIds = (long)mcsConnectInitial.minimumParameters.maxUserIds.Value; pdu.mcsCi.minimumParameters.minThroughput = (long)mcsConnectInitial.minimumParameters.minThroughput.Value; pdu.mcsCi.minimumParameters.numPriorities = (long)mcsConnectInitial.minimumParameters.numPriorities.Value; pdu.mcsCi.minimumParameters.protocolVersion = (long)mcsConnectInitial.minimumParameters.protocolVersion.Value; pdu.mcsCi.maximumParameters.maxChannelIds = (long)mcsConnectInitial.maximumParameters.maxChannelIds.Value; pdu.mcsCi.maximumParameters.maxHeight = (long)mcsConnectInitial.maximumParameters.maxHeight.Value; pdu.mcsCi.maximumParameters.maxMcsPduSize = (long)mcsConnectInitial.maximumParameters.maxMCSPDUsize.Value; pdu.mcsCi.maximumParameters.maxTokenIds = (long)mcsConnectInitial.maximumParameters.maxTokenIds.Value; pdu.mcsCi.maximumParameters.maxUserIds = (long)mcsConnectInitial.maximumParameters.maxUserIds.Value; pdu.mcsCi.maximumParameters.minThroughput = (long)mcsConnectInitial.maximumParameters.minThroughput.Value; pdu.mcsCi.maximumParameters.numPriorities = (long)mcsConnectInitial.maximumParameters.numPriorities.Value; pdu.mcsCi.maximumParameters.protocolVersion = (long)mcsConnectInitial.maximumParameters.protocolVersion.Value; // T125 User Data: get McsConnectResponse's user data //byte[] userData = new byte[mcsConnectInitial.userData.Length]; //Stream mscInput = mcsConnectInitial.userData.toInputStream(); //mscInput.Read(userData, 0, userData.Length); byte[] userData = mcsConnectInitial.userData.ByteArrayValue; // T125 User Data: decode McsConnectResponse's user data Asn1DecodingBuffer connectDataBuffer = new Asn1DecodingBuffer(userData); ConnectData connectData = new ConnectData(); connectData.PerDecode(connectDataBuffer); // Gcc Data: get Gcc data int gccDataLength = userData.Length - ConstValue.GCC_CCI_DATA_OFFSET; if (gccDataLength <= 0) { throw new FormatException(ConstValue.ERROR_MESSAGE_DATA_INDEX_OUT_OF_RANGE); } byte[] gccData = new byte[gccDataLength]; Array.Copy(userData, ConstValue.GCC_CCI_DATA_OFFSET, gccData, 0, gccData.Length); // Gcc Data: decode Gcc data ConnectGCCPDU gccPdu = new ConnectGCCPDU(); Asn1DecodingBuffer gccPduBuffer = new Asn1DecodingBuffer(gccData); gccPdu.PerDecode(gccPduBuffer); // McsConnectResponse: H221Key ConferenceCreateRequest conferenceRequest = (ConferenceCreateRequest)gccPdu.GetData(); H221NonStandardIdentifier identifier = (H221NonStandardIdentifier)conferenceRequest.userData.Elements[0].key.GetData(); pdu.mcsCi.gccPdu.h221Key = Encoding.ASCII.GetString(identifier.ByteArrayValue); // Gcc User Data: get Gcc user data byte[] gccUserData = conferenceRequest.userData.Elements[0].value.ByteArrayValue; // Reset current index currentIndex = 0; while (currentIndex < gccUserData.Length) { // Peek data type int tempIndex = currentIndex; int orgIndex = currentIndex; TS_UD_HEADER_type_Values type = (TS_UD_HEADER_type_Values)ParseUInt16(gccUserData, ref tempIndex, false); ushort userDataLength = ParseUInt16(gccUserData, ref tempIndex, false); // Parse data by type switch (type) { case TS_UD_HEADER_type_Values.CS_CORE: pdu.mcsCi.gccPdu.clientCoreData = ParseTsUdCsCore(gccUserData, ref currentIndex, userDataLength); break; case TS_UD_HEADER_type_Values.CS_NET: pdu.mcsCi.gccPdu.clientNetworkData = ParseTsUdCsNet(gccUserData, ref currentIndex); break; case TS_UD_HEADER_type_Values.CS_SECURITY: pdu.mcsCi.gccPdu.clientSecurityData = ParseTsUdCsSec(gccUserData, ref currentIndex); break; case TS_UD_HEADER_type_Values.CS_CLUSTER: pdu.mcsCi.gccPdu.clientClusterData = ParseTsUdCsCluster(gccUserData, ref currentIndex); break; case TS_UD_HEADER_type_Values.CS_MONITOR: pdu.mcsCi.gccPdu.clientMonitorData = ParseTsUdCsMon(gccUserData, ref currentIndex); break; case TS_UD_HEADER_type_Values.CS_MCS_MSGCHANNEL: pdu.mcsCi.gccPdu.clientMessageChannelData = ParseTsUdCsMcsMsgChannel(gccUserData, ref currentIndex); break; case TS_UD_HEADER_type_Values.CS_MULTITRANSPORT: pdu.mcsCi.gccPdu.clientMultitransportChannelData = ParseTsUdCsMultiTransport(gccUserData, ref currentIndex); break; case TS_UD_HEADER_type_Values.CS_MONITOR_EX: pdu.mcsCi.gccPdu.clientMonitorExtendedData = ParseTsUdCsMonitorEX(gccUserData, ref currentIndex); break; default: break; //throw new FormatException(ConstValue.ERROR_MESSAGE_ENUM_UNRECOGNIZED); } currentIndex = orgIndex + userDataLength; } // Check if data length exceeded expectation VerifyDataLength(gccUserData.Length, currentIndex, ConstValue.ERROR_MESSAGE_DATA_LENGTH_EXCEEDED); return pdu; }
/// <summary> /// Expected a PreauthenticationRequired error /// </summary> /// <param name="eData">Error data of this error</param> /// <returns></returns> public KerberosKrbError ExpectPreauthRequiredError(out METHOD_DATA eData) { KerberosPdu responsePdu = this.ExpectPdu(KerberosConstValue.TIMEOUT_DEFAULT, typeof(KerberosKrbError)); this.testSite.Assert.IsNotNull(responsePdu, "Response Pdu should not be null."); this.testSite.Assert.IsInstanceOfType(responsePdu, typeof(KerberosKrbError), "Response type mismatch"); KerberosKrbError krbError = responsePdu as KerberosKrbError; this.testSite.Assert.AreEqual(KRB_ERROR_CODE.KDC_ERR_PREAUTH_REQUIRED, krbError.ErrorCode, "The Error code should be KDC_ERR_PREAUTH_REQUIRED"); this.testSite.Log.Add(LogEntryKind.Debug, "Receive preauthentication required error."); eData = new METHOD_DATA(); Asn1DecodingBuffer buffer = new Asn1DecodingBuffer(krbError.KrbError.e_data.ByteArrayValue); eData.BerDecode(buffer); return krbError; }
/// <summary> /// Decode KDCProxyMessage from bytes /// </summary> /// <param name="buffer">byte array to be decoded</param> /// <exception cref="System.ArgumentNullException">thrown when input buffer is null</exception> public void FromBytes(byte[] buffer) { if (null == buffer) { throw new ArgumentNullException("buffer"); } this.Message = new KDC_PROXY_MESSAGE(); Asn1DecodingBuffer decodeBuffer = new Asn1DecodingBuffer(buffer); this.Message.BerDecode(decodeBuffer); }
private void UpdateContext(KerberosAsResponse response) { KerberosFastResponse kerbFastRep = null; if (response.Response.padata != null && response.Response.padata.Elements != null) { foreach (PA_DATA paData in response.Response.padata.Elements) { var parsedPaData = PaDataParser.ParseRepPaData(paData); if (parsedPaData is PaETypeInfo2) { Asn1DecodingBuffer buffer = new Asn1DecodingBuffer(paData.padata_value.ByteArrayValue); ETYPE_INFO2 eTypeInfo2 = new ETYPE_INFO2(); eTypeInfo2.BerDecode(buffer); if (eTypeInfo2.Elements != null && eTypeInfo2.Elements.Length > 0) { // the salt is received from KDC if (eTypeInfo2.Elements[0].salt != null) Context.CName.Salt = eTypeInfo2.Elements[0].salt.Value; continue; } } if (parsedPaData is PaFxFastRep) { var armoredRep = ((PaFxFastRep)parsedPaData).GetArmoredRep(); kerbFastRep = ((PaFxFastRep)parsedPaData).GetKerberosFastRep(Context.FastArmorkey); var strKey = kerbFastRep.FastResponse.strengthen_key; Context.ReplyKey = KerberosUtility.KrbFxCf2( strKey, //Fix me: should be Context.ReplyKey KerberosUtility.MakeKey(Context.SelectedEType, Context.CName.Password, Context.CName.Salt), "strengthenkey", "replykey"); } } } if (Context.ReplyKey != null) { response.Decrypt(Context.ReplyKey.keyvalue.ByteArrayValue); } else { var encryptType = (EncryptionType)response.Response.enc_part.etype.Value; var key = KeyGenerator.MakeKey(encryptType, Context.CName.Password, Context.CName.Salt); Context.ReplyKey = new EncryptionKey(new KerbInt32((long)encryptType), new Asn1OctetString(key)); response.Decrypt(key); } if (response.EncPart != null) { Context.SessionKey = response.EncPart.key; } if (response.Response != null) { //Response.Response.cname is not the real CName of the ticket when hide-client-names=1 if (kerbFastRep != null && kerbFastRep.FastResponse != null && kerbFastRep.FastResponse.finished != null) { // Windows DC is case insensitive. It may change the cname in the response, e.g. administrator -> Administrator Context.CName.Name = kerbFastRep.FastResponse.finished.cname; Context.Ticket = new KerberosTicket(response.Response.ticket, kerbFastRep.FastResponse.finished.cname, response.EncPart.key); } else { // Windows DC is case insensitive. It may change the cname in the response, e.g. administrator -> Administrator Context.CName.Name = response.Response.cname; Context.Ticket = new KerberosTicket(response.Response.ticket, response.Response.cname, response.EncPart.key); } Context.SelectedEType = (EncryptionType)Context.Ticket.SessionKey.keytype.Value; if (Context.Ticket != null && Context.Ticket.Ticket.sname != null && Context.Ticket.Ticket.sname.name_string != null && Context.Ticket.Ticket.sname.name_string.Elements != null && Context.Ticket.Ticket.sname.name_string.Elements.Length > 1) { int count = Context.Ticket.Ticket.sname.name_string.Elements.Length; Context.Realm = new Realm(Context.Ticket.Ticket.sname.name_string.Elements[count - 1].Value); } } }
/// <summary> /// Decode AS Response from bytes /// </summary> /// <param name="buffer">the byte array to be decoded</param> /// <exception cref="System.ArgumentNullException">thrown when input buffer is null</exception> public override void FromBytes(byte[] buffer) { if (null == buffer) { throw new ArgumentNullException("buffer"); } KerberosUtility.OnDumpMessage("KRB5:KrbMessage", "Kerberos Message", KerberosUtility.DumpLevel.WholeMessage, buffer); // Decode AS Response Asn1DecodingBuffer decodeBuffer = new Asn1DecodingBuffer(buffer); this.Response.BerDecode(decodeBuffer); // Get the current encryption type, cipher data, session key EncryptionType encryptType = (EncryptionType)this.Response.enc_part.etype.Value; }
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); }