Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/SuperSocket.MySQL/MySQLConnection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ private byte[] GenerateNativePasswordResponse(byte[] salt)
}
}

private byte[] GenerateCachingSha2Response(byte[] salt)
internal byte[] GenerateCachingSha2Response(byte[] salt)
{
if (string.IsNullOrEmpty(_password))
return Array.Empty<byte>();
Expand Down Expand Up @@ -383,4 +383,4 @@ protected override void OnClosed(object sender, EventArgs e)
base.OnClosed(sender, e);
}
}
}
}
35 changes: 35 additions & 0 deletions tests/SuperSocket.MySQL.Test/HandshakeTest.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.Buffers;
using System.Collections.Generic;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using Xunit;
Expand Down Expand Up @@ -202,6 +203,40 @@ public void MySQLConnection_GenerateAuthResponse_ShouldHandleDifferentPasswords(
Assert.NotNull(connection);
}

[Fact]
public void MySQLConnection_GenerateCachingSha2Response_ShouldMatchExpected()
{
// Arrange
const string password = "test_password";
var connection = new MySQLConnection("localhost", 3306, "user", password);
// Include a trailing null byte to validate trimming of the salt.
var salt = new byte[] { 0x33, 0x21, 0x55, 0x42, 0x19, 0x76, 0xA1, 0x0B, 0x10, 0x5C, 0x2D, 0x48, 0x5A, 0x00 };

// Act
var response = connection.GenerateCachingSha2Response(salt);

// Assert
var trimmedSaltLength = salt[^1] == 0 ? salt.Length - 1 : salt.Length;
var trimmedSalt = new byte[trimmedSaltLength];
Array.Copy(salt, trimmedSalt, trimmedSaltLength);

using var sha256 = SHA256.Create();
var passwordBytes = Encoding.UTF8.GetBytes(password);
var sha256Password = sha256.ComputeHash(passwordBytes);
var sha256Sha256Password = sha256.ComputeHash(sha256Password);
var hashAndSalt = new byte[sha256Sha256Password.Length + trimmedSalt.Length];
Array.Copy(sha256Sha256Password, 0, hashAndSalt, 0, sha256Sha256Password.Length);
Array.Copy(trimmedSalt, 0, hashAndSalt, sha256Sha256Password.Length, trimmedSalt.Length);
var sha256Combined = sha256.ComputeHash(hashAndSalt);
var expected = new byte[sha256Password.Length];
for (int i = 0; i < expected.Length; i++)
{
expected[i] = (byte)(sha256Password[i] ^ sha256Combined[i]);
}

Assert.Equal(expected, response);
}

[Fact]
public void EOFPacket_ShouldNotIndicateAuthenticationSuccess()
{
Expand Down