using NATS.NKeys; using NATS.Server.Auth; using NATS.Server.Protocol; namespace NATS.Server.Tests; public class NKeyAuthenticatorTests { private static (string PublicKey, string SignatureBase64) CreateSignedNonce(byte[] nonce) { var kp = KeyPair.CreatePair(PrefixByte.User); var publicKey = kp.GetPublicKey(); var sig = new byte[64]; kp.Sign(nonce, sig); var sigBase64 = Convert.ToBase64String(sig); return (publicKey, sigBase64); } private static string SignNonce(KeyPair kp, byte[] nonce) { var sig = new byte[64]; kp.Sign(nonce, sig); return Convert.ToBase64String(sig); } [Fact] public void Returns_result_for_valid_signature() { var kp = KeyPair.CreatePair(PrefixByte.User); var publicKey = kp.GetPublicKey(); var nonce = "test-nonce-123"u8.ToArray(); var sigBase64 = SignNonce(kp, nonce); var nkeyUser = new NKeyUser { Nkey = publicKey }; var auth = new NKeyAuthenticator([nkeyUser]); var ctx = new ClientAuthContext { Opts = new ClientOptions { Nkey = publicKey, Sig = sigBase64 }, Nonce = nonce, }; var result = auth.Authenticate(ctx); result.ShouldNotBeNull(); result.Identity.ShouldBe(publicKey); } [Fact] public void Returns_null_for_invalid_signature() { var kp = KeyPair.CreatePair(PrefixByte.User); var publicKey = kp.GetPublicKey(); var nonce = "test-nonce-123"u8.ToArray(); var nkeyUser = new NKeyUser { Nkey = publicKey }; var auth = new NKeyAuthenticator([nkeyUser]); var ctx = new ClientAuthContext { Opts = new ClientOptions { Nkey = publicKey, Sig = Convert.ToBase64String(new byte[64]) }, Nonce = nonce, }; auth.Authenticate(ctx).ShouldBeNull(); } [Fact] public void Returns_null_for_unknown_nkey() { var kp = KeyPair.CreatePair(PrefixByte.User); var publicKey = kp.GetPublicKey(); var nonce = "test-nonce-123"u8.ToArray(); var sigBase64 = SignNonce(kp, nonce); var auth = new NKeyAuthenticator([]); var ctx = new ClientAuthContext { Opts = new ClientOptions { Nkey = publicKey, Sig = sigBase64 }, Nonce = nonce, }; auth.Authenticate(ctx).ShouldBeNull(); } [Fact] public void Returns_null_when_no_nkey_provided() { var kp = KeyPair.CreatePair(PrefixByte.User); var publicKey = kp.GetPublicKey(); var nkeyUser = new NKeyUser { Nkey = publicKey }; var auth = new NKeyAuthenticator([nkeyUser]); var ctx = new ClientAuthContext { Opts = new ClientOptions(), Nonce = "nonce"u8.ToArray(), }; auth.Authenticate(ctx).ShouldBeNull(); } [Fact] public void Returns_permissions_from_nkey_user() { var kp = KeyPair.CreatePair(PrefixByte.User); var publicKey = kp.GetPublicKey(); var nonce = "test-nonce"u8.ToArray(); var sigBase64 = SignNonce(kp, nonce); var perms = new Permissions { Publish = new SubjectPermission { Allow = ["foo.>"] }, }; var nkeyUser = new NKeyUser { Nkey = publicKey, Permissions = perms }; var auth = new NKeyAuthenticator([nkeyUser]); var ctx = new ClientAuthContext { Opts = new ClientOptions { Nkey = publicKey, Sig = sigBase64 }, Nonce = nonce, }; var result = auth.Authenticate(ctx); result.ShouldNotBeNull(); result.Permissions.ShouldBe(perms); } }