Corrected SPNEGO implementation

This commit is contained in:
Tal Aloni 2017-02-04 21:21:46 +02:00
parent 2f78339fc8
commit cd03f7c946
3 changed files with 146 additions and 191 deletions

View file

@ -24,25 +24,19 @@ namespace SMBLibrary.Authentication
{ {
if (token is SimpleProtectedNegotiationTokenInit) if (token is SimpleProtectedNegotiationTokenInit)
{ {
List<TokenInitEntry> tokens = ((SimpleProtectedNegotiationTokenInit)token).Tokens; SimpleProtectedNegotiationTokenInit tokenInit = (SimpleProtectedNegotiationTokenInit)token;
foreach (TokenInitEntry entry in tokens) foreach (byte[] identifier in tokenInit.MechanismTypeList)
{ {
foreach (byte[] identifier in entry.MechanismTypeList) if (ByteUtils.AreByteArraysEqual(identifier, NTLMSSPIdentifier))
{ {
if (ByteUtils.AreByteArraysEqual(identifier, NTLMSSPIdentifier)) return tokenInit.MechanismToken;
{
return entry.MechanismToken;
}
} }
} }
} }
else else
{ {
List<TokenResponseEntry> tokens = ((SimpleProtectedNegotiationTokenResponse)token).Tokens; SimpleProtectedNegotiationTokenResponse tokenResponse = (SimpleProtectedNegotiationTokenResponse)token;
if (tokens.Count > 0) return tokenResponse.ResponseToken;
{
return tokens[0].ResponseToken;
}
} }
} }
return null; return null;
@ -51,30 +45,24 @@ namespace SMBLibrary.Authentication
public static byte[] GetGSSTokenInitNTLMSSPBytes() public static byte[] GetGSSTokenInitNTLMSSPBytes()
{ {
SimpleProtectedNegotiationTokenInit token = new SimpleProtectedNegotiationTokenInit(); SimpleProtectedNegotiationTokenInit token = new SimpleProtectedNegotiationTokenInit();
TokenInitEntry entry = new TokenInitEntry(); token.MechanismTypeList = new List<byte[]>();
entry.MechanismTypeList = new List<byte[]>(); token.MechanismTypeList.Add(NTLMSSPIdentifier);
entry.MechanismTypeList.Add(NTLMSSPIdentifier);
token.Tokens.Add(entry);
return SimpleProtectedNegotiationToken.GetTokenBytes(token); return SimpleProtectedNegotiationToken.GetTokenBytes(token);
} }
public static byte[] GetGSSTokenResponseBytesFromNTLMSSPMessage(byte[] messageBytes) public static byte[] GetGSSTokenResponseBytesFromNTLMSSPMessage(byte[] messageBytes)
{ {
SimpleProtectedNegotiationTokenResponse token = new SimpleProtectedNegotiationTokenResponse(); SimpleProtectedNegotiationTokenResponse token = new SimpleProtectedNegotiationTokenResponse();
TokenResponseEntry entry = new TokenResponseEntry(); token.NegState = NegState.AcceptIncomplete;
entry.NegState = NegState.AcceptIncomplete; token.SupportedMechanism = NTLMSSPIdentifier;
entry.SupportedMechanism = NTLMSSPIdentifier; token.ResponseToken = messageBytes;
entry.ResponseToken = messageBytes;
token.Tokens.Add(entry);
return token.GetBytes(); return token.GetBytes();
} }
public static byte[] GetGSSTokenAcceptCompletedResponse() public static byte[] GetGSSTokenAcceptCompletedResponse()
{ {
SimpleProtectedNegotiationTokenResponse token = new SimpleProtectedNegotiationTokenResponse(); SimpleProtectedNegotiationTokenResponse token = new SimpleProtectedNegotiationTokenResponse();
TokenResponseEntry entry = new TokenResponseEntry(); token.NegState = NegState.AcceptCompleted;
entry.NegState = NegState.AcceptCompleted;
token.Tokens.Add(entry);
return token.GetBytes(); return token.GetBytes();
} }
} }

View file

@ -11,14 +11,6 @@ using Utilities;
namespace SMBLibrary.Authentication namespace SMBLibrary.Authentication
{ {
public class TokenInitEntry
{
public List<byte[]> MechanismTypeList; // Optional
// reqFlags - Optional, RECOMMENDED to be left out
public byte[] MechanismToken; // Optional
public byte[] MechanismListMIC; // Optional
}
/// <summary> /// <summary>
/// RFC 4178 - negTokenInit /// RFC 4178 - negTokenInit
/// </summary> /// </summary>
@ -30,7 +22,10 @@ namespace SMBLibrary.Authentication
public const byte MechanismTokenTag = 0xA2; public const byte MechanismTokenTag = 0xA2;
public const byte MechanismListMICTag = 0xA3; public const byte MechanismListMICTag = 0xA3;
public List<TokenInitEntry> Tokens = new List<TokenInitEntry>(); public List<byte[]> MechanismTypeList; // Optional
// reqFlags - Optional, RECOMMENDED to be left out
public byte[] MechanismToken; // Optional
public byte[] MechanismListMIC; // Optional
public SimpleProtectedNegotiationTokenInit() public SimpleProtectedNegotiationTokenInit()
{ {
@ -40,95 +35,85 @@ namespace SMBLibrary.Authentication
public SimpleProtectedNegotiationTokenInit(byte[] buffer, int offset) public SimpleProtectedNegotiationTokenInit(byte[] buffer, int offset)
{ {
int constructionLength = DerEncodingHelper.ReadLength(buffer, ref offset); int constructionLength = DerEncodingHelper.ReadLength(buffer, ref offset);
int sequenceEndOffset = offset + constructionLength;
byte tag = ByteReader.ReadByte(buffer, ref offset); byte tag = ByteReader.ReadByte(buffer, ref offset);
if (tag != (byte)DerEncodingTag.Sequence) if (tag != (byte)DerEncodingTag.Sequence)
{ {
throw new InvalidDataException(); throw new InvalidDataException();
} }
int sequenceLength = DerEncodingHelper.ReadLength(buffer, ref offset);
int sequenceEndOffset = offset + sequenceLength;
while (offset < sequenceEndOffset) while (offset < sequenceEndOffset)
{ {
int entryLength = DerEncodingHelper.ReadLength(buffer, ref offset); tag = ByteReader.ReadByte(buffer, ref offset);
int entryEndOffset = offset + entryLength; if (tag == MechanismTypeListTag)
TokenInitEntry entry = new TokenInitEntry();
while (offset < entryEndOffset)
{ {
tag = ByteReader.ReadByte(buffer, ref offset); MechanismTypeList = ReadMechanismTypeList(buffer, ref offset);
if (tag == MechanismTypeListTag) }
{ else if (tag == RequiredFlagsTag)
entry.MechanismTypeList = ReadMechanismTypeList(buffer, ref offset); {
} throw new NotImplementedException("negTokenInit.ReqFlags is not implemented");
else if (tag == RequiredFlagsTag) }
{ else if (tag == MechanismTokenTag)
throw new NotImplementedException("negTokenInit.ReqFlags is not implemented"); {
} MechanismToken = ReadMechanismToken(buffer, ref offset);
else if (tag == MechanismTokenTag) }
{ else if (tag == MechanismListMICTag)
entry.MechanismToken = ReadMechanismToken(buffer, ref offset); {
} MechanismListMIC = ReadMechanismListMIC(buffer, ref offset);
else if (tag == MechanismListMICTag) }
{ else
entry.MechanismListMIC = ReadMechanismListMIC(buffer, ref offset); {
} throw new InvalidDataException("Invalid negTokenInit structure");
else
{
throw new InvalidDataException("Invalid negTokenInit structure");
}
} }
Tokens.Add(entry);
} }
} }
public override byte[] GetBytes() public override byte[] GetBytes()
{ {
int sequenceLength = 0; int sequenceLength = GetTokenFieldsLength();
foreach (TokenInitEntry token in Tokens) int sequenceLengthFieldSize = DerEncodingHelper.GetLengthFieldSize(sequenceLength);
{ int constructionLength = 1 + sequenceLengthFieldSize + sequenceLength;
int entryLength = GetEntryLength(token); int constructionLengthFieldSize = DerEncodingHelper.GetLengthFieldSize(constructionLength);
sequenceLength += DerEncodingHelper.GetLengthFieldSize(entryLength) + entryLength; int bufferSize = 1 + constructionLengthFieldSize + 1 + sequenceLengthFieldSize + sequenceLength;
}
int constructionLengthFieldSize = DerEncodingHelper.GetLengthFieldSize(1 + sequenceLength);
int bufferSize = 1 + constructionLengthFieldSize + 1 + sequenceLength;
byte[] buffer = new byte[bufferSize]; byte[] buffer = new byte[bufferSize];
int offset = 0; int offset = 0;
ByteWriter.WriteByte(buffer, ref offset, NegTokenInitTag); ByteWriter.WriteByte(buffer, ref offset, NegTokenInitTag);
DerEncodingHelper.WriteLength(buffer, ref offset, 1 + sequenceLength); DerEncodingHelper.WriteLength(buffer, ref offset, constructionLength);
ByteWriter.WriteByte(buffer, ref offset, (byte)DerEncodingTag.Sequence); ByteWriter.WriteByte(buffer, ref offset, (byte)DerEncodingTag.Sequence);
foreach (TokenInitEntry token in Tokens) DerEncodingHelper.WriteLength(buffer, ref offset, sequenceLength);
if (MechanismTypeList != null)
{ {
int entryLength = GetEntryLength(token); WriteMechanismTypeList(buffer, ref offset, MechanismTypeList);
DerEncodingHelper.WriteLength(buffer, ref offset, entryLength); }
if (token.MechanismTypeList != null) if (MechanismToken != null)
{ {
WriteMechanismTypeList(buffer, ref offset, token.MechanismTypeList); WriteMechanismToken(buffer, ref offset, MechanismToken);
} }
if (token.MechanismToken != null) if (MechanismListMIC != null)
{ {
WriteMechanismToken(buffer, ref offset, token.MechanismToken); WriteMechanismListMIC(buffer, ref offset, MechanismListMIC);
}
if (token.MechanismListMIC != null)
{
WriteMechanismListMIC(buffer, ref offset, token.MechanismListMIC);
}
} }
return buffer; return buffer;
} }
public int GetEntryLength(TokenInitEntry token) private int GetTokenFieldsLength()
{ {
int result = 0; int result = 0;
if (token.MechanismTypeList != null) if (MechanismTypeList != null)
{ {
int typeListSequenceLength = GetSequenceLength(token.MechanismTypeList); int typeListSequenceLength = GetSequenceLength(MechanismTypeList);
int constructionLenthFieldSize = DerEncodingHelper.GetLengthFieldSize(1 + typeListSequenceLength); int typeListSequenceLengthFieldSize = DerEncodingHelper.GetLengthFieldSize(typeListSequenceLength);
int typeListLength = 1 + constructionLenthFieldSize + 1 + typeListSequenceLength; int typeListConstructionLength = 1 + typeListSequenceLengthFieldSize + typeListSequenceLength;
int typeListConstructionLengthFieldSize = DerEncodingHelper.GetLengthFieldSize(typeListConstructionLength);
int typeListLength = 1 + typeListConstructionLengthFieldSize + 1 + typeListSequenceLengthFieldSize + typeListSequenceLength;
result += typeListLength; result += typeListLength;
} }
if (token.MechanismToken != null) if (MechanismToken != null)
{ {
int byteArrayFieldSize = DerEncodingHelper.GetLengthFieldSize(token.MechanismToken.Length); int mechanismTokenBytesFieldSize = DerEncodingHelper.GetLengthFieldSize(MechanismToken.Length);
int constructionLengthFieldSize = DerEncodingHelper.GetLengthFieldSize(1 + byteArrayFieldSize + token.MechanismToken.Length); int mechanismTokenConstructionLength = 1 + mechanismTokenBytesFieldSize + MechanismToken.Length;
int tokenLength = 1 + constructionLengthFieldSize + 1 + byteArrayFieldSize + token.MechanismToken.Length; int mechanismTokenConstructionLengthFieldSize = DerEncodingHelper.GetLengthFieldSize(mechanismTokenConstructionLength);
int tokenLength = 1 + mechanismTokenConstructionLengthFieldSize + 1 + mechanismTokenBytesFieldSize + MechanismToken.Length;
result += tokenLength; result += tokenLength;
} }
return result; return result;
@ -138,16 +123,15 @@ namespace SMBLibrary.Authentication
{ {
List<byte[]> result = new List<byte[]>(); List<byte[]> result = new List<byte[]>();
int constructionLength = DerEncodingHelper.ReadLength(buffer, ref offset); int constructionLength = DerEncodingHelper.ReadLength(buffer, ref offset);
int sequenceEndOffset = offset + constructionLength;
byte tag = ByteReader.ReadByte(buffer, ref offset); byte tag = ByteReader.ReadByte(buffer, ref offset);
if (tag != (byte)DerEncodingTag.Sequence) if (tag != (byte)DerEncodingTag.Sequence)
{ {
throw new InvalidDataException(); throw new InvalidDataException();
} }
int sequenceLength = DerEncodingHelper.ReadLength(buffer, ref offset);
int sequenceEndOffset = offset + sequenceLength;
while (offset < sequenceEndOffset) while (offset < sequenceEndOffset)
{ {
int entryLength = DerEncodingHelper.ReadLength(buffer, ref offset);
int entryEndOffset = offset + entryLength;
tag = ByteReader.ReadByte(buffer, ref offset); tag = ByteReader.ReadByte(buffer, ref offset);
if (tag != (byte)DerEncodingTag.ObjectIdentifier) if (tag != (byte)DerEncodingTag.ObjectIdentifier)
{ {
@ -192,7 +176,7 @@ namespace SMBLibrary.Authentication
{ {
int lengthFieldSize = DerEncodingHelper.GetLengthFieldSize(mechanismType.Length); int lengthFieldSize = DerEncodingHelper.GetLengthFieldSize(mechanismType.Length);
int entryLength = 1 + lengthFieldSize + mechanismType.Length; int entryLength = 1 + lengthFieldSize + mechanismType.Length;
sequenceLength += DerEncodingHelper.GetLengthFieldSize(entryLength) + entryLength; sequenceLength += entryLength;
} }
return sequenceLength; return sequenceLength;
} }
@ -200,15 +184,14 @@ namespace SMBLibrary.Authentication
private static void WriteMechanismTypeList(byte[] buffer, ref int offset, List<byte[]> mechanismTypeList) private static void WriteMechanismTypeList(byte[] buffer, ref int offset, List<byte[]> mechanismTypeList)
{ {
int sequenceLength = GetSequenceLength(mechanismTypeList); int sequenceLength = GetSequenceLength(mechanismTypeList);
int sequenceLengthFieldSize = DerEncodingHelper.GetLengthFieldSize(sequenceLength);
int constructionLength = 1 + sequenceLengthFieldSize + sequenceLength;
ByteWriter.WriteByte(buffer, ref offset, MechanismTypeListTag); ByteWriter.WriteByte(buffer, ref offset, MechanismTypeListTag);
DerEncodingHelper.WriteLength(buffer, ref offset, 1 + sequenceLength); DerEncodingHelper.WriteLength(buffer, ref offset, constructionLength);
ByteWriter.WriteByte(buffer, ref offset, (byte)DerEncodingTag.Sequence); ByteWriter.WriteByte(buffer, ref offset, (byte)DerEncodingTag.Sequence);
DerEncodingHelper.WriteLength(buffer, ref offset, sequenceLength);
foreach (byte[] mechanismType in mechanismTypeList) foreach (byte[] mechanismType in mechanismTypeList)
{ {
int lengthFieldSize = DerEncodingHelper.GetLengthFieldSize(mechanismType.Length);
int entryLength = 1 + lengthFieldSize + mechanismType.Length;
DerEncodingHelper.WriteLength(buffer, ref offset, entryLength);
ByteWriter.WriteByte(buffer, ref offset, (byte)DerEncodingTag.ObjectIdentifier); ByteWriter.WriteByte(buffer, ref offset, (byte)DerEncodingTag.ObjectIdentifier);
DerEncodingHelper.WriteLength(buffer, ref offset, mechanismType.Length); DerEncodingHelper.WriteLength(buffer, ref offset, mechanismType.Length);
ByteWriter.WriteBytes(buffer, ref offset, mechanismType); ByteWriter.WriteBytes(buffer, ref offset, mechanismType);

View file

@ -19,14 +19,6 @@ namespace SMBLibrary.Authentication
RequestMic = 0x03, RequestMic = 0x03,
} }
public class TokenResponseEntry
{
public NegState? NegState; // Optional
public byte[] SupportedMechanism; // Optional
public byte[] ResponseToken; // Optional
public byte[] MechanismListMIC; // Optional
}
/// <summary> /// <summary>
/// RFC 4178 - negTokenResp /// RFC 4178 - negTokenResp
/// </summary> /// </summary>
@ -38,7 +30,10 @@ namespace SMBLibrary.Authentication
public const byte ResponseTokenTag = 0xA2; public const byte ResponseTokenTag = 0xA2;
public const byte MechanismListMICTag = 0xA3; public const byte MechanismListMICTag = 0xA3;
public List<TokenResponseEntry> Tokens = new List<TokenResponseEntry>(); public NegState? NegState; // Optional
public byte[] SupportedMechanism; // Optional
public byte[] ResponseToken; // Optional
public byte[] MechanismListMIC; // Optional
public SimpleProtectedNegotiationTokenResponse() public SimpleProtectedNegotiationTokenResponse()
{ {
@ -48,84 +43,98 @@ namespace SMBLibrary.Authentication
public SimpleProtectedNegotiationTokenResponse(byte[] buffer, int offset) public SimpleProtectedNegotiationTokenResponse(byte[] buffer, int offset)
{ {
int constuctionLength = DerEncodingHelper.ReadLength(buffer, ref offset); int constuctionLength = DerEncodingHelper.ReadLength(buffer, ref offset);
int sequenceEndOffset = offset + constuctionLength;
byte tag = ByteReader.ReadByte(buffer, ref offset); byte tag = ByteReader.ReadByte(buffer, ref offset);
if (tag != (byte)DerEncodingTag.Sequence) if (tag != (byte)DerEncodingTag.Sequence)
{ {
throw new InvalidDataException(); throw new InvalidDataException();
} }
int sequenceLength = DerEncodingHelper.ReadLength(buffer, ref offset);
int sequenceEndOffset = offset + sequenceLength;
while (offset < sequenceEndOffset) while (offset < sequenceEndOffset)
{ {
int entryLength = DerEncodingHelper.ReadLength(buffer, ref offset); tag = ByteReader.ReadByte(buffer, ref offset);
int entryEndOffset = offset + entryLength; if (tag == NegStateTag)
TokenResponseEntry entry = new TokenResponseEntry();
while (offset < entryEndOffset)
{ {
tag = ByteReader.ReadByte(buffer, ref offset); NegState = ReadNegState(buffer, ref offset);
if (tag == NegStateTag) }
{ else if (tag == SupportedMechanismTag)
entry.NegState = ReadNegState(buffer, ref offset); {
} SupportedMechanism = ReadSupportedMechanism(buffer, ref offset);
else if (tag == SupportedMechanismTag) }
{ else if (tag == ResponseTokenTag)
entry.SupportedMechanism = ReadSupportedMechanism(buffer, ref offset); {
} ResponseToken = ReadResponseToken(buffer, ref offset);
else if (tag == ResponseTokenTag) }
{ else if (tag == MechanismListMICTag)
entry.ResponseToken = ReadResponseToken(buffer, ref offset); {
} MechanismListMIC = ReadMechanismListMIC(buffer, ref offset);
else if (tag == MechanismListMICTag) }
{ else
entry.MechanismListMIC = ReadMechanismListMIC(buffer, ref offset); {
} throw new InvalidDataException("Invalid negTokenResp structure");
else
{
throw new InvalidDataException("Invalid negTokenResp structure");
}
} }
Tokens.Add(entry);
} }
} }
public override byte[] GetBytes() public override byte[] GetBytes()
{ {
int sequenceLength = 0; int sequenceLength = GetTokenFieldsLength();
foreach (TokenResponseEntry token in Tokens) int sequenceLengthFieldSize = DerEncodingHelper.GetLengthFieldSize(sequenceLength);
{ int constructionLength = 1 + sequenceLengthFieldSize + sequenceLength;
int entryLength = GetEntryLength(token); int constructionLengthFieldSize = DerEncodingHelper.GetLengthFieldSize(constructionLength);
sequenceLength += DerEncodingHelper.GetLengthFieldSize(entryLength) + entryLength; int bufferSize = 1 + constructionLengthFieldSize + 1 + sequenceLengthFieldSize + sequenceLength;
}
int constructionLengthFieldSize = DerEncodingHelper.GetLengthFieldSize(1 + sequenceLength);
int bufferSize = 1 + constructionLengthFieldSize + 1 + sequenceLength;
byte[] buffer = new byte[bufferSize]; byte[] buffer = new byte[bufferSize];
int offset = 0; int offset = 0;
ByteWriter.WriteByte(buffer, ref offset, NegTokenRespTag); ByteWriter.WriteByte(buffer, ref offset, NegTokenRespTag);
DerEncodingHelper.WriteLength(buffer, ref offset, 1 + sequenceLength); DerEncodingHelper.WriteLength(buffer, ref offset, constructionLength);
ByteWriter.WriteByte(buffer, ref offset, (byte)DerEncodingTag.Sequence); ByteWriter.WriteByte(buffer, ref offset, (byte)DerEncodingTag.Sequence);
foreach (TokenResponseEntry token in Tokens) DerEncodingHelper.WriteLength(buffer, ref offset, sequenceLength);
if (NegState.HasValue)
{ {
int entryLength = GetEntryLength(token); WriteNegState(buffer, ref offset, NegState.Value);
DerEncodingHelper.WriteLength(buffer, ref offset, entryLength); }
if (token.NegState.HasValue) if (SupportedMechanism != null)
{ {
WriteNegState(buffer, ref offset, token.NegState.Value); WriteSupportedMechanism(buffer, ref offset, SupportedMechanism);
} }
if (token.SupportedMechanism != null) if (ResponseToken != null)
{ {
WriteSupportedMechanism(buffer, ref offset, token.SupportedMechanism); WriteResponseToken(buffer, ref offset, ResponseToken);
} }
if (token.ResponseToken != null) if (MechanismListMIC != null)
{ {
WriteResponseToken(buffer, ref offset, token.ResponseToken); WriteMechanismListMIC(buffer, ref offset, MechanismListMIC);
}
if (token.MechanismListMIC != null)
{
WriteMechanismListMIC(buffer, ref offset, token.MechanismListMIC);
}
} }
return buffer; return buffer;
} }
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;
}
return result;
}
private static NegState ReadNegState(byte[] buffer, ref int offset) private static NegState ReadNegState(byte[] buffer, ref int offset)
{ {
int length = DerEncodingHelper.ReadLength(buffer, ref offset); int length = DerEncodingHelper.ReadLength(buffer, ref offset);
@ -174,31 +183,6 @@ namespace SMBLibrary.Authentication
return ByteReader.ReadBytes(buffer, ref offset, length); return ByteReader.ReadBytes(buffer, ref offset, length);
} }
private static int GetEntryLength(TokenResponseEntry token)
{
int result = 0;
if (token.NegState.HasValue)
{
int negStateLength = 5;
result += negStateLength;
}
if (token.SupportedMechanism != null)
{
int supportedMechanismLength2FieldSize = DerEncodingHelper.GetLengthFieldSize(token.SupportedMechanism.Length);
int supportedMechanismLength1FieldSize = DerEncodingHelper.GetLengthFieldSize(1 + supportedMechanismLength2FieldSize + token.SupportedMechanism.Length);
int supportedMechanismLength = 1 + supportedMechanismLength1FieldSize + 1 + supportedMechanismLength2FieldSize + token.SupportedMechanism.Length;
result += supportedMechanismLength;
}
if (token.ResponseToken != null)
{
int responseToken2FieldSize = DerEncodingHelper.GetLengthFieldSize(token.ResponseToken.Length);
int responseToken1FieldSize = DerEncodingHelper.GetLengthFieldSize(1 + responseToken2FieldSize + token.ResponseToken.Length);
int responseTokenLength = 1 + responseToken1FieldSize + 1 + responseToken2FieldSize + token.ResponseToken.Length;
result += responseTokenLength;
}
return result;
}
private static void WriteNegState(byte[] buffer, ref int offset, NegState negState) private static void WriteNegState(byte[] buffer, ref int offset, NegState negState)
{ {
ByteWriter.WriteByte(buffer, ref offset, NegStateTag); ByteWriter.WriteByte(buffer, ref offset, NegStateTag);