internal virtual DtlsTransport ClientHandshake(DtlsClientProtocol.ClientHandshakeState state, DtlsRecordLayer recordLayer)
{
SecurityParameters securityParameters = state.clientContext.SecurityParameters;
DtlsReliableHandshake dtlsReliableHandshake = new DtlsReliableHandshake(state.clientContext, recordLayer);
byte[] array = this.GenerateClientHello(state, state.client);
dtlsReliableHandshake.SendMessage(1, array);
DtlsReliableHandshake.Message message = dtlsReliableHandshake.ReceiveMessage();
while (message.Type == 3)
{
ProtocolVersion protocolVersion = recordLayer.ResetDiscoveredPeerVersion();
ProtocolVersion clientVersion = state.clientContext.ClientVersion;
if (!protocolVersion.IsEqualOrEarlierVersionOf(clientVersion))
{
throw new TlsFatalAlert(47);
}
byte[] cookie = this.ProcessHelloVerifyRequest(state, message.Body);
byte[] body = DtlsClientProtocol.PatchClientHelloWithCookie(array, cookie);
dtlsReliableHandshake.ResetHandshakeMessagesDigest();
dtlsReliableHandshake.SendMessage(1, body);
message = dtlsReliableHandshake.ReceiveMessage();
}
if (message.Type != 2)
{
throw new TlsFatalAlert(10);
}
this.ReportServerVersion(state, recordLayer.DiscoveredPeerVersion);
this.ProcessServerHello(state, message.Body);
dtlsReliableHandshake.NotifyHelloComplete();
DtlsProtocol.ApplyMaxFragmentLengthExtension(recordLayer, securityParameters.maxFragmentLength);
if (state.resumedSession)
{
securityParameters.masterSecret = Arrays.Clone(state.sessionParameters.MasterSecret);
recordLayer.InitPendingEpoch(state.client.GetCipher());
byte[] expected_verify_data = TlsUtilities.CalculateVerifyData(state.clientContext, "server finished", TlsProtocol.GetCurrentPrfHash(state.clientContext, dtlsReliableHandshake.HandshakeHash, null));
this.ProcessFinished(dtlsReliableHandshake.ReceiveMessageBody(20), expected_verify_data);
byte[] body2 = TlsUtilities.CalculateVerifyData(state.clientContext, "client finished", TlsProtocol.GetCurrentPrfHash(state.clientContext, dtlsReliableHandshake.HandshakeHash, null));
dtlsReliableHandshake.SendMessage(20, body2);
dtlsReliableHandshake.Finish();
state.clientContext.SetResumableSession(state.tlsSession);
state.client.NotifyHandshakeComplete();
return(new DtlsTransport(recordLayer));
}
this.InvalidateSession(state);
if (state.selectedSessionID.Length > 0)
{
state.tlsSession = new TlsSessionImpl(state.selectedSessionID, null);
}
message = dtlsReliableHandshake.ReceiveMessage();
if (message.Type == 23)
{
this.ProcessServerSupplementalData(state, message.Body);
message = dtlsReliableHandshake.ReceiveMessage();
}
else
{
state.client.ProcessServerSupplementalData(null);
}
state.keyExchange = state.client.GetKeyExchange();
state.keyExchange.Init(state.clientContext);
Certificate certificate = null;
if (message.Type == 11)
{
certificate = this.ProcessServerCertificate(state, message.Body);
message = dtlsReliableHandshake.ReceiveMessage();
}
else
{
state.keyExchange.SkipServerCredentials();
}
if (certificate == null || certificate.IsEmpty)
{
state.allowCertificateStatus = false;
}
if (message.Type == 22)
{
this.ProcessCertificateStatus(state, message.Body);
message = dtlsReliableHandshake.ReceiveMessage();
}
if (message.Type == 12)
{
this.ProcessServerKeyExchange(state, message.Body);
message = dtlsReliableHandshake.ReceiveMessage();
}
else
{
state.keyExchange.SkipServerKeyExchange();
}
if (message.Type == 13)
{
this.ProcessCertificateRequest(state, message.Body);
TlsUtilities.TrackHashAlgorithms(dtlsReliableHandshake.HandshakeHash, state.certificateRequest.SupportedSignatureAlgorithms);
message = dtlsReliableHandshake.ReceiveMessage();
}
if (message.Type != 14)
{
throw new TlsFatalAlert(10);
}
if (message.Body.Length != 0)
{
throw new TlsFatalAlert(50);
}
dtlsReliableHandshake.HandshakeHash.SealHashAlgorithms();
IList clientSupplementalData = state.client.GetClientSupplementalData();
if (clientSupplementalData != null)
{
byte[] body3 = DtlsProtocol.GenerateSupplementalData(clientSupplementalData);
dtlsReliableHandshake.SendMessage(23, body3);
}
if (state.certificateRequest != null)
{
state.clientCredentials = state.authentication.GetClientCredentials(state.certificateRequest);
Certificate certificate2 = null;
if (state.clientCredentials != null)
{
certificate2 = state.clientCredentials.Certificate;
}
if (certificate2 == null)
{
certificate2 = Certificate.EmptyChain;
}
byte[] body4 = DtlsProtocol.GenerateCertificate(certificate2);
dtlsReliableHandshake.SendMessage(11, body4);
}
if (state.clientCredentials != null)
{
state.keyExchange.ProcessClientCredentials(state.clientCredentials);
}
else
{
state.keyExchange.SkipClientCredentials();
}
byte[] body5 = this.GenerateClientKeyExchange(state);
dtlsReliableHandshake.SendMessage(16, body5);
TlsHandshakeHash tlsHandshakeHash = dtlsReliableHandshake.PrepareToFinish();
securityParameters.sessionHash = TlsProtocol.GetCurrentPrfHash(state.clientContext, tlsHandshakeHash, null);
TlsProtocol.EstablishMasterSecret(state.clientContext, state.keyExchange);
recordLayer.InitPendingEpoch(state.client.GetCipher());
if (state.clientCredentials != null && state.clientCredentials is TlsSignerCredentials)
{
TlsSignerCredentials tlsSignerCredentials = (TlsSignerCredentials)state.clientCredentials;
SignatureAndHashAlgorithm signatureAndHashAlgorithm = TlsUtilities.GetSignatureAndHashAlgorithm(state.clientContext, tlsSignerCredentials);
byte[] hash;
if (signatureAndHashAlgorithm == null)
{
hash = securityParameters.SessionHash;
}
else
{
hash = tlsHandshakeHash.GetFinalHash(signatureAndHashAlgorithm.Hash);
}
byte[] signature = tlsSignerCredentials.GenerateCertificateSignature(hash);
DigitallySigned certificateVerify = new DigitallySigned(signatureAndHashAlgorithm, signature);
byte[] body6 = this.GenerateCertificateVerify(state, certificateVerify);
dtlsReliableHandshake.SendMessage(15, body6);
}
byte[] body7 = TlsUtilities.CalculateVerifyData(state.clientContext, "client finished", TlsProtocol.GetCurrentPrfHash(state.clientContext, dtlsReliableHandshake.HandshakeHash, null));
dtlsReliableHandshake.SendMessage(20, body7);
if (state.expectSessionTicket)
{
message = dtlsReliableHandshake.ReceiveMessage();
if (message.Type != 4)
{
throw new TlsFatalAlert(10);
}
this.ProcessNewSessionTicket(state, message.Body);
}
byte[] expected_verify_data2 = TlsUtilities.CalculateVerifyData(state.clientContext, "server finished", TlsProtocol.GetCurrentPrfHash(state.clientContext, dtlsReliableHandshake.HandshakeHash, null));
this.ProcessFinished(dtlsReliableHandshake.ReceiveMessageBody(20), expected_verify_data2);
dtlsReliableHandshake.Finish();
if (state.tlsSession != null)
{
state.sessionParameters = new SessionParameters.Builder().SetCipherSuite(securityParameters.CipherSuite).SetCompressionAlgorithm(securityParameters.CompressionAlgorithm).SetMasterSecret(securityParameters.MasterSecret).SetPeerCertificate(certificate).SetPskIdentity(securityParameters.PskIdentity).SetSrpIdentity(securityParameters.SrpIdentity).SetServerExtensions(state.serverExtensions).Build();
state.tlsSession = TlsUtilities.ImportSession(state.tlsSession.SessionID, state.sessionParameters);
state.clientContext.SetResumableSession(state.tlsSession);
}
state.client.NotifyHandshakeComplete();
return(new DtlsTransport(recordLayer));
}