Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in / Register
Toggle navigation
T
Titanium-Web-Proxy
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Administrator
Titanium-Web-Proxy
Commits
722036e4
Commit
722036e4
authored
Sep 14, 2016
by
ilushka85
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Switch to CertEnroll instead of makecert
parent
2f2a3b2f
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
263 additions
and
220 deletions
+263
-220
CertEnrollEngine.cs
Titanium.Web.Proxy/Network/CertEnrollEngine.cs
+238
-0
CertificateManager.cs
Titanium.Web.Proxy/Network/CertificateManager.cs
+10
-211
ProxyServer.cs
Titanium.Web.Proxy/ProxyServer.cs
+1
-1
RequestHandler.cs
Titanium.Web.Proxy/RequestHandler.cs
+2
-2
Titanium.Web.Proxy.csproj
Titanium.Web.Proxy/Titanium.Web.Proxy.csproj
+12
-6
makecert.exe
Titanium.Web.Proxy/makecert.exe
+0
-0
No files found.
Titanium.Web.Proxy/Network/CertEnrollEngine.cs
0 → 100644
View file @
722036e4
using
System
;
using
System.Collections.Generic
;
using
System.Linq
;
using
System.Text
;
using
System.Threading.Tasks
;
using
System.Reflection
;
using
System.Security.Cryptography.X509Certificates
;
using
System.Threading
;
namespace
Titanium.Web.Proxy.Network
{
public
class
CertEnrollEngine
{
private
Type
typeX500DN
;
private
Type
typeX509PrivateKey
;
private
Type
typeOID
;
private
Type
typeOIDS
;
private
Type
typeKUExt
;
private
Type
typeEKUExt
;
private
Type
typeRequestCert
;
private
Type
typeX509Extensions
;
private
Type
typeBasicConstraints
;
private
Type
typeSignerCertificate
;
private
Type
typeX509Enrollment
;
private
Type
typeAlternativeName
;
private
Type
typeAlternativeNames
;
private
Type
typeAlternativeNamesExt
;
private
string
sProviderName
=
"Microsoft Enhanced Cryptographic Provider v1.0"
;
private
object
_SharedPrivateKey
;
public
CertEnrollEngine
()
{
this
.
typeX500DN
=
Type
.
GetTypeFromProgID
(
"X509Enrollment.CX500DistinguishedName"
,
true
);
this
.
typeX509PrivateKey
=
Type
.
GetTypeFromProgID
(
"X509Enrollment.CX509PrivateKey"
,
true
);
this
.
typeOID
=
Type
.
GetTypeFromProgID
(
"X509Enrollment.CObjectId"
,
true
);
this
.
typeOIDS
=
Type
.
GetTypeFromProgID
(
"X509Enrollment.CObjectIds.1"
,
true
);
this
.
typeEKUExt
=
Type
.
GetTypeFromProgID
(
"X509Enrollment.CX509ExtensionEnhancedKeyUsage"
);
this
.
typeKUExt
=
Type
.
GetTypeFromProgID
(
"X509Enrollment.CX509ExtensionKeyUsage"
);
this
.
typeRequestCert
=
Type
.
GetTypeFromProgID
(
"X509Enrollment.CX509CertificateRequestCertificate"
);
this
.
typeX509Extensions
=
Type
.
GetTypeFromProgID
(
"X509Enrollment.CX509Extensions"
);
this
.
typeBasicConstraints
=
Type
.
GetTypeFromProgID
(
"X509Enrollment.CX509ExtensionBasicConstraints"
);
this
.
typeSignerCertificate
=
Type
.
GetTypeFromProgID
(
"X509Enrollment.CSignerCertificate"
);
this
.
typeX509Enrollment
=
Type
.
GetTypeFromProgID
(
"X509Enrollment.CX509Enrollment"
);
this
.
typeAlternativeName
=
Type
.
GetTypeFromProgID
(
"X509Enrollment.CAlternativeName"
);
this
.
typeAlternativeNames
=
Type
.
GetTypeFromProgID
(
"X509Enrollment.CAlternativeNames"
);
this
.
typeAlternativeNamesExt
=
Type
.
GetTypeFromProgID
(
"X509Enrollment.CX509ExtensionAlternativeNames"
);
}
public
X509Certificate2
CreateCert
(
string
sSubjectCN
,
bool
isRoot
,
X509Certificate2
signingCert
=
null
)
{
return
this
.
InternalCreateCert
(
sSubjectCN
,
isRoot
,
true
,
signingCert
);
}
private
X509Certificate2
GenerateCertificate
(
bool
IsRoot
,
string
SubjectCN
,
string
FullSubject
,
int
PrivateKeyLength
,
string
HashAlg
,
DateTime
ValidFrom
,
DateTime
ValidTo
,
X509Certificate2
SigningCertificate
)
{
X509Certificate2
cert
;
if
(
IsRoot
!=
(
null
==
SigningCertificate
))
{
throw
new
ArgumentException
(
"You must specify a Signing Certificate if and only if you are not creating a root."
,
"oSigningCertificate"
);
}
object
x500DN
=
Activator
.
CreateInstance
(
this
.
typeX500DN
);
object
[]
subject
=
new
object
[]
{
FullSubject
,
0
};
this
.
typeX500DN
.
InvokeMember
(
"Encode"
,
BindingFlags
.
InvokeMethod
,
null
,
x500DN
,
subject
);
object
x500DN2
=
Activator
.
CreateInstance
(
this
.
typeX500DN
);
if
(!
IsRoot
)
{
subject
[
0
]
=
SigningCertificate
.
Subject
;
}
this
.
typeX500DN
.
InvokeMember
(
"Encode"
,
BindingFlags
.
InvokeMethod
,
null
,
x500DN2
,
subject
);
object
sharedPrivateKey
=
null
;
if
(!
IsRoot
)
{
sharedPrivateKey
=
this
.
_SharedPrivateKey
;
}
if
(
sharedPrivateKey
==
null
)
{
sharedPrivateKey
=
Activator
.
CreateInstance
(
this
.
typeX509PrivateKey
);
subject
=
new
object
[]
{
this
.
sProviderName
};
this
.
typeX509PrivateKey
.
InvokeMember
(
"ProviderName"
,
BindingFlags
.
PutDispProperty
,
null
,
sharedPrivateKey
,
subject
);
subject
[
0
]
=
2
;
this
.
typeX509PrivateKey
.
InvokeMember
(
"ExportPolicy"
,
BindingFlags
.
PutDispProperty
,
null
,
sharedPrivateKey
,
subject
);
subject
=
new
object
[]
{
(
IsRoot
?
2
:
1
)
};
this
.
typeX509PrivateKey
.
InvokeMember
(
"KeySpec"
,
BindingFlags
.
PutDispProperty
,
null
,
sharedPrivateKey
,
subject
);
if
(!
IsRoot
)
{
subject
=
new
object
[]
{
176
};
this
.
typeX509PrivateKey
.
InvokeMember
(
"KeyUsage"
,
BindingFlags
.
PutDispProperty
,
null
,
sharedPrivateKey
,
subject
);
}
subject
[
0
]
=
PrivateKeyLength
;
this
.
typeX509PrivateKey
.
InvokeMember
(
"Length"
,
BindingFlags
.
PutDispProperty
,
null
,
sharedPrivateKey
,
subject
);
this
.
typeX509PrivateKey
.
InvokeMember
(
"Create"
,
BindingFlags
.
InvokeMethod
,
null
,
sharedPrivateKey
,
null
);
if
(!
IsRoot
)
{
this
.
_SharedPrivateKey
=
sharedPrivateKey
;
}
}
subject
=
new
object
[
1
];
object
obj3
=
Activator
.
CreateInstance
(
this
.
typeOID
);
subject
[
0
]
=
"1.3.6.1.5.5.7.3.1"
;
this
.
typeOID
.
InvokeMember
(
"InitializeFromValue"
,
BindingFlags
.
InvokeMethod
,
null
,
obj3
,
subject
);
object
obj4
=
Activator
.
CreateInstance
(
this
.
typeOIDS
);
subject
[
0
]
=
obj3
;
this
.
typeOIDS
.
InvokeMember
(
"Add"
,
BindingFlags
.
InvokeMethod
,
null
,
obj4
,
subject
);
object
obj5
=
Activator
.
CreateInstance
(
this
.
typeEKUExt
);
subject
[
0
]
=
obj4
;
this
.
typeEKUExt
.
InvokeMember
(
"InitializeEncode"
,
BindingFlags
.
InvokeMethod
,
null
,
obj5
,
subject
);
object
obj6
=
Activator
.
CreateInstance
(
this
.
typeRequestCert
);
subject
=
new
object
[]
{
1
,
sharedPrivateKey
,
string
.
Empty
};
this
.
typeRequestCert
.
InvokeMember
(
"InitializeFromPrivateKey"
,
BindingFlags
.
InvokeMethod
,
null
,
obj6
,
subject
);
subject
=
new
object
[]
{
x500DN
};
this
.
typeRequestCert
.
InvokeMember
(
"Subject"
,
BindingFlags
.
PutDispProperty
,
null
,
obj6
,
subject
);
subject
[
0
]
=
x500DN
;
this
.
typeRequestCert
.
InvokeMember
(
"Issuer"
,
BindingFlags
.
PutDispProperty
,
null
,
obj6
,
subject
);
subject
[
0
]
=
ValidFrom
;
this
.
typeRequestCert
.
InvokeMember
(
"NotBefore"
,
BindingFlags
.
PutDispProperty
,
null
,
obj6
,
subject
);
subject
[
0
]
=
ValidTo
;
this
.
typeRequestCert
.
InvokeMember
(
"NotAfter"
,
BindingFlags
.
PutDispProperty
,
null
,
obj6
,
subject
);
object
obj7
=
Activator
.
CreateInstance
(
this
.
typeKUExt
);
subject
[
0
]
=
176
;
this
.
typeKUExt
.
InvokeMember
(
"InitializeEncode"
,
BindingFlags
.
InvokeMethod
,
null
,
obj7
,
subject
);
object
obj8
=
this
.
typeRequestCert
.
InvokeMember
(
"X509Extensions"
,
BindingFlags
.
GetProperty
,
null
,
obj6
,
null
);
subject
=
new
object
[
1
];
if
(!
IsRoot
)
{
subject
[
0
]
=
obj7
;
this
.
typeX509Extensions
.
InvokeMember
(
"Add"
,
BindingFlags
.
InvokeMethod
,
null
,
obj8
,
subject
);
}
subject
[
0
]
=
obj5
;
this
.
typeX509Extensions
.
InvokeMember
(
"Add"
,
BindingFlags
.
InvokeMethod
,
null
,
obj8
,
subject
);
if
(!
IsRoot
)
{
object
obj12
=
Activator
.
CreateInstance
(
this
.
typeSignerCertificate
);
subject
=
new
object
[]
{
0
,
0
,
12
,
SigningCertificate
.
Thumbprint
};
this
.
typeSignerCertificate
.
InvokeMember
(
"Initialize"
,
BindingFlags
.
InvokeMethod
,
null
,
obj12
,
subject
);
subject
=
new
object
[]
{
obj12
};
this
.
typeRequestCert
.
InvokeMember
(
"SignerCertificate"
,
BindingFlags
.
PutDispProperty
,
null
,
obj6
,
subject
);
}
else
{
object
obj13
=
Activator
.
CreateInstance
(
this
.
typeBasicConstraints
);
subject
=
new
object
[]
{
"true"
,
"0"
};
this
.
typeBasicConstraints
.
InvokeMember
(
"InitializeEncode"
,
BindingFlags
.
InvokeMethod
,
null
,
obj13
,
subject
);
subject
=
new
object
[]
{
obj13
};
this
.
typeX509Extensions
.
InvokeMember
(
"Add"
,
BindingFlags
.
InvokeMethod
,
null
,
obj8
,
subject
);
}
object
obj14
=
Activator
.
CreateInstance
(
this
.
typeOID
);
subject
=
new
object
[]
{
1
,
0
,
0
,
HashAlg
};
this
.
typeOID
.
InvokeMember
(
"InitializeFromAlgorithmName"
,
BindingFlags
.
InvokeMethod
,
null
,
obj14
,
subject
);
subject
=
new
object
[]
{
obj14
};
this
.
typeRequestCert
.
InvokeMember
(
"HashAlgorithm"
,
BindingFlags
.
PutDispProperty
,
null
,
obj6
,
subject
);
this
.
typeRequestCert
.
InvokeMember
(
"Encode"
,
BindingFlags
.
InvokeMethod
,
null
,
obj6
,
null
);
object
obj15
=
Activator
.
CreateInstance
(
this
.
typeX509Enrollment
);
subject
[
0
]
=
obj6
;
this
.
typeX509Enrollment
.
InvokeMember
(
"InitializeFromRequest"
,
BindingFlags
.
InvokeMethod
,
null
,
obj15
,
subject
);
if
(
IsRoot
)
{
subject
[
0
]
=
"DO_NOT_TRUST_FiddlerRoot-CE"
;
this
.
typeX509Enrollment
.
InvokeMember
(
"CertificateFriendlyName"
,
BindingFlags
.
PutDispProperty
,
null
,
obj15
,
subject
);
}
subject
[
0
]
=
0
;
object
obj16
=
this
.
typeX509Enrollment
.
InvokeMember
(
"CreateRequest"
,
BindingFlags
.
InvokeMethod
,
null
,
obj15
,
subject
);
subject
=
new
object
[]
{
2
,
obj16
,
0
,
string
.
Empty
};
this
.
typeX509Enrollment
.
InvokeMember
(
"InstallResponse"
,
BindingFlags
.
InvokeMethod
,
null
,
obj15
,
subject
);
subject
=
new
object
[]
{
null
,
0
,
1
};
string
empty
=
string
.
Empty
;
try
{
empty
=
(
string
)
this
.
typeX509Enrollment
.
InvokeMember
(
"CreatePFX"
,
BindingFlags
.
InvokeMethod
,
null
,
obj15
,
subject
);
return
new
X509Certificate2
(
Convert
.
FromBase64String
(
empty
),
string
.
Empty
,
X509KeyStorageFlags
.
Exportable
);
}
catch
(
Exception
exception1
)
{
Exception
exception
=
exception1
;
cert
=
null
;
}
return
cert
;
}
private
X509Certificate2
InternalCreateCert
(
string
sSubjectCN
,
bool
isRoot
,
bool
switchToMTAIfNeeded
,
X509Certificate2
signingCert
=
null
)
{
X509Certificate2
rCert
=
null
;
if
(
switchToMTAIfNeeded
&&
Thread
.
CurrentThread
.
GetApartmentState
()
!=
ApartmentState
.
MTA
)
{
ManualResetEvent
manualResetEvent
=
new
ManualResetEvent
(
false
);
ThreadPool
.
QueueUserWorkItem
((
object
o
)
=>
{
rCert
=
this
.
InternalCreateCert
(
sSubjectCN
,
isRoot
,
false
,
signingCert
);
manualResetEvent
.
Set
();
});
manualResetEvent
.
WaitOne
();
manualResetEvent
.
Close
();
return
rCert
;
}
string
fullSubject
=
string
.
Format
(
"CN={0}{1}"
,
sSubjectCN
,
""
);
//Subject
string
HashAlgo
=
"SHA256"
;
//Sig Algo
int
GraceDays
=
-
366
;
//Grace Days
int
ValidDays
=
1825
;
//ValiDays
int
keyLength
=
2048
;
//KeyLength
DateTime
graceTime
=
DateTime
.
Now
.
AddDays
((
double
)
GraceDays
);
DateTime
now
=
DateTime
.
Now
;
try
{
if
(!
isRoot
)
{
rCert
=
this
.
GenerateCertificate
(
false
,
sSubjectCN
,
fullSubject
,
keyLength
,
HashAlgo
,
graceTime
,
now
.
AddDays
((
double
)
ValidDays
),
signingCert
);
}
else
{
rCert
=
this
.
GenerateCertificate
(
true
,
sSubjectCN
,
fullSubject
,
keyLength
,
HashAlgo
,
graceTime
,
now
.
AddDays
((
double
)
ValidDays
),
null
);
}
}
catch
(
Exception
e
)
{
return
null
;
}
return
rCert
;
}
}
}
Titanium.Web.Proxy/Network/CertificateManager.cs
View file @
722036e4
using
System
;
using
System.IO
;
using
System.Diagnostics
;
using
System.Collections.Generic
;
using
System.Security.Cryptography.X509Certificates
;
using
System.Reflection
;
using
System.Threading.Tasks
;
using
System.Threading
;
using
System.Linq
;
...
...
@@ -16,33 +13,27 @@ namespace Titanium.Web.Proxy.Network
/// </summary>
internal
class
CertificateManager
:
IDisposable
{
private
const
string
CertCreateFormat
=
"-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 {5}"
;
private
CertEnrollEngine
certEngine
=
null
;
/// <summary>
/// Cache dictionary
/// </summary>
private
readonly
IDictionary
<
string
,
CachedCertificate
>
certificateCache
;
/// <summary>
/// A lock to manage concurrency
/// </summary>
private
SemaphoreSlim
semaphoreLock
=
new
SemaphoreSlim
(
1
);
internal
string
Issuer
{
get
;
private
set
;
}
internal
string
RootCertificateName
{
get
;
private
set
;
}
internal
X509Store
MyStore
{
get
;
private
set
;
}
internal
X509Store
RootStore
{
get
;
private
set
;
}
internal
X509Certificate2
rootCertificate
{
get
;
set
;
}
internal
CertificateManager
(
string
issuer
,
string
rootCertificateName
)
{
certEngine
=
new
CertEnrollEngine
();
Issuer
=
issuer
;
RootCertificateName
=
rootCertificateName
;
MyStore
=
new
X509Store
(
StoreName
.
My
,
StoreLocation
.
CurrentUser
);
RootStore
=
new
X509Store
(
StoreName
.
Root
,
StoreLocation
.
CurrentUser
);
certificateCache
=
new
ConcurrentDictionary
<
string
,
CachedCertificate
>();
}
...
...
@@ -50,40 +41,12 @@ namespace Titanium.Web.Proxy.Network
/// Attempts to move a self-signed certificate to the root store.
/// </summary>
/// <returns>true if succeeded, else false</returns>
internal
async
Task
<
bool
>
CreateTrustedRootCertificate
()
internal
bool
CreateTrustedRootCertificate
()
{
X509Certificate2
rootCertificate
=
await
CreateCertificate
(
RootStore
,
RootCertificateName
,
true
);
rootCertificate
=
CreateCertificate
(
RootCertificateName
,
true
);
return
rootCertificate
!=
null
;
}
/// <summary>
/// Attempts to remove the self-signed certificate from the root store.
/// </summary>
/// <returns>true if succeeded, else false</returns>
internal
bool
DestroyTrustedRootCertificate
()
{
return
DestroyCertificate
(
RootStore
,
RootCertificateName
,
false
);
}
internal
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
;
}
internal
async
Task
<
X509Certificate2
>
CreateCertificate
(
string
certificateName
,
bool
isRootCertificate
)
{
return
await
CreateCertificate
(
MyStore
,
certificateName
,
isRootCertificate
);
}
/// <summary>
/// Create an SSL certificate
/// </summary>
...
...
@@ -91,9 +54,8 @@ namespace Titanium.Web.Proxy.Network
/// <param name="certificateName"></param>
/// <param name="isRootCertificate"></param>
/// <returns></returns>
p
rotected
async
virtual
Task
<
X509Certificate2
>
CreateCertificate
(
X509Store
store
,
string
certificateName
,
bool
isRootCertificate
)
p
ublic
virtual
X509Certificate2
CreateCertificate
(
string
certificateName
,
bool
isRootCertificate
)
{
try
{
if
(
certificateCache
.
ContainsKey
(
certificateName
))
...
...
@@ -108,55 +70,9 @@ namespace Titanium.Web.Proxy.Network
}
X509Certificate2
certificate
=
certEngine
.
CreateCert
(
certificateName
,
isRootCertificate
,
rootCertificate
);
X509Certificate2
certificate
=
null
;
store
.
Open
(
OpenFlags
.
ReadWrite
);
string
certificateSubject
=
string
.
Format
(
"CN={0}, O={1}"
,
certificateName
,
Issuer
);
X509Certificate2Collection
certificates
;
if
(
isRootCertificate
)
{
certificates
=
FindCertificates
(
store
,
certificateSubject
);
if
(
certificates
!=
null
)
{
certificate
=
certificates
[
0
];
}
}
if
(
certificate
==
null
)
{
string
[]
args
=
new
[]
{
GetCertificateCreateArgs
(
store
,
certificateName
)
};
await
semaphoreLock
.
WaitAsync
();
try
{
await
CreateCertificate
(
args
);
}
finally
{
semaphoreLock
.
Release
();
}
certificates
=
FindCertificates
(
store
,
certificateSubject
);
//remove it from store
if
(!
isRootCertificate
)
{
DestroyCertificate
(
certificateName
);
}
if
(
certificates
!=
null
)
{
certificate
=
certificates
[
0
];
}
}
store
.
Close
();
if
(
certificate
!=
null
&&
!
certificateCache
.
ContainsKey
(
certificateName
))
{
certificateCache
.
Add
(
certificateName
,
new
CachedCertificate
()
{
Certificate
=
certificate
});
...
...
@@ -166,112 +82,6 @@ namespace Titanium.Web.Proxy.Network
}
/// <summary>
/// Create certificate using makecert.exe
/// </summary>
/// <param name="args"></param>
/// <returns></returns>
protected
virtual
Task
<
int
>
CreateCertificate
(
string
[]
args
)
{
// there is no non-generic TaskCompletionSource
var
tcs
=
new
TaskCompletionSource
<
int
>();
var
process
=
new
Process
();
string
file
=
Path
.
Combine
(
Path
.
GetDirectoryName
(
Assembly
.
GetExecutingAssembly
().
Location
),
"makecert.exe"
);
if
(!
File
.
Exists
(
file
))
{
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
=
file
;
process
.
EnableRaisingEvents
=
true
;
process
.
Exited
+=
(
sender
,
processArgs
)
=>
{
tcs
.
SetResult
(
process
.
ExitCode
);
process
.
Dispose
();
};
bool
started
=
process
.
Start
();
if
(!
started
)
{
//you may allow for the process to be re-used (started = false)
//but I'm not sure about the guarantees of the Exited event in such a case
throw
new
InvalidOperationException
(
"Could not start process: "
+
process
);
}
return
tcs
.
Task
;
}
/// <summary>
/// Destroy an SSL certificate from local store
/// </summary>
/// <param name="certificateName"></param>
/// <returns></returns>
internal
bool
DestroyCertificate
(
string
certificateName
)
{
return
DestroyCertificate
(
MyStore
,
certificateName
,
false
);
}
/// <summary>
/// Destroy certificate from the specified store
/// optionally also remove from proxy certificate cache
/// </summary>
/// <param name="store"></param>
/// <param name="certificateName"></param>
/// <param name="removeFromCache"></param>
/// <returns></returns>
protected
virtual
bool
DestroyCertificate
(
X509Store
store
,
string
certificateName
,
bool
removeFromCache
)
{
X509Certificate2Collection
certificates
=
null
;
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
);
}
store
.
Close
();
if
(
removeFromCache
&&
certificateCache
.
ContainsKey
(
certificateName
))
{
certificateCache
.
Remove
(
certificateName
);
}
return
certificates
==
null
;
}
/// <summary>
/// Create the neccessary arguments for makecert.exe to create the required certificate
/// </summary>
/// <param name="store"></param>
/// <param name="certificateName"></param>
/// <returns></returns>
protected
virtual
string
GetCertificateCreateArgs
(
X509Store
store
,
string
certificateName
)
{
bool
isRootCertificate
=
(
certificateName
==
RootCertificateName
);
string
certCreatArgs
=
string
.
Format
(
CertCreateFormat
,
store
.
Name
,
certificateName
,
Issuer
,
isRootCertificate
?
"signature"
:
"exchange"
,
isRootCertificate
?
"authority"
:
"end"
,
isRootCertificate
?
"-h 1 -r"
:
string
.
Format
(
"-pe -in \"{0}\" -is Root"
,
RootCertificateName
));
return
certCreatArgs
;
}
private
bool
clearCertificates
{
get
;
set
;
}
...
...
@@ -291,7 +101,6 @@ namespace Titanium.Web.Proxy.Network
clearCertificates
=
true
;
while
(
clearCertificates
)
{
await
semaphoreLock
.
WaitAsync
();
try
{
...
...
@@ -306,7 +115,6 @@ namespace Titanium.Web.Proxy.Network
}
finally
{
semaphoreLock
.
Release
();
}
//after a minute come back to check for outdated certificates in cache
...
...
@@ -316,15 +124,6 @@ namespace Titanium.Web.Proxy.Network
public
void
Dispose
()
{
if
(
MyStore
!=
null
)
{
MyStore
.
Close
();
}
if
(
RootStore
!=
null
)
{
RootStore
.
Close
();
}
}
}
}
\ No newline at end of file
Titanium.Web.Proxy/ProxyServer.cs
View file @
722036e4
...
...
@@ -289,7 +289,7 @@ namespace Titanium.Web.Proxy
throw
new
Exception
(
"Proxy is already running."
);
}
certTrusted
=
certificateCacheManager
.
CreateTrustedRootCertificate
()
.
Result
;
certTrusted
=
certificateCacheManager
.
CreateTrustedRootCertificate
();
foreach
(
var
endPoint
in
ProxyEndPoints
)
{
...
...
Titanium.Web.Proxy/RequestHandler.cs
View file @
722036e4
...
...
@@ -186,7 +186,7 @@ namespace Titanium.Web.Proxy
{
sslStream
=
new
SslStream
(
clientStream
,
true
);
var
certificate
=
await
certificateCacheManager
.
CreateCertificate
(
httpRemoteUri
.
Host
,
false
);
var
certificate
=
certificateCacheManager
.
CreateCertificate
(
httpRemoteUri
.
Host
,
false
);
//Successfully managed to authenticate the client using the fake certificate
await
sslStream
.
AuthenticateAsServerAsync
(
certificate
,
false
,
SupportedSslProtocols
,
false
);
...
...
@@ -259,7 +259,7 @@ namespace Titanium.Web.Proxy
var
sslStream
=
new
SslStream
(
clientStream
,
true
);
//implement in future once SNI supported by SSL stream, for now use the same certificate
certificate
=
await
certificateCacheManager
.
CreateCertificate
(
endPoint
.
GenericCertificateName
,
false
);
certificate
=
certificateCacheManager
.
CreateCertificate
(
endPoint
.
GenericCertificateName
,
false
);
try
{
...
...
Titanium.Web.Proxy/Titanium.Web.Proxy.csproj
View file @
722036e4
...
...
@@ -65,6 +65,7 @@
<Compile
Include=
"EventArguments\CertificateValidationEventArgs.cs"
/>
<Compile
Include=
"Extensions\ByteArrayExtensions.cs"
/>
<Compile
Include=
"Network\CachedCertificate.cs"
/>
<Compile
Include=
"Network\CertEnrollEngine.cs"
/>
<Compile
Include=
"Network\ProxyClient.cs"
/>
<Compile
Include=
"Exceptions\BodyNotFoundException.cs"
/>
<Compile
Include=
"Extensions\HttpWebResponseExtensions.cs"
/>
...
...
@@ -93,15 +94,20 @@
<Compile
Include=
"Http\Responses\RedirectResponse.cs"
/>
<Compile
Include=
"Shared\ProxyConstants.cs"
/>
</ItemGroup>
<ItemGroup
/>
<ItemGroup>
<None
Include=
"app.config"
/>
<None
Include=
"packages.config"
/>
<COMReference
Include=
"CERTENROLLLib"
>
<Guid>
{728AB348-217D-11DA-B2A4-000E7BBB2B09}
</Guid>
<VersionMajor>
1
</VersionMajor>
<VersionMinor>
0
</VersionMinor>
<Lcid>
0
</Lcid>
<WrapperTool>
tlbimp
</WrapperTool>
<Isolated>
False
</Isolated>
<EmbedInteropTypes>
True
</EmbedInteropTypes>
</COMReference>
</ItemGroup>
<ItemGroup>
<None
Include=
"makecert.exe"
>
<CopyToOutputDirectory>
PreserveNewest
</CopyToOutputDirectory>
</None>
<None
Include=
"app.config"
/>
<None
Include=
"packages.config"
/>
</ItemGroup>
<Import
Project=
"$(MSBuildToolsPath)\Microsoft.CSharp.targets"
/>
<Import
Project=
"$(SolutionDir)\.nuget\NuGet.targets"
Condition=
"Exists('$(SolutionDir)\.nuget\NuGet.targets')"
/>
...
...
Titanium.Web.Proxy/makecert.exe
deleted
100644 → 0
View file @
2f2a3b2f
File deleted
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment