tris: accept other post-handshake messages as client

Do not assume that every post-handshake messages are HelloRequests that
try to trigger a renegotiation. This could result in a no_renegotiation
(rather than an unexpected_message) alert even for other message types
(like NewSessionTicket).

This change makes the caller of readRecord(recordTypeApplicationData)
responsible for checking for renegotiation in case of a handshake
message, but that is currently already the case. And the condition
"c.phase == waitingClientFinished" can only be hit by the server, so
that won't have break the handshake either.

Related: https://github.com/cloudflare/tls-tris/issues/50
This commit is contained in:
Peter Wu 2017-11-12 01:02:42 +00:00 committed by Peter Wu
parent 4e6ebb63dd
commit de3ae8f61d

26
conn.go
View File

@ -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
}
}