diff --git a/websocket-sharp/Ext.cs b/websocket-sharp/Ext.cs
index 441476d4..d1aafab3 100644
--- a/websocket-sharp/Ext.cs
+++ b/websocket-sharp/Ext.cs
@@ -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)
diff --git a/websocket-sharp/Net/ClientCertAuthConfiguration.cs b/websocket-sharp/Net/ClientCertAuthConfiguration.cs
new file mode 100644
index 00000000..6cabd20b
--- /dev/null
+++ b/websocket-sharp/Net/ClientCertAuthConfiguration.cs
@@ -0,0 +1,44 @@
+using System.Security.Authentication;
+using System.Security.Cryptography.X509Certificates;
+
+namespace WebSocketSharp
+{
+ public class ClientCertAuthConfiguration
+ {
+ ///
+ /// Gets or sets the certificate configuration used to authenticate the clients on the secure connection.
+ ///
+ ///
+ /// A that represents the certificate collection used to authenticate
+ /// the clients.
+ ///
+ public X509CertificateCollection clientCertificates { get; set; }
+
+ ///
+ /// Gets or sets the Ssl protocols type enabled.
+ ///
+ ///
+ /// The value that represents the protocol used for authentication.
+ ///
+ public SslProtocols EnabledSslProtocols { get; set; }
+
+ ///
+ /// Gets or sets the verification of certificate revocation option.
+ ///
+ ///
+ /// A Boolean value that specifies whether the certificate revocation list is checked during authentication.
+ ///
+ public bool CheckCertificateRevocation { get; set; }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public ClientCertAuthConfiguration(X509CertificateCollection clientCertificates,
+ SslProtocols enabledSslProtocols = SslProtocols.Default, bool checkCertificateRevocation = false)
+ {
+ this.clientCertificates = clientCertificates;
+ this.EnabledSslProtocols = enabledSslProtocols;
+ this.CheckCertificateRevocation = checkCertificateRevocation;
+ }
+ }
+}
\ No newline at end of file
diff --git a/websocket-sharp/Net/EndPointListener.cs b/websocket-sharp/Net/EndPointListener.cs
index 74d52a98..46e6a7dc 100644
--- a/websocket-sharp/Net/EndPointListener.cs
+++ b/websocket-sharp/Net/EndPointListener.cs
@@ -54,7 +54,7 @@ namespace WebSocketSharp.Net
#region Private Fields
private List _all; // host == '+'
- private X509Certificate2 _cert;
+ private ServerCertAuthConfiguration _certConfig;
private static readonly string _defaultCertFolderPath;
private IPEndPoint _endpoint;
private Dictionary _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 {
diff --git a/websocket-sharp/Net/EndPointManager.cs b/websocket-sharp/Net/EndPointManager.cs
index f0b2b1e0..8b135bf8 100644
--- a/websocket-sharp/Net/EndPointManager.cs
+++ b/websocket-sharp/Net/EndPointManager.cs
@@ -107,7 +107,7 @@ namespace WebSocketSharp.Net
port,
secure,
httpListener.CertificateFolderPath,
- httpListener.DefaultCertificate,
+ httpListener.DefaultCertificateConfig,
httpListener.ReuseAddress);
eps[port] = epl;
diff --git a/websocket-sharp/Net/HttpConnection.cs b/websocket-sharp/Net/HttpConnection.cs
index b1b4f064..03e92a7a 100644
--- a/websocket-sharp/Net/HttpConnection.cs
+++ b/websocket-sharp/Net/HttpConnection.cs
@@ -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 {
diff --git a/websocket-sharp/Net/HttpListener.cs b/websocket-sharp/Net/HttpListener.cs
index de253457..3b5e9f55 100644
--- a/websocket-sharp/Net/HttpListener.cs
+++ b/websocket-sharp/Net/HttpListener.cs
@@ -64,7 +64,7 @@ namespace WebSocketSharp.Net
private Dictionary _ctxRegistry;
private object _ctxRegistrySync;
private Func _credFinder;
- private X509Certificate2 _defaultCert;
+ private ServerCertAuthConfiguration _defaultCert;
private bool _disposed;
private bool _ignoreWriteExceptions;
private bool _listening;
@@ -224,7 +224,8 @@ namespace WebSocketSharp.Net
///
/// This listener has been closed.
///
- public X509Certificate2 DefaultCertificate {
+ public ServerCertAuthConfiguration DefaultCertificateConfig
+ {
get {
CheckDisposed ();
return _defaultCert;
diff --git a/websocket-sharp/Net/WebSockets/TcpListenerWebSocketContext.cs b/websocket-sharp/Net/WebSockets/TcpListenerWebSocketContext.cs
index d571d557..38d615f4 100644
--- a/websocket-sharp/Net/WebSockets/TcpListenerWebSocketContext.cs
+++ b/websocket-sharp/Net/WebSockets/TcpListenerWebSocketContext.cs
@@ -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 {
diff --git a/websocket-sharp/Server/HttpServer.cs b/websocket-sharp/Server/HttpServer.cs
index 35a54729..1157683c 100644
--- a/websocket-sharp/Server/HttpServer.cs
+++ b/websocket-sharp/Server/HttpServer.cs
@@ -187,9 +187,10 @@ namespace WebSocketSharp.Server
/// A that represents the certificate used to authenticate
/// the server.
///
- 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;
}
diff --git a/websocket-sharp/Server/ServerCertAuthConfiguration.cs b/websocket-sharp/Server/ServerCertAuthConfiguration.cs
new file mode 100644
index 00000000..2f1252a1
--- /dev/null
+++ b/websocket-sharp/Server/ServerCertAuthConfiguration.cs
@@ -0,0 +1,53 @@
+using System.Security.Authentication;
+using System.Security.Cryptography.X509Certificates;
+
+namespace WebSocketSharp
+{
+ public class ServerCertAuthConfiguration
+ {
+ ///
+ /// Gets or sets the certificate used to authenticate the server on the secure connection.
+ ///
+ ///
+ /// A that represents the certificate used to authenticate
+ /// the server.
+ ///
+ public X509Certificate2 ServerCertificate { get; set; }
+
+ ///
+ /// Gets or sets the client certificate request option.
+ ///
+ ///
+ /// A Boolean value that specifies whether the client must supply a certificate for authentication.
+ ///
+ public bool ClientCertificateRequired { get; set; }
+
+ ///
+ /// Gets or sets the Ssl protocols type enabled.
+ ///
+ ///
+ /// The value that represents the protocol used for authentication.
+ ///
+ public SslProtocols EnabledSslProtocols { get; set; }
+
+ ///
+ /// Gets or sets the verification of certificate revocation option.
+ ///
+ ///
+ /// A Boolean value that specifies whether the certificate revocation list is checked during authentication.
+ ///
+ public bool CheckCertificateRevocation { get; set; }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ 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;
+ }
+ }
+}
\ No newline at end of file
diff --git a/websocket-sharp/Server/WebSocketServer.cs b/websocket-sharp/Server/WebSocketServer.cs
index 1e9b7065..efede111 100644
--- a/websocket-sharp/Server/WebSocketServer.cs
+++ b/websocket-sharp/Server/WebSocketServer.cs
@@ -60,7 +60,7 @@ namespace WebSocketSharp.Server
private System.Net.IPAddress _address;
private AuthenticationSchemes _authSchemes;
- private X509Certificate2 _certificate;
+ private ServerCertAuthConfiguration _certificateConfig;
private Func _credentialsFinder;
private TcpListener _listener;
private Logger _logger;
@@ -312,15 +312,16 @@ namespace WebSocketSharp.Server
}
///
- /// 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.
///
///
- /// A that represents the certificate used to authenticate
+ /// A that represents the certificate configuration used to authenticate
/// the server.
///
- 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;
diff --git a/websocket-sharp/WebSocket.cs b/websocket-sharp/WebSocket.cs
index e8056a47..2c5acaeb 100644
--- a/websocket-sharp/WebSocket.cs
+++ b/websocket-sharp/WebSocket.cs
@@ -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
}
}
+ ///
+ /// Gets or sets the certificate configuration used to authenticate the client on the secure connection.
+ ///
+ ///
+ /// A that represents the certificate configuration used to authenticate
+ /// the client.
+ ///
+ 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;
+ }
+ }
+ }
+
///
/// Gets or sets the callback used to validate the certificate supplied by the server.
///
@@ -1343,7 +1379,13 @@ namespace WebSocketSharp
((sender, targetHost, localCertificates, remoteCertificate, acceptableIssuers) =>
null));
- sslStream.AuthenticateAsClient (_uri.DnsSafeHost);
+ if (_certificateConfig == null)
+ sslStream.AuthenticateAsClient(_uri.DnsSafeHost);
+ else
+ {
+ sslStream.AuthenticateAsClient(_uri.DnsSafeHost, _certificateConfig.clientCertificates,
+ _certificateConfig.EnabledSslProtocols, _certificateConfig.CheckCertificateRevocation);
+ }
_stream = sslStream;
}
}
diff --git a/websocket-sharp/websocket-sharp.csproj b/websocket-sharp/websocket-sharp.csproj
index 047df93a..72dd9ae1 100644
--- a/websocket-sharp/websocket-sharp.csproj
+++ b/websocket-sharp/websocket-sharp.csproj
@@ -1,4 +1,4 @@
-
+
Debug
@@ -67,6 +67,8 @@
+
+