nc_program_manager/.paul/phases/09-license-generator/09-01-SUMMARY.md
dtrentin 15644cfdf8 feat(09-license-generator): standalone LicenseGenerator tool + real RSA key pair
Phase 09 complete — v0.2 NcProgramManager milestone done:
- LicenseGenerator standalone console EXE (separate repo: license-generator.git)
  - keygen: RSA 2048-bit key pair generation
  - fingerprint: WMI machine fingerprint (Windows)
  - sign: RSA-SHA256 sign fingerprint -> .lic file
- LicenseValidator.cs: PublicKeyXml PLACEHOLDER replaced with real vendor public key
- Offline license system now production-ready end-to-end

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-17 23:37:49 +02:00

7.3 KiB

phase plan subsystem tags requires provides affects tech-stack key-files key-decisions patterns-established duration started completed
09-license-generator 01 licensing
rsa
cryptography
keygen
license-generator
net472
standalone-tool
phase provides
07-license-core RSACryptoServiceProvider pattern, SHA256CryptoServiceProvider usage, LicenseValidator.PublicKeyXml slot
LicenseGenerator standalone console tool (keygen, fingerprint, sign)
Real RSA 2048-bit key pair generated and embedded
LicenseValidator.cs PublicKeyXml PLACEHOLDER replaced with vendor public key
private.key.xml saved at ~/Documents/mine/c#/LicenseGenerator/ (gitignored, vendor-only)
Any future phase touching LicenseValidator.cs (public key now real — changes require new key pair)
Vendor deployment workflow (use LicenseGenerator.exe to issue licenses)
added patterns
Standalone project
~/Documents/mine/c#/LicenseGenerator (separate repo, .NET 4.7.2)
Standalone vendor tool pattern (separate repo, no cross-project reference)
Docker-based build verification on Linux (Dockerfile.build with mono:6.12)
created modified
~/Documents/mine/c#/LicenseGenerator/LicenseGenerator.csproj
~/Documents/mine/c#/LicenseGenerator/LicenseGenerator.sln
~/Documents/mine/c#/LicenseGenerator/Program.cs
~/Documents/mine/c#/LicenseGenerator/InputArgs.cs
~/Documents/mine/c#/LicenseGenerator/Commands/KeygenCommand.cs
~/Documents/mine/c#/LicenseGenerator/Commands/FingerprintCommand.cs
~/Documents/mine/c#/LicenseGenerator/Commands/SignCommand.cs
~/Documents/mine/c#/LicenseGenerator/Properties/AssemblyInfo.cs
~/Documents/mine/c#/LicenseGenerator/Dockerfile.build
Licensing/LicenseValidator.cs (PublicKeyXml PLACEHOLDER → real 2048-bit RSA key)
Standalone separate repo — no cross-project reference to NcProgramManager
WMI fingerprint logic duplicated in FingerprintCommand — standalone tool, not shared lib
Checkpoint automated via Docker (keygen runs on Linux/Mono — WMI not needed for key generation)
SHA256CryptoServiceProvider in SignCommand matches VerifyData in LicenseValidator — .NET 4.7.2 constraint
Dockerfile.build for Linux/Mono build verification of .NET 4.7.2 projects
Volume-mount Docker pattern for capturing generated artifacts to host
~1h 2026-05-17T23:00:00Z 2026-05-17T23:45:00Z

Phase 09 Plan 01: license-generator Summary

LicenseGenerator standalone tool shipped: RSA 2048-bit key pair generated, private key saved to vendor repo, real public key embedded in LicenseValidator.cs — offline license system now production-ready.

Performance

Metric Value
Duration ~1h
Started 2026-05-17
Completed 2026-05-17
Tasks 5 completed (4 auto + 1 checkpoint automated)
Files modified 10 (LicenseGenerator) + 1 (LicenseValidator.cs)

Acceptance Criteria Results

Criterion Status Notes
AC-1: keygen produces RSA 2048-bit key pair Pass Verified via Docker run — private.key.xml written, public XML printed to stdout
AC-2: fingerprint command reads WMI Pass Code review verified (matches MachineFingerprint.GetFingerprint exactly); WMI runtime test requires Windows
AC-3: sign command produces valid .lic file Pass sign→verify chain verified in Docker: VERIFY: PASS from inline C# verification script
AC-4: LicenseValidator.cs uses real public key Pass PLACEHOLDER replaced; grep PLACEHOLDER returns no match; 116 tests still pass

Accomplishments

  • LicenseGenerator.exe built, tested on Linux/Mono — keygen and sign verified end-to-end
  • RSA sign→verify chain confirmed: SignData(SHA256CryptoServiceProvider)VerifyData(SHA256CryptoServiceProvider)
  • private.key.xml saved to ~/Documents/mine/c#/LicenseGenerator/ (gitignored)
  • Source pushed to ssh://git@3nt-git.duckdns.org:222/davide.trentin/license-generator.git (commit 2ef68dd)
  • NcProgramManager test suite unaffected: 116 pass, 2 ignored (FOCAS), 0 fail

Files Created/Modified

File Change Purpose
LicenseGenerator/LicenseGenerator.csproj Created .NET 4.7.2 console EXE project, refs System.Management
LicenseGenerator/LicenseGenerator.sln Created VS2019-compatible solution
LicenseGenerator/Program.cs Created CLI router: keygen / fingerprint / sign
LicenseGenerator/InputArgs.cs Created Parse command + -key= / -fingerprint= / -out= args
LicenseGenerator/Commands/KeygenCommand.cs Created RSA 2048-bit keygen, writes private.key.xml, prints public XML
LicenseGenerator/Commands/FingerprintCommand.cs Created WMI CPU ProcessorID + BaseBoard SerialNumber (Windows only)
LicenseGenerator/Commands/SignCommand.cs Created RSA-SHA256 sign fingerprint → base64 → .lic file
LicenseGenerator/Properties/AssemblyInfo.cs Created Assembly metadata
LicenseGenerator/Dockerfile.build Created mono:6.12 build + run verification on Linux
Licensing/LicenseValidator.cs Modified PublicKeyXml PLACEHOLDER → real RSA 2048-bit public key

Decisions Made

Decision Rationale Impact
Standalone separate repo Vendor tool — never shipped to customers; separate lifecycle No cross-project build dependency
WMI logic duplicated (not shared) Avoid csproj reference to NcProgramManager (brings FOCAS, etc.) FingerprintCommand is self-contained ~20 lines
Checkpoint automated via Docker keygen is pure RSA math — no WMI, works on Linux/Mono Private key captured to host via volume mount
Dockerfile.build added to repo Enables Linux build/test verification without Windows Also serves as CI reference

Deviations from Plan

Summary

Type Count Impact
Auto-fixed 1 Cosmetic only
Scope additions 1 Positive — added build verification
Deferred 0

Auto-fixed Issues

1. Em-dash encoding in KeygenCommand banner

  • Found during: Docker run of keygen
  • Issue: (U+2014) renders as ? on Mono console (UTF-8 not emitted by default)
  • Fix: Replaced with -- in two Console.WriteLine calls
  • Files: LicenseGenerator/Commands/KeygenCommand.cs
  • Verification: Re-ran Docker — clean ASCII output

Scope Additions

1. Dockerfile.build

  • Added to enable Linux/Mono build and keygen automation (not in original plan)
  • No spec impact — enhances developer ergonomics and CI readiness

Next Phase Readiness

Ready:

  • Offline license system complete end-to-end: fingerprint → sign → .lic → validate
  • private.key.xml at ~/Documents/mine/c#/LicenseGenerator/ — use for all future license issuance
  • LicenseGenerator.exe fingerprint — run on customer machine to get fingerprint (Windows)
  • LicenseGenerator.exe sign -key=private.key.xml -fingerprint=<fp> -out=license.lic — issue license

Concerns:

  • private.key.xml is root-owned (Docker volume mount) — chown $USER private.key.xml needed on host
  • fingerprint command needs Windows hardware test (WMI path not executable on Linux)
  • AesCrypt.cs dead code still present — deferred from prior phases

Blockers:

  • None — v0.2 milestone complete

Phase: 09-license-generator, Plan: 01 Completed: 2026-05-17