From 711388d720f8ba8abfb4ae43359e67367bc271bd Mon Sep 17 00:00:00 2001 From: Andreas Dirnberger Date: Wed, 29 May 2024 20:20:51 +0200 Subject: [PATCH] test and fix Nkeys.FromPublicKey (#897) --- src/NATS.Client/NKeys.cs | 36 +++++++++++++++++++------------- src/Tests/UnitTests/TestNkeys.cs | 16 ++++++++++++++ 2 files changed, 37 insertions(+), 15 deletions(-) diff --git a/src/NATS.Client/NKeys.cs b/src/NATS.Client/NKeys.cs index c12af6a8e..b3e19591f 100644 --- a/src/NATS.Client/NKeys.cs +++ b/src/NATS.Client/NKeys.cs @@ -11,12 +11,11 @@ // See the License for the specific language governing permissions and // limitations under the License. + using System; using System.IO; using System.Security.Cryptography; -using System.Text; using NATS.Client.NaCl; - namespace NATS.Client { internal static class Crc16 @@ -115,7 +114,7 @@ internal NkeyPair(byte[] userSeed, Nkeys.PrefixType type) public byte[] PrivateKeySeed => seed; public string EncodedSeed => Nkeys.Encode(Nkeys.PrefixFromType(Type), true, seed); - + /// /// Wipes clean the internal private keys. /// @@ -137,7 +136,7 @@ public byte[] Sign(byte[] src) return rv; } -#region IDisposable Support + #region IDisposable Support private bool disposedValue = false; // To detect redundant calls /// @@ -164,7 +163,7 @@ public void Dispose() { Dispose(true); } -#endregion + #endregion } /// @@ -195,7 +194,7 @@ public class Nkeys // PrefixByteUnknown is for unknown prefixes. internal const byte PrefixByteUknown = 23 << 3; // Base32-encodes to 'X...' - + public enum PrefixType { User, @@ -224,7 +223,7 @@ public static byte[] Decode(string src) if (crc != Crc16.Checksum(data)) throw new NATSException("Invalid CRC"); - + return data; } @@ -286,7 +285,7 @@ public static void Wipe(string src) // This code commented out b/c string.remove does not touch the original string. // There is not way to really wipe the contents of a string. // if (src != null && src.Length > 0) - // src.Remove(0); + // src.Remove(0); } internal static byte[] DecodeSeed(byte[] raw) @@ -337,12 +336,11 @@ internal static byte[] DecodeSeed(string src, out PrefixType type) { return DecodeSeed(Nkeys.Decode(src), out type); } - - public static NkeyPair FromPublicKey(char[] publicKey) + + public static NkeyPair FromPublicKey(string publicKey) { - string pkStr = new string(publicKey); - byte[] raw = Nkeys.Decode(pkStr); - byte prefix = (byte)(raw[0] & 0xFF); + byte[] raw = Nkeys.Decode(publicKey); + byte prefix = raw[0]; PrefixType? tfp = TypeFromPrefix(prefix); if (!tfp.HasValue) @@ -350,7 +348,15 @@ public static NkeyPair FromPublicKey(char[] publicKey) throw new NATSException("Not a valid public NKey"); } - return new NkeyPair(Encoding.ASCII.GetBytes(pkStr), null, tfp.Value); + var pk = new byte[32]; + Buffer.BlockCopy(raw, 1, pk, 0, 32); + + return new NkeyPair(pk, null, tfp.Value); + } + + public static NkeyPair FromPublicKey(char[] publicKey) + { + return FromPublicKey(new string(publicKey)); } /// @@ -372,7 +378,7 @@ public static NkeyPair FromSeed(string seed) Wipe(ref userSeed); } } - + internal static string Encode(byte prefixbyte, bool seed, byte[] src) { if (!IsValidPublicPrefixByte(prefixbyte)) diff --git a/src/Tests/UnitTests/TestNkeys.cs b/src/Tests/UnitTests/TestNkeys.cs index 58e4d9444..8b285978f 100644 --- a/src/Tests/UnitTests/TestNkeys.cs +++ b/src/Tests/UnitTests/TestNkeys.cs @@ -79,6 +79,22 @@ public void TestNKEYPublicKeyFromSeed() pk = Nkeys.PublicKeyFromSeed("SUAGDLNBWI2SGHDRYBHD63NH5FGZSVJUW2J7GAJZXWANQFLDW6G5SXZESU"); Assert.Equal("UBICBTHDKQRB4LIYA6BMIJ7EA2G7YS7FIWMMVKZJE6M3HS5IVCOLKDY2", pk); } + + [Theory] + [InlineData("SUAHBVFYZF3DIEO4UIHIZMJICVLURLBM5JJPK7GSVGP2QUC3NZ323BRE6A", "UCM5BG6AAZSEGREBCLG7PG4GFQNJABSAVIXC6VWS7TDHZFPIYFVYHIDG")] + [InlineData("SAADARCQJ3JA737Z443YNAZBNJNTFP7YNAF4QFUXKTBFBS4KAVK55DGSOQ", "AD2HQTUKOPBUGOPHA6KFRE6ZW5TH43D7P7E56OAQBZQLW2ECMNML6MVA")] + [InlineData("SNAH645525YA4PNXHWWS46VNXXQTYAXOPKGHXYAHXZZ43XTDDG2ZQAX7LY", "NBZCD2OSMSDRVYCAI77HUN6A2WNDWNT2DMVVEW66DHNWCDXVOUWRCCK7")] + [InlineData("SOAF5OP7UPK6XJCMNRYEJRET6YQSOE3FD4I4ERSN6WKHLYUC5AQDCOAFVY", "OA6SJACXYP2QGNLU4QYLJTVRVZPCZEEUNO2UQOVNGXYUPUJJHCVZIZQ2")] + [InlineData("SCAP4LGVURDWVL37AZIM5O47UKANFI6FKBY77HMYF55CKW2XFKLNUBTTFE", "CAO36T42KFA2LMIZ6YHJKPQEJWT5ULYSV633FWBCEJ7MREZPHHC56BSC")] + public void TestNKEYFromPublicKey(string encodedSeed, string encodedPubKey) + { + NkeyPair fromSeed = Nkeys.FromSeed(encodedSeed); + NkeyPair fromKey = Nkeys.FromPublicKey(fromSeed.EncodedPublicKey); + + Assert.Equal(fromSeed.PublicKey, fromKey.PublicKey); + Assert.Equal(encodedPubKey, fromSeed.EncodedPublicKey); + Assert.Equal(encodedPubKey, fromKey.EncodedPublicKey); + } } #pragma warning restore CS0618