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 List<byte[]> MechanismTypeList = new List<byte[]>(); // Optional
// reqFlags - Optional, Unused
// reqFlags - Optional, RECOMMENDED to be left out
public byte[] MechanismToken = new byte[0]; // Optional
// mechListMIC - Optional, Unused
public byte[] MechanismListMIC; // Optional
}
/// <summary>
@ -58,13 +58,21 @@ namespace SMBLibrary.Authentication
{
entry.MechanismTypeList = ReadMechanismTypeList(buffer, ref offset);
}
else if (tag == RequiredFlagsTag)
{
throw new NotImplementedException("negTokenInit.ReqFlags is not implemented");
}
else if (tag == MechanismTokenTag)
{
entry.MechanismToken = ReadMechanismToken(buffer, ref offset);
}
else if (tag == MechanismListMICTag)
{
entry.MechanismListMIC = ReadMechanismListMIC(buffer, ref offset);
}
else
{
throw new InvalidDataException();
throw new InvalidDataException("Invalid negTokenInit structure");
}
}
Tokens.Add(entry);
@ -96,7 +104,11 @@ namespace SMBLibrary.Authentication
}
if (token.MechanismToken != null)
{
WriteMechanismToken(buffer, ref offset, token.MechanismToken);
WriteMechanismToken(buffer, ref offset, token.MechanismToken);
}
if (token.MechanismListMIC != null)
{
WriteMechanismListMIC(buffer, ref offset, token.MechanismListMIC);
}
}
return buffer;
@ -161,6 +173,18 @@ namespace SMBLibrary.Authentication
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)
{
int sequenceLength = 0;
@ -199,6 +223,16 @@ namespace SMBLibrary.Authentication
ByteWriter.WriteByte(buffer, ref offset, (byte)DerEncodingTag.ByteArray);
DerEncodingHelper.WriteLength(buffer, ref offset, mechanismToken.Length);
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 byte[] SupportedMechanism; // Optional
public byte[] ResponseToken; // Optional
// mechListMIC - Optional, Unused
public byte[] MechanismListMIC; // Optional
}
/// <summary>
/// RFC 4178 - negTokenInit
/// RFC 4178 - negTokenResp
/// </summary>
public class SimpleProtectedNegotiationTokenResponse : SimpleProtectedNegotiationToken
{
@ -78,9 +78,13 @@ namespace SMBLibrary.Authentication
{
entry.ResponseToken = ReadResponseToken(buffer, ref offset);
}
else if (tag == MechanismListMICTag)
{
entry.MechanismListMIC = ReadMechanismListMIC(buffer, ref offset);
}
else
{
throw new InvalidDataException();
throw new InvalidDataException("Invalid negTokenResp structure");
}
}
Tokens.Add(entry);
@ -118,6 +122,10 @@ namespace SMBLibrary.Authentication
{
WriteResponseToken(buffer, ref offset, token.ResponseToken);
}
if (token.MechanismListMIC != null)
{
WriteMechanismListMIC(buffer, ref offset, token.MechanismListMIC);
}
}
return buffer;
}
@ -158,6 +166,18 @@ namespace SMBLibrary.Authentication
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)
{
int result = 0;
@ -211,5 +231,15 @@ namespace SMBLibrary.Authentication
DerEncodingHelper.WriteLength(buffer, ref offset, responseToken.Length);
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);
}
}
}