Commit f65cd0fd authored by titanium007's avatar titanium007

Merge branch 'ArachisH-master'

parents 3ffd1f2c d586a230
using System;
using System.IO;
using System.Diagnostics;
using System.Collections.Generic;
using System.Security.Cryptography.X509Certificates;
namespace Titanium.Web.Proxy.Helpers
{
public class CertificateManager
{
private const string CERT_CREATE_FORMAT =
"-ss {0} -n \"CN={1}, O={2}\" -sky {3} -cy {4} -m 120 -a sha256 -eku 1.3.6.1.5.5.7.3.1 -b {5:MM/dd/yyyy} {6}";
private readonly IDictionary<string, X509Certificate2> _certificateCache;
public string Issuer { get; private set; }
public string RootCertificateName { get; private set; }
public X509Store MyStore { get; private set; }
public X509Store RootStore { get; private set; }
public CertificateManager(string issuer, string rootCertificateName)
{
Issuer = issuer;
RootCertificateName = rootCertificateName;
MyStore = new X509Store(StoreName.My, StoreLocation.CurrentUser);
RootStore = new X509Store(StoreName.Root, StoreLocation.CurrentUser);
_certificateCache = new Dictionary<string, X509Certificate2>();
}
/// <summary>
/// Attempts to move a self-signed certificate to the root store.
/// </summary>
/// <returns>true if succeeded, else false</returns>
public bool CreateTrustedRootCertificate()
{
X509Certificate2 rootCertificate =
CreateCertificate(RootStore, RootCertificateName);
return rootCertificate != null;
}
/// <summary>
/// Attempts to remove the self-signed certificate from the root store.
/// </summary>
/// <returns>true if succeeded, else false</returns>
public bool DestroyTrustedRootCertificate()
{
return DestroyCertificate(RootStore, RootCertificateName);
}
public X509Certificate2Collection FindCertificates(string certificateSubject)
{
return FindCertificates(MyStore, certificateSubject);
}
protected virtual X509Certificate2Collection FindCertificates(X509Store store, string certificateSubject)
{
X509Certificate2Collection discoveredCertificates = store.Certificates
.Find(X509FindType.FindBySubjectDistinguishedName, certificateSubject, false);
return discoveredCertificates.Count > 0 ?
discoveredCertificates : null;
}
public X509Certificate2 CreateCertificate(string certificateName)
{
return CreateCertificate(MyStore, certificateName);
}
protected virtual X509Certificate2 CreateCertificate(X509Store store, string certificateName)
{
if (_certificateCache.ContainsKey(certificateName))
return _certificateCache[certificateName];
lock (store)
{
X509Certificate2 certificate = null;
try
{
store.Open(OpenFlags.ReadWrite);
string certificateSubject = string.Format("CN={0}, O={1}", certificateName, Issuer);
X509Certificate2Collection certificates =
FindCertificates(store, certificateSubject);
if (certificates != null)
certificate = certificates[0];
if (certificate == null)
{
string[] args = new[] {
GetCertificateCreateArgs(store, certificateName) };
CreateCertificate(args);
certificates = FindCertificates(store, certificateSubject);
return certificates != null ?
certificates[0] : null;
}
return certificate;
}
finally
{
store.Close();
if (certificate != null && !_certificateCache.ContainsKey(certificateName))
_certificateCache.Add(certificateName, certificate);
}
}
}
protected virtual void CreateCertificate(string[] args)
{
using (var process = new Process())
{
if (!File.Exists("makecert.exe"))
throw new Exception("Unable to locate 'makecert.exe'.");
process.StartInfo.Verb = "runas";
process.StartInfo.Arguments = args != null ? args[0] : string.Empty;
process.StartInfo.CreateNoWindow = true;
process.StartInfo.UseShellExecute = false;
process.StartInfo.FileName = "makecert.exe";
process.Start();
process.WaitForExit();
}
}
public bool DestroyCertificate(string certificateName)
{
return DestroyCertificate(MyStore, certificateName);
}
protected virtual bool DestroyCertificate(X509Store store, string certificateName)
{
lock (store)
{
X509Certificate2Collection certificates = null;
try
{
store.Open(OpenFlags.ReadWrite);
string certificateSubject = string.Format("CN={0}, O={1}", certificateName, Issuer);
certificates = FindCertificates(store, certificateSubject);
if (certificates != null)
{
store.RemoveRange(certificates);
certificates = FindCertificates(store, certificateSubject);
}
return certificates == null;
}
finally
{
store.Close();
if (certificates == null &&
_certificateCache.ContainsKey(certificateName))
{
_certificateCache.Remove(certificateName);
}
}
}
}
protected virtual string GetCertificateCreateArgs(X509Store store, string certificateName)
{
bool isRootCertificate =
(certificateName == RootCertificateName);
string certCreatArgs = string.Format(CERT_CREATE_FORMAT,
store.Name, certificateName, Issuer,
isRootCertificate ? "signature" : "exchange",
isRootCertificate ? "authority" : "end", DateTime.Now,
isRootCertificate ? "-h 1 -r" : string.Format("-pe -in \"{0}\" -is Root", RootCertificateName));
return certCreatArgs;
}
}
}
\ No newline at end of file
...@@ -53,8 +53,15 @@ namespace Titanium.Web.Proxy ...@@ -53,8 +53,15 @@ namespace Titanium.Web.Proxy
{ {
return ((IPEndPoint)listener.LocalEndpoint).Port; return ((IPEndPoint)listener.LocalEndpoint).Port;
} }
}
public static CertificateManager CertManager { get; set; }
static ProxyServer()
{
CertManager = new CertificateManager("Titanium",
"Titanium Root Certificate Authority");
} }
public ProxyServer() public ProxyServer()
{ {
...@@ -92,8 +99,14 @@ namespace Titanium.Web.Proxy ...@@ -92,8 +99,14 @@ namespace Titanium.Web.Proxy
SystemProxyHelper.EnableProxyHTTP("localhost", ListeningPort); SystemProxyHelper.EnableProxyHTTP("localhost", ListeningPort);
FireFoxHelper.AddFirefox(); FireFoxHelper.AddFirefox();
RootCertificateName = RootCertificateName == null ? "DO_NOT_TRUST_FiddlerRoot" : RootCertificateName; RootCertificateName = RootCertificateName == null ? "DO_NOT_TRUST_FiddlerRoot" : RootCertificateName;
CertificateHelper.InstallCertificate(Path.Combine(System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), string.Concat(RootCertificateName, ".cer")));
bool certTrusted = CertManager.CreateTrustedRootCertificate();
if (!certTrusted)
{
// The user didn't want to install the self-signed certificate to the root store.
}
//CertificateHelper.InstallCertificate(Path.Combine(System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), string.Concat(RootCertificateName, ".cer")));
if (EnableSSL) if (EnableSSL)
{ {
......
...@@ -119,8 +119,8 @@ namespace Titanium.Web.Proxy ...@@ -119,8 +119,8 @@ namespace Titanium.Web.Proxy
return; return;
} }
Monitor.Enter(certificateAccessLock); Monitor.Enter(certificateAccessLock);
var _certificate = CertificateHelper.GetCertificate(RootCertificateName, tunnelHostName); var _certificate = ProxyServer.CertManager.CreateCertificate(tunnelHostName); //CertificateHelper.GetCertificate(RootCertificateName, tunnelHostName);
Monitor.Exit(certificateAccessLock); Monitor.Exit(certificateAccessLock);
SslStream sslStream = null; SslStream sslStream = null;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment