Files
Wino-Mail/Wino.Mail.WinUI/Services/SmimeCertificateService.cs
T

63 lines
2.7 KiB
C#
Raw Normal View History

2025-11-23 20:56:57 +01:00
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";
/// <summary>
/// Retrieves all personal certificates from the current user's certificate store.
/// </summary>
/// <remarks>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.</remarks>
/// <returns>An enumerable collection of <see cref="X509Certificate2"/> objects representing the personal certificates that
/// meet the specified criteria. If no matching certificates are found, the collection will be empty.</returns>
public IEnumerable<X509Certificate2> 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);
}
}
}