Skip to content

Commit e72bff4

Browse files
committed
Add client_ed25519 authentication support.
Signed-off-by: Bradley Grainger <[email protected]>
1 parent a0e8207 commit e72bff4

File tree

2 files changed

+38
-5
lines changed

2 files changed

+38
-5
lines changed

src/MySqlConnector.Authentication.Ed25519/Ed25519.cs renamed to src/MySqlConnector.Authentication.Ed25519/Ed25519AuthenticationPlugin.cs

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,28 @@
55

66
namespace MySqlConnector.Authentication.Ed25519
77
{
8-
public static class Ed25519
8+
/// <summary>
9+
/// Provides an implementation of the <c>client_ed25519</c> authentication plugin for MariaDB.
10+
/// </summary>
11+
/// <remarks>See <a href="https://mariadb.com/kb/en/library/authentication-plugin-ed25519/">Authentication Plugin - ed25519</a>.</remarks>
12+
public sealed class Ed25519AuthenticationPlugin : IAuthenticationPlugin
913
{
10-
public static byte[] Ed25519SignWithPassword(string password, byte[] seed)
14+
/// <summary>
15+
/// Registers the Ed25519 authentication plugin with MySqlConnector. You must call this method once before
16+
/// opening a connection that uses Ed25519 authentication.
17+
/// </summary>
18+
public static void Install()
19+
{
20+
if (!s_isInstalled)
21+
{
22+
AuthenticationPlugins.Register(new Ed25519AuthenticationPlugin());
23+
s_isInstalled = true;
24+
}
25+
}
26+
27+
public string Name => "client_ed25519";
28+
29+
public byte[] CreateResponse(string password, ReadOnlySpan<byte> authenticationData)
1130
{
1231
// Java reference: https://github.com/MariaDB/mariadb-connector-j/blob/master/src/main/java/org/mariadb/jdbc/internal/com/send/authentication/Ed25519PasswordPlugin.java
1332
// C reference: https://github.com/MariaDB/server/blob/592fe954ef82be1bc08b29a8e54f7729eb1e1343/plugin/auth_ed25519/ref10/sign.c#L7
@@ -64,10 +83,10 @@ public static byte[] Ed25519SignWithPassword(string password, byte[] seed)
6483
crypto_hash_sha512(nonce,sm + 32,mlen + 32);
6584
*/
6685

67-
byte[] sm = new byte[64 + seed.Length];
68-
Buffer.BlockCopy(seed, 0, sm, 64, seed.Length);
86+
byte[] sm = new byte[64 + authenticationData.Length];
87+
authenticationData.CopyTo(sm.AsSpan().Slice(64));
6988
Buffer.BlockCopy(az, 32, sm, 32, 32);
70-
byte[] nonce = sha512.ComputeHash(sm, 32, seed.Length + 32);
89+
byte[] nonce = sha512.ComputeHash(sm, 32, authenticationData.Length + 32);
7190

7291
/*** Java
7392
ScalarOps scalar = new ScalarOps();
@@ -133,5 +152,11 @@ public static byte[] Ed25519SignWithPassword(string password, byte[] seed)
133152
return result;
134153
}
135154
}
155+
156+
private Ed25519AuthenticationPlugin()
157+
{
158+
}
159+
160+
static bool s_isInstalled;
136161
}
137162
}

src/MySqlConnector/Core/ServerSession.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
using System.Threading;
2020
using System.Threading.Tasks;
2121
using MySql.Data.MySqlClient;
22+
using MySqlConnector.Authentication;
2223
using MySqlConnector.Logging;
2324
using MySqlConnector.Protocol;
2425
using MySqlConnector.Protocol.Payloads;
@@ -518,6 +519,13 @@ private async Task<PayloadData> SwitchAuthenticationAsync(ConnectionSettings cs,
518519
Log.Error("Session{0} is requesting AuthenticationMethod '{1}' which is not supported", m_logArguments);
519520
throw new NotSupportedException("'MySQL Server is requesting the insecure pre-4.1 auth mechanism (mysql_old_password). The user password must be upgraded; see https://dev.mysql.com/doc/refman/5.7/en/account-upgrades.html.");
520521

522+
case "client_ed25519":
523+
if (!AuthenticationPlugins.TryGetPlugin(switchRequest.Name, out var ed25519Plugin))
524+
throw new NotSupportedException("You must install the MySqlConnector.Authentication.Ed25519 package and call Ed25519AuthenticationPlugin.Install to use client_ed25519 authentication.");
525+
payload = new PayloadData(ed25519Plugin.CreateResponse(cs.Password, switchRequest.Data));
526+
await SendReplyAsync(payload, ioBehavior, cancellationToken).ConfigureAwait(false);
527+
return await ReceiveReplyAsync(ioBehavior, cancellationToken).ConfigureAwait(false);
528+
521529
default:
522530
Log.Error("Session{0} is requesting AuthenticationMethod '{1}' which is not supported", m_logArguments);
523531
throw new NotSupportedException("Authentication method '{0}' is not supported.".FormatInvariant(switchRequest.Name));

0 commit comments

Comments
 (0)