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);
}
}
}