protected virtual void ReceiveClientKeyExchangeMessage(MemoryStream buf) { mKeyExchange.ProcessClientKeyExchange(buf); AssertEmpty(buf); if (TlsUtilities.IsSsl(Context)) { EstablishMasterSecret(Context, mKeyExchange); } this.mPrepareFinishHash = mRecordStream.PrepareToFinish(); this.mSecurityParameters.sessionHash = GetCurrentPrfHash(Context, mPrepareFinishHash, null); if (!TlsUtilities.IsSsl(Context)) { EstablishMasterSecret(Context, mKeyExchange); } mRecordStream.SetPendingConnectionState(Peer.GetCompression(), Peer.GetCipher()); if (!mExpectSessionTicket) { SendChangeCipherSpecMessage(); } }
internal virtual TlsHandshakeHash PrepareToFinish() { TlsHandshakeHash mHandshakeHash = this.mHandshakeHash; this.mHandshakeHash = this.mHandshakeHash.StopTracking(); return(mHandshakeHash); }
internal DtlsReliableHandshake(TlsContext context, DtlsRecordLayer transport, int timeoutMillis) { this.mRecordLayer = transport; this.mHandshakeTimeout = Timeout.ForWaitMillis(timeoutMillis); this.mHandshakeHash = new DeferredHash(); this.mHandshakeHash.Init(context); }
internal TlsHandshakeHash PrepareToFinish() { TlsHandshakeHash result = mHandshakeHash; this.mHandshakeHash = mHandshakeHash.StopTracking(); return(result); }
internal virtual void Init(TlsContext context) { this.mReadCipher = new TlsNullCipher(context); this.mWriteCipher = this.mReadCipher; this.mHandshakeHash = new DeferredHash(); this.mHandshakeHash.Init(context); this.SetPlaintextLimit(0x4000); }
internal virtual void Init(TlsContext context) { mReadCipher = new TlsNullCipher(context); mWriteCipher = mReadCipher; mHandshakeHash = new DeferredHash(); mHandshakeHash.Init(context); SetPlaintextLimit(16384); }
protected override void CleanupHandshake() { base.CleanupHandshake(); this.mKeyExchange = null; this.mServerCredentials = null; this.mCertificateRequest = null; this.mPrepareFinishHash = null; }
internal virtual void Init(TlsContext context) { this.mReadCipher = new TlsNullCipher(context); this.mWriteCipher = this.mReadCipher; this.mHandshakeHash = new DeferredHash(); this.mHandshakeHash.Init(context); SetPlaintextLimit(DEFAULT_PLAINTEXT_LIMIT); }
protected internal static byte[] GetCurrentPrfHash(TlsContext context, TlsHandshakeHash handshakeHash, byte[] sslSender) { IDigest digest = handshakeHash.ForkPrfHash(); if (sslSender != null && TlsUtilities.IsSsl(context)) { digest.BlockUpdate(sslSender, 0, sslSender.Length); } return(DigestUtilities.DoFinal(digest)); }
protected virtual void ReceiveClientKeyExchangeMessage(MemoryStream buf) { this.mKeyExchange.ProcessClientKeyExchange(buf); TlsProtocol.AssertEmpty(buf); this.mPrepareFinishHash = this.mRecordStream.PrepareToFinish(); this.mSecurityParameters.sessionHash = TlsProtocol.GetCurrentPrfHash(this.Context, this.mPrepareFinishHash, null); TlsProtocol.EstablishMasterSecret(this.Context, this.mKeyExchange); this.mRecordStream.SetPendingConnectionState(this.Peer.GetCompression(), this.Peer.GetCipher()); if (!this.mExpectSessionTicket) { this.SendChangeCipherSpecMessage(); } }
public AsyncDtlsRecordLayer(TlsHandshakeHash handshakeHash, HandshakeHandler handshakeHandler, IChannel channel, TlsContext context, TlsPeer peer) { this.handshakeHash = handshakeHash; this.channel = channel; this.handshakeHandler = handshakeHandler; this.peer = peer; this.inHandshake = true; this.currentEpoch = new AsyncDtlsEpoch(0, new TlsNullCipher(context)); this.pendingEpoch = null; this.readEpoch = currentEpoch; this.writeEpoch = currentEpoch; SetPlaintextLimit(MAX_FRAGMENT_LENGTH); }
protected virtual void ReceiveClientKeyExchangeMessage(MemoryStream buf) { mKeyExchange.ProcessClientKeyExchange(buf); AssertEmpty(buf); EstablishMasterSecret(Context, mKeyExchange); mRecordStream.SetPendingConnectionState(Peer.GetCompression(), Peer.GetCipher()); this.mPrepareFinishHash = mRecordStream.PrepareToFinish(); if (!mExpectSessionTicket) { SendChangeCipherSpecMessage(); } }
internal virtual DtlsTransport ServerHandshake(ServerHandshakeState state, DtlsRecordLayer recordLayer) { SecurityParameters securityParameters = state.serverContext.SecurityParameters; DtlsReliableHandshake handshake = new DtlsReliableHandshake(state.serverContext, recordLayer); DtlsReliableHandshake.Message clientMessage = handshake.ReceiveMessage(); // NOTE: DTLSRecordLayer requires any DTLS version, we don't otherwise constrain this //ProtocolVersion recordLayerVersion = recordLayer.ReadVersion; if (clientMessage.Type == HandshakeType.client_hello) { ProcessClientHello(state, clientMessage.Body); } else { throw new TlsFatalAlert(AlertDescription.unexpected_message); } { byte[] serverHelloBody = GenerateServerHello(state); ApplyMaxFragmentLengthExtension(recordLayer, securityParameters.maxFragmentLength); ProtocolVersion recordLayerVersion = state.serverContext.ServerVersion; recordLayer.ReadVersion = recordLayerVersion; recordLayer.SetWriteVersion(recordLayerVersion); handshake.SendMessage(HandshakeType.server_hello, serverHelloBody); } handshake.NotifyHelloComplete(); IList serverSupplementalData = state.server.GetServerSupplementalData(); if (serverSupplementalData != null) { byte[] supplementalDataBody = GenerateSupplementalData(serverSupplementalData); handshake.SendMessage(HandshakeType.supplemental_data, supplementalDataBody); } state.keyExchange = state.server.GetKeyExchange(); state.keyExchange.Init(state.serverContext); state.serverCredentials = state.server.GetCredentials(); Certificate serverCertificate = null; if (state.serverCredentials == null) { state.keyExchange.SkipServerCredentials(); } else { state.keyExchange.ProcessServerCredentials(state.serverCredentials); serverCertificate = state.serverCredentials.Certificate; byte[] certificateBody = GenerateCertificate(serverCertificate); handshake.SendMessage(HandshakeType.certificate, certificateBody); } // TODO[RFC 3546] Check whether empty certificates is possible, allowed, or excludes CertificateStatus if (serverCertificate == null || serverCertificate.IsEmpty) { state.allowCertificateStatus = false; } if (state.allowCertificateStatus) { CertificateStatus certificateStatus = state.server.GetCertificateStatus(); if (certificateStatus != null) { byte[] certificateStatusBody = GenerateCertificateStatus(state, certificateStatus); handshake.SendMessage(HandshakeType.certificate_status, certificateStatusBody); } } byte[] serverKeyExchange = state.keyExchange.GenerateServerKeyExchange(); if (serverKeyExchange != null) { handshake.SendMessage(HandshakeType.server_key_exchange, serverKeyExchange); } if (state.serverCredentials != null) { state.certificateRequest = state.server.GetCertificateRequest(); if (state.certificateRequest != null) { if (TlsUtilities.IsTlsV12(state.serverContext) != (state.certificateRequest.SupportedSignatureAlgorithms != null)) { throw new TlsFatalAlert(AlertDescription.internal_error); } state.keyExchange.ValidateCertificateRequest(state.certificateRequest); byte[] certificateRequestBody = GenerateCertificateRequest(state, state.certificateRequest); handshake.SendMessage(HandshakeType.certificate_request, certificateRequestBody); TlsUtilities.TrackHashAlgorithms(handshake.HandshakeHash, state.certificateRequest.SupportedSignatureAlgorithms); } } handshake.SendMessage(HandshakeType.server_hello_done, TlsUtilities.EmptyBytes); handshake.HandshakeHash.SealHashAlgorithms(); clientMessage = handshake.ReceiveMessage(); if (clientMessage.Type == HandshakeType.supplemental_data) { ProcessClientSupplementalData(state, clientMessage.Body); clientMessage = handshake.ReceiveMessage(); } else { state.server.ProcessClientSupplementalData(null); } if (state.certificateRequest == null) { state.keyExchange.SkipClientCredentials(); } else { if (clientMessage.Type == HandshakeType.certificate) { ProcessClientCertificate(state, clientMessage.Body); clientMessage = handshake.ReceiveMessage(); } else { if (TlsUtilities.IsTlsV12(state.serverContext)) { /* * RFC 5246 If no suitable certificate is available, the client MUST send a * certificate message containing no certificates. * * NOTE: In previous RFCs, this was SHOULD instead of MUST. */ throw new TlsFatalAlert(AlertDescription.unexpected_message); } NotifyClientCertificate(state, Certificate.EmptyChain); } } if (clientMessage.Type == HandshakeType.client_key_exchange) { ProcessClientKeyExchange(state, clientMessage.Body); } else { throw new TlsFatalAlert(AlertDescription.unexpected_message); } TlsHandshakeHash prepareFinishHash = handshake.PrepareToFinish(); securityParameters.sessionHash = TlsProtocol.GetCurrentPrfHash(state.serverContext, prepareFinishHash, null); TlsProtocol.EstablishMasterSecret(state.serverContext, state.keyExchange); recordLayer.InitPendingEpoch(state.server.GetCipher()); /* * RFC 5246 7.4.8 This message is only sent following a client certificate that has signing * capability (i.e., all certificates except those containing fixed Diffie-Hellman * parameters). */ if (ExpectCertificateVerifyMessage(state)) { byte[] certificateVerifyBody = handshake.ReceiveMessageBody(HandshakeType.certificate_verify); ProcessCertificateVerify(state, certificateVerifyBody, prepareFinishHash); } // NOTE: Calculated exclusive of the actual Finished message from the client byte[] expectedClientVerifyData = TlsUtilities.CalculateVerifyData(state.serverContext, ExporterLabel.client_finished, TlsProtocol.GetCurrentPrfHash(state.serverContext, handshake.HandshakeHash, null)); ProcessFinished(handshake.ReceiveMessageBody(HandshakeType.finished), expectedClientVerifyData); if (state.expectSessionTicket) { NewSessionTicket newSessionTicket = state.server.GetNewSessionTicket(); byte[] newSessionTicketBody = GenerateNewSessionTicket(state, newSessionTicket); handshake.SendMessage(HandshakeType.session_ticket, newSessionTicketBody); } // NOTE: Calculated exclusive of the Finished message itself byte[] serverVerifyData = TlsUtilities.CalculateVerifyData(state.serverContext, ExporterLabel.server_finished, TlsProtocol.GetCurrentPrfHash(state.serverContext, handshake.HandshakeHash, null)); handshake.SendMessage(HandshakeType.finished, serverVerifyData); handshake.Finish(); state.server.NotifyHandshakeComplete(); return(new DtlsTransport(recordLayer)); }
protected virtual void ProcessCertificateVerify(ServerHandshakeState state, byte[] body, TlsHandshakeHash prepareFinishHash) { if (state.certificateRequest == null) { throw new InvalidOperationException(); } MemoryStream buf = new MemoryStream(body, false); TlsServerContextImpl context = state.serverContext; DigitallySigned clientCertificateVerify = DigitallySigned.Parse(context, buf); TlsProtocol.AssertEmpty(buf); // Verify the CertificateVerify message contains a correct signature. try { SignatureAndHashAlgorithm signatureAlgorithm = clientCertificateVerify.Algorithm; byte[] hash; if (TlsUtilities.IsTlsV12(context)) { TlsUtilities.VerifySupportedSignatureAlgorithm(state.certificateRequest.SupportedSignatureAlgorithms, signatureAlgorithm); hash = prepareFinishHash.GetFinalHash(signatureAlgorithm.Hash); } else { hash = context.SecurityParameters.SessionHash; } X509CertificateStructure x509Cert = state.clientCertificate.GetCertificateAt(0); SubjectPublicKeyInfo keyInfo = x509Cert.SubjectPublicKeyInfo; AsymmetricKeyParameter publicKey = PublicKeyFactory.CreateKey(keyInfo); TlsSigner tlsSigner = TlsUtilities.CreateTlsSigner((byte)state.clientCertificateType); tlsSigner.Init(context); if (!tlsSigner.VerifyRawSignature(signatureAlgorithm, clientCertificateVerify.Signature, publicKey, hash)) { throw new TlsFatalAlert(AlertDescription.decrypt_error); } } catch (TlsFatalAlert e) { throw e; } catch (Exception e) { throw new TlsFatalAlert(AlertDescription.decrypt_error, e); } }
internal TlsHandshakeHash PrepareToFinish() { TlsHandshakeHash result = mHandshakeHash; this.mHandshakeHash = mHandshakeHash.StopTracking(); return result; }
internal void NotifyHelloComplete() { this.mHandshakeHash = mHandshakeHash.NotifyPrfDetermined(); }
protected virtual void ReceiveClientKeyExchangeMessage(MemoryStream buf) { mKeyExchange.ProcessClientKeyExchange(buf); AssertEmpty(buf); this.mPrepareFinishHash = mRecordStream.PrepareToFinish(); this.mSecurityParameters.sessionHash = GetCurrentPrfHash(Context, mPrepareFinishHash, null); EstablishMasterSecret(Context, mKeyExchange); mRecordStream.SetPendingConnectionState(Peer.GetCompression(), Peer.GetCipher()); if (!mExpectSessionTicket) { SendChangeCipherSpecMessage(); } }
internal virtual DtlsTransport ServerHandshake(DtlsServerProtocol.ServerHandshakeState state, DtlsRecordLayer recordLayer) { SecurityParameters securityParameters = state.serverContext.SecurityParameters; DtlsReliableHandshake dtlsReliableHandshake = new DtlsReliableHandshake(state.serverContext, recordLayer); DtlsReliableHandshake.Message message = dtlsReliableHandshake.ReceiveMessage(); ProtocolVersion discoveredPeerVersion = recordLayer.DiscoveredPeerVersion; state.serverContext.SetClientVersion(discoveredPeerVersion); if (message.Type != 1) { throw new TlsFatalAlert(10); } this.ProcessClientHello(state, message.Body); byte[] body = this.GenerateServerHello(state); DtlsProtocol.ApplyMaxFragmentLengthExtension(recordLayer, securityParameters.maxFragmentLength); dtlsReliableHandshake.SendMessage(2, body); dtlsReliableHandshake.NotifyHelloComplete(); IList serverSupplementalData = state.server.GetServerSupplementalData(); if (serverSupplementalData != null) { byte[] body2 = DtlsProtocol.GenerateSupplementalData(serverSupplementalData); dtlsReliableHandshake.SendMessage(23, body2); } state.keyExchange = state.server.GetKeyExchange(); state.keyExchange.Init(state.serverContext); state.serverCredentials = state.server.GetCredentials(); Certificate certificate = null; if (state.serverCredentials == null) { state.keyExchange.SkipServerCredentials(); } else { state.keyExchange.ProcessServerCredentials(state.serverCredentials); certificate = state.serverCredentials.Certificate; byte[] body3 = DtlsProtocol.GenerateCertificate(certificate); dtlsReliableHandshake.SendMessage(11, body3); } if (certificate == null || certificate.IsEmpty) { state.allowCertificateStatus = false; } if (state.allowCertificateStatus) { CertificateStatus certificateStatus = state.server.GetCertificateStatus(); if (certificateStatus != null) { byte[] body4 = this.GenerateCertificateStatus(state, certificateStatus); dtlsReliableHandshake.SendMessage(22, body4); } } byte[] array = state.keyExchange.GenerateServerKeyExchange(); if (array != null) { dtlsReliableHandshake.SendMessage(12, array); } if (state.serverCredentials != null) { state.certificateRequest = state.server.GetCertificateRequest(); if (state.certificateRequest != null) { state.keyExchange.ValidateCertificateRequest(state.certificateRequest); byte[] body5 = this.GenerateCertificateRequest(state, state.certificateRequest); dtlsReliableHandshake.SendMessage(13, body5); TlsUtilities.TrackHashAlgorithms(dtlsReliableHandshake.HandshakeHash, state.certificateRequest.SupportedSignatureAlgorithms); } } dtlsReliableHandshake.SendMessage(14, TlsUtilities.EmptyBytes); dtlsReliableHandshake.HandshakeHash.SealHashAlgorithms(); message = dtlsReliableHandshake.ReceiveMessage(); if (message.Type == 23) { this.ProcessClientSupplementalData(state, message.Body); message = dtlsReliableHandshake.ReceiveMessage(); } else { state.server.ProcessClientSupplementalData(null); } if (state.certificateRequest == null) { state.keyExchange.SkipClientCredentials(); } else if (message.Type == 11) { this.ProcessClientCertificate(state, message.Body); message = dtlsReliableHandshake.ReceiveMessage(); } else { if (TlsUtilities.IsTlsV12(state.serverContext)) { throw new TlsFatalAlert(10); } this.NotifyClientCertificate(state, Certificate.EmptyChain); } if (message.Type == 16) { this.ProcessClientKeyExchange(state, message.Body); TlsHandshakeHash tlsHandshakeHash = dtlsReliableHandshake.PrepareToFinish(); securityParameters.sessionHash = TlsProtocol.GetCurrentPrfHash(state.serverContext, tlsHandshakeHash, null); TlsProtocol.EstablishMasterSecret(state.serverContext, state.keyExchange); recordLayer.InitPendingEpoch(state.server.GetCipher()); if (this.ExpectCertificateVerifyMessage(state)) { byte[] body6 = dtlsReliableHandshake.ReceiveMessageBody(15); this.ProcessCertificateVerify(state, body6, tlsHandshakeHash); } byte[] expected_verify_data = TlsUtilities.CalculateVerifyData(state.serverContext, "client finished", TlsProtocol.GetCurrentPrfHash(state.serverContext, dtlsReliableHandshake.HandshakeHash, null)); this.ProcessFinished(dtlsReliableHandshake.ReceiveMessageBody(20), expected_verify_data); if (state.expectSessionTicket) { NewSessionTicket newSessionTicket = state.server.GetNewSessionTicket(); byte[] body7 = this.GenerateNewSessionTicket(state, newSessionTicket); dtlsReliableHandshake.SendMessage(4, body7); } byte[] body8 = TlsUtilities.CalculateVerifyData(state.serverContext, "server finished", TlsProtocol.GetCurrentPrfHash(state.serverContext, dtlsReliableHandshake.HandshakeHash, null)); dtlsReliableHandshake.SendMessage(20, body8); dtlsReliableHandshake.Finish(); state.server.NotifyHandshakeComplete(); return(new DtlsTransport(recordLayer)); } throw new TlsFatalAlert(10); }
internal static void TrackHashAlgorithms(TlsHandshakeHash handshakeHash, IList supportedSignatureAlgorithms) { if (supportedSignatureAlgorithms != null) { foreach (SignatureAndHashAlgorithm signatureAndHashAlgorithm in supportedSignatureAlgorithms) { byte hashAlgorithm = signatureAndHashAlgorithm.Hash; // TODO Support values in the "Reserved for Private Use" range if (!HashAlgorithm.IsPrivate(hashAlgorithm)) { handshakeHash.TrackHashAlgorithm(hashAlgorithm); } } } }
/** * 'sender' only relevant to SSLv3 */ protected internal static byte[] GetCurrentPrfHash(TlsContext context, TlsHandshakeHash handshakeHash, byte[] sslSender) { IDigest d = handshakeHash.ForkPrfHash(); if (sslSender != null && TlsUtilities.IsSsl(context)) { d.BlockUpdate(sslSender, 0, sslSender.Length); } return DigestUtilities.DoFinal(d); }
protected virtual void ProcessCertificateVerify(ServerHandshakeState state, byte[] body, TlsHandshakeHash prepareFinishHash) { if (state.certificateRequest == null) throw new InvalidOperationException(); MemoryStream buf = new MemoryStream(body, false); TlsServerContextImpl context = state.serverContext; DigitallySigned clientCertificateVerify = DigitallySigned.Parse(context, buf); TlsProtocol.AssertEmpty(buf); // Verify the CertificateVerify message contains a correct signature. try { SignatureAndHashAlgorithm signatureAlgorithm = clientCertificateVerify.Algorithm; byte[] hash; if (TlsUtilities.IsTlsV12(context)) { TlsUtilities.VerifySupportedSignatureAlgorithm(state.certificateRequest.SupportedSignatureAlgorithms, signatureAlgorithm); hash = prepareFinishHash.GetFinalHash(signatureAlgorithm.Hash); } else { hash = context.SecurityParameters.SessionHash; } X509CertificateStructure x509Cert = state.clientCertificate.GetCertificateAt(0); SubjectPublicKeyInfo keyInfo = x509Cert.SubjectPublicKeyInfo; AsymmetricKeyParameter publicKey = PublicKeyFactory.CreateKey(keyInfo); TlsSigner tlsSigner = TlsUtilities.CreateTlsSigner((byte)state.clientCertificateType); tlsSigner.Init(context); if (!tlsSigner.VerifyRawSignature(signatureAlgorithm, clientCertificateVerify.Signature, publicKey, hash)) throw new TlsFatalAlert(AlertDescription.decrypt_error); } catch (TlsFatalAlert e) { throw e; } catch (Exception e) { throw new TlsFatalAlert(AlertDescription.decrypt_error, e); } }
protected virtual void ProcessCertificateVerify(ServerHandshakeState state, byte[] body, TlsHandshakeHash prepareFinishHash) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Expected O, but got Unknown if (state.certificateRequest == null) { throw new InvalidOperationException(); } MemoryStream val = new MemoryStream(body, false); TlsServerContextImpl serverContext = state.serverContext; DigitallySigned digitallySigned = DigitallySigned.Parse(serverContext, (Stream)(object)val); TlsProtocol.AssertEmpty(val); try { SignatureAndHashAlgorithm algorithm = digitallySigned.Algorithm; byte[] hash; if (TlsUtilities.IsTlsV12(serverContext)) { TlsUtilities.VerifySupportedSignatureAlgorithm(state.certificateRequest.SupportedSignatureAlgorithms, algorithm); hash = prepareFinishHash.GetFinalHash(algorithm.Hash); } else { hash = serverContext.SecurityParameters.SessionHash; } X509CertificateStructure certificateAt = state.clientCertificate.GetCertificateAt(0); SubjectPublicKeyInfo subjectPublicKeyInfo = certificateAt.SubjectPublicKeyInfo; AsymmetricKeyParameter publicKey = PublicKeyFactory.CreateKey(subjectPublicKeyInfo); TlsSigner tlsSigner = TlsUtilities.CreateTlsSigner((byte)state.clientCertificateType); tlsSigner.Init(serverContext); if (!tlsSigner.VerifyRawSignature(algorithm, digitallySigned.Signature, publicKey, hash)) { throw new TlsFatalAlert(51); } } catch (TlsFatalAlert tlsFatalAlert) { throw tlsFatalAlert; } catch (global::System.Exception alertCause) { throw new TlsFatalAlert(51, alertCause); } }
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)); }
public void PostProcessServerHelloDone() { IList <SupplementalDataEntry> clientSupplementalData = (IList <SupplementalDataEntry>)clientState.Client.GetClientSupplementalData(); if (clientSupplementalData != null) { int totalLength = 3 + DtlsHelper.CalculateSupplementalDataLength(clientSupplementalData); IByteBuffer supplementalDataOutput = Unpooled.Buffer(DtlsHelper.HANDSHAKE_MESSAGE_HEADER_LENGTH + totalLength); short sdataSequence = sequence++; DtlsHelper.WriteHandshakeHeader(sdataSequence, MessageType.SUPPLEMENTAL_DATA, supplementalDataOutput, totalLength); DtlsHelper.WriteSupplementalData(supplementalDataOutput, clientSupplementalData); recordLayer.Send(sdataSequence, MessageType.SUPPLEMENTAL_DATA, supplementalDataOutput); } if (clientState.CertificateRequest != null) { clientState.ClientCredentials = clientState.Authentication.GetClientCredentials(clientState.CertificateRequest); Certificate clientCertificate = null; if (clientState.ClientCredentials != null) { clientCertificate = clientState.ClientCredentials.Certificate; } if (clientCertificate == null) { clientCertificate = Certificate.EmptyChain; } short certificateSequence = sequence++; IByteBuffer certificateOutput = DtlsHelper.WriteCertificate(certificateSequence, clientCertificate); recordLayer.Send(certificateSequence, MessageType.CERTIFICATE, certificateOutput); } if (clientState.ClientCredentials != null) { clientState.KeyExchange.ProcessClientCredentials(clientState.ClientCredentials); } else { clientState.KeyExchange.SkipClientCredentials(); } MemoryStream buf = new MemoryStream(); clientState.KeyExchange.GenerateClientKeyExchange(buf); byte[] clientKeyExchange = buf.GetBuffer(); Array.Resize(ref clientKeyExchange, clientKeyExchange[0] + 1); IByteBuffer keyExchangeOutput = Unpooled.Buffer(DtlsHelper.HANDSHAKE_MESSAGE_HEADER_LENGTH + clientKeyExchange.Length); short currSequence = sequence++; DtlsHelper.WriteHandshakeHeader(currSequence, MessageType.CLIENT_KEY_EXCHANGE, keyExchangeOutput, clientKeyExchange.Length); keyExchangeOutput.WriteBytes(clientKeyExchange); recordLayer.Send(currSequence, MessageType.CLIENT_KEY_EXCHANGE, keyExchangeOutput); TlsHandshakeHash prepareFinishHash = clientState.HandshakeHash; //clientState.setHandshakeHash(clientState.getHandshakeHash().stopTracking()); ((AsyncDtlsSecurityParameters)clientState.ClientContext.SecurityParameters).SetSessionHash(DtlsHelper.GetCurrentPRFHash(clientState.ClientContext, prepareFinishHash, null)); DtlsHelper.EstablishMasterSecret((AsyncDtlsSecurityParameters)clientState.ClientContext.SecurityParameters, clientState.ClientContext, clientState.KeyExchange); recordLayer.InitPendingEpoch(clientState.Client.GetCipher()); if (clientState.ClientCredentials != null && clientState.ClientCredentials is TlsSignerCredentials) { TlsSignerCredentials signerCredentials = (TlsSignerCredentials)clientState.ClientCredentials; SignatureAndHashAlgorithm signatureAndHashAlgorithm = DtlsHelper.GetSignatureAndHashAlgorithm(clientState.ClientContext, signerCredentials); byte[] hash; if (signatureAndHashAlgorithm == null) { hash = ((AsyncDtlsSecurityParameters)clientState.ClientContext.SecurityParameters).SessionHash; } else { hash = prepareFinishHash.GetFinalHash(signatureAndHashAlgorithm.Hash); } byte[] signature = signerCredentials.GenerateCertificateSignature(hash); int addon = 0; if (signatureAndHashAlgorithm != null) { addon = 2; } IByteBuffer certificateVerifyBody = Unpooled.Buffer(DtlsHelper.HANDSHAKE_MESSAGE_HEADER_LENGTH + addon + 2 + signature.Length); currSequence = sequence++; DtlsHelper.WriteHandshakeHeader(currSequence, MessageType.CERTIFICATE_VERIFY, certificateVerifyBody, addon + 2 + signature.Length); if (signatureAndHashAlgorithm != null) { certificateVerifyBody.WriteByte(signatureAndHashAlgorithm.Hash); certificateVerifyBody.WriteByte(signatureAndHashAlgorithm.Signature); } certificateVerifyBody.WriteShort(signature.Length); certificateVerifyBody.WriteBytes(signature); recordLayer.Send(currSequence, MessageType.CERTIFICATE_VERIFY, certificateVerifyBody); } byte[] clientVerifyData = DtlsHelper.CalculateVerifyData(clientState.ClientContext, ExporterLabel.client_finished, DtlsHelper.GetCurrentPRFHash(clientState.ClientContext, clientState.HandshakeHash, null)); IByteBuffer serverVerifyBuffer = Unpooled.Buffer(DtlsHelper.HANDSHAKE_MESSAGE_HEADER_LENGTH + clientVerifyData.Length); currSequence = sequence++; DtlsHelper.WriteHandshakeHeader(currSequence, MessageType.FINISHED, serverVerifyBuffer, clientVerifyData.Length); serverVerifyBuffer.WriteBytes(clientVerifyData); recordLayer.Send(currSequence, MessageType.FINISHED, serverVerifyBuffer); clientVerifyData = DtlsHelper.CalculateVerifyData(clientState.ClientContext, ExporterLabel.client_finished, DtlsHelper.GetCurrentPRFHash(clientState.ClientContext, clientState.HandshakeHash, null)); }
internal DtlsReliableHandshake(TlsContext context, DtlsRecordLayer transport) { this.mRecordLayer = transport; this.mHandshakeHash = new DeferredHash(); this.mHandshakeHash.Init(context); }
protected override void HandleHandshakeMessage(byte type, byte[] data) { MemoryStream buf = new MemoryStream(data, false); if (this.mResumedSession) { if (type != HandshakeType.finished || this.mConnectionState != CS_SERVER_HELLO) { throw new TlsFatalAlert(AlertDescription.unexpected_message); } ProcessFinishedMessage(buf); this.mConnectionState = CS_SERVER_FINISHED; SendFinishedMessage(); this.mConnectionState = CS_CLIENT_FINISHED; this.mConnectionState = CS_END; return; } switch (type) { case HandshakeType.certificate: { switch (this.mConnectionState) { case CS_SERVER_HELLO: case CS_SERVER_SUPPLEMENTAL_DATA: { if (this.mConnectionState == CS_SERVER_HELLO) { HandleSupplementalData(null); } // Parse the Certificate message and Send to cipher suite this.mPeerCertificate = Certificate.Parse(buf); AssertEmpty(buf); // TODO[RFC 3546] Check whether empty certificates is possible, allowed, or excludes CertificateStatus if (this.mPeerCertificate == null || this.mPeerCertificate.IsEmpty) { this.mAllowCertificateStatus = false; } this.mKeyExchange.ProcessServerCertificate(this.mPeerCertificate); this.mAuthentication = mTlsClient.GetAuthentication(); this.mAuthentication.NotifyServerCertificate(this.mPeerCertificate); break; } default: throw new TlsFatalAlert(AlertDescription.unexpected_message); } this.mConnectionState = CS_SERVER_CERTIFICATE; break; } case HandshakeType.certificate_status: { switch (this.mConnectionState) { case CS_SERVER_CERTIFICATE: { if (!this.mAllowCertificateStatus) { /* * RFC 3546 3.6. If a server returns a "CertificateStatus" message, then the * server MUST have included an extension of type "status_request" with empty * "extension_data" in the extended server hello.. */ throw new TlsFatalAlert(AlertDescription.unexpected_message); } this.mCertificateStatus = CertificateStatus.Parse(buf); AssertEmpty(buf); // TODO[RFC 3546] Figure out how to provide this to the client/authentication. this.mConnectionState = CS_CERTIFICATE_STATUS; break; } default: throw new TlsFatalAlert(AlertDescription.unexpected_message); } break; } case HandshakeType.finished: { switch (this.mConnectionState) { case CS_CLIENT_FINISHED: case CS_SERVER_SESSION_TICKET: { if (this.mConnectionState == CS_CLIENT_FINISHED && this.mExpectSessionTicket) { /* * RFC 5077 3.3. This message MUST be sent if the server included a * SessionTicket extension in the ServerHello. */ throw new TlsFatalAlert(AlertDescription.unexpected_message); } ProcessFinishedMessage(buf); this.mConnectionState = CS_SERVER_FINISHED; this.mConnectionState = CS_END; break; } default: throw new TlsFatalAlert(AlertDescription.unexpected_message); } break; } case HandshakeType.server_hello: { switch (this.mConnectionState) { case CS_CLIENT_HELLO: { ReceiveServerHelloMessage(buf); this.mConnectionState = CS_SERVER_HELLO; this.mRecordStream.NotifyHelloComplete(); ApplyMaxFragmentLengthExtension(); if (this.mResumedSession) { this.mSecurityParameters.masterSecret = Arrays.Clone(this.mSessionParameters.MasterSecret); this.mRecordStream.SetPendingConnectionState(Peer.GetCompression(), Peer.GetCipher()); SendChangeCipherSpecMessage(); } else { InvalidateSession(); if (this.mSelectedSessionID.Length > 0) { this.mTlsSession = new TlsSessionImpl(this.mSelectedSessionID, null); } } break; } default: throw new TlsFatalAlert(AlertDescription.unexpected_message); } break; } case HandshakeType.supplemental_data: { switch (this.mConnectionState) { case CS_SERVER_HELLO: { HandleSupplementalData(ReadSupplementalDataMessage(buf)); break; } default: throw new TlsFatalAlert(AlertDescription.unexpected_message); } break; } case HandshakeType.server_hello_done: { switch (this.mConnectionState) { case CS_SERVER_HELLO: case CS_SERVER_SUPPLEMENTAL_DATA: case CS_SERVER_CERTIFICATE: case CS_CERTIFICATE_STATUS: case CS_SERVER_KEY_EXCHANGE: case CS_CERTIFICATE_REQUEST: { if (mConnectionState < CS_SERVER_SUPPLEMENTAL_DATA) { HandleSupplementalData(null); } if (mConnectionState < CS_SERVER_CERTIFICATE) { // There was no server certificate message; check it's OK this.mKeyExchange.SkipServerCredentials(); this.mAuthentication = null; } if (mConnectionState < CS_SERVER_KEY_EXCHANGE) { // There was no server key exchange message; check it's OK this.mKeyExchange.SkipServerKeyExchange(); } AssertEmpty(buf); this.mConnectionState = CS_SERVER_HELLO_DONE; this.mRecordStream.HandshakeHash.SealHashAlgorithms(); IList clientSupplementalData = mTlsClient.GetClientSupplementalData(); if (clientSupplementalData != null) { SendSupplementalDataMessage(clientSupplementalData); } this.mConnectionState = CS_CLIENT_SUPPLEMENTAL_DATA; TlsCredentials clientCreds = null; if (mCertificateRequest == null) { this.mKeyExchange.SkipClientCredentials(); } else { clientCreds = this.mAuthentication.GetClientCredentials(this.Context, mCertificateRequest); if (clientCreds == null) { this.mKeyExchange.SkipClientCredentials(); /* * RFC 5246 If no suitable certificate is available, the client MUST Send a * certificate message containing no certificates. * * NOTE: In previous RFCs, this was SHOULD instead of MUST. */ SendCertificateMessage(Certificate.EmptyChain); } else { this.mKeyExchange.ProcessClientCredentials(clientCreds); SendCertificateMessage(clientCreds.Certificate); } } this.mConnectionState = CS_CLIENT_CERTIFICATE; /* * Send the client key exchange message, depending on the key exchange we are using * in our CipherSuite. */ SendClientKeyExchangeMessage(); this.mConnectionState = CS_CLIENT_KEY_EXCHANGE; TlsHandshakeHash prepareFinishHash = mRecordStream.PrepareToFinish(); this.mSecurityParameters.sessionHash = GetCurrentPrfHash(Context, prepareFinishHash, null); EstablishMasterSecret(Context, mKeyExchange); mRecordStream.SetPendingConnectionState(Peer.GetCompression(), Peer.GetCipher()); if (clientCreds != null && clientCreds is TlsSignerCredentials) { TlsSignerCredentials signerCredentials = (TlsSignerCredentials)clientCreds; /* * RFC 5246 4.7. digitally-signed element needs SignatureAndHashAlgorithm from TLS 1.2 */ SignatureAndHashAlgorithm signatureAndHashAlgorithm = TlsUtilities.GetSignatureAndHashAlgorithm( Context, signerCredentials); byte[] hash; if (signatureAndHashAlgorithm == null) { hash = mSecurityParameters.SessionHash; } else { hash = prepareFinishHash.GetFinalHash(signatureAndHashAlgorithm.Hash); } byte[] signature = signerCredentials.GenerateCertificateSignature(hash); DigitallySigned certificateVerify = new DigitallySigned(signatureAndHashAlgorithm, signature); SendCertificateVerifyMessage(certificateVerify); this.mConnectionState = CS_CERTIFICATE_VERIFY; } SendChangeCipherSpecMessage(); SendFinishedMessage(); break; } default: throw new TlsFatalAlert(AlertDescription.handshake_failure); } this.mConnectionState = CS_CLIENT_FINISHED; break; } case HandshakeType.server_key_exchange: { switch (this.mConnectionState) { case CS_SERVER_HELLO: case CS_SERVER_SUPPLEMENTAL_DATA: case CS_SERVER_CERTIFICATE: case CS_CERTIFICATE_STATUS: { if (mConnectionState < CS_SERVER_SUPPLEMENTAL_DATA) { HandleSupplementalData(null); } if (mConnectionState < CS_SERVER_CERTIFICATE) { // There was no server certificate message; check it's OK this.mKeyExchange.SkipServerCredentials(); this.mAuthentication = null; } this.mKeyExchange.ProcessServerKeyExchange(buf); AssertEmpty(buf); break; } default: throw new TlsFatalAlert(AlertDescription.unexpected_message); } this.mConnectionState = CS_SERVER_KEY_EXCHANGE; break; } case HandshakeType.certificate_request: { switch (this.mConnectionState) { case CS_SERVER_CERTIFICATE: case CS_CERTIFICATE_STATUS: case CS_SERVER_KEY_EXCHANGE: { if (this.mConnectionState != CS_SERVER_KEY_EXCHANGE) { // There was no server key exchange message; check it's OK this.mKeyExchange.SkipServerKeyExchange(); } if (this.mAuthentication == null) { /* * RFC 2246 7.4.4. It is a fatal handshake_failure alert for an anonymous server * to request client identification. */ throw new TlsFatalAlert(AlertDescription.handshake_failure); } this.mCertificateRequest = CertificateRequest.Parse(Context, buf); AssertEmpty(buf); this.mKeyExchange.ValidateCertificateRequest(this.mCertificateRequest); /* * TODO Give the client a chance to immediately select the CertificateVerify hash * algorithm here to avoid tracking the other hash algorithms unnecessarily? */ TlsUtilities.TrackHashAlgorithms(this.mRecordStream.HandshakeHash, this.mCertificateRequest.SupportedSignatureAlgorithms); break; } default: throw new TlsFatalAlert(AlertDescription.unexpected_message); } this.mConnectionState = CS_CERTIFICATE_REQUEST; break; } case HandshakeType.session_ticket: { switch (this.mConnectionState) { case CS_CLIENT_FINISHED: { if (!this.mExpectSessionTicket) { /* * RFC 5077 3.3. This message MUST NOT be sent if the server did not include a * SessionTicket extension in the ServerHello. */ throw new TlsFatalAlert(AlertDescription.unexpected_message); } /* * RFC 5077 3.4. If the client receives a session ticket from the server, then it * discards any Session ID that was sent in the ServerHello. */ InvalidateSession(); ReceiveNewSessionTicketMessage(buf); break; } default: throw new TlsFatalAlert(AlertDescription.unexpected_message); } this.mConnectionState = CS_SERVER_SESSION_TICKET; break; } case HandshakeType.hello_request: { AssertEmpty(buf); /* * RFC 2246 7.4.1.1 Hello request This message will be ignored by the client if the * client is currently negotiating a session. This message may be ignored by the client * if it does not wish to renegotiate a session, or the client may, if it wishes, * respond with a no_renegotiation alert. */ if (this.mConnectionState == CS_END) { RefuseRenegotiation(); } break; } case HandshakeType.client_hello: case HandshakeType.client_key_exchange: case HandshakeType.certificate_verify: case HandshakeType.hello_verify_request: default: throw new TlsFatalAlert(AlertDescription.unexpected_message); } }
protected override void HandleHandshakeMessage(byte type, byte[] data) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Expected O, but got Unknown MemoryStream val = new MemoryStream(data, false); if (mResumedSession) { if (type != 20 || mConnectionState != 2) { throw new TlsFatalAlert(10); } ProcessFinishedMessage(val); mConnectionState = 15; SendFinishedMessage(); mConnectionState = 13; mConnectionState = 16; CompleteHandshake(); return; } switch (type) { case 11: switch (mConnectionState) { case 2: case 3: if (mConnectionState == 2) { HandleSupplementalData(null); } mPeerCertificate = Certificate.Parse((Stream)(object)val); TlsProtocol.AssertEmpty(val); if (mPeerCertificate == null || mPeerCertificate.IsEmpty) { mAllowCertificateStatus = false; } mKeyExchange.ProcessServerCertificate(mPeerCertificate); mAuthentication = mTlsClient.GetAuthentication(); mAuthentication.NotifyServerCertificate(mPeerCertificate); mConnectionState = 4; break; default: throw new TlsFatalAlert(10); } break; case 22: { short num = mConnectionState; if (num == 4) { if (!mAllowCertificateStatus) { throw new TlsFatalAlert(10); } mCertificateStatus = CertificateStatus.Parse((Stream)(object)val); TlsProtocol.AssertEmpty(val); mConnectionState = 5; break; } throw new TlsFatalAlert(10); } case 20: switch (mConnectionState) { case 13: case 14: if (mConnectionState == 13 && mExpectSessionTicket) { throw new TlsFatalAlert(10); } ProcessFinishedMessage(val); mConnectionState = 15; mConnectionState = 16; CompleteHandshake(); break; default: throw new TlsFatalAlert(10); } break; case 2: { short num = mConnectionState; if (num == 1) { ReceiveServerHelloMessage(val); mConnectionState = 2; mRecordStream.NotifyHelloComplete(); ApplyMaxFragmentLengthExtension(); if (mResumedSession) { mSecurityParameters.masterSecret = Arrays.Clone(mSessionParameters.MasterSecret); mRecordStream.SetPendingConnectionState(Peer.GetCompression(), Peer.GetCipher()); SendChangeCipherSpecMessage(); break; } InvalidateSession(); if (mSelectedSessionID.Length > 0) { mTlsSession = new TlsSessionImpl(mSelectedSessionID, null); } break; } throw new TlsFatalAlert(10); } case 23: { short num = mConnectionState; if (num == 2) { HandleSupplementalData(TlsProtocol.ReadSupplementalDataMessage(val)); break; } throw new TlsFatalAlert(10); } case 14: switch (mConnectionState) { case 2: case 3: case 4: case 5: case 6: case 7: { if (mConnectionState < 3) { HandleSupplementalData(null); } if (mConnectionState < 4) { mKeyExchange.SkipServerCredentials(); mAuthentication = null; } if (mConnectionState < 6) { mKeyExchange.SkipServerKeyExchange(); } TlsProtocol.AssertEmpty(val); mConnectionState = 8; mRecordStream.HandshakeHash.SealHashAlgorithms(); global::System.Collections.IList clientSupplementalData = mTlsClient.GetClientSupplementalData(); if (clientSupplementalData != null) { SendSupplementalDataMessage(clientSupplementalData); } mConnectionState = 9; TlsCredentials tlsCredentials = null; if (mCertificateRequest == null) { mKeyExchange.SkipClientCredentials(); } else { tlsCredentials = mAuthentication.GetClientCredentials(mCertificateRequest); if (tlsCredentials == null) { mKeyExchange.SkipClientCredentials(); SendCertificateMessage(Certificate.EmptyChain); } else { mKeyExchange.ProcessClientCredentials(tlsCredentials); SendCertificateMessage(tlsCredentials.Certificate); } } mConnectionState = 10; SendClientKeyExchangeMessage(); mConnectionState = 11; TlsHandshakeHash tlsHandshakeHash = mRecordStream.PrepareToFinish(); mSecurityParameters.sessionHash = TlsProtocol.GetCurrentPrfHash(Context, tlsHandshakeHash, null); TlsProtocol.EstablishMasterSecret(Context, mKeyExchange); mRecordStream.SetPendingConnectionState(Peer.GetCompression(), Peer.GetCipher()); if (tlsCredentials != null && tlsCredentials is TlsSignerCredentials) { TlsSignerCredentials tlsSignerCredentials = (TlsSignerCredentials)tlsCredentials; SignatureAndHashAlgorithm signatureAndHashAlgorithm = TlsUtilities.GetSignatureAndHashAlgorithm(Context, tlsSignerCredentials); byte[] hash = ((signatureAndHashAlgorithm != null) ? tlsHandshakeHash.GetFinalHash(signatureAndHashAlgorithm.Hash) : mSecurityParameters.SessionHash); byte[] signature = tlsSignerCredentials.GenerateCertificateSignature(hash); DigitallySigned certificateVerify = new DigitallySigned(signatureAndHashAlgorithm, signature); SendCertificateVerifyMessage(certificateVerify); mConnectionState = 12; } SendChangeCipherSpecMessage(); SendFinishedMessage(); mConnectionState = 13; break; } default: throw new TlsFatalAlert(40); } break; case 12: switch (mConnectionState) { case 2: case 3: case 4: case 5: if (mConnectionState < 3) { HandleSupplementalData(null); } if (mConnectionState < 4) { mKeyExchange.SkipServerCredentials(); mAuthentication = null; } mKeyExchange.ProcessServerKeyExchange((Stream)(object)val); TlsProtocol.AssertEmpty(val); mConnectionState = 6; break; default: throw new TlsFatalAlert(10); } break; case 13: switch (mConnectionState) { case 4: case 5: case 6: if (mConnectionState != 6) { mKeyExchange.SkipServerKeyExchange(); } if (mAuthentication == null) { throw new TlsFatalAlert(40); } mCertificateRequest = CertificateRequest.Parse(Context, (Stream)(object)val); TlsProtocol.AssertEmpty(val); mKeyExchange.ValidateCertificateRequest(mCertificateRequest); TlsUtilities.TrackHashAlgorithms(mRecordStream.HandshakeHash, mCertificateRequest.SupportedSignatureAlgorithms); mConnectionState = 7; break; default: throw new TlsFatalAlert(10); } break; case 4: { short num = mConnectionState; if (num == 13) { if (!mExpectSessionTicket) { throw new TlsFatalAlert(10); } InvalidateSession(); ReceiveNewSessionTicketMessage(val); mConnectionState = 14; break; } throw new TlsFatalAlert(10); } case 0: TlsProtocol.AssertEmpty(val); if (mConnectionState == 16) { RefuseRenegotiation(); } break; default: throw new TlsFatalAlert(10); } }
protected virtual void ProcessCertificateVerify(ServerHandshakeState state, byte[] body, TlsHandshakeHash prepareFinishHash) { MemoryStream buf = new MemoryStream(body, false); TlsServerContextImpl context = state.serverContext; DigitallySigned clientCertificateVerify = DigitallySigned.Parse(context, buf); TlsProtocol.AssertEmpty(buf); // Verify the CertificateVerify message contains a correct signature. bool verified = false; try { byte[] hash; if (TlsUtilities.IsTlsV12(context)) { hash = prepareFinishHash.GetFinalHash(clientCertificateVerify.Algorithm.Hash); } else { hash = context.SecurityParameters.SessionHash; } X509CertificateStructure x509Cert = state.clientCertificate.GetCertificateAt(0); SubjectPublicKeyInfo keyInfo = x509Cert.SubjectPublicKeyInfo; AsymmetricKeyParameter publicKey = PublicKeyFactory.CreateKey(keyInfo); TlsSigner tlsSigner = TlsUtilities.CreateTlsSigner((byte)state.clientCertificateType); tlsSigner.Init(context); verified = tlsSigner.VerifyRawSignature(clientCertificateVerify.Algorithm, clientCertificateVerify.Signature, publicKey, hash); } catch (Exception) { } if (!verified) throw new TlsFatalAlert(AlertDescription.decrypt_error); }
protected virtual void ProcessCertificateVerify(DtlsServerProtocol.ServerHandshakeState state, byte[] body, TlsHandshakeHash prepareFinishHash) { MemoryStream memoryStream = new MemoryStream(body, false); TlsServerContextImpl serverContext = state.serverContext; DigitallySigned digitallySigned = DigitallySigned.Parse(serverContext, memoryStream); TlsProtocol.AssertEmpty(memoryStream); bool flag = false; try { byte[] hash; if (TlsUtilities.IsTlsV12(serverContext)) { hash = prepareFinishHash.GetFinalHash(digitallySigned.Algorithm.Hash); } else { hash = serverContext.SecurityParameters.SessionHash; } X509CertificateStructure certificateAt = state.clientCertificate.GetCertificateAt(0); SubjectPublicKeyInfo subjectPublicKeyInfo = certificateAt.SubjectPublicKeyInfo; AsymmetricKeyParameter publicKey = PublicKeyFactory.CreateKey(subjectPublicKeyInfo); TlsSigner tlsSigner = TlsUtilities.CreateTlsSigner((byte)state.clientCertificateType); tlsSigner.Init(serverContext); flag = tlsSigner.VerifyRawSignature(digitallySigned.Algorithm, digitallySigned.Signature, publicKey, hash); } catch (Exception) { } if (!flag) { throw new TlsFatalAlert(51); } }
internal static void TrackHashAlgorithms(TlsHandshakeHash handshakeHash, IList supportedSignatureAlgorithms) { if (supportedSignatureAlgorithms != null) { foreach (SignatureAndHashAlgorithm signatureAndHashAlgorithm in supportedSignatureAlgorithms) { byte hashAlgorithm = signatureAndHashAlgorithm.Hash; handshakeHash.TrackHashAlgorithm(hashAlgorithm); } } }
internal virtual DtlsTransport ClientHandshake(ClientHandshakeState state, DtlsRecordLayer recordLayer) { SecurityParameters securityParameters = state.clientContext.SecurityParameters; DtlsReliableHandshake handshake = new DtlsReliableHandshake(state.clientContext, recordLayer); byte[] clientHelloBody = GenerateClientHello(state, state.client); handshake.SendMessage(HandshakeType.client_hello, clientHelloBody); DtlsReliableHandshake.Message serverMessage = handshake.ReceiveMessage(); while (serverMessage.Type == HandshakeType.hello_verify_request) { ProtocolVersion recordLayerVersion = recordLayer.ResetDiscoveredPeerVersion(); ProtocolVersion client_version = state.clientContext.ClientVersion; /* * RFC 6347 4.2.1 DTLS 1.2 server implementations SHOULD use DTLS version 1.0 regardless of * the version of TLS that is expected to be negotiated. DTLS 1.2 and 1.0 clients MUST use * the version solely to indicate packet formatting (which is the same in both DTLS 1.2 and * 1.0) and not as part of version negotiation. */ if (!recordLayerVersion.IsEqualOrEarlierVersionOf(client_version)) { throw new TlsFatalAlert(AlertDescription.illegal_parameter); } byte[] cookie = ProcessHelloVerifyRequest(state, serverMessage.Body); byte[] patched = PatchClientHelloWithCookie(clientHelloBody, cookie); handshake.ResetHandshakeMessagesDigest(); handshake.SendMessage(HandshakeType.client_hello, patched); serverMessage = handshake.ReceiveMessage(); } if (serverMessage.Type == HandshakeType.server_hello) { ReportServerVersion(state, recordLayer.DiscoveredPeerVersion); ProcessServerHello(state, serverMessage.Body); } else { throw new TlsFatalAlert(AlertDescription.unexpected_message); } if (state.maxFragmentLength >= 0) { int plainTextLimit = 1 << (8 + state.maxFragmentLength); recordLayer.SetPlaintextLimit(plainTextLimit); } securityParameters.cipherSuite = state.selectedCipherSuite; securityParameters.compressionAlgorithm = (byte)state.selectedCompressionMethod; securityParameters.prfAlgorithm = TlsProtocol.GetPrfAlgorithm(state.clientContext, state.selectedCipherSuite); /* * RFC 5264 7.4.9. Any cipher suite which does not explicitly specify verify_data_length has * a verify_data_length equal to 12. This includes all existing cipher suites. */ securityParameters.verifyDataLength = 12; handshake.NotifyHelloComplete(); bool resumedSession = state.selectedSessionID.Length > 0 && state.tlsSession != null && Arrays.AreEqual(state.selectedSessionID, state.tlsSession.SessionID); if (resumedSession) { if (securityParameters.CipherSuite != state.sessionParameters.CipherSuite || securityParameters.CompressionAlgorithm != state.sessionParameters.CompressionAlgorithm) { throw new TlsFatalAlert(AlertDescription.illegal_parameter); } IDictionary sessionServerExtensions = state.sessionParameters.ReadServerExtensions(); securityParameters.extendedMasterSecret = TlsExtensionsUtilities.HasExtendedMasterSecretExtension(sessionServerExtensions); securityParameters.masterSecret = Arrays.Clone(state.sessionParameters.MasterSecret); recordLayer.InitPendingEpoch(state.client.GetCipher()); // NOTE: Calculated exclusive of the actual Finished message from the server byte[] resExpectedServerVerifyData = TlsUtilities.CalculateVerifyData(state.clientContext, ExporterLabel.server_finished, TlsProtocol.GetCurrentPrfHash(state.clientContext, handshake.HandshakeHash, null)); ProcessFinished(handshake.ReceiveMessageBody(HandshakeType.finished), resExpectedServerVerifyData); // NOTE: Calculated exclusive of the Finished message itself byte[] resClientVerifyData = TlsUtilities.CalculateVerifyData(state.clientContext, ExporterLabel.client_finished, TlsProtocol.GetCurrentPrfHash(state.clientContext, handshake.HandshakeHash, null)); handshake.SendMessage(HandshakeType.finished, resClientVerifyData); handshake.Finish(); state.clientContext.SetResumableSession(state.tlsSession); state.client.NotifyHandshakeComplete(); return(new DtlsTransport(recordLayer)); } InvalidateSession(state); if (state.selectedSessionID.Length > 0) { state.tlsSession = new TlsSessionImpl(state.selectedSessionID, null); } serverMessage = handshake.ReceiveMessage(); if (serverMessage.Type == HandshakeType.supplemental_data) { ProcessServerSupplementalData(state, serverMessage.Body); serverMessage = handshake.ReceiveMessage(); } else { state.client.ProcessServerSupplementalData(null); } state.keyExchange = state.client.GetKeyExchange(); state.keyExchange.Init(state.clientContext); Certificate serverCertificate = null; if (serverMessage.Type == HandshakeType.certificate) { serverCertificate = ProcessServerCertificate(state, serverMessage.Body); serverMessage = handshake.ReceiveMessage(); } else { // Okay, Certificate is optional state.keyExchange.SkipServerCredentials(); } // TODO[RFC 3546] Check whether empty certificates is possible, allowed, or excludes CertificateStatus if (serverCertificate == null || serverCertificate.IsEmpty) { state.allowCertificateStatus = false; } if (serverMessage.Type == HandshakeType.certificate_status) { ProcessCertificateStatus(state, serverMessage.Body); serverMessage = handshake.ReceiveMessage(); } else { // Okay, CertificateStatus is optional } if (serverMessage.Type == HandshakeType.server_key_exchange) { ProcessServerKeyExchange(state, serverMessage.Body); serverMessage = handshake.ReceiveMessage(); } else { // Okay, ServerKeyExchange is optional state.keyExchange.SkipServerKeyExchange(); } if (serverMessage.Type == HandshakeType.certificate_request) { ProcessCertificateRequest(state, serverMessage.Body); /* * TODO Give the client a chance to immediately select the CertificateVerify hash * algorithm here to avoid tracking the other hash algorithms unnecessarily? */ TlsUtilities.TrackHashAlgorithms(handshake.HandshakeHash, state.certificateRequest.SupportedSignatureAlgorithms); serverMessage = handshake.ReceiveMessage(); } else { // Okay, CertificateRequest is optional } if (serverMessage.Type == HandshakeType.server_hello_done) { if (serverMessage.Body.Length != 0) { throw new TlsFatalAlert(AlertDescription.decode_error); } } else { throw new TlsFatalAlert(AlertDescription.unexpected_message); } handshake.HandshakeHash.SealHashAlgorithms(); IList clientSupplementalData = state.client.GetClientSupplementalData(); if (clientSupplementalData != null) { byte[] supplementalDataBody = GenerateSupplementalData(clientSupplementalData); handshake.SendMessage(HandshakeType.supplemental_data, supplementalDataBody); } if (state.certificateRequest != null) { state.clientCredentials = state.authentication.GetClientCredentials(state.certificateRequest); /* * RFC 5246 If no suitable certificate is available, the client MUST send a certificate * message containing no certificates. * * NOTE: In previous RFCs, this was SHOULD instead of MUST. */ Certificate clientCertificate = null; if (state.clientCredentials != null) { clientCertificate = state.clientCredentials.Certificate; } if (clientCertificate == null) { clientCertificate = Certificate.EmptyChain; } byte[] certificateBody = GenerateCertificate(clientCertificate); handshake.SendMessage(HandshakeType.certificate, certificateBody); } if (state.clientCredentials != null) { state.keyExchange.ProcessClientCredentials(state.clientCredentials); } else { state.keyExchange.SkipClientCredentials(); } byte[] clientKeyExchangeBody = GenerateClientKeyExchange(state); handshake.SendMessage(HandshakeType.client_key_exchange, clientKeyExchangeBody); TlsHandshakeHash prepareFinishHash = handshake.PrepareToFinish(); securityParameters.sessionHash = TlsProtocol.GetCurrentPrfHash(state.clientContext, prepareFinishHash, null); TlsProtocol.EstablishMasterSecret(state.clientContext, state.keyExchange); recordLayer.InitPendingEpoch(state.client.GetCipher()); if (state.clientCredentials != null && state.clientCredentials is TlsSignerCredentials) { TlsSignerCredentials signerCredentials = (TlsSignerCredentials)state.clientCredentials; /* * RFC 5246 4.7. digitally-signed element needs SignatureAndHashAlgorithm from TLS 1.2 */ SignatureAndHashAlgorithm signatureAndHashAlgorithm; byte[] hash; if (TlsUtilities.IsTlsV12(state.clientContext)) { signatureAndHashAlgorithm = signerCredentials.SignatureAndHashAlgorithm; if (signatureAndHashAlgorithm == null) { throw new TlsFatalAlert(AlertDescription.internal_error); } hash = prepareFinishHash.GetFinalHash(signatureAndHashAlgorithm.Hash); } else { signatureAndHashAlgorithm = null; hash = securityParameters.SessionHash; } byte[] signature = signerCredentials.GenerateCertificateSignature(hash); DigitallySigned certificateVerify = new DigitallySigned(signatureAndHashAlgorithm, signature); byte[] certificateVerifyBody = GenerateCertificateVerify(state, certificateVerify); handshake.SendMessage(HandshakeType.certificate_verify, certificateVerifyBody); } // NOTE: Calculated exclusive of the Finished message itself byte[] clientVerifyData = TlsUtilities.CalculateVerifyData(state.clientContext, ExporterLabel.client_finished, TlsProtocol.GetCurrentPrfHash(state.clientContext, handshake.HandshakeHash, null)); handshake.SendMessage(HandshakeType.finished, clientVerifyData); if (state.expectSessionTicket) { serverMessage = handshake.ReceiveMessage(); if (serverMessage.Type == HandshakeType.session_ticket) { ProcessNewSessionTicket(state, serverMessage.Body); } else { throw new TlsFatalAlert(AlertDescription.unexpected_message); } } // NOTE: Calculated exclusive of the actual Finished message from the server byte[] expectedServerVerifyData = TlsUtilities.CalculateVerifyData(state.clientContext, ExporterLabel.server_finished, TlsProtocol.GetCurrentPrfHash(state.clientContext, handshake.HandshakeHash, null)); ProcessFinished(handshake.ReceiveMessageBody(HandshakeType.finished), expectedServerVerifyData); handshake.Finish(); if (state.tlsSession != null) { state.sessionParameters = new SessionParameters.Builder() .SetCipherSuite(securityParameters.cipherSuite) .SetCompressionAlgorithm(securityParameters.compressionAlgorithm) .SetMasterSecret(securityParameters.masterSecret) .SetPeerCertificate(serverCertificate) .SetPskIdentity(securityParameters.pskIdentity) .Build(); state.tlsSession = TlsUtilities.ImportSession(state.tlsSession.SessionID, state.sessionParameters); state.clientContext.SetResumableSession(state.tlsSession); } state.client.NotifyHandshakeComplete(); return(new DtlsTransport(recordLayer)); }
protected override void HandleHandshakeMessage(byte type, byte[] data) { MemoryStream buf = new MemoryStream(data, false); if (base.mResumedSession) { if ((type != 20) || (base.mConnectionState != 2)) { throw new TlsFatalAlert(10); } this.ProcessFinishedMessage(buf); base.mConnectionState = 15; this.SendFinishedMessage(); base.mConnectionState = 13; base.mConnectionState = 0x10; this.CompleteHandshake(); } else { switch (type) { case 0: TlsProtocol.AssertEmpty(buf); if (base.mConnectionState == 0x10) { this.RefuseRenegotiation(); } return; case 2: if (base.mConnectionState != 1) { throw new TlsFatalAlert(10); } this.ReceiveServerHelloMessage(buf); base.mConnectionState = 2; base.mRecordStream.NotifyHelloComplete(); this.ApplyMaxFragmentLengthExtension(); if (base.mResumedSession) { base.mSecurityParameters.masterSecret = Arrays.Clone(base.mSessionParameters.MasterSecret); base.mRecordStream.SetPendingConnectionState(this.Peer.GetCompression(), this.Peer.GetCipher()); this.SendChangeCipherSpecMessage(); } else { this.InvalidateSession(); if (this.mSelectedSessionID.Length > 0) { base.mTlsSession = new TlsSessionImpl(this.mSelectedSessionID, null); } } return; case 4: if (base.mConnectionState != 13) { throw new TlsFatalAlert(10); } if (!base.mExpectSessionTicket) { throw new TlsFatalAlert(10); } this.InvalidateSession(); this.ReceiveNewSessionTicketMessage(buf); base.mConnectionState = 14; return; case 11: switch (base.mConnectionState) { case 2: case 3: if (base.mConnectionState == 2) { this.HandleSupplementalData(null); } base.mPeerCertificate = Certificate.Parse(buf); TlsProtocol.AssertEmpty(buf); if ((base.mPeerCertificate == null) || base.mPeerCertificate.IsEmpty) { base.mAllowCertificateStatus = false; } this.mKeyExchange.ProcessServerCertificate(base.mPeerCertificate); this.mAuthentication = this.mTlsClient.GetAuthentication(); this.mAuthentication.NotifyServerCertificate(base.mPeerCertificate); base.mConnectionState = 4; return; } throw new TlsFatalAlert(10); case 12: switch (base.mConnectionState) { case 2: case 3: case 4: case 5: if (base.mConnectionState < 3) { this.HandleSupplementalData(null); } if (base.mConnectionState < 4) { this.mKeyExchange.SkipServerCredentials(); this.mAuthentication = null; } this.mKeyExchange.ProcessServerKeyExchange(buf); TlsProtocol.AssertEmpty(buf); base.mConnectionState = 6; return; } throw new TlsFatalAlert(10); case 13: switch (base.mConnectionState) { case 4: case 5: case 6: if (base.mConnectionState != 6) { this.mKeyExchange.SkipServerKeyExchange(); } if (this.mAuthentication == null) { throw new TlsFatalAlert(40); } this.mCertificateRequest = CertificateRequest.Parse(this.Context, buf); TlsProtocol.AssertEmpty(buf); this.mKeyExchange.ValidateCertificateRequest(this.mCertificateRequest); TlsUtilities.TrackHashAlgorithms(base.mRecordStream.HandshakeHash, this.mCertificateRequest.SupportedSignatureAlgorithms); base.mConnectionState = 7; return; } throw new TlsFatalAlert(10); case 14: switch (base.mConnectionState) { case 2: case 3: case 4: case 5: case 6: case 7: { if (base.mConnectionState < 3) { this.HandleSupplementalData(null); } if (base.mConnectionState < 4) { this.mKeyExchange.SkipServerCredentials(); this.mAuthentication = null; } if (base.mConnectionState < 6) { this.mKeyExchange.SkipServerKeyExchange(); } TlsProtocol.AssertEmpty(buf); base.mConnectionState = 8; base.mRecordStream.HandshakeHash.SealHashAlgorithms(); IList clientSupplementalData = this.mTlsClient.GetClientSupplementalData(); if (clientSupplementalData != null) { this.SendSupplementalDataMessage(clientSupplementalData); } base.mConnectionState = 9; TlsCredentials clientCredentials = null; if (this.mCertificateRequest == null) { this.mKeyExchange.SkipClientCredentials(); } else { clientCredentials = this.mAuthentication.GetClientCredentials(this.Context, this.mCertificateRequest); if (clientCredentials == null) { this.mKeyExchange.SkipClientCredentials(); this.SendCertificateMessage(Certificate.EmptyChain); } else { this.mKeyExchange.ProcessClientCredentials(clientCredentials); this.SendCertificateMessage(clientCredentials.Certificate); } } base.mConnectionState = 10; this.SendClientKeyExchangeMessage(); base.mConnectionState = 11; TlsHandshakeHash handshakeHash = base.mRecordStream.PrepareToFinish(); base.mSecurityParameters.sessionHash = TlsProtocol.GetCurrentPrfHash(this.Context, handshakeHash, null); TlsProtocol.EstablishMasterSecret(this.Context, this.mKeyExchange); base.mRecordStream.SetPendingConnectionState(this.Peer.GetCompression(), this.Peer.GetCipher()); if ((clientCredentials != null) && (clientCredentials is TlsSignerCredentials)) { byte[] sessionHash; TlsSignerCredentials signerCredentials = (TlsSignerCredentials)clientCredentials; SignatureAndHashAlgorithm signatureAndHashAlgorithm = TlsUtilities.GetSignatureAndHashAlgorithm(this.Context, signerCredentials); if (signatureAndHashAlgorithm == null) { sessionHash = base.mSecurityParameters.SessionHash; } else { sessionHash = handshakeHash.GetFinalHash(signatureAndHashAlgorithm.Hash); } byte[] signature = signerCredentials.GenerateCertificateSignature(sessionHash); DigitallySigned certificateVerify = new DigitallySigned(signatureAndHashAlgorithm, signature); this.SendCertificateVerifyMessage(certificateVerify); base.mConnectionState = 12; } this.SendChangeCipherSpecMessage(); this.SendFinishedMessage(); base.mConnectionState = 13; return; } } throw new TlsFatalAlert(40); case 20: switch (base.mConnectionState) { case 13: case 14: if ((base.mConnectionState == 13) && base.mExpectSessionTicket) { throw new TlsFatalAlert(10); } this.ProcessFinishedMessage(buf); base.mConnectionState = 15; base.mConnectionState = 0x10; this.CompleteHandshake(); return; } throw new TlsFatalAlert(10); case 0x16: if (base.mConnectionState != 4) { throw new TlsFatalAlert(10); } if (!base.mAllowCertificateStatus) { throw new TlsFatalAlert(10); } this.mCertificateStatus = CertificateStatus.Parse(buf); TlsProtocol.AssertEmpty(buf); base.mConnectionState = 5; return; case 0x17: if (base.mConnectionState != 2) { throw new TlsFatalAlert(10); } this.HandleSupplementalData(TlsProtocol.ReadSupplementalDataMessage(buf)); return; } throw new TlsFatalAlert(10); } }