Commit 298418cf authored by mohammadlachgar's avatar mohammadlachgar

**Add password to rootCert.pfx. and more...

**Save all fake certificates in folder "crts"(will be save in proxy dll directory)
 for can load the certificate and not make new certificate every time .
**Manually load a RootCertificate
parent 6afbec82
...@@ -23,7 +23,7 @@ namespace Titanium.Web.Proxy.Examples.Wpf ...@@ -23,7 +23,7 @@ namespace Titanium.Web.Proxy.Examples.Wpf
private int lastSessionNumber; private int lastSessionNumber;
public ObservableCollection<SessionListItem> Sessions { get; } = new ObservableCollection<SessionListItem>(); public ObservableCollection<SessionListItem> Sessions { get; } = new ObservableCollection<SessionListItem>();
public SessionListItem SelectedSession public SessionListItem SelectedSession
{ {
...@@ -63,8 +63,24 @@ namespace Titanium.Web.Proxy.Examples.Wpf ...@@ -63,8 +63,24 @@ namespace Titanium.Web.Proxy.Examples.Wpf
{ {
proxyServer = new ProxyServer(); proxyServer = new ProxyServer();
//proxyServer.CertificateEngine = CertificateEngine.DefaultWindows; //proxyServer.CertificateEngine = CertificateEngine.DefaultWindows;
proxyServer.TrustRootCertificate = true;
proxyServer.CertificateManager.TrustRootCertificateAsAdministrator(); //add password to rootCert.pfx
//proxyServer.Password_rootCert = "MyPassword";
//save all fake certificates in folder "crts"(will be save in proxy dll directory)
//proxyServer.SaveFakeCertificates = true;
//proxyServer.TrustRootCertificate = true;
//or if you need Load or Create Certificate now. ////// "true" if you need Enable===> Trust the RootCertificate used by this proxy server
proxyServer.EnsureRootCertificate(true);
//proxyServer.CertificateManager.TrustRootCertificateAsAdministrator();
proxyServer.ForwardToUpstreamGateway = true; proxyServer.ForwardToUpstreamGateway = true;
var explicitEndPoint = new ExplicitProxyEndPoint(IPAddress.Any, 8000, true) var explicitEndPoint = new ExplicitProxyEndPoint(IPAddress.Any, 8000, true)
......
using System; using System;
using System.Collections;
using System.IO; using System.IO;
using System.Reflection;
using System.Security.Cryptography.X509Certificates; using System.Security.Cryptography.X509Certificates;
using System.Threading; using System.Threading;
using Org.BouncyCastle.Asn1; using Org.BouncyCastle.Asn1;
...@@ -68,7 +70,7 @@ namespace Titanium.Web.Proxy.Network.Certificate ...@@ -68,7 +70,7 @@ namespace Titanium.Web.Proxy.Network.Certificate
string issuerName, DateTime validFrom, string issuerName, DateTime validFrom,
DateTime validTo, int keyStrength = 2048, DateTime validTo, int keyStrength = 2048,
string signatureAlgorithm = "SHA256WithRSA", string signatureAlgorithm = "SHA256WithRSA",
AsymmetricKeyParameter issuerPrivateKey = null) AsymmetricKeyParameter issuerPrivateKey = null, X509Certificate2 cloneCertificate = null)
{ {
// Generating Random Numbers // Generating Random Numbers
var randomGenerator = new CryptoApiRandomGenerator(); var randomGenerator = new CryptoApiRandomGenerator();
...@@ -98,13 +100,14 @@ namespace Titanium.Web.Proxy.Network.Certificate ...@@ -98,13 +100,14 @@ namespace Titanium.Web.Proxy.Network.Certificate
var subjectAlternativeNamesExtension = new DerSequence(subjectAlternativeNames); var subjectAlternativeNamesExtension = new DerSequence(subjectAlternativeNames);
certificateGenerator.AddExtension(X509Extensions.SubjectAlternativeName.Id, false, subjectAlternativeNamesExtension); certificateGenerator.AddExtension(X509Extensions.SubjectAlternativeName.Id, false, subjectAlternativeNamesExtension);
} }
// Subject Public Key // Subject Public Key
var keyGenerationParameters = new KeyGenerationParameters(secureRandom, keyStrength); var keyGenerationParameters = new KeyGenerationParameters(secureRandom, keyStrength);
var keyPairGenerator = new RsaKeyPairGenerator(); var keyPairGenerator = new RsaKeyPairGenerator();
keyPairGenerator.Init(keyGenerationParameters); keyPairGenerator.Init(keyGenerationParameters);
var subjectKeyPair = keyPairGenerator.GenerateKeyPair(); var subjectKeyPair = keyPairGenerator.GenerateKeyPair();
certificateGenerator.SetPublicKey(subjectKeyPair.Public); certificateGenerator.SetPublicKey(subjectKeyPair.Public);
// Set certificate intended purposes to only Server Authentication // Set certificate intended purposes to only Server Authentication
...@@ -134,7 +137,7 @@ namespace Titanium.Web.Proxy.Network.Certificate ...@@ -134,7 +137,7 @@ namespace Titanium.Web.Proxy.Network.Certificate
rsa.Exponent2, rsa.Coefficient); rsa.Exponent2, rsa.Coefficient);
#if NET45 #if NET45
// Set private key onto certificate instance // Set private key onto certificate instance X509Certificate2
var x509Certificate = new X509Certificate2(certificate.GetEncoded()); var x509Certificate = new X509Certificate2(certificate.GetEncoded());
x509Certificate.PrivateKey = DotNetUtilities.ToRSA(rsaparams); x509Certificate.PrivateKey = DotNetUtilities.ToRSA(rsaparams);
#else #else
...@@ -146,7 +149,7 @@ namespace Titanium.Web.Proxy.Network.Certificate ...@@ -146,7 +149,7 @@ namespace Titanium.Web.Proxy.Network.Certificate
{ {
try try
{ {
x509Certificate.FriendlyName = subjectName; x509Certificate.FriendlyName = System.Text.RegularExpressions.Regex.Replace(subjectName.ToLower(), @"^" + "CN".ToLower() + @"\s*=\s*", "");
} }
catch (PlatformNotSupportedException) catch (PlatformNotSupportedException)
{ {
...@@ -172,7 +175,7 @@ namespace Titanium.Web.Proxy.Network.Certificate ...@@ -172,7 +175,7 @@ namespace Titanium.Web.Proxy.Network.Certificate
return new X509Certificate2(ms.ToArray(), password, X509KeyStorageFlags.Exportable); return new X509Certificate2(ms.ToArray(), password, X509KeyStorageFlags.Exportable);
} }
} }
/// <summary> /// <summary>
/// Makes the certificate internal. /// Makes the certificate internal.
/// </summary> /// </summary>
...@@ -199,11 +202,17 @@ namespace Titanium.Web.Proxy.Network.Certificate ...@@ -199,11 +202,17 @@ namespace Titanium.Web.Proxy.Network.Certificate
} }
else else
{ {
var kp = DotNetUtilities.GetKeyPair(signingCertificate.PrivateKey); var kp = DotNetUtilities.GetKeyPair(signingCertificate.PrivateKey);
return GenerateCertificate(hostName, subjectName, signingCertificate.Subject, validFrom, validTo, issuerPrivateKey: kp.Private); return GenerateCertificate(hostName, subjectName, signingCertificate.Subject, validFrom, validTo, issuerPrivateKey: kp.Private);
} }
} }
/// <summary> /// <summary>
/// Makes the certificate internal. /// Makes the certificate internal.
/// </summary> /// </summary>
......
...@@ -28,6 +28,9 @@ namespace Titanium.Web.Proxy.Network ...@@ -28,6 +28,9 @@ namespace Titanium.Web.Proxy.Network
BouncyCastle = 1 BouncyCastle = 1
} }
/// <summary> /// <summary>
/// A class to manage SSL certificates used by this proxy server /// A class to manage SSL certificates used by this proxy server
/// </summary> /// </summary>
...@@ -57,6 +60,30 @@ namespace Titanium.Web.Proxy.Network ...@@ -57,6 +60,30 @@ namespace Titanium.Web.Proxy.Network
} }
} }
private bool trustRootCertificate;
public bool TrustrootCertificate
{
get => trustRootCertificate;
set
{
trustRootCertificate = value;
}
}
private bool saveCertificate;
public bool SaveCertificate
{
get => saveCertificate;
set
{
saveCertificate = value;
}
}
private const string defaultRootCertificateIssuer = "Titanium"; private const string defaultRootCertificateIssuer = "Titanium";
private const string defaultRootRootCertificateName = "Titanium Root Certificate Authority"; private const string defaultRootRootCertificateName = "Titanium Root Certificate Authority";
...@@ -73,6 +100,8 @@ namespace Titanium.Web.Proxy.Network ...@@ -73,6 +100,8 @@ namespace Titanium.Web.Proxy.Network
private X509Certificate2 rootCertificate; private X509Certificate2 rootCertificate;
public bool only_load_rootCert { get; set; }
/// <summary> /// <summary>
/// Cache dictionary /// Cache dictionary
/// </summary> /// </summary>
...@@ -80,13 +109,14 @@ namespace Titanium.Web.Proxy.Network ...@@ -80,13 +109,14 @@ namespace Titanium.Web.Proxy.Network
private readonly Action<Exception> exceptionFunc; private readonly Action<Exception> exceptionFunc;
internal string Issuer internal string Issuer
{ {
get => issuer ?? defaultRootCertificateIssuer; get => issuer ?? defaultRootCertificateIssuer;
set set
{ {
issuer = value; issuer = value;
ClearRootCertificate(); //ClearRootCertificate();
} }
} }
...@@ -96,7 +126,7 @@ namespace Titanium.Web.Proxy.Network ...@@ -96,7 +126,7 @@ namespace Titanium.Web.Proxy.Network
set set
{ {
rootCertificateName = value; rootCertificateName = value;
ClearRootCertificate(); //ClearRootCertificate();
} }
} }
...@@ -110,6 +140,18 @@ namespace Titanium.Web.Proxy.Network ...@@ -110,6 +140,18 @@ namespace Titanium.Web.Proxy.Network
} }
} }
private string password_rootCert = string.Empty;
public string Password_rootCert
{
get => password_rootCert;
set
{
password_rootCert = value;
}
}
/// <summary> /// <summary>
/// Is the root certificate used by this proxy is valid? /// Is the root certificate used by this proxy is valid?
/// </summary> /// </summary>
...@@ -124,13 +166,14 @@ namespace Titanium.Web.Proxy.Network ...@@ -124,13 +166,14 @@ namespace Titanium.Web.Proxy.Network
certificateCache = new ConcurrentDictionary<string, CachedCertificate>(); certificateCache = new ConcurrentDictionary<string, CachedCertificate>();
} }
private void ClearRootCertificate() public void ClearRootCertificate()
{ {
certificateCache.Clear(); certificateCache.Clear();
rootCertificate = null; rootCertificate = null;
} }
private string GetRootCertificatePath()
private string GetRootCertificateDirectory()
{ {
string assemblyLocation = Assembly.GetExecutingAssembly().Location; string assemblyLocation = Assembly.GetExecutingAssembly().Location;
...@@ -143,18 +186,43 @@ namespace Titanium.Web.Proxy.Network ...@@ -143,18 +186,43 @@ namespace Titanium.Web.Proxy.Network
string path = Path.GetDirectoryName(assemblyLocation); string path = Path.GetDirectoryName(assemblyLocation);
if (null == path) if (null == path)
throw new NullReferenceException(); throw new NullReferenceException();
return path;
}
private string GetCertPath()
{
string path = GetRootCertificateDirectory();
string certPath = Path.Combine(path, "crts");
if (!Directory.Exists(certPath)) { Directory.CreateDirectory(certPath); }
return certPath;
}
private string GetRootCertificatePath()
{
string path = GetRootCertificateDirectory();
string fileName = Path.Combine(path, "rootCert.pfx"); string fileName = Path.Combine(path, "rootCert.pfx");
return fileName; return fileName;
} }
private X509Certificate2 LoadRootCertificate() public X509Certificate2 LoadRootCertificate()
{ {
string fileName = GetRootCertificatePath(); string fileName = filename_loadx;
if (/*(fileName.Trim().Length<=0)||*/ (fileName == string.Empty))
{
fileName = GetRootCertificatePath();
passwordx = password_rootCert; /*string.Empty;*/
StorageFlag = X509KeyStorageFlags.Exportable;
}
if (!File.Exists(fileName)) if (!File.Exists(fileName))
return null; return null;
try try
{ {
return new X509Certificate2(fileName, string.Empty, X509KeyStorageFlags.Exportable); //return new X509Certificate2(fileName, string.Empty, X509KeyStorageFlags.Exportable);
return new X509Certificate2(fileName, passwordx, StorageFlag);
} }
catch (Exception e) catch (Exception e)
{ {
...@@ -163,6 +231,12 @@ namespace Titanium.Web.Proxy.Network ...@@ -163,6 +231,12 @@ namespace Titanium.Web.Proxy.Network
} }
} }
/// <summary> /// <summary>
/// Attempts to create a RootCertificate /// Attempts to create a RootCertificate
/// </summary> /// </summary>
...@@ -174,17 +248,30 @@ namespace Titanium.Web.Proxy.Network ...@@ -174,17 +248,30 @@ namespace Titanium.Web.Proxy.Network
{ {
if (persistToFile && RootCertificate == null) if (persistToFile && RootCertificate == null)
{ {
RootCertificate = LoadRootCertificate(); RootCertificate = LoadRootCertificate();
} }
if (RootCertificate != null) if (RootCertificate != null)
{ {
return true; return true;
} }
else
{
if (only_load_rootCert == true)
{
return false;
}
}
try try
{ {
RootCertificate = CreateCertificate(RootCertificateName, true); RootCertificate = CreateCertificate(RootCertificateName, true);
} }
catch (Exception e) catch (Exception e)
{ {
...@@ -195,8 +282,16 @@ namespace Titanium.Web.Proxy.Network ...@@ -195,8 +282,16 @@ namespace Titanium.Web.Proxy.Network
{ {
try try
{ {
try
{
Directory.Delete(GetCertPath(), true);
}
catch { }
string fileName = GetRootCertificatePath(); string fileName = GetRootCertificatePath();
File.WriteAllBytes(fileName, RootCertificate.Export(X509ContentType.Pkcs12)); File.WriteAllBytes(fileName, RootCertificate.Export(X509ContentType.Pkcs12, password_rootCert));
} }
catch (Exception e) catch (Exception e)
{ {
...@@ -204,9 +299,54 @@ namespace Titanium.Web.Proxy.Network ...@@ -204,9 +299,54 @@ namespace Titanium.Web.Proxy.Network
} }
} }
return RootCertificate != null; return RootCertificate != null;
} }
/// <summary>
/// Attempts to Manually load a RootCertificate
/// set password and path_fileCertificate
/// </summary>
/// <returns>
/// true if succeeded, else false
/// </returns>
public void SetInfo_LoadRootCertificate(string fileName, string passwordx, X509KeyStorageFlags StorageFlag = X509KeyStorageFlags.Exportable)
{
filename_loadx = fileName;
this.passwordx = passwordx;
this.StorageFlag = StorageFlag;
only_load_rootCert = true;
}
/// <summary>
/// Attempts to Manually load a RootCertificate
/// </summary>
/// <returns>
/// true if succeeded, else false
/// </returns>
public bool LoadRootCertificate(string fileName, string passwordx, X509KeyStorageFlags StorageFlag = X509KeyStorageFlags.Exportable)
{
filename_loadx = fileName;
this.passwordx = passwordx;
this.StorageFlag = StorageFlag;
only_load_rootCert = true;
RootCertificate = LoadRootCertificate();
return (RootCertificate != null);
}
private string passwordx = string.Empty;
private string filename_loadx = "";
X509KeyStorageFlags StorageFlag = X509KeyStorageFlags.Exportable;
/// <summary> /// <summary>
/// Trusts the root certificate. /// Trusts the root certificate.
/// </summary> /// </summary>
...@@ -219,6 +359,9 @@ namespace Titanium.Web.Proxy.Network ...@@ -219,6 +359,9 @@ namespace Titanium.Web.Proxy.Network
TrustRootCertificate(StoreLocation.LocalMachine); TrustRootCertificate(StoreLocation.LocalMachine);
} }
/// <summary> /// <summary>
/// Puts the certificate to the local machine's certificate store. /// Puts the certificate to the local machine's certificate store.
/// Needs elevated permission. Works only on Windows. /// Needs elevated permission. Works only on Windows.
...@@ -232,12 +375,12 @@ namespace Titanium.Web.Proxy.Network ...@@ -232,12 +375,12 @@ namespace Titanium.Web.Proxy.Network
} }
string fileName = Path.GetTempFileName(); string fileName = Path.GetTempFileName();
File.WriteAllBytes(fileName, RootCertificate.Export(X509ContentType.Pkcs12)); File.WriteAllBytes(fileName, RootCertificate.Export(X509ContentType.Pkcs12, password_rootCert));
var info = new ProcessStartInfo var info = new ProcessStartInfo
{ {
FileName = "certutil.exe", FileName = "certutil.exe",
Arguments = "-importPFX -p \"\" -f \"" + fileName + "\"", Arguments = "-importPFX -p \"" + password_rootCert + "\" -f \"" + fileName + "\"",
CreateNoWindow = true, CreateNoWindow = true,
UseShellExecute = true, UseShellExecute = true,
Verb = "runas", Verb = "runas",
...@@ -352,6 +495,17 @@ namespace Titanium.Web.Proxy.Network ...@@ -352,6 +495,17 @@ namespace Titanium.Web.Proxy.Network
} }
} }
private X509Certificate2 makeCertificate(string certificateName, bool isRootCertificate)
{
if (!isRootCertificate && RootCertificate == null)
{
CreateTrustedRootCertificate();
}
return certEngine.MakeCertificate(certificateName, isRootCertificate, RootCertificate);
}
/// <summary> /// <summary>
/// Create an SSL certificate /// Create an SSL certificate
/// </summary> /// </summary>
...@@ -374,12 +528,44 @@ namespace Titanium.Web.Proxy.Network ...@@ -374,12 +528,44 @@ namespace Titanium.Web.Proxy.Network
{ {
try try
{ {
if (!isRootCertificate && RootCertificate == null)
//if (!isRootCertificate && RootCertificate == null)
// {
// CreateTrustedRootCertificate();
// }
if ((isRootCertificate == false) && (saveCertificate == true))
{
string path = GetCertPath();
string subjectName = System.Text.RegularExpressions.Regex.Replace(certificateName.ToLower(), @"^" + "CN".ToLower() + @"\s*=\s*", "");
subjectName = subjectName.Replace("*", "$x$");
subjectName = Path.Combine(path, subjectName + ".pfx");
if (!File.Exists(subjectName))
{
certificate = this.makeCertificate(certificateName, isRootCertificate);
File.WriteAllBytes(subjectName, certificate.Export(X509ContentType.Pkcs12));
}
else
{
try
{
certificate = new X509Certificate2(subjectName, string.Empty, StorageFlag);
}
catch/* (Exception e)*/
{
certificate = this.makeCertificate(certificateName, isRootCertificate);
}
}
}
else
{ {
CreateTrustedRootCertificate();
certificate = this.makeCertificate(certificateName, isRootCertificate);
} }
certificate = certEngine.MakeCertificate(certificateName, isRootCertificate, RootCertificate);
} }
catch (Exception e) catch (Exception e)
{ {
...@@ -402,7 +588,7 @@ namespace Titanium.Web.Proxy.Network ...@@ -402,7 +588,7 @@ namespace Titanium.Web.Proxy.Network
return cached.Certificate; return cached.Certificate;
} }
} }
} }
return certificate; return certificate;
} }
...@@ -475,6 +661,7 @@ namespace Titanium.Web.Proxy.Network ...@@ -475,6 +661,7 @@ namespace Titanium.Web.Proxy.Network
} }
} }
/// <summary> /// <summary>
/// Remove the Root Certificate trust /// Remove the Root Certificate trust
/// </summary> /// </summary>
...@@ -488,6 +675,7 @@ namespace Titanium.Web.Proxy.Network ...@@ -488,6 +675,7 @@ namespace Titanium.Web.Proxy.Network
new Exception("Could not set root certificate" new Exception("Could not set root certificate"
+ " as system proxy since it is null or empty.")); + " as system proxy since it is null or empty."));
return; return;
} }
......
...@@ -42,6 +42,16 @@ namespace Titanium.Web.Proxy ...@@ -42,6 +42,16 @@ namespace Titanium.Web.Proxy
/// </summary> /// </summary>
private bool trustRootCertificate; private bool trustRootCertificate;
private bool saveCertificate = false;
/// <summary>
/// Password for export and load rootCert.pfx
/// </summary>
private string password_rootCert = string.Empty;
/// <summary> /// <summary>
/// Backing field for corresponding public property /// Backing field for corresponding public property
/// </summary> /// </summary>
...@@ -122,13 +132,46 @@ namespace Titanium.Web.Proxy ...@@ -122,13 +132,46 @@ namespace Titanium.Web.Proxy
set set
{ {
trustRootCertificate = value; trustRootCertificate = value;
if (value) CertificateManager.TrustrootCertificate = trustRootCertificate;
{ //if (value)
EnsureRootCertificate(); //{
} ////convert to public function
///now, "Manually" call this function===> EnsureRootCertificate();
//
//}
} }
} }
/// <summary>
/// Save all fake certificates in folder "crts"(will be save in proxy dll directory)
/// for can load the certificate and not make new certificate every time
/// </summary>
public bool SaveFakeCertificates
{
get => saveCertificate;
set
{
saveCertificate = value;
CertificateManager.SaveCertificate = saveCertificate;
}
}
/// <summary>
/// add password to rootCert.pfx
/// </summary>
public string Password_rootCert
{
get => this.password_rootCert;
set
{
this.password_rootCert = value;
CertificateManager.Password_rootCert = this.password_rootCert;
}
}
/// <summary> /// <summary>
/// Select Certificate Engine /// Select Certificate Engine
/// Optionally set to BouncyCastle /// Optionally set to BouncyCastle
...@@ -331,6 +374,7 @@ namespace Titanium.Web.Proxy ...@@ -331,6 +374,7 @@ namespace Titanium.Web.Proxy
/// <param name="endPoint"></param> /// <param name="endPoint"></param>
public void AddEndPoint(ProxyEndPoint endPoint) public void AddEndPoint(ProxyEndPoint endPoint)
{ {
if (ProxyEndPoints.Any(x => x.IpAddress.Equals(endPoint.IpAddress) && endPoint.Port != 0 && x.Port == endPoint.Port)) if (ProxyEndPoints.Any(x => x.IpAddress.Equals(endPoint.IpAddress) && endPoint.Port != 0 && x.Port == endPoint.Port))
{ {
throw new Exception("Cannot add another endpoint to same port & ip address"); throw new Exception("Cannot add another endpoint to same port & ip address");
...@@ -406,7 +450,6 @@ namespace Titanium.Web.Proxy ...@@ -406,7 +450,6 @@ namespace Titanium.Web.Proxy
{ {
throw new Exception("Endpoint do not support Https connections"); throw new Exception("Endpoint do not support Https connections");
} }
EnsureRootCertificate(); EnsureRootCertificate();
//If certificate was trusted by the machine //If certificate was trusted by the machine
...@@ -520,6 +563,18 @@ namespace Titanium.Web.Proxy ...@@ -520,6 +563,18 @@ namespace Titanium.Web.Proxy
throw new Exception("Proxy is already running."); throw new Exception("Proxy is already running.");
} }
try
{
if (ProxyEndPoints.Any(x => (x as ExplicitProxyEndPoint).GenericCertificate == null))
{
EnsureRootCertificate();
}
}
catch
{
}
//clear any system proxy settings which is pointing to our own endpoint (causing a cycle) //clear any system proxy settings which is pointing to our own endpoint (causing a cycle)
//due to non gracious proxy shutdown before or something else //due to non gracious proxy shutdown before or something else
if (systemProxySettingsManager != null && RunTime.IsWindows) if (systemProxySettingsManager != null && RunTime.IsWindows)
...@@ -692,10 +747,21 @@ namespace Titanium.Web.Proxy ...@@ -692,10 +747,21 @@ namespace Titanium.Web.Proxy
return Task.FromResult(proxy); return Task.FromResult(proxy);
} }
private void EnsureRootCertificate() /// <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>
/// </summary>
public void EnsureRootCertificate(bool TrustRootCertificate)
{
this.TrustRootCertificate = TrustRootCertificate;
EnsureRootCertificate();
}
public void EnsureRootCertificate()
{ {
if (!CertificateManager.CertValidated) if (!CertificateManager.CertValidated)
{ {
CertificateManager.CreateTrustedRootCertificate(); CertificateManager.CreateTrustedRootCertificate();
if (TrustRootCertificate) if (TrustRootCertificate)
...@@ -705,6 +771,8 @@ namespace Titanium.Web.Proxy ...@@ -705,6 +771,8 @@ namespace Titanium.Web.Proxy
} }
} }
/// <summary> /// <summary>
/// When a connection is received from client act /// When a connection is received from client act
/// </summary> /// </summary>
......
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