Phase 07 complete: - IMachineFingerprint + ILicenseValidator interfaces - MachineFingerprint: WMI CPU ProcessorID + BaseBoard SerialNumber - LicenseValidator: RSACryptoServiceProvider + SHA256, injectable public key - LicenseFile.TryRead: out-param bool, no exceptions from file I/O - 6 NUnit tests (valid/wrong-machine/tampered/empty/not-base64/missing-file) - 118 tests total, 116 pass, 2 Fanuc FOCAS ignored (Windows DLL) - Fix: missing 'using System' in CncMachineFactoryTests.cs - Fix: Dockerfile.test updated for NcProgramManager rename PublicKeyXml = PLACEHOLDER until Phase 09 generates real key pair. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
46 lines
1.5 KiB
C#
46 lines
1.5 KiB
C#
using System;
|
|
using System.Security.Cryptography;
|
|
using System.Text;
|
|
|
|
namespace NcProgramManager.Licensing
|
|
{
|
|
internal class LicenseValidator : ILicenseValidator
|
|
{
|
|
// Placeholder — replace with real vendor public key XML after Phase 09 generates the key pair.
|
|
// Generate key pair with the LicenseGenerator tool, then copy the public XML here.
|
|
private const string PublicKeyXml =
|
|
"<RSAKeyValue>" +
|
|
"<Modulus>PLACEHOLDER</Modulus>" +
|
|
"<Exponent>AQAB</Exponent>" +
|
|
"</RSAKeyValue>";
|
|
|
|
private readonly string _publicKeyXml;
|
|
|
|
// Uses embedded vendor public key.
|
|
internal LicenseValidator() : this(PublicKeyXml) { }
|
|
|
|
// Accepts any public key XML — used in unit tests.
|
|
internal LicenseValidator(string publicKeyXml)
|
|
{
|
|
_publicKeyXml = publicKeyXml;
|
|
}
|
|
|
|
public bool Validate(string fingerprint, string licenseBase64)
|
|
{
|
|
try
|
|
{
|
|
byte[] signature = Convert.FromBase64String(licenseBase64);
|
|
byte[] data = Encoding.UTF8.GetBytes(fingerprint);
|
|
using (var rsa = new RSACryptoServiceProvider())
|
|
{
|
|
rsa.FromXmlString(_publicKeyXml);
|
|
return rsa.VerifyData(data, new SHA256CryptoServiceProvider(), signature);
|
|
}
|
|
}
|
|
catch
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
}
|