nc_program_manager/.paul/phases/08-license-integration/08-01-PLAN.md
dtrentin 3312a57757 feat(08-license-integration): wire RSA license check, remove -chiave arg
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>
2026-05-17 23:10:05 +02:00

6.6 KiB

phase plan type wave depends_on files_modified autonomous
08-license-integration 01 execute 1
07-01
Program.cs
true
## 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
## 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

<acceptance_criteria>

AC-1: -chiave= arg still parsed, value treated as .lic file path

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

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

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=

Given MostraAiuto is called
When its output is inspected
Then -chiave= is documented as the path to the .lic license file

</acceptance_criteria>

Task 1: Wire RSA license check into Program.cs Program.cs **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.
```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). 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.

DO NOT CHANGE

  • InputArgs.cschiave 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
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

<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>
After completion, create `.paul/phases/08-license-integration/08-01-SUMMARY.md`