using App.Core.Services.Licensing; using Org.BouncyCastle.Crypto.Generators; using Org.BouncyCastle.Crypto.Parameters; using Org.BouncyCastle.Crypto.Signers; using Org.BouncyCastle.Security; namespace App.Core.Tests.Licensing; public class LicenseValidatorTests { /// /// Génère une paire de clés de TEST (jamais la clé de production) et signe une licence /// avec, exactement comme le fait LicenseGenerator. Permet de tester LicenseValidator sans /// dépendre de la clé publique embarquée dans Ed25519PublicKeyProvider. /// private static (byte[] PublicKey, LicenseFile SignedLicense) CreateSignedLicense( string companyName = "ACME Industries", string motherboardUuid = "MB-1234", string diskSerial = "DISK-5678", int maxUsers = 5, int maxMachines = 50) { var generator = new Ed25519KeyPairGenerator(); generator.Init(new Ed25519KeyGenerationParameters(new SecureRandom())); var keyPair = generator.GenerateKeyPair(); var privateKey = (Ed25519PrivateKeyParameters)keyPair.Private; var publicKey = (Ed25519PublicKeyParameters)keyPair.Public; var unsigned = new LicenseFile( companyName, motherboardUuid, diskSerial, new DateOnly(2026, 1, 1), null, maxUsers, maxMachines, Signature: string.Empty); var canonicalBytes = LicenseFileCanonicalSerializer.GetCanonicalBytes(unsigned); var signer = new Ed25519Signer(); signer.Init(forSigning: true, privateKey); signer.BlockUpdate(canonicalBytes, 0, canonicalBytes.Length); var signature = Convert.ToBase64String(signer.GenerateSignature()); return (publicKey.GetEncoded(), unsigned with { Signature = signature }); } [Fact] public void VerifySignature_ValidLicense_ReturnsTrue() { var (publicKey, license) = CreateSignedLicense(); Assert.True(LicenseValidator.VerifySignature(license, publicKey)); } [Fact] public void VerifySignature_TamperedField_ReturnsFalse() { var (publicKey, license) = CreateSignedLicense(); var tampered = license with { MaxUsers = 9999 }; Assert.False(LicenseValidator.VerifySignature(tampered, publicKey)); } [Fact] public void VerifySignature_WrongPublicKey_ReturnsFalse() { var (_, license) = CreateSignedLicense(); var (otherPublicKey, _) = CreateSignedLicense(); Assert.False(LicenseValidator.VerifySignature(license, otherPublicKey)); } [Fact] public void VerifySignature_CorruptedBase64Signature_ReturnsFalseWithoutThrowing() { var (publicKey, license) = CreateSignedLicense(); var corrupted = license with { Signature = "pas-du-base64-valide!!" }; Assert.False(LicenseValidator.VerifySignature(corrupted, publicKey)); } [Theory] [InlineData("MB-1234", "DISK-5678", true)] [InlineData("mb-1234", "disk-5678", true)] // comparaison insensible à la casse [InlineData("MB-9999", "DISK-5678", false)] [InlineData("MB-1234", "DISK-0000", false)] public void MatchesHardware_RequiresBothIdentifiersToMatch(string motherboard, string disk, bool expected) { var (_, license) = CreateSignedLicense(motherboardUuid: "MB-1234", diskSerial: "DISK-5678"); var current = new HardwareId(motherboard, disk); Assert.Equal(expected, LicenseValidator.MatchesHardware(license, current)); } }