261 lines
7.3 KiB
C#
261 lines
7.3 KiB
C#
using System.Collections;
|
|
using Org.BouncyCastle.Utilities;
|
|
|
|
namespace Org.BouncyCastle.Crypto.Tls;
|
|
|
|
public abstract class AbstractTlsServer : AbstractTlsPeer, TlsServer, TlsPeer
|
|
{
|
|
protected TlsCipherFactory mCipherFactory;
|
|
|
|
protected TlsServerContext mContext;
|
|
|
|
protected ProtocolVersion mClientVersion;
|
|
|
|
protected int[] mOfferedCipherSuites;
|
|
|
|
protected byte[] mOfferedCompressionMethods;
|
|
|
|
protected IDictionary mClientExtensions;
|
|
|
|
protected bool mEncryptThenMacOffered;
|
|
|
|
protected short mMaxFragmentLengthOffered;
|
|
|
|
protected bool mTruncatedHMacOffered;
|
|
|
|
protected IList mSupportedSignatureAlgorithms;
|
|
|
|
protected bool mEccCipherSuitesOffered;
|
|
|
|
protected int[] mNamedCurves;
|
|
|
|
protected byte[] mClientECPointFormats;
|
|
|
|
protected byte[] mServerECPointFormats;
|
|
|
|
protected ProtocolVersion mServerVersion;
|
|
|
|
protected int mSelectedCipherSuite;
|
|
|
|
protected byte mSelectedCompressionMethod;
|
|
|
|
protected IDictionary mServerExtensions;
|
|
|
|
protected virtual bool AllowEncryptThenMac => true;
|
|
|
|
protected virtual bool AllowTruncatedHMac => false;
|
|
|
|
protected virtual ProtocolVersion MaximumVersion => ProtocolVersion.TLSv11;
|
|
|
|
protected virtual ProtocolVersion MinimumVersion => ProtocolVersion.TLSv10;
|
|
|
|
public AbstractTlsServer()
|
|
: this(new DefaultTlsCipherFactory())
|
|
{
|
|
}
|
|
|
|
public AbstractTlsServer(TlsCipherFactory cipherFactory)
|
|
{
|
|
mCipherFactory = cipherFactory;
|
|
}
|
|
|
|
protected virtual IDictionary CheckServerExtensions()
|
|
{
|
|
return mServerExtensions = TlsExtensionsUtilities.EnsureExtensionsInitialised(mServerExtensions);
|
|
}
|
|
|
|
protected abstract int[] GetCipherSuites();
|
|
|
|
protected byte[] GetCompressionMethods()
|
|
{
|
|
return new byte[1];
|
|
}
|
|
|
|
protected virtual bool SupportsClientEccCapabilities(int[] namedCurves, byte[] ecPointFormats)
|
|
{
|
|
if (namedCurves == null)
|
|
{
|
|
return TlsEccUtilities.HasAnySupportedNamedCurves();
|
|
}
|
|
foreach (int namedCurve in namedCurves)
|
|
{
|
|
if (NamedCurve.IsValid(namedCurve) && (!NamedCurve.RefersToASpecificNamedCurve(namedCurve) || TlsEccUtilities.IsSupportedNamedCurve(namedCurve)))
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
public virtual void Init(TlsServerContext context)
|
|
{
|
|
mContext = context;
|
|
}
|
|
|
|
public virtual void NotifyClientVersion(ProtocolVersion clientVersion)
|
|
{
|
|
mClientVersion = clientVersion;
|
|
}
|
|
|
|
public virtual void NotifyFallback(bool isFallback)
|
|
{
|
|
if (isFallback && MaximumVersion.IsLaterVersionOf(mClientVersion))
|
|
{
|
|
throw new TlsFatalAlert(86);
|
|
}
|
|
}
|
|
|
|
public virtual void NotifyOfferedCipherSuites(int[] offeredCipherSuites)
|
|
{
|
|
mOfferedCipherSuites = offeredCipherSuites;
|
|
mEccCipherSuitesOffered = TlsEccUtilities.ContainsEccCipherSuites(mOfferedCipherSuites);
|
|
}
|
|
|
|
public virtual void NotifyOfferedCompressionMethods(byte[] offeredCompressionMethods)
|
|
{
|
|
mOfferedCompressionMethods = offeredCompressionMethods;
|
|
}
|
|
|
|
public virtual void ProcessClientExtensions(IDictionary clientExtensions)
|
|
{
|
|
mClientExtensions = clientExtensions;
|
|
if (clientExtensions != null)
|
|
{
|
|
mEncryptThenMacOffered = TlsExtensionsUtilities.HasEncryptThenMacExtension(clientExtensions);
|
|
mMaxFragmentLengthOffered = TlsExtensionsUtilities.GetMaxFragmentLengthExtension(clientExtensions);
|
|
if (mMaxFragmentLengthOffered >= 0 && !MaxFragmentLength.IsValid((byte)mMaxFragmentLengthOffered))
|
|
{
|
|
throw new TlsFatalAlert(47);
|
|
}
|
|
mTruncatedHMacOffered = TlsExtensionsUtilities.HasTruncatedHMacExtension(clientExtensions);
|
|
mSupportedSignatureAlgorithms = TlsUtilities.GetSignatureAlgorithmsExtension(clientExtensions);
|
|
if (mSupportedSignatureAlgorithms != null && !TlsUtilities.IsSignatureAlgorithmsExtensionAllowed(mClientVersion))
|
|
{
|
|
throw new TlsFatalAlert(47);
|
|
}
|
|
mNamedCurves = TlsEccUtilities.GetSupportedEllipticCurvesExtension(clientExtensions);
|
|
mClientECPointFormats = TlsEccUtilities.GetSupportedPointFormatsExtension(clientExtensions);
|
|
}
|
|
}
|
|
|
|
public virtual ProtocolVersion GetServerVersion()
|
|
{
|
|
if (MinimumVersion.IsEqualOrEarlierVersionOf(mClientVersion))
|
|
{
|
|
ProtocolVersion maximumVersion = MaximumVersion;
|
|
if (mClientVersion.IsEqualOrEarlierVersionOf(maximumVersion))
|
|
{
|
|
return mServerVersion = mClientVersion;
|
|
}
|
|
if (mClientVersion.IsLaterVersionOf(maximumVersion))
|
|
{
|
|
return mServerVersion = maximumVersion;
|
|
}
|
|
}
|
|
throw new TlsFatalAlert(70);
|
|
}
|
|
|
|
public virtual int GetSelectedCipherSuite()
|
|
{
|
|
IList usableSignatureAlgorithms = TlsUtilities.GetUsableSignatureAlgorithms(mSupportedSignatureAlgorithms);
|
|
bool flag = SupportsClientEccCapabilities(mNamedCurves, mClientECPointFormats);
|
|
int[] cipherSuites = GetCipherSuites();
|
|
foreach (int num in cipherSuites)
|
|
{
|
|
if (Arrays.Contains(mOfferedCipherSuites, num) && (flag || !TlsEccUtilities.IsEccCipherSuite(num)) && TlsUtilities.IsValidCipherSuiteForVersion(num, mServerVersion) && TlsUtilities.IsValidCipherSuiteForSignatureAlgorithms(num, usableSignatureAlgorithms))
|
|
{
|
|
return mSelectedCipherSuite = num;
|
|
}
|
|
}
|
|
throw new TlsFatalAlert(40);
|
|
}
|
|
|
|
public virtual byte GetSelectedCompressionMethod()
|
|
{
|
|
byte[] compressionMethods = GetCompressionMethods();
|
|
for (int i = 0; i < compressionMethods.Length; i++)
|
|
{
|
|
if (Arrays.Contains(mOfferedCompressionMethods, compressionMethods[i]))
|
|
{
|
|
return mSelectedCompressionMethod = compressionMethods[i];
|
|
}
|
|
}
|
|
throw new TlsFatalAlert(40);
|
|
}
|
|
|
|
public virtual IDictionary GetServerExtensions()
|
|
{
|
|
if (mEncryptThenMacOffered && AllowEncryptThenMac && TlsUtilities.IsBlockCipherSuite(mSelectedCipherSuite))
|
|
{
|
|
TlsExtensionsUtilities.AddEncryptThenMacExtension(CheckServerExtensions());
|
|
}
|
|
if (mMaxFragmentLengthOffered >= 0 && TlsUtilities.IsValidUint8(mMaxFragmentLengthOffered) && MaxFragmentLength.IsValid((byte)mMaxFragmentLengthOffered))
|
|
{
|
|
TlsExtensionsUtilities.AddMaxFragmentLengthExtension(CheckServerExtensions(), (byte)mMaxFragmentLengthOffered);
|
|
}
|
|
if (mTruncatedHMacOffered && AllowTruncatedHMac)
|
|
{
|
|
TlsExtensionsUtilities.AddTruncatedHMacExtension(CheckServerExtensions());
|
|
}
|
|
if (mClientECPointFormats != null && TlsEccUtilities.IsEccCipherSuite(mSelectedCipherSuite))
|
|
{
|
|
mServerECPointFormats = new byte[3] { 0, 1, 2 };
|
|
TlsEccUtilities.AddSupportedPointFormatsExtension(CheckServerExtensions(), mServerECPointFormats);
|
|
}
|
|
return mServerExtensions;
|
|
}
|
|
|
|
public virtual IList GetServerSupplementalData()
|
|
{
|
|
return null;
|
|
}
|
|
|
|
public abstract TlsCredentials GetCredentials();
|
|
|
|
public virtual CertificateStatus GetCertificateStatus()
|
|
{
|
|
return null;
|
|
}
|
|
|
|
public abstract TlsKeyExchange GetKeyExchange();
|
|
|
|
public virtual CertificateRequest GetCertificateRequest()
|
|
{
|
|
return null;
|
|
}
|
|
|
|
public virtual void ProcessClientSupplementalData(IList clientSupplementalData)
|
|
{
|
|
if (clientSupplementalData != null)
|
|
{
|
|
throw new TlsFatalAlert(10);
|
|
}
|
|
}
|
|
|
|
public virtual void NotifyClientCertificate(Certificate clientCertificate)
|
|
{
|
|
throw new TlsFatalAlert(80);
|
|
}
|
|
|
|
public override TlsCompression GetCompression()
|
|
{
|
|
if (mSelectedCompressionMethod == 0)
|
|
{
|
|
return new TlsNullCompression();
|
|
}
|
|
throw new TlsFatalAlert(80);
|
|
}
|
|
|
|
public override TlsCipher GetCipher()
|
|
{
|
|
int encryptionAlgorithm = TlsUtilities.GetEncryptionAlgorithm(mSelectedCipherSuite);
|
|
int macAlgorithm = TlsUtilities.GetMacAlgorithm(mSelectedCipherSuite);
|
|
return mCipherFactory.CreateCipher(mContext, encryptionAlgorithm, macAlgorithm);
|
|
}
|
|
|
|
public virtual NewSessionTicket GetNewSessionTicket()
|
|
{
|
|
return new NewSessionTicket(0L, TlsUtilities.EmptyBytes);
|
|
}
|
|
}
|