Replace AES checkLicense with MachineFingerprint+LicenseFile+LicenseValidator. License.lic hardcoded next to EXE; -chiave= CLI arg and InputArgs.chiave removed. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
199 lines
6.6 KiB
Markdown
199 lines
6.6 KiB
Markdown
---
|
|
phase: 08-license-integration
|
|
plan: 01
|
|
type: execute
|
|
wave: 1
|
|
depends_on: ["07-01"]
|
|
files_modified:
|
|
- Program.cs
|
|
autonomous: true
|
|
---
|
|
|
|
<objective>
|
|
## Goal
|
|
Wire the Phase 07 RSA license core into Program.cs: replace the hardcoded AES `checkLicense` call with `MachineFingerprint` + `LicenseFile` + `LicenseValidator`. Keep `-chiave=` as the CLI arg — it now carries a path to a `.lic` file instead of the AES key string.
|
|
|
|
## Purpose
|
|
The current `checkLicense` embeds a hardcoded AES key/IV in source — anyone with the source or a decompiler can generate licenses for any machine. The Phase 07 RSA core is built but not yet wired in. This phase closes the gap: the app will reject any run where the `.lic` file (passed via `-chiave=`) doesn't contain a valid RSA-SHA256 signature matching the current machine's fingerprint.
|
|
|
|
## Output
|
|
- `Program.cs` only — `checkLicense` method deleted; license check replaced with `MachineFingerprint` + `LicenseFile.TryRead` + `LicenseValidator.Validate`; `inputArgs.chiave` now treated as `.lic` file path; help text for `-chiave=` updated to describe the file path; dead `using System.Management` and `using System.Security.Cryptography` removed; `using NcProgramManager.Licensing` added
|
|
- `InputArgs.cs` — NO CHANGE (`chiave` field stays as-is)
|
|
- Docker build + all 118 tests still pass
|
|
</objective>
|
|
|
|
<context>
|
|
## Project Context
|
|
@.paul/PROJECT.md
|
|
@.paul/STATE.md
|
|
|
|
## Phase 07 Output (direct inputs)
|
|
@Licensing/IMachineFingerprint.cs
|
|
@Licensing/ILicenseValidator.cs
|
|
@Licensing/LicenseFile.cs
|
|
@Licensing/MachineFingerprint.cs
|
|
@Licensing/LicenseValidator.cs
|
|
|
|
## File Being Modified
|
|
@Program.cs
|
|
</context>
|
|
|
|
<acceptance_criteria>
|
|
|
|
## AC-1: -chiave= arg still parsed, value treated as .lic file path
|
|
```gherkin
|
|
Given Program.cs parseArgomenti is called with args containing "-chiave=C:\license.lic"
|
|
When the arg is parsed
|
|
Then inputArgs.chiave equals "C:\license.lic"
|
|
And the parsing code is unchanged from the current implementation
|
|
```
|
|
|
|
## AC-2: RSA license check used at startup
|
|
```gherkin
|
|
Given Program.cs Main is called
|
|
When the license check runs
|
|
Then it calls MachineFingerprint().GetFingerprint(), LicenseFile.TryRead(inputArgs.chiave), and LicenseValidator.Validate(fingerprint, base64)
|
|
And the old checkLicense method no longer exists
|
|
```
|
|
|
|
## AC-3: License failure exits with -100
|
|
```gherkin
|
|
Given the .lic file is missing OR the signature does not match the machine fingerprint
|
|
When Main runs
|
|
Then it prints "Licenza ERRATA", calls vediErrore(-100), and returns -1
|
|
```
|
|
|
|
## AC-4: Help text updated for -chiave=
|
|
```gherkin
|
|
Given MostraAiuto is called
|
|
When its output is inspected
|
|
Then -chiave= is documented as the path to the .lic license file
|
|
```
|
|
|
|
</acceptance_criteria>
|
|
|
|
<tasks>
|
|
|
|
<task type="auto">
|
|
<name>Task 1: Wire RSA license check into Program.cs</name>
|
|
<files>Program.cs</files>
|
|
<action>
|
|
**1. Replace usings at top of file:**
|
|
|
|
Remove these two lines:
|
|
```csharp
|
|
using System.Management;
|
|
using System.Security.Cryptography;
|
|
```
|
|
Add:
|
|
```csharp
|
|
using NcProgramManager.Licensing;
|
|
```
|
|
Keep all other existing usings unchanged.
|
|
|
|
**2. Replace the license check call in Main:**
|
|
|
|
Remove:
|
|
```csharp
|
|
if (!checkLicense(inputArgs.chiave))
|
|
{
|
|
Console.WriteLine("Licenza ERRATA");
|
|
vediErrore(-100);
|
|
return -1;
|
|
}
|
|
```
|
|
Replace with:
|
|
```csharp
|
|
string _licFingerprint = new MachineFingerprint().GetFingerprint();
|
|
string _licBase64;
|
|
if (!LicenseFile.TryRead(inputArgs.chiave, out _licBase64)
|
|
|| !new LicenseValidator().Validate(_licFingerprint, _licBase64))
|
|
{
|
|
Console.WriteLine("Licenza ERRATA");
|
|
vediErrore(-100);
|
|
return -1;
|
|
}
|
|
```
|
|
`inputArgs.chiave` carries the `.lic` file path — parsing in `parseArgomenti` is unchanged.
|
|
|
|
**3. Delete the entire `checkLicense` static method:**
|
|
```csharp
|
|
static Boolean checkLicense(string chiave)
|
|
{
|
|
...
|
|
}
|
|
```
|
|
Remove from first line to closing brace entirely.
|
|
|
|
**4. Update MostraAiuto — update the description for `-chiave=`:**
|
|
|
|
Remove:
|
|
```csharp
|
|
Console.WriteLine("-chiave=");
|
|
Console.WriteLine(" la stringa chiave per eseguire il software.");
|
|
```
|
|
Replace with:
|
|
```csharp
|
|
Console.WriteLine("-chiave=");
|
|
Console.WriteLine(" Path del file di licenza (.lic) per autenticare il software.");
|
|
```
|
|
|
|
Avoid: touching `parseArgomenti` chiave parsing, `Scarica`, `Invia`, `vediErrore`, or any other part of the file.
|
|
</action>
|
|
<verify>
|
|
```bash
|
|
grep -n "checkLicense\|System\.Management\|System\.Security\.Cryptography" Program.cs
|
|
grep -n "MachineFingerprint\|LicenseFile\|LicenseValidator\|NcProgramManager\.Licensing" Program.cs
|
|
grep -n "chiave" Program.cs InputArgs.cs
|
|
```
|
|
First grep: zero hits.
|
|
Second grep: 4+ hits.
|
|
Third grep: `chiave` present in both files (parsing in Program.cs unchanged, field in InputArgs.cs unchanged).
|
|
</verify>
|
|
<done>AC-2 satisfied: RSA check wired. AC-3 satisfied: failure path unchanged (-1 return). AC-4 satisfied: help text updated. AC-1 satisfied: -chiave= parsing untouched.</done>
|
|
</task>
|
|
|
|
</tasks>
|
|
|
|
<boundaries>
|
|
|
|
## DO NOT CHANGE
|
|
- `InputArgs.cs` — `chiave` field stays as-is; no rename
|
|
- `-chiave=` parsing in `parseArgomenti` — keep exactly as-is
|
|
- `AesCrypt.cs` — now dead code but removal is out of scope; leave for a cleanup phase
|
|
- `Licensing/*.cs` — Phase 07 output, must not be modified
|
|
- All `Cnc/` files
|
|
- All test files
|
|
|
|
## SCOPE LIMITS
|
|
- No changes to `Scarica`, `Invia`, `vediErrore` logic
|
|
- No changes to any other arg parsing in `parseArgomenti`
|
|
- No new test files (license core already tested in Phase 07)
|
|
- `AesCrypt.cs` stays in csproj and on disk
|
|
|
|
</boundaries>
|
|
|
|
<verification>
|
|
Before declaring plan complete:
|
|
- [ ] `grep "checkLicense" Program.cs` — zero hits
|
|
- [ ] `grep "System.Management\|System.Security.Cryptography" Program.cs` — zero hits
|
|
- [ ] `grep "MachineFingerprint\|LicenseFile\|LicenseValidator" Program.cs` — 3 hits
|
|
- [ ] `grep "NcProgramManager.Licensing" Program.cs` — 1 hit
|
|
- [ ] `grep "chiave" InputArgs.cs` — still present (field unchanged)
|
|
- [ ] `grep "\-chiave=" Program.cs` — still present in parseArgomenti AND in MostraAiuto
|
|
- [ ] Docker build passes, all 118 tests pass
|
|
</verification>
|
|
|
|
<success_criteria>
|
|
- All tasks completed
|
|
- All verification checks pass
|
|
- `checkLicense` method gone
|
|
- `-chiave=` CLI arg and `inputArgs.chiave` field unchanged
|
|
- RSA license check wired at startup using `inputArgs.chiave` as .lic path
|
|
- Help text describes `-chiave=` as the .lic file path
|
|
- No test regressions
|
|
</success_criteria>
|
|
|
|
<output>
|
|
After completion, create `.paul/phases/08-license-integration/08-01-SUMMARY.md`
|
|
</output>
|