<PackageReference Include="BouncyCastle.Cryptography" Version="2.5.1" />

ProtocolVersion

public sealed class ProtocolVersion
using System; using System.Collections.Generic; namespace Org.BouncyCastle.Tls { public sealed class ProtocolVersion { public static readonly ProtocolVersion SSLv3 = new ProtocolVersion(768, "SSL 3.0"); public static readonly ProtocolVersion TLSv10 = new ProtocolVersion(769, "TLS 1.0"); public static readonly ProtocolVersion TLSv11 = new ProtocolVersion(770, "TLS 1.1"); public static readonly ProtocolVersion TLSv12 = new ProtocolVersion(771, "TLS 1.2"); public static readonly ProtocolVersion TLSv13 = new ProtocolVersion(772, "TLS 1.3"); public static readonly ProtocolVersion DTLSv10 = new ProtocolVersion(65279, "DTLS 1.0"); public static readonly ProtocolVersion DTLSv12 = new ProtocolVersion(65277, "DTLS 1.2"); public static readonly ProtocolVersion DTLSv13 = new ProtocolVersion(65276, "DTLS 1.3"); internal static readonly ProtocolVersion CLIENT_EARLIEST_SUPPORTED_DTLS = DTLSv10; internal static readonly ProtocolVersion CLIENT_EARLIEST_SUPPORTED_TLS = SSLv3; internal static readonly ProtocolVersion CLIENT_LATEST_SUPPORTED_DTLS = DTLSv12; internal static readonly ProtocolVersion CLIENT_LATEST_SUPPORTED_TLS = TLSv13; internal static readonly ProtocolVersion SERVER_EARLIEST_SUPPORTED_DTLS = DTLSv10; internal static readonly ProtocolVersion SERVER_EARLIEST_SUPPORTED_TLS = SSLv3; internal static readonly ProtocolVersion SERVER_LATEST_SUPPORTED_DTLS = DTLSv12; internal static readonly ProtocolVersion SERVER_LATEST_SUPPORTED_TLS = TLSv13; private readonly int version; private readonly string name; public int FullVersion => version; public int MajorVersion => version >> 8; public int MinorVersion => version & 255; public string Name => name; public bool IsDtls => MajorVersion == 254; public bool IsSsl => this == SSLv3; public bool IsTls => MajorVersion == 3; public static bool Contains(ProtocolVersion[] versions, ProtocolVersion version) { if (versions != null && version != null) { for (int i = 0; i < versions.Length; i++) { if (version.Equals(versions[i])) return true; } } return false; } public static ProtocolVersion GetEarliestDtls(ProtocolVersion[] versions) { ProtocolVersion protocolVersion = null; if (versions != null) { foreach (ProtocolVersion protocolVersion2 in versions) { if (protocolVersion2 != null && protocolVersion2.IsDtls && (protocolVersion == null || protocolVersion2.MinorVersion > protocolVersion.MinorVersion)) protocolVersion = protocolVersion2; } } return protocolVersion; } public static ProtocolVersion GetEarliestTls(ProtocolVersion[] versions) { ProtocolVersion protocolVersion = null; if (versions != null) { foreach (ProtocolVersion protocolVersion2 in versions) { if (protocolVersion2 != null && protocolVersion2.IsTls && (protocolVersion == null || protocolVersion2.MinorVersion < protocolVersion.MinorVersion)) protocolVersion = protocolVersion2; } } return protocolVersion; } public static ProtocolVersion GetLatestDtls(ProtocolVersion[] versions) { ProtocolVersion protocolVersion = null; if (versions != null) { foreach (ProtocolVersion protocolVersion2 in versions) { if (protocolVersion2 != null && protocolVersion2.IsDtls && (protocolVersion == null || protocolVersion2.MinorVersion < protocolVersion.MinorVersion)) protocolVersion = protocolVersion2; } } return protocolVersion; } public static ProtocolVersion GetLatestTls(ProtocolVersion[] versions) { ProtocolVersion protocolVersion = null; if (versions != null) { foreach (ProtocolVersion protocolVersion2 in versions) { if (protocolVersion2 != null && protocolVersion2.IsTls && (protocolVersion == null || protocolVersion2.MinorVersion > protocolVersion.MinorVersion)) protocolVersion = protocolVersion2; } } return protocolVersion; } internal static bool IsSupportedDtlsVersionClient(ProtocolVersion version) { if (version != null && version.IsEqualOrLaterVersionOf(CLIENT_EARLIEST_SUPPORTED_DTLS)) return version.IsEqualOrEarlierVersionOf(CLIENT_LATEST_SUPPORTED_DTLS); return false; } internal static bool IsSupportedDtlsVersionServer(ProtocolVersion version) { if (version != null && version.IsEqualOrLaterVersionOf(SERVER_EARLIEST_SUPPORTED_DTLS)) return version.IsEqualOrEarlierVersionOf(SERVER_LATEST_SUPPORTED_DTLS); return false; } internal static bool IsSupportedTlsVersionClient(ProtocolVersion version) { if (version == null) return false; int fullVersion = version.FullVersion; if (fullVersion >= CLIENT_EARLIEST_SUPPORTED_TLS.FullVersion) return fullVersion <= CLIENT_LATEST_SUPPORTED_TLS.FullVersion; return false; } internal static bool IsSupportedTlsVersionServer(ProtocolVersion version) { if (version == null) return false; int fullVersion = version.FullVersion; if (fullVersion >= SERVER_EARLIEST_SUPPORTED_TLS.FullVersion) return fullVersion <= SERVER_LATEST_SUPPORTED_TLS.FullVersion; return false; } private ProtocolVersion(int v, string name) { version = (v & 65535); this.name = name; } public ProtocolVersion[] DownTo(ProtocolVersion min) { if (!IsEqualOrLaterVersionOf(min)) throw new ArgumentException("must be an equal or earlier version of this one", "min"); List<ProtocolVersion> list = new List<ProtocolVersion>(); list.Add(this); ProtocolVersion protocolVersion = this; while (!protocolVersion.Equals(min)) { protocolVersion = protocolVersion.GetPreviousVersion(); list.Add(protocolVersion); } return list.ToArray(); } public ProtocolVersion GetEquivalentTlsVersion() { switch (MajorVersion) { case 3: return this; case 254: switch (MinorVersion) { case 255: return TLSv11; case 253: return TLSv12; case 252: return TLSv13; default: return null; } default: return null; } } public ProtocolVersion GetNextVersion() { int majorVersion = MajorVersion; int minorVersion = MinorVersion; switch (majorVersion) { case 3: if (minorVersion == 255) return null; return Get(majorVersion, minorVersion + 1); case 254: switch (minorVersion) { case 0: return null; case 255: return DTLSv12; default: return Get(majorVersion, minorVersion - 1); } default: return null; } } public ProtocolVersion GetPreviousVersion() { int majorVersion = MajorVersion; int minorVersion = MinorVersion; switch (majorVersion) { case 3: if (minorVersion == 0) return null; return Get(majorVersion, minorVersion - 1); case 254: switch (minorVersion) { case 255: return null; case 253: return DTLSv10; default: return Get(majorVersion, minorVersion + 1); } default: return null; } } public bool IsEarlierVersionOf(ProtocolVersion version) { if (version == null || MajorVersion != version.MajorVersion) return false; int num = MinorVersion - version.MinorVersion; if (!IsDtls) return num < 0; return num > 0; } public bool IsEqualOrEarlierVersionOf(ProtocolVersion version) { if (version == null || MajorVersion != version.MajorVersion) return false; int num = MinorVersion - version.MinorVersion; if (!IsDtls) return num <= 0; return num >= 0; } public bool IsEqualOrLaterVersionOf(ProtocolVersion version) { if (version == null || MajorVersion != version.MajorVersion) return false; int num = MinorVersion - version.MinorVersion; if (!IsDtls) return num >= 0; return num <= 0; } public bool IsLaterVersionOf(ProtocolVersion version) { if (version == null || MajorVersion != version.MajorVersion) return false; int num = MinorVersion - version.MinorVersion; if (!IsDtls) return num > 0; return num < 0; } public override bool Equals(object other) { if (this != other) { if (other is ProtocolVersion) return Equals((ProtocolVersion)other); return false; } return true; } public bool Equals(ProtocolVersion other) { if (other != null) return version == other.version; return false; } public override int GetHashCode() { return version; } public static ProtocolVersion Get(int major, int minor) { switch (major) { case 3: switch (minor) { case 0: return SSLv3; case 1: return TLSv10; case 2: return TLSv11; case 3: return TLSv12; case 4: return TLSv13; default: return GetUnknownVersion(major, minor, "TLS"); } case 254: switch (minor) { case 255: return DTLSv10; case 254: throw new ArgumentException("{0xFE, 0xFE} is a reserved protocol version"); case 253: return DTLSv12; case 252: return DTLSv13; default: return GetUnknownVersion(major, minor, "DTLS"); } default: return GetUnknownVersion(major, minor, "UNKNOWN"); } } public ProtocolVersion[] Only() { return new ProtocolVersion[1] { this }; } public override string ToString() { return name; } private static void CheckUint8(int versionOctet) { if (!TlsUtilities.IsValidUint8(versionOctet)) throw new ArgumentException("not a valid octet", "versionOctet"); } private static ProtocolVersion GetUnknownVersion(int major, int minor, string prefix) { CheckUint8(major); CheckUint8(minor); int num = (major << 8) | minor; string str = Convert.ToString(65536 | num, 16).Substring(1).ToUpperInvariant(); return new ProtocolVersion(num, prefix + " 0x" + str); } } }