using System; using System.Collections.Generic; using System.Security.Cryptography.X509Certificates; using System.Windows; using System.Windows.Controls; namespace QuickLook.Plugin.CertViewer; public partial class CertViewerControl : UserControl, IDisposable { private string _currentPath; public CertViewerControl() { InitializeComponent(); } /// /// Load a certificate file from path. If the file appears password-protected, /// the control will show an inline password input and allow the user to retry. /// public void LoadFromPath(string path) { _currentPath = path; var result = CertUtils.TryLoadCertificate(path); if (!result.Success && result.NeedsPassword) { // show password overlay, hide main content PasswordOverlay.Visibility = Visibility.Visible; MainTab.Visibility = Visibility.Collapsed; InlinePasswordBox.Password = string.Empty; return; } PasswordOverlay.Visibility = Visibility.Collapsed; MainTab.Visibility = Visibility.Visible; if (result.Success && result.Certificate != null) LoadCertificate(result.Certificate); else LoadRaw(path, result.Message, result.RawContent); } public void LoadCertificate(X509Certificate2 cert) { PasswordOverlay.Visibility = Visibility.Collapsed; MainTab.Visibility = Visibility.Visible; var items = new List> { new("[Version]", "V" + cert.Version), new("[Subject]", cert.SubjectName.Name) }; string nameInfo = cert.GetNameInfo(X509NameType.SimpleName, false); if (!string.IsNullOrEmpty(nameInfo)) items.Add(new(" Simple Name", nameInfo)); string email = cert.GetNameInfo(X509NameType.EmailName, false); if (!string.IsNullOrEmpty(email)) items.Add(new(" Email Name", email)); string upn = cert.GetNameInfo(X509NameType.UpnName, false); if (!string.IsNullOrEmpty(upn)) items.Add(new(" UPN Name", upn)); string dns = cert.GetNameInfo(X509NameType.DnsName, false); if (!string.IsNullOrEmpty(dns)) items.Add(new(" DNS Name", dns)); // [Issuer] items.Add(new("[Issuer]", cert.IssuerName.Name)); nameInfo = cert.GetNameInfo(X509NameType.SimpleName, true); if (!string.IsNullOrEmpty(nameInfo)) items.Add(new(" Simple Name", nameInfo)); email = cert.GetNameInfo(X509NameType.EmailName, true); if (!string.IsNullOrEmpty(email)) items.Add(new(" Email Name", email)); upn = cert.GetNameInfo(X509NameType.UpnName, true); if (!string.IsNullOrEmpty(upn)) items.Add(new(" UPN Name", upn)); dns = cert.GetNameInfo(X509NameType.DnsName, true); if (!string.IsNullOrEmpty(dns)) items.Add(new(" DNS Name", dns)); // [Serial Number] items.Add(new("[Serial Number]", cert.SerialNumber)); // [Not Before] items.Add(new("[Not Before]", cert.NotBefore.ToString())); // [Not After] items.Add(new("[Not After]", cert.NotAfter.ToString())); // [Thumbprint] items.Add(new("[Thumbprint]", cert.Thumbprint)); // [Signature Algorithm] items.Add(new("[Signature Algorithm]", cert.SignatureAlgorithm.FriendlyName + " (" + cert.SignatureAlgorithm.Value + ")")); // [Public Key] var pk = cert.PublicKey; items.Add(new("[Public Key]", "")); items.Add(new(" Algorithm", pk.Oid.FriendlyName)); try { items.Add(new(" Length", pk.Key.KeySize.ToString())); } catch { } items.Add(new(" Key Blob", pk.EncodedKeyValue.Format(true))); items.Add(new(" Parameters", pk.EncodedParameters.Format(true))); // [Private Key] if (cert.HasPrivateKey) { items.Add(new("[Private Key]", "Present")); } // [Extensions] if (cert.Extensions != null && cert.Extensions.Count > 0) { items.Add(new("[Extensions]", "")); foreach (var ext in cert.Extensions) { try { string extName = ext.Oid.FriendlyName + " (" + ext.Oid.Value + ")"; items.Add(new(" " + extName, ext.Format(true))); } catch { } } } PropertyList.ItemsSource = items; RawText.Text = cert.ToString(); } public void LoadRaw(string path, string message, string content) { PasswordOverlay.Visibility = Visibility.Collapsed; MainTab.Visibility = Visibility.Visible; PropertyList.ItemsSource = new List> { new("Path", path), new("Info", message) }; RawText.Text = content ?? "(No content to display)"; } public void Dispose() { } private void LoadWithPasswordButton_Click(object sender, RoutedEventArgs e) { var pwd = InlinePasswordBox.Password; if (string.IsNullOrEmpty(_currentPath)) return; var result = CertUtils.TryLoadCertificate(_currentPath, pwd); if (!result.Success && result.NeedsPassword) { // still need password, keep overlay InlinePasswordBox.Password = string.Empty; return; } PasswordOverlay.Visibility = Visibility.Collapsed; MainTab.Visibility = Visibility.Visible; if (result.Success && result.Certificate != null) { LoadCertificate(result.Certificate); } else { LoadRaw(_currentPath, result.Message, result.RawContent); } } private void CancelPasswordButton_Click(object sender, RoutedEventArgs e) { // show failure/raw view if (string.IsNullOrEmpty(_currentPath)) return; var result = CertUtils.TryLoadCertificate(_currentPath); PasswordOverlay.Visibility = Visibility.Collapsed; MainTab.Visibility = Visibility.Visible; LoadRaw(_currentPath, result.Message, result.RawContent); } }