Refactored PreAuthIntegrityCapabilities and EncryptionCapabilities to inherit from NegotiateContext

This commit is contained in:
Tal Aloni 2024-08-03 14:03:04 +03:00
parent d7d65f0ef2
commit e0d8e8dfbd
4 changed files with 74 additions and 52 deletions

View file

@ -683,8 +683,8 @@ namespace SMBLibrary.Client
return new List<NegotiateContext>() return new List<NegotiateContext>()
{ {
new NegotiateContext(preAuthIntegrityCapabilities), preAuthIntegrityCapabilities,
new NegotiateContext(encryptionCapabilities) encryptionCapabilities
}; };
} }

View file

@ -12,7 +12,7 @@ namespace SMBLibrary.SMB2
/// <summary> /// <summary>
/// [MS-SMB2] 2.2.3.1.2 SMB2_ENCRYPTION_CAPABILITIES /// [MS-SMB2] 2.2.3.1.2 SMB2_ENCRYPTION_CAPABILITIES
/// </summary> /// </summary>
public class EncryptionCapabilities public class EncryptionCapabilities : NegotiateContext
{ {
// ushort CipherCount; // ushort CipherCount;
public List<CipherAlgorithm> Ciphers = new List<CipherAlgorithm>(); public List<CipherAlgorithm> Ciphers = new List<CipherAlgorithm>();
@ -21,26 +21,33 @@ namespace SMBLibrary.SMB2
{ {
} }
public EncryptionCapabilities(byte[] buffer, int offset) public EncryptionCapabilities(byte[] buffer, int offset) : base(buffer, offset)
{ {
ushort cipherCount = LittleEndianConverter.ToUInt16(buffer, offset); ushort cipherCount = LittleEndianConverter.ToUInt16(Data, 0);
for (int index = 0; index < cipherCount; index++) for (int index = 0; index < cipherCount; index++)
{ {
Ciphers.Add((CipherAlgorithm)LittleEndianConverter.ToUInt16(buffer, offset + index * 2)); Ciphers.Add((CipherAlgorithm)LittleEndianConverter.ToUInt16(Data, index * 2));
} }
} }
public byte[] GetBytes() public override void WriteData()
{ {
int length = 2 + Ciphers.Count * 2; Data = new byte[DataLength];
byte[] buffer = new byte[length]; LittleEndianWriter.WriteUInt16(Data, 0, (ushort)Ciphers.Count);
LittleEndianWriter.WriteUInt16(buffer, 0, (ushort)Ciphers.Count);
for (int index = 0; index < Ciphers.Count; index++) for (int index = 0; index < Ciphers.Count; index++)
{ {
LittleEndianWriter.WriteUInt16(buffer, 2 + index * 2, (ushort)Ciphers[index]); LittleEndianWriter.WriteUInt16(Data, 2 + index * 2, (ushort)Ciphers[index]);
}
} }
return buffer; public override int DataLength
{
get
{
return 2 + Ciphers.Count * 2;
} }
} }
public override NegotiateContextType ContextType => NegotiateContextType.SMB2_ENCRYPTION_CAPABILITIES;
}
} }

View file

@ -4,7 +4,6 @@
* the GNU Lesser Public License as published by the Free Software Foundation, * the GNU Lesser Public License as published by the Free Software Foundation,
* either version 3 of the License, or (at your option) any later version. * either version 3 of the License, or (at your option) any later version.
*/ */
using System;
using System.Collections.Generic; using System.Collections.Generic;
using Utilities; using Utilities;
@ -17,8 +16,8 @@ namespace SMBLibrary.SMB2
{ {
public const int FixedLength = 8; public const int FixedLength = 8;
public NegotiateContextType ContextType; private NegotiateContextType m_contextType;
private ushort DataLength; // ushort DataLength;
public uint Reserved; public uint Reserved;
public byte[] Data = new byte[0]; public byte[] Data = new byte[0];
@ -26,31 +25,23 @@ namespace SMBLibrary.SMB2
{ {
} }
public NegotiateContext(PreAuthIntegrityCapabilities preAuthIntegrityCapabilities)
{
ContextType = NegotiateContextType.SMB2_PREAUTH_INTEGRITY_CAPABILITIES;
Data = preAuthIntegrityCapabilities.GetBytes();
}
public NegotiateContext(EncryptionCapabilities encryptionCapabilities)
{
ContextType = NegotiateContextType.SMB2_ENCRYPTION_CAPABILITIES;
Data = encryptionCapabilities.GetBytes();
}
public NegotiateContext(byte[] buffer, int offset) public NegotiateContext(byte[] buffer, int offset)
{ {
ContextType = (NegotiateContextType)LittleEndianConverter.ToUInt16(buffer, offset + 0); m_contextType = (NegotiateContextType)LittleEndianConverter.ToUInt16(buffer, offset + 0);
DataLength = LittleEndianConverter.ToUInt16(buffer, offset + 2); int dataLength = LittleEndianConverter.ToUInt16(buffer, offset + 2);
Reserved = LittleEndianConverter.ToUInt32(buffer, offset + 4); Reserved = LittleEndianConverter.ToUInt32(buffer, offset + 4);
Data = ByteReader.ReadBytes(buffer, offset + 8, DataLength); Data = ByteReader.ReadBytes(buffer, offset + 8, dataLength);
}
public virtual void WriteData()
{
} }
public void WriteBytes(byte[] buffer, int offset) public void WriteBytes(byte[] buffer, int offset)
{ {
DataLength = (ushort)Data.Length; WriteData();
LittleEndianWriter.WriteUInt16(buffer, offset + 0, (ushort)ContextType); LittleEndianWriter.WriteUInt16(buffer, offset + 0, (ushort)ContextType);
LittleEndianWriter.WriteUInt16(buffer, offset + 2, DataLength); LittleEndianWriter.WriteUInt16(buffer, offset + 2, (ushort)DataLength);
LittleEndianWriter.WriteUInt32(buffer, offset + 4, Reserved); LittleEndianWriter.WriteUInt32(buffer, offset + 4, Reserved);
ByteWriter.WriteBytes(buffer, offset + 8, Data); ByteWriter.WriteBytes(buffer, offset + 8, Data);
} }
@ -59,7 +50,7 @@ namespace SMBLibrary.SMB2
{ {
get get
{ {
return FixedLength + Data.Length; return FixedLength + DataLength;
} }
} }
@ -67,17 +58,31 @@ namespace SMBLibrary.SMB2
{ {
get get
{ {
int paddingLength = (8 - (Data.Length % 8)) % 8; int paddingLength = (8 - (DataLength % 8)) % 8;
return this.Length + paddingLength; return this.Length + paddingLength;
} }
} }
public static NegotiateContext ReadNegotiateContext(byte[] buffer, int offset)
{
NegotiateContextType contextType = (NegotiateContextType)LittleEndianConverter.ToUInt16(buffer, offset + 0);
switch (contextType)
{
case NegotiateContextType.SMB2_PREAUTH_INTEGRITY_CAPABILITIES:
return new PreAuthIntegrityCapabilities(buffer, offset);
case NegotiateContextType.SMB2_ENCRYPTION_CAPABILITIES:
return new EncryptionCapabilities(buffer, offset);
default:
return new NegotiateContext(buffer, offset);
}
}
public static List<NegotiateContext> ReadNegotiateContextList(byte[] buffer, int offset, int count) public static List<NegotiateContext> ReadNegotiateContextList(byte[] buffer, int offset, int count)
{ {
List<NegotiateContext> result = new List<NegotiateContext>(); List<NegotiateContext> result = new List<NegotiateContext>();
for (int index = 0; index < count; index++) for (int index = 0; index < count; index++)
{ {
NegotiateContext context = new NegotiateContext(buffer, offset); NegotiateContext context = ReadNegotiateContext(buffer, offset);
result.Add(context); result.Add(context);
offset += context.PaddedLength; offset += context.PaddedLength;
} }
@ -112,5 +117,9 @@ namespace SMBLibrary.SMB2
} }
return result; return result;
} }
public virtual int DataLength => Data.Length;
public virtual NegotiateContextType ContextType => m_contextType;
} }
} }

View file

@ -12,7 +12,7 @@ namespace SMBLibrary.SMB2
/// <summary> /// <summary>
/// [MS-SMB2] 2.2.3.1.1 - SMB2_PREAUTH_INTEGRITY_CAPABILITIES /// [MS-SMB2] 2.2.3.1.1 - SMB2_PREAUTH_INTEGRITY_CAPABILITIES
/// </summary> /// </summary>
public class PreAuthIntegrityCapabilities public class PreAuthIntegrityCapabilities : NegotiateContext
{ {
// ushort HashAlgorithmCount; // ushort HashAlgorithmCount;
// ushort SaltLength; // ushort SaltLength;
@ -23,31 +23,37 @@ namespace SMBLibrary.SMB2
{ {
} }
public PreAuthIntegrityCapabilities(byte[] buffer, int offset) public PreAuthIntegrityCapabilities(byte[] buffer, int offset) : base(buffer, offset)
{ {
ushort hashAlgorithmCount = LittleEndianConverter.ToUInt16(buffer, offset + 0); ushort hashAlgorithmCount = LittleEndianConverter.ToUInt16(Data, 0);
ushort saltLength = LittleEndianConverter.ToUInt16(buffer, offset + 2); ushort saltLength = LittleEndianConverter.ToUInt16(Data, 2);
for (int index = 0; index < hashAlgorithmCount; index++) for (int index = 0; index < hashAlgorithmCount; index++)
{ {
HashAlgorithms.Add((HashAlgorithm)LittleEndianConverter.ToUInt16(buffer, offset + 4 + index * 2)); HashAlgorithms.Add((HashAlgorithm)LittleEndianConverter.ToUInt16(Data, 4 + index * 2));
} }
Salt = ByteReader.ReadBytes(buffer, offset + 4 + hashAlgorithmCount * 2, saltLength); Salt = ByteReader.ReadBytes(Data, 4 + hashAlgorithmCount * 2, saltLength);
} }
public byte[] GetBytes() public override void WriteData()
{ {
int length = 4 + HashAlgorithms.Count * 2 + Salt.Length; Data = new byte[DataLength];
LittleEndianWriter.WriteUInt16(Data, 0, (ushort)HashAlgorithms.Count);
byte[] buffer = new byte[length]; LittleEndianWriter.WriteUInt16(Data, 2, (ushort)Salt.Length);
LittleEndianWriter.WriteUInt16(buffer, 0, (ushort)HashAlgorithms.Count);
LittleEndianWriter.WriteUInt16(buffer, 2, (ushort)Salt.Length);
for (int index = 0; index < HashAlgorithms.Count; index++) for (int index = 0; index < HashAlgorithms.Count; index++)
{ {
LittleEndianWriter.WriteUInt16(buffer, 4 + index * 2, (ushort)HashAlgorithms[index]); LittleEndianWriter.WriteUInt16(Data, 4 + index * 2, (ushort)HashAlgorithms[index]);
}
ByteWriter.WriteBytes(Data, 4 + HashAlgorithms.Count * 2, Salt);
} }
ByteWriter.WriteBytes(buffer, 4 + HashAlgorithms.Count * 2, Salt);
return buffer; public override int DataLength
{
get
{
return 4 + HashAlgorithms.Count * 2 + Salt.Length;
} }
} }
public override NegotiateContextType ContextType => NegotiateContextType.SMB2_PREAUTH_INTEGRITY_CAPABILITIES;
}
} }