Fix for pull request #85, added TargetHost property to ClientSslAuthConfiguration class, and refactored

This commit is contained in:
sta 2014-11-03 15:11:43 +09:00
parent 1fc568c4e8
commit c511f9d7ac
2 changed files with 54 additions and 46 deletions

View File

@ -34,14 +34,14 @@
*/ */
#endregion #endregion
using System.Net.Security;
using System.Security.Authentication; using System.Security.Authentication;
using System.Security.Cryptography.X509Certificates; using System.Security.Cryptography.X509Certificates;
namespace WebSocketSharp.Net namespace WebSocketSharp.Net
{ {
/// <summary> /// <summary>
/// Stores the parameters used in configuring <see cref="System.Net.Security.SslStream"/> /// Stores the parameters used to configure a <see cref="SslStream"/> instance as a client.
/// as a client.
/// </summary> /// </summary>
public class ClientSslAuthConfiguration public class ClientSslAuthConfiguration
{ {
@ -49,39 +49,26 @@ namespace WebSocketSharp.Net
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="ClientSslAuthConfiguration"/> class with /// Initializes a new instance of the <see cref="ClientSslAuthConfiguration"/> class with
/// the specified <paramref name="clientCertificates"/>. /// the specified <paramref name="targetHost"/>.
/// </summary> /// </summary>
/// <param name="clientCertificates"> /// <param name="targetHost">
/// A <see cref="X509CertificateCollection"/> that contains client certificates. /// A <see cref="string"/> that represents the name of the server that shares
/// a secure connection.
/// </param> /// </param>
public ClientSslAuthConfiguration (X509CertificateCollection clientCertificates) public ClientSslAuthConfiguration (string targetHost)
: this (clientCertificates, SslProtocols.Default, false) : this (targetHost, null, SslProtocols.Default, false)
{ {
} }
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="ClientSslAuthConfiguration"/> class with /// Initializes a new instance of the <see cref="ClientSslAuthConfiguration"/> class with
/// the specified <paramref name="clientCertificates"/> and /// the specified <paramref name="targetHost"/>, <paramref name="clientCertificates"/>,
/// <paramref name="enabledSslProtocols"/>. /// <paramref name="enabledSslProtocols"/>, and <paramref name="checkCertificateRevocation"/>.
/// </summary> /// </summary>
/// <param name="clientCertificates"> /// <param name="targetHost">
/// A <see cref="X509CertificateCollection"/> that contains client certificates. /// A <see cref="string"/> that represents the name of the server that shares
/// a secure connection.
/// </param> /// </param>
/// <param name="enabledSslProtocols">
/// The <see cref="SslProtocols"/> enum value that represents the protocols used for
/// authentication.
/// </param>
public ClientSslAuthConfiguration (
X509CertificateCollection clientCertificates, SslProtocols enabledSslProtocols)
: this (clientCertificates, enabledSslProtocols, false)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="ClientSslAuthConfiguration"/> class with
/// the specified <paramref name="clientCertificates"/>, <paramref name="enabledSslProtocols"/>,
/// and <paramref name="checkCertificateRevocation"/>.
/// </summary>
/// <param name="clientCertificates"> /// <param name="clientCertificates">
/// A <see cref="X509CertificateCollection"/> that contains client certificates. /// A <see cref="X509CertificateCollection"/> that contains client certificates.
/// </param> /// </param>
@ -94,10 +81,12 @@ namespace WebSocketSharp.Net
/// otherwise, <c>false</c>. /// otherwise, <c>false</c>.
/// </param> /// </param>
public ClientSslAuthConfiguration ( public ClientSslAuthConfiguration (
string targetHost,
X509CertificateCollection clientCertificates, X509CertificateCollection clientCertificates,
SslProtocols enabledSslProtocols, SslProtocols enabledSslProtocols,
bool checkCertificateRevocation) bool checkCertificateRevocation)
{ {
TargetHost = targetHost;
ClientCertificates = clientCertificates; ClientCertificates = clientCertificates;
EnabledSslProtocols = enabledSslProtocols; EnabledSslProtocols = enabledSslProtocols;
CheckCertificateRevocation = checkCertificateRevocation; CheckCertificateRevocation = checkCertificateRevocation;
@ -133,6 +122,15 @@ namespace WebSocketSharp.Net
/// </value> /// </value>
public SslProtocols EnabledSslProtocols { get; set; } public SslProtocols EnabledSslProtocols { get; set; }
/// <summary>
/// Gets or sets the name of the server that shares a secure connection.
/// </summary>
/// <value>
/// A <see cref="string"/> that represents the name of the server that shares
/// a secure connection.
/// </value>
public string TargetHost { get; set; }
#endregion #endregion
} }
} }

View File

@ -498,16 +498,19 @@ namespace WebSocketSharp
} }
/// <summary> /// <summary>
/// Gets or sets the SSL configuration used to authenticate the server and optionally the client /// Gets or sets the SSL configuration used to authenticate the server and
/// on the secure connection. /// optionally the client for secure connection.
/// </summary> /// </summary>
/// <value> /// <value>
/// A <see cref="ClientSslAuthConfiguration"/> that represents the SSL configuration used to /// A <see cref="ClientSslAuthConfiguration"/> that represents the configuration
/// authenticate the server and optionally the client. /// used to authenticate the server and optionally the client for secure connection,
/// or <see langword="null"/> if the <see cref="WebSocket"/> is used as server.
/// </value> /// </value>
public ClientSslAuthConfiguration SslConfiguration { public ClientSslAuthConfiguration SslConfiguration {
get { get {
return _sslConfig; return _client
? (_sslConfig ?? (_sslConfig = new ClientSslAuthConfiguration (_uri.DnsSafeHost)))
: null;
} }
set { set {
@ -1366,6 +1369,12 @@ namespace WebSocketSharp
} }
if (_secure) { if (_secure) {
var conf = SslConfiguration;
if (conf.TargetHost != _uri.DnsSafeHost)
throw new WebSocketException (
CloseStatusCode.TlsHandshakeFailure, "An invalid host name is specified.");
try {
var sslStream = new SslStream ( var sslStream = new SslStream (
_stream, _stream,
false, false,
@ -1374,17 +1383,18 @@ namespace WebSocketSharp
((sender, targetHost, localCertificates, remoteCertificate, acceptableIssuers) => ((sender, targetHost, localCertificates, remoteCertificate, acceptableIssuers) =>
null)); null));
if (_sslConfig == null)
sslStream.AuthenticateAsClient (_uri.DnsSafeHost);
else
sslStream.AuthenticateAsClient ( sslStream.AuthenticateAsClient (
_uri.DnsSafeHost, conf.TargetHost,
_sslConfig.ClientCertificates, conf.ClientCertificates,
_sslConfig.EnabledSslProtocols, conf.EnabledSslProtocols,
_sslConfig.CheckCertificateRevocation); conf.CheckCertificateRevocation);
_stream = sslStream; _stream = sslStream;
} }
catch (Exception ex) {
throw new WebSocketException (CloseStatusCode.TlsHandshakeFailure, ex);
}
}
} }
private void startReceiving () private void startReceiving ()