public void SendFinished(Stream stream) { Record record; /* change cipher spec */ record = new Record(20, VERSION); record.Fragment = new byte[] { 0x01 }; _recordHandler.ProcessOutputRecord(record); SendRecord(stream, record); /* change our own cipher spec */ _recordHandler.ChangeLocalState(); ProtocolVersion version = VERSION; byte[] handshakeMessages = _handshakeStream.ToArray(); Console.WriteLine("handshake messages length " + handshakeMessages.Length); PseudoRandomFunction prf = _cipherSuite.PseudoRandomFunction; HashAlgorithm verifyHash = prf.CreateVerifyHashAlgorithm(_masterSecret); verifyHash.TransformBlock(handshakeMessages, 0, handshakeMessages.Length, handshakeMessages, 0); byte[] verifyData; if (version == ProtocolVersion.SSL3_0) { byte[] senderBytes = Encoding.ASCII.GetBytes("CLNT"); verifyHash.TransformFinalBlock(senderBytes, 0, senderBytes.Length); verifyData = verifyHash.Hash; } else { verifyHash.TransformFinalBlock(new byte[0], 0, 0); byte[] hash = verifyHash.Hash; int length = _cipherSuite.PseudoRandomFunction.VerifyDataLength; verifyData = _cipherSuite.PseudoRandomFunction.GetBytes(_masterSecret, "client finished", hash, length); } HandshakeMessage finished = new HandshakeMessage(HandshakeMessageType.Finished, VERSION, verifyData); PrintBytes("verify data", finished.Data); record = new Record(22, VERSION); record.Fragment = finished.Encode(); _recordHandler.ProcessOutputRecord(record); SendRecord(stream, record); Console.WriteLine("encrypted finished sent"); }
private async Task SendClientChangeCipherSpec(CancellationToken token) { logger?.Debug("Sending change cipher spec to server..."); // Create the change cipher spec protocol packet // NOTE: this has to be before recordHandler.ChangeLocalState since it uses the old state var record = new Record( RecordType.ChangeCipherSpec, _handshakeSession.NegotiatedVersion, new byte[] { 0x01 }); _recordHandler.ProcessOutputRecord(record); // NOTE: keep this before recordHandler.ChangeLocalState since it may generate masterSecret _handshakeSession.LocalChangeCipherSpec(); // Change cipher suite in record handler and handle it in handshake session _recordHandler.SetCipherSuite(_handshakeSession.CipherSuite, _handshakeSession.ConnectionState); _recordHandler.ChangeLocalState(); // Send the change cipher spec protocol packet await _recordStream.SendAsync(new[] { record }, token); }
private void ProcessSendChangeCipherSpec(AsyncHandshakeResult asyncHandshakeResult) { // Create the change cipher spec protocol packet // NOTE: this has to be before recordHandler.ChangeLocalState since it uses the old state Record record = new Record(RecordType.ChangeCipherSpec, _handshakeSession.NegotiatedVersion, new byte[] { 0x01 }); _recordHandler.ProcessOutputRecord(record); // NOTE: keep this before recordHandler.ChangeLocalState since it may generate masterSecret _handshakeSession.LocalChangeCipherSpec(); // Change cipher suite in record handler and handle it in handshake session _recordHandler.SetCipherSuite(_handshakeSession.CipherSuite, _handshakeSession.ConnectionState); _recordHandler.ChangeLocalState(); // Send the change cipher spec protocol packet _recordStream.BeginSend(new Record[] { record }, new AsyncCallback(SendHandshakeCallback), asyncHandshakeResult); }