Files
natsnet/dotnet/src/ZB.MOM.NatsNet.Server/Auth/CipherSuites.cs

121 lines
4.6 KiB
C#

// Copyright 2016-2025 The NATS Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Adapted from server/ciphersuites.go in the NATS server Go source.
using System.Net.Security;
using System.Security.Authentication;
namespace ZB.MOM.NatsNet.Server.Auth;
/// <summary>
/// TLS cipher suite and curve preference definitions.
/// Mirrors Go <c>ciphersuites.go</c> — cipherMap, defaultCipherSuites, curvePreferenceMap,
/// defaultCurvePreferences.
/// </summary>
public static class CipherSuites
{
/// <summary>
/// Map of cipher suite names to their <see cref="TlsCipherSuite"/> values.
/// Populated at static init time — mirrors Go <c>init()</c> + <c>cipherMap</c>.
/// </summary>
public static IReadOnlyDictionary<string, TlsCipherSuite> CipherMap { get; }
/// <summary>
/// Reverse map of cipher suite ID to name.
/// Mirrors Go <c>cipherMapByID</c>.
/// </summary>
public static IReadOnlyDictionary<TlsCipherSuite, string> CipherMapById { get; }
static CipherSuites()
{
// .NET does not have a direct equivalent of Go's tls.CipherSuites() /
// tls.InsecureCipherSuites() enumeration. We enumerate the well-known
// TLS 1.2 and 1.3 cipher suites defined in the TlsCipherSuite enum.
var byName = new Dictionary<string, TlsCipherSuite>(StringComparer.OrdinalIgnoreCase);
var byId = new Dictionary<TlsCipherSuite, string>();
foreach (TlsCipherSuite cs in Enum.GetValues(typeof(TlsCipherSuite)))
{
var name = cs.ToString();
byName.TryAdd(name, cs);
byId.TryAdd(cs, name);
}
CipherMap = byName;
CipherMapById = byId;
}
/// <summary>
/// Compatibility init hook for PortTracker parity with Go <c>init()</c>.
/// Safe and idempotent.
/// </summary>
public static void Init()
{
_ = CipherMap;
_ = CipherMapById;
}
/// <summary>
/// Returns the default set of TLS 1.2 cipher suites.
/// .NET manages cipher suite selection at the OS/SChannel/OpenSSL level;
/// this list provides the preferred suites for configuration alignment with Go.
/// Mirrors Go <c>defaultCipherSuites</c>.
/// </summary>
public static TlsCipherSuite[] DefaultCipherSuites()
{
// Return commonly-used TLS 1.2 cipher suites in preference order.
// TLS 1.3 suites are always enabled in .NET and cannot be individually toggled.
return
[
TlsCipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
TlsCipherSuite.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
TlsCipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
TlsCipherSuite.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
TlsCipherSuite.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,
TlsCipherSuite.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
];
}
/// <summary>
/// Supported named curve / key exchange preferences.
/// Mirrors Go <c>curvePreferenceMap</c>.
/// </summary>
public static IReadOnlyDictionary<string, SslApplicationProtocol> CurvePreferenceMap { get; } =
new Dictionary<string, SslApplicationProtocol>(StringComparer.OrdinalIgnoreCase)
{
// .NET does not expose individual curve selection in the same way as Go.
// These entries exist for configuration-file compatibility and mapping.
// Actual curve negotiation is handled by the OS TLS stack.
["X25519"] = new SslApplicationProtocol("X25519"),
["CurveP256"] = new SslApplicationProtocol("CurveP256"),
["CurveP384"] = new SslApplicationProtocol("CurveP384"),
["CurveP521"] = new SslApplicationProtocol("CurveP521"),
};
/// <summary>
/// Returns the default curve preferences, ordered highest security first.
/// Mirrors Go <c>defaultCurvePreferences</c>.
/// </summary>
public static string[] DefaultCurvePreferences()
{
return
[
"X25519",
"CurveP256",
"CurveP384",
"CurveP521",
];
}
}