Skip to content
This repository was archived by the owner on Jul 9, 2023. It is now read-only.

Commit 698084c

Browse files
Merge pull request #421 from justcoding121/master
cleanup win certificate generator
2 parents 347fa30 + 7023f63 commit 698084c

File tree

3 files changed

+48
-79
lines changed

3 files changed

+48
-79
lines changed
Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
using System;
22
using System.Collections.Generic;
3+
using System.Diagnostics;
4+
using System.Linq;
35
using System.Threading.Tasks;
46
using Microsoft.VisualStudio.TestTools.UnitTesting;
57
using Titanium.Web.Proxy.Network;
@@ -12,7 +14,6 @@ public class CertificateManagerTests
1214
private static readonly string[] hostNames
1315
= { "facebook.com", "youtube.com", "google.com", "bing.com", "yahoo.com" };
1416

15-
private readonly Random random = new Random();
1617

1718
[TestMethod]
1819
public async Task Simple_BC_Create_Certificate_Test()
@@ -21,22 +22,21 @@ public async Task Simple_BC_Create_Certificate_Test()
2122

2223
var mgr = new CertificateManager(null, null, false, false, false, new Lazy<ExceptionHandler>(() => (e =>
2324
{
24-
//Console.WriteLine(e.ToString() + e.InnerException != null ? e.InnerException.ToString() : string.Empty);
25-
})).Value);
26-
27-
mgr.CertificateEngine = CertificateEngine.BouncyCastle;
25+
Debug.WriteLine(e.ToString());
26+
Debug.WriteLine(e.InnerException?.ToString());
27+
})).Value)
28+
{
29+
CertificateEngine = CertificateEngine.BouncyCastle
30+
};
2831
mgr.ClearIdleCertificates();
2932
for (int i = 0; i < 5; i++)
3033
{
31-
foreach (string host in hostNames)
34+
tasks.AddRange(hostNames.Select(host => Task.Run(() =>
3235
{
33-
tasks.Add(Task.Run(() =>
34-
{
35-
//get the connection
36-
var certificate = mgr.CreateCertificate(host, false);
37-
Assert.IsNotNull(certificate);
38-
}));
39-
}
36+
//get the connection
37+
var certificate = mgr.CreateCertificate(host, false);
38+
Assert.IsNotNull(certificate);
39+
})));
4040
}
4141

4242
await Task.WhenAll(tasks.ToArray());
@@ -48,34 +48,34 @@ public async Task Simple_BC_Create_Certificate_Test()
4848
[TestMethod]
4949
public async Task Simple_Create_Win_Certificate_Test()
5050
{
51+
5152
var tasks = new List<Task>();
5253

5354
var mgr = new CertificateManager(null, null, false, false, false, new Lazy<ExceptionHandler>(() => (e =>
5455
{
55-
//Console.WriteLine(e.ToString() + e.InnerException != null ? e.InnerException.ToString() : string.Empty);
56-
})).Value);
56+
Debug.WriteLine(e.ToString());
57+
Debug.WriteLine(e.InnerException?.ToString());
58+
})).Value)
59+
{ CertificateEngine = CertificateEngine.DefaultWindows };
5760

58-
mgr.CertificateEngine = CertificateEngine.DefaultWindows;
59-
mgr.CreateRootCertificate(true);
61+
mgr.CreateRootCertificate();
6062
mgr.TrustRootCertificate(true);
6163
mgr.ClearIdleCertificates();
6264

6365
for (int i = 0; i < 5; i++)
6466
{
65-
foreach (string host in hostNames)
67+
tasks.AddRange(hostNames.Select(host => Task.Run(() =>
6668
{
67-
tasks.Add(Task.Run(() =>
68-
{
69-
//get the connection
70-
var certificate = mgr.CreateCertificate(host, false);
71-
Assert.IsNotNull(certificate);
72-
}));
73-
}
69+
//get the connection
70+
var certificate = mgr.CreateCertificate(host, false);
71+
Assert.IsNotNull(certificate);
72+
})));
7473
}
7574

7675
await Task.WhenAll(tasks.ToArray());
7776
mgr.RemoveTrustedRootCertificate(true);
7877
mgr.StopClearIdleCertificates();
78+
7979
}
8080
}
8181
}

Titanium.Web.Proxy/Network/Certificate/WinCertificateMaker.cs

Lines changed: 12 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,11 @@
22
using System.Reflection;
33
using System.Security.Cryptography.X509Certificates;
44
using System.Threading;
5+
using System.Threading.Tasks;
56

67
namespace Titanium.Web.Proxy.Network.Certificate
78
{
9+
/// <inheritdoc />
810
/// <summary>
911
/// Certificate Maker - uses MakeCert
1012
/// Calls COM objects using reflection
@@ -104,8 +106,8 @@ private X509Certificate2 MakeCertificate(bool isRoot, string subject, string ful
104106
}
105107

106108
typeX500DN.InvokeMember("Encode", BindingFlags.InvokeMethod, null, x500RootCertDN, typeValue);
107-
object sharedPrivateKey = null;
108109

110+
object sharedPrivateKey = null;
109111
if (!isRoot)
110112
{
111113
sharedPrivateKey = this.sharedPrivateKey;
@@ -276,49 +278,27 @@ private X509Certificate2 MakeCertificateInternal(string sSubjectCN, bool isRoot,
276278
bool switchToMTAIfNeeded, X509Certificate2 signingCert = null,
277279
CancellationToken cancellationToken = default)
278280
{
279-
X509Certificate2 certificate = null;
280281
if (switchToMTAIfNeeded && Thread.CurrentThread.GetApartmentState() != ApartmentState.MTA)
281282
{
282-
using (var manualResetEvent = new ManualResetEventSlim(false))
283-
{
284-
ThreadPool.QueueUserWorkItem(o =>
285-
{
286-
try
287-
{
288-
certificate = MakeCertificateInternal(sSubjectCN, isRoot, false, signingCert);
289-
}
290-
catch (Exception ex)
291-
{
292-
exceptionFunc(new Exception("Failed to create Win certificate", ex));
293-
}
294-
295-
if (!cancellationToken.IsCancellationRequested)
296-
{
297-
manualResetEvent.Set();
298-
}
299-
});
300-
301-
manualResetEvent.Wait(TimeSpan.FromMinutes(1), cancellationToken);
302-
}
303-
304-
return certificate;
283+
return Task.Run(() => MakeCertificateInternal(sSubjectCN, isRoot, false, signingCert),
284+
cancellationToken).Result;
305285
}
306286

307287
//Subject
308288
string fullSubject = $"CN={sSubjectCN}";
309289
//Sig Algo
310-
string HashAlgo = "SHA256";
290+
const string hashAlgo = "SHA256";
311291
//Grace Days
312-
int GraceDays = -366;
292+
const int graceDays = -366;
313293
//ValiDays
314-
int ValidDays = 1825;
294+
const int validDays = 1825;
315295
//KeyLength
316-
int keyLength = 2048;
296+
const int keyLength = 2048;
317297

318-
var graceTime = DateTime.Now.AddDays(GraceDays);
298+
var graceTime = DateTime.Now.AddDays(graceDays);
319299
var now = DateTime.Now;
320-
certificate = MakeCertificate(isRoot, sSubjectCN, fullSubject, keyLength, HashAlgo, graceTime,
321-
now.AddDays(ValidDays), isRoot ? null : signingCert);
300+
var certificate = MakeCertificate(isRoot, sSubjectCN, fullSubject, keyLength, hashAlgo, graceTime,
301+
now.AddDays(validDays), isRoot ? null : signingCert);
322302
return certificate;
323303
}
324304
}

Titanium.Web.Proxy/Network/CertificateManager.cs

Lines changed: 11 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -79,11 +79,7 @@ internal CertificateManager(string rootCertificateName, string rootCertificateIs
7979
{
8080
this.exceptionFunc = exceptionFunc;
8181

82-
UserTrustRoot = userTrustRootCertificate;
83-
if (machineTrustRootCertificate)
84-
{
85-
userTrustRootCertificate = true;
86-
}
82+
UserTrustRoot = userTrustRootCertificate || machineTrustRootCertificate;
8783

8884
MachineTrustRoot = machineTrustRootCertificate;
8985
TrustRootAsAdministrator = trustRootCertificateAsAdmin;
@@ -338,14 +334,14 @@ private void InstallCertificate(StoreName storeName, StoreLocation storeLocation
338334
return;
339335
}
340336

341-
var x509store = new X509Store(storeName, storeLocation);
337+
var x509Store = new X509Store(storeName, storeLocation);
342338

343339
//TODO
344340
//also it should do not duplicate if certificate already exists
345341
try
346342
{
347-
x509store.Open(OpenFlags.ReadWrite);
348-
x509store.Add(RootCertificate);
343+
x509Store.Open(OpenFlags.ReadWrite);
344+
x509Store.Add(RootCertificate);
349345
}
350346
catch (Exception e)
351347
{
@@ -356,7 +352,7 @@ private void InstallCertificate(StoreName storeName, StoreLocation storeLocation
356352
}
357353
finally
358354
{
359-
x509store.Close();
355+
x509Store.Close();
360356
}
361357
}
362358

@@ -436,7 +432,7 @@ internal X509Certificate2 CreateCertificate(string certificateName, bool isRootC
436432

437433
if (!File.Exists(certificatePath))
438434
{
439-
certificate = MakeCertificate(certificateName, isRootCertificate);
435+
certificate = MakeCertificate(certificateName, false);
440436

441437
//store as cache
442438
Task.Run(() =>
@@ -460,7 +456,7 @@ internal X509Certificate2 CreateCertificate(string certificateName, bool isRootC
460456
//if load failed create again
461457
catch
462458
{
463-
certificate = MakeCertificate(certificateName, isRootCertificate);
459+
certificate = MakeCertificate(certificateName, false);
464460
}
465461
}
466462
}
@@ -485,17 +481,15 @@ internal X509Certificate2 CreateCertificate(string certificateName, bool isRootC
485481
internal async Task<X509Certificate2> CreateCertificateAsync(string certificateName)
486482
{
487483
//check in cache first
488-
CachedCertificate cached;
489-
if (certificateCache.TryGetValue(certificateName, out cached))
484+
if (certificateCache.TryGetValue(certificateName, out var cached))
490485
{
491486
cached.LastAccess = DateTime.Now;
492487
return cached.Certificate;
493488
}
494489

495490
//handle burst requests with same certificate name
496491
//by checking for existing task for same certificate name
497-
Task<X509Certificate2> task;
498-
if (pendingCertificateCreationTasks.TryGetValue(certificateName, out task))
492+
if (pendingCertificateCreationTasks.TryGetValue(certificateName, out var task))
499493
{
500494
return await task;
501495
}
@@ -785,12 +779,7 @@ public void EnsureRootCertificate()
785779
public void EnsureRootCertificate(bool userTrustRootCertificate,
786780
bool machineTrustRootCertificate, bool trustRootCertificateAsAdmin = false)
787781
{
788-
UserTrustRoot = userTrustRootCertificate;
789-
if (machineTrustRootCertificate)
790-
{
791-
userTrustRootCertificate = true;
792-
}
793-
782+
UserTrustRoot = userTrustRootCertificate || machineTrustRootCertificate;
794783
MachineTrustRoot = machineTrustRootCertificate;
795784
TrustRootAsAdministrator = trustRootCertificateAsAdmin;
796785

@@ -909,7 +898,7 @@ public bool RemoveTrustedRootCertificateAsAdmin(bool machineTrusted = false)
909898
success = false;
910899
}
911900

912-
process.WaitForExit();
901+
process?.WaitForExit();
913902
}
914903
}
915904
catch

0 commit comments

Comments
 (0)