diff --git a/conn.go b/conn.go index 002222d..5fd2b13 100644 --- a/conn.go +++ b/conn.go @@ -837,9 +837,11 @@ Again: case recordTypeHandshake: // TODO(rsc): Should at least pick off connection close. - if typ != want && !(c.isClient && c.config.Renegotiation != RenegotiateNever) && - c.phase != waitingClientFinished { - return c.in.setErrorLocked(c.sendAlert(alertNoRenegotiation)) + // If early data was being read, a Finished message is expected + // instead of (early) application data. Other post-handshake + // messages include HelloRequest and NewSessionTicket. + if typ != want && want != recordTypeApplicationData { + return c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage)) } c.hand.Write(data) if typ != want && c.phase == waitingClientFinished { @@ -1243,20 +1245,26 @@ func (c *Conn) Write(b []byte) (int, error) { return n + m, c.out.setErrorLocked(err) } -// handleRenegotiation processes a HelloRequest handshake message. +// Process Handshake messages after the handshake has completed. // c.in.Mutex <= L -func (c *Conn) handleRenegotiation() error { +func (c *Conn) handlePostHandshake() error { msg, err := c.readHandshake() if err != nil { return err } - _, ok := msg.(*helloRequestMsg) - if !ok { + switch hm := msg.(type) { + case *helloRequestMsg: + return c.handleRenegotiation(hm) + default: c.sendAlert(alertUnexpectedMessage) return alertUnexpectedMessage } +} +// handleRenegotiation processes a HelloRequest handshake message. +// c.in.Mutex <= L +func (c *Conn) handleRenegotiation(*helloRequestMsg) error { if !c.isClient { return c.sendAlert(alertNoRenegotiation) } @@ -1432,9 +1440,7 @@ func (c *Conn) Read(b []byte) (n int, err error) { return 0, err } if c.hand.Len() > 0 { - // We received handshake bytes, indicating the - // start of a renegotiation. - if err := c.handleRenegotiation(); err != nil { + if err := c.handlePostHandshake(); err != nil { return 0, err } }