init commit

This commit is contained in:
2025-10-09 09:57:24 +09:00
commit 4d551bd74f
6636 changed files with 1218703 additions and 0 deletions

View File

@@ -0,0 +1,558 @@
using System;
using System.Collections;
using System.IO;
using Org.BouncyCastle.Asn1.X509;
using Org.BouncyCastle.Security;
using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Crypto.Tls;
public class TlsServerProtocol : TlsProtocol
{
protected TlsServer mTlsServer = null;
internal TlsServerContextImpl mTlsServerContext = null;
protected TlsKeyExchange mKeyExchange = null;
protected TlsCredentials mServerCredentials = null;
protected CertificateRequest mCertificateRequest = null;
protected short mClientCertificateType = -1;
protected TlsHandshakeHash mPrepareFinishHash = null;
protected override TlsContext Context => mTlsServerContext;
internal override AbstractTlsContext ContextAdmin => mTlsServerContext;
protected override TlsPeer Peer => mTlsServer;
public TlsServerProtocol(Stream stream, SecureRandom secureRandom)
: base(stream, secureRandom)
{
}
public TlsServerProtocol(Stream input, Stream output, SecureRandom secureRandom)
: base(input, output, secureRandom)
{
}
public TlsServerProtocol(SecureRandom secureRandom)
: base(secureRandom)
{
}
public virtual void Accept(TlsServer tlsServer)
{
if (tlsServer == null)
{
throw new ArgumentNullException("tlsServer");
}
if (mTlsServer != null)
{
throw new InvalidOperationException("'Accept' can only be called once");
}
mTlsServer = tlsServer;
mSecurityParameters = new SecurityParameters();
mSecurityParameters.entity = 0;
mTlsServerContext = new TlsServerContextImpl(mSecureRandom, mSecurityParameters);
mSecurityParameters.serverRandom = TlsProtocol.CreateRandomBlock(tlsServer.ShouldUseGmtUnixTime(), mTlsServerContext.NonceRandomGenerator);
mTlsServer.Init(mTlsServerContext);
mRecordStream.Init(mTlsServerContext);
mRecordStream.SetRestrictReadVersion(enabled: false);
BlockForHandshake();
}
protected override void CleanupHandshake()
{
base.CleanupHandshake();
mKeyExchange = null;
mServerCredentials = null;
mCertificateRequest = null;
mPrepareFinishHash = null;
}
protected override void HandleHandshakeMessage(byte type, MemoryStream buf)
{
switch (type)
{
case 1:
switch (mConnectionState)
{
case 0:
{
ReceiveClientHelloMessage(buf);
mConnectionState = 1;
SendServerHelloMessage();
mConnectionState = 2;
mRecordStream.NotifyHelloComplete();
IList serverSupplementalData = mTlsServer.GetServerSupplementalData();
if (serverSupplementalData != null)
{
SendSupplementalDataMessage(serverSupplementalData);
}
mConnectionState = 3;
mKeyExchange = mTlsServer.GetKeyExchange();
mKeyExchange.Init(Context);
mServerCredentials = mTlsServer.GetCredentials();
Certificate certificate = null;
if (mServerCredentials == null)
{
mKeyExchange.SkipServerCredentials();
}
else
{
mKeyExchange.ProcessServerCredentials(mServerCredentials);
certificate = mServerCredentials.Certificate;
SendCertificateMessage(certificate);
}
mConnectionState = 4;
if (certificate == null || certificate.IsEmpty)
{
mAllowCertificateStatus = false;
}
if (mAllowCertificateStatus)
{
CertificateStatus certificateStatus = mTlsServer.GetCertificateStatus();
if (certificateStatus != null)
{
SendCertificateStatusMessage(certificateStatus);
}
}
mConnectionState = 5;
byte[] array = mKeyExchange.GenerateServerKeyExchange();
if (array != null)
{
SendServerKeyExchangeMessage(array);
}
mConnectionState = 6;
if (mServerCredentials != null)
{
mCertificateRequest = mTlsServer.GetCertificateRequest();
if (mCertificateRequest != null)
{
if (TlsUtilities.IsTlsV12(Context) != (mCertificateRequest.SupportedSignatureAlgorithms != null))
{
throw new TlsFatalAlert(80);
}
mKeyExchange.ValidateCertificateRequest(mCertificateRequest);
SendCertificateRequestMessage(mCertificateRequest);
TlsUtilities.TrackHashAlgorithms(mRecordStream.HandshakeHash, mCertificateRequest.SupportedSignatureAlgorithms);
}
}
mConnectionState = 7;
SendServerHelloDoneMessage();
mConnectionState = 8;
mRecordStream.HandshakeHash.SealHashAlgorithms();
break;
}
case 16:
RefuseRenegotiation();
break;
default:
throw new TlsFatalAlert(10);
}
break;
case 23:
{
short num = mConnectionState;
if (num == 8)
{
mTlsServer.ProcessClientSupplementalData(TlsProtocol.ReadSupplementalDataMessage(buf));
mConnectionState = 9;
break;
}
throw new TlsFatalAlert(10);
}
case 11:
switch (mConnectionState)
{
case 8:
case 9:
if (mConnectionState < 9)
{
mTlsServer.ProcessClientSupplementalData(null);
}
if (mCertificateRequest == null)
{
throw new TlsFatalAlert(10);
}
ReceiveCertificateMessage(buf);
mConnectionState = 10;
break;
default:
throw new TlsFatalAlert(10);
}
break;
case 16:
switch (mConnectionState)
{
case 8:
case 9:
case 10:
if (mConnectionState < 9)
{
mTlsServer.ProcessClientSupplementalData(null);
}
if (mConnectionState < 10)
{
if (mCertificateRequest == null)
{
mKeyExchange.SkipClientCredentials();
}
else
{
if (TlsUtilities.IsTlsV12(Context))
{
throw new TlsFatalAlert(10);
}
if (TlsUtilities.IsSsl(Context))
{
if (mPeerCertificate == null)
{
throw new TlsFatalAlert(10);
}
}
else
{
NotifyClientCertificate(Certificate.EmptyChain);
}
}
}
ReceiveClientKeyExchangeMessage(buf);
mConnectionState = 11;
break;
default:
throw new TlsFatalAlert(10);
}
break;
case 15:
{
short num = mConnectionState;
if (num == 11)
{
if (!ExpectCertificateVerifyMessage())
{
throw new TlsFatalAlert(10);
}
ReceiveCertificateVerifyMessage(buf);
mConnectionState = 12;
break;
}
throw new TlsFatalAlert(10);
}
case 20:
switch (mConnectionState)
{
case 11:
case 12:
if (mConnectionState < 12 && ExpectCertificateVerifyMessage())
{
throw new TlsFatalAlert(10);
}
ProcessFinishedMessage(buf);
mConnectionState = 13;
if (mExpectSessionTicket)
{
SendNewSessionTicketMessage(mTlsServer.GetNewSessionTicket());
}
mConnectionState = 14;
SendChangeCipherSpecMessage();
SendFinishedMessage();
mConnectionState = 15;
CompleteHandshake();
break;
default:
throw new TlsFatalAlert(10);
}
break;
default:
throw new TlsFatalAlert(10);
}
}
protected override void HandleAlertWarningMessage(byte alertDescription)
{
base.HandleAlertWarningMessage(alertDescription);
byte b = alertDescription;
if (b != 41)
{
return;
}
if (TlsUtilities.IsSsl(Context) && mCertificateRequest != null)
{
switch (mConnectionState)
{
case 8:
case 9:
if (mConnectionState < 9)
{
mTlsServer.ProcessClientSupplementalData(null);
}
NotifyClientCertificate(Certificate.EmptyChain);
mConnectionState = 10;
return;
}
}
throw new TlsFatalAlert(10);
}
protected virtual void NotifyClientCertificate(Certificate clientCertificate)
{
if (mCertificateRequest == null)
{
throw new InvalidOperationException();
}
if (mPeerCertificate != null)
{
throw new TlsFatalAlert(10);
}
mPeerCertificate = clientCertificate;
if (clientCertificate.IsEmpty)
{
mKeyExchange.SkipClientCredentials();
}
else
{
mClientCertificateType = TlsUtilities.GetClientCertificateType(clientCertificate, mServerCredentials.Certificate);
mKeyExchange.ProcessClientCertificate(clientCertificate);
}
mTlsServer.NotifyClientCertificate(clientCertificate);
}
protected virtual void ReceiveCertificateMessage(MemoryStream buf)
{
Certificate clientCertificate = Certificate.Parse(buf);
TlsProtocol.AssertEmpty(buf);
NotifyClientCertificate(clientCertificate);
}
protected virtual void ReceiveCertificateVerifyMessage(MemoryStream buf)
{
if (mCertificateRequest == null)
{
throw new InvalidOperationException();
}
DigitallySigned digitallySigned = DigitallySigned.Parse(Context, buf);
TlsProtocol.AssertEmpty(buf);
try
{
SignatureAndHashAlgorithm algorithm = digitallySigned.Algorithm;
byte[] hash;
if (TlsUtilities.IsTlsV12(Context))
{
TlsUtilities.VerifySupportedSignatureAlgorithm(mCertificateRequest.SupportedSignatureAlgorithms, algorithm);
hash = mPrepareFinishHash.GetFinalHash(algorithm.Hash);
}
else
{
hash = mSecurityParameters.SessionHash;
}
X509CertificateStructure certificateAt = mPeerCertificate.GetCertificateAt(0);
SubjectPublicKeyInfo subjectPublicKeyInfo = certificateAt.SubjectPublicKeyInfo;
AsymmetricKeyParameter publicKey = PublicKeyFactory.CreateKey(subjectPublicKeyInfo);
TlsSigner tlsSigner = TlsUtilities.CreateTlsSigner((byte)mClientCertificateType);
tlsSigner.Init(Context);
if (!tlsSigner.VerifyRawSignature(algorithm, digitallySigned.Signature, publicKey, hash))
{
throw new TlsFatalAlert(51);
}
}
catch (TlsFatalAlert tlsFatalAlert)
{
throw tlsFatalAlert;
}
catch (Exception alertCause)
{
throw new TlsFatalAlert(51, alertCause);
}
}
protected virtual void ReceiveClientHelloMessage(MemoryStream buf)
{
ProtocolVersion protocolVersion = TlsUtilities.ReadVersion(buf);
mRecordStream.SetWriteVersion(protocolVersion);
if (protocolVersion.IsDtls)
{
throw new TlsFatalAlert(47);
}
byte[] clientRandom = TlsUtilities.ReadFully(32, buf);
byte[] array = TlsUtilities.ReadOpaque8(buf);
if (array.Length > 32)
{
throw new TlsFatalAlert(47);
}
int num = TlsUtilities.ReadUint16(buf);
if (num < 2 || (num & 1) != 0)
{
throw new TlsFatalAlert(50);
}
mOfferedCipherSuites = TlsUtilities.ReadUint16Array(num / 2, buf);
int num2 = TlsUtilities.ReadUint8(buf);
if (num2 < 1)
{
throw new TlsFatalAlert(47);
}
mOfferedCompressionMethods = TlsUtilities.ReadUint8Array(num2, buf);
mClientExtensions = TlsProtocol.ReadExtensions(buf);
mSecurityParameters.extendedMasterSecret = TlsExtensionsUtilities.HasExtendedMasterSecretExtension(mClientExtensions);
if (!mSecurityParameters.IsExtendedMasterSecret && mTlsServer.RequiresExtendedMasterSecret())
{
throw new TlsFatalAlert(40);
}
ContextAdmin.SetClientVersion(protocolVersion);
mTlsServer.NotifyClientVersion(protocolVersion);
mTlsServer.NotifyFallback(Arrays.Contains(mOfferedCipherSuites, 22016));
mSecurityParameters.clientRandom = clientRandom;
mTlsServer.NotifyOfferedCipherSuites(mOfferedCipherSuites);
mTlsServer.NotifyOfferedCompressionMethods(mOfferedCompressionMethods);
if (Arrays.Contains(mOfferedCipherSuites, 255))
{
mSecureRenegotiation = true;
}
byte[] extensionData = TlsUtilities.GetExtensionData(mClientExtensions, 65281);
if (extensionData != null)
{
mSecureRenegotiation = true;
if (!Arrays.ConstantTimeAreEqual(extensionData, TlsProtocol.CreateRenegotiationInfo(TlsUtilities.EmptyBytes)))
{
throw new TlsFatalAlert(40);
}
}
mTlsServer.NotifySecureRenegotiation(mSecureRenegotiation);
if (mClientExtensions != null)
{
TlsExtensionsUtilities.GetPaddingExtension(mClientExtensions);
mTlsServer.ProcessClientExtensions(mClientExtensions);
}
}
protected virtual void ReceiveClientKeyExchangeMessage(MemoryStream buf)
{
mKeyExchange.ProcessClientKeyExchange(buf);
TlsProtocol.AssertEmpty(buf);
if (TlsUtilities.IsSsl(Context))
{
TlsProtocol.EstablishMasterSecret(Context, mKeyExchange);
}
mPrepareFinishHash = mRecordStream.PrepareToFinish();
mSecurityParameters.sessionHash = TlsProtocol.GetCurrentPrfHash(Context, mPrepareFinishHash, null);
if (!TlsUtilities.IsSsl(Context))
{
TlsProtocol.EstablishMasterSecret(Context, mKeyExchange);
}
mRecordStream.SetPendingConnectionState(Peer.GetCompression(), Peer.GetCipher());
}
protected virtual void SendCertificateRequestMessage(CertificateRequest certificateRequest)
{
HandshakeMessage handshakeMessage = new HandshakeMessage(13);
certificateRequest.Encode(handshakeMessage);
handshakeMessage.WriteToRecordStream(this);
}
protected virtual void SendCertificateStatusMessage(CertificateStatus certificateStatus)
{
HandshakeMessage handshakeMessage = new HandshakeMessage(22);
certificateStatus.Encode(handshakeMessage);
handshakeMessage.WriteToRecordStream(this);
}
protected virtual void SendNewSessionTicketMessage(NewSessionTicket newSessionTicket)
{
if (newSessionTicket == null)
{
throw new TlsFatalAlert(80);
}
HandshakeMessage handshakeMessage = new HandshakeMessage(4);
newSessionTicket.Encode(handshakeMessage);
handshakeMessage.WriteToRecordStream(this);
}
protected virtual void SendServerHelloMessage()
{
HandshakeMessage handshakeMessage = new HandshakeMessage(2);
ProtocolVersion serverVersion = mTlsServer.GetServerVersion();
if (!serverVersion.IsEqualOrEarlierVersionOf(Context.ClientVersion))
{
throw new TlsFatalAlert(80);
}
mRecordStream.ReadVersion = serverVersion;
mRecordStream.SetWriteVersion(serverVersion);
mRecordStream.SetRestrictReadVersion(enabled: true);
ContextAdmin.SetServerVersion(serverVersion);
TlsUtilities.WriteVersion(serverVersion, handshakeMessage);
handshakeMessage.Write(mSecurityParameters.serverRandom);
TlsUtilities.WriteOpaque8(TlsUtilities.EmptyBytes, handshakeMessage);
int selectedCipherSuite = mTlsServer.GetSelectedCipherSuite();
if (!Arrays.Contains(mOfferedCipherSuites, selectedCipherSuite) || selectedCipherSuite == 0 || CipherSuite.IsScsv(selectedCipherSuite) || !TlsUtilities.IsValidCipherSuiteForVersion(selectedCipherSuite, Context.ServerVersion))
{
throw new TlsFatalAlert(80);
}
mSecurityParameters.cipherSuite = selectedCipherSuite;
byte selectedCompressionMethod = mTlsServer.GetSelectedCompressionMethod();
if (!Arrays.Contains(mOfferedCompressionMethods, selectedCompressionMethod))
{
throw new TlsFatalAlert(80);
}
mSecurityParameters.compressionAlgorithm = selectedCompressionMethod;
TlsUtilities.WriteUint16(selectedCipherSuite, handshakeMessage);
TlsUtilities.WriteUint8(selectedCompressionMethod, handshakeMessage);
mServerExtensions = TlsExtensionsUtilities.EnsureExtensionsInitialised(mTlsServer.GetServerExtensions());
if (mSecureRenegotiation)
{
byte[] extensionData = TlsUtilities.GetExtensionData(mServerExtensions, 65281);
if (null == extensionData)
{
mServerExtensions[65281] = TlsProtocol.CreateRenegotiationInfo(TlsUtilities.EmptyBytes);
}
}
if (TlsUtilities.IsSsl(mTlsServerContext))
{
mSecurityParameters.extendedMasterSecret = false;
}
else if (mSecurityParameters.IsExtendedMasterSecret)
{
TlsExtensionsUtilities.AddExtendedMasterSecretExtension(mServerExtensions);
}
if (mServerExtensions.Count > 0)
{
mSecurityParameters.encryptThenMac = TlsExtensionsUtilities.HasEncryptThenMacExtension(mServerExtensions);
mSecurityParameters.maxFragmentLength = ProcessMaxFragmentLengthExtension(mClientExtensions, mServerExtensions, 80);
mSecurityParameters.truncatedHMac = TlsExtensionsUtilities.HasTruncatedHMacExtension(mServerExtensions);
mAllowCertificateStatus = !mResumedSession && TlsUtilities.HasExpectedEmptyExtensionData(mServerExtensions, 5, 80);
mExpectSessionTicket = !mResumedSession && TlsUtilities.HasExpectedEmptyExtensionData(mServerExtensions, 35, 80);
TlsProtocol.WriteExtensions(handshakeMessage, mServerExtensions);
}
mSecurityParameters.prfAlgorithm = TlsProtocol.GetPrfAlgorithm(Context, mSecurityParameters.CipherSuite);
mSecurityParameters.verifyDataLength = 12;
ApplyMaxFragmentLengthExtension();
handshakeMessage.WriteToRecordStream(this);
}
protected virtual void SendServerHelloDoneMessage()
{
byte[] array = new byte[4];
TlsUtilities.WriteUint8(14, array, 0);
TlsUtilities.WriteUint24(0, array, 1);
WriteHandshakeMessage(array, 0, array.Length);
}
protected virtual void SendServerKeyExchangeMessage(byte[] serverKeyExchange)
{
HandshakeMessage handshakeMessage = new HandshakeMessage(12, serverKeyExchange.Length);
handshakeMessage.Write(serverKeyExchange);
handshakeMessage.WriteToRecordStream(this);
}
protected virtual bool ExpectCertificateVerifyMessage()
{
if (mClientCertificateType >= 0)
{
return TlsUtilities.HasSigningCapability((byte)mClientCertificateType);
}
return false;
}
}