Add SslStream Configuration for Client & Server
This commit is contained in:
parent
72867a26da
commit
cc0ab61eb9
@ -554,10 +554,10 @@ namespace WebSocketSharp
|
||||
this TcpClient tcpClient,
|
||||
string protocol,
|
||||
bool secure,
|
||||
X509Certificate certificate,
|
||||
ServerCertAuthConfiguration certificateConfig,
|
||||
Logger logger)
|
||||
{
|
||||
return new TcpListenerWebSocketContext (tcpClient, protocol, secure, certificate, logger);
|
||||
return new TcpListenerWebSocketContext (tcpClient, protocol, secure, certificateConfig, logger);
|
||||
}
|
||||
|
||||
internal static byte[] InternalToByteArray (this ushort value, ByteOrder order)
|
||||
|
44
websocket-sharp/Net/ClientCertAuthConfiguration.cs
Normal file
44
websocket-sharp/Net/ClientCertAuthConfiguration.cs
Normal file
@ -0,0 +1,44 @@
|
||||
using System.Security.Authentication;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
|
||||
namespace WebSocketSharp
|
||||
{
|
||||
public class ClientCertAuthConfiguration
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the certificate configuration used to authenticate the clients on the secure connection.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// A <see cref="X509CertificateCollection"/> that represents the certificate collection used to authenticate
|
||||
/// the clients.
|
||||
/// </value>
|
||||
public X509CertificateCollection clientCertificates { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Ssl protocols type enabled.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The <see cref="SslProtocols"/> value that represents the protocol used for authentication.
|
||||
/// </value>
|
||||
public SslProtocols EnabledSslProtocols { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the verification of certificate revocation option.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// A Boolean value that specifies whether the certificate revocation list is checked during authentication.
|
||||
/// </value>
|
||||
public bool CheckCertificateRevocation { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ClientCertAuthConfiguration"/> class.
|
||||
/// </summary>
|
||||
public ClientCertAuthConfiguration(X509CertificateCollection clientCertificates,
|
||||
SslProtocols enabledSslProtocols = SslProtocols.Default, bool checkCertificateRevocation = false)
|
||||
{
|
||||
this.clientCertificates = clientCertificates;
|
||||
this.EnabledSslProtocols = enabledSslProtocols;
|
||||
this.CheckCertificateRevocation = checkCertificateRevocation;
|
||||
}
|
||||
}
|
||||
}
|
@ -54,7 +54,7 @@ namespace WebSocketSharp.Net
|
||||
#region Private Fields
|
||||
|
||||
private List<HttpListenerPrefix> _all; // host == '+'
|
||||
private X509Certificate2 _cert;
|
||||
private ServerCertAuthConfiguration _certConfig;
|
||||
private static readonly string _defaultCertFolderPath;
|
||||
private IPEndPoint _endpoint;
|
||||
private Dictionary<HttpListenerPrefix, HttpListener> _prefixes;
|
||||
@ -83,13 +83,13 @@ namespace WebSocketSharp.Net
|
||||
int port,
|
||||
bool secure,
|
||||
string certificateFolderPath,
|
||||
X509Certificate2 defaultCertificate,
|
||||
ServerCertAuthConfiguration defaultCertificate,
|
||||
bool reuseAddress)
|
||||
{
|
||||
if (secure) {
|
||||
_secure = secure;
|
||||
_cert = getCertificate (port, certificateFolderPath, defaultCertificate);
|
||||
if (_cert == null)
|
||||
_certConfig = getCertificate (port, certificateFolderPath, defaultCertificate);
|
||||
if (_certConfig == null)
|
||||
throw new ArgumentException ("No server certificate could be found.");
|
||||
}
|
||||
|
||||
@ -116,9 +116,10 @@ namespace WebSocketSharp.Net
|
||||
|
||||
#region Public Properties
|
||||
|
||||
public X509Certificate2 Certificate {
|
||||
public ServerCertAuthConfiguration CertificateConfig
|
||||
{
|
||||
get {
|
||||
return _cert;
|
||||
return _certConfig;
|
||||
}
|
||||
}
|
||||
|
||||
@ -173,8 +174,8 @@ namespace WebSocketSharp.Net
|
||||
return rsa;
|
||||
}
|
||||
|
||||
private static X509Certificate2 getCertificate (
|
||||
int port, string certificateFolderPath, X509Certificate2 defaultCertificate)
|
||||
private static ServerCertAuthConfiguration getCertificate(
|
||||
int port, string certificateFolderPath, ServerCertAuthConfiguration defaultCertificate)
|
||||
{
|
||||
if (certificateFolderPath == null || certificateFolderPath.Length == 0)
|
||||
certificateFolderPath = _defaultCertFolderPath;
|
||||
@ -186,7 +187,7 @@ namespace WebSocketSharp.Net
|
||||
var cert = new X509Certificate2 (cer);
|
||||
cert.PrivateKey = createRSAFromFile (key);
|
||||
|
||||
return cert;
|
||||
return new ServerCertAuthConfiguration(cert);
|
||||
}
|
||||
}
|
||||
catch {
|
||||
|
@ -107,7 +107,7 @@ namespace WebSocketSharp.Net
|
||||
port,
|
||||
secure,
|
||||
httpListener.CertificateFolderPath,
|
||||
httpListener.DefaultCertificate,
|
||||
httpListener.DefaultCertificateConfig,
|
||||
httpListener.ReuseAddress);
|
||||
|
||||
eps[port] = epl;
|
||||
|
@ -87,7 +87,10 @@ namespace WebSocketSharp.Net
|
||||
var netStream = new NetworkStream (socket, false);
|
||||
if (_secure) {
|
||||
var sslStream = new SslStream (netStream, false);
|
||||
sslStream.AuthenticateAsServer (listener.Certificate);
|
||||
var certificateConfig = listener.CertificateConfig;
|
||||
sslStream.AuthenticateAsServer(certificateConfig.ServerCertificate,
|
||||
certificateConfig.ClientCertificateRequired, certificateConfig.EnabledSslProtocols,
|
||||
certificateConfig.CheckCertificateRevocation);
|
||||
_stream = sslStream;
|
||||
}
|
||||
else {
|
||||
|
@ -64,7 +64,7 @@ namespace WebSocketSharp.Net
|
||||
private Dictionary<HttpListenerContext, HttpListenerContext> _ctxRegistry;
|
||||
private object _ctxRegistrySync;
|
||||
private Func<IIdentity, NetworkCredential> _credFinder;
|
||||
private X509Certificate2 _defaultCert;
|
||||
private ServerCertAuthConfiguration _defaultCert;
|
||||
private bool _disposed;
|
||||
private bool _ignoreWriteExceptions;
|
||||
private bool _listening;
|
||||
@ -224,7 +224,8 @@ namespace WebSocketSharp.Net
|
||||
/// <exception cref="ObjectDisposedException">
|
||||
/// This listener has been closed.
|
||||
/// </exception>
|
||||
public X509Certificate2 DefaultCertificate {
|
||||
public ServerCertAuthConfiguration DefaultCertificateConfig
|
||||
{
|
||||
get {
|
||||
CheckDisposed ();
|
||||
return _defaultCert;
|
||||
|
@ -61,7 +61,7 @@ namespace WebSocketSharp.Net.WebSockets
|
||||
#region Internal Constructors
|
||||
|
||||
internal TcpListenerWebSocketContext (
|
||||
TcpClient tcpClient, string protocol, bool secure, X509Certificate certificate, Logger logger)
|
||||
TcpClient tcpClient, string protocol, bool secure, ServerCertAuthConfiguration certificateConfig, Logger logger)
|
||||
{
|
||||
_tcpClient = tcpClient;
|
||||
_secure = secure;
|
||||
@ -69,7 +69,9 @@ namespace WebSocketSharp.Net.WebSockets
|
||||
var netStream = tcpClient.GetStream ();
|
||||
if (secure) {
|
||||
var sslStream = new SslStream (netStream, false);
|
||||
sslStream.AuthenticateAsServer (certificate);
|
||||
sslStream.AuthenticateAsServer(certificateConfig.ServerCertificate,
|
||||
certificateConfig.ClientCertificateRequired, certificateConfig.EnabledSslProtocols,
|
||||
certificateConfig.CheckCertificateRevocation);
|
||||
_stream = sslStream;
|
||||
}
|
||||
else {
|
||||
|
@ -187,9 +187,10 @@ namespace WebSocketSharp.Server
|
||||
/// A <see cref="X509Certificate2"/> that represents the certificate used to authenticate
|
||||
/// the server.
|
||||
/// </value>
|
||||
public X509Certificate2 Certificate {
|
||||
public ServerCertAuthConfiguration CertificateConfig
|
||||
{
|
||||
get {
|
||||
return _listener.DefaultCertificate;
|
||||
return _listener.DefaultCertificateConfig;
|
||||
}
|
||||
|
||||
set {
|
||||
@ -202,7 +203,7 @@ namespace WebSocketSharp.Server
|
||||
if (EndPointListener.CertificateExists (_port, _listener.CertificateFolderPath))
|
||||
_logger.Warn ("The server certificate associated with the port number already exists.");
|
||||
|
||||
_listener.DefaultCertificate = value;
|
||||
_listener.DefaultCertificateConfig = value;
|
||||
}
|
||||
}
|
||||
|
||||
@ -508,7 +509,7 @@ namespace WebSocketSharp.Server
|
||||
{
|
||||
return _secure &&
|
||||
!EndPointListener.CertificateExists (_port, _listener.CertificateFolderPath) &&
|
||||
_listener.DefaultCertificate == null
|
||||
_listener.DefaultCertificateConfig == null
|
||||
? "The secure connection requires a server certificate."
|
||||
: null;
|
||||
}
|
||||
|
53
websocket-sharp/Server/ServerCertAuthConfiguration.cs
Normal file
53
websocket-sharp/Server/ServerCertAuthConfiguration.cs
Normal file
@ -0,0 +1,53 @@
|
||||
using System.Security.Authentication;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
|
||||
namespace WebSocketSharp
|
||||
{
|
||||
public class ServerCertAuthConfiguration
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the certificate used to authenticate the server on the secure connection.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// A <see cref="X509Certificate2"/> that represents the certificate used to authenticate
|
||||
/// the server.
|
||||
/// </value>
|
||||
public X509Certificate2 ServerCertificate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the client certificate request option.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// A Boolean value that specifies whether the client must supply a certificate for authentication.
|
||||
/// </value>
|
||||
public bool ClientCertificateRequired { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Ssl protocols type enabled.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The <see cref="SslProtocols"/> value that represents the protocol used for authentication.
|
||||
/// </value>
|
||||
public SslProtocols EnabledSslProtocols { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the verification of certificate revocation option.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// A Boolean value that specifies whether the certificate revocation list is checked during authentication.
|
||||
/// </value>
|
||||
public bool CheckCertificateRevocation { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ServerCertAuthConfiguration"/> class.
|
||||
/// </summary>
|
||||
public ServerCertAuthConfiguration(X509Certificate2 serverCertificate, bool clientCertificateRequired = false,
|
||||
SslProtocols enabledSslProtocols = SslProtocols.Default, bool checkCertificateRevocation = false)
|
||||
{
|
||||
this.ServerCertificate = serverCertificate;
|
||||
this.ClientCertificateRequired = clientCertificateRequired;
|
||||
this.EnabledSslProtocols = enabledSslProtocols;
|
||||
this.CheckCertificateRevocation = checkCertificateRevocation;
|
||||
}
|
||||
}
|
||||
}
|
@ -60,7 +60,7 @@ namespace WebSocketSharp.Server
|
||||
|
||||
private System.Net.IPAddress _address;
|
||||
private AuthenticationSchemes _authSchemes;
|
||||
private X509Certificate2 _certificate;
|
||||
private ServerCertAuthConfiguration _certificateConfig;
|
||||
private Func<IIdentity, NetworkCredential> _credentialsFinder;
|
||||
private TcpListener _listener;
|
||||
private Logger _logger;
|
||||
@ -312,15 +312,16 @@ namespace WebSocketSharp.Server
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the certificate used to authenticate the server on the secure connection.
|
||||
/// Gets or sets the certificate configuration used to authenticate the server on the secure connection.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// A <see cref="X509Certificate2"/> that represents the certificate used to authenticate
|
||||
/// A <see cref="ServerCertAuthConfiguration"/> that represents the certificate configuration used to authenticate
|
||||
/// the server.
|
||||
/// </value>
|
||||
public X509Certificate2 Certificate {
|
||||
public ServerCertAuthConfiguration CertificateConfig
|
||||
{
|
||||
get {
|
||||
return _certificate;
|
||||
return _certificateConfig;
|
||||
}
|
||||
|
||||
set {
|
||||
@ -330,7 +331,7 @@ namespace WebSocketSharp.Server
|
||||
return;
|
||||
}
|
||||
|
||||
_certificate = value;
|
||||
_certificateConfig = value;
|
||||
}
|
||||
}
|
||||
|
||||
@ -587,7 +588,8 @@ namespace WebSocketSharp.Server
|
||||
|
||||
private string checkIfCertificateExists ()
|
||||
{
|
||||
return _secure && _certificate == null
|
||||
return _secure && (_certificateConfig == null
|
||||
|| _certificateConfig != null && _certificateConfig.ServerCertificate == null)
|
||||
? "The secure connection requires a server certificate."
|
||||
: null;
|
||||
}
|
||||
@ -638,7 +640,7 @@ namespace WebSocketSharp.Server
|
||||
ThreadPool.QueueUserWorkItem (
|
||||
state => {
|
||||
try {
|
||||
var ctx = cl.GetWebSocketContext (null, _secure, _certificate, _logger);
|
||||
var ctx = cl.GetWebSocketContext (null, _secure, _certificateConfig, _logger);
|
||||
if (_authSchemes != AuthenticationSchemes.Anonymous &&
|
||||
!authenticateRequest (_authSchemes, ctx))
|
||||
return;
|
||||
|
@ -71,6 +71,8 @@ namespace WebSocketSharp
|
||||
private string _base64Key;
|
||||
private LocalCertificateSelectionCallback
|
||||
_certSelectionCallback;
|
||||
private ClientCertAuthConfiguration
|
||||
_certificateConfig;
|
||||
private RemoteCertificateValidationCallback
|
||||
_certValidationCallback;
|
||||
private bool _client;
|
||||
@ -461,6 +463,40 @@ namespace WebSocketSharp
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the certificate configuration used to authenticate the client on the secure connection.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// A <see cref="ClientCertAuthConfiguration"/> that represents the certificate configuration used to authenticate
|
||||
/// the client.
|
||||
/// </value>
|
||||
public ClientCertAuthConfiguration CertificateConfig
|
||||
{
|
||||
get
|
||||
{
|
||||
return _certificateConfig;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
lock (_forConn)
|
||||
{
|
||||
var msg = checkIfAvailable(false, false);
|
||||
if (msg != null)
|
||||
{
|
||||
_logger.Error(msg);
|
||||
error(
|
||||
"An error has occurred in setting the server certificate configuration.",
|
||||
null);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
_certificateConfig = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the callback used to validate the certificate supplied by the server.
|
||||
/// </summary>
|
||||
@ -1343,7 +1379,13 @@ namespace WebSocketSharp
|
||||
((sender, targetHost, localCertificates, remoteCertificate, acceptableIssuers) =>
|
||||
null));
|
||||
|
||||
if (_certificateConfig == null)
|
||||
sslStream.AuthenticateAsClient(_uri.DnsSafeHost);
|
||||
else
|
||||
{
|
||||
sslStream.AuthenticateAsClient(_uri.DnsSafeHost, _certificateConfig.clientCertificates,
|
||||
_certificateConfig.EnabledSslProtocols, _certificateConfig.CheckCertificateRevocation);
|
||||
}
|
||||
_stream = sslStream;
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="3.5" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
@ -67,6 +67,8 @@
|
||||
<Compile Include="CloseEventArgs.cs" />
|
||||
<Compile Include="ByteOrder.cs" />
|
||||
<Compile Include="ErrorEventArgs.cs" />
|
||||
<Compile Include="Net\ClientCertAuthConfiguration.cs" />
|
||||
<Compile Include="Server\ServerCertAuthConfiguration.cs" />
|
||||
<Compile Include="WebSocket.cs" />
|
||||
<Compile Include="Server\WebSocketServer.cs" />
|
||||
<Compile Include="Net\AuthenticationSchemes.cs" />
|
||||
|
Loading…
Reference in New Issue
Block a user