protected void OutputMessage(HandshakeMessage message) { byte[] data = message.Encode(); _handshakeStream.Write(data, 0, data.Length); _outputMessages.Add(message); }
public void ProcessMessage(HandshakeMessage message) { byte[] msgData = message.Encode(); _handshakeStream.Write(msgData, 0, msgData.Length); switch (message.Type) { case HandshakeMessageType.HelloRequest: ProcessHelloRequest(); break; case HandshakeMessageType.ClientHello: ProcessClientHello((HandshakeClientHello) message); break; case HandshakeMessageType.ServerHello: ProcessServerHello((HandshakeServerHello) message); break; case HandshakeMessageType.NewSessionTicket: ProcessNewSessionTicket(message); break; case HandshakeMessageType.Certificate: ProcessCertificate((HandshakeCertificate) message); break; case HandshakeMessageType.ServerKeyExchange: ProcessServerKeyExchange(message); break; case HandshakeMessageType.CertificateRequest: ProcessCertificateRequest((HandshakeCertificateRequest)message); break; case HandshakeMessageType.ServerHelloDone: ProcessServerHelloDone(message); break; case HandshakeMessageType.CertificateVerify: ProcessCertificateVerify(message); break; case HandshakeMessageType.ClientKeyExchange: ProcessClientKeyExchange(message); break; case HandshakeMessageType.Finished: ProcessFinished(message); break; } }
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"); }
public void SendClientKey(Stream stream) { byte[] clientKeys = _cipherSuite.KeyExchangeAlgorithm.GetClientKeys(VERSION, VERSION, _rsaPublicKey); if (VERSION != ProtocolVersion.SSL3_0) { byte[] tmpArray = new byte[clientKeys.Length+2]; tmpArray[0] = (byte) (clientKeys.Length >> 8); tmpArray[1] = (byte) (clientKeys.Length); Buffer.BlockCopy(clientKeys, 0, tmpArray, 2, clientKeys.Length); clientKeys = tmpArray; } HandshakeMessage keyex = new HandshakeMessage(HandshakeMessageType.ClientKeyExchange, VERSION, clientKeys); Record record = new Record(22, VERSION); record.Fragment = keyex.Encode(); _recordHandler.ProcessOutputRecord(record); SendRecord(stream, record); }
protected override void ProcessFinished(HandshakeMessage finished) { if (_state != HandshakeState.ReceivedChangeCipherSpec) { throw new AlertException(AlertDescription.UnexpectedMessage, "Finished message received at the wrong time"); } byte[] allMessages = _handshakeStream.ToArray(); byte[] handshakeMessages = new byte[allMessages.Length - finished.Encode().Length]; Buffer.BlockCopy(allMessages, 0, handshakeMessages, 0, handshakeMessages.Length); PseudoRandomFunction prf = _cipherSuite.PseudoRandomFunction; HashAlgorithm verifyHash = prf.CreateVerifyHashAlgorithm(_connectionState.MasterSecret); verifyHash.TransformBlock(handshakeMessages, 0, handshakeMessages.Length, handshakeMessages, 0); byte[] ourVerifyData; if (_version == ProtocolVersion.SSL3_0) { byte[] senderBytes = Encoding.ASCII.GetBytes("SRVR"); verifyHash.TransformFinalBlock(senderBytes, 0, senderBytes.Length); ourVerifyData = verifyHash.Hash; } else { verifyHash.TransformFinalBlock(new byte[0], 0, 0); byte[] hash = verifyHash.Hash; int length = _cipherSuite.PseudoRandomFunction.VerifyDataLength; ourVerifyData = _cipherSuite.PseudoRandomFunction.GetBytes(_connectionState.MasterSecret, "server finished", hash, length); } // Verify that the received data matches ours bool verifyOk = false; if (ourVerifyData.Length == finished.Data.Length) { verifyOk = true; for (int i=0; i<ourVerifyData.Length; i++) { if (ourVerifyData[i] != finished.Data[i]) { verifyOk = false; } } } if (!verifyOk) { throw new AlertException(AlertDescription.DecryptError, "Finished packet contents incorrect"); } _connectionState.ServerVerifyData = ourVerifyData; // Cleanup the handshake stream used for verify hashes _handshakeStream = new MemoryStream(); // Everything done and handshake finished _state = HandshakeState.Finished; }
protected override void ProcessCertificateVerify(HandshakeMessage verify) { if (_state != HandshakeState.ReceivedClientKeyExchange) { throw new AlertException(AlertDescription.UnexpectedMessage, "Certificate verify received at the wrong time"); } if (!_clientCertificateReceived) { throw new AlertException(AlertDescription.UnexpectedMessage, "Certificate verify received even though client certificate not received"); } // Get all handshake messages up to, but not including, this one byte[] allMessages = _handshakeStream.ToArray(); byte[] handshakeMessages = new byte[allMessages.Length - verify.Encode().Length]; Buffer.BlockCopy(allMessages, 0, handshakeMessages, 0, handshakeMessages.Length); // Verify the signature of handshake messages CertificatePublicKey publicKey = new CertificatePublicKey(_clientCertificates[0]); bool signatureOk = VerifySignature(publicKey, handshakeMessages, verify.Data); if (!signatureOk) { throw new AlertException(AlertDescription.DecodeError, "Signature from client incorrect"); } // Wait for changecipherspec+finished _state = HandshakeState.ReceivedClientKeyExchange; }