Files
Disco/Disco.ClientBootstrapper/Interop/CertificateInterop.cs
T
2024-12-14 16:55:37 +11:00

200 lines
7.6 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography.X509Certificates;
using System.Text.RegularExpressions;
using System.IO;
namespace Disco.ClientBootstrapper.Interop
{
public static class CertificateInterop
{
private static List<string> _tempCerts;
public static void RemoveTempCerts()
{
if (_tempCerts != null && _tempCerts.Count > 0)
{
Remove(StoreName.My, StoreLocation.LocalMachine, _tempCerts);
// dont remove root/intermediate certs as they may be have installed by client
//Remove(StoreName.CertificateAuthority, StoreLocation.LocalMachine, _tempCerts);
//Remove(StoreName.Root, StoreLocation.LocalMachine, _tempCerts);
}
}
public static void AddTempCerts()
{
if (_tempCerts == null)
_tempCerts = new List<string>();
var inlineCertificateLocation = Program.InlinePath.Value;
// Root Certificates
try
{
var CertFiles = Directory.EnumerateFiles(inlineCertificateLocation, "WLAN_Cert_Root_*.*").ToList();
if (CertFiles.Count > 0)
{
foreach (var certFile in CertFiles)
{
var cert = new X509Certificate2(File.ReadAllBytes(certFile), "password");
var result = Add(StoreName.Root, StoreLocation.LocalMachine, cert);
if (result)
{
if (Path.GetFileNameWithoutExtension(certFile).ToLower().Contains("temp"))
_tempCerts.Add(cert.SerialNumber);
Program.Status.UpdateStatus(null, null, string.Format("Added Root Certificate: {0}", cert.ShortSubjectName()));
Program.SleepThread(500, false);
}
}
}
}
catch (Exception)
{
throw;
}
// Intermediate Certificates
try
{
var CertFiles = Directory.EnumerateFiles(inlineCertificateLocation, "WLAN_Cert_Intermediate_*.*").ToList();
if (CertFiles.Count > 0)
{
foreach (var certFile in CertFiles)
{
var cert = new X509Certificate2(File.ReadAllBytes(certFile), "password");
var result = Add(StoreName.CertificateAuthority, StoreLocation.LocalMachine, cert);
if (result)
{
if (Path.GetFileNameWithoutExtension(certFile).ToLower().Contains("temp"))
_tempCerts.Add(cert.SerialNumber);
Program.Status.UpdateStatus(null, null, string.Format("Added Intermediate Certificate: {0}", cert.ShortSubjectName()));
Program.SleepThread(500, false);
}
}
}
}
catch (Exception)
{
throw;
}
// Host/Personal Certificates
try
{
var CertFiles = Directory.EnumerateFiles(inlineCertificateLocation, "WLAN_Cert_Personal_*.*").ToList();
if (CertFiles.Count > 0)
{
foreach (var certFile in CertFiles)
{
var cert = new X509Certificate2(File.ReadAllBytes(certFile), "password", X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet);
var result = Add(StoreName.My, StoreLocation.LocalMachine, cert);
if (result)
{
if (Path.GetFileNameWithoutExtension(certFile).ToLower().Contains("temp"))
_tempCerts.Add(cert.SerialNumber);
Program.Status.UpdateStatus(null, null, string.Format("Added Host Certificate: {0}", cert.ShortSubjectName()));
Program.SleepThread(500, false);
}
}
}
}
catch (Exception)
{
throw;
}
}
public static string ShortSubjectName(this X509Certificate2 Certificate)
{
string s = Certificate.Subject;
if (string.IsNullOrWhiteSpace(s))
{
return $"Unknown Certificate: {Certificate.Thumbprint}";
}
else
{
if (s.Length > 3 && s.StartsWith("CN=", StringComparison.OrdinalIgnoreCase))
{
var nameLength = s.IndexOf(',') - 3;
if (nameLength > 0)
{
return s.Substring(3, nameLength);
}
else
{
return s.Substring(3);
}
}
return s;
}
}
public static bool Add(StoreName StoreName, StoreLocation StoreLocation, X509Certificate2 Certificate)
{
var certStore = new X509Store(StoreName, StoreLocation);
bool certAlreadyExists = false;
certStore.Open(OpenFlags.ReadWrite);
foreach (var cert in certStore.Certificates)
{
if (cert.SerialNumber.Equals(Certificate.SerialNumber))
{
certAlreadyExists = true;
break;
}
}
if (!certAlreadyExists)
{
certStore.Add(Certificate);
}
certStore.Close();
return !certAlreadyExists;
}
public static bool Remove(StoreName StoreName, StoreLocation StoreLocation, List<Regex> RegexMatches, string SerialException)
{
var certStore = new X509Store(StoreName, StoreLocation);
var removeCerts = new List<X509Certificate2>();
certStore.Open(OpenFlags.ReadWrite);
foreach (var cert in certStore.Certificates)
{
if (!cert.SerialNumber.Equals(SerialException))
{
foreach (var subjectRegex in RegexMatches)
{
if (subjectRegex.IsMatch(cert.Subject))
{
removeCerts.Add(cert);
break;
}
}
}
}
foreach (var cert in removeCerts)
{
certStore.Remove(cert);
}
certStore.Close();
return (removeCerts.Count > 0);
}
public static bool Remove(StoreName StoreName, StoreLocation StoreLocation, List<string> CertificateSerials)
{
var certStore = new X509Store(StoreName, StoreLocation);
var removeCerts = new List<X509Certificate2>();
certStore.Open(OpenFlags.ReadWrite);
foreach (var cert in certStore.Certificates)
{
if (CertificateSerials.Contains(cert.SerialNumber))
{
removeCerts.Add(cert);
}
}
foreach (var cert in removeCerts)
{
certStore.Remove(cert);
}
certStore.Close();
return (removeCerts.Count > 0);
}
}
}