process the NewSessionTicket TLS message

This commit is contained in:
Marten Seemann 2019-03-28 11:07:40 +01:00
parent da4b3e3176
commit 2adf923ee6
6 changed files with 32 additions and 14 deletions

View file

@ -16,17 +16,20 @@ type cryptoStreamManager struct {
initialStream cryptoStream initialStream cryptoStream
handshakeStream cryptoStream handshakeStream cryptoStream
oneRTTStream cryptoStream
} }
func newCryptoStreamManager( func newCryptoStreamManager(
cryptoHandler cryptoDataHandler, cryptoHandler cryptoDataHandler,
initialStream cryptoStream, initialStream cryptoStream,
handshakeStream cryptoStream, handshakeStream cryptoStream,
oneRTTStream cryptoStream,
) *cryptoStreamManager { ) *cryptoStreamManager {
return &cryptoStreamManager{ return &cryptoStreamManager{
cryptoHandler: cryptoHandler, cryptoHandler: cryptoHandler,
initialStream: initialStream, initialStream: initialStream,
handshakeStream: handshakeStream, handshakeStream: handshakeStream,
oneRTTStream: oneRTTStream,
} }
} }
@ -38,8 +41,7 @@ func (m *cryptoStreamManager) HandleCryptoFrame(frame *wire.CryptoFrame, encLeve
case protocol.EncryptionHandshake: case protocol.EncryptionHandshake:
str = m.handshakeStream str = m.handshakeStream
case protocol.Encryption1RTT: case protocol.Encryption1RTT:
// TODO(#981): process session tickets str = m.oneRTTStream
return false, nil
default: default:
return false, fmt.Errorf("received CRYPTO frame with unexpected encryption level: %s", encLevel) return false, fmt.Errorf("received CRYPTO frame with unexpected encryption level: %s", encLevel)
} }

View file

@ -18,13 +18,15 @@ var _ = Describe("Crypto Stream Manager", func() {
initialStream *MockCryptoStream initialStream *MockCryptoStream
handshakeStream *MockCryptoStream handshakeStream *MockCryptoStream
oneRTTStream *MockCryptoStream
) )
BeforeEach(func() { BeforeEach(func() {
initialStream = NewMockCryptoStream(mockCtrl) initialStream = NewMockCryptoStream(mockCtrl)
handshakeStream = NewMockCryptoStream(mockCtrl) handshakeStream = NewMockCryptoStream(mockCtrl)
oneRTTStream = NewMockCryptoStream(mockCtrl)
cs = NewMockCryptoDataHandler(mockCtrl) cs = NewMockCryptoDataHandler(mockCtrl)
csm = newCryptoStreamManager(cs, initialStream, handshakeStream) csm = newCryptoStreamManager(cs, initialStream, handshakeStream, oneRTTStream)
}) })
It("passes messages to the initial stream", func() { It("passes messages to the initial stream", func() {
@ -49,6 +51,17 @@ var _ = Describe("Crypto Stream Manager", func() {
Expect(encLevelChanged).To(BeFalse()) Expect(encLevelChanged).To(BeFalse())
}) })
It("passes messages to the 1-RTT stream", func() {
cf := &wire.CryptoFrame{Data: []byte("foobar")}
oneRTTStream.EXPECT().HandleCryptoFrame(cf)
oneRTTStream.EXPECT().GetCryptoData().Return([]byte("foobar"))
oneRTTStream.EXPECT().GetCryptoData()
cs.EXPECT().HandleMessage([]byte("foobar"), protocol.Encryption1RTT)
encLevelChanged, err := csm.HandleCryptoFrame(cf, protocol.Encryption1RTT)
Expect(err).ToNot(HaveOccurred())
Expect(encLevelChanged).To(BeFalse())
})
It("doesn't call the message handler, if there's no message", func() { It("doesn't call the message handler, if there's no message", func() {
cf := &wire.CryptoFrame{Data: []byte("foobar")} cf := &wire.CryptoFrame{Data: []byte("foobar")}
handshakeStream.EXPECT().HandleCryptoFrame(cf) handshakeStream.EXPECT().HandleCryptoFrame(cf)
@ -98,12 +111,6 @@ var _ = Describe("Crypto Stream Manager", func() {
Expect(err).To(MatchError(err)) Expect(err).To(MatchError(err))
}) })
It("ignores post-handshake crypto data", func() {
changed, err := csm.HandleCryptoFrame(&wire.CryptoFrame{}, protocol.Encryption1RTT)
Expect(err).ToNot(HaveOccurred())
Expect(changed).To(BeFalse())
})
It("errors for unknown encryption levels", func() { It("errors for unknown encryption levels", func() {
_, err := csm.HandleCryptoFrame(&wire.CryptoFrame{}, 42) _, err := csm.HandleCryptoFrame(&wire.CryptoFrame{}, 42)
Expect(err).To(HaveOccurred()) Expect(err).To(HaveOccurred())

2
go.mod
View file

@ -5,7 +5,7 @@ go 1.12
require ( require (
github.com/cheekybits/genny v1.0.0 github.com/cheekybits/genny v1.0.0
github.com/golang/mock v1.2.0 github.com/golang/mock v1.2.0
github.com/marten-seemann/qtls v0.2.2 github.com/marten-seemann/qtls v0.2.3
github.com/onsi/ginkgo v1.7.0 github.com/onsi/ginkgo v1.7.0
github.com/onsi/gomega v1.4.3 github.com/onsi/gomega v1.4.3
golang.org/x/crypto v0.0.0-20190228161510-8dd112bcdc25 golang.org/x/crypto v0.0.0-20190228161510-8dd112bcdc25

4
go.sum
View file

@ -8,8 +8,8 @@ github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/marten-seemann/qtls v0.2.2 h1:QcmNbsYmV0ByHRkBRhSik8rxmB3S/SPzd+LMlXTgyJM= github.com/marten-seemann/qtls v0.2.3 h1:0yWJ43C62LsZt08vuQJDK1uC1czUc3FJeCLPoNAI4vA=
github.com/marten-seemann/qtls v0.2.2/go.mod h1:xzjG7avBwGGbdZ8dTGxlBnLArsVKLvwmjgmPuiQEcYk= github.com/marten-seemann/qtls v0.2.3/go.mod h1:xzjG7avBwGGbdZ8dTGxlBnLArsVKLvwmjgmPuiQEcYk=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.7.0 h1:WSHQ+IS43OoUrWtD1/bbclrwK8TTH5hzp+umCiuxHgs= github.com/onsi/ginkgo v1.7.0 h1:WSHQ+IS43OoUrWtD1/bbclrwK8TTH5hzp+umCiuxHgs=
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=

View file

@ -21,6 +21,7 @@ type messageType uint8
const ( const (
typeClientHello messageType = 1 typeClientHello messageType = 1
typeServerHello messageType = 2 typeServerHello messageType = 2
typeNewSessionTicket messageType = 4
typeEncryptedExtensions messageType = 8 typeEncryptedExtensions messageType = 8
typeCertificate messageType = 11 typeCertificate messageType = 11
typeCertificateRequest messageType = 13 typeCertificateRequest messageType = 13
@ -34,6 +35,8 @@ func (m messageType) String() string {
return "ClientHello" return "ClientHello"
case typeServerHello: case typeServerHello:
return "ServerHello" return "ServerHello"
case typeNewSessionTicket:
return "NewSessionTicket"
case typeEncryptedExtensions: case typeEncryptedExtensions:
return "EncryptedExtensions" return "EncryptedExtensions"
case typeCertificate: case typeCertificate:
@ -294,6 +297,8 @@ func (h *cryptoSetup) checkEncryptionLevel(msgType messageType, encLevel protoco
typeCertificateVerify, typeCertificateVerify,
typeFinished: typeFinished:
expected = protocol.EncryptionHandshake expected = protocol.EncryptionHandshake
case typeNewSessionTicket:
expected = protocol.Encryption1RTT
default: default:
return fmt.Errorf("unexpected handshake message: %d", msgType) return fmt.Errorf("unexpected handshake message: %d", msgType)
} }
@ -399,6 +404,10 @@ func (h *cryptoSetup) handleMessageForClient(msgType messageType) bool {
return false return false
} }
return true return true
case typeNewSessionTicket:
<-h.handshakeDone // don't process session tickets before the handshake has completed
h.conn.HandlePostHandshakeMessage()
return false
default: default:
panic("unexpected handshake message: ") panic("unexpected handshake message: ")
} }

View file

@ -219,7 +219,7 @@ var newSession = func(
s.perspective, s.perspective,
s.version, s.version,
) )
s.cryptoStreamManager = newCryptoStreamManager(cs, initialStream, handshakeStream) s.cryptoStreamManager = newCryptoStreamManager(cs, initialStream, handshakeStream, oneRTTStream)
if err := s.postSetup(); err != nil { if err := s.postSetup(); err != nil {
return nil, err return nil, err
@ -275,7 +275,7 @@ var newClientSession = func(
} }
s.clientHelloWritten = clientHelloWritten s.clientHelloWritten = clientHelloWritten
s.cryptoStreamHandler = cs s.cryptoStreamHandler = cs
s.cryptoStreamManager = newCryptoStreamManager(cs, initialStream, handshakeStream) s.cryptoStreamManager = newCryptoStreamManager(cs, initialStream, handshakeStream, oneRTTStream)
s.unpacker = newPacketUnpacker(cs, s.version) s.unpacker = newPacketUnpacker(cs, s.version)
s.streamsMap = newStreamsMap( s.streamsMap = newStreamsMap(
s, s,