SPNEGO: Added MechanismListMIC to negTokenInit and negTokenResp structures

This commit is contained in:
Tal Aloni 2017-01-10 10:46:51 +02:00
parent cf9aba4a31
commit 3b4c50c190
2 changed files with 72 additions and 8 deletions

View file

@ -14,9 +14,9 @@ namespace SMBLibrary.Authentication
public class TokenInitEntry public class TokenInitEntry
{ {
public List<byte[]> MechanismTypeList = new List<byte[]>(); // Optional public List<byte[]> MechanismTypeList = new List<byte[]>(); // Optional
// reqFlags - Optional, Unused // reqFlags - Optional, RECOMMENDED to be left out
public byte[] MechanismToken = new byte[0]; // Optional public byte[] MechanismToken = new byte[0]; // Optional
// mechListMIC - Optional, Unused public byte[] MechanismListMIC; // Optional
} }
/// <summary> /// <summary>
@ -58,13 +58,21 @@ namespace SMBLibrary.Authentication
{ {
entry.MechanismTypeList = ReadMechanismTypeList(buffer, ref offset); entry.MechanismTypeList = ReadMechanismTypeList(buffer, ref offset);
} }
else if (tag == RequiredFlagsTag)
{
throw new NotImplementedException("negTokenInit.ReqFlags is not implemented");
}
else if (tag == MechanismTokenTag) else if (tag == MechanismTokenTag)
{ {
entry.MechanismToken = ReadMechanismToken(buffer, ref offset); entry.MechanismToken = ReadMechanismToken(buffer, ref offset);
} }
else if (tag == MechanismListMICTag)
{
entry.MechanismListMIC = ReadMechanismListMIC(buffer, ref offset);
}
else else
{ {
throw new InvalidDataException(); throw new InvalidDataException("Invalid negTokenInit structure");
} }
} }
Tokens.Add(entry); Tokens.Add(entry);
@ -98,6 +106,10 @@ namespace SMBLibrary.Authentication
{ {
WriteMechanismToken(buffer, ref offset, token.MechanismToken); WriteMechanismToken(buffer, ref offset, token.MechanismToken);
} }
if (token.MechanismListMIC != null)
{
WriteMechanismListMIC(buffer, ref offset, token.MechanismListMIC);
}
} }
return buffer; return buffer;
} }
@ -161,6 +173,18 @@ namespace SMBLibrary.Authentication
return token; return token;
} }
private static byte[] ReadMechanismListMIC(byte[] buffer, ref int offset)
{
int constructionLength = 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);
}
private static int GetSequenceLength(List<byte[]> mechanismTypeList) private static int GetSequenceLength(List<byte[]> mechanismTypeList)
{ {
int sequenceLength = 0; int sequenceLength = 0;
@ -200,5 +224,15 @@ namespace SMBLibrary.Authentication
DerEncodingHelper.WriteLength(buffer, ref offset, mechanismToken.Length); DerEncodingHelper.WriteLength(buffer, ref offset, mechanismToken.Length);
ByteWriter.WriteBytes(buffer, ref offset, mechanismToken); ByteWriter.WriteBytes(buffer, ref offset, mechanismToken);
} }
private 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);
}
} }
} }

View file

@ -24,11 +24,11 @@ namespace SMBLibrary.Authentication
public NegState? NegState; // Optional public NegState? NegState; // Optional
public byte[] SupportedMechanism; // Optional public byte[] SupportedMechanism; // Optional
public byte[] ResponseToken; // Optional public byte[] ResponseToken; // Optional
// mechListMIC - Optional, Unused public byte[] MechanismListMIC; // Optional
} }
/// <summary> /// <summary>
/// RFC 4178 - negTokenInit /// RFC 4178 - negTokenResp
/// </summary> /// </summary>
public class SimpleProtectedNegotiationTokenResponse : SimpleProtectedNegotiationToken public class SimpleProtectedNegotiationTokenResponse : SimpleProtectedNegotiationToken
{ {
@ -78,9 +78,13 @@ namespace SMBLibrary.Authentication
{ {
entry.ResponseToken = ReadResponseToken(buffer, ref offset); entry.ResponseToken = ReadResponseToken(buffer, ref offset);
} }
else if (tag == MechanismListMICTag)
{
entry.MechanismListMIC = ReadMechanismListMIC(buffer, ref offset);
}
else else
{ {
throw new InvalidDataException(); throw new InvalidDataException("Invalid negTokenResp structure");
} }
} }
Tokens.Add(entry); Tokens.Add(entry);
@ -118,6 +122,10 @@ namespace SMBLibrary.Authentication
{ {
WriteResponseToken(buffer, ref offset, token.ResponseToken); WriteResponseToken(buffer, ref offset, token.ResponseToken);
} }
if (token.MechanismListMIC != null)
{
WriteMechanismListMIC(buffer, ref offset, token.MechanismListMIC);
}
} }
return buffer; return buffer;
} }
@ -158,6 +166,18 @@ namespace SMBLibrary.Authentication
return ByteReader.ReadBytes(buffer, ref offset, length); return ByteReader.ReadBytes(buffer, ref offset, length);
} }
private static byte[] ReadMechanismListMIC(byte[] buffer, ref int offset)
{
int constructionLength = 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);
}
private static int GetEntryLength(TokenResponseEntry token) private static int GetEntryLength(TokenResponseEntry token)
{ {
int result = 0; int result = 0;
@ -211,5 +231,15 @@ namespace SMBLibrary.Authentication
DerEncodingHelper.WriteLength(buffer, ref offset, responseToken.Length); DerEncodingHelper.WriteLength(buffer, ref offset, responseToken.Length);
ByteWriter.WriteBytes(buffer, ref offset, responseToken); ByteWriter.WriteBytes(buffer, ref offset, responseToken);
} }
private 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);
}
} }
} }