Commit 3d37c4cf authored by Jon Cole's avatar Jon Cole

Add support for SslProtocols in CORE_CLR.

parent 0d84b984
...@@ -187,7 +187,7 @@ public void CreateDisconnectedNonsenseConnection_DNS() ...@@ -187,7 +187,7 @@ public void CreateDisconnectedNonsenseConnection_DNS()
Console.WriteLine(log); Console.WriteLine(log);
} }
} }
#if !CORE_CLR
[Test] [Test]
public void SslProtocols_SingleValue() public void SslProtocols_SingleValue()
{ {
...@@ -223,7 +223,6 @@ public void SslProtocols_InvalidValue() ...@@ -223,7 +223,6 @@ public void SslProtocols_InvalidValue()
var log = new StringWriter(); var log = new StringWriter();
Assert.Throws<ArgumentOutOfRangeException>(() => ConfigurationOptions.Parse("myhost,sslProtocols=InvalidSslProtocol")); Assert.Throws<ArgumentOutOfRangeException>(() => ConfigurationOptions.Parse("myhost,sslProtocols=InvalidSslProtocol"));
} }
#endif //#if !CORE_CLR
[Test] [Test]
public void ConfigurationOptionsDefaultForAzure() public void ConfigurationOptionsDefaultForAzure()
......
...@@ -66,7 +66,7 @@ internal static Proxy ParseProxy(string key, string value) ...@@ -66,7 +66,7 @@ internal static Proxy ParseProxy(string key, string value)
if (!Enum.TryParse(value, true, out tmp)) throw new ArgumentOutOfRangeException("Keyword '" + key + "' requires a proxy value"); if (!Enum.TryParse(value, true, out tmp)) throw new ArgumentOutOfRangeException("Keyword '" + key + "' requires a proxy value");
return tmp; return tmp;
} }
#if !CORE_CLR
internal static SslProtocols ParseSslProtocols(string key, string value) internal static SslProtocols ParseSslProtocols(string key, string value)
{ {
SslProtocols tmp; SslProtocols tmp;
...@@ -77,7 +77,7 @@ internal static SslProtocols ParseSslProtocols(string key, string value) ...@@ -77,7 +77,7 @@ internal static SslProtocols ParseSslProtocols(string key, string value)
return tmp; return tmp;
} }
#endif
internal static void Unknown(string key) internal static void Unknown(string key)
{ {
throw new ArgumentException("Keyword '" + key + "' is not supported"); throw new ArgumentException("Keyword '" + key + "' is not supported");
...@@ -90,9 +90,7 @@ internal static void Unknown(string key) ...@@ -90,9 +90,7 @@ internal static void Unknown(string key)
ConfigChannel = "configChannel", AbortOnConnectFail = "abortConnect", ResolveDns = "resolveDns", ConfigChannel = "configChannel", AbortOnConnectFail = "abortConnect", ResolveDns = "resolveDns",
ChannelPrefix = "channelPrefix", Proxy = "proxy", ConnectRetry = "connectRetry", ChannelPrefix = "channelPrefix", Proxy = "proxy", ConnectRetry = "connectRetry",
ConfigCheckSeconds = "configCheckSeconds", ResponseTimeout = "responseTimeout", DefaultDatabase = "defaultDatabase"; ConfigCheckSeconds = "configCheckSeconds", ResponseTimeout = "responseTimeout", DefaultDatabase = "defaultDatabase";
#if !CORE_CLR
internal const string SslProtocols = "sslProtocols"; internal const string SslProtocols = "sslProtocols";
#endif
private static readonly Dictionary<string, string> normalizedOptions = new[] private static readonly Dictionary<string, string> normalizedOptions = new[]
{ {
...@@ -103,9 +101,7 @@ internal static void Unknown(string key) ...@@ -103,9 +101,7 @@ internal static void Unknown(string key)
ConfigChannel, AbortOnConnectFail, ResolveDns, ConfigChannel, AbortOnConnectFail, ResolveDns,
ChannelPrefix, Proxy, ConnectRetry, ChannelPrefix, Proxy, ConnectRetry,
ConfigCheckSeconds, DefaultDatabase, ConfigCheckSeconds, DefaultDatabase,
#if !CORE_CLR
SslProtocols, SslProtocols,
#endif
}.ToDictionary(x => x, StringComparer.OrdinalIgnoreCase); }.ToDictionary(x => x, StringComparer.OrdinalIgnoreCase);
public static string TryNormalize(string value) public static string TryNormalize(string value)
...@@ -175,13 +171,11 @@ public static string TryNormalize(string value) ...@@ -175,13 +171,11 @@ public static string TryNormalize(string value)
/// </summary> /// </summary>
public bool Ssl { get { return ssl.GetValueOrDefault(); } set { ssl = value; } } public bool Ssl { get { return ssl.GetValueOrDefault(); } set { ssl = value; } }
#if !CORE_CLR
/// <summary> /// <summary>
/// Configures which Ssl/TLS protocols should be allowed. If not set, defaults are chosen by the .NET framework. /// Configures which Ssl/TLS protocols should be allowed. If not set, defaults are chosen by the .NET framework.
/// </summary> /// </summary>
public SslProtocols? SslProtocols { get; set; } public SslProtocols? SslProtocols { get; set; }
#endif
/// <summary> /// <summary>
/// Automatically encodes and decodes channels /// Automatically encodes and decodes channels
/// </summary> /// </summary>
......
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Net.Security;
using System.Security.Authentication;
using System.Security.Cryptography.X509Certificates;
namespace StackExchange.Redis namespace StackExchange.Redis
{ {
...@@ -122,5 +125,33 @@ public static string[] ToStringArray(this RedisValue[] values) ...@@ -122,5 +125,33 @@ public static string[] ToStringArray(this RedisValue[] values)
if (values.Length == 0) return nix; if (values.Length == 0) return nix;
return ConvertHelper.ConvertAll(values, x => (string)x); return ConvertHelper.ConvertAll(values, x => (string)x);
} }
internal static void AuthenticateAsClient(this SslStream ssl, string host, SslProtocols? allowedProtocols)
{
if (!allowedProtocols.HasValue)
{
//Default to the sslProtocols defined by the .NET Framework
AuthenticateAsClientUsingDefaultProtocols(ssl, host);
return;
}
var certificateCollection = new X509CertificateCollection();
const bool checkCertRevocation = true;
#if CORE_CLR
ssl.AuthenticateAsClientAsync(host, certificateCollection, allowedProtocols.Value, checkCertRevocation)
.GetAwaiter().GetResult();
#else
ssl.AuthenticateAsClient(host, certificateCollection, allowedProtocols.Value, checkCertRevocation);
#endif
}
private static void AuthenticateAsClientUsingDefaultProtocols(SslStream ssl, string host)
{
#if CORE_CLR
ssl.AuthenticateAsClientAsync(host).GetAwaiter().GetResult();
#else
ssl.AuthenticateAsClient(host);
#endif
}
} }
} }
...@@ -783,22 +783,9 @@ SocketMode ISocketCallback.Connected(Stream stream, TextWriter log) ...@@ -783,22 +783,9 @@ SocketMode ISocketCallback.Connected(Stream stream, TextWriter log)
); );
try try
{ {
#if CORE_CLR ssl.AuthenticateAsClient(host, config.SslProtocols);
ssl.AuthenticateAsClientAsync(host).GetAwaiter().GetResult();
#else
if (config.SslProtocols.HasValue)
{
var allowedProtocols = config.SslProtocols.Value;
ssl.AuthenticateAsClient(host, new X509CertificateCollection(), allowedProtocols, checkCertificateRevocation: true);
}
else
{
// default to defaults for the .NET framework
ssl.AuthenticateAsClient(host);
}
Multiplexer.LogLocked(log, $"SSL connection established successfully using protocol: {ssl.SslProtocol}"); Multiplexer.LogLocked(log, $"SSL connection established successfully using protocol: {ssl.SslProtocol}");
#endif
} }
catch (AuthenticationException authexception) catch (AuthenticationException authexception)
{ {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment