using System;
|
|
using System.IO;
|
|
using System.Security.Cryptography.X509Certificates;
|
|
using System.Security.Permissions;
|
|
using System.Threading;
|
|
using BWP.ABCClient.Exceptions;
|
|
using TSingSoft.WebPluginFramework.TimerTasks;
|
|
|
|
namespace BWP.ABCClient
|
|
{
|
|
public class CertManager
|
|
{
|
|
public static CertManager MainSystemCertManager
|
|
{
|
|
get
|
|
{
|
|
return new CertManager("MainSystemABCCerts");
|
|
}
|
|
}
|
|
|
|
CertManager(string storeName)
|
|
{
|
|
_store = new X509Store(storeName, StoreLocation.LocalMachine);
|
|
new StorePermission(StorePermissionFlags.AllFlags).Assert();
|
|
}
|
|
|
|
private readonly X509Store _store;
|
|
|
|
public CertManager():this("ABCCerts")
|
|
{
|
|
}
|
|
|
|
volatile static object _lockObj = new object();
|
|
|
|
public void SetupPfx(Stream stream, string password)
|
|
{
|
|
if (!Monitor.TryEnter(_lockObj))
|
|
{
|
|
throw new ApplicationException("另一名操作员正在导入证书,请稍后再试");
|
|
}
|
|
try
|
|
{
|
|
_store.Open(OpenFlags.ReadWrite);
|
|
using (var binaryReader = new BinaryReader(stream))
|
|
{
|
|
var bytes = binaryReader.ReadBytes((int)stream.Length);
|
|
var cert = new X509Certificate2(bytes, password);
|
|
if (_store.Certificates.Find(X509FindType.FindBySerialNumber, cert.SerialNumber, false).Count == 0)
|
|
{
|
|
_store.Add(new X509Certificate2(bytes, password, X509KeyStorageFlags.Exportable | X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet));
|
|
}
|
|
}
|
|
_store.Close();
|
|
}
|
|
finally
|
|
{
|
|
Monitor.Exit(_lockObj);
|
|
}
|
|
}
|
|
|
|
public void SetupPfx(string fileName, string password)
|
|
{
|
|
using (var stream = new FileStream(fileName, FileMode.Open, FileAccess.Read))
|
|
{
|
|
SetupPfx(stream, password);
|
|
}
|
|
}
|
|
|
|
public X509Certificate2 Fetch(string merchantID)
|
|
{
|
|
return Fetch(X509FindType.FindBySubjectName, merchantID);
|
|
}
|
|
|
|
public X509Certificate2 Fetch(X509FindType findType, string findValue)
|
|
{
|
|
_store.Open(OpenFlags.ReadOnly);
|
|
var certs = _store.Certificates.Find(findType, findValue, false);
|
|
_store.Close();
|
|
if (certs.Count == 0) {
|
|
throw new RSAException("找不到商户号对应的证书");
|
|
}
|
|
if (certs.Count > 1) {
|
|
throw new RSAException("同一个商户号有多张证书");
|
|
}
|
|
return certs[0];
|
|
}
|
|
|
|
public bool TryFetch(string merchantID, out X509Certificate2 cert)
|
|
{
|
|
cert = null;
|
|
_store.Open(OpenFlags.ReadOnly);
|
|
var certs = _store.Certificates.Find(X509FindType.FindBySubjectName, merchantID, false);
|
|
_store.Close();
|
|
if (certs.Count == 0) {
|
|
return false;
|
|
}
|
|
cert = certs[0];
|
|
return true;
|
|
}
|
|
|
|
public void Remove(string merchantID)
|
|
{
|
|
var cert = Fetch(merchantID);
|
|
_store.Open(OpenFlags.ReadWrite);
|
|
_store.Remove(cert);
|
|
_store.Close();
|
|
}
|
|
|
|
public void Remove(X509Certificate2 cert)
|
|
{
|
|
_store.Open(OpenFlags.ReadWrite);
|
|
_store.Remove(cert);
|
|
_store.Close();
|
|
}
|
|
|
|
public void ClearAll()
|
|
{
|
|
_store.Open(OpenFlags.ReadWrite);
|
|
_store.RemoveRange(_store.Certificates);
|
|
_store.Close();
|
|
}
|
|
|
|
public X509Certificate2Collection FetchAll()
|
|
{
|
|
_store.Open(OpenFlags.ReadWrite);
|
|
var certs = _store.Certificates;
|
|
_store.Close();
|
|
return certs;
|
|
}
|
|
|
|
public void Export(string merchantID, string password, Stream stream)
|
|
{
|
|
var cert = Fetch(merchantID);
|
|
var bytes = cert.Export(X509ContentType.Pfx, password);
|
|
stream.Write(bytes, 0, bytes.Length);
|
|
}
|
|
|
|
public void SetupABCPubKey(string fileName)
|
|
{
|
|
_store.Open(OpenFlags.ReadWrite);
|
|
_store.Add(new X509Certificate2(fileName));
|
|
_store.Close();
|
|
}
|
|
|
|
public X509Certificate2 GetABCPubKey()
|
|
{
|
|
_store.Open(OpenFlags.ReadOnly);
|
|
var certs = _store.Certificates.Find(X509FindType.FindBySerialNumber, "7b97ca10275a0000d99d", false);
|
|
if (certs.Count == 0) {
|
|
throw new RSAException("找不到农行公钥");
|
|
}
|
|
return certs[0];
|
|
}
|
|
|
|
public X509Certificate2 GetABCTestPubKey()
|
|
{
|
|
_store.Open(OpenFlags.ReadOnly);
|
|
var certs = _store.Certificates.Find(X509FindType.FindBySerialNumber, "50 3a ca 10 53 5b 00 00 02 7f", false);
|
|
if (certs.Count == 0) {
|
|
throw new RSAException("找不到农行公钥");
|
|
}
|
|
return certs[0];
|
|
}
|
|
}
|
|
}
|