Commit 14087ba5 authored by Honfika's avatar Honfika

add timeout to WinCert maker, too. Try-catch added

parent aa3a0147
...@@ -32,6 +32,13 @@ namespace Titanium.Web.Proxy.Network.Certificate ...@@ -32,6 +32,13 @@ namespace Titanium.Web.Proxy.Network.Certificate
// Set this flag to true when exception detected to avoid further exceptions // Set this flag to true when exception detected to avoid further exceptions
private static bool doNotSetFriendlyName; private static bool doNotSetFriendlyName;
private readonly Action<Exception> exceptionFunc;
internal BCCertificateMaker(Action<Exception> exceptionFunc)
{
this.exceptionFunc = exceptionFunc;
}
/// <summary> /// <summary>
/// Makes the certificate. /// Makes the certificate.
/// </summary> /// </summary>
...@@ -198,11 +205,18 @@ namespace Titanium.Web.Proxy.Network.Certificate ...@@ -198,11 +205,18 @@ namespace Titanium.Web.Proxy.Network.Certificate
{ {
ThreadPool.QueueUserWorkItem(o => ThreadPool.QueueUserWorkItem(o =>
{ {
certificate = MakeCertificateInternal(subject, isRoot, false, signingCert); try
{
certificate = MakeCertificateInternal(subject, isRoot, false, signingCert);
}
catch (Exception ex)
{
exceptionFunc.Invoke(new Exception("Failed to create BC certificate", ex));
}
if (!cancellationToken.IsCancellationRequested) if (!cancellationToken.IsCancellationRequested)
{ {
manualResetEvent?.Set(); manualResetEvent.Set();
} }
}); });
......
...@@ -43,11 +43,14 @@ namespace Titanium.Web.Proxy.Network.Certificate ...@@ -43,11 +43,14 @@ namespace Titanium.Web.Proxy.Network.Certificate
private object sharedPrivateKey; private object sharedPrivateKey;
private readonly Action<Exception> exceptionFunc;
/// <summary> /// <summary>
/// Constructor. /// Constructor.
/// </summary> /// </summary>
internal WinCertificateMaker() internal WinCertificateMaker(Action<Exception> exceptionFunc)
{ {
this.exceptionFunc = exceptionFunc;
typeX500DN = Type.GetTypeFromProgID("X509Enrollment.CX500DistinguishedName", true); typeX500DN = Type.GetTypeFromProgID("X509Enrollment.CX500DistinguishedName", true);
typeX509PrivateKey = Type.GetTypeFromProgID("X509Enrollment.CX509PrivateKey", true); typeX509PrivateKey = Type.GetTypeFromProgID("X509Enrollment.CX509PrivateKey", true);
typeOID = Type.GetTypeFromProgID("X509Enrollment.CObjectId", true); typeOID = Type.GetTypeFromProgID("X509Enrollment.CObjectId", true);
...@@ -261,24 +264,36 @@ namespace Titanium.Web.Proxy.Network.Certificate ...@@ -261,24 +264,36 @@ namespace Titanium.Web.Proxy.Network.Certificate
} }
private X509Certificate2 MakeCertificateInternal(string sSubjectCN, bool isRoot, private X509Certificate2 MakeCertificateInternal(string sSubjectCN, bool isRoot,
bool switchToMTAIfNeeded, bool switchToMTAIfNeeded, X509Certificate2 signingCert = null,
X509Certificate2 signingCert = null) CancellationToken cancellationToken = default(CancellationToken))
{ {
X509Certificate2 rCert = null; X509Certificate2 certificate = null;
#if NET45
if (switchToMTAIfNeeded && Thread.CurrentThread.GetApartmentState() != ApartmentState.MTA) if (switchToMTAIfNeeded && Thread.CurrentThread.GetApartmentState() != ApartmentState.MTA)
{ {
var manualResetEvent = new ManualResetEvent(false); using (var manualResetEvent = new ManualResetEventSlim(false))
ThreadPool.QueueUserWorkItem(o =>
{ {
rCert = MakeCertificateInternal(sSubjectCN, isRoot, false, signingCert); ThreadPool.QueueUserWorkItem(o =>
manualResetEvent.Set(); {
}); try
manualResetEvent.WaitOne(); {
manualResetEvent.Close(); certificate = MakeCertificateInternal(sSubjectCN, isRoot, false, signingCert);
return rCert; }
catch (Exception ex)
{
exceptionFunc.Invoke(new Exception("Failed to create Win certificate", ex));
}
if (!cancellationToken.IsCancellationRequested)
{
manualResetEvent.Set();
}
});
manualResetEvent.Wait(TimeSpan.FromMinutes(1), cancellationToken);
}
return certificate;
} }
#endif
//Subject //Subject
string fullSubject = $"CN={sSubjectCN}"; string fullSubject = $"CN={sSubjectCN}";
...@@ -293,8 +308,8 @@ namespace Titanium.Web.Proxy.Network.Certificate ...@@ -293,8 +308,8 @@ namespace Titanium.Web.Proxy.Network.Certificate
var graceTime = DateTime.Now.AddDays(GraceDays); var graceTime = DateTime.Now.AddDays(GraceDays);
var now = DateTime.Now; var now = DateTime.Now;
rCert = MakeCertificate(isRoot, sSubjectCN, fullSubject, keyLength, HashAlgo, graceTime, now.AddDays(ValidDays), isRoot ? null : signingCert); certificate = MakeCertificate(isRoot, sSubjectCN, fullSubject, keyLength, HashAlgo, graceTime, now.AddDays(ValidDays), isRoot ? null : signingCert);
return rCert; return certificate;
} }
} }
} }
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