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>()
{
new NegotiateContext(preAuthIntegrityCapabilities),
new NegotiateContext(encryptionCapabilities)
preAuthIntegrityCapabilities,
encryptionCapabilities
};
}

View file

@ -12,7 +12,7 @@ namespace SMBLibrary.SMB2
/// <summary>
/// [MS-SMB2] 2.2.3.1.2 SMB2_ENCRYPTION_CAPABILITIES
/// </summary>
public class EncryptionCapabilities
public class EncryptionCapabilities : NegotiateContext
{
// ushort CipherCount;
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++)
{
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;
byte[] buffer = new byte[length];
LittleEndianWriter.WriteUInt16(buffer, 0, (ushort)Ciphers.Count);
Data = new byte[DataLength];
LittleEndianWriter.WriteUInt16(Data, 0, (ushort)Ciphers.Count);
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,
* either version 3 of the License, or (at your option) any later version.
*/
using System;
using System.Collections.Generic;
using Utilities;
@ -17,8 +16,8 @@ namespace SMBLibrary.SMB2
{
public const int FixedLength = 8;
public NegotiateContextType ContextType;
private ushort DataLength;
private NegotiateContextType m_contextType;
// ushort DataLength;
public uint Reserved;
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)
{
ContextType = (NegotiateContextType)LittleEndianConverter.ToUInt16(buffer, offset + 0);
DataLength = LittleEndianConverter.ToUInt16(buffer, offset + 2);
m_contextType = (NegotiateContextType)LittleEndianConverter.ToUInt16(buffer, offset + 0);
int dataLength = LittleEndianConverter.ToUInt16(buffer, offset + 2);
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)
{
DataLength = (ushort)Data.Length;
WriteData();
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);
ByteWriter.WriteBytes(buffer, offset + 8, Data);
}
@ -59,7 +50,7 @@ namespace SMBLibrary.SMB2
{
get
{
return FixedLength + Data.Length;
return FixedLength + DataLength;
}
}
@ -67,17 +58,31 @@ namespace SMBLibrary.SMB2
{
get
{
int paddingLength = (8 - (Data.Length % 8)) % 8;
int paddingLength = (8 - (DataLength % 8)) % 8;
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)
{
List<NegotiateContext> result = new List<NegotiateContext>();
for (int index = 0; index < count; index++)
{
NegotiateContext context = new NegotiateContext(buffer, offset);
NegotiateContext context = ReadNegotiateContext(buffer, offset);
result.Add(context);
offset += context.PaddedLength;
}
@ -112,5 +117,9 @@ namespace SMBLibrary.SMB2
}
return result;
}
public virtual int DataLength => Data.Length;
public virtual NegotiateContextType ContextType => m_contextType;
}
}

View file

@ -12,7 +12,7 @@ namespace SMBLibrary.SMB2
/// <summary>
/// [MS-SMB2] 2.2.3.1.1 - SMB2_PREAUTH_INTEGRITY_CAPABILITIES
/// </summary>
public class PreAuthIntegrityCapabilities
public class PreAuthIntegrityCapabilities : NegotiateContext
{
// ushort HashAlgorithmCount;
// 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 saltLength = LittleEndianConverter.ToUInt16(buffer, offset + 2);
ushort hashAlgorithmCount = LittleEndianConverter.ToUInt16(Data, 0);
ushort saltLength = LittleEndianConverter.ToUInt16(Data, 2);
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;
byte[] buffer = new byte[length];
LittleEndianWriter.WriteUInt16(buffer, 0, (ushort)HashAlgorithms.Count);
LittleEndianWriter.WriteUInt16(buffer, 2, (ushort)Salt.Length);
Data = new byte[DataLength];
LittleEndianWriter.WriteUInt16(Data, 0, (ushort)HashAlgorithms.Count);
LittleEndianWriter.WriteUInt16(Data, 2, (ushort)Salt.Length);
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;
}
}