Commit 992886a3 authored by Honfika's avatar Honfika

fixes

parent 625db8ed
......@@ -65,13 +65,13 @@ namespace Titanium.Web.Proxy.Examples.Wpf
//proxyServer.CertificateEngine = CertificateEngine.DefaultWindows;
////Set a password for the .pfx file
//proxyServer.PasswordPFX = "PfxPassword";
//proxyServer.PfxPassword = "PfxPassword";
////Set Name(path) of the Root certificate file
//proxyServer.NamePFXfile = @"C:\NameFolder\rootCert.pfx";
//proxyServer.PfxFilePath = @"C:\NameFolder\rootCert.pfx";
////do you want Replace an existing Root certificate file(.pfx) if password is incorrect(RootCertificate=null)? yes====>true
//proxyServer.OverwritePFXfile = true;
//proxyServer.OverwritePfxFile = true;
////save all fake certificates in folder "crts"(will be created in proxy dll directory)
////if create new Root certificate file(.pfx) ====> delete folder "crts"
......@@ -83,19 +83,18 @@ namespace Titanium.Web.Proxy.Examples.Wpf
////if you need Load or Create Certificate now. ////// "true" if you need Enable===> Trust the RootCertificate used by this proxy server
//proxyServer.EnsureRootCertificate(true);
//or load directly certificate(As Administrator if need this)
//and At the same time chose path and password
//if password is incorrect and (overwriteRootCert=true)(RootCertificate=null) ====> replace an existing .pfx file
//note : load now (if existed)
////or load directly certificate(As Administrator if need this)
////and At the same time chose path and password
////if password is incorrect and (overwriteRootCert=true)(RootCertificate=null) ====> replace an existing .pfx file
////note : load now (if existed)
//proxyServer.CertificateManager.LoadRootCertificate(@"C:\NameFolder\rootCert.pfx", "PfxPassword");
//proxyServer.CertificateManager.TrustRootCertificateAsAdministrator();
//proxyServer.ForwardToUpstreamGateway = true;
proxyServer.CertificateManager.TrustRootCertificateAsAdministrator();
proxyServer.ForwardToUpstreamGateway = true;
var explicitEndPoint = new ExplicitProxyEndPoint(IPAddress.Any, 8000, true)
{
//ExcludedHttpsHostNameRegex = new[] { "ssllabs.com" },
ExcludedHttpsHostNameRegex = new[] { "ssllabs.com" },
//IncludedHttpsHostNameRegex = new string[0],
};
......@@ -114,7 +113,8 @@ namespace Titanium.Web.Proxy.Examples.Wpf
proxyServer.TunnelConnectResponse += ProxyServer_TunnelConnectResponse;
proxyServer.ClientConnectionCountChanged += delegate { Dispatcher.Invoke(() => { ClientConnectionCount = proxyServer.ClientConnectionCount; }); };
proxyServer.ServerConnectionCountChanged += delegate { Dispatcher.Invoke(() => { ServerConnectionCount = proxyServer.ServerConnectionCount; }); };
proxyServer.Start();
proxyServer.Start();
proxyServer.SetAsSystemProxy(explicitEndPoint, ProxyProtocolType.AllHttp);
InitializeComponent();
......
using System;
using System.IO;
using System.Security.Cryptography.X509Certificates;
using System.Text.RegularExpressions;
using System.Threading;
using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Asn1.Pkcs;
......@@ -24,6 +25,8 @@ namespace Titanium.Web.Proxy.Network.Certificate
/// </summary>
internal class BCCertificateMaker : ICertificateMaker
{
public static readonly Regex CNRemoverRegex = new Regex(@"^CN\s*=\s*", RegexOptions.IgnoreCase | RegexOptions.Compiled);
private const int certificateValidDays = 1825;
private const int certificateGraceDays = 366;
......@@ -146,7 +149,7 @@ namespace Titanium.Web.Proxy.Network.Certificate
{
try
{
x509Certificate.FriendlyName = System.Text.RegularExpressions.Regex.Replace(subjectName, @"^CN\s*=\s*", "", System.Text.RegularExpressions.RegexOptions.IgnoreCase);
x509Certificate.FriendlyName = CNRemoverRegex.Replace(subjectName, string.Empty);
}
catch (PlatformNotSupportedException)
{
......
......@@ -69,7 +69,7 @@ namespace Titanium.Web.Proxy.Network
private string rootCertificateName;
private bool PFXfileExists = false;
private bool pfxFileExists = false;
private bool clearCertificates { get; set; }
......@@ -77,15 +77,15 @@ namespace Titanium.Web.Proxy.Network
internal bool trustRootCertificate { get; set; } = false;
internal bool overwritePFXfile { get; set; } = true;
internal bool OverwritePfXFile { get; set; } = true;
internal string passwordpfx { get; set; } = string.Empty;
internal string PfxPassword { get; set; } = string.Empty;
internal string namePFXfile { get; set; } = string.Empty;
internal string PfxFilePath { get; set; } = string.Empty;
internal X509KeyStorageFlags storageFlag { get; set; } = X509KeyStorageFlags.Exportable;
internal X509KeyStorageFlags StorageFlag { get; set; } = X509KeyStorageFlags.Exportable;
internal bool saveFakeCertificates { get; set; }=false;
internal bool SaveFakeCertificates { get; set; } = false;
/// <summary>
/// Cache dictionary
......@@ -156,6 +156,7 @@ namespace Titanium.Web.Proxy.Network
string path = Path.GetDirectoryName(assemblyLocation);
if (null == path)
throw new NullReferenceException();
return path;
}
......@@ -164,7 +165,11 @@ namespace Titanium.Web.Proxy.Network
string path = GetRootCertificateDirectory();
string certPath = Path.Combine(path, "crts");
if (!Directory.Exists(certPath)) { Directory.CreateDirectory(certPath); }
if (!Directory.Exists(certPath))
{
Directory.CreateDirectory(certPath);
}
return certPath;
}
......@@ -172,28 +177,28 @@ namespace Titanium.Web.Proxy.Network
{
string path = GetRootCertificateDirectory();
string fileName = namePFXfile;
if ((fileName == string.Empty))
string fileName = PfxFilePath;
if (fileName == string.Empty)
{
fileName = Path.Combine(path, "rootCert.pfx");
storageFlag = X509KeyStorageFlags.Exportable;
StorageFlag = X509KeyStorageFlags.Exportable;
}
return fileName;
}
public X509Certificate2 LoadRootCertificate()
{
string fileName = GetRootCertificatePath();
this.PFXfileExists = File.Exists(fileName);
if (!this.PFXfileExists)
pfxFileExists = File.Exists(fileName);
if (!pfxFileExists)
{
return null;
}
try
{
//return new X509Certificate2(fileName, string.Empty, X509KeyStorageFlags.Exportable);
return new X509Certificate2(fileName, passwordpfx, storageFlag);
return new X509Certificate2(fileName, PfxPassword, StorageFlag);
}
catch (Exception e)
{
......@@ -213,21 +218,17 @@ namespace Titanium.Web.Proxy.Network
{
if (persistToFile && RootCertificate == null)
{
RootCertificate = LoadRootCertificate();
RootCertificate = LoadRootCertificate();
}
if (RootCertificate != null)
{
return true;
}
else
if (!OverwritePfXFile && pfxFileExists)
{
if ((overwritePFXfile == false) && (PFXfileExists == true))
{
return false;
}
return false;
}
try
......@@ -243,36 +244,43 @@ namespace Titanium.Web.Proxy.Network
{
try
{
try {
Directory.Delete(GetCertPath(), true);
} catch { }
try
{
Directory.Delete(GetCertPath(), true);
}
catch
{
// ignore
}
string fileName = GetRootCertificatePath();
File.WriteAllBytes(fileName, RootCertificate.Export(X509ContentType.Pkcs12, passwordpfx));
File.WriteAllBytes(fileName, RootCertificate.Export(X509ContentType.Pkcs12, PfxPassword));
}
catch (Exception e)
{
exceptionFunc(e);
}
}
return RootCertificate != null;
}
/// <summary>
/// Manually load a Root certificate file(.pfx file)
/// </summary>
/// <param name="namePFXfile">Set the name(path) of the .pfx file. If it is string.Empty Root certificate file will be named as "rootCert.pfx" (and will be saved in proxy dll directory)</param>
/// <param name="pfxFilePath">Set the name(path) of the .pfx file. If it is string.Empty Root certificate file will be named as "rootCert.pfx" (and will be saved in proxy dll directory)</param>
/// <param name="password">Set a password for the .pfx file</param>
/// <param name="overwritePFXfile">true : replace an existing .pfx file if password is incorect or if RootCertificate==null</param>
/// <param name="StorageFlag"></param>
/// <param name="overwritePfXFile">true : replace an existing .pfx file if password is incorect or if RootCertificate==null</param>
/// <param name="storageFlag"></param>
/// <returns>
/// true if succeeded, else false
/// </returns>
public bool LoadRootCertificate(string namePFXfile, string password, bool overwritePFXfile = true, X509KeyStorageFlags StorageFlag = X509KeyStorageFlags.Exportable)
public bool LoadRootCertificate(string pfxFilePath, string password, bool overwritePfXFile = true, X509KeyStorageFlags storageFlag = X509KeyStorageFlags.Exportable)
{
this.namePFXfile = namePFXfile;
this.passwordpfx = password;
this.overwritePFXfile = overwritePFXfile;
this.storageFlag = StorageFlag;
PfxFilePath = pfxFilePath;
PfxPassword = password;
OverwritePfXFile = overwritePfXFile;
StorageFlag = storageFlag;
RootCertificate = LoadRootCertificate();
......@@ -304,12 +312,12 @@ namespace Titanium.Web.Proxy.Network
}
string fileName = Path.GetTempFileName();
File.WriteAllBytes(fileName, RootCertificate.Export(X509ContentType.Pkcs12, passwordpfx));
File.WriteAllBytes(fileName, RootCertificate.Export(X509ContentType.Pkcs12, PfxPassword));
var info = new ProcessStartInfo
{
FileName = "certutil.exe",
Arguments = "-importPFX -p \""+ passwordpfx + "\" -f \"" + fileName + "\"",
Arguments = "-importPFX -p \""+ PfxPassword + "\" -f \"" + fileName + "\"",
CreateNoWindow = true,
UseShellExecute = true,
Verb = "runas",
......@@ -424,12 +432,13 @@ namespace Titanium.Web.Proxy.Network
}
}
private X509Certificate2 makeCertificate(string certificateName, bool isRootCertificate)
private X509Certificate2 MakeCertificate(string certificateName, bool isRootCertificate)
{
if (!isRootCertificate && RootCertificate == null)
{
CreateTrustedRootCertificate();
}
return certEngine.MakeCertificate(certificateName, isRootCertificate, RootCertificate);
}
......@@ -455,36 +464,40 @@ namespace Titanium.Web.Proxy.Network
{
try
{
if ((isRootCertificate == false) && (saveFakeCertificates == true)) {
string path = GetCertPath();
string subjectName = System.Text.RegularExpressions.Regex.Replace(certificateName, @"^CN\s*=\s*", "", System.Text.RegularExpressions.RegexOptions.IgnoreCase);
if (!isRootCertificate && SaveFakeCertificates)
{
string path = GetCertPath();
string subjectName = BCCertificateMaker.CNRemoverRegex.Replace(certificateName, string.Empty);
subjectName = subjectName.Replace("*", "$x$");
subjectName= Path.Combine(path, subjectName+ ".pfx");
subjectName = Path.Combine(path, subjectName + ".pfx");
if (!File.Exists(subjectName))
{
certificate = this.makeCertificate(certificateName, isRootCertificate);
certificate = MakeCertificate(certificateName, isRootCertificate);
File.WriteAllBytes(subjectName, certificate.Export(X509ContentType.Pkcs12));
}
else
{
try
{
certificate = new X509Certificate2(subjectName, string.Empty, storageFlag);
certificate = new X509Certificate2(subjectName, string.Empty, StorageFlag);
}
catch/* (Exception e)*/
catch /* (Exception e)*/
{
certificate = this.makeCertificate(certificateName, isRootCertificate);
certificate = MakeCertificate(certificateName, isRootCertificate);
}
}
}
else {
certificate = this.makeCertificate(certificateName, isRootCertificate);
else
{
certificate = MakeCertificate(certificateName, isRootCertificate);
}
}
catch (Exception e)
{
exceptionFunc(e);
}
if (certificate != null && !certificateCache.ContainsKey(certificateName))
{
certificateCache.Add(certificateName, new CachedCertificate
......@@ -502,7 +515,7 @@ namespace Titanium.Web.Proxy.Network
return cached.Certificate;
}
}
}
}
return certificate;
}
......
......@@ -17,7 +17,7 @@ namespace Titanium.Web.Proxy.Network.Tcp
/// <param name="tcpRows">TcpRow collection to initialize with.</param>
internal TcpTable(IEnumerable<TcpRow> tcpRows)
{
this.TcpRows = tcpRows;
TcpRows = tcpRows;
}
/// <summary>
......
......@@ -47,24 +47,8 @@ namespace Titanium.Web.Proxy
/// </summary>
private int serverConnectionCount;
/// <summary>
/// Backing field for corresponding public property
/// </summary>
private bool trustRootCertificate = false;
private bool overwritePFXfile = true;
/// <summary>
/// Password for export and load rootCert.pfx
/// </summary>
private string passwordPFX = string.Empty;
private string namePFXfile = string.Empty;
private X509KeyStorageFlags storageFlag = X509KeyStorageFlags.Exportable;
private bool saveFakeCertificates = false;
/// <summary>
/// A object that creates tcp connection to server
/// </summary>
......@@ -131,12 +115,8 @@ namespace Titanium.Web.Proxy
/// </summary>
public bool TrustRootCertificate
{
get => trustRootCertificate;
set
{
trustRootCertificate = value;
CertificateManager.trustRootCertificate = trustRootCertificate;
}
get => CertificateManager.trustRootCertificate;
set => CertificateManager.trustRootCertificate = value;
}
/// <summary>
......@@ -145,54 +125,38 @@ namespace Titanium.Web.Proxy
/// </summary>
public bool SaveFakeCertificates
{
get => saveFakeCertificates;
set
{
saveFakeCertificates = value;
CertificateManager.saveFakeCertificates = saveFakeCertificates;
}
get => CertificateManager.SaveFakeCertificates;
set => CertificateManager.SaveFakeCertificates = value;
}
/// <summary>
/// Overwrite Root certificate file
/// <para>true : replace an existing .pfx file if password is incorect or if RootCertificate = null</para>
/// </summary>
public bool OverwritePFXfile
public bool OverwritePfxFile
{
get => overwritePFXfile;
set
{
overwritePFXfile = value;
CertificateManager.overwritePFXfile = this.overwritePFXfile;
}
get => CertificateManager.OverwritePfXFile;
set => CertificateManager.OverwritePfXFile = value;
}
/// <summary>
/// Password of the Root certificate file
/// <para>Set a password for the .pfx file</para>
/// </summary>
public string PasswordPFX
public string PfxPassword
{
get => passwordPFX;
set
{
passwordPFX = value;
CertificateManager.passwordpfx = this.passwordPFX;
}
get => CertificateManager.PfxPassword;
set => CertificateManager.PfxPassword = value;
}
/// <summary>
/// Name(path) of the Root certificate file
/// <para>Set the name(path) of the .pfx file. If it is string.Empty Root certificate file will be named as "rootCert.pfx" (and will be saved in proxy dll directory)</para>
/// </summary>
public string NamePFXfile
public string PfxFilePath
{
get => namePFXfile;
set
{
namePFXfile = value;
CertificateManager.namePFXfile = this.namePFXfile;
}
get => CertificateManager.PfxFilePath;
set => CertificateManager.PfxFilePath = value;
}
public X509KeyStorageFlags StorageFlag
......@@ -201,7 +165,7 @@ namespace Titanium.Web.Proxy
set
{
storageFlag = value;
CertificateManager.storageFlag = this.storageFlag;
CertificateManager.StorageFlag = storageFlag;
}
}
......@@ -480,7 +444,8 @@ namespace Titanium.Web.Proxy
if (!endPoint.EnableSsl)
{
throw new Exception("Endpoint do not support Https connections");
}
}
EnsureRootCertificate();
//If certificate was trusted by the machine
......@@ -772,11 +737,11 @@ namespace Titanium.Web.Proxy
/// <summary>
/// Load or Create Certificate : after "Test Is the root certificate used by this proxy is valid?"
/// <param name="TrustRootCertificate">"Make current machine trust the Root Certificate used by this proxy" ==> True or False</param>
/// <param name="trustRootCertificate">"Make current machine trust the Root Certificate used by this proxy" ==> True or False</param>
/// </summary>
public void EnsureRootCertificate(bool TrustRootCertificate)
public void EnsureRootCertificate(bool trustRootCertificate)
{
this.TrustRootCertificate = TrustRootCertificate;
TrustRootCertificate = trustRootCertificate;
EnsureRootCertificate();
}
......
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