using System;
using System.Collections;
using System.IO;
using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Tls
{
public abstract class DtlsProtocol
{
internal DtlsProtocol()
{
}
///
internal virtual void ProcessFinished(byte[] body, byte[] expected_verify_data)
{
MemoryStream buf = new MemoryStream(body, false);
byte[] verify_data = TlsUtilities.ReadFully(expected_verify_data.Length, buf);
TlsProtocol.AssertEmpty(buf);
if (!Arrays.ConstantTimeAreEqual(expected_verify_data, verify_data))
throw new TlsFatalAlert(AlertDescription.handshake_failure);
}
///
internal static void ApplyMaxFragmentLengthExtension(DtlsRecordLayer recordLayer, short maxFragmentLength)
{
if (maxFragmentLength >= 0)
{
if (!MaxFragmentLength.IsValid(maxFragmentLength))
throw new TlsFatalAlert(AlertDescription.internal_error);
int plainTextLimit = 1 << (8 + maxFragmentLength);
recordLayer.SetPlaintextLimit(plainTextLimit);
}
}
///
internal static short EvaluateMaxFragmentLengthExtension(bool resumedSession, IDictionary clientExtensions,
IDictionary serverExtensions, short alertDescription)
{
short maxFragmentLength = TlsExtensionsUtilities.GetMaxFragmentLengthExtension(serverExtensions);
if (maxFragmentLength >= 0)
{
if (!MaxFragmentLength.IsValid(maxFragmentLength)
|| (!resumedSession && maxFragmentLength != TlsExtensionsUtilities
.GetMaxFragmentLengthExtension(clientExtensions)))
{
throw new TlsFatalAlert(alertDescription);
}
}
return maxFragmentLength;
}
///
internal static byte[] GenerateCertificate(TlsContext context, Certificate certificate, Stream endPointHash)
{
MemoryStream buf = new MemoryStream();
certificate.Encode(context, buf, endPointHash);
return buf.ToArray();
}
///
internal static byte[] GenerateSupplementalData(IList supplementalData)
{
MemoryStream buf = new MemoryStream();
TlsProtocol.WriteSupplementalData(buf, supplementalData);
return buf.ToArray();
}
///
internal static void SendCertificateMessage(TlsContext context, DtlsReliableHandshake handshake,
Certificate certificate, Stream endPointHash)
{
SecurityParameters securityParameters = context.SecurityParameters;
if (null != securityParameters.LocalCertificate)
throw new TlsFatalAlert(AlertDescription.internal_error);
if (null == certificate)
{
certificate = Certificate.EmptyChain;
}
byte[] certificateBody = GenerateCertificate(context, certificate, endPointHash);
handshake.SendMessage(HandshakeType.certificate, certificateBody);
securityParameters.m_localCertificate = certificate;
}
///
internal static int ValidateSelectedCipherSuite(int selectedCipherSuite, short alertDescription)
{
switch (TlsUtilities.GetEncryptionAlgorithm(selectedCipherSuite))
{
case EncryptionAlgorithm.RC4_40:
case EncryptionAlgorithm.RC4_128:
case -1:
throw new TlsFatalAlert(alertDescription);
default:
return selectedCipherSuite;
}
}
}
}