#endif
}
+static void ResetProtocolRestrictions(SSL_CTX* ctx)
+{
+#ifndef SSL_CTRL_SET_MIN_PROTO_VERSION
+#define SSL_CTRL_SET_MIN_PROTO_VERSION 123
+#endif
+#ifndef SSL_CTRL_SET_MAX_PROTO_VERSION
+#define SSL_CTRL_SET_MAX_PROTO_VERSION 124
+#endif
+
+ SSL_CTX_ctrl(ctx, SSL_CTRL_SET_MIN_PROTO_VERSION, 0, NULL);
+ SSL_CTX_ctrl(ctx, SSL_CTRL_SET_MAX_PROTO_VERSION, 0, NULL);
+}
+
void CryptoNative_SetProtocolOptions(SSL_CTX* ctx, SslProtocols protocols)
{
// Ensure that ECDHE is available
protocolOptions |= SSL_OP_NO_TLSv1_3;
}
+ // We manually set protocols - we need to reset OpenSSL restrictions
+ // to a maximum possible range
+ ResetProtocolRestrictions(ctx);
+
// OpenSSL 1.0 calls this long, OpenSSL 1.1 calls it unsigned long.
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wsign-conversion"
case NoEncryption:
// No minimum security policy, same as OpenSSL 1.0
SSL_CTX_set_security_level(ctx, 0);
+ ResetProtocolRestrictions(ctx);
return true;
case RequireEncryption:
return true;
ApplicationProtocols = sslClientAuthenticationOptions.ApplicationProtocols;
CertValidationDelegate = remoteCallback;
CheckCertName = true;
- EnabledSslProtocols = sslClientAuthenticationOptions.EnabledSslProtocols;
+ EnabledSslProtocols = FilterOutIncompatibleSslProtocols(sslClientAuthenticationOptions.EnabledSslProtocols);
EncryptionPolicy = sslClientAuthenticationOptions.EncryptionPolicy;
IsServer = false;
RemoteCertRequired = true;
AllowRenegotiation = sslServerAuthenticationOptions.AllowRenegotiation;
ApplicationProtocols = sslServerAuthenticationOptions.ApplicationProtocols;
CheckCertName = false;
- EnabledSslProtocols = sslServerAuthenticationOptions.EnabledSslProtocols;
+ EnabledSslProtocols = FilterOutIncompatibleSslProtocols(sslServerAuthenticationOptions.EnabledSslProtocols);
EncryptionPolicy = sslServerAuthenticationOptions.EncryptionPolicy;
IsServer = true;
RemoteCertRequired = sslServerAuthenticationOptions.ClientCertificateRequired;
CipherSuitesPolicy = sslServerAuthenticationOptions.CipherSuitesPolicy;
}
+ private static SslProtocols FilterOutIncompatibleSslProtocols(SslProtocols protocols)
+ {
+ if (protocols.HasFlag(SslProtocols.Tls12) || protocols.HasFlag(SslProtocols.Tls13))
+ {
+#pragma warning disable 0618
+ // SSL2 is mutually exclusive with >= TLS1.2
+ // On Windows10 SSL2 flag has no effect but on earlier versions of the OS
+ // opting into both SSL2 and >= TLS1.2 causes negotiation to always fail.
+ protocols &= ~SslProtocols.Ssl2;
+#pragma warning restore 0618
+ }
+
+ return protocols;
+ }
+
internal bool AllowRenegotiation { get; set; }
internal string TargetHost { get; set; }
internal X509CertificateCollection ClientCertificates { get; set; }
public class CertificateValidationClientServer : IDisposable
{
- private readonly ITestOutputHelper _output;
+ private readonly ITestOutputHelper _output;
private readonly X509Certificate2 _clientCertificate;
private readonly X509Certificate2Collection _clientCertificateCollection;
private readonly X509Certificate2 _serverCertificate;
[InlineData(true)]
public async Task CertificateValidationClientServer_EndToEnd_Ok(bool useClientSelectionCallback)
{
- IPEndPoint endPoint = new IPEndPoint(IPAddress.IPv6Loopback, 0);
+ IPEndPoint endPoint = new IPEndPoint(IPAddress.Loopback, 0);
var server = new TcpListener(endPoint);
server.Start();
_clientCertificateRemovedByFilter = true;
}
- using (var clientConnection = new TcpClient(AddressFamily.InterNetworkV6))
+ using (var clientConnection = new TcpClient())
{
IPEndPoint serverEndPoint = (IPEndPoint)server.LocalEndpoint;
// Verify that the certificate is in the trustedChain.
_output.WriteLine($"cert: subject={cert.Subject}, issuer={cert.Issuer}, thumbprint={cert.Thumbprint}");
Assert.Equal(cert.Thumbprint, trustedChain.ChainElements[0].Certificate.Thumbprint);
-
+
// Verify that the root certificate in the chain is the one that issued the received certificate.
foreach (X509ChainElement element in trustedChain.ChainElements)
{
{
_log.WriteLine("Server: " + serverSslProtocols + "; Client: " + clientSslProtocols);
- IPEndPoint endPoint = new IPEndPoint(IPAddress.IPv6Loopback, 0);
+ IPEndPoint endPoint = new IPEndPoint(IPAddress.Loopback, 0);
using (var server = new DummyTcpServer(endPoint, encryptionPolicy))
- using (var client = new TcpClient(AddressFamily.InterNetworkV6))
+ using (var client = new TcpClient())
{
server.SslProtocols = serverSslProtocols;
await client.ConnectAsync(server.RemoteEndPoint.Address, server.RemoteEndPoint.Port);
int timeOut = expectedToFail ? TestConfiguration.FailingTestTimeoutMiliseconds
: TestConfiguration.PassingTestTimeoutMilliseconds;
- IPEndPoint endPoint = new IPEndPoint(IPAddress.IPv6Loopback, 0);
+ IPEndPoint endPoint = new IPEndPoint(IPAddress.Loopback, 0);
var server = new TcpListener(endPoint);
server.Start();
- using (var clientConnection = new TcpClient(AddressFamily.InterNetworkV6))
+ using (var clientConnection = new TcpClient())
{
IPEndPoint serverEndPoint = (IPEndPoint)server.LocalEndpoint;
public class NegotiatedCipherSuiteTest
{
#pragma warning disable CS0618 // Ssl2 and Ssl3 are obsolete
- private const SslProtocols AllProtocols =
+ public const SslProtocols AllProtocols =
SslProtocols.Ssl2 | SslProtocols.Ssl3 |
SslProtocols.Tls | SslProtocols.Tls11 | SslProtocols.Tls12 | SslProtocols.Tls13;
#pragma warning restore CS0618
- private const SslProtocols NonTls13Protocols = AllProtocols & (~SslProtocols.Tls13);
+ public const SslProtocols NonTls13Protocols = AllProtocols & (~SslProtocols.Tls13);
private static bool IsKnownPlatformSupportingTls13 => PlatformDetection.SupportsTls13;
private static bool CipherSuitesPolicySupported => s_cipherSuitePolicySupported.Value;
};
NegotiatedParams ret = ConnectAndGetNegotiatedParams(p, p);
- ret.Succeeded();
-
- Assert.True(
- s_protocolCipherSuiteLookup[protocol].Contains(ret.CipherSuite),
- $"`{ret.CipherSuite}` is not recognized as {protocol} cipher suite");
+ if (ret.HasSucceeded)
+ {
+ Assert.True(
+ s_protocolCipherSuiteLookup[protocol].Contains(ret.CipherSuite),
+ $"`{ret.CipherSuite}` is not recognized as {protocol} cipher suite");
+ }
+ else
+ {
+ // currently TLS 1.2 should be enabled by all known implementations
+ Assert.NotEqual(SslProtocols.Tls12, protocol);
+ }
}
[Fact]
var validationCallback = new RemoteCertificateValidationCallback((object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) =>
{
Assert.Equal(serverCert, certificate);
- return true;
+ return true;
});
VirtualNetwork vn = new VirtualNetwork();
return new SslServerAuthenticationOptions()
{
ClientCertificateRequired = false,
- EnabledSslProtocols = SslProtocols.Tls,
+ EnabledSslProtocols = SslProtocols.None,
CertificateRevocationCheckMode = X509RevocationMode.NoCheck,
};
}
[InlineData(SslProtocols.None, null)]
[InlineData(null, SslProtocols.None)]
[InlineData(SslProtocols.None, SslProtocols.None)]
- [InlineData(null, SslProtocols.Tls11)]
- [InlineData(SslProtocols.Tls11, null)]
+ [InlineData(NegotiatedCipherSuiteTest.NonTls13Protocols, SslProtocols.Tls11)]
+ [InlineData(SslProtocols.Tls11, NegotiatedCipherSuiteTest.NonTls13Protocols)]
[InlineData(null, SslProtocols.Tls12)]
[InlineData(SslProtocols.Tls12, null)]
[InlineData(SslProtocols.Tls | SslProtocols.Tls11 | SslProtocols.Tls12, null)]
[InlineData(null, SslProtocols.Tls | SslProtocols.Tls11 | SslProtocols.Tls12)]
#pragma warning disable 0618
- [InlineData(SslProtocols.Default, null)]
- [InlineData(null, SslProtocols.Default)]
+ [InlineData(SslProtocols.Default, NegotiatedCipherSuiteTest.NonTls13Protocols)]
+ [InlineData(NegotiatedCipherSuiteTest.NonTls13Protocols, SslProtocols.Default)]
#pragma warning restore 0618
public async Task ClientAndServer_OneOrBothUseDefault_Ok(SslProtocols? clientProtocols, SslProtocols? serverProtocols)
{