From df74db73229beddd7f1315bd8279ab2f6a1dc193 Mon Sep 17 00:00:00 2001 From: Kevin Froman Date: Mon, 25 May 2020 15:17:41 -0500 Subject: [PATCH] ported to dotnet core, fixed bad random number generator vuln --- src/niceware.tests/NicewareTests.cs | 94 ------------------------ src/niceware.tests/niceware.tests.csproj | 14 ---- src/niceware/AssemblyInfo.cs | 8 -- src/niceware/Niceware.cs | 8 +- src/niceware/niceware.csproj | 34 ++------- src/tests/NicewareTest.cs | 48 ++++++++++++ src/tests/tests.csproj | 19 +++++ 7 files changed, 78 insertions(+), 147 deletions(-) delete mode 100644 src/niceware.tests/NicewareTests.cs delete mode 100644 src/niceware.tests/niceware.tests.csproj delete mode 100644 src/niceware/AssemblyInfo.cs create mode 100644 src/tests/NicewareTest.cs create mode 100644 src/tests/tests.csproj diff --git a/src/niceware.tests/NicewareTests.cs b/src/niceware.tests/NicewareTests.cs deleted file mode 100644 index 6e937cf..0000000 --- a/src/niceware.tests/NicewareTests.cs +++ /dev/null @@ -1,94 +0,0 @@ -using System; -using System.Collections.Generic; -using Xunit; -using niceware; - -namespace niceware.tests -{ - public class NicewareTests - { - [Theory] - [MemberData(nameof(ToPassphraseData))] - public void ToPassphrase(byte[] bytes, IEnumerable expected) - { - var actual = bytes.ToPassphrase(); - Assert.Equal(expected, actual); - } - - public static IEnumerable ToPassphraseData() - { - yield return new object[] { new byte[0], new string[0] }; - yield return new object[] { new byte[] { 0, 0}, new [] { "a" } }; - yield return new object[] { new byte[] { 255, 255}, new [] { "zyzzyva" } }; - yield return new object[] - { - new byte[] { 0, 0, 17, 212, 12, 140, 90, 247, 46, 83, 254, 60, 54, 169, 255, 255 }, - new [] { "a", "bioengineering", "balloted", "gobbledegook", "creneled", "written", "depriving", "zyzzyva" } - }; - } - - [Theory] - [InlineData(2, 1)] - [InlineData(0, 0)] - [InlineData(8, 4)] - [InlineData(20, 10)] - [InlineData(512, 256)] - public void GeneratePassphrase(int length, int expectedWords) - { - var actual = Niceware.GeneratePassphrase(length); - Assert.Equal(expectedWords, actual.Count); - } - - [Theory] - [InlineData(1)] - [InlineData(23)] - public void GeneratePassphrase_OddBytes(int length) - { - var ex = Assert.Throws(() => Niceware.GeneratePassphrase(length)); - Assert.Equal("Only even-sized byte arrays are supported", ex.Message); - } - - [Theory] - [InlineData(1025)] - [InlineData(-1)] - public void GeneratePassphrase_OutOfRange(int length) - { - var ex = Assert.Throws(() => Niceware.GeneratePassphrase(length)); - Assert.Equal($"Size must be between 0 and {Niceware.MaxPassphraseSize} bytes", ex.Message); - } - - [Theory] - [MemberData(nameof(PassphraseToBytesData))] - public void PassphraseToBytes(IEnumerable passphrase, byte[] expected) - { - var actual = passphrase.PassphraseToBytes(); - Assert.Equal(expected, actual); - } - - public static IEnumerable PassphraseToBytesData() - { - yield return new object[] { new [] { "A" }, new byte[] { 0, 0 } }; - yield return new object[] { new [] { "zyzzyva" }, new byte[] { 255, 255 } }; - yield return new object[] - { - new [] { "A", "bioengineering", "Balloted", "gobbledegooK", "cReneled", "wriTTen", "depriving", "zyzzyva" }, - new byte[] { 0, 0, 17, 212, 12, 140, 90, 247, 46, 83, 254, 60, 54, 169, 255, 255 } - }; - } - - [Fact] - public void PassphraseToBytes_NullOk() - { - var actual = ((string[])null).PassphraseToBytes(); - Assert.Equal(new byte[0], actual); - } - - [Fact] - public void PassphraseToBytes_InvalidWord() - { - var ex = Assert.Throws(() => new [] { "You", "love", "ninetales" }.PassphraseToBytes()); - Assert.StartsWith("Invalid word", ex.Message); - } - } -} - diff --git a/src/niceware.tests/niceware.tests.csproj b/src/niceware.tests/niceware.tests.csproj deleted file mode 100644 index e821504..0000000 --- a/src/niceware.tests/niceware.tests.csproj +++ /dev/null @@ -1,14 +0,0 @@ - - - - netcoreapp1.1;net462 - - - - - - - - - - diff --git a/src/niceware/AssemblyInfo.cs b/src/niceware/AssemblyInfo.cs deleted file mode 100644 index 6fb1625..0000000 --- a/src/niceware/AssemblyInfo.cs +++ /dev/null @@ -1,8 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -[assembly: AssemblyProduct("Niceware")] -[assembly: AssemblyVersion("0.1.0.0")] -[assembly: AssemblyFileVersion("0.1.0.0")] -[assembly: AssemblyInformationalVersion("0.1.0.0")] \ No newline at end of file diff --git a/src/niceware/Niceware.cs b/src/niceware/Niceware.cs index cbac488..d1fd721 100644 --- a/src/niceware/Niceware.cs +++ b/src/niceware/Niceware.cs @@ -6,8 +6,6 @@ namespace niceware { public static partial class Niceware { - private static Random _random = new Random((int)DateTime.Now.Ticks); - /// Maximum number of bytes for a passphrase public const int MaxPassphraseSize = 1024; @@ -51,10 +49,12 @@ namespace niceware } var bytes = new Byte[size]; - _random.NextBytes(bytes); + var rng = System.Security.Cryptography.RandomNumberGenerator.Create(); + rng.GetBytes(bytes); + rng.Dispose(); return new Tuple, byte[]>(bytes.ToPassphrase(), bytes); } - + /// Converts a phrase back into the original byte array /// Passphrase /// Array of bytes diff --git a/src/niceware/niceware.csproj b/src/niceware/niceware.csproj index 5b26daa..72764a6 100644 --- a/src/niceware/niceware.csproj +++ b/src/niceware/niceware.csproj @@ -1,27 +1,7 @@ - - - - netstandard1.4;net462 - portable - Niceware - Library - - false - false - false - false - false - false - false - - 0.1.0.1 - Niceware for .NET - Todd Palmer - A library for generating random-yet-memorable passwords - false - niceware passphrase - https://github.com/trpalmer/dotnet-niceware - https://github.com/trpalmer/dotnet-niceware - - - + + + + netstandard2.0 + + + diff --git a/src/tests/NicewareTest.cs b/src/tests/NicewareTest.cs new file mode 100644 index 0000000..f78dbb1 --- /dev/null +++ b/src/tests/NicewareTest.cs @@ -0,0 +1,48 @@ +using NUnit.Framework; +using System; +using niceware; + +namespace tests +{ + public class Tests + { + + [SetUp] + public void Setup() + { + } + + [Test] + public void TestToBytes() + { + byte[] bytes = {5, 3, 3, 2, 100, 255}; + var pass = Niceware.ToPassphrase(bytes); + string[] expected = {"anatomic", "aliphatic", "homebuilding"}; + for (int i = 0; i < expected.Length; i++){ + Assert.IsEqual() + } + } + + + [Test] + public void TestGeneratePassphraseCount() + { + // 2 bytes per word + Assert.IsTrue(Niceware.GeneratePassphrase(4).Count == 2); + } + + + + [Test] + public void TestNoOdd(){ + bool success = true; + try{ + Niceware.GeneratePassphrase(3); + } + catch(System.ArgumentException){ + success = false; + } + Assert.IsFalse(success); + } + } +} \ No newline at end of file diff --git a/src/tests/tests.csproj b/src/tests/tests.csproj new file mode 100644 index 0000000..31e1e88 --- /dev/null +++ b/src/tests/tests.csproj @@ -0,0 +1,19 @@ + + + + netcoreapp3.1 + + false + + + + + + + + + + + + +