diff --git a/src/Standard.Licensing.Tests/KeyGeneratorTests.cs b/src/Standard.Licensing.Tests/KeyGeneratorTests.cs index 2dea38b..1eadf1b 100644 --- a/src/Standard.Licensing.Tests/KeyGeneratorTests.cs +++ b/src/Standard.Licensing.Tests/KeyGeneratorTests.cs @@ -23,7 +23,6 @@ // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -using System.Collections.Generic; using NUnit.Framework; using Standard.Licensing.Security.Cryptography; @@ -35,9 +34,9 @@ public class KeyGeneratorTests [Test] // See Bug #135 public void Ensure_To_Not_Generate_Identical_Keys() { - var passPhrase = "test"; - var privKeySet = new HashSet(); - var pubKeySet = new HashSet(); + string passPhrase = "test"; + HashSet privKeySet = new HashSet(); + HashSet pubKeySet = new HashSet(); // add well known key privKeySet.Add( @@ -47,10 +46,10 @@ public void Ensure_To_Not_Generate_Identical_Keys() for (int i = 0; i < 100; i++) { - var keyGenerator = new KeyGenerator(256); //default key size - var pair = keyGenerator.GenerateKeyPair(); - var privateKey = pair.ToEncryptedPrivateKeyString(passPhrase); - var publicKey = pair.ToPublicKeyString(); + KeyGenerator keyGenerator = new KeyGenerator(256); //default key size + KeyPair? pair = keyGenerator.GenerateKeyPair(); + string? privateKey = pair.ToEncryptedPrivateKeyString(passPhrase); + string? publicKey = pair.ToPublicKeyString(); Assert.That(privKeySet.Add(privateKey), Is.True); Assert.That(pubKeySet.Add(publicKey), Is.True); diff --git a/src/Standard.Licensing.Tests/LicenseSignatureTests.cs b/src/Standard.Licensing.Tests/LicenseSignatureTests.cs index c3537be..1201cb3 100644 --- a/src/Standard.Licensing.Tests/LicenseSignatureTests.cs +++ b/src/Standard.Licensing.Tests/LicenseSignatureTests.cs @@ -23,12 +23,12 @@ // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -using System; -using System.Collections.Generic; using System.Globalization; using System.Xml.Linq; using NUnit.Framework; +using Standard.Licensing.Security.Cryptography; + namespace Standard.Licensing.Tests { [TestFixture] @@ -42,8 +42,8 @@ public class LicenseSignatureTests public void Init() { passPhrase = Guid.NewGuid().ToString(); - var keyGenerator = Security.Cryptography.KeyGenerator.Create(); - var keyPair = keyGenerator.GenerateKeyPair(); + KeyGenerator? keyGenerator = KeyGenerator.Create(); + KeyPair? keyPair = keyGenerator.GenerateKeyPair(); privateKey = keyPair.ToEncryptedPrivateKeyString(passPhrase); publicKey = keyPair.ToPublicKeyString(); } @@ -58,14 +58,14 @@ private static DateTime ConvertToRfc1123(DateTime dateTime) [Test] public void Can_Generate_And_Validate_Signature_With_Empty_License() { - var license = License.New() - .CreateAndSignWithPrivateKey(privateKey, passPhrase); + License? license = License.New() + .CreateAndSignWithPrivateKey(privateKey, passPhrase); Assert.That(license, Is.Not.Null); Assert.That(license.Signature, Is.Not.Null); // validate xml - var xmlElement = XElement.Parse(license.ToString(), LoadOptions.None); + XElement xmlElement = XElement.Parse(license.ToString(), LoadOptions.None); Assert.That(xmlElement.HasElements, Is.True); // validate default values when not set @@ -83,31 +83,31 @@ public void Can_Generate_And_Validate_Signature_With_Empty_License() [Test] public void Can_Generate_And_Validate_Signature_With_Standard_License() { - var licenseId = Guid.NewGuid(); - var customerName = "Max Mustermann"; - var customerEmail = "max@mustermann.tld"; - var expirationDate = DateTime.Now.AddYears(1); - var productFeatures = new Dictionary - { - {"Sales Module", "yes"}, - {"Purchase Module", "yes"}, - {"Maximum Transactions", "10000"} - }; - - var license = License.New() - .WithUniqueIdentifier(licenseId) - .As(LicenseType.Standard) - .WithMaximumUtilization(10) - .WithProductFeatures(productFeatures) - .LicensedTo(customerName, customerEmail) - .ExpiresAt(expirationDate) - .CreateAndSignWithPrivateKey(privateKey, passPhrase); + Guid licenseId = Guid.NewGuid(); + string customerName = "Max Mustermann"; + string customerEmail = "max@mustermann.tld"; + DateTime expirationDate = DateTime.Now.AddYears(1); + Dictionary productFeatures = new Dictionary + { + {"Sales Module", "yes"}, + {"Purchase Module", "yes"}, + {"Maximum Transactions", "10000"} + }; + + License? license = License.New() + .WithUniqueIdentifier(licenseId) + .As(LicenseType.Standard) + .WithMaximumUtilization(10) + .WithProductFeatures(productFeatures) + .LicensedTo(customerName, customerEmail) + .ExpiresAt(expirationDate) + .CreateAndSignWithPrivateKey(privateKey, passPhrase); Assert.That(license, Is.Not.Null); Assert.That(license.Signature, Is.Not.Null); // validate xml - var xmlElement = XElement.Parse(license.ToString(), LoadOptions.None); + XElement xmlElement = XElement.Parse(license.ToString(), LoadOptions.None); Assert.That(xmlElement.HasElements, Is.True); // validate default values when not set @@ -128,25 +128,25 @@ public void Can_Generate_And_Validate_Signature_With_Standard_License() [Test] public void Can_Detect_Hacked_License() { - var licenseId = Guid.NewGuid(); - var customerName = "Max Mustermann"; - var customerEmail = "max@mustermann.tld"; - var expirationDate = DateTime.Now.AddYears(1); - var productFeatures = new Dictionary - { - {"Sales Module", "yes"}, - {"Purchase Module", "yes"}, - {"Maximum Transactions", "10000"} - }; - - var license = License.New() - .WithUniqueIdentifier(licenseId) - .As(LicenseType.Standard) - .WithMaximumUtilization(10) - .WithProductFeatures(productFeatures) - .LicensedTo(customerName, customerEmail) - .ExpiresAt(expirationDate) - .CreateAndSignWithPrivateKey(privateKey, passPhrase); + Guid licenseId = Guid.NewGuid(); + string customerName = "Max Mustermann"; + string customerEmail = "max@mustermann.tld"; + DateTime expirationDate = DateTime.Now.AddYears(1); + Dictionary productFeatures = new Dictionary + { + {"Sales Module", "yes"}, + {"Purchase Module", "yes"}, + {"Maximum Transactions", "10000"} + }; + + License? license = License.New() + .WithUniqueIdentifier(licenseId) + .As(LicenseType.Standard) + .WithMaximumUtilization(10) + .WithProductFeatures(productFeatures) + .LicensedTo(customerName, customerEmail) + .ExpiresAt(expirationDate) + .CreateAndSignWithPrivateKey(privateKey, passPhrase); Assert.That(license, Is.Not.Null); Assert.That(license.Signature, Is.Not.Null); @@ -155,7 +155,7 @@ public void Can_Detect_Hacked_License() Assert.That(license.VerifySignature(publicKey), Is.True); // validate xml - var xmlElement = XElement.Parse(license.ToString(), LoadOptions.None); + XElement xmlElement = XElement.Parse(license.ToString(), LoadOptions.None); Assert.That(xmlElement.HasElements, Is.True); // manipulate xml @@ -163,7 +163,7 @@ public void Can_Detect_Hacked_License() xmlElement.Element("Quantity").Value = "11"; // now we want to have 11 licenses // load license from manipulated xml - var hackedLicense = License.Load(xmlElement.ToString()); + License? hackedLicense = License.Load(xmlElement.ToString()); // validate default values when not set Assert.That(hackedLicense.Id, Is.EqualTo(licenseId)); diff --git a/src/Standard.Licensing.Tests/LicenseValidationTests.cs b/src/Standard.Licensing.Tests/LicenseValidationTests.cs index 9a0b601..a22e394 100644 --- a/src/Standard.Licensing.Tests/LicenseValidationTests.cs +++ b/src/Standard.Licensing.Tests/LicenseValidationTests.cs @@ -22,14 +22,11 @@ // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + using NUnit.Framework; + +using Standard.Licensing.Security.Cryptography; using Standard.Licensing.Validation; namespace Standard.Licensing.Tests @@ -40,9 +37,8 @@ public class LicenseValidationTests [Test] public void Can_Validate_Valid_Signature() { - var publicKey = - @"MIIBKjCB4wYHKoZIzj0CATCB1wIBATAsBgcqhkjOPQEBAiEA/////wAAAAEAAAAAAAAAAAAAAAD///////////////8wWwQg/////wAAAAEAAAAAAAAAAAAAAAD///////////////wEIFrGNdiqOpPns+u9VXaYhrxlHQawzFOw9jvOPD4n0mBLAxUAxJ02CIbnBJNqZnjhE50mt4GffpAEIQNrF9Hy4SxCR/i85uVjpEDydwN9gS3rM6D0oTlF2JjClgIhAP////8AAAAA//////////+85vqtpxeehPO5ysL8YyVRAgEBA0IABNVLQ1xKY80BFMgGXec++Vw7n8vvNrq32PaHuBiYMm0PEj2JoB7qSSWhfgcjxNVJsxqJ6gDQVWgl0r7LH4dr0KU="; - var licenseData = @" + const string? publicKey = "MIIBKjCB4wYHKoZIzj0CATCB1wIBATAsBgcqhkjOPQEBAiEA/////wAAAAEAAAAAAAAAAAAAAAD///////////////8wWwQg/////wAAAAEAAAAAAAAAAAAAAAD///////////////wEIFrGNdiqOpPns+u9VXaYhrxlHQawzFOw9jvOPD4n0mBLAxUAxJ02CIbnBJNqZnjhE50mt4GffpAEIQNrF9Hy4SxCR/i85uVjpEDydwN9gS3rM6D0oTlF2JjClgIhAP////8AAAAA//////////+85vqtpxeehPO5ysL8YyVRAgEBA0IABNVLQ1xKY80BFMgGXec++Vw7n8vvNrq32PaHuBiYMm0PEj2JoB7qSSWhfgcjxNVJsxqJ6gDQVWgl0r7LH4dr0KU="; + const string? licenseData = @" 77d4c193-6088-4c64-9663-ed7398ae8c1a Trial Sun, 31 Dec 1899 23:00:00 GMT @@ -56,23 +52,23 @@ public void Can_Validate_Valid_Signature() MEUCIQCCEDAldOZHHIKvYZRDdzUP4V51y23d6deeK5jIFy27GQIgDz2CndjBh4Vb8tiC3FGQ6fn3GKt8d/P5+luJH0cWv+I= "; - var license = License.Load(licenseData); + License? license = License.Load(licenseData); - var validationResults = license - .Validate() - .Signature(publicKey) - .AssertValidLicense(); + IEnumerable? validationResults = license + .Validate() + .Signature(publicKey) + .AssertValidLicense(); - Assert.That(validationResults, Is.Not.Null); - Assert.That(validationResults.Count(), Is.EqualTo(0)); + IEnumerable validationFailures = validationResults.ToList(); + Assert.That(validationFailures, Is.Not.Null); + Assert.That(validationFailures.Count(), Is.EqualTo(0)); } [Test] public void Can_Validate_Invalid_Signature() { - var publicKey = - @"MIIBKjCB4wYHKoZIzj0CATCB1wIBATAsBgcqhkjOPQEBAiEA/////wAAAAEAAAAAAAAAAAAAAAD///////////////8wWwQg/////wAAAAEAAAAAAAAAAAAAAAD///////////////wEIFrGNdiqOpPns+u9VXaYhrxlHQawzFOw9jvOPD4n0mBLAxUAxJ02CIbnBJNqZnjhE50mt4GffpAEIQNrF9Hy4SxCR/i85uVjpEDydwN9gS3rM6D0oTlF2JjClgIhAP////8AAAAA//////////+85vqtpxeehPO5ysL8YyVRAgEBA0IABNVLQ1xKY80BFMgGXec++Vw7n8vvNrq32PaHuBiYMm0PEj2JoB7qSSWhfgcjxNVJsxqJ6gDQVWgl0r7LH4dr0KU="; - var licenseData = @" + const string publicKey = "MIIBKjCB4wYHKoZIzj0CATCB1wIBATAsBgcqhkjOPQEBAiEA/////wAAAAEAAAAAAAAAAAAAAAD///////////////8wWwQg/////wAAAAEAAAAAAAAAAAAAAAD///////////////wEIFrGNdiqOpPns+u9VXaYhrxlHQawzFOw9jvOPD4n0mBLAxUAxJ02CIbnBJNqZnjhE50mt4GffpAEIQNrF9Hy4SxCR/i85uVjpEDydwN9gS3rM6D0oTlF2JjClgIhAP////8AAAAA//////////+85vqtpxeehPO5ysL8YyVRAgEBA0IABNVLQ1xKY80BFMgGXec++Vw7n8vvNrq32PaHuBiYMm0PEj2JoB7qSSWhfgcjxNVJsxqJ6gDQVWgl0r7LH4dr0KU="; + const string licenseData = @" 77d4c193-6088-4c64-9663-ed7398ae8c1a Trial Sun, 31 Dec 1899 23:00:00 GMT @@ -86,12 +82,12 @@ public void Can_Validate_Invalid_Signature() MEUCIQCCEDAldOZHHIKvYZRDdzUP4V51y23d6deeK5jIFy27GQIgDz2CndjBh4Vb8tiC3FGQ6fn3GKt8d/P5+luJH0cWv+I= "; - var license = License.Load(licenseData); + License? license = License.Load(licenseData); - var validationResults = license - .Validate() - .Signature(publicKey) - .AssertValidLicense().ToList(); + List validationResults = license + .Validate() + .Signature(publicKey) + .AssertValidLicense().ToList(); Assert.That(validationResults, Is.Not.Null); Assert.That(validationResults.Count(), Is.EqualTo(1)); @@ -101,8 +97,7 @@ public void Can_Validate_Invalid_Signature() [Test] public void Can_Validate_Expired_ExpirationDate() { - var publicKey = ""; - var licenseData = @" + const string licenseData = @" 77d4c193-6088-4c64-9663-ed7398ae8c1a Trial Sun, 31 Dec 1899 23:00:00 GMT @@ -116,12 +111,12 @@ public void Can_Validate_Expired_ExpirationDate() MEUCIQCCEDAldOZHHIKvYZRDdzUP4V51y23d6deeK5jIFy27GQIgDz2CndjBh4Vb8tiC3FGQ6fn3GKt8d/P5+luJH0cWv+I= "; - var license = License.Load(licenseData); + License? license = License.Load(licenseData); - var validationResults = license - .Validate() - .ExpirationDate() - .AssertValidLicense().ToList(); + List validationResults = license + .Validate() + .ExpirationDate() + .AssertValidLicense().ToList(); Assert.That(validationResults, Is.Not.Null); Assert.That(validationResults.Count(), Is.EqualTo(1)); @@ -132,8 +127,7 @@ public void Can_Validate_Expired_ExpirationDate() [Test] public void Can_Validate_Expired_ExpirationDate_CustomDateTime() { - var publicKey = ""; - var licenseData = @" + const string licenseData = @" 77d4c193-6088-4c64-9663-ed7398ae8c1a Trial Sun, 31 Dec 1899 23:00:00 GMT @@ -147,12 +141,12 @@ public void Can_Validate_Expired_ExpirationDate_CustomDateTime() MEUCIQCCEDAldOZHHIKvYZRDdzUP4V51y23d6deeK5jIFy27GQIgDz2CndjBh4Vb8tiC3FGQ6fn3GKt8d/P5+luJH0cWv+I= "; - var license = License.Load(licenseData); + License? license = License.Load(licenseData); - var validationResults = license - .Validate() - .ExpirationDate(systemDateTime: new DateTime(1900, 1, 2, 0, 0, 0, DateTimeKind.Utc)) - .AssertValidLicense().ToList(); + List validationResults = license + .Validate() + .ExpirationDate(systemDateTime: new DateTime(1900, 1, 2, 0, 0, 0, DateTimeKind.Utc)) + .AssertValidLicense().ToList(); Assert.That(validationResults, Is.Not.Null); Assert.That(validationResults.Count(), Is.EqualTo(1)); @@ -163,8 +157,8 @@ public void Can_Validate_Expired_ExpirationDate_CustomDateTime() [Test] public void Can_Validate_CustomAssertion() { - var publicKey = @"MIIBKjCB4wYHKoZIzj0CATCB1wIBATAsBgcqhkjOPQEBAiEA/////wAAAAEAAAAAAAAAAAAAAAD///////////////8wWwQg/////wAAAAEAAAAAAAAAAAAAAAD///////////////wEIFrGNdiqOpPns+u9VXaYhrxlHQawzFOw9jvOPD4n0mBLAxUAxJ02CIbnBJNqZnjhE50mt4GffpAEIQNrF9Hy4SxCR/i85uVjpEDydwN9gS3rM6D0oTlF2JjClgIhAP////8AAAAA//////////+85vqtpxeehPO5ysL8YyVRAgEBA0IABNVLQ1xKY80BFMgGXec++Vw7n8vvNrq32PaHuBiYMm0PEj2JoB7qSSWhfgcjxNVJsxqJ6gDQVWgl0r7LH4dr0KU="; - var licenseData = @" + string publicKey = "MIIBKjCB4wYHKoZIzj0CATCB1wIBATAsBgcqhkjOPQEBAiEA/////wAAAAEAAAAAAAAAAAAAAAD///////////////8wWwQg/////wAAAAEAAAAAAAAAAAAAAAD///////////////wEIFrGNdiqOpPns+u9VXaYhrxlHQawzFOw9jvOPD4n0mBLAxUAxJ02CIbnBJNqZnjhE50mt4GffpAEIQNrF9Hy4SxCR/i85uVjpEDydwN9gS3rM6D0oTlF2JjClgIhAP////8AAAAA//////////+85vqtpxeehPO5ysL8YyVRAgEBA0IABNVLQ1xKY80BFMgGXec++Vw7n8vvNrq32PaHuBiYMm0PEj2JoB7qSSWhfgcjxNVJsxqJ6gDQVWgl0r7LH4dr0KU="; + string licenseData = @" 77d4c193-6088-4c64-9663-ed7398ae8c1a Trial Thu, 31 Dec 2009 23:00:00 GMT @@ -184,18 +178,18 @@ public void Can_Validate_CustomAssertion() MEUCIQCa6A7Cts5ex4rGHAPxiXpy+2ocZzTDSP7SsddopKUx5QIgHnqv0DjoOpc+K9wALqajxxvmLCRJAywCX5vDAjmWqr8= "; - var license = License.Load(licenseData); + License? license = License.Load(licenseData); - var validationResults = license - .Validate() - .AssertThat(lic => lic.ProductFeatures.Contains("Sales Module"), - new GeneralValidationFailure {Message = "Sales Module not licensed!"}) - .And() - .AssertThat(lic => lic.AdditionalAttributes.Get("Assembly Signature") == "123456789", - new GeneralValidationFailure {Message = "Assembly Signature does not match!"}) - .And() - .Signature(publicKey) - .AssertValidLicense().ToList(); + List validationResults = license + .Validate() + .AssertThat(lic => lic.ProductFeatures.Contains("Sales Module"), + new GeneralValidationFailure {Message = "Sales Module not licensed!"}) + .And() + .AssertThat(lic => lic.AdditionalAttributes.Get("Assembly Signature") == "123456789", + new GeneralValidationFailure {Message = "Assembly Signature does not match!"}) + .And() + .Signature(publicKey) + .AssertValidLicense().ToList(); Assert.That(validationResults, Is.Not.Null); Assert.That(validationResults.Count(), Is.EqualTo(0)); @@ -204,18 +198,17 @@ public void Can_Validate_CustomAssertion() [Test] public void Do_Not_Crash_On_Invalid_Data() { - var publicKey = "1234"; - var licenseData = - @"John Doe"; + const string publicKey = "1234"; + const string licenseData = "John Doe"; - var license = License.Load(licenseData); + License? license = License.Load(licenseData); - var validationResults = license - .Validate() - .ExpirationDate() - .And() - .Signature(publicKey) - .AssertValidLicense().ToList(); + List validationResults = license + .Validate() + .ExpirationDate() + .And() + .Signature(publicKey) + .AssertValidLicense().ToList(); Assert.That(validationResults, Is.Not.Null); Assert.That(validationResults.Count(), Is.EqualTo(1)); @@ -226,28 +219,31 @@ public void Do_Not_Crash_On_Invalid_Data() [Test] public void Test_ValidationChainBuilder_ValidationFailure_List() { - var keyGenerator = Standard.Licensing.Security.Cryptography.KeyGenerator.Create(); - var keyPair = keyGenerator.GenerateKeyPair(); - var publicKey = keyPair.ToPublicKeyString(); + KeyGenerator? keyGenerator = KeyGenerator.Create(); + KeyPair? keyPair = keyGenerator.GenerateKeyPair(); + string? publicKey = keyPair.ToPublicKeyString(); - var invalidLicense = @" + const string invalidLicense = @" WFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFg= "; - var licenseToVerify = License.Load(invalidLicense); + License? licenseToVerify = License.Load(invalidLicense); - var validationFailures = licenseToVerify - .Validate() - .Signature(publicKey) - .AssertValidLicense(); + IEnumerable? validationFailures = licenseToVerify + .Validate() + .Signature(publicKey) + .AssertValidLicense(); - var count = 0; - foreach (var v in validationFailures) - count++; + int count = 0; + IEnumerable enumerable = validationFailures.ToList(); + foreach (IValidationFailure? v in enumerable) + { + count++; + } Assert.That(count, Is.EqualTo(1)); - Assert.That(validationFailures.ToArray().Length, Is.EqualTo(1)); - Assert.That(validationFailures.ToArray().Length, Is.EqualTo(1)); + Assert.That(enumerable.ToArray().Length, Is.EqualTo(1)); + Assert.That(enumerable.ToArray().Length, Is.EqualTo(1)); } } } \ No newline at end of file diff --git a/src/Standard.Licensing/AssemblyBuildDateAttribute.cs b/src/Standard.Licensing/AssemblyBuildDateAttribute.cs index 09b8858..2ce0d5c 100644 --- a/src/Standard.Licensing/AssemblyBuildDateAttribute.cs +++ b/src/Standard.Licensing/AssemblyBuildDateAttribute.cs @@ -31,11 +31,9 @@ namespace Standard.Licensing /// /// Defines assembly build date information for an assembly manifest. /// - [AttributeUsage(AttributeTargets.Assembly, Inherited = false)] + [AttributeUsage(AttributeTargets.Assembly)] public sealed class AssemblyBuildDateAttribute : Attribute { - private readonly DateTime buildDate; - /// /// Initializes a new instance of the class /// with the specified build date. @@ -43,7 +41,7 @@ public sealed class AssemblyBuildDateAttribute : Attribute /// The build date of the assembly. public AssemblyBuildDateAttribute(DateTime buildDate) { - this.buildDate = buildDate; + BuildDate = buildDate; } /// @@ -53,15 +51,12 @@ public AssemblyBuildDateAttribute(DateTime buildDate) /// The build date of the assembly. public AssemblyBuildDateAttribute(string buildDateString) { - buildDate = DateTime.Parse(buildDateString, CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal); + BuildDate = DateTime.Parse(buildDateString, CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal); } /// /// Gets the assembly build date. /// - public DateTime BuildDate - { - get { return buildDate; } - } + public DateTime BuildDate { get; } } } \ No newline at end of file diff --git a/src/Standard.Licensing/Customer.cs b/src/Standard.Licensing/Customer.cs index 67c00bb..7c00f39 100644 --- a/src/Standard.Licensing/Customer.cs +++ b/src/Standard.Licensing/Customer.cs @@ -42,17 +42,17 @@ internal Customer(XElement xmlData) /// public string Name { - get { return GetTag("Name"); } - set { SetTag("Name", value); } + get => GetTag("Name"); + set => SetTag("Name", value); } - + /// /// Gets or sets the Company of this . /// public string Company { - get { return GetTag("Company"); } - set { SetTag("Company", value); } + get => GetTag("Company"); + set => SetTag("Company", value); } /// @@ -60,8 +60,8 @@ public string Company /// public string Email { - get { return GetTag("Email"); } - set { SetTag("Email", value); } + get => GetTag("Email"); + set => SetTag("Email", value); } } } \ No newline at end of file diff --git a/src/Standard.Licensing/License.cs b/src/Standard.Licensing/License.cs index 397e10e..eb73346 100644 --- a/src/Standard.Licensing/License.cs +++ b/src/Standard.Licensing/License.cs @@ -30,6 +30,7 @@ using System.Xml; using System.Xml.Linq; using Org.BouncyCastle.Asn1.X9; +using Org.BouncyCastle.Crypto; using Org.BouncyCastle.Security; using Standard.Licensing.Security.Cryptography; @@ -67,8 +68,12 @@ internal License(XElement xmlData) /// public Guid Id { - get { return new Guid(GetTag("Id") ?? Guid.Empty.ToString()); } - set { if (!IsSigned) SetTag("Id", value.ToString()); } + get => new Guid(GetTag("Id") ?? Guid.Empty.ToString()); + set { if (!IsSigned) + { + SetTag("Id", value.ToString()); + } + } } /// @@ -76,13 +81,14 @@ public Guid Id /// public LicenseType Type { - get - { - return - (LicenseType) - Enum.Parse(typeof (LicenseType), GetTag("Type") ?? LicenseType.Trial.ToString(), false); + get => + (LicenseType) + Enum.Parse(typeof(LicenseType), GetTag("Type") ?? LicenseType.Trial.ToString(), false); + set { if (!IsSigned) + { + SetTag("Type", value.ToString()); + } } - set { if (!IsSigned) SetTag("Type", value.ToString()); } } /// @@ -91,8 +97,12 @@ public LicenseType Type /// public int Quantity { - get { return int.Parse(GetTag("Quantity") ?? "0"); } - set { if (!IsSigned) SetTag("Quantity", value.ToString()); } + get => int.Parse(GetTag("Quantity") ?? "0"); + set { if (!IsSigned) + { + SetTag("Quantity", value.ToString()); + } + } } /// @@ -102,7 +112,7 @@ public LicenseAttributes ProductFeatures { get { - var xmlElement = xmlData.Element("ProductFeatures"); + XElement xmlElement = xmlData.Element("ProductFeatures"); if (!IsSigned && xmlElement == null) { @@ -125,7 +135,7 @@ public Customer Customer { get { - var xmlElement = xmlData.Element("Customer"); + XElement xmlElement = xmlData.Element("Customer"); if (!IsSigned && xmlElement == null) { @@ -148,7 +158,7 @@ public LicenseAttributes AdditionalAttributes { get { - var xmlElement = xmlData.Element("LicenseAttributes"); + XElement xmlElement = xmlData.Element("LicenseAttributes"); if (!IsSigned && xmlElement == null) { @@ -171,25 +181,25 @@ public LicenseAttributes AdditionalAttributes /// public DateTime Expiration { - get - { - return - DateTime.ParseExact( - GetTag("Expiration") ?? - DateTime.MaxValue.ToUniversalTime().ToString("r", CultureInfo.InvariantCulture) - , "r", CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal); + get => + DateTime.ParseExact( + GetTag("Expiration") ?? + DateTime.MaxValue.ToUniversalTime().ToString("r", CultureInfo.InvariantCulture), + "r", + CultureInfo.InvariantCulture, + DateTimeStyles.AssumeUniversal); + set { if (!IsSigned) + { + SetTag("Expiration", value.ToUniversalTime().ToString("r", CultureInfo.InvariantCulture)); + } } - set { if (!IsSigned) SetTag("Expiration", value.ToUniversalTime().ToString("r", CultureInfo.InvariantCulture)); } } /// /// Gets the digital signature of this license. /// /// Use the method to compute a signature. - public string Signature - { - get { return GetTag("Signature"); } - } + public string Signature => GetTag("Signature"); /// /// Compute a signature and sign this with the provided key. @@ -198,20 +208,22 @@ public string Signature /// The pass phrase to decrypt the private key. public void Sign(string privateKey, string passPhrase) { - var signTag = xmlData.Element("Signature") ?? new XElement("Signature"); + XElement signTag = xmlData.Element("Signature") ?? new XElement("Signature"); try { if (signTag.Parent != null) + { signTag.Remove(); + } - var privKey = KeyFactory.FromEncryptedPrivateKeyString(privateKey, passPhrase); + AsymmetricKeyParameter privKey = KeyFactory.FromEncryptedPrivateKeyString(privateKey, passPhrase); - var documentToSign = Encoding.UTF8.GetBytes(xmlData.ToString(SaveOptions.DisableFormatting)); - var signer = SignerUtilities.GetSigner(signatureAlgorithm); + byte[] documentToSign = Encoding.UTF8.GetBytes(xmlData.ToString(SaveOptions.DisableFormatting)); + ISigner signer = SignerUtilities.GetSigner(signatureAlgorithm); signer.Init(true, privKey); signer.BlockUpdate(documentToSign, 0, documentToSign.Length); - var signature = signer.GenerateSignature(); + byte[] signature = signer.GenerateSignature(); signTag.Value = Convert.ToBase64String(signature); } finally @@ -227,19 +239,21 @@ public void Sign(string privateKey, string passPhrase) /// true if the verifies; otherwise false. public bool VerifySignature(string publicKey) { - var signTag = xmlData.Element("Signature"); + XElement signTag = xmlData.Element("Signature"); if (signTag == null) + { return false; + } try { signTag.Remove(); - var pubKey = KeyFactory.FromPublicKeyString(publicKey); + AsymmetricKeyParameter pubKey = KeyFactory.FromPublicKeyString(publicKey); - var documentToSign = Encoding.UTF8.GetBytes(xmlData.ToString(SaveOptions.DisableFormatting)); - var signer = SignerUtilities.GetSigner(signatureAlgorithm); + byte[] documentToSign = Encoding.UTF8.GetBytes(xmlData.ToString(SaveOptions.DisableFormatting)); + ISigner signer = SignerUtilities.GetSigner(signatureAlgorithm); signer.Init(false, pubKey); signer.BlockUpdate(documentToSign, 0, documentToSign.Length); @@ -346,14 +360,11 @@ public override string ToString() /// /// Gets a value indicating whether this is already signed. /// - private bool IsSigned - { - get { return (!string.IsNullOrEmpty(Signature)); } - } + private bool IsSigned => !string.IsNullOrEmpty(Signature); private void SetTag(string name, string value) { - var element = xmlData.Element(name); + XElement element = xmlData.Element(name); if (element == null) { @@ -362,13 +373,15 @@ private void SetTag(string name, string value) } if (value != null) + { element.Value = value; + } } private string GetTag(string name) { - var element = xmlData.Element(name); - return element != null ? element.Value : null; + XElement element = xmlData.Element(name); + return element?.Value; } } } \ No newline at end of file diff --git a/src/Standard.Licensing/LicenseAttributes.cs b/src/Standard.Licensing/LicenseAttributes.cs index 7d72456..309310f 100644 --- a/src/Standard.Licensing/LicenseAttributes.cs +++ b/src/Standard.Licensing/LicenseAttributes.cs @@ -34,16 +34,16 @@ namespace Standard.Licensing /// public class LicenseAttributes { - protected readonly XElement xmlData; - protected readonly XName childName; + protected readonly XElement XmlData; + protected readonly XName ChildName; /// /// Initializes a new instance of the class. /// internal LicenseAttributes(XElement xmlData, XName childName) { - this.xmlData = xmlData ?? new XElement("null"); - this.childName = childName; + XmlData = xmlData ?? new XElement("null"); + ChildName = childName; } /// @@ -63,8 +63,10 @@ public virtual void Add(string key, string value) /// The dictionary of elements. public virtual void AddAll(IDictionary features) { - foreach (var feature in features) + foreach (KeyValuePair feature in features) + { Add(feature.Key, feature.Value); + } } /// @@ -74,12 +76,14 @@ public virtual void AddAll(IDictionary features) /// The key of the element. public virtual void Remove(string key) { - var element = - xmlData.Elements(childName) - .FirstOrDefault(e => e.Attribute("name") != null && e.Attribute("name").Value == key); + XElement element = + XmlData.Elements(ChildName) + .FirstOrDefault(e => e.Attribute("name") != null && e.Attribute("name")?.Value == key); if (element != null) + { element.Remove(); + } } /// @@ -87,7 +91,7 @@ public virtual void Remove(string key) /// public virtual void RemoveAll() { - xmlData.RemoveAll(); + XmlData.RemoveAll(); } /// @@ -107,7 +111,7 @@ public virtual string Get(string key) /// A dictionary of all elements in this collection. public virtual IDictionary GetAll() { - return xmlData.Elements(childName).ToDictionary(e => e.Attribute("name").Value, e => e.Value); + return XmlData.Elements(ChildName).ToDictionary(e => e.Attribute("name")?.Value, e => e.Value); } /// @@ -118,7 +122,7 @@ public virtual IDictionary GetAll() /// true if the collection contains this element; otherwise false. public virtual bool Contains(string key) { - return xmlData.Elements(childName).Any(e => e.Attribute("name") != null && e.Attribute("name").Value == key); + return XmlData.Elements(ChildName).Any(e => e.Attribute("name") != null && e.Attribute("name")?.Value == key); } /// @@ -129,53 +133,57 @@ public virtual bool Contains(string key) /// true if the collection contains all specified elements; otherwise false. public virtual bool ContainsAll(string[] keys) { - return xmlData.Elements(childName).All(e => e.Attribute("name") != null && keys.Contains(e.Attribute("name").Value)); + return XmlData.Elements(ChildName).All(e => e.Attribute("name") != null && keys.Contains(e.Attribute("name")?.Value)); } protected virtual void SetTag(string name, string value) { - var element = xmlData.Element(name); + XElement element = XmlData.Element(name); if (element == null) { element = new XElement(name); - xmlData.Add(element); + XmlData.Add(element); } if (value != null) + { element.Value = value; + } } protected virtual void SetChildTag(string name, string value) { - var element = - xmlData.Elements(childName) - .FirstOrDefault(e => e.Attribute("name") != null && e.Attribute("name").Value == name); + XElement element = + XmlData.Elements(ChildName) + .FirstOrDefault(e => e.Attribute("name") != null && e.Attribute("name")?.Value == name); if (element == null) { - element = new XElement(childName); + element = new XElement(ChildName); element.Add(new XAttribute("name", name)); - xmlData.Add(element); + XmlData.Add(element); } if (value != null) + { element.Value = value; + } } protected virtual string GetTag(string name) { - var element = xmlData.Element(name); - return element != null ? element.Value : null; + XElement element = XmlData.Element(name); + return element?.Value; } protected virtual string GetChildTag(string name) { - var element = - xmlData.Elements(childName) - .FirstOrDefault(e => e.Attribute("name") != null && e.Attribute("name").Value == name); + XElement element = + XmlData.Elements(ChildName) + .FirstOrDefault(e => e.Attribute("name") != null && e.Attribute("name")?.Value == name); - return element != null ? element.Value : null; + return element?.Value; } } } \ No newline at end of file diff --git a/src/Standard.Licensing/Properties/AssemblyInfo.cs b/src/Standard.Licensing/Properties/AssemblyInfo.cs index f1a14bb..3e481cb 100644 --- a/src/Standard.Licensing/Properties/AssemblyInfo.cs +++ b/src/Standard.Licensing/Properties/AssemblyInfo.cs @@ -1,22 +1,20 @@ -using System; -using System.Reflection; +using System.Reflection; //using System.Security.Permissions; #if PORTABLE using System.Linq; #else -using System.Runtime.InteropServices; #endif internal class AssemblyInfo { - private static string version = null; + private static string _version = null; public static string Version { get { - if (version == null) + if (_version == null) { #if PORTABLE #if NEW_REFLECTION @@ -32,17 +30,17 @@ public static string Version version = v.Version; } #else - version = Assembly.GetExecutingAssembly().GetName().Version.ToString(); + _version = Assembly.GetExecutingAssembly().GetName().Version.ToString(); #endif // if we're still here, then don't try again - if (version == null) + if (_version == null) { - version = string.Empty; + _version = string.Empty; } } - return version; + return _version; } } } diff --git a/src/Standard.Licensing/Security/Cryptography/KeyFactory.cs b/src/Standard.Licensing/Security/Cryptography/KeyFactory.cs index f4f01b7..8eef280 100644 --- a/src/Standard.Licensing/Security/Cryptography/KeyFactory.cs +++ b/src/Standard.Licensing/Security/Cryptography/KeyFactory.cs @@ -33,7 +33,7 @@ namespace Standard.Licensing.Security.Cryptography { internal static class KeyFactory { - private static readonly string keyEncryptionAlgorithm = PkcsObjectIdentifiers.PbeWithShaAnd3KeyTripleDesCbc.Id; + private static readonly string _keyEncryptionAlgorithm = PkcsObjectIdentifiers.PbeWithShaAnd3KeyTripleDesCbc.Id; /// /// Encrypts and encodes the private key. @@ -43,13 +43,13 @@ internal static class KeyFactory /// The encrypted private key. public static string ToEncryptedPrivateKeyString(AsymmetricKeyParameter key, string passPhrase) { - var salt = new byte[16]; - var secureRandom = SecureRandom.GetInstance("SHA256PRNG"); + byte[] salt = new byte[16]; + SecureRandom secureRandom = SecureRandom.GetInstance("SHA256PRNG"); secureRandom.SetSeed(secureRandom.GenerateSeed(16)); //See Bug #135 secureRandom.NextBytes(salt); return - Convert.ToBase64String(PrivateKeyFactory.EncryptKey(keyEncryptionAlgorithm, passPhrase.ToCharArray(), + Convert.ToBase64String(PrivateKeyFactory.EncryptKey(_keyEncryptionAlgorithm, passPhrase.ToCharArray(), salt, 10, key)); } diff --git a/src/Standard.Licensing/Security/Cryptography/KeyGenerator.cs b/src/Standard.Licensing/Security/Cryptography/KeyGenerator.cs index 0f8759e..632a264 100644 --- a/src/Standard.Licensing/Security/Cryptography/KeyGenerator.cs +++ b/src/Standard.Licensing/Security/Cryptography/KeyGenerator.cs @@ -77,10 +77,10 @@ public KeyGenerator(int keySize) /// The seed. public KeyGenerator(int keySize, byte[] seed) { - var secureRandom = SecureRandom.GetInstance("SHA256PRNG"); + SecureRandom secureRandom = SecureRandom.GetInstance("SHA256PRNG"); secureRandom.SetSeed(seed); - var keyParams = new KeyGenerationParameters(secureRandom, keySize); + KeyGenerationParameters keyParams = new KeyGenerationParameters(secureRandom, keySize); keyGenerator = new ECKeyPairGenerator(); keyGenerator.Init(keyParams); } diff --git a/src/Standard.Licensing/Validation/LicenseValidationExtensions.cs b/src/Standard.Licensing/Validation/LicenseValidationExtensions.cs index f65cdbe..a4dc7ba 100644 --- a/src/Standard.Licensing/Validation/LicenseValidationExtensions.cs +++ b/src/Standard.Licensing/Validation/LicenseValidationExtensions.cs @@ -64,15 +64,19 @@ public static IValidationChain ExpirationDate(this IStartValidationChain validat /// An instance of . public static IValidationChain ExpirationDate(this IStartValidationChain validationChain, DateTime systemDateTime) { - var validationChainBuilder = (validationChain as ValidationChainBuilder); - var validator = validationChainBuilder.StartValidatorChain(); - validator.Validate = license => license.Expiration > systemDateTime; + ValidationChainBuilder validationChainBuilder = validationChain as ValidationChainBuilder; - validator.FailureResult = new LicenseExpiredValidationFailure() + if (validationChainBuilder != null) { - Message = "Licensing for this product has expired!", - HowToResolve = @"Your license is expired. Please contact your distributor/vendor to renew the license." - }; + ILicenseValidator validator = validationChainBuilder.StartValidatorChain(); + validator.Validate = license => license.Expiration > systemDateTime; + + validator.FailureResult = new LicenseExpiredValidationFailure + { + Message = "Licensing for this product has expired!", + HowToResolve = "Your license is expired. Please contact your distributor/vendor to renew the license." + }; + } return validationChainBuilder; } @@ -86,18 +90,21 @@ public static IValidationChain ExpirationDate(this IStartValidationChain validat /// An instance of . public static IValidationChain ProductBuildDate(this IStartValidationChain validationChain, Assembly[] assemblies) { - var validationChainBuilder = (validationChain as ValidationChainBuilder); - var validator = validationChainBuilder.StartValidatorChain(); + ValidationChainBuilder validationChainBuilder = validationChain as ValidationChainBuilder; -#if !NEW_REFLECTION + if (validationChainBuilder != null) + { + ILicenseValidator validator = validationChainBuilder.StartValidatorChain(); - validator.Validate = license => assemblies.All( - asm => - asm.GetCustomAttributes(typeof (AssemblyBuildDateAttribute), false) - .Cast() - .All(a => a.BuildDate < license.Expiration)); + #if !NEW_REFLECTION + + validator.Validate = license => assemblies.All( + asm => + asm.GetCustomAttributes(typeof (AssemblyBuildDateAttribute), false) + .Cast() + .All(a => a.BuildDate < license.Expiration)); -#else + #else validator.Validate = license => assemblies.All( asm => @@ -105,13 +112,14 @@ public static IValidationChain ProductBuildDate(this IStartValidationChain valid .Cast() .All(a => a.BuildDate < license.Expiration)); -#endif + #endif - validator.FailureResult = new LicenseExpiredValidationFailure() - { - Message = "Licensing for this product has expired!", - HowToResolve = @"Your license is expired. Please contact your distributor/vendor to renew the license." - }; + validator.FailureResult = new LicenseExpiredValidationFailure + { + Message = "Licensing for this product has expired!", + HowToResolve = "Your license is expired. Please contact your distributor/vendor to renew the license." + }; + } return validationChainBuilder; } @@ -125,11 +133,15 @@ public static IValidationChain ProductBuildDate(this IStartValidationChain valid /// An instance of . public static IValidationChain AssertThat(this IStartValidationChain validationChain, Predicate predicate, IValidationFailure failure) { - var validationChainBuilder = (validationChain as ValidationChainBuilder); - var validator = validationChainBuilder.StartValidatorChain(); + ValidationChainBuilder validationChainBuilder = validationChain as ValidationChainBuilder; + + if (validationChainBuilder != null) + { + ILicenseValidator validator = validationChainBuilder.StartValidatorChain(); - validator.Validate = predicate; - validator.FailureResult = failure; + validator.Validate = predicate; + validator.FailureResult = failure; + } return validationChainBuilder; } @@ -142,15 +154,19 @@ public static IValidationChain AssertThat(this IStartValidationChain validationC /// An instance of . public static IValidationChain Signature(this IStartValidationChain validationChain, string publicKey) { - var validationChainBuilder = (validationChain as ValidationChainBuilder); - var validator = validationChainBuilder.StartValidatorChain(); - validator.Validate = license => license.VerifySignature(publicKey); + ValidationChainBuilder validationChainBuilder = validationChain as ValidationChainBuilder; - validator.FailureResult = new InvalidSignatureValidationFailure() + if (validationChainBuilder != null) { - Message = "License signature validation error!", - HowToResolve = @"The license signature and data does not match. This usually happens when a license file is corrupted or has been altered." - }; + ILicenseValidator validator = validationChainBuilder.StartValidatorChain(); + validator.Validate = license => license.VerifySignature(publicKey); + + validator.FailureResult = new InvalidSignatureValidationFailure + { + Message = "License signature validation error!", + HowToResolve = "The license signature and data does not match. This usually happens when a license file is corrupted or has been altered." + }; + } return validationChainBuilder; } diff --git a/src/Standard.Licensing/Validation/ValidationChainBuilder.cs b/src/Standard.Licensing/Validation/ValidationChainBuilder.cs index b87c30a..af03511 100644 --- a/src/Standard.Licensing/Validation/ValidationChainBuilder.cs +++ b/src/Standard.Licensing/Validation/ValidationChainBuilder.cs @@ -25,6 +25,7 @@ using System; using System.Collections.Generic; +using System.Linq; namespace Standard.Licensing.Validation { @@ -48,7 +49,9 @@ public ILicenseValidator StartValidatorChain() public void CompleteValidatorChain() { if (currentValidatorChain == null) + { return; + } validators.Add(currentValidatorChain); currentValidatorChain = null; @@ -70,17 +73,13 @@ public IEnumerable AssertValidLicense() { CompleteValidatorChain(); - foreach (var validator in validators) + foreach (ILicenseValidator validator in validators.Where(validator => validator.ValidateWhen == null || validator.ValidateWhen(license)).Where(validator => !validator.Validate(license))) { - if (validator.ValidateWhen != null && !validator.ValidateWhen(license)) - continue; - - if (!validator.Validate(license)) - yield return validator.FailureResult - ?? new GeneralValidationFailure - { - Message = "License validation failed!" - }; + yield return validator.FailureResult + ?? new GeneralValidationFailure + { + Message = "License validation failed!" + }; } } }