using System;
using System.Runtime.InteropServices;
using System.Security.Cryptography.X509Certificates;
using System.Collections.Generic;
namespace CertificateHelper
{
// COM Интерфейс для доступа
[ComVisible(true)]
[Guid("12345678-1234-1234-1234-123456789012")]
[InterfaceType(ComInterfaceType.InterfaceIsDual)]
public interface ICertificateManager
{
int GetCertificateCount(string storeName, string storeLocation);
string GetCertificateSubject(string storeName, string storeLocation, int index);
string GetCertificateThumbprint(string storeName, string storeLocation, int index);
string GetCertificateIssuer(string storeName, string storeLocation, int index);
bool FindCertificateByThumbprint(string storeName, string storeLocation, string thumbprint);
string[] GetAllCertificateThumbprints(string storeName, string storeLocation);
bool IsCertificateValid(string storeName, string storeLocation, string thumbprint);
}
// собственно, реализация
[ComVisible(true)]
[Guid("87654321-4321-4321-4321-210987654321")]
[ClassInterface(ClassInterfaceType.None)]
[ProgId("CertificateHelper.CertificateManager")]
public class CertificateManager : ICertificateManager
{
private X509Store GetStore(string storeName, string storeLocation)
{
StoreName name;
StoreLocation location;
// парсим имена
switch (storeName.ToUpper())
{
case "MY":
case "PERSONAL":
name = StoreName.My;
break;
case "ROOT":
name = StoreName.Root;
break;
case "CA":
case "INTERMEDIATE":
name = StoreName.CertificateAuthority;
break;
default:
name = StoreName.My;
break;
}
// парсим раположение
switch (storeLocation.ToUpper())
{
case "CURRENTUSER":
location = StoreLocation.CurrentUser;
break;
case "LOCALMACHINE":
location = StoreLocation.LocalMachine;
break;
default:
location = StoreLocation.CurrentUser;
break;
}
return new X509Store(name, location);
}
public int GetCertificateCount(string storeName, string storeLocation)
{
try
{
using (var store = GetStore(storeName, storeLocation))
{
store.Open(OpenFlags.ReadOnly);
return store.Certificates.Count;
}
}
catch
{
return -1;
}
}
public string GetCertificateSubject(string storeName, string storeLocation, int index)
{
try
{
using (var store = GetStore(storeName, storeLocation))
{
store.Open(OpenFlags.ReadOnly);
if (index >= 0 && index < store.Certificates.Count)
{
return store.Certificates[index].Subject;
}
}
}
catch
{
// если ошибка, вернем пустую строку
}
return "";
}
public string GetCertificateThumbprint(string storeName, string storeLocation, int index)
{
try
{
using (var store = GetStore(storeName, storeLocation))
{
store.Open(OpenFlags.ReadOnly);
if (index >= 0 && index < store.Certificates.Count)
{
return store.Certificates[index].Thumbprint;
}
}
}
catch
{
// если ошибка, вернем пустую строку
}
return "";
}
public string GetCertificateIssuer(string storeName, string storeLocation, int index)
{
try
{
using (var store = GetStore(storeName, storeLocation))
{
store.Open(OpenFlags.ReadOnly);
if (index >= 0 && index < store.Certificates.Count)
{
return store.Certificates[index].Issuer;
}
}
}
catch
{
// если ошибка, вернем пустую строку
}
return "";
}
public bool FindCertificateByThumbprint(string storeName, string storeLocation, string thumbprint)
{
try
{
using (var store = GetStore(storeName, storeLocation))
{
store.Open(OpenFlags.ReadOnly);
var collection = store.Certificates.Find(X509FindType.FindByThumbprint, thumbprint, false);
return collection.Count > 0;
}
}
catch
{
return false;
}
}
public string[] GetAllCertificateThumbprints(string storeName, string storeLocation)
{
try
{
using (var store = GetStore(storeName, storeLocation))
{
store.Open(OpenFlags.ReadOnly);
List<string> thumbprints = new List<string>();
foreach (X509Certificate2 cert in store.Certificates)
{
thumbprints.Add(cert.Thumbprint);
}
return thumbprints.ToArray();
}
}
catch
{
return new string[0];
}
}
public bool IsCertificateValid(string storeName, string storeLocation, string thumbprint)
{
try
{
using (var store = GetStore(storeName, storeLocation))
{
store.Open(OpenFlags.ReadOnly);
var collection = store.Certificates.Find(X509FindType.FindByThumbprint, thumbprint, false);
if (collection.Count > 0)
{
var cert = collection[0];
return DateTime.Now >= cert.NotBefore && DateTime.Now <= cert.NotAfter;
}
}
}
catch
{
// если ошибка, вернем false
}
return false;
}
}
}