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);
}
}
}