using System; using System.Collections.Generic; using System.Linq; using System.Security.Cryptography.X509Certificates; using Wino.Core.Domain.Interfaces; namespace Wino.Core.WinUI.Services; public class SmimeCertificateService : ISmimeCertificateService { private const string CertificateFriendlyName = "Wino Mail Certificate"; /// /// Retrieves all personal certificates from the current user's certificate store. /// /// This method enumerates certificates in the current user's "My" certificate store that have a /// private key and at least one extension. The store is opened in read-only mode. /// An enumerable collection of objects representing the personal certificates that /// meet the specified criteria. If no matching certificates are found, the collection will be empty. public IEnumerable GetCertificates(StoreName storeName = StoreName.My, StoreLocation storeLocation = StoreLocation.CurrentUser, string? emailAddress = null) { using var store = new X509Store(storeName, storeLocation); store.Open(OpenFlags.ReadOnly); var certs = store.Certificates.Where(cert => cert.FriendlyName == CertificateFriendlyName); return emailAddress != null ? certs.Where(cert => cert.Subject.Contains(emailAddress, StringComparison.OrdinalIgnoreCase)) : certs; } public void ImportCertificate(string fileExtension, byte[] rawData, string? password = null, StoreName storeName = StoreName.My, StoreLocation storeLocation = StoreLocation.CurrentUser) { X509Certificate2Collection collection = []; if (fileExtension is ".p12" or ".pfx") { collection.AddRange(X509CertificateLoader.LoadPkcs12Collection(rawData, password, X509KeyStorageFlags.DefaultKeySet | X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.Exportable)); } else { collection.Add(X509CertificateLoader.LoadCertificate(rawData)); } foreach (var cert in collection) { cert.FriendlyName = CertificateFriendlyName; } using var store = new X509Store(storeName, storeLocation); store.Open(OpenFlags.ReadWrite); store.AddRange(collection); store.Close(); } public void RemoveCertificate(string thumbprint, StoreName storeName = StoreName.My, StoreLocation storeLocation = StoreLocation.CurrentUser) { using var store = new X509Store(storeName, storeLocation); store.Open(OpenFlags.ReadWrite); var cert = store.Certificates.FirstOrDefault(c => c.Thumbprint == thumbprint); if (cert != null) { store.Remove(cert); } } }