From b45a65dfa077bf2d9dc385b25c5348bca986616d Mon Sep 17 00:00:00 2001 From: grim Date: Sat, 25 Oct 2025 09:59:25 +0200 Subject: [PATCH] polishing --- certmgr/CertGen/KeyUsage.cs | 37 ++++++++++++++++++++++++++++ certmgr/Jobs/CertificateSettings.cs | 6 +++++ certmgr/Jobs/CreateCertificateJob.cs | 10 +++++--- 3 files changed, 49 insertions(+), 4 deletions(-) create mode 100644 certmgr/CertGen/KeyUsage.cs diff --git a/certmgr/CertGen/KeyUsage.cs b/certmgr/CertGen/KeyUsage.cs new file mode 100644 index 0000000..9d946be --- /dev/null +++ b/certmgr/CertGen/KeyUsage.cs @@ -0,0 +1,37 @@ +using System.Security.Cryptography.X509Certificates; + +namespace CertMgr.CertGen; + +[Flags] +public enum KeyUsage +{ + /// No key usage parameters. + None = X509KeyUsageFlags.None, + + /// The key can be used for encryption only. + EncipherOnly = X509KeyUsageFlags.EncipherOnly, + + /// The key can be used to sign a certificate revocation list (CRL). + CrlSign = X509KeyUsageFlags.CrlSign, + + /// The key can be used to sign certificates. + KeyCertSign = X509KeyUsageFlags.KeyCertSign, + + /// The key can be used to determine key agreement, such as a key created using the Diffie-Hellman key agreement algorithm. + KeyAgreement = X509KeyUsageFlags.KeyAgreement, + + /// The key can be used for data encryption. + DataEncipherment = X509KeyUsageFlags.DataEncipherment, + + /// The key can be used for key encryption. + KeyEncipherment = X509KeyUsageFlags.KeyEncipherment, + + /// The key can be used for authentication. + NonRepudiation = X509KeyUsageFlags.NonRepudiation, + + /// The key can be used as a digital signature. + DigitalSignature = X509KeyUsageFlags.DigitalSignature, + + /// The key can be used for decryption only. + DecipherOnly = X509KeyUsageFlags.DecipherOnly +} diff --git a/certmgr/Jobs/CertificateSettings.cs b/certmgr/Jobs/CertificateSettings.cs index 212bec0..115604e 100644 --- a/certmgr/Jobs/CertificateSettings.cs +++ b/certmgr/Jobs/CertificateSettings.cs @@ -31,6 +31,12 @@ public sealed class CertificateSettings : JobSettings [Setting("subject-alternate-name", AlternateNames = ["san"], Validator = typeof(SubjectAlternateNamesValidator))] public IReadOnlyCollection? SubjectAlternateNames { [DebuggerStepThrough] get; [DebuggerStepThrough] set; } + [Setting("friendly-name")] + public string? FriendlyName { [DebuggerStepThrough] get; [DebuggerStepThrough] set; } + + [Setting("key-usage", Default = CertGen.KeyUsage.None, Converter = typeof(EnumConverter))] + public KeyUsage? KeyUsage { [DebuggerStepThrough] get; [DebuggerStepThrough] set; } + [Setting("algorithm", Default = CertificateAlgorithm.ECDsa, Converter = typeof(EnumConverter))] public CertificateAlgorithm? Algorithm { [DebuggerStepThrough] get; [DebuggerStepThrough] set; } diff --git a/certmgr/Jobs/CreateCertificateJob.cs b/certmgr/Jobs/CreateCertificateJob.cs index 9fc941e..a7b6eff 100644 --- a/certmgr/Jobs/CreateCertificateJob.cs +++ b/certmgr/Jobs/CreateCertificateJob.cs @@ -38,7 +38,6 @@ public sealed class CreateCertificateJob : Job throw new JobException(writeResult.Exception, "Failed to write create certificate to target storage (type = '{0}', storage = '{1}')", Settings.Storage.GetType().ToString(false), Settings.Storage.ToString()); } } - } } @@ -70,15 +69,19 @@ public sealed class CreateCertificateJob : Job CertGen.CertificateSettings cgcs = new CertGen.CertificateSettings(); - X509KeyStorageFlags flags = X509KeyStorageFlags.Exportable | X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet; + cgcs.SubjectName = Settings.Subject; cgcs.ValidityPeriod = Settings.ValidityPeriod.HasValue ? Settings.ValidityPeriod.Value : TimeSpan.FromDays(365); - cgcs.FriendlyName = "I'm your friend"; + cgcs.FriendlyName = Settings.FriendlyName; + cgcs.IsCertificateAuthority = Settings.IsCertificateAuthority; + cgcs.KeyUsage = (X509KeyUsageFlags)(Settings.KeyUsage.HasValue ? Settings.KeyUsage.Value : KeyUsage.None); if (Settings.Issuer != null) { try { using (MemoryStream ms = new MemoryStream()) { + // X509KeyStorageFlags flags = X509KeyStorageFlags.Exportable | X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet; + X509KeyStorageFlags flags = X509KeyStorageFlags.DefaultKeySet; await Settings.Issuer.ReadAsync(ms, cancellationToken).ConfigureAwait(false); cgcs.Issuer = X509CertificateLoader.LoadPkcs12(ms.GetBuffer(), Settings.IssuerPassword, flags); } @@ -88,7 +91,6 @@ public sealed class CreateCertificateJob : Job throw new CertGenException(e, "Failed to load issuer's certificate"); } } - cgcs.SubjectName = Settings.Subject; if (Settings.SubjectAlternateNames != null) { foreach (string altName in Settings.SubjectAlternateNames)