mirror of
https://github.com/TalAloni/SMBLibrary.git
synced 2025-07-04 16:53:18 +02:00
Corrected SPNEGO implementation
This commit is contained in:
parent
2f78339fc8
commit
cd03f7c946
3 changed files with 146 additions and 191 deletions
|
@ -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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue