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

AbstractTlsServer

Base class for a TLS server.
using Org.BouncyCastle.Tls.Crypto; using Org.BouncyCastle.Utilities; using System; using System.Collections.Generic; namespace Org.BouncyCastle.Tls { public abstract class AbstractTlsServer : AbstractTlsPeer, TlsServer, TlsPeer { protected TlsServerContext m_context; protected ProtocolVersion[] m_protocolVersions; protected int[] m_cipherSuites; protected int[] m_offeredCipherSuites; protected IDictionary<int, byte[]> m_clientExtensions; protected bool m_encryptThenMACOffered; protected short m_maxFragmentLengthOffered; protected bool m_truncatedHMacOffered; protected bool m_clientSentECPointFormats; protected CertificateStatusRequest m_certificateStatusRequest; protected IList<CertificateStatusRequestItemV2> m_statusRequestV2; protected IList<TrustedAuthority> m_trustedCAKeys; protected int m_selectedCipherSuite; protected IList<ProtocolName> m_clientProtocolNames; protected ProtocolName m_selectedProtocolName; protected readonly IDictionary<int, byte[]> m_serverExtensions = new Dictionary<int, byte[]>(); public AbstractTlsServer(TlsCrypto crypto) : base(crypto) { } protected virtual bool AllowCertificateStatus() { return true; } protected virtual bool AllowEncryptThenMac() { return true; } protected virtual bool AllowMultiCertStatus() { return false; } protected virtual bool AllowTruncatedHmac() { return false; } protected virtual bool AllowTrustedCAIndication() { return false; } protected virtual string GetDetailMessageNoCipherSuite() { return "No selectable cipher suite"; } protected virtual int GetMaximumNegotiableCurveBits() { int num = 0; int[] clientSupportedGroups = m_context.SecurityParameters.ClientSupportedGroups; if (clientSupportedGroups != null) { for (int i = 0; i < clientSupportedGroups.Length; i++) { num = System.Math.Max(num, NamedGroup.GetCurveBits(clientSupportedGroups[i])); } } else num = NamedGroup.GetMaximumCurveBits(); return num; } protected virtual int GetMaximumNegotiableFiniteFieldBits() { int num = 0; bool flag = false; int[] clientSupportedGroups = m_context.SecurityParameters.ClientSupportedGroups; if (clientSupportedGroups != null) { for (int i = 0; i < clientSupportedGroups.Length; i++) { flag |= NamedGroup.IsFiniteField(clientSupportedGroups[i]); num = System.Math.Max(num, NamedGroup.GetFiniteFieldBits(clientSupportedGroups[i])); } } if (!flag) num = NamedGroup.GetMaximumFiniteFieldBits(); return num; } protected virtual IList<ProtocolName> GetProtocolNames() { return null; } protected virtual bool IsSelectableCipherSuite(int cipherSuite, int availCurveBits, int availFiniteFieldBits, IList<short> sigAlgs) { if (TlsUtilities.IsValidVersionForCipherSuite(cipherSuite, m_context.ServerVersion) && availCurveBits >= TlsEccUtilities.GetMinimumCurveBits(cipherSuite) && availFiniteFieldBits >= TlsDHUtilities.GetMinimumFiniteFieldBits(cipherSuite)) return TlsUtilities.IsValidCipherSuiteForSignatureAlgorithms(cipherSuite, sigAlgs); return false; } protected virtual bool PreferLocalCipherSuites() { return false; } protected virtual bool SelectCipherSuite(int cipherSuite) { m_selectedCipherSuite = cipherSuite; return true; } protected virtual int SelectDH(int minimumFiniteFieldBits) { int[] clientSupportedGroups = m_context.SecurityParameters.ClientSupportedGroups; if (clientSupportedGroups == null) return SelectDHDefault(minimumFiniteFieldBits); foreach (int num in clientSupportedGroups) { if (NamedGroup.GetFiniteFieldBits(num) >= minimumFiniteFieldBits) return num; } return -1; } protected virtual int SelectDHDefault(int minimumFiniteFieldBits) { if (minimumFiniteFieldBits > 2048) { if (minimumFiniteFieldBits > 3072) { if (minimumFiniteFieldBits > 4096) { if (minimumFiniteFieldBits > 6144) { if (minimumFiniteFieldBits > 8192) return -1; return 260; } return 259; } return 258; } return 257; } return 256; } protected virtual int SelectECDH(int minimumCurveBits) { int[] clientSupportedGroups = m_context.SecurityParameters.ClientSupportedGroups; if (clientSupportedGroups == null) return SelectECDHDefault(minimumCurveBits); foreach (int num in clientSupportedGroups) { if (NamedGroup.GetCurveBits(num) >= minimumCurveBits) return num; } return -1; } protected virtual int SelectECDHDefault(int minimumCurveBits) { if (minimumCurveBits > 256) { if (minimumCurveBits > 384) { if (minimumCurveBits > 521) return -1; return 25; } return 24; } return 23; } protected virtual ProtocolName SelectProtocolName() { IList<ProtocolName> protocolNames = GetProtocolNames(); if (protocolNames == null || protocolNames.Count < 1) return null; ProtocolName protocolName = SelectProtocolName(m_clientProtocolNames, protocolNames); if (protocolName == null) throw new TlsFatalAlert(120); return protocolName; } protected virtual ProtocolName SelectProtocolName(IList<ProtocolName> clientProtocolNames, IList<ProtocolName> serverProtocolNames) { foreach (ProtocolName serverProtocolName in serverProtocolNames) { if (clientProtocolNames.Contains(serverProtocolName)) return serverProtocolName; } return null; } protected virtual bool ShouldSelectProtocolNameEarly() { return true; } protected virtual bool PreferLocalClientCertificateTypes() { return false; } protected virtual short[] GetAllowedClientCertificateTypes() { return null; } protected virtual byte[] GetNewConnectionID() { return null; } public virtual void Init(TlsServerContext context) { m_context = context; m_protocolVersions = GetSupportedVersions(); m_cipherSuites = GetSupportedCipherSuites(); } public override ProtocolVersion[] GetProtocolVersions() { return m_protocolVersions; } public override int[] GetCipherSuites() { return m_cipherSuites; } public override void NotifyHandshakeBeginning() { base.NotifyHandshakeBeginning(); m_offeredCipherSuites = null; m_clientExtensions = null; m_encryptThenMACOffered = false; m_maxFragmentLengthOffered = 0; m_truncatedHMacOffered = false; m_clientSentECPointFormats = false; m_certificateStatusRequest = null; m_selectedCipherSuite = -1; m_selectedProtocolName = null; m_serverExtensions.Clear(); } public virtual TlsSession GetSessionToResume(byte[] sessionID) { return null; } public virtual byte[] GetNewSessionID() { return null; } public virtual TlsPskExternal GetExternalPsk(IList<PskIdentity> identities) { return null; } public virtual void NotifySession(TlsSession session) { } public virtual void NotifyClientVersion(ProtocolVersion clientVersion) { } public virtual void NotifyFallback(bool isFallback) { if (isFallback) { ProtocolVersion[] protocolVersions = GetProtocolVersions(); ProtocolVersion clientVersion = m_context.ClientVersion; ProtocolVersion protocolVersion; if (clientVersion.IsTls) protocolVersion = ProtocolVersion.GetLatestTls(protocolVersions); else { if (!clientVersion.IsDtls) throw new TlsFatalAlert(80); protocolVersion = ProtocolVersion.GetLatestDtls(protocolVersions); } if (protocolVersion != null && protocolVersion.IsLaterVersionOf(clientVersion)) throw new TlsFatalAlert(86); } } public virtual void NotifyOfferedCipherSuites(int[] offeredCipherSuites) { m_offeredCipherSuites = offeredCipherSuites; } public virtual void ProcessClientExtensions(IDictionary<int, byte[]> clientExtensions) { m_clientExtensions = clientExtensions; if (clientExtensions != null) { m_clientProtocolNames = TlsExtensionsUtilities.GetAlpnExtensionClient(clientExtensions); if (ShouldSelectProtocolNameEarly() && m_clientProtocolNames != null && m_clientProtocolNames.Count > 0) m_selectedProtocolName = SelectProtocolName(); m_encryptThenMACOffered = TlsExtensionsUtilities.HasEncryptThenMacExtension(clientExtensions); m_truncatedHMacOffered = TlsExtensionsUtilities.HasTruncatedHmacExtension(clientExtensions); m_statusRequestV2 = TlsExtensionsUtilities.GetStatusRequestV2Extension(clientExtensions); m_trustedCAKeys = TlsExtensionsUtilities.GetTrustedCAKeysExtensionClient(clientExtensions); m_clientSentECPointFormats = (TlsExtensionsUtilities.GetSupportedPointFormatsExtension(clientExtensions) != null); m_certificateStatusRequest = TlsExtensionsUtilities.GetStatusRequestExtension(clientExtensions); m_maxFragmentLengthOffered = TlsExtensionsUtilities.GetMaxFragmentLengthExtension(clientExtensions); if (m_maxFragmentLengthOffered >= 0 && !MaxFragmentLength.IsValid(m_maxFragmentLengthOffered)) throw new TlsFatalAlert(47); } } public virtual ProtocolVersion GetServerVersion() { ProtocolVersion[] protocolVersions = GetProtocolVersions(); ProtocolVersion[] clientSupportedVersions = m_context.ClientSupportedVersions; foreach (ProtocolVersion protocolVersion in clientSupportedVersions) { if (ProtocolVersion.Contains(protocolVersions, protocolVersion)) return protocolVersion; } throw new TlsFatalAlert(70); } public virtual int[] GetSupportedGroups() { return new int[7] { 29, 30, 23, 24, 256, 257, 258 }; } public virtual int GetSelectedCipherSuite() { SecurityParameters securityParameters = m_context.SecurityParameters; ProtocolVersion negotiatedVersion = securityParameters.NegotiatedVersion; if (TlsUtilities.IsTlsV13(negotiatedVersion)) { int commonCipherSuite = TlsUtilities.GetCommonCipherSuite13(negotiatedVersion, m_offeredCipherSuites, GetCipherSuites(), PreferLocalCipherSuites()); if (commonCipherSuite >= 0 && SelectCipherSuite(commonCipherSuite)) return commonCipherSuite; } else { IList<short> usableSignatureAlgorithms = TlsUtilities.GetUsableSignatureAlgorithms(securityParameters.ClientSigAlgs); int maximumNegotiableCurveBits = GetMaximumNegotiableCurveBits(); int maximumNegotiableFiniteFieldBits = GetMaximumNegotiableFiniteFieldBits(); int[] commonCipherSuites = TlsUtilities.GetCommonCipherSuites(m_offeredCipherSuites, GetCipherSuites(), PreferLocalCipherSuites()); foreach (int num in commonCipherSuites) { if (IsSelectableCipherSuite(num, maximumNegotiableCurveBits, maximumNegotiableFiniteFieldBits, usableSignatureAlgorithms) && SelectCipherSuite(num)) return num; } } throw new TlsFatalAlert(40, GetDetailMessageNoCipherSuite()); } public virtual IDictionary<int, byte[]> GetServerExtensions() { bool flag = TlsUtilities.IsTlsV13(m_context); if (flag) { if (m_certificateStatusRequest != null && !AllowCertificateStatus()) goto IL_00e9; } else { if (m_encryptThenMACOffered && AllowEncryptThenMac() && TlsUtilities.IsBlockCipherSuite(m_selectedCipherSuite)) TlsExtensionsUtilities.AddEncryptThenMacExtension(m_serverExtensions); if (m_truncatedHMacOffered && AllowTruncatedHmac()) TlsExtensionsUtilities.AddTruncatedHmacExtension(m_serverExtensions); if (m_clientSentECPointFormats && TlsEccUtilities.IsEccCipherSuite(m_selectedCipherSuite)) TlsExtensionsUtilities.AddSupportedPointFormatsExtension(m_serverExtensions, new short[1]); if (m_statusRequestV2 != null && AllowMultiCertStatus()) TlsExtensionsUtilities.AddEmptyExtensionData(m_serverExtensions, 17); else if (m_certificateStatusRequest != null && AllowCertificateStatus()) { TlsExtensionsUtilities.AddEmptyExtensionData(m_serverExtensions, 5); } if (m_trustedCAKeys != null && AllowTrustedCAIndication()) TlsExtensionsUtilities.AddTrustedCAKeysExtensionServer(m_serverExtensions); } goto IL_00e9; IL_00e9: if (m_maxFragmentLengthOffered >= 0 && MaxFragmentLength.IsValid(m_maxFragmentLengthOffered)) TlsExtensionsUtilities.AddMaxFragmentLengthExtension(m_serverExtensions, m_maxFragmentLengthOffered); short[] serverCertificateTypeExtensionClient = TlsExtensionsUtilities.GetServerCertificateTypeExtensionClient(m_clientExtensions); if (serverCertificateTypeExtensionClient != null) { TlsCredentials credentials = GetCredentials(); if (credentials != null) { short certificateType = credentials.Certificate.CertificateType; if ((1 == certificateType) & flag) throw new TlsFatalAlert(80, "The OpenPGP certificate type MUST NOT be used with TLS 1.3"); if (!Arrays.Contains(serverCertificateTypeExtensionClient, certificateType)) throw new TlsFatalAlert(43); TlsExtensionsUtilities.AddServerCertificateTypeExtensionServer(m_serverExtensions, certificateType); } } short[] clientCertificateTypeExtensionClient = TlsExtensionsUtilities.GetClientCertificateTypeExtensionClient(m_clientExtensions); if (clientCertificateTypeExtensionClient != null) { short[] allowedClientCertificateTypes = GetAllowedClientCertificateTypes(); if (allowedClientCertificateTypes != null) { short[] array; short[] a; if (PreferLocalClientCertificateTypes()) { array = allowedClientCertificateTypes; a = clientCertificateTypeExtensionClient; } else { array = clientCertificateTypeExtensionClient; a = allowedClientCertificateTypes; } short num = -1; foreach (short num2 in array) { if (!((1 == num2) & flag) && Arrays.Contains(a, num2)) { num = num2; break; } } if (num == -1) throw new TlsFatalAlert(43); TlsExtensionsUtilities.AddClientCertificateTypeExtensionServer(m_serverExtensions, num); } } return m_serverExtensions; } public virtual void GetServerExtensionsForConnection(IDictionary<int, byte[]> serverExtensions) { if (!ShouldSelectProtocolNameEarly() && m_clientProtocolNames != null && m_clientProtocolNames.Count > 0) m_selectedProtocolName = SelectProtocolName(); if (m_selectedProtocolName == null) serverExtensions.Remove(16); else TlsExtensionsUtilities.AddAlpnExtensionServer(serverExtensions, m_selectedProtocolName); if (ProtocolVersion.DTLSv12.Equals(m_context.ServerVersion) && m_clientExtensions != null && m_clientExtensions.ContainsKey(54)) { byte[] newConnectionID = GetNewConnectionID(); if (newConnectionID != null) TlsExtensionsUtilities.AddConnectionIDExtension(m_serverExtensions, newConnectionID); } } public virtual IList<SupplementalDataEntry> GetServerSupplementalData() { return null; } public abstract TlsCredentials GetCredentials(); public virtual CertificateStatus GetCertificateStatus() { return null; } public virtual CertificateRequest GetCertificateRequest() { return null; } public virtual TlsPskIdentityManager GetPskIdentityManager() { return null; } public virtual TlsSrpLoginParameters GetSrpLoginParameters() { return null; } public virtual TlsDHConfig GetDHConfig() { int minimumFiniteFieldBits = TlsDHUtilities.GetMinimumFiniteFieldBits(m_selectedCipherSuite); int namedGroup = SelectDH(minimumFiniteFieldBits); return TlsDHUtilities.CreateNamedDHConfig(m_context, namedGroup); } public virtual TlsECConfig GetECDHConfig() { int minimumCurveBits = TlsEccUtilities.GetMinimumCurveBits(m_selectedCipherSuite); int namedGroup = SelectECDH(minimumCurveBits); return TlsEccUtilities.CreateNamedECConfig(m_context, namedGroup); } public virtual void ProcessClientSupplementalData(IList<SupplementalDataEntry> clientSupplementalData) { if (clientSupplementalData != null) throw new TlsFatalAlert(10); } public virtual void NotifyClientCertificate(Certificate clientCertificate) { throw new TlsFatalAlert(80); } public virtual NewSessionTicket GetNewSessionTicket() { return new NewSessionTicket(0, TlsUtilities.EmptyBytes); } } }