diff --git a/Src/SmtpServer/EndpointDefinitionBuilder.cs b/Src/SmtpServer/EndpointDefinitionBuilder.cs
index 95332bc..87a0df3 100644
--- a/Src/SmtpServer/EndpointDefinitionBuilder.cs
+++ b/Src/SmtpServer/EndpointDefinitionBuilder.cs
@@ -99,6 +99,21 @@ public EndpointDefinitionBuilder AllowUnsecureAuthentication(bool value = true)
return this;
}
+#if NETSTANDARD2_1_OR_GREATER
+ ///
+ /// Sets a value indicating wheter client ssl renegotiation should be allowed, this is not recommended
+ /// since it might allow for the following vulnerability https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2009-3555
+ /// .NET 7.0 has made renagotiation false by default https://learn.microsoft.com/en-us/dotnet/core/compatibility/networking/7.0/allowrenegotiation-default
+ ///
+ ///
+ ///
+ public EndpointDefinitionBuilder AllowClientSslRenegotiation(bool value = true)
+ {
+ _setters.Add(options => options.AllowClientSslRenegotiation = value);
+ return this;
+ }
+#endif
+
///
/// Sets the read timeout to apply to stream operations.
///
@@ -154,6 +169,7 @@ internal sealed class EndpointDefinition : IEndpointDefinition
///
public bool AuthenticationRequired { get; set; }
+
///
/// Gets a value indicating whether authentication should be allowed on an unsecure session.
///
@@ -173,6 +189,13 @@ internal sealed class EndpointDefinition : IEndpointDefinition
/// The supported SSL protocols.
///
public SslProtocols SupportedSslProtocols { get; set; }
+
+#if NETSTANDARD2_1_OR_GREATER
+ ///
+ /// Gets a value indicating if during an SSL connection a client ssl renegotiation is allowed
+ ///
+ public bool AllowClientSslRenegotiation { get; set; }
+#endif
}
#endregion
diff --git a/Src/SmtpServer/IEndpointDefinition.cs b/Src/SmtpServer/IEndpointDefinition.cs
index 7489dc1..e5b8079 100644
--- a/Src/SmtpServer/IEndpointDefinition.cs
+++ b/Src/SmtpServer/IEndpointDefinition.cs
@@ -27,6 +27,14 @@ public interface IEndpointDefinition
///
bool AllowUnsecureAuthentication { get; }
+
+#if NETSTANDARD2_1_OR_GREATER
+ ///
+ /// Gets a value indicating if during an SSL connection a client ssl renegotiation is allowed
+ ///
+ bool AllowClientSslRenegotiation { get; }
+#endif
+
///
/// The timeout on each individual buffer read.
///
diff --git a/Src/SmtpServer/IO/SecurableDuplexPipe.cs b/Src/SmtpServer/IO/SecurableDuplexPipe.cs
index 32f2c5b..02548d3 100644
--- a/Src/SmtpServer/IO/SecurableDuplexPipe.cs
+++ b/Src/SmtpServer/IO/SecurableDuplexPipe.cs
@@ -29,6 +29,10 @@ internal SecurableDuplexPipe(Stream stream, Action disposeAction)
Output = PipeWriter.Create(_stream);
}
+#if NETSTANDARD2_1_OR_GREATER
+ public bool AllowRenegotiation { get; set; } = false;
+#endif
+
///
/// Upgrade to a secure pipeline.
///
@@ -40,8 +44,18 @@ public async Task UpgradeAsync(X509Certificate certificate, SslProtocols protoco
{
var stream = new SslStream(_stream, true);
+#if NETSTANDARD2_1_OR_GREATER
+ await stream.AuthenticateAsServerAsync(new SslServerAuthenticationOptions
+ {
+ AllowRenegotiation = AllowRenegotiation,
+ ServerCertificate = certificate,
+ CertificateRevocationCheckMode = X509RevocationMode.Online,
+ ClientCertificateRequired = false,
+ EnabledSslProtocols = protocols,
+ }, cancellationToken);
+#else
await stream.AuthenticateAsServerAsync(certificate, false, protocols, true).ConfigureAwait(false);
-
+#endif
_stream = stream;
Input = PipeReader.Create(_stream);
diff --git a/Src/SmtpServer/Net/EndpointListener.cs b/Src/SmtpServer/Net/EndpointListener.cs
index 55523dd..4158929 100644
--- a/Src/SmtpServer/Net/EndpointListener.cs
+++ b/Src/SmtpServer/Net/EndpointListener.cs
@@ -29,6 +29,12 @@ internal EndpointListener(IEndpointDefinition endpointDefinition, TcpListener tc
_disposeAction = disposeAction;
}
+ ///
+ /// During ssl connections allows the client to drop the connection and reconnect while renegotiation for a different TLS version
+ /// .NET 7.0 has set this to false to prevent the following vulnerability https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2009-3555
+ ///
+ public bool AllowSslClientRenegotiation { get; set; } = false;
+
///
/// Returns a securable pipe to the endpoint.
///
@@ -50,7 +56,12 @@ public async Task GetPipeAsync(ISessionContext context, Ca
{
tcpClient.Close();
tcpClient.Dispose();
- });
+ })
+ {
+#if NETSTANDARD2_1_OR_GREATER
+ AllowRenegotiation = AllowSslClientRenegotiation
+#endif
+ };
}
///
diff --git a/Src/SmtpServer/SmtpServer.csproj b/Src/SmtpServer/SmtpServer.csproj
index d940c8c..3fc0531 100644
--- a/Src/SmtpServer/SmtpServer.csproj
+++ b/Src/SmtpServer/SmtpServer.csproj
@@ -1,7 +1,7 @@
- netstandard2.0
+ netstandard2.0;netstandard2.1
8.0
SmtpServer
SmtpServer