Prepare Pro 1.0.1 imports and license tooling

This commit is contained in:
livio committed 2026-09-28 19:41:57 +02:00
1 parent 62f28c5621
commit 0b5017739c
13 files changed
+437 -48

No files matched your search

+26 -6
View File
@@ -240,14 +240,25 @@ internal sealed class LicenseRepository
{
if (File.Exists(PrivateKeyPath))
{
using var existing = LoadPrivateKey();
if (!_allowKeyGeneration && !IsExpectedSigningKey(existing))
try
{
throw new CryptographicException("La chiave locale non corrisponde alla chiave pubblica incorporata in LME Pro.");
}
using var existing = LoadPrivateKey();
if (!_allowKeyGeneration && !IsExpectedSigningKey(existing))
{
PreserveIncompatiblePrivateKey();
File.WriteAllText(PublicKeyPath, ExpectedPublicKeyPem, Encoding.ASCII);
return;
}
File.WriteAllText(PublicKeyPath, existing.ExportSubjectPublicKeyInfoPem(), Encoding.ASCII);
return;
File.WriteAllText(PublicKeyPath, existing.ExportSubjectPublicKeyInfoPem(), Encoding.ASCII);
return;
}
catch (CryptographicException) when (!_allowKeyGeneration)
{
PreserveIncompatiblePrivateKey();
File.WriteAllText(PublicKeyPath, ExpectedPublicKeyPem, Encoding.ASCII);
return;
}
}
if (!_allowKeyGeneration)
@@ -265,6 +276,15 @@ internal sealed class LicenseRepository
File.SetAttributes(PrivateKeyPath, FileAttributes.Hidden);
}
private void PreserveIncompatiblePrivateKey()
{
File.SetAttributes(PrivateKeyPath, FileAttributes.Normal);
var preservedPath = Path.Combine(
_directory,
$"manual-license-private-incompatible-{DateTime.UtcNow:yyyyMMddHHmmss}.dpapi");
File.Move(PrivateKeyPath, preservedPath);
}
private static bool IsExpectedSigningKey(RSA rsa)
{
using var expected = RSA.Create();
+11 -4
View File
@@ -65,16 +65,23 @@ internal sealed class MainForm : Form
};
panel.Controls.Add(text, 0, 0);
var commands = new FlowLayoutPanel { AutoSize = true, FlowDirection = FlowDirection.LeftToRight, Margin = new Padding(8, 0, 0, 12) };
var commands = new TableLayoutPanel
{
AutoSize = true,
AutoSizeMode = AutoSizeMode.GrowAndShrink,
ColumnCount = 1,
RowCount = 3,
Margin = new Padding(8, 0, 0, 12)
};
var openFolder = new Button { Text = "Apri archivio", AutoSize = true };
openFolder.Click += (_, _) => Process.Start(new ProcessStartInfo("explorer.exe", _repository.StoragePath) { UseShellExecute = true });
var exportKey = new Button { Text = "Backup chiave", AutoSize = true };
exportKey.Click += (_, _) => ExportSigningKey();
var importKey = new Button { Text = "Ripristina chiave", AutoSize = true };
importKey.Click += (_, _) => ImportSigningKey();
commands.Controls.Add(openFolder);
commands.Controls.Add(exportKey);
commands.Controls.Add(importKey);
commands.Controls.Add(openFolder, 0, 0);
commands.Controls.Add(exportKey, 0, 1);
commands.Controls.Add(importKey, 0, 2);
panel.Controls.Add(commands, 1, 0);
return panel;
}
+27 -1
View File
@@ -5,6 +5,21 @@ internal static class Program
[STAThread]
private static void Main(string[] args)
{
if (args.Length == 2 && args[0].Equals("--export-key", StringComparison.OrdinalIgnoreCase))
{
var password = Environment.GetEnvironmentVariable("LME_LICENSE_BACKUP_PASSWORD");
if (string.IsNullOrWhiteSpace(password))
{
throw new InvalidOperationException("Imposta LME_LICENSE_BACKUP_PASSWORD per esportare la chiave.");
}
var exportRepository = new LicenseRepository();
exportRepository.Initialize();
exportRepository.ExportSigningKeyBackup(Path.GetFullPath(args[1]), password);
Console.WriteLine($"Backup chiave creato: {Path.GetFullPath(args[1])}");
return;
}
if (args.Contains("--self-test", StringComparer.OrdinalIgnoreCase))
{
RunSelfTest();
@@ -26,6 +41,7 @@ internal static class Program
{
var testDirectory = Path.Combine(Path.GetTempPath(), $"LME-License-SelfTest-{Guid.NewGuid():N}");
var importedDirectory = Path.Combine(Path.GetTempPath(), $"LME-License-SelfTest-{Guid.NewGuid():N}");
var incompatibleDirectory = Path.Combine(Path.GetTempPath(), $"LME-License-SelfTest-{Guid.NewGuid():N}");
const string backupPassword = "LME-Test-Backup-Password-2026";
try
{
@@ -60,11 +76,21 @@ internal static class Program
throw new InvalidOperationException("La chiave importata non produce licenze compatibili.");
}
var incompatibleRepository = new LicenseRepository(incompatibleDirectory, allowKeyGeneration: true);
incompatibleRepository.Initialize();
var strictRepository = new LicenseRepository(incompatibleDirectory);
strictRepository.Initialize();
if (File.Exists(Path.Combine(incompatibleDirectory, "manual-license-private.dpapi"))
|| Directory.GetFiles(incompatibleDirectory, "manual-license-private-incompatible-*.dpapi").Length != 1)
{
throw new InvalidOperationException("La chiave incompatibile non e stata conservata correttamente.");
}
Console.WriteLine("Self-test licenze e portabilita chiave completato.");
}
finally
{
foreach (var directory in new[] { testDirectory, importedDirectory })
foreach (var directory in new[] { testDirectory, importedDirectory, incompatibleDirectory })
{
var fullPath = Path.GetFullPath(directory);
var tempRoot = Path.GetFullPath(Path.GetTempPath());
@@ -0,0 +1,11 @@
-----BEGIN PUBLIC KEY-----
MIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEAmjh4E1fpaaonATNDipsR
1iy5cNSStD7fgB7i5xJTSZV36Td1B7hQXfZB8Z7vx9iFJpbCQMePuFiDKNbTUQFf
EKEp8lBq7SHo0LvbKNOSK9RMkqpb3ova9Er14gSCgshivf1c774VXTlt9J7uAWoE
QeQMNKJUSogoMkxEKc4Xmye65lGjJVeiuqdDCJh5o42j8DfGwqOyGX4808vSeixe
3lArRmoq9SGNO05VVunF8NKJyhiRLfropUvC+eFsiJMp3VMEYVn5FUcd8ljO67jv
pnngWh6zCZxs+h0mT0YRU9F3tWHqqsG1PE6NZnspmBdNfUfb9LxKt1RshEhUWiBx
0vvdUtg20nESOvFnieIX64pcx0LqFlDMmEWDMQjZ7KEtwXVphN1mhsryUiS6Cz3b
oKTryH4FQY9iIWNNzdzXujrV5ycE49orFEtrXRPnXBlB97Hl3Dlxi19lvPwxWXQ5
fKXrTJ2rL/WvlMpZ5YOggAmv7P7tA4B+Oi5uMiHzXEDlAgMBAAE=
-----END PUBLIC KEY-----