internal void TrySendCommand(SMB2Command request, bool encryptData) { if (m_dialect == SMB2Dialect.SMB202 || m_transport == SMBTransportType.NetBiosOverTCP) { request.Header.CreditCharge = 0; request.Header.Credits = 1; m_availableCredits -= 1; } else { if (request.Header.CreditCharge == 0) { request.Header.CreditCharge = 1; } if (m_availableCredits < request.Header.CreditCharge) { throw new Exception("Not enough credits"); } m_availableCredits -= request.Header.CreditCharge; if (m_availableCredits < DesiredCredits) { request.Header.Credits += (ushort)(DesiredCredits - m_availableCredits); } } request.Header.MessageID = m_messageID; request.Header.SessionID = m_sessionID; // [MS-SMB2] If the client encrypts the message [..] then the client MUST set the Signature field of the SMB2 header to zero if (m_signingRequired && !encryptData) { request.Header.IsSigned = (m_sessionID != 0 && ((request.CommandName == SMB2CommandName.TreeConnect || request.Header.TreeID != 0) || (m_dialect == SMB2Dialect.SMB300 && request.CommandName == SMB2CommandName.Logoff))); if (request.Header.IsSigned) { request.Header.Signature = new byte[16]; // Request could be reused byte[] buffer = request.GetBytes(); byte[] signature = SMB2Cryptography.CalculateSignature(m_signingKey, m_dialect, buffer, 0, buffer.Length); // [MS-SMB2] The first 16 bytes of the hash MUST be copied into the 16-byte signature field of the SMB2 Header. request.Header.Signature = ByteReader.ReadBytes(signature, 0, 16); } } TrySendCommand(m_clientSocket, request, encryptData ? m_encryptionKey : null); if (m_dialect == SMB2Dialect.SMB202 || m_transport == SMBTransportType.NetBiosOverTCP) { m_messageID++; } else { m_messageID += request.Header.CreditCharge; } }
public void TestSMB210SignatureCalculation() { byte[] exportedSessionKey = new byte[] { 0x04, 0xE7, 0x07, 0x57, 0x1F, 0x8E, 0x03, 0x53, 0xB7, 0x7A, 0x94, 0xC3, 0x65, 0x3B, 0x87, 0xB5 }; byte[] message = new byte[] { 0xfe, 0x53, 0x4d, 0x42, 0x40, 0x00, 0x01, 0x00, 0x28, 0x01, 0x00, 0xc0, 0x0b, 0x00, 0x07, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xfe, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0xa1, 0x64, 0xff, 0xe5, 0x3d, 0x68, 0x11, 0x98, 0x1f, 0x38, 0x67, 0x72, 0xe3, 0x87, 0xe0, 0x6f, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff }; ByteWriter.WriteBytes(message, 48, new byte[16]); byte[] signature = SMB2Cryptography.CalculateSignature(exportedSessionKey, SMB2Dialect.SMB210, message, 0, message.Length); signature = ByteReader.ReadBytes(signature, 0, 16); byte[] expected = new byte[] { 0xa1, 0x64, 0xff, 0xe5, 0x3d, 0x68, 0x11, 0x98, 0x1f, 0x38, 0x67, 0x72, 0xe3, 0x87, 0xe0, 0x6f }; Assert.True(ByteUtils.AreByteArraysEqual(signature, expected)); }
public void TestSMB202SignatureCalculation() { byte[] exportedSessionKey = new byte[] { 0xD3, 0x83, 0x54, 0xCC, 0x37, 0x43, 0x39, 0xF0, 0x52, 0x4F, 0x78, 0x91, 0x46, 0x78, 0x99, 0x21 }; byte[] message = new byte[] { 0xfe, 0x53, 0x4d, 0x42, 0x40, 0x00, 0x01, 0x00, 0x28, 0x01, 0x00, 0xc0, 0x0b, 0x00, 0x07, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xfe, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0xfb, 0xd2, 0x84, 0x34, 0x03, 0x24, 0xc6, 0x2f, 0xbe, 0xbb, 0x65, 0xdd, 0x10, 0x51, 0xf3, 0xae, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff }; ByteWriter.WriteBytes(message, 48, new byte[16]); byte[] signature = SMB2Cryptography.CalculateSignature(exportedSessionKey, SMB2Dialect.SMB202, message, 0, message.Length); signature = ByteReader.ReadBytes(signature, 0, 16); byte[] expected = new byte[] { 0xfb, 0xd2, 0x84, 0x34, 0x03, 0x24, 0xc6, 0x2f, 0xbe, 0xbb, 0x65, 0xdd, 0x10, 0x51, 0xf3, 0xae }; Assert.True(ByteUtils.AreByteArraysEqual(signature, expected)); }
public void TestSMB300SignatureCalculation() { byte[] exportedSessionKey = new byte[] { 0x35, 0x40, 0x24, 0xCB, 0xCA, 0x4F, 0x94, 0xAA, 0x51, 0xD4, 0x03, 0x3E, 0x6E, 0x9B, 0x2F, 0x98 }; byte[] signingKey = SMB2Cryptography.GenerateSigningKey(exportedSessionKey, SMB2Dialect.SMB300, null); byte[] message = new byte[] { 0xFE, 0x53, 0x4D, 0x42, 0x40, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4D, 0x00, 0x00, 0x20, 0x00, 0x70, 0x00, 0x00, 0x73, 0xF2, 0xCC, 0x56, 0x09, 0x3E, 0xD2, 0xB5, 0xD7, 0x10, 0x66, 0x6C, 0xE4, 0x28, 0x2D, 0xD1, 0x09, 0x00, 0x00, 0x00, 0x48, 0x00, 0x09, 0x00, 0xA1, 0x07, 0x30, 0x05, 0xA0, 0x03, 0x0A, 0x01, 0x00 }; ByteWriter.WriteBytes(message, 48, new byte[16]); byte[] signature = SMB2Cryptography.CalculateSignature(signingKey, SMB2Dialect.SMB300, message, 0, message.Length); signature = ByteReader.ReadBytes(signature, 0, 16); byte[] expected = new byte[] { 0x73, 0xF2, 0xCC, 0x56, 0x09, 0x3E, 0xD2, 0xB5, 0xD7, 0x10, 0x66, 0x6C, 0xE4, 0x28, 0x2D, 0xD1 }; Assert.True(ByteUtils.AreByteArraysEqual(signature, expected)); }