public override byte[] GetBytes() { int sequenceLength = GetTokenFieldsLength(); int sequenceLengthFieldSize = DerEncodingHelper.GetLengthFieldSize(sequenceLength); int constructionLength = 1 + sequenceLengthFieldSize + sequenceLength; int constructionLengthFieldSize = DerEncodingHelper.GetLengthFieldSize(constructionLength); int bufferSize = 1 + constructionLengthFieldSize + 1 + sequenceLengthFieldSize + sequenceLength; byte[] buffer = new byte[bufferSize]; int offset = 0; ByteWriter.WriteByte(buffer, ref offset, NegTokenRespTag); DerEncodingHelper.WriteLength(buffer, ref offset, constructionLength); ByteWriter.WriteByte(buffer, ref offset, (byte)DerEncodingTag.Sequence); DerEncodingHelper.WriteLength(buffer, ref offset, sequenceLength); if (NegState.HasValue) { WriteNegState(buffer, ref offset, NegState.Value); } if (SupportedMechanism != null) { WriteSupportedMechanism(buffer, ref offset, SupportedMechanism); } if (ResponseToken != null) { WriteResponseToken(buffer, ref offset, ResponseToken); } if (MechanismListMic != null) { WriteMechanismListMIC(buffer, ref offset, MechanismListMic); } return(buffer); }
protected static string?ReadHints(byte[] buffer, ref int offset, out byte[]?hintAddress) { string?hintName = null; hintAddress = null; _ = DerEncodingHelper.ReadLength(buffer, ref offset); byte tag = ByteReader.ReadByte(buffer, ref offset); if (tag != (byte)DerEncodingTag.Sequence) { throw new InvalidDataException(); } int sequenceLength = DerEncodingHelper.ReadLength(buffer, ref offset); int sequenceEndOffset = offset + sequenceLength; while (offset < sequenceEndOffset) { tag = ByteReader.ReadByte(buffer, ref offset); switch (tag) { case HintNameTag: hintName = ReadHintName(buffer, ref offset); break; case HintAddressTag: hintAddress = ReadHintAddress(buffer, ref offset); break; default: throw new InvalidDataException(); } } return(hintName); }
protected static List <byte[]> ReadMechanismTypeList(byte[] buffer, ref int offset) { List <byte[]> result = new List <byte[]>(); _ = DerEncodingHelper.ReadLength(buffer, ref offset); byte tag = ByteReader.ReadByte(buffer, ref offset); if (tag != (byte)DerEncodingTag.Sequence) { throw new InvalidDataException(); } int sequenceLength = DerEncodingHelper.ReadLength(buffer, ref offset); int sequenceEndOffset = offset + sequenceLength; while (offset < sequenceEndOffset) { tag = ByteReader.ReadByte(buffer, ref offset); if (tag != (byte)DerEncodingTag.ObjectIdentifier) { throw new InvalidDataException(); } int mechanismTypeLength = DerEncodingHelper.ReadLength(buffer, ref offset); byte[] mechanismType = ByteReader.ReadBytes(buffer, ref offset, mechanismTypeLength); result.Add(mechanismType); } return(result); }
protected virtual int GetTokenFieldsLength() { int result = 0; if (MechanismTypeList != null) { int typeListSequenceLength = GetMechanismTypeListSequenceLength(MechanismTypeList); int typeListSequenceLengthFieldSize = DerEncodingHelper.GetLengthFieldSize(typeListSequenceLength); int typeListConstructionLength = 1 + typeListSequenceLengthFieldSize + typeListSequenceLength; int typeListConstructionLengthFieldSize = DerEncodingHelper.GetLengthFieldSize(typeListConstructionLength); int entryLength = 1 + typeListConstructionLengthFieldSize + 1 + typeListSequenceLengthFieldSize + typeListSequenceLength; result += entryLength; } if (MechanismToken != null) { int mechanismTokenLengthFieldSize = DerEncodingHelper.GetLengthFieldSize(MechanismToken.Length); int mechanismTokenConstructionLength = 1 + mechanismTokenLengthFieldSize + MechanismToken.Length; int mechanismTokenConstructionLengthFieldSize = DerEncodingHelper.GetLengthFieldSize(mechanismTokenConstructionLength); int entryLength = 1 + mechanismTokenConstructionLengthFieldSize + 1 + mechanismTokenLengthFieldSize + MechanismToken.Length;; result += entryLength; } if (MechanismListMIC != null) { int mechanismListMICLengthFieldSize = DerEncodingHelper.GetLengthFieldSize(MechanismListMIC.Length); int mechanismListMICConstructionLength = 1 + mechanismListMICLengthFieldSize + MechanismListMIC.Length; int mechanismListMICConstructionLengthFieldSize = DerEncodingHelper.GetLengthFieldSize(mechanismListMICConstructionLength); int entryLength = 1 + mechanismListMICConstructionLengthFieldSize + 1 + mechanismListMICLengthFieldSize + MechanismListMIC.Length; result += entryLength; } return(result); }
private int GetTokenFieldsLength() { int result = 0; if (NegState.HasValue) { int negStateLength = 5; result += negStateLength; } if (SupportedMechanism != null) { int supportedMechanismBytesLengthFieldSize = DerEncodingHelper.GetLengthFieldSize(SupportedMechanism.Length); int supportedMechanismConstructionLength = 1 + supportedMechanismBytesLengthFieldSize + SupportedMechanism.Length; int supportedMechanismConstructionLengthFieldSize = DerEncodingHelper.GetLengthFieldSize(supportedMechanismConstructionLength); int supportedMechanismLength = 1 + supportedMechanismConstructionLengthFieldSize + 1 + supportedMechanismBytesLengthFieldSize + SupportedMechanism.Length; result += supportedMechanismLength; } if (ResponseToken != null) { int responseTokenBytesLengthFieldSize = DerEncodingHelper.GetLengthFieldSize(ResponseToken.Length); int responseTokenConstructionLength = 1 + responseTokenBytesLengthFieldSize + ResponseToken.Length; int responseTokenConstructionLengthFieldSize = DerEncodingHelper.GetLengthFieldSize(responseTokenConstructionLength); int responseTokenLength = 1 + responseTokenConstructionLengthFieldSize + 1 + responseTokenBytesLengthFieldSize + ResponseToken.Length; result += responseTokenLength; } if (MechanismListMic != null) { int mechanismListMICBytesLengthFieldSize = DerEncodingHelper.GetLengthFieldSize(MechanismListMic.Length); int mechanismListMICConstructionLength = 1 + mechanismListMICBytesLengthFieldSize + MechanismListMic.Length; int mechanismListMICConstructionLengthFieldSize = DerEncodingHelper.GetLengthFieldSize(mechanismListMICConstructionLength); int responseTokenLength = 1 + mechanismListMICConstructionLengthFieldSize + 1 + mechanismListMICBytesLengthFieldSize + MechanismListMic.Length; result += responseTokenLength; } return(result); }
public override byte[] GetBytes() { int sequenceLength = GetTokenFieldsLength(); int sequenceLengthFieldSize = DerEncodingHelper.GetLengthFieldSize(sequenceLength); int constructionLength = 1 + sequenceLengthFieldSize + sequenceLength; int constructionLengthFieldSize = DerEncodingHelper.GetLengthFieldSize(constructionLength); int bufferSize = 1 + constructionLengthFieldSize + 1 + sequenceLengthFieldSize + sequenceLength; byte[] buffer = new byte[bufferSize]; int offset = 0; ByteWriter.WriteByte(buffer, ref offset, NegTokenInitTag); DerEncodingHelper.WriteLength(buffer, ref offset, constructionLength); ByteWriter.WriteByte(buffer, ref offset, (byte)DerEncodingTag.Sequence); DerEncodingHelper.WriteLength(buffer, ref offset, sequenceLength); WriteMechanismTypeList(buffer, ref offset, MechanismTypeList); WriteMechanismToken(buffer, ref offset, MechanismToken); if (HintAddress != null) { WriteHints(buffer, ref offset, HintName, HintAddress); } WriteMechanismListMIC(buffer, ref offset, MechanismListMIC); return(buffer); }
private static void WriteNegState(byte[] buffer, ref int offset, NegState negState) { ByteWriter.WriteByte(buffer, ref offset, NegStateTag); DerEncodingHelper.WriteLength(buffer, ref offset, 3); ByteWriter.WriteByte(buffer, ref offset, (byte)DerEncodingTag.Enum); DerEncodingHelper.WriteLength(buffer, ref offset, 1); ByteWriter.WriteByte(buffer, ref offset, (byte)negState); }
protected static void WriteMechanismToken(byte[] buffer, ref int offset, byte[] mechanismToken) { int constructionLength = 1 + DerEncodingHelper.GetLengthFieldSize(mechanismToken.Length) + mechanismToken.Length; ByteWriter.WriteByte(buffer, ref offset, MechanismTokenTag); DerEncodingHelper.WriteLength(buffer, ref offset, constructionLength); ByteWriter.WriteByte(buffer, ref offset, (byte)DerEncodingTag.ByteArray); DerEncodingHelper.WriteLength(buffer, ref offset, mechanismToken.Length); ByteWriter.WriteBytes(buffer, ref offset, mechanismToken); }
private static void WriteResponseToken(byte[] buffer, ref int offset, byte[] responseToken) { int responseTokenLengthFieldSize = DerEncodingHelper.GetLengthFieldSize(responseToken.Length); ByteWriter.WriteByte(buffer, ref offset, ResponseTokenTag); DerEncodingHelper.WriteLength(buffer, ref offset, 1 + responseTokenLengthFieldSize + responseToken.Length); ByteWriter.WriteByte(buffer, ref offset, (byte)DerEncodingTag.ByteArray); DerEncodingHelper.WriteLength(buffer, ref offset, responseToken.Length); ByteWriter.WriteBytes(buffer, ref offset, responseToken); }
private static void WriteHintAddress(byte[] buffer, ref int offset, byte[] hintAddress) { int constructionLength = 1 + DerEncodingHelper.GetLengthFieldSize(hintAddress.Length) + hintAddress.Length; ByteWriter.WriteByte(buffer, ref offset, HintAddressTag); DerEncodingHelper.WriteLength(buffer, ref offset, constructionLength); ByteWriter.WriteByte(buffer, ref offset, (byte)DerEncodingTag.ByteArray); DerEncodingHelper.WriteLength(buffer, ref offset, hintAddress.Length); ByteWriter.WriteBytes(buffer, ref offset, hintAddress); }
private static void WriteSupportedMechanism(byte[] buffer, ref int offset, byte[] supportedMechanism) { int supportedMechanismLengthFieldSize = DerEncodingHelper.GetLengthFieldSize(supportedMechanism.Length); ByteWriter.WriteByte(buffer, ref offset, SupportedMechanismTag); DerEncodingHelper.WriteLength(buffer, ref offset, 1 + supportedMechanismLengthFieldSize + supportedMechanism.Length); ByteWriter.WriteByte(buffer, ref offset, (byte)DerEncodingTag.ObjectIdentifier); DerEncodingHelper.WriteLength(buffer, ref offset, supportedMechanism.Length); ByteWriter.WriteBytes(buffer, ref offset, supportedMechanism); }
new protected static void WriteMechanismListMIC(byte[] buffer, ref int offset, byte[] mechanismListMIC) { int mechanismListMICLengthFieldSize = DerEncodingHelper.GetLengthFieldSize(mechanismListMIC.Length); ByteWriter.WriteByte(buffer, ref offset, MechanismListMICTag); DerEncodingHelper.WriteLength(buffer, ref offset, 1 + mechanismListMICLengthFieldSize + mechanismListMIC.Length); ByteWriter.WriteByte(buffer, ref offset, (byte)DerEncodingTag.ByteArray); DerEncodingHelper.WriteLength(buffer, ref offset, mechanismListMIC.Length); ByteWriter.WriteBytes(buffer, ref offset, mechanismListMIC); }
private static void WriteHintName(byte[] buffer, ref int offset, string hintName) { byte[] hintNameBytes = DerEncodingHelper.EncodeGeneralString(hintName); int constructionLength = 1 + DerEncodingHelper.GetLengthFieldSize(hintNameBytes.Length) + hintNameBytes.Length; ByteWriter.WriteByte(buffer, ref offset, HintNameTag); DerEncodingHelper.WriteLength(buffer, ref offset, constructionLength); ByteWriter.WriteByte(buffer, ref offset, (byte)DerEncodingTag.GeneralString); DerEncodingHelper.WriteLength(buffer, ref offset, hintNameBytes.Length); ByteWriter.WriteBytes(buffer, ref offset, hintNameBytes); }
protected static int GetMechanismTypeListSequenceLength(List <byte[]> mechanismTypeList) { int sequenceLength = 0; foreach (byte[] mechanismType in mechanismTypeList) { int lengthFieldSize = DerEncodingHelper.GetLengthFieldSize(mechanismType.Length); int entryLength = 1 + lengthFieldSize + mechanismType.Length; sequenceLength += entryLength; } return(sequenceLength); }
private static NegState ReadNegState(byte[] buffer, ref int offset) { _ = DerEncodingHelper.ReadLength(buffer, ref offset); byte tag = ByteReader.ReadByte(buffer, ref offset); if (tag != (byte)DerEncodingTag.Enum) { throw new InvalidDataException(); } _ = DerEncodingHelper.ReadLength(buffer, ref offset); return((NegState)ByteReader.ReadByte(buffer, ref offset)); }
private static byte[] ReadSupportedMechanism(byte[] buffer, ref int offset) { _ = DerEncodingHelper.ReadLength(buffer, ref offset); byte tag = ByteReader.ReadByte(buffer, ref offset); if (tag != (byte)DerEncodingTag.ObjectIdentifier) { throw new InvalidDataException(); } int length = DerEncodingHelper.ReadLength(buffer, ref offset); return(ByteReader.ReadBytes(buffer, ref offset, length)); }
protected static byte[] ReadHintAddress(byte[] buffer, ref int offset) { _ = DerEncodingHelper.ReadLength(buffer, ref offset); byte tag = ByteReader.ReadByte(buffer, ref offset); if (tag != (byte)DerEncodingTag.ByteArray) { throw new InvalidDataException(); } int hintLength = DerEncodingHelper.ReadLength(buffer, ref offset); return(ByteReader.ReadBytes(buffer, ref offset, hintLength)); }
private static byte[] ReadMechanismListMIC(byte[] buffer, ref int offset) { _ = DerEncodingHelper.ReadLength(buffer, ref offset); byte tag = ByteReader.ReadByte(buffer, ref offset); if (tag != (byte)DerEncodingTag.ByteArray) { throw new InvalidDataException(); } int length = DerEncodingHelper.ReadLength(buffer, ref offset); return(ByteReader.ReadBytes(buffer, ref offset, length)); }
protected static string ReadHintName(byte[] buffer, ref int offset) { _ = DerEncodingHelper.ReadLength(buffer, ref offset); byte tag = ByteReader.ReadByte(buffer, ref offset); if (tag != (byte)DerEncodingTag.GeneralString) { throw new InvalidDataException(); } int hintLength = DerEncodingHelper.ReadLength(buffer, ref offset); byte[] hintNameBytes = ByteReader.ReadBytes(buffer, ref offset, hintLength); return(DerEncodingHelper.DecodeGeneralString(hintNameBytes)); }
protected static byte[] ReadMechanismToken(byte[] buffer, ref int offset) { _ = DerEncodingHelper.ReadLength(buffer, ref offset); byte tag = ByteReader.ReadByte(buffer, ref offset); if (tag != (byte)DerEncodingTag.ByteArray) { throw new InvalidDataException(); } int mechanismTokenLength = DerEncodingHelper.ReadLength(buffer, ref offset); byte[] token = ByteReader.ReadBytes(buffer, ref offset, mechanismTokenLength); return(token); }
/// <summary> /// https://tools.ietf.org/html/rfc2743 /// </summary> /// <exception cref="System.IO.InvalidDataException"></exception> public static SimpleProtectedNegotiationToken?ReadToken(byte[] tokenBytes, int offset, bool serverInitiatedNegotiation) { byte tag = ByteReader.ReadByte(tokenBytes, ref offset); if (tag == ApplicationTag) { // https://msdn.microsoft.com/en-us/library/ms995330.aspx // when an InitToken is sent, it is prepended by an Application Constructed Object specifier (0x60), // and the OID for SPNEGO. This is the generic GSSAPI header. // [RFC 2743] The use of the Mechanism-Independent Token Format is required for initial context // establishment tokens, use in non-initial tokens is optional. _ = DerEncodingHelper.ReadLength(tokenBytes, ref offset); tag = ByteReader.ReadByte(tokenBytes, ref offset); if (tag == (byte)DerEncodingTag.ObjectIdentifier) { int objectIdentifierLength = DerEncodingHelper.ReadLength(tokenBytes, ref offset); byte[] objectIdentifier = ByteReader.ReadBytes(tokenBytes, ref offset, objectIdentifierLength); if (ByteUtils.AreByteArraysEqual(objectIdentifier, SPNEGOIdentifier)) { tag = ByteReader.ReadByte(tokenBytes, ref offset); if (tag == SimpleProtectedNegotiationTokenInit.NegTokenInitTag) { if (serverInitiatedNegotiation) { // [MS-SPNG] Standard GSS has a strict notion of client (initiator) and server (acceptor). // If the client has not sent a negTokenInit ([RFC4178] section 4.2.1) message, no context establishment token is expected from the server. // The [NegTokenInit2] SPNEGO extension allows the server to generate a context establishment token message [..] and send it to the client. return(new SimpleProtectedNegotiationTokenInit2(tokenBytes, offset)); } return(new SimpleProtectedNegotiationTokenInit(tokenBytes, offset)); } if (tag == SimpleProtectedNegotiationTokenResponse.NegTokenRespTag) { return(new SimpleProtectedNegotiationTokenResponse(tokenBytes, offset)); } } } } else if (tag == SimpleProtectedNegotiationTokenResponse.NegTokenRespTag) { return(new SimpleProtectedNegotiationTokenResponse(tokenBytes, offset)); } return(null); }
protected static void WriteMechanismTypeList(byte[] buffer, ref int offset, List <byte[]> mechanismTypeList) { int sequenceLength = GetMechanismTypeListSequenceLength(mechanismTypeList); int sequenceLengthFieldSize = DerEncodingHelper.GetLengthFieldSize(sequenceLength); int constructionLength = 1 + sequenceLengthFieldSize + sequenceLength; ByteWriter.WriteByte(buffer, ref offset, MechanismTypeListTag); DerEncodingHelper.WriteLength(buffer, ref offset, constructionLength); ByteWriter.WriteByte(buffer, ref offset, (byte)DerEncodingTag.Sequence); DerEncodingHelper.WriteLength(buffer, ref offset, sequenceLength); foreach (byte[] mechanismType in mechanismTypeList) { ByteWriter.WriteByte(buffer, ref offset, (byte)DerEncodingTag.ObjectIdentifier); DerEncodingHelper.WriteLength(buffer, ref offset, mechanismType.Length); ByteWriter.WriteBytes(buffer, ref offset, mechanismType); } }
protected override int GetTokenFieldsLength() { int result = base.GetTokenFieldsLength();; if (HintAddress == null) { return(result); } int hintsSequenceLength = GetHintsSequenceLength(HintName, HintAddress); int hintsSequenceLengthFieldSize = DerEncodingHelper.GetLengthFieldSize(hintsSequenceLength); int hintsSequenceConstructionLength = 1 + hintsSequenceLengthFieldSize + hintsSequenceLength; int hintsSequenceConstructionLengthFieldSize = DerEncodingHelper.GetLengthFieldSize(hintsSequenceConstructionLength); int entryLength = 1 + hintsSequenceConstructionLengthFieldSize + 1 + hintsSequenceLengthFieldSize + hintsSequenceLength; result += entryLength; return(result); }
private static void WriteHints(byte[] buffer, ref int offset, string hintName, byte[] hintAddress) { int sequenceLength = GetHintsSequenceLength(hintName, hintAddress); int sequenceLengthFieldSize = DerEncodingHelper.GetLengthFieldSize(sequenceLength); int constructionLength = 1 + sequenceLengthFieldSize + sequenceLength; ByteWriter.WriteByte(buffer, ref offset, NegHintsTag); DerEncodingHelper.WriteLength(buffer, ref offset, constructionLength); ByteWriter.WriteByte(buffer, ref offset, (byte)DerEncodingTag.Sequence); DerEncodingHelper.WriteLength(buffer, ref offset, sequenceLength); if (hintName != null) { WriteHintName(buffer, ref offset, hintName); } if (hintAddress != null) { WriteHintAddress(buffer, ref offset, hintAddress); } }
/// <summary></summary> /// <param name="buffer">A buffer object to write to</param> /// <param name="offset">The offset following the NegTokenInit2 tag</param> /// <exception cref="InvalidDataException"></exception> public SimpleProtectedNegotiationTokenInit2(byte[] buffer, int offset) { _ = DerEncodingHelper.ReadLength(buffer, ref offset); byte tag = ByteReader.ReadByte(buffer, ref offset); if (tag != (byte)DerEncodingTag.Sequence) { throw new InvalidDataException(); } int sequenceLength = DerEncodingHelper.ReadLength(buffer, ref offset); int sequenceEndOffset = offset + sequenceLength; while (offset < sequenceEndOffset) { tag = ByteReader.ReadByte(buffer, ref offset); if (tag == MechanismTypeListTag) { MechanismTypeList = ReadMechanismTypeList(buffer, ref offset); } else if (tag == RequiredFlagsTag) { throw new NotImplementedException("negTokenInit.ReqFlags is not implemented"); } else if (tag == MechanismTokenTag) { MechanismToken = ReadMechanismToken(buffer, ref offset); } else if (tag == NegHintsTag) { HintName = ReadHints(buffer, ref offset, out HintAddress); } else if (tag == MechanismListMICTag) { MechanismListMIC = ReadMechanismListMIC(buffer, ref offset); } else { throw new InvalidDataException("Invalid negTokenInit structure"); } } }
/// <param name="includeHeader">Prepend the generic GSSAPI header. Required for negTokenInit, optional for negTokenResp.</param> public byte[] GetBytes(bool includeHeader) { byte[] tokenBytes = GetBytes(); if (includeHeader) { int objectIdentifierFieldSize = DerEncodingHelper.GetLengthFieldSize(SPNEGOIdentifier.Length); int tokenLength = 1 + objectIdentifierFieldSize + SPNEGOIdentifier.Length + tokenBytes.Length; int tokenLengthFieldSize = DerEncodingHelper.GetLengthFieldSize(tokenLength); int headerLength = 1 + tokenLengthFieldSize + 1 + objectIdentifierFieldSize + SPNEGOIdentifier.Length; byte[] buffer = new byte[headerLength + tokenBytes.Length]; int offset = 0; ByteWriter.WriteByte(buffer, ref offset, ApplicationTag); DerEncodingHelper.WriteLength(buffer, ref offset, tokenLength); ByteWriter.WriteByte(buffer, ref offset, (byte)DerEncodingTag.ObjectIdentifier); DerEncodingHelper.WriteLength(buffer, ref offset, SPNEGOIdentifier.Length); ByteWriter.WriteBytes(buffer, ref offset, SPNEGOIdentifier); ByteWriter.WriteBytes(buffer, ref offset, tokenBytes); return(buffer); } return(tokenBytes); }
protected static int GetHintsSequenceLength(string hintName, byte[] hintAddress) { int sequenceLength = 0; if (hintName != null) { byte[] hintNameBytes = DerEncodingHelper.EncodeGeneralString(hintName); int lengthFieldSize = DerEncodingHelper.GetLengthFieldSize(hintNameBytes.Length); int constructionLength = 1 + lengthFieldSize + hintNameBytes.Length; int constructionLengthFieldSize = DerEncodingHelper.GetLengthFieldSize(constructionLength); int entryLength = 1 + constructionLengthFieldSize + 1 + lengthFieldSize + hintNameBytes.Length; sequenceLength += entryLength; } if (hintAddress != null) { int lengthFieldSize = DerEncodingHelper.GetLengthFieldSize(hintAddress.Length); int constructionLength = 1 + lengthFieldSize + hintAddress.Length; int constructionLengthFieldSize = DerEncodingHelper.GetLengthFieldSize(constructionLength); int entryLength = 1 + constructionLengthFieldSize + 1 + lengthFieldSize + hintAddress.Length; sequenceLength += entryLength; } return(sequenceLength); }
/// <param name="buffer"></param> /// <param name="offset">The offset following the NegTokenResp tag</param> /// <exception cref="InvalidDataException"></exception> public SimpleProtectedNegotiationTokenResponse(byte[] buffer, int offset) { _ = DerEncodingHelper.ReadLength(buffer, ref offset); byte tag = ByteReader.ReadByte(buffer, ref offset); if (tag != (byte)DerEncodingTag.Sequence) { throw new InvalidDataException(); } int sequenceLength = DerEncodingHelper.ReadLength(buffer, ref offset); int sequenceEndOffset = offset + sequenceLength; while (offset < sequenceEndOffset) { tag = ByteReader.ReadByte(buffer, ref offset); if (tag == NegStateTag) { NegState = ReadNegState(buffer, ref offset); } else if (tag == SupportedMechanismTag) { SupportedMechanism = ReadSupportedMechanism(buffer, ref offset); } else if (tag == ResponseTokenTag) { ResponseToken = ReadResponseToken(buffer, ref offset); } else if (tag == MechanismListMICTag) { MechanismListMic = ReadMechanismListMIC(buffer, ref offset); } else { throw new InvalidDataException("Invalid negTokenResp structure"); } } }